velocious 1.0.240 → 1.0.241
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 +3 -1
- package/build/src/environment-handlers/node/cli/commands/test.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/test.js +5 -1
- package/build/src/testing/test-runner.d.ts +50 -7
- package/build/src/testing/test-runner.d.ts.map +1 -1
- package/build/src/testing/test-runner.js +191 -88
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -71,10 +71,12 @@ Retry flaky tests by setting a retry count on the test args.
|
|
|
71
71
|
|
|
72
72
|
```js
|
|
73
73
|
describe("Tasks", () => {
|
|
74
|
-
|
|
74
|
+
it("retries a flaky check", {retry: 2}, async () => {})
|
|
75
75
|
})
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
+
During a failing run, Velocious captures all console output emitted while each test executes. At the end of a failed run, those logs are saved under `tmp/screenshots` next to failure screenshots/browser logs/HTML, and each failed test summary prints the saved console log path.
|
|
79
|
+
|
|
78
80
|
Listen for retry events if you need to restart services between attempts.
|
|
79
81
|
|
|
80
82
|
```js
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../../../../../src/environment-handlers/node/cli/commands/test.js"],"names":[],"mappings":"AAQA;IACE,
|
|
1
|
+
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../../../../../src/environment-handlers/node/cli/commands/test.js"],"names":[],"mappings":"AAQA;IACE,yBA8FC;CACF;wBAtGuB,iCAAiC"}
|
|
@@ -63,6 +63,7 @@ export default class VelociousCliCommandsTest extends BaseCommand {
|
|
|
63
63
|
process.exit(1);
|
|
64
64
|
}
|
|
65
65
|
if (testRunner.isFailed()) {
|
|
66
|
+
await testRunner.persistFailedTestConsoleOutputsToAssets();
|
|
66
67
|
const failedTests = testRunner.getFailedTestDetails();
|
|
67
68
|
if (failedTests.length > 0) {
|
|
68
69
|
console.error(picocolors.red("\nFailed tests:"));
|
|
@@ -71,6 +72,9 @@ export default class VelociousCliCommandsTest extends BaseCommand {
|
|
|
71
72
|
? ` (${failed.filePath}:${failed.line})`
|
|
72
73
|
: "";
|
|
73
74
|
console.error(picocolors.red(`- ${failed.fullDescription}${location}`));
|
|
75
|
+
if (failed.consoleLogPath) {
|
|
76
|
+
console.error(picocolors.red(` Console log: ${failed.consoleLogPath}`));
|
|
77
|
+
}
|
|
74
78
|
}
|
|
75
79
|
}
|
|
76
80
|
console.error(picocolors.red(`\nTest run failed with ${testRunner.getFailedTests()} failed tests and ${testRunner.getSuccessfulTests()} successfull`));
|
|
@@ -86,4 +90,4 @@ export default class VelociousCliCommandsTest extends BaseCommand {
|
|
|
86
90
|
}
|
|
87
91
|
}
|
|
88
92
|
}
|
|
89
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9lbnZpcm9ubWVudC1oYW5kbGVycy9ub2RlL2NsaS9jb21tYW5kcy90ZXN0LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLFdBQVcsTUFBTSxpQ0FBaUMsQ0FBQTtBQUN6RCxPQUFPLFVBQVUsTUFBTSxZQUFZLENBQUE7QUFDbkMsT0FBTyxlQUFlLE1BQU0sMENBQTBDLENBQUE7QUFDdEUsT0FBTyxVQUFVLE1BQU0sb0NBQW9DLENBQUE7QUFDM0QsT0FBTyxFQUFDLHdCQUF3QixFQUFFLFlBQVksRUFBQyxNQUFNLDJDQUEyQyxDQUFBO0FBRWhHLE1BQU0sQ0FBQyxPQUFPLE9BQU8sd0JBQXlCLFNBQVEsV0FBVztJQUMvRCxLQUFLLENBQUMsT0FBTztRQUNYLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUU5QyxJQUFJLFNBQVMsQ0FBQTtRQUNiLE1BQU0sV0FBVyxHQUFHLEVBQUUsQ0FBQTtRQUV0QixJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUNuQyxTQUFTLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQTtZQUMxQyxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0JBQWtCLENBQUMsQ0FBQTtRQUNsRCxDQUFDO2FBQU0sQ0FBQztZQUNOLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUE7WUFDNUIsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUE7WUFDakQsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUE7WUFDN0MsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFH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QUFDLENBQUMsQ0FBQyxDQUFBO1FBQ2pCLENBQUM7YUFBTSxDQUFDO1lBQ04sT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLDZCQUE2QixVQUFVLENBQUMsa0JBQWtCLEVBQUUsbUJBQW1CLENBQUMsQ0FBQyxDQUFBO1lBQzlHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDakIsQ0FBQztJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgQmFzZUNvbW1hbmQgZnJvbSBcIi4uLy4uLy4uLy4uL2NsaS9iYXNlLWNvbW1hbmQuanNcIlxuaW1wb3J0IHBpY29jb2xvcnMgZnJvbSBcInBpY29jb2xvcnNcIlxuaW1wb3J0IFRlc3RGaWxlc0ZpbmRlciBmcm9tIFwiLi4vLi4vLi4vLi4vdGVzdGluZy90ZXN0LWZpbGVzLWZpbmRlci5qc1wiXG5pbXBvcnQgVGVzdFJ1bm5lciBmcm9tIFwiLi4vLi4vLi4vLi4vdGVzdGluZy90ZXN0LXJ1bm5lci5qc1wiXG5pbXBvcnQge25vcm1hbGl6ZUV4YW1wbGVQYXR0ZXJucywgcGFyc2VGaWx0ZXJzfSBmcm9tIFwiLi4vLi4vLi4vLi4vdGVzdGluZy90ZXN0LWZpbHRlci1wYXJzZXIuanNcIlxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWZWxvY2lvdXNDbGlDb21tYW5kc1Rlc3QgZXh0ZW5kcyBCYXNlQ29tbWFuZCB7XG4gIGFzeW5jIGV4ZWN1dGUoKSB7XG4gICAgdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuc2V0RW52aXJvbm1lbnQoXCJ0ZXN0XCIpXG5cbiAgICBsZXQgZGlyZWN0b3J5XG4gICAgY29uc3QgZGlyZWN0b3JpZXMgPSBbXVxuXG4gICAgaWYgKHByb2Nlc3MuZW52LlZFTE9DSU9VU19URVNUX0RJUikge1xuICAgICAgZGlyZWN0b3J5ID0gcHJvY2Vzcy5lbnYuVkVMT0NJT1VTX1RFU1RfRElSXG4gICAgICBkaXJlY3Rvcmllcy5wdXNoKHByb2Nlc3MuZW52LlZFTE9DSU9VU19URVNUX0RJUilcbiAgICB9IGVsc2Uge1xuICAgICAgZGlyZWN0b3J5ID0gdGhpcy5kaXJlY3RvcnkoKVxuICAgICAgZGlyZWN0b3JpZXMucHVzaChgJHt0aGlzLmRpcmVjdG9yeSgpfS9fX3Rlc3RzX19gKVxuICAgICAgZGlyZWN0b3JpZXMucHVzaChgJHt0aGlzLmRpcmVjdG9yeSgpfS90ZXN0c2ApXG4gICAgICBkaXJlY3Rvcmllcy5wdXNoKGAke3RoaXMuZGlyZWN0b3J5KCl9L3NwZWNgKVxuICAgIH1cblxuICAgIGNvbnN0IHtpbmNsdWRlVGFncywgZXhjbHVkZVRhZ3MsIGV4YW1wbGVQYXR0ZXJucywgZmlsdGVyZWRQcm9jZXNzQXJnc30gPSBwYXJzZUZpbHRlcnModGhpcy5wcm9jZXNzQXJncyB8fCBbXSlcbiAgICBjb25zdCB0ZXN0RmlsZXNGaW5kZXIgPSBuZXcgVGVzdEZpbGVzRmluZGVyKHtkaXJlY3RvcnksIGRpcmVjdG9yaWVzLCBwcm9jZXNzQXJnczogZmlsdGVyZWRQcm9jZXNzQXJnc30pXG4gICAgY29uc3QgdGVzdEZpbGVzID0gYXdhaXQgdGVzdEZpbGVzRmluZGVyLmZpbmRUZXN0RmlsZXMoKVxuICAgIGNvbnN0IHRlc3RSdW5uZXIgPSBuZXcgVGVzdFJ1bm5lcih7XG4gICAgICBjb25maWd1cmF0aW9uOiB0aGlzLmdldENvbmZpZ3VyYXRpb24oKSxcbiAgICAgIGV4Y2x1ZGVUYWdzLFxuICAgICAgaW5jbHVkZVRhZ3MsXG4gICAgICB0ZXN0RmlsZXMsXG4gICAgICBsaW5lRmlsdGVyczogdGVzdEZpbGVzRmluZGVyLmdldExpbmVGaWx0ZXJzQnlGaWxlKCksXG4gICAgICBleGFtcGxlUGF0dGVybnM6IG5vcm1hbGl6ZUV4YW1wbGVQYXR0ZXJucyhleGFtcGxlUGF0dGVybnMpXG4gICAgfSlcbiAgICBsZXQgc2lnbmFsSGFuZGxlZCA9IGZhbHNlXG5cbiAgICBjb25zdCBoYW5kbGVTaWduYWwgPSBhc3luYyAoc2lnbmFsKSA9PiB7XG4gICAgICBpZiAoc2lnbmFsSGFuZGxlZCkgcmV0dXJuXG4gICAgICBzaWduYWxIYW5kbGVkID0gdHJ1ZVxuICAgICAgY29uc29sZS5lcnJvcihgXFxuUmVjZWl2ZWQgJHtzaWduYWx9LCBydW5uaW5nIGFmdGVyQWxsIGhvb2tzIGJlZm9yZSBleGl0Li4uYClcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGVzdFJ1bm5lci5ydW5BZnRlckFsbHNGb3JBY3RpdmVTY29wZXMoKVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcIkZhaWxlZCB3aGlsZSBydW5uaW5nIGFmdGVyQWxsIGhvb2tzOlwiLCBlcnJvcilcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgxMzApXG4gICAgICB9XG4gICAgfVxuXG4gICAgcHJvY2Vzcy5vbmNlKFwiU0lHSU5UXCIsICgpID0+IHsgdm9pZCBoYW5kbGVTaWduYWwoXCJTSUdJTlRcIikgfSlcbiAgICBwcm9jZXNzLm9uY2UoXCJTSUdURVJNXCIsICgpID0+IHsgdm9pZCBoYW5kbGVTaWduYWwoXCJTSUdURVJNXCIpIH0pXG5cbiAgICBhd2FpdCB0ZXN0UnVubmVyLnByZXBhcmUoKVxuXG4gICAgaWYgKHRlc3RSdW5uZXIuZ2V0VGVzdHNDb3VudCgpID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dGVzdFJ1bm5lci5nZXRUZXN0c0NvdW50KCl9IHRlc3RzIHdhcyBmb3VuZCBpbiAke3Rlc3RGaWxlcy5sZW5ndGh9IGZpbGUocylgKVxuICAgIH1cblxuICAgIGF3YWl0IHRlc3RSdW5uZXIucnVuKClcblxuICAgIGNvbnN0IGV4ZWN1dGVkVGVzdHMgPSB0ZXN0UnVubmVyLmdldEV4ZWN1dGVkVGVzdHNDb3VudCgpXG5cbiAgICBjb25zdCBsaW5lRmlsdGVycyA9IHRlc3RSdW5uZXIuZ2V0TGluZUZpbHRlcnMoKVxuICAgIGNvbnN0IGhhc0xpbmVGaWx0ZXJzID0gT2JqZWN0LmtleXMobGluZUZpbHRlcnMpLmxlbmd0aCA+IDBcbiAgICBjb25zdCBoYXNFeGFtcGxlRmlsdGVycyA9IGV4YW1wbGVQYXR0ZXJucy5sZW5ndGggPiAwXG4gICAgY29uc3QgaGFzVGFnRmlsdGVycyA9IGluY2x1ZGVUYWdzLmxlbmd0aCA+IDAgfHwgZXhjbHVkZVRhZ3MubGVuZ3RoID4gMFxuXG4gICAgaWYgKChoYXNUYWdGaWx0ZXJzIHx8IGhhc0xpbmVGaWx0ZXJzIHx8IGhhc0V4YW1wbGVGaWx0ZXJzKSAmJiBleGVjdXRlZFRlc3RzID09PSAwKSB7XG4gICAgICBjb25zb2xlLmVycm9yKHBpY29jb2xvcnMucmVkKFwiXFxuTm8gdGVzdHMgbWF0Y2hlZCB0aGUgcHJvdmlkZWQgZmlsdGVyc1wiKSlcbiAgICAgIHByb2Nlc3MuZXhpdCgxKVxuICAgIH1cblxuICAgIGlmICh0ZXN0UnVubmVyLmlzRmFpbGVkKCkpIHtcbiAgICAgIGNvbnN0IGZhaWxlZFRlc3RzID0gdGVzdFJ1bm5lci5nZXRGYWlsZWRUZXN0RGV0YWlscygpXG5cbiAgICAgIGlmIChmYWlsZWRUZXN0cy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zb2xlLmVycm9yKHBpY29jb2xvcnMucmVkKFwiXFxuRmFpbGVkIHRlc3RzOlwiKSlcblxuICAgICAgICBmb3IgKGNvbnN0IGZhaWxlZCBvZiBmYWlsZWRUZXN0cykge1xuICAgICAgICAgIGNvbnN0IGxvY2F0aW9uID0gZmFpbGVkLmZpbGVQYXRoICYmIGZhaWxlZC5saW5lXG4gICAgICAgICAgICA/IGAgKCR7ZmFpbGVkLmZpbGVQYXRofToke2ZhaWxlZC5saW5lfSlgXG4gICAgICAgICAgICA6IFwiXCJcbiAgICAgICAgICBjb25zb2xlLmVycm9yKHBpY29jb2xvcnMucmVkKGAtICR7ZmFpbGVkLmZ1bGxEZXNjcmlwdGlvbn0ke2xvY2F0aW9ufWApKVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnNvbGUuZXJyb3IocGljb2NvbG9ycy5yZWQoYFxcblRlc3QgcnVuIGZhaWxlZCB3aXRoICR7dGVzdFJ1bm5lci5nZXRGYWlsZWRUZXN0cygpfSBmYWlsZWQgdGVzdHMgYW5kICR7dGVzdFJ1bm5lci5nZXRTdWNjZXNzZnVsVGVzdHMoKX0gc3VjY2Vzc2Z1bGxgKSlcbiAgICAgIHByb2Nlc3MuZXhpdCgxKVxuICAgIH0gZWxzZSBpZiAodGVzdFJ1bm5lci5hcmVBbnlUZXN0c0ZvY3Vzc2VkKCkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IocGljb2NvbG9ycy5yZWQoYFxcbkZvY3Vzc2VkIHJ1biB3aXRoICR7dGVzdFJ1bm5lci5nZXRGYWlsZWRUZXN0cygpfSBmYWlsZWQgdGVzdHMgYW5kICR7dGVzdFJ1bm5lci5nZXRTdWNjZXNzZnVsVGVzdHMoKX0gc3VjY2Vzc2Z1bGxgKSlcbiAgICAgIHByb2Nlc3MuZXhpdCgxKVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLmxvZyhwaWNvY29sb3JzLmdyZWVuKGBcXG5UZXN0IHJ1biBzdWNjZWVkZWQgd2l0aCAke3Rlc3RSdW5uZXIuZ2V0U3VjY2Vzc2Z1bFRlc3RzKCl9IHN1Y2Nlc3NmdWwgdGVzdHNgKSlcbiAgICAgIHByb2Nlc3MuZXhpdCgwKVxuICAgIH1cbiAgfVxufVxuIl19
|
|
93
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9lbnZpcm9ubWVudC1oYW5kbGVycy9ub2RlL2NsaS9jb21tYW5kcy90ZXN0LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLFdBQVcsTUFBTSxpQ0FBaUMsQ0FBQTtBQUN6RCxPQUFPLFVBQVUsTUFBTSxZQUFZLENBQUE7QUFDbkMsT0FBTyxlQUFlLE1BQU0sMENBQTBDLENBQUE7QUFDdEUsT0FBTyxVQUFVLE1BQU0sb0NBQW9DLENBQUE7QUFDM0QsT0FBTyxFQUFDLHdCQUF3QixFQUFFLFlBQVksRUFBQyxNQUFNLDJDQUEyQyxDQUFBO0FBRWhHLE1BQU0sQ0FBQyxPQUFPLE9BQU8sd0JBQXlCLFNBQVEsV0FBVztJQUMvRCxLQUFLLENBQUMsT0FBTztRQUNYLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUU5QyxJQUFJLFNBQVMsQ0FBQTtRQUNiLE1BQU0sV0FBVyxHQUFHLEVBQUUsQ0FBQTtRQUV0QixJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUNuQyxTQUFTLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQTtZQUMxQyxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0JBQWtCLENBQUMsQ0FBQTtRQUNsRCxDQUFDO2FBQU0sQ0FBQztZQUNOLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUE7WUFDNUIsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUE7WUFDakQsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUE7WUFDN0MsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFH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QUFVLENBQUMsbUJBQW1CLEVBQUUsRUFBRSxDQUFDO1lBQzVDLE9BQU8sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyx1QkFBdUIsVUFBVSxDQUFDLGNBQWMsRUFBRSxxQkFBcUIsVUFBVSxDQUFDLGtCQUFrQixFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUE7WUFDbkosT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUNqQixDQUFDO2FBQU0sQ0FBQztZQUNOLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyw2QkFBNkIsVUFBVSxDQUFDLGtCQUFrQixFQUFFLG1CQUFtQixDQUFDLENBQUMsQ0FBQTtZQUM5RyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQ2pCLENBQUM7SUFDSCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IEJhc2VDb21tYW5kIGZyb20gXCIuLi8uLi8uLi8uLi9jbGkvYmFzZS1jb21tYW5kLmpzXCJcbmltcG9ydCBwaWNvY29sb3JzIGZyb20gXCJwaWNvY29sb3JzXCJcbmltcG9ydCBUZXN0RmlsZXNGaW5kZXIgZnJvbSBcIi4uLy4uLy4uLy4uL3Rlc3RpbmcvdGVzdC1maWxlcy1maW5kZXIuanNcIlxuaW1wb3J0IFRlc3RSdW5uZXIgZnJvbSBcIi4uLy4uLy4uLy4uL3Rlc3RpbmcvdGVzdC1ydW5uZXIuanNcIlxuaW1wb3J0IHtub3JtYWxpemVFeGFtcGxlUGF0dGVybnMsIHBhcnNlRmlsdGVyc30gZnJvbSBcIi4uLy4uLy4uLy4uL3Rlc3RpbmcvdGVzdC1maWx0ZXItcGFyc2VyLmpzXCJcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVmVsb2Npb3VzQ2xpQ29tbWFuZHNUZXN0IGV4dGVuZHMgQmFzZUNvbW1hbmQge1xuICBhc3luYyBleGVjdXRlKCkge1xuICAgIHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLnNldEVudmlyb25tZW50KFwidGVzdFwiKVxuXG4gICAgbGV0IGRpcmVjdG9yeVxuICAgIGNvbnN0IGRpcmVjdG9yaWVzID0gW11cblxuICAgIGlmIChwcm9jZXNzLmVudi5WRUxPQ0lPVVNfVEVTVF9ESVIpIHtcbiAgICAgIGRpcmVjdG9yeSA9IHByb2Nlc3MuZW52LlZFTE9DSU9VU19URVNUX0RJUlxuICAgICAgZGlyZWN0b3JpZXMucHVzaChwcm9jZXNzLmVudi5WRUxPQ0lPVVNfVEVTVF9ESVIpXG4gICAgfSBlbHNlIHtcbiAgICAgIGRpcmVjdG9yeSA9IHRoaXMuZGlyZWN0b3J5KClcbiAgICAgIGRpcmVjdG9yaWVzLnB1c2goYCR7dGhpcy5kaXJlY3RvcnkoKX0vX190ZXN0c19fYClcbiAgICAgIGRpcmVjdG9yaWVzLnB1c2goYCR7dGhpcy5kaXJlY3RvcnkoKX0vdGVzdHNgKVxuICAgICAgZGlyZWN0b3JpZXMucHVzaChgJHt0aGlzLmRpcmVjdG9yeSgpfS9zcGVjYClcbiAgICB9XG5cbiAgICBjb25zdCB7aW5jbHVkZVRhZ3MsIGV4Y2x1ZGVUYWdzLCBleGFtcGxlUGF0dGVybnMsIGZpbHRlcmVkUHJvY2Vzc0FyZ3N9ID0gcGFyc2VGaWx0ZXJzKHRoaXMucHJvY2Vzc0FyZ3MgfHwgW10pXG4gICAgY29uc3QgdGVzdEZpbGVzRmluZGVyID0gbmV3IFRlc3RGaWxlc0ZpbmRlcih7ZGlyZWN0b3J5LCBkaXJlY3RvcmllcywgcHJvY2Vzc0FyZ3M6IGZpbHRlcmVkUHJvY2Vzc0FyZ3N9KVxuICAgIGNvbnN0IHRlc3RGaWxlcyA9IGF3YWl0IHRlc3RGaWxlc0ZpbmRlci5maW5kVGVzdEZpbGVzKClcbiAgICBjb25zdCB0ZXN0UnVubmVyID0gbmV3IFRlc3RSdW5uZXIoe1xuICAgICAgY29uZmlndXJhdGlvbjogdGhpcy5nZXRDb25maWd1cmF0aW9uKCksXG4gICAgICBleGNsdWRlVGFncyxcbiAgICAgIGluY2x1ZGVUYWdzLFxuICAgICAgdGVzdEZpbGVzLFxuICAgICAgbGluZUZpbHRlcnM6IHRlc3RGaWxlc0ZpbmRlci5nZXRMaW5lRmlsdGVyc0J5RmlsZSgpLFxuICAgICAgZXhhbXBsZVBhdHRlcm5zOiBub3JtYWxpemVFeGFtcGxlUGF0dGVybnMoZXhhbXBsZVBhdHRlcm5zKVxuICAgIH0pXG4gICAgbGV0IHNpZ25hbEhhbmRsZWQgPSBmYWxzZVxuXG4gICAgY29uc3QgaGFuZGxlU2lnbmFsID0gYXN5bmMgKHNpZ25hbCkgPT4ge1xuICAgICAgaWYgKHNpZ25hbEhhbmRsZWQpIHJldHVyblxuICAgICAgc2lnbmFsSGFuZGxlZCA9IHRydWVcbiAgICAgIGNvbnNvbGUuZXJyb3IoYFxcblJlY2VpdmVkICR7c2lnbmFsfSwgcnVubmluZyBhZnRlckFsbCBob29rcyBiZWZvcmUgZXhpdC4uLmApXG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRlc3RSdW5uZXIucnVuQWZ0ZXJBbGxzRm9yQWN0aXZlU2NvcGVzKClcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXCJGYWlsZWQgd2hpbGUgcnVubmluZyBhZnRlckFsbCBob29rczpcIiwgZXJyb3IpXG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBwcm9jZXNzLmV4aXQoMTMwKVxuICAgICAgfVxuICAgIH1cblxuICAgIHByb2Nlc3Mub25jZShcIlNJR0lOVFwiLCAoKSA9PiB7IHZvaWQgaGFuZGxlU2lnbmFsKFwiU0lHSU5UXCIpIH0pXG4gICAgcHJvY2Vzcy5vbmNlKFwiU0lHVEVSTVwiLCAoKSA9PiB7IHZvaWQgaGFuZGxlU2lnbmFsKFwiU0lHVEVSTVwiKSB9KVxuXG4gICAgYXdhaXQgdGVzdFJ1bm5lci5wcmVwYXJlKClcblxuICAgIGlmICh0ZXN0UnVubmVyLmdldFRlc3RzQ291bnQoKSA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3Rlc3RSdW5uZXIuZ2V0VGVzdHNDb3VudCgpfSB0ZXN0cyB3YXMgZm91bmQgaW4gJHt0ZXN0RmlsZXMubGVuZ3RofSBmaWxlKHMpYClcbiAgICB9XG5cbiAgICBhd2FpdCB0ZXN0UnVubmVyLnJ1bigpXG5cbiAgICBjb25zdCBleGVjdXRlZFRlc3RzID0gdGVzdFJ1bm5lci5nZXRFeGVjdXRlZFRlc3RzQ291bnQoKVxuXG4gICAgY29uc3QgbGluZUZpbHRlcnMgPSB0ZXN0UnVubmVyLmdldExpbmVGaWx0ZXJzKClcbiAgICBjb25zdCBoYXNMaW5lRmlsdGVycyA9IE9iamVjdC5rZXlzKGxpbmVGaWx0ZXJzKS5sZW5ndGggPiAwXG4gICAgY29uc3QgaGFzRXhhbXBsZUZpbHRlcnMgPSBleGFtcGxlUGF0dGVybnMubGVuZ3RoID4gMFxuICAgIGNvbnN0IGhhc1RhZ0ZpbHRlcnMgPSBpbmNsdWRlVGFncy5sZW5ndGggPiAwIHx8IGV4Y2x1ZGVUYWdzLmxlbmd0aCA+IDBcblxuICAgIGlmICgoaGFzVGFnRmlsdGVycyB8fCBoYXNMaW5lRmlsdGVycyB8fCBoYXNFeGFtcGxlRmlsdGVycykgJiYgZXhlY3V0ZWRUZXN0cyA9PT0gMCkge1xuICAgICAgY29uc29sZS5lcnJvcihwaWNvY29sb3JzLnJlZChcIlxcbk5vIHRlc3RzIG1hdGNoZWQgdGhlIHByb3ZpZGVkIGZpbHRlcnNcIikpXG4gICAgICBwcm9jZXNzLmV4aXQoMSlcbiAgICB9XG5cbiAgICBpZiAodGVzdFJ1bm5lci5pc0ZhaWxlZCgpKSB7XG4gICAgICBhd2FpdCB0ZXN0UnVubmVyLnBlcnNpc3RGYWlsZWRUZXN0Q29uc29sZU91dHB1dHNUb0Fzc2V0cygpXG4gICAgICBjb25zdCBmYWlsZWRUZXN0cyA9IHRlc3RSdW5uZXIuZ2V0RmFpbGVkVGVzdERldGFpbHMoKVxuXG4gICAgICBpZiAoZmFpbGVkVGVzdHMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc29sZS5lcnJvcihwaWNvY29sb3JzLnJlZChcIlxcbkZhaWxlZCB0ZXN0czpcIikpXG5cbiAgICAgICAgZm9yIChjb25zdCBmYWlsZWQgb2YgZmFpbGVkVGVzdHMpIHtcbiAgICAgICAgICBjb25zdCBsb2NhdGlvbiA9IGZhaWxlZC5maWxlUGF0aCAmJiBmYWlsZWQubGluZVxuICAgICAgICAgICAgPyBgICgke2ZhaWxlZC5maWxlUGF0aH06JHtmYWlsZWQubGluZX0pYFxuICAgICAgICAgICAgOiBcIlwiXG4gICAgICAgICAgY29uc29sZS5lcnJvcihwaWNvY29sb3JzLnJlZChgLSAke2ZhaWxlZC5mdWxsRGVzY3JpcHRpb259JHtsb2NhdGlvbn1gKSlcblxuICAgICAgICAgIGlmIChmYWlsZWQuY29uc29sZUxvZ1BhdGgpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IocGljb2NvbG9ycy5yZWQoYCAgQ29uc29sZSBsb2c6ICR7ZmFpbGVkLmNvbnNvbGVMb2dQYXRofWApKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zb2xlLmVycm9yKHBpY29jb2xvcnMucmVkKGBcXG5UZXN0IHJ1biBmYWlsZWQgd2l0aCAke3Rlc3RSdW5uZXIuZ2V0RmFpbGVkVGVzdHMoKX0gZmFpbGVkIHRlc3RzIGFuZCAke3Rlc3RSdW5uZXIuZ2V0U3VjY2Vzc2Z1bFRlc3RzKCl9IHN1Y2Nlc3NmdWxsYCkpXG4gICAgICBwcm9jZXNzLmV4aXQoMSlcbiAgICB9IGVsc2UgaWYgKHRlc3RSdW5uZXIuYXJlQW55VGVzdHNGb2N1c3NlZCgpKSB7XG4gICAgICBjb25zb2xlLmVycm9yKHBpY29jb2xvcnMucmVkKGBcXG5Gb2N1c3NlZCBydW4gd2l0aCAke3Rlc3RSdW5uZXIuZ2V0RmFpbGVkVGVzdHMoKX0gZmFpbGVkIHRlc3RzIGFuZCAke3Rlc3RSdW5uZXIuZ2V0U3VjY2Vzc2Z1bFRlc3RzKCl9IHN1Y2Nlc3NmdWxsYCkpXG4gICAgICBwcm9jZXNzLmV4aXQoMSlcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5sb2cocGljb2NvbG9ycy5ncmVlbihgXFxuVGVzdCBydW4gc3VjY2VlZGVkIHdpdGggJHt0ZXN0UnVubmVyLmdldFN1Y2Nlc3NmdWxUZXN0cygpfSBzdWNjZXNzZnVsIHRlc3RzYCkpXG4gICAgICBwcm9jZXNzLmV4aXQoMClcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|
|
@@ -19,6 +19,15 @@
|
|
|
19
19
|
* @property {number} [line] - Source line number.
|
|
20
20
|
* @property {function(TestArgs) : (void|Promise<void>)} function - Test callback to execute.
|
|
21
21
|
*/
|
|
22
|
+
/**
|
|
23
|
+
* @typedef {object} FailedTestDetail
|
|
24
|
+
* @property {string} fullDescription - Full test description.
|
|
25
|
+
* @property {string} [filePath] - Source file path.
|
|
26
|
+
* @property {number} [line] - Source line number.
|
|
27
|
+
* @property {unknown} error - Failure error.
|
|
28
|
+
* @property {string} [consoleOutput] - Captured console output while test ran.
|
|
29
|
+
* @property {string} [consoleLogPath] - Saved console log path.
|
|
30
|
+
*/
|
|
22
31
|
/**
|
|
23
32
|
* @typedef {function({configuration: import("../configuration.js").default, testArgs: TestArgs, testData: TestData}) : (void|Promise<void>)} AfterBeforeEachCallbackType
|
|
24
33
|
*/
|
|
@@ -188,13 +197,16 @@ export default class TestRunner {
|
|
|
188
197
|
* @returns {number} - The failed tests.
|
|
189
198
|
*/
|
|
190
199
|
getFailedTests(): number;
|
|
191
|
-
/** @returns {
|
|
192
|
-
getFailedTestDetails():
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
200
|
+
/** @returns {FailedTestDetail[]} - Failed test details. */
|
|
201
|
+
getFailedTestDetails(): FailedTestDetail[];
|
|
202
|
+
/**
|
|
203
|
+
* @param {object} [args] - Options object.
|
|
204
|
+
* @param {string} [args.assetsPath] - Assets directory path.
|
|
205
|
+
* @returns {Promise<string[]>} - Written log file paths.
|
|
206
|
+
*/
|
|
207
|
+
persistFailedTestConsoleOutputsToAssets({ assetsPath }?: {
|
|
208
|
+
assetsPath?: string;
|
|
209
|
+
}): Promise<string[]>;
|
|
198
210
|
/**
|
|
199
211
|
* @returns {number} - The successful tests.
|
|
200
212
|
*/
|
|
@@ -290,7 +302,12 @@ export default class TestRunner {
|
|
|
290
302
|
testDescription: string;
|
|
291
303
|
testData: TestData;
|
|
292
304
|
}): string | undefined;
|
|
305
|
+
/**
|
|
306
|
+
* @returns {() => string} - Stops the capture and returns captured text.
|
|
307
|
+
*/
|
|
308
|
+
startConsoleCapture(): () => string;
|
|
293
309
|
}
|
|
310
|
+
export type ConsoleMethodName = "log" | "info" | "warn" | "error" | "debug";
|
|
294
311
|
export type TestArgs = {
|
|
295
312
|
/**
|
|
296
313
|
* - Application instance for integration tests.
|
|
@@ -350,6 +367,32 @@ export type TestData = {
|
|
|
350
367
|
*/
|
|
351
368
|
function: (arg0: TestArgs) => (void | Promise<void>);
|
|
352
369
|
};
|
|
370
|
+
export type FailedTestDetail = {
|
|
371
|
+
/**
|
|
372
|
+
* - Full test description.
|
|
373
|
+
*/
|
|
374
|
+
fullDescription: string;
|
|
375
|
+
/**
|
|
376
|
+
* - Source file path.
|
|
377
|
+
*/
|
|
378
|
+
filePath?: string;
|
|
379
|
+
/**
|
|
380
|
+
* - Source line number.
|
|
381
|
+
*/
|
|
382
|
+
line?: number;
|
|
383
|
+
/**
|
|
384
|
+
* - Failure error.
|
|
385
|
+
*/
|
|
386
|
+
error: unknown;
|
|
387
|
+
/**
|
|
388
|
+
* - Captured console output while test ran.
|
|
389
|
+
*/
|
|
390
|
+
consoleOutput?: string;
|
|
391
|
+
/**
|
|
392
|
+
* - Saved console log path.
|
|
393
|
+
*/
|
|
394
|
+
consoleLogPath?: string;
|
|
395
|
+
};
|
|
353
396
|
export type AfterBeforeEachCallbackType = (arg0: {
|
|
354
397
|
configuration: import("../configuration.js").default;
|
|
355
398
|
testArgs: TestArgs;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-runner.d.ts","sourceRoot":"","sources":["../../../src/testing/test-runner.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"test-runner.d.ts","sourceRoot":"","sources":["../../../src/testing/test-runner.js"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import { addTrackedStackToError } from "../utils/with-tracked-stack.js";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
3
4
|
import path from "path";
|
|
5
|
+
import { format } from "node:util";
|
|
4
6
|
import Application from "../../src/application.js";
|
|
5
7
|
import BacktraceCleaner from "../utils/backtrace-cleaner.js";
|
|
6
8
|
import RequestClient from "./request-client.js";
|
|
@@ -29,6 +31,20 @@ function runWithTimeout(promise, timeoutMs, testDescription) {
|
|
|
29
31
|
});
|
|
30
32
|
});
|
|
31
33
|
}
|
|
34
|
+
/** @typedef {"log" | "info" | "warn" | "error" | "debug"} ConsoleMethodName */
|
|
35
|
+
/** @type {ConsoleMethodName[]} */
|
|
36
|
+
const CAPTURED_CONSOLE_METHODS = ["log", "info", "warn", "error", "debug"];
|
|
37
|
+
/**
|
|
38
|
+
* @param {string} value - Value to sanitize.
|
|
39
|
+
* @returns {string} - Slug-safe value.
|
|
40
|
+
*/
|
|
41
|
+
function toFileSlug(value) {
|
|
42
|
+
return value
|
|
43
|
+
.toLowerCase()
|
|
44
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
45
|
+
.replace(/^-+|-+$/g, "")
|
|
46
|
+
.slice(0, 80) || "failed-test";
|
|
47
|
+
}
|
|
32
48
|
/**
|
|
33
49
|
* @typedef {object} TestArgs
|
|
34
50
|
* @property {Application} [application] - Application instance for integration tests.
|
|
@@ -50,6 +66,15 @@ function runWithTimeout(promise, timeoutMs, testDescription) {
|
|
|
50
66
|
* @property {number} [line] - Source line number.
|
|
51
67
|
* @property {function(TestArgs) : (void|Promise<void>)} function - Test callback to execute.
|
|
52
68
|
*/
|
|
69
|
+
/**
|
|
70
|
+
* @typedef {object} FailedTestDetail
|
|
71
|
+
* @property {string} fullDescription - Full test description.
|
|
72
|
+
* @property {string} [filePath] - Source file path.
|
|
73
|
+
* @property {number} [line] - Source line number.
|
|
74
|
+
* @property {unknown} error - Failure error.
|
|
75
|
+
* @property {string} [consoleOutput] - Captured console output while test ran.
|
|
76
|
+
* @property {string} [consoleLogPath] - Saved console log path.
|
|
77
|
+
*/
|
|
53
78
|
/**
|
|
54
79
|
* @typedef {function({configuration: import("../configuration.js").default, testArgs: TestArgs, testData: TestData}) : (void|Promise<void>)} AfterBeforeEachCallbackType
|
|
55
80
|
*/
|
|
@@ -361,10 +386,47 @@ export default class TestRunner {
|
|
|
361
386
|
throw new Error("Tests hasn't been run yet");
|
|
362
387
|
return this._failedTests;
|
|
363
388
|
}
|
|
364
|
-
/** @returns {
|
|
389
|
+
/** @returns {FailedTestDetail[]} - Failed test details. */
|
|
365
390
|
getFailedTestDetails() {
|
|
366
391
|
return this._failedTestDetails;
|
|
367
392
|
}
|
|
393
|
+
/**
|
|
394
|
+
* @param {object} [args] - Options object.
|
|
395
|
+
* @param {string} [args.assetsPath] - Assets directory path.
|
|
396
|
+
* @returns {Promise<string[]>} - Written log file paths.
|
|
397
|
+
*/
|
|
398
|
+
async persistFailedTestConsoleOutputsToAssets({ assetsPath = path.join(process.cwd(), "tmp/screenshots") } = {}) {
|
|
399
|
+
const failedTestDetails = this.getFailedTestDetails();
|
|
400
|
+
const writtenLogPaths = [];
|
|
401
|
+
let createdDirectory = false;
|
|
402
|
+
for (let index = 0; index < failedTestDetails.length; index++) {
|
|
403
|
+
const failedTestDetail = failedTestDetails[index];
|
|
404
|
+
const consoleOutput = failedTestDetail.consoleOutput;
|
|
405
|
+
if (!consoleOutput)
|
|
406
|
+
continue;
|
|
407
|
+
if (!createdDirectory) {
|
|
408
|
+
await fs.mkdir(assetsPath, { recursive: true });
|
|
409
|
+
createdDirectory = true;
|
|
410
|
+
}
|
|
411
|
+
const now = new Date();
|
|
412
|
+
const timestamp = [
|
|
413
|
+
String(now.getFullYear()),
|
|
414
|
+
String(now.getMonth() + 1).padStart(2, "0"),
|
|
415
|
+
String(now.getDate()).padStart(2, "0"),
|
|
416
|
+
String(now.getHours()).padStart(2, "0"),
|
|
417
|
+
String(now.getMinutes()).padStart(2, "0"),
|
|
418
|
+
String(now.getSeconds()).padStart(2, "0"),
|
|
419
|
+
String(now.getMilliseconds()).padStart(3, "0")
|
|
420
|
+
].join("");
|
|
421
|
+
const slug = toFileSlug(failedTestDetail.fullDescription);
|
|
422
|
+
const fileName = `${timestamp}-${String(index + 1).padStart(2, "0")}-${slug}.console.log`;
|
|
423
|
+
const filePath = path.join(assetsPath, fileName);
|
|
424
|
+
await fs.writeFile(filePath, consoleOutput, "utf8");
|
|
425
|
+
failedTestDetail.consoleLogPath = filePath;
|
|
426
|
+
writtenLogPaths.push(filePath);
|
|
427
|
+
}
|
|
428
|
+
return writtenLogPaths;
|
|
429
|
+
}
|
|
368
430
|
/**
|
|
369
431
|
* @returns {number} - The successful tests.
|
|
370
432
|
*/
|
|
@@ -505,6 +567,7 @@ export default class TestRunner {
|
|
|
505
567
|
testArgs.client = await this.requestClient();
|
|
506
568
|
}
|
|
507
569
|
console.log(`${leftPadding}it ${testDescription}`);
|
|
570
|
+
const stopConsoleCapture = this.startConsoleCapture();
|
|
508
571
|
const retryCount = typeof testArgs.retry === "number" && Number.isFinite(testArgs.retry)
|
|
509
572
|
? Math.max(0, Math.floor(testArgs.retry))
|
|
510
573
|
: 0;
|
|
@@ -514,46 +577,65 @@ export default class TestRunner {
|
|
|
514
577
|
const timeoutMs = useTimeout ? timeoutSeconds * 1000 : undefined;
|
|
515
578
|
let retriesUsed = 0;
|
|
516
579
|
let attemptNumber = 1;
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
580
|
+
try {
|
|
581
|
+
while (true) {
|
|
582
|
+
let shouldRetry = false;
|
|
583
|
+
/** @type {unknown} */
|
|
584
|
+
let failedError;
|
|
585
|
+
/** @type {unknown} */
|
|
586
|
+
let lastError;
|
|
587
|
+
try {
|
|
588
|
+
await this.runWithDummyIfNeeded(testArgs, async () => {
|
|
589
|
+
try {
|
|
590
|
+
clearDeliveries();
|
|
591
|
+
for (const beforeEachData of newBeforeEaches) {
|
|
592
|
+
await beforeEachData.callback({ configuration: this.getConfiguration(), testArgs, testData });
|
|
593
|
+
}
|
|
594
|
+
const testPromise = testData.function(testArgs);
|
|
595
|
+
if (useTimeout && timeoutMs !== undefined) {
|
|
596
|
+
await runWithTimeout(testPromise, timeoutMs, testDescription);
|
|
597
|
+
}
|
|
598
|
+
else {
|
|
599
|
+
await testPromise;
|
|
600
|
+
}
|
|
601
|
+
this._successfulTests++;
|
|
529
602
|
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
603
|
+
finally {
|
|
604
|
+
for (const afterEachData of newAfterEaches) {
|
|
605
|
+
await afterEachData.callback({ configuration: this.getConfiguration(), testArgs, testData });
|
|
606
|
+
}
|
|
533
607
|
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
catch (error) {
|
|
611
|
+
lastError = error;
|
|
612
|
+
if (retriesUsed < retryCount) {
|
|
613
|
+
retriesUsed++;
|
|
614
|
+
shouldRetry = true;
|
|
615
|
+
console.warn(picocolors.red(`${leftPadding} Retrying (${retriesUsed}/${retryCount}) after error: ${error instanceof Error ? error.message : String(error)}`));
|
|
616
|
+
await this.emitEvent("testRetrying", {
|
|
617
|
+
configuration: this.getConfiguration(),
|
|
618
|
+
descriptions,
|
|
619
|
+
error,
|
|
620
|
+
nextAttempt: attemptNumber + 1,
|
|
621
|
+
retriesUsed,
|
|
622
|
+
retryCount,
|
|
623
|
+
testArgs,
|
|
624
|
+
testData,
|
|
625
|
+
testDescription,
|
|
626
|
+
testRunner: this
|
|
627
|
+
});
|
|
538
628
|
}
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
await afterEachData.callback({ configuration: this.getConfiguration(), testArgs, testData });
|
|
542
|
-
}
|
|
629
|
+
else {
|
|
630
|
+
failedError = error;
|
|
543
631
|
}
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
lastError = error;
|
|
548
|
-
if (retriesUsed < retryCount) {
|
|
549
|
-
retriesUsed++;
|
|
550
|
-
shouldRetry = true;
|
|
551
|
-
console.warn(picocolors.red(`${leftPadding} Retrying (${retriesUsed}/${retryCount}) after error: ${error instanceof Error ? error.message : String(error)}`));
|
|
552
|
-
await this.emitEvent("testRetrying", {
|
|
632
|
+
}
|
|
633
|
+
if (attemptNumber > 1) {
|
|
634
|
+
await this.emitEvent("testRetried", {
|
|
553
635
|
configuration: this.getConfiguration(),
|
|
554
636
|
descriptions,
|
|
555
|
-
error,
|
|
556
|
-
|
|
637
|
+
error: lastError,
|
|
638
|
+
attemptNumber,
|
|
557
639
|
retriesUsed,
|
|
558
640
|
retryCount,
|
|
559
641
|
testArgs,
|
|
@@ -562,62 +644,49 @@ export default class TestRunner {
|
|
|
562
644
|
testRunner: this
|
|
563
645
|
});
|
|
564
646
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
testDescription,
|
|
580
|
-
testRunner: this
|
|
581
|
-
});
|
|
582
|
-
}
|
|
583
|
-
attemptNumber++;
|
|
584
|
-
if (shouldRetry)
|
|
585
|
-
continue;
|
|
586
|
-
if (failedError) {
|
|
587
|
-
this._failedTests++;
|
|
588
|
-
this._failedTestDetails.push({
|
|
589
|
-
fullDescription: this.buildFullDescription(descriptions, testDescription),
|
|
590
|
-
filePath: testData.filePath,
|
|
591
|
-
line: testData.line,
|
|
592
|
-
error: failedError
|
|
593
|
-
});
|
|
594
|
-
if (failedError instanceof Error) {
|
|
595
|
-
console.error(picocolors.red(`${leftPadding} Test failed: ${failedError.message}`));
|
|
596
|
-
addTrackedStackToError(failedError);
|
|
597
|
-
const backtraceCleaner = new BacktraceCleaner(failedError);
|
|
598
|
-
const cleanedStack = backtraceCleaner.getCleanedStack();
|
|
599
|
-
const stackLines = cleanedStack?.split("\n");
|
|
600
|
-
if (stackLines) {
|
|
601
|
-
for (const stackLine of stackLines) {
|
|
602
|
-
console.error(picocolors.red(`${leftPadding} ${stackLine}`));
|
|
647
|
+
attemptNumber++;
|
|
648
|
+
if (shouldRetry)
|
|
649
|
+
continue;
|
|
650
|
+
if (failedError) {
|
|
651
|
+
if (failedError instanceof Error) {
|
|
652
|
+
console.error(picocolors.red(`${leftPadding} Test failed: ${failedError.message}`));
|
|
653
|
+
addTrackedStackToError(failedError);
|
|
654
|
+
const backtraceCleaner = new BacktraceCleaner(failedError);
|
|
655
|
+
const cleanedStack = backtraceCleaner.getCleanedStack();
|
|
656
|
+
const stackLines = cleanedStack?.split("\n");
|
|
657
|
+
if (stackLines) {
|
|
658
|
+
for (const stackLine of stackLines) {
|
|
659
|
+
console.error(picocolors.red(`${leftPadding} ${stackLine}`));
|
|
660
|
+
}
|
|
603
661
|
}
|
|
604
662
|
}
|
|
663
|
+
else {
|
|
664
|
+
console.error(picocolors.red(`${leftPadding} Test failed with a ${typeof failedError}: ${String(failedError)}`));
|
|
665
|
+
}
|
|
666
|
+
this._failedTests++;
|
|
667
|
+
this._failedTestDetails.push({
|
|
668
|
+
fullDescription: this.buildFullDescription(descriptions, testDescription),
|
|
669
|
+
filePath: testData.filePath,
|
|
670
|
+
line: testData.line,
|
|
671
|
+
error: failedError,
|
|
672
|
+
consoleOutput: stopConsoleCapture()
|
|
673
|
+
});
|
|
674
|
+
await this.emitEvent("testFailed", {
|
|
675
|
+
configuration: this.getConfiguration(),
|
|
676
|
+
descriptions,
|
|
677
|
+
error: failedError,
|
|
678
|
+
testArgs,
|
|
679
|
+
testData,
|
|
680
|
+
testDescription,
|
|
681
|
+
testRunner: this
|
|
682
|
+
});
|
|
683
|
+
this.printRerunCommand({ descriptions, testDescription, testData, leftPadding });
|
|
605
684
|
}
|
|
606
|
-
|
|
607
|
-
console.error(picocolors.red(`${leftPadding} Test failed with a ${typeof failedError}: ${String(failedError)}`));
|
|
608
|
-
}
|
|
609
|
-
await this.emitEvent("testFailed", {
|
|
610
|
-
configuration: this.getConfiguration(),
|
|
611
|
-
descriptions,
|
|
612
|
-
error: failedError,
|
|
613
|
-
testArgs,
|
|
614
|
-
testData,
|
|
615
|
-
testDescription,
|
|
616
|
-
testRunner: this
|
|
617
|
-
});
|
|
618
|
-
this.printRerunCommand({ descriptions, testDescription, testData, leftPadding });
|
|
685
|
+
break;
|
|
619
686
|
}
|
|
620
|
-
|
|
687
|
+
}
|
|
688
|
+
finally {
|
|
689
|
+
stopConsoleCapture();
|
|
621
690
|
}
|
|
622
691
|
}
|
|
623
692
|
for (const subDescription in tests.subs) {
|
|
@@ -703,5 +772,39 @@ export default class TestRunner {
|
|
|
703
772
|
}
|
|
704
773
|
return undefined;
|
|
705
774
|
}
|
|
775
|
+
/**
|
|
776
|
+
* @returns {() => string} - Stops the capture and returns captured text.
|
|
777
|
+
*/
|
|
778
|
+
startConsoleCapture() {
|
|
779
|
+
const lines = [];
|
|
780
|
+
/** @type {Record<ConsoleMethodName, (...args: unknown[]) => void>} */
|
|
781
|
+
const consoleObject = /** @type {Record<ConsoleMethodName, (...args: unknown[]) => void>} */ (console);
|
|
782
|
+
/** @type {Record<ConsoleMethodName, (...args: unknown[]) => void>} */
|
|
783
|
+
const originalConsoleMethods = {
|
|
784
|
+
debug: consoleObject.debug.bind(console),
|
|
785
|
+
error: consoleObject.error.bind(console),
|
|
786
|
+
info: consoleObject.info.bind(console),
|
|
787
|
+
log: consoleObject.log.bind(console),
|
|
788
|
+
warn: consoleObject.warn.bind(console)
|
|
789
|
+
};
|
|
790
|
+
let stopped = false;
|
|
791
|
+
let outputText = "";
|
|
792
|
+
for (const methodName of CAPTURED_CONSOLE_METHODS) {
|
|
793
|
+
consoleObject[methodName] = (...args) => {
|
|
794
|
+
lines.push(`[${new Date().toISOString()}] [${methodName}] ${format(...args)}`);
|
|
795
|
+
originalConsoleMethods[methodName](...args);
|
|
796
|
+
};
|
|
797
|
+
}
|
|
798
|
+
return () => {
|
|
799
|
+
if (!stopped) {
|
|
800
|
+
stopped = true;
|
|
801
|
+
for (const methodName of CAPTURED_CONSOLE_METHODS) {
|
|
802
|
+
consoleObject[methodName] = originalConsoleMethods[methodName];
|
|
803
|
+
}
|
|
804
|
+
outputText = lines.join("\n");
|
|
805
|
+
}
|
|
806
|
+
return outputText;
|
|
807
|
+
};
|
|
808
|
+
}
|
|
706
809
|
}
|
|
707
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1ydW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGVzdGluZy90ZXN0LXJ1bm5lci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxFQUFDLHNCQUFzQixFQUFDLE1BQU0sZ0NBQWdDLENBQUE7QUFDckUsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBQ3ZCLE9BQU8sV0FBVyxNQUFNLDBCQUEwQixDQUFBO0FBQ2xELE9BQU8sZ0JBQWdCLE1BQU0sK0JBQStCLENBQUE7QUFDNUQsT0FBTyxhQUFhLE1BQU0scUJBQXFCLENBQUE7QUFDL0MsT0FBTyxVQUFVLE1BQU0sWUFBWSxDQUFBO0FBQ25DLE9BQU8sYUFBYSxNQUFNLDZCQUE2QixDQUFBO0FBQ3ZELE9BQU8sRUFBQyxVQUFVLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBQyxNQUFNLFdBQVcsQ0FBQTtBQUN2RCxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0sS0FBSyxDQUFBO0FBQ2pDLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxjQUFjLENBQUE7QUFFNUM7Ozs7O0dBS0c7QUFDSCxTQUFTLGNBQWMsQ0FBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLGVBQWU7SUFDekQsTUFBTSxjQUFjLEdBQUcsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUE7SUFDMUUsTUFBTSxZQUFZLEdBQUcsSUFBSSxLQUFLLENBQUMsbUJBQW1CLGNBQWMsTUFBTSxlQUFlLEVBQUUsQ0FBQyxDQUFBO0lBRXhGLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDckMsTUFBTSxPQUFPLEdBQUcsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQTtRQUVqRSxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ3ZDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQTtZQUNyQixPQUFPLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDakIsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDakIsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBQ3JCLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUNmLENBQUMsQ0FBQyxDQUFBO0lBQ0osQ0FBQyxDQUFDLENBQUE7QUFDSixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUVIOzs7Ozs7R0FNRztBQUVIOztHQUVHO0FBRUg7OztHQUdHO0FBRUg7O0dBRUc7QUFFSDs7O0dBR0c7QUFFSDs7Ozs7Ozs7Ozs7O0dBWUc7QUFFSCxNQUFNLENBQUMsT0FBTyxPQUFPLFVBQVU7SUFDN0I7Ozs7Ozs7O09BUUc7SUFDSCxZQUFZLEVBQUMsYUFBYSxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsR0FBRyxRQUFRLEVBQUM7UUFDekcsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBRXZCLElBQUksQ0FBQyxhQUFhO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQywyQkFBMkIsQ0FBQyxDQUFBO1FBRWhFLElBQUksQ0FBQyxjQUFjLEdBQUcsYUFBYSxDQUFBO1FBQ25DLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsQ0FBQTtRQUNuRCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQTtRQUNoRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLENBQUE7UUFDbkQsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUE7UUFDaEQsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUE7UUFDM0IsSUFBSSxDQUFDLFlBQVksR0FBRyxXQUFXLElBQUksRUFBRSxDQUFBO1FBQ3JDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxlQUFlLElBQUksRUFBRSxDQUFBO1FBRTdDLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFBO1FBQ3JCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLENBQUE7UUFDekIsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUE7UUFDcEIsSUFBSSxDQUFDLHFCQUFxQixHQUFHLEVBQUUsQ0FBQTtRQUMvQixJQUFJLENBQUMsa0JBQWtCLEdBQUcsRUFBRSxDQUFBO0lBQzlCLENBQUM7SUFFRDs7T0FFRztJQUNILGdCQUFnQixLQUFLLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQSxDQUFDLENBQUM7SUFFakQ7O09BRUc7SUFDSCxZQUFZLEtBQUssT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFBLENBQUMsQ0FBQztJQUV6QywwREFBMEQ7SUFDMUQsY0FBYyxLQUFLLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQSxDQUFDLENBQUM7SUFFN0MsOENBQThDO0lBQzlDLGtCQUFrQixLQUFLLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFBLENBQUMsQ0FBQztJQUVyRDs7O09BR0c7SUFDSCxhQUFhLENBQUMsSUFBSTtRQUNoQixJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU8sRUFBRSxDQUFBO1FBRXBCLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQTtRQUNqQixNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUE7UUFFbkQsS0FBSyxNQUFNLE1BQU0sSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUM3QixJQUFJLE1BQU0sS0FBSyxTQUFTLElBQUksTUFBTSxLQUFLLElBQUk7Z0JBQUUsU0FBUTtZQUVyRCxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBRXZDLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7Z0JBQ3pCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQTtnQkFFM0IsSUFBSSxPQUFPO29CQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUE7WUFDbkMsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQTtJQUNwQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILE1BQU0sQ0FBQyxRQUFRLEVBQUUsR0FBRztRQUNsQixPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUN6RCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxpQkFBaUI7UUFDZixPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsdUJBQXVCLEtBQUssTUFBTSxDQUFBO0lBQ3ZELENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLG9CQUFvQixDQUFDLFFBQVEsRUFBRSxRQUFRO1FBQzNDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ3BDLE1BQU0sUUFBUSxFQUFFLENBQUE7WUFDaEIsT0FBTTtRQUNSLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLENBQUM7WUFDN0IsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsQ0FBQyxDQUFBO1lBQ3BDLE9BQU07UUFDUixDQUFDO1FBRUQsTUFBTSxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBQ25DLENBQUM7SUFFRDs7O09BR0c7SUFDSCxLQUFLLENBQUMsWUFBWSxDQUFDLFFBQVE7UUFDekIsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQTtRQUM3RSxNQUFNLFdBQVcsR0FBRyxNQUFNLE1BQU0sQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDL0QsTUFBTSxLQUFLLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQTtRQUVqQyxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxDQUFDO1lBQ2hCLE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQTZCLFNBQVMsRUFBRSxDQUFDLENBQUE7UUFDM0QsQ0FBQztRQUVELE1BQU0sS0FBSyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQTtJQUMzQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxnQkFBZ0I7UUFDZCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFBO1FBQ3ZDLE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUVoRCxJQUFJLFVBQVUsQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQztZQUN2QyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQyxDQUFBO1FBQ25DLENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLHFCQUFxQixDQUFDLENBQUE7SUFDOUMsQ0FBQztJQUVEOzs7T0FHRztJQUNILEtBQUssQ0FBQyxlQUFlLENBQUMsUUFBUTtRQUM1QixNQUFNLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLGlCQUFpQixDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsRUFBRTtZQUM1RCxNQUFNLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUVqQyxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxRQUFRLEVBQUUsQ0FBQTtZQUNsQixDQUFDO29CQUFTLENBQUM7Z0JBQ1QsTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLENBQUE7WUFDbkMsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUVEOzs7T0FHRztJQUNILEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHO1FBQ3pCLEtBQUssTUFBTSxVQUFVLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzFDLE1BQU0sR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLGlCQUFpQixFQUFFLENBQUE7UUFDM0MsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNILGdCQUFnQjtRQUNkLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUE7UUFFdEYsT0FBTyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUE7SUFDdkQsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxjQUFjLENBQUMsUUFBUSxFQUFFLE1BQU07UUFDN0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJO1lBQUUsT0FBTyxLQUFLLENBQUE7UUFFOUIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUUvQyxLQUFLLE1BQU0sR0FBRyxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQzdCLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7Z0JBQUUsT0FBTyxJQUFJLENBQUE7UUFDbEMsQ0FBQztRQUVELE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLFlBQVksR0FBRyxFQUFFLEVBQUUsa0JBQWtCLEdBQUcsS0FBSztRQUNuRSxLQUFLLE1BQU0sZUFBZSxJQUFJLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUMxQyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFBO1lBQzdDLE1BQU0sUUFBUSxHQUFHLHVCQUF1QixDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7WUFDM0UsTUFBTSxhQUFhLEdBQUcsa0JBQWtCLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxDQUFBO1lBRTVFLElBQUksSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLO2dCQUFFLFNBQVE7WUFDbkQsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsZUFBZSxFQUFFLFlBQVksRUFBRSxhQUFhLENBQUM7Z0JBQUUsU0FBUTtZQUVuRyxPQUFPLElBQUksQ0FBQTtRQUNiLENBQUM7UUFFRCxLQUFLLE1BQU0sY0FBYyxJQUFJLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUN4QyxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFBO1lBQzFDLE1BQU0sY0FBYyxHQUFHLGtCQUFrQixJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQTtZQUM1RSxNQUFNLGdCQUFnQixHQUFHLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFBO1lBRTlELElBQUksSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0I7Z0JBQUUsU0FBUTtZQUM3RCxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsY0FBYyxDQUFDO2dCQUFFLE9BQU8sSUFBSSxDQUFBO1FBQ25GLENBQUM7UUFFRCxPQUFPLEtBQUssQ0FBQTtJQUNkLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsY0FBYyxDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsZUFBZSxFQUFFLFlBQVksRUFBRSxrQkFBa0I7UUFDbEYsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQTtRQUU1RSxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNwRCxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUM7Z0JBQUUsT0FBTyxJQUFJLENBQUE7UUFDM0UsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3pDLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxZQUFZLEVBQUUsZUFBZSxDQUFDLENBQUE7WUFDaEYsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7Z0JBQ3pELE9BQU8sQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFBO2dCQUNyQixPQUFPLE9BQU8sQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUE7WUFDdEMsQ0FBQyxDQUFDLENBQUE7WUFFRixJQUFJLENBQUMsT0FBTztnQkFBRSxPQUFPLElBQUksQ0FBQTtRQUMzQixDQUFDO1FBRUQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFBO1FBRXpDLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDeEMsSUFBSSxDQUFDLGtCQUFrQixJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQztnQkFBRSxPQUFPLElBQUksQ0FBQTtRQUMzRSxDQUFDO1FBRUQsT0FBTyxLQUFLLENBQUE7SUFDZCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsaUJBQWlCLENBQUMsS0FBSztRQUNyQixJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJO1lBQUUsT0FBTyxLQUFLLENBQUE7UUFFMUQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUE7UUFDN0MsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBRTdDLElBQUksQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDO1lBQUUsT0FBTyxLQUFLLENBQUE7UUFFOUMsT0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUNuQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILG9CQUFvQixDQUFDLFlBQVksRUFBRSxlQUFlO1FBQ2hELE1BQU0sS0FBSyxHQUFHLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFBO1FBRXBELE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQTtJQUMvQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsV0FBVztRQUNmLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLFdBQVcsQ0FBQztnQkFDbEMsYUFBYSxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtnQkFDdEMsVUFBVSxFQUFFLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBQztnQkFDekIsSUFBSSxFQUFFLGFBQWE7YUFDcEIsQ0FBQyxDQUFBO1lBRUYsTUFBTSxJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsRUFBRSxDQUFBO1lBQ3BDLE1BQU0sSUFBSSxDQUFDLFlBQVksQ0FBQyxlQUFlLEVBQUUsQ0FBQTtRQUMzQyxDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFBO0lBQzFCLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxhQUFhO1FBQ2pCLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDekIsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLGFBQWEsRUFBRSxDQUFBO1FBQzNDLENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUE7SUFDNUIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLGVBQWU7UUFDbkIsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQTtJQUM1RixDQUFDO0lBRUQ7O09BRUc7SUFDSCxRQUFRLEtBQUssT0FBTyxJQUFJLENBQUMsWUFBWSxLQUFLLFNBQVMsSUFBSSxJQUFJLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQSxDQUFDLENBQUM7SUFFOUU7O09BRUc7SUFDSCxjQUFjO1FBQ1osSUFBSSxJQUFJLENBQUMsWUFBWSxLQUFLLFNBQVM7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLDJCQUEyQixDQUFDLENBQUE7UUFFakYsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFBO0lBQzFCLENBQUM7SUFFRCwySEFBMkg7SUFDM0gsb0JBQW9CO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUFBO0lBQ2hDLENBQUM7SUFFRDs7T0FFRztJQUNILGtCQUFrQjtRQUNoQixJQUFJLElBQUksQ0FBQyxnQkFBZ0IsS0FBSyxTQUFTO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQywyQkFBMkIsQ0FBQyxDQUFBO1FBRXJGLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFBO0lBQzlCLENBQUM7SUFFRDs7T0FFRztJQUNILGFBQWE7UUFDWCxJQUFJLElBQUksQ0FBQyxXQUFXLEtBQUssU0FBUztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsMkJBQTJCLENBQUMsQ0FBQTtRQUVoRixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUE7SUFDekIsQ0FBQztJQUVEOztPQUVHO0lBQ0gscUJBQXFCO1FBQ25CLElBQUksSUFBSSxDQUFDLGdCQUFnQixLQUFLLFNBQVMsSUFBSSxJQUFJLENBQUMsWUFBWSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzNFLE1BQU0sSUFBSSxLQUFLLENBQUMsMkJBQTJCLENBQUMsQ0FBQTtRQUM5QyxDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQTtJQUNsRCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsT0FBTztRQUNYLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxLQUFLLENBQUE7UUFDN0IsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUE7UUFDckIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLENBQUMsQ0FBQTtRQUN6QixJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQTtRQUNwQixJQUFJLENBQUMsa0JBQWtCLEdBQUcsRUFBRSxDQUFBO1FBQzVCLE1BQU0sSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFBO1FBQzVCLE1BQU0sSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUM5QixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQTtRQUUxQyxNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLFVBQVUsRUFBRSxDQUFBO1FBRTlELElBQUksaUJBQWlCLEVBQUUsQ0FBQztZQUN0QixNQUFNLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLHFCQUFxQixFQUFFLENBQUMsdUJBQXVCLEVBQUUsQ0FBQTtRQUNqRixDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsbUJBQW1CO1FBQ2pCLElBQUksSUFBSSxDQUFDLGdCQUFnQixLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3hDLE1BQU0sSUFBSSxLQUFLLENBQUMsMEJBQTBCLENBQUMsQ0FBQTtRQUM3QyxDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUE7SUFDOUIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLEdBQUc7UUFDUCxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLGlCQUFpQixDQUFDLEtBQUssSUFBSSxFQUFFO1lBQ3pELE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQztnQkFDbEIsV0FBVyxFQUFFLEVBQUU7Z0JBQ2YsWUFBWSxFQUFFLEVBQUU7Z0JBQ2hCLEtBQUs7Z0JBQ0wsWUFBWSxFQUFFLEVBQUU7Z0JBQ2hCLFdBQVcsRUFBRSxDQUFDO2FBQ2YsQ0FBQyxDQUFBO1FBQ0osQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsMkJBQTJCO1FBQy9CLE1BQU0sTUFBTSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQTtRQUV4RCxLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQzNCLE1BQU0sSUFBSSxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ3hDLENBQUM7UUFFRCxJQUFJLENBQUMscUJBQXFCLEdBQUcsRUFBRSxDQUFBO0lBQ2pDLENBQUM7SUFFRDs7O09BR0c7SUFDSCxZQUFZLENBQUMsS0FBSztRQUNoQixJQUFJLHFCQUFxQixHQUFHLEtBQUssQ0FBQTtRQUVqQyxLQUFLLE1BQU0sZUFBZSxJQUFJLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUMxQyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFBO1lBQzdDLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQTtZQUVqRCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUE7WUFFbEIsSUFBSSxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ25CLHFCQUFxQixHQUFHLElBQUksQ0FBQTtnQkFDNUIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQTtZQUM5QixDQUFDO1FBQ0gsQ0FBQztRQUVELEtBQUssTUFBTSxjQUFjLElBQUksS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3hDLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUE7WUFDMUMsTUFBTSxFQUFDLGdCQUFnQixFQUFDLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQTtZQUVyRCxJQUFJLGdCQUFnQixFQUFFLENBQUM7Z0JBQ3JCLHFCQUFxQixHQUFHLElBQUksQ0FBQTtZQUM5QixDQUFDO1lBRUQsT0FBTyxDQUFDLGdCQUFnQixHQUFHLGdCQUFnQixDQUFBO1FBQzdDLENBQUM7UUFFRCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUUscUJBQXFCLEVBQUMsQ0FBQTtJQUNsRCxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0gsS0FBSyxDQUFDLFFBQVEsQ0FBQyxFQUFDLFdBQVcsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsa0JBQWtCLEdBQUcsS0FBSyxFQUFDO1FBQ3RHLE1BQU0sV0FBVyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQyxDQUFBO1FBQy9DLE1BQU0sY0FBYyxHQUFHLENBQUMsR0FBRyxXQUFXLEVBQUUsR0FBRyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUE7UUFDN0QsTUFBTSxlQUFlLEdBQUcsQ0FBQyxHQUFHLFlBQVksRUFBRSxHQUFHLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQTtRQUNoRSxNQUFNLGNBQWMsR0FBRyxrQkFBa0IsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDMUUsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLFlBQVksRUFBRSxjQUFjLENBQUMsQ0FBQTtRQUVwRixJQUFJLENBQUMsaUJBQWlCO1lBQUUsT0FBTTtRQUU5Qiw0REFBNEQ7UUFDNUQsTUFBTSxVQUFVLEdBQUcsRUFBQyxLQUFLLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBQyxDQUFBO1FBQy9DLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUE7UUFFM0MsSUFBSSxDQUFDO1lBQ0gsS0FBSyxNQUFNLGFBQWEsSUFBSSxLQUFLLENBQUMsVUFBVSxJQUFJLEVBQUUsRUFBRSxDQUFDO2dCQUNuRCxNQUFNLGFBQWEsQ0FBQyxRQUFRLENBQUMsRUFBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEVBQUMsQ0FBQyxDQUFBO1lBQ3hFLENBQUM7WUFFRCxLQUFLLE1BQU0sZUFBZSxJQUFJLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDMUMsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQTtnQkFDN0MsTUFBTSxRQUFRLEdBQUcsdUJBQXVCLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtnQkFDM0UsTUFBTSxhQUFhLEdBQUcsY0FBYyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsQ0FBQTtnQkFFeEUsSUFBSSxJQUFJLENBQUMsYUFBYSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUs7b0JBQUUsU0FBUTtnQkFDbkQsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsZUFBZSxFQUFFLFlBQVksRUFBRSxhQUFhLENBQUM7b0JBQUUsU0FBUTtnQkFFbkcsSUFBSSxRQUFRLENBQUMsSUFBSSxJQUFJLE9BQU8sSUFBSSxRQUFRLENBQUMsSUFBSSxJQUFJLFNBQVMsRUFBRSxDQUFDO29CQUMzRCxRQUFRLENBQUMsV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFBO2dCQUNqRCxDQUFDO2dCQUVELElBQUksUUFBUSxDQUFDLElBQUksSUFBSSxTQUFTLEVBQUUsQ0FBQztvQkFDL0IsUUFBUSxDQUFDLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQTtnQkFDOUMsQ0FBQztnQkFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsV0FBVyxNQUFNLGVBQWUsRUFBRSxDQUFDLENBQUE7Z0JBRWxELE1BQU0sVUFBVSxHQUFHLE9BQU8sUUFBUSxDQUFDLEtBQUssS0FBSyxRQUFRLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO29CQUN0RixDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQ3pDLENBQUMsQ0FBQyxDQUFDLENBQUE7Z0JBQ0wsTUFBTSxvQkFBb0IsR0FBRyxPQUFPLFVBQVUsQ0FBQyxxQkFBcUIsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFBO2dCQUNoSSxNQUFNLGNBQWMsR0FBRyxPQUFPLFFBQVEsQ0FBQyxjQUFjLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQTtnQkFDbkgsTUFBTSxVQUFVLEdBQUcsT0FBTyxjQUFjLEtBQUssUUFBUSxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLElBQUksY0FBYyxHQUFHLENBQUMsQ0FBQTtnQkFDOUcsTUFBTSxTQUFTLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUE7Z0JBQ2hFLElBQUksV0FBVyxHQUFHLENBQUMsQ0FBQTtnQkFDbkIsSUFBSSxhQUFhLEdBQUcsQ0FBQyxDQUFBO2dCQUVyQixPQUFPLElBQUksRUFBRSxDQUFDO29CQUNaLElBQUksV0FBVyxHQUFHLEtBQUssQ0FBQTtvQkFDdkIsc0JBQXNCO29CQUN0QixJQUFJLFdBQVcsQ0FBQTtvQkFDZixzQkFBc0I7b0JBQ3RCLElBQUksU0FBUyxDQUFBO29CQUViLElBQUksQ0FBQzt3QkFDSCxNQUFNLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLEVBQUUsS0FBSyxJQUFJLEVBQUU7NEJBQ25ELElBQUksQ0FBQztnQ0FDSCxlQUFlLEVBQUUsQ0FBQTtnQ0FDakIsS0FBSyxNQUFNLGNBQWMsSUFBSSxlQUFlLEVBQUUsQ0FBQztvQ0FDN0MsTUFBTSxjQUFjLENBQUMsUUFBUSxDQUFDLEVBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUMsQ0FBQyxDQUFBO2dDQUM3RixDQUFDO2dDQUVELE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUE7Z0NBRS9DLElBQUksVUFBVSxJQUFJLFNBQVMsS0FBSyxTQUFTLEVBQUUsQ0FBQztvQ0FDMUMsTUFBTSxjQUFjLENBQUMsV0FBVyxFQUFFLFNBQVMsRUFBRSxlQUFlLENBQUMsQ0FBQTtnQ0FDL0QsQ0FBQztxQ0FBTSxDQUFDO29DQUNOLE1BQU0sV0FBVyxDQUFBO2dDQUNuQixDQUFDO2dDQUNELElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFBOzRCQUN6QixDQUFDO29DQUFTLENBQUM7Z0NBQ1QsS0FBSyxNQUFNLGFBQWEsSUFBSSxjQUFjLEVBQUUsQ0FBQztvQ0FDM0MsTUFBTSxhQUFhLENBQUMsUUFBUSxDQUFDLEVBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUMsQ0FBQyxDQUFBO2dDQUM1RixDQUFDOzRCQUNILENBQUM7d0JBQ0gsQ0FBQyxDQUFDLENBQUE7b0JBQ0osQ0FBQztvQkFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO3dCQUNmLFNBQVMsR0FBRyxLQUFLLENBQUE7d0JBQ2pCLElBQUksV0FBVyxHQUFHLFVBQVUsRUFBRSxDQUFDOzRCQUM3QixXQUFXLEVBQUUsQ0FBQTs0QkFDYixXQUFXLEdBQUcsSUFBSSxDQUFBOzRCQUNsQixPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxXQUFXLGVBQWUsV0FBVyxJQUFJLFVBQVUsa0JBQWtCLEtBQUssWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQTs0QkFDOUosTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsRUFBRTtnQ0FDbkMsYUFBYSxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtnQ0FDdEMsWUFBWTtnQ0FDWixLQUFLO2dDQUNMLFdBQVcsRUFBRSxhQUFhLEdBQUcsQ0FBQztnQ0FDOUIsV0FBVztnQ0FDWCxVQUFVO2dDQUNWLFFBQVE7Z0NBQ1IsUUFBUTtnQ0FDUixlQUFlO2dDQUNmLFVBQVUsRUFBRSxJQUFJOzZCQUNqQixDQUFDLENBQUE7d0JBQ0osQ0FBQzs2QkFBTSxDQUFDOzRCQUNOLFdBQVcsR0FBRyxLQUFLLENBQUE7d0JBQ3JCLENBQUM7b0JBQ0gsQ0FBQztvQkFFRCxJQUFJLGFBQWEsR0FBRyxDQUFDLEVBQUUsQ0FBQzt3QkFDdEIsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsRUFBRTs0QkFDbEMsYUFBYSxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTs0QkFDdEMsWUFBWTs0QkFDWixLQUFLLEVBQUUsU0FBUzs0QkFDaEIsYUFBYTs0QkFDYixXQUFXOzRCQUNYLFVBQVU7NEJBQ1YsUUFBUTs0QkFDUixRQUFROzRCQUNSLGVBQWU7NEJBQ2YsVUFBVSxFQUFFLElBQUk7eUJBQ2pCLENBQUMsQ0FBQTtvQkFDSixDQUFDO29CQUVELGFBQWEsRUFBRSxDQUFBO29CQUVmLElBQUksV0FBVzt3QkFBRSxTQUFRO29CQUV6QixJQUFJLFdBQVcsRUFBRSxDQUFDO3dCQUNoQixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUE7d0JBQ25CLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUM7NEJBQzNCLGVBQWUsRUFBRSxJQUFJLENBQUMsb0JBQW9CLENBQUMsWUFBWSxFQUFFLGVBQWUsQ0FBQzs0QkFDekUsUUFBUSxFQUFFLFFBQVEsQ0FBQyxRQUFROzRCQUMzQixJQUFJLEVBQUUsUUFBUSxDQUFDLElBQUk7NEJBQ25CLEtBQUssRUFBRSxXQUFXO3lCQUNuQixDQUFDLENBQUE7d0JBRUYsSUFBSSxXQUFXLFlBQVksS0FBSyxFQUFFLENBQUM7NEJBQ2pDLE9BQU8sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLFdBQVcsa0JBQWtCLFdBQVcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUE7NEJBQ3BGLHNCQUFzQixDQUFDLFdBQVcsQ0FBQyxDQUFBOzRCQUVuQyxNQUFNLGdCQUFnQixHQUFHLElBQUksZ0JBQWdCLENBQUMsV0FBVyxDQUFDLENBQUE7NEJBQzFELE1BQU0sWUFBWSxHQUFHLGdCQUFnQixDQUFDLGVBQWUsRUFBRSxDQUFBOzRCQUN2RCxNQUFNLFVBQVUsR0FBRyxZQUFZLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFBOzRCQUU1QyxJQUFJLFVBQVUsRUFBRSxDQUFDO2dDQUNmLEtBQUssTUFBTSxTQUFTLElBQUksVUFBVSxFQUFFLENBQUM7b0NBQ25DLE9BQU8sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLFdBQVcsS0FBSyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUE7Z0NBQy9ELENBQUM7NEJBQ0gsQ0FBQzt3QkFDSCxDQUFDOzZCQUFNLENBQUM7NEJBQ04sT0FBTyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsV0FBVyx3QkFBd0IsT0FBTyxXQUFXLEtBQUssTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFBO3dCQUNuSCxDQUFDO3dCQUVELE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLEVBQUU7NEJBQ2pDLGFBQWEsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7NEJBQ3RDLFlBQVk7NEJBQ1osS0FBSyxFQUFFLFdBQVc7NEJBQ2xCLFFBQVE7NEJBQ1IsUUFBUTs0QkFDUixlQUFlOzRCQUNmLFVBQVUsRUFBRSxJQUFJO3lCQUNqQixDQUFDLENBQUE7d0JBRUYsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEVBQUMsWUFBWSxFQUFFLGVBQWUsRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFDLENBQUMsQ0FBQTtvQkFDaEYsQ0FBQztvQkFFRCxNQUFLO2dCQUNQLENBQUM7WUFDSCxDQUFDO1lBRUQsS0FBSyxNQUFNLGNBQWMsSUFBSSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ3hDLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUE7Z0JBQzFDLE1BQU0sY0FBYyxHQUFHLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFBO2dCQUM1RCxNQUFNLG1CQUFtQixHQUFHLGNBQWMsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUE7Z0JBRTdFLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxJQUFJLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO29CQUNwRCxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsV0FBVyxHQUFHLGNBQWMsRUFBRSxDQUFDLENBQUE7b0JBQzlDLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQzt3QkFDbEIsV0FBVyxFQUFFLGNBQWM7d0JBQzNCLFlBQVksRUFBRSxlQUFlO3dCQUM3QixLQUFLLEVBQUUsT0FBTzt3QkFDZCxZQUFZLEVBQUUsY0FBYzt3QkFDNUIsV0FBVyxFQUFFLFdBQVcsR0FBRyxDQUFDO3dCQUM1QixrQkFBa0IsRUFBRSxtQkFBbUI7cUJBQ3hDLENBQUMsQ0FBQTtnQkFDSixDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7Z0JBQVMsQ0FBQztZQUNULE1BQU0sSUFBSSxDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxDQUFBO1lBQzNDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUE7WUFFakUsSUFBSSxVQUFVLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ3BCLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFBO1lBQ2xELENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7T0FHRztJQUNILEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVO1FBQ25DLElBQUksVUFBVSxDQUFDLFlBQVk7WUFBRSxPQUFNO1FBRW5DLFVBQVUsQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFBO1FBRTlCLEtBQUssTUFBTSxZQUFZLElBQUksVUFBVSxDQUFDLEtBQUssQ0FBQyxTQUFTLElBQUksRUFBRSxFQUFFLENBQUM7WUFDNUQsTUFBTSxZQUFZLENBQUMsUUFBUSxDQUFDLEVBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxFQUFDLENBQUMsQ0FBQTtRQUN2RSxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxPQUFPO1FBQ2hDLE1BQU0sU0FBUyxHQUFHLFVBQVUsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUE7UUFFakQsS0FBSyxNQUFNLFFBQVEsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUNqQyxNQUFNLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUN6QixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxpQkFBaUIsQ0FBQyxFQUFDLFlBQVksRUFBRSxlQUFlLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBQztRQUN0RSxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsRUFBQyxZQUFZLEVBQUUsZUFBZSxFQUFFLFFBQVEsRUFBQyxDQUFDLENBQUE7UUFFL0UsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUNWLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxXQUFXLGFBQWEsS0FBSyxFQUFFLENBQUMsQ0FBQTtRQUNuRCxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILGlCQUFpQixDQUFDLEVBQUMsWUFBWSxFQUFFLGVBQWUsRUFBRSxRQUFRLEVBQUM7UUFDekQsTUFBTSxXQUFXLEdBQUcsb0JBQW9CLENBQUE7UUFDeEMsTUFBTSxRQUFRLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQTtRQUNsQyxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFBO1FBRTFCLElBQUksUUFBUSxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ3JCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFBO1lBQzNELE9BQU8sR0FBRyxXQUFXLElBQUksWUFBWSxJQUFJLElBQUksRUFBRSxDQUFBO1FBQ2pELENBQUM7UUFFRCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsWUFBWSxFQUFFLGVBQWUsQ0FBQyxDQUFBO1FBRWhGLElBQUksZUFBZSxFQUFFLENBQUM7WUFDcEIsT0FBTyxHQUFHLFdBQVcsY0FBYyxJQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUE7UUFDdEUsQ0FBQztRQUVELE9BQU8sU0FBUyxDQUFBO0lBQ2xCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQge2FkZFRyYWNrZWRTdGFja1RvRXJyb3J9IGZyb20gXCIuLi91dGlscy93aXRoLXRyYWNrZWQtc3RhY2suanNcIlxuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIlxuaW1wb3J0IEFwcGxpY2F0aW9uIGZyb20gXCIuLi8uLi9zcmMvYXBwbGljYXRpb24uanNcIlxuaW1wb3J0IEJhY2t0cmFjZUNsZWFuZXIgZnJvbSBcIi4uL3V0aWxzL2JhY2t0cmFjZS1jbGVhbmVyLmpzXCJcbmltcG9ydCBSZXF1ZXN0Q2xpZW50IGZyb20gXCIuL3JlcXVlc3QtY2xpZW50LmpzXCJcbmltcG9ydCBwaWNvY29sb3JzIGZyb20gXCJwaWNvY29sb3JzXCJcbmltcG9ydCByZXN0QXJnc0Vycm9yIGZyb20gXCIuLi91dGlscy9yZXN0LWFyZ3MtZXJyb3IuanNcIlxuaW1wb3J0IHt0ZXN0Q29uZmlnLCB0ZXN0RXZlbnRzLCB0ZXN0c30gZnJvbSBcIi4vdGVzdC5qc1wiXG5pbXBvcnQge3BhdGhUb0ZpbGVVUkx9IGZyb20gXCJ1cmxcIlxuaW1wb3J0IHtjbGVhckRlbGl2ZXJpZXN9IGZyb20gXCIuLi9tYWlsZXIuanNcIlxuXG4vKipcbiAqIEBwYXJhbSB7UHJvbWlzZTx1bmtub3duPiB8IHVua25vd259IHByb21pc2UgLSBQcm9taXNlIG9yIHZhbHVlLlxuICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXRNcyAtIFRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzLlxuICogQHBhcmFtIHtzdHJpbmd9IHRlc3REZXNjcmlwdGlvbiAtIFRlc3QgZGVzY3JpcHRpb24uXG4gKiBAcmV0dXJucyB7UHJvbWlzZTx1bmtub3duPn0gLSBSZXNvbHZlcyBvciByZWplY3RzIGJhc2VkIG9uIHRpbWVvdXQgb3IgcHJvbWlzZSByZXN1bHQuXG4gKi9cbmZ1bmN0aW9uIHJ1bldpdGhUaW1lb3V0KHByb21pc2UsIHRpbWVvdXRNcywgdGVzdERlc2NyaXB0aW9uKSB7XG4gIGNvbnN0IHRpbWVvdXRTZWNvbmRzID0gKHRpbWVvdXRNcyAvIDEwMDApLnRvRml4ZWQoMykucmVwbGFjZSgvXFwuPzArJC8sIFwiXCIpXG4gIGNvbnN0IHRpbWVvdXRFcnJvciA9IG5ldyBFcnJvcihgVGltZWQgb3V0IGFmdGVyICR7dGltZW91dFNlY29uZHN9czogJHt0ZXN0RGVzY3JpcHRpb259YClcblxuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHJlamVjdCh0aW1lb3V0RXJyb3IpLCB0aW1lb3V0TXMpXG5cbiAgICBQcm9taXNlLnJlc29sdmUocHJvbWlzZSkudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dClcbiAgICAgIHJlc29sdmUocmVzdWx0KVxuICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpXG4gICAgICByZWplY3QoZXJyb3IpXG4gICAgfSlcbiAgfSlcbn1cblxuLyoqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBUZXN0QXJnc1xuICogQHByb3BlcnR5IHtBcHBsaWNhdGlvbn0gW2FwcGxpY2F0aW9uXSAtIEFwcGxpY2F0aW9uIGluc3RhbmNlIGZvciBpbnRlZ3JhdGlvbiB0ZXN0cy5cbiAqIEBwcm9wZXJ0eSB7UmVxdWVzdENsaWVudH0gW2NsaWVudF0gLSBIVFRQIGNsaWVudCBmb3IgcmVxdWVzdCB0ZXN0cy5cbiAqIEBwcm9wZXJ0eSB7b2JqZWN0fSBbZGF0YWJhc2VDbGVhbmluZ10gLSBEYXRhYmFzZSBjbGVhbnVwIG9wdGlvbnMgZm9yIHRlc3RzLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbZGF0YWJhc2VDbGVhbmluZy50cmFuc2FjdGlvbl0gLSBVc2UgdHJhbnNhY3Rpb25zIHRvIHJvbGxiYWNrIGJldHdlZW4gdGVzdHMuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtkYXRhYmFzZUNsZWFuaW5nLnRydW5jYXRlXSAtIFRydW5jYXRlIHRhYmxlcyBiZXR3ZWVuIHRlc3RzLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbZm9jdXNdIC0gV2hldGhlciB0aGlzIHRlc3QgaXMgZm9jdXNlZC5cbiAqIEBwcm9wZXJ0eSB7KCkgPT4gKHZvaWR8UHJvbWlzZTx2b2lkPil9IFtmdW5jdGlvbl0gLSBUZXN0IGNhbGxiYWNrIGZ1bmN0aW9uLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtyZXRyeV0gLSBOdW1iZXIgb2YgcmV0cmllcyB3aGVuIGEgdGVzdCBmYWlscy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW10gfCBzdHJpbmd9IFt0YWdzXSAtIFRhZ3MgZm9yIGZpbHRlcmluZy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbdGltZW91dFNlY29uZHNdIC0gVGltZW91dCBpbiBzZWNvbmRzIGZvciB0aGUgdGVzdC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbdHlwZV0gLSBUZXN0IHR5cGUgaWRlbnRpZmllci5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtvYmplY3R9IFRlc3REYXRhXG4gKiBAcHJvcGVydHkge1Rlc3RBcmdzfSBhcmdzIC0gQXJndW1lbnRzIHBhc3NlZCB0byB0aGUgdGVzdC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbZmlsZVBhdGhdIC0gU291cmNlIGZpbGUgcGF0aC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbGluZV0gLSBTb3VyY2UgbGluZSBudW1iZXIuXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9uKFRlc3RBcmdzKSA6ICh2b2lkfFByb21pc2U8dm9pZD4pfSBmdW5jdGlvbiAtIFRlc3QgY2FsbGJhY2sgdG8gZXhlY3V0ZS5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtmdW5jdGlvbih7Y29uZmlndXJhdGlvbjogaW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0LCB0ZXN0QXJnczogVGVzdEFyZ3MsIHRlc3REYXRhOiBUZXN0RGF0YX0pIDogKHZvaWR8UHJvbWlzZTx2b2lkPil9IEFmdGVyQmVmb3JlRWFjaENhbGxiYWNrVHlwZVxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge29iamVjdH0gQWZ0ZXJCZWZvcmVFYWNoQ2FsbGJhY2tPYmplY3RUeXBlXG4gKiBAcHJvcGVydHkge0FmdGVyQmVmb3JlRWFjaENhbGxiYWNrVHlwZX0gY2FsbGJhY2sgLSBIb29rIGNhbGxiYWNrIHRvIGV4ZWN1dGUuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oe2NvbmZpZ3VyYXRpb246IGltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0pIDogKHZvaWR8UHJvbWlzZTx2b2lkPil9IEJlZm9yZUFmdGVyQWxsQ2FsbGJhY2tUeXBlXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBCZWZvcmVBZnRlckFsbENhbGxiYWNrT2JqZWN0VHlwZVxuICogQHByb3BlcnR5IHtCZWZvcmVBZnRlckFsbENhbGxiYWNrVHlwZX0gY2FsbGJhY2sgLSBIb29rIGNhbGxiYWNrIHRvIGV4ZWN1dGUuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBUZXN0c0FyZ3VtZW50XG4gKiBAcHJvcGVydHkge1JlY29yZDxzdHJpbmcsIFRlc3REYXRhPn0gYXJncyAtIEFyZ3VtZW50cyBrZXllZCBieSB0ZXN0IGRlc2NyaXB0aW9uLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbYW55VGVzdHNGb2N1c3NlZF0gLSBXaGV0aGVyIGFueSB0ZXN0cyBpbiB0aGUgdHJlZSBhcmUgZm9jdXNlZC5cbiAqIEBwcm9wZXJ0eSB7QWZ0ZXJCZWZvcmVFYWNoQ2FsbGJhY2tPYmplY3RUeXBlW119IGFmdGVyRWFjaGVzIC0gQWZ0ZXItZWFjaCBob29rcyBmb3IgdGhpcyBzY29wZS5cbiAqIEBwcm9wZXJ0eSB7QmVmb3JlQWZ0ZXJBbGxDYWxsYmFja09iamVjdFR5cGVbXX0gYWZ0ZXJBbGxzIC0gQWZ0ZXItYWxsIGhvb2tzIGZvciB0aGlzIHNjb3BlLlxuICogQHByb3BlcnR5IHtCZWZvcmVBZnRlckFsbENhbGxiYWNrT2JqZWN0VHlwZVtdfSBiZWZvcmVBbGxzIC0gQmVmb3JlLWFsbCBob29rcyBmb3IgdGhpcyBzY29wZS5cbiAqIEBwcm9wZXJ0eSB7QWZ0ZXJCZWZvcmVFYWNoQ2FsbGJhY2tPYmplY3RUeXBlW119IGJlZm9yZUVhY2hlcyAtIEJlZm9yZS1lYWNoIGhvb2tzIGZvciB0aGlzIHNjb3BlLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtmaWxlUGF0aF0gLSBTb3VyY2UgZmlsZSBwYXRoLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtsaW5lXSAtIFNvdXJjZSBsaW5lIG51bWJlci5cbiAqIEBwcm9wZXJ0eSB7UmVjb3JkPHN0cmluZywgVGVzdERhdGE+fSB0ZXN0cyAtIEEgdW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBub2RlLlxuICogQHByb3BlcnR5IHtSZWNvcmQ8c3RyaW5nLCBUZXN0c0FyZ3VtZW50Pn0gc3VicyAtIE9wdGlvbmFsIGNoaWxkIG5vZGVzLiBFYWNoIGl0ZW0gaXMgYW5vdGhlciBgTm9kZWAsIGFsbG93aW5nIHJlY3Vyc2lvbi5cbiAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUZXN0UnVubmVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSBhcmdzLmNvbmZpZ3VyYXRpb24gLSBDb25maWd1cmF0aW9uIGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdIHwgc3RyaW5nfSBbYXJncy5leGNsdWRlVGFnc10gLSBUYWdzIHRvIGV4Y2x1ZGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nW10gfCBzdHJpbmd9IFthcmdzLmluY2x1ZGVUYWdzXSAtIFRhZ3MgdG8gaW5jbHVkZS5cbiAgICogQHBhcmFtIHtBcnJheTxzdHJpbmc+fSBhcmdzLnRlc3RGaWxlcyAtIFRlc3QgZmlsZXMuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgbnVtYmVyW10+fSBbYXJncy5saW5lRmlsdGVyc10gLSBMaW5lIGZpbHRlcnMgYnkgZmlsZS5cbiAgICogQHBhcmFtIHtSZWdFeHBbXX0gW2FyZ3MuZXhhbXBsZVBhdHRlcm5zXSAtIEV4YW1wbGUgcGF0dGVybnMuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7Y29uZmlndXJhdGlvbiwgZXhjbHVkZVRhZ3MsIGluY2x1ZGVUYWdzLCB0ZXN0RmlsZXMsIGxpbmVGaWx0ZXJzLCBleGFtcGxlUGF0dGVybnMsIC4uLnJlc3RBcmdzfSkge1xuICAgIHJlc3RBcmdzRXJyb3IocmVzdEFyZ3MpXG5cbiAgICBpZiAoIWNvbmZpZ3VyYXRpb24pIHRocm93IG5ldyBFcnJvcihcImNvbmZpZ3VyYXRpb24gaXMgcmVxdWlyZWRcIilcblxuICAgIHRoaXMuX2NvbmZpZ3VyYXRpb24gPSBjb25maWd1cmF0aW9uXG4gICAgdGhpcy5fZXhjbHVkZVRhZ3MgPSB0aGlzLm5vcm1hbGl6ZVRhZ3MoZXhjbHVkZVRhZ3MpXG4gICAgdGhpcy5fZXhjbHVkZVRhZ1NldCA9IG5ldyBTZXQodGhpcy5fZXhjbHVkZVRhZ3MpXG4gICAgdGhpcy5faW5jbHVkZVRhZ3MgPSB0aGlzLm5vcm1hbGl6ZVRhZ3MoaW5jbHVkZVRhZ3MpXG4gICAgdGhpcy5faW5jbHVkZVRhZ1NldCA9IG5ldyBTZXQodGhpcy5faW5jbHVkZVRhZ3MpXG4gICAgdGhpcy5fdGVzdEZpbGVzID0gdGVzdEZpbGVzXG4gICAgdGhpcy5fbGluZUZpbHRlcnMgPSBsaW5lRmlsdGVycyB8fCB7fVxuICAgIHRoaXMuX2V4YW1wbGVQYXR0ZXJucyA9IGV4YW1wbGVQYXR0ZXJucyB8fCBbXVxuXG4gICAgdGhpcy5fZmFpbGVkVGVzdHMgPSAwXG4gICAgdGhpcy5fc3VjY2Vzc2Z1bFRlc3RzID0gMFxuICAgIHRoaXMuX3Rlc3RzQ291bnQgPSAwXG4gICAgdGhpcy5fYWN0aXZlQWZ0ZXJBbGxTY29wZXMgPSBbXVxuICAgIHRoaXMuX2ZhaWxlZFRlc3REZXRhaWxzID0gW11cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSAtIFRoZSBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgZ2V0Q29uZmlndXJhdGlvbigpIHsgcmV0dXJuIHRoaXMuX2NvbmZpZ3VyYXRpb24gfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nW119IC0gVGhlIHRlc3QgZmlsZXMuXG4gICAqL1xuICBnZXRUZXN0RmlsZXMoKSB7IHJldHVybiB0aGlzLl90ZXN0RmlsZXMgfVxuXG4gIC8qKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgbnVtYmVyW10+fSAtIExpbmUgZmlsdGVycy4gKi9cbiAgZ2V0TGluZUZpbHRlcnMoKSB7IHJldHVybiB0aGlzLl9saW5lRmlsdGVycyB9XG5cbiAgLyoqIEByZXR1cm5zIHtSZWdFeHBbXX0gLSBFeGFtcGxlIHBhdHRlcm5zLiAqL1xuICBnZXRFeGFtcGxlUGF0dGVybnMoKSB7IHJldHVybiB0aGlzLl9leGFtcGxlUGF0dGVybnMgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdIHwgc3RyaW5nIHwgdW5kZWZpbmVkfSB0YWdzIC0gVGFncy5cbiAgICogQHJldHVybnMge3N0cmluZ1tdfSAtIE5vcm1hbGl6ZWQgdGFncy5cbiAgICovXG4gIG5vcm1hbGl6ZVRhZ3ModGFncykge1xuICAgIGlmICghdGFncykgcmV0dXJuIFtdXG5cbiAgICBjb25zdCB2YWx1ZXMgPSBbXVxuICAgIGNvbnN0IHJhd1RhZ3MgPSBBcnJheS5pc0FycmF5KHRhZ3MpID8gdGFncyA6IFt0YWdzXVxuXG4gICAgZm9yIChjb25zdCByYXdUYWcgb2YgcmF3VGFncykge1xuICAgICAgaWYgKHJhd1RhZyA9PT0gdW5kZWZpbmVkIHx8IHJhd1RhZyA9PT0gbnVsbCkgY29udGludWVcblxuICAgICAgY29uc3QgcGFydHMgPSBTdHJpbmcocmF3VGFnKS5zcGxpdChcIixcIilcblxuICAgICAgZm9yIChjb25zdCBwYXJ0IG9mIHBhcnRzKSB7XG4gICAgICAgIGNvbnN0IHRyaW1tZWQgPSBwYXJ0LnRyaW0oKVxuXG4gICAgICAgIGlmICh0cmltbWVkKSB2YWx1ZXMucHVzaCh0cmltbWVkKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQodmFsdWVzKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1Rlc3RBcmdzfSB0ZXN0QXJncyAtIFRlc3QgYXJncy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhZyAtIFRhZyB0byBjaGVjayBmb3IuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgdGFnIGlzIHByZXNlbnQuXG4gICAqL1xuICBoYXNUYWcodGVzdEFyZ3MsIHRhZykge1xuICAgIHJldHVybiB0aGlzLm5vcm1hbGl6ZVRhZ3ModGVzdEFyZ3M/LnRhZ3MpLmluY2x1ZGVzKHRhZylcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHJ1bm5pbmcgYnJvd3NlciB0ZXN0cy5cbiAgICovXG4gIGlzQnJvd3NlclRlc3RNb2RlKCkge1xuICAgIHJldHVybiBwcm9jZXNzLmVudi5WRUxPQ0lPVVNfQlJPV1NFUl9URVNUUyA9PT0gXCJ0cnVlXCJcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1Rlc3RBcmdzfSB0ZXN0QXJncyAtIFRlc3QgYXJncy5cbiAgICogQHBhcmFtIHsoKSA9PiBQcm9taXNlPHZvaWQ+fSBjYWxsYmFjayAtIENhbGxiYWNrIHRvIHJ1bi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHJ1bldpdGhEdW1teUlmTmVlZGVkKHRlc3RBcmdzLCBjYWxsYmFjaykge1xuICAgIGlmICghdGhpcy5oYXNUYWcodGVzdEFyZ3MsIFwiZHVtbXlcIikpIHtcbiAgICAgIGF3YWl0IGNhbGxiYWNrKClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmICh0aGlzLmlzQnJvd3NlclRlc3RNb2RlKCkpIHtcbiAgICAgIGF3YWl0IHRoaXMucnVuQnJvd3NlckR1bW15KGNhbGxiYWNrKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5ydW5Ob2RlRHVtbXkoY2FsbGJhY2spXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHsoKSA9PiBQcm9taXNlPHZvaWQ+fSBjYWxsYmFjayAtIENhbGxiYWNrIHRvIHJ1bi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHJ1bk5vZGVEdW1teShjYWxsYmFjaykge1xuICAgIGNvbnN0IGR1bW15UGF0aCA9IHByb2Nlc3MuZW52LlZFTE9DSU9VU19EVU1NWV9QQVRIIHx8IHRoaXMuZGVmYXVsdER1bW15UGF0aCgpXG4gICAgY29uc3QgZHVtbXlJbXBvcnQgPSBhd2FpdCBpbXBvcnQocGF0aFRvRmlsZVVSTChkdW1teVBhdGgpLmhyZWYpXG4gICAgY29uc3QgRHVtbXkgPSBkdW1teUltcG9ydC5kZWZhdWx0XG5cbiAgICBpZiAoIUR1bW15Py5ydW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRHVtbXkgaGVscGVyIG5vdCBmb3VuZCBhdCAke2R1bW15UGF0aH1gKVxuICAgIH1cblxuICAgIGF3YWl0IER1bW15LnJ1bihjYWxsYmFjaylcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIERlZmF1bHQgZHVtbXkgaGVscGVyIHBhdGguXG4gICAqL1xuICBkZWZhdWx0RHVtbXlQYXRoKCkge1xuICAgIGNvbnN0IGN3ZCA9IHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpKVxuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBjd2Quc3BsaXQocGF0aC5zZXApLmpvaW4oXCIvXCIpXG5cbiAgICBpZiAobm9ybWFsaXplZC5lbmRzV2l0aChcIi9zcGVjL2R1bW15XCIpKSB7XG4gICAgICByZXR1cm4gcGF0aC5qb2luKGN3ZCwgXCJpbmRleC5qc1wiKVxuICAgIH1cblxuICAgIHJldHVybiBwYXRoLmpvaW4oY3dkLCBcInNwZWMvZHVtbXkvaW5kZXguanNcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0geygpID0+IFByb21pc2U8dm9pZD59IGNhbGxiYWNrIC0gQ2FsbGJhY2sgdG8gcnVuLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgcnVuQnJvd3NlckR1bW15KGNhbGxiYWNrKSB7XG4gICAgYXdhaXQgdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuZW5zdXJlQ29ubmVjdGlvbnMoYXN5bmMgKGRicykgPT4ge1xuICAgICAgYXdhaXQgdGhpcy50cnVuY2F0ZURhdGFiYXNlcyhkYnMpXG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGNhbGxiYWNrKClcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGF3YWl0IHRoaXMudHJ1bmNhdGVEYXRhYmFzZXMoZGJzKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBpbXBvcnQoXCIuLi9kYXRhYmFzZS9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59IGRicyAtIERhdGFiYXNlIGNvbm5lY3Rpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgdHJ1bmNhdGVEYXRhYmFzZXMoZGJzKSB7XG4gICAgZm9yIChjb25zdCBpZGVudGlmaWVyIG9mIE9iamVjdC5rZXlzKGRicykpIHtcbiAgICAgIGF3YWl0IGRic1tpZGVudGlmaWVyXS50cnVuY2F0ZUFsbFRhYmxlcygpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtTZXQ8c3RyaW5nPn0gLSBFeGNsdWRlIHRhZyBzZXQuXG4gICAqL1xuICBnZXRFeGNsdWRlVGFnU2V0KCkge1xuICAgIGNvbnN0IGNvbmZpZ1RhZ3MgPSBBcnJheS5pc0FycmF5KHRlc3RDb25maWcuZXhjbHVkZVRhZ3MpID8gdGVzdENvbmZpZy5leGNsdWRlVGFncyA6IFtdXG5cbiAgICByZXR1cm4gbmV3IFNldChbLi4udGhpcy5fZXhjbHVkZVRhZ3MsIC4uLmNvbmZpZ1RhZ3NdKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nW10gfCBzdHJpbmcgfCB1bmRlZmluZWR9IHRlc3RUYWdzIC0gVGVzdCB0YWdzLlxuICAgKiBAcGFyYW0ge1NldDxzdHJpbmc+fSB0YWdTZXQgLSBUYWcgc2V0LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGFueSB0YWdzIG1hdGNoLlxuICAgKi9cbiAgaGFzTWF0Y2hpbmdUYWcodGVzdFRhZ3MsIHRhZ1NldCkge1xuICAgIGlmICghdGFnU2V0LnNpemUpIHJldHVybiBmYWxzZVxuXG4gICAgY29uc3Qgbm9ybWFsaXplZCA9IHRoaXMubm9ybWFsaXplVGFncyh0ZXN0VGFncylcblxuICAgIGZvciAoY29uc3QgdGFnIG9mIG5vcm1hbGl6ZWQpIHtcbiAgICAgIGlmICh0YWdTZXQuaGFzKHRhZykpIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtUZXN0c0FyZ3VtZW50fSB0ZXN0cyAtIFRlc3RzLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBbZGVzY3JpcHRpb25zXSAtIERlc2NyaXB0aW9uIHN0YWNrLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtsaW5lTWF0Y2hlZEluU2NvcGVdIC0gV2hldGhlciBsaW5lIG1hdGNoZWQgaW4gc2NvcGUuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgYW55IHRlc3RzIGluIHRoaXMgc2NvcGUgd2lsbCBydW4uXG4gICAqL1xuICBoYXNSdW5uYWJsZVRlc3RzKHRlc3RzLCBkZXNjcmlwdGlvbnMgPSBbXSwgbGluZU1hdGNoZWRJblNjb3BlID0gZmFsc2UpIHtcbiAgICBmb3IgKGNvbnN0IHRlc3REZXNjcmlwdGlvbiBpbiB0ZXN0cy50ZXN0cykge1xuICAgICAgY29uc3QgdGVzdERhdGEgPSB0ZXN0cy50ZXN0c1t0ZXN0RGVzY3JpcHRpb25dXG4gICAgICBjb25zdCB0ZXN0QXJncyA9IC8qKiBAdHlwZSB7VGVzdEFyZ3N9ICovIChPYmplY3QuYXNzaWduKHt9LCB0ZXN0RGF0YS5hcmdzKSlcbiAgICAgIGNvbnN0IGluY2x1ZGVCeUxpbmUgPSBsaW5lTWF0Y2hlZEluU2NvcGUgfHwgdGhpcy5tYXRjaGVzTGluZUZpbHRlcih0ZXN0RGF0YSlcblxuICAgICAgaWYgKHRoaXMuX29ubHlGb2N1c3NlZCAmJiAhdGVzdEFyZ3MuZm9jdXMpIGNvbnRpbnVlXG4gICAgICBpZiAodGhpcy5zaG91bGRTa2lwVGVzdCh0ZXN0QXJncywgdGVzdERhdGEsIHRlc3REZXNjcmlwdGlvbiwgZGVzY3JpcHRpb25zLCBpbmNsdWRlQnlMaW5lKSkgY29udGludWVcblxuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHN1YkRlc2NyaXB0aW9uIGluIHRlc3RzLnN1YnMpIHtcbiAgICAgIGNvbnN0IHN1YlRlc3QgPSB0ZXN0cy5zdWJzW3N1YkRlc2NyaXB0aW9uXVxuICAgICAgY29uc3Qgc2NvcGVMaW5lTWF0Y2ggPSBsaW5lTWF0Y2hlZEluU2NvcGUgfHwgdGhpcy5tYXRjaGVzTGluZUZpbHRlcihzdWJUZXN0KVxuICAgICAgY29uc3QgbmV4dERlc2NyaXB0aW9ucyA9IGRlc2NyaXB0aW9ucy5jb25jYXQoW3N1YkRlc2NyaXB0aW9uXSlcblxuICAgICAgaWYgKHRoaXMuX29ubHlGb2N1c3NlZCAmJiAhc3ViVGVzdC5hbnlUZXN0c0ZvY3Vzc2VkKSBjb250aW51ZVxuICAgICAgaWYgKHRoaXMuaGFzUnVubmFibGVUZXN0cyhzdWJUZXN0LCBuZXh0RGVzY3JpcHRpb25zLCBzY29wZUxpbmVNYXRjaCkpIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtUZXN0QXJnc30gdGVzdEFyZ3MgLSBUZXN0IGFyZ3MuXG4gICAqIEBwYXJhbSB7VGVzdERhdGF9IHRlc3REYXRhIC0gVGVzdCBkYXRhLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGVzdERlc2NyaXB0aW9uIC0gVGVzdCBkZXNjcmlwdGlvbi5cbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gZGVzY3JpcHRpb25zIC0gRGVzY3JpcHRpb24gc3RhY2suXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gbGluZU1hdGNoZWRJblNjb3BlIC0gV2hldGhlciBsaW5lIG1hdGNoZWQgaW4gc2NvcGUuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgdGhlIHRlc3Qgc2hvdWxkIGJlIHNraXBwZWQuXG4gICAqL1xuICBzaG91bGRTa2lwVGVzdCh0ZXN0QXJncywgdGVzdERhdGEsIHRlc3REZXNjcmlwdGlvbiwgZGVzY3JpcHRpb25zLCBsaW5lTWF0Y2hlZEluU2NvcGUpIHtcbiAgICBpZiAodGhpcy5oYXNNYXRjaGluZ1RhZyh0ZXN0QXJncy50YWdzLCB0aGlzLmdldEV4Y2x1ZGVUYWdTZXQoKSkpIHJldHVybiB0cnVlXG5cbiAgICBpZiAodGhpcy5faW5jbHVkZVRhZ1NldC5zaXplID4gMCAmJiAhdGVzdEFyZ3MuZm9jdXMpIHtcbiAgICAgIGlmICghdGhpcy5oYXNNYXRjaGluZ1RhZyh0ZXN0QXJncy50YWdzLCB0aGlzLl9pbmNsdWRlVGFnU2V0KSkgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICBpZiAodGhpcy5nZXRFeGFtcGxlUGF0dGVybnMoKS5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBmdWxsRGVzY3JpcHRpb24gPSB0aGlzLmJ1aWxkRnVsbERlc2NyaXB0aW9uKGRlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uKVxuICAgICAgY29uc3QgbWF0Y2hlcyA9IHRoaXMuZ2V0RXhhbXBsZVBhdHRlcm5zKCkuc29tZSgocGF0dGVybikgPT4ge1xuICAgICAgICBwYXR0ZXJuLmxhc3RJbmRleCA9IDBcbiAgICAgICAgcmV0dXJuIHBhdHRlcm4udGVzdChmdWxsRGVzY3JpcHRpb24pXG4gICAgICB9KVxuXG4gICAgICBpZiAoIW1hdGNoZXMpIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgY29uc3QgbGluZUZpbHRlcnMgPSB0aGlzLmdldExpbmVGaWx0ZXJzKClcblxuICAgIGlmIChPYmplY3Qua2V5cyhsaW5lRmlsdGVycykubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKCFsaW5lTWF0Y2hlZEluU2NvcGUgJiYgIXRoaXMubWF0Y2hlc0xpbmVGaWx0ZXIodGVzdERhdGEpKSByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7VGVzdERhdGEgfCBUZXN0c0FyZ3VtZW50fSBlbnRyeSAtIFRlc3QgZW50cnkuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgbGluZSBmaWx0ZXIgbWF0Y2hlcyBlbnRyeS5cbiAgICovXG4gIG1hdGNoZXNMaW5lRmlsdGVyKGVudHJ5KSB7XG4gICAgaWYgKCFlbnRyeSB8fCAhZW50cnkuZmlsZVBhdGggfHwgIWVudHJ5LmxpbmUpIHJldHVybiBmYWxzZVxuXG4gICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLnJlc29sdmUoZW50cnkuZmlsZVBhdGgpXG4gICAgY29uc3QgbGluZXMgPSB0aGlzLmdldExpbmVGaWx0ZXJzKClbZmlsZVBhdGhdXG5cbiAgICBpZiAoIWxpbmVzIHx8IGxpbmVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhbHNlXG5cbiAgICByZXR1cm4gbGluZXMuaW5jbHVkZXMoZW50cnkubGluZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBkZXNjcmlwdGlvbnMgLSBEZXNjcmlwdGlvbiBzdGFjay5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRlc3REZXNjcmlwdGlvbiAtIFRlc3QgZGVzY3JpcHRpb24uXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gRnVsbCBkZXNjcmlwdGlvbi5cbiAgICovXG4gIGJ1aWxkRnVsbERlc2NyaXB0aW9uKGRlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uKSB7XG4gICAgY29uc3QgcGFydHMgPSBkZXNjcmlwdGlvbnMuY29uY2F0KFt0ZXN0RGVzY3JpcHRpb25dKVxuXG4gICAgcmV0dXJuIHBhcnRzLmpvaW4oXCIgXCIpLnRyaW0oKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPEFwcGxpY2F0aW9uPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBhcHBsaWNhdGlvbi5cbiAgICovXG4gIGFzeW5jIGFwcGxpY2F0aW9uKCkge1xuICAgIGlmICghdGhpcy5fYXBwbGljYXRpb24pIHtcbiAgICAgIHRoaXMuX2FwcGxpY2F0aW9uID0gbmV3IEFwcGxpY2F0aW9uKHtcbiAgICAgICAgY29uZmlndXJhdGlvbjogdGhpcy5nZXRDb25maWd1cmF0aW9uKCksXG4gICAgICAgIGh0dHBTZXJ2ZXI6IHtwb3J0OiAzMTAwNn0sXG4gICAgICAgIHR5cGU6IFwidGVzdC1ydW5uZXJcIlxuICAgICAgfSlcblxuICAgICAgYXdhaXQgdGhpcy5fYXBwbGljYXRpb24uaW5pdGlhbGl6ZSgpXG4gICAgICBhd2FpdCB0aGlzLl9hcHBsaWNhdGlvbi5zdGFydEh0dHBTZXJ2ZXIoKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9hcHBsaWNhdGlvblxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFJlcXVlc3RDbGllbnQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIHJlcXVlc3QgY2xpZW50LlxuICAgKi9cbiAgYXN5bmMgcmVxdWVzdENsaWVudCgpIHtcbiAgICBpZiAoIXRoaXMuX3JlcXVlc3RDbGllbnQpIHtcbiAgICAgIHRoaXMuX3JlcXVlc3RDbGllbnQgPSBuZXcgUmVxdWVzdENsaWVudCgpXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3JlcXVlc3RDbGllbnRcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgaW1wb3J0VGVzdEZpbGVzKCkge1xuICAgIGF3YWl0IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLmdldEVudmlyb25tZW50SGFuZGxlcigpLmltcG9ydFRlc3RGaWxlcyh0aGlzLmdldFRlc3RGaWxlcygpKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgZmFpbGVkLlxuICAgKi9cbiAgaXNGYWlsZWQoKSB7IHJldHVybiB0aGlzLl9mYWlsZWRUZXN0cyAhPT0gdW5kZWZpbmVkICYmIHRoaXMuX2ZhaWxlZFRlc3RzID4gMCB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gVGhlIGZhaWxlZCB0ZXN0cy5cbiAgICovXG4gIGdldEZhaWxlZFRlc3RzKCkge1xuICAgIGlmICh0aGlzLl9mYWlsZWRUZXN0cyA9PT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgRXJyb3IoXCJUZXN0cyBoYXNuJ3QgYmVlbiBydW4geWV0XCIpXG5cbiAgICByZXR1cm4gdGhpcy5fZmFpbGVkVGVzdHNcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7QXJyYXk8e2Z1bGxEZXNjcmlwdGlvbjogc3RyaW5nLCBmaWxlUGF0aD86IHN0cmluZywgbGluZT86IG51bWJlciwgZXJyb3I6IHVua25vd259Pn0gLSBGYWlsZWQgdGVzdCBkZXRhaWxzLiAqL1xuICBnZXRGYWlsZWRUZXN0RGV0YWlscygpIHtcbiAgICByZXR1cm4gdGhpcy5fZmFpbGVkVGVzdERldGFpbHNcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIFRoZSBzdWNjZXNzZnVsIHRlc3RzLlxuICAgKi9cbiAgZ2V0U3VjY2Vzc2Z1bFRlc3RzKCkge1xuICAgIGlmICh0aGlzLl9zdWNjZXNzZnVsVGVzdHMgPT09IHVuZGVmaW5lZCkgdGhyb3cgbmV3IEVycm9yKFwiVGVzdHMgaGFzbid0IGJlZW4gcnVuIHlldFwiKVxuXG4gICAgcmV0dXJuIHRoaXMuX3N1Y2Nlc3NmdWxUZXN0c1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gVGhlIHRlc3RzIGNvdW50LlxuICAgKi9cbiAgZ2V0VGVzdHNDb3VudCgpIHtcbiAgICBpZiAodGhpcy5fdGVzdHNDb3VudCA9PT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgRXJyb3IoXCJUZXN0cyBoYXNuJ3QgYmVlbiBydW4geWV0XCIpXG5cbiAgICByZXR1cm4gdGhpcy5fdGVzdHNDb3VudFxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gVGhlIGV4ZWN1dGVkIHRlc3RzIGNvdW50LlxuICAgKi9cbiAgZ2V0RXhlY3V0ZWRUZXN0c0NvdW50KCkge1xuICAgIGlmICh0aGlzLl9zdWNjZXNzZnVsVGVzdHMgPT09IHVuZGVmaW5lZCB8fCB0aGlzLl9mYWlsZWRUZXN0cyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUZXN0cyBoYXNuJ3QgYmVlbiBydW4geWV0XCIpXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3N1Y2Nlc3NmdWxUZXN0cyArIHRoaXMuX2ZhaWxlZFRlc3RzXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHByZXBhcmUoKSB7XG4gICAgdGhpcy5hbnlUZXN0c0ZvY3Vzc2VkID0gZmFsc2VcbiAgICB0aGlzLl9mYWlsZWRUZXN0cyA9IDBcbiAgICB0aGlzLl9zdWNjZXNzZnVsVGVzdHMgPSAwXG4gICAgdGhpcy5fdGVzdHNDb3VudCA9IDBcbiAgICB0aGlzLl9mYWlsZWRUZXN0RGV0YWlscyA9IFtdXG4gICAgYXdhaXQgdGhpcy5pbXBvcnRUZXN0RmlsZXMoKVxuICAgIGF3YWl0IHRoaXMuYW5hbHl6ZVRlc3RzKHRlc3RzKVxuICAgIHRoaXMuX29ubHlGb2N1c3NlZCA9IHRoaXMuYW55VGVzdHNGb2N1c3NlZFxuXG4gICAgY29uc3QgdGVzdGluZ0NvbmZpZ1BhdGggPSB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5nZXRUZXN0aW5nKClcblxuICAgIGlmICh0ZXN0aW5nQ29uZmlnUGF0aCkge1xuICAgICAgYXdhaXQgdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuZ2V0RW52aXJvbm1lbnRIYW5kbGVyKCkuaW1wb3J0VGVzdGluZ0NvbmZpZ1BhdGgoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGFueSB0ZXN0cyBmb2N1c3NlZC5cbiAgICovXG4gIGFyZUFueVRlc3RzRm9jdXNzZWQoKSB7XG4gICAgaWYgKHRoaXMuYW55VGVzdHNGb2N1c3NlZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJIYXNuJ3QgYmVlbiBkZXRlY3RlZCB5ZXRcIilcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5hbnlUZXN0c0ZvY3Vzc2VkXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHJ1bigpIHtcbiAgICBhd2FpdCB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5lbnN1cmVDb25uZWN0aW9ucyhhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCB0aGlzLnJ1blRlc3RzKHtcbiAgICAgICAgYWZ0ZXJFYWNoZXM6IFtdLFxuICAgICAgICBiZWZvcmVFYWNoZXM6IFtdLFxuICAgICAgICB0ZXN0cyxcbiAgICAgICAgZGVzY3JpcHRpb25zOiBbXSxcbiAgICAgICAgaW5kZW50TGV2ZWw6IDBcbiAgICAgIH0pXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNsZWFudXAgaG9va3MgZmluaXNoLlxuICAgKi9cbiAgYXN5bmMgcnVuQWZ0ZXJBbGxzRm9yQWN0aXZlU2NvcGVzKCkge1xuICAgIGNvbnN0IHNjb3BlcyA9IFsuLi50aGlzLl9hY3RpdmVBZnRlckFsbFNjb3Blc10ucmV2ZXJzZSgpXG5cbiAgICBmb3IgKGNvbnN0IHNjb3BlIG9mIHNjb3Blcykge1xuICAgICAgYXdhaXQgdGhpcy5ydW5BZnRlckFsbHNGb3JTY29wZShzY29wZSlcbiAgICB9XG5cbiAgICB0aGlzLl9hY3RpdmVBZnRlckFsbFNjb3BlcyA9IFtdXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtUZXN0c0FyZ3VtZW50fSB0ZXN0cyAtIFRlc3RzLlxuICAgKiBAcmV0dXJucyB7e2FueVRlc3RzRm9jdXNzZWQ6IGJvb2xlYW59fSAtIFdoZXRoZXIgYW55IHRlc3RzIGluIHRoZSB0cmVlIGFyZSBmb2N1c2VkLlxuICAgKi9cbiAgYW5hbHl6ZVRlc3RzKHRlc3RzKSB7XG4gICAgbGV0IGFueVRlc3RzRm9jdXNzZWRGb3VuZCA9IGZhbHNlXG5cbiAgICBmb3IgKGNvbnN0IHRlc3REZXNjcmlwdGlvbiBpbiB0ZXN0cy50ZXN0cykge1xuICAgICAgY29uc3QgdGVzdERhdGEgPSB0ZXN0cy50ZXN0c1t0ZXN0RGVzY3JpcHRpb25dXG4gICAgICBjb25zdCB0ZXN0QXJncyA9IE9iamVjdC5hc3NpZ24oe30sIHRlc3REYXRhLmFyZ3MpXG5cbiAgICAgIHRoaXMuX3Rlc3RzQ291bnQrK1xuXG4gICAgICBpZiAodGVzdEFyZ3MuZm9jdXMpIHtcbiAgICAgICAgYW55VGVzdHNGb2N1c3NlZEZvdW5kID0gdHJ1ZVxuICAgICAgICB0aGlzLmFueVRlc3RzRm9jdXNzZWQgPSB0cnVlXG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBzdWJEZXNjcmlwdGlvbiBpbiB0ZXN0cy5zdWJzKSB7XG4gICAgICBjb25zdCBzdWJUZXN0ID0gdGVzdHMuc3Vic1tzdWJEZXNjcmlwdGlvbl1cbiAgICAgIGNvbnN0IHthbnlUZXN0c0ZvY3Vzc2VkfSA9IHRoaXMuYW5hbHl6ZVRlc3RzKHN1YlRlc3QpXG5cbiAgICAgIGlmIChhbnlUZXN0c0ZvY3Vzc2VkKSB7XG4gICAgICAgIGFueVRlc3RzRm9jdXNzZWRGb3VuZCA9IHRydWVcbiAgICAgIH1cblxuICAgICAgc3ViVGVzdC5hbnlUZXN0c0ZvY3Vzc2VkID0gYW55VGVzdHNGb2N1c3NlZFxuICAgIH1cblxuICAgIHJldHVybiB7YW55VGVzdHNGb2N1c3NlZDogYW55VGVzdHNGb2N1c3NlZEZvdW5kfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7QXJyYXk8QWZ0ZXJCZWZvcmVFYWNoQ2FsbGJhY2tPYmplY3RUeXBlPn0gYXJncy5hZnRlckVhY2hlcyAtIEFmdGVyIGVhY2hlcy5cbiAgICogQHBhcmFtIHtBcnJheTxBZnRlckJlZm9yZUVhY2hDYWxsYmFja09iamVjdFR5cGU+fSBhcmdzLmJlZm9yZUVhY2hlcyAtIEJlZm9yZSBlYWNoZXMuXG4gICAqIEBwYXJhbSB7VGVzdHNBcmd1bWVudH0gYXJncy50ZXN0cyAtIFRlc3RzLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBhcmdzLmRlc2NyaXB0aW9ucyAtIERlc2NyaXB0aW9ucy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGFyZ3MuaW5kZW50TGV2ZWwgLSBJbmRlbnQgbGV2ZWwuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2FyZ3MubGluZU1hdGNoZWRJblNjb3BlXSAtIFdoZXRoZXIgbGluZSBtYXRjaGVkIGluIHNjb3BlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgcnVuVGVzdHMoe2FmdGVyRWFjaGVzLCBiZWZvcmVFYWNoZXMsIHRlc3RzLCBkZXNjcmlwdGlvbnMsIGluZGVudExldmVsLCBsaW5lTWF0Y2hlZEluU2NvcGUgPSBmYWxzZX0pIHtcbiAgICBjb25zdCBsZWZ0UGFkZGluZyA9IFwiIFwiLnJlcGVhdChpbmRlbnRMZXZlbCAqIDIpXG4gICAgY29uc3QgbmV3QWZ0ZXJFYWNoZXMgPSBbLi4uYWZ0ZXJFYWNoZXMsIC4uLnRlc3RzLmFmdGVyRWFjaGVzXVxuICAgIGNvbnN0IG5ld0JlZm9yZUVhY2hlcyA9IFsuLi5iZWZvcmVFYWNoZXMsIC4uLnRlc3RzLmJlZm9yZUVhY2hlc11cbiAgICBjb25zdCBzY29wZUxpbmVNYXRjaCA9IGxpbmVNYXRjaGVkSW5TY29wZSB8fCB0aGlzLm1hdGNoZXNMaW5lRmlsdGVyKHRlc3RzKVxuICAgIGNvbnN0IHNob3VsZFJ1bkFueVRlc3RzID0gdGhpcy5oYXNSdW5uYWJsZVRlc3RzKHRlc3RzLCBkZXNjcmlwdGlvbnMsIHNjb3BlTGluZU1hdGNoKVxuXG4gICAgaWYgKCFzaG91bGRSdW5BbnlUZXN0cykgcmV0dXJuXG5cbiAgICAvKiogQHR5cGUge3t0ZXN0czogVGVzdHNBcmd1bWVudCwgYWZ0ZXJBbGxzUnVuOiBib29sZWFufX0gKi9cbiAgICBjb25zdCBzY29wZUVudHJ5ID0ge3Rlc3RzLCBhZnRlckFsbHNSdW46IGZhbHNlfVxuICAgIHRoaXMuX2FjdGl2ZUFmdGVyQWxsU2NvcGVzLnB1c2goc2NvcGVFbnRyeSlcblxuICAgIHRyeSB7XG4gICAgICBmb3IgKGNvbnN0IGJlZm9yZUFsbERhdGEgb2YgdGVzdHMuYmVmb3JlQWxscyB8fCBbXSkge1xuICAgICAgICBhd2FpdCBiZWZvcmVBbGxEYXRhLmNhbGxiYWNrKHtjb25maWd1cmF0aW9uOiB0aGlzLmdldENvbmZpZ3VyYXRpb24oKX0pXG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgdGVzdERlc2NyaXB0aW9uIGluIHRlc3RzLnRlc3RzKSB7XG4gICAgICAgIGNvbnN0IHRlc3REYXRhID0gdGVzdHMudGVzdHNbdGVzdERlc2NyaXB0aW9uXVxuICAgICAgICBjb25zdCB0ZXN0QXJncyA9IC8qKiBAdHlwZSB7VGVzdEFyZ3N9ICovIChPYmplY3QuYXNzaWduKHt9LCB0ZXN0RGF0YS5hcmdzKSlcbiAgICAgICAgY29uc3QgaW5jbHVkZUJ5TGluZSA9IHNjb3BlTGluZU1hdGNoIHx8IHRoaXMubWF0Y2hlc0xpbmVGaWx0ZXIodGVzdERhdGEpXG5cbiAgICAgICAgaWYgKHRoaXMuX29ubHlGb2N1c3NlZCAmJiAhdGVzdEFyZ3MuZm9jdXMpIGNvbnRpbnVlXG4gICAgICAgIGlmICh0aGlzLnNob3VsZFNraXBUZXN0KHRlc3RBcmdzLCB0ZXN0RGF0YSwgdGVzdERlc2NyaXB0aW9uLCBkZXNjcmlwdGlvbnMsIGluY2x1ZGVCeUxpbmUpKSBjb250aW51ZVxuXG4gICAgICAgIGlmICh0ZXN0QXJncy50eXBlID09IFwibW9kZWxcIiB8fCB0ZXN0QXJncy50eXBlID09IFwicmVxdWVzdFwiKSB7XG4gICAgICAgICAgdGVzdEFyZ3MuYXBwbGljYXRpb24gPSBhd2FpdCB0aGlzLmFwcGxpY2F0aW9uKClcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0ZXN0QXJncy50eXBlID09IFwicmVxdWVzdFwiKSB7XG4gICAgICAgICAgdGVzdEFyZ3MuY2xpZW50ID0gYXdhaXQgdGhpcy5yZXF1ZXN0Q2xpZW50KClcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUubG9nKGAke2xlZnRQYWRkaW5nfWl0ICR7dGVzdERlc2NyaXB0aW9ufWApXG5cbiAgICAgICAgY29uc3QgcmV0cnlDb3VudCA9IHR5cGVvZiB0ZXN0QXJncy5yZXRyeSA9PT0gXCJudW1iZXJcIiAmJiBOdW1iZXIuaXNGaW5pdGUodGVzdEFyZ3MucmV0cnkpXG4gICAgICAgICAgPyBNYXRoLm1heCgwLCBNYXRoLmZsb29yKHRlc3RBcmdzLnJldHJ5KSlcbiAgICAgICAgICA6IDBcbiAgICAgICAgY29uc3QgY29uZmlnVGltZW91dFNlY29uZHMgPSB0eXBlb2YgdGVzdENvbmZpZy5kZWZhdWx0VGltZW91dFNlY29uZHMgPT09IFwibnVtYmVyXCIgPyB0ZXN0Q29uZmlnLmRlZmF1bHRUaW1lb3V0U2Vjb25kcyA6IHVuZGVmaW5lZFxuICAgICAgICBjb25zdCB0aW1lb3V0U2Vjb25kcyA9IHR5cGVvZiB0ZXN0QXJncy50aW1lb3V0U2Vjb25kcyA9PT0gXCJudW1iZXJcIiA/IHRlc3RBcmdzLnRpbWVvdXRTZWNvbmRzIDogY29uZmlnVGltZW91dFNlY29uZHNcbiAgICAgICAgY29uc3QgdXNlVGltZW91dCA9IHR5cGVvZiB0aW1lb3V0U2Vjb25kcyA9PT0gXCJudW1iZXJcIiAmJiBOdW1iZXIuaXNGaW5pdGUodGltZW91dFNlY29uZHMpICYmIHRpbWVvdXRTZWNvbmRzID4gMFxuICAgICAgICBjb25zdCB0aW1lb3V0TXMgPSB1c2VUaW1lb3V0ID8gdGltZW91dFNlY29uZHMgKiAxMDAwIDogdW5kZWZpbmVkXG4gICAgICAgIGxldCByZXRyaWVzVXNlZCA9IDBcbiAgICAgICAgbGV0IGF0dGVtcHROdW1iZXIgPSAxXG5cbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICBsZXQgc2hvdWxkUmV0cnkgPSBmYWxzZVxuICAgICAgICAgIC8qKiBAdHlwZSB7dW5rbm93bn0gKi9cbiAgICAgICAgICBsZXQgZmFpbGVkRXJyb3JcbiAgICAgICAgICAvKiogQHR5cGUge3Vua25vd259ICovXG4gICAgICAgICAgbGV0IGxhc3RFcnJvclxuXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucnVuV2l0aER1bW15SWZOZWVkZWQodGVzdEFyZ3MsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjbGVhckRlbGl2ZXJpZXMoKVxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYmVmb3JlRWFjaERhdGEgb2YgbmV3QmVmb3JlRWFjaGVzKSB7XG4gICAgICAgICAgICAgICAgICBhd2FpdCBiZWZvcmVFYWNoRGF0YS5jYWxsYmFjayh7Y29uZmlndXJhdGlvbjogdGhpcy5nZXRDb25maWd1cmF0aW9uKCksIHRlc3RBcmdzLCB0ZXN0RGF0YX0pXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgdGVzdFByb21pc2UgPSB0ZXN0RGF0YS5mdW5jdGlvbih0ZXN0QXJncylcblxuICAgICAgICAgICAgICAgIGlmICh1c2VUaW1lb3V0ICYmIHRpbWVvdXRNcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICBhd2FpdCBydW5XaXRoVGltZW91dCh0ZXN0UHJvbWlzZSwgdGltZW91dE1zLCB0ZXN0RGVzY3JpcHRpb24pXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGF3YWl0IHRlc3RQcm9taXNlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX3N1Y2Nlc3NmdWxUZXN0cysrXG4gICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBhZnRlckVhY2hEYXRhIG9mIG5ld0FmdGVyRWFjaGVzKSB7XG4gICAgICAgICAgICAgICAgICBhd2FpdCBhZnRlckVhY2hEYXRhLmNhbGxiYWNrKHtjb25maWd1cmF0aW9uOiB0aGlzLmdldENvbmZpZ3VyYXRpb24oKSwgdGVzdEFyZ3MsIHRlc3REYXRhfSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxhc3RFcnJvciA9IGVycm9yXG4gICAgICAgICAgICBpZiAocmV0cmllc1VzZWQgPCByZXRyeUNvdW50KSB7XG4gICAgICAgICAgICAgIHJldHJpZXNVc2VkKytcbiAgICAgICAgICAgICAgc2hvdWxkUmV0cnkgPSB0cnVlXG4gICAgICAgICAgICAgIGNvbnNvbGUud2FybihwaWNvY29sb3JzLnJlZChgJHtsZWZ0UGFkZGluZ30gIFJldHJ5aW5nICgke3JldHJpZXNVc2VkfS8ke3JldHJ5Q291bnR9KSBhZnRlciBlcnJvcjogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcil9YCkpXG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdEV2ZW50KFwidGVzdFJldHJ5aW5nXCIsIHtcbiAgICAgICAgICAgICAgICBjb25maWd1cmF0aW9uOiB0aGlzLmdldENvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbnMsXG4gICAgICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgICAgICAgbmV4dEF0dGVtcHQ6IGF0dGVtcHROdW1iZXIgKyAxLFxuICAgICAgICAgICAgICAgIHJldHJpZXNVc2VkLFxuICAgICAgICAgICAgICAgIHJldHJ5Q291bnQsXG4gICAgICAgICAgICAgICAgdGVzdEFyZ3MsXG4gICAgICAgICAgICAgICAgdGVzdERhdGEsXG4gICAgICAgICAgICAgICAgdGVzdERlc2NyaXB0aW9uLFxuICAgICAgICAgICAgICAgIHRlc3RSdW5uZXI6IHRoaXNcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGZhaWxlZEVycm9yID0gZXJyb3JcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoYXR0ZW1wdE51bWJlciA+IDEpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdEV2ZW50KFwidGVzdFJldHJpZWRcIiwge1xuICAgICAgICAgICAgICBjb25maWd1cmF0aW9uOiB0aGlzLmdldENvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICAgICAgICBlcnJvcjogbGFzdEVycm9yLFxuICAgICAgICAgICAgICBhdHRlbXB0TnVtYmVyLFxuICAgICAgICAgICAgICByZXRyaWVzVXNlZCxcbiAgICAgICAgICAgICAgcmV0cnlDb3VudCxcbiAgICAgICAgICAgICAgdGVzdEFyZ3MsXG4gICAgICAgICAgICAgIHRlc3REYXRhLFxuICAgICAgICAgICAgICB0ZXN0RGVzY3JpcHRpb24sXG4gICAgICAgICAgICAgIHRlc3RSdW5uZXI6IHRoaXNcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYXR0ZW1wdE51bWJlcisrXG5cbiAgICAgICAgICBpZiAoc2hvdWxkUmV0cnkpIGNvbnRpbnVlXG5cbiAgICAgICAgICBpZiAoZmFpbGVkRXJyb3IpIHtcbiAgICAgICAgICAgIHRoaXMuX2ZhaWxlZFRlc3RzKytcbiAgICAgICAgICAgIHRoaXMuX2ZhaWxlZFRlc3REZXRhaWxzLnB1c2goe1xuICAgICAgICAgICAgICBmdWxsRGVzY3JpcHRpb246IHRoaXMuYnVpbGRGdWxsRGVzY3JpcHRpb24oZGVzY3JpcHRpb25zLCB0ZXN0RGVzY3JpcHRpb24pLFxuICAgICAgICAgICAgICBmaWxlUGF0aDogdGVzdERhdGEuZmlsZVBhdGgsXG4gICAgICAgICAgICAgIGxpbmU6IHRlc3REYXRhLmxpbmUsXG4gICAgICAgICAgICAgIGVycm9yOiBmYWlsZWRFcnJvclxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgaWYgKGZhaWxlZEVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihwaWNvY29sb3JzLnJlZChgJHtsZWZ0UGFkZGluZ30gIFRlc3QgZmFpbGVkOiAke2ZhaWxlZEVycm9yLm1lc3NhZ2V9YCkpXG4gICAgICAgICAgICAgIGFkZFRyYWNrZWRTdGFja1RvRXJyb3IoZmFpbGVkRXJyb3IpXG5cbiAgICAgICAgICAgICAgY29uc3QgYmFja3RyYWNlQ2xlYW5lciA9IG5ldyBCYWNrdHJhY2VDbGVhbmVyKGZhaWxlZEVycm9yKVxuICAgICAgICAgICAgICBjb25zdCBjbGVhbmVkU3RhY2sgPSBiYWNrdHJhY2VDbGVhbmVyLmdldENsZWFuZWRTdGFjaygpXG4gICAgICAgICAgICAgIGNvbnN0IHN0YWNrTGluZXMgPSBjbGVhbmVkU3RhY2s/LnNwbGl0KFwiXFxuXCIpXG5cbiAgICAgICAgICAgICAgaWYgKHN0YWNrTGluZXMpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHN0YWNrTGluZSBvZiBzdGFja0xpbmVzKSB7XG4gICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKHBpY29jb2xvcnMucmVkKGAke2xlZnRQYWRkaW5nfSAgJHtzdGFja0xpbmV9YCkpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKHBpY29jb2xvcnMucmVkKGAke2xlZnRQYWRkaW5nfSAgVGVzdCBmYWlsZWQgd2l0aCBhICR7dHlwZW9mIGZhaWxlZEVycm9yfTogJHtTdHJpbmcoZmFpbGVkRXJyb3IpfWApKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmVtaXRFdmVudChcInRlc3RGYWlsZWRcIiwge1xuICAgICAgICAgICAgICBjb25maWd1cmF0aW9uOiB0aGlzLmdldENvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICAgICAgICBlcnJvcjogZmFpbGVkRXJyb3IsXG4gICAgICAgICAgICAgIHRlc3RBcmdzLFxuICAgICAgICAgICAgICB0ZXN0RGF0YSxcbiAgICAgICAgICAgICAgdGVzdERlc2NyaXB0aW9uLFxuICAgICAgICAgICAgICB0ZXN0UnVubmVyOiB0aGlzXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICB0aGlzLnByaW50UmVydW5Db21tYW5kKHtkZXNjcmlwdGlvbnMsIHRlc3REZXNjcmlwdGlvbiwgdGVzdERhdGEsIGxlZnRQYWRkaW5nfSlcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3Qgc3ViRGVzY3JpcHRpb24gaW4gdGVzdHMuc3Vicykge1xuICAgICAgICBjb25zdCBzdWJUZXN0ID0gdGVzdHMuc3Vic1tzdWJEZXNjcmlwdGlvbl1cbiAgICAgICAgY29uc3QgbmV3RGVjcmlwdGlvbnMgPSBkZXNjcmlwdGlvbnMuY29uY2F0KFtzdWJEZXNjcmlwdGlvbl0pXG4gICAgICAgIGNvbnN0IGNoaWxkU2NvcGVMaW5lTWF0Y2ggPSBzY29wZUxpbmVNYXRjaCB8fCB0aGlzLm1hdGNoZXNMaW5lRmlsdGVyKHN1YlRlc3QpXG5cbiAgICAgICAgaWYgKCF0aGlzLl9vbmx5Rm9jdXNzZWQgfHwgc3ViVGVzdC5hbnlUZXN0c0ZvY3Vzc2VkKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYCR7bGVmdFBhZGRpbmd9JHtzdWJEZXNjcmlwdGlvbn1gKVxuICAgICAgICAgIGF3YWl0IHRoaXMucnVuVGVzdHMoe1xuICAgICAgICAgICAgYWZ0ZXJFYWNoZXM6IG5ld0FmdGVyRWFjaGVzLFxuICAgICAgICAgICAgYmVmb3JlRWFjaGVzOiBuZXdCZWZvcmVFYWNoZXMsXG4gICAgICAgICAgICB0ZXN0czogc3ViVGVzdCxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uczogbmV3RGVjcmlwdGlvbnMsXG4gICAgICAgICAgICBpbmRlbnRMZXZlbDogaW5kZW50TGV2ZWwgKyAxLFxuICAgICAgICAgICAgbGluZU1hdGNoZWRJblNjb3BlOiBjaGlsZFNjb3BlTGluZU1hdGNoXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCB0aGlzLnJ1bkFmdGVyQWxsc0ZvclNjb3BlKHNjb3BlRW50cnkpXG4gICAgICBjb25zdCBzY29wZUluZGV4ID0gdGhpcy5fYWN0aXZlQWZ0ZXJBbGxTY29wZXMuaW5kZXhPZihzY29wZUVudHJ5KVxuXG4gICAgICBpZiAoc2NvcGVJbmRleCA+PSAwKSB7XG4gICAgICAgIHRoaXMuX2FjdGl2ZUFmdGVyQWxsU2NvcGVzLnNwbGljZShzY29wZUluZGV4LCAxKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3t0ZXN0czogVGVzdHNBcmd1bWVudCwgYWZ0ZXJBbGxzUnVuOiBib29sZWFufX0gc2NvcGVFbnRyeSAtIFNjb3BlIGVudHJ5LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIHNjb3BlIGNsZWFudXAgZmluaXNoZXMuXG4gICAqL1xuICBhc3luYyBydW5BZnRlckFsbHNGb3JTY29wZShzY29wZUVudHJ5KSB7XG4gICAgaWYgKHNjb3BlRW50cnkuYWZ0ZXJBbGxzUnVuKSByZXR1cm5cblxuICAgIHNjb3BlRW50cnkuYWZ0ZXJBbGxzUnVuID0gdHJ1ZVxuXG4gICAgZm9yIChjb25zdCBhZnRlckFsbERhdGEgb2Ygc2NvcGVFbnRyeS50ZXN0cy5hZnRlckFsbHMgfHwgW10pIHtcbiAgICAgIGF3YWl0IGFmdGVyQWxsRGF0YS5jYWxsYmFjayh7Y29uZmlndXJhdGlvbjogdGhpcy5nZXRDb25maWd1cmF0aW9uKCl9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lIC0gRXZlbnQgbmFtZS5cbiAgICogQHBhcmFtIHtvYmplY3R9IHBheWxvYWQgLSBFdmVudCBwYXlsb2FkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGFsbCBsaXN0ZW5lcnMgY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBlbWl0RXZlbnQoZXZlbnROYW1lLCBwYXlsb2FkKSB7XG4gICAgY29uc3QgbGlzdGVuZXJzID0gdGVzdEV2ZW50cy5saXN0ZW5lcnMoZXZlbnROYW1lKVxuXG4gICAgZm9yIChjb25zdCBsaXN0ZW5lciBvZiBsaXN0ZW5lcnMpIHtcbiAgICAgIGF3YWl0IGxpc3RlbmVyKHBheWxvYWQpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGFyZ3MuZGVzY3JpcHRpb25zIC0gRGVzY3JpcHRpb24gc3RhY2suXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLnRlc3REZXNjcmlwdGlvbiAtIFRlc3QgZGVzY3JpcHRpb24uXG4gICAqIEBwYXJhbSB7VGVzdERhdGF9IGFyZ3MudGVzdERhdGEgLSBUZXN0IGRhdGEuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmxlZnRQYWRkaW5nIC0gTGVmdCBwYWRkaW5nLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBwcmludFJlcnVuQ29tbWFuZCh7ZGVzY3JpcHRpb25zLCB0ZXN0RGVzY3JpcHRpb24sIHRlc3REYXRhLCBsZWZ0UGFkZGluZ30pIHtcbiAgICBjb25zdCByZXJ1biA9IHRoaXMuYnVpbGRSZXJ1bkNvbW1hbmQoe2Rlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uLCB0ZXN0RGF0YX0pXG5cbiAgICBpZiAocmVydW4pIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoYCR7bGVmdFBhZGRpbmd9ICBSZS1ydW46ICR7cmVydW59YClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gYXJncy5kZXNjcmlwdGlvbnMgLSBEZXNjcmlwdGlvbiBzdGFjay5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MudGVzdERlc2NyaXB0aW9uIC0gVGVzdCBkZXNjcmlwdGlvbi5cbiAgICogQHBhcmFtIHtUZXN0RGF0YX0gYXJncy50ZXN0RGF0YSAtIFRlc3QgZGF0YS5cbiAgICogQHJldHVybnMge3N0cmluZyB8IHVuZGVmaW5lZH0gLSBSZXJ1biBjb21tYW5kLlxuICAgKi9cbiAgYnVpbGRSZXJ1bkNvbW1hbmQoe2Rlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uLCB0ZXN0RGF0YX0pIHtcbiAgICBjb25zdCBiYXNlQ29tbWFuZCA9IFwibnB4IHZlbG9jaW91cyB0ZXN0XCJcbiAgICBjb25zdCBmaWxlUGF0aCA9IHRlc3REYXRhLmZpbGVQYXRoXG4gICAgY29uc3QgbGluZSA9IHRlc3REYXRhLmxpbmVcblxuICAgIGlmIChmaWxlUGF0aCAmJiBsaW5lKSB7XG4gICAgICBjb25zdCByZWxhdGl2ZVBhdGggPSBwYXRoLnJlbGF0aXZlKHByb2Nlc3MuY3dkKCksIGZpbGVQYXRoKVxuICAgICAgcmV0dXJuIGAke2Jhc2VDb21tYW5kfSAke3JlbGF0aXZlUGF0aH06JHtsaW5lfWBcbiAgICB9XG5cbiAgICBjb25zdCBmdWxsRGVzY3JpcHRpb24gPSB0aGlzLmJ1aWxkRnVsbERlc2NyaXB0aW9uKGRlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uKVxuXG4gICAgaWYgKGZ1bGxEZXNjcmlwdGlvbikge1xuICAgICAgcmV0dXJuIGAke2Jhc2VDb21tYW5kfSAtLWV4YW1wbGUgJHtKU09OLnN0cmluZ2lmeShmdWxsRGVzY3JpcHRpb24pfWBcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbn1cbiJdfQ==
|
|
810
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1ydW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGVzdGluZy90ZXN0LXJ1bm5lci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxFQUFDLHNCQUFzQixFQUFDLE1BQU0sZ0NBQWdDLENBQUE7QUFDckUsT0FBTyxFQUFFLE1BQU0sa0JBQWtCLENBQUE7QUFDakMsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBQ3ZCLE9BQU8sRUFBQyxNQUFNLEVBQUMsTUFBTSxXQUFXLENBQUE7QUFDaEMsT0FBTyxXQUFXLE1BQU0sMEJBQTBCLENBQUE7QUFDbEQsT0FBTyxnQkFBZ0IsTUFBTSwrQkFBK0IsQ0FBQTtBQUM1RCxPQUFPLGFBQWEsTUFBTSxxQkFBcUIsQ0FBQTtBQUMvQyxPQUFPLFVBQVUsTUFBTSxZQUFZLENBQUE7QUFDbkMsT0FBTyxhQUFhLE1BQU0sNkJBQTZCLENBQUE7QUFDdkQsT0FBTyxFQUFDLFVBQVUsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFDLE1BQU0sV0FBVyxDQUFBO0FBQ3ZELE9BQU8sRUFBQyxhQUFhLEVBQUMsTUFBTSxLQUFLLENBQUE7QUFDakMsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLGNBQWMsQ0FBQTtBQUU1Qzs7Ozs7R0FLRztBQUNILFNBQVMsY0FBYyxDQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsZUFBZTtJQUN6RCxNQUFNLGNBQWMsR0FBRyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQTtJQUMxRSxNQUFNLFlBQVksR0FBRyxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsY0FBYyxNQUFNLGVBQWUsRUFBRSxDQUFDLENBQUE7SUFFeEYsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtRQUNyQyxN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bEQsYUFBYSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLEVBQUUsRUFBRTtnQkFDdEMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLE1BQU0sVUFBVSxLQUFLLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQTtnQkFDOUUsc0JBQXNCLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQTtZQUM3QyxDQUFDLENBQUE7UUFDSCxDQUFDO1FBRUQsT0FBTyxHQUFHLEVBQUU7WUFDVixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ2IsT0FBTyxHQUFHLElBQUksQ0FBQTtnQkFFZCxLQUFLLE1BQU0sVUFBVSxJQUFJLHdCQUF3QixFQUFFLENBQUM7b0JBQ2xELGFBQWEsQ0FBQyxVQUFVLENBQUMsR0FBRyxzQkFBc0IsQ0FBQyxVQUFVLENBQUMsQ0FBQTtnQkFDaEUsQ0FBQztnQkFFRCxVQUFVLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtZQUMvQixDQUFDO1lBRUQsT0FBTyxVQUFVLENBQUE7UUFDbkIsQ0FBQyxDQUFBO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB7YWRkVHJhY2tlZFN0YWNrVG9FcnJvcn0gZnJvbSBcIi4uL3V0aWxzL3dpdGgtdHJhY2tlZC1zdGFjay5qc1wiXG5pbXBvcnQgZnMgZnJvbSBcIm5vZGU6ZnMvcHJvbWlzZXNcIlxuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIlxuaW1wb3J0IHtmb3JtYXR9IGZyb20gXCJub2RlOnV0aWxcIlxuaW1wb3J0IEFwcGxpY2F0aW9uIGZyb20gXCIuLi8uLi9zcmMvYXBwbGljYXRpb24uanNcIlxuaW1wb3J0IEJhY2t0cmFjZUNsZWFuZXIgZnJvbSBcIi4uL3V0aWxzL2JhY2t0cmFjZS1jbGVhbmVyLmpzXCJcbmltcG9ydCBSZXF1ZXN0Q2xpZW50IGZyb20gXCIuL3JlcXVlc3QtY2xpZW50LmpzXCJcbmltcG9ydCBwaWNvY29sb3JzIGZyb20gXCJwaWNvY29sb3JzXCJcbmltcG9ydCByZXN0QXJnc0Vycm9yIGZyb20gXCIuLi91dGlscy9yZXN0LWFyZ3MtZXJyb3IuanNcIlxuaW1wb3J0IHt0ZXN0Q29uZmlnLCB0ZXN0RXZlbnRzLCB0ZXN0c30gZnJvbSBcIi4vdGVzdC5qc1wiXG5pbXBvcnQge3BhdGhUb0ZpbGVVUkx9IGZyb20gXCJ1cmxcIlxuaW1wb3J0IHtjbGVhckRlbGl2ZXJpZXN9IGZyb20gXCIuLi9tYWlsZXIuanNcIlxuXG4vKipcbiAqIEBwYXJhbSB7UHJvbWlzZTx1bmtub3duPiB8IHVua25vd259IHByb21pc2UgLSBQcm9taXNlIG9yIHZhbHVlLlxuICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXRNcyAtIFRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzLlxuICogQHBhcmFtIHtzdHJpbmd9IHRlc3REZXNjcmlwdGlvbiAtIFRlc3QgZGVzY3JpcHRpb24uXG4gKiBAcmV0dXJucyB7UHJvbWlzZTx1bmtub3duPn0gLSBSZXNvbHZlcyBvciByZWplY3RzIGJhc2VkIG9uIHRpbWVvdXQgb3IgcHJvbWlzZSByZXN1bHQuXG4gKi9cbmZ1bmN0aW9uIHJ1bldpdGhUaW1lb3V0KHByb21pc2UsIHRpbWVvdXRNcywgdGVzdERlc2NyaXB0aW9uKSB7XG4gIGNvbnN0IHRpbWVvdXRTZWNvbmRzID0gKHRpbWVvdXRNcyAvIDEwMDApLnRvRml4ZWQoMykucmVwbGFjZSgvXFwuPzArJC8sIFwiXCIpXG4gIGNvbnN0IHRpbWVvdXRFcnJvciA9IG5ldyBFcnJvcihgVGltZWQgb3V0IGFmdGVyICR7dGltZW91dFNlY29uZHN9czogJHt0ZXN0RGVzY3JpcHRpb259YClcblxuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHJlamVjdCh0aW1lb3V0RXJyb3IpLCB0aW1lb3V0TXMpXG5cbiAgICBQcm9taXNlLnJlc29sdmUocHJvbWlzZSkudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dClcbiAgICAgIHJlc29sdmUocmVzdWx0KVxuICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpXG4gICAgICByZWplY3QoZXJyb3IpXG4gICAgfSlcbiAgfSlcbn1cblxuLyoqIEB0eXBlZGVmIHtcImxvZ1wiIHwgXCJpbmZvXCIgfCBcIndhcm5cIiB8IFwiZXJyb3JcIiB8IFwiZGVidWdcIn0gQ29uc29sZU1ldGhvZE5hbWUgKi9cblxuLyoqIEB0eXBlIHtDb25zb2xlTWV0aG9kTmFtZVtdfSAqL1xuY29uc3QgQ0FQVFVSRURfQ09OU09MRV9NRVRIT0RTID0gW1wibG9nXCIsIFwiaW5mb1wiLCBcIndhcm5cIiwgXCJlcnJvclwiLCBcImRlYnVnXCJdXG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIC0gVmFsdWUgdG8gc2FuaXRpemUuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSAtIFNsdWctc2FmZSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gdG9GaWxlU2x1Zyh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWVcbiAgICAudG9Mb3dlckNhc2UoKVxuICAgIC5yZXBsYWNlKC9bXmEtejAtOV0rL2csIFwiLVwiKVxuICAgIC5yZXBsYWNlKC9eLSt8LSskL2csIFwiXCIpXG4gICAgLnNsaWNlKDAsIDgwKSB8fCBcImZhaWxlZC10ZXN0XCJcbn1cblxuLyoqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBUZXN0QXJnc1xuICogQHByb3BlcnR5IHtBcHBsaWNhdGlvbn0gW2FwcGxpY2F0aW9uXSAtIEFwcGxpY2F0aW9uIGluc3RhbmNlIGZvciBpbnRlZ3JhdGlvbiB0ZXN0cy5cbiAqIEBwcm9wZXJ0eSB7UmVxdWVzdENsaWVudH0gW2NsaWVudF0gLSBIVFRQIGNsaWVudCBmb3IgcmVxdWVzdCB0ZXN0cy5cbiAqIEBwcm9wZXJ0eSB7b2JqZWN0fSBbZGF0YWJhc2VDbGVhbmluZ10gLSBEYXRhYmFzZSBjbGVhbnVwIG9wdGlvbnMgZm9yIHRlc3RzLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbZGF0YWJhc2VDbGVhbmluZy50cmFuc2FjdGlvbl0gLSBVc2UgdHJhbnNhY3Rpb25zIHRvIHJvbGxiYWNrIGJldHdlZW4gdGVzdHMuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtkYXRhYmFzZUNsZWFuaW5nLnRydW5jYXRlXSAtIFRydW5jYXRlIHRhYmxlcyBiZXR3ZWVuIHRlc3RzLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbZm9jdXNdIC0gV2hldGhlciB0aGlzIHRlc3QgaXMgZm9jdXNlZC5cbiAqIEBwcm9wZXJ0eSB7KCkgPT4gKHZvaWR8UHJvbWlzZTx2b2lkPil9IFtmdW5jdGlvbl0gLSBUZXN0IGNhbGxiYWNrIGZ1bmN0aW9uLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtyZXRyeV0gLSBOdW1iZXIgb2YgcmV0cmllcyB3aGVuIGEgdGVzdCBmYWlscy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW10gfCBzdHJpbmd9IFt0YWdzXSAtIFRhZ3MgZm9yIGZpbHRlcmluZy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbdGltZW91dFNlY29uZHNdIC0gVGltZW91dCBpbiBzZWNvbmRzIGZvciB0aGUgdGVzdC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbdHlwZV0gLSBUZXN0IHR5cGUgaWRlbnRpZmllci5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtvYmplY3R9IFRlc3REYXRhXG4gKiBAcHJvcGVydHkge1Rlc3RBcmdzfSBhcmdzIC0gQXJndW1lbnRzIHBhc3NlZCB0byB0aGUgdGVzdC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbZmlsZVBhdGhdIC0gU291cmNlIGZpbGUgcGF0aC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbGluZV0gLSBTb3VyY2UgbGluZSBudW1iZXIuXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9uKFRlc3RBcmdzKSA6ICh2b2lkfFByb21pc2U8dm9pZD4pfSBmdW5jdGlvbiAtIFRlc3QgY2FsbGJhY2sgdG8gZXhlY3V0ZS5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtvYmplY3R9IEZhaWxlZFRlc3REZXRhaWxcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBmdWxsRGVzY3JpcHRpb24gLSBGdWxsIHRlc3QgZGVzY3JpcHRpb24uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2ZpbGVQYXRoXSAtIFNvdXJjZSBmaWxlIHBhdGguXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2xpbmVdIC0gU291cmNlIGxpbmUgbnVtYmVyLlxuICogQHByb3BlcnR5IHt1bmtub3dufSBlcnJvciAtIEZhaWx1cmUgZXJyb3IuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2NvbnNvbGVPdXRwdXRdIC0gQ2FwdHVyZWQgY29uc29sZSBvdXRwdXQgd2hpbGUgdGVzdCByYW4uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2NvbnNvbGVMb2dQYXRoXSAtIFNhdmVkIGNvbnNvbGUgbG9nIHBhdGguXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oe2NvbmZpZ3VyYXRpb246IGltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdCwgdGVzdEFyZ3M6IFRlc3RBcmdzLCB0ZXN0RGF0YTogVGVzdERhdGF9KSA6ICh2b2lkfFByb21pc2U8dm9pZD4pfSBBZnRlckJlZm9yZUVhY2hDYWxsYmFja1R5cGVcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtvYmplY3R9IEFmdGVyQmVmb3JlRWFjaENhbGxiYWNrT2JqZWN0VHlwZVxuICogQHByb3BlcnR5IHtBZnRlckJlZm9yZUVhY2hDYWxsYmFja1R5cGV9IGNhbGxiYWNrIC0gSG9vayBjYWxsYmFjayB0byBleGVjdXRlLlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge2Z1bmN0aW9uKHtjb25maWd1cmF0aW9uOiBpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9KSA6ICh2b2lkfFByb21pc2U8dm9pZD4pfSBCZWZvcmVBZnRlckFsbENhbGxiYWNrVHlwZVxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge29iamVjdH0gQmVmb3JlQWZ0ZXJBbGxDYWxsYmFja09iamVjdFR5cGVcbiAqIEBwcm9wZXJ0eSB7QmVmb3JlQWZ0ZXJBbGxDYWxsYmFja1R5cGV9IGNhbGxiYWNrIC0gSG9vayBjYWxsYmFjayB0byBleGVjdXRlLlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge29iamVjdH0gVGVzdHNBcmd1bWVudFxuICogQHByb3BlcnR5IHtSZWNvcmQ8c3RyaW5nLCBUZXN0RGF0YT59IGFyZ3MgLSBBcmd1bWVudHMga2V5ZWQgYnkgdGVzdCBkZXNjcmlwdGlvbi5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2FueVRlc3RzRm9jdXNzZWRdIC0gV2hldGhlciBhbnkgdGVzdHMgaW4gdGhlIHRyZWUgYXJlIGZvY3VzZWQuXG4gKiBAcHJvcGVydHkge0FmdGVyQmVmb3JlRWFjaENhbGxiYWNrT2JqZWN0VHlwZVtdfSBhZnRlckVhY2hlcyAtIEFmdGVyLWVhY2ggaG9va3MgZm9yIHRoaXMgc2NvcGUuXG4gKiBAcHJvcGVydHkge0JlZm9yZUFmdGVyQWxsQ2FsbGJhY2tPYmplY3RUeXBlW119IGFmdGVyQWxscyAtIEFmdGVyLWFsbCBob29rcyBmb3IgdGhpcyBzY29wZS5cbiAqIEBwcm9wZXJ0eSB7QmVmb3JlQWZ0ZXJBbGxDYWxsYmFja09iamVjdFR5cGVbXX0gYmVmb3JlQWxscyAtIEJlZm9yZS1hbGwgaG9va3MgZm9yIHRoaXMgc2NvcGUuXG4gKiBAcHJvcGVydHkge0FmdGVyQmVmb3JlRWFjaENhbGxiYWNrT2JqZWN0VHlwZVtdfSBiZWZvcmVFYWNoZXMgLSBCZWZvcmUtZWFjaCBob29rcyBmb3IgdGhpcyBzY29wZS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbZmlsZVBhdGhdIC0gU291cmNlIGZpbGUgcGF0aC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbGluZV0gLSBTb3VyY2UgbGluZSBudW1iZXIuXG4gKiBAcHJvcGVydHkge1JlY29yZDxzdHJpbmcsIFRlc3REYXRhPn0gdGVzdHMgLSBBIHVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgbm9kZS5cbiAqIEBwcm9wZXJ0eSB7UmVjb3JkPHN0cmluZywgVGVzdHNBcmd1bWVudD59IHN1YnMgLSBPcHRpb25hbCBjaGlsZCBub2Rlcy4gRWFjaCBpdGVtIGlzIGFub3RoZXIgYE5vZGVgLCBhbGxvd2luZyByZWN1cnNpb24uXG4gKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGVzdFJ1bm5lciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0gYXJncy5jb25maWd1cmF0aW9uIC0gQ29uZmlndXJhdGlvbiBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtzdHJpbmdbXSB8IHN0cmluZ30gW2FyZ3MuZXhjbHVkZVRhZ3NdIC0gVGFncyB0byBleGNsdWRlLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdIHwgc3RyaW5nfSBbYXJncy5pbmNsdWRlVGFnc10gLSBUYWdzIHRvIGluY2x1ZGUuXG4gICAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gYXJncy50ZXN0RmlsZXMgLSBUZXN0IGZpbGVzLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIG51bWJlcltdPn0gW2FyZ3MubGluZUZpbHRlcnNdIC0gTGluZSBmaWx0ZXJzIGJ5IGZpbGUuXG4gICAqIEBwYXJhbSB7UmVnRXhwW119IFthcmdzLmV4YW1wbGVQYXR0ZXJuc10gLSBFeGFtcGxlIHBhdHRlcm5zLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioe2NvbmZpZ3VyYXRpb24sIGV4Y2x1ZGVUYWdzLCBpbmNsdWRlVGFncywgdGVzdEZpbGVzLCBsaW5lRmlsdGVycywgZXhhbXBsZVBhdHRlcm5zLCAuLi5yZXN0QXJnc30pIHtcbiAgICByZXN0QXJnc0Vycm9yKHJlc3RBcmdzKVxuXG4gICAgaWYgKCFjb25maWd1cmF0aW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJjb25maWd1cmF0aW9uIGlzIHJlcXVpcmVkXCIpXG5cbiAgICB0aGlzLl9jb25maWd1cmF0aW9uID0gY29uZmlndXJhdGlvblxuICAgIHRoaXMuX2V4Y2x1ZGVUYWdzID0gdGhpcy5ub3JtYWxpemVUYWdzKGV4Y2x1ZGVUYWdzKVxuICAgIHRoaXMuX2V4Y2x1ZGVUYWdTZXQgPSBuZXcgU2V0KHRoaXMuX2V4Y2x1ZGVUYWdzKVxuICAgIHRoaXMuX2luY2x1ZGVUYWdzID0gdGhpcy5ub3JtYWxpemVUYWdzKGluY2x1ZGVUYWdzKVxuICAgIHRoaXMuX2luY2x1ZGVUYWdTZXQgPSBuZXcgU2V0KHRoaXMuX2luY2x1ZGVUYWdzKVxuICAgIHRoaXMuX3Rlc3RGaWxlcyA9IHRlc3RGaWxlc1xuICAgIHRoaXMuX2xpbmVGaWx0ZXJzID0gbGluZUZpbHRlcnMgfHwge31cbiAgICB0aGlzLl9leGFtcGxlUGF0dGVybnMgPSBleGFtcGxlUGF0dGVybnMgfHwgW11cblxuICAgIHRoaXMuX2ZhaWxlZFRlc3RzID0gMFxuICAgIHRoaXMuX3N1Y2Nlc3NmdWxUZXN0cyA9IDBcbiAgICB0aGlzLl90ZXN0c0NvdW50ID0gMFxuICAgIHRoaXMuX2FjdGl2ZUFmdGVyQWxsU2NvcGVzID0gW11cbiAgICB0aGlzLl9mYWlsZWRUZXN0RGV0YWlscyA9IFtdXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0gLSBUaGUgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIGdldENvbmZpZ3VyYXRpb24oKSB7IHJldHVybiB0aGlzLl9jb25maWd1cmF0aW9uIH1cblxuICAvKipcbiAgICogQHJldHVybnMge3N0cmluZ1tdfSAtIFRoZSB0ZXN0IGZpbGVzLlxuICAgKi9cbiAgZ2V0VGVzdEZpbGVzKCkgeyByZXR1cm4gdGhpcy5fdGVzdEZpbGVzIH1cblxuICAvKiogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIG51bWJlcltdPn0gLSBMaW5lIGZpbHRlcnMuICovXG4gIGdldExpbmVGaWx0ZXJzKCkgeyByZXR1cm4gdGhpcy5fbGluZUZpbHRlcnMgfVxuXG4gIC8qKiBAcmV0dXJucyB7UmVnRXhwW119IC0gRXhhbXBsZSBwYXR0ZXJucy4gKi9cbiAgZ2V0RXhhbXBsZVBhdHRlcm5zKCkgeyByZXR1cm4gdGhpcy5fZXhhbXBsZVBhdHRlcm5zIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmdbXSB8IHN0cmluZyB8IHVuZGVmaW5lZH0gdGFncyAtIFRhZ3MuXG4gICAqIEByZXR1cm5zIHtzdHJpbmdbXX0gLSBOb3JtYWxpemVkIHRhZ3MuXG4gICAqL1xuICBub3JtYWxpemVUYWdzKHRhZ3MpIHtcbiAgICBpZiAoIXRhZ3MpIHJldHVybiBbXVxuXG4gICAgY29uc3QgdmFsdWVzID0gW11cbiAgICBjb25zdCByYXdUYWdzID0gQXJyYXkuaXNBcnJheSh0YWdzKSA/IHRhZ3MgOiBbdGFnc11cblxuICAgIGZvciAoY29uc3QgcmF3VGFnIG9mIHJhd1RhZ3MpIHtcbiAgICAgIGlmIChyYXdUYWcgPT09IHVuZGVmaW5lZCB8fCByYXdUYWcgPT09IG51bGwpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IHBhcnRzID0gU3RyaW5nKHJhd1RhZykuc3BsaXQoXCIsXCIpXG5cbiAgICAgIGZvciAoY29uc3QgcGFydCBvZiBwYXJ0cykge1xuICAgICAgICBjb25zdCB0cmltbWVkID0gcGFydC50cmltKClcblxuICAgICAgICBpZiAodHJpbW1lZCkgdmFsdWVzLnB1c2godHJpbW1lZClcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gQXJyYXkuZnJvbShuZXcgU2V0KHZhbHVlcykpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtUZXN0QXJnc30gdGVzdEFyZ3MgLSBUZXN0IGFyZ3MuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgLSBUYWcgdG8gY2hlY2sgZm9yLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRhZyBpcyBwcmVzZW50LlxuICAgKi9cbiAgaGFzVGFnKHRlc3RBcmdzLCB0YWcpIHtcbiAgICByZXR1cm4gdGhpcy5ub3JtYWxpemVUYWdzKHRlc3RBcmdzPy50YWdzKS5pbmNsdWRlcyh0YWcpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciBydW5uaW5nIGJyb3dzZXIgdGVzdHMuXG4gICAqL1xuICBpc0Jyb3dzZXJUZXN0TW9kZSgpIHtcbiAgICByZXR1cm4gcHJvY2Vzcy5lbnYuVkVMT0NJT1VTX0JST1dTRVJfVEVTVFMgPT09IFwidHJ1ZVwiXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtUZXN0QXJnc30gdGVzdEFyZ3MgLSBUZXN0IGFyZ3MuXG4gICAqIEBwYXJhbSB7KCkgPT4gUHJvbWlzZTx2b2lkPn0gY2FsbGJhY2sgLSBDYWxsYmFjayB0byBydW4uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBydW5XaXRoRHVtbXlJZk5lZWRlZCh0ZXN0QXJncywgY2FsbGJhY2spIHtcbiAgICBpZiAoIXRoaXMuaGFzVGFnKHRlc3RBcmdzLCBcImR1bW15XCIpKSB7XG4gICAgICBhd2FpdCBjYWxsYmFjaygpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc0Jyb3dzZXJUZXN0TW9kZSgpKSB7XG4gICAgICBhd2FpdCB0aGlzLnJ1bkJyb3dzZXJEdW1teShjYWxsYmFjaylcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGF3YWl0IHRoaXMucnVuTm9kZUR1bW15KGNhbGxiYWNrKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7KCkgPT4gUHJvbWlzZTx2b2lkPn0gY2FsbGJhY2sgLSBDYWxsYmFjayB0byBydW4uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBydW5Ob2RlRHVtbXkoY2FsbGJhY2spIHtcbiAgICBjb25zdCBkdW1teVBhdGggPSBwcm9jZXNzLmVudi5WRUxPQ0lPVVNfRFVNTVlfUEFUSCB8fCB0aGlzLmRlZmF1bHREdW1teVBhdGgoKVxuICAgIGNvbnN0IGR1bW15SW1wb3J0ID0gYXdhaXQgaW1wb3J0KHBhdGhUb0ZpbGVVUkwoZHVtbXlQYXRoKS5ocmVmKVxuICAgIGNvbnN0IER1bW15ID0gZHVtbXlJbXBvcnQuZGVmYXVsdFxuXG4gICAgaWYgKCFEdW1teT8ucnVuKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYER1bW15IGhlbHBlciBub3QgZm91bmQgYXQgJHtkdW1teVBhdGh9YClcbiAgICB9XG5cbiAgICBhd2FpdCBEdW1teS5ydW4oY2FsbGJhY2spXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge3N0cmluZ30gLSBEZWZhdWx0IGR1bW15IGhlbHBlciBwYXRoLlxuICAgKi9cbiAgZGVmYXVsdER1bW15UGF0aCgpIHtcbiAgICBjb25zdCBjd2QgPSBwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSlcbiAgICBjb25zdCBub3JtYWxpemVkID0gY3dkLnNwbGl0KHBhdGguc2VwKS5qb2luKFwiL1wiKVxuXG4gICAgaWYgKG5vcm1hbGl6ZWQuZW5kc1dpdGgoXCIvc3BlYy9kdW1teVwiKSkge1xuICAgICAgcmV0dXJuIHBhdGguam9pbihjd2QsIFwiaW5kZXguanNcIilcbiAgICB9XG5cbiAgICByZXR1cm4gcGF0aC5qb2luKGN3ZCwgXCJzcGVjL2R1bW15L2luZGV4LmpzXCIpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHsoKSA9PiBQcm9taXNlPHZvaWQ+fSBjYWxsYmFjayAtIENhbGxiYWNrIHRvIHJ1bi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHJ1bkJyb3dzZXJEdW1teShjYWxsYmFjaykge1xuICAgIGF3YWl0IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLmVuc3VyZUNvbm5lY3Rpb25zKGFzeW5jIChkYnMpID0+IHtcbiAgICAgIGF3YWl0IHRoaXMudHJ1bmNhdGVEYXRhYmFzZXMoZGJzKVxuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBjYWxsYmFjaygpXG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCB0aGlzLnRydW5jYXRlRGF0YWJhc2VzKGRicylcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgaW1wb3J0KFwiLi4vZGF0YWJhc2UvZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+fSBkYnMgLSBEYXRhYmFzZSBjb25uZWN0aW9ucy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHRydW5jYXRlRGF0YWJhc2VzKGRicykge1xuICAgIGZvciAoY29uc3QgaWRlbnRpZmllciBvZiBPYmplY3Qua2V5cyhkYnMpKSB7XG4gICAgICBhd2FpdCBkYnNbaWRlbnRpZmllcl0udHJ1bmNhdGVBbGxUYWJsZXMoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7U2V0PHN0cmluZz59IC0gRXhjbHVkZSB0YWcgc2V0LlxuICAgKi9cbiAgZ2V0RXhjbHVkZVRhZ1NldCgpIHtcbiAgICBjb25zdCBjb25maWdUYWdzID0gQXJyYXkuaXNBcnJheSh0ZXN0Q29uZmlnLmV4Y2x1ZGVUYWdzKSA/IHRlc3RDb25maWcuZXhjbHVkZVRhZ3MgOiBbXVxuXG4gICAgcmV0dXJuIG5ldyBTZXQoWy4uLnRoaXMuX2V4Y2x1ZGVUYWdzLCAuLi5jb25maWdUYWdzXSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdIHwgc3RyaW5nIHwgdW5kZWZpbmVkfSB0ZXN0VGFncyAtIFRlc3QgdGFncy5cbiAgICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gdGFnU2V0IC0gVGFnIHNldC5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciBhbnkgdGFncyBtYXRjaC5cbiAgICovXG4gIGhhc01hdGNoaW5nVGFnKHRlc3RUYWdzLCB0YWdTZXQpIHtcbiAgICBpZiAoIXRhZ1NldC5zaXplKSByZXR1cm4gZmFsc2VcblxuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSB0aGlzLm5vcm1hbGl6ZVRhZ3ModGVzdFRhZ3MpXG5cbiAgICBmb3IgKGNvbnN0IHRhZyBvZiBub3JtYWxpemVkKSB7XG4gICAgICBpZiAodGFnU2V0Lmhhcyh0YWcpKSByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7VGVzdHNBcmd1bWVudH0gdGVzdHMgLSBUZXN0cy5cbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gW2Rlc2NyaXB0aW9uc10gLSBEZXNjcmlwdGlvbiBzdGFjay5cbiAgICogQHBhcmFtIHtib29sZWFufSBbbGluZU1hdGNoZWRJblNjb3BlXSAtIFdoZXRoZXIgbGluZSBtYXRjaGVkIGluIHNjb3BlLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGFueSB0ZXN0cyBpbiB0aGlzIHNjb3BlIHdpbGwgcnVuLlxuICAgKi9cbiAgaGFzUnVubmFibGVUZXN0cyh0ZXN0cywgZGVzY3JpcHRpb25zID0gW10sIGxpbmVNYXRjaGVkSW5TY29wZSA9IGZhbHNlKSB7XG4gICAgZm9yIChjb25zdCB0ZXN0RGVzY3JpcHRpb24gaW4gdGVzdHMudGVzdHMpIHtcbiAgICAgIGNvbnN0IHRlc3REYXRhID0gdGVzdHMudGVzdHNbdGVzdERlc2NyaXB0aW9uXVxuICAgICAgY29uc3QgdGVzdEFyZ3MgPSAvKiogQHR5cGUge1Rlc3RBcmdzfSAqLyAoT2JqZWN0LmFzc2lnbih7fSwgdGVzdERhdGEuYXJncykpXG4gICAgICBjb25zdCBpbmNsdWRlQnlMaW5lID0gbGluZU1hdGNoZWRJblNjb3BlIHx8IHRoaXMubWF0Y2hlc0xpbmVGaWx0ZXIodGVzdERhdGEpXG5cbiAgICAgIGlmICh0aGlzLl9vbmx5Rm9jdXNzZWQgJiYgIXRlc3RBcmdzLmZvY3VzKSBjb250aW51ZVxuICAgICAgaWYgKHRoaXMuc2hvdWxkU2tpcFRlc3QodGVzdEFyZ3MsIHRlc3REYXRhLCB0ZXN0RGVzY3JpcHRpb24sIGRlc2NyaXB0aW9ucywgaW5jbHVkZUJ5TGluZSkpIGNvbnRpbnVlXG5cbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBzdWJEZXNjcmlwdGlvbiBpbiB0ZXN0cy5zdWJzKSB7XG4gICAgICBjb25zdCBzdWJUZXN0ID0gdGVzdHMuc3Vic1tzdWJEZXNjcmlwdGlvbl1cbiAgICAgIGNvbnN0IHNjb3BlTGluZU1hdGNoID0gbGluZU1hdGNoZWRJblNjb3BlIHx8IHRoaXMubWF0Y2hlc0xpbmVGaWx0ZXIoc3ViVGVzdClcbiAgICAgIGNvbnN0IG5leHREZXNjcmlwdGlvbnMgPSBkZXNjcmlwdGlvbnMuY29uY2F0KFtzdWJEZXNjcmlwdGlvbl0pXG5cbiAgICAgIGlmICh0aGlzLl9vbmx5Rm9jdXNzZWQgJiYgIXN1YlRlc3QuYW55VGVzdHNGb2N1c3NlZCkgY29udGludWVcbiAgICAgIGlmICh0aGlzLmhhc1J1bm5hYmxlVGVzdHMoc3ViVGVzdCwgbmV4dERlc2NyaXB0aW9ucywgc2NvcGVMaW5lTWF0Y2gpKSByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7VGVzdEFyZ3N9IHRlc3RBcmdzIC0gVGVzdCBhcmdzLlxuICAgKiBAcGFyYW0ge1Rlc3REYXRhfSB0ZXN0RGF0YSAtIFRlc3QgZGF0YS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRlc3REZXNjcmlwdGlvbiAtIFRlc3QgZGVzY3JpcHRpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGRlc2NyaXB0aW9ucyAtIERlc2NyaXB0aW9uIHN0YWNrLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGxpbmVNYXRjaGVkSW5TY29wZSAtIFdoZXRoZXIgbGluZSBtYXRjaGVkIGluIHNjb3BlLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoZSB0ZXN0IHNob3VsZCBiZSBza2lwcGVkLlxuICAgKi9cbiAgc2hvdWxkU2tpcFRlc3QodGVzdEFyZ3MsIHRlc3REYXRhLCB0ZXN0RGVzY3JpcHRpb24sIGRlc2NyaXB0aW9ucywgbGluZU1hdGNoZWRJblNjb3BlKSB7XG4gICAgaWYgKHRoaXMuaGFzTWF0Y2hpbmdUYWcodGVzdEFyZ3MudGFncywgdGhpcy5nZXRFeGNsdWRlVGFnU2V0KCkpKSByZXR1cm4gdHJ1ZVxuXG4gICAgaWYgKHRoaXMuX2luY2x1ZGVUYWdTZXQuc2l6ZSA+IDAgJiYgIXRlc3RBcmdzLmZvY3VzKSB7XG4gICAgICBpZiAoIXRoaXMuaGFzTWF0Y2hpbmdUYWcodGVzdEFyZ3MudGFncywgdGhpcy5faW5jbHVkZVRhZ1NldCkpIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZ2V0RXhhbXBsZVBhdHRlcm5zKCkubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgZnVsbERlc2NyaXB0aW9uID0gdGhpcy5idWlsZEZ1bGxEZXNjcmlwdGlvbihkZXNjcmlwdGlvbnMsIHRlc3REZXNjcmlwdGlvbilcbiAgICAgIGNvbnN0IG1hdGNoZXMgPSB0aGlzLmdldEV4YW1wbGVQYXR0ZXJucygpLnNvbWUoKHBhdHRlcm4pID0+IHtcbiAgICAgICAgcGF0dGVybi5sYXN0SW5kZXggPSAwXG4gICAgICAgIHJldHVybiBwYXR0ZXJuLnRlc3QoZnVsbERlc2NyaXB0aW9uKVxuICAgICAgfSlcblxuICAgICAgaWYgKCFtYXRjaGVzKSByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIGNvbnN0IGxpbmVGaWx0ZXJzID0gdGhpcy5nZXRMaW5lRmlsdGVycygpXG5cbiAgICBpZiAoT2JqZWN0LmtleXMobGluZUZpbHRlcnMpLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmICghbGluZU1hdGNoZWRJblNjb3BlICYmICF0aGlzLm1hdGNoZXNMaW5lRmlsdGVyKHRlc3REYXRhKSkgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1Rlc3REYXRhIHwgVGVzdHNBcmd1bWVudH0gZW50cnkgLSBUZXN0IGVudHJ5LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGxpbmUgZmlsdGVyIG1hdGNoZXMgZW50cnkuXG4gICAqL1xuICBtYXRjaGVzTGluZUZpbHRlcihlbnRyeSkge1xuICAgIGlmICghZW50cnkgfHwgIWVudHJ5LmZpbGVQYXRoIHx8ICFlbnRyeS5saW5lKSByZXR1cm4gZmFsc2VcblxuICAgIGNvbnN0IGZpbGVQYXRoID0gcGF0aC5yZXNvbHZlKGVudHJ5LmZpbGVQYXRoKVxuICAgIGNvbnN0IGxpbmVzID0gdGhpcy5nZXRMaW5lRmlsdGVycygpW2ZpbGVQYXRoXVxuXG4gICAgaWYgKCFsaW5lcyB8fCBsaW5lcy5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZVxuXG4gICAgcmV0dXJuIGxpbmVzLmluY2x1ZGVzKGVudHJ5LmxpbmUpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gZGVzY3JpcHRpb25zIC0gRGVzY3JpcHRpb24gc3RhY2suXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXN0RGVzY3JpcHRpb24gLSBUZXN0IGRlc2NyaXB0aW9uLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIEZ1bGwgZGVzY3JpcHRpb24uXG4gICAqL1xuICBidWlsZEZ1bGxEZXNjcmlwdGlvbihkZXNjcmlwdGlvbnMsIHRlc3REZXNjcmlwdGlvbikge1xuICAgIGNvbnN0IHBhcnRzID0gZGVzY3JpcHRpb25zLmNvbmNhdChbdGVzdERlc2NyaXB0aW9uXSlcblxuICAgIHJldHVybiBwYXJ0cy5qb2luKFwiIFwiKS50cmltKClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxBcHBsaWNhdGlvbj59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgYXBwbGljYXRpb24uXG4gICAqL1xuICBhc3luYyBhcHBsaWNhdGlvbigpIHtcbiAgICBpZiAoIXRoaXMuX2FwcGxpY2F0aW9uKSB7XG4gICAgICB0aGlzLl9hcHBsaWNhdGlvbiA9IG5ldyBBcHBsaWNhdGlvbih7XG4gICAgICAgIGNvbmZpZ3VyYXRpb246IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLFxuICAgICAgICBodHRwU2VydmVyOiB7cG9ydDogMzEwMDZ9LFxuICAgICAgICB0eXBlOiBcInRlc3QtcnVubmVyXCJcbiAgICAgIH0pXG5cbiAgICAgIGF3YWl0IHRoaXMuX2FwcGxpY2F0aW9uLmluaXRpYWxpemUoKVxuICAgICAgYXdhaXQgdGhpcy5fYXBwbGljYXRpb24uc3RhcnRIdHRwU2VydmVyKClcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fYXBwbGljYXRpb25cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxSZXF1ZXN0Q2xpZW50Pn0gLSBSZXNvbHZlcyB3aXRoIHRoZSByZXF1ZXN0IGNsaWVudC5cbiAgICovXG4gIGFzeW5jIHJlcXVlc3RDbGllbnQoKSB7XG4gICAgaWYgKCF0aGlzLl9yZXF1ZXN0Q2xpZW50KSB7XG4gICAgICB0aGlzLl9yZXF1ZXN0Q2xpZW50ID0gbmV3IFJlcXVlc3RDbGllbnQoKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9yZXF1ZXN0Q2xpZW50XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGltcG9ydFRlc3RGaWxlcygpIHtcbiAgICBhd2FpdCB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5nZXRFbnZpcm9ubWVudEhhbmRsZXIoKS5pbXBvcnRUZXN0RmlsZXModGhpcy5nZXRUZXN0RmlsZXMoKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGZhaWxlZC5cbiAgICovXG4gIGlzRmFpbGVkKCkgeyByZXR1cm4gdGhpcy5fZmFpbGVkVGVzdHMgIT09IHVuZGVmaW5lZCAmJiB0aGlzLl9mYWlsZWRUZXN0cyA+IDAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIFRoZSBmYWlsZWQgdGVzdHMuXG4gICAqL1xuICBnZXRGYWlsZWRUZXN0cygpIHtcbiAgICBpZiAodGhpcy5fZmFpbGVkVGVzdHMgPT09IHVuZGVmaW5lZCkgdGhyb3cgbmV3IEVycm9yKFwiVGVzdHMgaGFzbid0IGJlZW4gcnVuIHlldFwiKVxuXG4gICAgcmV0dXJuIHRoaXMuX2ZhaWxlZFRlc3RzXG4gIH1cblxuICAvKiogQHJldHVybnMge0ZhaWxlZFRlc3REZXRhaWxbXX0gLSBGYWlsZWQgdGVzdCBkZXRhaWxzLiAqL1xuICBnZXRGYWlsZWRUZXN0RGV0YWlscygpIHtcbiAgICByZXR1cm4gdGhpcy5fZmFpbGVkVGVzdERldGFpbHNcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gW2FyZ3NdIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYXJncy5hc3NldHNQYXRoXSAtIEFzc2V0cyBkaXJlY3RvcnkgcGF0aC5cbiAgICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nW10+fSAtIFdyaXR0ZW4gbG9nIGZpbGUgcGF0aHMuXG4gICAqL1xuICBhc3luYyBwZXJzaXN0RmFpbGVkVGVzdENvbnNvbGVPdXRwdXRzVG9Bc3NldHMoe2Fzc2V0c1BhdGggPSBwYXRoLmpvaW4ocHJvY2Vzcy5jd2QoKSwgXCJ0bXAvc2NyZWVuc2hvdHNcIil9ID0ge30pIHtcbiAgICBjb25zdCBmYWlsZWRUZXN0RGV0YWlscyA9IHRoaXMuZ2V0RmFpbGVkVGVzdERldGFpbHMoKVxuICAgIGNvbnN0IHdyaXR0ZW5Mb2dQYXRocyA9IFtdXG4gICAgbGV0IGNyZWF0ZWREaXJlY3RvcnkgPSBmYWxzZVxuXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGZhaWxlZFRlc3REZXRhaWxzLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgY29uc3QgZmFpbGVkVGVzdERldGFpbCA9IGZhaWxlZFRlc3REZXRhaWxzW2luZGV4XVxuICAgICAgY29uc3QgY29uc29sZU91dHB1dCA9IGZhaWxlZFRlc3REZXRhaWwuY29uc29sZU91dHB1dFxuXG4gICAgICBpZiAoIWNvbnNvbGVPdXRwdXQpIGNvbnRpbnVlXG5cbiAgICAgIGlmICghY3JlYXRlZERpcmVjdG9yeSkge1xuICAgICAgICBhd2FpdCBmcy5ta2Rpcihhc3NldHNQYXRoLCB7cmVjdXJzaXZlOiB0cnVlfSlcbiAgICAgICAgY3JlYXRlZERpcmVjdG9yeSA9IHRydWVcbiAgICAgIH1cblxuICAgICAgY29uc3Qgbm93ID0gbmV3IERhdGUoKVxuICAgICAgY29uc3QgdGltZXN0YW1wID0gW1xuICAgICAgICBTdHJpbmcobm93LmdldEZ1bGxZZWFyKCkpLFxuICAgICAgICBTdHJpbmcobm93LmdldE1vbnRoKCkgKyAxKS5wYWRTdGFydCgyLCBcIjBcIiksXG4gICAgICAgIFN0cmluZyhub3cuZ2V0RGF0ZSgpKS5wYWRTdGFydCgyLCBcIjBcIiksXG4gICAgICAgIFN0cmluZyhub3cuZ2V0SG91cnMoKSkucGFkU3RhcnQoMiwgXCIwXCIpLFxuICAgICAgICBTdHJpbmcobm93LmdldE1pbnV0ZXMoKSkucGFkU3RhcnQoMiwgXCIwXCIpLFxuICAgICAgICBTdHJpbmcobm93LmdldFNlY29uZHMoKSkucGFkU3RhcnQoMiwgXCIwXCIpLFxuICAgICAgICBTdHJpbmcobm93LmdldE1pbGxpc2Vjb25kcygpKS5wYWRTdGFydCgzLCBcIjBcIilcbiAgICAgIF0uam9pbihcIlwiKVxuICAgICAgY29uc3Qgc2x1ZyA9IHRvRmlsZVNsdWcoZmFpbGVkVGVzdERldGFpbC5mdWxsRGVzY3JpcHRpb24pXG4gICAgICBjb25zdCBmaWxlTmFtZSA9IGAke3RpbWVzdGFtcH0tJHtTdHJpbmcoaW5kZXggKyAxKS5wYWRTdGFydCgyLCBcIjBcIil9LSR7c2x1Z30uY29uc29sZS5sb2dgXG4gICAgICBjb25zdCBmaWxlUGF0aCA9IHBhdGguam9pbihhc3NldHNQYXRoLCBmaWxlTmFtZSlcblxuICAgICAgYXdhaXQgZnMud3JpdGVGaWxlKGZpbGVQYXRoLCBjb25zb2xlT3V0cHV0LCBcInV0ZjhcIilcbiAgICAgIGZhaWxlZFRlc3REZXRhaWwuY29uc29sZUxvZ1BhdGggPSBmaWxlUGF0aFxuICAgICAgd3JpdHRlbkxvZ1BhdGhzLnB1c2goZmlsZVBhdGgpXG4gICAgfVxuXG4gICAgcmV0dXJuIHdyaXR0ZW5Mb2dQYXRoc1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gVGhlIHN1Y2Nlc3NmdWwgdGVzdHMuXG4gICAqL1xuICBnZXRTdWNjZXNzZnVsVGVzdHMoKSB7XG4gICAgaWYgKHRoaXMuX3N1Y2Nlc3NmdWxUZXN0cyA9PT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgRXJyb3IoXCJUZXN0cyBoYXNuJ3QgYmVlbiBydW4geWV0XCIpXG5cbiAgICByZXR1cm4gdGhpcy5fc3VjY2Vzc2Z1bFRlc3RzXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge251bWJlcn0gLSBUaGUgdGVzdHMgY291bnQuXG4gICAqL1xuICBnZXRUZXN0c0NvdW50KCkge1xuICAgIGlmICh0aGlzLl90ZXN0c0NvdW50ID09PSB1bmRlZmluZWQpIHRocm93IG5ldyBFcnJvcihcIlRlc3RzIGhhc24ndCBiZWVuIHJ1biB5ZXRcIilcblxuICAgIHJldHVybiB0aGlzLl90ZXN0c0NvdW50XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge251bWJlcn0gLSBUaGUgZXhlY3V0ZWQgdGVzdHMgY291bnQuXG4gICAqL1xuICBnZXRFeGVjdXRlZFRlc3RzQ291bnQoKSB7XG4gICAgaWYgKHRoaXMuX3N1Y2Nlc3NmdWxUZXN0cyA9PT0gdW5kZWZpbmVkIHx8IHRoaXMuX2ZhaWxlZFRlc3RzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRlc3RzIGhhc24ndCBiZWVuIHJ1biB5ZXRcIilcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fc3VjY2Vzc2Z1bFRlc3RzICsgdGhpcy5fZmFpbGVkVGVzdHNcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgcHJlcGFyZSgpIHtcbiAgICB0aGlzLmFueVRlc3RzRm9jdXNzZWQgPSBmYWxzZVxuICAgIHRoaXMuX2ZhaWxlZFRlc3RzID0gMFxuICAgIHRoaXMuX3N1Y2Nlc3NmdWxUZXN0cyA9IDBcbiAgICB0aGlzLl90ZXN0c0NvdW50ID0gMFxuICAgIHRoaXMuX2ZhaWxlZFRlc3REZXRhaWxzID0gW11cbiAgICBhd2FpdCB0aGlzLmltcG9ydFRlc3RGaWxlcygpXG4gICAgYXdhaXQgdGhpcy5hbmFseXplVGVzdHModGVzdHMpXG4gICAgdGhpcy5fb25seUZvY3Vzc2VkID0gdGhpcy5hbnlUZXN0c0ZvY3Vzc2VkXG5cbiAgICBjb25zdCB0ZXN0aW5nQ29uZmlnUGF0aCA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLmdldFRlc3RpbmcoKVxuXG4gICAgaWYgKHRlc3RpbmdDb25maWdQYXRoKSB7XG4gICAgICBhd2FpdCB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5nZXRFbnZpcm9ubWVudEhhbmRsZXIoKS5pbXBvcnRUZXN0aW5nQ29uZmlnUGF0aCgpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgYW55IHRlc3RzIGZvY3Vzc2VkLlxuICAgKi9cbiAgYXJlQW55VGVzdHNGb2N1c3NlZCgpIHtcbiAgICBpZiAodGhpcy5hbnlUZXN0c0ZvY3Vzc2VkID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkhhc24ndCBiZWVuIGRldGVjdGVkIHlldFwiKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmFueVRlc3RzRm9jdXNzZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgcnVuKCkge1xuICAgIGF3YWl0IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLmVuc3VyZUNvbm5lY3Rpb25zKGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHRoaXMucnVuVGVzdHMoe1xuICAgICAgICBhZnRlckVhY2hlczogW10sXG4gICAgICAgIGJlZm9yZUVhY2hlczogW10sXG4gICAgICAgIHRlc3RzLFxuICAgICAgICBkZXNjcmlwdGlvbnM6IFtdLFxuICAgICAgICBpbmRlbnRMZXZlbDogMFxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY2xlYW51cCBob29rcyBmaW5pc2guXG4gICAqL1xuICBhc3luYyBydW5BZnRlckFsbHNGb3JBY3RpdmVTY29wZXMoKSB7XG4gICAgY29uc3Qgc2NvcGVzID0gWy4uLnRoaXMuX2FjdGl2ZUFmdGVyQWxsU2NvcGVzXS5yZXZlcnNlKClcblxuICAgIGZvciAoY29uc3Qgc2NvcGUgb2Ygc2NvcGVzKSB7XG4gICAgICBhd2FpdCB0aGlzLnJ1bkFmdGVyQWxsc0ZvclNjb3BlKHNjb3BlKVxuICAgIH1cblxuICAgIHRoaXMuX2FjdGl2ZUFmdGVyQWxsU2NvcGVzID0gW11cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1Rlc3RzQXJndW1lbnR9IHRlc3RzIC0gVGVzdHMuXG4gICAqIEByZXR1cm5zIHt7YW55VGVzdHNGb2N1c3NlZDogYm9vbGVhbn19IC0gV2hldGhlciBhbnkgdGVzdHMgaW4gdGhlIHRyZWUgYXJlIGZvY3VzZWQuXG4gICAqL1xuICBhbmFseXplVGVzdHModGVzdHMpIHtcbiAgICBsZXQgYW55VGVzdHNGb2N1c3NlZEZvdW5kID0gZmFsc2VcblxuICAgIGZvciAoY29uc3QgdGVzdERlc2NyaXB0aW9uIGluIHRlc3RzLnRlc3RzKSB7XG4gICAgICBjb25zdCB0ZXN0RGF0YSA9IHRlc3RzLnRlc3RzW3Rlc3REZXNjcmlwdGlvbl1cbiAgICAgIGNvbnN0IHRlc3RBcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgdGVzdERhdGEuYXJncylcblxuICAgICAgdGhpcy5fdGVzdHNDb3VudCsrXG5cbiAgICAgIGlmICh0ZXN0QXJncy5mb2N1cykge1xuICAgICAgICBhbnlUZXN0c0ZvY3Vzc2VkRm91bmQgPSB0cnVlXG4gICAgICAgIHRoaXMuYW55VGVzdHNGb2N1c3NlZCA9IHRydWVcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHN1YkRlc2NyaXB0aW9uIGluIHRlc3RzLnN1YnMpIHtcbiAgICAgIGNvbnN0IHN1YlRlc3QgPSB0ZXN0cy5zdWJzW3N1YkRlc2NyaXB0aW9uXVxuICAgICAgY29uc3Qge2FueVRlc3RzRm9jdXNzZWR9ID0gdGhpcy5hbmFseXplVGVzdHMoc3ViVGVzdClcblxuICAgICAgaWYgKGFueVRlc3RzRm9jdXNzZWQpIHtcbiAgICAgICAgYW55VGVzdHNGb2N1c3NlZEZvdW5kID0gdHJ1ZVxuICAgICAgfVxuXG4gICAgICBzdWJUZXN0LmFueVRlc3RzRm9jdXNzZWQgPSBhbnlUZXN0c0ZvY3Vzc2VkXG4gICAgfVxuXG4gICAgcmV0dXJuIHthbnlUZXN0c0ZvY3Vzc2VkOiBhbnlUZXN0c0ZvY3Vzc2VkRm91bmR9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtBcnJheTxBZnRlckJlZm9yZUVhY2hDYWxsYmFja09iamVjdFR5cGU+fSBhcmdzLmFmdGVyRWFjaGVzIC0gQWZ0ZXIgZWFjaGVzLlxuICAgKiBAcGFyYW0ge0FycmF5PEFmdGVyQmVmb3JlRWFjaENhbGxiYWNrT2JqZWN0VHlwZT59IGFyZ3MuYmVmb3JlRWFjaGVzIC0gQmVmb3JlIGVhY2hlcy5cbiAgICogQHBhcmFtIHtUZXN0c0FyZ3VtZW50fSBhcmdzLnRlc3RzIC0gVGVzdHMuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGFyZ3MuZGVzY3JpcHRpb25zIC0gRGVzY3JpcHRpb25zLlxuICAgKiBAcGFyYW0ge251bWJlcn0gYXJncy5pbmRlbnRMZXZlbCAtIEluZGVudCBsZXZlbC5cbiAgICogQHBhcmFtIHtib29sZWFufSBbYXJncy5saW5lTWF0Y2hlZEluU2NvcGVdIC0gV2hldGhlciBsaW5lIG1hdGNoZWQgaW4gc2NvcGUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBydW5UZXN0cyh7YWZ0ZXJFYWNoZXMsIGJlZm9yZUVhY2hlcywgdGVzdHMsIGRlc2NyaXB0aW9ucywgaW5kZW50TGV2ZWwsIGxpbmVNYXRjaGVkSW5TY29wZSA9IGZhbHNlfSkge1xuICAgIGNvbnN0IGxlZnRQYWRkaW5nID0gXCIgXCIucmVwZWF0KGluZGVudExldmVsICogMilcbiAgICBjb25zdCBuZXdBZnRlckVhY2hlcyA9IFsuLi5hZnRlckVhY2hlcywgLi4udGVzdHMuYWZ0ZXJFYWNoZXNdXG4gICAgY29uc3QgbmV3QmVmb3JlRWFjaGVzID0gWy4uLmJlZm9yZUVhY2hlcywgLi4udGVzdHMuYmVmb3JlRWFjaGVzXVxuICAgIGNvbnN0IHNjb3BlTGluZU1hdGNoID0gbGluZU1hdGNoZWRJblNjb3BlIHx8IHRoaXMubWF0Y2hlc0xpbmVGaWx0ZXIodGVzdHMpXG4gICAgY29uc3Qgc2hvdWxkUnVuQW55VGVzdHMgPSB0aGlzLmhhc1J1bm5hYmxlVGVzdHModGVzdHMsIGRlc2NyaXB0aW9ucywgc2NvcGVMaW5lTWF0Y2gpXG5cbiAgICBpZiAoIXNob3VsZFJ1bkFueVRlc3RzKSByZXR1cm5cblxuICAgIC8qKiBAdHlwZSB7e3Rlc3RzOiBUZXN0c0FyZ3VtZW50LCBhZnRlckFsbHNSdW46IGJvb2xlYW59fSAqL1xuICAgIGNvbnN0IHNjb3BlRW50cnkgPSB7dGVzdHMsIGFmdGVyQWxsc1J1bjogZmFsc2V9XG4gICAgdGhpcy5fYWN0aXZlQWZ0ZXJBbGxTY29wZXMucHVzaChzY29wZUVudHJ5KVxuXG4gICAgdHJ5IHtcbiAgICAgIGZvciAoY29uc3QgYmVmb3JlQWxsRGF0YSBvZiB0ZXN0cy5iZWZvcmVBbGxzIHx8IFtdKSB7XG4gICAgICAgIGF3YWl0IGJlZm9yZUFsbERhdGEuY2FsbGJhY2soe2NvbmZpZ3VyYXRpb246IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpfSlcbiAgICAgIH1cblxuICAgICAgZm9yIChjb25zdCB0ZXN0RGVzY3JpcHRpb24gaW4gdGVzdHMudGVzdHMpIHtcbiAgICAgICAgY29uc3QgdGVzdERhdGEgPSB0ZXN0cy50ZXN0c1t0ZXN0RGVzY3JpcHRpb25dXG4gICAgICAgIGNvbnN0IHRlc3RBcmdzID0gLyoqIEB0eXBlIHtUZXN0QXJnc30gKi8gKE9iamVjdC5hc3NpZ24oe30sIHRlc3REYXRhLmFyZ3MpKVxuICAgICAgICBjb25zdCBpbmNsdWRlQnlMaW5lID0gc2NvcGVMaW5lTWF0Y2ggfHwgdGhpcy5tYXRjaGVzTGluZUZpbHRlcih0ZXN0RGF0YSlcblxuICAgICAgICBpZiAodGhpcy5fb25seUZvY3Vzc2VkICYmICF0ZXN0QXJncy5mb2N1cykgY29udGludWVcbiAgICAgICAgaWYgKHRoaXMuc2hvdWxkU2tpcFRlc3QodGVzdEFyZ3MsIHRlc3REYXRhLCB0ZXN0RGVzY3JpcHRpb24sIGRlc2NyaXB0aW9ucywgaW5jbHVkZUJ5TGluZSkpIGNvbnRpbnVlXG5cbiAgICAgICAgaWYgKHRlc3RBcmdzLnR5cGUgPT0gXCJtb2RlbFwiIHx8IHRlc3RBcmdzLnR5cGUgPT0gXCJyZXF1ZXN0XCIpIHtcbiAgICAgICAgICB0ZXN0QXJncy5hcHBsaWNhdGlvbiA9IGF3YWl0IHRoaXMuYXBwbGljYXRpb24oKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRlc3RBcmdzLnR5cGUgPT0gXCJyZXF1ZXN0XCIpIHtcbiAgICAgICAgICB0ZXN0QXJncy5jbGllbnQgPSBhd2FpdCB0aGlzLnJlcXVlc3RDbGllbnQoKVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc29sZS5sb2coYCR7bGVmdFBhZGRpbmd9aXQgJHt0ZXN0RGVzY3JpcHRpb259YClcbiAgICAgICAgY29uc3Qgc3RvcENvbnNvbGVDYXB0dXJlID0gdGhpcy5zdGFydENvbnNvbGVDYXB0dXJlKClcblxuICAgICAgICBjb25zdCByZXRyeUNvdW50ID0gdHlwZW9mIHRlc3RBcmdzLnJldHJ5ID09PSBcIm51bWJlclwiICYmIE51bWJlci5pc0Zpbml0ZSh0ZXN0QXJncy5yZXRyeSlcbiAgICAgICAgICA/IE1hdGgubWF4KDAsIE1hdGguZmxvb3IodGVzdEFyZ3MucmV0cnkpKVxuICAgICAgICAgIDogMFxuICAgICAgICBjb25zdCBjb25maWdUaW1lb3V0U2Vjb25kcyA9IHR5cGVvZiB0ZXN0Q29uZmlnLmRlZmF1bHRUaW1lb3V0U2Vjb25kcyA9PT0gXCJudW1iZXJcIiA/IHRlc3RDb25maWcuZGVmYXVsdFRpbWVvdXRTZWNvbmRzIDogdW5kZWZpbmVkXG4gICAgICAgIGNvbnN0IHRpbWVvdXRTZWNvbmRzID0gdHlwZW9mIHRlc3RBcmdzLnRpbWVvdXRTZWNvbmRzID09PSBcIm51bWJlclwiID8gdGVzdEFyZ3MudGltZW91dFNlY29uZHMgOiBjb25maWdUaW1lb3V0U2Vjb25kc1xuICAgICAgICBjb25zdCB1c2VUaW1lb3V0ID0gdHlwZW9mIHRpbWVvdXRTZWNvbmRzID09PSBcIm51bWJlclwiICYmIE51bWJlci5pc0Zpbml0ZSh0aW1lb3V0U2Vjb25kcykgJiYgdGltZW91dFNlY29uZHMgPiAwXG4gICAgICAgIGNvbnN0IHRpbWVvdXRNcyA9IHVzZVRpbWVvdXQgPyB0aW1lb3V0U2Vjb25kcyAqIDEwMDAgOiB1bmRlZmluZWRcbiAgICAgICAgbGV0IHJldHJpZXNVc2VkID0gMFxuICAgICAgICBsZXQgYXR0ZW1wdE51bWJlciA9IDFcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICBsZXQgc2hvdWxkUmV0cnkgPSBmYWxzZVxuICAgICAgICAgICAgLyoqIEB0eXBlIHt1bmtub3dufSAqL1xuICAgICAgICAgICAgbGV0IGZhaWxlZEVycm9yXG4gICAgICAgICAgICAvKiogQHR5cGUge3Vua25vd259ICovXG4gICAgICAgICAgICBsZXQgbGFzdEVycm9yXG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMucnVuV2l0aER1bW15SWZOZWVkZWQodGVzdEFyZ3MsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgY2xlYXJEZWxpdmVyaWVzKClcbiAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYmVmb3JlRWFjaERhdGEgb2YgbmV3QmVmb3JlRWFjaGVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGJlZm9yZUVhY2hEYXRhLmNhbGxiYWNrKHtjb25maWd1cmF0aW9uOiB0aGlzLmdldENvbmZpZ3VyYXRpb24oKSwgdGVzdEFyZ3MsIHRlc3REYXRhfSlcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgY29uc3QgdGVzdFByb21pc2UgPSB0ZXN0RGF0YS5mdW5jdGlvbih0ZXN0QXJncylcblxuICAgICAgICAgICAgICAgICAgaWYgKHVzZVRpbWVvdXQgJiYgdGltZW91dE1zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgcnVuV2l0aFRpbWVvdXQodGVzdFByb21pc2UsIHRpbWVvdXRNcywgdGVzdERlc2NyaXB0aW9uKVxuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGVzdFByb21pc2VcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIHRoaXMuX3N1Y2Nlc3NmdWxUZXN0cysrXG4gICAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYWZ0ZXJFYWNoRGF0YSBvZiBuZXdBZnRlckVhY2hlcykge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBhZnRlckVhY2hEYXRhLmNhbGxiYWNrKHtjb25maWd1cmF0aW9uOiB0aGlzLmdldENvbmZpZ3VyYXRpb24oKSwgdGVzdEFyZ3MsIHRlc3REYXRhfSlcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICBsYXN0RXJyb3IgPSBlcnJvclxuICAgICAgICAgICAgICBpZiAocmV0cmllc1VzZWQgPCByZXRyeUNvdW50KSB7XG4gICAgICAgICAgICAgICAgcmV0cmllc1VzZWQrK1xuICAgICAgICAgICAgICAgIHNob3VsZFJldHJ5ID0gdHJ1ZVxuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihwaWNvY29sb3JzLnJlZChgJHtsZWZ0UGFkZGluZ30gIFJldHJ5aW5nICgke3JldHJpZXNVc2VkfS8ke3JldHJ5Q291bnR9KSBhZnRlciBlcnJvcjogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcil9YCkpXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0RXZlbnQoXCJ0ZXN0UmV0cnlpbmdcIiwge1xuICAgICAgICAgICAgICAgICAgY29uZmlndXJhdGlvbjogdGhpcy5nZXRDb25maWd1cmF0aW9uKCksXG4gICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbnMsXG4gICAgICAgICAgICAgICAgICBlcnJvcixcbiAgICAgICAgICAgICAgICAgIG5leHRBdHRlbXB0OiBhdHRlbXB0TnVtYmVyICsgMSxcbiAgICAgICAgICAgICAgICAgIHJldHJpZXNVc2VkLFxuICAgICAgICAgICAgICAgICAgcmV0cnlDb3VudCxcbiAgICAgICAgICAgICAgICAgIHRlc3RBcmdzLFxuICAgICAgICAgICAgICAgICAgdGVzdERhdGEsXG4gICAgICAgICAgICAgICAgICB0ZXN0RGVzY3JpcHRpb24sXG4gICAgICAgICAgICAgICAgICB0ZXN0UnVubmVyOiB0aGlzXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBmYWlsZWRFcnJvciA9IGVycm9yXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGF0dGVtcHROdW1iZXIgPiAxKSB7XG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdEV2ZW50KFwidGVzdFJldHJpZWRcIiwge1xuICAgICAgICAgICAgICAgIGNvbmZpZ3VyYXRpb246IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9ucyxcbiAgICAgICAgICAgICAgICBlcnJvcjogbGFzdEVycm9yLFxuICAgICAgICAgICAgICAgIGF0dGVtcHROdW1iZXIsXG4gICAgICAgICAgICAgICAgcmV0cmllc1VzZWQsXG4gICAgICAgICAgICAgICAgcmV0cnlDb3VudCxcbiAgICAgICAgICAgICAgICB0ZXN0QXJncyxcbiAgICAgICAgICAgICAgICB0ZXN0RGF0YSxcbiAgICAgICAgICAgICAgICB0ZXN0RGVzY3JpcHRpb24sXG4gICAgICAgICAgICAgICAgdGVzdFJ1bm5lcjogdGhpc1xuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBhdHRlbXB0TnVtYmVyKytcblxuICAgICAgICAgICAgaWYgKHNob3VsZFJldHJ5KSBjb250aW51ZVxuXG4gICAgICAgICAgICBpZiAoZmFpbGVkRXJyb3IpIHtcbiAgICAgICAgICAgICAgaWYgKGZhaWxlZEVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKHBpY29jb2xvcnMucmVkKGAke2xlZnRQYWRkaW5nfSAgVGVzdCBmYWlsZWQ6ICR7ZmFpbGVkRXJyb3IubWVzc2FnZX1gKSlcbiAgICAgICAgICAgICAgICBhZGRUcmFja2VkU3RhY2tUb0Vycm9yKGZhaWxlZEVycm9yKVxuXG4gICAgICAgICAgICAgICAgY29uc3QgYmFja3RyYWNlQ2xlYW5lciA9IG5ldyBCYWNrdHJhY2VDbGVhbmVyKGZhaWxlZEVycm9yKVxuICAgICAgICAgICAgICAgIGNvbnN0IGNsZWFuZWRTdGFjayA9IGJhY2t0cmFjZUNsZWFuZXIuZ2V0Q2xlYW5lZFN0YWNrKClcbiAgICAgICAgICAgICAgICBjb25zdCBzdGFja0xpbmVzID0gY2xlYW5lZFN0YWNrPy5zcGxpdChcIlxcblwiKVxuXG4gICAgICAgICAgICAgICAgaWYgKHN0YWNrTGluZXMpIHtcbiAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgc3RhY2tMaW5lIG9mIHN0YWNrTGluZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihwaWNvY29sb3JzLnJlZChgJHtsZWZ0UGFkZGluZ30gICR7c3RhY2tMaW5lfWApKVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKHBpY29jb2xvcnMucmVkKGAke2xlZnRQYWRkaW5nfSAgVGVzdCBmYWlsZWQgd2l0aCBhICR7dHlwZW9mIGZhaWxlZEVycm9yfTogJHtTdHJpbmcoZmFpbGVkRXJyb3IpfWApKVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgdGhpcy5fZmFpbGVkVGVzdHMrK1xuICAgICAgICAgICAgICB0aGlzLl9mYWlsZWRUZXN0RGV0YWlscy5wdXNoKHtcbiAgICAgICAgICAgICAgICBmdWxsRGVzY3JpcHRpb246IHRoaXMuYnVpbGRGdWxsRGVzY3JpcHRpb24oZGVzY3JpcHRpb25zLCB0ZXN0RGVzY3JpcHRpb24pLFxuICAgICAgICAgICAgICAgIGZpbGVQYXRoOiB0ZXN0RGF0YS5maWxlUGF0aCxcbiAgICAgICAgICAgICAgICBsaW5lOiB0ZXN0RGF0YS5saW5lLFxuICAgICAgICAgICAgICAgIGVycm9yOiBmYWlsZWRFcnJvcixcbiAgICAgICAgICAgICAgICBjb25zb2xlT3V0cHV0OiBzdG9wQ29uc29sZUNhcHR1cmUoKVxuICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdEV2ZW50KFwidGVzdEZhaWxlZFwiLCB7XG4gICAgICAgICAgICAgICAgY29uZmlndXJhdGlvbjogdGhpcy5nZXRDb25maWd1cmF0aW9uKCksXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICAgICAgICAgIGVycm9yOiBmYWlsZWRFcnJvcixcbiAgICAgICAgICAgICAgICB0ZXN0QXJncyxcbiAgICAgICAgICAgICAgICB0ZXN0RGF0YSxcbiAgICAgICAgICAgICAgICB0ZXN0RGVzY3JpcHRpb24sXG4gICAgICAgICAgICAgICAgdGVzdFJ1bm5lcjogdGhpc1xuICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgIHRoaXMucHJpbnRSZXJ1bkNvbW1hbmQoe2Rlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uLCB0ZXN0RGF0YSwgbGVmdFBhZGRpbmd9KVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIH1cbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBzdG9wQ29uc29sZUNhcHR1cmUoKVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3Qgc3ViRGVzY3JpcHRpb24gaW4gdGVzdHMuc3Vicykge1xuICAgICAgICBjb25zdCBzdWJUZXN0ID0gdGVzdHMuc3Vic1tzdWJEZXNjcmlwdGlvbl1cbiAgICAgICAgY29uc3QgbmV3RGVjcmlwdGlvbnMgPSBkZXNjcmlwdGlvbnMuY29uY2F0KFtzdWJEZXNjcmlwdGlvbl0pXG4gICAgICAgIGNvbnN0IGNoaWxkU2NvcGVMaW5lTWF0Y2ggPSBzY29wZUxpbmVNYXRjaCB8fCB0aGlzLm1hdGNoZXNMaW5lRmlsdGVyKHN1YlRlc3QpXG5cbiAgICAgICAgaWYgKCF0aGlzLl9vbmx5Rm9jdXNzZWQgfHwgc3ViVGVzdC5hbnlUZXN0c0ZvY3Vzc2VkKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYCR7bGVmdFBhZGRpbmd9JHtzdWJEZXNjcmlwdGlvbn1gKVxuICAgICAgICAgIGF3YWl0IHRoaXMucnVuVGVzdHMoe1xuICAgICAgICAgICAgYWZ0ZXJFYWNoZXM6IG5ld0FmdGVyRWFjaGVzLFxuICAgICAgICAgICAgYmVmb3JlRWFjaGVzOiBuZXdCZWZvcmVFYWNoZXMsXG4gICAgICAgICAgICB0ZXN0czogc3ViVGVzdCxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uczogbmV3RGVjcmlwdGlvbnMsXG4gICAgICAgICAgICBpbmRlbnRMZXZlbDogaW5kZW50TGV2ZWwgKyAxLFxuICAgICAgICAgICAgbGluZU1hdGNoZWRJblNjb3BlOiBjaGlsZFNjb3BlTGluZU1hdGNoXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCB0aGlzLnJ1bkFmdGVyQWxsc0ZvclNjb3BlKHNjb3BlRW50cnkpXG4gICAgICBjb25zdCBzY29wZUluZGV4ID0gdGhpcy5fYWN0aXZlQWZ0ZXJBbGxTY29wZXMuaW5kZXhPZihzY29wZUVudHJ5KVxuXG4gICAgICBpZiAoc2NvcGVJbmRleCA+PSAwKSB7XG4gICAgICAgIHRoaXMuX2FjdGl2ZUFmdGVyQWxsU2NvcGVzLnNwbGljZShzY29wZUluZGV4LCAxKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3t0ZXN0czogVGVzdHNBcmd1bWVudCwgYWZ0ZXJBbGxzUnVuOiBib29sZWFufX0gc2NvcGVFbnRyeSAtIFNjb3BlIGVudHJ5LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIHNjb3BlIGNsZWFudXAgZmluaXNoZXMuXG4gICAqL1xuICBhc3luYyBydW5BZnRlckFsbHNGb3JTY29wZShzY29wZUVudHJ5KSB7XG4gICAgaWYgKHNjb3BlRW50cnkuYWZ0ZXJBbGxzUnVuKSByZXR1cm5cblxuICAgIHNjb3BlRW50cnkuYWZ0ZXJBbGxzUnVuID0gdHJ1ZVxuXG4gICAgZm9yIChjb25zdCBhZnRlckFsbERhdGEgb2Ygc2NvcGVFbnRyeS50ZXN0cy5hZnRlckFsbHMgfHwgW10pIHtcbiAgICAgIGF3YWl0IGFmdGVyQWxsRGF0YS5jYWxsYmFjayh7Y29uZmlndXJhdGlvbjogdGhpcy5nZXRDb25maWd1cmF0aW9uKCl9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lIC0gRXZlbnQgbmFtZS5cbiAgICogQHBhcmFtIHtvYmplY3R9IHBheWxvYWQgLSBFdmVudCBwYXlsb2FkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGFsbCBsaXN0ZW5lcnMgY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBlbWl0RXZlbnQoZXZlbnROYW1lLCBwYXlsb2FkKSB7XG4gICAgY29uc3QgbGlzdGVuZXJzID0gdGVzdEV2ZW50cy5saXN0ZW5lcnMoZXZlbnROYW1lKVxuXG4gICAgZm9yIChjb25zdCBsaXN0ZW5lciBvZiBsaXN0ZW5lcnMpIHtcbiAgICAgIGF3YWl0IGxpc3RlbmVyKHBheWxvYWQpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGFyZ3MuZGVzY3JpcHRpb25zIC0gRGVzY3JpcHRpb24gc3RhY2suXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLnRlc3REZXNjcmlwdGlvbiAtIFRlc3QgZGVzY3JpcHRpb24uXG4gICAqIEBwYXJhbSB7VGVzdERhdGF9IGFyZ3MudGVzdERhdGEgLSBUZXN0IGRhdGEuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmxlZnRQYWRkaW5nIC0gTGVmdCBwYWRkaW5nLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBwcmludFJlcnVuQ29tbWFuZCh7ZGVzY3JpcHRpb25zLCB0ZXN0RGVzY3JpcHRpb24sIHRlc3REYXRhLCBsZWZ0UGFkZGluZ30pIHtcbiAgICBjb25zdCByZXJ1biA9IHRoaXMuYnVpbGRSZXJ1bkNvbW1hbmQoe2Rlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uLCB0ZXN0RGF0YX0pXG5cbiAgICBpZiAocmVydW4pIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoYCR7bGVmdFBhZGRpbmd9ICBSZS1ydW46ICR7cmVydW59YClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gYXJncy5kZXNjcmlwdGlvbnMgLSBEZXNjcmlwdGlvbiBzdGFjay5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MudGVzdERlc2NyaXB0aW9uIC0gVGVzdCBkZXNjcmlwdGlvbi5cbiAgICogQHBhcmFtIHtUZXN0RGF0YX0gYXJncy50ZXN0RGF0YSAtIFRlc3QgZGF0YS5cbiAgICogQHJldHVybnMge3N0cmluZyB8IHVuZGVmaW5lZH0gLSBSZXJ1biBjb21tYW5kLlxuICAgKi9cbiAgYnVpbGRSZXJ1bkNvbW1hbmQoe2Rlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uLCB0ZXN0RGF0YX0pIHtcbiAgICBjb25zdCBiYXNlQ29tbWFuZCA9IFwibnB4IHZlbG9jaW91cyB0ZXN0XCJcbiAgICBjb25zdCBmaWxlUGF0aCA9IHRlc3REYXRhLmZpbGVQYXRoXG4gICAgY29uc3QgbGluZSA9IHRlc3REYXRhLmxpbmVcblxuICAgIGlmIChmaWxlUGF0aCAmJiBsaW5lKSB7XG4gICAgICBjb25zdCByZWxhdGl2ZVBhdGggPSBwYXRoLnJlbGF0aXZlKHByb2Nlc3MuY3dkKCksIGZpbGVQYXRoKVxuICAgICAgcmV0dXJuIGAke2Jhc2VDb21tYW5kfSAke3JlbGF0aXZlUGF0aH06JHtsaW5lfWBcbiAgICB9XG5cbiAgICBjb25zdCBmdWxsRGVzY3JpcHRpb24gPSB0aGlzLmJ1aWxkRnVsbERlc2NyaXB0aW9uKGRlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uKVxuXG4gICAgaWYgKGZ1bGxEZXNjcmlwdGlvbikge1xuICAgICAgcmV0dXJuIGAke2Jhc2VDb21tYW5kfSAtLWV4YW1wbGUgJHtKU09OLnN0cmluZ2lmeShmdWxsRGVzY3JpcHRpb24pfWBcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMgeygpID0+IHN0cmluZ30gLSBTdG9wcyB0aGUgY2FwdHVyZSBhbmQgcmV0dXJucyBjYXB0dXJlZCB0ZXh0LlxuICAgKi9cbiAgc3RhcnRDb25zb2xlQ2FwdHVyZSgpIHtcbiAgICBjb25zdCBsaW5lcyA9IFtdXG4gICAgLyoqIEB0eXBlIHtSZWNvcmQ8Q29uc29sZU1ldGhvZE5hbWUsICguLi5hcmdzOiB1bmtub3duW10pID0+IHZvaWQ+fSAqL1xuICAgIGNvbnN0IGNvbnNvbGVPYmplY3QgPSAvKiogQHR5cGUge1JlY29yZDxDb25zb2xlTWV0aG9kTmFtZSwgKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gdm9pZD59ICovIChjb25zb2xlKVxuICAgIC8qKiBAdHlwZSB7UmVjb3JkPENvbnNvbGVNZXRob2ROYW1lLCAoLi4uYXJnczogdW5rbm93bltdKSA9PiB2b2lkPn0gKi9cbiAgICBjb25zdCBvcmlnaW5hbENvbnNvbGVNZXRob2RzID0ge1xuICAgICAgZGVidWc6IGNvbnNvbGVPYmplY3QuZGVidWcuYmluZChjb25zb2xlKSxcbiAgICAgIGVycm9yOiBjb25zb2xlT2JqZWN0LmVycm9yLmJpbmQoY29uc29sZSksXG4gICAgICBpbmZvOiBjb25zb2xlT2JqZWN0LmluZm8uYmluZChjb25zb2xlKSxcbiAgICAgIGxvZzogY29uc29sZU9iamVjdC5sb2cuYmluZChjb25zb2xlKSxcbiAgICAgIHdhcm46IGNvbnNvbGVPYmplY3Qud2Fybi5iaW5kKGNvbnNvbGUpXG4gICAgfVxuICAgIGxldCBzdG9wcGVkID0gZmFsc2VcbiAgICBsZXQgb3V0cHV0VGV4dCA9IFwiXCJcblxuICAgIGZvciAoY29uc3QgbWV0aG9kTmFtZSBvZiBDQVBUVVJFRF9DT05TT0xFX01FVEhPRFMpIHtcbiAgICAgIGNvbnNvbGVPYmplY3RbbWV0aG9kTmFtZV0gPSAoLi4uYXJncykgPT4ge1xuICAgICAgICBsaW5lcy5wdXNoKGBbJHtuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCl9XSBbJHttZXRob2ROYW1lfV0gJHtmb3JtYXQoLi4uYXJncyl9YClcbiAgICAgICAgb3JpZ2luYWxDb25zb2xlTWV0aG9kc1ttZXRob2ROYW1lXSguLi5hcmdzKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBpZiAoIXN0b3BwZWQpIHtcbiAgICAgICAgc3RvcHBlZCA9IHRydWVcblxuICAgICAgICBmb3IgKGNvbnN0IG1ldGhvZE5hbWUgb2YgQ0FQVFVSRURfQ09OU09MRV9NRVRIT0RTKSB7XG4gICAgICAgICAgY29uc29sZU9iamVjdFttZXRob2ROYW1lXSA9IG9yaWdpbmFsQ29uc29sZU1ldGhvZHNbbWV0aG9kTmFtZV1cbiAgICAgICAgfVxuXG4gICAgICAgIG91dHB1dFRleHQgPSBsaW5lcy5qb2luKFwiXFxuXCIpXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBvdXRwdXRUZXh0XG4gICAgfVxuICB9XG59XG4iXX0=
|