parse-server 6.0.0-alpha.2 → 6.0.0-alpha.21

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 (191) hide show
  1. package/README.md +45 -17
  2. package/lib/AccountLockout.js +11 -26
  3. package/lib/Adapters/AdapterLoader.js +8 -14
  4. package/lib/Adapters/Analytics/AnalyticsAdapter.js +2 -8
  5. package/lib/Adapters/Auth/AuthAdapter.js +7 -16
  6. package/lib/Adapters/Auth/OAuth1Client.js +32 -57
  7. package/lib/Adapters/Auth/apple.js +6 -22
  8. package/lib/Adapters/Auth/facebook.js +7 -37
  9. package/lib/Adapters/Auth/gcenter.js +8 -37
  10. package/lib/Adapters/Auth/github.js +7 -10
  11. package/lib/Adapters/Auth/google.js +11 -34
  12. package/lib/Adapters/Auth/gpgames.js +5 -8
  13. package/lib/Adapters/Auth/httpsRequest.js +1 -7
  14. package/lib/Adapters/Auth/index.js +20 -65
  15. package/lib/Adapters/Auth/instagram.js +5 -9
  16. package/lib/Adapters/Auth/janraincapture.js +8 -12
  17. package/lib/Adapters/Auth/janrainengage.js +7 -11
  18. package/lib/Adapters/Auth/keycloak.js +5 -19
  19. package/lib/Adapters/Auth/ldap.js +1 -15
  20. package/lib/Adapters/Auth/line.js +7 -10
  21. package/lib/Adapters/Auth/linkedin.js +7 -12
  22. package/lib/Adapters/Auth/meetup.js +7 -10
  23. package/lib/Adapters/Auth/microsoft.js +7 -10
  24. package/lib/Adapters/Auth/oauth2.js +6 -18
  25. package/lib/Adapters/Auth/phantauth.js +8 -10
  26. package/lib/Adapters/Auth/qq.js +7 -13
  27. package/lib/Adapters/Auth/spotify.js +7 -14
  28. package/lib/Adapters/Auth/twitter.js +5 -15
  29. package/lib/Adapters/Auth/vkontakte.js +9 -15
  30. package/lib/Adapters/Auth/wechat.js +7 -10
  31. package/lib/Adapters/Auth/weibo.js +7 -11
  32. package/lib/Adapters/Cache/CacheAdapter.js +4 -12
  33. package/lib/Adapters/Cache/InMemoryCache.js +5 -19
  34. package/lib/Adapters/Cache/InMemoryCacheAdapter.js +1 -11
  35. package/lib/Adapters/Cache/LRUCache.js +1 -11
  36. package/lib/Adapters/Cache/NullCacheAdapter.js +1 -8
  37. package/lib/Adapters/Cache/RedisCacheAdapter.js +46 -87
  38. package/lib/Adapters/Cache/SchemaCache.js +1 -6
  39. package/lib/Adapters/Email/MailAdapter.js +2 -7
  40. package/lib/Adapters/Files/FilesAdapter.js +7 -21
  41. package/lib/Adapters/Files/GridFSBucketAdapter.js +6 -44
  42. package/lib/Adapters/Files/GridStoreAdapter.js +1 -1
  43. package/lib/Adapters/Logger/LoggerAdapter.js +2 -11
  44. package/lib/Adapters/Logger/WinstonLogger.js +3 -30
  45. package/lib/Adapters/Logger/WinstonLoggerAdapter.js +5 -16
  46. package/lib/Adapters/MessageQueue/EventEmitterMQ.js +3 -20
  47. package/lib/Adapters/PubSub/EventEmitterPubSub.js +1 -16
  48. package/lib/Adapters/PubSub/PubSubAdapter.js +2 -9
  49. package/lib/Adapters/PubSub/RedisPubSub.js +13 -10
  50. package/lib/Adapters/Push/PushAdapter.js +2 -8
  51. package/lib/Adapters/Storage/Mongo/MongoCollection.js +12 -37
  52. package/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js +26 -79
  53. package/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js +78 -209
  54. package/lib/Adapters/Storage/Mongo/MongoTransform.js +82 -371
  55. package/lib/Adapters/Storage/Postgres/PostgresClient.js +1 -13
  56. package/lib/Adapters/Storage/Postgres/PostgresConfigParser.js +1 -20
  57. package/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js +119 -446
  58. package/lib/Adapters/Storage/Postgres/sql/index.js +4 -7
  59. package/lib/Adapters/Storage/StorageAdapter.js +1 -1
  60. package/lib/Adapters/WebSocketServer/WSAdapter.js +3 -12
  61. package/lib/Adapters/WebSocketServer/WSSAdapter.js +7 -12
  62. package/lib/Auth.js +54 -121
  63. package/lib/ClientSDK.js +3 -11
  64. package/lib/Config.js +69 -113
  65. package/lib/Controllers/AdaptableController.js +6 -18
  66. package/lib/Controllers/AnalyticsController.js +1 -9
  67. package/lib/Controllers/CacheController.js +3 -23
  68. package/lib/Controllers/DatabaseController.js +147 -345
  69. package/lib/Controllers/FilesController.js +5 -34
  70. package/lib/Controllers/HooksController.js +1 -51
  71. package/lib/Controllers/LiveQueryController.js +4 -23
  72. package/lib/Controllers/LoggerController.js +15 -54
  73. package/lib/Controllers/ParseGraphQLController.js +49 -104
  74. package/lib/Controllers/PushController.js +20 -59
  75. package/lib/Controllers/SchemaController.js +154 -344
  76. package/lib/Controllers/UserController.js +11 -72
  77. package/lib/Controllers/index.js +19 -68
  78. package/lib/Controllers/types.js +1 -1
  79. package/lib/Deprecator/Deprecations.js +1 -8
  80. package/lib/Deprecator/Deprecator.js +9 -18
  81. package/lib/GraphQL/ParseGraphQLSchema.js +16 -100
  82. package/lib/GraphQL/ParseGraphQLServer.js +2 -29
  83. package/lib/GraphQL/helpers/objectsMutations.js +2 -12
  84. package/lib/GraphQL/helpers/objectsQueries.js +18 -76
  85. package/lib/GraphQL/loaders/defaultGraphQLMutations.js +1 -9
  86. package/lib/GraphQL/loaders/defaultGraphQLQueries.js +1 -8
  87. package/lib/GraphQL/loaders/defaultGraphQLTypes.js +9 -115
  88. package/lib/GraphQL/loaders/defaultRelaySchema.js +6 -18
  89. package/lib/GraphQL/loaders/filesMutations.js +2 -19
  90. package/lib/GraphQL/loaders/functionsMutations.js +6 -17
  91. package/lib/GraphQL/loaders/parseClassMutations.js +6 -44
  92. package/lib/GraphQL/loaders/parseClassQueries.js +1 -26
  93. package/lib/GraphQL/loaders/parseClassTypes.js +10 -64
  94. package/lib/GraphQL/loaders/schemaDirectives.js +1 -17
  95. package/lib/GraphQL/loaders/schemaMutations.js +1 -20
  96. package/lib/GraphQL/loaders/schemaQueries.js +1 -14
  97. package/lib/GraphQL/loaders/schemaTypes.js +2 -6
  98. package/lib/GraphQL/loaders/usersMutations.js +6 -28
  99. package/lib/GraphQL/loaders/usersQueries.js +4 -26
  100. package/lib/GraphQL/parseGraphQLUtils.js +6 -19
  101. package/lib/GraphQL/transformers/className.js +1 -4
  102. package/lib/GraphQL/transformers/constraintType.js +1 -20
  103. package/lib/GraphQL/transformers/inputType.js +1 -20
  104. package/lib/GraphQL/transformers/mutation.js +6 -51
  105. package/lib/GraphQL/transformers/outputType.js +1 -20
  106. package/lib/GraphQL/transformers/query.js +6 -42
  107. package/lib/GraphQL/transformers/schemaFields.js +7 -34
  108. package/lib/KeyPromiseQueue.js +1 -12
  109. package/lib/LiveQuery/Client.js +1 -25
  110. package/lib/LiveQuery/Id.js +1 -7
  111. package/lib/LiveQuery/ParseCloudCodePublisher.js +13 -19
  112. package/lib/LiveQuery/ParseLiveQueryServer.js +92 -306
  113. package/lib/LiveQuery/ParsePubSub.js +1 -12
  114. package/lib/LiveQuery/ParseWebSocketServer.js +4 -26
  115. package/lib/LiveQuery/QueryTools.js +14 -116
  116. package/lib/LiveQuery/RequestSchema.js +1 -1
  117. package/lib/LiveQuery/SessionTokenCache.js +1 -17
  118. package/lib/LiveQuery/Subscription.js +4 -18
  119. package/lib/LiveQuery/equalObjects.js +2 -14
  120. package/lib/Options/Definitions.js +79 -10
  121. package/lib/Options/docs.js +23 -3
  122. package/lib/Options/index.js +4 -12
  123. package/lib/Options/parsers.js +1 -18
  124. package/lib/Page.js +1 -9
  125. package/lib/ParseMessageQueue.js +1 -10
  126. package/lib/ParseServer.js +144 -182
  127. package/lib/ParseServerRESTController.js +6 -33
  128. package/lib/PromiseRouter.js +16 -50
  129. package/lib/Push/PushQueue.js +3 -15
  130. package/lib/Push/PushWorker.js +7 -32
  131. package/lib/Push/utils.js +9 -38
  132. package/lib/RestQuery.js +105 -242
  133. package/lib/RestWrite.js +212 -377
  134. package/lib/Routers/AggregateRouter.js +14 -51
  135. package/lib/Routers/AnalyticsRouter.js +2 -8
  136. package/lib/Routers/AudiencesRouter.js +1 -15
  137. package/lib/Routers/ClassesRouter.js +3 -53
  138. package/lib/Routers/CloudCodeRouter.js +1 -19
  139. package/lib/Routers/FeaturesRouter.js +1 -10
  140. package/lib/Routers/FilesRouter.js +29 -76
  141. package/lib/Routers/FunctionsRouter.js +5 -28
  142. package/lib/Routers/GlobalConfigRouter.js +4 -18
  143. package/lib/Routers/GraphQLRouter.js +1 -14
  144. package/lib/Routers/HooksRouter.js +1 -29
  145. package/lib/Routers/IAPValidationRouter.js +6 -29
  146. package/lib/Routers/InstallationsRouter.js +2 -12
  147. package/lib/Routers/LogsRouter.js +4 -16
  148. package/lib/Routers/PagesRouter.js +69 -129
  149. package/lib/Routers/PublicAPIRouter.js +3 -62
  150. package/lib/Routers/PurgeRouter.js +1 -15
  151. package/lib/Routers/PushRouter.js +2 -18
  152. package/lib/Routers/RolesRouter.js +1 -7
  153. package/lib/Routers/SchemasRouter.js +4 -34
  154. package/lib/Routers/SecurityRouter.js +1 -12
  155. package/lib/Routers/SessionsRouter.js +3 -19
  156. package/lib/Routers/UsersRouter.js +58 -155
  157. package/lib/SchemaMigrations/DefinedSchemas.js +56 -115
  158. package/lib/SchemaMigrations/Migrations.js +2 -8
  159. package/lib/Security/Check.js +8 -16
  160. package/lib/Security/CheckGroup.js +4 -11
  161. package/lib/Security/CheckGroups/CheckGroupDatabase.js +8 -18
  162. package/lib/Security/CheckGroups/CheckGroupServerConfig.js +5 -15
  163. package/lib/Security/CheckGroups/CheckGroups.js +1 -4
  164. package/lib/Security/CheckRunner.js +22 -41
  165. package/lib/StatusHandler.js +12 -69
  166. package/lib/TestUtils.js +1 -6
  167. package/lib/Utils.js +27 -66
  168. package/lib/batch.js +17 -28
  169. package/lib/cache.js +1 -3
  170. package/lib/cli/definitions/parse-live-query-server.js +1 -3
  171. package/lib/cli/definitions/parse-server.js +1 -3
  172. package/lib/cli/parse-live-query-server.js +1 -6
  173. package/lib/cli/parse-server.js +11 -21
  174. package/lib/cli/utils/commander.js +13 -51
  175. package/lib/cli/utils/runner.js +1 -14
  176. package/lib/cloud-code/Parse.Cloud.js +71 -92
  177. package/lib/cryptoUtils.js +11 -19
  178. package/lib/defaults.js +2 -14
  179. package/lib/deprecated.js +1 -2
  180. package/lib/index.js +16 -34
  181. package/lib/logger.js +6 -13
  182. package/lib/middlewares.js +147 -151
  183. package/lib/password.js +6 -10
  184. package/lib/request.js +173 -2
  185. package/lib/requiredParameter.js +1 -3
  186. package/lib/rest.js +19 -41
  187. package/lib/triggers.js +54 -252
  188. package/lib/vendor/mongodbUrl.js +125 -305
  189. package/package.json +22 -19
  190. package/lib/cloud-code/HTTPResponse.js +0 -73
  191. package/lib/cloud-code/httpRequest.js +0 -192
@@ -4,101 +4,62 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  var _Options = require("./Options");
9
-
10
8
  var _defaults = _interopRequireDefault(require("./defaults"));
11
-
12
9
  var logging = _interopRequireWildcard(require("./logger"));
13
-
14
10
  var _Config = _interopRequireDefault(require("./Config"));
15
-
16
11
  var _PromiseRouter = _interopRequireDefault(require("./PromiseRouter"));
17
-
18
12
  var _requiredParameter = _interopRequireDefault(require("./requiredParameter"));
19
-
20
13
  var _AnalyticsRouter = require("./Routers/AnalyticsRouter");
21
-
22
14
  var _ClassesRouter = require("./Routers/ClassesRouter");
23
-
24
15
  var _FeaturesRouter = require("./Routers/FeaturesRouter");
25
-
26
16
  var _FilesRouter = require("./Routers/FilesRouter");
27
-
28
17
  var _FunctionsRouter = require("./Routers/FunctionsRouter");
29
-
30
18
  var _GlobalConfigRouter = require("./Routers/GlobalConfigRouter");
31
-
32
19
  var _GraphQLRouter = require("./Routers/GraphQLRouter");
33
-
34
20
  var _HooksRouter = require("./Routers/HooksRouter");
35
-
36
21
  var _IAPValidationRouter = require("./Routers/IAPValidationRouter");
37
-
38
22
  var _InstallationsRouter = require("./Routers/InstallationsRouter");
39
-
40
23
  var _LogsRouter = require("./Routers/LogsRouter");
41
-
42
24
  var _ParseLiveQueryServer = require("./LiveQuery/ParseLiveQueryServer");
43
-
44
25
  var _PagesRouter = require("./Routers/PagesRouter");
45
-
46
26
  var _PublicAPIRouter = require("./Routers/PublicAPIRouter");
47
-
48
27
  var _PushRouter = require("./Routers/PushRouter");
49
-
50
28
  var _CloudCodeRouter = require("./Routers/CloudCodeRouter");
51
-
52
29
  var _RolesRouter = require("./Routers/RolesRouter");
53
-
54
30
  var _SchemasRouter = require("./Routers/SchemasRouter");
55
-
56
31
  var _SessionsRouter = require("./Routers/SessionsRouter");
57
-
58
32
  var _UsersRouter = require("./Routers/UsersRouter");
59
-
60
33
  var _PurgeRouter = require("./Routers/PurgeRouter");
61
-
62
34
  var _AudiencesRouter = require("./Routers/AudiencesRouter");
63
-
64
35
  var _AggregateRouter = require("./Routers/AggregateRouter");
65
-
66
36
  var _ParseServerRESTController = require("./ParseServerRESTController");
67
-
68
37
  var controllers = _interopRequireWildcard(require("./Controllers"));
69
-
70
38
  var _ParseGraphQLServer = require("./GraphQL/ParseGraphQLServer");
71
-
72
39
  var _SecurityRouter = require("./Routers/SecurityRouter");
73
-
74
40
  var _CheckRunner = _interopRequireDefault(require("./Security/CheckRunner"));
75
-
76
41
  var _Deprecator = _interopRequireDefault(require("./Deprecator/Deprecator"));
77
-
78
42
  var _DefinedSchemas = require("./SchemaMigrations/DefinedSchemas");
79
-
80
43
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
81
-
82
44
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
83
-
84
45
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
85
-
86
46
  // ParseServer - open-source compatible API Server for Parse apps
87
- var batch = require('./batch'),
88
- bodyParser = require('body-parser'),
89
- express = require('express'),
90
- middlewares = require('./middlewares'),
91
- Parse = require('parse/node').Parse,
92
- {
93
- parse
94
- } = require('graphql'),
95
- path = require('path'),
96
- fs = require('fs');
97
47
 
48
+ var batch = require('./batch'),
49
+ bodyParser = require('body-parser'),
50
+ express = require('express'),
51
+ middlewares = require('./middlewares'),
52
+ Parse = require('parse/node').Parse,
53
+ {
54
+ parse
55
+ } = require('graphql'),
56
+ path = require('path'),
57
+ fs = require('fs');
98
58
  // Mutate the Parse object to add the Cloud Code handlers
99
- addParseCloud(); // ParseServer works like a constructor of an express app.
100
- // https://parseplatform.org/parse-server/api/master/ParseServerOptions.html
59
+ addParseCloud();
101
60
 
61
+ // ParseServer works like a constructor of an express app.
62
+ // https://parseplatform.org/parse-server/api/master/ParseServerOptions.html
102
63
  class ParseServer {
103
64
  /**
104
65
  * @constructor
@@ -106,131 +67,154 @@ class ParseServer {
106
67
  */
107
68
  constructor(options) {
108
69
  // Scan for deprecated Parse Server options
109
- _Deprecator.default.scanParseServerOptions(options); // Set option defaults
110
-
111
-
70
+ _Deprecator.default.scanParseServerOptions(options);
71
+ // Set option defaults
112
72
  injectDefaults(options);
113
73
  const {
114
74
  appId = (0, _requiredParameter.default)('You must provide an appId!'),
115
75
  masterKey = (0, _requiredParameter.default)('You must provide a masterKey!'),
116
- cloud,
117
- security,
118
76
  javascriptKey,
119
- serverURL = (0, _requiredParameter.default)('You must provide a serverURL!'),
120
- serverStartComplete,
121
- schema
122
- } = options; // Initialize the node client SDK automatically
123
-
77
+ serverURL = (0, _requiredParameter.default)('You must provide a serverURL!')
78
+ } = options;
79
+ // Initialize the node client SDK automatically
124
80
  Parse.initialize(appId, javascriptKey || 'unused', masterKey);
125
81
  Parse.serverURL = serverURL;
126
82
  const allControllers = controllers.getControllers(options);
127
- const {
128
- loggerController,
129
- databaseController,
130
- hooksController
131
- } = allControllers;
83
+ options.state = 'initialized';
132
84
  this.config = _Config.default.put(Object.assign({}, options, allControllers));
133
- logging.setLogger(loggerController); // Note: Tests will start to fail if any validation happens after this is called.
85
+ logging.setLogger(allControllers.loggerController);
86
+ }
134
87
 
135
- databaseController.performInitialization().then(() => hooksController.load()).then(async () => {
88
+ /**
89
+ * Starts Parse Server as an express app; this promise resolves when Parse Server is ready to accept requests.
90
+ */
91
+
92
+ async start() {
93
+ try {
94
+ if (this.config.state === 'ok') {
95
+ return this;
96
+ }
97
+ this.config.state = 'starting';
98
+ _Config.default.put(this.config);
99
+ const {
100
+ databaseController,
101
+ hooksController,
102
+ cloud,
103
+ security,
104
+ schema,
105
+ cacheAdapter,
106
+ liveQueryController
107
+ } = this.config;
108
+ try {
109
+ await databaseController.performInitialization();
110
+ } catch (e) {
111
+ if (e.code !== Parse.Error.DUPLICATE_VALUE) {
112
+ throw e;
113
+ }
114
+ }
115
+ await hooksController.load();
116
+ const startupPromises = [];
136
117
  if (schema) {
137
- await new _DefinedSchemas.DefinedSchemas(schema, this.config).execute();
118
+ startupPromises.push(new _DefinedSchemas.DefinedSchemas(schema, this.config).execute());
138
119
  }
139
-
140
- if (serverStartComplete) {
141
- serverStartComplete();
120
+ if (cacheAdapter !== null && cacheAdapter !== void 0 && cacheAdapter.connect && typeof cacheAdapter.connect === 'function') {
121
+ startupPromises.push(cacheAdapter.connect());
142
122
  }
143
- }).catch(error => {
144
- if (serverStartComplete) {
145
- serverStartComplete(error);
146
- } else {
147
- console.error(error);
148
- process.exit(1);
123
+ startupPromises.push(liveQueryController.connect());
124
+ await Promise.all(startupPromises);
125
+ if (cloud) {
126
+ addParseCloud();
127
+ if (typeof cloud === 'function') {
128
+ await Promise.resolve(cloud(Parse));
129
+ } else if (typeof cloud === 'string') {
130
+ var _json;
131
+ let json;
132
+ if (process.env.npm_package_json) {
133
+ json = require(process.env.npm_package_json);
134
+ }
135
+ if (process.env.npm_package_type === 'module' || ((_json = json) === null || _json === void 0 ? void 0 : _json.type) === 'module') {
136
+ await import(path.resolve(process.cwd(), cloud)).default;
137
+ } else {
138
+ require(path.resolve(process.cwd(), cloud));
139
+ }
140
+ } else {
141
+ throw "argument 'cloud' must either be a string or a function";
142
+ }
143
+ await new Promise(resolve => setTimeout(resolve, 10));
149
144
  }
150
- });
151
-
152
- if (cloud) {
153
- addParseCloud();
154
-
155
- if (typeof cloud === 'function') {
156
- cloud(Parse);
157
- } else if (typeof cloud === 'string') {
158
- require(path.resolve(process.cwd(), cloud));
159
- } else {
160
- throw "argument 'cloud' must either be a string or a function";
145
+ if (security && security.enableCheck && security.enableCheckLog) {
146
+ new _CheckRunner.default(security).run();
161
147
  }
162
- }
163
-
164
- if (security && security.enableCheck && security.enableCheckLog) {
165
- new _CheckRunner.default(options.security).run();
148
+ this.config.state = 'ok';
149
+ _Config.default.put(this.config);
150
+ return this;
151
+ } catch (error) {
152
+ console.error(error);
153
+ this.config.state = 'error';
154
+ throw error;
166
155
  }
167
156
  }
168
-
169
157
  get app() {
170
158
  if (!this._app) {
171
159
  this._app = ParseServer.app(this.config);
172
160
  }
173
-
174
161
  return this._app;
175
162
  }
176
-
177
163
  handleShutdown() {
178
164
  const promises = [];
179
165
  const {
180
166
  adapter: databaseAdapter
181
167
  } = this.config.databaseController;
182
-
183
168
  if (databaseAdapter && typeof databaseAdapter.handleShutdown === 'function') {
184
169
  promises.push(databaseAdapter.handleShutdown());
185
170
  }
186
-
187
171
  const {
188
172
  adapter: fileAdapter
189
173
  } = this.config.filesController;
190
-
191
174
  if (fileAdapter && typeof fileAdapter.handleShutdown === 'function') {
192
175
  promises.push(fileAdapter.handleShutdown());
193
176
  }
194
-
195
177
  const {
196
178
  adapter: cacheAdapter
197
179
  } = this.config.cacheController;
198
-
199
180
  if (cacheAdapter && typeof cacheAdapter.handleShutdown === 'function') {
200
181
  promises.push(cacheAdapter.handleShutdown());
201
182
  }
202
-
203
183
  return (promises.length > 0 ? Promise.all(promises) : Promise.resolve()).then(() => {
204
184
  if (this.config.serverCloseComplete) {
205
185
  this.config.serverCloseComplete();
206
186
  }
207
187
  });
208
188
  }
189
+
209
190
  /**
210
191
  * @static
211
192
  * Create an express app for the parse server
212
193
  * @param {Object} options let you specify the maxUploadSize when creating the express app */
213
-
214
-
215
194
  static app(options) {
216
195
  const {
217
196
  maxUploadSize = '20mb',
218
197
  appId,
219
198
  directAccess,
220
- pages
221
- } = options; // This app serves the Parse API directly.
199
+ pages,
200
+ rateLimit = []
201
+ } = options;
202
+ // This app serves the Parse API directly.
222
203
  // It's the equivalent of https://api.parse.com/1 in the hosted Parse API.
223
-
224
- var api = express(); //api.use("/apps", express.static(__dirname + "/public"));
225
-
226
- api.use(middlewares.allowCrossDomain(appId)); // File handling needs to be before default middlewares are applied
227
-
204
+ var api = express();
205
+ //api.use("/apps", express.static(__dirname + "/public"));
206
+ api.use(middlewares.allowCrossDomain(appId));
207
+ // File handling needs to be before default middlewares are applied
228
208
  api.use('/', new _FilesRouter.FilesRouter().expressRouter({
229
209
  maxUploadSize: maxUploadSize
230
210
  }));
231
211
  api.use('/health', function (req, res) {
212
+ res.status(options.state === 'ok' ? 200 : 503);
213
+ if (options.state === 'starting') {
214
+ res.set('Retry-After', 1);
215
+ }
232
216
  res.json({
233
- status: 'ok'
217
+ status: options.state
234
218
  });
235
219
  });
236
220
  api.use('/', bodyParser.urlencoded({
@@ -242,15 +226,20 @@ class ParseServer {
242
226
  }));
243
227
  api.use(middlewares.allowMethodOverride);
244
228
  api.use(middlewares.handleParseHeaders);
229
+ const routes = Array.isArray(rateLimit) ? rateLimit : [rateLimit];
230
+ for (const route of routes) {
231
+ middlewares.addRateLimit(route, options);
232
+ }
233
+ api.use(middlewares.handleParseSession);
245
234
  const appRouter = ParseServer.promiseRouter({
246
235
  appId
247
236
  });
248
237
  api.use(appRouter.expressRouter());
249
- api.use(middlewares.handleParseErrors); // run the following when not testing
238
+ api.use(middlewares.handleParseErrors);
250
239
 
240
+ // run the following when not testing
251
241
  if (!process.env.TESTING) {
252
242
  //This causes tests to spew some useless warnings, so disable in test
253
-
254
243
  /* istanbul ignore next */
255
244
  process.on('uncaughtException', err => {
256
245
  if (err.code === 'EADDRINUSE') {
@@ -260,22 +249,18 @@ class ParseServer {
260
249
  } else {
261
250
  throw err;
262
251
  }
263
- }); // verify the server url after a 'mount' event is received
264
-
252
+ });
253
+ // verify the server url after a 'mount' event is received
265
254
  /* istanbul ignore next */
266
-
267
255
  api.on('mount', function () {
268
256
  ParseServer.verifyServerUrl();
269
257
  });
270
258
  }
271
-
272
259
  if (process.env.PARSE_SERVER_ENABLE_EXPERIMENTAL_DIRECT_ACCESS === '1' || directAccess) {
273
260
  Parse.CoreManager.setRESTController((0, _ParseServerRESTController.ParseServerRESTController)(appId, appRouter));
274
261
  }
275
-
276
262
  return api;
277
263
  }
278
-
279
264
  static promiseRouter({
280
265
  appId
281
266
  }) {
@@ -287,20 +272,23 @@ class ParseServer {
287
272
  batch.mountOnto(appRouter);
288
273
  return appRouter;
289
274
  }
275
+
290
276
  /**
291
277
  * starts the parse server's express app
292
278
  * @param {ParseServerOptions} options to use to start the server
293
- * @param {Function} callback called when the server has started
294
279
  * @returns {ParseServer} the parse server instance
295
280
  */
296
281
 
297
-
298
- start(options, callback) {
282
+ async startApp(options) {
283
+ try {
284
+ await this.start();
285
+ } catch (e) {
286
+ console.error('Error on ParseServer.startApp: ', e);
287
+ throw e;
288
+ }
299
289
  const app = express();
300
-
301
290
  if (options.middleware) {
302
291
  let middleware;
303
-
304
292
  if (typeof options.middleware == 'string') {
305
293
  middleware = require(path.resolve(process.cwd(), options.middleware));
306
294
  } else {
@@ -309,96 +297,86 @@ class ParseServer {
309
297
 
310
298
  app.use(middleware);
311
299
  }
312
-
313
300
  app.use(options.mountPath, this.app);
314
-
315
301
  if (options.mountGraphQL === true || options.mountPlayground === true) {
316
302
  let graphQLCustomTypeDefs = undefined;
317
-
318
303
  if (typeof options.graphQLSchema === 'string') {
319
304
  graphQLCustomTypeDefs = parse(fs.readFileSync(options.graphQLSchema, 'utf8'));
320
305
  } else if (typeof options.graphQLSchema === 'object' || typeof options.graphQLSchema === 'function') {
321
306
  graphQLCustomTypeDefs = options.graphQLSchema;
322
307
  }
323
-
324
308
  const parseGraphQLServer = new _ParseGraphQLServer.ParseGraphQLServer(this, {
325
309
  graphQLPath: options.graphQLPath,
326
310
  playgroundPath: options.playgroundPath,
327
311
  graphQLCustomTypeDefs
328
312
  });
329
-
330
313
  if (options.mountGraphQL) {
331
314
  parseGraphQLServer.applyGraphQL(app);
332
315
  }
333
-
334
316
  if (options.mountPlayground) {
335
317
  parseGraphQLServer.applyPlayground(app);
336
318
  }
337
319
  }
338
-
339
- const server = app.listen(options.port, options.host, callback);
320
+ const server = await new Promise(resolve => {
321
+ app.listen(options.port, options.host, function () {
322
+ resolve(this);
323
+ });
324
+ });
340
325
  this.server = server;
341
-
342
326
  if (options.startLiveQueryServer || options.liveQueryServerOptions) {
343
- this.liveQueryServer = ParseServer.createLiveQueryServer(server, options.liveQueryServerOptions, options);
327
+ this.liveQueryServer = await ParseServer.createLiveQueryServer(server, options.liveQueryServerOptions, options);
328
+ }
329
+ if (options.trustProxy) {
330
+ app.set('trust proxy', options.trustProxy);
344
331
  }
345
332
  /* istanbul ignore next */
346
-
347
-
348
333
  if (!process.env.TESTING) {
349
334
  configureListeners(this);
350
335
  }
351
-
352
336
  this.expressApp = app;
353
337
  return this;
354
338
  }
339
+
355
340
  /**
356
341
  * Creates a new ParseServer and starts it.
357
342
  * @param {ParseServerOptions} options used to start the server
358
- * @param {Function} callback called when the server has started
359
343
  * @returns {ParseServer} the parse server instance
360
344
  */
361
-
362
-
363
- static start(options, callback) {
345
+ static async startApp(options) {
364
346
  const parseServer = new ParseServer(options);
365
- return parseServer.start(options, callback);
347
+ return parseServer.startApp(options);
366
348
  }
349
+
367
350
  /**
368
351
  * Helper method to create a liveQuery server
369
352
  * @static
370
353
  * @param {Server} httpServer an optional http server to pass
371
354
  * @param {LiveQueryServerOptions} config options for the liveQueryServer
372
355
  * @param {ParseServerOptions} options options for the ParseServer
373
- * @returns {ParseLiveQueryServer} the live query server instance
356
+ * @returns {Promise<ParseLiveQueryServer>} the live query server instance
374
357
  */
375
-
376
-
377
- static createLiveQueryServer(httpServer, config, options) {
358
+ static async createLiveQueryServer(httpServer, config, options) {
378
359
  if (!httpServer || config && config.port) {
379
360
  var app = express();
380
361
  httpServer = require('http').createServer(app);
381
362
  httpServer.listen(config.port);
382
363
  }
383
-
384
- return new _ParseLiveQueryServer.ParseLiveQueryServer(httpServer, config, options);
364
+ const server = new _ParseLiveQueryServer.ParseLiveQueryServer(httpServer, config, options);
365
+ await server.connect();
366
+ return server;
385
367
  }
386
-
387
368
  static verifyServerUrl(callback) {
388
369
  // perform a health check on the serverURL value
389
370
  if (Parse.serverURL) {
390
371
  const request = require('./request');
391
-
392
372
  request({
393
373
  url: Parse.serverURL.replace(/\/$/, '') + '/health'
394
374
  }).catch(response => response).then(response => {
395
375
  const json = response.data || null;
396
-
397
376
  if (response.status !== 200 || !json || json && json.status !== 'ok') {
398
377
  /* eslint-disable no-console */
399
378
  console.warn(`\nWARNING, Unable to connect to '${Parse.serverURL}'.` + ` Cloud code and push notifications may be unavailable!\n`);
400
379
  /* eslint-enable no-console */
401
-
402
380
  if (callback) {
403
381
  callback(false);
404
382
  }
@@ -410,73 +388,63 @@ class ParseServer {
410
388
  });
411
389
  }
412
390
  }
413
-
414
391
  }
415
-
416
392
  function addParseCloud() {
417
393
  const ParseCloud = require('./cloud-code/Parse.Cloud');
418
-
419
394
  Object.defineProperty(Parse, 'Server', {
420
395
  get() {
421
396
  return _Config.default.get(Parse.applicationId);
422
397
  },
423
-
424
398
  set(newVal) {
425
399
  newVal.appId = Parse.applicationId;
426
-
427
400
  _Config.default.put(newVal);
428
401
  },
429
-
430
402
  configurable: true
431
403
  });
432
404
  Object.assign(Parse.Cloud, ParseCloud);
433
405
  global.Parse = Parse;
434
406
  }
435
-
436
407
  function injectDefaults(options) {
437
408
  Object.keys(_defaults.default).forEach(key => {
438
409
  if (!Object.prototype.hasOwnProperty.call(options, key)) {
439
410
  options[key] = _defaults.default[key];
440
411
  }
441
412
  });
442
-
443
413
  if (!Object.prototype.hasOwnProperty.call(options, 'serverURL')) {
444
414
  options.serverURL = `http://localhost:${options.port}${options.mountPath}`;
445
- } // Reserved Characters
446
-
415
+ }
447
416
 
417
+ // Reserved Characters
448
418
  if (options.appId) {
449
419
  const regex = /[!#$%'()*+&/:;=?@[\]{}^,|<>]/g;
450
-
451
420
  if (options.appId.match(regex)) {
452
421
  console.warn(`\nWARNING, appId that contains special characters can cause issues while using with urls.\n`);
453
422
  }
454
- } // Backwards compatibility
455
-
423
+ }
456
424
 
425
+ // Backwards compatibility
457
426
  if (options.userSensitiveFields) {
458
427
  /* eslint-disable no-console */
459
428
  !process.env.TESTING && console.warn(`\nDEPRECATED: userSensitiveFields has been replaced by protectedFields allowing the ability to protect fields in all classes with CLP. \n`);
460
429
  /* eslint-enable no-console */
461
430
 
462
- const userSensitiveFields = Array.from(new Set([...(_defaults.default.userSensitiveFields || []), ...(options.userSensitiveFields || [])])); // If the options.protectedFields is unset,
431
+ const userSensitiveFields = Array.from(new Set([...(_defaults.default.userSensitiveFields || []), ...(options.userSensitiveFields || [])]));
432
+
433
+ // If the options.protectedFields is unset,
463
434
  // it'll be assigned the default above.
464
435
  // Here, protect against the case where protectedFields
465
436
  // is set, but doesn't have _User.
466
-
467
437
  if (!('_User' in options.protectedFields)) {
468
438
  options.protectedFields = Object.assign({
469
439
  _User: []
470
440
  }, options.protectedFields);
471
441
  }
472
-
473
442
  options.protectedFields['_User']['*'] = Array.from(new Set([...(options.protectedFields['_User']['*'] || []), ...userSensitiveFields]));
474
- } // Merge protectedFields options with defaults.
475
-
443
+ }
476
444
 
445
+ // Merge protectedFields options with defaults.
477
446
  Object.keys(_defaults.default.protectedFields).forEach(c => {
478
447
  const cur = options.protectedFields[c];
479
-
480
448
  if (!cur) {
481
449
  options.protectedFields[c] = _defaults.default.protectedFields[c];
482
450
  } else {
@@ -487,17 +455,15 @@ function injectDefaults(options) {
487
455
  }
488
456
  });
489
457
  options.masterKeyIps = Array.from(new Set(options.masterKeyIps.concat(_defaults.default.masterKeyIps, options.masterKeyIps)));
490
- } // Those can't be tested as it requires a subprocess
458
+ }
491
459
 
460
+ // Those can't be tested as it requires a subprocess
492
461
  /* istanbul ignore next */
493
-
494
-
495
462
  function configureListeners(parseServer) {
496
463
  const server = parseServer.server;
497
464
  const sockets = {};
498
465
  /* Currently, express doesn't shut down immediately after receiving SIGINT/SIGTERM if it has client connections that haven't timed out. (This is a known issue with node - https://github.com/nodejs/node/issues/2642)
499
466
  This function, along with `destroyAliveConnections()`, intend to fix this behavior such that parse server will close all open connections and initiate the shutdown process as soon as it receives a SIGINT/SIGTERM signal. */
500
-
501
467
  server.on('connection', socket => {
502
468
  const socketId = socket.remoteAddress + ':' + socket.remotePort;
503
469
  sockets[socketId] = socket;
@@ -505,7 +471,6 @@ function configureListeners(parseServer) {
505
471
  delete sockets[socketId];
506
472
  });
507
473
  });
508
-
509
474
  const destroyAliveConnections = function () {
510
475
  for (const socketId in sockets) {
511
476
  try {
@@ -515,18 +480,15 @@ function configureListeners(parseServer) {
515
480
  }
516
481
  }
517
482
  };
518
-
519
483
  const handleShutdown = function () {
520
484
  process.stdout.write('Termination signal received. Shutting down.');
521
485
  destroyAliveConnections();
522
486
  server.close();
523
487
  parseServer.handleShutdown();
524
488
  };
525
-
526
489
  process.on('SIGTERM', handleShutdown);
527
490
  process.on('SIGINT', handleShutdown);
528
491
  }
529
-
530
492
  var _default = ParseServer;
531
493
  exports.default = _default;
532
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9QYXJzZVNlcnZlci5qcyJdLCJuYW1lcyI6WyJiYXRjaCIsInJlcXVpcmUiLCJib2R5UGFyc2VyIiwiZXhwcmVzcyIsIm1pZGRsZXdhcmVzIiwiUGFyc2UiLCJwYXJzZSIsInBhdGgiLCJmcyIsImFkZFBhcnNlQ2xvdWQiLCJQYXJzZVNlcnZlciIsImNvbnN0cnVjdG9yIiwib3B0aW9ucyIsIkRlcHJlY2F0b3IiLCJzY2FuUGFyc2VTZXJ2ZXJPcHRpb25zIiwiaW5qZWN0RGVmYXVsdHMiLCJhcHBJZCIsIm1hc3RlcktleSIsImNsb3VkIiwic2VjdXJpdHkiLCJqYXZhc2NyaXB0S2V5Iiwic2VydmVyVVJMIiwic2VydmVyU3RhcnRDb21wbGV0ZSIsInNjaGVtYSIsImluaXRpYWxpemUiLCJhbGxDb250cm9sbGVycyIsImNvbnRyb2xsZXJzIiwiZ2V0Q29udHJvbGxlcnMiLCJsb2dnZXJDb250cm9sbGVyIiwiZGF0YWJhc2VDb250cm9sbGVyIiwiaG9va3NDb250cm9sbGVyIiwiY29uZmlnIiwiQ29uZmlnIiwicHV0IiwiT2JqZWN0IiwiYXNzaWduIiwibG9nZ2luZyIsInNldExvZ2dlciIsInBlcmZvcm1Jbml0aWFsaXphdGlvbiIsInRoZW4iLCJsb2FkIiwiRGVmaW5lZFNjaGVtYXMiLCJleGVjdXRlIiwiY2F0Y2giLCJlcnJvciIsImNvbnNvbGUiLCJwcm9jZXNzIiwiZXhpdCIsInJlc29sdmUiLCJjd2QiLCJlbmFibGVDaGVjayIsImVuYWJsZUNoZWNrTG9nIiwiQ2hlY2tSdW5uZXIiLCJydW4iLCJhcHAiLCJfYXBwIiwiaGFuZGxlU2h1dGRvd24iLCJwcm9taXNlcyIsImFkYXB0ZXIiLCJkYXRhYmFzZUFkYXB0ZXIiLCJwdXNoIiwiZmlsZUFkYXB0ZXIiLCJmaWxlc0NvbnRyb2xsZXIiLCJjYWNoZUFkYXB0ZXIiLCJjYWNoZUNvbnRyb2xsZXIiLCJsZW5ndGgiLCJQcm9taXNlIiwiYWxsIiwic2VydmVyQ2xvc2VDb21wbGV0ZSIsIm1heFVwbG9hZFNpemUiLCJkaXJlY3RBY2Nlc3MiLCJwYWdlcyIsImFwaSIsInVzZSIsImFsbG93Q3Jvc3NEb21haW4iLCJGaWxlc1JvdXRlciIsImV4cHJlc3NSb3V0ZXIiLCJyZXEiLCJyZXMiLCJqc29uIiwic3RhdHVzIiwidXJsZW5jb2RlZCIsImV4dGVuZGVkIiwiZW5hYmxlUm91dGVyIiwiUGFnZXNSb3V0ZXIiLCJQdWJsaWNBUElSb3V0ZXIiLCJ0eXBlIiwibGltaXQiLCJhbGxvd01ldGhvZE92ZXJyaWRlIiwiaGFuZGxlUGFyc2VIZWFkZXJzIiwiYXBwUm91dGVyIiwicHJvbWlzZVJvdXRlciIsImhhbmRsZVBhcnNlRXJyb3JzIiwiZW52IiwiVEVTVElORyIsIm9uIiwiZXJyIiwiY29kZSIsInN0ZGVyciIsIndyaXRlIiwicG9ydCIsInZlcmlmeVNlcnZlclVybCIsIlBBUlNFX1NFUlZFUl9FTkFCTEVfRVhQRVJJTUVOVEFMX0RJUkVDVF9BQ0NFU1MiLCJDb3JlTWFuYWdlciIsInNldFJFU1RDb250cm9sbGVyIiwicm91dGVycyIsIkNsYXNzZXNSb3V0ZXIiLCJVc2Vyc1JvdXRlciIsIlNlc3Npb25zUm91dGVyIiwiUm9sZXNSb3V0ZXIiLCJBbmFseXRpY3NSb3V0ZXIiLCJJbnN0YWxsYXRpb25zUm91dGVyIiwiRnVuY3Rpb25zUm91dGVyIiwiU2NoZW1hc1JvdXRlciIsIlB1c2hSb3V0ZXIiLCJMb2dzUm91dGVyIiwiSUFQVmFsaWRhdGlvblJvdXRlciIsIkZlYXR1cmVzUm91dGVyIiwiR2xvYmFsQ29uZmlnUm91dGVyIiwiR3JhcGhRTFJvdXRlciIsIlB1cmdlUm91dGVyIiwiSG9va3NSb3V0ZXIiLCJDbG91ZENvZGVSb3V0ZXIiLCJBdWRpZW5jZXNSb3V0ZXIiLCJBZ2dyZWdhdGVSb3V0ZXIiLCJTZWN1cml0eVJvdXRlciIsInJvdXRlcyIsInJlZHVjZSIsIm1lbW8iLCJyb3V0ZXIiLCJjb25jYXQiLCJQcm9taXNlUm91dGVyIiwibW91bnRPbnRvIiwic3RhcnQiLCJjYWxsYmFjayIsIm1pZGRsZXdhcmUiLCJtb3VudFBhdGgiLCJtb3VudEdyYXBoUUwiLCJtb3VudFBsYXlncm91bmQiLCJncmFwaFFMQ3VzdG9tVHlwZURlZnMiLCJ1bmRlZmluZWQiLCJncmFwaFFMU2NoZW1hIiwicmVhZEZpbGVTeW5jIiwicGFyc2VHcmFwaFFMU2VydmVyIiwiUGFyc2VHcmFwaFFMU2VydmVyIiwiZ3JhcGhRTFBhdGgiLCJwbGF5Z3JvdW5kUGF0aCIsImFwcGx5R3JhcGhRTCIsImFwcGx5UGxheWdyb3VuZCIsInNlcnZlciIsImxpc3RlbiIsImhvc3QiLCJzdGFydExpdmVRdWVyeVNlcnZlciIsImxpdmVRdWVyeVNlcnZlck9wdGlvbnMiLCJsaXZlUXVlcnlTZXJ2ZXIiLCJjcmVhdGVMaXZlUXVlcnlTZXJ2ZXIiLCJjb25maWd1cmVMaXN0ZW5lcnMiLCJleHByZXNzQXBwIiwicGFyc2VTZXJ2ZXIiLCJodHRwU2VydmVyIiwiY3JlYXRlU2VydmVyIiwiUGFyc2VMaXZlUXVlcnlTZXJ2ZXIiLCJyZXF1ZXN0IiwidXJsIiwicmVwbGFjZSIsInJlc3BvbnNlIiwiZGF0YSIsIndhcm4iLCJQYXJzZUNsb3VkIiwiZGVmaW5lUHJvcGVydHkiLCJnZXQiLCJhcHBsaWNhdGlvbklkIiwic2V0IiwibmV3VmFsIiwiY29uZmlndXJhYmxlIiwiQ2xvdWQiLCJnbG9iYWwiLCJrZXlzIiwiZGVmYXVsdHMiLCJmb3JFYWNoIiwia2V5IiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwicmVnZXgiLCJtYXRjaCIsInVzZXJTZW5zaXRpdmVGaWVsZHMiLCJBcnJheSIsImZyb20iLCJTZXQiLCJwcm90ZWN0ZWRGaWVsZHMiLCJfVXNlciIsImMiLCJjdXIiLCJyIiwidW5xIiwibWFzdGVyS2V5SXBzIiwic29ja2V0cyIsInNvY2tldCIsInNvY2tldElkIiwicmVtb3RlQWRkcmVzcyIsInJlbW90ZVBvcnQiLCJkZXN0cm95QWxpdmVDb25uZWN0aW9ucyIsImRlc3Ryb3kiLCJlIiwic3Rkb3V0IiwiY2xvc2UiXSwibWFw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QUFPLENBQUMrSixNQUFSLENBQWUxRyxLQUFmLENBQXFCLDZDQUFyQjtBQUNBdUcsSUFBQUEsdUJBQXVCO0FBQ3ZCckQsSUFBQUEsTUFBTSxDQUFDeUQsS0FBUDtBQUNBaEQsSUFBQUEsV0FBVyxDQUFDdEcsY0FBWjtBQUNELEdBTEQ7O0FBTUFWLEVBQUFBLE9BQU8sQ0FBQ2lELEVBQVIsQ0FBVyxTQUFYLEVBQXNCdkMsY0FBdEI7QUFDQVYsRUFBQUEsT0FBTyxDQUFDaUQsRUFBUixDQUFXLFFBQVgsRUFBcUJ2QyxjQUFyQjtBQUNEOztlQUVjOUMsVyIsInNvdXJjZXNDb250ZW50IjpbIi8vIFBhcnNlU2VydmVyIC0gb3Blbi1zb3VyY2UgY29tcGF0aWJsZSBBUEkgU2VydmVyIGZvciBQYXJzZSBhcHBzXG5cbnZhciBiYXRjaCA9IHJlcXVpcmUoJy4vYmF0Y2gnKSxcbiAgYm9keVBhcnNlciA9IHJlcXVpcmUoJ2JvZHktcGFyc2VyJyksXG4gIGV4cHJlc3MgPSByZXF1aXJlKCdleHByZXNzJyksXG4gIG1pZGRsZXdhcmVzID0gcmVxdWlyZSgnLi9taWRkbGV3YXJlcycpLFxuICBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZSxcbiAgeyBwYXJzZSB9ID0gcmVxdWlyZSgnZ3JhcGhxbCcpLFxuICBwYXRoID0gcmVxdWlyZSgncGF0aCcpLFxuICBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG5cbmltcG9ydCB7IFBhcnNlU2VydmVyT3B0aW9ucywgTGl2ZVF1ZXJ5U2VydmVyT3B0aW9ucyB9IGZyb20gJy4vT3B0aW9ucyc7XG5pbXBvcnQgZGVmYXVsdHMgZnJvbSAnLi9kZWZhdWx0cyc7XG5pbXBvcnQgKiBhcyBsb2dnaW5nIGZyb20gJy4vbG9nZ2VyJztcbmltcG9ydCBDb25maWcgZnJvbSAnLi9Db25maWcnO1xuaW1wb3J0IFByb21pc2VSb3V0ZXIgZnJvbSAnLi9Qcm9taXNlUm91dGVyJztcbmltcG9ydCByZXF1aXJlZFBhcmFtZXRlciBmcm9tICcuL3JlcXVpcmVkUGFyYW1ldGVyJztcbmltcG9ydCB7IEFuYWx5dGljc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9BbmFseXRpY3NSb3V0ZXInO1xuaW1wb3J0IHsgQ2xhc3Nlc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9DbGFzc2VzUm91dGVyJztcbmltcG9ydCB7IEZlYXR1cmVzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0ZlYXR1cmVzUm91dGVyJztcbmltcG9ydCB7IEZpbGVzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0ZpbGVzUm91dGVyJztcbmltcG9ydCB7IEZ1bmN0aW9uc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9GdW5jdGlvbnNSb3V0ZXInO1xuaW1wb3J0IHsgR2xvYmFsQ29uZmlnUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0dsb2JhbENvbmZpZ1JvdXRlcic7XG5pbXBvcnQgeyBHcmFwaFFMUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0dyYXBoUUxSb3V0ZXInO1xuaW1wb3J0IHsgSG9va3NSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvSG9va3NSb3V0ZXInO1xuaW1wb3J0IHsgSUFQVmFsaWRhdGlvblJvdXRlciB9IGZyb20gJy4vUm91dGVycy9JQVBWYWxpZGF0aW9uUm91dGVyJztcbmltcG9ydCB7IEluc3RhbGxhdGlvbnNSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvSW5zdGFsbGF0aW9uc1JvdXRlcic7XG5pbXBvcnQgeyBMb2dzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0xvZ3NSb3V0ZXInO1xuaW1wb3J0IHsgUGFyc2VMaXZlUXVlcnlTZXJ2ZXIgfSBmcm9tICcuL0xpdmVRdWVyeS9QYXJzZUxpdmVRdWVyeVNlcnZlcic7XG5pbXBvcnQgeyBQYWdlc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9QYWdlc1JvdXRlcic7XG5pbXBvcnQgeyBQdWJsaWNBUElSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvUHVibGljQVBJUm91dGVyJztcbmltcG9ydCB7IFB1c2hSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvUHVzaFJvdXRlcic7XG5pbXBvcnQgeyBDbG91ZENvZGVSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvQ2xvdWRDb2RlUm91dGVyJztcbmltcG9ydCB7IFJvbGVzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL1JvbGVzUm91dGVyJztcbmltcG9ydCB7IFNjaGVtYXNSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvU2NoZW1hc1JvdXRlcic7XG5pbXBvcnQgeyBTZXNzaW9uc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9TZXNzaW9uc1JvdXRlcic7XG5pbXBvcnQgeyBVc2Vyc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9Vc2Vyc1JvdXRlcic7XG5pbXBvcnQgeyBQdXJnZVJvdXRlciB9IGZyb20gJy4vUm91dGVycy9QdXJnZVJvdXRlcic7XG5pbXBvcnQgeyBBdWRpZW5jZXNSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvQXVkaWVuY2VzUm91dGVyJztcbmltcG9ydCB7IEFnZ3JlZ2F0ZVJvdXRlciB9IGZyb20gJy4vUm91dGVycy9BZ2dyZWdhdGVSb3V0ZXInO1xuaW1wb3J0IHsgUGFyc2VTZXJ2ZXJSRVNUQ29udHJvbGxlciB9IGZyb20gJy4vUGFyc2VTZXJ2ZXJSRVNUQ29udHJvbGxlcic7XG5pbXBvcnQgKiBhcyBjb250cm9sbGVycyBmcm9tICcuL0NvbnRyb2xsZXJzJztcbmltcG9ydCB7IFBhcnNlR3JhcGhRTFNlcnZlciB9IGZyb20gJy4vR3JhcGhRTC9QYXJzZUdyYXBoUUxTZXJ2ZXInO1xuaW1wb3J0IHsgU2VjdXJpdHlSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvU2VjdXJpdHlSb3V0ZXInO1xuaW1wb3J0IENoZWNrUnVubmVyIGZyb20gJy4vU2VjdXJpdHkvQ2hlY2tSdW5uZXInO1xuaW1wb3J0IERlcHJlY2F0b3IgZnJvbSAnLi9EZXByZWNhdG9yL0RlcHJlY2F0b3InO1xuaW1wb3J0IHsgRGVmaW5lZFNjaGVtYXMgfSBmcm9tICcuL1NjaGVtYU1pZ3JhdGlvbnMvRGVmaW5lZFNjaGVtYXMnO1xuXG4vLyBNdXRhdGUgdGhlIFBhcnNlIG9iamVjdCB0byBhZGQgdGhlIENsb3VkIENvZGUgaGFuZGxlcnNcbmFkZFBhcnNlQ2xvdWQoKTtcblxuLy8gUGFyc2VTZXJ2ZXIgd29ya3MgbGlrZSBhIGNvbnN0cnVjdG9yIG9mIGFuIGV4cHJlc3MgYXBwLlxuLy8gaHR0cHM6Ly9wYXJzZXBsYXRmb3JtLm9yZy9wYXJzZS1zZXJ2ZXIvYXBpL21hc3Rlci9QYXJzZVNlcnZlck9wdGlvbnMuaHRtbFxuY2xhc3MgUGFyc2VTZXJ2ZXIge1xuICAvKipcbiAgICogQGNvbnN0cnVjdG9yXG4gICAqIEBwYXJhbSB7UGFyc2VTZXJ2ZXJPcHRpb25zfSBvcHRpb25zIHRoZSBwYXJzZSBzZXJ2ZXIgaW5pdGlhbGl6YXRpb24gb3B0aW9uc1xuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9uczogUGFyc2VTZXJ2ZXJPcHRpb25zKSB7XG4gICAgLy8gU2NhbiBmb3IgZGVwcmVjYXRlZCBQYXJzZSBTZXJ2ZXIgb3B0aW9uc1xuICAgIERlcHJlY2F0b3Iuc2NhblBhcnNlU2VydmVyT3B0aW9ucyhvcHRpb25zKTtcbiAgICAvLyBTZXQgb3B0aW9uIGRlZmF1bHRzXG4gICAgaW5qZWN0RGVmYXVsdHMob3B0aW9ucyk7XG4gICAgY29uc3Qge1xuICAgICAgYXBwSWQgPSByZXF1aXJlZFBhcmFtZXRlcignWW91IG11c3QgcHJvdmlkZSBhbiBhcHBJZCEnKSxcbiAgICAgIG1hc3RlcktleSA9IHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGEgbWFzdGVyS2V5IScpLFxuICAgICAgY2xvdWQsXG4gICAgICBzZWN1cml0eSxcbiAgICAgIGphdmFzY3JpcHRLZXksXG4gICAgICBzZXJ2ZXJVUkwgPSByZXF1aXJlZFBhcmFtZXRlcignWW91IG11c3QgcHJvdmlkZSBhIHNlcnZlclVSTCEnKSxcbiAgICAgIHNlcnZlclN0YXJ0Q29tcGxldGUsXG4gICAgICBzY2hlbWEsXG4gICAgfSA9IG9wdGlvbnM7XG4gICAgLy8gSW5pdGlhbGl6ZSB0aGUgbm9kZSBjbGllbnQgU0RLIGF1dG9tYXRpY2FsbHlcbiAgICBQYXJzZS5pbml0aWFsaXplKGFwcElkLCBqYXZhc2NyaXB0S2V5IHx8ICd1bnVzZWQnLCBtYXN0ZXJLZXkpO1xuICAgIFBhcnNlLnNlcnZlclVSTCA9IHNlcnZlclVSTDtcblxuICAgIGNvbnN0IGFsbENvbnRyb2xsZXJzID0gY29udHJvbGxlcnMuZ2V0Q29udHJvbGxlcnMob3B0aW9ucyk7XG5cbiAgICBjb25zdCB7IGxvZ2dlckNvbnRyb2xsZXIsIGRhdGFiYXNlQ29udHJvbGxlciwgaG9va3NDb250cm9sbGVyIH0gPSBhbGxDb250cm9sbGVycztcbiAgICB0aGlzLmNvbmZpZyA9IENvbmZpZy5wdXQoT2JqZWN0LmFzc2lnbih7fSwgb3B0aW9ucywgYWxsQ29udHJvbGxlcnMpKTtcblxuICAgIGxvZ2dpbmcuc2V0TG9nZ2VyKGxvZ2dlckNvbnRyb2xsZXIpO1xuXG4gICAgLy8gTm90ZTogVGVzdHMgd2lsbCBzdGFydCB0byBmYWlsIGlmIGFueSB2YWxpZGF0aW9uIGhhcHBlbnMgYWZ0ZXIgdGhpcyBpcyBjYWxsZWQuXG4gICAgZGF0YWJhc2VDb250cm9sbGVyXG4gICAgICAucGVyZm9ybUluaXRpYWxpemF0aW9uKClcbiAgICAgIC50aGVuKCgpID0+IGhvb2tzQ29udHJvbGxlci5sb2FkKCkpXG4gICAgICAudGhlbihhc3luYyAoKSA9PiB7XG4gICAgICAgIGlmIChzY2hlbWEpIHtcbiAgICAgICAgICBhd2FpdCBuZXcgRGVmaW5lZFNjaGVtYXMoc2NoZW1hLCB0aGlzLmNvbmZpZykuZXhlY3V0ZSgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZXJ2ZXJTdGFydENvbXBsZXRlKSB7XG4gICAgICAgICAgc2VydmVyU3RhcnRDb21wbGV0ZSgpO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKHNlcnZlclN0YXJ0Q29tcGxldGUpIHtcbiAgICAgICAgICBzZXJ2ZXJTdGFydENvbXBsZXRlKGVycm9yKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgaWYgKGNsb3VkKSB7XG4gICAgICBhZGRQYXJzZUNsb3VkKCk7XG4gICAgICBpZiAodHlwZW9mIGNsb3VkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGNsb3VkKFBhcnNlKTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGNsb3VkID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXF1aXJlKHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBjbG91ZCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgXCJhcmd1bWVudCAnY2xvdWQnIG11c3QgZWl0aGVyIGJlIGEgc3RyaW5nIG9yIGEgZnVuY3Rpb25cIjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2VjdXJpdHkgJiYgc2VjdXJpdHkuZW5hYmxlQ2hlY2sgJiYgc2VjdXJpdHkuZW5hYmxlQ2hlY2tMb2cpIHtcbiAgICAgIG5ldyBDaGVja1J1bm5lcihvcHRpb25zLnNlY3VyaXR5KS5ydW4oKTtcbiAgICB9XG4gIH1cblxuICBnZXQgYXBwKCkge1xuICAgIGlmICghdGhpcy5fYXBwKSB7XG4gICAgICB0aGlzLl9hcHAgPSBQYXJzZVNlcnZlci5hcHAodGhpcy5jb25maWcpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fYXBwO1xuICB9XG5cbiAgaGFuZGxlU2h1dGRvd24oKSB7XG4gICAgY29uc3QgcHJvbWlzZXMgPSBbXTtcbiAgICBjb25zdCB7IGFkYXB0ZXI6IGRhdGFiYXNlQWRhcHRlciB9ID0gdGhpcy5jb25maWcuZGF0YWJhc2VDb250cm9sbGVyO1xuICAgIGlmIChkYXRhYmFzZUFkYXB0ZXIgJiYgdHlwZW9mIGRhdGFiYXNlQWRhcHRlci5oYW5kbGVTaHV0ZG93biA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcHJvbWlzZXMucHVzaChkYXRhYmFzZUFkYXB0ZXIuaGFuZGxlU2h1dGRvd24oKSk7XG4gICAgfVxuICAgIGNvbnN0IHsgYWRhcHRlcjogZmlsZUFkYXB0ZXIgfSA9IHRoaXMuY29uZmlnLmZpbGVzQ29udHJvbGxlcjtcbiAgICBpZiAoZmlsZUFkYXB0ZXIgJiYgdHlwZW9mIGZpbGVBZGFwdGVyLmhhbmRsZVNodXRkb3duID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwcm9taXNlcy5wdXNoKGZpbGVBZGFwdGVyLmhhbmRsZVNodXRkb3duKCkpO1xuICAgIH1cbiAgICBjb25zdCB7IGFkYXB0ZXI6IGNhY2hlQWRhcHRlciB9ID0gdGhpcy5jb25maWcuY2FjaGVDb250cm9sbGVyO1xuICAgIGlmIChjYWNoZUFkYXB0ZXIgJiYgdHlwZW9mIGNhY2hlQWRhcHRlci5oYW5kbGVTaHV0ZG93biA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcHJvbWlzZXMucHVzaChjYWNoZUFkYXB0ZXIuaGFuZGxlU2h1dGRvd24oKSk7XG4gICAgfVxuICAgIHJldHVybiAocHJvbWlzZXMubGVuZ3RoID4gMCA/IFByb21pc2UuYWxsKHByb21pc2VzKSA6IFByb21pc2UucmVzb2x2ZSgpKS50aGVuKCgpID0+IHtcbiAgICAgIGlmICh0aGlzLmNvbmZpZy5zZXJ2ZXJDbG9zZUNvbXBsZXRlKSB7XG4gICAgICAgIHRoaXMuY29uZmlnLnNlcnZlckNsb3NlQ29tcGxldGUoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3RhdGljXG4gICAqIENyZWF0ZSBhbiBleHByZXNzIGFwcCBmb3IgdGhlIHBhcnNlIHNlcnZlclxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBsZXQgeW91IHNwZWNpZnkgdGhlIG1heFVwbG9hZFNpemUgd2hlbiBjcmVhdGluZyB0aGUgZXhwcmVzcyBhcHAgICovXG4gIHN0YXRpYyBhcHAob3B0aW9ucykge1xuICAgIGNvbnN0IHsgbWF4VXBsb2FkU2l6ZSA9ICcyMG1iJywgYXBwSWQsIGRpcmVjdEFjY2VzcywgcGFnZXMgfSA9IG9wdGlvbnM7XG4gICAgLy8gVGhpcyBhcHAgc2VydmVzIHRoZSBQYXJzZSBBUEkgZGlyZWN0bHkuXG4gICAgLy8gSXQncyB0aGUgZXF1aXZhbGVudCBvZiBodHRwczovL2FwaS5wYXJzZS5jb20vMSBpbiB0aGUgaG9zdGVkIFBhcnNlIEFQSS5cbiAgICB2YXIgYXBpID0gZXhwcmVzcygpO1xuICAgIC8vYXBpLnVzZShcIi9hcHBzXCIsIGV4cHJlc3Muc3RhdGljKF9fZGlybmFtZSArIFwiL3B1YmxpY1wiKSk7XG4gICAgYXBpLnVzZShtaWRkbGV3YXJlcy5hbGxvd0Nyb3NzRG9tYWluKGFwcElkKSk7XG4gICAgLy8gRmlsZSBoYW5kbGluZyBuZWVkcyB0byBiZSBiZWZvcmUgZGVmYXVsdCBtaWRkbGV3YXJlcyBhcmUgYXBwbGllZFxuICAgIGFwaS51c2UoXG4gICAgICAnLycsXG4gICAgICBuZXcgRmlsZXNSb3V0ZXIoKS5leHByZXNzUm91dGVyKHtcbiAgICAgICAgbWF4VXBsb2FkU2l6ZTogbWF4VXBsb2FkU2l6ZSxcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIGFwaS51c2UoJy9oZWFsdGgnLCBmdW5jdGlvbiAocmVxLCByZXMpIHtcbiAgICAgIHJlcy5qc29uKHtcbiAgICAgICAgc3RhdHVzOiAnb2snLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBhcGkudXNlKFxuICAgICAgJy8nLFxuICAgICAgYm9keVBhcnNlci51cmxlbmNvZGVkKHsgZXh0ZW5kZWQ6IGZhbHNlIH0pLFxuICAgICAgcGFnZXMuZW5hYmxlUm91dGVyXG4gICAgICAgID8gbmV3IFBhZ2VzUm91dGVyKHBhZ2VzKS5leHByZXNzUm91dGVyKClcbiAgICAgICAgOiBuZXcgUHVibGljQVBJUm91dGVyKCkuZXhwcmVzc1JvdXRlcigpXG4gICAgKTtcblxuICAgIGFwaS51c2UoYm9keVBhcnNlci5qc29uKHsgdHlwZTogJyovKicsIGxpbWl0OiBtYXhVcGxvYWRTaXplIH0pKTtcbiAgICBhcGkudXNlKG1pZGRsZXdhcmVzLmFsbG93TWV0aG9kT3ZlcnJpZGUpO1xuICAgIGFwaS51c2UobWlkZGxld2FyZXMuaGFuZGxlUGFyc2VIZWFkZXJzKTtcblxuICAgIGNvbnN0IGFwcFJvdXRlciA9IFBhcnNlU2VydmVyLnByb21pc2VSb3V0ZXIoeyBhcHBJZCB9KTtcbiAgICBhcGkudXNlKGFwcFJvdXRlci5leHByZXNzUm91dGVyKCkpO1xuXG4gICAgYXBpLnVzZShtaWRkbGV3YXJlcy5oYW5kbGVQYXJzZUVycm9ycyk7XG5cbiAgICAvLyBydW4gdGhlIGZvbGxvd2luZyB3aGVuIG5vdCB0ZXN0aW5nXG4gICAgaWYgKCFwcm9jZXNzLmVudi5URVNUSU5HKSB7XG4gICAgICAvL1RoaXMgY2F1c2VzIHRlc3RzIHRvIHNwZXcgc29tZSB1c2VsZXNzIHdhcm5pbmdzLCBzbyBkaXNhYmxlIGluIHRlc3RcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICBwcm9jZXNzLm9uKCd1bmNhdWdodEV4Y2VwdGlvbicsIGVyciA9PiB7XG4gICAgICAgIGlmIChlcnIuY29kZSA9PT0gJ0VBRERSSU5VU0UnKSB7XG4gICAgICAgICAgLy8gdXNlci1mcmllbmRseSBtZXNzYWdlIGZvciB0aGlzIGNvbW1vbiBlcnJvclxuICAgICAgICAgIHByb2Nlc3Muc3RkZXJyLndyaXRlKGBVbmFibGUgdG8gbGlzdGVuIG9uIHBvcnQgJHtlcnIucG9ydH0uIFRoZSBwb3J0IGlzIGFscmVhZHkgaW4gdXNlLmApO1xuICAgICAgICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgLy8gdmVyaWZ5IHRoZSBzZXJ2ZXIgdXJsIGFmdGVyIGEgJ21vdW50JyBldmVudCBpcyByZWNlaXZlZFxuICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgIGFwaS5vbignbW91bnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIFBhcnNlU2VydmVyLnZlcmlmeVNlcnZlclVybCgpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChwcm9jZXNzLmVudi5QQVJTRV9TRVJWRVJfRU5BQkxFX0VYUEVSSU1FTlRBTF9ESVJFQ1RfQUNDRVNTID09PSAnMScgfHwgZGlyZWN0QWNjZXNzKSB7XG4gICAgICBQYXJzZS5Db3JlTWFuYWdlci5zZXRSRVNUQ29udHJvbGxlcihQYXJzZVNlcnZlclJFU1RDb250cm9sbGVyKGFwcElkLCBhcHBSb3V0ZXIpKTtcbiAgICB9XG4gICAgcmV0dXJuIGFwaTtcbiAgfVxuXG4gIHN0YXRpYyBwcm9taXNlUm91dGVyKHsgYXBwSWQgfSkge1xuICAgIGNvbnN0IHJvdXRlcnMgPSBbXG4gICAgICBuZXcgQ2xhc3Nlc1JvdXRlcigpLFxuICAgICAgbmV3IFVzZXJzUm91dGVyKCksXG4gICAgICBuZXcgU2Vzc2lvbnNSb3V0ZXIoKSxcbiAgICAgIG5ldyBSb2xlc1JvdXRlcigpLFxuICAgICAgbmV3IEFuYWx5dGljc1JvdXRlcigpLFxuICAgICAgbmV3IEluc3RhbGxhdGlvbnNSb3V0ZXIoKSxcbiAgICAgIG5ldyBGdW5jdGlvbnNSb3V0ZXIoKSxcbiAgICAgIG5ldyBTY2hlbWFzUm91dGVyKCksXG4gICAgICBuZXcgUHVzaFJvdXRlcigpLFxuICAgICAgbmV3IExvZ3NSb3V0ZXIoKSxcbiAgICAgIG5ldyBJQVBWYWxpZGF0aW9uUm91dGVyKCksXG4gICAgICBuZXcgRmVhdHVyZXNSb3V0ZXIoKSxcbiAgICAgIG5ldyBHbG9iYWxDb25maWdSb3V0ZXIoKSxcbiAgICAgIG5ldyBHcmFwaFFMUm91dGVyKCksXG4gICAgICBuZXcgUHVyZ2VSb3V0ZXIoKSxcbiAgICAgIG5ldyBIb29rc1JvdXRlcigpLFxuICAgICAgbmV3IENsb3VkQ29kZVJvdXRlcigpLFxuICAgICAgbmV3IEF1ZGllbmNlc1JvdXRlcigpLFxuICAgICAgbmV3IEFnZ3JlZ2F0ZVJvdXRlcigpLFxuICAgICAgbmV3IFNlY3VyaXR5Um91dGVyKCksXG4gICAgXTtcblxuICAgIGNvbnN0IHJvdXRlcyA9IHJvdXRlcnMucmVkdWNlKChtZW1vLCByb3V0ZXIpID0+IHtcbiAgICAgIHJldHVybiBtZW1vLmNvbmNhdChyb3V0ZXIucm91dGVzKTtcbiAgICB9LCBbXSk7XG5cbiAgICBjb25zdCBhcHBSb3V0ZXIgPSBuZXcgUHJvbWlzZVJvdXRlcihyb3V0ZXMsIGFwcElkKTtcblxuICAgIGJhdGNoLm1vdW50T250byhhcHBSb3V0ZXIpO1xuICAgIHJldHVybiBhcHBSb3V0ZXI7XG4gIH1cblxuICAvKipcbiAgICogc3RhcnRzIHRoZSBwYXJzZSBzZXJ2ZXIncyBleHByZXNzIGFwcFxuICAgKiBAcGFyYW0ge1BhcnNlU2VydmVyT3B0aW9uc30gb3B0aW9ucyB0byB1c2UgdG8gc3RhcnQgdGhlIHNlcnZlclxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBjYWxsZWQgd2hlbiB0aGUgc2VydmVyIGhhcyBzdGFydGVkXG4gICAqIEByZXR1cm5zIHtQYXJzZVNlcnZlcn0gdGhlIHBhcnNlIHNlcnZlciBpbnN0YW5jZVxuICAgKi9cbiAgc3RhcnQob3B0aW9uczogUGFyc2VTZXJ2ZXJPcHRpb25zLCBjYWxsYmFjazogPygpID0+IHZvaWQpIHtcbiAgICBjb25zdCBhcHAgPSBleHByZXNzKCk7XG4gICAgaWYgKG9wdGlvbnMubWlkZGxld2FyZSkge1xuICAgICAgbGV0IG1pZGRsZXdhcmU7XG4gICAgICBpZiAodHlwZW9mIG9wdGlvbnMubWlkZGxld2FyZSA9PSAnc3RyaW5nJykge1xuICAgICAgICBtaWRkbGV3YXJlID0gcmVxdWlyZShwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSwgb3B0aW9ucy5taWRkbGV3YXJlKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtaWRkbGV3YXJlID0gb3B0aW9ucy5taWRkbGV3YXJlOyAvLyB1c2UgYXMtaXMgbGV0IGV4cHJlc3MgZmFpbFxuICAgICAgfVxuICAgICAgYXBwLnVzZShtaWRkbGV3YXJlKTtcbiAgICB9XG5cbiAgICBhcHAudXNlKG9wdGlvbnMubW91bnRQYXRoLCB0aGlzLmFwcCk7XG5cbiAgICBpZiAob3B0aW9ucy5tb3VudEdyYXBoUUwgPT09IHRydWUgfHwgb3B0aW9ucy5tb3VudFBsYXlncm91bmQgPT09IHRydWUpIHtcbiAgICAgIGxldCBncmFwaFFMQ3VzdG9tVHlwZURlZnMgPSB1bmRlZmluZWQ7XG4gICAgICBpZiAodHlwZW9mIG9wdGlvbnMuZ3JhcGhRTFNjaGVtYSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgZ3JhcGhRTEN1c3RvbVR5cGVEZWZzID0gcGFyc2UoZnMucmVhZEZpbGVTeW5jKG9wdGlvbnMuZ3JhcGhRTFNjaGVtYSwgJ3V0ZjgnKSk7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICB0eXBlb2Ygb3B0aW9ucy5ncmFwaFFMU2NoZW1hID09PSAnb2JqZWN0JyB8fFxuICAgICAgICB0eXBlb2Ygb3B0aW9ucy5ncmFwaFFMU2NoZW1hID09PSAnZnVuY3Rpb24nXG4gICAgICApIHtcbiAgICAgICAgZ3JhcGhRTEN1c3RvbVR5cGVEZWZzID0gb3B0aW9ucy5ncmFwaFFMU2NoZW1hO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwYXJzZUdyYXBoUUxTZXJ2ZXIgPSBuZXcgUGFyc2VHcmFwaFFMU2VydmVyKHRoaXMsIHtcbiAgICAgICAgZ3JhcGhRTFBhdGg6IG9wdGlvbnMuZ3JhcGhRTFBhdGgsXG4gICAgICAgIHBsYXlncm91bmRQYXRoOiBvcHRpb25zLnBsYXlncm91bmRQYXRoLFxuICAgICAgICBncmFwaFFMQ3VzdG9tVHlwZURlZnMsXG4gICAgICB9KTtcblxuICAgICAgaWYgKG9wdGlvbnMubW91bnRHcmFwaFFMKSB7XG4gICAgICAgIHBhcnNlR3JhcGhRTFNlcnZlci5hcHBseUdyYXBoUUwoYXBwKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wdGlvbnMubW91bnRQbGF5Z3JvdW5kKSB7XG4gICAgICAgIHBhcnNlR3JhcGhRTFNlcnZlci5hcHBseVBsYXlncm91bmQoYXBwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzZXJ2ZXIgPSBhcHAubGlzdGVuKG9wdGlvbnMucG9ydCwgb3B0aW9ucy5ob3N0LCBjYWxsYmFjayk7XG4gICAgdGhpcy5zZXJ2ZXIgPSBzZXJ2ZXI7XG5cbiAgICBpZiAob3B0aW9ucy5zdGFydExpdmVRdWVyeVNlcnZlciB8fCBvcHRpb25zLmxpdmVRdWVyeVNlcnZlck9wdGlvbnMpIHtcbiAgICAgIHRoaXMubGl2ZVF1ZXJ5U2VydmVyID0gUGFyc2VTZXJ2ZXIuY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyKFxuICAgICAgICBzZXJ2ZXIsXG4gICAgICAgIG9wdGlvbnMubGl2ZVF1ZXJ5U2VydmVyT3B0aW9ucyxcbiAgICAgICAgb3B0aW9uc1xuICAgICAgKTtcbiAgICB9XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBpZiAoIXByb2Nlc3MuZW52LlRFU1RJTkcpIHtcbiAgICAgIGNvbmZpZ3VyZUxpc3RlbmVycyh0aGlzKTtcbiAgICB9XG4gICAgdGhpcy5leHByZXNzQXBwID0gYXBwO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgUGFyc2VTZXJ2ZXIgYW5kIHN0YXJ0cyBpdC5cbiAgICogQHBhcmFtIHtQYXJzZVNlcnZlck9wdGlvbnN9IG9wdGlvbnMgdXNlZCB0byBzdGFydCB0aGUgc2VydmVyXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIGNhbGxlZCB3aGVuIHRoZSBzZXJ2ZXIgaGFzIHN0YXJ0ZWRcbiAgICogQHJldHVybnMge1BhcnNlU2VydmVyfSB0aGUgcGFyc2Ugc2VydmVyIGluc3RhbmNlXG4gICAqL1xuICBzdGF0aWMgc3RhcnQob3B0aW9uczogUGFyc2VTZXJ2ZXJPcHRpb25zLCBjYWxsYmFjazogPygpID0+IHZvaWQpIHtcbiAgICBjb25zdCBwYXJzZVNlcnZlciA9IG5ldyBQYXJzZVNlcnZlcihvcHRpb25zKTtcbiAgICByZXR1cm4gcGFyc2VTZXJ2ZXIuc3RhcnQob3B0aW9ucywgY2FsbGJhY2spO1xuICB9XG5cbiAgLyoqXG4gICAqIEhlbHBlciBtZXRob2QgdG8gY3JlYXRlIGEgbGl2ZVF1ZXJ5IHNlcnZlclxuICAgKiBAc3RhdGljXG4gICAqIEBwYXJhbSB7U2VydmVyfSBodHRwU2VydmVyIGFuIG9wdGlvbmFsIGh0dHAgc2VydmVyIHRvIHBhc3NcbiAgICogQHBhcmFtIHtMaXZlUXVlcnlTZXJ2ZXJPcHRpb25zfSBjb25maWcgb3B0aW9ucyBmb3IgdGhlIGxpdmVRdWVyeVNlcnZlclxuICAgKiBAcGFyYW0ge1BhcnNlU2VydmVyT3B0aW9uc30gb3B0aW9ucyBvcHRpb25zIGZvciB0aGUgUGFyc2VTZXJ2ZXJcbiAgICogQHJldHVybnMge1BhcnNlTGl2ZVF1ZXJ5U2VydmVyfSB0aGUgbGl2ZSBxdWVyeSBzZXJ2ZXIgaW5zdGFuY2VcbiAgICovXG4gIHN0YXRpYyBjcmVhdGVMaXZlUXVlcnlTZXJ2ZXIoXG4gICAgaHR0cFNlcnZlcixcbiAgICBjb25maWc6IExpdmVRdWVyeVNlcnZlck9wdGlvbnMsXG4gICAgb3B0aW9uczogUGFyc2VTZXJ2ZXJPcHRpb25zXG4gICkge1xuICAgIGlmICghaHR0cFNlcnZlciB8fCAoY29uZmlnICYmIGNvbmZpZy5wb3J0KSkge1xuICAgICAgdmFyIGFwcCA9IGV4cHJlc3MoKTtcbiAgICAgIGh0dHBTZXJ2ZXIgPSByZXF1aXJlKCdodHRwJykuY3JlYXRlU2VydmVyKGFwcCk7XG4gICAgICBodHRwU2VydmVyLmxpc3Rlbihjb25maWcucG9ydCk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgUGFyc2VMaXZlUXVlcnlTZXJ2ZXIoaHR0cFNlcnZlciwgY29uZmlnLCBvcHRpb25zKTtcbiAgfVxuXG4gIHN0YXRpYyB2ZXJpZnlTZXJ2ZXJVcmwoY2FsbGJhY2spIHtcbiAgICAvLyBwZXJmb3JtIGEgaGVhbHRoIGNoZWNrIG9uIHRoZSBzZXJ2ZXJVUkwgdmFsdWVcbiAgICBpZiAoUGFyc2Uuc2VydmVyVVJMKSB7XG4gICAgICBjb25zdCByZXF1ZXN0ID0gcmVxdWlyZSgnLi9yZXF1ZXN0Jyk7XG4gICAgICByZXF1ZXN0KHsgdXJsOiBQYXJzZS5zZXJ2ZXJVUkwucmVwbGFjZSgvXFwvJC8sICcnKSArICcvaGVhbHRoJyB9KVxuICAgICAgICAuY2F0Y2gocmVzcG9uc2UgPT4gcmVzcG9uc2UpXG4gICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICBjb25zdCBqc29uID0gcmVzcG9uc2UuZGF0YSB8fCBudWxsO1xuICAgICAgICAgIGlmIChyZXNwb25zZS5zdGF0dXMgIT09IDIwMCB8fCAhanNvbiB8fCAoanNvbiAmJiBqc29uLnN0YXR1cyAhPT0gJ29rJykpIHtcbiAgICAgICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgYFxcbldBUk5JTkcsIFVuYWJsZSB0byBjb25uZWN0IHRvICcke1BhcnNlLnNlcnZlclVSTH0nLmAgK1xuICAgICAgICAgICAgICAgIGAgQ2xvdWQgY29kZSBhbmQgcHVzaCBub3RpZmljYXRpb25zIG1heSBiZSB1bmF2YWlsYWJsZSFcXG5gXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuby1jb25zb2xlICovXG4gICAgICAgICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgY2FsbGJhY2soZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgY2FsbGJhY2sodHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWRkUGFyc2VDbG91ZCgpIHtcbiAgY29uc3QgUGFyc2VDbG91ZCA9IHJlcXVpcmUoJy4vY2xvdWQtY29kZS9QYXJzZS5DbG91ZCcpO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUGFyc2UsICdTZXJ2ZXInLCB7XG4gICAgZ2V0KCkge1xuICAgICAgcmV0dXJuIENvbmZpZy5nZXQoUGFyc2UuYXBwbGljYXRpb25JZCk7XG4gICAgfSxcbiAgICBzZXQobmV3VmFsKSB7XG4gICAgICBuZXdWYWwuYXBwSWQgPSBQYXJzZS5hcHBsaWNhdGlvbklkO1xuICAgICAgQ29uZmlnLnB1dChuZXdWYWwpO1xuICAgIH0sXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICB9KTtcbiAgT2JqZWN0LmFzc2lnbihQYXJzZS5DbG91ZCwgUGFyc2VDbG91ZCk7XG4gIGdsb2JhbC5QYXJzZSA9IFBhcnNlO1xufVxuXG5mdW5jdGlvbiBpbmplY3REZWZhdWx0cyhvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMpIHtcbiAgT2JqZWN0LmtleXMoZGVmYXVsdHMpLmZvckVhY2goa2V5ID0+IHtcbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvcHRpb25zLCBrZXkpKSB7XG4gICAgICBvcHRpb25zW2tleV0gPSBkZWZhdWx0c1trZXldO1xuICAgIH1cbiAgfSk7XG5cbiAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob3B0aW9ucywgJ3NlcnZlclVSTCcpKSB7XG4gICAgb3B0aW9ucy5zZXJ2ZXJVUkwgPSBgaHR0cDovL2xvY2FsaG9zdDoke29wdGlvbnMucG9ydH0ke29wdGlvbnMubW91bnRQYXRofWA7XG4gIH1cblxuICAvLyBSZXNlcnZlZCBDaGFyYWN0ZXJzXG4gIGlmIChvcHRpb25zLmFwcElkKSB7XG4gICAgY29uc3QgcmVnZXggPSAvWyEjJCUnKCkqKyYvOjs9P0BbXFxde31eLHw8Pl0vZztcbiAgICBpZiAob3B0aW9ucy5hcHBJZC5tYXRjaChyZWdleCkpIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgYFxcbldBUk5JTkcsIGFwcElkIHRoYXQgY29udGFpbnMgc3BlY2lhbCBjaGFyYWN0ZXJzIGNhbiBjYXVzZSBpc3N1ZXMgd2hpbGUgdXNpbmcgd2l0aCB1cmxzLlxcbmBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLy8gQmFja3dhcmRzIGNvbXBhdGliaWxpdHlcbiAgaWYgKG9wdGlvbnMudXNlclNlbnNpdGl2ZUZpZWxkcykge1xuICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbiAgICAhcHJvY2Vzcy5lbnYuVEVTVElORyAmJlxuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBgXFxuREVQUkVDQVRFRDogdXNlclNlbnNpdGl2ZUZpZWxkcyBoYXMgYmVlbiByZXBsYWNlZCBieSBwcm90ZWN0ZWRGaWVsZHMgYWxsb3dpbmcgdGhlIGFiaWxpdHkgdG8gcHJvdGVjdCBmaWVsZHMgaW4gYWxsIGNsYXNzZXMgd2l0aCBDTFAuIFxcbmBcbiAgICAgICk7XG4gICAgLyogZXNsaW50LWVuYWJsZSBuby1jb25zb2xlICovXG5cbiAgICBjb25zdCB1c2VyU2Vuc2l0aXZlRmllbGRzID0gQXJyYXkuZnJvbShcbiAgICAgIG5ldyBTZXQoWy4uLihkZWZhdWx0cy51c2VyU2Vuc2l0aXZlRmllbGRzIHx8IFtdKSwgLi4uKG9wdGlvbnMudXNlclNlbnNpdGl2ZUZpZWxkcyB8fCBbXSldKVxuICAgICk7XG5cbiAgICAvLyBJZiB0aGUgb3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHMgaXMgdW5zZXQsXG4gICAgLy8gaXQnbGwgYmUgYXNzaWduZWQgdGhlIGRlZmF1bHQgYWJvdmUuXG4gICAgLy8gSGVyZSwgcHJvdGVjdCBhZ2FpbnN0IHRoZSBjYXNlIHdoZXJlIHByb3RlY3RlZEZpZWxkc1xuICAgIC8vIGlzIHNldCwgYnV0IGRvZXNuJ3QgaGF2ZSBfVXNlci5cbiAgICBpZiAoISgnX1VzZXInIGluIG9wdGlvbnMucHJvdGVjdGVkRmllbGRzKSkge1xuICAgICAgb3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHMgPSBPYmplY3QuYXNzaWduKHsgX1VzZXI6IFtdIH0sIG9wdGlvbnMucHJvdGVjdGVkRmllbGRzKTtcbiAgICB9XG5cbiAgICBvcHRpb25zLnByb3RlY3RlZEZpZWxkc1snX1VzZXInXVsnKiddID0gQXJyYXkuZnJvbShcbiAgICAgIG5ldyBTZXQoWy4uLihvcHRpb25zLnByb3RlY3RlZEZpZWxkc1snX1VzZXInXVsnKiddIHx8IFtdKSwgLi4udXNlclNlbnNpdGl2ZUZpZWxkc10pXG4gICAgKTtcbiAgfVxuXG4gIC8vIE1lcmdlIHByb3RlY3RlZEZpZWxkcyBvcHRpb25zIHdpdGggZGVmYXVsdHMuXG4gIE9iamVjdC5rZXlzKGRlZmF1bHRzLnByb3RlY3RlZEZpZWxkcykuZm9yRWFjaChjID0+IHtcbiAgICBjb25zdCBjdXIgPSBvcHRpb25zLnByb3RlY3RlZEZpZWxkc1tjXTtcbiAgICBpZiAoIWN1cikge1xuICAgICAgb3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHNbY10gPSBkZWZhdWx0cy5wcm90ZWN0ZWRGaWVsZHNbY107XG4gICAgfSBlbHNlIHtcbiAgICAgIE9iamVjdC5rZXlzKGRlZmF1bHRzLnByb3RlY3RlZEZpZWxkc1tjXSkuZm9yRWFjaChyID0+IHtcbiAgICAgICAgY29uc3QgdW5xID0gbmV3IFNldChbXG4gICAgICAgICAgLi4uKG9wdGlvbnMucHJvdGVjdGVkRmllbGRzW2NdW3JdIHx8IFtdKSxcbiAgICAgICAgICAuLi5kZWZhdWx0cy5wcm90ZWN0ZWRGaWVsZHNbY11bcl0sXG4gICAgICAgIF0pO1xuICAgICAgICBvcHRpb25zLnByb3RlY3RlZEZpZWxkc1tjXVtyXSA9IEFycmF5LmZyb20odW5xKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgb3B0aW9ucy5tYXN0ZXJLZXlJcHMgPSBBcnJheS5mcm9tKFxuICAgIG5ldyBTZXQob3B0aW9ucy5tYXN0ZXJLZXlJcHMuY29uY2F0KGRlZmF1bHRzLm1hc3RlcktleUlwcywgb3B0aW9ucy5tYXN0ZXJLZXlJcHMpKVxuICApO1xufVxuXG4vLyBUaG9zZSBjYW4ndCBiZSB0ZXN0ZWQgYXMgaXQgcmVxdWlyZXMgYSBzdWJwcm9jZXNzXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuZnVuY3Rpb24gY29uZmlndXJlTGlzdGVuZXJzKHBhcnNlU2VydmVyKSB7XG4gIGNvbnN0IHNlcnZlciA9IHBhcnNlU2VydmVyLnNlcnZlcjtcbiAgY29uc3Qgc29ja2V0cyA9IHt9O1xuICAvKiBDdXJyZW50bHksIGV4cHJlc3MgZG9lc24ndCBzaHV0IGRvd24gaW1tZWRpYXRlbHkgYWZ0ZXIgcmVjZWl2aW5nIFNJR0lOVC9TSUdURVJNIGlmIGl0IGhhcyBjbGllbnQgY29ubmVjdGlvbnMgdGhhdCBoYXZlbid0IHRpbWVkIG91dC4gKFRoaXMgaXMgYSBrbm93biBpc3N1ZSB3aXRoIG5vZGUgLSBodHRwczovL2dpdGh1Yi5jb20vbm9kZWpzL25vZGUvaXNzdWVzLzI2NDIpXG4gICAgVGhpcyBmdW5jdGlvbiwgYWxvbmcgd2l0aCBgZGVzdHJveUFsaXZlQ29ubmVjdGlvbnMoKWAsIGludGVuZCB0byBmaXggdGhpcyBiZWhhdmlvciBzdWNoIHRoYXQgcGFyc2Ugc2VydmVyIHdpbGwgY2xvc2UgYWxsIG9wZW4gY29ubmVjdGlvbnMgYW5kIGluaXRpYXRlIHRoZSBzaHV0ZG93biBwcm9jZXNzIGFzIHNvb24gYXMgaXQgcmVjZWl2ZXMgYSBTSUdJTlQvU0lHVEVSTSBzaWduYWwuICovXG4gIHNlcnZlci5vbignY29ubmVjdGlvbicsIHNvY2tldCA9PiB7XG4gICAgY29uc3Qgc29ja2V0SWQgPSBzb2NrZXQucmVtb3RlQWRkcmVzcyArICc6JyArIHNvY2tldC5yZW1vdGVQb3J0O1xuICAgIHNvY2tldHNbc29ja2V0SWRdID0gc29ja2V0O1xuICAgIHNvY2tldC5vbignY2xvc2UnLCAoKSA9PiB7XG4gICAgICBkZWxldGUgc29ja2V0c1tzb2NrZXRJZF07XG4gICAgfSk7XG4gIH0pO1xuXG4gIGNvbnN0IGRlc3Ryb3lBbGl2ZUNvbm5lY3Rpb25zID0gZnVuY3Rpb24gKCkge1xuICAgIGZvciAoY29uc3Qgc29ja2V0SWQgaW4gc29ja2V0cykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgc29ja2V0c1tzb2NrZXRJZF0uZGVzdHJveSgpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvKiAqL1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBjb25zdCBoYW5kbGVTaHV0ZG93biA9IGZ1bmN0aW9uICgpIHtcbiAgICBwcm9jZXNzLnN0ZG91dC53cml0ZSgnVGVybWluYXRpb24gc2lnbmFsIHJlY2VpdmVkLiBTaHV0dGluZyBkb3duLicpO1xuICAgIGRlc3Ryb3lBbGl2ZUNvbm5lY3Rpb25zKCk7XG4gICAgc2VydmVyLmNsb3NlKCk7XG4gICAgcGFyc2VTZXJ2ZXIuaGFuZGxlU2h1dGRvd24oKTtcbiAgfTtcbiAgcHJvY2Vzcy5vbignU0lHVEVSTScsIGhhbmRsZVNodXRkb3duKTtcbiAgcHJvY2Vzcy5vbignU0lHSU5UJywgaGFuZGxlU2h1dGRvd24pO1xufVxuXG5leHBvcnQgZGVmYXVsdCBQYXJzZVNlcnZlcjtcbiJdfQ==
494
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJiYXRjaCIsInJlcXVpcmUiLCJib2R5UGFyc2VyIiwiZXhwcmVzcyIsIm1pZGRsZXdhcmVzIiwiUGFyc2UiLCJwYXJzZSIsInBhdGgiLCJmcyIsImFkZFBhcnNlQ2xvdWQiLCJQYXJzZVNlcnZlciIsImNvbnN0cnVjdG9yIiwib3B0aW9ucyIsIkRlcHJlY2F0b3IiLCJzY2FuUGFyc2VTZXJ2ZXJPcHRpb25zIiwiaW5qZWN0RGVmYXVsdHMiLCJhcHBJZCIsInJlcXVpcmVkUGFyYW1ldGVyIiwibWFzdGVyS2V5IiwiamF2YXNjcmlwdEtleSIsInNlcnZlclVSTCIsImluaXRpYWxpemUiLCJhbGxDb250cm9sbGVycyIsImNvbnRyb2xsZXJzIiwiZ2V0Q29udHJvbGxlcnMiLCJzdGF0ZSIsImNvbmZpZyIsIkNvbmZpZyIsInB1dCIsIk9iamVjdCIsImFzc2lnbiIsImxvZ2dpbmciLCJzZXRMb2dnZXIiLCJsb2dnZXJDb250cm9sbGVyIiwic3RhcnQiLCJkYXRhYmFzZUNvbnRyb2xsZXIiLCJob29rc0NvbnRyb2xsZXIiLCJjbG91ZCIsInNlY3VyaXR5Iiwic2NoZW1hIiwiY2FjaGVBZGFwdGVyIiwibGl2ZVF1ZXJ5Q29udHJvbGxlciIsInBlcmZvcm1Jbml0aWFsaXphdGlvbiIsImUiLCJjb2RlIiwiRXJyb3IiLCJEVVBMSUNBVEVfVkFMVUUiLCJsb2FkIiwic3RhcnR1cFByb21pc2VzIiwicHVzaCIsIkRlZmluZWRTY2hlbWFzIiwiZXhlY3V0ZSIsImNvbm5lY3QiLCJQcm9taXNlIiwiYWxsIiwicmVzb2x2ZSIsImpzb24iLCJwcm9jZXNzIiwiZW52IiwibnBtX3BhY2thZ2VfanNvbiIsIm5wbV9wYWNrYWdlX3R5cGUiLCJ0eXBlIiwiY3dkIiwiZGVmYXVsdCIsInNldFRpbWVvdXQiLCJlbmFibGVDaGVjayIsImVuYWJsZUNoZWNrTG9nIiwiQ2hlY2tSdW5uZXIiLCJydW4iLCJlcnJvciIsImNvbnNvbGUiLCJhcHAiLCJfYXBwIiwiaGFuZGxlU2h1dGRvd24iLCJwcm9taXNlcyIsImFkYXB0ZXIiLCJkYXRhYmFzZUFkYXB0ZXIiLCJmaWxlQWRhcHRlciIsImZpbGVzQ29udHJvbGxlciIsImNhY2hlQ29udHJvbGxlciIsImxlbmd0aCIsInRoZW4iLCJzZXJ2ZXJDbG9zZUNvbXBsZXRlIiwibWF4VXBsb2FkU2l6ZSIsImRpcmVjdEFjY2VzcyIsInBhZ2VzIiwicmF0ZUxpbWl0IiwiYXBpIiwidXNlIiwiYWxsb3dDcm9zc0RvbWFpbiIsIkZpbGVzUm91dGVyIiwiZXhwcmVzc1JvdXRlciIsInJlcSIsInJlcyIsInN0YXR1cyIsInNldCIsInVybGVuY29kZWQiLCJleHRlbmRlZCIsImVuYWJsZVJvdXRlciIsIlBhZ2VzUm91dGVyIiwiUHVibGljQVBJUm91dGVyIiwibGltaXQiLCJhbGxvd01ldGhvZE92ZXJyaWRlIiwiaGFuZGxlUGFyc2VIZWFkZXJzIiwicm91dGVzIiwiQXJyYXkiLCJpc0FycmF5Iiwicm91dGUiLCJhZGRSYXRlTGltaXQiLCJoYW5kbGVQYXJzZVNlc3Npb24iLCJhcHBSb3V0ZXIiLCJwcm9taXNlUm91dGVyIiwiaGFuZGxlUGFyc2VFcnJvcnMiLCJURVNUSU5HIiwib24iLCJlcnIiLCJzdGRlcnIiLCJ3cml0ZSIsInBvcnQiLCJleGl0IiwidmVyaWZ5U2VydmVyVXJsIiwiUEFSU0VfU0VSVkVSX0VOQUJMRV9FWFBFUklNRU5UQUxfRElSRUNUX0FDQ0VTUyIsIkNvcmVNYW5hZ2VyIiwic2V0UkVTVENvbnRyb2xsZXIiLCJQYXJzZVNlcnZlclJFU1RDb250cm9sbGVyIiwicm91dGVycyIsIkNsYXNzZXNSb3V0ZXIiLCJVc2Vyc1JvdXRlciIsIlNlc3Npb25zUm91dGVyIiwiUm9sZXNSb3V0ZXIiLCJBbmFseXRpY3NSb3V0ZXIiLCJJbnN0YWxsYXRpb25zUm91dGVyIiwiRnVuY3Rpb25zUm91dGVyIiwiU2NoZW1hc1JvdXRlciIsIlB1c2hSb3V0ZXIiLCJMb2dzUm91dGVyIiwiSUFQVmFsaWRhdGlvblJvdXRlciIsIkZlYXR1cmVzUm91dGVyIiwiR2xvYmFsQ29uZmlnUm91dGVyIiwiR3JhcGhRTFJvdXRlciIsIlB1cmdlUm91dGVyIiwiSG9va3NSb3V0ZXIiLCJDbG91ZENvZGVSb3V0ZXIiLCJBdWRpZW5jZXNSb3V0ZXIiLCJBZ2dyZWdhdGVSb3V0ZXIiLCJTZWN1cml0eVJvdXRlciIsInJlZHVjZSIsIm1lbW8iLCJyb3V0ZXIiLCJjb25jYXQiLCJQcm9taXNlUm91dGVyIiwibW91bnRPbnRvIiwic3RhcnRBcHAiLCJtaWRkbGV3YXJlIiwibW91bnRQYXRoIiwibW91bnRHcmFwaFFMIiwibW91bnRQbGF5Z3JvdW5kIiwiZ3JhcGhRTEN1c3RvbVR5cGVEZWZzIiwidW5kZWZpbmVkIiwiZ3JhcGhRTFNjaGVtYSIsInJlYWRGaWxlU3luYyIsInBhcnNlR3JhcGhRTFNlcnZlciIsIlBhcnNlR3JhcGhRTFNlcnZlciIsImdyYXBoUUxQYXRoIiwicGxheWdyb3VuZFBhdGgiLCJhcHBseUdyYXBoUUwiLCJhcHBseVBsYXlncm91bmQiLCJzZXJ2ZXIiLCJsaXN0ZW4iLCJob3N0Iiwic3RhcnRMaXZlUXVlcnlTZXJ2ZXIiLCJsaXZlUXVlcnlTZXJ2ZXJPcHRpb25zIiwibGl2ZVF1ZXJ5U2VydmVyIiwiY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyIiwidHJ1c3RQcm94eSIsImNvbmZpZ3VyZUxpc3RlbmVycyIsImV4cHJlc3NBcHAiLCJwYXJzZVNlcnZlciIsImh0dHBTZXJ2ZXIiLCJjcmVhdGVTZXJ2ZXIiLCJQYXJzZUxpdmVRdWVyeVNlcnZlciIsImNhbGxiYWNrIiwicmVxdWVzdCIsInVybCIsInJlcGxhY2UiLCJjYXRjaCIsInJlc3BvbnNlIiwiZGF0YSIsIndhcm4iLCJQYXJzZUNsb3VkIiwiZGVmaW5lUHJvcGVydHkiLCJnZXQiLCJhcHBsaWNhdGlvbklkIiwibmV3VmFsIiwiY29uZmlndXJhYmxlIiwiQ2xvdWQiLCJnbG9iYWwiLCJrZXlzIiwiZGVmYXVsdHMiLCJmb3JFYWNoIiwia2V5IiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwicmVnZXgiLCJtYXRjaCIsInVzZXJTZW5zaXRpdmVGaWVsZHMiLCJmcm9tIiwiU2V0IiwicHJvdGVjdGVkRmllbGRzIiwiX1VzZXIiLCJjIiwiY3VyIiwiciIsInVucSIsIm1hc3RlcktleUlwcyIsInNvY2tldHMiLCJzb2NrZXQiLCJzb2NrZXRJZCIsInJlbW90ZUFkZHJlc3MiLCJyZW1vdGVQb3J0IiwiZGVzdHJveUFsaXZlQ29ubmVjdGlvbnMiLCJkZXN0cm95Iiwic3Rkb3V0IiwiY2xvc2UiXSwic291cmNlcyI6WyIuLi9zcmMvUGFyc2VTZXJ2ZXIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gUGFyc2VTZXJ2ZXIgLSBvcGVuLXNvdXJjZSBjb21wYXRpYmxlIEFQSSBTZXJ2ZXIgZm9yIFBhcnNlIGFwcHNcblxudmFyIGJhdGNoID0gcmVxdWlyZSgnLi9iYXRjaCcpLFxuICBib2R5UGFyc2VyID0gcmVxdWlyZSgnYm9keS1wYXJzZXInKSxcbiAgZXhwcmVzcyA9IHJlcXVpcmUoJ2V4cHJlc3MnKSxcbiAgbWlkZGxld2FyZXMgPSByZXF1aXJlKCcuL21pZGRsZXdhcmVzJyksXG4gIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlLFxuICB7IHBhcnNlIH0gPSByZXF1aXJlKCdncmFwaHFsJyksXG4gIHBhdGggPSByZXF1aXJlKCdwYXRoJyksXG4gIGZzID0gcmVxdWlyZSgnZnMnKTtcblxuaW1wb3J0IHsgUGFyc2VTZXJ2ZXJPcHRpb25zLCBMaXZlUXVlcnlTZXJ2ZXJPcHRpb25zIH0gZnJvbSAnLi9PcHRpb25zJztcbmltcG9ydCBkZWZhdWx0cyBmcm9tICcuL2RlZmF1bHRzJztcbmltcG9ydCAqIGFzIGxvZ2dpbmcgZnJvbSAnLi9sb2dnZXInO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuL0NvbmZpZyc7XG5pbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0IHJlcXVpcmVkUGFyYW1ldGVyIGZyb20gJy4vcmVxdWlyZWRQYXJhbWV0ZXInO1xuaW1wb3J0IHsgQW5hbHl0aWNzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0FuYWx5dGljc1JvdXRlcic7XG5pbXBvcnQgeyBDbGFzc2VzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0NsYXNzZXNSb3V0ZXInO1xuaW1wb3J0IHsgRmVhdHVyZXNSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvRmVhdHVyZXNSb3V0ZXInO1xuaW1wb3J0IHsgRmlsZXNSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvRmlsZXNSb3V0ZXInO1xuaW1wb3J0IHsgRnVuY3Rpb25zUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0Z1bmN0aW9uc1JvdXRlcic7XG5pbXBvcnQgeyBHbG9iYWxDb25maWdSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvR2xvYmFsQ29uZmlnUm91dGVyJztcbmltcG9ydCB7IEdyYXBoUUxSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvR3JhcGhRTFJvdXRlcic7XG5pbXBvcnQgeyBIb29rc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9Ib29rc1JvdXRlcic7XG5pbXBvcnQgeyBJQVBWYWxpZGF0aW9uUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0lBUFZhbGlkYXRpb25Sb3V0ZXInO1xuaW1wb3J0IHsgSW5zdGFsbGF0aW9uc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9JbnN0YWxsYXRpb25zUm91dGVyJztcbmltcG9ydCB7IExvZ3NSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvTG9nc1JvdXRlcic7XG5pbXBvcnQgeyBQYXJzZUxpdmVRdWVyeVNlcnZlciB9IGZyb20gJy4vTGl2ZVF1ZXJ5L1BhcnNlTGl2ZVF1ZXJ5U2VydmVyJztcbmltcG9ydCB7IFBhZ2VzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL1BhZ2VzUm91dGVyJztcbmltcG9ydCB7IFB1YmxpY0FQSVJvdXRlciB9IGZyb20gJy4vUm91dGVycy9QdWJsaWNBUElSb3V0ZXInO1xuaW1wb3J0IHsgUHVzaFJvdXRlciB9IGZyb20gJy4vUm91dGVycy9QdXNoUm91dGVyJztcbmltcG9ydCB7IENsb3VkQ29kZVJvdXRlciB9IGZyb20gJy4vUm91dGVycy9DbG91ZENvZGVSb3V0ZXInO1xuaW1wb3J0IHsgUm9sZXNSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvUm9sZXNSb3V0ZXInO1xuaW1wb3J0IHsgU2NoZW1hc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9TY2hlbWFzUm91dGVyJztcbmltcG9ydCB7IFNlc3Npb25zUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL1Nlc3Npb25zUm91dGVyJztcbmltcG9ydCB7IFVzZXJzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL1VzZXJzUm91dGVyJztcbmltcG9ydCB7IFB1cmdlUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL1B1cmdlUm91dGVyJztcbmltcG9ydCB7IEF1ZGllbmNlc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9BdWRpZW5jZXNSb3V0ZXInO1xuaW1wb3J0IHsgQWdncmVnYXRlUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0FnZ3JlZ2F0ZVJvdXRlcic7XG5pbXBvcnQgeyBQYXJzZVNlcnZlclJFU1RDb250cm9sbGVyIH0gZnJvbSAnLi9QYXJzZVNlcnZlclJFU1RDb250cm9sbGVyJztcbmltcG9ydCAqIGFzIGNvbnRyb2xsZXJzIGZyb20gJy4vQ29udHJvbGxlcnMnO1xuaW1wb3J0IHsgUGFyc2VHcmFwaFFMU2VydmVyIH0gZnJvbSAnLi9HcmFwaFFML1BhcnNlR3JhcGhRTFNlcnZlcic7XG5pbXBvcnQgeyBTZWN1cml0eVJvdXRlciB9IGZyb20gJy4vUm91dGVycy9TZWN1cml0eVJvdXRlcic7XG5pbXBvcnQgQ2hlY2tSdW5uZXIgZnJvbSAnLi9TZWN1cml0eS9DaGVja1J1bm5lcic7XG5pbXBvcnQgRGVwcmVjYXRvciBmcm9tICcuL0RlcHJlY2F0b3IvRGVwcmVjYXRvcic7XG5pbXBvcnQgeyBEZWZpbmVkU2NoZW1hcyB9IGZyb20gJy4vU2NoZW1hTWlncmF0aW9ucy9EZWZpbmVkU2NoZW1hcyc7XG5cbi8vIE11dGF0ZSB0aGUgUGFyc2Ugb2JqZWN0IHRvIGFkZCB0aGUgQ2xvdWQgQ29kZSBoYW5kbGVyc1xuYWRkUGFyc2VDbG91ZCgpO1xuXG4vLyBQYXJzZVNlcnZlciB3b3JrcyBsaWtlIGEgY29uc3RydWN0b3Igb2YgYW4gZXhwcmVzcyBhcHAuXG4vLyBodHRwczovL3BhcnNlcGxhdGZvcm0ub3JnL3BhcnNlLXNlcnZlci9hcGkvbWFzdGVyL1BhcnNlU2VydmVyT3B0aW9ucy5odG1sXG5jbGFzcyBQYXJzZVNlcnZlciB7XG4gIC8qKlxuICAgKiBAY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtQYXJzZVNlcnZlck9wdGlvbnN9IG9wdGlvbnMgdGhlIHBhcnNlIHNlcnZlciBpbml0aWFsaXphdGlvbiBvcHRpb25zXG4gICAqL1xuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMpIHtcbiAgICAvLyBTY2FuIGZvciBkZXByZWNhdGVkIFBhcnNlIFNlcnZlciBvcHRpb25zXG4gICAgRGVwcmVjYXRvci5zY2FuUGFyc2VTZXJ2ZXJPcHRpb25zKG9wdGlvbnMpO1xuICAgIC8vIFNldCBvcHRpb24gZGVmYXVsdHNcbiAgICBpbmplY3REZWZhdWx0cyhvcHRpb25zKTtcbiAgICBjb25zdCB7XG4gICAgICBhcHBJZCA9IHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGFuIGFwcElkIScpLFxuICAgICAgbWFzdGVyS2V5ID0gcmVxdWlyZWRQYXJhbWV0ZXIoJ1lvdSBtdXN0IHByb3ZpZGUgYSBtYXN0ZXJLZXkhJyksXG4gICAgICBqYXZhc2NyaXB0S2V5LFxuICAgICAgc2VydmVyVVJMID0gcmVxdWlyZWRQYXJhbWV0ZXIoJ1lvdSBtdXN0IHByb3ZpZGUgYSBzZXJ2ZXJVUkwhJyksXG4gICAgfSA9IG9wdGlvbnM7XG4gICAgLy8gSW5pdGlhbGl6ZSB0aGUgbm9kZSBjbGllbnQgU0RLIGF1dG9tYXRpY2FsbHlcbiAgICBQYXJzZS5pbml0aWFsaXplKGFwcElkLCBqYXZhc2NyaXB0S2V5IHx8ICd1bnVzZWQnLCBtYXN0ZXJLZXkpO1xuICAgIFBhcnNlLnNlcnZlclVSTCA9IHNlcnZlclVSTDtcblxuICAgIGNvbnN0IGFsbENvbnRyb2xsZXJzID0gY29udHJvbGxlcnMuZ2V0Q29udHJvbGxlcnMob3B0aW9ucyk7XG4gICAgb3B0aW9ucy5zdGF0ZSA9ICdpbml0aWFsaXplZCc7XG4gICAgdGhpcy5jb25maWcgPSBDb25maWcucHV0KE9iamVjdC5hc3NpZ24oe30sIG9wdGlvbnMsIGFsbENvbnRyb2xsZXJzKSk7XG4gICAgbG9nZ2luZy5zZXRMb2dnZXIoYWxsQ29udHJvbGxlcnMubG9nZ2VyQ29udHJvbGxlcik7XG4gIH1cblxuICAvKipcbiAgICogU3RhcnRzIFBhcnNlIFNlcnZlciBhcyBhbiBleHByZXNzIGFwcDsgdGhpcyBwcm9taXNlIHJlc29sdmVzIHdoZW4gUGFyc2UgU2VydmVyIGlzIHJlYWR5IHRvIGFjY2VwdCByZXF1ZXN0cy5cbiAgICovXG5cbiAgYXN5bmMgc3RhcnQoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGlmICh0aGlzLmNvbmZpZy5zdGF0ZSA9PT0gJ29rJykge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHRoaXMuY29uZmlnLnN0YXRlID0gJ3N0YXJ0aW5nJztcbiAgICAgIENvbmZpZy5wdXQodGhpcy5jb25maWcpO1xuICAgICAgY29uc3Qge1xuICAgICAgICBkYXRhYmFzZUNvbnRyb2xsZXIsXG4gICAgICAgIGhvb2tzQ29udHJvbGxlcixcbiAgICAgICAgY2xvdWQsXG4gICAgICAgIHNlY3VyaXR5LFxuICAgICAgICBzY2hlbWEsXG4gICAgICAgIGNhY2hlQWRhcHRlcixcbiAgICAgICAgbGl2ZVF1ZXJ5Q29udHJvbGxlcixcbiAgICAgIH0gPSB0aGlzLmNvbmZpZztcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGRhdGFiYXNlQ29udHJvbGxlci5wZXJmb3JtSW5pdGlhbGl6YXRpb24oKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKGUuY29kZSAhPT0gUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFKSB7XG4gICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYXdhaXQgaG9va3NDb250cm9sbGVyLmxvYWQoKTtcbiAgICAgIGNvbnN0IHN0YXJ0dXBQcm9taXNlcyA9IFtdO1xuICAgICAgaWYgKHNjaGVtYSkge1xuICAgICAgICBzdGFydHVwUHJvbWlzZXMucHVzaChuZXcgRGVmaW5lZFNjaGVtYXMoc2NoZW1hLCB0aGlzLmNvbmZpZykuZXhlY3V0ZSgpKTtcbiAgICAgIH1cbiAgICAgIGlmIChjYWNoZUFkYXB0ZXI/LmNvbm5lY3QgJiYgdHlwZW9mIGNhY2hlQWRhcHRlci5jb25uZWN0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHN0YXJ0dXBQcm9taXNlcy5wdXNoKGNhY2hlQWRhcHRlci5jb25uZWN0KCkpO1xuICAgICAgfVxuICAgICAgc3RhcnR1cFByb21pc2VzLnB1c2gobGl2ZVF1ZXJ5Q29udHJvbGxlci5jb25uZWN0KCkpO1xuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoc3RhcnR1cFByb21pc2VzKTtcbiAgICAgIGlmIChjbG91ZCkge1xuICAgICAgICBhZGRQYXJzZUNsb3VkKCk7XG4gICAgICAgIGlmICh0eXBlb2YgY2xvdWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBhd2FpdCBQcm9taXNlLnJlc29sdmUoY2xvdWQoUGFyc2UpKTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgY2xvdWQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgbGV0IGpzb247XG4gICAgICAgICAgaWYgKHByb2Nlc3MuZW52Lm5wbV9wYWNrYWdlX2pzb24pIHtcbiAgICAgICAgICAgIGpzb24gPSByZXF1aXJlKHByb2Nlc3MuZW52Lm5wbV9wYWNrYWdlX2pzb24pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocHJvY2Vzcy5lbnYubnBtX3BhY2thZ2VfdHlwZSA9PT0gJ21vZHVsZScgfHwganNvbj8udHlwZSA9PT0gJ21vZHVsZScpIHtcbiAgICAgICAgICAgIGF3YWl0IGltcG9ydChwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSwgY2xvdWQpKS5kZWZhdWx0O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXF1aXJlKHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBjbG91ZCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBcImFyZ3VtZW50ICdjbG91ZCcgbXVzdCBlaXRoZXIgYmUgYSBzdHJpbmcgb3IgYSBmdW5jdGlvblwiO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKHJlc29sdmUgPT4gc2V0VGltZW91dChyZXNvbHZlLCAxMCkpO1xuICAgICAgfVxuICAgICAgaWYgKHNlY3VyaXR5ICYmIHNlY3VyaXR5LmVuYWJsZUNoZWNrICYmIHNlY3VyaXR5LmVuYWJsZUNoZWNrTG9nKSB7XG4gICAgICAgIG5ldyBDaGVja1J1bm5lcihzZWN1cml0eSkucnVuKCk7XG4gICAgICB9XG4gICAgICB0aGlzLmNvbmZpZy5zdGF0ZSA9ICdvayc7XG4gICAgICBDb25maWcucHV0KHRoaXMuY29uZmlnKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgIHRoaXMuY29uZmlnLnN0YXRlID0gJ2Vycm9yJztcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIGdldCBhcHAoKSB7XG4gICAgaWYgKCF0aGlzLl9hcHApIHtcbiAgICAgIHRoaXMuX2FwcCA9IFBhcnNlU2VydmVyLmFwcCh0aGlzLmNvbmZpZyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9hcHA7XG4gIH1cblxuICBoYW5kbGVTaHV0ZG93bigpIHtcbiAgICBjb25zdCBwcm9taXNlcyA9IFtdO1xuICAgIGNvbnN0IHsgYWRhcHRlcjogZGF0YWJhc2VBZGFwdGVyIH0gPSB0aGlzLmNvbmZpZy5kYXRhYmFzZUNvbnRyb2xsZXI7XG4gICAgaWYgKGRhdGFiYXNlQWRhcHRlciAmJiB0eXBlb2YgZGF0YWJhc2VBZGFwdGVyLmhhbmRsZVNodXRkb3duID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwcm9taXNlcy5wdXNoKGRhdGFiYXNlQWRhcHRlci5oYW5kbGVTaHV0ZG93bigpKTtcbiAgICB9XG4gICAgY29uc3QgeyBhZGFwdGVyOiBmaWxlQWRhcHRlciB9ID0gdGhpcy5jb25maWcuZmlsZXNDb250cm9sbGVyO1xuICAgIGlmIChmaWxlQWRhcHRlciAmJiB0eXBlb2YgZmlsZUFkYXB0ZXIuaGFuZGxlU2h1dGRvd24gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHByb21pc2VzLnB1c2goZmlsZUFkYXB0ZXIuaGFuZGxlU2h1dGRvd24oKSk7XG4gICAgfVxuICAgIGNvbnN0IHsgYWRhcHRlcjogY2FjaGVBZGFwdGVyIH0gPSB0aGlzLmNvbmZpZy5jYWNoZUNvbnRyb2xsZXI7XG4gICAgaWYgKGNhY2hlQWRhcHRlciAmJiB0eXBlb2YgY2FjaGVBZGFwdGVyLmhhbmRsZVNodXRkb3duID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwcm9taXNlcy5wdXNoKGNhY2hlQWRhcHRlci5oYW5kbGVTaHV0ZG93bigpKTtcbiAgICB9XG4gICAgcmV0dXJuIChwcm9taXNlcy5sZW5ndGggPiAwID8gUHJvbWlzZS5hbGwocHJvbWlzZXMpIDogUHJvbWlzZS5yZXNvbHZlKCkpLnRoZW4oKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuY29uZmlnLnNlcnZlckNsb3NlQ29tcGxldGUpIHtcbiAgICAgICAgdGhpcy5jb25maWcuc2VydmVyQ2xvc2VDb21wbGV0ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdGF0aWNcbiAgICogQ3JlYXRlIGFuIGV4cHJlc3MgYXBwIGZvciB0aGUgcGFyc2Ugc2VydmVyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIGxldCB5b3Ugc3BlY2lmeSB0aGUgbWF4VXBsb2FkU2l6ZSB3aGVuIGNyZWF0aW5nIHRoZSBleHByZXNzIGFwcCAgKi9cbiAgc3RhdGljIGFwcChvcHRpb25zKSB7XG4gICAgY29uc3QgeyBtYXhVcGxvYWRTaXplID0gJzIwbWInLCBhcHBJZCwgZGlyZWN0QWNjZXNzLCBwYWdlcywgcmF0ZUxpbWl0ID0gW10gfSA9IG9wdGlvbnM7XG4gICAgLy8gVGhpcyBhcHAgc2VydmVzIHRoZSBQYXJzZSBBUEkgZGlyZWN0bHkuXG4gICAgLy8gSXQncyB0aGUgZXF1aXZhbGVudCBvZiBodHRwczovL2FwaS5wYXJzZS5jb20vMSBpbiB0aGUgaG9zdGVkIFBhcnNlIEFQSS5cbiAgICB2YXIgYXBpID0gZXhwcmVzcygpO1xuICAgIC8vYXBpLnVzZShcIi9hcHBzXCIsIGV4cHJlc3Muc3RhdGljKF9fZGlybmFtZSArIFwiL3B1YmxpY1wiKSk7XG4gICAgYXBpLnVzZShtaWRkbGV3YXJlcy5hbGxvd0Nyb3NzRG9tYWluKGFwcElkKSk7XG4gICAgLy8gRmlsZSBoYW5kbGluZyBuZWVkcyB0byBiZSBiZWZvcmUgZGVmYXVsdCBtaWRkbGV3YXJlcyBhcmUgYXBwbGllZFxuICAgIGFwaS51c2UoXG4gICAgICAnLycsXG4gICAgICBuZXcgRmlsZXNSb3V0ZXIoKS5leHByZXNzUm91dGVyKHtcbiAgICAgICAgbWF4VXBsb2FkU2l6ZTogbWF4VXBsb2FkU2l6ZSxcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIGFwaS51c2UoJy9oZWFsdGgnLCBmdW5jdGlvbiAocmVxLCByZXMpIHtcbiAgICAgIHJlcy5zdGF0dXMob3B0aW9ucy5zdGF0ZSA9PT0gJ29rJyA/IDIwMCA6IDUwMyk7XG4gICAgICBpZiAob3B0aW9ucy5zdGF0ZSA9PT0gJ3N0YXJ0aW5nJykge1xuICAgICAgICByZXMuc2V0KCdSZXRyeS1BZnRlcicsIDEpO1xuICAgICAgfVxuICAgICAgcmVzLmpzb24oe1xuICAgICAgICBzdGF0dXM6IG9wdGlvbnMuc3RhdGUsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGFwaS51c2UoXG4gICAgICAnLycsXG4gICAgICBib2R5UGFyc2VyLnVybGVuY29kZWQoeyBleHRlbmRlZDogZmFsc2UgfSksXG4gICAgICBwYWdlcy5lbmFibGVSb3V0ZXJcbiAgICAgICAgPyBuZXcgUGFnZXNSb3V0ZXIocGFnZXMpLmV4cHJlc3NSb3V0ZXIoKVxuICAgICAgICA6IG5ldyBQdWJsaWNBUElSb3V0ZXIoKS5leHByZXNzUm91dGVyKClcbiAgICApO1xuXG4gICAgYXBpLnVzZShib2R5UGFyc2VyLmpzb24oeyB0eXBlOiAnKi8qJywgbGltaXQ6IG1heFVwbG9hZFNpemUgfSkpO1xuICAgIGFwaS51c2UobWlkZGxld2FyZXMuYWxsb3dNZXRob2RPdmVycmlkZSk7XG4gICAgYXBpLnVzZShtaWRkbGV3YXJlcy5oYW5kbGVQYXJzZUhlYWRlcnMpO1xuICAgIGNvbnN0IHJvdXRlcyA9IEFycmF5LmlzQXJyYXkocmF0ZUxpbWl0KSA/IHJhdGVMaW1pdCA6IFtyYXRlTGltaXRdO1xuICAgIGZvciAoY29uc3Qgcm91dGUgb2Ygcm91dGVzKSB7XG4gICAgICBtaWRkbGV3YXJlcy5hZGRSYXRlTGltaXQocm91dGUsIG9wdGlvbnMpO1xuICAgIH1cbiAgICBhcGkudXNlKG1pZGRsZXdhcmVzLmhhbmRsZVBhcnNlU2Vzc2lvbik7XG5cbiAgICBjb25zdCBhcHBSb3V0ZXIgPSBQYXJzZVNlcnZlci5wcm9taXNlUm91dGVyKHsgYXBwSWQgfSk7XG4gICAgYXBpLnVzZShhcHBSb3V0ZXIuZXhwcmVzc1JvdXRlcigpKTtcblxuICAgIGFwaS51c2UobWlkZGxld2FyZXMuaGFuZGxlUGFyc2VFcnJvcnMpO1xuXG4gICAgLy8gcnVuIHRoZSBmb2xsb3dpbmcgd2hlbiBub3QgdGVzdGluZ1xuICAgIGlmICghcHJvY2Vzcy5lbnYuVEVTVElORykge1xuICAgICAgLy9UaGlzIGNhdXNlcyB0ZXN0cyB0byBzcGV3IHNvbWUgdXNlbGVzcyB3YXJuaW5ncywgc28gZGlzYWJsZSBpbiB0ZXN0XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgcHJvY2Vzcy5vbigndW5jYXVnaHRFeGNlcHRpb24nLCBlcnIgPT4ge1xuICAgICAgICBpZiAoZXJyLmNvZGUgPT09ICdFQUREUklOVVNFJykge1xuICAgICAgICAgIC8vIHVzZXItZnJpZW5kbHkgbWVzc2FnZSBmb3IgdGhpcyBjb21tb24gZXJyb3JcbiAgICAgICAgICBwcm9jZXNzLnN0ZGVyci53cml0ZShgVW5hYmxlIHRvIGxpc3RlbiBvbiBwb3J0ICR7ZXJyLnBvcnR9LiBUaGUgcG9ydCBpcyBhbHJlYWR5IGluIHVzZS5gKTtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIC8vIHZlcmlmeSB0aGUgc2VydmVyIHVybCBhZnRlciBhICdtb3VudCcgZXZlbnQgaXMgcmVjZWl2ZWRcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICBhcGkub24oJ21vdW50JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBQYXJzZVNlcnZlci52ZXJpZnlTZXJ2ZXJVcmwoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAocHJvY2Vzcy5lbnYuUEFSU0VfU0VSVkVSX0VOQUJMRV9FWFBFUklNRU5UQUxfRElSRUNUX0FDQ0VTUyA9PT0gJzEnIHx8IGRpcmVjdEFjY2Vzcykge1xuICAgICAgUGFyc2UuQ29yZU1hbmFnZXIuc2V0UkVTVENvbnRyb2xsZXIoUGFyc2VTZXJ2ZXJSRVNUQ29udHJvbGxlcihhcHBJZCwgYXBwUm91dGVyKSk7XG4gICAgfVxuICAgIHJldHVybiBhcGk7XG4gIH1cblxuICBzdGF0aWMgcHJvbWlzZVJvdXRlcih7IGFwcElkIH0pIHtcbiAgICBjb25zdCByb3V0ZXJzID0gW1xuICAgICAgbmV3IENsYXNzZXNSb3V0ZXIoKSxcbiAgICAgIG5ldyBVc2Vyc1JvdXRlcigpLFxuICAgICAgbmV3IFNlc3Npb25zUm91dGVyKCksXG4gICAgICBuZXcgUm9sZXNSb3V0ZXIoKSxcbiAgICAgIG5ldyBBbmFseXRpY3NSb3V0ZXIoKSxcbiAgICAgIG5ldyBJbnN0YWxsYXRpb25zUm91dGVyKCksXG4gICAgICBuZXcgRnVuY3Rpb25zUm91dGVyKCksXG4gICAgICBuZXcgU2NoZW1hc1JvdXRlcigpLFxuICAgICAgbmV3IFB1c2hSb3V0ZXIoKSxcbiAgICAgIG5ldyBMb2dzUm91dGVyKCksXG4gICAgICBuZXcgSUFQVmFsaWRhdGlvblJvdXRlcigpLFxuICAgICAgbmV3IEZlYXR1cmVzUm91dGVyKCksXG4gICAgICBuZXcgR2xvYmFsQ29uZmlnUm91dGVyKCksXG4gICAgICBuZXcgR3JhcGhRTFJvdXRlcigpLFxuICAgICAgbmV3IFB1cmdlUm91dGVyKCksXG4gICAgICBuZXcgSG9va3NSb3V0ZXIoKSxcbiAgICAgIG5ldyBDbG91ZENvZGVSb3V0ZXIoKSxcbiAgICAgIG5ldyBBdWRpZW5jZXNSb3V0ZXIoKSxcbiAgICAgIG5ldyBBZ2dyZWdhdGVSb3V0ZXIoKSxcbiAgICAgIG5ldyBTZWN1cml0eVJvdXRlcigpLFxuICAgIF07XG5cbiAgICBjb25zdCByb3V0ZXMgPSByb3V0ZXJzLnJlZHVjZSgobWVtbywgcm91dGVyKSA9PiB7XG4gICAgICByZXR1cm4gbWVtby5jb25jYXQocm91dGVyLnJvdXRlcyk7XG4gICAgfSwgW10pO1xuXG4gICAgY29uc3QgYXBwUm91dGVyID0gbmV3IFByb21pc2VSb3V0ZXIocm91dGVzLCBhcHBJZCk7XG5cbiAgICBiYXRjaC5tb3VudE9udG8oYXBwUm91dGVyKTtcbiAgICByZXR1cm4gYXBwUm91dGVyO1xuICB9XG5cbiAgLyoqXG4gICAqIHN0YXJ0cyB0aGUgcGFyc2Ugc2VydmVyJ3MgZXhwcmVzcyBhcHBcbiAgICogQHBhcmFtIHtQYXJzZVNlcnZlck9wdGlvbnN9IG9wdGlvbnMgdG8gdXNlIHRvIHN0YXJ0IHRoZSBzZXJ2ZXJcbiAgICogQHJldHVybnMge1BhcnNlU2VydmVyfSB0aGUgcGFyc2Ugc2VydmVyIGluc3RhbmNlXG4gICAqL1xuXG4gIGFzeW5jIHN0YXJ0QXBwKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucykge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLnN0YXJ0KCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS5lcnJvcignRXJyb3Igb24gUGFyc2VTZXJ2ZXIuc3RhcnRBcHA6ICcsIGUpO1xuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gICAgY29uc3QgYXBwID0gZXhwcmVzcygpO1xuICAgIGlmIChvcHRpb25zLm1pZGRsZXdhcmUpIHtcbiAgICAgIGxldCBtaWRkbGV3YXJlO1xuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLm1pZGRsZXdhcmUgPT0gJ3N0cmluZycpIHtcbiAgICAgICAgbWlkZGxld2FyZSA9IHJlcXVpcmUocGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIG9wdGlvbnMubWlkZGxld2FyZSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWlkZGxld2FyZSA9IG9wdGlvbnMubWlkZGxld2FyZTsgLy8gdXNlIGFzLWlzIGxldCBleHByZXNzIGZhaWxcbiAgICAgIH1cbiAgICAgIGFwcC51c2UobWlkZGxld2FyZSk7XG4gICAgfVxuICAgIGFwcC51c2Uob3B0aW9ucy5tb3VudFBhdGgsIHRoaXMuYXBwKTtcblxuICAgIGlmIChvcHRpb25zLm1vdW50R3JhcGhRTCA9PT0gdHJ1ZSB8fCBvcHRpb25zLm1vdW50UGxheWdyb3VuZCA9PT0gdHJ1ZSkge1xuICAgICAgbGV0IGdyYXBoUUxDdXN0b21UeXBlRGVmcyA9IHVuZGVmaW5lZDtcbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5ncmFwaFFMU2NoZW1hID09PSAnc3RyaW5nJykge1xuICAgICAgICBncmFwaFFMQ3VzdG9tVHlwZURlZnMgPSBwYXJzZShmcy5yZWFkRmlsZVN5bmMob3B0aW9ucy5ncmFwaFFMU2NoZW1hLCAndXRmOCcpKTtcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIHR5cGVvZiBvcHRpb25zLmdyYXBoUUxTY2hlbWEgPT09ICdvYmplY3QnIHx8XG4gICAgICAgIHR5cGVvZiBvcHRpb25zLmdyYXBoUUxTY2hlbWEgPT09ICdmdW5jdGlvbidcbiAgICAgICkge1xuICAgICAgICBncmFwaFFMQ3VzdG9tVHlwZURlZnMgPSBvcHRpb25zLmdyYXBoUUxTY2hlbWE7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBhcnNlR3JhcGhRTFNlcnZlciA9IG5ldyBQYXJzZUdyYXBoUUxTZXJ2ZXIodGhpcywge1xuICAgICAgICBncmFwaFFMUGF0aDogb3B0aW9ucy5ncmFwaFFMUGF0aCxcbiAgICAgICAgcGxheWdyb3VuZFBhdGg6IG9wdGlvbnMucGxheWdyb3VuZFBhdGgsXG4gICAgICAgIGdyYXBoUUxDdXN0b21UeXBlRGVmcyxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAob3B0aW9ucy5tb3VudEdyYXBoUUwpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2VydmVyLmFwcGx5R3JhcGhRTChhcHApO1xuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9ucy5tb3VudFBsYXlncm91bmQpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2VydmVyLmFwcGx5UGxheWdyb3VuZChhcHApO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBzZXJ2ZXIgPSBhd2FpdCBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgIGFwcC5saXN0ZW4ob3B0aW9ucy5wb3J0LCBvcHRpb25zLmhvc3QsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmVzb2x2ZSh0aGlzKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHRoaXMuc2VydmVyID0gc2VydmVyO1xuXG4gICAgaWYgKG9wdGlvbnMuc3RhcnRMaXZlUXVlcnlTZXJ2ZXIgfHwgb3B0aW9ucy5saXZlUXVlcnlTZXJ2ZXJPcHRpb25zKSB7XG4gICAgICB0aGlzLmxpdmVRdWVyeVNlcnZlciA9IGF3YWl0IFBhcnNlU2VydmVyLmNyZWF0ZUxpdmVRdWVyeVNlcnZlcihcbiAgICAgICAgc2VydmVyLFxuICAgICAgICBvcHRpb25zLmxpdmVRdWVyeVNlcnZlck9wdGlvbnMsXG4gICAgICAgIG9wdGlvbnNcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLnRydXN0UHJveHkpIHtcbiAgICAgIGFwcC5zZXQoJ3RydXN0IHByb3h5Jywgb3B0aW9ucy50cnVzdFByb3h5KTtcbiAgICB9XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBpZiAoIXByb2Nlc3MuZW52LlRFU1RJTkcpIHtcbiAgICAgIGNvbmZpZ3VyZUxpc3RlbmVycyh0aGlzKTtcbiAgICB9XG4gICAgdGhpcy5leHByZXNzQXBwID0gYXBwO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgUGFyc2VTZXJ2ZXIgYW5kIHN0YXJ0cyBpdC5cbiAgICogQHBhcmFtIHtQYXJzZVNlcnZlck9wdGlvbnN9IG9wdGlvbnMgdXNlZCB0byBzdGFydCB0aGUgc2VydmVyXG4gICAqIEByZXR1cm5zIHtQYXJzZVNlcnZlcn0gdGhlIHBhcnNlIHNlcnZlciBpbnN0YW5jZVxuICAgKi9cbiAgc3RhdGljIGFzeW5jIHN0YXJ0QXBwKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucykge1xuICAgIGNvbnN0IHBhcnNlU2VydmVyID0gbmV3IFBhcnNlU2VydmVyKG9wdGlvbnMpO1xuICAgIHJldHVybiBwYXJzZVNlcnZlci5zdGFydEFwcChvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIZWxwZXIgbWV0aG9kIHRvIGNyZWF0ZSBhIGxpdmVRdWVyeSBzZXJ2ZXJcbiAgICogQHN0YXRpY1xuICAgKiBAcGFyYW0ge1NlcnZlcn0gaHR0cFNlcnZlciBhbiBvcHRpb25hbCBodHRwIHNlcnZlciB0byBwYXNzXG4gICAqIEBwYXJhbSB7TGl2ZVF1ZXJ5U2VydmVyT3B0aW9uc30gY29uZmlnIG9wdGlvbnMgZm9yIHRoZSBsaXZlUXVlcnlTZXJ2ZXJcbiAgICogQHBhcmFtIHtQYXJzZVNlcnZlck9wdGlvbnN9IG9wdGlvbnMgb3B0aW9ucyBmb3IgdGhlIFBhcnNlU2VydmVyXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFBhcnNlTGl2ZVF1ZXJ5U2VydmVyPn0gdGhlIGxpdmUgcXVlcnkgc2VydmVyIGluc3RhbmNlXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyKFxuICAgIGh0dHBTZXJ2ZXIsXG4gICAgY29uZmlnOiBMaXZlUXVlcnlTZXJ2ZXJPcHRpb25zLFxuICAgIG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9uc1xuICApIHtcbiAgICBpZiAoIWh0dHBTZXJ2ZXIgfHwgKGNvbmZpZyAmJiBjb25maWcucG9ydCkpIHtcbiAgICAgIHZhciBhcHAgPSBleHByZXNzKCk7XG4gICAgICBodHRwU2VydmVyID0gcmVxdWlyZSgnaHR0cCcpLmNyZWF0ZVNlcnZlcihhcHApO1xuICAgICAgaHR0cFNlcnZlci5saXN0ZW4oY29uZmlnLnBvcnQpO1xuICAgIH1cbiAgICBjb25zdCBzZXJ2ZXIgPSBuZXcgUGFyc2VMaXZlUXVlcnlTZXJ2ZXIoaHR0cFNlcnZlciwgY29uZmlnLCBvcHRpb25zKTtcbiAgICBhd2FpdCBzZXJ2ZXIuY29ubmVjdCgpO1xuICAgIHJldHVybiBzZXJ2ZXI7XG4gIH1cblxuICBzdGF0aWMgdmVyaWZ5U2VydmVyVXJsKGNhbGxiYWNrKSB7XG4gICAgLy8gcGVyZm9ybSBhIGhlYWx0aCBjaGVjayBvbiB0aGUgc2VydmVyVVJMIHZhbHVlXG4gICAgaWYgKFBhcnNlLnNlcnZlclVSTCkge1xuICAgICAgY29uc3QgcmVxdWVzdCA9IHJlcXVpcmUoJy4vcmVxdWVzdCcpO1xuICAgICAgcmVxdWVzdCh7IHVybDogUGFyc2Uuc2VydmVyVVJMLnJlcGxhY2UoL1xcLyQvLCAnJykgKyAnL2hlYWx0aCcgfSlcbiAgICAgICAgLmNhdGNoKHJlc3BvbnNlID0+IHJlc3BvbnNlKVxuICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgY29uc3QganNvbiA9IHJlc3BvbnNlLmRhdGEgfHwgbnVsbDtcbiAgICAgICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzICE9PSAyMDAgfHwgIWpzb24gfHwgKGpzb24gJiYganNvbi5zdGF0dXMgIT09ICdvaycpKSB7XG4gICAgICAgICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAgIGBcXG5XQVJOSU5HLCBVbmFibGUgdG8gY29ubmVjdCB0byAnJHtQYXJzZS5zZXJ2ZXJVUkx9Jy5gICtcbiAgICAgICAgICAgICAgICBgIENsb3VkIGNvZGUgYW5kIHB1c2ggbm90aWZpY2F0aW9ucyBtYXkgYmUgdW5hdmFpbGFibGUhXFxuYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIC8qIGVzbGludC1lbmFibGUgbm8tY29uc29sZSAqL1xuICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrKGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrKHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGFkZFBhcnNlQ2xvdWQoKSB7XG4gIGNvbnN0IFBhcnNlQ2xvdWQgPSByZXF1aXJlKCcuL2Nsb3VkLWNvZGUvUGFyc2UuQ2xvdWQnKTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFBhcnNlLCAnU2VydmVyJywge1xuICAgIGdldCgpIHtcbiAgICAgIHJldHVybiBDb25maWcuZ2V0KFBhcnNlLmFwcGxpY2F0aW9uSWQpO1xuICAgIH0sXG4gICAgc2V0KG5ld1ZhbCkge1xuICAgICAgbmV3VmFsLmFwcElkID0gUGFyc2UuYXBwbGljYXRpb25JZDtcbiAgICAgIENvbmZpZy5wdXQobmV3VmFsKTtcbiAgICB9LFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgfSk7XG4gIE9iamVjdC5hc3NpZ24oUGFyc2UuQ2xvdWQsIFBhcnNlQ2xvdWQpO1xuICBnbG9iYWwuUGFyc2UgPSBQYXJzZTtcbn1cblxuZnVuY3Rpb24gaW5qZWN0RGVmYXVsdHMob3B0aW9uczogUGFyc2VTZXJ2ZXJPcHRpb25zKSB7XG4gIE9iamVjdC5rZXlzKGRlZmF1bHRzKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob3B0aW9ucywga2V5KSkge1xuICAgICAgb3B0aW9uc1trZXldID0gZGVmYXVsdHNba2V5XTtcbiAgICB9XG4gIH0pO1xuXG4gIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9wdGlvbnMsICdzZXJ2ZXJVUkwnKSkge1xuICAgIG9wdGlvbnMuc2VydmVyVVJMID0gYGh0dHA6Ly9sb2NhbGhvc3Q6JHtvcHRpb25zLnBvcnR9JHtvcHRpb25zLm1vdW50UGF0aH1gO1xuICB9XG5cbiAgLy8gUmVzZXJ2ZWQgQ2hhcmFjdGVyc1xuICBpZiAob3B0aW9ucy5hcHBJZCkge1xuICAgIGNvbnN0IHJlZ2V4ID0gL1shIyQlJygpKismLzo7PT9AW1xcXXt9Xix8PD5dL2c7XG4gICAgaWYgKG9wdGlvbnMuYXBwSWQubWF0Y2gocmVnZXgpKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIGBcXG5XQVJOSU5HLCBhcHBJZCB0aGF0IGNvbnRhaW5zIHNwZWNpYWwgY2hhcmFjdGVycyBjYW4gY2F1c2UgaXNzdWVzIHdoaWxlIHVzaW5nIHdpdGggdXJscy5cXG5gXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8vIEJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG4gIGlmIChvcHRpb25zLnVzZXJTZW5zaXRpdmVGaWVsZHMpIHtcbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG4gICAgIXByb2Nlc3MuZW52LlRFU1RJTkcgJiZcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgYFxcbkRFUFJFQ0FURUQ6IHVzZXJTZW5zaXRpdmVGaWVsZHMgaGFzIGJlZW4gcmVwbGFjZWQgYnkgcHJvdGVjdGVkRmllbGRzIGFsbG93aW5nIHRoZSBhYmlsaXR5IHRvIHByb3RlY3QgZmllbGRzIGluIGFsbCBjbGFzc2VzIHdpdGggQ0xQLiBcXG5gXG4gICAgICApO1xuICAgIC8qIGVzbGludC1lbmFibGUgbm8tY29uc29sZSAqL1xuXG4gICAgY29uc3QgdXNlclNlbnNpdGl2ZUZpZWxkcyA9IEFycmF5LmZyb20oXG4gICAgICBuZXcgU2V0KFsuLi4oZGVmYXVsdHMudXNlclNlbnNpdGl2ZUZpZWxkcyB8fCBbXSksIC4uLihvcHRpb25zLnVzZXJTZW5zaXRpdmVGaWVsZHMgfHwgW10pXSlcbiAgICApO1xuXG4gICAgLy8gSWYgdGhlIG9wdGlvbnMucHJvdGVjdGVkRmllbGRzIGlzIHVuc2V0LFxuICAgIC8vIGl0J2xsIGJlIGFzc2lnbmVkIHRoZSBkZWZhdWx0IGFib3ZlLlxuICAgIC8vIEhlcmUsIHByb3RlY3QgYWdhaW5zdCB0aGUgY2FzZSB3aGVyZSBwcm90ZWN0ZWRGaWVsZHNcbiAgICAvLyBpcyBzZXQsIGJ1dCBkb2Vzbid0IGhhdmUgX1VzZXIuXG4gICAgaWYgKCEoJ19Vc2VyJyBpbiBvcHRpb25zLnByb3RlY3RlZEZpZWxkcykpIHtcbiAgICAgIG9wdGlvbnMucHJvdGVjdGVkRmllbGRzID0gT2JqZWN0LmFzc2lnbih7IF9Vc2VyOiBbXSB9LCBvcHRpb25zLnByb3RlY3RlZEZpZWxkcyk7XG4gICAgfVxuXG4gICAgb3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHNbJ19Vc2VyJ11bJyonXSA9IEFycmF5LmZyb20oXG4gICAgICBuZXcgU2V0KFsuLi4ob3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHNbJ19Vc2VyJ11bJyonXSB8fCBbXSksIC4uLnVzZXJTZW5zaXRpdmVGaWVsZHNdKVxuICAgICk7XG4gIH1cblxuICAvLyBNZXJnZSBwcm90ZWN0ZWRGaWVsZHMgb3B0aW9ucyB3aXRoIGRlZmF1bHRzLlxuICBPYmplY3Qua2V5cyhkZWZhdWx0cy5wcm90ZWN0ZWRGaWVsZHMpLmZvckVhY2goYyA9PiB7XG4gICAgY29uc3QgY3VyID0gb3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHNbY107XG4gICAgaWYgKCFjdXIpIHtcbiAgICAgIG9wdGlvbnMucHJvdGVjdGVkRmllbGRzW2NdID0gZGVmYXVsdHMucHJvdGVjdGVkRmllbGRzW2NdO1xuICAgIH0gZWxzZSB7XG4gICAgICBPYmplY3Qua2V5cyhkZWZhdWx0cy5wcm90ZWN0ZWRGaWVsZHNbY10pLmZvckVhY2gociA9PiB7XG4gICAgICAgIGNvbnN0IHVucSA9IG5ldyBTZXQoW1xuICAgICAgICAgIC4uLihvcHRpb25zLnByb3RlY3RlZEZpZWxkc1tjXVtyXSB8fCBbXSksXG4gICAgICAgICAgLi4uZGVmYXVsdHMucHJvdGVjdGVkRmllbGRzW2NdW3JdLFxuICAgICAgICBdKTtcbiAgICAgICAgb3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHNbY11bcl0gPSBBcnJheS5mcm9tKHVucSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIG9wdGlvbnMubWFzdGVyS2V5SXBzID0gQXJyYXkuZnJvbShcbiAgICBuZXcgU2V0KG9wdGlvbnMubWFzdGVyS2V5SXBzLmNvbmNhdChkZWZhdWx0cy5tYXN0ZXJLZXlJcHMsIG9wdGlvbnMubWFzdGVyS2V5SXBzKSlcbiAgKTtcbn1cblxuLy8gVGhvc2UgY2FuJ3QgYmUgdGVzdGVkIGFzIGl0IHJlcXVpcmVzIGEgc3VicHJvY2Vzc1xuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmZ1bmN0aW9uIGNvbmZpZ3VyZUxpc3RlbmVycyhwYXJzZVNlcnZlcikge1xuICBjb25zdCBzZXJ2ZXIgPSBwYXJzZVNlcnZlci5zZXJ2ZXI7XG4gIGNvbnN0IHNvY2tldHMgPSB7fTtcbiAgLyogQ3VycmVudGx5LCBleHByZXNzIGRvZXNuJ3Qgc2h1dCBkb3duIGltbWVkaWF0ZWx5IGFmdGVyIHJlY2VpdmluZyBTSUdJTlQvU0lHVEVSTSBpZiBpdCBoYXMgY2xpZW50IGNvbm5lY3Rpb25zIHRoYXQgaGF2ZW4ndCB0aW1lZCBvdXQuIChUaGlzIGlzIGEga25vd24gaXNzdWUgd2l0aCBub2RlIC0gaHR0cHM6Ly9naXRodWIuY29tL25vZGVqcy9ub2RlL2lzc3Vlcy8yNjQyKVxuICAgIFRoaXMgZnVuY3Rpb24sIGFsb25nIHdpdGggYGRlc3Ryb3lBbGl2ZUNvbm5lY3Rpb25zKClgLCBpbnRlbmQgdG8gZml4IHRoaXMgYmVoYXZpb3Igc3VjaCB0aGF0IHBhcnNlIHNlcnZlciB3aWxsIGNsb3NlIGFsbCBvcGVuIGNvbm5lY3Rpb25zIGFuZCBpbml0aWF0ZSB0aGUgc2h1dGRvd24gcHJvY2VzcyBhcyBzb29uIGFzIGl0IHJlY2VpdmVzIGEgU0lHSU5UL1NJR1RFUk0gc2lnbmFsLiAqL1xuICBzZXJ2ZXIub24oJ2Nvbm5lY3Rpb24nLCBzb2NrZXQgPT4ge1xuICAgIGNvbnN0IHNvY2tldElkID0gc29ja2V0LnJlbW90ZUFkZHJlc3MgKyAnOicgKyBzb2NrZXQucmVtb3RlUG9ydDtcbiAgICBzb2NrZXRzW3NvY2tldElkXSA9IHNvY2tldDtcbiAgICBzb2NrZXQub24oJ2Nsb3NlJywgKCkgPT4ge1xuICAgICAgZGVsZXRlIHNvY2tldHNbc29ja2V0SWRdO1xuICAgIH0pO1xuICB9KTtcblxuICBjb25zdCBkZXN0cm95QWxpdmVDb25uZWN0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICBmb3IgKGNvbnN0IHNvY2tldElkIGluIHNvY2tldHMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHNvY2tldHNbc29ja2V0SWRdLmRlc3Ryb3koKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLyogKi9cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgY29uc3QgaGFuZGxlU2h1dGRvd24gPSBmdW5jdGlvbiAoKSB7XG4gICAgcHJvY2Vzcy5zdGRvdXQud3JpdGUoJ1Rlcm1pbmF0aW9uIHNpZ25hbCByZWNlaXZlZC4gU2h1dHRpbmcgZG93bi4nKTtcbiAgICBkZXN0cm95QWxpdmVDb25uZWN0aW9ucygpO1xuICAgIHNlcnZlci5jbG9zZSgpO1xuICAgIHBhcnNlU2VydmVyLmhhbmRsZVNodXRkb3duKCk7XG4gIH07XG4gIHByb2Nlc3Mub24oJ1NJR1RFUk0nLCBoYW5kbGVTaHV0ZG93bik7XG4gIHByb2Nlc3Mub24oJ1NJR0lOVCcsIGhhbmRsZVNodXRkb3duKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgUGFyc2VTZXJ2ZXI7XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQVdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFtRTtBQUFBO0FBQUE7QUE5Q25FOztBQUVBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLFNBQVMsQ0FBQztFQUM1QkMsVUFBVSxHQUFHRCxPQUFPLENBQUMsYUFBYSxDQUFDO0VBQ25DRSxPQUFPLEdBQUdGLE9BQU8sQ0FBQyxTQUFTLENBQUM7RUFDNUJHLFdBQVcsR0FBR0gsT0FBTyxDQUFDLGVBQWUsQ0FBQztFQUN0Q0ksS0FBSyxHQUFHSixPQUFPLENBQUMsWUFBWSxDQUFDLENBQUNJLEtBQUs7RUFDbkM7SUFBRUM7RUFBTSxDQUFDLEdBQUdMLE9BQU8sQ0FBQyxTQUFTLENBQUM7RUFDOUJNLElBQUksR0FBR04sT0FBTyxDQUFDLE1BQU0sQ0FBQztFQUN0Qk8sRUFBRSxHQUFHUCxPQUFPLENBQUMsSUFBSSxDQUFDO0FBdUNwQjtBQUNBUSxhQUFhLEVBQUU7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