sliftutils 1.7.129 → 1.7.131

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 (78) hide show
  1. package/index.d.ts +4 -51
  2. package/misc/dist/ownIPs.ts.cache +29 -3
  3. package/misc/dist/strings.ts.cache +2 -2
  4. package/misc/https/dist/certs.ts.cache +2 -2
  5. package/misc/https/dist/persistentLocalStorage.ts.cache +2 -2
  6. package/misc/ownIPs.ts +29 -1
  7. package/package.json +1 -1
  8. package/security/authorizedKeys/authorizedKeys.d.ts +37 -0
  9. package/security/authorizedKeys/daemon/changes.d.ts +17 -0
  10. package/security/authorizedKeys/daemon/dist/changes.ts.cache +2 -2
  11. package/security/authorizedKeys/daemon/dist/git.ts.cache +2 -2
  12. package/security/authorizedKeys/daemon/dist/notify.ts.cache +2 -2
  13. package/security/authorizedKeys/daemon/dist/paths.ts.cache +4 -7
  14. package/security/authorizedKeys/daemon/dist/repoFiles.ts.cache +2 -2
  15. package/security/authorizedKeys/daemon/dist/revocation.ts.cache +0 -0
  16. package/security/authorizedKeys/daemon/dist/sessions.ts.cache +2 -2
  17. package/security/authorizedKeys/daemon/dist/state.ts.cache +6 -4
  18. package/security/authorizedKeys/daemon/dist/trust.ts.cache +2 -2
  19. package/security/authorizedKeys/daemon/git.d.ts +35 -0
  20. package/security/authorizedKeys/daemon/notify.d.ts +8 -0
  21. package/security/authorizedKeys/daemon/paths.d.ts +15 -0
  22. package/security/authorizedKeys/daemon/paths.ts +0 -3
  23. package/security/authorizedKeys/daemon/repoFiles.d.ts +25 -0
  24. package/security/authorizedKeys/daemon/revocation.d.ts +74 -0
  25. package/security/authorizedKeys/daemon/revocation.ts +0 -0
  26. package/security/authorizedKeys/daemon/sessions.d.ts +19 -0
  27. package/security/authorizedKeys/daemon/state.d.ts +67 -0
  28. package/security/authorizedKeys/daemon/state.ts +4 -8
  29. package/security/authorizedKeys/daemon/trust.d.ts +20 -0
  30. package/security/authorizedKeys/dist/authorizedKeys.ts.cache +2 -2
  31. package/security/authorizedKeys/dist/keysRepo.ts.cache +111 -0
  32. package/security/authorizedKeys/dist/revokeSource.ts.cache +2 -2
  33. package/security/authorizedKeys/dist/secureSSH.ts.cache +147 -71
  34. package/security/authorizedKeys/dist/sources.ts.cache +2 -2
  35. package/security/authorizedKeys/dist/unrevoke.ts.cache +70 -51
  36. package/security/authorizedKeys/keysRepo.d.ts +10 -0
  37. package/security/authorizedKeys/keysRepo.ts +111 -0
  38. package/security/authorizedKeys/revokeSource.d.ts +13 -0
  39. package/security/authorizedKeys/secureSSH.ts +28 -38
  40. package/security/authorizedKeys/sources.d.ts +17 -0
  41. package/security/authorizedKeys/unrevoke.ts +9 -36
  42. package/security/helpers/dist/paths.ts.cache +2 -2
  43. package/security/helpers/dist/spawn.ts.cache +2 -2
  44. package/security/helpers/paths.d.ts +4 -0
  45. package/security/helpers/spawn.d.ts +16 -0
  46. package/security/keys/deriveKey.d.ts +16 -0
  47. package/security/keys/dist/deriveKey.ts.cache +2 -2
  48. package/security/keys/dist/sshKeyFile.ts.cache +2 -2
  49. package/security/keys/sshKeyFile.d.ts +18 -0
  50. package/security/machines/addMachine.ts +80 -27
  51. package/security/machines/dist/addMachine.ts.cache +6 -5
  52. package/security/machines/dist/machines.ts.cache +110 -101
  53. package/security/machines/machines.d.ts +81 -0
  54. package/security/machines/machines.ts +123 -99
  55. package/security/machines/trustServer.ts +5 -3
  56. package/security/notifications/discord.d.ts +36 -0
  57. package/security/notifications/dist/discord.ts.cache +2 -2
  58. package/security/notifications/dist/remoteWebhook.ts.cache +78 -0
  59. package/security/notifications/dist/setupNotify.ts.cache +39 -0
  60. package/security/signedFiles/dist/manifest.ts.cache +2 -2
  61. package/security/signedFiles/dist/signFiles.ts.cache +8 -10
  62. package/security/signedFiles/manifest.d.ts +44 -0
  63. package/security/signedFiles/signFiles.ts +6 -10
  64. package/storage/remoteStorage/ArchivesRemote.ts +8 -10
  65. package/storage/remoteStorage/accessPage.tsx +13 -90
  66. package/storage/remoteStorage/dist/ArchivesRemote.ts.cache +11 -12
  67. package/storage/remoteStorage/dist/serverConfig.ts.cache +7 -49
  68. package/storage/remoteStorage/dist/storageController.ts.cache +33 -114
  69. package/storage/remoteStorage/serverConfig.d.ts +0 -10
  70. package/storage/remoteStorage/serverConfig.ts +6 -48
  71. package/storage/remoteStorage/storageController.d.ts +4 -36
  72. package/storage/remoteStorage/storageController.ts +40 -126
  73. package/storage/remoteStorage/storageServer.ts +1 -8
  74. package/storage/remoteStorage/storageServerCli.ts +14 -0
  75. package/security/machines/trustState.ts +0 -53
  76. package/storage/remoteStorage/grantAccess.js +0 -4
  77. package/storage/remoteStorage/grantAccessCli.d.ts +0 -1
  78. package/storage/remoteStorage/grantAccessCli.ts +0 -25
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
3
+ //exports.main = void 0;
4
+ const discord_1 = require("./discord");
5
+ const remoteWebhook_1 = require("./remoteWebhook");
6
+ const remoteSSH_1 = require("../helpers/remoteSSH");
7
+ const USAGE = `Usage: yarn setupnotify [host] <discord-webhook-url> [${remoteWebhook_1.REPLACE_KEYWORD}]
8
+
9
+ With no host it sets the webhook up on this machine.`;
10
+ function parseArgs(argv) {
11
+ let replace = argv.includes(remoteWebhook_1.REPLACE_KEYWORD);
12
+ let positional = argv.filter(arg => arg !== remoteWebhook_1.REPLACE_KEYWORD);
13
+ if (!positional.length || positional.length > 2) {
14
+ throw new Error(`Expected a webhook URL, and optionally a host before it, was ${positional.length}`
15
+ + ` argument(s): ${positional.join(" ") || "(none)"}\n${USAGE}`);
16
+ }
17
+ // The webhook url is the last one, so whatever comes before it is the host. Without one this
18
+ // machine is the target.
19
+ let webhookURL = positional[positional.length - 1];
20
+ let host = positional.length > 1 && positional[0] || remoteSSH_1.THIS_MACHINE;
21
+ // Validates the URL shape up front, so we never go anywhere with a bad webhook.
22
+ (0, discord_1.parseWebhookFile)({ contents: webhookURL, sourceName: "the command line" });
23
+ return { host, webhookURL, replace };
24
+ }
25
+ async function main() {
26
+ let { host, webhookURL, replace } = parseArgs(process.argv.slice(2));
27
+ let { outcome, filePath } = await (0, remoteWebhook_1.ensureRemoteWebhook)({ host, webhookURL, replace });
28
+ if (outcome === "unchanged") {
29
+ console.log(`${(0, remoteSSH_1.describeHost)(host)} already has this exact webhook in ${filePath}, nothing to do.`);
30
+ return;
31
+ }
32
+ if (outcome === "replaced") {
33
+ console.log(`Replaced the webhook on ${(0, remoteSSH_1.describeHost)(host)} and notified the old one.`);
34
+ }
35
+ console.log(`Wrote ${filePath} on ${(0, remoteSSH_1.describeHost)(host)} (mode 600), and confirmed on the new webhook.`);
36
+ }
37
+ exports.main = main;
38
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dXBOb3RpZnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJzZXR1cE5vdGlmeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx1Q0FBNkM7QUFDN0MsbURBQXVFO0FBQ3ZFLG9EQUFrRTtBQUVsRSxNQUFNLEtBQUssR0FBRyx5REFBeUQsK0JBQWU7O3FEQUVqQyxDQUFDO0FBRXRELFNBQVMsU0FBUyxDQUFDLElBQWM7SUFDN0IsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQywrQkFBZSxDQUFDLENBQUM7SUFDN0MsSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSywrQkFBZSxDQUFDLENBQUM7SUFDN0QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLElBQUksVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUM5QyxNQUFNLElBQUksS0FBSyxDQUNYLGdFQUFnRSxVQUFVLENBQUMsTUFBTSxFQUFFO2NBQ2pGLGlCQUFpQixVQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLFFBQVEsS0FBSyxLQUFLLEVBQUUsQ0FDbEUsQ0FBQztJQUNOLENBQUM7SUFDRCw2RkFBNkY7SUFDN0YseUJBQXlCO0lBQ3pCLElBQUksVUFBVSxHQUFHLFVBQVUsQ0FBQyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ25ELElBQUksSUFBSSxHQUFHLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSx3QkFBWSxDQUFDO0lBQ2xFLGdGQUFnRjtJQUNoRixJQUFBLDBCQUFnQixFQUFDLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDO0lBQzNFLE9BQU8sRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxDQUFDO0FBQ3pDLENBQUM7QUFFTSxLQUFLLFVBQVUsSUFBSTtJQUN0QixJQUFJLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNyRSxJQUFJLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxHQUFHLE1BQU0sSUFBQSxtQ0FBbUIsRUFBQyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUNyRixJQUFJLE9BQU8sS0FBSyxXQUFXLEVBQUUsQ0FBQztRQUMxQixPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBQSx3QkFBWSxFQUFDLElBQUksQ0FBQyxzQ0FBc0MsUUFBUSxrQkFBa0IsQ0FBQyxDQUFDO1FBQ25HLE9BQU87SUFDWCxDQUFDO0lBQ0QsSUFBSSxPQUFPLEtBQUssVUFBVSxFQUFFLENBQUM7UUFDekIsT0FBTyxDQUFDLEdBQUcsQ0FBQywyQkFBMkIsSUFBQSx3QkFBWSxFQUFDLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO0lBQzNGLENBQUM7SUFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsUUFBUSxPQUFPLElBQUEsd0JBQVksRUFBQyxJQUFJLENBQUMsZ0RBQWdELENBQUMsQ0FBQztBQUM1RyxDQUFDO0FBWEQsb0JBV0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBwYXJzZVdlYmhvb2tGaWxlIH0gZnJvbSBcIi4vZGlzY29yZFwiO1xuaW1wb3J0IHsgZW5zdXJlUmVtb3RlV2ViaG9vaywgUkVQTEFDRV9LRVlXT1JEIH0gZnJvbSBcIi4vcmVtb3RlV2ViaG9va1wiO1xuaW1wb3J0IHsgZGVzY3JpYmVIb3N0LCBUSElTX01BQ0hJTkUgfSBmcm9tIFwiLi4vaGVscGVycy9yZW1vdGVTU0hcIjtcblxuY29uc3QgVVNBR0UgPSBgVXNhZ2U6IHlhcm4gc2V0dXBub3RpZnkgW2hvc3RdIDxkaXNjb3JkLXdlYmhvb2stdXJsPiBbJHtSRVBMQUNFX0tFWVdPUkR9XVxuXG5XaXRoIG5vIGhvc3QgaXQgc2V0cyB0aGUgd2ViaG9vayB1cCBvbiB0aGlzIG1hY2hpbmUuYDtcblxuZnVuY3Rpb24gcGFyc2VBcmdzKGFyZ3Y6IHN0cmluZ1tdKSB7XG4gICAgbGV0IHJlcGxhY2UgPSBhcmd2LmluY2x1ZGVzKFJFUExBQ0VfS0VZV09SRCk7XG4gICAgbGV0IHBvc2l0aW9uYWwgPSBhcmd2LmZpbHRlcihhcmcgPT4gYXJnICE9PSBSRVBMQUNFX0tFWVdPUkQpO1xuICAgIGlmICghcG9zaXRpb25hbC5sZW5ndGggfHwgcG9zaXRpb25hbC5sZW5ndGggPiAyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBFeHBlY3RlZCBhIHdlYmhvb2sgVVJMLCBhbmQgb3B0aW9uYWxseSBhIGhvc3QgYmVmb3JlIGl0LCB3YXMgJHtwb3NpdGlvbmFsLmxlbmd0aH1gXG4gICAgICAgICAgICArIGAgYXJndW1lbnQocyk6ICR7cG9zaXRpb25hbC5qb2luKFwiIFwiKSB8fCBcIihub25lKVwifVxcbiR7VVNBR0V9YFxuICAgICAgICApO1xuICAgIH1cbiAgICAvLyBUaGUgd2ViaG9vayB1cmwgaXMgdGhlIGxhc3Qgb25lLCBzbyB3aGF0ZXZlciBjb21lcyBiZWZvcmUgaXQgaXMgdGhlIGhvc3QuIFdpdGhvdXQgb25lIHRoaXNcbiAgICAvLyBtYWNoaW5lIGlzIHRoZSB0YXJnZXQuXG4gICAgbGV0IHdlYmhvb2tVUkwgPSBwb3NpdGlvbmFsW3Bvc2l0aW9uYWwubGVuZ3RoIC0gMV07XG4gICAgbGV0IGhvc3QgPSBwb3NpdGlvbmFsLmxlbmd0aCA+IDEgJiYgcG9zaXRpb25hbFswXSB8fCBUSElTX01BQ0hJTkU7XG4gICAgLy8gVmFsaWRhdGVzIHRoZSBVUkwgc2hhcGUgdXAgZnJvbnQsIHNvIHdlIG5ldmVyIGdvIGFueXdoZXJlIHdpdGggYSBiYWQgd2ViaG9vay5cbiAgICBwYXJzZVdlYmhvb2tGaWxlKHsgY29udGVudHM6IHdlYmhvb2tVUkwsIHNvdXJjZU5hbWU6IFwidGhlIGNvbW1hbmQgbGluZVwiIH0pO1xuICAgIHJldHVybiB7IGhvc3QsIHdlYmhvb2tVUkwsIHJlcGxhY2UgfTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1haW4oKSB7XG4gICAgbGV0IHsgaG9zdCwgd2ViaG9va1VSTCwgcmVwbGFjZSB9ID0gcGFyc2VBcmdzKHByb2Nlc3MuYXJndi5zbGljZSgyKSk7XG4gICAgbGV0IHsgb3V0Y29tZSwgZmlsZVBhdGggfSA9IGF3YWl0IGVuc3VyZVJlbW90ZVdlYmhvb2soeyBob3N0LCB3ZWJob29rVVJMLCByZXBsYWNlIH0pO1xuICAgIGlmIChvdXRjb21lID09PSBcInVuY2hhbmdlZFwiKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGAke2Rlc2NyaWJlSG9zdChob3N0KX0gYWxyZWFkeSBoYXMgdGhpcyBleGFjdCB3ZWJob29rIGluICR7ZmlsZVBhdGh9LCBub3RoaW5nIHRvIGRvLmApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChvdXRjb21lID09PSBcInJlcGxhY2VkXCIpIHtcbiAgICAgICAgY29uc29sZS5sb2coYFJlcGxhY2VkIHRoZSB3ZWJob29rIG9uICR7ZGVzY3JpYmVIb3N0KGhvc3QpfSBhbmQgbm90aWZpZWQgdGhlIG9sZCBvbmUuYCk7XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKGBXcm90ZSAke2ZpbGVQYXRofSBvbiAke2Rlc2NyaWJlSG9zdChob3N0KX0gKG1vZGUgNjAwKSwgYW5kIGNvbmZpcm1lZCBvbiB0aGUgbmV3IHdlYmhvb2suYCk7XG59XG4iXX0=
39
+ /* _JS_SOURCE_HASH = "75262294c247703aec2fc4b9dcf81c245e79b0b1566401ca4654e019705f6a40"; */
@@ -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
  };
@@ -82,4 +82,4 @@ function formatManifest(manifest) {
82
82
  }
83
83
  exports.formatManifest = formatManifest;
84
84
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFuaWZlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtYW5pZmVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsMkRBQTZCO0FBQzdCLGdEQUF3QjtBQUN4Qiw0Q0FBZ0Q7QUFFaEQsa0dBQWtHO0FBQ2xHLGlHQUFpRztBQUNqRyxrR0FBa0c7QUFDbEcsdUJBQXVCO0FBRVYsUUFBQSxhQUFhLEdBQUcsa0JBQWtCLENBQUM7QUFDbkMsUUFBQSxjQUFjLEdBQUcsc0JBQXNCLENBQUM7QUFDckQsb0dBQW9HO0FBQ3ZGLFFBQUEsY0FBYyxHQUFHLFdBQVcsQ0FBQztBQUM3QixRQUFBLGdCQUFnQixHQUFHLENBQUMsQ0FBQztBQU9sQzs7Ozs7OzswRkFPMEY7QUFDbkYsS0FBSyxVQUFVLGFBQWEsQ0FBQyxRQUFnQjtJQUNoRCxJQUFJLE1BQU0sR0FBRyxNQUFNLElBQUEsb0JBQVksRUFBQztRQUM1QixPQUFPLEVBQUUsS0FBSztRQUNkLElBQUksRUFBRSxDQUFDLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLG9CQUFvQixDQUFDO1FBQ2hFLEdBQUcsRUFBRSxRQUFRO0tBQ2hCLENBQUMsQ0FBQztJQUNILElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN0QixNQUFNLElBQUksS0FBSyxDQUNYLGlDQUFpQyxRQUFRLHlCQUF5QixNQUFNLENBQUMsTUFBTSxJQUFJO2NBQ2pGLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUNoRCxDQUFDO0lBQ04sQ0FBQztJQUNELElBQUksTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQztTQUNqQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7U0FDeEIsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxJQUFJLElBQUksS0FBSyxxQkFBYSxJQUFJLElBQUksS0FBSyxzQkFBYyxDQUFDO1NBQ3pFLElBQUksRUFBRSxDQUFDO0lBRVosSUFBSSxPQUFPLEdBQWEsRUFBRSxDQUFDO0lBQzNCLEtBQUssSUFBSSxZQUFZLElBQUksTUFBTSxFQUFFLENBQUM7UUFDOUIsSUFBSSxDQUFDO1lBQ0QsTUFBTSxrQkFBRSxDQUFDLE1BQU0sQ0FBQyxjQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO1lBQ25ELE9BQU8sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDL0IsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDVCxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsWUFBWSx3REFBd0QsQ0FBQyxDQUFDO1FBQ2pHLENBQUM7SUFDTCxDQUFDO0lBQ0QsT0FBTyxPQUFPLENBQUM7QUFDbkIsQ0FBQztBQTNCRCxzQ0EyQkM7QUFFRDs7OytCQUcrQjtBQUMvQixTQUFnQixnQkFBZ0IsQ0FBQyxRQUFnQjtJQUM3QyxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQ3JGLENBQUM7QUFGRCw0Q0FFQztBQUVEOytGQUMrRjtBQUN4RixLQUFLLFVBQVUsVUFBVSxDQUFDLFFBQWdCO0lBQzdDLElBQUksUUFBUSxHQUFHLGdCQUFnQixDQUFDLE1BQU0sa0JBQUUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUM3RCxPQUFPLEVBQUUsSUFBSSxFQUFFLFFBQVEsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLGdCQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztBQUN6RyxDQUFDO0FBSEQsZ0NBR0M7QUFFTSxLQUFLLFVBQVUsYUFBYSxDQUFDLFFBQWdCO0lBQ2hELElBQUksS0FBSyxHQUFzQixFQUFFLENBQUM7SUFDbEMsS0FBSyxJQUFJLFlBQVksSUFBSSxNQUFNLGFBQWEsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1FBQ3JELElBQUksTUFBTSxHQUFHLE1BQU0sVUFBVSxDQUFDLGNBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFDakUsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQ2pGLENBQUM7SUFDRCxPQUFPLEVBQUUsT0FBTyxFQUFFLHdCQUFnQixFQUFFLEtBQUssRUFBRSxDQUFDO0FBQ2hELENBQUM7QUFQRCxzQ0FPQztBQUVELG1HQUFtRztBQUNuRyxTQUFnQixjQUFjLENBQUMsUUFBa0I7SUFDN0MsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQ3pELENBQUM7QUFGRCx3Q0FFQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBjcnlwdG8gZnJvbSBcImNyeXB0b1wiO1xuaW1wb3J0IGZzIGZyb20gXCJmcy9wcm9taXNlc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IHNwYXduUHJvbWlzZSB9IGZyb20gXCIuLi9oZWxwZXJzL3NwYXduXCI7XG5cbi8vIFBPUlRFRCBDT0RFOiBzZWN1cml0eS9hdXRob3JpemVkS2V5cy9kYWVtb24vcG9ydHNlY3VyZURhZW1vbi5qcyBjb250YWlucyBhIHBsYWluIEpTIHBvcnQgb2YgdGhlXG4vLyB2ZXJpZnlpbmcgaGFsZiBvZiB0aGlzIGZpbGUsIHNvIGl0IGNhbiBjaGVjayBhIHNpZ25hdHVyZSB3aXRoIG5vIGRlcGVuZGVuY2llcy4gQm90aCBzaWRlcyBtdXN0XG4vLyBhZ3JlZSBvbiB0aGUgbWFuaWZlc3Qgc2hhcGUgYW5kIG9uIHdoaWNoIGZpbGVzIGl0IGNvdmVycyAtIGlmIHlvdSBjaGFuZ2Ugb25lLCBtYWtlIHRoZSBtYXRjaGluZ1xuLy8gY2hhbmdlIGluIHRoZSBvdGhlci5cblxuZXhwb3J0IGNvbnN0IE1BTklGRVNUX05BTUUgPSBcInNpZ25lZGZpbGVzLmpzb25cIjtcbmV4cG9ydCBjb25zdCBTSUdOQVRVUkVfTkFNRSA9IFwic2lnbmVkZmlsZXMuanNvbi5zaWdcIjtcbi8vIHNzaCBzaWduYXR1cmVzIGFyZSBuYW1lc3BhY2VkLCBzbyBhIHNpZ25hdHVyZSBtYWRlIGZvciBvbmUgcHVycG9zZSBjYW5ub3QgYmUgcmVwbGF5ZWQgYXMgYW5vdGhlci5cbmV4cG9ydCBjb25zdCBTSUdOX05BTUVTUEFDRSA9IFwic2lnbmZpbGVzXCI7XG5leHBvcnQgY29uc3QgTUFOSUZFU1RfVkVSU0lPTiA9IDE7XG5cbmV4cG9ydCB0eXBlIE1hbmlmZXN0ID0ge1xuICAgIHZlcnNpb246IG51bWJlcjtcbiAgICBmaWxlczogeyBwYXRoOiBzdHJpbmc7IHNpemU6IG51bWJlcjsgc2hhMjU2OiBzdHJpbmcgfVtdO1xufTtcblxuLyoqIEV2ZXJ5dGhpbmcgaW4gdGhlIHJlcG8gdGhhdCBpcyBub3QgaWdub3JlZDogd2hhdCBpcyBpbiB0aGUgaW5kZXgsIHBsdXMgd2hhdCBpcyBub3Qgc3RhZ2VkIHlldC5cbiAgICBHaXQgaXMgYXNrZWQgYmVjYXVzZSBnaXQgaXMgd2hhdCBrbm93cyBob3cgdG8gYXBwbHkgdGhlIGlnbm9yZSBydWxlcy5cblxuICAgIFdoYXQgY29tZXMgYmFjayBpcyBhIGhpbnQgdGhhdCBhIGZpbGUgbWlnaHQgYmUgdGhlcmUsIG5vdCB0aGF0IGl0IGlzLiBBIGZpbGUgZGVsZXRlZCBmcm9tIHRoZVxuICAgIHdvcmtpbmcgdHJlZSBzdGF5cyBpbiB0aGUgaW5kZXggdW50aWwgdGhhdCBkZWxldGlvbiBpcyBzdGFnZWQsIHNvIGdpdCBuYW1lcyBpdCBhbmQgdGhlcmUgaXNcbiAgICBub3RoaW5nIHRvIHJlYWQsIHdoaWNoIGlzIHdoeSBlYWNoIG9uZSBpcyBjaGVja2VkIGJlZm9yZSBpdCBnb2VzIGluLlxuXG4gICAgVGhlIG1hbmlmZXN0IGFuZCBpdHMgc2lnbmF0dXJlIGFyZSBsZWZ0IG91dCwgc2luY2UgdGhleSBjYW5ub3QgZGVzY3JpYmUgdGhlbXNlbHZlcy4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsaXN0UmVwb0ZpbGVzKHJlcG9QYXRoOiBzdHJpbmcpIHtcbiAgICBsZXQgcmVzdWx0ID0gYXdhaXQgc3Bhd25Qcm9taXNlKHtcbiAgICAgICAgY29tbWFuZDogXCJnaXRcIixcbiAgICAgICAgYXJnczogW1wibHMtZmlsZXNcIiwgXCItLWNhY2hlZFwiLCBcIi0tb3RoZXJzXCIsIFwiLS1leGNsdWRlLXN0YW5kYXJkXCJdLFxuICAgICAgICBjd2Q6IHJlcG9QYXRoLFxuICAgIH0pO1xuICAgIGlmIChyZXN1bHQuc3RhdHVzICE9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBFeHBlY3RlZCB0byBsaXN0IHRoZSBmaWxlcyBpbiAke3JlcG9QYXRofSwgZ2l0IGxzLWZpbGVzIGV4aXRlZCAke3Jlc3VsdC5zdGF0dXN9LiBgXG4gICAgICAgICAgICArIGAkeyhyZXN1bHQuc3Rkb3V0ICsgcmVzdWx0LnN0ZGVycikudHJpbSgpfWBcbiAgICAgICAgKTtcbiAgICB9XG4gICAgbGV0IGxpc3RlZCA9IHJlc3VsdC5zdGRvdXQuc3BsaXQoXCJcXG5cIilcbiAgICAgICAgLm1hcChsaW5lID0+IGxpbmUudHJpbSgpKVxuICAgICAgICAuZmlsdGVyKGxpbmUgPT4gbGluZSAmJiBsaW5lICE9PSBNQU5JRkVTVF9OQU1FICYmIGxpbmUgIT09IFNJR05BVFVSRV9OQU1FKVxuICAgICAgICAuc29ydCgpO1xuXG4gICAgbGV0IHByZXNlbnQ6IHN0cmluZ1tdID0gW107XG4gICAgZm9yIChsZXQgcmVsYXRpdmVQYXRoIG9mIGxpc3RlZCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgZnMuYWNjZXNzKHBhdGguam9pbihyZXBvUGF0aCwgcmVsYXRpdmVQYXRoKSk7XG4gICAgICAgICAgICBwcmVzZW50LnB1c2gocmVsYXRpdmVQYXRoKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYExlYXZpbmcgJHtyZWxhdGl2ZVBhdGh9IG91dCBvZiB0aGUgbWFuaWZlc3QsIGl0IGlzIGdvbmUgZnJvbSB0aGUgd29ya2luZyB0cmVlYCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHByZXNlbnQ7XG59XG5cbi8qKiBBIFdpbmRvd3MgY2hlY2tvdXQgdHVybnMgTEYgaW50byBDUkxGLCBzbyB0aGUgc2FtZSBjb21taXQgaGFzaGVzIGRpZmZlcmVudGx5IHRoZXJlIHRoYW4gaXRcbiAgICBkb2VzIG9uIHRoZSBtYWNoaW5lIHRoYXQgcHVsbHMgaXQuIE5vcm1hbGlzaW5nIGZpcnN0IG1ha2VzIHRoZSBkaWdlc3QgZGVzY3JpYmUgdGhlIGNvbnRlbnRcbiAgICByYXRoZXIgdGhhbiB3aGljaGV2ZXIgY2hlY2tvdXQgcHJvZHVjZWQgaXQuIGxhdGluMSByb3VuZCB0cmlwcyBldmVyeSBieXRlLCBzbyB0aGlzIGlzIHNhZmUgb25cbiAgICBmaWxlcyB0aGF0IGFyZSBub3QgdGV4dC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVDb250ZW50KGNvbnRlbnRzOiBCdWZmZXIpIHtcbiAgICByZXR1cm4gQnVmZmVyLmZyb20oY29udGVudHMudG9TdHJpbmcoXCJsYXRpbjFcIikucmVwbGFjZSgvXFxyXFxuL2csIFwiXFxuXCIpLCBcImxhdGluMVwiKTtcbn1cblxuLyoqIFRoZSBzaXplIGFuZCBoYXNoIG9mIGEgZmlsZSdzIG5vcm1hbGlzZWQgY29udGVudC4gVGhlIHNpemUgaXMgdGhlIG5vcm1hbGlzZWQgb25lIG9uIHB1cnBvc2UsXG4gICAgc28gaXQgYWdyZWVzIHdpdGggdGhlIGhhc2ggcmF0aGVyIHRoYW4gd2l0aCB3aGF0ZXZlciB0aGUgbG9jYWwgY2hlY2tvdXQgaGFwcGVucyB0byBob2xkLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRpZ2VzdEZpbGUoZmlsZVBhdGg6IHN0cmluZykge1xuICAgIGxldCBjb250ZW50cyA9IG5vcm1hbGl6ZUNvbnRlbnQoYXdhaXQgZnMucmVhZEZpbGUoZmlsZVBhdGgpKTtcbiAgICByZXR1cm4geyBzaXplOiBjb250ZW50cy5sZW5ndGgsIHNoYTI1NjogY3J5cHRvLmNyZWF0ZUhhc2goXCJzaGEyNTZcIikudXBkYXRlKGNvbnRlbnRzKS5kaWdlc3QoXCJoZXhcIikgfTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGJ1aWxkTWFuaWZlc3QocmVwb1BhdGg6IHN0cmluZykge1xuICAgIGxldCBmaWxlczogTWFuaWZlc3RbXCJmaWxlc1wiXSA9IFtdO1xuICAgIGZvciAobGV0IHJlbGF0aXZlUGF0aCBvZiBhd2FpdCBsaXN0UmVwb0ZpbGVzKHJlcG9QYXRoKSkge1xuICAgICAgICBsZXQgZGlnZXN0ID0gYXdhaXQgZGlnZXN0RmlsZShwYXRoLmpvaW4ocmVwb1BhdGgsIHJlbGF0aXZlUGF0aCkpO1xuICAgICAgICBmaWxlcy5wdXNoKHsgcGF0aDogcmVsYXRpdmVQYXRoLCBzaXplOiBkaWdlc3Quc2l6ZSwgc2hhMjU2OiBkaWdlc3Quc2hhMjU2IH0pO1xuICAgIH1cbiAgICByZXR1cm4geyB2ZXJzaW9uOiBNQU5JRkVTVF9WRVJTSU9OLCBmaWxlcyB9O1xufVxuXG4vKiogU29ydGVkIGtleXMgYW5kIGEgdHJhaWxpbmcgbmV3bGluZSwgc28gdGhlIHNhbWUgdHJlZSBhbHdheXMgcHJvZHVjZXMgdGhlIHNhbWUgYnl0ZXMgdG8gc2lnbi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXRNYW5pZmVzdChtYW5pZmVzdDogTWFuaWZlc3QpIHtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkobWFuaWZlc3QsIHVuZGVmaW5lZCwgNCkgKyBcIlxcblwiO1xufVxuIl19
85
- /* _JS_SOURCE_HASH = "e58787cb53d84ba9647f11c90c737f7303e120b8e02ca37cc9f38202fce1929d"; */
85
+ /* _JS_SOURCE_HASH = "201e773734f1a3a4a276457669646f936d46b81026afab845e5b8161d1b4310d"; */
@@ -12,6 +12,7 @@ const paths_1 = require("../helpers/paths");
12
12
  const spawn_1 = require("../helpers/spawn");
13
13
  const manifest_1 = require("./manifest");
14
14
  const unrevoke_1 = require("../authorizedKeys/unrevoke");
15
+ const keysRepo_1 = require("../authorizedKeys/keysRepo");
15
16
  const authorizedKeys_1 = require("../authorizedKeys/authorizedKeys");
16
17
  // A hardware backed key is the entire point. A key sitting on disk is compromised the moment the
17
18
  // machine is, and then the signature proves nothing, so this is what we make when asked to make one.
@@ -150,14 +151,11 @@ async function signRepo(config) {
150
151
  exports.signRepo = signRepo;
151
152
  async function main() {
152
153
  let { keyPath, pushToGit } = parseArgs(process.argv.slice(2));
153
- // Read for its value, so stdout has to be on its own. runPromise joins it with stderr, and a
154
- // git warning glued to the front of this becomes a directory that does not exist.
155
- let topLevel = await (0, spawn_1.spawnPromise)({ command: "git", args: ["rev-parse", "--show-toplevel"] });
156
- let repoPath = topLevel.stdout.trim();
157
- if (topLevel.status !== 0 || !repoPath) {
158
- throw new Error(`Expected the current directory to be inside a git repo, it is not.\n`
159
- + `${(topLevel.stdout + topLevel.stderr).trim()}\n${USAGE}`);
160
- }
154
+ // The keys repo, which is this one when it holds keys and this machine's otherwise. Signing
155
+ // whatever repo the terminal happened to be in is how you end up signing something that is not
156
+ // a keys repo at all.
157
+ let { repoPath } = await (0, keysRepo_1.resolveKeysRepo)();
158
+ console.log(`Signing ${repoPath}`);
161
159
  await signRepo({ repoPath, keyPath });
162
160
  if (!pushToGit) {
163
161
  console.log(`Commit and push ${manifest_1.MANIFEST_NAME} and ${manifest_1.SIGNATURE_NAME} for anything to see them.`);
@@ -177,5 +175,5 @@ async function main() {
177
175
  console.log(`Committed and pushed.`);
178
176
  }
179
177
  exports.main = main;
180
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbkZpbGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic2lnbkZpbGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLDJEQUE2QjtBQUM3Qiw0Q0FBb0I7QUFDcEIsZ0RBQXdCO0FBQ3hCLCtEQUE0RDtBQUM1RCw0Q0FBOEM7QUFDOUMsNENBQWdEO0FBQ2hELHlDQUEwRztBQUMxRyx5REFBK0Q7QUFDL0QscUVBQWtGO0FBRWxGLGlHQUFpRztBQUNqRyxxR0FBcUc7QUFDckcsTUFBTSxnQkFBZ0IsR0FBRyxZQUFZLENBQUM7QUFDdEMsTUFBTSxnQkFBZ0IsR0FBRyw2QkFBNkIsQ0FBQztBQUN2RCxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUM7QUFDMUIsTUFBTSxjQUFjLEdBQUcsd0JBQXdCLENBQUM7QUFDaEQsTUFBTSxxQkFBcUIsR0FBRyxHQUFHLENBQUM7QUFDbEMsTUFBTSxLQUFLLEdBQUcsd0NBQXdDLFdBQVc7OztFQUcvRCxnQkFBZ0IsV0FBVyxnQkFBZ0I7T0FDdEMsV0FBVyxzQ0FBc0MsQ0FBQztBQUV6RDswRUFDMEU7QUFDMUUsU0FBUyxLQUFLLENBQUMsS0FBYTtJQUN4QixPQUFPLElBQUksS0FBSyxHQUFHLENBQUM7QUFDeEIsQ0FBQztBQUVELEtBQUssVUFBVSxVQUFVLENBQUMsUUFBZ0I7SUFDdEMsSUFBSSxDQUFDO1FBQ0QsTUFBTSxrQkFBRSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMxQixPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUNULE9BQU8sS0FBSyxDQUFDO0lBQ2pCLENBQUM7QUFDTCxDQUFDO0FBRUQsb0VBQW9FO0FBQ3BFLEtBQUssVUFBVSxnQkFBZ0I7SUFDM0IsSUFBSSxPQUFPLEdBQUcsSUFBQSxrQkFBVSxFQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDM0MsSUFBSSxNQUFNLFVBQVUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQzVCLE9BQU8sT0FBTyxDQUFDO0lBQ25CLENBQUM7SUFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLHFCQUFxQixPQUFPLGlCQUFpQixnQkFBZ0IsT0FBTyxDQUFDLENBQUM7SUFDbEYsT0FBTyxDQUFDLEdBQUcsQ0FBQyw0REFBNEQsQ0FBQyxDQUFDO0lBQzFFLE1BQU0sa0JBQUUsQ0FBQyxLQUFLLENBQUMsY0FBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDeEUsTUFBTSxJQUFBLHVCQUFVLEVBQUMsaUJBQWlCLGdCQUFnQixPQUFPLEtBQUssQ0FBQyxPQUFPLENBQUMscUJBQXFCLENBQUMsQ0FBQztJQUM5RixPQUFPLE9BQU8sQ0FBQztBQUNuQixDQUFDO0FBRUQ7dUNBQ3VDO0FBQ3ZDLEtBQUssVUFBVSxXQUFXLENBQUMsT0FBZTtJQUN0QyxJQUFJLFFBQVEsR0FBRyxNQUFNLGtCQUFFLENBQUMsUUFBUSxDQUFDLEdBQUcsT0FBTyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDM0QsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsR0FBRyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3RELElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLDRCQUE0QixPQUFPLGFBQWEsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUscUJBQXFCLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDaEgsQ0FBQztJQUNELE9BQU8sR0FBRyxPQUFPLElBQUksT0FBTyxFQUFFLENBQUM7QUFDbkMsQ0FBQztBQUVEOytGQUMrRjtBQUMvRixLQUFLLFVBQVUsa0JBQWtCLENBQUMsUUFBZ0I7SUFDOUMsSUFBSSxjQUFjLEdBQUcsY0FBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUM1RCxJQUFJLENBQUMsTUFBTSxVQUFVLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQztRQUNwQyxPQUFPO0lBQ1gsQ0FBQztJQUNELElBQUksUUFBUSxHQUFHLElBQUEsZ0NBQWUsRUFBQyxJQUFBLDhCQUFhLEVBQUMsTUFBTSxrQkFBRSxDQUFDLFFBQVEsQ0FBQyxjQUFjLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3pGLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDbkIsT0FBTztJQUNYLENBQUM7SUFDRCxNQUFNLElBQUksS0FBSyxDQUNYLHlCQUF5QixjQUFjLGdEQUFnRDtVQUNyRixVQUFVLFFBQVEsQ0FBQyxNQUFNLGdCQUFnQjtVQUN6QyxRQUFRLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsT0FBTyxPQUFPLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7VUFDcEQsMkZBQTJGO1VBQzNGLHlGQUF5RjtVQUN6Riw4REFBOEQsQ0FDbkUsQ0FBQztBQUNOLENBQUM7QUFFRDs7eURBRXlEO0FBQ3pELEtBQUssVUFBVSxpQkFBaUIsQ0FBQyxRQUFnQjtJQUM3QyxJQUFJLENBQUMsTUFBTSxVQUFVLENBQUMsY0FBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDNUQsT0FBTztJQUNYLENBQUM7SUFDRCx1RkFBdUY7SUFDdkYsSUFBSSxNQUFNLEdBQUcsTUFBTSxJQUFBLG9CQUFZLEVBQUMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRSxTQUFTLEVBQUUsUUFBUSxDQUFDLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDMUcsSUFBSSxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNyQyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDcEMsT0FBTztJQUNYLENBQUM7SUFDRCxJQUFJLE9BQU8sQ0FBQztJQUNaLElBQUksQ0FBQztRQUNELE9BQU8sR0FBRyxNQUFNLElBQUEsNEJBQWlCLEVBQUMsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUM7SUFDMUUsQ0FBQztJQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDVCxnRkFBZ0Y7UUFDaEYsT0FBTztJQUNYLENBQUM7SUFDRCxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2xCLE9BQU87SUFDWCxDQUFDO0lBQ0QsTUFBTSxJQUFJLEtBQUssQ0FDWCxZQUFZLFFBQVEsc0NBQXNDLE9BQU8sQ0FBQyxNQUFNLEtBQUs7VUFDM0UsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRTs7WUFBQyxPQUFBLEtBQUssS0FBSyxDQUFDLFVBQVUsQ0FBQyxXQUFXLGVBQWUsS0FBSyxDQUFDLFVBQVUsQ0FBQyxTQUFTLElBQUksR0FBRyxFQUFFO2tCQUNwRyxtQkFBbUIsQ0FBQSxNQUFBLEtBQUssQ0FBQyxVQUFVLENBQUMsT0FBTywwQ0FBRSxFQUFFLEtBQUksR0FBRyxFQUFFLENBQUE7U0FBQSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztVQUN4RSxzRkFBc0YsQ0FDM0YsQ0FBQztBQUNOLENBQUM7QUFFRCxTQUFTLFNBQVMsQ0FBQyxJQUFjO0lBQzdCLElBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDM0MsSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxXQUFXLENBQUMsQ0FBQztJQUN6RCxJQUFJLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDeEIsTUFBTSxJQUFJLEtBQUssQ0FBQyx1Q0FBdUMsVUFBVSxDQUFDLE1BQU0saUJBQWlCLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssS0FBSyxFQUFFLENBQUMsQ0FBQztJQUMvSCxDQUFDO0lBQ0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUM7QUFDakQsQ0FBQztBQUVEOzRGQUM0RjtBQUNyRixLQUFLLFVBQVUsUUFBUSxDQUFDLE1BQThDO0lBQ3pFLElBQUksRUFBRSxRQUFRLEVBQUUsR0FBRyxNQUFNLENBQUM7SUFDMUIsSUFBSSxVQUFVLEdBQUcsTUFBTSxDQUFDLE9BQU8sSUFBSSxJQUFBLGtCQUFVLEVBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLE1BQU0sZ0JBQWdCLEVBQUUsQ0FBQztJQUMxRixJQUFJLENBQUMsTUFBTSxVQUFVLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztRQUNoQyxNQUFNLElBQUksS0FBSyxDQUFDLDZCQUE2QixVQUFVLHVCQUF1QixDQUFDLENBQUM7SUFDcEYsQ0FBQztJQUVELE1BQU0sa0JBQWtCLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDbkMsTUFBTSxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUVsQyxJQUFJLFFBQVEsR0FBRyxNQUFNLElBQUEsd0JBQWEsRUFBQyxRQUFRLENBQUMsQ0FBQztJQUM3QyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsd0JBQWEsV0FBVyxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sZUFBZSxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBRXZGLDBGQUEwRjtJQUMxRiw2RkFBNkY7SUFDN0YsMERBQTBEO0lBQzFELElBQUksZ0JBQWdCLEdBQUcsTUFBTSxrQkFBRSxDQUFDLE9BQU8sQ0FBQyxjQUFJLENBQUMsSUFBSSxDQUFDLFlBQUUsQ0FBQyxNQUFNLEVBQUUsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQzlFLElBQUksY0FBYyxHQUFHLGNBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsd0JBQWEsQ0FBQyxDQUFDO0lBQ2hFLElBQUksZUFBZSxHQUFHLEdBQUcsY0FBYyxNQUFNLENBQUM7SUFDOUMsTUFBTSxrQkFBRSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsSUFBQSx5QkFBYyxFQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFFN0QsK0ZBQStGO0lBQy9GLE1BQU0sSUFBQSx1QkFBVSxFQUFDLHlCQUF5QixLQUFLLENBQUMsVUFBVSxDQUFDLE9BQU8seUJBQWMsSUFBSSxLQUFLLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzdHLHNGQUFzRjtJQUN0RixNQUFNLElBQUEsdUJBQVUsRUFDWixxQ0FBcUMseUJBQWMsT0FBTyxLQUFLLENBQUMsZUFBZSxDQUFDLE1BQU0sS0FBSyxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQ2hILENBQUM7SUFDRixNQUFNLGtCQUFFLENBQUMsUUFBUSxDQUFDLGNBQWMsRUFBRSxjQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSx3QkFBYSxDQUFDLENBQUMsQ0FBQztJQUN0RSxNQUFNLGtCQUFFLENBQUMsUUFBUSxDQUFDLGVBQWUsRUFBRSxjQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSx5QkFBYyxDQUFDLENBQUMsQ0FBQztJQUN4RSxNQUFNLGtCQUFFLENBQUMsRUFBRSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUNoRSxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsTUFBTSxXQUFXLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ2hFLENBQUM7QUEvQkQsNEJBK0JDO0FBRU0sS0FBSyxVQUFVLElBQUk7SUFDdEIsSUFBSSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUU5RCw2RkFBNkY7SUFDN0Ysa0ZBQWtGO0lBQ2xGLElBQUksUUFBUSxHQUFHLE1BQU0sSUFBQSxvQkFBWSxFQUFDLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsaUJBQWlCLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDOUYsSUFBSSxRQUFRLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUN0QyxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDckMsTUFBTSxJQUFJLEtBQUssQ0FDWCxzRUFBc0U7Y0FDcEUsR0FBRyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLEtBQUssRUFBRSxDQUM5RCxDQUFDO0lBQ04sQ0FBQztJQUNELE1BQU0sUUFBUSxDQUFDLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFFdEMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ2IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsd0JBQWEsUUFBUSx5QkFBYyw0QkFBNEIsQ0FBQyxDQUFDO1FBQ2hHLE9BQU87SUFDWCxDQUFDO0lBQ0QsTUFBTSxJQUFBLHVCQUFVLEVBQUMsWUFBWSxFQUFFLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDbEQsOEZBQThGO0lBQzlGLGtGQUFrRjtJQUNsRixJQUFJLE1BQU0sR0FBRyxNQUFNLElBQUEsb0JBQVksRUFBQyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFLGFBQWEsQ0FBQyxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQ3BHLElBQUksTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDM0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDO1FBQ2pCLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLHdCQUFhLFFBQVEseUJBQWMseUJBQXlCLENBQUMsQ0FBQztRQUM5RixPQUFPO0lBQ1gsQ0FBQztJQUNELE1BQU0sSUFBQSx1QkFBVSxFQUFDLGlCQUFpQixLQUFLLENBQUMsY0FBYyxDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQzlFLE1BQU0sSUFBQSx1QkFBVSxFQUFDLFVBQVUsRUFBRSxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQ2hELE9BQU8sQ0FBQyxHQUFHLENBQUMsdUJBQXVCLENBQUMsQ0FBQztBQUN6QyxDQUFDO0FBL0JELG9CQStCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBmcyBmcm9tIFwiZnMvcHJvbWlzZXNcIjtcbmltcG9ydCBvcyBmcm9tIFwib3NcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBydW5Qcm9taXNlIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvcnVuUHJvbWlzZVwiO1xuaW1wb3J0IHsgZXhwYW5kSG9tZSB9IGZyb20gXCIuLi9oZWxwZXJzL3BhdGhzXCI7XG5pbXBvcnQgeyBzcGF3blByb21pc2UgfSBmcm9tIFwiLi4vaGVscGVycy9zcGF3blwiO1xuaW1wb3J0IHsgYnVpbGRNYW5pZmVzdCwgZm9ybWF0TWFuaWZlc3QsIE1BTklGRVNUX05BTUUsIFNJR05BVFVSRV9OQU1FLCBTSUdOX05BTUVTUEFDRSB9IGZyb20gXCIuL21hbmlmZXN0XCI7XG5pbXBvcnQgeyByZXZva2VkS2V5c0luUmVwbyB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5cy91bnJldm9rZVwiO1xuaW1wb3J0IHsgZmluZEtleVByb2JsZW1zLCBub3JtYWxpemVLZXlzIH0gZnJvbSBcIi4uL2F1dGhvcml6ZWRLZXlzL2F1dGhvcml6ZWRLZXlzXCI7XG5cbi8vIEEgaGFyZHdhcmUgYmFja2VkIGtleSBpcyB0aGUgZW50aXJlIHBvaW50LiBBIGtleSBzaXR0aW5nIG9uIGRpc2sgaXMgY29tcHJvbWlzZWQgdGhlIG1vbWVudCB0aGVcbi8vIG1hY2hpbmUgaXMsIGFuZCB0aGVuIHRoZSBzaWduYXR1cmUgcHJvdmVzIG5vdGhpbmcsIHNvIHRoaXMgaXMgd2hhdCB3ZSBtYWtlIHdoZW4gYXNrZWQgdG8gbWFrZSBvbmUuXG5jb25zdCBERUZBVUxUX0tFWV9UWVBFID0gXCJlZDI1NTE5LXNrXCI7XG5jb25zdCBERUZBVUxUX0tFWV9QQVRIID0gXCJ+Ly5zc2gvc2lnbmZpbGVzX2VkMjU1MTlfc2tcIjtcbmNvbnN0IEdJVF9LRVlXT1JEID0gXCJnaXRcIjtcbmNvbnN0IENPTU1JVF9NRVNTQUdFID0gXCJkZXBsb3lpbmcgc2lnbmVkIGZpbGVzXCI7XG5jb25zdCBNQVhfRVJST1JfQk9EWV9MRU5HVEggPSA1MDA7XG5jb25zdCBVU0FHRSA9IGBVc2FnZTogeWFybiBzaWduZmlsZXMgW3NpZ25pbmcta2V5XSBbJHtHSVRfS0VZV09SRH1dXG5cblNpZ25zIHRoZSBmaWxlcyBvZiB0aGUgcmVwbyBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkuIFdpdGggbm8ga2V5LCBhIGhhcmR3YXJlIGJhY2tlZFxuJHtERUZBVUxUX0tFWV9UWVBFfSBrZXkgYXQgJHtERUZBVUxUX0tFWV9QQVRIfSBpcyB1c2VkLCBhbmQgY3JlYXRlZCBpZiBpdCBkb2VzIG5vdCBleGlzdC5cblBhc3MgJHtHSVRfS0VZV09SRH0gdG8gYWxzbyBjb21taXQgYW5kIHB1c2ggdGhlIHJlc3VsdC5gO1xuXG4vKiogcnVuUHJvbWlzZSB0YWtlcyBhIGNvbW1hbmQgbGluZSByYXRoZXIgdGhhbiBhbiBhcmd1bWVudCBsaXN0LCBzbyBhbnl0aGluZyBob2xkaW5nIGEgcGF0aCBoYXMgdG9cbiAgICBzdXJ2aXZlIHRoZSBzaGVsbC4gRG91YmxlIHF1b3RlcyB3b3JrIG9uIGJvdGggY21kIGFuZCBwb3NpeCBzaGVsbHMuICovXG5mdW5jdGlvbiBxdW90ZSh2YWx1ZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGBcIiR7dmFsdWV9XCJgO1xufVxuXG5hc3luYyBmdW5jdGlvbiBwYXRoRXhpc3RzKGZpbGVQYXRoOiBzdHJpbmcpIHtcbiAgICB0cnkge1xuICAgICAgICBhd2FpdCBmcy5hY2Nlc3MoZmlsZVBhdGgpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59XG5cbi8qKiBDcmVhdGluZyB0aGlzIG5lZWRzIHRoZSBzZWN1cml0eSBrZXkgcGx1Z2dlZCBpbiwgYW5kIGEgdG91Y2guICovXG5hc3luYyBmdW5jdGlvbiBlbnN1cmVEZWZhdWx0S2V5KCkge1xuICAgIGxldCBrZXlQYXRoID0gZXhwYW5kSG9tZShERUZBVUxUX0tFWV9QQVRIKTtcbiAgICBpZiAoYXdhaXQgcGF0aEV4aXN0cyhrZXlQYXRoKSkge1xuICAgICAgICByZXR1cm4ga2V5UGF0aDtcbiAgICB9XG4gICAgY29uc29sZS5sb2coYE5vIHNpZ25pbmcga2V5IGF0ICR7a2V5UGF0aH0sIGNyZWF0aW5nIGFuICR7REVGQVVMVF9LRVlfVFlQRX0gb25lLmApO1xuICAgIGNvbnNvbGUubG9nKGBQbHVnIHlvdXIgc2VjdXJpdHkga2V5IGluIC0geW91IHdpbGwgYmUgYXNrZWQgdG8gdG91Y2ggaXQuYCk7XG4gICAgYXdhaXQgZnMubWtkaXIocGF0aC5kaXJuYW1lKGtleVBhdGgpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSwgbW9kZTogMG83MDAgfSk7XG4gICAgYXdhaXQgcnVuUHJvbWlzZShgc3NoLWtleWdlbiAtdCAke0RFRkFVTFRfS0VZX1RZUEV9IC1mICR7cXVvdGUoa2V5UGF0aCl9IC1OIFwiXCIgLUMgc2lnbmZpbGVzYCk7XG4gICAgcmV0dXJuIGtleVBhdGg7XG59XG5cbi8qKiBUaGUgcHVibGljIGtleSBpbiB0aGUgZm9ybSB0aGUgZGFlbW9uIHJlcG9ydHMgaXQsIHNvIHdoYXQgaXMgcHJpbnRlZCBoZXJlIGNhbiBiZSBjb21wYXJlZFxuICAgIGFnYWluc3Qgd2hhdCBhcnJpdmVzIG9uIERpc2NvcmQuICovXG5hc3luYyBmdW5jdGlvbiBwdWJsaWNLZXlPZihrZXlQYXRoOiBzdHJpbmcpIHtcbiAgICBsZXQgY29udGVudHMgPSBhd2FpdCBmcy5yZWFkRmlsZShgJHtrZXlQYXRofS5wdWJgLCBcInV0ZjhcIik7XG4gICAgbGV0IFtrZXlUeXBlLCBrZXlCb2R5XSA9IGNvbnRlbnRzLnRyaW0oKS5zcGxpdCgvXFxzKy8pO1xuICAgIGlmICgha2V5VHlwZSB8fCAha2V5Qm9keSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGEgcHVibGljIGtleSBpbiAke2tleVBhdGh9LnB1Yiwgd2FzICR7Y29udGVudHMuc2xpY2UoMCwgTUFYX0VSUk9SX0JPRFlfTEVOR1RIKX1gKTtcbiAgICB9XG4gICAgcmV0dXJuIGAke2tleVR5cGV9ICR7a2V5Qm9keX1gO1xufVxuXG4vKiogQSBrZXlzIHJlcG8gaGFzIHJ1bGVzIHRoZSByZXN0IG9mIHRoaXMgY2Fubm90IGVuZm9yY2UgYWZ0ZXJ3YXJkcywgc28gdGhleSBhcmUgZW5mb3JjZWQgYmVmb3JlIGl0XG4gICAgaXMgc2lnbmVkLiBTaWduaW5nIGFueXRoaW5nIHRoYXQgaXMgbm90IGEga2V5cyByZXBvIGlzIG5vbmUgb2YgdGhpcyBmdW5jdGlvbidzIGJ1c2luZXNzLiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVmdXNlVW51c2FibGVLZXlzKHJlcG9QYXRoOiBzdHJpbmcpIHtcbiAgICBsZXQgYXV0aG9yaXplZFBhdGggPSBwYXRoLmpvaW4ocmVwb1BhdGgsIFwiYXV0aG9yaXplZF9rZXlzXCIpO1xuICAgIGlmICghYXdhaXQgcGF0aEV4aXN0cyhhdXRob3JpemVkUGF0aCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgcHJvYmxlbXMgPSBmaW5kS2V5UHJvYmxlbXMobm9ybWFsaXplS2V5cyhhd2FpdCBmcy5yZWFkRmlsZShhdXRob3JpemVkUGF0aCwgXCJ1dGY4XCIpKSk7XG4gICAgaWYgKCFwcm9ibGVtcy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBFeHBlY3RlZCBldmVyeSBrZXkgaW4gJHthdXRob3JpemVkUGF0aH0gdG8gYmUgcmVzdHJpY3RlZCBhbmQgdG8gYmVsb25nIHRvIG9uZSBwZXJzb24sYFxuICAgICAgICArIGAgZm91bmQgJHtwcm9ibGVtcy5sZW5ndGh9IHByb2JsZW0ocyk6XFxuYFxuICAgICAgICArIHByb2JsZW1zLm1hcChwcm9ibGVtID0+IGAgIC0gJHtwcm9ibGVtfWApLmpvaW4oXCJcXG5cIilcbiAgICAgICAgKyBgXFxuXFxuRXZlcnkga2V5IG5lZWRzIGEgZnJvbT0gbmFtaW5nIHRoZSBhZGRyZXNzZXMgaXQgbWF5IGJlIHVzZWQgZnJvbSwgYW5kIG5vIHR3byBrZXlzIG1heWBcbiAgICAgICAgKyBgXFxubmFtZSB0aGUgc2FtZSBvbmVzLiBSZXZva2luZyBhIGtleSB0aGF0IHNoYXJlcyBpdHMgYWRkcmVzc2VzIHdpdGggYW5vdGhlciBsZWF2ZXMgdGhhdGBcbiAgICAgICAgKyBgXFxub3RoZXIga2V5IHdvcmtpbmcsIHdoaWNoIGRlZmVhdHMgdGhlIHBvaW50IG9mIHJldm9raW5nIGl0LmBcbiAgICApO1xufVxuXG4vKiogU2lnbmluZyBhIGtleXMgcmVwbyB0aGF0IHN0aWxsIGhvbGRzIGEgcmV2b2tlZCBrZXkgd291bGQgcHVibGlzaCBpdCBiYWNrIHRvIGV2ZXJ5IG1hY2hpbmUgdGhhdFxuICAgIHRvb2sgaXQgb3V0LiBPbmx5IGFwcGxpZXMgdG8gYSByZXBvIHRoYXQgaG9sZHMga2V5cyBhbmQgaGFzIGEgcmV2b2tlIHJlcG8gdG8gY2hlY2sgLSBzaWduaW5nXG4gICAgYW55dGhpbmcgZWxzZSBpcyBub25lIG9mIHRoaXMgZnVuY3Rpb24ncyBidXNpbmVzcy4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlZnVzZVJldm9rZWRLZXlzKHJlcG9QYXRoOiBzdHJpbmcpIHtcbiAgICBpZiAoIWF3YWl0IHBhdGhFeGlzdHMocGF0aC5qb2luKHJlcG9QYXRoLCBcImF1dGhvcml6ZWRfa2V5c1wiKSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBSZWFkIGZvciBpdHMgdmFsdWUsIHNvIHN0ZG91dCBoYXMgdG8gYmUgb24gaXRzIG93bi4gcnVuUHJvbWlzZSBqb2lucyBpdCB3aXRoIHN0ZGVyci5cbiAgICBsZXQgb3JpZ2luID0gYXdhaXQgc3Bhd25Qcm9taXNlKHsgY29tbWFuZDogXCJnaXRcIiwgYXJnczogW1wicmVtb3RlXCIsIFwiZ2V0LXVybFwiLCBcIm9yaWdpblwiXSwgY3dkOiByZXBvUGF0aCB9KTtcbiAgICBsZXQgb3JpZ2luVVJMID0gb3JpZ2luLnN0ZG91dC50cmltKCk7XG4gICAgaWYgKG9yaWdpbi5zdGF0dXMgIT09IDAgfHwgIW9yaWdpblVSTCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCByZXZva2VkO1xuICAgIHRyeSB7XG4gICAgICAgIHJldm9rZWQgPSBhd2FpdCByZXZva2VkS2V5c0luUmVwbyh7IHJlcG9QYXRoLCBzb3VyY2VVUkw6IG9yaWdpblVSTCB9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIE5vIHJldm9rZSByZXBvLCBvciBubyBhY2Nlc3MgdG8gaXQuIE5vdGhpbmcgaGFzIGJlZW4gcmV2b2tlZCB0aGF0IHdlIGNhbiBzZWUuXG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCFyZXZva2VkLmxlbmd0aCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEV4cGVjdGVkICR7cmVwb1BhdGh9IHRvIGhvbGQgbm8gcmV2b2tlZCBrZXlzLCBpdCBob2xkcyAke3Jldm9rZWQubGVuZ3RofTpcXG5gXG4gICAgICAgICsgcmV2b2tlZC5tYXAoZW50cnkgPT4gYCAgJHtlbnRyeS5yZXZvY2F0aW9uLmZpbmdlcnByaW50fSByZXZva2VkIGJ5ICR7ZW50cnkucmV2b2NhdGlvbi5yZXZva2VkQnkgfHwgXCI/XCJ9YFxuICAgICAgICAgICAgKyBgIGFmdGVyIHVzZSBmcm9tICR7ZW50cnkucmV2b2NhdGlvbi5hdHRlbXB0Py5pcCB8fCBcIj9cIn1gKS5qb2luKFwiXFxuXCIpXG4gICAgICAgICsgYFxcbkRlbGV0ZSB0aGVtIGZyb20gYXV0aG9yaXplZF9rZXlzLCBvciBydW4gXCJ5YXJuIHVucmV2b2tlXCIgaGVyZSB0byBhbGxvdyB0aGVtIGFnYWluLmBcbiAgICApO1xufVxuXG5mdW5jdGlvbiBwYXJzZUFyZ3MoYXJndjogc3RyaW5nW10pIHtcbiAgICBsZXQgcHVzaFRvR2l0ID0gYXJndi5pbmNsdWRlcyhHSVRfS0VZV09SRCk7XG4gICAgbGV0IHBvc2l0aW9uYWwgPSBhcmd2LmZpbHRlcihhcmcgPT4gYXJnICE9PSBHSVRfS0VZV09SRCk7XG4gICAgaWYgKHBvc2l0aW9uYWwubGVuZ3RoID4gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGF0IG1vc3QgYSBzaWduaW5nIGtleSwgd2FzICR7cG9zaXRpb25hbC5sZW5ndGh9IGFyZ3VtZW50KHMpOiAke3Bvc2l0aW9uYWwuam9pbihcIiBcIil9XFxuJHtVU0FHRX1gKTtcbiAgICB9XG4gICAgcmV0dXJuIHsga2V5UGF0aDogcG9zaXRpb25hbFswXSwgcHVzaFRvR2l0IH07XG59XG5cbi8qKiBXcml0ZXMgdGhlIG1hbmlmZXN0IGFuZCBpdHMgc2lnbmF0dXJlIGludG8gYSByZXBvLiBTZXBhcmF0ZSBmcm9tIHRoZSBjb21tYW5kIHNvIGFueXRoaW5nIHRoYXRcbiAgICBjaGFuZ2VzIGEga2V5cyByZXBvIGNhbiBsZWF2ZSBpdCBzaWduZWQsIHJhdGhlciB0aGFuIHRlbGxpbmcgc29tZW9uZSB0byBnbyBhbmQgZG8gaXQuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2lnblJlcG8oY29uZmlnOiB7IHJlcG9QYXRoOiBzdHJpbmc7IGtleVBhdGg/OiBzdHJpbmcgfSkge1xuICAgIGxldCB7IHJlcG9QYXRoIH0gPSBjb25maWc7XG4gICAgbGV0IHNpZ25pbmdLZXkgPSBjb25maWcua2V5UGF0aCAmJiBleHBhbmRIb21lKGNvbmZpZy5rZXlQYXRoKSB8fCBhd2FpdCBlbnN1cmVEZWZhdWx0S2V5KCk7XG4gICAgaWYgKCFhd2FpdCBwYXRoRXhpc3RzKHNpZ25pbmdLZXkpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgYSBzaWduaW5nIGtleSBhdCAke3NpZ25pbmdLZXl9LCBubyBzdWNoIGZpbGUgZXhpc3RzYCk7XG4gICAgfVxuXG4gICAgYXdhaXQgcmVmdXNlVW51c2FibGVLZXlzKHJlcG9QYXRoKTtcbiAgICBhd2FpdCByZWZ1c2VSZXZva2VkS2V5cyhyZXBvUGF0aCk7XG5cbiAgICBsZXQgbWFuaWZlc3QgPSBhd2FpdCBidWlsZE1hbmlmZXN0KHJlcG9QYXRoKTtcbiAgICBjb25zb2xlLmxvZyhgJHtNQU5JRkVTVF9OQU1FfSBjb3ZlcnMgJHttYW5pZmVzdC5maWxlcy5sZW5ndGh9IGZpbGUocykgaW4gJHtyZXBvUGF0aH1gKTtcblxuICAgIC8vIFRoZSBtYW5pZmVzdCBpcyBidWlsdCBhbmQgc2lnbmVkIGF3YXkgZnJvbSB0aGUgcmVwbywgYW5kIG9ubHkgbW92ZWQgaW4gb25jZSBib3RoIGV4aXN0LlxuICAgIC8vIExhbmRpbmcgYSBuZXcgbWFuaWZlc3QgbmV4dCB0byBhbiBvbGQgc2lnbmF0dXJlIHByb2R1Y2VzIGEgcGFpciB0aGF0IGNhbiBuZXZlciB2ZXJpZnksIGFuZFxuICAgIC8vIHRoZSBkYWVtb24gcmVhZGluZyBpdCBjYW4gb25seSB0cmVhdCB0aGF0IGFzIHRhbXBlcmluZy5cbiAgICBsZXQgc3RhZ2luZ0RpcmVjdG9yeSA9IGF3YWl0IGZzLm1rZHRlbXAocGF0aC5qb2luKG9zLnRtcGRpcigpLCBcInNpZ25maWxlcy1cIikpO1xuICAgIGxldCBzdGFnZWRNYW5pZmVzdCA9IHBhdGguam9pbihzdGFnaW5nRGlyZWN0b3J5LCBNQU5JRkVTVF9OQU1FKTtcbiAgICBsZXQgc3RhZ2VkU2lnbmF0dXJlID0gYCR7c3RhZ2VkTWFuaWZlc3R9LnNpZ2A7XG4gICAgYXdhaXQgZnMud3JpdGVGaWxlKHN0YWdlZE1hbmlmZXN0LCBmb3JtYXRNYW5pZmVzdChtYW5pZmVzdCkpO1xuXG4gICAgLy8gU2lnbmluZyBoYXBwZW5zIGJlZm9yZSBhbnkgZ2l0IHdvcmssIHNvIGEgZmFpbGVkIHB1c2ggbmV2ZXIgY29zdHMgYSBzZWNvbmQgdG91Y2ggb2YgdGhlIGtleS5cbiAgICBhd2FpdCBydW5Qcm9taXNlKGBzc2gta2V5Z2VuIC1ZIHNpZ24gLWYgJHtxdW90ZShzaWduaW5nS2V5KX0gLW4gJHtTSUdOX05BTUVTUEFDRX0gJHtxdW90ZShzdGFnZWRNYW5pZmVzdCl9YCk7XG4gICAgLy8gQ2hlY2tlZCBoZXJlIHJhdGhlciB0aGFuIGxlZnQgZm9yIGEgbWFjaGluZSB0aGF0IGhhcyBhbHJlYWR5IHB1bGxlZCBpdCB0byBkaXNjb3Zlci5cbiAgICBhd2FpdCBydW5Qcm9taXNlKFxuICAgICAgICBgc3NoLWtleWdlbiAtWSBjaGVjay1ub3ZhbGlkYXRlIC1uICR7U0lHTl9OQU1FU1BBQ0V9IC1zICR7cXVvdGUoc3RhZ2VkU2lnbmF0dXJlKX0gPCAke3F1b3RlKHN0YWdlZE1hbmlmZXN0KX1gXG4gICAgKTtcbiAgICBhd2FpdCBmcy5jb3B5RmlsZShzdGFnZWRNYW5pZmVzdCwgcGF0aC5qb2luKHJlcG9QYXRoLCBNQU5JRkVTVF9OQU1FKSk7XG4gICAgYXdhaXQgZnMuY29weUZpbGUoc3RhZ2VkU2lnbmF0dXJlLCBwYXRoLmpvaW4ocmVwb1BhdGgsIFNJR05BVFVSRV9OQU1FKSk7XG4gICAgYXdhaXQgZnMucm0oc3RhZ2luZ0RpcmVjdG9yeSwgeyByZWN1cnNpdmU6IHRydWUsIGZvcmNlOiB0cnVlIH0pO1xuICAgIGNvbnNvbGUubG9nKGBTaWduZWQgd2l0aCAke2F3YWl0IHB1YmxpY0tleU9mKHNpZ25pbmdLZXkpfWApO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbWFpbigpIHtcbiAgICBsZXQgeyBrZXlQYXRoLCBwdXNoVG9HaXQgfSA9IHBhcnNlQXJncyhwcm9jZXNzLmFyZ3Yuc2xpY2UoMikpO1xuXG4gICAgLy8gUmVhZCBmb3IgaXRzIHZhbHVlLCBzbyBzdGRvdXQgaGFzIHRvIGJlIG9uIGl0cyBvd24uIHJ1blByb21pc2Ugam9pbnMgaXQgd2l0aCBzdGRlcnIsIGFuZCBhXG4gICAgLy8gZ2l0IHdhcm5pbmcgZ2x1ZWQgdG8gdGhlIGZyb250IG9mIHRoaXMgYmVjb21lcyBhIGRpcmVjdG9yeSB0aGF0IGRvZXMgbm90IGV4aXN0LlxuICAgIGxldCB0b3BMZXZlbCA9IGF3YWl0IHNwYXduUHJvbWlzZSh7IGNvbW1hbmQ6IFwiZ2l0XCIsIGFyZ3M6IFtcInJldi1wYXJzZVwiLCBcIi0tc2hvdy10b3BsZXZlbFwiXSB9KTtcbiAgICBsZXQgcmVwb1BhdGggPSB0b3BMZXZlbC5zdGRvdXQudHJpbSgpO1xuICAgIGlmICh0b3BMZXZlbC5zdGF0dXMgIT09IDAgfHwgIXJlcG9QYXRoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBFeHBlY3RlZCB0aGUgY3VycmVudCBkaXJlY3RvcnkgdG8gYmUgaW5zaWRlIGEgZ2l0IHJlcG8sIGl0IGlzIG5vdC5cXG5gXG4gICAgICAgICAgICArIGAkeyh0b3BMZXZlbC5zdGRvdXQgKyB0b3BMZXZlbC5zdGRlcnIpLnRyaW0oKX1cXG4ke1VTQUdFfWBcbiAgICAgICAgKTtcbiAgICB9XG4gICAgYXdhaXQgc2lnblJlcG8oeyByZXBvUGF0aCwga2V5UGF0aCB9KTtcblxuICAgIGlmICghcHVzaFRvR2l0KSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBDb21taXQgYW5kIHB1c2ggJHtNQU5JRkVTVF9OQU1FfSBhbmQgJHtTSUdOQVRVUkVfTkFNRX0gZm9yIGFueXRoaW5nIHRvIHNlZSB0aGVtLmApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGF3YWl0IHJ1blByb21pc2UoYGdpdCBhZGQgLUFgLCB7IGN3ZDogcmVwb1BhdGggfSk7XG4gICAgLy8gTm90aGluZyBzdGFnZWQgaXMgbm90IHdvcnRoIHN0b3BwaW5nIG9uLiBnaXQgY29tbWl0IGNhbGxzIHRoYXQgYSBmYWlsdXJlLCBidXQgaXQgb25seSBtZWFuc1xuICAgIC8vIHRoZSBzaWduYXR1cmUgbWF0Y2hlcyB0aGUgb25lIGFscmVhZHkgY29tbWl0dGVkLCBzbyB0aGVyZSBpcyBub3RoaW5nIHRvIGRlcGxveS5cbiAgICBsZXQgc3RhdHVzID0gYXdhaXQgc3Bhd25Qcm9taXNlKHsgY29tbWFuZDogXCJnaXRcIiwgYXJnczogW1wic3RhdHVzXCIsIFwiLS1wb3JjZWxhaW5cIl0sIGN3ZDogcmVwb1BhdGggfSk7XG4gICAgbGV0IHN0YWdlZCA9IHN0YXR1cy5zdGRvdXQ7XG4gICAgaWYgKCFzdGFnZWQudHJpbSgpKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBOb3RoaW5nIGNoYW5nZWQsICR7TUFOSUZFU1RfTkFNRX0gYW5kICR7U0lHTkFUVVJFX05BTUV9IGFyZSBhbHJlYWR5IGNvbW1pdHRlZC5gKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBhd2FpdCBydW5Qcm9taXNlKGBnaXQgY29tbWl0IC1tICR7cXVvdGUoQ09NTUlUX01FU1NBR0UpfWAsIHsgY3dkOiByZXBvUGF0aCB9KTtcbiAgICBhd2FpdCBydW5Qcm9taXNlKGBnaXQgcHVzaGAsIHsgY3dkOiByZXBvUGF0aCB9KTtcbiAgICBjb25zb2xlLmxvZyhgQ29tbWl0dGVkIGFuZCBwdXNoZWQuYCk7XG59XG4iXX0=
181
- /* _JS_SOURCE_HASH = "5656bac7a766bdb1101df9294951fc82d227c63f880590d3dd4eb51bd67c88d1"; */
178
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbkZpbGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic2lnbkZpbGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLDJEQUE2QjtBQUM3Qiw0Q0FBb0I7QUFDcEIsZ0RBQXdCO0FBQ3hCLCtEQUE0RDtBQUM1RCw0Q0FBOEM7QUFDOUMsNENBQWdEO0FBQ2hELHlDQUEwRztBQUMxRyx5REFBK0Q7QUFDL0QseURBQTZEO0FBQzdELHFFQUFrRjtBQUVsRixpR0FBaUc7QUFDakcscUdBQXFHO0FBQ3JHLE1BQU0sZ0JBQWdCLEdBQUcsWUFBWSxDQUFDO0FBQ3RDLE1BQU0sZ0JBQWdCLEdBQUcsNkJBQTZCLENBQUM7QUFDdkQsTUFBTSxXQUFXLEdBQUcsS0FBSyxDQUFDO0FBQzFCLE1BQU0sY0FBYyxHQUFHLHdCQUF3QixDQUFDO0FBQ2hELE1BQU0scUJBQXFCLEdBQUcsR0FBRyxDQUFDO0FBQ2xDLE1BQU0sS0FBSyxHQUFHLHdDQUF3QyxXQUFXOzs7RUFHL0QsZ0JBQWdCLFdBQVcsZ0JBQWdCO09BQ3RDLFdBQVcsc0NBQXNDLENBQUM7QUFFekQ7MEVBQzBFO0FBQzFFLFNBQVMsS0FBSyxDQUFDLEtBQWE7SUFDeEIsT0FBTyxJQUFJLEtBQUssR0FBRyxDQUFDO0FBQ3hCLENBQUM7QUFFRCxLQUFLLFVBQVUsVUFBVSxDQUFDLFFBQWdCO0lBQ3RDLElBQUksQ0FBQztRQUNELE1BQU0sa0JBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDMUIsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDVCxPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDO0FBQ0wsQ0FBQztBQUVELG9FQUFvRTtBQUNwRSxLQUFLLFVBQVUsZ0JBQWdCO0lBQzNCLElBQUksT0FBTyxHQUFHLElBQUEsa0JBQVUsRUFBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQzNDLElBQUksTUFBTSxVQUFVLENBQUMsT0FB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QyxDQUFDO0FBQ3pDLENBQUM7QUExQkQsb0JBMEJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGZzIGZyb20gXCJmcy9wcm9taXNlc1wiO1xuaW1wb3J0IG9zIGZyb20gXCJvc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IHJ1blByb21pc2UgfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL3NyYy9ydW5Qcm9taXNlXCI7XG5pbXBvcnQgeyBleHBhbmRIb21lIH0gZnJvbSBcIi4uL2hlbHBlcnMvcGF0aHNcIjtcbmltcG9ydCB7IHNwYXduUHJvbWlzZSB9IGZyb20gXCIuLi9oZWxwZXJzL3NwYXduXCI7XG5pbXBvcnQgeyBidWlsZE1hbmlmZXN0LCBmb3JtYXRNYW5pZmVzdCwgTUFOSUZFU1RfTkFNRSwgU0lHTkFUVVJFX05BTUUsIFNJR05fTkFNRVNQQUNFIH0gZnJvbSBcIi4vbWFuaWZlc3RcIjtcbmltcG9ydCB7IHJldm9rZWRLZXlzSW5SZXBvIH0gZnJvbSBcIi4uL2F1dGhvcml6ZWRLZXlzL3VucmV2b2tlXCI7XG5pbXBvcnQgeyByZXNvbHZlS2V5c1JlcG8gfSBmcm9tIFwiLi4vYXV0aG9yaXplZEtleXMva2V5c1JlcG9cIjtcbmltcG9ydCB7IGZpbmRLZXlQcm9ibGVtcywgbm9ybWFsaXplS2V5cyB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5cy9hdXRob3JpemVkS2V5c1wiO1xuXG4vLyBBIGhhcmR3YXJlIGJhY2tlZCBrZXkgaXMgdGhlIGVudGlyZSBwb2ludC4gQSBrZXkgc2l0dGluZyBvbiBkaXNrIGlzIGNvbXByb21pc2VkIHRoZSBtb21lbnQgdGhlXG4vLyBtYWNoaW5lIGlzLCBhbmQgdGhlbiB0aGUgc2lnbmF0dXJlIHByb3ZlcyBub3RoaW5nLCBzbyB0aGlzIGlzIHdoYXQgd2UgbWFrZSB3aGVuIGFza2VkIHRvIG1ha2Ugb25lLlxuY29uc3QgREVGQVVMVF9LRVlfVFlQRSA9IFwiZWQyNTUxOS1za1wiO1xuY29uc3QgREVGQVVMVF9LRVlfUEFUSCA9IFwifi8uc3NoL3NpZ25maWxlc19lZDI1NTE5X3NrXCI7XG5jb25zdCBHSVRfS0VZV09SRCA9IFwiZ2l0XCI7XG5jb25zdCBDT01NSVRfTUVTU0FHRSA9IFwiZGVwbG95aW5nIHNpZ25lZCBmaWxlc1wiO1xuY29uc3QgTUFYX0VSUk9SX0JPRFlfTEVOR1RIID0gNTAwO1xuY29uc3QgVVNBR0UgPSBgVXNhZ2U6IHlhcm4gc2lnbmZpbGVzIFtzaWduaW5nLWtleV0gWyR7R0lUX0tFWVdPUkR9XVxuXG5TaWducyB0aGUgZmlsZXMgb2YgdGhlIHJlcG8gaW4gdGhlIGN1cnJlbnQgZGlyZWN0b3J5LiBXaXRoIG5vIGtleSwgYSBoYXJkd2FyZSBiYWNrZWRcbiR7REVGQVVMVF9LRVlfVFlQRX0ga2V5IGF0ICR7REVGQVVMVF9LRVlfUEFUSH0gaXMgdXNlZCwgYW5kIGNyZWF0ZWQgaWYgaXQgZG9lcyBub3QgZXhpc3QuXG5QYXNzICR7R0lUX0tFWVdPUkR9IHRvIGFsc28gY29tbWl0IGFuZCBwdXNoIHRoZSByZXN1bHQuYDtcblxuLyoqIHJ1blByb21pc2UgdGFrZXMgYSBjb21tYW5kIGxpbmUgcmF0aGVyIHRoYW4gYW4gYXJndW1lbnQgbGlzdCwgc28gYW55dGhpbmcgaG9sZGluZyBhIHBhdGggaGFzIHRvXG4gICAgc3Vydml2ZSB0aGUgc2hlbGwuIERvdWJsZSBxdW90ZXMgd29yayBvbiBib3RoIGNtZCBhbmQgcG9zaXggc2hlbGxzLiAqL1xuZnVuY3Rpb24gcXVvdGUodmFsdWU6IHN0cmluZykge1xuICAgIHJldHVybiBgXCIke3ZhbHVlfVwiYDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcGF0aEV4aXN0cyhmaWxlUGF0aDogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgZnMuYWNjZXNzKGZpbGVQYXRoKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuXG4vKiogQ3JlYXRpbmcgdGhpcyBuZWVkcyB0aGUgc2VjdXJpdHkga2V5IHBsdWdnZWQgaW4sIGFuZCBhIHRvdWNoLiAqL1xuYXN5bmMgZnVuY3Rpb24gZW5zdXJlRGVmYXVsdEtleSgpIHtcbiAgICBsZXQga2V5UGF0aCA9IGV4cGFuZEhvbWUoREVGQVVMVF9LRVlfUEFUSCk7XG4gICAgaWYgKGF3YWl0IHBhdGhFeGlzdHMoa2V5UGF0aCkpIHtcbiAgICAgICAgcmV0dXJuIGtleVBhdGg7XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKGBObyBzaWduaW5nIGtleSBhdCAke2tleVBhdGh9LCBjcmVhdGluZyBhbiAke0RFRkFVTFRfS0VZX1RZUEV9IG9uZS5gKTtcbiAgICBjb25zb2xlLmxvZyhgUGx1ZyB5b3VyIHNlY3VyaXR5IGtleSBpbiAtIHlvdSB3aWxsIGJlIGFza2VkIHRvIHRvdWNoIGl0LmApO1xuICAgIGF3YWl0IGZzLm1rZGlyKHBhdGguZGlybmFtZShrZXlQYXRoKSwgeyByZWN1cnNpdmU6IHRydWUsIG1vZGU6IDBvNzAwIH0pO1xuICAgIGF3YWl0IHJ1blByb21pc2UoYHNzaC1rZXlnZW4gLXQgJHtERUZBVUxUX0tFWV9UWVBFfSAtZiAke3F1b3RlKGtleVBhdGgpfSAtTiBcIlwiIC1DIHNpZ25maWxlc2ApO1xuICAgIHJldHVybiBrZXlQYXRoO1xufVxuXG4vKiogVGhlIHB1YmxpYyBrZXkgaW4gdGhlIGZvcm0gdGhlIGRhZW1vbiByZXBvcnRzIGl0LCBzbyB3aGF0IGlzIHByaW50ZWQgaGVyZSBjYW4gYmUgY29tcGFyZWRcbiAgICBhZ2FpbnN0IHdoYXQgYXJyaXZlcyBvbiBEaXNjb3JkLiAqL1xuYXN5bmMgZnVuY3Rpb24gcHVibGljS2V5T2Yoa2V5UGF0aDogc3RyaW5nKSB7XG4gICAgbGV0IGNvbnRlbnRzID0gYXdhaXQgZnMucmVhZEZpbGUoYCR7a2V5UGF0aH0ucHViYCwgXCJ1dGY4XCIpO1xuICAgIGxldCBba2V5VHlwZSwga2V5Qm9keV0gPSBjb250ZW50cy50cmltKCkuc3BsaXQoL1xccysvKTtcbiAgICBpZiAoIWtleVR5cGUgfHwgIWtleUJvZHkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBhIHB1YmxpYyBrZXkgaW4gJHtrZXlQYXRofS5wdWIsIHdhcyAke2NvbnRlbnRzLnNsaWNlKDAsIE1BWF9FUlJPUl9CT0RZX0xFTkdUSCl9YCk7XG4gICAgfVxuICAgIHJldHVybiBgJHtrZXlUeXBlfSAke2tleUJvZHl9YDtcbn1cblxuLyoqIEEga2V5cyByZXBvIGhhcyBydWxlcyB0aGUgcmVzdCBvZiB0aGlzIGNhbm5vdCBlbmZvcmNlIGFmdGVyd2FyZHMsIHNvIHRoZXkgYXJlIGVuZm9yY2VkIGJlZm9yZSBpdFxuICAgIGlzIHNpZ25lZC4gU2lnbmluZyBhbnl0aGluZyB0aGF0IGlzIG5vdCBhIGtleXMgcmVwbyBpcyBub25lIG9mIHRoaXMgZnVuY3Rpb24ncyBidXNpbmVzcy4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlZnVzZVVudXNhYmxlS2V5cyhyZXBvUGF0aDogc3RyaW5nKSB7XG4gICAgbGV0IGF1dGhvcml6ZWRQYXRoID0gcGF0aC5qb2luKHJlcG9QYXRoLCBcImF1dGhvcml6ZWRfa2V5c1wiKTtcbiAgICBpZiAoIWF3YWl0IHBhdGhFeGlzdHMoYXV0aG9yaXplZFBhdGgpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IHByb2JsZW1zID0gZmluZEtleVByb2JsZW1zKG5vcm1hbGl6ZUtleXMoYXdhaXQgZnMucmVhZEZpbGUoYXV0aG9yaXplZFBhdGgsIFwidXRmOFwiKSkpO1xuICAgIGlmICghcHJvYmxlbXMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgRXhwZWN0ZWQgZXZlcnkga2V5IGluICR7YXV0aG9yaXplZFBhdGh9IHRvIGJlIHJlc3RyaWN0ZWQgYW5kIHRvIGJlbG9uZyB0byBvbmUgcGVyc29uLGBcbiAgICAgICAgKyBgIGZvdW5kICR7cHJvYmxlbXMubGVuZ3RofSBwcm9ibGVtKHMpOlxcbmBcbiAgICAgICAgKyBwcm9ibGVtcy5tYXAocHJvYmxlbSA9PiBgICAtICR7cHJvYmxlbX1gKS5qb2luKFwiXFxuXCIpXG4gICAgICAgICsgYFxcblxcbkV2ZXJ5IGtleSBuZWVkcyBhIGZyb209IG5hbWluZyB0aGUgYWRkcmVzc2VzIGl0IG1heSBiZSB1c2VkIGZyb20sIGFuZCBubyB0d28ga2V5cyBtYXlgXG4gICAgICAgICsgYFxcbm5hbWUgdGhlIHNhbWUgb25lcy4gUmV2b2tpbmcgYSBrZXkgdGhhdCBzaGFyZXMgaXRzIGFkZHJlc3NlcyB3aXRoIGFub3RoZXIgbGVhdmVzIHRoYXRgXG4gICAgICAgICsgYFxcbm90aGVyIGtleSB3b3JraW5nLCB3aGljaCBkZWZlYXRzIHRoZSBwb2ludCBvZiByZXZva2luZyBpdC5gXG4gICAgKTtcbn1cblxuLyoqIFNpZ25pbmcgYSBrZXlzIHJlcG8gdGhhdCBzdGlsbCBob2xkcyBhIHJldm9rZWQga2V5IHdvdWxkIHB1Ymxpc2ggaXQgYmFjayB0byBldmVyeSBtYWNoaW5lIHRoYXRcbiAgICB0b29rIGl0IG91dC4gT25seSBhcHBsaWVzIHRvIGEgcmVwbyB0aGF0IGhvbGRzIGtleXMgYW5kIGhhcyBhIHJldm9rZSByZXBvIHRvIGNoZWNrIC0gc2lnbmluZ1xuICAgIGFueXRoaW5nIGVsc2UgaXMgbm9uZSBvZiB0aGlzIGZ1bmN0aW9uJ3MgYnVzaW5lc3MuICovXG5hc3luYyBmdW5jdGlvbiByZWZ1c2VSZXZva2VkS2V5cyhyZXBvUGF0aDogc3RyaW5nKSB7XG4gICAgaWYgKCFhd2FpdCBwYXRoRXhpc3RzKHBhdGguam9pbihyZXBvUGF0aCwgXCJhdXRob3JpemVkX2tleXNcIikpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gUmVhZCBmb3IgaXRzIHZhbHVlLCBzbyBzdGRvdXQgaGFzIHRvIGJlIG9uIGl0cyBvd24uIHJ1blByb21pc2Ugam9pbnMgaXQgd2l0aCBzdGRlcnIuXG4gICAgbGV0IG9yaWdpbiA9IGF3YWl0IHNwYXduUHJvbWlzZSh7IGNvbW1hbmQ6IFwiZ2l0XCIsIGFyZ3M6IFtcInJlbW90ZVwiLCBcImdldC11cmxcIiwgXCJvcmlnaW5cIl0sIGN3ZDogcmVwb1BhdGggfSk7XG4gICAgbGV0IG9yaWdpblVSTCA9IG9yaWdpbi5zdGRvdXQudHJpbSgpO1xuICAgIGlmIChvcmlnaW4uc3RhdHVzICE9PSAwIHx8ICFvcmlnaW5VUkwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgcmV2b2tlZDtcbiAgICB0cnkge1xuICAgICAgICByZXZva2VkID0gYXdhaXQgcmV2b2tlZEtleXNJblJlcG8oeyByZXBvUGF0aCwgc291cmNlVVJMOiBvcmlnaW5VUkwgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBObyByZXZva2UgcmVwbywgb3Igbm8gYWNjZXNzIHRvIGl0LiBOb3RoaW5nIGhhcyBiZWVuIHJldm9rZWQgdGhhdCB3ZSBjYW4gc2VlLlxuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghcmV2b2tlZC5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBFeHBlY3RlZCAke3JlcG9QYXRofSB0byBob2xkIG5vIHJldm9rZWQga2V5cywgaXQgaG9sZHMgJHtyZXZva2VkLmxlbmd0aH06XFxuYFxuICAgICAgICArIHJldm9rZWQubWFwKGVudHJ5ID0+IGAgICR7ZW50cnkucmV2b2NhdGlvbi5maW5nZXJwcmludH0gcmV2b2tlZCBieSAke2VudHJ5LnJldm9jYXRpb24ucmV2b2tlZEJ5IHx8IFwiP1wifWBcbiAgICAgICAgICAgICsgYCBhZnRlciB1c2UgZnJvbSAke2VudHJ5LnJldm9jYXRpb24uYXR0ZW1wdD8uaXAgfHwgXCI/XCJ9YCkuam9pbihcIlxcblwiKVxuICAgICAgICArIGBcXG5EZWxldGUgdGhlbSBmcm9tIGF1dGhvcml6ZWRfa2V5cywgb3IgcnVuIFwieWFybiB1bnJldm9rZVwiIGhlcmUgdG8gYWxsb3cgdGhlbSBhZ2Fpbi5gXG4gICAgKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VBcmdzKGFyZ3Y6IHN0cmluZ1tdKSB7XG4gICAgbGV0IHB1c2hUb0dpdCA9IGFyZ3YuaW5jbHVkZXMoR0lUX0tFWVdPUkQpO1xuICAgIGxldCBwb3NpdGlvbmFsID0gYXJndi5maWx0ZXIoYXJnID0+IGFyZyAhPT0gR0lUX0tFWVdPUkQpO1xuICAgIGlmIChwb3NpdGlvbmFsLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBhdCBtb3N0IGEgc2lnbmluZyBrZXksIHdhcyAke3Bvc2l0aW9uYWwubGVuZ3RofSBhcmd1bWVudChzKTogJHtwb3NpdGlvbmFsLmpvaW4oXCIgXCIpfVxcbiR7VVNBR0V9YCk7XG4gICAgfVxuICAgIHJldHVybiB7IGtleVBhdGg6IHBvc2l0aW9uYWxbMF0sIHB1c2hUb0dpdCB9O1xufVxuXG4vKiogV3JpdGVzIHRoZSBtYW5pZmVzdCBhbmQgaXRzIHNpZ25hdHVyZSBpbnRvIGEgcmVwby4gU2VwYXJhdGUgZnJvbSB0aGUgY29tbWFuZCBzbyBhbnl0aGluZyB0aGF0XG4gICAgY2hhbmdlcyBhIGtleXMgcmVwbyBjYW4gbGVhdmUgaXQgc2lnbmVkLCByYXRoZXIgdGhhbiB0ZWxsaW5nIHNvbWVvbmUgdG8gZ28gYW5kIGRvIGl0LiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNpZ25SZXBvKGNvbmZpZzogeyByZXBvUGF0aDogc3RyaW5nOyBrZXlQYXRoPzogc3RyaW5nIH0pIHtcbiAgICBsZXQgeyByZXBvUGF0aCB9ID0gY29uZmlnO1xuICAgIGxldCBzaWduaW5nS2V5ID0gY29uZmlnLmtleVBhdGggJiYgZXhwYW5kSG9tZShjb25maWcua2V5UGF0aCkgfHwgYXdhaXQgZW5zdXJlRGVmYXVsdEtleSgpO1xuICAgIGlmICghYXdhaXQgcGF0aEV4aXN0cyhzaWduaW5nS2V5KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGEgc2lnbmluZyBrZXkgYXQgJHtzaWduaW5nS2V5fSwgbm8gc3VjaCBmaWxlIGV4aXN0c2ApO1xuICAgIH1cblxuICAgIGF3YWl0IHJlZnVzZVVudXNhYmxlS2V5cyhyZXBvUGF0aCk7XG4gICAgYXdhaXQgcmVmdXNlUmV2b2tlZEtleXMocmVwb1BhdGgpO1xuXG4gICAgbGV0IG1hbmlmZXN0ID0gYXdhaXQgYnVpbGRNYW5pZmVzdChyZXBvUGF0aCk7XG4gICAgY29uc29sZS5sb2coYCR7TUFOSUZFU1RfTkFNRX0gY292ZXJzICR7bWFuaWZlc3QuZmlsZXMubGVuZ3RofSBmaWxlKHMpIGluICR7cmVwb1BhdGh9YCk7XG5cbiAgICAvLyBUaGUgbWFuaWZlc3QgaXMgYnVpbHQgYW5kIHNpZ25lZCBhd2F5IGZyb20gdGhlIHJlcG8sIGFuZCBvbmx5IG1vdmVkIGluIG9uY2UgYm90aCBleGlzdC5cbiAgICAvLyBMYW5kaW5nIGEgbmV3IG1hbmlmZXN0IG5leHQgdG8gYW4gb2xkIHNpZ25hdHVyZSBwcm9kdWNlcyBhIHBhaXIgdGhhdCBjYW4gbmV2ZXIgdmVyaWZ5LCBhbmRcbiAgICAvLyB0aGUgZGFlbW9uIHJlYWRpbmcgaXQgY2FuIG9ubHkgdHJlYXQgdGhhdCBhcyB0YW1wZXJpbmcuXG4gICAgbGV0IHN0YWdpbmdEaXJlY3RvcnkgPSBhd2FpdCBmcy5ta2R0ZW1wKHBhdGguam9pbihvcy50bXBkaXIoKSwgXCJzaWduZmlsZXMtXCIpKTtcbiAgICBsZXQgc3RhZ2VkTWFuaWZlc3QgPSBwYXRoLmpvaW4oc3RhZ2luZ0RpcmVjdG9yeSwgTUFOSUZFU1RfTkFNRSk7XG4gICAgbGV0IHN0YWdlZFNpZ25hdHVyZSA9IGAke3N0YWdlZE1hbmlmZXN0fS5zaWdgO1xuICAgIGF3YWl0IGZzLndyaXRlRmlsZShzdGFnZWRNYW5pZmVzdCwgZm9ybWF0TWFuaWZlc3QobWFuaWZlc3QpKTtcblxuICAgIC8vIFNpZ25pbmcgaGFwcGVucyBiZWZvcmUgYW55IGdpdCB3b3JrLCBzbyBhIGZhaWxlZCBwdXNoIG5ldmVyIGNvc3RzIGEgc2Vjb25kIHRvdWNoIG9mIHRoZSBrZXkuXG4gICAgYXdhaXQgcnVuUHJvbWlzZShgc3NoLWtleWdlbiAtWSBzaWduIC1mICR7cXVvdGUoc2lnbmluZ0tleSl9IC1uICR7U0lHTl9OQU1FU1BBQ0V9ICR7cXVvdGUoc3RhZ2VkTWFuaWZlc3QpfWApO1xuICAgIC8vIENoZWNrZWQgaGVyZSByYXRoZXIgdGhhbiBsZWZ0IGZvciBhIG1hY2hpbmUgdGhhdCBoYXMgYWxyZWFkeSBwdWxsZWQgaXQgdG8gZGlzY292ZXIuXG4gICAgYXdhaXQgcnVuUHJvbWlzZShcbiAgICAgICAgYHNzaC1rZXlnZW4gLVkgY2hlY2stbm92YWxpZGF0ZSAtbiAke1NJR05fTkFNRVNQQUNFfSAtcyAke3F1b3RlKHN0YWdlZFNpZ25hdHVyZSl9IDwgJHtxdW90ZShzdGFnZWRNYW5pZmVzdCl9YFxuICAgICk7XG4gICAgYXdhaXQgZnMuY29weUZpbGUoc3RhZ2VkTWFuaWZlc3QsIHBhdGguam9pbihyZXBvUGF0aCwgTUFOSUZFU1RfTkFNRSkpO1xuICAgIGF3YWl0IGZzLmNvcHlGaWxlKHN0YWdlZFNpZ25hdHVyZSwgcGF0aC5qb2luKHJlcG9QYXRoLCBTSUdOQVRVUkVfTkFNRSkpO1xuICAgIGF3YWl0IGZzLnJtKHN0YWdpbmdEaXJlY3RvcnksIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgICBjb25zb2xlLmxvZyhgU2lnbmVkIHdpdGggJHthd2FpdCBwdWJsaWNLZXlPZihzaWduaW5nS2V5KX1gKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1haW4oKSB7XG4gICAgbGV0IHsga2V5UGF0aCwgcHVzaFRvR2l0IH0gPSBwYXJzZUFyZ3MocHJvY2Vzcy5hcmd2LnNsaWNlKDIpKTtcblxuICAgIC8vIFRoZSBrZXlzIHJlcG8sIHdoaWNoIGlzIHRoaXMgb25lIHdoZW4gaXQgaG9sZHMga2V5cyBhbmQgdGhpcyBtYWNoaW5lJ3Mgb3RoZXJ3aXNlLiBTaWduaW5nXG4gICAgLy8gd2hhdGV2ZXIgcmVwbyB0aGUgdGVybWluYWwgaGFwcGVuZWQgdG8gYmUgaW4gaXMgaG93IHlvdSBlbmQgdXAgc2lnbmluZyBzb21ldGhpbmcgdGhhdCBpcyBub3RcbiAgICAvLyBhIGtleXMgcmVwbyBhdCBhbGwuXG4gICAgbGV0IHsgcmVwb1BhdGggfSA9IGF3YWl0IHJlc29sdmVLZXlzUmVwbygpO1xuICAgIGNvbnNvbGUubG9nKGBTaWduaW5nICR7cmVwb1BhdGh9YCk7XG4gICAgYXdhaXQgc2lnblJlcG8oeyByZXBvUGF0aCwga2V5UGF0aCB9KTtcblxuICAgIGlmICghcHVzaFRvR2l0KSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBDb21taXQgYW5kIHB1c2ggJHtNQU5JRkVTVF9OQU1FfSBhbmQgJHtTSUdOQVRVUkVfTkFNRX0gZm9yIGFueXRoaW5nIHRvIHNlZSB0aGVtLmApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGF3YWl0IHJ1blByb21pc2UoYGdpdCBhZGQgLUFgLCB7IGN3ZDogcmVwb1BhdGggfSk7XG4gICAgLy8gTm90aGluZyBzdGFnZWQgaXMgbm90IHdvcnRoIHN0b3BwaW5nIG9uLiBnaXQgY29tbWl0IGNhbGxzIHRoYXQgYSBmYWlsdXJlLCBidXQgaXQgb25seSBtZWFuc1xuICAgIC8vIHRoZSBzaWduYXR1cmUgbWF0Y2hlcyB0aGUgb25lIGFscmVhZHkgY29tbWl0dGVkLCBzbyB0aGVyZSBpcyBub3RoaW5nIHRvIGRlcGxveS5cbiAgICBsZXQgc3RhdHVzID0gYXdhaXQgc3Bhd25Qcm9taXNlKHsgY29tbWFuZDogXCJnaXRcIiwgYXJnczogW1wic3RhdHVzXCIsIFwiLS1wb3JjZWxhaW5cIl0sIGN3ZDogcmVwb1BhdGggfSk7XG4gICAgbGV0IHN0YWdlZCA9IHN0YXR1cy5zdGRvdXQ7XG4gICAgaWYgKCFzdGFnZWQudHJpbSgpKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBOb3RoaW5nIGNoYW5nZWQsICR7TUFOSUZFU1RfTkFNRX0gYW5kICR7U0lHTkFUVVJFX05BTUV9IGFyZSBhbHJlYWR5IGNvbW1pdHRlZC5gKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBhd2FpdCBydW5Qcm9taXNlKGBnaXQgY29tbWl0IC1tICR7cXVvdGUoQ09NTUlUX01FU1NBR0UpfWAsIHsgY3dkOiByZXBvUGF0aCB9KTtcbiAgICBhd2FpdCBydW5Qcm9taXNlKGBnaXQgcHVzaGAsIHsgY3dkOiByZXBvUGF0aCB9KTtcbiAgICBjb25zb2xlLmxvZyhgQ29tbWl0dGVkIGFuZCBwdXNoZWQuYCk7XG59XG4iXX0=
179
+ /* _JS_SOURCE_HASH = "e62739f311ed1c2d2b818032186647cfb19cc96beec3178194cb15bda564b243"; */
@@ -0,0 +1,44 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ export declare const MANIFEST_NAME = "signedfiles.json";
4
+ export declare const SIGNATURE_NAME = "signedfiles.json.sig";
5
+ export declare const SIGN_NAMESPACE = "signfiles";
6
+ export declare const MANIFEST_VERSION = 1;
7
+ export type Manifest = {
8
+ version: number;
9
+ files: {
10
+ path: string;
11
+ size: number;
12
+ sha256: string;
13
+ }[];
14
+ };
15
+ /** Everything in the repo that is not ignored: what is in the index, plus what is not staged yet.
16
+ Git is asked because git is what knows how to apply the ignore rules.
17
+
18
+ What comes back is a hint that a file might be there, not that it is. A file deleted from the
19
+ working tree stays in the index until that deletion is staged, so git names it and there is
20
+ nothing to read, which is why each one is checked before it goes in.
21
+
22
+ The manifest and its signature are left out, since they cannot describe themselves. */
23
+ export declare function listRepoFiles(repoPath: string): Promise<string[]>;
24
+ /** A Windows checkout turns LF into CRLF, so the same commit hashes differently there than it
25
+ does on the machine that pulls it. Normalising first makes the digest describe the content
26
+ rather than whichever checkout produced it. latin1 round trips every byte, so this is safe on
27
+ files that are not text. */
28
+ export declare function normalizeContent(contents: Buffer): Buffer;
29
+ /** The size and hash of a file's normalised content. The size is the normalised one on purpose,
30
+ so it agrees with the hash rather than with whatever the local checkout happens to hold. */
31
+ export declare function digestFile(filePath: string): Promise<{
32
+ size: number;
33
+ sha256: string;
34
+ }>;
35
+ export declare function buildManifest(repoPath: string): Promise<{
36
+ version: number;
37
+ files: {
38
+ path: string;
39
+ size: number;
40
+ sha256: string;
41
+ }[];
42
+ }>;
43
+ /** Sorted keys and a trailing newline, so the same tree always produces the same bytes to sign. */
44
+ export declare function formatManifest(manifest: Manifest): string;
@@ -6,6 +6,7 @@ import { expandHome } from "../helpers/paths";
6
6
  import { spawnPromise } from "../helpers/spawn";
7
7
  import { buildManifest, formatManifest, MANIFEST_NAME, SIGNATURE_NAME, SIGN_NAMESPACE } from "./manifest";
8
8
  import { revokedKeysInRepo } from "../authorizedKeys/unrevoke";
9
+ import { resolveKeysRepo } from "../authorizedKeys/keysRepo";
9
10
  import { findKeyProblems, normalizeKeys } from "../authorizedKeys/authorizedKeys";
10
11
 
11
12
  // A hardware backed key is the entire point. A key sitting on disk is compromised the moment the
@@ -159,16 +160,11 @@ export async function signRepo(config: { repoPath: string; keyPath?: string }) {
159
160
  export async function main() {
160
161
  let { keyPath, pushToGit } = parseArgs(process.argv.slice(2));
161
162
 
162
- // Read for its value, so stdout has to be on its own. runPromise joins it with stderr, and a
163
- // git warning glued to the front of this becomes a directory that does not exist.
164
- let topLevel = await spawnPromise({ command: "git", args: ["rev-parse", "--show-toplevel"] });
165
- let repoPath = topLevel.stdout.trim();
166
- if (topLevel.status !== 0 || !repoPath) {
167
- throw new Error(
168
- `Expected the current directory to be inside a git repo, it is not.\n`
169
- + `${(topLevel.stdout + topLevel.stderr).trim()}\n${USAGE}`
170
- );
171
- }
163
+ // The keys repo, which is this one when it holds keys and this machine's otherwise. Signing
164
+ // whatever repo the terminal happened to be in is how you end up signing something that is not
165
+ // a keys repo at all.
166
+ let { repoPath } = await resolveKeysRepo();
167
+ console.log(`Signing ${repoPath}`);
172
168
  await signRepo({ repoPath, keyPath });
173
169
 
174
170
  if (!pushToGit) {
@@ -99,15 +99,14 @@ export class ArchivesRemote implements IArchives {
99
99
  }
100
100
  }
101
101
 
102
- // Returns undefined if this machine has access to the account. Otherwise puts in an access request and returns our machineId + ip (so the caller can display them alongside the link, for the approver to match the incoming request) and the link to the grant page.
102
+ // Returns undefined if this machine has access to the account. Otherwise returns our machineId + ip as the server sees them, and the link to the access page - which shows the single command that grants access.
103
103
  public async waitingForAccess(): Promise<{ link: string; machineId: string; ip: string } | undefined> {
104
104
  let state = await this.callAuthed(() => this.controller.getAccessState({ account: this.account }));
105
105
  if (state.hasAccess) return undefined;
106
- let requested = await this.callAuthed(() => this.controller.requestAccess({ account: this.account }));
107
106
  return {
108
107
  link: `https://${this.parsed.address}:${this.parsed.port}/${this.account}`,
109
- machineId: requested.machineId,
110
- ip: requested.ip,
108
+ machineId: state.machineId,
109
+ ip: state.ip,
111
110
  };
112
111
  }
113
112
 
@@ -116,13 +115,12 @@ export class ArchivesRemote implements IArchives {
116
115
  return !!state.hasAccess;
117
116
  }
118
117
 
119
- // Registers our access request server-side (so an admin has a requestId to grant) and logs the grant instructions, at most once a minute
118
+ // Logs how to get access, at most once a minute. There is nothing to register any more: the server decides from the signed repo, so what it hands back is the command that puts us in it.
120
119
  private async registerAccessRequest(): Promise<void> {
121
- let requested = await this.callAuthed(() => this.controller.requestAccess({ account: this.account }));
122
- if (Date.now() - this.lastDeniedLog > timeInMinute) {
123
- this.lastDeniedLog = Date.now();
124
- console.log(`No access to storage account ${JSON.stringify(this.account)} on ${this.parsed.address}:${this.parsed.port} (our machine ${requested.machineId}, ip ${requested.ip}). See https://${this.parsed.address}:${this.parsed.port}/${this.account} - or grant it with: ${requested.grantAccessCommand}`);
125
- }
120
+ if (Date.now() - this.lastDeniedLog < timeInMinute) return;
121
+ let state = await this.callAuthed(() => this.controller.getAccessState({ account: this.account }));
122
+ this.lastDeniedLog = Date.now();
123
+ console.log(`No access to storage account ${JSON.stringify(this.account)} on ${this.parsed.address}:${this.parsed.port} (our machine ${state.machineId}, ip ${state.ip}). ${state.reason || ""} Grant it with: ${state.addMachineCommand || ""}`);
126
124
  }
127
125
 
128
126
  // Runs a call, authenticating (and re-authenticating after reconnects) and waiting for account access as needed. With waitForAccess false, denied calls throw immediately instead - but the access request is still registered (in the background), so the denial is grantable.
@@ -6,10 +6,10 @@ import { observer } from "../../render-utils/observer";
6
6
  import { isNode } from "socket-function/src/misc";
7
7
  import { css } from "typesafecss";
8
8
  import { SocketFunction } from "socket-function/SocketFunction";
9
- import { RemoteStorageController, AccessState, AccessRequest } from "./storageController";
9
+ import { RemoteStorageController, AccessState } from "./storageController";
10
10
  import { authenticateStorage } from "./ArchivesRemote";
11
11
 
12
- // The storage server's access page. Visit https://<storageDomain>:<port>/<accountName> to request access to that account for this browser's machine identity. Once granted, lists the machines that have access. To approve someone else's request, the user must type in the requester's IP pending requests are NEVER shown unsolicited (so a trusted user can't accidentally approve a random machine's request).
12
+ // The storage server's access page. Visit https://<storageDomain>:<port>/<accountName> to see whether this browser's machine identity has access, and if not, the one command that grants it. Nothing is requested or approved here: trust lives in the signed authorized_keys repo, so access is granted by someone running addmachine there with the hardware key, and this page only reports what that repo says.
13
13
 
14
14
  const REFRESH_INTERVAL = 1000 * 15;
15
15
  const COPIED_RESET_DELAY = 2000;
@@ -45,11 +45,6 @@ class AccessPage extends preact.Component {
45
45
  account: "",
46
46
  state: undefined as AccessState | undefined,
47
47
  error: "",
48
- lookupIp: "",
49
- lookupResults: undefined as { ip: string; requests: AccessRequest[] } | undefined,
50
- lookupError: "",
51
- looking: false,
52
- granting: "",
53
48
  });
54
49
 
55
50
  componentDidMount() {
@@ -82,123 +77,51 @@ class AccessPage extends preact.Component {
82
77
  }
83
78
  private async refresh(account: string) {
84
79
  let controller = await this.controller();
85
- await controller.requestAccess({ account });
86
80
  this.synced.state = await controller.getAccessState({ account });
87
81
  this.synced.error = "";
88
82
  }
89
83
 
90
- private lookupIP = async () => {
91
- let ip = this.synced.lookupIp.trim();
92
- if (!ip) return;
93
- this.synced.looking = true;
94
- this.synced.lookupError = "";
95
- try {
96
- let controller = await this.controller();
97
- let requests = await controller.listRequestsForIP({ account: this.synced.account, ip });
98
- this.synced.lookupResults = { ip, requests };
99
- } catch (e) {
100
- this.synced.lookupError = String(e);
101
- } finally {
102
- this.synced.looking = false;
103
- }
104
- };
105
-
106
- private approve = async (request: AccessRequest) => {
107
- this.synced.granting = request.requestId;
108
- try {
109
- let controller = await this.controller();
110
- await controller.grantAccess({ requestId: request.requestId });
111
- if (this.synced.lookupResults) {
112
- this.synced.lookupResults.requests = this.synced.lookupResults.requests.filter(r => r.requestId !== request.requestId);
113
- }
114
- await this.refresh(this.synced.account);
115
- } catch (e) {
116
- this.synced.lookupError = String(e);
117
- } finally {
118
- this.synced.granting = "";
119
- }
120
- };
121
-
122
84
  render() {
123
85
  let synced = this.synced;
124
86
  let { account, state, error } = synced;
125
87
  if (!account) {
126
88
  return <div className={css.vbox(8).pad2(16)}>
127
89
  <div>Remote storage server.</div>
128
- <div>Visit /(account name) to request access to an account for this browser.</div>
90
+ <div>Visit /(account name) to see whether this browser's machine has access to an account.</div>
129
91
  </div>;
130
92
  }
131
93
  return <div className={css.vbox(12).pad2(16)}>
132
94
  <div>Storage account: {account}</div>
133
95
  {error && <div>Error: {error}</div>}
134
- {!state && !error && <div>Requesting access...</div>}
96
+ {!state && !error && <div>Checking access...</div>}
135
97
  {state && !state.hasAccess && <div className={css.vbox(8)}>
136
- <div>This machine ({state.machineId}, ip {state.ip}) does NOT have access yet.</div>
137
- <div>An access request has been made. To grant it, run this command:</div>
138
- {state.grantAccessCommand && <CopyableCommand command={state.grantAccessCommand} />}
98
+ <div>This machine ({state.machineId}, ip {state.ip}) does NOT have access.</div>
99
+ {state.reason && <div>{state.reason}</div>}
100
+ <div>Run this in the authorized_keys repo, on a machine with the signing key:</div>
101
+ {state.addMachineCommand && <CopyableCommand command={state.addMachineCommand} />}
139
102
  <div>This page rechecks every {REFRESH_INTERVAL / 1000} seconds.</div>
140
103
  </div>}
141
104
  {state && state.hasAccess && <div className={css.vbox(16)}>
142
105
  <div>This machine ({state.machineId}, ip {state.ip}) has access.</div>
143
106
  <div className={css.vbox(6)}>
144
- <div>Machines with access:</div>
107
+ <div>Trusted machines:</div>
145
108
  <table>
146
109
  <thead>
147
110
  <tr>
148
111
  <th className={css.pad2(8, 2).textAlign("left")}>Machine</th>
149
- <th className={css.pad2(8, 2).textAlign("left")}>IP</th>
150
- <th className={css.pad2(8, 2).textAlign("left")}>Granted</th>
112
+ <th className={css.pad2(8, 2).textAlign("left")}>Allowed from</th>
113
+ <th className={css.pad2(8, 2).textAlign("left")}>Added</th>
151
114
  </tr>
152
115
  </thead>
153
116
  <tbody>
154
117
  {(state.trustedMachines || []).map(m => <tr key={m.machineId}>
155
118
  <td className={css.pad2(8, 2)}>{m.machineId}</td>
156
- <td className={css.pad2(8, 2)}>{m.ip}</td>
157
- <td className={css.pad2(8, 2)}>{new Date(m.time).toLocaleString()}</td>
119
+ <td className={css.pad2(8, 2)}>{m.ips.join(", ")}</td>
120
+ <td className={css.pad2(8, 2)}>{m.addedAt}</td>
158
121
  </tr>)}
159
122
  </tbody>
160
123
  </table>
161
124
  </div>
162
- <div className={css.vbox(6)}>
163
- <div>Approve request</div>
164
- <div className={css.hbox(8).alignItems("center")}>
165
- <input
166
- placeholder="ip"
167
- value={synced.lookupIp}
168
- onInput={e => { synced.lookupIp = (e.currentTarget as HTMLInputElement).value; }}
169
- onKeyDown={e => { if (e.key === "Enter") void this.lookupIP(); }}
170
- />
171
- <button disabled={synced.looking || !synced.lookupIp.trim()} onClick={this.lookupIP}>
172
- search
173
- </button>
174
- </div>
175
- {synced.lookupError && <div>Error: {synced.lookupError}</div>}
176
- {synced.lookupResults && synced.lookupResults.requests.length === 0 && <div>
177
- No pending requests for {synced.lookupResults.ip} on this account.
178
- </div>}
179
- {synced.lookupResults && synced.lookupResults.requests.length > 0 && <table>
180
- <thead>
181
- <tr>
182
- <th className={css.pad2(8, 2).textAlign("left")}>Machine</th>
183
- <th className={css.pad2(8, 2).textAlign("left")}>IP</th>
184
- <th className={css.pad2(8, 2).textAlign("left")}>Requested</th>
185
- <th className={css.pad2(8, 2).textAlign("left")}></th>
186
- </tr>
187
- </thead>
188
- <tbody>
189
- {synced.lookupResults.requests.map(r => <tr key={r.requestId}>
190
- <td className={css.pad2(8, 2)}>{r.machineId}</td>
191
- <td className={css.pad2(8, 2)}>{r.ip}</td>
192
- <td className={css.pad2(8, 2)}>{new Date(r.time).toLocaleString()}</td>
193
- <td className={css.pad2(8, 2)}>
194
- <button disabled={!!synced.granting} onClick={async () => this.approve(r)}>
195
- {synced.granting === r.requestId && "Approving..." || "Approve"}
196
- </button>
197
- </td>
198
- </tr>)}
199
- </tbody>
200
- </table>}
201
- </div>
202
125
  </div>}
203
126
  </div>;
204
127
  }