hivessh
Version:
HiveSsh is an innovative library designed to streamline SSH2 connections and simplify task execution on Linux servers.
237 lines • 35.3 kB
JavaScript
export const defaultCmdChannelSettings = {
pwd: "/",
env: undefined,
timeoutMillis: -1,
sudo: false,
};
export class SshChannelExitError extends Error {
exit;
constructor(message, exit) {
super(message);
this.exit = exit;
}
}
export function toSshChannel(channel, extras) {
const sshChannel = channel;
for (const key of Object.typedKeys(extras)) {
sshChannel[key] = extras[key];
}
return sshChannel;
}
export async function execSshChannel(sshClient, cmd, options) {
const settings = {
...defaultCmdChannelSettings,
...options,
};
settings.env = {
...settings.env,
PWD: settings.pwd,
};
if (settings.sudo) {
cmd = "sudo " + cmd;
}
const baseChannel = await new Promise((res, rej) => sshClient.exec(cmd, settings, (err, channel) => err ?
rej(err) :
res(channel)));
const channel = toSshChannel(baseChannel, {
cmd,
settings,
stdout: baseChannel.stdout,
toPromise: sshChannelToPromise(baseChannel, cmd)
});
if (typeof settings.timeoutMillis == "number" &&
settings.timeoutMillis > 0) {
channel.timeout = setTimeout(() => {
if (!channel.closed) {
channel.close("Timeout", settings.timeoutMillis);
}
}, settings.timeoutMillis);
channel.once("close", () => clearTimeout(channel.timeout));
}
return channel;
}
export const defaultChannelToPromiseSettings = {
mapOut: undefined,
mapStdOut: undefined,
mapErrOut: undefined,
filterOut: undefined,
filterStdOut: undefined,
filterErrOut: undefined,
filterOutOptions: undefined,
filterStdOutOptions: undefined,
filterErrOutOptions: undefined,
throwOnOut: undefined,
throwOnStdOut: false,
throwOnErrOut: true,
expectedExitCode: [0],
};
export function checkDataChunk(chunk) {
if (chunk instanceof Buffer) {
return chunk.toString("utf8");
}
else if (typeof chunk != "string") {
throw new Error("Unexpected chunk type: '" + typeof chunk + "'\n" +
"Value: '" + chunk + "'");
}
return chunk;
}
export function sshChannelToPromise(channel, cmd) {
return (options) => {
let resolved = false;
let resolveValue;
let rejected = false;
let rejectReason;
let res = (value) => {
if (rejected || resolved) {
return;
}
resolved = true;
resolveValue = value;
};
let rej = (reason) => {
if (rejected || resolved) {
return;
}
rejected = true;
rejectReason = reason;
};
const settings = {
...defaultChannelToPromiseSettings,
...options,
expectedExitCode: undefined,
};
if (typeof settings.expectedExitCode == "number") {
settings.expectedExitCode = [settings.expectedExitCode];
}
const chunks = [];
let anyErr = false;
let anyStd = false;
let stdout = channel.stdout;
let stderr = channel.stderr;
if (typeof settings == "object") {
if (settings.filterOut) {
settings.filterStdOut = settings.filterOut;
settings.filterErrOut = settings.filterOut;
}
if (settings.filterOutOptions) {
settings.filterStdOutOptions = settings.filterOutOptions;
settings.filterErrOutOptions = settings.filterOutOptions;
}
if (settings.throwOnOut) {
settings.throwOnStdOut = settings.throwOnOut;
settings.throwOnErrOut = settings.throwOnOut;
}
if (settings.mapOut) {
settings.mapStdOut = settings.mapOut;
settings.mapErrOut = settings.mapOut;
}
if (settings.filterStdOut) {
const filterStdOut = settings.filterStdOut;
stdout.filter((data, options) => filterStdOut(data, false, options), settings.filterStdOutOptions);
}
if (settings.filterErrOut) {
const filterErrOut = settings.filterErrOut;
stderr.filter((data, options) => filterErrOut(data, true, options), settings.filterErrOutOptions);
}
if (settings.mapStdOut) {
const mapStdOut = settings.mapStdOut;
stdout.on("data", (chunk) => {
chunk = checkDataChunk(chunk);
chunk = mapStdOut(chunk, false);
if (typeof chunk == "string") {
chunks.push([false, "" + chunk]);
}
});
}
else {
stdout.on("data", (chunk) => {
chunk = checkDataChunk(chunk);
chunks.push([false, "" + chunk]);
});
}
if (settings.mapErrOut) {
const mapErrOut = settings.mapErrOut;
stderr.on("data", (chunk) => {
chunk = checkDataChunk(chunk);
chunk = mapErrOut(chunk, true);
if (typeof chunk == "string") {
chunks.push([true, "" + chunk]);
}
});
}
else {
stderr.on("data", (chunk) => {
chunk = checkDataChunk(chunk);
chunks.push([true, "" + chunk]);
});
}
}
else {
stdout.on("data", (chunk) => {
chunk = checkDataChunk(chunk);
chunks.push([false, "" + chunk]);
});
stderr.on("data", (chunk) => {
chunk = checkDataChunk(chunk);
chunks.push([true, "" + chunk]);
});
}
stdout.on("data", () => {
anyStd = true;
});
stderr.on("data", () => {
anyErr = true;
});
channel.once("error", (err) => {
rej(err);
if (!channel.closed) {
channel.close();
}
});
channel.once("close", (...params) => channel.emit("exit", ...params));
channel.once("exit", (code, signal, dump, desc) => {
if (!channel.closed) {
channel.close();
}
const exit = {
cmd,
code: code === null ? -1 : code,
signal,
dump,
desc,
chunks,
anyErr,
anyStd,
out: chunks.map((v) => v[1]).join("\n")
};
if (options) {
if (options.throwOnErrOut &&
anyErr) {
rej(new SshChannelExitError("Unexpected error stream output:\n " +
chunks.filter((chunks) => chunks[0]).join("\n "), exit));
return;
}
if (options.throwOnStdOut &&
anyStd) {
rej(new SshChannelExitError("Unexpected standard stream output:\n " +
chunks.filter((chunks) => !chunks[0]).join("\n "), exit));
return;
}
}
res(exit);
});
return new Promise((res2, rej2) => {
if (resolved) {
res2(resolveValue);
return;
}
else if (rejected) {
rej2(rejectReason);
return;
}
res = res2;
rej = rej2;
});
};
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3NoRXhlYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9Tc2hFeGVjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXdCQSxNQUFNLENBQUMsTUFBTSx5QkFBeUIsR0FBdUI7SUFDekQsR0FBRyxFQUFFLEdBQUc7SUFDUixHQUFHLEVBQUUsU0FBUztJQUNkLGFBQWEsRUFBRSxDQUFDLENBQUM7SUFDakIsSUFBSSxFQUFFLEtBQUs7Q0FDZCxDQUFBO0FBZ0JELE1BQU0sT0FBTyxtQkFBb0IsU0FBUSxLQUFLO0lBRy9CO0lBRlgsWUFDSSxPQUFlLEVBQ1IsSUFBb0I7UUFFM0IsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBRlAsU0FBSSxHQUFKLElBQUksQ0FBZ0I7SUFHL0IsQ0FBQztDQUNKO0FBY0QsTUFBTSxVQUFVLFlBQVksQ0FDeEIsT0FBc0IsRUFDdEIsTUFBd0I7SUFFeEIsTUFBTSxVQUFVLEdBQUcsT0FBYyxDQUFBO0lBRWpDLEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQ3pDLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7SUFDakMsQ0FBQztJQUVELE9BQU8sVUFBVSxDQUFBO0FBQ3JCLENBQUM7QUFFRCxNQUFNLENBQUMsS0FBSyxVQUFVLGNBQWMsQ0FDaEMsU0FBb0IsRUFDcEIsR0FBVyxFQUNYLE9BQTJCO0lBRTNCLE1BQU0sUUFBUSxHQUF1QjtRQUNqQyxHQUFHLHlCQUF5QjtRQUM1QixHQUFHLE9BQU87S0FDYixDQUFBO0lBRUQsUUFBUSxDQUFDLEdBQUcsR0FBRztRQUNYLEdBQUcsUUFBUSxDQUFDLEdBQUc7UUFDZixHQUFHLEVBQUUsUUFBUSxDQUFDLEdBQUc7S0FDcEIsQ0FBQTtJQUVELElBQUksUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2hCLEdBQUcsR0FBRyxPQUFPLEdBQUcsR0FBRyxD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Q0FBQztvQkFDQyxHQUFHLENBQUMsSUFBSSxtQkFBbUIsQ0FDdkIsd0NBQXdDO3dCQUN4QyxNQUFNLENBQUMsTUFBTSxDQUNULENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FDekIsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQ2QsSUFBSSxDQUNQLENBQUMsQ0FBQTtvQkFDRixPQUFNO2dCQUVWLENBQUM7WUFDTCxDQUFDO1lBRUQsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQ2IsQ0FBQyxDQUFDLENBQUE7UUFHRixPQUFPLElBQUksT0FBTyxDQUNkLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFO1lBQ1gsSUFBSSxRQUFRLEVBQUUsQ0FBQztnQkFDWCxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUE7Z0JBQ2xCLE9BQU07WUFDVixDQUFDO2lCQUFNLElBQUksUUFBUSxFQUFFLENBQUM7Z0JBQ2xCLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQTtnQkFDbEIsT0FBTTtZQUNWLENBQUM7WUFFRCxHQUFHLEdBQUcsSUFBSSxDQUFBO1lBQ1YsR0FBRyxHQUFHLElBQUksQ0FBQTtRQUNkLENBQUMsQ0FDSixDQUFBO0lBQ0wsQ0FBQyxDQUFBO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENsaWVudENoYW5uZWwsIEV4ZWNPcHRpb25zLCBDbGllbnQgYXMgU3NoQ2xpZW50IH0gZnJvbSBcInNzaDJcIjtcbmltcG9ydCB7IFJlYWRhYmxlIH0gZnJvbSBcInN0cmVhbVwiO1xuaW1wb3J0IHsgQXdhaXRhYmxlIH0gZnJvbSBcIi4vdXRpbHMvYmFzZS5qc1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIEFycmF5T3B0aW9ucyB7XG4gICAgY29uY3VycmVuY3k/OiBudW1iZXI7XG4gICAgc2lnbmFsPzogQWJvcnRTaWduYWw7XG4gICAgZW5jb2Rpbmc/OiBCdWZmZXJFbmNvZGluZ1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENtZENoYW5uZWxPcHRpb25zIGV4dGVuZHMgRXhlY09wdGlvbnMge1xuICAgIHB3ZD86IHN0cmluZyxcbiAgICBlbnY/OiBOb2RlSlMuUHJvY2Vzc0VudixcbiAgICB0aW1lb3V0TWlsbGlzPzogbnVtYmVyLFxuICAgIHN1ZG8/OiBib29sZWFuLFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIENtZENoYW5uZWxTZXR0aW5ncyBleHRlbmRzIEV4ZWNPcHRpb25zIHtcbiAgICBwd2Q6IHN0cmluZyxcbiAgICBlbnY6IE5vZGVKUy5Qcm9jZXNzRW52IHwgdW5kZWZpbmVkLFxuICAgIHRpbWVvdXRNaWxsaXM6IG51bWJlcixcbiAgICBzdWRvOiBib29sZWFuLFxufVxuXG5leHBvcnQgY29uc3QgZGVmYXVsdENtZENoYW5uZWxTZXR0aW5nczogQ21kQ2hhbm5lbFNldHRpbmdzID0ge1xuICAgIHB3ZDogXCIvXCIsXG4gICAgZW52OiB1bmRlZmluZWQsXG4gICAgdGltZW91dE1pbGxpczogLTEsXG4gICAgc3VkbzogZmFsc2UsXG59XG5cbmV4cG9ydCB0eXBlIENtZEV4ZWNPcHRpb25zID0gQ21kQ2hhbm5lbE9wdGlvbnMgJiBDaGFubmVsVG9Qcm9taXNlT3B0aW9uc1xuXG5leHBvcnQgaW50ZXJmYWNlIFNzaENoYW5uZWxFeGl0IHtcbiAgICBjbWQ6IHN0cmluZyxcbiAgICBvdXQ6IHN0cmluZyxcbiAgICBjaHVua3M6IFtib29sZWFuLCBzdHJpbmddW10sXG4gICAgYW55RXJyOiBib29sZWFuLFxuICAgIGFueVN0ZDogYm9vbGVhbixcbiAgICBjb2RlOiBudW1iZXIsXG4gICAgc2lnbmFsPzogc3RyaW5nLFxuICAgIGR1bXA/OiBzdHJpbmcsXG4gICAgZGVzYz86IHN0cmluZ1xufVxuXG5leHBvcnQgY2xhc3MgU3NoQ2hhbm5lbEV4aXRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgbWVzc2FnZTogc3RyaW5nLFxuICAgICAgICBwdWJsaWMgZXhpdDogU3NoQ2hhbm5lbEV4aXQsXG4gICAgKSB7XG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpXG4gICAgfVxufVxuXG5leHBvcnQgdHlwZSBTc2hDaGFubmVsVG9Qcm9taXNlID0gKG9wdGlvbnM/OiBDaGFubmVsVG9Qcm9taXNlT3B0aW9ucykgPT4gUHJvbWlzZTxTc2hDaGFubmVsRXhpdD5cblxuZXhwb3J0IGludGVyZmFjZSBTc2hDaGFubmVsRXh0cmFzIHtcbiAgICBjbWQ6IHN0cmluZyxcbiAgICB0aW1lb3V0PzogTm9kZUpTLlRpbWVvdXQgfCB1bmRlZmluZWQsXG4gICAgc2V0dGluZ3M6IENtZENoYW5uZWxTZXR0aW5ncyxcbiAgICBzdGRvdXQ6IFJlYWRhYmxlLFxuICAgIHRvUHJvbWlzZTogU3NoQ2hhbm5lbFRvUHJvbWlzZVxufVxuXG5leHBvcnQgdHlwZSBTc2hDaGFubmVsID0gT21pdDxDbGllbnRDaGFubmVsLCBcInN0ZG91dFwiPiAmIFNzaENoYW5uZWxFeHRyYXNcblxuZXhwb3J0IGZ1bmN0aW9uIHRvU3NoQ2hhbm5lbChcbiAgICBjaGFubmVsOiBDbGllbnRDaGFubmVsLFxuICAgIGV4dHJhczogU3NoQ2hhbm5lbEV4dHJhcyxcbik6IFNzaENoYW5uZWwge1xuICAgIGNvbnN0IHNzaENoYW5uZWwgPSBjaGFubmVsIGFzIGFueVxuXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LnR5cGVkS2V5cyhleHRyYXMpKSB7XG4gICAgICAgIHNzaENoYW5uZWxba2V5XSA9IGV4dHJhc1trZXldXG4gICAgfVxuXG4gICAgcmV0dXJuIHNzaENoYW5uZWxcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGV4ZWNTc2hDaGFubmVsKFxuICAgIHNzaENsaWVudDogU3NoQ2xpZW50LFxuICAgIGNtZDogc3RyaW5nLFxuICAgIG9wdGlvbnM/OiBDbWRDaGFubmVsT3B0aW9uc1xuKTogUHJvbWlzZTxTc2hDaGFubmVsPiB7XG4gICAgY29uc3Qgc2V0dGluZ3M6IENtZENoYW5uZWxTZXR0aW5ncyA9IHtcbiAgICAgICAgLi4uZGVmYXVsdENtZENoYW5uZWxTZXR0aW5ncyxcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICB9XG5cbiAgICBzZXR0aW5ncy5lbnYgPSB7XG4gICAgICAgIC4uLnNldHRpbmdzLmVudixcbiAgICAgICAgUFdEOiBzZXR0aW5ncy5wd2QsXG4gICAgfVxuXG4gICAgaWYgKHNldHRpbmdzLnN1ZG8pIHtcbiAgICAgICAgY21kID0gXCJzdWRvIFwiICsgY21kXG4gICAgfVxuXG4gICAgY29uc3QgYmFzZUNoYW5uZWwgPSBhd2FpdCBuZXcgUHJvbWlzZTxDbGllbnRDaGFubmVsPihcbiAgICAgICAgKHJlcywgcmVqKSA9PiBzc2hDbGllbnQuZXhlYyhcbiAgICAgICAgICAgIGNtZCxcbiAgICAgICAgICAgIHNldHRpbmdzLFxuICAgICAgICAgICAgKGVyciwgY2hhbm5lbCkgPT5cbiAgICAgICAgICAgICAgICBlcnIgP1xuICAgICAgICAgICAgICAgICAgICByZWooZXJyKSA6XG4gICAgICAgICAgICAgICAgICAgIHJlcyhjaGFubmVsKVxuICAgICAgICApXG4gICAgKVxuXG4gICAgY29uc3QgY2hhbm5lbCA9IHRvU3NoQ2hhbm5lbChcbiAgICAgICAgYmFzZUNoYW5uZWwsXG4gICAgICAgIHtcbiAgICAgICAgICAgIGNtZCxcbiAgICAgICAgICAgIHNldHRpbmdzLFxuICAgICAgICAgICAgc3Rkb3V0OiBiYXNlQ2hhbm5lbC5zdGRvdXQsXG4gICAgICAgICAgICB0b1Byb21pc2U6IHNzaENoYW5uZWxUb1Byb21pc2UoXG4gICAgICAgICAgICAgICAgYmFzZUNoYW5uZWwsXG4gICAgICAgICAgICAgICAgY21kLFxuICAgICAgICAgICAgKVxuICAgICAgICB9XG4gICAgKVxuXG4gICAgaWYgKFxuICAgICAgICB0eXBlb2Ygc2V0dGluZ3MudGltZW91dE1pbGxpcyA9PSBcIm51bWJlclwiICYmXG4gICAgICAgIHNldHRpbmdzLnRpbWVvdXRNaWxsaXMgPiAwXG4gICAgKSB7XG5cbiAgICAgICAgY2hhbm5lbC50aW1lb3V0ID0gc2V0VGltZW91dChcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIWNoYW5uZWwuY2xvc2VkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWwuY2xvc2UoXG4gICAgICAgICAgICAgICAgICAgICAgICBcIlRpbWVvdXRcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldHRpbmdzLnRpbWVvdXRNaWxsaXNcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXR0aW5ncy50aW1lb3V0TWlsbGlzXG4gICAgICAgIClcbiAgICAgICAgY2hhbm5lbC5vbmNlKFxuICAgICAgICAgICAgXCJjbG9zZVwiLFxuICAgICAgICAgICAgKCkgPT4gY2xlYXJUaW1lb3V0KFxuICAgICAgICAgICAgICAgIGNoYW5uZWwudGltZW91dFxuICAgICAgICAgICAgKVxuICAgICAgICApXG4gICAgfVxuXG4gICAgcmV0dXJuIGNoYW5uZWxcbn1cblxuZXhwb3J0IHR5cGUgU3RyZWFtRGF0YU1hcHBlciA9IChcbiAgICBkYXRhOiBzdHJpbmcsXG4gICAgZXJyOiBib29sZWFuXG4pID0+IEF3YWl0YWJsZTxzdHJpbmcgfCB1bmRlZmluZWQgfCB2b2lkPlxuXG5leHBvcnQgdHlwZSBTdHJlYW1EYXRhRmlsdGVyID0gKFxuICAgIGRhdGE6IHN0cmluZyxcbiAgICBlcnI6IGJvb2xlYW4sXG4gICAgb3B0aW9ucz86IFBpY2s8QXJyYXlPcHRpb25zLCBcInNpZ25hbFwiPlxuKSA9PiBBd2FpdGFibGU8Ym9vbGVhbj5cblxuZXhwb3J0IGludGVyZmFjZSBDaGFubmVsVG9Qcm9taXNlT3B0aW9ucyB7XG4gICAgbWFwT3V0PzogU3RyZWFtRGF0YU1hcHBlcixcbiAgICBtYXBTdGRPdXQ/OiBTdHJlYW1EYXRhTWFwcGVyLFxuICAgIG1hcEVyck91dD86IFN0cmVhbURhdGFNYXBwZXIsXG4gICAgZmlsdGVyT3V0PzogU3RyZWFtRGF0YUZpbHRlcixcbiAgICBmaWx0ZXJTdGRPdXQ/OiBTdHJlYW1EYXRhRmlsdGVyLFxuICAgIGZpbHRlckVyck91dD86IFN0cmVhbURhdGFGaWx0ZXIsXG4gICAgZmlsdGVyT3V0T3B0aW9ucz86IEFycmF5T3B0aW9ucyxcbiAgICBmaWx0ZXJTdGRPdXRPcHRpb25zPzogQXJyYXlPcHRpb25zLFxuICAgIGZpbHRlckVyck91dE9wdGlvbnM/OiBBcnJheU9wdGlvbnMsXG4gICAgdGhyb3dPbk91dD86IGJvb2xlYW4sXG4gICAgdGhyb3dPblN0ZE91dD86IGJvb2xlYW4sXG4gICAgdGhyb3dPbkVyck91dD86IGJvb2xlYW4sXG4gICAgZXhwZWN0ZWRFeGl0Q29kZT86IG51bWJlciB8IG51bWJlcltdLFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIENoYW5uZWxUb1Byb21pc2VTZXR0aW5ncyB7XG4gICAgbWFwT3V0OiBTdHJlYW1EYXRhTWFwcGVyIHwgdW5kZWZpbmVkLFxuICAgIG1hcFN0ZE91dDogU3RyZWFtRGF0YU1hcHBlciB8IHVuZGVmaW5lZCxcbiAgICBtYXBFcnJPdXQ6IFN0cmVhbURhdGFNYXBwZXIgfCB1bmRlZmluZWQsXG4gICAgZmlsdGVyT3V0OiBTdHJlYW1EYXRhRmlsdGVyIHwgdW5kZWZpbmVkLFxuICAgIGZpbHRlclN0ZE91dDogU3RyZWFtRGF0YUZpbHRlciB8IHVuZGVmaW5lZCxcbiAgICBmaWx0ZXJFcnJPdXQ6IFN0cmVhbURhdGFGaWx0ZXIgfCB1bmRlZmluZWQsXG4gICAgZmlsdGVyT3V0T3B0aW9uczogQXJyYXlPcHRpb25zIHwgdW5kZWZpbmVkLFxuICAgIGZpbHRlclN0ZE91dE9wdGlvbnM6IEFycmF5T3B0aW9ucyB8IHVuZGVmaW5lZCxcbiAgICBmaWx0ZXJFcnJPdXRPcHRpb25zOiBBcnJheU9wdGlvbnMgfCB1bmRlZmluZWQsXG4gICAgdGhyb3dPbk91dDogYm9vbGVhbiB8IHVuZGVmaW5lZCxcbiAgICB0aHJvd09uU3RkT3V0OiBib29sZWFuLFxuICAgIHRocm93T25FcnJPdXQ6IGJvb2xlYW4sXG4gICAgZXhwZWN0ZWRFeGl0Q29kZTogbnVtYmVyW10sXG59XG5cbmV4cG9ydCBjb25zdCBkZWZhdWx0Q2hhbm5lbFRvUHJvbWlzZVNldHRpbmdzOiBDaGFubmVsVG9Qcm9taXNlU2V0dGluZ3MgPSB7XG4gICAgbWFwT3V0OiB1bmRlZmluZWQsXG4gICAgbWFwU3RkT3V0OiB1bmRlZmluZWQsXG4gICAgbWFwRXJyT3V0OiB1bmRlZmluZWQsXG4gICAgZmlsdGVyT3V0OiB1bmRlZmluZWQsXG4gICAgZmlsdGVyU3RkT3V0OiB1bmRlZmluZWQsXG4gICAgZmlsdGVyRXJyT3V0OiB1bmRlZmluZWQsXG4gICAgZmlsdGVyT3V0T3B0aW9uczogdW5kZWZpbmVkLFxuICAgIGZpbHRlclN0ZE91dE9wdGlvbnM6IHVuZGVmaW5lZCxcbiAgICBmaWx0ZXJFcnJPdXRPcHRpb25zOiB1bmRlZmluZWQsXG4gICAgdGhyb3dPbk91dDogdW5kZWZpbmVkLFxuICAgIHRocm93T25TdGRPdXQ6IGZhbHNlLFxuICAgIHRocm93T25FcnJPdXQ6IHRydWUsXG4gICAgZXhwZWN0ZWRFeGl0Q29kZTogWzBdLFxufVxuXG5leHBvcnQgZnVuY3Rpb24gY2hlY2tEYXRhQ2h1bmsoY2h1bms6IGFueSk6IHN0cmluZyB7XG4gICAgaWYgKGNodW5rIGluc3RhbmNlb2YgQnVmZmVyKSB7XG4gICAgICAgIHJldHVybiBjaHVuay50b1N0cmluZyhcInV0ZjhcIilcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBjaHVuayAhPSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIFwiVW5leHBlY3RlZCBjaHVuayB0eXBlOiAnXCIgKyB0eXBlb2YgY2h1bmsgKyBcIidcXG5cIiArXG4gICAgICAgICAgICBcIlZhbHVlOiAnXCIgKyBjaHVuayArIFwiJ1wiXG4gICAgICAgIClcbiAgICB9XG4gICAgcmV0dXJuIGNodW5rXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzc2hDaGFubmVsVG9Qcm9taXNlKFxuICAgIGNoYW5uZWw6IENsaWVudENoYW5uZWwsXG4gICAgY21kOiBzdHJpbmcsXG4pOiBTc2hDaGFubmVsVG9Qcm9taXNlIHtcbiAgICByZXR1cm4gKFxuICAgICAgICBvcHRpb25zPzogQ2hhbm5lbFRvUHJvbWlzZU9wdGlvbnNcbiAgICApID0+IHtcbiAgICAgICAgbGV0IHJlc29sdmVkOiBib29sZWFuID0gZmFsc2VcbiAgICAgICAgbGV0IHJlc29sdmVWYWx1ZTogU3NoQ2hhbm5lbEV4aXQgfCBQcm9taXNlTGlrZTxTc2hDaGFubmVsRXhpdD5cblxuICAgICAgICBsZXQgcmVqZWN0ZWQ6IGJvb2xlYW4gPSBmYWxzZVxuICAgICAgICBsZXQgcmVqZWN0UmVhc29uOiBhbnlcblxuICAgICAgICBsZXQgcmVzOiAodmFsdWU6IFNzaENoYW5uZWxFeGl0IHwgUHJvbWlzZUxpa2U8U3NoQ2hhbm5lbEV4aXQ+KSA9PiB2b2lkID0gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBpZiAocmVqZWN0ZWQgfHwgcmVzb2x2ZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc29sdmVkID0gdHJ1ZVxuICAgICAgICAgICAgcmVzb2x2ZVZhbHVlID0gdmFsdWVcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVqOiAocmVhc29uPzogYW55KSA9PiB2b2lkID0gKHJlYXNvbikgPT4ge1xuICAgICAgICAgICAgaWYgKHJlamVjdGVkIHx8IHJlc29sdmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZWplY3RlZCA9IHRydWVcbiAgICAgICAgICAgIHJlamVjdFJlYXNvbiA9IHJlYXNvblxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc2V0dGluZ3M6IENoYW5uZWxUb1Byb21pc2VTZXR0aW5ncyA9IHtcbiAgICAgICAgICAgIC4uLmRlZmF1bHRDaGFubmVsVG9Qcm9taXNlU2V0dGluZ3MsXG4gICAgICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICAgICAgZXhwZWN0ZWRFeGl0Q29kZTogdW5kZWZpbmVkIGFzIGFueSxcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2Ygc2V0dGluZ3MuZXhwZWN0ZWRFeGl0Q29kZSA9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICBzZXR0aW5ncy5leHBlY3RlZEV4aXRDb2RlID0gW3NldHRpbmdzLmV4cGVjdGVkRXhpdENvZGVdXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjaHVua3M6IFtib29sZWFuLCBzdHJpbmddW10gPSBbXVxuICAgICAgICBsZXQgYW55RXJyOiBib29sZWFuID0gZmFsc2VcbiAgICAgICAgbGV0IGFueVN0ZDogYm9vbGVhbiA9IGZhbHNlXG4gICAgICAgIGxldCBzdGRvdXQ6IFJlYWRhYmxlID0gY2hhbm5lbC5zdGRvdXRcbiAgICAgICAgbGV0IHN0ZGVycjogUmVhZGFibGUgPSBjaGFubmVsLnN0ZGVyclxuXG4gICAgICAgIGlmICh0eXBlb2Ygc2V0dGluZ3MgPT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgaWYgKHNldHRpbmdzLmZpbHRlck91dCkge1xuICAgICAgICAgICAgICAgIHNldHRpbmdzLmZpbHRlclN0ZE91dCA9IHNldHRpbmdzLmZpbHRlck91dFxuICAgICAgICAgICAgICAgIHNldHRpbmdzLmZpbHRlckVyck91dCA9IHNldHRpbmdzLmZpbHRlck91dFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHNldHRpbmdzLmZpbHRlck91dE9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBzZXR0aW5ncy5maWx0ZXJTdGRPdXRPcHRpb25zID0gc2V0dGluZ3MuZmlsdGVyT3V0T3B0aW9uc1xuICAgICAgICAgICAgICAgIHNldHRpbmdzLmZpbHRlckVyck91dE9wdGlvbnMgPSBzZXR0aW5ncy5maWx0ZXJPdXRPcHRpb25zXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc2V0dGluZ3MudGhyb3dPbk91dCkge1xuICAgICAgICAgICAgICAgIHNldHRpbmdzLnRocm93T25TdGRPdXQgPSBzZXR0aW5ncy50aHJvd09uT3V0XG4gICAgICAgICAgICAgICAgc2V0dGluZ3MudGhyb3dPbkVyck91dCA9IHNldHRpbmdzLnRocm93T25PdXRcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHNldHRpbmdzLm1hcE91dCkge1xuICAgICAgICAgICAgICAgIHNldHRpbmdzLm1hcFN0ZE91dCA9IHNldHRpbmdzLm1hcE91dFxuICAgICAgICAgICAgICAgIHNldHRpbmdzLm1hcEVyck91dCA9IHNldHRpbmdzLm1hcE91dFxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc2V0dGluZ3MuZmlsdGVyU3RkT3V0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZmlsdGVyU3RkT3V0ID0gc2V0dGluZ3MuZmlsdGVyU3RkT3V0XG4gICAgICAgICAgICAgICAgc3Rkb3V0LmZpbHRlcihcbiAgICAgICAgICAgICAgICAgICAgKGRhdGEsIG9wdGlvbnMpID0+IGZpbHRlclN0ZE91dChcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnNcbiAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgc2V0dGluZ3MuZmlsdGVyU3RkT3V0T3B0aW9uc1xuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzZXR0aW5ncy5maWx0ZXJFcnJPdXQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXJFcnJPdXQgPSBzZXR0aW5ncy5maWx0ZXJFcnJPdXRcbiAgICAgICAgICAgICAgICBzdGRlcnIuZmlsdGVyKFxuICAgICAgICAgICAgICAgICAgICAoZGF0YSwgb3B0aW9ucykgPT4gZmlsdGVyRXJyT3V0KFxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zXG4gICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgIHNldHRpbmdzLmZpbHRlckVyck91dE9wdGlvbnNcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzZXR0aW5ncy5tYXBTdGRPdXQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBtYXBTdGRPdXQgPSBzZXR0aW5ncy5tYXBTdGRPdXRcbiAgICAgICAgICAgICAgICBzdGRvdXQub24oXCJkYXRhXCIsIChjaHVuaykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjaHVuayA9IGNoZWNrRGF0YUNodW5rKGNodW5rKVxuICAgICAgICAgICAgICAgICAgICBjaHVuayA9IG1hcFN0ZE91dChjaHVuaywgZmFsc2UpXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY2h1bmsgPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2h1bmtzLnB1c2goW2ZhbHNlLCBcIlwiICsgY2h1bmtdKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3Rkb3V0Lm9uKFwiZGF0YVwiLCAoY2h1bmspID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY2h1bmsgPSBjaGVja0RhdGFDaHVuayhjaHVuaylcbiAgICAgICAgICAgICAgICAgICAgY2h1bmtzLnB1c2goW2ZhbHNlLCBcIlwiICsgY2h1bmtdKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzZXR0aW5ncy5tYXBFcnJPdXQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBtYXBFcnJPdXQgPSBzZXR0aW5ncy5tYXBFcnJPdXRcbiAgICAgICAgICAgICAgICBzdGRlcnIub24oXCJkYXRhXCIsIChjaHVuaykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjaHVuayA9IGNoZWNrRGF0YUNodW5rKGNodW5rKVxuICAgICAgICAgICAgICAgICAgICBjaHVuayA9IG1hcEVyck91dChjaHVuaywgdHJ1ZSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBjaHVuayA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjaHVua3MucHVzaChbdHJ1ZSwgXCJcIiArIGNodW5rXSlcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHN0ZGVyci5vbihcImRhdGFcIiwgKGNodW5rKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNodW5rID0gY2hlY2tEYXRhQ2h1bmsoY2h1bmspXG4gICAgICAgICAgICAgICAgICAgIGNodW5rcy5wdXNoKFt0cnVlLCBcIlwiICsgY2h1bmtdKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdGRvdXQub24oXCJkYXRhXCIsIChjaHVuaykgPT4ge1xuICAgICAgICAgICAgICAgIGNodW5rID0gY2hlY2tEYXRhQ2h1bmsoY2h1bmspXG4gICAgICAgICAgICAgICAgY2h1bmtzLnB1c2goW2ZhbHNlLCBcIlwiICsgY2h1bmtdKVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgc3RkZXJyLm9uKFwiZGF0YVwiLCAoY2h1bmspID0+IHtcbiAgICAgICAgICAgICAgICBjaHVuayA9IGNoZWNrRGF0YUNodW5rKGNodW5rKVxuICAgICAgICAgICAgICAgIGNodW5rcy5wdXNoKFt0cnVlLCBcIlwiICsgY2h1bmtdKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIHN0ZG91dC5vbihcImRhdGFcIiwgKCkgPT4ge1xuICAgICAgICAgICAgYW55U3RkID0gdHJ1ZVxuICAgICAgICB9KVxuXG4gICAgICAgIHN0ZGVyci5vbihcImRhdGFcIiwgKCkgPT4ge1xuICAgICAgICAgICAgYW55RXJyID0gdHJ1ZVxuICAgICAgICB9KVxuXG4gICAgICAgIGNoYW5uZWwub25jZShcbiAgICAgICAgICAgIFwiZXJyb3JcIixcbiAgICAgICAgICAgIChlcnI6IEVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVqKGVycilcbiAgICAgICAgICAgICAgICBpZiAoIWNoYW5uZWwuY2xvc2VkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWwuY2xvc2UoKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgKVxuXG4gICAgICAgIGNoYW5uZWwub25jZShcbiAgICAgICAgICAgIFwiY2xvc2VcIixcbiAgICAgICAgICAgICguLi5wYXJhbXM6IGFueVtdKSA9PiBjaGFubmVsLmVtaXQoXCJleGl0XCIsIC4uLnBhcmFtcylcbiAgICAgICAgKVxuXG4gICAgICAgIGNoYW5uZWwub25jZShcImV4aXRcIiwgKFxuICAgICAgICAgICAgY29kZTogbnVtYmVyIHwgbnVsbCxcbiAgICAgICAgICAgIHNpZ25hbD86IHN0cmluZyxcbiAgICAgICAgICAgIGR1bXA/OiBzdHJpbmcsXG4gICAgICAgICAgICBkZXNjPzogc3RyaW5nLFxuICAgICAgICApID0+IHtcbiAgICAgICAgICAgIGlmICghY2hhbm5lbC5jbG9zZWQpIHtcbiAgICAgICAgICAgICAgICBjaGFubmVsLmNsb3NlKClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZXhpdDogU3NoQ2hhbm5lbEV4aXQgPSB7XG4gICAgICAgICAgICAgICAgY21kLFxuICAgICAgICAgICAgICAgIGNvZGU6IGNvZGUgPT09IG51bGwgPyAtMSA6IGNvZGUsXG4gICAgICAgICAgICAgICAgc2lnbmFsLFxuICAgICAgICAgICAgICAgIGR1bXAsXG4gICAgICAgICAgICAgICAgZGVzYyxcbiAgICAgICAgICAgICAgICBjaHVua3MsXG4gICAgICAgICAgICAgICAgYW55RXJyLFxuICAgICAgICAgICAgICAgIGFueVN0ZCxcbiAgICAgICAgICAgICAgICBvdXQ6IGNodW5rcy5tYXAoKHYpID0+IHZbMV0pLmpvaW4oXCJcXG5cIilcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKG9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMudGhyb3dPbkVyck91dCAmJlxuICAgICAgICAgICAgICAgICAgICBhbnlFcnJcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqKG5ldyBTc2hDaGFubmVsRXhpdEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJVbmV4cGVjdGVkIGVycm9yIHN0cmVhbSBvdXRwdXQ6XFxuICBcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICBjaHVua3MuZmlsdGVyKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjaHVua3MpID0+IGNodW5rc1swXVxuICAgICAgICAgICAgICAgICAgICAgICAgKS5qb2luKFwiXFxuICBcIiksXG4gICAgICAgICAgICAgICAgICAgICAgICBleGl0XG4gICAgICAgICAgICAgICAgICAgICkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMudGhyb3dPblN0ZE91dCAmJlxuICAgICAgICAgICAgICAgICAgICBhbnlTdGRcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqKG5ldyBTc2hDaGFubmVsRXhpdEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJVbmV4cGVjdGVkIHN0YW5kYXJkIHN0cmVhbSBvdXRwdXQ6XFxuICBcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICBjaHVua3MuZmlsdGVyKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjaHVua3MpID0+ICFjaHVua3NbMF1cbiAgICAgICAgICAgICAgICAgICAgICAgICkuam9pbihcIlxcbiAgXCIpLFxuICAgICAgICAgICAgICAgICAgICAgICAgZXhpdFxuICAgICAgICAgICAgICAgICAgICApKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm5cblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmVzKGV4aXQpXG4gICAgICAgIH0pXG5cblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8U3NoQ2hhbm5lbEV4aXQ+KFxuICAgICAgICAgICAgKHJlczIsIHJlajIpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAocmVzb2x2ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzMihyZXNvbHZlVmFsdWUpXG4gICAgICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVqZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqMihyZWplY3RSZWFzb24pXG4gICAgICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJlcyA9IHJlczJcbiAgICAgICAgICAgICAgICByZWogPSByZWoyXG4gICAgICAgICAgICB9XG4gICAgICAgIClcbiAgICB9XG59Il19