experimental-agent 0.1.1 → 0.1.2
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/dist/agent-workflow.d.mts +3 -2
- package/dist/agent-workflow.d.ts +3 -2
- package/dist/agent-workflow.js +29 -29
- package/dist/agent-workflow.mjs +1 -2
- package/dist/{chunk-GJETDXOU.mjs → chunk-2SPAJ777.mjs} +5 -1
- package/dist/chunk-6J462JGP.mjs +1267 -0
- package/dist/{chunk-T2UUL6VC.mjs → chunk-E7TOPGHY.mjs} +3 -3
- package/dist/chunk-ILPVXRI5.mjs +2026 -0
- package/dist/chunk-ORE6LK2L.mjs +344 -0
- package/dist/chunk-W4SSZPDX.mjs +106 -0
- package/dist/{types-DuTc4UQW.d.mts → client-CKLwB-ES.d.mts} +730 -3
- package/dist/{types-DuTc4UQW.d.ts → client-CKLwB-ES.d.ts} +730 -3
- package/dist/{client-66JIQLSA.mjs → client-YUU54ZZH.mjs} +1 -1
- package/dist/{handler-BQY5SOI2.mjs → handler-LDFBSCRA.mjs} +1 -1
- package/dist/index.d.mts +4 -18
- package/dist/index.d.ts +4 -18
- package/dist/index.js +67 -40
- package/dist/index.mjs +21 -16
- package/dist/lifecycle-workflow.d.mts +2 -3
- package/dist/lifecycle-workflow.d.ts +2 -3
- package/dist/lifecycle-workflow.js +19 -15
- package/dist/lifecycle-workflow.mjs +1 -2
- package/dist/local-fs-handlers-SY2RDXZE.mjs +314 -0
- package/dist/next/loader.js +3 -3
- package/dist/next/loader.mjs +1 -1
- package/dist/next.js +3 -5
- package/dist/next.mjs +2 -4
- package/dist/{sandbox-27X2DSE3.mjs → sandbox-GPCA35PJ.mjs} +2 -3
- package/dist/{storage-KQYV42J4.mjs → storage-LL6IA24R.mjs} +2 -2
- package/package.json +2 -2
- package/dist/chunk-2IIWVPZB.mjs +0 -334
- package/dist/chunk-A63YU65A.mjs +0 -20
- package/dist/chunk-RDKDLHXM.mjs +0 -2031
- package/dist/chunk-VGJISV6O.mjs +0 -108
- package/dist/chunk-VS7U6SXN.mjs +0 -1261
- package/dist/client-DjcE0ATp.d.mts +0 -710
- package/dist/client-DwrDzn4_.d.ts +0 -710
- package/dist/local-fs-handlers-Q5W52DKV.mjs +0 -290
|
@@ -1,290 +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.list": async ({ tags, order, cursor, limit }) => {
|
|
71
|
-
const allSessions = await readAllFromDir(sessionDir);
|
|
72
|
-
let filtered = allSessions;
|
|
73
|
-
if (tags && Object.keys(tags).length > 0) {
|
|
74
|
-
filtered = filtered.filter((s) => {
|
|
75
|
-
const sessionTags = s.tags ?? {};
|
|
76
|
-
return Object.entries(tags).every(
|
|
77
|
-
([key, value]) => equal(sessionTags[key], value)
|
|
78
|
-
);
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
const resolvedOrder = order ?? "updatedAt_desc";
|
|
82
|
-
const sortField = resolvedOrder.startsWith("updatedAt") ? "updatedAt" : "createdAt";
|
|
83
|
-
const sortDir = resolvedOrder.endsWith("_desc") ? -1 : 1;
|
|
84
|
-
filtered.sort((a, b) => sortDir * (a[sortField] - b[sortField]));
|
|
85
|
-
return paginate({ items: filtered, cursor, limit });
|
|
86
|
-
},
|
|
87
|
-
"session.listBySandbox": async ({
|
|
88
|
-
sandboxId,
|
|
89
|
-
tags,
|
|
90
|
-
order,
|
|
91
|
-
cursor,
|
|
92
|
-
limit
|
|
93
|
-
}) => {
|
|
94
|
-
const allSessions = await readAllFromDir(sessionDir);
|
|
95
|
-
let filtered = allSessions.filter((s) => s.sandboxId === sandboxId);
|
|
96
|
-
if (tags && Object.keys(tags).length > 0) {
|
|
97
|
-
filtered = filtered.filter((s) => {
|
|
98
|
-
const sessionTags = s.tags ?? {};
|
|
99
|
-
return Object.entries(tags).every(
|
|
100
|
-
([key, value]) => equal(sessionTags[key], value)
|
|
101
|
-
);
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
const resolvedOrder = order ?? "updatedAt_desc";
|
|
105
|
-
const sortField = resolvedOrder.startsWith("updatedAt") ? "updatedAt" : "createdAt";
|
|
106
|
-
const sortDir = resolvedOrder.endsWith("_desc") ? -1 : 1;
|
|
107
|
-
filtered.sort((a, b) => sortDir * (a[sortField] - b[sortField]));
|
|
108
|
-
return paginate({ items: filtered, cursor, limit });
|
|
109
|
-
},
|
|
110
|
-
"session.tag.set": async ({ sessionId, tags }) => {
|
|
111
|
-
const sessionPath = join(sessionDir, `${sessionId}.json`);
|
|
112
|
-
const existing = await readJson(sessionPath);
|
|
113
|
-
if (!existing) {
|
|
114
|
-
throw new Error(`Session ${sessionId} not found`);
|
|
115
|
-
}
|
|
116
|
-
const mergedTags = { ...existing.tags, ...tags };
|
|
117
|
-
const now = Date.now();
|
|
118
|
-
const updatedSession = {
|
|
119
|
-
...existing,
|
|
120
|
-
tags: mergedTags,
|
|
121
|
-
updatedAt: now
|
|
122
|
-
};
|
|
123
|
-
await writeJsonFile(sessionPath, updatedSession);
|
|
124
|
-
return updatedSession;
|
|
125
|
-
},
|
|
126
|
-
"message.get": async ({ id }) => {
|
|
127
|
-
return await readJson(join(messageDir, `${id}.json`));
|
|
128
|
-
},
|
|
129
|
-
"message.set": async (message) => {
|
|
130
|
-
await writeJsonFile(join(messageDir, `${message.id}.json`), message);
|
|
131
|
-
return message;
|
|
132
|
-
},
|
|
133
|
-
"message.list": async ({ sessionId, cursor, limit }) => {
|
|
134
|
-
const allMessages = await readAllFromDir(messageDir);
|
|
135
|
-
const filtered = allMessages.filter((m) => m.sessionId === sessionId).sort((a, b) => a.createdAt - b.createdAt);
|
|
136
|
-
return paginate({ items: filtered, cursor, limit });
|
|
137
|
-
},
|
|
138
|
-
"part.listByMessage": async ({ messageId, cursor, limit }) => {
|
|
139
|
-
const allParts = await readAllFromDir(partDir);
|
|
140
|
-
const filtered = allParts.filter((p) => p.messageId === messageId).sort((a, b) => a.index - b.index);
|
|
141
|
-
return paginate({ items: filtered, cursor, limit });
|
|
142
|
-
},
|
|
143
|
-
"part.listBySession": async ({ sessionId, cursor, limit }) => {
|
|
144
|
-
const allParts = await readAllFromDir(partDir);
|
|
145
|
-
const filtered = allParts.filter((p) => p.sessionId === sessionId).sort((a, b) => {
|
|
146
|
-
if (a.messageId !== b.messageId) {
|
|
147
|
-
return a.messageId.localeCompare(b.messageId);
|
|
148
|
-
}
|
|
149
|
-
return a.index - b.index;
|
|
150
|
-
});
|
|
151
|
-
return paginate({ items: filtered, cursor, limit });
|
|
152
|
-
},
|
|
153
|
-
"part.set": async (part) => {
|
|
154
|
-
await writeJsonFile(join(partDir, `${part.id}.json`), part);
|
|
155
|
-
return part;
|
|
156
|
-
},
|
|
157
|
-
"part.delete": async ({ id }) => {
|
|
158
|
-
try {
|
|
159
|
-
await unlink(join(partDir, `${id}.json`));
|
|
160
|
-
} catch {
|
|
161
|
-
}
|
|
162
|
-
},
|
|
163
|
-
"sandbox.get": async ({ key }) => {
|
|
164
|
-
const safeName = Buffer.from(key).toString("base64url");
|
|
165
|
-
const sandboxPath = join(sandboxDir, `${safeName}.json`);
|
|
166
|
-
const data = await readJson(sandboxPath);
|
|
167
|
-
if (!data) {
|
|
168
|
-
return null;
|
|
169
|
-
}
|
|
170
|
-
return data;
|
|
171
|
-
},
|
|
172
|
-
"sandbox.set": async (record) => {
|
|
173
|
-
const safeName = Buffer.from(record.id).toString("base64url");
|
|
174
|
-
const sandboxPath = join(sandboxDir, `${safeName}.json`);
|
|
175
|
-
const existing = await readJson(sandboxPath);
|
|
176
|
-
const newRecord = {
|
|
177
|
-
...record,
|
|
178
|
-
tags: record.tags ?? existing?.tags ?? null
|
|
179
|
-
};
|
|
180
|
-
await writeJsonFile(sandboxPath, newRecord);
|
|
181
|
-
},
|
|
182
|
-
"sandbox.list": async ({ tags, order, cursor, limit }) => {
|
|
183
|
-
const allSandboxes = await readAllFromDir(sandboxDir);
|
|
184
|
-
let filtered = allSandboxes;
|
|
185
|
-
if (tags && Object.keys(tags).length > 0) {
|
|
186
|
-
filtered = filtered.filter((s) => {
|
|
187
|
-
const sandboxTags = s.tags ?? {};
|
|
188
|
-
return Object.entries(tags).every(
|
|
189
|
-
([key, value]) => equal(sandboxTags[key], value)
|
|
190
|
-
);
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
const sortField = order?.startsWith("lastActivityAt") ? "lastActivityAt" : "createdAt";
|
|
194
|
-
const sortDir = order?.endsWith("_desc") ? -1 : 1;
|
|
195
|
-
filtered.sort(
|
|
196
|
-
(a, b) => sortDir * ((a[sortField] ?? 0) - (b[sortField] ?? 0))
|
|
197
|
-
);
|
|
198
|
-
return paginate({ items: filtered, cursor, limit });
|
|
199
|
-
},
|
|
200
|
-
"sandbox.tag.set": async ({ sandboxId, tags }) => {
|
|
201
|
-
const safeName = Buffer.from(sandboxId).toString("base64url");
|
|
202
|
-
const sandboxPath = join(sandboxDir, `${safeName}.json`);
|
|
203
|
-
const existing = await readJson(sandboxPath);
|
|
204
|
-
if (!existing) {
|
|
205
|
-
throw new Error(`Sandbox ${sandboxId} not found`);
|
|
206
|
-
}
|
|
207
|
-
const mergedTags = { ...existing.tags, ...tags };
|
|
208
|
-
const updatedSandbox = {
|
|
209
|
-
...existing,
|
|
210
|
-
tags: mergedTags
|
|
211
|
-
};
|
|
212
|
-
await writeJsonFile(sandboxPath, updatedSandbox);
|
|
213
|
-
return updatedSandbox;
|
|
214
|
-
},
|
|
215
|
-
"sandbox.getBySession": async ({ sessionId }) => {
|
|
216
|
-
const allSandboxes = await readAllFromDir(sandboxDir);
|
|
217
|
-
const matching = allSandboxes.filter(
|
|
218
|
-
(s) => s.id.startsWith(`${sessionId}-`)
|
|
219
|
-
);
|
|
220
|
-
if (matching.length === 0) {
|
|
221
|
-
return null;
|
|
222
|
-
}
|
|
223
|
-
matching.sort(
|
|
224
|
-
(a, b) => (b.lastActivityAt ?? 0) - (a.lastActivityAt ?? 0)
|
|
225
|
-
);
|
|
226
|
-
return matching[0];
|
|
227
|
-
},
|
|
228
|
-
"command.get": async ({ id }) => {
|
|
229
|
-
return await readJson(join(commandDir, `${id}.json`));
|
|
230
|
-
},
|
|
231
|
-
"command.set": async (command) => {
|
|
232
|
-
await writeJsonFile(join(commandDir, `${command.id}.json`), command);
|
|
233
|
-
return command;
|
|
234
|
-
},
|
|
235
|
-
"setup.get": async ({ key }) => {
|
|
236
|
-
const safeName = Buffer.from(key).toString("base64url");
|
|
237
|
-
return await readJson(join(setupDir, `${safeName}.json`));
|
|
238
|
-
},
|
|
239
|
-
"setup.set": async (snapshot) => {
|
|
240
|
-
const safeName = Buffer.from(snapshot.key).toString("base64url");
|
|
241
|
-
await writeJsonFile(join(setupDir, `${safeName}.json`), snapshot);
|
|
242
|
-
},
|
|
243
|
-
"setup.acquireLock": async ({ key, lockId, lockTimeoutMs }) => {
|
|
244
|
-
const safeName = Buffer.from(key).toString("base64url");
|
|
245
|
-
const filePath = join(setupDir, `${safeName}.json`);
|
|
246
|
-
const existing = await readJson(filePath);
|
|
247
|
-
if (existing?.acquiringLockId && existing.acquiringLockAt && Date.now() - existing.acquiringLockAt < lockTimeoutMs) {
|
|
248
|
-
return null;
|
|
249
|
-
}
|
|
250
|
-
const now = Date.now();
|
|
251
|
-
const snapshot = {
|
|
252
|
-
key,
|
|
253
|
-
snapshotId: existing?.snapshotId ?? null,
|
|
254
|
-
createdAt: existing?.createdAt ?? now,
|
|
255
|
-
lastUsedAt: existing?.lastUsedAt ?? null,
|
|
256
|
-
acquiringLockId: lockId,
|
|
257
|
-
acquiringLockAt: now
|
|
258
|
-
};
|
|
259
|
-
await writeJsonFile(filePath, snapshot);
|
|
260
|
-
return snapshot;
|
|
261
|
-
},
|
|
262
|
-
"sandbox.acquireLock": async ({ record, lockTimeoutMs }) => {
|
|
263
|
-
const safeName = Buffer.from(record.id).toString("base64url");
|
|
264
|
-
const filePath = join(sandboxDir, `${safeName}.json`);
|
|
265
|
-
const existing = await readJson(filePath);
|
|
266
|
-
if (existing?.acquiringLockId && existing.acquiringLockAt && Date.now() - existing.acquiringLockAt < lockTimeoutMs) {
|
|
267
|
-
return null;
|
|
268
|
-
}
|
|
269
|
-
const newRecord = {
|
|
270
|
-
...record,
|
|
271
|
-
tags: record.tags ?? existing?.tags ?? null
|
|
272
|
-
};
|
|
273
|
-
await writeJsonFile(filePath, newRecord);
|
|
274
|
-
return newRecord;
|
|
275
|
-
},
|
|
276
|
-
"command.list": async ({ sessionId, includeFinished, cursor, limit }) => {
|
|
277
|
-
const allCommands = await readAllFromDir(commandDir);
|
|
278
|
-
let filtered = allCommands.filter((c) => c.sessionId === sessionId);
|
|
279
|
-
if (!includeFinished) {
|
|
280
|
-
filtered = filtered.filter((c) => c.status === "running");
|
|
281
|
-
}
|
|
282
|
-
filtered.sort((a, b) => a.startedAt - b.startedAt);
|
|
283
|
-
return paginate({ items: filtered, cursor, limit });
|
|
284
|
-
}
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
export {
|
|
288
|
-
createFilesystemHandlers
|
|
289
|
-
};
|
|
290
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3N0b3JhZ2UvYmluZGluZ3MvbG9jYWwtZnMtaGFuZGxlcnMudHMiLCAiLi4vc3JjL3V0aWxzL3BhZ2luYXRlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgeyBta2RpciwgcmVhZGRpciwgcmVhZEZpbGUsIHVubGluaywgd3JpdGVGaWxlIH0gZnJvbSBcIm5vZGU6ZnMvcHJvbWlzZXNcIjtcbmltcG9ydCB7IGRpcm5hbWUsIGpvaW4sIHJlc29sdmUgfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgZXF1YWwgZnJvbSBcImZhc3QtZGVlcC1lcXVhbFwiO1xuaW1wb3J0IHsgcGFnaW5hdGUgfSBmcm9tIFwiLi4vLi4vdXRpbHMvcGFnaW5hdGVcIjtcbmltcG9ydCB0eXBlIHtcbiAgQ29tbWFuZCxcbiAgSGFuZGxlcnMsXG4gIE1lc3NhZ2UsXG4gIFBhcnQsXG4gIFNhbmRib3hSZWNvcmQsXG4gIFNlc3Npb24sXG4gIFNldHVwU25hcHNob3QsXG59IGZyb20gXCIuLlwiO1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRmlsZXN5c3RlbUhhbmRsZXJzKGJhc2VQYXRoOiBzdHJpbmcpOiBIYW5kbGVycyB7XG4gIGNvbnN0IHJlc29sdmVkQmFzZSA9IHJlc29sdmUoYmFzZVBhdGgpO1xuICBjb25zdCBzZXNzaW9uRGlyID0gam9pbihyZXNvbHZlZEJhc2UsIFwic2Vzc2lvblwiKTtcbiAgY29uc3QgbWVzc2FnZURpciA9IGpvaW4ocmVzb2x2ZWRCYXNlLCBcIm1lc3NhZ2VcIik7XG4gIGNvbnN0IHBhcnREaXIgPSBqb2luKHJlc29sdmVkQmFzZSwgXCJwYXJ0XCIpO1xuICBjb25zdCBzYW5kYm94RGlyID0gam9pbihyZXNvbHZlZEJhc2UsIFwic2FuZGJveFwiKTtcbiAgY29uc3QgY29tbWFuZERpciA9IGpvaW4ocmVzb2x2ZWRCYXNlLCBcImNvbW1hbmRcIik7XG4gIGNvbnN0IHNldHVwRGlyID0gam9pbihyZXNvbHZlZEJhc2UsIFwic2V0dXBcIik7XG5cbiAgYXN5bmMgZnVuY3Rpb24gZW5zdXJlRGlyKGRpcjogc3RyaW5nKSB7XG4gICAgYXdhaXQgbWtkaXIoZGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIHJlYWRKc29uPFQ+KGZpbGVQYXRoOiBzdHJpbmcpOiBQcm9taXNlPFQgfCBudWxsPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBhd2FpdCByZWFkRmlsZShmaWxlUGF0aCwgXCJ1dGYtOFwiKTtcbiAgICAgIHJldHVybiBKU09OLnBhcnNlKGNvbnRlbnQpIGFzIFQ7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiB3cml0ZUpzb25GaWxlKGZpbGVQYXRoOiBzdHJpbmcsIGRhdGE6IHVua25vd24pIHtcbiAgICBhd2FpdCBlbnN1cmVEaXIoZGlybmFtZShmaWxlUGF0aCkpO1xuICAgIGF3YWl0IHdyaXRlRmlsZShmaWxlUGF0aCwgSlNPTi5zdHJpbmdpZnkoZGF0YSwgbnVsbCwgMikpO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gcmVhZEFsbEZyb21EaXI8VD4oZGlyOiBzdHJpbmcpOiBQcm9taXNlPFRbXT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBmaWxlcyA9IGF3YWl0IHJlYWRkaXIoZGlyKTtcbiAgICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgZmlsZXNcbiAgICAgICAgICAuZmlsdGVyKChmKSA9PiBmLmVuZHNXaXRoKFwiLmpzb25cIikpXG4gICAgICAgICAgLm1hcCgoZikgPT4gcmVhZEpzb248VD4oam9pbihkaXIsIGYpKSlcbiAgICAgICk7XG4gICAgICByZXR1cm4gcmVzdWx0cy5maWx0ZXIoKHIpOiByIGlzIE5vbk51bGxhYmxlPHR5cGVvZiByPiA9PiByICE9PSBudWxsKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIFwic2Vzc2lvbi5nZXRcIjogYXN5bmMgKHsgaWQgfSkgPT4ge1xuICAgICAgY29uc3Qgc2Vzc2lvblBhdGggPSBqb2luKHNlc3Npb25EaXIsIGAke2lkfS5qc29uYCk7XG4gICAgICByZXR1cm4gKGF3YWl0IHJlYWRKc29uPFNlc3Npb24+KHNlc3Npb25QYXRoKSkgPz8gbnVsbDtcbiAgICB9LFxuXG4gICAgXCJzZXNzaW9uLnNldFwiOiBhc3luYyAoc2Vzc2lvbikgPT4ge1xuICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IHNlc3Npb25QYXRoID0gam9pbihzZXNzaW9uRGlyLCBgJHtzZXNzaW9uLmlkfS5qc29uYCk7XG4gICAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHJlYWRKc29uPFNlc3Npb24+KHNlc3Npb25QYXRoKTtcbiAgICAgIGNvbnN0IG5ld1Nlc3Npb246IFNlc3Npb24gPSB7XG4gICAgICAgIC4uLnNlc3Npb24sXG4gICAgICAgIHRhZ3M6IHNlc3Npb24udGFncyA/PyBleGlzdGluZz8udGFncyA/PyB7fSxcbiAgICAgICAgY3JlYXRlZEF0OiBleGlzdGluZz8uY3JlYXRlZEF0ID8/IHNlc3Npb24uY3JlYXRlZEF0ID8/IG5vdyxcbiAgICAgICAgdXBkYXRlZEF0OiBub3csXG4gICAgICB9O1xuICAgICAgYXdhaXQgd3JpdGVKc29uRmlsZShzZXNzaW9uUGF0aCwgbmV3U2Vzc2lvbik7XG4gICAgICByZXR1cm4gbmV3U2Vzc2lvbjtcbiAgICB9LFxuXG4gICAgXCJzZXNzaW9uLmxpc3RcIjogYXN5bmMgKHsgdGFncywgb3JkZXIsIGN1cnNvciwgbGltaXQgfSkgPT4ge1xuICAgICAgY29uc3QgYWxsU2Vzc2lvbnMgPSBhd2FpdCByZWFkQWxsRnJvbURpcjxTZXNzaW9uPihzZXNzaW9uRGlyKTtcbiAgICAgIGxldCBmaWx0ZXJlZCA9IGFsbFNlc3Npb25zO1xuICAgICAgaWYgKHRhZ3MgJiYgT2JqZWN0LmtleXModGFncykubGVuZ3RoID4gMCkge1xuICAgICAgICBmaWx0ZXJlZCA9IGZpbHRlcmVkLmZpbHRlcigocykgPT4ge1xuICAgICAgICAgIGNvbnN0IHNlc3Npb25UYWdzID0gcy50YWdzID8/IHt9O1xuICAgICAgICAgIHJldHVybiBPYmplY3QuZW50cmllcyh0YWdzKS5ldmVyeSgoW2tleSwgdmFsdWVdKSA9PlxuICAgICAgICAgICAgZXF1YWwoc2Vzc2lvblRhZ3Nba2V5XSwgdmFsdWUpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCByZXNvbHZlZE9yZGVyID0gb3JkZXIgPz8gXCJ1cGRhdGVkQXRfZGVzY1wiO1xuICAgICAgY29uc3Qgc29ydEZpZWxkID0gcmVzb2x2ZWRPcmRlci5zdGFydHNXaXRoKFwidXBkYXRlZEF0XCIpXG4gICAgICAgID8gXCJ1cGRhdGVkQXRcIlxuICAgICAgICA6IFwiY3JlYXRlZEF0XCI7XG4gICAgICBjb25zdCBzb3J0RGlyID0gcmVzb2x2ZWRPcmRlci5lbmRzV2l0aChcIl9kZXNjXCIpID8gLTEgOiAxO1xuICAgICAgZmlsdGVyZWQuc29ydCgoYSwgYikgPT4gc29ydERpciAqIChhW3NvcnRGaWVsZF0gLSBiW3NvcnRGaWVsZF0pKTtcbiAgICAgIHJldHVybiBwYWdpbmF0ZSh7IGl0ZW1zOiBmaWx0ZXJlZCwgY3Vyc29yLCBsaW1pdCB9KTtcbiAgICB9LFxuXG4gICAgXCJzZXNzaW9uLmxpc3RCeVNhbmRib3hcIjogYXN5bmMgKHtcbiAgICAgIHNhbmRib3hJZCxcbiAgICAgIHRhZ3MsXG4gICAgICBvcmRlcixcbiAgICAgIGN1cnNvcixcbiAgICAgIGxpbWl0LFxuICAgIH0pID0+IHtcbiAgICAgIGNvbnN0IGFsbFNlc3Npb25zID0gYXdhaXQgcmVhZEFsbEZyb21EaXI8U2Vzc2lvbj4oc2Vzc2lvbkRpcik7XG4gICAgICBsZXQgZmlsdGVyZWQgPSBhbGxTZXNzaW9ucy5maWx0ZXIoKHMpID0+IHMuc2FuZGJveElkID09PSBzYW5kYm94SWQpO1xuICAgICAgaWYgKHRhZ3MgJiYgT2JqZWN0LmtleXModGFncykubGVuZ3RoID4gMCkge1xuICAgICAgICBmaWx0ZXJlZCA9IGZpbHRlcmVkLmZpbHRlcigocykgPT4ge1xuICAgICAgICAgIGNvbnN0IHNlc3Npb25UYWdzID0gcy50YWdzID8/IHt9O1xuICAgICAgICAgIHJldHVybiBPYmplY3QuZW50cmllcyh0YWdzKS5ldmVyeSgoW2tleSwgdmFsdWVdKSA9PlxuICAgICAgICAgICAgZXF1YWwoc2Vzc2lvblRhZ3Nba2V5XSwgdmFsdWUpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCByZXNvbHZlZE9yZGVyID0gb3JkZXIgPz8gXCJ1cGRhdGVkQXRfZGVzY1wiO1xuICAgICAgY29uc3Qgc29ydEZpZWxkID0gcmVzb2x2ZWRPcmRlci5zdGFydHNXaXRoKFwidXBkYXRlZEF0XCIpXG4gICAgICAgID8gXCJ1cGRhdGVkQXRcIlxuICAgICAgICA6IFwiY3JlYXRlZEF0XCI7XG4gICAgICBjb25zdCBzb3J0RGlyID0gcmVzb2x2ZWRPcmRlci5lbmRzV2l0aChcIl9kZXNjXCIpID8gLTEgOiAxO1xuICAgICAgZmlsdGVyZWQuc29ydCgoYSwgYikgPT4gc29ydERpciAqIChhW3NvcnRGaWVsZF0gLSBiW3NvcnRGaWVsZF0pKTtcbiAgICAgIHJldHVybiBwYWdpbmF0ZSh7IGl0ZW1zOiBmaWx0ZXJlZCwgY3Vyc29yLCBsaW1pdCB9KTtcbiAgICB9LFxuXG4gICAgXCJzZXNzaW9uLnRhZy5zZXRcIjogYXN5bmMgKHsgc2Vzc2lvbklkLCB0YWdzIH0pID0+IHtcbiAgICAgIGNvbnN0IHNlc3Npb25QYXRoID0gam9pbihzZXNzaW9uRGlyLCBgJHtzZXNzaW9uSWR9Lmpzb25gKTtcbiAgICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgcmVhZEpzb248U2Vzc2lvbj4oc2Vzc2lvblBhdGgpO1xuICAgICAgaWYgKCFleGlzdGluZykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFNlc3Npb24gJHtzZXNzaW9uSWR9IG5vdCBmb3VuZGApO1xuICAgICAgfVxuICAgICAgY29uc3QgbWVyZ2VkVGFncyA9IHsgLi4uZXhpc3RpbmcudGFncywgLi4udGFncyB9O1xuICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IHVwZGF0ZWRTZXNzaW9uOiBTZXNzaW9uID0ge1xuICAgICAgICAuLi5leGlzdGluZyxcbiAgICAgICAgdGFnczogbWVyZ2VkVGFncyxcbiAgICAgICAgdXBkYXRlZEF0OiBub3csXG4gICAgICB9O1xuICAgICAgYXdhaXQgd3JpdGVKc29uRmlsZShzZXNzaW9uUGF0aCwgdXBkYXRlZFNlc3Npb24pO1xuICAgICAgcmV0dXJuIHVwZGF0ZWRTZXNzaW9uO1xuICAgIH0sXG5cbiAgICBcIm1lc3NhZ2UuZ2V0XCI6IGFzeW5jICh7IGlkIH0pID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCByZWFkSnNvbjxNZXNzYWdlPihqb2luKG1lc3NhZ2VEaXIsIGAke2lkfS5qc29uYCkpO1xuICAgIH0sXG5cbiAgICBcIm1lc3NhZ2Uuc2V0XCI6IGFzeW5jIChtZXNzYWdlKSA9PiB7XG4gICAgICBhd2FpdCB3cml0ZUpzb25GaWxlKGpvaW4obWVzc2FnZURpciwgYCR7bWVzc2FnZS5pZH0uanNvbmApLCBtZXNzYWdlKTtcbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH0sXG5cbiAgICBcIm1lc3NhZ2UubGlzdFwiOiBhc3luYyAoeyBzZXNzaW9uSWQsIGN1cnNvciwgbGltaXQgfSkgPT4ge1xuICAgICAgY29uc3QgYWxsTWVzc2FnZXMgPSBhd2FpdCByZWFkQWxsRnJvbURpcjxNZXNzYWdlPihtZXNzYWdlRGlyKTtcbiAgICAgIGNvbnN0IGZpbHRlcmVkID0gYWxsTWVzc2FnZXNcbiAgICAgICAgLmZpbHRlcigobSkgPT4gbS5zZXNzaW9uSWQgPT09IHNlc3Npb25JZClcbiAgICAgICAgLnNvcnQoKGEsIGIpID0+IGEuY3JlYXRlZEF0IC0gYi5jcmVhdGVkQXQpO1xuICAgICAgcmV0dXJuIHBhZ2luYXRlKHsgaXRlbXM6IGZpbHRlcmVkLCBjdXJzb3IsIGxpbWl0IH0pO1xuICAgIH0sXG5cbiAgICBcInBhcnQubGlzdEJ5TWVzc2FnZVwiOiBhc3luYyAoeyBtZXNzYWdlSWQsIGN1cnNvciwgbGltaXQgfSkgPT4ge1xuICAgICAgY29uc3QgYWxsUGFydHMgPSBhd2FpdCByZWFkQWxsRnJvbURpcjxQYXJ0PihwYXJ0RGlyKTtcbiAgICAgIGNvbnN0IGZpbHRlcmVkID0gYWxsUGFydHNcbiAgICAgICAgLmZpbHRlcigocCkgPT4gcC5tZXNzYWdlSWQgPT09IG1lc3NhZ2VJZClcbiAgICAgICAgLnNvcnQoKGEsIGIpID0+IGEuaW5kZXggLSBiLmluZGV4KTtcbiAgICAgIHJldHVybiBwYWdpbmF0ZSh7IGl0ZW1zOiBmaWx0ZXJlZCwgY3Vyc29yLCBsaW1pdCB9KTtcbiAgICB9LFxuXG4gICAgXCJwYXJ0Lmxpc3RCeVNlc3Npb25cIjogYXN5bmMgKHsgc2Vzc2lvbklkLCBjdXJzb3IsIGxpbWl0IH0pID0+IHtcbiAgICAgIGNvbnN0IGFsbFBhcnRzID0gYXdhaXQgcmVhZEFsbEZyb21EaXI8UGFydD4ocGFydERpcik7XG4gICAgICBjb25zdCBmaWx0ZXJlZCA9IGFsbFBhcnRzXG4gICAgICAgIC5maWx0ZXIoKHApID0+IHAuc2Vzc2lvbklkID09PSBzZXNzaW9uSWQpXG4gICAgICAgIC5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgICAgaWYgKGEubWVzc2FnZUlkICE9PSBiLm1lc3NhZ2VJZCkge1xuICAgICAgICAgICAgcmV0dXJuIGEubWVzc2FnZUlkLmxvY2FsZUNvbXBhcmUoYi5tZXNzYWdlSWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gYS5pbmRleCAtIGIuaW5kZXg7XG4gICAgICAgIH0pO1xuICAgICAgcmV0dXJuIHBhZ2luYXRlKHsgaXRlbXM6IGZpbHRlcmVkLCBjdXJzb3IsIGxpbWl0IH0pO1xuICAgIH0sXG5cbiAgICBcInBhcnQuc2V0XCI6IGFzeW5jIChwYXJ0KSA9PiB7XG4gICAgICBhd2FpdCB3cml0ZUpzb25GaWxlKGpvaW4ocGFydERpciwgYCR7cGFydC5pZH0uanNvbmApLCBwYXJ0KTtcbiAgICAgIHJldHVybiBwYXJ0O1xuICAgIH0sXG5cbiAgICBcInBhcnQuZGVsZXRlXCI6IGFzeW5jICh7IGlkIH0pID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHVubGluayhqb2luKHBhcnREaXIsIGAke2lkfS5qc29uYCkpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIElnbm9yZSBpZiBmaWxlIGRvZXNuJ3QgZXhpc3RcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgXCJzYW5kYm94LmdldFwiOiBhc3luYyAoeyBrZXkgfSkgPT4ge1xuICAgICAgY29uc3Qgc2FmZU5hbWUgPSBCdWZmZXIuZnJvbShrZXkpLnRvU3RyaW5nKFwiYmFzZTY0dXJsXCIpO1xuICAgICAgY29uc3Qgc2FuZGJveFBhdGggPSBqb2luKHNhbmRib3hEaXIsIGAke3NhZmVOYW1lfS5qc29uYCk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVhZEpzb248U2FuZGJveFJlY29yZD4oc2FuZGJveFBhdGgpO1xuICAgICAgaWYgKCFkYXRhKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfSxcblxuICAgIFwic2FuZGJveC5zZXRcIjogYXN5bmMgKHJlY29yZCkgPT4ge1xuICAgICAgY29uc3Qgc2FmZU5hbWUgPSBCdWZmZXIuZnJvbShyZWNvcmQuaWQpLnRvU3RyaW5nKFwiYmFzZTY0dXJsXCIpO1xuICAgICAgY29uc3Qgc2FuZGJveFBhdGggPSBqb2luKHNhbmRib3hEaXIsIGAke3NhZmVOYW1lfS5qc29uYCk7XG4gICAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHJlYWRKc29uPFNhbmRib3hSZWNvcmQ+KHNhbmRib3hQYXRoKTtcbiAgICAgIGNvbnN0IG5ld1JlY29yZDogU2FuZGJveFJlY29yZCA9IHtcbiAgICAgICAgLi4ucmVjb3JkLFxuICAgICAgICB0YWdzOiByZWNvcmQudGFncyA/PyBleGlzdGluZz8udGFncyA/PyBudWxsLFxuICAgICAgfTtcbiAgICAgIGF3YWl0IHdyaXRlSnNvbkZpbGUoc2FuZGJveFBhdGgsIG5ld1JlY29yZCk7XG4gICAgfSxcblxuICAgIFwic2FuZGJveC5saXN0XCI6IGFzeW5jICh7IHRhZ3MsIG9yZGVyLCBjdXJzb3IsIGxpbWl0IH0pID0+IHtcbiAgICAgIGNvbnN0IGFsbFNhbmRib3hlcyA9IGF3YWl0IHJlYWRBbGxGcm9tRGlyPFNhbmRib3hSZWNvcmQ+KHNhbmRib3hEaXIpO1xuICAgICAgbGV0IGZpbHRlcmVkID0gYWxsU2FuZGJveGVzO1xuICAgICAgaWYgKHRhZ3MgJiYgT2JqZWN0LmtleXModGFncykubGVuZ3RoID4gMCkge1xuICAgICAgICBmaWx0ZXJlZCA9IGZpbHRlcmVkLmZpbHRlcigocykgPT4ge1xuICAgICAgICAgIGNvbnN0IHNhbmRib3hUYWdzID0gcy50YWdzID8/IHt9O1xuICAgICAgICAgIHJldHVybiBPYmplY3QuZW50cmllcyh0YWdzKS5ldmVyeSgoW2tleSwgdmFsdWVdKSA9PlxuICAgICAgICAgICAgZXF1YWwoc2FuZGJveFRhZ3Nba2V5XSwgdmFsdWUpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBzb3J0RmllbGQgPSBvcmRlcj8uc3RhcnRzV2l0aChcImxhc3RBY3Rpdml0eUF0XCIpXG4gICAgICAgID8gXCJsYXN0QWN0aXZpdHlBdFwiXG4gICAgICAgIDogXCJjcmVhdGVkQXRcIjtcbiAgICAgIGNvbnN0IHNvcnREaXIgPSBvcmRlcj8uZW5kc1dpdGgoXCJfZGVzY1wiKSA/IC0xIDogMTtcbiAgICAgIGZpbHRlcmVkLnNvcnQoXG4gICAgICAgIChhLCBiKSA9PiBzb3J0RGlyICogKChhW3NvcnRGaWVsZF0gPz8gMCkgLSAoYltzb3J0RmllbGRdID8/IDApKVxuICAgICAgKTtcbiAgICAgIHJldHVybiBwYWdpbmF0ZSh7IGl0ZW1zOiBmaWx0ZXJlZCwgY3Vyc29yLCBsaW1pdCB9KTtcbiAgICB9LFxuXG4gICAgXCJzYW5kYm94LnRhZy5zZXRcIjogYXN5bmMgKHsgc2FuZGJveElkLCB0YWdzIH0pID0+IHtcbiAgICAgIGNvbnN0IHNhZmVOYW1lID0gQnVmZmVyLmZyb20oc2FuZGJveElkKS50b1N0cmluZyhcImJhc2U2NHVybFwiKTtcbiAgICAgIGNvbnN0IHNhbmRib3hQYXRoID0gam9pbihzYW5kYm94RGlyLCBgJHtzYWZlTmFtZX0uanNvbmApO1xuICAgICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCByZWFkSnNvbjxTYW5kYm94UmVjb3JkPihzYW5kYm94UGF0aCk7XG4gICAgICBpZiAoIWV4aXN0aW5nKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgU2FuZGJveCAke3NhbmRib3hJZH0gbm90IGZvdW5kYCk7XG4gICAgICB9XG4gICAgICBjb25zdCBtZXJnZWRUYWdzID0geyAuLi5leGlzdGluZy50YWdzLCAuLi50YWdzIH07XG4gICAgICBjb25zdCB1cGRhdGVkU2FuZGJveDogU2FuZGJveFJlY29yZCA9IHtcbiAgICAgICAgLi4uZXhpc3RpbmcsXG4gICAgICAgIHRhZ3M6IG1lcmdlZFRhZ3MsXG4gICAgICB9O1xuICAgICAgYXdhaXQgd3JpdGVKc29uRmlsZShzYW5kYm94UGF0aCwgdXBkYXRlZFNhbmRib3gpO1xuICAgICAgcmV0dXJuIHVwZGF0ZWRTYW5kYm94O1xuICAgIH0sXG5cbiAgICBcInNhbmRib3guZ2V0QnlTZXNzaW9uXCI6IGFzeW5jICh7IHNlc3Npb25JZCB9KSA9PiB7XG4gICAgICBjb25zdCBhbGxTYW5kYm94ZXMgPSBhd2FpdCByZWFkQWxsRnJvbURpcjxTYW5kYm94UmVjb3JkPihzYW5kYm94RGlyKTtcbiAgICAgIGNvbnN0IG1hdGNoaW5nID0gYWxsU2FuZGJveGVzLmZpbHRlcigocykgPT5cbiAgICAgICAgcy5pZC5zdGFydHNXaXRoKGAke3Nlc3Npb25JZH0tYClcbiAgICAgICk7XG4gICAgICBpZiAobWF0Y2hpbmcubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgbWF0Y2hpbmcuc29ydChcbiAgICAgICAgKGEsIGIpID0+IChiLmxhc3RBY3Rpdml0eUF0ID8/IDApIC0gKGEubGFzdEFjdGl2aXR5QXQgPz8gMClcbiAgICAgICk7XG4gICAgICByZXR1cm4gbWF0Y2hpbmdbMF07XG4gICAgfSxcblxuICAgIFwiY29tbWFuZC5nZXRcIjogYXN5bmMgKHsgaWQgfSkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlYWRKc29uPENvbW1hbmQ+KGpvaW4oY29tbWFuZERpciwgYCR7aWR9Lmpzb25gKSk7XG4gICAgfSxcblxuICAgIFwiY29tbWFuZC5zZXRcIjogYXN5bmMgKGNvbW1hbmQpID0+IHtcbiAgICAgIGF3YWl0IHdyaXRlSnNvbkZpbGUoam9pbihjb21tYW5kRGlyLCBgJHtjb21tYW5kLmlkfS5qc29uYCksIGNvbW1hbmQpO1xuICAgICAgcmV0dXJuIGNvbW1hbmQ7XG4gICAgfSxcblxuICAgIFwic2V0dXAuZ2V0XCI6IGFzeW5jICh7IGtleSB9KSA9PiB7XG4gICAgICBjb25zdCBzYWZlTmFtZSA9IEJ1ZmZlci5mcm9tKGtleSkudG9TdHJpbmcoXCJiYXNlNjR1cmxcIik7XG4gICAgICByZXR1cm4gYXdhaXQgcmVhZEpzb248U2V0dXBTbmFwc2hvdD4oam9pbihzZXR1cERpciwgYCR7c2FmZU5hbWV9Lmpzb25gKSk7XG4gICAgfSxcblxuICAgIFwic2V0dXAuc2V0XCI6IGFzeW5jIChzbmFwc2hvdCkgPT4ge1xuICAgICAgY29uc3Qgc2FmZU5hbWUgPSBCdWZmZXIuZnJvbShzbmFwc2hvdC5rZXkpLnRvU3RyaW5nKFwiYmFzZTY0dXJsXCIpO1xuICAgICAgYXdhaXQgd3JpdGVKc29uRmlsZShqb2luKHNldHVwRGlyLCBgJHtzYWZlTmFtZX0uanNvbmApLCBzbmFwc2hvdCk7XG4gICAgfSxcblxuICAgIFwic2V0dXAuYWNxdWlyZUxvY2tcIjogYXN5bmMgKHsga2V5LCBsb2NrSWQsIGxvY2tUaW1lb3V0TXMgfSkgPT4ge1xuICAgICAgY29uc3Qgc2FmZU5hbWUgPSBCdWZmZXIuZnJvbShrZXkpLnRvU3RyaW5nKFwiYmFzZTY0dXJsXCIpO1xuICAgICAgY29uc3QgZmlsZVBhdGggPSBqb2luKHNldHVwRGlyLCBgJHtzYWZlTmFtZX0uanNvbmApO1xuICAgICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCByZWFkSnNvbjxTZXR1cFNuYXBzaG90PihmaWxlUGF0aCk7XG4gICAgICBpZiAoXG4gICAgICAgIGV4aXN0aW5nPy5hY3F1aXJpbmdMb2NrSWQgJiZcbiAgICAgICAgZXhpc3RpbmcuYWNxdWlyaW5nTG9ja0F0ICYmXG4gICAgICAgIERhdGUubm93KCkgLSBleGlzdGluZy5hY3F1aXJpbmdMb2NrQXQgPCBsb2NrVGltZW91dE1zXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIG51bGw7IC8vIGFjdGl2ZSBsb2NrIGhlbGQgYnkgc29tZW9uZSBlbHNlXG4gICAgICB9XG4gICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgY29uc3Qgc25hcHNob3Q6IFNldHVwU25hcHNob3QgPSB7XG4gICAgICAgIGtleSxcbiAgICAgICAgc25hcHNob3RJZDogZXhpc3Rpbmc/LnNuYXBzaG90SWQgPz8gbnVsbCxcbiAgICAgICAgY3JlYXRlZEF0OiBleGlzdGluZz8uY3JlYXRlZEF0ID8/IG5vdyxcbiAgICAgICAgbGFzdFVzZWRBdDogZXhpc3Rpbmc/Lmxhc3RVc2VkQXQgPz8gbnVsbCxcbiAgICAgICAgYWNxdWlyaW5nTG9ja0lkOiBsb2NrSWQsXG4gICAgICAgIGFjcXVpcmluZ0xvY2tBdDogbm93LFxuICAgICAgfTtcbiAgICAgIGF3YWl0IHdyaXRlSnNvbkZpbGUoZmlsZVBhdGgsIHNuYXBzaG90KTtcbiAgICAgIHJldHVybiBzbmFwc2hvdDtcbiAgICB9LFxuXG4gICAgXCJzYW5kYm94LmFjcXVpcmVMb2NrXCI6IGFzeW5jICh7IHJlY29yZCwgbG9ja1RpbWVvdXRNcyB9KSA9PiB7XG4gICAgICBjb25zdCBzYWZlTmFtZSA9IEJ1ZmZlci5mcm9tKHJlY29yZC5pZCkudG9TdHJpbmcoXCJiYXNlNjR1cmxcIik7XG4gICAgICBjb25zdCBmaWxlUGF0aCA9IGpvaW4oc2FuZGJveERpciwgYCR7c2FmZU5hbWV9Lmpzb25gKTtcbiAgICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgcmVhZEpzb248U2FuZGJveFJlY29yZD4oZmlsZVBhdGgpO1xuICAgICAgaWYgKFxuICAgICAgICBleGlzdGluZz8uYWNxdWlyaW5nTG9ja0lkICYmXG4gICAgICAgIGV4aXN0aW5nLmFjcXVpcmluZ0xvY2tBdCAmJlxuICAgICAgICBEYXRlLm5vdygpIC0gZXhpc3RpbmcuYWNxdWlyaW5nTG9ja0F0IDwgbG9ja1RpbWVvdXRNc1xuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBudWxsOyAvLyBhY3RpdmUgbG9jayBoZWxkIGJ5IHNvbWVvbmUgZWxzZVxuICAgICAgfVxuICAgICAgY29uc3QgbmV3UmVjb3JkOiBTYW5kYm94UmVjb3JkID0ge1xuICAgICAgICAuLi5yZWNvcmQsXG4gICAgICAgIHRhZ3M6IHJlY29yZC50YWdzID8/IGV4aXN0aW5nPy50YWdzID8/IG51bGwsXG4gICAgICB9O1xuICAgICAgYXdhaXQgd3JpdGVKc29uRmlsZShmaWxlUGF0aCwgbmV3UmVjb3JkKTtcbiAgICAgIHJldHVybiBuZXdSZWNvcmQ7XG4gICAgfSxcblxuICAgIFwiY29tbWFuZC5saXN0XCI6IGFzeW5jICh7IHNlc3Npb25JZCwgaW5jbHVkZUZpbmlzaGVkLCBjdXJzb3IsIGxpbWl0IH0pID0+IHtcbiAgICAgIGNvbnN0IGFsbENvbW1hbmRzID0gYXdhaXQgcmVhZEFsbEZyb21EaXI8Q29tbWFuZD4oY29tbWFuZERpcik7XG4gICAgICBsZXQgZmlsdGVyZWQgPSBhbGxDb21tYW5kcy5maWx0ZXIoKGMpID0+IGMuc2Vzc2lvbklkID09PSBzZXNzaW9uSWQpO1xuICAgICAgaWYgKCFpbmNsdWRlRmluaXNoZWQpIHtcbiAgICAgICAgZmlsdGVyZWQgPSBmaWx0ZXJlZC5maWx0ZXIoKGMpID0+IGMuc3RhdHVzID09PSBcInJ1bm5pbmdcIik7XG4gICAgICB9XG4gICAgICBmaWx0ZXJlZC5zb3J0KChhLCBiKSA9PiBhLnN0YXJ0ZWRBdCAtIGIuc3RhcnRlZEF0KTtcbiAgICAgIHJldHVybiBwYWdpbmF0ZSh7IGl0ZW1zOiBmaWx0ZXJlZCwgY3Vyc29yLCBsaW1pdCB9KTtcbiAgICB9LFxuICB9O1xufVxuIiwgImltcG9ydCB0eXBlIHsgTGlzdFJlc3VsdCB9IGZyb20gXCIuLi9zdG9yYWdlXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBwYWdpbmF0ZTxUIGV4dGVuZHMgeyBpZDogc3RyaW5nIH0+KG9wdHM6IHtcbiAgaXRlbXM6IFRbXTtcbiAgY3Vyc29yPzogc3RyaW5nO1xuICBsaW1pdD86IG51bWJlcjtcbn0pOiBMaXN0UmVzdWx0PFQ+IHtcbiAgY29uc3QgeyBpdGVtcywgY3Vyc29yLCBsaW1pdCB9ID0gb3B0cztcbiAgY29uc3Qgc3RhcnRJbmRleCA9IGN1cnNvciA/IGl0ZW1zLmZpbmRJbmRleCgobSkgPT4gbS5pZCA9PT0gY3Vyc29yKSArIDEgOiAwO1xuICBjb25zdCBzbGljZWQgPVxuICAgIGxpbWl0ICE9PSB1bmRlZmluZWRcbiAgICAgID8gaXRlbXMuc2xpY2Uoc3RhcnRJbmRleCwgc3RhcnRJbmRleCArIGxpbWl0KVxuICAgICAgOiBpdGVtcy5zbGljZShzdGFydEluZGV4KTtcbiAgY29uc3QgbmV4dEN1cnNvciA9XG4gICAgbGltaXQgIT09IHVuZGVmaW5lZCAmJiBzdGFydEluZGV4ICsgbGltaXQgPCBpdGVtcy5sZW5ndGhcbiAgICAgID8gKHNsaWNlZC5hdCgtMSk/LmlkID8/IG51bGwpXG4gICAgICA6IG51bGw7XG4g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
|