velocious 1.0.663 → 1.0.665
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 +2 -2
- package/build/background-jobs/client.js +36 -6
- package/build/configuration-types.js +3 -3
- package/build/database/query/alter-table-base.js +11 -1
- package/build/src/background-jobs/client.d.ts.map +1 -1
- package/build/src/background-jobs/client.js +35 -6
- package/build/src/configuration-types.d.ts +8 -4
- package/build/src/configuration-types.d.ts.map +1 -1
- package/build/src/configuration-types.js +4 -4
- package/build/src/database/query/alter-table-base.d.ts.map +1 -1
- package/build/src/database/query/alter-table-base.js +12 -2
- package/build/src/sync/sync-api-client.d.ts +36 -10
- package/build/src/sync/sync-api-client.d.ts.map +1 -1
- package/build/src/sync/sync-api-client.js +58 -14
- package/build/src/sync/sync-client-types.d.ts +41 -2
- package/build/src/sync/sync-client-types.d.ts.map +1 -1
- package/build/src/sync/sync-client-types.js +20 -3
- package/build/src/sync/sync-client.d.ts +112 -3
- package/build/src/sync/sync-client.d.ts.map +1 -1
- package/build/src/sync/sync-client.js +306 -60
- package/build/src/sync/sync-publisher-types.d.ts +36 -3
- package/build/src/sync/sync-publisher-types.d.ts.map +1 -1
- package/build/src/sync/sync-publisher-types.js +16 -2
- package/build/src/sync/sync-publisher.d.ts +22 -3
- package/build/src/sync/sync-publisher.d.ts.map +1 -1
- package/build/src/sync/sync-publisher.js +134 -13
- package/build/src/sync/sync-realtime-bridge.d.ts +11 -5
- package/build/src/sync/sync-realtime-bridge.d.ts.map +1 -1
- package/build/src/sync/sync-realtime-bridge.js +37 -13
- package/build/src/sync/sync-scope-store.d.ts +32 -0
- package/build/src/sync/sync-scope-store.d.ts.map +1 -1
- package/build/src/sync/sync-scope-store.js +74 -4
- package/build/sync/sync-api-client.js +58 -13
- package/build/sync/sync-client-types.js +22 -2
- package/build/sync/sync-client.js +333 -63
- package/build/sync/sync-publisher-types.js +17 -1
- package/build/sync/sync-publisher.js +156 -15
- package/build/sync/sync-realtime-bridge.js +37 -12
- package/build/sync/sync-scope-store.js +79 -3
- package/package.json +1 -1
- package/src/background-jobs/client.js +36 -6
- package/src/configuration-types.js +3 -3
- package/src/database/query/alter-table-base.js +11 -1
- package/src/sync/sync-api-client.js +58 -13
- package/src/sync/sync-client-types.js +22 -2
- package/src/sync/sync-client.js +333 -63
- package/src/sync/sync-publisher-types.js +17 -1
- package/src/sync/sync-publisher.js +156 -15
- package/src/sync/sync-realtime-bridge.js +37 -12
- package/src/sync/sync-scope-store.js +79 -3
|
@@ -204,11 +204,12 @@ export default class SyncScopeStore {
|
|
|
204
204
|
this._assertScopeRow(scopeRow);
|
|
205
205
|
await this.ensureReady();
|
|
206
206
|
if (this._usesMemoryStorage()) {
|
|
207
|
-
|
|
207
|
+
const currentScope = this._memoryScopes.get(scopeRow.scopeDigest);
|
|
208
|
+
return currentScope?.id === scopeRow.id ? currentScope.cursorPayload : null;
|
|
208
209
|
}
|
|
209
210
|
return await this._withDb(async (db) => {
|
|
210
211
|
const row = await this._rowByScopeDigest(db, scopeRow.scopeDigest);
|
|
211
|
-
return row ? row.cursorPayload : null;
|
|
212
|
+
return row?.id === scopeRow.id ? row.cursorPayload : null;
|
|
212
213
|
});
|
|
213
214
|
}
|
|
214
215
|
/**
|
|
@@ -227,12 +228,14 @@ export default class SyncScopeStore {
|
|
|
227
228
|
const memoryScope = this._memoryScopes.get(scopeRow.scopeDigest);
|
|
228
229
|
if (!memoryScope)
|
|
229
230
|
throw new Error(`No sync scope found for: ${scopeRow.scopeDigest}`);
|
|
231
|
+
if (memoryScope.id !== scopeRow.id || memoryScope.state !== "active")
|
|
232
|
+
return;
|
|
230
233
|
memoryScope.cursorPayload = cursorPayload;
|
|
231
234
|
return;
|
|
232
235
|
}
|
|
233
236
|
await this._withDb(async (db) => {
|
|
234
237
|
await db.update({
|
|
235
|
-
conditions: { scope_digest: scopeRow.scopeDigest },
|
|
238
|
+
conditions: { id: scopeRow.id, scope_digest: scopeRow.scopeDigest, state: "active" },
|
|
236
239
|
data: { cursor_json: cursorPayload, updated_at: new Date() },
|
|
237
240
|
tableName: TABLE_NAME
|
|
238
241
|
});
|
|
@@ -256,6 +259,73 @@ export default class SyncScopeStore {
|
|
|
256
259
|
await db.update({ conditions: { scope_digest: digest }, data: { state: "removed", updated_at: new Date() }, tableName: TABLE_NAME });
|
|
257
260
|
});
|
|
258
261
|
}
|
|
262
|
+
/**
|
|
263
|
+
* Atomically deactivates selected scopes, clears their cursors and rotates
|
|
264
|
+
* their row identities. A cursor save carrying a pre-reset row identity can
|
|
265
|
+
* therefore never repopulate the reset scope. The optional cleanup hook runs
|
|
266
|
+
* inside the same database transaction, allowing an app to purge the local
|
|
267
|
+
* rows owned by those scopes without a cursor/cache split.
|
|
268
|
+
* @param {import("./sync-client-types.js").SerializedSyncScope[]} scopes - Selected scopes to reset.
|
|
269
|
+
* @param {object} [options] - Reset options.
|
|
270
|
+
* @param {(args: {connection: import("../database/drivers/base.js").default | null, scopes: import("./sync-client-types.js").SerializedSyncScope[]}) => Promise<void> | void} [options.cleanup] - App-owned local-row cleanup hook.
|
|
271
|
+
* @returns {Promise<void>}
|
|
272
|
+
*/
|
|
273
|
+
async reset(scopes, { cleanup } = {}) {
|
|
274
|
+
if (!Array.isArray(scopes) || scopes.length === 0)
|
|
275
|
+
throw new Error("SyncScopeStore.reset requires at least one serialized scope");
|
|
276
|
+
if (cleanup !== undefined && typeof cleanup !== "function")
|
|
277
|
+
throw new Error("SyncScopeStore.reset cleanup must be a function");
|
|
278
|
+
await this.ensureReady();
|
|
279
|
+
const uniqueScopes = [...new Map(scopes.map((scope) => [scopeDigestForScope(scope), scope])).values()];
|
|
280
|
+
if (this._usesMemoryStorage()) {
|
|
281
|
+
if (cleanup)
|
|
282
|
+
await cleanup({ connection: null, scopes: uniqueScopes });
|
|
283
|
+
for (const scope of uniqueScopes)
|
|
284
|
+
this._resetMemoryScope(scope);
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
await this._withDb(async (db) => {
|
|
288
|
+
await db.transaction(async () => {
|
|
289
|
+
if (cleanup)
|
|
290
|
+
await cleanup({ connection: db, scopes: uniqueScopes });
|
|
291
|
+
for (const scope of uniqueScopes)
|
|
292
|
+
await this._resetDatabaseScope({ db, scope });
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Resets one memory-backed scope while preserving repeated-reset idempotence.
|
|
298
|
+
* @param {import("./sync-client-types.js").SerializedSyncScope} scope - Scope to reset.
|
|
299
|
+
* @returns {void}
|
|
300
|
+
*/
|
|
301
|
+
_resetMemoryScope(scope) {
|
|
302
|
+
const digest = scopeDigestForScope(scope);
|
|
303
|
+
const memoryScope = this._memoryScopes.get(digest);
|
|
304
|
+
if (!memoryScope || (memoryScope.state === "removed" && memoryScope.cursorPayload === null))
|
|
305
|
+
return;
|
|
306
|
+
this._memoryScopes.set(digest, {
|
|
307
|
+
...memoryScope,
|
|
308
|
+
cursorPayload: null,
|
|
309
|
+
id: new UUID(4).format(),
|
|
310
|
+
state: "removed"
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Resets one database-backed scope while preserving repeated-reset idempotence.
|
|
315
|
+
* @param {{db: import("../database/drivers/base.js").default, scope: import("./sync-client-types.js").SerializedSyncScope}} args - Database and scope.
|
|
316
|
+
* @returns {Promise<void>}
|
|
317
|
+
*/
|
|
318
|
+
async _resetDatabaseScope({ db, scope }) {
|
|
319
|
+
const digest = scopeDigestForScope(scope);
|
|
320
|
+
const existingRow = await this._rowByScopeDigest(db, digest);
|
|
321
|
+
if (!existingRow || (existingRow.state === "removed" && existingRow.cursorPayload === null))
|
|
322
|
+
return;
|
|
323
|
+
await db.update({
|
|
324
|
+
conditions: { id: existingRow.id, scope_digest: digest },
|
|
325
|
+
data: { cursor_json: null, id: new UUID(4).format(), state: "removed", updated_at: new Date() },
|
|
326
|
+
tableName: TABLE_NAME
|
|
327
|
+
});
|
|
328
|
+
}
|
|
259
329
|
/**
|
|
260
330
|
* Whether the store runs without a configured database.
|
|
261
331
|
* @returns {boolean} Whether memory storage is used.
|
|
@@ -349,4 +419,4 @@ export default class SyncScopeStore {
|
|
|
349
419
|
}
|
|
350
420
|
}
|
|
351
421
|
}
|
|
352
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1zY29wZS1zdG9yZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zeW5jL3N5bmMtc2NvcGUtc3RvcmUuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sU0FBUyxNQUFNLGlDQUFpQyxDQUFBO0FBQ3ZELE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQTtBQUU1QixPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sa0JBQWtCLENBQUE7QUFDekMsT0FBTyxtQkFBbUIsTUFBTSxrQkFBa0IsQ0FBQTtBQUVsRDs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLFVBQVUsR0FBRyx1QkFBdUIsQ0FBQTtBQUMxQyxNQUFNLG1CQUFtQixHQUFHLHVCQUF1QixDQUFBO0FBRW5EOzs7OztHQUtHO0FBQ0gsU0FBUyxtQkFBbUIsQ0FBQyxLQUFLO0lBQ2hDLE9BQU8sSUFBSSxJQUFJLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxHQUFHLG1CQUFtQixHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUE7QUFDbkYsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8sY0FBYztJQUNqQzs7Ozs7O09BTUc7SUFDSCxZQUFZLEVBQUMsYUFBYSxFQUFFLGtCQUFrQixHQUFHLFNBQVMsRUFBRSxZQUFZLEVBQUM7UUFDdkUsSUFBSSxZQUFZO1lBQUUsWUFBWSxDQUFDLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxDQUFBO1FBRWpFLElBQUksQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFBO1FBQ2xDLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxrQkFBa0IsQ0FBQTtRQUM1QyxJQUFJLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQTtRQUNoQyxJQUFJLENBQUMsYUFBYSxHQUFHLFlBQVk7WUFDL0IsQ0FBQyxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsQ0FBQyxrQkFBa0IsQ0FBQztZQUNuRCxDQUFDLENBQUMsaUJBQWlCLGtCQUFrQixFQUFFLENBQUE7UUFDekMsd0NBQXdDO1FBQ3hDLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQTtRQUM5QixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQTtRQUNyQixtQ0FBbUM7UUFDbkMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUE7UUFDekIsMEhBQTBIO1FBQzFILElBQUksQ0FBQyx5QkFBeUIsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFBO0lBQ2hELENBQUM7SUFFRDs7O09BR0c7SUFDSCxLQUFLLENBQUMsV0FBVztRQUNmLElBQUksSUFBSSxDQUFDLFFBQVE7WUFBRSxPQUFNO1FBRXpCLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFLEVBQUUsQ0FBQztZQUM5QixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQTtZQUNwQixPQUFNO1FBQ1IsQ0FBQztRQUVELE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxNQUFNLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFBO0lBQ3JFLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLGtCQUFrQixDQUFDLEVBQUU7UUFDekIsSUFBSSxJQUFJLENBQUMsUUFBUTtZQUFFLE9BQU07UUFFekIsTUFBTSxxQkFBcUIsR0FBRyxFQUFFLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLHFCQUFxQixFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQTtRQUN4RixNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUE7UUFFL0QsSUFBSSxxQkFBcUIsSUFBSSxnQkFBZ0IsRUFBRSxVQUFVLEtBQUsscUJBQXFCLEVBQUUsQ0FBQztZQUNwRixNQUFNLGdCQUFnQixDQUFDLE9BQU8sQ0FBQTtZQUM5QixPQUFNO1FBQ1IsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3ZCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUE7WUFFdkMsTUFBTSxZQUFZLENBQUE7WUFDbEIsSUFBSSxJQUFJLENBQUMsYUFBYSxLQUFLLFlBQVk7Z0JBQUUsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUE7WUFDbEUsSUFBSSxJQUFJLENBQUMsUUFBUTtnQkFBRSxPQUFNO1lBRXpCLE1BQU0sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFBO1lBQ3hCLE9BQU07UUFDUixDQUFDO1FBRUQsSUFBSSxxQkFBcUIsRUFBRSxDQUFDO1lBQzFCLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEVBQUUsQ0FBQyxDQUFBO1lBQ3JELE1BQU0sdUJBQXVCLEdBQUcsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFBO1lBRXZFLE1BQU0sbUJBQW1CLEdBQUcsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtnQkFDbkUsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO29CQUNiLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFBO29CQUNwQixPQUFNO2dCQUNSLENBQUM7Z0JBRUQsTUFBTSxxQkFBcUIsQ0FBQTtZQUM3QixDQUFDLENBQUMsQ0FBQTtZQUVGLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUMsVUFBVSxFQUFFLHFCQUFxQixFQUFFLE9BQU8sRUFBRSx1QkFBdUIsRUFBQyxDQUFDLENBQUE7WUFDN0csSUFBSSxDQUFDLGFBQWEsR0FBRyxtQkFBbUIsQ0FBQTtZQUN4QyxNQUFNLHVCQUF1QixDQUFBO1lBQzdCLE9BQU07UUFDUixDQUFDO1FBRUQsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRTtZQUN6RCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQTtRQUN0QixDQUFDLENBQUMsQ0FBQTtRQUVGLElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQTtRQUMxQixDQUFDO2dCQUFTLENBQUM7WUFDVCxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVE7Z0JBQUUsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUE7UUFDL0MsQ0FBQztJQUNILENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLGlCQUFpQixDQUFDLEtBQUs7UUFDM0IsTUFBTSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUE7UUFFeEIsTUFBTSxNQUFNLEdBQUcsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUE7UUFFekMsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsRUFBRSxDQUFDO1lBQzlCLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFBO1lBRXBELElBQUksYUFBYSxFQUFFLENBQUM7Z0JBQ2xCLElBQUksYUFBYSxDQUFDLEtBQUssS0FBSyxRQUFRO29CQUFFLGFBQWEsQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFBO2dCQUVwRSxPQUFPLGFBQWEsQ0FBQTtZQUN0QixDQUFDO1lBRUQsTUFBTSxRQUFRLEdBQUc7Z0JBQ2YsVUFBVSxFQUFFLEtBQUssQ0FBQyxVQUFVO2dCQUM1QixhQUFhLEVBQUUsSUFBSTtnQkFDbkIsRUFBRSxFQUFFLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRTtnQkFDeEIsWUFBWSxFQUFFLEtBQUssQ0FBQyxZQUFZLElBQUksSUFBSTtnQkFDeEMsV0FBVyxFQUFFLE1BQU07Z0JBQ25CLEtBQUssRUFBRSxRQUFRO2dCQUNmLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYTthQUNsQyxDQUFBO1lBRUQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFBO1lBRXhDLE9BQU8sUUFBUSxDQUFBO1FBQ2pCLENBQUM7UUFFRCxPQUFPLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEVBQUU7WUFDckMsTUFBTSxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFBO1lBRTVELElBQUksV0FBVyxFQUFFLENBQUM7Z0JBQ2hCLElBQUksV0FBVyxDQUFDLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztvQkFDbkMsTUFBTSxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUMsVUFBVSxFQUFFLEVBQUMsRUFBRSxFQUFFLFdBQVcsQ0FBQyxFQUFFLEVBQUMsRUFBRSxJQUFJLEVBQUUsRUFBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxJQUFJLElBQUksRUFBRSxFQUFDLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBQyxDQUFDLENBQUE7b0JBQzNILFdBQVcsQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFBO2dCQUM5QixDQUFDO2dCQUVELE9BQU8sV0FBVyxDQUFBO1lBQ3BCLENBQUM7WUFFRCxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUM7Z0JBQ2QsU0FBUyxFQUFFLFVBQVU7Z0JBQ3JCLElBQUksRUFBRTtvQkFDSixlQUFlLEVBQUUsbUJBQW1CLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQztvQkFDdEQsVUFBVSxFQUFFLElBQUksSUFBSSxFQUFFO29CQUN0QixXQUFXLEVBQUUsSUFBSTtvQkFDakIsRUFBRSxFQUFFLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRTtvQkFDeEIsaUZBQWlGO29CQUNqRixpRUFBaUU7b0JBQ2pFLGFBQWEsRUFBRSxLQUFLLENBQUMsWUFBWSxJQUFJLEVBQUU7b0JBQ3ZDLFlBQVksRUFBRSxNQUFNO29CQUNwQixLQUFLLEVBQUUsUUFBUTtvQkFDZixVQUFVLEVBQUUsSUFBSSxJQUFJLEVBQUU7aUJBQ3ZCO2FBQ0YsQ0FBQyxDQUFBO1lBRUYsTUFBTSxVQUFVLEdBQUcsTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFBO1lBRTNELElBQUksQ0FBQyxVQUFVO2dCQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLENBQUMsQ0FBQTtZQUVoRSxPQUFPLFVBQVUsQ0FBQTtRQUNuQixDQUFDLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFFRDs7O09BR0c7SUFDSCxLQUFLLENBQUMsWUFBWTtRQUNoQixNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQTtRQUV4QixJQUFJLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxFQUFFLENBQUM7WUFDOUIsT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssS0FBSyxRQUFRLENBQUMsQ0FBQTtRQUNyRixDQUFDO1FBRUQsT0FBTyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxFQUFFO1lBQ3JDLE1BQU0sSUFBSSxHQUFHLG1FQUFtRSxDQUFDLENBQUMsTUFBTSxFQUFFO2lCQUN2RixRQUFRLEVBQUU7aUJBQ1YsSUFBSSxDQUFDLFVBQVUsQ0FBQztpQkFDaEIsS0FBSyxDQUFDLEVBQUMsS0FBSyxFQUFFLFFBQVEsRUFBQyxDQUFDO2lCQUN4QixLQUFLLENBQUMsZ0JBQWdCLENBQUM7aUJBQ3ZCLE9BQU8sRUFBRSxDQUFDLENBQUE7WUFFYixPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO1FBQ3hELENBQUMsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsVUFBVSxDQUFDLFFBQVE7UUFDdkIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUM5QixNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQTtRQUV4QixJQUFJLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxFQUFFLENBQUM7WUFDOUIsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLEVBQUUsYUFBYSxJQUFJLElBQUksQ0FBQTtRQUM1RSxDQUFDO1FBRUQsT0FBTyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxFQUFFO1lBQ3JDLE1BQU0sR0FBRyxHQUFHLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsRUFBRSxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUE7WUFFbEUsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQTtRQUN2QyxDQUFDLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILEtBQUssQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLE1BQU07UUFDL0IsSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUM5QixJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU07UUFFbkIsTUFBTSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUE7UUFFeEIsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUU1QyxJQUFJLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxFQUFFLENBQUM7WUFDOUIsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFBO1lBRWhFLElBQUksQ0FBQyxXQUFXO2dCQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsNEJBQTRCLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFBO1lBRXJGLFdBQVcsQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFBO1lBQ3pDLE9BQU07UUFDUixDQUFDO1FBRUQsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsRUFBRTtZQUM5QixNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUM7Z0JBQ2QsVUFBVSxFQUFFLEVBQUMsWUFBWSxFQUFFLFFBQVEsQ0FBQyxXQUFXLEVBQUM7Z0JBQ2hELElBQUksRUFBRSxFQUFDLFdBQVcsRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLElBQUksSUFBSSxFQUFFLEVBQUM7Z0JBQzFELFNBQVMsRUFBRSxVQUFVO2FBQ3RCLENBQUMsQ0FBQTtRQUNKLENBQUMsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsVUFBVSxDQUFDLEtBQUs7UUFDcEIsTUFBTSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUE7UUFFeEIsTUFBTSxNQUFNLEdBQUcsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUE7UUFFekMsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsRUFBRSxDQUFDO1lBQzlCLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFBO1lBRWxELElBQUksV0FBVztnQkFBRSxXQUFXLENBQUMsS0FBSyxHQUFHLFNBQVMsQ0FBQTtZQUU5QyxPQUFNO1FBQ1IsQ0FBQztRQUVELE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEVBQUU7WUFDOUIsTUFBTSxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUMsVUFBVSxFQUFFLEVBQUMsWUFBWSxFQUFFLE1BQU0sRUFBQyxFQUFFLElBQUksRUFBRSxFQUFDLEtBQUssRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLElBQUksSUFBSSxFQUFFLEVBQUMsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFDLENBQUMsQ0FBQTtRQUNoSSxDQUFDLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFFRDs7O09BR0c7SUFDSCxrQkFBa0I7UUFDaEIsSUFBSSxDQUFDO1lBQ0gsT0FBTyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsd0JBQXdCLEVBQUUsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQTtRQUNoRixDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsT0FBTyxJQUFJLENBQUE7UUFDYixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRO1FBQ3BCLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3RCLE9BQU8sTUFBTSxJQUFJLENBQUMsWUFBWSxDQUFDLGlCQUFpQixDQUFDLEVBQUMsa0JBQWtCLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixFQUFFLElBQUksRUFBRSx5QkFBeUIsRUFBQyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsRUFBRTtnQkFDbkosT0FBTyxNQUFNLFFBQVEsQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQTtZQUMvQyxDQUFDLENBQUMsQ0FBQTtRQUNKLENBQUM7UUFFRCxPQUFPLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFDLG1CQUFtQixFQUFFLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEVBQUUsSUFBSSxFQUFFLGtCQUFrQixFQUFDLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFO1lBQzFJLE1BQU0sRUFBRSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQTtZQUV2QyxJQUFJLENBQUMsRUFBRTtnQkFBRSxNQUFNLElBQUksS0FBSyxDQUFDLG9EQUFvRCxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxDQUFBO1lBRXZHLE9BQU8sTUFBTSxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUE7UUFDM0IsQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFO1FBQ3pCLElBQUksTUFBTSxFQUFFLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQztZQUFFLE9BQU8sS0FBSyxDQUFBO1FBRWxELE1BQU0sS0FBSyxHQUFHLElBQUksU0FBUyxDQUFDLFVBQVUsRUFBRSxFQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFBO1FBRTVELEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFDLENBQUMsQ0FBQTtRQUNuRCxLQUFLLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxFQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBQyxDQUFDLENBQUE7UUFDeEQsS0FBSyxDQUFDLE1BQU0sQ0FBQyxlQUFlLEVBQUUsRUFBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUMsQ0FBQyxDQUFBO1FBQ3pELEtBQUssQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsRUFBQyxJQUFJLEVBQUUsS0FBSyxFQUFDLENBQUMsQ0FBQTtRQUM1QyxLQUFLLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxFQUFDLElBQUksRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFBO1FBQ3ZDLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLEVBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFDLENBQUMsQ0FBQTtRQUNqRCxLQUFLLENBQUMsUUFBUSxDQUFDLFlBQVksRUFBRSxFQUFDLElBQUksRUFBRSxLQUFLLEVBQUMsQ0FBQyxDQUFBO1FBQzNDLEtBQUssQ0FBQyxRQUFRLENBQUMsWUFBWSxFQUFFLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBQyxDQUFDLENBQUE7UUFFM0MsTUFBTSxFQUFFLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBRTNCLE9BQU8sSUFBSSxDQUFBO0lBQ2IsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsS0FBSyxDQUFDLGlCQUFpQixDQUFDLEVBQUUsRUFBRSxNQUFNO1FBQ2hDLE1BQU0sSUFBSSxHQUFHLG1FQUFtRSxDQUFDLENBQUMsTUFBTSxFQUFFO2FBQ3ZGLFFBQVEsRUFBRTthQUNWLElBQUksQ0FBQyxVQUFVLENBQUM7YUFDaEIsS0FBSyxDQUFDLEVBQUMsWUFBWSxFQUFFLE1BQU0sRUFBQyxDQUFDO2FBQzdCLEtBQUssQ0FBQyxDQUFDLENBQUM7YUFDUixPQUFPLEVBQUUsQ0FBQyxDQUFBO1FBRWIsT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFBO0lBQzFELENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsa0JBQWtCLENBQUMsR0FBRztRQUNwQixPQUFPO1lBQ0wsVUFBVSxFQUFFLDREQUE0RCxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7WUFDbEgsYUFBYSxFQUFFLEdBQUcsQ0FBQyxXQUFXLEtBQUssSUFBSSxJQUFJLEdBQUcsQ0FBQyxXQUFXLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDO1lBQ3pHLEVBQUUsRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNsQixZQUFZLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUM7WUFDakYsV0FBVyxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDO1lBQ3JDLEtBQUssRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQztZQUN4QixhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWE7U0FDbEMsQ0FBQTtJQUNILENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsZUFBZSxDQUFDLFFBQVE7UUFDdEIsSUFBSSxRQUFRLENBQUMsYUFBYSxLQUFLLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNsRCxNQUFNLElBQUksS0FBSyxDQUFDLDREQUE0RCxDQUFDLENBQUE7UUFDL0UsQ0FBQztJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgVGFibGVEYXRhIGZyb20gXCIuLi9kYXRhYmFzZS90YWJsZS1kYXRhL2luZGV4LmpzXCJcbmltcG9ydCBVVUlEIGZyb20gXCJwdXJlLXV1aWRcIlxuXG5pbXBvcnQge3Njb3BlS2V5fSBmcm9tIFwiLi9xdWVyeS1zY29wZS5qc1wiXG5pbXBvcnQgc3RhYmxlSnNvblN0cmluZ2lmeSBmcm9tIFwiLi9zdGFibGUtanNvbi5qc1wiXG5cbi8qKlxuICogQHR5cGVkZWYge29iamVjdH0gU3luY1Njb3BlUm93XG4gKiBAcHJvcGVydHkge1JlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gY29uZGl0aW9ucyAtIFNjb3BlIGF0dHJpYnV0ZSBjb25kaXRpb25zLlxuICogQHByb3BlcnR5IHtzdHJpbmcgfCBudWxsfSBjdXJzb3JQYXlsb2FkIC0gUGVyc2lzdGVkIGN1cnNvciBKU09OIHBheWxvYWQuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gaWQgLSBTY29wZSByb3cgaWQuXG4gKiBAcHJvcGVydHkge3N0cmluZyB8IG51bGx9IHJlc291cmNlVHlwZSAtIFNjb3BlIHJlc291cmNlL21vZGVsIG5hbWUsIG9yIG51bGwgZm9yIHRoZSBhbGwtdHlwZXMgKHVzZXIpIHNjb3BlLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHNjb3BlRGlnZXN0IC0gRml4ZWQtc2l6ZSBkZXRlcm1pbmlzdGljIGRpZ2VzdCBvZiB0aGUgY2Fub25pY2FsIHNjb3BlIGtleS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzdGF0ZSAtIFNjb3BlIHN0YXRlIChcImFjdGl2ZVwiIG9yIFwicmVtb3ZlZFwiKS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzdG9yZUlkZW50aXR5IC0gUGh5c2ljYWwgc3RvcmUgaWRlbnRpdHkgb3duaW5nIHRoaXMgcm93LlxuICovXG5jb25zdCBUQUJMRV9OQU1FID0gXCJ2ZWxvY2lvdXNfc3luY19zY29wZXNcIlxuY29uc3QgU0NPUEVfRElHRVNUX1BSRUZJWCA9IFwidmVsb2Npb3VzLXN5bmMtc2NvcGU6XCJcblxuLyoqXG4gKiBEaWdlc3RzIGEgc2VyaWFsaXplZCBzY29wZSBpbnRvIGEgZml4ZWQtc2l6ZSBkZXRlcm1pbmlzdGljIGtleSwgc28gc2NvcGVcbiAqIGlkZW50aXRpZXMgd2l0aCBsb25nIGNvbmRpdGlvbiB2YWx1ZXMgZml0IGFuIGluZGV4ZWQgc3RyaW5nIGNvbHVtbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9zeW5jLWNsaWVudC10eXBlcy5qc1wiKS5TZXJpYWxpemVkU3luY1Njb3BlfSBzY29wZSAtIFNlcmlhbGl6ZWQgc3luYyBzY29wZS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IERldGVybWluaXN0aWMgVVVJRHY1IGRpZ2VzdCBvZiB0aGUgY2Fub25pY2FsIHNjb3BlIGtleS5cbiAqL1xuZnVuY3Rpb24gc2NvcGVEaWdlc3RGb3JTY29wZShzY29wZSkge1xuICByZXR1cm4gbmV3IFVVSUQoNSwgXCJuczpVUkxcIiwgYCR7U0NPUEVfRElHRVNUX1BSRUZJWH0ke3Njb3BlS2V5KHNjb3BlKX1gKS5mb3JtYXQoKVxufVxuXG4vKipcbiAqIEZyYW1ld29yay1vd25lZCBsb2NhbCBwZXJzaXN0ZW5jZSBmb3IgZGVjbGFyZWQgc3luYyBzY29wZXMgYW5kIHRoZWlyIGN1cnNvcnMuXG4gKlxuICogQmFja2VkIGJ5IGFuIGF1dG8tY3JlYXRlZCBgdmVsb2Npb3VzX3N5bmNfc2NvcGVzYCB0YWJsZSBvbiB0aGUgY29uZmlndXJlZFxuICogZGF0YWJhc2UsIHdpdGggYSBwcm9jZXNzLWxvY2FsIG1lbW9yeSBmYWxsYmFjayB3aGVuIG5vIGRhdGFiYXNlIGlzXG4gKiBjb25maWd1cmVkIChtaXJyb3JpbmcgdGhlIHNlcnZlciBjaGFuZ2UtZmVlZCBzdG9yZSkuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFN5bmNTY29wZVN0b3JlIHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBzeW5jIHNjb3BlIHN0b3JlLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSBhcmdzLmNvbmZpZ3VyYXRpb24gLSBDb25maWd1cmF0aW9uIG93bmluZyB0aGUgZGF0YWJhc2UuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYXJncy5kYXRhYmFzZUlkZW50aWZpZXJdIC0gRGF0YWJhc2UgaWRlbnRpZmllci5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi90ZW5hbnRzL3RlbmFudC1oYW5kbGUuanNcIikuZGVmYXVsdH0gW2FyZ3MudGVuYW50SGFuZGxlXSAtIEltbXV0YWJsZSB0ZW5hbnQgaGFuZGxlIG93bmluZyB0aGUgcGh5c2ljYWwgc3RvcmUuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7Y29uZmlndXJhdGlvbiwgZGF0YWJhc2VJZGVudGlmaWVyID0gXCJkZWZhdWx0XCIsIHRlbmFudEhhbmRsZX0pIHtcbiAgICBpZiAodGVuYW50SGFuZGxlKSB0ZW5hbnRIYW5kbGUuYXNzZXJ0Q29uZmlndXJhdGlvbihjb25maWd1cmF0aW9uKVxuXG4gICAgdGhpcy5jb25maWd1cmF0aW9uID0gY29uZmlndXJhdGlvblxuICAgIHRoaXMuZGF0YWJhc2VJZGVudGlmaWVyID0gZGF0YWJhc2VJZGVudGlmaWVyXG4gICAgdGhpcy50ZW5hbnRIYW5kbGUgPSB0ZW5hbnRIYW5kbGVcbiAgICB0aGlzLnN0b3JlSWRlbnRpdHkgPSB0ZW5hbnRIYW5kbGVcbiAgICAgID8gdGVuYW50SGFuZGxlLmRhdGFiYXNlSWRlbnRpdHkoZGF0YWJhc2VJZGVudGlmaWVyKVxuICAgICAgOiBgY29uZmlndXJhdGlvbjoke2RhdGFiYXNlSWRlbnRpZmllcn1gXG4gICAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBTeW5jU2NvcGVSb3c+fSAqL1xuICAgIHRoaXMuX21lbW9yeVNjb3BlcyA9IG5ldyBNYXAoKVxuICAgIHRoaXMuX2lzUmVhZHkgPSBmYWxzZVxuICAgIC8qKiBAdHlwZSB7UHJvbWlzZTx2b2lkPiB8IG51bGx9ICovXG4gICAgdGhpcy5fcmVhZHlQcm9taXNlID0gbnVsbFxuICAgIC8qKiBAdHlwZSB7V2Vha01hcDxpbXBvcnQoXCIuLi9kYXRhYmFzZS9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCwge2NvbXBsZXRpb246IFByb21pc2U8dm9pZD4sIHByb21pc2U6IFByb21pc2U8dm9pZD59Pn0gKi9cbiAgICB0aGlzLl90cmFuc2FjdGlvblJlYWR5UHJvbWlzZXMgPSBuZXcgV2Vha01hcCgpXG4gIH1cblxuICAvKipcbiAgICogRW5zdXJlcyB0aGUgYmFja2luZyB0YWJsZSBleGlzdHMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBSZXNvbHZlcyB3aGVuIHJlYWR5LlxuICAgKi9cbiAgYXN5bmMgZW5zdXJlUmVhZHkoKSB7XG4gICAgaWYgKHRoaXMuX2lzUmVhZHkpIHJldHVyblxuXG4gICAgaWYgKHRoaXMuX3VzZXNNZW1vcnlTdG9yYWdlKCkpIHtcbiAgICAgIHRoaXMuX2lzUmVhZHkgPSB0cnVlXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLl93aXRoRGIoYXN5bmMgKGRiKSA9PiBhd2FpdCB0aGlzLl9lbnN1cmVSZWFkeVdpdGhEYihkYikpXG4gIH1cblxuICAvKipcbiAgICogQ29vcmRpbmF0ZXMgZHVyYWJsZSBhbmQgdHJhbnNhY3Rpb24tbG9jYWwgcmVhZGluZXNzIG9uIG9uZSBjb25uZWN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RhdGFiYXNlL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBkYiAtIERhdGFiYXNlIGNvbm5lY3Rpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBSZXNvbHZlcyB3aGVuIHRoaXMgY2FsbGVyIGNhbiB1c2UgdGhlIHRhYmxlLlxuICAgKi9cbiAgYXN5bmMgX2Vuc3VyZVJlYWR5V2l0aERiKGRiKSB7XG4gICAgaWYgKHRoaXMuX2lzUmVhZHkpIHJldHVyblxuXG4gICAgY29uc3QgdHJhbnNhY3Rpb25Db21wbGV0aW9uID0gZGIuaW5zaWRlVHJhbnNhY3Rpb24oKSA/IGRiLnRyYW5zYWN0aW9uQ29tcGxldGlvbigpIDogbnVsbFxuICAgIGNvbnN0IHRyYW5zYWN0aW9uUmVhZHkgPSB0aGlzLl90cmFuc2FjdGlvblJlYWR5UHJvbWlzZXMuZ2V0KGRiKVxuXG4gICAgaWYgKHRyYW5zYWN0aW9uQ29tcGxldGlvbiAmJiB0cmFuc2FjdGlvblJlYWR5Py5jb21wbGV0aW9uID09PSB0cmFuc2FjdGlvbkNvbXBsZXRpb24pIHtcbiAgICAgIGF3YWl0IHRyYW5zYWN0aW9uUmVhZHkucHJvbWlzZVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3JlYWR5UHJvbWlzZSkge1xuICAgICAgY29uc3QgcmVhZHlQcm9taXNlID0gdGhpcy5fcmVhZHlQcm9taXNlXG5cbiAgICAgIGF3YWl0IHJlYWR5UHJvbWlzZVxuICAgICAgaWYgKHRoaXMuX3JlYWR5UHJvbWlzZSA9PT0gcmVhZHlQcm9taXNlKSB0aGlzLl9yZWFkeVByb21pc2UgPSBudWxsXG4gICAgICBpZiAodGhpcy5faXNSZWFkeSkgcmV0dXJuXG5cbiAgICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVhZHkoKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHRyYW5zYWN0aW9uQ29tcGxldGlvbikge1xuICAgICAgY29uc3QgdGFibGVSZWFkeVByb21pc2UgPSB0aGlzLl9lbnN1cmVTY29wZXNUYWJsZShkYilcbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uUmVhZHlQcm9taXNlID0gdGFibGVSZWFkeVByb21pc2UudGhlbigoKSA9PiB1bmRlZmluZWQpXG5cbiAgICAgIGNvbnN0IGR1cmFibGVSZWFkeVByb21pc2UgPSB0YWJsZVJlYWR5UHJvbWlzZS50aGVuKGFzeW5jIChjcmVhdGVkKSA9PiB7XG4gICAgICAgIGlmICghY3JlYXRlZCkge1xuICAgICAgICAgIHRoaXMuX2lzUmVhZHkgPSB0cnVlXG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCB0cmFuc2FjdGlvbkNvbXBsZXRpb25cbiAgICAgIH0pXG5cbiAgICAgIHRoaXMuX3RyYW5zYWN0aW9uUmVhZHlQcm9taXNlcy5zZXQoZGIsIHtjb21wbGV0aW9uOiB0cmFuc2FjdGlvbkNvbXBsZXRpb24sIHByb21pc2U6IHRyYW5zYWN0aW9uUmVhZHlQcm9taXNlfSlcbiAgICAgIHRoaXMuX3JlYWR5UHJvbWlzZSA9IGR1cmFibGVSZWFkeVByb21pc2VcbiAgICAgIGF3YWl0IHRyYW5zYWN0aW9uUmVhZHlQcm9taXNlXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLl9yZWFkeVByb21pc2UgPSB0aGlzLl9lbnN1cmVTY29wZXNUYWJsZShkYikudGhlbigoKSA9PiB7XG4gICAgICB0aGlzLl9pc1JlYWR5ID0gdHJ1ZVxuICAgIH0pXG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5fcmVhZHlQcm9taXNlXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGlmICghdGhpcy5faXNSZWFkeSkgdGhpcy5fcmVhZHlQcm9taXNlID0gbnVsbFxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kcyBvciBjcmVhdGVzIHRoZSBzY29wZSByb3cgZm9yIGEgc2VyaWFsaXplZCBzY29wZSwgcmVhY3RpdmF0aW5nIHJlbW92ZWQgc2NvcGVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vc3luYy1jbGllbnQtdHlwZXMuanNcIikuU2VyaWFsaXplZFN5bmNTY29wZX0gc2NvcGUgLSBTZXJpYWxpemVkIHN5bmMgc2NvcGUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFN5bmNTY29wZVJvdz59IFBlcnNpc3RlZCBzY29wZSByb3cuXG4gICAqL1xuICBhc3luYyBmaW5kT3JDcmVhdGVTY29wZShzY29wZSkge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVhZHkoKVxuXG4gICAgY29uc3QgZGlnZXN0ID0gc2NvcGVEaWdlc3RGb3JTY29wZShzY29wZSlcblxuICAgIGlmICh0aGlzLl91c2VzTWVtb3J5U3RvcmFnZSgpKSB7XG4gICAgICBjb25zdCBleGlzdGluZ1Njb3BlID0gdGhpcy5fbWVtb3J5U2NvcGVzLmdldChkaWdlc3QpXG5cbiAgICAgIGlmIChleGlzdGluZ1Njb3BlKSB7XG4gICAgICAgIGlmIChleGlzdGluZ1Njb3BlLnN0YXRlICE9PSBcImFjdGl2ZVwiKSBleGlzdGluZ1Njb3BlLnN0YXRlID0gXCJhY3RpdmVcIlxuXG4gICAgICAgIHJldHVybiBleGlzdGluZ1Njb3BlXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5ld1Njb3BlID0ge1xuICAgICAgICBjb25kaXRpb25zOiBzY29wZS5jb25kaXRpb25zLFxuICAgICAgICBjdXJzb3JQYXlsb2FkOiBudWxsLFxuICAgICAgICBpZDogbmV3IFVVSUQoNCkuZm9ybWF0KCksXG4gICAgICAgIHJlc291cmNlVHlwZTogc2NvcGUucmVzb3VyY2VUeXBlID8/IG51bGwsXG4gICAgICAgIHNjb3BlRGlnZXN0OiBkaWdlc3QsXG4gICAgICAgIHN0YXRlOiBcImFjdGl2ZVwiLFxuICAgICAgICBzdG9yZUlkZW50aXR5OiB0aGlzLnN0b3JlSWRlbnRpdHlcbiAgICAgIH1cblxuICAgICAgdGhpcy5fbWVtb3J5U2NvcGVzLnNldChkaWdlc3QsIG5ld1Njb3BlKVxuXG4gICAgICByZXR1cm4gbmV3U2NvcGVcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5fd2l0aERiKGFzeW5jIChkYikgPT4ge1xuICAgICAgY29uc3QgZXhpc3RpbmdSb3cgPSBhd2FpdCB0aGlzLl9yb3dCeVNjb3BlRGlnZXN0KGRiLCBkaWdlc3QpXG5cbiAgICAgIGlmIChleGlzdGluZ1Jvdykge1xuICAgICAgICBpZiAoZXhpc3RpbmdSb3cuc3RhdGUgIT09IFwiYWN0aXZlXCIpIHtcbiAgICAgICAgICBhd2FpdCBkYi51cGRhdGUoe2NvbmRpdGlvbnM6IHtpZDogZXhpc3RpbmdSb3cuaWR9LCBkYXRhOiB7c3RhdGU6IFwiYWN0aXZlXCIsIHVwZGF0ZWRfYXQ6IG5ldyBEYXRlKCl9LCB0YWJsZU5hbWU6IFRBQkxFX05BTUV9KVxuICAgICAgICAgIGV4aXN0aW5nUm93LnN0YXRlID0gXCJhY3RpdmVcIlxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGV4aXN0aW5nUm93XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IGRiLmluc2VydCh7XG4gICAgICAgIHRhYmxlTmFtZTogVEFCTEVfTkFNRSxcbiAgICAgICAgZGF0YToge1xuICAgICAgICAgIGNvbmRpdGlvbnNfanNvbjogc3RhYmxlSnNvblN0cmluZ2lmeShzY29wZS5jb25kaXRpb25zKSxcbiAgICAgICAgICBjcmVhdGVkX2F0OiBuZXcgRGF0ZSgpLFxuICAgICAgICAgIGN1cnNvcl9qc29uOiBudWxsLFxuICAgICAgICAgIGlkOiBuZXcgVVVJRCg0KS5mb3JtYXQoKSxcbiAgICAgICAgICAvLyBUaGUgYWxsLXR5cGVzICh1c2VyKSBzY29wZSBoYXMgbm8gcmVzb3VyY2UgdHlwZTsgdGhlIGNvbHVtbiBpcyBub24tbnVsbCwgc28gaXRcbiAgICAgICAgICAvLyBzdG9yZXMgYXMgYW4gZW1wdHkgc3RyaW5nIGFuZCBub3JtYWxpemVzIGJhY2sgdG8gbnVsbCBvbiByZWFkLlxuICAgICAgICAgIHJlc291cmNlX3R5cGU6IHNjb3BlLnJlc291cmNlVHlwZSA/PyBcIlwiLFxuICAgICAgICAgIHNjb3BlX2RpZ2VzdDogZGlnZXN0LFxuICAgICAgICAgIHN0YXRlOiBcImFjdGl2ZVwiLFxuICAgICAgICAgIHVwZGF0ZWRfYXQ6IG5ldyBEYXRlKClcbiAgICAgICAgfVxuICAgICAgfSlcblxuICAgICAgY29uc3QgY3JlYXRlZFJvdyA9IGF3YWl0IHRoaXMuX3Jvd0J5U2NvcGVEaWdlc3QoZGIsIGRpZ2VzdClcblxuICAgICAgaWYgKCFjcmVhdGVkUm93KSB0aHJvdyBuZXcgRXJyb3IoXCJGYWlsZWQgdG8gcGVyc2lzdCBzeW5jIHNjb3BlXCIpXG5cbiAgICAgIHJldHVybiBjcmVhdGVkUm93XG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFsbCBhY3RpdmUgc2NvcGUgcm93cy5cbiAgICogQHJldHVybnMge1Byb21pc2U8U3luY1Njb3BlUm93W10+fSBBY3RpdmUgc2NvcGUgcm93cy5cbiAgICovXG4gIGFzeW5jIGFjdGl2ZVNjb3BlcygpIHtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlYWR5KClcblxuICAgIGlmICh0aGlzLl91c2VzTWVtb3J5U3RvcmFnZSgpKSB7XG4gICAgICByZXR1cm4gWy4uLnRoaXMuX21lbW9yeVNjb3Blcy52YWx1ZXMoKV0uZmlsdGVyKChzY29wZSkgPT4gc2NvcGUuc3RhdGUgPT09IFwiYWN0aXZlXCIpXG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuX3dpdGhEYihhc3luYyAoZGIpID0+IHtcbiAgICAgIGNvbnN0IHJvd3MgPSAvKiogQHR5cGUge0FycmF5PFJlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pj59ICovIChhd2FpdCBkYlxuICAgICAgICAubmV3UXVlcnkoKVxuICAgICAgICAuZnJvbShUQUJMRV9OQU1FKVxuICAgICAgICAud2hlcmUoe3N0YXRlOiBcImFjdGl2ZVwifSlcbiAgICAgICAgLm9yZGVyKFwiY3JlYXRlZF9hdCBBU0NcIilcbiAgICAgICAgLnJlc3VsdHMoKSlcblxuICAgICAgcmV0dXJuIHJvd3MubWFwKChyb3cpID0+IHRoaXMuX25vcm1hbGl6ZVNjb3BlUm93KHJvdykpXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkcyB0aGUgcGVyc2lzdGVkIGN1cnNvciBwYXlsb2FkIGZvciBhIHNjb3BlIHJvdy5cbiAgICogQHBhcmFtIHtTeW5jU2NvcGVSb3d9IHNjb3BlUm93IC0gU2NvcGUgcm93LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmcgfCBudWxsPn0gQ3Vyc29yIEpTT04gcGF5bG9hZC5cbiAgICovXG4gIGFzeW5jIGxvYWRDdXJzb3Ioc2NvcGVSb3cpIHtcbiAgICB0aGlzLl9hc3NlcnRTY29wZVJvdyhzY29wZVJvdylcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlYWR5KClcblxuICAgIGlmICh0aGlzLl91c2VzTWVtb3J5U3RvcmFnZSgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5fbWVtb3J5U2NvcGVzLmdldChzY29wZVJvdy5zY29wZURpZ2VzdCk/LmN1cnNvclBheWxvYWQgPz8gbnVsbFxuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLl93aXRoRGIoYXN5bmMgKGRiKSA9PiB7XG4gICAgICBjb25zdCByb3cgPSBhd2FpdCB0aGlzLl9yb3dCeVNjb3BlRGlnZXN0KGRiLCBzY29wZVJvdy5zY29wZURpZ2VzdClcblxuICAgICAgcmV0dXJuIHJvdyA/IHJvdy5jdXJzb3JQYXlsb2FkIDogbnVsbFxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUGVyc2lzdHMgdGhlIGFja25vd2xlZGdlZCBjdXJzb3IgZm9yIGEgc2NvcGUgcm93LlxuICAgKiBAcGFyYW0ge1N5bmNTY29wZVJvd30gc2NvcGVSb3cgLSBTY29wZSByb3cuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9zeW5jLWFwaS1jbGllbnQtdHlwZXMuanNcIikuU3luY0N1cnNvcn0gY3Vyc29yIC0gQWNrbm93bGVkZ2VkIGN1cnNvci5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBzYXZlQ3Vyc29yKHNjb3BlUm93LCBjdXJzb3IpIHtcbiAgICB0aGlzLl9hc3NlcnRTY29wZVJvdyhzY29wZVJvdylcbiAgICBpZiAoIWN1cnNvcikgcmV0dXJuXG5cbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlYWR5KClcblxuICAgIGNvbnN0IGN1cnNvclBheWxvYWQgPSBKU09OLnN0cmluZ2lmeShjdXJzb3IpXG5cbiAgICBpZiAodGhpcy5fdXNlc01lbW9yeVN0b3JhZ2UoKSkge1xuICAgICAgY29uc3QgbWVtb3J5U2NvcGUgPSB0aGlzLl9tZW1vcnlTY29wZXMuZ2V0KHNjb3BlUm93LnNjb3BlRGlnZXN0KVxuXG4gICAgICBpZiAoIW1lbW9yeVNjb3BlKSB0aHJvdyBuZXcgRXJyb3IoYE5vIHN5bmMgc2NvcGUgZm91bmQgZm9yOiAke3Njb3BlUm93LnNjb3BlRGlnZXN0fWApXG5cbiAgICAgIG1lbW9yeVNjb3BlLmN1cnNvclBheWxvYWQgPSBjdXJzb3JQYXlsb2FkXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLl93aXRoRGIoYXN5bmMgKGRiKSA9PiB7XG4gICAgICBhd2FpdCBkYi51cGRhdGUoe1xuICAgICAgICBjb25kaXRpb25zOiB7c2NvcGVfZGlnZXN0OiBzY29wZVJvdy5zY29wZURpZ2VzdH0sXG4gICAgICAgIGRhdGE6IHtjdXJzb3JfanNvbjogY3Vyc29yUGF5bG9hZCwgdXBkYXRlZF9hdDogbmV3IERhdGUoKX0sXG4gICAgICAgIHRhYmxlTmFtZTogVEFCTEVfTkFNRVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIERlYWN0aXZhdGVzIHRoZSBzY29wZSByb3cgZm9yIGEgc2VyaWFsaXplZCBzY29wZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3N5bmMtY2xpZW50LXR5cGVzLmpzXCIpLlNlcmlhbGl6ZWRTeW5jU2NvcGV9IHNjb3BlIC0gU2VyaWFsaXplZCBzeW5jIHNjb3BlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIGRlYWN0aXZhdGUoc2NvcGUpIHtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlYWR5KClcblxuICAgIGNvbnN0IGRpZ2VzdCA9IHNjb3BlRGlnZXN0Rm9yU2NvcGUoc2NvcGUpXG5cbiAgICBpZiAodGhpcy5fdXNlc01lbW9yeVN0b3JhZ2UoKSkge1xuICAgICAgY29uc3QgbWVtb3J5U2NvcGUgPSB0aGlzLl9tZW1vcnlTY29wZXMuZ2V0KGRpZ2VzdClcblxuICAgICAgaWYgKG1lbW9yeVNjb3BlKSBtZW1vcnlTY29wZS5zdGF0ZSA9IFwicmVtb3ZlZFwiXG5cbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuX3dpdGhEYihhc3luYyAoZGIpID0+IHtcbiAgICAgIGF3YWl0IGRiLnVwZGF0ZSh7Y29uZGl0aW9uczoge3Njb3BlX2RpZ2VzdDogZGlnZXN0fSwgZGF0YToge3N0YXRlOiBcInJlbW92ZWRcIiwgdXBkYXRlZF9hdDogbmV3IERhdGUoKX0sIHRhYmxlTmFtZTogVEFCTEVfTkFNRX0pXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBzdG9yZSBydW5zIHdpdGhvdXQgYSBjb25maWd1cmVkIGRhdGFiYXNlLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciBtZW1vcnkgc3RvcmFnZSBpcyB1c2VkLlxuICAgKi9cbiAgX3VzZXNNZW1vcnlTdG9yYWdlKCkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gIXRoaXMuY29uZmlndXJhdGlvbi5nZXREYXRhYmFzZUNvbmZpZ3VyYXRpb24oKVt0aGlzLmRhdGFiYXNlSWRlbnRpZmllcl1cbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYSBjYWxsYmFjayB3aXRoIGEgZGF0YWJhc2UgY29ubmVjdGlvbi5cbiAgICogQHRlbXBsYXRlIFJlc3VsdFxuICAgKiBAcGFyYW0geyhkYjogaW1wb3J0KFwiLi4vZGF0YWJhc2UvZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQpID0+IFByb21pc2U8UmVzdWx0Pn0gY2FsbGJhY2sgLSBEYXRhYmFzZSBjYWxsYmFjay5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVzdWx0Pn0gQ2FsbGJhY2sgcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgX3dpdGhEYihjYWxsYmFjaykge1xuICAgIGlmICh0aGlzLnRlbmFudEhhbmRsZSkge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMudGVuYW50SGFuZGxlLmRhdGFiYXNlT3BlcmF0aW9uKHtkYXRhYmFzZUlkZW50aWZpZXI6IHRoaXMuZGF0YWJhc2VJZGVudGlmaWVyLCBuYW1lOiBcIlRlbmFudCBzeW5jIHNjb3BlIHN0b3JlXCJ9LCBhc3luYyAob3BlcmF0aW9uKSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCBjYWxsYmFjayhvcGVyYXRpb24uY29ubmVjdGlvbigpKVxuICAgICAgfSlcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLmVuc3VyZUNvbm5lY3Rpb25zKHtkYXRhYmFzZUlkZW50aWZpZXJzOiBbdGhpcy5kYXRhYmFzZUlkZW50aWZpZXJdLCBuYW1lOiBcIlN5bmMgc2NvcGUgc3RvcmVcIn0sIGFzeW5jIChkYnMpID0+IHtcbiAgICAgIGNvbnN0IGRiID0gZGJzW3RoaXMuZGF0YWJhc2VJZGVudGlmaWVyXVxuXG4gICAgICBpZiAoIWRiKSB0aHJvdyBuZXcgRXJyb3IoYE5vIGRhdGFiYXNlIGNvbm5lY3Rpb24gYXZhaWxhYmxlIGZvciBpZGVudGlmaWVyOiAke3RoaXMuZGF0YWJhc2VJZGVudGlmaWVyfWApXG5cbiAgICAgIHJldHVybiBhd2FpdCBjYWxsYmFjayhkYilcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIEVuc3VyZXMgdGhlIHNjb3BlcyB0YWJsZSBleGlzdHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZGF0YWJhc2UvZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGRiIC0gRGF0YWJhc2UgY29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IFdoZXRoZXIgdGhlIHRhYmxlIGhhZCB0byBiZSBjcmVhdGVkLlxuICAgKi9cbiAgYXN5bmMgX2Vuc3VyZVNjb3Blc1RhYmxlKGRiKSB7XG4gICAgaWYgKGF3YWl0IGRiLnRhYmxlRXhpc3RzKFRBQkxFX05BTUUpKSByZXR1cm4gZmFsc2VcblxuICAgIGNvbnN0IHRhYmxlID0gbmV3IFRhYmxlRGF0YShUQUJMRV9OQU1FLCB7aWZOb3RFeGlzdHM6IHRydWV9KVxuXG4gICAgdGFibGUuc3RyaW5nKFwiaWRcIiwge251bGw6IGZhbHNlLCBwcmltYXJ5S2V5OiB0cnVlfSlcbiAgICB0YWJsZS5zdHJpbmcoXCJzY29wZV9kaWdlc3RcIiwge2luZGV4OiB0cnVlLCBudWxsOiBmYWxzZX0pXG4gICAgdGFibGUuc3RyaW5nKFwicmVzb3VyY2VfdHlwZVwiLCB7aW5kZXg6IHRydWUsIG51bGw6IGZhbHNlfSlcbiAgICB0YWJsZS50ZXh0KFwiY29uZGl0aW9uc19qc29uXCIsIHtudWxsOiBmYWxzZX0pXG4gICAgdGFibGUudGV4dChcImN1cnNvcl9qc29uXCIsIHtudWxsOiB0cnVlfSlcbiAgICB0YWJsZS5zdHJpbmcoXCJzdGF0ZVwiLCB7aW5kZXg6IHRydWUsIG51bGw6IGZhbHNlfSlcbiAgICB0YWJsZS5kYXRldGltZShcImNyZWF0ZWRfYXRcIiwge251bGw6IGZhbHNlfSlcbiAgICB0YWJsZS5kYXRldGltZShcInVwZGF0ZWRfYXRcIiwge251bGw6IGZhbHNlfSlcblxuICAgIGF3YWl0IGRiLmNyZWF0ZVRhYmxlKHRhYmxlKVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyBhIHNjb3BlIHJvdyBieSBpdHMgZGlnZXN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RhdGFiYXNlL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBkYiAtIERhdGFiYXNlIGNvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBkaWdlc3QgLSBGaXhlZC1zaXplIHNjb3BlIGRpZ2VzdC5cbiAgICogQHJldHVybnMge1Byb21pc2U8U3luY1Njb3BlUm93IHwgbnVsbD59IFNjb3BlIHJvdyBvciBudWxsLlxuICAgKi9cbiAgYXN5bmMgX3Jvd0J5U2NvcGVEaWdlc3QoZGIsIGRpZ2VzdCkge1xuICAgIGNvbnN0IHJvd3MgPSAvKiogQHR5cGUge0FycmF5PFJlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pj59ICovIChhd2FpdCBkYlxuICAgICAgLm5ld1F1ZXJ5KClcbiAgICAgIC5mcm9tKFRBQkxFX05BTUUpXG4gICAgICAud2hlcmUoe3Njb3BlX2RpZ2VzdDogZGlnZXN0fSlcbiAgICAgIC5saW1pdCgxKVxuICAgICAgLnJlc3VsdHMoKSlcblxuICAgIHJldHVybiByb3dzWzBdID8gdGhpcy5fbm9ybWFsaXplU2NvcGVSb3cocm93c1swXSkgOiBudWxsXG4gIH1cblxuICAvKipcbiAgICogTm9ybWFsaXplcyBhIHJhdyBzY29wZSB0YWJsZSByb3cuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+fSByb3cgLSBSYXcgdGFibGUgcm93LlxuICAgKiBAcmV0dXJucyB7U3luY1Njb3BlUm93fSBOb3JtYWxpemVkIHNjb3BlIHJvdy5cbiAgICovXG4gIF9ub3JtYWxpemVTY29wZVJvdyhyb3cpIHtcbiAgICByZXR1cm4ge1xuICAgICAgY29uZGl0aW9uczogLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59ICovIChKU09OLnBhcnNlKFN0cmluZyhyb3cuY29uZGl0aW9uc19qc29uKSkpLFxuICAgICAgY3Vyc29yUGF5bG9hZDogcm93LmN1cnNvcl9qc29uID09PSBudWxsIHx8IHJvdy5jdXJzb3JfanNvbiA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IFN0cmluZyhyb3cuY3Vyc29yX2pzb24pLFxuICAgICAgaWQ6IFN0cmluZyhyb3cuaWQpLFxuICAgICAgcmVzb3VyY2VUeXBlOiBTdHJpbmcocm93LnJlc291cmNlX3R5cGUpID09PSBcIlwiID8gbnVsbCA6IFN0cmluZyhyb3cucmVzb3VyY2VfdHlwZSksXG4gICAgICBzY29wZURpZ2VzdDogU3RyaW5nKHJvdy5zY29wZV9kaWdlc3QpLFxuICAgICAgc3RhdGU6IFN0cmluZyhyb3cuc3RhdGUpLFxuICAgICAgc3RvcmVJZGVudGl0eTogdGhpcy5zdG9yZUlkZW50aXR5XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlamVjdHMgcGFzc2luZyBhIHNjb3BlIHJvdyBjYXB0dXJlZCBmcm9tIGFub3RoZXIgcGh5c2ljYWwgc3RvcmUuXG4gICAqIEBwYXJhbSB7U3luY1Njb3BlUm93fSBzY29wZVJvdyAtIFNjb3BlIHJvdyB0byB2YWxpZGF0ZS5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBfYXNzZXJ0U2NvcGVSb3coc2NvcGVSb3cpIHtcbiAgICBpZiAoc2NvcGVSb3cuc3RvcmVJZGVudGl0eSAhPT0gdGhpcy5zdG9yZUlkZW50aXR5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTeW5jIHNjb3BlIHJvdyBiZWxvbmdzIHRvIGFub3RoZXIgcGh5c2ljYWwgdGVuYW50IGRhdGFiYXNlXCIpXG4gICAgfVxuICB9XG59XG4iXX0=
|
|
422
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1zY29wZS1zdG9yZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zeW5jL3N5bmMtc2NvcGUtc3RvcmUuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sU0FBUyxNQUFNLGlDQUFpQyxDQUFBO0FBQ3ZELE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQTtBQUU1QixPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sa0JBQWtCLENBQUE7QUFDekMsT0FBTyxtQkFBbUIsTUFBTSxrQkFBa0IsQ0FBQTtBQUVsRDs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLFVBQVUsR0FBRyx1QkFBdUIsQ0FBQTtBQUMxQyxNQUFNLG1CQUFtQixHQUFHLHVCQUF1QixDQUFBO0FBRW5EOzs7OztHQUtHO0FBQ0gsU0FBUyxtQkFBbUIsQ0FBQyxLQUFLO0lBQ2hDLE9BQU8sSUFBSSxJQUFJLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxHQUFHLG1CQUFtQixHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUE7QUFDbkYsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8sY0FBYztJQUNqQzs7Ozs7O09BTUc7SUFDSCxZQUFZLEVBQUMsYUFBYSxFQUFFLGtCQUFrQixHQUFHLFNBQVMsRUFBRSxZQUFZLEVBQUM7UUFDdkUsSUFBSSxZQUFZO1lBQUUsWUFBWSxDQUFDLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxDQUFBO1FBRWpFLElBQUksQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFBO1FBQ2xDLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxrQkFBa0IsQ0FBQTtRQUM1QyxJQUFJLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQTtRQUNoQyxJQUFJLENBQUMsYUFBYSxHQUFHLFlBQVk7WUFDL0IsQ0FBQyxDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsQ0FBQyxrQkFBa0Is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QixPQUFPO1lBQ0wsVUFBVSxFQUFFLDREQUE0RCxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7WUFDbEgsYUFBYSxFQUFFLEdBQUcsQ0FBQyxXQUFXLEtBQUssSUFBSSxJQUFJLEdBQUcsQ0FBQyxXQUFXLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDO1lBQ3pHLEVBQUUsRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNsQixZQUFZLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUM7WUFDakYsV0FBVyxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDO1lBQ3JDLEtBQUssRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQztZQUN4QixhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWE7U0FDbEMsQ0FBQTtJQUNILENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsZUFBZSxDQUFDLFFBQVE7UUFDdEIsSUFBSSxRQUFRLENBQUMsYUFBYSxLQUFLLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNsRCxNQUFNLElBQUksS0FBSyxDQUFDLDREQUE0RCxDQUFDLENBQUE7UUFDL0UsQ0FBQztJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgVGFibGVEYXRhIGZyb20gXCIuLi9kYXRhYmFzZS90YWJsZS1kYXRhL2luZGV4LmpzXCJcbmltcG9ydCBVVUlEIGZyb20gXCJwdXJlLXV1aWRcIlxuXG5pbXBvcnQge3Njb3BlS2V5fSBmcm9tIFwiLi9xdWVyeS1zY29wZS5qc1wiXG5pbXBvcnQgc3RhYmxlSnNvblN0cmluZ2lmeSBmcm9tIFwiLi9zdGFibGUtanNvbi5qc1wiXG5cbi8qKlxuICogQHR5cGVkZWYge29iamVjdH0gU3luY1Njb3BlUm93XG4gKiBAcHJvcGVydHkge1JlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gY29uZGl0aW9ucyAtIFNjb3BlIGF0dHJpYnV0ZSBjb25kaXRpb25zLlxuICogQHByb3BlcnR5IHtzdHJpbmcgfCBudWxsfSBjdXJzb3JQYXlsb2FkIC0gUGVyc2lzdGVkIGN1cnNvciBKU09OIHBheWxvYWQuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gaWQgLSBTY29wZSByb3cgaWQuXG4gKiBAcHJvcGVydHkge3N0cmluZyB8IG51bGx9IHJlc291cmNlVHlwZSAtIFNjb3BlIHJlc291cmNlL21vZGVsIG5hbWUsIG9yIG51bGwgZm9yIHRoZSBhbGwtdHlwZXMgKHVzZXIpIHNjb3BlLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHNjb3BlRGlnZXN0IC0gRml4ZWQtc2l6ZSBkZXRlcm1pbmlzdGljIGRpZ2VzdCBvZiB0aGUgY2Fub25pY2FsIHNjb3BlIGtleS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzdGF0ZSAtIFNjb3BlIHN0YXRlIChcImFjdGl2ZVwiIG9yIFwicmVtb3ZlZFwiKS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzdG9yZUlkZW50aXR5IC0gUGh5c2ljYWwgc3RvcmUgaWRlbnRpdHkgb3duaW5nIHRoaXMgcm93LlxuICovXG5jb25zdCBUQUJMRV9OQU1FID0gXCJ2ZWxvY2lvdXNfc3luY19zY29wZXNcIlxuY29uc3QgU0NPUEVfRElHRVNUX1BSRUZJWCA9IFwidmVsb2Npb3VzLXN5bmMtc2NvcGU6XCJcblxuLyoqXG4gKiBEaWdlc3RzIGEgc2VyaWFsaXplZCBzY29wZSBpbnRvIGEgZml4ZWQtc2l6ZSBkZXRlcm1pbmlzdGljIGtleSwgc28gc2NvcGVcbiAqIGlkZW50aXRpZXMgd2l0aCBsb25nIGNvbmRpdGlvbiB2YWx1ZXMgZml0IGFuIGluZGV4ZWQgc3RyaW5nIGNvbHVtbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9zeW5jLWNsaWVudC10eXBlcy5qc1wiKS5TZXJpYWxpemVkU3luY1Njb3BlfSBzY29wZSAtIFNlcmlhbGl6ZWQgc3luYyBzY29wZS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IERldGVybWluaXN0aWMgVVVJRHY1IGRpZ2VzdCBvZiB0aGUgY2Fub25pY2FsIHNjb3BlIGtleS5cbiAqL1xuZnVuY3Rpb24gc2NvcGVEaWdlc3RGb3JTY29wZShzY29wZSkge1xuICByZXR1cm4gbmV3IFVVSUQoNSwgXCJuczpVUkxcIiwgYCR7U0NPUEVfRElHRVNUX1BSRUZJWH0ke3Njb3BlS2V5KHNjb3BlKX1gKS5mb3JtYXQoKVxufVxuXG4vKipcbiAqIEZyYW1ld29yay1vd25lZCBsb2NhbCBwZXJzaXN0ZW5jZSBmb3IgZGVjbGFyZWQgc3luYyBzY29wZXMgYW5kIHRoZWlyIGN1cnNvcnMuXG4gKlxuICogQmFja2VkIGJ5IGFuIGF1dG8tY3JlYXRlZCBgdmVsb2Npb3VzX3N5bmNfc2NvcGVzYCB0YWJsZSBvbiB0aGUgY29uZmlndXJlZFxuICogZGF0YWJhc2UsIHdpdGggYSBwcm9jZXNzLWxvY2FsIG1lbW9yeSBmYWxsYmFjayB3aGVuIG5vIGRhdGFiYXNlIGlzXG4gKiBjb25maWd1cmVkIChtaXJyb3JpbmcgdGhlIHNlcnZlciBjaGFuZ2UtZmVlZCBzdG9yZSkuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFN5bmNTY29wZVN0b3JlIHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBzeW5jIHNjb3BlIHN0b3JlLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSBhcmdzLmNvbmZpZ3VyYXRpb24gLSBDb25maWd1cmF0aW9uIG93bmluZyB0aGUgZGF0YWJhc2UuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYXJncy5kYXRhYmFzZUlkZW50aWZpZXJdIC0gRGF0YWJhc2UgaWRlbnRpZmllci5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi90ZW5hbnRzL3RlbmFudC1oYW5kbGUuanNcIikuZGVmYXVsdH0gW2FyZ3MudGVuYW50SGFuZGxlXSAtIEltbXV0YWJsZSB0ZW5hbnQgaGFuZGxlIG93bmluZyB0aGUgcGh5c2ljYWwgc3RvcmUuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7Y29uZmlndXJhdGlvbiwgZGF0YWJhc2VJZGVudGlmaWVyID0gXCJkZWZhdWx0XCIsIHRlbmFudEhhbmRsZX0pIHtcbiAgICBpZiAodGVuYW50SGFuZGxlKSB0ZW5hbnRIYW5kbGUuYXNzZXJ0Q29uZmlndXJhdGlvbihjb25maWd1cmF0aW9uKVxuXG4gICAgdGhpcy5jb25maWd1cmF0aW9uID0gY29uZmlndXJhdGlvblxuICAgIHRoaXMuZGF0YWJhc2VJZGVudGlmaWVyID0gZGF0YWJhc2VJZGVudGlmaWVyXG4gICAgdGhpcy50ZW5hbnRIYW5kbGUgPSB0ZW5hbnRIYW5kbGVcbiAgICB0aGlzLnN0b3JlSWRlbnRpdHkgPSB0ZW5hbnRIYW5kbGVcbiAgICAgID8gdGVuYW50SGFuZGxlLmRhdGFiYXNlSWRlbnRpdHkoZGF0YWJhc2VJZGVudGlmaWVyKVxuICAgICAgOiBgY29uZmlndXJhdGlvbjoke2RhdGFiYXNlSWRlbnRpZmllcn1gXG4gICAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBTeW5jU2NvcGVSb3c+fSAqL1xuICAgIHRoaXMuX21lbW9yeVNjb3BlcyA9IG5ldyBNYXAoKVxuICAgIHRoaXMuX2lzUmVhZHkgPSBmYWxzZVxuICAgIC8qKiBAdHlwZSB7UHJvbWlzZTx2b2lkPiB8IG51bGx9ICovXG4gICAgdGhpcy5fcmVhZHlQcm9taXNlID0gbnVsbFxuICAgIC8qKiBAdHlwZSB7V2Vha01hcDxpbXBvcnQoXCIuLi9kYXRhYmFzZS9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCwge2NvbXBsZXRpb246IFByb21pc2U8dm9pZD4sIHByb21pc2U6IFByb21pc2U8dm9pZD59Pn0gKi9cbiAgICB0aGlzLl90cmFuc2FjdGlvblJlYWR5UHJvbWlzZXMgPSBuZXcgV2Vha01hcCgpXG4gIH1cblxuICAvKipcbiAgICogRW5zdXJlcyB0aGUgYmFja2luZyB0YWJsZSBleGlzdHMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBSZXNvbHZlcyB3aGVuIHJlYWR5LlxuICAgKi9cbiAgYXN5bmMgZW5zdXJlUmVhZHkoKSB7XG4gICAgaWYgKHRoaXMuX2lzUmVhZHkpIHJldHVyblxuXG4gICAgaWYgKHRoaXMuX3VzZXNNZW1vcnlTdG9yYWdlKCkpIHtcbiAgICAgIHRoaXMuX2lzUmVhZHkgPSB0cnVlXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLl93aXRoRGIoYXN5bmMgKGRiKSA9PiBhd2FpdCB0aGlzLl9lbnN1cmVSZWFkeVdpdGhEYihkYikpXG4gIH1cblxuICAvKipcbiAgICogQ29vcmRpbmF0ZXMgZHVyYWJsZSBhbmQgdHJhbnNhY3Rpb24tbG9jYWwgcmVhZGluZXNzIG9uIG9uZSBjb25uZWN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RhdGFiYXNlL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBkYiAtIERhdGFiYXNlIGNvbm5lY3Rpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBSZXNvbHZlcyB3aGVuIHRoaXMgY2FsbGVyIGNhbiB1c2UgdGhlIHRhYmxlLlxuICAgKi9cbiAgYXN5bmMgX2Vuc3VyZVJlYWR5V2l0aERiKGRiKSB7XG4gICAgaWYgKHRoaXMuX2lzUmVhZHkpIHJldHVyblxuXG4gICAgY29uc3QgdHJhbnNhY3Rpb25Db21wbGV0aW9uID0gZGIuaW5zaWRlVHJhbnNhY3Rpb24oKSA/IGRiLnRyYW5zYWN0aW9uQ29tcGxldGlvbigpIDogbnVsbFxuICAgIGNvbnN0IHRyYW5zYWN0aW9uUmVhZHkgPSB0aGlzLl90cmFuc2FjdGlvblJlYWR5UHJvbWlzZXMuZ2V0KGRiKVxuXG4gICAgaWYgKHRyYW5zYWN0aW9uQ29tcGxldGlvbiAmJiB0cmFuc2FjdGlvblJlYWR5Py5jb21wbGV0aW9uID09PSB0cmFuc2FjdGlvbkNvbXBsZXRpb24pIHtcbiAgICAgIGF3YWl0IHRyYW5zYWN0aW9uUmVhZHkucHJvbWlzZVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3JlYWR5UHJvbWlzZSkge1xuICAgICAgY29uc3QgcmVhZHlQcm9taXNlID0gdGhpcy5fcmVhZHlQcm9taXNlXG5cbiAgICAgIGF3YWl0IHJlYWR5UHJvbWlzZVxuICAgICAgaWYgKHRoaXMuX3JlYWR5UHJvbWlzZSA9PT0gcmVhZHlQcm9taXNlKSB0aGlzLl9yZWFkeVByb21pc2UgPSBudWxsXG4gICAgICBpZiAodGhpcy5faXNSZWFkeSkgcmV0dXJuXG5cbiAgICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVhZHkoKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHRyYW5zYWN0aW9uQ29tcGxldGlvbikge1xuICAgICAgY29uc3QgdGFibGVSZWFkeVByb21pc2UgPSB0aGlzLl9lbnN1cmVTY29wZXNUYWJsZShkYilcbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uUmVhZHlQcm9taXNlID0gdGFibGVSZWFkeVByb21pc2UudGhlbigoKSA9PiB1bmRlZmluZWQpXG5cbiAgICAgIGNvbnN0IGR1cmFibGVSZWFkeVByb21pc2UgPSB0YWJsZVJlYWR5UHJvbWlzZS50aGVuKGFzeW5jIChjcmVhdGVkKSA9PiB7XG4gICAgICAgIGlmICghY3JlYXRlZCkge1xuICAgICAgICAgIHRoaXMuX2lzUmVhZHkgPSB0cnVlXG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCB0cmFuc2FjdGlvbkNvbXBsZXRpb25cbiAgICAgIH0pXG5cbiAgICAgIHRoaXMuX3RyYW5zYWN0aW9uUmVhZHlQcm9taXNlcy5zZXQoZGIsIHtjb21wbGV0aW9uOiB0cmFuc2FjdGlvbkNvbXBsZXRpb24sIHByb21pc2U6IHRyYW5zYWN0aW9uUmVhZHlQcm9taXNlfSlcbiAgICAgIHRoaXMuX3JlYWR5UHJvbWlzZSA9IGR1cmFibGVSZWFkeVByb21pc2VcbiAgICAgIGF3YWl0IHRyYW5zYWN0aW9uUmVhZHlQcm9taXNlXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLl9yZWFkeVByb21pc2UgPSB0aGlzLl9lbnN1cmVTY29wZXNUYWJsZShkYikudGhlbigoKSA9PiB7XG4gICAgICB0aGlzLl9pc1JlYWR5ID0gdHJ1ZVxuICAgIH0pXG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5fcmVhZHlQcm9taXNlXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGlmICghdGhpcy5faXNSZWFkeSkgdGhpcy5fcmVhZHlQcm9taXNlID0gbnVsbFxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kcyBvciBjcmVhdGVzIHRoZSBzY29wZSByb3cgZm9yIGEgc2VyaWFsaXplZCBzY29wZSwgcmVhY3RpdmF0aW5nIHJlbW92ZWQgc2NvcGVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vc3luYy1jbGllbnQtdHlwZXMuanNcIikuU2VyaWFsaXplZFN5bmNTY29wZX0gc2NvcGUgLSBTZXJpYWxpemVkIHN5bmMgc2NvcGUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFN5bmNTY29wZVJvdz59IFBlcnNpc3RlZCBzY29wZSByb3cuXG4gICAqL1xuICBhc3luYyBmaW5kT3JDcmVhdGVTY29wZShzY29wZSkge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVhZHkoKVxuXG4gICAgY29uc3QgZGlnZXN0ID0gc2NvcGVEaWdlc3RGb3JTY29wZShzY29wZSlcblxuICAgIGlmICh0aGlzLl91c2VzTWVtb3J5U3RvcmFnZSgpKSB7XG4gICAgICBjb25zdCBleGlzdGluZ1Njb3BlID0gdGhpcy5fbWVtb3J5U2NvcGVzLmdldChkaWdlc3QpXG5cbiAgICAgIGlmIChleGlzdGluZ1Njb3BlKSB7XG4gICAgICAgIGlmIChleGlzdGluZ1Njb3BlLnN0YXRlICE9PSBcImFjdGl2ZVwiKSBleGlzdGluZ1Njb3BlLnN0YXRlID0gXCJhY3RpdmVcIlxuXG4gICAgICAgIHJldHVybiBleGlzdGluZ1Njb3BlXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5ld1Njb3BlID0ge1xuICAgICAgICBjb25kaXRpb25zOiBzY29wZS5jb25kaXRpb25zLFxuICAgICAgICBjdXJzb3JQYXlsb2FkOiBudWxsLFxuICAgICAgICBpZDogbmV3IFVVSUQoNCkuZm9ybWF0KCksXG4gICAgICAgIHJlc291cmNlVHlwZTogc2NvcGUucmVzb3VyY2VUeXBlID8/IG51bGwsXG4gICAgICAgIHNjb3BlRGlnZXN0OiBkaWdlc3QsXG4gICAgICAgIHN0YXRlOiBcImFjdGl2ZVwiLFxuICAgICAgICBzdG9yZUlkZW50aXR5OiB0aGlzLnN0b3JlSWRlbnRpdHlcbiAgICAgIH1cblxuICAgICAgdGhpcy5fbWVtb3J5U2NvcGVzLnNldChkaWdlc3QsIG5ld1Njb3BlKVxuXG4gICAgICByZXR1cm4gbmV3U2NvcGVcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5fd2l0aERiKGFzeW5jIChkYikgPT4ge1xuICAgICAgY29uc3QgZXhpc3RpbmdSb3cgPSBhd2FpdCB0aGlzLl9yb3dCeVNjb3BlRGlnZXN0KGRiLCBkaWdlc3QpXG5cbiAgICAgIGlmIChleGlzdGluZ1Jvdykge1xuICAgICAgICBpZiAoZXhpc3RpbmdSb3cuc3RhdGUgIT09IFwiYWN0aXZlXCIpIHtcbiAgICAgICAgICBhd2FpdCBkYi51cGRhdGUoe2NvbmRpdGlvbnM6IHtpZDogZXhpc3RpbmdSb3cuaWR9LCBkYXRhOiB7c3RhdGU6IFwiYWN0aXZlXCIsIHVwZGF0ZWRfYXQ6IG5ldyBEYXRlKCl9LCB0YWJsZU5hbWU6IFRBQkxFX05BTUV9KVxuICAgICAgICAgIGV4aXN0aW5nUm93LnN0YXRlID0gXCJhY3RpdmVcIlxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGV4aXN0aW5nUm93XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IGRiLmluc2VydCh7XG4gICAgICAgIHRhYmxlTmFtZTogVEFCTEVfTkFNRSxcbiAgICAgICAgZGF0YToge1xuICAgICAgICAgIGNvbmRpdGlvbnNfanNvbjogc3RhYmxlSnNvblN0cmluZ2lmeShzY29wZS5jb25kaXRpb25zKSxcbiAgICAgICAgICBjcmVhdGVkX2F0OiBuZXcgRGF0ZSgpLFxuICAgICAgICAgIGN1cnNvcl9qc29uOiBudWxsLFxuICAgICAgICAgIGlkOiBuZXcgVVVJRCg0KS5mb3JtYXQoKSxcbiAgICAgICAgICAvLyBUaGUgYWxsLXR5cGVzICh1c2VyKSBzY29wZSBoYXMgbm8gcmVzb3VyY2UgdHlwZTsgdGhlIGNvbHVtbiBpcyBub24tbnVsbCwgc28gaXRcbiAgICAgICAgICAvLyBzdG9yZXMgYXMgYW4gZW1wdHkgc3RyaW5nIGFuZCBub3JtYWxpemVzIGJhY2sgdG8gbnVsbCBvbiByZWFkLlxuICAgICAgICAgIHJlc291cmNlX3R5cGU6IHNjb3BlLnJlc291cmNlVHlwZSA/PyBcIlwiLFxuICAgICAgICAgIHNjb3BlX2RpZ2VzdDogZGlnZXN0LFxuICAgICAgICAgIHN0YXRlOiBcImFjdGl2ZVwiLFxuICAgICAgICAgIHVwZGF0ZWRfYXQ6IG5ldyBEYXRlKClcbiAgICAgICAgfVxuICAgICAgfSlcblxuICAgICAgY29uc3QgY3JlYXRlZFJvdyA9IGF3YWl0IHRoaXMuX3Jvd0J5U2NvcGVEaWdlc3QoZGIsIGRpZ2VzdClcblxuICAgICAgaWYgKCFjcmVhdGVkUm93KSB0aHJvdyBuZXcgRXJyb3IoXCJGYWlsZWQgdG8gcGVyc2lzdCBzeW5jIHNjb3BlXCIpXG5cbiAgICAgIHJldHVybiBjcmVhdGVkUm93XG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFsbCBhY3RpdmUgc2NvcGUgcm93cy5cbiAgICogQHJldHVybnMge1Byb21pc2U8U3luY1Njb3BlUm93W10+fSBBY3RpdmUgc2NvcGUgcm93cy5cbiAgICovXG4gIGFzeW5jIGFjdGl2ZVNjb3BlcygpIHtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlYWR5KClcblxuICAgIGlmICh0aGlzLl91c2VzTWVtb3J5U3RvcmFnZSgpKSB7XG4gICAgICByZXR1cm4gWy4uLnRoaXMuX21lbW9yeVNjb3Blcy52YWx1ZXMoKV0uZmlsdGVyKChzY29wZSkgPT4gc2NvcGUuc3RhdGUgPT09IFwiYWN0aXZlXCIpXG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuX3dpdGhEYihhc3luYyAoZGIpID0+IHtcbiAgICAgIGNvbnN0IHJvd3MgPSAvKiogQHR5cGUge0FycmF5PFJlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pj59ICovIChhd2FpdCBkYlxuICAgICAgICAubmV3UXVlcnkoKVxuICAgICAgICAuZnJvbShUQUJMRV9OQU1FKVxuICAgICAgICAud2hlcmUoe3N0YXRlOiBcImFjdGl2ZVwifSlcbiAgICAgICAgLm9yZGVyKFwiY3JlYXRlZF9hdCBBU0NcIilcbiAgICAgICAgLnJlc3VsdHMoKSlcblxuICAgICAgcmV0dXJuIHJvd3MubWFwKChyb3cpID0+IHRoaXMuX25vcm1hbGl6ZVNjb3BlUm93KHJvdykpXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkcyB0aGUgcGVyc2lzdGVkIGN1cnNvciBwYXlsb2FkIGZvciBhIHNjb3BlIHJvdy5cbiAgICogQHBhcmFtIHtTeW5jU2NvcGVSb3d9IHNjb3BlUm93IC0gU2NvcGUgcm93LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmcgfCBudWxsPn0gQ3Vyc29yIEpTT04gcGF5bG9hZC5cbiAgICovXG4gIGFzeW5jIGxvYWRDdXJzb3Ioc2NvcGVSb3cpIHtcbiAgICB0aGlzLl9hc3NlcnRTY29wZVJvdyhzY29wZVJvdylcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlYWR5KClcblxuICAgIGlmICh0aGlzLl91c2VzTWVtb3J5U3RvcmFnZSgpKSB7XG4gICAgICBjb25zdCBjdXJyZW50U2NvcGUgPSB0aGlzLl9tZW1vcnlTY29wZXMuZ2V0KHNjb3BlUm93LnNjb3BlRGlnZXN0KVxuXG4gICAgICByZXR1cm4gY3VycmVudFNjb3BlPy5pZCA9PT0gc2NvcGVSb3cuaWQgPyBjdXJyZW50U2NvcGUuY3Vyc29yUGF5bG9hZCA6IG51bGxcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5fd2l0aERiKGFzeW5jIChkYikgPT4ge1xuICAgICAgY29uc3Qgcm93ID0gYXdhaXQgdGhpcy5fcm93QnlTY29wZURpZ2VzdChkYiwgc2NvcGVSb3cuc2NvcGVEaWdlc3QpXG5cbiAgICAgIHJldHVybiByb3c/LmlkID09PSBzY29wZVJvdy5pZCA/IHJvdy5jdXJzb3JQYXlsb2FkIDogbnVsbFxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUGVyc2lzdHMgdGhlIGFja25vd2xlZGdlZCBjdXJzb3IgZm9yIGEgc2NvcGUgcm93LlxuICAgKiBAcGFyYW0ge1N5bmNTY29wZVJvd30gc2NvcGVSb3cgLSBTY29wZSByb3cuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9zeW5jLWFwaS1jbGllbnQtdHlwZXMuanNcIikuU3luY0N1cnNvcn0gY3Vyc29yIC0gQWNrbm93bGVkZ2VkIGN1cnNvci5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBzYXZlQ3Vyc29yKHNjb3BlUm93LCBjdXJzb3IpIHtcbiAgICB0aGlzLl9hc3NlcnRTY29wZVJvdyhzY29wZVJvdylcbiAgICBpZiAoIWN1cnNvcikgcmV0dXJuXG5cbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlYWR5KClcblxuICAgIGNvbnN0IGN1cnNvclBheWxvYWQgPSBKU09OLnN0cmluZ2lmeShjdXJzb3IpXG5cbiAgICBpZiAodGhpcy5fdXNlc01lbW9yeVN0b3JhZ2UoKSkge1xuICAgICAgY29uc3QgbWVtb3J5U2NvcGUgPSB0aGlzLl9tZW1vcnlTY29wZXMuZ2V0KHNjb3BlUm93LnNjb3BlRGlnZXN0KVxuXG4gICAgICBpZiAoIW1lbW9yeVNjb3BlKSB0aHJvdyBuZXcgRXJyb3IoYE5vIHN5bmMgc2NvcGUgZm91bmQgZm9yOiAke3Njb3BlUm93LnNjb3BlRGlnZXN0fWApXG4gICAgICBpZiAobWVtb3J5U2NvcGUuaWQgIT09IHNjb3BlUm93LmlkIHx8IG1lbW9yeVNjb3BlLnN0YXRlICE9PSBcImFjdGl2ZVwiKSByZXR1cm5cblxuICAgICAgbWVtb3J5U2NvcGUuY3Vyc29yUGF5bG9hZCA9IGN1cnNvclBheWxvYWRcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuX3dpdGhEYihhc3luYyAoZGIpID0+IHtcbiAgICAgIGF3YWl0IGRiLnVwZGF0ZSh7XG4gICAgICAgIGNvbmRpdGlvbnM6IHtpZDogc2NvcGVSb3cuaWQsIHNjb3BlX2RpZ2VzdDogc2NvcGVSb3cuc2NvcGVEaWdlc3QsIHN0YXRlOiBcImFjdGl2ZVwifSxcbiAgICAgICAgZGF0YToge2N1cnNvcl9qc29uOiBjdXJzb3JQYXlsb2FkLCB1cGRhdGVkX2F0OiBuZXcgRGF0ZSgpfSxcbiAgICAgICAgdGFibGVOYW1lOiBUQUJMRV9OQU1FXG4gICAgICB9KVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogRGVhY3RpdmF0ZXMgdGhlIHNjb3BlIHJvdyBmb3IgYSBzZXJpYWxpemVkIHNjb3BlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vc3luYy1jbGllbnQtdHlwZXMuanNcIikuU2VyaWFsaXplZFN5bmNTY29wZX0gc2NvcGUgLSBTZXJpYWxpemVkIHN5bmMgc2NvcGUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgKi9cbiAgYXN5bmMgZGVhY3RpdmF0ZShzY29wZSkge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVhZHkoKVxuXG4gICAgY29uc3QgZGlnZXN0ID0gc2NvcGVEaWdlc3RGb3JTY29wZShzY29wZSlcblxuICAgIGlmICh0aGlzLl91c2VzTWVtb3J5U3RvcmFnZSgpKSB7XG4gICAgICBjb25zdCBtZW1vcnlTY29wZSA9IHRoaXMuX21lbW9yeVNjb3Blcy5nZXQoZGlnZXN0KVxuXG4gICAgICBpZiAobWVtb3J5U2NvcGUpIG1lbW9yeVNjb3BlLnN0YXRlID0gXCJyZW1vdmVkXCJcblxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5fd2l0aERiKGFzeW5jIChkYikgPT4ge1xuICAgICAgYXdhaXQgZGIudXBkYXRlKHtjb25kaXRpb25zOiB7c2NvcGVfZGlnZXN0OiBkaWdlc3R9LCBkYXRhOiB7c3RhdGU6IFwicmVtb3ZlZFwiLCB1cGRhdGVkX2F0OiBuZXcgRGF0ZSgpfSwgdGFibGVOYW1lOiBUQUJMRV9OQU1FfSlcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIEF0b21pY2FsbHkgZGVhY3RpdmF0ZXMgc2VsZWN0ZWQgc2NvcGVzLCBjbGVhcnMgdGhlaXIgY3Vyc29ycyBhbmQgcm90YXRlc1xuICAgKiB0aGVpciByb3cgaWRlbnRpdGllcy4gQSBjdXJzb3Igc2F2ZSBjYXJyeWluZyBhIHByZS1yZXNldCByb3cgaWRlbnRpdHkgY2FuXG4gICAqIHRoZXJlZm9yZSBuZXZlciByZXBvcHVsYXRlIHRoZSByZXNldCBzY29wZS4gVGhlIG9wdGlvbmFsIGNsZWFudXAgaG9vayBydW5zXG4gICAqIGluc2lkZSB0aGUgc2FtZSBkYXRhYmFzZSB0cmFuc2FjdGlvbiwgYWxsb3dpbmcgYW4gYXBwIHRvIHB1cmdlIHRoZSBsb2NhbFxuICAgKiByb3dzIG93bmVkIGJ5IHRob3NlIHNjb3BlcyB3aXRob3V0IGEgY3Vyc29yL2NhY2hlIHNwbGl0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vc3luYy1jbGllbnQtdHlwZXMuanNcIikuU2VyaWFsaXplZFN5bmNTY29wZVtdfSBzY29wZXMgLSBTZWxlY3RlZCBzY29wZXMgdG8gcmVzZXQuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0aW9uc10gLSBSZXNldCBvcHRpb25zLlxuICAgKiBAcGFyYW0geyhhcmdzOiB7Y29ubmVjdGlvbjogaW1wb3J0KFwiLi4vZGF0YWJhc2UvZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgfCBudWxsLCBzY29wZXM6IGltcG9ydChcIi4vc3luYy1jbGllbnQtdHlwZXMuanNcIikuU2VyaWFsaXplZFN5bmNTY29wZVtdfSkgPT4gUHJvbWlzZTx2b2lkPiB8IHZvaWR9IFtvcHRpb25zLmNsZWFudXBdIC0gQXBwLW93bmVkIGxvY2FsLXJvdyBjbGVhbnVwIGhvb2suXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgKi9cbiAgYXN5bmMgcmVzZXQoc2NvcGVzLCB7Y2xlYW51cH0gPSB7fSkge1xuICAgIGlmICghQXJyYXkuaXNBcnJheShzY29wZXMpIHx8IHNjb3Blcy5sZW5ndGggPT09IDApIHRocm93IG5ldyBFcnJvcihcIlN5bmNTY29wZVN0b3JlLnJlc2V0IHJlcXVpcmVzIGF0IGxlYXN0IG9uZSBzZXJpYWxpemVkIHNjb3BlXCIpXG4gICAgaWYgKGNsZWFudXAgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgY2xlYW51cCAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgRXJyb3IoXCJTeW5jU2NvcGVTdG9yZS5yZXNldCBjbGVhbnVwIG11c3QgYmUgYSBmdW5jdGlvblwiKVxuXG4gICAgYXdhaXQgdGhpcy5lbnN1cmVSZWFkeSgpXG5cbiAgICBjb25zdCB1bmlxdWVTY29wZXMgPSBbLi4ubmV3IE1hcChzY29wZXMubWFwKChzY29wZSkgPT4gW3Njb3BlRGlnZXN0Rm9yU2NvcGUoc2NvcGUpLCBzY29wZV0pKS52YWx1ZXMoKV1cblxuICAgIGlmICh0aGlzLl91c2VzTWVtb3J5U3RvcmFnZSgpKSB7XG4gICAgICBpZiAoY2xlYW51cCkgYXdhaXQgY2xlYW51cCh7Y29ubmVjdGlvbjogbnVsbCwgc2NvcGVzOiB1bmlxdWVTY29wZXN9KVxuXG4gICAgICBmb3IgKGNvbnN0IHNjb3BlIG9mIHVuaXF1ZVNjb3BlcykgdGhpcy5fcmVzZXRNZW1vcnlTY29wZShzY29wZSlcblxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5fd2l0aERiKGFzeW5jIChkYikgPT4ge1xuICAgICAgYXdhaXQgZGIudHJhbnNhY3Rpb24oYXN5bmMgKCkgPT4ge1xuICAgICAgICBpZiAoY2xlYW51cCkgYXdhaXQgY2xlYW51cCh7Y29ubmVjdGlvbjogZGIsIHNjb3BlczogdW5pcXVlU2NvcGVzfSlcblxuICAgICAgICBmb3IgKGNvbnN0IHNjb3BlIG9mIHVuaXF1ZVNjb3BlcykgYXdhaXQgdGhpcy5fcmVzZXREYXRhYmFzZVNjb3BlKHtkYiwgc2NvcGV9KVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0cyBvbmUgbWVtb3J5LWJhY2tlZCBzY29wZSB3aGlsZSBwcmVzZXJ2aW5nIHJlcGVhdGVkLXJlc2V0IGlkZW1wb3RlbmNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vc3luYy1jbGllbnQtdHlwZXMuanNcIikuU2VyaWFsaXplZFN5bmNTY29wZX0gc2NvcGUgLSBTY29wZSB0byByZXNldC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBfcmVzZXRNZW1vcnlTY29wZShzY29wZSkge1xuICAgIGNvbnN0IGRpZ2VzdCA9IHNjb3BlRGlnZXN0Rm9yU2NvcGUoc2NvcGUpXG4gICAgY29uc3QgbWVtb3J5U2NvcGUgPSB0aGlzLl9tZW1vcnlTY29wZXMuZ2V0KGRpZ2VzdClcblxuICAgIGlmICghbWVtb3J5U2NvcGUgfHwgKG1lbW9yeVNjb3BlLnN0YXRlID09PSBcInJlbW92ZWRcIiAmJiBtZW1vcnlTY29wZS5jdXJzb3JQYXlsb2FkID09PSBudWxsKSkgcmV0dXJuXG5cbiAgICB0aGlzLl9tZW1vcnlTY29wZXMuc2V0KGRpZ2VzdCwge1xuICAgICAgLi4ubWVtb3J5U2NvcGUsXG4gICAgICBjdXJzb3JQYXlsb2FkOiBudWxsLFxuICAgICAgaWQ6IG5ldyBVVUlEKDQpLmZvcm1hdCgpLFxuICAgICAgc3RhdGU6IFwicmVtb3ZlZFwiXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNldHMgb25lIGRhdGFiYXNlLWJhY2tlZCBzY29wZSB3aGlsZSBwcmVzZXJ2aW5nIHJlcGVhdGVkLXJlc2V0IGlkZW1wb3RlbmNlLlxuICAgKiBAcGFyYW0ge3tkYjogaW1wb3J0KFwiLi4vZGF0YWJhc2UvZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQsIHNjb3BlOiBpbXBvcnQoXCIuL3N5bmMtY2xpZW50LXR5cGVzLmpzXCIpLlNlcmlhbGl6ZWRTeW5jU2NvcGV9fSBhcmdzIC0gRGF0YWJhc2UgYW5kIHNjb3BlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIF9yZXNldERhdGFiYXNlU2NvcGUoe2RiLCBzY29wZX0pIHtcbiAgICBjb25zdCBkaWdlc3QgPSBzY29wZURpZ2VzdEZvclNjb3BlKHNjb3BlKVxuICAgIGNvbnN0IGV4aXN0aW5nUm93ID0gYXdhaXQgdGhpcy5fcm93QnlTY29wZURpZ2VzdChkYiwgZGlnZXN0KVxuXG4gICAgaWYgKCFleGlzdGluZ1JvdyB8fCAoZXhpc3RpbmdSb3cuc3RhdGUgPT09IFwicmVtb3ZlZFwiICYmIGV4aXN0aW5nUm93LmN1cnNvclBheWxvYWQgPT09IG51bGwpKSByZXR1cm5cblxuICAgIGF3YWl0IGRiLnVwZGF0ZSh7XG4gICAgICBjb25kaXRpb25zOiB7aWQ6IGV4aXN0aW5nUm93LmlkLCBzY29wZV9kaWdlc3Q6IGRpZ2VzdH0sXG4gICAgICBkYXRhOiB7Y3Vyc29yX2pzb246IG51bGwsIGlkOiBuZXcgVVVJRCg0KS5mb3JtYXQoKSwgc3RhdGU6IFwicmVtb3ZlZFwiLCB1cGRhdGVkX2F0OiBuZXcgRGF0ZSgpfSxcbiAgICAgIHRhYmxlTmFtZTogVEFCTEVfTkFNRVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogV2hldGhlciB0aGUgc3RvcmUgcnVucyB3aXRob3V0IGEgY29uZmlndXJlZCBkYXRhYmFzZS5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgbWVtb3J5IHN0b3JhZ2UgaXMgdXNlZC5cbiAgICovXG4gIF91c2VzTWVtb3J5U3RvcmFnZSgpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuICF0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0RGF0YWJhc2VDb25maWd1cmF0aW9uKClbdGhpcy5kYXRhYmFzZUlkZW50aWZpZXJdXG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGEgY2FsbGJhY2sgd2l0aCBhIGRhdGFiYXNlIGNvbm5lY3Rpb24uXG4gICAqIEB0ZW1wbGF0ZSBSZXN1bHRcbiAgICogQHBhcmFtIHsoZGI6IGltcG9ydChcIi4uL2RhdGFiYXNlL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0KSA9PiBQcm9taXNlPFJlc3VsdD59IGNhbGxiYWNrIC0gRGF0YWJhc2UgY2FsbGJhY2suXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFJlc3VsdD59IENhbGxiYWNrIHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIF93aXRoRGIoY2FsbGJhY2spIHtcbiAgICBpZiAodGhpcy50ZW5hbnRIYW5kbGUpIHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnRlbmFudEhhbmRsZS5kYXRhYmFzZU9wZXJhdGlvbih7ZGF0YWJhc2VJZGVudGlmaWVyOiB0aGlzLmRhdGFiYXNlSWRlbnRpZmllciwgbmFtZTogXCJUZW5hbnQgc3luYyBzY29wZSBzdG9yZVwifSwgYXN5bmMgKG9wZXJhdGlvbikgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgY2FsbGJhY2sob3BlcmF0aW9uLmNvbm5lY3Rpb24oKSlcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5lbnN1cmVDb25uZWN0aW9ucyh7ZGF0YWJhc2VJZGVudGlmaWVyczogW3RoaXMuZGF0YWJhc2VJZGVudGlmaWVyXSwgbmFtZTogXCJTeW5jIHNjb3BlIHN0b3JlXCJ9LCBhc3luYyAoZGJzKSA9PiB7XG4gICAgICBjb25zdCBkYiA9IGRic1t0aGlzLmRhdGFiYXNlSWRlbnRpZmllcl1cblxuICAgICAgaWYgKCFkYikgdGhyb3cgbmV3IEVycm9yKGBObyBkYXRhYmFzZSBjb25uZWN0aW9uIGF2YWlsYWJsZSBmb3IgaWRlbnRpZmllcjogJHt0aGlzLmRhdGFiYXNlSWRlbnRpZmllcn1gKVxuXG4gICAgICByZXR1cm4gYXdhaXQgY2FsbGJhY2soZGIpXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmVzIHRoZSBzY29wZXMgdGFibGUgZXhpc3RzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RhdGFiYXNlL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBkYiAtIERhdGFiYXNlIGNvbm5lY3Rpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGJvb2xlYW4+fSBXaGV0aGVyIHRoZSB0YWJsZSBoYWQgdG8gYmUgY3JlYXRlZC5cbiAgICovXG4gIGFzeW5jIF9lbnN1cmVTY29wZXNUYWJsZShkYikge1xuICAgIGlmIChhd2FpdCBkYi50YWJsZUV4aXN0cyhUQUJMRV9OQU1FKSkgcmV0dXJuIGZhbHNlXG5cbiAgICBjb25zdCB0YWJsZSA9IG5ldyBUYWJsZURhdGEoVEFCTEVfTkFNRSwge2lmTm90RXhpc3RzOiB0cnVlfSlcblxuICAgIHRhYmxlLnN0cmluZyhcImlkXCIsIHtudWxsOiBmYWxzZSwgcHJpbWFyeUtleTogdHJ1ZX0pXG4gICAgdGFibGUuc3RyaW5nKFwic2NvcGVfZGlnZXN0XCIsIHtpbmRleDogdHJ1ZSwgbnVsbDogZmFsc2V9KVxuICAgIHRhYmxlLnN0cmluZyhcInJlc291cmNlX3R5cGVcIiwge2luZGV4OiB0cnVlLCBudWxsOiBmYWxzZX0pXG4gICAgdGFibGUudGV4dChcImNvbmRpdGlvbnNfanNvblwiLCB7bnVsbDogZmFsc2V9KVxuICAgIHRhYmxlLnRleHQoXCJjdXJzb3JfanNvblwiLCB7bnVsbDogdHJ1ZX0pXG4gICAgdGFibGUuc3RyaW5nKFwic3RhdGVcIiwge2luZGV4OiB0cnVlLCBudWxsOiBmYWxzZX0pXG4gICAgdGFibGUuZGF0ZXRpbWUoXCJjcmVhdGVkX2F0XCIsIHtudWxsOiBmYWxzZX0pXG4gICAgdGFibGUuZGF0ZXRpbWUoXCJ1cGRhdGVkX2F0XCIsIHtudWxsOiBmYWxzZX0pXG5cbiAgICBhd2FpdCBkYi5jcmVhdGVUYWJsZSh0YWJsZSlcblxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgYSBzY29wZSByb3cgYnkgaXRzIGRpZ2VzdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gZGIgLSBEYXRhYmFzZSBjb25uZWN0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZGlnZXN0IC0gRml4ZWQtc2l6ZSBzY29wZSBkaWdlc3QuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFN5bmNTY29wZVJvdyB8IG51bGw+fSBTY29wZSByb3cgb3IgbnVsbC5cbiAgICovXG4gIGFzeW5jIF9yb3dCeVNjb3BlRGlnZXN0KGRiLCBkaWdlc3QpIHtcbiAgICBjb25zdCByb3dzID0gLyoqIEB0eXBlIHtBcnJheTxSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj4+fSAqLyAoYXdhaXQgZGJcbiAgICAgIC5uZXdRdWVyeSgpXG4gICAgICAuZnJvbShUQUJMRV9OQU1FKVxuICAgICAgLndoZXJlKHtzY29wZV9kaWdlc3Q6IGRpZ2VzdH0pXG4gICAgICAubGltaXQoMSlcbiAgICAgIC5yZXN1bHRzKCkpXG5cbiAgICByZXR1cm4gcm93c1swXSA/IHRoaXMuX25vcm1hbGl6ZVNjb3BlUm93KHJvd3NbMF0pIDogbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIE5vcm1hbGl6ZXMgYSByYXcgc2NvcGUgdGFibGUgcm93LlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gcm93IC0gUmF3IHRhYmxlIHJvdy5cbiAgICogQHJldHVybnMge1N5bmNTY29wZVJvd30gTm9ybWFsaXplZCBzY29wZSByb3cuXG4gICAqL1xuICBfbm9ybWFsaXplU2NvcGVSb3cocm93KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbmRpdGlvbnM6IC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+fSAqLyAoSlNPTi5wYXJzZShTdHJpbmcocm93LmNvbmRpdGlvbnNfanNvbikpKSxcbiAgICAgIGN1cnNvclBheWxvYWQ6IHJvdy5jdXJzb3JfanNvbiA9PT0gbnVsbCB8fCByb3cuY3Vyc29yX2pzb24gPT09IHVuZGVmaW5lZCA/IG51bGwgOiBTdHJpbmcocm93LmN1cnNvcl9qc29uKSxcbiAgICAgIGlkOiBTdHJpbmcocm93LmlkKSxcbiAgICAgIHJlc291cmNlVHlwZTogU3RyaW5nKHJvdy5yZXNvdXJjZV90eXBlKSA9PT0gXCJcIiA/IG51bGwgOiBTdHJpbmcocm93LnJlc291cmNlX3R5cGUpLFxuICAgICAgc2NvcGVEaWdlc3Q6IFN0cmluZyhyb3cuc2NvcGVfZGlnZXN0KSxcbiAgICAgIHN0YXRlOiBTdHJpbmcocm93LnN0YXRlKSxcbiAgICAgIHN0b3JlSWRlbnRpdHk6IHRoaXMuc3RvcmVJZGVudGl0eVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWplY3RzIHBhc3NpbmcgYSBzY29wZSByb3cgY2FwdHVyZWQgZnJvbSBhbm90aGVyIHBoeXNpY2FsIHN0b3JlLlxuICAgKiBAcGFyYW0ge1N5bmNTY29wZVJvd30gc2NvcGVSb3cgLSBTY29wZSByb3cgdG8gdmFsaWRhdGUuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgX2Fzc2VydFNjb3BlUm93KHNjb3BlUm93KSB7XG4gICAgaWYgKHNjb3BlUm93LnN0b3JlSWRlbnRpdHkgIT09IHRoaXMuc3RvcmVJZGVudGl0eSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU3luYyBzY29wZSByb3cgYmVsb25ncyB0byBhbm90aGVyIHBoeXNpY2FsIHRlbmFudCBkYXRhYmFzZVwiKVxuICAgIH1cbiAgfVxufVxuIl19
|
|
@@ -71,16 +71,19 @@ export default class SyncApiClient {
|
|
|
71
71
|
* @param {string} args.authenticationToken - Authentication token.
|
|
72
72
|
* @param {number} [args.batchSize] - Batch size.
|
|
73
73
|
* @param {import("./sync-client-types.js").SyncClientConflictTrackingConfig} args.conflictTracking - Tracking configuration.
|
|
74
|
-
* @param {(payload: {authenticationToken: string, syncs: Array<Record<string, ReturnType<typeof JSON.parse>>>}) => Promise<SyncReplayResponse>} args.postReplay - Transport boundary.
|
|
74
|
+
* @param {(payload: {authenticationToken: string, syncs: Array<Record<string, ReturnType<typeof JSON.parse>>>}, options?: {signal?: AbortSignal}) => Promise<SyncReplayResponse>} args.postReplay - Transport boundary.
|
|
75
75
|
* @param {(identity: string) => number} args.remoteGeneration - Current remote generation.
|
|
76
76
|
* @param {string} args.resourceType - Resource whose log records should drain.
|
|
77
|
+
* @param {AbortSignal} [args.signal] - Lifecycle cancellation signal.
|
|
77
78
|
* @returns {Promise<void>} Resolves when no ready intent remains.
|
|
78
79
|
*/
|
|
79
|
-
static async replayConflictTrackedSyncs({authenticationToken, batchSize, conflictTracking, postReplay, remoteGeneration, resourceType}) {
|
|
80
|
+
static async replayConflictTrackedSyncs({authenticationToken, batchSize, conflictTracking, postReplay, remoteGeneration, resourceType, signal}) {
|
|
80
81
|
const maxBatchSize = this.normalizedBatchSize(batchSize)
|
|
81
82
|
|
|
82
83
|
while (true) {
|
|
84
|
+
throwIfSyncAborted(signal)
|
|
83
85
|
const records = await conflictTracking.mutationLog.records()
|
|
86
|
+
throwIfSyncAborted(signal)
|
|
84
87
|
const statuses = new Map(records.map((record) => [record.mutation.clientMutationId, record.status]))
|
|
85
88
|
const pending = records.filter((record) => record.status === "pending" && record.mutation.model === resourceType)
|
|
86
89
|
const ready = pending.filter((record) => record.dependencies.every((dependency) => statuses.get(dependency.clientMutationId) === "synced"))
|
|
@@ -92,13 +95,15 @@ export default class SyncApiClient {
|
|
|
92
95
|
const response = await postReplay({
|
|
93
96
|
authenticationToken,
|
|
94
97
|
syncs: groups.map((group) => this.conflictReplayPayload(group))
|
|
95
|
-
})
|
|
98
|
+
}, {signal})
|
|
96
99
|
|
|
100
|
+
throwIfSyncAborted(signal)
|
|
97
101
|
this.ensureSuccessfulResponse(response)
|
|
98
102
|
|
|
99
103
|
const responsesById = new Map((response.syncs || []).map((result) => [String(result.id), result]))
|
|
100
104
|
|
|
101
105
|
for (const group of groups) {
|
|
106
|
+
throwIfSyncAborted(signal)
|
|
102
107
|
const result = responsesById.get(group[0].mutation.clientMutationId)
|
|
103
108
|
|
|
104
109
|
if (!result) throw new Error(`Sync response missing result for mutation ${group[0].mutation.clientMutationId}`)
|
|
@@ -108,6 +113,7 @@ export default class SyncApiClient {
|
|
|
108
113
|
|
|
109
114
|
for (const record of group) {
|
|
110
115
|
await applySyncReplayResultToLocalMutationLog({mutationLog: conflictTracking.mutationLog, record, result: /** @type {Record<string, ReturnType<typeof JSON.parse>>} */ (result)})
|
|
116
|
+
throwIfSyncAborted(signal)
|
|
111
117
|
}
|
|
112
118
|
|
|
113
119
|
if (["successful", "duplicate"].includes(result.syncState) && result.serverVersion !== undefined) {
|
|
@@ -115,6 +121,7 @@ export default class SyncApiClient {
|
|
|
115
121
|
|
|
116
122
|
if (remoteGeneration(identity) === generations.get(group[0].mutation.clientMutationId)) {
|
|
117
123
|
await this.rebaseConflictSuccessor({conflictTracking, predecessor: group[group.length - 1], serverVersion: result.serverVersion})
|
|
124
|
+
throwIfSyncAborted(signal)
|
|
118
125
|
}
|
|
119
126
|
}
|
|
120
127
|
}
|
|
@@ -261,6 +268,7 @@ export default class SyncApiClient {
|
|
|
261
268
|
* @param {(payload: SyncChangesRequest) => Promise<SyncChangesResponse>} args.postChanges - Posts one changes request.
|
|
262
269
|
* @param {Record<string, SyncResourceConfig>} args.resources - Resource policies.
|
|
263
270
|
* @param {(progress: import("./sync-api-client-types.js").SyncPullProgress) => void} [args.onProgress] - Progress callback.
|
|
271
|
+
* @param {AbortSignal} [args.signal] - Lifecycle cancellation signal.
|
|
264
272
|
* @returns {Promise<SyncChangesResult>} Pull result.
|
|
265
273
|
*/
|
|
266
274
|
static async pullChangesWithCursor(args) {
|
|
@@ -271,7 +279,8 @@ export default class SyncApiClient {
|
|
|
271
279
|
saveCursor: async (cursor) => await this.saveSyncCursor({cursor, cursorKey: args.cursorKey, cursorModel: args.cursorModel}),
|
|
272
280
|
postChanges: args.postChanges,
|
|
273
281
|
applySync: this.resourceApplier(args.resources),
|
|
274
|
-
onProgress: args.onProgress
|
|
282
|
+
onProgress: args.onProgress,
|
|
283
|
+
signal: args.signal
|
|
275
284
|
})
|
|
276
285
|
}
|
|
277
286
|
|
|
@@ -309,12 +318,14 @@ export default class SyncApiClient {
|
|
|
309
318
|
* @param {number} [args.batchSize] - Max syncs per request. Defaults to 100.
|
|
310
319
|
* @param {() => Promise<SyncCursor | string | null | undefined>} args.loadCursor - Loads the persisted local cursor.
|
|
311
320
|
* @param {(cursor: SyncCursor) => Promise<void>} args.saveCursor - Persists the final acknowledged cursor.
|
|
312
|
-
* @param {(payload: SyncChangesRequest) => Promise<SyncChangesResponse>} args.postChanges - Posts one changes request.
|
|
321
|
+
* @param {(payload: SyncChangesRequest, options?: {signal?: AbortSignal}) => Promise<SyncChangesResponse>} args.postChanges - Posts one changes request.
|
|
313
322
|
* @param {(sync: SyncChangeEnvelope) => Promise<SyncChangeApplyResult>} args.applySync - Applies one normalized sync row locally.
|
|
314
323
|
* @param {(progress: import("./sync-api-client-types.js").SyncPullProgress) => void} [args.onProgress] - Progress callback invoked per applied page (and once for an empty pull) with the applied counts and the stable server total.
|
|
324
|
+
* @param {AbortSignal} [args.signal] - Lifecycle cancellation signal.
|
|
315
325
|
* @returns {Promise<SyncChangesResult>} Pull result.
|
|
316
326
|
*/
|
|
317
327
|
static async pullChanges(args) {
|
|
328
|
+
throwIfSyncAborted(args.signal)
|
|
318
329
|
let afterCursor = this.syncCursorFromPayload(await args.loadCursor())
|
|
319
330
|
let upToCursor = null
|
|
320
331
|
let pages = 0
|
|
@@ -326,7 +337,9 @@ export default class SyncApiClient {
|
|
|
326
337
|
const batchSize = this.normalizedBatchSize(args.batchSize)
|
|
327
338
|
|
|
328
339
|
while (true) {
|
|
340
|
+
throwIfSyncAborted(args.signal)
|
|
329
341
|
const changesResponse = await this.changesPage({...args, afterCursor, batchSize, upToCursor})
|
|
342
|
+
throwIfSyncAborted(args.signal)
|
|
330
343
|
const syncs = changesResponse.syncs
|
|
331
344
|
|
|
332
345
|
if (!upToCursor) upToCursor = changesResponse.upToCursor
|
|
@@ -341,6 +354,7 @@ export default class SyncApiClient {
|
|
|
341
354
|
if (syncs.length === 0) {
|
|
342
355
|
// Report the terminal progress once for an entirely empty pull so consumers observe
|
|
343
356
|
// total 0; a pull that already applied pages reported its final counts on its last page.
|
|
357
|
+
throwIfSyncAborted(args.signal)
|
|
344
358
|
if (pages === 0 && args.onProgress) args.onProgress({pages, syncedCount, total})
|
|
345
359
|
|
|
346
360
|
break
|
|
@@ -354,7 +368,9 @@ export default class SyncApiClient {
|
|
|
354
368
|
// waiting for the rest of the pull.
|
|
355
369
|
await recordChanges.batch(async () => {
|
|
356
370
|
for (const sync of syncs) {
|
|
371
|
+
throwIfSyncAborted(args.signal)
|
|
357
372
|
const applyResult = await args.applySync(sync)
|
|
373
|
+
throwIfSyncAborted(args.signal)
|
|
358
374
|
const resourceType = applyResult.resourceType ?? sync.resourceType()
|
|
359
375
|
|
|
360
376
|
changed ||= applyResult.changed === true
|
|
@@ -369,11 +385,14 @@ export default class SyncApiClient {
|
|
|
369
385
|
|
|
370
386
|
afterCursor = changesResponse.nextCursor
|
|
371
387
|
|
|
388
|
+
throwIfSyncAborted(args.signal)
|
|
372
389
|
if (args.onProgress) args.onProgress({pages, syncedCount, total})
|
|
373
390
|
if (syncs.length < batchSize) break
|
|
374
391
|
}
|
|
375
392
|
|
|
393
|
+
throwIfSyncAborted(args.signal)
|
|
376
394
|
if (afterCursor) await args.saveCursor(afterCursor)
|
|
395
|
+
throwIfSyncAborted(args.signal)
|
|
377
396
|
|
|
378
397
|
return {changed, pages, resourceChanged, resourceCounts, syncedCount, total}
|
|
379
398
|
}
|
|
@@ -384,18 +403,21 @@ export default class SyncApiClient {
|
|
|
384
403
|
* @param {SyncCursor} args.afterCursor - Last acknowledged cursor.
|
|
385
404
|
* @param {string} args.authenticationToken - Auth token.
|
|
386
405
|
* @param {number} args.batchSize - Page size.
|
|
387
|
-
* @param {(payload: SyncChangesRequest) => Promise<SyncChangesResponse>} args.postChanges - Changes poster.
|
|
406
|
+
* @param {(payload: SyncChangesRequest, options?: {signal?: AbortSignal}) => Promise<SyncChangesResponse>} args.postChanges - Changes poster.
|
|
407
|
+
* @param {AbortSignal} [args.signal] - Lifecycle cancellation signal.
|
|
388
408
|
* @param {SyncCursor} args.upToCursor - Snapshot upper-bound cursor.
|
|
389
409
|
* @returns {Promise<{nextCursor: SyncCursor, syncs: SyncChangeEnvelope[], total: number | null, upToCursor: SyncCursor}>} Normalized changes page.
|
|
390
410
|
*/
|
|
391
|
-
static async changesPage({afterCursor, authenticationToken, batchSize, postChanges, upToCursor}) {
|
|
411
|
+
static async changesPage({afterCursor, authenticationToken, batchSize, postChanges, signal, upToCursor}) {
|
|
412
|
+
throwIfSyncAborted(signal)
|
|
392
413
|
const response = await postChanges({
|
|
393
414
|
authenticationToken,
|
|
394
415
|
limit: batchSize,
|
|
395
416
|
...this.cursorPayload("after", afterCursor),
|
|
396
417
|
...this.cursorPayload("upTo", upToCursor)
|
|
397
|
-
})
|
|
418
|
+
}, {signal})
|
|
398
419
|
|
|
420
|
+
throwIfSyncAborted(signal)
|
|
399
421
|
this.ensureSuccessfulChangesResponse(response)
|
|
400
422
|
|
|
401
423
|
const syncs = /** @type {unknown[]} */ (response.syncs)
|
|
@@ -578,7 +600,8 @@ export default class SyncApiClient {
|
|
|
578
600
|
* @param {string} args.authenticationToken - Auth token to send with replay requests.
|
|
579
601
|
* @param {number} [args.batchSize] - Max syncs per request.
|
|
580
602
|
* @param {ReturnType<typeof JSON.parse>} args.syncModel - Local Sync model class.
|
|
581
|
-
* @param {(payload: {authenticationToken: string, syncs: Array<Record<string, ReturnType<typeof JSON.parse>>>}) => Promise<SyncReplayResponse>} args.postReplay - Replay poster.
|
|
603
|
+
* @param {(payload: {authenticationToken: string, syncs: Array<Record<string, ReturnType<typeof JSON.parse>>>}, options?: {signal?: AbortSignal}) => Promise<SyncReplayResponse>} args.postReplay - Replay poster.
|
|
604
|
+
* @param {AbortSignal} [args.signal] - Lifecycle cancellation signal.
|
|
582
605
|
* @returns {Promise<void>}
|
|
583
606
|
*/
|
|
584
607
|
static async replayLocalSyncs(args) {
|
|
@@ -602,6 +625,7 @@ export default class SyncApiClient {
|
|
|
602
625
|
},
|
|
603
626
|
pendingSyncs: async () => await args.syncModel.preload({resource: true}).where({state: "pending"}).order("created_at").toArray(),
|
|
604
627
|
postReplay: args.postReplay,
|
|
628
|
+
signal: args.signal,
|
|
605
629
|
syncId: (sync) => (/** @type {{id: () => string | number | null | undefined}} */ (sync)).id(),
|
|
606
630
|
syncPayload: (sync) => {
|
|
607
631
|
postedSnapshotsBySyncId.set(String((/** @type {{id: () => string | number | null | undefined}} */ (sync)).id()), this.localSyncReplaySnapshot(sync))
|
|
@@ -810,15 +834,19 @@ export default class SyncApiClient {
|
|
|
810
834
|
* @param {() => Promise<Array<unknown>>} args.pendingSyncs - Loads pending local sync rows in replay order.
|
|
811
835
|
* @param {(sync: unknown) => string | number | null | undefined} args.syncId - Returns the local sync id.
|
|
812
836
|
* @param {(sync: unknown) => Record<string, ReturnType<typeof JSON.parse>>} args.syncPayload - Builds the API sync envelope.
|
|
813
|
-
* @param {(payload: {authenticationToken: string, syncs: Array<Record<string, ReturnType<typeof JSON.parse>>>}) => Promise<SyncReplayResponse>} args.postReplay - Posts one replay request.
|
|
837
|
+
* @param {(payload: {authenticationToken: string, syncs: Array<Record<string, ReturnType<typeof JSON.parse>>>}, options?: {signal?: AbortSignal}) => Promise<SyncReplayResponse>} args.postReplay - Posts one replay request.
|
|
814
838
|
* @param {(sync: unknown, response: SyncReplayItem) => Promise<void>} args.markSuccessful - Marks one sync as successful locally.
|
|
839
|
+
* @param {AbortSignal} [args.signal] - Lifecycle cancellation signal.
|
|
815
840
|
* @returns {Promise<void>} Resolves after all batches are replayed.
|
|
816
841
|
*/
|
|
817
842
|
static async replayPending(args) {
|
|
843
|
+
throwIfSyncAborted(args.signal)
|
|
818
844
|
const pendingSyncs = await args.pendingSyncs()
|
|
845
|
+
throwIfSyncAborted(args.signal)
|
|
819
846
|
const batchSize = this.normalizedBatchSize(args.batchSize)
|
|
820
847
|
|
|
821
848
|
for (let offset = 0; offset < pendingSyncs.length; offset += batchSize) {
|
|
849
|
+
throwIfSyncAborted(args.signal)
|
|
822
850
|
await this.replayBatch({...args, pendingSyncs: pendingSyncs.slice(offset, offset + batchSize)})
|
|
823
851
|
}
|
|
824
852
|
}
|
|
@@ -830,14 +858,16 @@ export default class SyncApiClient {
|
|
|
830
858
|
* @param {Array<unknown>} args.pendingSyncs - Batch syncs.
|
|
831
859
|
* @param {(sync: unknown) => string | number | null | undefined} args.syncId - Sync id getter.
|
|
832
860
|
* @param {(sync: unknown) => Record<string, ReturnType<typeof JSON.parse>>} args.syncPayload - Payload builder.
|
|
833
|
-
* @param {(payload: {authenticationToken: string, syncs: Array<Record<string, ReturnType<typeof JSON.parse>>>}) => Promise<SyncReplayResponse>} args.postReplay - Replay poster.
|
|
861
|
+
* @param {(payload: {authenticationToken: string, syncs: Array<Record<string, ReturnType<typeof JSON.parse>>>}, options?: {signal?: AbortSignal}) => Promise<SyncReplayResponse>} args.postReplay - Replay poster.
|
|
834
862
|
* @param {(sync: unknown, response: SyncReplayItem) => Promise<void>} args.markSuccessful - Success hook.
|
|
863
|
+
* @param {AbortSignal} [args.signal] - Lifecycle cancellation signal.
|
|
835
864
|
* @returns {Promise<void>} Resolves after the batch is acknowledged.
|
|
836
865
|
*/
|
|
837
866
|
static async replayBatch(args) {
|
|
838
|
-
const {authenticationToken, markSuccessful, pendingSyncs, postReplay, syncId, syncPayload} = args
|
|
867
|
+
const {authenticationToken, markSuccessful, pendingSyncs, postReplay, signal, syncId, syncPayload} = args
|
|
839
868
|
|
|
840
869
|
if (pendingSyncs.length === 0) return
|
|
870
|
+
throwIfSyncAborted(signal)
|
|
841
871
|
|
|
842
872
|
const syncsById = new Map()
|
|
843
873
|
|
|
@@ -850,11 +880,13 @@ export default class SyncApiClient {
|
|
|
850
880
|
const response = await postReplay({
|
|
851
881
|
authenticationToken,
|
|
852
882
|
syncs: pendingSyncs.map((sync) => syncPayload(sync))
|
|
853
|
-
})
|
|
883
|
+
}, {signal})
|
|
854
884
|
|
|
885
|
+
throwIfSyncAborted(signal)
|
|
855
886
|
this.ensureSuccessfulResponse(response)
|
|
856
887
|
|
|
857
888
|
for (const syncResponse of response.syncs || []) {
|
|
889
|
+
throwIfSyncAborted(signal)
|
|
858
890
|
const sync = syncsById.get(String(syncResponse.id))
|
|
859
891
|
|
|
860
892
|
if (!sync) continue
|
|
@@ -863,6 +895,7 @@ export default class SyncApiClient {
|
|
|
863
895
|
}
|
|
864
896
|
|
|
865
897
|
await markSuccessful(sync, syncResponse)
|
|
898
|
+
throwIfSyncAborted(signal)
|
|
866
899
|
}
|
|
867
900
|
}
|
|
868
901
|
|
|
@@ -887,3 +920,15 @@ export default class SyncApiClient {
|
|
|
887
920
|
return Math.floor(batchSize)
|
|
888
921
|
}
|
|
889
922
|
}
|
|
923
|
+
|
|
924
|
+
/**
|
|
925
|
+
* Throws the exact abort reason at lifecycle boundaries so callers can
|
|
926
|
+
* distinguish an expected cooperative stop from transport or apply failures.
|
|
927
|
+
* @param {AbortSignal | undefined} signal - Lifecycle signal.
|
|
928
|
+
* @returns {void}
|
|
929
|
+
*/
|
|
930
|
+
function throwIfSyncAborted(signal) {
|
|
931
|
+
if (!signal?.aborted) return
|
|
932
|
+
|
|
933
|
+
throw signal.reason instanceof Error ? signal.reason : new Error("Sync operation aborted")
|
|
934
|
+
}
|
|
@@ -97,6 +97,26 @@
|
|
|
97
97
|
* @property {import("../tenants/tenant-handle.js").default} [tenantHandle] - Immutable tenant handle binding every local sync state transition.
|
|
98
98
|
*/
|
|
99
99
|
|
|
100
|
+
/**
|
|
101
|
+
* Local cleanup hook that runs transactionally with selected scope resets.
|
|
102
|
+
* @typedef {(args: {connection: import("../database/drivers/base.js").default | null, scopes: SerializedSyncScope[]}) => Promise<void> | void} SyncClientScopeCleanup
|
|
103
|
+
*/
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Options for stopping and resetting a sync client lifecycle.
|
|
107
|
+
* @typedef {object} SyncClientStopOptions
|
|
108
|
+
* @property {SyncClientScopeCleanup} [cleanup] - App-owned local-row purge run atomically with resetScopes.
|
|
109
|
+
* @property {SerializedSyncScope[]} [resetScopes] - Selected scope rows to deactivate and restart from a null cursor.
|
|
110
|
+
*/
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Options for atomically replacing the external identity read by sync.client.
|
|
114
|
+
* @typedef {SyncClientStopOptions & {
|
|
115
|
+
* replace: () => Promise<void> | void,
|
|
116
|
+
* subscribeUserScope?: boolean
|
|
117
|
+
* }} SyncClientReplaceIdentityOptions
|
|
118
|
+
*/
|
|
119
|
+
|
|
100
120
|
/**
|
|
101
121
|
* Internal derived sync client configuration built by the SyncClient
|
|
102
122
|
* constructor — not an app-facing API.
|
|
@@ -107,8 +127,8 @@
|
|
|
107
127
|
* @property {() => boolean | Promise<boolean>} [isOnline] - Connectivity gate for pulls and replays. Defaults to always online.
|
|
108
128
|
* @property {(args: {scope: SerializedSyncScope}) => string | null | Promise<string | null>} [legacyCursor] - Seeds a newly declared scope's cursor (e.g. from a pre-scope cursor store) so devices don't re-pull everything.
|
|
109
129
|
* @property {(error: Error) => void} [onError] - Reports background replay/pull failures. Defaults to rethrowing.
|
|
110
|
-
* @property {(payload: import("./sync-api-client-types.js").SyncChangesRequest & {scope: SerializedSyncScope}) => Promise<import("./sync-api-client-types.js").SyncChangesResponse>} postChanges - Posts one changes request.
|
|
111
|
-
* @property {(payload: {authenticationToken: string, syncs: Array<Record<string, ReturnType<typeof JSON.parse>>>}) => Promise<import("./sync-api-client-types.js").SyncReplayResponse>} postReplay - Posts one replay request.
|
|
130
|
+
* @property {(payload: import("./sync-api-client-types.js").SyncChangesRequest & {scope: SerializedSyncScope}, options?: {signal?: AbortSignal}) => Promise<import("./sync-api-client-types.js").SyncChangesResponse>} postChanges - Posts one changes request.
|
|
131
|
+
* @property {(payload: {authenticationToken: string, syncs: Array<Record<string, ReturnType<typeof JSON.parse>>>}, options?: {signal?: AbortSignal}) => Promise<import("./sync-api-client-types.js").SyncReplayResponse>} postReplay - Posts one replay request.
|
|
112
132
|
* @property {import("../configuration-types.js").VelociousSyncClientRealtimeConfiguration} [realtime] - Realtime push configuration consumed by `subscribeRealtime(...)`.
|
|
113
133
|
* @property {import("../remote-request-context.js").RemoteRequestContext} requestContext - Immutable scalar context captured for this client.
|
|
114
134
|
* @property {Record<string, SyncClientResourceConfig>} resources - Derived resource policies keyed by resource/model name.
|