PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-coin-stx/dist/test/unit/transactionBuilder
Просмотр файла: fungibleTokenTransferBuilder.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 statics_1 = require("@bitgo/statics");
const transactions_1 = require("@stacks/transactions");
const should_1 = __importDefault(require("should"));
const network_1 = require("@stacks/network");
const sdk_core_1 = require("@bitgo/sdk-core");
const assert_1 = __importDefault(require("assert"));
const src_1 = require("../../../src");
const testData = __importStar(require("../resources"));
describe('Stacks: Fungible Token Transfer Builder', () => {
const coinName = 'stx:sbtc';
const coinNameTest = 'tstx:tsip6dp';
let bitgo;
before(function () {
bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, {
env: 'mock',
});
bitgo.initializeTestVars();
bitgo.safeRegister('tstx:tsip6dp', src_1.Sip10Token.createInstance);
});
describe('Sip10 fungible token transfer builder', function () {
const factory = new src_1.StxLib.TransactionBuilderFactory(statics_1.coins.get(coinNameTest));
const factoryProd = new src_1.StxLib.TransactionBuilderFactory(statics_1.coins.get(coinName));
const initTxBuilder = () => {
const txBuilder = factory.getFungibleTokenTransferBuilder();
txBuilder.fee({ fee: '180' });
txBuilder.nonce(0);
txBuilder.contractAddress(testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.CONTRACT_ADDRESS);
txBuilder.contractName(testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.CONTRACT_NAME);
txBuilder.functionName(testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.FUNCTION_NAME);
txBuilder.tokenName(testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.TOKEN_NAME);
return txBuilder;
};
describe('fungible token builder environment', function () {
it('should select the right network', function () {
should_1.default.equal(factory.getFungibleTokenTransferBuilder().coinName(), 'tstx:tsip6dp');
should_1.default.equal(factoryProd.getFungibleTokenTransferBuilder().coinName(), 'stx:sbtc');
// used type any to access protected properties
const txBuilder = factory.getFungibleTokenTransferBuilder();
const txBuilderProd = factoryProd.getFungibleTokenTransferBuilder();
txBuilder._network.should.deepEqual(new network_1.StacksTestnet());
txBuilderProd._network.should.deepEqual(new network_1.StacksMainnet());
});
});
describe('should build', function () {
it('an unsigned fungible token transfer transaction', async () => {
const builder = initTxBuilder();
builder.functionArgs([
(0, transactions_1.uintCV)('10000'),
(0, transactions_1.standardPrincipalCV)(testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.SENDER_ADDRESS),
(0, transactions_1.standardPrincipalCV)(testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.RECEIVER_ADDRESS),
(0, transactions_1.someCV)((0, transactions_1.bufferCVFromString)('1')),
]);
builder.fromPubKey(testData.TX_SENDER.pub);
builder.numberSignatures(1);
const tx = await builder.build();
const stacksTxn = tx;
should_1.default.deepEqual(stacksTxn.stxTransaction.postConditions.values.length, 1);
const txJson = tx.toJson();
should_1.default.deepEqual(txJson.payload.contractAddress, testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.CONTRACT_ADDRESS);
should_1.default.deepEqual(txJson.payload.contractName, 'tsip6dp-token');
should_1.default.deepEqual(txJson.payload.functionName, 'transfer');
should_1.default.deepEqual(txJson.nonce, 0);
should_1.default.deepEqual(txJson.fee.toString(), '180');
should_1.default.deepEqual(tx.toBroadcastFormat(), testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.UNSIGNED_SINGLE_SIG_TX);
tx.type.should.equal(sdk_core_1.TransactionType.Send);
tx.outputs.length.should.equal(1);
tx.outputs[0].address.should.equal(testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.RECEIVER_ADDRESS);
tx.outputs[0].value.should.equal('10000');
tx.inputs.length.should.equal(1);
tx.inputs[0].address.should.equal(testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.SENDER_ADDRESS);
tx.inputs[0].value.should.equal('10000');
});
it('an unsigned fungible token transfer transaction without memo', async () => {
const builder = initTxBuilder();
builder.functionArgs([
(0, transactions_1.uintCV)('10000'),
(0, transactions_1.standardPrincipalCV)(testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.SENDER_ADDRESS),
(0, transactions_1.standardPrincipalCV)(testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.RECEIVER_ADDRESS),
]);
builder.fromPubKey(testData.TX_SENDER.pub);
builder.numberSignatures(1);
const tx = await builder.build();
const txJson = tx.toJson();
should_1.default.deepEqual(txJson.payload.contractAddress, testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.CONTRACT_ADDRESS);
should_1.default.deepEqual(txJson.payload.contractName, 'tsip6dp-token');
should_1.default.deepEqual(txJson.payload.functionName, 'transfer');
should_1.default.deepEqual(txJson.nonce, 0);
should_1.default.deepEqual(txJson.fee.toString(), '180');
should_1.default.deepEqual(tx.toBroadcastFormat(), testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.UNSIGNED_SINGLE_SIG_TX_WITHOUT_MEMO);
tx.type.should.equal(sdk_core_1.TransactionType.Send);
tx.outputs.length.should.equal(1);
tx.outputs[0].address.should.equal(testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.RECEIVER_ADDRESS);
tx.outputs[0].value.should.equal('10000');
tx.inputs.length.should.equal(1);
tx.inputs[0].address.should.equal(testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.SENDER_ADDRESS);
tx.inputs[0].value.should.equal('10000');
});
it('a multisig fungible token transfer transaction with memo', async () => {
const builder = initTxBuilder();
builder.functionArgs([
(0, transactions_1.uintCV)('10000'),
(0, transactions_1.standardPrincipalCV)(testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.SENDER_ADDRESS),
(0, transactions_1.standardPrincipalCV)(testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.RECEIVER_ADDRESS),
(0, transactions_1.someCV)((0, transactions_1.bufferCVFromString)('1')),
]);
builder.sign({ key: testData.prv1 });
builder.sign({ key: testData.prv2 });
builder.fromPubKey([testData.pub1, testData.pub2, testData.pub3]);
builder.numberSignatures(2);
const tx = await builder.build();
JSON.stringify(tx.toJson());
should_1.default.deepEqual(tx.toBroadcastFormat(), testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.SIGNED_MULTI_SIG_TX);
});
it('a multisig fungible token transfer transaction without memo', async () => {
const builder = initTxBuilder();
builder.functionArgs([
(0, transactions_1.uintCV)('10000'),
(0, transactions_1.standardPrincipalCV)(testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.SENDER_ADDRESS),
(0, transactions_1.standardPrincipalCV)(testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.RECEIVER_ADDRESS),
(0, transactions_1.noneCV)(),
]);
builder.sign({ key: testData.prv1 });
builder.sign({ key: testData.prv2 });
builder.fromPubKey([testData.pub1, testData.pub2, testData.pub3]);
builder.numberSignatures(2);
const tx = await builder.build();
JSON.stringify(tx.toJson());
should_1.default.deepEqual(tx.toBroadcastFormat(), testData.FUNGIBLE_TOKEN_TRANSFER_CONSTANTS.SIGNED_MULTI_SIG_TX_WITHOUT_MEMO);
});
});
describe('should fail', () => {
it('a fungible token transfer builder with an invalid key', () => {
const builder = initTxBuilder();
assert_1.default.throws(() => builder.sign({ key: 'invalidKey' }), /Unsupported private key/);
});
it('a fungible token transfer builder with an invalid contract address', () => {
const builder = initTxBuilder();
assert_1.default.throws(() => builder.contractAddress('invalidContractAddress'), /Invalid address/);
});
it('a fungible token transfer builder with an invalid contract function name', () => {
const builder = initTxBuilder();
assert_1.default.throws(() => builder.functionName('test-function'), new RegExp('test-function is not supported contract function name'));
});
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnVuZ2libGVUb2tlblRyYW5zZmVyQnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvdW5pdC90cmFuc2FjdGlvbkJ1aWxkZXIvZnVuZ2libGVUb2tlblRyYW5zZmVyQnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDhDQUEwRDtBQUMxRCw0Q0FBMEM7QUFDMUMsNENBQXVDO0FBQ3ZDLHVEQUF1RztBQUN2RyxvREFBNEI7QUFDNUIsNkNBQStEO0FBQy9ELDhDQUFrRDtBQUNsRCxvREFBNEI7QUFFNUIsc0NBQWtEO0FBRWxELHVEQUF5QztBQUV6QyxRQUFRLENBQUMseUNBQXlDLEVBQUUsR0FBRyxFQUFFO0lBQ3ZELE1BQU0sUUFBUSxHQUFHLFVBQVUsQ0FBQztJQUM1QixNQUFNLFlBQVksR0FBRyxjQUFjLENBQUM7SUFDcEMsSUFBSSxLQUFtQixDQUFDO0lBRXhCLE1BQU0sQ0FBQztRQUNMLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxrQkFBUSxFQUFFO1lBQ25DLEdBQUcsRUFBRSxNQUFNO1NBQ1osQ0FBQyxDQUFDO1FBQ0gsS0FBSyxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDM0IsS0FBSyxDQUFDLFlBQVksQ0FBQyxjQUFjLEVBQUUsZ0JBQVUsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUNoRSxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyx1Q0FBdUMsRUFBRTtRQUNoRCxNQUFNLE9BQU8sR0FBRyxJQUFJLFlBQU0sQ0FBQyx5QkFBeUIsQ0FBQyxlQUFLLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFDOUUsTUFBTSxXQUFXLEdBQUcsSUFBSSxZQUFNLENBQUMseUJBQXlCLENBQUMsZUFBSyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1FBRTlFLE1BQU0sYUFB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O2dCQUM1RSxNQUFNLE9BQU8sR0FBRyxhQUFhLEVBQUUsQ0FBQztnQkFDaEMsZ0JBQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyx3QkFBd0IsQ0FBQyxFQUFFLGlCQUFpQixDQUFDLENBQUM7WUFDNUYsQ0FBQyxDQUFDLENBQUM7WUFDSCxFQUFFLENBQUMsMEVBQTBFLEVBQUUsR0FBRyxFQUFFO2dCQUNsRixNQUFNLE9BQU8sR0FBRyxhQUFhLEVBQUUsQ0FBQztnQkFDaEMsZ0JBQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxlQUFlLENBQUMsRUFDM0MsSUFBSSxNQUFNLENBQUMsdURBQXVELENBQUMsQ0FDcEUsQ0FBQztZQUNKLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVGVzdEJpdEdvLCBUZXN0Qml0R29BUEkgfSBmcm9tICdAYml0Z28vc2RrLXRlc3QnO1xuaW1wb3J0IHsgQml0R29BUEkgfSBmcm9tICdAYml0Z28vc2RrLWFwaSc7XG5pbXBvcnQgeyBjb2lucyB9IGZyb20gJ0BiaXRnby9zdGF0aWNzJztcbmltcG9ydCB7IGJ1ZmZlckNWRnJvbVN0cmluZywgbm9uZUNWLCBzb21lQ1YsIHN0YW5kYXJkUHJpbmNpcGFsQ1YsIHVpbnRDViB9IGZyb20gJ0BzdGFja3MvdHJhbnNhY3Rpb25zJztcbmltcG9ydCBzaG91bGQgZnJvbSAnc2hvdWxkJztcbmltcG9ydCB7IFN0YWNrc01haW5uZXQsIFN0YWNrc1Rlc3RuZXQgfSBmcm9tICdAc3RhY2tzL25ldHdvcmsnO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25UeXBlIH0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcblxuaW1wb3J0IHsgU2lwMTBUb2tlbiwgU3R4TGliIH0gZnJvbSAnLi4vLi4vLi4vc3JjJztcbmltcG9ydCB7IFRyYW5zYWN0aW9uIH0gZnJvbSAnLi4vLi4vLi4vc3JjL2xpYic7XG5pbXBvcnQgKiBhcyB0ZXN0RGF0YSBmcm9tICcuLi9yZXNvdXJjZXMnO1xuXG5kZXNjcmliZSgnU3RhY2tzOiBGdW5naWJsZSBUb2tlbiBUcmFuc2ZlciBCdWlsZGVyJywgKCkgPT4ge1xuICBjb25zdCBjb2luTmFtZSA9ICdzdHg6c2J0Yyc7XG4gIGNvbnN0IGNvaW5OYW1lVGVzdCA9ICd0c3R4OnRzaXA2ZHAnO1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcblxuICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7XG4gICAgICBlbnY6ICdtb2NrJyxcbiAgICB9KTtcbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ3RzdHg6dHNpcDZkcCcsIFNpcDEwVG9rZW4uY3JlYXRlSW5zdGFuY2UpO1xuICB9KTtcblxuICBkZXNjcmliZSgnU2lwMTAgZnVuZ2libGUgdG9rZW4gdHJhbnNmZXIgYnVpbGRlcicsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBmYWN0b3J5ID0gbmV3IFN0eExpYi5UcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldChjb2luTmFtZVRlc3QpKTtcbiAgICBjb25zdCBmYWN0b3J5UHJvZCA9IG5ldyBTdHhMaWIuVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2lucy5nZXQoY29pbk5hbWUpKTtcblxuICAgIGNvbnN0IGluaXRUeEJ1aWxkZXIgPSAoKSA9PiB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldEZ1bmdpYmxlVG9rZW5UcmFuc2ZlckJ1aWxkZXIoKTtcbiAgICAgIHR4QnVpbGRlci5mZWUoeyBmZWU6ICcxODAnIH0pO1xuICAgICAgdHhCdWlsZGVyLm5vbmNlKDApO1xuICAgICAgdHhCdWlsZGVyLmNvbnRyYWN0QWRkcmVzcyh0ZXN0RGF0YS5GVU5HSUJMRV9UT0tFTl9UUkFOU0ZFUl9DT05TVEFOVFMuQ09OVFJBQ1RfQUREUkVTUyk7XG4gICAgICB0eEJ1aWxkZXIuY29udHJhY3ROYW1lKHRlc3REYXRhLkZVTkdJQkxFX1RPS0VOX1RSQU5TRkVSX0NPTlNUQU5UUy5DT05UUkFDVF9OQU1FKTtcbiAgICAgIHR4QnVpbGRlci5mdW5jdGlvbk5hbWUodGVzdERhdGEuRlVOR0lCTEVfVE9LRU5fVFJBTlNGRVJfQ09OU1RBTlRTLkZVTkNUSU9OX05BTUUpO1xuICAgICAgdHhCdWlsZGVyLnRva2VuTmFtZSh0ZXN0RGF0YS5GVU5HSUJMRV9UT0tFTl9UUkFOU0ZFUl9DT05TVEFOVFMuVE9LRU5fTkFNRSk7XG4gICAgICByZXR1cm4gdHhCdWlsZGVyO1xuICAgIH07XG5cbiAgICBkZXNjcmliZSgnZnVuZ2libGUgdG9rZW4gYnVpbGRlciBlbnZpcm9ubWVudCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgc2VsZWN0IHRoZSByaWdodCBuZXR3b3JrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBzaG91bGQuZXF1YWwoZmFjdG9yeS5nZXRGdW5naWJsZVRva2VuVHJhbnNmZXJCdWlsZGVyKCkuY29pbk5hbWUoKSwgJ3RzdHg6dHNpcDZkcCcpO1xuICAgICAgICBzaG91bGQuZXF1YWwoZmFjdG9yeVByb2QuZ2V0RnVuZ2libGVUb2tlblRyYW5zZmVyQnVpbGRlcigpLmNvaW5OYW1lKCksICdzdHg6c2J0YycpO1xuICAgICAgICAvLyB1c2VkIHR5cGUgYW55IHRvIGFjY2VzcyBwcm90ZWN0ZWQgcHJvcGVydGllc1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXI6IGFueSA9IGZhY3RvcnkuZ2V0RnVuZ2libGVUb2tlblRyYW5zZmVyQnVpbGRlcigpO1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXJQcm9kOiBhbnkgPSBmYWN0b3J5UHJvZC5nZXRGdW5naWJsZVRva2VuVHJhbnNmZXJCdWlsZGVyKCk7XG5cbiAgICAgICAgdHhCdWlsZGVyLl9uZXR3b3JrLnNob3VsZC5kZWVwRXF1YWwobmV3IFN0YWNrc1Rlc3RuZXQoKSk7XG4gICAgICAgIHR4QnVpbGRlclByb2QuX25ldHdvcmsuc2hvdWxkLmRlZXBFcXVhbChuZXcgU3RhY2tzTWFpbm5ldCgpKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3Nob3VsZCBidWlsZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdhbiB1bnNpZ25lZCBmdW5naWJsZSB0b2tlbiB0cmFuc2ZlciB0cmFuc2FjdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgYnVpbGRlciA9IGluaXRUeEJ1aWxkZXIoKTtcbiAgICAgICAgYnVpbGRlci5mdW5jdGlvbkFyZ3MoW1xuICAgICAgICAgIHVpbnRDVignMTAwMDAnKSxcbiAgICAgICAgICBzdGFuZGFyZFByaW5jaXBhbENWKHRlc3REYXRhLkZVTkdJQkxFX1RPS0VOX1RSQU5TRkVSX0NPTlNUQU5UUy5TRU5ERVJfQUREUkVTUyksXG4gICAgICAgICAgc3RhbmRhcmRQcmluY2lwYWxDVih0ZXN0RGF0YS5GVU5HSUJMRV9UT0tFTl9UUkFOU0ZFUl9DT05TVEFOVFMuUkVDRUlWRVJfQUREUkVTUyksXG4gICAgICAgICAgc29tZUNWKGJ1ZmZlckNWRnJvbVN0cmluZygnMScpKSxcbiAgICAgICAgXSk7XG4gICAgICAgIGJ1aWxkZXIuZnJvbVB1YktleSh0ZXN0RGF0YS5UWF9TRU5ERVIucHViKTtcbiAgICAgICAgYnVpbGRlci5udW1iZXJTaWduYXR1cmVzKDEpO1xuICAgICAgICBjb25zdCB0eCA9IGF3YWl0IGJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgICAgY29uc3Qgc3RhY2tzVHhuID0gdHggYXMgVHJhbnNhY3Rpb247XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwoc3RhY2tzVHhuLnN0eFRyYW5zYWN0aW9uLnBvc3RDb25kaXRpb25zLnZhbHVlcy5sZW5ndGgsIDEpO1xuXG4gICAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5wYXlsb2FkLmNvbnRyYWN0QWRkcmVzcywgdGVzdERhdGEuRlVOR0lCTEVfVE9LRU5fVFJBTlNGRVJfQ09OU1RBTlRTLkNPTlRSQUNUX0FERFJFU1MpO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5wYXlsb2FkLmNvbnRyYWN0TmFtZSwgJ3RzaXA2ZHAtdG9rZW4nKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ucGF5bG9hZC5mdW5jdGlvbk5hbWUsICd0cmFuc2ZlcicpO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5ub25jZSwgMCk7XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmZlZS50b1N0cmluZygpLCAnMTgwJyk7XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwodHgudG9Ccm9hZGNhc3RGb3JtYXQoKSwgdGVzdERhdGEuRlVOR0lCTEVfVE9LRU5fVFJBTlNGRVJfQ09OU1RBTlRTLlVOU0lHTkVEX1NJTkdMRV9TSUdfVFgpO1xuXG4gICAgICAgIHR4LnR5cGUuc2hvdWxkLmVxdWFsKFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcbiAgICAgICAgdHgub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICB0eC5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLkZVTkdJQkxFX1RPS0VOX1RSQU5TRkVSX0NPTlNUQU5UUy5SRUNFSVZFUl9BRERSRVNTKTtcbiAgICAgICAgdHgub3V0cHV0c1swXS52YWx1ZS5zaG91bGQuZXF1YWwoJzEwMDAwJyk7XG4gICAgICAgIHR4LmlucHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICB0eC5pbnB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwodGVzdERhdGEuRlVOR0lCTEVfVE9LRU5fVFJBTlNGRVJfQ09OU1RBTlRTLlNFTkRFUl9BRERSRVNTKTtcbiAgICAgICAgdHguaW5wdXRzWzBdLnZhbHVlLnNob3VsZC5lcXVhbCgnMTAwMDAnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnYW4gdW5zaWduZWQgZnVuZ2libGUgdG9rZW4gdHJhbnNmZXIgdHJhbnNhY3Rpb24gd2l0aG91dCBtZW1vJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBidWlsZGVyID0gaW5pdFR4QnVpbGRlcigpO1xuICAgICAgICBidWlsZGVyLmZ1bmN0aW9uQXJncyhbXG4gICAgICAgICAgdWludENWKCcxMDAwMCcpLFxuICAgICAgICAgIHN0YW5kYXJkUHJpbmNpcGFsQ1YodGVzdERhdGEuRlVOR0lCTEVfVE9LRU5fVFJBTlNGRVJfQ09OU1RBTlRTLlNFTkRFUl9BRERSRVNTKSxcbiAgICAgICAgICBzdGFuZGFyZFByaW5jaXBhbENWKHRlc3REYXRhLkZVTkdJQkxFX1RPS0VOX1RSQU5TRkVSX0NPTlNUQU5UUy5SRUNFSVZFUl9BRERSRVNTKSxcbiAgICAgICAgXSk7XG4gICAgICAgIGJ1aWxkZXIuZnJvbVB1YktleSh0ZXN0RGF0YS5UWF9TRU5ERVIucHViKTtcbiAgICAgICAgYnVpbGRlci5udW1iZXJTaWduYXR1cmVzKDEpO1xuICAgICAgICBjb25zdCB0eCA9IGF3YWl0IGJ1aWxkZXIuYnVpbGQoKTtcblxuICAgICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ucGF5bG9hZC5jb250cmFjdEFkZHJlc3MsIHRlc3REYXRhLkZVTkdJQkxFX1RPS0VOX1RSQU5TRkVSX0NPTlNUQU5UUy5DT05UUkFDVF9BRERSRVNTKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ucGF5bG9hZC5jb250cmFjdE5hbWUsICd0c2lwNmRwLXRva2VuJyk7XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLnBheWxvYWQuZnVuY3Rpb25OYW1lLCAndHJhbnNmZXInKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ubm9uY2UsIDApO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5mZWUudG9TdHJpbmcoKSwgJzE4MCcpO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKFxuICAgICAgICAgIHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCksXG4gICAgICAgICAgdGVzdERhdGEuRlVOR0lCTEVfVE9LRU5fVFJBTlNGRVJfQ09OU1RBTlRTLlVOU0lHTkVEX1NJTkdMRV9TSUdfVFhfV0lUSE9VVF9NRU1PXG4gICAgICAgICk7XG5cbiAgICAgICAgdHgudHlwZS5zaG91bGQuZXF1YWwoVHJhbnNhY3Rpb25UeXBlLlNlbmQpO1xuICAgICAgICB0eC5vdXRwdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICAgIHR4Lm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwodGVzdERhdGEuRlVOR0lCTEVfVE9LRU5fVFJBTlNGRVJfQ09OU1RBTlRTLlJFQ0VJVkVSX0FERFJFU1MpO1xuICAgICAgICB0eC5vdXRwdXRzWzBdLnZhbHVlLnNob3VsZC5lcXVhbCgnMTAwMDAnKTtcbiAgICAgICAgdHguaW5wdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICAgIHR4LmlucHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5GVU5HSUJMRV9UT0tFTl9UUkFOU0ZFUl9DT05TVEFOVFMuU0VOREVSX0FERFJFU1MpO1xuICAgICAgICB0eC5pbnB1dHNbMF0udmFsdWUuc2hvdWxkLmVxdWFsKCcxMDAwMCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdhIG11bHRpc2lnIGZ1bmdpYmxlIHRva2VuIHRyYW5zZmVyIHRyYW5zYWN0aW9uIHdpdGggbWVtbycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgYnVpbGRlciA9IGluaXRUeEJ1aWxkZXIoKTtcbiAgICAgICAgYnVpbGRlci5mdW5jdGlvbkFyZ3MoW1xuICAgICAgICAgIHVpbnRDVignMTAwMDAnKSxcbiAgICAgICAgICBzdGFuZGFyZFByaW5jaXBhbENWKHRlc3REYXRhLkZVTkdJQkxFX1RPS0VOX1RSQU5TRkVSX0NPTlNUQU5UUy5TRU5ERVJfQUREUkVTUyksXG4gICAgICAgICAgc3RhbmRhcmRQcmluY2lwYWxDVih0ZXN0RGF0YS5GVU5HSUJMRV9UT0tFTl9UUkFOU0ZFUl9DT05TVEFOVFMuUkVDRUlWRVJfQUREUkVTUyksXG4gICAgICAgICAgc29tZUNWKGJ1ZmZlckNWRnJvbVN0cmluZygnMScpKSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgYnVpbGRlci5zaWduKHsga2V5OiB0ZXN0RGF0YS5wcnYxIH0pO1xuICAgICAgICBidWlsZGVyLnNpZ24oeyBrZXk6IHRlc3REYXRhLnBydjIgfSk7XG4gICAgICAgIGJ1aWxkZXIuZnJvbVB1YktleShbdGVzdERhdGEucHViMSwgdGVzdERhdGEucHViMiwgdGVzdERhdGEucHViM10pO1xuICAgICAgICBidWlsZGVyLm51bWJlclNpZ25hdHVyZXMoMik7XG4gICAgICAgIGNvbnN0IHR4ID0gYXdhaXQgYnVpbGRlci5idWlsZCgpO1xuICAgICAgICBKU09OLnN0cmluZ2lmeSh0eC50b0pzb24oKSk7XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwodHgudG9Ccm9hZGNhc3RGb3JtYXQoKSwgdGVzdERhdGEuRlVOR0lCTEVfVE9LRU5fVFJBTlNGRVJfQ09OU1RBTlRTLlNJR05FRF9NVUxUSV9TSUdfVFgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdhIG11bHRpc2lnIGZ1bmdpYmxlIHRva2VuIHRyYW5zZmVyIHRyYW5zYWN0aW9uIHdpdGhvdXQgbWVtbycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgYnVpbGRlciA9IGluaXRUeEJ1aWxkZXIoKTtcbiAgICAgICAgYnVpbGRlci5mdW5jdGlvbkFyZ3MoW1xuICAgICAgICAgIHVpbnRDVignMTAwMDAnKSxcbiAgICAgICAgICBzdGFuZGFyZFByaW5jaXBhbENWKHRlc3REYXRhLkZVTkdJQkxFX1RPS0VOX1RSQU5TRkVSX0NPTlNUQU5UUy5TRU5ERVJfQUREUkVTUyksXG4gICAgICAgICAgc3RhbmRhcmRQcmluY2lwYWxDVih0ZXN0RGF0YS5GVU5HSUJMRV9UT0tFTl9UUkFOU0ZFUl9DT05TVEFOVFMuUkVDRUlWRVJfQUREUkVTUyksXG4gICAgICAgICAgbm9uZUNWKCksXG4gICAgICAgIF0pO1xuXG4gICAgICAgIGJ1aWxkZXIuc2lnbih7IGtleTogdGVzdERhdGEucHJ2MSB9KTtcbiAgICAgICAgYnVpbGRlci5zaWduKHsga2V5OiB0ZXN0RGF0YS5wcnYyIH0pO1xuICAgICAgICBidWlsZGVyLmZyb21QdWJLZXkoW3Rlc3REYXRhLnB1YjEsIHRlc3REYXRhLnB1YjIsIHRlc3REYXRhLnB1YjNdKTtcbiAgICAgICAgYnVpbGRlci5udW1iZXJTaWduYXR1cmVzKDIpO1xuICAgICAgICBjb25zdCB0eCA9IGF3YWl0IGJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkodHgudG9Kc29uKCkpO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKFxuICAgICAgICAgIHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCksXG4gICAgICAgICAgdGVzdERhdGEuRlVOR0lCTEVfVE9LRU5fVFJBTlNGRVJfQ09OU1RBTlRTLlNJR05FRF9NVUxUSV9TSUdfVFhfV0lUSE9VVF9NRU1PXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdzaG91bGQgZmFpbCcsICgpID0+IHtcbiAgICAgIGl0KCdhIGZ1bmdpYmxlIHRva2VuIHRyYW5zZmVyIGJ1aWxkZXIgd2l0aCBhbiBpbnZhbGlkIGtleScsICgpID0+IHtcbiAgICAgICAgY29uc3QgYnVpbGRlciA9IGluaXRUeEJ1aWxkZXIoKTtcbiAgICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiBidWlsZGVyLnNpZ24oeyBrZXk6ICdpbnZhbGlkS2V5JyB9KSwgL1Vuc3VwcG9ydGVkIHByaXZhdGUga2V5Lyk7XG4gICAgICB9KTtcbiAgICAgIGl0KCdhIGZ1bmdpYmxlIHRva2VuIHRyYW5zZmVyIGJ1aWxkZXIgd2l0aCBhbiBpbnZhbGlkIGNvbnRyYWN0IGFkZHJlc3MnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGJ1aWxkZXIgPSBpbml0VHhCdWlsZGVyKCk7XG4gICAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gYnVpbGRlci5jb250cmFjdEFkZHJlc3MoJ2ludmFsaWRDb250cmFjdEFkZHJlc3MnKSwgL0ludmFsaWQgYWRkcmVzcy8pO1xuICAgICAgfSk7XG4gICAgICBpdCgnYSBmdW5naWJsZSB0b2tlbiB0cmFuc2ZlciBidWlsZGVyIHdpdGggYW4gaW52YWxpZCBjb250cmFjdCBmdW5jdGlvbiBuYW1lJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBidWlsZGVyID0gaW5pdFR4QnVpbGRlcigpO1xuICAgICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAgICgpID0+IGJ1aWxkZXIuZnVuY3Rpb25OYW1lKCd0ZXN0LWZ1bmN0aW9uJyksXG4gICAgICAgICAgbmV3IFJlZ0V4cCgndGVzdC1mdW5jdGlvbiBpcyBub3Qgc3VwcG9ydGVkIGNvbnRyYWN0IGZ1bmN0aW9uIG5hbWUnKVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=Выполнить команду
Для локальной разработки. Не используйте в интернете!