sliftutils 1.7.147 → 1.7.148
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CLAUDE.md
CHANGED
|
@@ -9,6 +9,7 @@ from `.cursor/rules/*.mdc` so Claude reads them automatically.
|
|
|
9
9
|
- Don't run shell commands when you need to create or move small code files. Use tool calls. Use tool calls to make files within folders — you don't need to make the folder, just make the file, the folder will be created automatically.
|
|
10
10
|
- If you need to add a dependency, don't just edit `package.json`. Use `yarn add` so you get the latest version, unless the user specifies a version.
|
|
11
11
|
- Use tool calls to read and write files and directories, as opposed to shell commands running `ls`, `dir`, etc.
|
|
12
|
+
- Almost never run shell commands. Prefer a `yarn` command — if one doesn't exist for what you need, write it: a reusable script (an entry point in `bin/`, wired up in `package.json`) that anyone can run again, rather than a one-off shell invocation that only existed in your terminal.
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
## Coding styles
|
package/package.json
CHANGED
|
@@ -42,11 +42,12 @@ import { checkOtherUserKeys, seedUserKeys } from "./userKeys";
|
|
|
42
42
|
// 4. A source's history was rewritten.
|
|
43
43
|
// 5. A source started being signed by a different key, so its new keys are being held.
|
|
44
44
|
// 6. A source is now signed when it was not before, applied right away.
|
|
45
|
-
// 7. A source
|
|
46
|
-
// 8.
|
|
47
|
-
// 9.
|
|
48
|
-
// 10. A trusted machine talked to us from an address it is not allowed from, so it was frozen
|
|
45
|
+
// 7. A source has a corrupted signature, so its contents are ignored.
|
|
46
|
+
// 8. The webhook file itself changed, reported to the webhook being replaced.
|
|
47
|
+
// 9. A trusted machine talked to us from an address it is not allowed from, so it was frozen
|
|
49
48
|
// everywhere. Sent by whichever machine wrote that revocation, from machines.ts.
|
|
49
|
+
// A file that does not match the manifest is NOT on this list. It is one file we hold no
|
|
50
|
+
// signature for, it is logged where it is skipped, and the rest of the repo is unaffected.
|
|
50
51
|
|
|
51
52
|
type DaemonConfig = {
|
|
52
53
|
repoSources: string[];
|
|
@@ -62,9 +62,9 @@ function noteRevocation(revocationId, identity, ip) {
|
|
|
62
62
|
absorbedRevocations.set(revocationId, { identity, ip });
|
|
63
63
|
}
|
|
64
64
|
exports.noteRevocation = noteRevocation;
|
|
65
|
-
/** A repo
|
|
66
|
-
treats
|
|
67
|
-
kind is carried rather than acted on here. */
|
|
65
|
+
/** A repo whose signature does not check out, with the message ready for whoever asked. Not every
|
|
66
|
+
caller treats it the same - a source keeps its last keys, a machine list is just refused - so
|
|
67
|
+
the kind is carried rather than acted on here. */
|
|
68
68
|
class SignedRepoError extends Error {
|
|
69
69
|
constructor(problem, headline, body) {
|
|
70
70
|
super(`${headline}. ${body}`);
|
|
@@ -77,11 +77,14 @@ exports.SignedRepoError = SignedRepoError;
|
|
|
77
77
|
/** Everything a signed checkout vouches for, in one call: who signed it, and the contents of every
|
|
78
78
|
file the signature actually covers.
|
|
79
79
|
|
|
80
|
-
UNSIGNED with no files when there is no signature at all. Throws a SignedRepoError when
|
|
81
|
-
signature
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
80
|
+
UNSIGNED with no files when there is no signature at all. Throws a SignedRepoError only when the
|
|
81
|
+
signature over the manifest does not hold up, since then nothing in the repo can be believed and
|
|
82
|
+
the caller keeps whatever it last accepted.
|
|
83
|
+
|
|
84
|
+
Individual files are included or left out one at a time, and a file being left out never affects
|
|
85
|
+
the others: a file the manifest does not name, a file whose contents no longer match what was
|
|
86
|
+
signed, and a file the manifest names that is not on disk are all simply files we hold no
|
|
87
|
+
signature for. */
|
|
85
88
|
async function readSignedRepo(config) {
|
|
86
89
|
var _a;
|
|
87
90
|
let { repoPath, sourceURL } = config;
|
|
@@ -112,8 +115,6 @@ async function readSignedRepo(config) {
|
|
|
112
115
|
catch (e) {
|
|
113
116
|
throw broken(`${e}`);
|
|
114
117
|
}
|
|
115
|
-
let stale = (detail) => new SignedRepoError("stale", `KEY REPO CHANGED WITHOUT BEING SIGNED`, `${detail}, so the repo is being ignored and this machine keeps using what it last accepted.`
|
|
116
|
-
+ `\n\nTo make the change take effect, run in that repo:\n\`\`\`\n${SIGN_COMMAND}\n\`\`\``);
|
|
117
118
|
// Every file on disk, other than git's own directory and the two signature files, which cannot
|
|
118
119
|
// describe themselves.
|
|
119
120
|
let listCheckoutFiles = async (prefix) => {
|
|
@@ -134,27 +135,30 @@ async function readSignedRepo(config) {
|
|
|
134
135
|
};
|
|
135
136
|
let manifest = JSON.parse(manifestBytes.toString("utf8"));
|
|
136
137
|
let listed = new Map((manifest.files || []).map((file) => [file.path, file]));
|
|
138
|
+
// A file counts only if the manifest names it AND its contents still match. Anything else is
|
|
139
|
+
// left out, one file at a time: an unsigned file, a file edited after signing, and a file the
|
|
140
|
+
// manifest names that is not here are all just files we have no signature for. None of them
|
|
141
|
+
// says anything about the files that DO match, so none of them takes the rest of the repo down
|
|
142
|
+
// with it - the signature over the manifest is the only thing that can do that.
|
|
137
143
|
let files = new Map();
|
|
138
144
|
for (let filePath of await listCheckoutFiles()) {
|
|
139
145
|
let expected = listed.get(filePath);
|
|
140
|
-
// A file the signature never mentioned is not tampering, it is just unsigned - left out
|
|
141
|
-
// rather than trusted. An extra file in a working tree is ordinary, so it is only a note.
|
|
142
146
|
if (!expected) {
|
|
143
147
|
console.log(`Ignoring ${path_1.default.join(repoPath, filePath)}, it is not in the signed manifest`);
|
|
144
148
|
continue;
|
|
145
149
|
}
|
|
146
150
|
let contents = (0, manifest_1.normalizeContent)(await promises_1.default.readFile(path_1.default.join(repoPath, filePath)));
|
|
147
151
|
let hash = crypto_1.default.createHash("sha256").update(contents).digest("hex");
|
|
148
|
-
// A file the manifest DOES name, but whose content no longer matches, is a signed file
|
|
149
|
-
// changed without re-signing - the repo being edited out from under its signature.
|
|
150
152
|
if (contents.length !== expected.size || hash !== expected.sha256) {
|
|
151
|
-
|
|
153
|
+
console.log(`Ignoring ${path_1.default.join(repoPath, filePath)}, it was changed after it was signed.`
|
|
154
|
+
+ ` Run ${SIGN_COMMAND} in that repo to sign it as it now is.`);
|
|
155
|
+
continue;
|
|
152
156
|
}
|
|
153
157
|
files.set(filePath, contents);
|
|
154
158
|
}
|
|
155
159
|
for (let filePath of listed.keys()) {
|
|
156
160
|
if (!files.has(filePath)) {
|
|
157
|
-
|
|
161
|
+
console.log(`${path_1.default.join(repoPath, filePath)} is in the signed manifest, but there is nothing here that matches it`);
|
|
158
162
|
}
|
|
159
163
|
}
|
|
160
164
|
// Absorb the revoke repo's files into the sticky map. Once seen a revocation never leaves it,
|
|
@@ -233,5 +237,5 @@ async function readSignedRepo(config) {
|
|
|
233
237
|
return { signer, manifestHash, signatureHash, files };
|
|
234
238
|
}
|
|
235
239
|
exports.readSignedRepo = readSignedRepo;
|
|
236
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJ1c3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0cnVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsMkRBQTZCO0FBQzdCLGdEQUF3QjtBQUN4Qix5REFBNkc7QUFDN0cscURBQXdEO0FBQ3hELHNEQUFtRDtBQUNuRCxrREFBaUQ7QUFFakQsaUdBQWlHO0FBQ2pHLG1EQUFtRDtBQUN0QyxRQUFBLFFBQVEsR0FBRyxFQUFFLENBQUM7QUFDM0IsNkZBQTZGO0FBQzdGLGtDQUFrQztBQUNsQyxNQUFNLFlBQVksR0FBRyxvQkFBb0IsQ0FBQztBQUMxQyxNQUFNLGVBQWUsR0FBRyxhQUFhLENBQUM7QUFDdEMsTUFBTSxhQUFhLEdBQUcsV0FBVyxDQUFDO0FBRWxDLGtHQUFrRztBQUNsRyxtR0FBbUc7QUFDbkcsZ0dBQWdHO0FBQ2hHLDBGQUEwRjtBQUMxRixJQUFJLG1CQUFtQixHQUFHLElBQUksR0FBRyxFQUE0QyxDQUFDO0FBQzlFLGtHQUFrRztBQUNsRyw4RUFBOEU7QUFDOUUsSUFBSSxjQUFjLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztBQUN2QyxJQUFJLFlBQVksR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO0FBRXJDO2tHQUNrRztBQUNsRyxTQUFnQixnQkFBZ0IsQ0FBQyxRQUFnQjtJQUM3QyxLQUFLLElBQUksQ0FBQyxZQUFZLEVBQUUsVUFBVSxDQUFDLElBQUksbUJBQW1CLEVBQUUsQ0FBQztRQUN6RCxJQUFJLFVBQVUsQ0FBQyxRQUFRLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDbkMsU0FBUztRQUNiLENBQUM7UUFDRCxJQUFJLFlBQVksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLElBQUksY0FBYyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFFBQVEsSUFBSSxVQUFVLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ3ZGLFNBQVM7UUFDYixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2pCLENBQUM7QUFYRCw0Q0FXQztBQUVELFNBQWdCLGFBQWEsQ0FBQyxRQUFnQixFQUFFLEVBQVU7SUFDdEQsS0FBSyxJQUFJLENBQUMsWUFBWSxFQUFFLFVBQVUsQ0FBQyxJQUFJLG1CQUFtQixFQUFFLENBQUM7UUFDekQsSUFBSSxVQUFVLENBQUMsUUFBUSxLQUFLLFFBQVEsSUFBSSxVQUFVLENBQUMsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztZQUM5RixPQUFPLElBQUksQ0FBQztRQUNoQixDQUFDO0lBQ0wsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2pCLENBQUM7QUFQRCxzQ0FPQztBQUVELFNBQWdCLGVBQWUsQ0FBQyxRQUFnQixFQUFFLEVBQVU7SUFDeEQsT0FBTyxjQUFjLENBQUMsR0FBRyxDQUFDLEdBQUcsUUFBUSxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDbkQsQ0FBQztBQUZELDBDQUVDO0FBRUQ7b0NBQ29DO0FBQ3BDLFNBQWdCLGNBQWMsQ0FBQyxZQUFvQixFQUFFLFFBQWdCLEVBQUUsRUFBVTtJQUM3RSxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDNUQsQ0FBQztBQUZELHdDQUVDO0FBRUQ7O2lEQUVpRDtBQUNqRCxNQUFhLGVBQWdCLFNBQVEsS0FBSztJQUN0QyxZQUFtQixPQUFlLEVBQVMsUUFBZ0IsRUFBUyxJQUFZO1FBQzVFLEtBQUssQ0FBQyxHQUFHLFFBQVEsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRGYsWUFBTyxHQUFQLE9BQU8sQ0FBUTtRQUFTLGFBQVEsR0FBUixRQUFRLENBQVE7UUFBUyxTQUFJLEdBQUosSUFBSSxDQUFRO0lBRWhGLENBQUM7Q0FDSjtBQUpELDBDQUlDO0FBRUQ7Ozs7Ozs7d0VBT3dFO0FBQ2pFLEtBQUssVUFBVSxjQUFjLENBQUMsTUFBK0M7O0lBTWhGLElBQUksRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLEdBQUcsTUFBTSxDQUFDO0lBQ3JDLElBQUksYUFBYSxHQUFHLE1BQU0sa0JBQUUsQ0FBQyxRQUFRLENBQUMsY0FBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsd0JBQWEsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ2pHLElBQUksY0FBYyxHQUFHLE1BQU0sa0JBQUUsQ0FBQyxRQUFRLENBQUMsY0FBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUseUJBQWMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ25HLElBQUksWUFBWSxHQUFHLGFBQWEsSUFBSSxnQkFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUMxRyxJQUFJLGFBQWEsR0FBRyxjQUFjLElBQUksZ0JBQU0sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7SUFFN0csSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3BDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxRQUFRLDJDQUEyQyxDQUFDLENBQUM7UUFDcEUsT0FBTyxFQUFFLE1BQU0sRUFBRSxnQkFBUSxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLElBQUksR0FBRyxFQUFFLEVBQUUsQ0FBQztJQUMvRSxDQUFDO0lBRUQsSUFBSSxNQUFNLEdBQUcsQ0FBQyxNQUFjLEVBQUUsRUFBRSxDQUFDLElBQUksZUFBZSxDQUNoRCxTQUFTLEVBQ1QsOEJBQThCLEVBQzlCLG9CQUFvQixRQUFRLCtEQUErRDtVQUN6Rix1REFBdUQsTUFBTSxFQUFFO1VBQy9ELDREQUE0RCxZQUFZLFVBQVUsQ0FDdkYsQ0FBQztJQUNGLElBQUksQ0FBQyxhQUFhLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUNwQyxNQUFNLE1BQU0sQ0FBQyxlQUFlLHdCQUFhLFFBQVEseUJBQWMsY0FBYyxDQUFDLENBQUM7SUFDbkYsQ0FBQztJQUVELElBQUksTUFBYyxDQUFDO0lBQ25CLElBQUksQ0FBQztRQUNELHdGQUF3RjtRQUN4RiwrQ0FBK0M7UUFDL0MsTUFBTSxHQUFHLElBQUEscUJBQVksRUFBQztZQUNsQixTQUFTLEVBQUUsY0FBYyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7WUFDMUMsT0FBTyxFQUFFLElBQUEsMkJBQWdCLEVBQUMsYUFBYSxDQUFDO1lBQ3hDLFNBQVMsRUFBRSx5QkFBYztTQUM1QixDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ2pCLENBQUM7SUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ1QsTUFBTSxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3pCLENBQUM7SUFFRCxJQUFJLEtBQUssR0FBRyxDQUFDLE1BQWMsRUFBRSxFQUFFLENBQUMsSUFBSSxlQUFlLENBQy9DLE9BQU8sRUFDUCx1Q0FBdUMsRUFDdkMsR0FBRyxNQUFNLG9GQUFvRjtVQUMzRixrRUFBa0UsWUFBWSxVQUFVLENBQzdGLENBQUM7SUFFRiwrRkFBK0Y7SUFDL0YsdUJBQXVCO0lBQ3ZCLElBQUksaUJBQWlCLEdBQUcsS0FBSyxFQUFFLE1BQWUsRUFBcUIsRUFBRTtRQUNqRSxJQUFJLEtBQUssR0FBYSxFQUFFLENBQUM7UUFDekIsS0FBSyxJQUFJLEtBQUssSUFBSSxNQUFNLGtCQUFFLENBQUMsT0FBTyxDQUFDLGNBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE1BQU0sSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDN0YsSUFBSSxZQUFZLEdBQUcsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDO1lBQ3JFLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxNQUFNO2dCQUFFLFNBQVM7WUFDcEMsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssd0JBQWEsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLHlCQUFjLENBQUM7Z0JBQUUsU0FBUztZQUN6RixJQUFJLEtBQUssQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDO2dCQUN0QixLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO2dCQUNyRCxTQUFTO1lBQ2IsQ0FBQztZQUNELEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDN0IsQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3hCLENBQUMsQ0FBQztJQUVGLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQzFELElBQUksTUFBTSxHQUFHLElBQUksR0FBRyxDQUNoQixDQUFDLFFBQVEsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBb0QsRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQzFHLENBQUM7SUFFRixJQUFJLEtBQUssR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUN0QyxLQUFLLElBQUksUUFBUSxJQUFJLE1BQU0saUJBQWlCLEVBQUUsRUFBRSxDQUFDO1FBQzdDLElBQUksUUFBUSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDcEMsd0ZBQXdGO1FBQ3hGLDBGQUEwRjtRQUMxRixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDWixPQUFPLENBQUMsR0FBRyxDQUFDLFlBQVksY0FBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLG9DQUFvQyxDQUFDLENBQUM7WUFDM0YsU0FBUztRQUNiLENBQUM7UUFDRCxJQUFJLFFBQVEsR0FBRyxJQUFBLDJCQUFnQixFQUFDLE1BQU0sa0JBQUUsQ0FBQyxRQUFRLENBQUMsY0FBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xGLElBQUksSUFBSSxHQUFHLGdCQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdEUsdUZBQXVGO1FBQ3ZGLG1GQUFtRjtRQUNuRixJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssUUFBUSxDQUFDLElBQUksSUFBSSxJQUFJLEtBQUssUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2hFLE1BQU0sS0FBSyxDQUFDLEdBQUcsY0FBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLGtDQUFrQyxDQUFDLENBQUM7UUFDcEYsQ0FBQztRQUNELEtBQUssQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFDRCxLQUFLLElBQUksUUFBUSxJQUFJLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDdkIsTUFBTSxLQUFLLENBQUMsR0FBRyxjQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsNEJBQTRCLENBQUMsQ0FBQztRQUM5RSxDQUFDO0lBQ0wsQ0FBQztJQUVELDhGQUE4RjtJQUM5RiwrRkFBK0Y7SUFDL0YsaUVBQWlFO0lBQ2pFLElBQUksb0JBQW9CLEdBQUcsY0FBSSxDQUFDLElBQUksQ0FBQyxJQUFBLDZCQUFjLEVBQUMsU0FBUyxDQUFDLEVBQUUsZUFBZSxDQUFDLENBQUM7SUFDakYsS0FBSyxJQUFJLElBQUksSUFBSSxDQUFDLE1BQU0sa0JBQUUsQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBYyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDO1FBQzNGLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDMUIsU0FBUztRQUNiLENBQUM7UUFDRCxJQUFJLENBQUM7WUFDRCxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sa0JBQUUsQ0FBQyxRQUFRLENBQUMsY0FBSSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxJQUFJLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQzFGLElBQUksUUFBUSxHQUFHLE1BQU0sQ0FBQyxXQUFXLElBQUksTUFBTSxDQUFDLFNBQVMsQ0FBQztZQUN0RCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ1osU0FBUztZQUNiLENBQUM7WUFDRCxJQUFJLFlBQVksR0FBRyxNQUFNLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ3RFLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztnQkFDekMsbUJBQW1CLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsTUFBTSxDQUFDLEVBQUUsS0FBSSxNQUFBLE1BQU0sQ0FBQyxPQUFPLDBDQUFFLEVBQUUsQ0FBQSxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDbkcsQ0FBQztRQUNMLENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQ0FBa0MsY0FBSSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2pHLENBQUM7SUFDTCxDQUFDO0lBRUQsMEZBQTBGO0lBQzFGLGdFQUFnRTtJQUNoRSxjQUFjLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUMzQixZQUFZLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUN6QixLQUFLLElBQUksQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLElBQUksS0FBSyxFQUFFLENBQUM7UUFDckMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsR0FBRyxhQUFhLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQzNFLFNBQVM7UUFDYixDQUFDO1FBQ0QsSUFBSSxDQUFDO1lBQ0QsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDbkQsS0FBSyxJQUFJLE9BQU8sSUFBSSxNQUFNLENBQUMsT0FBTyxJQUFJLEVBQUUsRUFBRSxDQUFDO2dCQUN2QyxJQUFJLFFBQVEsR0FBRyxPQUFPLENBQUMsV0FBVyxJQUFJLE9BQU8sQ0FBQyxTQUFTLENBQUM7Z0JBQ3hELElBQUksUUFBUSxJQUFJLE9BQU8sQ0FBQyxFQUFFLEVBQUUsQ0FBQztvQkFDekIsY0FBYyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFFBQVEsSUFBSSxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDcEQsQ0FBQztZQUNMLENBQUM7WUFDRCxLQUFLLElBQUksWUFBWSxJQUFJLE1BQU0sQ0FBQyxhQUFhLElBQUksRUFBRSxFQUFFLENBQUM7Z0JBQ2xELFlBQVksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDbkMsQ0FBQztRQUNMLENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQ0FBZ0MsUUFBUSxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDbEUsQ0FBQztJQUNMLENBQUM7SUFFRCw0RkFBNEY7SUFDNUYseUZBQXlGO0lBQ3pGLHFFQUFxRTtJQUNyRSxLQUFLLElBQUksQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDMUMsSUFBSSxRQUFRLEtBQUssaUJBQWlCLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDM0YsSUFBSSxLQUFLLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDbEQsSUFBSSxJQUFJLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRTtnQkFDM0IsSUFBSSxXQUFXLEdBQUcsSUFBQSwrQkFBYyxFQUFDLElBQUksQ0FBQyxDQUFDO2dCQUN2QyxJQUFJLFdBQVcsSUFBSSxnQkFBZ0IsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO29CQUMvQyxPQUFPLENBQUMsR0FBRyxDQUFDLHdCQUF3QixXQUFXLFNBQVMsY0FBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO29CQUN6RixPQUFPLEtBQUssQ0FBQztnQkFDakIsQ0FBQztnQkFDRCxPQUFPLElBQUksQ0FBQztZQUNoQixDQUFDLENBQUMsQ0FBQztZQUNILElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQy9CLEtBQUssQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDdEQsQ0FBQztRQUNMLENBQUM7UUFDRCxJQUFJLFFBQVEsQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLElBQUksUUFBUSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ2pFLElBQUksU0FBUyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNwRSxJQUFJLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7Z0JBQzlCLE9BQU8sQ0FBQyxHQUFHLENBQUMsMkJBQTJCLFNBQVMsU0FBUyxjQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQzFGLEtBQUssQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDM0IsQ0FBQztRQUNMLENBQUM7SUFDTCxDQUFDO0lBRUQsT0FBTyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxDQUFDO0FBQzFELENBQUM7QUF6S0Qsd0NBeUtDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGNyeXB0byBmcm9tIFwiY3J5cHRvXCI7XG5pbXBvcnQgZnMgZnJvbSBcImZzL3Byb21pc2VzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgTUFOSUZFU1RfTkFNRSwgbm9ybWFsaXplQ29udGVudCwgU0lHTl9OQU1FU1BBQ0UsIFNJR05BVFVSRV9OQU1FIH0gZnJvbSBcIi4uLy4uL3NpZ25lZEZpbGVzL21hbmlmZXN0XCI7XG5pbXBvcnQgeyB2ZXJpZnlTU0hTSUcgfSBmcm9tIFwiLi4vLi4vc2lnbmVkRmlsZXMvc3Noc2lnXCI7XG5pbXBvcnQgeyBrZXlGaW5nZXJwcmludCB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5c1wiO1xuaW1wb3J0IHsgcmV2b2tlUmVwb1BhdGggfSBmcm9tIFwiLi4vcmV2b2tlU291cmNlXCI7XG5cbi8vIEEgc291cmNlIHRoYXQgaGFzIG5ldmVyIGJlZW4gc2lnbmVkIHJlYWRzIGFzIHRoaXMsIHNvIGxvc2luZyBhIHNpZ25hdHVyZSBjb3VudHMgYXMgYSBjaGFuZ2Ugb2Zcbi8vIHNpZ25lciByYXRoZXIgdGhhbiBhcyBzb21ldGhpbmcgdG8gd2F2ZSB0aHJvdWdoLlxuZXhwb3J0IGNvbnN0IFVOU0lHTkVEID0gXCJcIjtcbi8vIFdoYXQgZml4ZXMgYm90aCBvZiB0aGUgc2lnbmF0dXJlIHByb2JsZW1zIHdlIHJlcG9ydCwgc28gdGhlIG1lc3NhZ2UgY2FuIHNheSBzbyByYXRoZXIgdGhhblxuLy8gbGVhdmluZyBzb21lb25lIHRvIHdvcmsgaXQgb3V0LlxuY29uc3QgU0lHTl9DT01NQU5EID0gXCJ5YXJuIHNpZ25maWxlcyBnaXRcIjtcbmNvbnN0IFJFVk9DQVRJT05TX0RJUiA9IFwicmV2b2NhdGlvbnNcIjtcbmNvbnN0IFVOUkVWT0tFU19ESVIgPSBcInVucmV2b2tlZFwiO1xuXG4vLyBFdmVyeSByZXZvY2F0aW9uIHRoaXMgcHJvY2VzcyBoYXMgZXZlciBzZWVuLCBrZXllZCBieSByZXZvY2F0aW9uIGlkLiBPbmNlIGFic29yYmVkIGEgcmV2b2NhdGlvblxuLy8gbmV2ZXIgbGVhdmVzLCBldmVuIGlmIGl0cyBmaWxlIGRpc2FwcGVhcnMgZnJvbSB0aGUgcmV2b2tlIHJlcG8gLSB0aGUga2V5IHRoYXQgd3JpdGVzIHJldm9jYXRpb25zXG4vLyBpcyBvbiBldmVyeSBzZXJ2ZXIsIHNvIHdob2V2ZXIgc3RvbGUgb25lIGNvdWxkIG90aGVyd2lzZSBlcmFzZSB0aGUgcmVjb3JkIHRoYXQgc2h1dCB0aGVtIG91dC5cbi8vIFJlc3RhcnRpbmcgdGhlIHByb2Nlc3MgaXMgdGhlIHdheSBiYWNrIGZyb20gYSByZXZvY2F0aW9uIHRoYXQgc2hvdWxkIG5vdCBoYXZlIGhhcHBlbmVkLlxubGV0IGFic29yYmVkUmV2b2NhdGlvbnMgPSBuZXcgTWFwPHN0cmluZywgeyBpZGVudGl0eTogc3RyaW5nOyBpcDogc3RyaW5nIH0+KCk7XG4vLyBUaGUgcGFpcnMgdGhlIHNpZ25lZCB1bnJldm9rZXMgYWxsb3csIGFuZCB0aGUgbGVnYWN5IHJldm9jYXRpb24gaWRzIHRoZXkgbmFtZS4gUmVidWlsdCBvbiBldmVyeVxuLy8gcmVhZCwgc2luY2UgdW5yZXZva2VzIGFyZSBzaWduZWQgY29udGVudCBhbmQgcmVtb3Zpbmcgb25lIG11c3QgdGFrZSBlZmZlY3QuXG5sZXQgdW5yZXZva2VkUGFpcnMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbmxldCB1bnJldm9rZWRJZHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuLyoqIFdoZXRoZXIgYW4gaWRlbnRpdHkgLSBhIGtleSBmaW5nZXJwcmludCBvciBhIG1hY2hpbmUgaWQgLSBoYXMgYSByZXZvY2F0aW9uIG5vdGhpbmcgaGFzIHVuZG9uZS5cbiAgICBUaGUgb25lIG1lYW5pbmcgb2YgXCJmcm96ZW5cIiwgdXNlZCBib3RoIHdoZW4gc3RyaXBwaW5nIHJlcG8gY29udGVudCBhbmQgd2hlbiBleHBsYWluaW5nIHdoeS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0lkZW50aXR5RnJvemVuKGlkZW50aXR5OiBzdHJpbmcpIHtcbiAgICBmb3IgKGxldCBbcmV2b2NhdGlvbklkLCByZXZvY2F0aW9uXSBvZiBhYnNvcmJlZFJldm9jYXRpb25zKSB7XG4gICAgICAgIGlmIChyZXZvY2F0aW9uLmlkZW50aXR5ICE9PSBpZGVudGl0eSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHVucmV2b2tlZElkcy5oYXMocmV2b2NhdGlvbklkKSB8fCB1bnJldm9rZWRQYWlycy5oYXMoYCR7aWRlbnRpdHl9ICR7cmV2b2NhdGlvbi5pcH1gKSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzUGFpclJldm9rZWQoaWRlbnRpdHk6IHN0cmluZywgaXA6IHN0cmluZykge1xuICAgIGZvciAobGV0IFtyZXZvY2F0aW9uSWQsIHJldm9jYXRpb25dIG9mIGFic29yYmVkUmV2b2NhdGlvbnMpIHtcbiAgICAgICAgaWYgKHJldm9jYXRpb24uaWRlbnRpdHkgPT09IGlkZW50aXR5ICYmIHJldm9jYXRpb24uaXAgPT09IGlwICYmICF1bnJldm9rZWRJZHMuaGFzKHJldm9jYXRpb25JZCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzUGFpclVucmV2b2tlZChpZGVudGl0eTogc3RyaW5nLCBpcDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHVucmV2b2tlZFBhaXJzLmhhcyhgJHtpZGVudGl0eX0gJHtpcH1gKTtcbn1cblxuLyoqIEZvciB3aG9ldmVyIGp1c3Qgd3JvdGUgYSByZXZvY2F0aW9uLCBzbyBpdCBob2xkcyBoZXJlIGltbWVkaWF0ZWx5IHJhdGhlciB0aGFuIG9uIHRoZSBuZXh0XG4gICAgYWJzb3JiLiBTdGlja3kgbGlrZSB0aGUgcmVzdC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3RlUmV2b2NhdGlvbihyZXZvY2F0aW9uSWQ6IHN0cmluZywgaWRlbnRpdHk6IHN0cmluZywgaXA6IHN0cmluZykge1xuICAgIGFic29yYmVkUmV2b2NhdGlvbnMuc2V0KHJldm9jYXRpb25JZCwgeyBpZGVudGl0eSwgaXAgfSk7XG59XG5cbi8qKiBBIHJlcG8gdGhhdCBjYW5ub3QgYmUgdHJ1c3RlZCwgd2l0aCB0aGUgbWVzc2FnZSByZWFkeSBmb3Igd2hvZXZlciBhc2tlZC4gTm90IGV2ZXJ5IGNhbGxlclxuICAgIHRyZWF0cyB0aGVzZSB0aGUgc2FtZSAtIGEgc291cmNlIGtlZXBzIGl0cyBsYXN0IGtleXMsIGEgbWFjaGluZSBsaXN0IGlzIGp1c3QgcmVmdXNlZCAtIHNvIHRoZVxuICAgIGtpbmQgaXMgY2FycmllZCByYXRoZXIgdGhhbiBhY3RlZCBvbiBoZXJlLiAqL1xuZXhwb3J0IGNsYXNzIFNpZ25lZFJlcG9FcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgcHJvYmxlbTogc3RyaW5nLCBwdWJsaWMgaGVhZGxpbmU6IHN0cmluZywgcHVibGljIGJvZHk6IHN0cmluZykge1xuICAgICAgICBzdXBlcihgJHtoZWFkbGluZX0uICR7Ym9keX1gKTtcbiAgICB9XG59XG5cbi8qKiBFdmVyeXRoaW5nIGEgc2lnbmVkIGNoZWNrb3V0IHZvdWNoZXMgZm9yLCBpbiBvbmUgY2FsbDogd2hvIHNpZ25lZCBpdCwgYW5kIHRoZSBjb250ZW50cyBvZiBldmVyeVxuICAgIGZpbGUgdGhlIHNpZ25hdHVyZSBhY3R1YWxseSBjb3ZlcnMuXG5cbiAgICBVTlNJR05FRCB3aXRoIG5vIGZpbGVzIHdoZW4gdGhlcmUgaXMgbm8gc2lnbmF0dXJlIGF0IGFsbC4gVGhyb3dzIGEgU2lnbmVkUmVwb0Vycm9yIHdoZW4gYVxuICAgIHNpZ25hdHVyZSBpcyBwcmVzZW50IGJ1dCBkb2VzIG5vdCBob2xkIHVwLCBvciB3aGVuIGEgZmlsZSBpdCBzaWduZWQgZm9yIHdhcyBjaGFuZ2VkIG9yIHJlbW92ZWRcbiAgICB3aXRob3V0IHJlLXNpZ25pbmcgLSBlaXRoZXIgd2F5IHRoZSBjYWxsZXIga2VlcHMgd2hhdGV2ZXIgaXQgbGFzdCBhY2NlcHRlZCByYXRoZXIgdGhhbiBiZWxpZXZpbmdcbiAgICBhIHJlcG8gdGhhdCBubyBsb25nZXIgbWF0Y2hlcyB3aGF0IHdhcyBzaWduZWQuIEEgZmlsZSBub3QgaW4gdGhlIG1hbmlmZXN0IGlzIGp1c3QgdW5zaWduZWQsIHNvXG4gICAgaXQgaXMgbGVmdCBvdXQgYW5kIHdhcm5lZCBhYm91dCByYXRoZXIgdGhhbiB0cmVhdGVkIGFzIHRhbXBlcmluZy4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWFkU2lnbmVkUmVwbyhjb25maWc6IHsgcmVwb1BhdGg6IHN0cmluZzsgc291cmNlVVJMOiBzdHJpbmcgfSk6IFByb21pc2U8e1xuICAgIHNpZ25lcjogc3RyaW5nO1xuICAgIG1hbmlmZXN0SGFzaDogc3RyaW5nO1xuICAgIHNpZ25hdHVyZUhhc2g6IHN0cmluZztcbiAgICBmaWxlczogTWFwPHN0cmluZywgQnVmZmVyPjtcbn0+IHtcbiAgICBsZXQgeyByZXBvUGF0aCwgc291cmNlVVJMIH0gPSBjb25maWc7XG4gICAgbGV0IG1hbmlmZXN0Qnl0ZXMgPSBhd2FpdCBmcy5yZWFkRmlsZShwYXRoLmpvaW4ocmVwb1BhdGgsIE1BTklGRVNUX05BTUUpKS5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xuICAgIGxldCBzaWduYXR1cmVCeXRlcyA9IGF3YWl0IGZzLnJlYWRGaWxlKHBhdGguam9pbihyZXBvUGF0aCwgU0lHTkFUVVJFX05BTUUpKS5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xuICAgIGxldCBtYW5pZmVzdEhhc2ggPSBtYW5pZmVzdEJ5dGVzICYmIGNyeXB0by5jcmVhdGVIYXNoKFwic2hhMjU2XCIpLnVwZGF0ZShtYW5pZmVzdEJ5dGVzKS5kaWdlc3QoXCJoZXhcIikgfHwgXCJcIjtcbiAgICBsZXQgc2lnbmF0dXJlSGFzaCA9IHNpZ25hdHVyZUJ5dGVzICYmIGNyeXB0by5jcmVhdGVIYXNoKFwic2hhMjU2XCIpLnVwZGF0ZShzaWduYXR1cmVCeXRlcykuZGlnZXN0KFwiaGV4XCIpIHx8IFwiXCI7XG5cbiAgICBpZiAoIW1hbmlmZXN0Qnl0ZXMgJiYgIXNpZ25hdHVyZUJ5dGVzKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGAke3JlcG9QYXRofSBpcyBub3Qgc2lnbmVkLCBpZ25vcmluZyBhbGwgb2YgaXRzIGZpbGVzYCk7XG4gICAgICAgIHJldHVybiB7IHNpZ25lcjogVU5TSUdORUQsIG1hbmlmZXN0SGFzaCwgc2lnbmF0dXJlSGFzaCwgZmlsZXM6IG5ldyBNYXAoKSB9O1xuICAgIH1cblxuICAgIGxldCBicm9rZW4gPSAoZGV0YWlsOiBzdHJpbmcpID0+IG5ldyBTaWduZWRSZXBvRXJyb3IoXG4gICAgICAgIFwiY29ycnVwdFwiLFxuICAgICAgICBgS0VZIFJFUE8gU0lHTkFUVVJFIElTIEJST0tFTmAsXG4gICAgICAgIGBUaGUgc2lnbmF0dXJlIG9uICR7cmVwb1BhdGh9IGRvZXMgbm90IGNoZWNrIG91dCwgc28gZXZlcnl0aGluZyBpbiBpdCBpcyBiZWluZyBpZ25vcmVkIGFuZGBcbiAgICAgICAgKyBgIHRoaXMgbWFjaGluZSBrZWVwcyB1c2luZyB3aGF0IGl0IGxhc3QgYWNjZXB0ZWQuXFxuXFxuJHtkZXRhaWx9YFxuICAgICAgICArIGBcXG5cXG5UbyByZXBsYWNlIHRoZSBzaWduYXR1cmUsIHJ1biBpbiB0aGF0IHJlcG86XFxuXFxgXFxgXFxgXFxuJHtTSUdOX0NPTU1BTkR9XFxuXFxgXFxgXFxgYFxuICAgICk7XG4gICAgaWYgKCFtYW5pZmVzdEJ5dGVzIHx8ICFzaWduYXR1cmVCeXRlcykge1xuICAgICAgICB0aHJvdyBicm9rZW4oYE9ubHkgb25lIG9mICR7TUFOSUZFU1RfTkFNRX0gYW5kICR7U0lHTkFUVVJFX05BTUV9IGlzIHByZXNlbnQuYCk7XG4gICAgfVxuXG4gICAgbGV0IHNpZ25lcjogc3RyaW5nO1xuICAgIHRyeSB7XG4gICAgICAgIC8vIFRoZSBzaWduYXR1cmUgY292ZXJzIHRoZSBub3JtYWxpc2VkIGJ5dGVzLCBzbyBhIGNoZWNrb3V0IHRoYXQgYXJyaXZlZCB3aXRoIENSTEYgc3RpbGxcbiAgICAgICAgLy8gdmVyaWZpZXMgcmF0aGVyIHRoYW4gbG9va2luZyBsaWtlIHRhbXBlcmluZy5cbiAgICAgICAgc2lnbmVyID0gdmVyaWZ5U1NIU0lHKHtcbiAgICAgICAgICAgIHNpZ25hdHVyZTogc2lnbmF0dXJlQnl0ZXMudG9TdHJpbmcoXCJ1dGY4XCIpLFxuICAgICAgICAgICAgbWVzc2FnZTogbm9ybWFsaXplQ29udGVudChtYW5pZmVzdEJ5dGVzKSxcbiAgICAgICAgICAgIG5hbWVzcGFjZTogU0lHTl9OQU1FU1BBQ0UsXG4gICAgICAgIH0pLnB1YmxpY0tleTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocm93IGJyb2tlbihgJHtlfWApO1xuICAgIH1cblxuICAgIGxldCBzdGFsZSA9IChkZXRhaWw6IHN0cmluZykgPT4gbmV3IFNpZ25lZFJlcG9FcnJvcihcbiAgICAgICAgXCJzdGFsZVwiLFxuICAgICAgICBgS0VZIFJFUE8gQ0hBTkdFRCBXSVRIT1VUIEJFSU5HIFNJR05FRGAsXG4gICAgICAgIGAke2RldGFpbH0sIHNvIHRoZSByZXBvIGlzIGJlaW5nIGlnbm9yZWQgYW5kIHRoaXMgbWFjaGluZSBrZWVwcyB1c2luZyB3aGF0IGl0IGxhc3QgYWNjZXB0ZWQuYFxuICAgICAgICArIGBcXG5cXG5UbyBtYWtlIHRoZSBjaGFuZ2UgdGFrZSBlZmZlY3QsIHJ1biBpbiB0aGF0IHJlcG86XFxuXFxgXFxgXFxgXFxuJHtTSUdOX0NPTU1BTkR9XFxuXFxgXFxgXFxgYFxuICAgICk7XG5cbiAgICAvLyBFdmVyeSBmaWxlIG9uIGRpc2ssIG90aGVyIHRoYW4gZ2l0J3Mgb3duIGRpcmVjdG9yeSBhbmQgdGhlIHR3byBzaWduYXR1cmUgZmlsZXMsIHdoaWNoIGNhbm5vdFxuICAgIC8vIGRlc2NyaWJlIHRoZW1zZWx2ZXMuXG4gICAgbGV0IGxpc3RDaGVja291dEZpbGVzID0gYXN5bmMgKHByZWZpeD86IHN0cmluZyk6IFByb21pc2U8c3RyaW5nW10+ID0+IHtcbiAgICAgICAgbGV0IGZvdW5kOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICBmb3IgKGxldCBlbnRyeSBvZiBhd2FpdCBmcy5yZWFkZGlyKHBhdGguam9pbihyZXBvUGF0aCwgcHJlZml4IHx8IFwiXCIpLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSkpIHtcbiAgICAgICAgICAgIGxldCByZWxhdGl2ZVBhdGggPSBwcmVmaXggJiYgYCR7cHJlZml4fS8ke2VudHJ5Lm5hbWV9YCB8fCBlbnRyeS5uYW1lO1xuICAgICAgICAgICAgaWYgKGVudHJ5Lm5hbWUgPT09IFwiLmdpdFwiKSBjb250aW51ZTtcbiAgICAgICAgICAgIGlmICghcHJlZml4ICYmIChlbnRyeS5uYW1lID09PSBNQU5JRkVTVF9OQU1FIHx8IGVudHJ5Lm5hbWUgPT09IFNJR05BVFVSRV9OQU1FKSkgY29udGludWU7XG4gICAgICAgICAgICBpZiAoZW50cnkuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICAgICAgICAgIGZvdW5kLnB1c2goLi4uYXdhaXQgbGlzdENoZWNrb3V0RmlsZXMocmVsYXRpdmVQYXRoKSk7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3VuZC5wdXNoKHJlbGF0aXZlUGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZvdW5kLnNvcnQoKTtcbiAgICB9O1xuXG4gICAgbGV0IG1hbmlmZXN0ID0gSlNPTi5wYXJzZShtYW5pZmVzdEJ5dGVzLnRvU3RyaW5nKFwidXRmOFwiKSk7XG4gICAgbGV0IGxpc3RlZCA9IG5ldyBNYXA8c3RyaW5nLCB7IHNpemU6IG51bWJlcjsgc2hhMjU2OiBzdHJpbmcgfT4oXG4gICAgICAgIChtYW5pZmVzdC5maWxlcyB8fCBbXSkubWFwKChmaWxlOiB7IHBhdGg6IHN0cmluZzsgc2l6ZTogbnVtYmVyOyBzaGEyNTY6IHN0cmluZyB9KSA9PiBbZmlsZS5wYXRoLCBmaWxlXSlcbiAgICApO1xuXG4gICAgbGV0IGZpbGVzID0gbmV3IE1hcDxzdHJpbmcsIEJ1ZmZlcj4oKTtcbiAgICBmb3IgKGxldCBmaWxlUGF0aCBvZiBhd2FpdCBsaXN0Q2hlY2tvdXRGaWxlcygpKSB7XG4gICAgICAgIGxldCBleHBlY3RlZCA9IGxpc3RlZC5nZXQoZmlsZVBhdGgpO1xuICAgICAgICAvLyBBIGZpbGUgdGhlIHNpZ25hdHVyZSBuZXZlciBtZW50aW9uZWQgaXMgbm90IHRhbXBlcmluZywgaXQgaXMganVzdCB1bnNpZ25lZCAtIGxlZnQgb3V0XG4gICAgICAgIC8vIHJhdGhlciB0aGFuIHRydXN0ZWQuIEFuIGV4dHJhIGZpbGUgaW4gYSB3b3JraW5nIHRyZWUgaXMgb3JkaW5hcnksIHNvIGl0IGlzIG9ubHkgYSBub3RlLlxuICAgICAgICBpZiAoIWV4cGVjdGVkKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgSWdub3JpbmcgJHtwYXRoLmpvaW4ocmVwb1BhdGgsIGZpbGVQYXRoKX0sIGl0IGlzIG5vdCBpbiB0aGUgc2lnbmVkIG1hbmlmZXN0YCk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgY29udGVudHMgPSBub3JtYWxpemVDb250ZW50KGF3YWl0IGZzLnJlYWRGaWxlKHBhdGguam9pbihyZXBvUGF0aCwgZmlsZVBhdGgpKSk7XG4gICAgICAgIGxldCBoYXNoID0gY3J5cHRvLmNyZWF0ZUhhc2goXCJzaGEyNTZcIikudXBkYXRlKGNvbnRlbnRzKS5kaWdlc3QoXCJoZXhcIik7XG4gICAgICAgIC8vIEEgZmlsZSB0aGUgbWFuaWZlc3QgRE9FUyBuYW1lLCBidXQgd2hvc2UgY29udGVudCBubyBsb25nZXIgbWF0Y2hlcywgaXMgYSBzaWduZWQgZmlsZVxuICAgICAgICAvLyBjaGFuZ2VkIHdpdGhvdXQgcmUtc2lnbmluZyAtIHRoZSByZXBvIGJlaW5nIGVkaXRlZCBvdXQgZnJvbSB1bmRlciBpdHMgc2lnbmF0dXJlLlxuICAgICAgICBpZiAoY29udGVudHMubGVuZ3RoICE9PSBleHBlY3RlZC5zaXplIHx8IGhhc2ggIT09IGV4cGVjdGVkLnNoYTI1Nikge1xuICAgICAgICAgICAgdGhyb3cgc3RhbGUoYCR7cGF0aC5qb2luKHJlcG9QYXRoLCBmaWxlUGF0aCl9IHdhcyBjaGFuZ2VkIGFmdGVyIGl0IHdhcyBzaWduZWRgKTtcbiAgICAgICAgfVxuICAgICAgICBmaWxlcy5zZXQoZmlsZVBhdGgsIGNvbnRlbnRzKTtcbiAgICB9XG4gICAgZm9yIChsZXQgZmlsZVBhdGggb2YgbGlzdGVkLmtleXMoKSkge1xuICAgICAgICBpZiAoIWZpbGVzLmhhcyhmaWxlUGF0aCkpIHtcbiAgICAgICAgICAgIHRocm93IHN0YWxlKGAke3BhdGguam9pbihyZXBvUGF0aCwgZmlsZVBhdGgpfSBpcyBzaWduZWQgZm9yIGJ1dCBtaXNzaW5nYCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBBYnNvcmIgdGhlIHJldm9rZSByZXBvJ3MgZmlsZXMgaW50byB0aGUgc3RpY2t5IG1hcC4gT25jZSBzZWVuIGEgcmV2b2NhdGlvbiBuZXZlciBsZWF2ZXMgaXQsXG4gICAgLy8gZXZlbiBpZiBpdHMgZmlsZSBkaXNhcHBlYXJzIC0gdGhlIGtleSB0aGF0IHdyaXRlcyByZXZvY2F0aW9ucyBpcyBvbiBldmVyeSBzZXJ2ZXIsIHNvIHdob2V2ZXJcbiAgICAvLyBzdG9sZSBvbmUgY291bGQgb3RoZXJ3aXNlIGVyYXNlIHRoZSByZWNvcmQgdGhhdCBzaHV0IHRoZW0gb3V0LlxuICAgIGxldCByZXZvY2F0aW9uc0RpcmVjdG9yeSA9IHBhdGguam9pbihyZXZva2VSZXBvUGF0aChzb3VyY2VVUkwpLCBSRVZPQ0FUSU9OU19ESVIpO1xuICAgIGZvciAobGV0IG5hbWUgb2YgKGF3YWl0IGZzLnJlYWRkaXIocmV2b2NhdGlvbnNEaXJlY3RvcnkpLmNhdGNoKCgpID0+IFtdIGFzIHN0cmluZ1tdKSkuc29ydCgpKSB7XG4gICAgICAgIGlmICghbmFtZS5lbmRzV2l0aChcIi5qc29uXCIpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IHBhcnNlZCA9IEpTT04ucGFyc2UoYXdhaXQgZnMucmVhZEZpbGUocGF0aC5qb2luKHJldm9jYXRpb25zRGlyZWN0b3J5LCBuYW1lKSwgXCJ1dGY4XCIpKTtcbiAgICAgICAgICAgIGxldCBpZGVudGl0eSA9IHBhcnNlZC5maW5nZXJwcmludCB8fCBwYXJzZWQubWFjaGluZUlkO1xuICAgICAgICAgICAgaWYgKCFpZGVudGl0eSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IHJldm9jYXRpb25JZCA9IHBhcnNlZC5yZXZvY2F0aW9uSWQgfHwgbmFtZS5yZXBsYWNlKC9cXC5qc29uJC8sIFwiXCIpO1xuICAgICAgICAgICAgaWYgKCFhYnNvcmJlZFJldm9jYXRpb25zLmhhcyhyZXZvY2F0aW9uSWQpKSB7XG4gICAgICAgICAgICAgICAgYWJzb3JiZWRSZXZvY2F0aW9ucy5zZXQocmV2b2NhdGlvbklkLCB7IGlkZW50aXR5LCBpcDogcGFyc2VkLmlwIHx8IHBhcnNlZC5hdHRlbXB0Py5pcCB8fCBcIlwiIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgSWdub3JpbmcgdW5yZWFkYWJsZSByZXZvY2F0aW9uICR7cGF0aC5qb2luKHJldm9jYXRpb25zRGlyZWN0b3J5LCBuYW1lKX0uICR7ZX1gKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJlYnVpbGQgdGhlIHVucmV2b2tlcyBmcm9tIHRoZSBzaWduZWQgZmlsZXMganVzdCByZWFkLiBVbnJldm9rZXMgYXJlIHNpZ25lZCBjb250ZW50LCBzb1xuICAgIC8vIHJlbW92aW5nIG9uZSBtdXN0IHRha2UgZWZmZWN0LCB1bmxpa2UgdGhlIHN0aWNreSByZXZvY2F0aW9ucy5cbiAgICB1bnJldm9rZWRQYWlycyA9IG5ldyBTZXQoKTtcbiAgICB1bnJldm9rZWRJZHMgPSBuZXcgU2V0KCk7XG4gICAgZm9yIChsZXQgW2ZpbGVQYXRoLCBjb250ZW50c10gb2YgZmlsZXMpIHtcbiAgICAgICAgaWYgKCFmaWxlUGF0aC5zdGFydHNXaXRoKGAke1VOUkVWT0tFU19ESVJ9L2ApIHx8ICFmaWxlUGF0aC5lbmRzV2l0aChcIi5qc29uXCIpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IHBhcnNlZCA9IEpTT04ucGFyc2UoY29udGVudHMudG9TdHJpbmcoXCJ1dGY4XCIpKTtcbiAgICAgICAgICAgIGZvciAobGV0IGFsbG93ZWQgb2YgcGFyc2VkLmFsbG93ZWQgfHwgW10pIHtcbiAgICAgICAgICAgICAgICBsZXQgaWRlbnRpdHkgPSBhbGxvd2VkLmZpbmdlcnByaW50IHx8IGFsbG93ZWQubWFjaGluZUlkO1xuICAgICAgICAgICAgICAgIGlmIChpZGVudGl0eSAmJiBhbGxvd2VkLmlwKSB7XG4gICAgICAgICAgICAgICAgICAgIHVucmV2b2tlZFBhaXJzLmFkZChgJHtpZGVudGl0eX0gJHthbGxvd2VkLmlwfWApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IHJldm9jYXRpb25JZCBvZiBwYXJzZWQucmV2b2NhdGlvbklkcyB8fCBbXSkge1xuICAgICAgICAgICAgICAgIHVucmV2b2tlZElkcy5hZGQocmV2b2NhdGlvbklkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYElnbm9yaW5nIHVucmVhZGFibGUgdW5yZXZva2UgJHtmaWxlUGF0aH0uICR7ZX1gKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIERyb3AgZXZlcnl0aGluZyBmcm96ZW46IHJldm9rZWQga2V5cyBvdXQgb2YgYXV0aG9yaXplZF9rZXlzIGFuZCB0b3AgbGV2ZWwgLnB1YiBmaWxlcywgYW5kXG4gICAgLy8gZnJvemVuIG1hY2hpbmVzJyBmaWxlcyBvdXQgb2YgbWFjaGluZXMvLiBXaGF0IGNvbWVzIGJhY2sgaXMgd2hhdCB0aGlzIG1hY2hpbmUgYWN0dWFsbHlcbiAgICAvLyB0cnVzdHMsIHNvIG5vIGNhbGxlciBjYW4gcmVhZCB0aGUgbGlzdCBhbmQgZm9yZ2V0IHRoZSByZXZvY2F0aW9ucy5cbiAgICBmb3IgKGxldCBbZmlsZVBhdGgsIGNvbnRlbnRzXSBvZiBbLi4uZmlsZXNdKSB7XG4gICAgICAgIGlmIChmaWxlUGF0aCA9PT0gXCJhdXRob3JpemVkX2tleXNcIiB8fCAoZmlsZVBhdGguZW5kc1dpdGgoXCIucHViXCIpICYmICFmaWxlUGF0aC5pbmNsdWRlcyhcIi9cIikpKSB7XG4gICAgICAgICAgICBsZXQgbGluZXMgPSBjb250ZW50cy50b1N0cmluZyhcInV0ZjhcIikuc3BsaXQoXCJcXG5cIik7XG4gICAgICAgICAgICBsZXQga2VwdCA9IGxpbmVzLmZpbHRlcihsaW5lID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgZmluZ2VycHJpbnQgPSBrZXlGaW5nZXJwcmludChsaW5lKTtcbiAgICAgICAgICAgICAgICBpZiAoZmluZ2VycHJpbnQgJiYgaXNJZGVudGl0eUZyb3plbihmaW5nZXJwcmludCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYERyb3BwaW5nIHJldm9rZWQga2V5ICR7ZmluZ2VycHJpbnR9IGZyb20gJHtwYXRoLmpvaW4ocmVwb1BhdGgsIGZpbGVQYXRoKX1gKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKGtlcHQubGVuZ3RoICE9PSBsaW5lcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBmaWxlcy5zZXQoZmlsZVBhdGgsIEJ1ZmZlci5mcm9tKGtlcHQuam9pbihcIlxcblwiKSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChmaWxlUGF0aC5zdGFydHNXaXRoKFwibWFjaGluZXMvXCIpICYmIGZpbGVQYXRoLmVuZHNXaXRoKFwiLmpzb25cIikpIHtcbiAgICAgICAgICAgIGxldCBtYWNoaW5lSWQgPSBmaWxlUGF0aC5zbGljZShcIm1hY2hpbmVzL1wiLmxlbmd0aCwgLVwiLmpzb25cIi5sZW5ndGgpO1xuICAgICAgICAgICAgaWYgKGlzSWRlbnRpdHlGcm96ZW4obWFjaGluZUlkKSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBEcm9wcGluZyBmcm96ZW4gbWFjaGluZSAke21hY2hpbmVJZH0gZnJvbSAke3BhdGguam9pbihyZXBvUGF0aCwgZmlsZVBhdGgpfWApO1xuICAgICAgICAgICAgICAgIGZpbGVzLmRlbGV0ZShmaWxlUGF0aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4geyBzaWduZXIsIG1hbmlmZXN0SGFzaCwgc2lnbmF0dXJlSGFzaCwgZmlsZXMgfTtcbn1cbiJdfQ==
|
|
237
|
-
/* _JS_SOURCE_HASH = "
|
|
240
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJ1c3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0cnVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsMkRBQTZCO0FBQzdCLGdEQUF3QjtBQUN4Qix5REFBNkc7QUFDN0cscURBQXdEO0FBQ3hELHNEQUFtRDtBQUNuRCxrREFBaUQ7QUFFakQsaUdBQWlHO0FBQ2pHLG1EQUFtRDtBQUN0QyxRQUFBLFFBQVEsR0FBRyxFQUFFLENBQUM7QUFDM0IsNkZBQTZGO0FBQzdGLGtDQUFrQztBQUNsQyxNQUFNLFlBQVksR0FBRyxvQkFBb0IsQ0FBQztBQUMxQyxNQUFNLGVBQWUsR0FBRyxhQUFhLENBQUM7QUFDdEMsTUFBTSxhQUFhLEdBQUcsV0FBVyxDQUFDO0FBRWxDLGtHQUFrRztBQUNsRyxtR0FBbUc7QUFDbkcsZ0dBQWdHO0FBQ2hHLDBGQUEwRjtBQUMxRixJQUFJLG1CQUFtQixHQUFHLElBQUksR0FBRyxFQUE0QyxDQUFDO0FBQzlFLGtHQUFrRztBQUNsRyw4RUFBOEU7QUFDOUUsSUFBSSxjQUFjLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztBQUN2QyxJQUFJLFlBQVksR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO0FBRXJDO2tHQUNrRztBQUNsRyxTQUFnQixnQkFBZ0IsQ0FBQyxRQUFnQjtJQUM3QyxLQUFLLElBQUksQ0FBQyxZQUFZLEVBQUUsVUFBVSxDQUFDLElBQUksbUJBQW1CLEVBQUUsQ0FBQztRQUN6RCxJQUFJLFVBQVUsQ0FBQyxRQUFRLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDbkMsU0FBUztRQUNiLENBQUM7UUFDRCxJQUFJLFlBQVksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLElBQUksY0FBYyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFFBQVEsSUFBSSxVQUFVLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ3ZGLFNBQVM7UUFDYixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2pCLENBQUM7QUFYRCw0Q0FXQztBQUVELFNBQWdCLGFBQWEsQ0FBQyxRQUFnQixFQUFFLEVBQVU7SUFDdEQsS0FBSyxJQUFJLENBQUMsWUFBWSxFQUFFLFVBQVUsQ0FBQyxJQUFJLG1CQUFtQixFQUFFLENBQUM7UUFDekQsSUFBSSxVQUFVLENBQUMsUUFBUSxLQUFLLFFBQVEsSUFBSSxVQUFVLENBQUMsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztZQUM5RixPQUFPLElBQUksQ0FBQztRQUNoQixDQUFDO0lBQ0wsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2pCLENBQUM7QUFQRCxzQ0FPQztBQUVELFNBQWdCLGVBQWUsQ0FBQyxRQUFnQixFQUFFLEVBQVU7SUFDeEQsT0FBTyxjQUFjLENBQUMsR0FBRyxDQUFDLEdBQUcsUUFBUSxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDbkQsQ0FBQztBQUZELDBDQUVDO0FBRUQ7b0NBQ29DO0FBQ3BDLFNBQWdCLGNBQWMsQ0FBQyxZQUFvQixFQUFFLFFBQWdCLEVBQUUsRUFBVTtJQUM3RSxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDNUQsQ0FBQztBQUZELHdDQUVDO0FBRUQ7O3FEQUVxRDtBQUNyRCxNQUFhLGVBQWdCLFNBQVEsS0FBSztJQUN0QyxZQUFtQixPQUFlLEVBQVMsUUFBZ0IsRUFBUyxJQUFZO1FBQzVFLEtBQUssQ0FBQyxHQUFHLFFBQVEsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRGYsWUFBTyxHQUFQLE9BQU8sQ0FBUTtRQUFTLGFBQVEsR0FBUixRQUFRLENBQVE7UUFBUyxTQUFJLEdBQUosSUFBSSxDQUFRO0lBRWhGLENBQUM7Q0FDSjtBQUpELDBDQUlDO0FBRUQ7Ozs7Ozs7Ozs7cUJBVXFCO0FBQ2QsS0FBSyxVQUFVLGNBQWMsQ0FBQyxNQUErQzs7SUFNaEYsSUFBSSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsR0FBRyxNQUFNLENBQUM7SUFDckMsSUFBSSxhQUFhLEdBQUcsTUFBTSxrQkFBRSxDQUFDLFFBQVEsQ0FBQyxjQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSx3QkFBYSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDakcsSUFBSSxjQUFjLEdBQUcsTUFBTSxrQkFBRSxDQUFDLFFBQVEsQ0FBQyxjQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSx5QkFBYyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDbkcsSUFBSSxZQUFZLEdBQUcsYUFBYSxJQUFJLGdCQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzFHLElBQUksYUFBYSxHQUFHLGNBQWMsSUFBSSxnQkFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUU3RyxJQUFJLENBQUMsYUFBYSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDcEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFFBQVEsMkNBQTJDLENBQUMsQ0FBQztRQUNwRSxPQUFPLEVBQUUsTUFBTSxFQUFFLGdCQUFRLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUUsSUFBSSxHQUFHLEVBQUUsRUFBRSxDQUFDO0lBQy9FLENBQUM7SUFFRCxJQUFJLE1BQU0sR0FBRyxDQUFDLE1BQWMsRUFBRSxFQUFFLENBQUMsSUFBSSxlQUFlLENBQ2hELFNBQVMsRUFDVCw4QkFBOEIsRUFDOUIsb0JBQW9CLFFBQVEsK0RBQStEO1VBQ3pGLHVEQUF1RCxNQUFNLEVBQUU7VUFDL0QsNERBQTRELFlBQVksVUFBVSxDQUN2RixDQUFDO0lBQ0YsSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3BDLE1BQU0sTUFBTSxDQUFDLGVBQWUsd0JBQWEsUUFBUSx5QkFBYyxjQUFjLENBQUMsQ0FBQztJQUNuRixDQUFDO0lBRUQsSUFBSSxNQUFjLENBQUM7SUFDbkIsSUFBSSxDQUFDO1FBQ0Qsd0ZBQXdGO1FBQ3hGLCtDQUErQztRQUMvQyxNQUFNLEdBQUcsSUFBQSxxQkFBWSxFQUFDO1lBQ2xCLFNBQVMsRUFBRSxjQUFjLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQztZQUMxQyxPQUFPLEVBQUUsSUFBQSwyQkFBZ0IsRUFBQyxhQUFhLENBQUM7WUFDeEMsU0FBUyxFQUFFLHlCQUFjO1NBQzVCLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDakIsQ0FBQztJQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDVCxNQUFNLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDekIsQ0FBQztJQUVELCtGQUErRjtJQUMvRix1QkFBdUI7SUFDdkIsSUFBSSxpQkFBaUIsR0FBRyxLQUFLLEVBQUUsTUFBZSxFQUFxQixFQUFFO1FBQ2pFLElBQUksS0FBSyxHQUFhLEVBQUUsQ0FBQztRQUN6QixLQUFLLElBQUksS0FBSyxJQUFJLE1BQU0sa0JBQUUsQ0FBQyxPQUFPLENBQUMsY0FBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsTUFBTSxJQUFJLEVBQUUsQ0FBQyxFQUFFLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUM3RixJQUFJLFlBQVksR0FBRyxNQUFNLElBQUksR0FBRyxNQUFNLElBQUksS0FBSyxDQUFDLElBQUksRUFBRSxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUM7WUFDckUsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLE1BQU07Z0JBQUUsU0FBUztZQUNwQyxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyx3QkFBYSxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUsseUJBQWMsQ0FBQztnQkFBRSxTQUFTO1lBQ3pGLElBQUksS0FBSyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7Z0JBQ3RCLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLGlCQUFpQixDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7Z0JBQ3JELFNBQVM7WUFDYixDQUFDO1lBQ0QsS0FBSyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM3QixDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDeEIsQ0FBQyxDQUFDO0lBRUYsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDMUQsSUFBSSxNQUFNLEdBQUcsSUFBSSxHQUFHLENBQ2hCLENBQUMsUUFBUSxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFvRCxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FDMUcsQ0FBQztJQUVGLDZGQUE2RjtJQUM3Riw4RkFBOEY7SUFDOUYsNEZBQTRGO0lBQzVGLCtGQUErRjtJQUMvRixnRkFBZ0Y7SUFDaEYsSUFBSSxLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7SUFDdEMsS0FBSyxJQUFJLFFBQVEsSUFBSSxNQUFNLGlCQUFpQixFQUFFLEVBQUUsQ0FBQztRQUM3QyxJQUFJLFFBQVEsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNaLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxjQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsb0NBQW9DLENBQUMsQ0FBQztZQUMzRixTQUFTO1FBQ2IsQ0FBQztRQUNELElBQUksUUFBUSxHQUFHLElBQUEsMkJBQWdCLEVBQUMsTUFBTSxrQkFBRSxDQUFDLFFBQVEsQ0FBQyxjQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbEYsSUFBSSxJQUFJLEdBQUcsZ0JBQU0sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN0RSxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssUUFBUSxDQUFDLElBQUksSUFBSSxJQUFJLEtBQUssUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2hFLE9BQU8sQ0FBQyxHQUFHLENBQ1AsWUFBWSxjQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsdUNBQXVDO2tCQUM5RSxRQUFRLFlBQVksd0NBQXdDLENBQ2pFLENBQUM7WUFDRixTQUFTO1FBQ2IsQ0FBQztRQUNELEtBQUssQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFDRCxLQUFLLElBQUksUUFBUSxJQUFJLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDdkIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLGNBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyx1RUFBdUUsQ0FBQyxDQUFDO1FBQ3pILENBQUM7SUFDTCxDQUFDO0lBRUQsOEZBQThGO0lBQzlGLCtGQUErRjtJQUMvRixpRUFBaUU7SUFDakUsSUFBSSxvQkFBb0IsR0FBRyxjQUFJLENBQUMsSUFBSSxDQUFDLElBQUEsNkJBQWMsRUFBQyxTQUFTLENBQUMsRUFBRSxlQUFlLENBQUMsQ0FBQztJQUNqRixLQUFLLElBQUksSUFBSSxJQUFJLENBQUMsTUFBTSxrQkFBRSxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFjLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7UUFDM0YsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUMxQixTQUFTO1FBQ2IsQ0FBQztRQUNELElBQUksQ0FBQztZQUNELElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxrQkFBRSxDQUFDLFFBQVEsQ0FBQyxjQUFJLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLElBQUksQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDMUYsSUFBSSxRQUFRLEdBQUcsTUFBTSxDQUFDLFdBQVcsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDO1lBQ3RELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDWixTQUFTO1lBQ2IsQ0FBQztZQUNELElBQUksWUFBWSxHQUFHLE1BQU0sQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDdEUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO2dCQUN6QyxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxNQUFNLENBQUMsRUFBRSxLQUFJLE1BQUEsTUFBTSxDQUFDLE9BQU8sMENBQUUsRUFBRSxDQUFBLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNuRyxDQUFDO1FBQ0wsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDVCxPQUFPLENBQUMsR0FBRyxDQUFDLGtDQUFrQyxjQUFJLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDakcsQ0FBQztJQUNMLENBQUM7SUFFRCwwRkFBMEY7SUFDMUYsZ0VBQWdFO0lBQ2hFLGNBQWMsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQzNCLFlBQVksR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ3pCLEtBQUssSUFBSSxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUNyQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxHQUFHLGFBQWEsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDM0UsU0FBUztRQUNiLENBQUM7UUFDRCxJQUFJLENBQUM7WUFDRCxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNuRCxLQUFLLElBQUksT0FBTyxJQUFJLE1BQU0sQ0FBQyxPQUFPLElBQUksRUFBRSxFQUFFLENBQUM7Z0JBQ3ZDLElBQUksUUFBUSxHQUFHLE9BQU8sQ0FBQyxXQUFXLElBQUksT0FBTyxDQUFDLFNBQVMsQ0FBQztnQkFDeEQsSUFBSSxRQUFRLElBQUksT0FBTyxDQUFDLEVBQUUsRUFBRSxDQUFDO29CQUN6QixjQUFjLENBQUMsR0FBRyxDQUFDLEdBQUcsUUFBUSxJQUFJLE9BQU8sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUNwRCxDQUFDO1lBQ0wsQ0FBQztZQUNELEtBQUssSUFBSSxZQUFZLElBQUksTUFBTSxDQUFDLGFBQWEsSUFBSSxFQUFFLEVBQUUsQ0FBQztnQkFDbEQsWUFBWSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUNuQyxDQUFDO1FBQ0wsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDVCxPQUFPLENBQUMsR0FBRyxDQUFDLGdDQUFnQyxRQUFRLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNsRSxDQUFDO0lBQ0wsQ0FBQztJQUVELDRGQUE0RjtJQUM1Rix5RkFBeUY7SUFDekYscUVBQXFFO0lBQ3JFLEtBQUssSUFBSSxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUMxQyxJQUFJLFFBQVEsS0FBSyxpQkFBaUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUMzRixJQUFJLEtBQUssR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNsRCxJQUFJLElBQUksR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUMzQixJQUFJLFdBQVcsR0FBRyxJQUFBLCtCQUFjLEVBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ3ZDLElBQUksV0FBVyxJQUFJLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7b0JBQy9DLE9BQU8sQ0FBQyxHQUFHLENBQUMsd0JBQXdCLFdBQVcsU0FBUyxjQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBQ3pGLE9BQU8sS0FBSyxDQUFDO2dCQUNqQixDQUFDO2dCQUNELE9BQU8sSUFBSSxDQUFDO1lBQ2hCLENBQUMsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDL0IsS0FBSyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN0RCxDQUFDO1FBQ0wsQ0FBQztRQUNELElBQUksUUFBUSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsSUFBSSxRQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDakUsSUFBSSxTQUFTLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3BFLElBQUksZ0JBQWdCLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztnQkFDOUIsT0FBTyxDQUFDLEdBQUcsQ0FBQywyQkFBMkIsU0FBUyxTQUFTLGNBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDMUYsS0FBSyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUMzQixDQUFDO1FBQ0wsQ0FBQztJQUNMLENBQUM7SUFFRCxPQUFPLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLENBQUM7QUFDMUQsQ0FBQztBQXZLRCx3Q0F1S0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY3J5cHRvIGZyb20gXCJjcnlwdG9cIjtcbmltcG9ydCBmcyBmcm9tIFwiZnMvcHJvbWlzZXNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBNQU5JRkVTVF9OQU1FLCBub3JtYWxpemVDb250ZW50LCBTSUdOX05BTUVTUEFDRSwgU0lHTkFUVVJFX05BTUUgfSBmcm9tIFwiLi4vLi4vc2lnbmVkRmlsZXMvbWFuaWZlc3RcIjtcbmltcG9ydCB7IHZlcmlmeVNTSFNJRyB9IGZyb20gXCIuLi8uLi9zaWduZWRGaWxlcy9zc2hzaWdcIjtcbmltcG9ydCB7IGtleUZpbmdlcnByaW50IH0gZnJvbSBcIi4uL2F1dGhvcml6ZWRLZXlzXCI7XG5pbXBvcnQgeyByZXZva2VSZXBvUGF0aCB9IGZyb20gXCIuLi9yZXZva2VTb3VyY2VcIjtcblxuLy8gQSBzb3VyY2UgdGhhdCBoYXMgbmV2ZXIgYmVlbiBzaWduZWQgcmVhZHMgYXMgdGhpcywgc28gbG9zaW5nIGEgc2lnbmF0dXJlIGNvdW50cyBhcyBhIGNoYW5nZSBvZlxuLy8gc2lnbmVyIHJhdGhlciB0aGFuIGFzIHNvbWV0aGluZyB0byB3YXZlIHRocm91Z2guXG5leHBvcnQgY29uc3QgVU5TSUdORUQgPSBcIlwiO1xuLy8gV2hhdCBmaXhlcyBib3RoIG9mIHRoZSBzaWduYXR1cmUgcHJvYmxlbXMgd2UgcmVwb3J0LCBzbyB0aGUgbWVzc2FnZSBjYW4gc2F5IHNvIHJhdGhlciB0aGFuXG4vLyBsZWF2aW5nIHNvbWVvbmUgdG8gd29yayBpdCBvdXQuXG5jb25zdCBTSUdOX0NPTU1BTkQgPSBcInlhcm4gc2lnbmZpbGVzIGdpdFwiO1xuY29uc3QgUkVWT0NBVElPTlNfRElSID0gXCJyZXZvY2F0aW9uc1wiO1xuY29uc3QgVU5SRVZPS0VTX0RJUiA9IFwidW5yZXZva2VkXCI7XG5cbi8vIEV2ZXJ5IHJldm9jYXRpb24gdGhpcyBwcm9jZXNzIGhhcyBldmVyIHNlZW4sIGtleWVkIGJ5IHJldm9jYXRpb24gaWQuIE9uY2UgYWJzb3JiZWQgYSByZXZvY2F0aW9uXG4vLyBuZXZlciBsZWF2ZXMsIGV2ZW4gaWYgaXRzIGZpbGUgZGlzYXBwZWFycyBmcm9tIHRoZSByZXZva2UgcmVwbyAtIHRoZSBrZXkgdGhhdCB3cml0ZXMgcmV2b2NhdGlvbnNcbi8vIGlzIG9uIGV2ZXJ5IHNlcnZlciwgc28gd2hvZXZlciBzdG9sZSBvbmUgY291bGQgb3RoZXJ3aXNlIGVyYXNlIHRoZSByZWNvcmQgdGhhdCBzaHV0IHRoZW0gb3V0LlxuLy8gUmVzdGFydGluZyB0aGUgcHJvY2VzcyBpcyB0aGUgd2F5IGJhY2sgZnJvbSBhIHJldm9jYXRpb24gdGhhdCBzaG91bGQgbm90IGhhdmUgaGFwcGVuZWQuXG5sZXQgYWJzb3JiZWRSZXZvY2F0aW9ucyA9IG5ldyBNYXA8c3RyaW5nLCB7IGlkZW50aXR5OiBzdHJpbmc7IGlwOiBzdHJpbmcgfT4oKTtcbi8vIFRoZSBwYWlycyB0aGUgc2lnbmVkIHVucmV2b2tlcyBhbGxvdywgYW5kIHRoZSBsZWdhY3kgcmV2b2NhdGlvbiBpZHMgdGhleSBuYW1lLiBSZWJ1aWx0IG9uIGV2ZXJ5XG4vLyByZWFkLCBzaW5jZSB1bnJldm9rZXMgYXJlIHNpZ25lZCBjb250ZW50IGFuZCByZW1vdmluZyBvbmUgbXVzdCB0YWtlIGVmZmVjdC5cbmxldCB1bnJldm9rZWRQYWlycyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xubGV0IHVucmV2b2tlZElkcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4vKiogV2hldGhlciBhbiBpZGVudGl0eSAtIGEga2V5IGZpbmdlcnByaW50IG9yIGEgbWFjaGluZSBpZCAtIGhhcyBhIHJldm9jYXRpb24gbm90aGluZyBoYXMgdW5kb25lLlxuICAgIFRoZSBvbmUgbWVhbmluZyBvZiBcImZyb3plblwiLCB1c2VkIGJvdGggd2hlbiBzdHJpcHBpbmcgcmVwbyBjb250ZW50IGFuZCB3aGVuIGV4cGxhaW5pbmcgd2h5LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzSWRlbnRpdHlGcm96ZW4oaWRlbnRpdHk6IHN0cmluZykge1xuICAgIGZvciAobGV0IFtyZXZvY2F0aW9uSWQsIHJldm9jYXRpb25dIG9mIGFic29yYmVkUmV2b2NhdGlvbnMpIHtcbiAgICAgICAgaWYgKHJldm9jYXRpb24uaWRlbnRpdHkgIT09IGlkZW50aXR5KSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodW5yZXZva2VkSWRzLmhhcyhyZXZvY2F0aW9uSWQpIHx8IHVucmV2b2tlZFBhaXJzLmhhcyhgJHtpZGVudGl0eX0gJHtyZXZvY2F0aW9uLmlwfWApKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNQYWlyUmV2b2tlZChpZGVudGl0eTogc3RyaW5nLCBpcDogc3RyaW5nKSB7XG4gICAgZm9yIChsZXQgW3Jldm9jYXRpb25JZCwgcmV2b2NhdGlvbl0gb2YgYWJzb3JiZWRSZXZvY2F0aW9ucykge1xuICAgICAgICBpZiAocmV2b2NhdGlvbi5pZGVudGl0eSA9PT0gaWRlbnRpdHkgJiYgcmV2b2NhdGlvbi5pcCA9PT0gaXAgJiYgIXVucmV2b2tlZElkcy5oYXMocmV2b2NhdGlvbklkKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNQYWlyVW5yZXZva2VkKGlkZW50aXR5OiBzdHJpbmcsIGlwOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdW5yZXZva2VkUGFpcnMuaGFzKGAke2lkZW50aXR5fSAke2lwfWApO1xufVxuXG4vKiogRm9yIHdob2V2ZXIganVzdCB3cm90ZSBhIHJldm9jYXRpb24sIHNvIGl0IGhvbGRzIGhlcmUgaW1tZWRpYXRlbHkgcmF0aGVyIHRoYW4gb24gdGhlIG5leHRcbiAgICBhYnNvcmIuIFN0aWNreSBsaWtlIHRoZSByZXN0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vdGVSZXZvY2F0aW9uKHJldm9jYXRpb25JZDogc3RyaW5nLCBpZGVudGl0eTogc3RyaW5nLCBpcDogc3RyaW5nKSB7XG4gICAgYWJzb3JiZWRSZXZvY2F0aW9ucy5zZXQocmV2b2NhdGlvbklkLCB7IGlkZW50aXR5LCBpcCB9KTtcbn1cblxuLyoqIEEgcmVwbyB3aG9zZSBzaWduYXR1cmUgZG9lcyBub3QgY2hlY2sgb3V0LCB3aXRoIHRoZSBtZXNzYWdlIHJlYWR5IGZvciB3aG9ldmVyIGFza2VkLiBOb3QgZXZlcnlcbiAgICBjYWxsZXIgdHJlYXRzIGl0IHRoZSBzYW1lIC0gYSBzb3VyY2Uga2VlcHMgaXRzIGxhc3Qga2V5cywgYSBtYWNoaW5lIGxpc3QgaXMganVzdCByZWZ1c2VkIC0gc29cbiAgICB0aGUga2luZCBpcyBjYXJyaWVkIHJhdGhlciB0aGFuIGFjdGVkIG9uIGhlcmUuICovXG5leHBvcnQgY2xhc3MgU2lnbmVkUmVwb0Vycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIGNvbnN0cnVjdG9yKHB1YmxpYyBwcm9ibGVtOiBzdHJpbmcsIHB1YmxpYyBoZWFkbGluZTogc3RyaW5nLCBwdWJsaWMgYm9keTogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGAke2hlYWRsaW5lfS4gJHtib2R5fWApO1xuICAgIH1cbn1cblxuLyoqIEV2ZXJ5dGhpbmcgYSBzaWduZWQgY2hlY2tvdXQgdm91Y2hlcyBmb3IsIGluIG9uZSBjYWxsOiB3aG8gc2lnbmVkIGl0LCBhbmQgdGhlIGNvbnRlbnRzIG9mIGV2ZXJ5XG4gICAgZmlsZSB0aGUgc2lnbmF0dXJlIGFjdHVhbGx5IGNvdmVycy5cblxuICAgIFVOU0lHTkVEIHdpdGggbm8gZmlsZXMgd2hlbiB0aGVyZSBpcyBubyBzaWduYXR1cmUgYXQgYWxsLiBUaHJvd3MgYSBTaWduZWRSZXBvRXJyb3Igb25seSB3aGVuIHRoZVxuICAgIHNpZ25hdHVyZSBvdmVyIHRoZSBtYW5pZmVzdCBkb2VzIG5vdCBob2xkIHVwLCBzaW5jZSB0aGVuIG5vdGhpbmcgaW4gdGhlIHJlcG8gY2FuIGJlIGJlbGlldmVkIGFuZFxuICAgIHRoZSBjYWxsZXIga2VlcHMgd2hhdGV2ZXIgaXQgbGFzdCBhY2NlcHRlZC5cblxuICAgIEluZGl2aWR1YWwgZmlsZXMgYXJlIGluY2x1ZGVkIG9yIGxlZnQgb3V0IG9uZSBhdCBhIHRpbWUsIGFuZCBhIGZpbGUgYmVpbmcgbGVmdCBvdXQgbmV2ZXIgYWZmZWN0c1xuICAgIHRoZSBvdGhlcnM6IGEgZmlsZSB0aGUgbWFuaWZlc3QgZG9lcyBub3QgbmFtZSwgYSBmaWxlIHdob3NlIGNvbnRlbnRzIG5vIGxvbmdlciBtYXRjaCB3aGF0IHdhc1xuICAgIHNpZ25lZCwgYW5kIGEgZmlsZSB0aGUgbWFuaWZlc3QgbmFtZXMgdGhhdCBpcyBub3Qgb24gZGlzayBhcmUgYWxsIHNpbXBseSBmaWxlcyB3ZSBob2xkIG5vXG4gICAgc2lnbmF0dXJlIGZvci4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWFkU2lnbmVkUmVwbyhjb25maWc6IHsgcmVwb1BhdGg6IHN0cmluZzsgc291cmNlVVJMOiBzdHJpbmcgfSk6IFByb21pc2U8e1xuICAgIHNpZ25lcjogc3RyaW5nO1xuICAgIG1hbmlmZXN0SGFzaDogc3RyaW5nO1xuICAgIHNpZ25hdHVyZUhhc2g6IHN0cmluZztcbiAgICBmaWxlczogTWFwPHN0cmluZywgQnVmZmVyPjtcbn0+IHtcbiAgICBsZXQgeyByZXBvUGF0aCwgc291cmNlVVJMIH0gPSBjb25maWc7XG4gICAgbGV0IG1hbmlmZXN0Qnl0ZXMgPSBhd2FpdCBmcy5yZWFkRmlsZShwYXRoLmpvaW4ocmVwb1BhdGgsIE1BTklGRVNUX05BTUUpKS5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xuICAgIGxldCBzaWduYXR1cmVCeXRlcyA9IGF3YWl0IGZzLnJlYWRGaWxlKHBhdGguam9pbihyZXBvUGF0aCwgU0lHTkFUVVJFX05BTUUpKS5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xuICAgIGxldCBtYW5pZmVzdEhhc2ggPSBtYW5pZmVzdEJ5dGVzICYmIGNyeXB0by5jcmVhdGVIYXNoKFwic2hhMjU2XCIpLnVwZGF0ZShtYW5pZmVzdEJ5dGVzKS5kaWdlc3QoXCJoZXhcIikgfHwgXCJcIjtcbiAgICBsZXQgc2lnbmF0dXJlSGFzaCA9IHNpZ25hdHVyZUJ5dGVzICYmIGNyeXB0by5jcmVhdGVIYXNoKFwic2hhMjU2XCIpLnVwZGF0ZShzaWduYXR1cmVCeXRlcykuZGlnZXN0KFwiaGV4XCIpIHx8IFwiXCI7XG5cbiAgICBpZiAoIW1hbmlmZXN0Qnl0ZXMgJiYgIXNpZ25hdHVyZUJ5dGVzKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGAke3JlcG9QYXRofSBpcyBub3Qgc2lnbmVkLCBpZ25vcmluZyBhbGwgb2YgaXRzIGZpbGVzYCk7XG4gICAgICAgIHJldHVybiB7IHNpZ25lcjogVU5TSUdORUQsIG1hbmlmZXN0SGFzaCwgc2lnbmF0dXJlSGFzaCwgZmlsZXM6IG5ldyBNYXAoKSB9O1xuICAgIH1cblxuICAgIGxldCBicm9rZW4gPSAoZGV0YWlsOiBzdHJpbmcpID0+IG5ldyBTaWduZWRSZXBvRXJyb3IoXG4gICAgICAgIFwiY29ycnVwdFwiLFxuICAgICAgICBgS0VZIFJFUE8gU0lHTkFUVVJFIElTIEJST0tFTmAsXG4gICAgICAgIGBUaGUgc2lnbmF0dXJlIG9uICR7cmVwb1BhdGh9IGRvZXMgbm90IGNoZWNrIG91dCwgc28gZXZlcnl0aGluZyBpbiBpdCBpcyBiZWluZyBpZ25vcmVkIGFuZGBcbiAgICAgICAgKyBgIHRoaXMgbWFjaGluZSBrZWVwcyB1c2luZyB3aGF0IGl0IGxhc3QgYWNjZXB0ZWQuXFxuXFxuJHtkZXRhaWx9YFxuICAgICAgICArIGBcXG5cXG5UbyByZXBsYWNlIHRoZSBzaWduYXR1cmUsIHJ1biBpbiB0aGF0IHJlcG86XFxuXFxgXFxgXFxgXFxuJHtTSUdOX0NPTU1BTkR9XFxuXFxgXFxgXFxgYFxuICAgICk7XG4gICAgaWYgKCFtYW5pZmVzdEJ5dGVzIHx8ICFzaWduYXR1cmVCeXRlcykge1xuICAgICAgICB0aHJvdyBicm9rZW4oYE9ubHkgb25lIG9mICR7TUFOSUZFU1RfTkFNRX0gYW5kICR7U0lHTkFUVVJFX05BTUV9IGlzIHByZXNlbnQuYCk7XG4gICAgfVxuXG4gICAgbGV0IHNpZ25lcjogc3RyaW5nO1xuICAgIHRyeSB7XG4gICAgICAgIC8vIFRoZSBzaWduYXR1cmUgY292ZXJzIHRoZSBub3JtYWxpc2VkIGJ5dGVzLCBzbyBhIGNoZWNrb3V0IHRoYXQgYXJyaXZlZCB3aXRoIENSTEYgc3RpbGxcbiAgICAgICAgLy8gdmVyaWZpZXMgcmF0aGVyIHRoYW4gbG9va2luZyBsaWtlIHRhbXBlcmluZy5cbiAgICAgICAgc2lnbmVyID0gdmVyaWZ5U1NIU0lHKHtcbiAgICAgICAgICAgIHNpZ25hdHVyZTogc2lnbmF0dXJlQnl0ZXMudG9TdHJpbmcoXCJ1dGY4XCIpLFxuICAgICAgICAgICAgbWVzc2FnZTogbm9ybWFsaXplQ29udGVudChtYW5pZmVzdEJ5dGVzKSxcbiAgICAgICAgICAgIG5hbWVzcGFjZTogU0lHTl9OQU1FU1BBQ0UsXG4gICAgICAgIH0pLnB1YmxpY0tleTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocm93IGJyb2tlbihgJHtlfWApO1xuICAgIH1cblxuICAgIC8vIEV2ZXJ5IGZpbGUgb24gZGlzaywgb3RoZXIgdGhhbiBnaXQncyBvd24gZGlyZWN0b3J5IGFuZCB0aGUgdHdvIHNpZ25hdHVyZSBmaWxlcywgd2hpY2ggY2Fubm90XG4gICAgLy8gZGVzY3JpYmUgdGhlbXNlbHZlcy5cbiAgICBsZXQgbGlzdENoZWNrb3V0RmlsZXMgPSBhc3luYyAocHJlZml4Pzogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmdbXT4gPT4ge1xuICAgICAgICBsZXQgZm91bmQ6IHN0cmluZ1tdID0gW107XG4gICAgICAgIGZvciAobGV0IGVudHJ5IG9mIGF3YWl0IGZzLnJlYWRkaXIocGF0aC5qb2luKHJlcG9QYXRoLCBwcmVmaXggfHwgXCJcIiksIHsgd2l0aEZpbGVUeXBlczogdHJ1ZSB9KSkge1xuICAgICAgICAgICAgbGV0IHJlbGF0aXZlUGF0aCA9IHByZWZpeCAmJiBgJHtwcmVmaXh9LyR7ZW50cnkubmFtZX1gIHx8IGVudHJ5Lm5hbWU7XG4gICAgICAgICAgICBpZiAoZW50cnkubmFtZSA9PT0gXCIuZ2l0XCIpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKCFwcmVmaXggJiYgKGVudHJ5Lm5hbWUgPT09IE1BTklGRVNUX05BTUUgfHwgZW50cnkubmFtZSA9PT0gU0lHTkFUVVJFX05BTUUpKSBjb250aW51ZTtcbiAgICAgICAgICAgIGlmIChlbnRyeS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgICAgICAgICAgZm91bmQucHVzaCguLi5hd2FpdCBsaXN0Q2hlY2tvdXRGaWxlcyhyZWxhdGl2ZVBhdGgpKTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvdW5kLnB1c2gocmVsYXRpdmVQYXRoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZm91bmQuc29ydCgpO1xuICAgIH07XG5cbiAgICBsZXQgbWFuaWZlc3QgPSBKU09OLnBhcnNlKG1hbmlmZXN0Qnl0ZXMudG9TdHJpbmcoXCJ1dGY4XCIpKTtcbiAgICBsZXQgbGlzdGVkID0gbmV3IE1hcDxzdHJpbmcsIHsgc2l6ZTogbnVtYmVyOyBzaGEyNTY6IHN0cmluZyB9PihcbiAgICAgICAgKG1hbmlmZXN0LmZpbGVzIHx8IFtdKS5tYXAoKGZpbGU6IHsgcGF0aDogc3RyaW5nOyBzaXplOiBudW1iZXI7IHNoYTI1Njogc3RyaW5nIH0pID0+IFtmaWxlLnBhdGgsIGZpbGVdKVxuICAgICk7XG5cbiAgICAvLyBBIGZpbGUgY291bnRzIG9ubHkgaWYgdGhlIG1hbmlmZXN0IG5hbWVzIGl0IEFORCBpdHMgY29udGVudHMgc3RpbGwgbWF0Y2guIEFueXRoaW5nIGVsc2UgaXNcbiAgICAvLyBsZWZ0IG91dCwgb25lIGZpbGUgYXQgYSB0aW1lOiBhbiB1bnNpZ25lZCBmaWxlLCBhIGZpbGUgZWRpdGVkIGFmdGVyIHNpZ25pbmcsIGFuZCBhIGZpbGUgdGhlXG4gICAgLy8gbWFuaWZlc3QgbmFtZXMgdGhhdCBpcyBub3QgaGVyZSBhcmUgYWxsIGp1c3QgZmlsZXMgd2UgaGF2ZSBubyBzaWduYXR1cmUgZm9yLiBOb25lIG9mIHRoZW1cbiAgICAvLyBzYXlzIGFueXRoaW5nIGFib3V0IHRoZSBmaWxlcyB0aGF0IERPIG1hdGNoLCBzbyBub25lIG9mIHRoZW0gdGFrZXMgdGhlIHJlc3Qgb2YgdGhlIHJlcG8gZG93blxuICAgIC8vIHdpdGggaXQgLSB0aGUgc2lnbmF0dXJlIG92ZXIgdGhlIG1hbmlmZXN0IGlzIHRoZSBvbmx5IHRoaW5nIHRoYXQgY2FuIGRvIHRoYXQuXG4gICAgbGV0IGZpbGVzID0gbmV3IE1hcDxzdHJpbmcsIEJ1ZmZlcj4oKTtcbiAgICBmb3IgKGxldCBmaWxlUGF0aCBvZiBhd2FpdCBsaXN0Q2hlY2tvdXRGaWxlcygpKSB7XG4gICAgICAgIGxldCBleHBlY3RlZCA9IGxpc3RlZC5nZXQoZmlsZVBhdGgpO1xuICAgICAgICBpZiAoIWV4cGVjdGVkKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgSWdub3JpbmcgJHtwYXRoLmpvaW4ocmVwb1BhdGgsIGZpbGVQYXRoKX0sIGl0IGlzIG5vdCBpbiB0aGUgc2lnbmVkIG1hbmlmZXN0YCk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgY29udGVudHMgPSBub3JtYWxpemVDb250ZW50KGF3YWl0IGZzLnJlYWRGaWxlKHBhdGguam9pbihyZXBvUGF0aCwgZmlsZVBhdGgpKSk7XG4gICAgICAgIGxldCBoYXNoID0gY3J5cHRvLmNyZWF0ZUhhc2goXCJzaGEyNTZcIikudXBkYXRlKGNvbnRlbnRzKS5kaWdlc3QoXCJoZXhcIik7XG4gICAgICAgIGlmIChjb250ZW50cy5sZW5ndGggIT09IGV4cGVjdGVkLnNpemUgfHwgaGFzaCAhPT0gZXhwZWN0ZWQuc2hhMjU2KSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgICBgSWdub3JpbmcgJHtwYXRoLmpvaW4ocmVwb1BhdGgsIGZpbGVQYXRoKX0sIGl0IHdhcyBjaGFuZ2VkIGFmdGVyIGl0IHdhcyBzaWduZWQuYFxuICAgICAgICAgICAgICAgICsgYCBSdW4gJHtTSUdOX0NPTU1BTkR9IGluIHRoYXQgcmVwbyB0byBzaWduIGl0IGFzIGl0IG5vdyBpcy5gXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgZmlsZXMuc2V0KGZpbGVQYXRoLCBjb250ZW50cyk7XG4gICAgfVxuICAgIGZvciAobGV0IGZpbGVQYXRoIG9mIGxpc3RlZC5rZXlzKCkpIHtcbiAgICAgICAgaWYgKCFmaWxlcy5oYXMoZmlsZVBhdGgpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgJHtwYXRoLmpvaW4ocmVwb1BhdGgsIGZpbGVQYXRoKX0gaXMgaW4gdGhlIHNpZ25lZCBtYW5pZmVzdCwgYnV0IHRoZXJlIGlzIG5vdGhpbmcgaGVyZSB0aGF0IG1hdGNoZXMgaXRgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEFic29yYiB0aGUgcmV2b2tlIHJlcG8ncyBmaWxlcyBpbnRvIHRoZSBzdGlja3kgbWFwLiBPbmNlIHNlZW4gYSByZXZvY2F0aW9uIG5ldmVyIGxlYXZlcyBpdCxcbiAgICAvLyBldmVuIGlmIGl0cyBmaWxlIGRpc2FwcGVhcnMgLSB0aGUga2V5IHRoYXQgd3JpdGVzIHJldm9jYXRpb25zIGlzIG9uIGV2ZXJ5IHNlcnZlciwgc28gd2hvZXZlclxuICAgIC8vIHN0b2xlIG9uZSBjb3VsZCBvdGhlcndpc2UgZXJhc2UgdGhlIHJlY29yZCB0aGF0IHNodXQgdGhlbSBvdXQuXG4gICAgbGV0IHJldm9jYXRpb25zRGlyZWN0b3J5ID0gcGF0aC5qb2luKHJldm9rZVJlcG9QYXRoKHNvdXJjZVVSTCksIFJFVk9DQVRJT05TX0RJUik7XG4gICAgZm9yIChsZXQgbmFtZSBvZiAoYXdhaXQgZnMucmVhZGRpcihyZXZvY2F0aW9uc0RpcmVjdG9yeSkuY2F0Y2goKCkgPT4gW10gYXMgc3RyaW5nW10pKS5zb3J0KCkpIHtcbiAgICAgICAgaWYgKCFuYW1lLmVuZHNXaXRoKFwiLmpzb25cIikpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgcGFyc2VkID0gSlNPTi5wYXJzZShhd2FpdCBmcy5yZWFkRmlsZShwYXRoLmpvaW4ocmV2b2NhdGlvbnNEaXJlY3RvcnksIG5hbWUpLCBcInV0ZjhcIikpO1xuICAgICAgICAgICAgbGV0IGlkZW50aXR5ID0gcGFyc2VkLmZpbmdlcnByaW50IHx8IHBhcnNlZC5tYWNoaW5lSWQ7XG4gICAgICAgICAgICBpZiAoIWlkZW50aXR5KSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgcmV2b2NhdGlvbklkID0gcGFyc2VkLnJldm9jYXRpb25JZCB8fCBuYW1lLnJlcGxhY2UoL1xcLmpzb24kLywgXCJcIik7XG4gICAgICAgICAgICBpZiAoIWFic29yYmVkUmV2b2NhdGlvbnMuaGFzKHJldm9jYXRpb25JZCkpIHtcbiAgICAgICAgICAgICAgICBhYnNvcmJlZFJldm9jYXRpb25zLnNldChyZXZvY2F0aW9uSWQsIHsgaWRlbnRpdHksIGlwOiBwYXJzZWQuaXAgfHwgcGFyc2VkLmF0dGVtcHQ/LmlwIHx8IFwiXCIgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBJZ25vcmluZyB1bnJlYWRhYmxlIHJldm9jYXRpb24gJHtwYXRoLmpvaW4ocmV2b2NhdGlvbnNEaXJlY3RvcnksIG5hbWUpfS4gJHtlfWApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gUmVidWlsZCB0aGUgdW5yZXZva2VzIGZyb20gdGhlIHNpZ25lZCBmaWxlcyBqdXN0IHJlYWQuIFVucmV2b2tlcyBhcmUgc2lnbmVkIGNvbnRlbnQsIHNvXG4gICAgLy8gcmVtb3Zpbmcgb25lIG11c3QgdGFrZSBlZmZlY3QsIHVubGlrZSB0aGUgc3RpY2t5IHJldm9jYXRpb25zLlxuICAgIHVucmV2b2tlZFBhaXJzID0gbmV3IFNldCgpO1xuICAgIHVucmV2b2tlZElkcyA9IG5ldyBTZXQoKTtcbiAgICBmb3IgKGxldCBbZmlsZVBhdGgsIGNvbnRlbnRzXSBvZiBmaWxlcykge1xuICAgICAgICBpZiAoIWZpbGVQYXRoLnN0YXJ0c1dpdGgoYCR7VU5SRVZPS0VTX0RJUn0vYCkgfHwgIWZpbGVQYXRoLmVuZHNXaXRoKFwiLmpzb25cIikpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgcGFyc2VkID0gSlNPTi5wYXJzZShjb250ZW50cy50b1N0cmluZyhcInV0ZjhcIikpO1xuICAgICAgICAgICAgZm9yIChsZXQgYWxsb3dlZCBvZiBwYXJzZWQuYWxsb3dlZCB8fCBbXSkge1xuICAgICAgICAgICAgICAgIGxldCBpZGVudGl0eSA9IGFsbG93ZWQuZmluZ2VycHJpbnQgfHwgYWxsb3dlZC5tYWNoaW5lSWQ7XG4gICAgICAgICAgICAgICAgaWYgKGlkZW50aXR5ICYmIGFsbG93ZWQuaXApIHtcbiAgICAgICAgICAgICAgICAgICAgdW5yZXZva2VkUGFpcnMuYWRkKGAke2lkZW50aXR5fSAke2FsbG93ZWQuaXB9YCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChsZXQgcmV2b2NhdGlvbklkIG9mIHBhcnNlZC5yZXZvY2F0aW9uSWRzIHx8IFtdKSB7XG4gICAgICAgICAgICAgICAgdW5yZXZva2VkSWRzLmFkZChyZXZvY2F0aW9uSWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgSWdub3JpbmcgdW5yZWFkYWJsZSB1bnJldm9rZSAke2ZpbGVQYXRofS4gJHtlfWApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gRHJvcCBldmVyeXRoaW5nIGZyb3plbjogcmV2b2tlZCBrZXlzIG91dCBvZiBhdXRob3JpemVkX2tleXMgYW5kIHRvcCBsZXZlbCAucHViIGZpbGVzLCBhbmRcbiAgICAvLyBmcm96ZW4gbWFjaGluZXMnIGZpbGVzIG91dCBvZiBtYWNoaW5lcy8uIFdoYXQgY29tZXMgYmFjayBpcyB3aGF0IHRoaXMgbWFjaGluZSBhY3R1YWxseVxuICAgIC8vIHRydXN0cywgc28gbm8gY2FsbGVyIGNhbiByZWFkIHRoZSBsaXN0IGFuZCBmb3JnZXQgdGhlIHJldm9jYXRpb25zLlxuICAgIGZvciAobGV0IFtmaWxlUGF0aCwgY29udGVudHNdIG9mIFsuLi5maWxlc10pIHtcbiAgICAgICAgaWYgKGZpbGVQYXRoID09PSBcImF1dGhvcml6ZWRfa2V5c1wiIHx8IChmaWxlUGF0aC5lbmRzV2l0aChcIi5wdWJcIikgJiYgIWZpbGVQYXRoLmluY2x1ZGVzKFwiL1wiKSkpIHtcbiAgICAgICAgICAgIGxldCBsaW5lcyA9IGNvbnRlbnRzLnRvU3RyaW5nKFwidXRmOFwiKS5zcGxpdChcIlxcblwiKTtcbiAgICAgICAgICAgIGxldCBrZXB0ID0gbGluZXMuZmlsdGVyKGxpbmUgPT4ge1xuICAgICAgICAgICAgICAgIGxldCBmaW5nZXJwcmludCA9IGtleUZpbmdlcnByaW50KGxpbmUpO1xuICAgICAgICAgICAgICAgIGlmIChmaW5nZXJwcmludCAmJiBpc0lkZW50aXR5RnJvemVuKGZpbmdlcnByaW50KSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgRHJvcHBpbmcgcmV2b2tlZCBrZXkgJHtmaW5nZXJwcmludH0gZnJvbSAke3BhdGguam9pbihyZXBvUGF0aCwgZmlsZVBhdGgpfWApO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoa2VwdC5sZW5ndGggIT09IGxpbmVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGZpbGVzLnNldChmaWxlUGF0aCwgQnVmZmVyLmZyb20oa2VwdC5qb2luKFwiXFxuXCIpKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZpbGVQYXRoLnN0YXJ0c1dpdGgoXCJtYWNoaW5lcy9cIikgJiYgZmlsZVBhdGguZW5kc1dpdGgoXCIuanNvblwiKSkge1xuICAgICAgICAgICAgbGV0IG1hY2hpbmVJZCA9IGZpbGVQYXRoLnNsaWNlKFwibWFjaGluZXMvXCIubGVuZ3RoLCAtXCIuanNvblwiLmxlbmd0aCk7XG4gICAgICAgICAgICBpZiAoaXNJZGVudGl0eUZyb3plbihtYWNoaW5lSWQpKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coYERyb3BwaW5nIGZyb3plbiBtYWNoaW5lICR7bWFjaGluZUlkfSBmcm9tICR7cGF0aC5qb2luKHJlcG9QYXRoLCBmaWxlUGF0aCl9YCk7XG4gICAgICAgICAgICAgICAgZmlsZXMuZGVsZXRlKGZpbGVQYXRoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7IHNpZ25lciwgbWFuaWZlc3RIYXNoLCBzaWduYXR1cmVIYXNoLCBmaWxlcyB9O1xufVxuIl19
|
|
241
|
+
/* _JS_SOURCE_HASH = "d3acdb6db034d40babc0df2c4f949cd4683a1b30159b8c43a628e0bf4c60fa50"; */
|
|
@@ -9,9 +9,9 @@ export declare function isPairUnrevoked(identity: string, ip: string): boolean;
|
|
|
9
9
|
/** For whoever just wrote a revocation, so it holds here immediately rather than on the next
|
|
10
10
|
absorb. Sticky like the rest. */
|
|
11
11
|
export declare function noteRevocation(revocationId: string, identity: string, ip: string): void;
|
|
12
|
-
/** A repo
|
|
13
|
-
treats
|
|
14
|
-
kind is carried rather than acted on here. */
|
|
12
|
+
/** A repo whose signature does not check out, with the message ready for whoever asked. Not every
|
|
13
|
+
caller treats it the same - a source keeps its last keys, a machine list is just refused - so
|
|
14
|
+
the kind is carried rather than acted on here. */
|
|
15
15
|
export declare class SignedRepoError extends Error {
|
|
16
16
|
problem: string;
|
|
17
17
|
headline: string;
|
|
@@ -21,11 +21,14 @@ export declare class SignedRepoError extends Error {
|
|
|
21
21
|
/** Everything a signed checkout vouches for, in one call: who signed it, and the contents of every
|
|
22
22
|
file the signature actually covers.
|
|
23
23
|
|
|
24
|
-
UNSIGNED with no files when there is no signature at all. Throws a SignedRepoError when
|
|
25
|
-
signature
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
UNSIGNED with no files when there is no signature at all. Throws a SignedRepoError only when the
|
|
25
|
+
signature over the manifest does not hold up, since then nothing in the repo can be believed and
|
|
26
|
+
the caller keeps whatever it last accepted.
|
|
27
|
+
|
|
28
|
+
Individual files are included or left out one at a time, and a file being left out never affects
|
|
29
|
+
the others: a file the manifest does not name, a file whose contents no longer match what was
|
|
30
|
+
signed, and a file the manifest names that is not on disk are all simply files we hold no
|
|
31
|
+
signature for. */
|
|
29
32
|
export declare function readSignedRepo(config: {
|
|
30
33
|
repoPath: string;
|
|
31
34
|
sourceURL: string;
|
|
@@ -59,9 +59,9 @@ export function noteRevocation(revocationId: string, identity: string, ip: strin
|
|
|
59
59
|
absorbedRevocations.set(revocationId, { identity, ip });
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
/** A repo
|
|
63
|
-
treats
|
|
64
|
-
kind is carried rather than acted on here. */
|
|
62
|
+
/** A repo whose signature does not check out, with the message ready for whoever asked. Not every
|
|
63
|
+
caller treats it the same - a source keeps its last keys, a machine list is just refused - so
|
|
64
|
+
the kind is carried rather than acted on here. */
|
|
65
65
|
export class SignedRepoError extends Error {
|
|
66
66
|
constructor(public problem: string, public headline: string, public body: string) {
|
|
67
67
|
super(`${headline}. ${body}`);
|
|
@@ -71,11 +71,14 @@ export class SignedRepoError extends Error {
|
|
|
71
71
|
/** Everything a signed checkout vouches for, in one call: who signed it, and the contents of every
|
|
72
72
|
file the signature actually covers.
|
|
73
73
|
|
|
74
|
-
UNSIGNED with no files when there is no signature at all. Throws a SignedRepoError when
|
|
75
|
-
signature
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
74
|
+
UNSIGNED with no files when there is no signature at all. Throws a SignedRepoError only when the
|
|
75
|
+
signature over the manifest does not hold up, since then nothing in the repo can be believed and
|
|
76
|
+
the caller keeps whatever it last accepted.
|
|
77
|
+
|
|
78
|
+
Individual files are included or left out one at a time, and a file being left out never affects
|
|
79
|
+
the others: a file the manifest does not name, a file whose contents no longer match what was
|
|
80
|
+
signed, and a file the manifest names that is not on disk are all simply files we hold no
|
|
81
|
+
signature for. */
|
|
79
82
|
export async function readSignedRepo(config: { repoPath: string; sourceURL: string }): Promise<{
|
|
80
83
|
signer: string;
|
|
81
84
|
manifestHash: string;
|
|
@@ -117,13 +120,6 @@ export async function readSignedRepo(config: { repoPath: string; sourceURL: stri
|
|
|
117
120
|
throw broken(`${e}`);
|
|
118
121
|
}
|
|
119
122
|
|
|
120
|
-
let stale = (detail: string) => new SignedRepoError(
|
|
121
|
-
"stale",
|
|
122
|
-
`KEY REPO CHANGED WITHOUT BEING SIGNED`,
|
|
123
|
-
`${detail}, so the repo is being ignored and this machine keeps using what it last accepted.`
|
|
124
|
-
+ `\n\nTo make the change take effect, run in that repo:\n\`\`\`\n${SIGN_COMMAND}\n\`\`\``
|
|
125
|
-
);
|
|
126
|
-
|
|
127
123
|
// Every file on disk, other than git's own directory and the two signature files, which cannot
|
|
128
124
|
// describe themselves.
|
|
129
125
|
let listCheckoutFiles = async (prefix?: string): Promise<string[]> => {
|
|
@@ -146,27 +142,32 @@ export async function readSignedRepo(config: { repoPath: string; sourceURL: stri
|
|
|
146
142
|
(manifest.files || []).map((file: { path: string; size: number; sha256: string }) => [file.path, file])
|
|
147
143
|
);
|
|
148
144
|
|
|
145
|
+
// A file counts only if the manifest names it AND its contents still match. Anything else is
|
|
146
|
+
// left out, one file at a time: an unsigned file, a file edited after signing, and a file the
|
|
147
|
+
// manifest names that is not here are all just files we have no signature for. None of them
|
|
148
|
+
// says anything about the files that DO match, so none of them takes the rest of the repo down
|
|
149
|
+
// with it - the signature over the manifest is the only thing that can do that.
|
|
149
150
|
let files = new Map<string, Buffer>();
|
|
150
151
|
for (let filePath of await listCheckoutFiles()) {
|
|
151
152
|
let expected = listed.get(filePath);
|
|
152
|
-
// A file the signature never mentioned is not tampering, it is just unsigned - left out
|
|
153
|
-
// rather than trusted. An extra file in a working tree is ordinary, so it is only a note.
|
|
154
153
|
if (!expected) {
|
|
155
154
|
console.log(`Ignoring ${path.join(repoPath, filePath)}, it is not in the signed manifest`);
|
|
156
155
|
continue;
|
|
157
156
|
}
|
|
158
157
|
let contents = normalizeContent(await fs.readFile(path.join(repoPath, filePath)));
|
|
159
158
|
let hash = crypto.createHash("sha256").update(contents).digest("hex");
|
|
160
|
-
// A file the manifest DOES name, but whose content no longer matches, is a signed file
|
|
161
|
-
// changed without re-signing - the repo being edited out from under its signature.
|
|
162
159
|
if (contents.length !== expected.size || hash !== expected.sha256) {
|
|
163
|
-
|
|
160
|
+
console.log(
|
|
161
|
+
`Ignoring ${path.join(repoPath, filePath)}, it was changed after it was signed.`
|
|
162
|
+
+ ` Run ${SIGN_COMMAND} in that repo to sign it as it now is.`
|
|
163
|
+
);
|
|
164
|
+
continue;
|
|
164
165
|
}
|
|
165
166
|
files.set(filePath, contents);
|
|
166
167
|
}
|
|
167
168
|
for (let filePath of listed.keys()) {
|
|
168
169
|
if (!files.has(filePath)) {
|
|
169
|
-
|
|
170
|
+
console.log(`${path.join(repoPath, filePath)} is in the signed manifest, but there is nothing here that matches it`);
|
|
170
171
|
}
|
|
171
172
|
}
|
|
172
173
|
|