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,57 +4,44 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = exports.PushController = void 0;
7
-
8
7
  var _node = require("parse/node");
9
-
10
8
  var _RestQuery = _interopRequireDefault(require("../RestQuery"));
11
-
12
9
  var _RestWrite = _interopRequireDefault(require("../RestWrite"));
13
-
14
10
  var _Auth = require("../Auth");
15
-
16
11
  var _StatusHandler = require("../StatusHandler");
17
-
18
12
  var _utils = require("../Push/utils");
19
-
20
13
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
-
22
14
  class PushController {
23
15
  sendPush(body = {}, where = {}, config, auth, onPushStatusSaved = () => {}, now = new Date()) {
24
16
  if (!config.hasPushSupport) {
25
17
  throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Missing push configuration');
26
- } // Replace the expiration_time and push_time with a valid Unix epoch milliseconds time
27
-
18
+ }
28
19
 
20
+ // Replace the expiration_time and push_time with a valid Unix epoch milliseconds time
29
21
  body.expiration_time = PushController.getExpirationTime(body);
30
22
  body.expiration_interval = PushController.getExpirationInterval(body);
31
-
32
23
  if (body.expiration_time && body.expiration_interval) {
33
24
  throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Both expiration_time and expiration_interval cannot be set');
34
- } // Immediate push
35
-
25
+ }
36
26
 
27
+ // Immediate push
37
28
  if (body.expiration_interval && !Object.prototype.hasOwnProperty.call(body, 'push_time')) {
38
29
  const ttlMs = body.expiration_interval * 1000;
39
30
  body.expiration_time = new Date(now.valueOf() + ttlMs).valueOf();
40
31
  }
41
-
42
32
  const pushTime = PushController.getPushTime(body);
43
-
44
33
  if (pushTime && pushTime.date !== 'undefined') {
45
34
  body['push_time'] = PushController.formatPushTime(pushTime);
46
- } // TODO: If the req can pass the checking, we return immediately instead of waiting
47
- // pushes to be sent. We probably change this behaviour in the future.
48
-
35
+ }
49
36
 
37
+ // TODO: If the req can pass the checking, we return immediately instead of waiting
38
+ // pushes to be sent. We probably change this behaviour in the future.
50
39
  let badgeUpdate = () => {
51
40
  return Promise.resolve();
52
41
  };
53
-
54
42
  if (body.data && body.data.badge) {
55
43
  const badge = body.data.badge;
56
44
  let restUpdate = {};
57
-
58
45
  if (typeof badge == 'string' && badge.toLowerCase() === 'increment') {
59
46
  restUpdate = {
60
47
  badge: {
@@ -75,11 +62,10 @@ class PushController {
75
62
  };
76
63
  } else {
77
64
  throw "Invalid value for badge, expected number or 'Increment' or {increment: number}";
78
- } // Force filtering on only valid device tokens
79
-
65
+ }
80
66
 
67
+ // Force filtering on only valid device tokens
81
68
  const updateWhere = (0, _utils.applyDeviceTokenExists)(where);
82
-
83
69
  badgeUpdate = () => {
84
70
  // Build a real RestQuery so we can use it in RestWrite
85
71
  const restQuery = new _RestQuery.default(config, (0, _Auth.master)(config), '_Installation', updateWhere);
@@ -90,7 +76,6 @@ class PushController {
90
76
  });
91
77
  };
92
78
  }
93
-
94
79
  const pushStatus = (0, _StatusHandler.pushStatusHandler)(config);
95
80
  return Promise.resolve().then(() => {
96
81
  return pushStatus.setInitial(body, where);
@@ -115,15 +100,13 @@ class PushController {
115
100
  objectId: audienceId
116
101
  }, updateAudience);
117
102
  write.execute();
118
- } // Don't wait for the audience update promise to resolve.
119
-
120
-
103
+ }
104
+ // Don't wait for the audience update promise to resolve.
121
105
  return Promise.resolve();
122
106
  }).then(() => {
123
107
  if (Object.prototype.hasOwnProperty.call(body, 'push_time') && config.hasPushScheduledSupport) {
124
108
  return Promise.resolve();
125
109
  }
126
-
127
110
  return config.pushControllerQueue.enqueue(body, where, config, auth, pushStatus);
128
111
  }).catch(err => {
129
112
  return pushStatus.fail(err).then(() => {
@@ -131,72 +114,57 @@ class PushController {
131
114
  });
132
115
  });
133
116
  }
117
+
134
118
  /**
135
119
  * Get expiration time from the request body.
136
120
  * @param {Object} request A request object
137
121
  * @returns {Number|undefined} The expiration time if it exists in the request
138
122
  */
139
-
140
-
141
123
  static getExpirationTime(body = {}) {
142
124
  var hasExpirationTime = Object.prototype.hasOwnProperty.call(body, 'expiration_time');
143
-
144
125
  if (!hasExpirationTime) {
145
126
  return;
146
127
  }
147
-
148
128
  var expirationTimeParam = body['expiration_time'];
149
129
  var expirationTime;
150
-
151
130
  if (typeof expirationTimeParam === 'number') {
152
131
  expirationTime = new Date(expirationTimeParam * 1000);
153
132
  } else if (typeof expirationTimeParam === 'string') {
154
133
  expirationTime = new Date(expirationTimeParam);
155
134
  } else {
156
135
  throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, body['expiration_time'] + ' is not valid time.');
157
- } // Check expirationTime is valid or not, if it is not valid, expirationTime is NaN
158
-
159
-
136
+ }
137
+ // Check expirationTime is valid or not, if it is not valid, expirationTime is NaN
160
138
  if (!isFinite(expirationTime)) {
161
139
  throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, body['expiration_time'] + ' is not valid time.');
162
140
  }
163
-
164
141
  return expirationTime.valueOf();
165
142
  }
166
-
167
143
  static getExpirationInterval(body = {}) {
168
144
  const hasExpirationInterval = Object.prototype.hasOwnProperty.call(body, 'expiration_interval');
169
-
170
145
  if (!hasExpirationInterval) {
171
146
  return;
172
147
  }
173
-
174
148
  var expirationIntervalParam = body['expiration_interval'];
175
-
176
149
  if (typeof expirationIntervalParam !== 'number' || expirationIntervalParam <= 0) {
177
150
  throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, `expiration_interval must be a number greater than 0`);
178
151
  }
179
-
180
152
  return expirationIntervalParam;
181
153
  }
154
+
182
155
  /**
183
156
  * Get push time from the request body.
184
157
  * @param {Object} request A request object
185
158
  * @returns {Number|undefined} The push time if it exists in the request
186
159
  */
187
-
188
-
189
160
  static getPushTime(body = {}) {
190
161
  var hasPushTime = Object.prototype.hasOwnProperty.call(body, 'push_time');
191
-
192
162
  if (!hasPushTime) {
193
163
  return;
194
164
  }
195
-
196
165
  var pushTimeParam = body['push_time'];
197
166
  var date;
198
167
  var isLocalTime = true;
199
-
200
168
  if (typeof pushTimeParam === 'number') {
201
169
  date = new Date(pushTimeParam * 1000);
202
170
  } else if (typeof pushTimeParam === 'string') {
@@ -204,38 +172,34 @@ class PushController {
204
172
  date = new Date(pushTimeParam);
205
173
  } else {
206
174
  throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, body['push_time'] + ' is not valid time.');
207
- } // Check pushTime is valid or not, if it is not valid, pushTime is NaN
208
-
209
-
175
+ }
176
+ // Check pushTime is valid or not, if it is not valid, pushTime is NaN
210
177
  if (!isFinite(date)) {
211
178
  throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, body['push_time'] + ' is not valid time.');
212
179
  }
213
-
214
180
  return {
215
181
  date,
216
182
  isLocalTime
217
183
  };
218
184
  }
185
+
219
186
  /**
220
187
  * Checks if a ISO8601 formatted date contains a timezone component
221
188
  * @param pushTimeParam {string}
222
189
  * @returns {boolean}
223
190
  */
224
-
225
-
226
191
  static pushTimeHasTimezoneComponent(pushTimeParam) {
227
192
  const offsetPattern = /(.+)([+-])\d\d:\d\d$/;
228
193
  return pushTimeParam.indexOf('Z') === pushTimeParam.length - 1 || offsetPattern.test(pushTimeParam) // 2007-04-05T12:30Z
229
194
  ; // 2007-04-05T12:30.000+02:00, 2007-04-05T12:30.000-02:00
230
195
  }
196
+
231
197
  /**
232
198
  * Converts a date to ISO format in UTC time and strips the timezone if `isLocalTime` is true
233
199
  * @param date {Date}
234
200
  * @param isLocalTime {boolean}
235
201
  * @returns {string}
236
202
  */
237
-
238
-
239
203
  static formatPushTime({
240
204
  date,
241
205
  isLocalTime
@@ -245,13 +209,10 @@ class PushController {
245
209
  const isoString = date.toISOString();
246
210
  return isoString.substring(0, isoString.indexOf('Z'));
247
211
  }
248
-
249
212
  return date.toISOString();
250
213
  }
251
-
252
214
  }
253
-
254
215
  exports.PushController = PushController;
255
216
  var _default = PushController;
256
217
  exports.default = _default;
257
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9QdXNoQ29udHJvbGxlci5qcyJdLCJuYW1lcyI6WyJQdXNoQ29udHJvbGxlciIsInNlbmRQdXNoIiwiYm9keSIsIndoZXJlIiwiY29uZmlnIiwiYXV0aCIsIm9uUHVzaFN0YXR1c1NhdmVkIiwibm93IiwiRGF0ZSIsImhhc1B1c2hTdXBwb3J0IiwiUGFyc2UiLCJFcnJvciIsIlBVU0hfTUlTQ09ORklHVVJFRCIsImV4cGlyYXRpb25fdGltZSIsImdldEV4cGlyYXRpb25UaW1lIiwiZXhwaXJhdGlvbl9pbnRlcnZhbCIsImdldEV4cGlyYXRpb25JbnRlcnZhbCIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInR0bE1zIiwidmFsdWVPZiIsInB1c2hUaW1lIiwiZ2V0UHVzaFRpbWUiLCJkYXRlIiwiZm9ybWF0UHVzaFRpbWUiLCJiYWRnZVVwZGF0ZSIsIlByb21pc2UiLCJyZXNvbHZlIiwiZGF0YSIsImJhZGdlIiwicmVzdFVwZGF0ZSIsInRvTG93ZXJDYXNlIiwiX19vcCIsImFtb3VudCIsIk51bWJlciIsInVwZGF0ZVdoZXJlIiwicmVzdFF1ZXJ5IiwiUmVzdFF1ZXJ5IiwiYnVpbGRSZXN0V2hlcmUiLCJ0aGVuIiwid3JpdGUiLCJSZXN0V3JpdGUiLCJyZXN0V2hlcmUiLCJydW5PcHRpb25zIiwibWFueSIsImV4ZWN1dGUiLCJwdXNoU3RhdHVzIiwic2V0SW5pdGlhbCIsIm9iamVjdElkIiwiYXVkaWVuY2VfaWQiLCJhdWRpZW5jZUlkIiwidXBkYXRlQXVkaWVuY2UiLCJsYXN0VXNlZCIsIl9fdHlwZSIsImlzbyIsInRvSVNPU3RyaW5nIiwidGltZXNVc2VkIiwiaGFzUHVzaFNjaGVkdWxlZFN1cHBvcnQiLCJwdXNoQ29udHJvbGxlclF1ZXVlIiwiZW5xdWV1ZSIsImNhdGNoIiwiZXJyIiwiZmFpbCIsImhhc0V4cGlyYXRpb25UaW1lIiwiZXhwaXJhdGlvblRpbWVQYXJhbSIsImV4cGlyYXRpb25UaW1lIiwiaXNGaW5pdGUiLCJoYXNFeHBpcmF0aW9uSW50ZXJ2YWwiLCJleHBpcmF0aW9uSW50ZXJ2YWxQYXJhbSIsImhhc1B1c2hUaW1lIiwicHVzaFRpbWVQYXJhbSIsImlzTG9jYWxUaW1lIiwicHVzaFRpbWVIYXNUaW1lem9uZUNvbXBvbmVudCIsIm9mZnNldFBhdHRlcm4iLCJpbmRleE9mIiwibGVuZ3RoIiwidGVzdCIsImlzb1N0cmluZyIsInN1YnN0cmluZyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRU8sTUFBTUEsY0FBTixDQUFxQjtBQUMxQkMsRUFBQUEsUUFBUSxDQUFDQyxJQUFJLEdBQUcsRUFBUixFQUFZQyxLQUFLLEdBQUcsRUFBcEIsRUFBd0JDLE1BQXhCLEVBQWdDQyxJQUFoQyxFQUFzQ0MsaUJBQWlCLEdBQUcsTUFBTSxDQUFFLENBQWxFLEVBQW9FQyxHQUFHLEdBQUcsSUFBSUMsSUFBSixFQUExRSxFQUFzRjtBQUM1RixRQUFJLENBQUNKLE1BQU0sQ0FBQ0ssY0FBWixFQUE0QjtBQUMxQixZQUFNLElBQUlDLFlBQU1DLEtBQVYsQ0FBZ0JELFlBQU1DLEtBQU4sQ0FBWUMsa0JBQTVCLEVBQWdELDRCQUFoRCxDQUFOO0FBQ0QsS0FIMkYsQ0FLNUY7OztBQUNBVixJQUFBQSxJQUFJLENBQUNXLGVBQUwsR0FBdUJiLGNBQWMsQ0FBQ2MsaUJBQWYsQ0FBaUNaLElBQWpDLENBQXZCO0FBQ0FBLElBQUFBLElBQUksQ0FBQ2EsbUJBQUwsR0FBMkJmLGNBQWMsQ0FBQ2dCLHFCQUFmLENBQXFDZCxJQUFyQyxDQUEzQjs7QUFDQSxRQUFJQSxJQUFJLENBQUNXLGVBQUwsSUFBd0JYLElBQUksQ0FBQ2EsbUJBQWpDLEVBQXNEO0FBQ3BELFlBQU0sSUFBSUwsWUFBTUMsS0FBVixDQUNKRCxZQUFNQyxLQUFOLENBQVlDLGtCQURSLEVBRUosNERBRkksQ0FBTjtBQUlELEtBYjJGLENBZTVGOzs7QUFDQSxRQUFJVixJ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QUFkLENBQW1CTixhQUFuQixDQUQ3RCxDQUMrRjtBQUQvRixLQUZrRSxDQUkvRDtBQUNKO0FBRUQ7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDdUIsU0FBZDlDLGNBQWMsQ0FBQztBQUFFRCxJQUFBQSxJQUFGO0FBQVFnRCxJQUFBQTtBQUFSLEdBQUQsRUFBOEQ7QUFDakYsUUFBSUEsV0FBSixFQUFpQjtBQUNmO0FBQ0EsWUFBTU0sU0FBUyxHQUFHdEQsSUFBSSxDQUFDZ0MsV0FBTCxFQUFsQjtBQUNBLGFBQU9zQixTQUFTLENBQUNDLFNBQVYsQ0FBb0IsQ0FBcEIsRUFBdUJELFNBQVMsQ0FBQ0gsT0FBVixDQUFrQixHQUFsQixDQUF2QixDQUFQO0FBQ0Q7O0FBQ0QsV0FBT25ELElBQUksQ0FBQ2dDLFdBQUwsRUFBUDtBQUNEOztBQW5PeUI7OztlQXNPYnpELGMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBQYXJzZSB9IGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IFJlc3RRdWVyeSBmcm9tICcuLi9SZXN0UXVlcnknO1xuaW1wb3J0IFJlc3RXcml0ZSBmcm9tICcuLi9SZXN0V3JpdGUnO1xuaW1wb3J0IHsgbWFzdGVyIH0gZnJvbSAnLi4vQXV0aCc7XG5pbXBvcnQgeyBwdXNoU3RhdHVzSGFuZGxlciB9IGZyb20gJy4uL1N0YXR1c0hhbmRsZXInO1xuaW1wb3J0IHsgYXBwbHlEZXZpY2VUb2tlbkV4aXN0cyB9IGZyb20gJy4uL1B1c2gvdXRpbHMnO1xuXG5leHBvcnQgY2xhc3MgUHVzaENvbnRyb2xsZXIge1xuICBzZW5kUHVzaChib2R5ID0ge30sIHdoZXJlID0ge30sIGNvbmZpZywgYXV0aCwgb25QdXNoU3RhdHVzU2F2ZWQgPSAoKSA9PiB7fSwgbm93ID0gbmV3IERhdGUoKSkge1xuICAgIGlmICghY29uZmlnLmhhc1B1c2hTdXBwb3J0KSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELCAnTWlzc2luZyBwdXNoIGNvbmZpZ3VyYXRpb24nKTtcbiAgICB9XG5cbiAgICAvLyBSZXBsYWNlIHRoZSBleHBpcmF0aW9uX3RpbWUgYW5kIHB1c2hfdGltZSB3aXRoIGEgdmFsaWQgVW5peCBlcG9jaCBtaWxsaXNlY29uZHMgdGltZVxuICAgIGJvZHkuZXhwaXJhdGlvbl90aW1lID0gUHVzaENvbnRyb2xsZXIuZ2V0RXhwaXJhdGlvblRpbWUoYm9keSk7XG4gICAgYm9keS5leHBpcmF0aW9uX2ludGVydmFsID0gUHVzaENvbnRyb2xsZXIuZ2V0RXhwaXJhdGlvbkludGVydmFsKGJvZHkpO1xuICAgIGlmIChib2R5LmV4cGlyYXRpb25fdGltZSAmJiBib2R5LmV4cGlyYXRpb25faW50ZXJ2YWwpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICAnQm90aCBleHBpcmF0aW9uX3RpbWUgYW5kIGV4cGlyYXRpb25faW50ZXJ2YWwgY2Fubm90IGJlIHNldCdcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gSW1tZWRpYXRlIHB1c2hcbiAgICBpZiAoYm9keS5leHBpcmF0aW9uX2ludGVydmFsICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYm9keSwgJ3B1c2hfdGltZScpKSB7XG4gICAgICBjb25zdCB0dGxNcyA9IGJvZHkuZXhwaXJhdGlvbl9pbnRlcnZhbCAqIDEwMDA7XG4gICAgICBib2R5LmV4cGlyYXRpb25fdGltZSA9IG5ldyBEYXRlKG5vdy52YWx1ZU9mKCkgKyB0dGxNcykudmFsdWVPZigpO1xuICAgIH1cblxuICAgIGNvbnN0IHB1c2hUaW1lID0gUHVzaENvbnRyb2xsZXIuZ2V0UHVzaFRpbWUoYm9keSk7XG4gICAgaWYgKHB1c2hUaW1lICYmIHB1c2hUaW1lLmRhdGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBib2R5WydwdXNoX3RpbWUnXSA9IFB1c2hDb250cm9sbGVyLmZvcm1hdFB1c2hUaW1lKHB1c2hUaW1lKTtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBJZiB0aGUgcmVxIGNhbiBwYXNzIHRoZSBjaGVja2luZywgd2UgcmV0dXJuIGltbWVkaWF0ZWx5IGluc3RlYWQgb2Ygd2FpdGluZ1xuICAgIC8vIHB1c2hlcyB0byBiZSBzZW50LiBXZSBwcm9iYWJseSBjaGFuZ2UgdGhpcyBiZWhhdmlvdXIgaW4gdGhlIGZ1dHVyZS5cbiAgICBsZXQgYmFkZ2VVcGRhdGUgPSAoKSA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfTtcblxuICAgIGlmIChib2R5LmRhdGEgJiYgYm9keS5kYXRhLmJhZGdlKSB7XG4gICAgICBjb25zdCBiYWRnZSA9IGJvZHkuZGF0YS5iYWRnZTtcbiAgICAgIGxldCByZXN0VXBkYXRlID0ge307XG4gICAgICBpZiAodHlwZW9mIGJhZGdlID09ICdzdHJpbmcnICYmIGJhZGdlLnRvTG93ZXJDYXNlKCkgPT09ICdpbmNyZW1lbnQnKSB7XG4gICAgICAgIHJlc3RVcGRhdGUgPSB7IGJhZGdlOiB7IF9fb3A6ICdJbmNyZW1lbnQnLCBhbW91bnQ6IDEgfSB9O1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgdHlwZW9mIGJhZGdlID09ICdvYmplY3QnICYmXG4gICAgICAgIHR5cGVvZiBiYWRnZS5fX29wID09ICdzdHJpbmcnICYmXG4gICAgICAgIGJhZGdlLl9fb3AudG9Mb3dlckNhc2UoKSA9PSAnaW5jcmVtZW50JyAmJlxuICAgICAgICBOdW1iZXIoYmFkZ2UuYW1vdW50KVxuICAgICAgKSB7XG4gICAgICAgIHJlc3RVcGRhdGUgPSB7IGJhZGdlOiB7IF9fb3A6ICdJbmNyZW1lbnQnLCBhbW91bnQ6IGJhZGdlLmFtb3VudCB9IH07XG4gICAgICB9IGVsc2UgaWYgKE51bWJlcihiYWRnZSkpIHtcbiAgICAgICAgcmVzdFVwZGF0ZSA9IHsgYmFkZ2U6IGJhZGdlIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBcIkludmFsaWQgdmFsdWUgZm9yIGJhZGdlLCBleHBlY3RlZCBudW1iZXIgb3IgJ0luY3JlbWVudCcgb3Ige2luY3JlbWVudDogbnVtYmVyfVwiO1xuICAgICAgfVxuXG4gICAgICAvLyBGb3JjZSBmaWx0ZXJpbmcgb24gb25seSB2YWxpZCBkZXZpY2UgdG9rZW5zXG4gICAgICBjb25zdCB1cGRhdGVXaGVyZSA9IGFwcGx5RGV2aWNlVG9rZW5FeGlzdHMod2hlcmUpO1xuICAgICAgYmFkZ2VVcGRhdGUgPSAoKSA9PiB7XG4gICAgICAgIC8vIEJ1aWxkIGEgcmVhbCBSZXN0UXVlcnkgc28gd2UgY2FuIHVzZSBpdCBpbiBSZXN0V3JpdGVcbiAgICAgICAgY29uc3QgcmVzdFF1ZXJ5ID0gbmV3IFJlc3RRdWVyeShjb25maWcsIG1hc3Rlcihjb25maWcpLCAnX0luc3RhbGxhdGlvbicsIHVwZGF0ZVdoZXJlKTtcbiAgICAgICAgcmV0dXJuIHJlc3RRdWVyeS5idWlsZFJlc3RXaGVyZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHdyaXRlID0gbmV3IFJlc3RXcml0ZShcbiAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgIG1hc3Rlcihjb25maWcpLFxuICAgICAgICAgICAgJ19JbnN0YWxsYXRpb24nLFxuICAgICAgICAgICAgcmVzdFF1ZXJ5LnJlc3RXaGVyZSxcbiAgICAgICAgICAgIHJlc3RVcGRhdGVcbiAgICAgICAgICApO1xuICAgICAgICAgIHdyaXRlLnJ1bk9wdGlvbnMubWFueSA9IHRydWU7XG4gICAgICAgICAgcmV0dXJuIHdyaXRlLmV4ZWN1dGUoKTtcbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgIH1cbiAgICBjb25zdCBwdXNoU3RhdHVzID0gcHVzaFN0YXR1c0hhbmRsZXIoY29uZmlnKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHB1c2hTdGF0dXMuc2V0SW5pdGlhbChib2R5LCB3aGVyZSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBvblB1c2hTdGF0dXNTYXZlZChwdXNoU3RhdHVzLm9iamVjdElkKTtcbiAgICAgICAgcmV0dXJuIGJhZGdlVXBkYXRlKCk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAvLyBVcGRhdGUgYXVkaWVuY2UgbGFzdFVzZWQgYW5kIHRpbWVzVXNlZFxuICAgICAgICBpZiAoYm9keS5hdWRpZW5jZV9pZCkge1xuICAgICAgICAgIGNvbnN0IGF1ZGllbmNlSWQgPSBib2R5LmF1ZGllbmNlX2lkO1xuXG4gICAgICAgICAgdmFyIHVwZGF0ZUF1ZGllbmNlID0ge1xuICAgICAgICAgICAgbGFzdFVzZWQ6IHsgX190eXBlOiAnRGF0ZScsIGlzbzogbmV3IERhdGUoKS50b0lTT1N0cmluZygpIH0sXG4gICAgICAgICAgICB0aW1lc1VzZWQ6IHsgX19vcDogJ0luY3JlbWVudCcsIGFtb3VudDogMSB9LFxuICAgICAgICAgIH07XG4gICAgICAgICAgY29uc3Qgd3JpdGUgPSBuZXcgUmVzdFdyaXRlKFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgbWFzdGVyKGNvbmZpZyksXG4gICAgICAgICAgICAnX0F1ZGllbmNlJyxcbiAgICAgICAgICAgIHsgb2JqZWN0SWQ6IGF1ZGllbmNlSWQgfSxcbiAgICAgICAgICAgIHVwZGF0ZUF1ZGllbmNlXG4gICAgICAgICAgKTtcbiAgICAgICAgICB3cml0ZS5leGVjdXRlKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRG9uJ3Qgd2FpdCBmb3IgdGhlIGF1ZGllbmNlIHVwZGF0ZSBwcm9taXNlIHRvIHJlc29sdmUuXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYm9keSwgJ3B1c2hfdGltZScpICYmXG4gICAgICAgICAgY29uZmlnLmhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0XG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29uZmlnLnB1c2hDb250cm9sbGVyUXVldWUuZW5xdWV1ZShib2R5LCB3aGVyZSwgY29uZmlnLCBhdXRoLCBwdXNoU3RhdHVzKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgcmV0dXJuIHB1c2hTdGF0dXMuZmFpbChlcnIpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZXhwaXJhdGlvbiB0aW1lIGZyb20gdGhlIHJlcXVlc3QgYm9keS5cbiAgICogQHBhcmFtIHtPYmplY3R9IHJlcXVlc3QgQSByZXF1ZXN0IG9iamVjdFxuICAgKiBAcmV0dXJucyB7TnVtYmVyfHVuZGVmaW5lZH0gVGhlIGV4cGlyYXRpb24gdGltZSBpZiBpdCBleGlzdHMgaW4gdGhlIHJlcXVlc3RcbiAgICovXG4gIHN0YXRpYyBnZXRFeHBpcmF0aW9uVGltZShib2R5ID0ge30pIHtcbiAgICB2YXIgaGFzRXhwaXJhdGlvblRpbWUgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYm9keSwgJ2V4cGlyYXRpb25fdGltZScpO1xuICAgIGlmICghaGFzRXhwaXJhdGlvblRpbWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIGV4cGlyYXRpb25UaW1lUGFyYW0gPSBib2R5WydleHBpcmF0aW9uX3RpbWUnXTtcbiAgICB2YXIgZXhwaXJhdGlvblRpbWU7XG4gICAgaWYgKHR5cGVvZiBleHBpcmF0aW9uVGltZVBhcmFtID09PSAnbnVtYmVyJykge1xuICAgICAgZXhwaXJhdGlvblRpbWUgPSBuZXcgRGF0ZShleHBpcmF0aW9uVGltZVBhcmFtICogMTAwMCk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZXhwaXJhdGlvblRpbWVQYXJhbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGV4cGlyYXRpb25UaW1lID0gbmV3IERhdGUoZXhwaXJhdGlvblRpbWVQYXJhbSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICBib2R5WydleHBpcmF0aW9uX3RpbWUnXSArICcgaXMgbm90IHZhbGlkIHRpbWUuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgLy8gQ2hlY2sgZXhwaXJhdGlvblRpbWUgaXMgdmFsaWQgb3Igbm90LCBpZiBpdCBpcyBub3QgdmFsaWQsIGV4cGlyYXRpb25UaW1lIGlzIE5hTlxuICAgIGlmICghaXNGaW5pdGUoZXhwaXJhdGlvblRpbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgYm9keVsnZXhwaXJhdGlvbl90aW1lJ10gKyAnIGlzIG5vdCB2YWxpZCB0aW1lLidcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBleHBpcmF0aW9uVGltZS52YWx1ZU9mKCk7XG4gIH1cblxuICBzdGF0aWMgZ2V0RXhwaXJhdGlvbkludGVydmFsKGJvZHkgPSB7fSkge1xuICAgIGNvbnN0IGhhc0V4cGlyYXRpb25JbnRlcnZhbCA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChib2R5LCAnZXhwaXJhdGlvbl9pbnRlcnZhbCcpO1xuICAgIGlmICghaGFzRXhwaXJhdGlvbkludGVydmFsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGV4cGlyYXRpb25JbnRlcnZhbFBhcmFtID0gYm9keVsnZXhwaXJhdGlvbl9pbnRlcnZhbCddO1xuICAgIGlmICh0eXBlb2YgZXhwaXJhdGlvbkludGVydmFsUGFyYW0gIT09ICdudW1iZXInIHx8IGV4cGlyYXRpb25JbnRlcnZhbFBhcmFtIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICBgZXhwaXJhdGlvbl9pbnRlcnZhbCBtdXN0IGJlIGEgbnVtYmVyIGdyZWF0ZXIgdGhhbiAwYFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIGV4cGlyYXRpb25JbnRlcnZhbFBhcmFtO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBwdXNoIHRpbWUgZnJvbSB0aGUgcmVxdWVzdCBib2R5LlxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxdWVzdCBBIHJlcXVlc3Qgb2JqZWN0XG4gICAqIEByZXR1cm5zIHtOdW1iZXJ8dW5kZWZpbmVkfSBUaGUgcHVzaCB0aW1lIGlmIGl0IGV4aXN0cyBpbiB0aGUgcmVxdWVzdFxuICAgKi9cbiAgc3RhdGljIGdldFB1c2hUaW1lKGJvZHkgPSB7fSkge1xuICAgIHZhciBoYXNQdXNoVGltZSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChib2R5LCAncHVzaF90aW1lJyk7XG4gICAgaWYgKCFoYXNQdXNoVGltZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgcHVzaFRpbWVQYXJhbSA9IGJvZHlbJ3B1c2hfdGltZSddO1xuICAgIHZhciBkYXRlO1xuICAgIHZhciBpc0xvY2FsVGltZSA9IHRydWU7XG5cbiAgICBpZiAodHlwZW9mIHB1c2hUaW1lUGFyYW0gPT09ICdudW1iZXInKSB7XG4gICAgICBkYXRlID0gbmV3IERhdGUocHVzaFRpbWVQYXJhbSAqIDEwMDApO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHB1c2hUaW1lUGFyYW0gPT09ICdzdHJpbmcnKSB7XG4gICAgICBpc0xvY2FsVGltZSA9ICFQdXNoQ29udHJvbGxlci5wdXNoVGltZUhhc1RpbWV6b25lQ29tcG9uZW50KHB1c2hUaW1lUGFyYW0pO1xuICAgICAgZGF0ZSA9IG5ldyBEYXRlKHB1c2hUaW1lUGFyYW0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgYm9keVsncHVzaF90aW1lJ10gKyAnIGlzIG5vdCB2YWxpZCB0aW1lLidcbiAgICAgICk7XG4gICAgfVxuICAgIC8vIENoZWNrIHB1c2hUaW1lIGlzIHZhbGlkIG9yIG5vdCwgaWYgaXQgaXMgbm90IHZhbGlkLCBwdXNoVGltZSBpcyBOYU5cbiAgICBpZiAoIWlzRmluaXRlKGRhdGUpKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgYm9keVsncHVzaF90aW1lJ10gKyAnIGlzIG5vdCB2YWxpZCB0aW1lLidcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGUsXG4gICAgICBpc0xvY2FsVGltZSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiBhIElTTzg2MDEgZm9ybWF0dGVkIGRhdGUgY29udGFpbnMgYSB0aW1lem9uZSBjb21wb25lbnRcbiAgICogQHBhcmFtIHB1c2hUaW1lUGFyYW0ge3N0cmluZ31cbiAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAqL1xuICBzdGF0aWMgcHVzaFRpbWVIYXNUaW1lem9uZUNvbXBvbmVudChwdXNoVGltZVBhcmFtOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBjb25zdCBvZmZzZXRQYXR0ZXJuID0gLyguKykoWystXSlcXGRcXGQ6XFxkXFxkJC87XG4gICAgcmV0dXJuIChcbiAgICAgIHB1c2hUaW1lUGFyYW0uaW5kZXhPZignWicpID09PSBwdXNoVGltZVBhcmFtLmxlbmd0aCAtIDEgfHwgb2Zmc2V0UGF0dGVybi50ZXN0KHB1c2hUaW1lUGFyYW0pIC8vIDIwMDctMDQtMDVUMTI6MzBaXG4gICAgKTsgLy8gMjAwNy0wNC0wNVQxMjozMC4wMDArMDI6MDAsIDIwMDctMDQtMDVUMTI6MzAuMDAwLTAyOjAwXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYSBkYXRlIHRvIElTTyBmb3JtYXQgaW4gVVRDIHRpbWUgYW5kIHN0cmlwcyB0aGUgdGltZXpvbmUgaWYgYGlzTG9jYWxUaW1lYCBpcyB0cnVlXG4gICAqIEBwYXJhbSBkYXRlIHtEYXRlfVxuICAgKiBAcGFyYW0gaXNMb2NhbFRpbWUge2Jvb2xlYW59XG4gICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAqL1xuICBzdGF0aWMgZm9ybWF0UHVzaFRpbWUoeyBkYXRlLCBpc0xvY2FsVGltZSB9OiB7IGRhdGU6IERhdGUsIGlzTG9jYWxUaW1lOiBib29sZWFuIH0pIHtcbiAgICBpZiAoaXNMb2NhbFRpbWUpIHtcbiAgICAgIC8vIFN0cmlwICdaJ1xuICAgICAgY29uc3QgaXNvU3RyaW5nID0gZGF0ZS50b0lTT1N0cmluZygpO1xuICAgICAgcmV0dXJuIGlzb1N0cmluZy5zdWJzdHJpbmcoMCwgaXNvU3RyaW5nLmluZGV4T2YoJ1onKSk7XG4gICAgfVxuICAgIHJldHVybiBkYXRlLnRvSVNPU3RyaW5nKCk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUHVzaENvbnRyb2xsZXI7XG4iXX0=
218
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJQdXNoQ29udHJvbGxlciIsInNlbmRQdXNoIiwiYm9keSIsIndoZXJlIiwiY29uZmlnIiwiYXV0aCIsIm9uUHVzaFN0YXR1c1NhdmVkIiwibm93IiwiRGF0ZSIsImhhc1B1c2hTdXBwb3J0IiwiUGFyc2UiLCJFcnJvciIsIlBVU0hfTUlTQ09ORklHVVJFRCIsImV4cGlyYXRpb25fdGltZSIsImdldEV4cGlyYXRpb25UaW1lIiwiZXhwaXJhdGlvbl9pbnRlcnZhbCIsImdldEV4cGlyYXRpb25JbnRlcnZhbCIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInR0bE1zIiwidmFsdWVPZiIsInB1c2hUaW1lIiwiZ2V0UHVzaFRpbWUiLCJkYXRlIiwiZm9ybWF0UHVzaFRpbWUiLCJiYWRnZVVwZGF0ZSIsIlByb21pc2UiLCJyZXNvbHZlIiwiZGF0YSIsImJhZGdlIiwicmVzdFVwZGF0ZSIsInRvTG93ZXJDYXNlIiwiX19vcCIsImFtb3VudCIsIk51bWJlciIsInVwZGF0ZVdoZXJlIiwiYXBwbHlEZXZpY2VUb2tlbkV4aXN0cyIsInJlc3RRdWVyeSIsIlJlc3RRdWVyeSIsIm1hc3RlciIsImJ1aWxkUmVzdFdoZXJlIiwidGhlbiIsIndyaXRlIiwiUmVzdFdyaXRlIiwicmVzdFdoZXJlIiwicnVuT3B0aW9ucyIsIm1hbnkiLCJleGVjdXRlIiwicHVzaFN0YXR1cyIsInB1c2hTdGF0dXNIYW5kbGVyIiwic2V0SW5pdGlhbCIsIm9iamVjdElkIiwiYXVkaWVuY2VfaWQiLCJhdWRpZW5jZUlkIiwidXBkYXRlQXVkaWVuY2UiLCJsYXN0VXNlZCIsIl9fdHlwZSIsImlzbyIsInRvSVNPU3RyaW5nIiwidGltZXNVc2VkIiwiaGFzUHVzaFNjaGVkdWxlZFN1cHBvcnQiLCJwdXNoQ29udHJvbGxlclF1ZXVlIiwiZW5xdWV1ZSIsImNhdGNoIiwiZXJyIiwiZmFpbCIsImhhc0V4cGlyYXRpb25UaW1lIiwiZXhwaXJhdGlvblRpbWVQYXJhbSIsImV4cGlyYXRpb25UaW1lIiwiaXNGaW5pdGUiLCJoYXNFeHBpcmF0aW9uSW50ZXJ2YWwiLCJleHBpcmF0aW9uSW50ZXJ2YWxQYXJhbSIsImhhc1B1c2hUaW1lIiwicHVzaFRpbWVQYXJhbSIsImlzTG9jYWxUaW1lIiwicHVzaFRpbWVIYXNUaW1lem9uZUNvbXBvbmVudCIsIm9mZnNldFBhdHRlcm4iLCJpbmRleE9mIiwibGVuZ3RoIiwidGVzdCIsImlzb1N0cmluZyIsInN1YnN0cmluZyJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9QdXNoQ29udHJvbGxlci5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBQYXJzZSB9IGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IFJlc3RRdWVyeSBmcm9tICcuLi9SZXN0UXVlcnknO1xuaW1wb3J0IFJlc3RXcml0ZSBmcm9tICcuLi9SZXN0V3JpdGUnO1xuaW1wb3J0IHsgbWFzdGVyIH0gZnJvbSAnLi4vQXV0aCc7XG5pbXBvcnQgeyBwdXNoU3RhdHVzSGFuZGxlciB9IGZyb20gJy4uL1N0YXR1c0hhbmRsZXInO1xuaW1wb3J0IHsgYXBwbHlEZXZpY2VUb2tlbkV4aXN0cyB9IGZyb20gJy4uL1B1c2gvdXRpbHMnO1xuXG5leHBvcnQgY2xhc3MgUHVzaENvbnRyb2xsZXIge1xuICBzZW5kUHVzaChib2R5ID0ge30sIHdoZXJlID0ge30sIGNvbmZpZywgYXV0aCwgb25QdXNoU3RhdHVzU2F2ZWQgPSAoKSA9PiB7fSwgbm93ID0gbmV3IERhdGUoKSkge1xuICAgIGlmICghY29uZmlnLmhhc1B1c2hTdXBwb3J0KSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELCAnTWlzc2luZyBwdXNoIGNvbmZpZ3VyYXRpb24nKTtcbiAgICB9XG5cbiAgICAvLyBSZXBsYWNlIHRoZSBleHBpcmF0aW9uX3RpbWUgYW5kIHB1c2hfdGltZSB3aXRoIGEgdmFsaWQgVW5peCBlcG9jaCBtaWxsaXNlY29uZHMgdGltZVxuICAgIGJvZHkuZXhwaXJhdGlvbl90aW1lID0gUHVzaENvbnRyb2xsZXIuZ2V0RXhwaXJhdGlvblRpbWUoYm9keSk7XG4gICAgYm9keS5leHBpcmF0aW9uX2ludGVydmFsID0gUHVzaENvbnRyb2xsZXIuZ2V0RXhwaXJhdGlvbkludGVydmFsKGJvZHkpO1xuICAgIGlmIChib2R5LmV4cGlyYXRpb25fdGltZSAmJiBib2R5LmV4cGlyYXRpb25faW50ZXJ2YWwpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICAnQm90aCBleHBpcmF0aW9uX3RpbWUgYW5kIGV4cGlyYXRpb25faW50ZXJ2YWwgY2Fubm90IGJlIHNldCdcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gSW1tZWRpYXRlIHB1c2hcbiAgICBpZiAoYm9keS5leHBpcmF0aW9uX2ludGVydmFsICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYm9keSwgJ3B1c2hfdGltZScpKSB7XG4gICAgICBjb25zdCB0dGxNcyA9IGJvZHkuZXhwaXJhdGlvbl9pbnRlcnZhbCAqIDEwMDA7XG4gICAgICBib2R5LmV4cGlyYXRpb25fdGltZSA9IG5ldyBEYXRlKG5vdy52YWx1ZU9mKCkgKyB0dGxNcykudmFsdWVPZigpO1xuICAgIH1cblxuICAgIGNvbnN0IHB1c2hUaW1lID0gUHVzaENvbnRyb2xsZXIuZ2V0UHVzaFRpbWUoYm9keSk7XG4gICAgaWYgKHB1c2hUaW1lICYmIHB1c2hUaW1lLmRhdGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBib2R5WydwdXNoX3RpbWUnXSA9IFB1c2hDb250cm9sbGVyLmZvcm1hdFB1c2hUaW1lKHB1c2hUaW1lKTtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBJZiB0aGUgcmVxIGNhbiBwYXNzIHRoZSBjaGVja2luZywgd2UgcmV0dXJuIGltbWVkaWF0ZWx5IGluc3RlYWQgb2Ygd2FpdGluZ1xuICAgIC8vIHB1c2hlcyB0byBiZSBzZW50LiBXZSBwcm9iYWJseSBjaGFuZ2UgdGhpcyBiZWhhdmlvdXIgaW4gdGhlIGZ1dHVyZS5cbiAgICBsZXQgYmFkZ2VVcGRhdGUgPSAoKSA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfTtcblxuICAgIGlmIChib2R5LmRhdGEgJiYgYm9keS5kYXRhLmJhZGdlKSB7XG4gICAgICBjb25zdCBiYWRnZSA9IGJvZHkuZGF0YS5iYWRnZTtcbiAgICAgIGxldCByZXN0VXBkYXRlID0ge307XG4gICAgICBpZiAodHlwZW9mIGJhZGdlID09ICdzdHJpbmcnICYmIGJhZGdlLnRvTG93ZXJDYXNlKCkgPT09ICdpbmNyZW1lbnQnKSB7XG4gICAgICAgIHJlc3RVcGRhdGUgPSB7IGJhZGdlOiB7IF9fb3A6ICdJbmNyZW1lbnQnLCBhbW91bnQ6IDEgfSB9O1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgdHlwZW9mIGJhZGdlID09ICdvYmplY3QnICYmXG4gICAgICAgIHR5cGVvZiBiYWRnZS5fX29wID09ICdzdHJpbmcnICYmXG4gICAgICAgIGJhZGdlLl9fb3AudG9Mb3dlckNhc2UoKSA9PSAnaW5jcmVtZW50JyAmJlxuICAgICAgICBOdW1iZXIoYmFkZ2UuYW1vdW50KVxuICAgICAgKSB7XG4gICAgICAgIHJlc3RVcGRhdGUgPSB7IGJhZGdlOiB7IF9fb3A6ICdJbmNyZW1lbnQnLCBhbW91bnQ6IGJhZGdlLmFtb3VudCB9IH07XG4gICAgICB9IGVsc2UgaWYgKE51bWJlcihiYWRnZSkpIHtcbiAgICAgICAgcmVzdFVwZGF0ZSA9IHsgYmFkZ2U6IGJhZGdlIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBcIkludmFsaWQgdmFsdWUgZm9yIGJhZGdlLCBleHBlY3RlZCBudW1iZXIgb3IgJ0luY3JlbWVudCcgb3Ige2luY3JlbWVudDogbnVtYmVyfVwiO1xuICAgICAgfVxuXG4gICAgICAvLyBGb3JjZSBmaWx0ZXJpbmcgb24gb25seSB2YWxpZCBkZXZpY2UgdG9rZW5zXG4gICAgICBjb25zdCB1cGRhdGVXaGVyZSA9IGFwcGx5RGV2aWNlVG9rZW5FeGlzdHMod2hlcmUpO1xuICAgICAgYmFkZ2VVcGRhdGUgPSAoKSA9PiB7XG4gICAgICAgIC8vIEJ1aWxkIGEgcmVhbCBSZXN0UXVlcnkgc28gd2UgY2FuIHVzZSBpdCBpbiBSZXN0V3JpdGVcbiAgICAgICAgY29uc3QgcmVzdFF1ZXJ5ID0gbmV3IFJlc3RRdWVyeShjb25maWcsIG1hc3Rlcihjb25maWcpLCAnX0luc3RhbGxhdGlvbicsIHVwZGF0ZVdoZXJlKTtcbiAgICAgICAgcmV0dXJuIHJlc3RRdWVyeS5idWlsZFJlc3RXaGVyZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHdyaXRlID0gbmV3IFJlc3RXcml0ZShcbiAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgIG1hc3Rlcihjb25maWcpLFxuICAgICAgICAgICAgJ19JbnN0YWxsYXRpb24nLFxuICAgICAgICAgICAgcmVzdFF1ZXJ5LnJlc3RXaGVyZSxcbiAgICAgICAgICAgIHJlc3RVcGRhdGVcbiAgICAgICAgICApO1xuICAgICAgICAgIHdyaXRlLnJ1bk9wdGlvbnMubWFueSA9IHRydWU7XG4gICAgICAgICAgcmV0dXJuIHdyaXRlLmV4ZWN1dGUoKTtcbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgIH1cbiAgICBjb25zdCBwdXNoU3RhdHVzID0gcHVzaFN0YXR1c0hhbmRsZXIoY29uZmlnKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHB1c2hTdGF0dXMuc2V0SW5pdGlhbChib2R5LCB3aGVyZSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBvblB1c2hTdGF0dXNTYXZlZChwdXNoU3RhdHVzLm9iamVjdElkKTtcbiAgICAgICAgcmV0dXJuIGJhZGdlVXBkYXRlKCk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAvLyBVcGRhdGUgYXVkaWVuY2UgbGFzdFVzZWQgYW5kIHRpbWVzVXNlZFxuICAgICAgICBpZiAoYm9keS5hdWRpZW5jZV9pZCkge1xuICAgICAgICAgIGNvbnN0IGF1ZGllbmNlSWQgPSBib2R5LmF1ZGllbmNlX2lkO1xuXG4gICAgICAgICAgdmFyIHVwZGF0ZUF1ZGllbmNlID0ge1xuICAgICAgICAgICAgbGFzdFVzZWQ6IHsgX190eXBlOiAnRGF0ZScsIGlzbzogbmV3IERhdGUoKS50b0lTT1N0cmluZygpIH0sXG4gICAgICAgICAgICB0aW1lc1VzZWQ6IHsgX19vcDogJ0luY3JlbWVudCcsIGFtb3VudDogMSB9LFxuICAgICAgICAgIH07XG4gICAgICAgICAgY29uc3Qgd3JpdGUgPSBuZXcgUmVzdFdyaXRlKFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgbWFzdGVyKGNvbmZpZyksXG4gICAgICAgICAgICAnX0F1ZGllbmNlJyxcbiAgICAgICAgICAgIHsgb2JqZWN0SWQ6IGF1ZGllbmNlSWQgfSxcbiAgICAgICAgICAgIHVwZGF0ZUF1ZGllbmNlXG4gICAgICAgICAgKTtcbiAgICAgICAgICB3cml0ZS5leGVjdXRlKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRG9uJ3Qgd2FpdCBmb3IgdGhlIGF1ZGllbmNlIHVwZGF0ZSBwcm9taXNlIHRvIHJlc29sdmUuXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYm9keSwgJ3B1c2hfdGltZScpICYmXG4gICAgICAgICAgY29uZmlnLmhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0XG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29uZmlnLnB1c2hDb250cm9sbGVyUXVldWUuZW5xdWV1ZShib2R5LCB3aGVyZSwgY29uZmlnLCBhdXRoLCBwdXNoU3RhdHVzKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgcmV0dXJuIHB1c2hTdGF0dXMuZmFpbChlcnIpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZXhwaXJhdGlvbiB0aW1lIGZyb20gdGhlIHJlcXVlc3QgYm9keS5cbiAgICogQHBhcmFtIHtPYmplY3R9IHJlcXVlc3QgQSByZXF1ZXN0IG9iamVjdFxuICAgKiBAcmV0dXJucyB7TnVtYmVyfHVuZGVmaW5lZH0gVGhlIGV4cGlyYXRpb24gdGltZSBpZiBpdCBleGlzdHMgaW4gdGhlIHJlcXVlc3RcbiAgICovXG4gIHN0YXRpYyBnZXRFeHBpcmF0aW9uVGltZShib2R5ID0ge30pIHtcbiAgICB2YXIgaGFzRXhwaXJhdGlvblRpbWUgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYm9keSwgJ2V4cGlyYXRpb25fdGltZScpO1xuICAgIGlmICghaGFzRXhwaXJhdGlvblRpbWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIGV4cGlyYXRpb25UaW1lUGFyYW0gPSBib2R5WydleHBpcmF0aW9uX3RpbWUnXTtcbiAgICB2YXIgZXhwaXJhdGlvblRpbWU7XG4gICAgaWYgKHR5cGVvZiBleHBpcmF0aW9uVGltZVBhcmFtID09PSAnbnVtYmVyJykge1xuICAgICAgZXhwaXJhdGlvblRpbWUgPSBuZXcgRGF0ZShleHBpcmF0aW9uVGltZVBhcmFtICogMTAwMCk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZXhwaXJhdGlvblRpbWVQYXJhbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGV4cGlyYXRpb25UaW1lID0gbmV3IERhdGUoZXhwaXJhdGlvblRpbWVQYXJhbSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICBib2R5WydleHBpcmF0aW9uX3RpbWUnXSArICcgaXMgbm90IHZhbGlkIHRpbWUuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgLy8gQ2hlY2sgZXhwaXJhdGlvblRpbWUgaXMgdmFsaWQgb3Igbm90LCBpZiBpdCBpcyBub3QgdmFsaWQsIGV4cGlyYXRpb25UaW1lIGlzIE5hTlxuICAgIGlmICghaXNGaW5pdGUoZXhwaXJhdGlvblRpbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgYm9keVsnZXhwaXJhdGlvbl90aW1lJ10gKyAnIGlzIG5vdCB2YWxpZCB0aW1lLidcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBleHBpcmF0aW9uVGltZS52YWx1ZU9mKCk7XG4gIH1cblxuICBzdGF0aWMgZ2V0RXhwaXJhdGlvbkludGVydmFsKGJvZHkgPSB7fSkge1xuICAgIGNvbnN0IGhhc0V4cGlyYXRpb25JbnRlcnZhbCA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChib2R5LCAnZXhwaXJhdGlvbl9pbnRlcnZhbCcpO1xuICAgIGlmICghaGFzRXhwaXJhdGlvbkludGVydmFsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGV4cGlyYXRpb25JbnRlcnZhbFBhcmFtID0gYm9keVsnZXhwaXJhdGlvbl9pbnRlcnZhbCddO1xuICAgIGlmICh0eXBlb2YgZXhwaXJhdGlvbkludGVydmFsUGFyYW0gIT09ICdudW1iZXInIHx8IGV4cGlyYXRpb25JbnRlcnZhbFBhcmFtIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICBgZXhwaXJhdGlvbl9pbnRlcnZhbCBtdXN0IGJlIGEgbnVtYmVyIGdyZWF0ZXIgdGhhbiAwYFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIGV4cGlyYXRpb25JbnRlcnZhbFBhcmFtO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBwdXNoIHRpbWUgZnJvbSB0aGUgcmVxdWVzdCBib2R5LlxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxdWVzdCBBIHJlcXVlc3Qgb2JqZWN0XG4gICAqIEByZXR1cm5zIHtOdW1iZXJ8dW5kZWZpbmVkfSBUaGUgcHVzaCB0aW1lIGlmIGl0IGV4aXN0cyBpbiB0aGUgcmVxdWVzdFxuICAgKi9cbiAgc3RhdGljIGdldFB1c2hUaW1lKGJvZHkgPSB7fSkge1xuICAgIHZhciBoYXNQdXNoVGltZSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChib2R5LCAncHVzaF90aW1lJyk7XG4gICAgaWYgKCFoYXNQdXNoVGltZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgcHVzaFRpbWVQYXJhbSA9IGJvZHlbJ3B1c2hfdGltZSddO1xuICAgIHZhciBkYXRlO1xuICAgIHZhciBpc0xvY2FsVGltZSA9IHRydWU7XG5cbiAgICBpZiAodHlwZW9mIHB1c2hUaW1lUGFyYW0gPT09ICdudW1iZXInKSB7XG4gICAgICBkYXRlID0gbmV3IERhdGUocHVzaFRpbWVQYXJhbSAqIDEwMDApO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHB1c2hUaW1lUGFyYW0gPT09ICdzdHJpbmcnKSB7XG4gICAgICBpc0xvY2FsVGltZSA9ICFQdXNoQ29udHJvbGxlci5wdXNoVGltZUhhc1RpbWV6b25lQ29tcG9uZW50KHB1c2hUaW1lUGFyYW0pO1xuICAgICAgZGF0ZSA9IG5ldyBEYXRlKHB1c2hUaW1lUGFyYW0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgYm9keVsncHVzaF90aW1lJ10gKyAnIGlzIG5vdCB2YWxpZCB0aW1lLidcbiAgICAgICk7XG4gICAgfVxuICAgIC8vIENoZWNrIHB1c2hUaW1lIGlzIHZhbGlkIG9yIG5vdCwgaWYgaXQgaXMgbm90IHZhbGlkLCBwdXNoVGltZSBpcyBOYU5cbiAgICBpZiAoIWlzRmluaXRlKGRhdGUpKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgYm9keVsncHVzaF90aW1lJ10gKyAnIGlzIG5vdCB2YWxpZCB0aW1lLidcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGUsXG4gICAgICBpc0xvY2FsVGltZSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiBhIElTTzg2MDEgZm9ybWF0dGVkIGRhdGUgY29udGFpbnMgYSB0aW1lem9uZSBjb21wb25lbnRcbiAgICogQHBhcmFtIHB1c2hUaW1lUGFyYW0ge3N0cmluZ31cbiAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAqL1xuICBzdGF0aWMgcHVzaFRpbWVIYXNUaW1lem9uZUNvbXBvbmVudChwdXNoVGltZVBhcmFtOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBjb25zdCBvZmZzZXRQYXR0ZXJuID0gLyguKykoWystXSlcXGRcXGQ6XFxkXFxkJC87XG4gICAgcmV0dXJuIChcbiAgICAgIHB1c2hUaW1lUGFyYW0uaW5kZXhPZignWicpID09PSBwdXNoVGltZVBhcmFtLmxlbmd0aCAtIDEgfHwgb2Zmc2V0UGF0dGVybi50ZXN0KHB1c2hUaW1lUGFyYW0pIC8vIDIwMDctMDQtMDVUMTI6MzBaXG4gICAgKTsgLy8gMjAwNy0wNC0wNVQxMjozMC4wMDArMDI6MDAsIDIwMDctMDQtMDVUMTI6MzAuMDAwLTAyOjAwXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYSBkYXRlIHRvIElTTyBmb3JtYXQgaW4gVVRDIHRpbWUgYW5kIHN0cmlwcyB0aGUgdGltZXpvbmUgaWYgYGlzTG9jYWxUaW1lYCBpcyB0cnVlXG4gICAqIEBwYXJhbSBkYXRlIHtEYXRlfVxuICAgKiBAcGFyYW0gaXNMb2NhbFRpbWUge2Jvb2xlYW59XG4gICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAqL1xuICBzdGF0aWMgZm9ybWF0UHVzaFRpbWUoeyBkYXRlLCBpc0xvY2FsVGltZSB9OiB7IGRhdGU6IERhdGUsIGlzTG9jYWxUaW1lOiBib29sZWFuIH0pIHtcbiAgICBpZiAoaXNMb2NhbFRpbWUpIHtcbiAgICAgIC8vIFN0cmlwICdaJ1xuICAgICAgY29uc3QgaXNvU3RyaW5nID0gZGF0ZS50b0lTT1N0cmluZygpO1xuICAgICAgcmV0dXJuIGlzb1N0cmluZy5zdWJzdHJpbmcoMCwgaXNvU3RyaW5nLmluZGV4T2YoJ1onKSk7XG4gICAgfVxuICAgIHJldHVybiBkYXRlLnRvSVNPU3RyaW5nKCk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUHVzaENvbnRyb2xsZXI7XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUF1RDtBQUVoRCxNQUFNQSxjQUFjLENBQUM7RUFDMUJDLFFBQVEsQ0FBQ0MsSUFBSSxHQUFHLENBQUMsQ0FBQyxFQUFFQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEVBQUVDLE1BQU0sRUFBRUMsSUFBSSxFQUFFQyxpQkFBaUIsR0FBRyxNQUFNLENBQUMsQ0FBQyxFQUFFQyxHQUFHLEdBQUcsSUFBSUMsSUFBSSxFQUFFLEVBQUU7SUFDNUYsSUFBSSxDQUFDSixNQUFNLENBQUNLLGNBQWMsRUFBRTtNQUMxQixNQUFNLElBQUlDLFdBQUssQ0FBQ0MsS0FBSyxDQUFDRCxXQUFLLENBQUNDLEtBQUssQ0FBQ0Msa0JBQWtCLEVBQUUsNEJBQTRCLENBQUM7SUFDckY7O0lBRUE7SUFDQVYsSUFBSSxDQUFDVyxlQUFlLEdBQUdiLGNB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