PHP WebShell
Текущая директория: /opt/BitGoJS/modules/utxo-lib/dist/test/integration_local_rpc/generate
Просмотр файла: main.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
const utxolib = require('../../../src');
const src_1 = require("../../../src");
const regtestNode_1 = require("./regtestNode");
const outputScripts_util_1 = require("./outputScripts.util");
const RpcClient_1 = require("./RpcClient");
const fixtures_1 = require("./fixtures");
const outputScripts_1 = require("../../../src/bitgo/outputScripts");
const faucet_1 = require("./faucet");
const bitgo_1 = require("../../../src/bitgo");
function getScriptTypes() {
// FIXME(BG-66941): p2trMusig2 signing does not work in this test suite yet
// because the test suite is written with TransactionBuilder
return outputScripts_util_1.scriptTypes.filter((scriptType) => scriptType);
}
async function printRpcHelp(rpc, network) {
console.log(await rpc.getHelp());
}
async function printNodeHelp(network) {
const { stdout, stderr } = await (0, regtestNode_1.getRegtestNodeHelp)(network);
if (stderr) {
console.error(stderr);
throw new Error(`stderr`);
}
console.log(stdout);
}
async function initBlockchain(rpc, protocol) {
let minBlocks = 300;
switch (protocol.network) {
case utxolib.networks.bitcoingoldTestnet:
// The actual BTC/BTG fork flag only gets activated at this height.
// On mainnet the height was at 491407 (Around 10/25/2017 12:00 UTC)
// Prior to that, signatures that use the BIP143 sighash flag are invalid.
// https://github.com/BTCGPU/BTCGPU/blob/71894be9/src/chainparams.cpp#L371
minBlocks = 2000;
break;
case utxolib.networks.dogecoinTest:
// Mine 1000 blocks to get at least 100 M doge to send
minBlocks = 1000;
break;
case utxolib.networks.zcashTest:
switch (protocol.version) {
case bitgo_1.ZcashTransaction.VERSION4_BRANCH_CANOPY:
minBlocks = 400;
break;
case bitgo_1.ZcashTransaction.VERSION4_BRANCH_NU5:
case bitgo_1.ZcashTransaction.VERSION5_BRANCH_NU5:
minBlocks = 500;
break;
default:
throw new Error(`unexpected protocol version ${protocol.version}`);
}
break;
}
const diff = minBlocks - (await rpc.getBlockCount());
if (diff > 0) {
console.log(`mining ${diff} blocks to reach height ${minBlocks}`);
await (0, faucet_1.generateToFaucet)(rpc, diff);
}
}
function toRegtestAddress(network, scriptType, script) {
if (scriptType === 'p2wsh' || scriptType === 'p2wkh' || scriptType === 'p2tr' || scriptType === 'p2trMusig2') {
switch (network) {
case utxolib.networks.testnet:
network = { bech32: 'bcrt' };
break;
case utxolib.networks.litecoinTest:
network = { bech32: 'rltc' };
break;
case utxolib.networks.bitcoingoldTestnet:
network = { bech32: 'btgrt' };
break;
}
}
return utxolib.address.fromOutputScript(script, network);
}
function getSpendTx(scriptType, inputTxs, script, protocol, amountType, p2trMusig2SpendType) {
if (scriptType === 'p2trMusig2') {
if (!p2trMusig2SpendType) {
throw new Error('Invalid p2tr spend type');
}
const index = (0, outputScripts_util_1.getP2trMusig2Index)(p2trMusig2SpendType);
const signers = p2trMusig2SpendType === 'keyPath' ? ['user', 'bitgo'] : ['user', 'backup'];
const rootWalletKeys = new bitgo_1.RootWalletKeys(fixtures_1.fixtureKeys);
return (0, outputScripts_util_1.createPsbtSpendTransaction)({
rootWalletKeys,
chain: (0, bitgo_1.getInternalChainCode)(scriptType),
index,
signers,
inputTxs,
network: protocol.network,
version: protocol.version,
amountType,
});
}
else {
return (0, outputScripts_util_1.createSpendTransaction)(fixtures_1.fixtureKeys, scriptType, inputTxs, script, protocol.network, protocol.version, amountType);
}
}
async function createTransactionsForScriptType(rpc, scriptType, protocol, p2trMusig2SpendType) {
const fullScriptType = `${scriptType}${p2trMusig2SpendType ? p2trMusig2SpendType : ''}`;
const logTag = `createTransaction ${fullScriptType} ${(0, src_1.getNetworkName)(protocol.network)} v=${protocol.version}`;
if (!(0, outputScripts_util_1.isSupportedDepositType)(protocol.network, scriptType)) {
console.log(logTag + ': not supported, skipping');
return;
}
console.log(logTag);
let keys = fixtures_1.fixtureKeys;
if (scriptType === 'p2trMusig2') {
if (!p2trMusig2SpendType) {
throw new Error('Invalid p2tr spend type');
}
const index = (0, outputScripts_util_1.getP2trMusig2Index)(p2trMusig2SpendType);
const rootWalletKeys = new bitgo_1.RootWalletKeys(fixtures_1.fixtureKeys);
keys = rootWalletKeys.deriveForChainAndIndex((0, bitgo_1.getInternalChainCode)(scriptType), index).triple;
}
const script = (0, outputScripts_util_1.createScriptPubKey)(keys, scriptType, protocol.network);
const address = toRegtestAddress(protocol.network, scriptType, script);
const deposit1Txid = await (0, faucet_1.sendFromFaucet)(rpc, address, 1);
const deposit1Tx = await rpc.getRawTransaction(deposit1Txid);
await (0, fixtures_1.writeTransactionFixtureWithInputs)(rpc, protocol, `deposit_${fullScriptType}.json`, deposit1Txid);
if (!(0, outputScripts_1.isScriptType2Of3)(scriptType) || !(0, outputScripts_1.isSupportedScriptType)(protocol.network, scriptType)) {
console.log(logTag + ': spend not supported, skipping spend');
return;
}
let amount = 1;
switch (protocol.network) {
case utxolib.networks.dogecoinTest:
// Exercise bigint precision with an amount > 100M and also where number would lose precision
amount = 109999998.00000001;
break;
}
const deposit2Txid = await (0, faucet_1.sendFromFaucet)(rpc, address, amount);
const deposit2Tx = await rpc.getRawTransaction(deposit2Txid);
let spendTx;
switch (protocol.network) {
case utxolib.networks.dogecoinTest:
spendTx = getSpendTx(scriptType, [deposit1Tx, deposit2Tx], script, protocol, 'bigint');
break;
default:
spendTx = getSpendTx(scriptType, [deposit1Tx, deposit2Tx], script, protocol, 'number', p2trMusig2SpendType);
break;
}
const spendTxid = await rpc.sendRawTransaction(spendTx.toBuffer());
assert.strictEqual(spendTxid, spendTx.getId());
await (0, fixtures_1.writeTransactionFixtureWithInputs)(rpc, protocol, `spend_${fullScriptType}.json`, spendTxid);
}
async function createTransactions(rpc, protocol) {
for (const scriptType of getScriptTypes()) {
if (scriptType === 'p2trMusig2') {
await createTransactionsForScriptType(rpc, scriptType, protocol, 'keyPath');
await createTransactionsForScriptType(rpc, scriptType, protocol, 'scriptPath');
}
else {
await createTransactionsForScriptType(rpc, scriptType, protocol);
}
}
}
async function withRpcClient(protocol, f) {
await (0, fixtures_1.wipeFixtures)(protocol);
let rpc;
let node;
if (process.env.UTXOLIB_TESTS_USE_DOCKER === '1') {
node = await (0, regtestNode_1.getRegtestNode)(protocol.network);
rpc = await RpcClient_1.RpcClient.forUrlWait(protocol.network, (0, regtestNode_1.getRegtestNodeUrl)(protocol.network));
}
else {
rpc = await RpcClient_1.RpcClient.fromEnvvar(protocol.network);
}
try {
await f(rpc);
}
catch (e) {
console.error(`error for network ${(0, src_1.getNetworkName)(protocol.network)}`);
throw e;
}
finally {
if (node) {
await node.stop();
}
}
}
async function run(protocol) {
await withRpcClient(protocol, async (rpc) => {
if (process.env.UTXOLIB_TESTS_PRINT_RPC_HELP === '1') {
await printRpcHelp(rpc, protocol.network);
}
else {
await initBlockchain(rpc, protocol);
await createTransactions(rpc, protocol);
}
});
}
async function main(args) {
const allowedNetworks = args.map((name) => {
const network = utxolib.networks[name];
if (!network) {
throw new Error(`invalid network ${name}`);
}
return (0, src_1.getMainnet)(network);
});
for (const networkName of Object.keys(utxolib.networks)) {
const network = utxolib.networks[networkName];
if (!(0, src_1.isTestnet)(network)) {
continue;
}
if (allowedNetworks.length && !allowedNetworks.some((n) => n === (0, src_1.getMainnet)(network))) {
console.log(`skipping ${networkName}`);
continue;
}
if (process.env.UTXOLIB_TESTS_PRINT_NODE_HELP === '1') {
await printNodeHelp(network);
continue;
}
for (const version of (0, fixtures_1.getProtocolVersions)(network)) {
await run({ network, version });
}
}
}
if (require.main === module) {
main(process.argv.slice(2)).catch((e) => {
console.error(e);
process.exit(1);
});
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvaW50ZWdyYXRpb25fbG9jYWxfcnBjL2dlbmVyYXRlL21haW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxpQ0FBaUM7QUFFakMsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDO0FBRXhDLHNDQUE4RTtBQUU5RSwrQ0FBNEY7QUFDNUYsNkRBUThCO0FBQzlCLDJDQUF3QztBQUN4Qyx5Q0FNb0I7QUFDcEIsb0VBQTJHO0FBQzNHLHFDQUE0RDtBQUM1RCw4Q0FBNEc7QUFFNUcsU0FBUyxjQUFjO0lBQ3JCLDJFQUEyRTtJQUMzRSw2REFBNkQ7SUFDN0QsT0FBTyxnQ0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDeEQsQ0FBQztBQUVELEtBQUssVUFBVSxZQUFZLENBQUMsR0FBYyxFQUFFLE9BQWdCO0lBQzFELE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztBQUNuQyxDQUFDO0FBRUQsS0FBSyxVQUFVLGFBQWEsQ0FBQyxPQUFnQjtJQUMzQyxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFBQSxnQ0FBa0IsRUFBQyxPQUFPLENBQUMsQ0FBQztJQUM3RCxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN0QixNQUFNLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3RCLENBQUM7QUFFRCxLQUFLLFVBQVUsY0FBYyxDQUFDLEdBQWMsRUFBRSxRQUFrQjtJQUM5RCxJQUFJLFNBQVMsR0FBRyxHQUFHLENBQUM7SUFDcEIsUUFB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ZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmNvbnN0IHV0eG9saWIgPSByZXF1aXJlKCcuLi8uLi8uLi9zcmMnKTtcblxuaW1wb3J0IHsgTmV0d29yaywgZ2V0TWFpbm5ldCwgZ2V0TmV0d29ya05hbWUsIGlzVGVzdG5ldCB9IGZyb20gJy4uLy4uLy4uL3NyYyc7XG5cbmltcG9ydCB7IGdldFJlZ3Rlc3ROb2RlLCBnZXRSZWd0ZXN0Tm9kZVVybCwgTm9kZSwgZ2V0UmVndGVzdE5vZGVIZWxwIH0gZnJvbSAnLi9yZWd0ZXN0Tm9kZSc7XG5pbXBvcnQge1xuICBjcmVhdGVTY3JpcHRQdWJLZXksXG4gIGNyZWF0ZVNwZW5kVHJhbnNhY3Rpb24sXG4gIGNyZWF0ZVBzYnRTcGVuZFRyYW5zYWN0aW9uLFxuICBpc1N1cHBvcnRlZERlcG9zaXRUeXBlLFxuICBTY3JpcHRUeXBlLFxuICBzY3JpcHRUeXBlcyxcbiAgZ2V0UDJ0ck11c2lnMkluZGV4LFxufSBmcm9tICcuL291dHB1dFNjcmlwdHMudXRpbCc7XG5pbXBvcnQgeyBScGNDbGllbnQgfSBmcm9tICcuL1JwY0NsaWVudCc7XG5pbXBvcnQge1xuICBmaXh0dXJlS2V5cyxcbiAgZ2V0UHJvdG9jb2xWZXJzaW9ucyxcbiAgUHJvdG9jb2wsXG4gIHdpcGVGaXh0dXJlcyxcbiAgd3JpdGVUcmFuc2FjdGlvbkZpeHR1cmVXaXRoSW5wdXRzLFxufSBmcm9tICcuL2ZpeHR1cmVzJztcbmltcG9ydCB7IGlzU2NyaXB0VHlwZTJPZjMsIGlzU3VwcG9ydGVkU2NyaXB0VHlwZSwgU2NyaXB0VHlwZTJPZjMgfSBmcm9tICcuLi8uLi8uLi9zcmMvYml0Z28vb3V0cHV0U2NyaXB0cyc7XG5pbXBvcnQgeyBzZW5kRnJvbUZhdWNldCwgZ2VuZXJhdGVUb0ZhdWNldCB9IGZyb20gJy4vZmF1Y2V0JztcbmltcG9ydCB7IGdldEludGVybmFsQ2hhaW5Db2RlLCBLZXlOYW1lLCBSb290V2FsbGV0S2V5cywgVHVwbGUsIFpjYXNoVHJhbnNhY3Rpb24gfSBmcm9tICcuLi8uLi8uLi9zcmMvYml0Z28nO1xuXG5mdW5jdGlvbiBnZXRTY3JpcHRUeXBlcygpIHtcbiAgLy8gRklYTUUoQkctNjY5NDEpOiBwMnRyTXVzaWcyIHNpZ25pbmcgZG9lcyBub3Qgd29yayBpbiB0aGlzIHRlc3Qgc3VpdGUgeWV0XG4gIC8vICBiZWNhdXNlIHRoZSB0ZXN0IHN1aXRlIGlzIHdyaXR0ZW4gd2l0aCBUcmFuc2FjdGlvbkJ1aWxkZXJcbiAgcmV0dXJuIHNjcmlwdFR5cGVzLmZpbHRlcigoc2NyaXB0VHlwZSkgPT4gc2NyaXB0VHlwZSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHByaW50UnBjSGVscChycGM6IFJwY0NsaWVudCwgbmV0d29yazogTmV0d29yayk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zb2xlLmxvZyhhd2FpdCBycGMuZ2V0SGVscCgpKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcHJpbnROb2RlSGVscChuZXR3b3JrOiBOZXR3b3JrKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHsgc3Rkb3V0LCBzdGRlcnIgfSA9IGF3YWl0IGdldFJlZ3Rlc3ROb2RlSGVscChuZXR3b3JrKTtcbiAgaWYgKHN0ZGVycikge1xuICAgIGNvbnNvbGUuZXJyb3Ioc3RkZXJyKTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHN0ZGVycmApO1xuICB9XG4gIGNvbnNvbGUubG9nKHN0ZG91dCk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGluaXRCbG9ja2NoYWluKHJwYzogUnBjQ2xpZW50LCBwcm90b2NvbDogUHJvdG9jb2wpOiBQcm9taXNlPHZvaWQ+IHtcbiAgbGV0IG1pbkJsb2NrcyA9IDMwMDtcbiAgc3dpdGNoIChwcm90b2NvbC5uZXR3b3JrKSB7XG4gICAgY2FzZSB1dHhvbGliLm5ldHdvcmtzLmJpdGNvaW5nb2xkVGVzdG5ldDpcbiAgICAgIC8vIFRoZSBhY3R1YWwgQlRDL0JURyBmb3JrIGZsYWcgb25seSBnZXRzIGFjdGl2YXRlZCBhdCB0aGlzIGhlaWdodC5cbiAgICAgIC8vIE9uIG1haW5uZXQgdGhlIGhlaWdodCB3YXMgYXQgNDkxNDA3IChBcm91bmQgMTAvMjUvMjAxNyAxMjowMCBVVEMpXG4gICAgICAvLyBQcmlvciB0byB0aGF0LCBzaWduYXR1cmVzIHRoYXQgdXNlIHRoZSBCSVAxNDMgc2lnaGFzaCBmbGFnIGFyZSBpbnZhbGlkLlxuICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL0JUQ0dQVS9CVENHUFUvYmxvYi83MTg5NGJlOS9zcmMvY2hhaW5wYXJhbXMuY3BwI0wzNzFcbiAgICAgIG1pbkJsb2NrcyA9IDIwMDA7XG4gICAgICBicmVhaztcbiAgICBjYXNlIHV0eG9saWIubmV0d29ya3MuZG9nZWNvaW5UZXN0OlxuICAgICAgLy8gTWluZSAxMDAwIGJsb2NrcyB0byBnZXQgYXQgbGVhc3QgMTAwIE0gZG9nZSB0byBzZW5kXG4gICAgICBtaW5CbG9ja3MgPSAxMDAwO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSB1dHhvbGliLm5ldHdvcmtzLnpjYXNoVGVzdDpcbiAgICAgIHN3aXRjaCAocHJvdG9jb2wudmVyc2lvbikge1xuICAgICAgICBjYXNlIFpjYXNoVHJhbnNhY3Rpb24uVkVSU0lPTjRfQlJBTkNIX0NBTk9QWTpcbiAgICAgICAgICBtaW5CbG9ja3MgPSA0MDA7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgWmNhc2hUcmFuc2FjdGlvbi5WRVJTSU9ONF9CUkFOQ0hfTlU1OlxuICAgICAgICBjYXNlIFpjYXNoVHJhbnNhY3Rpb24uVkVSU0lPTjVfQlJBTkNIX05VNTpcbiAgICAgICAgICBtaW5CbG9ja3MgPSA1MDA7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bmV4cGVjdGVkIHByb3RvY29sIHZlcnNpb24gJHtwcm90b2NvbC52ZXJzaW9ufWApO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gIH1cblxuICBjb25zdCBkaWZmID0gbWluQmxvY2tzIC0gKGF3YWl0IHJwYy5nZXRCbG9ja0NvdW50KCkpO1xuXG4gIGlmIChkaWZmID4gMCkge1xuICAgIGNvbnNvbGUubG9nKGBtaW5pbmcgJHtkaWZmfSBibG9ja3MgdG8gcmVhY2ggaGVpZ2h0ICR7bWluQmxvY2tzfWApO1xuICAgIGF3YWl0IGdlbmVyYXRlVG9GYXVjZXQocnBjLCBkaWZmKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB0b1JlZ3Rlc3RBZGRyZXNzKG5ldHdvcms6IHsgYmVjaDMyPzogc3RyaW5nIH0sIHNjcmlwdFR5cGU6IFNjcmlwdFR5cGUsIHNjcmlwdDogQnVmZmVyKTogc3RyaW5nIHtcbiAgaWYgKHNjcmlwdFR5cGUgPT09ICdwMndzaCcgfHwgc2NyaXB0VHlwZSA9PT0gJ3Ayd2toJyB8fCBzY3JpcHRUeXBlID09PSAncDJ0cicgfHwgc2NyaXB0VHlwZSA9PT0gJ3AydHJNdXNpZzInKSB7XG4gICAgc3dpdGNoIChuZXR3b3JrKSB7XG4gICAgICBjYXNlIHV0eG9saWIubmV0d29ya3MudGVzdG5ldDpcbiAgICAgICAgbmV0d29yayA9IHsgYmVjaDMyOiAnYmNydCcgfTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIHV0eG9saWIubmV0d29ya3MubGl0ZWNvaW5UZXN0OlxuICAgICAgICBuZXR3b3JrID0geyBiZWNoMzI6ICdybHRjJyB9O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgdXR4b2xpYi5uZXR3b3Jrcy5iaXRjb2luZ29sZFRlc3RuZXQ6XG4gICAgICAgIG5ldHdvcmsgPSB7IGJlY2gzMjogJ2J0Z3J0JyB9O1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHV0eG9saWIuYWRkcmVzcy5mcm9tT3V0cHV0U2NyaXB0KHNjcmlwdCwgbmV0d29yayk7XG59XG5cbmZ1bmN0aW9uIGdldFNwZW5kVHgoXG4gIHNjcmlwdFR5cGU6IFNjcmlwdFR5cGUyT2YzLFxuICBpbnB1dFR4czogQnVmZmVyW10sXG4gIHNjcmlwdCxcbiAgcHJvdG9jb2w6IFByb3RvY29sLFxuICBhbW91bnRUeXBlOiAnbnVtYmVyJyB8ICdiaWdpbnQnLFxuICBwMnRyTXVzaWcyU3BlbmRUeXBlPzogJ2tleVBhdGgnIHwgJ3NjcmlwdFBhdGgnXG4pIHtcbiAgaWYgKHNjcmlwdFR5cGUgPT09ICdwMnRyTXVzaWcyJykge1xuICAgIGlmICghcDJ0ck11c2lnMlNwZW5kVHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHAydHIgc3BlbmQgdHlwZScpO1xuICAgIH1cbiAgICBjb25zdCBpbmRleCA9IGdldFAydHJNdXNpZzJJbmRleChwMnRyTXVzaWcyU3BlbmRUeXBlKTtcbiAgICBjb25zdCBzaWduZXJzOiBUdXBsZTxLZXlOYW1lPiA9IHAydHJNdXNpZzJTcGVuZFR5cGUgPT09ICdrZXlQYXRoJyA/IFsndXNlcicsICdiaXRnbyddIDogWyd1c2VyJywgJ2JhY2t1cCddO1xuICAgIGNvbnN0IHJvb3RXYWxsZXRLZXlzID0gbmV3IFJvb3RXYWxsZXRLZXlzKGZpeHR1cmVLZXlzKTtcbiAgICByZXR1cm4gY3JlYXRlUHNidFNwZW5kVHJhbnNhY3Rpb24oe1xuICAgICAgcm9vdFdhbGxldEtleXMsXG4gICAgICBjaGFpbjogZ2V0SW50ZXJuYWxDaGFpbkNvZGUoc2NyaXB0VHlwZSksXG4gICAgICBpbmRleCxcbiAgICAgIHNpZ25lcnMsXG4gICAgICBpbnB1dFR4cyxcbiAgICAgIG5ldHdvcms6IHByb3RvY29sLm5ldHdvcmssXG4gICAgICB2ZXJzaW9uOiBwcm90b2NvbC52ZXJzaW9uLFxuICAgICAgYW1vdW50VHlwZSxcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gY3JlYXRlU3BlbmRUcmFuc2FjdGlvbihcbiAgICAgIGZpeHR1cmVLZXlzLFxuICAgICAgc2NyaXB0VHlwZSxcbiAgICAgIGlucHV0VHhzLFxuICAgICAgc2NyaXB0LFxuICAgICAgcHJvdG9jb2wubmV0d29yayxcbiAgICAgIHByb3RvY29sLnZlcnNpb24sXG4gICAgICBhbW91bnRUeXBlXG4gICAgKTtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBjcmVhdGVUcmFuc2FjdGlvbnNGb3JTY3JpcHRUeXBlKFxuICBycGM6IFJwY0NsaWVudCxcbiAgc2NyaXB0VHlwZTogU2NyaXB0VHlwZSxcbiAgcHJvdG9jb2w6IFByb3RvY29sLFxuICBwMnRyTXVzaWcyU3BlbmRUeXBlPzogJ2tleVBhdGgnIHwgJ3NjcmlwdFBhdGgnXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgZnVsbFNjcmlwdFR5cGUgPSBgJHtzY3JpcHRUeXBlfSR7cDJ0ck11c2lnMlNwZW5kVHlwZSA/IHAydHJNdXNpZzJTcGVuZFR5cGUgOiAnJ31gO1xuICBjb25zdCBsb2dUYWcgPSBgY3JlYXRlVHJhbnNhY3Rpb24gJHtmdWxsU2NyaXB0VHlwZX0gJHtnZXROZXR3b3JrTmFtZShwcm90b2NvbC5uZXR3b3JrKX0gdj0ke3Byb3RvY29sLnZlcnNpb259YDtcbiAgaWYgKCFpc1N1cHBvcnRlZERlcG9zaXRUeXBlKHByb3RvY29sLm5ldHdvcmssIHNjcmlwdFR5cGUpKSB7XG4gICAgY29uc29sZS5sb2cobG9nVGFnICsgJzogbm90IHN1cHBvcnRlZCwgc2tpcHBpbmcnKTtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc29sZS5sb2cobG9nVGFnKTtcblxuICBsZXQga2V5cyA9IGZpeHR1cmVLZXlzO1xuICBpZiAoc2NyaXB0VHlwZSA9PT0gJ3AydHJNdXNpZzInKSB7XG4gICAgaWYgKCFwMnRyTXVzaWcyU3BlbmRUeXBlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgcDJ0ciBzcGVuZCB0eXBlJyk7XG4gICAgfVxuICAgIGNvbnN0IGluZGV4ID0gZ2V0UDJ0ck11c2lnMkluZGV4KHAydHJNdXNpZzJTcGVuZFR5cGUpO1xuICAgIGNvbnN0IHJvb3RXYWxsZXRLZXlzID0gbmV3IFJvb3RXYWxsZXRLZXlzKGZpeHR1cmVLZXlzKTtcbiAgICBrZXlzID0gcm9vdFdhbGxldEtleXMuZGVyaXZlRm9yQ2hhaW5BbmRJbmRleChnZXRJbnRlcm5hbENoYWluQ29kZShzY3JpcHRUeXBlKSwgaW5kZXgpLnRyaXBsZTtcbiAgfVxuXG4gIGNvbnN0IHNjcmlwdCA9IGNyZWF0ZVNjcmlwdFB1YktleShrZXlzLCBzY3JpcHRUeXBlLCBwcm90b2NvbC5uZXR3b3JrKTtcbiAgY29uc3QgYWRkcmVzcyA9IHRvUmVndGVzdEFkZHJlc3MocHJvdG9jb2wubmV0d29yayBhcyB7IGJlY2gzMjogc3RyaW5nIH0sIHNjcmlwdFR5cGUsIHNjcmlwdCk7XG4gIGNvbnN0IGRlcG9zaXQxVHhpZCA9IGF3YWl0IHNlbmRGcm9tRmF1Y2V0KHJwYywgYWRkcmVzcywgMSk7XG4gIGNvbnN0IGRlcG9zaXQxVHggPSBhd2FpdCBycGMuZ2V0UmF3VHJhbnNhY3Rpb24oZGVwb3NpdDFUeGlkKTtcbiAgYXdhaXQgd3JpdGVUcmFuc2FjdGlvbkZpeHR1cmVXaXRoSW5wdXRzKHJwYywgcHJvdG9jb2wsIGBkZXBvc2l0XyR7ZnVsbFNjcmlwdFR5cGV9Lmpzb25gLCBkZXBvc2l0MVR4aWQpO1xuICBpZiAoIWlzU2NyaXB0VHlwZTJPZjMoc2NyaXB0VHlwZSkgfHwgIWlzU3VwcG9ydGVkU2NyaXB0VHlwZShwcm90b2NvbC5uZXR3b3JrLCBzY3JpcHRUeXBlKSkge1xuICAgIGNvbnNvbGUubG9nKGxvZ1RhZyArICc6IHNwZW5kIG5vdCBzdXBwb3J0ZWQsIHNraXBwaW5nIHNwZW5kJyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgbGV0IGFtb3VudDogbnVtYmVyIHwgc3RyaW5nID0gMTtcbiAgc3dpdGNoIChwcm90b2NvbC5uZXR3b3JrKSB7XG4gICAgY2FzZSB1dHhvbGliLm5ldHdvcmtzLmRvZ2Vjb2luVGVzdDpcbiAgICAgIC8vIEV4ZXJjaXNlIGJpZ2ludCBwcmVjaXNpb24gd2l0aCBhbiBhbW91bnQgPiAxMDBNIGFuZCBhbHNvIHdoZXJlIG51bWJlciB3b3VsZCBsb3NlIHByZWNpc2lvblxuICAgICAgYW1vdW50ID0gMTA5OTk5OTk4LjAwMDAwMDAxO1xuICAgICAgYnJlYWs7XG4gIH1cbiAgY29uc3QgZGVwb3NpdDJUeGlkID0gYXdhaXQgc2VuZEZyb21GYXVjZXQocnBjLCBhZGRyZXNzLCBhbW91bnQpO1xuICBjb25zdCBkZXBvc2l0MlR4ID0gYXdhaXQgcnBjLmdldFJhd1RyYW5zYWN0aW9uKGRlcG9zaXQyVHhpZCk7XG4gIGxldCBzcGVuZFR4O1xuICBzd2l0Y2ggKHByb3RvY29sLm5ldHdvcmspIHtcbiAgICBjYXNlIHV0eG9saWIubmV0d29ya3MuZG9nZWNvaW5UZXN0OlxuICAgICAgc3BlbmRUeCA9IGdldFNwZW5kVHgoc2NyaXB0VHlwZSwgW2RlcG9zaXQxVHgsIGRlcG9zaXQyVHhdLCBzY3JpcHQsIHByb3RvY29sLCAnYmlnaW50Jyk7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgc3BlbmRUeCA9IGdldFNwZW5kVHgoc2NyaXB0VHlwZSwgW2RlcG9zaXQxVHgsIGRlcG9zaXQyVHhdLCBzY3JpcHQsIHByb3RvY29sLCAnbnVtYmVyJywgcDJ0ck11c2lnMlNwZW5kVHlwZSk7XG4gICAgICBicmVhaztcbiAgfVxuICBjb25zdCBzcGVuZFR4aWQgPSBhd2FpdCBycGMuc2VuZFJhd1RyYW5zYWN0aW9uKHNwZW5kVHgudG9CdWZmZXIoKSk7XG4gIGFzc2VydC5zdHJpY3RFcXVhbChzcGVuZFR4aWQsIHNwZW5kVHguZ2V0SWQoKSk7XG4gIGF3YWl0IHdyaXRlVHJhbnNhY3Rpb25GaXh0dXJlV2l0aElucHV0cyhycGMsIHByb3RvY29sLCBgc3BlbmRfJHtmdWxsU2NyaXB0VHlwZX0uanNvbmAsIHNwZW5kVHhpZCk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVRyYW5zYWN0aW9ucyhycGM6IFJwY0NsaWVudCwgcHJvdG9jb2w6IFByb3RvY29sKSB7XG4gIGZvciAoY29uc3Qgc2NyaXB0VHlwZSBvZiBnZXRTY3JpcHRUeXBlcygpKSB7XG4gICAgaWYgKHNjcmlwdFR5cGUgPT09ICdwMnRyTXVzaWcyJykge1xuICAgICAgYXdhaXQgY3JlYXRlVHJhbnNhY3Rpb25zRm9yU2NyaXB0VHlwZShycGMsIHNjcmlwdFR5cGUsIHByb3RvY29sLCAna2V5UGF0aCcpO1xuICAgICAgYXdhaXQgY3JlYXRlVHJhbnNhY3Rpb25zRm9yU2NyaXB0VHlwZShycGMsIHNjcmlwdFR5cGUsIHByb3RvY29sLCAnc2NyaXB0UGF0aCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhd2FpdCBjcmVhdGVUcmFuc2FjdGlvbnNGb3JTY3JpcHRUeXBlKHJwYywgc2NyaXB0VHlwZSwgcHJvdG9jb2wpO1xuICAgIH1cbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiB3aXRoUnBjQ2xpZW50KHByb3RvY29sOiBQcm90b2NvbCwgZjogKGM6IFJwY0NsaWVudCkgPT4gUHJvbWlzZTx2b2lkPik6IFByb21pc2U8dm9pZD4ge1xuICBhd2FpdCB3aXBlRml4dHVyZXMocHJvdG9jb2wpO1xuXG4gIGxldCBycGM7XG4gIGxldCBub2RlOiBOb2RlIHwgdW5kZWZpbmVkO1xuICBpZiAocHJvY2Vzcy5lbnYuVVRYT0xJQl9URVNUU19VU0VfRE9DS0VSID09PSAnMScpIHtcbiAgICBub2RlID0gYXdhaXQgZ2V0UmVndGVzdE5vZGUocHJvdG9jb2wubmV0d29yayk7XG4gICAgcnBjID0gYXdhaXQgUnBjQ2xpZW50LmZvclVybFdhaXQocHJvdG9jb2wubmV0d29yaywgZ2V0UmVndGVzdE5vZGVVcmwocHJvdG9jb2wubmV0d29yaykpO1xuICB9IGVsc2Uge1xuICAgIHJwYyA9IGF3YWl0IFJwY0NsaWVudC5mcm9tRW52dmFyKHByb3RvY29sLm5ldHdvcmspO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBhd2FpdCBmKHJwYyk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zb2xlLmVycm9yKGBlcnJvciBmb3IgbmV0d29yayAke2dldE5ldHdvcmtOYW1lKHByb3RvY29sLm5ldHdvcmspfWApO1xuICAgIHRocm93IGU7XG4gIH0gZmluYWxseSB7XG4gICAgaWYgKG5vZGUpIHtcbiAgICAgIGF3YWl0IG5vZGUuc3RvcCgpO1xuICAgIH1cbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBydW4ocHJvdG9jb2w6IFByb3RvY29sKSB7XG4gIGF3YWl0IHdpdGhScGNDbGllbnQocHJvdG9jb2wsIGFzeW5jIChycGMpID0+IHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuVVRYT0xJQl9URVNUU19QUklOVF9SUENfSEVMUCA9PT0gJzEnKSB7XG4gICAgICBhd2FpdCBwcmludFJwY0hlbHAocnBjLCBwcm90b2NvbC5uZXR3b3JrKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXdhaXQgaW5pdEJsb2NrY2hhaW4ocnBjLCBwcm90b2NvbCk7XG4gICAgICBhd2FpdCBjcmVhdGVUcmFuc2FjdGlvbnMocnBjLCBwcm90b2NvbCk7XG4gICAgfVxuICB9KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gbWFpbihhcmdzOiBzdHJpbmdbXSkge1xuICBjb25zdCBhbGxvd2VkTmV0d29ya3MgPSBhcmdzLm1hcCgobmFtZSkgPT4ge1xuICAgIGNvbnN0IG5ldHdvcmsgPSB1dHhvbGliLm5ldHdvcmtzW25hbWVdO1xuICAgIGlmICghbmV0d29yaykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIG5ldHdvcmsgJHtuYW1lfWApO1xuICAgIH1cbiAgICByZXR1cm4gZ2V0TWFpbm5ldChuZXR3b3JrKTtcbiAgfSk7XG5cbiAgZm9yIChjb25zdCBuZXR3b3JrTmFtZSBvZiBPYmplY3Qua2V5cyh1dHhvbGliLm5ldHdvcmtzKSkge1xuICAgIGNvbnN0IG5ldHdvcms6IE5ldHdvcmsgPSB1dHhvbGliLm5ldHdvcmtzW25ldHdvcmtOYW1lXTtcbiAgICBpZiAoIWlzVGVzdG5ldChuZXR3b3JrKSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKGFsbG93ZWROZXR3b3Jrcy5sZW5ndGggJiYgIWFsbG93ZWROZXR3b3Jrcy5zb21lKChuKSA9PiBuID09PSBnZXRNYWlubmV0KG5ldHdvcmspKSkge1xuICAgICAgY29uc29sZS5sb2coYHNraXBwaW5nICR7bmV0d29ya05hbWV9YCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAocHJvY2Vzcy5lbnYuVVRYT0xJQl9URVNUU19QUklOVF9OT0RFX0hFTFAgPT09ICcxJykge1xuICAgICAgYXdhaXQgcHJpbnROb2RlSGVscChuZXR3b3JrKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgdmVyc2lvbiBvZiBnZXRQcm90b2NvbFZlcnNpb25zKG5ldHdvcmspKSB7XG4gICAgICBhd2FpdCBydW4oeyBuZXR3b3JrLCB2ZXJzaW9uIH0pO1xuICAgIH1cbiAgfVxufVxuXG5pZiAocmVxdWlyZS5tYWluID09PSBtb2R1bGUpIHtcbiAgbWFpbihwcm9jZXNzLmFyZ3Yuc2xpY2UoMikpLmNhdGNoKChlKSA9PiB7XG4gICAgY29uc29sZS5lcnJvcihlKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH0pO1xufVxuIl19Выполнить команду
Для локальной разработки. Не используйте в интернете!