testcafe 1.14.1 → 1.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (332) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/LICENSE +21 -21
  3. package/bin/testcafe-with-v8-flag-filter.js +0 -0
  4. package/lib/api/exportable-lib/index.js +49 -49
  5. package/lib/api/request-hooks/assert-type.js +7 -7
  6. package/lib/api/request-hooks/hook-method-names.js +9 -9
  7. package/lib/api/request-hooks/hook.js +32 -32
  8. package/lib/api/request-hooks/interfaces.js +2 -2
  9. package/lib/api/request-hooks/request-logger.js +112 -112
  10. package/lib/api/request-hooks/request-mock/create-request-mock.js +10 -10
  11. package/lib/api/request-hooks/request-mock/index.js +44 -44
  12. package/lib/api/request-hooks/request-mock.js +46 -46
  13. package/lib/api/structure/base-unit.js +11 -11
  14. package/lib/api/structure/fixture.js +75 -75
  15. package/lib/api/structure/interfaces.js +2 -2
  16. package/lib/api/structure/test-file.js +31 -31
  17. package/lib/api/structure/test-timeout.js +9 -9
  18. package/lib/api/structure/test.js +85 -85
  19. package/lib/api/structure/testing-unit.js +89 -89
  20. package/lib/api/structure/unit-type.js +9 -9
  21. package/lib/api/test-controller/assertion.js +88 -88
  22. package/lib/api/test-controller/execution-context.js +82 -82
  23. package/lib/api/test-controller/index.js +358 -358
  24. package/lib/api/test-controller/proxy.js +28 -28
  25. package/lib/api/test-page-url.js +60 -60
  26. package/lib/api/test-run-tracker.js +68 -68
  27. package/lib/api/wrap-test-function.js +49 -49
  28. package/lib/assertions/executor.js +74 -74
  29. package/lib/assertions/get-fn.js +46 -46
  30. package/lib/assertions/type.js +20 -20
  31. package/lib/assets/content-types.js +9 -9
  32. package/lib/assets/injectables.js +18 -18
  33. package/lib/browser/connection/command.js +10 -10
  34. package/lib/browser/connection/error-hints.js +9 -9
  35. package/lib/browser/connection/gateway.js +159 -159
  36. package/lib/browser/connection/get-hints.js +33 -33
  37. package/lib/browser/connection/heartbeat-status.js +8 -8
  38. package/lib/browser/connection/index.js +328 -328
  39. package/lib/browser/connection/remotes-queue.js +46 -46
  40. package/lib/browser/connection/service-routes.js +12 -12
  41. package/lib/browser/connection/status.js +12 -12
  42. package/lib/browser/interfaces.js +2 -2
  43. package/lib/browser/provider/built-in/dedicated/base.js +80 -80
  44. package/lib/browser/provider/built-in/dedicated/chrome/browser-client.js +204 -204
  45. package/lib/browser/provider/built-in/dedicated/chrome/build-chrome-args.js +17 -17
  46. package/lib/browser/provider/built-in/dedicated/chrome/config.js +110 -110
  47. package/lib/browser/provider/built-in/dedicated/chrome/create-temp-profile.js +45 -45
  48. package/lib/browser/provider/built-in/dedicated/chrome/elapsed-upperbounds.js +15 -15
  49. package/lib/browser/provider/built-in/dedicated/chrome/index.js +102 -102
  50. package/lib/browser/provider/built-in/dedicated/chrome/interfaces.js +2 -2
  51. package/lib/browser/provider/built-in/dedicated/chrome/local-chrome.js +24 -24
  52. package/lib/browser/provider/built-in/dedicated/chrome/runtime-info.js +29 -29
  53. package/lib/browser/provider/built-in/dedicated/edge/index.js +10 -10
  54. package/lib/browser/provider/built-in/dedicated/edge/runtime-info.js +29 -29
  55. package/lib/browser/provider/built-in/dedicated/firefox/config.js +33 -33
  56. package/lib/browser/provider/built-in/dedicated/firefox/create-temp-profile.js +78 -78
  57. package/lib/browser/provider/built-in/dedicated/firefox/index.js +73 -73
  58. package/lib/browser/provider/built-in/dedicated/firefox/local-firefox.js +36 -36
  59. package/lib/browser/provider/built-in/dedicated/firefox/marionette-client/commands.js +13 -13
  60. package/lib/browser/provider/built-in/dedicated/firefox/marionette-client/index.js +200 -200
  61. package/lib/browser/provider/built-in/dedicated/firefox/runtime-info.js +17 -17
  62. package/lib/browser/provider/built-in/index.js +21 -21
  63. package/lib/browser/provider/built-in/locally-installed.js +30 -30
  64. package/lib/browser/provider/built-in/path.js +47 -47
  65. package/lib/browser/provider/built-in/remote.js +58 -58
  66. package/lib/browser/provider/index.js +303 -303
  67. package/lib/browser/provider/parse-provider-name.js +16 -16
  68. package/lib/browser/provider/plugin-host.js +121 -121
  69. package/lib/browser/provider/pool.js +115 -115
  70. package/lib/browser/provider/utils/argument-parsing.js +74 -74
  71. package/lib/browser/provider/utils/browser-starter.js +34 -34
  72. package/lib/browser/provider/utils/client-functions.js +24 -24
  73. package/lib/browser/provider/utils/get-maximized-headless-window-size.js +9 -9
  74. package/lib/cli/argument-parser.js +284 -284
  75. package/lib/cli/authentication-helper.js +35 -35
  76. package/lib/cli/cli.js +134 -134
  77. package/lib/cli/correct-browsers-and-sources.js +40 -40
  78. package/lib/cli/index.js +19 -19
  79. package/lib/cli/log.js +43 -43
  80. package/lib/cli/remotes-wizard.js +36 -36
  81. package/lib/cli/termination-handler.js +38 -38
  82. package/lib/client/automation/index.js +34 -16
  83. package/lib/client/automation/index.min.js +1 -1
  84. package/lib/client/browser/idle-page/index.html.mustache +35 -35
  85. package/lib/client/browser/idle-page/logo.svg +86 -86
  86. package/lib/client/core/index.js +14 -14
  87. package/lib/client/driver/index.js +46 -16
  88. package/lib/client/driver/index.min.js +1 -1
  89. package/lib/client/driver/internal-properties.js +9 -9
  90. package/lib/client/test-run/iframe.js.mustache +17 -17
  91. package/lib/client/test-run/index.js.mustache +51 -51
  92. package/lib/client/ui/index.js +14 -14
  93. package/lib/client/ui/sprite.svg +42 -42
  94. package/lib/client-functions/builder-symbol.js +4 -4
  95. package/lib/client-functions/client-function-builder.js +155 -155
  96. package/lib/client-functions/replicator.js +61 -61
  97. package/lib/client-functions/return-single-prop-mode.js +8 -8
  98. package/lib/client-functions/selector-api-execution-mode.js +20 -20
  99. package/lib/client-functions/selectors/add-api.js +645 -645
  100. package/lib/client-functions/selectors/create-snapshot-methods.js +13 -13
  101. package/lib/client-functions/selectors/prepare-api-args.js +20 -20
  102. package/lib/client-functions/selectors/selector-attribute-filter.js +22 -22
  103. package/lib/client-functions/selectors/selector-builder.js +153 -153
  104. package/lib/client-functions/selectors/selector-text-filter.js +43 -43
  105. package/lib/client-functions/selectors/snapshot-properties.js +48 -48
  106. package/lib/client-functions/types.js +18 -18
  107. package/lib/compiler/babel/format-babel-produced-code.js +10 -10
  108. package/lib/compiler/babel/get-base-babel-options.js +11 -11
  109. package/lib/compiler/babel/load-libs.js +63 -63
  110. package/lib/compiler/babel/preset-stage-2.js +19 -19
  111. package/lib/compiler/compile-client-function.js +73 -73
  112. package/lib/compiler/compilers.js +33 -33
  113. package/lib/compiler/index.js +92 -92
  114. package/lib/compiler/interfaces.js +2 -2
  115. package/lib/compiler/test-file/api-based.js +146 -146
  116. package/lib/compiler/test-file/base.js +36 -36
  117. package/lib/compiler/test-file/exportble-lib-path.js +5 -5
  118. package/lib/compiler/test-file/formats/coffeescript/compiler.js +38 -38
  119. package/lib/compiler/test-file/formats/coffeescript/get-test-list.js +29 -29
  120. package/lib/compiler/test-file/formats/es-next/compiler.js +42 -42
  121. package/lib/compiler/test-file/formats/es-next/get-test-list.js +166 -166
  122. package/lib/compiler/test-file/formats/es-next/is-flow-code.js +7 -7
  123. package/lib/compiler/test-file/formats/raw.js +85 -85
  124. package/lib/compiler/test-file/formats/typescript/compiler.js +135 -135
  125. package/lib/compiler/test-file/formats/typescript/get-test-list.js +185 -185
  126. package/lib/compiler/test-file/test-file-parser-base.js +214 -214
  127. package/lib/configuration/configuration-base.js +165 -165
  128. package/lib/configuration/constants.js +9 -9
  129. package/lib/configuration/customizable-compilers.js +7 -7
  130. package/lib/configuration/default-values.js +51 -51
  131. package/lib/configuration/interfaces.js +2 -2
  132. package/lib/configuration/option-names.js +53 -53
  133. package/lib/configuration/option-source.js +9 -9
  134. package/lib/configuration/option.js +14 -14
  135. package/lib/configuration/quarantine-option-names.js +8 -8
  136. package/lib/configuration/run-option-names.js +26 -26
  137. package/lib/configuration/screenshot-option-names.js +10 -10
  138. package/lib/configuration/testcafe-configuration.js +163 -163
  139. package/lib/configuration/types.js +2 -2
  140. package/lib/configuration/typescript-configuration.js +62 -62
  141. package/lib/custom-client-scripts/assert-type.js +7 -7
  142. package/lib/custom-client-scripts/client-script-init.js +2 -2
  143. package/lib/custom-client-scripts/client-script.js +106 -106
  144. package/lib/custom-client-scripts/get-code.js +11 -11
  145. package/lib/custom-client-scripts/get-url.js +6 -6
  146. package/lib/custom-client-scripts/load.js +15 -15
  147. package/lib/custom-client-scripts/problematic-scripts.js +2 -2
  148. package/lib/custom-client-scripts/routing.js +36 -36
  149. package/lib/custom-client-scripts/utils.js +60 -60
  150. package/lib/embedding-utils.js +83 -83
  151. package/lib/errors/create-stack-filter.js +18 -18
  152. package/lib/errors/error-list.js +26 -26
  153. package/lib/errors/get-callsite.js +31 -31
  154. package/lib/errors/internal-modules-prefix.js +8 -8
  155. package/lib/errors/is-internal-stack-frame.js +45 -45
  156. package/lib/errors/process-test-fn-error.js +37 -37
  157. package/lib/errors/runtime/index.js +123 -123
  158. package/lib/errors/runtime/templates.js +115 -115
  159. package/lib/errors/runtime/type-assertions.js +112 -112
  160. package/lib/errors/stack-cleaning-hook.js +64 -64
  161. package/lib/errors/test-run/formattable-adapter.js +59 -59
  162. package/lib/errors/test-run/index.js +301 -301
  163. package/lib/errors/test-run/render-error-template.js +31 -31
  164. package/lib/errors/test-run/templates.js +91 -91
  165. package/lib/errors/test-run/utils.js +89 -89
  166. package/lib/errors/types.js +156 -156
  167. package/lib/index.js +81 -81
  168. package/lib/live/bootstrapper.js +43 -43
  169. package/lib/live/controller.js +107 -107
  170. package/lib/live/file-watcher/index.js +67 -67
  171. package/lib/live/file-watcher/modules-graph.js +58 -58
  172. package/lib/live/keyboard-observer.js +76 -76
  173. package/lib/live/logger/index.js +64 -64
  174. package/lib/live/test-run-controller.js +96 -96
  175. package/lib/live/test-run-state.js +6 -6
  176. package/lib/live/test-run.js +56 -56
  177. package/lib/live/test-runner.js +167 -167
  178. package/lib/load-assets.js +29 -29
  179. package/lib/notifications/add-rendered-warning.js +16 -16
  180. package/lib/notifications/debug-logger.js +78 -78
  181. package/lib/notifications/deprecated.js +24 -24
  182. package/lib/notifications/information-message.js +9 -9
  183. package/lib/notifications/warning-log.js +31 -31
  184. package/lib/notifications/warning-message.js +47 -47
  185. package/lib/reporter/command/command-formatter.js +120 -109
  186. package/lib/reporter/command/format-command.js +8 -8
  187. package/lib/reporter/command/interfaces.js +2 -2
  188. package/lib/reporter/index.js +319 -314
  189. package/lib/reporter/interfaces.js +2 -2
  190. package/lib/reporter/plugin-host.js +135 -135
  191. package/lib/reporter/plugin-methods.js +12 -12
  192. package/lib/role/index.js +74 -74
  193. package/lib/role/marker-symbol.js +7 -7
  194. package/lib/role/phase.js +9 -9
  195. package/lib/runner/bootstrapper.js +271 -271
  196. package/lib/runner/browser-job-result.js +9 -9
  197. package/lib/runner/browser-job.js +152 -152
  198. package/lib/runner/browser-set.js +114 -114
  199. package/lib/runner/fixture-hook-controller.js +85 -85
  200. package/lib/runner/index.js +449 -449
  201. package/lib/runner/interfaces.js +2 -2
  202. package/lib/runner/reporter-stream-controller.js +27 -27
  203. package/lib/runner/task/index.js +151 -151
  204. package/lib/runner/task/phase.js +9 -9
  205. package/lib/runner/test-run-controller.js +165 -165
  206. package/lib/runner/tested-app.js +72 -72
  207. package/lib/screenshots/capturer.js +141 -141
  208. package/lib/screenshots/constants.js +11 -11
  209. package/lib/screenshots/crop.js +111 -111
  210. package/lib/screenshots/default-extension.js +4 -4
  211. package/lib/screenshots/index.js +67 -67
  212. package/lib/screenshots/utils.js +39 -39
  213. package/lib/services/compiler/host.js +190 -190
  214. package/lib/services/compiler/io.js +9 -9
  215. package/lib/services/compiler/protocol.js +17 -16
  216. package/lib/services/compiler/service.js +225 -212
  217. package/lib/services/compiler/test-run-proxy.js +111 -111
  218. package/lib/services/interfaces.js +2 -2
  219. package/lib/services/process-title.js +8 -8
  220. package/lib/services/serialization/prepare-options.js +17 -17
  221. package/lib/services/serialization/replicator/create-replicator.js +25 -25
  222. package/lib/services/serialization/replicator/custom-error-transform.js +26 -26
  223. package/lib/services/serialization/test-structure.js +92 -92
  224. package/lib/services/utils/ipc/interfaces.js +30 -30
  225. package/lib/services/utils/ipc/io.js +108 -108
  226. package/lib/services/utils/ipc/message.js +75 -75
  227. package/lib/services/utils/ipc/packet.js +55 -55
  228. package/lib/services/utils/ipc/proxy.js +109 -109
  229. package/lib/services/utils/ipc/transport.js +64 -64
  230. package/lib/shared/errors/index.js +382 -382
  231. package/lib/shared/node-modules-folder-name.js +4 -4
  232. package/lib/test-run/bookmark.js +90 -90
  233. package/lib/test-run/browser-console-messages.js +73 -73
  234. package/lib/test-run/browser-manipulation-queue.js +92 -92
  235. package/lib/test-run/client-messages.js +9 -9
  236. package/lib/test-run/commands/actions.js +486 -483
  237. package/lib/test-run/commands/assertion.js +45 -45
  238. package/lib/test-run/commands/base.js +14 -14
  239. package/lib/test-run/commands/browser-manipulation.js +95 -95
  240. package/lib/test-run/commands/from-object.js +82 -82
  241. package/lib/test-run/commands/observation.js +61 -61
  242. package/lib/test-run/commands/options.js +231 -215
  243. package/lib/test-run/commands/service.js +54 -48
  244. package/lib/test-run/commands/type.js +65 -64
  245. package/lib/test-run/commands/utils.js +87 -87
  246. package/lib/test-run/commands/validations/argument.js +90 -90
  247. package/lib/test-run/commands/validations/factories.js +47 -47
  248. package/lib/test-run/commands/validations/initializers.js +44 -44
  249. package/lib/test-run/debug-log.js +32 -32
  250. package/lib/test-run/execute-js-expression.js +74 -74
  251. package/lib/test-run/index.js +823 -799
  252. package/lib/test-run/marker-symbol.js +7 -7
  253. package/lib/test-run/observed-callsites-storage.js +17 -17
  254. package/lib/test-run/phase.js +16 -16
  255. package/lib/test-run/session-controller.js +104 -104
  256. package/lib/testcafe.js +118 -118
  257. package/lib/utils/assignable.js +39 -39
  258. package/lib/utils/async-event-emitter.js +28 -28
  259. package/lib/utils/async-queue.js +14 -14
  260. package/lib/utils/browser-connection-timeouts.js +19 -19
  261. package/lib/utils/callsite.js +17 -17
  262. package/lib/utils/check-file-path.js +31 -31
  263. package/lib/utils/check-url.js +51 -51
  264. package/lib/utils/convert-to-best-fit-type.js +16 -16
  265. package/lib/utils/correct-file-path.js +21 -21
  266. package/lib/utils/define-lazy-property.js +13 -13
  267. package/lib/utils/delay.js +6 -6
  268. package/lib/utils/delegated-api.js +44 -44
  269. package/lib/utils/detect-display.js +6 -6
  270. package/lib/utils/detect-ffmpeg.js +44 -44
  271. package/lib/utils/diff/colors.js +29 -29
  272. package/lib/utils/diff/index.js +52 -52
  273. package/lib/utils/diff/util.js +23 -23
  274. package/lib/utils/diff.js +29 -29
  275. package/lib/utils/escape-user-agent.js +10 -10
  276. package/lib/utils/flag-list.js +17 -17
  277. package/lib/utils/get-any-key.js +8 -8
  278. package/lib/utils/get-browser.js +8 -8
  279. package/lib/utils/get-common-path.js +34 -34
  280. package/lib/utils/get-filter-fn.js +40 -40
  281. package/lib/utils/get-options/base.js +36 -36
  282. package/lib/utils/get-options/compiler.js +33 -33
  283. package/lib/utils/get-options/grep.js +15 -15
  284. package/lib/utils/get-options/index.js +20 -20
  285. package/lib/utils/get-options/meta.js +22 -22
  286. package/lib/utils/get-options/quarantine.js +91 -91
  287. package/lib/utils/get-options/screenshot.js +17 -17
  288. package/lib/utils/get-options/ssl.js +45 -45
  289. package/lib/utils/get-options/video.js +10 -10
  290. package/lib/utils/get-viewport-width.js +17 -17
  291. package/lib/utils/guard-time-execution.js +10 -10
  292. package/lib/utils/handle-errors.js +74 -74
  293. package/lib/utils/handle-tag-args.js +8 -8
  294. package/lib/utils/http.js +30 -30
  295. package/lib/utils/is-localhost.js +11 -11
  296. package/lib/utils/is-password-input.js +11 -0
  297. package/lib/utils/is-repl.js +10 -10
  298. package/lib/utils/is-window-in-iframe.js +6 -6
  299. package/lib/utils/limit-number.js +10 -10
  300. package/lib/utils/make-reg-exp.js +7 -7
  301. package/lib/utils/moment-loader.js +20 -20
  302. package/lib/utils/parse-file-list.js +71 -71
  303. package/lib/utils/parse-user-agent.js +55 -55
  304. package/lib/utils/path-pattern.js +114 -114
  305. package/lib/utils/prepare-reporters.js +30 -30
  306. package/lib/utils/prerender-callsite.js +18 -18
  307. package/lib/utils/process.js +119 -119
  308. package/lib/utils/promisified-functions.js +46 -46
  309. package/lib/utils/re-executable-promise.js +39 -39
  310. package/lib/utils/render-callsite-sync.js +29 -29
  311. package/lib/utils/render-template.js +9 -9
  312. package/lib/utils/reporter.js +30 -30
  313. package/lib/utils/resolve-path-relatively-cwd.js +7 -7
  314. package/lib/utils/string.js +105 -105
  315. package/lib/utils/temp-directory/cleanup-process/commands.js +7 -7
  316. package/lib/utils/temp-directory/cleanup-process/index.js +143 -143
  317. package/lib/utils/temp-directory/cleanup-process/worker.js +58 -58
  318. package/lib/utils/temp-directory/index.js +87 -87
  319. package/lib/utils/temp-directory/lockfile.js +56 -56
  320. package/lib/utils/thennable.js +7 -7
  321. package/lib/utils/timer.js +15 -15
  322. package/lib/utils/to-posix-path.js +8 -8
  323. package/lib/utils/types.js +2 -2
  324. package/lib/video-recorder/interfaces.js +2 -2
  325. package/lib/video-recorder/process.js +126 -126
  326. package/lib/video-recorder/recorder.js +136 -136
  327. package/lib/video-recorder/test-run-video-recorder.js +69 -69
  328. package/lib/video-recorder/videos.js +37 -37
  329. package/package.json +2 -2
  330. package/ts-defs/index.d.ts +25 -14
  331. package/ts-defs/selectors.d.ts +16 -5
  332. package/ts-defs/testcafe-scripts.d.ts +17 -6
@@ -1,213 +1,226 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const fs_1 = __importDefault(require("fs"));
7
- const compiler_1 = __importDefault(require("../../compiler"));
8
- const test_run_proxy_1 = __importDefault(require("./test-run-proxy"));
9
- const test_structure_1 = require("../serialization/test-structure");
10
- const io_1 = require("./io");
11
- const proxy_1 = require("../utils/ipc/proxy");
12
- const transport_1 = require("../utils/ipc/transport");
13
- const source_map_support_1 = __importDefault(require("source-map-support"));
14
- const protocol_1 = require("./protocol");
15
- const process_title_1 = __importDefault(require("../process-title"));
16
- const hook_method_names_1 = __importDefault(require("../../api/request-hooks/hook-method-names"));
17
- const testcafe_hammerhead_1 = require("testcafe-hammerhead");
18
- source_map_support_1.default.install({
19
- hookRequire: true,
20
- handleUncaughtExceptions: false,
21
- environment: 'node'
22
- });
23
- class CompilerService {
24
- constructor() {
25
- process.title = process_title_1.default.service;
26
- const input = fs_1.default.createReadStream('', { fd: io_1.SERVICE_INPUT_FD });
27
- const output = fs_1.default.createWriteStream('', { fd: io_1.SERVICE_OUTPUT_FD });
28
- this.proxy = new proxy_1.IPCProxy(new transport_1.ServiceTransport(input, output, io_1.SERVICE_SYNC_FD));
29
- this.state = this._initState();
30
- this._setupRoutes();
31
- this.ready();
32
- }
33
- _initState() {
34
- return {
35
- testRuns: {},
36
- fixtureCtxs: {},
37
- units: {},
38
- options: {}
39
- };
40
- }
41
- _getFixtureCtx({ id }) {
42
- const unit = this.state.units[id];
43
- const fixtureId = test_structure_1.isTest(unit) ? unit.fixture.id : unit.id;
44
- if (!this.state.fixtureCtxs[fixtureId])
45
- this.state.fixtureCtxs[fixtureId] = Object.create(null);
46
- return this.state.fixtureCtxs[fixtureId];
47
- }
48
- _getContext(args) {
49
- const { testRunId } = args;
50
- const fixtureCtx = this._getFixtureCtx(args);
51
- if (!testRunId)
52
- return fixtureCtx;
53
- return this.state.testRuns[testRunId];
54
- }
55
- _setupRoutes() {
56
- this.proxy.register([
57
- this.getTests,
58
- this.runTest,
59
- this.cleanUp,
60
- this.setOptions,
61
- this.onRequestHookEvent,
62
- this.setMock,
63
- this.setConfigureResponseEventOptions,
64
- this.setHeaderOnConfigureResponseEvent,
65
- this.removeHeaderOnConfigureResponseEvent,
66
- this.executeRequestFilterRulePredicate,
67
- this.executeMockPredicate,
68
- this.getWarningMessages,
69
- this.addRequestEventListeners,
70
- this.removeRequestEventListeners,
71
- this.initializeTestRunProxy
72
- ], this);
73
- }
74
- _getFunction(unit, functionName) {
75
- if (test_structure_1.isTest(unit) && protocol_1.isTestFunctionProperty(functionName))
76
- return unit[functionName];
77
- if (test_structure_1.isFixture(unit) && protocol_1.isFixtureFunctionProperty(functionName))
78
- return unit[functionName];
79
- throw new Error(`Cannot find '${functionName}' function for ${typeof unit}`);
80
- }
81
- _wrapEventMethods({ name, testId, hookId, eventData }) {
82
- if (name === hook_method_names_1.default.onRequest)
83
- this._wrapSetMockFn({ testId, hookId, event: eventData });
84
- else if (name === hook_method_names_1.default._onConfigureResponse)
85
- this._wrapConfigureResponseEventMethods(eventData);
86
- }
87
- _wrapSetMockFn({ testId, hookId, event }) {
88
- event.setMock = async (mock) => {
89
- await this.setMock({
90
- responseEventId: event.id,
91
- ruleId: event.requestFilterRule.id,
92
- testId,
93
- hookId,
94
- mock
95
- });
96
- };
97
- }
98
- _wrapConfigureResponseEventMethods(event) {
99
- event.setHeader = async (name, value) => {
100
- await this.setHeaderOnConfigureResponseEvent({
101
- eventId: event.id,
102
- headerName: name,
103
- headerValue: value
104
- });
105
- };
106
- event.removeHeader = async (name) => {
107
- await this.removeHeaderOnConfigureResponseEvent({
108
- eventId: event.id,
109
- headerName: name
110
- });
111
- };
112
- }
113
- _restoreRequestFilterRule(event) {
114
- event.requestFilterRule = testcafe_hammerhead_1.RequestFilterRule.from(event.requestFilterRule);
115
- }
116
- async setOptions({ value }) {
117
- this.state.options = value;
118
- }
119
- async ready() {
120
- this.proxy.call(this.ready);
121
- }
122
- async cleanUp() {
123
- await compiler_1.default.cleanUp();
124
- }
125
- async getTests({ sourceList, compilerOptions }) {
126
- const compiler = new compiler_1.default(sourceList, compilerOptions);
127
- const tests = await compiler.getTests();
128
- const units = test_structure_1.flatten(tests);
129
- Object.assign(this.state.units, units);
130
- return test_structure_1.serialize(units);
131
- }
132
- async runTest(args) {
133
- const { id, functionName } = args;
134
- const unit = this.state.units[id];
135
- const context = this._getContext(args);
136
- const functionObject = this._getFunction(unit, functionName);
137
- if (!functionObject)
138
- throw new Error(`Cannot find the "${functionName}" of ${typeof unit}`);
139
- return await functionObject(context);
140
- }
141
- executeActionSync({ id, apiMethodName, command, callsite }) {
142
- return this.proxy.callSync(this.executeAction, { id, apiMethodName, command, callsite });
143
- }
144
- async executeAction({ id, apiMethodName, command, callsite }) {
145
- return this.proxy.call(this.executeAction, { id, apiMethodName, command, callsite });
146
- }
147
- async executeCommand({ command, id }) {
148
- return this.proxy.call(this.executeCommand, { id, command });
149
- }
150
- async onRequestHookEvent({ name, testId, hookId, eventData }) {
151
- this._wrapEventMethods({ name, testId, hookId, eventData });
152
- this._restoreRequestFilterRule(eventData);
153
- const test = this.state.units[testId];
154
- const targetHook = test.requestHooks.find(hook => hook.id === hookId);
155
- // @ts-ignore
156
- await targetHook[name].call(targetHook, eventData);
157
- if (name === hook_method_names_1.default._onConfigureResponse && targetHook._responseEventConfigureOpts) {
158
- const { opts, id: eventId } = eventData;
159
- await this.setConfigureResponseEventOptions({ eventId, opts });
160
- }
161
- }
162
- async setMock({ testId, hookId, ruleId, responseEventId, mock }) {
163
- await this.proxy.call(this.setMock, { testId, hookId, ruleId, responseEventId, mock });
164
- }
165
- async setConfigureResponseEventOptions({ eventId, opts }) {
166
- await this.proxy.call(this.setConfigureResponseEventOptions, { eventId, opts });
167
- }
168
- async setHeaderOnConfigureResponseEvent({ eventId, headerName, headerValue }) {
169
- await this.proxy.call(this.setHeaderOnConfigureResponseEvent, { eventId, headerName, headerValue });
170
- }
171
- async removeHeaderOnConfigureResponseEvent({ eventId, headerName }) {
172
- await this.proxy.call(this.removeHeaderOnConfigureResponseEvent, { eventId, headerName });
173
- }
174
- async executeRequestFilterRulePredicate({ testId, hookId, ruleId, requestInfo }) {
175
- const test = this.state.units[testId];
176
- const targetHook = test.requestHooks.find(hook => hook.id === hookId);
177
- const targetRule = targetHook._requestFilterRules.find(rule => rule.id === ruleId);
178
- const result = await targetRule.options.call(targetRule, requestInfo);
179
- return !!result;
180
- }
181
- async executeMockPredicate({ testId, hookId, ruleId, requestInfo, res }) {
182
- const test = this.state.units[testId];
183
- const requestMock = test.requestHooks.find(hook => hook.id === hookId);
184
- const responseMock = requestMock.mocks.get(ruleId);
185
- testcafe_hammerhead_1.responseMockSetBodyMethod.add(res);
186
- res = Object.assign(res, await responseMock.body(requestInfo, res));
187
- testcafe_hammerhead_1.responseMockSetBodyMethod.remove(res);
188
- return res;
189
- }
190
- async getWarningMessages({ testRunId }) {
191
- const testRunProxy = this.state.testRuns[testRunId];
192
- return testRunProxy.warningLog.messages;
193
- }
194
- async addRequestEventListeners({ hookId, hookClassName, rules }) {
195
- return await this.proxy.call(this.addRequestEventListeners, { hookId, hookClassName, rules });
196
- }
197
- async removeRequestEventListeners({ rules }) {
198
- return await this.proxy.call(this.removeRequestEventListeners, { rules });
199
- }
200
- async initializeTestRunProxy({ testRunId, testId }) {
201
- const test = this.state.units[testId];
202
- const testRunProxy = new test_run_proxy_1.default({
203
- dispatcher: this,
204
- id: testRunId,
205
- options: this.state.options,
206
- test
207
- });
208
- this.state.testRuns[testRunId] = testRunProxy;
209
- }
210
- }
211
- exports.default = new CompilerService();
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const fs_1 = __importDefault(require("fs"));
7
+ const compiler_1 = __importDefault(require("../../compiler"));
8
+ const test_run_proxy_1 = __importDefault(require("./test-run-proxy"));
9
+ const test_structure_1 = require("../serialization/test-structure");
10
+ const io_1 = require("./io");
11
+ const proxy_1 = require("../utils/ipc/proxy");
12
+ const transport_1 = require("../utils/ipc/transport");
13
+ const source_map_support_1 = __importDefault(require("source-map-support"));
14
+ const protocol_1 = require("./protocol");
15
+ const process_title_1 = __importDefault(require("../process-title"));
16
+ const hook_method_names_1 = __importDefault(require("../../api/request-hooks/hook-method-names"));
17
+ const testcafe_hammerhead_1 = require("testcafe-hammerhead");
18
+ source_map_support_1.default.install({
19
+ hookRequire: true,
20
+ handleUncaughtExceptions: false,
21
+ environment: 'node'
22
+ });
23
+ class CompilerService {
24
+ constructor() {
25
+ process.title = process_title_1.default.service;
26
+ const input = fs_1.default.createReadStream('', { fd: io_1.SERVICE_INPUT_FD });
27
+ const output = fs_1.default.createWriteStream('', { fd: io_1.SERVICE_OUTPUT_FD });
28
+ this.proxy = new proxy_1.IPCProxy(new transport_1.ServiceTransport(input, output, io_1.SERVICE_SYNC_FD));
29
+ this.state = this._initState();
30
+ this._setupRoutes();
31
+ this.ready();
32
+ }
33
+ _initState() {
34
+ return {
35
+ testRuns: {},
36
+ fixtureCtxs: {},
37
+ units: {},
38
+ options: {}
39
+ };
40
+ }
41
+ _getFixtureCtx({ id }) {
42
+ const unit = this.state.units[id];
43
+ const fixtureId = test_structure_1.isTest(unit) ? unit.fixture.id : unit.id;
44
+ return this.state.fixtureCtxs[fixtureId];
45
+ }
46
+ _getTestCtx({ testRunId }, test) {
47
+ const testRunProxy = this.state.testRuns[testRunId];
48
+ const targetFixtureCtx = this.state.fixtureCtxs[test.fixture.id];
49
+ testRunProxy.fixtureCtx = targetFixtureCtx;
50
+ return testRunProxy;
51
+ }
52
+ _getContext(args, unit) {
53
+ const { testRunId } = args;
54
+ if (testRunId)
55
+ return this._getTestCtx(args, unit);
56
+ return this._getFixtureCtx(args);
57
+ }
58
+ _setupRoutes() {
59
+ this.proxy.register([
60
+ this.getTests,
61
+ this.runTestFn,
62
+ this.cleanUp,
63
+ this.setOptions,
64
+ this.onRequestHookEvent,
65
+ this.setMock,
66
+ this.setConfigureResponseEventOptions,
67
+ this.setHeaderOnConfigureResponseEvent,
68
+ this.removeHeaderOnConfigureResponseEvent,
69
+ this.executeRequestFilterRulePredicate,
70
+ this.executeMockPredicate,
71
+ this.getWarningMessages,
72
+ this.addRequestEventListeners,
73
+ this.removeRequestEventListeners,
74
+ this.initializeTestRunData
75
+ ], this);
76
+ }
77
+ _getFunction(unit, functionName) {
78
+ if (test_structure_1.isTest(unit) && protocol_1.isTestFunctionProperty(functionName))
79
+ return unit[functionName];
80
+ if (test_structure_1.isFixture(unit) && protocol_1.isFixtureFunctionProperty(functionName))
81
+ return unit[functionName];
82
+ throw new Error(`Cannot find '${functionName}' function for ${typeof unit}`);
83
+ }
84
+ _wrapEventMethods({ name, testId, hookId, eventData }) {
85
+ if (name === hook_method_names_1.default.onRequest)
86
+ this._wrapSetMockFn({ testId, hookId, event: eventData });
87
+ else if (name === hook_method_names_1.default._onConfigureResponse)
88
+ this._wrapConfigureResponseEventMethods(eventData);
89
+ }
90
+ _wrapSetMockFn({ testId, hookId, event }) {
91
+ event.setMock = async (mock) => {
92
+ await this.setMock({
93
+ responseEventId: event.id,
94
+ ruleId: event.requestFilterRule.id,
95
+ testId,
96
+ hookId,
97
+ mock
98
+ });
99
+ };
100
+ }
101
+ _wrapConfigureResponseEventMethods(event) {
102
+ event.setHeader = async (name, value) => {
103
+ await this.setHeaderOnConfigureResponseEvent({
104
+ eventId: event.id,
105
+ headerName: name,
106
+ headerValue: value
107
+ });
108
+ };
109
+ event.removeHeader = async (name) => {
110
+ await this.removeHeaderOnConfigureResponseEvent({
111
+ eventId: event.id,
112
+ headerName: name
113
+ });
114
+ };
115
+ }
116
+ _restoreRequestFilterRule(event) {
117
+ event.requestFilterRule = testcafe_hammerhead_1.RequestFilterRule.from(event.requestFilterRule);
118
+ }
119
+ _initializeTestRunProxy(testRunId, test) {
120
+ const testRunProxy = new test_run_proxy_1.default({
121
+ dispatcher: this,
122
+ id: testRunId,
123
+ options: this.state.options,
124
+ test
125
+ });
126
+ this.state.testRuns[testRunId] = testRunProxy;
127
+ }
128
+ _initializeFixtureCtx(test) {
129
+ const fixtureId = test.fixture.id;
130
+ if (this.state.fixtureCtxs[fixtureId])
131
+ return;
132
+ this.state.fixtureCtxs[fixtureId] = Object.create(null);
133
+ }
134
+ async setOptions({ value }) {
135
+ this.state.options = value;
136
+ }
137
+ async ready() {
138
+ this.proxy.call(this.ready);
139
+ }
140
+ async cleanUp() {
141
+ await compiler_1.default.cleanUp();
142
+ }
143
+ async getTests({ sourceList, compilerOptions }) {
144
+ const compiler = new compiler_1.default(sourceList, compilerOptions);
145
+ const tests = await compiler.getTests();
146
+ const units = test_structure_1.flatten(tests);
147
+ Object.assign(this.state.units, units);
148
+ return test_structure_1.serialize(units);
149
+ }
150
+ async runTestFn(args) {
151
+ const { id, functionName } = args;
152
+ const unit = this.state.units[id];
153
+ const context = this._getContext(args, unit);
154
+ const functionObject = this._getFunction(unit, functionName);
155
+ if (!functionObject)
156
+ throw new Error(`Cannot find the "${functionName}" of ${typeof unit}`);
157
+ return await functionObject(context);
158
+ }
159
+ executeActionSync({ id, apiMethodName, command, callsite }) {
160
+ return this.proxy.callSync(this.executeAction, { id, apiMethodName, command, callsite });
161
+ }
162
+ async executeAction({ id, apiMethodName, command, callsite }) {
163
+ return this.proxy.call(this.executeAction, { id, apiMethodName, command, callsite });
164
+ }
165
+ async executeCommand({ command, id }) {
166
+ return this.proxy.call(this.executeCommand, { id, command });
167
+ }
168
+ async onRequestHookEvent({ name, testId, hookId, eventData }) {
169
+ this._wrapEventMethods({ name, testId, hookId, eventData });
170
+ this._restoreRequestFilterRule(eventData);
171
+ const test = this.state.units[testId];
172
+ const targetHook = test.requestHooks.find(hook => hook.id === hookId);
173
+ // @ts-ignore
174
+ await targetHook[name].call(targetHook, eventData);
175
+ if (name === hook_method_names_1.default._onConfigureResponse && targetHook._responseEventConfigureOpts) {
176
+ const { opts, id: eventId } = eventData;
177
+ await this.setConfigureResponseEventOptions({ eventId, opts });
178
+ }
179
+ }
180
+ async setMock({ testId, hookId, ruleId, responseEventId, mock }) {
181
+ await this.proxy.call(this.setMock, { testId, hookId, ruleId, responseEventId, mock });
182
+ }
183
+ async setConfigureResponseEventOptions({ eventId, opts }) {
184
+ await this.proxy.call(this.setConfigureResponseEventOptions, { eventId, opts });
185
+ }
186
+ async setHeaderOnConfigureResponseEvent({ eventId, headerName, headerValue }) {
187
+ await this.proxy.call(this.setHeaderOnConfigureResponseEvent, { eventId, headerName, headerValue });
188
+ }
189
+ async removeHeaderOnConfigureResponseEvent({ eventId, headerName }) {
190
+ await this.proxy.call(this.removeHeaderOnConfigureResponseEvent, { eventId, headerName });
191
+ }
192
+ async executeRequestFilterRulePredicate({ testId, hookId, ruleId, requestInfo }) {
193
+ const test = this.state.units[testId];
194
+ const targetHook = test.requestHooks.find(hook => hook.id === hookId);
195
+ const targetRule = targetHook._requestFilterRules.find(rule => rule.id === ruleId);
196
+ const result = await targetRule.options.call(targetRule, requestInfo);
197
+ return !!result;
198
+ }
199
+ async executeMockPredicate({ testId, hookId, ruleId, requestInfo, res }) {
200
+ const test = this.state.units[testId];
201
+ const requestMock = test.requestHooks.find(hook => hook.id === hookId);
202
+ const responseMock = requestMock.mocks.get(ruleId);
203
+ testcafe_hammerhead_1.responseMockSetBodyMethod.add(res);
204
+ res = Object.assign(res, await responseMock.body(requestInfo, res));
205
+ testcafe_hammerhead_1.responseMockSetBodyMethod.remove(res);
206
+ return res;
207
+ }
208
+ async getWarningMessages({ testRunId }) {
209
+ const testRunProxy = this.state.testRuns[testRunId];
210
+ return testRunProxy.warningLog.messages;
211
+ }
212
+ async addRequestEventListeners({ hookId, hookClassName, rules }) {
213
+ return await this.proxy.call(this.addRequestEventListeners, { hookId, hookClassName, rules });
214
+ }
215
+ async removeRequestEventListeners({ rules }) {
216
+ return await this.proxy.call(this.removeRequestEventListeners, { rules });
217
+ }
218
+ async initializeTestRunData({ testRunId, testId }) {
219
+ const test = this.state.units[testId];
220
+ this._initializeTestRunProxy(testRunId, test);
221
+ this._initializeFixtureCtx(test);
222
+ }
223
+ }
224
+ exports.default = new CompilerService();
212
225
  module.exports = exports.default;
213
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZXJ2aWNlcy9jb21waWxlci9zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsNENBQW9CO0FBQ3BCLDhEQUFzQztBQUN0QyxzRUFBNEM7QUFFNUMsb0VBT3lDO0FBRXpDLDZCQUljO0FBRWQsOENBQThDO0FBQzlDLHNEQUEwRDtBQUMxRCw0RUFBa0Q7QUFFbEQseUNBcUJvQjtBQUtwQixxRUFBNEM7QUFFNUMsa0dBQStFO0FBRS9FLDZEQVE2QjtBQUs3Qiw0QkFBZ0IsQ0FBQyxPQUFPLENBQUM7SUFDckIsV0FBVyxFQUFlLElBQUk7SUFDOUIsd0JBQXdCLEVBQUUsS0FBSztJQUMvQixXQUFXLEVBQWUsTUFBTTtDQUNuQyxDQUFDLENBQUM7QUFtQkgsTUFBTSxlQUFlO0lBSWpCO1FBQ0ksT0FBTyxDQUFDLEtBQUssR0FBRyx1QkFBWSxDQUFDLE9BQU8sQ0FBQztRQUVyQyxNQUFNLEtBQUssR0FBSSxZQUFFLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLHFCQUFnQixFQUFFLENBQUMsQ0FBQztRQUNqRSxNQUFNLE1BQU0sR0FBRyxZQUFFLENBQUMsaUJBQWlCLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLHNCQUFpQixFQUFFLENBQUMsQ0FBQztRQUVuRSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksZ0JBQVEsQ0FBQyxJQUFJLDRCQUFnQixDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsb0JBQWUsQ0FBQyxDQUFDLENBQUM7UUFDaEYsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFFL0IsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNqQixDQUFDO0lBRU8sVUFBVTtRQUNkLE9BQU87WUFDSCxRQUFRLEVBQUssRUFBRTtZQUNmLFdBQVcsRUFBRSxFQUFFO1lBQ2YsS0FBSyxFQUFRLEVBQUU7WUFDZixPQUFPLEVBQU0sRUFBRTtTQUNsQixDQUFDO0lBQ04sQ0FBQztJQUVPLGNBQWMsQ0FBRSxFQUFFLEVBQUUsRUFBb0I7UUFDNUMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFbEMsTUFBTSxTQUFTLEdBQUcsdUJBQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFFLElBQWdCLENBQUMsRUFBRSxDQUFDO1FBRXhFLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUM7WUFDbEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUU1RCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFTyxXQUFXLENBQUUsSUFBc0I7UUFDdkMsTUFBTSxFQUFFLFNBQVMsRUFBRSxHQUFHLElBQUksQ0FBQztRQUMzQixNQUFNLFVBQVUsR0FBTSxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRWhELElBQUksQ0FBQyxTQUFTO1lBQ1YsT0FBTyxVQUFVLENBQUM7UUFFdEIsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRU8sWUFBWTtRQUNoQixJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQztZQUNoQixJQUFJLENBQUMsUUFBUTtZQUNiLElBQUksQ0FBQyxPQUFPO1lBQ1osSUFBSSxDQUFDLE9BQU87WUFDWixJQUFJLENBQUMsVUFBVTtZQUNmLElBQUksQ0FBQyxrQkFBa0I7WUFDdkIsSUFBSSxDQUFDLE9BQU87WUFDWixJQUFJLENBQUMsZ0NBQWdDO1lBQ3JDLElBQUksQ0FBQyxpQ0FBaUM7WUFDdEMsSUFBSSxDQUFDLG9DQUFvQztZQUN6QyxJQUFJLENBQUMsaUNBQWlDO1lBQ3RDLElBQUksQ0FBQyxvQkFBb0I7WUFDekIsSUFBSSxDQUFDLGtCQUFrQjtZQUN2QixJQUFJLENBQUMsd0JBQXdCO1lBQzdCLElBQUksQ0FBQywyQkFBMkI7WUFDaEMsSUFBSSxDQUFDLHNCQUFzQjtTQUM5QixFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2IsQ0FBQztJQUVPLFlBQVksQ0FBRSxJQUFVLEVBQUUsWUFBZ0M7UUFDOUQsSUFBSSx1QkFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLGlDQUFzQixDQUFDLFlBQVksQ0FBQztZQUNwRCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUU5QixJQUFJLDBCQUFTLENBQUMsSUFBSSxDQUFDLElBQUksb0NBQXlCLENBQUMsWUFBWSxDQUFDO1lBQzFELE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRTlCLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0JBQWdCLFlBQVksa0JBQWtCLE9BQU8sSUFBSSxFQUFFLENBQUMsQ0FBQztJQUNqRixDQUFDO0lBRU8saUJBQWlCLENBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQTZCO1FBQ3JGLElBQUksSUFBSSxLQUFLLDJCQUFzQixDQUFDLFNBQVM7WUFDekMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLFNBQXlCLEVBQUUsQ0FBQyxDQUFDO2FBQ3pFLElBQUksSUFBSSxLQUFLLDJCQUFzQixDQUFDLG9CQUFvQjtZQUN6RCxJQUFJLENBQUMsa0NBQWtDLENBQUMsU0FBbUMsQ0FBQyxDQUFDO0lBQ3JGLENBQUM7SUFFTyxjQUFjLENBQUUsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBd0I7UUFDbkUsS0FBSyxDQUFDLE9BQU8sR0FBRyxLQUFLLEVBQUUsSUFBa0IsRUFBRSxFQUFFO1lBQ3pDLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQztnQkFDZixlQUFlLEVBQUUsS0FBSyxDQUFDLEVBQUU7Z0JBQ3pCLE1BQU0sRUFBVyxLQUFLLENBQUMsaUJBQWlCLENBQUMsRUFBRTtnQkFDM0MsTUFBTTtnQkFDTixNQUFNO2dCQUNOLElBQUk7YUFDUCxDQUFDLENBQUM7UUFDUCxDQUFDLENBQUM7SUFDTixDQUFDO0lBRU8sa0NBQWtDLENBQUUsS0FBNkI7UUFDckUsS0FBSyxDQUFDLFNBQVMsR0FBRyxLQUFLLEVBQUUsSUFBWSxFQUFFLEtBQWEsRUFBRSxFQUFFO1lBQ3BELE1BQU0sSUFBSSxDQUFDLGlDQUFpQyxDQUFDO2dCQUN6QyxPQUFPLEVBQU0sS0FBSyxDQUFDLEVBQUU7Z0JBQ3JCLFVBQVUsRUFBRyxJQUFJO2dCQUNqQixXQUFXLEVBQUUsS0FBSzthQUNyQixDQUFDLENBQUM7UUFDUCxDQUFDLENBQUM7UUFFRixLQUFLLENBQUMsWUFBWSxHQUFHLEtBQUssRUFBRSxJQUFZLEVBQUUsRUFBRTtZQUN4QyxNQUFNLElBQUksQ0FBQyxvQ0FBb0MsQ0FBQztnQkFDNUMsT0FBTyxFQUFLLEtBQUssQ0FBQyxFQUFFO2dCQUNwQixVQUFVLEVBQUUsSUFBSTthQUNuQixDQUFDLENBQUM7UUFDUCxDQUFDLENBQUM7SUFDTixDQUFDO0lBRU8seUJBQXlCLENBQUUsS0FBNEQ7UUFDM0YsS0FBSyxDQUFDLGlCQUFpQixHQUFHLHVDQUFpQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsaUJBQTJCLENBQUMsQ0FBQztJQUN4RixDQUFDO0lBRU0sS0FBSyxDQUFDLFVBQVUsQ0FBRSxFQUFFLEtBQUssRUFBdUI7UUFDbkQsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO0lBQy9CLENBQUM7SUFFTSxLQUFLLENBQUMsS0FBSztRQUNkLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBRU0sS0FBSyxDQUFDLE9BQU87UUFDaEIsTUFBTSxrQkFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFTSxLQUFLLENBQUMsUUFBUSxDQUFFLEVBQUUsVUFBVSxFQUFFLGVBQWUsRUFBcUI7UUFDckUsTUFBTSxRQUFRLEdBQUcsSUFBSSxrQkFBUSxDQUFDLFVBQVUsRUFBRSxlQUFlLENBQUMsQ0FBQztRQUUzRCxNQUFNLEtBQUssR0FBRyxNQUFNLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUN4QyxNQUFNLEtBQUssR0FBRyx3QkFBb0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUUxQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRXZDLE9BQU8sMEJBQXNCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVNLEtBQUssQ0FBQyxPQUFPLENBQUUsSUFBc0I7UUFDeEMsTUFBTSxFQUFFLEVBQUUsRUFBRSxZQUFZLEVBQUUsR0FBRyxJQUFJLENBQUM7UUFFbEMsTUFBTSxJQUFJLEdBQWEsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDNUMsTUFBTSxPQUFPLEdBQVUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM5QyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQztRQUU3RCxJQUFJLENBQUMsY0FBYztZQUNmLE1BQU0sSUFBSSxLQUFLLENBQUMsb0JBQW9CLFlBQVksUUFBUSxPQUFPLElBQUksRUFBRSxDQUFDLENBQUM7UUFFM0UsT0FBTyxNQUFNLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRU0saUJBQWlCLENBQUUsRUFBRSxFQUFFLEVBQUUsYUFBYSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQTBCO1FBQ3RGLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxFQUFFLEVBQUUsRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDN0YsQ0FBQztJQUVNLEtBQUssQ0FBQyxhQUFhLENBQUUsRUFBRSxFQUFFLEVBQUUsYUFBYSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQTBCO1FBQ3hGLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxFQUFFLEVBQUUsRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDekYsQ0FBQztJQUVNLEtBQUssQ0FBQyxjQUFjLENBQUUsRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUEyQjtRQUNqRSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsRUFBRSxFQUFFLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUNqRSxDQUFDO0lBRU0sS0FBSyxDQUFDLGtCQUFrQixDQUFFLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUE2QjtRQUMzRixJQUFJLENBQUMsaUJBQWlCLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQzVELElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUUxQyxNQUFNLElBQUksR0FBUyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQVMsQ0FBQztRQUNwRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssTUFBTSxDQUFnQixDQUFDO1FBRXJGLGFBQWE7UUFDYixNQUFNLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBRW5ELElBQUksSUFBSSxLQUFLLDJCQUFzQixDQUFDLG9CQUFvQixJQUFJLFVBQVUsQ0FBQywyQkFBMkIsRUFBRTtZQUNoRyxNQUFNLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxPQUFPLEVBQUUsR0FBRyxTQUFtQyxDQUFDO1lBRWxFLE1BQU0sSUFBSSxDQUFDLGdDQUFnQyxDQUFDLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7U0FDbEU7SUFDTCxDQUFDO0lBRU0sS0FBSyxDQUFDLE9BQU8sQ0FBRSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQW9CO1FBQ3JGLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzNGLENBQUM7SUFFTSxLQUFLLENBQUMsZ0NBQWdDLENBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUE2QztRQUN2RyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxnQ0FBZ0MsRUFBRSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3BGLENBQUM7SUFFTSxLQUFLLENBQUMsaUNBQWlDLENBQUUsRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBOEM7UUFDNUgsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsaUNBQWlDLEVBQUUsRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDeEcsQ0FBQztJQUVNLEtBQUssQ0FBQyxvQ0FBb0MsQ0FBRSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQWlEO1FBQ3JILE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLG9DQUFvQyxFQUFFLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUM7SUFDOUYsQ0FBQztJQUVNLEtBQUssQ0FBQyxpQ0FBaUMsQ0FBRSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBOEM7UUFDL0gsTUFBTSxJQUFJLEdBQVMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFTLENBQUM7UUFDcEQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLE1BQU0sQ0FBZ0IsQ0FBQztRQUNyRixNQUFNLFVBQVUsR0FBRyxVQUFVLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxNQUFNLENBQXNCLENBQUM7UUFDeEcsTUFBTSxNQUFNLEdBQU8sTUFBTSxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFFMUUsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQ3BCLENBQUM7SUFFTSxLQUFLLENBQUMsb0JBQW9CLENBQUUsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsR0FBRyxFQUF3QjtRQUNqRyxNQUFNLElBQUksR0FBVyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQVMsQ0FBQztRQUN0RCxNQUFNLFdBQVcsR0FBSSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssTUFBTSxDQUFnQixDQUFDO1FBQ3ZGLE1BQU0sWUFBWSxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBaUIsQ0FBQztRQUVuRSwrQ0FBeUIsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFbkMsR0FBRyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLE1BQU8sWUFBWSxDQUFDLElBQWlCLENBQUMsV0FBVyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFFbEYsK0NBQXlCLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRXRDLE9BQU8sR0FBRyxDQUFDO0lBQ2YsQ0FBQztJQUVNLEtBQUssQ0FBQyxrQkFBa0IsQ0FBRSxFQUFFLFNBQVMsRUFBK0I7UUFDdkUsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFcEQsT0FBTyxZQUFZLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQztJQUM1QyxDQUFDO0lBRU0sS0FBSyxDQUFDLHdCQUF3QixDQUFHLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQXFDO1FBQ3ZHLE9BQU8sTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsRUFBRSxNQUFNLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDbEcsQ0FBQztJQUVNLEtBQUssQ0FBQywyQkFBMkIsQ0FBRSxFQUFFLEtBQUssRUFBd0M7UUFDckYsT0FBTyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQywyQkFBMkIsRUFBRSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDOUUsQ0FBQztJQUVNLEtBQUssQ0FBQyxzQkFBc0IsQ0FBRSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQW1DO1FBQ3ZGLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBUyxDQUFDO1FBRTlDLE1BQU0sWUFBWSxHQUFHLElBQUksd0JBQVksQ0FBQztZQUNsQyxVQUFVLEVBQUUsSUFBSTtZQUNoQixFQUFFLEVBQVUsU0FBUztZQUNyQixPQUFPLEVBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPO1lBQzlCLElBQUk7U0FDUCxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsR0FBRyxZQUFZLENBQUM7SUFDbEQsQ0FBQztDQUNKO0FBRUQsa0JBQWUsSUFBSSxlQUFlLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBmcyBmcm9tICdmcyc7XG5pbXBvcnQgQ29tcGlsZXIgZnJvbSAnLi4vLi4vY29tcGlsZXInO1xuaW1wb3J0IFRlc3RSdW5Qcm94eSBmcm9tICcuL3Rlc3QtcnVuLXByb3h5JztcblxuaW1wb3J0IHtcbiAgICBmbGF0dGVuIGFzIGZsYXR0ZW5UZXN0U3RydWN0dXJlLFxuICAgIGlzRml4dHVyZSxcbiAgICBpc1Rlc3QsXG4gICAgc2VyaWFsaXplIGFzIHNlcmlhbGl6ZVRlc3RTdHJ1Y3R1cmUsXG4gICAgVW5pdCxcbiAgICBVbml0c1xufSBmcm9tICcuLi9zZXJpYWxpemF0aW9uL3Rlc3Qtc3RydWN0dXJlJztcblxuaW1wb3J0IHtcbiAgICBTRVJWSUNFX0lOUFVUX0ZELFxuICAgIFNFUlZJQ0VfT1VUUFVUX0ZELFxuICAgIFNFUlZJQ0VfU1lOQ19GRFxufSBmcm9tICcuL2lvJztcblxuaW1wb3J0IHsgSVBDUHJveHkgfSBmcm9tICcuLi91dGlscy9pcGMvcHJveHknO1xuaW1wb3J0IHsgU2VydmljZVRyYW5zcG9ydCB9IGZyb20gJy4uL3V0aWxzL2lwYy90cmFuc3BvcnQnO1xuaW1wb3J0IHNvdXJjZU1hcFN1cHBvcnQgZnJvbSAnc291cmNlLW1hcC1zdXBwb3J0JztcblxuaW1wb3J0IHtcbiAgICBDb21waWxlclByb3RvY29sLFxuICAgIEV4ZWN1dGVBY3Rpb25Bcmd1bWVudHMsXG4gICAgRXhlY3V0ZUNvbW1hbmRBcmd1bWVudHMsXG4gICAgRXhlY3V0ZU1vY2tQcmVkaWNhdGUsXG4gICAgRXhlY3V0ZVJlcXVlc3RGaWx0ZXJSdWxlUHJlZGljYXRlQXJndW1lbnRzLFxuICAgIEZ1bmN0aW9uUHJvcGVydGllcyxcbiAgICBpc0ZpeHR1cmVGdW5jdGlvblByb3BlcnR5LFxuICAgIGlzVGVzdEZ1bmN0aW9uUHJvcGVydHksXG4gICAgUmVtb3ZlSGVhZGVyT25Db25maWd1cmVSZXNwb25zZUV2ZW50QXJndW1lbnRzLFxuICAgIFJlcXVlc3RIb29rRXZlbnRBcmd1bWVudHMsXG4gICAgUmVxdWVzdEhvb2tMb2NhdG9yLFxuICAgIFJ1blRlc3RBcmd1bWVudHMsXG4gICAgU2V0Q29uZmlndXJlUmVzcG9uc2VFdmVudE9wdGlvbnNBcmd1bWVudHMsXG4gICAgU2V0SGVhZGVyT25Db25maWd1cmVSZXNwb25zZUV2ZW50QXJndW1lbnRzLFxuICAgIFNldE1vY2tBcmd1bWVudHMsXG4gICAgU2V0T3B0aW9uc0FyZ3VtZW50cyxcbiAgICBHZXRXYXJuaW5nTWVzc2FnZXNBcmd1bWVudHMsXG4gICAgQWRkUmVxdWVzdEV2ZW50TGlzdGVuZXJzQXJndW1lbnRzLFxuICAgIFJlbW92ZVJlcXVlc3RFdmVudExpc3RlbmVyc0FyZ3VtZW50cyxcbiAgICBJbml0aWFsaXplVGVzdFJ1blByb3h5QXJndW1lbnRzXG59IGZyb20gJy4vcHJvdG9jb2wnO1xuXG5pbXBvcnQgeyBDb21waWxlckFyZ3VtZW50cyB9IGZyb20gJy4uLy4uL2NvbXBpbGVyL2ludGVyZmFjZXMnO1xuaW1wb3J0IEZpeHR1cmUgZnJvbSAnLi4vLi4vYXBpL3N0cnVjdHVyZS9maXh0dXJlJztcbmltcG9ydCB7IERpY3Rpb25hcnkgfSBmcm9tICcuLi8uLi9jb25maWd1cmF0aW9uL2ludGVyZmFjZXMnO1xuaW1wb3J0IFByb2Nlc3NUaXRsZSBmcm9tICcuLi9wcm9jZXNzLXRpdGxlJztcbmltcG9ydCBUZXN0IGZyb20gJy4uLy4uL2FwaS9zdHJ1Y3R1cmUvdGVzdCc7XG5pbXBvcnQgUmVxdWVzdEhvb2tNZXRob2ROYW1lcyBmcm9tICcuLi8uLi9hcGkvcmVxdWVzdC1ob29rcy9ob29rLW1ldGhvZC1uYW1lcyc7XG5cbmltcG9ydCB7XG4gICAgQ29uZmlndXJlUmVzcG9uc2VFdmVudCxcbiAgICBJbmNvbWluZ01lc3NhZ2VMaWtlSW5pdE9wdGlvbnMsXG4gICAgUmVxdWVzdEV2ZW50LFxuICAgIFJlcXVlc3RGaWx0ZXJSdWxlLFxuICAgIFJlc3BvbnNlRXZlbnQsXG4gICAgUmVzcG9uc2VNb2NrLFxuICAgIHJlc3BvbnNlTW9ja1NldEJvZHlNZXRob2Rcbn0gZnJvbSAndGVzdGNhZmUtaGFtbWVyaGVhZCc7XG5cbmltcG9ydCBSZXF1ZXN0SG9vayBmcm9tICcuLi8uLi9hcGkvcmVxdWVzdC1ob29rcy9ob29rJztcbmltcG9ydCBSZXF1ZXN0TW9jayBmcm9tICcuLi8uLi9hcGkvcmVxdWVzdC1ob29rcy9yZXF1ZXN0LW1vY2snO1xuXG5zb3VyY2VNYXBTdXBwb3J0Lmluc3RhbGwoe1xuICAgIGhvb2tSZXF1aXJlOiAgICAgICAgICAgICAgdHJ1ZSxcbiAgICBoYW5kbGVVbmNhdWdodEV4Y2VwdGlvbnM6IGZhbHNlLFxuICAgIGVudmlyb25tZW50OiAgICAgICAgICAgICAgJ25vZGUnXG59KTtcblxuaW50ZXJmYWNlIFNlcnZpY2VTdGF0ZSB7XG4gICAgdGVzdFJ1bnM6IHsgW2lkOiBzdHJpbmddOiBUZXN0UnVuUHJveHkgfTtcbiAgICBmaXh0dXJlQ3R4czogeyBbaWQ6IHN0cmluZ106IG9iamVjdCB9O1xuICAgIHVuaXRzOiBVbml0cztcbiAgICBvcHRpb25zOiBEaWN0aW9uYXJ5PE9wdGlvblZhbHVlPjtcbn1cblxuaW50ZXJmYWNlIFRlc3RSdW5Qcm94eUNyZWF0aW9uQXJncyB7XG4gICAgdGVzdFJ1bklkOiBzdHJpbmc7XG4gICAgdGVzdElkOiBzdHJpbmc7XG4gICAgZml4dHVyZUN0eDogdW5rbm93bjtcbn1cblxuaW50ZXJmYWNlIFdyYXBTZXRNb2NrQXJndW1lbnRzIGV4dGVuZHMgUmVxdWVzdEhvb2tMb2NhdG9yIHtcbiAgICBldmVudDogUmVxdWVzdEV2ZW50O1xufVxuXG5jbGFzcyBDb21waWxlclNlcnZpY2UgaW1wbGVtZW50cyBDb21waWxlclByb3RvY29sIHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IHByb3h5OiBJUENQcm94eTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IHN0YXRlOiBTZXJ2aWNlU3RhdGU7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBwcm9jZXNzLnRpdGxlID0gUHJvY2Vzc1RpdGxlLnNlcnZpY2U7XG5cbiAgICAgICAgY29uc3QgaW5wdXQgID0gZnMuY3JlYXRlUmVhZFN0cmVhbSgnJywgeyBmZDogU0VSVklDRV9JTlBVVF9GRCB9KTtcbiAgICAgICAgY29uc3Qgb3V0cHV0ID0gZnMuY3JlYXRlV3JpdGVTdHJlYW0oJycsIHsgZmQ6IFNFUlZJQ0VfT1VUUFVUX0ZEIH0pO1xuXG4gICAgICAgIHRoaXMucHJveHkgPSBuZXcgSVBDUHJveHkobmV3IFNlcnZpY2VUcmFuc3BvcnQoaW5wdXQsIG91dHB1dCwgU0VSVklDRV9TWU5DX0ZEKSk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB0aGlzLl9pbml0U3RhdGUoKTtcblxuICAgICAgICB0aGlzLl9zZXR1cFJvdXRlcygpO1xuICAgICAgICB0aGlzLnJlYWR5KCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfaW5pdFN0YXRlICgpOiBTZXJ2aWNlU3RhdGUge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdGVzdFJ1bnM6ICAgIHt9LFxuICAgICAgICAgICAgZml4dHVyZUN0eHM6IHt9LFxuICAgICAgICAgICAgdW5pdHM6ICAgICAgIHt9LFxuICAgICAgICAgICAgb3B0aW9uczogICAgIHt9XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZ2V0Rml4dHVyZUN0eCAoeyBpZCB9OiBSdW5UZXN0QXJndW1lbnRzKTogdW5rbm93biB7XG4gICAgICAgIGNvbnN0IHVuaXQgPSB0aGlzLnN0YXRlLnVuaXRzW2lkXTtcblxuICAgICAgICBjb25zdCBmaXh0dXJlSWQgPSBpc1Rlc3QodW5pdCkgPyB1bml0LmZpeHR1cmUuaWQgOiAodW5pdCBhcyBGaXh0dXJlKS5pZDtcblxuICAgICAgICBpZiAoIXRoaXMuc3RhdGUuZml4dHVyZUN0eHNbZml4dHVyZUlkXSlcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZml4dHVyZUN0eHNbZml4dHVyZUlkXSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhdGUuZml4dHVyZUN0eHNbZml4dHVyZUlkXTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9nZXRDb250ZXh0IChhcmdzOiBSdW5UZXN0QXJndW1lbnRzKTogVGVzdFJ1blByb3h5IHwgdW5rbm93biB7XG4gICAgICAgIGNvbnN0IHsgdGVzdFJ1bklkIH0gPSBhcmdzO1xuICAgICAgICBjb25zdCBmaXh0dXJlQ3R4ICAgID0gdGhpcy5fZ2V0Rml4dHVyZUN0eChhcmdzKTtcblxuICAgICAgICBpZiAoIXRlc3RSdW5JZClcbiAgICAgICAgICAgIHJldHVybiBmaXh0dXJlQ3R4O1xuXG4gICAgICAgIHJldHVybiB0aGlzLnN0YXRlLnRlc3RSdW5zW3Rlc3RSdW5JZF07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfc2V0dXBSb3V0ZXMgKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnByb3h5LnJlZ2lzdGVyKFtcbiAgICAgICAgICAgIHRoaXMuZ2V0VGVzdHMsXG4gICAgICAgICAgICB0aGlzLnJ1blRlc3QsXG4gICAgICAgICAgICB0aGlzLmNsZWFuVXAsXG4gICAgICAgICAgICB0aGlzLnNldE9wdGlvbnMsXG4gICAgICAgICAgICB0aGlzLm9uUmVxdWVzdEhvb2tFdmVudCxcbiAgICAgICAgICAgIHRoaXMuc2V0TW9jayxcbiAgICAgICAgICAgIHRoaXMuc2V0Q29uZmlndXJlUmVzcG9uc2VFdmVudE9wdGlvbnMsXG4gICAgICAgICAgICB0aGlzLnNldEhlYWRlck9uQ29uZmlndXJlUmVzcG9uc2VFdmVudCxcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlSGVhZGVyT25Db25maWd1cmVSZXNwb25zZUV2ZW50LFxuICAgICAgICAgICAgdGhpcy5leGVjdXRlUmVxdWVzdEZpbHRlclJ1bGVQcmVkaWNhdGUsXG4gICAgICAgICAgICB0aGlzLmV4ZWN1dGVNb2NrUHJlZGljYXRlLFxuICAgICAgICAgICAgdGhpcy5nZXRXYXJuaW5nTWVzc2FnZXMsXG4gICAgICAgICAgICB0aGlzLmFkZFJlcXVlc3RFdmVudExpc3RlbmVycyxcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlUmVxdWVzdEV2ZW50TGlzdGVuZXJzLFxuICAgICAgICAgICAgdGhpcy5pbml0aWFsaXplVGVzdFJ1blByb3h5XG4gICAgICAgIF0sIHRoaXMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2dldEZ1bmN0aW9uICh1bml0OiBVbml0LCBmdW5jdGlvbk5hbWU6IEZ1bmN0aW9uUHJvcGVydGllcyk6IEZ1bmN0aW9ufG51bGwge1xuICAgICAgICBpZiAoaXNUZXN0KHVuaXQpICYmIGlzVGVzdEZ1bmN0aW9uUHJvcGVydHkoZnVuY3Rpb25OYW1lKSlcbiAgICAgICAgICAgIHJldHVybiB1bml0W2Z1bmN0aW9uTmFtZV07XG5cbiAgICAgICAgaWYgKGlzRml4dHVyZSh1bml0KSAmJiBpc0ZpeHR1cmVGdW5jdGlvblByb3BlcnR5KGZ1bmN0aW9uTmFtZSkpXG4gICAgICAgICAgICByZXR1cm4gdW5pdFtmdW5jdGlvbk5hbWVdO1xuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGZpbmQgJyR7ZnVuY3Rpb25OYW1lfScgZnVuY3Rpb24gZm9yICR7dHlwZW9mIHVuaXR9YCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfd3JhcEV2ZW50TWV0aG9kcyAoeyBuYW1lLCB0ZXN0SWQsIGhvb2tJZCwgZXZlbnREYXRhIH06IFJlcXVlc3RIb29rRXZlbnRBcmd1bWVudHMpOiB2b2lkIHtcbiAgICAgICAgaWYgKG5hbWUgPT09IFJlcXVlc3RIb29rTWV0aG9kTmFtZXMub25SZXF1ZXN0KVxuICAgICAgICAgICAgdGhpcy5fd3JhcFNldE1vY2tGbih7IHRlc3RJZCwgaG9va0lkLCBldmVudDogZXZlbnREYXRhIGFzIFJlcXVlc3RFdmVudCB9KTtcbiAgICAgICAgZWxzZSBpZiAobmFtZSA9PT0gUmVxdWVzdEhvb2tNZXRob2ROYW1lcy5fb25Db25maWd1cmVSZXNwb25zZSlcbiAgICAgICAgICAgIHRoaXMuX3dyYXBDb25maWd1cmVSZXNwb25zZUV2ZW50TWV0aG9kcyhldmVudERhdGEgYXMgQ29uZmlndXJlUmVzcG9uc2VFdmVudCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfd3JhcFNldE1vY2tGbiAoeyB0ZXN0SWQsIGhvb2tJZCwgZXZlbnQgfTogV3JhcFNldE1vY2tBcmd1bWVudHMpOiB2b2lkIHtcbiAgICAgICAgZXZlbnQuc2V0TW9jayA9IGFzeW5jIChtb2NrOiBSZXNwb25zZU1vY2spID0+IHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc2V0TW9jayh7XG4gICAgICAgICAgICAgICAgcmVzcG9uc2VFdmVudElkOiBldmVudC5pZCxcbiAgICAgICAgICAgICAgICBydWxlSWQ6ICAgICAgICAgIGV2ZW50LnJlcXVlc3RGaWx0ZXJSdWxlLmlkLFxuICAgICAgICAgICAgICAgIHRlc3RJZCxcbiAgICAgICAgICAgICAgICBob29rSWQsXG4gICAgICAgICAgICAgICAgbW9ja1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfd3JhcENvbmZpZ3VyZVJlc3BvbnNlRXZlbnRNZXRob2RzIChldmVudDogQ29uZmlndXJlUmVzcG9uc2VFdmVudCk6IHZvaWQge1xuICAgICAgICBldmVudC5zZXRIZWFkZXIgPSBhc3luYyAobmFtZTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNldEhlYWRlck9uQ29uZmlndXJlUmVzcG9uc2VFdmVudCh7XG4gICAgICAgICAgICAgICAgZXZlbnRJZDogICAgIGV2ZW50LmlkLFxuICAgICAgICAgICAgICAgIGhlYWRlck5hbWU6ICBuYW1lLFxuICAgICAgICAgICAgICAgIGhlYWRlclZhbHVlOiB2YWx1ZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgZXZlbnQucmVtb3ZlSGVhZGVyID0gYXN5bmMgKG5hbWU6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5yZW1vdmVIZWFkZXJPbkNvbmZpZ3VyZVJlc3BvbnNlRXZlbnQoe1xuICAgICAgICAgICAgICAgIGV2ZW50SWQ6ICAgIGV2ZW50LmlkLFxuICAgICAgICAgICAgICAgIGhlYWRlck5hbWU6IG5hbWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgX3Jlc3RvcmVSZXF1ZXN0RmlsdGVyUnVsZSAoZXZlbnQ6IFJlcXVlc3RFdmVudCB8IENvbmZpZ3VyZVJlc3BvbnNlRXZlbnQgfCBSZXNwb25zZUV2ZW50KTogdm9pZCB7XG4gICAgICAgIGV2ZW50LnJlcXVlc3RGaWx0ZXJSdWxlID0gUmVxdWVzdEZpbHRlclJ1bGUuZnJvbShldmVudC5yZXF1ZXN0RmlsdGVyUnVsZSBhcyBvYmplY3QpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBzZXRPcHRpb25zICh7IHZhbHVlIH06IFNldE9wdGlvbnNBcmd1bWVudHMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5zdGF0ZS5vcHRpb25zID0gdmFsdWU7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHJlYWR5ICgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5wcm94eS5jYWxsKHRoaXMucmVhZHkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBjbGVhblVwICgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgQ29tcGlsZXIuY2xlYW5VcCgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBnZXRUZXN0cyAoeyBzb3VyY2VMaXN0LCBjb21waWxlck9wdGlvbnMgfTogQ29tcGlsZXJBcmd1bWVudHMpOiBQcm9taXNlPFVuaXRzPiB7XG4gICAgICAgIGNvbnN0IGNvbXBpbGVyID0gbmV3IENvbXBpbGVyKHNvdXJjZUxpc3QsIGNvbXBpbGVyT3B0aW9ucyk7XG5cbiAgICAgICAgY29uc3QgdGVzdHMgPSBhd2FpdCBjb21waWxlci5nZXRUZXN0cygpO1xuICAgICAgICBjb25zdCB1bml0cyA9IGZsYXR0ZW5UZXN0U3RydWN0dXJlKHRlc3RzKTtcblxuICAgICAgICBPYmplY3QuYXNzaWduKHRoaXMuc3RhdGUudW5pdHMsIHVuaXRzKTtcblxuICAgICAgICByZXR1cm4gc2VyaWFsaXplVGVzdFN0cnVjdHVyZSh1bml0cyk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHJ1blRlc3QgKGFyZ3M6IFJ1blRlc3RBcmd1bWVudHMpOiBQcm9taXNlPHVua25vd24+IHtcbiAgICAgICAgY29uc3QgeyBpZCwgZnVuY3Rpb25OYW1lIH0gPSBhcmdzO1xuXG4gICAgICAgIGNvbnN0IHVuaXQgICAgICAgICAgID0gdGhpcy5zdGF0ZS51bml0c1tpZF07XG4gICAgICAgIGNvbnN0IGNvbnRleHQgICAgICAgID0gdGhpcy5fZ2V0Q29udGV4dChhcmdzKTtcbiAgICAgICAgY29uc3QgZnVuY3Rpb25PYmplY3QgPSB0aGlzLl9nZXRGdW5jdGlvbih1bml0LCBmdW5jdGlvbk5hbWUpO1xuXG4gICAgICAgIGlmICghZnVuY3Rpb25PYmplY3QpXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBmaW5kIHRoZSBcIiR7ZnVuY3Rpb25OYW1lfVwiIG9mICR7dHlwZW9mIHVuaXR9YCk7XG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IGZ1bmN0aW9uT2JqZWN0KGNvbnRleHQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBleGVjdXRlQWN0aW9uU3luYyAoeyBpZCwgYXBpTWV0aG9kTmFtZSwgY29tbWFuZCwgY2FsbHNpdGUgfTogRXhlY3V0ZUFjdGlvbkFyZ3VtZW50cyk6IHVua25vd24ge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm94eS5jYWxsU3luYyh0aGlzLmV4ZWN1dGVBY3Rpb24sIHsgaWQsIGFwaU1ldGhvZE5hbWUsIGNvbW1hbmQsIGNhbGxzaXRlIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBleGVjdXRlQWN0aW9uICh7IGlkLCBhcGlNZXRob2ROYW1lLCBjb21tYW5kLCBjYWxsc2l0ZSB9OiBFeGVjdXRlQWN0aW9uQXJndW1lbnRzKTogUHJvbWlzZTx1bmtub3duPiB7XG4gICAgICAgIHJldHVybiB0aGlzLnByb3h5LmNhbGwodGhpcy5leGVjdXRlQWN0aW9uLCB7IGlkLCBhcGlNZXRob2ROYW1lLCBjb21tYW5kLCBjYWxsc2l0ZSB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZXhlY3V0ZUNvbW1hbmQgKHsgY29tbWFuZCwgaWQgfTogRXhlY3V0ZUNvbW1hbmRBcmd1bWVudHMpOiBQcm9taXNlPHVua25vd24+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJveHkuY2FsbCh0aGlzLmV4ZWN1dGVDb21tYW5kLCB7IGlkLCBjb21tYW5kIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBvblJlcXVlc3RIb29rRXZlbnQgKHsgbmFtZSwgdGVzdElkLCBob29rSWQsIGV2ZW50RGF0YSB9OiBSZXF1ZXN0SG9va0V2ZW50QXJndW1lbnRzKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMuX3dyYXBFdmVudE1ldGhvZHMoeyBuYW1lLCB0ZXN0SWQsIGhvb2tJZCwgZXZlbnREYXRhIH0pO1xuICAgICAgICB0aGlzLl9yZXN0b3JlUmVxdWVzdEZpbHRlclJ1bGUoZXZlbnREYXRhKTtcblxuICAgICAgICBjb25zdCB0ZXN0ICAgICAgID0gdGhpcy5zdGF0ZS51bml0c1t0ZXN0SWRdIGFzIFRlc3Q7XG4gICAgICAgIGNvbnN0IHRhcmdldEhvb2sgPSB0ZXN0LnJlcXVlc3RIb29rcy5maW5kKGhvb2sgPT4gaG9vay5pZCA9PT0gaG9va0lkKSBhcyBSZXF1ZXN0SG9vaztcblxuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIGF3YWl0IHRhcmdldEhvb2tbbmFtZV0uY2FsbCh0YXJnZXRIb29rLCBldmVudERhdGEpO1xuXG4gICAgICAgIGlmIChuYW1lID09PSBSZXF1ZXN0SG9va01ldGhvZE5hbWVzLl9vbkNvbmZpZ3VyZVJlc3BvbnNlICYmIHRhcmdldEhvb2suX3Jlc3BvbnNlRXZlbnRDb25maWd1cmVPcHRzKSB7XG4gICAgICAgICAgICBjb25zdCB7IG9wdHMsIGlkOiBldmVudElkIH0gPSBldmVudERhdGEgYXMgQ29uZmlndXJlUmVzcG9uc2VFdmVudDtcblxuICAgICAgICAgICAgYXdhaXQgdGhpcy5zZXRDb25maWd1cmVSZXNwb25zZUV2ZW50T3B0aW9ucyh7IGV2ZW50SWQsIG9wdHMgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgc2V0TW9jayAoeyB0ZXN0SWQsIGhvb2tJZCwgcnVsZUlkLCByZXNwb25zZUV2ZW50SWQsIG1vY2sgfTogU2V0TW9ja0FyZ3VtZW50cyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLnByb3h5LmNhbGwodGhpcy5zZXRNb2NrLCB7IHRlc3RJZCwgaG9va0lkLCBydWxlSWQsIHJlc3BvbnNlRXZlbnRJZCwgbW9jayB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgc2V0Q29uZmlndXJlUmVzcG9uc2VFdmVudE9wdGlvbnMgKHsgZXZlbnRJZCwgb3B0cyB9OiBTZXRDb25maWd1cmVSZXNwb25zZUV2ZW50T3B0aW9uc0FyZ3VtZW50cyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLnByb3h5LmNhbGwodGhpcy5zZXRDb25maWd1cmVSZXNwb25zZUV2ZW50T3B0aW9ucywgeyBldmVudElkLCBvcHRzIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBzZXRIZWFkZXJPbkNvbmZpZ3VyZVJlc3BvbnNlRXZlbnQgKHsgZXZlbnRJZCwgaGVhZGVyTmFtZSwgaGVhZGVyVmFsdWUgfTogU2V0SGVhZGVyT25Db25maWd1cmVSZXNwb25zZUV2ZW50QXJndW1lbnRzKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMucHJveHkuY2FsbCh0aGlzLnNldEhlYWRlck9uQ29uZmlndXJlUmVzcG9uc2VFdmVudCwgeyBldmVudElkLCBoZWFkZXJOYW1lLCBoZWFkZXJWYWx1ZSB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgcmVtb3ZlSGVhZGVyT25Db25maWd1cmVSZXNwb25zZUV2ZW50ICh7IGV2ZW50SWQsIGhlYWRlck5hbWUgfTogUmVtb3ZlSGVhZGVyT25Db25maWd1cmVSZXNwb25zZUV2ZW50QXJndW1lbnRzKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMucHJveHkuY2FsbCh0aGlzLnJlbW92ZUhlYWRlck9uQ29uZmlndXJlUmVzcG9uc2VFdmVudCwgeyBldmVudElkLCBoZWFkZXJOYW1lIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBleGVjdXRlUmVxdWVzdEZpbHRlclJ1bGVQcmVkaWNhdGUgKHsgdGVzdElkLCBob29rSWQsIHJ1bGVJZCwgcmVxdWVzdEluZm8gfTogRXhlY3V0ZVJlcXVlc3RGaWx0ZXJSdWxlUHJlZGljYXRlQXJndW1lbnRzKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIGNvbnN0IHRlc3QgICAgICAgPSB0aGlzLnN0YXRlLnVuaXRzW3Rlc3RJZF0gYXMgVGVzdDtcbiAgICAgICAgY29uc3QgdGFyZ2V0SG9vayA9IHRlc3QucmVxdWVzdEhvb2tzLmZpbmQoaG9vayA9PiBob29rLmlkID09PSBob29rSWQpIGFzIFJlcXVlc3RIb29rO1xuICAgICAgICBjb25zdCB0YXJnZXRSdWxlID0gdGFyZ2V0SG9vay5fcmVxdWVzdEZpbHRlclJ1bGVzLmZpbmQocnVsZSA9PiBydWxlLmlkID09PSBydWxlSWQpIGFzIFJlcXVlc3RGaWx0ZXJSdWxlO1xuICAgICAgICBjb25zdCByZXN1bHQgICAgID0gYXdhaXQgdGFyZ2V0UnVsZS5vcHRpb25zLmNhbGwodGFyZ2V0UnVsZSwgcmVxdWVzdEluZm8pO1xuXG4gICAgICAgIHJldHVybiAhIXJlc3VsdDtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZXhlY3V0ZU1vY2tQcmVkaWNhdGUgKHsgdGVzdElkLCBob29rSWQsIHJ1bGVJZCwgcmVxdWVzdEluZm8sIHJlcyB9OiBFeGVjdXRlTW9ja1ByZWRpY2F0ZSk6IFByb21pc2U8SW5jb21pbmdNZXNzYWdlTGlrZUluaXRPcHRpb25zPiB7XG4gICAgICAgIGNvbnN0IHRlc3QgICAgICAgICA9IHRoaXMuc3RhdGUudW5pdHNbdGVzdElkXSBhcyBUZXN0O1xuICAgICAgICBjb25zdCByZXF1ZXN0TW9jayAgPSB0ZXN0LnJlcXVlc3RIb29rcy5maW5kKGhvb2sgPT4gaG9vay5pZCA9PT0gaG9va0lkKSBhcyBSZXF1ZXN0TW9jaztcbiAgICAgICAgY29uc3QgcmVzcG9uc2VNb2NrID0gcmVxdWVzdE1vY2subW9ja3MuZ2V0KHJ1bGVJZCkgYXMgUmVzcG9uc2VNb2NrO1xuXG4gICAgICAgIHJlc3BvbnNlTW9ja1NldEJvZHlNZXRob2QuYWRkKHJlcyk7XG5cbiAgICAgICAgcmVzID0gT2JqZWN0LmFzc2lnbihyZXMsIGF3YWl0IChyZXNwb25zZU1vY2suYm9keSBhcyBGdW5jdGlvbikocmVxdWVzdEluZm8sIHJlcykpO1xuXG4gICAgICAgIHJlc3BvbnNlTW9ja1NldEJvZHlNZXRob2QucmVtb3ZlKHJlcyk7XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0V2FybmluZ01lc3NhZ2VzICh7IHRlc3RSdW5JZCB9OiBHZXRXYXJuaW5nTWVzc2FnZXNBcmd1bWVudHMpOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgICAgIGNvbnN0IHRlc3RSdW5Qcm94eSA9IHRoaXMuc3RhdGUudGVzdFJ1bnNbdGVzdFJ1bklkXTtcblxuICAgICAgICByZXR1cm4gdGVzdFJ1blByb3h5Lndhcm5pbmdMb2cubWVzc2FnZXM7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGFkZFJlcXVlc3RFdmVudExpc3RlbmVycyAoIHsgaG9va0lkLCBob29rQ2xhc3NOYW1lLCBydWxlcyB9OiBBZGRSZXF1ZXN0RXZlbnRMaXN0ZW5lcnNBcmd1bWVudHMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucHJveHkuY2FsbCh0aGlzLmFkZFJlcXVlc3RFdmVudExpc3RlbmVycywgeyBob29rSWQsIGhvb2tDbGFzc05hbWUsIHJ1bGVzIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyByZW1vdmVSZXF1ZXN0RXZlbnRMaXN0ZW5lcnMgKHsgcnVsZXMgfTogUmVtb3ZlUmVxdWVzdEV2ZW50TGlzdGVuZXJzQXJndW1lbnRzKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLnByb3h5LmNhbGwodGhpcy5yZW1vdmVSZXF1ZXN0RXZlbnRMaXN0ZW5lcnMsIHsgcnVsZXMgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGluaXRpYWxpemVUZXN0UnVuUHJveHkgKHsgdGVzdFJ1bklkLCB0ZXN0SWQgfTogSW5pdGlhbGl6ZVRlc3RSdW5Qcm94eUFyZ3VtZW50cyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCB0ZXN0ID0gdGhpcy5zdGF0ZS51bml0c1t0ZXN0SWRdIGFzIFRlc3Q7XG5cbiAgICAgICAgY29uc3QgdGVzdFJ1blByb3h5ID0gbmV3IFRlc3RSdW5Qcm94eSh7XG4gICAgICAgICAgICBkaXNwYXRjaGVyOiB0aGlzLFxuICAgICAgICAgICAgaWQ6ICAgICAgICAgdGVzdFJ1bklkLFxuICAgICAgICAgICAgb3B0aW9uczogICAgdGhpcy5zdGF0ZS5vcHRpb25zLFxuICAgICAgICAgICAgdGVzdFxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnN0YXRlLnRlc3RSdW5zW3Rlc3RSdW5JZF0gPSB0ZXN0UnVuUHJveHk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBuZXcgQ29tcGlsZXJTZXJ2aWNlKCk7XG4iXX0=
226
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZXJ2aWNlcy9jb21waWxlci9zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsNENBQW9CO0FBQ3BCLDhEQUFzQztBQUN0QyxzRUFBNEM7QUFFNUMsb0VBT3lDO0FBRXpDLDZCQUljO0FBRWQsOENBQThDO0FBQzlDLHNEQUEwRDtBQUMxRCw0RUFBa0Q7QUFFbEQseUNBcUJvQjtBQUtwQixxRUFBNEM7QUFFNUMsa0dBQStFO0FBRS9FLDZEQVE2QjtBQUs3Qiw0QkFBZ0IsQ0FBQyxPQUFPLENBQUM7SUFDckIsV0FBVyxFQUFlLElBQUk7SUFDOUIsd0JBQXdCLEVBQUUsS0FBSztJQUMvQixXQUFXLEVBQWUsTUFBTTtDQUNuQyxDQUFDLENBQUM7QUFtQkgsTUFBTSxlQUFlO0lBSWpCO1FBQ0ksT0FBTyxDQUFDLEtBQUssR0FBRyx1QkFBWSxDQUFDLE9BQU8sQ0FBQztRQUVyQyxNQUFNLEtBQUssR0FBSSxZQUFFLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLHFCQUFnQixFQUFFLENBQUMsQ0FBQztRQUNqRSxNQUFNLE1BQU0sR0FBRyxZQUFFLENBQUMsaUJBQWlCLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLHNCQUFpQixFQUFFLENBQUMsQ0FBQztRQUVuRSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksZ0JBQVEsQ0FBQyxJQUFJLDRCQUFnQixDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsb0JBQWUsQ0FBQyxDQUFDLENBQUM7UUFDaEYsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFFL0IsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNqQixDQUFDO0lBRU8sVUFBVTtRQUNkLE9BQU87WUFDSCxRQUFRLEVB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VUFBVSxDQUFDLFFBQVEsQ0FBQztJQUM1QyxDQUFDO0lBRU0sS0FBSyxDQUFDLHdCQUF3QixDQUFHLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQXFDO1FBQ3ZHLE9BQU8sTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsRUFBRSxNQUFNLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDbEcsQ0FBQztJQUVNLEtBQUssQ0FBQywyQkFBMkIsQ0FBRSxFQUFFLEtBQUssRUFBd0M7UUFDckYsT0FBTyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQywyQkFBMkIsRUFBRSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDOUUsQ0FBQztJQUVNLEtBQUssQ0FBQyxxQkFBcUIsQ0FBRSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQWtDO1FBQ3JGLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBUyxDQUFDO1FBRTlDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDOUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3JDLENBQUM7Q0FDSjtBQUVELGtCQUFlLElBQUksZUFBZSxFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZnMgZnJvbSAnZnMnO1xuaW1wb3J0IENvbXBpbGVyIGZyb20gJy4uLy4uL2NvbXBpbGVyJztcbmltcG9ydCBUZXN0UnVuUHJveHkgZnJvbSAnLi90ZXN0LXJ1bi1wcm94eSc7XG5cbmltcG9ydCB7XG4gICAgZmxhdHRlbiBhcyBmbGF0dGVuVGVzdFN0cnVjdHVyZSxcbiAgICBpc0ZpeHR1cmUsXG4gICAgaXNUZXN0LFxuICAgIHNlcmlhbGl6ZSBhcyBzZXJpYWxpemVUZXN0U3RydWN0dXJlLFxuICAgIFVuaXQsXG4gICAgVW5pdHNcbn0gZnJvbSAnLi4vc2VyaWFsaXphdGlvbi90ZXN0LXN0cnVjdHVyZSc7XG5cbmltcG9ydCB7XG4gICAgU0VSVklDRV9JTlBVVF9GRCxcbiAgICBTRVJWSUNFX09VVFBVVF9GRCxcbiAgICBTRVJWSUNFX1NZTkNfRkRcbn0gZnJvbSAnLi9pbyc7XG5cbmltcG9ydCB7IElQQ1Byb3h5IH0gZnJvbSAnLi4vdXRpbHMvaXBjL3Byb3h5JztcbmltcG9ydCB7IFNlcnZpY2VUcmFuc3BvcnQgfSBmcm9tICcuLi91dGlscy9pcGMvdHJhbnNwb3J0JztcbmltcG9ydCBzb3VyY2VNYXBTdXBwb3J0IGZyb20gJ3NvdXJjZS1tYXAtc3VwcG9ydCc7XG5cbmltcG9ydCB7XG4gICAgQ29tcGlsZXJQcm90b2NvbCxcbiAgICBFeGVjdXRlQWN0aW9uQXJndW1lbnRzLFxuICAgIEV4ZWN1dGVDb21tYW5kQXJndW1lbnRzLFxuICAgIEV4ZWN1dGVNb2NrUHJlZGljYXRlLFxuICAgIEV4ZWN1dGVSZXF1ZXN0RmlsdGVyUnVsZVByZWRpY2F0ZUFyZ3VtZW50cyxcbiAgICBGdW5jdGlvblByb3BlcnRpZXMsXG4gICAgaXNGaXh0dXJlRnVuY3Rpb25Qcm9wZXJ0eSxcbiAgICBpc1Rlc3RGdW5jdGlvblByb3BlcnR5LFxuICAgIFJlbW92ZUhlYWRlck9uQ29uZmlndXJlUmVzcG9uc2VFdmVudEFyZ3VtZW50cyxcbiAgICBSZXF1ZXN0SG9va0V2ZW50QXJndW1lbnRzLFxuICAgIFJlcXVlc3RIb29rTG9jYXRvcixcbiAgICBSdW5UZXN0QXJndW1lbnRzLFxuICAgIFNldENvbmZpZ3VyZVJlc3BvbnNlRXZlbnRPcHRpb25zQXJndW1lbnRzLFxuICAgIFNldEhlYWRlck9uQ29uZmlndXJlUmVzcG9uc2VFdmVudEFyZ3VtZW50cyxcbiAgICBTZXRNb2NrQXJndW1lbnRzLFxuICAgIFNldE9wdGlvbnNBcmd1bWVudHMsXG4gICAgR2V0V2FybmluZ01lc3NhZ2VzQXJndW1lbnRzLFxuICAgIEFkZFJlcXVlc3RFdmVudExpc3RlbmVyc0FyZ3VtZW50cyxcbiAgICBSZW1vdmVSZXF1ZXN0RXZlbnRMaXN0ZW5lcnNBcmd1bWVudHMsXG4gICAgSW5pdGlhbGl6ZVRlc3RSdW5EYXRhQXJndW1lbnRzXG59IGZyb20gJy4vcHJvdG9jb2wnO1xuXG5pbXBvcnQgeyBDb21waWxlckFyZ3VtZW50cyB9IGZyb20gJy4uLy4uL2NvbXBpbGVyL2ludGVyZmFjZXMnO1xuaW1wb3J0IEZpeHR1cmUgZnJvbSAnLi4vLi4vYXBpL3N0cnVjdHVyZS9maXh0dXJlJztcbmltcG9ydCB7IERpY3Rpb25hcnkgfSBmcm9tICcuLi8uLi9jb25maWd1cmF0aW9uL2ludGVyZmFjZXMnO1xuaW1wb3J0IFByb2Nlc3NUaXRsZSBmcm9tICcuLi9wcm9jZXNzLXRpdGxlJztcbmltcG9ydCBUZXN0IGZyb20gJy4uLy4uL2FwaS9zdHJ1Y3R1cmUvdGVzdCc7XG5pbXBvcnQgUmVxdWVzdEhvb2tNZXRob2ROYW1lcyBmcm9tICcuLi8uLi9hcGkvcmVxdWVzdC1ob29rcy9ob29rLW1ldGhvZC1uYW1lcyc7XG5cbmltcG9ydCB7XG4gICAgQ29uZmlndXJlUmVzcG9uc2VFdmVudCxcbiAgICBJbmNvbWluZ01lc3NhZ2VMaWtlSW5pdE9wdGlvbnMsXG4gICAgUmVxdWVzdEV2ZW50LFxuICAgIFJlcXVlc3RGaWx0ZXJSdWxlLFxuICAgIFJlc3BvbnNlRXZlbnQsXG4gICAgUmVzcG9uc2VNb2NrLFxuICAgIHJlc3BvbnNlTW9ja1NldEJvZHlNZXRob2Rcbn0gZnJvbSAndGVzdGNhZmUtaGFtbWVyaGVhZCc7XG5cbmltcG9ydCBSZXF1ZXN0SG9vayBmcm9tICcuLi8uLi9hcGkvcmVxdWVzdC1ob29rcy9ob29rJztcbmltcG9ydCBSZXF1ZXN0TW9jayBmcm9tICcuLi8uLi9hcGkvcmVxdWVzdC1ob29rcy9yZXF1ZXN0LW1vY2snO1xuXG5zb3VyY2VNYXBTdXBwb3J0Lmluc3RhbGwoe1xuICAgIGhvb2tSZXF1aXJlOiAgICAgICAgICAgICAgdHJ1ZSxcbiAgICBoYW5kbGVVbmNhdWdodEV4Y2VwdGlvbnM6IGZhbHNlLFxuICAgIGVudmlyb25tZW50OiAgICAgICAgICAgICAgJ25vZGUnXG59KTtcblxuaW50ZXJmYWNlIFNlcnZpY2VTdGF0ZSB7XG4gICAgdGVzdFJ1bnM6IHsgW2lkOiBzdHJpbmddOiBUZXN0UnVuUHJveHkgfTtcbiAgICBmaXh0dXJlQ3R4czogeyBbaWQ6IHN0cmluZ106IG9iamVjdCB9O1xuICAgIHVuaXRzOiBVbml0cztcbiAgICBvcHRpb25zOiBEaWN0aW9uYXJ5PE9wdGlvblZhbHVlPjtcbn1cblxuaW50ZXJmYWNlIFRlc3RSdW5Qcm94eUNyZWF0aW9uQXJncyB7XG4gICAgdGVzdFJ1bklkOiBzdHJpbmc7XG4gICAgdGVzdElkOiBzdHJpbmc7XG4gICAgZml4dHVyZUN0eDogdW5rbm93bjtcbn1cblxuaW50ZXJmYWNlIFdyYXBTZXRNb2NrQXJndW1lbnRzIGV4dGVuZHMgUmVxdWVzdEhvb2tMb2NhdG9yIHtcbiAgICBldmVudDogUmVxdWVzdEV2ZW50O1xufVxuXG5jbGFzcyBDb21waWxlclNlcnZpY2UgaW1wbGVtZW50cyBDb21waWxlclByb3RvY29sIHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IHByb3h5OiBJUENQcm94eTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IHN0YXRlOiBTZXJ2aWNlU3RhdGU7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBwcm9jZXNzLnRpdGxlID0gUHJvY2Vzc1RpdGxlLnNlcnZpY2U7XG5cbiAgICAgICAgY29uc3QgaW5wdXQgID0gZnMuY3JlYXRlUmVhZFN0cmVhbSgnJywgeyBmZDogU0VSVklDRV9JTlBVVF9GRCB9KTtcbiAgICAgICAgY29uc3Qgb3V0cHV0ID0gZnMuY3JlYXRlV3JpdGVTdHJlYW0oJycsIHsgZmQ6IFNFUlZJQ0VfT1VUUFVUX0ZEIH0pO1xuXG4gICAgICAgIHRoaXMucHJveHkgPSBuZXcgSVBDUHJveHkobmV3IFNlcnZpY2VUcmFuc3BvcnQoaW5wdXQsIG91dHB1dCwgU0VSVklDRV9TWU5DX0ZEKSk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB0aGlzLl9pbml0U3RhdGUoKTtcblxuICAgICAgICB0aGlzLl9zZXR1cFJvdXRlcygpO1xuICAgICAgICB0aGlzLnJlYWR5KCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfaW5pdFN0YXRlICgpOiBTZXJ2aWNlU3RhdGUge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdGVzdFJ1bnM6ICAgIHt9LFxuICAgICAgICAgICAgZml4dHVyZUN0eHM6IHt9LFxuICAgICAgICAgICAgdW5pdHM6ICAgICAgIHt9LFxuICAgICAgICAgICAgb3B0aW9uczogICAgIHt9XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZ2V0Rml4dHVyZUN0eCAoeyBpZCB9OiBSdW5UZXN0QXJndW1lbnRzKTogdW5rbm93biB7XG4gICAgICAgIGNvbnN0IHVuaXQgPSB0aGlzLnN0YXRlLnVuaXRzW2lkXTtcblxuICAgICAgICBjb25zdCBmaXh0dXJlSWQgPSBpc1Rlc3QodW5pdCkgPyB1bml0LmZpeHR1cmUuaWQgOiAodW5pdCBhcyBGaXh0dXJlKS5pZDtcblxuICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZS5maXh0dXJlQ3R4c1tmaXh0dXJlSWRdO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2dldFRlc3RDdHggKHsgdGVzdFJ1bklkIH06IFJ1blRlc3RBcmd1bWVudHMsIHRlc3Q6IFRlc3QpOiBUZXN0UnVuUHJveHkge1xuICAgICAgICBjb25zdCB0ZXN0UnVuUHJveHkgICAgID0gdGhpcy5zdGF0ZS50ZXN0UnVuc1t0ZXN0UnVuSWRdO1xuICAgICAgICBjb25zdCB0YXJnZXRGaXh0dXJlQ3R4ID0gdGhpcy5zdGF0ZS5maXh0dXJlQ3R4c1t0ZXN0LmZpeHR1cmUuaWRdO1xuXG4gICAgICAgIHRlc3RSdW5Qcm94eS5maXh0dXJlQ3R4ID0gdGFyZ2V0Rml4dHVyZUN0eDtcblxuICAgICAgICByZXR1cm4gdGVzdFJ1blByb3h5O1xuICAgIH1cblxuICAgIHByaXZhdGUgX2dldENvbnRleHQgKGFyZ3M6IFJ1blRlc3RBcmd1bWVudHMsIHVuaXQ6IFVuaXQpOiBUZXN0UnVuUHJveHkgfCB1bmtub3duIHtcbiAgICAgICAgY29uc3QgeyB0ZXN0UnVuSWQgfSA9IGFyZ3M7XG5cbiAgICAgICAgaWYgKHRlc3RSdW5JZClcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRUZXN0Q3R4KGFyZ3MsIHVuaXQgYXMgVGVzdCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldEZpeHR1cmVDdHgoYXJncyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfc2V0dXBSb3V0ZXMgKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnByb3h5LnJlZ2lzdGVyKFtcbiAgICAgICAgICAgIHRoaXMuZ2V0VGVzdHMsXG4gICAgICAgICAgICB0aGlzLnJ1blRlc3RGbixcbiAgICAgICAgICAgIHRoaXMuY2xlYW5VcCxcbiAgICAgICAgICAgIHRoaXMuc2V0T3B0aW9ucyxcbiAgICAgICAgICAgIHRoaXMub25SZXF1ZXN0SG9va0V2ZW50LFxuICAgICAgICAgICAgdGhpcy5zZXRNb2NrLFxuICAgICAgICAgICAgdGhpcy5zZXRDb25maWd1cmVSZXNwb25zZUV2ZW50T3B0aW9ucyxcbiAgICAgICAgICAgIHRoaXMuc2V0SGVhZGVyT25Db25maWd1cmVSZXNwb25zZUV2ZW50LFxuICAgICAgICAgICAgdGhpcy5yZW1vdmVIZWFkZXJPbkNvbmZpZ3VyZVJlc3BvbnNlRXZlbnQsXG4gICAgICAgICAgICB0aGlzLmV4ZWN1dGVSZXF1ZXN0RmlsdGVyUnVsZVByZWRpY2F0ZSxcbiAgICAgICAgICAgIHRoaXMuZXhlY3V0ZU1vY2tQcmVkaWNhdGUsXG4gICAgICAgICAgICB0aGlzLmdldFdhcm5pbmdNZXNzYWdlcyxcbiAgICAgICAgICAgIHRoaXMuYWRkUmVxdWVzdEV2ZW50TGlzdGVuZXJzLFxuICAgICAgICAgICAgdGhpcy5yZW1vdmVSZXF1ZXN0RXZlbnRMaXN0ZW5lcnMsXG4gICAgICAgICAgICB0aGlzLmluaXRpYWxpemVUZXN0UnVuRGF0YVxuICAgICAgICBdLCB0aGlzKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9nZXRGdW5jdGlvbiAodW5pdDogVW5pdCwgZnVuY3Rpb25OYW1lOiBGdW5jdGlvblByb3BlcnRpZXMpOiBGdW5jdGlvbnxudWxsIHtcbiAgICAgICAgaWYgKGlzVGVzdCh1bml0KSAmJiBpc1Rlc3RGdW5jdGlvblByb3BlcnR5KGZ1bmN0aW9uTmFtZSkpXG4gICAgICAgICAgICByZXR1cm4gdW5pdFtmdW5jdGlvbk5hbWVdO1xuXG4gICAgICAgIGlmIChpc0ZpeHR1cmUodW5pdCkgJiYgaXNGaXh0dXJlRnVuY3Rpb25Qcm9wZXJ0eShmdW5jdGlvbk5hbWUpKVxuICAgICAgICAgICAgcmV0dXJuIHVuaXRbZnVuY3Rpb25OYW1lXTtcblxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBmaW5kICcke2Z1bmN0aW9uTmFtZX0nIGZ1bmN0aW9uIGZvciAke3R5cGVvZiB1bml0fWApO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3dyYXBFdmVudE1ldGhvZHMgKHsgbmFtZSwgdGVzdElkLCBob29rSWQsIGV2ZW50RGF0YSB9OiBSZXF1ZXN0SG9va0V2ZW50QXJndW1lbnRzKTogdm9pZCB7XG4gICAgICAgIGlmIChuYW1lID09PSBSZXF1ZXN0SG9va01ldGhvZE5hbWVzLm9uUmVxdWVzdClcbiAgICAgICAgICAgIHRoaXMuX3dyYXBTZXRNb2NrRm4oeyB0ZXN0SWQsIGhvb2tJZCwgZXZlbnQ6IGV2ZW50RGF0YSBhcyBSZXF1ZXN0RXZlbnQgfSk7XG4gICAgICAgIGVsc2UgaWYgKG5hbWUgPT09IFJlcXVlc3RIb29rTWV0aG9kTmFtZXMuX29uQ29uZmlndXJlUmVzcG9uc2UpXG4gICAgICAgICAgICB0aGlzLl93cmFwQ29uZmlndXJlUmVzcG9uc2VFdmVudE1ldGhvZHMoZXZlbnREYXRhIGFzIENvbmZpZ3VyZVJlc3BvbnNlRXZlbnQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3dyYXBTZXRNb2NrRm4gKHsgdGVzdElkLCBob29rSWQsIGV2ZW50IH06IFdyYXBTZXRNb2NrQXJndW1lbnRzKTogdm9pZCB7XG4gICAgICAgIGV2ZW50LnNldE1vY2sgPSBhc3luYyAobW9jazogUmVzcG9uc2VNb2NrKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNldE1vY2soe1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlRXZlbnRJZDogZXZlbnQuaWQsXG4gICAgICAgICAgICAgICAgcnVsZUlkOiAgICAgICAgICBldmVudC5yZXF1ZXN0RmlsdGVyUnVsZS5pZCxcbiAgICAgICAgICAgICAgICB0ZXN0SWQsXG4gICAgICAgICAgICAgICAgaG9va0lkLFxuICAgICAgICAgICAgICAgIG1vY2tcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgX3dyYXBDb25maWd1cmVSZXNwb25zZUV2ZW50TWV0aG9kcyAoZXZlbnQ6IENvbmZpZ3VyZVJlc3BvbnNlRXZlbnQpOiB2b2lkIHtcbiAgICAgICAgZXZlbnQuc2V0SGVhZGVyID0gYXN5bmMgKG5hbWU6IHN0cmluZywgdmFsdWU6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5zZXRIZWFkZXJPbkNvbmZpZ3VyZVJlc3BvbnNlRXZlbnQoe1xuICAgICAgICAgICAgICAgIGV2ZW50SWQ6ICAgICBldmVudC5pZCxcbiAgICAgICAgICAgICAgICBoZWFkZXJOYW1lOiAgbmFtZSxcbiAgICAgICAgICAgICAgICBoZWFkZXJWYWx1ZTogdmFsdWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIGV2ZW50LnJlbW92ZUhlYWRlciA9IGFzeW5jIChuYW1lOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucmVtb3ZlSGVhZGVyT25Db25maWd1cmVSZXNwb25zZUV2ZW50KHtcbiAgICAgICAgICAgICAgICBldmVudElkOiAgICBldmVudC5pZCxcbiAgICAgICAgICAgICAgICBoZWFkZXJOYW1lOiBuYW1lXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9yZXN0b3JlUmVxdWVzdEZpbHRlclJ1bGUgKGV2ZW50OiBSZXF1ZXN0RXZlbnQgfCBDb25maWd1cmVSZXNwb25zZUV2ZW50IHwgUmVzcG9uc2VFdmVudCk6IHZvaWQge1xuICAgICAgICBldmVudC5yZXF1ZXN0RmlsdGVyUnVsZSA9IFJlcXVlc3RGaWx0ZXJSdWxlLmZyb20oZXZlbnQucmVxdWVzdEZpbHRlclJ1bGUgYXMgb2JqZWN0KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9pbml0aWFsaXplVGVzdFJ1blByb3h5ICh0ZXN0UnVuSWQ6IHN0cmluZywgdGVzdDogVGVzdCk6IHZvaWQge1xuICAgICAgICBjb25zdCB0ZXN0UnVuUHJveHkgPSBuZXcgVGVzdFJ1blByb3h5KHtcbiAgICAgICAgICAgIGRpc3BhdGNoZXI6IHRoaXMsXG4gICAgICAgICAgICBpZDogICAgICAgICB0ZXN0UnVuSWQsXG4gICAgICAgICAgICBvcHRpb25zOiAgICB0aGlzLnN0YXRlLm9wdGlvbnMsXG4gICAgICAgICAgICB0ZXN0XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuc3RhdGUudGVzdFJ1bnNbdGVzdFJ1bklkXSA9IHRlc3RSdW5Qcm94eTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9pbml0aWFsaXplRml4dHVyZUN0eCAodGVzdDogVGVzdCk6IHZvaWQge1xuICAgICAgICBjb25zdCBmaXh0dXJlSWQgPSB0ZXN0LmZpeHR1cmUuaWQ7XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuZml4dHVyZUN0eHNbZml4dHVyZUlkXSlcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICB0aGlzLnN0YXRlLmZpeHR1cmVDdHhzW2ZpeHR1cmVJZF0gPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBzZXRPcHRpb25zICh7IHZhbHVlIH06IFNldE9wdGlvbnNBcmd1bWVudHMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5zdGF0ZS5vcHRpb25zID0gdmFsdWU7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHJlYWR5ICgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5wcm94eS5jYWxsKHRoaXMucmVhZHkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBjbGVhblVwICgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgQ29tcGlsZXIuY2xlYW5VcCgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBnZXRUZXN0cyAoeyBzb3VyY2VMaXN0LCBjb21waWxlck9wdGlvbnMgfTogQ29tcGlsZXJBcmd1bWVudHMpOiBQcm9taXNlPFVuaXRzPiB7XG4gICAgICAgIGNvbnN0IGNvbXBpbGVyID0gbmV3IENvbXBpbGVyKHNvdXJjZUxpc3QsIGNvbXBpbGVyT3B0aW9ucyk7XG5cbiAgICAgICAgY29uc3QgdGVzdHMgPSBhd2FpdCBjb21waWxlci5nZXRUZXN0cygpO1xuICAgICAgICBjb25zdCB1bml0cyA9IGZsYXR0ZW5UZXN0U3RydWN0dXJlKHRlc3RzKTtcblxuICAgICAgICBPYmplY3QuYXNzaWduKHRoaXMuc3RhdGUudW5pdHMsIHVuaXRzKTtcblxuICAgICAgICByZXR1cm4gc2VyaWFsaXplVGVzdFN0cnVjdHVyZSh1bml0cyk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHJ1blRlc3RGbiAoYXJnczogUnVuVGVzdEFyZ3VtZW50cyk6IFByb21pc2U8dW5rbm93bj4ge1xuICAgICAgICBjb25zdCB7IGlkLCBmdW5jdGlvbk5hbWUgfSA9IGFyZ3M7XG5cbiAgICAgICAgY29uc3QgdW5pdCAgICAgICAgICAgPSB0aGlzLnN0YXRlLnVuaXRzW2lkXTtcbiAgICAgICAgY29uc3QgY29udGV4dCAgICAgICAgPSB0aGlzLl9nZXRDb250ZXh0KGFyZ3MsIHVuaXQpO1xuICAgICAgICBjb25zdCBmdW5jdGlvbk9iamVjdCA9IHRoaXMuX2dldEZ1bmN0aW9uKHVuaXQsIGZ1bmN0aW9uTmFtZSk7XG5cbiAgICAgICAgaWYgKCFmdW5jdGlvbk9iamVjdClcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGZpbmQgdGhlIFwiJHtmdW5jdGlvbk5hbWV9XCIgb2YgJHt0eXBlb2YgdW5pdH1gKTtcblxuICAgICAgICByZXR1cm4gYXdhaXQgZnVuY3Rpb25PYmplY3QoY29udGV4dCk7XG4gICAgfVxuXG4gICAgcHVibGljIGV4ZWN1dGVBY3Rpb25TeW5jICh7IGlkLCBhcGlNZXRob2ROYW1lLCBjb21tYW5kLCBjYWxsc2l0ZSB9OiBFeGVjdXRlQWN0aW9uQXJndW1lbnRzKTogdW5rbm93biB7XG4gICAgICAgIHJldHVybiB0aGlzLnByb3h5LmNhbGxTeW5jKHRoaXMuZXhlY3V0ZUFjdGlvbiwgeyBpZCwgYXBpTWV0aG9kTmFtZSwgY29tbWFuZCwgY2FsbHNpdGUgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGV4ZWN1dGVBY3Rpb24gKHsgaWQsIGFwaU1ldGhvZE5hbWUsIGNvbW1hbmQsIGNhbGxzaXRlIH06IEV4ZWN1dGVBY3Rpb25Bcmd1bWVudHMpOiBQcm9taXNlPHVua25vd24+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJveHkuY2FsbCh0aGlzLmV4ZWN1dGVBY3Rpb24sIHsgaWQsIGFwaU1ldGhvZE5hbWUsIGNvbW1hbmQsIGNhbGxzaXRlIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBleGVjdXRlQ29tbWFuZCAoeyBjb21tYW5kLCBpZCB9OiBFeGVjdXRlQ29tbWFuZEFyZ3VtZW50cyk6IFByb21pc2U8dW5rbm93bj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm94eS5jYWxsKHRoaXMuZXhlY3V0ZUNvbW1hbmQsIHsgaWQsIGNvbW1hbmQgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIG9uUmVxdWVzdEhvb2tFdmVudCAoeyBuYW1lLCB0ZXN0SWQsIGhvb2tJZCwgZXZlbnREYXRhIH06IFJlcXVlc3RIb29rRXZlbnRBcmd1bWVudHMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5fd3JhcEV2ZW50TWV0aG9kcyh7IG5hbWUsIHRlc3RJZCwgaG9va0lkLCBldmVudERhdGEgfSk7XG4gICAgICAgIHRoaXMuX3Jlc3RvcmVSZXF1ZXN0RmlsdGVyUnVsZShldmVudERhdGEpO1xuXG4gICAgICAgIGNvbnN0IHRlc3QgICAgICAgPSB0aGlzLnN0YXRlLnVuaXRzW3Rlc3RJZF0gYXMgVGVzdDtcbiAgICAgICAgY29uc3QgdGFyZ2V0SG9vayA9IHRlc3QucmVxdWVzdEhvb2tzLmZpbmQoaG9vayA9PiBob29rLmlkID09PSBob29rSWQpIGFzIFJlcXVlc3RIb29rO1xuXG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgYXdhaXQgdGFyZ2V0SG9va1tuYW1lXS5jYWxsKHRhcmdldEhvb2ssIGV2ZW50RGF0YSk7XG5cbiAgICAgICAgaWYgKG5hbWUgPT09IFJlcXVlc3RIb29rTWV0aG9kTmFtZXMuX29uQ29uZmlndXJlUmVzcG9uc2UgJiYgdGFyZ2V0SG9vay5fcmVzcG9uc2VFdmVudENvbmZpZ3VyZU9wdHMpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgb3B0cywgaWQ6IGV2ZW50SWQgfSA9IGV2ZW50RGF0YSBhcyBDb25maWd1cmVSZXNwb25zZUV2ZW50O1xuXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNldENvbmZpZ3VyZVJlc3BvbnNlRXZlbnRPcHRpb25zKHsgZXZlbnRJZCwgb3B0cyB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBzZXRNb2NrICh7IHRlc3RJZCwgaG9va0lkLCBydWxlSWQsIHJlc3BvbnNlRXZlbnRJZCwgbW9jayB9OiBTZXRNb2NrQXJndW1lbnRzKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMucHJveHkuY2FsbCh0aGlzLnNldE1vY2ssIHsgdGVzdElkLCBob29rSWQsIHJ1bGVJZCwgcmVzcG9uc2VFdmVudElkLCBtb2NrIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBzZXRDb25maWd1cmVSZXNwb25zZUV2ZW50T3B0aW9ucyAoeyBldmVudElkLCBvcHRzIH06IFNldENvbmZpZ3VyZVJlc3BvbnNlRXZlbnRPcHRpb25zQXJndW1lbnRzKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHRoaXMucHJveHkuY2FsbCh0aGlzLnNldENvbmZpZ3VyZVJlc3BvbnNlRXZlbnRPcHRpb25zLCB7IGV2ZW50SWQsIG9wdHMgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHNldEhlYWRlck9uQ29uZmlndXJlUmVzcG9uc2VFdmVudCAoeyBldmVudElkLCBoZWFkZXJOYW1lLCBoZWFkZXJWYWx1ZSB9OiBTZXRIZWFkZXJPbkNvbmZpZ3VyZVJlc3BvbnNlRXZlbnRBcmd1bWVudHMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5wcm94eS5jYWxsKHRoaXMuc2V0SGVhZGVyT25Db25maWd1cmVSZXNwb25zZUV2ZW50LCB7IGV2ZW50SWQsIGhlYWRlck5hbWUsIGhlYWRlclZhbHVlIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyByZW1vdmVIZWFkZXJPbkNvbmZpZ3VyZVJlc3BvbnNlRXZlbnQgKHsgZXZlbnRJZCwgaGVhZGVyTmFtZSB9OiBSZW1vdmVIZWFkZXJPbkNvbmZpZ3VyZVJlc3BvbnNlRXZlbnRBcmd1bWVudHMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5wcm94eS5jYWxsKHRoaXMucmVtb3ZlSGVhZGVyT25Db25maWd1cmVSZXNwb25zZUV2ZW50LCB7IGV2ZW50SWQsIGhlYWRlck5hbWUgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGV4ZWN1dGVSZXF1ZXN0RmlsdGVyUnVsZVByZWRpY2F0ZSAoeyB0ZXN0SWQsIGhvb2tJZCwgcnVsZUlkLCByZXF1ZXN0SW5mbyB9OiBFeGVjdXRlUmVxdWVzdEZpbHRlclJ1bGVQcmVkaWNhdGVBcmd1bWVudHMpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgICAgY29uc3QgdGVzdCAgICAgICA9IHRoaXMuc3RhdGUudW5pdHNbdGVzdElkXSBhcyBUZXN0O1xuICAgICAgICBjb25zdCB0YXJnZXRIb29rID0gdGVzdC5yZXF1ZXN0SG9va3MuZmluZChob29rID0+IGhvb2suaWQgPT09IGhvb2tJZCkgYXMgUmVxdWVzdEhvb2s7XG4gICAgICAgIGNvbnN0IHRhcmdldFJ1bGUgPSB0YXJnZXRIb29rLl9yZXF1ZXN0RmlsdGVyUnVsZXMuZmluZChydWxlID0+IHJ1bGUuaWQgPT09IHJ1bGVJZCkgYXMgUmVxdWVzdEZpbHRlclJ1bGU7XG4gICAgICAgIGNvbnN0IHJlc3VsdCAgICAgPSBhd2FpdCB0YXJnZXRSdWxlLm9wdGlvbnMuY2FsbCh0YXJnZXRSdWxlLCByZXF1ZXN0SW5mbyk7XG5cbiAgICAgICAgcmV0dXJuICEhcmVzdWx0O1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBleGVjdXRlTW9ja1ByZWRpY2F0ZSAoeyB0ZXN0SWQsIGhvb2tJZCwgcnVsZUlkLCByZXF1ZXN0SW5mbywgcmVzIH06IEV4ZWN1dGVNb2NrUHJlZGljYXRlKTogUHJvbWlzZTxJbmNvbWluZ01lc3NhZ2VMaWtlSW5pdE9wdGlvbnM+IHtcbiAgICAgICAgY29uc3QgdGVzdCAgICAgICAgID0gdGhpcy5zdGF0ZS51bml0c1t0ZXN0SWRdIGFzIFRlc3Q7XG4gICAgICAgIGNvbnN0IHJlcXVlc3RNb2NrICA9IHRlc3QucmVxdWVzdEhvb2tzLmZpbmQoaG9vayA9PiBob29rLmlkID09PSBob29rSWQpIGFzIFJlcXVlc3RNb2NrO1xuICAgICAgICBjb25zdCByZXNwb25zZU1vY2sgPSByZXF1ZXN0TW9jay5tb2Nrcy5nZXQocnVsZUlkKSBhcyBSZXNwb25zZU1vY2s7XG5cbiAgICAgICAgcmVzcG9uc2VNb2NrU2V0Qm9keU1ldGhvZC5hZGQocmVzKTtcblxuICAgICAgICByZXMgPSBPYmplY3QuYXNzaWduKHJlcywgYXdhaXQgKHJlc3BvbnNlTW9jay5ib2R5IGFzIEZ1bmN0aW9uKShyZXF1ZXN0SW5mbywgcmVzKSk7XG5cbiAgICAgICAgcmVzcG9uc2VNb2NrU2V0Qm9keU1ldGhvZC5yZW1vdmUocmVzKTtcblxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBnZXRXYXJuaW5nTWVzc2FnZXMgKHsgdGVzdFJ1bklkIH06IEdldFdhcm5pbmdNZXNzYWdlc0FyZ3VtZW50cyk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICAgICAgY29uc3QgdGVzdFJ1blByb3h5ID0gdGhpcy5zdGF0ZS50ZXN0UnVuc1t0ZXN0UnVuSWRdO1xuXG4gICAgICAgIHJldHVybiB0ZXN0UnVuUHJveHkud2FybmluZ0xvZy5tZXNzYWdlcztcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgYWRkUmVxdWVzdEV2ZW50TGlzdGVuZXJzICggeyBob29rSWQsIGhvb2tDbGFzc05hbWUsIHJ1bGVzIH06IEFkZFJlcXVlc3RFdmVudExpc3RlbmVyc0FyZ3VtZW50cyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5wcm94eS5jYWxsKHRoaXMuYWRkUmVxdWVzdEV2ZW50TGlzdGVuZXJzLCB7IGhvb2tJZCwgaG9va0NsYXNzTmFtZSwgcnVsZXMgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHJlbW92ZVJlcXVlc3RFdmVudExpc3RlbmVycyAoeyBydWxlcyB9OiBSZW1vdmVSZXF1ZXN0RXZlbnRMaXN0ZW5lcnNBcmd1bWVudHMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucHJveHkuY2FsbCh0aGlzLnJlbW92ZVJlcXVlc3RFdmVudExpc3RlbmVycywgeyBydWxlcyB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgaW5pdGlhbGl6ZVRlc3RSdW5EYXRhICh7IHRlc3RSdW5JZCwgdGVzdElkIH06IEluaXRpYWxpemVUZXN0UnVuRGF0YUFyZ3VtZW50cyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCB0ZXN0ID0gdGhpcy5zdGF0ZS51bml0c1t0ZXN0SWRdIGFzIFRlc3Q7XG5cbiAgICAgICAgdGhpcy5faW5pdGlhbGl6ZVRlc3RSdW5Qcm94eSh0ZXN0UnVuSWQsIHRlc3QpO1xuICAgICAgICB0aGlzLl9pbml0aWFsaXplRml4dHVyZUN0eCh0ZXN0KTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG5ldyBDb21waWxlclNlcnZpY2UoKTtcbiJdfQ==