testcafe 2.6.0 → 2.6.1

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 (112) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/bin/testcafe-with-v8-flag-filter.js +10 -16
  3. package/lib/api/exportable-lib/index.js +1 -11
  4. package/lib/api/structure/test.js +4 -11
  5. package/lib/api/test-controller/index.js +3 -10
  6. package/lib/api/test-run-tracker.js +1 -1
  7. package/lib/assertions/executor.js +2 -11
  8. package/lib/browser/connection/gateway/index.js +3 -4
  9. package/lib/cli/argument-parser/index.js +1 -3
  10. package/lib/cli/cli.js +3 -11
  11. package/lib/client/automation/index.js +49 -36
  12. package/lib/client/automation/index.min.js +1 -1
  13. package/lib/client/browser/idle-page/index.js +13 -5
  14. package/lib/client/core/index.js +14 -8
  15. package/lib/client/core/index.min.js +1 -1
  16. package/lib/client/driver/index.js +19 -20
  17. package/lib/client/driver/index.min.js +1 -1
  18. package/lib/compiler/babel/load-libs.js +3 -3
  19. package/lib/compiler/compilers.js +6 -6
  20. package/lib/compiler/index.js +3 -3
  21. package/lib/compiler/interfaces.js +1 -1
  22. package/lib/compiler/test-file/add-export-api.js +3 -3
  23. package/lib/compiler/test-file/api-based.js +5 -34
  24. package/lib/compiler/test-file/formats/es-next/compiler.js +4 -4
  25. package/lib/compiler/test-file/formats/typescript/compiler.js +5 -5
  26. package/lib/configuration/option-names.js +1 -2
  27. package/lib/errors/runtime/templates.js +1 -2
  28. package/lib/errors/types.js +2 -3
  29. package/lib/index.js +1 -3
  30. package/lib/live/bootstrapper.js +3 -3
  31. package/lib/live/test-runner.js +5 -5
  32. package/lib/native-automation/add-custom-debug-formatters.js +3 -2
  33. package/lib/native-automation/client/event-descriptor.js +11 -5
  34. package/lib/native-automation/client/input.js +3 -7
  35. package/lib/native-automation/request-hooks/event-provider.js +4 -1
  36. package/lib/native-automation/request-pipeline/context-info.js +4 -1
  37. package/lib/native-automation/request-pipeline/index.js +39 -19
  38. package/lib/native-automation/request-pipeline/safe-api.js +10 -7
  39. package/lib/native-automation/request-pipeline/special-handlers.js +16 -13
  40. package/lib/native-automation/resource-injector.js +7 -7
  41. package/lib/native-automation/types.js +1 -1
  42. package/lib/native-automation/utils/cdp.js +3 -2
  43. package/lib/role/role.js +4 -39
  44. package/lib/runner/bootstrapper.js +4 -11
  45. package/lib/runner/browser-job.js +4 -5
  46. package/lib/runner/fixture-hook-controller.js +1 -7
  47. package/lib/runner/index.js +6 -53
  48. package/lib/runner/interfaces.js +1 -1
  49. package/lib/runner/task/index.js +2 -4
  50. package/lib/runner/test-run-controller.js +2 -4
  51. package/lib/test-run/bookmark.js +5 -23
  52. package/lib/test-run/commands/service.js +2 -3
  53. package/lib/test-run/commands/utils.js +4 -2
  54. package/lib/test-run/index.js +9 -132
  55. package/lib/testcafe.js +1 -9
  56. package/lib/utils/debug-loggers.js +4 -2
  57. package/lib/utils/parse-user-agent.js +17 -2
  58. package/package.json +3 -4
  59. package/lib/compiler/test-file/test-file-temp-variable-name.js +0 -6
  60. package/lib/dashboard/config-storage.js +0 -26
  61. package/lib/dashboard/connector.js +0 -84
  62. package/lib/dashboard/documentation-url.js +0 -6
  63. package/lib/dashboard/formatting.js +0 -26
  64. package/lib/dashboard/get-dashboard-url.js +0 -10
  65. package/lib/dashboard/get-default-project-link.js +0 -23
  66. package/lib/dashboard/get-env-options.js +0 -26
  67. package/lib/dashboard/index.js +0 -145
  68. package/lib/dashboard/interfaces.js +0 -3
  69. package/lib/dashboard/messages.js +0 -21
  70. package/lib/services/compiler/esm-runtime-holder-name.js +0 -6
  71. package/lib/services/compiler/host.js +0 -370
  72. package/lib/services/compiler/interfaces.js +0 -3
  73. package/lib/services/compiler/io.js +0 -10
  74. package/lib/services/compiler/protocol.js +0 -17
  75. package/lib/services/compiler/service-loader.js +0 -18
  76. package/lib/services/compiler/service.js +0 -362
  77. package/lib/services/compiler/test-run-proxy.js +0 -157
  78. package/lib/services/interfaces.js +0 -3
  79. package/lib/services/process-title.js +0 -10
  80. package/lib/services/serialization/prepare-options.js +0 -23
  81. package/lib/services/serialization/replicator/create-replicator.js +0 -58
  82. package/lib/services/serialization/replicator/interfaces.js +0 -3
  83. package/lib/services/serialization/replicator/transforms/base-transform.js +0 -16
  84. package/lib/services/serialization/replicator/transforms/browser-console-messages-transform.js +0 -23
  85. package/lib/services/serialization/replicator/transforms/callsite-record-transform.js +0 -24
  86. package/lib/services/serialization/replicator/transforms/command-base-trasform/assertion-command-constructors.js +0 -28
  87. package/lib/services/serialization/replicator/transforms/command-base-trasform/command-constructors.js +0 -67
  88. package/lib/services/serialization/replicator/transforms/command-base-trasform/index.js +0 -49
  89. package/lib/services/serialization/replicator/transforms/command-base-trasform/types.js +0 -3
  90. package/lib/services/serialization/replicator/transforms/configure-response-event-option-transform.js +0 -21
  91. package/lib/services/serialization/replicator/transforms/custom-error-transform.js +0 -29
  92. package/lib/services/serialization/replicator/transforms/function-marker-transform/index.js +0 -21
  93. package/lib/services/serialization/replicator/transforms/function-marker-transform/marker.js +0 -9
  94. package/lib/services/serialization/replicator/transforms/promise-marker-transform/index.js +0 -21
  95. package/lib/services/serialization/replicator/transforms/promise-marker-transform/marker.js +0 -9
  96. package/lib/services/serialization/replicator/transforms/raw-command-callsite-record-transform.js +0 -22
  97. package/lib/services/serialization/replicator/transforms/re-executable-promise-transform/index.js +0 -22
  98. package/lib/services/serialization/replicator/transforms/re-executable-promise-transform/marker.js +0 -6
  99. package/lib/services/serialization/replicator/transforms/request-filter-rule-transform.js +0 -23
  100. package/lib/services/serialization/replicator/transforms/request-hook-event-data-transform.js +0 -41
  101. package/lib/services/serialization/replicator/transforms/response-mock-transform.js +0 -23
  102. package/lib/services/serialization/replicator/transforms/role-transform.js +0 -21
  103. package/lib/services/serialization/replicator/transforms/testcafe-error-list-transform.js +0 -23
  104. package/lib/services/serialization/replicator/transforms/url-transform.js +0 -23
  105. package/lib/services/serialization/test-structure.js +0 -91
  106. package/lib/services/utils/ipc/interfaces.js +0 -29
  107. package/lib/services/utils/ipc/io.js +0 -109
  108. package/lib/services/utils/ipc/message.js +0 -84
  109. package/lib/services/utils/ipc/packet.js +0 -57
  110. package/lib/services/utils/ipc/proxy.js +0 -94
  111. package/lib/services/utils/ipc/transport.js +0 -65
  112. package/lib/services/utils/method-should-not-be-called-error.js +0 -10
@@ -1,362 +0,0 @@
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_controller_1 = __importDefault(require("../../api/test-controller"));
10
- const test_structure_1 = require("../serialization/test-structure");
11
- const io_1 = require("./io");
12
- const proxy_1 = require("../utils/ipc/proxy");
13
- const transport_1 = require("../utils/ipc/transport");
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
- const user_variables_1 = __importDefault(require("../../api/user-variables"));
19
- const execute_js_expression_1 = require("../../test-run/execute-js-expression");
20
- const test_run_1 = require("../../errors/test-run");
21
- const utils_1 = require("../../errors/test-run/render-error-template/utils");
22
- const setup_sourcemap_support_1 = require("../../utils/setup-sourcemap-support");
23
- const handle_errors_1 = require("../../utils/handle-errors");
24
- const errors_1 = require("../../shared/errors");
25
- const lodash_1 = require("lodash");
26
- (0, setup_sourcemap_support_1.setupSourceMapSupport)();
27
- // This is hack for supporting the 'import { t } from "testcafe"' expression in tests.
28
- // It caused by using the 'esm' module.
29
- require('../../api/test-controller/proxy');
30
- class CompilerService {
31
- constructor() {
32
- process.title = process_title_1.default.service;
33
- const input = fs_1.default.createReadStream('', { fd: io_1.SERVICE_INPUT_FD });
34
- const output = fs_1.default.createWriteStream('', { fd: io_1.SERVICE_OUTPUT_FD });
35
- this.proxy = new proxy_1.IPCProxy(new transport_1.ServiceTransport(input, output, io_1.SERVICE_SYNC_FD));
36
- this.state = this._initState();
37
- this._runnableConfigurationUnitsRelations = {};
38
- this._registerErrorHandlers();
39
- this._setupRoutes();
40
- this.ready();
41
- }
42
- _initState() {
43
- return {
44
- testRuns: {},
45
- fixtureCtxs: {},
46
- units: {},
47
- options: {},
48
- roles: new Map(),
49
- };
50
- }
51
- async _handleUnexpectedError(ErrorCtor, error) {
52
- const message = (0, handle_errors_1.formatError)(ErrorCtor, error);
53
- const type = ErrorCtor.name;
54
- await this.addUnexpectedError({ type, message });
55
- }
56
- _registerErrorHandlers() {
57
- process.on('unhandledRejection', async (e) => this._handleUnexpectedError(test_run_1.UnhandledPromiseRejectionError, e));
58
- process.on('uncaughtException', async (e) => this._handleUnexpectedError(test_run_1.UncaughtExceptionError, e));
59
- }
60
- _getFixtureCtx(unit) {
61
- const fixtureId = (0, test_structure_1.isTest)(unit) ? unit.fixture.id : unit.id;
62
- return this.state.fixtureCtxs[fixtureId];
63
- }
64
- _getTestCtx({ testRunId }, unit) {
65
- const testRunProxy = this._getTargetTestRun(testRunId);
66
- testRunProxy.fixtureCtx = this._getFixtureCtx(unit);
67
- return testRunProxy;
68
- }
69
- _getContext(args, unit) {
70
- const { testRunId } = args;
71
- if (testRunId)
72
- return this._getTestCtx(args, unit);
73
- return this._getFixtureCtx(unit);
74
- }
75
- _setupRoutes() {
76
- this.proxy.register([
77
- this.getTests,
78
- this.runTestFn,
79
- this.cleanUp,
80
- this.setUserVariables,
81
- this.setOptions,
82
- this.onRequestHookEvent,
83
- this.setMock,
84
- this.setConfigureResponseEventOptions,
85
- this.setHeaderOnConfigureResponseEvent,
86
- this.removeHeaderOnConfigureResponseEvent,
87
- this.executeRequestFilterRulePredicate,
88
- this.executeMockPredicate,
89
- this.getWarningMessages,
90
- this.addRequestEventListeners,
91
- this.removeRequestEventListeners,
92
- this.initializeTestRunData,
93
- this.getAssertionActualValue,
94
- this.executeRoleInitFn,
95
- this.getCtx,
96
- this.getFixtureCtx,
97
- this.setCtx,
98
- this.setFixtureCtx,
99
- this.updateRoleProperty,
100
- this.executeJsExpression,
101
- this.executeAsyncJsExpression,
102
- this.addUnexpectedError,
103
- this.checkWindow,
104
- this.removeTestRunFromState,
105
- this.removeFixtureCtxsFromState,
106
- this.removeUnitsFromState,
107
- ], this);
108
- }
109
- _getFunction(unit, functionName) {
110
- if ((0, test_structure_1.isTest)(unit) && (0, protocol_1.isTestFunctionProperty)(functionName))
111
- return unit[functionName];
112
- if ((0, test_structure_1.isFixture)(unit) && (0, protocol_1.isFixtureFunctionProperty)(functionName))
113
- return unit[functionName];
114
- throw new Error(`Cannot find '${functionName}' function for ${typeof unit}`);
115
- }
116
- _wrapEventMethods({ name, testId, hookId, eventData }) {
117
- if (name === hook_method_names_1.default.onRequest)
118
- this._wrapSetMockFn({ testId, hookId, event: eventData });
119
- else if (name === hook_method_names_1.default._onConfigureResponse)
120
- this._wrapConfigureResponseEventMethods(eventData);
121
- }
122
- _wrapSetMockFn({ testId, hookId, event }) {
123
- event.setMock = async (mock) => {
124
- await this.setMock({
125
- responseEventId: event.id,
126
- ruleId: event.requestFilterRule.id,
127
- testId,
128
- hookId,
129
- mock,
130
- });
131
- };
132
- }
133
- _wrapConfigureResponseEventMethods(event) {
134
- event.setHeader = async (name, value) => {
135
- await this.setHeaderOnConfigureResponseEvent({
136
- eventId: event.id,
137
- headerName: name,
138
- headerValue: value,
139
- });
140
- };
141
- event.removeHeader = async (name) => {
142
- await this.removeHeaderOnConfigureResponseEvent({
143
- eventId: event.id,
144
- headerName: name,
145
- });
146
- };
147
- }
148
- _initializeTestRunProxy({ testRunId, test, browser, activeWindowId, messageBus, isNativeAutomation }) {
149
- const testRunProxy = new test_run_proxy_1.default({
150
- dispatcher: this,
151
- id: testRunId,
152
- options: this.state.options,
153
- test,
154
- browser,
155
- activeWindowId,
156
- messageBus,
157
- isNativeAutomation,
158
- });
159
- this.state.testRuns[testRunId] = testRunProxy;
160
- }
161
- _initializeFixtureCtx(test) {
162
- const fixtureId = test.fixture.id;
163
- if (this.state.fixtureCtxs[fixtureId])
164
- return;
165
- this.state.fixtureCtxs[fixtureId] = Object.create(null);
166
- }
167
- _getTargetTestRun(testRunId) {
168
- return this.state.testRuns[testRunId];
169
- }
170
- _getTargetRole(roleId) {
171
- return this.state.roles.get(roleId);
172
- }
173
- async setUserVariables(value) {
174
- user_variables_1.default.value = value;
175
- }
176
- _getUnitIds(tests) {
177
- const testIds = tests.map(test => test.id);
178
- const fixtureIds = tests.map(test => { var _a; return (_a = test.fixture) === null || _a === void 0 ? void 0 : _a.id; });
179
- const testFileIds = tests.map(test => test.testFile.id);
180
- return (0, lodash_1.uniq)([...testIds, ...fixtureIds, ...testFileIds]);
181
- }
182
- async setOptions({ value }) {
183
- this.state.options = value;
184
- }
185
- async ready() {
186
- this.proxy.call(this.ready);
187
- }
188
- async cleanUp() {
189
- await compiler_1.default.cleanUp();
190
- }
191
- async getTests({ sourceList, compilerOptions, runnableConfigurationId }, baseUrl) {
192
- const compiler = new compiler_1.default(sourceList, compilerOptions, { isCompilerServiceMode: true, baseUrl, esm: false });
193
- const tests = await compiler.getTests();
194
- const units = (0, test_structure_1.flatten)(tests);
195
- const unitIds = this._getUnitIds(tests);
196
- this._runnableConfigurationUnitsRelations[runnableConfigurationId] = unitIds;
197
- Object.assign(this.state.units, units);
198
- return (0, test_structure_1.serialize)(units);
199
- }
200
- async runTestFn(args) {
201
- const { id, functionName } = args;
202
- const unit = this.state.units[id];
203
- const context = this._getContext(args, unit);
204
- const functionObject = this._getFunction(unit, functionName);
205
- if (!functionObject)
206
- throw new Error(`Cannot find the "${functionName}" of ${typeof unit}`);
207
- return await functionObject(context);
208
- }
209
- executeCommandSync({ id, command, callsite }) {
210
- return this.proxy.callSync(this.executeCommand, { id, command, callsite });
211
- }
212
- async executeCommand({ command, id, callsite }) {
213
- return this.proxy.call(this.executeCommand, { id, command, callsite });
214
- }
215
- async onRequestHookEvent({ name, testId, hookId, eventData }) {
216
- this._wrapEventMethods({ name, testId, hookId, eventData });
217
- const test = this.state.units[testId];
218
- const targetHook = test.requestHooks.find(hook => hook.id === hookId);
219
- // @ts-ignore
220
- await targetHook[name].call(targetHook, eventData);
221
- if (name === hook_method_names_1.default._onConfigureResponse && targetHook._responseEventConfigureOpts) {
222
- const { opts, id: eventId } = eventData;
223
- await this.setConfigureResponseEventOptions({ eventId, opts });
224
- }
225
- }
226
- async setMock({ testId, hookId, ruleId, responseEventId, mock }) {
227
- await this.proxy.call(this.setMock, { testId, hookId, ruleId, responseEventId, mock });
228
- }
229
- async setConfigureResponseEventOptions({ eventId, opts }) {
230
- await this.proxy.call(this.setConfigureResponseEventOptions, { eventId, opts });
231
- }
232
- async setHeaderOnConfigureResponseEvent({ eventId, headerName, headerValue }) {
233
- await this.proxy.call(this.setHeaderOnConfigureResponseEvent, { eventId, headerName, headerValue });
234
- }
235
- async removeHeaderOnConfigureResponseEvent({ eventId, headerName }) {
236
- await this.proxy.call(this.removeHeaderOnConfigureResponseEvent, { eventId, headerName });
237
- }
238
- async executeRequestFilterRulePredicate({ testId, hookId, ruleId, requestInfo }) {
239
- const test = this.state.units[testId];
240
- const targetHook = test.requestHooks.find(hook => hook.id === hookId);
241
- const targetRule = targetHook._requestFilterRules.find(rule => rule.id === ruleId);
242
- const result = await targetRule.options.call(targetRule, requestInfo);
243
- return !!result;
244
- }
245
- async executeMockPredicate({ testId, hookId, ruleId, requestInfo, res }) {
246
- const test = this.state.units[testId];
247
- const requestMock = test.requestHooks.find(hook => hook.id === hookId);
248
- const responseMock = requestMock.mocks.get(ruleId);
249
- testcafe_hammerhead_1.responseMockSetBodyMethod.add(res);
250
- res = Object.assign(res, await responseMock.body(requestInfo, res));
251
- testcafe_hammerhead_1.responseMockSetBodyMethod.remove(res);
252
- return res;
253
- }
254
- async getWarningMessages({ testRunId }) {
255
- // NOTE: In case of raising an error into ReporterPluginHost methods,
256
- // TestRun has time to start.
257
- const targetTestRun = this._getTargetTestRun(testRunId);
258
- return targetTestRun ? targetTestRun.warningLog.messageInfos : [];
259
- }
260
- async addRequestEventListeners({ hookId, hookClassName, rules }) {
261
- return await this.proxy.call(this.addRequestEventListeners, { hookId, hookClassName, rules });
262
- }
263
- async removeRequestEventListeners({ rules }) {
264
- return await this.proxy.call(this.removeRequestEventListeners, { rules });
265
- }
266
- async initializeTestRunData({ testRunId, testId, browser, activeWindowId, messageBus, isNativeAutomation }) {
267
- // NOTE: In case of raising an error into ReporterPluginHost methods,
268
- // TestRun has time to start.
269
- const test = this.state.units[testId];
270
- if (!test)
271
- return;
272
- this._initializeTestRunProxy({ testRunId, test, browser, activeWindowId, messageBus, isNativeAutomation });
273
- this._initializeFixtureCtx(test);
274
- }
275
- enableDebugForNonDebugCommands() {
276
- test_controller_1.default.enableDebugForNonDebugCommands();
277
- }
278
- disableDebugForNonDebugCommands() {
279
- test_controller_1.default.disableDebugForNonDebugCommands();
280
- }
281
- async getAssertionActualValue({ testRunId, commandId }) {
282
- return this._getTargetTestRun(testRunId).getAssertionActualValue(commandId);
283
- }
284
- async executeRoleInitFn({ testRunId, roleId }) {
285
- const role = this._getTargetRole(roleId);
286
- const testRunProxy = this._getTargetTestRun(testRunId);
287
- return role._initFn(testRunProxy);
288
- }
289
- async getCtx({ testRunId }) {
290
- return this._getTargetTestRun(testRunId).ctx;
291
- }
292
- async getFixtureCtx({ testRunId }) {
293
- return this._getTargetTestRun(testRunId).fixtureCtx;
294
- }
295
- async setCtx({ testRunId, value }) {
296
- this._getTargetTestRun(testRunId).ctx = value;
297
- }
298
- async setFixtureCtx({ testRunId, value }) {
299
- this._getTargetTestRun(testRunId).fixtureCtx = value;
300
- }
301
- onRoleAppeared(role) {
302
- if (this.state.roles.has(role.id))
303
- return;
304
- this.state.roles.set(role.id, role);
305
- }
306
- async updateRoleProperty({ roleId, name, value }) {
307
- const role = this._getTargetRole(roleId);
308
- // @ts-ignore
309
- role[name] = value;
310
- }
311
- async executeJsExpression({ expression, testRunId, options }) {
312
- const testRunProxy = this._getTargetTestRun(testRunId);
313
- return (0, execute_js_expression_1.executeJsExpression)(expression, testRunProxy, options);
314
- }
315
- async executeAsyncJsExpression({ expression, testRunId, callsite }) {
316
- const testRunProxy = this._getTargetTestRun(testRunId);
317
- return (0, execute_js_expression_1.executeAsyncJsExpression)(expression, testRunProxy, callsite, async (err) => {
318
- if (err instanceof test_run_1.UncaughtTestCafeErrorInCustomScript === false)
319
- return;
320
- const targetError = err;
321
- if (!(0, utils_1.shouldRenderHtmlWithoutStack)(targetError))
322
- return;
323
- testRunProxy.restoreOriginCallsiteForError(targetError);
324
- // @ts-ignore
325
- err.errCallsite = (0, utils_1.renderHtmlWithoutStack)(targetError);
326
- });
327
- }
328
- async executeAssertionFn({ testRunId, commandId }) {
329
- return this
330
- ._getTargetTestRun(testRunId)
331
- .executeAssertionFn(commandId);
332
- }
333
- async addUnexpectedError({ type, message }) {
334
- return this.proxy.call(this.addUnexpectedError, { type, message });
335
- }
336
- async checkWindow({ testRunId, commandId, url, title }) {
337
- try {
338
- return this
339
- ._getTargetTestRun(testRunId)
340
- .checkWindow(commandId, { title, url });
341
- }
342
- catch (err) {
343
- throw new errors_1.SwitchToWindowPredicateError(err.message);
344
- }
345
- }
346
- async removeTestRunFromState({ testRunId }) {
347
- delete this.state.testRuns[testRunId];
348
- }
349
- async removeFixtureCtxsFromState({ fixtureIds }) {
350
- for (const fixtureId of fixtureIds)
351
- delete this.state.fixtureCtxs[fixtureId];
352
- }
353
- async removeUnitsFromState({ runnableConfigurationId }) {
354
- const unitIds = this._runnableConfigurationUnitsRelations[runnableConfigurationId];
355
- for (const unitId of unitIds)
356
- delete this.state.units[unitId];
357
- delete this._runnableConfigurationUnitsRelations[runnableConfigurationId];
358
- }
359
- }
360
- exports.default = new CompilerService();
361
- module.exports = exports.default;
362
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZXJ2aWNlcy9jb21waWxlci9zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsNENBQW9CO0FBQ3BCLDhEQUFzQztBQUN0QyxzRUFBNEM7QUFDNUMsZ0ZBQXVEO0FBRXZELG9FQU95QztBQUV6Qyw2QkFJYztBQUVkLDhDQUE4QztBQUM5QyxzREFBMEQ7QUFFMUQseUNBTW9CO0FBZ0NwQixxRUFBNEM7QUFFNUMsa0dBQStFO0FBRS9FLDZEQU82QjtBQUs3Qiw4RUFBcUQ7QUFDckQsZ0ZBQXFHO0FBRXJHLG9EQUsrQjtBQUUvQiw2RUFBeUg7QUFDekgsaUZBQTRFO0FBQzVFLDZEQUF3RDtBQUN4RCxnREFBbUU7QUFHbkUsbUNBQThCO0FBRTlCLElBQUEsK0NBQXFCLEdBQUUsQ0FBQztBQUV4QixzRkFBc0Y7QUFDdEYsdUNBQXVDO0FBQ3ZDLE9BQU8sQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO0FBdUIzQyxNQUFNLGVBQWU7SUFLakI7UUFDSSxPQUFPLENBQUMsS0FBSyxHQUFHLHVCQUFZLENBQUMsT0FBTyxDQUFDO1FBRXJDLE1BQU0sS0FBSyxHQUFJLFlBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUscUJBQWdCLEVBQUUsQ0FBQyxDQUFDO1FBQ2pFLE1BQU0sTUFBTSxHQUFHLFlBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsc0JBQWlCLEVBQUUsQ0FBQyxDQUFDO1FBRW5FLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxnQkFBUSxDQUFDLElBQUksNEJBQWdCLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxvQkFBZSxDQUFDLENBQUMsQ0FBQztRQUNoRixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUUvQixJQUFJLENBQUMsb0NBQW9D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Q0FBQztDQUNKO0FBRUQsa0JBQWUsSUFBSSxlQUFlLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBmcyBmcm9tICdmcyc7XG5pbXBvcnQgQ29tcGlsZXIgZnJvbSAnLi4vLi4vY29tcGlsZXInO1xuaW1wb3J0IFRlc3RSdW5Qcm94eSBmcm9tICcuL3Rlc3QtcnVuLXByb3h5JztcbmltcG9ydCBUZXN0Q29udHJvbGxlciBmcm9tICcuLi8uLi9hcGkvdGVzdC1jb250cm9sbGVyJztcblxuaW1wb3J0IHtcbiAgICBmbGF0dGVuIGFzIGZsYXR0ZW5UZXN0U3RydWN0dXJlLFxuICAgIGlzRml4dHVyZSxcbiAgICBpc1Rlc3QsXG4gICAgc2VyaWFsaXplIGFzIHNlcmlhbGl6ZVRlc3RTdHJ1Y3R1cmUsXG4gICAgVW5pdCxcbiAgICBVbml0cyxcbn0gZnJvbSAnLi4vc2VyaWFsaXphdGlvbi90ZXN0LXN0cnVjdHVyZSc7XG5cbmltcG9ydCB7XG4gICAgU0VSVklDRV9JTlBVVF9GRCxcbiAgICBTRVJWSUNFX09VVFBVVF9GRCxcbiAgICBTRVJWSUNFX1NZTkNfRkQsXG59IGZyb20gJy4vaW8nO1xuXG5pbXBvcnQgeyBJUENQcm94eSB9IGZyb20gJy4uL3V0aWxzL2lwYy9wcm94eSc7XG5pbXBvcnQgeyBTZXJ2aWNlVHJhbnNwb3J0IH0gZnJvbSAnLi4vdXRpbHMvaXBjL3RyYW5zcG9ydCc7XG5cbmltcG9ydCB7XG4gICAgQ29tcGlsZXJQcm90b2NvbCxcbiAgICBGdW5jdGlvblByb3BlcnRpZXMsXG4gICAgaXNGaXh0dXJlRnVuY3Rpb25Qcm9wZXJ0eSxcbiAgICBpc1Rlc3RGdW5jdGlvblByb3BlcnR5LFxuICAgIFJ1blRlc3RBcmd1bWVudHMsXG59IGZyb20gJy4vcHJvdG9jb2wnO1xuXG5pbXBvcnQge1xuICAgIEV4ZWN1dGVDb21tYW5kQXJndW1lbnRzLFxuICAgIEV4ZWN1dGVNb2NrUHJlZGljYXRlLFxuICAgIEV4ZWN1dGVSZXF1ZXN0RmlsdGVyUnVsZVByZWRpY2F0ZUFyZ3VtZW50cyxcbiAgICBSZW1vdmVIZWFkZXJPbkNvbmZpZ3VyZVJlc3BvbnNlRXZlbnRBcmd1bWVudHMsXG4gICAgUmVxdWVzdEhvb2tFdmVudEFyZ3VtZW50cyxcbiAgICBSZXF1ZXN0SG9va0xvY2F0b3IsXG4gICAgU2V0Q29uZmlndXJlUmVzcG9uc2VFdmVudE9wdGlvbnNBcmd1bWVudHMsXG4gICAgU2V0SGVhZGVyT25Db25maWd1cmVSZXNwb25zZUV2ZW50QXJndW1lbnRzLFxuICAgIFNldE1vY2tBcmd1bWVudHMsXG4gICAgU2V0T3B0aW9uc0FyZ3VtZW50cyxcbiAgICBBZGRSZXF1ZXN0RXZlbnRMaXN0ZW5lcnNBcmd1bWVudHMsXG4gICAgUmVtb3ZlUmVxdWVzdEV2ZW50TGlzdGVuZXJzQXJndW1lbnRzLFxuICAgIEluaXRpYWxpemVUZXN0UnVuRGF0YUFyZ3VtZW50cyxcbiAgICBUZXN0UnVuTG9jYXRvcixcbiAgICBTZXRDdHhBcmd1bWVudHMsXG4gICAgRXhlY3V0ZVJvbGVJbml0Rm5Bcmd1bWVudHMsXG4gICAgVXBkYXRlUm9sZVByb3BlcnR5QXJndW1lbnRzLFxuICAgIEV4ZWN1dGVKc0V4cHJlc3Npb25Bcmd1bWVudHMsXG4gICAgRXhlY3V0ZUFzeW5jSnNFeHByZXNzaW9uQXJndW1lbnRzLFxuICAgIENvbW1hbmRMb2NhdG9yLFxuICAgIEFkZFVuZXhwZWN0ZWRFcnJvckFyZ3VtZW50cyxcbiAgICBDaGVja1dpbmRvd0FyZ3VtZW50LFxuICAgIFJlbW92ZUZpeHR1cmVDdHhzQXJndW1lbnRzLFxuICAgIFJlbW92ZVVuaXRzRnJvbVN0YXRlQXJndW1lbnRzLFxufSBmcm9tICcuL2ludGVyZmFjZXMnO1xuXG5pbXBvcnQgeyBDb21waWxlckFyZ3VtZW50cyB9IGZyb20gJy4uLy4uL2NvbXBpbGVyL2ludGVyZmFjZXMnO1xuaW1wb3J0IEZpeHR1cmUgZnJvbSAnLi4vLi4vYXBpL3N0cnVjdHVyZS9maXh0dXJlJztcbmltcG9ydCB7IERpY3Rpb25hcnkgfSBmcm9tICcuLi8uLi9jb25maWd1cmF0aW9uL2ludGVyZmFjZXMnO1xuaW1wb3J0IFByb2Nlc3NUaXRsZSBmcm9tICcuLi9wcm9jZXNzLXRpdGxlJztcbmltcG9ydCBUZXN0IGZyb20gJy4uLy4uL2FwaS9zdHJ1Y3R1cmUvdGVzdCc7XG5pbXBvcnQgUmVxdWVzdEhvb2tNZXRob2ROYW1lcyBmcm9tICcuLi8uLi9hcGkvcmVxdWVzdC1ob29rcy9ob29rLW1ldGhvZC1uYW1lcyc7XG5cbmltcG9ydCB7XG4gICAgQ29uZmlndXJlUmVzcG9uc2VFdmVudCxcbiAgICBJbmNvbWluZ01lc3NhZ2VMaWtlSW5pdE9wdGlvbnMsXG4gICAgUmVxdWVzdEV2ZW50LFxuICAgIFJlcXVlc3RGaWx0ZXJSdWxlLFxuICAgIFJlc3BvbnNlTW9jayxcbiAgICByZXNwb25zZU1vY2tTZXRCb2R5TWV0aG9kLFxufSBmcm9tICd0ZXN0Y2FmZS1oYW1tZXJoZWFkJztcblxuaW1wb3J0IFJlcXVlc3RIb29rIGZyb20gJy4uLy4uL2FwaS9yZXF1ZXN0LWhvb2tzL2hvb2snO1xuaW1wb3J0IFJlcXVlc3RNb2NrIGZyb20gJy4uLy4uL2FwaS9yZXF1ZXN0LWhvb2tzL3JlcXVlc3QtbW9jayc7XG5pbXBvcnQgUm9sZSBmcm9tICcuLi8uLi9yb2xlL3JvbGUnO1xuaW1wb3J0IHVzZXJWYXJpYWJsZXMgZnJvbSAnLi4vLi4vYXBpL3VzZXItdmFyaWFibGVzJztcbmltcG9ydCB7IGV4ZWN1dGVKc0V4cHJlc3Npb24sIGV4ZWN1dGVBc3luY0pzRXhwcmVzc2lvbiB9IGZyb20gJy4uLy4uL3Rlc3QtcnVuL2V4ZWN1dGUtanMtZXhwcmVzc2lvbic7XG5cbmltcG9ydCB7XG4gICAgVW5jYXVnaHRFcnJvckluQ3VzdG9tU2NyaXB0LFxuICAgIFVuY2F1Z2h0RXhjZXB0aW9uRXJyb3IsXG4gICAgVW5jYXVnaHRUZXN0Q2FmZUVycm9ySW5DdXN0b21TY3JpcHQsXG4gICAgVW5oYW5kbGVkUHJvbWlzZVJlamVjdGlvbkVycm9yLFxufSBmcm9tICcuLi8uLi9lcnJvcnMvdGVzdC1ydW4nO1xuXG5pbXBvcnQgeyByZW5kZXJIdG1sV2l0aG91dFN0YWNrLCBzaG91bGRSZW5kZXJIdG1sV2l0aG91dFN0YWNrIH0gZnJvbSAnLi4vLi4vZXJyb3JzL3Rlc3QtcnVuL3JlbmRlci1lcnJvci10ZW1wbGF0ZS91dGlscyc7XG5pbXBvcnQgeyBzZXR1cFNvdXJjZU1hcFN1cHBvcnQgfSBmcm9tICcuLi8uLi91dGlscy9zZXR1cC1zb3VyY2VtYXAtc3VwcG9ydCc7XG5pbXBvcnQgeyBmb3JtYXRFcnJvciB9IGZyb20gJy4uLy4uL3V0aWxzL2hhbmRsZS1lcnJvcnMnO1xuaW1wb3J0IHsgU3dpdGNoVG9XaW5kb3dQcmVkaWNhdGVFcnJvciB9IGZyb20gJy4uLy4uL3NoYXJlZC9lcnJvcnMnO1xuaW1wb3J0IE1lc3NhZ2VCdXMgZnJvbSAnLi4vLi4vdXRpbHMvbWVzc2FnZS1idXMnO1xuaW1wb3J0IHsgV2FybmluZ0xvZ01lc3NhZ2UgfSBmcm9tICcuLi8uLi9ub3RpZmljYXRpb25zL3dhcm5pbmctbG9nJztcbmltcG9ydCB7IHVuaXEgfSBmcm9tICdsb2Rhc2gnO1xuXG5zZXR1cFNvdXJjZU1hcFN1cHBvcnQoKTtcblxuLy8gVGhpcyBpcyBoYWNrIGZvciBzdXBwb3J0aW5nIHRoZSAnaW1wb3J0IHsgdCB9IGZyb20gXCJ0ZXN0Y2FmZVwiJyBleHByZXNzaW9uIGluIHRlc3RzLlxuLy8gSXQgY2F1c2VkIGJ5IHVzaW5nIHRoZSAnZXNtJyBtb2R1bGUuXG5yZXF1aXJlKCcuLi8uLi9hcGkvdGVzdC1jb250cm9sbGVyL3Byb3h5Jyk7XG5cbmludGVyZmFjZSBTZXJ2aWNlU3RhdGUge1xuICAgIHRlc3RSdW5zOiB7IFtpZDogc3RyaW5nXTogVGVzdFJ1blByb3h5IH07XG4gICAgZml4dHVyZUN0eHM6IHsgW2lkOiBzdHJpbmddOiBvYmplY3QgfTtcbiAgICB1bml0czogVW5pdHM7XG4gICAgb3B0aW9uczogRGljdGlvbmFyeTxPcHRpb25WYWx1ZT47XG4gICAgcm9sZXM6IE1hcDxzdHJpbmcsIFJvbGU+O1xufVxuXG5pbnRlcmZhY2UgV3JhcFNldE1vY2tBcmd1bWVudHMgZXh0ZW5kcyBSZXF1ZXN0SG9va0xvY2F0b3Ige1xuICAgIGV2ZW50OiBSZXF1ZXN0RXZlbnQ7XG59XG5cbmludGVyZmFjZSBJbml0VGVzdFJ1blByb3h5RGF0YSB7XG4gICAgdGVzdFJ1bklkOiBzdHJpbmc7XG4gICAgdGVzdDogVGVzdDtcbiAgICBicm93c2VyOiBCcm93c2VyO1xuICAgIGFjdGl2ZVdpbmRvd0lkOiBzdHJpbmcgfCBudWxsO1xuICAgIG1lc3NhZ2VCdXM/OiBNZXNzYWdlQnVzO1xuICAgIGlzTmF0aXZlQXV0b21hdGlvbjogYm9vbGVhbjtcbn1cblxuY2xhc3MgQ29tcGlsZXJTZXJ2aWNlIGltcGxlbWVudHMgQ29tcGlsZXJQcm90b2NvbCB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBwcm94eTogSVBDUHJveHk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBzdGF0ZTogU2VydmljZVN0YXRlO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX3J1bm5hYmxlQ29uZmlndXJhdGlvblVuaXRzUmVsYXRpb25zOiB7IFtpZDogc3RyaW5nXTogc3RyaW5nW10gfTtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHByb2Nlc3MudGl0bGUgPSBQcm9jZXNzVGl0bGUuc2VydmljZTtcblxuICAgICAgICBjb25zdCBpbnB1dCAgPSBmcy5jcmVhdGVSZWFkU3RyZWFtKCcnLCB7IGZkOiBTRVJWSUNFX0lOUFVUX0ZEIH0pO1xuICAgICAgICBjb25zdCBvdXRwdXQgPSBmcy5jcmVhdGVXcml0ZVN0cmVhbSgnJywgeyBmZDogU0VSVklDRV9PVVRQVVRfRkQgfSk7XG5cbiAgICAgICAgdGhpcy5wcm94eSA9IG5ldyBJUENQcm94eShuZXcgU2VydmljZVRyYW5zcG9ydChpbnB1dCwgb3V0cHV0LCBTRVJWSUNFX1NZTkNfRkQpKTtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHRoaXMuX2luaXRTdGF0ZSgpO1xuXG4gICAgICAgIHRoaXMuX3J1bm5hYmxlQ29uZmlndXJhdGlvblVuaXRzUmVsYXRpb25zID0ge307XG5cbiAgICAgICAgdGhpcy5fcmVnaXN0ZXJFcnJvckhhbmRsZXJzKCk7XG4gICAgICAgIHRoaXMuX3NldHVwUm91dGVzKCk7XG4gICAgICAgIHRoaXMucmVhZHkoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9pbml0U3RhdGUgKCk6IFNlcnZpY2VTdGF0ZSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0ZXN0UnVuczogICAge30sXG4gICAgICAgICAgICBmaXh0dXJlQ3R4czoge30sXG4gICAgICAgICAgICB1bml0czogICAgICAge30sXG4gICAgICAgICAgICBvcHRpb25zOiAgICAge30sXG4gICAgICAgICAgICByb2xlczogICAgICAgbmV3IE1hcDxzdHJpbmcsIFJvbGU+KCksXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBfaGFuZGxlVW5leHBlY3RlZEVycm9yIChFcnJvckN0b3I6IEZ1bmN0aW9uLCBlcnJvcjogRXJyb3IpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IGZvcm1hdEVycm9yKEVycm9yQ3RvciwgZXJyb3IpO1xuICAgICAgICBjb25zdCB0eXBlICAgID0gRXJyb3JDdG9yLm5hbWU7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5hZGRVbmV4cGVjdGVkRXJyb3IoeyB0eXBlLCBtZXNzYWdlIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3JlZ2lzdGVyRXJyb3JIYW5kbGVycyAoKTogdm9pZCB7XG4gICAgICAgIHByb2Nlc3Mub24oJ3VuaGFuZGxlZFJlamVjdGlvbicsIGFzeW5jIGUgPT4gdGhpcy5faGFuZGxlVW5leHBlY3RlZEVycm9yKFVuaGFuZGxlZFByb21pc2VSZWplY3Rpb25FcnJvciwgZSBhcyBFcnJvcikpO1xuICAgICAgICBwcm9jZXNzLm9uKCd1bmNhdWdodEV4Y2VwdGlvbicsIGFzeW5jIGUgPT4gdGhpcy5faGFuZGxlVW5leHBlY3RlZEVycm9yKFVuY2F1Z2h0RXhjZXB0aW9uRXJyb3IsIGUgYXMgRXJyb3IpKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9nZXRGaXh0dXJlQ3R4ICh1bml0OiBVbml0KTogb2JqZWN0IHtcbiAgICAgICAgY29uc3QgZml4dHVyZUlkID0gaXNUZXN0KHVuaXQpID8gKHVuaXQuZml4dHVyZSBhcyBGaXh0dXJlKS5pZCA6ICh1bml0IGFzIEZpeHR1cmUpLmlkO1xuXG4gICAgICAgIHJldHVybiB0aGlzLnN0YXRlLmZpeHR1cmVDdHhzW2ZpeHR1cmVJZF07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZ2V0VGVzdEN0eCAoeyB0ZXN0UnVuSWQgfTogUnVuVGVzdEFyZ3VtZW50cywgdW5pdDogVW5pdCk6IFRlc3RSdW5Qcm94eSB7XG4gICAgICAgIGNvbnN0IHRlc3RSdW5Qcm94eSA9IHRoaXMuX2dldFRhcmdldFRlc3RSdW4odGVzdFJ1bklkKTtcblxuICAgICAgICB0ZXN0UnVuUHJveHkuZml4dHVyZUN0eCA9IHRoaXMuX2dldEZpeHR1cmVDdHgodW5pdCk7XG5cbiAgICAgICAgcmV0dXJuIHRlc3RSdW5Qcm94eTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9nZXRDb250ZXh0IChhcmdzOiBSdW5UZXN0QXJndW1lbnRzLCB1bml0OiBVbml0KTogVGVzdFJ1blByb3h5IHwgdW5rbm93biB7XG4gICAgICAgIGNvbnN0IHsgdGVzdFJ1bklkIH0gPSBhcmdzO1xuXG4gICAgICAgIGlmICh0ZXN0UnVuSWQpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0VGVzdEN0eChhcmdzLCB1bml0KTtcblxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0Rml4dHVyZUN0eCh1bml0KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9zZXR1cFJvdXRlcyAoKTogdm9pZCB7XG4gICAgICAgIHRoaXMucHJveHkucmVnaXN0ZXIoW1xuICAgICAgICAgICAgdGhpcy5nZXRUZXN0cyxcbiAgICAgICAgICAgIHRoaXMucnVuVGVzdEZuLFxuICAgICAgICAgICAgdGhpcy5jbGVhblVwLFxuICAgICAgICAgICAgdGhpcy5zZXRVc2VyVmFyaWFibGVzLFxuICAgICAgICAgICAgdGhpcy5zZXRPcHRpb25zLFxuICAgICAgICAgICAgdGhpcy5vblJlcXVlc3RIb29rRXZlbnQsXG4gICAgICAgICAgICB0aGlzLnNldE1vY2ssXG4gICAgICAgICAgICB0aGlzLnNldENvbmZpZ3VyZVJlc3BvbnNlRXZlbnRPcHRpb25zLFxuICAgICAgICAgICAgdGhpcy5zZXRIZWFkZXJPbkNvbmZpZ3VyZVJlc3BvbnNlRXZlbnQsXG4gICAgICAgICAgICB0aGlzLnJlbW92ZUhlYWRlck9uQ29uZmlndXJlUmVzcG9uc2VFdmVudCxcbiAgICAgICAgICAgIHRoaXMuZXhlY3V0ZVJlcXVlc3RGaWx0ZXJSdWxlUHJlZGljYXRlLFxuICAgICAgICAgICAgdGhpcy5leGVjdXRlTW9ja1ByZWRpY2F0ZSxcbiAgICAgICAgICAgIHRoaXMuZ2V0V2FybmluZ01lc3NhZ2VzLFxuICAgICAgICAgICAgdGhpcy5hZGRSZXF1ZXN0RXZlbnRMaXN0ZW5lcnMsXG4gICAgICAgICAgICB0aGlzLnJlbW92ZVJlcXVlc3RFdmVudExpc3RlbmVycyxcbiAgICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZVRlc3RSdW5EYXRhLFxuICAgICAgICAgICAgdGhpcy5nZXRBc3NlcnRpb25BY3R1YWxWYWx1ZSxcbiAgICAgICAgICAgIHRoaXMuZXhlY3V0ZVJvbGVJbml0Rm4sXG4gICAgICAgICAgICB0aGlzLmdldEN0eCxcbiAgICAgICAgICAgIHRoaXMuZ2V0Rml4dHVyZUN0eCxcbiAgICAgICAgICAgIHRoaXMuc2V0Q3R4LFxuICAgICAgICAgICAgdGhpcy5zZXRGaXh0dXJlQ3R4LFxuICAgICAgICAgICAgdGhpcy51cGRhdGVSb2xlUHJvcGVydHksXG4gICAgICAgICAgICB0aGlzLmV4ZWN1dGVKc0V4cHJlc3Npb24sXG4gICAgICAgICAgICB0aGlzLmV4ZWN1dGVBc3luY0pzRXhwcmVzc2lvbixcbiAgICAgICAgICAgIHRoaXMuYWRkVW5leHBlY3RlZEVycm9yLFxuICAgICAgICAgICAgdGhpcy5jaGVja1dpbmRvdyxcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlVGVzdFJ1bkZyb21TdGF0ZSxcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlRml4dHVyZUN0eHNGcm9tU3RhdGUsXG4gICAgICAgICAgICB0aGlzLnJlbW92ZVVuaXRzRnJvbVN0YXRlLFxuICAgICAgICBdLCB0aGlzKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9nZXRGdW5jdGlvbiAodW5pdDogVW5pdCwgZnVuY3Rpb25OYW1lOiBGdW5jdGlvblByb3BlcnRpZXMpOiBGdW5jdGlvbnxudWxsIHtcbiAgICAgICAgaWYgKGlzVGVzdCh1bml0KSAmJiBpc1Rlc3RGdW5jdGlvblByb3BlcnR5KGZ1bmN0aW9uTmFtZSkpXG4gICAgICAgICAgICByZXR1cm4gdW5pdFtmdW5jdGlvbk5hbWVdO1xuXG4gICAgICAgIGlmIChpc0ZpeHR1cmUodW5pdCkgJiYgaXNGaXh0dXJlRnVuY3Rpb25Qcm9wZXJ0eShmdW5jdGlvbk5hbWUpKVxuICAgICAgICAgICAgcmV0dXJuIHVuaXRbZnVuY3Rpb25OYW1lXTtcblxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBmaW5kICcke2Z1bmN0aW9uTmFtZX0nIGZ1bmN0aW9uIGZvciAke3R5cGVvZiB1bml0fWApO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3dyYXBFdmVudE1ldGhvZHMgKHsgbmFtZSwgdGVzdElkLCBob29rSWQsIGV2ZW50RGF0YSB9OiBSZXF1ZXN0SG9va0V2ZW50QXJndW1lbnRzKTogdm9pZCB7XG4gICAgICAgIGlmIChuYW1lID09PSBSZXF1ZXN0SG9va01ldGhvZE5hbWVzLm9uUmVxdWVzdClcbiAgICAgICAgICAgIHRoaXMuX3dyYXBTZXRNb2NrRm4oeyB0ZXN0SWQsIGhvb2tJZCwgZXZlbnQ6IGV2ZW50RGF0YSBhcyBSZXF1ZXN0RXZlbnQgfSk7XG4gICAgICAgIGVsc2UgaWYgKG5hbWUgPT09IFJlcXVlc3RIb29rTWV0aG9kTmFtZXMuX29uQ29uZmlndXJlUmVzcG9uc2UpXG4gICAgICAgICAgICB0aGlzLl93cmFwQ29uZmlndXJlUmVzcG9uc2VFdmVudE1ldGhvZHMoZXZlbnREYXRhIGFzIENvbmZpZ3VyZVJlc3BvbnNlRXZlbnQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3dyYXBTZXRNb2NrRm4gKHsgdGVzdElkLCBob29rSWQsIGV2ZW50IH06IFdyYXBTZXRNb2NrQXJndW1lbnRzKTogdm9pZCB7XG4gICAgICAgIGV2ZW50LnNldE1vY2sgPSBhc3luYyAobW9jazogUmVzcG9uc2VNb2NrKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNldE1vY2soe1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlRXZlbnRJZDogZXZlbnQuaWQsXG4gICAgICAgICAgICAgICAgcnVsZUlkOiAgICAgICAgICBldmVudC5yZXF1ZXN0RmlsdGVyUnVsZS5pZCxcbiAgICAgICAgICAgICAgICB0ZXN0SWQsXG4gICAgICAgICAgICAgICAgaG9va0lkLFxuICAgICAgICAgICAgICAgIG1vY2ssXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF93cmFwQ29uZmlndXJlUmVzcG9uc2VFdmVudE1ldGhvZHMgKGV2ZW50OiBDb25maWd1cmVSZXNwb25zZUV2ZW50KTogdm9pZCB7XG4gICAgICAgIGV2ZW50LnNldEhlYWRlciA9IGFzeW5jIChuYW1lOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc2V0SGVhZGVyT25Db25maWd1cmVSZXNwb25zZUV2ZW50KHtcbiAgICAgICAgICAgICAgICBldmVudElkOiAgICAgZXZlbnQuaWQsXG4gICAgICAgICAgICAgICAgaGVhZGVyTmFtZTogIG5hbWUsXG4gICAgICAgICAgICAgICAgaGVhZGVyVmFsdWU6IHZhbHVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgZXZlbnQucmVtb3ZlSGVhZGVyID0gYXN5bmMgKG5hbWU6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5yZW1vdmVIZWFkZXJPbkNvbmZpZ3VyZVJlc3BvbnNlRXZlbnQoe1xuICAgICAgICAgICAgICAgIGV2ZW50SWQ6ICAgIGV2ZW50LmlkLFxuICAgICAgICAgICAgICAgIGhlYWRlck5hbWU6IG5hbWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9pbml0aWFsaXplVGVzdFJ1blByb3h5ICh7IHRlc3RSdW5JZCwgdGVzdCwgYnJvd3NlciwgYWN0aXZlV2luZG93SWQsIG1lc3NhZ2VCdXMsIGlzTmF0aXZlQXV0b21hdGlvbiB9OiBJbml0VGVzdFJ1blByb3h5RGF0YSk6IHZvaWQge1xuICAgICAgICBjb25zdCB0ZXN0UnVuUHJveHkgPSBuZXcgVGVzdFJ1blByb3h5KHtcbiAgICAgICAgICAgIGRpc3BhdGNoZXI6IHRoaXMsXG4gICAgICAgICAgICBpZDogICAgICAgICB0ZXN0UnVuSWQsXG4gICAgICAgICAgICBvcHRpb25zOiAgICB0aGlzLnN0YXRlLm9wdGlvbnMsXG4gICAgICAgICAgICB0ZXN0LFxuICAgICAgICAgICAgYnJvd3NlcixcbiAgICAgICAgICAgIGFjdGl2ZVdpbmRvd0lkLFxuICAgICAgICAgICAgbWVzc2FnZUJ1cyxcbiAgICAgICAgICAgIGlzTmF0aXZlQXV0b21hdGlvbixcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5zdGF0ZS50ZXN0UnVuc1t0ZXN0UnVuSWRdID0gdGVzdFJ1blByb3h5O1xuICAgIH1cblxuICAgIHByaXZhdGUgX2luaXRpYWxpemVGaXh0dXJlQ3R4ICh0ZXN0OiBUZXN0KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGZpeHR1cmVJZCA9ICh0ZXN0LmZpeHR1cmUgYXMgRml4dHVyZSkuaWQ7XG5cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuZml4dHVyZUN0eHNbZml4dHVyZUlkXSlcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICB0aGlzLnN0YXRlLmZpeHR1cmVDdHhzW2ZpeHR1cmVJZF0gPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2dldFRhcmdldFRlc3RSdW4gKHRlc3RSdW5JZDogc3RyaW5nKTogVGVzdFJ1blByb3h5IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhdGUudGVzdFJ1bnNbdGVzdFJ1bklkXTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9nZXRUYXJnZXRSb2xlIChyb2xlSWQ6IHN0cmluZyk6IFJvbGUge1xuICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZS5yb2xlcy5nZXQocm9sZUlkKSBhcyBSb2xlO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBzZXRVc2VyVmFyaWFibGVzICh2YWx1ZTogVXNlclZhcmlhYmxlcyB8IG51bGwpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdXNlclZhcmlhYmxlcy52YWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2dldFVuaXRJZHMgKHRlc3RzOiBUZXN0W10pOiBzdHJpbmdbXSB7XG4gICAgICAgIGNvbnN0IHRlc3RJZHMgICAgID0gdGVzdHMubWFwKHRlc3QgPT4gdGVzdC5pZCk7XG4gICAgICAgIGNvbnN0IGZpeHR1cmVJZHMgID0gdGVzdHMubWFwKHRlc3QgPT4gdGVzdC5maXh0dXJlPy5pZCkgYXMgc3RyaW5nW107XG4gICAgICAgIGNvbnN0IHRlc3RGaWxlSWRzID0gdGVzdHMubWFwKHRlc3QgPT4gdGVzdC50ZXN0RmlsZS5pZCk7XG5cbiAgICAgICAgcmV0dXJuIHVuaXEoWy4uLnRlc3RJZHMsIC4uLmZpeHR1cmVJZHMsIC4uLnRlc3RGaWxlSWRzXSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHNldE9wdGlvbnMgKHsgdmFsdWUgfTogU2V0T3B0aW9uc0FyZ3VtZW50cyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLnN0YXRlLm9wdGlvbnMgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgcmVhZHkgKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLnByb3h5LmNhbGwodGhpcy5yZWFkeSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGNsZWFuVXAgKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCBDb21waWxlci5jbGVhblVwKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGdldFRlc3RzICh7IHNvdXJjZUxpc3QsIGNvbXBpbGVyT3B0aW9ucywgcnVubmFibGVDb25maWd1cmF0aW9uSWQgfTogQ29tcGlsZXJBcmd1bWVudHMsIGJhc2VVcmw/OiBzdHJpbmcpOiBQcm9taXNlPFVuaXRzPiB7XG4gICAgICAgIGNvbnN0IGNvbXBpbGVyID0gbmV3IENvbXBpbGVyKHNvdXJjZUxpc3QsIGNvbXBpbGVyT3B0aW9ucywgeyBpc0NvbXBpbGVyU2VydmljZU1vZGU6IHRydWUsIGJhc2VVcmwsIGVzbTogZmFsc2UgfSk7XG5cbiAgICAgICAgY29uc3QgdGVzdHMgICA9IGF3YWl0IGNvbXBpbGVyLmdldFRlc3RzKCk7XG4gICAgICAgIGNvbnN0IHVuaXRzICAgPSBmbGF0dGVuVGVzdFN0cnVjdHVyZSh0ZXN0cyk7XG4gICAgICAgIGNvbnN0IHVuaXRJZHMgPSB0aGlzLl9nZXRVbml0SWRzKHRlc3RzKTtcblxuICAgICAgICB0aGlzLl9ydW5uYWJsZUNvbmZpZ3VyYXRpb25Vbml0c1JlbGF0aW9uc1tydW5uYWJsZUNvbmZpZ3VyYXRpb25JZF0gPSB1bml0SWRzO1xuXG4gICAgICAgIE9iamVjdC5hc3NpZ24odGhpcy5zdGF0ZS51bml0cywgdW5pdHMpO1xuXG4gICAgICAgIHJldHVybiBzZXJpYWxpemVUZXN0U3RydWN0dXJlKHVuaXRzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgcnVuVGVzdEZuIChhcmdzOiBSdW5UZXN0QXJndW1lbnRzKTogUHJvbWlzZTx1bmtub3duPiB7XG4gICAgICAgIGNvbnN0IHsgaWQsIGZ1bmN0aW9uTmFtZSB9ID0gYXJncztcblxuICAgICAgICBjb25zdCB1bml0ICAgICAgICAgICA9IHRoaXMuc3RhdGUudW5pdHNbaWRdO1xuICAgICAgICBjb25zdCBjb250ZXh0ICAgICAgICA9IHRoaXMuX2dldENvbnRleHQoYXJncywgdW5pdCk7XG4gICAgICAgIGNvbnN0IGZ1bmN0aW9uT2JqZWN0ID0gdGhpcy5fZ2V0RnVuY3Rpb24odW5pdCwgZnVuY3Rpb25OYW1lKTtcblxuICAgICAgICBpZiAoIWZ1bmN0aW9uT2JqZWN0KVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgZmluZCB0aGUgXCIke2Z1bmN0aW9uTmFtZX1cIiBvZiAke3R5cGVvZiB1bml0fWApO1xuXG4gICAgICAgIHJldHVybiBhd2FpdCBmdW5jdGlvbk9iamVjdChjb250ZXh0KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZXhlY3V0ZUNvbW1hbmRTeW5jICh7IGlkLCBjb21tYW5kLCBjYWxsc2l0ZSB9OiBFeGVjdXRlQ29tbWFuZEFyZ3VtZW50cyk6IHVua25vd24ge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm94eS5jYWxsU3luYyh0aGlzLmV4ZWN1dGVDb21tYW5kLCB7IGlkLCBjb21tYW5kLCBjYWxsc2l0ZSB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZXhlY3V0ZUNvbW1hbmQgKHsgY29tbWFuZCwgaWQsIGNhbGxzaXRlIH06IEV4ZWN1dGVDb21tYW5kQXJndW1lbnRzKTogUHJvbWlzZTx1bmtub3duPiB7XG4gICAgICAgIHJldHVybiB0aGlzLnByb3h5LmNhbGwodGhpcy5leGVjdXRlQ29tbWFuZCwgeyBpZCwgY29tbWFuZCwgY2FsbHNpdGUgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIG9uUmVxdWVzdEhvb2tFdmVudCAoeyBuYW1lLCB0ZXN0SWQsIGhvb2tJZCwgZXZlbnREYXRhIH06IFJlcXVlc3RIb29rRXZlbnRBcmd1bWVudHMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5fd3JhcEV2ZW50TWV0aG9kcyh7IG5hbWUsIHRlc3RJZCwgaG9va0lkLCBldmVudERhdGEgfSk7XG5cbiAgICAgICAgY29uc3QgdGVzdCAgICAgICA9IHRoaXMuc3RhdGUudW5pdHNbdGVzdElkXSBhcyBUZXN0O1xuICAgICAgICBjb25zdCB0YXJnZXRIb29rID0gdGVzdC5yZXF1ZXN0SG9va3MuZmluZChob29rID0+IGhvb2suaWQgPT09IGhvb2tJZCkgYXMgUmVxdWVzdEhvb2s7XG5cbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBhd2FpdCB0YXJnZXRIb29rW25hbWVdLmNhbGwodGFyZ2V0SG9vaywgZXZlbnREYXRhKTtcblxuICAgICAgICBpZiAobmFtZSA9PT0gUmVxdWVzdEhvb2tNZXRob2ROYW1lcy5fb25Db25maWd1cmVSZXNwb25zZSAmJiB0YXJnZXRIb29rLl9yZXNwb25zZUV2ZW50Q29uZmlndXJlT3B0cykge1xuICAgICAgICAgICAgY29uc3QgeyBvcHRzLCBpZDogZXZlbnRJZCB9ID0gZXZlbnREYXRhIGFzIENvbmZpZ3VyZVJlc3BvbnNlRXZlbnQ7XG5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc2V0Q29uZmlndXJlUmVzcG9uc2VFdmVudE9wdGlvbnMoeyBldmVudElkLCBvcHRzIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHNldE1vY2sgKHsgdGVzdElkLCBob29rSWQsIHJ1bGVJZCwgcmVzcG9uc2VFdmVudElkLCBtb2NrIH06IFNldE1vY2tBcmd1bWVudHMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5wcm94eS5jYWxsKHRoaXMuc2V0TW9jaywgeyB0ZXN0SWQsIGhvb2tJZCwgcnVsZUlkLCByZXNwb25zZUV2ZW50SWQsIG1vY2sgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHNldENvbmZpZ3VyZVJlc3BvbnNlRXZlbnRPcHRpb25zICh7IGV2ZW50SWQsIG9wdHMgfTogU2V0Q29uZmlndXJlUmVzcG9uc2VFdmVudE9wdGlvbnNBcmd1bWVudHMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5wcm94eS5jYWxsKHRoaXMuc2V0Q29uZmlndXJlUmVzcG9uc2VFdmVudE9wdGlvbnMsIHsgZXZlbnRJZCwgb3B0cyB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgc2V0SGVhZGVyT25Db25maWd1cmVSZXNwb25zZUV2ZW50ICh7IGV2ZW50SWQsIGhlYWRlck5hbWUsIGhlYWRlclZhbHVlIH06IFNldEhlYWRlck9uQ29uZmlndXJlUmVzcG9uc2VFdmVudEFyZ3VtZW50cyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLnByb3h5LmNhbGwodGhpcy5zZXRIZWFkZXJPbkNvbmZpZ3VyZVJlc3BvbnNlRXZlbnQsIHsgZXZlbnRJZCwgaGVhZGVyTmFtZSwgaGVhZGVyVmFsdWUgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIHJlbW92ZUhlYWRlck9uQ29uZmlndXJlUmVzcG9uc2VFdmVudCAoeyBldmVudElkLCBoZWFkZXJOYW1lIH06IFJlbW92ZUhlYWRlck9uQ29uZmlndXJlUmVzcG9uc2VFdmVudEFyZ3VtZW50cyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLnByb3h5LmNhbGwodGhpcy5yZW1vdmVIZWFkZXJPbkNvbmZpZ3VyZVJlc3BvbnNlRXZlbnQsIHsgZXZlbnRJZCwgaGVhZGVyTmFtZSB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZXhlY3V0ZVJlcXVlc3RGaWx0ZXJSdWxlUHJlZGljYXRlICh7IHRlc3RJZCwgaG9va0lkLCBydWxlSWQsIHJlcXVlc3RJbmZvIH06IEV4ZWN1dGVSZXF1ZXN0RmlsdGVyUnVsZVByZWRpY2F0ZUFyZ3VtZW50cyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgICAgICBjb25zdCB0ZXN0ICAgICAgID0gdGhpcy5zdGF0ZS51bml0c1t0ZXN0SWRdIGFzIFRlc3Q7XG4gICAgICAgIGNvbnN0IHRhcmdldEhvb2sgPSB0ZXN0LnJlcXVlc3RIb29rcy5maW5kKGhvb2sgPT4gaG9vay5pZCA9PT0gaG9va0lkKSBhcyBSZXF1ZXN0SG9vaztcbiAgICAgICAgY29uc3QgdGFyZ2V0UnVsZSA9IHRhcmdldEhvb2suX3JlcXVlc3RGaWx0ZXJSdWxlcy5maW5kKHJ1bGUgPT4gcnVsZS5pZCA9PT0gcnVsZUlkKSBhcyBSZXF1ZXN0RmlsdGVyUnVsZTtcbiAgICAgICAgY29uc3QgcmVzdWx0ICAgICA9IGF3YWl0IHRhcmdldFJ1bGUub3B0aW9ucy5jYWxsKHRhcmdldFJ1bGUsIHJlcXVlc3RJbmZvKTtcblxuICAgICAgICByZXR1cm4gISFyZXN1bHQ7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGV4ZWN1dGVNb2NrUHJlZGljYXRlICh7IHRlc3RJZCwgaG9va0lkLCBydWxlSWQsIHJlcXVlc3RJbmZvLCByZXMgfTogRXhlY3V0ZU1vY2tQcmVkaWNhdGUpOiBQcm9taXNlPEluY29taW5nTWVzc2FnZUxpa2VJbml0T3B0aW9ucz4ge1xuICAgICAgICBjb25zdCB0ZXN0ICAgICAgICAgPSB0aGlzLnN0YXRlLnVuaXRzW3Rlc3RJZF0gYXMgVGVzdDtcbiAgICAgICAgY29uc3QgcmVxdWVzdE1vY2sgID0gdGVzdC5yZXF1ZXN0SG9va3MuZmluZChob29rID0+IGhvb2suaWQgPT09IGhvb2tJZCkgYXMgUmVxdWVzdE1vY2s7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlTW9jayA9IHJlcXVlc3RNb2NrLm1vY2tzLmdldChydWxlSWQpIGFzIFJlc3BvbnNlTW9jaztcblxuICAgICAgICByZXNwb25zZU1vY2tTZXRCb2R5TWV0aG9kLmFkZChyZXMpO1xuXG4gICAgICAgIHJlcyA9IE9iamVjdC5hc3NpZ24ocmVzLCBhd2FpdCAocmVzcG9uc2VNb2NrLmJvZHkgYXMgRnVuY3Rpb24pKHJlcXVlc3RJbmZvLCByZXMpKTtcblxuICAgICAgICByZXNwb25zZU1vY2tTZXRCb2R5TWV0aG9kLnJlbW92ZShyZXMpO1xuXG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGdldFdhcm5pbmdNZXNzYWdlcyAoeyB0ZXN0UnVuSWQgfTogVGVzdFJ1bkxvY2F0b3IpOiBQcm9taXNlPFdhcm5pbmdMb2dNZXNzYWdlW10+IHtcbiAgICAgICAgLy8gTk9URTogSW4gY2FzZSBvZiByYWlzaW5nIGFuIGVycm9yIGludG8gUmVwb3J0ZXJQbHVnaW5Ib3N0IG1ldGhvZHMsXG4gICAgICAgIC8vIFRlc3RSdW4gaGFzIHRpbWUgdG8gc3RhcnQuXG4gICAgICAgIGNvbnN0IHRhcmdldFRlc3RSdW4gPSB0aGlzLl9nZXRUYXJnZXRUZXN0UnVuKHRlc3RSdW5JZCk7XG5cbiAgICAgICAgcmV0dXJuIHRhcmdldFRlc3RSdW4gPyB0YXJnZXRUZXN0UnVuLndhcm5pbmdMb2cubWVzc2FnZUluZm9zIDogW107XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGFkZFJlcXVlc3RFdmVudExpc3RlbmVycyAoIHsgaG9va0lkLCBob29rQ2xhc3NOYW1lLCBydWxlcyB9OiBBZGRSZXF1ZXN0RXZlbnRMaXN0ZW5lcnNBcmd1bWVudHMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucHJveHkuY2FsbCh0aGlzLmFkZFJlcXVlc3RFdmVudExpc3RlbmVycywgeyBob29rSWQsIGhvb2tDbGFzc05hbWUsIHJ1bGVzIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyByZW1vdmVSZXF1ZXN0RXZlbnRMaXN0ZW5lcnMgKHsgcnVsZXMgfTogUmVtb3ZlUmVxdWVzdEV2ZW50TGlzdGVuZXJzQXJndW1lbnRzKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLnByb3h5LmNhbGwodGhpcy5yZW1vdmVSZXF1ZXN0RXZlbnRMaXN0ZW5lcnMsIHsgcnVsZXMgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGluaXRpYWxpemVUZXN0UnVuRGF0YSAoeyB0ZXN0UnVuSWQsIHRlc3RJZCwgYnJvd3NlciwgYWN0aXZlV2luZG93SWQsIG1lc3NhZ2VCdXMsIGlzTmF0aXZlQXV0b21hdGlvbiB9OiBJbml0aWFsaXplVGVzdFJ1bkRhdGFBcmd1bWVudHMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgLy8gTk9URTogSW4gY2FzZSBvZiByYWlzaW5nIGFuIGVycm9yIGludG8gUmVwb3J0ZXJQbHVnaW5Ib3N0IG1ldGhvZHMsXG4gICAgICAgIC8vIFRlc3RSdW4gaGFzIHRpbWUgdG8gc3RhcnQuXG4gICAgICAgIGNvbnN0IHRlc3QgPSB0aGlzLnN0YXRlLnVuaXRzW3Rlc3RJZF0gYXMgVGVzdDtcblxuICAgICAgICBpZiAoIXRlc3QpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgdGhpcy5faW5pdGlhbGl6ZVRlc3RSdW5Qcm94eSh7IHRlc3RSdW5JZCwgdGVzdCwgYnJvd3NlciwgYWN0aXZlV2luZG93SWQsIG1lc3NhZ2VCdXMsIGlzTmF0aXZlQXV0b21hdGlvbiB9KTtcbiAgICAgICAgdGhpcy5faW5pdGlhbGl6ZUZpeHR1cmVDdHgodGVzdCk7XG4gICAgfVxuXG4gICAgcHVibGljIGVuYWJsZURlYnVnRm9yTm9uRGVidWdDb21tYW5kcyAoKTogdm9pZCB7XG4gICAgICAgIFRlc3RDb250cm9sbGVyLmVuYWJsZURlYnVnRm9yTm9uRGVidWdDb21tYW5kcygpO1xuICAgIH1cblxuICAgIHB1YmxpYyBkaXNhYmxlRGVidWdGb3JOb25EZWJ1Z0NvbW1hbmRzICgpOiB2b2lkIHtcbiAgICAgICAgVGVzdENvbnRyb2xsZXIuZGlzYWJsZURlYnVnRm9yTm9uRGVidWdDb21tYW5kcygpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBnZXRBc3NlcnRpb25BY3R1YWxWYWx1ZSAoeyB0ZXN0UnVuSWQsIGNvbW1hbmRJZCB9OiBDb21tYW5kTG9jYXRvcik6IFByb21pc2U8dW5rbm93bj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0VGFyZ2V0VGVzdFJ1bih0ZXN0UnVuSWQpLmdldEFzc2VydGlvbkFjdHVhbFZhbHVlKGNvbW1hbmRJZCk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGV4ZWN1dGVSb2xlSW5pdEZuICh7IHRlc3RSdW5JZCwgcm9sZUlkIH06IEV4ZWN1dGVSb2xlSW5pdEZuQXJndW1lbnRzKTogUHJvbWlzZTx1bmtub3duPiB7XG4gICAgICAgIGNvbnN0IHJvbGUgICAgICAgICA9IHRoaXMuX2dldFRhcmdldFJvbGUocm9sZUlkKTtcbiAgICAgICAgY29uc3QgdGVzdFJ1blByb3h5ID0gdGhpcy5fZ2V0VGFyZ2V0VGVzdFJ1bih0ZXN0UnVuSWQpO1xuXG4gICAgICAgIHJldHVybiAocm9sZS5faW5pdEZuIGFzIEZ1bmN0aW9uKSh0ZXN0UnVuUHJveHkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBnZXRDdHggKHsgdGVzdFJ1bklkIH06IFRlc3RSdW5Mb2NhdG9yKTogUHJvbWlzZTxvYmplY3Q+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldFRhcmdldFRlc3RSdW4odGVzdFJ1bklkKS5jdHg7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGdldEZpeHR1cmVDdHggKHsgdGVzdFJ1bklkIH06IFRlc3RSdW5Mb2NhdG9yKTogUHJvbWlzZTxvYmplY3Q+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldFRhcmdldFRlc3RSdW4odGVzdFJ1bklkKS5maXh0dXJlQ3R4O1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBzZXRDdHggKHsgdGVzdFJ1bklkLCB2YWx1ZSB9OiBTZXRDdHhBcmd1bWVudHMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5fZ2V0VGFyZ2V0VGVzdFJ1bih0ZXN0UnVuSWQpLmN0eCA9IHZhbHVlO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBzZXRGaXh0dXJlQ3R4ICh7IHRlc3RSdW5JZCwgdmFsdWUgfTogU2V0Q3R4QXJndW1lbnRzKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMuX2dldFRhcmdldFRlc3RSdW4odGVzdFJ1bklkKS5maXh0dXJlQ3R4ID0gdmFsdWU7XG4gICAgfVxuXG4gICAgcHVibGljIG9uUm9sZUFwcGVhcmVkIChyb2xlOiBSb2xlKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLnJvbGVzLmhhcyhyb2xlLmlkKSlcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICB0aGlzLnN0YXRlLnJvbGVzLnNldChyb2xlLmlkLCByb2xlKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgdXBkYXRlUm9sZVByb3BlcnR5ICh7IHJvbGVJZCwgbmFtZSwgdmFsdWUgfTogVXBkYXRlUm9sZVByb3BlcnR5QXJndW1lbnRzKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IHJvbGUgPSB0aGlzLl9nZXRUYXJnZXRSb2xlKHJvbGVJZCk7XG5cbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICByb2xlW25hbWVdID0gdmFsdWU7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGV4ZWN1dGVKc0V4cHJlc3Npb24gKHsgZXhwcmVzc2lvbiwgdGVzdFJ1bklkLCBvcHRpb25zIH06IEV4ZWN1dGVKc0V4cHJlc3Npb25Bcmd1bWVudHMpOiBQcm9taXNlPHVua25vd24+IHtcbiAgICAgICAgY29uc3QgdGVzdFJ1blByb3h5ID0gdGhpcy5fZ2V0VGFyZ2V0VGVzdFJ1bih0ZXN0UnVuSWQpO1xuXG4gICAgICAgIHJldHVybiBleGVjdXRlSnNFeHByZXNzaW9uKGV4cHJlc3Npb24sIHRlc3RSdW5Qcm94eSwgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGV4ZWN1dGVBc3luY0pzRXhwcmVzc2lvbiAoeyBleHByZXNzaW9uLCB0ZXN0UnVuSWQsIGNhbGxzaXRlIH06IEV4ZWN1dGVBc3luY0pzRXhwcmVzc2lvbkFyZ3VtZW50cyk6IFByb21pc2U8dW5rbm93bj4ge1xuICAgICAgICBjb25zdCB0ZXN0UnVuUHJveHkgPSB0aGlzLl9nZXRUYXJnZXRUZXN0UnVuKHRlc3RSdW5JZCk7XG5cbiAgICAgICAgcmV0dXJuIGV4ZWN1dGVBc3luY0pzRXhwcmVzc2lvbihleHByZXNzaW9uLCB0ZXN0UnVuUHJveHksIGNhbGxzaXRlLCBhc3luYyAoZXJyOiBVbmNhdWdodFRlc3RDYWZlRXJyb3JJbkN1c3RvbVNjcmlwdCB8IFVuY2F1Z2h0RXJyb3JJbkN1c3RvbVNjcmlwdCkgPT4ge1xuICAgICAgICAgICAgaWYgKGVyciBpbnN0YW5jZW9mIFVuY2F1Z2h0VGVzdENhZmVFcnJvckluQ3VzdG9tU2NyaXB0ID09PSBmYWxzZSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgICAgIGNvbnN0IHRhcmdldEVycm9yID0gZXJyIGFzIFVuY2F1Z2h0VGVzdENhZmVFcnJvckluQ3VzdG9tU2NyaXB0O1xuXG4gICAgICAgICAgICBpZiAoIXNob3VsZFJlbmRlckh0bWxXaXRob3V0U3RhY2sodGFyZ2V0RXJyb3IpKVxuICAgICAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICAgICAgdGVzdFJ1blByb3h5LnJlc3RvcmVPcmlnaW5DYWxsc2l0ZUZvckVycm9yKHRhcmdldEVycm9yKTtcblxuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgZXJyLmVyckNhbGxzaXRlID0gcmVuZGVySHRtbFdpdGhvdXRTdGFjayh0YXJnZXRFcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBleGVjdXRlQXNzZXJ0aW9uRm4gKHsgdGVzdFJ1bklkLCBjb21tYW5kSWQgfTogQ29tbWFuZExvY2F0b3IpOiBQcm9taXNlPHVua25vd24+IHtcbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICAgICAgICAgIC5fZ2V0VGFyZ2V0VGVzdFJ1bih0ZXN0UnVuSWQpXG4gICAgICAgICAgICAuZXhlY3V0ZUFzc2VydGlvbkZuKGNvbW1hbmRJZCk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGFkZFVuZXhwZWN0ZWRFcnJvciAoeyB0eXBlLCBtZXNzYWdlIH06IEFkZFVuZXhwZWN0ZWRFcnJvckFyZ3VtZW50cyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm94eS5jYWxsKHRoaXMuYWRkVW5leHBlY3RlZEVycm9yLCB7IHR5cGUsIG1lc3NhZ2UgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGNoZWNrV2luZG93ICh7IHRlc3RSdW5JZCwgY29tbWFuZElkLCB1cmwsIHRpdGxlIH06IENoZWNrV2luZG93QXJndW1lbnQpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzXG4gICAgICAgICAgICAgICAgLl9nZXRUYXJnZXRUZXN0UnVuKHRlc3RSdW5JZClcbiAgICAgICAgICAgICAgICAuY2hlY2tXaW5kb3coY29tbWFuZElkLCB7IHRpdGxlLCB1cmwgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgU3dpdGNoVG9XaW5kb3dQcmVkaWNhdGVFcnJvcihlcnIubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgcmVtb3ZlVGVzdFJ1bkZyb21TdGF0ZSAoeyB0ZXN0UnVuSWQgfTogVGVzdFJ1bkxvY2F0b3IpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgZGVsZXRlIHRoaXMuc3RhdGUudGVzdFJ1bnNbdGVzdFJ1bklkXTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgcmVtb3ZlRml4dHVyZUN0eHNGcm9tU3RhdGUgKHsgZml4dHVyZUlkcyB9OiBSZW1vdmVGaXh0dXJlQ3R4c0FyZ3VtZW50cyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBmb3IgKGNvbnN0IGZpeHR1cmVJZCBvZiBmaXh0dXJlSWRzKVxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3RhdGUuZml4dHVyZUN0eHNbZml4dHVyZUlkXTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgcmVtb3ZlVW5pdHNGcm9tU3RhdGUgKHsgcnVubmFibGVDb25maWd1cmF0aW9uSWQgfTogUmVtb3ZlVW5pdHNGcm9tU3RhdGVBcmd1bWVudHMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgdW5pdElkcyA9IHRoaXMuX3J1bm5hYmxlQ29uZmlndXJhdGlvblVuaXRzUmVsYXRpb25zW3J1bm5hYmxlQ29uZmlndXJhdGlvbklkXTtcblxuICAgICAgICBmb3IgKGNvbnN0IHVuaXRJZCBvZiB1bml0SWRzKVxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3RhdGUudW5pdHNbdW5pdElkXTtcblxuICAgICAgICBkZWxldGUgdGhpcy5fcnVubmFibGVDb25maWd1cmF0aW9uVW5pdHNSZWxhdGlvbnNbcnVubmFibGVDb25maWd1cmF0aW9uSWRdO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgbmV3IENvbXBpbGVyU2VydmljZSgpO1xuIl19