velocious 1.0.644 → 1.0.646

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 (259) hide show
  1. package/README.md +11 -9
  2. package/build/authorization/ability.js +36 -13
  3. package/build/background-jobs/adapter.js +9 -0
  4. package/build/background-jobs/main.js +35 -10
  5. package/build/background-jobs/store.js +217 -38
  6. package/build/background-jobs/types.js +15 -0
  7. package/build/configuration-types.js +1 -1
  8. package/build/configuration.js +45 -9
  9. package/build/database/drivers/base-column.js +8 -0
  10. package/build/database/drivers/mssql/sql/update.js +1 -3
  11. package/build/database/drivers/mysql/sql/update.js +1 -3
  12. package/build/database/drivers/pgsql/column.js +22 -0
  13. package/build/database/drivers/pgsql/sql/update.js +1 -3
  14. package/build/database/drivers/sqlite/sql/alter-table.js +11 -1
  15. package/build/database/drivers/sqlite/sql/update.js +1 -3
  16. package/build/database/query/index.js +2 -2
  17. package/build/database/query/model-class-query.js +26 -10
  18. package/build/database/query/preloader/has-many.js +4 -1
  19. package/build/database/query/query-data.js +2 -1
  20. package/build/database/query/update-base.js +14 -0
  21. package/build/database/query/with-count.js +3 -1
  22. package/build/database/record/acts-as-list.js +37 -13
  23. package/build/database/record/attachments/store.js +336 -26
  24. package/build/database/record/auditing.js +6 -3
  25. package/build/database/record/index.js +197 -42
  26. package/build/database/record/instance-relationships/belongs-to.js +2 -1
  27. package/build/database/record/validators/uniqueness.js +8 -5
  28. package/build/environment-handlers/node/cli/commands/generate/frontend-models.js +24 -8
  29. package/build/frontend-model-controller.js +136 -53
  30. package/build/frontend-model-resource/base-resource.js +87 -37
  31. package/build/frontend-model-resource/velocious-attachment-resource.js +98 -31
  32. package/build/frontend-models/base.js +307 -59
  33. package/build/frontend-models/preloader.js +6 -3
  34. package/build/frontend-models/query.js +15 -6
  35. package/build/frontend-models/resource-definition.js +21 -2
  36. package/build/frontend-models/use-destroyed-event.js +1 -1
  37. package/build/frontend-models/use-model-class-event.js +2 -2
  38. package/build/frontend-models/use-updated-event.js +1 -1
  39. package/build/frontend-models/websocket-channel.js +256 -93
  40. package/build/frontend-models/websocket-publishers.js +218 -18
  41. package/build/http-server/client/websocket-session.js +13 -1
  42. package/build/http-server/websocket-channel.js +15 -2
  43. package/build/src/authorization/ability.d.ts +9 -3
  44. package/build/src/authorization/ability.d.ts.map +1 -1
  45. package/build/src/authorization/ability.js +33 -14
  46. package/build/src/background-jobs/adapter.d.ts +6 -0
  47. package/build/src/background-jobs/adapter.d.ts.map +1 -1
  48. package/build/src/background-jobs/adapter.js +9 -1
  49. package/build/src/background-jobs/main.d.ts +6 -0
  50. package/build/src/background-jobs/main.d.ts.map +1 -1
  51. package/build/src/background-jobs/main.js +34 -11
  52. package/build/src/background-jobs/store.d.ts +66 -12
  53. package/build/src/background-jobs/store.d.ts.map +1 -1
  54. package/build/src/background-jobs/store.js +191 -35
  55. package/build/src/background-jobs/types.d.ts +55 -0
  56. package/build/src/background-jobs/types.d.ts.map +1 -1
  57. package/build/src/background-jobs/types.js +16 -1
  58. package/build/src/configuration-types.d.ts +3 -3
  59. package/build/src/configuration-types.d.ts.map +1 -1
  60. package/build/src/configuration-types.js +2 -2
  61. package/build/src/configuration.d.ts +18 -8
  62. package/build/src/configuration.d.ts.map +1 -1
  63. package/build/src/configuration.js +38 -7
  64. package/build/src/database/drivers/base-column.d.ts +5 -0
  65. package/build/src/database/drivers/base-column.d.ts.map +1 -1
  66. package/build/src/database/drivers/base-column.js +8 -1
  67. package/build/src/database/drivers/mssql/sql/update.d.ts.map +1 -1
  68. package/build/src/database/drivers/mssql/sql/update.js +2 -4
  69. package/build/src/database/drivers/mysql/sql/update.d.ts.map +1 -1
  70. package/build/src/database/drivers/mysql/sql/update.js +2 -4
  71. package/build/src/database/drivers/pgsql/column.d.ts +5 -0
  72. package/build/src/database/drivers/pgsql/column.d.ts.map +1 -1
  73. package/build/src/database/drivers/pgsql/column.js +19 -1
  74. package/build/src/database/drivers/pgsql/sql/update.d.ts.map +1 -1
  75. package/build/src/database/drivers/pgsql/sql/update.js +2 -4
  76. package/build/src/database/drivers/sqlite/sql/alter-table.d.ts.map +1 -1
  77. package/build/src/database/drivers/sqlite/sql/alter-table.js +6 -2
  78. package/build/src/database/drivers/sqlite/sql/update.d.ts.map +1 -1
  79. package/build/src/database/drivers/sqlite/sql/update.js +2 -4
  80. package/build/src/database/query/index.d.ts +4 -4
  81. package/build/src/database/query/index.d.ts.map +1 -1
  82. package/build/src/database/query/index.js +3 -3
  83. package/build/src/database/query/model-class-query.d.ts +8 -2
  84. package/build/src/database/query/model-class-query.d.ts.map +1 -1
  85. package/build/src/database/query/model-class-query.js +25 -11
  86. package/build/src/database/query/preloader/has-many.d.ts.map +1 -1
  87. package/build/src/database/query/preloader/has-many.js +4 -2
  88. package/build/src/database/query/query-data.d.ts.map +1 -1
  89. package/build/src/database/query/query-data.js +3 -2
  90. package/build/src/database/query/update-base.d.ts +7 -0
  91. package/build/src/database/query/update-base.d.ts.map +1 -1
  92. package/build/src/database/query/update-base.js +13 -1
  93. package/build/src/database/query/with-count.d.ts.map +1 -1
  94. package/build/src/database/query/with-count.js +3 -2
  95. package/build/src/database/record/acts-as-list.d.ts.map +1 -1
  96. package/build/src/database/record/acts-as-list.js +35 -14
  97. package/build/src/database/record/attachments/store.d.ts +67 -0
  98. package/build/src/database/record/attachments/store.d.ts.map +1 -1
  99. package/build/src/database/record/attachments/store.js +301 -25
  100. package/build/src/database/record/auditing.d.ts.map +1 -1
  101. package/build/src/database/record/auditing.js +7 -4
  102. package/build/src/database/record/index.d.ts +78 -26
  103. package/build/src/database/record/index.d.ts.map +1 -1
  104. package/build/src/database/record/index.js +171 -42
  105. package/build/src/database/record/instance-relationships/belongs-to.d.ts.map +1 -1
  106. package/build/src/database/record/instance-relationships/belongs-to.js +3 -2
  107. package/build/src/database/record/validators/uniqueness.d.ts.map +1 -1
  108. package/build/src/database/record/validators/uniqueness.js +8 -6
  109. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts +4 -4
  110. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts.map +1 -1
  111. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.js +24 -12
  112. package/build/src/frontend-model-controller.d.ts +29 -8
  113. package/build/src/frontend-model-controller.d.ts.map +1 -1
  114. package/build/src/frontend-model-controller.js +122 -51
  115. package/build/src/frontend-model-resource/base-resource.d.ts +51 -24
  116. package/build/src/frontend-model-resource/base-resource.d.ts.map +1 -1
  117. package/build/src/frontend-model-resource/base-resource.js +83 -37
  118. package/build/src/frontend-model-resource/velocious-attachment-resource.d.ts +45 -26
  119. package/build/src/frontend-model-resource/velocious-attachment-resource.d.ts.map +1 -1
  120. package/build/src/frontend-model-resource/velocious-attachment-resource.js +89 -31
  121. package/build/src/frontend-models/base.d.ts +53 -20
  122. package/build/src/frontend-models/base.d.ts.map +1 -1
  123. package/build/src/frontend-models/base.js +275 -59
  124. package/build/src/frontend-models/preloader.d.ts.map +1 -1
  125. package/build/src/frontend-models/preloader.js +6 -4
  126. package/build/src/frontend-models/query.d.ts +2 -2
  127. package/build/src/frontend-models/query.d.ts.map +1 -1
  128. package/build/src/frontend-models/query.js +14 -7
  129. package/build/src/frontend-models/resource-definition.d.ts.map +1 -1
  130. package/build/src/frontend-models/resource-definition.js +20 -3
  131. package/build/src/frontend-models/use-destroyed-event.d.ts +1 -1
  132. package/build/src/frontend-models/use-destroyed-event.d.ts.map +1 -1
  133. package/build/src/frontend-models/use-destroyed-event.js +2 -2
  134. package/build/src/frontend-models/use-model-class-event.d.ts +2 -2
  135. package/build/src/frontend-models/use-model-class-event.d.ts.map +1 -1
  136. package/build/src/frontend-models/use-model-class-event.js +3 -3
  137. package/build/src/frontend-models/use-updated-event.d.ts +1 -1
  138. package/build/src/frontend-models/use-updated-event.d.ts.map +1 -1
  139. package/build/src/frontend-models/use-updated-event.js +2 -2
  140. package/build/src/frontend-models/websocket-channel.d.ts +60 -41
  141. package/build/src/frontend-models/websocket-channel.d.ts.map +1 -1
  142. package/build/src/frontend-models/websocket-channel.js +225 -85
  143. package/build/src/frontend-models/websocket-publishers.d.ts +9 -0
  144. package/build/src/frontend-models/websocket-publishers.d.ts.map +1 -1
  145. package/build/src/frontend-models/websocket-publishers.js +190 -19
  146. package/build/src/http-server/client/websocket-session.d.ts.map +1 -1
  147. package/build/src/http-server/client/websocket-session.js +11 -2
  148. package/build/src/http-server/websocket-channel.d.ts +20 -8
  149. package/build/src/http-server/websocket-channel.d.ts.map +1 -1
  150. package/build/src/http-server/websocket-channel.js +15 -3
  151. package/build/src/sync/sync-api-client.d.ts.map +1 -1
  152. package/build/src/sync/sync-api-client.js +4 -3
  153. package/build/src/sync/sync-client.d.ts.map +1 -1
  154. package/build/src/sync/sync-client.js +3 -2
  155. package/build/src/sync/sync-envelope-replay-service.d.ts.map +1 -1
  156. package/build/src/sync/sync-envelope-replay-service.js +6 -5
  157. package/build/src/sync/sync-publisher.d.ts.map +1 -1
  158. package/build/src/sync/sync-publisher.js +4 -3
  159. package/build/src/testing/browser-frontend-model-event-hook-scenarios.d.ts +2 -2
  160. package/build/src/testing/browser-frontend-model-event-hook-scenarios.d.ts.map +1 -1
  161. package/build/src/testing/browser-frontend-model-event-hook-scenarios.js +3 -3
  162. package/build/src/testing/test-profiler.d.ts +4 -4
  163. package/build/src/testing/test-profiler.d.ts.map +1 -1
  164. package/build/src/testing/test-profiler.js +3 -3
  165. package/build/src/testing/test-runner.d.ts +271 -117
  166. package/build/src/testing/test-runner.d.ts.map +1 -1
  167. package/build/src/testing/test-runner.js +496 -427
  168. package/build/src/testing/test.d.ts +11 -72
  169. package/build/src/testing/test.d.ts.map +1 -1
  170. package/build/src/testing/test.js +131 -284
  171. package/build/src/testing/velocious-attempt-executor.d.ts +14 -29
  172. package/build/src/testing/velocious-attempt-executor.d.ts.map +1 -1
  173. package/build/src/testing/velocious-attempt-executor.js +52 -46
  174. package/build/src/testing/velocious-runner-reporter.d.ts +29 -34
  175. package/build/src/testing/velocious-runner-reporter.d.ts.map +1 -1
  176. package/build/src/testing/velocious-runner-reporter.js +145 -57
  177. package/build/src/testing/velocious-suite-hook-executor.d.ts +5 -23
  178. package/build/src/testing/velocious-suite-hook-executor.d.ts.map +1 -1
  179. package/build/src/testing/velocious-suite-hook-executor.js +22 -47
  180. package/build/src/testing/velocious-test-arguments.d.ts +11 -6
  181. package/build/src/testing/velocious-test-arguments.d.ts.map +1 -1
  182. package/build/src/testing/velocious-test-arguments.js +18 -10
  183. package/build/src/utils/model-primary-key.d.ts +73 -0
  184. package/build/src/utils/model-primary-key.d.ts.map +1 -0
  185. package/build/src/utils/model-primary-key.js +144 -0
  186. package/build/sync/sync-api-client.js +3 -2
  187. package/build/sync/sync-client.js +2 -1
  188. package/build/sync/sync-envelope-replay-service.js +5 -4
  189. package/build/sync/sync-publisher.js +3 -2
  190. package/build/testing/browser-frontend-model-event-hook-scenarios.js +2 -2
  191. package/build/testing/test-profiler.js +2 -2
  192. package/build/testing/test-runner.js +493 -449
  193. package/build/testing/test.js +164 -306
  194. package/build/testing/velocious-attempt-executor.js +55 -45
  195. package/build/testing/velocious-runner-reporter.js +156 -58
  196. package/build/testing/velocious-suite-hook-executor.js +22 -50
  197. package/build/testing/velocious-test-arguments.js +19 -10
  198. package/build/utils/model-primary-key.js +171 -0
  199. package/package.json +6 -5
  200. package/src/authorization/ability.js +36 -13
  201. package/src/background-jobs/adapter.js +9 -0
  202. package/src/background-jobs/main.js +35 -10
  203. package/src/background-jobs/store.js +217 -38
  204. package/src/background-jobs/types.js +15 -0
  205. package/src/configuration-types.js +1 -1
  206. package/src/configuration.js +45 -9
  207. package/src/database/drivers/base-column.js +8 -0
  208. package/src/database/drivers/mssql/sql/update.js +1 -3
  209. package/src/database/drivers/mysql/sql/update.js +1 -3
  210. package/src/database/drivers/pgsql/column.js +22 -0
  211. package/src/database/drivers/pgsql/sql/update.js +1 -3
  212. package/src/database/drivers/sqlite/sql/alter-table.js +11 -1
  213. package/src/database/drivers/sqlite/sql/update.js +1 -3
  214. package/src/database/query/index.js +2 -2
  215. package/src/database/query/model-class-query.js +26 -10
  216. package/src/database/query/preloader/has-many.js +4 -1
  217. package/src/database/query/query-data.js +2 -1
  218. package/src/database/query/update-base.js +14 -0
  219. package/src/database/query/with-count.js +3 -1
  220. package/src/database/record/acts-as-list.js +37 -13
  221. package/src/database/record/attachments/store.js +336 -26
  222. package/src/database/record/auditing.js +6 -3
  223. package/src/database/record/index.js +197 -42
  224. package/src/database/record/instance-relationships/belongs-to.js +2 -1
  225. package/src/database/record/validators/uniqueness.js +8 -5
  226. package/src/environment-handlers/node/cli/commands/generate/frontend-models.js +24 -8
  227. package/src/frontend-model-controller.js +136 -53
  228. package/src/frontend-model-resource/base-resource.js +87 -37
  229. package/src/frontend-model-resource/velocious-attachment-resource.js +98 -31
  230. package/src/frontend-models/base.js +307 -59
  231. package/src/frontend-models/preloader.js +6 -3
  232. package/src/frontend-models/query.js +15 -6
  233. package/src/frontend-models/resource-definition.js +21 -2
  234. package/src/frontend-models/use-destroyed-event.js +1 -1
  235. package/src/frontend-models/use-model-class-event.js +2 -2
  236. package/src/frontend-models/use-updated-event.js +1 -1
  237. package/src/frontend-models/websocket-channel.js +256 -93
  238. package/src/frontend-models/websocket-publishers.js +218 -18
  239. package/src/http-server/client/websocket-session.js +13 -1
  240. package/src/http-server/websocket-channel.js +15 -2
  241. package/src/sync/sync-api-client.js +3 -2
  242. package/src/sync/sync-client.js +2 -1
  243. package/src/sync/sync-envelope-replay-service.js +5 -4
  244. package/src/sync/sync-publisher.js +3 -2
  245. package/src/testing/browser-frontend-model-event-hook-scenarios.js +2 -2
  246. package/src/testing/test-profiler.js +2 -2
  247. package/src/testing/test-runner.js +493 -449
  248. package/src/testing/test.js +164 -306
  249. package/src/testing/velocious-attempt-executor.js +55 -45
  250. package/src/testing/velocious-runner-reporter.js +156 -58
  251. package/src/testing/velocious-suite-hook-executor.js +22 -50
  252. package/src/testing/velocious-test-arguments.js +19 -10
  253. package/src/utils/model-primary-key.js +171 -0
  254. package/build/src/testing/testing-package-adapter.d.ts +0 -9
  255. package/build/src/testing/testing-package-adapter.d.ts.map +0 -1
  256. package/build/src/testing/testing-package-adapter.js +0 -69
  257. package/build/testing/testing-package-adapter.js +0 -76
  258. package/build/tsconfig.tsbuildinfo +0 -1
  259. package/src/testing/testing-package-adapter.js +0 -76
@@ -2,7 +2,8 @@
2
2
  import { TestDatabaseAccessRevokedError } from "../environment-handlers/base.js";
3
3
  import { clearDeliveries } from "../mailer.js";
4
4
  import restArgsError from "../utils/rest-args-error.js";
5
- import { testConfig } from "./test.js";
5
+ import { clearTimeout as realClearTimeout, setTimeout as realSetTimeout } from "node:timers";
6
+ /** @typedef {import("@velocious/testing/runner").AttemptExecutorInput["beforeEach"][number]} PackageHookDeclaration */
6
7
  /**
7
8
  * Marks one whole-lifecycle timeout while its underlying promise keeps running.
8
9
  * @typedef {Error & {velociousTestTimeout?: true}} TestTimeoutError
@@ -20,12 +21,12 @@ function runWithTimeout(promise, timeoutMs, testDescription) {
20
21
  const timeoutError = new Error(`Timed out after ${timeoutSeconds}s: ${testDescription}`);
21
22
  timeoutError.velociousTestTimeout = true;
22
23
  return new Promise((resolve, reject) => {
23
- const timeout = setTimeout(() => reject(timeoutError), timeoutMs);
24
+ const timeout = realSetTimeout(() => reject(timeoutError), timeoutMs);
24
25
  Promise.resolve(promise).then((result) => {
25
- clearTimeout(timeout);
26
+ realClearTimeout(timeout);
26
27
  resolve(result);
27
28
  }).catch((error) => {
28
- clearTimeout(timeout);
29
+ realClearTimeout(timeout);
29
30
  reject(error);
30
31
  });
31
32
  });
@@ -39,7 +40,7 @@ function runWithTimeout(promise, timeoutMs, testDescription) {
39
40
  function awaitSettledOrGrace(lifecycle, graceMs) {
40
41
  return new Promise((resolve) => {
41
42
  let settled = false;
42
- const graceTimer = setTimeout(() => {
43
+ const graceTimer = realSetTimeout(() => {
43
44
  if (settled)
44
45
  return;
45
46
  settled = true;
@@ -49,13 +50,13 @@ function awaitSettledOrGrace(lifecycle, graceMs) {
49
50
  if (settled)
50
51
  return;
51
52
  settled = true;
52
- clearTimeout(graceTimer);
53
+ realClearTimeout(graceTimer);
53
54
  resolve({ settled: true, status: "fulfilled" });
54
55
  }, (reason) => {
55
56
  if (settled)
56
57
  return;
57
58
  settled = true;
58
- clearTimeout(graceTimer);
59
+ realClearTimeout(graceTimer);
59
60
  resolve({ settled: true, status: "rejected", reason });
60
61
  });
61
62
  });
@@ -83,22 +84,30 @@ export default class VelociousAttemptExecutor {
83
84
  restArgsError(restArgs);
84
85
  this.testRunner = testRunner;
85
86
  }
87
+ /**
88
+ * Normalizes the legacy timeout contract at the framework adapter boundary.
89
+ * @param {number | undefined} timeoutMs - Declared package timeout.
90
+ * @returns {number | undefined} - Positive finite timeout, or no timeout.
91
+ */
92
+ normalizeTimeoutMs(timeoutMs) {
93
+ return typeof timeoutMs === "number" && Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : undefined;
94
+ }
86
95
  /**
87
96
  * Executes exactly one complete Velocious-owned test attempt.
88
- * @param {object} args - Attempt arguments.
89
- * @param {import("./test-runner.js").AfterBeforeEachCallbackObjectType[]} args.afterEaches - Cleanup hooks.
90
- * @param {number} args.attemptNumber - One-based attempt number.
91
- * @param {import("./test-runner.js").AfterBeforeEachCallbackObjectType[]} args.beforeEaches - Setup hooks.
92
- * @param {string[]} args.descriptions - Parent descriptions.
93
- * @param {import("./velocious-test-arguments.js").TestArgs} args.testArgs - Stable test arguments.
94
- * @param {import("./velocious-test-arguments.js").TestData} args.testData - Test registration.
95
- * @param {string} args.testDescription - Test description.
96
- * @param {number} [args.timeoutMs] - Whole-lifecycle timeout.
97
- * @returns {Promise<{abortRemainingTests: boolean, consoleOutput: string, error: ReturnType<typeof JSON.parse>, failed: boolean}>} - Attempt outcome.
97
+ * @param {import("@velocious/testing/runner").AttemptExecutorInput} input - Package attempt.
98
+ * @returns {Promise<void>} - Resolves after one complete framework attempt.
98
99
  */
99
- async execute({ afterEaches, attemptNumber, beforeEaches, descriptions, testArgs, testData, testDescription, timeoutMs, ...restArgs }) {
100
+ async execute({ afterEach, args, attemptNumber, beforeEach, context, defaultExecute, fullName, suite, test, timeoutMs, ...restArgs }) {
100
101
  restArgsError(restArgs);
102
+ void context;
103
+ void defaultExecute;
104
+ void suite;
101
105
  const testRunner = this.testRunner;
106
+ const effectiveTimeoutMs = this.normalizeTimeoutMs(timeoutMs);
107
+ const compatibility = await testRunner.testCompatibility(test);
108
+ const { testArgs, testData } = compatibility;
109
+ const metadata = testRunner.testMetadata(test);
110
+ const { descriptions, testDescription } = metadata;
102
111
  /** @type {ReturnType<typeof JSON.parse>} */
103
112
  let caughtError;
104
113
  let failed = false;
@@ -120,14 +129,9 @@ export default class VelociousAttemptExecutor {
120
129
  const recordedTimeoutCleanupErrors = new Set();
121
130
  let abortRemainingTests = false;
122
131
  let attemptTimedOut = false;
123
- /** @type {string} */
124
- let consoleOutput;
125
132
  testArgs.registerTransactionalTenant = async (args) => {
126
133
  await testRunner.registerTransactionalTenant(args, transactionalTenantRegistrations);
127
134
  };
128
- const stopConsoleCapture = testRunner.startConsoleCapture({
129
- passthrough: testConfig.consoleOutput === "live"
130
- });
131
135
  const profiler = testRunner._profiler;
132
136
  const profileAttempt = profiler?.startAttempt({
133
137
  descriptions,
@@ -155,7 +159,7 @@ export default class VelociousAttemptExecutor {
155
159
  }
156
160
  runCleanupHooks = true;
157
161
  clearDeliveries();
158
- await this.runBeforeEaches({ beforeEaches, testArgs, testData });
162
+ await this.runBeforeEaches({ beforeEaches: beforeEach, testArgs, testData });
159
163
  if (useSharedTestConnections) {
160
164
  const activeConnections = testRunner.sharedTransactionConnections({ transactionsOnly: true });
161
165
  if (sharedTransactionBrokerPreparation && !testRunner.sharedTransactionBrokerMatchesConnections(sharedTransactionBrokerPreparation, activeConnections)) {
@@ -171,12 +175,12 @@ export default class VelociousAttemptExecutor {
171
175
  }
172
176
  }
173
177
  testRunner._lastTestContext = {
174
- fullDescription: testRunner.buildFullDescription(descriptions, testDescription),
178
+ fullDescription: fullName,
175
179
  filePath: testData.filePath ?? "<unknown>",
176
180
  line: testData.line ?? 0
177
181
  };
178
182
  await testRunner.runProfileSpan({ phase: "test body", filePath: testData.ownerFilePath ?? testData.filePath }, async () => {
179
- await testData.function(testArgs);
183
+ await test.callback(...args);
180
184
  });
181
185
  }
182
186
  catch (error) {
@@ -208,7 +212,7 @@ export default class VelociousAttemptExecutor {
208
212
  lifecycleErrors.push(error);
209
213
  }
210
214
  try {
211
- await this.runAfterEaches({ afterEaches, testArgs, testData });
215
+ await this.runAfterEaches({ afterEaches: [...afterEach].reverse(), testArgs, testData });
212
216
  }
213
217
  catch (error) {
214
218
  lifecycleErrors.push(error);
@@ -246,8 +250,8 @@ export default class VelociousAttemptExecutor {
246
250
  testLifecycle = profileAttempt && profiler
247
251
  ? profiler.runAttempt(profileAttempt, lifecycleCallback)
248
252
  : lifecycleCallback();
249
- if (timeoutMs !== undefined) {
250
- await runWithTimeout(testLifecycle, timeoutMs, testDescription);
253
+ if (effectiveTimeoutMs !== undefined) {
254
+ await runWithTimeout(testLifecycle, effectiveTimeoutMs, testDescription);
251
255
  }
252
256
  else {
253
257
  await testLifecycle;
@@ -262,7 +266,7 @@ export default class VelociousAttemptExecutor {
262
266
  const emergencyCleanupErrors = [];
263
267
  if (profileAttempt && profiler)
264
268
  profiler.finishAttempt(profileAttempt, "timed-out");
265
- const lifecycleOutcome = await awaitSettledOrGrace(testLifecycle, timeoutMs ?? 60000);
269
+ const lifecycleOutcome = await awaitSettledOrGrace(testLifecycle, effectiveTimeoutMs ?? 60000);
266
270
  if (lifecycleOutcome.settled && lifecycleOutcome.status === "rejected") {
267
271
  emergencyCleanupErrors.push(lifecycleOutcome.reason);
268
272
  }
@@ -274,7 +278,7 @@ export default class VelociousAttemptExecutor {
274
278
  testRunner.recordTimeoutCleanupFailure(cleanupError, "test lifecycle", recordedTimeoutCleanupErrors);
275
279
  });
276
280
  const quarantine = testRunner.quarantineBrowserDummyConnections(browserDummyConnectionRegistrations);
277
- const quarantineOutcome = await awaitSettledOrGrace(quarantine, timeoutMs ?? 60000);
281
+ const quarantineOutcome = await awaitSettledOrGrace(quarantine, effectiveTimeoutMs ?? 60000);
278
282
  const usesBrowserTransactions = testArgs.databaseCleaning?.transaction === true;
279
283
  const usesBrowserTruncation = testArgs.databaseCleaning?.truncate ?? !usesBrowserTransactions;
280
284
  abortRemainingTests = testRunner.isBrowserTestMode()
@@ -300,7 +304,7 @@ export default class VelociousAttemptExecutor {
300
304
  emergencyCleanupErrors.push(cleanupError);
301
305
  }
302
306
  const brokerCleanup = testRunner.stopSharedTransactionBroker(sharedTransactionBrokerRegistration || sharedTransactionBrokerPreparation);
303
- const brokerCleanupOutcome = await awaitSettledOrGrace(brokerCleanup, timeoutMs ?? 60000);
307
+ const brokerCleanupOutcome = await awaitSettledOrGrace(brokerCleanup, effectiveTimeoutMs ?? 60000);
304
308
  if (brokerCleanupOutcome.settled && brokerCleanupOutcome.status === "rejected") {
305
309
  emergencyCleanupErrors.push(brokerCleanupOutcome.reason);
306
310
  }
@@ -312,7 +316,7 @@ export default class VelociousAttemptExecutor {
312
316
  sharedTransactionBrokerRegistration = undefined;
313
317
  sharedTransactionBrokerPreparation = undefined;
314
318
  const emergencyCleanup = testRunner.cleanupTransactionalTenants(transactionalTenantRegistrations, { discard: true });
315
- const emergencyCleanupOutcome = await awaitSettledOrGrace(emergencyCleanup, timeoutMs ?? 60000);
319
+ const emergencyCleanupOutcome = await awaitSettledOrGrace(emergencyCleanup, effectiveTimeoutMs ?? 60000);
316
320
  if (emergencyCleanupOutcome.settled && emergencyCleanupOutcome.status === "rejected") {
317
321
  emergencyCleanupErrors.push(emergencyCleanupOutcome.reason);
318
322
  }
@@ -332,35 +336,36 @@ export default class VelociousAttemptExecutor {
332
336
  }
333
337
  finally {
334
338
  testDatabaseAccessScope.revoked = true;
335
- consoleOutput = stopConsoleCapture();
336
339
  if (profileAttempt && profiler) {
337
340
  profiler.finishAttempt(profileAttempt, failed
338
341
  ? (attemptTimedOut ? "timed-out" : "failed")
339
342
  : "passed");
340
343
  }
341
344
  }
342
- return {
345
+ testRunner.recordAttemptOutcome(test, attemptNumber, {
343
346
  abortRemainingTests,
344
- consoleOutput,
345
347
  error: caughtError,
346
348
  failed
347
- };
349
+ });
350
+ if (failed)
351
+ throw caughtError;
348
352
  }
349
353
  /**
350
354
  * Runs before-each hooks in inherited declaration order.
351
355
  * @param {object} args - Hook arguments.
352
- * @param {import("./test-runner.js").AfterBeforeEachCallbackObjectType[]} args.beforeEaches - Setup hooks.
356
+ * @param {PackageHookDeclaration[]} args.beforeEaches - Setup hooks.
353
357
  * @param {import("./velocious-test-arguments.js").TestArgs} args.testArgs - Stable test arguments.
354
358
  * @param {import("./velocious-test-arguments.js").TestData} args.testData - Test registration.
355
359
  * @returns {Promise<void>} - Resolves after all setup hooks complete.
356
360
  */
357
361
  async runBeforeEaches({ beforeEaches, testArgs, testData }) {
358
362
  for (const hook of beforeEaches) {
363
+ const metadata = this.testRunner.hookMetadata(hook);
359
364
  await this.testRunner.runProfileSpan({
360
365
  phase: "beforeEach",
361
- declarationIndex: hook.declarationIndex,
362
- declarationScopeId: hook.declarationScopeId,
363
- filePath: hook.ownerFilePath
366
+ declarationIndex: metadata.declarationIndex,
367
+ declarationScopeId: metadata.declarationScopeId,
368
+ filePath: metadata.ownerFilePath
364
369
  }, async () => {
365
370
  await hook.callback({ configuration: this.testRunner.getConfiguration(), testArgs, testData });
366
371
  });
@@ -369,7 +374,7 @@ export default class VelociousAttemptExecutor {
369
374
  /**
370
375
  * Runs every after-each hook while preserving all failures.
371
376
  * @param {object} args - Hook arguments.
372
- * @param {import("./test-runner.js").AfterBeforeEachCallbackObjectType[]} args.afterEaches - Cleanup hooks.
377
+ * @param {PackageHookDeclaration[]} args.afterEaches - Cleanup hooks.
373
378
  * @param {import("./velocious-test-arguments.js").TestArgs} args.testArgs - Stable test arguments.
374
379
  * @param {import("./velocious-test-arguments.js").TestData} args.testData - Test registration.
375
380
  * @returns {Promise<void>} - Resolves after every cleanup hook settles.
@@ -378,12 +383,13 @@ export default class VelociousAttemptExecutor {
378
383
  /** @type {ReturnType<typeof JSON.parse>[]} */
379
384
  const errors = [];
380
385
  for (const hook of afterEaches) {
386
+ const metadata = this.testRunner.hookMetadata(hook);
381
387
  try {
382
388
  await this.testRunner.runProfileSpan({
383
389
  phase: "afterEach",
384
- declarationIndex: hook.declarationIndex,
385
- declarationScopeId: hook.declarationScopeId,
386
- filePath: hook.ownerFilePath
390
+ declarationIndex: metadata.declarationIndex,
391
+ declarationScopeId: metadata.declarationScopeId,
392
+ filePath: metadata.ownerFilePath
387
393
  }, async () => {
388
394
  await hook.callback({ configuration: this.testRunner.getConfiguration(), testArgs, testData });
389
395
  });
@@ -399,4 +405,4 @@ export default class VelociousAttemptExecutor {
399
405
  }
400
406
  }
401
407
  }
402
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVsb2Npb3VzLWF0dGVtcHQtZXhlY3V0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGVzdGluZy92ZWxvY2lvdXMtYXR0ZW1wdC1leGVjdXRvci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0saUNBQWlDLENBQUE7QUFDaEYsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGNBQWMsQ0FBQTtBQUM5QyxPQUFPLGFBQWEsTUFBTSw2QkFBNkIsQ0FBQTtBQUN2RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBRXRDOzs7R0FHRztBQUVIOzs7Ozs7R0FNRztBQUNILFNBQVMsY0FBYyxDQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsZUFBZTtJQUN6RCxNQUFNLGNBQWMsR0FBRyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQTtJQUMxRSwrQkFBK0I7SUFDL0IsTUFBTSxZQUFZLEdBQUcsSUFBSSxLQUFLLENBQUMsbUJBQW1CLGNBQWMsTUFBTSxlQUFlLEVBQUUsQ0FBQyxDQUFBO0lBQ3hGLFlBQVksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUE7SUFFeEMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtRQUNyQyxNQUFNLE9BQU8sR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFBO1FBRWpFLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDdkMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBQ3JCLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUNqQixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUNqQixZQUFZLENBQUMsT0FBTyxDQUFDLENBQUE7WUFDckIsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ2YsQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDLENBQUMsQ0FBQTtBQUNKLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQVMsbUJBQW1CLENBQUMsU0FBUyxFQUFFLE9BQU87SUFDN0MsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1FBQzdCLElBQUksT0FBTyxHQUFHLEtBQUssQ0FBQTtRQUNuQixNQUFNLFVBQVUsR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2pDLElBQUksT0FBTztnQkFBRSxPQUFNO1lBRW5CLE9BQU8sR0FBRyxJQUFJLENBQUE7WUFDZCxPQUFPLENBQUMsRUFBQyxPQUFPLEVBQUUsS0FBSyxFQUFDLENBQUMsQ0FBQTtRQUMzQixDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUE7UUFFWCxPQUFPLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksQ0FDN0IsR0FBRyxFQUFFO1lBQ0gsSUFBSSxPQUFPO2dCQUFFLE9BQU07WUFFbkIsT0FBTyxHQUFHLElBQUksQ0FBQTtZQUNkLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQTtZQUN4QixPQUFPLENBQUMsRUFBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUMsQ0FBQyxDQUFBO1FBQy9DLENBQUMsRUFDRCxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ1QsSUFBSSxPQUFPO2dCQUFFLE9BQU07WUFFbkIsT0FBTyxHQUFHLElBQUksQ0FBQTtZQUNkLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQTtZQUN4QixPQUFPLENBQUMsRUFBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFDLENBQUMsQ0FBQTtRQUN0RCxDQUFDLENBQ0YsQ0FBQTtJQUNILENBQUMsQ0FBQyxDQUFBO0FBQ0osQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFTLDhCQUE4QixDQUFDLEtBQUs7SUFDM0MsSUFBSSxLQUFLLFlBQVksOEJBQThCO1FBQUUsT0FBTyxJQUFJLENBQUE7SUFDaEUsSUFBSSxLQUFLLFlBQVksY0FBYyxFQUFFLENBQUM7UUFDcEMsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLDhCQUE4QixDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUE7SUFDcEgsQ0FBQztJQUVELE9BQU8sS0FBSyxDQUFBO0FBQ2QsQ0FBQztBQUVELE1BQU0sQ0FBQyxPQUFPLE9BQU8sd0JBQXdCO0lBQzNDOzs7O09BSUc7SUFDSCxZQUFZLEVBQUMsVUFBVSxFQUFFLEdBQUcsUUFBUSxFQUFDO1FBQ25DLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUN2QixJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQTtJQUM5QixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0gsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFDLFdBQVcsRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQUUsR0FBRyxRQUFRLEVBQUM7UUFDakksYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBQ3ZCLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUE7UUFDbEMsNENBQTRDO1FBQzVDLElBQUksV0FBVyxDQUFBO1FBQ2YsSUFBSSxNQUFNLEdBQUcsS0FBSyxDQUFBO1FBQ2xCLGlFQUFpRTtRQUNqRSxJQUFJLGFBQWEsQ0FBQTtRQUNqQixzSkFBc0o7UUFDdEosSUFBSSxpQ0FBaUMsR0FBRyxFQUFFLENBQUE7UUFDMUMsSUFBSSwyQkFBMkIsR0FBRyxLQUFLLENBQUE7UUFDdkMseUZBQXlGO1FBQ3pGLElBQUksbUNBQW1DLENBQUE7UUFDdkMseUZBQXlGO1FBQ3pGLElBQUksa0NBQWtDLENBQUE7UUFDdEMsMkVBQTJFO1FBQzNFLE1BQU0sZ0NBQWdDLEdBQUcsRUFBRSxDQUFBO1FBQzNDLDhFQUE4RTtRQUM5RSxNQUFNLG1DQUFtQyxHQUFHLEVBQUUsQ0FBQTtRQUM5QyxNQUFNLHVCQUF1QixHQUFHLEVBQUMsT0FBTyxFQUFFLEtBQUssRUFBQyxDQUFBO1FBQ2hELHlCQUF5QjtRQUN6QixNQUFNLDRCQUE0QixHQUFHLElBQUksR0FBRyxFQUFFLENBQUE7UUFDOUMsSUFBSSxtQkFBbUIsR0FBRyxLQUFLLENBQUE7UUFDL0IsSUFBSSxlQUFlLEdBQUcsS0FBSyxDQUFBO1FBQzNCLHFCQUFxQjtRQUNyQixJQUFJLGFBQWEsQ0FBQTtRQUNqQixRQUFRLENBQUMsMkJBQTJCLEdBQUcsS0FBSyxFQUFFLElBQUksRUFBRSxFQUFFO1lBQ3BELE1BQU0sVUFBVSxDQUFDLDJCQUEyQixDQUFDLElBQUksRUFBRSxnQ0FBZ0MsQ0FBQyxDQUFBO1FBQ3RGLENBQUMsQ0FBQTtRQUNELE1BQU0sa0JBQWtCLEdBQUcsVUFBVSxDQUFDLG1CQUFtQixDQUFDO1lBQ3hELFdBQVcsRUFBRSxVQUFVLENBQUMsYUFBYSxLQUFLLE1BQU07U0FDakQsQ0FBQyxDQUFBO1FBQ0YsTUFBTSxRQUFRLEdBQUcsVUFBVSxDQUFDLFNBQVMsQ0FBQTtRQUNyQyxNQUFNLGNBQWMsR0FBRyxRQUFRLEVBQUUsWUFBWSxDQUFDO1lBQzVDLFlBQVk7WUFDWixhQUFhO1lBQ2IsUUFBUTtZQUNSLGVBQWU7U0FDaEIsQ0FBQyxDQUFBO1FBRUYsSUFBSSxDQUFDO1lBQ0gsTUFBTSxvQkFBb0IsR0FBRyxLQUFLLElBQUksRUFBRSxDQUFDLE1BQU0sVUFBVSxDQUFDLG9CQUFvQixDQUFDLFFBQVEsRUFBRSxLQUFLLElBQUksRUFBRTtnQkFDbEcsTUFBTSxjQUFjLEdBQUcsUUFBUSxDQUFDLGdCQUFnQixFQUFFLFdBQVcsS0FBSyxJQUFJLENBQUE7Z0JBQ3RFLE1BQU0sY0FBYyxHQUFHLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRSxRQUFRLElBQUksQ0FBQyxjQUFjLENBQUE7Z0JBQzdFLE1BQU0sd0JBQXdCLEdBQUcsY0FBYyxJQUFJLFFBQVEsQ0FBQyxJQUFJLElBQUksU0FBUyxDQUFBO2dCQUM3RSxNQUFNLGtCQUFrQixHQUFHLHdCQUF3QixJQUFJLGNBQWMsQ0FBQTtnQkFDckUsTUFBTSxjQUFjLEdBQUcsS0FBSyxJQUFJLEVBQUU7b0JBQ2hDLElBQUksd0JBQXdCLEVBQUUsQ0FBQzt3QkFDN0IsaUNBQWlDLEdBQUcsVUFBVSxDQUFDLDZCQUE2QixFQUFFLENBQUE7d0JBQzlFLDJCQUEyQixHQUFHLElBQUksQ0FBQTtvQkFDcEMsQ0FBQztvQkFDRCw4Q0FBOEM7b0JBQzlDLE1BQU0sZUFBZSxHQUFHLEVBQUUsQ0FBQTtvQkFDMUIsSUFBSSxlQUFlLEdBQUcsS0FBSyxDQUFBO29CQUUzQixJQUFJLENBQUM7d0JBQ0gsSUFBSSx3QkFBd0IsRUFBRSxDQUFDOzRCQUM3QixrQ0FBa0MsR0FBRyxNQUFNLFVBQVUsQ0FBQyw4QkFBOEIsRUFBRSxDQUFBO3dCQUN4RixDQUFDO3dCQUNELGVBQWUsR0FBRyxJQUFJLENBQUE7d0JBRXRCLGVBQWUsRUFBRSxDQUFBO3dCQUNqQixNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsRUFBQyxZQUFZLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBQyxDQUFDLENBQUE7d0JBRTlELElBQUksd0JBQXdCLEVBQUUsQ0FBQzs0QkFDN0IsTUFBTSxpQkFBaUIsR0FBRyxVQUFVLENBQUMsNEJBQTRCLENBQUMsRUFBQyxnQkFBZ0IsRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFBOzRCQUMzRixJQUFJLGtDQUFrQyxJQUFJLENBQUMsVUFBVSxDQUFDLHlDQUF5QyxDQUFDLGtDQUFrQyxFQUFFLGlCQUFpQixDQUFDLEVBQUUsQ0FBQztnQ0FDdkosVUFBVSxDQUFDLDBCQUEwQixDQUFDLGlDQUFpQyxDQUFDLENBQUE7Z0NBQ3hFLGlDQUFpQyxHQUFHLEVBQUUsQ0FBQTtnQ0FDdEMsMkJBQTJCLEdBQUcsS0FBSyxDQUFBOzRCQUNyQyxDQUFDOzRCQUVELG1DQUFtQyxHQUFHLE1BQU0sVUFBVSxDQUFDLDRCQUE0QixDQUFDLGtDQUFrQyxFQUFFLGlCQUFpQixDQUFDLENBQUE7NEJBQzFJLGtDQUFrQyxHQUFHLFNBQVMsQ0FBQTs0QkFDOUMsSUFBSSxtQ0FBbUMsSUFBSSxDQUFDLDJCQUEyQixFQUFFLENBQUM7Z0NBQ3hFLGlDQUFpQyxHQUFHLFVBQVUsQ0FBQyw2QkFBNkIsRUFBRSxDQUFBO2dDQUM5RSwyQkFBMkIsR0FBRyxJQUFJLENBQUE7NEJBQ3BDLENBQUM7d0JBQ0gsQ0FBQzt3QkFFRCxVQUFVLENBQUMsZ0JBQWdCLEdBQUc7NEJBQzVCLGVBQWUsRUFBRSxVQUFVLENBQUMsb0JBQW9CLENBQUMsWUFBWSxFQUFFLGVBQWUsQ0FBQzs0QkFDL0UsUUFBUSxFQUFFLFFBQVEsQ0FBQyxRQUFRLElBQUksV0FBVzs0QkFDMUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxJQUFJLElBQUksQ0FBQzt5QkFDekIsQ0FBQTt3QkFDRCxNQUFNLFVBQVUsQ0FBQyxjQUFjLENBQUMsRUFBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUMsYUFBYSxJQUFJLFFBQVEsQ0FBQyxRQUFRLEVBQUMsRUFBRSxLQUFLLElBQUksRUFBRTs0QkFDdEgsTUFBTSxRQUFRLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFBO3dCQUNuQyxDQUFDLENBQUMsQ0FBQTtvQkFDSixDQUFDO29CQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7d0JBQ2YsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtvQkFDN0IsQ0FBQztvQkFFRCxJQUFJLGVBQWUsRUFBRSxDQUFDO3dCQUNwQixJQUFJLENBQUM7NEJBQ0gsTUFBTSxVQUFVLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxzQkFBc0IsRUFBRSxDQUFBO3dCQUM5RCxDQUFDO3dCQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7NEJBQ2YsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTt3QkFDN0IsQ0FBQzt3QkFFRCxJQUFJLENBQUM7NEJBQ0gsSUFBSSwyQkFBMkIsRUFBRSxDQUFDO2dDQUNoQyxVQUFVLENBQUMsMEJBQTBCLENBQUMsaUNBQWlDLENBQUMsQ0FBQTtnQ0FDeEUsaUNBQWlDLEdBQUcsRUFBRSxDQUFBO2dDQUN0QywyQkFBMkIsR0FBRyxLQUFLLENBQUE7NEJBQ3JDLENBQUM7d0JBQ0gsQ0FBQzt3QkFBQyxPQUFPLEtBQUssRUFBRSxDQUFDOzRCQUNmLGVBQWUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7d0JBQzdCLENBQUM7d0JBRUQsSUFBSSxDQUFDOzRCQUNILE1BQU0sVUFBVSxDQUFDLDJCQUEyQixDQUFDLG1DQUFtQyxJQUFJLGtDQUFrQyxDQUFDLENBQUE7NEJBQ3ZILG1DQUFtQyxHQUFHLFNBQVMsQ0FBQTs0QkFDL0Msa0NBQWtDLEdBQUcsU0FBUyxDQUFBO3dCQUNoRCxDQUFDO3dCQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7NEJBQ2YsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTt3QkFDN0IsQ0FBQzt3QkFFRCxJQUFJLENBQUM7NEJBQ0gsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLEVBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUMsQ0FBQyxDQUFBO3dCQUM5RCxDQUFDO3dCQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7NEJBQ2YsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTt3QkFDN0IsQ0FBQzt3QkFFRCxJQUFJLENBQUM7NEJBQ0gsTUFBTSxVQUFVLENBQUMsMkJBQTJCLENBQUMsZ0NBQWdDLENBQUMsQ0FBQTt3QkFDaEYsQ0FBQzt3QkFBQyxPQUFPLEtBQUssRUFBRSxDQUFDOzRCQUNmLGVBQWUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7d0JBQzdCLENBQUM7b0JBQ0gsQ0FBQztvQkFFRCxJQUFJLDJCQUEyQixFQUFFLENBQUM7d0JBQ2hDLElBQUksQ0FBQzs0QkFDSCxVQUFVLENBQUMsMEJBQTBCLENBQUMsaUNBQWlDLENBQUMsQ0FBQTt3QkFDMUUsQ0FBQzt3QkFBQyxPQUFPLEtBQUssRUFBRSxDQUFDOzRCQUNmLGVBQWUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7d0JBQzdCLENBQUM7d0JBQ0QsMkJBQTJCLEdBQUcsS0FBSyxDQUFBO29CQUNyQyxDQUFDO29CQUVELElBQUksZUFBZSxDQUFDLE1BQU0sSUFBSSxDQUFDO3dCQUFFLE1BQU0sZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFBO29CQUN6RCxJQUFJLGVBQWUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7d0JBQy9CLE1BQU0sSUFBSSxjQUFjLENBQUMsZUFBZSxFQUFFLG1DQUFtQyxFQUFFLEVBQUMsS0FBSyxFQUFFLGVBQWUsQ0FBQyxDQUFDLENBQUMsRUFBQyxDQUFDLENBQUE7b0JBQzdHLENBQUM7Z0JBQ0gsQ0FBQyxDQUFBO2dCQUVELElBQUksa0JBQWtCLEVBQUUsQ0FBQztvQkFDdkIsTUFBTSxVQUFVLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFDLElBQUksRUFBRSxTQUFTLGVBQWUsRUFBRSxFQUFDLEVBQUUsY0FBYyxDQUFDLENBQUE7Z0JBQzNHLENBQUM7cUJBQU0sQ0FBQztvQkFDTixNQUFNLGNBQWMsRUFBRSxDQUFBO2dCQUN4QixDQUFDO1lBQ0gsQ0FBQyxFQUFFLG1DQUFtQyxDQUFDLENBQUE7WUFDdkMsTUFBTSxpQkFBaUIsR0FBRyxLQUFLLElBQUksRUFBRSxDQUFDLE1BQU0sVUFBVSxDQUFDLGdCQUFnQixFQUFFLENBQUMsOEJBQThCLENBQUMsdUJBQXVCLEVBQUUsb0JBQW9CLENBQUMsQ0FBQTtZQUN2SixhQUFhLEdBQUcsY0FBYyxJQUFJLFFBQVE7Z0JBQ3hDLENBQUMsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLGNBQWMsRUFBRSxpQkFBaUIsQ0FBQztnQkFDeEQsQ0FBQyxDQUFDLGlCQUFpQixFQUFFLENBQUE7WUFFdkIsSUFBSSxTQUFTLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQzVCLE1BQU0sY0FBYyxDQUFDLGFBQWEsRUFBRSxTQUFTLEVBQUUsZUFBZSxDQUFDLENBQUE7WUFDakUsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE1BQU0sYUFBYSxDQUFBO1lBQ3JCLENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE1BQU0sR0FBRyxJQUFJLENBQUE7WUFDYixXQUFXLEdBQUcsS0FBSyxDQUFBO1lBQ25CLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQywrQkFBK0IsQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUFFLG9CQUFvQixDQUFDLENBQUE7WUFDdkYsZUFBZSxHQUFHLFFBQVEsQ0FBQTtZQUUxQixJQUFJLFFBQVEsSUFBSSxhQUFhLEVBQUUsQ0FBQztnQkFDOUIsTUFBTSxzQkFBc0IsR0FBRyxFQUFFLENBQUE7Z0JBRWpDLElBQUksY0FBYyxJQUFJLFFBQVE7b0JBQUUsUUFBUSxDQUFDLGFBQWEsQ0FBQyxjQUFjLEVBQUUsV0FBVyxDQUFDLENBQUE7Z0JBQ25GLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxtQkFBbUIsQ0FBQyxhQUFhLEVBQUUsU0FBUyxJQUFJLEtBQUssQ0FBQyxDQUFBO2dCQUVyRixJQUFJLGdCQUFnQixDQUFDLE9BQU8sSUFBSSxnQkFBZ0IsQ0FBQyxNQUFNLEtBQUssVUFBVSxFQUFFLENBQUM7b0JBQ3ZFLHNCQUFzQixDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQTtnQkFDdEQsQ0FBQztnQkFFRCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLENBQUM7b0JBQzlCLHVCQUF1QixDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUE7b0JBQ3RDLEtBQUssYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDLFlBQVksRUFBRSxFQUFFO3dCQUN4QyxJQUFJLDhCQUE4QixDQUFDLFlBQVksQ0FBQzs0QkFBRSxPQUFNO3dCQUN4RCxVQUFVLENBQUMsMkJBQTJCLENBQUMsWUFBWSxFQUFFLGdCQUFnQixFQUFFLDRCQUE0QixDQUFDLENBQUE7b0JBQ3RHLENBQUMsQ0FBQyxDQUFBO29CQUNGLE1BQU0sVUFBVSxHQUFHLFVBQVUsQ0FBQyxpQ0FBaUMsQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFBO29CQUNwRyxNQUFNLGlCQUFpQixHQUFHLE1BQU0sbUJBQW1CLENBQUMsVUFBVSxFQUFFLFNBQVMsSUFBSSxLQUFLLENBQUMsQ0FBQTtvQkFDbkYsTUFBTSx1QkFBdUIsR0FBRyxRQUFRLENBQUMsZ0JBQWdCLEVBQUUsV0FBVyxLQUFLLElBQUksQ0FBQTtvQkFDL0UsTUFBTSxxQkFBcUIsR0FBRyxRQUFRLENBQUMsZ0JBQWdCLEVBQUUsUUFBUSxJQUFJLENBQUMsdUJBQXVCLENBQUE7b0JBRTdGLG1CQUFtQixHQUFHLFVBQVUsQ0FBQyxpQkFBaUIsRUFBRTsyQkFDL0MsVUFBVSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDOzJCQUNwQyxDQUFDLHVCQUF1QixJQUFJLHFCQUFxQixDQUFDLENBQUE7b0JBRXZELElBQUksaUJBQWlCLENBQUMsT0FBTyxJQUFJLGlCQUFpQixDQUFDLE1BQU0sS0FBSyxVQUFVLEVBQUUsQ0FBQzt3QkFDekUsc0JBQXNCLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFBO29CQUN2RCxDQUFDO3lCQUFNLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLEVBQUUsQ0FBQzt3QkFDdEMsS0FBSyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsWUFBWSxFQUFFLEVBQUU7NEJBQ3JDLFVBQVUsQ0FBQywyQkFBMkIsQ0FBQyxZQUFZLEVBQUUscUNBQXFDLEVBQUUsNEJBQTRCLENBQUMsQ0FBQTt3QkFDM0gsQ0FBQyxDQUFDLENBQUE7b0JBQ0osQ0FBQztnQkFDSCxDQUFDO2dCQUVELElBQUksQ0FBQztvQkFDSCxJQUFJLDJCQUEyQixFQUFFLENBQUM7d0JBQ2hDLFVBQVUsQ0FBQywwQkFBMEIsQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFBO3dCQUN4RSxpQ0FBaUMsR0FBRyxFQUFFLENBQUE7d0JBQ3RDLDJCQUEyQixHQUFHLEtBQUssQ0FBQTtvQkFDckMsQ0FBQztnQkFDSCxDQUFDO2dCQUFDLE9BQU8sWUFBWSxFQUFFLENBQUM7b0JBQ3RCLHNCQUFzQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQTtnQkFDM0MsQ0FBQztnQkFFRCxNQUFNLGFBQWEsR0FBRyxVQUFVLENBQUMsMkJBQTJCLENBQUMsbUNBQW1DLElBQUksa0NBQWtDLENBQUMsQ0FBQTtnQkFDdkksTUFBTSxvQkFBb0IsR0FBRyxNQUFNLG1CQUFtQixDQUFDLGFBQWEsRUFBRSxTQUFTLElBQUksS0FBSyxDQUFDLENBQUE7Z0JBRXpGLElBQUksb0JBQW9CLENBQUMsT0FBTyxJQUFJLG9CQUFvQixDQUFDLE1BQU0sS0FBSyxVQUFVLEVBQUUsQ0FBQztvQkFDL0Usc0JBQXNCLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFBO2dCQUMxRCxDQUFDO3FCQUFNLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQztvQkFDekMsS0FBSyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsWUFBWSxFQUFFLEVBQUU7d0JBQ3hDLFVBQVUsQ0FBQywyQkFBMkIsQ0FBQyxZQUFZLEVBQUUsMkJBQTJCLEVBQUUsNEJBQTRCLENBQUMsQ0FBQTtvQkFDakgsQ0FBQyxDQUFDLENBQUE7Z0JBQ0osQ0FBQztnQkFDRCxtQ0FBbUMsR0FBRyxTQUFTLENBQUE7Z0JBQy9DLGtDQUFrQyxHQUFHLFNBQVMsQ0FBQTtnQkFDOUMsTUFBTSxnQkFBZ0IsR0FBRyxVQUFVLENBQUMsMkJBQTJCLENBQUMsZ0NBQWdDLEVBQUUsRUFBQyxPQUFPLEVBQUUsSUFBSSxFQUFDLENBQUMsQ0FBQTtnQkFDbEgsTUFBTSx1QkFBdUIsR0FBRyxNQUFNLG1CQUFtQixDQUFDLGdCQUFnQixFQUFFLFNBQVMsSUFBSSxLQUFLLENBQUMsQ0FBQTtnQkFFL0YsSUFBSSx1QkFBdUIsQ0FBQyxPQUFPLElBQUksdUJBQXVCLENBQUMsTUFBTSxLQUFLLFVBQVUsRUFBRSxDQUFDO29CQUNyRixzQkFBc0IsQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsTUFBTSxDQUFDLENBQUE7Z0JBQzdELENBQUM7cUJBQU0sSUFBSSxDQUFDLHVCQUF1QixDQUFDLE9BQU8sRUFBRSxDQUFDO29CQUM1QyxLQUFLLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDLFlBQVksRUFBRSxFQUFFO3dCQUMzQyxVQUFVLENBQUMsMkJBQTJCLENBQUMsWUFBWSxFQUFFLHNCQUFzQixFQUFFLDRCQUE0QixDQUFDLENBQUE7b0JBQzVHLENBQUMsQ0FBQyxDQUFBO2dCQUNKLENBQUM7Z0JBRUQsSUFBSSxzQkFBc0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7b0JBQ3RDLFdBQVcsR0FBRyxJQUFJLGNBQWMsQ0FDOUIsQ0FBQyxXQUFXLEVBQUUsR0FBRyxzQkFBc0IsQ0FBQyxFQUN4QywyQ0FBMkMsRUFDM0MsRUFBQyxLQUFLLEVBQUUsV0FBVyxFQUFDLENBQ3JCLENBQUE7Z0JBQ0gsQ0FBQztZQUNILENBQUM7WUFFRCxJQUFJLG1DQUFtQyxDQUFDLElBQUksQ0FBQyxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3pGLHVCQUF1QixDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUE7Z0JBQ3RDLG1CQUFtQixHQUFHLElBQUksQ0FBQTtZQUM1QixDQUFDO1FBQ0gsQ0FBQztnQkFBUyxDQUFDO1lBQ1QsdUJBQXVCLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQTtZQUN0QyxhQUFhLEdBQUcsa0JBQWtCLEVBQUUsQ0FBQTtZQUVwQyxJQUFJLGNBQWMsSUFBSSxRQUFRLEVBQUUsQ0FBQztnQkFDL0IsUUFBUSxDQUFDLGFBQWEsQ0FBQyxjQUFjLEVBQUUsTUFBTTtvQkFDM0MsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztvQkFDNUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFBO1lBQ2YsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPO1lBQ0wsbUJBQW1CO1lBQ25CLGFBQWE7WUFDYixLQUFLLEVBQUUsV0FBVztZQUNsQixNQUFNO1NBQ1AsQ0FBQTtJQUNILENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsS0FBSyxDQUFDLGVBQWUsQ0FBQyxFQUFDLFlBQVksRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFDO1FBQ3RELEtBQUssTUFBTSxJQUFJLElBQUksWUFBWSxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQztnQkFDbkMsS0FBSyxFQUFFLFlBQVk7Z0JBQ25CLGdCQUFnQixFQUFFLElBQUksQ0FBQyxnQkFBZ0I7Z0JBQ3ZDLGtCQUFrQixFQUFFLElBQUksQ0FBQyxrQkFBa0I7Z0JBQzNDLFFBQVEsRUFBRSxJQUFJLENBQUMsYUFBYTthQUM3QixFQUFFLEtBQUssSUFBSSxFQUFFO2dCQUNaLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBQyxDQUFDLENBQUE7WUFDOUYsQ0FBQyxDQUFDLENBQUE7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxLQUFLLENBQUMsY0FBYyxDQUFDLEVBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUM7UUFDcEQsOENBQThDO1FBQzlDLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQTtRQUVqQixLQUFLLE1BQU0sSUFBSSxJQUFJLFdBQVcsRUFBRSxDQUFDO1lBQy9CLElBQUksQ0FBQztnQkFDSCxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDO29CQUNuQyxLQUFLLEVBQUUsV0FBVztvQkFDbEIsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLGdCQUFnQjtvQkFDdkMsa0JBQWtCLEVBQUUsSUFBSSxDQUFDLGtCQUFrQjtvQkFDM0MsUUFBUSxFQUFFLElBQUksQ0FBQyxhQUFhO2lCQUM3QixFQUFFLEtBQUssSUFBSSxFQUFFO29CQUNaLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBQyxDQUFDLENBQUE7Z0JBQzlGLENBQUMsQ0FBQyxDQUFBO1lBQ0osQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtZQUNwQixDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksTUFBTSxDQUFDLE1BQU0sSUFBSSxDQUFDO1lBQUUsTUFBTSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDdkMsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3RCLE1BQU0sSUFBSSxjQUFjLENBQUMsTUFBTSxFQUFFLGlDQUFpQyxFQUFFLEVBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBQyxDQUFDLENBQUE7UUFDekYsQ0FBQztJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgeyBUZXN0RGF0YWJhc2VBY2Nlc3NSZXZva2VkRXJyb3IgfSBmcm9tIFwiLi4vZW52aXJvbm1lbnQtaGFuZGxlcnMvYmFzZS5qc1wiXG5pbXBvcnQgeyBjbGVhckRlbGl2ZXJpZXMgfSBmcm9tIFwiLi4vbWFpbGVyLmpzXCJcbmltcG9ydCByZXN0QXJnc0Vycm9yIGZyb20gXCIuLi91dGlscy9yZXN0LWFyZ3MtZXJyb3IuanNcIlxuaW1wb3J0IHsgdGVzdENvbmZpZyB9IGZyb20gXCIuL3Rlc3QuanNcIlxuXG4vKipcbiAqIE1hcmtzIG9uZSB3aG9sZS1saWZlY3ljbGUgdGltZW91dCB3aGlsZSBpdHMgdW5kZXJseWluZyBwcm9taXNlIGtlZXBzIHJ1bm5pbmcuXG4gKiBAdHlwZWRlZiB7RXJyb3IgJiB7dmVsb2Npb3VzVGVzdFRpbWVvdXQ/OiB0cnVlfX0gVGVzdFRpbWVvdXRFcnJvclxuICovXG5cbi8qKlxuICogUnVucyBvbmUgcHJvbWlzZSB3aXRoIGEgbGlmZWN5Y2xlIHRpbWVvdXQuXG4gKiBAcGFyYW0ge1Byb21pc2U8UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+IHwgUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IHByb21pc2UgLSBQcm9taXNlIG9yIHZhbHVlLlxuICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXRNcyAtIFRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzLlxuICogQHBhcmFtIHtzdHJpbmd9IHRlc3REZXNjcmlwdGlvbiAtIFRlc3QgZGVzY3JpcHRpb24uXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59IC0gTGlmZWN5Y2xlIHJlc3VsdC5cbiAqL1xuZnVuY3Rpb24gcnVuV2l0aFRpbWVvdXQocHJvbWlzZSwgdGltZW91dE1zLCB0ZXN0RGVzY3JpcHRpb24pIHtcbiAgY29uc3QgdGltZW91dFNlY29uZHMgPSAodGltZW91dE1zIC8gMTAwMCkudG9GaXhlZCgzKS5yZXBsYWNlKC9cXC4/MCskLywgXCJcIilcbiAgLyoqIEB0eXBlIHtUZXN0VGltZW91dEVycm9yfSAqL1xuICBjb25zdCB0aW1lb3V0RXJyb3IgPSBuZXcgRXJyb3IoYFRpbWVkIG91dCBhZnRlciAke3RpbWVvdXRTZWNvbmRzfXM6ICR7dGVzdERlc2NyaXB0aW9ufWApXG4gIHRpbWVvdXRFcnJvci52ZWxvY2lvdXNUZXN0VGltZW91dCA9IHRydWVcblxuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHJlamVjdCh0aW1lb3V0RXJyb3IpLCB0aW1lb3V0TXMpXG5cbiAgICBQcm9taXNlLnJlc29sdmUocHJvbWlzZSkudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dClcbiAgICAgIHJlc29sdmUocmVzdWx0KVxuICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpXG4gICAgICByZWplY3QoZXJyb3IpXG4gICAgfSlcbiAgfSlcbn1cblxuLyoqXG4gKiBXYWl0cyBmb3IgZGV0YWNoZWQgbGlmZWN5Y2xlIGNsZWFudXAgdXAgdG8gdGhlIHRpbWVvdXQgZ3JhY2UgcGVyaW9kLlxuICogQHBhcmFtIHtQcm9taXNlPFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gbGlmZWN5Y2xlIC0gRGV0YWNoZWQgbGlmZWN5Y2xlIHByb21pc2UuXG4gKiBAcGFyYW0ge251bWJlcn0gZ3JhY2VNcyAtIE1heGltdW0gd2FpdC5cbiAqIEByZXR1cm5zIHtQcm9taXNlPHtzZXR0bGVkOiBmYWxzZX0gfCB7c2V0dGxlZDogdHJ1ZSwgc3RhdHVzOiBcImZ1bGZpbGxlZFwifSB8IHtzZXR0bGVkOiB0cnVlLCBzdGF0dXM6IFwicmVqZWN0ZWRcIiwgcmVhc29uOiBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0+fSAtIFNldHRsZW1lbnQgb3V0Y29tZS5cbiAqL1xuZnVuY3Rpb24gYXdhaXRTZXR0bGVkT3JHcmFjZShsaWZlY3ljbGUsIGdyYWNlTXMpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgbGV0IHNldHRsZWQgPSBmYWxzZVxuICAgIGNvbnN0IGdyYWNlVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmIChzZXR0bGVkKSByZXR1cm5cblxuICAgICAgc2V0dGxlZCA9IHRydWVcbiAgICAgIHJlc29sdmUoe3NldHRsZWQ6IGZhbHNlfSlcbiAgICB9LCBncmFjZU1zKVxuXG4gICAgUHJvbWlzZS5yZXNvbHZlKGxpZmVjeWNsZSkudGhlbihcbiAgICAgICgpID0+IHtcbiAgICAgICAgaWYgKHNldHRsZWQpIHJldHVyblxuXG4gICAgICAgIHNldHRsZWQgPSB0cnVlXG4gICAgICAgIGNsZWFyVGltZW91dChncmFjZVRpbWVyKVxuICAgICAgICByZXNvbHZlKHtzZXR0bGVkOiB0cnVlLCBzdGF0dXM6IFwiZnVsZmlsbGVkXCJ9KVxuICAgICAgfSxcbiAgICAgIChyZWFzb24pID0+IHtcbiAgICAgICAgaWYgKHNldHRsZWQpIHJldHVyblxuXG4gICAgICAgIHNldHRsZWQgPSB0cnVlXG4gICAgICAgIGNsZWFyVGltZW91dChncmFjZVRpbWVyKVxuICAgICAgICByZXNvbHZlKHtzZXR0bGVkOiB0cnVlLCBzdGF0dXM6IFwicmVqZWN0ZWRcIiwgcmVhc29ufSlcbiAgICAgIH1cbiAgICApXG4gIH0pXG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYSBsYXRlIGxpZmVjeWNsZSBzdG9wcGVkIG9ubHkgYmVjYXVzZSBpdHMgYXR0ZW1wdCBhY2Nlc3Mgd2FzIHJldm9rZWQuXG4gKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSBlcnJvciAtIExpZmVjeWNsZSByZWplY3Rpb24uXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGV2ZXJ5IGNvbnRhaW5lZCBlcnJvciBpcyBleHBlY3RlZCByZXZvY2F0aW9uLlxuICovXG5mdW5jdGlvbiBpc1Rlc3REYXRhYmFzZUFjY2Vzc1Jldm9jYXRpb24oZXJyb3IpIHtcbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgVGVzdERhdGFiYXNlQWNjZXNzUmV2b2tlZEVycm9yKSByZXR1cm4gdHJ1ZVxuICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBBZ2dyZWdhdGVFcnJvcikge1xuICAgIHJldHVybiBlcnJvci5lcnJvcnMubGVuZ3RoID4gMCAmJiBlcnJvci5lcnJvcnMuZXZlcnkoKG5lc3RlZEVycm9yKSA9PiBpc1Rlc3REYXRhYmFzZUFjY2Vzc1Jldm9jYXRpb24obmVzdGVkRXJyb3IpKVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlXG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFZlbG9jaW91c0F0dGVtcHRFeGVjdXRvciB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGV4ZWN1dG9yIGZvciBmcmFtZXdvcmstb3duZWQgYXR0ZW1wdCBsaWZlY3ljbGUgd29yay5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBDb25zdHJ1Y3RvciBhcmd1bWVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi90ZXN0LXJ1bm5lci5qc1wiKS5kZWZhdWx0fSBhcmdzLnRlc3RSdW5uZXIgLSBPd25pbmcgVmVsb2Npb3VzIHJ1bm5lci5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHt0ZXN0UnVubmVyLCAuLi5yZXN0QXJnc30pIHtcbiAgICByZXN0QXJnc0Vycm9yKHJlc3RBcmdzKVxuICAgIHRoaXMudGVzdFJ1bm5lciA9IHRlc3RSdW5uZXJcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlcyBleGFjdGx5IG9uZSBjb21wbGV0ZSBWZWxvY2lvdXMtb3duZWQgdGVzdCBhdHRlbXB0LlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEF0dGVtcHQgYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuQWZ0ZXJCZWZvcmVFYWNoQ2FsbGJhY2tPYmplY3RUeXBlW119IGFyZ3MuYWZ0ZXJFYWNoZXMgLSBDbGVhbnVwIGhvb2tzLlxuICAgKiBAcGFyYW0ge251bWJlcn0gYXJncy5hdHRlbXB0TnVtYmVyIC0gT25lLWJhc2VkIGF0dGVtcHQgbnVtYmVyLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuQWZ0ZXJCZWZvcmVFYWNoQ2FsbGJhY2tPYmplY3RUeXBlW119IGFyZ3MuYmVmb3JlRWFjaGVzIC0gU2V0dXAgaG9va3MuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGFyZ3MuZGVzY3JpcHRpb25zIC0gUGFyZW50IGRlc2NyaXB0aW9ucy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3ZlbG9jaW91cy10ZXN0LWFyZ3VtZW50cy5qc1wiKS5UZXN0QXJnc30gYXJncy50ZXN0QXJncyAtIFN0YWJsZSB0ZXN0IGFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3ZlbG9jaW91cy10ZXN0LWFyZ3VtZW50cy5qc1wiKS5UZXN0RGF0YX0gYXJncy50ZXN0RGF0YSAtIFRlc3QgcmVnaXN0cmF0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy50ZXN0RGVzY3JpcHRpb24gLSBUZXN0IGRlc2NyaXB0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW2FyZ3MudGltZW91dE1zXSAtIFdob2xlLWxpZmVjeWNsZSB0aW1lb3V0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx7YWJvcnRSZW1haW5pbmdUZXN0czogYm9vbGVhbiwgY29uc29sZU91dHB1dDogc3RyaW5nLCBlcnJvcjogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4sIGZhaWxlZDogYm9vbGVhbn0+fSAtIEF0dGVtcHQgb3V0Y29tZS5cbiAgICovXG4gIGFzeW5jIGV4ZWN1dGUoe2FmdGVyRWFjaGVzLCBhdHRlbXB0TnVtYmVyLCBiZWZvcmVFYWNoZXMsIGRlc2NyaXB0aW9ucywgdGVzdEFyZ3MsIHRlc3REYXRhLCB0ZXN0RGVzY3JpcHRpb24sIHRpbWVvdXRNcywgLi4ucmVzdEFyZ3N9KSB7XG4gICAgcmVzdEFyZ3NFcnJvcihyZXN0QXJncylcbiAgICBjb25zdCB0ZXN0UnVubmVyID0gdGhpcy50ZXN0UnVubmVyXG4gICAgLyoqIEB0eXBlIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gKi9cbiAgICBsZXQgY2F1Z2h0RXJyb3JcbiAgICBsZXQgZmFpbGVkID0gZmFsc2VcbiAgICAvKiogQHR5cGUge1Byb21pc2U8UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+IHwgdW5kZWZpbmVkfSAqL1xuICAgIGxldCB0ZXN0TGlmZWN5Y2xlXG4gICAgLyoqIEB0eXBlIHt7cG9vbDogaW1wb3J0KFwiLi4vZGF0YWJhc2UvcG9vbC9iYXNlLmpzXCIpLmRlZmF1bHQsIHJlZ2lzdHJhdGlvbjogaW1wb3J0KFwiLi4vZGF0YWJhc2UvcG9vbC9iYXNlLmpzXCIpLlRlc3RTaGFyZWRDb25uZWN0aW9uUmVnaXN0cmF0aW9ufVtdfSAqL1xuICAgIGxldCB0ZXN0U2hhcmVkQ29ubmVjdGlvblJlZ2lzdHJhdGlvbnMgPSBbXVxuICAgIGxldCB0ZXN0U2hhcmVkQ29ubmVjdGlvbnNBY3RpdmUgPSBmYWxzZVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90ZXN0LXJ1bm5lci5qc1wiKS5TaGFyZWRUcmFuc2FjdGlvbkJyb2tlclJlZ2lzdHJhdGlvbiB8IHVuZGVmaW5lZH0gKi9cbiAgICBsZXQgc2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJSZWdpc3RyYXRpb25cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuU2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJSZWdpc3RyYXRpb24gfCB1bmRlZmluZWR9ICovXG4gICAgbGV0IHNoYXJlZFRyYW5zYWN0aW9uQnJva2VyUHJlcGFyYXRpb25cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuVHJhbnNhY3Rpb25hbFRlbmFudFJlZ2lzdHJhdGlvbltdfSAqL1xuICAgIGNvbnN0IHRyYW5zYWN0aW9uYWxUZW5hbnRSZWdpc3RyYXRpb25zID0gW11cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuQnJvd3NlckR1bW15Q29ubmVjdGlvblJlZ2lzdHJhdGlvbltdfSAqL1xuICAgIGNvbnN0IGJyb3dzZXJEdW1teUNvbm5lY3Rpb25SZWdpc3RyYXRpb25zID0gW11cbiAgICBjb25zdCB0ZXN0RGF0YWJhc2VBY2Nlc3NTY29wZSA9IHtyZXZva2VkOiBmYWxzZX1cbiAgICAvKiogQHR5cGUge1NldDxFcnJvcj59ICovXG4gICAgY29uc3QgcmVjb3JkZWRUaW1lb3V0Q2xlYW51cEVycm9ycyA9IG5ldyBTZXQoKVxuICAgIGxldCBhYm9ydFJlbWFpbmluZ1Rlc3RzID0gZmFsc2VcbiAgICBsZXQgYXR0ZW1wdFRpbWVkT3V0ID0gZmFsc2VcbiAgICAvKiogQHR5cGUge3N0cmluZ30gKi9cbiAgICBsZXQgY29uc29sZU91dHB1dFxuICAgIHRlc3RBcmdzLnJlZ2lzdGVyVHJhbnNhY3Rpb25hbFRlbmFudCA9IGFzeW5jIChhcmdzKSA9PiB7XG4gICAgICBhd2FpdCB0ZXN0UnVubmVyLnJlZ2lzdGVyVHJhbnNhY3Rpb25hbFRlbmFudChhcmdzLCB0cmFuc2FjdGlvbmFsVGVuYW50UmVnaXN0cmF0aW9ucylcbiAgICB9XG4gICAgY29uc3Qgc3RvcENvbnNvbGVDYXB0dXJlID0gdGVzdFJ1bm5lci5zdGFydENvbnNvbGVDYXB0dXJlKHtcbiAgICAgIHBhc3N0aHJvdWdoOiB0ZXN0Q29uZmlnLmNvbnNvbGVPdXRwdXQgPT09IFwibGl2ZVwiXG4gICAgfSlcbiAgICBjb25zdCBwcm9maWxlciA9IHRlc3RSdW5uZXIuX3Byb2ZpbGVyXG4gICAgY29uc3QgcHJvZmlsZUF0dGVtcHQgPSBwcm9maWxlcj8uc3RhcnRBdHRlbXB0KHtcbiAgICAgIGRlc2NyaXB0aW9ucyxcbiAgICAgIGF0dGVtcHROdW1iZXIsXG4gICAgICB0ZXN0RGF0YSxcbiAgICAgIHRlc3REZXNjcmlwdGlvblxuICAgIH0pXG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcnVuTGlmZWN5Y2xlQ2FsbGJhY2sgPSBhc3luYyAoKSA9PiBhd2FpdCB0ZXN0UnVubmVyLnJ1bldpdGhEdW1teUlmTmVlZGVkKHRlc3RBcmdzLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHVzZVRyYW5zYWN0aW9uID0gdGVzdEFyZ3MuZGF0YWJhc2VDbGVhbmluZz8udHJhbnNhY3Rpb24gPT09IHRydWVcbiAgICAgICAgY29uc3Qgc2hvdWxkVHJ1bmNhdGUgPSB0ZXN0QXJncy5kYXRhYmFzZUNsZWFuaW5nPy50cnVuY2F0ZSA/PyAhdXNlVHJhbnNhY3Rpb25cbiAgICAgICAgY29uc3QgdXNlU2hhcmVkVGVzdENvbm5lY3Rpb25zID0gdXNlVHJhbnNhY3Rpb24gfHwgdGVzdEFyZ3MudHlwZSA9PSBcInJlcXVlc3RcIlxuICAgICAgICBjb25zdCB1c2VUZXN0Q29ubmVjdGlvbnMgPSB1c2VTaGFyZWRUZXN0Q29ubmVjdGlvbnMgfHwgc2hvdWxkVHJ1bmNhdGVcbiAgICAgICAgY29uc3QgcnVuVGVzdEF0dGVtcHQgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgaWYgKHVzZVNoYXJlZFRlc3RDb25uZWN0aW9ucykge1xuICAgICAgICAgICAgdGVzdFNoYXJlZENvbm5lY3Rpb25SZWdpc3RyYXRpb25zID0gdGVzdFJ1bm5lci5hY3RpdmF0ZVRlc3RTaGFyZWRDb25uZWN0aW9ucygpXG4gICAgICAgICAgICB0ZXN0U2hhcmVkQ29ubmVjdGlvbnNBY3RpdmUgPSB0cnVlXG4gICAgICAgICAgfVxuICAgICAgICAgIC8qKiBAdHlwZSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT5bXX0gKi9cbiAgICAgICAgICBjb25zdCBsaWZlY3ljbGVFcnJvcnMgPSBbXVxuICAgICAgICAgIGxldCBydW5DbGVhbnVwSG9va3MgPSBmYWxzZVxuXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmICh1c2VTaGFyZWRUZXN0Q29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgc2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJQcmVwYXJhdGlvbiA9IGF3YWl0IHRlc3RSdW5uZXIucHJlcGFyZVNoYXJlZFRyYW5zYWN0aW9uQnJva2VyKClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJ1bkNsZWFudXBIb29rcyA9IHRydWVcblxuICAgICAgICAgICAgY2xlYXJEZWxpdmVyaWVzKClcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucnVuQmVmb3JlRWFjaGVzKHtiZWZvcmVFYWNoZXMsIHRlc3RBcmdzLCB0ZXN0RGF0YX0pXG5cbiAgICAgICAgICAgIGlmICh1c2VTaGFyZWRUZXN0Q29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgY29uc3QgYWN0aXZlQ29ubmVjdGlvbnMgPSB0ZXN0UnVubmVyLnNoYXJlZFRyYW5zYWN0aW9uQ29ubmVjdGlvbnMoe3RyYW5zYWN0aW9uc09ubHk6IHRydWV9KVxuICAgICAgICAgICAgICBpZiAoc2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJQcmVwYXJhdGlvbiAmJiAhdGVzdFJ1bm5lci5zaGFyZWRUcmFuc2FjdGlvbkJyb2tlck1hdGNoZXNDb25uZWN0aW9ucyhzaGFyZWRUcmFuc2FjdGlvbkJyb2tlclByZXBhcmF0aW9uLCBhY3RpdmVDb25uZWN0aW9ucykpIHtcbiAgICAgICAgICAgICAgICB0ZXN0UnVubmVyLmNsZWFyVGVzdFNoYXJlZENvbm5lY3Rpb25zKHRlc3RTaGFyZWRDb25uZWN0aW9uUmVnaXN0cmF0aW9ucylcbiAgICAgICAgICAgICAgICB0ZXN0U2hhcmVkQ29ubmVjdGlvblJlZ2lzdHJhdGlvbnMgPSBbXVxuICAgICAgICAgICAgICAgIHRlc3RTaGFyZWRDb25uZWN0aW9uc0FjdGl2ZSA9IGZhbHNlXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBzaGFyZWRUcmFuc2FjdGlvbkJyb2tlclJlZ2lzdHJhdGlvbiA9IGF3YWl0IHRlc3RSdW5uZXIuc3RhcnRTaGFyZWRUcmFuc2FjdGlvbkJyb2tlcihzaGFyZWRUcmFuc2FjdGlvbkJyb2tlclByZXBhcmF0aW9uLCBhY3RpdmVDb25uZWN0aW9ucylcbiAgICAgICAgICAgICAgc2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJQcmVwYXJhdGlvbiA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgICBpZiAoc2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJSZWdpc3RyYXRpb24gJiYgIXRlc3RTaGFyZWRDb25uZWN0aW9uc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgIHRlc3RTaGFyZWRDb25uZWN0aW9uUmVnaXN0cmF0aW9ucyA9IHRlc3RSdW5uZXIuYWN0aXZhdGVUZXN0U2hhcmVkQ29ubmVjdGlvbnMoKVxuICAgICAgICAgICAgICAgIHRlc3RTaGFyZWRDb25uZWN0aW9uc0FjdGl2ZSA9IHRydWVcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0ZXN0UnVubmVyLl9sYXN0VGVzdENvbnRleHQgPSB7XG4gICAgICAgICAgICAgIGZ1bGxEZXNjcmlwdGlvbjogdGVzdFJ1bm5lci5idWlsZEZ1bGxEZXNjcmlwdGlvbihkZXNjcmlwdGlvbnMsIHRlc3REZXNjcmlwdGlvbiksXG4gICAgICAgICAgICAgIGZpbGVQYXRoOiB0ZXN0RGF0YS5maWxlUGF0aCA/PyBcIjx1bmtub3duPlwiLFxuICAgICAgICAgICAgICBsaW5lOiB0ZXN0RGF0YS5saW5lID8/IDBcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHRlc3RSdW5uZXIucnVuUHJvZmlsZVNwYW4oe3BoYXNlOiBcInRlc3QgYm9keVwiLCBmaWxlUGF0aDogdGVzdERhdGEub3duZXJGaWxlUGF0aCA/PyB0ZXN0RGF0YS5maWxlUGF0aH0sIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgYXdhaXQgdGVzdERhdGEuZnVuY3Rpb24odGVzdEFyZ3MpXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBsaWZlY3ljbGVFcnJvcnMucHVzaChlcnJvcilcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAocnVuQ2xlYW51cEhvb2tzKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBhd2FpdCB0ZXN0UnVubmVyLmdldENvbmZpZ3VyYXRpb24oKS5hd2FpdFBlbmRpbmdCcm9hZGNhc3RzKClcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGxpZmVjeWNsZUVycm9ycy5wdXNoKGVycm9yKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBpZiAodGVzdFNoYXJlZENvbm5lY3Rpb25zQWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgdGVzdFJ1bm5lci5jbGVhclRlc3RTaGFyZWRDb25uZWN0aW9ucyh0ZXN0U2hhcmVkQ29ubmVjdGlvblJlZ2lzdHJhdGlvbnMpXG4gICAgICAgICAgICAgICAgdGVzdFNoYXJlZENvbm5lY3Rpb25SZWdpc3RyYXRpb25zID0gW11cbiAgICAgICAgICAgICAgICB0ZXN0U2hhcmVkQ29ubmVjdGlvbnNBY3RpdmUgPSBmYWxzZVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICBsaWZlY3ljbGVFcnJvcnMucHVzaChlcnJvcilcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgYXdhaXQgdGVzdFJ1bm5lci5zdG9wU2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXIoc2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJSZWdpc3RyYXRpb24gfHwgc2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJQcmVwYXJhdGlvbilcbiAgICAgICAgICAgICAgc2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJSZWdpc3RyYXRpb24gPSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgc2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJQcmVwYXJhdGlvbiA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgbGlmZWN5Y2xlRXJyb3JzLnB1c2goZXJyb3IpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMucnVuQWZ0ZXJFYWNoZXMoe2FmdGVyRWFjaGVzLCB0ZXN0QXJncywgdGVzdERhdGF9KVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgbGlmZWN5Y2xlRXJyb3JzLnB1c2goZXJyb3IpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGF3YWl0IHRlc3RSdW5uZXIuY2xlYW51cFRyYW5zYWN0aW9uYWxUZW5hbnRzKHRyYW5zYWN0aW9uYWxUZW5hbnRSZWdpc3RyYXRpb25zKVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgbGlmZWN5Y2xlRXJyb3JzLnB1c2goZXJyb3IpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHRlc3RTaGFyZWRDb25uZWN0aW9uc0FjdGl2ZSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgdGVzdFJ1bm5lci5jbGVhclRlc3RTaGFyZWRDb25uZWN0aW9ucyh0ZXN0U2hhcmVkQ29ubmVjdGlvblJlZ2lzdHJhdGlvbnMpXG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICBsaWZlY3ljbGVFcnJvcnMucHVzaChlcnJvcilcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRlc3RTaGFyZWRDb25uZWN0aW9uc0FjdGl2ZSA9IGZhbHNlXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGxpZmVjeWNsZUVycm9ycy5sZW5ndGggPT0gMSkgdGhyb3cgbGlmZWN5Y2xlRXJyb3JzWzBdXG4gICAgICAgICAgaWYgKGxpZmVjeWNsZUVycm9ycy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQWdncmVnYXRlRXJyb3IobGlmZWN5Y2xlRXJyb3JzLCBcIlRlc3QgbGlmZWN5Y2xlIGFuZCBjbGVhbnVwIGZhaWxlZFwiLCB7Y2F1c2U6IGxpZmVjeWNsZUVycm9yc1swXX0pXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHVzZVRlc3RDb25uZWN0aW9ucykge1xuICAgICAgICAgIGF3YWl0IHRlc3RSdW5uZXIuZ2V0Q29uZmlndXJhdGlvbigpLmVuc3VyZUNvbm5lY3Rpb25zKHtuYW1lOiBgVGVzdDogJHt0ZXN0RGVzY3JpcHRpb259YH0sIHJ1blRlc3RBdHRlbXB0KVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGF3YWl0IHJ1blRlc3RBdHRlbXB0KClcbiAgICAgICAgfVxuICAgICAgfSwgYnJvd3NlckR1bW15Q29ubmVjdGlvblJlZ2lzdHJhdGlvbnMpXG4gICAgICBjb25zdCBsaWZlY3ljbGVDYWxsYmFjayA9IGFzeW5jICgpID0+IGF3YWl0IHRlc3RSdW5uZXIuZ2V0Q29uZmlndXJhdGlvbigpLnJ1bldpdGhUZXN0RGF0YWJhc2VBY2Nlc3NTY29wZSh0ZXN0RGF0YWJhc2VBY2Nlc3NTY29wZSwgcnVuTGlmZWN5Y2xlQ2FsbGJhY2spXG4gICAgICB0ZXN0TGlmZWN5Y2xlID0gcHJvZmlsZUF0dGVtcHQgJiYgcHJvZmlsZXJcbiAgICAgICAgPyBwcm9maWxlci5ydW5BdHRlbXB0KHByb2ZpbGVBdHRlbXB0LCBsaWZlY3ljbGVDYWxsYmFjaylcbiAgICAgICAgOiBsaWZlY3ljbGVDYWxsYmFjaygpXG5cbiAgICAgIGlmICh0aW1lb3V0TXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhd2FpdCBydW5XaXRoVGltZW91dCh0ZXN0TGlmZWN5Y2xlLCB0aW1lb3V0TXMsIHRlc3REZXNjcmlwdGlvbilcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGF3YWl0IHRlc3RMaWZlY3ljbGVcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgZmFpbGVkID0gdHJ1ZVxuICAgICAgY2F1Z2h0RXJyb3IgPSBlcnJvclxuICAgICAgY29uc3QgdGltZWRPdXQgPSBCb29sZWFuKC8qKiBAdHlwZSB7VGVzdFRpbWVvdXRFcnJvcn0gKi8gKGVycm9yKT8udmVsb2Npb3VzVGVzdFRpbWVvdXQpXG4gICAgICBhdHRlbXB0VGltZWRPdXQgPSB0aW1lZE91dFxuXG4gICAgICBpZiAodGltZWRPdXQgJiYgdGVzdExpZmVjeWNsZSkge1xuICAgICAgICBjb25zdCBlbWVyZ2VuY3lDbGVhbnVwRXJyb3JzID0gW11cblxuICAgICAgICBpZiAocHJvZmlsZUF0dGVtcHQgJiYgcHJvZmlsZXIpIHByb2ZpbGVyLmZpbmlzaEF0dGVtcHQocHJvZmlsZUF0dGVtcHQsIFwidGltZWQtb3V0XCIpXG4gICAgICAgIGNvbnN0IGxpZmVjeWNsZU91dGNvbWUgPSBhd2FpdCBhd2FpdFNldHRsZWRPckdyYWNlKHRlc3RMaWZlY3ljbGUsIHRpbWVvdXRNcyA/PyA2MDAwMClcblxuICAgICAgICBpZiAobGlmZWN5Y2xlT3V0Y29tZS5zZXR0bGVkICYmIGxpZmVjeWNsZU91dGNvbWUuc3RhdHVzID09PSBcInJlamVjdGVkXCIpIHtcbiAgICAgICAgICBlbWVyZ2VuY3lDbGVhbnVwRXJyb3JzLnB1c2gobGlmZWN5Y2xlT3V0Y29tZS5yZWFzb24pXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWxpZmVjeWNsZU91dGNvbWUuc2V0dGxlZCkge1xuICAgICAgICAgIHRlc3REYXRhYmFzZUFjY2Vzc1Njb3BlLnJldm9rZWQgPSB0cnVlXG4gICAgICAgICAgdm9pZCB0ZXN0TGlmZWN5Y2xlLmNhdGNoKChjbGVhbnVwRXJyb3IpID0+IHtcbiAgICAgICAgICAgIGlmIChpc1Rlc3REYXRhYmFzZUFjY2Vzc1Jldm9jYXRpb24oY2xlYW51cEVycm9yKSkgcmV0dXJuXG4gICAgICAgICAgICB0ZXN0UnVubmVyLnJlY29yZFRpbWVvdXRDbGVhbnVwRmFpbHVyZShjbGVhbnVwRXJyb3IsIFwidGVzdCBsaWZlY3ljbGVcIiwgcmVjb3JkZWRUaW1lb3V0Q2xlYW51cEVycm9ycylcbiAgICAgICAgICB9KVxuICAgICAgICAgIGNvbnN0IHF1YXJhbnRpbmUgPSB0ZXN0UnVubmVyLnF1YXJhbnRpbmVCcm93c2VyRHVtbXlDb25uZWN0aW9ucyhicm93c2VyRHVtbXlDb25uZWN0aW9uUmVnaXN0cmF0aW9ucylcbiAgICAgICAgICBjb25zdCBxdWFyYW50aW5lT3V0Y29tZSA9IGF3YWl0IGF3YWl0U2V0dGxlZE9yR3JhY2UocXVhcmFudGluZSwgdGltZW91dE1zID8/IDYwMDAwKVxuICAgICAgICAgIGNvbnN0IHVzZXNCcm93c2VyVHJhbnNhY3Rpb25zID0gdGVzdEFyZ3MuZGF0YWJhc2VDbGVhbmluZz8udHJhbnNhY3Rpb24gPT09IHRydWVcbiAgICAgICAgICBjb25zdCB1c2VzQnJvd3NlclRydW5jYXRpb24gPSB0ZXN0QXJncy5kYXRhYmFzZUNsZWFuaW5nPy50cnVuY2F0ZSA/PyAhdXNlc0Jyb3dzZXJUcmFuc2FjdGlvbnNcblxuICAgICAgICAgIGFib3J0UmVtYWluaW5nVGVzdHMgPSB0ZXN0UnVubmVyLmlzQnJvd3NlclRlc3RNb2RlKClcbiAgICAgICAgICAgICYmIHRlc3RSdW5uZXIuaGFzVGFnKHRlc3RBcmdzLCBcImR1bW15XCIpXG4gICAgICAgICAgICAmJiAodXNlc0Jyb3dzZXJUcmFuc2FjdGlvbnMgfHwgdXNlc0Jyb3dzZXJUcnVuY2F0aW9uKVxuXG4gICAgICAgICAgaWYgKHF1YXJhbnRpbmVPdXRjb21lLnNldHRsZWQgJiYgcXVhcmFudGluZU91dGNvbWUuc3RhdHVzID09PSBcInJlamVjdGVkXCIpIHtcbiAgICAgICAgICAgIGVtZXJnZW5jeUNsZWFudXBFcnJvcnMucHVzaChxdWFyYW50aW5lT3V0Y29tZS5yZWFzb24pXG4gICAgICAgICAgfSBlbHNlIGlmICghcXVhcmFudGluZU91dGNvbWUuc2V0dGxlZCkge1xuICAgICAgICAgICAgdm9pZCBxdWFyYW50aW5lLmNhdGNoKChjbGVhbnVwRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgdGVzdFJ1bm5lci5yZWNvcmRUaW1lb3V0Q2xlYW51cEZhaWx1cmUoY2xlYW51cEVycm9yLCBcImJyb3dzZXIgZHVtbXkgY29ubmVjdGlvbiBxdWFyYW50aW5lXCIsIHJlY29yZGVkVGltZW91dENsZWFudXBFcnJvcnMpXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgaWYgKHRlc3RTaGFyZWRDb25uZWN0aW9uc0FjdGl2ZSkge1xuICAgICAgICAgICAgdGVzdFJ1bm5lci5jbGVhclRlc3RTaGFyZWRDb25uZWN0aW9ucyh0ZXN0U2hhcmVkQ29ubmVjdGlvblJlZ2lzdHJhdGlvbnMpXG4gICAgICAgICAgICB0ZXN0U2hhcmVkQ29ubmVjdGlvblJlZ2lzdHJhdGlvbnMgPSBbXVxuICAgICAgICAgICAgdGVzdFNoYXJlZENvbm5lY3Rpb25zQWN0aXZlID0gZmFsc2VcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGNsZWFudXBFcnJvcikge1xuICAgICAgICAgIGVtZXJnZW5jeUNsZWFudXBFcnJvcnMucHVzaChjbGVhbnVwRXJyb3IpXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBicm9rZXJDbGVhbnVwID0gdGVzdFJ1bm5lci5zdG9wU2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXIoc2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJSZWdpc3RyYXRpb24gfHwgc2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJQcmVwYXJhdGlvbilcbiAgICAgICAgY29uc3QgYnJva2VyQ2xlYW51cE91dGNvbWUgPSBhd2FpdCBhd2FpdFNldHRsZWRPckdyYWNlKGJyb2tlckNsZWFudXAsIHRpbWVvdXRNcyA/PyA2MDAwMClcblxuICAgICAgICBpZiAoYnJva2VyQ2xlYW51cE91dGNvbWUuc2V0dGxlZCAmJiBicm9rZXJDbGVhbnVwT3V0Y29tZS5zdGF0dXMgPT09IFwicmVqZWN0ZWRcIikge1xuICAgICAgICAgIGVtZXJnZW5jeUNsZWFudXBFcnJvcnMucHVzaChicm9rZXJDbGVhbnVwT3V0Y29tZS5yZWFzb24pXG4gICAgICAgIH0gZWxzZSBpZiAoIWJyb2tlckNsZWFudXBPdXRjb21lLnNldHRsZWQpIHtcbiAgICAgICAgICB2b2lkIGJyb2tlckNsZWFudXAuY2F0Y2goKGNsZWFudXBFcnJvcikgPT4ge1xuICAgICAgICAgICAgdGVzdFJ1bm5lci5yZWNvcmRUaW1lb3V0Q2xlYW51cEZhaWx1cmUoY2xlYW51cEVycm9yLCBcInNoYXJlZCB0cmFuc2FjdGlvbiBicm9rZXJcIiwgcmVjb3JkZWRUaW1lb3V0Q2xlYW51cEVycm9ycylcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICAgIHNoYXJlZFRyYW5zYWN0aW9uQnJva2VyUmVnaXN0cmF0aW9uID0gdW5kZWZpbmVkXG4gICAgICAgIHNoYXJlZFRyYW5zYWN0aW9uQnJva2VyUHJlcGFyYXRpb24gPSB1bmRlZmluZWRcbiAgICAgICAgY29uc3QgZW1lcmdlbmN5Q2xlYW51cCA9IHRlc3RSdW5uZXIuY2xlYW51cFRyYW5zYWN0aW9uYWxUZW5hbnRzKHRyYW5zYWN0aW9uYWxUZW5hbnRSZWdpc3RyYXRpb25zLCB7ZGlzY2FyZDogdHJ1ZX0pXG4gICAgICAgIGNvbnN0IGVtZXJnZW5jeUNsZWFudXBPdXRjb21lID0gYXdhaXQgYXdhaXRTZXR0bGVkT3JHcmFjZShlbWVyZ2VuY3lDbGVhbnVwLCB0aW1lb3V0TXMgPz8gNjAwMDApXG5cbiAgICAgICAgaWYgKGVtZXJnZW5jeUNsZWFudXBPdXRjb21lLnNldHRsZWQgJiYgZW1lcmdlbmN5Q2xlYW51cE91dGNvbWUuc3RhdHVzID09PSBcInJlamVjdGVkXCIpIHtcbiAgICAgICAgICBlbWVyZ2VuY3lDbGVhbnVwRXJyb3JzLnB1c2goZW1lcmdlbmN5Q2xlYW51cE91dGNvbWUucmVhc29uKVxuICAgICAgICB9IGVsc2UgaWYgKCFlbWVyZ2VuY3lDbGVhbnVwT3V0Y29tZS5zZXR0bGVkKSB7XG4gICAgICAgICAgdm9pZCBlbWVyZ2VuY3lDbGVhbnVwLmNhdGNoKChjbGVhbnVwRXJyb3IpID0+IHtcbiAgICAgICAgICAgIHRlc3RSdW5uZXIucmVjb3JkVGltZW91dENsZWFudXBGYWlsdXJlKGNsZWFudXBFcnJvciwgXCJ0cmFuc2FjdGlvbmFsIHRlbmFudFwiLCByZWNvcmRlZFRpbWVvdXRDbGVhbnVwRXJyb3JzKVxuICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZW1lcmdlbmN5Q2xlYW51cEVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY2F1Z2h0RXJyb3IgPSBuZXcgQWdncmVnYXRlRXJyb3IoXG4gICAgICAgICAgICBbY2F1Z2h0RXJyb3IsIC4uLmVtZXJnZW5jeUNsZWFudXBFcnJvcnNdLFxuICAgICAgICAgICAgXCJUZXN0IHRpbWVvdXQgYW5kIGVtZXJnZW5jeSBjbGVhbnVwIGZhaWxlZFwiLFxuICAgICAgICAgICAge2NhdXNlOiBjYXVnaHRFcnJvcn1cbiAgICAgICAgICApXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGJyb3dzZXJEdW1teUNvbm5lY3Rpb25SZWdpc3RyYXRpb25zLnNvbWUoKHJlZ2lzdHJhdGlvbikgPT4gcmVnaXN0cmF0aW9uLnF1YXJhbnRpbmVkKSkge1xuICAgICAgICB0ZXN0RGF0YWJhc2VBY2Nlc3NTY29wZS5yZXZva2VkID0gdHJ1ZVxuICAgICAgICBhYm9ydFJlbWFpbmluZ1Rlc3RzID0gdHJ1ZVxuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0ZXN0RGF0YWJhc2VBY2Nlc3NTY29wZS5yZXZva2VkID0gdHJ1ZVxuICAgICAgY29uc29sZU91dHB1dCA9IHN0b3BDb25zb2xlQ2FwdHVyZSgpXG5cbiAgICAgIGlmIChwcm9maWxlQXR0ZW1wdCAmJiBwcm9maWxlcikge1xuICAgICAgICBwcm9maWxlci5maW5pc2hBdHRlbXB0KHByb2ZpbGVBdHRlbXB0LCBmYWlsZWRcbiAgICAgICAgICA/IChhdHRlbXB0VGltZWRPdXQgPyBcInRpbWVkLW91dFwiIDogXCJmYWlsZWRcIilcbiAgICAgICAgICA6IFwicGFzc2VkXCIpXG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFib3J0UmVtYWluaW5nVGVzdHMsXG4gICAgICBjb25zb2xlT3V0cHV0LFxuICAgICAgZXJyb3I6IGNhdWdodEVycm9yLFxuICAgICAgZmFpbGVkXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYmVmb3JlLWVhY2ggaG9va3MgaW4gaW5oZXJpdGVkIGRlY2xhcmF0aW9uIG9yZGVyLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEhvb2sgYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuQWZ0ZXJCZWZvcmVFYWNoQ2FsbGJhY2tPYmplY3RUeXBlW119IGFyZ3MuYmVmb3JlRWFjaGVzIC0gU2V0dXAgaG9va3MuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi92ZWxvY2lvdXMtdGVzdC1hcmd1bWVudHMuanNcIikuVGVzdEFyZ3N9IGFyZ3MudGVzdEFyZ3MgLSBTdGFibGUgdGVzdCBhcmd1bWVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi92ZWxvY2lvdXMtdGVzdC1hcmd1bWVudHMuanNcIikuVGVzdERhdGF9IGFyZ3MudGVzdERhdGEgLSBUZXN0IHJlZ2lzdHJhdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgYWZ0ZXIgYWxsIHNldHVwIGhvb2tzIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgcnVuQmVmb3JlRWFjaGVzKHtiZWZvcmVFYWNoZXMsIHRlc3RBcmdzLCB0ZXN0RGF0YX0pIHtcbiAgICBmb3IgKGNvbnN0IGhvb2sgb2YgYmVmb3JlRWFjaGVzKSB7XG4gICAgICBhd2FpdCB0aGlzLnRlc3RSdW5uZXIucnVuUHJvZmlsZVNwYW4oe1xuICAgICAgICBwaGFzZTogXCJiZWZvcmVFYWNoXCIsXG4gICAgICAgIGRlY2xhcmF0aW9uSW5kZXg6IGhvb2suZGVjbGFyYXRpb25JbmRleCxcbiAgICAgICAgZGVjbGFyYXRpb25TY29wZUlkOiBob29rLmRlY2xhcmF0aW9uU2NvcGVJZCxcbiAgICAgICAgZmlsZVBhdGg6IGhvb2sub3duZXJGaWxlUGF0aFxuICAgICAgfSwgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCBob29rLmNhbGxiYWNrKHtjb25maWd1cmF0aW9uOiB0aGlzLnRlc3RSdW5uZXIuZ2V0Q29uZmlndXJhdGlvbigpLCB0ZXN0QXJncywgdGVzdERhdGF9KVxuICAgICAgfSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBldmVyeSBhZnRlci1lYWNoIGhvb2sgd2hpbGUgcHJlc2VydmluZyBhbGwgZmFpbHVyZXMuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gSG9vayBhcmd1bWVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi90ZXN0LXJ1bm5lci5qc1wiKS5BZnRlckJlZm9yZUVhY2hDYWxsYmFja09iamVjdFR5cGVbXX0gYXJncy5hZnRlckVhY2hlcyAtIENsZWFudXAgaG9va3MuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi92ZWxvY2lvdXMtdGVzdC1hcmd1bWVudHMuanNcIikuVGVzdEFyZ3N9IGFyZ3MudGVzdEFyZ3MgLSBTdGFibGUgdGVzdCBhcmd1bWVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi92ZWxvY2lvdXMtdGVzdC1hcmd1bWVudHMuanNcIikuVGVzdERhdGF9IGFyZ3MudGVzdERhdGEgLSBUZXN0IHJlZ2lzdHJhdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgYWZ0ZXIgZXZlcnkgY2xlYW51cCBob29rIHNldHRsZXMuXG4gICAqL1xuICBhc3luYyBydW5BZnRlckVhY2hlcyh7YWZ0ZXJFYWNoZXMsIHRlc3RBcmdzLCB0ZXN0RGF0YX0pIHtcbiAgICAvKiogQHR5cGUge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+W119ICovXG4gICAgY29uc3QgZXJyb3JzID0gW11cblxuICAgIGZvciAoY29uc3QgaG9vayBvZiBhZnRlckVhY2hlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy50ZXN0UnVubmVyLnJ1blByb2ZpbGVTcGFuKHtcbiAgICAgICAgICBwaGFzZTogXCJhZnRlckVhY2hcIixcbiAgICAgICAgICBkZWNsYXJhdGlvbkluZGV4OiBob29rLmRlY2xhcmF0aW9uSW5kZXgsXG4gICAgICAgICAgZGVjbGFyYXRpb25TY29wZUlkOiBob29rLmRlY2xhcmF0aW9uU2NvcGVJZCxcbiAgICAgICAgICBmaWxlUGF0aDogaG9vay5vd25lckZpbGVQYXRoXG4gICAgICAgIH0sIGFzeW5jICgpID0+IHtcbiAgICAgICAgICBhd2FpdCBob29rLmNhbGxiYWNrKHtjb25maWd1cmF0aW9uOiB0aGlzLnRlc3RSdW5uZXIuZ2V0Q29uZmlndXJhdGlvbigpLCB0ZXN0QXJncywgdGVzdERhdGF9KVxuICAgICAgICB9KVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goZXJyb3IpXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVycm9ycy5sZW5ndGggPT0gMSkgdGhyb3cgZXJyb3JzWzBdXG4gICAgaWYgKGVycm9ycy5sZW5ndGggPiAxKSB7XG4gICAgICB0aHJvdyBuZXcgQWdncmVnYXRlRXJyb3IoZXJyb3JzLCBcIk11bHRpcGxlIGFmdGVyRWFjaCBob29rcyBmYWlsZWRcIiwge2NhdXNlOiBlcnJvcnNbMF19KVxuICAgIH1cbiAgfVxufVxuIl19
408
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVsb2Npb3VzLWF0dGVtcHQtZXhlY3V0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGVzdGluZy92ZWxvY2lvdXMtYXR0ZW1wdC1leGVjdXRvci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0saUNBQWlDLENBQUE7QUFDaEYsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGNBQWMsQ0FBQTtBQUM5QyxPQUFPLGFBQWEsTUFBTSw2QkFBNkIsQ0FBQTtBQUN2RCxPQUFPLEVBQUMsWUFBWSxJQUFJLGdCQUFnQixFQUFFLFVBQVUsSUFBSSxjQUFjLEVBQUMsTUFBTSxhQUFhLENBQUE7QUFFMUYsdUhBQXVIO0FBRXZIOzs7R0FHRztBQUVIOzs7Ozs7R0FNRztBQUNILFNBQVMsY0FBYyxDQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsZUFBZTtJQUN6RCxNQUFNLGNBQWMsR0FBRyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQTtJQUMxRSwrQkFBK0I7SUFDL0IsTUFBTSxZQUFZLEdBQUcsSUFBSSxLQUFLLENBQUMsbUJBQW1CLGNBQWMsTUFBTSxlQUFlLEVBQUUsQ0FBQyxDQUFBO0lBQ3hGLFlBQVksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUE7SUFFeEMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtRQUNyQyxNQUFNLE9BQU8sR0FBRyxjQUFjLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFBO1FBRXJFLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDdkMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUE7WUFDekIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQ2pCLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ2pCLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBQ3pCLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUNmLENBQUMsQ0FBQyxDQUFBO0lBQ0osQ0FBQyxDQUFDLENBQUE7QUFDSixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFTLG1CQUFtQixDQUFDLFNBQVMsRUFBRSxPQUFPO0lBQzdDLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtRQUM3QixJQUFJLE9BQU8sR0FBRyxLQUFLLENBQUE7UUFDbkIsTUFBTSxVQUFVLEdBQUcsY0FBYyxDQUFDLEdBQUcsRUFBRTtZQUNyQyxJQUFJLE9BQU87Z0JBQUUsT0FBTTtZQUVuQixPQUFPLEdBQUcsSUFBSSxDQUFBO1lBQ2QsT0FBTyxDQUFDLEVBQUMsT0FBTyxFQUFFLEtBQUssRUFBQyxDQUFDLENBQUE7UUFDM0IsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFBO1FBRVgsT0FBTyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQzdCLEdBQUcsRUFBRTtZQUNILElBQUksT0FBTztnQkFBRSxPQUFNO1lBRW5CLE9BQU8sR0FBRyxJQUFJLENBQUE7WUFDZCxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsQ0FBQTtZQUM1QixPQUFPLENBQUMsRUFBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUMsQ0FBQyxDQUFBO1FBQy9DLENBQUMsRUFDRCxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ1QsSUFBSSxPQUFPO2dCQUFFLE9BQU07WUFFbkIsT0FBTyxHQUFHLElBQUksQ0FBQTtZQUNkLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFBO1lBQzVCLE9BQU8sQ0FBQyxFQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUMsQ0FBQyxDQUFBO1FBQ3RELENBQUMsQ0FDRixDQUFBO0lBQ0gsQ0FBQyxDQUFDLENBQUE7QUFDSixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsOEJBQThCLENBQUMsS0FBSztJQUMzQyxJQUFJLEtBQUssWUFBWSw4QkFBOEI7UUFBRSxPQUFPLElBQUksQ0FBQTtJQUNoRSxJQUFJLEtBQUssWUFBWSxjQUFjLEVBQUUsQ0FBQztRQUNwQyxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsOEJBQThCLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQTtJQUNwSCxDQUFDO0lBRUQsT0FBTyxLQUFLLENBQUE7QUFDZCxDQUFDO0FBRUQsTUFBTSxDQUFDLE9BQU8sT0FBTyx3QkFBd0I7SUFDM0M7Ozs7T0FJRztJQUNILFlBQVksRUFBQyxVQUFVLEVBQUUsR0FBRyxRQUFRLEVBQUM7UUFDbkMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBQ3ZCLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFBO0lBQzlCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsa0JBQWtCLENBQUMsU0FBUztRQUMxQixPQUFPLE9BQU8sU0FBUyxLQUFLLFFBQVEsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxJQUFJLFNBQVMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFBO0lBQzdHLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxHQUFHLFFBQVEsRUFBQztRQUNoSSxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUE7UUFDdkIsS0FBSyxPQUFPLENBQUE7UUFDWixLQUFLLGNBQWMsQ0FBQTtRQUNuQixLQUFLLEtBQUssQ0FBQTtRQUNWLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUE7UUFDbEMsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLENBQUE7UUFDN0QsTUFBTSxhQUFhLEdBQUcsTUFBTSxVQUFVLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDOUQsTUFBTSxFQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUMsR0FBRyxhQUFhLENBQUE7UUFDMUMsTUFBTSxRQUFRLEdBQUcsVUFBVSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUM5QyxNQUFNLEVBQUMsWUFBWSxFQUFFLGVBQWUsRUFBQyxHQUFHLFFBQVEsQ0FBQTtRQUNoRCw0Q0FBNEM7UUFDNUMsSUFBSSxXQUFXLENBQUE7UUFDZixJQUFJLE1BQU0sR0FBRyxLQUFLLENBQUE7UUFDbEIsaUVBQWlFO1FBQ2pFLElBQUksYUFBYSxDQUFBO1FBQ2pCLHNKQUFzSjtRQUN0SixJQUFJLGlDQUFpQyxHQUFHLEVBQUUsQ0FBQTtRQUMxQyxJQUFJLDJCQUEyQixHQUFHLEtBQUssQ0FBQTtRQUN2Qyx5RkFBeUY7UUFDekYsSUFBSSxtQ0FBbUMsQ0FBQTtRQUN2Qyx5RkFBeUY7UUFDekYsSUFBSSxrQ0FBa0MsQ0FBQTtRQUN0QywyRUFBMkU7UUFDM0UsTUFBTSxnQ0FBZ0MsR0FBRyxFQUFFLENBQUE7UUFDM0MsOEVBQThFO1FBQzlFLE1BQU0sbUNBQW1DLEdBQUcsRUFBRSxDQUFBO1FBQzlDLE1BQU0sdUJBQXVCLEdBQUcsRUFBQyxPQUFPLEVBQUUsS0FBSyxFQUFDLENBQUE7UUFDaEQseUJBQXlCO1FBQ3pCLE1BQU0sNEJBQTRCLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQTtRQUM5QyxJQUFJLG1CQUFtQixHQUFHLEtBQUssQ0FBQTtRQUMvQixJQUFJLGVBQWUsR0FBRyxLQUFLLENBQUE7UUFDM0IsUUFBUSxDQUFDLDJCQUEyQixHQUFHLEtBQUssRUFBRSxJQUFJLEVBQUUsRUFBRTtZQUNwRCxNQUFNLFVBQVUsQ0FBQywyQkFBMkIsQ0FBQyxJQUFJLEVBQUUsZ0NBQWdDLENBQUMsQ0FBQTtRQUN0RixDQUFDLENBQUE7UUFDRCxNQUFNLFFBQVEsR0FBRyxVQUFVLENBQUMsU0FBUyxDQUFBO1FBQ3JDLE1BQU0sY0FBYyxHQUFHLFFBQVEsRUFBRSxZQUFZLENBQUM7WUFDNUMsWUFBWTtZQUNaLGFBQWE7WUFDYixRQUFRO1lBQ1IsZUFBZTtTQUNoQixDQUFDLENBQUE7UUFFRixJQUFJLENBQUM7WUFDSCxNQUFNLG9CQUFvQixHQUFHLEtBQUssSUFBSSxFQUFFLENBQUMsTUFBTSxVQUFVLENBQUMsb0JBQW9CLENBQUMsUUFBUSxFQUFFLEtBQUssSUFBSSxFQUFFO2dCQUNsRyxNQUFNLGNBQWMsR0FBRyxRQUFRLENBQUMsZ0JBQWdCLEVBQUUsV0FBVyxLQUFLLElBQUksQ0FBQTtnQkFDdEUsTUFBTSxjQUFjLEdBQUcsUUFBUSxDQUFDLGdCQUFnQixFQUFFLFFBQVEsSUFBSSxDQUFDLGNBQWMsQ0FBQTtnQkFDN0UsTUFBTSx3QkFBd0IsR0FBRyxjQUFjLElBQUksUUFBUSxDQUFDLElBQUksSUFBSSxTQUFTLENBQUE7Z0JBQzdFLE1BQU0sa0JBQWtCLEdBQUcsd0JBQXdCLElBQUksY0FBYyxDQUFBO2dCQUNyRSxNQUFNLGNBQWMsR0FBRyxLQUFLLElBQUksRUFBRTtvQkFDaEMsSUFBSSx3QkFBd0IsRUFBRSxDQUFDO3dCQUM3QixpQ0FBaUMsR0FBRyxVQUFVLENBQUMsNkJBQTZCLEVBQUUsQ0FBQTt3QkFDOUUsMkJBQTJCLEdBQUcsSUFBSSxDQUFBO29CQUNwQyxDQUFDO29CQUNELDhDQUE4QztvQkFDOUMsTUFBTSxlQUFlLEdBQUcsRUFBRSxDQUFBO29CQUMxQixJQUFJLGVBQWUsR0FBRyxLQUFLLENBQUE7b0JBRTNCLElBQUksQ0FBQzt3QkFDSCxJQUFJLHdCQUF3QixFQUFFLENBQUM7NEJBQzdCLGtDQUFrQyxHQUFHLE1BQU0sVUFBVSxDQUFDLDhCQUE4QixFQUFFLENBQUE7d0JBQ3hGLENBQUM7d0JBQ0QsZUFBZSxHQUFHLElBQUksQ0FBQTt3QkFFdEIsZUFBZSxFQUFFLENBQUE7d0JBQ2pCLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxFQUFDLFlBQVksRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBQyxDQUFDLENBQUE7d0JBRTFFLElBQUksd0JBQXdCLEVBQUUsQ0FBQzs0QkFDN0IsTUFBTSxpQkFBaUIsR0FBRyxVQUFVLENBQUMsNEJBQTRCLENBQUMsRUFBQyxnQkFBZ0IsRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFBOzRCQUMzRixJQUFJLGtDQUFrQyxJQUFJLENBQUMsVUFBVSxDQUFDLHlDQUF5QyxDQUFDLGtDQUFrQyxFQUFFLGlCQUFpQixDQUFDLEVBQUUsQ0FBQztnQ0FDdkosVUFBVSxDQUFDLDBCQUEwQixDQUFDLGlDQUFpQyxDQUFDLENBQUE7Z0NBQ3hFLGlDQUFpQyxHQUFHLEVBQUUsQ0FBQTtnQ0FDdEMsMkJBQTJCLEdBQUcsS0FBSyxDQUFBOzRCQUNyQyxDQUFDOzRCQUVELG1DQUFtQyxHQUFHLE1BQU0sVUFBVSxDQUFDLDRCQUE0QixDQUFDLGtDQUFrQyxFQUFFLGlCQUFpQixDQUFDLENBQUE7NEJBQzFJLGtDQUFrQyxHQUFHLFNBQVMsQ0FBQTs0QkFDOUMsSUFBSSxtQ0FBbUMsSUFBSSxDQUFDLDJCQUEyQixFQUFFLENBQUM7Z0NBQ3hFLGlDQUFpQyxHQUFHLFVBQVUsQ0FBQyw2QkFBNkIsRUFBRSxDQUFBO2dDQUM5RSwyQkFBMkIsR0FBRyxJQUFJLENBQUE7NEJBQ3BDLENBQUM7d0JBQ0gsQ0FBQzt3QkFFRCxVQUFVLENBQUMsZ0JBQWdCLEdBQUc7NEJBQzVCLGVBQWUsRUFBRSxRQUFROzRCQUN6QixRQUFRLEVBQUUsUUFBUSxDQUFDLFFBQVEsSUFBSSxXQUFXOzRCQUMxQyxJQUFJLEVBQUUsUUFBUSxDQUFDLElBQUksSUFBSSxDQUFDO3lCQUN6QixDQUFBO3dCQUNELE1BQU0sVUFBVSxDQUFDLGNBQWMsQ0FBQyxFQUFDLEtBQUssRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBQyxhQUFhLElBQUksUUFBUSxDQUFDLFFBQVEsRUFBQyxFQUFFLEtBQUssSUFBSSxFQUFFOzRCQUN0SCxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQTt3QkFDOUIsQ0FBQyxDQUFDLENBQUE7b0JBQ0osQ0FBQztvQkFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO3dCQUNmLGVBQWUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7b0JBQzdCLENBQUM7b0JBRUQsSUFBSSxlQUFlLEVBQUUsQ0FBQzt3QkFDcEIsSUFBSSxDQUFDOzRCQUNILE1BQU0sVUFBVSxDQUFDLGdCQUFnQixFQUFFLENBQUMsc0JBQXNCLEVBQUUsQ0FBQTt3QkFDOUQsQ0FBQzt3QkFBQyxPQUFPLEtBQUssRUFBRSxDQUFDOzRCQUNmLGVBQWUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7d0JBQzdCLENBQUM7d0JBRUQsSUFBSSxDQUFDOzRCQUNILElBQUksMkJBQTJCLEVBQUUsQ0FBQztnQ0FDaEMsVUFBVSxDQUFDLDBCQUEwQixDQUFDLGlDQUFpQyxDQUFDLENBQUE7Z0NBQ3hFLGlDQUFpQyxHQUFHLEVBQUUsQ0FBQTtnQ0FDdEMsMkJBQTJCLEdBQUcsS0FBSyxDQUFBOzRCQUNyQyxDQUFDO3dCQUNILENBQUM7d0JBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQzs0QkFDZixlQUFlLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO3dCQUM3QixDQUFDO3dCQUVELElBQUksQ0FBQzs0QkFDSCxNQUFNLFVBQVUsQ0FBQywyQkFBMkIsQ0FBQyxtQ0FBbUMsSUFBSSxrQ0FBa0MsQ0FBQyxDQUFBOzRCQUN2SCxtQ0FBbUMsR0FBRyxTQUFTLENBQUE7NEJBQy9DLGtDQUFrQyxHQUFHLFNBQVMsQ0FBQTt3QkFDaEQsQ0FBQzt3QkFBQyxPQUFPLEtBQUssRUFBRSxDQUFDOzRCQUNmLGVBQWUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7d0JBQzdCLENBQUM7d0JBRUQsSUFBSSxDQUFDOzRCQUNILE1BQU0sSUFBSSxDQUFDLGNBQWMsQ0FBQyxFQUFDLFdBQVcsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBQyxDQUFDLENBQUE7d0JBQ3hGLENBQUM7d0JBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQzs0QkFDZixlQUFlLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO3dCQUM3QixDQUFDO3dCQUVELElBQUksQ0FBQzs0QkFDSCxNQUFNLFVBQVUsQ0FBQywyQkFBMkIsQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFBO3dCQUNoRixDQUFDO3dCQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7NEJBQ2YsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTt3QkFDN0IsQ0FBQztvQkFDSCxDQUFDO29CQUVELElBQUksMkJBQTJCLEVBQUUsQ0FBQzt3QkFDaEMsSUFBSSxDQUFDOzRCQUNILFVBQVUsQ0FBQywwQkFBMEIsQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFBO3dCQUMxRSxDQUFDO3dCQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7NEJBQ2YsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTt3QkFDN0IsQ0FBQzt3QkFDRCwyQkFBMkIsR0FBRyxLQUFLLENBQUE7b0JBQ3JDLENBQUM7b0JBRUQsSUFBSSxlQUFlLENBQUMsTUFBTSxJQUFJLENBQUM7d0JBQUUsTUFBTSxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUE7b0JBQ3pELElBQUksZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQzt3QkFDL0IsTUFBTSxJQUFJLGNBQWMsQ0FBQyxlQUFlLEVBQUUsbUNBQW1DLEVBQUUsRUFBQyxLQUFLLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQTtvQkFDN0csQ0FBQztnQkFDSCxDQUFDLENBQUE7Z0JBRUQsSUFBSSxrQkFBa0IsRUFBRSxDQUFDO29CQUN2QixNQUFNLFVBQVUsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLGlCQUFpQixDQUFDLEVBQUMsSUFBSSxFQUFFLFNBQVMsZUFBZSxFQUFFLEVBQUMsRUFBRSxjQUFjLENBQUMsQ0FBQTtnQkFDM0csQ0FBQztxQkFBTSxDQUFDO29CQUNOLE1BQU0sY0FBYyxFQUFFLENBQUE7Z0JBQ3hCLENBQUM7WUFDSCxDQUFDLEVBQUUsbUNBQW1DLENBQUMsQ0FBQTtZQUN2QyxNQUFNLGlCQUFpQixHQUFHLEtBQUssSUFBSSxFQUFFLENBQUMsTUFBTSxVQUFVLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyw4QkFBOEIsQ0FBQyx1QkFBdUIsRUFBRSxvQkFBb0IsQ0FBQyxDQUFBO1lBQ3ZKLGFBQWEsR0FBRyxjQUFjLElBQUksUUFBUTtnQkFDeEMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsY0FBYyxFQUFFLGlCQUFpQixDQUFDO2dCQUN4RCxDQUFDLENBQUMsaUJBQWlCLEVBQUUsQ0FBQTtZQUV2QixJQUFJLGtCQUFrQixLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUNyQyxNQUFNLGNBQWMsQ0FBQyxhQUFhLEVBQUUsa0JBQWtCLEVBQUUsZUFBZSxDQUFDLENBQUE7WUFDMUUsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE1BQU0sYUFBYSxDQUFBO1lBQ3JCLENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE1BQU0sR0FBRyxJQUFJLENBQUE7WUFDYixXQUFXLEdBQUcsS0FBSyxDQUFBO1lBQ25CLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQywrQkFBK0IsQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUFFLG9CQUFvQixDQUFDLENBQUE7WUFDdkYsZUFBZSxHQUFHLFFBQVEsQ0FBQTtZQUUxQixJQUFJLFFBQVEsSUFBSSxhQUFhLEVBQUUsQ0FBQztnQkFDOUIsTUFBTSxzQkFBc0IsR0FBRyxFQUFFLENBQUE7Z0JBRWpDLElBQUksY0FBYyxJQUFJLFFBQVE7b0JBQUUsUUFBUSxDQUFDLGFBQWEsQ0FBQyxjQUFjLEVBQUUsV0FBVyxDQUFDLENBQUE7Z0JBQ25GLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxtQkFBbUIsQ0FBQyxhQUFhLEVBQUUsa0JBQWtCLElBQUksS0FBSyxDQUFDLENBQUE7Z0JBRTlGLElBQUksZ0JBQWdCLENBQUMsT0FBTyxJQUFJLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxVQUFVLEVBQUUsQ0FBQztvQkFDdkUsc0JBQXNCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFBO2dCQUN0RCxDQUFDO2dCQUVELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQztvQkFDOUIsdUJBQXVCLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQTtvQkFDdEMsS0FBSyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsWUFBWSxFQUFFLEVBQUU7d0JBQ3hDLElBQUksOEJBQThCLENBQUMsWUFBWSxDQUFDOzRCQUFFLE9BQU07d0JBQ3hELFVBQVUsQ0FBQywyQkFBMkIsQ0FBQyxZQUFZLEVBQUUsZ0JBQWdCLEVBQUUsNEJBQTRCLENBQUMsQ0FBQTtvQkFDdEcsQ0FBQyxDQUFDLENBQUE7b0JBQ0YsTUFBTSxVQUFVLEdBQUcsVUFBVSxDQUFDLGlDQUFpQyxDQUFDLG1DQUFtQyxDQUFDLENBQUE7b0JBQ3BHLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxtQkFBbUIsQ0FBQyxVQUFVLEVBQUUsa0JBQWtCLElBQUksS0FBSyxDQUFDLENBQUE7b0JBQzVGLE1BQU0sdUJBQXVCLEdBQUcsUUFBUSxDQUFDLGdCQUFnQixFQUFFLFdBQVcsS0FBSyxJQUFJLENBQUE7b0JBQy9FLE1BQU0scUJBQXFCLEdBQUcsUUFBUSxDQUFDLGdCQUFnQixFQUFFLFFBQVEsSUFBSSxDQUFDLHVCQUF1QixDQUFBO29CQUU3RixtQkFBbUIsR0FBRyxVQUFVLENBQUMsaUJBQWlCLEVBQUU7MkJBQy9DLFVBQVUsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQzsyQkFDcEMsQ0FBQyx1QkFBdUIsSUFBSSxxQkFBcUIsQ0FBQyxDQUFBO29CQUV2RCxJQUFJLGlCQUFpQixDQUFDLE9BQU8sSUFBSSxpQkFBaUIsQ0FBQyxNQUFNLEtBQUssVUFBVSxFQUFFLENBQUM7d0JBQ3pFLHNCQUFzQixDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQTtvQkFDdkQsQ0FBQzt5QkFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxFQUFFLENBQUM7d0JBQ3RDLEtBQUssVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLFlBQVksRUFBRSxFQUFFOzRCQUNyQyxVQUFVLENBQUMsMkJBQTJCLENBQUMsWUFBWSxFQUFFLHFDQUFxQyxFQUFFLDRCQUE0QixDQUFDLENBQUE7d0JBQzNILENBQUMsQ0FBQyxDQUFBO29CQUNKLENBQUM7Z0JBQ0gsQ0FBQztnQkFFRCxJQUFJLENBQUM7b0JBQ0gsSUFBSSwyQkFBMkIsRUFBRSxDQUFDO3dCQUNoQyxVQUFVLENBQUMsMEJBQTBCLENBQUMsaUNBQWlDLENBQUMsQ0FBQTt3QkFDeEUsaUNBQWlDLEdBQUcsRUFBRSxDQUFBO3dCQUN0QywyQkFBMkIsR0FBRyxLQUFLLENBQUE7b0JBQ3JDLENBQUM7Z0JBQ0gsQ0FBQztnQkFBQyxPQUFPLFlBQVksRUFBRSxDQUFDO29CQUN0QixzQkFBc0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUE7Z0JBQzNDLENBQUM7Z0JBRUQsTUFBTSxhQUFhLEdBQUcsVUFBVSxDQUFDLDJCQUEyQixDQUFDLG1DQUFtQyxJQUFJLGtDQUFrQyxDQUFDLENBQUE7Z0JBQ3ZJLE1BQU0sb0JBQW9CLEdBQUcsTUFBTSxtQkFBbUIsQ0FBQyxhQUFhLEVBQUUsa0JBQWtCLElBQUksS0FBSyxDQUFDLENBQUE7Z0JBRWxHLElBQUksb0JBQW9CLENBQUMsT0FBTyxJQUFJLG9CQUFvQixDQUFDLE1BQU0sS0FBSyxVQUFVLEVBQUUsQ0FBQztvQkFDL0Usc0JBQXNCLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFBO2dCQUMxRCxDQUFDO3FCQUFNLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQztvQkFDekMsS0FBSyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsWUFBWSxFQUFFLEVBQUU7d0JBQ3hDLFVBQVUsQ0FBQywyQkFBMkIsQ0FBQyxZQUFZLEVBQUUsMkJBQTJCLEVBQUUsNEJBQTRCLENBQUMsQ0FBQTtvQkFDakgsQ0FBQyxDQUFDLENBQUE7Z0JBQ0osQ0FBQztnQkFDRCxtQ0FBbUMsR0FBRyxTQUFTLENBQUE7Z0JBQy9DLGtDQUFrQyxHQUFHLFNBQVMsQ0FBQTtnQkFDOUMsTUFBTSxnQkFBZ0IsR0FBRyxVQUFVLENBQUMsMkJBQTJCLENBQUMsZ0NBQWdDLEVBQUUsRUFBQyxPQUFPLEVBQUUsSUFBSSxFQUFDLENBQUMsQ0FBQTtnQkFDbEgsTUFBTSx1QkFBdUIsR0FBRyxNQUFNLG1CQUFtQixDQUFDLGdCQUFnQixFQUFFLGtCQUFrQixJQUFJLEtBQUssQ0FBQyxDQUFBO2dCQUV4RyxJQUFJLHVCQUF1QixDQUFDLE9BQU8sSUFBSSx1QkFBdUIsQ0FBQyxNQUFNLEtBQUssVUFBVSxFQUFFLENBQUM7b0JBQ3JGLHNCQUFzQixDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxNQUFNLENBQUMsQ0FBQTtnQkFDN0QsQ0FBQztxQkFBTSxJQUFJLENBQUMsdUJBQXVCLENBQUMsT0FBTyxFQUFFLENBQUM7b0JBQzVDLEtBQUssZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUMsWUFBWSxFQUFFLEVBQUU7d0JBQzNDLFVBQVUsQ0FBQywyQkFBMkIsQ0FBQyxZQUFZLEVBQUUsc0JBQXNCLEVBQUUsNEJBQTRCLENBQUMsQ0FBQTtvQkFDNUcsQ0FBQyxDQUFDLENBQUE7Z0JBQ0osQ0FBQztnQkFFRCxJQUFJLHNCQUFzQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztvQkFDdEMsV0FBVyxHQUFHLElBQUksY0FBYyxDQUM5QixDQUFDLFdBQVcsRUFBRSxHQUFHLHNCQUFzQixDQUFDLEVBQ3hDLDJDQUEyQyxFQUMzQyxFQUFDLEtBQUssRUFBRSxXQUFXLEVBQUMsQ0FDckIsQ0FBQTtnQkFDSCxDQUFDO1lBQ0gsQ0FBQztZQUVELElBQUksbUNBQW1DLENBQUMsSUFBSSxDQUFDLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztnQkFDekYsdUJBQXVCLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQTtnQkFDdEMsbUJBQW1CLEdBQUcsSUFBSSxDQUFBO1lBQzVCLENBQUM7UUFDSCxDQUFDO2dCQUFTLENBQUM7WUFDVCx1QkFBdUIsQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFBO1lBRXRDLElBQUksY0FBYyxJQUFJLFFBQVEsRUFBRSxDQUFDO2dCQUMvQixRQUFRLENBQUMsYUFBYSxDQUFDLGNBQWMsRUFBRSxNQUFNO29CQUMzQyxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDO29CQUM1QyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUE7WUFDZixDQUFDO1FBQ0gsQ0FBQztRQUVELFVBQVUsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsYUFBYSxFQUFFO1lBQ25ELG1CQUFtQjtZQUNuQixLQUFLLEVBQUUsV0FBVztZQUNsQixNQUFNO1NBQ1AsQ0FBQyxDQUFBO1FBRUYsSUFBSSxNQUFNO1lBQUUsTUFBTSxXQUFXLENBQUE7SUFDL0IsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxLQUFLLENBQUMsZUFBZSxDQUFDLEVBQUMsWUFBWSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUM7UUFDdEQsS0FBSyxNQUFNLElBQUksSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUNoQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQTtZQUVuRCxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDO2dCQUNuQyxLQUFLLEVBQUUsWUFBWTtnQkFDbkIsZ0JBQWdCLEVBQUUsUUFBUSxDQUFDLGdCQUFnQjtnQkFDM0Msa0JBQWtCLEVBQUUsUUFBUSxDQUFDLGtCQUFrQjtnQkFDL0MsUUFBUSxFQUFFLFFBQVEsQ0FBQyxhQUFhO2FBQ2pDLEVBQUUsS0FBSyxJQUFJLEVBQUU7Z0JBQ1osTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFDLENBQUMsQ0FBQTtZQUM5RixDQUFDLENBQUMsQ0FBQTtRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILEtBQUssQ0FBQyxjQUFjLENBQUMsRUFBQyxXQUFXLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBQztRQUNwRCw4Q0FBOEM7UUFDOUMsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFBO1FBRWpCLEtBQUssTUFBTSxJQUFJLElBQUksV0FBVyxFQUFFLENBQUM7WUFDL0IsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUE7WUFFbkQsSUFBSSxDQUFDO2dCQUNILE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUM7b0JBQ25DLEtBQUssRUFBRSxXQUFXO29CQUNsQixnQkFBZ0IsRUFBRSxRQUFRLENBQUMsZ0JBQWdCO29CQUMzQyxrQkFBa0IsRUFBRSxRQUFRLENBQUMsa0JBQWtCO29CQUMvQyxRQUFRLEVBQUUsUUFBUSxDQUFDLGFBQWE7aUJBQ2pDLEVBQUUsS0FBSyxJQUFJLEVBQUU7b0JBQ1osTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFDLENBQUMsQ0FBQTtnQkFDOUYsQ0FBQyxDQUFDLENBQUE7WUFDSixDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDZixNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO1lBQ3BCLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxNQUFNLENBQUMsTUFBTSxJQUFJLENBQUM7WUFBRSxNQUFNLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUN2QyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDdEIsTUFBTSxJQUFJLGNBQWMsQ0FBQyxNQUFNLEVBQUUsaUNBQWlDLEVBQUUsRUFBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQTtRQUN6RixDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB7IFRlc3REYXRhYmFzZUFjY2Vzc1Jldm9rZWRFcnJvciB9IGZyb20gXCIuLi9lbnZpcm9ubWVudC1oYW5kbGVycy9iYXNlLmpzXCJcbmltcG9ydCB7IGNsZWFyRGVsaXZlcmllcyB9IGZyb20gXCIuLi9tYWlsZXIuanNcIlxuaW1wb3J0IHJlc3RBcmdzRXJyb3IgZnJvbSBcIi4uL3V0aWxzL3Jlc3QtYXJncy1lcnJvci5qc1wiXG5pbXBvcnQge2NsZWFyVGltZW91dCBhcyByZWFsQ2xlYXJUaW1lb3V0LCBzZXRUaW1lb3V0IGFzIHJlYWxTZXRUaW1lb3V0fSBmcm9tIFwibm9kZTp0aW1lcnNcIlxuXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIkB2ZWxvY2lvdXMvdGVzdGluZy9ydW5uZXJcIikuQXR0ZW1wdEV4ZWN1dG9ySW5wdXRbXCJiZWZvcmVFYWNoXCJdW251bWJlcl19IFBhY2thZ2VIb29rRGVjbGFyYXRpb24gKi9cblxuLyoqXG4gKiBNYXJrcyBvbmUgd2hvbGUtbGlmZWN5Y2xlIHRpbWVvdXQgd2hpbGUgaXRzIHVuZGVybHlpbmcgcHJvbWlzZSBrZWVwcyBydW5uaW5nLlxuICogQHR5cGVkZWYge0Vycm9yICYge3ZlbG9jaW91c1Rlc3RUaW1lb3V0PzogdHJ1ZX19IFRlc3RUaW1lb3V0RXJyb3JcbiAqL1xuXG4vKipcbiAqIFJ1bnMgb25lIHByb21pc2Ugd2l0aCBhIGxpZmVjeWNsZSB0aW1lb3V0LlxuICogQHBhcmFtIHtQcm9taXNlPFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+PiB8IFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSBwcm9taXNlIC0gUHJvbWlzZSBvciB2YWx1ZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lb3V0TXMgLSBUaW1lb3V0IGluIG1pbGxpc2Vjb25kcy5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXN0RGVzY3JpcHRpb24gLSBUZXN0IGRlc2NyaXB0aW9uLlxuICogQHJldHVybnMge1Byb21pc2U8UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+fSAtIExpZmVjeWNsZSByZXN1bHQuXG4gKi9cbmZ1bmN0aW9uIHJ1bldpdGhUaW1lb3V0KHByb21pc2UsIHRpbWVvdXRNcywgdGVzdERlc2NyaXB0aW9uKSB7XG4gIGNvbnN0IHRpbWVvdXRTZWNvbmRzID0gKHRpbWVvdXRNcyAvIDEwMDApLnRvRml4ZWQoMykucmVwbGFjZSgvXFwuPzArJC8sIFwiXCIpXG4gIC8qKiBAdHlwZSB7VGVzdFRpbWVvdXRFcnJvcn0gKi9cbiAgY29uc3QgdGltZW91dEVycm9yID0gbmV3IEVycm9yKGBUaW1lZCBvdXQgYWZ0ZXIgJHt0aW1lb3V0U2Vjb25kc31zOiAke3Rlc3REZXNjcmlwdGlvbn1gKVxuICB0aW1lb3V0RXJyb3IudmVsb2Npb3VzVGVzdFRpbWVvdXQgPSB0cnVlXG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCB0aW1lb3V0ID0gcmVhbFNldFRpbWVvdXQoKCkgPT4gcmVqZWN0KHRpbWVvdXRFcnJvciksIHRpbWVvdXRNcylcblxuICAgIFByb21pc2UucmVzb2x2ZShwcm9taXNlKS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgIHJlYWxDbGVhclRpbWVvdXQodGltZW91dClcbiAgICAgIHJlc29sdmUocmVzdWx0KVxuICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgcmVhbENsZWFyVGltZW91dCh0aW1lb3V0KVxuICAgICAgcmVqZWN0KGVycm9yKVxuICAgIH0pXG4gIH0pXG59XG5cbi8qKlxuICogV2FpdHMgZm9yIGRldGFjaGVkIGxpZmVjeWNsZSBjbGVhbnVwIHVwIHRvIHRoZSB0aW1lb3V0IGdyYWNlIHBlcmlvZC5cbiAqIEBwYXJhbSB7UHJvbWlzZTxSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59IGxpZmVjeWNsZSAtIERldGFjaGVkIGxpZmVjeWNsZSBwcm9taXNlLlxuICogQHBhcmFtIHtudW1iZXJ9IGdyYWNlTXMgLSBNYXhpbXVtIHdhaXQuXG4gKiBAcmV0dXJucyB7UHJvbWlzZTx7c2V0dGxlZDogZmFsc2V9IHwge3NldHRsZWQ6IHRydWUsIHN0YXR1czogXCJmdWxmaWxsZWRcIn0gfCB7c2V0dGxlZDogdHJ1ZSwgc3RhdHVzOiBcInJlamVjdGVkXCIsIHJlYXNvbjogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59Pn0gLSBTZXR0bGVtZW50IG91dGNvbWUuXG4gKi9cbmZ1bmN0aW9uIGF3YWl0U2V0dGxlZE9yR3JhY2UobGlmZWN5Y2xlLCBncmFjZU1zKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgIGxldCBzZXR0bGVkID0gZmFsc2VcbiAgICBjb25zdCBncmFjZVRpbWVyID0gcmVhbFNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgaWYgKHNldHRsZWQpIHJldHVyblxuXG4gICAgICBzZXR0bGVkID0gdHJ1ZVxuICAgICAgcmVzb2x2ZSh7c2V0dGxlZDogZmFsc2V9KVxuICAgIH0sIGdyYWNlTXMpXG5cbiAgICBQcm9taXNlLnJlc29sdmUobGlmZWN5Y2xlKS50aGVuKFxuICAgICAgKCkgPT4ge1xuICAgICAgICBpZiAoc2V0dGxlZCkgcmV0dXJuXG5cbiAgICAgICAgc2V0dGxlZCA9IHRydWVcbiAgICAgICAgcmVhbENsZWFyVGltZW91dChncmFjZVRpbWVyKVxuICAgICAgICByZXNvbHZlKHtzZXR0bGVkOiB0cnVlLCBzdGF0dXM6IFwiZnVsZmlsbGVkXCJ9KVxuICAgICAgfSxcbiAgICAgIChyZWFzb24pID0+IHtcbiAgICAgICAgaWYgKHNldHRsZWQpIHJldHVyblxuXG4gICAgICAgIHNldHRsZWQgPSB0cnVlXG4gICAgICAgIHJlYWxDbGVhclRpbWVvdXQoZ3JhY2VUaW1lcilcbiAgICAgICAgcmVzb2x2ZSh7c2V0dGxlZDogdHJ1ZSwgc3RhdHVzOiBcInJlamVjdGVkXCIsIHJlYXNvbn0pXG4gICAgICB9XG4gICAgKVxuICB9KVxufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIGEgbGF0ZSBsaWZlY3ljbGUgc3RvcHBlZCBvbmx5IGJlY2F1c2UgaXRzIGF0dGVtcHQgYWNjZXNzIHdhcyByZXZva2VkLlxuICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gZXJyb3IgLSBMaWZlY3ljbGUgcmVqZWN0aW9uLlxuICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciBldmVyeSBjb250YWluZWQgZXJyb3IgaXMgZXhwZWN0ZWQgcmV2b2NhdGlvbi5cbiAqL1xuZnVuY3Rpb24gaXNUZXN0RGF0YWJhc2VBY2Nlc3NSZXZvY2F0aW9uKGVycm9yKSB7XG4gIGlmIChlcnJvciBpbnN0YW5jZW9mIFRlc3REYXRhYmFzZUFjY2Vzc1Jldm9rZWRFcnJvcikgcmV0dXJuIHRydWVcbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgQWdncmVnYXRlRXJyb3IpIHtcbiAgICByZXR1cm4gZXJyb3IuZXJyb3JzLmxlbmd0aCA+IDAgJiYgZXJyb3IuZXJyb3JzLmV2ZXJ5KChuZXN0ZWRFcnJvcikgPT4gaXNUZXN0RGF0YWJhc2VBY2Nlc3NSZXZvY2F0aW9uKG5lc3RlZEVycm9yKSlcbiAgfVxuXG4gIHJldHVybiBmYWxzZVxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWZWxvY2lvdXNBdHRlbXB0RXhlY3V0b3Ige1xuICAvKipcbiAgICogQ3JlYXRlcyBhbiBleGVjdXRvciBmb3IgZnJhbWV3b3JrLW93bmVkIGF0dGVtcHQgbGlmZWN5Y2xlIHdvcmsuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gQ29uc3RydWN0b3IgYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuZGVmYXVsdH0gYXJncy50ZXN0UnVubmVyIC0gT3duaW5nIFZlbG9jaW91cyBydW5uZXIuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7dGVzdFJ1bm5lciwgLi4ucmVzdEFyZ3N9KSB7XG4gICAgcmVzdEFyZ3NFcnJvcihyZXN0QXJncylcbiAgICB0aGlzLnRlc3RSdW5uZXIgPSB0ZXN0UnVubmVyXG4gIH1cblxuICAvKipcbiAgICogTm9ybWFsaXplcyB0aGUgbGVnYWN5IHRpbWVvdXQgY29udHJhY3QgYXQgdGhlIGZyYW1ld29yayBhZGFwdGVyIGJvdW5kYXJ5LlxuICAgKiBAcGFyYW0ge251bWJlciB8IHVuZGVmaW5lZH0gdGltZW91dE1zIC0gRGVjbGFyZWQgcGFja2FnZSB0aW1lb3V0LlxuICAgKiBAcmV0dXJucyB7bnVtYmVyIHwgdW5kZWZpbmVkfSAtIFBvc2l0aXZlIGZpbml0ZSB0aW1lb3V0LCBvciBubyB0aW1lb3V0LlxuICAgKi9cbiAgbm9ybWFsaXplVGltZW91dE1zKHRpbWVvdXRNcykge1xuICAgIHJldHVybiB0eXBlb2YgdGltZW91dE1zID09PSBcIm51bWJlclwiICYmIE51bWJlci5pc0Zpbml0ZSh0aW1lb3V0TXMpICYmIHRpbWVvdXRNcyA+IDAgPyB0aW1lb3V0TXMgOiB1bmRlZmluZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlcyBleGFjdGx5IG9uZSBjb21wbGV0ZSBWZWxvY2lvdXMtb3duZWQgdGVzdCBhdHRlbXB0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIkB2ZWxvY2lvdXMvdGVzdGluZy9ydW5uZXJcIikuQXR0ZW1wdEV4ZWN1dG9ySW5wdXR9IGlucHV0IC0gUGFja2FnZSBhdHRlbXB0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciBvbmUgY29tcGxldGUgZnJhbWV3b3JrIGF0dGVtcHQuXG4gICAqL1xuICBhc3luYyBleGVjdXRlKHthZnRlckVhY2gsIGFyZ3MsIGF0dGVtcHROdW1iZXIsIGJlZm9yZUVhY2gsIGNvbnRleHQsIGRlZmF1bHRFeGVjdXRlLCBmdWxsTmFtZSwgc3VpdGUsIHRlc3QsIHRpbWVvdXRNcywgLi4ucmVzdEFyZ3N9KSB7XG4gICAgcmVzdEFyZ3NFcnJvcihyZXN0QXJncylcbiAgICB2b2lkIGNvbnRleHRcbiAgICB2b2lkIGRlZmF1bHRFeGVjdXRlXG4gICAgdm9pZCBzdWl0ZVxuICAgIGNvbnN0IHRlc3RSdW5uZXIgPSB0aGlzLnRlc3RSdW5uZXJcbiAgICBjb25zdCBlZmZlY3RpdmVUaW1lb3V0TXMgPSB0aGlzLm5vcm1hbGl6ZVRpbWVvdXRNcyh0aW1lb3V0TXMpXG4gICAgY29uc3QgY29tcGF0aWJpbGl0eSA9IGF3YWl0IHRlc3RSdW5uZXIudGVzdENvbXBhdGliaWxpdHkodGVzdClcbiAgICBjb25zdCB7dGVzdEFyZ3MsIHRlc3REYXRhfSA9IGNvbXBhdGliaWxpdHlcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRlc3RSdW5uZXIudGVzdE1ldGFkYXRhKHRlc3QpXG4gICAgY29uc3Qge2Rlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9ufSA9IG1ldGFkYXRhXG4gICAgLyoqIEB0eXBlIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gKi9cbiAgICBsZXQgY2F1Z2h0RXJyb3JcbiAgICBsZXQgZmFpbGVkID0gZmFsc2VcbiAgICAvKiogQHR5cGUge1Byb21pc2U8UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+IHwgdW5kZWZpbmVkfSAqL1xuICAgIGxldCB0ZXN0TGlmZWN5Y2xlXG4gICAgLyoqIEB0eXBlIHt7cG9vbDogaW1wb3J0KFwiLi4vZGF0YWJhc2UvcG9vbC9iYXNlLmpzXCIpLmRlZmF1bHQsIHJlZ2lzdHJhdGlvbjogaW1wb3J0KFwiLi4vZGF0YWJhc2UvcG9vbC9iYXNlLmpzXCIpLlRlc3RTaGFyZWRDb25uZWN0aW9uUmVnaXN0cmF0aW9ufVtdfSAqL1xuICAgIGxldCB0ZXN0U2hhcmVkQ29ubmVjdGlvblJlZ2lzdHJhdGlvbnMgPSBbXVxuICAgIGxldCB0ZXN0U2hhcmVkQ29ubmVjdGlvbnNBY3RpdmUgPSBmYWxzZVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90ZXN0LXJ1bm5lci5qc1wiKS5TaGFyZWRUcmFuc2FjdGlvbkJyb2tlclJlZ2lzdHJhdGlvbiB8IHVuZGVmaW5lZH0gKi9cbiAgICBsZXQgc2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJSZWdpc3RyYXRpb25cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuU2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJSZWdpc3RyYXRpb24gfCB1bmRlZmluZWR9ICovXG4gICAgbGV0IHNoYXJlZFRyYW5zYWN0aW9uQnJva2VyUHJlcGFyYXRpb25cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuVHJhbnNhY3Rpb25hbFRlbmFudFJlZ2lzdHJhdGlvbltdfSAqL1xuICAgIGNvbnN0IHRyYW5zYWN0aW9uYWxUZW5hbnRSZWdpc3RyYXRpb25zID0gW11cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuQnJvd3NlckR1bW15Q29ubmVjdGlvblJlZ2lzdHJhdGlvbltdfSAqL1xuICAgIGNvbnN0IGJyb3dzZXJEdW1teUNvbm5lY3Rpb25SZWdpc3RyYXRpb25zID0gW11cbiAgICBjb25zdCB0ZXN0RGF0YWJhc2VBY2Nlc3NTY29wZSA9IHtyZXZva2VkOiBmYWxzZX1cbiAgICAvKiogQHR5cGUge1NldDxFcnJvcj59ICovXG4gICAgY29uc3QgcmVjb3JkZWRUaW1lb3V0Q2xlYW51cEVycm9ycyA9IG5ldyBTZXQoKVxuICAgIGxldCBhYm9ydFJlbWFpbmluZ1Rlc3RzID0gZmFsc2VcbiAgICBsZXQgYXR0ZW1wdFRpbWVkT3V0ID0gZmFsc2VcbiAgICB0ZXN0QXJncy5yZWdpc3RlclRyYW5zYWN0aW9uYWxUZW5hbnQgPSBhc3luYyAoYXJncykgPT4ge1xuICAgICAgYXdhaXQgdGVzdFJ1bm5lci5yZWdpc3RlclRyYW5zYWN0aW9uYWxUZW5hbnQoYXJncywgdHJhbnNhY3Rpb25hbFRlbmFudFJlZ2lzdHJhdGlvbnMpXG4gICAgfVxuICAgIGNvbnN0IHByb2ZpbGVyID0gdGVzdFJ1bm5lci5fcHJvZmlsZXJcbiAgICBjb25zdCBwcm9maWxlQXR0ZW1wdCA9IHByb2ZpbGVyPy5zdGFydEF0dGVtcHQoe1xuICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgYXR0ZW1wdE51bWJlcixcbiAgICAgIHRlc3REYXRhLFxuICAgICAgdGVzdERlc2NyaXB0aW9uXG4gICAgfSlcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBydW5MaWZlY3ljbGVDYWxsYmFjayA9IGFzeW5jICgpID0+IGF3YWl0IHRlc3RSdW5uZXIucnVuV2l0aER1bW15SWZOZWVkZWQodGVzdEFyZ3MsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgdXNlVHJhbnNhY3Rpb24gPSB0ZXN0QXJncy5kYXRhYmFzZUNsZWFuaW5nPy50cmFuc2FjdGlvbiA9PT0gdHJ1ZVxuICAgICAgICBjb25zdCBzaG91bGRUcnVuY2F0ZSA9IHRlc3RBcmdzLmRhdGFiYXNlQ2xlYW5pbmc/LnRydW5jYXRlID8/ICF1c2VUcmFuc2FjdGlvblxuICAgICAgICBjb25zdCB1c2VTaGFyZWRUZXN0Q29ubmVjdGlvbnMgPSB1c2VUcmFuc2FjdGlvbiB8fCB0ZXN0QXJncy50eXBlID09IFwicmVxdWVzdFwiXG4gICAgICAgIGNvbnN0IHVzZVRlc3RDb25uZWN0aW9ucyA9IHVzZVNoYXJlZFRlc3RDb25uZWN0aW9ucyB8fCBzaG91bGRUcnVuY2F0ZVxuICAgICAgICBjb25zdCBydW5UZXN0QXR0ZW1wdCA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgICBpZiAodXNlU2hhcmVkVGVzdENvbm5lY3Rpb25zKSB7XG4gICAgICAgICAgICB0ZXN0U2hhcmVkQ29ubmVjdGlvblJlZ2lzdHJhdGlvbnMgPSB0ZXN0UnVubmVyLmFjdGl2YXRlVGVzdFNoYXJlZENvbm5lY3Rpb25zKClcbiAgICAgICAgICAgIHRlc3RTaGFyZWRDb25uZWN0aW9uc0FjdGl2ZSA9IHRydWVcbiAgICAgICAgICB9XG4gICAgICAgICAgLyoqIEB0eXBlIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPltdfSAqL1xuICAgICAgICAgIGNvbnN0IGxpZmVjeWNsZUVycm9ycyA9IFtdXG4gICAgICAgICAgbGV0IHJ1bkNsZWFudXBIb29rcyA9IGZhbHNlXG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHVzZVNoYXJlZFRlc3RDb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICBzaGFyZWRUcmFuc2FjdGlvbkJyb2tlclByZXBhcmF0aW9uID0gYXdhaXQgdGVzdFJ1bm5lci5wcmVwYXJlU2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXIoKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcnVuQ2xlYW51cEhvb2tzID0gdHJ1ZVxuXG4gICAgICAgICAgICBjbGVhckRlbGl2ZXJpZXMoKVxuICAgICAgICAgICAgYXdhaXQgdGhpcy5ydW5CZWZvcmVFYWNoZXMoe2JlZm9yZUVhY2hlczogYmVmb3JlRWFjaCwgdGVzdEFyZ3MsIHRlc3REYXRhfSlcblxuICAgICAgICAgICAgaWYgKHVzZVNoYXJlZFRlc3RDb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICBjb25zdCBhY3RpdmVDb25uZWN0aW9ucyA9IHRlc3RSdW5uZXIuc2hhcmVkVHJhbnNhY3Rpb25Db25uZWN0aW9ucyh7dHJhbnNhY3Rpb25zT25seTogdHJ1ZX0pXG4gICAgICAgICAgICAgIGlmIChzaGFyZWRUcmFuc2FjdGlvbkJyb2tlclByZXBhcmF0aW9uICYmICF0ZXN0UnVubmVyLnNoYXJlZFRyYW5zYWN0aW9uQnJva2VyTWF0Y2hlc0Nvbm5lY3Rpb25zKHNoYXJlZFRyYW5zYWN0aW9uQnJva2VyUHJlcGFyYXRpb24sIGFjdGl2ZUNvbm5lY3Rpb25zKSkge1xuICAgICAgICAgICAgICAgIHRlc3RSdW5uZXIuY2xlYXJUZXN0U2hhcmVkQ29ubmVjdGlvbnModGVzdFNoYXJlZENvbm5lY3Rpb25SZWdpc3RyYXRpb25zKVxuICAgICAgICAgICAgICAgIHRlc3RTaGFyZWRDb25uZWN0aW9uUmVnaXN0cmF0aW9ucyA9IFtdXG4gICAgICAgICAgICAgICAgdGVzdFNoYXJlZENvbm5lY3Rpb25zQWN0aXZlID0gZmFsc2VcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHNoYXJlZFRyYW5zYWN0aW9uQnJva2VyUmVnaXN0cmF0aW9uID0gYXdhaXQgdGVzdFJ1bm5lci5zdGFydFNoYXJlZFRyYW5zYWN0aW9uQnJva2VyKHNoYXJlZFRyYW5zYWN0aW9uQnJva2VyUHJlcGFyYXRpb24sIGFjdGl2ZUNvbm5lY3Rpb25zKVxuICAgICAgICAgICAgICBzaGFyZWRUcmFuc2FjdGlvbkJyb2tlclByZXBhcmF0aW9uID0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgIGlmIChzaGFyZWRUcmFuc2FjdGlvbkJyb2tlclJlZ2lzdHJhdGlvbiAmJiAhdGVzdFNoYXJlZENvbm5lY3Rpb25zQWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgdGVzdFNoYXJlZENvbm5lY3Rpb25SZWdpc3RyYXRpb25zID0gdGVzdFJ1bm5lci5hY3RpdmF0ZVRlc3RTaGFyZWRDb25uZWN0aW9ucygpXG4gICAgICAgICAgICAgICAgdGVzdFNoYXJlZENvbm5lY3Rpb25zQWN0aXZlID0gdHJ1ZVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRlc3RSdW5uZXIuX2xhc3RUZXN0Q29udGV4dCA9IHtcbiAgICAgICAgICAgICAgZnVsbERlc2NyaXB0aW9uOiBmdWxsTmFtZSxcbiAgICAgICAgICAgICAgZmlsZVBhdGg6IHRlc3REYXRhLmZpbGVQYXRoID8/IFwiPHVua25vd24+XCIsXG4gICAgICAgICAgICAgIGxpbmU6IHRlc3REYXRhLmxpbmUgPz8gMFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgdGVzdFJ1bm5lci5ydW5Qcm9maWxlU3Bhbih7cGhhc2U6IFwidGVzdCBib2R5XCIsIGZpbGVQYXRoOiB0ZXN0RGF0YS5vd25lckZpbGVQYXRoID8/IHRlc3REYXRhLmZpbGVQYXRofSwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICBhd2FpdCB0ZXN0LmNhbGxiYWNrKC4uLmFyZ3MpXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBsaWZlY3ljbGVFcnJvcnMucHVzaChlcnJvcilcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAocnVuQ2xlYW51cEhvb2tzKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBhd2FpdCB0ZXN0UnVubmVyLmdldENvbmZpZ3VyYXRpb24oKS5hd2FpdFBlbmRpbmdCcm9hZGNhc3RzKClcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGxpZmVjeWNsZUVycm9ycy5wdXNoKGVycm9yKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBpZiAodGVzdFNoYXJlZENvbm5lY3Rpb25zQWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgdGVzdFJ1bm5lci5jbGVhclRlc3RTaGFyZWRDb25uZWN0aW9ucyh0ZXN0U2hhcmVkQ29ubmVjdGlvblJlZ2lzdHJhdGlvbnMpXG4gICAgICAgICAgICAgICAgdGVzdFNoYXJlZENvbm5lY3Rpb25SZWdpc3RyYXRpb25zID0gW11cbiAgICAgICAgICAgICAgICB0ZXN0U2hhcmVkQ29ubmVjdGlvbnNBY3RpdmUgPSBmYWxzZVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICBsaWZlY3ljbGVFcnJvcnMucHVzaChlcnJvcilcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgYXdhaXQgdGVzdFJ1bm5lci5zdG9wU2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXIoc2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJSZWdpc3RyYXRpb24gfHwgc2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJQcmVwYXJhdGlvbilcbiAgICAgICAgICAgICAgc2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJSZWdpc3RyYXRpb24gPSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgc2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJQcmVwYXJhdGlvbiA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgbGlmZWN5Y2xlRXJyb3JzLnB1c2goZXJyb3IpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMucnVuQWZ0ZXJFYWNoZXMoe2FmdGVyRWFjaGVzOiBbLi4uYWZ0ZXJFYWNoXS5yZXZlcnNlKCksIHRlc3RBcmdzLCB0ZXN0RGF0YX0pXG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICBsaWZlY3ljbGVFcnJvcnMucHVzaChlcnJvcilcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgYXdhaXQgdGVzdFJ1bm5lci5jbGVhbnVwVHJhbnNhY3Rpb25hbFRlbmFudHModHJhbnNhY3Rpb25hbFRlbmFudFJlZ2lzdHJhdGlvbnMpXG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICBsaWZlY3ljbGVFcnJvcnMucHVzaChlcnJvcilcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodGVzdFNoYXJlZENvbm5lY3Rpb25zQWN0aXZlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICB0ZXN0UnVubmVyLmNsZWFyVGVzdFNoYXJlZENvbm5lY3Rpb25zKHRlc3RTaGFyZWRDb25uZWN0aW9uUmVnaXN0cmF0aW9ucylcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGxpZmVjeWNsZUVycm9ycy5wdXNoKGVycm9yKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGVzdFNoYXJlZENvbm5lY3Rpb25zQWN0aXZlID0gZmFsc2VcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAobGlmZWN5Y2xlRXJyb3JzLmxlbmd0aCA9PSAxKSB0aHJvdyBsaWZlY3ljbGVFcnJvcnNbMF1cbiAgICAgICAgICBpZiAobGlmZWN5Y2xlRXJyb3JzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBZ2dyZWdhdGVFcnJvcihsaWZlY3ljbGVFcnJvcnMsIFwiVGVzdCBsaWZlY3ljbGUgYW5kIGNsZWFudXAgZmFpbGVkXCIsIHtjYXVzZTogbGlmZWN5Y2xlRXJyb3JzWzBdfSlcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodXNlVGVzdENvbm5lY3Rpb25zKSB7XG4gICAgICAgICAgYXdhaXQgdGVzdFJ1bm5lci5nZXRDb25maWd1cmF0aW9uKCkuZW5zdXJlQ29ubmVjdGlvbnMoe25hbWU6IGBUZXN0OiAke3Rlc3REZXNjcmlwdGlvbn1gfSwgcnVuVGVzdEF0dGVtcHQpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYXdhaXQgcnVuVGVzdEF0dGVtcHQoKVxuICAgICAgICB9XG4gICAgICB9LCBicm93c2VyRHVtbXlDb25uZWN0aW9uUmVnaXN0cmF0aW9ucylcbiAgICAgIGNvbnN0IGxpZmVjeWNsZUNhbGxiYWNrID0gYXN5bmMgKCkgPT4gYXdhaXQgdGVzdFJ1bm5lci5nZXRDb25maWd1cmF0aW9uKCkucnVuV2l0aFRlc3REYXRhYmFzZUFjY2Vzc1Njb3BlKHRlc3REYXRhYmFzZUFjY2Vzc1Njb3BlLCBydW5MaWZlY3ljbGVDYWxsYmFjaylcbiAgICAgIHRlc3RMaWZlY3ljbGUgPSBwcm9maWxlQXR0ZW1wdCAmJiBwcm9maWxlclxuICAgICAgICA/IHByb2ZpbGVyLnJ1bkF0dGVtcHQocHJvZmlsZUF0dGVtcHQsIGxpZmVjeWNsZUNhbGxiYWNrKVxuICAgICAgICA6IGxpZmVjeWNsZUNhbGxiYWNrKClcblxuICAgICAgaWYgKGVmZmVjdGl2ZVRpbWVvdXRNcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGF3YWl0IHJ1bldpdGhUaW1lb3V0KHRlc3RMaWZlY3ljbGUsIGVmZmVjdGl2ZVRpbWVvdXRNcywgdGVzdERlc2NyaXB0aW9uKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXdhaXQgdGVzdExpZmVjeWNsZVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBmYWlsZWQgPSB0cnVlXG4gICAgICBjYXVnaHRFcnJvciA9IGVycm9yXG4gICAgICBjb25zdCB0aW1lZE91dCA9IEJvb2xlYW4oLyoqIEB0eXBlIHtUZXN0VGltZW91dEVycm9yfSAqLyAoZXJyb3IpPy52ZWxvY2lvdXNUZXN0VGltZW91dClcbiAgICAgIGF0dGVtcHRUaW1lZE91dCA9IHRpbWVkT3V0XG5cbiAgICAgIGlmICh0aW1lZE91dCAmJiB0ZXN0TGlmZWN5Y2xlKSB7XG4gICAgICAgIGNvbnN0IGVtZXJnZW5jeUNsZWFudXBFcnJvcnMgPSBbXVxuXG4gICAgICAgIGlmIChwcm9maWxlQXR0ZW1wdCAmJiBwcm9maWxlcikgcHJvZmlsZXIuZmluaXNoQXR0ZW1wdChwcm9maWxlQXR0ZW1wdCwgXCJ0aW1lZC1vdXRcIilcbiAgICAgICAgY29uc3QgbGlmZWN5Y2xlT3V0Y29tZSA9IGF3YWl0IGF3YWl0U2V0dGxlZE9yR3JhY2UodGVzdExpZmVjeWNsZSwgZWZmZWN0aXZlVGltZW91dE1zID8/IDYwMDAwKVxuXG4gICAgICAgIGlmIChsaWZlY3ljbGVPdXRjb21lLnNldHRsZWQgJiYgbGlmZWN5Y2xlT3V0Y29tZS5zdGF0dXMgPT09IFwicmVqZWN0ZWRcIikge1xuICAgICAgICAgIGVtZXJnZW5jeUNsZWFudXBFcnJvcnMucHVzaChsaWZlY3ljbGVPdXRjb21lLnJlYXNvbilcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghbGlmZWN5Y2xlT3V0Y29tZS5zZXR0bGVkKSB7XG4gICAgICAgICAgdGVzdERhdGFiYXNlQWNjZXNzU2NvcGUucmV2b2tlZCA9IHRydWVcbiAgICAgICAgICB2b2lkIHRlc3RMaWZlY3ljbGUuY2F0Y2goKGNsZWFudXBFcnJvcikgPT4ge1xuICAgICAgICAgICAgaWYgKGlzVGVzdERhdGFiYXNlQWNjZXNzUmV2b2NhdGlvbihjbGVhbnVwRXJyb3IpKSByZXR1cm5cbiAgICAgICAgICAgIHRlc3RSdW5uZXIucmVjb3JkVGltZW91dENsZWFudXBGYWlsdXJlKGNsZWFudXBFcnJvciwgXCJ0ZXN0IGxpZmVjeWNsZVwiLCByZWNvcmRlZFRpbWVvdXRDbGVhbnVwRXJyb3JzKVxuICAgICAgICAgIH0pXG4gICAgICAgICAgY29uc3QgcXVhcmFudGluZSA9IHRlc3RSdW5uZXIucXVhcmFudGluZUJyb3dzZXJEdW1teUNvbm5lY3Rpb25zKGJyb3dzZXJEdW1teUNvbm5lY3Rpb25SZWdpc3RyYXRpb25zKVxuICAgICAgICAgIGNvbnN0IHF1YXJhbnRpbmVPdXRjb21lID0gYXdhaXQgYXdhaXRTZXR0bGVkT3JHcmFjZShxdWFyYW50aW5lLCBlZmZlY3RpdmVUaW1lb3V0TXMgPz8gNjAwMDApXG4gICAgICAgICAgY29uc3QgdXNlc0Jyb3dzZXJUcmFuc2FjdGlvbnMgPSB0ZXN0QXJncy5kYXRhYmFzZUNsZWFuaW5nPy50cmFuc2FjdGlvbiA9PT0gdHJ1ZVxuICAgICAgICAgIGNvbnN0IHVzZXNCcm93c2VyVHJ1bmNhdGlvbiA9IHRlc3RBcmdzLmRhdGFiYXNlQ2xlYW5pbmc/LnRydW5jYXRlID8/ICF1c2VzQnJvd3NlclRyYW5zYWN0aW9uc1xuXG4gICAgICAgICAgYWJvcnRSZW1haW5pbmdUZXN0cyA9IHRlc3RSdW5uZXIuaXNCcm93c2VyVGVzdE1vZGUoKVxuICAgICAgICAgICAgJiYgdGVzdFJ1bm5lci5oYXNUYWcodGVzdEFyZ3MsIFwiZHVtbXlcIilcbiAgICAgICAgICAgICYmICh1c2VzQnJvd3NlclRyYW5zYWN0aW9ucyB8fCB1c2VzQnJvd3NlclRydW5jYXRpb24pXG5cbiAgICAgICAgICBpZiAocXVhcmFudGluZU91dGNvbWUuc2V0dGxlZCAmJiBxdWFyYW50aW5lT3V0Y29tZS5zdGF0dXMgPT09IFwicmVqZWN0ZWRcIikge1xuICAgICAgICAgICAgZW1lcmdlbmN5Q2xlYW51cEVycm9ycy5wdXNoKHF1YXJhbnRpbmVPdXRjb21lLnJlYXNvbilcbiAgICAgICAgICB9IGVsc2UgaWYgKCFxdWFyYW50aW5lT3V0Y29tZS5zZXR0bGVkKSB7XG4gICAgICAgICAgICB2b2lkIHF1YXJhbnRpbmUuY2F0Y2goKGNsZWFudXBFcnJvcikgPT4ge1xuICAgICAgICAgICAgICB0ZXN0UnVubmVyLnJlY29yZFRpbWVvdXRDbGVhbnVwRmFpbHVyZShjbGVhbnVwRXJyb3IsIFwiYnJvd3NlciBkdW1teSBjb25uZWN0aW9uIHF1YXJhbnRpbmVcIiwgcmVjb3JkZWRUaW1lb3V0Q2xlYW51cEVycm9ycylcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpZiAodGVzdFNoYXJlZENvbm5lY3Rpb25zQWN0aXZlKSB7XG4gICAgICAgICAgICB0ZXN0UnVubmVyLmNsZWFyVGVzdFNoYXJlZENvbm5lY3Rpb25zKHRlc3RTaGFyZWRDb25uZWN0aW9uUmVnaXN0cmF0aW9ucylcbiAgICAgICAgICAgIHRlc3RTaGFyZWRDb25uZWN0aW9uUmVnaXN0cmF0aW9ucyA9IFtdXG4gICAgICAgICAgICB0ZXN0U2hhcmVkQ29ubmVjdGlvbnNBY3RpdmUgPSBmYWxzZVxuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoY2xlYW51cEVycm9yKSB7XG4gICAgICAgICAgZW1lcmdlbmN5Q2xlYW51cEVycm9ycy5wdXNoKGNsZWFudXBFcnJvcilcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGJyb2tlckNsZWFudXAgPSB0ZXN0UnVubmVyLnN0b3BTaGFyZWRUcmFuc2FjdGlvbkJyb2tlcihzaGFyZWRUcmFuc2FjdGlvbkJyb2tlclJlZ2lzdHJhdGlvbiB8fCBzaGFyZWRUcmFuc2FjdGlvbkJyb2tlclByZXBhcmF0aW9uKVxuICAgICAgICBjb25zdCBicm9rZXJDbGVhbnVwT3V0Y29tZSA9IGF3YWl0IGF3YWl0U2V0dGxlZE9yR3JhY2UoYnJva2VyQ2xlYW51cCwgZWZmZWN0aXZlVGltZW91dE1zID8/IDYwMDAwKVxuXG4gICAgICAgIGlmIChicm9rZXJDbGVhbnVwT3V0Y29tZS5zZXR0bGVkICYmIGJyb2tlckNsZWFudXBPdXRjb21lLnN0YXR1cyA9PT0gXCJyZWplY3RlZFwiKSB7XG4gICAgICAgICAgZW1lcmdlbmN5Q2xlYW51cEVycm9ycy5wdXNoKGJyb2tlckNsZWFudXBPdXRjb21lLnJlYXNvbilcbiAgICAgICAgfSBlbHNlIGlmICghYnJva2VyQ2xlYW51cE91dGNvbWUuc2V0dGxlZCkge1xuICAgICAgICAgIHZvaWQgYnJva2VyQ2xlYW51cC5jYXRjaCgoY2xlYW51cEVycm9yKSA9PiB7XG4gICAgICAgICAgICB0ZXN0UnVubmVyLnJlY29yZFRpbWVvdXRDbGVhbnVwRmFpbHVyZShjbGVhbnVwRXJyb3IsIFwic2hhcmVkIHRyYW5zYWN0aW9uIGJyb2tlclwiLCByZWNvcmRlZFRpbWVvdXRDbGVhbnVwRXJyb3JzKVxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgc2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJSZWdpc3RyYXRpb24gPSB1bmRlZmluZWRcbiAgICAgICAgc2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJQcmVwYXJhdGlvbiA9IHVuZGVmaW5lZFxuICAgICAgICBjb25zdCBlbWVyZ2VuY3lDbGVhbnVwID0gdGVzdFJ1bm5lci5jbGVhbnVwVHJhbnNhY3Rpb25hbFRlbmFudHModHJhbnNhY3Rpb25hbFRlbmFudFJlZ2lzdHJhdGlvbnMsIHtkaXNjYXJkOiB0cnVlfSlcbiAgICAgICAgY29uc3QgZW1lcmdlbmN5Q2xlYW51cE91dGNvbWUgPSBhd2FpdCBhd2FpdFNldHRsZWRPckdyYWNlKGVtZXJnZW5jeUNsZWFudXAsIGVmZmVjdGl2ZVRpbWVvdXRNcyA/PyA2MDAwMClcblxuICAgICAgICBpZiAoZW1lcmdlbmN5Q2xlYW51cE91dGNvbWUuc2V0dGxlZCAmJiBlbWVyZ2VuY3lDbGVhbnVwT3V0Y29tZS5zdGF0dXMgPT09IFwicmVqZWN0ZWRcIikge1xuICAgICAgICAgIGVtZXJnZW5jeUNsZWFudXBFcnJvcnMucHVzaChlbWVyZ2VuY3lDbGVhbnVwT3V0Y29tZS5yZWFzb24pXG4gICAgICAgIH0gZWxzZSBpZiAoIWVtZXJnZW5jeUNsZWFudXBPdXRjb21lLnNldHRsZWQpIHtcbiAgICAgICAgICB2b2lkIGVtZXJnZW5jeUNsZWFudXAuY2F0Y2goKGNsZWFudXBFcnJvcikgPT4ge1xuICAgICAgICAgICAgdGVzdFJ1bm5lci5yZWNvcmRUaW1lb3V0Q2xlYW51cEZhaWx1cmUoY2xlYW51cEVycm9yLCBcInRyYW5zYWN0aW9uYWwgdGVuYW50XCIsIHJlY29yZGVkVGltZW91dENsZWFudXBFcnJvcnMpXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbWVyZ2VuY3lDbGVhbnVwRXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBjYXVnaHRFcnJvciA9IG5ldyBBZ2dyZWdhdGVFcnJvcihcbiAgICAgICAgICAgIFtjYXVnaHRFcnJvciwgLi4uZW1lcmdlbmN5Q2xlYW51cEVycm9yc10sXG4gICAgICAgICAgICBcIlRlc3QgdGltZW91dCBhbmQgZW1lcmdlbmN5IGNsZWFudXAgZmFpbGVkXCIsXG4gICAgICAgICAgICB7Y2F1c2U6IGNhdWdodEVycm9yfVxuICAgICAgICAgIClcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoYnJvd3NlckR1bW15Q29ubmVjdGlvblJlZ2lzdHJhdGlvbnMuc29tZSgocmVnaXN0cmF0aW9uKSA9PiByZWdpc3RyYXRpb24ucXVhcmFudGluZWQpKSB7XG4gICAgICAgIHRlc3REYXRhYmFzZUFjY2Vzc1Njb3BlLnJldm9rZWQgPSB0cnVlXG4gICAgICAgIGFib3J0UmVtYWluaW5nVGVzdHMgPSB0cnVlXG4gICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRlc3REYXRhYmFzZUFjY2Vzc1Njb3BlLnJldm9rZWQgPSB0cnVlXG5cbiAgICAgIGlmIChwcm9maWxlQXR0ZW1wdCAmJiBwcm9maWxlcikge1xuICAgICAgICBwcm9maWxlci5maW5pc2hBdHRlbXB0KHByb2ZpbGVBdHRlbXB0LCBmYWlsZWRcbiAgICAgICAgICA/IChhdHRlbXB0VGltZWRPdXQgPyBcInRpbWVkLW91dFwiIDogXCJmYWlsZWRcIilcbiAgICAgICAgICA6IFwicGFzc2VkXCIpXG4gICAgICB9XG4gICAgfVxuXG4gICAgdGVzdFJ1bm5lci5yZWNvcmRBdHRlbXB0T3V0Y29tZSh0ZXN0LCBhdHRlbXB0TnVtYmVyLCB7XG4gICAgICBhYm9ydFJlbWFpbmluZ1Rlc3RzLFxuICAgICAgZXJyb3I6IGNhdWdodEVycm9yLFxuICAgICAgZmFpbGVkXG4gICAgfSlcblxuICAgIGlmIChmYWlsZWQpIHRocm93IGNhdWdodEVycm9yXG4gIH1cblxuICAvKipcbiAgICogUnVucyBiZWZvcmUtZWFjaCBob29rcyBpbiBpbmhlcml0ZWQgZGVjbGFyYXRpb24gb3JkZXIuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gSG9vayBhcmd1bWVudHMuXG4gICAqIEBwYXJhbSB7UGFja2FnZUhvb2tEZWNsYXJhdGlvbltdfSBhcmdzLmJlZm9yZUVhY2hlcyAtIFNldHVwIGhvb2tzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdmVsb2Npb3VzLXRlc3QtYXJndW1lbnRzLmpzXCIpLlRlc3RBcmdzfSBhcmdzLnRlc3RBcmdzIC0gU3RhYmxlIHRlc3QgYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdmVsb2Npb3VzLXRlc3QtYXJndW1lbnRzLmpzXCIpLlRlc3REYXRhfSBhcmdzLnRlc3REYXRhIC0gVGVzdCByZWdpc3RyYXRpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIGFmdGVyIGFsbCBzZXR1cCBob29rcyBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHJ1bkJlZm9yZUVhY2hlcyh7YmVmb3JlRWFjaGVzLCB0ZXN0QXJncywgdGVzdERhdGF9KSB7XG4gICAgZm9yIChjb25zdCBob29rIG9mIGJlZm9yZUVhY2hlcykge1xuICAgICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLnRlc3RSdW5uZXIuaG9va01ldGFkYXRhKGhvb2spXG5cbiAgICAgIGF3YWl0IHRoaXMudGVzdFJ1bm5lci5ydW5Qcm9maWxlU3Bhbih7XG4gICAgICAgIHBoYXNlOiBcImJlZm9yZUVhY2hcIixcbiAgICAgICAgZGVjbGFyYXRpb25JbmRleDogbWV0YWRhdGEuZGVjbGFyYXRpb25JbmRleCxcbiAgICAgICAgZGVjbGFyYXRpb25TY29wZUlkOiBtZXRhZGF0YS5kZWNsYXJhdGlvblNjb3BlSWQsXG4gICAgICAgIGZpbGVQYXRoOiBtZXRhZGF0YS5vd25lckZpbGVQYXRoXG4gICAgICB9LCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IGhvb2suY2FsbGJhY2soe2NvbmZpZ3VyYXRpb246IHRoaXMudGVzdFJ1bm5lci5nZXRDb25maWd1cmF0aW9uKCksIHRlc3RBcmdzLCB0ZXN0RGF0YX0pXG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGV2ZXJ5IGFmdGVyLWVhY2ggaG9vayB3aGlsZSBwcmVzZXJ2aW5nIGFsbCBmYWlsdXJlcy5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBIb29rIGFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHtQYWNrYWdlSG9va0RlY2xhcmF0aW9uW119IGFyZ3MuYWZ0ZXJFYWNoZXMgLSBDbGVhbnVwIGhvb2tzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdmVsb2Npb3VzLXRlc3QtYXJndW1lbnRzLmpzXCIpLlRlc3RBcmdzfSBhcmdzLnRlc3RBcmdzIC0gU3RhYmxlIHRlc3QgYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdmVsb2Npb3VzLXRlc3QtYXJndW1lbnRzLmpzXCIpLlRlc3REYXRhfSBhcmdzLnRlc3REYXRhIC0gVGVzdCByZWdpc3RyYXRpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIGFmdGVyIGV2ZXJ5IGNsZWFudXAgaG9vayBzZXR0bGVzLlxuICAgKi9cbiAgYXN5bmMgcnVuQWZ0ZXJFYWNoZXMoe2FmdGVyRWFjaGVzLCB0ZXN0QXJncywgdGVzdERhdGF9KSB7XG4gICAgLyoqIEB0eXBlIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPltdfSAqL1xuICAgIGNvbnN0IGVycm9ycyA9IFtdXG5cbiAgICBmb3IgKGNvbnN0IGhvb2sgb2YgYWZ0ZXJFYWNoZXMpIHtcbiAgICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy50ZXN0UnVubmVyLmhvb2tNZXRhZGF0YShob29rKVxuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLnRlc3RSdW5uZXIucnVuUHJvZmlsZVNwYW4oe1xuICAgICAgICAgIHBoYXNlOiBcImFmdGVyRWFjaFwiLFxuICAgICAgICAgIGRlY2xhcmF0aW9uSW5kZXg6IG1ldGFkYXRhLmRlY2xhcmF0aW9uSW5kZXgsXG4gICAgICAgICAgZGVjbGFyYXRpb25TY29wZUlkOiBtZXRhZGF0YS5kZWNsYXJhdGlvblNjb3BlSWQsXG4gICAgICAgICAgZmlsZVBhdGg6IG1ldGFkYXRhLm93bmVyRmlsZVBhdGhcbiAgICAgICAgfSwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGF3YWl0IGhvb2suY2FsbGJhY2soe2NvbmZpZ3VyYXRpb246IHRoaXMudGVzdFJ1bm5lci5nZXRDb25maWd1cmF0aW9uKCksIHRlc3RBcmdzLCB0ZXN0RGF0YX0pXG4gICAgICAgIH0pXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBlcnJvcnMucHVzaChlcnJvcilcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZXJyb3JzLmxlbmd0aCA9PSAxKSB0aHJvdyBlcnJvcnNbMF1cbiAgICBpZiAoZXJyb3JzLmxlbmd0aCA+IDEpIHtcbiAgICAgIHRocm93IG5ldyBBZ2dyZWdhdGVFcnJvcihlcnJvcnMsIFwiTXVsdGlwbGUgYWZ0ZXJFYWNoIGhvb2tzIGZhaWxlZFwiLCB7Y2F1c2U6IGVycm9yc1swXX0pXG4gICAgfVxuICB9XG59XG4iXX0=
@@ -1,5 +1,14 @@
1
+ export type PackageTestDeclaration = import("@velocious/testing/runner").TestDeclaration;
2
+ /** @typedef {import("@velocious/testing/runner").TestDeclaration} PackageTestDeclaration */
3
+ /** Stops package traversal after framework-owned connection quarantine. */
4
+ export declare class AbortRemainingTestsError extends Error {
5
+ }
1
6
  export default class VelociousRunnerReporter {
2
7
  testRunner: import("./test-runner.js").default;
8
+ /** @type {WeakMap<PackageTestDeclaration, import("./test-runner.js").AttemptConsoleOutput[]>} */
9
+ attemptConsoleOutputs: WeakMap<PackageTestDeclaration, import("./test-runner.js").AttemptConsoleOutput[]>;
10
+ /** @type {PackageTestDeclaration | undefined} */
11
+ activeTest: PackageTestDeclaration | undefined;
3
12
  /**
4
13
  * Creates the legacy event and result projection adapter.
5
14
  * @param {object} args - Constructor arguments.
@@ -9,37 +18,23 @@ export default class VelociousRunnerReporter {
9
18
  testRunner: import("./test-runner.js").default;
10
19
  });
11
20
  /**
12
- * Projects one completed attempt into legacy events and final result accounting.
13
- * Retry eligibility is decided by the caller before this method runs.
14
- * @param {object} args - Completed attempt and retry metadata.
15
- * @param {import("./test-runner.js").AttemptConsoleOutput[]} args.attemptConsoleOutputs - Captured output across attempts.
16
- * @param {number} args.attemptNumber - Current one-based attempt.
17
- * @param {string[]} args.descriptions - Parent description stack.
18
- * @param {ReturnType<typeof JSON.parse>} args.error - Raw thrown or rejected value.
19
- * @param {boolean} args.failed - Whether the attempt failed, independently of error truthiness.
20
- * @param {string} args.leftPadding - Console indentation.
21
- * @param {number} args.retriesUsed - Retry count consumed after this attempt.
22
- * @param {number} args.retryCount - Configured retry limit.
23
- * @param {import("./velocious-test-arguments.js").TestArgs} args.testArgs - Stable test arguments.
24
- * @param {import("./velocious-test-arguments.js").TestData} args.testData - Test registration.
25
- * @param {string} args.testDescription - Test description.
26
- * @param {boolean} args.willRetry - Whether the legacy loop will run another attempt.
27
- * @returns {Promise<void>} - Resolves after all legacy listeners complete.
21
+ * Translates one awaited package runner event into the legacy contract.
22
+ * @param {import("@velocious/testing/runner").RunnerEvent} event - Structured package event.
23
+ * @returns {Promise<void>} - Resolves after legacy listeners finish.
28
24
  */
29
- reportAttempt({ attemptConsoleOutputs, attemptNumber, descriptions, error, failed, leftPadding, retriesUsed, retryCount, testArgs, testData, testDescription, willRetry, ...restArgs }: {
30
- attemptConsoleOutputs: import("./test-runner.js").AttemptConsoleOutput[];
31
- attemptNumber: number;
32
- descriptions: string[];
33
- error: ReturnType<typeof JSON.parse>;
34
- failed: boolean;
35
- leftPadding: string;
36
- retriesUsed: number;
37
- retryCount: number;
38
- testArgs: import("./velocious-test-arguments.js").TestArgs;
39
- testData: import("./velocious-test-arguments.js").TestData;
40
- testDescription: string;
41
- willRetry: boolean;
42
- }): Promise<void>;
25
+ onEvent(event: import("@velocious/testing/runner").RunnerEvent): Promise<void>;
26
+ /**
27
+ * Projects attempt failure/retry events while retaining the raw thrown value.
28
+ * @param {import("@velocious/testing/runner").RunnerEvent} event - Attempt event.
29
+ * @returns {Promise<void>} - Resolves after listeners finish.
30
+ */
31
+ reportAttemptEvent(event: import("@velocious/testing/runner").RunnerEvent): Promise<void>;
32
+ /**
33
+ * Projects final package result accounting and failures.
34
+ * @param {import("@velocious/testing/runner").RunnerEvent} event - Test result event.
35
+ * @returns {Promise<void>} - Resolves after listeners finish.
36
+ */
37
+ reportTestEvent(event: import("@velocious/testing/runner").RunnerEvent): Promise<void>;
43
38
  /**
44
39
  * Records and emits one final failed test result.
45
40
  * @param {object} args - Final failure metadata.
@@ -47,8 +42,8 @@ export default class VelociousRunnerReporter {
47
42
  * @param {string[]} args.descriptions - Parent description stack.
48
43
  * @param {ReturnType<typeof JSON.parse>} args.error - Raw final failure.
49
44
  * @param {string} args.leftPadding - Console indentation.
50
- * @param {import("./velocious-test-arguments.js").TestArgs} args.testArgs - Stable test arguments.
51
- * @param {import("./velocious-test-arguments.js").TestData} args.testData - Test registration.
45
+ * @param {import("./test-runner.js").TestArgs} args.testArgs - Stable test arguments.
46
+ * @param {import("./test-runner.js").TestData} args.testData - Test registration.
52
47
  * @param {string} args.testDescription - Test description.
53
48
  * @returns {Promise<void>} - Resolves after the final-failure listener completes.
54
49
  */
@@ -57,8 +52,8 @@ export default class VelociousRunnerReporter {
57
52
  descriptions: string[];
58
53
  error: ReturnType<typeof JSON.parse>;
59
54
  leftPadding: string;
60
- testArgs: import("./velocious-test-arguments.js").TestArgs;
61
- testData: import("./velocious-test-arguments.js").TestData;
55
+ testArgs: import("./test-runner.js").TestArgs;
56
+ testData: import("./test-runner.js").TestData;
62
57
  testDescription: string;
63
58
  }): Promise<void>;
64
59
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"velocious-runner-reporter.d.ts","sourceRoot":"","sources":["../../../src/testing/velocious-runner-reporter.js"],"names":[],"mappings":"AAQA,MAAM,CAAC,OAAO,OAAO,uBAAuB;IAQnC,UAAU;IAPjB;;;;OAIG;IACH,YAAY,EAAC,UAAU,EAAE,GAAG,QAAQ,EAAC,EAFlC;QAAiD,UAAU,EAAnD,OAAO,kBAAkB,EAAE,OAAO,CAC5C;KACoC,EAGpC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACG,aAAa,CAAC,EAAC,qBAAqB,EAAE,aAAa,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,EAAE,GAAG,QAAQ,EAAC,EAdvL;QAAgE,qBAAqB,EAA7E,OAAO,kBAAkB,EAAE,oBAAoB,EAAE,CACzD;QAAqB,aAAa,EAA1B,MAAM,CACd;QAAuB,YAAY,EAA3B,MAAM,EAAE,CAChB;QAA4C,KAAK,EAAzC,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CACrC;QAAsB,MAAM,EAApB,OAAO,CACf;QAAqB,WAAW,EAAxB,MAAM,CACd;QAAqB,WAAW,EAAxB,MAAM,CACd;QAAqB,UAAU,EAAvB,MAAM,CACd;QAA+D,QAAQ,EAA/D,OAAO,+BAA+B,EAAE,QAAQ,CACxD;QAA+D,QAAQ,EAA/D,OAAO,+BAA+B,EAAE,QAAQ,CACxD;QAAqB,eAAe,EAA5B,MAAM,CACd;QAAsB,SAAS,EAAvB,OAAO,CACf;KAEuL,GAF7K,OAAO,CAAC,IAAI,CAAC,CA2DzB;IAED;;;;;;;;;;;OAWG;IACG,gBAAgB,CAAC,EAAC,qBAAqB,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAC,EATlH;QAAgE,qBAAqB,EAA7E,OAAO,kBAAkB,EAAE,oBAAoB,EAAE,CACzD;QAAuB,YAAY,EAA3B,MAAM,EAAE,CAChB;QAA4C,KAAK,EAAzC,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CACrC;QAAqB,WAAW,EAAxB,MAAM,CACd;QAA+D,QAAQ,EAA/D,OAAO,+BAA+B,EAAE,QAAQ,CACxD;QAA+D,QAAQ,EAA/D,OAAO,+BAA+B,EAAE,QAAQ,CACxD;QAAqB,eAAe,EAA5B,MAAM,CACd;KAEkH,GAFxG,OAAO,CAAC,IAAI,CAAC,CA4CzB;IAED;;;;;OAKG;IACG,SAAS,CAAC,SAAS,EAJd,MAIc,EAAE,OAAO,EAHvB,MAGuB,GAFrB,OAAO,CAAC,IAAI,CAAC,CAQzB;CACF"}
1
+ {"version":3,"file":"velocious-runner-reporter.d.ts","sourceRoot":"","sources":["../../../src/testing/velocious-runner-reporter.js"],"names":[],"mappings":"AAQI,YAA+D,sBAAsB,GAA3E,OAAO,2BAA2B,EAAE,eAAe,CAAwB;AAAzF,4FAA4F;AAE5F,2EAA2E;AAC3E,qBAAa,wBAAyB,SAAQ,KAAK;CAAG;AAEtD,MAAM,CAAC,OAAO,OAAO,uBAAuB;IAQnC,UAAU;IACf,iGAAiG;IAC5F,qBAAqB,EADf,OAAO,CAAC,sBAAsB,EAAE,OAAO,kBAAkB,EAAE,oBAAoB,EAAE,CAAC;IAE7F,iDAAiD;IAC5C,UAAU,EADJ,sBAAsB,GAAG,SAAS;IAV/C;;;;OAIG;IACH,YAAY,EAAC,UAAU,EAAE,GAAG,QAAQ,EAAC,EAFlC;QAAiD,UAAU,EAAnD,OAAO,kBAAkB,EAAE,OAAO,CAC5C;KACoC,EAOpC;IAED;;;;OAIG;IACG,OAAO,CAAC,KAAK,EAHR,OAAO,2BAA2B,EAAE,WAG5B,GAFN,OAAO,CAAC,IAAI,CAAC,CAuBzB;IAED;;;;OAIG;IACG,kBAAkB,CAAC,KAAK,EAHnB,OAAO,2BAA2B,EAAE,WAGjB,GAFjB,OAAO,CAAC,IAAI,CAAC,CA+FzB;IAED;;;;OAIG;IACG,eAAe,CAAC,KAAK,EAHhB,OAAO,2BAA2B,EAAE,WAGpB,GAFd,OAAO,CAAC,IAAI,CAAC,CA8CzB;IAED;;;;;;;;;;;OAWG;IACG,gBAAgB,CAAC,EAAC,qBAAqB,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAC,EATlH;QAAgE,qBAAqB,EAA7E,OAAO,kBAAkB,EAAE,oBAAoB,EAAE,CACzD;QAAuB,YAAY,EAA3B,MAAM,EAAE,CAChB;QAA4C,KAAK,EAAzC,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CACrC;QAAqB,WAAW,EAAxB,MAAM,CACd;QAAkD,QAAQ,EAAlD,OAAO,kBAAkB,EAAE,QAAQ,CAC3C;QAAkD,QAAQ,EAAlD,OAAO,kBAAkB,EAAE,QAAQ,CAC3C;QAAqB,eAAe,EAA5B,MAAM,CACd;KAEkH,GAFxG,OAAO,CAAC,IAAI,CAAC,CAmCzB;IAED;;;;;OAKG;IACG,SAAS,CAAC,SAAS,EAJd,MAIc,EAAE,OAAO,EAHvB,MAGuB,GAFrB,OAAO,CAAC,IAAI,CAAC,CAIzB;CACF"}