sliftutils 1.7.129 → 1.7.130

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 (28) hide show
  1. package/misc/dist/ownIPs.ts.cache +30 -4
  2. package/misc/dist/strings.ts.cache +2 -2
  3. package/misc/https/dist/certs.ts.cache +2 -2
  4. package/misc/https/dist/persistentLocalStorage.ts.cache +2 -2
  5. package/misc/ownIPs.ts +29 -1
  6. package/package.json +1 -1
  7. package/security/authorizedKeys/daemon/dist/paths.ts.cache +3 -6
  8. package/security/authorizedKeys/daemon/dist/revocation.ts.cache +0 -0
  9. package/security/authorizedKeys/daemon/dist/state.ts.cache +5 -3
  10. package/security/authorizedKeys/daemon/paths.ts +0 -3
  11. package/security/authorizedKeys/daemon/revocation.ts +0 -0
  12. package/security/authorizedKeys/daemon/state.ts +4 -8
  13. package/security/authorizedKeys/dist/keysRepo.ts.cache +111 -0
  14. package/security/authorizedKeys/dist/secureSSH.ts.cache +147 -71
  15. package/security/authorizedKeys/dist/unrevoke.ts.cache +70 -51
  16. package/security/authorizedKeys/keysRepo.ts +111 -0
  17. package/security/authorizedKeys/secureSSH.ts +28 -38
  18. package/security/authorizedKeys/unrevoke.ts +9 -36
  19. package/security/machines/addMachine.ts +4 -3
  20. package/security/machines/dist/identity.ts.cache +2 -2
  21. package/security/machines/dist/machines.ts.cache +36 -94
  22. package/security/machines/machines.ts +39 -90
  23. package/security/machines/trustServer.ts +5 -3
  24. package/security/notifications/dist/remoteWebhook.ts.cache +78 -0
  25. package/security/notifications/dist/setupNotify.ts.cache +39 -0
  26. package/security/signedFiles/dist/signFiles.ts.cache +8 -10
  27. package/security/signedFiles/signFiles.ts +6 -10
  28. package/security/machines/trustState.ts +0 -53
@@ -9,7 +9,8 @@ import { signRepo } from "../signedFiles/signFiles";
9
9
  import { readRepoKeys } from "./authorizedKeys";
10
10
  import { expandHome } from "../helpers/paths";
11
11
  import { spawnPromise } from "../helpers/spawn";
12
- import { machineState } from "../machines/machines";
12
+ import { getMachines, setMachines } from "../machines/machines";
13
+ import { resolveKeysRepo } from "./keysRepo";
13
14
 
14
15
  const UNREVOKES_DIR = "unrevoked";
15
16
  const REVOCATIONS_DIR = "revocations";
@@ -18,8 +19,8 @@ const COMMIT_MESSAGE = "unrevoke keys";
18
19
  const USAGE = `Usage: yarn unrevoke [keys-repo] [${GIT_KEYWORD}]
19
20
 
20
21
  Run this in a keys repo, or name one. It reads that repo's revoke repo and writes one unrevoke file
21
- naming every revocation in it, so the keys are accepted again once each machine's hour long wait
22
- passes. It signs the result, and with ${GIT_KEYWORD} it commits and pushes it too.
22
+ naming every revocation in it, so the keys are accepted again as each machine picks it up. It signs
23
+ the result, and with ${GIT_KEYWORD} it commits and pushes it too.
23
24
 
24
25
  Keys that were revoked should normally be deleted from the repo instead. Unrevoking only matters
25
26
  for a key you still want.`;
@@ -170,7 +171,7 @@ async function allowAddressesForMachines(config: { repoPath: string; revocations
170
171
  let added = new Map<string, string[]>();
171
172
  // Read the whole list, change what these revocations are about, write it back. Setting is by
172
173
  // the whole set, so writing one machine at a time would delete every other machine.
173
- let machines = await machineState({ repoPath });
174
+ let machines = await getMachines(repoPath);
174
175
  for (let revocation of revocations) {
175
176
  let machineId = revocation.machineId;
176
177
  let ip = revocationIP(revocation);
@@ -191,37 +192,11 @@ async function allowAddressesForMachines(config: { repoPath: string; revocations
191
192
  added.set(machineId, [...(added.get(machineId) || []), ip]);
192
193
  }
193
194
  if (added.size) {
194
- await machineState({ repoPath, machines });
195
+ await setMachines({ repoPath, machines });
195
196
  }
196
197
  return added;
197
198
  }
198
199
 
199
- /** The repo named, or the one we are standing in. Checked the same way securessh checks it: a git
200
- repo that actually holds keys and has an origin to clone from. */
201
- async function resolveKeysRepo(named: string | undefined) {
202
- let cwd = named && expandHome(named) || undefined;
203
- // spawnPromise rather than runPromise, because these two are read for their value. runPromise
204
- // returns stdout and stderr joined, so one git warning ends up glued to the front of the path.
205
- let topLevel = await spawnPromise({ command: "git", args: ["rev-parse", "--show-toplevel"], cwd });
206
- let repoPath = topLevel.stdout.trim();
207
- if (topLevel.status !== 0 || !repoPath) {
208
- throw new Error(
209
- `Expected ${named || "the current directory"} to be inside a git repo, it is not.\n`
210
- + `${(topLevel.stdout + topLevel.stderr).trim()}\n${USAGE}`
211
- );
212
- }
213
- try {
214
- await readRepoKeys(repoPath);
215
- } catch (e) {
216
- throw new Error(`Expected ${repoPath} to be a keys repo, it holds no keys.\n${e}\n${USAGE}`);
217
- }
218
- let origin = await spawnPromise({ command: "git", args: ["remote", "get-url", "origin"], cwd: repoPath });
219
- let originURL = origin.stdout.trim();
220
- if (origin.status !== 0 || !originURL) {
221
- throw new Error(`Expected ${repoPath} to have an origin remote, it has none.\n${USAGE}`);
222
- }
223
- return { repoPath, originURL };
224
- }
225
200
 
226
201
  export async function main() {
227
202
  let argv = process.argv.slice(2);
@@ -230,7 +205,7 @@ export async function main() {
230
205
  if (positional.length > 1) {
231
206
  throw new Error(`Expected at most a keys repo, was ${positional.length} argument(s)\n${USAGE}`);
232
207
  }
233
- let { repoPath, originURL } = await resolveKeysRepo(positional[0]);
208
+ let { repoPath, sourceURL: originURL } = await resolveKeysRepo(positional[0]);
234
209
 
235
210
  let revocations = await readRemoteRevocations({ sourceURL: originURL });
236
211
  if (!revocations.length) {
@@ -322,14 +297,12 @@ export async function main() {
322
297
  await signRepo({ repoPath });
323
298
 
324
299
  if (!pushToGit) {
325
- console.log(`\nCommit and push it, and each machine will wait an hour after seeing it before`);
326
- console.log(`those keys work again:`);
300
+ console.log(`\nCommit and push it, and those keys work again as each machine picks it up:`);
327
301
  console.log(`\`\`\`\ngit add -A\ngit commit -m "${COMMIT_MESSAGE}"\ngit push\n\`\`\``);
328
302
  return;
329
303
  }
330
304
  await runPromise(`git add -A`, { cwd: repoPath });
331
305
  await runPromise(`git commit -m "${COMMIT_MESSAGE}"`, { cwd: repoPath });
332
306
  await runPromise(`git push`, { cwd: repoPath });
333
- console.log(`\nCommitted and pushed. Each machine waits an hour after seeing it before those`);
334
- console.log(`keys work again.`);
307
+ console.log(`\nCommitted and pushed. Those keys work again as each machine picks it up.`);
335
308
  }
@@ -2,7 +2,8 @@ import os from "os";
2
2
  import { getOwnIPs } from "../../misc/ownIPs";
3
3
  import { describeHost } from "../helpers/remoteSSH";
4
4
  import { createRemoteIdentity, Identity, localDomains, localIdentity, remoteIdentity } from "./identity";
5
- import { machineState, resolveKeysRepo } from "./machines";
5
+ import { resolveKeysRepo } from "../authorizedKeys/keysRepo";
6
+ import { getMachines, setMachines } from "./machines";
6
7
 
7
8
  const USAGE = `Usage: yarn addmachine <domain> [ip]
8
9
 
@@ -58,7 +59,7 @@ export async function main() {
58
59
 
59
60
  // The whole list is read and written back, because setting is by the set: writing this one
60
61
  // machine alone would remove every other machine from the repo.
61
- let machines = await machineState({ repoPath });
62
+ let machines = await getMachines(repoPath);
62
63
  let existing = machines.find(machine => machine.machineId === identity.machineId);
63
64
  let ips = [...(existing?.ips || [])];
64
65
  let added = addresses.filter(address => !ips.includes(address));
@@ -67,7 +68,7 @@ export async function main() {
67
68
  } else {
68
69
  machines.push({ machineId: identity.machineId, ips: [...added], addedAt: "" });
69
70
  }
70
- await machineState({ repoPath, machines });
71
+ await setMachines({ repoPath, machines });
71
72
 
72
73
  console.log(`\nTrusting machine ${identity.machineId}`);
73
74
  console.log(`Allowing IP ${[...ips, ...added].join(", ")}`);
@@ -1,4 +1,4 @@
1
- "use strict";
1
+ "use strict"; var console = (function shimConsole() { let baseConsole = globalThis.console; if (typeof window !== "undefined") return baseConsole; let name = __filename.replaceAll("\\", "/").split("/").pop(); let dirName = __dirname.replaceAll("\\", "/").split("/").pop(); let context = { __FILE__: __filename, __DIR__: __dirname, __NAME__: name, __DIRNAME__: dirName }; let newConsole = { ...baseConsole }; for (let shim of ["log", "info", "warn", "error"]) { newConsole[shim] = (...args) => { args.push(context); baseConsole[shim](...args); }; } newConsole.__context = context; return newConsole; })(); "use strict";
2
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule && mod.default) ? mod : { "default": mod };
4
4
  };
@@ -173,4 +173,4 @@ function verifyTrustPacket(packet) {
173
173
  }
174
174
  exports.verifyTrustPacket = verifyTrustPacket;
175
175
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWRlbnRpdHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpZGVudGl0eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsMkRBQTZCO0FBQzdCLDRDQUFvQjtBQUNwQixnREFBd0I7QUFDeEIsa0RBQTRJO0FBQzVJLG9EQUFtRTtBQUVuRSxpR0FBaUc7QUFDakcsK0ZBQStGO0FBQy9GLDhGQUE4RjtBQUM5RixtREFBbUQ7QUFDbkQsTUFBTSxlQUFlLEdBQUcsV0FBVyxDQUFDO0FBQ3BDLE1BQU0sZUFBZSxHQUFHLElBQUksMEJBQWtCLE9BQU8sQ0FBQztBQUN0RCxrR0FBa0c7QUFDbEcsaURBQWlEO0FBQ3BDLFFBQUEsZUFBZSxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBUzdDLFNBQVMsZ0JBQWdCLENBQUMsTUFBYztJQUNwQyxPQUFPLEdBQUcsZUFBZSxHQUFHLE1BQU0sR0FBRyxlQUFlLEVBQUUsQ0FBQztBQUMzRCxDQUFDO0FBRUQseUVBQXlFO0FBQ3pFLFNBQVMsZ0JBQWdCLENBQUMsUUFBZ0I7SUFDdEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUM7UUFDL0UsT0FBTyxFQUFFLENBQUM7SUFDZCxDQUFDO0lBQ0QsT0FBTyxRQUFRLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDM0UsQ0FBQztBQUVELFNBQVMsZ0JBQWdCLENBQUMsTUFBdUQ7SUFDN0UsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUM7SUFDaEMsT0FBTztRQUNILFNBQVMsRUFBRSxJQUFBLG9CQUFZLEVBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUM7UUFDOUMsTUFBTTtRQUNO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LENBQUMsT0FBTyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQzlELENBQUM7SUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ1QsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLHNDQUFzQyxDQUFDLEVBQUUsRUFBRSxDQUFDO0lBQ2hGLENBQUM7SUFDRCw2RkFBNkY7SUFDN0YsSUFBSSxDQUFDLElBQUEsbUNBQTJCLEVBQUMsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsY0FBYyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQ3BHLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxvREFBb0QsRUFBRSxDQUFDO0lBQzNGLENBQUM7SUFDRCxJQUFJLE1BQU0sR0FBRyxnQkFBTSxDQUFDLE1BQU0sQ0FDdEIsSUFBSSxFQUNKLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsU0FBUyxJQUFJLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUNyRCxTQUFTLEVBQ1QsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLFFBQVEsQ0FBQyxDQUM3QyxDQUFDO0lBQ0YsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ1YsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLGtDQUFrQyxFQUFFLENBQUM7SUFDekUsQ0FBQztJQUNELE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsQ0FBQztBQUN4QyxDQUFDO0FBNUJELDhDQTRCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBjcnlwdG8gZnJvbSBcImNyeXB0b1wiO1xuaW1wb3J0IGZzIGZyb20gXCJmcy9wcm9taXNlc1wiO1xuaW1wb3J0IG9zIGZyb20gXCJvc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IGdlbmVyYXRlVGVzdENBLCBnZXRNYWNoaW5lSWQsIGlkZW50aXR5U3RvcmFnZUtleSwgSWRlbnRpdHlTdG9yYWdlVHlwZSwgdmVyaWZ5TWFjaGluZUlkRm9yUHVibGljS2V5IH0gZnJvbSBcIi4uLy4uL21pc2MvaHR0cHMvY2VydHNcIjtcbmltcG9ydCB7IHJ1bk92ZXJTU0gsIHdyaXRlUmVtb3RlRmlsZSB9IGZyb20gXCIuLi9oZWxwZXJzL3JlbW90ZVNTSFwiO1xuXG4vLyBBIG1hY2hpbmUncyBpZGVudGl0eSBpcyB0aGUgQ0EgaXQgZ2VuZXJhdGVkIGZvciBpdHNlbGYsIGtlcHQgaW4gb25lIGZpbGUgaW4gdGhlIGhvbWUgZGlyZWN0b3J5XG4vLyBvZiB3aG9ldmVyIHJ1bnMgaXQuIFRoZSBuYW1lIGNhcnJpZXMgdGhlIGRvbWFpbiBpdCBiZWxvbmdzIHRvLCBzbyBhIG1hY2hpbmUgY2FuIGhvbGQgb25lIHBlclxuLy8gZG9tYWluLCBhbmQgdGhlIGlkIGl0c2VsZiBpcyBhIGhhc2ggb2YgdGhhdCBDQSdzIHB1YmxpYyBrZXkgLSB3aGljaCBpcyB3aHkgYSBtYWNoaW5lIGNhbm5vdFxuLy8gY2xhaW0gdG8gYmUgYW5vdGhlciBvbmUgd2l0aG91dCBob2xkaW5nIGl0cyBrZXkuXG5jb25zdCBJREVOVElUWV9QUkVGSVggPSBcImtleXN0b3JlX1wiO1xuY29uc3QgSURFTlRJVFlfU1VGRklYID0gYF8ke2lkZW50aXR5U3RvcmFnZUtleX0uanNvbmA7XG4vLyBIb3cgc3RhbGUgYSBzaWduZWQgcGFja2V0IG1heSBiZS4gTG9uZyBlbm91Z2ggZm9yIGNsb2NrIHNrZXcgYmV0d2VlbiB0d28gbWFjaGluZXMsIHNob3J0IGVub3VnaFxuLy8gdGhhdCBhIGNhcHR1cmVkIHBhY2tldCBpcyBub3Qgd29ydGggcmVwbGF5aW5nLlxuZXhwb3J0IGNvbnN0IFBBQ0tFVF9MSUZFVElNRSA9IDIgKiA2MCAqIDEwMDA7XG5cbmV4cG9ydCB0eXBlIElkZW50aXR5ID0ge1xuICAgIG1hY2hpbmVJZDogc3RyaW5nO1xuICAgIGRvbWFpbjogc3RyaW5nO1xuICAgIGZ1bGxEb21haW46IHN0cmluZztcbiAgICBmaWxlTmFtZTogc3RyaW5nO1xufTtcblxuZnVuY3Rpb24gaWRlbnRpdHlGaWxlTmFtZShkb21haW46IHN0cmluZykge1xuICAgIHJldHVybiBgJHtJREVOVElUWV9QUkVGSVh9JHtkb21haW59JHtJREVOVElUWV9TVUZGSVh9YDtcbn1cblxuLyoqIFRoZSBkb21haW4gb3V0IG9mIGFuIGlkZW50aXR5IGZpbGUncyBuYW1lLCBvciBcIlwiIGlmIGl0IGlzIG5vdCBvbmUuICovXG5mdW5jdGlvbiBkb21haW5PZkZpbGVOYW1lKGZpbGVOYW1lOiBzdHJpbmcpIHtcbiAgICBpZiAoIWZpbGVOYW1lLnN0YXJ0c1dpdGgoSURFTlRJVFlfUFJFRklYKSB8fCAhZmlsZU5hbWUuZW5kc1dpdGgoSURFTlRJVFlfU1VGRklYKSkge1xuICAgICAgICByZXR1cm4gXCJcIjtcbiAgICB9XG4gICAgcmV0dXJuIGZpbGVOYW1lLnNsaWNlKElERU5USVRZX1BSRUZJWC5sZW5ndGgsIC1JREVOVElUWV9TVUZGSVgubGVuZ3RoKTtcbn1cblxuZnVuY3Rpb24gZGVzY3JpYmVJZGVudGl0eShjb25maWc6IHsgZG9tYWluOiBzdHJpbmc7IHN0b3JlZDogSWRlbnRpdHlTdG9yYWdlVHlwZSB9KSB7XG4gICAgbGV0IHsgZG9tYWluLCBzdG9yZWQgfSA9IGNvbmZpZztcbiAgICByZXR1cm4ge1xuICAgICAgICBtYWNoaW5lSWQ6IGdldE1hY2hpbmVJZChzdG9yZWQuZG9tYWluLCBkb21haW4pLFxuICAgICAgICBkb21haW4sXG4gICAgICAgIGZ1bGxEb21haW46IHN0b3JlZC5kb21haW4sXG4gICAgICAgIGZpbGVOYW1lOiBpZGVudGl0eUZpbGVOYW1lKGRvbWFpbiksXG4gICAgfTtcbn1cblxuLyoqIEV2ZXJ5IGRvbWFpbiB0aGlzIG1hY2hpbmUgaG9sZHMgYW4gaWRlbnRpdHkgdW5kZXIuIEEgbWFjaGluZSBoYXMgb25lIGlkZW50aXR5IHBlciBkb21haW4sIGFuZFxuICAgIHRoZXkgYXJlIGRpZmZlcmVudCBtYWNoaW5lIGlkcywgc28gd2hpY2ggb25lIGlzIG1lYW50IGlzIGEgcmVhbCBxdWVzdGlvbiByYXRoZXIgdGhhbiBhIGRldGFpbC4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsb2NhbERvbWFpbnMoKSB7XG4gICAgbGV0IGRvbWFpbnM6IHN0cmluZ1tdID0gW107XG4gICAgZm9yIChsZXQgbmFtZSBvZiAoYXdhaXQgZnMucmVhZGRpcihvcy5ob21lZGlyKCkpLmNhdGNoKCgpID0+IFtdIGFzIHN0cmluZ1tdKSkuc29ydCgpKSB7XG4gICAgICAgIGxldCBkb21haW4gPSBkb21haW5PZkZpbGVOYW1lKG5hbWUpO1xuICAgICAgICBpZiAoZG9tYWluKSB7XG4gICAgICAgICAgICBkb21haW5zLnB1c2goZG9tYWluKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZG9tYWlucztcbn1cblxuLyoqIFRoaXMgbWFjaGluZSdzIGlkZW50aXR5IHVuZGVyIG9uZSBkb21haW4uIFVuZGVmaW5lZCB3aGVuIGl0IGhhcyBub25lIHVuZGVyIHRoYXQgb25lLlxuXG4gICAgVGhlIGRvbWFpbiBpcyByZXF1aXJlZCBldmVyeXdoZXJlIGl0IGFwcGVhcnMuIEEgbWFjaGluZSBoYXMgYSBkaWZmZXJlbnQgaWRlbnRpdHksIGFuZCBzbyBhXG4gICAgZGlmZmVyZW50IG1hY2hpbmUgaWQsIHVuZGVyIGV2ZXJ5IGRvbWFpbiBpdCBydW5zIHVuZGVyLCBzbyBcInRoaXMgbWFjaGluZVwiIG9uIGl0cyBvd24gZG9lcyBub3RcbiAgICBuYW1lIGFueXRoaW5nOiBhbnN3ZXJpbmcgdW5kZXIgdGhlIHdyb25nIG9uZSBtZWFucyBhbnN3ZXJpbmcgYXMgYSBtYWNoaW5lIHdlIGFyZSBub3QuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbG9jYWxJZGVudGl0eShkb21haW46IHN0cmluZyk6IFByb21pc2U8SWRlbnRpdHkgfCB1bmRlZmluZWQ+IHtcbiAgICBpZiAoIWRvbWFpbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGEgZG9tYWluLCB3YXMgJHtKU09OLnN0cmluZ2lmeShkb21haW4pfWApO1xuICAgIH1cbiAgICBsZXQgY29udGVudHMgPSBhd2FpdCBmcy5yZWFkRmlsZShwYXRoLmpvaW4ob3MuaG9tZWRpcigpLCBpZGVudGl0eUZpbGVOYW1lKGRvbWFpbikpLCBcInV0ZjhcIikuY2F0Y2goKCkgPT4gXCJcIik7XG4gICAgaWYgKCFjb250ZW50cykge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gZGVzY3JpYmVJZGVudGl0eSh7IGRvbWFpbiwgc3RvcmVkOiBKU09OLnBhcnNlKGNvbnRlbnRzKSB9KTtcbn1cblxuLyoqIFRoaXMgbWFjaGluZSdzIGlkZW50aXR5IGFuZCBpdHMga2V5cywgZm9yIHNpZ25pbmcuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbG9jYWxJZGVudGl0eUtleXMoZG9tYWluOiBzdHJpbmcpIHtcbiAgICBsZXQgaWRlbnRpdHkgPSBhd2FpdCBsb2NhbElkZW50aXR5KGRvbWFpbik7XG4gICAgaWYgKCFpZGVudGl0eSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgRXhwZWN0ZWQgYW4gaWRlbnRpdHkgZm9yICR7ZG9tYWlufSBhdCAke3BhdGguam9pbihvcy5ob21lZGlyKCksIGlkZW50aXR5RmlsZU5hbWUoZG9tYWluKSl9LGBcbiAgICAgICAgICAgICsgYCB0aGVyZSBpcyBub25lLlxcbmBcbiAgICAgICAgICAgICsgYFRoaXMgbWFjaGluZSBoYXM6ICR7KGF3YWl0IGxvY2FsRG9tYWlucygpKS5qb2luKFwiLCBcIikgfHwgXCJubyBpZGVudGl0aWVzIGF0IGFsbFwifWBcbiAgICAgICAgKTtcbiAgICB9XG4gICAgbGV0IHN0b3JlZDogSWRlbnRpdHlTdG9yYWdlVHlwZSA9IEpTT04ucGFyc2UoXG4gICAgICAgIGF3YWl0IGZzLnJlYWRGaWxlKHBhdGguam9pbihvcy5ob21lZGlyKCksIGlkZW50aXR5LmZpbGVOYW1lKSwgXCJ1dGY4XCIpXG4gICAgKTtcbiAgICByZXR1cm4geyBpZGVudGl0eSwgc3RvcmVkIH07XG59XG5cbi8qKiBUaGUgaWRlbnRpdHkgb2YgYW5vdGhlciBtYWNoaW5lIHVuZGVyIG9uZSBkb21haW4sIG92ZXIgc3NoLiBVbmRlZmluZWQgd2hlbiBpdCBoYXMgbm9uZSB1bmRlclxuICAgIHRoYXQgZG9tYWluLCB3aGF0ZXZlciBlbHNlIGl0IG1heSBoYXZlIHVuZGVyIG90aGVycy4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZW1vdGVJZGVudGl0eShob3N0OiBzdHJpbmcsIGRvbWFpbjogc3RyaW5nKTogUHJvbWlzZTxJZGVudGl0eSB8IHVuZGVmaW5lZD4ge1xuICAgIGlmICghZG9tYWluKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgYSBkb21haW4sIHdhcyAke0pTT04uc3RyaW5naWZ5KGRvbWFpbil9YCk7XG4gICAgfVxuICAgIGxldCBob21lID0gKGF3YWl0IHJ1bk92ZXJTU0goeyBob3N0LCBzY3JpcHQ6IGBlY2hvICRIT01FYCB9KSkuc3Rkb3V0LnRyaW0oKTtcbiAgICBpZiAoIWhvbWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAke2hvc3R9IHRvIHJlcG9ydCBhIGhvbWUgZGlyZWN0b3J5LCBpdCByZXBvcnRlZCBub3RoaW5nYCk7XG4gICAgfVxuICAgIGxldCBjb250ZW50cyA9IGF3YWl0IHJ1bk92ZXJTU0goe1xuICAgICAgICBob3N0LFxuICAgICAgICBzY3JpcHQ6IGBjYXQgJHtob21lfS8ke2lkZW50aXR5RmlsZU5hbWUoZG9tYWluKX0gMj4vZGV2L251bGwgfHwgdHJ1ZWAsXG4gICAgfSk7XG4gICAgaWYgKCFjb250ZW50cy5zdGRvdXQudHJpbSgpKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiBkZXNjcmliZUlkZW50aXR5KHsgZG9tYWluLCBzdG9yZWQ6IEpTT04ucGFyc2UoY29udGVudHMuc3Rkb3V0KSB9KTtcbn1cblxuLyoqIEdpdmVzIGEgbWFjaGluZSBhbiBpZGVudGl0eSBpdCBkb2VzIG5vdCBoYXZlIHlldCwgYnkgZ2VuZXJhdGluZyBvbmUgaGVyZSBhbmQgd3JpdGluZyBpdCB0aGVyZS5cblxuICAgIFRoZSBDQSBpcyBzZWxmIHNpZ25lZCBhbmQgbmV2ZXIgbGVhdmVzIHRoYXQgbWFjaGluZSBhZnRlcndhcmRzLCBzbyBnZW5lcmF0aW5nIGl0IGhlcmUgaXMgb25seSBhXG4gICAgY29udmVuaWVuY2U6IHdoYXQgbWF0dGVycyBpcyB0aGF0IHRoZSBwcml2YXRlIGtleSBlbmRzIHVwIGluIG9uZSBwbGFjZSBhbmQgdGhlIGlkIGlzIHRoZSBoYXNoXG4gICAgb2YgaXRzIHB1YmxpYyBoYWxmLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVJlbW90ZUlkZW50aXR5KGNvbmZpZzogeyBob3N0OiBzdHJpbmc7IGRvbWFpbjogc3RyaW5nIH0pIHtcbiAgICBsZXQgeyBob3N0LCBkb21haW4gfSA9IGNvbmZpZztcbiAgICBsZXQgZ2VuZXJhdGVkID0gZ2VuZXJhdGVUZXN0Q0EoZG9tYWluKTtcbiAgICBsZXQgc3RvcmVkOiBJZGVudGl0eVN0b3JhZ2VUeXBlID0ge1xuICAgICAgICBkb21haW46IGdlbmVyYXRlZC5kb21haW4sXG4gICAgICAgIGNlcnRCNjQ6IGdlbmVyYXRlZC5jZXJ0LnRvU3RyaW5nKFwiYmFzZTY0XCIpLFxuICAgICAgICBrZXlCNjQ6IGdlbmVyYXRlZC5rZXkudG9TdHJpbmcoXCJiYXNlNjRcIiksXG4gICAgfTtcbiAgICBsZXQgaG9tZSA9IChhd2FpdCBydW5PdmVyU1NIKHsgaG9zdCwgc2NyaXB0OiBgZWNobyAkSE9NRWAgfSkpLnN0ZG91dC50cmltKCk7XG4gICAgYXdhaXQgd3JpdGVSZW1vdGVGaWxlKHtcbiAgICAgICAgaG9zdCxcbiAgICAgICAgZmlsZVBhdGg6IGAke2hvbWV9LyR7aWRlbnRpdHlGaWxlTmFtZShkb21haW4pfWAsXG4gICAgICAgIGNvbnRlbnRzOiBKU09OLnN0cmluZ2lmeShzdG9yZWQpLFxuICAgICAgICBmaWxlTW9kZTogXCI2MDBcIixcbiAgICAgICAgLy8gVGhlIGhvbWUgZGlyZWN0b3J5IGlzIGFscmVhZHkgdGhlcmUsIHRoaXMgaXMgb25seSB3aGF0IGl0IGlzIGNyZWF0ZWQgd2l0aCBpZiBpdCBpcyBub3QuXG4gICAgICAgIGRpcmVjdG9yeU1vZGU6IFwiNzAwXCIsXG4gICAgfSk7XG4gICAgcmV0dXJuIGRlc2NyaWJlSWRlbnRpdHkoeyBkb21haW4sIHN0b3JlZCB9KTtcbn1cblxuLyoqIFRoZSByYXcgZWQyNTUxOSBwdWJsaWMga2V5IG91dCBvZiBhIGNlcnRpZmljYXRlLCB3aGljaCBpcyB3aGF0IHRoZSBtYWNoaW5lIGlkIGlzIGEgaGFzaCBvZi4gKi9cbmZ1bmN0aW9uIHB1YmxpY0tleUJ5dGVzKGNlcnRQRU06IHN0cmluZykge1xuICAgIGxldCBzcGtpID0gbmV3IGNyeXB0by5YNTA5Q2VydGlmaWNhdGUoY2VydFBFTSkucHVibGljS2V5LmV4cG9ydCh7IHR5cGU6IFwic3BraVwiLCBmb3JtYXQ6IFwiZGVyXCIgfSk7XG4gICAgLy8gQW4gZWQyNTUxOSBTUEtJIGlzIGEgZml4ZWQgMTIgYnl0ZSBoZWFkZXIgZm9sbG93ZWQgYnkgdGhlIDMyIGJ5dGUga2V5LlxuICAgIHJldHVybiBzcGtpLnN1YmFycmF5KHNwa2kubGVuZ3RoIC0gMzIpO1xufVxuXG5leHBvcnQgdHlwZSBUcnVzdFBhY2tldCA9IHtcbiAgICBtYWNoaW5lSWQ6IHN0cmluZztcbiAgICBjZXJ0QjY0OiBzdHJpbmc7XG4gICAgc2lnbmVkQXQ6IG51bWJlcjtcbiAgICBzaWduYXR1cmVCNjQ6IHN0cmluZztcbn07XG5cbi8qKiBQcm92ZXMgd2UgaG9sZCB0aGUgcHJpdmF0ZSBrZXkgYmVoaW5kIG91ciBtYWNoaW5lIGlkLCByaWdodCBub3cuIFRoZSBzaWduYXR1cmUgY292ZXJzIHRoZSBpZFxuICAgIGFuZCB0aGUgdGltZSwgc28gdGhlIHBhY2tldCBjYW5ub3QgYmUgcmVwbGF5ZWQgbGF0ZXIgb3IgcmV1c2VkIGZvciBhbm90aGVyIGlkLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNpZ25UcnVzdFBhY2tldChkb21haW46IHN0cmluZyk6IFByb21pc2U8VHJ1c3RQYWNrZXQ+IHtcbiAgICBsZXQgeyBpZGVudGl0eSwgc3RvcmVkIH0gPSBhd2FpdCBsb2NhbElkZW50aXR5S2V5cyhkb21haW4pO1xuICAgIGxldCBzaWduZWRBdCA9IERhdGUubm93KCk7XG4gICAgbGV0IHNpZ25hdHVyZSA9IGNyeXB0by5zaWduKFxuICAgICAgICBudWxsLFxuICAgICAgICBCdWZmZXIuZnJvbShgJHtpZGVudGl0eS5tYWNoaW5lSWR9ICR7c2lnbmVkQXR9YCksXG4gICAgICAgIGNyeXB0by5jcmVhdGVQcml2YXRlS2V5KEJ1ZmZlci5mcm9tKHN0b3JlZC5rZXlCNjQsIFwiYmFzZTY0XCIpLnRvU3RyaW5nKCkpXG4gICAgKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBtYWNoaW5lSWQ6IGlkZW50aXR5Lm1hY2hpbmVJZCxcbiAgICAgICAgY2VydEI2NDogc3RvcmVkLmNlcnRCNjQsXG4gICAgICAgIHNpZ25lZEF0LFxuICAgICAgICBzaWduYXR1cmVCNjQ6IHNpZ25hdHVyZS50b1N0cmluZyhcImJhc2U2NFwiKSxcbiAgICB9O1xufVxuXG4vKiogV2hldGhlciBhIHBhY2tldCByZWFsbHkgY2FtZSBmcm9tIHRoZSBtYWNoaW5lIGl0IG5hbWVzLiBTYXlzIHdoeSB3aGVuIGl0IGRpZCBub3QsIGJlY2F1c2VcbiAgICBcInRoaXMgaXMgbm90IHRoYXQgbWFjaGluZVwiIGFuZCBcInRoaXMgYXJyaXZlZCB0b28gbGF0ZVwiIGFyZSBkaWZmZXJlbnQgcHJvYmxlbXMuICovXG5leHBvcnQgZnVuY3Rpb24gdmVyaWZ5VHJ1c3RQYWNrZXQocGFja2V0OiBUcnVzdFBhY2tldCkge1xuICAgIGlmICghcGFja2V0IHx8ICFwYWNrZXQubWFjaGluZUlkIHx8ICFwYWNrZXQuY2VydEI2NCB8fCAhcGFja2V0LnNpZ25hdHVyZUI2NCkge1xuICAgICAgICByZXR1cm4geyB2YWxpZDogZmFsc2UsIHByb2JsZW06IFwidGhlIHBhY2tldCBpcyBtaXNzaW5nIGZpZWxkc1wiIH07XG4gICAgfVxuICAgIGlmIChNYXRoLmFicyhEYXRlLm5vdygpIC0gcGFja2V0LnNpZ25lZEF0KSA+IFBBQ0tFVF9MSUZFVElNRSkge1xuICAgICAgICByZXR1cm4geyB2YWxpZDogZmFsc2UsIHByb2JsZW06IGBpdCB3YXMgc2lnbmVkICR7TWF0aC5yb3VuZCgoRGF0ZS5ub3coKSAtIHBhY2tldC5zaWduZWRBdCkgLyAxMDAwKX1zIGFnb2AgfTtcbiAgICB9XG4gICAgbGV0IGNlcnRQRU0gPSBCdWZmZXIuZnJvbShwYWNrZXQuY2VydEI2NCwgXCJiYXNlNjRcIikudG9TdHJpbmcoKTtcbiAgICBsZXQgcHVibGljS2V5OiBjcnlwdG8uS2V5T2JqZWN0O1xuICAgIHRyeSB7XG4gICAgICAgIHB1YmxpY0tleSA9IG5ldyBjcnlwdG8uWDUwOUNlcnRpZmljYXRlKGNlcnRQRU0pLnB1YmxpY0tleTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiB7IHZhbGlkOiBmYWxzZSwgcHJvYmxlbTogYGl0cyBjZXJ0aWZpY2F0ZSBjb3VsZCBub3QgYmUgcmVhZCwgJHtlfWAgfTtcbiAgICB9XG4gICAgLy8gVGhlIGlkIGlzIGEgaGFzaCBvZiB0aGUgcHVibGljIGtleSwgc28gdGhpcyBpcyB3aGF0IHN0b3BzIGEgbWFjaGluZSBjbGFpbWluZyBhbm90aGVyJ3MgaWQuXG4gICAgaWYgKCF2ZXJpZnlNYWNoaW5lSWRGb3JQdWJsaWNLZXkoeyBtYWNoaW5lSWQ6IHBhY2tldC5tYWNoaW5lSWQsIHB1YmxpY0tleTogcHVibGljS2V5Qnl0ZXMoY2VydFBFTSkgfSkpIHtcbiAgICAgICAgcmV0dXJuIHsgdmFsaWQ6IGZhbHNlLCBwcm9ibGVtOiBcInRoZSBtYWNoaW5lIGlkIGRvZXMgbm90IGJlbG9uZyB0byB0aGF0IGNlcnRpZmljYXRlXCIgfTtcbiAgICB9XG4gICAgbGV0IHNpZ25lZCA9IGNyeXB0by52ZXJpZnkoXG4gICAgICAgIG51bGwsXG4gICAgICAgIEJ1ZmZlci5mcm9tKGAke3BhY2tldC5tYWNoaW5lSWR9ICR7cGFja2V0LnNpZ25lZEF0fWApLFxuICAgICAgICBwdWJsaWNLZXksXG4gICAgICAgIEJ1ZmZlci5mcm9tKHBhY2tldC5zaWduYXR1cmVCNjQsIFwiYmFzZTY0XCIpXG4gICAgKTtcbiAgICBpZiAoIXNpZ25lZCkge1xuICAgICAgICByZXR1cm4geyB2YWxpZDogZmFsc2UsIHByb2JsZW06IFwidGhlIHNpZ25hdHVyZSBkb2VzIG5vdCBjaGVjayBvdXRcIiB9O1xuICAgIH1cbiAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSwgcHJvYmxlbTogXCJcIiB9O1xufVxuIl19
176
- /* _JS_SOURCE_HASH = "2b16a13142ed08ef2e755cf33ce9a940aaef44261d0b1bdd42b8efe807f54df2"; */
176
+ /* _JS_SOURCE_HASH = "77f05d180437cd251908f65840a875daf9e90268122306a6cbbc5c81e6e1824c"; */
@@ -3,11 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule && mod.default) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
6
- //exports.isMachineAccepted = exports.resolveKeysRepo = exports.machineState = exports.MACHINES_DIR = void 0;
6
+ //exports.isMachineAccepted = exports.setMachines = exports.getMachines = exports.MACHINES_DIR = void 0;
7
7
  const promises_1 = __importDefault(require("fs/promises"));
8
8
  const os_1 = __importDefault(require("os"));
9
9
  const path_1 = __importDefault(require("path"));
10
- const paths_1 = require("../authorizedKeys/daemon/paths");
10
+ const keysRepo_1 = require("../authorizedKeys/keysRepo");
11
11
  const repoFiles_1 = require("../authorizedKeys/daemon/repoFiles");
12
12
  const repoFiles_2 = require("../authorizedKeys/daemon/repoFiles");
13
13
  const revocation_1 = require("../authorizedKeys/daemon/revocation");
@@ -15,11 +15,8 @@ const git_1 = require("../authorizedKeys/daemon/git");
15
15
  const repoFiles_3 = require("../authorizedKeys/daemon/repoFiles");
16
16
  const trust_1 = require("../authorizedKeys/daemon/trust");
17
17
  const revokeSource_1 = require("../authorizedKeys/revokeSource");
18
- const sources_1 = require("../authorizedKeys/sources");
19
18
  const notify_1 = require("../authorizedKeys/daemon/notify");
20
19
  const discord_1 = require("../notifications/discord");
21
- const trustState_1 = require("./trustState");
22
- const spawn_1 = require("../helpers/spawn");
23
20
  // Which machines this system talks to, kept in the same repo as the ssh keys. That repo is already
24
21
  // signed, already distributed to every machine, and already has somewhere to record a rejection,
25
22
  // so a second one would only be a second thing to keep in step.
@@ -29,9 +26,6 @@ const REVOCATION_REASON = "a machine talked to us from an unapproved IP";
29
26
  // The revoke repo is pulled at most this often. A check happens per request, and a request must
30
27
  // not cost a round trip to github.
31
28
  const REVOKE_SYNC_INTERVAL = 60 * 1000;
32
- // Where a Windows machine is expected to keep the repo, relative to the working directory. There
33
- // is no daemon there to ask, and no /etc to look in.
34
- const WINDOWS_REPO_PATH = "../authorized_keys";
35
29
  async function pathExists(filePath) {
36
30
  try {
37
31
  await promises_1.default.access(filePath);
@@ -44,24 +38,25 @@ async function pathExists(filePath) {
44
38
  function machineFilePath(repoPath, machineId) {
45
39
  return path_1.default.join(repoPath, exports.MACHINES_DIR, `${machineId}.json`);
46
40
  }
47
- /** Reads every machine a checkout lists, or sets them.
41
+ /** Every machine a checkout lists. */
42
+ async function getMachines(repoPath) {
43
+ return [...(await readMachines(repoPath)).values()];
44
+ }
45
+ exports.getMachines = getMachines;
46
+ /** Makes a checkout list exactly these machines: those named are written with the addresses given,
47
+ and anything not named is removed. So read them, change what you want, and write the result.
48
48
 
49
- Passing `machines` makes the repo match it exactly: machines named are written with the
50
- addresses given, and machines not named are removed. That is why the addresses are part of
51
- setting rather than a separate step - a machine with no address it may talk from is not a
52
- machine we would accept anyway, so there is no state where naming one without them means
53
- anything. Read first, change what you want, write the result.
49
+ The addresses are part of setting rather than a separate step, because a machine with no
50
+ address it may talk from is not a machine that would ever be accepted - there is no state where
51
+ naming one without them means anything.
54
52
 
55
- Nothing here signs or commits anything. The signature is what every other machine checks before
53
+ Nothing here signs or commits. The signature is what every other machine checks before
56
54
  believing any of this, and it takes the hardware key, so `yarn signfiles git` is still yours to
57
55
  run afterwards. */
58
- async function machineState(config) {
56
+ async function setMachines(config) {
59
57
  var _a;
60
58
  let { repoPath, machines } = config;
61
59
  let existing = await readMachines(repoPath);
62
- if (!machines) {
63
- return [...existing.values()];
64
- }
65
60
  let directory = path_1.default.join(repoPath, exports.MACHINES_DIR);
66
61
  let written = [];
67
62
  for (let machine of machines) {
@@ -91,7 +86,7 @@ async function machineState(config) {
91
86
  }
92
87
  return written;
93
88
  }
94
- exports.machineState = machineState;
89
+ exports.setMachines = setMachines;
95
90
  /** Every machine the repo lists. */
96
91
  async function readMachines(repoPath) {
97
92
  let machines = new Map();
@@ -112,52 +107,6 @@ async function readMachines(repoPath) {
112
107
  }
113
108
  return machines;
114
109
  }
115
- async function isKeysRepo(repoPath) {
116
- return await pathExists(path_1.default.join(repoPath, ".git"))
117
- && await pathExists(path_1.default.join(repoPath, "authorized_keys"));
118
- }
119
- async function originOf(repoPath) {
120
- let origin = await (0, spawn_1.spawnPromise)({ command: "git", args: ["remote", "get-url", "origin"], cwd: repoPath });
121
- let url = origin.stdout.trim();
122
- if (origin.status !== 0 || !url) {
123
- throw new Error(`Expected ${repoPath} to have an origin remote, it has none`);
124
- }
125
- return url;
126
- }
127
- /** The keys repo this machine answers from, and the one anything editing the machine list edits.
128
-
129
- On a host, that is the checkout the daemon already keeps up to date. On Windows there is no
130
- daemon and no /etc, so the repo is expected beside the working directory, which is where a
131
- developer working on both would have it.
132
-
133
- Never the directory the command happens to be run from. Which repo this machine trusts is a
134
- property of the machine, not of where somebody was standing when they typed something. */
135
- async function resolveKeysRepo() {
136
- if (os_1.default.platform() === "win32") {
137
- let repoPath = path_1.default.resolve(WINDOWS_REPO_PATH);
138
- if (!await isKeysRepo(repoPath)) {
139
- throw new Error(`Expected ${repoPath} to be an authorized_keys repo, it is not.\n`
140
- + `On Windows the repo is read from there, so clone it beside this one:\n`
141
- + ` git clone <your authorized_keys repo> ${repoPath}`);
142
- }
143
- return { repoPath, sourceURL: await originOf(repoPath) };
144
- }
145
- let config = await promises_1.default.readFile(paths_1.CONFIG_PATH, "utf8").catch(() => "");
146
- let sourceURL = config && (JSON.parse(config).repoSources || [])[0] || "";
147
- if (!sourceURL) {
148
- throw new Error(`Expected this machine to be set up with an authorized_keys repo, ${paths_1.CONFIG_PATH} names none.\n`
149
- + `Set it up first:\n`
150
- + ` yarn setupnotify <discord-webhook-url>\n`
151
- + ` yarn securessh add <repo-private-key> <repo-url>`);
152
- }
153
- let repoPath = (0, sources_1.sourceRepoPath)(sourceURL);
154
- if (!await isKeysRepo(repoPath)) {
155
- throw new Error(`Expected a checkout of ${sourceURL} at ${repoPath}, there is none.\n`
156
- + `Run \`yarn securessh update\` to put it back.`);
157
- }
158
- return { repoPath, sourceURL };
159
- }
160
- exports.resolveKeysRepo = resolveKeysRepo;
161
110
  let lastRevokeSync = 0;
162
111
  /** Pulled at most once a REVOKE_SYNC_INTERVAL, because this is asked per request. A sync that
163
112
  fails leaves the checkout we already have, which is the safe direction: revocations we know
@@ -256,67 +205,60 @@ async function recordMachineRevocation(config) {
256
205
  + `\n\nIt is frozen everywhere now, and nothing accepts it.`
257
206
  + `\n\nIf this was an attack, remove \`machines/${machineId}.json\` from \`${sourceURL}\` now.`
258
207
  + `\nIf it was legitimate, run \`yarn unrevoke git\` in that repo. It allows ${ip} for that`
259
- + ` machine, and takes an hour to reach every machine.`
208
+ + ` machine, and takes effect as each machine picks it up.`
260
209
  + `\n\nmachine: \`${machineId}\``
261
210
  + `\nfrozen by: \`${hostLabel}\``);
262
211
  }
263
- /** Whether we will talk to this machine, coming from this address.
264
-
265
- Both halves are required and neither is a guess: the caller knows the machine id because the
266
- connection proved it, and knows the address because the packets came from there. A machine we
267
- do not list is simply not accepted. A machine we do list, arriving from an address it does not
268
- have, is treated as the same kind of event as a stolen ssh key - it is revoked everywhere, and
269
- stays revoked until an unrevoke allows that machine from that address.
270
-
271
- Throws when the repo itself cannot be read or is not signed, rather than answering false: that
272
- is a broken installation, not a rejected machine, and the two deserve different handling. */
273
212
  async function isMachineAccepted(config) {
274
213
  let { machineId, ip } = config;
275
214
  if (!machineId || !ip) {
276
215
  throw new Error(`Expected a machineId and an ip, was ${JSON.stringify(machineId)} and ${JSON.stringify(ip)}`);
277
216
  }
278
- let { repoPath, sourceURL } = await resolveKeysRepo();
217
+ let { repoPath, sourceURL } = await (0, keysRepo_1.resolveKeysRepo)();
279
218
  // Unsigned, or signed over different contents, means the machine list is not evidence of
280
219
  // anything. Same gate the ssh keys go through.
281
220
  await (0, trust_1.verifyCheckout)(repoPath);
282
221
  let machine = (await readMachines(repoPath)).get(machineId);
283
222
  if (!machine) {
284
- return false;
223
+ return { accepted: false, reason: "that machine is not trusted" };
285
224
  }
286
225
  await syncRevocations(sourceURL);
287
226
  let unrevokes = await (0, revocation_1.readUnrevokes)(sourceURL).catch(() => ({ pairs: new Map(), legacyIds: new Map() }));
288
- // An unrevoke is only honoured once it has waited out its hour, exactly as an ssh key's is.
289
- let allowedAgain = async (pair) => {
290
- let unrevokeId = unrevokes.pairs.get(pair);
291
- return !!unrevokeId && await (0, trustState_1.unrevokeInEffect)(unrevokeId);
292
- };
227
+ // An unrevoke counts as soon as it is seen. It is signed, so writing one already takes the
228
+ // hardware key, and anyone holding that can sign anything at all - a wait before honouring it
229
+ // guards against an attacker who has no need of it.
230
+ let allowedAgain = (pair) => { var _a; return !!((_a = unrevokes.pairs.get(pair)) === null || _a === void 0 ? void 0 : _a.length); };
293
231
  let revocations = await readMachineRevocations(sourceURL);
294
232
  // Any revocation nothing has undone keeps the machine out, from everywhere, the way a revoked
295
233
  // ssh key is out everywhere rather than only from the address it was misused from.
296
- let revoked = false;
234
+ let frozenFrom = "";
297
235
  for (let revocation of revocations) {
298
236
  if (revocation.machineId !== machineId) {
299
237
  continue;
300
238
  }
301
- if (!await allowedAgain((0, revocation_1.pairKey)({ fingerprint: revocation.machineId, ip: revocation.ip }))) {
302
- revoked = true;
239
+ if (!allowedAgain((0, revocation_1.pairKey)({ fingerprint: revocation.machineId, ip: revocation.ip }))) {
240
+ frozenFrom = revocation.ip;
303
241
  }
304
242
  }
305
- if (revoked) {
306
- return false;
243
+ if (frozenFrom) {
244
+ return {
245
+ accepted: false,
246
+ reason: `that machine is frozen, it was used from ${frozenFrom} which it is not allowed from`,
247
+ };
307
248
  }
308
249
  if (machine.ips.includes(ip)) {
309
- return true;
250
+ return { accepted: true, reason: "" };
310
251
  }
311
252
  // Listed, but talking to us from somewhere it should not be. Recorded once for this machine
312
253
  // and address, so being talked to repeatedly does not write repeatedly.
313
254
  let pair = (0, revocation_1.pairKey)({ fingerprint: machineId, ip });
314
255
  let alreadyRecorded = revocations.some(revocation => (0, revocation_1.pairKey)({ fingerprint: revocation.machineId, ip: revocation.ip }) === pair);
315
- if (!alreadyRecorded && !await allowedAgain(pair)) {
256
+ if (!alreadyRecorded && !allowedAgain(pair)) {
316
257
  await recordMachineRevocation({ sourceURL, machineId, ip, hostLabel: os_1.default.hostname() });
258
+ return { accepted: false, reason: `that machine is not allowed from ${ip}, so it is now frozen everywhere` };
317
259
  }
318
- return false;
260
+ return { accepted: false, reason: `that machine is not allowed from ${ip}` };
319
261
  }
320
262
  exports.isMachineAccepted = isMachineAccepted;
321
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFjaGluZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtYWNoaW5lcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSwyREFBNkI7QUFDN0IsNENBQW9CO0FBQ3BCLGdEQUF3QjtBQUN4QiwwREFBNkQ7QUFDN0Qsa0VBQStFO0FBQy9FLGtFQUErRTtBQUMvRSxvRUFBbUg7QUFDbkgsc0RBQXNEO0FBQ3RELGtFQUFxRTtBQUNyRSwwREFBZ0U7QUFDaEUsaUVBQStFO0FBQy9FLHVEQUEyRDtBQUMzRCw0REFBeUQ7QUFDekQsc0RBQXVJO0FBQ3ZJLDZDQUFnRDtBQUNoRCw0Q0FBZ0Q7QUFFaEQsbUdBQW1HO0FBQ25HLGlHQUFpRztBQUNqRyxnRUFBZ0U7QUFDbkQsUUFBQSxZQUFZLEdBQUcsVUFBVSxDQUFDO0FBQ3ZDLE1BQU0sZUFBZSxHQUFHLGFBQWEsQ0FBQztBQUN0QyxNQUFNLGlCQUFpQixHQUFHLDhDQUE4QyxDQUFDO0FBQ3pFLGdHQUFnRztBQUNoRyxtQ0FBbUM7QUFDbkMsTUFBTSxvQkFBb0IsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQ3ZDLGlHQUFpRztBQUNqRyxxREFBcUQ7QUFDckQsTUFBTSxpQkFBaUIsR0FBRyxvQkFBb0IsQ0FBQztBQVMvQyxLQUFLLFVBQVUsVUFBVSxDQUFDLFFBQWdCO0lBQ3RDLElBQUksQ0FBQztRQUNELE1BQU0sa0JBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDMUIsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDVCxPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDO0FBQ0wsQ0FBQztBQUVELFNBQVMsZUFBZSxDQUFDLFFBQWdCLEVBQUUsU0FBaUI7SUFDeEQsT0FBTyxjQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxvQkFBWSxFQUFFLEdBQUcsU0FBUyxPQUFPLENBQUMsQ0FBQztBQUNsRSxDQUFDO0FBRUQ7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SUFFRCw0RkFBNEY7SUFDNUYsd0VBQXdFO0lBQ3hFLElBQUksSUFBSSxHQUFHLElBQUEsb0JBQU8sRUFBQyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNuRCxJQUFJLGVBQWUsR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQ2hELElBQUEsb0JBQU8sRUFBQyxFQUFFLFdBQVcsRUFBRSxVQUFVLENBQUMsU0FBUyxFQUFFLEVBQUUsRUFBRSxVQUFVLENBQUMsRUFBRSxFQUFFLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQztJQUNoRixJQUFJLENBQUMsZUFBZSxJQUFJLENBQUMsTUFBTSxZQUFZLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUNoRCxNQUFNLHVCQUF1QixDQUFDLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLFlBQUUsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDMUYsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2pCLENBQUM7QUFuREQsOENBbURDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGZzIGZyb20gXCJmcy9wcm9taXNlc1wiO1xuaW1wb3J0IG9zIGZyb20gXCJvc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IENPTkZJR19QQVRIIH0gZnJvbSBcIi4uL2F1dGhvcml6ZWRLZXlzL2RhZW1vbi9wYXRoc1wiO1xuaW1wb3J0IHsgcmV2b2tlUmVwbywgc3luY1JlcG9GaWxlcyB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5cy9kYWVtb24vcmVwb0ZpbGVzXCI7XG5pbXBvcnQgeyBsaXN0UmVwb0RpciwgcmVhZFJlcG9GaWxlIH0gZnJvbSBcIi4uL2F1dGhvcml6ZWRLZXlzL2RhZW1vbi9yZXBvRmlsZXNcIjtcbmltcG9ydCB7IG5ld1Jldm9jYXRpb25JZCwgcGFpcktleSwgcmVhZFJldm9jYXRpb25GaWxlcywgcmVhZFVucmV2b2tlcyB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5cy9kYWVtb24vcmV2b2NhdGlvblwiO1xuaW1wb3J0IHsgcnVuR2l0IH0gZnJvbSBcIi4uL2F1dGhvcml6ZWRLZXlzL2RhZW1vbi9naXRcIjtcbmltcG9ydCB7IGVuc3VyZVJldm9rZUtleSB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5cy9kYWVtb24vcmVwb0ZpbGVzXCI7XG5pbXBvcnQgeyB2ZXJpZnlDaGVja291dCB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5cy9kYWVtb24vdHJ1c3RcIjtcbmltcG9ydCB7IHJldm9rZVJlcG9QYXRoLCByZXZva2VSZXBvVVJMIH0gZnJvbSBcIi4uL2F1dGhvcml6ZWRLZXlzL3Jldm9rZVNvdXJjZVwiO1xuaW1wb3J0IHsgc291cmNlUmVwb1BhdGggfSBmcm9tIFwiLi4vYXV0aG9yaXplZEtleXMvc291cmNlc1wiO1xuaW1wb3J0IHsgbm90aWZ5IH0gZnJvbSBcIi4uL2F1dGhvcml6ZWRLZXlzL2RhZW1vbi9ub3RpZnlcIjtcbmltcG9ydCB7IGFyZURpc2NvcmROb3RpZmljYXRpb25zQ29uZmlndXJlZCwgY29uZmlndXJlRGlzY29yZE5vdGlmaWNhdGlvbnMsIERFRkFVTFRfV0VCSE9PS19GSUxFX1BBVEggfSBmcm9tIFwiLi4vbm90aWZpY2F0aW9ucy9kaXNjb3JkXCI7XG5pbXBvcnQgeyB1bnJldm9rZUluRWZmZWN0IH0gZnJvbSBcIi4vdHJ1c3RTdGF0ZVwiO1xuaW1wb3J0IHsgc3Bhd25Qcm9taXNlIH0gZnJvbSBcIi4uL2hlbHBlcnMvc3Bhd25cIjtcblxuLy8gV2hpY2ggbWFjaGluZXMgdGhpcyBzeXN0ZW0gdGFsa3MgdG8sIGtlcHQgaW4gdGhlIHNhbWUgcmVwbyBhcyB0aGUgc3NoIGtleXMuIFRoYXQgcmVwbyBpcyBhbHJlYWR5XG4vLyBzaWduZWQsIGFscmVhZHkgZGlzdHJpYnV0ZWQgdG8gZXZlcnkgbWFjaGluZSwgYW5kIGFscmVhZHkgaGFzIHNvbWV3aGVyZSB0byByZWNvcmQgYSByZWplY3Rpb24sXG4vLyBzbyBhIHNlY29uZCBvbmUgd291bGQgb25seSBiZSBhIHNlY29uZCB0aGluZyB0byBrZWVwIGluIHN0ZXAuXG5leHBvcnQgY29uc3QgTUFDSElORVNfRElSID0gXCJtYWNoaW5lc1wiO1xuY29uc3QgUkVWT0NBVElPTlNfRElSID0gXCJyZXZvY2F0aW9uc1wiO1xuY29uc3QgUkVWT0NBVElPTl9SRUFTT04gPSBcImEgbWFjaGluZSB0YWxrZWQgdG8gdXMgZnJvbSBhbiB1bmFwcHJvdmVkIElQXCI7XG4vLyBUaGUgcmV2b2tlIHJlcG8gaXMgcHVsbGVkIGF0IG1vc3QgdGhpcyBvZnRlbi4gQSBjaGVjayBoYXBwZW5zIHBlciByZXF1ZXN0LCBhbmQgYSByZXF1ZXN0IG11c3Rcbi8vIG5vdCBjb3N0IGEgcm91bmQgdHJpcCB0byBnaXRodWIuXG5jb25zdCBSRVZPS0VfU1lOQ19JTlRFUlZBTCA9IDYwICogMTAwMDtcbi8vIFdoZXJlIGEgV2luZG93cyBtYWNoaW5lIGlzIGV4cGVjdGVkIHRvIGtlZXAgdGhlIHJlcG8sIHJlbGF0aXZlIHRvIHRoZSB3b3JraW5nIGRpcmVjdG9yeS4gVGhlcmVcbi8vIGlzIG5vIGRhZW1vbiB0aGVyZSB0byBhc2ssIGFuZCBubyAvZXRjIHRvIGxvb2sgaW4uXG5jb25zdCBXSU5ET1dTX1JFUE9fUEFUSCA9IFwiLi4vYXV0aG9yaXplZF9rZXlzXCI7XG5cbi8qKiBPbmUgbWFjaGluZSB3ZSBhcmUgd2lsbGluZyB0byB0YWxrIHRvLCBhbmQgdGhlIGFkZHJlc3NlcyBpdCBtYXkgdGFsayB0byB1cyBmcm9tLiAqL1xuZXhwb3J0IHR5cGUgTWFjaGluZVN0YXRlID0ge1xuICAgIG1hY2hpbmVJZDogc3RyaW5nO1xuICAgIGlwczogc3RyaW5nW107XG4gICAgYWRkZWRBdDogc3RyaW5nO1xufTtcblxuYXN5bmMgZnVuY3Rpb24gcGF0aEV4aXN0cyhmaWxlUGF0aDogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgZnMuYWNjZXNzKGZpbGVQYXRoKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBtYWNoaW5lRmlsZVBhdGgocmVwb1BhdGg6IHN0cmluZywgbWFjaGluZUlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gcGF0aC5qb2luKHJlcG9QYXRoLCBNQUNISU5FU19ESVIsIGAke21hY2hpbmVJZH0uanNvbmApO1xufVxuXG4vKiogUmVhZHMgZXZlcnkgbWFjaGluZSBhIGNoZWNrb3V0IGxpc3RzLCBvciBzZXRzIHRoZW0uXG5cbiAgICBQYXNzaW5nIGBtYWNoaW5lc2AgbWFrZXMgdGhlIHJlcG8gbWF0Y2ggaXQgZXhhY3RseTogbWFjaGluZXMgbmFtZWQgYXJlIHdyaXR0ZW4gd2l0aCB0aGVcbiAgICBhZGRyZXNzZXMgZ2l2ZW4sIGFuZCBtYWNoaW5lcyBub3QgbmFtZWQgYXJlIHJlbW92ZWQuIFRoYXQgaXMgd2h5IHRoZSBhZGRyZXNzZXMgYXJlIHBhcnQgb2ZcbiAgICBzZXR0aW5nIHJhdGhlciB0aGFuIGEgc2VwYXJhdGUgc3RlcCAtIGEgbWFjaGluZSB3aXRoIG5vIGFkZHJlc3MgaXQgbWF5IHRhbGsgZnJvbSBpcyBub3QgYVxuICAgIG1hY2hpbmUgd2Ugd291bGQgYWNjZXB0IGFueXdheSwgc28gdGhlcmUgaXMgbm8gc3RhdGUgd2hlcmUgbmFtaW5nIG9uZSB3aXRob3V0IHRoZW0gbWVhbnNcbiAgICBhbnl0aGluZy4gUmVhZCBmaXJzdCwgY2hhbmdlIHdoYXQgeW91IHdhbnQsIHdyaXRlIHRoZSByZXN1bHQuXG5cbiAgICBOb3RoaW5nIGhlcmUgc2lnbnMgb3IgY29tbWl0cyBhbnl0aGluZy4gVGhlIHNpZ25hdHVyZSBpcyB3aGF0IGV2ZXJ5IG90aGVyIG1hY2hpbmUgY2hlY2tzIGJlZm9yZVxuICAgIGJlbGlldmluZyBhbnkgb2YgdGhpcywgYW5kIGl0IHRha2VzIHRoZSBoYXJkd2FyZSBrZXksIHNvIGB5YXJuIHNpZ25maWxlcyBnaXRgIGlzIHN0aWxsIHlvdXJzIHRvXG4gICAgcnVuIGFmdGVyd2FyZHMuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbWFjaGluZVN0YXRlKGNvbmZpZzoge1xuICAgIHJlcG9QYXRoOiBzdHJpbmc7XG4gICAgbWFjaGluZXM/OiB7IG1hY2hpbmVJZDogc3RyaW5nOyBpcHM6IHN0cmluZ1tdIH1bXTtcbn0pOiBQcm9taXNlPE1hY2hpbmVTdGF0ZVtdPiB7XG4gICAgbGV0IHsgcmVwb1BhdGgsIG1hY2hpbmVzIH0gPSBjb25maWc7XG4gICAgbGV0IGV4aXN0aW5nID0gYXdhaXQgcmVhZE1hY2hpbmVzKHJlcG9QYXRoKTtcbiAgICBpZiAoIW1hY2hpbmVzKSB7XG4gICAgICAgIHJldHVybiBbLi4uZXhpc3RpbmcudmFsdWVzKCldO1xuICAgIH1cblxuICAgIGxldCBkaXJlY3RvcnkgPSBwYXRoLmpvaW4ocmVwb1BhdGgsIE1BQ0hJTkVTX0RJUik7XG4gICAgbGV0IHdyaXR0ZW46IE1hY2hpbmVTdGF0ZVtdID0gW107XG4gICAgZm9yIChsZXQgbWFjaGluZSBvZiBtYWNoaW5lcykge1xuICAgICAgICBpZiAoIW1hY2hpbmUubWFjaGluZUlkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGEgbWFjaGluZUlkLCB3YXMgJHtKU09OLnN0cmluZ2lmeShtYWNoaW5lLm1hY2hpbmVJZCl9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFtYWNoaW5lLmlwcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBgRXhwZWN0ZWQgYWRkcmVzc2VzIGZvciAke21hY2hpbmUubWFjaGluZUlkfSwgd2FzIG5vbmUuIEEgbWFjaGluZSBpcyB0cnVzdGVkIGZyb21gXG4gICAgICAgICAgICAgICAgKyBgIHRoZSBhZGRyZXNzZXMgaXQgbWF5IHRhbGsgZnJvbSwgc28gbGVhdmUgaXQgb3V0IG9mIHRoZSBsaXN0IHRvIHJlbW92ZSBpdC5gXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGxldCBpcHMgPSBtYWNoaW5lLmlwcy5maWx0ZXIoKGlwLCBpbmRleCkgPT4gaXAgJiYgbWFjaGluZS5pcHMuaW5kZXhPZihpcCkgPT09IGluZGV4KTtcbiAgICAgICAgbGV0IHN0YXRlOiBNYWNoaW5lU3RhdGUgPSB7XG4gICAgICAgICAgICBtYWNoaW5lSWQ6IG1hY2hpbmUubWFjaGluZUlkLFxuICAgICAgICAgICAgLy8gSW4gdGhlIG9yZGVyIGdpdmVuLCB3aXRob3V0IGR1cGxpY2F0ZXMsIHNvIHRoZSBmaWxlIHJlYWRzIHRoZSB3YXkgaXQgd2FzIHNldC5cbiAgICAgICAgICAgIGlwcyxcbiAgICAgICAgICAgIGFkZGVkQXQ6IGV4aXN0aW5nLmdldChtYWNoaW5lLm1hY2hpbmVJZCk/LmFkZGVkQXQgfHwgbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICB9O1xuICAgICAgICBhd2FpdCBmcy5ta2RpcihkaXJlY3RvcnksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgICBhd2FpdCBmcy53cml0ZUZpbGUobWFjaGluZUZpbGVQYXRoKHJlcG9QYXRoLCBzdGF0ZS5tYWNoaW5lSWQpLCBKU09OLnN0cmluZ2lmeShzdGF0ZSwgdW5kZWZpbmVkLCA0KSArIFwiXFxuXCIpO1xuICAgICAgICB3cml0dGVuLnB1c2goc3RhdGUpO1xuICAgIH1cblxuICAgIC8vIFdoYXRldmVyIHRoZSByZXBvIGhhZCBhbmQgdGhlIGNhbGxlciBkaWQgbm90IG5hbWUgaXMgbm8gbG9uZ2VyIHRydXN0ZWQuXG4gICAgZm9yIChsZXQgbWFjaGluZUlkIG9mIGV4aXN0aW5nLmtleXMoKSkge1xuICAgICAgICBpZiAoIW1hY2hpbmVzLnNvbWUobWFjaGluZSA9PiBtYWNoaW5lLm1hY2hpbmVJZCA9PT0gbWFjaGluZUlkKSkge1xuICAgICAgICAgICAgYXdhaXQgZnMucm0obWFjaGluZUZpbGVQYXRoKHJlcG9QYXRoLCBtYWNoaW5lSWQpLCB7IGZvcmNlOiB0cnVlIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB3cml0dGVuO1xufVxuXG4vKiogRXZlcnkgbWFjaGluZSB0aGUgcmVwbyBsaXN0cy4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlYWRNYWNoaW5lcyhyZXBvUGF0aDogc3RyaW5nKSB7XG4gICAgbGV0IG1hY2hpbmVzID0gbmV3IE1hcDxzdHJpbmcsIE1hY2hpbmVTdGF0ZT4oKTtcbiAgICBsZXQgZGlyZWN0b3J5ID0gcGF0aC5qb2luKHJlcG9QYXRoLCBNQUNISU5FU19ESVIpO1xuICAgIGxldCBuYW1lcyA9IGF3YWl0IGZzLnJlYWRkaXIoZGlyZWN0b3J5KS5jYXRjaCgoKSA9PiBbXSBhcyBzdHJpbmdbXSk7XG4gICAgZm9yIChsZXQgbmFtZSBvZiBuYW1lcy5zb3J0KCkpIHtcbiAgICAgICAgaWYgKCFuYW1lLmVuZHNXaXRoKFwiLmpzb25cIikpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgcGFyc2VkID0gSlNPTi5wYXJzZShhd2FpdCBmcy5yZWFkRmlsZShwYXRoLmpvaW4oZGlyZWN0b3J5LCBuYW1lKSwgXCJ1dGY4XCIpKTtcbiAgICAgICAgICAgIGxldCBtYWNoaW5lSWQgPSBwYXJzZWQubWFjaGluZUlkIHx8IG5hbWUucmVwbGFjZSgvXFwuanNvbiQvLCBcIlwiKTtcbiAgICAgICAgICAgIG1hY2hpbmVzLnNldChtYWNoaW5lSWQsIHsgbWFjaGluZUlkLCBpcHM6IHBhcnNlZC5pcHMgfHwgW10sIGFkZGVkQXQ6IHBhcnNlZC5hZGRlZEF0IHx8IFwiXCIgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBJZ25vcmluZyB1bnJlYWRhYmxlIG1hY2hpbmUgZmlsZSAke25hbWV9LiAke2V9YCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hY2hpbmVzO1xufVxuXG5hc3luYyBmdW5jdGlvbiBpc0tleXNSZXBvKHJlcG9QYXRoOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gYXdhaXQgcGF0aEV4aXN0cyhwYXRoLmpvaW4ocmVwb1BhdGgsIFwiLmdpdFwiKSlcbiAgICAgICAgJiYgYXdhaXQgcGF0aEV4aXN0cyhwYXRoLmpvaW4ocmVwb1BhdGgsIFwiYXV0aG9yaXplZF9rZXlzXCIpKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gb3JpZ2luT2YocmVwb1BhdGg6IHN0cmluZykge1xuICAgIGxldCBvcmlnaW4gPSBhd2FpdCBzcGF3blByb21pc2UoeyBjb21tYW5kOiBcImdpdFwiLCBhcmdzOiBbXCJyZW1vdGVcIiwgXCJnZXQtdXJsXCIsIFwib3JpZ2luXCJdLCBjd2Q6IHJlcG9QYXRoIH0pO1xuICAgIGxldCB1cmwgPSBvcmlnaW4uc3Rkb3V0LnRyaW0oKTtcbiAgICBpZiAob3JpZ2luLnN0YXR1cyAhPT0gMCB8fCAhdXJsKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgJHtyZXBvUGF0aH0gdG8gaGF2ZSBhbiBvcmlnaW4gcmVtb3RlLCBpdCBoYXMgbm9uZWApO1xuICAgIH1cbiAgICByZXR1cm4gdXJsO1xufVxuXG4vKiogVGhlIGtleXMgcmVwbyB0aGlzIG1hY2hpbmUgYW5zd2VycyBmcm9tLCBhbmQgdGhlIG9uZSBhbnl0aGluZyBlZGl0aW5nIHRoZSBtYWNoaW5lIGxpc3QgZWRpdHMuXG5cbiAgICBPbiBhIGhvc3QsIHRoYXQgaXMgdGhlIGNoZWNrb3V0IHRoZSBkYWVtb24gYWxyZWFkeSBrZWVwcyB1cCB0byBkYXRlLiBPbiBXaW5kb3dzIHRoZXJlIGlzIG5vXG4gICAgZGFlbW9uIGFuZCBubyAvZXRjLCBzbyB0aGUgcmVwbyBpcyBleHBlY3RlZCBiZXNpZGUgdGhlIHdvcmtpbmcgZGlyZWN0b3J5LCB3aGljaCBpcyB3aGVyZSBhXG4gICAgZGV2ZWxvcGVyIHdvcmtpbmcgb24gYm90aCB3b3VsZCBoYXZlIGl0LlxuXG4gICAgTmV2ZXIgdGhlIGRpcmVjdG9yeSB0aGUgY29tbWFuZCBoYXBwZW5zIHRvIGJlIHJ1biBmcm9tLiBXaGljaCByZXBvIHRoaXMgbWFjaGluZSB0cnVzdHMgaXMgYVxuICAgIHByb3BlcnR5IG9mIHRoZSBtYWNoaW5lLCBub3Qgb2Ygd2hlcmUgc29tZWJvZHkgd2FzIHN0YW5kaW5nIHdoZW4gdGhleSB0eXBlZCBzb21ldGhpbmcuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZUtleXNSZXBvKCkge1xuICAgIGlmIChvcy5wbGF0Zm9ybSgpID09PSBcIndpbjMyXCIpIHtcbiAgICAgICAgbGV0IHJlcG9QYXRoID0gcGF0aC5yZXNvbHZlKFdJTkRPV1NfUkVQT19QQVRIKTtcbiAgICAgICAgaWYgKCFhd2FpdCBpc0tleXNSZXBvKHJlcG9QYXRoKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIGBFeHBlY3RlZCAke3JlcG9QYXRofSB0byBiZSBhbiBhdXRob3JpemVkX2tleXMgcmVwbywgaXQgaXMgbm90LlxcbmBcbiAgICAgICAgICAgICAgICArIGBPbiBXaW5kb3dzIHRoZSByZXBvIGlzIHJlYWQgZnJvbSB0aGVyZSwgc28gY2xvbmUgaXQgYmVzaWRlIHRoaXMgb25lOlxcbmBcbiAgICAgICAgICAgICAgICArIGAgIGdpdCBjbG9uZSA8eW91ciBhdXRob3JpemVkX2tleXMgcmVwbz4gJHtyZXBvUGF0aH1gXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IHJlcG9QYXRoLCBzb3VyY2VVUkw6IGF3YWl0IG9yaWdpbk9mKHJlcG9QYXRoKSB9O1xuICAgIH1cblxuICAgIGxldCBjb25maWcgPSBhd2FpdCBmcy5yZWFkRmlsZShDT05GSUdfUEFUSCwgXCJ1dGY4XCIpLmNhdGNoKCgpID0+IFwiXCIpO1xuICAgIGxldCBzb3VyY2VVUkwgPSBjb25maWcgJiYgKEpTT04ucGFyc2UoY29uZmlnKS5yZXBvU291cmNlcyB8fCBbXSlbMF0gfHwgXCJcIjtcbiAgICBpZiAoIXNvdXJjZVVSTCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgRXhwZWN0ZWQgdGhpcyBtYWNoaW5lIHRvIGJlIHNldCB1cCB3aXRoIGFuIGF1dGhvcml6ZWRfa2V5cyByZXBvLCAke0NPTkZJR19QQVRIfSBuYW1lcyBub25lLlxcbmBcbiAgICAgICAgICAgICsgYFNldCBpdCB1cCBmaXJzdDpcXG5gXG4gICAgICAgICAgICArIGAgIHlhcm4gc2V0dXBub3RpZnkgPGRpc2NvcmQtd2ViaG9vay11cmw+XFxuYFxuICAgICAgICAgICAgKyBgICB5YXJuIHNlY3VyZXNzaCBhZGQgPHJlcG8tcHJpdmF0ZS1rZXk+IDxyZXBvLXVybD5gXG4gICAgICAgICk7XG4gICAgfVxuICAgIGxldCByZXBvUGF0aCA9IHNvdXJjZVJlcG9QYXRoKHNvdXJjZVVSTCk7XG4gICAgaWYgKCFhd2FpdCBpc0tleXNSZXBvKHJlcG9QYXRoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgRXhwZWN0ZWQgYSBjaGVja291dCBvZiAke3NvdXJjZVVSTH0gYXQgJHtyZXBvUGF0aH0sIHRoZXJlIGlzIG5vbmUuXFxuYFxuICAgICAgICAgICAgKyBgUnVuIFxcYHlhcm4gc2VjdXJlc3NoIHVwZGF0ZVxcYCB0byBwdXQgaXQgYmFjay5gXG4gICAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB7IHJlcG9QYXRoLCBzb3VyY2VVUkwgfTtcbn1cblxubGV0IGxhc3RSZXZva2VTeW5jID0gMDtcblxuLyoqIFB1bGxlZCBhdCBtb3N0IG9uY2UgYSBSRVZPS0VfU1lOQ19JTlRFUlZBTCwgYmVjYXVzZSB0aGlzIGlzIGFza2VkIHBlciByZXF1ZXN0LiBBIHN5bmMgdGhhdFxuICAgIGZhaWxzIGxlYXZlcyB0aGUgY2hlY2tvdXQgd2UgYWxyZWFkeSBoYXZlLCB3aGljaCBpcyB0aGUgc2FmZSBkaXJlY3Rpb246IHJldm9jYXRpb25zIHdlIGtub3dcbiAgICBhYm91dCBzdGF5IGtub3duLiAqL1xuYXN5bmMgZnVuY3Rpb24gc3luY1Jldm9jYXRpb25zKHNvdXJjZVVSTDogc3RyaW5nKSB7XG4gICAgaWYgKERhdGUubm93KCkgLSBsYXN0UmV2b2tlU3luYyA8IFJFVk9LRV9TWU5DX0lOVEVSVkFMKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGFzdFJldm9rZVN5bmMgPSBEYXRlLm5vdygpO1xuICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHN5bmNSZXBvRmlsZXMocmV2b2tlUmVwbyhzb3VyY2VVUkwpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBDb3VsZCBub3QgcmVhZCAke3Jldm9rZVJlcG9VUkwoc291cmNlVVJMKX0sIHVzaW5nIHRoZSByZXZvY2F0aW9ucyBhbHJlYWR5IGhlcmUuICR7ZX1gKTtcbiAgICB9XG59XG5cbi8qKiBNYWNoaW5lIHJldm9jYXRpb25zLCByZWFkIG91dCBvZiB0aGUgcmV2b2tlIHJlcG8gdGhlIHNhbWUgd2F5IGtleSByZXZvY2F0aW9ucyBhcmUuICovXG5hc3luYyBmdW5jdGlvbiByZWFkTWFjaGluZVJldm9jYXRpb25zKHNvdXJjZVVSTDogc3RyaW5nKSB7XG4gICAgbGV0IHJlcG8gPSByZXZva2VSZXBvKHNvdXJjZVVSTCk7XG4gICAgbGV0IHJldm9jYXRpb25zOiB7IHJldm9jYXRpb25JZDogc3RyaW5nOyBtYWNoaW5lSWQ6IHN0cmluZzsgaXA6IHN0cmluZyB9W10gPSBbXTtcbiAgICBmb3IgKGxldCBuYW1lIG9mIGF3YWl0IGxpc3RSZXBvRGlyKHJlcG8sIFJFVk9DQVRJT05TX0RJUikpIHtcbiAgICAgICAgaWYgKCFuYW1lLmVuZHNXaXRoKFwiLmpzb25cIikpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgcGFyc2VkID0gSlNPTi5wYXJzZShhd2FpdCByZWFkUmVwb0ZpbGUocmVwbywgcGF0aC5qb2luKFJFVk9DQVRJT05TX0RJUiwgbmFtZSkpIHx8IFwiXCIpO1xuICAgICAgICAgICAgaWYgKHBhcnNlZC5tYWNoaW5lSWQpIHtcbiAgICAgICAgICAgICAgICByZXZvY2F0aW9ucy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgcmV2b2NhdGlvbklkOiBwYXJzZWQucmV2b2NhdGlvbklkIHx8IG5hbWUucmVwbGFjZSgvXFwuanNvbiQvLCBcIlwiKSxcbiAgICAgICAgICAgICAgICAgICAgbWFjaGluZUlkOiBwYXJzZWQubWFjaGluZUlkLFxuICAgICAgICAgICAgICAgICAgICBpcDogcGFyc2VkLmlwIHx8IFwiXCIsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBJZ25vcmluZyB1bnJlYWRhYmxlIHJldm9jYXRpb24gJHtuYW1lfS4gJHtlfWApO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXZvY2F0aW9ucztcbn1cblxuLyoqIFNlbmRzIHRoZSBvbmUgbm90aWZpY2F0aW9uIHRoaXMgZmlsZSBpcyBhbGxvd2VkIHRvIHNlbmQsIHdoZW4gaXQgY2FuLlxuXG4gICAgVGhlIGRhZW1vbiBjb25maWd1cmVzIG5vdGlmaWNhdGlvbnMgb24gc3RhcnR1cCBhbmQgd291bGQgc2ltcGx5IHNlbmQuIFRoaXMgY2FuIGFsc28gcnVuIGluIHNvbWVcbiAgICBvdGhlciBwcm9jZXNzLCB3aGljaCBoYXMgbm90LCBzbyB0aGUgd2ViaG9vayBpcyBwaWNrZWQgdXAgaGVyZSBpZiBpdCBpcyByZWFkYWJsZS4gQSBtYWNoaW5lXG4gICAgd2l0aCBubyB3ZWJob29rIHNldCB1cCBzdGlsbCByZWNvcmRzIHRoZSByZXZvY2F0aW9uIC0gYmVpbmcgdW5hYmxlIHRvIHRlbGwgYW55b25lIGlzIG5vdCBhXG4gICAgcmVhc29uIHRvIGtlZXAgYWNjZXB0aW5nIGEgbWFjaGluZSB0aGF0IGlzIGJlaW5nIG1pc3VzZWQuICovXG5hc3luYyBmdW5jdGlvbiBub3RpZnlCZXN0RWZmb3J0KGhlYWRsaW5lOiBzdHJpbmcsIGJvZHk6IHN0cmluZykge1xuICAgIHRyeSB7XG4gICAgICAgIGlmICghYXJlRGlzY29yZE5vdGlmaWNhdGlvbnNDb25maWd1cmVkKCkpIHtcbiAgICAgICAgICAgIC8vIFJlYWQgZmlyc3Q6IGNvbmZpZ3VyZURpc2NvcmROb3RpZmljYXRpb25zIGV4aXRzIHRoZSBwcm9jZXNzIHdoZW4gdGhlIGZpbGUgaXMgbWlzc2luZyxcbiAgICAgICAgICAgIC8vIHdoaWNoIGlzIHJpZ2h0IGZvciB0aGUgZGFlbW9uIGF0IHN0YXJ0dXAgYW5kIHdyb25nIGZvciBhIGxpYnJhcnkgY2FsbC5cbiAgICAgICAgICAgIGF3YWl0IGZzLnJlYWRGaWxlKERFRkFVTFRfV0VCSE9PS19GSUxFX1BBVEgsIFwidXRmOFwiKTtcbiAgICAgICAgICAgIGF3YWl0IGNvbmZpZ3VyZURpc2NvcmROb3RpZmljYXRpb25zKHsgZmlsZVBhdGg6IERFRkFVTFRfV0VCSE9PS19GSUxFX1BBVEggfSk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgbm90aWZ5KGhlYWRsaW5lLCBib2R5KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBDb3VsZCBub3Qgc2VuZCBhIG5vdGlmaWNhdGlvbiBhYm91dCB0aGlzLCBpdCBpcyBvbmx5IGluIHRoZSBsb2cuICR7ZX1gKTtcbiAgICB9XG59XG5cbi8qKiBSZWNvcmRzIHRoYXQgYSBtYWNoaW5lIHdlIGFjY2VwdCB0YWxrZWQgdG8gdXMgZnJvbSBhbiBhZGRyZXNzIGl0IGlzIG5vdCBhbGxvd2VkIGZyb20uIE9uZSBwZXJcbiAgICBtYWNoaW5lIGFuZCBhZGRyZXNzLCBzbyBhIHNlY29uZCBhZGRyZXNzIGlzIGEgc2Vjb25kIHJldm9jYXRpb24gYW5kIGFuIHVucmV2b2tlIG9mIHRoZSBmaXJzdFxuICAgIGRvZXMgbm90IGNvdmVyIGl0LiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVjb3JkTWFjaGluZVJldm9jYXRpb24oY29uZmlnOiB7XG4gICAgc291cmNlVVJMOiBzdHJpbmc7XG4gICAgbWFjaGluZUlkOiBzdHJpbmc7XG4gICAgaXA6IHN0cmluZztcbiAgICBob3N0TGFiZWw6IHN0cmluZztcbn0pIHtcbiAgICBsZXQgeyBzb3VyY2VVUkwsIG1hY2hpbmVJZCwgaXAsIGhvc3RMYWJlbCB9ID0gY29uZmlnO1xuICAgIGxldCByZXBvUGF0aCA9IHJldm9rZVJlcG9QYXRoKHNvdXJjZVVSTCk7XG4gICAgbGV0IGtleVBhdGggPSBhd2FpdCBlbnN1cmVSZXZva2VLZXkoc291cmNlVVJMKTtcbiAgICBsZXQgcmV2b2NhdGlvbklkID0gbmV3UmV2b2NhdGlvbklkKG1hY2hpbmVJZCk7XG4gICAgbGV0IGRpcmVjdG9yeSA9IHBhdGguam9pbihyZXBvUGF0aCwgUkVWT0NBVElPTlNfRElSKTtcbiAgICBhd2FpdCBmcy5ta2RpcihkaXJlY3RvcnksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgIGF3YWl0IGZzLndyaXRlRmlsZShwYXRoLmpvaW4oZGlyZWN0b3J5LCBgJHtyZXZvY2F0aW9uSWR9Lmpzb25gKSwgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICByZXZvY2F0aW9uSWQsXG4gICAgICAgIG1hY2hpbmVJZCxcbiAgICAgICAgaXAsXG4gICAgICAgIHJldm9rZWRBdDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICByZXZva2VkQnk6IGhvc3RMYWJlbCxcbiAgICAgICAgcmVhc29uOiBSRVZPQ0FUSU9OX1JFQVNPTixcbiAgICB9LCB1bmRlZmluZWQsIDQpICsgXCJcXG5cIik7XG5cbiAgICBhd2FpdCBydW5HaXQoeyBhcmdzOiBbXCJhZGRcIiwgXCItQVwiXSwgY3dkOiByZXBvUGF0aCwga2V5UGF0aCB9KTtcbiAgICBhd2FpdCBydW5HaXQoe1xuICAgICAgICBhcmdzOiBbXCItY1wiLCBcInVzZXIuZW1haWw9cG9ydHNlY3VyZUBsb2NhbGhvc3RcIiwgXCItY1wiLCBcInVzZXIubmFtZT1wb3J0c2VjdXJlXCIsIFwiY29tbWl0XCIsIFwiLW1cIiwgYHJldm9rZSAke3Jldm9jYXRpb25JZH1gXSxcbiAgICAgICAgY3dkOiByZXBvUGF0aCwga2V5UGF0aCxcbiAgICB9KTtcbiAgICBsZXQgcHVzaCA9IGF3YWl0IHJ1bkdpdCh7IGFyZ3M6IFtcInB1c2hcIiwgXCJvcmlnaW5cIiwgXCJIRUFEXCJdLCBjd2Q6IHJlcG9QYXRoLCBrZXlQYXRoLCBhbGxvd0ZhaWx1cmU6IHRydWUgfSk7XG4gICAgaWYgKHB1c2guc3RhdHVzICE9PSAwKSB7XG4gICAgICAgIC8vIEFub3RoZXIgbWFjaGluZSBtb3N0IGxpa2VseSByZWNvcmRlZCB0aGUgc2FtZSB0aGluZyBmaXJzdCwgYW5kIHRoZSBuZXh0IHJlYWQgcGlja3MgaXQgdXAuXG4gICAgICAgIGNvbnNvbGUubG9nKGBDb3VsZCBub3QgcHVzaCB0aGUgcmV2b2NhdGlvbiBvZiAke21hY2hpbmVJZH0gZnJvbSAke2lwfS4gJHsocHVzaC5zdGRvdXQgKyBwdXNoLnN0ZGVycikudHJpbSgpfWApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKGBSZXZva2VkICR7bWFjaGluZUlkfSBmcm9tICR7aXB9LCAke3Jldm9jYXRpb25JZH1gKTtcblxuICAgIC8vIFNhaWQgYnkgd2hvZXZlciB3cm90ZSB0aGUgcmV2b2NhdGlvbiwgb25jZSwgdGhlIHNhbWUgYXMgZm9yIGFuIHNzaCBrZXkuIE1hY2hpbmVzIHRoYXQgb25seVxuICAgIC8vIHJlYWQgaXQgbGF0ZXIgc2F5IG5vdGhpbmcsIG9yIG9uZSBldmVudCB3b3VsZCBiZSByZXBvcnRlZCBieSBldmVyeSBtYWNoaW5lIHRoYXQgc2F3IGl0LlxuICAgIGF3YWl0IG5vdGlmeUJlc3RFZmZvcnQoXG4gICAgICAgIGBTVVNQSUNJT1VTIElQICR7aXB9IEZST1pFIE1BQ0hJTkUgJHttYWNoaW5lSWR9YCxcbiAgICAgICAgYEEgbWFjaGluZSB3ZSB0cnVzdCB0YWxrZWQgdG8gdXMgZnJvbSAke2lwfSwgd2hpY2ggaXMgbm90IGFuIGFkZHJlc3MgaXQgaXMgYWxsb3dlZCB0byB0YWxrYFxuICAgICAgICArIGAgZnJvbS4gSXQgcHJvdmVkIGl0IGhvbGRzIHRoYXQgbWFjaGluZSdzIGtleSwgc28gZWl0aGVyIHNvbWVvbmUgZWxzZSBoYXMgYSBjb3B5IG9mIGl0LGBcbiAgICAgICAgKyBgIG9yIHRoYXQgbWFjaGluZSdzIGFkZHJlc3MgY2hhbmdlZC5gXG4gICAgICAgICsgYFxcblxcbkl0IGlzIGZyb3plbiBldmVyeXdoZXJlIG5vdywgYW5kIG5vdGhpbmcgYWNjZXB0cyBpdC5gXG4gICAgICAgICsgYFxcblxcbklmIHRoaXMgd2FzIGFuIGF0dGFjaywgcmVtb3ZlIFxcYG1hY2hpbmVzLyR7bWFjaGluZUlkfS5qc29uXFxgIGZyb20gXFxgJHtzb3VyY2VVUkx9XFxgIG5vdy5gXG4gICAgICAgICsgYFxcbklmIGl0IHdhcyBsZWdpdGltYXRlLCBydW4gXFxgeWFybiB1bnJldm9rZSBnaXRcXGAgaW4gdGhhdCByZXBvLiBJdCBhbGxvd3MgJHtpcH0gZm9yIHRoYXRgXG4gICAgICAgICsgYCBtYWNoaW5lLCBhbmQgdGFrZXMgYW4gaG91ciB0byByZWFjaCBldmVyeSBtYWNoaW5lLmBcbiAgICAgICAgKyBgXFxuXFxubWFjaGluZTogXFxgJHttYWNoaW5lSWR9XFxgYFxuICAgICAgICArIGBcXG5mcm96ZW4gYnk6IFxcYCR7aG9zdExhYmVsfVxcYGBcbiAgICApO1xufVxuXG4vKiogV2hldGhlciB3ZSB3aWxsIHRhbGsgdG8gdGhpcyBtYWNoaW5lLCBjb21pbmcgZnJvbSB0aGlzIGFkZHJlc3MuXG5cbiAgICBCb3RoIGhhbHZlcyBhcmUgcmVxdWlyZWQgYW5kIG5laXRoZXIgaXMgYSBndWVzczogdGhlIGNhbGxlciBrbm93cyB0aGUgbWFjaGluZSBpZCBiZWNhdXNlIHRoZVxuICAgIGNvbm5lY3Rpb24gcHJvdmVkIGl0LCBhbmQga25vd3MgdGhlIGFkZHJlc3MgYmVjYXVzZSB0aGUgcGFja2V0cyBjYW1lIGZyb20gdGhlcmUuIEEgbWFjaGluZSB3ZVxuICAgIGRvIG5vdCBsaXN0IGlzIHNpbXBseSBub3QgYWNjZXB0ZWQuIEEgbWFjaGluZSB3ZSBkbyBsaXN0LCBhcnJpdmluZyBmcm9tIGFuIGFkZHJlc3MgaXQgZG9lcyBub3RcbiAgICBoYXZlLCBpcyB0cmVhdGVkIGFzIHRoZSBzYW1lIGtpbmQgb2YgZXZlbnQgYXMgYSBzdG9sZW4gc3NoIGtleSAtIGl0IGlzIHJldm9rZWQgZXZlcnl3aGVyZSwgYW5kXG4gICAgc3RheXMgcmV2b2tlZCB1bnRpbCBhbiB1bnJldm9rZSBhbGxvd3MgdGhhdCBtYWNoaW5lIGZyb20gdGhhdCBhZGRyZXNzLlxuXG4gICAgVGhyb3dzIHdoZW4gdGhlIHJlcG8gaXRzZWxmIGNhbm5vdCBiZSByZWFkIG9yIGlzIG5vdCBzaWduZWQsIHJhdGhlciB0aGFuIGFuc3dlcmluZyBmYWxzZTogdGhhdFxuICAgIGlzIGEgYnJva2VuIGluc3RhbGxhdGlvbiwgbm90IGEgcmVqZWN0ZWQgbWFjaGluZSwgYW5kIHRoZSB0d28gZGVzZXJ2ZSBkaWZmZXJlbnQgaGFuZGxpbmcuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaXNNYWNoaW5lQWNjZXB0ZWQoY29uZmlnOiB7IG1hY2hpbmVJZDogc3RyaW5nOyBpcDogc3RyaW5nIH0pOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBsZXQgeyBtYWNoaW5lSWQsIGlwIH0gPSBjb25maWc7XG4gICAgaWYgKCFtYWNoaW5lSWQgfHwgIWlwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgYSBtYWNoaW5lSWQgYW5kIGFuIGlwLCB3YXMgJHtKU09OLnN0cmluZ2lmeShtYWNoaW5lSWQpfSBhbmQgJHtKU09OLnN0cmluZ2lmeShpcCl9YCk7XG4gICAgfVxuICAgIGxldCB7IHJlcG9QYXRoLCBzb3VyY2VVUkwgfSA9IGF3YWl0IHJlc29sdmVLZXlzUmVwbygpO1xuICAgIC8vIFVuc2lnbmVkLCBvciBzaWduZWQgb3ZlciBkaWZmZXJlbnQgY29udGVudHMsIG1lYW5zIHRoZSBtYWNoaW5lIGxpc3QgaXMgbm90IGV2aWRlbmNlIG9mXG4gICAgLy8gYW55dGhpbmcuIFNhbWUgZ2F0ZSB0aGUgc3NoIGtleXMgZ28gdGhyb3VnaC5cbiAgICBhd2FpdCB2ZXJpZnlDaGVja291dChyZXBvUGF0aCk7XG5cbiAgICBsZXQgbWFjaGluZSA9IChhd2FpdCByZWFkTWFjaGluZXMocmVwb1BhdGgpKS5nZXQobWFjaGluZUlkKTtcbiAgICBpZiAoIW1hY2hpbmUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGF3YWl0IHN5bmNSZXZvY2F0aW9ucyhzb3VyY2VVUkwpO1xuICAgIGxldCB1bnJldm9rZXMgPSBhd2FpdCByZWFkVW5yZXZva2VzKHNvdXJjZVVSTCkuY2F0Y2goKCkgPT4gKHsgcGFpcnM6IG5ldyBNYXAoKSwgbGVnYWN5SWRzOiBuZXcgTWFwKCkgfSkpO1xuICAgIC8vIEFuIHVucmV2b2tlIGlzIG9ubHkgaG9ub3VyZWQgb25jZSBpdCBoYXMgd2FpdGVkIG91dCBpdHMgaG91ciwgZXhhY3RseSBhcyBhbiBzc2gga2V5J3MgaXMuXG4gICAgbGV0IGFsbG93ZWRBZ2FpbiA9IGFzeW5jIChwYWlyOiBzdHJpbmcpID0+IHtcbiAgICAgICAgbGV0IHVucmV2b2tlSWQgPSB1bnJldm9rZXMucGFpcnMuZ2V0KHBhaXIpO1xuICAgICAgICByZXR1cm4gISF1bnJldm9rZUlkICYmIGF3YWl0IHVucmV2b2tlSW5FZmZlY3QodW5yZXZva2VJZCk7XG4gICAgfTtcbiAgICBsZXQgcmV2b2NhdGlvbnMgPSBhd2FpdCByZWFkTWFjaGluZVJldm9jYXRpb25zKHNvdXJjZVVSTCk7XG4gICAgLy8gQW55IHJldm9jYXRpb24gbm90aGluZyBoYXMgdW5kb25lIGtlZXBzIHRoZSBtYWNoaW5lIG91dCwgZnJvbSBldmVyeXdoZXJlLCB0aGUgd2F5IGEgcmV2b2tlZFxuICAgIC8vIHNzaCBrZXkgaXMgb3V0IGV2ZXJ5d2hlcmUgcmF0aGVyIHRoYW4gb25seSBmcm9tIHRoZSBhZGRyZXNzIGl0IHdhcyBtaXN1c2VkIGZyb20uXG4gICAgbGV0IHJldm9rZWQgPSBmYWxzZTtcbiAgICBmb3IgKGxldCByZXZvY2F0aW9uIG9mIHJldm9jYXRpb25zKSB7XG4gICAgICAgIGlmIChyZXZvY2F0aW9uLm1hY2hpbmVJZCAhPT0gbWFjaGluZUlkKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWF3YWl0IGFsbG93ZWRBZ2FpbihwYWlyS2V5KHsgZmluZ2VycHJpbnQ6IHJldm9jYXRpb24ubWFjaGluZUlkLCBpcDogcmV2b2NhdGlvbi5pcCB9KSkpIHtcbiAgICAgICAgICAgIHJldm9rZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChyZXZva2VkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAobWFjaGluZS5pcHMuaW5jbHVkZXMoaXApKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIExpc3RlZCwgYnV0IHRhbGtpbmcgdG8gdXMgZnJvbSBzb21ld2hlcmUgaXQgc2hvdWxkIG5vdCBiZS4gUmVjb3JkZWQgb25jZSBmb3IgdGhpcyBtYWNoaW5lXG4gICAgLy8gYW5kIGFkZHJlc3MsIHNvIGJlaW5nIHRhbGtlZCB0byByZXBlYXRlZGx5IGRvZXMgbm90IHdyaXRlIHJlcGVhdGVkbHkuXG4gICAgbGV0IHBhaXIgPSBwYWlyS2V5KHsgZmluZ2VycHJpbnQ6IG1hY2hpbmVJZCwgaXAgfSk7XG4gICAgbGV0IGFscmVhZHlSZWNvcmRlZCA9IHJldm9jYXRpb25zLnNvbWUocmV2b2NhdGlvbiA9PlxuICAgICAgICBwYWlyS2V5KHsgZmluZ2VycHJpbnQ6IHJldm9jYXRpb24ubWFjaGluZUlkLCBpcDogcmV2b2NhdGlvbi5pcCB9KSA9PT0gcGFpcik7XG4gICAgaWYgKCFhbHJlYWR5UmVjb3JkZWQgJiYgIWF3YWl0IGFsbG93ZWRBZ2FpbihwYWlyKSkge1xuICAgICAgICBhd2FpdCByZWNvcmRNYWNoaW5lUmV2b2NhdGlvbih7IHNvdXJjZVVSTCwgbWFjaGluZUlkLCBpcCwgaG9zdExhYmVsOiBvcy5ob3N0bmFtZSgpIH0pO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG4iXX0=
322
- /* _JS_SOURCE_HASH = "42ec23e7ee1a7879769634b3b36b652f35e6140757988d443d15d7a3a5d4adec"; */
263
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFjaGluZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtYWNoaW5lcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSwyREFBNkI7QUFDN0IsNENBQW9CO0FBQ3BCLGdEQUF3QjtBQUN4Qix5REFBNkQ7QUFDN0Qsa0VBQStFO0FBQy9FLGtFQUErRTtBQUMvRSxvRUFBbUg7QUFDbkgsc0RBQXNEO0FBQ3RELGtFQUFxRTtBQUNyRSwwREFBZ0U7QUFDaEUsaUVBQStFO0FBQy9FLDREQUF5RDtBQUN6RCxzREFBdUk7QUFHdkksbUdBQW1HO0FBQ25HLGlHQUFpRztBQUNqRyxnRUFBZ0U7QUFDbkQsUUFBQSxZQUFZLEdBQUcsVUFBVSxDQUFDO0FBQ3ZDLE1BQU0sZUFBZSxHQUFHLGFBQWEsQ0FBQztBQUN0QyxNQUFNLGlCQUFpQixHQUFHLDhDQUE4QyxDQUFDO0FBQ3pFLGdHQUFnRztBQUNoRyxtQ0FBbUM7QUFDbkMsTUFBTSxvQkFBb0IsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBU3ZDLEtBQUssVUFBVSxVQUFVLENBQUMsUUFBZ0I7SUFDdEMsSUFBSSxDQUFDO1FBQ0QsTUFBTSxrQkFBRSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMxQixPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUNULE9BQU8sS0FBSyxDQUFDO0lBQ2pCLENBQUM7QUFDTCxDQUFDO0FBRUQsU0FBUyxlQUFlLENBQUMsUUFBZ0IsRUFBRSxTQUFpQjtJQUN4RCxPQUFPLGNBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLG9CQUFZLEVBQUUsR0FBRyxTQUFTLE9BQU8sQ0FBQyxDQUFDO0FBQ2xFLENBQUM7QUFFRCxzQ0FBc0M7QUFDL0IsS0FBSyxVQUFVLFdBQVcsQ0FBQyxRQUFnQjtJQUM5QyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMs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cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGZzIGZyb20gXCJmcy9wcm9taXNlc1wiO1xuaW1wb3J0IG9zIGZyb20gXCJvc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IHJlc29sdmVLZXlzUmVwbyB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5cy9rZXlzUmVwb1wiO1xuaW1wb3J0IHsgcmV2b2tlUmVwbywgc3luY1JlcG9GaWxlcyB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5cy9kYWVtb24vcmVwb0ZpbGVzXCI7XG5pbXBvcnQgeyBsaXN0UmVwb0RpciwgcmVhZFJlcG9GaWxlIH0gZnJvbSBcIi4uL2F1dGhvcml6ZWRLZXlzL2RhZW1vbi9yZXBvRmlsZXNcIjtcbmltcG9ydCB7IG5ld1Jldm9jYXRpb25JZCwgcGFpcktleSwgcmVhZFJldm9jYXRpb25GaWxlcywgcmVhZFVucmV2b2tlcyB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5cy9kYWVtb24vcmV2b2NhdGlvblwiO1xuaW1wb3J0IHsgcnVuR2l0IH0gZnJvbSBcIi4uL2F1dGhvcml6ZWRLZXlzL2RhZW1vbi9naXRcIjtcbmltcG9ydCB7IGVuc3VyZVJldm9rZUtleSB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5cy9kYWVtb24vcmVwb0ZpbGVzXCI7XG5pbXBvcnQgeyB2ZXJpZnlDaGVja291dCB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5cy9kYWVtb24vdHJ1c3RcIjtcbmltcG9ydCB7IHJldm9rZVJlcG9QYXRoLCByZXZva2VSZXBvVVJMIH0gZnJvbSBcIi4uL2F1dGhvcml6ZWRLZXlzL3Jldm9rZVNvdXJjZVwiO1xuaW1wb3J0IHsgbm90aWZ5IH0gZnJvbSBcIi4uL2F1dGhvcml6ZWRLZXlzL2RhZW1vbi9ub3RpZnlcIjtcbmltcG9ydCB7IGFyZURpc2NvcmROb3RpZmljYXRpb25zQ29uZmlndXJlZCwgY29uZmlndXJlRGlzY29yZE5vdGlmaWNhdGlvbnMsIERFRkFVTFRfV0VCSE9PS19GSUxFX1BBVEggfSBmcm9tIFwiLi4vbm90aWZpY2F0aW9ucy9kaXNjb3JkXCI7XG5pbXBvcnQgeyBzcGF3blByb21pc2UgfSBmcm9tIFwiLi4vaGVscGVycy9zcGF3blwiO1xuXG4vLyBXaGljaCBtYWNoaW5lcyB0aGlzIHN5c3RlbSB0YWxrcyB0bywga2VwdCBpbiB0aGUgc2FtZSByZXBvIGFzIHRoZSBzc2gga2V5cy4gVGhhdCByZXBvIGlzIGFscmVhZHlcbi8vIHNpZ25lZCwgYWxyZWFkeSBkaXN0cmlidXRlZCB0byBldmVyeSBtYWNoaW5lLCBhbmQgYWxyZWFkeSBoYXMgc29tZXdoZXJlIHRvIHJlY29yZCBhIHJlamVjdGlvbixcbi8vIHNvIGEgc2Vjb25kIG9uZSB3b3VsZCBvbmx5IGJlIGEgc2Vjb25kIHRoaW5nIHRvIGtlZXAgaW4gc3RlcC5cbmV4cG9ydCBjb25zdCBNQUNISU5FU19ESVIgPSBcIm1hY2hpbmVzXCI7XG5jb25zdCBSRVZPQ0FUSU9OU19ESVIgPSBcInJldm9jYXRpb25zXCI7XG5jb25zdCBSRVZPQ0FUSU9OX1JFQVNPTiA9IFwiYSBtYWNoaW5lIHRhbGtlZCB0byB1cyBmcm9tIGFuIHVuYXBwcm92ZWQgSVBcIjtcbi8vIFRoZSByZXZva2UgcmVwbyBpcyBwdWxsZWQgYXQgbW9zdCB0aGlzIG9mdGVuLiBBIGNoZWNrIGhhcHBlbnMgcGVyIHJlcXVlc3QsIGFuZCBhIHJlcXVlc3QgbXVzdFxuLy8gbm90IGNvc3QgYSByb3VuZCB0cmlwIHRvIGdpdGh1Yi5cbmNvbnN0IFJFVk9LRV9TWU5DX0lOVEVSVkFMID0gNjAgKiAxMDAwO1xuXG4vKiogT25lIG1hY2hpbmUgd2UgYXJlIHdpbGxpbmcgdG8gdGFsayB0bywgYW5kIHRoZSBhZGRyZXNzZXMgaXQgbWF5IHRhbGsgdG8gdXMgZnJvbS4gKi9cbmV4cG9ydCB0eXBlIE1hY2hpbmVTdGF0ZSA9IHtcbiAgICBtYWNoaW5lSWQ6IHN0cmluZztcbiAgICBpcHM6IHN0cmluZ1tdO1xuICAgIGFkZGVkQXQ6IHN0cmluZztcbn07XG5cbmFzeW5jIGZ1bmN0aW9uIHBhdGhFeGlzdHMoZmlsZVBhdGg6IHN0cmluZykge1xuICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGZzLmFjY2VzcyhmaWxlUGF0aCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gbWFjaGluZUZpbGVQYXRoKHJlcG9QYXRoOiBzdHJpbmcsIG1hY2hpbmVJZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHBhdGguam9pbihyZXBvUGF0aCwgTUFDSElORVNfRElSLCBgJHttYWNoaW5lSWR9Lmpzb25gKTtcbn1cblxuLyoqIEV2ZXJ5IG1hY2hpbmUgYSBjaGVja291dCBsaXN0cy4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRNYWNoaW5lcyhyZXBvUGF0aDogc3RyaW5nKTogUHJvbWlzZTxNYWNoaW5lU3RhdGVbXT4ge1xuICAgIHJldHVybiBbLi4uKGF3YWl0IHJlYWRNYWNoaW5lcyhyZXBvUGF0aCkpLnZhbHVlcygpXTtcbn1cblxuLyoqIE1ha2VzIGEgY2hlY2tvdXQgbGlzdCBleGFjdGx5IHRoZXNlIG1hY2hpbmVzOiB0aG9zZSBuYW1lZCBhcmUgd3JpdHRlbiB3aXRoIHRoZSBhZGRyZXNzZXMgZ2l2ZW4sXG4gICAgYW5kIGFueXRoaW5nIG5vdCBuYW1lZCBpcyByZW1vdmVkLiBTbyByZWFkIHRoZW0sIGNoYW5nZSB3aGF0IHlvdSB3YW50LCBhbmQgd3JpdGUgdGhlIHJlc3VsdC5cblxuICAgIFRoZSBhZGRyZXNzZXMgYXJlIHBhcnQgb2Ygc2V0dGluZyByYXRoZXIgdGhhbiBhIHNlcGFyYXRlIHN0ZXAsIGJlY2F1c2UgYSBtYWNoaW5lIHdpdGggbm9cbiAgICBhZGRyZXNzIGl0IG1heSB0YWxrIGZyb20gaXMgbm90IGEgbWFjaGluZSB0aGF0IHdvdWxkIGV2ZXIgYmUgYWNjZXB0ZWQgLSB0aGVyZSBpcyBubyBzdGF0ZSB3aGVyZVxuICAgIG5hbWluZyBvbmUgd2l0aG91dCB0aGVtIG1lYW5zIGFueXRoaW5nLlxuXG4gICAgTm90aGluZyBoZXJlIHNpZ25zIG9yIGNvbW1pdHMuIFRoZSBzaWduYXR1cmUgaXMgd2hhdCBldmVyeSBvdGhlciBtYWNoaW5lIGNoZWNrcyBiZWZvcmVcbiAgICBiZWxpZXZpbmcgYW55IG9mIHRoaXMsIGFuZCBpdCB0YWtlcyB0aGUgaGFyZHdhcmUga2V5LCBzbyBgeWFybiBzaWduZmlsZXMgZ2l0YCBpcyBzdGlsbCB5b3VycyB0b1xuICAgIHJ1biBhZnRlcndhcmRzLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNldE1hY2hpbmVzKGNvbmZpZzoge1xuICAgIHJlcG9QYXRoOiBzdHJpbmc7XG4gICAgbWFjaGluZXM6IHsgbWFjaGluZUlkOiBzdHJpbmc7IGlwczogc3RyaW5nW10gfVtdO1xufSk6IFByb21pc2U8TWFjaGluZVN0YXRlW10+IHtcbiAgICBsZXQgeyByZXBvUGF0aCwgbWFjaGluZXMgfSA9IGNvbmZpZztcbiAgICBsZXQgZXhpc3RpbmcgPSBhd2FpdCByZWFkTWFjaGluZXMocmVwb1BhdGgpO1xuICAgIGxldCBkaXJlY3RvcnkgPSBwYXRoLmpvaW4ocmVwb1BhdGgsIE1BQ0hJTkVTX0RJUik7XG4gICAgbGV0IHdyaXR0ZW46IE1hY2hpbmVTdGF0ZVtdID0gW107XG4gICAgZm9yIChsZXQgbWFjaGluZSBvZiBtYWNoaW5lcykge1xuICAgICAgICBpZiAoIW1hY2hpbmUubWFjaGluZUlkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGEgbWFjaGluZUlkLCB3YXMgJHtKU09OLnN0cmluZ2lmeShtYWNoaW5lLm1hY2hpbmVJZCl9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFtYWNoaW5lLmlwcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBgRXhwZWN0ZWQgYWRkcmVzc2VzIGZvciAke21hY2hpbmUubWFjaGluZUlkfSwgd2FzIG5vbmUuIEEgbWFjaGluZSBpcyB0cnVzdGVkIGZyb21gXG4gICAgICAgICAgICAgICAgKyBgIHRoZSBhZGRyZXNzZXMgaXQgbWF5IHRhbGsgZnJvbSwgc28gbGVhdmUgaXQgb3V0IG9mIHRoZSBsaXN0IHRvIHJlbW92ZSBpdC5gXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGxldCBpcHMgPSBtYWNoaW5lLmlwcy5maWx0ZXIoKGlwLCBpbmRleCkgPT4gaXAgJiYgbWFjaGluZS5pcHMuaW5kZXhPZihpcCkgPT09IGluZGV4KTtcbiAgICAgICAgbGV0IHN0YXRlOiBNYWNoaW5lU3RhdGUgPSB7XG4gICAgICAgICAgICBtYWNoaW5lSWQ6IG1hY2hpbmUubWFjaGluZUlkLFxuICAgICAgICAgICAgLy8gSW4gdGhlIG9yZGVyIGdpdmVuLCB3aXRob3V0IGR1cGxpY2F0ZXMsIHNvIHRoZSBmaWxlIHJlYWRzIHRoZSB3YXkgaXQgd2FzIHNldC5cbiAgICAgICAgICAgIGlwcyxcbiAgICAgICAgICAgIGFkZGVkQXQ6IGV4aXN0aW5nLmdldChtYWNoaW5lLm1hY2hpbmVJZCk/LmFkZGVkQXQgfHwgbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICB9O1xuICAgICAgICBhd2FpdCBmcy5ta2RpcihkaXJlY3RvcnksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgICBhd2FpdCBmcy53cml0ZUZpbGUobWFjaGluZUZpbGVQYXRoKHJlcG9QYXRoLCBzdGF0ZS5tYWNoaW5lSWQpLCBKU09OLnN0cmluZ2lmeShzdGF0ZSwgdW5kZWZpbmVkLCA0KSArIFwiXFxuXCIpO1xuICAgICAgICB3cml0dGVuLnB1c2goc3RhdGUpO1xuICAgIH1cblxuICAgIC8vIFdoYXRldmVyIHRoZSByZXBvIGhhZCBhbmQgdGhlIGNhbGxlciBkaWQgbm90IG5hbWUgaXMgbm8gbG9uZ2VyIHRydXN0ZWQuXG4gICAgZm9yIChsZXQgbWFjaGluZUlkIG9mIGV4aXN0aW5nLmtleXMoKSkge1xuICAgICAgICBpZiAoIW1hY2hpbmVzLnNvbWUobWFjaGluZSA9PiBtYWNoaW5lLm1hY2hpbmVJZCA9PT0gbWFjaGluZUlkKSkge1xuICAgICAgICAgICAgYXdhaXQgZnMucm0obWFjaGluZUZpbGVQYXRoKHJlcG9QYXRoLCBtYWNoaW5lSWQpLCB7IGZvcmNlOiB0cnVlIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB3cml0dGVuO1xufVxuXG4vKiogRXZlcnkgbWFjaGluZSB0aGUgcmVwbyBsaXN0cy4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlYWRNYWNoaW5lcyhyZXBvUGF0aDogc3RyaW5nKSB7XG4gICAgbGV0IG1hY2hpbmVzID0gbmV3IE1hcDxzdHJpbmcsIE1hY2hpbmVTdGF0ZT4oKTtcbiAgICBsZXQgZGlyZWN0b3J5ID0gcGF0aC5qb2luKHJlcG9QYXRoLCBNQUNISU5FU19ESVIpO1xuICAgIGxldCBuYW1lcyA9IGF3YWl0IGZzLnJlYWRkaXIoZGlyZWN0b3J5KS5jYXRjaCgoKSA9PiBbXSBhcyBzdHJpbmdbXSk7XG4gICAgZm9yIChsZXQgbmFtZSBvZiBuYW1lcy5zb3J0KCkpIHtcbiAgICAgICAgaWYgKCFuYW1lLmVuZHNXaXRoKFwiLmpzb25cIikpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgcGFyc2VkID0gSlNPTi5wYXJzZShhd2FpdCBmcy5yZWFkRmlsZShwYXRoLmpvaW4oZGlyZWN0b3J5LCBuYW1lKSwgXCJ1dGY4XCIpKTtcbiAgICAgICAgICAgIGxldCBtYWNoaW5lSWQgPSBwYXJzZWQubWFjaGluZUlkIHx8IG5hbWUucmVwbGFjZSgvXFwuanNvbiQvLCBcIlwiKTtcbiAgICAgICAgICAgIG1hY2hpbmVzLnNldChtYWNoaW5lSWQsIHsgbWFjaGluZUlkLCBpcHM6IHBhcnNlZC5pcHMgfHwgW10sIGFkZGVkQXQ6IHBhcnNlZC5hZGRlZEF0IHx8IFwiXCIgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBJZ25vcmluZyB1bnJlYWRhYmxlIG1hY2hpbmUgZmlsZSAke25hbWV9LiAke2V9YCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hY2hpbmVzO1xufVxuXG5sZXQgbGFzdFJldm9rZVN5bmMgPSAwO1xuXG4vKiogUHVsbGVkIGF0IG1vc3Qgb25jZSBhIFJFVk9LRV9TWU5DX0lOVEVSVkFMLCBiZWNhdXNlIHRoaXMgaXMgYXNrZWQgcGVyIHJlcXVlc3QuIEEgc3luYyB0aGF0XG4gICAgZmFpbHMgbGVhdmVzIHRoZSBjaGVja291dCB3ZSBhbHJlYWR5IGhhdmUsIHdoaWNoIGlzIHRoZSBzYWZlIGRpcmVjdGlvbjogcmV2b2NhdGlvbnMgd2Uga25vd1xuICAgIGFib3V0IHN0YXkga25vd24uICovXG5hc3luYyBmdW5jdGlvbiBzeW5jUmV2b2NhdGlvbnMoc291cmNlVVJMOiBzdHJpbmcpIHtcbiAgICBpZiAoRGF0ZS5ub3coKSAtIGxhc3RSZXZva2VTeW5jIDwgUkVWT0tFX1NZTkNfSU5URVJWQUwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsYXN0UmV2b2tlU3luYyA9IERhdGUubm93KCk7XG4gICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc3luY1JlcG9GaWxlcyhyZXZva2VSZXBvKHNvdXJjZVVSTCkpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc29sZS5sb2coYENvdWxkIG5vdCByZWFkICR7cmV2b2tlUmVwb1VSTChzb3VyY2VVUkwpfSwgdXNpbmcgdGhlIHJldm9jYXRpb25zIGFscmVhZHkgaGVyZS4gJHtlfWApO1xuICAgIH1cbn1cblxuLyoqIE1hY2hpbmUgcmV2b2NhdGlvbnMsIHJlYWQgb3V0IG9mIHRoZSByZXZva2UgcmVwbyB0aGUgc2FtZSB3YXkga2V5IHJldm9jYXRpb25zIGFyZS4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlYWRNYWNoaW5lUmV2b2NhdGlvbnMoc291cmNlVVJMOiBzdHJpbmcpIHtcbiAgICBsZXQgcmVwbyA9IHJldm9rZVJlcG8oc291cmNlVVJMKTtcbiAgICBsZXQgcmV2b2NhdGlvbnM6IHsgcmV2b2NhdGlvbklkOiBzdHJpbmc7IG1hY2hpbmVJZDogc3RyaW5nOyBpcDogc3RyaW5nIH1bXSA9IFtdO1xuICAgIGZvciAobGV0IG5hbWUgb2YgYXdhaXQgbGlzdFJlcG9EaXIocmVwbywgUkVWT0NBVElPTlNfRElSKSkge1xuICAgICAgICBpZiAoIW5hbWUuZW5kc1dpdGgoXCIuanNvblwiKSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGxldCBwYXJzZWQgPSBKU09OLnBhcnNlKGF3YWl0IHJlYWRSZXBvRmlsZShyZXBvLCBwYXRoLmpvaW4oUkVWT0NBVElPTlNfRElSLCBuYW1lKSkgfHwgXCJcIik7XG4gICAgICAgICAgICBpZiAocGFyc2VkLm1hY2hpbmVJZCkge1xuICAgICAgICAgICAgICAgIHJldm9jYXRpb25zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICByZXZvY2F0aW9uSWQ6IHBhcnNlZC5yZXZvY2F0aW9uSWQgfHwgbmFtZS5yZXBsYWNlKC9cXC5qc29uJC8sIFwiXCIpLFxuICAgICAgICAgICAgICAgICAgICBtYWNoaW5lSWQ6IHBhcnNlZC5tYWNoaW5lSWQsXG4gICAgICAgICAgICAgICAgICAgIGlwOiBwYXJzZWQuaXAgfHwgXCJcIixcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYElnbm9yaW5nIHVucmVhZGFibGUgcmV2b2NhdGlvbiAke25hbWV9LiAke2V9YCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJldm9jYXRpb25zO1xufVxuXG4vKiogU2VuZHMgdGhlIG9uZSBub3RpZmljYXRpb24gdGhpcyBmaWxlIGlzIGFsbG93ZWQgdG8gc2VuZCwgd2hlbiBpdCBjYW4uXG5cbiAgICBUaGUgZGFlbW9uIGNvbmZpZ3VyZXMgbm90aWZpY2F0aW9ucyBvbiBzdGFydHVwIGFuZCB3b3VsZCBzaW1wbHkgc2VuZC4gVGhpcyBjYW4gYWxzbyBydW4gaW4gc29tZVxuICAgIG90aGVyIHByb2Nlc3MsIHdoaWNoIGhhcyBub3QsIHNvIHRoZSB3ZWJob29rIGlzIHBpY2tlZCB1cCBoZXJlIGlmIGl0IGlzIHJlYWRhYmxlLiBBIG1hY2hpbmVcbiAgICB3aXRoIG5vIHdlYmhvb2sgc2V0IHVwIHN0aWxsIHJlY29yZHMgdGhlIHJldm9jYXRpb24gLSBiZWluZyB1bmFibGUgdG8gdGVsbCBhbnlvbmUgaXMgbm90IGFcbiAgICByZWFzb24gdG8ga2VlcCBhY2NlcHRpbmcgYSBtYWNoaW5lIHRoYXQgaXMgYmVpbmcgbWlzdXNlZC4gKi9cbmFzeW5jIGZ1bmN0aW9uIG5vdGlmeUJlc3RFZmZvcnQoaGVhZGxpbmU6IHN0cmluZywgYm9keTogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKCFhcmVEaXNjb3JkTm90aWZpY2F0aW9uc0NvbmZpZ3VyZWQoKSkge1xuICAgICAgICAgICAgLy8gUmVhZCBmaXJzdDogY29uZmlndXJlRGlzY29yZE5vdGlmaWNhdGlvbnMgZXhpdHMgdGhlIHByb2Nlc3Mgd2hlbiB0aGUgZmlsZSBpcyBtaXNzaW5nLFxuICAgICAgICAgICAgLy8gd2hpY2ggaXMgcmlnaHQgZm9yIHRoZSBkYWVtb24gYXQgc3RhcnR1cCBhbmQgd3JvbmcgZm9yIGEgbGlicmFyeSBjYWxsLlxuICAgICAgICAgICAgYXdhaXQgZnMucmVhZEZpbGUoREVGQVVMVF9XRUJIT09LX0ZJTEVfUEFUSCwgXCJ1dGY4XCIpO1xuICAgICAgICAgICAgYXdhaXQgY29uZmlndXJlRGlzY29yZE5vdGlmaWNhdGlvbnMoeyBmaWxlUGF0aDogREVGQVVMVF9XRUJIT09LX0ZJTEVfUEFUSCB9KTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCBub3RpZnkoaGVhZGxpbmUsIGJvZHkpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc29sZS5sb2coYENvdWxkIG5vdCBzZW5kIGEgbm90aWZpY2F0aW9uIGFib3V0IHRoaXMsIGl0IGlzIG9ubHkgaW4gdGhlIGxvZy4gJHtlfWApO1xuICAgIH1cbn1cblxuLyoqIFJlY29yZHMgdGhhdCBhIG1hY2hpbmUgd2UgYWNjZXB0IHRhbGtlZCB0byB1cyBmcm9tIGFuIGFkZHJlc3MgaXQgaXMgbm90IGFsbG93ZWQgZnJvbS4gT25lIHBlclxuICAgIG1hY2hpbmUgYW5kIGFkZHJlc3MsIHNvIGEgc2Vjb25kIGFkZHJlc3MgaXMgYSBzZWNvbmQgcmV2b2NhdGlvbiBhbmQgYW4gdW5yZXZva2Ugb2YgdGhlIGZpcnN0XG4gICAgZG9lcyBub3QgY292ZXIgaXQuICovXG5hc3luYyBmdW5jdGlvbiByZWNvcmRNYWNoaW5lUmV2b2NhdGlvbihjb25maWc6IHtcbiAgICBzb3VyY2VVUkw6IHN0cmluZztcbiAgICBtYWNoaW5lSWQ6IHN0cmluZztcbiAgICBpcDogc3RyaW5nO1xuICAgIGhvc3RMYWJlbDogc3RyaW5nO1xufSkge1xuICAgIGxldCB7IHNvdXJjZVVSTCwgbWFjaGluZUlkLCBpcCwgaG9zdExhYmVsIH0gPSBjb25maWc7XG4gICAgbGV0IHJlcG9QYXRoID0gcmV2b2tlUmVwb1BhdGgoc291cmNlVVJMKTtcbiAgICBsZXQga2V5UGF0aCA9IGF3YWl0IGVuc3VyZVJldm9rZUtleShzb3VyY2VVUkwpO1xuICAgIGxldCByZXZvY2F0aW9uSWQgPSBuZXdSZXZvY2F0aW9uSWQobWFjaGluZUlkKTtcbiAgICBsZXQgZGlyZWN0b3J5ID0gcGF0aC5qb2luKHJlcG9QYXRoLCBSRVZPQ0FUSU9OU19ESVIpO1xuICAgIGF3YWl0IGZzLm1rZGlyKGRpcmVjdG9yeSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgYXdhaXQgZnMud3JpdGVGaWxlKHBhdGguam9pbihkaXJlY3RvcnksIGAke3Jldm9jYXRpb25JZH0uanNvbmApLCBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIHJldm9jYXRpb25JZCxcbiAgICAgICAgbWFjaGluZUlkLFxuICAgICAgICBpcCxcbiAgICAgICAgcmV2b2tlZEF0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgIHJldm9rZWRCeTogaG9zdExhYmVsLFxuICAgICAgICByZWFzb246IFJFVk9DQVRJT05fUkVBU09OLFxuICAgIH0sIHVuZGVmaW5lZCwgNCkgKyBcIlxcblwiKTtcblxuICAgIGF3YWl0IHJ1bkdpdCh7IGFyZ3M6IFtcImFkZFwiLCBcIi1BXCJdLCBjd2Q6IHJlcG9QYXRoLCBrZXlQYXRoIH0pO1xuICAgIGF3YWl0IHJ1bkdpdCh7XG4gICAgICAgIGFyZ3M6IFtcIi1jXCIsIFwidXNlci5lbWFpbD1wb3J0c2VjdXJlQGxvY2FsaG9zdFwiLCBcIi1jXCIsIFwidXNlci5uYW1lPXBvcnRzZWN1cmVcIiwgXCJjb21taXRcIiwgXCItbVwiLCBgcmV2b2tlICR7cmV2b2NhdGlvbklkfWBdLFxuICAgICAgICBjd2Q6IHJlcG9QYXRoLCBrZXlQYXRoLFxuICAgIH0pO1xuICAgIGxldCBwdXNoID0gYXdhaXQgcnVuR2l0KHsgYXJnczogW1wicHVzaFwiLCBcIm9yaWdpblwiLCBcIkhFQURcIl0sIGN3ZDogcmVwb1BhdGgsIGtleVBhdGgsIGFsbG93RmFpbHVyZTogdHJ1ZSB9KTtcbiAgICBpZiAocHVzaC5zdGF0dXMgIT09IDApIHtcbiAgICAgICAgLy8gQW5vdGhlciBtYWNoaW5lIG1vc3QgbGlrZWx5IHJlY29yZGVkIHRoZSBzYW1lIHRoaW5nIGZpcnN0LCBhbmQgdGhlIG5leHQgcmVhZCBwaWNrcyBpdCB1cC5cbiAgICAgICAgY29uc29sZS5sb2coYENvdWxkIG5vdCBwdXNoIHRoZSByZXZvY2F0aW9uIG9mICR7bWFjaGluZUlkfSBmcm9tICR7aXB9LiAkeyhwdXNoLnN0ZG91dCArIHB1c2guc3RkZXJyKS50cmltKCl9YCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc29sZS5sb2coYFJldm9rZWQgJHttYWNoaW5lSWR9IGZyb20gJHtpcH0sICR7cmV2b2NhdGlvbklkfWApO1xuXG4gICAgLy8gU2FpZCBieSB3aG9ldmVyIHdyb3RlIHRoZSByZXZvY2F0aW9uLCBvbmNlLCB0aGUgc2FtZSBhcyBmb3IgYW4gc3NoIGtleS4gTWFjaGluZXMgdGhhdCBvbmx5XG4gICAgLy8gcmVhZCBpdCBsYXRlciBzYXkgbm90aGluZywgb3Igb25lIGV2ZW50IHdvdWxkIGJlIHJlcG9ydGVkIGJ5IGV2ZXJ5IG1hY2hpbmUgdGhhdCBzYXcgaXQuXG4gICAgYXdhaXQgbm90aWZ5QmVzdEVmZm9ydChcbiAgICAgICAgYFNVU1BJQ0lPVVMgSVAgJHtpcH0gRlJPWkUgTUFDSElORSAke21hY2hpbmVJZH1gLFxuICAgICAgICBgQSBtYWNoaW5lIHdlIHRydXN0IHRhbGtlZCB0byB1cyBmcm9tICR7aXB9LCB3aGljaCBpcyBub3QgYW4gYWRkcmVzcyBpdCBpcyBhbGxvd2VkIHRvIHRhbGtgXG4gICAgICAgICsgYCBmcm9tLiBJdCBwcm92ZWQgaXQgaG9sZHMgdGhhdCBtYWNoaW5lJ3Mga2V5LCBzbyBlaXRoZXIgc29tZW9uZSBlbHNlIGhhcyBhIGNvcHkgb2YgaXQsYFxuICAgICAgICArIGAgb3IgdGhhdCBtYWNoaW5lJ3MgYWRkcmVzcyBjaGFuZ2VkLmBcbiAgICAgICAgKyBgXFxuXFxuSXQgaXMgZnJvemVuIGV2ZXJ5d2hlcmUgbm93LCBhbmQgbm90aGluZyBhY2NlcHRzIGl0LmBcbiAgICAgICAgKyBgXFxuXFxuSWYgdGhpcyB3YXMgYW4gYXR0YWNrLCByZW1vdmUgXFxgbWFjaGluZXMvJHttYWNoaW5lSWR9Lmpzb25cXGAgZnJvbSBcXGAke3NvdXJjZVVSTH1cXGAgbm93LmBcbiAgICAgICAgKyBgXFxuSWYgaXQgd2FzIGxlZ2l0aW1hdGUsIHJ1biBcXGB5YXJuIHVucmV2b2tlIGdpdFxcYCBpbiB0aGF0IHJlcG8uIEl0IGFsbG93cyAke2lwfSBmb3IgdGhhdGBcbiAgICAgICAgKyBgIG1hY2hpbmUsIGFuZCB0YWtlcyBlZmZlY3QgYXMgZWFjaCBtYWNoaW5lIHBpY2tzIGl0IHVwLmBcbiAgICAgICAgKyBgXFxuXFxubWFjaGluZTogXFxgJHttYWNoaW5lSWR9XFxgYFxuICAgICAgICArIGBcXG5mcm96ZW4gYnk6IFxcYCR7aG9zdExhYmVsfVxcYGBcbiAgICApO1xufVxuXG4vKiogV2hldGhlciB3ZSB3aWxsIHRhbGsgdG8gdGhpcyBtYWNoaW5lLCBjb21pbmcgZnJvbSB0aGlzIGFkZHJlc3MuXG5cbiAgICBCb3RoIGhhbHZlcyBhcmUgcmVxdWlyZWQgYW5kIG5laXRoZXIgaXMgYSBndWVzczogdGhlIGNhbGxlciBrbm93cyB0aGUgbWFjaGluZSBpZCBiZWNhdXNlIHRoZVxuICAgIGNvbm5lY3Rpb24gcHJvdmVkIGl0LCBhbmQga25vd3MgdGhlIGFkZHJlc3MgYmVjYXVzZSB0aGUgcGFja2V0cyBjYW1lIGZyb20gdGhlcmUuIEEgbWFjaGluZSB3ZVxuICAgIGRvIG5vdCBsaXN0IGlzIHNpbXBseSBub3QgYWNjZXB0ZWQuIEEgbWFjaGluZSB3ZSBkbyBsaXN0LCBhcnJpdmluZyBmcm9tIGFuIGFkZHJlc3MgaXQgZG9lcyBub3RcbiAgICBoYXZlLCBpcyB0cmVhdGVkIGFzIHRoZSBzYW1lIGtpbmQgb2YgZXZlbnQgYXMgYSBzdG9sZW4gc3NoIGtleSAtIGl0IGlzIHJldm9rZWQgZXZlcnl3aGVyZSwgYW5kXG4gICAgc3RheXMgcmV2b2tlZCB1bnRpbCBhbiB1bnJldm9rZSBhbGxvd3MgdGhhdCBtYWNoaW5lIGZyb20gdGhhdCBhZGRyZXNzLlxuXG4gICAgU2F5cyB3aHkgd2hlbiB0aGUgYW5zd2VyIGlzIG5vLCBiZWNhdXNlIHRoZSB0aHJlZSB3YXlzIHRvIGJlIHJlZnVzZWQgYXJlIGVudGlyZWx5IGRpZmZlcmVudFxuICAgIHRoaW5ncyB0byBhIHBlcnNvbiByZWFkaW5nIGl0OiBuZXZlciB0cnVzdGVkIGF0IGFsbCwgdHJ1c3RlZCBidXQgZnJvemVuLCBvciB0cnVzdGVkIGFuZCB0YWxraW5nXG4gICAgZnJvbSBzb21ld2hlcmUgaXQgc2hvdWxkIG5vdCBiZS5cblxuICAgIFRocm93cyB3aGVuIHRoZSByZXBvIGl0c2VsZiBjYW5ub3QgYmUgcmVhZCBvciBpcyBub3Qgc2lnbmVkLCByYXRoZXIgdGhhbiBhbnN3ZXJpbmcgZmFsc2U6IHRoYXRcbiAgICBpcyBhIGJyb2tlbiBpbnN0YWxsYXRpb24sIG5vdCBhIHJlamVjdGVkIG1hY2hpbmUsIGFuZCB0aGUgdHdvIGRlc2VydmUgZGlmZmVyZW50IGhhbmRsaW5nLiAqL1xuZXhwb3J0IHR5cGUgTWFjaGluZVZlcmRpY3QgPSB7IGFjY2VwdGVkOiBib29sZWFuOyByZWFzb246IHN0cmluZyB9O1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaXNNYWNoaW5lQWNjZXB0ZWQoY29uZmlnOiB7IG1hY2hpbmVJZDogc3RyaW5nOyBpcDogc3RyaW5nIH0pOiBQcm9taXNlPE1hY2hpbmVWZXJkaWN0PiB7XG4gICAgbGV0IHsgbWFjaGluZUlkLCBpcCB9ID0gY29uZmlnO1xuICAgIGlmICghbWFjaGluZUlkIHx8ICFpcCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGEgbWFjaGluZUlkIGFuZCBhbiBpcCwgd2FzICR7SlNPTi5zdHJpbmdpZnkobWFjaGluZUlkKX0gYW5kICR7SlNPTi5zdHJpbmdpZnkoaXApfWApO1xuICAgIH1cbiAgICBsZXQgeyByZXBvUGF0aCwgc291cmNlVVJMIH0gPSBhd2FpdCByZXNvbHZlS2V5c1JlcG8oKTtcbiAgICAvLyBVbnNpZ25lZCwgb3Igc2lnbmVkIG92ZXIgZGlmZmVyZW50IGNvbnRlbnRzLCBtZWFucyB0aGUgbWFjaGluZSBsaXN0IGlzIG5vdCBldmlkZW5jZSBvZlxuICAgIC8vIGFueXRoaW5nLiBTYW1lIGdhdGUgdGhlIHNzaCBrZXlzIGdvIHRocm91Z2guXG4gICAgYXdhaXQgdmVyaWZ5Q2hlY2tvdXQocmVwb1BhdGgpO1xuXG4gICAgbGV0IG1hY2hpbmUgPSAoYXdhaXQgcmVhZE1hY2hpbmVzKHJlcG9QYXRoKSkuZ2V0KG1hY2hpbmVJZCk7XG4gICAgaWYgKCFtYWNoaW5lKSB7XG4gICAgICAgIHJldHVybiB7IGFjY2VwdGVkOiBmYWxzZSwgcmVhc29uOiBcInRoYXQgbWFjaGluZSBpcyBub3QgdHJ1c3RlZFwiIH07XG4gICAgfVxuXG4gICAgYXdhaXQgc3luY1Jldm9jYXRpb25zKHNvdXJjZVVSTCk7XG4gICAgbGV0IHVucmV2b2tlcyA9IGF3YWl0IHJlYWRVbnJldm9rZXMoc291cmNlVVJMKS5jYXRjaCgoKSA9PiAoeyBwYWlyczogbmV3IE1hcCgpLCBsZWdhY3lJZHM6IG5ldyBNYXAoKSB9KSk7XG4gICAgLy8gQW4gdW5yZXZva2UgY291bnRzIGFzIHNvb24gYXMgaXQgaXMgc2Vlbi4gSXQgaXMgc2lnbmVkLCBzbyB3cml0aW5nIG9uZSBhbHJlYWR5IHRha2VzIHRoZVxuICAgIC8vIGhhcmR3YXJlIGtleSwgYW5kIGFueW9uZSBob2xkaW5nIHRoYXQgY2FuIHNpZ24gYW55dGhpbmcgYXQgYWxsIC0gYSB3YWl0IGJlZm9yZSBob25vdXJpbmcgaXRcbiAgICAvLyBndWFyZHMgYWdhaW5zdCBhbiBhdHRhY2tlciB3aG8gaGFzIG5vIG5lZWQgb2YgaXQuXG4gICAgbGV0IGFsbG93ZWRBZ2FpbiA9IChwYWlyOiBzdHJpbmcpID0+ICEhdW5yZXZva2VzLnBhaXJzLmdldChwYWlyKT8ubGVuZ3RoO1xuICAgIGxldCByZXZvY2F0aW9ucyA9IGF3YWl0IHJlYWRNYWNoaW5lUmV2b2NhdGlvbnMoc291cmNlVVJMKTtcbiAgICAvLyBBbnkgcmV2b2NhdGlvbiBub3RoaW5nIGhhcyB1bmRvbmUga2VlcHMgdGhlIG1hY2hpbmUgb3V0LCBmcm9tIGV2ZXJ5d2hlcmUsIHRoZSB3YXkgYSByZXZva2VkXG4gICAgLy8gc3NoIGtleSBpcyBvdXQgZXZlcnl3aGVyZSByYXRoZXIgdGhhbiBvbmx5IGZyb20gdGhlIGFkZHJlc3MgaXQgd2FzIG1pc3VzZWQgZnJvbS5cbiAgICBsZXQgZnJvemVuRnJvbSA9IFwiXCI7XG4gICAgZm9yIChsZXQgcmV2b2NhdGlvbiBvZiByZXZvY2F0aW9ucykge1xuICAgICAgICBpZiAocmV2b2NhdGlvbi5tYWNoaW5lSWQgIT09IG1hY2hpbmVJZCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFhbGxvd2VkQWdhaW4ocGFpcktleSh7IGZpbmdlcnByaW50OiByZXZvY2F0aW9uLm1hY2hpbmVJZCwgaXA6IHJldm9jYXRpb24uaXAgfSkpKSB7XG4gICAgICAgICAgICBmcm96ZW5Gcm9tID0gcmV2b2NhdGlvbi5pcDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoZnJvemVuRnJvbSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYWNjZXB0ZWQ6IGZhbHNlLFxuICAgICAgICAgICAgcmVhc29uOiBgdGhhdCBtYWNoaW5lIGlzIGZyb3plbiwgaXQgd2FzIHVzZWQgZnJvbSAke2Zyb3plbkZyb219IHdoaWNoIGl0IGlzIG5vdCBhbGxvd2VkIGZyb21gLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGlmIChtYWNoaW5lLmlwcy5pbmNsdWRlcyhpcCkpIHtcbiAgICAgICAgcmV0dXJuIHsgYWNjZXB0ZWQ6IHRydWUsIHJlYXNvbjogXCJcIiB9O1xuICAgIH1cblxuICAgIC8vIExpc3RlZCwgYnV0IHRhbGtpbmcgdG8gdXMgZnJvbSBzb21ld2hlcmUgaXQgc2hvdWxkIG5vdCBiZS4gUmVjb3JkZWQgb25jZSBmb3IgdGhpcyBtYWNoaW5lXG4gICAgLy8gYW5kIGFkZHJlc3MsIHNvIGJlaW5nIHRhbGtlZCB0byByZXBlYXRlZGx5IGRvZXMgbm90IHdyaXRlIHJlcGVhdGVkbHkuXG4gICAgbGV0IHBhaXIgPSBwYWlyS2V5KHsgZmluZ2VycHJpbnQ6IG1hY2hpbmVJZCwgaXAgfSk7XG4gICAgbGV0IGFscmVhZHlSZWNvcmRlZCA9IHJldm9jYXRpb25zLnNvbWUocmV2b2NhdGlvbiA9PlxuICAgICAgICBwYWlyS2V5KHsgZmluZ2VycHJpbnQ6IHJldm9jYXRpb24ubWFjaGluZUlkLCBpcDogcmV2b2NhdGlvbi5pcCB9KSA9PT0gcGFpcik7XG4gICAgaWYgKCFhbHJlYWR5UmVjb3JkZWQgJiYgIWFsbG93ZWRBZ2FpbihwYWlyKSkge1xuICAgICAgICBhd2FpdCByZWNvcmRNYWNoaW5lUmV2b2NhdGlvbih7IHNvdXJjZVVSTCwgbWFjaGluZUlkLCBpcCwgaG9zdExhYmVsOiBvcy5ob3N0bmFtZSgpIH0pO1xuICAgICAgICByZXR1cm4geyBhY2NlcHRlZDogZmFsc2UsIHJlYXNvbjogYHRoYXQgbWFjaGluZSBpcyBub3QgYWxsb3dlZCBmcm9tICR7aXB9LCBzbyBpdCBpcyBub3cgZnJvemVuIGV2ZXJ5d2hlcmVgIH07XG4gICAgfVxuICAgIHJldHVybiB7IGFjY2VwdGVkOiBmYWxzZSwgcmVhc29uOiBgdGhhdCBtYWNoaW5lIGlzIG5vdCBhbGxvd2VkIGZyb20gJHtpcH1gIH07XG59XG4iXX0=
264
+ /* _JS_SOURCE_HASH = "4f49b3c9f4a58987204c92820f6aca5ff7cf73325e697e849445299f06638103"; */