PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-coin-sui/dist/test/unit/transactionBuilder
Просмотр файла: transferBuilder.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 assert_1 = __importDefault(require("assert"));
const getBuilderFactory_1 = require("../getBuilderFactory");
const testData = __importStar(require("../../resources/sui"));
const should_1 = __importDefault(require("should"));
const sdk_core_1 = require("@bitgo/sdk-core");
const utils_1 = __importDefault(require("../../../src/lib/utils"));
const transaction_1 = require("../../../src/lib/transaction");
const iface_1 = require("../../../src/lib/iface");
const constants_1 = require("../../../src/lib/constants");
describe('Sui Transfer Builder', () => {
const factory = (0, getBuilderFactory_1.getBuilderFactory)('tsui');
describe('Succeed', () => {
it('should build a transfer tx', async function () {
const txBuilder = factory.getTransferBuilder();
txBuilder.type(iface_1.SuiTransactionType.Transfer);
txBuilder.sender(testData.sender.address);
txBuilder.send(testData.recipients);
txBuilder.gasData(testData.gasData);
const tx = await txBuilder.build();
should_1.default.equal(tx.type, sdk_core_1.TransactionType.Send);
tx.suiTransaction.gasData.payment.should.deepEqual(testData.coinsGasPayment);
tx.inputs.length.should.equal(1);
tx.inputs[0].should.deepEqual({
address: testData.sender.address,
value: (testData.AMOUNT * 2).toString(),
coin: 'tsui',
});
tx.outputs.length.should.equal(2);
tx.outputs[0].should.deepEqual({
address: testData.recipients[0].address,
value: testData.recipients[0].amount,
coin: 'tsui',
});
tx.outputs[1].should.deepEqual({
address: testData.recipients[1].address,
value: testData.recipients[1].amount,
coin: 'tsui',
});
const rawTx = tx.toBroadcastFormat();
should_1.default.equal(utils_1.default.isValidRawTransaction(rawTx), true);
should_1.default.equal(rawTx, testData.TRANSFER);
});
it('should build a split coin tx', async function () {
const txBuilder = factory.getTransferBuilder();
txBuilder.type(iface_1.SuiTransactionType.Transfer);
txBuilder.sender(testData.sender.address);
const amount = 1000000000;
const recipients = new Array(100).fill({ address: testData.sender.address, amount: amount.toString() });
txBuilder.send(recipients);
txBuilder.gasData(testData.gasData);
const tx = await txBuilder.build();
should_1.default.equal(tx.type, sdk_core_1.TransactionType.Send);
tx.suiTransaction.gasData.payment.should.deepEqual(testData.coinsGasPayment);
tx.inputs.length.should.equal(1);
tx.inputs[0].should.deepEqual({
address: testData.sender.address,
value: (amount * 100).toString(),
coin: 'tsui',
});
tx.outputs.length.should.equal(100);
tx.outputs.forEach((output) => output.should.deepEqual({
address: testData.sender.address,
value: amount.toString(),
coin: 'tsui',
}));
});
it('should build a split coin tx with more than 255 input objects', async function () {
const amount = 1000000000;
const numberOfRecipients = 10;
const numberOfPaymentObjects = 1000;
const txBuilder = factory.getTransferBuilder();
txBuilder.type(iface_1.SuiTransactionType.Transfer);
txBuilder.sender(testData.sender.address);
const recipients = new Array(numberOfRecipients).fill({
address: testData.sender.address,
amount: amount.toString(),
});
const gasData = {
...testData.gasData,
payment: testData.generateObjects(numberOfPaymentObjects),
};
txBuilder.send(recipients);
txBuilder.gasData(gasData);
const tx = await txBuilder.build();
(0, assert_1.default)(tx instanceof transaction_1.Transaction);
tx.type.should.equal(sdk_core_1.TransactionType.Send);
tx.inputs.length.should.equal(1);
tx.inputs[0].should.deepEqual({
address: testData.sender.address,
value: (amount * 10).toString(),
coin: 'tsui',
});
tx.outputs.length.should.equal(10);
tx.outputs.forEach((output) => output.should.deepEqual({
coin: 'tsui',
address: testData.sender.address,
value: amount.toString(),
}));
tx.suiTransaction.gasData.owner.should.equal(gasData.owner);
tx.suiTransaction.gasData.price.should.equal(gasData.price);
tx.suiTransaction.gasData.budget.should.equal(gasData.budget);
tx.suiTransaction.gasData.payment.length.should.equal(constants_1.MAX_GAS_OBJECTS - 1);
const programmableTx = tx.suiTransaction.tx;
// total objects - objects sent as gas payment + no. of recipient amounts(pure)
// + no. of unique recipient addresses(de-duped objects)
programmableTx.inputs.length.should.equal(numberOfPaymentObjects - (constants_1.MAX_GAS_OBJECTS - 1) + numberOfRecipients + 1);
programmableTx.transactions[0].kind.should.equal('MergeCoins');
programmableTx.transactions[0].sources.length.should.equal(constants_1.MAX_COMMAND_ARGS - 1);
programmableTx.transactions[1].kind.should.equal('MergeCoins');
programmableTx.transactions[1].sources.length.should.equal(numberOfPaymentObjects - (constants_1.MAX_COMMAND_ARGS - 1) - (constants_1.MAX_GAS_OBJECTS - 1));
const rawTx = tx.toBroadcastFormat();
should_1.default.equal(utils_1.default.isValidRawTransaction(rawTx), true);
const rebuilder = factory.from(rawTx);
rebuilder.addSignature({ pub: testData.sender.publicKey }, Buffer.from(testData.sender.signatureHex));
const rebuiltTx = await rebuilder.build();
rebuiltTx.toBroadcastFormat().should.equal(rawTx);
rebuiltTx.toJson().gasData.payment.length.should.equal(numberOfPaymentObjects);
});
});
describe('Fail', () => {
it('should fail for invalid sender', async function () {
const builder = factory.getTransferBuilder();
(0, should_1.default)(() => builder.sender('randomString')).throwError('Invalid or missing sender, got: randomString');
});
it('should fail for invalid payTx', async function () {
const builder = factory.getTransferBuilder();
(0, should_1.default)(() => builder.send([testData.invalidRecipients[0]])).throwError('Invalid or missing address, got: randomString');
(0, should_1.default)(() => builder.send([testData.invalidRecipients[1]])).throwError('Invalid recipient amount');
});
it('should fail for invalid gasData', function () {
const builder = factory.getTransferBuilder();
(0, should_1.default)(() => builder.gasData(testData.invalidGasOwner)).throwError(`Invalid gas address ${testData.invalidGasOwner.owner}`);
});
it('should fail for invalid gasBudget', function () {
const builder = factory.getTransferBuilder();
(0, should_1.default)(() => builder.gasData(testData.invalidGasBudget)).throwError('Invalid gas budget -1');
});
it('should fail for invalid gasPayment', function () {
const builder = factory.getTransferBuilder();
const invalidGasPayment = {
...testData.gasDataWithoutGasPayment,
payment: [
{
objectId: '',
version: -1,
digest: '',
},
],
};
(0, should_1.default)(() => builder.gasData(invalidGasPayment)).throwError('Invalid payment, invalid or missing version');
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmZXJCdWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC91bml0L3RyYW5zYWN0aW9uQnVpbGRlci90cmFuc2ZlckJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsNERBQXlEO0FBQ3pELDhEQUFnRDtBQUNoRCxvREFBNEI7QUFDNUIsOENBQWtEO0FBQ2xELG1FQUEyQztBQUMzQyw4REFBNkU7QUFDN0Usa0RBQTZGO0FBQzdGLDBEQUErRTtBQUUvRSxRQUFRLENBQUMsc0JBQXNCLEVBQUUsR0FBRyxFQUFFO0lBQ3BDLE1BQU0sT0FBTyxHQUFHLElBQUEscUNBQWlCLEVBQUMsTUFBTSxDQUFDLENBQUM7SUFFMUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUU7UUFDdkIsRUFBRSxDQUFDLDRCQUE0QixFQUFFLEtBQUs7WUFDcEMsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDL0MsU0FBUyxDQUFDLElBQUksQ0FBQywwQkFBa0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUM1QyxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDMUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDcEMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDcEMsTUFBTSxFQUFFLEdBQUcsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDbkMsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSwwQkFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzNDLEVBQXNELENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxPQUFRLENB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L0YsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsb0NBQW9DLEVBQUU7WUFDdkMsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDN0MsTUFBTSxpQkFBaUIsR0FBRztnQkFDeEIsR0FBRyxRQUFRLENBQUMsd0JBQXdCO2dCQUNwQyxPQUFPLEVBQUU7b0JBQ1A7d0JBQ0UsUUFBUSxFQUFFLEVBQUU7d0JBQ1osT0FBTyxFQUFFLENBQUMsQ0FBQzt3QkFDWCxNQUFNLEVBQUUsRUFBRTtxQkFDWDtpQkFDRjthQUNGLENBQUM7WUFDRixJQUFBLGdCQUFNLEVBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLDZDQUE2QyxDQUFDLENBQUM7UUFDN0csQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHsgZ2V0QnVpbGRlckZhY3RvcnkgfSBmcm9tICcuLi9nZXRCdWlsZGVyRmFjdG9yeSc7XG5pbXBvcnQgKiBhcyB0ZXN0RGF0YSBmcm9tICcuLi8uLi9yZXNvdXJjZXMvc3VpJztcbmltcG9ydCBzaG91bGQgZnJvbSAnc2hvdWxkJztcbmltcG9ydCB7IFRyYW5zYWN0aW9uVHlwZSB9IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgdXRpbHMgZnJvbSAnLi4vLi4vLi4vc3JjL2xpYi91dGlscyc7XG5pbXBvcnQgeyBUcmFuc2FjdGlvbiBhcyBTdWlUcmFuc2FjdGlvbiB9IGZyb20gJy4uLy4uLy4uL3NyYy9saWIvdHJhbnNhY3Rpb24nO1xuaW1wb3J0IHsgU3VpVHJhbnNhY3Rpb25UeXBlLCBUcmFuc2ZlclByb2dyYW1tYWJsZVRyYW5zYWN0aW9uIH0gZnJvbSAnLi4vLi4vLi4vc3JjL2xpYi9pZmFjZSc7XG5pbXBvcnQgeyBNQVhfQ09NTUFORF9BUkdTLCBNQVhfR0FTX09CSkVDVFMgfSBmcm9tICcuLi8uLi8uLi9zcmMvbGliL2NvbnN0YW50cyc7XG5cbmRlc2NyaWJlKCdTdWkgVHJhbnNmZXIgQnVpbGRlcicsICgpID0+IHtcbiAgY29uc3QgZmFjdG9yeSA9IGdldEJ1aWxkZXJGYWN0b3J5KCd0c3VpJyk7XG5cbiAgZGVzY3JpYmUoJ1N1Y2NlZWQnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBidWlsZCBhIHRyYW5zZmVyIHR4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRUcmFuc2ZlckJ1aWxkZXIoKTtcbiAgICAgIHR4QnVpbGRlci50eXBlKFN1aVRyYW5zYWN0aW9uVHlwZS5UcmFuc2Zlcik7XG4gICAgICB0eEJ1aWxkZXIuc2VuZGVyKHRlc3REYXRhLnNlbmRlci5hZGRyZXNzKTtcbiAgICAgIHR4QnVpbGRlci5zZW5kKHRlc3REYXRhLnJlY2lwaWVudHMpO1xuICAgICAgdHhCdWlsZGVyLmdhc0RhdGEodGVzdERhdGEuZ2FzRGF0YSk7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4LnR5cGUsIFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcbiAgICAgICh0eCBhcyBTdWlUcmFuc2FjdGlvbjxUcmFuc2ZlclByb2dyYW1tYWJsZVRyYW5zYWN0aW9uPikuc3VpVHJhbnNhY3Rpb24uZ2FzRGF0YS5wYXltZW50IS5zaG91bGQuZGVlcEVxdWFsKFxuICAgICAgICB0ZXN0RGF0YS5jb2luc0dhc1BheW1lbnRcbiAgICAgICk7XG5cbiAgICAgIHR4LmlucHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgdHguaW5wdXRzWzBdLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBhZGRyZXNzOiB0ZXN0RGF0YS5zZW5kZXIuYWRkcmVzcyxcbiAgICAgICAgdmFsdWU6ICh0ZXN0RGF0YS5BTU9VTlQgKiAyKS50b1N0cmluZygpLFxuICAgICAgICBjb2luOiAndHN1aScsXG4gICAgICB9KTtcbiAgICAgIHR4Lm91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcbiAgICAgIHR4Lm91dHB1dHNbMF0uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGFkZHJlc3M6IHRlc3REYXRhLnJlY2lwaWVudHNbMF0uYWRkcmVzcyxcbiAgICAgICAgdmFsdWU6IHRlc3REYXRhLnJlY2lwaWVudHNbMF0uYW1vdW50LFxuICAgICAgICBjb2luOiAndHN1aScsXG4gICAgICB9KTtcbiAgICAgIHR4Lm91dHB1dHNbMV0uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGFkZHJlc3M6IHRlc3REYXRhLnJlY2lwaWVudHNbMV0uYWRkcmVzcyxcbiAgICAgICAgdmFsdWU6IHRlc3REYXRhLnJlY2lwaWVudHNbMV0uYW1vdW50LFxuICAgICAgICBjb2luOiAndHN1aScsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHJhd1R4ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkUmF3VHJhbnNhY3Rpb24ocmF3VHgpLCB0cnVlKTtcbiAgICAgIHNob3VsZC5lcXVhbChyYXdUeCwgdGVzdERhdGEuVFJBTlNGRVIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBidWlsZCBhIHNwbGl0IGNvaW4gdHgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgICAgdHhCdWlsZGVyLnR5cGUoU3VpVHJhbnNhY3Rpb25UeXBlLlRyYW5zZmVyKTtcbiAgICAgIHR4QnVpbGRlci5zZW5kZXIodGVzdERhdGEuc2VuZGVyLmFkZHJlc3MpO1xuICAgICAgY29uc3QgYW1vdW50ID0gMTAwMDAwMDAwMDtcbiAgICAgIGNvbnN0IHJlY2lwaWVudHMgPSBuZXcgQXJyYXkoMTAwKS5maWxsKHsgYWRkcmVzczogdGVzdERhdGEuc2VuZGVyLmFkZHJlc3MsIGFtb3VudDogYW1vdW50LnRvU3RyaW5nKCkgfSk7XG4gICAgICB0eEJ1aWxkZXIuc2VuZChyZWNpcGllbnRzKTtcbiAgICAgIHR4QnVpbGRlci5nYXNEYXRhKHRlc3REYXRhLmdhc0RhdGEpO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eC50eXBlLCBUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgICAodHggYXMgU3VpVHJhbnNhY3Rpb248VHJhbnNmZXJQcm9ncmFtbWFibGVUcmFuc2FjdGlvbj4pLnN1aVRyYW5zYWN0aW9uLmdhc0RhdGEucGF5bWVudCEuc2hvdWxkLmRlZXBFcXVhbChcbiAgICAgICAgdGVzdERhdGEuY29pbnNHYXNQYXltZW50XG4gICAgICApO1xuXG4gICAgICB0eC5pbnB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIHR4LmlucHV0c1swXS5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgYWRkcmVzczogdGVzdERhdGEuc2VuZGVyLmFkZHJlc3MsXG4gICAgICAgIHZhbHVlOiAoYW1vdW50ICogMTAwKS50b1N0cmluZygpLFxuICAgICAgICBjb2luOiAndHN1aScsXG4gICAgICB9KTtcbiAgICAgIHR4Lm91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxMDApO1xuICAgICAgdHgub3V0cHV0cy5mb3JFYWNoKChvdXRwdXQpID0+XG4gICAgICAgIG91dHB1dC5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgICBhZGRyZXNzOiB0ZXN0RGF0YS5zZW5kZXIuYWRkcmVzcyxcbiAgICAgICAgICB2YWx1ZTogYW1vdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgY29pbjogJ3RzdWknLFxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYnVpbGQgYSBzcGxpdCBjb2luIHR4IHdpdGggbW9yZSB0aGFuIDI1NSBpbnB1dCBvYmplY3RzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYW1vdW50ID0gMTAwMDAwMDAwMDtcbiAgICAgIGNvbnN0IG51bWJlck9mUmVjaXBpZW50cyA9IDEwO1xuICAgICAgY29uc3QgbnVtYmVyT2ZQYXltZW50T2JqZWN0cyA9IDEwMDA7XG5cbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgICB0eEJ1aWxkZXIudHlwZShTdWlUcmFuc2FjdGlvblR5cGUuVHJhbnNmZXIpO1xuICAgICAgdHhCdWlsZGVyLnNlbmRlcih0ZXN0RGF0YS5zZW5kZXIuYWRkcmVzcyk7XG5cbiAgICAgIGNvbnN0IHJlY2lwaWVudHMgPSBuZXcgQXJyYXkobnVtYmVyT2ZSZWNpcGllbnRzKS5maWxsKHtcbiAgICAgICAgYWRkcmVzczogdGVzdERhdGEuc2VuZGVyLmFkZHJlc3MsXG4gICAgICAgIGFtb3VudDogYW1vdW50LnRvU3RyaW5nKCksXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgZ2FzRGF0YSA9IHtcbiAgICAgICAgLi4udGVzdERhdGEuZ2FzRGF0YSxcbiAgICAgICAgcGF5bWVudDogdGVzdERhdGEuZ2VuZXJhdGVPYmplY3RzKG51bWJlck9mUGF5bWVudE9iamVjdHMpLFxuICAgICAgfTtcblxuICAgICAgdHhCdWlsZGVyLnNlbmQocmVjaXBpZW50cyk7XG4gICAgICB0eEJ1aWxkZXIuZ2FzRGF0YShnYXNEYXRhKTtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG5cbiAgICAgIGFzc2VydCh0eCBpbnN0YW5jZW9mIFN1aVRyYW5zYWN0aW9uKTtcbiAgICAgIHR4LnR5cGUuc2hvdWxkLmVxdWFsKFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcbiAgICAgIHR4LmlucHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgdHguaW5wdXRzWzBdLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBhZGRyZXNzOiB0ZXN0RGF0YS5zZW5kZXIuYWRkcmVzcyxcbiAgICAgICAgdmFsdWU6IChhbW91bnQgKiAxMCkudG9TdHJpbmcoKSxcbiAgICAgICAgY29pbjogJ3RzdWknLFxuICAgICAgfSk7XG4gICAgICB0eC5vdXRwdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMTApO1xuICAgICAgdHgub3V0cHV0cy5mb3JFYWNoKChvdXRwdXQpID0+XG4gICAgICAgIG91dHB1dC5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgICBjb2luOiAndHN1aScsXG4gICAgICAgICAgYWRkcmVzczogdGVzdERhdGEuc2VuZGVyLmFkZHJlc3MsXG4gICAgICAgICAgdmFsdWU6IGFtb3VudC50b1N0cmluZygpLFxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICAgIHR4LnN1aVRyYW5zYWN0aW9uLmdhc0RhdGEub3duZXIuc2hvdWxkLmVxdWFsKGdhc0RhdGEub3duZXIpO1xuICAgICAgdHguc3VpVHJhbnNhY3Rpb24uZ2FzRGF0YS5wcmljZS5zaG91bGQuZXF1YWwoZ2FzRGF0YS5wcmljZSk7XG4gICAgICB0eC5zdWlUcmFuc2FjdGlvbi5nYXNEYXRhLmJ1ZGdldC5zaG91bGQuZXF1YWwoZ2FzRGF0YS5idWRnZXQpO1xuICAgICAgdHguc3VpVHJhbnNhY3Rpb24uZ2FzRGF0YS5wYXltZW50Lmxlbmd0aC5zaG91bGQuZXF1YWwoTUFYX0dBU19PQkpFQ1RTIC0gMSk7XG5cbiAgICAgIGNvbnN0IHByb2dyYW1tYWJsZVR4ID0gdHguc3VpVHJhbnNhY3Rpb24udHg7XG5cbiAgICAgIC8vIHRvdGFsIG9iamVjdHMgLSBvYmplY3RzIHNlbnQgYXMgZ2FzIHBheW1lbnQgKyBuby4gb2YgcmVjaXBpZW50IGFtb3VudHMocHVyZSlcbiAgICAgIC8vICsgbm8uIG9mIHVuaXF1ZSByZWNpcGllbnQgYWRkcmVzc2VzKGRlLWR1cGVkIG9iamVjdHMpXG4gICAgICBwcm9ncmFtbWFibGVUeC5pbnB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbChcbiAgICAgICAgbnVtYmVyT2ZQYXltZW50T2JqZWN0cyAtIChNQVhfR0FTX09CSkVDVFMgLSAxKSArIG51bWJlck9mUmVjaXBpZW50cyArIDFcbiAgICAgICk7XG4gICAgICBwcm9ncmFtbWFibGVUeC50cmFuc2FjdGlvbnNbMF0ua2luZC5zaG91bGQuZXF1YWwoJ01lcmdlQ29pbnMnKTtcbiAgICAgIHByb2dyYW1tYWJsZVR4LnRyYW5zYWN0aW9uc1swXS5zb3VyY2VzLmxlbmd0aC5zaG91bGQuZXF1YWwoTUFYX0NPTU1BTkRfQVJHUyAtIDEpO1xuICAgICAgcHJvZ3JhbW1hYmxlVHgudHJhbnNhY3Rpb25zWzFdLmtpbmQuc2hvdWxkLmVxdWFsKCdNZXJnZUNvaW5zJyk7XG4gICAgICBwcm9ncmFtbWFibGVUeC50cmFuc2FjdGlvbnNbMV0uc291cmNlcy5sZW5ndGguc2hvdWxkLmVxdWFsKFxuICAgICAgICBudW1iZXJPZlBheW1lbnRPYmplY3RzIC0gKE1BWF9DT01NQU5EX0FSR1MgLSAxKSAtIChNQVhfR0FTX09CSkVDVFMgLSAxKVxuICAgICAgKTtcblxuICAgICAgY29uc3QgcmF3VHggPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRSYXdUcmFuc2FjdGlvbihyYXdUeCksIHRydWUpO1xuICAgICAgY29uc3QgcmVidWlsZGVyID0gZmFjdG9yeS5mcm9tKHJhd1R4KTtcbiAgICAgIHJlYnVpbGRlci5hZGRTaWduYXR1cmUoeyBwdWI6IHRlc3REYXRhLnNlbmRlci5wdWJsaWNLZXkgfSwgQnVmZmVyLmZyb20odGVzdERhdGEuc2VuZGVyLnNpZ25hdHVyZUhleCkpO1xuICAgICAgY29uc3QgcmVidWlsdFR4ID0gYXdhaXQgcmVidWlsZGVyLmJ1aWxkKCk7XG4gICAgICByZWJ1aWx0VHgudG9Ccm9hZGNhc3RGb3JtYXQoKS5zaG91bGQuZXF1YWwocmF3VHgpO1xuICAgICAgcmVidWlsdFR4LnRvSnNvbigpLmdhc0RhdGEucGF5bWVudC5sZW5ndGguc2hvdWxkLmVxdWFsKG51bWJlck9mUGF5bWVudE9iamVjdHMpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnRmFpbCcsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGZhaWwgZm9yIGludmFsaWQgc2VuZGVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYnVpbGRlciA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgICBzaG91bGQoKCkgPT4gYnVpbGRlci5zZW5kZXIoJ3JhbmRvbVN0cmluZycpKS50aHJvd0Vycm9yKCdJbnZhbGlkIG9yIG1pc3Npbmcgc2VuZGVyLCBnb3Q6IHJhbmRvbVN0cmluZycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIGZvciBpbnZhbGlkIHBheVR4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYnVpbGRlciA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgICBzaG91bGQoKCkgPT4gYnVpbGRlci5zZW5kKFt0ZXN0RGF0YS5pbnZhbGlkUmVjaXBpZW50c1swXV0pKS50aHJvd0Vycm9yKFxuICAgICAgICAnSW52YWxpZCBvciBtaXNzaW5nIGFkZHJlc3MsIGdvdDogcmFuZG9tU3RyaW5nJ1xuICAgICAgKTtcbiAgICAgIHNob3VsZCgoKSA9PiBidWlsZGVyLnNlbmQoW3Rlc3REYXRhLmludmFsaWRSZWNpcGllbnRzWzFdXSkpLnRocm93RXJyb3IoJ0ludmFsaWQgcmVjaXBpZW50IGFtb3VudCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIGZvciBpbnZhbGlkIGdhc0RhdGEnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBidWlsZGVyID0gZmFjdG9yeS5nZXRUcmFuc2ZlckJ1aWxkZXIoKTtcbiAgICAgIHNob3VsZCgoKSA9PiBidWlsZGVyLmdhc0RhdGEodGVzdERhdGEuaW52YWxpZEdhc093bmVyKSkudGhyb3dFcnJvcihcbiAgICAgICAgYEludmFsaWQgZ2FzIGFkZHJlc3MgJHt0ZXN0RGF0YS5pbnZhbGlkR2FzT3duZXIub3duZXJ9YFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCBmb3IgaW52YWxpZCBnYXNCdWRnZXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBidWlsZGVyID0gZmFjdG9yeS5nZXRUcmFuc2ZlckJ1aWxkZXIoKTtcbiAgICAgIHNob3VsZCgoKSA9PiBidWlsZGVyLmdhc0RhdGEodGVzdERhdGEuaW52YWxpZEdhc0J1ZGdldCkpLnRocm93RXJyb3IoJ0ludmFsaWQgZ2FzIGJ1ZGdldCAtMScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIGZvciBpbnZhbGlkIGdhc1BheW1lbnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBidWlsZGVyID0gZmFjdG9yeS5nZXRUcmFuc2ZlckJ1aWxkZXIoKTtcbiAgICAgIGNvbnN0IGludmFsaWRHYXNQYXltZW50ID0ge1xuICAgICAgICAuLi50ZXN0RGF0YS5nYXNEYXRhV2l0aG91dEdhc1BheW1lbnQsXG4gICAgICAgIHBheW1lbnQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBvYmplY3RJZDogJycsXG4gICAgICAgICAgICB2ZXJzaW9uOiAtMSxcbiAgICAgICAgICAgIGRpZ2VzdDogJycsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgICBzaG91bGQoKCkgPT4gYnVpbGRlci5nYXNEYXRhKGludmFsaWRHYXNQYXltZW50KSkudGhyb3dFcnJvcignSW52YWxpZCBwYXltZW50LCBpbnZhbGlkIG9yIG1pc3NpbmcgdmVyc2lvbicpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19Выполнить команду
Для локальной разработки. Не используйте в интернете!