velocious 1.0.618 → 1.0.620
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 +4 -2
- package/build/configuration.js +1 -1
- package/build/database/pool/async-tracked-multi-connection.js +25 -5
- package/build/database/pool/base.js +20 -10
- package/build/environment-handlers/base.js +9 -1
- package/build/environment-handlers/node.js +22 -4
- package/build/src/configuration.js +2 -2
- package/build/src/database/pool/async-tracked-multi-connection.d.ts +19 -1
- package/build/src/database/pool/async-tracked-multi-connection.d.ts.map +1 -1
- package/build/src/database/pool/async-tracked-multi-connection.js +26 -4
- package/build/src/database/pool/base.d.ts +12 -1
- package/build/src/database/pool/base.d.ts.map +1 -1
- package/build/src/database/pool/base.js +20 -11
- package/build/src/environment-handlers/base.d.ts +9 -1
- package/build/src/environment-handlers/base.d.ts.map +1 -1
- package/build/src/environment-handlers/base.js +9 -2
- package/build/src/environment-handlers/node.d.ts +10 -2
- package/build/src/environment-handlers/node.d.ts.map +1 -1
- package/build/src/environment-handlers/node.js +24 -5
- package/build/src/testing/shared-transaction-broker-client.d.ts +4 -2
- package/build/src/testing/shared-transaction-broker-client.d.ts.map +1 -1
- package/build/src/testing/shared-transaction-broker-client.js +5 -3
- package/build/src/testing/shared-transaction-broker.d.ts +21 -0
- package/build/src/testing/shared-transaction-broker.d.ts.map +1 -1
- package/build/src/testing/shared-transaction-broker.js +61 -18
- package/build/src/testing/shared-transaction-connection-coordinator.d.ts +2 -0
- package/build/src/testing/shared-transaction-connection-coordinator.d.ts.map +1 -1
- package/build/src/testing/shared-transaction-connection-coordinator.js +79 -12
- package/build/src/testing/shared-transaction-proxy-driver.d.ts +22 -3
- package/build/src/testing/shared-transaction-proxy-driver.d.ts.map +1 -1
- package/build/src/testing/shared-transaction-proxy-driver.js +51 -14
- package/build/src/testing/test-transaction-session.d.ts +129 -0
- package/build/src/testing/test-transaction-session.d.ts.map +1 -0
- package/build/src/testing/test-transaction-session.js +255 -0
- package/build/src/testing/test.d.ts +1 -1
- package/build/src/testing/test.d.ts.map +1 -1
- package/build/src/testing/test.js +2 -2
- package/build/testing/shared-transaction-broker-client.js +4 -2
- package/build/testing/shared-transaction-broker.js +58 -16
- package/build/testing/shared-transaction-connection-coordinator.js +83 -10
- package/build/testing/shared-transaction-proxy-driver.js +52 -13
- package/build/testing/test-transaction-session.js +240 -0
- package/build/testing/test.js +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
- package/src/configuration.js +1 -1
- package/src/database/pool/async-tracked-multi-connection.js +25 -5
- package/src/database/pool/base.js +20 -10
- package/src/environment-handlers/base.js +9 -1
- package/src/environment-handlers/node.js +22 -4
- package/src/testing/shared-transaction-broker-client.js +4 -2
- package/src/testing/shared-transaction-broker.js +58 -16
- package/src/testing/shared-transaction-connection-coordinator.js +83 -10
- package/src/testing/shared-transaction-proxy-driver.js +52 -13
- package/src/testing/test-transaction-session.js +240 -0
- package/src/testing/test.js +1 -1
- package/build/src/testing/wait-for-event.d.ts +0 -46
- package/build/src/testing/wait-for-event.d.ts.map +0 -1
- package/build/src/testing/wait-for-event.js +0 -64
- package/build/testing/wait-for-event.js +0 -72
- package/src/testing/wait-for-event.js +0 -72
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import SharedTransactionBroker from "./shared-transaction-broker.js";
|
|
3
|
+
import { runWithSharedTransactionBrokerConfig, sharedTransactionBrokerContextMatches } from "./shared-transaction-proxy-driver.js";
|
|
4
|
+
/** @typedef {{connection: import("../database/drivers/base.js").default, databaseIdentifier: string, release: () => Promise<void>, reuseKey: string}} Enrollment */
|
|
5
|
+
/**
|
|
6
|
+
* Backend-owned, capability-scoped transaction set for long-lived test services.
|
|
7
|
+
* Join coordinates are intentionally obtainable only as a live control message.
|
|
8
|
+
*/
|
|
9
|
+
export default class TestTransactionSession {
|
|
10
|
+
/**
|
|
11
|
+
* Creates an unstarted transaction session.
|
|
12
|
+
* @param {import("../configuration.js").default} [configuration] - Backend configuration owning enrolled pools.
|
|
13
|
+
*/
|
|
14
|
+
constructor(configuration) {
|
|
15
|
+
this.configuration = configuration;
|
|
16
|
+
/** @type {SharedTransactionBroker | undefined} */
|
|
17
|
+
this.broker = undefined;
|
|
18
|
+
/** @type {Map<string, Enrollment>} */
|
|
19
|
+
this.enrollments = new Map();
|
|
20
|
+
/** @type {Map<string, {pool: import("../database/pool/base.js").default, registration: import("../database/pool/base.js").TestSharedConnectionRegistration}>} */
|
|
21
|
+
this.sharedConnectionRegistrations = new Map();
|
|
22
|
+
/** @type {Promise<void> | undefined} */
|
|
23
|
+
this.cleanupPromise = undefined;
|
|
24
|
+
/** @type {Promise<void> | undefined} */
|
|
25
|
+
this.rollbackPromise = undefined;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Begins a test transaction session.
|
|
29
|
+
* @param {{configuration?: import("../configuration.js").default}} [args] - Backend owner.
|
|
30
|
+
* @returns {Promise<TestTransactionSession>} - Begun session.
|
|
31
|
+
*/
|
|
32
|
+
static async begin({ configuration } = {}) {
|
|
33
|
+
const session = new TestTransactionSession(configuration);
|
|
34
|
+
session.broker = await SharedTransactionBroker.start({ connections: {} });
|
|
35
|
+
return session;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Joins one request/job callback from a live backend control message.
|
|
39
|
+
* @template T
|
|
40
|
+
* @param {{address: string, capability: string}} message - Ephemeral coordinates received over live IPC.
|
|
41
|
+
* @param {() => T} callback - Backend request or worker work.
|
|
42
|
+
* @returns {T} - Callback result.
|
|
43
|
+
*/
|
|
44
|
+
static join(message, callback) {
|
|
45
|
+
return runWithSharedTransactionBrokerConfig({ ...message, allowDynamicIdentities: true, databaseIdentifiers: [], expected: true }, callback);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Lazily adds an exact physical connection to the common rollback set.
|
|
49
|
+
* @param {Enrollment} enrollment - Checked-out physical connection and owner release hook.
|
|
50
|
+
*/
|
|
51
|
+
async enroll(enrollment) {
|
|
52
|
+
const broker = this.requiredBroker();
|
|
53
|
+
const identity = `${enrollment.databaseIdentifier}\0${enrollment.reuseKey}`;
|
|
54
|
+
const existing = this.enrollments.get(identity);
|
|
55
|
+
if (existing) {
|
|
56
|
+
if (existing.connection !== enrollment.connection)
|
|
57
|
+
await enrollment.release();
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
await enrollment.connection.startTransaction();
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
/** @type {Error | undefined} */
|
|
65
|
+
let releaseFailure;
|
|
66
|
+
try {
|
|
67
|
+
await enrollment.release();
|
|
68
|
+
}
|
|
69
|
+
catch (releaseError) {
|
|
70
|
+
releaseFailure = this.normalizeError(releaseError);
|
|
71
|
+
}
|
|
72
|
+
if (releaseFailure) {
|
|
73
|
+
throw new AggregateError([this.normalizeError(error), releaseFailure], "Test transaction enrollment start and release failed", { cause: error });
|
|
74
|
+
}
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
broker.enrollConnection(enrollment);
|
|
79
|
+
this.enrollments.set(identity, enrollment);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
await this.rollbackAndRelease(enrollment);
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Lazily checks out and enrolls the physical database selected by a tenant descriptor.
|
|
88
|
+
* @param {{databaseIdentifier: string, tenant?: object}} args - Logical and tenant identity.
|
|
89
|
+
*/
|
|
90
|
+
async enrollDatabase({ databaseIdentifier, tenant }) {
|
|
91
|
+
if (!this.configuration)
|
|
92
|
+
throw new Error("Test transaction session requires a configuration to enroll a database");
|
|
93
|
+
const pool = this.configuration.getDatabasePool(databaseIdentifier);
|
|
94
|
+
const databaseConfiguration = this.configuration.resolveDatabaseConfiguration(databaseIdentifier, tenant);
|
|
95
|
+
const reuseKey = pool.getConfigurationReuseKey(databaseConfiguration);
|
|
96
|
+
const identity = `${databaseIdentifier}\0${reuseKey}`;
|
|
97
|
+
if (this.enrollments.has(identity))
|
|
98
|
+
return;
|
|
99
|
+
const connection = await this.configuration.runWithTenant(tenant, async () => {
|
|
100
|
+
return await pool.checkout({ name: "Test transaction session" });
|
|
101
|
+
});
|
|
102
|
+
await this.enroll({
|
|
103
|
+
connection,
|
|
104
|
+
databaseIdentifier,
|
|
105
|
+
release: async () => { await pool.checkin(connection); },
|
|
106
|
+
reuseKey
|
|
107
|
+
});
|
|
108
|
+
this.installSharedConnectionProvider(databaseIdentifier, pool);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Makes in-process request/Scoundrel checkouts resolve by current physical identity.
|
|
112
|
+
* @param {string} databaseIdentifier - Logical database identifier.
|
|
113
|
+
* @param {import("../database/pool/base.js").default} pool - Owning pool.
|
|
114
|
+
*/
|
|
115
|
+
installSharedConnectionProvider(databaseIdentifier, pool) {
|
|
116
|
+
if (this.sharedConnectionRegistrations.has(databaseIdentifier))
|
|
117
|
+
return;
|
|
118
|
+
const broker = this.requiredBroker();
|
|
119
|
+
const sessionIdentity = { address: broker.address(), capability: broker.capability() };
|
|
120
|
+
const registration = pool.registerTestSharedConnectionProvider({
|
|
121
|
+
matches: () => sharedTransactionBrokerContextMatches(sessionIdentity),
|
|
122
|
+
provider: () => {
|
|
123
|
+
if (!broker.accepting)
|
|
124
|
+
throw new Error("Test transaction session capability has been revoked");
|
|
125
|
+
const reuseKey = pool.getConfigurationReuseKey();
|
|
126
|
+
const connection = this.enrollments.get(`${databaseIdentifier}\0${reuseKey}`)?.connection;
|
|
127
|
+
if (!connection)
|
|
128
|
+
throw new Error(`Test transaction physical identity is not enrolled: ${databaseIdentifier}`);
|
|
129
|
+
return connection;
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
if (registration)
|
|
133
|
+
this.sharedConnectionRegistrations.set(databaseIdentifier, { pool, registration });
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Returns ephemeral coordinates for one live IPC/control message.
|
|
137
|
+
* @returns {{address: string, capability: string}} - Non-durable join coordinates.
|
|
138
|
+
*/
|
|
139
|
+
joinMessage() {
|
|
140
|
+
const broker = this.requiredBroker();
|
|
141
|
+
if (!broker.accepting)
|
|
142
|
+
throw new Error("Test transaction session capability has been revoked");
|
|
143
|
+
return { address: broker.address(), capability: broker.capability() };
|
|
144
|
+
}
|
|
145
|
+
/** Stops admission to the capability. */
|
|
146
|
+
revoke() { this.requiredBroker().revoke(); }
|
|
147
|
+
/** Drains work accepted before revocation. */
|
|
148
|
+
async drain() { await this.requiredBroker().drain(); }
|
|
149
|
+
/**
|
|
150
|
+
* Rolls back and releases the complete enrolled set after admission stops.
|
|
151
|
+
* @returns {Promise<void>} - Resolves after rollback and release.
|
|
152
|
+
*/
|
|
153
|
+
async rollback() {
|
|
154
|
+
if (this.rollbackPromise)
|
|
155
|
+
return await this.rollbackPromise;
|
|
156
|
+
this.rollbackPromise = this.rollbackActual();
|
|
157
|
+
return await this.rollbackPromise;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Performs rollback and release once.
|
|
161
|
+
* @returns {Promise<void>} - Resolves after actual rollback and release.
|
|
162
|
+
*/
|
|
163
|
+
async rollbackActual() {
|
|
164
|
+
const broker = this.requiredBroker();
|
|
165
|
+
if (broker.accepting)
|
|
166
|
+
throw new Error("Test transaction session must be revoked before rollback");
|
|
167
|
+
/** @type {Array<Error>} */
|
|
168
|
+
const errors = [];
|
|
169
|
+
try {
|
|
170
|
+
await broker.close();
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
errors.push(this.normalizeError(error));
|
|
174
|
+
}
|
|
175
|
+
for (const { pool, registration } of this.sharedConnectionRegistrations.values()) {
|
|
176
|
+
pool.clearTestSharedConnection(registration);
|
|
177
|
+
}
|
|
178
|
+
this.sharedConnectionRegistrations.clear();
|
|
179
|
+
for (const enrollment of this.enrollments.values()) {
|
|
180
|
+
try {
|
|
181
|
+
await this.rollbackAndRelease(enrollment);
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
errors.push(this.normalizeError(error));
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
this.enrollments.clear();
|
|
188
|
+
if (errors.length > 0)
|
|
189
|
+
throw new AggregateError(errors, "Test transaction session rollback failed");
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Revokes, drains, rolls back, and releases every enrolled physical connection exactly once.
|
|
193
|
+
* @returns {Promise<void>} - Resolves after idempotent cleanup.
|
|
194
|
+
*/
|
|
195
|
+
async cleanup() {
|
|
196
|
+
if (this.cleanupPromise)
|
|
197
|
+
return await this.cleanupPromise;
|
|
198
|
+
this.cleanupPromise = this.cleanupActual();
|
|
199
|
+
return await this.cleanupPromise;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Performs idempotent cleanup once.
|
|
203
|
+
* @returns {Promise<void>} - Resolves after actual cleanup.
|
|
204
|
+
*/
|
|
205
|
+
async cleanupActual() {
|
|
206
|
+
this.revoke();
|
|
207
|
+
await this.rollback();
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Returns capability-free session diagnostics.
|
|
211
|
+
* @returns {{accepting: boolean, enrollmentCount: number}} - Capability-free diagnostics.
|
|
212
|
+
*/
|
|
213
|
+
debugSnapshot() {
|
|
214
|
+
return { accepting: this.broker?.accepting === true, enrollmentCount: this.enrollments.size };
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Returns the begun broker.
|
|
218
|
+
* @returns {SharedTransactionBroker} - Begun broker.
|
|
219
|
+
*/
|
|
220
|
+
requiredBroker() {
|
|
221
|
+
if (!this.broker)
|
|
222
|
+
throw new Error("Test transaction session has not begun");
|
|
223
|
+
return this.broker;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Rolls back and releases one owned physical connection.
|
|
227
|
+
* @param {Enrollment} enrollment - Owned physical connection.
|
|
228
|
+
* @returns {Promise<void>} - Resolves after rollback and release.
|
|
229
|
+
*/
|
|
230
|
+
async rollbackAndRelease(enrollment) {
|
|
231
|
+
/** @type {Array<Error>} */
|
|
232
|
+
const errors = [];
|
|
233
|
+
try {
|
|
234
|
+
await enrollment.connection.rollbackTransaction();
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
errors.push(this.normalizeError(error));
|
|
238
|
+
}
|
|
239
|
+
try {
|
|
240
|
+
await enrollment.release();
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
errors.push(this.normalizeError(error));
|
|
244
|
+
}
|
|
245
|
+
if (errors.length > 0)
|
|
246
|
+
throw new AggregateError(errors, "Test transaction enrollment cleanup failed");
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Normalizes a thrown cleanup value.
|
|
250
|
+
* @param {unknown} error - Opaque thrown cleanup value narrowed at this boundary.
|
|
251
|
+
* @returns {Error} - Error instance.
|
|
252
|
+
*/
|
|
253
|
+
normalizeError(error) { return error instanceof Error ? error : new Error(String(error)); }
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC10cmFuc2FjdGlvbi1zZXNzaW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3Rlc3RpbmcvdGVzdC10cmFuc2FjdGlvbi1zZXNzaW9uLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLHVCQUF1QixNQUFNLGdDQUFnQyxDQUFBO0FBQ3BFLE9BQU8sRUFBRSxvQ0FBb0MsRUFBRSxxQ0FBcUMsRUFBRSxNQUFNLHNDQUFzQyxDQUFBO0FBRWxJLG9LQUFvSztBQUVwSzs7O0dBR0c7QUFDSCxNQUFNLENBQUMsT0FBTyxPQUFPLHNCQUFzQjtJQUN6Qzs7O09BR0c7SUFDSCxZQUFZLGFBQWE7UUFDdkIsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUE7UUFDbEMsa0RBQWtEO1FBQ2xELElBQUksQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFBO1FBQ3ZCLHNDQUFzQztRQUN0QyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksR0FBRyxFQUFFLENBQUE7UUFDNUIsaUtBQWlLO1FBQ2pLLElBQUksQ0FBQyw2QkFBNkIsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFBO1FBQzlDLHdDQUF3QztRQUN4QyxJQUFJLENBQUMsY0FBYyxHQUFHLFNBQVMsQ0FBQTtRQUMvQix3Q0FBd0M7UUFDeEMsSUFBSSxDQUFDLGVBQWUsR0FBRyxTQUFTLENBQUE7SUFDbEMsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFDLGFBQWEsRUFBQyxHQUFHLEVBQUU7UUFDckMsTUFBTSxPQUFPLEdBQUcsSUFBSSxzQkFBc0IsQ0FBQyxhQUFhLENBQUMsQ0FBQTtRQUN6RCxPQUFPLENBQUMsTUFBTSxHQUFHLE1BQU0sdUJBQXVCLENBQUMsS0FBSyxDQUFDLEVBQUMsV0FBVyxFQUFFLEVBQUUsRUFBQyxDQUFDLENBQUE7UUFDdkUsT0FBTyxPQUFPLENBQUE7SUFDaEIsQ0FBQztJ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QUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFBO1FBQUMsQ0FBQztRQUM1RixJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQztZQUFFLE1BQU0sSUFBSSxjQUFjLENBQUMsTUFBTSxFQUFFLDRDQUE0QyxDQUFDLENBQUE7SUFDdkcsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxjQUFjLENBQUMsS0FBSyxJQUFJLE9BQU8sS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQSxDQUFDLENBQUM7Q0FDM0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IFNoYXJlZFRyYW5zYWN0aW9uQnJva2VyIGZyb20gXCIuL3NoYXJlZC10cmFuc2FjdGlvbi1icm9rZXIuanNcIlxuaW1wb3J0IHsgcnVuV2l0aFNoYXJlZFRyYW5zYWN0aW9uQnJva2VyQ29uZmlnLCBzaGFyZWRUcmFuc2FjdGlvbkJyb2tlckNvbnRleHRNYXRjaGVzIH0gZnJvbSBcIi4vc2hhcmVkLXRyYW5zYWN0aW9uLXByb3h5LWRyaXZlci5qc1wiXG5cbi8qKiBAdHlwZWRlZiB7e2Nvbm5lY3Rpb246IGltcG9ydChcIi4uL2RhdGFiYXNlL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0LCBkYXRhYmFzZUlkZW50aWZpZXI6IHN0cmluZywgcmVsZWFzZTogKCkgPT4gUHJvbWlzZTx2b2lkPiwgcmV1c2VLZXk6IHN0cmluZ319IEVucm9sbG1lbnQgKi9cblxuLyoqXG4gKiBCYWNrZW5kLW93bmVkLCBjYXBhYmlsaXR5LXNjb3BlZCB0cmFuc2FjdGlvbiBzZXQgZm9yIGxvbmctbGl2ZWQgdGVzdCBzZXJ2aWNlcy5cbiAqIEpvaW4gY29vcmRpbmF0ZXMgYXJlIGludGVudGlvbmFsbHkgb2J0YWluYWJsZSBvbmx5IGFzIGEgbGl2ZSBjb250cm9sIG1lc3NhZ2UuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRlc3RUcmFuc2FjdGlvblNlc3Npb24ge1xuICAvKipcbiAgICogQ3JlYXRlcyBhbiB1bnN0YXJ0ZWQgdHJhbnNhY3Rpb24gc2Vzc2lvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9IFtjb25maWd1cmF0aW9uXSAtIEJhY2tlbmQgY29uZmlndXJhdGlvbiBvd25pbmcgZW5yb2xsZWQgcG9vbHMuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uKSB7XG4gICAgdGhpcy5jb25maWd1cmF0aW9uID0gY29uZmlndXJhdGlvblxuICAgIC8qKiBAdHlwZSB7U2hhcmVkVHJhbnNhY3Rpb25Ccm9rZXIgfCB1bmRlZmluZWR9ICovXG4gICAgdGhpcy5icm9rZXIgPSB1bmRlZmluZWRcbiAgICAvKiogQHR5cGUge01hcDxzdHJpbmcsIEVucm9sbG1lbnQ+fSAqL1xuICAgIHRoaXMuZW5yb2xsbWVudHMgPSBuZXcgTWFwKClcbiAgICAvKiogQHR5cGUge01hcDxzdHJpbmcsIHtwb29sOiBpbXBvcnQoXCIuLi9kYXRhYmFzZS9wb29sL2Jhc2UuanNcIikuZGVmYXVsdCwgcmVnaXN0cmF0aW9uOiBpbXBvcnQoXCIuLi9kYXRhYmFzZS9wb29sL2Jhc2UuanNcIikuVGVzdFNoYXJlZENvbm5lY3Rpb25SZWdpc3RyYXRpb259Pn0gKi9cbiAgICB0aGlzLnNoYXJlZENvbm5lY3Rpb25SZWdpc3RyYXRpb25zID0gbmV3IE1hcCgpXG4gICAgLyoqIEB0eXBlIHtQcm9taXNlPHZvaWQ+IHwgdW5kZWZpbmVkfSAqL1xuICAgIHRoaXMuY2xlYW51cFByb21pc2UgPSB1bmRlZmluZWRcbiAgICAvKiogQHR5cGUge1Byb21pc2U8dm9pZD4gfCB1bmRlZmluZWR9ICovXG4gICAgdGhpcy5yb2xsYmFja1Byb21pc2UgPSB1bmRlZmluZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBCZWdpbnMgYSB0ZXN0IHRyYW5zYWN0aW9uIHNlc3Npb24uXG4gICAqIEBwYXJhbSB7e2NvbmZpZ3VyYXRpb24/OiBpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9fSBbYXJnc10gLSBCYWNrZW5kIG93bmVyLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUZXN0VHJhbnNhY3Rpb25TZXNzaW9uPn0gLSBCZWd1biBzZXNzaW9uLlxuICAgKi9cbiAgc3RhdGljIGFzeW5jIGJlZ2luKHtjb25maWd1cmF0aW9ufSA9IHt9KSB7XG4gICAgY29uc3Qgc2Vzc2lvbiA9IG5ldyBUZXN0VHJhbnNhY3Rpb25TZXNzaW9uKGNvbmZpZ3VyYXRpb24pXG4gICAgc2Vzc2lvbi5icm9rZXIgPSBhd2FpdCBTaGFyZWRUcmFuc2FjdGlvbkJyb2tlci5zdGFydCh7Y29ubmVjdGlvbnM6IHt9fSlcbiAgICByZXR1cm4gc2Vzc2lvblxuICB9XG5cbiAgLyoqXG4gICAqIEpvaW5zIG9uZSByZXF1ZXN0L2pvYiBjYWxsYmFjayBmcm9tIGEgbGl2ZSBiYWNrZW5kIGNvbnRyb2wgbWVzc2FnZS5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQHBhcmFtIHt7YWRkcmVzczogc3RyaW5nLCBjYXBhYmlsaXR5OiBzdHJpbmd9fSBtZXNzYWdlIC0gRXBoZW1lcmFsIGNvb3JkaW5hdGVzIHJlY2VpdmVkIG92ZXIgbGl2ZSBJUEMuXG4gICAqIEBwYXJhbSB7KCkgPT4gVH0gY2FsbGJhY2sgLSBCYWNrZW5kIHJlcXVlc3Qgb3Igd29ya2VyIHdvcmsuXG4gICAqIEByZXR1cm5zIHtUfSAtIENhbGxiYWNrIHJlc3VsdC5cbiAgICovXG4gIHN0YXRpYyBqb2luKG1lc3NhZ2UsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIHJ1bldpdGhTaGFyZWRUcmFuc2FjdGlvbkJyb2tlckNvbmZpZyh7Li4ubWVzc2FnZSwgYWxsb3dEeW5hbWljSWRlbnRpdGllczogdHJ1ZSwgZGF0YWJhc2VJZGVudGlmaWVyczogW10sIGV4cGVjdGVkOiB0cnVlfSwgY2FsbGJhY2spXG4gIH1cblxuICAvKipcbiAgICogTGF6aWx5IGFkZHMgYW4gZXhhY3QgcGh5c2ljYWwgY29ubmVjdGlvbiB0byB0aGUgY29tbW9uIHJvbGxiYWNrIHNldC5cbiAgICogQHBhcmFtIHtFbnJvbGxtZW50fSBlbnJvbGxtZW50IC0gQ2hlY2tlZC1vdXQgcGh5c2ljYWwgY29ubmVjdGlvbiBhbmQgb3duZXIgcmVsZWFzZSBob29rLlxuICAgKi9cbiAgYXN5bmMgZW5yb2xsKGVucm9sbG1lbnQpIHtcbiAgICBjb25zdCBicm9rZXIgPSB0aGlzLnJlcXVpcmVkQnJva2VyKClcbiAgICBjb25zdCBpZGVudGl0eSA9IGAke2Vucm9sbG1lbnQuZGF0YWJhc2VJZGVudGlmaWVyfVxcMCR7ZW5yb2xsbWVudC5yZXVzZUtleX1gXG4gICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLmVucm9sbG1lbnRzLmdldChpZGVudGl0eSlcbiAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgIGlmIChleGlzdGluZy5jb25uZWN0aW9uICE9PSBlbnJvbGxtZW50LmNvbm5lY3Rpb24pIGF3YWl0IGVucm9sbG1lbnQucmVsZWFzZSgpXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGVucm9sbG1lbnQuY29ubmVjdGlvbi5zdGFydFRyYW5zYWN0aW9uKClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLyoqIEB0eXBlIHtFcnJvciB8IHVuZGVmaW5lZH0gKi9cbiAgICAgIGxldCByZWxlYXNlRmFpbHVyZVxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgZW5yb2xsbWVudC5yZWxlYXNlKClcbiAgICAgIH0gY2F0Y2ggKHJlbGVhc2VFcnJvcikge1xuICAgICAgICByZWxlYXNlRmFpbHVyZSA9IHRoaXMubm9ybWFsaXplRXJyb3IocmVsZWFzZUVycm9yKVxuICAgICAgfVxuICAgICAgaWYgKHJlbGVhc2VGYWlsdXJlKSB7XG4gICAgICAgIHRocm93IG5ldyBBZ2dyZWdhdGVFcnJvcihcbiAgICAgICAgICBbdGhpcy5ub3JtYWxpemVFcnJvcihlcnJvciksIHJlbGVhc2VGYWlsdXJlXSxcbiAgICAgICAgICBcIlRlc3QgdHJhbnNhY3Rpb24gZW5yb2xsbWVudCBzdGFydCBhbmQgcmVsZWFzZSBmYWlsZWRcIixcbiAgICAgICAgICB7Y2F1c2U6IGVycm9yfVxuICAgICAgICApXG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvclxuICAgIH1cbiAgICB0cnkge1xuICAgICAgYnJva2VyLmVucm9sbENvbm5lY3Rpb24oZW5yb2xsbWVudClcbiAgICAgIHRoaXMuZW5yb2xsbWVudHMuc2V0KGlkZW50aXR5LCBlbnJvbGxtZW50KVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBhd2FpdCB0aGlzLnJvbGxiYWNrQW5kUmVsZWFzZShlbnJvbGxtZW50KVxuICAgICAgdGhyb3cgZXJyb3JcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTGF6aWx5IGNoZWNrcyBvdXQgYW5kIGVucm9sbHMgdGhlIHBoeXNpY2FsIGRhdGFiYXNlIHNlbGVjdGVkIGJ5IGEgdGVuYW50IGRlc2NyaXB0b3IuXG4gICAqIEBwYXJhbSB7e2RhdGFiYXNlSWRlbnRpZmllcjogc3RyaW5nLCB0ZW5hbnQ/OiBvYmplY3R9fSBhcmdzIC0gTG9naWNhbCBhbmQgdGVuYW50IGlkZW50aXR5LlxuICAgKi9cbiAgYXN5bmMgZW5yb2xsRGF0YWJhc2Uoe2RhdGFiYXNlSWRlbnRpZmllciwgdGVuYW50fSkge1xuICAgIGlmICghdGhpcy5jb25maWd1cmF0aW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJUZXN0IHRyYW5zYWN0aW9uIHNlc3Npb24gcmVxdWlyZXMgYSBjb25maWd1cmF0aW9uIHRvIGVucm9sbCBhIGRhdGFiYXNlXCIpXG4gICAgY29uc3QgcG9vbCA9IHRoaXMuY29uZmlndXJhdGlvbi5nZXREYXRhYmFzZVBvb2woZGF0YWJhc2VJZGVudGlmaWVyKVxuICAgIGNvbnN0IGRhdGFiYXNlQ29uZmlndXJhdGlvbiA9IHRoaXMuY29uZmlndXJhdGlvbi5yZXNvbHZlRGF0YWJhc2VDb25maWd1cmF0aW9uKGRhdGFiYXNlSWRlbnRpZmllciwgdGVuYW50KVxuICAgIGNvbnN0IHJldXNlS2V5ID0gcG9vbC5nZXRDb25maWd1cmF0aW9uUmV1c2VLZXkoZGF0YWJhc2VDb25maWd1cmF0aW9uKVxuICAgIGNvbnN0IGlkZW50aXR5ID0gYCR7ZGF0YWJhc2VJZGVudGlmaWVyfVxcMCR7cmV1c2VLZXl9YFxuICAgIGlmICh0aGlzLmVucm9sbG1lbnRzLmhhcyhpZGVudGl0eSkpIHJldHVyblxuICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24ucnVuV2l0aFRlbmFudCh0ZW5hbnQsIGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCBwb29sLmNoZWNrb3V0KHtuYW1lOiBcIlRlc3QgdHJhbnNhY3Rpb24gc2Vzc2lvblwifSlcbiAgICB9KVxuICAgIGF3YWl0IHRoaXMuZW5yb2xsKHtcbiAgICAgIGNvbm5lY3Rpb24sXG4gICAgICBkYXRhYmFzZUlkZW50aWZpZXIsXG4gICAgICByZWxlYXNlOiBhc3luYyAoKSA9PiB7IGF3YWl0IHBvb2wuY2hlY2tpbihjb25uZWN0aW9uKSB9LFxuICAgICAgcmV1c2VLZXlcbiAgICB9KVxuICAgIHRoaXMuaW5zdGFsbFNoYXJlZENvbm5lY3Rpb25Qcm92aWRlcihkYXRhYmFzZUlkZW50aWZpZXIsIHBvb2wpXG4gIH1cblxuICAvKipcbiAgICogTWFrZXMgaW4tcHJvY2VzcyByZXF1ZXN0L1Njb3VuZHJlbCBjaGVja291dHMgcmVzb2x2ZSBieSBjdXJyZW50IHBoeXNpY2FsIGlkZW50aXR5LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZGF0YWJhc2VJZGVudGlmaWVyIC0gTG9naWNhbCBkYXRhYmFzZSBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RhdGFiYXNlL3Bvb2wvYmFzZS5qc1wiKS5kZWZhdWx0fSBwb29sIC0gT3duaW5nIHBvb2wuXG4gICAqL1xuICBpbnN0YWxsU2hhcmVkQ29ubmVjdGlvblByb3ZpZGVyKGRhdGFiYXNlSWRlbnRpZmllciwgcG9vbCkge1xuICAgIGlmICh0aGlzLnNoYXJlZENvbm5lY3Rpb25SZWdpc3RyYXRpb25zLmhhcyhkYXRhYmFzZUlkZW50aWZpZXIpKSByZXR1cm5cbiAgICBjb25zdCBicm9rZXIgPSB0aGlzLnJlcXVpcmVkQnJva2VyKClcbiAgICBjb25zdCBzZXNzaW9uSWRlbnRpdHkgPSB7YWRkcmVzczogYnJva2VyLmFkZHJlc3MoKSwgY2FwYWJpbGl0eTogYnJva2VyLmNhcGFiaWxpdHkoKX1cbiAgICBjb25zdCByZWdpc3RyYXRpb24gPSBwb29sLnJlZ2lzdGVyVGVzdFNoYXJlZENvbm5lY3Rpb25Qcm92aWRlcih7XG4gICAgICBtYXRjaGVzOiAoKSA9PiBzaGFyZWRUcmFuc2FjdGlvbkJyb2tlckNvbnRleHRNYXRjaGVzKHNlc3Npb25JZGVudGl0eSksXG4gICAgICBwcm92aWRlcjogKCkgPT4ge1xuICAgICAgICBpZiAoIWJyb2tlci5hY2NlcHRpbmcpIHRocm93IG5ldyBFcnJvcihcIlRlc3QgdHJhbnNhY3Rpb24gc2Vzc2lvbiBjYXBhYmlsaXR5IGhhcyBiZWVuIHJldm9rZWRcIilcbiAgICAgICAgY29uc3QgcmV1c2VLZXkgPSBwb29sLmdldENvbmZpZ3VyYXRpb25SZXVzZUtleSgpXG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSB0aGlzLmVucm9sbG1lbnRzLmdldChgJHtkYXRhYmFzZUlkZW50aWZpZXJ9XFwwJHtyZXVzZUtleX1gKT8uY29ubmVjdGlvblxuICAgICAgICBpZiAoIWNvbm5lY3Rpb24pIHRocm93IG5ldyBFcnJvcihgVGVzdCB0cmFuc2FjdGlvbiBwaHlzaWNhbCBpZGVudGl0eSBpcyBub3QgZW5yb2xsZWQ6ICR7ZGF0YWJhc2VJZGVudGlmaWVyfWApXG4gICAgICAgIHJldHVybiBjb25uZWN0aW9uXG4gICAgICB9XG4gICAgfSlcbiAgICBpZiAocmVnaXN0cmF0aW9uKSB0aGlzLnNoYXJlZENvbm5lY3Rpb25SZWdpc3RyYXRpb25zLnNldChkYXRhYmFzZUlkZW50aWZpZXIsIHtwb29sLCByZWdpc3RyYXRpb259KVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgZXBoZW1lcmFsIGNvb3JkaW5hdGVzIGZvciBvbmUgbGl2ZSBJUEMvY29udHJvbCBtZXNzYWdlLlxuICAgKiBAcmV0dXJucyB7e2FkZHJlc3M6IHN0cmluZywgY2FwYWJpbGl0eTogc3RyaW5nfX0gLSBOb24tZHVyYWJsZSBqb2luIGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgam9pbk1lc3NhZ2UoKSB7XG4gICAgY29uc3QgYnJva2VyID0gdGhpcy5yZXF1aXJlZEJyb2tlcigpXG4gICAgaWYgKCFicm9rZXIuYWNjZXB0aW5nKSB0aHJvdyBuZXcgRXJyb3IoXCJUZXN0IHRyYW5zYWN0aW9uIHNlc3Npb24gY2FwYWJpbGl0eSBoYXMgYmVlbiByZXZva2VkXCIpXG4gICAgcmV0dXJuIHthZGRyZXNzOiBicm9rZXIuYWRkcmVzcygpLCBjYXBhYmlsaXR5OiBicm9rZXIuY2FwYWJpbGl0eSgpfVxuICB9XG5cbiAgLyoqIFN0b3BzIGFkbWlzc2lvbiB0byB0aGUgY2FwYWJpbGl0eS4gKi9cbiAgcmV2b2tlKCkgeyB0aGlzLnJlcXVpcmVkQnJva2VyKCkucmV2b2tlKCkgfVxuXG4gIC8qKiBEcmFpbnMgd29yayBhY2NlcHRlZCBiZWZvcmUgcmV2b2NhdGlvbi4gKi9cbiAgYXN5bmMgZHJhaW4oKSB7IGF3YWl0IHRoaXMucmVxdWlyZWRCcm9rZXIoKS5kcmFpbigpIH1cblxuICAvKipcbiAgICogUm9sbHMgYmFjayBhbmQgcmVsZWFzZXMgdGhlIGNvbXBsZXRlIGVucm9sbGVkIHNldCBhZnRlciBhZG1pc3Npb24gc3RvcHMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIGFmdGVyIHJvbGxiYWNrIGFuZCByZWxlYXNlLlxuICAgKi9cbiAgYXN5bmMgcm9sbGJhY2soKSB7XG4gICAgaWYgKHRoaXMucm9sbGJhY2tQcm9taXNlKSByZXR1cm4gYXdhaXQgdGhpcy5yb2xsYmFja1Byb21pc2VcbiAgICB0aGlzLnJvbGxiYWNrUHJvbWlzZSA9IHRoaXMucm9sbGJhY2tBY3R1YWwoKVxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJvbGxiYWNrUHJvbWlzZVxuICB9XG5cbiAgLyoqXG4gICAqIFBlcmZvcm1zIHJvbGxiYWNrIGFuZCByZWxlYXNlIG9uY2UuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIGFmdGVyIGFjdHVhbCByb2xsYmFjayBhbmQgcmVsZWFzZS5cbiAgICovXG4gIGFzeW5jIHJvbGxiYWNrQWN0dWFsKCkge1xuICAgIGNvbnN0IGJyb2tlciA9IHRoaXMucmVxdWlyZWRCcm9rZXIoKVxuICAgIGlmIChicm9rZXIuYWNjZXB0aW5nKSB0aHJvdyBuZXcgRXJyb3IoXCJUZXN0IHRyYW5zYWN0aW9uIHNlc3Npb24gbXVzdCBiZSByZXZva2VkIGJlZm9yZSByb2xsYmFja1wiKVxuICAgIC8qKiBAdHlwZSB7QXJyYXk8RXJyb3I+fSAqL1xuICAgIGNvbnN0IGVycm9ycyA9IFtdXG4gICAgdHJ5IHsgYXdhaXQgYnJva2VyLmNsb3NlKCkgfSBjYXRjaCAoZXJyb3IpIHsgZXJyb3JzLnB1c2godGhpcy5ub3JtYWxpemVFcnJvcihlcnJvcikpIH1cbiAgICBmb3IgKGNvbnN0IHtwb29sLCByZWdpc3RyYXRpb259IG9mIHRoaXMuc2hhcmVkQ29ubmVjdGlvblJlZ2lzdHJhdGlvbnMudmFsdWVzKCkpIHtcbiAgICAgIHBvb2wuY2xlYXJUZXN0U2hhcmVkQ29ubmVjdGlvbihyZWdpc3RyYXRpb24pXG4gICAgfVxuICAgIHRoaXMuc2hhcmVkQ29ubmVjdGlvblJlZ2lzdHJhdGlvbnMuY2xlYXIoKVxuICAgIGZvciAoY29uc3QgZW5yb2xsbWVudCBvZiB0aGlzLmVucm9sbG1lbnRzLnZhbHVlcygpKSB7XG4gICAgICB0cnkgeyBhd2FpdCB0aGlzLnJvbGxiYWNrQW5kUmVsZWFzZShlbnJvbGxtZW50KSB9IGNhdGNoIChlcnJvcikgeyBlcnJvcnMucHVzaCh0aGlzLm5vcm1hbGl6ZUVycm9yKGVycm9yKSkgfVxuICAgIH1cbiAgICB0aGlzLmVucm9sbG1lbnRzLmNsZWFyKClcbiAgICBpZiAoZXJyb3JzLmxlbmd0aCA+IDApIHRocm93IG5ldyBBZ2dyZWdhdGVFcnJvcihlcnJvcnMsIFwiVGVzdCB0cmFuc2FjdGlvbiBzZXNzaW9uIHJvbGxiYWNrIGZhaWxlZFwiKVxuICB9XG5cbiAgLyoqXG4gICAqIFJldm9rZXMsIGRyYWlucywgcm9sbHMgYmFjaywgYW5kIHJlbGVhc2VzIGV2ZXJ5IGVucm9sbGVkIHBoeXNpY2FsIGNvbm5lY3Rpb24gZXhhY3RseSBvbmNlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciBpZGVtcG90ZW50IGNsZWFudXAuXG4gICAqL1xuICBhc3luYyBjbGVhbnVwKCkge1xuICAgIGlmICh0aGlzLmNsZWFudXBQcm9taXNlKSByZXR1cm4gYXdhaXQgdGhpcy5jbGVhbnVwUHJvbWlzZVxuICAgIHRoaXMuY2xlYW51cFByb21pc2UgPSB0aGlzLmNsZWFudXBBY3R1YWwoKVxuICAgIHJldHVybiBhd2FpdCB0aGlzLmNsZWFudXBQcm9taXNlXG4gIH1cblxuICAvKipcbiAgICogUGVyZm9ybXMgaWRlbXBvdGVudCBjbGVhbnVwIG9uY2UuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIGFmdGVyIGFjdHVhbCBjbGVhbnVwLlxuICAgKi9cbiAgYXN5bmMgY2xlYW51cEFjdHVhbCgpIHtcbiAgICB0aGlzLnJldm9rZSgpXG4gICAgYXdhaXQgdGhpcy5yb2xsYmFjaygpXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBjYXBhYmlsaXR5LWZyZWUgc2Vzc2lvbiBkaWFnbm9zdGljcy5cbiAgICogQHJldHVybnMge3thY2NlcHRpbmc6IGJvb2xlYW4sIGVucm9sbG1lbnRDb3VudDogbnVtYmVyfX0gLSBDYXBhYmlsaXR5LWZyZWUgZGlhZ25vc3RpY3MuXG4gICAqL1xuICBkZWJ1Z1NuYXBzaG90KCkge1xuICAgIHJldHVybiB7YWNjZXB0aW5nOiB0aGlzLmJyb2tlcj8uYWNjZXB0aW5nID09PSB0cnVlLCBlbnJvbGxtZW50Q291bnQ6IHRoaXMuZW5yb2xsbWVudHMuc2l6ZX1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBiZWd1biBicm9rZXIuXG4gICAqIEByZXR1cm5zIHtTaGFyZWRUcmFuc2FjdGlvbkJyb2tlcn0gLSBCZWd1biBicm9rZXIuXG4gICAqL1xuICByZXF1aXJlZEJyb2tlcigpIHtcbiAgICBpZiAoIXRoaXMuYnJva2VyKSB0aHJvdyBuZXcgRXJyb3IoXCJUZXN0IHRyYW5zYWN0aW9uIHNlc3Npb24gaGFzIG5vdCBiZWd1blwiKVxuICAgIHJldHVybiB0aGlzLmJyb2tlclxuICB9XG5cbiAgLyoqXG4gICAqIFJvbGxzIGJhY2sgYW5kIHJlbGVhc2VzIG9uZSBvd25lZCBwaHlzaWNhbCBjb25uZWN0aW9uLlxuICAgKiBAcGFyYW0ge0Vucm9sbG1lbnR9IGVucm9sbG1lbnQgLSBPd25lZCBwaHlzaWNhbCBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciByb2xsYmFjayBhbmQgcmVsZWFzZS5cbiAgICovXG4gIGFzeW5jIHJvbGxiYWNrQW5kUmVsZWFzZShlbnJvbGxtZW50KSB7XG4gICAgLyoqIEB0eXBlIHtBcnJheTxFcnJvcj59ICovXG4gICAgY29uc3QgZXJyb3JzID0gW11cbiAgICB0cnkgeyBhd2FpdCBlbnJvbGxtZW50LmNvbm5lY3Rpb24ucm9sbGJhY2tUcmFuc2FjdGlvbigpIH0gY2F0Y2ggKGVycm9yKSB7IGVycm9ycy5wdXNoKHRoaXMubm9ybWFsaXplRXJyb3IoZXJyb3IpKSB9XG4gICAgdHJ5IHsgYXdhaXQgZW5yb2xsbWVudC5yZWxlYXNlKCkgfSBjYXRjaCAoZXJyb3IpIHsgZXJyb3JzLnB1c2godGhpcy5ub3JtYWxpemVFcnJvcihlcnJvcikpIH1cbiAgICBpZiAoZXJyb3JzLmxlbmd0aCA+IDApIHRocm93IG5ldyBBZ2dyZWdhdGVFcnJvcihlcnJvcnMsIFwiVGVzdCB0cmFuc2FjdGlvbiBlbnJvbGxtZW50IGNsZWFudXAgZmFpbGVkXCIpXG4gIH1cblxuICAvKipcbiAgICogTm9ybWFsaXplcyBhIHRocm93biBjbGVhbnVwIHZhbHVlLlxuICAgKiBAcGFyYW0ge3Vua25vd259IGVycm9yIC0gT3BhcXVlIHRocm93biBjbGVhbnVwIHZhbHVlIG5hcnJvd2VkIGF0IHRoaXMgYm91bmRhcnkuXG4gICAqIEByZXR1cm5zIHtFcnJvcn0gLSBFcnJvciBpbnN0YW5jZS5cbiAgICovXG4gIG5vcm1hbGl6ZUVycm9yKGVycm9yKSB7IHJldHVybiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoU3RyaW5nKGVycm9yKSkgfVxufVxuIl19
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../../src/testing/test.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../../src/testing/test.js"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { fileURLToPath } from "url";
|
|
4
|
+
import { waitForEvent } from "@velocious/testing";
|
|
4
5
|
import EventEmitter from "../utils/event-emitter.js";
|
|
5
6
|
import Expect from "./expect.js";
|
|
6
|
-
import waitForEvent from "./wait-for-event.js";
|
|
7
7
|
import { arrayContaining, objectContaining } from "./expect-utils.js";
|
|
8
8
|
/**
|
|
9
9
|
* VelociousTestConfig type.
|
|
@@ -318,4 +318,4 @@ Object.assign(globalThis, {
|
|
|
318
318
|
testEvents
|
|
319
319
|
});
|
|
320
320
|
export { afterAll, afterEach, beforeAll, beforeEach, configureTests, describe, expect, fit, it, arrayContaining, objectContaining, testConfig, testEvents, tests, waitForEvent };
|
|
321
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90ZXN0aW5nL3Rlc3QuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQTtBQUN2QixPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0sS0FBSyxDQUFBO0FBQ2pDLE9BQU8sWUFBWSxNQUFNLDJCQUEyQixDQUFBO0FBQ3BELE9BQU8sTUFBTSxNQUFNLGFBQWEsQ0FBQTtBQUNoQyxPQUFPLFlBQVksTUFBTSxxQkFBcUIsQ0FBQTtBQUM5QyxPQUFPLEVBQUMsZUFBZSxFQUFFLGdCQUFnQixFQUFDLE1BQU0sbUJBQW1CLENBQUE7QUFFbkU7Ozs7Ozs7R0FPRztBQUNIOztzREFFc0Q7QUFDdEQsTUFBTSxLQUFLLEdBQUc7SUFDWjs7Z0ZBRTRFO0lBQzVFLFdBQVcsRUFBRSxFQUFFO0lBQ2Y7OytFQUUyRTtJQUMzRSxTQUFTLEVBQUUsRUFBRTtJQUNiLElBQUksRUFBRSxFQUFFO0lBRVI7OytFQUUyRTtJQUMzRSxVQUFVLEVBQUUsRUFBRTtJQUNkOztnRkFFNEU7SUFDNUUsWUFBWSxFQUFFLEVBQUU7SUFDaEIsUUFBUSxFQUFFLFNBQVM7SUFDbkIsSUFBSSxFQUFFLFNBQVM7SUFDZixJQUFJLEVBQUUsRUFBRTtJQUNSLEtBQUssRUFBRSxFQUFFO0NBQ1YsQ0FBQTtBQUVELE1BQU0sVUFBVSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUE7QUFFckMsSUFBSSxXQUFXLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQTtBQUV6Qjs7O0dBR0c7QUFDSCxTQUFTLGVBQWU7SUFDdEIsTUFBTSxLQUFLLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQTtJQUN6QixNQUFNLEtBQUssR0FBRyxPQUFPLEtBQUssQ0FBQyxLQUFLLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMs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ZWNrXG5cbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCJcbmltcG9ydCB7ZmlsZVVSTFRvUGF0aH0gZnJvbSBcInVybFwiXG5pbXBvcnQgRXZlbnRFbWl0dGVyIGZyb20gXCIuLi91dGlscy9ldmVudC1lbWl0dGVyLmpzXCJcbmltcG9ydCBFeHBlY3QgZnJvbSBcIi4vZXhwZWN0LmpzXCJcbmltcG9ydCB3YWl0Rm9yRXZlbnQgZnJvbSBcIi4vd2FpdC1mb3ItZXZlbnQuanNcIlxuaW1wb3J0IHthcnJheUNvbnRhaW5pbmcsIG9iamVjdENvbnRhaW5pbmd9IGZyb20gXCIuL2V4cGVjdC11dGlscy5qc1wiXG5cbi8qKlxuICogVmVsb2Npb3VzVGVzdENvbmZpZyB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gVmVsb2Npb3VzVGVzdENvbmZpZ1xuICogQHByb3BlcnR5IHtcImZhaWx1cmVcIiB8IFwibGl2ZVwifSBjb25zb2xlT3V0cHV0IC0gQ29uc29sZSBvdXRwdXQgbW9kZS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IGV4Y2x1ZGVUYWdzIC0gVGFncyBleGNsdWRlZCBieSBkZWZhdWx0LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGRlZmF1bHRUaW1lb3V0U2Vjb25kcyAtIERlZmF1bHQgdGltZW91dCBpbiBzZWNvbmRzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGZhaWxlZENvbnNvbGVPdXRwdXRNYXhMaW5lcyAtIE1heGltdW0gZmFpbGVkIGNvbnNvbGUgbGluZXMgdG8gcHJpbnQgaW5saW5lLlxuICovXG4vKipcbiAqIFRlc3RzLlxuICogQHR5cGUge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuVGVzdHNBcmd1bWVudH0gKi9cbmNvbnN0IHRlc3RzID0ge1xuICAvKipcbiAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgKiBAdHlwZSB7aW1wb3J0KFwiLi90ZXN0LXJ1bm5lci5qc1wiKS5BZnRlckJlZm9yZUVhY2hDYWxsYmFja09iamVjdFR5cGVbXX0gKi9cbiAgYWZ0ZXJFYWNoZXM6IFtdLFxuICAvKipcbiAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgKiBAdHlwZSB7aW1wb3J0KFwiLi90ZXN0LXJ1bm5lci5qc1wiKS5CZWZvcmVBZnRlckFsbENhbGxiYWNrT2JqZWN0VHlwZVtdfSAqL1xuICBhZnRlckFsbHM6IFtdLFxuICBhcmdzOiB7fSxcblxuICAvKipcbiAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgKiBAdHlwZSB7aW1wb3J0KFwiLi90ZXN0LXJ1bm5lci5qc1wiKS5CZWZvcmVBZnRlckFsbENhbGxiYWNrT2JqZWN0VHlwZVtdfSAqL1xuICBiZWZvcmVBbGxzOiBbXSxcbiAgLyoqXG4gICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICogQHR5cGUge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuQWZ0ZXJCZWZvcmVFYWNoQ2FsbGJhY2tPYmplY3RUeXBlW119ICovXG4gIGJlZm9yZUVhY2hlczogW10sXG4gIGZpbGVQYXRoOiB1bmRlZmluZWQsXG4gIGxpbmU6IHVuZGVmaW5lZCxcbiAgc3Viczoge30sXG4gIHRlc3RzOiB7fVxufVxuXG5jb25zdCB0ZXN0RXZlbnRzID0gbmV3IEV2ZW50RW1pdHRlcigpXG5cbmxldCBjdXJyZW50UGF0aCA9IFt0ZXN0c11cblxuLyoqXG4gKiBSdW5zIGNhcHR1cmUgbG9jYXRpb24uXG4gKiBAcmV0dXJucyB7e2ZpbGVQYXRoPzogc3RyaW5nLCBsaW5lPzogbnVtYmVyfX0gLSBMb2NhdGlvbi5cbiAqL1xuZnVuY3Rpb24gY2FwdHVyZUxvY2F0aW9uKCkge1xuICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcigpXG4gIGNvbnN0IHN0YWNrID0gdHlwZW9mIGVycm9yLnN0YWNrID09PSBcInN0cmluZ1wiID8gZXJyb3Iuc3RhY2suc3BsaXQoXCJcXG5cIikgOiBbXVxuXG4gIGZvciAoY29uc3QgbGluZSBvZiBzdGFjaykge1xuICAgIGNvbnN0IHRyaW1tZWQgPSBsaW5lLnRyaW0oKVxuXG4gICAgaWYgKCF0cmltbWVkLmluY2x1ZGVzKFwiYXRcIikpIGNvbnRpbnVlXG4gICAgaWYgKHRyaW1tZWQuaW5jbHVkZXMoXCIvc3JjL3Rlc3RpbmcvdGVzdC5qc1wiKSkgY29udGludWVcblxuICAgIGNvbnN0IG1hdGNoID0gdHJpbW1lZC5tYXRjaCgvKD86XFwofFxccykoZmlsZTpcXC9cXC8uKj98XFwvLio/KTooXFxkKyk6KFxcZCspXFwpPyQvKVxuXG4gICAgaWYgKCFtYXRjaCkgY29udGludWVcblxuICAgIGNvbnN0IHJhd1BhdGggPSBtYXRjaFsxXVxuICAgIGNvbnN0IGxpbmVOdW1iZXIgPSBOdW1iZXIobWF0Y2hbMl0pXG4gICAgY29uc3QgZmlsZVBhdGggPSByYXdQYXRoLnN0YXJ0c1dpdGgoXCJmaWxlOi8vXCIpXG4gICAgICA/IGZpbGVVUkxUb1BhdGgocmF3UGF0aClcbiAgICAgIDogcmF3UGF0aFxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGZpbGVQYXRoOiBwYXRoLnJlc29sdmUoZmlsZVBhdGgpLFxuICAgICAgbGluZTogTnVtYmVyLmlzRmluaXRlKGxpbmVOdW1iZXIpID8gbGluZU51bWJlciA6IHVuZGVmaW5lZFxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7fVxufVxuXG4vKipcbiAqIFJ1bnMgbm9ybWFsaXplIHRhZ3MuXG4gKiBAcGFyYW0ge3N0cmluZ1tdIHwgc3RyaW5nIHwgdW5kZWZpbmVkfSB0YWdzIC0gVGFncy5cbiAqIEByZXR1cm5zIHtzdHJpbmdbXX0gLSBOb3JtYWxpemVkIHRhZ3MuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZVRhZ3ModGFncykge1xuICBpZiAoIXRhZ3MpIHJldHVybiBbXVxuXG4gIGNvbnN0IHZhbHVlcyA9IFtdXG4gIGNvbnN0IHJhd1RhZ3MgPSBBcnJheS5pc0FycmF5KHRhZ3MpID8gdGFncyA6IFt0YWdzXVxuXG4gIGZvciAoY29uc3QgcmF3VGFnIG9mIHJhd1RhZ3MpIHtcbiAgICBpZiAocmF3VGFnID09PSB1bmRlZmluZWQgfHwgcmF3VGFnID09PSBudWxsKSBjb250aW51ZVxuXG4gICAgY29uc3QgcGFydHMgPSBTdHJpbmcocmF3VGFnKS5zcGxpdChcIixcIilcblxuICAgIGZvciAoY29uc3QgcGFydCBvZiBwYXJ0cykge1xuICAgICAgY29uc3QgdHJpbW1lZCA9IHBhcnQudHJpbSgpXG5cbiAgICAgIGlmICh0cmltbWVkKSB2YWx1ZXMucHVzaCh0cmltbWVkKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQodmFsdWVzKSlcbn1cblxuLyoqXG4gKiBUZXN0IGNvbmZpZy5cbiAqIEB0eXBlIHtWZWxvY2lvdXNUZXN0Q29uZmlnfSAqL1xuY29uc3QgdGVzdENvbmZpZyA9IHtcbiAgY29uc29sZU91dHB1dDogXCJmYWlsdXJlXCIsXG4gIGZhaWxlZENvbnNvbGVPdXRwdXRNYXhMaW5lczogMjAwLFxuICBleGNsdWRlVGFnczogW10sXG4gIGRlZmF1bHRUaW1lb3V0U2Vjb25kczogNjBcbn1cblxuLyoqXG4gKiBSdW5zIGNvbmZpZ3VyZSB0ZXN0cy5cbiAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucy5cbiAqIEBwYXJhbSB7XCJmYWlsdXJlXCIgfCBcImxpdmVcIn0gW2FyZ3MuY29uc29sZU91dHB1dF0gLSBDb25zb2xlIG91dHB1dCBtb2RlLlxuICogQHBhcmFtIHtzdHJpbmdbXSB8IHN0cmluZ30gW2FyZ3MuZXhjbHVkZVRhZ3NdIC0gVGFncyB0byBleGNsdWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IFthcmdzLmRlZmF1bHRUaW1lb3V0U2Vjb25kc10gLSBEZWZhdWx0IHRpbWVvdXQgaW4gc2Vjb25kcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJncy5mYWlsZWRDb25zb2xlT3V0cHV0TWF4TGluZXNdIC0gTWF4aW11bSBmYWlsZWQgY29uc29sZSBsaW5lcyB0byBwcmludCBpbmxpbmUuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gY29uZmlndXJlVGVzdHMoe2NvbnNvbGVPdXRwdXQsIGV4Y2x1ZGVUYWdzLCBkZWZhdWx0VGltZW91dFNlY29uZHMsIGZhaWxlZENvbnNvbGVPdXRwdXRNYXhMaW5lc30gPSB7fSkge1xuICBpZiAoZXhjbHVkZVRhZ3MgIT09IHVuZGVmaW5lZCkge1xuICAgIHRlc3RDb25maWcuZXhjbHVkZVRhZ3MgPSBub3JtYWxpemVUYWdzKGV4Y2x1ZGVUYWdzKVxuICB9XG5cbiAgaWYgKGNvbnNvbGVPdXRwdXQgIT09IHVuZGVmaW5lZCkge1xuICAgIGlmIChjb25zb2xlT3V0cHV0ICE9PSBcImZhaWx1cmVcIiAmJiBjb25zb2xlT3V0cHV0ICE9PSBcImxpdmVcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGNvbnNvbGVPdXRwdXQgY29uZmlnOiAke2NvbnNvbGVPdXRwdXR9YClcbiAgICB9XG5cbiAgICB0ZXN0Q29uZmlnLmNvbnNvbGVPdXRwdXQgPSBjb25zb2xlT3V0cHV0XG4gIH1cblxuICBpZiAodHlwZW9mIGRlZmF1bHRUaW1lb3V0U2Vjb25kcyA9PT0gXCJudW1iZXJcIikge1xuICAgIHRlc3RDb25maWcuZGVmYXVsdFRpbWVvdXRTZWNvbmRzID0gZGVmYXVsdFRpbWVvdXRTZWNvbmRzXG4gIH1cblxuICBpZiAodHlwZW9mIGZhaWxlZENvbnNvbGVPdXRwdXRNYXhMaW5lcyA9PT0gXCJudW1iZXJcIikge1xuICAgIHRlc3RDb25maWcuZmFpbGVkQ29uc29sZU91dHB1dE1heExpbmVzID0gZmFpbGVkQ29uc29sZU91dHB1dE1heExpbmVzXG4gIH1cbn1cblxuLyoqXG4gKiBSdW5zIG1lcmdlIHRlc3QgYXJncy5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+fSBiYXNlQXJncyAtIEJhc2UgYXJncy5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+fSBleHRyYUFyZ3MgLSBFeHRyYSBhcmdzLlxuICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gLSBNZXJnZWQgYXJncy5cbiAqL1xuZnVuY3Rpb24gbWVyZ2VUZXN0QXJncyhiYXNlQXJncywgZXh0cmFBcmdzKSB7XG4gIGNvbnN0IG1lcmdlZCA9IE9iamVjdC5hc3NpZ24oe30sIGJhc2VBcmdzLCBleHRyYUFyZ3MpXG4gIGNvbnN0IG1lcmdlZFRhZ3MgPSBbLi4ubm9ybWFsaXplVGFncyhiYXNlQXJncz8udGFncyksIC4uLm5vcm1hbGl6ZVRhZ3MoZXh0cmFBcmdzPy50YWdzKV1cblxuICBpZiAobWVyZ2VkVGFncy5sZW5ndGggPiAwKSB7XG4gICAgbWVyZ2VkLnRhZ3MgPSBBcnJheS5mcm9tKG5ldyBTZXQobWVyZ2VkVGFncykpXG4gIH0gZWxzZSBpZiAoXCJ0YWdzXCIgaW4gbWVyZ2VkKSB7XG4gICAgZGVsZXRlIG1lcmdlZC50YWdzXG4gIH1cblxuICByZXR1cm4gbWVyZ2VkXG59XG5cbi8qKlxuICogUnVucyBiZWZvcmUgZWFjaC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90ZXN0LXJ1bm5lci5qc1wiKS5BZnRlckJlZm9yZUVhY2hDYWxsYmFja1R5cGV9IGNhbGxiYWNrIC0gQ2FsbGJhY2sgZnVuY3Rpb24uXG4gKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIGJlZm9yZUVhY2goY2FsbGJhY2spIHtcbiAgY29uc3QgY3VycmVudFRlc3QgPSBjdXJyZW50UGF0aFtjdXJyZW50UGF0aC5sZW5ndGggLSAxXVxuXG4gIGN1cnJlbnRUZXN0LmJlZm9yZUVhY2hlcy5wdXNoKHtjYWxsYmFja30pXG59XG5cbi8qKlxuICogUnVucyBiZWZvcmUgYWxsLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3Rlc3QtcnVubmVyLmpzXCIpLkJlZm9yZUFmdGVyQWxsQ2FsbGJhY2tUeXBlfSBjYWxsYmFjayAtIENhbGxiYWNrIGZ1bmN0aW9uLlxuICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICovXG5mdW5jdGlvbiBiZWZvcmVBbGwoY2FsbGJhY2spIHtcbiAgY29uc3QgY3VycmVudFRlc3QgPSBjdXJyZW50UGF0aFtjdXJyZW50UGF0aC5sZW5ndGggLSAxXVxuXG4gIGN1cnJlbnRUZXN0LmJlZm9yZUFsbHMucHVzaCh7Y2FsbGJhY2t9KVxufVxuXG4vKipcbiAqIFJ1bnMgYWZ0ZXIgZWFjaC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90ZXN0LXJ1bm5lci5qc1wiKS5BZnRlckJlZm9yZUVhY2hDYWxsYmFja1R5cGV9IGNhbGxiYWNrIC0gQ2FsbGJhY2sgZnVuY3Rpb24uXG4gKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIGFmdGVyRWFjaChjYWxsYmFjaykge1xuICBjb25zdCBjdXJyZW50VGVzdCA9IGN1cnJlbnRQYXRoW2N1cnJlbnRQYXRoLmxlbmd0aCAtIDFdXG5cbiAgY3VycmVudFRlc3QuYWZ0ZXJFYWNoZXMucHVzaCh7Y2FsbGJhY2t9KVxufVxuXG4vKipcbiAqIFJ1bnMgYWZ0ZXIgYWxsLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3Rlc3QtcnVubmVyLmpzXCIpLkJlZm9yZUFmdGVyQWxsQ2FsbGJhY2tUeXBlfSBjYWxsYmFjayAtIENhbGxiYWNrIGZ1bmN0aW9uLlxuICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICovXG5mdW5jdGlvbiBhZnRlckFsbChjYWxsYmFjaykge1xuICBjb25zdCBjdXJyZW50VGVzdCA9IGN1cnJlbnRQYXRoW2N1cnJlbnRQYXRoLmxlbmd0aCAtIDFdXG5cbiAgY3VycmVudFRlc3QuYWZ0ZXJBbGxzLnB1c2goe2NhbGxiYWNrfSlcbn1cblxuLyoqXG4gKiBSdW5zIGRlc2NyaWJlLlxuICogQHBhcmFtIHtzdHJpbmd9IGRlc2NyaXB0aW9uIC0gRGVzY3JpcHRpb24uXG4gKiBAcGFyYW0ge29iamVjdHwoKCkgPT4gKHZvaWR8UHJvbWlzZTx2b2lkPikpfSBhcmcxIC0gQXJnMS5cbiAqIEBwYXJhbSB7dW5kZWZpbmVkfCgoKSA9PiAodm9pZHxQcm9taXNlPHZvaWQ+KSl9IFthcmcyXSAtIEFyZzIuXG4gKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICovXG5hc3luYyBmdW5jdGlvbiBkZXNjcmliZShkZXNjcmlwdGlvbiwgYXJnMSwgYXJnMikge1xuICAvKipcbiAgICogRGVmaW5lcyB0ZXN0QXJncy5cbiAgICogQHR5cGUge1JlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gKi9cbiAgbGV0IHRlc3RBcmdzLCB0ZXN0RnVuY3Rpb25cblxuICBpZiAodHlwZW9mIGFyZzIgPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgdGVzdEZ1bmN0aW9uID0gYXJnMlxuICAgIHRlc3RBcmdzID0gYXJnMVxuICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcxID09IFwiZnVuY3Rpb25cIikge1xuICAgIHRlc3RGdW5jdGlvbiA9IGFyZzFcbiAgICB0ZXN0QXJncyA9IHt9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGFyZ3VtZW50cyBmb3IgZGVzY3JpYmU6ICR7YXJnMX0sICR7YXJnMn1gKVxuICB9XG5cbiAgY29uc3QgY3VycmVudFRlc3QgPSBjdXJyZW50UGF0aFtjdXJyZW50UGF0aC5sZW5ndGggLSAxXVxuICBjb25zdCBuZXdUZXN0QXJncyA9IG1lcmdlVGVzdEFyZ3MoY3VycmVudFRlc3QuYXJncywgdGVzdEFyZ3MpXG5cbiAgaWYgKGRlc2NyaXB0aW9uIGluIGN1cnJlbnRUZXN0LnN1YnMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYER1cGxpY2F0ZSB0ZXN0IGRlc2NyaXB0aW9uOiAke2Rlc2NyaXB0aW9ufWApXG4gIH1cblxuICBjb25zdCBsb2NhdGlvbiA9IGNhcHR1cmVMb2NhdGlvbigpXG4gIGNvbnN0IG5ld1Rlc3REYXRhID0ge1xuICAgIGFmdGVyRWFjaGVzOiBbXSxcbiAgICBhZnRlckFsbHM6IFtdLFxuICAgIGFyZ3M6IG5ld1Rlc3RBcmdzLFxuICAgIGJlZm9yZUFsbHM6IFtdLFxuICAgIGJlZm9yZUVhY2hlczogW10sXG4gICAgZmlsZVBhdGg6IGxvY2F0aW9uLmZpbGVQYXRoLFxuICAgIGxpbmU6IGxvY2F0aW9uLmxpbmUsXG4gICAgc3Viczoge30sXG4gICAgdGVzdHM6IHt9XG4gIH1cblxuICBjdXJyZW50VGVzdC5zdWJzW2Rlc2NyaXB0aW9uXSA9IG5ld1Rlc3REYXRhXG4gIGN1cnJlbnRQYXRoLnB1c2gobmV3VGVzdERhdGEpXG5cbiAgdHJ5IHtcbiAgICBhd2FpdCB0ZXN0RnVuY3Rpb24oKVxuICB9IGZpbmFsbHkge1xuICAgIGN1cnJlbnRQYXRoLnBvcCgpXG4gIH1cbn1cblxuLyoqXG4gKiBSdW5zIGV4cGVjdC5cbiAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IGFyZyAtIEFyZy5cbiAqIEByZXR1cm5zIHtFeHBlY3R9IC0gVGhlIGV4cGVjdC5cbiAqL1xuZnVuY3Rpb24gZXhwZWN0KGFyZykge1xuICByZXR1cm4gbmV3IEV4cGVjdChhcmcpXG59XG5cbmV4cGVjdC5vYmplY3RDb250YWluaW5nID0gb2JqZWN0Q29udGFpbmluZ1xuZXhwZWN0LmFycmF5Q29udGFpbmluZyA9IGFycmF5Q29udGFpbmluZ1xuXG4vKipcbiAqIFJ1bnMgaXQuXG4gKiBAcGFyYW0ge3N0cmluZ30gZGVzY3JpcHRpb24gLSBEZXNjcmlwdGlvbi5cbiAqIEBwYXJhbSB7b2JqZWN0fCgoKSA9PiAodm9pZHxQcm9taXNlPHZvaWQ+KSl9IGFyZzEgLSBBcmcxLlxuICogQHBhcmFtIHt1bmRlZmluZWR8KCgpID0+ICh2b2lkfFByb21pc2U8dm9pZD4pKX0gW2FyZzJdIC0gQXJnMi5cbiAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gaXQoZGVzY3JpcHRpb24sIGFyZzEsIGFyZzIpIHtcbiAgY29uc3QgY3VycmVudFRlc3QgPSBjdXJyZW50UGF0aFtjdXJyZW50UGF0aC5sZW5ndGggLSAxXVxuICAvKipcbiAgICogRGVmaW5lcyB0ZXN0QXJncy5cbiAgICogQHR5cGUge1JlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gKi9cbiAgbGV0IHRlc3RBcmdzXG5cbiAgLyoqXG4gICAqIERlZmluZXMgdGVzdEZ1bmN0aW9uLlxuICAgKiBAdHlwZSB7KCkgPT4gKHZvaWR8UHJvbWlzZTx2b2lkPil9ICovXG4gIGxldCB0ZXN0RnVuY3Rpb25cblxuICBpZiAodHlwZW9mIGFyZzEgPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgdGVzdEZ1bmN0aW9uID0gLyoqIEB0eXBlIHsoKSA9PiAodm9pZHxQcm9taXNlPHZvaWQ+KX0gKi8gKGFyZzEpXG4gICAgdGVzdEFyZ3MgPSB7fVxuICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcyID09IFwiZnVuY3Rpb25cIikge1xuICAgIHRlc3RGdW5jdGlvbiA9IC8qKiBAdHlwZSB7KCkgPT4gKHZvaWR8UHJvbWlzZTx2b2lkPil9ICovIChhcmcyKVxuICAgIHRlc3RBcmdzID0gYXJnMVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBhcmd1bWVudHMgZm9yIGl0OiAke2Rlc2NyaXB0aW9ufSwgJHthcmcxfWApXG4gIH1cblxuICBjb25zdCBuZXdUZXN0QXJncyA9IG1lcmdlVGVzdEFyZ3MoY3VycmVudFRlc3QuYXJncywgdGVzdEFyZ3MpXG5cbiAgY29uc3QgbG9jYXRpb24gPSBjYXB0dXJlTG9jYXRpb24oKVxuXG4gIGN1cnJlbnRUZXN0LnRlc3RzW2Rlc2NyaXB0aW9uXSA9IHtcbiAgICBhcmdzOiBuZXdUZXN0QXJncyxcbiAgICBmdW5jdGlvbjogdGVzdEZ1bmN0aW9uLFxuICAgIGZpbGVQYXRoOiBsb2NhdGlvbi5maWxlUGF0aCxcbiAgICBsaW5lOiBsb2NhdGlvbi5saW5lXG4gIH1cbn1cblxuLyoqXG4gKiBSdW5zIGZpdC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBkZXNjcmlwdGlvbiAtIERlc2NyaXB0aW9uLlxuICogQHBhcmFtIHtvYmplY3R8KCgpID0+ICh2b2lkfFByb21pc2U8dm9pZD4pKX0gYXJnMSAtIEFyZzEuXG4gKiBAcGFyYW0ge3VuZGVmaW5lZHwoKCkgPT4gKHZvaWR8UHJvbWlzZTx2b2lkPikpfSBbYXJnMl0gLSBBcmcyLlxuICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICovXG5mdW5jdGlvbiBmaXQoZGVzY3JpcHRpb24sIGFyZzEsIGFyZzIpIHtcbiAgLyoqXG4gICAqIERlZmluZXMgdGVzdEFyZ3MuXG4gICAqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59ICovXG4gIGxldCB0ZXN0QXJnc1xuXG4gIC8qKlxuICAgKiBEZWZpbmVzIHRlc3RGdW5jdGlvbi5cbiAgICogQHR5cGUgeygpID0+ICh2b2lkfFByb21pc2U8dm9pZD4pfSAqL1xuICBsZXQgdGVzdEZ1bmN0aW9uXG5cbiAgaWYgKHR5cGVvZiBhcmcxID09IFwiZnVuY3Rpb25cIikge1xuICAgIHRlc3RGdW5jdGlvbiA9IC8qKiBAdHlwZSB7KCkgPT4gKHZvaWR8UHJvbWlzZTx2b2lkPil9ICovIChhcmcxKVxuICAgIHRlc3RBcmdzID0ge2ZvY3VzOiB0cnVlfVxuICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcyID09IFwiZnVuY3Rpb25cIikge1xuICAgIHRlc3RGdW5jdGlvbiA9IC8qKiBAdHlwZSB7KCkgPT4gKHZvaWR8UHJvbWlzZTx2b2lkPil9ICovIChhcmcyKVxuICAgIHRlc3RBcmdzID0gT2JqZWN0LmFzc2lnbih7Zm9jdXM6IHRydWV9LCBhcmcxKVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBhcmd1bWVudHMgZm9yIGl0OiAke2Rlc2NyaXB0aW9ufSwgJHthcmcxfWApXG4gIH1cblxuICByZXR1cm4gaXQoZGVzY3JpcHRpb24sIHRlc3RBcmdzLCB0ZXN0RnVuY3Rpb24pXG59XG5cbi8vIE1ha2UgdGhlIG1ldGhvZHMgZ2xvYmFsIHNvIHRoZXkgY2FuIGJlIHVzZWQgaW4gdGVzdCBmaWxlc1xuT2JqZWN0LmFzc2lnbihnbG9iYWxUaGlzLCB7XG4gIGFmdGVyQWxsLFxuICBhZnRlckVhY2gsXG4gIGJlZm9yZUFsbCxcbiAgYmVmb3JlRWFjaCxcbiAgY29uZmlndXJlVGVzdHMsXG4gIGRlc2NyaWJlLFxuICBleHBlY3QsXG4gIGZpdCxcbiAgaXQsXG4gIHRlc3RFdmVudHNcbn0pXG5cbmV4cG9ydCB7YWZ0ZXJBbGwsIGFmdGVyRWFjaCwgYmVmb3JlQWxsLCBiZWZvcmVFYWNoLCBjb25maWd1cmVUZXN0cywgZGVzY3JpYmUsIGV4cGVjdCwgZml0LCBpdCwgYXJyYXlDb250YWluaW5nLCBvYmplY3RDb250YWluaW5nLCB0ZXN0Q29uZmlnLCB0ZXN0RXZlbnRzLCB0ZXN0cywgd2FpdEZvckV2ZW50fVxuIl19
|
|
321
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90ZXN0aW5nL3Rlc3QuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQTtBQUN2QixPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0sS0FBSyxDQUFBO0FBQ2pDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUNqRCxPQUFPLFlBQVksTUFBTSwyQkFBMkIsQ0FBQTtBQUNwRCxPQUFPLE1BQU0sTUFBTSxhQUFhLENBQUE7QUFDaEMsT0FBTyxFQUFDLGVBQWUsRUFBRSxnQkFBZ0IsRUFBQyxNQUFNLG1CQUFtQixDQUFBO0FBRW5FOzs7Ozs7O0dBT0c7QUFDSDs7c0RBRXNEO0FBQ3RELE1BQU0sS0FBSyxHQUFHO0lBQ1o7O2dGQUU0RTtJQUM1RSxXQUFXLEVBQUUsRUFBRTtJQUNmOzsrRUFFMkU7SUFDM0UsU0FBUyxFQUFFLEVBQUU7SUFDYixJQUFJLEVBQUUsRUFBRTtJQUVSOzsrRUFFMkU7SUFDM0UsVUFBVSxFQUFFLEVBQUU7SUFDZDs7Z0ZBRTRFO0lBQzVFLFlBQVksRUFBRSxFQUFFO0lBQ2hCLFFBQVEsRUFBRSxTQUFTO0lBQ25CLElBQUksRUFBRSxTQUFTO0lBQ2YsSUFBSSxFQUFFLEVBQUU7SUFDUixLQUFLLEVBQUUsRUFBRTtDQUNWLENBQUE7QUFFRCxNQUFNLFVBQVUsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFBO0FBRXJDLElBQUksV0FBVyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUE7QUFFekI7OztHQUdHO0FBQ0gsU0FBUyxlQUFlO0lBQ3RCLE1BQU0sS0FBSyxHQUFHLElBQUksS0FBSyxFQUFFLENBQUE7SUFDekIsTUFBTSxLQUFLLEdBQUcsT0FBTyxLQUFLLENBQUMsS0FBSyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMs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Ii8vIEB0cy1jaGVja1xuXG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiXG5pbXBvcnQge2ZpbGVVUkxUb1BhdGh9IGZyb20gXCJ1cmxcIlxuaW1wb3J0IHsgd2FpdEZvckV2ZW50IH0gZnJvbSBcIkB2ZWxvY2lvdXMvdGVzdGluZ1wiXG5pbXBvcnQgRXZlbnRFbWl0dGVyIGZyb20gXCIuLi91dGlscy9ldmVudC1lbWl0dGVyLmpzXCJcbmltcG9ydCBFeHBlY3QgZnJvbSBcIi4vZXhwZWN0LmpzXCJcbmltcG9ydCB7YXJyYXlDb250YWluaW5nLCBvYmplY3RDb250YWluaW5nfSBmcm9tIFwiLi9leHBlY3QtdXRpbHMuanNcIlxuXG4vKipcbiAqIFZlbG9jaW91c1Rlc3RDb25maWcgdHlwZS5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IFZlbG9jaW91c1Rlc3RDb25maWdcbiAqIEBwcm9wZXJ0eSB7XCJmYWlsdXJlXCIgfCBcImxpdmVcIn0gY29uc29sZU91dHB1dCAtIENvbnNvbGUgb3V0cHV0IG1vZGUuXG4gKiBAcHJvcGVydHkge3N0cmluZ1tdfSBleGNsdWRlVGFncyAtIFRhZ3MgZXhjbHVkZWQgYnkgZGVmYXVsdC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBkZWZhdWx0VGltZW91dFNlY29uZHMgLSBEZWZhdWx0IHRpbWVvdXQgaW4gc2Vjb25kcy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBmYWlsZWRDb25zb2xlT3V0cHV0TWF4TGluZXMgLSBNYXhpbXVtIGZhaWxlZCBjb25zb2xlIGxpbmVzIHRvIHByaW50IGlubGluZS5cbiAqL1xuLyoqXG4gKiBUZXN0cy5cbiAqIEB0eXBlIHtpbXBvcnQoXCIuL3Rlc3QtcnVubmVyLmpzXCIpLlRlc3RzQXJndW1lbnR9ICovXG5jb25zdCB0ZXN0cyA9IHtcbiAgLyoqXG4gICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICogQHR5cGUge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuQWZ0ZXJCZWZvcmVFYWNoQ2FsbGJhY2tPYmplY3RUeXBlW119ICovXG4gIGFmdGVyRWFjaGVzOiBbXSxcbiAgLyoqXG4gICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICogQHR5cGUge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuQmVmb3JlQWZ0ZXJBbGxDYWxsYmFja09iamVjdFR5cGVbXX0gKi9cbiAgYWZ0ZXJBbGxzOiBbXSxcbiAgYXJnczoge30sXG5cbiAgLyoqXG4gICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICogQHR5cGUge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuQmVmb3JlQWZ0ZXJBbGxDYWxsYmFja09iamVjdFR5cGVbXX0gKi9cbiAgYmVmb3JlQWxsczogW10sXG4gIC8qKlxuICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAqIEB0eXBlIHtpbXBvcnQoXCIuL3Rlc3QtcnVubmVyLmpzXCIpLkFmdGVyQmVmb3JlRWFjaENhbGxiYWNrT2JqZWN0VHlwZVtdfSAqL1xuICBiZWZvcmVFYWNoZXM6IFtdLFxuICBmaWxlUGF0aDogdW5kZWZpbmVkLFxuICBsaW5lOiB1bmRlZmluZWQsXG4gIHN1YnM6IHt9LFxuICB0ZXN0czoge31cbn1cblxuY29uc3QgdGVzdEV2ZW50cyA9IG5ldyBFdmVudEVtaXR0ZXIoKVxuXG5sZXQgY3VycmVudFBhdGggPSBbdGVzdHNdXG5cbi8qKlxuICogUnVucyBjYXB0dXJlIGxvY2F0aW9uLlxuICogQHJldHVybnMge3tmaWxlUGF0aD86IHN0cmluZywgbGluZT86IG51bWJlcn19IC0gTG9jYXRpb24uXG4gKi9cbmZ1bmN0aW9uIGNhcHR1cmVMb2NhdGlvbigpIHtcbiAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoKVxuICBjb25zdCBzdGFjayA9IHR5cGVvZiBlcnJvci5zdGFjayA9PT0gXCJzdHJpbmdcIiA/IGVycm9yLnN0YWNrLnNwbGl0KFwiXFxuXCIpIDogW11cblxuICBmb3IgKGNvbnN0IGxpbmUgb2Ygc3RhY2spIHtcbiAgICBjb25zdCB0cmltbWVkID0gbGluZS50cmltKClcblxuICAgIGlmICghdHJpbW1lZC5pbmNsdWRlcyhcImF0XCIpKSBjb250aW51ZVxuICAgIGlmICh0cmltbWVkLmluY2x1ZGVzKFwiL3NyYy90ZXN0aW5nL3Rlc3QuanNcIikpIGNvbnRpbnVlXG5cbiAgICBjb25zdCBtYXRjaCA9IHRyaW1tZWQubWF0Y2goLyg/OlxcKHxcXHMpKGZpbGU6XFwvXFwvLio/fFxcLy4qPyk6KFxcZCspOihcXGQrKVxcKT8kLylcblxuICAgIGlmICghbWF0Y2gpIGNvbnRpbnVlXG5cbiAgICBjb25zdCByYXdQYXRoID0gbWF0Y2hbMV1cbiAgICBjb25zdCBsaW5lTnVtYmVyID0gTnVtYmVyKG1hdGNoWzJdKVxuICAgIGNvbnN0IGZpbGVQYXRoID0gcmF3UGF0aC5zdGFydHNXaXRoKFwiZmlsZTovL1wiKVxuICAgICAgPyBmaWxlVVJMVG9QYXRoKHJhd1BhdGgpXG4gICAgICA6IHJhd1BhdGhcblxuICAgIHJldHVybiB7XG4gICAgICBmaWxlUGF0aDogcGF0aC5yZXNvbHZlKGZpbGVQYXRoKSxcbiAgICAgIGxpbmU6IE51bWJlci5pc0Zpbml0ZShsaW5lTnVtYmVyKSA/IGxpbmVOdW1iZXIgOiB1bmRlZmluZWRcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge31cbn1cblxuLyoqXG4gKiBSdW5zIG5vcm1hbGl6ZSB0YWdzLlxuICogQHBhcmFtIHtzdHJpbmdbXSB8IHN0cmluZyB8IHVuZGVmaW5lZH0gdGFncyAtIFRhZ3MuXG4gKiBAcmV0dXJucyB7c3RyaW5nW119IC0gTm9ybWFsaXplZCB0YWdzLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVUYWdzKHRhZ3MpIHtcbiAgaWYgKCF0YWdzKSByZXR1cm4gW11cblxuICBjb25zdCB2YWx1ZXMgPSBbXVxuICBjb25zdCByYXdUYWdzID0gQXJyYXkuaXNBcnJheSh0YWdzKSA/IHRhZ3MgOiBbdGFnc11cblxuICBmb3IgKGNvbnN0IHJhd1RhZyBvZiByYXdUYWdzKSB7XG4gICAgaWYgKHJhd1RhZyA9PT0gdW5kZWZpbmVkIHx8IHJhd1RhZyA9PT0gbnVsbCkgY29udGludWVcblxuICAgIGNvbnN0IHBhcnRzID0gU3RyaW5nKHJhd1RhZykuc3BsaXQoXCIsXCIpXG5cbiAgICBmb3IgKGNvbnN0IHBhcnQgb2YgcGFydHMpIHtcbiAgICAgIGNvbnN0IHRyaW1tZWQgPSBwYXJ0LnRyaW0oKVxuXG4gICAgICBpZiAodHJpbW1lZCkgdmFsdWVzLnB1c2godHJpbW1lZClcbiAgICB9XG4gIH1cblxuICByZXR1cm4gQXJyYXkuZnJvbShuZXcgU2V0KHZhbHVlcykpXG59XG5cbi8qKlxuICogVGVzdCBjb25maWcuXG4gKiBAdHlwZSB7VmVsb2Npb3VzVGVzdENvbmZpZ30gKi9cbmNvbnN0IHRlc3RDb25maWcgPSB7XG4gIGNvbnNvbGVPdXRwdXQ6IFwiZmFpbHVyZVwiLFxuICBmYWlsZWRDb25zb2xlT3V0cHV0TWF4TGluZXM6IDIwMCxcbiAgZXhjbHVkZVRhZ3M6IFtdLFxuICBkZWZhdWx0VGltZW91dFNlY29uZHM6IDYwXG59XG5cbi8qKlxuICogUnVucyBjb25maWd1cmUgdGVzdHMuXG4gKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMuXG4gKiBAcGFyYW0ge1wiZmFpbHVyZVwiIHwgXCJsaXZlXCJ9IFthcmdzLmNvbnNvbGVPdXRwdXRdIC0gQ29uc29sZSBvdXRwdXQgbW9kZS5cbiAqIEBwYXJhbSB7c3RyaW5nW10gfCBzdHJpbmd9IFthcmdzLmV4Y2x1ZGVUYWdzXSAtIFRhZ3MgdG8gZXhjbHVkZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJncy5kZWZhdWx0VGltZW91dFNlY29uZHNdIC0gRGVmYXVsdCB0aW1lb3V0IGluIHNlY29uZHMuXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyZ3MuZmFpbGVkQ29uc29sZU91dHB1dE1heExpbmVzXSAtIE1heGltdW0gZmFpbGVkIGNvbnNvbGUgbGluZXMgdG8gcHJpbnQgaW5saW5lLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIGNvbmZpZ3VyZVRlc3RzKHtjb25zb2xlT3V0cHV0LCBleGNsdWRlVGFncywgZGVmYXVsdFRpbWVvdXRTZWNvbmRzLCBmYWlsZWRDb25zb2xlT3V0cHV0TWF4TGluZXN9ID0ge30pIHtcbiAgaWYgKGV4Y2x1ZGVUYWdzICE9PSB1bmRlZmluZWQpIHtcbiAgICB0ZXN0Q29uZmlnLmV4Y2x1ZGVUYWdzID0gbm9ybWFsaXplVGFncyhleGNsdWRlVGFncylcbiAgfVxuXG4gIGlmIChjb25zb2xlT3V0cHV0ICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoY29uc29sZU91dHB1dCAhPT0gXCJmYWlsdXJlXCIgJiYgY29uc29sZU91dHB1dCAhPT0gXCJsaXZlXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBjb25zb2xlT3V0cHV0IGNvbmZpZzogJHtjb25zb2xlT3V0cHV0fWApXG4gICAgfVxuXG4gICAgdGVzdENvbmZpZy5jb25zb2xlT3V0cHV0ID0gY29uc29sZU91dHB1dFxuICB9XG5cbiAgaWYgKHR5cGVvZiBkZWZhdWx0VGltZW91dFNlY29uZHMgPT09IFwibnVtYmVyXCIpIHtcbiAgICB0ZXN0Q29uZmlnLmRlZmF1bHRUaW1lb3V0U2Vjb25kcyA9IGRlZmF1bHRUaW1lb3V0U2Vjb25kc1xuICB9XG5cbiAgaWYgKHR5cGVvZiBmYWlsZWRDb25zb2xlT3V0cHV0TWF4TGluZXMgPT09IFwibnVtYmVyXCIpIHtcbiAgICB0ZXN0Q29uZmlnLmZhaWxlZENvbnNvbGVPdXRwdXRNYXhMaW5lcyA9IGZhaWxlZENvbnNvbGVPdXRwdXRNYXhMaW5lc1xuICB9XG59XG5cbi8qKlxuICogUnVucyBtZXJnZSB0ZXN0IGFyZ3MuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gYmFzZUFyZ3MgLSBCYXNlIGFyZ3MuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gZXh0cmFBcmdzIC0gRXh0cmEgYXJncy5cbiAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59IC0gTWVyZ2VkIGFyZ3MuXG4gKi9cbmZ1bmN0aW9uIG1lcmdlVGVzdEFyZ3MoYmFzZUFyZ3MsIGV4dHJhQXJncykge1xuICBjb25zdCBtZXJnZWQgPSBPYmplY3QuYXNzaWduKHt9LCBiYXNlQXJncywgZXh0cmFBcmdzKVxuICBjb25zdCBtZXJnZWRUYWdzID0gWy4uLm5vcm1hbGl6ZVRhZ3MoYmFzZUFyZ3M/LnRhZ3MpLCAuLi5ub3JtYWxpemVUYWdzKGV4dHJhQXJncz8udGFncyldXG5cbiAgaWYgKG1lcmdlZFRhZ3MubGVuZ3RoID4gMCkge1xuICAgIG1lcmdlZC50YWdzID0gQXJyYXkuZnJvbShuZXcgU2V0KG1lcmdlZFRhZ3MpKVxuICB9IGVsc2UgaWYgKFwidGFnc1wiIGluIG1lcmdlZCkge1xuICAgIGRlbGV0ZSBtZXJnZWQudGFnc1xuICB9XG5cbiAgcmV0dXJuIG1lcmdlZFxufVxuXG4vKipcbiAqIFJ1bnMgYmVmb3JlIGVhY2guXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuQWZ0ZXJCZWZvcmVFYWNoQ2FsbGJhY2tUeXBlfSBjYWxsYmFjayAtIENhbGxiYWNrIGZ1bmN0aW9uLlxuICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICovXG5mdW5jdGlvbiBiZWZvcmVFYWNoKGNhbGxiYWNrKSB7XG4gIGNvbnN0IGN1cnJlbnRUZXN0ID0gY3VycmVudFBhdGhbY3VycmVudFBhdGgubGVuZ3RoIC0gMV1cblxuICBjdXJyZW50VGVzdC5iZWZvcmVFYWNoZXMucHVzaCh7Y2FsbGJhY2t9KVxufVxuXG4vKipcbiAqIFJ1bnMgYmVmb3JlIGFsbC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90ZXN0LXJ1bm5lci5qc1wiKS5CZWZvcmVBZnRlckFsbENhbGxiYWNrVHlwZX0gY2FsbGJhY2sgLSBDYWxsYmFjayBmdW5jdGlvbi5cbiAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gYmVmb3JlQWxsKGNhbGxiYWNrKSB7XG4gIGNvbnN0IGN1cnJlbnRUZXN0ID0gY3VycmVudFBhdGhbY3VycmVudFBhdGgubGVuZ3RoIC0gMV1cblxuICBjdXJyZW50VGVzdC5iZWZvcmVBbGxzLnB1c2goe2NhbGxiYWNrfSlcbn1cblxuLyoqXG4gKiBSdW5zIGFmdGVyIGVhY2guXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdGVzdC1ydW5uZXIuanNcIikuQWZ0ZXJCZWZvcmVFYWNoQ2FsbGJhY2tUeXBlfSBjYWxsYmFjayAtIENhbGxiYWNrIGZ1bmN0aW9uLlxuICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICovXG5mdW5jdGlvbiBhZnRlckVhY2goY2FsbGJhY2spIHtcbiAgY29uc3QgY3VycmVudFRlc3QgPSBjdXJyZW50UGF0aFtjdXJyZW50UGF0aC5sZW5ndGggLSAxXVxuXG4gIGN1cnJlbnRUZXN0LmFmdGVyRWFjaGVzLnB1c2goe2NhbGxiYWNrfSlcbn1cblxuLyoqXG4gKiBSdW5zIGFmdGVyIGFsbC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90ZXN0LXJ1bm5lci5qc1wiKS5CZWZvcmVBZnRlckFsbENhbGxiYWNrVHlwZX0gY2FsbGJhY2sgLSBDYWxsYmFjayBmdW5jdGlvbi5cbiAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gYWZ0ZXJBbGwoY2FsbGJhY2spIHtcbiAgY29uc3QgY3VycmVudFRlc3QgPSBjdXJyZW50UGF0aFtjdXJyZW50UGF0aC5sZW5ndGggLSAxXVxuXG4gIGN1cnJlbnRUZXN0LmFmdGVyQWxscy5wdXNoKHtjYWxsYmFja30pXG59XG5cbi8qKlxuICogUnVucyBkZXNjcmliZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBkZXNjcmlwdGlvbiAtIERlc2NyaXB0aW9uLlxuICogQHBhcmFtIHtvYmplY3R8KCgpID0+ICh2b2lkfFByb21pc2U8dm9pZD4pKX0gYXJnMSAtIEFyZzEuXG4gKiBAcGFyYW0ge3VuZGVmaW5lZHwoKCkgPT4gKHZvaWR8UHJvbWlzZTx2b2lkPikpfSBbYXJnMl0gLSBBcmcyLlxuICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZGVzY3JpYmUoZGVzY3JpcHRpb24sIGFyZzEsIGFyZzIpIHtcbiAgLyoqXG4gICAqIERlZmluZXMgdGVzdEFyZ3MuXG4gICAqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59ICovXG4gIGxldCB0ZXN0QXJncywgdGVzdEZ1bmN0aW9uXG5cbiAgaWYgKHR5cGVvZiBhcmcyID09IFwiZnVuY3Rpb25cIikge1xuICAgIHRlc3RGdW5jdGlvbiA9IGFyZzJcbiAgICB0ZXN0QXJncyA9IGFyZzFcbiAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMSA9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICB0ZXN0RnVuY3Rpb24gPSBhcmcxXG4gICAgdGVzdEFyZ3MgPSB7fVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBhcmd1bWVudHMgZm9yIGRlc2NyaWJlOiAke2FyZzF9LCAke2FyZzJ9YClcbiAgfVxuXG4gIGNvbnN0IGN1cnJlbnRUZXN0ID0gY3VycmVudFBhdGhbY3VycmVudFBhdGgubGVuZ3RoIC0gMV1cbiAgY29uc3QgbmV3VGVzdEFyZ3MgPSBtZXJnZVRlc3RBcmdzKGN1cnJlbnRUZXN0LmFyZ3MsIHRlc3RBcmdzKVxuXG4gIGlmIChkZXNjcmlwdGlvbiBpbiBjdXJyZW50VGVzdC5zdWJzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBEdXBsaWNhdGUgdGVzdCBkZXNjcmlwdGlvbjogJHtkZXNjcmlwdGlvbn1gKVxuICB9XG5cbiAgY29uc3QgbG9jYXRpb24gPSBjYXB0dXJlTG9jYXRpb24oKVxuICBjb25zdCBuZXdUZXN0RGF0YSA9IHtcbiAgICBhZnRlckVhY2hlczogW10sXG4gICAgYWZ0ZXJBbGxzOiBbXSxcbiAgICBhcmdzOiBuZXdUZXN0QXJncyxcbiAgICBiZWZvcmVBbGxzOiBbXSxcbiAgICBiZWZvcmVFYWNoZXM6IFtdLFxuICAgIGZpbGVQYXRoOiBsb2NhdGlvbi5maWxlUGF0aCxcbiAgICBsaW5lOiBsb2NhdGlvbi5saW5lLFxuICAgIHN1YnM6IHt9LFxuICAgIHRlc3RzOiB7fVxuICB9XG5cbiAgY3VycmVudFRlc3Quc3Vic1tkZXNjcmlwdGlvbl0gPSBuZXdUZXN0RGF0YVxuICBjdXJyZW50UGF0aC5wdXNoKG5ld1Rlc3REYXRhKVxuXG4gIHRyeSB7XG4gICAgYXdhaXQgdGVzdEZ1bmN0aW9uKClcbiAgfSBmaW5hbGx5IHtcbiAgICBjdXJyZW50UGF0aC5wb3AoKVxuICB9XG59XG5cbi8qKlxuICogUnVucyBleHBlY3QuXG4gKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSBhcmcgLSBBcmcuXG4gKiBAcmV0dXJucyB7RXhwZWN0fSAtIFRoZSBleHBlY3QuXG4gKi9cbmZ1bmN0aW9uIGV4cGVjdChhcmcpIHtcbiAgcmV0dXJuIG5ldyBFeHBlY3QoYXJnKVxufVxuXG5leHBlY3Qub2JqZWN0Q29udGFpbmluZyA9IG9iamVjdENvbnRhaW5pbmdcbmV4cGVjdC5hcnJheUNvbnRhaW5pbmcgPSBhcnJheUNvbnRhaW5pbmdcblxuLyoqXG4gKiBSdW5zIGl0LlxuICogQHBhcmFtIHtzdHJpbmd9IGRlc2NyaXB0aW9uIC0gRGVzY3JpcHRpb24uXG4gKiBAcGFyYW0ge29iamVjdHwoKCkgPT4gKHZvaWR8UHJvbWlzZTx2b2lkPikpfSBhcmcxIC0gQXJnMS5cbiAqIEBwYXJhbSB7dW5kZWZpbmVkfCgoKSA9PiAodm9pZHxQcm9taXNlPHZvaWQ+KSl9IFthcmcyXSAtIEFyZzIuXG4gKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIGl0KGRlc2NyaXB0aW9uLCBhcmcxLCBhcmcyKSB7XG4gIGNvbnN0IGN1cnJlbnRUZXN0ID0gY3VycmVudFBhdGhbY3VycmVudFBhdGgubGVuZ3RoIC0gMV1cbiAgLyoqXG4gICAqIERlZmluZXMgdGVzdEFyZ3MuXG4gICAqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59ICovXG4gIGxldCB0ZXN0QXJnc1xuXG4gIC8qKlxuICAgKiBEZWZpbmVzIHRlc3RGdW5jdGlvbi5cbiAgICogQHR5cGUgeygpID0+ICh2b2lkfFByb21pc2U8dm9pZD4pfSAqL1xuICBsZXQgdGVzdEZ1bmN0aW9uXG5cbiAgaWYgKHR5cGVvZiBhcmcxID09IFwiZnVuY3Rpb25cIikge1xuICAgIHRlc3RGdW5jdGlvbiA9IC8qKiBAdHlwZSB7KCkgPT4gKHZvaWR8UHJvbWlzZTx2b2lkPil9ICovIChhcmcxKVxuICAgIHRlc3RBcmdzID0ge31cbiAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMiA9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICB0ZXN0RnVuY3Rpb24gPSAvKiogQHR5cGUgeygpID0+ICh2b2lkfFByb21pc2U8dm9pZD4pfSAqLyAoYXJnMilcbiAgICB0ZXN0QXJncyA9IGFyZzFcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgYXJndW1lbnRzIGZvciBpdDogJHtkZXNjcmlwdGlvbn0sICR7YXJnMX1gKVxuICB9XG5cbiAgY29uc3QgbmV3VGVzdEFyZ3MgPSBtZXJnZVRlc3RBcmdzKGN1cnJlbnRUZXN0LmFyZ3MsIHRlc3RBcmdzKVxuXG4gIGNvbnN0IGxvY2F0aW9uID0gY2FwdHVyZUxvY2F0aW9uKClcblxuICBjdXJyZW50VGVzdC50ZXN0c1tkZXNjcmlwdGlvbl0gPSB7XG4gICAgYXJnczogbmV3VGVzdEFyZ3MsXG4gICAgZnVuY3Rpb246IHRlc3RGdW5jdGlvbixcbiAgICBmaWxlUGF0aDogbG9jYXRpb24uZmlsZVBhdGgsXG4gICAgbGluZTogbG9jYXRpb24ubGluZVxuICB9XG59XG5cbi8qKlxuICogUnVucyBmaXQuXG4gKiBAcGFyYW0ge3N0cmluZ30gZGVzY3JpcHRpb24gLSBEZXNjcmlwdGlvbi5cbiAqIEBwYXJhbSB7b2JqZWN0fCgoKSA9PiAodm9pZHxQcm9taXNlPHZvaWQ+KSl9IGFyZzEgLSBBcmcxLlxuICogQHBhcmFtIHt1bmRlZmluZWR8KCgpID0+ICh2b2lkfFByb21pc2U8dm9pZD4pKX0gW2FyZzJdIC0gQXJnMi5cbiAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gZml0KGRlc2NyaXB0aW9uLCBhcmcxLCBhcmcyKSB7XG4gIC8qKlxuICAgKiBEZWZpbmVzIHRlc3RBcmdzLlxuICAgKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+fSAqL1xuICBsZXQgdGVzdEFyZ3NcblxuICAvKipcbiAgICogRGVmaW5lcyB0ZXN0RnVuY3Rpb24uXG4gICAqIEB0eXBlIHsoKSA9PiAodm9pZHxQcm9taXNlPHZvaWQ+KX0gKi9cbiAgbGV0IHRlc3RGdW5jdGlvblxuXG4gIGlmICh0eXBlb2YgYXJnMSA9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICB0ZXN0RnVuY3Rpb24gPSAvKiogQHR5cGUgeygpID0+ICh2b2lkfFByb21pc2U8dm9pZD4pfSAqLyAoYXJnMSlcbiAgICB0ZXN0QXJncyA9IHtmb2N1czogdHJ1ZX1cbiAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMiA9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICB0ZXN0RnVuY3Rpb24gPSAvKiogQHR5cGUgeygpID0+ICh2b2lkfFByb21pc2U8dm9pZD4pfSAqLyAoYXJnMilcbiAgICB0ZXN0QXJncyA9IE9iamVjdC5hc3NpZ24oe2ZvY3VzOiB0cnVlfSwgYXJnMSlcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgYXJndW1lbnRzIGZvciBpdDogJHtkZXNjcmlwdGlvbn0sICR7YXJnMX1gKVxuICB9XG5cbiAgcmV0dXJuIGl0KGRlc2NyaXB0aW9uLCB0ZXN0QXJncywgdGVzdEZ1bmN0aW9uKVxufVxuXG4vLyBNYWtlIHRoZSBtZXRob2RzIGdsb2JhbCBzbyB0aGV5IGNhbiBiZSB1c2VkIGluIHRlc3QgZmlsZXNcbk9iamVjdC5hc3NpZ24oZ2xvYmFsVGhpcywge1xuICBhZnRlckFsbCxcbiAgYWZ0ZXJFYWNoLFxuICBiZWZvcmVBbGwsXG4gIGJlZm9yZUVhY2gsXG4gIGNvbmZpZ3VyZVRlc3RzLFxuICBkZXNjcmliZSxcbiAgZXhwZWN0LFxuICBmaXQsXG4gIGl0LFxuICB0ZXN0RXZlbnRzXG59KVxuXG5leHBvcnQge2FmdGVyQWxsLCBhZnRlckVhY2gsIGJlZm9yZUFsbCwgYmVmb3JlRWFjaCwgY29uZmlndXJlVGVzdHMsIGRlc2NyaWJlLCBleHBlY3QsIGZpdCwgaXQsIGFycmF5Q29udGFpbmluZywgb2JqZWN0Q29udGFpbmluZywgdGVzdENvbmZpZywgdGVzdEV2ZW50cywgdGVzdHMsIHdhaXRGb3JFdmVudH1cbiJdfQ==
|
|
@@ -6,11 +6,12 @@ import { decodeBrokerValue, encodeBrokerValue } from "./shared-transaction-codec
|
|
|
6
6
|
export default class SharedTransactionBrokerClient {
|
|
7
7
|
/**
|
|
8
8
|
* Creates a broker client.
|
|
9
|
-
* @param {{address: string, capability: string, databaseIdentifier: string}} args - Broker coordinates.
|
|
9
|
+
* @param {{address: string, capability: string, databaseIdentifier: string, reuseKey?: string}} args - Broker coordinates.
|
|
10
10
|
*/
|
|
11
|
-
constructor({address, capability, databaseIdentifier}) {
|
|
11
|
+
constructor({address, capability, databaseIdentifier, reuseKey}) {
|
|
12
12
|
this.capability = capability
|
|
13
13
|
this.databaseIdentifier = databaseIdentifier
|
|
14
|
+
this.reuseKey = reuseKey
|
|
14
15
|
this.nextRequestId = 1
|
|
15
16
|
/** @type {Map<number, {reject: (error: Error) => void, resolve: (value: ReturnType<typeof decodeBrokerValue>) => void}>} */
|
|
16
17
|
this.pending = new Map()
|
|
@@ -46,6 +47,7 @@ export default class SharedTransactionBrokerClient {
|
|
|
46
47
|
requestId,
|
|
47
48
|
capability: this.capability,
|
|
48
49
|
databaseIdentifier: this.databaseIdentifier,
|
|
50
|
+
reuseKey: this.reuseKey,
|
|
49
51
|
method,
|
|
50
52
|
args: encodeBrokerValue(args)
|
|
51
53
|
}), (error) => {
|
|
@@ -80,15 +80,9 @@ export default class SharedTransactionBroker extends EventEmitter {
|
|
|
80
80
|
/** @type {Map<object, symbol>} */
|
|
81
81
|
this.connectionCoordinatorOwners = new Map()
|
|
82
82
|
for (const connection of new Set(Object.values(connections))) {
|
|
83
|
-
|
|
84
|
-
* Serializes parent operations with child broker traffic.
|
|
85
|
-
* @param {() => Promise<unknown>} callback - Parent operation.
|
|
86
|
-
* @returns {Promise<unknown>} - Operation result.
|
|
87
|
-
*/
|
|
88
|
-
const coordinator = async (callback) => await this.serialize(this.connectionState(connection), callback)
|
|
89
|
-
this.connectionCoordinators.set(connection, coordinator)
|
|
90
|
-
this.connectionCoordinatorOwners.set(connection, setSharedTransactionCoordinator(connection, coordinator))
|
|
83
|
+
this.installConnectionCoordinator(connection)
|
|
91
84
|
}
|
|
85
|
+
this.physicalConnections = new Map()
|
|
92
86
|
this.httpServer = createServer()
|
|
93
87
|
this.websocketServer = new WebSocketServer({server: this.httpServer, maxPayload: 16 * 1024 * 1024})
|
|
94
88
|
this.websocketServer.on("connection", (socket) => {
|
|
@@ -101,6 +95,37 @@ export default class SharedTransactionBroker extends EventEmitter {
|
|
|
101
95
|
})
|
|
102
96
|
}
|
|
103
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Installs serialization ownership for a newly enrolled physical connection.
|
|
100
|
+
* @param {object} connection - Parent-owned physical connection.
|
|
101
|
+
* @returns {void}
|
|
102
|
+
*/
|
|
103
|
+
installConnectionCoordinator(connection) {
|
|
104
|
+
if (this.connectionCoordinators.has(connection)) return
|
|
105
|
+
/**
|
|
106
|
+
* Serializes parent operations with child broker traffic.
|
|
107
|
+
* @param {() => Promise<unknown>} callback - Parent operation.
|
|
108
|
+
* @returns {Promise<unknown>} - Operation result.
|
|
109
|
+
*/
|
|
110
|
+
const coordinator = async (callback) => await this.serialize(this.connectionState(connection), callback)
|
|
111
|
+
this.connectionCoordinators.set(connection, coordinator)
|
|
112
|
+
this.connectionCoordinatorOwners.set(connection, setSharedTransactionCoordinator(connection, coordinator))
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Enrolls one exact physical database identity in this capability's rollback set.
|
|
117
|
+
* @param {{connection: object, databaseIdentifier: string, reuseKey: string}} args - Physical connection identity.
|
|
118
|
+
* @returns {void}
|
|
119
|
+
*/
|
|
120
|
+
enrollConnection({connection, databaseIdentifier, reuseKey}) {
|
|
121
|
+
if (!this.accepting) throw new Error("Shared transaction broker capability has been revoked")
|
|
122
|
+
const identity = `${databaseIdentifier}\0${reuseKey}`
|
|
123
|
+
const existing = this.physicalConnections.get(identity)
|
|
124
|
+
if (existing && existing !== connection) throw new Error(`Shared transaction physical connection identity is already enrolled: ${databaseIdentifier}`)
|
|
125
|
+
this.installConnectionCoordinator(connection)
|
|
126
|
+
this.physicalConnections.set(identity, connection)
|
|
127
|
+
}
|
|
128
|
+
|
|
104
129
|
/**
|
|
105
130
|
* Starts a broker on an ephemeral loopback port.
|
|
106
131
|
* @param {{connections: Record<string, object>}} args - Parent-owned physical connections.
|
|
@@ -140,18 +165,22 @@ export default class SharedTransactionBroker extends EventEmitter {
|
|
|
140
165
|
async handleRequest(socket, serialized) {
|
|
141
166
|
let requestId = 0
|
|
142
167
|
try {
|
|
143
|
-
const request = /** @type {{requestId: number, capability: string, databaseIdentifier: string, method: string, args: import("./shared-transaction-codec.js").EncodedBrokerValue}} */ (JSON.parse(serialized))
|
|
168
|
+
const request = /** @type {{requestId: number, capability: string, databaseIdentifier: string, reuseKey?: string, method: string, args: import("./shared-transaction-codec.js").EncodedBrokerValue}} */ (JSON.parse(serialized))
|
|
144
169
|
requestId = request.requestId
|
|
145
170
|
if (!this.accepting) throw new Error("Shared transaction broker capability has been revoked")
|
|
146
171
|
if (!capabilityMatches(request.capability, this.secret)) throw new Error("Unknown shared transaction broker capability")
|
|
147
|
-
const connection =
|
|
148
|
-
|
|
172
|
+
const connection = request.reuseKey
|
|
173
|
+
? this.physicalConnections.get(`${request.databaseIdentifier}\0${request.reuseKey}`)
|
|
174
|
+
: this.connections[request.databaseIdentifier]
|
|
175
|
+
if (!connection) {
|
|
176
|
+
if (request.reuseKey) throw new Error(`Unenrolled physical connection identity: ${request.databaseIdentifier}`)
|
|
177
|
+
throw new Error(`Unknown shared transaction database identifier: ${request.databaseIdentifier}`)
|
|
178
|
+
}
|
|
149
179
|
if (!ALLOWED_METHODS.has(request.method)) throw new Error(`Unsupported shared transaction broker method: ${request.method}`)
|
|
150
180
|
const args = decodeBrokerValue(request.args)
|
|
151
181
|
if (!Array.isArray(args)) throw new TypeError("Shared transaction broker arguments must be an array")
|
|
152
182
|
this.emit("work-queued", {connection, databaseIdentifier: request.databaseIdentifier, method: request.method})
|
|
153
183
|
const result = await this.runConnectionRequest({connection, method: request.method, savePointName: typeof args[0] === "string" ? args[0] : undefined, socket}, async () => {
|
|
154
|
-
if (!this.accepting) throw new Error("Shared transaction broker capability has been revoked")
|
|
155
184
|
if (request.method === "rootTransactionRollback") {
|
|
156
185
|
await this.rollbackRootSavePoint(connection, /** @type {string} */ (args[0]))
|
|
157
186
|
return undefined
|
|
@@ -258,10 +287,11 @@ export default class SharedTransactionBroker extends EventEmitter {
|
|
|
258
287
|
|
|
259
288
|
state.queue = previous.then(async () => {
|
|
260
289
|
try {
|
|
261
|
-
if (
|
|
290
|
+
if (socket.readyState !== socket.OPEN) throw new Error("Shared transaction broker root transaction session closed before lease acquisition")
|
|
262
291
|
const result = await callback()
|
|
263
292
|
state.lease = {operations: Promise.resolve(), release, savePointName, socket}
|
|
264
293
|
resolveStarted(result)
|
|
294
|
+
if (!this.accepting) await this.scheduleSessionCleanup(socket)
|
|
265
295
|
await held
|
|
266
296
|
} catch (error) {
|
|
267
297
|
state.rootSessions.delete(socket)
|
|
@@ -418,17 +448,29 @@ export default class SharedTransactionBroker extends EventEmitter {
|
|
|
418
448
|
return await this.closePromise
|
|
419
449
|
}
|
|
420
450
|
|
|
451
|
+
/** Revokes admission without interrupting already accepted work. */
|
|
452
|
+
revoke() {
|
|
453
|
+
if (!this.accepting) return
|
|
454
|
+
this.accepting = false
|
|
455
|
+
this.secret = randomBytes(32).toString("base64url")
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/** Drains all work accepted before capability revocation. */
|
|
459
|
+
async drain() {
|
|
460
|
+
if (this.accepting) throw new Error("Shared transaction broker must be revoked before drain")
|
|
461
|
+
await Promise.all(Array.from(this.connectionStates.values()).map((state) => state.queue))
|
|
462
|
+
}
|
|
463
|
+
|
|
421
464
|
/**
|
|
422
465
|
* Performs deterministic transport shutdown and reports cleanup failures last.
|
|
423
466
|
* @returns {Promise<void>} - Resolves after shutdown or rejects with cleanup errors.
|
|
424
467
|
*/
|
|
425
468
|
async closeTransport() {
|
|
426
|
-
this.
|
|
427
|
-
this.secret = randomBytes(32).toString("base64url")
|
|
469
|
+
this.revoke()
|
|
428
470
|
const closingSessions = Array.from(this.sessions)
|
|
429
471
|
await Promise.all(closingSessions.map(async (socket) => await this.scheduleSessionCleanup(socket)))
|
|
472
|
+
await this.drain()
|
|
430
473
|
for (const socket of closingSessions) socket.close(1001, "Shared transaction broker closed")
|
|
431
|
-
await Promise.allSettled(Array.from(this.connectionStates.values()).map((state) => state.queue))
|
|
432
474
|
await new Promise((resolve) => this.websocketServer.close(() => resolve(undefined)))
|
|
433
475
|
await new Promise((resolve) => this.httpServer.close(() => resolve(undefined)))
|
|
434
476
|
await Promise.all(Array.from(this.sessionCleanup.values()))
|