velocious 1.0.644 → 1.0.646
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -9
- package/build/authorization/ability.js +36 -13
- package/build/background-jobs/adapter.js +9 -0
- package/build/background-jobs/main.js +35 -10
- package/build/background-jobs/store.js +217 -38
- package/build/background-jobs/types.js +15 -0
- package/build/configuration-types.js +1 -1
- package/build/configuration.js +45 -9
- package/build/database/drivers/base-column.js +8 -0
- package/build/database/drivers/mssql/sql/update.js +1 -3
- package/build/database/drivers/mysql/sql/update.js +1 -3
- package/build/database/drivers/pgsql/column.js +22 -0
- package/build/database/drivers/pgsql/sql/update.js +1 -3
- package/build/database/drivers/sqlite/sql/alter-table.js +11 -1
- package/build/database/drivers/sqlite/sql/update.js +1 -3
- package/build/database/query/index.js +2 -2
- package/build/database/query/model-class-query.js +26 -10
- package/build/database/query/preloader/has-many.js +4 -1
- package/build/database/query/query-data.js +2 -1
- package/build/database/query/update-base.js +14 -0
- package/build/database/query/with-count.js +3 -1
- package/build/database/record/acts-as-list.js +37 -13
- package/build/database/record/attachments/store.js +336 -26
- package/build/database/record/auditing.js +6 -3
- package/build/database/record/index.js +197 -42
- package/build/database/record/instance-relationships/belongs-to.js +2 -1
- package/build/database/record/validators/uniqueness.js +8 -5
- package/build/environment-handlers/node/cli/commands/generate/frontend-models.js +24 -8
- package/build/frontend-model-controller.js +136 -53
- package/build/frontend-model-resource/base-resource.js +87 -37
- package/build/frontend-model-resource/velocious-attachment-resource.js +98 -31
- package/build/frontend-models/base.js +307 -59
- package/build/frontend-models/preloader.js +6 -3
- package/build/frontend-models/query.js +15 -6
- package/build/frontend-models/resource-definition.js +21 -2
- package/build/frontend-models/use-destroyed-event.js +1 -1
- package/build/frontend-models/use-model-class-event.js +2 -2
- package/build/frontend-models/use-updated-event.js +1 -1
- package/build/frontend-models/websocket-channel.js +256 -93
- package/build/frontend-models/websocket-publishers.js +218 -18
- package/build/http-server/client/websocket-session.js +13 -1
- package/build/http-server/websocket-channel.js +15 -2
- package/build/src/authorization/ability.d.ts +9 -3
- package/build/src/authorization/ability.d.ts.map +1 -1
- package/build/src/authorization/ability.js +33 -14
- package/build/src/background-jobs/adapter.d.ts +6 -0
- package/build/src/background-jobs/adapter.d.ts.map +1 -1
- package/build/src/background-jobs/adapter.js +9 -1
- package/build/src/background-jobs/main.d.ts +6 -0
- package/build/src/background-jobs/main.d.ts.map +1 -1
- package/build/src/background-jobs/main.js +34 -11
- package/build/src/background-jobs/store.d.ts +66 -12
- package/build/src/background-jobs/store.d.ts.map +1 -1
- package/build/src/background-jobs/store.js +191 -35
- package/build/src/background-jobs/types.d.ts +55 -0
- package/build/src/background-jobs/types.d.ts.map +1 -1
- package/build/src/background-jobs/types.js +16 -1
- package/build/src/configuration-types.d.ts +3 -3
- package/build/src/configuration-types.d.ts.map +1 -1
- package/build/src/configuration-types.js +2 -2
- package/build/src/configuration.d.ts +18 -8
- package/build/src/configuration.d.ts.map +1 -1
- package/build/src/configuration.js +38 -7
- package/build/src/database/drivers/base-column.d.ts +5 -0
- package/build/src/database/drivers/base-column.d.ts.map +1 -1
- package/build/src/database/drivers/base-column.js +8 -1
- package/build/src/database/drivers/mssql/sql/update.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/sql/update.js +2 -4
- package/build/src/database/drivers/mysql/sql/update.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/sql/update.js +2 -4
- package/build/src/database/drivers/pgsql/column.d.ts +5 -0
- package/build/src/database/drivers/pgsql/column.d.ts.map +1 -1
- package/build/src/database/drivers/pgsql/column.js +19 -1
- package/build/src/database/drivers/pgsql/sql/update.d.ts.map +1 -1
- package/build/src/database/drivers/pgsql/sql/update.js +2 -4
- package/build/src/database/drivers/sqlite/sql/alter-table.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/sql/alter-table.js +6 -2
- package/build/src/database/drivers/sqlite/sql/update.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/sql/update.js +2 -4
- package/build/src/database/query/index.d.ts +4 -4
- package/build/src/database/query/index.d.ts.map +1 -1
- package/build/src/database/query/index.js +3 -3
- package/build/src/database/query/model-class-query.d.ts +8 -2
- package/build/src/database/query/model-class-query.d.ts.map +1 -1
- package/build/src/database/query/model-class-query.js +25 -11
- package/build/src/database/query/preloader/has-many.d.ts.map +1 -1
- package/build/src/database/query/preloader/has-many.js +4 -2
- package/build/src/database/query/query-data.d.ts.map +1 -1
- package/build/src/database/query/query-data.js +3 -2
- package/build/src/database/query/update-base.d.ts +7 -0
- package/build/src/database/query/update-base.d.ts.map +1 -1
- package/build/src/database/query/update-base.js +13 -1
- package/build/src/database/query/with-count.d.ts.map +1 -1
- package/build/src/database/query/with-count.js +3 -2
- package/build/src/database/record/acts-as-list.d.ts.map +1 -1
- package/build/src/database/record/acts-as-list.js +35 -14
- package/build/src/database/record/attachments/store.d.ts +67 -0
- package/build/src/database/record/attachments/store.d.ts.map +1 -1
- package/build/src/database/record/attachments/store.js +301 -25
- package/build/src/database/record/auditing.d.ts.map +1 -1
- package/build/src/database/record/auditing.js +7 -4
- package/build/src/database/record/index.d.ts +78 -26
- package/build/src/database/record/index.d.ts.map +1 -1
- package/build/src/database/record/index.js +171 -42
- package/build/src/database/record/instance-relationships/belongs-to.d.ts.map +1 -1
- package/build/src/database/record/instance-relationships/belongs-to.js +3 -2
- package/build/src/database/record/validators/uniqueness.d.ts.map +1 -1
- package/build/src/database/record/validators/uniqueness.js +8 -6
- package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts +4 -4
- package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.js +24 -12
- package/build/src/frontend-model-controller.d.ts +29 -8
- package/build/src/frontend-model-controller.d.ts.map +1 -1
- package/build/src/frontend-model-controller.js +122 -51
- package/build/src/frontend-model-resource/base-resource.d.ts +51 -24
- package/build/src/frontend-model-resource/base-resource.d.ts.map +1 -1
- package/build/src/frontend-model-resource/base-resource.js +83 -37
- package/build/src/frontend-model-resource/velocious-attachment-resource.d.ts +45 -26
- package/build/src/frontend-model-resource/velocious-attachment-resource.d.ts.map +1 -1
- package/build/src/frontend-model-resource/velocious-attachment-resource.js +89 -31
- package/build/src/frontend-models/base.d.ts +53 -20
- package/build/src/frontend-models/base.d.ts.map +1 -1
- package/build/src/frontend-models/base.js +275 -59
- package/build/src/frontend-models/preloader.d.ts.map +1 -1
- package/build/src/frontend-models/preloader.js +6 -4
- package/build/src/frontend-models/query.d.ts +2 -2
- package/build/src/frontend-models/query.d.ts.map +1 -1
- package/build/src/frontend-models/query.js +14 -7
- package/build/src/frontend-models/resource-definition.d.ts.map +1 -1
- package/build/src/frontend-models/resource-definition.js +20 -3
- package/build/src/frontend-models/use-destroyed-event.d.ts +1 -1
- package/build/src/frontend-models/use-destroyed-event.d.ts.map +1 -1
- package/build/src/frontend-models/use-destroyed-event.js +2 -2
- package/build/src/frontend-models/use-model-class-event.d.ts +2 -2
- package/build/src/frontend-models/use-model-class-event.d.ts.map +1 -1
- package/build/src/frontend-models/use-model-class-event.js +3 -3
- package/build/src/frontend-models/use-updated-event.d.ts +1 -1
- package/build/src/frontend-models/use-updated-event.d.ts.map +1 -1
- package/build/src/frontend-models/use-updated-event.js +2 -2
- package/build/src/frontend-models/websocket-channel.d.ts +60 -41
- package/build/src/frontend-models/websocket-channel.d.ts.map +1 -1
- package/build/src/frontend-models/websocket-channel.js +225 -85
- package/build/src/frontend-models/websocket-publishers.d.ts +9 -0
- package/build/src/frontend-models/websocket-publishers.d.ts.map +1 -1
- package/build/src/frontend-models/websocket-publishers.js +190 -19
- package/build/src/http-server/client/websocket-session.d.ts.map +1 -1
- package/build/src/http-server/client/websocket-session.js +11 -2
- package/build/src/http-server/websocket-channel.d.ts +20 -8
- package/build/src/http-server/websocket-channel.d.ts.map +1 -1
- package/build/src/http-server/websocket-channel.js +15 -3
- package/build/src/sync/sync-api-client.d.ts.map +1 -1
- package/build/src/sync/sync-api-client.js +4 -3
- package/build/src/sync/sync-client.d.ts.map +1 -1
- package/build/src/sync/sync-client.js +3 -2
- package/build/src/sync/sync-envelope-replay-service.d.ts.map +1 -1
- package/build/src/sync/sync-envelope-replay-service.js +6 -5
- package/build/src/sync/sync-publisher.d.ts.map +1 -1
- package/build/src/sync/sync-publisher.js +4 -3
- package/build/src/testing/browser-frontend-model-event-hook-scenarios.d.ts +2 -2
- package/build/src/testing/browser-frontend-model-event-hook-scenarios.d.ts.map +1 -1
- package/build/src/testing/browser-frontend-model-event-hook-scenarios.js +3 -3
- package/build/src/testing/test-profiler.d.ts +4 -4
- package/build/src/testing/test-profiler.d.ts.map +1 -1
- package/build/src/testing/test-profiler.js +3 -3
- package/build/src/testing/test-runner.d.ts +271 -117
- package/build/src/testing/test-runner.d.ts.map +1 -1
- package/build/src/testing/test-runner.js +496 -427
- package/build/src/testing/test.d.ts +11 -72
- package/build/src/testing/test.d.ts.map +1 -1
- package/build/src/testing/test.js +131 -284
- package/build/src/testing/velocious-attempt-executor.d.ts +14 -29
- package/build/src/testing/velocious-attempt-executor.d.ts.map +1 -1
- package/build/src/testing/velocious-attempt-executor.js +52 -46
- package/build/src/testing/velocious-runner-reporter.d.ts +29 -34
- package/build/src/testing/velocious-runner-reporter.d.ts.map +1 -1
- package/build/src/testing/velocious-runner-reporter.js +145 -57
- package/build/src/testing/velocious-suite-hook-executor.d.ts +5 -23
- package/build/src/testing/velocious-suite-hook-executor.d.ts.map +1 -1
- package/build/src/testing/velocious-suite-hook-executor.js +22 -47
- package/build/src/testing/velocious-test-arguments.d.ts +11 -6
- package/build/src/testing/velocious-test-arguments.d.ts.map +1 -1
- package/build/src/testing/velocious-test-arguments.js +18 -10
- package/build/src/utils/model-primary-key.d.ts +73 -0
- package/build/src/utils/model-primary-key.d.ts.map +1 -0
- package/build/src/utils/model-primary-key.js +144 -0
- package/build/sync/sync-api-client.js +3 -2
- package/build/sync/sync-client.js +2 -1
- package/build/sync/sync-envelope-replay-service.js +5 -4
- package/build/sync/sync-publisher.js +3 -2
- package/build/testing/browser-frontend-model-event-hook-scenarios.js +2 -2
- package/build/testing/test-profiler.js +2 -2
- package/build/testing/test-runner.js +493 -449
- package/build/testing/test.js +164 -306
- package/build/testing/velocious-attempt-executor.js +55 -45
- package/build/testing/velocious-runner-reporter.js +156 -58
- package/build/testing/velocious-suite-hook-executor.js +22 -50
- package/build/testing/velocious-test-arguments.js +19 -10
- package/build/utils/model-primary-key.js +171 -0
- package/package.json +6 -5
- package/src/authorization/ability.js +36 -13
- package/src/background-jobs/adapter.js +9 -0
- package/src/background-jobs/main.js +35 -10
- package/src/background-jobs/store.js +217 -38
- package/src/background-jobs/types.js +15 -0
- package/src/configuration-types.js +1 -1
- package/src/configuration.js +45 -9
- package/src/database/drivers/base-column.js +8 -0
- package/src/database/drivers/mssql/sql/update.js +1 -3
- package/src/database/drivers/mysql/sql/update.js +1 -3
- package/src/database/drivers/pgsql/column.js +22 -0
- package/src/database/drivers/pgsql/sql/update.js +1 -3
- package/src/database/drivers/sqlite/sql/alter-table.js +11 -1
- package/src/database/drivers/sqlite/sql/update.js +1 -3
- package/src/database/query/index.js +2 -2
- package/src/database/query/model-class-query.js +26 -10
- package/src/database/query/preloader/has-many.js +4 -1
- package/src/database/query/query-data.js +2 -1
- package/src/database/query/update-base.js +14 -0
- package/src/database/query/with-count.js +3 -1
- package/src/database/record/acts-as-list.js +37 -13
- package/src/database/record/attachments/store.js +336 -26
- package/src/database/record/auditing.js +6 -3
- package/src/database/record/index.js +197 -42
- package/src/database/record/instance-relationships/belongs-to.js +2 -1
- package/src/database/record/validators/uniqueness.js +8 -5
- package/src/environment-handlers/node/cli/commands/generate/frontend-models.js +24 -8
- package/src/frontend-model-controller.js +136 -53
- package/src/frontend-model-resource/base-resource.js +87 -37
- package/src/frontend-model-resource/velocious-attachment-resource.js +98 -31
- package/src/frontend-models/base.js +307 -59
- package/src/frontend-models/preloader.js +6 -3
- package/src/frontend-models/query.js +15 -6
- package/src/frontend-models/resource-definition.js +21 -2
- package/src/frontend-models/use-destroyed-event.js +1 -1
- package/src/frontend-models/use-model-class-event.js +2 -2
- package/src/frontend-models/use-updated-event.js +1 -1
- package/src/frontend-models/websocket-channel.js +256 -93
- package/src/frontend-models/websocket-publishers.js +218 -18
- package/src/http-server/client/websocket-session.js +13 -1
- package/src/http-server/websocket-channel.js +15 -2
- package/src/sync/sync-api-client.js +3 -2
- package/src/sync/sync-client.js +2 -1
- package/src/sync/sync-envelope-replay-service.js +5 -4
- package/src/sync/sync-publisher.js +3 -2
- package/src/testing/browser-frontend-model-event-hook-scenarios.js +2 -2
- package/src/testing/test-profiler.js +2 -2
- package/src/testing/test-runner.js +493 -449
- package/src/testing/test.js +164 -306
- package/src/testing/velocious-attempt-executor.js +55 -45
- package/src/testing/velocious-runner-reporter.js +156 -58
- package/src/testing/velocious-suite-hook-executor.js +22 -50
- package/src/testing/velocious-test-arguments.js +19 -10
- package/src/utils/model-primary-key.js +171 -0
- package/build/src/testing/testing-package-adapter.d.ts +0 -9
- package/build/src/testing/testing-package-adapter.d.ts.map +0 -1
- package/build/src/testing/testing-package-adapter.js +0 -69
- package/build/testing/testing-package-adapter.js +0 -76
- package/build/tsconfig.tsbuildinfo +0 -1
- package/src/testing/testing-package-adapter.js +0 -76
|
@@ -1,24 +1,27 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import fs from "node:fs/promises";
|
|
3
3
|
import path from "path";
|
|
4
|
-
import { format } from "node:util";
|
|
5
4
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5
|
+
import { createTestContext, defaultTestContext } from "@velocious/testing";
|
|
6
|
+
import { TestRunner as PackageTestRunner } from "@velocious/testing/runner";
|
|
6
7
|
import Application from "../../src/application.js";
|
|
7
8
|
import RequestClient from "./request-client.js";
|
|
8
9
|
import picocolors from "picocolors";
|
|
9
10
|
import restArgsError from "../utils/rest-args-error.js";
|
|
10
|
-
import { testConfig
|
|
11
|
-
import { pathToFileURL } from "url";
|
|
11
|
+
import { testConfig } from "./test.js";
|
|
12
|
+
import { fileURLToPath, pathToFileURL } from "url";
|
|
12
13
|
import SharedTransactionBroker from "./shared-transaction-broker.js";
|
|
13
14
|
import { SHARED_TRANSACTION_BROKER_ENV } from "./shared-transaction-proxy-driver.js";
|
|
14
|
-
import { synchronizeTestingPackageTests } from "./testing-package-adapter.js";
|
|
15
15
|
import VelociousAttemptExecutor from "./velocious-attempt-executor.js";
|
|
16
|
-
import VelociousRunnerReporter from "./velocious-runner-reporter.js";
|
|
16
|
+
import VelociousRunnerReporter, { AbortRemainingTestsError } from "./velocious-runner-reporter.js";
|
|
17
17
|
import VelociousSuiteHookExecutor from "./velocious-suite-hook-executor.js";
|
|
18
18
|
import VelociousTestArguments from "./velocious-test-arguments.js";
|
|
19
|
-
/**
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
/** @typedef {typeof defaultTestContext} PackageTestContext */
|
|
20
|
+
/** @typedef {(typeof defaultTestContext.registry.suites)[number]} PackageSuiteDeclaration */
|
|
21
|
+
/** @typedef {PackageSuiteDeclaration["tests"][number]} PackageTestDeclaration */
|
|
22
|
+
/** @typedef {PackageSuiteDeclaration["hooks"]["beforeAll"][number]} PackageHookDeclaration */
|
|
23
|
+
/** @typedef {PackageSuiteDeclaration | PackageTestDeclaration | PackageHookDeclaration} PackageRegistration */
|
|
24
|
+
/** @typedef {{hadRetries: boolean, options: PackageTestDeclaration["options"], retries: number | undefined}} PackageRetryOptionRestoration */
|
|
22
25
|
/**
|
|
23
26
|
* AttemptConsoleOutput type.
|
|
24
27
|
* @typedef {object} AttemptConsoleOutput
|
|
@@ -60,6 +63,7 @@ import VelociousTestArguments from "./velocious-test-arguments.js";
|
|
|
60
63
|
* @property {number} [line] - Source line number.
|
|
61
64
|
* @property {string} [ownerFilePath] - Deterministic importing test file.
|
|
62
65
|
* @property {(arg: TestArgs) => (void|Promise<void>)} function - Test callback to execute.
|
|
66
|
+
* @property {PackageTestDeclaration} [declaration] - Package declaration.
|
|
63
67
|
*/
|
|
64
68
|
/**
|
|
65
69
|
* FailedTestDetail type.
|
|
@@ -71,13 +75,6 @@ import VelociousTestArguments from "./velocious-test-arguments.js";
|
|
|
71
75
|
* @property {string} [consoleOutput] - Captured console output while test ran.
|
|
72
76
|
* @property {string} [consoleLogPath] - Saved console log path.
|
|
73
77
|
*/
|
|
74
|
-
/**
|
|
75
|
-
* ActiveAfterAllScopeEntry type.
|
|
76
|
-
* @typedef {object} ActiveAfterAllScopeEntry
|
|
77
|
-
* @property {TestsArgument} tests - Scope test tree.
|
|
78
|
-
* @property {boolean} afterAllsRun - Whether cleanup hooks have run.
|
|
79
|
-
* @property {string} [profileScopeId] - Opaque profile scope identifier.
|
|
80
|
-
*/
|
|
81
78
|
/**
|
|
82
79
|
* Defines this typedef.
|
|
83
80
|
* @typedef {(args: {configuration: import("../configuration.js").default, testArgs: TestArgs, testData: TestData}) => (void|Promise<void>)} AfterBeforeEachCallbackType
|
|
@@ -141,10 +138,6 @@ import VelociousTestArguments from "./velocious-test-arguments.js";
|
|
|
141
138
|
* @property {string} reuseKey - Resolved physical configuration identity.
|
|
142
139
|
* @property {import("../database/pool/base.js").TestSharedConnectionRegistration | undefined} sharedRegistration - Physical-key shared registration once published.
|
|
143
140
|
*/
|
|
144
|
-
/**
|
|
145
|
-
* Captured console methods.
|
|
146
|
-
* @type {ConsoleMethodName[]} */
|
|
147
|
-
const CAPTURED_CONSOLE_METHODS = ["log", "info", "warn", "error", "debug"];
|
|
148
141
|
/**
|
|
149
142
|
* Runs to file slug.
|
|
150
143
|
* @param {string} value - Value to sanitize.
|
|
@@ -158,10 +151,8 @@ function toFileSlug(value) {
|
|
|
158
151
|
.slice(0, 80) || "failed-test";
|
|
159
152
|
}
|
|
160
153
|
export default class TestRunner {
|
|
161
|
-
/**
|
|
162
|
-
|
|
163
|
-
* @type {ActiveAfterAllScopeEntry[]} */
|
|
164
|
-
_activeAfterAllScopes;
|
|
154
|
+
/** @type {PackageTestContext} */
|
|
155
|
+
_context;
|
|
165
156
|
/**
|
|
166
157
|
* Narrows the runtime value to the documented type.
|
|
167
158
|
* @type {FailedTestDetail[]} */
|
|
@@ -170,6 +161,7 @@ export default class TestRunner {
|
|
|
170
161
|
* Runs constructor.
|
|
171
162
|
* @param {object} args - Options object.
|
|
172
163
|
* @param {import("../configuration.js").default} args.configuration - Configuration instance.
|
|
164
|
+
* @param {PackageTestContext} [args.context] - Declaration context.
|
|
173
165
|
* @param {string[] | string} [args.excludeTags] - Tags to exclude.
|
|
174
166
|
* @param {string[] | string} [args.includeTags] - Tags to include.
|
|
175
167
|
* @param {Array<string>} args.testFiles - Test files.
|
|
@@ -177,17 +169,16 @@ export default class TestRunner {
|
|
|
177
169
|
* @param {RegExp[]} [args.examplePatterns] - Example patterns.
|
|
178
170
|
* @param {import("./test-profiler.js").default} [args.profiler] - Opt-in profiler.
|
|
179
171
|
*/
|
|
180
|
-
constructor({ configuration, excludeTags, includeTags, testFiles, lineFilters, examplePatterns, profiler, ...restArgs }) {
|
|
172
|
+
constructor({ configuration, context = defaultTestContext, excludeTags, includeTags, testFiles, lineFilters, examplePatterns, profiler, ...restArgs }) {
|
|
181
173
|
restArgsError(restArgs);
|
|
182
174
|
if (!configuration)
|
|
183
175
|
throw new Error("configuration is required");
|
|
184
176
|
this._configuration = configuration;
|
|
177
|
+
this._context = context;
|
|
185
178
|
this._sharedTransactionCoordinatorOwnerStorage = new AsyncLocalStorage();
|
|
186
179
|
this._testDatabaseAccessScopeStorage = new AsyncLocalStorage();
|
|
187
180
|
this._excludeTags = this.normalizeTags(excludeTags);
|
|
188
|
-
this._excludeTagSet = new Set(this._excludeTags);
|
|
189
181
|
this._includeTags = this.normalizeTags(includeTags);
|
|
190
|
-
this._includeTagSet = new Set(this._includeTags);
|
|
191
182
|
this._testFiles = testFiles;
|
|
192
183
|
this._lineFilters = lineFilters || {};
|
|
193
184
|
this._examplePatterns = examplePatterns || [];
|
|
@@ -196,17 +187,47 @@ export default class TestRunner {
|
|
|
196
187
|
this._failedTests = 0;
|
|
197
188
|
this._successfulTests = 0;
|
|
198
189
|
this._testsCount = 0;
|
|
199
|
-
this._activeAfterAllScopes = [];
|
|
200
190
|
this._failedTestDetails = [];
|
|
201
191
|
/** @type {{fullDescription: string, filePath: string, line: number} | null} */
|
|
202
192
|
this._lastTestContext = null;
|
|
203
193
|
/** @type {Array<{fullDescription: string, filePath: string, line: number, durationMs: number}>} */
|
|
204
194
|
this._testDurations = [];
|
|
195
|
+
/** @type {WeakMap<PackageTestDeclaration, {testArgs: TestArgs, testData: TestData}>} */
|
|
196
|
+
this._testCompatibility = new WeakMap();
|
|
197
|
+
/** @type {WeakSet<PackageTestDeclaration>} */
|
|
198
|
+
this._injectedTests = new WeakSet();
|
|
199
|
+
/** @type {WeakSet<PackageTestDeclaration>} */
|
|
200
|
+
this._completedTests = new WeakSet();
|
|
201
|
+
/** @type {WeakMap<PackageTestDeclaration, {descriptions: string[], testDescription: string, fullDescription: string, ownerFilePath: string | undefined, suites: PackageSuiteDeclaration[]}>} */
|
|
202
|
+
this._testMetadata = new WeakMap();
|
|
203
|
+
/** @type {WeakMap<PackageHookDeclaration, {declarationIndex: number, declarationScopeId: string | undefined, ownerFilePath: string | undefined}>} */
|
|
204
|
+
this._hookMetadata = new WeakMap();
|
|
205
|
+
/** @type {WeakMap<PackageTestDeclaration, Map<number, {abortRemainingTests: boolean, error: ReturnType<typeof JSON.parse>, failed: boolean}>>} */
|
|
206
|
+
this._attemptOutcomes = new WeakMap();
|
|
207
|
+
/** @type {Array<{suite: PackageSuiteDeclaration, phase: "beforeAll" | "afterAll", error: ReturnType<typeof JSON.parse>}>} */
|
|
208
|
+
this._suiteHookFailures = [];
|
|
209
|
+
/** @type {Map<string, PackageTestDeclaration[]>} */
|
|
210
|
+
this._testsByFullName = new Map();
|
|
211
|
+
/** @type {WeakMap<PackageRegistration, string>} */
|
|
212
|
+
this._declarationOwners = new WeakMap();
|
|
213
|
+
/** @type {PackageTestRunner | undefined} */
|
|
214
|
+
this._packageRunner = undefined;
|
|
215
|
+
/** @type {import("@velocious/testing/runner").TestRunResult | undefined} */
|
|
216
|
+
this._packageResult = undefined;
|
|
217
|
+
/** @type {Map<string, TestData> | undefined} */
|
|
218
|
+
this._legacyFixtureDataByFullName = undefined;
|
|
219
|
+
/** @type {{filePath?: string, line?: number}} */
|
|
220
|
+
this._legacyFixtureLocation = {};
|
|
205
221
|
this._attemptExecutor = new VelociousAttemptExecutor({ testRunner: this });
|
|
206
222
|
this._runnerReporter = new VelociousRunnerReporter({ testRunner: this });
|
|
207
223
|
this._suiteHookExecutor = new VelociousSuiteHookExecutor({ testRunner: this });
|
|
208
224
|
this._testArguments = new VelociousTestArguments({ testRunner: this });
|
|
209
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Gets the package declaration context.
|
|
228
|
+
* @returns {PackageTestContext} - Package declaration context.
|
|
229
|
+
*/
|
|
230
|
+
getTestContext() { return this._context; }
|
|
210
231
|
/**
|
|
211
232
|
* Runs get configuration.
|
|
212
233
|
* @returns {import("../configuration.js").default} - The configuration.
|
|
@@ -243,23 +264,6 @@ export default class TestRunner {
|
|
|
243
264
|
return await callback();
|
|
244
265
|
return await this._profiler.runSpan(metadata, callback);
|
|
245
266
|
}
|
|
246
|
-
/**
|
|
247
|
-
* Adds declaration metadata to hooks only for an active profile.
|
|
248
|
-
* @template {AfterBeforeEachCallbackObjectType | BeforeAfterAllCallbackObjectType} T
|
|
249
|
-
* @param {T[]} hooks - Hooks declared in one scope.
|
|
250
|
-
* @param {string | undefined} declarationScopeId - Profile scope identifier.
|
|
251
|
-
* @param {string | undefined} ownerFilePath - Scope owner file.
|
|
252
|
-
* @returns {T[]} - Profile-aware hook entries.
|
|
253
|
-
*/
|
|
254
|
-
profileHookEntries(hooks, declarationScopeId, ownerFilePath) {
|
|
255
|
-
if (!this._profiler)
|
|
256
|
-
return hooks;
|
|
257
|
-
return hooks.map((hook, declarationIndex) => Object.assign({}, hook, {
|
|
258
|
-
declarationIndex: hook.declarationIndex ?? declarationIndex,
|
|
259
|
-
declarationScopeId: hook.declarationScopeId ?? declarationScopeId,
|
|
260
|
-
ownerFilePath: hook.ownerFilePath ?? ownerFilePath
|
|
261
|
-
}));
|
|
262
|
-
}
|
|
263
267
|
/**
|
|
264
268
|
* Runs normalize tags.
|
|
265
269
|
* @param {string[] | string | undefined} tags - Tags.
|
|
@@ -536,99 +540,6 @@ export default class TestRunner {
|
|
|
536
540
|
const configTags = Array.isArray(testConfig.excludeTags) ? testConfig.excludeTags : [];
|
|
537
541
|
return new Set([...this._excludeTags, ...configTags]);
|
|
538
542
|
}
|
|
539
|
-
/**
|
|
540
|
-
* Runs has matching tag.
|
|
541
|
-
* @param {string[] | string | undefined} testTags - Test tags.
|
|
542
|
-
* @param {Set<string>} tagSet - Tag set.
|
|
543
|
-
* @returns {boolean} - Whether any tags match.
|
|
544
|
-
*/
|
|
545
|
-
hasMatchingTag(testTags, tagSet) {
|
|
546
|
-
if (!tagSet.size)
|
|
547
|
-
return false;
|
|
548
|
-
const normalized = this.normalizeTags(testTags);
|
|
549
|
-
for (const tag of normalized) {
|
|
550
|
-
if (tagSet.has(tag))
|
|
551
|
-
return true;
|
|
552
|
-
}
|
|
553
|
-
return false;
|
|
554
|
-
}
|
|
555
|
-
/**
|
|
556
|
-
* Runs has runnable tests.
|
|
557
|
-
* @param {TestsArgument} tests - Tests.
|
|
558
|
-
* @param {string[]} [descriptions] - Description stack.
|
|
559
|
-
* @param {boolean} [lineMatchedInScope] - Whether line matched in scope.
|
|
560
|
-
* @returns {boolean} - Whether any tests in this scope will run.
|
|
561
|
-
*/
|
|
562
|
-
hasRunnableTests(tests, descriptions = [], lineMatchedInScope = false) {
|
|
563
|
-
for (const testDescription in tests.tests) {
|
|
564
|
-
const testData = tests.tests[testDescription];
|
|
565
|
-
const testArgs = /** @type {TestArgs} */ (Object.assign({}, testData.args));
|
|
566
|
-
const includeByLine = lineMatchedInScope || this.matchesLineFilter(testData);
|
|
567
|
-
if (this._onlyFocussed && !testArgs.focus)
|
|
568
|
-
continue;
|
|
569
|
-
if (this.shouldSkipTest(testArgs, testData, testDescription, descriptions, includeByLine))
|
|
570
|
-
continue;
|
|
571
|
-
return true;
|
|
572
|
-
}
|
|
573
|
-
for (const subDescription in tests.subs) {
|
|
574
|
-
const subTest = tests.subs[subDescription];
|
|
575
|
-
const scopeLineMatch = lineMatchedInScope || this.matchesLineFilter(subTest);
|
|
576
|
-
const nextDescriptions = descriptions.concat([subDescription]);
|
|
577
|
-
if (this._onlyFocussed && !subTest.anyTestsFocussed)
|
|
578
|
-
continue;
|
|
579
|
-
if (this.hasRunnableTests(subTest, nextDescriptions, scopeLineMatch))
|
|
580
|
-
return true;
|
|
581
|
-
}
|
|
582
|
-
return false;
|
|
583
|
-
}
|
|
584
|
-
/**
|
|
585
|
-
* Runs should skip test.
|
|
586
|
-
* @param {TestArgs} testArgs - Test args.
|
|
587
|
-
* @param {TestData} testData - Test data.
|
|
588
|
-
* @param {string} testDescription - Test description.
|
|
589
|
-
* @param {string[]} descriptions - Description stack.
|
|
590
|
-
* @param {boolean} lineMatchedInScope - Whether line matched in scope.
|
|
591
|
-
* @returns {boolean} - Whether the test should be skipped.
|
|
592
|
-
*/
|
|
593
|
-
shouldSkipTest(testArgs, testData, testDescription, descriptions, lineMatchedInScope) {
|
|
594
|
-
if (this.hasTag(testArgs, "browser-only") && !this.isBrowserTestMode())
|
|
595
|
-
return true;
|
|
596
|
-
if (this.hasMatchingTag(testArgs.tags, this.getExcludeTagSet()))
|
|
597
|
-
return true;
|
|
598
|
-
if (this._includeTagSet.size > 0 && !testArgs.focus) {
|
|
599
|
-
if (!this.hasMatchingTag(testArgs.tags, this._includeTagSet))
|
|
600
|
-
return true;
|
|
601
|
-
}
|
|
602
|
-
if (this.getExamplePatterns().length > 0) {
|
|
603
|
-
const fullDescription = this.buildFullDescription(descriptions, testDescription);
|
|
604
|
-
const matches = this.getExamplePatterns().some((pattern) => {
|
|
605
|
-
pattern.lastIndex = 0;
|
|
606
|
-
return pattern.test(fullDescription);
|
|
607
|
-
});
|
|
608
|
-
if (!matches)
|
|
609
|
-
return true;
|
|
610
|
-
}
|
|
611
|
-
const lineFilters = this.getLineFilters();
|
|
612
|
-
if (Object.keys(lineFilters).length > 0) {
|
|
613
|
-
if (!lineMatchedInScope && !this.matchesLineFilter(testData))
|
|
614
|
-
return true;
|
|
615
|
-
}
|
|
616
|
-
return false;
|
|
617
|
-
}
|
|
618
|
-
/**
|
|
619
|
-
* Runs matches line filter.
|
|
620
|
-
* @param {TestData | TestsArgument} entry - Test entry.
|
|
621
|
-
* @returns {boolean} - Whether line filter matches entry.
|
|
622
|
-
*/
|
|
623
|
-
matchesLineFilter(entry) {
|
|
624
|
-
if (!entry || !entry.filePath || !entry.line)
|
|
625
|
-
return false;
|
|
626
|
-
const filePath = path.resolve(entry.filePath);
|
|
627
|
-
const lines = this.getLineFilters()[filePath];
|
|
628
|
-
if (!lines || lines.length === 0)
|
|
629
|
-
return false;
|
|
630
|
-
return lines.includes(entry.line);
|
|
631
|
-
}
|
|
632
543
|
/**
|
|
633
544
|
* Runs build full description.
|
|
634
545
|
* @param {string[]} descriptions - Description stack.
|
|
@@ -967,63 +878,53 @@ export default class TestRunner {
|
|
|
967
878
|
const environmentHandler = this.getConfiguration().getEnvironmentHandler();
|
|
968
879
|
if (!this._profiler) {
|
|
969
880
|
await environmentHandler.importTestFiles(this.getTestFiles());
|
|
970
|
-
synchronizeTestingPackageTests(tests);
|
|
971
881
|
return;
|
|
972
882
|
}
|
|
973
883
|
for (const testFile of this.getTestFiles()) {
|
|
974
|
-
const existingRegistrations = this.testRegistrationObjects(
|
|
884
|
+
const existingRegistrations = this.testRegistrationObjects();
|
|
975
885
|
await this._profiler.measurePhase("imports", async () => {
|
|
976
886
|
await environmentHandler.importTestFiles([testFile]);
|
|
977
887
|
}, { filePath: testFile });
|
|
978
|
-
|
|
979
|
-
this.assignTestRegistrationOwnership(tests, existingRegistrations, testFile);
|
|
888
|
+
this.assignTestRegistrationOwnership(existingRegistrations, testFile);
|
|
980
889
|
}
|
|
981
890
|
}
|
|
982
891
|
/**
|
|
983
|
-
* Collects
|
|
984
|
-
* @param {
|
|
985
|
-
* @
|
|
986
|
-
* @returns {Set<object>} - Registration identities.
|
|
892
|
+
* Collects package declaration objects by identity.
|
|
893
|
+
* @param {Set<PackageRegistration>} [registrations] - Accumulated identities.
|
|
894
|
+
* @returns {Set<PackageRegistration>} - Registration identities.
|
|
987
895
|
*/
|
|
988
|
-
testRegistrationObjects(
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
896
|
+
testRegistrationObjects(registrations = new Set()) {
|
|
897
|
+
const visit = (/** @type {PackageSuiteDeclaration} */ suite) => {
|
|
898
|
+
registrations.add(suite);
|
|
899
|
+
for (const hook of [...suite.hooks.beforeAll, ...suite.hooks.beforeEach, ...suite.hooks.afterEach, ...suite.hooks.afterAll]) {
|
|
900
|
+
registrations.add(hook);
|
|
901
|
+
}
|
|
902
|
+
for (const testDeclaration of suite.tests)
|
|
903
|
+
registrations.add(testDeclaration);
|
|
904
|
+
for (const childSuite of suite.suites)
|
|
905
|
+
visit(childSuite);
|
|
906
|
+
};
|
|
907
|
+
for (const suite of this.getTestContext().registry.suites)
|
|
908
|
+
visit(suite);
|
|
997
909
|
return registrations;
|
|
998
910
|
}
|
|
999
911
|
/**
|
|
1000
|
-
* Assigns deterministic ownership to
|
|
1001
|
-
*
|
|
1002
|
-
* @param {TestsArgument} scope - Test scope.
|
|
1003
|
-
* @param {Set<object>} previousRegistrations - Identities present before import.
|
|
912
|
+
* Assigns deterministic ownership to package declarations added by one entry file.
|
|
913
|
+
* @param {Set<PackageRegistration>} previousRegistrations - Identities present before import.
|
|
1004
914
|
* @param {string} ownerFilePath - Importing entry file.
|
|
1005
915
|
* @returns {void}
|
|
1006
916
|
*/
|
|
1007
|
-
assignTestRegistrationOwnership(
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
if (!previousRegistrations.has(hook))
|
|
1012
|
-
hook.ownerFilePath ??= ownerFilePath;
|
|
1013
|
-
}
|
|
1014
|
-
for (const testData of Object.values(scope.tests)) {
|
|
1015
|
-
if (!previousRegistrations.has(testData))
|
|
1016
|
-
testData.ownerFilePath ??= ownerFilePath;
|
|
1017
|
-
}
|
|
1018
|
-
for (const childScope of Object.values(scope.subs)) {
|
|
1019
|
-
this.assignTestRegistrationOwnership(childScope, previousRegistrations, ownerFilePath);
|
|
917
|
+
assignTestRegistrationOwnership(previousRegistrations, ownerFilePath) {
|
|
918
|
+
for (const registration of this.testRegistrationObjects()) {
|
|
919
|
+
if (!previousRegistrations.has(registration))
|
|
920
|
+
this._declarationOwners.set(registration, ownerFilePath);
|
|
1020
921
|
}
|
|
1021
922
|
}
|
|
1022
923
|
/**
|
|
1023
924
|
* Runs is failed.
|
|
1024
925
|
* @returns {boolean} - Whether failed.
|
|
1025
926
|
*/
|
|
1026
|
-
isFailed() { return this._failedTests !== undefined && this._failedTests > 0; }
|
|
927
|
+
isFailed() { return this._failedTests !== undefined && (this._failedTests > 0 || this._packageResult?.status === "failed"); }
|
|
1027
928
|
/**
|
|
1028
929
|
* Runs get failed tests.
|
|
1029
930
|
* @returns {number} - The failed tests.
|
|
@@ -1101,7 +1002,7 @@ export default class TestRunner {
|
|
|
1101
1002
|
* @returns {number} - The executed tests count.
|
|
1102
1003
|
*/
|
|
1103
1004
|
getExecutedTestsCount() {
|
|
1104
|
-
return this._testDurations.length;
|
|
1005
|
+
return this._packageResult?.tests.length ?? this._testDurations.length;
|
|
1105
1006
|
}
|
|
1106
1007
|
/**
|
|
1107
1008
|
* Returns the tests recorded during the run, slowest first.
|
|
@@ -1124,15 +1025,75 @@ export default class TestRunner {
|
|
|
1124
1025
|
this._abortRemainingTests = false;
|
|
1125
1026
|
this._failedTestDetails = [];
|
|
1126
1027
|
this._testDurations = [];
|
|
1028
|
+
this._testCompatibility = new WeakMap();
|
|
1029
|
+
this._injectedTests = new WeakSet();
|
|
1030
|
+
this._completedTests = new WeakSet();
|
|
1031
|
+
this._testMetadata = new WeakMap();
|
|
1032
|
+
this._hookMetadata = new WeakMap();
|
|
1033
|
+
this._attemptOutcomes = new WeakMap();
|
|
1034
|
+
this._suiteHookFailures = [];
|
|
1035
|
+
this._testsByFullName = new Map();
|
|
1036
|
+
this._packageResult = undefined;
|
|
1037
|
+
const context = this.getTestContext();
|
|
1038
|
+
/** @type {string | undefined} */
|
|
1039
|
+
let ownerFilePath;
|
|
1040
|
+
context.reset({ config: true });
|
|
1041
|
+
context.setDeclarationLocator(() => this.captureTestDeclarationLocation(ownerFilePath));
|
|
1127
1042
|
const testingConfigPath = this.getConfiguration().getTesting();
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
await this.
|
|
1131
|
-
|
|
1043
|
+
await context.describe("", { databaseCleaning: { transaction: true } }, async () => {
|
|
1044
|
+
if (testingConfigPath) {
|
|
1045
|
+
await this.runProfileSpan({ phase: "testing config/global setup" }, async () => {
|
|
1046
|
+
await this.getConfiguration().getEnvironmentHandler().importTestingConfigPath();
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
if (!this._profiler) {
|
|
1050
|
+
await this.importTestFiles();
|
|
1051
|
+
}
|
|
1052
|
+
else {
|
|
1053
|
+
for (const testFile of this.getTestFiles()) {
|
|
1054
|
+
ownerFilePath = testFile;
|
|
1055
|
+
const existingRegistrations = this.testRegistrationObjects();
|
|
1056
|
+
await this._profiler.measurePhase("imports", async () => {
|
|
1057
|
+
await this.getConfiguration().getEnvironmentHandler().importTestFiles([testFile]);
|
|
1058
|
+
}, { filePath: testFile });
|
|
1059
|
+
this.assignTestRegistrationOwnership(existingRegistrations, testFile);
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
});
|
|
1063
|
+
ownerFilePath = undefined;
|
|
1064
|
+
this.analyzeDeclarations();
|
|
1065
|
+
}
|
|
1066
|
+
/**
|
|
1067
|
+
* Captures a test source location without attributing package/facade frames.
|
|
1068
|
+
* @param {string | undefined} ownerFilePath - Importing entry file fallback.
|
|
1069
|
+
* @returns {{filePath?: string, line?: number}} - Declaration location.
|
|
1070
|
+
*/
|
|
1071
|
+
captureTestDeclarationLocation(ownerFilePath) {
|
|
1072
|
+
const stack = new Error().stack?.split("\n") || [];
|
|
1073
|
+
for (const stackLine of stack) {
|
|
1074
|
+
const match = stackLine.match(/(?:\(|\s)(file:\/\/.*?|\/[^"]*?):(\d+):(\d+)\)?$/u);
|
|
1075
|
+
if (!match)
|
|
1076
|
+
continue;
|
|
1077
|
+
let filePath = match[1];
|
|
1078
|
+
if (filePath.startsWith("file://")) {
|
|
1079
|
+
try {
|
|
1080
|
+
filePath = fileURLToPath(filePath);
|
|
1081
|
+
}
|
|
1082
|
+
catch {
|
|
1083
|
+
continue;
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
const resolvedFilePath = path.resolve(filePath);
|
|
1087
|
+
const portablePath = resolvedFilePath.replaceAll(path.sep, "/");
|
|
1088
|
+
if (portablePath.endsWith("/src/testing/test-runner.js"))
|
|
1089
|
+
continue;
|
|
1090
|
+
if (portablePath.endsWith("/src/testing/test.js"))
|
|
1091
|
+
continue;
|
|
1092
|
+
if (portablePath.includes("/node_modules/@velocious/testing/"))
|
|
1093
|
+
continue;
|
|
1094
|
+
return { filePath: resolvedFilePath, line: Number(match[2]) };
|
|
1132
1095
|
}
|
|
1133
|
-
|
|
1134
|
-
await this.analyzeTests(tests);
|
|
1135
|
-
this._onlyFocussed = this.anyTestsFocussed;
|
|
1096
|
+
return ownerFilePath ? { filePath: ownerFilePath } : {};
|
|
1136
1097
|
}
|
|
1137
1098
|
/**
|
|
1138
1099
|
* Runs are any tests focussed.
|
|
@@ -1244,13 +1205,7 @@ export default class TestRunner {
|
|
|
1244
1205
|
process.on("unhandledRejection", onUnhandledRejection);
|
|
1245
1206
|
process.on("uncaughtException", onUncaughtException);
|
|
1246
1207
|
try {
|
|
1247
|
-
await this.
|
|
1248
|
-
afterEaches: [],
|
|
1249
|
-
beforeEaches: [],
|
|
1250
|
-
tests,
|
|
1251
|
-
descriptions: [],
|
|
1252
|
-
indentLevel: 0
|
|
1253
|
-
});
|
|
1208
|
+
await this.runPackageTests();
|
|
1254
1209
|
// A rejection scheduled by the final test (a detached rejected promise,
|
|
1255
1210
|
// or an afterCommit callback rejecting as the suite drains) is reported
|
|
1256
1211
|
// by Node on a LATER turn. Drain a few turns while the handler is still
|
|
@@ -1270,228 +1225,389 @@ export default class TestRunner {
|
|
|
1270
1225
|
* @returns {Promise<void>} - Resolves when cleanup hooks finish.
|
|
1271
1226
|
*/
|
|
1272
1227
|
async runAfterAllsForActiveScopes() {
|
|
1273
|
-
const
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1228
|
+
const failureStart = this._suiteHookFailures.length;
|
|
1229
|
+
await this._packageRunner?.cleanupActiveSuites();
|
|
1230
|
+
this.throwAfterAllFailures(this._suiteHookFailures.slice(failureStart));
|
|
1231
|
+
}
|
|
1232
|
+
/** Builds declaration metadata used only by framework adapters and projections. */
|
|
1233
|
+
analyzeDeclarations() {
|
|
1234
|
+
const visit = (/** @type {PackageSuiteDeclaration} */ suite, /** @type {PackageSuiteDeclaration[]} */ ancestors, /** @type {string | undefined} */ parentProfileScopeId) => {
|
|
1235
|
+
const suites = [...ancestors, suite];
|
|
1236
|
+
const descriptions = suites.map((entry) => entry.name).filter((name) => name !== "");
|
|
1237
|
+
const ownerFilePath = this._declarationOwners.get(suite) ?? suite.location.filePath;
|
|
1238
|
+
const profileScopeId = this._profiler?.scopeId(suite, {
|
|
1239
|
+
descriptions,
|
|
1240
|
+
filePath: ownerFilePath,
|
|
1241
|
+
line: suite.location.line,
|
|
1242
|
+
parentId: parentProfileScopeId
|
|
1243
|
+
});
|
|
1244
|
+
for (const hooks of Object.values(suite.hooks)) {
|
|
1245
|
+
hooks.forEach((hook, declarationIndex) => {
|
|
1246
|
+
this._hookMetadata.set(hook, {
|
|
1247
|
+
declarationIndex,
|
|
1248
|
+
declarationScopeId: profileScopeId,
|
|
1249
|
+
ownerFilePath: this._declarationOwners.get(hook) ?? hook.location.filePath ?? ownerFilePath
|
|
1250
|
+
});
|
|
1251
|
+
});
|
|
1279
1252
|
}
|
|
1280
|
-
|
|
1281
|
-
|
|
1253
|
+
for (const testDeclaration of suite.tests) {
|
|
1254
|
+
const fullDescription = this.buildFullDescription(descriptions, testDeclaration.name);
|
|
1255
|
+
const declarations = this._testsByFullName.get(fullDescription) || [];
|
|
1256
|
+
declarations.push(testDeclaration);
|
|
1257
|
+
this._testsByFullName.set(fullDescription, declarations);
|
|
1258
|
+
this._testMetadata.set(testDeclaration, {
|
|
1259
|
+
descriptions,
|
|
1260
|
+
testDescription: testDeclaration.name,
|
|
1261
|
+
fullDescription,
|
|
1262
|
+
ownerFilePath: this._declarationOwners.get(testDeclaration) ?? testDeclaration.location.filePath ?? ownerFilePath,
|
|
1263
|
+
suites
|
|
1264
|
+
});
|
|
1265
|
+
const legacyTestData = this._legacyFixtureDataByFullName?.get(fullDescription);
|
|
1266
|
+
if (legacyTestData) {
|
|
1267
|
+
this._testCompatibility.set(testDeclaration, {
|
|
1268
|
+
testArgs: this._testArguments.copy(testDeclaration),
|
|
1269
|
+
testData: legacyTestData
|
|
1270
|
+
});
|
|
1271
|
+
}
|
|
1272
|
+
this._testsCount++;
|
|
1273
|
+
if (testDeclaration.state === "run" && (testDeclaration.focus || suites.some((entry) => entry.focus))) {
|
|
1274
|
+
this.anyTestsFocussed = true;
|
|
1275
|
+
}
|
|
1282
1276
|
}
|
|
1277
|
+
for (const childSuite of suite.suites)
|
|
1278
|
+
visit(childSuite, suites, profileScopeId);
|
|
1279
|
+
};
|
|
1280
|
+
for (const suite of this.getTestContext().registry.suites)
|
|
1281
|
+
visit(suite, [], undefined);
|
|
1282
|
+
}
|
|
1283
|
+
/**
|
|
1284
|
+
* Gets package hook compatibility metadata.
|
|
1285
|
+
* @param {PackageHookDeclaration} hook - Package hook declaration.
|
|
1286
|
+
* @returns {{declarationIndex: number, declarationScopeId: string | undefined, ownerFilePath: string | undefined}} - Hook metadata.
|
|
1287
|
+
*/
|
|
1288
|
+
hookMetadata(hook) {
|
|
1289
|
+
return this._hookMetadata.get(hook) || { declarationIndex: 0, declarationScopeId: undefined, ownerFilePath: hook.location.filePath };
|
|
1290
|
+
}
|
|
1291
|
+
/**
|
|
1292
|
+
* Gets package test compatibility metadata.
|
|
1293
|
+
* @param {PackageTestDeclaration} test - Package test declaration.
|
|
1294
|
+
* @returns {{descriptions: string[], testDescription: string, fullDescription: string, ownerFilePath: string | undefined, suites: PackageSuiteDeclaration[]}} - Declaration metadata.
|
|
1295
|
+
*/
|
|
1296
|
+
testMetadata(test) {
|
|
1297
|
+
const metadata = this._testMetadata.get(test);
|
|
1298
|
+
if (!metadata)
|
|
1299
|
+
throw new Error(`Missing package test metadata: ${test.name}`);
|
|
1300
|
+
return metadata;
|
|
1301
|
+
}
|
|
1302
|
+
/**
|
|
1303
|
+
* Gets stable compatibility data for a package declaration.
|
|
1304
|
+
* @param {PackageTestDeclaration} test - Package test declaration.
|
|
1305
|
+
* @returns {{testArgs: TestArgs, testData: TestData}} - Stable compatibility data.
|
|
1306
|
+
*/
|
|
1307
|
+
testData(test) {
|
|
1308
|
+
let compatibility = this._testCompatibility.get(test);
|
|
1309
|
+
if (!compatibility) {
|
|
1310
|
+
const testArgs = this._testArguments.copy(test);
|
|
1311
|
+
const metadata = this.testMetadata(test);
|
|
1312
|
+
const testData = {
|
|
1313
|
+
args: testArgs,
|
|
1314
|
+
declaration: test,
|
|
1315
|
+
filePath: test.location.filePath,
|
|
1316
|
+
function: test.callback,
|
|
1317
|
+
line: test.location.line,
|
|
1318
|
+
ownerFilePath: metadata.ownerFilePath
|
|
1319
|
+
};
|
|
1320
|
+
compatibility = { testArgs, testData };
|
|
1321
|
+
this._testCompatibility.set(test, compatibility);
|
|
1283
1322
|
}
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1323
|
+
return compatibility;
|
|
1324
|
+
}
|
|
1325
|
+
/**
|
|
1326
|
+
* Injects framework collaborators into stable compatibility data once.
|
|
1327
|
+
* @param {PackageTestDeclaration} test - Package test declaration.
|
|
1328
|
+
* @returns {Promise<{testArgs: TestArgs, testData: TestData}>} - Injected compatibility data.
|
|
1329
|
+
*/
|
|
1330
|
+
async testCompatibility(test) {
|
|
1331
|
+
const compatibility = this.testData(test);
|
|
1332
|
+
if (!this._injectedTests.has(test)) {
|
|
1333
|
+
await this._testArguments.inject(compatibility.testArgs);
|
|
1334
|
+
this._injectedTests.add(test);
|
|
1289
1335
|
}
|
|
1336
|
+
return compatibility;
|
|
1337
|
+
}
|
|
1338
|
+
/**
|
|
1339
|
+
* Records a raw framework attempt outcome.
|
|
1340
|
+
* @param {PackageTestDeclaration} test - Package test declaration.
|
|
1341
|
+
* @param {number} attemptNumber - One-based attempt number.
|
|
1342
|
+
* @param {{abortRemainingTests: boolean, error: ReturnType<typeof JSON.parse>, failed: boolean}} outcome - Raw attempt outcome.
|
|
1343
|
+
* @returns {void}
|
|
1344
|
+
*/
|
|
1345
|
+
recordAttemptOutcome(test, attemptNumber, outcome) {
|
|
1346
|
+
const outcomes = this._attemptOutcomes.get(test) || new Map();
|
|
1347
|
+
outcomes.set(attemptNumber, outcome);
|
|
1348
|
+
this._attemptOutcomes.set(test, outcomes);
|
|
1349
|
+
if (outcome.abortRemainingTests)
|
|
1350
|
+
this._abortRemainingTests = true;
|
|
1351
|
+
}
|
|
1352
|
+
/**
|
|
1353
|
+
* Gets a raw framework attempt outcome.
|
|
1354
|
+
* @param {PackageTestDeclaration} test - Package test declaration.
|
|
1355
|
+
* @param {number} attemptNumber - One-based attempt number.
|
|
1356
|
+
* @returns {{abortRemainingTests: boolean, error: ReturnType<typeof JSON.parse>, failed: boolean} | undefined} - Raw attempt outcome.
|
|
1357
|
+
*/
|
|
1358
|
+
attemptOutcome(test, attemptNumber) { return this._attemptOutcomes.get(test)?.get(attemptNumber); }
|
|
1359
|
+
/**
|
|
1360
|
+
* Records a raw suite-hook failure.
|
|
1361
|
+
* @param {object} failure - Suite-hook failure.
|
|
1362
|
+
* @param {PackageSuiteDeclaration} failure.suite - Owning package suite.
|
|
1363
|
+
* @param {"beforeAll" | "afterAll"} failure.phase - Hook phase.
|
|
1364
|
+
* @param {ReturnType<typeof JSON.parse>} failure.error - Raw hook failure.
|
|
1365
|
+
* @returns {void}
|
|
1366
|
+
*/
|
|
1367
|
+
recordSuiteHookFailure(failure) { this._suiteHookFailures.push(failure); }
|
|
1368
|
+
/**
|
|
1369
|
+
* Gets the raw ancestor setup failure for a package test.
|
|
1370
|
+
* @param {PackageTestDeclaration} test - Package test declaration.
|
|
1371
|
+
* @returns {ReturnType<typeof JSON.parse>} - Raw setup failure.
|
|
1372
|
+
*/
|
|
1373
|
+
setupFailureFor(test) {
|
|
1374
|
+
const suites = this.testMetadata(test).suites;
|
|
1375
|
+
return this._suiteHookFailures.find((failure) => failure.phase === "beforeAll" && suites.includes(failure.suite))?.error;
|
|
1376
|
+
}
|
|
1377
|
+
/**
|
|
1378
|
+
* Finds the next incomplete declaration with a package full name.
|
|
1379
|
+
* @param {string} fullName - Package full name.
|
|
1380
|
+
* @returns {PackageTestDeclaration | undefined} - Next matching declaration.
|
|
1381
|
+
*/
|
|
1382
|
+
findTestDeclaration(fullName) {
|
|
1383
|
+
return this._testsByFullName.get(fullName)?.find((test) => !this._completedTests.has(test));
|
|
1290
1384
|
}
|
|
1291
1385
|
/**
|
|
1292
|
-
*
|
|
1293
|
-
* @param {
|
|
1294
|
-
* @returns {
|
|
1386
|
+
* Marks a package declaration complete.
|
|
1387
|
+
* @param {PackageTestDeclaration} test - Completed declaration.
|
|
1388
|
+
* @returns {void}
|
|
1389
|
+
*/
|
|
1390
|
+
completeTestDeclaration(test) { this._completedTests.add(test); }
|
|
1391
|
+
/**
|
|
1392
|
+
* Gets the effective package retry count.
|
|
1393
|
+
* @param {PackageTestDeclaration} test - Package test declaration.
|
|
1394
|
+
* @returns {number} - Effective retry count.
|
|
1395
|
+
*/
|
|
1396
|
+
retryCount(test) {
|
|
1397
|
+
const value = test.options.retries ?? test.options.retry ?? this.getTestContext().config.retries;
|
|
1398
|
+
return typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.floor(value)) : 0;
|
|
1399
|
+
}
|
|
1400
|
+
/**
|
|
1401
|
+
* Normalizes retry inputs for the package execution boundary while retaining
|
|
1402
|
+
* the declarations' original public options after the run.
|
|
1403
|
+
* @returns {() => void} - Restores original declaration options.
|
|
1295
1404
|
*/
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1405
|
+
normalizePackageRetriesForExecution() {
|
|
1406
|
+
/** @type {PackageRetryOptionRestoration[]} */
|
|
1407
|
+
const restorations = [];
|
|
1408
|
+
/**
|
|
1409
|
+
* Normalizes declarations in one suite.
|
|
1410
|
+
* @param {PackageSuiteDeclaration} suite - Suite whose tests are normalized.
|
|
1411
|
+
*/
|
|
1412
|
+
const visit = (suite) => {
|
|
1413
|
+
for (const test of suite.tests) {
|
|
1414
|
+
// Capture compatibility arguments before temporarily adapting package
|
|
1415
|
+
// execution options so callbacks retain their declared values/identity.
|
|
1416
|
+
this.testData(test);
|
|
1417
|
+
restorations.push({
|
|
1418
|
+
hadRetries: Object.hasOwn(test.options, "retries"),
|
|
1419
|
+
options: test.options,
|
|
1420
|
+
retries: test.options.retries
|
|
1421
|
+
});
|
|
1422
|
+
test.options.retries = this.retryCount(test);
|
|
1305
1423
|
}
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1424
|
+
for (const childSuite of suite.suites)
|
|
1425
|
+
visit(childSuite);
|
|
1426
|
+
};
|
|
1427
|
+
for (const suite of this.getTestContext().registry.suites)
|
|
1428
|
+
visit(suite);
|
|
1429
|
+
return () => {
|
|
1430
|
+
for (const restoration of restorations) {
|
|
1431
|
+
if (restoration.hadRetries)
|
|
1432
|
+
restoration.options.retries = restoration.retries;
|
|
1433
|
+
else
|
|
1434
|
+
delete restoration.options.retries;
|
|
1312
1435
|
}
|
|
1313
|
-
|
|
1314
|
-
}
|
|
1315
|
-
return { anyTestsFocussed: anyTestsFocussedFound };
|
|
1436
|
+
};
|
|
1316
1437
|
}
|
|
1317
1438
|
/**
|
|
1318
|
-
*
|
|
1319
|
-
* @param {
|
|
1320
|
-
* @
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1439
|
+
* Records one completed test duration.
|
|
1440
|
+
* @param {{durationMs: number, filePath: string, fullDescription: string, line: number}} duration - Completed test duration.
|
|
1441
|
+
* @returns {void}
|
|
1442
|
+
*/
|
|
1443
|
+
recordTestDuration(duration) { this._testDurations.push(duration); }
|
|
1444
|
+
/** Records one successful package result. */
|
|
1445
|
+
recordSuccessfulTest() { this._successfulTests++; }
|
|
1446
|
+
/**
|
|
1447
|
+
* Records one failed package test in the legacy result projection.
|
|
1448
|
+
* @param {object} args - Failed test metadata.
|
|
1449
|
+
* @param {string[]} args.descriptions - Parent descriptions.
|
|
1450
|
+
* @param {ReturnType<typeof JSON.parse>} args.error - Raw failure.
|
|
1451
|
+
* @param {string} args.consoleOutput - Captured console output.
|
|
1452
|
+
* @param {TestData} args.testData - Compatibility test data.
|
|
1453
|
+
* @param {string} args.testDescription - Test description.
|
|
1454
|
+
* @returns {void}
|
|
1324
1455
|
*/
|
|
1325
|
-
|
|
1326
|
-
|
|
1456
|
+
recordFailedTest({ descriptions, error, consoleOutput, testData, testDescription }) {
|
|
1457
|
+
this._failedTests++;
|
|
1458
|
+
this._failedTestDetails.push({
|
|
1459
|
+
fullDescription: this.buildFullDescription(descriptions, testDescription),
|
|
1460
|
+
filePath: testData.filePath,
|
|
1461
|
+
line: testData.line,
|
|
1462
|
+
error,
|
|
1463
|
+
consoleOutput: consoleOutput || undefined
|
|
1464
|
+
});
|
|
1327
1465
|
}
|
|
1328
1466
|
/**
|
|
1329
|
-
*
|
|
1330
|
-
* @param {
|
|
1331
|
-
* @
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
*
|
|
1336
|
-
* @
|
|
1337
|
-
* @param {string} [args.parentProfileScopeId] - Parent profile scope.
|
|
1338
|
-
* @returns {Promise<void>} - Resolves when complete.
|
|
1467
|
+
* Stores the completed package result.
|
|
1468
|
+
* @param {import("@velocious/testing/runner").TestRunResult} result - Package result.
|
|
1469
|
+
* @returns {void}
|
|
1470
|
+
*/
|
|
1471
|
+
recordPackageResult(result) { this._packageResult = result; }
|
|
1472
|
+
/**
|
|
1473
|
+
* Runs the package kernel with Velocious framework adapters.
|
|
1474
|
+
* @returns {Promise<void>} - Resolves after execution and teardown.
|
|
1339
1475
|
*/
|
|
1340
|
-
async
|
|
1476
|
+
async runPackageTests() {
|
|
1341
1477
|
const environmentHandler = this.getConfiguration().getEnvironmentHandler();
|
|
1342
1478
|
environmentHandler.installSharedTransactionCoordinatorOwnerStorage(this._sharedTransactionCoordinatorOwnerStorage);
|
|
1343
1479
|
environmentHandler.installTestDatabaseAccessScopeStorage(this._testDatabaseAccessScopeStorage);
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1480
|
+
this._packageRunner = new PackageTestRunner({
|
|
1481
|
+
context: this.getTestContext(),
|
|
1482
|
+
includeTags: this._includeTags,
|
|
1483
|
+
excludeTags: [...this.getExcludeTagSet(), ...(this.isBrowserTestMode() ? [] : ["browser-only"])],
|
|
1484
|
+
examples: this.getExamplePatterns(),
|
|
1485
|
+
lineFilters: this.getLineFilters(),
|
|
1486
|
+
includeTagMode: "any",
|
|
1487
|
+
focusedTestsBypassIncludeTags: true,
|
|
1488
|
+
omitEmptySuiteNames: true,
|
|
1489
|
+
attemptExecutorOwnsTimeout: true,
|
|
1490
|
+
attemptExecutor: (input) => this._attemptExecutor.execute(input),
|
|
1491
|
+
testArgumentResolver: (input) => this._testArguments.resolve(input),
|
|
1492
|
+
suiteHookExecutor: (input) => this._suiteHookExecutor.execute(input),
|
|
1493
|
+
reporter: this._runnerReporter
|
|
1351
1494
|
});
|
|
1352
|
-
const
|
|
1353
|
-
const
|
|
1354
|
-
|
|
1355
|
-
const newBeforeEaches = [...beforeEaches, ...ownBeforeEaches];
|
|
1356
|
-
const scopeLineMatch = lineMatchedInScope || this.matchesLineFilter(tests);
|
|
1357
|
-
const shouldRunAnyTests = this.hasRunnableTests(tests, descriptions, scopeLineMatch);
|
|
1358
|
-
if (!shouldRunAnyTests)
|
|
1359
|
-
return;
|
|
1360
|
-
/** @type {ActiveAfterAllScopeEntry} */
|
|
1361
|
-
const scopeEntry = { tests, afterAllsRun: false, profileScopeId };
|
|
1362
|
-
this._activeAfterAllScopes.push(scopeEntry);
|
|
1363
|
-
/** @type {unknown[]} */
|
|
1364
|
-
const scopeErrors = [];
|
|
1495
|
+
const failureStart = this._suiteHookFailures.length;
|
|
1496
|
+
const restoreRetryOptions = this.normalizePackageRetriesForExecution();
|
|
1497
|
+
let result;
|
|
1365
1498
|
try {
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
for (const testDescription in tests.tests) {
|
|
1369
|
-
const testData = tests.tests[testDescription];
|
|
1370
|
-
const testArgs = this._testArguments.copy(testData);
|
|
1371
|
-
const includeByLine = scopeLineMatch || this.matchesLineFilter(testData);
|
|
1372
|
-
if (this._onlyFocussed && !testArgs.focus)
|
|
1373
|
-
continue;
|
|
1374
|
-
if (this.shouldSkipTest(testArgs, testData, testDescription, descriptions, includeByLine))
|
|
1375
|
-
continue;
|
|
1376
|
-
await this._testArguments.inject(testArgs);
|
|
1377
|
-
const retryCount = typeof testArgs.retry === "number" && Number.isFinite(testArgs.retry)
|
|
1378
|
-
? Math.max(0, Math.floor(testArgs.retry))
|
|
1379
|
-
: 0;
|
|
1380
|
-
const configTimeoutSeconds = typeof testConfig.defaultTimeoutSeconds === "number" ? testConfig.defaultTimeoutSeconds : undefined;
|
|
1381
|
-
const timeoutSeconds = typeof testArgs.timeoutSeconds === "number" ? testArgs.timeoutSeconds : configTimeoutSeconds;
|
|
1382
|
-
const useTimeout = typeof timeoutSeconds === "number" && Number.isFinite(timeoutSeconds) && timeoutSeconds > 0;
|
|
1383
|
-
const timeoutMs = useTimeout ? timeoutSeconds * 1000 : undefined;
|
|
1384
|
-
let retriesUsed = 0;
|
|
1385
|
-
let attemptNumber = 1;
|
|
1386
|
-
/**
|
|
1387
|
-
* Attempt console outputs.
|
|
1388
|
-
* @type {AttemptConsoleOutput[]} */
|
|
1389
|
-
const attemptConsoleOutputs = [];
|
|
1390
|
-
console.log(`${leftPadding}it ${testDescription}`);
|
|
1391
|
-
const testStartMs = Date.now();
|
|
1392
|
-
while (true) {
|
|
1393
|
-
const attemptResult = await this._attemptExecutor.execute({
|
|
1394
|
-
afterEaches: newAfterEaches,
|
|
1395
|
-
attemptNumber,
|
|
1396
|
-
beforeEaches: newBeforeEaches,
|
|
1397
|
-
descriptions,
|
|
1398
|
-
testArgs,
|
|
1399
|
-
testData,
|
|
1400
|
-
testDescription,
|
|
1401
|
-
timeoutMs
|
|
1402
|
-
});
|
|
1403
|
-
if (attemptResult.consoleOutput) {
|
|
1404
|
-
attemptConsoleOutputs.push({ attemptNumber, output: attemptResult.consoleOutput });
|
|
1405
|
-
}
|
|
1406
|
-
if (attemptResult.abortRemainingTests)
|
|
1407
|
-
this._abortRemainingTests = true;
|
|
1408
|
-
const willRetry = attemptResult.failed && !this._abortRemainingTests && retriesUsed < retryCount;
|
|
1409
|
-
if (willRetry)
|
|
1410
|
-
retriesUsed++;
|
|
1411
|
-
await this._runnerReporter.reportAttempt({
|
|
1412
|
-
attemptConsoleOutputs,
|
|
1413
|
-
attemptNumber,
|
|
1414
|
-
descriptions,
|
|
1415
|
-
error: attemptResult.error,
|
|
1416
|
-
failed: attemptResult.failed,
|
|
1417
|
-
leftPadding,
|
|
1418
|
-
retriesUsed,
|
|
1419
|
-
retryCount,
|
|
1420
|
-
testArgs,
|
|
1421
|
-
testData,
|
|
1422
|
-
testDescription,
|
|
1423
|
-
willRetry
|
|
1424
|
-
});
|
|
1425
|
-
attemptNumber++;
|
|
1426
|
-
if (!willRetry)
|
|
1427
|
-
break;
|
|
1428
|
-
}
|
|
1429
|
-
this._testDurations.push({
|
|
1430
|
-
fullDescription: this.buildFullDescription(descriptions, testDescription),
|
|
1431
|
-
filePath: testData.filePath ?? "<unknown>",
|
|
1432
|
-
line: testData.line ?? 0,
|
|
1433
|
-
durationMs: Date.now() - testStartMs
|
|
1434
|
-
});
|
|
1435
|
-
if (this._abortRemainingTests)
|
|
1436
|
-
break;
|
|
1499
|
+
try {
|
|
1500
|
+
result = await this._packageRunner.run();
|
|
1437
1501
|
}
|
|
1438
|
-
|
|
1439
|
-
if (
|
|
1440
|
-
|
|
1441
|
-
const
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
console.log(`${leftPadding}${subDescription}`);
|
|
1446
|
-
await this.runTests({
|
|
1447
|
-
afterEaches: newAfterEaches,
|
|
1448
|
-
beforeEaches: newBeforeEaches,
|
|
1449
|
-
tests: subTest,
|
|
1450
|
-
descriptions: newDecriptions,
|
|
1451
|
-
indentLevel: indentLevel + 1,
|
|
1452
|
-
lineMatchedInScope: childScopeLineMatch,
|
|
1453
|
-
parentProfileScopeId: profileScopeId
|
|
1454
|
-
});
|
|
1455
|
-
}
|
|
1502
|
+
catch (error) {
|
|
1503
|
+
if (!(error instanceof AbortRemainingTestsError))
|
|
1504
|
+
throw error;
|
|
1505
|
+
const afterAll = this.afterAllOutcome(this._suiteHookFailures.slice(failureStart));
|
|
1506
|
+
if (afterAll.failed)
|
|
1507
|
+
this.recordTimeoutCleanupFailure(afterAll.error, "afterAll");
|
|
1508
|
+
return;
|
|
1456
1509
|
}
|
|
1510
|
+
this.recordPackageResult(result);
|
|
1511
|
+
this.throwAfterAllFailures(this._suiteHookFailures.slice(failureStart));
|
|
1457
1512
|
}
|
|
1458
|
-
|
|
1459
|
-
|
|
1513
|
+
finally {
|
|
1514
|
+
restoreRetryOptions();
|
|
1460
1515
|
}
|
|
1516
|
+
}
|
|
1517
|
+
/**
|
|
1518
|
+
* Aggregates raw after-all failures without using error truthiness.
|
|
1519
|
+
* @param {Array<{phase: "beforeAll" | "afterAll", error: ReturnType<typeof JSON.parse>}>} failures - Hook failures.
|
|
1520
|
+
* @returns {{failed: false} | {failed: true, error: ReturnType<typeof JSON.parse>}} - Explicit afterAll outcome.
|
|
1521
|
+
*/
|
|
1522
|
+
afterAllOutcome(failures) {
|
|
1523
|
+
const afterAllErrors = failures.filter((failure) => failure.phase === "afterAll").map((failure) => failure.error);
|
|
1524
|
+
if (afterAllErrors.length === 0)
|
|
1525
|
+
return { failed: false };
|
|
1526
|
+
if (afterAllErrors.length === 1)
|
|
1527
|
+
return { failed: true, error: afterAllErrors[0] };
|
|
1528
|
+
return {
|
|
1529
|
+
failed: true,
|
|
1530
|
+
error: new AggregateError(afterAllErrors, "Multiple active afterAll scopes failed", { cause: afterAllErrors[0] })
|
|
1531
|
+
};
|
|
1532
|
+
}
|
|
1533
|
+
/**
|
|
1534
|
+
* Throws one raw or aggregated after-all failure.
|
|
1535
|
+
* @param {Array<{phase: "beforeAll" | "afterAll", error: ReturnType<typeof JSON.parse>}>} failures - Hook failures.
|
|
1536
|
+
* @returns {void}
|
|
1537
|
+
*/
|
|
1538
|
+
throwAfterAllFailures(failures) {
|
|
1539
|
+
const afterAll = this.afterAllOutcome(failures);
|
|
1540
|
+
if (afterAll.failed)
|
|
1541
|
+
throw afterAll.error;
|
|
1542
|
+
}
|
|
1543
|
+
/**
|
|
1544
|
+
* Compatibility helper for focused framework lifecycle specs. It converts an
|
|
1545
|
+
* explicit legacy fixture into isolated package declarations; the package
|
|
1546
|
+
* runner remains the sole execution engine.
|
|
1547
|
+
* @param {object} args - Legacy fixture arguments.
|
|
1548
|
+
* @param {TestsArgument} args.tests - Fixture tree.
|
|
1549
|
+
* @returns {Promise<void>} - Resolves after package execution.
|
|
1550
|
+
*/
|
|
1551
|
+
async runTests({ tests }) {
|
|
1552
|
+
const context = createTestContext();
|
|
1553
|
+
const originalContext = this._context;
|
|
1554
|
+
context.configureTests({
|
|
1555
|
+
consoleOutput: originalContext.config.consoleOutput,
|
|
1556
|
+
defaultTimeoutMs: originalContext.config.defaultTimeoutMs,
|
|
1557
|
+
excludeTags: originalContext.config.excludeTags,
|
|
1558
|
+
failedConsoleOutputMaxLines: originalContext.config.failedConsoleOutputMaxLines,
|
|
1559
|
+
retries: originalContext.config.retries
|
|
1560
|
+
});
|
|
1561
|
+
this._context = context;
|
|
1562
|
+
this._testsCount = 0;
|
|
1563
|
+
this._testCompatibility = new WeakMap();
|
|
1564
|
+
this._injectedTests = new WeakSet();
|
|
1565
|
+
this._completedTests = new WeakSet();
|
|
1566
|
+
this._testMetadata = new WeakMap();
|
|
1567
|
+
this._hookMetadata = new WeakMap();
|
|
1568
|
+
this._attemptOutcomes = new WeakMap();
|
|
1569
|
+
this._suiteHookFailures = [];
|
|
1570
|
+
this._testsByFullName = new Map();
|
|
1571
|
+
this._legacyFixtureDataByFullName = new Map();
|
|
1572
|
+
context.setDeclarationLocator(() => this._legacyFixtureLocation);
|
|
1573
|
+
this.declareLegacyFixture(context, "", tests, []);
|
|
1574
|
+
this.analyzeDeclarations();
|
|
1461
1575
|
try {
|
|
1462
|
-
await this.
|
|
1463
|
-
}
|
|
1464
|
-
catch (error) {
|
|
1465
|
-
scopeErrors.push(error);
|
|
1466
|
-
}
|
|
1467
|
-
const scopeIndex = this._activeAfterAllScopes.indexOf(scopeEntry);
|
|
1468
|
-
if (scopeIndex >= 0) {
|
|
1469
|
-
this._activeAfterAllScopes.splice(scopeIndex, 1);
|
|
1576
|
+
await this.runPackageTests();
|
|
1470
1577
|
}
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
? scopeErrors[0]
|
|
1474
|
-
: new AggregateError(scopeErrors, "Test scope and afterAll cleanup failed", { cause: scopeErrors[0] });
|
|
1475
|
-
this.recordTimeoutCleanupFailure(error, "afterAll");
|
|
1476
|
-
return;
|
|
1578
|
+
finally {
|
|
1579
|
+
this._context = originalContext;
|
|
1477
1580
|
}
|
|
1478
|
-
if (scopeErrors.length == 1)
|
|
1479
|
-
throw scopeErrors[0];
|
|
1480
|
-
if (scopeErrors.length > 1)
|
|
1481
|
-
throw new AggregateError(scopeErrors, "Test scope and afterAll cleanup failed", { cause: scopeErrors[0] });
|
|
1482
1581
|
}
|
|
1483
1582
|
/**
|
|
1484
|
-
*
|
|
1485
|
-
* @param {
|
|
1486
|
-
* @
|
|
1583
|
+
* Declares an isolated legacy-shaped test fixture into a package context.
|
|
1584
|
+
* @param {PackageTestContext} context - Isolated package context.
|
|
1585
|
+
* @param {string} name - Suite name.
|
|
1586
|
+
* @param {TestsArgument} scope - Legacy fixture scope.
|
|
1587
|
+
* @param {string[]} descriptions - Ancestor descriptions.
|
|
1588
|
+
* @returns {void}
|
|
1487
1589
|
*/
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1590
|
+
declareLegacyFixture(context, name, scope, descriptions) {
|
|
1591
|
+
this._legacyFixtureLocation = { filePath: scope.filePath, line: scope.line };
|
|
1592
|
+
context.describe(name, scope.args || {}, () => {
|
|
1593
|
+
for (const hook of scope.beforeAlls || [])
|
|
1594
|
+
context.beforeAll(hook.callback);
|
|
1595
|
+
for (const hook of scope.beforeEaches || [])
|
|
1596
|
+
context.beforeEach(hook.callback);
|
|
1597
|
+
for (const hook of scope.afterEaches || [])
|
|
1598
|
+
context.afterEach(hook.callback);
|
|
1599
|
+
for (const hook of scope.afterAlls || [])
|
|
1600
|
+
context.afterAll(hook.callback);
|
|
1601
|
+
const nextDescriptions = name === "" ? descriptions : [...descriptions, name];
|
|
1602
|
+
for (const [testName, testData] of Object.entries(scope.tests || {})) {
|
|
1603
|
+
this._legacyFixtureLocation = { filePath: testData.filePath, line: testData.line };
|
|
1604
|
+
this._legacyFixtureDataByFullName?.set(this.buildFullDescription(nextDescriptions, testName), testData);
|
|
1605
|
+
context.it(testName, testData.args, testData.function);
|
|
1606
|
+
}
|
|
1607
|
+
for (const [suiteName, childScope] of Object.entries(scope.subs || {})) {
|
|
1608
|
+
this.declareLegacyFixture(context, suiteName, childScope, nextDescriptions);
|
|
1609
|
+
}
|
|
1610
|
+
});
|
|
1495
1611
|
}
|
|
1496
1612
|
/**
|
|
1497
1613
|
* Runs emit event.
|
|
@@ -1602,52 +1718,5 @@ export default class TestRunner {
|
|
|
1602
1718
|
console.error(picocolors.red(`${leftPadding} ${line}`));
|
|
1603
1719
|
}
|
|
1604
1720
|
}
|
|
1605
|
-
/**
|
|
1606
|
-
* Runs start console capture.
|
|
1607
|
-
* @param {object} [args] - Options object.
|
|
1608
|
-
* @param {boolean} [args.passthrough] - Whether to pass through to the original console.
|
|
1609
|
-
* @returns {() => string} - Stops the capture and returns captured text.
|
|
1610
|
-
*/
|
|
1611
|
-
startConsoleCapture({ passthrough = false } = {}) {
|
|
1612
|
-
/**
|
|
1613
|
-
* Lines.
|
|
1614
|
-
* @type {string[]} */
|
|
1615
|
-
const lines = [];
|
|
1616
|
-
/**
|
|
1617
|
-
* Console object.
|
|
1618
|
-
* @type {Record<ConsoleMethodName, (...args: Array<ReturnType<typeof JSON.parse>>) => void>} */
|
|
1619
|
-
const consoleObject = /** @type {Record<ConsoleMethodName, (...args: Array<ReturnType<typeof JSON.parse>>) => void>} */ (console);
|
|
1620
|
-
/**
|
|
1621
|
-
* Original console methods captured as direct references so stopping restores
|
|
1622
|
-
* the exact method that was installed at capture start.
|
|
1623
|
-
* @type {Record<ConsoleMethodName, (...args: Array<ReturnType<typeof JSON.parse>>) => void>} */
|
|
1624
|
-
const originalConsoleMethods = {
|
|
1625
|
-
debug: consoleObject.debug,
|
|
1626
|
-
error: consoleObject.error,
|
|
1627
|
-
info: consoleObject.info,
|
|
1628
|
-
log: consoleObject.log,
|
|
1629
|
-
warn: consoleObject.warn
|
|
1630
|
-
};
|
|
1631
|
-
let stopped = false;
|
|
1632
|
-
let outputText = "";
|
|
1633
|
-
for (const methodName of CAPTURED_CONSOLE_METHODS) {
|
|
1634
|
-
consoleObject[methodName] = (...args) => {
|
|
1635
|
-
lines.push(`[${new Date().toISOString()}] [${methodName}] ${format(...args)}`);
|
|
1636
|
-
if (passthrough) {
|
|
1637
|
-
originalConsoleMethods[methodName].apply(consoleObject, args);
|
|
1638
|
-
}
|
|
1639
|
-
};
|
|
1640
|
-
}
|
|
1641
|
-
return () => {
|
|
1642
|
-
if (!stopped) {
|
|
1643
|
-
stopped = true;
|
|
1644
|
-
for (const methodName of CAPTURED_CONSOLE_METHODS) {
|
|
1645
|
-
consoleObject[methodName] = originalConsoleMethods[methodName];
|
|
1646
|
-
}
|
|
1647
|
-
outputText = lines.join("\n");
|
|
1648
|
-
}
|
|
1649
|
-
return outputText;
|
|
1650
|
-
};
|
|
1651
|
-
}
|
|
1652
1721
|
}
|
|
1653
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1ydW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGVzdGluZy90ZXN0LXJ1bm5lci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxFQUFFLE1BQU0sa0JBQWtCLENBQUE7QUFDakMsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBQ3ZCLE9BQU8sRUFBQyxNQUFNLEVBQUMsTUFBTSxXQUFXLENBQUE7QUFDaEMsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sa0JBQWtCLENBQUE7QUFDbEQsT0FBTyxXQUFXLE1BQU0sMEJBQTBCLENBQUE7QUFDbEQsT0FBTyxhQUFhLE1BQU0scUJBQXFCLENBQUE7QUFDL0MsT0FBTyxVQUFVLE1BQU0sWUFBWSxDQUFBO0FBQ25DLE9BQU8sYUFBYSxNQUFNLDZCQUE2QixDQUFBO0FBQ3ZELE9BQU8sRUFBQyxVQUFVLEVBQUUsS0FBSyxFQUFDLE1BQU0sV0FBVyxDQUFBO0FBQzNDLE9BQU8sRUFBQyxhQUFhLEVBQUMsTUFBTSxLQUFLLENBQUE7QUFDakMsT0FBTyx1QkFBdUIsTUFBTSxnQ0FBZ0MsQ0FBQTtBQUNwRSxPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQTtBQUNwRixPQUFPLEVBQUMsOEJBQThCLEVBQUMsTUFBTSw4QkFBOEIsQ0FBQTtBQUMzRSxPQUFPLHdCQUF3QixNQUFNLGlDQUFpQyxDQUFBO0FBQ3RFLE9BQU8sdUJBQXVCLE1BQU0sZ0NBQWdDLENBQUE7QUFDcEUsT0FBTywwQkFBMEIsTUFBTSxvQ0FBb0MsQ0FBQTtBQUMzRSxPQUFPLHNCQUFzQixNQUFNLCtCQUErQixDQUFBO0FBRWxFOzs4RUFFOEU7QUFDOUU7Ozs7O0dBS0c7QUFDSDs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUNIOzs7Ozs7Ozs7R0FTRztBQUNIOzs7Ozs7OztHQVFHO0FBQ0g7Ozs7Ozs7OztHQVNHO0FBQ0g7Ozs7OztHQU1HO0FBQ0g7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QUFDLFVBQVUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLENBQUE7Z0JBQy9ELENBQUM7WUFDSCxDQUFDLENBQUE7UUFDSCxDQUFDO1FBRUQsT0FBTyxHQUFHLEVBQUU7WUFDVixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ2IsT0FBTyxHQUFHLElBQUksQ0FBQTtnQkFFZCxLQUFLLE1BQU0sVUFBVSxJQUFJLHdCQUF3QixFQUFFLENBQUM7b0JBQ2xELGFBQWEsQ0FBQyxVQUFVLENBQUMsR0FBRyxzQkFBc0IsQ0FBQyxVQUFVLENBQUMsQ0FBQTtnQkFDaEUsQ0FBQztnQkFFRCxVQUFVLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtZQUMvQixDQUFDO1lBRUQsT0FBTyxVQUFVLENBQUE7UUFDbkIsQ0FBQyxDQUFBO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBmcyBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiXG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiXG5pbXBvcnQge2Zvcm1hdH0gZnJvbSBcIm5vZGU6dXRpbFwiXG5pbXBvcnQge0FzeW5jTG9jYWxTdG9yYWdlfSBmcm9tIFwibm9kZTphc3luY19ob29rc1wiXG5pbXBvcnQgQXBwbGljYXRpb24gZnJvbSBcIi4uLy4uL3NyYy9hcHBsaWNhdGlvbi5qc1wiXG5pbXBvcnQgUmVxdWVzdENsaWVudCBmcm9tIFwiLi9yZXF1ZXN0LWNsaWVudC5qc1wiXG5pbXBvcnQgcGljb2NvbG9ycyBmcm9tIFwicGljb2NvbG9yc1wiXG5pbXBvcnQgcmVzdEFyZ3NFcnJvciBmcm9tIFwiLi4vdXRpbHMvcmVzdC1hcmdzLWVycm9yLmpzXCJcbmltcG9ydCB7dGVzdENvbmZpZywgdGVzdHN9IGZyb20gXCIuL3Rlc3QuanNcIlxuaW1wb3J0IHtwYXRoVG9GaWxlVVJMfSBmcm9tIFwidXJsXCJcbmltcG9ydCBTaGFyZWRUcmFuc2FjdGlvbkJyb2tlciBmcm9tIFwiLi9zaGFyZWQtdHJhbnNhY3Rpb24tYnJva2VyLmpzXCJcbmltcG9ydCB7IFNIQVJFRF9UUkFOU0FDVElPTl9CUk9LRVJfRU5WIH0gZnJvbSBcIi4vc2hhcmVkLXRyYW5zYWN0aW9uLXByb3h5LWRyaXZlci5qc1wiXG5pbXBvcnQge3N5bmNocm9uaXplVGVzdGluZ1BhY2thZ2VUZXN0c30gZnJvbSBcIi4vdGVzdGluZy1wYWNrYWdlLWFkYXB0ZXIuanNcIlxuaW1wb3J0IFZlbG9jaW91c0F0dGVtcHRFeGVjdXRvciBmcm9tIFwiLi92ZWxvY2lvdXMtYXR0ZW1wdC1leGVjdXRvci5qc1wiXG5pbXBvcnQgVmVsb2Npb3VzUnVubmVyUmVwb3J0ZXIgZnJvbSBcIi4vdmVsb2Npb3VzLXJ1bm5lci1yZXBvcnRlci5qc1wiXG5pbXBvcnQgVmVsb2Npb3VzU3VpdGVIb29rRXhlY3V0b3IgZnJvbSBcIi4vdmVsb2Npb3VzLXN1aXRlLWhvb2stZXhlY3V0b3IuanNcIlxuaW1wb3J0IFZlbG9jaW91c1Rlc3RBcmd1bWVudHMgZnJvbSBcIi4vdmVsb2Npb3VzLXRlc3QtYXJndW1lbnRzLmpzXCJcblxuLyoqXG4gKiBDb25zb2xlTWV0aG9kTmFtZSB0eXBlLlxuICogQHR5cGVkZWYge1wibG9nXCIgfCBcImluZm9cIiB8IFwid2FyblwiIHwgXCJlcnJvclwiIHwgXCJkZWJ1Z1wifSBDb25zb2xlTWV0aG9kTmFtZSAqL1xuLyoqXG4gKiBBdHRlbXB0Q29uc29sZU91dHB1dCB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gQXR0ZW1wdENvbnNvbGVPdXRwdXRcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBhdHRlbXB0TnVtYmVyIC0gQXR0ZW1wdCBudW1iZXIuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gb3V0cHV0IC0gQ2FwdHVyZWQgY29uc29sZSBvdXRwdXQuXG4gKi9cbi8qKlxuICogVGVzdEFyZ3MgdHlwZS5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IFRlc3RBcmdzXG4gKiBAcHJvcGVydHkge0FwcGxpY2F0aW9ufSBbYXBwbGljYXRpb25dIC0gQXBwbGljYXRpb24gaW5zdGFuY2UgZm9yIGludGVncmF0aW9uIHRlc3RzLlxuICogQHByb3BlcnR5IHtSZXF1ZXN0Q2xpZW50fSBbY2xpZW50XSAtIEhUVFAgY2xpZW50IGZvciByZXF1ZXN0IHRlc3RzLlxuICogQHByb3BlcnR5IHtvYmplY3R9IFtkYXRhYmFzZUNsZWFuaW5nXSAtIERhdGFiYXNlIGNsZWFudXAgb3B0aW9ucyBmb3IgdGVzdHMuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtkYXRhYmFzZUNsZWFuaW5nLnRyYW5zYWN0aW9uXSAtIFVzZSB0cmFuc2FjdGlvbnMgdG8gcm9sbGJhY2sgYmV0d2VlbiB0ZXN0cy5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2RhdGFiYXNlQ2xlYW5pbmcudHJ1bmNhdGVdIC0gVHJ1bmNhdGUgdGFibGVzIGJldHdlZW4gdGVzdHMuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtkYXRhYmFzZUNsZWFuaW5nLnRydW5jYXRlQmVmb3JlXSAtIFRydW5jYXRlIHRhYmxlcyBiZWZvcmUgZWFjaCB0ZXN0LCBpbiBhZGRpdGlvbiB0byB0aGUgZGVmYXVsdCBjbGVhbnVwLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbZm9jdXNdIC0gV2hldGhlciB0aGlzIHRlc3QgaXMgZm9jdXNlZC5cbiAqIEBwcm9wZXJ0eSB7KCkgPT4gKHZvaWR8UHJvbWlzZTx2b2lkPil9IFtmdW5jdGlvbl0gLSBUZXN0IGNhbGxiYWNrIGZ1bmN0aW9uLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtyZXRyeV0gLSBOdW1iZXIgb2YgcmV0cmllcyB3aGVuIGEgdGVzdCBmYWlscy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW10gfCBzdHJpbmd9IFt0YWdzXSAtIFRhZ3MgZm9yIGZpbHRlcmluZy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbdGltZW91dFNlY29uZHNdIC0gVGltZW91dCBpbiBzZWNvbmRzIGZvciB0aGUgdGVzdC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbdHlwZV0gLSBUZXN0IHR5cGUgaWRlbnRpZmllci5cbiAqIEBwcm9wZXJ0eSB7KGFyZ3M6IHtkYXRhYmFzZUlkZW50aWZpZXI6IHN0cmluZywgdGVuYW50OiBvYmplY3R9KSA9PiBQcm9taXNlPHZvaWQ+fSBbcmVnaXN0ZXJUcmFuc2FjdGlvbmFsVGVuYW50XSAtIFJlZ2lzdGVycyBvbmUgcmVzb2x2ZWQgdGVuYW50IGRhdGFiYXNlIHRyYW5zYWN0aW9uIGZvciB0aGlzIGF0dGVtcHQuXG4gKi9cbi8qKlxuICogQnJvd3NlckR1bW15Q29ubmVjdGlvblJlZ2lzdHJhdGlvbiB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gQnJvd3NlckR1bW15Q29ubmVjdGlvblJlZ2lzdHJhdGlvblxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gZGIgLSBBdHRlbXB0LW93bmVkIGNvbm5lY3Rpb24uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gZGF0YWJhc2VJZGVudGlmaWVyIC0gQ29uZmlndXJlZCBkYXRhYmFzZSBpZGVudGlmaWVyLlxuICogQHByb3BlcnR5IHtQcm9taXNlPHZvaWQ+fSBbcXVhcmFudGluZVByb21pc2VdIC0gU2hhcmVkIGNvbm5lY3Rpb24tZGlzY2FyZCBwcm9taXNlLlxuICogQHByb3BlcnR5IHtib29sZWFufSBxdWFyYW50aW5lZCAtIFdoZXRoZXIgdGhlIGNvbm5lY3Rpb24gaXMgdW5zYWZlIHRvIHJldXNlLlxuICogQHByb3BlcnR5IHtQcm9taXNlPHZvaWQ+fSBbcm9sbGJhY2tQcm9taXNlXSAtIFNoYXJlZCByb2xsYmFjayBwcm9taXNlLlxuICogQHByb3BlcnR5IHtQcm9taXNlPHZvaWQ+fSBbc3RhcnRQcm9taXNlXSAtIFRyYW5zYWN0aW9uIHN0YXJ0dXAgcHJvbWlzZSB3aGVuIHRyYW5zYWN0aW9uIGNsZWFuaW5nIGlzIGVuYWJsZWQuXG4gKi9cbi8qKlxuICogVGVzdERhdGEgdHlwZS5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IFRlc3REYXRhXG4gKiBAcHJvcGVydHkge1Rlc3RBcmdzfSBhcmdzIC0gQXJndW1lbnRzIHBhc3NlZCB0byB0aGUgdGVzdC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbZmlsZVBhdGhdIC0gU291cmNlIGZpbGUgcGF0aC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbGluZV0gLSBTb3VyY2UgbGluZSBudW1iZXIuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW293bmVyRmlsZVBhdGhdIC0gRGV0ZXJtaW5pc3RpYyBpbXBvcnRpbmcgdGVzdCBmaWxlLlxuICogQHByb3BlcnR5IHsoYXJnOiBUZXN0QXJncykgPT4gKHZvaWR8UHJvbWlzZTx2b2lkPil9IGZ1bmN0aW9uIC0gVGVzdCBjYWxsYmFjayB0byBleGVjdXRlLlxuICovXG4vKipcbiAqIEZhaWxlZFRlc3REZXRhaWwgdHlwZS5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IEZhaWxlZFRlc3REZXRhaWxcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBmdWxsRGVzY3JpcHRpb24gLSBGdWxsIHRlc3QgZGVzY3JpcHRpb24uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2ZpbGVQYXRoXSAtIFNvdXJjZSBmaWxlIHBhdGguXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2xpbmVdIC0gU291cmNlIGxpbmUgbnVtYmVyLlxuICogQHByb3BlcnR5IHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gZXJyb3IgLSBGYWlsdXJlIGVycm9yLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtjb25zb2xlT3V0cHV0XSAtIENhcHR1cmVkIGNvbnNvbGUgb3V0cHV0IHdoaWxlIHRlc3QgcmFuLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtjb25zb2xlTG9nUGF0aF0gLSBTYXZlZCBjb25zb2xlIGxvZyBwYXRoLlxuICovXG4vKipcbiAqIEFjdGl2ZUFmdGVyQWxsU2NvcGVFbnRyeSB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gQWN0aXZlQWZ0ZXJBbGxTY29wZUVudHJ5XG4gKiBAcHJvcGVydHkge1Rlc3RzQXJndW1lbnR9IHRlc3RzIC0gU2NvcGUgdGVzdCB0cmVlLlxuICogQHByb3BlcnR5IHtib29sZWFufSBhZnRlckFsbHNSdW4gLSBXaGV0aGVyIGNsZWFudXAgaG9va3MgaGF2ZSBydW4uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW3Byb2ZpbGVTY29wZUlkXSAtIE9wYXF1ZSBwcm9maWxlIHNjb3BlIGlkZW50aWZpZXIuXG4gKi9cbi8qKlxuICogRGVmaW5lcyB0aGlzIHR5cGVkZWYuXG4gKiBAdHlwZWRlZiB7KGFyZ3M6IHtjb25maWd1cmF0aW9uOiBpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHQsIHRlc3RBcmdzOiBUZXN0QXJncywgdGVzdERhdGE6IFRlc3REYXRhfSkgPT4gKHZvaWR8UHJvbWlzZTx2b2lkPil9IEFmdGVyQmVmb3JlRWFjaENhbGxiYWNrVHlwZVxuICovXG4vKipcbiAqIEFmdGVyQmVmb3JlRWFjaENhbGxiYWNrT2JqZWN0VHlwZSB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gQWZ0ZXJCZWZvcmVFYWNoQ2FsbGJhY2tPYmplY3RUeXBlXG4gKiBAcHJvcGVydHkge0FmdGVyQmVmb3JlRWFjaENhbGxiYWNrVHlwZX0gY2FsbGJhY2sgLSBIb29rIGNhbGxiYWNrIHRvIGV4ZWN1dGUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2RlY2xhcmF0aW9uSW5kZXhdIC0gSG9vayBpbmRleCB3aXRoaW4gaXRzIGRlY2xhcmF0aW9uIHNjb3BlLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtkZWNsYXJhdGlvblNjb3BlSWRdIC0gT3BhcXVlIHByb2ZpbGUgc2NvcGUgaWRlbnRpZmllci5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbb3duZXJGaWxlUGF0aF0gLSBEZXRlcm1pbmlzdGljIGltcG9ydGluZyB0ZXN0IGZpbGUuXG4gKi9cbi8qKlxuICogRGVmaW5lcyB0aGlzIHR5cGVkZWYuXG4gKiBAdHlwZWRlZiB7KGFyZ3M6IHtjb25maWd1cmF0aW9uOiBpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9KSA9PiAodm9pZHxQcm9taXNlPHZvaWQ+KX0gQmVmb3JlQWZ0ZXJBbGxDYWxsYmFja1R5cGVcbiAqL1xuLyoqXG4gKiBCZWZvcmVBZnRlckFsbENhbGxiYWNrT2JqZWN0VHlwZSB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gQmVmb3JlQWZ0ZXJBbGxDYWxsYmFja09iamVjdFR5cGVcbiAqIEBwcm9wZXJ0eSB7QmVmb3JlQWZ0ZXJBbGxDYWxsYmFja1R5cGV9IGNhbGxiYWNrIC0gSG9vayBjYWxsYmFjayB0byBleGVjdXRlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtkZWNsYXJhdGlvbkluZGV4XSAtIEhvb2sgaW5kZXggd2l0aGluIGl0cyBkZWNsYXJhdGlvbiBzY29wZS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbZGVjbGFyYXRpb25TY29wZUlkXSAtIE9wYXF1ZSBwcm9maWxlIHNjb3BlIGlkZW50aWZpZXIuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW293bmVyRmlsZVBhdGhdIC0gRGV0ZXJtaW5pc3RpYyBpbXBvcnRpbmcgdGVzdCBmaWxlLlxuICovXG4vKipcbiAqIFRlc3RzQXJndW1lbnQgdHlwZS5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IFRlc3RzQXJndW1lbnRcbiAqIEBwcm9wZXJ0eSB7VGVzdEFyZ3N9IGFyZ3MgLSBBcmd1bWVudHMgaW5oZXJpdGVkIGJ5IHRlc3RzIGluIHRoaXMgc2NvcGUuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFthbnlUZXN0c0ZvY3Vzc2VkXSAtIFdoZXRoZXIgYW55IHRlc3RzIGluIHRoZSB0cmVlIGFyZSBmb2N1c2VkLlxuICogQHByb3BlcnR5IHtBZnRlckJlZm9yZUVhY2hDYWxsYmFja09iamVjdFR5cGVbXX0gYWZ0ZXJFYWNoZXMgLSBBZnRlci1lYWNoIGhvb2tzIGZvciB0aGlzIHNjb3BlLlxuICogQHByb3BlcnR5IHtCZWZvcmVBZnRlckFsbENhbGxiYWNrT2JqZWN0VHlwZVtdfSBhZnRlckFsbHMgLSBBZnRlci1hbGwgaG9va3MgZm9yIHRoaXMgc2NvcGUuXG4gKiBAcHJvcGVydHkge0JlZm9yZUFmdGVyQWxsQ2FsbGJhY2tPYmplY3RUeXBlW119IGJlZm9yZUFsbHMgLSBCZWZvcmUtYWxsIGhvb2tzIGZvciB0aGlzIHNjb3BlLlxuICogQHByb3BlcnR5IHtBZnRlckJlZm9yZUVhY2hDYWxsYmFja09iamVjdFR5cGVbXX0gYmVmb3JlRWFjaGVzIC0gQmVmb3JlLWVhY2ggaG9va3MgZm9yIHRoaXMgc2NvcGUuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2ZpbGVQYXRoXSAtIFNvdXJjZSBmaWxlIHBhdGguXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2xpbmVdIC0gU291cmNlIGxpbmUgbnVtYmVyLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtvd25lckZpbGVQYXRoXSAtIERldGVybWluaXN0aWMgaW1wb3J0aW5nIHRlc3QgZmlsZS5cbiAqIEBwcm9wZXJ0eSB7UmVjb3JkPHN0cmluZywgVGVzdERhdGE+fSB0ZXN0cyAtIEEgdW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBub2RlLlxuICogQHByb3BlcnR5IHtSZWNvcmQ8c3RyaW5nLCBUZXN0c0FyZ3VtZW50Pn0gc3VicyAtIE9wdGlvbmFsIGNoaWxkIG5vZGVzLiBFYWNoIGl0ZW0gaXMgYW5vdGhlciBgTm9kZWAsIGFsbG93aW5nIHJlY3Vyc2lvbi5cbiAqL1xuLyoqXG4gKiBNYXJrcyB0aGUgZXJyb3IgdGhyb3duIGJ5IHRoZSBhdHRlbXB0IHRpbWVvdXQgc28gdGhlIHJ1bm5lciBjYW4gZGlzdGluZ3Vpc2hcbiAqIGRldGFjaGVkIGxpZmVjeWNsZSBjbGVhbnVwIGZyb20gYW4gb3JkaW5hcnkgdGVzdCBmYWlsdXJlLlxuICogQHR5cGVkZWYge0Vycm9yICYge3ZlbG9jaW91c1Rlc3RUaW1lb3V0PzogdHJ1ZX19IFRlc3RUaW1lb3V0RXJyb3JcbiAqL1xuLyoqXG4gKiBTaGFyZWRUcmFuc2FjdGlvbkJyb2tlclJlZ2lzdHJhdGlvbiB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gU2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJSZWdpc3RyYXRpb25cbiAqIEBwcm9wZXJ0eSB7U2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJ9IGJyb2tlciAtIEF0dGVtcHQgYnJva2VyIGFuZCBjb25uZWN0aW9uIGNvb3JkaW5hdG9yLlxuICogQHByb3BlcnR5IHtib29sZWFufSBlbnZpcm9ubWVudFB1Ymxpc2hlZCAtIFdoZXRoZXIgY2hpbGQtcHJvY2VzcyBjb29yZGluYXRlcyB3ZXJlIHB1Ymxpc2hlZC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nIHwgdW5kZWZpbmVkfSBwcmV2aW91c0Vudmlyb25tZW50IC0gRW52aXJvbm1lbnQgdmFsdWUgdG8gcmVzdG9yZSBhZnRlciBwdWJsaWNhdGlvbi5cbiAqL1xuLyoqXG4gKiBUcmFuc2FjdGlvbmFsVGVuYW50UmVnaXN0cmF0aW9uIHR5cGUuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBUcmFuc2FjdGlvbmFsVGVuYW50UmVnaXN0cmF0aW9uXG4gKiBAcHJvcGVydHkge1Byb21pc2U8e2Nvbm5lY3Rpb246IGltcG9ydChcIi4uL2RhdGFiYXNlL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0IHwgdW5kZWZpbmVkLCBlcnJvcjogRXJyb3IgfCB1bmRlZmluZWR9PiB8IHVuZGVmaW5lZH0gW2NoZWNrb3V0UHJvbWlzZV0gLSBBdHRlbXB0LW93bmVkIHBoeXNpY2FsIGNoZWNrb3V0IG91dGNvbWUuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2RhdGFiYXNlL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0IHwgdW5kZWZpbmVkfSBjb25uZWN0aW9uIC0gQXR0ZW1wdC1vd25lZCBwaHlzaWNhbCBjb25uZWN0aW9uIG9uY2UgY2hlY2tvdXQgcmVzb2x2ZXMuXG4gKiBAcHJvcGVydHkge1Byb21pc2U8dm9pZD4gfCB1bmRlZmluZWR9IFtjbGVhbnVwUHJvbWlzZV0gLSBTaW5nbGUgY2xlYW51cCBvcGVyYXRpb24gc2hhcmVkIGJ5IGVtZXJnZW5jeSBhbmQgZXZlbnR1YWwgbGlmZWN5Y2xlIGNsZWFudXAuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW4gfCB1bmRlZmluZWR9IFtkaXNjYXJkT25DbGVhbnVwXSAtIFdoZXRoZXIgdGltZW91dCBlbWVyZ2VuY3kgY2xlYW51cCBtdXN0IHF1YXJhbnRpbmUgdGhpcyBjb25uZWN0aW9uLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9wb29sL2Jhc2UuanNcIikuZGVmYXVsdH0gcG9vbCAtIE93bmluZyBsb2dpY2FsIHBvb2wuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHJldm9rZWQgLSBXaGV0aGVyIHRoaXMgYXR0ZW1wdCBtYXkgc3RpbGwgcHVibGlzaCB0aGUgcGh5c2ljYWwgcmVnaXN0cmF0aW9uLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHJldXNlS2V5IC0gUmVzb2x2ZWQgcGh5c2ljYWwgY29uZmlndXJhdGlvbiBpZGVudGl0eS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZGF0YWJhc2UvcG9vbC9iYXNlLmpzXCIpLlRlc3RTaGFyZWRDb25uZWN0aW9uUmVnaXN0cmF0aW9uIHwgdW5kZWZpbmVkfSBzaGFyZWRSZWdpc3RyYXRpb24gLSBQaHlzaWNhbC1rZXkgc2hhcmVkIHJlZ2lzdHJhdGlvbiBvbmNlIHB1Ymxpc2hlZC5cbiAqL1xuXG4vKipcbiAqIENhcHR1cmVkIGNvbnNvbGUgbWV0aG9kcy5cbiAqIEB0eXBlIHtDb25zb2xlTWV0aG9kTmFtZVtdfSAqL1xuY29uc3QgQ0FQVFVSRURfQ09OU09MRV9NRVRIT0RTID0gW1wibG9nXCIsIFwiaW5mb1wiLCBcIndhcm5cIiwgXCJlcnJvclwiLCBcImRlYnVnXCJdXG5cbi8qKlxuICogUnVucyB0byBmaWxlIHNsdWcuXG4gKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgLSBWYWx1ZSB0byBzYW5pdGl6ZS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IC0gU2x1Zy1zYWZlIHZhbHVlLlxuICovXG5mdW5jdGlvbiB0b0ZpbGVTbHVnKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZVxuICAgIC50b0xvd2VyQ2FzZSgpXG4gICAgLnJlcGxhY2UoL1teYS16MC05XSsvZywgXCItXCIpXG4gICAgLnJlcGxhY2UoL14tK3wtKyQvZywgXCJcIilcbiAgICAuc2xpY2UoMCwgODApIHx8IFwiZmFpbGVkLXRlc3RcIlxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUZXN0UnVubmVyIHtcbiAgLyoqXG4gICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICogQHR5cGUge0FjdGl2ZUFmdGVyQWxsU2NvcGVFbnRyeVtdfSAqL1xuICBfYWN0aXZlQWZ0ZXJBbGxTY29wZXNcblxuICAvKipcbiAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgKiBAdHlwZSB7RmFpbGVkVGVzdERldGFpbFtdfSAqL1xuICBfZmFpbGVkVGVzdERldGFpbHNcblxuICAvKipcbiAgICogUnVucyBjb25zdHJ1Y3Rvci5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9IGFyZ3MuY29uZmlndXJhdGlvbiAtIENvbmZpZ3VyYXRpb24gaW5zdGFuY2UuXG4gICAqIEBwYXJhbSB7c3RyaW5nW10gfCBzdHJpbmd9IFthcmdzLmV4Y2x1ZGVUYWdzXSAtIFRhZ3MgdG8gZXhjbHVkZS5cbiAgICogQHBhcmFtIHtzdHJpbmdbXSB8IHN0cmluZ30gW2FyZ3MuaW5jbHVkZVRhZ3NdIC0gVGFncyB0byBpbmNsdWRlLlxuICAgKiBAcGFyYW0ge0FycmF5PHN0cmluZz59IGFyZ3MudGVzdEZpbGVzIC0gVGVzdCBmaWxlcy5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBudW1iZXJbXT59IFthcmdzLmxpbmVGaWx0ZXJzXSAtIExpbmUgZmlsdGVycyBieSBmaWxlLlxuICAgKiBAcGFyYW0ge1JlZ0V4cFtdfSBbYXJncy5leGFtcGxlUGF0dGVybnNdIC0gRXhhbXBsZSBwYXR0ZXJucy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3Rlc3QtcHJvZmlsZXIuanNcIikuZGVmYXVsdH0gW2FyZ3MucHJvZmlsZXJdIC0gT3B0LWluIHByb2ZpbGVyLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioe2NvbmZpZ3VyYXRpb24sIGV4Y2x1ZGVUYWdzLCBpbmNsdWRlVGFncywgdGVzdEZpbGVzLCBsaW5lRmlsdGVycywgZXhhbXBsZVBhdHRlcm5zLCBwcm9maWxlciwgLi4ucmVzdEFyZ3N9KSB7XG4gICAgcmVzdEFyZ3NFcnJvcihyZXN0QXJncylcblxuICAgIGlmICghY29uZmlndXJhdGlvbikgdGhyb3cgbmV3IEVycm9yKFwiY29uZmlndXJhdGlvbiBpcyByZXF1aXJlZFwiKVxuXG4gICAgdGhpcy5fY29uZmlndXJhdGlvbiA9IGNvbmZpZ3VyYXRpb25cbiAgICB0aGlzLl9zaGFyZWRUcmFuc2FjdGlvbkNvb3JkaW5hdG9yT3duZXJTdG9yYWdlID0gbmV3IEFzeW5jTG9jYWxTdG9yYWdlKClcbiAgICB0aGlzLl90ZXN0RGF0YWJhc2VBY2Nlc3NTY29wZVN0b3JhZ2UgPSBuZXcgQXN5bmNMb2NhbFN0b3JhZ2UoKVxuICAgIHRoaXMuX2V4Y2x1ZGVUYWdzID0gdGhpcy5ub3JtYWxpemVUYWdzKGV4Y2x1ZGVUYWdzKVxuICAgIHRoaXMuX2V4Y2x1ZGVUYWdTZXQgPSBuZXcgU2V0KHRoaXMuX2V4Y2x1ZGVUYWdzKVxuICAgIHRoaXMuX2luY2x1ZGVUYWdzID0gdGhpcy5ub3JtYWxpemVUYWdzKGluY2x1ZGVUYWdzKVxuICAgIHRoaXMuX2luY2x1ZGVUYWdTZXQgPSBuZXcgU2V0KHRoaXMuX2luY2x1ZGVUYWdzKVxuICAgIHRoaXMuX3Rlc3RGaWxlcyA9IHRlc3RGaWxlc1xuICAgIHRoaXMuX2xpbmVGaWx0ZXJzID0gbGluZUZpbHRlcnMgfHwge31cbiAgICB0aGlzLl9leGFtcGxlUGF0dGVybnMgPSBleGFtcGxlUGF0dGVybnMgfHwgW11cbiAgICB0aGlzLl9wcm9maWxlciA9IHByb2ZpbGVyXG4gICAgdGhpcy5fYWJvcnRSZW1haW5pbmdUZXN0cyA9IGZhbHNlXG5cbiAgICB0aGlzLl9mYWlsZWRUZXN0cyA9IDBcbiAgICB0aGlzLl9zdWNjZXNzZnVsVGVzdHMgPSAwXG4gICAgdGhpcy5fdGVzdHNDb3VudCA9IDBcbiAgICB0aGlzLl9hY3RpdmVBZnRlckFsbFNjb3BlcyA9IFtdXG4gICAgdGhpcy5fZmFpbGVkVGVzdERldGFpbHMgPSBbXVxuICAgIC8qKiBAdHlwZSB7e2Z1bGxEZXNjcmlwdGlvbjogc3RyaW5nLCBmaWxlUGF0aDogc3RyaW5nLCBsaW5lOiBudW1iZXJ9IHwgbnVsbH0gKi9cbiAgICB0aGlzLl9sYXN0VGVzdENvbnRleHQgPSBudWxsXG4gICAgLyoqIEB0eXBlIHtBcnJheTx7ZnVsbERlc2NyaXB0aW9uOiBzdHJpbmcsIGZpbGVQYXRoOiBzdHJpbmcsIGxpbmU6IG51bWJlciwgZHVyYXRpb25NczogbnVtYmVyfT59ICovXG4gICAgdGhpcy5fdGVzdER1cmF0aW9ucyA9IFtdXG4gICAgdGhpcy5fYXR0ZW1wdEV4ZWN1dG9yID0gbmV3IFZlbG9jaW91c0F0dGVtcHRFeGVjdXRvcih7dGVzdFJ1bm5lcjogdGhpc30pXG4gICAgdGhpcy5fcnVubmVyUmVwb3J0ZXIgPSBuZXcgVmVsb2Npb3VzUnVubmVyUmVwb3J0ZXIoe3Rlc3RSdW5uZXI6IHRoaXN9KVxuICAgIHRoaXMuX3N1aXRlSG9va0V4ZWN1dG9yID0gbmV3IFZlbG9jaW91c1N1aXRlSG9va0V4ZWN1dG9yKHt0ZXN0UnVubmVyOiB0aGlzfSlcbiAgICB0aGlzLl90ZXN0QXJndW1lbnRzID0gbmV3IFZlbG9jaW91c1Rlc3RBcmd1bWVudHMoe3Rlc3RSdW5uZXI6IHRoaXN9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IGNvbmZpZ3VyYXRpb24uXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9IC0gVGhlIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBnZXRDb25maWd1cmF0aW9uKCkgeyByZXR1cm4gdGhpcy5fY29uZmlndXJhdGlvbiB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IHRlc3QgZmlsZXMuXG4gICAqIEByZXR1cm5zIHtzdHJpbmdbXX0gLSBUaGUgdGVzdCBmaWxlcy5cbiAgICovXG4gIGdldFRlc3RGaWxlcygpIHsgcmV0dXJuIHRoaXMuX3Rlc3RGaWxlcyB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IGxpbmUgZmlsdGVycy5cbiAgICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIG51bWJlcltdPn0gLSBMaW5lIGZpbHRlcnMuXG4gICAqL1xuICBnZXRMaW5lRmlsdGVycygpIHsgcmV0dXJuIHRoaXMuX2xpbmVGaWx0ZXJzIH1cblxuICAvKipcbiAgICogUnVucyBnZXQgZXhhbXBsZSBwYXR0ZXJucy5cbiAgICogQHJldHVybnMge1JlZ0V4cFtdfSAtIEV4YW1wbGUgcGF0dGVybnMuXG4gICAqL1xuICBnZXRFeGFtcGxlUGF0dGVybnMoKSB7IHJldHVybiB0aGlzLl9leGFtcGxlUGF0dGVybnMgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGEgcHJvZmlsZXIgc3BhbiBvbmx5IHdoZW4gcHJvZmlsaW5nIHdhcyBleHBsaWNpdGx5IGVuYWJsZWQuXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBtZXRhZGF0YSAtIFNwYW4gbWV0YWRhdGEuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXRhZGF0YS5waGFzZSAtIFBoYXNlIG5hbWUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbbWV0YWRhdGEuZGVjbGFyYXRpb25JbmRleF0gLSBIb29rIGRlY2xhcmF0aW9uIGluZGV4LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW21ldGFkYXRhLmRlY2xhcmF0aW9uU2NvcGVJZF0gLSBIb29rIGRlY2xhcmF0aW9uIHNjb3BlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW21ldGFkYXRhLmZpbGVQYXRoXSAtIFNvdXJjZSBvd25lcnNoaXAuXG4gICAqIEBwYXJhbSB7KCkgPT4gKFQgfCBQcm9taXNlPFQ+KX0gY2FsbGJhY2sgLSBUaW1lZCBjYWxsYmFjay5cbiAgICogQHJldHVybnMge1Byb21pc2U8VD59IC0gQ2FsbGJhY2sgcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgcnVuUHJvZmlsZVNwYW4obWV0YWRhdGEsIGNhbGxiYWNrKSB7XG4gICAgaWYgKCF0aGlzLl9wcm9maWxlcikgcmV0dXJuIGF3YWl0IGNhbGxiYWNrKClcblxuICAgIHJldHVybiBhd2FpdCB0aGlzLl9wcm9maWxlci5ydW5TcGFuKG1ldGFkYXRhLCBjYWxsYmFjaylcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGRlY2xhcmF0aW9uIG1ldGFkYXRhIHRvIGhvb2tzIG9ubHkgZm9yIGFuIGFjdGl2ZSBwcm9maWxlLlxuICAgKiBAdGVtcGxhdGUge0FmdGVyQmVmb3JlRWFjaENhbGxiYWNrT2JqZWN0VHlwZSB8IEJlZm9yZUFmdGVyQWxsQ2FsbGJhY2tPYmplY3RUeXBlfSBUXG4gICAqIEBwYXJhbSB7VFtdfSBob29rcyAtIEhvb2tzIGRlY2xhcmVkIGluIG9uZSBzY29wZS5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCB1bmRlZmluZWR9IGRlY2xhcmF0aW9uU2NvcGVJZCAtIFByb2ZpbGUgc2NvcGUgaWRlbnRpZmllci5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCB1bmRlZmluZWR9IG93bmVyRmlsZVBhdGggLSBTY29wZSBvd25lciBmaWxlLlxuICAgKiBAcmV0dXJucyB7VFtdfSAtIFByb2ZpbGUtYXdhcmUgaG9vayBlbnRyaWVzLlxuICAgKi9cbiAgcHJvZmlsZUhvb2tFbnRyaWVzKGhvb2tzLCBkZWNsYXJhdGlvblNjb3BlSWQsIG93bmVyRmlsZVBhdGgpIHtcbiAgICBpZiAoIXRoaXMuX3Byb2ZpbGVyKSByZXR1cm4gaG9va3NcblxuICAgIHJldHVybiBob29rcy5tYXAoKGhvb2ssIGRlY2xhcmF0aW9uSW5kZXgpID0+IE9iamVjdC5hc3NpZ24oe30sIGhvb2ssIHtcbiAgICAgIGRlY2xhcmF0aW9uSW5kZXg6IGhvb2suZGVjbGFyYXRpb25JbmRleCA/PyBkZWNsYXJhdGlvbkluZGV4LFxuICAgICAgZGVjbGFyYXRpb25TY29wZUlkOiBob29rLmRlY2xhcmF0aW9uU2NvcGVJZCA/PyBkZWNsYXJhdGlvblNjb3BlSWQsXG4gICAgICBvd25lckZpbGVQYXRoOiBob29rLm93bmVyRmlsZVBhdGggPz8gb3duZXJGaWxlUGF0aFxuICAgIH0pKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgbm9ybWFsaXplIHRhZ3MuXG4gICAqIEBwYXJhbSB7c3RyaW5nW10gfCBzdHJpbmcgfCB1bmRlZmluZWR9IHRhZ3MgLSBUYWdzLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nW119IC0gTm9ybWFsaXplZCB0YWdzLlxuICAgKi9cbiAgbm9ybWFsaXplVGFncyh0YWdzKSB7XG4gICAgaWYgKCF0YWdzKSByZXR1cm4gW11cblxuICAgIGNvbnN0IHZhbHVlcyA9IFtdXG4gICAgY29uc3QgcmF3VGFncyA9IEFycmF5LmlzQXJyYXkodGFncykgPyB0YWdzIDogW3RhZ3NdXG5cbiAgICBmb3IgKGNvbnN0IHJhd1RhZyBvZiByYXdUYWdzKSB7XG4gICAgICBpZiAocmF3VGFnID09PSB1bmRlZmluZWQgfHwgcmF3VGFnID09PSBudWxsKSBjb250aW51ZVxuXG4gICAgICBjb25zdCBwYXJ0cyA9IFN0cmluZyhyYXdUYWcpLnNwbGl0KFwiLFwiKVxuXG4gICAgICBmb3IgKGNvbnN0IHBhcnQgb2YgcGFydHMpIHtcbiAgICAgICAgY29uc3QgdHJpbW1lZCA9IHBhcnQudHJpbSgpXG5cbiAgICAgICAgaWYgKHRyaW1tZWQpIHZhbHVlcy5wdXNoKHRyaW1tZWQpXG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIEFycmF5LmZyb20obmV3IFNldCh2YWx1ZXMpKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaGFzIHRhZy5cbiAgICogQHBhcmFtIHtUZXN0QXJnc30gdGVzdEFyZ3MgLSBUZXN0IGFyZ3MuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgLSBUYWcgdG8gY2hlY2sgZm9yLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRhZyBpcyBwcmVzZW50LlxuICAgKi9cbiAgaGFzVGFnKHRlc3RBcmdzLCB0YWcpIHtcbiAgICByZXR1cm4gdGhpcy5ub3JtYWxpemVUYWdzKHRlc3RBcmdzPy50YWdzKS5pbmNsdWRlcyh0YWcpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBpcyBicm93c2VyIHRlc3QgbW9kZS5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciBydW5uaW5nIGJyb3dzZXIgdGVzdHMuXG4gICAqL1xuICBpc0Jyb3dzZXJUZXN0TW9kZSgpIHtcbiAgICByZXR1cm4gcHJvY2Vzcy5lbnYuVkVMT0NJT1VTX0JST1dTRVJfVEVTVFMgPT09IFwidHJ1ZVwiXG4gIH1cblxuICAvKipcbiAgICogUnVucyBydW4gd2l0aCBkdW1teSBpZiBuZWVkZWQuXG4gICAqIEBwYXJhbSB7VGVzdEFyZ3N9IHRlc3RBcmdzIC0gVGVzdCBhcmdzLlxuICAgKiBAcGFyYW0geygpID0+IFByb21pc2U8dm9pZD59IGNhbGxiYWNrIC0gQ2FsbGJhY2sgdG8gcnVuLlxuICAgKiBAcGFyYW0ge0Jyb3dzZXJEdW1teUNvbm5lY3Rpb25SZWdpc3RyYXRpb25bXX0gW2Jyb3dzZXJEdW1teUNvbm5lY3Rpb25SZWdpc3RyYXRpb25zXSAtIEF0dGVtcHQtb3duZWQgYnJvd3NlciBjb25uZWN0aW9ucy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHJ1bldpdGhEdW1teUlmTmVlZGVkKHRlc3RBcmdzLCBjYWxsYmFjaywgYnJvd3NlckR1bW15Q29ubmVjdGlvblJlZ2lzdHJhdGlvbnMgPSBbXSkge1xuICAgIGlmICghdGhpcy5oYXNUYWcodGVzdEFyZ3MsIFwiZHVtbXlcIikpIHtcbiAgICAgIGF3YWl0IGNhbGxiYWNrKClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmICh0aGlzLmlzQnJvd3NlclRlc3RNb2RlKCkpIHtcbiAgICAgIGF3YWl0IHRoaXMucnVuQnJvd3NlckR1bW15KHRlc3RBcmdzLCBjYWxsYmFjaywgYnJvd3NlckR1bW15Q29ubmVjdGlvblJlZ2lzdHJhdGlvbnMpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLnJ1bk5vZGVEdW1teShjYWxsYmFjaylcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHJ1biBub2RlIGR1bW15LlxuICAgKiBAcGFyYW0geygpID0+IFByb21pc2U8dm9pZD59IGNhbGxiYWNrIC0gQ2FsbGJhY2sgdG8gcnVuLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgcnVuTm9kZUR1bW15KGNhbGxiYWNrKSB7XG4gICAgY29uc3QgZHVtbXlQYXRoID0gcHJvY2Vzcy5lbnYuVkVMT0NJT1VTX0RVTU1ZX1BBVEggfHwgdGhpcy5kZWZhdWx0RHVtbXlQYXRoKClcbiAgICBjb25zdCBkdW1teUltcG9ydCA9IGF3YWl0IGltcG9ydChwYXRoVG9GaWxlVVJMKGR1bW15UGF0aCkuaHJlZilcbiAgICBjb25zdCBEdW1teSA9IGR1bW15SW1wb3J0LmRlZmF1bHRcblxuICAgIGlmICghRHVtbXk/LnJ1bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBEdW1teSBoZWxwZXIgbm90IGZvdW5kIGF0ICR7ZHVtbXlQYXRofWApXG4gICAgfVxuXG4gICAgLy8gUGVyc2lzdGVudCBzZXJ2ZXIgcmVzb3VyY2VzIG11c3Qgbm90IGluaGVyaXQgYW4gYXR0ZW1wdCBzY29wZSB0aGF0IHdpbGwgYmUgcmV2b2tlZC5cbiAgICBhd2FpdCB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5nZXRFbnZpcm9ubWVudEhhbmRsZXIoKS5ydW5XaXRoQ2FwdHVyZWRUZXN0RGF0YWJhc2VBY2Nlc3NTY29wZSh1bmRlZmluZWQsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IER1bW15LnJ1bihhc3luYyAoKSA9PiB7fSlcbiAgICB9KVxuICAgIHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLmFzc2VydERhdGFiYXNlQWNjZXNzQWxsb3dlZCgpXG4gICAgYXdhaXQgY2FsbGJhY2soKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZGVmYXVsdCBkdW1teSBwYXRoLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIERlZmF1bHQgZHVtbXkgaGVscGVyIHBhdGguXG4gICAqL1xuICBkZWZhdWx0RHVtbXlQYXRoKCkge1xuICAgIGNvbnN0IGN3ZCA9IHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpKVxuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBjd2Quc3BsaXQocGF0aC5zZXApLmpvaW4oXCIvXCIpXG5cbiAgICBpZiAobm9ybWFsaXplZC5lbmRzV2l0aChcIi9zcGVjL2R1bW15XCIpKSB7XG4gICAgICByZXR1cm4gcGF0aC5qb2luKGN3ZCwgXCJpbmRleC5qc1wiKVxuICAgIH1cblxuICAgIHJldHVybiBwYXRoLmpvaW4oY3dkLCBcInNwZWMvZHVtbXkvaW5kZXguanNcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHJ1biBicm93c2VyIGR1bW15LlxuICAgKiBAcGFyYW0ge1Rlc3RBcmdzfSB0ZXN0QXJncyAtIFRlc3QgYXJncy5cbiAgICogQHBhcmFtIHsoKSA9PiBQcm9taXNlPHZvaWQ+fSBjYWxsYmFjayAtIENhbGxiYWNrIHRvIHJ1bi5cbiAgICogQHBhcmFtIHtCcm93c2VyRHVtbXlDb25uZWN0aW9uUmVnaXN0cmF0aW9uW119IGNvbm5lY3Rpb25SZWdpc3RyYXRpb25zIC0gQXR0ZW1wdC1vd25lZCBicm93c2VyIGNvbm5lY3Rpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgcnVuQnJvd3NlckR1bW15KHRlc3RBcmdzLCBjYWxsYmFjaywgY29ubmVjdGlvblJlZ2lzdHJhdGlvbnMpIHtcbiAgICBjb25zdCB1c2VUcmFuc2FjdGlvbiA9IHRlc3RBcmdzLmRhdGFiYXNlQ2xlYW5pbmc/LnRyYW5zYWN0aW9uID09PSB0cnVlXG4gICAgY29uc3QgdHJ1bmNhdGUgPSB0ZXN0QXJncy5kYXRhYmFzZUNsZWFuaW5nPy50cnVuY2F0ZVxuICAgIGNvbnN0IHNob3VsZFRydW5jYXRlID0gdHJ1bmNhdGUgPT09IHVuZGVmaW5lZCA/ICF1c2VUcmFuc2FjdGlvbiA6IHRydW5jYXRlXG5cbiAgICBpZiAoIXVzZVRyYW5zYWN0aW9uICYmICFzaG91bGRUcnVuY2F0ZSkge1xuICAgICAgYXdhaXQgY2FsbGJhY2soKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuZW5zdXJlQ29ubmVjdGlvbnMoe25hbWU6IFwiVGVzdCBydW5uZXIgYnJvd3NlciBkdW1teVwifSwgYXN5bmMgKGRicykgPT4ge1xuICAgICAgY29uc3QgbmV3UmVnaXN0cmF0aW9ucyA9IE9iamVjdC5lbnRyaWVzKGRicykubWFwKChbZGF0YWJhc2VJZGVudGlmaWVyLCBkYl0pID0+IHtcbiAgICAgICAgLyoqIEB0eXBlIHtCcm93c2VyRHVtbXlDb25uZWN0aW9uUmVnaXN0cmF0aW9ufSAqL1xuICAgICAgICBjb25zdCByZWdpc3RyYXRpb24gPSB7XG4gICAgICAgICAgZGF0YWJhc2VJZGVudGlmaWVyLFxuICAgICAgICAgIGRiLFxuICAgICAgICAgIHF1YXJhbnRpbmVkOiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgY29ubmVjdGlvblJlZ2lzdHJhdGlvbnMucHVzaChyZWdpc3RyYXRpb24pXG5cbiAgICAgICAgcmV0dXJuIHJlZ2lzdHJhdGlvblxuICAgICAgfSlcblxuICAgICAgaWYgKHNob3VsZFRydW5jYXRlKSB7XG4gICAgICAgIHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLmFzc2VydERhdGFiYXNlQWNjZXNzQWxsb3dlZCgpXG4gICAgICAgIGF3YWl0IHRoaXMudHJ1bmNhdGVEYXRhYmFzZXMoZGJzKVxuICAgICAgfVxuICAgICAgLyoqIEB0eXBlIHt1bmtub3duW119ICovXG4gICAgICBjb25zdCBsaWZlY3ljbGVFcnJvcnMgPSBbXVxuXG4gICAgICB0cnkge1xuICAgICAgICBpZiAodXNlVHJhbnNhY3Rpb24pIHtcbiAgICAgICAgICBjb25zdCBzdGFydFByb21pc2VzID0gbmV3UmVnaXN0cmF0aW9ucy5tYXAoKHJlZ2lzdHJhdGlvbikgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RhcnRQcm9taXNlID0gcmVnaXN0cmF0aW9uLmRiLnN0YXJ0VHJhbnNhY3Rpb24oKVxuXG4gICAgICAgICAgICByZWdpc3RyYXRpb24uc3RhcnRQcm9taXNlID0gc3RhcnRQcm9taXNlXG4gICAgICAgICAgICByZXR1cm4gc3RhcnRQcm9taXNlXG4gICAgICAgICAgfSlcbiAgICAgICAgICBjb25zdCBzdGFydFJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoc3RhcnRQcm9taXNlcylcbiAgICAgICAgICBjb25zdCBzdGFydEVycm9ycyA9IHN0YXJ0UmVzdWx0c1xuICAgICAgICAgICAgLmZpbHRlcigocmVzdWx0KSA9PiByZXN1bHQuc3RhdHVzID09PSBcInJlamVjdGVkXCIpXG4gICAgICAgICAgICAubWFwKChyZXN1bHQpID0+IHJlc3VsdC5yZWFzb24pXG5cbiAgICAgICAgICBpZiAoc3RhcnRFcnJvcnMubGVuZ3RoID09IDEpIHRocm93IHN0YXJ0RXJyb3JzWzBdXG4gICAgICAgICAgaWYgKHN0YXJ0RXJyb3JzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBZ2dyZWdhdGVFcnJvcihzdGFydEVycm9ycywgXCJCcm93c2VyIGR1bW15IHRyYW5zYWN0aW9uIHN0YXJ0dXAgZmFpbGVkXCIsIHtjYXVzZTogc3RhcnRFcnJvcnNbMF19KVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLmFzc2VydERhdGFiYXNlQWNjZXNzQWxsb3dlZCgpXG4gICAgICAgIGF3YWl0IGNhbGxiYWNrKClcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGxpZmVjeWNsZUVycm9ycy5wdXNoKGVycm9yKVxuICAgICAgfVxuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLnJvbGxiYWNrQnJvd3NlckR1bW15VHJhbnNhY3Rpb25zKGNvbm5lY3Rpb25SZWdpc3RyYXRpb25zKVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgQWdncmVnYXRlRXJyb3IpIHtcbiAgICAgICAgICBsaWZlY3ljbGVFcnJvcnMucHVzaCguLi5lcnJvci5lcnJvcnMpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbGlmZWN5Y2xlRXJyb3JzLnB1c2goZXJyb3IpXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKHNob3VsZFRydW5jYXRlKSB7XG4gICAgICAgICAgdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuYXNzZXJ0RGF0YWJhc2VBY2Nlc3NBbGxvd2VkKClcbiAgICAgICAgICBhd2FpdCB0aGlzLnRydW5jYXRlRGF0YWJhc2VzKGRicylcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbGlmZWN5Y2xlRXJyb3JzLnB1c2goZXJyb3IpXG4gICAgICB9XG5cbiAgICAgIGlmIChsaWZlY3ljbGVFcnJvcnMubGVuZ3RoID09IDEpIHRocm93IGxpZmVjeWNsZUVycm9yc1swXVxuICAgICAgaWYgKGxpZmVjeWNsZUVycm9ycy5sZW5ndGggPiAxKSB7XG4gICAgICAgIHRocm93IG5ldyBBZ2dyZWdhdGVFcnJvcihsaWZlY3ljbGVFcnJvcnMsIFwiQnJvd3NlciBkdW1teSBsaWZlY3ljbGUgYW5kIGNsZWFudXAgZmFpbGVkXCIsIHtjYXVzZTogbGlmZWN5Y2xlRXJyb3JzWzBdfSlcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJvbGxzIGJhY2sgZXZlcnkgYXR0ZW1wdC1vd25lZCBicm93c2VyIHRyYW5zYWN0aW9uIGV4YWN0bHkgb25jZS5cbiAgICogQHBhcmFtIHtCcm93c2VyRHVtbXlDb25uZWN0aW9uUmVnaXN0cmF0aW9uW119IHJlZ2lzdHJhdGlvbnMgLSBCcm93c2VyIGNvbm5lY3Rpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciBhbGwgcm9sbGJhY2tzIHNldHRsZS5cbiAgICovXG4gIGFzeW5jIHJvbGxiYWNrQnJvd3NlckR1bW15VHJhbnNhY3Rpb25zKHJlZ2lzdHJhdGlvbnMpIHtcbiAgICBjb25zdCByb2xsYmFja1Jlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoWy4uLnJlZ2lzdHJhdGlvbnNdLnJldmVyc2UoKS5tYXAoKHJlZ2lzdHJhdGlvbikgPT4ge1xuICAgICAgY29uc3Qgc3RhcnRQcm9taXNlID0gcmVnaXN0cmF0aW9uLnN0YXJ0UHJvbWlzZVxuXG4gICAgICBpZiAoIXN0YXJ0UHJvbWlzZSkgcmV0dXJuXG5cbiAgICAgIHJlZ2lzdHJhdGlvbi5yb2xsYmFja1Byb21pc2UgPz89IChhc3luYyAoKSA9PiB7XG4gICAgICAgIGlmIChyZWdpc3RyYXRpb24ucXVhcmFudGluZWQpIHJldHVyblxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgc3RhcnRQcm9taXNlXG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnF1YXJhbnRpbmVCcm93c2VyRHVtbXlDb25uZWN0aW9uKHJlZ2lzdHJhdGlvbilcbiAgICAgICAgICB9IGNhdGNoIChxdWFyYW50aW5lRXJyb3IpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIHF1YXJhbnRpbmUgYnJvd3NlciBkdW1teSBkYXRhYmFzZSBhZnRlciB0cmFuc2FjdGlvbiBzdGFydHVwIGZhaWxlZDogJHtyZWdpc3RyYXRpb24uZGF0YWJhc2VJZGVudGlmaWVyfWAsIHtjYXVzZTogcXVhcmFudGluZUVycm9yfSlcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlZ2lzdHJhdGlvbi5xdWFyYW50aW5lZCkgcmV0dXJuXG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCByZWdpc3RyYXRpb24uZGIucm9sbGJhY2tUcmFuc2FjdGlvbigpXG4gICAgICAgIH0gY2F0Y2ggKHJvbGxiYWNrRXJyb3IpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5xdWFyYW50aW5lQnJvd3NlckR1bW15Q29ubmVjdGlvbihyZWdpc3RyYXRpb24pXG4gICAgICAgICAgfSBjYXRjaCAocXVhcmFudGluZUVycm9yKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQWdncmVnYXRlRXJyb3IoXG4gICAgICAgICAgICAgIFtyb2xsYmFja0Vycm9yLCBxdWFyYW50aW5lRXJyb3JdLFxuICAgICAgICAgICAgICBgRmFpbGVkIHRvIHJvbGwgYmFjayBhbmQgcXVhcmFudGluZSBicm93c2VyIGR1bW15IGRhdGFiYXNlOiAke3JlZ2lzdHJhdGlvbi5kYXRhYmFzZUlkZW50aWZpZXJ9YCxcbiAgICAgICAgICAgICAge2NhdXNlOiBxdWFyYW50aW5lRXJyb3J9XG4gICAgICAgICAgICApXG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IHJvbGxiYWNrRXJyb3JcbiAgICAgICAgfVxuICAgICAgfSkoKVxuXG4gICAgICByZXR1cm4gcmVnaXN0cmF0aW9uLnJvbGxiYWNrUHJvbWlzZVxuICAgIH0pKVxuICAgIGNvbnN0IGVycm9ycyA9IHJvbGxiYWNrUmVzdWx0c1xuICAgICAgLmZpbHRlcigocmVzdWx0KSA9PiByZXN1bHQuc3RhdHVzID09PSBcInJlamVjdGVkXCIpXG4gICAgICAubWFwKChyZXN1bHQpID0+IHJlc3VsdC5yZWFzb24pXG5cbiAgICBpZiAoZXJyb3JzLmxlbmd0aCA9PSAxKSB0aHJvdyBlcnJvcnNbMF1cbiAgICBpZiAoZXJyb3JzLmxlbmd0aCA+IDEpIHRocm93IG5ldyBBZ2dyZWdhdGVFcnJvcihlcnJvcnMsIFwiQnJvd3NlciBkdW1teSB0cmFuc2FjdGlvbiBjbGVhbnVwIGZhaWxlZFwiLCB7Y2F1c2U6IGVycm9yc1swXX0pXG4gIH1cblxuICAvKipcbiAgICogUGVybWFuZW50bHkgcmVtb3ZlcyBvbmUgYnJvd3NlciBjb25uZWN0aW9uIHRoYXQgY2Fubm90IGJlIHNoYXJlZCBzYWZlbHkuXG4gICAqIEBwYXJhbSB7QnJvd3NlckR1bW15Q29ubmVjdGlvblJlZ2lzdHJhdGlvbn0gcmVnaXN0cmF0aW9uIC0gQnJvd3NlciBjb25uZWN0aW9uIHJlZ2lzdHJhdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgYWZ0ZXIgdGhlIGNvbm5lY3Rpb24gaXMgZGlzY2FyZGVkLlxuICAgKi9cbiAgYXN5bmMgcXVhcmFudGluZUJyb3dzZXJEdW1teUNvbm5lY3Rpb24ocmVnaXN0cmF0aW9uKSB7XG4gICAgcmVnaXN0cmF0aW9uLnF1YXJhbnRpbmVkID0gdHJ1ZVxuICAgIHJlZ2lzdHJhdGlvbi5xdWFyYW50aW5lUHJvbWlzZSA/Pz0gdGhpcy5kaXNjYXJkQnJvd3NlckR1bW15Q29ubmVjdGlvbihyZWdpc3RyYXRpb24uZGF0YWJhc2VJZGVudGlmaWVyLCByZWdpc3RyYXRpb24uZGIpXG4gICAgYXdhaXQgcmVnaXN0cmF0aW9uLnF1YXJhbnRpbmVQcm9taXNlXG4gIH1cblxuICAvKipcbiAgICogRGlzY2FyZHMgb25lIGJyb3dzZXIgZHVtbXkgY29ubmVjdGlvbiB0aHJvdWdoIGl0cyBvd25pbmcgcG9vbC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGRhdGFiYXNlSWRlbnRpZmllciAtIENvbmZpZ3VyZWQgZGF0YWJhc2UgaWRlbnRpZmllci5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gZGIgLSBVbnNhZmUgY29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgYWZ0ZXIgZGlzY2FyZC5cbiAgICovXG4gIGFzeW5jIGRpc2NhcmRCcm93c2VyRHVtbXlDb25uZWN0aW9uKGRhdGFiYXNlSWRlbnRpZmllciwgZGIpIHtcbiAgICBhd2FpdCB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5nZXREYXRhYmFzZVBvb2woZGF0YWJhc2VJZGVudGlmaWVyKS5kaXNjYXJkKGRiKVxuICB9XG5cbiAgLyoqXG4gICAqIFF1YXJhbnRpbmVzIGFsbCBicm93c2VyIGNvbm5lY3Rpb25zIGNvbmN1cnJlbnRseS5cbiAgICogQHBhcmFtIHtCcm93c2VyRHVtbXlDb25uZWN0aW9uUmVnaXN0cmF0aW9uW119IHJlZ2lzdHJhdGlvbnMgLSBCcm93c2VyIGNvbm5lY3Rpb24gcmVnaXN0cmF0aW9ucy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgYWZ0ZXIgZXZlcnkgY29ubmVjdGlvbiBpcyBkaXNjYXJkZWQuXG4gICAqL1xuICBhc3luYyBxdWFyYW50aW5lQnJvd3NlckR1bW15Q29ubmVjdGlvbnMocmVnaXN0cmF0aW9ucykge1xuICAgIGNvbnN0IHF1YXJhbnRpbmVSZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKHJlZ2lzdHJhdGlvbnMubWFwKGFzeW5jIChyZWdpc3RyYXRpb24pID0+IHtcbiAgICAgIGF3YWl0IHRoaXMucXVhcmFudGluZUJyb3dzZXJEdW1teUNvbm5lY3Rpb24ocmVnaXN0cmF0aW9uKVxuICAgIH0pKVxuICAgIGNvbnN0IGVycm9ycyA9IHF1YXJhbnRpbmVSZXN1bHRzXG4gICAgICAuZmlsdGVyKChyZXN1bHQpID0+IHJlc3VsdC5zdGF0dXMgPT09IFwicmVqZWN0ZWRcIilcbiAgICAgIC5tYXAoKHJlc3VsdCkgPT4gcmVzdWx0LnJlYXNvbilcblxuICAgIGlmIChlcnJvcnMubGVuZ3RoID09IDEpIHRocm93IGVycm9yc1swXVxuICAgIGlmIChlcnJvcnMubGVuZ3RoID4gMSkgdGhyb3cgbmV3IEFnZ3JlZ2F0ZUVycm9yKGVycm9ycywgXCJCcm93c2VyIGR1bW15IGNvbm5lY3Rpb24gcXVhcmFudGluZSBmYWlsZWRcIiwge2NhdXNlOiBlcnJvcnNbMF19KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgdHJ1bmNhdGUgZGF0YWJhc2VzLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGltcG9ydChcIi4uL2RhdGFiYXNlL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gZGJzIC0gRGF0YWJhc2UgY29ubmVjdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyB0cnVuY2F0ZURhdGFiYXNlcyhkYnMpIHtcbiAgICBmb3IgKGNvbnN0IGlkZW50aWZpZXIgb2YgT2JqZWN0LmtleXMoZGJzKSkge1xuICAgICAgYXdhaXQgZGJzW2lkZW50aWZpZXJdLnRydW5jYXRlQWxsVGFibGVzKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBnZXQgZXhjbHVkZSB0YWcgc2V0LlxuICAgKiBAcmV0dXJucyB7U2V0PHN0cmluZz59IC0gRXhjbHVkZSB0YWcgc2V0LlxuICAgKi9cbiAgZ2V0RXhjbHVkZVRhZ1NldCgpIHtcbiAgICAvKipcbiAgICAgKiBDb25maWcgdGFncy5cbiAgICAgKiBAdHlwZSB7c3RyaW5nW119ICovXG4gICAgY29uc3QgY29uZmlnVGFncyA9IEFycmF5LmlzQXJyYXkodGVzdENvbmZpZy5leGNsdWRlVGFncykgPyB0ZXN0Q29uZmlnLmV4Y2x1ZGVUYWdzIDogW11cblxuICAgIHJldHVybiBuZXcgU2V0KFsuLi50aGlzLl9leGNsdWRlVGFncywgLi4uY29uZmlnVGFnc10pXG4gIH1cblxuICAvKipcbiAgICogUnVucyBoYXMgbWF0Y2hpbmcgdGFnLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdIHwgc3RyaW5nIHwgdW5kZWZpbmVkfSB0ZXN0VGFncyAtIFRlc3QgdGFncy5cbiAgICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gdGFnU2V0IC0gVGFnIHNldC5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciBhbnkgdGFncyBtYXRjaC5cbiAgICovXG4gIGhhc01hdGNoaW5nVGFnKHRlc3RUYWdzLCB0YWdTZXQpIHtcbiAgICBpZiAoIXRhZ1NldC5zaXplKSByZXR1cm4gZmFsc2VcblxuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSB0aGlzLm5vcm1hbGl6ZVRhZ3ModGVzdFRhZ3MpXG5cbiAgICBmb3IgKGNvbnN0IHRhZyBvZiBub3JtYWxpemVkKSB7XG4gICAgICBpZiAodGFnU2V0Lmhhcyh0YWcpKSByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaGFzIHJ1bm5hYmxlIHRlc3RzLlxuICAgKiBAcGFyYW0ge1Rlc3RzQXJndW1lbnR9IHRlc3RzIC0gVGVzdHMuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IFtkZXNjcmlwdGlvbnNdIC0gRGVzY3JpcHRpb24gc3RhY2suXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2xpbmVNYXRjaGVkSW5TY29wZV0gLSBXaGV0aGVyIGxpbmUgbWF0Y2hlZCBpbiBzY29wZS5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciBhbnkgdGVzdHMgaW4gdGhpcyBzY29wZSB3aWxsIHJ1bi5cbiAgICovXG4gIGhhc1J1bm5hYmxlVGVzdHModGVzdHMsIGRlc2NyaXB0aW9ucyA9IFtdLCBsaW5lTWF0Y2hlZEluU2NvcGUgPSBmYWxzZSkge1xuICAgIGZvciAoY29uc3QgdGVzdERlc2NyaXB0aW9uIGluIHRlc3RzLnRlc3RzKSB7XG4gICAgICBjb25zdCB0ZXN0RGF0YSA9IHRlc3RzLnRlc3RzW3Rlc3REZXNjcmlwdGlvbl1cbiAgICAgIGNvbnN0IHRlc3RBcmdzID0gLyoqIEB0eXBlIHtUZXN0QXJnc30gKi8gKE9iamVjdC5hc3NpZ24oe30sIHRlc3REYXRhLmFyZ3MpKVxuICAgICAgY29uc3QgaW5jbHVkZUJ5TGluZSA9IGxpbmVNYXRjaGVkSW5TY29wZSB8fCB0aGlzLm1hdGNoZXNMaW5lRmlsdGVyKHRlc3REYXRhKVxuXG4gICAgICBpZiAodGhpcy5fb25seUZvY3Vzc2VkICYmICF0ZXN0QXJncy5mb2N1cykgY29udGludWVcbiAgICAgIGlmICh0aGlzLnNob3VsZFNraXBUZXN0KHRlc3RBcmdzLCB0ZXN0RGF0YSwgdGVzdERlc2NyaXB0aW9uLCBkZXNjcmlwdGlvbnMsIGluY2x1ZGVCeUxpbmUpKSBjb250aW51ZVxuXG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIGZvciAoY29uc3Qgc3ViRGVzY3JpcHRpb24gaW4gdGVzdHMuc3Vicykge1xuICAgICAgY29uc3Qgc3ViVGVzdCA9IHRlc3RzLnN1YnNbc3ViRGVzY3JpcHRpb25dXG4gICAgICBjb25zdCBzY29wZUxpbmVNYXRjaCA9IGxpbmVNYXRjaGVkSW5TY29wZSB8fCB0aGlzLm1hdGNoZXNMaW5lRmlsdGVyKHN1YlRlc3QpXG4gICAgICBjb25zdCBuZXh0RGVzY3JpcHRpb25zID0gZGVzY3JpcHRpb25zLmNvbmNhdChbc3ViRGVzY3JpcHRpb25dKVxuXG4gICAgICBpZiAodGhpcy5fb25seUZvY3Vzc2VkICYmICFzdWJUZXN0LmFueVRlc3RzRm9jdXNzZWQpIGNvbnRpbnVlXG4gICAgICBpZiAodGhpcy5oYXNSdW5uYWJsZVRlc3RzKHN1YlRlc3QsIG5leHREZXNjcmlwdGlvbnMsIHNjb3BlTGluZU1hdGNoKSkgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHNob3VsZCBza2lwIHRlc3QuXG4gICAqIEBwYXJhbSB7VGVzdEFyZ3N9IHRlc3RBcmdzIC0gVGVzdCBhcmdzLlxuICAgKiBAcGFyYW0ge1Rlc3REYXRhfSB0ZXN0RGF0YSAtIFRlc3QgZGF0YS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRlc3REZXNjcmlwdGlvbiAtIFRlc3QgZGVzY3JpcHRpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGRlc2NyaXB0aW9ucyAtIERlc2NyaXB0aW9uIHN0YWNrLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGxpbmVNYXRjaGVkSW5TY29wZSAtIFdoZXRoZXIgbGluZSBtYXRjaGVkIGluIHNjb3BlLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoZSB0ZXN0IHNob3VsZCBiZSBza2lwcGVkLlxuICAgKi9cbiAgc2hvdWxkU2tpcFRlc3QodGVzdEFyZ3MsIHRlc3REYXRhLCB0ZXN0RGVzY3JpcHRpb24sIGRlc2NyaXB0aW9ucywgbGluZU1hdGNoZWRJblNjb3BlKSB7XG4gICAgaWYgKHRoaXMuaGFzVGFnKHRlc3RBcmdzLCBcImJyb3dzZXItb25seVwiKSAmJiAhdGhpcy5pc0Jyb3dzZXJUZXN0TW9kZSgpKSByZXR1cm4gdHJ1ZVxuICAgIGlmICh0aGlzLmhhc01hdGNoaW5nVGFnKHRlc3RBcmdzLnRhZ3MsIHRoaXMuZ2V0RXhjbHVkZVRhZ1NldCgpKSkgcmV0dXJuIHRydWVcblxuICAgIGlmICh0aGlzLl9pbmNsdWRlVGFnU2V0LnNpemUgPiAwICYmICF0ZXN0QXJncy5mb2N1cykge1xuICAgICAgaWYgKCF0aGlzLmhhc01hdGNoaW5nVGFnKHRlc3RBcmdzLnRhZ3MsIHRoaXMuX2luY2x1ZGVUYWdTZXQpKSByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIGlmICh0aGlzLmdldEV4YW1wbGVQYXR0ZXJucygpLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGZ1bGxEZXNjcmlwdGlvbiA9IHRoaXMuYnVpbGRGdWxsRGVzY3JpcHRpb24oZGVzY3JpcHRpb25zLCB0ZXN0RGVzY3JpcHRpb24pXG4gICAgICBjb25zdCBtYXRjaGVzID0gdGhpcy5nZXRFeGFtcGxlUGF0dGVybnMoKS5zb21lKChwYXR0ZXJuKSA9PiB7XG4gICAgICAgIHBhdHRlcm4ubGFzdEluZGV4ID0gMFxuICAgICAgICByZXR1cm4gcGF0dGVybi50ZXN0KGZ1bGxEZXNjcmlwdGlvbilcbiAgICAgIH0pXG5cbiAgICAgIGlmICghbWF0Y2hlcykgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICBjb25zdCBsaW5lRmlsdGVycyA9IHRoaXMuZ2V0TGluZUZpbHRlcnMoKVxuXG4gICAgaWYgKE9iamVjdC5rZXlzKGxpbmVGaWx0ZXJzKS5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAoIWxpbmVNYXRjaGVkSW5TY29wZSAmJiAhdGhpcy5tYXRjaGVzTGluZUZpbHRlcih0ZXN0RGF0YSkpIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogUnVucyBtYXRjaGVzIGxpbmUgZmlsdGVyLlxuICAgKiBAcGFyYW0ge1Rlc3REYXRhIHwgVGVzdHNBcmd1bWVudH0gZW50cnkgLSBUZXN0IGVudHJ5LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGxpbmUgZmlsdGVyIG1hdGNoZXMgZW50cnkuXG4gICAqL1xuICBtYXRjaGVzTGluZUZpbHRlcihlbnRyeSkge1xuICAgIGlmICghZW50cnkgfHwgIWVudHJ5LmZpbGVQYXRoIHx8ICFlbnRyeS5saW5lKSByZXR1cm4gZmFsc2VcblxuICAgIGNvbnN0IGZpbGVQYXRoID0gcGF0aC5yZXNvbHZlKGVudHJ5LmZpbGVQYXRoKVxuICAgIGNvbnN0IGxpbmVzID0gdGhpcy5nZXRMaW5lRmlsdGVycygpW2ZpbGVQYXRoXVxuXG4gICAgaWYgKCFsaW5lcyB8fCBsaW5lcy5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZVxuXG4gICAgcmV0dXJuIGxpbmVzLmluY2x1ZGVzKGVudHJ5LmxpbmUpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBidWlsZCBmdWxsIGRlc2NyaXB0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBkZXNjcmlwdGlvbnMgLSBEZXNjcmlwdGlvbiBzdGFjay5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRlc3REZXNjcmlwdGlvbiAtIFRlc3QgZGVzY3JpcHRpb24uXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gRnVsbCBkZXNjcmlwdGlvbi5cbiAgICovXG4gIGJ1aWxkRnVsbERlc2NyaXB0aW9uKGRlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uKSB7XG4gICAgY29uc3QgcGFydHMgPSBkZXNjcmlwdGlvbnMuY29uY2F0KFt0ZXN0RGVzY3JpcHRpb25dKVxuXG4gICAgcmV0dXJuIHBhcnRzLmpvaW4oXCIgXCIpLnRyaW0oKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYXBwbGljYXRpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPEFwcGxpY2F0aW9uPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBhcHBsaWNhdGlvbi5cbiAgICovXG4gIGFzeW5jIGFwcGxpY2F0aW9uKCkge1xuICAgIGlmICghdGhpcy5fYXBwbGljYXRpb24pIHtcbiAgICAgIHRoaXMuX2FwcGxpY2F0aW9uID0gbmV3IEFwcGxpY2F0aW9uKHtcbiAgICAgICAgY29uZmlndXJhdGlvbjogdGhpcy5nZXRDb25maWd1cmF0aW9uKCksXG4gICAgICAgIC8vIFJ1biByZXF1ZXN0IGhhbmRsZXJzIGluIHRoZSBtYWluIHRocmVhZCAobm90IHdvcmtlciB0aHJlYWRzKSBzbyB0aGV5XG4gICAgICAgIC8vIHJlc29sdmUgREIgd29yayB0byB0aGUgcGVyLXRlc3Qgc2hhcmVkIGNvbm5lY3Rpb24gc2V0IGJ5XG4gICAgICAgIC8vIHtAbGluayBhY3RpdmF0ZVRlc3RTaGFyZWRDb25uZWN0aW9uc30uIFRoaXMgbGV0cyByZXF1ZXN0LXR5cGUgc3BlY3MgdXNlXG4gICAgICAgIC8vIHRyYW5zYWN0aW9uLWJhc2VkIGNsZWFuaW5nICh0aGVpciB3cml0ZXMgbGFuZCBpbnNpZGUgdGhlIHRlc3Qnc1xuICAgICAgICAvLyB0cmFuc2FjdGlvbiBhbmQgcm9sbCBiYWNrKSBpbnN0ZWFkIG9mIHRydW5jYXRpbmcgZXZlcnkgdGFibGUuXG4gICAgICAgIGh0dHBTZXJ2ZXI6IHtpblByb2Nlc3M6IHRydWUsIHBvcnQ6IDMxMDA2fSxcbiAgICAgICAgdHlwZTogXCJ0ZXN0LXJ1bm5lclwiXG4gICAgICB9KVxuXG4gICAgICBhd2FpdCB0aGlzLl9hcHBsaWNhdGlvbi5pbml0aWFsaXplKClcbiAgICAgIGF3YWl0IHRoaXMuX2FwcGxpY2F0aW9uLnN0YXJ0SHR0cFNlcnZlcigpXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2FwcGxpY2F0aW9uXG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIGVhY2ggbm9uLXRlbmFudCBwZXItdGVzdCBjb25uZWN0aW9uIGFzIGEgZHluYW1pYyBjYW5kaWRhdGUgZm9yIGluLXByb2Nlc3NcbiAgICogcmVxdWVzdCBzaGFyaW5nLiBUaGUgcG9vbCBldmFsdWF0ZXMgdHJhbnNhY3Rpb24gc3RhdGUgd2hlbiBlYWNoIHJlcXVlc3QgaXMgZGlzcGF0Y2hlZCxcbiAgICogc28gYSB0cmFuc2FjdGlvbiBzdGFydGVkIG9yIGVuZGVkIGR1cmluZyBhIGhvb2sgY2FsbGJhY2sgdGFrZXMgZWZmZWN0IGltbWVkaWF0ZWx5LlxuICAgKiBJbmFjdGl2ZSBhbmQgdGVuYW50LW9ubHkgY29ubmVjdGlvbnMgcmVtYWluIGluZGVwZW5kZW50bHkgcG9vbGVkLiBQYWlyIHdpdGhcbiAgICoge0BsaW5rIGNsZWFyVGVzdFNoYXJlZENvbm5lY3Rpb25zfSBpbiBhIGZpbmFsbHkuXG4gICAqIEByZXR1cm5zIHt7cG9vbDogaW1wb3J0KFwiLi4vZGF0YWJhc2UvcG9vbC9iYXNlLmpzXCIpLmRlZmF1bHQsIHJlZ2lzdHJhdGlvbjogaW1wb3J0KFwiLi4vZGF0YWJhc2UvcG9vbC9iYXNlLmpzXCIpLlRlc3RTaGFyZWRDb25uZWN0aW9uUmVnaXN0cmF0aW9ufVtdfSAtIExpZmVjeWNsZS1vd25lZCByZWdpc3RyYXRpb25zLlxuICAgKi9cbiAgYWN0aXZhdGVUZXN0U2hhcmVkQ29ubmVjdGlvbnMoKSB7XG4gICAgY29uc3QgY29uZmlndXJhdGlvbiA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpXG4gICAgY29uc3QgY3VycmVudENvbm5lY3Rpb25zID0gY29uZmlndXJhdGlvbi5nZXRDdXJyZW50Q29ubmVjdGlvbnMoKVxuICAgIC8qKiBAdHlwZSB7e3Bvb2w6IGltcG9ydChcIi4uL2RhdGFiYXNlL3Bvb2wvYmFzZS5qc1wiKS5kZWZhdWx0LCByZWdpc3RyYXRpb246IGltcG9ydChcIi4uL2RhdGFiYXNlL3Bvb2wvYmFzZS5qc1wiKS5UZXN0U2hhcmVkQ29ubmVjdGlvblJlZ2lzdHJhdGlvbn1bXX0gKi9cbiAgICBjb25zdCByZWdpc3RyYXRpb25zID0gW11cblxuICAgIGZvciAoY29uc3QgaWRlbnRpZmllciBvZiBPYmplY3Qua2V5cyhjdXJyZW50Q29ubmVjdGlvbnMpKSB7XG4gICAgICBjb25zdCBwb29sID0gY29uZmlndXJhdGlvbi5nZXREYXRhYmFzZVBvb2woaWRlbnRpZmllcilcblxuICAgICAgLy8gVGVuYW50LXNjb3BlZCBwb29scyByZXNvbHZlIGEgZGlmZmVyZW50IGNvbm5lY3Rpb24gcGVyIHJlcXVlc3QgdGVuYW50XG4gICAgICAvLyAodmlhIHJ1bldpdGhUZW5hbnQpLCBzbyBmb3JjaW5nIGEgc2luZ2xlIHNoYXJlZCBjb25uZWN0aW9uIHdvdWxkIGJyZWFrXG4gICAgICAvLyBwZXItcmVxdWVzdCB0ZW5hbnQgcmVzb2x1dGlvbi4gT25seSBzaGFyZSBub24tdGVuYW50IHBvb2xzOyB0aGUgdGVuYW50XG4gICAgICAvLyBwb29sIGtlZXBzIHJlc29sdmluZyBpdHMgb3duIGNvbm5lY3Rpb24gcGVyIHJlcXVlc3QuXG4gICAgICBpZiAocG9vbC5nZXRDb25maWd1cmF0aW9uKCkudGVuYW50T25seSkge1xuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBjb25zdCBjb25uZWN0aW9uID0gY3VycmVudENvbm5lY3Rpb25zW2lkZW50aWZpZXJdXG5cbiAgICAgIGNvbnN0IHJlZ2lzdHJhdGlvbiA9IHBvb2wuc2V0VGVzdFNoYXJlZENvbm5lY3Rpb25Qcm92aWRlcigoKSA9PiB7XG4gICAgICAgIHJldHVybiBjb25uZWN0aW9uLmluc2lkZVRyYW5zYWN0aW9uKCkgPyBjb25uZWN0aW9uIDogdW5kZWZpbmVkXG4gICAgICB9KVxuXG4gICAgICBpZiAocmVnaXN0cmF0aW9uKSByZWdpc3RyYXRpb25zLnB1c2goe3Bvb2wsIHJlZ2lzdHJhdGlvbn0pXG4gICAgfVxuXG4gICAgcmV0dXJuIHJlZ2lzdHJhdGlvbnNcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhcnMgdGhlIGluLXByb2Nlc3MgdGVzdCBzaGFyZWQgY29ubmVjdGlvbiBvbiBldmVyeSBjb25maWd1cmVkIHBvb2wuIElkZW1wb3RlbnQgYW5kXG4gICAqIHNhZmUgdG8gY2FsbCB3aGVuIG5vbmUgd2FzIHNldC5cbiAgICogQHBhcmFtIHt7cG9vbDogaW1wb3J0KFwiLi4vZGF0YWJhc2UvcG9vbC9iYXNlLmpzXCIpLmRlZmF1bHQsIHJlZ2lzdHJhdGlvbjogaW1wb3J0KFwiLi4vZGF0YWJhc2UvcG9vbC9iYXNlLmpzXCIpLlRlc3RTaGFyZWRDb25uZWN0aW9uUmVnaXN0cmF0aW9ufVtdfSBbcmVnaXN0cmF0aW9uc10gLSBMaWZlY3ljbGUtb3duZWQgcmVnaXN0cmF0aW9ucyB0byBjbGVhciBjb25kaXRpb25hbGx5LlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGNsZWFyVGVzdFNoYXJlZENvbm5lY3Rpb25zKHJlZ2lzdHJhdGlvbnMpIHtcbiAgICBpZiAocmVnaXN0cmF0aW9ucykge1xuICAgICAgZm9yIChjb25zdCB7cG9vbCwgcmVnaXN0cmF0aW9ufSBvZiByZWdpc3RyYXRpb25zKSB7XG4gICAgICAgIHBvb2wuY2xlYXJUZXN0U2hhcmVkQ29ubmVjdGlvbihyZWdpc3RyYXRpb24pXG4gICAgICB9XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBjb25maWd1cmF0aW9uID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKClcblxuICAgIGZvciAoY29uc3QgaWRlbnRpZmllciBvZiBjb25maWd1cmF0aW9uLmdldERhdGFiYXNlSWRlbnRpZmllcnMoKSkge1xuICAgICAgY29uZmlndXJhdGlvbi5nZXREYXRhYmFzZVBvb2woaWRlbnRpZmllcikuY2xlYXJUZXN0U2hhcmVkQ29ubmVjdGlvbigpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBvdXQgYW5kIHJlZ2lzdGVycyBvbmUgcGh5c2ljYWwgdGVuYW50IHRyYW5zYWN0aW9uIGZvciB0aGUgY3VycmVudCBhdHRlbXB0LlxuICAgKiBAcGFyYW0ge3tkYXRhYmFzZUlkZW50aWZpZXI6IHN0cmluZywgdGVuYW50OiBvYmplY3R9fSBhcmdzIC0gTG9naWNhbCBpZGVudGlmaWVyIGFuZCB0ZW5hbnQgZGVzY3JpcHRvci5cbiAgICogQHBhcmFtIHtUcmFuc2FjdGlvbmFsVGVuYW50UmVnaXN0cmF0aW9uW119IHJlZ2lzdHJhdGlvbnMgLSBDdXJyZW50IGF0dGVtcHQgcmVnaXN0cmF0aW9ucy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyByZWdpc3RlclRyYW5zYWN0aW9uYWxUZW5hbnQoe2RhdGFiYXNlSWRlbnRpZmllciwgdGVuYW50LCAuLi5yZXN0QXJnc30sIHJlZ2lzdHJhdGlvbnMpIHtcbiAgICByZXN0QXJnc0Vycm9yKHJlc3RBcmdzKVxuICAgIGlmICghZGF0YWJhc2VJZGVudGlmaWVyKSB0aHJvdyBuZXcgRXJyb3IoXCJyZWdpc3RlclRyYW5zYWN0aW9uYWxUZW5hbnQgcmVxdWlyZXMgYSBkYXRhYmFzZUlkZW50aWZpZXJcIilcbiAgICBpZiAoIXRlbmFudCkgdGhyb3cgbmV3IEVycm9yKFwicmVnaXN0ZXJUcmFuc2FjdGlvbmFsVGVuYW50IHJlcXVpcmVzIGEgdGVuYW50XCIpXG5cbiAgICBjb25zdCBjb25maWd1cmF0aW9uID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKClcbiAgICBjb25zdCBwb29sID0gY29uZmlndXJhdGlvbi5nZXREYXRhYmFzZVBvb2woZGF0YWJhc2VJZGVudGlmaWVyKVxuICAgIGNvbnN0IGRhdGFiYXNlQ29uZmlndXJhdGlvbiA9IGNvbmZpZ3VyYXRpb24ucmVzb2x2ZURhdGFiYXNlQ29uZmlndXJhdGlvbihkYXRhYmFzZUlkZW50aWZpZXIsIHRlbmFudClcbiAgICBpZiAoIWRhdGFiYXNlQ29uZmlndXJhdGlvbi50ZW5hbnRPbmx5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHJlZ2lzdGVyVHJhbnNhY3Rpb25hbFRlbmFudCByZXF1aXJlcyBhIHRlbmFudE9ubHkgZGF0YWJhc2U6ICR7ZGF0YWJhc2VJZGVudGlmaWVyfWApXG4gICAgfVxuICAgIGNvbnN0IHJldXNlS2V5ID0gcG9vbC5nZXRDb25maWd1cmF0aW9uUmV1c2VLZXkoZGF0YWJhc2VDb25maWd1cmF0aW9uKVxuICAgIGlmIChyZWdpc3RyYXRpb25zLnNvbWUoKHJlZ2lzdHJhdGlvbikgPT4gcmVnaXN0cmF0aW9uLnBvb2wgPT09IHBvb2wgJiYgcmVnaXN0cmF0aW9uLnJldXNlS2V5ID09PSByZXVzZUtleSkpIHJldHVyblxuXG4gICAgLyoqIEB0eXBlIHtUcmFuc2FjdGlvbmFsVGVuYW50UmVnaXN0cmF0aW9ufSAqL1xuICAgIGNvbnN0IHJlZ2lzdHJhdGlvbiA9IHtcbiAgICAgIGNvbm5lY3Rpb246IHVuZGVmaW5lZCxcbiAgICAgIHBvb2wsXG4gICAgICByZXVzZUtleSxcbiAgICAgIHJldm9rZWQ6IGZhbHNlLFxuICAgICAgc2hhcmVkUmVnaXN0cmF0aW9uOiB1bmRlZmluZWRcbiAgICB9XG5cbiAgICByZWdpc3RyYXRpb25zLnB1c2gocmVnaXN0cmF0aW9uKVxuICAgIHJlZ2lzdHJhdGlvbi5jaGVja291dFByb21pc2UgPSBwb29sXG4gICAgICAuY2hlY2tvdXRGb3JDb25maWd1cmF0aW9uKGRhdGFiYXNlQ29uZmlndXJhdGlvbiwge25hbWU6IFwiVHJhbnNhY3Rpb25hbCB0ZW5hbnQgdGVzdCByZWdpc3RyYXRpb25cIn0pXG4gICAgICAudGhlbihcbiAgICAgICAgKGNvbm5lY3Rpb24pID0+ICh7Y29ubmVjdGlvbiwgZXJyb3I6IHVuZGVmaW5lZH0pLFxuICAgICAgICAoZXJyb3IpID0+ICh7XG4gICAgICAgICAgY29ubmVjdGlvbjogdW5kZWZpbmVkLFxuICAgICAgICAgIGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoXCJUcmFuc2FjdGlvbmFsIHRlbmFudCBjb25uZWN0aW9uIGNoZWNrb3V0IGZhaWxlZFwiLCB7Y2F1c2U6IGVycm9yfSlcbiAgICAgICAgfSlcbiAgICAgIClcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBjaGVja291dE91dGNvbWUgPSBhd2FpdCByZWdpc3RyYXRpb24uY2hlY2tvdXRQcm9taXNlXG5cbiAgICAgIGlmIChjaGVja291dE91dGNvbWUuZXJyb3IpIHRocm93IGNoZWNrb3V0T3V0Y29tZS5lcnJvclxuICAgICAgaWYgKCFjaGVja291dE91dGNvbWUuY29ubmVjdGlvbikgdGhyb3cgbmV3IEVycm9yKFwiVHJhbnNhY3Rpb25hbCB0ZW5hbnQgY29ubmVjdGlvbiBjaGVja291dCByZXR1cm5lZCBubyBjb25uZWN0aW9uXCIpXG4gICAgICByZWdpc3RyYXRpb24uY29ubmVjdGlvbiA9IGNoZWNrb3V0T3V0Y29tZS5jb25uZWN0aW9uXG4gICAgICBpZiAocmVnaXN0cmF0aW9uLnJldm9rZWQpIHRocm93IG5ldyBFcnJvcihcIlRyYW5zYWN0aW9uYWwgdGVuYW50IHRlc3QgcmVnaXN0cmF0aW9uIGF0dGVtcHQgaXMgbm8gbG9uZ2VyIGFjdGl2ZVwiKVxuXG4gICAgICBhd2FpdCByZWdpc3RyYXRpb24uY29ubmVjdGlvbi5zdGFydFRyYW5zYWN0aW9uKClcbiAgICAgIGlmIChyZWdpc3RyYXRpb24ucmV2b2tlZCkgdGhyb3cgbmV3IEVycm9yKFwiVHJhbnNhY3Rpb25hbCB0ZW5hbnQgdGVzdCByZWdpc3RyYXRpb24gYXR0ZW1wdCBpcyBubyBsb25nZXIgYWN0aXZlXCIpXG5cbiAgICAgIGNvbnN0IHNoYXJlZFJlZ2lzdHJhdGlvbiA9IHBvb2wuc2V0VGVzdFNoYXJlZENvbm5lY3Rpb25Gb3JDb25maWd1cmF0aW9uKHJlZ2lzdHJhdGlvbi5jb25uZWN0aW9uLCByZXVzZUtleSlcbiAgICAgIGlmICghc2hhcmVkUmVnaXN0cmF0aW9uKSB0aHJvdyBuZXcgRXJyb3IoYERhdGFiYXNlIHBvb2wgZG9lcyBub3Qgc3VwcG9ydCB0cmFuc2FjdGlvbmFsIHRlbmFudCB0ZXN0IGNvbm5lY3Rpb25zOiAke2RhdGFiYXNlSWRlbnRpZmllcn1gKVxuICAgICAgcmVnaXN0cmF0aW9uLnNoYXJlZFJlZ2lzdHJhdGlvbiA9IHNoYXJlZFJlZ2lzdHJhdGlvblxuICAgICAgaWYgKHJlZ2lzdHJhdGlvbi5yZXZva2VkKSB7XG4gICAgICAgIHBvb2wuY2xlYXJUZXN0U2hhcmVkQ29ubmVjdGlvbihzaGFyZWRSZWdpc3RyYXRpb24pXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRyYW5zYWN0aW9uYWwgdGVuYW50IHRlc3QgcmVnaXN0cmF0aW9uIGF0dGVtcHQgaXMgbm8gbG9uZ2VyIGFjdGl2ZVwiKVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZWdpc3RyYXRpb24ucmV2b2tlZCA9IHRydWVcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMuY2xlYW51cFRyYW5zYWN0aW9uYWxUZW5hbnRzKFtyZWdpc3RyYXRpb25dLCB7ZGlzY2FyZDogcmVnaXN0cmF0aW9uLmRpc2NhcmRPbkNsZWFudXAgPT09IHRydWV9KVxuICAgICAgfSBjYXRjaCAoY2xlYW51cEVycm9yKSB7XG4gICAgICAgIHRocm93IG5ldyBBZ2dyZWdhdGVFcnJvcihbZXJyb3IsIGNsZWFudXBFcnJvcl0sIFwiRmFpbGVkIHRvIHJlZ2lzdGVyIGFuZCBjbGVhbiB1cCBhIHRyYW5zYWN0aW9uYWwgdGVuYW50IHRlc3QgY29ubmVjdGlvblwiLCB7Y2F1c2U6IGNsZWFudXBFcnJvcn0pXG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvclxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXZva2VzIGF0dGVtcHQgcmVnaXN0cmF0aW9ucyBiZWZvcmUgcm9sbGluZyBiYWNrIGFuZCByZWxlYXNpbmcgdGhlaXIgY29ubmVjdGlvbnMuXG4gICAqIEBwYXJhbSB7VHJhbnNhY3Rpb25hbFRlbmFudFJlZ2lzdHJhdGlvbltdfSByZWdpc3RyYXRpb25zIC0gQXR0ZW1wdCByZWdpc3RyYXRpb25zLlxuICAgKiBAcGFyYW0ge3tkaXNjYXJkPzogYm9vbGVhbn19IFtvcHRpb25zXSAtIFdoZXRoZXIgY29ubmVjdGlvbnMgbXVzdCBiZSBkaXNjYXJkZWQgaW5zdGVhZCBvZiByZXR1cm5lZCB0byB0aGUgcG9vbC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBjbGVhbnVwVHJhbnNhY3Rpb25hbFRlbmFudHMocmVnaXN0cmF0aW9ucywge2Rpc2NhcmQgPSBmYWxzZX0gPSB7fSkge1xuICAgIGZvciAoY29uc3QgcmVnaXN0cmF0aW9uIG9mIHJlZ2lzdHJhdGlvbnMpIHtcbiAgICAgIHJlZ2lzdHJhdGlvbi5yZXZva2VkID0gdHJ1ZVxuICAgICAgaWYgKGRpc2NhcmQpIHJlZ2lzdHJhdGlvbi5kaXNjYXJkT25DbGVhbnVwID0gdHJ1ZVxuICAgICAgaWYgKHJlZ2lzdHJhdGlvbi5zaGFyZWRSZWdpc3RyYXRpb24pIHJlZ2lzdHJhdGlvbi5wb29sLmNsZWFyVGVzdFNoYXJlZENvbm5lY3Rpb24ocmVnaXN0cmF0aW9uLnNoYXJlZFJlZ2lzdHJhdGlvbilcbiAgICB9XG4gICAgY29uc3QgY2xlYW51cFJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoWy4uLnJlZ2lzdHJhdGlvbnNdLnJldmVyc2UoKS5tYXAoKHJlZ2lzdHJhdGlvbikgPT4ge1xuICAgICAgcmVnaXN0cmF0aW9uLmNsZWFudXBQcm9taXNlID8/PSB0aGlzLmNsZWFudXBUcmFuc2FjdGlvbmFsVGVuYW50UmVnaXN0cmF0aW9uKHJlZ2lzdHJhdGlvbilcblxuICAgICAgcmV0dXJuIHJlZ2lzdHJhdGlvbi5jbGVhbnVwUHJvbWlzZVxuICAgIH0pKVxuICAgIGNvbnN0IGVycm9ycyA9IGNsZWFudXBSZXN1bHRzXG4gICAgICAuZmlsdGVyKChyZXN1bHQpID0+IHJlc3VsdC5zdGF0dXMgPT09IFwicmVqZWN0ZWRcIilcbiAgICAgIC5tYXAoKHJlc3VsdCkgPT4gcmVzdWx0LnJlYXNvbilcblxuICAgIGlmIChlcnJvcnMubGVuZ3RoID09PSAxKSB0aHJvdyBlcnJvcnNbMF1cbiAgICBpZiAoZXJyb3JzLmxlbmd0aCA+IDEpIHRocm93IG5ldyBBZ2dyZWdhdGVFcnJvcihlcnJvcnMsIFwiRmFpbGVkIHRvIGNsZWFuIHVwIHRyYW5zYWN0aW9uYWwgdGVuYW50IHRlc3QgY29ubmVjdGlvbnNcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhbnMgb25lIGF0dGVtcHQgcmVnaXN0cmF0aW9uIGV4YWN0bHkgb25jZSwgaW5jbHVkaW5nIGEgY2hlY2tvdXQgdGhhdCB3YXMgc3RpbGwgcGVuZGluZyBhdCByZXZvY2F0aW9uLlxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9uYWxUZW5hbnRSZWdpc3RyYXRpb259IHJlZ2lzdHJhdGlvbiAtIEF0dGVtcHQtb3duZWQgcmVnaXN0cmF0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciByb2xsYmFjayBhbmQgcmVsZWFzZSBvciBxdWFyYW50aW5lLlxuICAgKi9cbiAgYXN5bmMgY2xlYW51cFRyYW5zYWN0aW9uYWxUZW5hbnRSZWdpc3RyYXRpb24ocmVnaXN0cmF0aW9uKSB7XG4gICAgbGV0IGNvbm5lY3Rpb24gPSByZWdpc3RyYXRpb24uY29ubmVjdGlvblxuXG4gICAgaWYgKCFjb25uZWN0aW9uICYmIHJlZ2lzdHJhdGlvbi5jaGVja291dFByb21pc2UpIHtcbiAgICAgIGNvbnN0IGNoZWNrb3V0T3V0Y29tZSA9IGF3YWl0IHJlZ2lzdHJhdGlvbi5jaGVja291dFByb21pc2VcblxuICAgICAgaWYgKGNoZWNrb3V0T3V0Y29tZS5lcnJvcikgcmV0dXJuXG4gICAgICBjb25uZWN0aW9uID0gY2hlY2tvdXRPdXRjb21lLmNvbm5lY3Rpb25cbiAgICAgIHJlZ2lzdHJhdGlvbi5jb25uZWN0aW9uID0gY29ubmVjdGlvblxuICAgIH1cbiAgICBpZiAoIWNvbm5lY3Rpb24pIHJldHVyblxuXG4gICAgY29uc3QgZXJyb3JzID0gW11cblxuICAgIHRyeSB7XG4gICAgICBpZiAoY29ubmVjdGlvbi5pbnNpZGVUcmFuc2FjdGlvbigpKSBhd2FpdCBjb25uZWN0aW9uLnJvbGxiYWNrVHJhbnNhY3Rpb24oKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBlcnJvcnMucHVzaChlcnJvcilcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKHJlZ2lzdHJhdGlvbi5kaXNjYXJkT25DbGVhbnVwKSB7XG4gICAgICAgICAgYXdhaXQgcmVnaXN0cmF0aW9uLnBvb2wuZGlzY2FyZChjb25uZWN0aW9uKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGF3YWl0IHJlZ2lzdHJhdGlvbi5wb29sLmNoZWNraW4oY29ubmVjdGlvbilcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goZXJyb3IpXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlcnJvcnMubGVuZ3RoID09PSAxKSB0aHJvdyBlcnJvcnNbMF1cbiAgICBpZiAoZXJyb3JzLmxlbmd0aCA+IDEpIHRocm93IG5ldyBBZ2dyZWdhdGVFcnJvcihlcnJvcnMsIFwiRmFpbGVkIHRvIGNsZWFuIHVwIGEgdHJhbnNhY3Rpb25hbCB0ZW5hbnQgdGVzdCBjb25uZWN0aW9uXCIpXG4gIH1cblxuICAvKipcbiAgICogU2VsZWN0cyB0aGUgY3VycmVudCBub24tdGVuYW50IGNvbm5lY3Rpb25zIGVsaWdpYmxlIGZvciBzaGFyZWQgdHJhbnNhY3Rpb24gd29yay5cbiAgICogQHBhcmFtIHt7dHJhbnNhY3Rpb25zT25seTogYm9vbGVhbn19IGFyZ3MgLSBTZWxlY3Rpb24gb3B0aW9ucy5cbiAgICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIGltcG9ydChcIi4uL2RhdGFiYXNlL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gLSBFbGlnaWJsZSBjb25uZWN0aW9ucyBieSBpZGVudGlmaWVyLlxuICAgKi9cbiAgc2hhcmVkVHJhbnNhY3Rpb25Db25uZWN0aW9ucyh7dHJhbnNhY3Rpb25zT25seX0pIHtcbiAgICBjb25zdCBjb25maWd1cmF0aW9uID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKClcbiAgICBjb25zdCBjdXJyZW50Q29ubmVjdGlvbnMgPSBjb25maWd1cmF0aW9uLmdldEN1cnJlbnRDb25uZWN0aW9ucygpXG4gICAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBpbXBvcnQoXCIuLi9kYXRhYmFzZS9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59ICovXG4gICAgY29uc3QgY29ubmVjdGlvbnMgPSB7fVxuXG4gICAgZm9yIChjb25zdCBbaWRlbnRpZmllciwgY29ubmVjdGlvbl0gb2YgT2JqZWN0LmVudHJpZXMoY3VycmVudENvbm5lY3Rpb25zKSkge1xuICAgICAgY29uc3QgcG9vbCA9IGNvbmZpZ3VyYXRpb24uZ2V0RGF0YWJhc2VQb29sKGlkZW50aWZpZXIpXG5cbiAgICAgIGlmIChwb29sLmdldENvbmZpZ3VyYXRpb24oKS50ZW5hbnRPbmx5KSBjb250aW51ZVxuICAgICAgaWYgKHRyYW5zYWN0aW9uc09ubHkgJiYgIWNvbm5lY3Rpb24uaW5zaWRlVHJhbnNhY3Rpb24oKSkgY29udGludWVcbiAgICAgIGNvbm5lY3Rpb25zW2lkZW50aWZpZXJdID0gY29ubmVjdGlvblxuICAgIH1cblxuICAgIHJldHVybiBjb25uZWN0aW9uc1xuICB9XG5cbiAgLyoqXG4gICAqIEluc3RhbGxzIHBoeXNpY2FsLWNvbm5lY3Rpb24gY29vcmRpbmF0aW9uIGJlZm9yZSBhIHRyYW5zYWN0aW9uLW9wZW5pbmcgaG9va1xuICAgKiBjYW4gZXhwb3NlIHRoZSBzaGFyZWQgY29ubmVjdGlvbiB0byBhIGxvbmctbGl2ZWQgaW4tcHJvY2VzcyBzZXJ2aWNlLlxuICAgKiBDaGlsZC1wcm9jZXNzIGNvb3JkaW5hdGVzIHJlbWFpbiB1bnB1Ymxpc2hlZCB1bnRpbCB0aGUgdHJhbnNhY3Rpb24gZXhpc3RzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxTaGFyZWRUcmFuc2FjdGlvbkJyb2tlclJlZ2lzdHJhdGlvbiB8IHVuZGVmaW5lZD59IC0gUHJlcGFyZWQgY29vcmRpbmF0b3IuXG4gICAqL1xuICBhc3luYyBwcmVwYXJlU2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXIoKSB7XG4gICAgY29uc3QgY29ubmVjdGlvbnMgPSB0aGlzLnNoYXJlZFRyYW5zYWN0aW9uQ29ubmVjdGlvbnMoe3RyYW5zYWN0aW9uc09ubHk6IGZhbHNlfSlcblxuICAgIGlmIChPYmplY3Qua2V5cyhjb25uZWN0aW9ucykubGVuZ3RoID09PSAwKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgICByZXR1cm4ge1xuICAgICAgYnJva2VyOiBhd2FpdCBTaGFyZWRUcmFuc2FjdGlvbkJyb2tlci5zdGFydCh7Y29ubmVjdGlvbnN9KSxcbiAgICAgIGVudmlyb25tZW50UHVibGlzaGVkOiBmYWxzZSxcbiAgICAgIHByZXZpb3VzRW52aXJvbm1lbnQ6IHVuZGVmaW5lZFxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3Mgd2hldGhlciBhIHByZXBhcmVkIGJyb2tlciBjb29yZGluYXRlcyBleGFjdGx5IHRoZSBzZWxlY3RlZCBwaHlzaWNhbCBjb25uZWN0aW9ucy5cbiAgICogQHBhcmFtIHtTaGFyZWRUcmFuc2FjdGlvbkJyb2tlclJlZ2lzdHJhdGlvbiB8IHVuZGVmaW5lZH0gcmVnaXN0cmF0aW9uIC0gUHJlcGFyZWQgY29vcmRpbmF0b3IuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgaW1wb3J0KFwiLi4vZGF0YWJhc2UvZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+fSBjb25uZWN0aW9ucyAtIFNlbGVjdGVkIGNvbm5lY3Rpb25zLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoZSBpZGVudGlmaWVyIHNldCBhbmQgcGh5c2ljYWwgY29ubmVjdGlvbnMgbWF0Y2ggZXhhY3RseS5cbiAgICovXG4gIHNoYXJlZFRyYW5zYWN0aW9uQnJva2VyTWF0Y2hlc0Nvbm5lY3Rpb25zKHJlZ2lzdHJhdGlvbiwgY29ubmVjdGlvbnMpIHtcbiAgICBjb25zdCBpZGVudGlmaWVycyA9IE9iamVjdC5rZXlzKGNvbm5lY3Rpb25zKVxuXG4gICAgaWYgKCFyZWdpc3RyYXRpb24gfHwgaWRlbnRpZmllcnMubGVuZ3RoID09PSAwKSByZXR1cm4gZmFsc2VcbiAgICBpZiAoT2JqZWN0LmtleXMocmVnaXN0cmF0aW9uLmJyb2tlci5jb25uZWN0aW9ucykubGVuZ3RoICE9PSBpZGVudGlmaWVycy5sZW5ndGgpIHJldHVybiBmYWxzZVxuXG4gICAgZm9yIChjb25zdCBbaWRlbnRpZmllciwgY29ubmVjdGlvbl0gb2YgT2JqZWN0LmVudHJpZXMoY29ubmVjdGlvbnMpKSB7XG4gICAgICBpZiAocmVnaXN0cmF0aW9uLmJyb2tlci5jb25uZWN0aW9uc1tpZGVudGlmaWVyXSAhPT0gY29ubmVjdGlvbikgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydHMgYSBjYXBhYmlsaXR5LXNjb3BlZCBicm9rZXIgZm9yIHRoZSBhY3RpdmUgbm9uLXRlbmFudCBwaHlzaWNhbFxuICAgKiB0cmFuc2FjdGlvbiBjb25uZWN0aW9ucy4gTm8gYnJva2VyL2VudiBpcyBpbnN0YWxsZWQgZm9yIHRydW5jYXRpb24tb25seSBvclxuICAgKiBvdGhlciB0cmFuc2FjdGlvbi1kaXNhYmxlZCBhdHRlbXB0cy5cbiAgICogQHBhcmFtIHtTaGFyZWRUcmFuc2FjdGlvbkJyb2tlclJlZ2lzdHJhdGlvbn0gW3ByZXBhcmVkUmVnaXN0cmF0aW9uXSAtIENvb3JkaW5hdG9yIHByZXBhcmVkIGJlZm9yZSBob29rcy5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBpbXBvcnQoXCIuLi9kYXRhYmFzZS9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59IFtzZWxlY3RlZENvbm5lY3Rpb25zXSAtIFBvc3QtaG9vayBhY3RpdmUgY29ubmVjdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFNoYXJlZFRyYW5zYWN0aW9uQnJva2VyUmVnaXN0cmF0aW9uIHwgdW5kZWZpbmVkPn0gLSBBdHRlbXB0IHJlZ2lzdHJhdGlvbi5cbiAgICovXG4gIGFzeW5jIHN0YXJ0U2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXIocHJlcGFyZWRSZWdpc3RyYXRpb24sIHNlbGVjdGVkQ29ubmVjdGlvbnMpIHtcbiAgICBjb25zdCBjb25uZWN0aW9ucyA9IHNlbGVjdGVkQ29ubmVjdGlvbnMgfHwgdGhpcy5zaGFyZWRUcmFuc2FjdGlvbkNvbm5lY3Rpb25zKHt0cmFuc2FjdGlvbnNPbmx5OiB0cnVlfSlcblxuICAgIGNvbnN0IGRhdGFiYXNlSWRlbnRpZmllcnMgPSBPYmplY3Qua2V5cyhjb25uZWN0aW9ucylcbiAgICBpZiAoZGF0YWJhc2VJZGVudGlmaWVycy5sZW5ndGggPT09IDApIHtcbiAgICAgIGF3YWl0IHRoaXMuc3RvcFNoYXJlZFRyYW5zYWN0aW9uQnJva2VyKHByZXBhcmVkUmVnaXN0cmF0aW9uKVxuICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgIH1cblxuICAgIGxldCBicm9rZXJcblxuICAgIGlmIChwcmVwYXJlZFJlZ2lzdHJhdGlvbiAmJiB0aGlzLnNoYXJlZFRyYW5zYWN0aW9uQnJva2VyTWF0Y2hlc0Nvbm5lY3Rpb25zKHByZXBhcmVkUmVnaXN0cmF0aW9uLCBjb25uZWN0aW9ucykpIHtcbiAgICAgIGJyb2tlciA9IHByZXBhcmVkUmVnaXN0cmF0aW9uLmJyb2tlclxuICAgIH0gZWxzZSB7XG4gICAgICBhd2FpdCB0aGlzLnN0b3BTaGFyZWRUcmFuc2FjdGlvbkJyb2tlcihwcmVwYXJlZFJlZ2lzdHJhdGlvbilcbiAgICAgIGJyb2tlciA9IGF3YWl0IFNoYXJlZFRyYW5zYWN0aW9uQnJva2VyLnN0YXJ0KHtjb25uZWN0aW9uc30pXG4gICAgfVxuXG4gICAgY29uc3QgcHJldmlvdXNFbnZpcm9ubWVudCA9IHByb2Nlc3MuZW52W1NIQVJFRF9UUkFOU0FDVElPTl9CUk9LRVJfRU5WXVxuICAgIHByb2Nlc3MuZW52W1NIQVJFRF9UUkFOU0FDVElPTl9CUk9LRVJfRU5WXSA9IEJ1ZmZlci5mcm9tKEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIGFkZHJlc3M6IGJyb2tlci5hZGRyZXNzKCksXG4gICAgICBjYXBhYmlsaXR5OiBicm9rZXIuY2FwYWJpbGl0eSgpLFxuICAgICAgZGF0YWJhc2VJZGVudGlmaWVycyxcbiAgICAgIGV4cGVjdGVkOiB0cnVlXG4gICAgfSkpLnRvU3RyaW5nKFwiYmFzZTY0dXJsXCIpXG5cbiAgICByZXR1cm4ge2Jyb2tlciwgZW52aXJvbm1lbnRQdWJsaXNoZWQ6IHRydWUsIHByZXZpb3VzRW52aXJvbm1lbnR9XG4gIH1cblxuICAvKipcbiAgICogUmV2b2tlcyBhbiBhdHRlbXB0IGJyb2tlciBiZWZvcmUgZGF0YWJhc2Ugcm9sbGJhY2sgaG9va3MgcnVuIGFuZCByZXN0b3Jlc1xuICAgKiB0aGUgY2FsbGVyJ3MgZW52aXJvbm1lbnQgc28gbGF0ZXIgcG9vbGVkL3NwYXduZWQgY2hpbGRyZW4gY2Fubm90IGluaGVyaXQgaXQuXG4gICAqIEBwYXJhbSB7U2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJSZWdpc3RyYXRpb24gfCB1bmRlZmluZWR9IHJlZ2lzdHJhdGlvbiAtIEF0dGVtcHQgcmVnaXN0cmF0aW9uLlxuICAgKi9cbiAgYXN5bmMgc3RvcFNoYXJlZFRyYW5zYWN0aW9uQnJva2VyKHJlZ2lzdHJhdGlvbikge1xuICAgIGlmICghcmVnaXN0cmF0aW9uKSByZXR1cm5cblxuICAgIGlmIChyZWdpc3RyYXRpb24uZW52aXJvbm1lbnRQdWJsaXNoZWQpIHtcbiAgICAgIGlmIChyZWdpc3RyYXRpb24ucHJldmlvdXNFbnZpcm9ubWVudCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGRlbGV0ZSBwcm9jZXNzLmVudltTSEFSRURfVFJBTlNBQ1RJT05fQlJPS0VSX0VOVl1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHByb2Nlc3MuZW52W1NIQVJFRF9UUkFOU0FDVElPTl9CUk9LRVJfRU5WXSA9IHJlZ2lzdHJhdGlvbi5wcmV2aW91c0Vudmlyb25tZW50XG4gICAgICB9XG4gICAgfVxuICAgIGF3YWl0IHJlZ2lzdHJhdGlvbi5icm9rZXIuY2xvc2UoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcmVxdWVzdCBjbGllbnQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFJlcXVlc3RDbGllbnQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIHJlcXVlc3QgY2xpZW50LlxuICAgKi9cbiAgYXN5bmMgcmVxdWVzdENsaWVudCgpIHtcbiAgICBpZiAoIXRoaXMuX3JlcXVlc3RDbGllbnQpIHtcbiAgICAgIHRoaXMuX3JlcXVlc3RDbGllbnQgPSBuZXcgUmVxdWVzdENsaWVudCgpXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3JlcXVlc3RDbGllbnRcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGltcG9ydCB0ZXN0IGZpbGVzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgaW1wb3J0VGVzdEZpbGVzKCkge1xuICAgIGNvbnN0IGVudmlyb25tZW50SGFuZGxlciA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLmdldEVudmlyb25tZW50SGFuZGxlcigpXG5cbiAgICBpZiAoIXRoaXMuX3Byb2ZpbGVyKSB7XG4gICAgICBhd2FpdCBlbnZpcm9ubWVudEhhbmRsZXIuaW1wb3J0VGVzdEZpbGVzKHRoaXMuZ2V0VGVzdEZpbGVzKCkpXG4gICAgICBzeW5jaHJvbml6ZVRlc3RpbmdQYWNrYWdlVGVzdHModGVzdHMpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHRlc3RGaWxlIG9mIHRoaXMuZ2V0VGVzdEZpbGVzKCkpIHtcbiAgICAgIGNvbnN0IGV4aXN0aW5nUmVnaXN0cmF0aW9ucyA9IHRoaXMudGVzdFJlZ2lzdHJhdGlvbk9iamVjdHModGVzdHMpXG5cbiAgICAgIGF3YWl0IHRoaXMuX3Byb2ZpbGVyLm1lYXN1cmVQaGFzZShcImltcG9ydHNcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCBlbnZpcm9ubWVudEhhbmRsZXIuaW1wb3J0VGVzdEZpbGVzKFt0ZXN0RmlsZV0pXG4gICAgICB9LCB7ZmlsZVBhdGg6IHRlc3RGaWxlfSlcbiAgICAgIHN5bmNocm9uaXplVGVzdGluZ1BhY2thZ2VUZXN0cyh0ZXN0cylcbiAgICAgIHRoaXMuYXNzaWduVGVzdFJlZ2lzdHJhdGlvbk93bmVyc2hpcCh0ZXN0cywgZXhpc3RpbmdSZWdpc3RyYXRpb25zLCB0ZXN0RmlsZSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29sbGVjdHMgcmVnaXN0ZXJlZCBzY29wZSwgaG9vaywgYW5kIHRlc3Qgb2JqZWN0cyBieSBpZGVudGl0eS5cbiAgICogQHBhcmFtIHtUZXN0c0FyZ3VtZW50fSBzY29wZSAtIFRlc3Qgc2NvcGUuXG4gICAqIEBwYXJhbSB7U2V0PG9iamVjdD59IFtyZWdpc3RyYXRpb25zXSAtIEFjY3VtdWxhdGVkIGlkZW50aXRpZXMuXG4gICAqIEByZXR1cm5zIHtTZXQ8b2JqZWN0Pn0gLSBSZWdpc3RyYXRpb24gaWRlbnRpdGllcy5cbiAgICovXG4gIHRlc3RSZWdpc3RyYXRpb25PYmplY3RzKHNjb3BlLCByZWdpc3RyYXRpb25zID0gbmV3IFNldCgpKSB7XG4gICAgcmVnaXN0cmF0aW9ucy5hZGQoc2NvcGUpXG5cbiAgICBmb3IgKGNvbnN0IGhvb2sgb2YgWy4uLnNjb3BlLmJlZm9yZUFsbHMsIC4uLnNjb3BlLmJlZm9yZUVhY2hlcywgLi4uc2NvcGUuYWZ0ZXJFYWNoZXMsIC4uLnNjb3BlLmFmdGVyQWxsc10pIHtcbiAgICAgIHJlZ2lzdHJhdGlvbnMuYWRkKGhvb2spXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCB0ZXN0RGF0YSBvZiBPYmplY3QudmFsdWVzKHNjb3BlLnRlc3RzKSkgcmVnaXN0cmF0aW9ucy5hZGQodGVzdERhdGEpXG4gICAgZm9yIChjb25zdCBjaGlsZFNjb3BlIG9mIE9iamVjdC52YWx1ZXMoc2NvcGUuc3VicykpIHRoaXMudGVzdFJlZ2lzdHJhdGlvbk9iamVjdHMoY2hpbGRTY29wZSwgcmVnaXN0cmF0aW9ucylcblxuICAgIHJldHVybiByZWdpc3RyYXRpb25zXG4gIH1cblxuICAvKipcbiAgICogQXNzaWducyBkZXRlcm1pbmlzdGljIG93bmVyc2hpcCB0byByZWdpc3RyYXRpb25zIGFkZGVkIGJ5IG9uZSBlbnRyeSBmaWxlLFxuICAgKiBpbmNsdWRpbmcgZGVjbGFyYXRpb25zIG9yaWdpbmF0aW5nIGluIGEgaGVscGVyIGltcG9ydGVkIGJ5IHRoYXQgZW50cnkgZmlsZS5cbiAgICogQHBhcmFtIHtUZXN0c0FyZ3VtZW50fSBzY29wZSAtIFRlc3Qgc2NvcGUuXG4gICAqIEBwYXJhbSB7U2V0PG9iamVjdD59IHByZXZpb3VzUmVnaXN0cmF0aW9ucyAtIElkZW50aXRpZXMgcHJlc2VudCBiZWZvcmUgaW1wb3J0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3duZXJGaWxlUGF0aCAtIEltcG9ydGluZyBlbnRyeSBmaWxlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGFzc2lnblRlc3RSZWdpc3RyYXRpb25Pd25lcnNoaXAoc2NvcGUsIHByZXZpb3VzUmVnaXN0cmF0aW9ucywgb3duZXJGaWxlUGF0aCkge1xuICAgIGlmICghcHJldmlvdXNSZWdpc3RyYXRpb25zLmhhcyhzY29wZSkpIHNjb3BlLm93bmVyRmlsZVBhdGggPz89IG93bmVyRmlsZVBhdGhcblxuICAgIGZvciAoY29uc3QgaG9vayBvZiBbLi4uc2NvcGUuYmVmb3JlQWxscywgLi4uc2NvcGUuYmVmb3JlRWFjaGVzLCAuLi5zY29wZS5hZnRlckVhY2hlcywgLi4uc2NvcGUuYWZ0ZXJBbGxzXSkge1xuICAgICAgaWYgKCFwcmV2aW91c1JlZ2lzdHJhdGlvbnMuaGFzKGhvb2spKSBob29rLm93bmVyRmlsZVBhdGggPz89IG93bmVyRmlsZVBhdGhcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHRlc3REYXRhIG9mIE9iamVjdC52YWx1ZXMoc2NvcGUudGVzdHMpKSB7XG4gICAgICBpZiAoIXByZXZpb3VzUmVnaXN0cmF0aW9ucy5oYXModGVzdERhdGEpKSB0ZXN0RGF0YS5vd25lckZpbGVQYXRoID8/PSBvd25lckZpbGVQYXRoXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBjaGlsZFNjb3BlIG9mIE9iamVjdC52YWx1ZXMoc2NvcGUuc3VicykpIHtcbiAgICAgIHRoaXMuYXNzaWduVGVzdFJlZ2lzdHJhdGlvbk93bmVyc2hpcChjaGlsZFNjb3BlLCBwcmV2aW91c1JlZ2lzdHJhdGlvbnMsIG93bmVyRmlsZVBhdGgpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaXMgZmFpbGVkLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGZhaWxlZC5cbiAgICovXG4gIGlzRmFpbGVkKCkgeyByZXR1cm4gdGhpcy5fZmFpbGVkVGVzdHMgIT09IHVuZGVmaW5lZCAmJiB0aGlzLl9mYWlsZWRUZXN0cyA+IDAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCBmYWlsZWQgdGVzdHMuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gVGhlIGZhaWxlZCB0ZXN0cy5cbiAgICovXG4gIGdldEZhaWxlZFRlc3RzKCkge1xuICAgIGlmICh0aGlzLl9mYWlsZWRUZXN0cyA9PT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgRXJyb3IoXCJUZXN0cyBoYXNuJ3QgYmVlbiBydW4geWV0XCIpXG5cbiAgICByZXR1cm4gdGhpcy5fZmFpbGVkVGVzdHNcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCBmYWlsZWQgdGVzdCBkZXRhaWxzLlxuICAgKiBAcmV0dXJucyB7RmFpbGVkVGVzdERldGFpbFtdfSAtIEZhaWxlZCB0ZXN0IGRldGFpbHMuXG4gICAqL1xuICBnZXRGYWlsZWRUZXN0RGV0YWlscygpIHtcbiAgICByZXR1cm4gdGhpcy5fZmFpbGVkVGVzdERldGFpbHNcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHBlcnNpc3QgZmFpbGVkIHRlc3QgY29uc29sZSBvdXRwdXRzIHRvIGFzc2V0cy5cbiAgICogQHBhcmFtIHtvYmplY3R9IFthcmdzXSAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2FyZ3MuYXNzZXRzUGF0aF0gLSBBc3NldHMgZGlyZWN0b3J5IHBhdGguXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZ1tdPn0gLSBXcml0dGVuIGxvZyBmaWxlIHBhdGhzLlxuICAgKi9cbiAgYXN5bmMgcGVyc2lzdEZhaWxlZFRlc3RDb25zb2xlT3V0cHV0c1RvQXNzZXRzKHthc3NldHNQYXRoID0gcGF0aC5qb2luKHByb2Nlc3MuY3dkKCksIFwidG1wL3NjcmVlbnNob3RzXCIpfSA9IHt9KSB7XG4gICAgY29uc3QgZmFpbGVkVGVzdERldGFpbHMgPSB0aGlzLmdldEZhaWxlZFRlc3REZXRhaWxzKClcbiAgICBjb25zdCB3cml0dGVuTG9nUGF0aHMgPSBbXVxuICAgIGxldCBjcmVhdGVkRGlyZWN0b3J5ID0gZmFsc2VcblxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBmYWlsZWRUZXN0RGV0YWlscy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgIGNvbnN0IGZhaWxlZFRlc3REZXRhaWwgPSBmYWlsZWRUZXN0RGV0YWlsc1tpbmRleF1cbiAgICAgIGNvbnN0IGNvbnNvbGVPdXRwdXQgPSBmYWlsZWRUZXN0RGV0YWlsLmNvbnNvbGVPdXRwdXRcblxuICAgICAgaWYgKCFjb25zb2xlT3V0cHV0KSBjb250aW51ZVxuXG4gICAgICBpZiAoIWNyZWF0ZWREaXJlY3RvcnkpIHtcbiAgICAgICAgYXdhaXQgZnMubWtkaXIoYXNzZXRzUGF0aCwge3JlY3Vyc2l2ZTogdHJ1ZX0pXG4gICAgICAgIGNyZWF0ZWREaXJlY3RvcnkgPSB0cnVlXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKClcbiAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IFtcbiAgICAgICAgU3RyaW5nKG5vdy5nZXRGdWxsWWVhcigpKSxcbiAgICAgICAgU3RyaW5nKG5vdy5nZXRNb250aCgpICsgMSkucGFkU3RhcnQoMiwgXCIwXCIpLFxuICAgICAgICBTdHJpbmcobm93LmdldERhdGUoKSkucGFkU3RhcnQoMiwgXCIwXCIpLFxuICAgICAgICBTdHJpbmcobm93LmdldEhvdXJzKCkpLnBhZFN0YXJ0KDIsIFwiMFwiKSxcbiAgICAgICAgU3RyaW5nKG5vdy5nZXRNaW51dGVzKCkpLnBhZFN0YXJ0KDIsIFwiMFwiKSxcbiAgICAgICAgU3RyaW5nKG5vdy5nZXRTZWNvbmRzKCkpLnBhZFN0YXJ0KDIsIFwiMFwiKSxcbiAgICAgICAgU3RyaW5nKG5vdy5nZXRNaWxsaXNlY29uZHMoKSkucGFkU3RhcnQoMywgXCIwXCIpXG4gICAgICBdLmpvaW4oXCJcIilcbiAgICAgIGNvbnN0IHNsdWcgPSB0b0ZpbGVTbHVnKGZhaWxlZFRlc3REZXRhaWwuZnVsbERlc2NyaXB0aW9uKVxuICAgICAgY29uc3QgZmlsZU5hbWUgPSBgJHt0aW1lc3RhbXB9LSR7U3RyaW5nKGluZGV4ICsgMSkucGFkU3RhcnQoMiwgXCIwXCIpfS0ke3NsdWd9LmNvbnNvbGUubG9nYFxuICAgICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLmpvaW4oYXNzZXRzUGF0aCwgZmlsZU5hbWUpXG5cbiAgICAgIGF3YWl0IGZzLndyaXRlRmlsZShmaWxlUGF0aCwgY29uc29sZU91dHB1dCwgXCJ1dGY4XCIpXG4gICAgICBmYWlsZWRUZXN0RGV0YWlsLmNvbnNvbGVMb2dQYXRoID0gZmlsZVBhdGhcbiAgICAgIHdyaXR0ZW5Mb2dQYXRocy5wdXNoKGZpbGVQYXRoKVxuICAgIH1cblxuICAgIHJldHVybiB3cml0dGVuTG9nUGF0aHNcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCBzdWNjZXNzZnVsIHRlc3RzLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIFRoZSBzdWNjZXNzZnVsIHRlc3RzLlxuICAgKi9cbiAgZ2V0U3VjY2Vzc2Z1bFRlc3RzKCkge1xuICAgIGlmICh0aGlzLl9zdWNjZXNzZnVsVGVzdHMgPT09IHVuZGVmaW5lZCkgdGhyb3cgbmV3IEVycm9yKFwiVGVzdHMgaGFzbid0IGJlZW4gcnVuIHlldFwiKVxuXG4gICAgcmV0dXJuIHRoaXMuX3N1Y2Nlc3NmdWxUZXN0c1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IHRlc3RzIGNvdW50LlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIFRoZSB0ZXN0cyBjb3VudC5cbiAgICovXG4gIGdldFRlc3RzQ291bnQoKSB7XG4gICAgaWYgKHRoaXMuX3Rlc3RzQ291bnQgPT09IHVuZGVmaW5lZCkgdGhyb3cgbmV3IEVycm9yKFwiVGVzdHMgaGFzbid0IGJlZW4gcnVuIHlldFwiKVxuXG4gICAgcmV0dXJuIHRoaXMuX3Rlc3RzQ291bnRcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCBleGVjdXRlZCB0ZXN0cyBjb3VudC5cbiAgICogQHJldHVybnMge251bWJlcn0gLSBUaGUgZXhlY3V0ZWQgdGVzdHMgY291bnQuXG4gICAqL1xuICBnZXRFeGVjdXRlZFRlc3RzQ291bnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3Rlc3REdXJhdGlvbnMubGVuZ3RoXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgdGVzdHMgcmVjb3JkZWQgZHVyaW5nIHRoZSBydW4sIHNsb3dlc3QgZmlyc3QuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbbGltaXRdIC0gTWF4aW11bSBudW1iZXIgb2YgdGVzdHMgdG8gcmV0dXJuICgwIHJldHVybnMgYWxsKS5cbiAgICogQHJldHVybnMge0FycmF5PHtmdWxsRGVzY3JpcHRpb246IHN0cmluZywgZmlsZVBhdGg6IHN0cmluZywgbGluZTogbnVtYmVyLCBkdXJhdGlvbk1zOiBudW1iZXJ9Pn0gLSBTbG93ZXN0IHRlc3RzLCBzbG93ZXN0IGZpcnN0LlxuICAgKi9cbiAgZ2V0U2xvd2VzdFRlc3RzKGxpbWl0ID0gMTApIHtcbiAgICBjb25zdCBzb3J0ZWQgPSBbLi4udGhpcy5fdGVzdER1cmF0aW9uc10uc29ydCgodGVzdEEsIHRlc3RCKSA9PiB0ZXN0Qi5kdXJhdGlvbk1zIC0gdGVzdEEuZHVyYXRpb25NcylcblxuICAgIHJldHVybiBsaW1pdCA+IDAgPyBzb3J0ZWQuc2xpY2UoMCwgbGltaXQpIDogc29ydGVkXG4gIH1cblxuICAvKipcbiAgICogUnVucyBwcmVwYXJlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgcHJlcGFyZSgpIHtcbiAgICB0aGlzLmFueVRlc3RzRm9jdXNzZWQgPSBmYWxzZVxuICAgIHRoaXMuX2ZhaWxlZFRlc3RzID0gMFxuICAgIHRoaXMuX3N1Y2Nlc3NmdWxUZXN0cyA9IDBcbiAgICB0aGlzLl90ZXN0c0NvdW50ID0gMFxuICAgIHRoaXMuX2Fib3J0UmVtYWluaW5nVGVzdHMgPSBmYWxzZVxuICAgIHRoaXMuX2ZhaWxlZFRlc3REZXRhaWxzID0gW11cbiAgICB0aGlzLl90ZXN0RHVyYXRpb25zID0gW11cbiAgICBjb25zdCB0ZXN0aW5nQ29uZmlnUGF0aCA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLmdldFRlc3RpbmcoKVxuXG4gICAgaWYgKHRlc3RpbmdDb25maWdQYXRoKSB7XG4gICAgICBhd2FpdCB0aGlzLnJ1blByb2ZpbGVTcGFuKHtwaGFzZTogXCJ0ZXN0aW5nIGNvbmZpZy9nbG9iYWwgc2V0dXBcIn0sIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuZ2V0RW52aXJvbm1lbnRIYW5kbGVyKCkuaW1wb3J0VGVzdGluZ0NvbmZpZ1BhdGgoKVxuICAgICAgfSlcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLmltcG9ydFRlc3RGaWxlcygpXG4gICAgYXdhaXQgdGhpcy5hbmFseXplVGVzdHModGVzdHMpXG4gICAgdGhpcy5fb25seUZvY3Vzc2VkID0gdGhpcy5hbnlUZXN0c0ZvY3Vzc2VkXG4gIH1cblxuICAvKipcbiAgICogUnVucyBhcmUgYW55IHRlc3RzIGZvY3Vzc2VkLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGFueSB0ZXN0cyBmb2N1c3NlZC5cbiAgICovXG4gIGFyZUFueVRlc3RzRm9jdXNzZWQoKSB7XG4gICAgaWYgKHRoaXMuYW55VGVzdHNGb2N1c3NlZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJIYXNuJ3QgYmVlbiBkZXRlY3RlZCB5ZXRcIilcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5hbnlUZXN0c0ZvY3Vzc2VkXG4gIH1cblxuICAvKipcbiAgICogUnVucyBydW4uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICAvKipcbiAgICogUmVjb3JkcyBhbiBhc3luY2hyb25vdXMgY3Jhc2ggKGFuIHVuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvbiBkZXRhY2hlZCBmcm9tXG4gICAqIGFueSBhd2FpdCwgZS5nLiBhIGB2b2lkIGNvbm5lY3Rpb24uYWZ0ZXJDb21taXQoYXN5bmMgKCkgPT4gYnJvYWRjYXN0KC4uLikpYFxuICAgKiBmcm9udGVuZC1tb2RlbCBwdWJsaXNoIOKAlCBvciBhIHN5bmNocm9ub3VzIHRocm93IGluc2lkZSBhIGRldGFjaGVkIGNhbGxiYWNrXG4gICAqIHN1Y2ggYXMgYSBkcml2ZXIgc29ja2V0IG9yIHRpbWVyIGNhbGxiYWNrKSBhcyBhIHJlYWwsIHZpc2libGUsIGF0dHJpYnV0ZWRcbiAgICogdGVzdCBmYWlsdXJlLlxuICAgKlxuICAgKiBXaXRob3V0IHRoaXMsIHN1Y2ggYSByZWplY3Rpb24vZXhjZXB0aW9uIGhhcyBubyBoYW5kbGVyLCBzbyBvbiBtb2Rlcm4gTm9kZVxuICAgKiB0aGUgcHJvY2VzcyBpcyBURVJNSU5BVEVEIOKAlCB0aGUgcnVuIGVuZHMgd2l0aCBubyByZXBvcnRlZCBmYWlsdXJlcyBhbmQgQ0lcbiAgICoganVzdCBzZWVzIGEgY3Jhc2hlZC9yZXRyaWVkIHNoYXJkIHdpdGggYW4gZW1wdHkgcmVzdWx0ICh0aGUgcmVjdXJyaW5nXG4gICAqIFwic2lsZW50IHRlc3QtcnVubmVyIGRlYXRoXCI6IGludmlzaWJsZSBhbmQgaW1wb3NzaWJsZSB0byBkaWFnbm9zZSkuIFR1cm5pbmdcbiAgICogaXQgaW50byBhIGZhaWx1cmUgbWFrZXMgdGhlIHJ1biBnbyByZWQgd2l0aCBzb21ldGhpbmcgZGVidWdnYWJsZSBpbnN0ZWFkIG9mXG4gICAqIHZhbmlzaGluZy5cbiAgICogQHBhcmFtIHtcInVuY2F1Z2h0RXhjZXB0aW9uXCIgfCBcInVuaGFuZGxlZFJlamVjdGlvblwifSBraW5kIC0gQXN5bmMtY3Jhc2gga2luZC5cbiAgICogQHBhcmFtIHt1bmtub3dufSByZWFzb24gLSBSZWplY3Rpb24gcmVhc29uIG9yIHRocm93biBlcnJvci5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICByZWNvcmRBc3luY0NyYXNoKGtpbmQsIHJlYXNvbikge1xuICAgIGNvbnN0IGVycm9yID0gcmVhc29uIGluc3RhbmNlb2YgRXJyb3IgPyByZWFzb24gOiBuZXcgRXJyb3IoYCR7a2luZH06ICR7U3RyaW5nKHJlYXNvbil9YClcbiAgICBjb25zdCBuZWFyID0gdGhpcy5fbGFzdFRlc3RDb250ZXh0XG4gICAgY29uc3QgYXR0cmlidXRpb24gPSBuZWFyID8gYCwgbmVhciB0ZXN0OiAke25lYXIuZnVsbERlc2NyaXB0aW9ufSAoJHtuZWFyLmZpbGVQYXRofToke25lYXIubGluZX0pYCA6IFwiXCJcblxuICAgIHRoaXMuX2ZhaWxlZFRlc3RzID0gKHRoaXMuX2ZhaWxlZFRlc3RzIHx8IDApICsgMVxuICAgIHRoaXMuX2ZhaWxlZFRlc3REZXRhaWxzLnB1c2goe1xuICAgICAgZnVsbERlc2NyaXB0aW9uOiBgPCR7a2luZH0gZHVyaW5nIHRlc3QgcnVuJHthdHRyaWJ1dGlvbn0+YCxcbiAgICAgIGZpbGVQYXRoOiBuZWFyID8gbmVhci5maWxlUGF0aCA6IFwiPHRlc3QgcnVubmVyPlwiLFxuICAgICAgbGluZTogbmVhciA/IG5lYXIubGluZSA6IDAsXG4gICAgICBlcnJvcixcbiAgICAgIGNvbnNvbGVPdXRwdXQ6IHVuZGVmaW5lZFxuICAgIH0pXG5cbiAgICBjb25zb2xlLmVycm9yKHBpY29jb2xvcnMucmVkKGBcXG5bdGVzdC1ydW5uZXJdICR7a2luZH0gZHVyaW5nIHRoZSB0ZXN0IHJ1biDigJQgdGhpcyB3b3VsZCBvdGhlcndpc2UgdGVybWluYXRlIHRoZSBwcm9jZXNzIHNpbGVudGx5IGFuZCBzdXJmYWNlIG9ubHkgYXMgYSBjcmFzaGVkL3JldHJpZWQgc2hhcmQgd2l0aCB6ZXJvIHJlcG9ydGVkIGZhaWx1cmVzLiR7YXR0cmlidXRpb259YCkpXG4gICAgY29uc29sZS5lcnJvcihlcnJvcilcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvcmRzIGEgY2xlYW51cCBmYWlsdXJlIGFmdGVyIHRpbWVvdXQgaGFuZGxpbmcgaGFzIGJlZ3VuLlxuICAgKiBAcGFyYW0ge3Vua25vd259IHJlYXNvbiAtIERldGFjaGVkIGNsZWFudXAgcmVqZWN0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2xlYW51cE5hbWUgLSBDbGVhbnVwIG9wZXJhdGlvbiBuYW1lLlxuICAgKiBAcGFyYW0ge1NldDxFcnJvcj59IFtyZWNvcmRlZEVycm9yc10gLSBBdHRlbXB0LW93bmVkIGNsZWFudXAgZXJyb3JzIGFscmVhZHkgcmVwb3J0ZWQuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgcmVjb3JkVGltZW91dENsZWFudXBGYWlsdXJlKHJlYXNvbiwgY2xlYW51cE5hbWUsIHJlY29yZGVkRXJyb3JzKSB7XG4gICAgY29uc3QgZXJyb3IgPSByZWFzb24gaW5zdGFuY2VvZiBFcnJvciA/IHJlYXNvbiA6IG5ldyBFcnJvcihgJHtjbGVhbnVwTmFtZX0gY2xlYW51cCBmYWlsZWQ6ICR7U3RyaW5nKHJlYXNvbil9YClcblxuICAgIGlmIChyZWNvcmRlZEVycm9ycykge1xuICAgICAgLy8gTXVsdGlwbGUgYm91bmRlZCBvYnNlcnZlcnMgY2FuIHJlY2VpdmUgdGhlIHNhbWUgZGV0YWNoZWQgY2xlYW51cCByZWplY3Rpb24uXG4gICAgICBpZiAocmVjb3JkZWRFcnJvcnMuaGFzKGVycm9yKSkgcmV0dXJuXG4gICAgICByZWNvcmRlZEVycm9ycy5hZGQoZXJyb3IpXG4gICAgfVxuXG4gICAgY29uc3QgbmVhciA9IHRoaXMuX2xhc3RUZXN0Q29udGV4dFxuICAgIGNvbnN0IGF0dHJpYnV0aW9uID0gbmVhciA/IGAsIG5lYXIgdGVzdDogJHtuZWFyLmZ1bGxEZXNjcmlwdGlvbn0gKCR7bmVhci5maWxlUGF0aH06JHtuZWFyLmxpbmV9KWAgOiBcIlwiXG5cbiAgICB0aGlzLl9mYWlsZWRUZXN0cyA9ICh0aGlzLl9mYWlsZWRUZXN0cyB8fCAwKSArIDFcbiAgICB0aGlzLl9mYWlsZWRUZXN0RGV0YWlscy5wdXNoKHtcbiAgICAgIGZ1bGxEZXNjcmlwdGlvbjogYDwke2NsZWFudXBOYW1lfSBlbWVyZ2VuY3kgY2xlYW51cCBmYWlsdXJlJHthdHRyaWJ1dGlvbn0+YCxcbiAgICAgIGZpbGVQYXRoOiBuZWFyID8gbmVhci5maWxlUGF0aCA6IFwiPHRlc3QgcnVubmVyPlwiLFxuICAgICAgbGluZTogbmVhciA/IG5lYXIubGluZSA6IDAsXG4gICAgICBlcnJvcixcbiAgICAgIGNvbnNvbGVPdXRwdXQ6IHVuZGVmaW5lZFxuICAgIH0pXG5cbiAgICBjb25zb2xlLmVycm9yKHBpY29jb2xvcnMucmVkKGBcXG5bdGVzdC1ydW5uZXJdICR7Y2xlYW51cE5hbWV9IGNsZWFudXAgZmFpbGVkIGFmdGVyIHRpbWVvdXQgaGFuZGxpbmcgYmVnYW4uJHthdHRyaWJ1dGlvbn1gKSlcbiAgICBjb25zb2xlLmVycm9yKGVycm9yKVxuICB9XG5cbiAgYXN5bmMgcnVuKCkge1xuICAgIC8qKlxuICAgICAqIEhhbmRsZXMgYSBwcm9jZXNzLWxldmVsIHVuaGFuZGxlZCByZWplY3Rpb24gZHVyaW5nIHRoZSBydW4uXG4gICAgICogQHBhcmFtIHt1bmtub3dufSByZWFzb24gLSBSZWplY3Rpb24gcmVhc29uLlxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxuICAgICAqL1xuICAgIGNvbnN0IG9uVW5oYW5kbGVkUmVqZWN0aW9uID0gKHJlYXNvbikgPT4ge1xuICAgICAgLy8gSWYgYSB0ZXN0IGF0dGFjaGVkIGl0cyBPV04gdW5oYW5kbGVkUmVqZWN0aW9uIGxpc3RlbmVyLCBpdCBpc1xuICAgICAgLy8gaW50ZW50aW9uYWxseSBvYnNlcnZpbmcvdHJpZ2dlcmluZyB0aGUgcmVqZWN0aW9uIChlLmcuIGJlYWNvblxuICAgICAgLy8gZXJyb3ItcmVwb3J0aW5nLXNwZWMuanMpIOKAlCBOb2RlIGRpc3BhdGNoZXMgdG8gRVZFUlkgbGlzdGVuZXIsIHNvIGFsc29cbiAgICAgIC8vIGZhaWxpbmcgdGhlIHN1aXRlIGhlcmUgd291bGQgYnJlYWsgdGhvc2UgdGVzdHMuIERlZmVyIHRvIHRoZSB0ZXN0J3NcbiAgICAgIC8vIGhhbmRsZXI7IG9ubHkgdHJlYXQgYSByZWplY3Rpb24gYXMgYSBzaWxlbnQtZGVhdGggY3Jhc2ggd2hlbiBvdXJzIGlzIHRoZVxuICAgICAgLy8gc29sZSBsaXN0ZW5lciAobm8gcGVyc2lzdGVudCBmcmFtZXdvcmsgbGlzdGVuZXIgZXhpc3RzIHRvIG1hc2sgdGhpcykuXG4gICAgICBpZiAocHJvY2Vzcy5saXN0ZW5lckNvdW50KFwidW5oYW5kbGVkUmVqZWN0aW9uXCIpID4gMSkgcmV0dXJuXG5cbiAgICAgIHRoaXMucmVjb3JkQXN5bmNDcmFzaChcInVuaGFuZGxlZFJlamVjdGlvblwiLCByZWFzb24pXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlcyBhIHByb2Nlc3MtbGV2ZWwgdW5jYXVnaHQgZXhjZXB0aW9uIGR1cmluZyB0aGUgcnVuIOKAlCBhXG4gICAgICogc3luY2hyb25vdXMgdGhyb3cgaW5zaWRlIGEgZGV0YWNoZWQgY2FsbGJhY2sgKGRyaXZlciBzb2NrZXQsIHRpbWVyLFxuICAgICAqIGV2ZW50IGVtaXR0ZXIpIHRoYXQgbm8gdGVzdCBhd2FpdCBvYnNlcnZlcy4gU2FtZSBzaWxlbnQtZGVhdGggbW9kZSBhc1xuICAgICAqIHVuaGFuZGxlZCByZWplY3Rpb25zOiB3aXRob3V0IGEgaGFuZGxlciB0aGUgcHJvY2VzcyBkaWVzIG1pZC1ydW4gYW5kIENJXG4gICAgICogc2VlcyBhIGNyYXNoZWQgc2hhcmQgd2l0aCB6ZXJvIHJlcG9ydGVkIGZhaWx1cmVzLlxuICAgICAqIEBwYXJhbSB7dW5rbm93bn0gZXJyb3IgLSBUaHJvd24gZXJyb3IuXG4gICAgICogQHJldHVybnMge3ZvaWR9XG4gICAgICovXG4gICAgY29uc3Qgb25VbmNhdWdodEV4Y2VwdGlvbiA9IChlcnJvcikgPT4ge1xuICAgICAgLy8gTWlycm9yIHRoZSB1bmhhbmRsZWRSZWplY3Rpb24gZGVmZXJyYWw6IGEgdGVzdCBvYnNlcnZpbmcvdHJpZ2dlcmluZ1xuICAgICAgLy8gdW5jYXVnaHQgZXhjZXB0aW9ucyB3aXRoIGl0cyBvd24gbGlzdGVuZXIgb3ducyB0aGVtLlxuICAgICAgaWYgKHByb2Nlc3MubGlzdGVuZXJDb3VudChcInVuY2F1Z2h0RXhjZXB0aW9uXCIpID4gMSkgcmV0dXJuXG5cbiAgICAgIHRoaXMucmVjb3JkQXN5bmNDcmFzaChcInVuY2F1Z2h0RXhjZXB0aW9uXCIsIGVycm9yKVxuICAgIH1cblxuICAgIHByb2Nlc3Mub24oXCJ1bmhhbmRsZWRSZWplY3Rpb25cIiwgb25VbmhhbmRsZWRSZWplY3Rpb24pXG4gICAgcHJvY2Vzcy5vbihcInVuY2F1Z2h0RXhjZXB0aW9uXCIsIG9uVW5jYXVnaHRFeGNlcHRpb24pXG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5ydW5UZXN0cyh7XG4gICAgICAgIGFmdGVyRWFjaGVzOiBbXSxcbiAgICAgICAgYmVmb3JlRWFjaGVzOiBbXSxcbiAgICAgICAgdGVzdHMsXG4gICAgICAgIGRlc2NyaXB0aW9uczogW10sXG4gICAgICAgIGluZGVudExldmVsOiAwXG4gICAgICB9KVxuXG4gICAgICAvLyBBIHJlamVjdGlvbiBzY2hlZHVsZWQgYnkgdGhlIGZpbmFsIHRlc3QgKGEgZGV0YWNoZWQgcmVqZWN0ZWQgcHJvbWlzZSxcbiAgICAgIC8vIG9yIGFuIGFmdGVyQ29tbWl0IGNhbGxiYWNrIHJlamVjdGluZyBhcyB0aGUgc3VpdGUgZHJhaW5zKSBpcyByZXBvcnRlZFxuICAgICAgLy8gYnkgTm9kZSBvbiBhIExBVEVSIHR1cm4uIERyYWluIGEgZmV3IHR1cm5zIHdoaWxlIHRoZSBoYW5kbGVyIGlzIHN0aWxsXG4gICAgICAvLyBhdHRhY2hlZCBzbyB0aG9zZSBsYXRlIHJlamVjdGlvbnMgYXJlIHJlY29yZGVkIGluc3RlYWQgb2YgZXNjYXBpbmcgdG9cbiAgICAgIC8vIHRoZSBkZWZhdWx0IGNyYXNoIHBhdGggYWZ0ZXIgY2xlYW51cC5cbiAgICAgIGZvciAobGV0IGRyYWluVHVybiA9IDA7IGRyYWluVHVybiA8IDM7IGRyYWluVHVybisrKSB7XG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiBzZXRJbW1lZGlhdGUocmVzb2x2ZSkpXG4gICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHByb2Nlc3Mub2ZmKFwidW5oYW5kbGVkUmVqZWN0aW9uXCIsIG9uVW5oYW5kbGVkUmVqZWN0aW9uKVxuICAgICAgcHJvY2Vzcy5vZmYoXCJ1bmNhdWdodEV4Y2VwdGlvblwiLCBvblVuY2F1Z2h0RXhjZXB0aW9uKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHJ1biBhZnRlciBhbGxzIGZvciBhY3RpdmUgc2NvcGVzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNsZWFudXAgaG9va3MgZmluaXNoLlxuICAgKi9cbiAgYXN5bmMgcnVuQWZ0ZXJBbGxzRm9yQWN0aXZlU2NvcGVzKCkge1xuICAgIGNvbnN0IHNjb3BlcyA9IFsuLi50aGlzLl9hY3RpdmVBZnRlckFsbFNjb3Blc10ucmV2ZXJzZSgpXG4gICAgLyoqIEB0eXBlIHt1bmtub3duW119ICovXG4gICAgY29uc3QgYWZ0ZXJBbGxFcnJvcnMgPSBbXVxuXG4gICAgZm9yIChjb25zdCBzY29wZSBvZiBzY29wZXMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMucnVuQWZ0ZXJBbGxzRm9yU2NvcGUoc2NvcGUpXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBhZnRlckFsbEVycm9ycy5wdXNoKGVycm9yKVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX2FjdGl2ZUFmdGVyQWxsU2NvcGVzID0gW11cblxuICAgIGlmIChhZnRlckFsbEVycm9ycy5sZW5ndGggPT0gMSkgdGhyb3cgYWZ0ZXJBbGxFcnJvcnNbMF1cbiAgICBpZiAoYWZ0ZXJBbGxFcnJvcnMubGVuZ3RoID4gMSkge1xuICAgICAgdGhyb3cgbmV3IEFnZ3JlZ2F0ZUVycm9yKGFmdGVyQWxsRXJyb3JzLCBcIk11bHRpcGxlIGFjdGl2ZSBhZnRlckFsbCBzY29wZXMgZmFpbGVkXCIsIHtjYXVzZTogYWZ0ZXJBbGxFcnJvcnNbMF19KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGFuYWx5emUgdGVzdHMuXG4gICAqIEBwYXJhbSB7VGVzdHNBcmd1bWVudH0gdGVzdHMgLSBUZXN0cy5cbiAgICogQHJldHVybnMge3thbnlUZXN0c0ZvY3Vzc2VkOiBib29sZWFufX0gLSBXaGV0aGVyIGFueSB0ZXN0cyBpbiB0aGUgdHJlZSBhcmUgZm9jdXNlZC5cbiAgICovXG4gIGFuYWx5emVUZXN0cyh0ZXN0cykge1xuICAgIGxldCBhbnlUZXN0c0ZvY3Vzc2VkRm91bmQgPSBmYWxzZVxuXG4gICAgZm9yIChjb25zdCB0ZXN0RGVzY3JpcHRpb24gaW4gdGVzdHMudGVzdHMpIHtcbiAgICAgIGNvbnN0IHRlc3REYXRhID0gdGVzdHMudGVzdHNbdGVzdERlc2NyaXB0aW9uXVxuICAgICAgY29uc3QgdGVzdEFyZ3MgPSBPYmplY3QuYXNzaWduKHt9LCB0ZXN0RGF0YS5hcmdzKVxuXG4gICAgICB0aGlzLl90ZXN0c0NvdW50KytcblxuICAgICAgaWYgKHRlc3RBcmdzLmZvY3VzKSB7XG4gICAgICAgIGFueVRlc3RzRm9jdXNzZWRGb3VuZCA9IHRydWVcbiAgICAgICAgdGhpcy5hbnlUZXN0c0ZvY3Vzc2VkID0gdHJ1ZVxuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3Qgc3ViRGVzY3JpcHRpb24gaW4gdGVzdHMuc3Vicykge1xuICAgICAgY29uc3Qgc3ViVGVzdCA9IHRlc3RzLnN1YnNbc3ViRGVzY3JpcHRpb25dXG4gICAgICBjb25zdCB7YW55VGVzdHNGb2N1c3NlZH0gPSB0aGlzLmFuYWx5emVUZXN0cyhzdWJUZXN0KVxuXG4gICAgICBpZiAoYW55VGVzdHNGb2N1c3NlZCkge1xuICAgICAgICBhbnlUZXN0c0ZvY3Vzc2VkRm91bmQgPSB0cnVlXG4gICAgICB9XG5cbiAgICAgIHN1YlRlc3QuYW55VGVzdHNGb2N1c3NlZCA9IGFueVRlc3RzRm9jdXNzZWRcbiAgICB9XG5cbiAgICByZXR1cm4ge2FueVRlc3RzRm9jdXNzZWQ6IGFueVRlc3RzRm9jdXNzZWRGb3VuZH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGV2ZXJ5IGFmdGVyLWVhY2ggaG9vayB3aGlsZSBwcmVzZXJ2aW5nIHRoZSBmaXJzdCBmYWlsdXJlLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEhvb2sgZXhlY3V0aW9uIGFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHtBZnRlckJlZm9yZUVhY2hDYWxsYmFja09iamVjdFR5cGVbXX0gYXJncy5hZnRlckVhY2hlcyAtIEhvb2tzIHRvIHJ1bi5cbiAgICogQHBhcmFtIHtUZXN0QXJnc30gYXJncy50ZXN0QXJncyAtIEN1cnJlbnQgdGVzdCBhcmd1bWVudHMuXG4gICAqIEBwYXJhbSB7VGVzdERhdGF9IGFyZ3MudGVzdERhdGEgLSBDdXJyZW50IHRlc3QgZGF0YS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgYWZ0ZXIgZXZlcnkgaG9vayBydW5zLlxuICAgKi9cbiAgYXN5bmMgcnVuQWZ0ZXJFYWNoZXMoe2FmdGVyRWFjaGVzLCB0ZXN0QXJncywgdGVzdERhdGF9KSB7XG4gICAgYXdhaXQgdGhpcy5fYXR0ZW1wdEV4ZWN1dG9yLnJ1bkFmdGVyRWFjaGVzKHthZnRlckVhY2hlcywgdGVzdEFyZ3MsIHRlc3REYXRhfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHJ1biB0ZXN0cy5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtBcnJheTxBZnRlckJlZm9yZUVhY2hDYWxsYmFja09iamVjdFR5cGU+fSBhcmdzLmFmdGVyRWFjaGVzIC0gQWZ0ZXIgZWFjaGVzLlxuICAgKiBAcGFyYW0ge0FycmF5PEFmdGVyQmVmb3JlRWFjaENhbGxiYWNrT2JqZWN0VHlwZT59IGFyZ3MuYmVmb3JlRWFjaGVzIC0gQmVmb3JlIGVhY2hlcy5cbiAgICogQHBhcmFtIHtUZXN0c0FyZ3VtZW50fSBhcmdzLnRlc3RzIC0gVGVzdHMuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGFyZ3MuZGVzY3JpcHRpb25zIC0gRGVzY3JpcHRpb25zLlxuICAgKiBAcGFyYW0ge251bWJlcn0gYXJncy5pbmRlbnRMZXZlbCAtIEluZGVudCBsZXZlbC5cbiAgICogQHBhcmFtIHtib29sZWFufSBbYXJncy5saW5lTWF0Y2hlZEluU2NvcGVdIC0gV2hldGhlciBsaW5lIG1hdGNoZWQgaW4gc2NvcGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYXJncy5wYXJlbnRQcm9maWxlU2NvcGVJZF0gLSBQYXJlbnQgcHJvZmlsZSBzY29wZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHJ1blRlc3RzKHthZnRlckVhY2hlcywgYmVmb3JlRWFjaGVzLCB0ZXN0cywgZGVzY3JpcHRpb25zLCBpbmRlbnRMZXZlbCwgbGluZU1hdGNoZWRJblNjb3BlID0gZmFsc2UsIHBhcmVudFByb2ZpbGVTY29wZUlkfSkge1xuICAgIGNvbnN0IGVudmlyb25tZW50SGFuZGxlciA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLmdldEVudmlyb25tZW50SGFuZGxlcigpXG5cbiAgICBlbnZpcm9ubWVudEhhbmRsZXIuaW5zdGFsbFNoYXJlZFRyYW5zYWN0aW9uQ29vcmRpbmF0b3JPd25lclN0b3JhZ2UodGhpcy5fc2hhcmVkVHJhbnNhY3Rpb25Db29yZGluYXRvck93bmVyU3RvcmFnZSlcbiAgICBlbnZpcm9ubWVudEhhbmRsZXIuaW5zdGFsbFRlc3REYXRhYmFzZUFjY2Vzc1Njb3BlU3RvcmFnZSh0aGlzLl90ZXN0RGF0YWJhc2VBY2Nlc3NTY29wZVN0b3JhZ2UpXG4gICAgY29uc3QgbGVmdFBhZGRpbmcgPSBcIiBcIi5yZXBlYXQoaW5kZW50TGV2ZWwgKiAyKVxuICAgIGNvbnN0IHNjb3BlT3duZXJGaWxlUGF0aCA9IHRlc3RzLm93bmVyRmlsZVBhdGggPz8gdGVzdHMuZmlsZVBhdGhcbiAgICBjb25zdCBwcm9maWxlU2NvcGVJZCA9IHRoaXMuX3Byb2ZpbGVyPy5zY29wZUlkKHRlc3RzLCB7XG4gICAgICBkZXNjcmlwdGlvbnMsXG4gICAgICBmaWxlUGF0aDogc2NvcGVPd25lckZpbGVQYXRoLFxuICAgICAgbGluZTogdGVzdHMubGluZSxcbiAgICAgIHBhcmVudElkOiBwYXJlbnRQcm9maWxlU2NvcGVJZFxuICAgIH0pXG4gICAgY29uc3Qgb3duQWZ0ZXJFYWNoZXMgPSBbLi4udGhpcy5wcm9maWxlSG9va0VudHJpZXModGVzdHMuYWZ0ZXJFYWNoZXMsIHByb2ZpbGVTY29wZUlkLCBzY29wZU93bmVyRmlsZVBhdGgpXS5yZXZlcnNlKClcbiAgICBjb25zdCBvd25CZWZvcmVFYWNoZXMgPSB0aGlzLnByb2ZpbGVIb29rRW50cmllcyh0ZXN0cy5iZWZvcmVFYWNoZXMsIHByb2ZpbGVTY29wZUlkLCBzY29wZU93bmVyRmlsZVBhdGgpXG4gICAgY29uc3QgbmV3QWZ0ZXJFYWNoZXMgPSBbLi4ub3duQWZ0ZXJFYWNoZXMsIC4uLmFmdGVyRWFjaGVzXVxuICAgIGNvbnN0IG5ld0JlZm9yZUVhY2hlcyA9IFsuLi5iZWZvcmVFYWNoZXMsIC4uLm93bkJlZm9yZUVhY2hlc11cbiAgICBjb25zdCBzY29wZUxpbmVNYXRjaCA9IGxpbmVNYXRjaGVkSW5TY29wZSB8fCB0aGlzLm1hdGNoZXNMaW5lRmlsdGVyKHRlc3RzKVxuICAgIGNvbnN0IHNob3VsZFJ1bkFueVRlc3RzID0gdGhpcy5oYXNSdW5uYWJsZVRlc3RzKHRlc3RzLCBkZXNjcmlwdGlvbnMsIHNjb3BlTGluZU1hdGNoKVxuXG4gICAgaWYgKCFzaG91bGRSdW5BbnlUZXN0cykgcmV0dXJuXG5cbiAgICAvKiogQHR5cGUge0FjdGl2ZUFmdGVyQWxsU2NvcGVFbnRyeX0gKi9cbiAgICBjb25zdCBzY29wZUVudHJ5ID0ge3Rlc3RzLCBhZnRlckFsbHNSdW46IGZhbHNlLCBwcm9maWxlU2NvcGVJZH1cbiAgICB0aGlzLl9hY3RpdmVBZnRlckFsbFNjb3Blcy5wdXNoKHNjb3BlRW50cnkpXG4gICAgLyoqIEB0eXBlIHt1bmtub3duW119ICovXG4gICAgY29uc3Qgc2NvcGVFcnJvcnMgPSBbXVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGJlZm9yZUFsbHMgPSB0aGlzLnByb2ZpbGVIb29rRW50cmllcyh0ZXN0cy5iZWZvcmVBbGxzIHx8IFtdLCBwcm9maWxlU2NvcGVJZCwgc2NvcGVPd25lckZpbGVQYXRoKVxuXG4gICAgICBhd2FpdCB0aGlzLl9zdWl0ZUhvb2tFeGVjdXRvci5ydW5CZWZvcmVBbGxzKHtob29rczogYmVmb3JlQWxsc30pXG5cbiAgICAgIGZvciAoY29uc3QgdGVzdERlc2NyaXB0aW9uIGluIHRlc3RzLnRlc3RzKSB7XG4gICAgICAgIGNvbnN0IHRlc3REYXRhID0gdGVzdHMudGVzdHNbdGVzdERlc2NyaXB0aW9uXVxuICAgICAgICBjb25zdCB0ZXN0QXJncyA9IHRoaXMuX3Rlc3RBcmd1bWVudHMuY29weSh0ZXN0RGF0YSlcbiAgICAgICAgY29uc3QgaW5jbHVkZUJ5TGluZSA9IHNjb3BlTGluZU1hdGNoIHx8IHRoaXMubWF0Y2hlc0xpbmVGaWx0ZXIodGVzdERhdGEpXG5cbiAgICAgICAgaWYgKHRoaXMuX29ubHlGb2N1c3NlZCAmJiAhdGVzdEFyZ3MuZm9jdXMpIGNvbnRpbnVlXG4gICAgICAgIGlmICh0aGlzLnNob3VsZFNraXBUZXN0KHRlc3RBcmdzLCB0ZXN0RGF0YSwgdGVzdERlc2NyaXB0aW9uLCBkZXNjcmlwdGlvbnMsIGluY2x1ZGVCeUxpbmUpKSBjb250aW51ZVxuXG4gICAgICAgIGF3YWl0IHRoaXMuX3Rlc3RBcmd1bWVudHMuaW5qZWN0KHRlc3RBcmdzKVxuXG4gICAgICAgIGNvbnN0IHJldHJ5Q291bnQgPSB0eXBlb2YgdGVzdEFyZ3MucmV0cnkgPT09IFwibnVtYmVyXCIgJiYgTnVtYmVyLmlzRmluaXRlKHRlc3RBcmdzLnJldHJ5KVxuICAgICAgICAgID8gTWF0aC5tYXgoMCwgTWF0aC5mbG9vcih0ZXN0QXJncy5yZXRyeSkpXG4gICAgICAgICAgOiAwXG4gICAgICAgIGNvbnN0IGNvbmZpZ1RpbWVvdXRTZWNvbmRzID0gdHlwZW9mIHRlc3RDb25maWcuZGVmYXVsdFRpbWVvdXRTZWNvbmRzID09PSBcIm51bWJlclwiID8gdGVzdENvbmZpZy5kZWZhdWx0VGltZW91dFNlY29uZHMgOiB1bmRlZmluZWRcbiAgICAgICAgY29uc3QgdGltZW91dFNlY29uZHMgPSB0eXBlb2YgdGVzdEFyZ3MudGltZW91dFNlY29uZHMgPT09IFwibnVtYmVyXCIgPyB0ZXN0QXJncy50aW1lb3V0U2Vjb25kcyA6IGNvbmZpZ1RpbWVvdXRTZWNvbmRzXG4gICAgICAgIGNvbnN0IHVzZVRpbWVvdXQgPSB0eXBlb2YgdGltZW91dFNlY29uZHMgPT09IFwibnVtYmVyXCIgJiYgTnVtYmVyLmlzRmluaXRlKHRpbWVvdXRTZWNvbmRzKSAmJiB0aW1lb3V0U2Vjb25kcyA+IDBcbiAgICAgICAgY29uc3QgdGltZW91dE1zID0gdXNlVGltZW91dCA/IHRpbWVvdXRTZWNvbmRzICogMTAwMCA6IHVuZGVmaW5lZFxuICAgICAgICBsZXQgcmV0cmllc1VzZWQgPSAwXG4gICAgICAgIGxldCBhdHRlbXB0TnVtYmVyID0gMVxuICAgICAgICAvKipcbiAgICAgICAgICogQXR0ZW1wdCBjb25zb2xlIG91dHB1dHMuXG4gICAgICAgICAqIEB0eXBlIHtBdHRlbXB0Q29uc29sZU91dHB1dFtdfSAqL1xuICAgICAgICBjb25zdCBhdHRlbXB0Q29uc29sZU91dHB1dHMgPSBbXVxuXG4gICAgICAgIGNvbnNvbGUubG9nKGAke2xlZnRQYWRkaW5nfWl0ICR7dGVzdERlc2NyaXB0aW9ufWApXG5cbiAgICAgICAgY29uc3QgdGVzdFN0YXJ0TXMgPSBEYXRlLm5vdygpXG5cbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICBjb25zdCBhdHRlbXB0UmVzdWx0ID0gYXdhaXQgdGhpcy5fYXR0ZW1wdEV4ZWN1dG9yLmV4ZWN1dGUoe1xuICAgICAgICAgICAgYWZ0ZXJFYWNoZXM6IG5ld0FmdGVyRWFjaGVzLFxuICAgICAgICAgICAgYXR0ZW1wdE51bWJlcixcbiAgICAgICAgICAgIGJlZm9yZUVhY2hlczogbmV3QmVmb3JlRWFjaGVzLFxuICAgICAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICAgICAgdGVzdEFyZ3MsXG4gICAgICAgICAgICB0ZXN0RGF0YSxcbiAgICAgICAgICAgIHRlc3REZXNjcmlwdGlvbixcbiAgICAgICAgICAgIHRpbWVvdXRNc1xuICAgICAgICAgIH0pXG5cbiAgICAgICAgICBpZiAoYXR0ZW1wdFJlc3VsdC5jb25zb2xlT3V0cHV0KSB7XG4gICAgICAgICAgICBhdHRlbXB0Q29uc29sZU91dHB1dHMucHVzaCh7YXR0ZW1wdE51bWJlciwgb3V0cHV0OiBhdHRlbXB0UmVzdWx0LmNvbnNvbGVPdXRwdXR9KVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoYXR0ZW1wdFJlc3VsdC5hYm9ydFJlbWFpbmluZ1Rlc3RzKSB0aGlzLl9hYm9ydFJlbWFpbmluZ1Rlc3RzID0gdHJ1ZVxuXG4gICAgICAgICAgY29uc3Qgd2lsbFJldHJ5ID0gYXR0ZW1wdFJlc3VsdC5mYWlsZWQgJiYgIXRoaXMuX2Fib3J0UmVtYWluaW5nVGVzdHMgJiYgcmV0cmllc1VzZWQgPCByZXRyeUNvdW50XG4gICAgICAgICAgaWYgKHdpbGxSZXRyeSkgcmV0cmllc1VzZWQrK1xuXG4gICAgICAgICAgYXdhaXQgdGhpcy5fcnVubmVyUmVwb3J0ZXIucmVwb3J0QXR0ZW1wdCh7XG4gICAgICAgICAgICBhdHRlbXB0Q29uc29sZU91dHB1dHMsXG4gICAgICAgICAgICBhdHRlbXB0TnVtYmVyLFxuICAgICAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICAgICAgZXJyb3I6IGF0dGVtcHRSZXN1bHQuZXJyb3IsXG4gICAgICAgICAgICBmYWlsZWQ6IGF0dGVtcHRSZXN1bHQuZmFpbGVkLFxuICAgICAgICAgICAgbGVmdFBhZGRpbmcsXG4gICAgICAgICAgICByZXRyaWVzVXNlZCxcbiAgICAgICAgICAgIHJldHJ5Q291bnQsXG4gICAgICAgICAgICB0ZXN0QXJncyxcbiAgICAgICAgICAgIHRlc3REYXRhLFxuICAgICAgICAgICAgdGVzdERlc2NyaXB0aW9uLFxuICAgICAgICAgICAgd2lsbFJldHJ5XG4gICAgICAgICAgfSlcbiAgICAgICAgICBhdHRlbXB0TnVtYmVyKytcblxuICAgICAgICAgIGlmICghd2lsbFJldHJ5KSBicmVha1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fdGVzdER1cmF0aW9ucy5wdXNoKHtcbiAgICAgICAgICBmdWxsRGVzY3JpcHRpb246IHRoaXMuYnVpbGRGdWxsRGVzY3JpcHRpb24oZGVzY3JpcHRpb25zLCB0ZXN0RGVzY3JpcHRpb24pLFxuICAgICAgICAgIGZpbGVQYXRoOiB0ZXN0RGF0YS5maWxlUGF0aCA/PyBcIjx1bmtub3duPlwiLFxuICAgICAgICAgIGxpbmU6IHRlc3REYXRhLmxpbmUgPz8gMCxcbiAgICAgICAgICBkdXJhdGlvbk1zOiBEYXRlLm5vdygpIC0gdGVzdFN0YXJ0TXNcbiAgICAgICAgfSlcblxuICAgICAgICBpZiAodGhpcy5fYWJvcnRSZW1haW5pbmdUZXN0cykgYnJlYWtcbiAgICAgIH1cblxuICAgICAgZm9yIChjb25zdCBzdWJEZXNjcmlwdGlvbiBpbiB0ZXN0cy5zdWJzKSB7XG4gICAgICAgIGlmICh0aGlzLl9hYm9ydFJlbWFpbmluZ1Rlc3RzKSBicmVha1xuXG4gICAgICAgIGNvbnN0IHN1YlRlc3QgPSB0ZXN0cy5zdWJzW3N1YkRlc2NyaXB0aW9uXVxuICAgICAgICBjb25zdCBuZXdEZWNyaXB0aW9ucyA9IGRlc2NyaXB0aW9ucy5jb25jYXQoW3N1YkRlc2NyaXB0aW9uXSlcbiAgICAgICAgY29uc3QgY2hpbGRTY29wZUxpbmVNYXRjaCA9IHNjb3BlTGluZU1hdGNoIHx8IHRoaXMubWF0Y2hlc0xpbmVGaWx0ZXIoc3ViVGVzdClcblxuICAgICAgICBpZiAoIXRoaXMuX29ubHlGb2N1c3NlZCB8fCBzdWJUZXN0LmFueVRlc3RzRm9jdXNzZWQpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgJHtsZWZ0UGFkZGluZ30ke3N1YkRlc2NyaXB0aW9ufWApXG4gICAgICAgICAgYXdhaXQgdGhpcy5ydW5UZXN0cyh7XG4gICAgICAgICAgICBhZnRlckVhY2hlczogbmV3QWZ0ZXJFYWNoZXMsXG4gICAgICAgICAgICBiZWZvcmVFYWNoZXM6IG5ld0JlZm9yZUVhY2hlcyxcbiAgICAgICAgICAgIHRlc3RzOiBzdWJUZXN0LFxuICAgICAgICAgICAgZGVzY3JpcHRpb25zOiBuZXdEZWNyaXB0aW9ucyxcbiAgICAgICAgICAgIGluZGVudExldmVsOiBpbmRlbnRMZXZlbCArIDEsXG4gICAgICAgICAgICBsaW5lTWF0Y2hlZEluU2NvcGU6IGNoaWxkU2NvcGVMaW5lTWF0Y2gsXG4gICAgICAgICAgICBwYXJlbnRQcm9maWxlU2NvcGVJZDogcHJvZmlsZVNjb3BlSWRcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHNjb3BlRXJyb3JzLnB1c2goZXJyb3IpXG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMucnVuQWZ0ZXJBbGxzRm9yU2NvcGUoc2NvcGVFbnRyeSlcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgc2NvcGVFcnJvcnMucHVzaChlcnJvcilcbiAgICB9XG4gICAgY29uc3Qgc2NvcGVJbmRleCA9IHRoaXMuX2FjdGl2ZUFmdGVyQWxsU2NvcGVzLmluZGV4T2Yoc2NvcGVFbnRyeSlcblxuICAgIGlmIChzY29wZUluZGV4ID49IDApIHtcbiAgICAgIHRoaXMuX2FjdGl2ZUFmdGVyQWxsU2NvcGVzLnNwbGljZShzY29wZUluZGV4LCAxKVxuICAgIH1cblxuICAgIGlmIChzY29wZUVycm9ycy5sZW5ndGggPiAwICYmIHRoaXMuX2Fib3J0UmVtYWluaW5nVGVzdHMpIHtcbiAgICAgIGNvbnN0IGVycm9yID0gc2NvcGVFcnJvcnMubGVuZ3RoID09IDFcbiAgICAgICAgPyBzY29wZUVycm9yc1swXVxuICAgICAgICA6IG5ldyBBZ2dyZWdhdGVFcnJvcihzY29wZUVycm9ycywgXCJUZXN0IHNjb3BlIGFuZCBhZnRlckFsbCBjbGVhbnVwIGZhaWxlZFwiLCB7Y2F1c2U6IHNjb3BlRXJyb3JzWzBdfSlcblxuICAgICAgdGhpcy5yZWNvcmRUaW1lb3V0Q2xlYW51cEZhaWx1cmUoZXJyb3IsIFwiYWZ0ZXJBbGxcIilcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBpZiAoc2NvcGVFcnJvcnMubGVuZ3RoID09IDEpIHRocm93IHNjb3BlRXJyb3JzWzBdXG4gICAgaWYgKHNjb3BlRXJyb3JzLmxlbmd0aCA+IDEpIHRocm93IG5ldyBBZ2dyZWdhdGVFcnJvcihzY29wZUVycm9ycywgXCJUZXN0IHNjb3BlIGFuZCBhZnRlckFsbCBjbGVhbnVwIGZhaWxlZFwiLCB7Y2F1c2U6IHNjb3BlRXJyb3JzWzBdfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHJ1biBhZnRlciBhbGxzIGZvciBzY29wZS5cbiAgICogQHBhcmFtIHtBY3RpdmVBZnRlckFsbFNjb3BlRW50cnl9IHNjb3BlRW50cnkgLSBTY29wZSBlbnRyeS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBzY29wZSBjbGVhbnVwIGZpbmlzaGVzLlxuICAgKi9cbiAgYXN5bmMgcnVuQWZ0ZXJBbGxzRm9yU2NvcGUoc2NvcGVFbnRyeSkge1xuICAgIGlmIChzY29wZUVudHJ5LmFmdGVyQWxsc1J1bikgcmV0dXJuXG5cbiAgICBzY29wZUVudHJ5LmFmdGVyQWxsc1J1biA9IHRydWVcblxuICAgIGNvbnN0IHNjb3BlT3duZXJGaWxlUGF0aCA9IHNjb3BlRW50cnkudGVzdHMub3duZXJGaWxlUGF0aCA/PyBzY29wZUVudHJ5LnRlc3RzLmZpbGVQYXRoXG4gICAgY29uc3QgYWZ0ZXJBbGxzID0gdGhpcy5wcm9maWxlSG9va0VudHJpZXMoXG4gICAgICBzY29wZUVudHJ5LnRlc3RzLmFmdGVyQWxscyB8fCBbXSxcbiAgICAgIHNjb3BlRW50cnkucHJvZmlsZVNjb3BlSWQsXG4gICAgICBzY29wZU93bmVyRmlsZVBhdGhcbiAgICApXG5cbiAgICBhd2FpdCB0aGlzLl9zdWl0ZUhvb2tFeGVjdXRvci5ydW5BZnRlckFsbHMoe2hvb2tzOiBhZnRlckFsbHN9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZW1pdCBldmVudC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSAtIEV2ZW50IG5hbWUuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBwYXlsb2FkIC0gRXZlbnQgcGF5bG9hZC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBhbGwgbGlzdGVuZXJzIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgZW1pdEV2ZW50KGV2ZW50TmFtZSwgcGF5bG9hZCkge1xuICAgIGF3YWl0IHRoaXMuX3J1bm5lclJlcG9ydGVyLmVtaXRFdmVudChldmVudE5hbWUsIHBheWxvYWQpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBwcmludCByZXJ1biBjb21tYW5kLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBhcmdzLmRlc2NyaXB0aW9ucyAtIERlc2NyaXB0aW9uIHN0YWNrLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy50ZXN0RGVzY3JpcHRpb24gLSBUZXN0IGRlc2NyaXB0aW9uLlxuICAgKiBAcGFyYW0ge1Rlc3REYXRhfSBhcmdzLnRlc3REYXRhIC0gVGVzdCBkYXRhLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5sZWZ0UGFkZGluZyAtIExlZnQgcGFkZGluZy5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgcHJpbnRSZXJ1bkNvbW1hbmQoe2Rlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uLCB0ZXN0RGF0YSwgbGVmdFBhZGRpbmd9KSB7XG4gICAgY29uc3QgcmVydW4gPSB0aGlzLmJ1aWxkUmVydW5Db21tYW5kKHtkZXNjcmlwdGlvbnMsIHRlc3REZXNjcmlwdGlvbiwgdGVzdERhdGF9KVxuXG4gICAgaWYgKHJlcnVuKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGAke2xlZnRQYWRkaW5nfSAgUmUtcnVuOiAke3JlcnVufWApXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYnVpbGQgcmVydW4gY29tbWFuZC5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gYXJncy5kZXNjcmlwdGlvbnMgLSBEZXNjcmlwdGlvbiBzdGFjay5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MudGVzdERlc2NyaXB0aW9uIC0gVGVzdCBkZXNjcmlwdGlvbi5cbiAgICogQHBhcmFtIHtUZXN0RGF0YX0gYXJncy50ZXN0RGF0YSAtIFRlc3QgZGF0YS5cbiAgICogQHJldHVybnMge3N0cmluZyB8IHVuZGVmaW5lZH0gLSBSZXJ1biBjb21tYW5kLlxuICAgKi9cbiAgYnVpbGRSZXJ1bkNvbW1hbmQoe2Rlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uLCB0ZXN0RGF0YX0pIHtcbiAgICBjb25zdCBiYXNlQ29tbWFuZCA9IFwibnB4IHZlbG9jaW91cyB0ZXN0XCJcbiAgICBjb25zdCBmaWxlUGF0aCA9IHRlc3REYXRhLmZpbGVQYXRoXG4gICAgY29uc3QgbGluZSA9IHRlc3REYXRhLmxpbmVcblxuICAgIGlmIChmaWxlUGF0aCAmJiBsaW5lKSB7XG4gICAgICBjb25zdCByZWxhdGl2ZVBhdGggPSBwYXRoLnJlbGF0aXZlKHByb2Nlc3MuY3dkKCksIGZpbGVQYXRoKVxuICAgICAgcmV0dXJuIGAke2Jhc2VDb21tYW5kfSAke3JlbGF0aXZlUGF0aH06JHtsaW5lfWBcbiAgICB9XG5cbiAgICBjb25zdCBmdWxsRGVzY3JpcHRpb24gPSB0aGlzLmJ1aWxkRnVsbERlc2NyaXB0aW9uKGRlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uKVxuXG4gICAgaWYgKGZ1bGxEZXNjcmlwdGlvbikge1xuICAgICAgcmV0dXJuIGAke2Jhc2VDb21tYW5kfSAtLWV4YW1wbGUgJHtKU09OLnN0cmluZ2lmeShmdWxsRGVzY3JpcHRpb24pfWBcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cblxuICAvKipcbiAgICogUnVucyBidWlsZCBjb25zb2xlIG91dHB1dC5cbiAgICogQHBhcmFtIHtBdHRlbXB0Q29uc29sZU91dHB1dFtdfSBhdHRlbXB0Q29uc29sZU91dHB1dHMgLSBBdHRlbXB0IG91dHB1dCBlbnRyaWVzLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIENvbWJpbmVkIGNvbnNvbGUgb3V0cHV0LlxuICAgKi9cbiAgYnVpbGRDb25zb2xlT3V0cHV0KGF0dGVtcHRDb25zb2xlT3V0cHV0cykge1xuICAgIGlmIChhdHRlbXB0Q29uc29sZU91dHB1dHMubGVuZ3RoID09PSAwKSByZXR1cm4gXCJcIlxuICAgIGlmIChhdHRlbXB0Q29uc29sZU91dHB1dHMubGVuZ3RoID09PSAxKSByZXR1cm4gYXR0ZW1wdENvbnNvbGVPdXRwdXRzWzBdLm91dHB1dFxuXG4gICAgcmV0dXJuIGF0dGVtcHRDb25zb2xlT3V0cHV0cy5tYXAoKGF0dGVtcHRDb25zb2xlT3V0cHV0KSA9PiB7XG4gICAgICByZXR1cm4gYC0tLSBBdHRlbXB0ICR7YXR0ZW1wdENvbnNvbGVPdXRwdXQuYXR0ZW1wdE51bWJlcn0gLS0tXFxuJHthdHRlbXB0Q29uc29sZU91dHB1dC5vdXRwdXR9YFxuICAgIH0pLmpvaW4oXCJcXG5cIilcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCBmYWlsZWQgY29uc29sZSBvdXRwdXQgbWF4IGxpbmVzLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIE1heGltdW0gZmFpbGVkIGNvbnNvbGUgbGluZXMuXG4gICAqL1xuICBnZXRGYWlsZWRDb25zb2xlT3V0cHV0TWF4TGluZXMoKSB7XG4gICAgY29uc3QgbWF4TGluZXMgPSB0ZXN0Q29uZmlnLmZhaWxlZENvbnNvbGVPdXRwdXRNYXhMaW5lc1xuXG4gICAgaWYgKHR5cGVvZiBtYXhMaW5lcyAhPT0gXCJudW1iZXJcIiB8fCAhTnVtYmVyLmlzRmluaXRlKG1heExpbmVzKSkgcmV0dXJuIDIwMFxuXG4gICAgcmV0dXJuIE1hdGgubWF4KDAsIE1hdGguZmxvb3IobWF4TGluZXMpKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgdHJ1bmNhdGUgZmFpbGVkIGNvbnNvbGUgb3V0cHV0IGxpbmVzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY29uc29sZU91dHB1dCAtIENvbnNvbGUgb3V0cHV0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nW119IC0gTGluZXMgZm9yIGlubGluZSBvdXRwdXQuXG4gICAqL1xuICB0cnVuY2F0ZUZhaWxlZENvbnNvbGVPdXRwdXRMaW5lcyhjb25zb2xlT3V0cHV0KSB7XG4gICAgY29uc3QgbGluZXMgPSBjb25zb2xlT3V0cHV0LnNwbGl0KFwiXFxuXCIpXG4gICAgY29uc3QgbWF4TGluZXMgPSB0aGlzLmdldEZhaWxlZENvbnNvbGVPdXRwdXRNYXhMaW5lcygpXG5cbiAgICBpZiAobWF4TGluZXMgPT09IDApIHJldHVybiBbXVxuICAgIGlmIChsaW5lcy5sZW5ndGggPD0gbWF4TGluZXMpIHJldHVybiBsaW5lc1xuXG4gICAgY29uc3Qgb21pdHRlZExpbmVzID0gbGluZXMubGVuZ3RoIC0gbWF4TGluZXNcbiAgICBjb25zdCBwbHVyYWwgPSBvbWl0dGVkTGluZXMgPT09IDEgPyBcIlwiIDogXCJzXCJcblxuICAgIHJldHVybiBbXG4gICAgICBgLi4uICR7b21pdHRlZExpbmVzfSBjb25zb2xlIG91dHB1dCBsaW5lJHtwbHVyYWx9IG9taXR0ZWQgLi4uYCxcbiAgICAgIC4uLmxpbmVzLnNsaWNlKC1tYXhMaW5lcylcbiAgICBdXG4gIH1cblxuICAvKipcbiAgICogUnVucyBwcmludCBmYWlsZWQgY29uc29sZSBvdXRwdXQuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmNvbnNvbGVPdXRwdXQgLSBDb25zb2xlIG91dHB1dC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MubGVmdFBhZGRpbmcgLSBMZWZ0IHBhZGRpbmcuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHByaW50RmFpbGVkQ29uc29sZU91dHB1dCh7Y29uc29sZU91dHB1dCwgbGVmdFBhZGRpbmd9KSB7XG4gICAgaWYgKHRlc3RDb25maWcuY29uc29sZU91dHB1dCAhPT0gXCJmYWlsdXJlXCIpIHJldHVyblxuICAgIGlmICghY29uc29sZU91dHB1dCkgcmV0dXJuXG5cbiAgICBjb25zdCBsaW5lcyA9IHRoaXMudHJ1bmNhdGVGYWlsZWRDb25zb2xlT3V0cHV0TGluZXMoY29uc29sZU91dHB1dClcblxuICAgIGlmIChsaW5lcy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gICAgY29uc29sZS5lcnJvcihwaWNvY29sb3JzLnJlZChgJHtsZWZ0UGFkZGluZ30gIENvbnNvbGUgb3V0cHV0OmApKVxuXG4gICAgZm9yIChjb25zdCBsaW5lIG9mIGxpbmVzKSB7XG4gICAgICBjb25zb2xlLmVycm9yKHBpY29jb2xvcnMucmVkKGAke2xlZnRQYWRkaW5nfSAgICAke2xpbmV9YCkpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgc3RhcnQgY29uc29sZSBjYXB0dXJlLlxuICAgKiBAcGFyYW0ge29iamVjdH0gW2FyZ3NdIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2FyZ3MucGFzc3Rocm91Z2hdIC0gV2hldGhlciB0byBwYXNzIHRocm91Z2ggdG8gdGhlIG9yaWdpbmFsIGNvbnNvbGUuXG4gICAqIEByZXR1cm5zIHsoKSA9PiBzdHJpbmd9IC0gU3RvcHMgdGhlIGNhcHR1cmUgYW5kIHJldHVybnMgY2FwdHVyZWQgdGV4dC5cbiAgICovXG4gIHN0YXJ0Q29uc29sZUNhcHR1cmUoe3Bhc3N0aHJvdWdoID0gZmFsc2V9ID0ge30pIHtcbiAgICAvKipcbiAgICAgKiBMaW5lcy5cbiAgICAgKiBAdHlwZSB7c3RyaW5nW119ICovXG4gICAgY29uc3QgbGluZXMgPSBbXVxuICAgIC8qKlxuICAgICAqIENvbnNvbGUgb2JqZWN0LlxuICAgICAqIEB0eXBlIHtSZWNvcmQ8Q29uc29sZU1ldGhvZE5hbWUsICguLi5hcmdzOiBBcnJheTxSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj4pID0+IHZvaWQ+fSAqL1xuICAgIGNvbnN0IGNvbnNvbGVPYmplY3QgPSAvKiogQHR5cGUge1JlY29yZDxDb25zb2xlTWV0aG9kTmFtZSwgKC4uLmFyZ3M6IEFycmF5PFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+PikgPT4gdm9pZD59ICovIChjb25zb2xlKVxuICAgIC8qKlxuICAgICAqIE9yaWdpbmFsIGNvbnNvbGUgbWV0aG9kcyBjYXB0dXJlZCBhcyBkaXJlY3QgcmVmZXJlbmNlcyBzbyBzdG9wcGluZyByZXN0b3Jlc1xuICAgICAqIHRoZSBleGFjdCBtZXRob2QgdGhhdCB3YXMgaW5zdGFsbGVkIGF0IGNhcHR1cmUgc3RhcnQuXG4gICAgICogQHR5cGUge1JlY29yZDxDb25zb2xlTWV0aG9kTmFtZSwgKC4uLmFyZ3M6IEFycmF5PFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+PikgPT4gdm9pZD59ICovXG4gICAgY29uc3Qgb3JpZ2luYWxDb25zb2xlTWV0aG9kcyA9IHtcbiAgICAgIGRlYnVnOiBjb25zb2xlT2JqZWN0LmRlYnVnLFxuICAgICAgZXJyb3I6IGNvbnNvbGVPYmplY3QuZXJyb3IsXG4gICAgICBpbmZvOiBjb25zb2xlT2JqZWN0LmluZm8sXG4gICAgICBsb2c6IGNvbnNvbGVPYmplY3QubG9nLFxuICAgICAgd2FybjogY29uc29sZU9iamVjdC53YXJuXG4gICAgfVxuICAgIGxldCBzdG9wcGVkID0gZmFsc2VcbiAgICBsZXQgb3V0cHV0VGV4dCA9IFwiXCJcblxuICAgIGZvciAoY29uc3QgbWV0aG9kTmFtZSBvZiBDQVBUVVJFRF9DT05TT0xFX01FVEhPRFMpIHtcbiAgICAgIGNvbnNvbGVPYmplY3RbbWV0aG9kTmFtZV0gPSAoLi4uYXJncykgPT4ge1xuICAgICAgICBsaW5lcy5wdXNoKGBbJHtuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCl9XSBbJHttZXRob2ROYW1lfV0gJHtmb3JtYXQoLi4uYXJncyl9YClcblxuICAgICAgICBpZiAocGFzc3Rocm91Z2gpIHtcbiAgICAgICAgICBvcmlnaW5hbENvbnNvbGVNZXRob2RzW21ldGhvZE5hbWVdLmFwcGx5KGNvbnNvbGVPYmplY3QsIGFyZ3MpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgaWYgKCFzdG9wcGVkKSB7XG4gICAgICAgIHN0b3BwZWQgPSB0cnVlXG5cbiAgICAgICAgZm9yIChjb25zdCBtZXRob2ROYW1lIG9mIENBUFRVUkVEX0NPTlNPTEVfTUVUSE9EUykge1xuICAgICAgICAgIGNvbnNvbGVPYmplY3RbbWV0aG9kTmFtZV0gPSBvcmlnaW5hbENvbnNvbGVNZXRob2RzW21ldGhvZE5hbWVdXG4gICAgICAgIH1cblxuICAgICAgICBvdXRwdXRUZXh0ID0gbGluZXMuam9pbihcIlxcblwiKVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gb3V0cHV0VGV4dFxuICAgIH1cbiAgfVxufVxuIl19
|
|
1722
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1ydW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGVzdGluZy90ZXN0LXJ1bm5lci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxFQUFFLE1BQU0sa0JBQWtCLENBQUE7QUFDakMsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBQ3ZCLE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLGtCQUFrQixDQUFBO0FBQ2xELE9BQU8sRUFBQyxpQkFBaUIsRUFBRSxrQkFBa0IsRUFBQyxNQUFNLG9CQUFvQixDQUFBO0FBQ3hFLE9BQU8sRUFBQyxVQUFVLElBQUksaUJBQWlCLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQTtBQUN6RSxPQUFPLFdBQVcsTUFBTSwwQkFBMEIsQ0FBQTtBQUNsRCxPQUFPLGFBQWEsTUFBTSxxQkFBcUIsQ0FBQTtBQUMvQyxPQUFPLFVBQVUsTUFBTSxZQUFZLENBQUE7QUFDbkMsT0FBTyxhQUFhLE1BQU0sNkJBQTZCLENBQUE7QUFDdkQsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLFdBQVcsQ0FBQTtBQUNwQyxPQUFPLEVBQUMsYUFBYSxFQUFFLGFBQWEsRUFBQyxNQUFNLEtBQUssQ0FBQTtBQUNoRCxPQUFPLHVCQUF1QixNQUFNLGdDQUFnQyxDQUFBO0FBQ3BFLE9BQU8sRUFBRSw2QkFBNkIsRUFBRSxNQUFNLHNDQUFzQyxDQUFBO0FBQ3BGLE9BQU8sd0JBQXdCLE1BQU0saUNBQWlDLENBQUE7QUFDdEUsT0FBTyx1QkFBdUIsRUFBRSxFQUFDLHdCQUF3QixFQUFDLE1BQU0sZ0NBQWdDLENBQUE7QUFDaEcsT0FBTywwQkFBMEIsTUFBTSxvQ0FBb0MsQ0FBQTtBQUMzRSxPQUFPLHNCQUFzQixNQUFNLCtCQUErQixDQUFBO0FBRWxFLDhEQUE4RDtBQUM5RCw2RkFBNkY7QUFDN0YsaUZBQWlGO0FBQ2pGLDhGQUE4RjtBQUM5RiwrR0FBK0c7QUFDL0csOElBQThJO0FB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VyxPQUFPLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQTtRQUM1RCxDQUFDO0lBQ0gsQ0FBQztDQUVGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBmcyBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiXG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiXG5pbXBvcnQge0FzeW5jTG9jYWxTdG9yYWdlfSBmcm9tIFwibm9kZTphc3luY19ob29rc1wiXG5pbXBvcnQge2NyZWF0ZVRlc3RDb250ZXh0LCBkZWZhdWx0VGVzdENvbnRleHR9IGZyb20gXCJAdmVsb2Npb3VzL3Rlc3RpbmdcIlxuaW1wb3J0IHtUZXN0UnVubmVyIGFzIFBhY2thZ2VUZXN0UnVubmVyfSBmcm9tIFwiQHZlbG9jaW91cy90ZXN0aW5nL3J1bm5lclwiXG5pbXBvcnQgQXBwbGljYXRpb24gZnJvbSBcIi4uLy4uL3NyYy9hcHBsaWNhdGlvbi5qc1wiXG5pbXBvcnQgUmVxdWVzdENsaWVudCBmcm9tIFwiLi9yZXF1ZXN0LWNsaWVudC5qc1wiXG5pbXBvcnQgcGljb2NvbG9ycyBmcm9tIFwicGljb2NvbG9yc1wiXG5pbXBvcnQgcmVzdEFyZ3NFcnJvciBmcm9tIFwiLi4vdXRpbHMvcmVzdC1hcmdzLWVycm9yLmpzXCJcbmltcG9ydCB7dGVzdENvbmZpZ30gZnJvbSBcIi4vdGVzdC5qc1wiXG5pbXBvcnQge2ZpbGVVUkxUb1BhdGgsIHBhdGhUb0ZpbGVVUkx9IGZyb20gXCJ1cmxcIlxuaW1wb3J0IFNoYXJlZFRyYW5zYWN0aW9uQnJva2VyIGZyb20gXCIuL3NoYXJlZC10cmFuc2FjdGlvbi1icm9rZXIuanNcIlxuaW1wb3J0IHsgU0hBUkVEX1RSQU5TQUNUSU9OX0JST0tFUl9FTlYgfSBmcm9tIFwiLi9zaGFyZWQtdHJhbnNhY3Rpb24tcHJveHktZHJpdmVyLmpzXCJcbmltcG9ydCBWZWxvY2lvdXNBdHRlbXB0RXhlY3V0b3IgZnJvbSBcIi4vdmVsb2Npb3VzLWF0dGVtcHQtZXhlY3V0b3IuanNcIlxuaW1wb3J0IFZlbG9jaW91c1J1bm5lclJlcG9ydGVyLCB7QWJvcnRSZW1haW5pbmdUZXN0c0Vycm9yfSBmcm9tIFwiLi92ZWxvY2lvdXMtcnVubmVyLXJlcG9ydGVyLmpzXCJcbmltcG9ydCBWZWxvY2lvdXNTdWl0ZUhvb2tFeGVjdXRvciBmcm9tIFwiLi92ZWxvY2lvdXMtc3VpdGUtaG9vay1leGVjdXRvci5qc1wiXG5pbXBvcnQgVmVsb2Npb3VzVGVzdEFyZ3VtZW50cyBmcm9tIFwiLi92ZWxvY2lvdXMtdGVzdC1hcmd1bWVudHMuanNcIlxuXG4vKiogQHR5cGVkZWYge3R5cGVvZiBkZWZhdWx0VGVzdENvbnRleHR9IFBhY2thZ2VUZXN0Q29udGV4dCAqL1xuLyoqIEB0eXBlZGVmIHsodHlwZW9mIGRlZmF1bHRUZXN0Q29udGV4dC5yZWdpc3RyeS5zdWl0ZXMpW251bWJlcl19IFBhY2thZ2VTdWl0ZURlY2xhcmF0aW9uICovXG4vKiogQHR5cGVkZWYge1BhY2thZ2VTdWl0ZURlY2xhcmF0aW9uW1widGVzdHNcIl1bbnVtYmVyXX0gUGFja2FnZVRlc3REZWNsYXJhdGlvbiAqL1xuLyoqIEB0eXBlZGVmIHtQYWNrYWdlU3VpdGVEZWNsYXJhdGlvbltcImhvb2tzXCJdW1wiYmVmb3JlQWxsXCJdW251bWJlcl19IFBhY2thZ2VIb29rRGVjbGFyYXRpb24gKi9cbi8qKiBAdHlwZWRlZiB7UGFja2FnZVN1aXRlRGVjbGFyYXRpb24gfCBQYWNrYWdlVGVzdERlY2xhcmF0aW9uIHwgUGFja2FnZUhvb2tEZWNsYXJhdGlvbn0gUGFja2FnZVJlZ2lzdHJhdGlvbiAqL1xuLyoqIEB0eXBlZGVmIHt7aGFkUmV0cmllczogYm9vbGVhbiwgb3B0aW9uczogUGFja2FnZVRlc3REZWNsYXJhdGlvbltcIm9wdGlvbnNcIl0sIHJldHJpZXM6IG51bWJlciB8IHVuZGVmaW5lZH19IFBhY2thZ2VSZXRyeU9wdGlvblJlc3RvcmF0aW9uICovXG5cbi8qKlxuICogQXR0ZW1wdENvbnNvbGVPdXRwdXQgdHlwZS5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IEF0dGVtcHRDb25zb2xlT3V0cHV0XG4gKiBAcHJvcGVydHkge251bWJlcn0gYXR0ZW1wdE51bWJlciAtIEF0dGVtcHQgbnVtYmVyLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IG91dHB1dCAtIENhcHR1cmVkIGNvbnNvbGUgb3V0cHV0LlxuICovXG4vKipcbiAqIFRlc3RBcmdzIHR5cGUuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBUZXN0QXJnc1xuICogQHByb3BlcnR5IHtBcHBsaWNhdGlvbn0gW2FwcGxpY2F0aW9uXSAtIEFwcGxpY2F0aW9uIGluc3RhbmNlIGZvciBpbnRlZ3JhdGlvbiB0ZXN0cy5cbiAqIEBwcm9wZXJ0eSB7UmVxdWVzdENsaWVudH0gW2NsaWVudF0gLSBIVFRQIGNsaWVudCBmb3IgcmVxdWVzdCB0ZXN0cy5cbiAqIEBwcm9wZXJ0eSB7b2JqZWN0fSBbZGF0YWJhc2VDbGVhbmluZ10gLSBEYXRhYmFzZSBjbGVhbnVwIG9wdGlvbnMgZm9yIHRlc3RzLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbZGF0YWJhc2VDbGVhbmluZy50cmFuc2FjdGlvbl0gLSBVc2UgdHJhbnNhY3Rpb25zIHRvIHJvbGxiYWNrIGJldHdlZW4gdGVzdHMuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtkYXRhYmFzZUNsZWFuaW5nLnRydW5jYXRlXSAtIFRydW5jYXRlIHRhYmxlcyBiZXR3ZWVuIHRlc3RzLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbZGF0YWJhc2VDbGVhbmluZy50cnVuY2F0ZUJlZm9yZV0gLSBUcnVuY2F0ZSB0YWJsZXMgYmVmb3JlIGVhY2ggdGVzdCwgaW4gYWRkaXRpb24gdG8gdGhlIGRlZmF1bHQgY2xlYW51cC5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2ZvY3VzXSAtIFdoZXRoZXIgdGhpcyB0ZXN0IGlzIGZvY3VzZWQuXG4gKiBAcHJvcGVydHkgeygpID0+ICh2b2lkfFByb21pc2U8dm9pZD4pfSBbZnVuY3Rpb25dIC0gVGVzdCBjYWxsYmFjayBmdW5jdGlvbi5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbcmV0cnldIC0gTnVtYmVyIG9mIHJldHJpZXMgd2hlbiBhIHRlc3QgZmFpbHMuXG4gKiBAcHJvcGVydHkge3N0cmluZ1tdIHwgc3RyaW5nfSBbdGFnc10gLSBUYWdzIGZvciBmaWx0ZXJpbmcuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3RpbWVvdXRTZWNvbmRzXSAtIFRpbWVvdXQgaW4gc2Vjb25kcyBmb3IgdGhlIHRlc3QuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW3R5cGVdIC0gVGVzdCB0eXBlIGlkZW50aWZpZXIuXG4gKiBAcHJvcGVydHkgeyhhcmdzOiB7ZGF0YWJhc2VJZGVudGlmaWVyOiBzdHJpbmcsIHRlbmFudDogb2JqZWN0fSkgPT4gUHJvbWlzZTx2b2lkPn0gW3JlZ2lzdGVyVHJhbnNhY3Rpb25hbFRlbmFudF0gLSBSZWdpc3RlcnMgb25lIHJlc29sdmVkIHRlbmFudCBkYXRhYmFzZSB0cmFuc2FjdGlvbiBmb3IgdGhpcyBhdHRlbXB0LlxuICovXG4vKipcbiAqIEJyb3dzZXJEdW1teUNvbm5lY3Rpb25SZWdpc3RyYXRpb24gdHlwZS5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IEJyb3dzZXJEdW1teUNvbm5lY3Rpb25SZWdpc3RyYXRpb25cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZGF0YWJhc2UvZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGRiIC0gQXR0ZW1wdC1vd25lZCBjb25uZWN0aW9uLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IGRhdGFiYXNlSWRlbnRpZmllciAtIENvbmZpZ3VyZWQgZGF0YWJhc2UgaWRlbnRpZmllci5cbiAqIEBwcm9wZXJ0eSB7UHJvbWlzZTx2b2lkPn0gW3F1YXJhbnRpbmVQcm9taXNlXSAtIFNoYXJlZCBjb25uZWN0aW9uLWRpc2NhcmQgcHJvbWlzZS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gcXVhcmFudGluZWQgLSBXaGV0aGVyIHRoZSBjb25uZWN0aW9uIGlzIHVuc2FmZSB0byByZXVzZS5cbiAqIEBwcm9wZXJ0eSB7UHJvbWlzZTx2b2lkPn0gW3JvbGxiYWNrUHJvbWlzZV0gLSBTaGFyZWQgcm9sbGJhY2sgcHJvbWlzZS5cbiAqIEBwcm9wZXJ0eSB7UHJvbWlzZTx2b2lkPn0gW3N0YXJ0UHJvbWlzZV0gLSBUcmFuc2FjdGlvbiBzdGFydHVwIHByb21pc2Ugd2hlbiB0cmFuc2FjdGlvbiBjbGVhbmluZyBpcyBlbmFibGVkLlxuICovXG4vKipcbiAqIFRlc3REYXRhIHR5cGUuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBUZXN0RGF0YVxuICogQHByb3BlcnR5IHtUZXN0QXJnc30gYXJncyAtIEFyZ3VtZW50cyBwYXNzZWQgdG8gdGhlIHRlc3QuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2ZpbGVQYXRoXSAtIFNvdXJjZSBmaWxlIHBhdGguXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2xpbmVdIC0gU291cmNlIGxpbmUgbnVtYmVyLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtvd25lckZpbGVQYXRoXSAtIERldGVybWluaXN0aWMgaW1wb3J0aW5nIHRlc3QgZmlsZS5cbiAqIEBwcm9wZXJ0eSB7KGFyZzogVGVzdEFyZ3MpID0+ICh2b2lkfFByb21pc2U8dm9pZD4pfSBmdW5jdGlvbiAtIFRlc3QgY2FsbGJhY2sgdG8gZXhlY3V0ZS5cbiAqIEBwcm9wZXJ0eSB7UGFja2FnZVRlc3REZWNsYXJhdGlvbn0gW2RlY2xhcmF0aW9uXSAtIFBhY2thZ2UgZGVjbGFyYXRpb24uXG4gKi9cbi8qKlxuICogRmFpbGVkVGVzdERldGFpbCB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gRmFpbGVkVGVzdERldGFpbFxuICogQHByb3BlcnR5IHtzdHJpbmd9IGZ1bGxEZXNjcmlwdGlvbiAtIEZ1bGwgdGVzdCBkZXNjcmlwdGlvbi5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbZmlsZVBhdGhdIC0gU291cmNlIGZpbGUgcGF0aC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbGluZV0gLSBTb3VyY2UgbGluZSBudW1iZXIuXG4gKiBAcHJvcGVydHkge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSBlcnJvciAtIEZhaWx1cmUgZXJyb3IuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2NvbnNvbGVPdXRwdXRdIC0gQ2FwdHVyZWQgY29uc29sZSBvdXRwdXQgd2hpbGUgdGVzdCByYW4uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2NvbnNvbGVMb2dQYXRoXSAtIFNhdmVkIGNvbnNvbGUgbG9nIHBhdGguXG4gKi9cbi8qKlxuICogRGVmaW5lcyB0aGlzIHR5cGVkZWYuXG4gKiBAdHlwZWRlZiB7KGFyZ3M6IHtjb25maWd1cmF0aW9uOiBpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHQsIHRlc3RBcmdzOiBUZXN0QXJncywgdGVzdERhdGE6IFRlc3REYXRhfSkgPT4gKHZvaWR8UHJvbWlzZTx2b2lkPil9IEFmdGVyQmVmb3JlRWFjaENhbGxiYWNrVHlwZVxuICovXG4vKipcbiAqIEFmdGVyQmVmb3JlRWFjaENhbGxiYWNrT2JqZWN0VHlwZSB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gQWZ0ZXJCZWZvcmVFYWNoQ2FsbGJhY2tPYmplY3RUeXBlXG4gKiBAcHJvcGVydHkge0FmdGVyQmVmb3JlRWFjaENhbGxiYWNrVHlwZX0gY2FsbGJhY2sgLSBIb29rIGNhbGxiYWNrIHRvIGV4ZWN1dGUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2RlY2xhcmF0aW9uSW5kZXhdIC0gSG9vayBpbmRleCB3aXRoaW4gaXRzIGRlY2xhcmF0aW9uIHNjb3BlLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtkZWNsYXJhdGlvblNjb3BlSWRdIC0gT3BhcXVlIHByb2ZpbGUgc2NvcGUgaWRlbnRpZmllci5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbb3duZXJGaWxlUGF0aF0gLSBEZXRlcm1pbmlzdGljIGltcG9ydGluZyB0ZXN0IGZpbGUuXG4gKi9cbi8qKlxuICogRGVmaW5lcyB0aGlzIHR5cGVkZWYuXG4gKiBAdHlwZWRlZiB7KGFyZ3M6IHtjb25maWd1cmF0aW9uOiBpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9KSA9PiAodm9pZHxQcm9taXNlPHZvaWQ+KX0gQmVmb3JlQWZ0ZXJBbGxDYWxsYmFja1R5cGVcbiAqL1xuLyoqXG4gKiBCZWZvcmVBZnRlckFsbENhbGxiYWNrT2JqZWN0VHlwZSB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gQmVmb3JlQWZ0ZXJBbGxDYWxsYmFja09iamVjdFR5cGVcbiAqIEBwcm9wZXJ0eSB7QmVmb3JlQWZ0ZXJBbGxDYWxsYmFja1R5cGV9IGNhbGxiYWNrIC0gSG9vayBjYWxsYmFjayB0byBleGVjdXRlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtkZWNsYXJhdGlvbkluZGV4XSAtIEhvb2sgaW5kZXggd2l0aGluIGl0cyBkZWNsYXJhdGlvbiBzY29wZS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbZGVjbGFyYXRpb25TY29wZUlkXSAtIE9wYXF1ZSBwcm9maWxlIHNjb3BlIGlkZW50aWZpZXIuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW293bmVyRmlsZVBhdGhdIC0gRGV0ZXJtaW5pc3RpYyBpbXBvcnRpbmcgdGVzdCBmaWxlLlxuICovXG4vKipcbiAqIFRlc3RzQXJndW1lbnQgdHlwZS5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IFRlc3RzQXJndW1lbnRcbiAqIEBwcm9wZXJ0eSB7VGVzdEFyZ3N9IGFyZ3MgLSBBcmd1bWVudHMgaW5oZXJpdGVkIGJ5IHRlc3RzIGluIHRoaXMgc2NvcGUuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFthbnlUZXN0c0ZvY3Vzc2VkXSAtIFdoZXRoZXIgYW55IHRlc3RzIGluIHRoZSB0cmVlIGFyZSBmb2N1c2VkLlxuICogQHByb3BlcnR5IHtBZnRlckJlZm9yZUVhY2hDYWxsYmFja09iamVjdFR5cGVbXX0gYWZ0ZXJFYWNoZXMgLSBBZnRlci1lYWNoIGhvb2tzIGZvciB0aGlzIHNjb3BlLlxuICogQHByb3BlcnR5IHtCZWZvcmVBZnRlckFsbENhbGxiYWNrT2JqZWN0VHlwZVtdfSBhZnRlckFsbHMgLSBBZnRlci1hbGwgaG9va3MgZm9yIHRoaXMgc2NvcGUuXG4gKiBAcHJvcGVydHkge0JlZm9yZUFmdGVyQWxsQ2FsbGJhY2tPYmplY3RUeXBlW119IGJlZm9yZUFsbHMgLSBCZWZvcmUtYWxsIGhvb2tzIGZvciB0aGlzIHNjb3BlLlxuICogQHByb3BlcnR5IHtBZnRlckJlZm9yZUVhY2hDYWxsYmFja09iamVjdFR5cGVbXX0gYmVmb3JlRWFjaGVzIC0gQmVmb3JlLWVhY2ggaG9va3MgZm9yIHRoaXMgc2NvcGUuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2ZpbGVQYXRoXSAtIFNvdXJjZSBmaWxlIHBhdGguXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2xpbmVdIC0gU291cmNlIGxpbmUgbnVtYmVyLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtvd25lckZpbGVQYXRoXSAtIERldGVybWluaXN0aWMgaW1wb3J0aW5nIHRlc3QgZmlsZS5cbiAqIEBwcm9wZXJ0eSB7UmVjb3JkPHN0cmluZywgVGVzdERhdGE+fSB0ZXN0cyAtIEEgdW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBub2RlLlxuICogQHByb3BlcnR5IHtSZWNvcmQ8c3RyaW5nLCBUZXN0c0FyZ3VtZW50Pn0gc3VicyAtIE9wdGlvbmFsIGNoaWxkIG5vZGVzLiBFYWNoIGl0ZW0gaXMgYW5vdGhlciBgTm9kZWAsIGFsbG93aW5nIHJlY3Vyc2lvbi5cbiAqL1xuLyoqXG4gKiBNYXJrcyB0aGUgZXJyb3IgdGhyb3duIGJ5IHRoZSBhdHRlbXB0IHRpbWVvdXQgc28gdGhlIHJ1bm5lciBjYW4gZGlzdGluZ3Vpc2hcbiAqIGRldGFjaGVkIGxpZmVjeWNsZSBjbGVhbnVwIGZyb20gYW4gb3JkaW5hcnkgdGVzdCBmYWlsdXJlLlxuICogQHR5cGVkZWYge0Vycm9yICYge3ZlbG9jaW91c1Rlc3RUaW1lb3V0PzogdHJ1ZX19IFRlc3RUaW1lb3V0RXJyb3JcbiAqL1xuLyoqXG4gKiBTaGFyZWRUcmFuc2FjdGlvbkJyb2tlclJlZ2lzdHJhdGlvbiB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gU2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJSZWdpc3RyYXRpb25cbiAqIEBwcm9wZXJ0eSB7U2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJ9IGJyb2tlciAtIEF0dGVtcHQgYnJva2VyIGFuZCBjb25uZWN0aW9uIGNvb3JkaW5hdG9yLlxuICogQHByb3BlcnR5IHtib29sZWFufSBlbnZpcm9ubWVudFB1Ymxpc2hlZCAtIFdoZXRoZXIgY2hpbGQtcHJvY2VzcyBjb29yZGluYXRlcyB3ZXJlIHB1Ymxpc2hlZC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nIHwgdW5kZWZpbmVkfSBwcmV2aW91c0Vudmlyb25tZW50IC0gRW52aXJvbm1lbnQgdmFsdWUgdG8gcmVzdG9yZSBhZnRlciBwdWJsaWNhdGlvbi5cbiAqL1xuLyoqXG4gKiBUcmFuc2FjdGlvbmFsVGVuYW50UmVnaXN0cmF0aW9uIHR5cGUuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBUcmFuc2FjdGlvbmFsVGVuYW50UmVnaXN0cmF0aW9uXG4gKiBAcHJvcGVydHkge1Byb21pc2U8e2Nvbm5lY3Rpb246IGltcG9ydChcIi4uL2RhdGFiYXNlL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0IHwgdW5kZWZpbmVkLCBlcnJvcjogRXJyb3IgfCB1bmRlZmluZWR9PiB8IHVuZGVmaW5lZH0gW2NoZWNrb3V0UHJvbWlzZV0gLSBBdHRlbXB0LW93bmVkIHBoeXNpY2FsIGNoZWNrb3V0IG91dGNvbWUuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2RhdGFiYXNlL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0IHwgdW5kZWZpbmVkfSBjb25uZWN0aW9uIC0gQXR0ZW1wdC1vd25lZCBwaHlzaWNhbCBjb25uZWN0aW9uIG9uY2UgY2hlY2tvdXQgcmVzb2x2ZXMuXG4gKiBAcHJvcGVydHkge1Byb21pc2U8dm9pZD4gfCB1bmRlZmluZWR9IFtjbGVhbnVwUHJvbWlzZV0gLSBTaW5nbGUgY2xlYW51cCBvcGVyYXRpb24gc2hhcmVkIGJ5IGVtZXJnZW5jeSBhbmQgZXZlbnR1YWwgbGlmZWN5Y2xlIGNsZWFudXAuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW4gfCB1bmRlZmluZWR9IFtkaXNjYXJkT25DbGVhbnVwXSAtIFdoZXRoZXIgdGltZW91dCBlbWVyZ2VuY3kgY2xlYW51cCBtdXN0IHF1YXJhbnRpbmUgdGhpcyBjb25uZWN0aW9uLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9wb29sL2Jhc2UuanNcIikuZGVmYXVsdH0gcG9vbCAtIE93bmluZyBsb2dpY2FsIHBvb2wuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHJldm9rZWQgLSBXaGV0aGVyIHRoaXMgYXR0ZW1wdCBtYXkgc3RpbGwgcHVibGlzaCB0aGUgcGh5c2ljYWwgcmVnaXN0cmF0aW9uLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHJldXNlS2V5IC0gUmVzb2x2ZWQgcGh5c2ljYWwgY29uZmlndXJhdGlvbiBpZGVudGl0eS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZGF0YWJhc2UvcG9vbC9iYXNlLmpzXCIpLlRlc3RTaGFyZWRDb25uZWN0aW9uUmVnaXN0cmF0aW9uIHwgdW5kZWZpbmVkfSBzaGFyZWRSZWdpc3RyYXRpb24gLSBQaHlzaWNhbC1rZXkgc2hhcmVkIHJlZ2lzdHJhdGlvbiBvbmNlIHB1Ymxpc2hlZC5cbiAqL1xuXG4vKipcbiAqIFJ1bnMgdG8gZmlsZSBzbHVnLlxuICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIC0gVmFsdWUgdG8gc2FuaXRpemUuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSAtIFNsdWctc2FmZSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gdG9GaWxlU2x1Zyh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWVcbiAgICAudG9Mb3dlckNhc2UoKVxuICAgIC5yZXBsYWNlKC9bXmEtejAtOV0rL2csIFwiLVwiKVxuICAgIC5yZXBsYWNlKC9eLSt8LSskL2csIFwiXCIpXG4gICAgLnNsaWNlKDAsIDgwKSB8fCBcImZhaWxlZC10ZXN0XCJcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGVzdFJ1bm5lciB7XG4gIC8qKiBAdHlwZSB7UGFja2FnZVRlc3RDb250ZXh0fSAqL1xuICBfY29udGV4dFxuXG4gIC8qKlxuICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAqIEB0eXBlIHtGYWlsZWRUZXN0RGV0YWlsW119ICovXG4gIF9mYWlsZWRUZXN0RGV0YWlsc1xuXG4gIC8qKlxuICAgKiBSdW5zIGNvbnN0cnVjdG9yLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0gYXJncy5jb25maWd1cmF0aW9uIC0gQ29uZmlndXJhdGlvbiBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtQYWNrYWdlVGVzdENvbnRleHR9IFthcmdzLmNvbnRleHRdIC0gRGVjbGFyYXRpb24gY29udGV4dC5cbiAgICogQHBhcmFtIHtzdHJpbmdbXSB8IHN0cmluZ30gW2FyZ3MuZXhjbHVkZVRhZ3NdIC0gVGFncyB0byBleGNsdWRlLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdIHwgc3RyaW5nfSBbYXJncy5pbmNsdWRlVGFnc10gLSBUYWdzIHRvIGluY2x1ZGUuXG4gICAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gYXJncy50ZXN0RmlsZXMgLSBUZXN0IGZpbGVzLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIG51bWJlcltdPn0gW2FyZ3MubGluZUZpbHRlcnNdIC0gTGluZSBmaWx0ZXJzIGJ5IGZpbGUuXG4gICAqIEBwYXJhbSB7UmVnRXhwW119IFthcmdzLmV4YW1wbGVQYXR0ZXJuc10gLSBFeGFtcGxlIHBhdHRlcm5zLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGVzdC1wcm9maWxlci5qc1wiKS5kZWZhdWx0fSBbYXJncy5wcm9maWxlcl0gLSBPcHQtaW4gcHJvZmlsZXIuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7Y29uZmlndXJhdGlvbiwgY29udGV4dCA9IGRlZmF1bHRUZXN0Q29udGV4dCwgZXhjbHVkZVRhZ3MsIGluY2x1ZGVUYWdzLCB0ZXN0RmlsZXMsIGxpbmVGaWx0ZXJzLCBleGFtcGxlUGF0dGVybnMsIHByb2ZpbGVyLCAuLi5yZXN0QXJnc30pIHtcbiAgICByZXN0QXJnc0Vycm9yKHJlc3RBcmdzKVxuXG4gICAgaWYgKCFjb25maWd1cmF0aW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJjb25maWd1cmF0aW9uIGlzIHJlcXVpcmVkXCIpXG5cbiAgICB0aGlzLl9jb25maWd1cmF0aW9uID0gY29uZmlndXJhdGlvblxuICAgIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0XG4gICAgdGhpcy5fc2hhcmVkVHJhbnNhY3Rpb25Db29yZGluYXRvck93bmVyU3RvcmFnZSA9IG5ldyBBc3luY0xvY2FsU3RvcmFnZSgpXG4gICAgdGhpcy5fdGVzdERhdGFiYXNlQWNjZXNzU2NvcGVTdG9yYWdlID0gbmV3IEFzeW5jTG9jYWxTdG9yYWdlKClcbiAgICB0aGlzLl9leGNsdWRlVGFncyA9IHRoaXMubm9ybWFsaXplVGFncyhleGNsdWRlVGFncylcbiAgICB0aGlzLl9pbmNsdWRlVGFncyA9IHRoaXMubm9ybWFsaXplVGFncyhpbmNsdWRlVGFncylcbiAgICB0aGlzLl90ZXN0RmlsZXMgPSB0ZXN0RmlsZXNcbiAgICB0aGlzLl9saW5lRmlsdGVycyA9IGxpbmVGaWx0ZXJzIHx8IHt9XG4gICAgdGhpcy5fZXhhbXBsZVBhdHRlcm5zID0gZXhhbXBsZVBhdHRlcm5zIHx8IFtdXG4gICAgdGhpcy5fcHJvZmlsZXIgPSBwcm9maWxlclxuICAgIHRoaXMuX2Fib3J0UmVtYWluaW5nVGVzdHMgPSBmYWxzZVxuXG4gICAgdGhpcy5fZmFpbGVkVGVzdHMgPSAwXG4gICAgdGhpcy5fc3VjY2Vzc2Z1bFRlc3RzID0gMFxuICAgIHRoaXMuX3Rlc3RzQ291bnQgPSAwXG4gICAgdGhpcy5fZmFpbGVkVGVzdERldGFpbHMgPSBbXVxuICAgIC8qKiBAdHlwZSB7e2Z1bGxEZXNjcmlwdGlvbjogc3RyaW5nLCBmaWxlUGF0aDogc3RyaW5nLCBsaW5lOiBudW1iZXJ9IHwgbnVsbH0gKi9cbiAgICB0aGlzLl9sYXN0VGVzdENvbnRleHQgPSBudWxsXG4gICAgLyoqIEB0eXBlIHtBcnJheTx7ZnVsbERlc2NyaXB0aW9uOiBzdHJpbmcsIGZpbGVQYXRoOiBzdHJpbmcsIGxpbmU6IG51bWJlciwgZHVyYXRpb25NczogbnVtYmVyfT59ICovXG4gICAgdGhpcy5fdGVzdER1cmF0aW9ucyA9IFtdXG4gICAgLyoqIEB0eXBlIHtXZWFrTWFwPFBhY2thZ2VUZXN0RGVjbGFyYXRpb24sIHt0ZXN0QXJnczogVGVzdEFyZ3MsIHRlc3REYXRhOiBUZXN0RGF0YX0+fSAqL1xuICAgIHRoaXMuX3Rlc3RDb21wYXRpYmlsaXR5ID0gbmV3IFdlYWtNYXAoKVxuICAgIC8qKiBAdHlwZSB7V2Vha1NldDxQYWNrYWdlVGVzdERlY2xhcmF0aW9uPn0gKi9cbiAgICB0aGlzLl9pbmplY3RlZFRlc3RzID0gbmV3IFdlYWtTZXQoKVxuICAgIC8qKiBAdHlwZSB7V2Vha1NldDxQYWNrYWdlVGVzdERlY2xhcmF0aW9uPn0gKi9cbiAgICB0aGlzLl9jb21wbGV0ZWRUZXN0cyA9IG5ldyBXZWFrU2V0KClcbiAgICAvKiogQHR5cGUge1dlYWtNYXA8UGFja2FnZVRlc3REZWNsYXJhdGlvbiwge2Rlc2NyaXB0aW9uczogc3RyaW5nW10sIHRlc3REZXNjcmlwdGlvbjogc3RyaW5nLCBmdWxsRGVzY3JpcHRpb246IHN0cmluZywgb3duZXJGaWxlUGF0aDogc3RyaW5nIHwgdW5kZWZpbmVkLCBzdWl0ZXM6IFBhY2thZ2VTdWl0ZURlY2xhcmF0aW9uW119Pn0gKi9cbiAgICB0aGlzLl90ZXN0TWV0YWRhdGEgPSBuZXcgV2Vha01hcCgpXG4gICAgLyoqIEB0eXBlIHtXZWFrTWFwPFBhY2thZ2VIb29rRGVjbGFyYXRpb24sIHtkZWNsYXJhdGlvbkluZGV4OiBudW1iZXIsIGRlY2xhcmF0aW9uU2NvcGVJZDogc3RyaW5nIHwgdW5kZWZpbmVkLCBvd25lckZpbGVQYXRoOiBzdHJpbmcgfCB1bmRlZmluZWR9Pn0gKi9cbiAgICB0aGlzLl9ob29rTWV0YWRhdGEgPSBuZXcgV2Vha01hcCgpXG4gICAgLyoqIEB0eXBlIHtXZWFrTWFwPFBhY2thZ2VUZXN0RGVjbGFyYXRpb24sIE1hcDxudW1iZXIsIHthYm9ydFJlbWFpbmluZ1Rlc3RzOiBib29sZWFuLCBlcnJvcjogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4sIGZhaWxlZDogYm9vbGVhbn0+Pn0gKi9cbiAgICB0aGlzLl9hdHRlbXB0T3V0Y29tZXMgPSBuZXcgV2Vha01hcCgpXG4gICAgLyoqIEB0eXBlIHtBcnJheTx7c3VpdGU6IFBhY2thZ2VTdWl0ZURlY2xhcmF0aW9uLCBwaGFzZTogXCJiZWZvcmVBbGxcIiB8IFwiYWZ0ZXJBbGxcIiwgZXJyb3I6IFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fT59ICovXG4gICAgdGhpcy5fc3VpdGVIb29rRmFpbHVyZXMgPSBbXVxuICAgIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgUGFja2FnZVRlc3REZWNsYXJhdGlvbltdPn0gKi9cbiAgICB0aGlzLl90ZXN0c0J5RnVsbE5hbWUgPSBuZXcgTWFwKClcbiAgICAvKiogQHR5cGUge1dlYWtNYXA8UGFja2FnZVJlZ2lzdHJhdGlvbiwgc3RyaW5nPn0gKi9cbiAgICB0aGlzLl9kZWNsYXJhdGlvbk93bmVycyA9IG5ldyBXZWFrTWFwKClcbiAgICAvKiogQHR5cGUge1BhY2thZ2VUZXN0UnVubmVyIHwgdW5kZWZpbmVkfSAqL1xuICAgIHRoaXMuX3BhY2thZ2VSdW5uZXIgPSB1bmRlZmluZWRcbiAgICAvKiogQHR5cGUge2ltcG9ydChcIkB2ZWxvY2lvdXMvdGVzdGluZy9ydW5uZXJcIikuVGVzdFJ1blJlc3VsdCB8IHVuZGVmaW5lZH0gKi9cbiAgICB0aGlzLl9wYWNrYWdlUmVzdWx0ID0gdW5kZWZpbmVkXG4gICAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBUZXN0RGF0YT4gfCB1bmRlZmluZWR9ICovXG4gICAgdGhpcy5fbGVnYWN5Rml4dHVyZURhdGFCeUZ1bGxOYW1lID0gdW5kZWZpbmVkXG4gICAgLyoqIEB0eXBlIHt7ZmlsZVBhdGg/OiBzdHJpbmcsIGxpbmU/OiBudW1iZXJ9fSAqL1xuICAgIHRoaXMuX2xlZ2FjeUZpeHR1cmVMb2NhdGlvbiA9IHt9XG4gICAgdGhpcy5fYXR0ZW1wdEV4ZWN1dG9yID0gbmV3IFZlbG9jaW91c0F0dGVtcHRFeGVjdXRvcih7dGVzdFJ1bm5lcjogdGhpc30pXG4gICAgdGhpcy5fcnVubmVyUmVwb3J0ZXIgPSBuZXcgVmVsb2Npb3VzUnVubmVyUmVwb3J0ZXIoe3Rlc3RSdW5uZXI6IHRoaXN9KVxuICAgIHRoaXMuX3N1aXRlSG9va0V4ZWN1dG9yID0gbmV3IFZlbG9jaW91c1N1aXRlSG9va0V4ZWN1dG9yKHt0ZXN0UnVubmVyOiB0aGlzfSlcbiAgICB0aGlzLl90ZXN0QXJndW1lbnRzID0gbmV3IFZlbG9jaW91c1Rlc3RBcmd1bWVudHMoe3Rlc3RSdW5uZXI6IHRoaXN9KVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIHBhY2thZ2UgZGVjbGFyYXRpb24gY29udGV4dC5cbiAgICogQHJldHVybnMge1BhY2thZ2VUZXN0Q29udGV4dH0gLSBQYWNrYWdlIGRlY2xhcmF0aW9uIGNvbnRleHQuXG4gICAqL1xuICBnZXRUZXN0Q29udGV4dCgpIHsgcmV0dXJuIHRoaXMuX2NvbnRleHQgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCBjb25maWd1cmF0aW9uLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSAtIFRoZSBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgZ2V0Q29uZmlndXJhdGlvbigpIHsgcmV0dXJuIHRoaXMuX2NvbmZpZ3VyYXRpb24gfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCB0ZXN0IGZpbGVzLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nW119IC0gVGhlIHRlc3QgZmlsZXMuXG4gICAqL1xuICBnZXRUZXN0RmlsZXMoKSB7IHJldHVybiB0aGlzLl90ZXN0RmlsZXMgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCBsaW5lIGZpbHRlcnMuXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCBudW1iZXJbXT59IC0gTGluZSBmaWx0ZXJzLlxuICAgKi9cbiAgZ2V0TGluZUZpbHRlcnMoKSB7IHJldHVybiB0aGlzLl9saW5lRmlsdGVycyB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IGV4YW1wbGUgcGF0dGVybnMuXG4gICAqIEByZXR1cm5zIHtSZWdFeHBbXX0gLSBFeGFtcGxlIHBhdHRlcm5zLlxuICAgKi9cbiAgZ2V0RXhhbXBsZVBhdHRlcm5zKCkgeyByZXR1cm4gdGhpcy5fZXhhbXBsZVBhdHRlcm5zIH1cblxuICAvKipcbiAgICogUnVucyBhIHByb2ZpbGVyIHNwYW4gb25seSB3aGVuIHByb2ZpbGluZyB3YXMgZXhwbGljaXRseSBlbmFibGVkLlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAcGFyYW0ge29iamVjdH0gbWV0YWRhdGEgLSBTcGFuIG1ldGFkYXRhLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWV0YWRhdGEucGhhc2UgLSBQaGFzZSBuYW1lLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW21ldGFkYXRhLmRlY2xhcmF0aW9uSW5kZXhdIC0gSG9vayBkZWNsYXJhdGlvbiBpbmRleC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFttZXRhZGF0YS5kZWNsYXJhdGlvblNjb3BlSWRdIC0gSG9vayBkZWNsYXJhdGlvbiBzY29wZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFttZXRhZGF0YS5maWxlUGF0aF0gLSBTb3VyY2Ugb3duZXJzaGlwLlxuICAgKiBAcGFyYW0geygpID0+IChUIHwgUHJvbWlzZTxUPil9IGNhbGxiYWNrIC0gVGltZWQgY2FsbGJhY2suXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFQ+fSAtIENhbGxiYWNrIHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIHJ1blByb2ZpbGVTcGFuKG1ldGFkYXRhLCBjYWxsYmFjaykge1xuICAgIGlmICghdGhpcy5fcHJvZmlsZXIpIHJldHVybiBhd2FpdCBjYWxsYmFjaygpXG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5fcHJvZmlsZXIucnVuU3BhbihtZXRhZGF0YSwgY2FsbGJhY2spXG4gIH1cblxuICAvKipcbiAgICogUnVucyBub3JtYWxpemUgdGFncy5cbiAgICogQHBhcmFtIHtzdHJpbmdbXSB8IHN0cmluZyB8IHVuZGVmaW5lZH0gdGFncyAtIFRhZ3MuXG4gICAqIEByZXR1cm5zIHtzdHJpbmdbXX0gLSBOb3JtYWxpemVkIHRhZ3MuXG4gICAqL1xuICBub3JtYWxpemVUYWdzKHRhZ3MpIHtcbiAgICBpZiAoIXRhZ3MpIHJldHVybiBbXVxuXG4gICAgY29uc3QgdmFsdWVzID0gW11cbiAgICBjb25zdCByYXdUYWdzID0gQXJyYXkuaXNBcnJheSh0YWdzKSA/IHRhZ3MgOiBbdGFnc11cblxuICAgIGZvciAoY29uc3QgcmF3VGFnIG9mIHJhd1RhZ3MpIHtcbiAgICAgIGlmIChyYXdUYWcgPT09IHVuZGVmaW5lZCB8fCByYXdUYWcgPT09IG51bGwpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IHBhcnRzID0gU3RyaW5nKHJhd1RhZykuc3BsaXQoXCIsXCIpXG5cbiAgICAgIGZvciAoY29uc3QgcGFydCBvZiBwYXJ0cykge1xuICAgICAgICBjb25zdCB0cmltbWVkID0gcGFydC50cmltKClcblxuICAgICAgICBpZiAodHJpbW1lZCkgdmFsdWVzLnB1c2godHJpbW1lZClcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gQXJyYXkuZnJvbShuZXcgU2V0KHZhbHVlcykpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBoYXMgdGFnLlxuICAgKiBAcGFyYW0ge1Rlc3RBcmdzfSB0ZXN0QXJncyAtIFRlc3QgYXJncy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhZyAtIFRhZyB0byBjaGVjayBmb3IuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgdGFnIGlzIHByZXNlbnQuXG4gICAqL1xuICBoYXNUYWcodGVzdEFyZ3MsIHRhZykge1xuICAgIHJldHVybiB0aGlzLm5vcm1hbGl6ZVRhZ3ModGVzdEFyZ3M/LnRhZ3MpLmluY2x1ZGVzKHRhZylcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGlzIGJyb3dzZXIgdGVzdCBtb2RlLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHJ1bm5pbmcgYnJvd3NlciB0ZXN0cy5cbiAgICovXG4gIGlzQnJvd3NlclRlc3RNb2RlKCkge1xuICAgIHJldHVybiBwcm9jZXNzLmVudi5WRUxPQ0lPVVNfQlJPV1NFUl9URVNUUyA9PT0gXCJ0cnVlXCJcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHJ1biB3aXRoIGR1bW15IGlmIG5lZWRlZC5cbiAgICogQHBhcmFtIHtUZXN0QXJnc30gdGVzdEFyZ3MgLSBUZXN0IGFyZ3MuXG4gICAqIEBwYXJhbSB7KCkgPT4gUHJvbWlzZTx2b2lkPn0gY2FsbGJhY2sgLSBDYWxsYmFjayB0byBydW4uXG4gICAqIEBwYXJhbSB7QnJvd3NlckR1bW15Q29ubmVjdGlvblJlZ2lzdHJhdGlvbltdfSBbYnJvd3NlckR1bW15Q29ubmVjdGlvblJlZ2lzdHJhdGlvbnNdIC0gQXR0ZW1wdC1vd25lZCBicm93c2VyIGNvbm5lY3Rpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgcnVuV2l0aER1bW15SWZOZWVkZWQodGVzdEFyZ3MsIGNhbGxiYWNrLCBicm93c2VyRHVtbXlDb25uZWN0aW9uUmVnaXN0cmF0aW9ucyA9IFtdKSB7XG4gICAgaWYgKCF0aGlzLmhhc1RhZyh0ZXN0QXJncywgXCJkdW1teVwiKSkge1xuICAgICAgYXdhaXQgY2FsbGJhY2soKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNCcm93c2VyVGVzdE1vZGUoKSkge1xuICAgICAgYXdhaXQgdGhpcy5ydW5Ccm93c2VyRHVtbXkodGVzdEFyZ3MsIGNhbGxiYWNrLCBicm93c2VyRHVtbXlDb25uZWN0aW9uUmVnaXN0cmF0aW9ucylcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGF3YWl0IHRoaXMucnVuTm9kZUR1bW15KGNhbGxiYWNrKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcnVuIG5vZGUgZHVtbXkuXG4gICAqIEBwYXJhbSB7KCkgPT4gUHJvbWlzZTx2b2lkPn0gY2FsbGJhY2sgLSBDYWxsYmFjayB0byBydW4uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBydW5Ob2RlRHVtbXkoY2FsbGJhY2spIHtcbiAgICBjb25zdCBkdW1teVBhdGggPSBwcm9jZXNzLmVudi5WRUxPQ0lPVVNfRFVNTVlfUEFUSCB8fCB0aGlzLmRlZmF1bHREdW1teVBhdGgoKVxuICAgIGNvbnN0IGR1bW15SW1wb3J0ID0gYXdhaXQgaW1wb3J0KHBhdGhUb0ZpbGVVUkwoZHVtbXlQYXRoKS5ocmVmKVxuICAgIGNvbnN0IER1bW15ID0gZHVtbXlJbXBvcnQuZGVmYXVsdFxuXG4gICAgaWYgKCFEdW1teT8ucnVuKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYER1bW15IGhlbHBlciBub3QgZm91bmQgYXQgJHtkdW1teVBhdGh9YClcbiAgICB9XG5cbiAgICAvLyBQZXJzaXN0ZW50IHNlcnZlciByZXNvdXJjZXMgbXVzdCBub3QgaW5oZXJpdCBhbiBhdHRlbXB0IHNjb3BlIHRoYXQgd2lsbCBiZSByZXZva2VkLlxuICAgIGF3YWl0IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLmdldEVudmlyb25tZW50SGFuZGxlcigpLnJ1bldpdGhDYXB0dXJlZFRlc3REYXRhYmFzZUFjY2Vzc1Njb3BlKHVuZGVmaW5lZCwgYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgRHVtbXkucnVuKGFzeW5jICgpID0+IHt9KVxuICAgIH0pXG4gICAgdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuYXNzZXJ0RGF0YWJhc2VBY2Nlc3NBbGxvd2VkKClcbiAgICBhd2FpdCBjYWxsYmFjaygpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBkZWZhdWx0IGR1bW15IHBhdGguXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gRGVmYXVsdCBkdW1teSBoZWxwZXIgcGF0aC5cbiAgICovXG4gIGRlZmF1bHREdW1teVBhdGgoKSB7XG4gICAgY29uc3QgY3dkID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCkpXG4gICAgY29uc3Qgbm9ybWFsaXplZCA9IGN3ZC5zcGxpdChwYXRoLnNlcCkuam9pbihcIi9cIilcblxuICAgIGlmIChub3JtYWxpemVkLmVuZHNXaXRoKFwiL3NwZWMvZHVtbXlcIikpIHtcbiAgICAgIHJldHVybiBwYXRoLmpvaW4oY3dkLCBcImluZGV4LmpzXCIpXG4gICAgfVxuXG4gICAgcmV0dXJuIHBhdGguam9pbihjd2QsIFwic3BlYy9kdW1teS9pbmRleC5qc1wiKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcnVuIGJyb3dzZXIgZHVtbXkuXG4gICAqIEBwYXJhbSB7VGVzdEFyZ3N9IHRlc3RBcmdzIC0gVGVzdCBhcmdzLlxuICAgKiBAcGFyYW0geygpID0+IFByb21pc2U8dm9pZD59IGNhbGxiYWNrIC0gQ2FsbGJhY2sgdG8gcnVuLlxuICAgKiBAcGFyYW0ge0Jyb3dzZXJEdW1teUNvbm5lY3Rpb25SZWdpc3RyYXRpb25bXX0gY29ubmVjdGlvblJlZ2lzdHJhdGlvbnMgLSBBdHRlbXB0LW93bmVkIGJyb3dzZXIgY29ubmVjdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBydW5Ccm93c2VyRHVtbXkodGVzdEFyZ3MsIGNhbGxiYWNrLCBjb25uZWN0aW9uUmVnaXN0cmF0aW9ucykge1xuICAgIGNvbnN0IHVzZVRyYW5zYWN0aW9uID0gdGVzdEFyZ3MuZGF0YWJhc2VDbGVhbmluZz8udHJhbnNhY3Rpb24gPT09IHRydWVcbiAgICBjb25zdCB0cnVuY2F0ZSA9IHRlc3RBcmdzLmRhdGFiYXNlQ2xlYW5pbmc/LnRydW5jYXRlXG4gICAgY29uc3Qgc2hvdWxkVHJ1bmNhdGUgPSB0cnVuY2F0ZSA9PT0gdW5kZWZpbmVkID8gIXVzZVRyYW5zYWN0aW9uIDogdHJ1bmNhdGVcblxuICAgIGlmICghdXNlVHJhbnNhY3Rpb24gJiYgIXNob3VsZFRydW5jYXRlKSB7XG4gICAgICBhd2FpdCBjYWxsYmFjaygpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5lbnN1cmVDb25uZWN0aW9ucyh7bmFtZTogXCJUZXN0IHJ1bm5lciBicm93c2VyIGR1bW15XCJ9LCBhc3luYyAoZGJzKSA9PiB7XG4gICAgICBjb25zdCBuZXdSZWdpc3RyYXRpb25zID0gT2JqZWN0LmVudHJpZXMoZGJzKS5tYXAoKFtkYXRhYmFzZUlkZW50aWZpZXIsIGRiXSkgPT4ge1xuICAgICAgICAvKiogQHR5cGUge0Jyb3dzZXJEdW1teUNvbm5lY3Rpb25SZWdpc3RyYXRpb259ICovXG4gICAgICAgIGNvbnN0IHJlZ2lzdHJhdGlvbiA9IHtcbiAgICAgICAgICBkYXRhYmFzZUlkZW50aWZpZXIsXG4gICAgICAgICAgZGIsXG4gICAgICAgICAgcXVhcmFudGluZWQ6IGZhbHNlXG4gICAgICAgIH1cblxuICAgICAgICBjb25uZWN0aW9uUmVnaXN0cmF0aW9ucy5wdXNoKHJlZ2lzdHJhdGlvbilcblxuICAgICAgICByZXR1cm4gcmVnaXN0cmF0aW9uXG4gICAgICB9KVxuXG4gICAgICBpZiAoc2hvdWxkVHJ1bmNhdGUpIHtcbiAgICAgICAgdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuYXNzZXJ0RGF0YWJhc2VBY2Nlc3NBbGxvd2VkKClcbiAgICAgICAgYXdhaXQgdGhpcy50cnVuY2F0ZURhdGFiYXNlcyhkYnMpXG4gICAgICB9XG4gICAgICAvKiogQHR5cGUge3Vua25vd25bXX0gKi9cbiAgICAgIGNvbnN0IGxpZmVjeWNsZUVycm9ycyA9IFtdXG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGlmICh1c2VUcmFuc2FjdGlvbikge1xuICAgICAgICAgIGNvbnN0IHN0YXJ0UHJvbWlzZXMgPSBuZXdSZWdpc3RyYXRpb25zLm1hcCgocmVnaXN0cmF0aW9uKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdGFydFByb21pc2UgPSByZWdpc3RyYXRpb24uZGIuc3RhcnRUcmFuc2FjdGlvbigpXG5cbiAgICAgICAgICAgIHJlZ2lzdHJhdGlvbi5zdGFydFByb21pc2UgPSBzdGFydFByb21pc2VcbiAgICAgICAgICAgIHJldHVybiBzdGFydFByb21pc2VcbiAgICAgICAgICB9KVxuICAgICAgICAgIGNvbnN0IHN0YXJ0UmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChzdGFydFByb21pc2VzKVxuICAgICAgICAgIGNvbnN0IHN0YXJ0RXJyb3JzID0gc3RhcnRSZXN1bHRzXG4gICAgICAgICAgICAuZmlsdGVyKChyZXN1bHQpID0+IHJlc3VsdC5zdGF0dXMgPT09IFwicmVqZWN0ZWRcIilcbiAgICAgICAgICAgIC5tYXAoKHJlc3VsdCkgPT4gcmVzdWx0LnJlYXNvbilcblxuICAgICAgICAgIGlmIChzdGFydEVycm9ycy5sZW5ndGggPT0gMSkgdGhyb3cgc3RhcnRFcnJvcnNbMF1cbiAgICAgICAgICBpZiAoc3RhcnRFcnJvcnMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFnZ3JlZ2F0ZUVycm9yKHN0YXJ0RXJyb3JzLCBcIkJyb3dzZXIgZHVtbXkgdHJhbnNhY3Rpb24gc3RhcnR1cCBmYWlsZWRcIiwge2NhdXNlOiBzdGFydEVycm9yc1swXX0pXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuYXNzZXJ0RGF0YWJhc2VBY2Nlc3NBbGxvd2VkKClcbiAgICAgICAgYXdhaXQgY2FsbGJhY2soKVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbGlmZWN5Y2xlRXJyb3JzLnB1c2goZXJyb3IpXG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMucm9sbGJhY2tCcm93c2VyRHVtbXlUcmFuc2FjdGlvbnMoY29ubmVjdGlvblJlZ2lzdHJhdGlvbnMpXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBBZ2dyZWdhdGVFcnJvcikge1xuICAgICAgICAgIGxpZmVjeWNsZUVycm9ycy5wdXNoKC4uLmVycm9yLmVycm9ycylcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsaWZlY3ljbGVFcnJvcnMucHVzaChlcnJvcilcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0cnkge1xuICAgICAgICBpZiAoc2hvdWxkVHJ1bmNhdGUpIHtcbiAgICAgICAgICB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5hc3NlcnREYXRhYmFzZUFjY2Vzc0FsbG93ZWQoKVxuICAgICAgICAgIGF3YWl0IHRoaXMudHJ1bmNhdGVEYXRhYmFzZXMoZGJzKVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBsaWZlY3ljbGVFcnJvcnMucHVzaChlcnJvcilcbiAgICAgIH1cblxuICAgICAgaWYgKGxpZmVjeWNsZUVycm9ycy5sZW5ndGggPT0gMSkgdGhyb3cgbGlmZWN5Y2xlRXJyb3JzWzBdXG4gICAgICBpZiAobGlmZWN5Y2xlRXJyb3JzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEFnZ3JlZ2F0ZUVycm9yKGxpZmVjeWNsZUVycm9ycywgXCJCcm93c2VyIGR1bW15IGxpZmVjeWNsZSBhbmQgY2xlYW51cCBmYWlsZWRcIiwge2NhdXNlOiBsaWZlY3ljbGVFcnJvcnNbMF19KVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUm9sbHMgYmFjayBldmVyeSBhdHRlbXB0LW93bmVkIGJyb3dzZXIgdHJhbnNhY3Rpb24gZXhhY3RseSBvbmNlLlxuICAgKiBAcGFyYW0ge0Jyb3dzZXJEdW1teUNvbm5lY3Rpb25SZWdpc3RyYXRpb25bXX0gcmVnaXN0cmF0aW9ucyAtIEJyb3dzZXIgY29ubmVjdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIGFmdGVyIGFsbCByb2xsYmFja3Mgc2V0dGxlLlxuICAgKi9cbiAgYXN5bmMgcm9sbGJhY2tCcm93c2VyRHVtbXlUcmFuc2FjdGlvbnMocmVnaXN0cmF0aW9ucykge1xuICAgIGNvbnN0IHJvbGxiYWNrUmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChbLi4ucmVnaXN0cmF0aW9uc10ucmV2ZXJzZSgpLm1hcCgocmVnaXN0cmF0aW9uKSA9PiB7XG4gICAgICBjb25zdCBzdGFydFByb21pc2UgPSByZWdpc3RyYXRpb24uc3RhcnRQcm9taXNlXG5cbiAgICAgIGlmICghc3RhcnRQcm9taXNlKSByZXR1cm5cblxuICAgICAgcmVnaXN0cmF0aW9uLnJvbGxiYWNrUHJvbWlzZSA/Pz0gKGFzeW5jICgpID0+IHtcbiAgICAgICAgaWYgKHJlZ2lzdHJhdGlvbi5xdWFyYW50aW5lZCkgcmV0dXJuXG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCBzdGFydFByb21pc2VcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucXVhcmFudGluZUJyb3dzZXJEdW1teUNvbm5lY3Rpb24ocmVnaXN0cmF0aW9uKVxuICAgICAgICAgIH0gY2F0Y2ggKHF1YXJhbnRpbmVFcnJvcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gcXVhcmFudGluZSBicm93c2VyIGR1bW15IGRhdGFiYXNlIGFmdGVyIHRyYW5zYWN0aW9uIHN0YXJ0dXAgZmFpbGVkOiAke3JlZ2lzdHJhdGlvbi5kYXRhYmFzZUlkZW50aWZpZXJ9YCwge2NhdXNlOiBxdWFyYW50aW5lRXJyb3J9KVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBpZiAocmVnaXN0cmF0aW9uLnF1YXJhbnRpbmVkKSByZXR1cm5cblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHJlZ2lzdHJhdGlvbi5kYi5yb2xsYmFja1RyYW5zYWN0aW9uKClcbiAgICAgICAgfSBjYXRjaCAocm9sbGJhY2tFcnJvcikge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnF1YXJhbnRpbmVCcm93c2VyRHVtbXlDb25uZWN0aW9uKHJlZ2lzdHJhdGlvbilcbiAgICAgICAgICB9IGNhdGNoIChxdWFyYW50aW5lRXJyb3IpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBZ2dyZWdhdGVFcnJvcihcbiAgICAgICAgICAgICAgW3JvbGxiYWNrRXJyb3IsIHF1YXJhbnRpbmVFcnJvcl0sXG4gICAgICAgICAgICAgIGBGYWlsZWQgdG8gcm9sbCBiYWNrIGFuZCBxdWFyYW50aW5lIGJyb3dzZXIgZHVtbXkgZGF0YWJhc2U6ICR7cmVnaXN0cmF0aW9uLmRhdGFiYXNlSWRlbnRpZmllcn1gLFxuICAgICAgICAgICAgICB7Y2F1c2U6IHF1YXJhbnRpbmVFcnJvcn1cbiAgICAgICAgICAgIClcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgcm9sbGJhY2tFcnJvclxuICAgICAgICB9XG4gICAgICB9KSgpXG5cbiAgICAgIHJldHVybiByZWdpc3RyYXRpb24ucm9sbGJhY2tQcm9taXNlXG4gICAgfSkpXG4gICAgY29uc3QgZXJyb3JzID0gcm9sbGJhY2tSZXN1bHRzXG4gICAgICAuZmlsdGVyKChyZXN1bHQpID0+IHJlc3VsdC5zdGF0dXMgPT09IFwicmVqZWN0ZWRcIilcbiAgICAgIC5tYXAoKHJlc3VsdCkgPT4gcmVzdWx0LnJlYXNvbilcblxuICAgIGlmIChlcnJvcnMubGVuZ3RoID09IDEpIHRocm93IGVycm9yc1swXVxuICAgIGlmIChlcnJvcnMubGVuZ3RoID4gMSkgdGhyb3cgbmV3IEFnZ3JlZ2F0ZUVycm9yKGVycm9ycywgXCJCcm93c2VyIGR1bW15IHRyYW5zYWN0aW9uIGNsZWFudXAgZmFpbGVkXCIsIHtjYXVzZTogZXJyb3JzWzBdfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBQZXJtYW5lbnRseSByZW1vdmVzIG9uZSBicm93c2VyIGNvbm5lY3Rpb24gdGhhdCBjYW5ub3QgYmUgc2hhcmVkIHNhZmVseS5cbiAgICogQHBhcmFtIHtCcm93c2VyRHVtbXlDb25uZWN0aW9uUmVnaXN0cmF0aW9ufSByZWdpc3RyYXRpb24gLSBCcm93c2VyIGNvbm5lY3Rpb24gcmVnaXN0cmF0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciB0aGUgY29ubmVjdGlvbiBpcyBkaXNjYXJkZWQuXG4gICAqL1xuICBhc3luYyBxdWFyYW50aW5lQnJvd3NlckR1bW15Q29ubmVjdGlvbihyZWdpc3RyYXRpb24pIHtcbiAgICByZWdpc3RyYXRpb24ucXVhcmFudGluZWQgPSB0cnVlXG4gICAgcmVnaXN0cmF0aW9uLnF1YXJhbnRpbmVQcm9taXNlID8/PSB0aGlzLmRpc2NhcmRCcm93c2VyRHVtbXlDb25uZWN0aW9uKHJlZ2lzdHJhdGlvbi5kYXRhYmFzZUlkZW50aWZpZXIsIHJlZ2lzdHJhdGlvbi5kYilcbiAgICBhd2FpdCByZWdpc3RyYXRpb24ucXVhcmFudGluZVByb21pc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNjYXJkcyBvbmUgYnJvd3NlciBkdW1teSBjb25uZWN0aW9uIHRocm91Z2ggaXRzIG93bmluZyBwb29sLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZGF0YWJhc2VJZGVudGlmaWVyIC0gQ29uZmlndXJlZCBkYXRhYmFzZSBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RhdGFiYXNlL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBkYiAtIFVuc2FmZSBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciBkaXNjYXJkLlxuICAgKi9cbiAgYXN5bmMgZGlzY2FyZEJyb3dzZXJEdW1teUNvbm5lY3Rpb24oZGF0YWJhc2VJZGVudGlmaWVyLCBkYikge1xuICAgIGF3YWl0IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLmdldERhdGFiYXNlUG9vbChkYXRhYmFzZUlkZW50aWZpZXIpLmRpc2NhcmQoZGIpXG4gIH1cblxuICAvKipcbiAgICogUXVhcmFudGluZXMgYWxsIGJyb3dzZXIgY29ubmVjdGlvbnMgY29uY3VycmVudGx5LlxuICAgKiBAcGFyYW0ge0Jyb3dzZXJEdW1teUNvbm5lY3Rpb25SZWdpc3RyYXRpb25bXX0gcmVnaXN0cmF0aW9ucyAtIEJyb3dzZXIgY29ubmVjdGlvbiByZWdpc3RyYXRpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciBldmVyeSBjb25uZWN0aW9uIGlzIGRpc2NhcmRlZC5cbiAgICovXG4gIGFzeW5jIHF1YXJhbnRpbmVCcm93c2VyRHVtbXlDb25uZWN0aW9ucyhyZWdpc3RyYXRpb25zKSB7XG4gICAgY29uc3QgcXVhcmFudGluZVJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQocmVnaXN0cmF0aW9ucy5tYXAoYXN5bmMgKHJlZ2lzdHJhdGlvbikgPT4ge1xuICAgICAgYXdhaXQgdGhpcy5xdWFyYW50aW5lQnJvd3NlckR1bW15Q29ubmVjdGlvbihyZWdpc3RyYXRpb24pXG4gICAgfSkpXG4gICAgY29uc3QgZXJyb3JzID0gcXVhcmFudGluZVJlc3VsdHNcbiAgICAgIC5maWx0ZXIoKHJlc3VsdCkgPT4gcmVzdWx0LnN0YXR1cyA9PT0gXCJyZWplY3RlZFwiKVxuICAgICAgLm1hcCgocmVzdWx0KSA9PiByZXN1bHQucmVhc29uKVxuXG4gICAgaWYgKGVycm9ycy5sZW5ndGggPT0gMSkgdGhyb3cgZXJyb3JzWzBdXG4gICAgaWYgKGVycm9ycy5sZW5ndGggPiAxKSB0aHJvdyBuZXcgQWdncmVnYXRlRXJyb3IoZXJyb3JzLCBcIkJyb3dzZXIgZHVtbXkgY29ubmVjdGlvbiBxdWFyYW50aW5lIGZhaWxlZFwiLCB7Y2F1c2U6IGVycm9yc1swXX0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyB0cnVuY2F0ZSBkYXRhYmFzZXMuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgaW1wb3J0KFwiLi4vZGF0YWJhc2UvZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+fSBkYnMgLSBEYXRhYmFzZSBjb25uZWN0aW9ucy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHRydW5jYXRlRGF0YWJhc2VzKGRicykge1xuICAgIGZvciAoY29uc3QgaWRlbnRpZmllciBvZiBPYmplY3Qua2V5cyhkYnMpKSB7XG4gICAgICBhd2FpdCBkYnNbaWRlbnRpZmllcl0udHJ1bmNhdGVBbGxUYWJsZXMoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCBleGNsdWRlIHRhZyBzZXQuXG4gICAqIEByZXR1cm5zIHtTZXQ8c3RyaW5nPn0gLSBFeGNsdWRlIHRhZyBzZXQuXG4gICAqL1xuICBnZXRFeGNsdWRlVGFnU2V0KCkge1xuICAgIC8qKlxuICAgICAqIENvbmZpZyB0YWdzLlxuICAgICAqIEB0eXBlIHtzdHJpbmdbXX0gKi9cbiAgICBjb25zdCBjb25maWdUYWdzID0gQXJyYXkuaXNBcnJheSh0ZXN0Q29uZmlnLmV4Y2x1ZGVUYWdzKSA/IHRlc3RDb25maWcuZXhjbHVkZVRhZ3MgOiBbXVxuXG4gICAgcmV0dXJuIG5ldyBTZXQoWy4uLnRoaXMuX2V4Y2x1ZGVUYWdzLCAuLi5jb25maWdUYWdzXSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGJ1aWxkIGZ1bGwgZGVzY3JpcHRpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGRlc2NyaXB0aW9ucyAtIERlc2NyaXB0aW9uIHN0YWNrLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGVzdERlc2NyaXB0aW9uIC0gVGVzdCBkZXNjcmlwdGlvbi5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBGdWxsIGRlc2NyaXB0aW9uLlxuICAgKi9cbiAgYnVpbGRGdWxsRGVzY3JpcHRpb24oZGVzY3JpcHRpb25zLCB0ZXN0RGVzY3JpcHRpb24pIHtcbiAgICBjb25zdCBwYXJ0cyA9IGRlc2NyaXB0aW9ucy5jb25jYXQoW3Rlc3REZXNjcmlwdGlvbl0pXG5cbiAgICByZXR1cm4gcGFydHMuam9pbihcIiBcIikudHJpbSgpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBhcHBsaWNhdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8QXBwbGljYXRpb24+fSAtIFJlc29sdmVzIHdpdGggdGhlIGFwcGxpY2F0aW9uLlxuICAgKi9cbiAgYXN5bmMgYXBwbGljYXRpb24oKSB7XG4gICAgaWYgKCF0aGlzLl9hcHBsaWNhdGlvbikge1xuICAgICAgdGhpcy5fYXBwbGljYXRpb24gPSBuZXcgQXBwbGljYXRpb24oe1xuICAgICAgICBjb25maWd1cmF0aW9uOiB0aGlzLmdldENvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgLy8gUnVuIHJlcXVlc3QgaGFuZGxlcnMgaW4gdGhlIG1haW4gdGhyZWFkIChub3Qgd29ya2VyIHRocmVhZHMpIHNvIHRoZXlcbiAgICAgICAgLy8gcmVzb2x2ZSBEQiB3b3JrIHRvIHRoZSBwZXItdGVzdCBzaGFyZWQgY29ubmVjdGlvbiBzZXQgYnlcbiAgICAgICAgLy8ge0BsaW5rIGFjdGl2YXRlVGVzdFNoYXJlZENvbm5lY3Rpb25zfS4gVGhpcyBsZXRzIHJlcXVlc3QtdHlwZSBzcGVjcyB1c2VcbiAgICAgICAgLy8gdHJhbnNhY3Rpb24tYmFzZWQgY2xlYW5pbmcgKHRoZWlyIHdyaXRlcyBsYW5kIGluc2lkZSB0aGUgdGVzdCdzXG4gICAgICAgIC8vIHRyYW5zYWN0aW9uIGFuZCByb2xsIGJhY2spIGluc3RlYWQgb2YgdHJ1bmNhdGluZyBldmVyeSB0YWJsZS5cbiAgICAgICAgaHR0cFNlcnZlcjoge2luUHJvY2VzczogdHJ1ZSwgcG9ydDogMzEwMDZ9LFxuICAgICAgICB0eXBlOiBcInRlc3QtcnVubmVyXCJcbiAgICAgIH0pXG5cbiAgICAgIGF3YWl0IHRoaXMuX2FwcGxpY2F0aW9uLmluaXRpYWxpemUoKVxuICAgICAgYXdhaXQgdGhpcy5fYXBwbGljYXRpb24uc3RhcnRIdHRwU2VydmVyKClcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fYXBwbGljYXRpb25cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgZWFjaCBub24tdGVuYW50IHBlci10ZXN0IGNvbm5lY3Rpb24gYXMgYSBkeW5hbWljIGNhbmRpZGF0ZSBmb3IgaW4tcHJvY2Vzc1xuICAgKiByZXF1ZXN0IHNoYXJpbmcuIFRoZSBwb29sIGV2YWx1YXRlcyB0cmFuc2FjdGlvbiBzdGF0ZSB3aGVuIGVhY2ggcmVxdWVzdCBpcyBkaXNwYXRjaGVkLFxuICAgKiBzbyBhIHRyYW5zYWN0aW9uIHN0YXJ0ZWQgb3IgZW5kZWQgZHVyaW5nIGEgaG9vayBjYWxsYmFjayB0YWtlcyBlZmZlY3QgaW1tZWRpYXRlbHkuXG4gICAqIEluYWN0aXZlIGFuZCB0ZW5hbnQtb25seSBjb25uZWN0aW9ucyByZW1haW4gaW5kZXBlbmRlbnRseSBwb29sZWQuIFBhaXIgd2l0aFxuICAgKiB7QGxpbmsgY2xlYXJUZXN0U2hhcmVkQ29ubmVjdGlvbnN9IGluIGEgZmluYWxseS5cbiAgICogQHJldHVybnMge3twb29sOiBpbXBvcnQoXCIuLi9kYXRhYmFzZS9wb29sL2Jhc2UuanNcIikuZGVmYXVsdCwgcmVnaXN0cmF0aW9uOiBpbXBvcnQoXCIuLi9kYXRhYmFzZS9wb29sL2Jhc2UuanNcIikuVGVzdFNoYXJlZENvbm5lY3Rpb25SZWdpc3RyYXRpb259W119IC0gTGlmZWN5Y2xlLW93bmVkIHJlZ2lzdHJhdGlvbnMuXG4gICAqL1xuICBhY3RpdmF0ZVRlc3RTaGFyZWRDb25uZWN0aW9ucygpIHtcbiAgICBjb25zdCBjb25maWd1cmF0aW9uID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKClcbiAgICBjb25zdCBjdXJyZW50Q29ubmVjdGlvbnMgPSBjb25maWd1cmF0aW9uLmdldEN1cnJlbnRDb25uZWN0aW9ucygpXG4gICAgLyoqIEB0eXBlIHt7cG9vbDogaW1wb3J0KFwiLi4vZGF0YWJhc2UvcG9vbC9iYXNlLmpzXCIpLmRlZmF1bHQsIHJlZ2lzdHJhdGlvbjogaW1wb3J0KFwiLi4vZGF0YWJhc2UvcG9vbC9iYXNlLmpzXCIpLlRlc3RTaGFyZWRDb25uZWN0aW9uUmVnaXN0cmF0aW9ufVtdfSAqL1xuICAgIGNvbnN0IHJlZ2lzdHJhdGlvbnMgPSBbXVxuXG4gICAgZm9yIChjb25zdCBpZGVudGlmaWVyIG9mIE9iamVjdC5rZXlzKGN1cnJlbnRDb25uZWN0aW9ucykpIHtcbiAgICAgIGNvbnN0IHBvb2wgPSBjb25maWd1cmF0aW9uLmdldERhdGFiYXNlUG9vbChpZGVudGlmaWVyKVxuXG4gICAgICAvLyBUZW5hbnQtc2NvcGVkIHBvb2xzIHJlc29sdmUgYSBkaWZmZXJlbnQgY29ubmVjdGlvbiBwZXIgcmVxdWVzdCB0ZW5hbnRcbiAgICAgIC8vICh2aWEgcnVuV2l0aFRlbmFudCksIHNvIGZvcmNpbmcgYSBzaW5nbGUgc2hhcmVkIGNvbm5lY3Rpb24gd291bGQgYnJlYWtcbiAgICAgIC8vIHBlci1yZXF1ZXN0IHRlbmFudCByZXNvbHV0aW9uLiBPbmx5IHNoYXJlIG5vbi10ZW5hbnQgcG9vbHM7IHRoZSB0ZW5hbnRcbiAgICAgIC8vIHBvb2wga2VlcHMgcmVzb2x2aW5nIGl0cyBvd24gY29ubmVjdGlvbiBwZXIgcmVxdWVzdC5cbiAgICAgIGlmIChwb29sLmdldENvbmZpZ3VyYXRpb24oKS50ZW5hbnRPbmx5KSB7XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBjdXJyZW50Q29ubmVjdGlvbnNbaWRlbnRpZmllcl1cblxuICAgICAgY29uc3QgcmVnaXN0cmF0aW9uID0gcG9vbC5zZXRUZXN0U2hhcmVkQ29ubmVjdGlvblByb3ZpZGVyKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIGNvbm5lY3Rpb24uaW5zaWRlVHJhbnNhY3Rpb24oKSA/IGNvbm5lY3Rpb24gOiB1bmRlZmluZWRcbiAgICAgIH0pXG5cbiAgICAgIGlmIChyZWdpc3RyYXRpb24pIHJlZ2lzdHJhdGlvbnMucHVzaCh7cG9vbCwgcmVnaXN0cmF0aW9ufSlcbiAgICB9XG5cbiAgICByZXR1cm4gcmVnaXN0cmF0aW9uc1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFycyB0aGUgaW4tcHJvY2VzcyB0ZXN0IHNoYXJlZCBjb25uZWN0aW9uIG9uIGV2ZXJ5IGNvbmZpZ3VyZWQgcG9vbC4gSWRlbXBvdGVudCBhbmRcbiAgICogc2FmZSB0byBjYWxsIHdoZW4gbm9uZSB3YXMgc2V0LlxuICAgKiBAcGFyYW0ge3twb29sOiBpbXBvcnQoXCIuLi9kYXRhYmFzZS9wb29sL2Jhc2UuanNcIikuZGVmYXVsdCwgcmVnaXN0cmF0aW9uOiBpbXBvcnQoXCIuLi9kYXRhYmFzZS9wb29sL2Jhc2UuanNcIikuVGVzdFNoYXJlZENvbm5lY3Rpb25SZWdpc3RyYXRpb259W119IFtyZWdpc3RyYXRpb25zXSAtIExpZmVjeWNsZS1vd25lZCByZWdpc3RyYXRpb25zIHRvIGNsZWFyIGNvbmRpdGlvbmFsbHkuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgY2xlYXJUZXN0U2hhcmVkQ29ubmVjdGlvbnMocmVnaXN0cmF0aW9ucykge1xuICAgIGlmIChyZWdpc3RyYXRpb25zKSB7XG4gICAgICBmb3IgKGNvbnN0IHtwb29sLCByZWdpc3RyYXRpb259IG9mIHJlZ2lzdHJhdGlvbnMpIHtcbiAgICAgICAgcG9vbC5jbGVhclRlc3RTaGFyZWRDb25uZWN0aW9uKHJlZ2lzdHJhdGlvbilcbiAgICAgIH1cbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IGNvbmZpZ3VyYXRpb24gPSB0aGlzLmdldENvbmZpZ3VyYXRpb24oKVxuXG4gICAgZm9yIChjb25zdCBpZGVudGlmaWVyIG9mIGNvbmZpZ3VyYXRpb24uZ2V0RGF0YWJhc2VJZGVudGlmaWVycygpKSB7XG4gICAgICBjb25maWd1cmF0aW9uLmdldERhdGFiYXNlUG9vbChpZGVudGlmaWVyKS5jbGVhclRlc3RTaGFyZWRDb25uZWN0aW9uKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIG91dCBhbmQgcmVnaXN0ZXJzIG9uZSBwaHlzaWNhbCB0ZW5hbnQgdHJhbnNhY3Rpb24gZm9yIHRoZSBjdXJyZW50IGF0dGVtcHQuXG4gICAqIEBwYXJhbSB7e2RhdGFiYXNlSWRlbnRpZmllcjogc3RyaW5nLCB0ZW5hbnQ6IG9iamVjdH19IGFyZ3MgLSBMb2dpY2FsIGlkZW50aWZpZXIgYW5kIHRlbmFudCBkZXNjcmlwdG9yLlxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9uYWxUZW5hbnRSZWdpc3RyYXRpb25bXX0gcmVnaXN0cmF0aW9ucyAtIEN1cnJlbnQgYXR0ZW1wdCByZWdpc3RyYXRpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIHJlZ2lzdGVyVHJhbnNhY3Rpb25hbFRlbmFudCh7ZGF0YWJhc2VJZGVudGlmaWVyLCB0ZW5hbnQsIC4uLnJlc3RBcmdzfSwgcmVnaXN0cmF0aW9ucykge1xuICAgIHJlc3RBcmdzRXJyb3IocmVzdEFyZ3MpXG4gICAgaWYgKCFkYXRhYmFzZUlkZW50aWZpZXIpIHRocm93IG5ldyBFcnJvcihcInJlZ2lzdGVyVHJhbnNhY3Rpb25hbFRlbmFudCByZXF1aXJlcyBhIGRhdGFiYXNlSWRlbnRpZmllclwiKVxuICAgIGlmICghdGVuYW50KSB0aHJvdyBuZXcgRXJyb3IoXCJyZWdpc3RlclRyYW5zYWN0aW9uYWxUZW5hbnQgcmVxdWlyZXMgYSB0ZW5hbnRcIilcblxuICAgIGNvbnN0IGNvbmZpZ3VyYXRpb24gPSB0aGlzLmdldENvbmZpZ3VyYXRpb24oKVxuICAgIGNvbnN0IHBvb2wgPSBjb25maWd1cmF0aW9uLmdldERhdGFiYXNlUG9vbChkYXRhYmFzZUlkZW50aWZpZXIpXG4gICAgY29uc3QgZGF0YWJhc2VDb25maWd1cmF0aW9uID0gY29uZmlndXJhdGlvbi5yZXNvbHZlRGF0YWJhc2VDb25maWd1cmF0aW9uKGRhdGFiYXNlSWRlbnRpZmllciwgdGVuYW50KVxuICAgIGlmICghZGF0YWJhc2VDb25maWd1cmF0aW9uLnRlbmFudE9ubHkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgcmVnaXN0ZXJUcmFuc2FjdGlvbmFsVGVuYW50IHJlcXVpcmVzIGEgdGVuYW50T25seSBkYXRhYmFzZTogJHtkYXRhYmFzZUlkZW50aWZpZXJ9YClcbiAgICB9XG4gICAgY29uc3QgcmV1c2VLZXkgPSBwb29sLmdldENvbmZpZ3VyYXRpb25SZXVzZUtleShkYXRhYmFzZUNvbmZpZ3VyYXRpb24pXG4gICAgaWYgKHJlZ2lzdHJhdGlvbnMuc29tZSgocmVnaXN0cmF0aW9uKSA9PiByZWdpc3RyYXRpb24ucG9vbCA9PT0gcG9vbCAmJiByZWdpc3RyYXRpb24ucmV1c2VLZXkgPT09IHJldXNlS2V5KSkgcmV0dXJuXG5cbiAgICAvKiogQHR5cGUge1RyYW5zYWN0aW9uYWxUZW5hbnRSZWdpc3RyYXRpb259ICovXG4gICAgY29uc3QgcmVnaXN0cmF0aW9uID0ge1xuICAgICAgY29ubmVjdGlvbjogdW5kZWZpbmVkLFxuICAgICAgcG9vbCxcbiAgICAgIHJldXNlS2V5LFxuICAgICAgcmV2b2tlZDogZmFsc2UsXG4gICAgICBzaGFyZWRSZWdpc3RyYXRpb246IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIHJlZ2lzdHJhdGlvbnMucHVzaChyZWdpc3RyYXRpb24pXG4gICAgcmVnaXN0cmF0aW9uLmNoZWNrb3V0UHJvbWlzZSA9IHBvb2xcbiAgICAgIC5jaGVja291dEZvckNvbmZpZ3VyYXRpb24oZGF0YWJhc2VDb25maWd1cmF0aW9uLCB7bmFtZTogXCJUcmFuc2FjdGlvbmFsIHRlbmFudCB0ZXN0IHJlZ2lzdHJhdGlvblwifSlcbiAgICAgIC50aGVuKFxuICAgICAgICAoY29ubmVjdGlvbikgPT4gKHtjb25uZWN0aW9uLCBlcnJvcjogdW5kZWZpbmVkfSksXG4gICAgICAgIChlcnJvcikgPT4gKHtcbiAgICAgICAgICBjb25uZWN0aW9uOiB1bmRlZmluZWQsXG4gICAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihcIlRyYW5zYWN0aW9uYWwgdGVuYW50IGNvbm5lY3Rpb24gY2hlY2tvdXQgZmFpbGVkXCIsIHtjYXVzZTogZXJyb3J9KVxuICAgICAgICB9KVxuICAgICAgKVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNoZWNrb3V0T3V0Y29tZSA9IGF3YWl0IHJlZ2lzdHJhdGlvbi5jaGVja291dFByb21pc2VcblxuICAgICAgaWYgKGNoZWNrb3V0T3V0Y29tZS5lcnJvcikgdGhyb3cgY2hlY2tvdXRPdXRjb21lLmVycm9yXG4gICAgICBpZiAoIWNoZWNrb3V0T3V0Y29tZS5jb25uZWN0aW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJUcmFuc2FjdGlvbmFsIHRlbmFudCBjb25uZWN0aW9uIGNoZWNrb3V0IHJldHVybmVkIG5vIGNvbm5lY3Rpb25cIilcbiAgICAgIHJlZ2lzdHJhdGlvbi5jb25uZWN0aW9uID0gY2hlY2tvdXRPdXRjb21lLmNvbm5lY3Rpb25cbiAgICAgIGlmIChyZWdpc3RyYXRpb24ucmV2b2tlZCkgdGhyb3cgbmV3IEVycm9yKFwiVHJhbnNhY3Rpb25hbCB0ZW5hbnQgdGVzdCByZWdpc3RyYXRpb24gYXR0ZW1wdCBpcyBubyBsb25nZXIgYWN0aXZlXCIpXG5cbiAgICAgIGF3YWl0IHJlZ2lzdHJhdGlvbi5jb25uZWN0aW9uLnN0YXJ0VHJhbnNhY3Rpb24oKVxuICAgICAgaWYgKHJlZ2lzdHJhdGlvbi5yZXZva2VkKSB0aHJvdyBuZXcgRXJyb3IoXCJUcmFuc2FjdGlvbmFsIHRlbmFudCB0ZXN0IHJlZ2lzdHJhdGlvbiBhdHRlbXB0IGlzIG5vIGxvbmdlciBhY3RpdmVcIilcblxuICAgICAgY29uc3Qgc2hhcmVkUmVnaXN0cmF0aW9uID0gcG9vbC5zZXRUZXN0U2hhcmVkQ29ubmVjdGlvbkZvckNvbmZpZ3VyYXRpb24ocmVnaXN0cmF0aW9uLmNvbm5lY3Rpb24sIHJldXNlS2V5KVxuICAgICAgaWYgKCFzaGFyZWRSZWdpc3RyYXRpb24pIHRocm93IG5ldyBFcnJvcihgRGF0YWJhc2UgcG9vbCBkb2VzIG5vdCBzdXBwb3J0IHRyYW5zYWN0aW9uYWwgdGVuYW50IHRlc3QgY29ubmVjdGlvbnM6ICR7ZGF0YWJhc2VJZGVudGlmaWVyfWApXG4gICAgICByZWdpc3RyYXRpb24uc2hhcmVkUmVnaXN0cmF0aW9uID0gc2hhcmVkUmVnaXN0cmF0aW9uXG4gICAgICBpZiAocmVnaXN0cmF0aW9uLnJldm9rZWQpIHtcbiAgICAgICAgcG9vbC5jbGVhclRlc3RTaGFyZWRDb25uZWN0aW9uKHNoYXJlZFJlZ2lzdHJhdGlvbilcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVHJhbnNhY3Rpb25hbCB0ZW5hbnQgdGVzdCByZWdpc3RyYXRpb24gYXR0ZW1wdCBpcyBubyBsb25nZXIgYWN0aXZlXCIpXG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJlZ2lzdHJhdGlvbi5yZXZva2VkID0gdHJ1ZVxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5jbGVhbnVwVHJhbnNhY3Rpb25hbFRlbmFudHMoW3JlZ2lzdHJhdGlvbl0sIHtkaXNjYXJkOiByZWdpc3RyYXRpb24uZGlzY2FyZE9uQ2xlYW51cCA9PT0gdHJ1ZX0pXG4gICAgICB9IGNhdGNoIChjbGVhbnVwRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IEFnZ3JlZ2F0ZUVycm9yKFtlcnJvciwgY2xlYW51cEVycm9yXSwgXCJGYWlsZWQgdG8gcmVnaXN0ZXIgYW5kIGNsZWFuIHVwIGEgdHJhbnNhY3Rpb25hbCB0ZW5hbnQgdGVzdCBjb25uZWN0aW9uXCIsIHtjYXVzZTogY2xlYW51cEVycm9yfSlcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldm9rZXMgYXR0ZW1wdCByZWdpc3RyYXRpb25zIGJlZm9yZSByb2xsaW5nIGJhY2sgYW5kIHJlbGVhc2luZyB0aGVpciBjb25uZWN0aW9ucy5cbiAgICogQHBhcmFtIHtUcmFuc2FjdGlvbmFsVGVuYW50UmVnaXN0cmF0aW9uW119IHJlZ2lzdHJhdGlvbnMgLSBBdHRlbXB0IHJlZ2lzdHJhdGlvbnMuXG4gICAqIEBwYXJhbSB7e2Rpc2NhcmQ/OiBib29sZWFufX0gW29wdGlvbnNdIC0gV2hldGhlciBjb25uZWN0aW9ucyBtdXN0IGJlIGRpc2NhcmRlZCBpbnN0ZWFkIG9mIHJldHVybmVkIHRvIHRoZSBwb29sLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIGNsZWFudXBUcmFuc2FjdGlvbmFsVGVuYW50cyhyZWdpc3RyYXRpb25zLCB7ZGlzY2FyZCA9IGZhbHNlfSA9IHt9KSB7XG4gICAgZm9yIChjb25zdCByZWdpc3RyYXRpb24gb2YgcmVnaXN0cmF0aW9ucykge1xuICAgICAgcmVnaXN0cmF0aW9uLnJldm9rZWQgPSB0cnVlXG4gICAgICBpZiAoZGlzY2FyZCkgcmVnaXN0cmF0aW9uLmRpc2NhcmRPbkNsZWFudXAgPSB0cnVlXG4gICAgICBpZiAocmVnaXN0cmF0aW9uLnNoYXJlZFJlZ2lzdHJhdGlvbikgcmVnaXN0cmF0aW9uLnBvb2wuY2xlYXJUZXN0U2hhcmVkQ29ubmVjdGlvbihyZWdpc3RyYXRpb24uc2hhcmVkUmVnaXN0cmF0aW9uKVxuICAgIH1cbiAgICBjb25zdCBjbGVhbnVwUmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChbLi4ucmVnaXN0cmF0aW9uc10ucmV2ZXJzZSgpLm1hcCgocmVnaXN0cmF0aW9uKSA9PiB7XG4gICAgICByZWdpc3RyYXRpb24uY2xlYW51cFByb21pc2UgPz89IHRoaXMuY2xlYW51cFRyYW5zYWN0aW9uYWxUZW5hbnRSZWdpc3RyYXRpb24ocmVnaXN0cmF0aW9uKVxuXG4gICAgICByZXR1cm4gcmVnaXN0cmF0aW9uLmNsZWFudXBQcm9taXNlXG4gICAgfSkpXG4gICAgY29uc3QgZXJyb3JzID0gY2xlYW51cFJlc3VsdHNcbiAgICAgIC5maWx0ZXIoKHJlc3VsdCkgPT4gcmVzdWx0LnN0YXR1cyA9PT0gXCJyZWplY3RlZFwiKVxuICAgICAgLm1hcCgocmVzdWx0KSA9PiByZXN1bHQucmVhc29uKVxuXG4gICAgaWYgKGVycm9ycy5sZW5ndGggPT09IDEpIHRocm93IGVycm9yc1swXVxuICAgIGlmIChlcnJvcnMubGVuZ3RoID4gMSkgdGhyb3cgbmV3IEFnZ3JlZ2F0ZUVycm9yKGVycm9ycywgXCJGYWlsZWQgdG8gY2xlYW4gdXAgdHJhbnNhY3Rpb25hbCB0ZW5hbnQgdGVzdCBjb25uZWN0aW9uc1wiKVxuICB9XG5cbiAgLyoqXG4gICAqIENsZWFucyBvbmUgYXR0ZW1wdCByZWdpc3RyYXRpb24gZXhhY3RseSBvbmNlLCBpbmNsdWRpbmcgYSBjaGVja291dCB0aGF0IHdhcyBzdGlsbCBwZW5kaW5nIGF0IHJldm9jYXRpb24uXG4gICAqIEBwYXJhbSB7VHJhbnNhY3Rpb25hbFRlbmFudFJlZ2lzdHJhdGlvbn0gcmVnaXN0cmF0aW9uIC0gQXR0ZW1wdC1vd25lZCByZWdpc3RyYXRpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIGFmdGVyIHJvbGxiYWNrIGFuZCByZWxlYXNlIG9yIHF1YXJhbnRpbmUuXG4gICAqL1xuICBhc3luYyBjbGVhbnVwVHJhbnNhY3Rpb25hbFRlbmFudFJlZ2lzdHJhdGlvbihyZWdpc3RyYXRpb24pIHtcbiAgICBsZXQgY29ubmVjdGlvbiA9IHJlZ2lzdHJhdGlvbi5jb25uZWN0aW9uXG5cbiAgICBpZiAoIWNvbm5lY3Rpb24gJiYgcmVnaXN0cmF0aW9uLmNoZWNrb3V0UHJvbWlzZSkge1xuICAgICAgY29uc3QgY2hlY2tvdXRPdXRjb21lID0gYXdhaXQgcmVnaXN0cmF0aW9uLmNoZWNrb3V0UHJvbWlzZVxuXG4gICAgICBpZiAoY2hlY2tvdXRPdXRjb21lLmVycm9yKSByZXR1cm5cbiAgICAgIGNvbm5lY3Rpb24gPSBjaGVja291dE91dGNvbWUuY29ubmVjdGlvblxuICAgICAgcmVnaXN0cmF0aW9uLmNvbm5lY3Rpb24gPSBjb25uZWN0aW9uXG4gICAgfVxuICAgIGlmICghY29ubmVjdGlvbikgcmV0dXJuXG5cbiAgICBjb25zdCBlcnJvcnMgPSBbXVxuXG4gICAgdHJ5IHtcbiAgICAgIGlmIChjb25uZWN0aW9uLmluc2lkZVRyYW5zYWN0aW9uKCkpIGF3YWl0IGNvbm5lY3Rpb24ucm9sbGJhY2tUcmFuc2FjdGlvbigpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGVycm9ycy5wdXNoKGVycm9yKVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAocmVnaXN0cmF0aW9uLmRpc2NhcmRPbkNsZWFudXApIHtcbiAgICAgICAgICBhd2FpdCByZWdpc3RyYXRpb24ucG9vbC5kaXNjYXJkKGNvbm5lY3Rpb24pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYXdhaXQgcmVnaXN0cmF0aW9uLnBvb2wuY2hlY2tpbihjb25uZWN0aW9uKVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBlcnJvcnMucHVzaChlcnJvcilcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVycm9ycy5sZW5ndGggPT09IDEpIHRocm93IGVycm9yc1swXVxuICAgIGlmIChlcnJvcnMubGVuZ3RoID4gMSkgdGhyb3cgbmV3IEFnZ3JlZ2F0ZUVycm9yKGVycm9ycywgXCJGYWlsZWQgdG8gY2xlYW4gdXAgYSB0cmFuc2FjdGlvbmFsIHRlbmFudCB0ZXN0IGNvbm5lY3Rpb25cIilcbiAgfVxuXG4gIC8qKlxuICAgKiBTZWxlY3RzIHRoZSBjdXJyZW50IG5vbi10ZW5hbnQgY29ubmVjdGlvbnMgZWxpZ2libGUgZm9yIHNoYXJlZCB0cmFuc2FjdGlvbiB3b3JrLlxuICAgKiBAcGFyYW0ge3t0cmFuc2FjdGlvbnNPbmx5OiBib29sZWFufX0gYXJncyAtIFNlbGVjdGlvbiBvcHRpb25zLlxuICAgKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgaW1wb3J0KFwiLi4vZGF0YWJhc2UvZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+fSAtIEVsaWdpYmxlIGNvbm5lY3Rpb25zIGJ5IGlkZW50aWZpZXIuXG4gICAqL1xuICBzaGFyZWRUcmFuc2FjdGlvbkNvbm5lY3Rpb25zKHt0cmFuc2FjdGlvbnNPbmx5fSkge1xuICAgIGNvbnN0IGNvbmZpZ3VyYXRpb24gPSB0aGlzLmdldENvbmZpZ3VyYXRpb24oKVxuICAgIGNvbnN0IGN1cnJlbnRDb25uZWN0aW9ucyA9IGNvbmZpZ3VyYXRpb24uZ2V0Q3VycmVudENvbm5lY3Rpb25zKClcbiAgICAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIGltcG9ydChcIi4uL2RhdGFiYXNlL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gKi9cbiAgICBjb25zdCBjb25uZWN0aW9ucyA9IHt9XG5cbiAgICBmb3IgKGNvbnN0IFtpZGVudGlmaWVyLCBjb25uZWN0aW9uXSBvZiBPYmplY3QuZW50cmllcyhjdXJyZW50Q29ubmVjdGlvbnMpKSB7XG4gICAgICBjb25zdCBwb29sID0gY29uZmlndXJhdGlvbi5nZXREYXRhYmFzZVBvb2woaWRlbnRpZmllcilcblxuICAgICAgaWYgKHBvb2wuZ2V0Q29uZmlndXJhdGlvbigpLnRlbmFudE9ubHkpIGNvbnRpbnVlXG4gICAgICBpZiAodHJhbnNhY3Rpb25zT25seSAmJiAhY29ubmVjdGlvbi5pbnNpZGVUcmFuc2FjdGlvbigpKSBjb250aW51ZVxuICAgICAgY29ubmVjdGlvbnNbaWRlbnRpZmllcl0gPSBjb25uZWN0aW9uXG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbm5lY3Rpb25zXG4gIH1cblxuICAvKipcbiAgICogSW5zdGFsbHMgcGh5c2ljYWwtY29ubmVjdGlvbiBjb29yZGluYXRpb24gYmVmb3JlIGEgdHJhbnNhY3Rpb24tb3BlbmluZyBob29rXG4gICAqIGNhbiBleHBvc2UgdGhlIHNoYXJlZCBjb25uZWN0aW9uIHRvIGEgbG9uZy1saXZlZCBpbi1wcm9jZXNzIHNlcnZpY2UuXG4gICAqIENoaWxkLXByb2Nlc3MgY29vcmRpbmF0ZXMgcmVtYWluIHVucHVibGlzaGVkIHVudGlsIHRoZSB0cmFuc2FjdGlvbiBleGlzdHMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFNoYXJlZFRyYW5zYWN0aW9uQnJva2VyUmVnaXN0cmF0aW9uIHwgdW5kZWZpbmVkPn0gLSBQcmVwYXJlZCBjb29yZGluYXRvci5cbiAgICovXG4gIGFzeW5jIHByZXBhcmVTaGFyZWRUcmFuc2FjdGlvbkJyb2tlcigpIHtcbiAgICBjb25zdCBjb25uZWN0aW9ucyA9IHRoaXMuc2hhcmVkVHJhbnNhY3Rpb25Db25uZWN0aW9ucyh7dHJhbnNhY3Rpb25zT25seTogZmFsc2V9KVxuXG4gICAgaWYgKE9iamVjdC5rZXlzKGNvbm5lY3Rpb25zKS5sZW5ndGggPT09IDApIHJldHVybiB1bmRlZmluZWRcblxuICAgIHJldHVybiB7XG4gICAgICBicm9rZXI6IGF3YWl0IFNoYXJlZFRyYW5zYWN0aW9uQnJva2VyLnN0YXJ0KHtjb25uZWN0aW9uc30pLFxuICAgICAgZW52aXJvbm1lbnRQdWJsaXNoZWQ6IGZhbHNlLFxuICAgICAgcHJldmlvdXNFbnZpcm9ubWVudDogdW5kZWZpbmVkXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyB3aGV0aGVyIGEgcHJlcGFyZWQgYnJva2VyIGNvb3JkaW5hdGVzIGV4YWN0bHkgdGhlIHNlbGVjdGVkIHBoeXNpY2FsIGNvbm5lY3Rpb25zLlxuICAgKiBAcGFyYW0ge1NoYXJlZFRyYW5zYWN0aW9uQnJva2VyUmVnaXN0cmF0aW9uIHwgdW5kZWZpbmVkfSByZWdpc3RyYXRpb24gLSBQcmVwYXJlZCBjb29yZGluYXRvci5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBpbXBvcnQoXCIuLi9kYXRhYmFzZS9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59IGNvbm5lY3Rpb25zIC0gU2VsZWN0ZWQgY29ubmVjdGlvbnMuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgdGhlIGlkZW50aWZpZXIgc2V0IGFuZCBwaHlzaWNhbCBjb25uZWN0aW9ucyBtYXRjaCBleGFjdGx5LlxuICAgKi9cbiAgc2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJNYXRjaGVzQ29ubmVjdGlvbnMocmVnaXN0cmF0aW9uLCBjb25uZWN0aW9ucykge1xuICAgIGNvbnN0IGlkZW50aWZpZXJzID0gT2JqZWN0LmtleXMoY29ubmVjdGlvbnMpXG5cbiAgICBpZiAoIXJlZ2lzdHJhdGlvbiB8fCBpZGVudGlmaWVycy5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZVxuICAgIGlmIChPYmplY3Qua2V5cyhyZWdpc3RyYXRpb24uYnJva2VyLmNvbm5lY3Rpb25zKS5sZW5ndGggIT09IGlkZW50aWZpZXJzLmxlbmd0aCkgcmV0dXJuIGZhbHNlXG5cbiAgICBmb3IgKGNvbnN0IFtpZGVudGlmaWVyLCBjb25uZWN0aW9uXSBvZiBPYmplY3QuZW50cmllcyhjb25uZWN0aW9ucykpIHtcbiAgICAgIGlmIChyZWdpc3RyYXRpb24uYnJva2VyLmNvbm5lY3Rpb25zW2lkZW50aWZpZXJdICE9PSBjb25uZWN0aW9uKSByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0cyBhIGNhcGFiaWxpdHktc2NvcGVkIGJyb2tlciBmb3IgdGhlIGFjdGl2ZSBub24tdGVuYW50IHBoeXNpY2FsXG4gICAqIHRyYW5zYWN0aW9uIGNvbm5lY3Rpb25zLiBObyBicm9rZXIvZW52IGlzIGluc3RhbGxlZCBmb3IgdHJ1bmNhdGlvbi1vbmx5IG9yXG4gICAqIG90aGVyIHRyYW5zYWN0aW9uLWRpc2FibGVkIGF0dGVtcHRzLlxuICAgKiBAcGFyYW0ge1NoYXJlZFRyYW5zYWN0aW9uQnJva2VyUmVnaXN0cmF0aW9ufSBbcHJlcGFyZWRSZWdpc3RyYXRpb25dIC0gQ29vcmRpbmF0b3IgcHJlcGFyZWQgYmVmb3JlIGhvb2tzLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGltcG9ydChcIi4uL2RhdGFiYXNlL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gW3NlbGVjdGVkQ29ubmVjdGlvbnNdIC0gUG9zdC1ob29rIGFjdGl2ZSBjb25uZWN0aW9ucy5cbiAgICogQHJldHVybnMge1Byb21pc2U8U2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJSZWdpc3RyYXRpb24gfCB1bmRlZmluZWQ+fSAtIEF0dGVtcHQgcmVnaXN0cmF0aW9uLlxuICAgKi9cbiAgYXN5bmMgc3RhcnRTaGFyZWRUcmFuc2FjdGlvbkJyb2tlcihwcmVwYXJlZFJlZ2lzdHJhdGlvbiwgc2VsZWN0ZWRDb25uZWN0aW9ucykge1xuICAgIGNvbnN0IGNvbm5lY3Rpb25zID0gc2VsZWN0ZWRDb25uZWN0aW9ucyB8fCB0aGlzLnNoYXJlZFRyYW5zYWN0aW9uQ29ubmVjdGlvbnMoe3RyYW5zYWN0aW9uc09ubHk6IHRydWV9KVxuXG4gICAgY29uc3QgZGF0YWJhc2VJZGVudGlmaWVycyA9IE9iamVjdC5rZXlzKGNvbm5lY3Rpb25zKVxuICAgIGlmIChkYXRhYmFzZUlkZW50aWZpZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgYXdhaXQgdGhpcy5zdG9wU2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXIocHJlcGFyZWRSZWdpc3RyYXRpb24pXG4gICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgfVxuXG4gICAgbGV0IGJyb2tlclxuXG4gICAgaWYgKHByZXBhcmVkUmVnaXN0cmF0aW9uICYmIHRoaXMuc2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXJNYXRjaGVzQ29ubmVjdGlvbnMocHJlcGFyZWRSZWdpc3RyYXRpb24sIGNvbm5lY3Rpb25zKSkge1xuICAgICAgYnJva2VyID0gcHJlcGFyZWRSZWdpc3RyYXRpb24uYnJva2VyXG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHRoaXMuc3RvcFNoYXJlZFRyYW5zYWN0aW9uQnJva2VyKHByZXBhcmVkUmVnaXN0cmF0aW9uKVxuICAgICAgYnJva2VyID0gYXdhaXQgU2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXIuc3RhcnQoe2Nvbm5lY3Rpb25zfSlcbiAgICB9XG5cbiAgICBjb25zdCBwcmV2aW91c0Vudmlyb25tZW50ID0gcHJvY2Vzcy5lbnZbU0hBUkVEX1RSQU5TQUNUSU9OX0JST0tFUl9FTlZdXG4gICAgcHJvY2Vzcy5lbnZbU0hBUkVEX1RSQU5TQUNUSU9OX0JST0tFUl9FTlZdID0gQnVmZmVyLmZyb20oSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgYWRkcmVzczogYnJva2VyLmFkZHJlc3MoKSxcbiAgICAgIGNhcGFiaWxpdHk6IGJyb2tlci5jYXBhYmlsaXR5KCksXG4gICAgICBkYXRhYmFzZUlkZW50aWZpZXJzLFxuICAgICAgZXhwZWN0ZWQ6IHRydWVcbiAgICB9KSkudG9TdHJpbmcoXCJiYXNlNjR1cmxcIilcblxuICAgIHJldHVybiB7YnJva2VyLCBlbnZpcm9ubWVudFB1Ymxpc2hlZDogdHJ1ZSwgcHJldmlvdXNFbnZpcm9ubWVudH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXZva2VzIGFuIGF0dGVtcHQgYnJva2VyIGJlZm9yZSBkYXRhYmFzZSByb2xsYmFjayBob29rcyBydW4gYW5kIHJlc3RvcmVzXG4gICAqIHRoZSBjYWxsZXIncyBlbnZpcm9ubWVudCBzbyBsYXRlciBwb29sZWQvc3Bhd25lZCBjaGlsZHJlbiBjYW5ub3QgaW5oZXJpdCBpdC5cbiAgICogQHBhcmFtIHtTaGFyZWRUcmFuc2FjdGlvbkJyb2tlclJlZ2lzdHJhdGlvbiB8IHVuZGVmaW5lZH0gcmVnaXN0cmF0aW9uIC0gQXR0ZW1wdCByZWdpc3RyYXRpb24uXG4gICAqL1xuICBhc3luYyBzdG9wU2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXIocmVnaXN0cmF0aW9uKSB7XG4gICAgaWYgKCFyZWdpc3RyYXRpb24pIHJldHVyblxuXG4gICAgaWYgKHJlZ2lzdHJhdGlvbi5lbnZpcm9ubWVudFB1Ymxpc2hlZCkge1xuICAgICAgaWYgKHJlZ2lzdHJhdGlvbi5wcmV2aW91c0Vudmlyb25tZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZGVsZXRlIHByb2Nlc3MuZW52W1NIQVJFRF9UUkFOU0FDVElPTl9CUk9LRVJfRU5WXVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcHJvY2Vzcy5lbnZbU0hBUkVEX1RSQU5TQUNUSU9OX0JST0tFUl9FTlZdID0gcmVnaXN0cmF0aW9uLnByZXZpb3VzRW52aXJvbm1lbnRcbiAgICAgIH1cbiAgICB9XG4gICAgYXdhaXQgcmVnaXN0cmF0aW9uLmJyb2tlci5jbG9zZSgpXG4gIH1cblxuICAvKipcbiAgICogUnVucyByZXF1ZXN0IGNsaWVudC5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVxdWVzdENsaWVudD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgcmVxdWVzdCBjbGllbnQuXG4gICAqL1xuICBhc3luYyByZXF1ZXN0Q2xpZW50KCkge1xuICAgIGlmICghdGhpcy5fcmVxdWVzdENsaWVudCkge1xuICAgICAgdGhpcy5fcmVxdWVzdENsaWVudCA9IG5ldyBSZXF1ZXN0Q2xpZW50KClcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fcmVxdWVzdENsaWVudFxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaW1wb3J0IHRlc3QgZmlsZXMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBpbXBvcnRUZXN0RmlsZXMoKSB7XG4gICAgY29uc3QgZW52aXJvbm1lbnRIYW5kbGVyID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuZ2V0RW52aXJvbm1lbnRIYW5kbGVyKClcblxuICAgIGlmICghdGhpcy5fcHJvZmlsZXIpIHtcbiAgICAgIGF3YWl0IGVudmlyb25tZW50SGFuZGxlci5pbXBvcnRUZXN0RmlsZXModGhpcy5nZXRUZXN0RmlsZXMoKSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGZvciAoY29uc3QgdGVzdEZpbGUgb2YgdGhpcy5nZXRUZXN0RmlsZXMoKSkge1xuICAgICAgY29uc3QgZXhpc3RpbmdSZWdpc3RyYXRpb25zID0gdGhpcy50ZXN0UmVnaXN0cmF0aW9uT2JqZWN0cygpXG5cbiAgICAgIGF3YWl0IHRoaXMuX3Byb2ZpbGVyLm1lYXN1cmVQaGFzZShcImltcG9ydHNcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCBlbnZpcm9ubWVudEhhbmRsZXIuaW1wb3J0VGVzdEZpbGVzKFt0ZXN0RmlsZV0pXG4gICAgICB9LCB7ZmlsZVBhdGg6IHRlc3RGaWxlfSlcbiAgICAgIHRoaXMuYXNzaWduVGVzdFJlZ2lzdHJhdGlvbk93bmVyc2hpcChleGlzdGluZ1JlZ2lzdHJhdGlvbnMsIHRlc3RGaWxlKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb2xsZWN0cyBwYWNrYWdlIGRlY2xhcmF0aW9uIG9iamVjdHMgYnkgaWRlbnRpdHkuXG4gICAqIEBwYXJhbSB7U2V0PFBhY2thZ2VSZWdpc3RyYXRpb24+fSBbcmVnaXN0cmF0aW9uc10gLSBBY2N1bXVsYXRlZCBpZGVudGl0aWVzLlxuICAgKiBAcmV0dXJucyB7U2V0PFBhY2thZ2VSZWdpc3RyYXRpb24+fSAtIFJlZ2lzdHJhdGlvbiBpZGVudGl0aWVzLlxuICAgKi9cbiAgdGVzdFJlZ2lzdHJhdGlvbk9iamVjdHMocmVnaXN0cmF0aW9ucyA9IG5ldyBTZXQoKSkge1xuICAgIGNvbnN0IHZpc2l0ID0gKC8qKiBAdHlwZSB7UGFja2FnZVN1aXRlRGVjbGFyYXRpb259ICovIHN1aXRlKSA9PiB7XG4gICAgICByZWdpc3RyYXRpb25zLmFkZChzdWl0ZSlcbiAgICAgIGZvciAoY29uc3QgaG9vayBvZiBbLi4uc3VpdGUuaG9va3MuYmVmb3JlQWxsLCAuLi5zdWl0ZS5ob29rcy5iZWZvcmVFYWNoLCAuLi5zdWl0ZS5ob29rcy5hZnRlckVhY2gsIC4uLnN1aXRlLmhvb2tzLmFmdGVyQWxsXSkge1xuICAgICAgICByZWdpc3RyYXRpb25zLmFkZChob29rKVxuICAgICAgfVxuICAgICAgZm9yIChjb25zdCB0ZXN0RGVjbGFyYXRpb24gb2Ygc3VpdGUudGVzdHMpIHJlZ2lzdHJhdGlvbnMuYWRkKHRlc3REZWNsYXJhdGlvbilcbiAgICAgIGZvciAoY29uc3QgY2hpbGRTdWl0ZSBvZiBzdWl0ZS5zdWl0ZXMpIHZpc2l0KGNoaWxkU3VpdGUpXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBzdWl0ZSBvZiB0aGlzLmdldFRlc3RDb250ZXh0KCkucmVnaXN0cnkuc3VpdGVzKSB2aXNpdChzdWl0ZSlcblxuICAgIHJldHVybiByZWdpc3RyYXRpb25zXG4gIH1cblxuICAvKipcbiAgICogQXNzaWducyBkZXRlcm1pbmlzdGljIG93bmVyc2hpcCB0byBwYWNrYWdlIGRlY2xhcmF0aW9ucyBhZGRlZCBieSBvbmUgZW50cnkgZmlsZS5cbiAgICogQHBhcmFtIHtTZXQ8UGFja2FnZVJlZ2lzdHJhdGlvbj59IHByZXZpb3VzUmVnaXN0cmF0aW9ucyAtIElkZW50aXRpZXMgcHJlc2VudCBiZWZvcmUgaW1wb3J0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3duZXJGaWxlUGF0aCAtIEltcG9ydGluZyBlbnRyeSBmaWxlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGFzc2lnblRlc3RSZWdpc3RyYXRpb25Pd25lcnNoaXAocHJldmlvdXNSZWdpc3RyYXRpb25zLCBvd25lckZpbGVQYXRoKSB7XG4gICAgZm9yIChjb25zdCByZWdpc3RyYXRpb24gb2YgdGhpcy50ZXN0UmVnaXN0cmF0aW9uT2JqZWN0cygpKSB7XG4gICAgICBpZiAoIXByZXZpb3VzUmVnaXN0cmF0aW9ucy5oYXMocmVnaXN0cmF0aW9uKSkgdGhpcy5fZGVjbGFyYXRpb25Pd25lcnMuc2V0KHJlZ2lzdHJhdGlvbiwgb3duZXJGaWxlUGF0aClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBpcyBmYWlsZWQuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgZmFpbGVkLlxuICAgKi9cbiAgaXNGYWlsZWQoKSB7IHJldHVybiB0aGlzLl9mYWlsZWRUZXN0cyAhPT0gdW5kZWZpbmVkICYmICh0aGlzLl9mYWlsZWRUZXN0cyA+IDAgfHwgdGhpcy5fcGFja2FnZVJlc3VsdD8uc3RhdHVzID09PSBcImZhaWxlZFwiKSB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IGZhaWxlZCB0ZXN0cy5cbiAgICogQHJldHVybnMge251bWJlcn0gLSBUaGUgZmFpbGVkIHRlc3RzLlxuICAgKi9cbiAgZ2V0RmFpbGVkVGVzdHMoKSB7XG4gICAgaWYgKHRoaXMuX2ZhaWxlZFRlc3RzID09PSB1bmRlZmluZWQpIHRocm93IG5ldyBFcnJvcihcIlRlc3RzIGhhc24ndCBiZWVuIHJ1biB5ZXRcIilcblxuICAgIHJldHVybiB0aGlzLl9mYWlsZWRUZXN0c1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IGZhaWxlZCB0ZXN0IGRldGFpbHMuXG4gICAqIEByZXR1cm5zIHtGYWlsZWRUZXN0RGV0YWlsW119IC0gRmFpbGVkIHRlc3QgZGV0YWlscy5cbiAgICovXG4gIGdldEZhaWxlZFRlc3REZXRhaWxzKCkge1xuICAgIHJldHVybiB0aGlzLl9mYWlsZWRUZXN0RGV0YWlsc1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcGVyc2lzdCBmYWlsZWQgdGVzdCBjb25zb2xlIG91dHB1dHMgdG8gYXNzZXRzLlxuICAgKiBAcGFyYW0ge29iamVjdH0gW2FyZ3NdIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYXJncy5hc3NldHNQYXRoXSAtIEFzc2V0cyBkaXJlY3RvcnkgcGF0aC5cbiAgICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nW10+fSAtIFdyaXR0ZW4gbG9nIGZpbGUgcGF0aHMuXG4gICAqL1xuICBhc3luYyBwZXJzaXN0RmFpbGVkVGVzdENvbnNvbGVPdXRwdXRzVG9Bc3NldHMoe2Fzc2V0c1BhdGggPSBwYXRoLmpvaW4ocHJvY2Vzcy5jd2QoKSwgXCJ0bXAvc2NyZWVuc2hvdHNcIil9ID0ge30pIHtcbiAgICBjb25zdCBmYWlsZWRUZXN0RGV0YWlscyA9IHRoaXMuZ2V0RmFpbGVkVGVzdERldGFpbHMoKVxuICAgIGNvbnN0IHdyaXR0ZW5Mb2dQYXRocyA9IFtdXG4gICAgbGV0IGNyZWF0ZWREaXJlY3RvcnkgPSBmYWxzZVxuXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGZhaWxlZFRlc3REZXRhaWxzLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgY29uc3QgZmFpbGVkVGVzdERldGFpbCA9IGZhaWxlZFRlc3REZXRhaWxzW2luZGV4XVxuICAgICAgY29uc3QgY29uc29sZU91dHB1dCA9IGZhaWxlZFRlc3REZXRhaWwuY29uc29sZU91dHB1dFxuXG4gICAgICBpZiAoIWNvbnNvbGVPdXRwdXQpIGNvbnRpbnVlXG5cbiAgICAgIGlmICghY3JlYXRlZERpcmVjdG9yeSkge1xuICAgICAgICBhd2FpdCBmcy5ta2Rpcihhc3NldHNQYXRoLCB7cmVjdXJzaXZlOiB0cnVlfSlcbiAgICAgICAgY3JlYXRlZERpcmVjdG9yeSA9IHRydWVcbiAgICAgIH1cblxuICAgICAgY29uc3Qgbm93ID0gbmV3IERhdGUoKVxuICAgICAgY29uc3QgdGltZXN0YW1wID0gW1xuICAgICAgICBTdHJpbmcobm93LmdldEZ1bGxZZWFyKCkpLFxuICAgICAgICBTdHJpbmcobm93LmdldE1vbnRoKCkgKyAxKS5wYWRTdGFydCgyLCBcIjBcIiksXG4gICAgICAgIFN0cmluZyhub3cuZ2V0RGF0ZSgpKS5wYWRTdGFydCgyLCBcIjBcIiksXG4gICAgICAgIFN0cmluZyhub3cuZ2V0SG91cnMoKSkucGFkU3RhcnQoMiwgXCIwXCIpLFxuICAgICAgICBTdHJpbmcobm93LmdldE1pbnV0ZXMoKSkucGFkU3RhcnQoMiwgXCIwXCIpLFxuICAgICAgICBTdHJpbmcobm93LmdldFNlY29uZHMoKSkucGFkU3RhcnQoMiwgXCIwXCIpLFxuICAgICAgICBTdHJpbmcobm93LmdldE1pbGxpc2Vjb25kcygpKS5wYWRTdGFydCgzLCBcIjBcIilcbiAgICAgIF0uam9pbihcIlwiKVxuICAgICAgY29uc3Qgc2x1ZyA9IHRvRmlsZVNsdWcoZmFpbGVkVGVzdERldGFpbC5mdWxsRGVzY3JpcHRpb24pXG4gICAgICBjb25zdCBmaWxlTmFtZSA9IGAke3RpbWVzdGFtcH0tJHtTdHJpbmcoaW5kZXggKyAxKS5wYWRTdGFydCgyLCBcIjBcIil9LSR7c2x1Z30uY29uc29sZS5sb2dgXG4gICAgICBjb25zdCBmaWxlUGF0aCA9IHBhdGguam9pbihhc3NldHNQYXRoLCBmaWxlTmFtZSlcblxuICAgICAgYXdhaXQgZnMud3JpdGVGaWxlKGZpbGVQYXRoLCBjb25zb2xlT3V0cHV0LCBcInV0ZjhcIilcbiAgICAgIGZhaWxlZFRlc3REZXRhaWwuY29uc29sZUxvZ1BhdGggPSBmaWxlUGF0aFxuICAgICAgd3JpdHRlbkxvZ1BhdGhzLnB1c2goZmlsZVBhdGgpXG4gICAgfVxuXG4gICAgcmV0dXJuIHdyaXR0ZW5Mb2dQYXRoc1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IHN1Y2Nlc3NmdWwgdGVzdHMuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gVGhlIHN1Y2Nlc3NmdWwgdGVzdHMuXG4gICAqL1xuICBnZXRTdWNjZXNzZnVsVGVzdHMoKSB7XG4gICAgaWYgKHRoaXMuX3N1Y2Nlc3NmdWxUZXN0cyA9PT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgRXJyb3IoXCJUZXN0cyBoYXNuJ3QgYmVlbiBydW4geWV0XCIpXG5cbiAgICByZXR1cm4gdGhpcy5fc3VjY2Vzc2Z1bFRlc3RzXG4gIH1cblxuICAvKipcbiAgICogUnVucyBnZXQgdGVzdHMgY291bnQuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gVGhlIHRlc3RzIGNvdW50LlxuICAgKi9cbiAgZ2V0VGVzdHNDb3VudCgpIHtcbiAgICBpZiAodGhpcy5fdGVzdHNDb3VudCA9PT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgRXJyb3IoXCJUZXN0cyBoYXNuJ3QgYmVlbiBydW4geWV0XCIpXG5cbiAgICByZXR1cm4gdGhpcy5fdGVzdHNDb3VudFxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IGV4ZWN1dGVkIHRlc3RzIGNvdW50LlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIFRoZSBleGVjdXRlZCB0ZXN0cyBjb3VudC5cbiAgICovXG4gIGdldEV4ZWN1dGVkVGVzdHNDb3VudCgpIHtcbiAgICByZXR1cm4gdGhpcy5fcGFja2FnZVJlc3VsdD8udGVzdHMubGVuZ3RoID8/IHRoaXMuX3Rlc3REdXJhdGlvbnMubGVuZ3RoXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgdGVzdHMgcmVjb3JkZWQgZHVyaW5nIHRoZSBydW4sIHNsb3dlc3QgZmlyc3QuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbbGltaXRdIC0gTWF4aW11bSBudW1iZXIgb2YgdGVzdHMgdG8gcmV0dXJuICgwIHJldHVybnMgYWxsKS5cbiAgICogQHJldHVybnMge0FycmF5PHtmdWxsRGVzY3JpcHRpb246IHN0cmluZywgZmlsZVBhdGg6IHN0cmluZywgbGluZTogbnVtYmVyLCBkdXJhdGlvbk1zOiBudW1iZXJ9Pn0gLSBTbG93ZXN0IHRlc3RzLCBzbG93ZXN0IGZpcnN0LlxuICAgKi9cbiAgZ2V0U2xvd2VzdFRlc3RzKGxpbWl0ID0gMTApIHtcbiAgICBjb25zdCBzb3J0ZWQgPSBbLi4udGhpcy5fdGVzdER1cmF0aW9uc10uc29ydCgodGVzdEEsIHRlc3RCKSA9PiB0ZXN0Qi5kdXJhdGlvbk1zIC0gdGVzdEEuZHVyYXRpb25NcylcblxuICAgIHJldHVybiBsaW1pdCA+IDAgPyBzb3J0ZWQuc2xpY2UoMCwgbGltaXQpIDogc29ydGVkXG4gIH1cblxuICAvKipcbiAgICogUnVucyBwcmVwYXJlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgcHJlcGFyZSgpIHtcbiAgICB0aGlzLmFueVRlc3RzRm9jdXNzZWQgPSBmYWxzZVxuICAgIHRoaXMuX2ZhaWxlZFRlc3RzID0gMFxuICAgIHRoaXMuX3N1Y2Nlc3NmdWxUZXN0cyA9IDBcbiAgICB0aGlzLl90ZXN0c0NvdW50ID0gMFxuICAgIHRoaXMuX2Fib3J0UmVtYWluaW5nVGVzdHMgPSBmYWxzZVxuICAgIHRoaXMuX2ZhaWxlZFRlc3REZXRhaWxzID0gW11cbiAgICB0aGlzLl90ZXN0RHVyYXRpb25zID0gW11cbiAgICB0aGlzLl90ZXN0Q29tcGF0aWJpbGl0eSA9IG5ldyBXZWFrTWFwKClcbiAgICB0aGlzLl9pbmplY3RlZFRlc3RzID0gbmV3IFdlYWtTZXQoKVxuICAgIHRoaXMuX2NvbXBsZXRlZFRlc3RzID0gbmV3IFdlYWtTZXQoKVxuICAgIHRoaXMuX3Rlc3RNZXRhZGF0YSA9IG5ldyBXZWFrTWFwKClcbiAgICB0aGlzLl9ob29rTWV0YWRhdGEgPSBuZXcgV2Vha01hcCgpXG4gICAgdGhpcy5fYXR0ZW1wdE91dGNvbWVzID0gbmV3IFdlYWtNYXAoKVxuICAgIHRoaXMuX3N1aXRlSG9va0ZhaWx1cmVzID0gW11cbiAgICB0aGlzLl90ZXN0c0J5RnVsbE5hbWUgPSBuZXcgTWFwKClcbiAgICB0aGlzLl9wYWNrYWdlUmVzdWx0ID0gdW5kZWZpbmVkXG4gICAgY29uc3QgY29udGV4dCA9IHRoaXMuZ2V0VGVzdENvbnRleHQoKVxuICAgIC8qKiBAdHlwZSB7c3RyaW5nIHwgdW5kZWZpbmVkfSAqL1xuICAgIGxldCBvd25lckZpbGVQYXRoXG5cbiAgICBjb250ZXh0LnJlc2V0KHtjb25maWc6IHRydWV9KVxuICAgIGNvbnRleHQuc2V0RGVjbGFyYXRpb25Mb2NhdG9yKCgpID0+IHRoaXMuY2FwdHVyZVRlc3REZWNsYXJhdGlvbkxvY2F0aW9uKG93bmVyRmlsZVBhdGgpKVxuICAgIGNvbnN0IHRlc3RpbmdDb25maWdQYXRoID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuZ2V0VGVzdGluZygpXG5cbiAgICBhd2FpdCBjb250ZXh0LmRlc2NyaWJlKFwiXCIsIHtkYXRhYmFzZUNsZWFuaW5nOiB7dHJhbnNhY3Rpb246IHRydWV9fSwgYXN5bmMgKCkgPT4ge1xuICAgICAgaWYgKHRlc3RpbmdDb25maWdQYXRoKSB7XG4gICAgICAgIGF3YWl0IHRoaXMucnVuUHJvZmlsZVNwYW4oe3BoYXNlOiBcInRlc3RpbmcgY29uZmlnL2dsb2JhbCBzZXR1cFwifSwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGF3YWl0IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLmdldEVudmlyb25tZW50SGFuZGxlcigpLmltcG9ydFRlc3RpbmdDb25maWdQYXRoKClcbiAgICAgICAgfSlcbiAgICAgIH1cblxuICAgICAgaWYgKCF0aGlzLl9wcm9maWxlcikge1xuICAgICAgICBhd2FpdCB0aGlzLmltcG9ydFRlc3RGaWxlcygpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGNvbnN0IHRlc3RGaWxlIG9mIHRoaXMuZ2V0VGVzdEZpbGVzKCkpIHtcbiAgICAgICAgICBvd25lckZpbGVQYXRoID0gdGVzdEZpbGVcbiAgICAgICAgICBjb25zdCBleGlzdGluZ1JlZ2lzdHJhdGlvbnMgPSB0aGlzLnRlc3RSZWdpc3RyYXRpb25PYmplY3RzKClcblxuICAgICAgICAgIGF3YWl0IHRoaXMuX3Byb2ZpbGVyLm1lYXN1cmVQaGFzZShcImltcG9ydHNcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuZ2V0RW52aXJvbm1lbnRIYW5kbGVyKCkuaW1wb3J0VGVzdEZpbGVzKFt0ZXN0RmlsZV0pXG4gICAgICAgICAgfSwge2ZpbGVQYXRoOiB0ZXN0RmlsZX0pXG4gICAgICAgICAgdGhpcy5hc3NpZ25UZXN0UmVnaXN0cmF0aW9uT3duZXJzaGlwKGV4aXN0aW5nUmVnaXN0cmF0aW9ucywgdGVzdEZpbGUpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KVxuICAgIG93bmVyRmlsZVBhdGggPSB1bmRlZmluZWRcbiAgICB0aGlzLmFuYWx5emVEZWNsYXJhdGlvbnMoKVxuICB9XG5cbiAgLyoqXG4gICAqIENhcHR1cmVzIGEgdGVzdCBzb3VyY2UgbG9jYXRpb24gd2l0aG91dCBhdHRyaWJ1dGluZyBwYWNrYWdlL2ZhY2FkZSBmcmFtZXMuXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgdW5kZWZpbmVkfSBvd25lckZpbGVQYXRoIC0gSW1wb3J0aW5nIGVudHJ5IGZpbGUgZmFsbGJhY2suXG4gICAqIEByZXR1cm5zIHt7ZmlsZVBhdGg/OiBzdHJpbmcsIGxpbmU/OiBudW1iZXJ9fSAtIERlY2xhcmF0aW9uIGxvY2F0aW9uLlxuICAgKi9cbiAgY2FwdHVyZVRlc3REZWNsYXJhdGlvbkxvY2F0aW9uKG93bmVyRmlsZVBhdGgpIHtcbiAgICBjb25zdCBzdGFjayA9IG5ldyBFcnJvcigpLnN0YWNrPy5zcGxpdChcIlxcblwiKSB8fCBbXVxuXG4gICAgZm9yIChjb25zdCBzdGFja0xpbmUgb2Ygc3RhY2spIHtcbiAgICAgIGNvbnN0IG1hdGNoID0gc3RhY2tMaW5lLm1hdGNoKC8oPzpcXCh8XFxzKShmaWxlOlxcL1xcLy4qP3xcXC9bXlwiXSo/KTooXFxkKyk6KFxcZCspXFwpPyQvdSlcbiAgICAgIGlmICghbWF0Y2gpIGNvbnRpbnVlXG5cbiAgICAgIGxldCBmaWxlUGF0aCA9IG1hdGNoWzFdXG4gICAgICBpZiAoZmlsZVBhdGguc3RhcnRzV2l0aChcImZpbGU6Ly9cIikpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBmaWxlUGF0aCA9IGZpbGVVUkxUb1BhdGgoZmlsZVBhdGgpXG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlc29sdmVkRmlsZVBhdGggPSBwYXRoLnJlc29sdmUoZmlsZVBhdGgpXG4gICAgICBjb25zdCBwb3J0YWJsZVBhdGggPSByZXNvbHZlZEZpbGVQYXRoLnJlcGxhY2VBbGwocGF0aC5zZXAsIFwiL1wiKVxuXG4gICAgICBpZiAocG9ydGFibGVQYXRoLmVuZHNXaXRoKFwiL3NyYy90ZXN0aW5nL3Rlc3QtcnVubmVyLmpzXCIpKSBjb250aW51ZVxuICAgICAgaWYgKHBvcnRhYmxlUGF0aC5lbmRzV2l0aChcIi9zcmMvdGVzdGluZy90ZXN0LmpzXCIpKSBjb250aW51ZVxuICAgICAgaWYgKHBvcnRhYmxlUGF0aC5pbmNsdWRlcyhcIi9ub2RlX21vZHVsZXMvQHZlbG9jaW91cy90ZXN0aW5nL1wiKSkgY29udGludWVcblxuICAgICAgcmV0dXJuIHtmaWxlUGF0aDogcmVzb2x2ZWRGaWxlUGF0aCwgbGluZTogTnVtYmVyKG1hdGNoWzJdKX1cbiAgICB9XG5cbiAgICByZXR1cm4gb3duZXJGaWxlUGF0aCA/IHtmaWxlUGF0aDogb3duZXJGaWxlUGF0aH0gOiB7fVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYXJlIGFueSB0ZXN0cyBmb2N1c3NlZC5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciBhbnkgdGVzdHMgZm9jdXNzZWQuXG4gICAqL1xuICBhcmVBbnlUZXN0c0ZvY3Vzc2VkKCkge1xuICAgIGlmICh0aGlzLmFueVRlc3RzRm9jdXNzZWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSGFzbid0IGJlZW4gZGV0ZWN0ZWQgeWV0XCIpXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuYW55VGVzdHNGb2N1c3NlZFxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcnVuLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgLyoqXG4gICAqIFJlY29yZHMgYW4gYXN5bmNocm9ub3VzIGNyYXNoIChhbiB1bmhhbmRsZWQgcHJvbWlzZSByZWplY3Rpb24gZGV0YWNoZWQgZnJvbVxuICAgKiBhbnkgYXdhaXQsIGUuZy4gYSBgdm9pZCBjb25uZWN0aW9uLmFmdGVyQ29tbWl0KGFzeW5jICgpID0+IGJyb2FkY2FzdCguLi4pKWBcbiAgICogZnJvbnRlbmQtbW9kZWwgcHVibGlzaCDigJQgb3IgYSBzeW5jaHJvbm91cyB0aHJvdyBpbnNpZGUgYSBkZXRhY2hlZCBjYWxsYmFja1xuICAgKiBzdWNoIGFzIGEgZHJpdmVyIHNvY2tldCBvciB0aW1lciBjYWxsYmFjaykgYXMgYSByZWFsLCB2aXNpYmxlLCBhdHRyaWJ1dGVkXG4gICAqIHRlc3QgZmFpbHVyZS5cbiAgICpcbiAgICogV2l0aG91dCB0aGlzLCBzdWNoIGEgcmVqZWN0aW9uL2V4Y2VwdGlvbiBoYXMgbm8gaGFuZGxlciwgc28gb24gbW9kZXJuIE5vZGVcbiAgICogdGhlIHByb2Nlc3MgaXMgVEVSTUlOQVRFRCDigJQgdGhlIHJ1biBlbmRzIHdpdGggbm8gcmVwb3J0ZWQgZmFpbHVyZXMgYW5kIENJXG4gICAqIGp1c3Qgc2VlcyBhIGNyYXNoZWQvcmV0cmllZCBzaGFyZCB3aXRoIGFuIGVtcHR5IHJlc3VsdCAodGhlIHJlY3VycmluZ1xuICAgKiBcInNpbGVudCB0ZXN0LXJ1bm5lciBkZWF0aFwiOiBpbnZpc2libGUgYW5kIGltcG9zc2libGUgdG8gZGlhZ25vc2UpLiBUdXJuaW5nXG4gICAqIGl0IGludG8gYSBmYWlsdXJlIG1ha2VzIHRoZSBydW4gZ28gcmVkIHdpdGggc29tZXRoaW5nIGRlYnVnZ2FibGUgaW5zdGVhZCBvZlxuICAgKiB2YW5pc2hpbmcuXG4gICAqIEBwYXJhbSB7XCJ1bmNhdWdodEV4Y2VwdGlvblwiIHwgXCJ1bmhhbmRsZWRSZWplY3Rpb25cIn0ga2luZCAtIEFzeW5jLWNyYXNoIGtpbmQuXG4gICAqIEBwYXJhbSB7dW5rbm93bn0gcmVhc29uIC0gUmVqZWN0aW9uIHJlYXNvbiBvciB0aHJvd24gZXJyb3IuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgcmVjb3JkQXN5bmNDcmFzaChraW5kLCByZWFzb24pIHtcbiAgICBjb25zdCBlcnJvciA9IHJlYXNvbiBpbnN0YW5jZW9mIEVycm9yID8gcmVhc29uIDogbmV3IEVycm9yKGAke2tpbmR9OiAke1N0cmluZyhyZWFzb24pfWApXG4gICAgY29uc3QgbmVhciA9IHRoaXMuX2xhc3RUZXN0Q29udGV4dFxuICAgIGNvbnN0IGF0dHJpYnV0aW9uID0gbmVhciA/IGAsIG5lYXIgdGVzdDogJHtuZWFyLmZ1bGxEZXNjcmlwdGlvbn0gKCR7bmVhci5maWxlUGF0aH06JHtuZWFyLmxpbmV9KWAgOiBcIlwiXG5cbiAgICB0aGlzLl9mYWlsZWRUZXN0cyA9ICh0aGlzLl9mYWlsZWRUZXN0cyB8fCAwKSArIDFcbiAgICB0aGlzLl9mYWlsZWRUZXN0RGV0YWlscy5wdXNoKHtcbiAgICAgIGZ1bGxEZXNjcmlwdGlvbjogYDwke2tpbmR9IGR1cmluZyB0ZXN0IHJ1biR7YXR0cmlidXRpb259PmAsXG4gICAgICBmaWxlUGF0aDogbmVhciA/IG5lYXIuZmlsZVBhdGggOiBcIjx0ZXN0IHJ1bm5lcj5cIixcbiAgICAgIGxpbmU6IG5lYXIgPyBuZWFyLmxpbmUgOiAwLFxuICAgICAgZXJyb3IsXG4gICAgICBjb25zb2xlT3V0cHV0OiB1bmRlZmluZWRcbiAgICB9KVxuXG4gICAgY29uc29sZS5lcnJvcihwaWNvY29sb3JzLnJlZChgXFxuW3Rlc3QtcnVubmVyXSAke2tpbmR9IGR1cmluZyB0aGUgdGVzdCBydW4g4oCUIHRoaXMgd291bGQgb3RoZXJ3aXNlIHRlcm1pbmF0ZSB0aGUgcHJvY2VzcyBzaWxlbnRseSBhbmQgc3VyZmFjZSBvbmx5IGFzIGEgY3Jhc2hlZC9yZXRyaWVkIHNoYXJkIHdpdGggemVybyByZXBvcnRlZCBmYWlsdXJlcy4ke2F0dHJpYnV0aW9ufWApKVxuICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpXG4gIH1cblxuICAvKipcbiAgICogUmVjb3JkcyBhIGNsZWFudXAgZmFpbHVyZSBhZnRlciB0aW1lb3V0IGhhbmRsaW5nIGhhcyBiZWd1bi5cbiAgICogQHBhcmFtIHt1bmtub3dufSByZWFzb24gLSBEZXRhY2hlZCBjbGVhbnVwIHJlamVjdGlvbi5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGNsZWFudXBOYW1lIC0gQ2xlYW51cCBvcGVyYXRpb24gbmFtZS5cbiAgICogQHBhcmFtIHtTZXQ8RXJyb3I+fSBbcmVjb3JkZWRFcnJvcnNdIC0gQXR0ZW1wdC1vd25lZCBjbGVhbnVwIGVycm9ycyBhbHJlYWR5IHJlcG9ydGVkLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHJlY29yZFRpbWVvdXRDbGVhbnVwRmFpbHVyZShyZWFzb24sIGNsZWFudXBOYW1lLCByZWNvcmRlZEVycm9ycykge1xuICAgIGNvbnN0IGVycm9yID0gcmVhc29uIGluc3RhbmNlb2YgRXJyb3IgPyByZWFzb24gOiBuZXcgRXJyb3IoYCR7Y2xlYW51cE5hbWV9IGNsZWFudXAgZmFpbGVkOiAke1N0cmluZyhyZWFzb24pfWApXG5cbiAgICBpZiAocmVjb3JkZWRFcnJvcnMpIHtcbiAgICAgIC8vIE11bHRpcGxlIGJvdW5kZWQgb2JzZXJ2ZXJzIGNhbiByZWNlaXZlIHRoZSBzYW1lIGRldGFjaGVkIGNsZWFudXAgcmVqZWN0aW9uLlxuICAgICAgaWYgKHJlY29yZGVkRXJyb3JzLmhhcyhlcnJvcikpIHJldHVyblxuICAgICAgcmVjb3JkZWRFcnJvcnMuYWRkKGVycm9yKVxuICAgIH1cblxuICAgIGNvbnN0IG5lYXIgPSB0aGlzLl9sYXN0VGVzdENvbnRleHRcbiAgICBjb25zdCBhdHRyaWJ1dGlvbiA9IG5lYXIgPyBgLCBuZWFyIHRlc3Q6ICR7bmVhci5mdWxsRGVzY3JpcHRpb259ICgke25lYXIuZmlsZVBhdGh9OiR7bmVhci5saW5lfSlgIDogXCJcIlxuXG4gICAgdGhpcy5fZmFpbGVkVGVzdHMgPSAodGhpcy5fZmFpbGVkVGVzdHMgfHwgMCkgKyAxXG4gICAgdGhpcy5fZmFpbGVkVGVzdERldGFpbHMucHVzaCh7XG4gICAgICBmdWxsRGVzY3JpcHRpb246IGA8JHtjbGVhbnVwTmFtZX0gZW1lcmdlbmN5IGNsZWFudXAgZmFpbHVyZSR7YXR0cmlidXRpb259PmAsXG4gICAgICBmaWxlUGF0aDogbmVhciA/IG5lYXIuZmlsZVBhdGggOiBcIjx0ZXN0IHJ1bm5lcj5cIixcbiAgICAgIGxpbmU6IG5lYXIgPyBuZWFyLmxpbmUgOiAwLFxuICAgICAgZXJyb3IsXG4gICAgICBjb25zb2xlT3V0cHV0OiB1bmRlZmluZWRcbiAgICB9KVxuXG4gICAgY29uc29sZS5lcnJvcihwaWNvY29sb3JzLnJlZChgXFxuW3Rlc3QtcnVubmVyXSAke2NsZWFudXBOYW1lfSBjbGVhbnVwIGZhaWxlZCBhZnRlciB0aW1lb3V0IGhhbmRsaW5nIGJlZ2FuLiR7YXR0cmlidXRpb259YCkpXG4gICAgY29uc29sZS5lcnJvcihlcnJvcilcbiAgfVxuXG4gIGFzeW5jIHJ1bigpIHtcbiAgICAvKipcbiAgICAgKiBIYW5kbGVzIGEgcHJvY2Vzcy1sZXZlbCB1bmhhbmRsZWQgcmVqZWN0aW9uIGR1cmluZyB0aGUgcnVuLlxuICAgICAqIEBwYXJhbSB7dW5rbm93bn0gcmVhc29uIC0gUmVqZWN0aW9uIHJlYXNvbi5cbiAgICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICAgKi9cbiAgICBjb25zdCBvblVuaGFuZGxlZFJlamVjdGlvbiA9IChyZWFzb24pID0+IHtcbiAgICAgIC8vIElmIGEgdGVzdCBhdHRhY2hlZCBpdHMgT1dOIHVuaGFuZGxlZFJlamVjdGlvbiBsaXN0ZW5lciwgaXQgaXNcbiAgICAgIC8vIGludGVudGlvbmFsbHkgb2JzZXJ2aW5nL3RyaWdnZXJpbmcgdGhlIHJlamVjdGlvbiAoZS5nLiBiZWFjb25cbiAgICAgIC8vIGVycm9yLXJlcG9ydGluZy1zcGVjLmpzKSDigJQgTm9kZSBkaXNwYXRjaGVzIHRvIEVWRVJZIGxpc3RlbmVyLCBzbyBhbHNvXG4gICAgICAvLyBmYWlsaW5nIHRoZSBzdWl0ZSBoZXJlIHdvdWxkIGJyZWFrIHRob3NlIHRlc3RzLiBEZWZlciB0byB0aGUgdGVzdCdzXG4gICAgICAvLyBoYW5kbGVyOyBvbmx5IHRyZWF0IGEgcmVqZWN0aW9uIGFzIGEgc2lsZW50LWRlYXRoIGNyYXNoIHdoZW4gb3VycyBpcyB0aGVcbiAgICAgIC8vIHNvbGUgbGlzdGVuZXIgKG5vIHBlcnNpc3RlbnQgZnJhbWV3b3JrIGxpc3RlbmVyIGV4aXN0cyB0byBtYXNrIHRoaXMpLlxuICAgICAgaWYgKHByb2Nlc3MubGlzdGVuZXJDb3VudChcInVuaGFuZGxlZFJlamVjdGlvblwiKSA+IDEpIHJldHVyblxuXG4gICAgICB0aGlzLnJlY29yZEFzeW5jQ3Jhc2goXCJ1bmhhbmRsZWRSZWplY3Rpb25cIiwgcmVhc29uKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhhbmRsZXMgYSBwcm9jZXNzLWxldmVsIHVuY2F1Z2h0IGV4Y2VwdGlvbiBkdXJpbmcgdGhlIHJ1biDigJQgYVxuICAgICAqIHN5bmNocm9ub3VzIHRocm93IGluc2lkZSBhIGRldGFjaGVkIGNhbGxiYWNrIChkcml2ZXIgc29ja2V0LCB0aW1lcixcbiAgICAgKiBldmVudCBlbWl0dGVyKSB0aGF0IG5vIHRlc3QgYXdhaXQgb2JzZXJ2ZXMuIFNhbWUgc2lsZW50LWRlYXRoIG1vZGUgYXNcbiAgICAgKiB1bmhhbmRsZWQgcmVqZWN0aW9uczogd2l0aG91dCBhIGhhbmRsZXIgdGhlIHByb2Nlc3MgZGllcyBtaWQtcnVuIGFuZCBDSVxuICAgICAqIHNlZXMgYSBjcmFzaGVkIHNoYXJkIHdpdGggemVybyByZXBvcnRlZCBmYWlsdXJlcy5cbiAgICAgKiBAcGFyYW0ge3Vua25vd259IGVycm9yIC0gVGhyb3duIGVycm9yLlxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxuICAgICAqL1xuICAgIGNvbnN0IG9uVW5jYXVnaHRFeGNlcHRpb24gPSAoZXJyb3IpID0+IHtcbiAgICAgIC8vIE1pcnJvciB0aGUgdW5oYW5kbGVkUmVqZWN0aW9uIGRlZmVycmFsOiBhIHRlc3Qgb2JzZXJ2aW5nL3RyaWdnZXJpbmdcbiAgICAgIC8vIHVuY2F1Z2h0IGV4Y2VwdGlvbnMgd2l0aCBpdHMgb3duIGxpc3RlbmVyIG93bnMgdGhlbS5cbiAgICAgIGlmIChwcm9jZXNzLmxpc3RlbmVyQ291bnQoXCJ1bmNhdWdodEV4Y2VwdGlvblwiKSA+IDEpIHJldHVyblxuXG4gICAgICB0aGlzLnJlY29yZEFzeW5jQ3Jhc2goXCJ1bmNhdWdodEV4Y2VwdGlvblwiLCBlcnJvcilcbiAgICB9XG5cbiAgICBwcm9jZXNzLm9uKFwidW5oYW5kbGVkUmVqZWN0aW9uXCIsIG9uVW5oYW5kbGVkUmVqZWN0aW9uKVxuICAgIHByb2Nlc3Mub24oXCJ1bmNhdWdodEV4Y2VwdGlvblwiLCBvblVuY2F1Z2h0RXhjZXB0aW9uKVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMucnVuUGFja2FnZVRlc3RzKClcblxuICAgICAgLy8gQSByZWplY3Rpb24gc2NoZWR1bGVkIGJ5IHRoZSBmaW5hbCB0ZXN0IChhIGRldGFjaGVkIHJlamVjdGVkIHByb21pc2UsXG4gICAgICAvLyBvciBhbiBhZnRlckNvbW1pdCBjYWxsYmFjayByZWplY3RpbmcgYXMgdGhlIHN1aXRlIGRyYWlucykgaXMgcmVwb3J0ZWRcbiAgICAgIC8vIGJ5IE5vZGUgb24gYSBMQVRFUiB0dXJuLiBEcmFpbiBhIGZldyB0dXJucyB3aGlsZSB0aGUgaGFuZGxlciBpcyBzdGlsbFxuICAgICAgLy8gYXR0YWNoZWQgc28gdGhvc2UgbGF0ZSByZWplY3Rpb25zIGFyZSByZWNvcmRlZCBpbnN0ZWFkIG9mIGVzY2FwaW5nIHRvXG4gICAgICAvLyB0aGUgZGVmYXVsdCBjcmFzaCBwYXRoIGFmdGVyIGNsZWFudXAuXG4gICAgICBmb3IgKGxldCBkcmFpblR1cm4gPSAwOyBkcmFpblR1cm4gPCAzOyBkcmFpblR1cm4rKykge1xuICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gc2V0SW1tZWRpYXRlKHJlc29sdmUpKVxuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBwcm9jZXNzLm9mZihcInVuaGFuZGxlZFJlamVjdGlvblwiLCBvblVuaGFuZGxlZFJlamVjdGlvbilcbiAgICAgIHByb2Nlc3Mub2ZmKFwidW5jYXVnaHRFeGNlcHRpb25cIiwgb25VbmNhdWdodEV4Y2VwdGlvbilcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBydW4gYWZ0ZXIgYWxscyBmb3IgYWN0aXZlIHNjb3Blcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjbGVhbnVwIGhvb2tzIGZpbmlzaC5cbiAgICovXG4gIGFzeW5jIHJ1bkFmdGVyQWxsc0ZvckFjdGl2ZVNjb3BlcygpIHtcbiAgICBjb25zdCBmYWlsdXJlU3RhcnQgPSB0aGlzLl9zdWl0ZUhvb2tGYWlsdXJlcy5sZW5ndGhcblxuICAgIGF3YWl0IHRoaXMuX3BhY2thZ2VSdW5uZXI/LmNsZWFudXBBY3RpdmVTdWl0ZXMoKVxuICAgIHRoaXMudGhyb3dBZnRlckFsbEZhaWx1cmVzKHRoaXMuX3N1aXRlSG9va0ZhaWx1cmVzLnNsaWNlKGZhaWx1cmVTdGFydCkpXG4gIH1cblxuICAvKiogQnVpbGRzIGRlY2xhcmF0aW9uIG1ldGFkYXRhIHVzZWQgb25seSBieSBmcmFtZXdvcmsgYWRhcHRlcnMgYW5kIHByb2plY3Rpb25zLiAqL1xuICBhbmFseXplRGVjbGFyYXRpb25zKCkge1xuICAgIGNvbnN0IHZpc2l0ID0gKC8qKiBAdHlwZSB7UGFja2FnZVN1aXRlRGVjbGFyYXRpb259ICovIHN1aXRlLCAvKiogQHR5cGUge1BhY2thZ2VTdWl0ZURlY2xhcmF0aW9uW119ICovIGFuY2VzdG9ycywgLyoqIEB0eXBlIHtzdHJpbmcgfCB1bmRlZmluZWR9ICovIHBhcmVudFByb2ZpbGVTY29wZUlkKSA9PiB7XG4gICAgICBjb25zdCBzdWl0ZXMgPSBbLi4uYW5jZXN0b3JzLCBzdWl0ZV1cbiAgICAgIGNvbnN0IGRlc2NyaXB0aW9ucyA9IHN1aXRlcy5tYXAoKGVudHJ5KSA9PiBlbnRyeS5uYW1lKS5maWx0ZXIoKG5hbWUpID0+IG5hbWUgIT09IFwiXCIpXG4gICAgICBjb25zdCBvd25lckZpbGVQYXRoID0gdGhpcy5fZGVjbGFyYXRpb25Pd25lcnMuZ2V0KHN1aXRlKSA/PyBzdWl0ZS5sb2NhdGlvbi5maWxlUGF0aFxuICAgICAgY29uc3QgcHJvZmlsZVNjb3BlSWQgPSB0aGlzLl9wcm9maWxlcj8uc2NvcGVJZChzdWl0ZSwge1xuICAgICAgICBkZXNjcmlwdGlvbnMsXG4gICAgICAgIGZpbGVQYXRoOiBvd25lckZpbGVQYXRoLFxuICAgICAgICBsaW5lOiBzdWl0ZS5sb2NhdGlvbi5saW5lLFxuICAgICAgICBwYXJlbnRJZDogcGFyZW50UHJvZmlsZVNjb3BlSWRcbiAgICAgIH0pXG5cbiAgICAgIGZvciAoY29uc3QgaG9va3Mgb2YgT2JqZWN0LnZhbHVlcyhzdWl0ZS5ob29rcykpIHtcbiAgICAgICAgaG9va3MuZm9yRWFjaCgoaG9vaywgZGVjbGFyYXRpb25JbmRleCkgPT4ge1xuICAgICAgICAgIHRoaXMuX2hvb2tNZXRhZGF0YS5zZXQoaG9vaywge1xuICAgICAgICAgICAgZGVjbGFyYXRpb25JbmRleCxcbiAgICAgICAgICAgIGRlY2xhcmF0aW9uU2NvcGVJZDogcHJvZmlsZVNjb3BlSWQsXG4gICAgICAgICAgICBvd25lckZpbGVQYXRoOiB0aGlzLl9kZWNsYXJhdGlvbk93bmVycy5nZXQoaG9vaykgPz8gaG9vay5sb2NhdGlvbi5maWxlUGF0aCA/PyBvd25lckZpbGVQYXRoXG4gICAgICAgICAgfSlcbiAgICAgICAgfSlcbiAgICAgIH1cblxuICAgICAgZm9yIChjb25zdCB0ZXN0RGVjbGFyYXRpb24gb2Ygc3VpdGUudGVzdHMpIHtcbiAgICAgICAgY29uc3QgZnVsbERlc2NyaXB0aW9uID0gdGhpcy5idWlsZEZ1bGxEZXNjcmlwdGlvbihkZXNjcmlwdGlvbnMsIHRlc3REZWNsYXJhdGlvbi5uYW1lKVxuICAgICAgICBjb25zdCBkZWNsYXJhdGlvbnMgPSB0aGlzLl90ZXN0c0J5RnVsbE5hbWUuZ2V0KGZ1bGxEZXNjcmlwdGlvbikgfHwgW11cblxuICAgICAgICBkZWNsYXJhdGlvbnMucHVzaCh0ZXN0RGVjbGFyYXRpb24pXG4gICAgICAgIHRoaXMuX3Rlc3RzQnlGdWxsTmFtZS5zZXQoZnVsbERlc2NyaXB0aW9uLCBkZWNsYXJhdGlvbnMpXG4gICAgICAgIHRoaXMuX3Rlc3RNZXRhZGF0YS5zZXQodGVzdERlY2xhcmF0aW9uLCB7XG4gICAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICAgIHRlc3REZXNjcmlwdGlvbjogdGVzdERlY2xhcmF0aW9uLm5hbWUsXG4gICAgICAgICAgZnVsbERlc2NyaXB0aW9uLFxuICAgICAgICAgIG93bmVyRmlsZVBhdGg6IHRoaXMuX2RlY2xhcmF0aW9uT3duZXJzLmdldCh0ZXN0RGVjbGFyYXRpb24pID8/IHRlc3REZWNsYXJhdGlvbi5sb2NhdGlvbi5maWxlUGF0aCA/PyBvd25lckZpbGVQYXRoLFxuICAgICAgICAgIHN1aXRlc1xuICAgICAgICB9KVxuICAgICAgICBjb25zdCBsZWdhY3lUZXN0RGF0YSA9IHRoaXMuX2xlZ2FjeUZpeHR1cmVEYXRhQnlGdWxsTmFtZT8uZ2V0KGZ1bGxEZXNjcmlwdGlvbilcbiAgICAgICAgaWYgKGxlZ2FjeVRlc3REYXRhKSB7XG4gICAgICAgICAgdGhpcy5fdGVzdENvbXBhdGliaWxpdHkuc2V0KHRlc3REZWNsYXJhdGlvbiwge1xuICAgICAgICAgICAgdGVzdEFyZ3M6IHRoaXMuX3Rlc3RBcmd1bWVudHMuY29weSh0ZXN0RGVjbGFyYXRpb24pLFxuICAgICAgICAgICAgdGVzdERhdGE6IGxlZ2FjeVRlc3REYXRhXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl90ZXN0c0NvdW50KytcbiAgICAgICAgaWYgKHRlc3REZWNsYXJhdGlvbi5zdGF0ZSA9PT0gXCJydW5cIiAmJiAodGVzdERlY2xhcmF0aW9uLmZvY3VzIHx8IHN1aXRlcy5zb21lKChlbnRyeSkgPT4gZW50cnkuZm9jdXMpKSkge1xuICAgICAgICAgIHRoaXMuYW55VGVzdHNGb2N1c3NlZCA9IHRydWVcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGNoaWxkU3VpdGUgb2Ygc3VpdGUuc3VpdGVzKSB2aXNpdChjaGlsZFN1aXRlLCBzdWl0ZXMsIHByb2ZpbGVTY29wZUlkKVxuICAgIH1cblxuICAgIGZvciAoY29uc3Qgc3VpdGUgb2YgdGhpcy5nZXRUZXN0Q29udGV4dCgpLnJlZ2lzdHJ5LnN1aXRlcykgdmlzaXQoc3VpdGUsIFtdLCB1bmRlZmluZWQpXG4gIH1cblxuICAvKipcbiAgICogR2V0cyBwYWNrYWdlIGhvb2sgY29tcGF0aWJpbGl0eSBtZXRhZGF0YS5cbiAgICogQHBhcmFtIHtQYWNrYWdlSG9va0RlY2xhcmF0aW9ufSBob29rIC0gUGFja2FnZSBob29rIGRlY2xhcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7e2RlY2xhcmF0aW9uSW5kZXg6IG51bWJlciwgZGVjbGFyYXRpb25TY29wZUlkOiBzdHJpbmcgfCB1bmRlZmluZWQsIG93bmVyRmlsZVBhdGg6IHN0cmluZyB8IHVuZGVmaW5lZH19IC0gSG9vayBtZXRhZGF0YS5cbiAgICovXG4gIGhvb2tNZXRhZGF0YShob29rKSB7XG4gICAgcmV0dXJuIHRoaXMuX2hvb2tNZXRhZGF0YS5nZXQoaG9vaykgfHwge2RlY2xhcmF0aW9uSW5kZXg6IDAsIGRlY2xhcmF0aW9uU2NvcGVJZDogdW5kZWZpbmVkLCBvd25lckZpbGVQYXRoOiBob29rLmxvY2F0aW9uLmZpbGVQYXRofVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgcGFja2FnZSB0ZXN0IGNvbXBhdGliaWxpdHkgbWV0YWRhdGEuXG4gICAqIEBwYXJhbSB7UGFja2FnZVRlc3REZWNsYXJhdGlvbn0gdGVzdCAtIFBhY2thZ2UgdGVzdCBkZWNsYXJhdGlvbi5cbiAgICogQHJldHVybnMge3tkZXNjcmlwdGlvbnM6IHN0cmluZ1tdLCB0ZXN0RGVzY3JpcHRpb246IHN0cmluZywgZnVsbERlc2NyaXB0aW9uOiBzdHJpbmcsIG93bmVyRmlsZVBhdGg6IHN0cmluZyB8IHVuZGVmaW5lZCwgc3VpdGVzOiBQYWNrYWdlU3VpdGVEZWNsYXJhdGlvbltdfX0gLSBEZWNsYXJhdGlvbiBtZXRhZGF0YS5cbiAgICovXG4gIHRlc3RNZXRhZGF0YSh0ZXN0KSB7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLl90ZXN0TWV0YWRhdGEuZ2V0KHRlc3QpXG4gICAgaWYgKCFtZXRhZGF0YSkgdGhyb3cgbmV3IEVycm9yKGBNaXNzaW5nIHBhY2thZ2UgdGVzdCBtZXRhZGF0YTogJHt0ZXN0Lm5hbWV9YClcbiAgICByZXR1cm4gbWV0YWRhdGFcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHN0YWJsZSBjb21wYXRpYmlsaXR5IGRhdGEgZm9yIGEgcGFja2FnZSBkZWNsYXJhdGlvbi5cbiAgICogQHBhcmFtIHtQYWNrYWdlVGVzdERlY2xhcmF0aW9ufSB0ZXN0IC0gUGFja2FnZSB0ZXN0IGRlY2xhcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7e3Rlc3RBcmdzOiBUZXN0QXJncywgdGVzdERhdGE6IFRlc3REYXRhfX0gLSBTdGFibGUgY29tcGF0aWJpbGl0eSBkYXRhLlxuICAgKi9cbiAgdGVzdERhdGEodGVzdCkge1xuICAgIGxldCBjb21wYXRpYmlsaXR5ID0gdGhpcy5fdGVzdENvbXBhdGliaWxpdHkuZ2V0KHRlc3QpXG5cbiAgICBpZiAoIWNvbXBhdGliaWxpdHkpIHtcbiAgICAgIGNvbnN0IHRlc3RBcmdzID0gdGhpcy5fdGVzdEFyZ3VtZW50cy5jb3B5KHRlc3QpXG4gICAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMudGVzdE1ldGFkYXRhKHRlc3QpXG4gICAgICBjb25zdCB0ZXN0RGF0YSA9IHtcbiAgICAgICAgYXJnczogdGVzdEFyZ3MsXG4gICAgICAgIGRlY2xhcmF0aW9uOiB0ZXN0LFxuICAgICAgICBmaWxlUGF0aDogdGVzdC5sb2NhdGlvbi5maWxlUGF0aCxcbiAgICAgICAgZnVuY3Rpb246IHRlc3QuY2FsbGJhY2ssXG4gICAgICAgIGxpbmU6IHRlc3QubG9jYXRpb24ubGluZSxcbiAgICAgICAgb3duZXJGaWxlUGF0aDogbWV0YWRhdGEub3duZXJGaWxlUGF0aFxuICAgICAgfVxuICAgICAgY29tcGF0aWJpbGl0eSA9IHt0ZXN0QXJncywgdGVzdERhdGF9XG4gICAgICB0aGlzLl90ZXN0Q29tcGF0aWJpbGl0eS5zZXQodGVzdCwgY29tcGF0aWJpbGl0eSlcbiAgICB9XG5cbiAgICByZXR1cm4gY29tcGF0aWJpbGl0eVxuICB9XG5cbiAgLyoqXG4gICAqIEluamVjdHMgZnJhbWV3b3JrIGNvbGxhYm9yYXRvcnMgaW50byBzdGFibGUgY29tcGF0aWJpbGl0eSBkYXRhIG9uY2UuXG4gICAqIEBwYXJhbSB7UGFja2FnZVRlc3REZWNsYXJhdGlvbn0gdGVzdCAtIFBhY2thZ2UgdGVzdCBkZWNsYXJhdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8e3Rlc3RBcmdzOiBUZXN0QXJncywgdGVzdERhdGE6IFRlc3REYXRhfT59IC0gSW5qZWN0ZWQgY29tcGF0aWJpbGl0eSBkYXRhLlxuICAgKi9cbiAgYXN5bmMgdGVzdENvbXBhdGliaWxpdHkodGVzdCkge1xuICAgIGNvbnN0IGNvbXBhdGliaWxpdHkgPSB0aGlzLnRlc3REYXRhKHRlc3QpXG5cbiAgICBpZiAoIXRoaXMuX2luamVjdGVkVGVzdHMuaGFzKHRlc3QpKSB7XG4gICAgICBhd2FpdCB0aGlzLl90ZXN0QXJndW1lbnRzLmluamVjdChjb21wYXRpYmlsaXR5LnRlc3RBcmdzKVxuICAgICAgdGhpcy5faW5qZWN0ZWRUZXN0cy5hZGQodGVzdClcbiAgICB9XG5cbiAgICByZXR1cm4gY29tcGF0aWJpbGl0eVxuICB9XG5cbiAgLyoqXG4gICAqIFJlY29yZHMgYSByYXcgZnJhbWV3b3JrIGF0dGVtcHQgb3V0Y29tZS5cbiAgICogQHBhcmFtIHtQYWNrYWdlVGVzdERlY2xhcmF0aW9ufSB0ZXN0IC0gUGFja2FnZSB0ZXN0IGRlY2xhcmF0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gYXR0ZW1wdE51bWJlciAtIE9uZS1iYXNlZCBhdHRlbXB0IG51bWJlci5cbiAgICogQHBhcmFtIHt7YWJvcnRSZW1haW5pbmdUZXN0czogYm9vbGVhbiwgZXJyb3I6IFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+LCBmYWlsZWQ6IGJvb2xlYW59fSBvdXRjb21lIC0gUmF3IGF0dGVtcHQgb3V0Y29tZS5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICByZWNvcmRBdHRlbXB0T3V0Y29tZSh0ZXN0LCBhdHRlbXB0TnVtYmVyLCBvdXRjb21lKSB7XG4gICAgY29uc3Qgb3V0Y29tZXMgPSB0aGlzLl9hdHRlbXB0T3V0Y29tZXMuZ2V0KHRlc3QpIHx8IG5ldyBNYXAoKVxuICAgIG91dGNvbWVzLnNldChhdHRlbXB0TnVtYmVyLCBvdXRjb21lKVxuICAgIHRoaXMuX2F0dGVtcHRPdXRjb21lcy5zZXQodGVzdCwgb3V0Y29tZXMpXG4gICAgaWYgKG91dGNvbWUuYWJvcnRSZW1haW5pbmdUZXN0cykgdGhpcy5fYWJvcnRSZW1haW5pbmdUZXN0cyA9IHRydWVcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGEgcmF3IGZyYW1ld29yayBhdHRlbXB0IG91dGNvbWUuXG4gICAqIEBwYXJhbSB7UGFja2FnZVRlc3REZWNsYXJhdGlvbn0gdGVzdCAtIFBhY2thZ2UgdGVzdCBkZWNsYXJhdGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGF0dGVtcHROdW1iZXIgLSBPbmUtYmFzZWQgYXR0ZW1wdCBudW1iZXIuXG4gICAqIEByZXR1cm5zIHt7YWJvcnRSZW1haW5pbmdUZXN0czogYm9vbGVhbiwgZXJyb3I6IFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+LCBmYWlsZWQ6IGJvb2xlYW59IHwgdW5kZWZpbmVkfSAtIFJhdyBhdHRlbXB0IG91dGNvbWUuXG4gICAqL1xuICBhdHRlbXB0T3V0Y29tZSh0ZXN0LCBhdHRlbXB0TnVtYmVyKSB7IHJldHVybiB0aGlzLl9hdHRlbXB0T3V0Y29tZXMuZ2V0KHRlc3QpPy5nZXQoYXR0ZW1wdE51bWJlcikgfVxuXG4gIC8qKlxuICAgKiBSZWNvcmRzIGEgcmF3IHN1aXRlLWhvb2sgZmFpbHVyZS5cbiAgICogQHBhcmFtIHtvYmplY3R9IGZhaWx1cmUgLSBTdWl0ZS1ob29rIGZhaWx1cmUuXG4gICAqIEBwYXJhbSB7UGFja2FnZVN1aXRlRGVjbGFyYXRpb259IGZhaWx1cmUuc3VpdGUgLSBPd25pbmcgcGFja2FnZSBzdWl0ZS5cbiAgICogQHBhcmFtIHtcImJlZm9yZUFsbFwiIHwgXCJhZnRlckFsbFwifSBmYWlsdXJlLnBoYXNlIC0gSG9vayBwaGFzZS5cbiAgICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gZmFpbHVyZS5lcnJvciAtIFJhdyBob29rIGZhaWx1cmUuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgcmVjb3JkU3VpdGVIb29rRmFpbHVyZShmYWlsdXJlKSB7IHRoaXMuX3N1aXRlSG9va0ZhaWx1cmVzLnB1c2goZmFpbHVyZSkgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSByYXcgYW5jZXN0b3Igc2V0dXAgZmFpbHVyZSBmb3IgYSBwYWNrYWdlIHRlc3QuXG4gICAqIEBwYXJhbSB7UGFja2FnZVRlc3REZWNsYXJhdGlvbn0gdGVzdCAtIFBhY2thZ2UgdGVzdCBkZWNsYXJhdGlvbi5cbiAgICogQHJldHVybnMge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSAtIFJhdyBzZXR1cCBmYWlsdXJlLlxuICAgKi9cbiAgc2V0dXBGYWlsdXJlRm9yKHRlc3QpIHtcbiAgICBjb25zdCBzdWl0ZXMgPSB0aGlzLnRlc3RNZXRhZGF0YSh0ZXN0KS5zdWl0ZXNcbiAgICByZXR1cm4gdGhpcy5fc3VpdGVIb29rRmFpbHVyZXMuZmluZCgoZmFpbHVyZSkgPT4gZmFpbHVyZS5waGFzZSA9PT0gXCJiZWZvcmVBbGxcIiAmJiBzdWl0ZXMuaW5jbHVkZXMoZmFpbHVyZS5zdWl0ZSkpPy5lcnJvclxuICB9XG5cbiAgLyoqXG4gICAqIEZpbmRzIHRoZSBuZXh0IGluY29tcGxldGUgZGVjbGFyYXRpb24gd2l0aCBhIHBhY2thZ2UgZnVsbCBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZnVsbE5hbWUgLSBQYWNrYWdlIGZ1bGwgbmFtZS5cbiAgICogQHJldHVybnMge1BhY2thZ2VUZXN0RGVjbGFyYXRpb24gfCB1bmRlZmluZWR9IC0gTmV4dCBtYXRjaGluZyBkZWNsYXJhdGlvbi5cbiAgICovXG4gIGZpbmRUZXN0RGVjbGFyYXRpb24oZnVsbE5hbWUpIHtcbiAgICByZXR1cm4gdGhpcy5fdGVzdHNCeUZ1bGxOYW1lLmdldChmdWxsTmFtZSk/LmZpbmQoKHRlc3QpID0+ICF0aGlzLl9jb21wbGV0ZWRUZXN0cy5oYXModGVzdCkpXG4gIH1cblxuICAvKipcbiAgICogTWFya3MgYSBwYWNrYWdlIGRlY2xhcmF0aW9uIGNvbXBsZXRlLlxuICAgKiBAcGFyYW0ge1BhY2thZ2VUZXN0RGVjbGFyYXRpb259IHRlc3QgLSBDb21wbGV0ZWQgZGVjbGFyYXRpb24uXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgY29tcGxldGVUZXN0RGVjbGFyYXRpb24odGVzdCkgeyB0aGlzLl9jb21wbGV0ZWRUZXN0cy5hZGQodGVzdCkgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBlZmZlY3RpdmUgcGFja2FnZSByZXRyeSBjb3VudC5cbiAgICogQHBhcmFtIHtQYWNrYWdlVGVzdERlY2xhcmF0aW9ufSB0ZXN0IC0gUGFja2FnZSB0ZXN0IGRlY2xhcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIEVmZmVjdGl2ZSByZXRyeSBjb3VudC5cbiAgICovXG4gIHJldHJ5Q291bnQodGVzdCkge1xuICAgIGNvbnN0IHZhbHVlID0gdGVzdC5vcHRpb25zLnJldHJpZXMgPz8gdGVzdC5vcHRpb25zLnJldHJ5ID8/IHRoaXMuZ2V0VGVzdENvbnRleHQoKS5jb25maWcucmV0cmllc1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgJiYgTnVtYmVyLmlzRmluaXRlKHZhbHVlKSA/IE1hdGgubWF4KDAsIE1hdGguZmxvb3IodmFsdWUpKSA6IDBcbiAgfVxuXG4gIC8qKlxuICAgKiBOb3JtYWxpemVzIHJldHJ5IGlucHV0cyBmb3IgdGhlIHBhY2thZ2UgZXhlY3V0aW9uIGJvdW5kYXJ5IHdoaWxlIHJldGFpbmluZ1xuICAgKiB0aGUgZGVjbGFyYXRpb25zJyBvcmlnaW5hbCBwdWJsaWMgb3B0aW9ucyBhZnRlciB0aGUgcnVuLlxuICAgKiBAcmV0dXJucyB7KCkgPT4gdm9pZH0gLSBSZXN0b3JlcyBvcmlnaW5hbCBkZWNsYXJhdGlvbiBvcHRpb25zLlxuICAgKi9cbiAgbm9ybWFsaXplUGFja2FnZVJldHJpZXNGb3JFeGVjdXRpb24oKSB7XG4gICAgLyoqIEB0eXBlIHtQYWNrYWdlUmV0cnlPcHRpb25SZXN0b3JhdGlvbltdfSAqL1xuICAgIGNvbnN0IHJlc3RvcmF0aW9ucyA9IFtdXG4gICAgLyoqXG4gICAgICogTm9ybWFsaXplcyBkZWNsYXJhdGlvbnMgaW4gb25lIHN1aXRlLlxuICAgICAqIEBwYXJhbSB7UGFja2FnZVN1aXRlRGVjbGFyYXRpb259IHN1aXRlIC0gU3VpdGUgd2hvc2UgdGVzdHMgYXJlIG5vcm1hbGl6ZWQuXG4gICAgICovXG4gICAgY29uc3QgdmlzaXQgPSAoc3VpdGUpID0+IHtcbiAgICAgIGZvciAoY29uc3QgdGVzdCBvZiBzdWl0ZS50ZXN0cykge1xuICAgICAgICAvLyBDYXB0dXJlIGNvbXBhdGliaWxpdHkgYXJndW1lbnRzIGJlZm9yZSB0ZW1wb3JhcmlseSBhZGFwdGluZyBwYWNrYWdlXG4gICAgICAgIC8vIGV4ZWN1dGlvbiBvcHRpb25zIHNvIGNhbGxiYWNrcyByZXRhaW4gdGhlaXIgZGVjbGFyZWQgdmFsdWVzL2lkZW50aXR5LlxuICAgICAgICB0aGlzLnRlc3REYXRhKHRlc3QpXG4gICAgICAgIHJlc3RvcmF0aW9ucy5wdXNoKHtcbiAgICAgICAgICBoYWRSZXRyaWVzOiBPYmplY3QuaGFzT3duKHRlc3Qub3B0aW9ucywgXCJyZXRyaWVzXCIpLFxuICAgICAgICAgIG9wdGlvbnM6IHRlc3Qub3B0aW9ucyxcbiAgICAgICAgICByZXRyaWVzOiB0ZXN0Lm9wdGlvbnMucmV0cmllc1xuICAgICAgICB9KVxuICAgICAgICB0ZXN0Lm9wdGlvbnMucmV0cmllcyA9IHRoaXMucmV0cnlDb3VudCh0ZXN0KVxuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGNoaWxkU3VpdGUgb2Ygc3VpdGUuc3VpdGVzKSB2aXNpdChjaGlsZFN1aXRlKVxuICAgIH1cblxuICAgIGZvciAoY29uc3Qgc3VpdGUgb2YgdGhpcy5nZXRUZXN0Q29udGV4dCgpLnJlZ2lzdHJ5LnN1aXRlcykgdmlzaXQoc3VpdGUpXG5cbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCByZXN0b3JhdGlvbiBvZiByZXN0b3JhdGlvbnMpIHtcbiAgICAgICAgaWYgKHJlc3RvcmF0aW9uLmhhZFJldHJpZXMpIHJlc3RvcmF0aW9uLm9wdGlvbnMucmV0cmllcyA9IHJlc3RvcmF0aW9uLnJldHJpZXNcbiAgICAgICAgZWxzZSBkZWxldGUgcmVzdG9yYXRpb24ub3B0aW9ucy5yZXRyaWVzXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlY29yZHMgb25lIGNvbXBsZXRlZCB0ZXN0IGR1cmF0aW9uLlxuICAgKiBAcGFyYW0ge3tkdXJhdGlvbk1zOiBudW1iZXIsIGZpbGVQYXRoOiBzdHJpbmcsIGZ1bGxEZXNjcmlwdGlvbjogc3RyaW5nLCBsaW5lOiBudW1iZXJ9fSBkdXJhdGlvbiAtIENvbXBsZXRlZCB0ZXN0IGR1cmF0aW9uLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHJlY29yZFRlc3REdXJhdGlvbihkdXJhdGlvbikgeyB0aGlzLl90ZXN0RHVyYXRpb25zLnB1c2goZHVyYXRpb24pIH1cblxuICAvKiogUmVjb3JkcyBvbmUgc3VjY2Vzc2Z1bCBwYWNrYWdlIHJlc3VsdC4gKi9cbiAgcmVjb3JkU3VjY2Vzc2Z1bFRlc3QoKSB7IHRoaXMuX3N1Y2Nlc3NmdWxUZXN0cysrIH1cblxuICAvKipcbiAgICogUmVjb3JkcyBvbmUgZmFpbGVkIHBhY2thZ2UgdGVzdCBpbiB0aGUgbGVnYWN5IHJlc3VsdCBwcm9qZWN0aW9uLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEZhaWxlZCB0ZXN0IG1ldGFkYXRhLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBhcmdzLmRlc2NyaXB0aW9ucyAtIFBhcmVudCBkZXNjcmlwdGlvbnMuXG4gICAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IGFyZ3MuZXJyb3IgLSBSYXcgZmFpbHVyZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuY29uc29sZU91dHB1dCAtIENhcHR1cmVkIGNvbnNvbGUgb3V0cHV0LlxuICAgKiBAcGFyYW0ge1Rlc3REYXRhfSBhcmdzLnRlc3REYXRhIC0gQ29tcGF0aWJpbGl0eSB0ZXN0IGRhdGEuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLnRlc3REZXNjcmlwdGlvbiAtIFRlc3QgZGVzY3JpcHRpb24uXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgcmVjb3JkRmFpbGVkVGVzdCh7ZGVzY3JpcHRpb25zLCBlcnJvciwgY29uc29sZU91dHB1dCwgdGVzdERhdGEsIHRlc3REZXNjcmlwdGlvbn0pIHtcbiAgICB0aGlzLl9mYWlsZWRUZXN0cysrXG4gICAgdGhpcy5fZmFpbGVkVGVzdERldGFpbHMucHVzaCh7XG4gICAgICBmdWxsRGVzY3JpcHRpb246IHRoaXMuYnVpbGRGdWxsRGVzY3JpcHRpb24oZGVzY3JpcHRpb25zLCB0ZXN0RGVzY3JpcHRpb24pLFxuICAgICAgZmlsZVBhdGg6IHRlc3REYXRhLmZpbGVQYXRoLFxuICAgICAgbGluZTogdGVzdERhdGEubGluZSxcbiAgICAgIGVycm9yLFxuICAgICAgY29uc29sZU91dHB1dDogY29uc29sZU91dHB1dCB8fCB1bmRlZmluZWRcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFN0b3JlcyB0aGUgY29tcGxldGVkIHBhY2thZ2UgcmVzdWx0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIkB2ZWxvY2lvdXMvdGVzdGluZy9ydW5uZXJcIikuVGVzdFJ1blJlc3VsdH0gcmVzdWx0IC0gUGFja2FnZSByZXN1bHQuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgcmVjb3JkUGFja2FnZVJlc3VsdChyZXN1bHQpIHsgdGhpcy5fcGFja2FnZVJlc3VsdCA9IHJlc3VsdCB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgdGhlIHBhY2thZ2Uga2VybmVsIHdpdGggVmVsb2Npb3VzIGZyYW1ld29yayBhZGFwdGVycy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgYWZ0ZXIgZXhlY3V0aW9uIGFuZCB0ZWFyZG93bi5cbiAgICovXG4gIGFzeW5jIHJ1blBhY2thZ2VUZXN0cygpIHtcbiAgICBjb25zdCBlbnZpcm9ubWVudEhhbmRsZXIgPSB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5nZXRFbnZpcm9ubWVudEhhbmRsZXIoKVxuICAgIGVudmlyb25tZW50SGFuZGxlci5pbnN0YWxsU2hhcmVkVHJhbnNhY3Rpb25Db29yZGluYXRvck93bmVyU3RvcmFnZSh0aGlzLl9zaGFyZWRUcmFuc2FjdGlvbkNvb3JkaW5hdG9yT3duZXJTdG9yYWdlKVxuICAgIGVudmlyb25tZW50SGFuZGxlci5pbnN0YWxsVGVzdERhdGFiYXNlQWNjZXNzU2NvcGVTdG9yYWdlKHRoaXMuX3Rlc3REYXRhYmFzZUFjY2Vzc1Njb3BlU3RvcmFnZSlcbiAgICB0aGlzLl9wYWNrYWdlUnVubmVyID0gbmV3IFBhY2thZ2VUZXN0UnVubmVyKHtcbiAgICAgIGNvbnRleHQ6IHRoaXMuZ2V0VGVzdENvbnRleHQoKSxcbiAgICAgIGluY2x1ZGVUYWdzOiB0aGlzLl9pbmNsdWRlVGFncyxcbiAgICAgIGV4Y2x1ZGVUYWdzOiBbLi4udGhpcy5nZXRFeGNsdWRlVGFnU2V0KCksIC4uLih0aGlzLmlzQnJvd3NlclRlc3RNb2RlKCkgPyBbXSA6IFtcImJyb3dzZXItb25seVwiXSldLFxuICAgICAgZXhhbXBsZXM6IHRoaXMuZ2V0RXhhbXBsZVBhdHRlcm5zKCksXG4gICAgICBsaW5lRmlsdGVyczogdGhpcy5nZXRMaW5lRmlsdGVycygpLFxuICAgICAgaW5jbHVkZVRhZ01vZGU6IFwiYW55XCIsXG4gICAgICBmb2N1c2VkVGVzdHNCeXBhc3NJbmNsdWRlVGFnczogdHJ1ZSxcbiAgICAgIG9taXRFbXB0eVN1aXRlTmFtZXM6IHRydWUsXG4gICAgICBhdHRlbXB0RXhlY3V0b3JPd25zVGltZW91dDogdHJ1ZSxcbiAgICAgIGF0dGVtcHRFeGVjdXRvcjogKGlucHV0KSA9PiB0aGlzLl9hdHRlbXB0RXhlY3V0b3IuZXhlY3V0ZShpbnB1dCksXG4gICAgICB0ZXN0QXJndW1lbnRSZXNvbHZlcjogKGlucHV0KSA9PiB0aGlzLl90ZXN0QXJndW1lbnRzLnJlc29sdmUoaW5wdXQpLFxuICAgICAgc3VpdGVIb29rRXhlY3V0b3I6IChpbnB1dCkgPT4gdGhpcy5fc3VpdGVIb29rRXhlY3V0b3IuZXhlY3V0ZShpbnB1dCksXG4gICAgICByZXBvcnRlcjogdGhpcy5fcnVubmVyUmVwb3J0ZXJcbiAgICB9KVxuICAgIGNvbnN0IGZhaWx1cmVTdGFydCA9IHRoaXMuX3N1aXRlSG9va0ZhaWx1cmVzLmxlbmd0aFxuICAgIGNvbnN0IHJlc3RvcmVSZXRyeU9wdGlvbnMgPSB0aGlzLm5vcm1hbGl6ZVBhY2thZ2VSZXRyaWVzRm9yRXhlY3V0aW9uKClcbiAgICBsZXQgcmVzdWx0XG5cbiAgICB0cnkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmVzdWx0ID0gYXdhaXQgdGhpcy5fcGFja2FnZVJ1bm5lci5ydW4oKVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKCEoZXJyb3IgaW5zdGFuY2VvZiBBYm9ydFJlbWFpbmluZ1Rlc3RzRXJyb3IpKSB0aHJvdyBlcnJvclxuXG4gICAgICAgIGNvbnN0IGFmdGVyQWxsID0gdGhpcy5hZnRlckFsbE91dGNvbWUodGhpcy5fc3VpdGVIb29rRmFpbHVyZXMuc2xpY2UoZmFpbHVyZVN0YXJ0KSlcbiAgICAgICAgaWYgKGFmdGVyQWxsLmZhaWxlZCkgdGhpcy5yZWNvcmRUaW1lb3V0Q2xlYW51cEZhaWx1cmUoYWZ0ZXJBbGwuZXJyb3IsIFwiYWZ0ZXJBbGxcIilcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIHRoaXMucmVjb3JkUGFja2FnZVJlc3VsdChyZXN1bHQpXG4gICAgICB0aGlzLnRocm93QWZ0ZXJBbGxGYWlsdXJlcyh0aGlzLl9zdWl0ZUhvb2tGYWlsdXJlcy5zbGljZShmYWlsdXJlU3RhcnQpKVxuICAgIH0gZmluYWxseSB7XG4gICAgICByZXN0b3JlUmV0cnlPcHRpb25zKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQWdncmVnYXRlcyByYXcgYWZ0ZXItYWxsIGZhaWx1cmVzIHdpdGhvdXQgdXNpbmcgZXJyb3IgdHJ1dGhpbmVzcy5cbiAgICogQHBhcmFtIHtBcnJheTx7cGhhc2U6IFwiYmVmb3JlQWxsXCIgfCBcImFmdGVyQWxsXCIsIGVycm9yOiBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0+fSBmYWlsdXJlcyAtIEhvb2sgZmFpbHVyZXMuXG4gICAqIEByZXR1cm5zIHt7ZmFpbGVkOiBmYWxzZX0gfCB7ZmFpbGVkOiB0cnVlLCBlcnJvcjogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59fSAtIEV4cGxpY2l0IGFmdGVyQWxsIG91dGNvbWUuXG4gICAqL1xuICBhZnRlckFsbE91dGNvbWUoZmFpbHVyZXMpIHtcbiAgICBjb25zdCBhZnRlckFsbEVycm9ycyA9IGZhaWx1cmVzLmZpbHRlcigoZmFpbHVyZSkgPT4gZmFpbHVyZS5waGFzZSA9PT0gXCJhZnRlckFsbFwiKS5tYXAoKGZhaWx1cmUpID0+IGZhaWx1cmUuZXJyb3IpXG5cbiAgICBpZiAoYWZ0ZXJBbGxFcnJvcnMubGVuZ3RoID09PSAwKSByZXR1cm4ge2ZhaWxlZDogZmFsc2V9XG4gICAgaWYgKGFmdGVyQWxsRXJyb3JzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIHtmYWlsZWQ6IHRydWUsIGVycm9yOiBhZnRlckFsbEVycm9yc1swXX1cbiAgICByZXR1cm4ge1xuICAgICAgZmFpbGVkOiB0cnVlLFxuICAgICAgZXJyb3I6IG5ldyBBZ2dyZWdhdGVFcnJvcihhZnRlckFsbEVycm9ycywgXCJNdWx0aXBsZSBhY3RpdmUgYWZ0ZXJBbGwgc2NvcGVzIGZhaWxlZFwiLCB7Y2F1c2U6IGFmdGVyQWxsRXJyb3JzWzBdfSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGhyb3dzIG9uZSByYXcgb3IgYWdncmVnYXRlZCBhZnRlci1hbGwgZmFpbHVyZS5cbiAgICogQHBhcmFtIHtBcnJheTx7cGhhc2U6IFwiYmVmb3JlQWxsXCIgfCBcImFmdGVyQWxsXCIsIGVycm9yOiBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0+fSBmYWlsdXJlcyAtIEhvb2sgZmFpbHVyZXMuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgdGhyb3dBZnRlckFsbEZhaWx1cmVzKGZhaWx1cmVzKSB7XG4gICAgY29uc3QgYWZ0ZXJBbGwgPSB0aGlzLmFmdGVyQWxsT3V0Y29tZShmYWlsdXJlcylcblxuICAgIGlmIChhZnRlckFsbC5mYWlsZWQpIHRocm93IGFmdGVyQWxsLmVycm9yXG4gIH1cblxuICAvKipcbiAgICogQ29tcGF0aWJpbGl0eSBoZWxwZXIgZm9yIGZvY3VzZWQgZnJhbWV3b3JrIGxpZmVjeWNsZSBzcGVjcy4gSXQgY29udmVydHMgYW5cbiAgICogZXhwbGljaXQgbGVnYWN5IGZpeHR1cmUgaW50byBpc29sYXRlZCBwYWNrYWdlIGRlY2xhcmF0aW9uczsgdGhlIHBhY2thZ2VcbiAgICogcnVubmVyIHJlbWFpbnMgdGhlIHNvbGUgZXhlY3V0aW9uIGVuZ2luZS5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBMZWdhY3kgZml4dHVyZSBhcmd1bWVudHMuXG4gICAqIEBwYXJhbSB7VGVzdHNBcmd1bWVudH0gYXJncy50ZXN0cyAtIEZpeHR1cmUgdHJlZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgYWZ0ZXIgcGFja2FnZSBleGVjdXRpb24uXG4gICAqL1xuICBhc3luYyBydW5UZXN0cyh7dGVzdHN9KSB7XG4gICAgY29uc3QgY29udGV4dCA9IGNyZWF0ZVRlc3RDb250ZXh0KClcbiAgICBjb25zdCBvcmlnaW5hbENvbnRleHQgPSB0aGlzLl9jb250ZXh0XG4gICAgY29udGV4dC5jb25maWd1cmVUZXN0cyh7XG4gICAgICBjb25zb2xlT3V0cHV0OiBvcmlnaW5hbENvbnRleHQuY29uZmlnLmNvbnNvbGVPdXRwdXQsXG4gICAgICBkZWZhdWx0VGltZW91dE1zOiBvcmlnaW5hbENvbnRleHQuY29uZmlnLmRlZmF1bHRUaW1lb3V0TXMsXG4gICAgICBleGNsdWRlVGFnczogb3JpZ2luYWxDb250ZXh0LmNvbmZpZy5leGNsdWRlVGFncyxcbiAgICAgIGZhaWxlZENvbnNvbGVPdXRwdXRNYXhMaW5lczogb3JpZ2luYWxDb250ZXh0LmNvbmZpZy5mYWlsZWRDb25zb2xlT3V0cHV0TWF4TGluZXMsXG4gICAgICByZXRyaWVzOiBvcmlnaW5hbENvbnRleHQuY29uZmlnLnJldHJpZXNcbiAgICB9KVxuICAgIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0XG4gICAgdGhpcy5fdGVzdHNDb3VudCA9IDBcbiAgICB0aGlzLl90ZXN0Q29tcGF0aWJpbGl0eSA9IG5ldyBXZWFrTWFwKClcbiAgICB0aGlzLl9pbmplY3RlZFRlc3RzID0gbmV3IFdlYWtTZXQoKVxuICAgIHRoaXMuX2NvbXBsZXRlZFRlc3RzID0gbmV3IFdlYWtTZXQoKVxuICAgIHRoaXMuX3Rlc3RNZXRhZGF0YSA9IG5ldyBXZWFrTWFwKClcbiAgICB0aGlzLl9ob29rTWV0YWRhdGEgPSBuZXcgV2Vha01hcCgpXG4gICAgdGhpcy5fYXR0ZW1wdE91dGNvbWVzID0gbmV3IFdlYWtNYXAoKVxuICAgIHRoaXMuX3N1aXRlSG9va0ZhaWx1cmVzID0gW11cbiAgICB0aGlzLl90ZXN0c0J5RnVsbE5hbWUgPSBuZXcgTWFwKClcbiAgICB0aGlzLl9sZWdhY3lGaXh0dXJlRGF0YUJ5RnVsbE5hbWUgPSBuZXcgTWFwKClcbiAgICBjb250ZXh0LnNldERlY2xhcmF0aW9uTG9jYXRvcigoKSA9PiB0aGlzLl9sZWdhY3lGaXh0dXJlTG9jYXRpb24pXG4gICAgdGhpcy5kZWNsYXJlTGVnYWN5Rml4dHVyZShjb250ZXh0LCBcIlwiLCB0ZXN0cywgW10pXG4gICAgdGhpcy5hbmFseXplRGVjbGFyYXRpb25zKClcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLnJ1blBhY2thZ2VUZXN0cygpXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuX2NvbnRleHQgPSBvcmlnaW5hbENvbnRleHRcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGVjbGFyZXMgYW4gaXNvbGF0ZWQgbGVnYWN5LXNoYXBlZCB0ZXN0IGZpeHR1cmUgaW50byBhIHBhY2thZ2UgY29udGV4dC5cbiAgICogQHBhcmFtIHtQYWNrYWdlVGVzdENvbnRleHR9IGNvbnRleHQgLSBJc29sYXRlZCBwYWNrYWdlIGNvbnRleHQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gU3VpdGUgbmFtZS5cbiAgICogQHBhcmFtIHtUZXN0c0FyZ3VtZW50fSBzY29wZSAtIExlZ2FjeSBmaXh0dXJlIHNjb3BlLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBkZXNjcmlwdGlvbnMgLSBBbmNlc3RvciBkZXNjcmlwdGlvbnMuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgZGVjbGFyZUxlZ2FjeUZpeHR1cmUoY29udGV4dCwgbmFtZSwgc2NvcGUsIGRlc2NyaXB0aW9ucykge1xuICAgIHRoaXMuX2xlZ2FjeUZpeHR1cmVMb2NhdGlvbiA9IHtmaWxlUGF0aDogc2NvcGUuZmlsZVBhdGgsIGxpbmU6IHNjb3BlLmxpbmV9XG4gICAgY29udGV4dC5kZXNjcmliZShuYW1lLCBzY29wZS5hcmdzIHx8IHt9LCAoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGhvb2sgb2Ygc2NvcGUuYmVmb3JlQWxscyB8fCBbXSkgY29udGV4dC5iZWZvcmVBbGwoaG9vay5jYWxsYmFjaylcbiAgICAgIGZvciAoY29uc3QgaG9vayBvZiBzY29wZS5iZWZvcmVFYWNoZXMgfHwgW10pIGNvbnRleHQuYmVmb3JlRWFjaChob29rLmNhbGxiYWNrKVxuICAgICAgZm9yIChjb25zdCBob29rIG9mIHNjb3BlLmFmdGVyRWFjaGVzIHx8IFtdKSBjb250ZXh0LmFmdGVyRWFjaChob29rLmNhbGxiYWNrKVxuICAgICAgZm9yIChjb25zdCBob29rIG9mIHNjb3BlLmFmdGVyQWxscyB8fCBbXSkgY29udGV4dC5hZnRlckFsbChob29rLmNhbGxiYWNrKVxuICAgICAgY29uc3QgbmV4dERlc2NyaXB0aW9ucyA9IG5hbWUgPT09IFwiXCIgPyBkZXNjcmlwdGlvbnMgOiBbLi4uZGVzY3JpcHRpb25zLCBuYW1lXVxuICAgICAgZm9yIChjb25zdCBbdGVzdE5hbWUsIHRlc3REYXRhXSBvZiBPYmplY3QuZW50cmllcyhzY29wZS50ZXN0cyB8fCB7fSkpIHtcbiAgICAgICAgdGhpcy5fbGVnYWN5Rml4dHVyZUxvY2F0aW9uID0ge2ZpbGVQYXRoOiB0ZXN0RGF0YS5maWxlUGF0aCwgbGluZTogdGVzdERhdGEubGluZX1cbiAgICAgICAgdGhpcy5fbGVnYWN5Rml4dHVyZURhdGFCeUZ1bGxOYW1lPy5zZXQodGhpcy5idWlsZEZ1bGxEZXNjcmlwdGlvbihuZXh0RGVzY3JpcHRpb25zLCB0ZXN0TmFtZSksIHRlc3REYXRhKVxuICAgICAgICBjb250ZXh0Lml0KHRlc3ROYW1lLCB0ZXN0RGF0YS5hcmdzLCB0ZXN0RGF0YS5mdW5jdGlvbilcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgW3N1aXRlTmFtZSwgY2hpbGRTY29wZV0gb2YgT2JqZWN0LmVudHJpZXMoc2NvcGUuc3VicyB8fCB7fSkpIHtcbiAgICAgICAgdGhpcy5kZWNsYXJlTGVnYWN5Rml4dHVyZShjb250ZXh0LCBzdWl0ZU5hbWUsIGNoaWxkU2NvcGUsIG5leHREZXNjcmlwdGlvbnMpXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGVtaXQgZXZlbnQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgLSBFdmVudCBuYW1lLlxuICAgKiBAcGFyYW0ge29iamVjdH0gcGF5bG9hZCAtIEV2ZW50IHBheWxvYWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gYWxsIGxpc3RlbmVycyBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGVtaXRFdmVudChldmVudE5hbWUsIHBheWxvYWQpIHtcbiAgICBhd2FpdCB0aGlzLl9ydW5uZXJSZXBvcnRlci5lbWl0RXZlbnQoZXZlbnROYW1lLCBwYXlsb2FkKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcHJpbnQgcmVydW4gY29tbWFuZC5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gYXJncy5kZXNjcmlwdGlvbnMgLSBEZXNjcmlwdGlvbiBzdGFjay5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MudGVzdERlc2NyaXB0aW9uIC0gVGVzdCBkZXNjcmlwdGlvbi5cbiAgICogQHBhcmFtIHtUZXN0RGF0YX0gYXJncy50ZXN0RGF0YSAtIFRlc3QgZGF0YS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MubGVmdFBhZGRpbmcgLSBMZWZ0IHBhZGRpbmcuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHByaW50UmVydW5Db21tYW5kKHtkZXNjcmlwdGlvbnMsIHRlc3REZXNjcmlwdGlvbiwgdGVzdERhdGEsIGxlZnRQYWRkaW5nfSkge1xuICAgIGNvbnN0IHJlcnVuID0gdGhpcy5idWlsZFJlcnVuQ29tbWFuZCh7ZGVzY3JpcHRpb25zLCB0ZXN0RGVzY3JpcHRpb24sIHRlc3REYXRhfSlcblxuICAgIGlmIChyZXJ1bikge1xuICAgICAgY29uc29sZS5lcnJvcihgJHtsZWZ0UGFkZGluZ30gIFJlLXJ1bjogJHtyZXJ1bn1gKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGJ1aWxkIHJlcnVuIGNvbW1hbmQuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGFyZ3MuZGVzY3JpcHRpb25zIC0gRGVzY3JpcHRpb24gc3RhY2suXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLnRlc3REZXNjcmlwdGlvbiAtIFRlc3QgZGVzY3JpcHRpb24uXG4gICAqIEBwYXJhbSB7VGVzdERhdGF9IGFyZ3MudGVzdERhdGEgLSBUZXN0IGRhdGEuXG4gICAqIEByZXR1cm5zIHtzdHJpbmcgfCB1bmRlZmluZWR9IC0gUmVydW4gY29tbWFuZC5cbiAgICovXG4gIGJ1aWxkUmVydW5Db21tYW5kKHtkZXNjcmlwdGlvbnMsIHRlc3REZXNjcmlwdGlvbiwgdGVzdERhdGF9KSB7XG4gICAgY29uc3QgYmFzZUNvbW1hbmQgPSBcIm5weCB2ZWxvY2lvdXMgdGVzdFwiXG4gICAgY29uc3QgZmlsZVBhdGggPSB0ZXN0RGF0YS5maWxlUGF0aFxuICAgIGNvbnN0IGxpbmUgPSB0ZXN0RGF0YS5saW5lXG5cbiAgICBpZiAoZmlsZVBhdGggJiYgbGluZSkge1xuICAgICAgY29uc3QgcmVsYXRpdmVQYXRoID0gcGF0aC5yZWxhdGl2ZShwcm9jZXNzLmN3ZCgpLCBmaWxlUGF0aClcbiAgICAgIHJldHVybiBgJHtiYXNlQ29tbWFuZH0gJHtyZWxhdGl2ZVBhdGh9OiR7bGluZX1gXG4gICAgfVxuXG4gICAgY29uc3QgZnVsbERlc2NyaXB0aW9uID0gdGhpcy5idWlsZEZ1bGxEZXNjcmlwdGlvbihkZXNjcmlwdGlvbnMsIHRlc3REZXNjcmlwdGlvbilcblxuICAgIGlmIChmdWxsRGVzY3JpcHRpb24pIHtcbiAgICAgIHJldHVybiBgJHtiYXNlQ29tbWFuZH0gLS1leGFtcGxlICR7SlNPTi5zdHJpbmdpZnkoZnVsbERlc2NyaXB0aW9uKX1gXG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZFxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYnVpbGQgY29uc29sZSBvdXRwdXQuXG4gICAqIEBwYXJhbSB7QXR0ZW1wdENvbnNvbGVPdXRwdXRbXX0gYXR0ZW1wdENvbnNvbGVPdXRwdXRzIC0gQXR0ZW1wdCBvdXRwdXQgZW50cmllcy5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBDb21iaW5lZCBjb25zb2xlIG91dHB1dC5cbiAgICovXG4gIGJ1aWxkQ29uc29sZU91dHB1dChhdHRlbXB0Q29uc29sZU91dHB1dHMpIHtcbiAgICBpZiAoYXR0ZW1wdENvbnNvbGVPdXRwdXRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFwiXCJcbiAgICBpZiAoYXR0ZW1wdENvbnNvbGVPdXRwdXRzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGF0dGVtcHRDb25zb2xlT3V0cHV0c1swXS5vdXRwdXRcblxuICAgIHJldHVybiBhdHRlbXB0Q29uc29sZU91dHB1dHMubWFwKChhdHRlbXB0Q29uc29sZU91dHB1dCkgPT4ge1xuICAgICAgcmV0dXJuIGAtLS0gQXR0ZW1wdCAke2F0dGVtcHRDb25zb2xlT3V0cHV0LmF0dGVtcHROdW1iZXJ9IC0tLVxcbiR7YXR0ZW1wdENvbnNvbGVPdXRwdXQub3V0cHV0fWBcbiAgICB9KS5qb2luKFwiXFxuXCIpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBnZXQgZmFpbGVkIGNvbnNvbGUgb3V0cHV0IG1heCBsaW5lcy5cbiAgICogQHJldHVybnMge251bWJlcn0gLSBNYXhpbXVtIGZhaWxlZCBjb25zb2xlIGxpbmVzLlxuICAgKi9cbiAgZ2V0RmFpbGVkQ29uc29sZU91dHB1dE1heExpbmVzKCkge1xuICAgIGNvbnN0IG1heExpbmVzID0gdGVzdENvbmZpZy5mYWlsZWRDb25zb2xlT3V0cHV0TWF4TGluZXNcblxuICAgIGlmICh0eXBlb2YgbWF4TGluZXMgIT09IFwibnVtYmVyXCIgfHwgIU51bWJlci5pc0Zpbml0ZShtYXhMaW5lcykpIHJldHVybiAyMDBcblxuICAgIHJldHVybiBNYXRoLm1heCgwLCBNYXRoLmZsb29yKG1heExpbmVzKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHRydW5jYXRlIGZhaWxlZCBjb25zb2xlIG91dHB1dCBsaW5lcy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGNvbnNvbGVPdXRwdXQgLSBDb25zb2xlIG91dHB1dC5cbiAgICogQHJldHVybnMge3N0cmluZ1tdfSAtIExpbmVzIGZvciBpbmxpbmUgb3V0cHV0LlxuICAgKi9cbiAgdHJ1bmNhdGVGYWlsZWRDb25zb2xlT3V0cHV0TGluZXMoY29uc29sZU91dHB1dCkge1xuICAgIGNvbnN0IGxpbmVzID0gY29uc29sZU91dHB1dC5zcGxpdChcIlxcblwiKVxuICAgIGNvbnN0IG1heExpbmVzID0gdGhpcy5nZXRGYWlsZWRDb25zb2xlT3V0cHV0TWF4TGluZXMoKVxuXG4gICAgaWYgKG1heExpbmVzID09PSAwKSByZXR1cm4gW11cbiAgICBpZiAobGluZXMubGVuZ3RoIDw9IG1heExpbmVzKSByZXR1cm4gbGluZXNcblxuICAgIGNvbnN0IG9taXR0ZWRMaW5lcyA9IGxpbmVzLmxlbmd0aCAtIG1heExpbmVzXG4gICAgY29uc3QgcGx1cmFsID0gb21pdHRlZExpbmVzID09PSAxID8gXCJcIiA6IFwic1wiXG5cbiAgICByZXR1cm4gW1xuICAgICAgYC4uLiAke29taXR0ZWRMaW5lc30gY29uc29sZSBvdXRwdXQgbGluZSR7cGx1cmFsfSBvbWl0dGVkIC4uLmAsXG4gICAgICAuLi5saW5lcy5zbGljZSgtbWF4TGluZXMpXG4gICAgXVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcHJpbnQgZmFpbGVkIGNvbnNvbGUgb3V0cHV0LlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5jb25zb2xlT3V0cHV0IC0gQ29uc29sZSBvdXRwdXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmxlZnRQYWRkaW5nIC0gTGVmdCBwYWRkaW5nLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBwcmludEZhaWxlZENvbnNvbGVPdXRwdXQoe2NvbnNvbGVPdXRwdXQsIGxlZnRQYWRkaW5nfSkge1xuICAgIGlmICh0ZXN0Q29uZmlnLmNvbnNvbGVPdXRwdXQgIT09IFwiZmFpbHVyZVwiKSByZXR1cm5cbiAgICBpZiAoIWNvbnNvbGVPdXRwdXQpIHJldHVyblxuXG4gICAgY29uc3QgbGluZXMgPSB0aGlzLnRydW5jYXRlRmFpbGVkQ29uc29sZU91dHB1dExpbmVzKGNvbnNvbGVPdXRwdXQpXG5cbiAgICBpZiAobGluZXMubGVuZ3RoID09PSAwKSByZXR1cm5cblxuICAgIGNvbnNvbGUuZXJyb3IocGljb2NvbG9ycy5yZWQoYCR7bGVmdFBhZGRpbmd9ICBDb25zb2xlIG91dHB1dDpgKSlcblxuICAgIGZvciAoY29uc3QgbGluZSBvZiBsaW5lcykge1xuICAgICAgY29uc29sZS5lcnJvcihwaWNvY29sb3JzLnJlZChgJHtsZWZ0UGFkZGluZ30gICAgJHtsaW5lfWApKVxuICAgIH1cbiAgfVxuXG59XG4iXX0=
|