PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-coin-cspr/dist/test/unit/lib/transactionBuilder
Просмотр файла: transactionBuilder.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 _ = __importStar(require("lodash"));
const assert_1 = __importDefault(require("assert"));
const should = __importStar(require("should"));
const testData = __importStar(require("../../../fixtures/resources"));
const lib_1 = require("../../../../src/lib");
const utils_1 = require("../../../../src/lib/utils");
const constants_1 = require("../../../../src/lib/constants");
const statics_1 = require("@bitgo/statics");
describe('Casper Transaction Builder', () => {
const factory = new lib_1.TransactionBuilderFactory(statics_1.coins.get('tcspr'));
const owner1Address = new lib_1.KeyPair({ pub: testData.ACCOUNT_1.publicKey }).getAddress();
const owner2Address = new lib_1.KeyPair({ pub: testData.ACCOUNT_2.publicKey }).getAddress();
const owner3Address = new lib_1.KeyPair({ pub: testData.ACCOUNT_3.publicKey }).getAddress();
const sourceAddress = new lib_1.KeyPair({ pub: testData.ROOT_ACCOUNT.publicKey }).getAddress();
const initTransferBuilder = () => {
const txBuilder = factory.getTransferBuilder();
txBuilder.fee({ gasLimit: testData.FEE.gasLimit, gasPrice: testData.FEE.gasPrice });
txBuilder.source({ address: owner1Address });
txBuilder.to(owner2Address);
txBuilder.transferId(255);
txBuilder.amount(testData.MIN_MOTES_AMOUNT);
return txBuilder;
};
const initWalletBuilder = () => {
const txBuilder = factory.getWalletInitializationBuilder();
txBuilder.fee(testData.FEE);
txBuilder.owner(owner1Address);
txBuilder.owner(owner2Address);
txBuilder.owner(owner3Address);
txBuilder.source({ address: sourceAddress });
return txBuilder;
};
const initDelegateBuilder = () => {
const txBuilder = factory.getDelegateBuilder();
txBuilder.fee({ gasLimit: testData.FEE.gasLimit, gasPrice: testData.FEE.gasPrice });
txBuilder.source({ address: sourceAddress });
txBuilder.amount(testData.MIN_MOTES_AMOUNT);
return txBuilder;
};
const initUndelegateBuilder = () => {
const txBuilder = factory.getUndelegateBuilder();
txBuilder.fee({ gasLimit: testData.FEE.gasLimit, gasPrice: testData.FEE.gasPrice });
txBuilder.source({ address: sourceAddress });
txBuilder.amount(testData.MIN_MOTES_AMOUNT);
return txBuilder;
};
describe('should validate', () => {
it('an empty raw transaction', () => {
const txBuilder = factory.getTransferBuilder();
assert_1.default.throws(() => {
txBuilder.validateRawTransaction('');
}, (e) => e.message === testData.ERROR_EMPTY_RAW_TRANSACTION);
});
it('an invalid raw transfer transaction', () => {
const txBuilder = factory.getTransferBuilder();
assert_1.default.throws(() => {
txBuilder.validateRawTransaction(testData.INVALID_RAW_TRANSACTION);
}, (e) => e.message === testData.ERROR_JSON_PARSING);
});
it('an invalid raw wallet init transaction', () => {
const txBuilder = factory.getWalletInitializationBuilder();
assert_1.default.throws(() => {
txBuilder.validateRawTransaction(testData.INVALID_RAW_TRANSACTION);
}, (e) => e.message === testData.ERROR_JSON_PARSING);
});
it('a valid raw transfer transaction', async () => {
const builder = initTransferBuilder();
builder.sign({ key: testData.ACCOUNT_1.privateKey });
builder.sign({ key: testData.ACCOUNT_2.privateKey });
const tx = await builder.build();
const txJson = tx.toJson();
should.doesNotThrow(() => {
builder.validateRawTransaction(JSON.stringify(txJson));
});
});
it('a valid raw transfer transaction both accounts using extended keys', async () => {
const builder = initTransferBuilder();
builder.sign({ key: testData.ACCOUNT_1.xPrivateKey });
builder.sign({ key: testData.ACCOUNT_2.xPrivateKey });
const tx = await builder.build();
const txJson = tx.toJson();
should.doesNotThrow(() => {
builder.validateRawTransaction(JSON.stringify(txJson));
});
});
it('a valid raw transfer transaction one account using extended key', async () => {
const builder = initTransferBuilder();
builder.sign({ key: testData.ACCOUNT_1.xPrivateKey });
builder.sign({ key: testData.ACCOUNT_2.privateKey });
const tx = await builder.build();
const txJson = tx.toJson();
should.doesNotThrow(() => {
builder.validateRawTransaction(JSON.stringify(txJson));
});
});
it('a valid raw wallet init transaction', async () => {
const builder = initWalletBuilder();
const tx = await builder.build();
const txJson = tx.toJson();
should.doesNotThrow(() => {
builder.validateRawTransaction(JSON.stringify(txJson));
});
});
it('an invalid expiration time', async () => {
const builder = initWalletBuilder();
assert_1.default.throws(() => builder.expiration(testData.MAX_TRANSACTION_EXPIRATION + 1), (e) => e.message === testData.INVALID_TRANSACTION_EXPIRATION_MESSAGE);
});
it('should validate addresses', async function () {
// validate secp256k1 address
const builder = initTransferBuilder();
let tx = await builder.build();
let txJson = tx.toJson();
should.doesNotThrow(() => {
builder.validateAddress({ address: txJson.to });
});
// validate ed25519 address
const ed25519Address = '01513fa90c1a74c34a8958dd86055e9736edb1ead918bd4d4d750ca851946be7aa';
builder.to(ed25519Address);
tx = await builder.build();
txJson = tx.toJson();
should.doesNotThrow(() => {
builder.validateAddress({ address: txJson.to });
});
});
});
describe('signatures', function () {
it('should sign a transaction', async function () {
const builder = initWalletBuilder();
builder.sign({ key: testData.ROOT_ACCOUNT.privateKey });
const tx = (await builder.build());
should.exists(tx.casperTx.approvals[0].signer);
should.exists(tx.casperTx.approvals[0].signature);
should.equal(tx.casperTx.approvals[0].signer, sourceAddress);
const txJson = tx.toJson();
should.doesNotThrow(() => {
builder.validateRawTransaction(JSON.stringify(txJson));
});
});
it('should sign a transaction using extended key', async function () {
const builder = initWalletBuilder();
builder.sign({ key: testData.ROOT_ACCOUNT.xPrivateKey });
const tx = (await builder.build());
should.exists(tx.casperTx.approvals[0].signer);
should.exists(tx.casperTx.approvals[0].signature);
should.equal(tx.casperTx.approvals[0].signer, sourceAddress);
const txJson = tx.toJson();
should.doesNotThrow(() => {
builder.validateRawTransaction(JSON.stringify(txJson));
});
});
it('should process signing only once per signer', async function () {
const builder = initWalletBuilder();
builder.sign({ key: testData.ROOT_ACCOUNT.privateKey });
let tx = (await builder.build());
tx.casperTx.approvals.length.should.equal(1);
should.equal(tx.casperTx.approvals[0].signer, sourceAddress);
tx = (await builder.build());
tx.casperTx.approvals.length.should.equal(1);
should.equal(tx.casperTx.approvals[0].signer, sourceAddress);
});
it('should process signing only once per signer with extended key', async function () {
const builder = initWalletBuilder();
builder.sign({ key: testData.ROOT_ACCOUNT.xPrivateKey });
let tx = (await builder.build());
tx.casperTx.approvals.length.should.equal(1);
should.equal(tx.casperTx.approvals[0].signer, sourceAddress);
tx = (await builder.build());
tx.casperTx.approvals.length.should.equal(1);
should.equal(tx.casperTx.approvals[0].signer, sourceAddress);
});
it('should add a signature to a transaction', async function () {
const builder = initWalletBuilder();
const sig = '0072f40621663fd03c5e13b413d5c354cdf4c7e76672aa61fd8ede0f1ac09f5de107d725eb40e1efb9037940d74ef9b2efaa1d66d0991a5322639481c2d4280775';
const pub = '03dca7d5d68fba12a604e992a47504d10e6795cdc6db438abb741788c71c4b7428';
const signingKeyPair = new lib_1.KeyPair({ pub });
builder.signature(sig, signingKeyPair);
const tx = (await builder.build());
const signer = tx.casperTx.approvals[0].signer;
const signature = tx.casperTx.approvals[0].signature;
(0, utils_1.removeAlgoPrefixFromHexValue)(signer).should.equal(pub);
(0, utils_1.removeAlgoPrefixFromHexValue)(signature).should.equal(_.toLower(sig));
const txJson = tx.toJson();
should.doesNotThrow(() => {
builder.validateRawTransaction(JSON.stringify(txJson));
});
});
it('should add a signature to a transaction using extended key', async function () {
const builder = initWalletBuilder();
const sig = '0220ade206fc0e7bf19c672aae122e037a7c0ad6c82fb65126735e61f370923f2706114647f9ea1e405fdbf9915c7eaf4325a5ddf9faf24935b20333526cf3b44d';
const xPub = 'xpub661MyMwAqRbcH4WAWt79QwMXc1MKaqxU8axkYJGfECGg3gTMuxHYfZzW8AyrRJwFrGZxdA1CgYtXtjVToMyUyfzQrjBayP47pbdWuhdrbYz';
const signingKeyPair = new lib_1.KeyPair({ pub: xPub });
builder.signature(sig, signingKeyPair);
const tx = (await builder.build());
const signer = tx.casperTx.approvals[0].signer;
const signature = tx.casperTx.approvals[0].signature;
(0, utils_1.removeAlgoPrefixFromHexValue)(signer).should.equal(signingKeyPair.getKeys().pub);
(0, utils_1.removeAlgoPrefixFromHexValue)(signature).should.equal(_.toLower(sig));
const txJson = tx.toJson();
should.doesNotThrow(() => {
builder.validateRawTransaction(JSON.stringify(txJson));
});
});
it('should process signing only once per signature added', async function () {
const builder = initWalletBuilder();
const sig = '0072f40621663fd03c5e13b413d5c354cdf4c7e76672aa61fd8ede0f1ac09f5de107d725eb40e1efb9037940d74ef9b2efaa1d66d0991a5322639481c2d4280775';
const pub = '03dca7d5d68fba12a604e992a47504d10e6795cdc6db438abb741788c71c4b7428';
const signingKeyPair = new lib_1.KeyPair({ pub });
builder.signature(sig, signingKeyPair);
let tx = (await builder.build());
tx.casperTx.approvals.length.should.equal(1);
tx = (await builder.build());
tx.casperTx.approvals.length.should.equal(1);
});
it('should process signing only once per signature added using extended key', async function () {
const builder = initWalletBuilder();
const sig = '0220ade206fc0e7bf19c672aae122e037a7c0ad6c82fb65126735e61f370923f2706114647f9ea1e405fdbf9915c7eaf4325a5ddf9faf24935b20333526cf3b44d';
const xPub = 'xpub661MyMwAqRbcH4WAWt79QwMXc1MKaqxU8axkYJGfECGg3gTMuxHYfZzW8AyrRJwFrGZxdA1CgYtXtjVToMyUyfzQrjBayP47pbdWuhdrbYz';
const signingKeyPair = new lib_1.KeyPair({ pub: xPub });
builder.signature(sig, signingKeyPair);
let tx = (await builder.build());
tx.casperTx.approvals.length.should.equal(1);
should.equal(tx.casperTx.approvals[0].signer, sourceAddress);
tx = (await builder.build());
tx.casperTx.approvals.length.should.equal(1);
should.equal(tx.casperTx.approvals[0].signer, sourceAddress);
});
});
describe('chain name', function () {
describe('has default value for', function () {
it('transfer transaction', function () {
const txBuilder = initTransferBuilder();
should.doesNotThrow(() => txBuilder.validateMandatoryFields());
txBuilder.chainName.should.equals(constants_1.DEFAULT_CHAIN_NAMES.testnet);
});
it('wallet initialization transaction', function () {
const txBuilder = initWalletBuilder();
should.doesNotThrow(() => txBuilder.validateMandatoryFields());
txBuilder.chainName.should.equals(constants_1.DEFAULT_CHAIN_NAMES.testnet);
});
it('delegation transaction', function () {
const txBuilder = initDelegateBuilder();
should.doesNotThrow(() => txBuilder.validateMandatoryFields());
txBuilder.chainName.should.equals(constants_1.DEFAULT_CHAIN_NAMES.testnet);
});
it('undelegation transaction', function () {
const txBuilder = initUndelegateBuilder();
should.doesNotThrow(() => txBuilder.validateMandatoryFields());
txBuilder.chainName.should.equals(constants_1.DEFAULT_CHAIN_NAMES.testnet);
});
});
describe('can be manually set for', function () {
it('transfer transaction', function () {
const txBuilder = initTransferBuilder()
.amount(testData.MIN_MOTES_AMOUNT)
.nodeChainName(testData.CUSTOM_CHAIN_NAME);
should.doesNotThrow(() => txBuilder.validateMandatoryFields());
txBuilder.chainName.should.equals(testData.CUSTOM_CHAIN_NAME);
});
it('wallet initialization transaction', function () {
const txBuilder = initWalletBuilder().nodeChainName(testData.CUSTOM_CHAIN_NAME);
should.doesNotThrow(() => txBuilder.validateMandatoryFields());
txBuilder.chainName.should.equals(testData.CUSTOM_CHAIN_NAME);
});
it('delegation transaction', function () {
const txBuilder = initDelegateBuilder().nodeChainName(testData.CUSTOM_CHAIN_NAME);
should.doesNotThrow(() => txBuilder.validateMandatoryFields());
txBuilder.chainName.should.equals(testData.CUSTOM_CHAIN_NAME);
});
it('undelegation transaction', function () {
const txBuilder = initUndelegateBuilder().nodeChainName(testData.CUSTOM_CHAIN_NAME);
should.doesNotThrow(() => txBuilder.validateMandatoryFields());
txBuilder.chainName.should.equals(testData.CUSTOM_CHAIN_NAME);
});
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb25CdWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vdGVzdC91bml0L2xpYi90cmFuc2FjdGlvbkJ1aWxkZXIvdHJhbnNhY3Rpb25CdWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsMENBQTRCO0FBQzVCLG9EQUE0QjtBQUM1QiwrQ0FBaUM7QUFDakMsc0VBQXdEO0FBQ3hELDZDQUF5RTtBQUV6RSxxREFBeUU7QUFDekUsNkRBQW9FO0FBQ3BFLDRDQUF1QztBQUV2QyxRQUFRLENBQUMsNEJBQTRCLEVBQUUsR0FBRyxFQUFFO0lBQzFDLE1BQU0sT0FBTyxHQUFHLElBQUksK0JBQXlCLENBQUMsZUFBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO0lBQ2xFLE1BQU0sYUFBYSxHQUFHLElBQUksYUFBTyxDQUFDLEVBQUUsR0FBRyxFQUFFLFFBQVEsQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUN0RixNQUFNLGFBQWEsR0FBRyxJQUFJLGFBQU8sQ0FBQyxFQUFFLEdBQUcsRUFBRSxRQUFRLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDdEYsTUFBTSxhQUFhLEdBQUcsSUFBSSxhQUFPLENBQUMsRUFBRSxHQUFHLEVBQUUsUUFBUSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ3RGLE1BQU0sYUFBYSxHQUFHLElBQUksYUFBTyxDQUFDLEVBQUUsR0FBRyxFQUFFLFFBQVEsQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUV6RixNQUFNLG1CQUFtQixHQUFHLEdBQUcsRUFBRTtRQUMvQixNQUFNLFNBQVMsR0FB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QUUsQ0FBQywwQkFBMEIsRUFBRTtnQkFDN0IsTUFBTSxTQUFTLEdBQUcscUJBQXFCLEVBQUUsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLGlCQUFpQixDQUFDLENBQUM7Z0JBQ3BGLE1BQU0sQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLHVCQUF1QixFQUFFLENBQUMsQ0FBQztnQkFDL0QsU0FBUyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQ2hFLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0ICogYXMgc2hvdWxkIGZyb20gJ3Nob3VsZCc7XG5pbXBvcnQgKiBhcyB0ZXN0RGF0YSBmcm9tICcuLi8uLi8uLi9maXh0dXJlcy9yZXNvdXJjZXMnO1xuaW1wb3J0IHsgS2V5UGFpciwgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeSB9IGZyb20gJy4uLy4uLy4uLy4uL3NyYy9saWInO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb24gfSBmcm9tICcuLi8uLi8uLi8uLi9zcmMvbGliL3RyYW5zYWN0aW9uJztcbmltcG9ydCB7IHJlbW92ZUFsZ29QcmVmaXhGcm9tSGV4VmFsdWUgfSBmcm9tICcuLi8uLi8uLi8uLi9zcmMvbGliL3V0aWxzJztcbmltcG9ydCB7IERFRkFVTFRfQ0hBSU5fTkFNRVMgfSBmcm9tICcuLi8uLi8uLi8uLi9zcmMvbGliL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBjb2lucyB9IGZyb20gJ0BiaXRnby9zdGF0aWNzJztcblxuZGVzY3JpYmUoJ0Nhc3BlciBUcmFuc2FjdGlvbiBCdWlsZGVyJywgKCkgPT4ge1xuICBjb25zdCBmYWN0b3J5ID0gbmV3IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbnMuZ2V0KCd0Y3NwcicpKTtcbiAgY29uc3Qgb3duZXIxQWRkcmVzcyA9IG5ldyBLZXlQYWlyKHsgcHViOiB0ZXN0RGF0YS5BQ0NPVU5UXzEucHVibGljS2V5IH0pLmdldEFkZHJlc3MoKTtcbiAgY29uc3Qgb3duZXIyQWRkcmVzcyA9IG5ldyBLZXlQYWlyKHsgcHViOiB0ZXN0RGF0YS5BQ0NPVU5UXzIucHVibGljS2V5IH0pLmdldEFkZHJlc3MoKTtcbiAgY29uc3Qgb3duZXIzQWRkcmVzcyA9IG5ldyBLZXlQYWlyKHsgcHViOiB0ZXN0RGF0YS5BQ0NPVU5UXzMucHVibGljS2V5IH0pLmdldEFkZHJlc3MoKTtcbiAgY29uc3Qgc291cmNlQWRkcmVzcyA9IG5ldyBLZXlQYWlyKHsgcHViOiB0ZXN0RGF0YS5ST09UX0FDQ09VTlQucHVibGljS2V5IH0pLmdldEFkZHJlc3MoKTtcblxuICBjb25zdCBpbml0VHJhbnNmZXJCdWlsZGVyID0gKCkgPT4ge1xuICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgdHhCdWlsZGVyLmZlZSh7IGdhc0xpbWl0OiB0ZXN0RGF0YS5GRUUuZ2FzTGltaXQsIGdhc1ByaWNlOiB0ZXN0RGF0YS5GRUUuZ2FzUHJpY2UgfSk7XG4gICAgdHhCdWlsZGVyLnNvdXJjZSh7IGFkZHJlc3M6IG93bmVyMUFkZHJlc3MgfSk7XG4gICAgdHhCdWlsZGVyLnRvKG93bmVyMkFkZHJlc3MpO1xuICAgIHR4QnVpbGRlci50cmFuc2ZlcklkKDI1NSk7XG4gICAgdHhCdWlsZGVyLmFtb3VudCh0ZXN0RGF0YS5NSU5fTU9URVNfQU1PVU5UKTtcbiAgICByZXR1cm4gdHhCdWlsZGVyO1xuICB9O1xuXG4gIGNvbnN0IGluaXRXYWxsZXRCdWlsZGVyID0gKCkgPT4ge1xuICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0V2FsbGV0SW5pdGlhbGl6YXRpb25CdWlsZGVyKCk7XG4gICAgdHhCdWlsZGVyLmZlZSh0ZXN0RGF0YS5GRUUpO1xuICAgIHR4QnVpbGRlci5vd25lcihvd25lcjFBZGRyZXNzKTtcbiAgICB0eEJ1aWxkZXIub3duZXIob3duZXIyQWRkcmVzcyk7XG4gICAgdHhCdWlsZGVyLm93bmVyKG93bmVyM0FkZHJlc3MpO1xuICAgIHR4QnVpbGRlci5zb3VyY2UoeyBhZGRyZXNzOiBzb3VyY2VBZGRyZXNzIH0pO1xuICAgIHJldHVybiB0eEJ1aWxkZXI7XG4gIH07XG5cbiAgY29uc3QgaW5pdERlbGVnYXRlQnVpbGRlciA9ICgpID0+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldERlbGVnYXRlQnVpbGRlcigpO1xuICAgIHR4QnVpbGRlci5mZWUoeyBnYXNMaW1pdDogdGVzdERhdGEuRkVFLmdhc0xpbWl0LCBnYXNQcmljZTogdGVzdERhdGEuRkVFLmdhc1ByaWNlIH0pO1xuICAgIHR4QnVpbGRlci5zb3VyY2UoeyBhZGRyZXNzOiBzb3VyY2VBZGRyZXNzIH0pO1xuICAgIHR4QnVpbGRlci5hbW91bnQodGVzdERhdGEuTUlOX01PVEVTX0FNT1VOVCk7XG4gICAgcmV0dXJuIHR4QnVpbGRlcjtcbiAgfTtcblxuICBjb25zdCBpbml0VW5kZWxlZ2F0ZUJ1aWxkZXIgPSAoKSA9PiB7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRVbmRlbGVnYXRlQnVpbGRlcigpO1xuICAgIHR4QnVpbGRlci5mZWUoeyBnYXNMaW1pdDogdGVzdERhdGEuRkVFLmdhc0xpbWl0LCBnYXNQcmljZTogdGVzdERhdGEuRkVFLmdhc1ByaWNlIH0pO1xuICAgIHR4QnVpbGRlci5zb3VyY2UoeyBhZGRyZXNzOiBzb3VyY2VBZGRyZXNzIH0pO1xuICAgIHR4QnVpbGRlci5hbW91bnQodGVzdERhdGEuTUlOX01PVEVTX0FNT1VOVCk7XG4gICAgcmV0dXJuIHR4QnVpbGRlcjtcbiAgfTtcblxuICBkZXNjcmliZSgnc2hvdWxkIHZhbGlkYXRlJywgKCkgPT4ge1xuICAgIGl0KCdhbiBlbXB0eSByYXcgdHJhbnNhY3Rpb24nLCAoKSA9PiB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHR4QnVpbGRlci52YWxpZGF0ZVJhd1RyYW5zYWN0aW9uKCcnKTtcbiAgICAgICAgfSxcbiAgICAgICAgKGU6IEVycm9yKSA9PiBlLm1lc3NhZ2UgPT09IHRlc3REYXRhLkVSUk9SX0VNUFRZX1JBV19UUkFOU0FDVElPTlxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdhbiBpbnZhbGlkIHJhdyB0cmFuc2ZlciB0cmFuc2FjdGlvbicsICgpID0+IHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdHhCdWlsZGVyLnZhbGlkYXRlUmF3VHJhbnNhY3Rpb24odGVzdERhdGEuSU5WQUxJRF9SQVdfVFJBTlNBQ1RJT04pO1xuICAgICAgICB9LFxuICAgICAgICAoZTogRXJyb3IpID0+IGUubWVzc2FnZSA9PT0gdGVzdERhdGEuRVJST1JfSlNPTl9QQVJTSU5HXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ2FuIGludmFsaWQgcmF3IHdhbGxldCBpbml0IHRyYW5zYWN0aW9uJywgKCkgPT4ge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRXYWxsZXRJbml0aWFsaXphdGlvbkJ1aWxkZXIoKTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0eEJ1aWxkZXIudmFsaWRhdGVSYXdUcmFuc2FjdGlvbih0ZXN0RGF0YS5JTlZBTElEX1JBV19UUkFOU0FDVElPTik7XG4gICAgICAgIH0sXG4gICAgICAgIChlOiBFcnJvcikgPT4gZS5tZXNzYWdlID09PSB0ZXN0RGF0YS5FUlJPUl9KU09OX1BBUlNJTkdcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnYSB2YWxpZCByYXcgdHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBidWlsZGVyID0gaW5pdFRyYW5zZmVyQnVpbGRlcigpO1xuICAgICAgYnVpbGRlci5zaWduKHsga2V5OiB0ZXN0RGF0YS5BQ0NPVU5UXzEucHJpdmF0ZUtleSB9KTtcbiAgICAgIGJ1aWxkZXIuc2lnbih7IGtleTogdGVzdERhdGEuQUNDT1VOVF8yLnByaXZhdGVLZXkgfSk7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IGJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiB7XG4gICAgICAgIGJ1aWxkZXIudmFsaWRhdGVSYXdUcmFuc2FjdGlvbihKU09OLnN0cmluZ2lmeSh0eEpzb24pKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2EgdmFsaWQgcmF3IHRyYW5zZmVyIHRyYW5zYWN0aW9uIGJvdGggYWNjb3VudHMgdXNpbmcgZXh0ZW5kZWQga2V5cycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBpbml0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgICBidWlsZGVyLnNpZ24oeyBrZXk6IHRlc3REYXRhLkFDQ09VTlRfMS54UHJpdmF0ZUtleSB9KTtcbiAgICAgIGJ1aWxkZXIuc2lnbih7IGtleTogdGVzdERhdGEuQUNDT1VOVF8yLnhQcml2YXRlS2V5IH0pO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCBidWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT4ge1xuICAgICAgICBidWlsZGVyLnZhbGlkYXRlUmF3VHJhbnNhY3Rpb24oSlNPTi5zdHJpbmdpZnkodHhKc29uKSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdhIHZhbGlkIHJhdyB0cmFuc2ZlciB0cmFuc2FjdGlvbiBvbmUgYWNjb3VudCB1c2luZyBleHRlbmRlZCBrZXknLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBidWlsZGVyID0gaW5pdFRyYW5zZmVyQnVpbGRlcigpO1xuICAgICAgYnVpbGRlci5zaWduKHsga2V5OiB0ZXN0RGF0YS5BQ0NPVU5UXzEueFByaXZhdGVLZXkgfSk7XG4gICAgICBidWlsZGVyLnNpZ24oeyBrZXk6IHRlc3REYXRhLkFDQ09VTlRfMi5wcml2YXRlS2V5IH0pO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCBidWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT4ge1xuICAgICAgICBidWlsZGVyLnZhbGlkYXRlUmF3VHJhbnNhY3Rpb24oSlNPTi5zdHJpbmdpZnkodHhKc29uKSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdhIHZhbGlkIHJhdyB3YWxsZXQgaW5pdCB0cmFuc2FjdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBpbml0V2FsbGV0QnVpbGRlcigpO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCBidWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT4ge1xuICAgICAgICBidWlsZGVyLnZhbGlkYXRlUmF3VHJhbnNhY3Rpb24oSlNPTi5zdHJpbmdpZnkodHhKc29uKSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdhbiBpbnZhbGlkIGV4cGlyYXRpb24gdGltZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBpbml0V2FsbGV0QnVpbGRlcigpO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4gYnVpbGRlci5leHBpcmF0aW9uKHRlc3REYXRhLk1BWF9UUkFOU0FDVElPTl9FWFBJUkFUSU9OICsgMSksXG4gICAgICAgIChlOiBFcnJvcikgPT4gZS5tZXNzYWdlID09PSB0ZXN0RGF0YS5JTlZBTElEX1RSQU5TQUNUSU9OX0VYUElSQVRJT05fTUVTU0FHRVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgYWRkcmVzc2VzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gdmFsaWRhdGUgc2VjcDI1NmsxIGFkZHJlc3NcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBpbml0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgICBsZXQgdHggPSBhd2FpdCBidWlsZGVyLmJ1aWxkKCk7XG4gICAgICBsZXQgdHhKc29uID0gdHgudG9Kc29uKCk7XG4gICAgICBzaG91bGQuZG9lc05vdFRocm93KCgpID0+IHtcbiAgICAgICAgYnVpbGRlci52YWxpZGF0ZUFkZHJlc3MoeyBhZGRyZXNzOiB0eEpzb24udG8gfSk7XG4gICAgICB9KTtcblxuICAgICAgLy8gdmFsaWRhdGUgZWQyNTUxOSBhZGRyZXNzXG4gICAgICBjb25zdCBlZDI1NTE5QWRkcmVzcyA9ICcwMTUxM2ZhOTBjMWE3NGMzNGE4OTU4ZGQ4NjA1NWU5NzM2ZWRiMWVhZDkxOGJkNGQ0ZDc1MGNhODUxOTQ2YmU3YWEnO1xuICAgICAgYnVpbGRlci50byhlZDI1NTE5QWRkcmVzcyk7XG4gICAgICB0eCA9IGF3YWl0IGJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiB7XG4gICAgICAgIGJ1aWxkZXIudmFsaWRhdGVBZGRyZXNzKHsgYWRkcmVzczogdHhKc29uLnRvIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdzaWduYXR1cmVzJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgc2lnbiBhIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYnVpbGRlciA9IGluaXRXYWxsZXRCdWlsZGVyKCk7XG4gICAgICBidWlsZGVyLnNpZ24oeyBrZXk6IHRlc3REYXRhLlJPT1RfQUNDT1VOVC5wcml2YXRlS2V5IH0pO1xuICAgICAgY29uc3QgdHggPSAoYXdhaXQgYnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgICAgIHNob3VsZC5leGlzdHModHguY2FzcGVyVHguYXBwcm92YWxzWzBdLnNpZ25lcik7XG4gICAgICBzaG91bGQuZXhpc3RzKHR4LmNhc3BlclR4LmFwcHJvdmFsc1swXS5zaWduYXR1cmUpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4LmNhc3BlclR4LmFwcHJvdmFsc1swXS5zaWduZXIsIHNvdXJjZUFkZHJlc3MpO1xuXG4gICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT4ge1xuICAgICAgICBidWlsZGVyLnZhbGlkYXRlUmF3VHJhbnNhY3Rpb24oSlNPTi5zdHJpbmdpZnkodHhKc29uKSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2lnbiBhIHRyYW5zYWN0aW9uIHVzaW5nIGV4dGVuZGVkIGtleScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBpbml0V2FsbGV0QnVpbGRlcigpO1xuICAgICAgYnVpbGRlci5zaWduKHsga2V5OiB0ZXN0RGF0YS5ST09UX0FDQ09VTlQueFByaXZhdGVLZXkgfSk7XG4gICAgICBjb25zdCB0eCA9IChhd2FpdCBidWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuICAgICAgc2hvdWxkLmV4aXN0cyh0eC5jYXNwZXJUeC5hcHByb3ZhbHNbMF0uc2lnbmVyKTtcbiAgICAgIHNob3VsZC5leGlzdHModHguY2FzcGVyVHguYXBwcm92YWxzWzBdLnNpZ25hdHVyZSk7XG4gICAgICBzaG91bGQuZXF1YWwodHguY2FzcGVyVHguYXBwcm92YWxzWzBdLnNpZ25lciwgc291cmNlQWRkcmVzcyk7XG5cbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiB7XG4gICAgICAgIGJ1aWxkZXIudmFsaWRhdGVSYXdUcmFuc2FjdGlvbihKU09OLnN0cmluZ2lmeSh0eEpzb24pKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9jZXNzIHNpZ25pbmcgb25seSBvbmNlIHBlciBzaWduZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBidWlsZGVyID0gaW5pdFdhbGxldEJ1aWxkZXIoKTtcbiAgICAgIGJ1aWxkZXIuc2lnbih7IGtleTogdGVzdERhdGEuUk9PVF9BQ0NPVU5ULnByaXZhdGVLZXkgfSk7XG4gICAgICBsZXQgdHggPSAoYXdhaXQgYnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgICAgIHR4LmNhc3BlclR4LmFwcHJvdmFscy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4LmNhc3BlclR4LmFwcHJvdmFsc1swXS5zaWduZXIsIHNvdXJjZUFkZHJlc3MpO1xuXG4gICAgICB0eCA9IChhd2FpdCBidWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuICAgICAgdHguY2FzcGVyVHguYXBwcm92YWxzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICBzaG91bGQuZXF1YWwodHguY2FzcGVyVHguYXBwcm92YWxzWzBdLnNpZ25lciwgc291cmNlQWRkcmVzcyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByb2Nlc3Mgc2lnbmluZyBvbmx5IG9uY2UgcGVyIHNpZ25lciB3aXRoIGV4dGVuZGVkIGtleScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBpbml0V2FsbGV0QnVpbGRlcigpO1xuICAgICAgYnVpbGRlci5zaWduKHsga2V5OiB0ZXN0RGF0YS5ST09UX0FDQ09VTlQueFByaXZhdGVLZXkgfSk7XG4gICAgICBsZXQgdHggPSAoYXdhaXQgYnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgICAgIHR4LmNhc3BlclR4LmFwcHJvdmFscy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4LmNhc3BlclR4LmFwcHJvdmFsc1swXS5zaWduZXIsIHNvdXJjZUFkZHJlc3MpO1xuXG4gICAgICB0eCA9IChhd2FpdCBidWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuICAgICAgdHguY2FzcGVyVHguYXBwcm92YWxzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICBzaG91bGQuZXF1YWwodHguY2FzcGVyVHguYXBwcm92YWxzWzBdLnNpZ25lciwgc291cmNlQWRkcmVzcyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFkZCBhIHNpZ25hdHVyZSB0byBhIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYnVpbGRlciA9IGluaXRXYWxsZXRCdWlsZGVyKCk7XG4gICAgICBjb25zdCBzaWcgPVxuICAgICAgICAnMDA3MmY0MDYyMTY2M2ZkMDNjNWUxM2I0MTNkNWMzNTRjZGY0YzdlNzY2NzJhYTYxZmQ4ZWRlMGYxYWMwOWY1ZGUxMDdkNzI1ZWI0MGUxZWZiOTAzNzk0MGQ3NGVmOWIyZWZhYTFkNjZkMDk5MWE1MzIyNjM5NDgxYzJkNDI4MDc3NSc7XG4gICAgICBjb25zdCBwdWIgPSAnMDNkY2E3ZDVkNjhmYmExMmE2MDRlOTkyYTQ3NTA0ZDEwZTY3OTVjZGM2ZGI0MzhhYmI3NDE3ODhjNzFjNGI3NDI4JztcbiAgICAgIGNvbnN0IHNpZ25pbmdLZXlQYWlyID0gbmV3IEtleVBhaXIoeyBwdWIgfSk7XG4gICAgICBidWlsZGVyLnNpZ25hdHVyZShzaWcsIHNpZ25pbmdLZXlQYWlyKTtcbiAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IGJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNhY3Rpb247XG4gICAgICBjb25zdCBzaWduZXIgPSB0eC5jYXNwZXJUeC5hcHByb3ZhbHNbMF0uc2lnbmVyO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gdHguY2FzcGVyVHguYXBwcm92YWxzWzBdLnNpZ25hdHVyZTtcblxuICAgICAgcmVtb3ZlQWxnb1ByZWZpeEZyb21IZXhWYWx1ZShzaWduZXIpLnNob3VsZC5lcXVhbChwdWIpO1xuICAgICAgcmVtb3ZlQWxnb1ByZWZpeEZyb21IZXhWYWx1ZShzaWduYXR1cmUpLnNob3VsZC5lcXVhbChfLnRvTG93ZXIoc2lnKSk7XG5cbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiB7XG4gICAgICAgIGJ1aWxkZXIudmFsaWRhdGVSYXdUcmFuc2FjdGlvbihKU09OLnN0cmluZ2lmeSh0eEpzb24pKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhZGQgYSBzaWduYXR1cmUgdG8gYSB0cmFuc2FjdGlvbiB1c2luZyBleHRlbmRlZCBrZXknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBidWlsZGVyID0gaW5pdFdhbGxldEJ1aWxkZXIoKTtcbiAgICAgIGNvbnN0IHNpZyA9XG4gICAgICAgICcwMjIwYWRlMjA2ZmMwZTdiZjE5YzY3MmFhZTEyMmUwMzdhN2MwYWQ2YzgyZmI2NTEyNjczNWU2MWYzNzA5MjNmMjcwNjExNDY0N2Y5ZWExZTQwNWZkYmY5OTE1YzdlYWY0MzI1YTVkZGY5ZmFmMjQ5MzViMjAzMzM1MjZjZjNiNDRkJztcbiAgICAgIGNvbnN0IHhQdWIgPVxuICAgICAgICAneHB1YjY2MU15TXdBcVJiY0g0V0FXdDc5UXdNWGMxTUthcXhVOGF4a1lKR2ZFQ0dnM2dUTXV4SFlmWnpXOEF5clJKd0ZyR1p4ZEExQ2dZdFh0alZUb015VXlmelFyakJheVA0N3BiZFd1aGRyYll6JztcbiAgICAgIGNvbnN0IHNpZ25pbmdLZXlQYWlyID0gbmV3IEtleVBhaXIoeyBwdWI6IHhQdWIgfSk7XG4gICAgICBidWlsZGVyLnNpZ25hdHVyZShzaWcsIHNpZ25pbmdLZXlQYWlyKTtcbiAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IGJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNhY3Rpb247XG4gICAgICBjb25zdCBzaWduZXIgPSB0eC5jYXNwZXJUeC5hcHByb3ZhbHNbMF0uc2lnbmVyO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gdHguY2FzcGVyVHguYXBwcm92YWxzWzBdLnNpZ25hdHVyZTtcblxuICAgICAgcmVtb3ZlQWxnb1ByZWZpeEZyb21IZXhWYWx1ZShzaWduZXIpLnNob3VsZC5lcXVhbChzaWduaW5nS2V5UGFpci5nZXRLZXlzKCkucHViKTtcbiAgICAgIHJlbW92ZUFsZ29QcmVmaXhGcm9tSGV4VmFsdWUoc2lnbmF0dXJlKS5zaG91bGQuZXF1YWwoXy50b0xvd2VyKHNpZykpO1xuXG4gICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT4ge1xuICAgICAgICBidWlsZGVyLnZhbGlkYXRlUmF3VHJhbnNhY3Rpb24oSlNPTi5zdHJpbmdpZnkodHhKc29uKSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcHJvY2VzcyBzaWduaW5nIG9ubHkgb25jZSBwZXIgc2lnbmF0dXJlIGFkZGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYnVpbGRlciA9IGluaXRXYWxsZXRCdWlsZGVyKCk7XG4gICAgICBjb25zdCBzaWcgPVxuICAgICAgICAnMDA3MmY0MDYyMTY2M2ZkMDNjNWUxM2I0MTNkNWMzNTRjZGY0YzdlNzY2NzJhYTYxZmQ4ZWRlMGYxYWMwOWY1ZGUxMDdkNzI1ZWI0MGUxZWZiOTAzNzk0MGQ3NGVmOWIyZWZhYTFkNjZkMDk5MWE1MzIyNjM5NDgxYzJkNDI4MDc3NSc7XG4gICAgICBjb25zdCBwdWIgPSAnMDNkY2E3ZDVkNjhmYmExMmE2MDRlOTkyYTQ3NTA0ZDEwZTY3OTVjZGM2ZGI0MzhhYmI3NDE3ODhjNzFjNGI3NDI4JztcbiAgICAgIGNvbnN0IHNpZ25pbmdLZXlQYWlyID0gbmV3IEtleVBhaXIoeyBwdWIgfSk7XG4gICAgICBidWlsZGVyLnNpZ25hdHVyZShzaWcsIHNpZ25pbmdLZXlQYWlyKTtcbiAgICAgIGxldCB0eCA9IChhd2FpdCBidWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuICAgICAgdHguY2FzcGVyVHguYXBwcm92YWxzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG5cbiAgICAgIHR4ID0gKGF3YWl0IGJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNhY3Rpb247XG4gICAgICB0eC5jYXNwZXJUeC5hcHByb3ZhbHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcHJvY2VzcyBzaWduaW5nIG9ubHkgb25jZSBwZXIgc2lnbmF0dXJlIGFkZGVkIHVzaW5nIGV4dGVuZGVkIGtleScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBpbml0V2FsbGV0QnVpbGRlcigpO1xuICAgICAgY29uc3Qgc2lnID1cbiAgICAgICAgJzAyMjBhZGUyMDZmYzBlN2JmMTljNjcyYWFlMTIyZTAzN2E3YzBhZDZjODJmYjY1MTI2NzM1ZTYxZjM3MDkyM2YyNzA2MTE0NjQ3ZjllYTFlNDA1ZmRiZjk5MTVjN2VhZjQzMjVhNWRkZjlmYWYyNDkzNWIyMDMzMzUyNmNmM2I0NGQnO1xuICAgICAgY29uc3QgeFB1YiA9XG4gICAgICAgICd4cHViNjYxTXlNd0FxUmJjSDRXQVd0NzlRd01YYzFNS2FxeFU4YXhrWUpHZkVDR2czZ1RNdXhIWWZaelc4QXlyUkp3RnJHWnhkQTFDZ1l0WHRqVlRvTXlVeWZ6UXJqQmF5UDQ3cGJkV3VoZHJiWXonO1xuICAgICAgY29uc3Qgc2lnbmluZ0tleVBhaXIgPSBuZXcgS2V5UGFpcih7IHB1YjogeFB1YiB9KTtcbiAgICAgIGJ1aWxkZXIuc2lnbmF0dXJlKHNpZywgc2lnbmluZ0tleVBhaXIpO1xuICAgICAgbGV0IHR4ID0gKGF3YWl0IGJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNhY3Rpb247XG4gICAgICB0eC5jYXNwZXJUeC5hcHByb3ZhbHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eC5jYXNwZXJUeC5hcHByb3ZhbHNbMF0uc2lnbmVyLCBzb3VyY2VBZGRyZXNzKTtcblxuICAgICAgdHggPSAoYXdhaXQgYnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgICAgIHR4LmNhc3BlclR4LmFwcHJvdmFscy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4LmNhc3BlclR4LmFwcHJvdmFsc1swXS5zaWduZXIsIHNvdXJjZUFkZHJlc3MpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnY2hhaW4gbmFtZScsIGZ1bmN0aW9uICgpIHtcbiAgICBkZXNjcmliZSgnaGFzIGRlZmF1bHQgdmFsdWUgZm9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3RyYW5zZmVyIHRyYW5zYWN0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBpbml0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT4gdHhCdWlsZGVyLnZhbGlkYXRlTWFuZGF0b3J5RmllbGRzKCkpO1xuICAgICAgICB0eEJ1aWxkZXIuY2hhaW5OYW1lLnNob3VsZC5lcXVhbHMoREVGQVVMVF9DSEFJTl9OQU1FUy50ZXN0bmV0KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnd2FsbGV0IGluaXRpYWxpemF0aW9uIHRyYW5zYWN0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBpbml0V2FsbGV0QnVpbGRlcigpO1xuICAgICAgICBzaG91bGQuZG9lc05vdFRocm93KCgpID0+IHR4QnVpbGRlci52YWxpZGF0ZU1hbmRhdG9yeUZpZWxkcygpKTtcbiAgICAgICAgdHhCdWlsZGVyLmNoYWluTmFtZS5zaG91bGQuZXF1YWxzKERFRkFVTFRfQ0hBSU5fTkFNRVMudGVzdG5ldCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ2RlbGVnYXRpb24gdHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGluaXREZWxlZ2F0ZUJ1aWxkZXIoKTtcbiAgICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiB0eEJ1aWxkZXIudmFsaWRhdGVNYW5kYXRvcnlGaWVsZHMoKSk7XG4gICAgICAgIHR4QnVpbGRlci5jaGFpbk5hbWUuc2hvdWxkLmVxdWFscyhERUZBVUxUX0NIQUlOX05BTUVTLnRlc3RuZXQpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCd1bmRlbGVnYXRpb24gdHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGluaXRVbmRlbGVnYXRlQnVpbGRlcigpO1xuICAgICAgICBzaG91bGQuZG9lc05vdFRocm93KCgpID0+IHR4QnVpbGRlci52YWxpZGF0ZU1hbmRhdG9yeUZpZWxkcygpKTtcbiAgICAgICAgdHhCdWlsZGVyLmNoYWluTmFtZS5zaG91bGQuZXF1YWxzKERFRkFVTFRfQ0hBSU5fTkFNRVMudGVzdG5ldCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBkZXNjcmliZSgnY2FuIGJlIG1hbnVhbGx5IHNldCBmb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgndHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGluaXRUcmFuc2ZlckJ1aWxkZXIoKVxuICAgICAgICAgIC5hbW91bnQodGVzdERhdGEuTUlOX01PVEVTX0FNT1VOVClcbiAgICAgICAgICAubm9kZUNoYWluTmFtZSh0ZXN0RGF0YS5DVVNUT01fQ0hBSU5fTkFNRSk7XG4gICAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT4gdHhCdWlsZGVyLnZhbGlkYXRlTWFuZGF0b3J5RmllbGRzKCkpO1xuICAgICAgICB0eEJ1aWxkZXIuY2hhaW5OYW1lLnNob3VsZC5lcXVhbHModGVzdERhdGEuQ1VTVE9NX0NIQUlOX05BTUUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCd3YWxsZXQgaW5pdGlhbGl6YXRpb24gdHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGluaXRXYWxsZXRCdWlsZGVyKCkubm9kZUNoYWluTmFtZSh0ZXN0RGF0YS5DVVNUT01fQ0hBSU5fTkFNRSk7XG4gICAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT4gdHhCdWlsZGVyLnZhbGlkYXRlTWFuZGF0b3J5RmllbGRzKCkpO1xuICAgICAgICB0eEJ1aWxkZXIuY2hhaW5OYW1lLnNob3VsZC5lcXVhbHModGVzdERhdGEuQ1VTVE9NX0NIQUlOX05BTUUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdkZWxlZ2F0aW9uIHRyYW5zYWN0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBpbml0RGVsZWdhdGVCdWlsZGVyKCkubm9kZUNoYWluTmFtZSh0ZXN0RGF0YS5DVVNUT01fQ0hBSU5fTkFNRSk7XG4gICAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT4gdHhCdWlsZGVyLnZhbGlkYXRlTWFuZGF0b3J5RmllbGRzKCkpO1xuICAgICAgICB0eEJ1aWxkZXIuY2hhaW5OYW1lLnNob3VsZC5lcXVhbHModGVzdERhdGEuQ1VTVE9NX0NIQUlOX05BTUUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCd1bmRlbGVnYXRpb24gdHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGluaXRVbmRlbGVnYXRlQnVpbGRlcigpLm5vZGVDaGFpbk5hbWUodGVzdERhdGEuQ1VTVE9NX0NIQUlOX05BTUUpO1xuICAgICAgICBzaG91bGQuZG9lc05vdFRocm93KCgpID0+IHR4QnVpbGRlci52YWxpZGF0ZU1hbmRhdG9yeUZpZWxkcygpKTtcbiAgICAgICAgdHhCdWlsZGVyLmNoYWluTmFtZS5zaG91bGQuZXF1YWxzKHRlc3REYXRhLkNVU1RPTV9DSEFJTl9OQU1FKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19Выполнить команду
Для локальной разработки. Не используйте в интернете!