experimental-agent 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +9 -0
  2. package/dist/agent-workflow.d.mts +1 -1
  3. package/dist/agent-workflow.d.ts +1 -1
  4. package/dist/agent-workflow.js +352 -104
  5. package/dist/agent-workflow.mjs +1 -1
  6. package/dist/{chunk-W4SSZPDX.mjs → chunk-24UDM5XV.mjs} +4 -4
  7. package/dist/chunk-2ZXHR6T6.mjs +401 -0
  8. package/dist/chunk-4WDKWMVB.mjs +389 -0
  9. package/dist/chunk-IACG26TC.mjs +2212 -0
  10. package/dist/chunk-NGLND33F.mjs +1247 -0
  11. package/dist/{chunk-E7TOPGHY.mjs → chunk-RXPVLORL.mjs} +3 -3
  12. package/dist/{chunk-HJGPUEFC.mjs → chunk-YRYXN7W4.mjs} +7 -1
  13. package/dist/client-Bkuq-Dfa.d.mts +2340 -0
  14. package/dist/client-Bkuq-Dfa.d.ts +2340 -0
  15. package/dist/{client-YUU54ZZH.mjs → client-SNN3XDKO.mjs} +2 -2
  16. package/dist/client.d.mts +1 -1
  17. package/dist/client.d.ts +1 -1
  18. package/dist/client.js +1 -1
  19. package/dist/client.mjs +1 -1
  20. package/dist/{handler-LDFBSCRA.mjs → handler-WFNQWR6V.mjs} +2 -1
  21. package/dist/index.d.mts +2 -2
  22. package/dist/index.d.ts +2 -2
  23. package/dist/index.js +623 -220
  24. package/dist/index.mjs +78 -40
  25. package/dist/lifecycle-workflow.d.mts +1 -1
  26. package/dist/lifecycle-workflow.d.ts +1 -1
  27. package/dist/lifecycle-workflow.js +88 -6
  28. package/dist/lifecycle-workflow.mjs +1 -1
  29. package/dist/local-fs-handlers-ESZBRAWK.mjs +439 -0
  30. package/dist/next/loader.js +3 -3
  31. package/dist/next/loader.mjs +1 -1
  32. package/dist/next.js +10 -4
  33. package/dist/next.mjs +9 -3
  34. package/dist/{sandbox-GPCA35PJ.mjs → sandbox-IFK5MVRM.mjs} +3 -3
  35. package/dist/{storage-LL6IA24R.mjs → storage-FCSHTDLC.mjs} +3 -3
  36. package/package.json +2 -2
  37. package/dist/chunk-2SPAJ777.mjs +0 -365
  38. package/dist/chunk-6J462JGP.mjs +0 -1267
  39. package/dist/chunk-ILPVXRI5.mjs +0 -2026
  40. package/dist/chunk-ORE6LK2L.mjs +0 -344
  41. package/dist/client-CKLwB-ES.d.mts +0 -2115
  42. package/dist/client-CKLwB-ES.d.ts +0 -2115
  43. package/dist/local-fs-handlers-SY2RDXZE.mjs +0 -314
@@ -1,314 +0,0 @@
1
- import "./chunk-BJTO5JO5.mjs";
2
-
3
- // src/storage/bindings/local-fs-handlers.ts
4
- import { mkdir, readdir, readFile, unlink, writeFile } from "fs/promises";
5
- import { dirname, join, resolve } from "path";
6
- import equal from "fast-deep-equal";
7
-
8
- // src/utils/paginate.ts
9
- function paginate(opts) {
10
- const { items, cursor, limit } = opts;
11
- const startIndex = cursor ? items.findIndex((m) => m.id === cursor) + 1 : 0;
12
- const sliced = limit !== void 0 ? items.slice(startIndex, startIndex + limit) : items.slice(startIndex);
13
- const nextCursor = limit !== void 0 && startIndex + limit < items.length ? sliced.at(-1)?.id ?? null : null;
14
- return { items: sliced, nextCursor };
15
- }
16
-
17
- // src/storage/bindings/local-fs-handlers.ts
18
- function createFilesystemHandlers(basePath) {
19
- const resolvedBase = resolve(basePath);
20
- const sessionDir = join(resolvedBase, "session");
21
- const messageDir = join(resolvedBase, "message");
22
- const partDir = join(resolvedBase, "part");
23
- const sandboxDir = join(resolvedBase, "sandbox");
24
- const commandDir = join(resolvedBase, "command");
25
- const setupDir = join(resolvedBase, "setup");
26
- async function ensureDir(dir) {
27
- await mkdir(dir, { recursive: true });
28
- }
29
- async function readJson(filePath) {
30
- try {
31
- const content = await readFile(filePath, "utf-8");
32
- return JSON.parse(content);
33
- } catch {
34
- return null;
35
- }
36
- }
37
- async function writeJsonFile(filePath, data) {
38
- await ensureDir(dirname(filePath));
39
- await writeFile(filePath, JSON.stringify(data, null, 2));
40
- }
41
- async function readAllFromDir(dir) {
42
- try {
43
- const files = await readdir(dir);
44
- const results = await Promise.all(
45
- files.filter((f) => f.endsWith(".json")).map((f) => readJson(join(dir, f)))
46
- );
47
- return results.filter((r) => r !== null);
48
- } catch {
49
- return [];
50
- }
51
- }
52
- return {
53
- "session.get": async ({ id }) => {
54
- const sessionPath = join(sessionDir, `${id}.json`);
55
- return await readJson(sessionPath) ?? null;
56
- },
57
- "session.set": async (session) => {
58
- const now = Date.now();
59
- const sessionPath = join(sessionDir, `${session.id}.json`);
60
- const existing = await readJson(sessionPath);
61
- const newSession = {
62
- ...session,
63
- tags: session.tags ?? existing?.tags ?? {},
64
- createdAt: existing?.createdAt ?? session.createdAt ?? now,
65
- updatedAt: now
66
- };
67
- await writeJsonFile(sessionPath, newSession);
68
- return newSession;
69
- },
70
- "session.delete": async ({ id }) => {
71
- try {
72
- await unlink(join(sessionDir, `${id}.json`));
73
- } catch {
74
- }
75
- const allMessages = await readAllFromDir(messageDir);
76
- const sessionMessages = allMessages.filter((m) => m.sessionId === id);
77
- const allParts = await readAllFromDir(partDir);
78
- const sessionParts = allParts.filter((p) => p.sessionId === id);
79
- const allCommands = await readAllFromDir(commandDir);
80
- const sessionCommands = allCommands.filter((c) => c.sessionId === id);
81
- const noop = () => void 0;
82
- await Promise.all([
83
- ...sessionMessages.map(
84
- (m) => unlink(join(messageDir, `${m.id}.json`)).catch(noop)
85
- ),
86
- ...sessionParts.map(
87
- (p) => unlink(join(partDir, `${p.id}.json`)).catch(noop)
88
- ),
89
- ...sessionCommands.map(
90
- (c) => unlink(join(commandDir, `${c.id}.json`)).catch(noop)
91
- )
92
- ]);
93
- },
94
- "session.list": async ({ tags, order, cursor, limit }) => {
95
- const allSessions = await readAllFromDir(sessionDir);
96
- let filtered = allSessions;
97
- if (tags && Object.keys(tags).length > 0) {
98
- filtered = filtered.filter((s) => {
99
- const sessionTags = s.tags ?? {};
100
- return Object.entries(tags).every(
101
- ([key, value]) => equal(sessionTags[key], value)
102
- );
103
- });
104
- }
105
- const resolvedOrder = order ?? "updatedAt_desc";
106
- const sortField = resolvedOrder.startsWith("updatedAt") ? "updatedAt" : "createdAt";
107
- const sortDir = resolvedOrder.endsWith("_desc") ? -1 : 1;
108
- filtered.sort((a, b) => sortDir * (a[sortField] - b[sortField]));
109
- return paginate({ items: filtered, cursor, limit });
110
- },
111
- "session.listBySandbox": async ({
112
- sandboxId,
113
- tags,
114
- order,
115
- cursor,
116
- limit
117
- }) => {
118
- const allSessions = await readAllFromDir(sessionDir);
119
- let filtered = allSessions.filter((s) => s.sandboxId === sandboxId);
120
- if (tags && Object.keys(tags).length > 0) {
121
- filtered = filtered.filter((s) => {
122
- const sessionTags = s.tags ?? {};
123
- return Object.entries(tags).every(
124
- ([key, value]) => equal(sessionTags[key], value)
125
- );
126
- });
127
- }
128
- const resolvedOrder = order ?? "updatedAt_desc";
129
- const sortField = resolvedOrder.startsWith("updatedAt") ? "updatedAt" : "createdAt";
130
- const sortDir = resolvedOrder.endsWith("_desc") ? -1 : 1;
131
- filtered.sort((a, b) => sortDir * (a[sortField] - b[sortField]));
132
- return paginate({ items: filtered, cursor, limit });
133
- },
134
- "session.tag.set": async ({ sessionId, tags }) => {
135
- const sessionPath = join(sessionDir, `${sessionId}.json`);
136
- const existing = await readJson(sessionPath);
137
- if (!existing) {
138
- throw new Error(`Session ${sessionId} not found`);
139
- }
140
- const mergedTags = { ...existing.tags, ...tags };
141
- const now = Date.now();
142
- const updatedSession = {
143
- ...existing,
144
- tags: mergedTags,
145
- updatedAt: now
146
- };
147
- await writeJsonFile(sessionPath, updatedSession);
148
- return updatedSession;
149
- },
150
- "message.get": async ({ id }) => {
151
- return await readJson(join(messageDir, `${id}.json`));
152
- },
153
- "message.set": async (message) => {
154
- await writeJsonFile(join(messageDir, `${message.id}.json`), message);
155
- return message;
156
- },
157
- "message.list": async ({ sessionId, cursor, limit }) => {
158
- const allMessages = await readAllFromDir(messageDir);
159
- const filtered = allMessages.filter((m) => m.sessionId === sessionId).sort((a, b) => a.createdAt - b.createdAt);
160
- return paginate({ items: filtered, cursor, limit });
161
- },
162
- "part.listByMessage": async ({ messageId, cursor, limit }) => {
163
- const allParts = await readAllFromDir(partDir);
164
- const filtered = allParts.filter((p) => p.messageId === messageId).sort((a, b) => a.index - b.index);
165
- return paginate({ items: filtered, cursor, limit });
166
- },
167
- "part.listBySession": async ({ sessionId, cursor, limit }) => {
168
- const allParts = await readAllFromDir(partDir);
169
- const filtered = allParts.filter((p) => p.sessionId === sessionId).sort((a, b) => {
170
- if (a.messageId !== b.messageId) {
171
- return a.messageId.localeCompare(b.messageId);
172
- }
173
- return a.index - b.index;
174
- });
175
- return paginate({ items: filtered, cursor, limit });
176
- },
177
- "part.set": async (part) => {
178
- await writeJsonFile(join(partDir, `${part.id}.json`), part);
179
- return part;
180
- },
181
- "part.delete": async ({ id }) => {
182
- try {
183
- await unlink(join(partDir, `${id}.json`));
184
- } catch {
185
- }
186
- },
187
- "sandbox.get": async ({ key }) => {
188
- const safeName = Buffer.from(key).toString("base64url");
189
- const sandboxPath = join(sandboxDir, `${safeName}.json`);
190
- const data = await readJson(sandboxPath);
191
- if (!data) {
192
- return null;
193
- }
194
- return data;
195
- },
196
- "sandbox.set": async (record) => {
197
- const safeName = Buffer.from(record.id).toString("base64url");
198
- const sandboxPath = join(sandboxDir, `${safeName}.json`);
199
- const existing = await readJson(sandboxPath);
200
- const newRecord = {
201
- ...record,
202
- tags: record.tags ?? existing?.tags ?? null
203
- };
204
- await writeJsonFile(sandboxPath, newRecord);
205
- },
206
- "sandbox.list": async ({ tags, order, cursor, limit }) => {
207
- const allSandboxes = await readAllFromDir(sandboxDir);
208
- let filtered = allSandboxes;
209
- if (tags && Object.keys(tags).length > 0) {
210
- filtered = filtered.filter((s) => {
211
- const sandboxTags = s.tags ?? {};
212
- return Object.entries(tags).every(
213
- ([key, value]) => equal(sandboxTags[key], value)
214
- );
215
- });
216
- }
217
- const sortField = order?.startsWith("lastActivityAt") ? "lastActivityAt" : "createdAt";
218
- const sortDir = order?.endsWith("_desc") ? -1 : 1;
219
- filtered.sort(
220
- (a, b) => sortDir * ((a[sortField] ?? 0) - (b[sortField] ?? 0))
221
- );
222
- return paginate({ items: filtered, cursor, limit });
223
- },
224
- "sandbox.tag.set": async ({ sandboxId, tags }) => {
225
- const safeName = Buffer.from(sandboxId).toString("base64url");
226
- const sandboxPath = join(sandboxDir, `${safeName}.json`);
227
- const existing = await readJson(sandboxPath);
228
- if (!existing) {
229
- throw new Error(`Sandbox ${sandboxId} not found`);
230
- }
231
- const mergedTags = { ...existing.tags, ...tags };
232
- const updatedSandbox = {
233
- ...existing,
234
- tags: mergedTags
235
- };
236
- await writeJsonFile(sandboxPath, updatedSandbox);
237
- return updatedSandbox;
238
- },
239
- "sandbox.getBySession": async ({ sessionId }) => {
240
- const allSandboxes = await readAllFromDir(sandboxDir);
241
- const matching = allSandboxes.filter(
242
- (s) => s.id.startsWith(`${sessionId}-`)
243
- );
244
- if (matching.length === 0) {
245
- return null;
246
- }
247
- matching.sort(
248
- (a, b) => (b.lastActivityAt ?? 0) - (a.lastActivityAt ?? 0)
249
- );
250
- return matching[0];
251
- },
252
- "command.get": async ({ id }) => {
253
- return await readJson(join(commandDir, `${id}.json`));
254
- },
255
- "command.set": async (command) => {
256
- await writeJsonFile(join(commandDir, `${command.id}.json`), command);
257
- return command;
258
- },
259
- "setup.get": async ({ key }) => {
260
- const safeName = Buffer.from(key).toString("base64url");
261
- return await readJson(join(setupDir, `${safeName}.json`));
262
- },
263
- "setup.set": async (snapshot) => {
264
- const safeName = Buffer.from(snapshot.key).toString("base64url");
265
- await writeJsonFile(join(setupDir, `${safeName}.json`), snapshot);
266
- },
267
- "setup.acquireLock": async ({ key, lockId, lockTimeoutMs }) => {
268
- const safeName = Buffer.from(key).toString("base64url");
269
- const filePath = join(setupDir, `${safeName}.json`);
270
- const existing = await readJson(filePath);
271
- if (existing?.acquiringLockId && existing.acquiringLockAt && Date.now() - existing.acquiringLockAt < lockTimeoutMs) {
272
- return null;
273
- }
274
- const now = Date.now();
275
- const snapshot = {
276
- key,
277
- snapshotId: existing?.snapshotId ?? null,
278
- createdAt: existing?.createdAt ?? now,
279
- lastUsedAt: existing?.lastUsedAt ?? null,
280
- acquiringLockId: lockId,
281
- acquiringLockAt: now
282
- };
283
- await writeJsonFile(filePath, snapshot);
284
- return snapshot;
285
- },
286
- "sandbox.acquireLock": async ({ record, lockTimeoutMs }) => {
287
- const safeName = Buffer.from(record.id).toString("base64url");
288
- const filePath = join(sandboxDir, `${safeName}.json`);
289
- const existing = await readJson(filePath);
290
- if (existing?.acquiringLockId && existing.acquiringLockAt && Date.now() - existing.acquiringLockAt < lockTimeoutMs) {
291
- return null;
292
- }
293
- const newRecord = {
294
- ...record,
295
- tags: record.tags ?? existing?.tags ?? null
296
- };
297
- await writeJsonFile(filePath, newRecord);
298
- return newRecord;
299
- },
300
- "command.list": async ({ sessionId, includeFinished, cursor, limit }) => {
301
- const allCommands = await readAllFromDir(commandDir);
302
- let filtered = allCommands.filter((c) => c.sessionId === sessionId);
303
- if (!includeFinished) {
304
- filtered = filtered.filter((c) => c.status === "running");
305
- }
306
- filtered.sort((a, b) => a.startedAt - b.startedAt);
307
- return paginate({ items: filtered, cursor, limit });
308
- }
309
- };
310
- }
311
- export {
312
- createFilesystemHandlers
313
- };
314
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3N0b3JhZ2UvYmluZGluZ3MvbG9jYWwtZnMtaGFuZGxlcnMudHMiLCAiLi4vc3JjL3V0aWxzL3BhZ2luYXRlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgeyBta2RpciwgcmVhZGRpciwgcmVhZEZpbGUsIHVubGluaywgd3JpdGVGaWxlIH0gZnJvbSBcIm5vZGU6ZnMvcHJvbWlzZXNcIjtcbmltcG9ydCB7IGRpcm5hbWUsIGpvaW4sIHJlc29sdmUgfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgZXF1YWwgZnJvbSBcImZhc3QtZGVlcC1lcXVhbFwiO1xuaW1wb3J0IHsgcGFnaW5hdGUgfSBmcm9tIFwiLi4vLi4vdXRpbHMvcGFnaW5hdGVcIjtcbmltcG9ydCB0eXBlIHtcbiAgQ29tbWFuZCxcbiAgSGFuZGxlcnMsXG4gIE1lc3NhZ2UsXG4gIFBhcnQsXG4gIFNhbmRib3hSZWNvcmQsXG4gIFNlc3Npb24sXG4gIFNldHVwU25hcHNob3QsXG59IGZyb20gXCIuLlwiO1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRmlsZXN5c3RlbUhhbmRsZXJzKGJhc2VQYXRoOiBzdHJpbmcpOiBIYW5kbGVycyB7XG4gIGNvbnN0IHJlc29sdmVkQmFzZSA9IHJlc29sdmUoYmFzZVBhdGgpO1xuICBjb25zdCBzZXNzaW9uRGlyID0gam9pbihyZXNvbHZlZEJhc2UsIFwic2Vzc2lvblwiKTtcbiAgY29uc3QgbWVzc2FnZURpciA9IGpvaW4ocmVzb2x2ZWRCYXNlLCBcIm1lc3NhZ2VcIik7XG4gIGNvbnN0IHBhcnREaXIgPSBqb2luKHJlc29sdmVkQmFzZSwgXCJwYXJ0XCIpO1xuICBjb25zdCBzYW5kYm94RGlyID0gam9pbihyZXNvbHZlZEJhc2UsIFwic2FuZGJveFwiKTtcbiAgY29uc3QgY29tbWFuZERpciA9IGpvaW4ocmVzb2x2ZWRCYXNlLCBcImNvbW1hbmRcIik7XG4gIGNvbnN0IHNldHVwRGlyID0gam9pbihyZXNvbHZlZEJhc2UsIFwic2V0dXBcIik7XG5cbiAgYXN5bmMgZnVuY3Rpb24gZW5zdXJlRGlyKGRpcjogc3RyaW5nKSB7XG4gICAgYXdhaXQgbWtkaXIoZGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIHJlYWRKc29uPFQ+KGZpbGVQYXRoOiBzdHJpbmcpOiBQcm9taXNlPFQgfCBudWxsPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBhd2FpdCByZWFkRmlsZShmaWxlUGF0aCwgXCJ1dGYtOFwiKTtcbiAgICAgIHJldHVybiBKU09OLnBhcnNlKGNvbnRlbnQpIGFzIFQ7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiB3cml0ZUpzb25GaWxlKGZpbGVQYXRoOiBzdHJpbmcsIGRhdGE6IHVua25vd24pIHtcbiAgICBhd2FpdCBlbnN1cmVEaXIoZGlybmFtZShmaWxlUGF0aCkpO1xuICAgIGF3YWl0IHdyaXRlRmlsZShmaWxlUGF0aCwgSlNPTi5zdHJpbmdpZnkoZGF0YSwgbnVsbCwgMikpO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gcmVhZEFsbEZyb21EaXI8VD4oZGlyOiBzdHJpbmcpOiBQcm9taXNlPFRbXT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBmaWxlcyA9IGF3YWl0IHJlYWRkaXIoZGlyKTtcbiAgICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgZmlsZXNcbiAgICAgICAgICAuZmlsdGVyKChmKSA9PiBmLmVuZHNXaXRoKFwiLmpzb25cIikpXG4gICAgICAgICAgLm1hcCgoZikgPT4gcmVhZEpzb248VD4oam9pbihkaXIsIGYpKSlcbiAgICAgICk7XG4gICAgICByZXR1cm4gcmVzdWx0cy5maWx0ZXIoKHIpOiByIGlzIE5vbk51bGxhYmxlPHR5cGVvZiByPiA9PiByICE9PSBudWxsKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIFwic2Vzc2lvbi5nZXRcIjogYXN5bmMgKHsgaWQgfSkgPT4ge1xuICAgICAgY29uc3Qgc2Vzc2lvblBhdGggPSBqb2luKHNlc3Npb25EaXIsIGAke2lkfS5qc29uYCk7XG4gICAgICByZXR1cm4gKGF3YWl0IHJlYWRKc29uPFNlc3Npb24+KHNlc3Npb25QYXRoKSkgPz8gbnVsbDtcbiAgICB9LFxuXG4gICAgXCJzZXNzaW9uLnNldFwiOiBhc3luYyAoc2Vzc2lvbikgPT4ge1xuICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IHNlc3Npb25QYXRoID0gam9pbihzZXNzaW9uRGlyLCBgJHtzZXNzaW9uLmlkfS5qc29uYCk7XG4gICAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHJlYWRKc29uPFNlc3Npb24+KHNlc3Npb25QYXRoKTtcbiAgICAgIGNvbnN0IG5ld1Nlc3Npb246IFNlc3Npb24gPSB7XG4gICAgICAgIC4uLnNlc3Npb24sXG4gICAgICAgIHRhZ3M6IHNlc3Npb24udGFncyA/PyBleGlzdGluZz8udGFncyA/PyB7fSxcbiAgICAgICAgY3JlYXRlZEF0OiBleGlzdGluZz8uY3JlYXRlZEF0ID8/IHNlc3Npb24uY3JlYXRlZEF0ID8/IG5vdyxcbiAgICAgICAgdXBkYXRlZEF0OiBub3csXG4gICAgICB9O1xuICAgICAgYXdhaXQgd3JpdGVKc29uRmlsZShzZXNzaW9uUGF0aCwgbmV3U2Vzc2lvbik7XG4gICAgICByZXR1cm4gbmV3U2Vzc2lvbjtcbiAgICB9LFxuXG4gICAgXCJzZXNzaW9uLmRlbGV0ZVwiOiBhc3luYyAoeyBpZCB9KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB1bmxpbmsoam9pbihzZXNzaW9uRGlyLCBgJHtpZH0uanNvbmApKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBpZ25vcmUgaWYgZmlsZSBkb2Vzbid0IGV4aXN0XG4gICAgICB9XG4gICAgICBjb25zdCBhbGxNZXNzYWdlcyA9IGF3YWl0IHJlYWRBbGxGcm9tRGlyPE1lc3NhZ2U+KG1lc3NhZ2VEaXIpO1xuICAgICAgY29uc3Qgc2Vzc2lvbk1lc3NhZ2VzID0gYWxsTWVzc2FnZXMuZmlsdGVyKChtKSA9PiBtLnNlc3Npb25JZCA9PT0gaWQpO1xuICAgICAgY29uc3QgYWxsUGFydHMgPSBhd2FpdCByZWFkQWxsRnJvbURpcjxQYXJ0PihwYXJ0RGlyKTtcbiAgICAgIGNvbnN0IHNlc3Npb25QYXJ0cyA9IGFsbFBhcnRzLmZpbHRlcigocCkgPT4gcC5zZXNzaW9uSWQgPT09IGlkKTtcbiAgICAgIGNvbnN0IGFsbENvbW1hbmRzID0gYXdhaXQgcmVhZEFsbEZyb21EaXI8Q29tbWFuZD4oY29tbWFuZERpcik7XG4gICAgICBjb25zdCBzZXNzaW9uQ29tbWFuZHMgPSBhbGxDb21tYW5kcy5maWx0ZXIoKGMpID0+IGMuc2Vzc2lvbklkID09PSBpZCk7XG4gICAgICBjb25zdCBub29wID0gKCkgPT4gdW5kZWZpbmVkO1xuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICAuLi5zZXNzaW9uTWVzc2FnZXMubWFwKChtKSA9PlxuICAgICAgICAgIHVubGluayhqb2luKG1lc3NhZ2VEaXIsIGAke20uaWR9Lmpzb25gKSkuY2F0Y2gobm9vcClcbiAgICAgICAgKSxcbiAgICAgICAgLi4uc2Vzc2lvblBhcnRzLm1hcCgocCkgPT5cbiAgICAgICAgICB1bmxpbmsoam9pbihwYXJ0RGlyLCBgJHtwLmlkfS5qc29uYCkpLmNhdGNoKG5vb3ApXG4gICAgICAgICksXG4gICAgICAgIC4uLnNlc3Npb25Db21tYW5kcy5tYXAoKGMpID0+XG4gICAgICAgICAgdW5saW5rKGpvaW4oY29tbWFuZERpciwgYCR7Yy5pZH0uanNvbmApKS5jYXRjaChub29wKVxuICAgICAgICApLFxuICAgICAgXSk7XG4gICAgfSxcblxuICAgIFwic2Vzc2lvbi5saXN0XCI6IGFzeW5jICh7IHRhZ3MsIG9yZGVyLCBjdXJzb3IsIGxpbWl0IH0pID0+IHtcbiAgICAgIGNvbnN0IGFsbFNlc3Npb25zID0gYXdhaXQgcmVhZEFsbEZyb21EaXI8U2Vzc2lvbj4oc2Vzc2lvbkRpcik7XG4gICAgICBsZXQgZmlsdGVyZWQgPSBhbGxTZXNzaW9ucztcbiAgICAgIGlmICh0YWdzICYmIE9iamVjdC5rZXlzKHRhZ3MpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZmlsdGVyZWQgPSBmaWx0ZXJlZC5maWx0ZXIoKHMpID0+IHtcbiAgICAgICAgICBjb25zdCBzZXNzaW9uVGFncyA9IHMudGFncyA/PyB7fTtcbiAgICAgICAgICByZXR1cm4gT2JqZWN0LmVudHJpZXModGFncykuZXZlcnkoKFtrZXksIHZhbHVlXSkgPT5cbiAgICAgICAgICAgIGVxdWFsKHNlc3Npb25UYWdzW2tleV0sIHZhbHVlKVxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgcmVzb2x2ZWRPcmRlciA9IG9yZGVyID8/IFwidXBkYXRlZEF0X2Rlc2NcIjtcbiAgICAgIGNvbnN0IHNvcnRGaWVsZCA9IHJlc29sdmVkT3JkZXIuc3RhcnRzV2l0aChcInVwZGF0ZWRBdFwiKVxuICAgICAgICA/IFwidXBkYXRlZEF0XCJcbiAgICAgICAgOiBcImNyZWF0ZWRBdFwiO1xuICAgICAgY29uc3Qgc29ydERpciA9IHJlc29sdmVkT3JkZXIuZW5kc1dpdGgoXCJfZGVzY1wiKSA/IC0xIDogMTtcbiAgICAgIGZpbHRlcmVkLnNvcnQoKGEsIGIpID0+IHNvcnREaXIgKiAoYVtzb3J0RmllbGRdIC0gYltzb3J0RmllbGRdKSk7XG4gICAgICByZXR1cm4gcGFnaW5hdGUoeyBpdGVtczogZmlsdGVyZWQsIGN1cnNvciwgbGltaXQgfSk7XG4gICAgfSxcblxuICAgIFwic2Vzc2lvbi5saXN0QnlTYW5kYm94XCI6IGFzeW5jICh7XG4gICAgICBzYW5kYm94SWQsXG4gICAgICB0YWdzLFxuICAgICAgb3JkZXIsXG4gICAgICBjdXJzb3IsXG4gICAgICBsaW1pdCxcbiAgICB9KSA9PiB7XG4gICAgICBjb25zdCBhbGxTZXNzaW9ucyA9IGF3YWl0IHJlYWRBbGxGcm9tRGlyPFNlc3Npb24+KHNlc3Npb25EaXIpO1xuICAgICAgbGV0IGZpbHRlcmVkID0gYWxsU2Vzc2lvbnMuZmlsdGVyKChzKSA9PiBzLnNhbmRib3hJZCA9PT0gc2FuZGJveElkKTtcbiAgICAgIGlmICh0YWdzICYmIE9iamVjdC5rZXlzKHRhZ3MpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZmlsdGVyZWQgPSBmaWx0ZXJlZC5maWx0ZXIoKHMpID0+IHtcbiAgICAgICAgICBjb25zdCBzZXNzaW9uVGFncyA9IHMudGFncyA/PyB7fTtcbiAgICAgICAgICByZXR1cm4gT2JqZWN0LmVudHJpZXModGFncykuZXZlcnkoKFtrZXksIHZhbHVlXSkgPT5cbiAgICAgICAgICAgIGVxdWFsKHNlc3Npb25UYWdzW2tleV0sIHZhbHVlKVxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgcmVzb2x2ZWRPcmRlciA9IG9yZGVyID8/IFwidXBkYXRlZEF0X2Rlc2NcIjtcbiAgICAgIGNvbnN0IHNvcnRGaWVsZCA9IHJlc29sdmVkT3JkZXIuc3RhcnRzV2l0aChcInVwZGF0ZWRBdFwiKVxuICAgICAgICA/IFwidXBkYXRlZEF0XCJcbiAgICAgICAgOiBcImNyZWF0ZWRBdFwiO1xuICAgICAgY29uc3Qgc29ydERpciA9IHJlc29sdmVkT3JkZXIuZW5kc1dpdGgoXCJfZGVzY1wiKSA/IC0xIDogMTtcbiAgICAgIGZpbHRlcmVkLnNvcnQoKGEsIGIpID0+IHNvcnREaXIgKiAoYVtzb3J0RmllbGRdIC0gYltzb3J0RmllbGRdKSk7XG4gICAgICByZXR1cm4gcGFnaW5hdGUoeyBpdGVtczogZmlsdGVyZWQsIGN1cnNvciwgbGltaXQgfSk7XG4gICAgfSxcblxuICAgIFwic2Vzc2lvbi50YWcuc2V0XCI6IGFzeW5jICh7IHNlc3Npb25JZCwgdGFncyB9KSA9PiB7XG4gICAgICBjb25zdCBzZXNzaW9uUGF0aCA9IGpvaW4oc2Vzc2lvbkRpciwgYCR7c2Vzc2lvbklkfS5qc29uYCk7XG4gICAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHJlYWRKc29uPFNlc3Npb24+KHNlc3Npb25QYXRoKTtcbiAgICAgIGlmICghZXhpc3RpbmcpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTZXNzaW9uICR7c2Vzc2lvbklkfSBub3QgZm91bmRgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG1lcmdlZFRhZ3MgPSB7IC4uLmV4aXN0aW5nLnRhZ3MsIC4uLnRhZ3MgfTtcbiAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICBjb25zdCB1cGRhdGVkU2Vzc2lvbjogU2Vzc2lvbiA9IHtcbiAgICAgICAgLi4uZXhpc3RpbmcsXG4gICAgICAgIHRhZ3M6IG1lcmdlZFRhZ3MsXG4gICAgICAgIHVwZGF0ZWRBdDogbm93LFxuICAgICAgfTtcbiAgICAgIGF3YWl0IHdyaXRlSnNvbkZpbGUoc2Vzc2lvblBhdGgsIHVwZGF0ZWRTZXNzaW9uKTtcbiAgICAgIHJldHVybiB1cGRhdGVkU2Vzc2lvbjtcbiAgICB9LFxuXG4gICAgXCJtZXNzYWdlLmdldFwiOiBhc3luYyAoeyBpZCB9KSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVhZEpzb248TWVzc2FnZT4oam9pbihtZXNzYWdlRGlyLCBgJHtpZH0uanNvbmApKTtcbiAgICB9LFxuXG4gICAgXCJtZXNzYWdlLnNldFwiOiBhc3luYyAobWVzc2FnZSkgPT4ge1xuICAgICAgYXdhaXQgd3JpdGVKc29uRmlsZShqb2luKG1lc3NhZ2VEaXIsIGAke21lc3NhZ2UuaWR9Lmpzb25gKSwgbWVzc2FnZSk7XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9LFxuXG4gICAgXCJtZXNzYWdlLmxpc3RcIjogYXN5bmMgKHsgc2Vzc2lvbklkLCBjdXJzb3IsIGxpbWl0IH0pID0+IHtcbiAgICAgIGNvbnN0IGFsbE1lc3NhZ2VzID0gYXdhaXQgcmVhZEFsbEZyb21EaXI8TWVzc2FnZT4obWVzc2FnZURpcik7XG4gICAgICBjb25zdCBmaWx0ZXJlZCA9IGFsbE1lc3NhZ2VzXG4gICAgICAgIC5maWx0ZXIoKG0pID0+IG0uc2Vzc2lvbklkID09PSBzZXNzaW9uSWQpXG4gICAgICAgIC5zb3J0KChhLCBiKSA9PiBhLmNyZWF0ZWRBdCAtIGIuY3JlYXRlZEF0KTtcbiAgICAgIHJldHVybiBwYWdpbmF0ZSh7IGl0ZW1zOiBmaWx0ZXJlZCwgY3Vyc29yLCBsaW1pdCB9KTtcbiAgICB9LFxuXG4gICAgXCJwYXJ0Lmxpc3RCeU1lc3NhZ2VcIjogYXN5bmMgKHsgbWVzc2FnZUlkLCBjdXJzb3IsIGxpbWl0IH0pID0+IHtcbiAgICAgIGNvbnN0IGFsbFBhcnRzID0gYXdhaXQgcmVhZEFsbEZyb21EaXI8UGFydD4ocGFydERpcik7XG4gICAgICBjb25zdCBmaWx0ZXJlZCA9IGFsbFBhcnRzXG4gICAgICAgIC5maWx0ZXIoKHApID0+IHAubWVzc2FnZUlkID09PSBtZXNzYWdlSWQpXG4gICAgICAgIC5zb3J0KChhLCBiKSA9PiBhLmluZGV4IC0gYi5pbmRleCk7XG4gICAgICByZXR1cm4gcGFnaW5hdGUoeyBpdGVtczogZmlsdGVyZWQsIGN1cnNvciwgbGltaXQgfSk7XG4gICAgfSxcblxuICAgIFwicGFydC5saXN0QnlTZXNzaW9uXCI6IGFzeW5jICh7IHNlc3Npb25JZCwgY3Vyc29yLCBsaW1pdCB9KSA9PiB7XG4gICAgICBjb25zdCBhbGxQYXJ0cyA9IGF3YWl0IHJlYWRBbGxGcm9tRGlyPFBhcnQ+KHBhcnREaXIpO1xuICAgICAgY29uc3QgZmlsdGVyZWQgPSBhbGxQYXJ0c1xuICAgICAgICAuZmlsdGVyKChwKSA9PiBwLnNlc3Npb25JZCA9PT0gc2Vzc2lvbklkKVxuICAgICAgICAuc29ydCgoYSwgYikgPT4ge1xuICAgICAgICAgIGlmIChhLm1lc3NhZ2VJZCAhPT0gYi5tZXNzYWdlSWQpIHtcbiAgICAgICAgICAgIHJldHVybiBhLm1lc3NhZ2VJZC5sb2NhbGVDb21wYXJlKGIubWVzc2FnZUlkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGEuaW5kZXggLSBiLmluZGV4O1xuICAgICAgICB9KTtcbiAgICAgIHJldHVybiBwYWdpbmF0ZSh7IGl0ZW1zOiBmaWx0ZXJlZCwgY3Vyc29yLCBsaW1pdCB9KTtcbiAgICB9LFxuXG4gICAgXCJwYXJ0LnNldFwiOiBhc3luYyAocGFydCkgPT4ge1xuICAgICAgYXdhaXQgd3JpdGVKc29uRmlsZShqb2luKHBhcnREaXIsIGAke3BhcnQuaWR9Lmpzb25gKSwgcGFydCk7XG4gICAgICByZXR1cm4gcGFydDtcbiAgICB9LFxuXG4gICAgXCJwYXJ0LmRlbGV0ZVwiOiBhc3luYyAoeyBpZCB9KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB1bmxpbmsoam9pbihwYXJ0RGlyLCBgJHtpZH0uanNvbmApKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBJZ25vcmUgaWYgZmlsZSBkb2Vzbid0IGV4aXN0XG4gICAgICB9XG4gICAgfSxcblxuICAgIFwic2FuZGJveC5nZXRcIjogYXN5bmMgKHsga2V5IH0pID0+IHtcbiAgICAgIGNvbnN0IHNhZmVOYW1lID0gQnVmZmVyLmZyb20oa2V5KS50b1N0cmluZyhcImJhc2U2NHVybFwiKTtcbiAgICAgIGNvbnN0IHNhbmRib3hQYXRoID0gam9pbihzYW5kYm94RGlyLCBgJHtzYWZlTmFtZX0uanNvbmApO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlYWRKc29uPFNhbmRib3hSZWNvcmQ+KHNhbmRib3hQYXRoKTtcbiAgICAgIGlmICghZGF0YSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH0sXG5cbiAgICBcInNhbmRib3guc2V0XCI6IGFzeW5jIChyZWNvcmQpID0+IHtcbiAgICAgIGNvbnN0IHNhZmVOYW1lID0gQnVmZmVyLmZyb20ocmVjb3JkLmlkKS50b1N0cmluZyhcImJhc2U2NHVybFwiKTtcbiAgICAgIGNvbnN0IHNhbmRib3hQYXRoID0gam9pbihzYW5kYm94RGlyLCBgJHtzYWZlTmFtZX0uanNvbmApO1xuICAgICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCByZWFkSnNvbjxTYW5kYm94UmVjb3JkPihzYW5kYm94UGF0aCk7XG4gICAgICBjb25zdCBuZXdSZWNvcmQ6IFNhbmRib3hSZWNvcmQgPSB7XG4gICAgICAgIC4uLnJlY29yZCxcbiAgICAgICAgdGFnczogcmVjb3JkLnRhZ3MgPz8gZXhpc3Rpbmc/LnRhZ3MgPz8gbnVsbCxcbiAgICAgIH07XG4gICAgICBhd2FpdCB3cml0ZUpzb25GaWxlKHNhbmRib3hQYXRoLCBuZXdSZWNvcmQpO1xuICAgIH0sXG5cbiAgICBcInNhbmRib3gubGlzdFwiOiBhc3luYyAoeyB0YWdzLCBvcmRlciwgY3Vyc29yLCBsaW1pdCB9KSA9PiB7XG4gICAgICBjb25zdCBhbGxTYW5kYm94ZXMgPSBhd2FpdCByZWFkQWxsRnJvbURpcjxTYW5kYm94UmVjb3JkPihzYW5kYm94RGlyKTtcbiAgICAgIGxldCBmaWx0ZXJlZCA9IGFsbFNhbmRib3hlcztcbiAgICAgIGlmICh0YWdzICYmIE9iamVjdC5rZXlzKHRhZ3MpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZmlsdGVyZWQgPSBmaWx0ZXJlZC5maWx0ZXIoKHMpID0+IHtcbiAgICAgICAgICBjb25zdCBzYW5kYm94VGFncyA9IHMudGFncyA/PyB7fTtcbiAgICAgICAgICByZXR1cm4gT2JqZWN0LmVudHJpZXModGFncykuZXZlcnkoKFtrZXksIHZhbHVlXSkgPT5cbiAgICAgICAgICAgIGVxdWFsKHNhbmRib3hUYWdzW2tleV0sIHZhbHVlKVxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3Qgc29ydEZpZWxkID0gb3JkZXI/LnN0YXJ0c1dpdGgoXCJsYXN0QWN0aXZpdHlBdFwiKVxuICAgICAgICA/IFwibGFzdEFjdGl2aXR5QXRcIlxuICAgICAgICA6IFwiY3JlYXRlZEF0XCI7XG4gICAgICBjb25zdCBzb3J0RGlyID0gb3JkZXI/LmVuZHNXaXRoKFwiX2Rlc2NcIikgPyAtMSA6IDE7XG4gICAgICBmaWx0ZXJlZC5zb3J0KFxuICAgICAgICAoYSwgYikgPT4gc29ydERpciAqICgoYVtzb3J0RmllbGRdID8/IDApIC0gKGJbc29ydEZpZWxkXSA/PyAwKSlcbiAgICAgICk7XG4gICAgICByZXR1cm4gcGFnaW5hdGUoeyBpdGVtczogZmlsdGVyZWQsIGN1cnNvciwgbGltaXQgfSk7XG4gICAgfSxcblxuICAgIFwic2FuZGJveC50YWcuc2V0XCI6IGFzeW5jICh7IHNhbmRib3hJZCwgdGFncyB9KSA9PiB7XG4gICAgICBjb25zdCBzYWZlTmFtZSA9IEJ1ZmZlci5mcm9tKHNhbmRib3hJZCkudG9TdHJpbmcoXCJiYXNlNjR1cmxcIik7XG4gICAgICBjb25zdCBzYW5kYm94UGF0aCA9IGpvaW4oc2FuZGJveERpciwgYCR7c2FmZU5hbWV9Lmpzb25gKTtcbiAgICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgcmVhZEpzb248U2FuZGJveFJlY29yZD4oc2FuZGJveFBhdGgpO1xuICAgICAgaWYgKCFleGlzdGluZykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFNhbmRib3ggJHtzYW5kYm94SWR9IG5vdCBmb3VuZGApO1xuICAgICAgfVxuICAgICAgY29uc3QgbWVyZ2VkVGFncyA9IHsgLi4uZXhpc3RpbmcudGFncywgLi4udGFncyB9O1xuICAgICAgY29uc3QgdXBkYXRlZFNhbmRib3g6IFNhbmRib3hSZWNvcmQgPSB7XG4gICAgICAgIC4uLmV4aXN0aW5nLFxuICAgICAgICB0YWdzOiBtZXJnZWRUYWdzLFxuICAgICAgfTtcbiAgICAgIGF3YWl0IHdyaXRlSnNvbkZpbGUoc2FuZGJveFBhdGgsIHVwZGF0ZWRTYW5kYm94KTtcbiAgICAgIHJldHVybiB1cGRhdGVkU2FuZGJveDtcbiAgICB9LFxuXG4gICAgXCJzYW5kYm94LmdldEJ5U2Vzc2lvblwiOiBhc3luYyAoeyBzZXNzaW9uSWQgfSkgPT4ge1xuICAgICAgY29uc3QgYWxsU2FuZGJveGVzID0gYXdhaXQgcmVhZEFsbEZyb21EaXI8U2FuZGJveFJlY29yZD4oc2FuZGJveERpcik7XG4gICAgICBjb25zdCBtYXRjaGluZyA9IGFsbFNhbmRib3hlcy5maWx0ZXIoKHMpID0+XG4gICAgICAgIHMuaWQuc3RhcnRzV2l0aChgJHtzZXNzaW9uSWR9LWApXG4gICAgICApO1xuICAgICAgaWYgKG1hdGNoaW5nLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIG1hdGNoaW5nLnNvcnQoXG4gICAgICAgIChhLCBiKSA9PiAoYi5sYXN0QWN0aXZpdHlBdCA/PyAwKSAtIChhLmxhc3RBY3Rpdml0eUF0ID8/IDApXG4gICAgICApO1xuICAgICAgcmV0dXJuIG1hdGNoaW5nWzBdO1xuICAgIH0sXG5cbiAgICBcImNvbW1hbmQuZ2V0XCI6IGFzeW5jICh7IGlkIH0pID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCByZWFkSnNvbjxDb21tYW5kPihqb2luKGNvbW1hbmREaXIsIGAke2lkfS5qc29uYCkpO1xuICAgIH0sXG5cbiAgICBcImNvbW1hbmQuc2V0XCI6IGFzeW5jIChjb21tYW5kKSA9PiB7XG4gICAgICBhd2FpdCB3cml0ZUpzb25GaWxlKGpvaW4oY29tbWFuZERpciwgYCR7Y29tbWFuZC5pZH0uanNvbmApLCBjb21tYW5kKTtcbiAgICAgIHJldHVybiBjb21tYW5kO1xuICAgIH0sXG5cbiAgICBcInNldHVwLmdldFwiOiBhc3luYyAoeyBrZXkgfSkgPT4ge1xuICAgICAgY29uc3Qgc2FmZU5hbWUgPSBCdWZmZXIuZnJvbShrZXkpLnRvU3RyaW5nKFwiYmFzZTY0dXJsXCIpO1xuICAgICAgcmV0dXJuIGF3YWl0IHJlYWRKc29uPFNldHVwU25hcHNob3Q+KGpvaW4oc2V0dXBEaXIsIGAke3NhZmVOYW1lfS5qc29uYCkpO1xuICAgIH0sXG5cbiAgICBcInNldHVwLnNldFwiOiBhc3luYyAoc25hcHNob3QpID0+IHtcbiAgICAgIGNvbnN0IHNhZmVOYW1lID0gQnVmZmVyLmZyb20oc25hcHNob3Qua2V5KS50b1N0cmluZyhcImJhc2U2NHVybFwiKTtcbiAgICAgIGF3YWl0IHdyaXRlSnNvbkZpbGUoam9pbihzZXR1cERpciwgYCR7c2FmZU5hbWV9Lmpzb25gKSwgc25hcHNob3QpO1xuICAgIH0sXG5cbiAgICBcInNldHVwLmFjcXVpcmVMb2NrXCI6IGFzeW5jICh7IGtleSwgbG9ja0lkLCBsb2NrVGltZW91dE1zIH0pID0+IHtcbiAgICAgIGNvbnN0IHNhZmVOYW1lID0gQnVmZmVyLmZyb20oa2V5KS50b1N0cmluZyhcImJhc2U2NHVybFwiKTtcbiAgICAgIGNvbnN0IGZpbGVQYXRoID0gam9pbihzZXR1cERpciwgYCR7c2FmZU5hbWV9Lmpzb25gKTtcbiAgICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgcmVhZEpzb248U2V0dXBTbmFwc2hvdD4oZmlsZVBhdGgpO1xuICAgICAgaWYgKFxuICAgICAgICBleGlzdGluZz8uYWNxdWlyaW5nTG9ja0lkICYmXG4gICAgICAgIGV4aXN0aW5nLmFjcXVpcmluZ0xvY2tBdCAmJlxuICAgICAgICBEYXRlLm5vdygpIC0gZXhpc3RpbmcuYWNxdWlyaW5nTG9ja0F0IDwgbG9ja1RpbWVvdXRNc1xuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBudWxsOyAvLyBhY3RpdmUgbG9jayBoZWxkIGJ5IHNvbWVvbmUgZWxzZVxuICAgICAgfVxuICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IHNuYXBzaG90OiBTZXR1cFNuYXBzaG90ID0ge1xuICAgICAgICBrZXksXG4gICAgICAgIHNuYXBzaG90SWQ6IGV4aXN0aW5nPy5zbmFwc2hvdElkID8/IG51bGwsXG4gICAgICAgIGNyZWF0ZWRBdDogZXhpc3Rpbmc/LmNyZWF0ZWRBdCA/PyBub3csXG4gICAgICAgIGxhc3RVc2VkQXQ6IGV4aXN0aW5nPy5sYXN0VXNlZEF0ID8/IG51bGwsXG4gICAgICAgIGFjcXVpcmluZ0xvY2tJZDogbG9ja0lkLFxuICAgICAgICBhY3F1aXJpbmdMb2NrQXQ6IG5vdyxcbiAgICAgIH07XG4gICAgICBhd2FpdCB3cml0ZUpzb25GaWxlKGZpbGVQYXRoLCBzbmFwc2hvdCk7XG4gICAgICByZXR1cm4gc25hcHNob3Q7XG4gICAgfSxcblxuICAgIFwic2FuZGJveC5hY3F1aXJlTG9ja1wiOiBhc3luYyAoeyByZWNvcmQsIGxvY2tUaW1lb3V0TXMgfSkgPT4ge1xuICAgICAgY29uc3Qgc2FmZU5hbWUgPSBCdWZmZXIuZnJvbShyZWNvcmQuaWQpLnRvU3RyaW5nKFwiYmFzZTY0dXJsXCIpO1xuICAgICAgY29uc3QgZmlsZVBhdGggPSBqb2luKHNhbmRib3hEaXIsIGAke3NhZmVOYW1lfS5qc29uYCk7XG4gICAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHJlYWRKc29uPFNhbmRib3hSZWNvcmQ+KGZpbGVQYXRoKTtcbiAgICAgIGlmIChcbiAgICAgICAgZXhpc3Rpbmc/LmFjcXVpcmluZ0xvY2tJZCAmJlxuICAgICAgICBleGlzdGluZy5hY3F1aXJpbmdMb2NrQXQgJiZcbiAgICAgICAgRGF0ZS5ub3coKSAtIGV4aXN0aW5nLmFjcXVpcmluZ0xvY2tBdCA8IGxvY2tUaW1lb3V0TXNcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gbnVsbDsgLy8gYWN0aXZlIGxvY2sgaGVsZCBieSBzb21lb25lIGVsc2VcbiAgICAgIH1cbiAgICAgIGNvbnN0IG5ld1JlY29yZDogU2FuZGJveFJlY29yZCA9IHtcbiAgICAgICAgLi4ucmVjb3JkLFxuICAgICAgICB0YWdzOiByZWNvcmQudGFncyA/PyBleGlzdGluZz8udGFncyA/PyBudWxsLFxuICAgICAgfTtcbiAgICAgIGF3YWl0IHdyaXRlSnNvbkZpbGUoZmlsZVBhdGgsIG5ld1JlY29yZCk7XG4gICAgICByZXR1cm4gbmV3UmVjb3JkO1xuICAgIH0sXG5cbiAgICBcImNvbW1hbmQubGlzdFwiOiBhc3luYyAoeyBzZXNzaW9uSWQsIGluY2x1ZGVGaW5pc2hlZCwgY3Vyc29yLCBsaW1pdCB9KSA9PiB7XG4gICAgICBjb25zdCBhbGxDb21tYW5kcyA9IGF3YWl0IHJlYWRBbGxGcm9tRGlyPENvbW1hbmQ+KGNvbW1hbmREaXIpO1xuICAgICAgbGV0IGZpbHRlcmVkID0gYWxsQ29tbWFuZHMuZmlsdGVyKChjKSA9PiBjLnNlc3Npb25JZCA9PT0gc2Vzc2lvbklkKTtcbiAgICAgIGlmICghaW5jbHVkZUZpbmlzaGVkKSB7XG4gICAgICAgIGZpbHRlcmVkID0gZmlsdGVyZWQuZmlsdGVyKChjKSA9PiBjLnN0YXR1cyA9PT0gXCJydW5uaW5nXCIpO1xuICAgICAgfVxuICAgICAgZmlsdGVyZWQuc29ydCgoYSwgYikgPT4gYS5zdGFydGVkQXQgLSBiLnN0YXJ0ZWRBdCk7XG4gICAgICByZXR1cm4gcGFnaW5hdGUoeyBpdGVtczogZmlsdGVyZWQsIGN1cnNvciwgbGltaXQgfSk7XG4gICAgfSxcbiAgfTtcbn1cbiIsICJpbXBvcnQgdHlwZSB7IExpc3RSZXN1bHQgfSBmcm9tIFwiLi4vc3RvcmFnZVwiO1xuXG5leHBvcnQgZnVuY3Rpb24gcGFnaW5hdGU8VCBleHRlbmRzIHsgaWQ6IHN0cmluZyB9PihvcHRzOiB7XG4gIGl0ZW1zOiBUW107XG4gIGN1cnNvcj86IHN0cmluZztcbiAgbGltaXQ/OiBudW1iZXI7XG59KTogTGlzdFJlc3VsdDxUPiB7XG4gIGNvbnN0IHsgaXRlbXMsIGN1cnNvciwgbGltaXQgfSA9IG9wdHM7XG4gIGNvbnN0IHN0YXJ0SW5kZXggPSBjdXJzb3IgPyBpdGVtcy5maW5kSW5kZXgoKG0pID0+IG0uaWQgPT09IGN1cnNvcikgKyAxIDogMDtcbiAgY29uc3Qgc2xpY2VkID1cbiAgICBsaW1pdCAhPT0gdW5kZWZpbmVkXG4gICAgICA/IGl0ZW1zLnNsaWNlKHN0YXJ0SW5kZXgsIHN0YXJ0SW5kZXggKyBsaW1pdClcbiAgICAgIDogaXRlbXMuc2xpY2Uoc3RhcnRJbmRleCk7XG4gIGNvbnN0IG5leHRDdXJzb3IgPVxuICAgIGxpbWl0ICE9PSB1bmRlZmluZWQgJiYgc3RhcnRJbmRleCArIGxpbWl0IDwgaXRlbXMubGVuZ3RoXG4gICAgICA/IChzbGljZWQuYXQoLTEpPy5pZCA/PyBudWxsKVxuICAgICAgOiBudWxsO1xuICByZXR1cm4geyBpdGVtczogc2xpY2VkLCBuZXh0Q3Vyc29yIH07XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7QUFBQSxTQUFTLE9BQU8sU0FBUyxVQUFVLFFBQVEsaUJBQWlCO0FBQzVELFNBQVMsU0FBUyxNQUFNLGVBQWU7QUFDdkMsT0FBTyxXQUFXOzs7QUNBWCxTQUFTLFNBQW1DLE1BSWpDO0FBQ2hCLFFBQU0sRUFBRSxPQUFPLFFBQVEsTUFBTSxJQUFJO0FBQ2pDLFFBQU0sYUFBYSxTQUFTLE1BQU0sVUFBVSxDQUFDLE1BQU0sRUFBRSxPQUFPLE1BQU0sSUFBSSxJQUFJO0FBQzFFLFFBQU0sU0FDSixVQUFVLFNBQ04sTUFBTSxNQUFNLFlBQVksYUFBYSxLQUFLLElBQzFDLE1BQU0sTUFBTSxVQUFVO0FBQzVCLFFBQU0sYUFDSixVQUFVLFVBQWEsYUFBYSxRQUFRLE1BQU0sU0FDN0MsT0FBTyxHQUFHLEVBQUUsR0FBRyxNQUFNLE9BQ3RCO0FBQ04sU0FBTyxFQUFFLE9BQU8sUUFBUSxXQUFXO0FBQ3JDOzs7QURKTyxTQUFTLHlCQUF5QixVQUE0QjtBQUNuRSxRQUFNLGVBQWUsUUFBUSxRQUFRO0FBQ3JDLFFBQU0sYUFBYSxLQUFLLGNBQWMsU0FBUztBQUMvQyxRQUFNLGFBQWEsS0FBSyxjQUFjLFNBQVM7QUFDL0MsUUFBTSxVQUFVLEtBQUssY0FBYyxNQUFNO0FBQ3pDLFFBQU0sYUFBYSxLQUFLLGNBQWMsU0FBUztBQUMvQyxRQUFNLGFBQWEsS0FBSyxjQUFjLFNBQVM7QUFDL0MsUUFBTSxXQUFXLEtBQUssY0FBYyxPQUFPO0FBRTNDLGlCQUFlLFVBQVUsS0FBYTtBQUNwQyxVQUFNLE1BQU0sS0FBSyxFQUFFLFdBQVcsS0FBSyxDQUFDO0FBQUEsRUFDdEM7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