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,40 +1,87 @@
1
- 'use strict';
1
+ "use strict";
2
2
 
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.handleParseHeaders = handleParseHeaders;
6
+ exports.addRateLimit = exports.DEFAULT_ALLOWED_HEADERS = void 0;
7
7
  exports.allowCrossDomain = allowCrossDomain;
8
+ exports.allowDoubleForwardSlash = allowDoubleForwardSlash;
8
9
  exports.allowMethodOverride = allowMethodOverride;
9
- exports.handleParseErrors = handleParseErrors;
10
+ exports.checkIp = void 0;
10
11
  exports.enforceMasterKeyAccess = enforceMasterKeyAccess;
12
+ exports.handleParseErrors = handleParseErrors;
13
+ exports.handleParseHeaders = handleParseHeaders;
14
+ exports.handleParseSession = void 0;
11
15
  exports.promiseEnforceMasterKeyAccess = promiseEnforceMasterKeyAccess;
16
+ exports.promiseEnsureIdempotency = promiseEnsureIdempotency;
17
+ var _cache = _interopRequireDefault(require("./cache"));
18
+ var _node = _interopRequireDefault(require("parse/node"));
19
+ var _Auth = _interopRequireDefault(require("./Auth"));
20
+ var _Config = _interopRequireDefault(require("./Config"));
21
+ var _ClientSDK = _interopRequireDefault(require("./ClientSDK"));
22
+ var _logger = _interopRequireDefault(require("./logger"));
23
+ var _rest = _interopRequireDefault(require("./rest"));
24
+ var _MongoStorageAdapter = _interopRequireDefault(require("./Adapters/Storage/Mongo/MongoStorageAdapter"));
25
+ var _PostgresStorageAdapter = _interopRequireDefault(require("./Adapters/Storage/Postgres/PostgresStorageAdapter"));
26
+ var _expressRateLimit = _interopRequireDefault(require("express-rate-limit"));
27
+ var _Definitions = require("./Options/Definitions");
28
+ var _pathToRegexp = require("path-to-regexp");
29
+ var _rateLimitRedis = _interopRequireDefault(require("rate-limit-redis"));
30
+ var _redis = require("redis");
31
+ var _net = require("net");
32
+ var _Error = require("./Error");
33
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
34
+ const DEFAULT_ALLOWED_HEADERS = exports.DEFAULT_ALLOWED_HEADERS = 'X-Parse-Master-Key, X-Parse-REST-API-Key, X-Parse-Javascript-Key, X-Parse-Application-Id, X-Parse-Client-Version, X-Parse-Session-Token, X-Requested-With, X-Parse-Revocable-Session, X-Parse-Request-Id, Content-Type, Pragma, Cache-Control';
35
+ const getMountForRequest = function (req) {
36
+ const mountPathLength = req.originalUrl.length - req.url.length;
37
+ const mountPath = req.originalUrl.slice(0, mountPathLength);
38
+ return req.protocol + '://' + req.get('host') + mountPath;
39
+ };
40
+ const getBlockList = (ipRangeList, store) => {
41
+ if (store.get('blockList')) {
42
+ return store.get('blockList');
43
+ }
44
+ const blockList = new _net.BlockList();
45
+ ipRangeList.forEach(fullIp => {
46
+ if (fullIp === '::/0' || fullIp === '::') {
47
+ store.set('allowAllIpv6', true);
48
+ return;
49
+ }
50
+ if (fullIp === '0.0.0.0/0' || fullIp === '0.0.0.0') {
51
+ store.set('allowAllIpv4', true);
52
+ return;
53
+ }
54
+ const [ip, mask] = fullIp.split('/');
55
+ if (!mask) {
56
+ blockList.addAddress(ip, (0, _net.isIPv4)(ip) ? 'ipv4' : 'ipv6');
57
+ } else {
58
+ blockList.addSubnet(ip, Number(mask), (0, _net.isIPv4)(ip) ? 'ipv4' : 'ipv6');
59
+ }
60
+ });
61
+ store.set('blockList', blockList);
62
+ return blockList;
63
+ };
64
+ const checkIp = (ip, ipRangeList, store) => {
65
+ const incomingIpIsV4 = (0, _net.isIPv4)(ip);
66
+ const blockList = getBlockList(ipRangeList, store);
67
+ if (store.get(ip)) {
68
+ return true;
69
+ }
70
+ if (store.get('allowAllIpv4') && incomingIpIsV4) {
71
+ return true;
72
+ }
73
+ if (store.get('allowAllIpv6') && !incomingIpIsV4) {
74
+ return true;
75
+ }
76
+ const result = blockList.check(ip, incomingIpIsV4 ? 'ipv4' : 'ipv6');
12
77
 
13
- var _cache = require('./cache');
14
-
15
- var _cache2 = _interopRequireDefault(_cache);
16
-
17
- var _logger = require('./logger');
18
-
19
- var _logger2 = _interopRequireDefault(_logger);
20
-
21
- var _node = require('parse/node');
22
-
23
- var _node2 = _interopRequireDefault(_node);
24
-
25
- var _Auth = require('./Auth');
26
-
27
- var _Auth2 = _interopRequireDefault(_Auth);
28
-
29
- var _Config = require('./Config');
30
-
31
- var _Config2 = _interopRequireDefault(_Config);
32
-
33
- var _ClientSDK = require('./ClientSDK');
34
-
35
- var _ClientSDK2 = _interopRequireDefault(_ClientSDK);
36
-
37
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
78
+ // If the ip is in the list, we store the result in the store
79
+ // so we have a optimized path for the next request
80
+ if (ipRangeList.includes(ip) && result) {
81
+ store.set(ip, result);
82
+ }
83
+ return result;
84
+ };
38
85
 
39
86
  // Checks that the request is authorized for this app and checks user
40
87
  // auth too.
@@ -42,56 +89,67 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
42
89
  // Adds info to the request:
43
90
  // req.config - the Config for this app
44
91
  // req.auth - the Auth for this request
45
- function handleParseHeaders(req, res, next) {
46
- var mountPathLength = req.originalUrl.length - req.url.length;
47
- var mountPath = req.originalUrl.slice(0, mountPathLength);
48
- var mount = req.protocol + '://' + req.get('host') + mountPath;
49
-
92
+ exports.checkIp = checkIp;
93
+ async function handleParseHeaders(req, res, next) {
94
+ var mount = getMountForRequest(req);
95
+ let context = {};
96
+ if (req.get('X-Parse-Cloud-Context') != null) {
97
+ try {
98
+ context = JSON.parse(req.get('X-Parse-Cloud-Context'));
99
+ if (Object.prototype.toString.call(context) !== '[object Object]') {
100
+ throw 'Context is not an object';
101
+ }
102
+ } catch {
103
+ return malformedContext(req, res);
104
+ }
105
+ }
50
106
  var info = {
51
107
  appId: req.get('X-Parse-Application-Id'),
52
108
  sessionToken: req.get('X-Parse-Session-Token'),
53
109
  masterKey: req.get('X-Parse-Master-Key'),
110
+ maintenanceKey: req.get('X-Parse-Maintenance-Key'),
54
111
  installationId: req.get('X-Parse-Installation-Id'),
55
112
  clientKey: req.get('X-Parse-Client-Key'),
56
113
  javascriptKey: req.get('X-Parse-Javascript-Key'),
57
114
  dotNetKey: req.get('X-Parse-Windows-Key'),
58
115
  restAPIKey: req.get('X-Parse-REST-API-Key'),
59
- clientVersion: req.get('X-Parse-Client-Version')
116
+ clientVersion: req.get('X-Parse-Client-Version'),
117
+ context: context
60
118
  };
61
-
62
119
  var basicAuth = httpAuth(req);
63
-
64
120
  if (basicAuth) {
65
121
  var basicAuthAppId = basicAuth.appId;
66
- if (_cache2.default.get(basicAuthAppId)) {
122
+ if (_cache.default.get(basicAuthAppId)) {
67
123
  info.appId = basicAuthAppId;
68
124
  info.masterKey = basicAuth.masterKey || info.masterKey;
69
125
  info.javascriptKey = basicAuth.javascriptKey || info.javascriptKey;
70
126
  }
71
127
  }
72
-
73
128
  if (req.body) {
74
129
  // Unity SDK sends a _noBody key which needs to be removed.
75
130
  // Unclear at this point if action needs to be taken.
76
131
  delete req.body._noBody;
77
132
  }
78
-
79
133
  var fileViaJSON = false;
80
-
81
- if (!info.appId || !_cache2.default.get(info.appId)) {
134
+ if (!info.appId || !_cache.default.get(info.appId)) {
82
135
  // See if we can find the app id on the body.
83
136
  if (req.body instanceof Buffer) {
84
137
  // The only chance to find the app id is if this is a file
85
138
  // upload that actually is a JSON body. So try to parse it.
86
- req.body = JSON.parse(req.body);
139
+ // https://github.com/parse-community/parse-server/issues/6589
140
+ // It is also possible that the client is trying to upload a file but forgot
141
+ // to provide x-parse-app-id in header and parse a binary file will fail
142
+ try {
143
+ req.body = JSON.parse(req.body);
144
+ } catch {
145
+ return invalidRequest(req, res);
146
+ }
87
147
  fileViaJSON = true;
88
148
  }
89
-
90
149
  if (req.body) {
91
150
  delete req.body._RevocableSession;
92
151
  }
93
-
94
- if (req.body && req.body._ApplicationId && _cache2.default.get(req.body._ApplicationId) && (!info.masterKey || _cache2.default.get(req.body._ApplicationId).masterKey === info.masterKey)) {
152
+ if (req.body && req.body._ApplicationId && _cache.default.get(req.body._ApplicationId) && (!info.masterKey || _cache.default.get(req.body._ApplicationId).masterKey === info.masterKey)) {
95
153
  info.appId = req.body._ApplicationId;
96
154
  info.javascriptKey = req.body._JavaScriptKey || '';
97
155
  delete req.body._ApplicationId;
@@ -114,6 +172,21 @@ function handleParseHeaders(req, res, next) {
114
172
  info.masterKey = req.body._MasterKey;
115
173
  delete req.body._MasterKey;
116
174
  }
175
+ if (req.body._context) {
176
+ if (req.body._context instanceof Object) {
177
+ info.context = req.body._context;
178
+ } else {
179
+ try {
180
+ info.context = JSON.parse(req.body._context);
181
+ if (Object.prototype.toString.call(info.context) !== '[object Object]') {
182
+ throw 'Context is not an object';
183
+ }
184
+ } catch {
185
+ return malformedContext(req, res);
186
+ }
187
+ }
188
+ delete req.body._context;
189
+ }
117
190
  if (req.body._ContentType) {
118
191
  req.headers['content-type'] = req.body._ContentType;
119
192
  delete req.body._ContentType;
@@ -122,132 +195,191 @@ function handleParseHeaders(req, res, next) {
122
195
  return invalidRequest(req, res);
123
196
  }
124
197
  }
125
-
198
+ if (info.sessionToken && typeof info.sessionToken !== 'string') {
199
+ info.sessionToken = info.sessionToken.toString();
200
+ }
126
201
  if (info.clientVersion) {
127
- info.clientSDK = _ClientSDK2.default.fromString(info.clientVersion);
202
+ info.clientSDK = _ClientSDK.default.fromString(info.clientVersion);
128
203
  }
129
-
130
- if (fileViaJSON) {
204
+ if (fileViaJSON && req.body) {
205
+ req.fileData = req.body.fileData;
131
206
  // We need to repopulate req.body with a buffer
132
207
  var base64 = req.body.base64;
133
- req.body = new Buffer(base64, 'base64');
208
+ req.body = Buffer.from(base64, 'base64');
134
209
  }
135
-
136
210
  const clientIp = getClientIp(req);
137
-
138
- info.app = _cache2.default.get(info.appId);
139
- req.config = _Config2.default.get(info.appId, mount);
211
+ const config = _Config.default.get(info.appId, mount);
212
+ if (config.state && config.state !== 'ok') {
213
+ res.status(500);
214
+ res.json({
215
+ code: _node.default.Error.INTERNAL_SERVER_ERROR,
216
+ error: `Invalid server state: ${config.state}`
217
+ });
218
+ return;
219
+ }
220
+ await config.loadKeys();
221
+ info.app = _cache.default.get(info.appId);
222
+ req.config = config;
140
223
  req.config.headers = req.headers || {};
141
224
  req.config.ip = clientIp;
142
225
  req.info = info;
143
-
144
- if (info.masterKey && req.config.masterKeyIps && req.config.masterKeyIps.length !== 0 && req.config.masterKeyIps.indexOf(clientIp) === -1) {
145
- return invalidRequest(req, res);
226
+ const isMaintenance = req.config.maintenanceKey && info.maintenanceKey === req.config.maintenanceKey;
227
+ if (isMaintenance) {
228
+ if (checkIp(clientIp, req.config.maintenanceKeyIps || [], req.config.maintenanceKeyIpsStore)) {
229
+ req.auth = new _Auth.default.Auth({
230
+ config: req.config,
231
+ installationId: info.installationId,
232
+ isMaintenance: true
233
+ });
234
+ next();
235
+ return;
236
+ }
237
+ const log = req.config?.loggerController || _logger.default;
238
+ log.error(`Request using maintenance key rejected as the request IP address '${clientIp}' is not set in Parse Server option 'maintenanceKeyIps'.`);
239
+ }
240
+ const masterKey = await req.config.loadMasterKey();
241
+ let isMaster = info.masterKey === masterKey;
242
+ if (isMaster && !checkIp(clientIp, req.config.masterKeyIps || [], req.config.masterKeyIpsStore)) {
243
+ const log = req.config?.loggerController || _logger.default;
244
+ log.error(`Request using master key rejected as the request IP address '${clientIp}' is not set in Parse Server option 'masterKeyIps'.`);
245
+ isMaster = false;
246
+ const error = new Error();
247
+ error.status = 403;
248
+ error.message = `unauthorized`;
249
+ throw error;
146
250
  }
147
-
148
- var isMaster = info.masterKey === req.config.masterKey;
149
-
150
251
  if (isMaster) {
151
- req.auth = new _Auth2.default.Auth({ config: req.config, installationId: info.installationId, isMaster: true });
152
- next();
153
- return;
252
+ req.auth = new _Auth.default.Auth({
253
+ config: req.config,
254
+ installationId: info.installationId,
255
+ isMaster: true
256
+ });
257
+ return handleRateLimit(req, res, next);
154
258
  }
155
-
156
259
  var isReadOnlyMaster = info.masterKey === req.config.readOnlyMasterKey;
157
260
  if (typeof req.config.readOnlyMasterKey != 'undefined' && req.config.readOnlyMasterKey && isReadOnlyMaster) {
158
- req.auth = new _Auth2.default.Auth({ config: req.config, installationId: info.installationId, isMaster: true, isReadOnly: true });
159
- next();
160
- return;
261
+ req.auth = new _Auth.default.Auth({
262
+ config: req.config,
263
+ installationId: info.installationId,
264
+ isMaster: true,
265
+ isReadOnly: true
266
+ });
267
+ return handleRateLimit(req, res, next);
161
268
  }
162
269
 
163
270
  // Client keys are not required in parse-server, but if any have been configured in the server, validate them
164
271
  // to preserve original behavior.
165
- const keys = ["clientKey", "javascriptKey", "dotNetKey", "restAPIKey"];
272
+ const keys = ['clientKey', 'javascriptKey', 'dotNetKey', 'restAPIKey'];
166
273
  const oneKeyConfigured = keys.some(function (key) {
167
274
  return req.config[key] !== undefined;
168
275
  });
169
276
  const oneKeyMatches = keys.some(function (key) {
170
277
  return req.config[key] !== undefined && info[key] === req.config[key];
171
278
  });
172
-
173
279
  if (oneKeyConfigured && !oneKeyMatches) {
174
280
  return invalidRequest(req, res);
175
281
  }
176
-
177
- if (req.url == "/login") {
282
+ if (req.url == '/login') {
178
283
  delete info.sessionToken;
179
284
  }
180
-
285
+ if (req.userFromJWT) {
286
+ req.auth = new _Auth.default.Auth({
287
+ config: req.config,
288
+ installationId: info.installationId,
289
+ isMaster: false,
290
+ user: req.userFromJWT
291
+ });
292
+ return handleRateLimit(req, res, next);
293
+ }
181
294
  if (!info.sessionToken) {
182
- req.auth = new _Auth2.default.Auth({ config: req.config, installationId: info.installationId, isMaster: false });
183
- next();
295
+ req.auth = new _Auth.default.Auth({
296
+ config: req.config,
297
+ installationId: info.installationId,
298
+ isMaster: false
299
+ });
300
+ }
301
+ handleRateLimit(req, res, next);
302
+ }
303
+ const handleRateLimit = async (req, res, next) => {
304
+ const rateLimits = req.config.rateLimits || [];
305
+ try {
306
+ await Promise.all(rateLimits.map(async limit => {
307
+ const pathExp = new RegExp(limit.path);
308
+ if (pathExp.test(req.url)) {
309
+ await limit.handler(req, res, err => {
310
+ if (err) {
311
+ if (err.code === _node.default.Error.CONNECTION_FAILED) {
312
+ throw err;
313
+ }
314
+ req.config.loggerController.error('An unknown error occured when attempting to apply the rate limiter: ', err);
315
+ }
316
+ });
317
+ }
318
+ }));
319
+ } catch (error) {
320
+ res.status(429);
321
+ res.json({
322
+ code: _node.default.Error.CONNECTION_FAILED,
323
+ error: error.message
324
+ });
184
325
  return;
185
326
  }
186
-
187
- return Promise.resolve().then(() => {
188
- // handle the upgradeToRevocableSession path on it's own
327
+ next();
328
+ };
329
+ const handleParseSession = async (req, res, next) => {
330
+ try {
331
+ const info = req.info;
332
+ if (req.auth || req.url === '/sessions/me') {
333
+ next();
334
+ return;
335
+ }
336
+ let requestAuth = null;
189
337
  if (info.sessionToken && req.url === '/upgradeToRevocableSession' && info.sessionToken.indexOf('r:') != 0) {
190
- return _Auth2.default.getAuthForLegacySessionToken({ config: req.config, installationId: info.installationId, sessionToken: info.sessionToken });
338
+ requestAuth = await _Auth.default.getAuthForLegacySessionToken({
339
+ config: req.config,
340
+ installationId: info.installationId,
341
+ sessionToken: info.sessionToken
342
+ });
191
343
  } else {
192
- return _Auth2.default.getAuthForSessionToken({ config: req.config, installationId: info.installationId, sessionToken: info.sessionToken });
344
+ requestAuth = await _Auth.default.getAuthForSessionToken({
345
+ config: req.config,
346
+ installationId: info.installationId,
347
+ sessionToken: info.sessionToken
348
+ });
193
349
  }
194
- }).then(auth => {
195
- if (auth) {
196
- req.auth = auth;
197
- next();
198
- }
199
- }).catch(error => {
200
- if (error instanceof _node2.default.Error) {
350
+ req.auth = requestAuth;
351
+ next();
352
+ } catch (error) {
353
+ if (error instanceof _node.default.Error) {
201
354
  next(error);
202
355
  return;
203
- } else {
204
- // TODO: Determine the correct error scenario.
205
- _logger2.default.error('error getting auth for sessionToken', error);
206
- throw new _node2.default.Error(_node2.default.Error.UNKNOWN_ERROR, error);
207
356
  }
208
- });
209
- }
210
-
211
- function getClientIp(req) {
212
- if (req.headers['x-forwarded-for']) {
213
- // try to get from x-forwared-for if it set (behind reverse proxy)
214
- return req.headers['x-forwarded-for'].split(',')[0];
215
- } else if (req.connection && req.connection.remoteAddress) {
216
- // no proxy, try getting from connection.remoteAddress
217
- return req.connection.remoteAddress;
218
- } else if (req.socket) {
219
- // try to get it from req.socket
220
- return req.socket.remoteAddress;
221
- } else if (req.connection && req.connection.socket) {
222
- // try to get it form the connection.socket
223
- return req.connection.socket.remoteAddress;
224
- } else {
225
- // if non above, fallback.
226
- return req.ip;
357
+ // TODO: Determine the correct error scenario.
358
+ req.config.loggerController.error('error getting auth for sessionToken', error);
359
+ throw new _node.default.Error(_node.default.Error.UNKNOWN_ERROR, error);
227
360
  }
361
+ };
362
+ exports.handleParseSession = handleParseSession;
363
+ function getClientIp(req) {
364
+ return req.ip;
228
365
  }
229
-
230
366
  function httpAuth(req) {
231
- if (!(req.req || req).headers.authorization) return;
232
-
367
+ if (!(req.req || req).headers.authorization) {
368
+ return;
369
+ }
233
370
  var header = (req.req || req).headers.authorization;
234
371
  var appId, masterKey, javascriptKey;
235
372
 
236
373
  // parse header
237
374
  var authPrefix = 'basic ';
238
-
239
375
  var match = header.toLowerCase().indexOf(authPrefix);
240
-
241
376
  if (match == 0) {
242
377
  var encodedAuth = header.substring(authPrefix.length, header.length);
243
378
  var credentials = decodeBase64(encodedAuth).split(':');
244
-
245
379
  if (credentials.length == 2) {
246
380
  appId = credentials[0];
247
381
  var key = credentials[1];
248
-
249
382
  var jsKeyPrefix = 'javascript-key=';
250
-
251
383
  var matchKey = key.indexOf(jsKeyPrefix);
252
384
  if (matchKey == 0) {
253
385
  javascriptKey = key.substring(jsKeyPrefix.length, key.length);
@@ -256,93 +388,285 @@ function httpAuth(req) {
256
388
  }
257
389
  }
258
390
  }
259
-
260
- return { appId: appId, masterKey: masterKey, javascriptKey: javascriptKey };
391
+ return {
392
+ appId: appId,
393
+ masterKey: masterKey,
394
+ javascriptKey: javascriptKey
395
+ };
261
396
  }
262
-
263
397
  function decodeBase64(str) {
264
- return new Buffer(str, 'base64').toString();
398
+ return Buffer.from(str, 'base64').toString();
265
399
  }
266
-
267
- function allowCrossDomain(req, res, next) {
268
- res.header('Access-Control-Allow-Origin', '*');
269
- res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
270
- res.header('Access-Control-Allow-Headers', 'X-Parse-Master-Key, X-Parse-REST-API-Key, X-Parse-Javascript-Key, X-Parse-Application-Id, X-Parse-Client-Version, X-Parse-Session-Token, X-Requested-With, X-Parse-Revocable-Session, Content-Type');
271
- res.header('Access-Control-Expose-Headers', 'X-Parse-Job-Status-Id, X-Parse-Push-Status-Id');
272
- // intercept OPTIONS method
273
- if ('OPTIONS' == req.method) {
274
- res.sendStatus(200);
275
- } else {
276
- next();
277
- }
400
+ function allowCrossDomain(appId) {
401
+ return (req, res, next) => {
402
+ const config = _Config.default.get(appId, getMountForRequest(req));
403
+ let allowHeaders = DEFAULT_ALLOWED_HEADERS;
404
+ if (config && config.allowHeaders) {
405
+ allowHeaders += `, ${config.allowHeaders.join(', ')}`;
406
+ }
407
+ const baseOrigins = typeof config?.allowOrigin === 'string' ? [config.allowOrigin] : config?.allowOrigin ?? ['*'];
408
+ const requestOrigin = req.headers.origin;
409
+ const allowOrigins = requestOrigin && baseOrigins.includes(requestOrigin) ? requestOrigin : baseOrigins[0];
410
+ res.header('Access-Control-Allow-Origin', allowOrigins);
411
+ res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
412
+ res.header('Access-Control-Allow-Headers', allowHeaders);
413
+ res.header('Access-Control-Expose-Headers', 'X-Parse-Job-Status-Id, X-Parse-Push-Status-Id');
414
+ // intercept OPTIONS method
415
+ if ('OPTIONS' == req.method) {
416
+ res.sendStatus(200);
417
+ } else {
418
+ next();
419
+ }
420
+ };
278
421
  }
279
-
280
422
  function allowMethodOverride(req, res, next) {
281
- if (req.method === 'POST' && req.body._method) {
423
+ if (req.method === 'POST' && req.body?._method) {
282
424
  req.originalMethod = req.method;
283
425
  req.method = req.body._method;
284
426
  delete req.body._method;
285
427
  }
286
428
  next();
287
429
  }
288
-
289
430
  function handleParseErrors(err, req, res, next) {
290
- if (err instanceof _node2.default.Error) {
431
+ const log = req.config && req.config.loggerController || _logger.default;
432
+ if (err instanceof _node.default.Error) {
433
+ if (req.config && req.config.enableExpressErrorHandler) {
434
+ return next(err);
435
+ }
291
436
  let httpStatus;
292
437
  // TODO: fill out this mapping
293
438
  switch (err.code) {
294
- case _node2.default.Error.INTERNAL_SERVER_ERROR:
439
+ case _node.default.Error.INTERNAL_SERVER_ERROR:
295
440
  httpStatus = 500;
296
441
  break;
297
- case _node2.default.Error.OBJECT_NOT_FOUND:
442
+ case _node.default.Error.OBJECT_NOT_FOUND:
298
443
  httpStatus = 404;
299
444
  break;
300
445
  default:
301
446
  httpStatus = 400;
302
447
  }
303
-
304
448
  res.status(httpStatus);
305
- res.json({ code: err.code, error: err.message });
306
- _logger2.default.error(err.message, err);
307
- if (req.config && req.config.enableExpressErrorHandler) {
308
- next(err);
309
- }
449
+ res.json({
450
+ code: err.code,
451
+ error: err.message
452
+ });
453
+ log.error('Parse error: ', err);
310
454
  } else if (err.status && err.message) {
311
455
  res.status(err.status);
312
- res.json({ error: err.message });
313
- next(err);
456
+ res.json({
457
+ error: err.message
458
+ });
459
+ if (!(process && process.env.TESTING)) {
460
+ next(err);
461
+ }
314
462
  } else {
315
- _logger2.default.error('Uncaught internal server error.', err, err.stack);
463
+ log.error('Uncaught internal server error.', err, err.stack);
316
464
  res.status(500);
317
465
  res.json({
318
- code: _node2.default.Error.INTERNAL_SERVER_ERROR,
466
+ code: _node.default.Error.INTERNAL_SERVER_ERROR,
319
467
  message: 'Internal server error.'
320
468
  });
321
- next(err);
469
+ if (!(process && process.env.TESTING)) {
470
+ next(err);
471
+ }
322
472
  }
323
473
  }
324
-
325
474
  function enforceMasterKeyAccess(req, res, next) {
326
475
  if (!req.auth.isMaster) {
327
- res.status(403);
328
- res.end('{"error":"unauthorized: master key is required"}');
476
+ const error = (0, _Error.createSanitizedHttpError)(403, 'unauthorized: master key is required', req.config);
477
+ res.status(error.status);
478
+ res.end(`{"error":"${error.message}"}`);
329
479
  return;
330
480
  }
331
481
  next();
332
482
  }
333
-
334
483
  function promiseEnforceMasterKeyAccess(request) {
335
484
  if (!request.auth.isMaster) {
336
- const error = new Error();
337
- error.status = 403;
338
- error.message = "unauthorized: master key is required";
339
- throw error;
485
+ throw (0, _Error.createSanitizedHttpError)(403, 'unauthorized: master key is required', request.config);
340
486
  }
341
487
  return Promise.resolve();
342
488
  }
343
-
489
+ const addRateLimit = (route, config, cloud) => {
490
+ if (typeof config === 'string') {
491
+ config = _Config.default.get(config);
492
+ }
493
+ for (const key in route) {
494
+ if (!_Definitions.RateLimitOptions[key]) {
495
+ throw `Invalid rate limit option "${key}"`;
496
+ }
497
+ }
498
+ if (!config.rateLimits) {
499
+ config.rateLimits = [];
500
+ }
501
+ const redisStore = {
502
+ connectionPromise: Promise.resolve(),
503
+ store: null
504
+ };
505
+ if (route.redisUrl) {
506
+ const log = config?.loggerController || _logger.default;
507
+ const client = (0, _redis.createClient)({
508
+ url: route.redisUrl
509
+ });
510
+ client.on('error', err => {
511
+ log.error('Middlewares addRateLimit Redis client error', {
512
+ error: err
513
+ });
514
+ });
515
+ client.on('connect', () => {});
516
+ client.on('reconnecting', () => {});
517
+ client.on('ready', () => {});
518
+ redisStore.connectionPromise = async () => {
519
+ if (client.isOpen) {
520
+ return;
521
+ }
522
+ try {
523
+ await client.connect();
524
+ } catch (e) {
525
+ log.error(`Could not connect to redisURL in rate limit: ${e}`);
526
+ }
527
+ };
528
+ redisStore.connectionPromise();
529
+ redisStore.store = new _rateLimitRedis.default({
530
+ sendCommand: async (...args) => {
531
+ await redisStore.connectionPromise();
532
+ return client.sendCommand(args);
533
+ }
534
+ });
535
+ }
536
+ let transformPath = route.requestPath.split('/*').join('/(.*)');
537
+ if (transformPath === '*') {
538
+ transformPath = '(.*)';
539
+ }
540
+ config.rateLimits.push({
541
+ path: (0, _pathToRegexp.pathToRegexp)(transformPath),
542
+ handler: (0, _expressRateLimit.default)({
543
+ windowMs: route.requestTimeWindow,
544
+ max: route.requestCount,
545
+ message: route.errorResponseMessage || _Definitions.RateLimitOptions.errorResponseMessage.default,
546
+ handler: (request, response, next, options) => {
547
+ throw {
548
+ code: _node.default.Error.CONNECTION_FAILED,
549
+ message: options.message
550
+ };
551
+ },
552
+ skip: request => {
553
+ if (request.ip === '127.0.0.1' && !route.includeInternalRequests) {
554
+ return true;
555
+ }
556
+ if (route.includeMasterKey) {
557
+ return false;
558
+ }
559
+ if (route.requestMethods) {
560
+ if (Array.isArray(route.requestMethods)) {
561
+ if (!route.requestMethods.includes(request.method)) {
562
+ return true;
563
+ }
564
+ } else {
565
+ const regExp = new RegExp(route.requestMethods);
566
+ if (!regExp.test(request.method)) {
567
+ return true;
568
+ }
569
+ }
570
+ }
571
+ return request.auth?.isMaster;
572
+ },
573
+ keyGenerator: async request => {
574
+ if (route.zone === _node.default.Server.RateLimitZone.global) {
575
+ return request.config.appId;
576
+ }
577
+ const token = request.info.sessionToken;
578
+ if (route.zone === _node.default.Server.RateLimitZone.session && token) {
579
+ return token;
580
+ }
581
+ if (route.zone === _node.default.Server.RateLimitZone.user && token) {
582
+ if (!request.auth) {
583
+ await new Promise(resolve => handleParseSession(request, null, resolve));
584
+ }
585
+ if (request.auth?.user?.id && request.zone === 'user') {
586
+ return request.auth.user.id;
587
+ }
588
+ }
589
+ return request.config.ip;
590
+ },
591
+ store: redisStore.store
592
+ }),
593
+ cloud
594
+ });
595
+ _Config.default.put(config);
596
+ };
597
+
598
+ /**
599
+ * Deduplicates a request to ensure idempotency. Duplicates are determined by the request ID
600
+ * in the request header. If a request has no request ID, it is executed anyway.
601
+ * @param {*} req The request to evaluate.
602
+ * @returns Promise<{}>
603
+ */
604
+ exports.addRateLimit = addRateLimit;
605
+ function promiseEnsureIdempotency(req) {
606
+ // Enable feature only for MongoDB
607
+ if (!(req.config.database.adapter instanceof _MongoStorageAdapter.default || req.config.database.adapter instanceof _PostgresStorageAdapter.default)) {
608
+ return Promise.resolve();
609
+ }
610
+ // Get parameters
611
+ const config = req.config;
612
+ const requestId = ((req || {}).headers || {})['x-parse-request-id'];
613
+ const {
614
+ paths,
615
+ ttl
616
+ } = config.idempotencyOptions;
617
+ if (!requestId || !config.idempotencyOptions) {
618
+ return Promise.resolve();
619
+ }
620
+ // Request path may contain trailing slashes, depending on the original request, so remove
621
+ // leading and trailing slashes to make it easier to specify paths in the configuration
622
+ const reqPath = req.path.replace(/^\/|\/$/, '');
623
+ // Determine whether idempotency is enabled for current request path
624
+ let match = false;
625
+ for (const path of paths) {
626
+ // Assume one wants a path to always match from the beginning to prevent any mistakes
627
+ const regex = new RegExp(path.charAt(0) === '^' ? path : '^' + path);
628
+ if (reqPath.match(regex)) {
629
+ match = true;
630
+ break;
631
+ }
632
+ }
633
+ if (!match) {
634
+ return Promise.resolve();
635
+ }
636
+ // Try to store request
637
+ const expiryDate = new Date(new Date().setSeconds(new Date().getSeconds() + ttl));
638
+ return _rest.default.create(config, _Auth.default.master(config), '_Idempotency', {
639
+ reqId: requestId,
640
+ expire: _node.default._encode(expiryDate)
641
+ }).catch(e => {
642
+ if (e.code == _node.default.Error.DUPLICATE_VALUE) {
643
+ throw new _node.default.Error(_node.default.Error.DUPLICATE_REQUEST, 'Duplicate request');
644
+ }
645
+ throw e;
646
+ });
647
+ }
344
648
  function invalidRequest(req, res) {
345
649
  res.status(403);
346
650
  res.end('{"error":"unauthorized"}');
347
651
  }
348
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9taWRkbGV3YXJlcy5qcyJdLCJuYW1lcyI6WyJoYW5kbGVQYXJzZUhlYWRlcnMiLCJhbGxvd0Nyb3NzRG9tYWluIiwiYWxsb3dNZXRob2RPdmVycmlkZSIsImhhbmRsZVBhcnNlRXJyb3JzIiwiZW5mb3JjZU1hc3RlcktleUFjY2VzcyIsInByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzIiwicmVxIiwicmVzIiwibmV4dCIsIm1vdW50UGF0aExlbmd0aCIsIm9yaWdpbmFsVXJsIiwibGVuZ3RoIiwidXJsIiwibW91bnRQYXRoIiwic2xpY2UiLCJtb3VudCIsInByb3RvY29sIiwiZ2V0IiwiaW5mbyIsImFwcElkIiwic2Vzc2lvblRva2VuIiwibWFzdGVyS2V5IiwiaW5zdGFsbGF0aW9uSWQiLCJjbGllbnRLZXkiLCJqYXZhc2NyaXB0S2V5IiwiZG90TmV0S2V5IiwicmVzdEFQSUtleSIsImNsaWVudFZlcnNpb24iLCJiYXNpY0F1dGgiLCJodHRwQXV0aCIsImJhc2ljQXV0aEFwcElkIiwiQXBwQ2FjaGUiLCJib2R5IiwiX25vQm9keSIsImZpbGVWaWFKU09OIiwiQnVmZmVyIiwiSlNPTiIsInBhcnNlIiwiX1Jldm9jYWJsZVNlc3Npb24iLCJfQXBwbGljYXRpb25JZCIsIl9KYXZhU2NyaXB0S2V5IiwiX0NsaWVudFZlcnNpb24iLCJfSW5zdGFsbGF0aW9uSWQiLCJfU2Vzc2lvblRva2VuIiwiX01hc3RlcktleSIsIl9Db250ZW50VHlwZSIsImhlYWRlcnMiLCJpbnZhbGlkUmVxdWVzdCIsImNsaWVudFNESyIsIkNsaWVudFNESyIsImZyb21TdHJpbmciLCJiYXNlNjQiLCJjbGllbnRJcCIsImdldENsaWVudElwIiwiYXBwIiwiY29uZmlnIiwiQ29uZmlnIiwiaXAiLCJtYXN0ZXJLZXlJcHMiLCJpbmRleE9mIiwiaXNNYXN0ZXIiLCJhdXRoIiwiQXV0aCIsImlzUmVhZE9ubHlNYXN0ZXIiLCJyZWFkT25seU1hc3RlcktleSIsImlzUmVhZE9ubHkiLCJrZXlzIiwib25lS2V5Q29uZmlndXJlZCIsInNvbWUiLCJrZXkiLCJ1bmRlZmluZWQiLCJvbmVLZXlNYXRjaGVzIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ0aGVuIiwiZ2V0QXV0aEZvckxlZ2FjeVNlc3Npb25Ub2tlbiIsImdldEF1dGhGb3JTZXNzaW9uVG9rZW4iLCJjYXRjaCIsImVycm9yIiwiUGFyc2UiLCJFcnJvciIsImxvZyIsIlVOS05PV05fRVJST1IiLCJzcGxpdCIsImNvbm5lY3Rpb24iLCJyZW1vdGVBZGRyZXNzIiwic29ja2V0IiwiYXV0aG9yaXphdGlvbiIsImhlYWRlciIsImF1dGhQcmVmaXgiLCJtYXRjaCIsInRvTG93ZXJDYXNlIiwiZW5jb2RlZEF1dGgiLCJzdWJzdHJpbmciLCJjcmVkZW50aWFscyIsImRlY29kZUJhc2U2NCIsImpzS2V5UHJlZml4IiwibWF0Y2hLZXkiLCJzdHIiLCJ0b1N0cmluZyIsIm1ldGhvZCIsInNlbmRTdGF0dXMiLCJfbWV0aG9kIiwib3JpZ2luYWxNZXRob2QiLCJlcnIiLCJodHRwU3RhdHVzIiwiY29kZSIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsIk9CSkVDVF9OT1RfRk9VTkQiLCJzdGF0dXMiLCJqc29uIiwibWVzc2FnZSIsImVuYWJsZUV4cHJlc3NFcnJvckhhbmRsZXIiLCJzdGFjayIsImVuZCIsInJlcXVlc3QiXSwibWFwcGluZ3MiOiI7Ozs7O1FBYWdCQSxrQixHQUFBQSxrQjtRQXdPQUMsZ0IsR0FBQUEsZ0I7UUFjQUMsbUIsR0FBQUEsbUI7UUFTQUMsaUIsR0FBQUEsaUI7UUFxQ0FDLHNCLEdBQUFBLHNCO1FBU0FDLDZCLEdBQUFBLDZCOztBQTFUaEI7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7Ozs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTTCxrQkFBVCxDQUE0Qk0sR0FBNUIsRUFBaUNDLEdBQWpDLEVBQXNDQyxJQUF0QyxFQUE0QztBQUNqRCxNQUFJQyxrQkFBa0JI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LEVBQUVoQyxPQUFPMEIsSUFBSU8sT0FBYixFQUFUO0FBQ0F2RyxTQUFLZ0csR0FBTDtBQUNELEdBSk0sTUFJQTtBQUNMdkIscUJBQUlILEtBQUosQ0FBVSxpQ0FBVixFQUE2QzBCLEdBQTdDLEVBQWtEQSxJQUFJUyxLQUF0RDtBQUNBMUcsUUFBSXNHLE1BQUosQ0FBVyxHQUFYO0FBQ0F0RyxRQUFJdUcsSUFBSixDQUFTO0FBQ1BKLFlBQU0zQixlQUFNQyxLQUFOLENBQVkyQixxQkFEWDtBQUVQSSxlQUFTO0FBRkYsS0FBVDtBQUlBdkcsU0FBS2dHLEdBQUw7QUFDRDtBQUVGOztBQUVNLFNBQVNwRyxzQkFBVCxDQUFnQ0UsR0FBaEMsRUFBcUNDLEdBQXJDLEVBQTBDQyxJQUExQyxFQUFnRDtBQUNyRCxNQUFJLENBQUNGLElBQUl1RCxJQUFKLENBQVNELFFBQWQsRUFBd0I7QUFDdEJyRCxRQUFJc0csTUFBSixDQUFXLEdBQVg7QUFDQXRHLFFBQUkyRyxHQUFKLENBQVEsa0RBQVI7QUFDQTtBQUNEO0FBQ0QxRztBQUNEOztBQUVNLFNBQVNILDZCQUFULENBQXVDOEcsT0FBdkMsRUFBZ0Q7QUFDckQsTUFBSSxDQUFDQSxRQUFRdEQsSUFBUixDQUFhRCxRQUFsQixFQUE0QjtBQUMxQixVQUFNa0IsUUFBUSxJQUFJRSxLQUFKLEVBQWQ7QUFDQUYsVUFBTStCLE1BQU4sR0FBZSxHQUFmO0FBQ0EvQixVQUFNaUMsT0FBTixHQUFnQixzQ0FBaEI7QUFDQSxVQUFNakMsS0FBTjtBQUNEO0FBQ0QsU0FBT04sUUFBUUMsT0FBUixFQUFQO0FBQ0Q7O0FBRUQsU0FBUzFCLGNBQVQsQ0FBd0J6QyxHQUF4QixFQUE2QkMsR0FBN0IsRUFBa0M7QUFDaENBLE1BQUlzRyxNQUFKLENBQVcsR0FBWDtBQUNBdEcsTUFBSTJHLEdBQUosQ0FBUSwwQkFBUjtBQUNEIiwiZmlsZSI6Im1pZGRsZXdhcmVzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFwcENhY2hlIGZyb20gJy4vY2FjaGUnO1xuaW1wb3J0IGxvZyBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgYXV0aCBmcm9tICcuL0F1dGgnO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuL0NvbmZpZyc7XG5pbXBvcnQgQ2xpZW50U0RLIGZyb20gJy4vQ2xpZW50U0RLJztcblxuLy8gQ2hlY2tzIHRoYXQgdGhlIHJlcXVlc3QgaXMgYXV0aG9yaXplZCBmb3IgdGhpcyBhcHAgYW5kIGNoZWNrcyB1c2VyXG4vLyBhdXRoIHRvby5cbi8vIFRoZSBib2R5cGFyc2VyIHNob3VsZCBydW4gYmVmb3JlIHRoaXMgbWlkZGxld2FyZS5cbi8vIEFkZHMgaW5mbyB0byB0aGUgcmVxdWVzdDpcbi8vIHJlcS5jb25maWcgLSB0aGUgQ29uZmlnIGZvciB0aGlzIGFwcFxuLy8gcmVxLmF1dGggLSB0aGUgQXV0aCBmb3IgdGhpcyByZXF1ZXN0XG5leHBvcnQgZnVuY3Rpb24gaGFuZGxlUGFyc2VIZWFkZXJzKHJlcSwgcmVzLCBuZXh0KSB7XG4gIHZhciBtb3VudFBhdGhMZW5ndGggPSByZXEub3JpZ2luYWxVcmwubGVuZ3RoIC0gcmVxLnVybC5sZW5ndGg7XG4gIHZhciBtb3VudFBhdGggPSByZXEub3JpZ2luYWxVcmwuc2xpY2UoMCwgbW91bnRQYXRoTGVuZ3RoKTtcbiAgdmFyIG1vdW50ID0gcmVxLnByb3RvY29sICsgJzovLycgKyByZXEuZ2V0KCdob3N0JykgKyBtb3VudFBhdGg7XG5cbiAgdmFyIGluZm8gPSB7XG4gICAgYXBwSWQ6IHJlcS5nZXQoJ1gtUGFyc2UtQXBwbGljYXRpb24tSWQnKSxcbiAgICBzZXNzaW9uVG9rZW46IHJlcS5nZXQoJ1gtUGFyc2UtU2Vzc2lvbi1Ub2tlbicpLFxuICAgIG1hc3RlcktleTogcmVxLmdldCgnWC1QYXJzZS1NYXN0ZXItS2V5JyksXG4gICAgaW5zdGFsbGF0aW9uSWQ6IHJlcS5nZXQoJ1gtUGFyc2UtSW5zdGFsbGF0aW9uLUlkJyksXG4gICAgY2xpZW50S2V5OiByZXEuZ2V0KCdYLVBhcnNlLUNsaWVudC1LZXknKSxcbiAgICBqYXZhc2NyaXB0S2V5OiByZXEuZ2V0KCdYLVBhcnNlLUphdmFzY3JpcHQtS2V5JyksXG4gICAgZG90TmV0S2V5OiByZXEuZ2V0KCdYLVBhcnNlLVdpbmRvd3MtS2V5JyksXG4gICAgcmVzdEFQSUtleTogcmVxLmdldCgnWC1QYXJzZS1SRVNULUFQSS1LZXknKSxcbiAgICBjbGllbnRWZXJzaW9uOiByZXEuZ2V0KCdYLVBhcnNlLUNsaWVudC1WZXJzaW9uJylcbiAgfTtcblxuICB2YXIgYmFzaWNBdXRoID0gaHR0cEF1dGgocmVxKTtcblxuICBpZiAoYmFzaWNBdXRoKSB7XG4gICAgdmFyIGJhc2ljQXV0aEFwcElkID0gYmFzaWNBdXRoLmFwcElkO1xuICAgIGlmIChBcHBDYWNoZS5nZXQoYmFzaWNBdXRoQXBwSWQpKSB7XG4gICAgICBpbmZvLmFwcElkID0gYmFzaWNBdXRoQXBwSWQ7XG4gICAgICBpbmZvLm1hc3RlcktleSA9IGJhc2ljQXV0aC5tYXN0ZXJLZXkgfHwgaW5mby5tYXN0ZXJLZXk7XG4gICAgICBpbmZvLmphdmFzY3JpcHRLZXkgPSBiYXNpY0F1dGguamF2YXNjcmlwdEtleSB8fCBpbmZvLmphdmFzY3JpcHRLZXk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHJlcS5ib2R5KSB7XG4gICAgLy8gVW5pdHkgU0RLIHNlbmRzIGEgX25vQm9keSBrZXkgd2hpY2ggbmVlZHMgdG8gYmUgcmVtb3ZlZC5cbiAgICAvLyBVbmNsZWFyIGF0IHRoaXMgcG9pbnQgaWYgYWN0aW9uIG5lZWRzIHRvIGJlIHRha2VuLlxuICAgIGRlbGV0ZSByZXEuYm9keS5fbm9Cb2R5O1xuICB9XG5cbiAgdmFyIGZpbGVWaWFKU09OID0gZmFsc2U7XG5cbiAgaWYgKCFpbmZvLmFwcElkIHx8ICFBcHBDYWNoZS5nZXQoaW5mby5hcHBJZCkpIHtcbiAgICAvLyBTZWUgaWYgd2UgY2FuIGZpbmQgdGhlIGFwcCBpZCBvbiB0aGUgYm9keS5cbiAgICBpZiAocmVxLmJvZHkgaW5zdGFuY2VvZiBCdWZmZXIpIHtcbiAgICAgIC8vIFRoZSBvbmx5IGNoYW5jZSB0byBmaW5kIHRoZSBhcHAgaWQgaXMgaWYgdGhpcyBpcyBhIGZpbGVcbiAgICAgIC8vIHVwbG9hZCB0aGF0IGFjdHVhbGx5IGlzIGEgSlNPTiBib2R5LiBTbyB0cnkgdG8gcGFyc2UgaXQuXG4gICAgICByZXEuYm9keSA9IEpTT04ucGFyc2UocmVxLmJvZHkpO1xuICAgICAgZmlsZVZpYUpTT04gPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChyZXEuYm9keSkge1xuICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9SZXZvY2FibGVTZXNzaW9uO1xuICAgIH1cblxuICAgIGlmIChyZXEuYm9keSAmJlxuICAgICAgcmVxLmJvZHkuX0FwcGxpY2F0aW9uSWQgJiZcbiAgICAgIEFwcENhY2hlLmdldChyZXEuYm9keS5fQXBwbGljYXRpb25JZCkgJiZcbiAgICAgICghaW5mby5tYXN0ZXJLZXkgfHwgQXBwQ2FjaGUuZ2V0KHJlcS5ib2R5Ll9BcHBsaWNhdGlvbklkKS5tYXN0ZXJLZXkgPT09IGluZm8ubWFzdGVyS2V5KVxuICAgICkge1xuICAgICAgaW5mby5hcHBJZCA9IHJlcS5ib2R5Ll9BcHBsaWNhdGlvbklkO1xuICAgICAgaW5mby5qYXZhc2NyaXB0S2V5ID0gcmVxLmJvZHkuX0phdmFTY3JpcHRLZXkgfHwgJyc7XG4gICAgICBkZWxldGUgcmVxLmJvZHkuX0FwcGxpY2F0aW9uSWQ7XG4gICAgICBkZWxldGUgcmVxLmJvZHkuX0phdmFTY3JpcHRLZXk7XG4gICAgICAvLyBUT0RPOiB0ZXN0IHRoYXQgdGhlIFJFU1QgQVBJIGZvcm1hdHMgZ2VuZXJhdGVkIGJ5IHRoZSBvdGhlclxuICAgICAgLy8gU0RLcyBhcmUgaGFuZGxlZCBva1xuICAgICAgaWYgKHJlcS5ib2R5Ll9DbGllbnRWZXJzaW9uKSB7XG4gICAgICAgIGluZm8uY2xpZW50VmVyc2lvbiA9IHJlcS5ib2R5Ll9DbGllbnRWZXJzaW9uO1xuICAgICAgICBkZWxldGUgcmVxLmJvZHkuX0NsaWVudFZlcnNpb247XG4gICAgICB9XG4gICAgICBpZiAocmVxLmJvZHkuX0luc3RhbGxhdGlvbklkKSB7XG4gICAgICAgIGluZm8uaW5zdGFsbGF0aW9uSWQgPSByZXEuYm9keS5fSW5zdGFsbGF0aW9uSWQ7XG4gICAgICAgIGRlbGV0ZSByZXEuYm9keS5fSW5zdGFsbGF0aW9uSWQ7XG4gICAgICB9XG4gICAgICBpZiAocmVxLmJvZHkuX1Nlc3Npb25Ub2tlbikge1xuICAgICAgICBpbmZvLnNlc3Npb25Ub2tlbiA9IHJlcS5ib2R5Ll9TZXNzaW9uVG9rZW47XG4gICAgICAgIGRlbGV0ZSByZXEuYm9keS5fU2Vzc2lvblRva2VuO1xuICAgICAgfVxuICAgICAgaWYgKHJlcS5ib2R5Ll9NYXN0ZXJLZXkpIHtcbiAgICAgICAgaW5mby5tYXN0ZXJLZXkgPSByZXEuYm9keS5fTWFzdGVyS2V5O1xuICAgICAgICBkZWxldGUgcmVxLmJvZHkuX01hc3RlcktleTtcbiAgICAgIH1cbiAgICAgIGlmIChyZXEuYm9keS5fQ29udGVudFR5cGUpIHtcbiAgICAgICAgcmVxLmhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddID0gcmVxLmJvZHkuX0NvbnRlbnRUeXBlO1xuICAgICAgICBkZWxldGUgcmVxLmJvZHkuX0NvbnRlbnRUeXBlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gaW52YWxpZFJlcXVlc3QocmVxLCByZXMpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChpbmZvLmNsaWVudFZlcnNpb24pIHtcbiAgICBpbmZvLmNsaWVudFNESyA9IENsaWVudFNESy5mcm9tU3RyaW5nKGluZm8uY2xpZW50VmVyc2lvbik7XG4gIH1cblxuICBpZiAoZmlsZVZpYUpTT04pIHtcbiAgICAvLyBXZSBuZWVkIHRvIHJlcG9wdWxhdGUgcmVxLmJvZHkgd2l0aCBhIGJ1ZmZlclxuICAgIHZhciBiYXNlNjQgPSByZXEuYm9keS5iYXNlNjQ7XG4gICAgcmVxLmJvZHkgPSBuZXcgQnVmZmVyKGJhc2U2NCwgJ2Jhc2U2NCcpO1xuICB9XG5cbiAgY29uc3QgY2xpZW50SXAgPSBnZXRDbGllbnRJcChyZXEpO1xuXG4gIGluZm8uYXBwID0gQXBwQ2FjaGUuZ2V0KGluZm8uYXBwSWQpO1xuICByZXEuY29uZmlnID0gQ29uZmlnLmdldChpbmZvLmFwcElkLCBtb3VudCk7XG4gIHJlcS5jb25maWcuaGVhZGVycyA9IHJlcS5oZWFkZXJzIHx8IHt9O1xuICByZXEuY29uZmlnLmlwID0gY2xpZW50SXA7XG4gIHJlcS5pbmZvID0gaW5mbztcblxuICBpZiAoaW5mby5tYXN0ZXJLZXkgJiYgcmVxLmNvbmZpZy5tYXN0ZXJLZXlJcHMgJiYgcmVxLmNvbmZpZy5tYXN0ZXJLZXlJcHMubGVuZ3RoICE9PSAwICYmIHJlcS5jb25maWcubWFzdGVyS2V5SXBzLmluZGV4T2YoY2xpZW50SXApID09PSAtMSkge1xuICAgIHJldHVybiBpbnZhbGlkUmVxdWVzdChyZXEsIHJlcyk7XG4gIH1cblxuICB2YXIgaXNNYXN0ZXIgPSAoaW5mby5tYXN0ZXJLZXkgPT09IHJlcS5jb25maWcubWFzdGVyS2V5KTtcblxuICBpZiAoaXNNYXN0ZXIpIHtcbiAgICByZXEuYXV0aCA9IG5ldyBhdXRoLkF1dGgoeyBjb25maWc6IHJlcS5jb25maWcsIGluc3RhbGxhdGlvbklkOiBpbmZvLmluc3RhbGxhdGlvbklkLCBpc01hc3RlcjogdHJ1ZSB9KTtcbiAgICBuZXh0KCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGlzUmVhZE9ubHlNYXN0ZXIgPSAoaW5mby5tYXN0ZXJLZXkgPT09IHJlcS5jb25maWcucmVhZE9ubHlNYXN0ZXJLZXkpO1xuICBpZiAodHlwZW9mIHJlcS5jb25maWcucmVhZE9ubHlNYXN0ZXJLZXkgIT0gJ3VuZGVmaW5lZCcgJiYgcmVxLmNvbmZpZy5yZWFkT25seU1hc3RlcktleSAmJiBpc1JlYWRPbmx5TWFzdGVyKSB7XG4gICAgcmVxLmF1dGggPSBuZXcgYXV0aC5BdXRoKHsgY29uZmlnOiByZXEuY29uZmlnLCBpbnN0YWxsYXRpb25JZDogaW5mby5pbnN0YWxsYXRpb25JZCwgaXNNYXN0ZXI6IHRydWUsIGlzUmVhZE9ubHk6IHRydWUgfSk7XG4gICAgbmV4dCgpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIENsaWVudCBrZXlzIGFyZSBub3QgcmVxdWlyZWQgaW4gcGFyc2Utc2VydmVyLCBidXQgaWYgYW55IGhhdmUgYmVlbiBjb25maWd1cmVkIGluIHRoZSBzZXJ2ZXIsIHZhbGlkYXRlIHRoZW1cbiAgLy8gIHRvIHByZXNlcnZlIG9yaWdpbmFsIGJlaGF2aW9yLlxuICBjb25zdCBrZXlzID0gW1wiY2xpZW50S2V5XCIsIFwiamF2YXNjcmlwdEtleVwiLCBcImRvdE5ldEtleVwiLCBcInJlc3RBUElLZXlcIl07XG4gIGNvbnN0IG9uZUtleUNvbmZpZ3VyZWQgPSBrZXlzLnNvbWUoZnVuY3Rpb24oa2V5KSB7XG4gICAgcmV0dXJuIHJlcS5jb25maWdba2V5XSAhPT0gdW5kZWZpbmVkO1xuICB9KTtcbiAgY29uc3Qgb25lS2V5TWF0Y2hlcyA9IGtleXMuc29tZShmdW5jdGlvbihrZXkpe1xuICAgIHJldHVybiByZXEuY29uZmlnW2tleV0gIT09IHVuZGVmaW5lZCAmJiBpbmZvW2tleV0gPT09IHJlcS5jb25maWdba2V5XTtcbiAgfSk7XG5cbiAgaWYgKG9uZUtleUNvbmZpZ3VyZWQgJiYgIW9uZUtleU1hdGNoZXMpIHtcbiAgICByZXR1cm4gaW52YWxpZFJlcXVlc3QocmVxLCByZXMpO1xuICB9XG5cbiAgaWYgKHJlcS51cmwgPT0gXCIvbG9naW5cIikge1xuICAgIGRlbGV0ZSBpbmZvLnNlc3Npb25Ub2tlbjtcbiAgfVxuXG4gIGlmICghaW5mby5zZXNzaW9uVG9rZW4pIHtcbiAgICByZXEuYXV0aCA9IG5ldyBhdXRoLkF1dGgoeyBjb25maWc6IHJlcS5jb25maWcsIGluc3RhbGxhdGlvbklkOiBpbmZvLmluc3RhbGxhdGlvbklkLCBpc01hc3RlcjogZmFsc2UgfSk7XG4gICAgbmV4dCgpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHtcbiAgICAvLyBoYW5kbGUgdGhlIHVwZ3JhZGVUb1Jldm9jYWJsZVNlc3Npb24gcGF0aCBvbiBpdCdzIG93blxuICAgIGlmIChpbmZvLnNlc3Npb25Ub2tlbiAmJlxuICAgICAgICByZXEudXJsID09PSAnL3VwZ3JhZGVUb1Jldm9jYWJsZVNlc3Npb24nICYmXG4gICAgICAgIGluZm8uc2Vzc2lvblRva2VuLmluZGV4T2YoJ3I6JykgIT0gMCkge1xuICAgICAgcmV0dXJuIGF1dGguZ2V0QXV0aEZvckxlZ2FjeVNlc3Npb25Ub2tlbih7IGNvbmZpZzogcmVxLmNvbmZpZywgaW5zdGFsbGF0aW9uSWQ6IGluZm8uaW5zdGFsbGF0aW9uSWQsIHNlc3Npb25Ub2tlbjogaW5mby5zZXNzaW9uVG9rZW4gfSlcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGF1dGguZ2V0QXV0aEZvclNlc3Npb25Ub2tlbih7IGNvbmZpZzogcmVxLmNvbmZpZywgaW5zdGFsbGF0aW9uSWQ6IGluZm8uaW5zdGFsbGF0aW9uSWQsIHNlc3Npb25Ub2tlbjogaW5mby5zZXNzaW9uVG9rZW4gfSlcbiAgICB9XG4gIH0pLnRoZW4oKGF1dGgpID0+IHtcbiAgICBpZiAoYXV0aCkge1xuICAgICAgcmVxLmF1dGggPSBhdXRoO1xuICAgICAgbmV4dCgpO1xuICAgIH1cbiAgfSlcbiAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICBpZihlcnJvciBpbnN0YW5jZW9mIFBhcnNlLkVycm9yKSB7XG4gICAgICAgIG5leHQoZXJyb3IpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgLy8gVE9ETzogRGV0ZXJtaW5lIHRoZSBjb3JyZWN0IGVycm9yIHNjZW5hcmlvLlxuICAgICAgICBsb2cuZXJyb3IoJ2Vycm9yIGdldHRpbmcgYXV0aCBmb3Igc2Vzc2lvblRva2VuJywgZXJyb3IpO1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuVU5LTk9XTl9FUlJPUiwgZXJyb3IpO1xuICAgICAgfVxuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBnZXRDbGllbnRJcChyZXEpe1xuICBpZiAocmVxLmhlYWRlcnNbJ3gtZm9yd2FyZGVkLWZvciddKSB7XG4gICAgLy8gdHJ5IHRvIGdldCBmcm9tIHgtZm9yd2FyZWQtZm9yIGlmIGl0IHNldCAoYmVoaW5kIHJldmVyc2UgcHJveHkpXG4gICAgcmV0dXJuIHJlcS5oZWFkZXJzWyd4LWZvcndhcmRlZC1mb3InXS5zcGxpdCgnLCcpWzBdO1xuICB9IGVsc2UgaWYgKHJlcS5jb25uZWN0aW9uICYmIHJlcS5jb25uZWN0aW9uLnJlbW90ZUFkZHJlc3MpIHtcbiAgICAvLyBubyBwcm94eSwgdHJ5IGdldHRpbmcgZnJvbSBjb25uZWN0aW9uLnJlbW90ZUFkZHJlc3NcbiAgICByZXR1cm4gcmVxLmNvbm5lY3Rpb24ucmVtb3RlQWRkcmVzcztcbiAgfSBlbHNlIGlmIChyZXEuc29ja2V0KSB7XG4gICAgLy8gdHJ5IHRvIGdldCBpdCBmcm9tIHJlcS5zb2NrZXRcbiAgICByZXR1cm4gcmVxLnNvY2tldC5yZW1vdGVBZGRyZXNzO1xuICB9IGVsc2UgaWYgKHJlcS5jb25uZWN0aW9uICYmIHJlcS5jb25uZWN0aW9uLnNvY2tldCkge1xuICAgIC8vIHRyeSB0byBnZXQgaXQgZm9ybSB0aGUgY29ubmVjdGlvbi5zb2NrZXRcbiAgICByZXR1cm4gcmVxLmNvbm5lY3Rpb24uc29ja2V0LnJlbW90ZUFkZHJlc3M7XG4gIH0gZWxzZSB7XG4gICAgLy8gaWYgbm9uIGFib3ZlLCBmYWxsYmFjay5cbiAgICByZXR1cm4gcmVxLmlwO1xuICB9XG59XG5cbmZ1bmN0aW9uIGh0dHBBdXRoKHJlcSkge1xuICBpZiAoIShyZXEucmVxIHx8IHJlcSkuaGVhZGVycy5hdXRob3JpemF0aW9uKVxuICAgIHJldHVybiA7XG5cbiAgdmFyIGhlYWRlciA9IChyZXEucmVxIHx8IHJlcSkuaGVhZGVycy5hdXRob3JpemF0aW9uO1xuICB2YXIgYXBwSWQsIG1hc3RlcktleSwgamF2YXNjcmlwdEtleTtcblxuICAvLyBwYXJzZSBoZWFkZXJcbiAgdmFyIGF1dGhQcmVmaXggPSAnYmFzaWMgJztcblxuICB2YXIgbWF0Y2ggPSBoZWFkZXIudG9Mb3dlckNhc2UoKS5pbmRleE9mKGF1dGhQcmVmaXgpO1xuXG4gIGlmIChtYXRjaCA9PSAwKSB7XG4gICAgdmFyIGVuY29kZWRBdXRoID0gaGVhZGVyLnN1YnN0cmluZyhhdXRoUHJlZml4Lmxlbmd0aCwgaGVhZGVyLmxlbmd0aCk7XG4gICAgdmFyIGNyZWRlbnRpYWxzID0gZGVjb2RlQmFzZTY0KGVuY29kZWRBdXRoKS5zcGxpdCgnOicpO1xuXG4gICAgaWYgKGNyZWRlbnRpYWxzLmxlbmd0aCA9PSAyKSB7XG4gICAgICBhcHBJZCA9IGNyZWRlbnRpYWxzWzBdO1xuICAgICAgdmFyIGtleSA9IGNyZWRlbnRpYWxzWzFdO1xuXG4gICAgICB2YXIganNLZXlQcmVmaXggPSAnamF2YXNjcmlwdC1rZXk9JztcblxuICAgICAgdmFyIG1hdGNoS2V5ID0ga2V5LmluZGV4T2YoanNLZXlQcmVmaXgpXG4gICAgICBpZiAobWF0Y2hLZXkgPT0gMCkge1xuICAgICAgICBqYXZhc2NyaXB0S2V5ID0ga2V5LnN1YnN0cmluZyhqc0tleVByZWZpeC5sZW5ndGgsIGtleS5sZW5ndGgpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIG1hc3RlcktleSA9IGtleTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4ge2FwcElkOiBhcHBJZCwgbWFzdGVyS2V5OiBtYXN0ZXJLZXksIGphdmFzY3JpcHRLZXk6IGphdmFzY3JpcHRLZXl9O1xufVxuXG5mdW5jdGlvbiBkZWNvZGVCYXNlNjQoc3RyKSB7XG4gIHJldHVybiBuZXcgQnVmZmVyKHN0ciwgJ2Jhc2U2NCcpLnRvU3RyaW5nKClcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFsbG93Q3Jvc3NEb21haW4ocmVxLCByZXMsIG5leHQpIHtcbiAgcmVzLmhlYWRlcignQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luJywgJyonKTtcbiAgcmVzLmhlYWRlcignQWNjZXNzLUNvbnRyb2wtQWxsb3ctTWV0aG9kcycsICdHRVQsUFVULFBPU1QsREVMRVRFLE9QVElPTlMnKTtcbiAgcmVzLmhlYWRlcignQWNjZXNzLUNvbnRyb2wtQWxsb3ctSGVhZGVycycsICdYLVBhcnNlLU1hc3Rlci1LZXksIFgtUGFyc2UtUkVTVC1BUEktS2V5LCBYLVBhcnNlLUphdmFzY3JpcHQtS2V5LCBYLVBhcnNlLUFwcGxpY2F0aW9uLUlkLCBYLVBhcnNlLUNsaWVudC1WZXJzaW9uLCBYLVBhcnNlLVNlc3Npb24tVG9rZW4sIFgtUmVxdWVzdGVkLVdpdGgsIFgtUGFyc2UtUmV2b2NhYmxlLVNlc3Npb24sIENvbnRlbnQtVHlwZScpO1xuICByZXMuaGVhZGVyKCdBY2Nlc3MtQ29udHJvbC1FeHBvc2UtSGVhZGVycycsICdYLVBhcnNlLUpvYi1TdGF0dXMtSWQsIFgtUGFyc2UtUHVzaC1TdGF0dXMtSWQnKTtcbiAgLy8gaW50ZXJjZXB0IE9QVElPTlMgbWV0aG9kXG4gIGlmICgnT1BUSU9OUycgPT0gcmVxLm1ldGhvZCkge1xuICAgIHJlcy5zZW5kU3RhdHVzKDIwMCk7XG4gIH1cbiAgZWxzZSB7XG4gICAgbmV4dCgpO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhbGxvd01ldGhvZE92ZXJyaWRlKHJlcSwgcmVzLCBuZXh0KSB7XG4gIGlmIChyZXEubWV0aG9kID09PSAnUE9TVCcgJiYgcmVxLmJvZHkuX21ldGhvZCkge1xuICAgIHJlcS5vcmlnaW5hbE1ldGhvZCA9IHJlcS5tZXRob2Q7XG4gICAgcmVxLm1ldGhvZCA9IHJlcS5ib2R5Ll9tZXRob2Q7XG4gICAgZGVsZXRlIHJlcS5ib2R5Ll9tZXRob2Q7XG4gIH1cbiAgbmV4dCgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFuZGxlUGFyc2VFcnJvcnMoZXJyLCByZXEsIHJlcywgbmV4dCkge1xuICBpZiAoZXJyIGluc3RhbmNlb2YgUGFyc2UuRXJyb3IpIHtcbiAgICBsZXQgaHR0cFN0YXR1cztcbiAgICAvLyBUT0RPOiBmaWxsIG91dCB0aGlzIG1hcHBpbmdcbiAgICBzd2l0Y2ggKGVyci5jb2RlKSB7XG4gICAgY2FzZSBQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1I6XG4gICAgICBodHRwU3RhdHVzID0gNTAwO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5EOlxuICAgICAgaHR0cFN0YXR1cyA9IDQwNDtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICBodHRwU3RhdHVzID0gNDAwO1xuICAgIH1cblxuICAgIHJlcy5zdGF0dXMoaHR0cFN0YXR1cyk7XG4gICAgcmVzLmpzb24oeyBjb2RlOiBlcnIuY29kZSwgZXJyb3I6IGVyci5tZXNzYWdlIH0pO1xuICAgIGxvZy5lcnJvcihlcnIubWVzc2FnZSwgZXJyKTtcbiAgICBpZiAocmVxLmNvbmZpZyAmJiByZXEuY29uZmlnLmVuYWJsZUV4cHJlc3NFcnJvckhhbmRsZXIpIHtcbiAgICAgIG5leHQoZXJyKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoZXJyLnN0YXR1cyAmJiBlcnIubWVzc2FnZSkge1xuICAgIHJlcy5zdGF0dXMoZXJyLnN0YXR1cyk7XG4gICAgcmVzLmpzb24oeyBlcnJvcjogZXJyLm1lc3NhZ2UgfSk7XG4gICAgbmV4dChlcnIpO1xuICB9IGVsc2Uge1xuICAgIGxvZy5lcnJvcignVW5jYXVnaHQgaW50ZXJuYWwgc2VydmVyIGVycm9yLicsIGVyciwgZXJyLnN0YWNrKTtcbiAgICByZXMuc3RhdHVzKDUwMCk7XG4gICAgcmVzLmpzb24oe1xuICAgICAgY29kZTogUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLFxuICAgICAgbWVzc2FnZTogJ0ludGVybmFsIHNlcnZlciBlcnJvci4nXG4gICAgfSk7XG4gICAgbmV4dChlcnIpO1xuICB9XG5cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MocmVxLCByZXMsIG5leHQpIHtcbiAgaWYgKCFyZXEuYXV0aC5pc01hc3Rlcikge1xuICAgIHJlcy5zdGF0dXMoNDAzKTtcbiAgICByZXMuZW5kKCd7XCJlcnJvclwiOlwidW5hdXRob3JpemVkOiBtYXN0ZXIga2V5IGlzIHJlcXVpcmVkXCJ9Jyk7XG4gICAgcmV0dXJuO1xuICB9XG4gIG5leHQoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzKHJlcXVlc3QpIHtcbiAgaWYgKCFyZXF1ZXN0LmF1dGguaXNNYXN0ZXIpIHtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcigpO1xuICAgIGVycm9yLnN0YXR1cyA9IDQwMztcbiAgICBlcnJvci5tZXNzYWdlID0gXCJ1bmF1dGhvcml6ZWQ6IG1hc3RlciBrZXkgaXMgcmVxdWlyZWRcIjtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbmZ1bmN0aW9uIGludmFsaWRSZXF1ZXN0KHJlcSwgcmVzKSB7XG4gIHJlcy5zdGF0dXMoNDAzKTtcbiAgcmVzLmVuZCgne1wiZXJyb3JcIjpcInVuYXV0aG9yaXplZFwifScpO1xufVxuIl19
652
+ function malformedContext(req, res) {
653
+ res.status(400);
654
+ res.json({
655
+ code: _node.default.Error.INVALID_JSON,
656
+ error: 'Invalid object for context.'
657
+ });
658
+ }
659
+
660
+ /**
661
+ * Express 4 allowed a double forward slash between a route and router. Although
662
+ * this should be considered an anti-pattern, we need to support it for backwards
663
+ * compatibility.
664
+ *
665
+ * Technically valid URL with double foroward slash:
666
+ * http://localhost:1337/parse//functions/testFunction
667
+ */
668
+ function allowDoubleForwardSlash(req, res, next) {
669
+ req.url = req.url.startsWith('//') ? req.url.substring(1) : req.url;
670
+ next();
671
+ }
672
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY2FjaGUiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9ub2RlIiwiX0F1dGgiLCJfQ29uZmlnIiwiX0NsaWVudFNESyIsIl9sb2dnZXIiLCJfcmVzdCIsIl9Nb25nb1N0b3JhZ2VBZGFwdGVyIiwiX1Bvc3RncmVzU3RvcmFnZUFkYXB0ZXIiLCJfZXhwcmVzc1JhdGVMaW1pdCIsIl9EZWZpbml0aW9ucyIsIl9wYXRoVG9SZWdleHAiLCJfcmF0ZUxpbWl0UmVkaXMiLCJfcmVkaXMiLCJfbmV0IiwiX0Vycm9yIiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiREVGQVVMVF9BTExPV0VEX0hFQURFUlMiLCJleHBvcnRzIiwiZ2V0TW91bnRGb3JSZXF1ZXN0IiwicmVxIiwibW91bnRQYXRoTGVuZ3RoIiwib3JpZ2luYWxVcmwiLCJsZW5ndGgiLCJ1cmwiLCJtb3VudFBhdGgiLCJzbGljZSIsInByb3RvY29sIiwiZ2V0IiwiZ2V0QmxvY2tMaXN0IiwiaXBSYW5nZUxpc3QiLCJzdG9yZSIsImJsb2NrTGlzdCIsIkJsb2NrTGlzdCIsImZvckVhY2giLCJmdWxsSXAiLCJzZXQiLCJpcCIsIm1hc2siLCJzcGxpdCIsImFkZEFkZHJlc3MiLCJpc0lQdjQiLCJhZGRTdWJuZXQiLCJOdW1iZXIiLCJjaGVja0lwIiwiaW5jb21pbmdJcElzVjQiLCJyZXN1bHQiLCJjaGVjayIsImluY2x1ZGVzIiwiaGFuZGxlUGFyc2VIZWFkZXJzIiwicmVzIiwibmV4dCIsIm1vdW50IiwiY29udGV4dCIsIkpTT04iLCJwYXJzZSIsIk9iamVjdCIsInByb3RvdHlwZSIsInRvU3RyaW5nIiwiY2FsbCIsIm1hbGZvcm1lZENvbnRleHQiLCJpbmZvIiwiYXBwSWQiLCJzZXNzaW9uVG9rZW4iLCJtYXN0ZXJLZXkiLCJtYWludGVuYW5jZUtleSIsImluc3RhbGxhdGlvbklkIiwiY2xpZW50S2V5IiwiamF2YXNjcmlwdEtleSIsImRvdE5ldEtleSIsInJlc3RBUElLZXkiLCJjbGllbnRWZXJzaW9uIiwiYmFzaWNBdXRoIiwiaHR0cEF1dGgiLCJiYXNpY0F1dGhBcHBJZCIsIkFwcENhY2hlIiwiYm9keSIsIl9ub0JvZHkiLCJmaWxlVmlhSlNPTiIsIkJ1ZmZlciIsImludmFsaWRSZXF1ZXN0IiwiX1Jldm9jYWJsZVNlc3Npb24iLCJfQXBwbGljYXRpb25JZCIsIl9KYXZhU2NyaXB0S2V5IiwiX0NsaWVudFZlcnNpb24iLCJfSW5zdGFsbGF0aW9uSWQiLCJfU2Vzc2lvblRva2VuIiwiX01hc3RlcktleSIsIl9jb250ZXh0IiwiX0NvbnRlbnRUeXBlIiwiaGVhZGVycyIsImNsaWVudFNESyIsIkNsaWVudFNESyIsImZyb21TdHJpbmciLCJmaWxlRGF0YSIsImJhc2U2NCIsImZyb20iLCJjbGllbnRJcCIsImdldENsaWVudElwIiwiY29uZmlnIiwiQ29uZmlnIiwic3RhdGUiLCJzdGF0dXMiLCJqc29uIiwiY29kZSIsIlBhcnNlIiwiRXJyb3IiLCJJTlRFUk5BTF9TRVJWRVJfRVJST1IiLCJlcnJvciIsImxvYWRLZXlzIiwiYXBwIiwiaXNNYWludGVuYW5jZSIsIm1haW50ZW5hbmNlS2V5SXBzIiwibWFpbnRlbmFuY2VLZXlJcHNTdG9yZSIsImF1dGgiLCJBdXRoIiwibG9nIiwibG9nZ2VyQ29udHJvbGxlciIsImRlZmF1bHRMb2dnZXIiLCJsb2FkTWFzdGVyS2V5IiwiaXNNYXN0ZXIiLCJtYXN0ZXJLZXlJcHMiLCJtYXN0ZXJLZXlJcHNTdG9yZSIsIm1lc3NhZ2UiLCJoYW5kbGVSYXRlTGltaXQiLCJpc1JlYWRPbmx5TWFzdGVyIiwicmVhZE9ubHlNYXN0ZXJLZXkiLCJpc1JlYWRPbmx5Iiwia2V5cyIsIm9uZUtleUNvbmZpZ3VyZWQiLCJzb21lIiwia2V5IiwidW5kZWZpbmVkIiwib25lS2V5TWF0Y2hlcyIsInVzZXJGcm9tSldUIiwidXNlciIsInJhdGVMaW1pdHMiLCJQcm9taXNlIiwiYWxsIiwibWFwIiwibGltaXQiLCJwYXRoRXhwIiwiUmVnRXhwIiwicGF0aCIsInRlc3QiLCJoYW5kbGVyIiwiZXJyIiwiQ09OTkVDVElPTl9GQUlMRUQiLCJoYW5kbGVQYXJzZVNlc3Npb24iLCJyZXF1ZXN0QXV0aCIsImluZGV4T2YiLCJnZXRBdXRoRm9yTGVnYWN5U2Vzc2lvblRva2VuIiwiZ2V0QXV0aEZvclNlc3Npb25Ub2tlbiIsIlVOS05PV05fRVJST1IiLCJhdXRob3JpemF0aW9uIiwiaGVhZGVyIiwiYXV0aFByZWZpeCIsIm1hdGNoIiwidG9Mb3dlckNhc2UiLCJlbmNvZGVkQXV0aCIsInN1YnN0cmluZyIsImNyZWRlbnRpYWxzIiwiZGVjb2RlQmFzZTY0IiwianNLZXlQcmVmaXgiLCJtYXRjaEtleSIsInN0ciIsImFsbG93Q3Jvc3NEb21haW4iLCJhbGxvd0hlYWRlcnMiLCJqb2luIiwiYmFzZU9yaWdpbnMiLCJhbGxvd09yaWdpbiIsInJlcXVlc3RPcmlnaW4iLCJvcmlnaW4iLCJhbGxvd09yaWdpbnMiLCJtZXRob2QiLCJzZW5kU3RhdHVzIiwiYWxsb3dNZXRob2RPdmVycmlkZSIsIl9tZXRob2QiLCJvcmlnaW5hbE1ldGhvZCIsImhhbmRsZVBhcnNlRXJyb3JzIiwiZW5hYmxlRXhwcmVzc0Vycm9ySGFuZGxlciIsImh0dHBTdGF0dXMiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwicHJvY2VzcyIsImVudiIsIlRFU1RJTkciLCJzdGFjayIsImVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiLCJjcmVhdGVTYW5pdGl6ZWRIdHRwRXJyb3IiLCJlbmQiLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyIsInJlcXVlc3QiLCJyZXNvbHZlIiwiYWRkUmF0ZUxpbWl0Iiwicm91dGUiLCJjbG91ZCIsIlJhdGVMaW1pdE9wdGlvbnMiLCJyZWRpc1N0b3JlIiwiY29ubmVjdGlvblByb21pc2UiLCJyZWRpc1VybCIsImNsaWVudCIsImNyZWF0ZUNsaWVudCIsIm9uIiwiaXNPcGVuIiwiY29ubmVjdCIsIlJlZGlzU3RvcmUiLCJzZW5kQ29tbWFuZCIsImFyZ3MiLCJ0cmFuc2Zvcm1QYXRoIiwicmVxdWVzdFBhdGgiLCJwdXNoIiwicGF0aFRvUmVnZXhwIiwicmF0ZUxpbWl0Iiwid2luZG93TXMiLCJyZXF1ZXN0VGltZVdpbmRvdyIsIm1heCIsInJlcXVlc3RDb3VudCIsImVycm9yUmVzcG9uc2VNZXNzYWdlIiwicmVzcG9uc2UiLCJvcHRpb25zIiwic2tpcCIsImluY2x1ZGVJbnRlcm5hbFJlcXVlc3RzIiwiaW5jbHVkZU1hc3RlcktleSIsInJlcXVlc3RNZXRob2RzIiwiQXJyYXkiLCJpc0FycmF5IiwicmVnRXhwIiwia2V5R2VuZXJhdG9yIiwiem9uZSIsIlNlcnZlciIsIlJhdGVMaW1pdFpvbmUiLCJnbG9iYWwiLCJ0b2tlbiIsInNlc3Npb24iLCJpZCIsInB1dCIsInByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSIsImRhdGFiYXNlIiwiYWRhcHRlciIsIk1vbmdvU3RvcmFnZUFkYXB0ZXIiLCJQb3N0Z3Jlc1N0b3JhZ2VBZGFwdGVyIiwicmVxdWVzdElkIiwicGF0aHMiLCJ0dGwiLCJpZGVtcG90ZW5jeU9wdGlvbnMiLCJyZXFQYXRoIiwicmVwbGFjZSIsInJlZ2V4IiwiY2hhckF0IiwiZXhwaXJ5RGF0ZSIsIkRhdGUiLCJzZXRTZWNvbmRzIiwiZ2V0U2Vjb25kcyIsInJlc3QiLCJjcmVhdGUiLCJtYXN0ZXIiLCJyZXFJZCIsImV4cGlyZSIsIl9lbmNvZGUiLCJjYXRjaCIsIkRVUExJQ0FURV9WQUxVRSIsIkRVUExJQ0FURV9SRVFVRVNUIiwiSU5WQUxJRF9KU09OIiwiYWxsb3dEb3VibGVGb3J3YXJkU2xhc2giLCJzdGFydHNXaXRoIl0sInNvdXJjZXMiOlsiLi4vc3JjL21pZGRsZXdhcmVzLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBBcHBDYWNoZSBmcm9tICcuL2NhY2hlJztcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBhdXRoIGZyb20gJy4vQXV0aCc7XG5pbXBvcnQgQ29uZmlnIGZyb20gJy4vQ29uZmlnJztcbmltcG9ydCBDbGllbnRTREsgZnJvbSAnLi9DbGllbnRTREsnO1xuaW1wb3J0IGRlZmF1bHRMb2dnZXIgZnJvbSAnLi9sb2dnZXInO1xuaW1wb3J0IHJlc3QgZnJvbSAnLi9yZXN0JztcbmltcG9ydCBNb25nb1N0b3JhZ2VBZGFwdGVyIGZyb20gJy4vQWRhcHRlcnMvU3RvcmFnZS9Nb25nby9Nb25nb1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCBQb3N0Z3Jlc1N0b3JhZ2VBZGFwdGVyIGZyb20gJy4vQWRhcHRlcnMvU3RvcmFnZS9Qb3N0Z3Jlcy9Qb3N0Z3Jlc1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCByYXRlTGltaXQgZnJvbSAnZXhwcmVzcy1yYXRlLWxpbWl0JztcbmltcG9ydCB7IFJhdGVMaW1pdE9wdGlvbnMgfSBmcm9tICcuL09wdGlvbnMvRGVmaW5pdGlvbnMnO1xuaW1wb3J0IHsgcGF0aFRvUmVnZXhwIH0gZnJvbSAncGF0aC10by1yZWdleHAnO1xuaW1wb3J0IFJlZGlzU3RvcmUgZnJvbSAncmF0ZS1saW1pdC1yZWRpcyc7XG5pbXBvcnQgeyBjcmVhdGVDbGllbnQgfSBmcm9tICdyZWRpcyc7XG5pbXBvcnQgeyBCbG9ja0xpc3QsIGlzSVB2NCB9IGZyb20gJ25ldCc7XG5pbXBvcnQgeyBjcmVhdGVTYW5pdGl6ZWRIdHRwRXJyb3IgfSBmcm9tICcuL0Vycm9yJztcblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfQUxMT1dFRF9IRUFERVJTID1cbiAgJ1gtUGFyc2UtTWFzdGVyLUtleSwgWC1QYXJzZS1SRVNULUFQSS1LZXksIFgtUGFyc2UtSmF2YXNjcmlwdC1LZXksIFgtUGFyc2UtQXBwbGljYXRpb24tSWQsIFgtUGFyc2UtQ2xpZW50LVZlcnNpb24sIFgtUGFyc2UtU2Vzc2lvbi1Ub2tlbiwgWC1SZXF1ZXN0ZWQtV2l0aCwgWC1QYXJzZS1SZXZvY2FibGUtU2Vzc2lvbiwgWC1QYXJzZS1SZXF1ZXN0LUlkLCBDb250ZW50LVR5cGUsIFByYWdtYSwgQ2FjaGUtQ29udHJvbCc7XG5cbmNvbnN0IGdldE1vdW50Rm9yUmVxdWVzdCA9IGZ1bmN0aW9uIChyZXEpIHtcbiAgY29uc3QgbW91bnRQYXRoTGVuZ3RoID0gcmVxLm9yaWdpbmFsVXJsLmxlbmd0aCAtIHJlcS51cmwubGVuZ3RoO1xuICBjb25zdCBtb3VudFBhdGggPSByZXEub3JpZ2luYWxVcmwuc2xpY2UoMCwgbW91bnRQYXRoTGVuZ3RoKTtcbiAgcmV0dXJuIHJlcS5wcm90b2NvbCArICc6Ly8nICsgcmVxLmdldCgnaG9zdCcpICsgbW91bnRQYXRoO1xufTtcblxuY29uc3QgZ2V0QmxvY2tMaXN0ID0gKGlwUmFuZ2VMaXN0LCBzdG9yZSkgPT4ge1xuICBpZiAoc3RvcmUuZ2V0KCdibG9ja0xpc3QnKSkgeyByZXR1cm4gc3RvcmUuZ2V0KCdibG9ja0xpc3QnKTsgfVxuICBjb25zdCBibG9ja0xpc3QgPSBuZXcgQmxvY2tMaXN0KCk7XG4gIGlwUmFuZ2VMaXN0LmZvckVhY2goZnVsbElwID0+IHtcbiAgICBpZiAoZnVsbElwID09PSAnOjovMCcgfHwgZnVsbElwID09PSAnOjonKSB7XG4gICAgICBzdG9yZS5zZXQoJ2FsbG93QWxsSXB2NicsIHRydWUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoZnVsbElwID09PSAnMC4wLjAuMC8wJyB8fCBmdWxsSXAgPT09ICcwLjAuMC4wJykge1xuICAgICAgc3RvcmUuc2V0KCdhbGxvd0FsbElwdjQnLCB0cnVlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgW2lwLCBtYXNrXSA9IGZ1bGxJcC5zcGxpdCgnLycpO1xuICAgIGlmICghbWFzaykge1xuICAgICAgYmxvY2tMaXN0LmFkZEFkZHJlc3MoaXAsIGlzSVB2NChpcCkgPyAnaXB2NCcgOiAnaXB2NicpO1xuICAgIH0gZWxzZSB7XG4gICAgICBibG9ja0xpc3QuYWRkU3VibmV0KGlwLCBOdW1iZXIobWFzayksIGlzSVB2NChpcCkgPyAnaXB2NCcgOiAnaXB2NicpO1xuICAgIH1cbiAgfSk7XG4gIHN0b3JlLnNldCgnYmxvY2tMaXN0JywgYmxvY2tMaXN0KTtcbiAgcmV0dXJuIGJsb2NrTGlzdDtcbn07XG5cbmV4cG9ydCBjb25zdCBjaGVja0lwID0gKGlwLCBpcFJhbmdlTGlzdCwgc3RvcmUpID0+IHtcbiAgY29uc3QgaW5jb21pbmdJcElzVjQgPSBpc0lQdjQoaXApO1xuICBjb25zdCBibG9ja0xpc3QgPSBnZXRCbG9ja0xpc3QoaXBSYW5nZUxpc3QsIHN0b3JlKTtcblxuICBpZiAoc3RvcmUuZ2V0KGlwKSkgeyByZXR1cm4gdHJ1ZTsgfVxuICBpZiAoc3RvcmUuZ2V0KCdhbGxvd0FsbElwdjQnKSAmJiBpbmNvbWluZ0lwSXNWNCkgeyByZXR1cm4gdHJ1ZTsgfVxuICBpZiAoc3RvcmUuZ2V0KCdhbGxvd0FsbElwdjYnKSAmJiAhaW5jb21pbmdJcElzVjQpIHsgcmV0dXJuIHRydWU7IH1cbiAgY29uc3QgcmVzdWx0ID0gYmxvY2tMaXN0LmNoZWNrKGlwLCBpbmNvbWluZ0lwSXNWNCA/ICdpcHY0JyA6ICdpcHY2Jyk7XG5cbiAgLy8gSWYgdGhlIGlwIGlzIGluIHRoZSBsaXN0LCB3ZSBzdG9yZSB0aGUgcmVzdWx0IGluIHRoZSBzdG9yZVxuICAvLyBzbyB3ZSBoYXZlIGEgb3B0aW1pemVkIHBhdGggZm9yIHRoZSBuZXh0IHJlcXVlc3RcbiAgaWYgKGlwUmFuZ2VMaXN0LmluY2x1ZGVzKGlwKSAmJiByZXN1bHQpIHtcbiAgICBzdG9yZS5zZXQoaXAsIHJlc3VsdCk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbi8vIENoZWNrcyB0aGF0IHRoZSByZXF1ZXN0IGlzIGF1dGhvcml6ZWQgZm9yIHRoaXMgYXBwIGFuZCBjaGVja3MgdXNlclxuLy8gYXV0aCB0b28uXG4vLyBUaGUgYm9keXBhcnNlciBzaG91bGQgcnVuIGJlZm9yZSB0aGlzIG1pZGRsZXdhcmUuXG4vLyBBZGRzIGluZm8gdG8gdGhlIHJlcXVlc3Q6XG4vLyByZXEuY29uZmlnIC0gdGhlIENvbmZpZyBmb3IgdGhpcyBhcHBcbi8vIHJlcS5hdXRoIC0gdGhlIEF1dGggZm9yIHRoaXMgcmVxdWVzdFxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZVBhcnNlSGVhZGVycyhyZXEsIHJlcywgbmV4dCkge1xuICB2YXIgbW91bnQgPSBnZXRNb3VudEZvclJlcXVlc3QocmVxKTtcblxuICBsZXQgY29udGV4dCA9IHt9O1xuICBpZiAocmVxLmdldCgnWC1QYXJzZS1DbG91ZC1Db250ZXh0JykgIT0gbnVsbCkge1xuICAgIHRyeSB7XG4gICAgICBjb250ZXh0ID0gSlNPTi5wYXJzZShyZXEuZ2V0KCdYLVBhcnNlLUNsb3VkLUNvbnRleHQnKSk7XG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGNvbnRleHQpICE9PSAnW29iamVjdCBPYmplY3RdJykge1xuICAgICAgICB0aHJvdyAnQ29udGV4dCBpcyBub3QgYW4gb2JqZWN0JztcbiAgICAgIH1cbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBtYWxmb3JtZWRDb250ZXh0KHJlcSwgcmVzKTtcbiAgICB9XG4gIH1cbiAgdmFyIGluZm8gPSB7XG4gICAgYXBwSWQ6IHJlcS5nZXQoJ1gtUGFyc2UtQXBwbGljYXRpb24tSWQnKSxcbiAgICBzZXNzaW9uVG9rZW46IHJlcS5nZXQoJ1gtUGFyc2UtU2Vzc2lvbi1Ub2tlbicpLFxuICAgIG1hc3RlcktleTogcmVxLmdldCgnWC1QYXJzZS1NYXN0ZXItS2V5JyksXG4gICAgbWFpbnRlbmFuY2VLZXk6IHJlcS5nZXQoJ1gtUGFyc2UtTWFpbnRlbmFuY2UtS2V5JyksXG4gICAgaW5zdGFsbGF0aW9uSWQ6IHJlcS5nZXQoJ1gtUGFyc2UtSW5zdGFsbGF0aW9uLUlkJyksXG4gICAgY2xpZW50S2V5OiByZXEuZ2V0KCdYLVBhcnNlLUNsaWVudC1LZXknKSxcbiAgICBqYXZhc2NyaXB0S2V5OiByZXEuZ2V0KCdYLVBhcnNlLUphdmFzY3JpcHQtS2V5JyksXG4gICAgZG90TmV0S2V5OiByZXEuZ2V0KCdYLVBhcnNlLVdpbmRvd3MtS2V5JyksXG4gICAgcmVzdEFQSUtleTogcmVxLmdldCgnWC1QYXJzZS1SRVNULUFQSS1LZXknKSxcbiAgICBjbGllbnRWZXJzaW9uOiByZXEuZ2V0KCdYLVBhcnNlLUNsaWVudC1WZXJzaW9uJyksXG4gICAgY29udGV4dDogY29udGV4dCxcbiAgfTtcblxuICB2YXIgYmFzaWNBdXRoID0gaHR0cEF1dGgocmVxKTtcblxuICBpZiAoYmFzaWNBdXRoKSB7XG4gICAgdmFyIGJhc2ljQXV0aEFwcElkID0gYmFzaWNBdXRoLmFwcElkO1xuICAgIGlmIChBcHBDYWNoZS5nZXQoYmFzaWNBdXRoQXBwSWQpKSB7XG4gICAgICBpbmZvLmFwcElkID0gYmFzaWNBdXRoQXBwSWQ7XG4gICAgICBpbmZvLm1hc3RlcktleSA9IGJhc2ljQXV0aC5tYXN0ZXJLZXkgfHwgaW5mby5tYXN0ZXJLZXk7XG4gICAgICBpbmZvLmphdmFzY3JpcHRLZXkgPSBiYXNpY0F1dGguamF2YXNjcmlwdEtleSB8fCBpbmZvLmphdmFzY3JpcHRLZXk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHJlcS5ib2R5KSB7XG4gICAgLy8gVW5pdHkgU0RLIHNlbmRzIGEgX25vQm9keSBrZXkgd2hpY2ggbmVlZHMgdG8gYmUgcmVtb3ZlZC5cbiAgICAvLyBVbmNsZWFyIGF0IHRoaXMgcG9pbnQgaWYgYWN0aW9uIG5lZWRzIHRvIGJlIHRha2VuLlxuICAgIGRlbGV0ZSByZXEuYm9keS5fbm9Cb2R5O1xuICB9XG5cbiAgdmFyIGZpbGVWaWFKU09OID0gZmFsc2U7XG5cbiAgaWYgKCFpbmZvLmFwcElkIHx8ICFBcHBDYWNoZS5nZXQoaW5mby5hcHBJZCkpIHtcbiAgICAvLyBTZWUgaWYgd2UgY2FuIGZpbmQgdGhlIGFwcCBpZCBvbiB0aGUgYm9keS5cbiAgICBpZiAocmVxLmJvZHkgaW5zdGFuY2VvZiBCdWZmZXIpIHtcbiAgICAgIC8vIFRoZSBvbmx5IGNoYW5jZSB0byBmaW5kIHRoZSBhcHAgaWQgaXMgaWYgdGhpcyBpcyBhIGZpbGVcbiAgICAgIC8vIHVwbG9hZCB0aGF0IGFjdHVhbGx5IGlzIGEgSlNPTiBib2R5LiBTbyB0cnkgdG8gcGFyc2UgaXQuXG4gICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vcGFyc2UtY29tbXVuaXR5L3BhcnNlLXNlcnZlci9pc3N1ZXMvNjU4OVxuICAgICAgLy8gSXQgaXMgYWxzbyBwb3NzaWJsZSB0aGF0IHRoZSBjbGllbnQgaXMgdHJ5aW5nIHRvIHVwbG9hZCBhIGZpbGUgYnV0IGZvcmdvdFxuICAgICAgLy8gdG8gcHJvdmlkZSB4LXBhcnNlLWFwcC1pZCBpbiBoZWFkZXIgYW5kIHBhcnNlIGEgYmluYXJ5IGZpbGUgd2lsbCBmYWlsXG4gICAgICB0cnkge1xuICAgICAgICByZXEuYm9keSA9IEpTT04ucGFyc2UocmVxLmJvZHkpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiBpbnZhbGlkUmVxdWVzdChyZXEsIHJlcyk7XG4gICAgICB9XG4gICAgICBmaWxlVmlhSlNPTiA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHJlcS5ib2R5KSB7XG4gICAgICBkZWxldGUgcmVxLmJvZHkuX1Jldm9jYWJsZVNlc3Npb247XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgcmVxLmJvZHkgJiZcbiAgICAgIHJlcS5ib2R5Ll9BcHBsaWNhdGlvbklkICYmXG4gICAgICBBcHBDYWNoZS5nZXQocmVxLmJvZHkuX0FwcGxpY2F0aW9uSWQpICYmXG4gICAgICAoIWluZm8ubWFzdGVyS2V5IHx8IEFwcENhY2hlLmdldChyZXEuYm9keS5fQXBwbGljYXRpb25JZCkubWFzdGVyS2V5ID09PSBpbmZvLm1hc3RlcktleSlcbiAgICApIHtcbiAgICAgIGluZm8uYXBwSWQgPSByZXEuYm9keS5fQXBwbGljYXRpb25JZDtcbiAgICAgIGluZm8uamF2YXNjcmlwdEtleSA9IHJlcS5ib2R5Ll9KYXZhU2NyaXB0S2V5IHx8ICcnO1xuICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9BcHBsaWNhdGlvbklkO1xuICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9KYXZhU2NyaXB0S2V5O1xuICAgICAgLy8gVE9ETzogdGVzdCB0aGF0IHRoZSBSRVNUIEFQSSBmb3JtYXRzIGdlbmVyYXRlZCBieSB0aGUgb3RoZXJcbiAgICAgIC8vIFNES3MgYXJlIGhhbmRsZWQgb2tcbiAgICAgIGlmIChyZXEuYm9keS5fQ2xpZW50VmVyc2lvbikge1xuICAgICAgICBpbmZvLmNsaWVudFZlcnNpb24gPSByZXEuYm9keS5fQ2xpZW50VmVyc2lvbjtcbiAgICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9DbGllbnRWZXJzaW9uO1xuICAgICAgfVxuICAgICAgaWYgKHJlcS5ib2R5Ll9JbnN0YWxsYXRpb25JZCkge1xuICAgICAgICBpbmZvLmluc3RhbGxhdGlvbklkID0gcmVxLmJvZHkuX0luc3RhbGxhdGlvbklkO1xuICAgICAgICBkZWxldGUgcmVxLmJvZHkuX0luc3RhbGxhdGlvbklkO1xuICAgICAgfVxuICAgICAgaWYgKHJlcS5ib2R5Ll9TZXNzaW9uVG9rZW4pIHtcbiAgICAgICAgaW5mby5zZXNzaW9uVG9rZW4gPSByZXEuYm9keS5fU2Vzc2lvblRva2VuO1xuICAgICAgICBkZWxldGUgcmVxLmJvZHkuX1Nlc3Npb25Ub2tlbjtcbiAgICAgIH1cbiAgICAgIGlmIChyZXEuYm9keS5fTWFzdGVyS2V5KSB7XG4gICAgICAgIGluZm8ubWFzdGVyS2V5ID0gcmVxLmJvZHkuX01hc3RlcktleTtcbiAgICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9NYXN0ZXJLZXk7XG4gICAgICB9XG4gICAgICBpZiAocmVxLmJvZHkuX2NvbnRleHQpIHtcbiAgICAgICAgaWYgKHJlcS5ib2R5Ll9jb250ZXh0IGluc3RhbmNlb2YgT2JqZWN0KSB7XG4gICAgICAgICAgaW5mby5jb250ZXh0ID0gcmVxLmJvZHkuX2NvbnRleHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGluZm8uY29udGV4dCA9IEpTT04ucGFyc2UocmVxLmJvZHkuX2NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpbmZvLmNvbnRleHQpICE9PSAnW29iamVjdCBPYmplY3RdJykge1xuICAgICAgICAgICAgICB0aHJvdyAnQ29udGV4dCBpcyBub3QgYW4gb2JqZWN0JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIHJldHVybiBtYWxmb3JtZWRDb250ZXh0KHJlcSwgcmVzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9jb250ZXh0O1xuICAgICAgfVxuICAgICAgaWYgKHJlcS5ib2R5Ll9Db250ZW50VHlwZSkge1xuICAgICAgICByZXEuaGVhZGVyc1snY29udGVudC10eXBlJ10gPSByZXEuYm9keS5fQ29udGVudFR5cGU7XG4gICAgICAgIGRlbGV0ZSByZXEuYm9keS5fQ29udGVudFR5cGU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBpbnZhbGlkUmVxdWVzdChyZXEsIHJlcyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGluZm8uc2Vzc2lvblRva2VuICYmIHR5cGVvZiBpbmZvLnNlc3Npb25Ub2tlbiAhPT0gJ3N0cmluZycpIHtcbiAgICBpbmZvLnNlc3Npb25Ub2tlbiA9IGluZm8uc2Vzc2lvblRva2VuLnRvU3RyaW5nKCk7XG4gIH1cblxuICBpZiAoaW5mby5jbGllbnRWZXJzaW9uKSB7XG4gICAgaW5mby5jbGllbnRTREsgPSBDbGllbnRTREsuZnJvbVN0cmluZyhpbmZvLmNsaWVudFZlcnNpb24pO1xuICB9XG5cbiAgaWYgKGZpbGVWaWFKU09OICYmIHJlcS5ib2R5KSB7XG4gICAgcmVxLmZpbGVEYXRhID0gcmVxLmJvZHkuZmlsZURhdGE7XG4gICAgLy8gV2UgbmVlZCB0byByZXBvcHVsYXRlIHJlcS5ib2R5IHdpdGggYSBidWZmZXJcbiAgICB2YXIgYmFzZTY0ID0gcmVxLmJvZHkuYmFzZTY0O1xuICAgIHJlcS5ib2R5ID0gQnVmZmVyLmZyb20oYmFzZTY0LCAnYmFzZTY0Jyk7XG4gIH1cblxuICBjb25zdCBjbGllbnRJcCA9IGdldENsaWVudElwKHJlcSk7XG4gIGNvbnN0IGNvbmZpZyA9IENvbmZpZy5nZXQoaW5mby5hcHBJZCwgbW91bnQpO1xuICBpZiAoY29uZmlnLnN0YXRlICYmIGNvbmZpZy5zdGF0ZSAhPT0gJ29rJykge1xuICAgIHJlcy5zdGF0dXMoNTAwKTtcbiAgICByZXMuanNvbih7XG4gICAgICBjb2RlOiBQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsXG4gICAgICBlcnJvcjogYEludmFsaWQgc2VydmVyIHN0YXRlOiAke2NvbmZpZy5zdGF0ZX1gLFxuICAgIH0pO1xuICAgIHJldHVybjtcbiAgfVxuICBhd2FpdCBjb25maWcubG9hZEtleXMoKTtcblxuICBpbmZvLmFwcCA9IEFwcENhY2hlLmdldChpbmZvLmFwcElkKTtcbiAgcmVxLmNvbmZpZyA9IGNvbmZpZztcbiAgcmVxLmNvbmZpZy5oZWFkZXJzID0gcmVxLmhlYWRlcnMgfHwge307XG4gIHJlcS5jb25maWcuaXAgPSBjbGllbnRJcDtcbiAgcmVxLmluZm8gPSBpbmZvO1xuXG4gIGNvbnN0IGlzTWFpbnRlbmFuY2UgPVxuICAgIHJlcS5jb25maWcubWFpbnRlbmFuY2VLZXkgJiYgaW5mby5tYWludGVuYW5jZUtleSA9PT0gcmVxLmNvbmZpZy5tYWludGVuYW5jZUtleTtcbiAgaWYgKGlzTWFpbnRlbmFuY2UpIHtcbiAgICBpZiAoY2hlY2tJcChjbGllbnRJcCwgcmVxLmNvbmZpZy5tYWludGVuYW5jZUtleUlwcyB8fCBbXSwgcmVxLmNvbmZpZy5tYWludGVuYW5jZUtleUlwc1N0b3JlKSkge1xuICAgICAgcmVxLmF1dGggPSBuZXcgYXV0aC5BdXRoKHtcbiAgICAgICAgY29uZmlnOiByZXEuY29uZmlnLFxuICAgICAgICBpbnN0YWxsYXRpb25JZDogaW5mby5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgaXNNYWludGVuYW5jZTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgICAgbmV4dCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBsb2cgPSByZXEuY29uZmlnPy5sb2dnZXJDb250cm9sbGVyIHx8IGRlZmF1bHRMb2dnZXI7XG4gICAgbG9nLmVycm9yKFxuICAgICAgYFJlcXVlc3QgdXNpbmcgbWFpbnRlbmFuY2Uga2V5IHJlamVjdGVkIGFzIHRoZSByZXF1ZXN0IElQIGFkZHJlc3MgJyR7Y2xpZW50SXB9JyBpcyBub3Qgc2V0IGluIFBhcnNlIFNlcnZlciBvcHRpb24gJ21haW50ZW5hbmNlS2V5SXBzJy5gXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IG1hc3RlcktleSA9IGF3YWl0IHJlcS5jb25maWcubG9hZE1hc3RlcktleSgpO1xuICBsZXQgaXNNYXN0ZXIgPSBpbmZvLm1hc3RlcktleSA9PT0gbWFzdGVyS2V5O1xuXG4gIGlmIChpc01hc3RlciAmJiAhY2hlY2tJcChjbGllbnRJcCwgcmVxLmNvbmZpZy5tYXN0ZXJLZXlJcHMgfHwgW10sIHJlcS5jb25maWcubWFzdGVyS2V5SXBzU3RvcmUpKSB7XG4gICAgY29uc3QgbG9nID0gcmVxLmNvbmZpZz8ubG9nZ2VyQ29udHJvbGxlciB8fCBkZWZhdWx0TG9nZ2VyO1xuICAgIGxvZy5lcnJvcihcbiAgICAgIGBSZXF1ZXN0IHVzaW5nIG1hc3RlciBrZXkgcmVqZWN0ZWQgYXMgdGhlIHJlcXVlc3QgSVAgYWRkcmVzcyAnJHtjbGllbnRJcH0nIGlzIG5vdCBzZXQgaW4gUGFyc2UgU2VydmVyIG9wdGlvbiAnbWFzdGVyS2V5SXBzJy5gXG4gICAgKTtcbiAgICBpc01hc3RlciA9IGZhbHNlO1xuICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKCk7XG4gICAgZXJyb3Iuc3RhdHVzID0gNDAzO1xuICAgIGVycm9yLm1lc3NhZ2UgPSBgdW5hdXRob3JpemVkYDtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuXG4gIGlmIChpc01hc3Rlcikge1xuICAgIHJlcS5hdXRoID0gbmV3IGF1dGguQXV0aCh7XG4gICAgICBjb25maWc6IHJlcS5jb25maWcsXG4gICAgICBpbnN0YWxsYXRpb25JZDogaW5mby5pbnN0YWxsYXRpb25JZCxcbiAgICAgIGlzTWFzdGVyOiB0cnVlLFxuICAgIH0pO1xuICAgIHJldHVybiBoYW5kbGVSYXRlTGltaXQocmVxLCByZXMsIG5leHQpO1xuICB9XG5cbiAgdmFyIGlzUmVhZE9ubHlNYXN0ZXIgPSBpbmZvLm1hc3RlcktleSA9PT0gcmVxLmNvbmZpZy5yZWFkT25seU1hc3RlcktleTtcbiAgaWYgKFxuICAgIHR5cGVvZiByZXEuY29uZmlnLnJlYWRPbmx5TWFzdGVyS2V5ICE9ICd1bmRlZmluZWQnICYmXG4gICAgcmVxLmNvbmZpZy5yZWFkT25seU1hc3RlcktleSAmJlxuICAgIGlzUmVhZE9ubHlNYXN0ZXJcbiAgKSB7XG4gICAgcmVxLmF1dGggPSBuZXcgYXV0aC5BdXRoKHtcbiAgICAgIGNvbmZpZzogcmVxLmNvbmZpZyxcbiAgICAgIGluc3RhbGxhdGlvbklkOiBpbmZvLmluc3RhbGxhdGlvbklkLFxuICAgICAgaXNNYXN0ZXI6IHRydWUsXG4gICAgICBpc1JlYWRPbmx5OiB0cnVlLFxuICAgIH0pO1xuICAgIHJldHVybiBoYW5kbGVSYXRlTGltaXQocmVxLCByZXMsIG5leHQpO1xuICB9XG5cbiAgLy8gQ2xpZW50IGtleXMgYXJlIG5vdCByZXF1aXJlZCBpbiBwYXJzZS1zZXJ2ZXIsIGJ1dCBpZiBhbnkgaGF2ZSBiZWVuIGNvbmZpZ3VyZWQgaW4gdGhlIHNlcnZlciwgdmFsaWRhdGUgdGhlbVxuICAvLyAgdG8gcHJlc2VydmUgb3JpZ2luYWwgYmVoYXZpb3IuXG4gIGNvbnN0IGtleXMgPSBbJ2NsaWVudEtleScsICdqYXZhc2NyaXB0S2V5JywgJ2RvdE5ldEtleScsICdyZXN0QVBJS2V5J107XG4gIGNvbnN0IG9uZUtleUNvbmZpZ3VyZWQgPSBrZXlzLnNvbWUoZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiByZXEuY29uZmlnW2tleV0gIT09IHVuZGVmaW5lZDtcbiAgfSk7XG4gIGNvbnN0IG9uZUtleU1hdGNoZXMgPSBrZXlzLnNvbWUoZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiByZXEuY29uZmlnW2tleV0gIT09IHVuZGVmaW5lZCAmJiBpbmZvW2tleV0gPT09IHJlcS5jb25maWdba2V5XTtcbiAgfSk7XG5cbiAgaWYgKG9uZUtleUNvbmZpZ3VyZWQgJiYgIW9uZUtleU1hdGNoZXMpIHtcbiAgICByZXR1cm4gaW52YWxpZFJlcXVlc3QocmVxLCByZXMpO1xuICB9XG5cbiAgaWYgKHJlcS51cmwgPT0gJy9sb2dpbicpIHtcbiAgICBkZWxldGUgaW5mby5zZXNzaW9uVG9rZW47XG4gIH1cblxuICBpZiAocmVxLnVzZXJGcm9tSldUKSB7XG4gICAgcmVxLmF1dGggPSBuZXcgYXV0aC5BdXRoKHtcbiAgICAgIGNvbmZpZzogcmVxLmNvbmZpZyxcbiAgICAgIGluc3RhbGxhdGlvbklkOiBpbmZvLmluc3RhbGxhdGlvbklkLFxuICAgICAgaXNNYXN0ZXI6IGZhbHNlLFxuICAgICAgdXNlcjogcmVxLnVzZXJGcm9tSldULFxuICAgIH0pO1xuICAgIHJldHVybiBoYW5kbGVSYXRlTGltaXQocmVxLCByZXMsIG5leHQpO1xuICB9XG5cbiAgaWYgKCFpbmZvLnNlc3Npb25Ub2tlbikge1xuICAgIHJlcS5hdXRoID0gbmV3IGF1dGguQXV0aCh7XG4gICAgICBjb25maWc6IHJlcS5jb25maWcsXG4gICAgICBpbnN0YWxsYXRpb25JZDogaW5mby5pbnN0YWxsYXRpb25JZCxcbiAgICAgIGlzTWFzdGVyOiBmYWxzZSxcbiAgICB9KTtcbiAgfVxuICBoYW5kbGVSYXRlTGltaXQocmVxLCByZXMsIG5leHQpO1xufVxuXG5jb25zdCBoYW5kbGVSYXRlTGltaXQgPSBhc3luYyAocmVxLCByZXMsIG5leHQpID0+IHtcbiAgY29uc3QgcmF0ZUxpbWl0cyA9IHJlcS5jb25maWcucmF0ZUxpbWl0cyB8fCBbXTtcbiAgdHJ5IHtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIHJhdGVMaW1pdHMubWFwKGFzeW5jIGxpbWl0ID0+IHtcbiAgICAgICAgY29uc3QgcGF0aEV4cCA9IG5ldyBSZWdFeHAobGltaXQucGF0aCk7XG4gICAgICAgIGlmIChwYXRoRXhwLnRlc3QocmVxLnVybCkpIHtcbiAgICAgICAgICBhd2FpdCBsaW1pdC5oYW5kbGVyKHJlcSwgcmVzLCBlcnIgPT4ge1xuICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT09IFBhcnNlLkVycm9yLkNPTk5FQ1RJT05fRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlcS5jb25maWcubG9nZ2VyQ29udHJvbGxlci5lcnJvcihcbiAgICAgICAgICAgICAgICAnQW4gdW5rbm93biBlcnJvciBvY2N1cmVkIHdoZW4gYXR0ZW1wdGluZyB0byBhcHBseSB0aGUgcmF0ZSBsaW1pdGVyOiAnLFxuICAgICAgICAgICAgICAgIGVyclxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmVzLnN0YXR1cyg0MjkpO1xuICAgIHJlcy5qc29uKHsgY29kZTogUGFyc2UuRXJyb3IuQ09OTkVDVElPTl9GQUlMRUQsIGVycm9yOiBlcnJvci5tZXNzYWdlIH0pO1xuICAgIHJldHVybjtcbiAgfVxuICBuZXh0KCk7XG59O1xuXG5leHBvcnQgY29uc3QgaGFuZGxlUGFyc2VTZXNzaW9uID0gYXN5bmMgKHJlcSwgcmVzLCBuZXh0KSA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3QgaW5mbyA9IHJlcS5pbmZvO1xuICAgIGlmIChyZXEuYXV0aCB8fCByZXEudXJsID09PSAnL3Nlc3Npb25zL21lJykge1xuICAgICAgbmV4dCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgcmVxdWVzdEF1dGggPSBudWxsO1xuICAgIGlmIChcbiAgICAgIGluZm8uc2Vzc2lvblRva2VuICYmXG4gICAgICByZXEudXJsID09PSAnL3VwZ3JhZGVUb1Jldm9jYWJsZVNlc3Npb24nICYmXG4gICAgICBpbmZvLnNlc3Npb25Ub2tlbi5pbmRleE9mKCdyOicpICE9IDBcbiAgICApIHtcbiAgICAgIHJlcXVlc3RBdXRoID0gYXdhaXQgYXV0aC5nZXRBdXRoRm9yTGVnYWN5U2Vzc2lvblRva2VuKHtcbiAgICAgICAgY29uZmlnOiByZXEuY29uZmlnLFxuICAgICAgICBpbnN0YWxsYXRpb25JZDogaW5mby5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgc2Vzc2lvblRva2VuOiBpbmZvLnNlc3Npb25Ub2tlbixcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXF1ZXN0QXV0aCA9IGF3YWl0IGF1dGguZ2V0QXV0aEZvclNlc3Npb25Ub2tlbih7XG4gICAgICAgIGNvbmZpZzogcmVxLmNvbmZpZyxcbiAgICAgICAgaW5zdGFsbGF0aW9uSWQ6IGluZm8uaW5zdGFsbGF0aW9uSWQsXG4gICAgICAgIHNlc3Npb25Ub2tlbjogaW5mby5zZXNzaW9uVG9rZW4sXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmVxLmF1dGggPSByZXF1ZXN0QXV0aDtcbiAgICBuZXh0KCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgUGFyc2UuRXJyb3IpIHtcbiAgICAgIG5leHQoZXJyb3IpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBUT0RPOiBEZXRlcm1pbmUgdGhlIGNvcnJlY3QgZXJyb3Igc2NlbmFyaW8uXG4gICAgcmVxLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyLmVycm9yKCdlcnJvciBnZXR0aW5nIGF1dGggZm9yIHNlc3Npb25Ub2tlbicsIGVycm9yKTtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuVU5LTk9XTl9FUlJPUiwgZXJyb3IpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBnZXRDbGllbnRJcChyZXEpIHtcbiAgcmV0dXJuIHJlcS5pcDtcbn1cblxuZnVuY3Rpb24gaHR0cEF1dGgocmVxKSB7XG4gIGlmICghKHJlcS5yZXEgfHwgcmVxKS5oZWFkZXJzLmF1dGhvcml6YXRpb24pIHsgcmV0dXJuOyB9XG5cbiAgdmFyIGhlYWRlciA9IChyZXEucmVxIHx8IHJlcSkuaGVhZGVycy5hdXRob3JpemF0aW9uO1xuICB2YXIgYXBwSWQsIG1hc3RlcktleSwgamF2YXNjcmlwdEtleTtcblxuICAvLyBwYXJzZSBoZWFkZXJcbiAgdmFyIGF1dGhQcmVmaXggPSAnYmFzaWMgJztcblxuICB2YXIgbWF0Y2ggPSBoZWFkZXIudG9Mb3dlckNhc2UoKS5pbmRleE9mKGF1dGhQcmVmaXgpO1xuXG4gIGlmIChtYXRjaCA9PSAwKSB7XG4gICAgdmFyIGVuY29kZWRBdXRoID0gaGVhZGVyLnN1YnN0cmluZyhhdXRoUHJlZml4Lmxlbmd0aCwgaGVhZGVyLmxlbmd0aCk7XG4gICAgdmFyIGNyZWRlbnRpYWxzID0gZGVjb2RlQmFzZTY0KGVuY29kZWRBdXRoKS5zcGxpdCgnOicpO1xuXG4gICAgaWYgKGNyZWRlbnRpYWxzLmxlbmd0aCA9PSAyKSB7XG4gICAgICBhcHBJZCA9IGNyZWRlbnRpYWxzWzBdO1xuICAgICAgdmFyIGtleSA9IGNyZWRlbnRpYWxzWzFdO1xuXG4gICAgICB2YXIganNLZXlQcmVmaXggPSAnamF2YXNjcmlwdC1rZXk9JztcblxuICAgICAgdmFyIG1hdGNoS2V5ID0ga2V5LmluZGV4T2YoanNLZXlQcmVmaXgpO1xuICAgICAgaWYgKG1hdGNoS2V5ID09IDApIHtcbiAgICAgICAgamF2YXNjcmlwdEtleSA9IGtleS5zdWJzdHJpbmcoanNLZXlQcmVmaXgubGVuZ3RoLCBrZXkubGVuZ3RoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1hc3RlcktleSA9IGtleTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4geyBhcHBJZDogYXBwSWQsIG1hc3RlcktleTogbWFzdGVyS2V5LCBqYXZhc2NyaXB0S2V5OiBqYXZhc2NyaXB0S2V5IH07XG59XG5cbmZ1bmN0aW9uIGRlY29kZUJhc2U2NChzdHIpIHtcbiAgcmV0dXJuIEJ1ZmZlci5mcm9tKHN0ciwgJ2Jhc2U2NCcpLnRvU3RyaW5nKCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhbGxvd0Nyb3NzRG9tYWluKGFwcElkKSB7XG4gIHJldHVybiAocmVxLCByZXMsIG5leHQpID0+IHtcbiAgICBjb25zdCBjb25maWcgPSBDb25maWcuZ2V0KGFwcElkLCBnZXRNb3VudEZvclJlcXVlc3QocmVxKSk7XG4gICAgbGV0IGFsbG93SGVhZGVycyA9IERFRkFVTFRfQUxMT1dFRF9IRUFERVJTO1xuICAgIGlmIChjb25maWcgJiYgY29uZmlnLmFsbG93SGVhZGVycykge1xuICAgICAgYWxsb3dIZWFkZXJzICs9IGAsICR7Y29uZmlnLmFsbG93SGVhZGVycy5qb2luKCcsICcpfWA7XG4gICAgfVxuXG4gICAgY29uc3QgYmFzZU9yaWdpbnMgPVxuICAgICAgdHlwZW9mIGNvbmZpZz8uYWxsb3dPcmlnaW4gPT09ICdzdHJpbmcnID8gW2NvbmZpZy5hbGxvd09yaWdpbl0gOiBjb25maWc/LmFsbG93T3JpZ2luID8/IFsnKiddO1xuICAgIGNvbnN0IHJlcXVlc3RPcmlnaW4gPSByZXEuaGVhZGVycy5vcmlnaW47XG4gICAgY29uc3QgYWxsb3dPcmlnaW5zID1cbiAgICAgIHJlcXVlc3RPcmlnaW4gJiYgYmFzZU9yaWdpbnMuaW5jbHVkZXMocmVxdWVzdE9yaWdpbikgPyByZXF1ZXN0T3JpZ2luIDogYmFzZU9yaWdpbnNbMF07XG4gICAgcmVzLmhlYWRlcignQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luJywgYWxsb3dPcmlnaW5zKTtcbiAgICByZXMuaGVhZGVyKCdBY2Nlc3MtQ29udHJvbC1BbGxvdy1NZXRob2RzJywgJ0dFVCxQVVQsUE9TVCxERUxFVEUsT1BUSU9OUycpO1xuICAgIHJlcy5oZWFkZXIoJ0FjY2Vzcy1Db250cm9sLUFsbG93LUhlYWRlcnMnLCBhbGxvd0hlYWRlcnMpO1xuICAgIHJlcy5oZWFkZXIoJ0FjY2Vzcy1Db250cm9sLUV4cG9zZS1IZWFkZXJzJywgJ1gtUGFyc2UtSm9iLVN0YXR1cy1JZCwgWC1QYXJzZS1QdXNoLVN0YXR1cy1JZCcpO1xuICAgIC8vIGludGVyY2VwdCBPUFRJT05TIG1ldGhvZFxuICAgIGlmICgnT1BUSU9OUycgPT0gcmVxLm1ldGhvZCkge1xuICAgICAgcmVzLnNlbmRTdGF0dXMoMjAwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV4dCgpO1xuICAgIH1cbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFsbG93TWV0aG9kT3ZlcnJpZGUocmVxLCByZXMsIG5leHQpIHtcbiAgaWYgKHJlcS5tZXRob2QgPT09ICdQT1NUJyAmJiByZXEuYm9keT8uX21ldGhvZCkge1xuICAgIHJlcS5vcmlnaW5hbE1ldGhvZCA9IHJlcS5tZXRob2Q7XG4gICAgcmVxLm1ldGhvZCA9IHJlcS5ib2R5Ll9tZXRob2Q7XG4gICAgZGVsZXRlIHJlcS5ib2R5Ll9tZXRob2Q7XG4gIH1cbiAgbmV4dCgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFuZGxlUGFyc2VFcnJvcnMoZXJyLCByZXEsIHJlcywgbmV4dCkge1xuICBjb25zdCBsb2cgPSAocmVxLmNvbmZpZyAmJiByZXEuY29uZmlnLmxvZ2dlckNvbnRyb2xsZXIpIHx8IGRlZmF1bHRMb2dnZXI7XG4gIGlmIChlcnIgaW5zdGFuY2VvZiBQYXJzZS5FcnJvcikge1xuICAgIGlmIChyZXEuY29uZmlnICYmIHJlcS5jb25maWcuZW5hYmxlRXhwcmVzc0Vycm9ySGFuZGxlcikge1xuICAgICAgcmV0dXJuIG5leHQoZXJyKTtcbiAgICB9XG4gICAgbGV0IGh0dHBTdGF0dXM7XG4gICAgLy8gVE9ETzogZmlsbCBvdXQgdGhpcyBtYXBwaW5nXG4gICAgc3dpdGNoIChlcnIuY29kZSkge1xuICAgICAgY2FzZSBQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1I6XG4gICAgICAgIGh0dHBTdGF0dXMgPSA1MDA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5EOlxuICAgICAgICBodHRwU3RhdHVzID0gNDA0O1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGh0dHBTdGF0dXMgPSA0MDA7XG4gICAgfVxuICAgIHJlcy5zdGF0dXMoaHR0cFN0YXR1cyk7XG4gICAgcmVzLmpzb24oeyBjb2RlOiBlcnIuY29kZSwgZXJyb3I6IGVyci5tZXNzYWdlIH0pO1xuICAgIGxvZy5lcnJvcignUGFyc2UgZXJyb3I6ICcsIGVycik7XG4gIH0gZWxzZSBpZiAoZXJyLnN0YXR1cyAmJiBlcnIubWVzc2FnZSkge1xuICAgIHJlcy5zdGF0dXMoZXJyLnN0YXR1cyk7XG4gICAgcmVzLmpzb24oeyBlcnJvcjogZXJyLm1lc3NhZ2UgfSk7XG4gICAgaWYgKCEocHJvY2VzcyAmJiBwcm9jZXNzLmVudi5URVNUSU5HKSkge1xuICAgICAgbmV4dChlcnIpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBsb2cuZXJyb3IoJ1VuY2F1Z2h0IGludGVybmFsIHNlcnZlciBlcnJvci4nLCBlcnIsIGVyci5zdGFjayk7XG4gICAgcmVzLnN0YXR1cyg1MDApO1xuICAgIHJlcy5qc29uKHtcbiAgICAgIGNvZGU6IFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUixcbiAgICAgIG1lc3NhZ2U6ICdJbnRlcm5hbCBzZXJ2ZXIgZXJyb3IuJyxcbiAgICB9KTtcbiAgICBpZiAoIShwcm9jZXNzICYmIHByb2Nlc3MuZW52LlRFU1RJTkcpKSB7XG4gICAgICBuZXh0KGVycik7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBlbmZvcmNlTWFzdGVyS2V5QWNjZXNzKHJlcSwgcmVzLCBuZXh0KSB7XG4gIGlmICghcmVxLmF1dGguaXNNYXN0ZXIpIHtcbiAgICBjb25zdCBlcnJvciA9IGNyZWF0ZVNhbml0aXplZEh0dHBFcnJvcig0MDMsICd1bmF1dGhvcml6ZWQ6IG1hc3RlciBrZXkgaXMgcmVxdWlyZWQnLCByZXEuY29uZmlnKTtcbiAgICByZXMuc3RhdHVzKGVycm9yLnN0YXR1cyk7XG4gICAgcmVzLmVuZChge1wiZXJyb3JcIjpcIiR7ZXJyb3IubWVzc2FnZX1cIn1gKTtcbiAgICByZXR1cm47XG4gIH1cbiAgbmV4dCgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MocmVxdWVzdCkge1xuICBpZiAoIXJlcXVlc3QuYXV0aC5pc01hc3Rlcikge1xuICAgIHRocm93IGNyZWF0ZVNhbml0aXplZEh0dHBFcnJvcig0MDMsICd1bmF1dGhvcml6ZWQ6IG1hc3RlciBrZXkgaXMgcmVxdWlyZWQnLCByZXF1ZXN0LmNvbmZpZyk7XG4gIH1cbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG5leHBvcnQgY29uc3QgYWRkUmF0ZUxpbWl0ID0gKHJvdXRlLCBjb25maWcsIGNsb3VkKSA9PiB7XG4gIGlmICh0eXBlb2YgY29uZmlnID09PSAnc3RyaW5nJykge1xuICAgIGNvbmZpZyA9IENvbmZpZy5nZXQoY29uZmlnKTtcbiAgfVxuICBmb3IgKGNvbnN0IGtleSBpbiByb3V0ZSkge1xuICAgIGlmICghUmF0ZUxpbWl0T3B0aW9uc1trZXldKSB7XG4gICAgICB0aHJvdyBgSW52YWxpZCByYXRlIGxpbWl0IG9wdGlvbiBcIiR7a2V5fVwiYDtcbiAgICB9XG4gIH1cbiAgaWYgKCFjb25maWcucmF0ZUxpbWl0cykge1xuICAgIGNvbmZpZy5yYXRlTGltaXRzID0gW107XG4gIH1cbiAgY29uc3QgcmVkaXNTdG9yZSA9IHtcbiAgICBjb25uZWN0aW9uUHJvbWlzZTogUHJvbWlzZS5yZXNvbHZlKCksXG4gICAgc3RvcmU6IG51bGwsXG4gIH07XG4gIGlmIChyb3V0ZS5yZWRpc1VybCkge1xuICAgIGNvbnN0IGxvZyA9IGNvbmZpZz8ubG9nZ2VyQ29udHJvbGxlciB8fCBkZWZhdWx0TG9nZ2VyO1xuICAgIGNvbnN0IGNsaWVudCA9IGNyZWF0ZUNsaWVudCh7XG4gICAgICB1cmw6IHJvdXRlLnJlZGlzVXJsLFxuICAgIH0pO1xuICAgIGNsaWVudC5vbignZXJyb3InLCBlcnIgPT4geyBsb2cuZXJyb3IoJ01pZGRsZXdhcmVzIGFkZFJhdGVMaW1pdCBSZWRpcyBjbGllbnQgZXJyb3InLCB7IGVycm9yOiBlcnIgfSkgfSk7XG4gICAgY2xpZW50Lm9uKCdjb25uZWN0JywgKCkgPT4geyB9KTtcbiAgICBjbGllbnQub24oJ3JlY29ubmVjdGluZycsICgpID0+IHsgfSk7XG4gICAgY2xpZW50Lm9uKCdyZWFkeScsICgpID0+IHsgfSk7XG4gICAgcmVkaXNTdG9yZS5jb25uZWN0aW9uUHJvbWlzZSA9IGFzeW5jICgpID0+IHtcbiAgICAgIGlmIChjbGllbnQuaXNPcGVuKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGNsaWVudC5jb25uZWN0KCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGxvZy5lcnJvcihgQ291bGQgbm90IGNvbm5lY3QgdG8gcmVkaXNVUkwgaW4gcmF0ZSBsaW1pdDogJHtlfWApO1xuICAgICAgfVxuICAgIH07XG4gICAgcmVkaXNTdG9yZS5jb25uZWN0aW9uUHJvbWlzZSgpO1xuICAgIHJlZGlzU3RvcmUuc3RvcmUgPSBuZXcgUmVkaXNTdG9yZSh7XG4gICAgICBzZW5kQ29tbWFuZDogYXN5bmMgKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgYXdhaXQgcmVkaXNTdG9yZS5jb25uZWN0aW9uUHJvbWlzZSgpO1xuICAgICAgICByZXR1cm4gY2xpZW50LnNlbmRDb21tYW5kKGFyZ3MpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuICBsZXQgdHJhbnNmb3JtUGF0aCA9IHJvdXRlLnJlcXVlc3RQYXRoLnNwbGl0KCcvKicpLmpvaW4oJy8oLiopJyk7XG4gIGlmICh0cmFuc2Zvcm1QYXRoID09PSAnKicpIHtcbiAgICB0cmFuc2Zvcm1QYXRoID0gJyguKiknO1xuICB9XG4gIGNvbmZpZy5yYXRlTGltaXRzLnB1c2goe1xuICAgIHBhdGg6IHBhdGhUb1JlZ2V4cCh0cmFuc2Zvcm1QYXRoKSxcbiAgICBoYW5kbGVyOiByYXRlTGltaXQoe1xuICAgICAgd2luZG93TXM6IHJvdXRlLnJlcXVlc3RUaW1lV2luZG93LFxuICAgICAgbWF4OiByb3V0ZS5yZXF1ZXN0Q291bnQsXG4gICAgICBtZXNzYWdlOiByb3V0ZS5lcnJvclJlc3BvbnNlTWVzc2FnZSB8fCBSYXRlTGltaXRPcHRpb25zLmVycm9yUmVzcG9uc2VNZXNzYWdlLmRlZmF1bHQsXG4gICAgICBoYW5kbGVyOiAocmVxdWVzdCwgcmVzcG9uc2UsIG5leHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgdGhyb3cge1xuICAgICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLkNPTk5FQ1RJT05fRkFJTEVELFxuICAgICAgICAgIG1lc3NhZ2U6IG9wdGlvbnMubWVzc2FnZSxcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgICBza2lwOiByZXF1ZXN0ID0+IHtcbiAgICAgICAgaWYgKHJlcXVlc3QuaXAgPT09ICcxMjcuMC4wLjEnICYmICFyb3V0ZS5pbmNsdWRlSW50ZXJuYWxSZXF1ZXN0cykge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyb3V0ZS5pbmNsdWRlTWFzdGVyS2V5KSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyb3V0ZS5yZXF1ZXN0TWV0aG9kcykge1xuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHJvdXRlLnJlcXVlc3RNZXRob2RzKSkge1xuICAgICAgICAgICAgaWYgKCFyb3V0ZS5yZXF1ZXN0TWV0aG9kcy5pbmNsdWRlcyhyZXF1ZXN0Lm1ldGhvZCkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHJlZ0V4cCA9IG5ldyBSZWdFeHAocm91dGUucmVxdWVzdE1ldGhvZHMpO1xuICAgICAgICAgICAgaWYgKCFyZWdFeHAudGVzdChyZXF1ZXN0Lm1ldGhvZCkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXF1ZXN0LmF1dGg/LmlzTWFzdGVyO1xuICAgICAgfSxcbiAgICAgIGtleUdlbmVyYXRvcjogYXN5bmMgcmVxdWVzdCA9PiB7XG4gICAgICAgIGlmIChyb3V0ZS56b25lID09PSBQYXJzZS5TZXJ2ZXIuUmF0ZUxpbWl0Wm9uZS5nbG9iYWwpIHtcbiAgICAgICAgICByZXR1cm4gcmVxdWVzdC5jb25maWcuYXBwSWQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdG9rZW4gPSByZXF1ZXN0LmluZm8uc2Vzc2lvblRva2VuO1xuICAgICAgICBpZiAocm91dGUuem9uZSA9PT0gUGFyc2UuU2VydmVyLlJhdGVMaW1pdFpvbmUuc2Vzc2lvbiAmJiB0b2tlbikge1xuICAgICAgICAgIHJldHVybiB0b2tlbjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocm91dGUuem9uZSA9PT0gUGFyc2UuU2VydmVyLlJhdGVMaW1pdFpvbmUudXNlciAmJiB0b2tlbikge1xuICAgICAgICAgIGlmICghcmVxdWVzdC5hdXRoKSB7XG4gICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZShyZXNvbHZlID0+IGhhbmRsZVBhcnNlU2Vzc2lvbihyZXF1ZXN0LCBudWxsLCByZXNvbHZlKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChyZXF1ZXN0LmF1dGg/LnVzZXI/LmlkICYmIHJlcXVlc3Quem9uZSA9PT0gJ3VzZXInKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVxdWVzdC5hdXRoLnVzZXIuaWQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXF1ZXN0LmNvbmZpZy5pcDtcbiAgICAgIH0sXG4gICAgICBzdG9yZTogcmVkaXNTdG9yZS5zdG9yZSxcbiAgICB9KSxcbiAgICBjbG91ZCxcbiAgfSk7XG4gIENvbmZpZy5wdXQoY29uZmlnKTtcbn07XG5cbi8qKlxuICogRGVkdXBsaWNhdGVzIGEgcmVxdWVzdCB0byBlbnN1cmUgaWRlbXBvdGVuY3kuIER1cGxpY2F0ZXMgYXJlIGRldGVybWluZWQgYnkgdGhlIHJlcXVlc3QgSURcbiAqIGluIHRoZSByZXF1ZXN0IGhlYWRlci4gSWYgYSByZXF1ZXN0IGhhcyBubyByZXF1ZXN0IElELCBpdCBpcyBleGVjdXRlZCBhbnl3YXkuXG4gKiBAcGFyYW0geyp9IHJlcSBUaGUgcmVxdWVzdCB0byBldmFsdWF0ZS5cbiAqIEByZXR1cm5zIFByb21pc2U8e30+XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcm9taXNlRW5zdXJlSWRlbXBvdGVuY3kocmVxKSB7XG4gIC8vIEVuYWJsZSBmZWF0dXJlIG9ubHkgZm9yIE1vbmdvREJcbiAgaWYgKFxuICAgICEoXG4gICAgICByZXEuY29uZmlnLmRhdGFiYXNlLmFkYXB0ZXIgaW5zdGFuY2VvZiBNb25nb1N0b3JhZ2VBZGFwdGVyIHx8XG4gICAgICByZXEuY29uZmlnLmRhdGFiYXNlLmFkYXB0ZXIgaW5zdGFuY2VvZiBQb3N0Z3Jlc1N0b3JhZ2VBZGFwdGVyXG4gICAgKVxuICApIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbiAgLy8gR2V0IHBhcmFtZXRlcnNcbiAgY29uc3QgY29uZmlnID0gcmVxLmNvbmZpZztcbiAgY29uc3QgcmVxdWVzdElkID0gKChyZXEgfHwge30pLmhlYWRlcnMgfHwge30pWyd4LXBhcnNlLXJlcXVlc3QtaWQnXTtcbiAgY29uc3QgeyBwYXRocywgdHRsIH0gPSBjb25maWcuaWRlbXBvdGVuY3lPcHRpb25zO1xuICBpZiAoIXJlcXVlc3RJZCB8fCAhY29uZmlnLmlkZW1wb3RlbmN5T3B0aW9ucykge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuICAvLyBSZXF1ZXN0IHBhdGggbWF5IGNvbnRhaW4gdHJhaWxpbmcgc2xhc2hlcywgZGVwZW5kaW5nIG9uIHRoZSBvcmlnaW5hbCByZXF1ZXN0LCBzbyByZW1vdmVcbiAgLy8gbGVhZGluZyBhbmQgdHJhaWxpbmcgc2xhc2hlcyB0byBtYWtlIGl0IGVhc2llciB0byBzcGVjaWZ5IHBhdGhzIGluIHRoZSBjb25maWd1cmF0aW9uXG4gIGNvbnN0IHJlcVBhdGggPSByZXEucGF0aC5yZXBsYWNlKC9eXFwvfFxcLyQvLCAnJyk7XG4gIC8vIERldGVybWluZSB3aGV0aGVyIGlkZW1wb3RlbmN5IGlzIGVuYWJsZWQgZm9yIGN1cnJlbnQgcmVxdWVzdCBwYXRoXG4gIGxldCBtYXRjaCA9IGZhbHNlO1xuICBmb3IgKGNvbnN0IHBhdGggb2YgcGF0aHMpIHtcbiAgICAvLyBBc3N1bWUgb25lIHdhbnRzIGEgcGF0aCB0byBhbHdheXMgbWF0Y2ggZnJvbSB0aGUgYmVnaW5uaW5nIHRvIHByZXZlbnQgYW55IG1pc3Rha2VzXG4gICAgY29uc3QgcmVnZXggPSBuZXcgUmVnRXhwKHBhdGguY2hhckF0KDApID09PSAnXicgPyBwYXRoIDogJ14nICsgcGF0aCk7XG4gICAgaWYgKHJlcVBhdGgubWF0Y2gocmVnZXgpKSB7XG4gICAgICBtYXRjaCA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgaWYgKCFtYXRjaCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuICAvLyBUcnkgdG8gc3RvcmUgcmVxdWVzdFxuICBjb25zdCBleHBpcnlEYXRlID0gbmV3IERhdGUobmV3IERhdGUoKS5zZXRTZWNvbmRzKG5ldyBEYXRlKCkuZ2V0U2Vjb25kcygpICsgdHRsKSk7XG4gIHJldHVybiByZXN0XG4gICAgLmNyZWF0ZShjb25maWcsIGF1dGgubWFzdGVyKGNvbmZpZyksICdfSWRlbXBvdGVuY3knLCB7XG4gICAgICByZXFJZDogcmVxdWVzdElkLFxuICAgICAgZXhwaXJlOiBQYXJzZS5fZW5jb2RlKGV4cGlyeURhdGUpLFxuICAgIH0pXG4gICAgLmNhdGNoKGUgPT4ge1xuICAgICAgaWYgKGUuY29kZSA9PSBQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkRVUExJQ0FURV9SRVFVRVNULCAnRHVwbGljYXRlIHJlcXVlc3QnKTtcbiAgICAgIH1cbiAgICAgIHRocm93IGU7XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGludmFsaWRSZXF1ZXN0KHJlcSwgcmVzKSB7XG4gIHJlcy5zdGF0dXMoNDAzKTtcbiAgcmVzLmVuZCgne1wiZXJyb3JcIjpcInVuYXV0aG9yaXplZFwifScpO1xufVxuXG5mdW5jdGlvbiBtYWxmb3JtZWRDb250ZXh0KHJlcSwgcmVzKSB7XG4gIHJlcy5zdGF0dXMoNDAwKTtcbiAgcmVzLmpzb24oeyBjb2RlOiBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sIGVycm9yOiAnSW52YWxpZCBvYmplY3QgZm9yIGNvbnRleHQuJyB9KTtcbn1cblxuLyoqXG4gKiBFeHByZXNzIDQgYWxsb3dlZCBhIGRvdWJsZSBmb3J3YXJkIHNsYXNoIGJldHdlZW4gYSByb3V0ZSBhbmQgcm91dGVyLiBBbHRob3VnaFxuICogdGhpcyBzaG91bGQgYmUgY29uc2lkZXJlZCBhbiBhbnRpLXBhdHRlcm4sIHdlIG5lZWQgdG8gc3VwcG9ydCBpdCBmb3IgYmFja3dhcmRzXG4gKiBjb21wYXRpYmlsaXR5LlxuICpcbiAqIFRlY2huaWNhbGx5IHZhbGlkIFVSTCB3aXRoIGRvdWJsZSBmb3Jvd2FyZCBzbGFzaDpcbiAqIGh0dHA6Ly9sb2NhbGhvc3Q6MTMzNy9wYXJzZS8vZnVuY3Rpb25zL3Rlc3RGdW5jdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gYWxsb3dEb3VibGVGb3J3YXJkU2xhc2gocmVxLCByZXMsIG5leHQpIHtcbiAgcmVxLnVybCA9IHJlcS51cmwuc3RhcnRzV2l0aCgnLy8nKSA/IHJlcS51cmwuc3Vic3RyaW5nKDEpIDogcmVxLnVybDtcbiAgbmV4dCgpO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsSUFBQUEsTUFBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsS0FBQSxHQUFBRixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUUsS0FBQSxHQUFBSCxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUcsT0FBQSxHQUFBSixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUksVUFBQSxHQUFBTCxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUssT0FBQSxHQUFBTixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQU0sS0FBQSxHQUFBUCxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQU8sb0JBQUEsR0FBQVIsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFRLHVCQUFBLEdBQUFULHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBUyxpQkFBQSxHQUFBVixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQVUsWUFBQSxHQUFBVixPQUFBO0FBQ0EsSUFBQVcsYUFBQSxHQUFBWCxPQUFBO0FBQ0EsSUFBQVksZUFBQSxHQUFBYixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQWEsTUFBQSxHQUFBYixPQUFBO0FBQ0EsSUFBQWMsSUFBQSxHQUFBZCxPQUFBO0FBQ0EsSUFBQWUsTUFBQSxHQUFBZixPQUFBO0FBQW1ELFNBQUFELHVCQUFBaUIsQ0FBQSxXQUFBQSxDQUFBLElBQUFBLENBQUEsQ0FBQUMsVUFBQSxHQUFBRCxDQUFBLEtBQUFFLE9BQUEsRUFBQUYsQ0FBQTtBQUU1QyxNQUFNRyx1QkFBdUIsR0FBQUMsT0FBQSxDQUFBRCx1QkFBQSxHQUNsQywrT0FBK087QUFFalAsTUFBTUUsa0JBQWtCLEdBQUcsU0FBQUEsQ0FBVUMsR0FBRyxFQUFFO0VBQ3hDLE1BQU1DLGVBQWUsR0FBR0QsR0FBRyxDQUFDRSxX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