PHP WebShell

Текущая директория: /opt/BitGoJS/modules/sdk-coin-etc/dist/test/unit

Просмотр файла: etc.js

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const sdk_test_1 = require("@bitgo/sdk-test");
const sdk_api_1 = require("@bitgo/sdk-api");
const src_1 = require("../../src");
const sinon_1 = __importDefault(require("sinon"));
const ethereumjs_util_1 = require("ethereumjs-util");
const getBuilder_1 = require("./getBuilder");
const should = __importStar(require("should"));
describe('Ethereum Classic', function () {
    let bitgo;
    before(function () {
        bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
        bitgo.initializeTestVars();
        bitgo.safeRegister('etc', src_1.Etc.createInstance);
        bitgo.safeRegister('tetc', src_1.Tetc.createInstance);
    });
    it('should instantiate the coin', function () {
        let localBasecoin = bitgo.coin('tetc');
        localBasecoin.should.be.an.instanceof(src_1.Tetc);
        localBasecoin = bitgo.coin('etc');
        localBasecoin.should.be.an.instanceof(src_1.Etc);
    });
});
describe('Wallet Recovery Wizard', function () {
    let sandbox;
    let bitgo;
    let tetcCoin;
    const sourceRootAddress = '0x321cbe223ff1c3d0c03b73b8c648ef2d91e4aaa1';
    const backupKeyAddress = '0x921f162bfd472424d6065b919c3f6e3bf13fe3d7';
    const destinationWalletAddress = '0x76e2dcc49618f3b9769fc8a80b6991388570b3ae';
    const walletPassPhrase = 'Z@oOQ6fkpzjkJXxM<bN1';
    beforeEach(function () {
        sandbox = sinon_1.default.createSandbox();
        const callBack = sandbox.stub(src_1.Etc.prototype, 'queryAddressBalance');
        callBack.withArgs(sourceRootAddress).resolves(new ethereumjs_util_1.BN('2190000000000000000'));
        callBack.withArgs(backupKeyAddress).resolves(new ethereumjs_util_1.BN('190000000000000000'));
        callBack.withArgs('0x5273e0d869226ccf579a81b6d291fb3702ba9dec').resolves(new ethereumjs_util_1.BN('0'));
        callBack.withArgs('0x1b9af47cc3048fe1d31ad72299611d3df3926755').resolves(new ethereumjs_util_1.BN('190000000000000000'));
        callBack.withArgs('0x7fcf95a9106a0ed3bd09e653c8ea3d5e489bfb23').resolves(new ethereumjs_util_1.BN('2190000000000000000'));
    });
    afterEach(function () {
        sandbox.restore();
    });
    before(function () {
        bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
        bitgo.safeRegister('tetc', src_1.Tetc.createInstance);
        bitgo.initializeTestVars();
    });
    describe('Non-BitGo Recovery', function () {
        beforeEach(function () {
            tetcCoin = bitgo.coin('tetc');
        });
        it('should build a recovery transaction for non-bitgo recovery', async function () {
            const walletContractAddress = sourceRootAddress;
            const recovery = (await tetcCoin.recover({
                userKey: '{"iv":"rP+aJBBP5VkYiGmc0KPz4A==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"/B4OU/PQ1Eg=","ct":"HvCzOA23n6WxgFcBdH3ZqrLnZl5NckPPUyC/UDSv/KO8ZPBb1xZVTTY2ZY6/JBG8dHp/ApvAlRFm1SC+MjZ/OF9LC6Zjz8vsoLiS0BHB+z8Z6qB/16aWJbEIRzEmgEkWRn10l9m646GS00qGNHKG1VBURvUOYN4="}',
                backupKey: '{"iv":"rDHtZUUKxaCQaIzGMB0b0w==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"0bmqSuxoVlA=","ct":"LyKRuUNVcRzhY5LUF15jKdKOpP04nUHs88FYPK1ZB9yuBSEGduQPjJs+xO62NCDh3pyiX1YeHBe9N6Gsm5Va0jSCk8XQ5pCwNuiO1RXvESAhfrXCivJMfRLVmCgaM79YMWapL7syUa//6mhu/1l4tPBBoZoBYc8="}',
                walletContractAddress,
                walletPassphrase: walletPassPhrase,
                recoveryDestination: destinationWalletAddress,
            }));
            recovery.should.not.be.undefined();
            recovery.should.have.property('id');
            recovery.should.have.property('tx');
            const txBuilder = (0, getBuilder_1.getBuilder)('tetc');
            txBuilder.from(recovery.tx);
            const tx = await txBuilder.build();
            tx.toBroadcastFormat().should.not.be.empty();
        });
        it('should error when the backup key is unfunded (cannot pay gas)', async function () {
            await tetcCoin
                .recover({
                userKey: '{"iv":"RI3d7nXJnnMTJFEKE5U6CA==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"qZtZ8FXlr5I=","ct":"F49E7Pi3duSQ9v1iauXuQ6q6SqmGHLPQ9RNJTmfJp0AH2mwNe1bl/pMpwsaT12Ay3x3roLsi5+WFzePK8q1z43xwKfMWjTdsxj0yHpwa+8kOyckEnKyZ5J/AUw0nS7ujegTelaKR/wT2D+mvpJejQ+NRs9Lvyrg="}\n',
                backupKey: '{"iv":"XJPzySPeTTAbLVol9fsQUA==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"6LzbWSvK9Wo=","ct":"8fBnXkAX38ZtoHjN9MBUSkJ3dGgR8FuAmOo1sO7XfOu6Pan23YVpy468dKgl0C+UkzBQbnepNQ0UOf3kEudTYqt3/HgtvUcDdkkD3YDfEF1gVN7ndiBabF2C3SwnMNxUkuD0n5YWaRmaBPo+A2AGj4VrQ0wzFZs="}',
                walletContractAddress: destinationWalletAddress,
                walletPassphrase: walletPassPhrase,
                recoveryDestination: sourceRootAddress,
            })
                .should.be.rejectedWith('Backup key address 0x5273e0d869226ccf579a81b6d291fb3702ba9dec has balance  0 Gwei.This address must have a balance of at least 10000000 Gwei to perform recoveries. Try sending some funds to this address then retry.');
        });
        it('should get the next sequence id for an address', async function () {
            const baseCoin = bitgo.coin('tetc');
            const walletContractAddress = '0x2E0b5638Bf3F774AF116029b09415AA9FDD812d5';
            const sequenceId = await baseCoin.querySequenceId(walletContractAddress);
            sequenceId.should.not.be.undefined();
        });
    });
    describe('Unsigned sweep for cold wallet', function () {
        const userXprv = 'xprv9s21ZrQH143K38Cfd5PyKGajVbA1sZYwAKQif8qvJMfMmSY85spqTnd4taexRHc9F92QCgBzHosCauYcnJWT9eWxfFKvSjAKoSgQkf74DoM';
        const userXpub = 'xpub661MyMwAqRbcFcH8j6vygQXU3czWH2GnXYLKTXFXrhCLeEsGdR961awYjr3yC8eUj9rqhgFWHVbQJWqZS7kXpLBDzvoCKDLaBujsCH12Zfj';
        const backupXprv = 'xprv9s21ZrQH143K3WkGc7rUw4NU5ZZTPczbMk9GajGxpJYhJXtfnYUL4j1x6vAGcxUg9XFzEHpQWPy3aYyJZcuGnYbc2eNzrsyNn3SRNdQa1PC';
        const backupXpub = 'xpub661MyMwAqRbcGYaF52itktGhGDfiL9CBBTh4TSXV6QqGgXRbhSS5DAaTbdCPJA425XwkvwyCKtTmoxcUTAUgKUf7Qr5Ks9gJP9DTfiV2PhU';
        const walletContractAddress = '0x7fcf95a9106a0ed3bd09e653c8ea3d5e489bfb23';
        // tetc wallet 1 receiveAddress 4
        const recoveryDestination = '0x321cbe223ff1c3d0c03b73b8c648ef2d91e4aaa1';
        const gasPrice = 25000000000;
        beforeEach(function () {
            tetcCoin = bitgo.coin('tetc');
        });
        afterEach(function () {
            sandbox.restore();
        });
        it('should generate an ETH unsigned sweep', async function () {
            const transaction = (await tetcCoin.recover({
                userKey: userXpub,
                backupKey: backupXpub,
                walletContractAddress,
                recoveryDestination,
                gasPrice,
            }));
            should.exist(transaction);
            transaction.should.have.property('txHex');
            transaction.should.have.property('userKey');
            transaction.should.have.property('backupKey');
            transaction.should.have.property('gasLimit');
            transaction.gasLimit.should.equal('500000');
            transaction.should.have.property('gasPrice');
            transaction.gasPrice.should.equal('25000000000');
            transaction.should.have.property('walletContractAddress');
            transaction.walletContractAddress.should.equal('0x7fcf95a9106a0ed3bd09e653c8ea3d5e489bfb23');
            transaction.should.have.property('recipient');
        });
        it('should add a second signature', async function () {
            const transaction = (await tetcCoin.recover({
                userKey: userXpub,
                backupKey: backupXpub,
                walletContractAddress,
                recoveryDestination,
                gasPrice,
            }));
            const txPrebuild = {
                txHex: transaction.txHex,
            };
            const params = {
                txPrebuild,
                prv: userXprv,
            };
            // sign transaction once
            const halfSigned = await tetcCoin.signTransaction(params);
            const halfSignedParams = {
                txPrebuild: halfSigned,
                isLastSignature: true,
                walletContractAddress: walletContractAddress,
                prv: backupXprv,
            };
            // sign transaction twice with the "isLastSignature" flag
            const finalSignedTx = (await tetcCoin.signTransaction(halfSignedParams));
            finalSignedTx.should.have.property('txHex');
            const txBuilder = tetcCoin.getTransactionBuilder();
            txBuilder.from(finalSignedTx.txHex);
            const rebuiltTx = await txBuilder.build();
            rebuiltTx.signature.length.should.equal(2);
            rebuiltTx.outputs.length.should.equal(1);
        });
    });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXRjLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L2V0Yy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDhDQUEwRDtBQUMxRCw0Q0FBMEM7QUFDMUMsbUNBQTBEO0FBQzFELGtEQUEwQjtBQUcxQixxREFBcUM7QUFDckMsNkNBQTBDO0FBRTFDLCtDQUFpQztBQUVqQyxRQUFRLENBQUMsa0JBQWtCLEVBQUU7SUFDM0IsSUFBSSxLQUFtQixDQUFDO0lBRXhCLE1BQU0sQ0FBQztRQUNMLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxrQkFBUSxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDdEQsS0FBSyxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDM0IsS0FBSyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsU0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQzlDLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLFVBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUNsRCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyw2QkFBNkIsRUFBRTtRQUNoQyxJQUFJLGFBQWEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3ZDLGFBQWEsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsVUFBSSxDQUFDLENBQUM7UUFFNUMsYUFBYSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbEMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxTQUFHLENBQUMsQ0FBQztJQUM3QyxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDO0FBRUgsUUFBUSxDQUFDLHdCQUF3QixF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QyxLQUFLLENBQUMsQ0FBQztZQUNwQyxNQUFNLFNBQVMsR0FBRyxNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUMxQyxTQUFTLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzNDLFNBQVMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0MsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVGVzdEJpdEdvLCBUZXN0Qml0R29BUEkgfSBmcm9tICdAYml0Z28vc2RrLXRlc3QnO1xuaW1wb3J0IHsgQml0R29BUEkgfSBmcm9tICdAYml0Z28vc2RrLWFwaSc7XG5pbXBvcnQgeyBFdGMsIFRldGMsIFRyYW5zYWN0aW9uQnVpbGRlciB9IGZyb20gJy4uLy4uL3NyYyc7XG5pbXBvcnQgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0IHsgT2ZmbGluZVZhdWx0VHhJbmZvLCBTaWduVHJhbnNhY3Rpb25PcHRpb25zIH0gZnJvbSAnQGJpdGdvL2Fic3RyYWN0LWV0aCc7XG5cbmltcG9ydCB7IEJOIH0gZnJvbSAnZXRoZXJldW1qcy11dGlsJztcbmltcG9ydCB7IGdldEJ1aWxkZXIgfSBmcm9tICcuL2dldEJ1aWxkZXInO1xuaW1wb3J0IHsgRnVsbHlTaWduZWRUcmFuc2FjdGlvbiB9IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgKiBhcyBzaG91bGQgZnJvbSAnc2hvdWxkJztcblxuZGVzY3JpYmUoJ0V0aGVyZXVtIENsYXNzaWMnLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuXG4gIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52OiAnbW9jaycgfSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCdldGMnLCBFdGMuY3JlYXRlSW5zdGFuY2UpO1xuICAgIGJpdGdvLnNhZmVSZWdpc3RlcigndGV0YycsIFRldGMuY3JlYXRlSW5zdGFuY2UpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGluc3RhbnRpYXRlIHRoZSBjb2luJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBsb2NhbEJhc2Vjb2luID0gYml0Z28uY29pbigndGV0YycpO1xuICAgIGxvY2FsQmFzZWNvaW4uc2hvdWxkLmJlLmFuLmluc3RhbmNlb2YoVGV0Yyk7XG5cbiAgICBsb2NhbEJhc2Vjb2luID0gYml0Z28uY29pbignZXRjJyk7XG4gICAgbG9jYWxCYXNlY29pbi5zaG91bGQuYmUuYW4uaW5zdGFuY2VvZihFdGMpO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnV2FsbGV0IFJlY292ZXJ5IFdpemFyZCcsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IHNhbmRib3g7XG4gIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuICBsZXQgdGV0Y0NvaW46IFRldGM7XG5cbiAgY29uc3Qgc291cmNlUm9vdEFkZHJlc3MgPSAnMHgzMjFjYmUyMjNmZjFjM2QwYzAzYjczYjhjNjQ4ZWYyZDkxZTRhYWExJztcbiAgY29uc3QgYmFja3VwS2V5QWRkcmVzcyA9ICcweDkyMWYxNjJiZmQ0NzI0MjRkNjA2NWI5MTljM2Y2ZTNiZjEzZmUzZDcnO1xuICBjb25zdCBkZXN0aW5hdGlvbldhbGxldEFkZHJlc3MgPSAnMHg3NmUyZGNjNDk2MThmM2I5NzY5ZmM4YTgwYjY5OTEzODg1NzBiM2FlJztcbiAgY29uc3Qgd2FsbGV0UGFzc1BocmFzZSA9ICdaQG9PUTZma3B6amtKWHhNPGJOMSc7XG5cbiAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICBjb25zdCBjYWxsQmFjayA9IHNhbmRib3guc3R1YihFdGMucHJvdG90eXBlLCAncXVlcnlBZGRyZXNzQmFsYW5jZScgYXMga2V5b2YgRXRjKTtcbiAgICBjYWxsQmFjay53aXRoQXJncyhzb3VyY2VSb290QWRkcmVzcykucmVzb2x2ZXMobmV3IEJOKCcyMTkwMDAwMDAwMDAwMDAwMDAwJykpO1xuICAgIGNhbGxCYWNrLndpdGhBcmdzKGJhY2t1cEtleUFkZHJlc3MpLnJlc29sdmVzKG5ldyBCTignMTkwMDAwMDAwMDAwMDAwMDAwJykpO1xuICAgIGNhbGxCYWNrLndpdGhBcmdzKCcweDUyNzNlMGQ4NjkyMjZjY2Y1NzlhODFiNmQyOTFmYjM3MDJiYTlkZWMnKS5yZXNvbHZlcyhuZXcgQk4oJzAnKSk7XG4gICAgY2FsbEJhY2sud2l0aEFyZ3MoJzB4MWI5YWY0N2NjMzA0OGZlMWQzMWFkNzIyOTk2MTFkM2RmMzkyNjc1NScpLnJlc29sdmVzKG5ldyBCTignMTkwMDAwMDAwMDAwMDAwMDAwJykpO1xuICAgIGNhbGxCYWNrLndpdGhBcmdzKCcweDdmY2Y5NWE5MTA2YTBlZDNiZDA5ZTY1M2M4ZWEzZDVlNDg5YmZiMjMnKS5yZXNvbHZlcyhuZXcgQk4oJzIxOTAwMDAwMDAwMDAwMDAwMDAnKSk7XG4gIH0pO1xuXG4gIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgc2FuZGJveC5yZXN0b3JlKCk7XG4gIH0pO1xuXG4gIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52OiAndGVzdCcgfSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0ZXRjJywgVGV0Yy5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdOb24tQml0R28gUmVjb3ZlcnknLCBmdW5jdGlvbiAoKSB7XG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB0ZXRjQ29pbiA9IGJpdGdvLmNvaW4oJ3RldGMnKSBhcyBUZXRjO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBidWlsZCBhIHJlY292ZXJ5IHRyYW5zYWN0aW9uIGZvciBub24tYml0Z28gcmVjb3ZlcnknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRDb250cmFjdEFkZHJlc3MgPSBzb3VyY2VSb290QWRkcmVzcztcbiAgICAgIGNvbnN0IHJlY292ZXJ5ID0gKGF3YWl0IHRldGNDb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OlxuICAgICAgICAgICd7XCJpdlwiOlwiclArYUpCQlA1VmtZaUdtYzBLUHo0QT09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIi9CNE9VL1BRMUVnPVwiLFwiY3RcIjpcIkh2Q3pPQTIzbjZXeGdGY0JkSDNacXJMblpsNU5ja1BQVXlDL1VEU3YvS084WlBCYjF4WlZUVFkyWlk2L0pCRzhkSHAvQXB2QWxSRm0xU0MrTWpaL09GOUxDNlpqejh2c29MaVMwQkhCK3o4WjZxQi8xNmFXSmJFSVJ6RW1nRWtXUm4xMGw5bTY0NkdTMDBxR05IS0cxVkJVUnZVT1lOND1cIn0nLFxuICAgICAgICBiYWNrdXBLZXk6XG4gICAgICAgICAgJ3tcIml2XCI6XCJyREh0WlVVS3hhQ1FhSXpHTUIwYjB3PT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiMGJtcVN1eG9WbEE9XCIsXCJjdFwiOlwiTHlLUnVVTlZjUnpoWTVMVUYxNWpLZEtPcFAwNG5VSHM4OEZZUEsxWkI5eXVCU0VHZHVRUGpKcyt4TzYyTkNEaDNweWlYMVllSEJlOU42R3NtNVZhMGpTQ2s4WFE1cEN3TnVpTzFSWHZFU0FoZnJYQ2l2Sk1mUkxWbUNnYU03OVlNV2FwTDdzeVVhLy82bWh1LzFsNHRQQkJvWm9CWWM4PVwifScsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogd2FsbGV0UGFzc1BocmFzZSxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogZGVzdGluYXRpb25XYWxsZXRBZGRyZXNzLFxuICAgICAgfSkpIGFzIE9mZmxpbmVWYXVsdFR4SW5mbztcblxuICAgICAgcmVjb3Zlcnkuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdpZCcpO1xuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4Jyk7XG5cbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIoJ3RldGMnKSBhcyBUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgICB0eEJ1aWxkZXIuZnJvbShyZWNvdmVyeS50eCk7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgdHgudG9Ccm9hZGNhc3RGb3JtYXQoKS5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGVycm9yIHdoZW4gdGhlIGJhY2t1cCBrZXkgaXMgdW5mdW5kZWQgKGNhbm5vdCBwYXkgZ2FzKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IHRldGNDb2luXG4gICAgICAgIC5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5OlxuICAgICAgICAgICAgJ3tcIml2XCI6XCJSSTNkN25YSm5uTVRKRkVLRTVVNkNBPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwicVp0WjhGWGxyNUk9XCIsXCJjdFwiOlwiRjQ5RTdQaTNkdVNROXYxaWF1WHVRNnE2U3FtR0hMUFE5Uk5KVG1mSnAwQUgybXdOZTFibC9wTXB3c2FUMTJBeTN4M3JvTHNpNStXRnplUEs4cTF6NDN4d0tmTVdqVGRzeGoweUhwd2ErOGtPeWNrRW5LeVo1Si9BVXcwblM3dWplZ1RlbGFLUi93VDJEK212cEplalErTlJzOUx2eXJnPVwifVxcbicsXG4gICAgICAgICAgYmFja3VwS2V5OlxuICAgICAgICAgICAgJ3tcIml2XCI6XCJYSlB6eVNQZVRUQWJMVm9sOWZzUVVBPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiNkx6YldTdks5V289XCIsXCJjdFwiOlwiOGZCblhrQVgzOFp0b0hqTjlNQlVTa0ozZEdnUjhGdUFtT28xc083WGZPdTZQYW4yM1lWcHk0NjhkS2dsMEMrVWt6QlFibmVwTlEwVU9mM2tFdWRUWXF0My9IZ3R2VWNEZGtrRDNZRGZFRjFnVk43bmRpQmFiRjJDM1N3bk1OeFVrdUQwbjVZV2FSbWFCUG8rQTJBR2o0VnJRMHd6RlpzPVwifScsXG4gICAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiBkZXN0aW5hdGlvbldhbGxldEFkZHJlc3MsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogd2FsbGV0UGFzc1BocmFzZSxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBzb3VyY2VSb290QWRkcmVzcyxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ0JhY2t1cCBrZXkgYWRkcmVzcyAweDUyNzNlMGQ4NjkyMjZjY2Y1NzlhODFiNmQyOTFmYjM3MDJiYTlkZWMgaGFzIGJhbGFuY2UgIDAgR3dlaS5UaGlzIGFkZHJlc3MgbXVzdCBoYXZlIGEgYmFsYW5jZSBvZiBhdCBsZWFzdCAxMDAwMDAwMCBHd2VpIHRvIHBlcmZvcm0gcmVjb3Zlcmllcy4gVHJ5IHNlbmRpbmcgc29tZSBmdW5kcyB0byB0aGlzIGFkZHJlc3MgdGhlbiByZXRyeS4nXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdldCB0aGUgbmV4dCBzZXF1ZW5jZSBpZCBmb3IgYW4gYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJhc2VDb2luID0gYml0Z28uY29pbigndGV0YycpIGFzIFRldGM7XG4gICAgICBjb25zdCB3YWxsZXRDb250cmFjdEFkZHJlc3MgPSAnMHgyRTBiNTYzOEJmM0Y3NzRBRjExNjAyOWIwOTQxNUFBOUZERDgxMmQ1JztcbiAgICAgIGNvbnN0IHNlcXVlbmNlSWQgPSBhd2FpdCBiYXNlQ29pbi5xdWVyeVNlcXVlbmNlSWQod2FsbGV0Q29udHJhY3RBZGRyZXNzKTtcbiAgICAgIHNlcXVlbmNlSWQuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1Vuc2lnbmVkIHN3ZWVwIGZvciBjb2xkIHdhbGxldCcsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCB1c2VyWHBydiA9XG4gICAgICAneHBydjlzMjFaclFIMTQzSzM4Q2ZkNVB5S0dhalZiQTFzWll3QUtRaWY4cXZKTWZNbVNZODVzcHFUbmQ0dGFleFJIYzlGOTJRQ2dCekhvc0NhdVljbkpXVDllV3hmRkt2U2pBS29TZ1FrZjc0RG9NJztcbiAgICBjb25zdCB1c2VyWHB1YiA9XG4gICAgICAneHB1YjY2MU15TXdBcVJiY0ZjSDhqNnZ5Z1FYVTNjeldIMkduWFlMS1RYRlhyaENMZUVzR2RSOTYxYXdZanIzeUM4ZVVqOXJxaGdGV0hWYlFKV3FaUzdrWHBMQkR6dm9DS0RMYUJ1anNDSDEyWmZqJztcbiAgICBjb25zdCBiYWNrdXBYcHJ2ID1cbiAgICAgICd4cHJ2OXMyMVpyUUgxNDNLM1drR2M3clV3NE5VNVpaVFBjemJNazlHYWpHeHBKWWhKWHRmbllVTDRqMXg2dkFHY3hVZzlYRnpFSHBRV1B5M2FZeUpaY3VHblliYzJlTnpyc3lObjNTUk5kUWExUEMnO1xuICAgIGNvbnN0IGJhY2t1cFhwdWIgPVxuICAgICAgJ3hwdWI2NjFNeU13QXFSYmNHWWFGNTJpdGt0R2hHRGZpTDlDQkJUaDRUU1hWNlFxR2dYUmJoU1M1REFhVGJkQ1BKQTQyNVh3a3Z3eUNLdFRtb3hjVVRBVWdLVWY3UXI1S3M5Z0pQOURUZmlWMlBoVSc7XG5cbiAgICBjb25zdCB3YWxsZXRDb250cmFjdEFkZHJlc3MgPSAnMHg3ZmNmOTVhOTEwNmEwZWQzYmQwOWU2NTNjOGVhM2Q1ZTQ4OWJmYjIzJztcbiAgICAvLyB0ZXRjIHdhbGxldCAxIHJlY2VpdmVBZGRyZXNzIDRcbiAgICBjb25zdCByZWNvdmVyeURlc3RpbmF0aW9uID0gJzB4MzIxY2JlMjIzZmYxYzNkMGMwM2I3M2I4YzY0OGVmMmQ5MWU0YWFhMSc7XG4gICAgY29uc3QgZ2FzUHJpY2UgPSAyNTAwMDAwMDAwMDtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgdGV0Y0NvaW4gPSBiaXRnby5jb2luKCd0ZXRjJykgYXMgVGV0YztcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzYW5kYm94LnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYW4gRVRIIHVuc2lnbmVkIHN3ZWVwJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb246IE9mZmxpbmVWYXVsdFR4SW5mbyA9IChhd2FpdCB0ZXRjQ29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTogdXNlclhwdWIsXG4gICAgICAgIGJhY2t1cEtleTogYmFja3VwWHB1YixcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgICBnYXNQcmljZSxcbiAgICAgIH0pKSBhcyBPZmZsaW5lVmF1bHRUeEluZm87XG4gICAgICBzaG91bGQuZXhpc3QodHJhbnNhY3Rpb24pO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4SGV4Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndXNlcktleScpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2JhY2t1cEtleScpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2dhc0xpbWl0Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5nYXNMaW1pdC5zaG91bGQuZXF1YWwoJzUwMDAwMCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2dhc1ByaWNlJyk7XG4gICAgICB0cmFuc2FjdGlvbi5nYXNQcmljZS5zaG91bGQuZXF1YWwoJzI1MDAwMDAwMDAwJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0Q29udHJhY3RBZGRyZXNzJyk7XG4gICAgICB0cmFuc2FjdGlvbi53YWxsZXRDb250cmFjdEFkZHJlc3Muc2hvdWxkLmVxdWFsKCcweDdmY2Y5NWE5MTA2YTBlZDNiZDA5ZTY1M2M4ZWEzZDVlNDg5YmZiMjMnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNpcGllbnQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYWRkIGEgc2Vjb25kIHNpZ25hdHVyZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gKGF3YWl0IHRldGNDb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiB1c2VyWHB1YixcbiAgICAgICAgYmFja3VwS2V5OiBiYWNrdXBYcHViLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3MsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb24sXG4gICAgICAgIGdhc1ByaWNlLFxuICAgICAgfSkpIGFzIE9mZmxpbmVWYXVsdFR4SW5mbztcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhIZXg6IHRyYW5zYWN0aW9uLnR4SGV4LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICBwcnY6IHVzZXJYcHJ2LFxuICAgICAgfTtcbiAgICAgIC8vIHNpZ24gdHJhbnNhY3Rpb24gb25jZVxuICAgICAgY29uc3QgaGFsZlNpZ25lZCA9IGF3YWl0IHRldGNDb2luLnNpZ25UcmFuc2FjdGlvbihwYXJhbXMgYXMgU2lnblRyYW5zYWN0aW9uT3B0aW9ucyk7XG4gICAgICBjb25zdCBoYWxmU2lnbmVkUGFyYW1zID0ge1xuICAgICAgICB0eFByZWJ1aWxkOiBoYWxmU2lnbmVkLFxuICAgICAgICBpc0xhc3RTaWduYXR1cmU6IHRydWUsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogd2FsbGV0Q29udHJhY3RBZGRyZXNzLFxuICAgICAgICBwcnY6IGJhY2t1cFhwcnYsXG4gICAgICB9O1xuICAgICAgLy8gc2lnbiB0cmFuc2FjdGlvbiB0d2ljZSB3aXRoIHRoZSBcImlzTGFzdFNpZ25hdHVyZVwiIGZsYWdcbiAgICAgIGNvbnN0IGZpbmFsU2lnbmVkVHggPSAoYXdhaXQgdGV0Y0NvaW4uc2lnblRyYW5zYWN0aW9uKFxuICAgICAgICBoYWxmU2lnbmVkUGFyYW1zIGFzIFNpZ25UcmFuc2FjdGlvbk9wdGlvbnNcbiAgICAgICkpIGFzIEZ1bGx5U2lnbmVkVHJhbnNhY3Rpb247XG4gICAgICBmaW5hbFNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEhleCcpO1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gdGV0Y0NvaW4uZ2V0VHJhbnNhY3Rpb25CdWlsZGVyKCkgYXMgVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgICAgdHhCdWlsZGVyLmZyb20oZmluYWxTaWduZWRUeC50eEhleCk7XG4gICAgICBjb25zdCByZWJ1aWx0VHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIHJlYnVpbHRUeC5zaWduYXR1cmUubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcbiAgICAgIHJlYnVpbHRUeC5vdXRwdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=

Выполнить команду


Для локальной разработки. Не используйте в интернете!