PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-coin-ada/dist/test/unit
Просмотр файла: 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 should_1 = __importDefault(require("should"));
const sdk_core_1 = require("@bitgo/sdk-core");
const testData = __importStar(require("../resources"));
const src_1 = require("../../src");
const statics_1 = require("@bitgo/statics");
const CardanoWasm = __importStar(require("@emurgo/cardano-serialization-lib-nodejs"));
const transaction_1 = require("../../src/lib/transaction");
describe('ADA Transaction Builder', async () => {
const factory = new src_1.TransactionBuilderFactory(statics_1.coins.get('tada'));
it('start and build an unsigned transfer tx for byron address', async () => {
const txBuilder = factory.getTransferBuilder();
txBuilder.input({
transaction_id: '1b53331e069a6e58fe77919d30c0cf299d13a2f5b3d9970ce473c1a66d71bf03',
transaction_index: 1,
});
const outputAmount = 200000000;
txBuilder.output({
address: testData.rawTxByron.outputAddress1.address,
amount: outputAmount.toString(),
});
const totalInput = 999600000;
txBuilder.changeAddress(testData.rawTxByron.outputAddress2.address, totalInput.toString());
txBuilder.ttl(800000000);
// txBuilder.fee('200000');
const tx = (await txBuilder.build());
should_1.default.equal(tx.type, sdk_core_1.TransactionType.Send);
const txData = tx.toJson();
txData.witnesses.length.should.equal(0);
txData.certs.length.should.equal(0);
txData.withdrawals.length.should.equal(0);
txData.outputs.length.should.equal(2);
txData.outputs[0].address.should.equal(testData.rawTxByron.outputAddress1.address);
txData.outputs[1].address.should.equal(testData.rawTxByron.outputAddress2.address);
const fee = tx.getFee;
txData.outputs[1].amount.should.equal((totalInput - outputAmount - Number(fee)).toString());
fee.should.equal('167437');
txData.id.should.equal(testData.rawTxByron.txHash2);
const txBroadcast = tx.toBroadcastFormat();
should_1.default.equal(txBroadcast, testData.rawTxByron.unsignedTx2);
});
it('start and build an unsigned transfer tx for shelley address', async () => {
const txBuilder = factory.getTransferBuilder();
txBuilder.input({
transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21',
transaction_index: 1,
});
const outputAmount = 7823121;
txBuilder.output({
address: testData.rawTx.outputAddress1.address,
amount: outputAmount.toString(),
});
const totalInput = 21032023;
txBuilder.changeAddress(testData.rawTx.outputAddress2.address, totalInput.toString());
txBuilder.ttl(800000000);
const tx = (await txBuilder.build());
should_1.default.equal(tx.type, sdk_core_1.TransactionType.Send);
const txData = tx.toJson();
txData.witnesses.length.should.equal(0);
txData.certs.length.should.equal(0);
txData.withdrawals.length.should.equal(0);
txData.outputs.length.should.equal(2);
txData.outputs[0].address.should.equal(testData.rawTx.outputAddress1.address);
txData.outputs[1].address.should.equal(testData.rawTx.outputAddress2.address);
const fee = tx.getFee;
txData.outputs[1].amount.should.equal((totalInput - outputAmount - Number(fee)).toString());
fee.should.equal('167173');
txData.id.should.equal(testData.rawTx.txHash2);
const txBroadcast = tx.toBroadcastFormat();
should_1.default.equal(txBroadcast, testData.rawTx.unsignedTx2);
});
it('should build a consolidate tx with no asset', async () => {
const txBuilder = factory.getTransferBuilder();
txBuilder.input({
transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21',
transaction_index: 1,
});
const outputAmount = 0;
const totalInput = 20000000;
txBuilder.changeAddress(testData.rawTx.outputAddress1.address, totalInput.toString());
txBuilder.ttl(800000000);
const tx = (await txBuilder.build());
should_1.default.equal(tx.type, sdk_core_1.TransactionType.Send);
const txData = tx.toJson();
txData.witnesses.length.should.equal(0);
txData.certs.length.should.equal(0);
txData.withdrawals.length.should.equal(0);
txData.outputs.length.should.equal(1);
txData.outputs[0].address.should.equal(testData.rawTx.outputAddress1.address);
const fee = tx.getFee;
txData.outputs[0].amount.should.equal((totalInput - outputAmount - Number(fee)).toString());
fee.should.equal('165545');
txData.id.should.equal(testData.rawTx.txHash5);
const txBroadcast = tx.toBroadcastFormat();
should_1.default.equal(txBroadcast, testData.rawTx.unsignedTx5);
});
it('should initialize and build tx with asset data', async () => {
const policyId = 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72';
const assetName = '4d494e';
const quantity = '2000000';
const preBuiltTx = new transaction_1.Transaction(statics_1.coins.get('tada'));
preBuiltTx.fromRawTransaction(testData.rawTx.unsignedTx3);
const txBuilder = factory.getTransferBuilder();
txBuilder.initBuilder(preBuiltTx);
const tx = (await txBuilder.build());
const txData = tx.toJson();
const expectedAssetName = CardanoWasm.AssetName.new(Buffer.from(assetName, 'hex'));
const expectedPolicyId = CardanoWasm.ScriptHash.from_bytes(Buffer.from(policyId, 'hex'));
txData.outputs[0].should.have.property('multiAssets');
txData.outputs[0].multiAssets
.get_asset(expectedPolicyId, expectedAssetName)
.to_str()
.should.equal(quantity);
txData.id.should.equal(testData.rawTx.txHash3);
const txBroadcast = tx.toBroadcastFormat();
should_1.default.equal(txBroadcast, testData.rawTx.unsignedTx3);
});
it('should build a consolidate tx with single asset', async () => {
const txBuilder = factory.getTransferBuilder();
txBuilder.input({
transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21',
transaction_index: 1,
});
const outputAmount = 0;
const policyId = 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72';
const assetName = '4d494e';
const quantity = '2000000';
txBuilder.assets({
policy_id: policyId,
asset_name: assetName,
quantity: quantity,
});
const minAmountForSingleAsset = 1500000;
const totalInput = 20000000;
txBuilder.changeAddress(testData.rawTx.outputAddress1.address, totalInput.toString());
txBuilder.ttl(800000000);
const tx = (await txBuilder.build());
should_1.default.equal(tx.type, sdk_core_1.TransactionType.Send);
const txData = tx.toJson();
txData.witnesses.length.should.equal(0);
txData.certs.length.should.equal(0);
txData.withdrawals.length.should.equal(0);
txData.outputs.length.should.equal(2);
txData.outputs[0].address.should.equal(testData.rawTx.outputAddress1.address);
txData.outputs[1].address.should.equal(testData.rawTx.outputAddress1.address);
// token assertion
const expectedAssetName = CardanoWasm.AssetName.new(Buffer.from(assetName, 'hex'));
const expectedPolicyId = CardanoWasm.ScriptHash.from_bytes(Buffer.from(policyId, 'hex'));
txData.outputs[0].amount.should.equal(minAmountForSingleAsset.toString());
txData.outputs[0].should.have.property('multiAssets');
txData.outputs[0].multiAssets
.get_asset(expectedPolicyId, expectedAssetName)
.to_str()
.should.equal(quantity);
const fee = tx.getFee;
txData.outputs[1].amount.should.equal((totalInput - minAmountForSingleAsset - outputAmount - Number(fee)).toString());
fee.should.equal('170253');
txData.id.should.equal(testData.rawTx.txHash3);
const txBroadcast = tx.toBroadcastFormat();
should_1.default.equal(txBroadcast, testData.rawTx.unsignedTx3);
});
it('should build a consolidate tx with multiple assets', async () => {
const txBuilder = factory.getTransferBuilder();
txBuilder.input({
transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21',
transaction_index: 1,
});
const outputAmount = 0;
const asset1_policyId = '279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3f';
const asset1_assetName = '534e454b';
const asset1_quantity = '6000000';
const asset2_policyId = '1f7a58a1aa1e6b047a42109ade331ce26c9c2cce027d043ff264fb1f';
const asset2_assetName = '425249434b53';
const asset2_quantity = '5000000';
txBuilder.assets({
policy_id: asset1_policyId,
asset_name: asset1_assetName,
quantity: asset1_quantity,
});
txBuilder.assets({
policy_id: asset2_policyId,
asset_name: asset2_assetName,
quantity: asset2_quantity,
});
const totalInput = 20000000;
const minAmountForSingleAsset = 1500000;
txBuilder.changeAddress(testData.rawTx.outputAddress1.address, totalInput.toString());
txBuilder.ttl(800000000);
const tx = (await txBuilder.build());
should_1.default.equal(tx.type, sdk_core_1.TransactionType.Send);
const txData = tx.toJson();
txData.witnesses.length.should.equal(0);
txData.certs.length.should.equal(0);
txData.withdrawals.length.should.equal(0);
txData.outputs.length.should.equal(3);
txData.outputs[0].address.should.equal(testData.rawTx.outputAddress1.address);
txData.outputs[1].address.should.equal(testData.rawTx.outputAddress1.address);
txData.outputs[2].address.should.equal(testData.rawTx.outputAddress1.address);
// token assertion
const asset1_expectedAssetName = CardanoWasm.AssetName.new(Buffer.from(asset1_assetName, 'hex'));
const asset1_expectedPolicyId = CardanoWasm.ScriptHash.from_bytes(Buffer.from(asset1_policyId, 'hex'));
txData.outputs[0].amount.should.equal(minAmountForSingleAsset.toString());
txData.outputs[0].should.have.property('multiAssets');
txData.outputs[0].multiAssets
.get_asset(asset1_expectedPolicyId, asset1_expectedAssetName)
.to_str()
.should.equal(asset1_quantity);
const asset2_expectedAssetName = CardanoWasm.AssetName.new(Buffer.from(asset2_assetName, 'hex'));
const asset2_expectedPolicyId = CardanoWasm.ScriptHash.from_bytes(Buffer.from(asset2_policyId, 'hex'));
txData.outputs[1].amount.should.equal(minAmountForSingleAsset.toString());
txData.outputs[1].should.have.property('multiAssets');
txData.outputs[1].multiAssets
.get_asset(asset2_expectedPolicyId, asset2_expectedAssetName)
.to_str()
.should.equal(asset2_quantity);
const fee = tx.getFee;
txData.outputs[2].amount.should.equal((totalInput - minAmountForSingleAsset * 2 - outputAmount - Number(fee)).toString());
fee.should.equal('175137');
txData.id.should.equal(testData.rawTx.txHash4);
const txBroadcast = tx.toBroadcastFormat();
should_1.default.equal(txBroadcast, testData.rawTx.unsignedTx4);
});
it('should fail to build a consolidate tx with single asset and insufficient minimum ADA', async () => {
const txBuilder = factory.getTransferBuilder();
txBuilder.input({
transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21',
transaction_index: 1,
});
const policyId = '279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3f';
const assetName = '534e454b';
const quantity = '6000000';
txBuilder.assets({
policy_id: policyId,
asset_name: assetName,
quantity: quantity,
});
// change = input amt - fee - output amt => change will be less than 1000000
// even if one output has less than 1 ADA, tx will fail
const totalInput = 1000000;
txBuilder.changeAddress(testData.rawTx.outputAddress1.address, totalInput.toString());
txBuilder.ttl(800000000);
await txBuilder
.build()
.should.rejectedWith('Insufficient funds: need a minimum of 1.5 ADA per output to construct token consolidation');
});
it('build and sign a transfer tx', async () => {
const txBuilder = factory.getTransferBuilder();
txBuilder.input({
transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21',
transaction_index: 1,
});
const outputAmount = 7823121;
txBuilder.output({
address: testData.rawTx.outputAddress1.address,
amount: outputAmount.toString(),
});
const totalInput = 21032023;
txBuilder.changeAddress(testData.rawTx.outputAddress2.address, totalInput.toString());
txBuilder.ttl(800000000);
txBuilder.sign({ key: testData.privateKeys.prvKey4 });
const tx = (await txBuilder.build());
should_1.default.equal(tx.type, sdk_core_1.TransactionType.Send);
const txData = tx.toJson();
txData.witnesses.length.should.equal(1);
txData.certs.length.should.equal(0);
txData.withdrawals.length.should.equal(0);
txData.outputs.length.should.equal(2);
txData.outputs[0].address.should.equal(testData.rawTx.outputAddress1.address);
txData.outputs[1].address.should.equal(testData.rawTx.outputAddress2.address);
const fee = tx.getFee;
txData.outputs[1].amount.should.equal((totalInput - outputAmount - Number(fee)).toString());
fee.should.equal('167173');
txData.id.should.equal(testData.rawTx.txHash2);
const txBroadcast = tx.toBroadcastFormat();
should_1.default.equal(txBroadcast, testData.rawTx.signedTx2);
});
it('should initialize a fee properly, not as zero', async () => {
const txBuilder = factory.getTransferBuilder();
txBuilder.input({
transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21',
transaction_index: 1,
});
txBuilder.output({
address: 'addr1q8rm9z7w4yx5gz652kn2q238efvms6t0qelur9nlglun8eu4tr5knj4fu4adelzqhxg8adu5xca4jra0gtllfrpcawyq9psz23',
amount: '7328383',
});
txBuilder.changeAddress(testData.address.address2, '1000000000');
txBuilder.ttl(800000000);
txBuilder.sign({ key: testData.privateKeys.prvKey4 });
const builtTx = (await txBuilder.build());
builtTx.getFee.should.equal('168405');
});
it('should not calculate fee and use one passed in', async () => {
const txBuilder = factory.getTransferBuilder();
txBuilder.input({
transaction_id: '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21',
transaction_index: 1,
});
txBuilder.output({
address: 'addr1q8rm9z7w4yx5gz652kn2q238efvms6t0qelur9nlglun8eu4tr5knj4fu4adelzqhxg8adu5xca4jra0gtllfrpcawyq9psz23',
amount: '7328383',
});
txBuilder.changeAddress(testData.address.address2, '1000000000');
txBuilder.ttl(800000000);
txBuilder.fee('170000');
txBuilder.sign({ key: testData.privateKeys.prvKey4 });
const builtTx = (await txBuilder.build());
builtTx.getFee.should.equal('170000');
});
it('build a send from unsigned rawTx', async () => {
const txBuilder = factory.from(testData.rawTx.unsignedTx2);
const builtTx = await txBuilder.build();
should_1.default.equal(builtTx.type, sdk_core_1.TransactionType.Send);
should_1.default.equal(builtTx.id, testData.rawTx.txHash2);
builtTx.outputs.length.should.equal(2);
builtTx.outputs[0].address.should.equal(testData.rawTx.outputAddress1.address);
builtTx.outputs[1].address.should.equal(testData.rawTx.outputAddress2.address);
});
it('match signature', async () => {
const txRaw = '582070081eeb1f312ec75af1b4f94a7963db3b264f2451369e4ea244a54de5d0';
const keyPair = new src_1.KeyPair();
const pkey = CardanoWasm.PrivateKey.from_normal_bytes(Buffer.from(keyPair.getKeys().prv, 'hex'));
const vkeyw = CardanoWasm.make_vkey_witness(CardanoWasm.TransactionHash.from_bytes(Buffer.from(txRaw, 'hex')), pkey);
const sig1 = vkeyw.signature().to_hex();
const sig2 = Buffer.from(keyPair.signMessage(txRaw)).toString('hex');
should_1.default.equal(sig1, sig2);
});
// NOTE: The tests below have been commented out as they are for testing during development changes. We don't
// want full node tests as part of our sdk unit tests. If you are commenting these back in, add axios and
// AddressFormat imports.
// xit('should submit a transaction', async () => {
// const keyPair = new KeyPair({ prv: testData.privateKeys.prvKey4 });
// const senderAddress = keyPair.getAddress(AddressFormat.testnet);
//
// const axiosConfig = {
// headers: {
// 'Content-Type': 'application/cbor',
// },
// timeout: 10000,
// };
//
// const txBuilder = factory.getTransferBuilder();
// const utxoData = await axios.get('https://testnet.koios.rest/api/v0/address_info?_address=' + senderAddress);
// const senderBalance = utxoData.data[0].balance;
// txBuilder.changeAddress(senderAddress, senderBalance);
// const utxoSet = utxoData.data[0].utxo_set;
// for (const utxo of utxoSet) {
// txBuilder.input({ transaction_id: utxo.tx_hash, transaction_index: utxo.tx_index });
// }
//
// txBuilder.output({
// address:
// 'addr_test1qz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3jcu5d8ps7zex2k2xt3uqxgjqnnj83ws8lhrn648jjxtwq2ytjqp',
// amount: '5000000',
// });
//
// txBuilder.ttl(800000000);
// txBuilder.sign({ key: keyPair.getKeys().prv });
//
// const tx = await txBuilder.build();
// const serializedTx = tx.toBroadcastFormat();
// const bytes = Uint8Array.from(Buffer.from(serializedTx, 'hex'));
//
// try {
// const res = await axios.post('https://testnet.koios.rest/api/v0/submittx', bytes, axiosConfig);
// console.log(res.data);
// } catch (err) {
// console.log(err);
// }
// });
//
// xit('should submit a transaction using signature interface', async () => {
// const keyPair = new KeyPair({ prv: testData.privateKeys.prvKey4 });
// const senderAddress = keyPair.getAddress(AddressFormat.testnet);
// const axiosConfig = {
// headers: {
// 'Content-Type': 'application/cbor',
// },
// timeout: 10000,
// };
// const txBuilder = factory.getTransferBuilder();
// const utxoData = await await axios.get('https://testnet.koios.rest/api/v0/address_info?_address=' + senderAddress);
// const senderBalance = utxoData.data[0].balance;
// txBuilder.changeAddress(senderAddress, senderBalance);
// const utxoSet = utxoData.data[0].utxo_set;
// for (const utxo of utxoSet) {
// txBuilder.input({ transaction_id: utxo.tx_hash, transaction_index: utxo.tx_index });
// }
// txBuilder.output({
// address:
// 'addr_test1qz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3jcu5d8ps7zex2k2xt3uqxgjqnnj83ws8lhrn648jjxtwq2ytjqp',
// amount: '5000000',
// });
//
// txBuilder.ttl(800000000);
//
// const unsignedTx = await txBuilder.build();
// const serializedTx = unsignedTx.toBroadcastFormat();
//
// const txBuilder2 = factory.from(serializedTx);
// const tx = await txBuilder2.build();
// const signableHex = tx.signablePayload.toString('hex');
// const signature = keyPair.signMessage(signableHex);
// txBuilder2.addSignature({ pub: keyPair.getKeys().pub }, Buffer.from(signature));
// const signedTransaction = await txBuilder2.build();
// const serializedTransaction = signedTransaction.toBroadcastFormat();
// const bytes = Uint8Array.from(Buffer.from(serializedTransaction, 'hex'));
//
// try {
// const res = await axios.post('https://testnet.koios.rest/api/v0/submittx', bytes, axiosConfig);
// console.log(res.data);
// } catch (err) {
// console.log(err);
// }
// });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb25CdWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L3RyYW5zYWN0aW9uQnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG9EQUE0QjtBQUM1Qiw4Q0FBa0Q7QUFDbEQsdURBQXlDO0FBQ3pDLG1DQUErRDtBQUMvRCw0Q0FBdUM7QUFDdkMsc0ZBQXdFO0FBQ3hFLDJEQUF3RDtBQUV4RCxRQUFRLENBQUMseUJBQXlCLEVBQUUsS0FBSyxJQUFJLEVBQUU7SUFDN0MsTUFBTSxPQUFPLEdBQUcsSUFBSSwrQkFBeUIsQ0FBQyxlQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDakUsRUFBRSxDQUFDLDJEQUEyRCxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3pFLE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQy9DLFNBQVMsQ0FBQyxLQUFLLENBQUM7WUFDZCxjQUFjLEVBQUUsa0VBQWtFO1lBQ2xGLGlCQUFpQixFQUFFLENBQUM7U0FDckIsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxZQUFZLEdBQUcsU0FBUyxDQUFDO1FBQy9CLFNBQVMsQ0FBQyxNQUFNLENBQUM7WUFDZixPQUFPLEVBQUUsUUFBUSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsT0FBTztZQUNuRCxNQUFNLEVBQUUsWUFBWSxDQUFDLFFBQVEsRUFBRTtTQUNoQyxDQUFDLENBQUM7UUFDSCxNQUFNLFVBQVUsR0FBRyxTQUFTLENBQUM7UUFDN0IsU0FBUyxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDM0YsU0FBUyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN6QiwyQkFB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SUFDeEMsaURBQWlEO0lBQ2pELHFFQUFxRTtJQUNyRSxFQUFFO0lBQ0YsVUFBVTtJQUNWLHNHQUFzRztJQUN0Ryw2QkFBNkI7SUFDN0Isb0JBQW9CO0lBQ3BCLHdCQUF3QjtJQUN4QixNQUFNO0lBQ04sTUFBTTtJQUNOLEVBQUU7SUFDRiw2RUFBNkU7SUFDN0Usd0VBQXdFO0lBQ3hFLHFFQUFxRTtJQUNyRSwwQkFBMEI7SUFDMUIsaUJBQWlCO0lBQ2pCLDRDQUE0QztJQUM1QyxTQUFTO0lBQ1Qsc0JBQXNCO0lBQ3RCLE9BQU87SUFDUCxvREFBb0Q7SUFDcEQsd0hBQXdIO0lBQ3hILG9EQUFvRDtJQUNwRCwyREFBMkQ7SUFDM0QsK0NBQStDO0lBQy9DLGtDQUFrQztJQUNsQywyRkFBMkY7SUFDM0YsTUFBTTtJQUNOLHVCQUF1QjtJQUN2QixlQUFlO0lBQ2Ysd0hBQXdIO0lBQ3hILHlCQUF5QjtJQUN6QixRQUFRO0lBQ1IsRUFBRTtJQUNGLDhCQUE4QjtJQUM5QixFQUFFO0lBQ0YsZ0RBQWdEO0lBQ2hELHlEQUF5RDtJQUN6RCxFQUFFO0lBQ0YsbURBQW1EO0lBQ25ELHlDQUF5QztJQUN6Qyw0REFBNEQ7SUFDNUQsd0RBQXdEO0lBQ3hELHFGQUFxRjtJQUNyRix3REFBd0Q7SUFDeEQseUVBQXlFO0lBQ3pFLDhFQUE4RTtJQUM5RSxFQUFFO0lBQ0YsVUFBVTtJQUNWLHNHQUFzRztJQUN0Ryw2QkFBNkI7SUFDN0Isb0JBQW9CO0lBQ3BCLHdCQUF3QjtJQUN4QixNQUFNO0lBQ04sTUFBTTtBQUNSLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25UeXBlIH0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCAqIGFzIHRlc3REYXRhIGZyb20gJy4uL3Jlc291cmNlcyc7XG5pbXBvcnQgeyBLZXlQYWlyLCBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5IH0gZnJvbSAnLi4vLi4vc3JjJztcbmltcG9ydCB7IGNvaW5zIH0gZnJvbSAnQGJpdGdvL3N0YXRpY3MnO1xuaW1wb3J0ICogYXMgQ2FyZGFub1dhc20gZnJvbSAnQGVtdXJnby9jYXJkYW5vLXNlcmlhbGl6YXRpb24tbGliLW5vZGVqcyc7XG5pbXBvcnQgeyBUcmFuc2FjdGlvbiB9IGZyb20gJy4uLy4uL3NyYy9saWIvdHJhbnNhY3Rpb24nO1xuXG5kZXNjcmliZSgnQURBIFRyYW5zYWN0aW9uIEJ1aWxkZXInLCBhc3luYyAoKSA9PiB7XG4gIGNvbnN0IGZhY3RvcnkgPSBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2lucy5nZXQoJ3RhZGEnKSk7XG4gIGl0KCdzdGFydCBhbmQgYnVpbGQgYW4gdW5zaWduZWQgdHJhbnNmZXIgdHggZm9yIGJ5cm9uIGFkZHJlc3MnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRUcmFuc2ZlckJ1aWxkZXIoKTtcbiAgICB0eEJ1aWxkZXIuaW5wdXQoe1xuICAgICAgdHJhbnNhY3Rpb25faWQ6ICcxYjUzMzMxZTA2OWE2ZTU4ZmU3NzkxOWQzMGMwY2YyOTlkMTNhMmY1YjNkOTk3MGNlNDczYzFhNjZkNzFiZjAzJyxcbiAgICAgIHRyYW5zYWN0aW9uX2luZGV4OiAxLFxuICAgIH0pO1xuICAgIGNvbnN0IG91dHB1dEFtb3VudCA9IDIwMDAwMDAwMDtcbiAgICB0eEJ1aWxkZXIub3V0cHV0KHtcbiAgICAgIGFkZHJlc3M6IHRlc3REYXRhLnJhd1R4Qnlyb24ub3V0cHV0QWRkcmVzczEuYWRkcmVzcyxcbiAgICAgIGFtb3VudDogb3V0cHV0QW1vdW50LnRvU3RyaW5nKCksXG4gICAgfSk7XG4gICAgY29uc3QgdG90YWxJbnB1dCA9IDk5OTYwMDAwMDtcbiAgICB0eEJ1aWxkZXIuY2hhbmdlQWRkcmVzcyh0ZXN0RGF0YS5yYXdUeEJ5cm9uLm91dHB1dEFkZHJlc3MyLmFkZHJlc3MsIHRvdGFsSW5wdXQudG9TdHJpbmcoKSk7XG4gICAgdHhCdWlsZGVyLnR0bCg4MDAwMDAwMDApO1xuICAgIC8vIHR4QnVpbGRlci5mZWUoJzIwMDAwMCcpO1xuICAgIGNvbnN0IHR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgICBzaG91bGQuZXF1YWwodHgudHlwZSwgVHJhbnNhY3Rpb25UeXBlLlNlbmQpO1xuICAgIGNvbnN0IHR4RGF0YSA9IHR4LnRvSnNvbigpO1xuICAgIHR4RGF0YS53aXRuZXNzZXMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB0eERhdGEuY2VydHMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB0eERhdGEud2l0aGRyYXdhbHMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB0eERhdGEub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDIpO1xuICAgIHR4RGF0YS5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJhd1R4Qnlyb24ub3V0cHV0QWRkcmVzczEuYWRkcmVzcyk7XG4gICAgdHhEYXRhLm91dHB1dHNbMV0uYWRkcmVzcy5zaG91bGQuZXF1YWwodGVzdERhdGEucmF3VHhCeXJvbi5vdXRwdXRBZGRyZXNzMi5hZGRyZXNzKTtcbiAgICBjb25zdCBmZWUgPSB0eC5nZXRGZWU7XG4gICAgdHhEYXRhLm91dHB1dHNbMV0uYW1vdW50LnNob3VsZC5lcXVhbCgodG90YWxJbnB1dCAtIG91dHB1dEFtb3VudCAtIE51bWJlcihmZWUpKS50b1N0cmluZygpKTtcbiAgICBmZWUuc2hvdWxkLmVxdWFsKCcxNjc0MzcnKTtcbiAgICB0eERhdGEuaWQuc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJhd1R4Qnlyb24udHhIYXNoMik7XG4gICAgY29uc3QgdHhCcm9hZGNhc3QgPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgIHNob3VsZC5lcXVhbCh0eEJyb2FkY2FzdCwgdGVzdERhdGEucmF3VHhCeXJvbi51bnNpZ25lZFR4Mik7XG4gIH0pO1xuXG4gIGl0KCdzdGFydCBhbmQgYnVpbGQgYW4gdW5zaWduZWQgdHJhbnNmZXIgdHggZm9yIHNoZWxsZXkgYWRkcmVzcycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgIHR4QnVpbGRlci5pbnB1dCh7XG4gICAgICB0cmFuc2FjdGlvbl9pZDogJzM2NzdlNzVjN2JhNjk5YmZkYzZjZDU3ZDQyZjI0NmY4NmY2M2FlZmQ3NjAyNTAwNmFjNzgzMTNmYWQyYmJhMjEnLFxuICAgICAgdHJhbnNhY3Rpb25faW5kZXg6IDEsXG4gICAgfSk7XG4gICAgY29uc3Qgb3V0cHV0QW1vdW50ID0gNzgyMzEyMTtcbiAgICB0eEJ1aWxkZXIub3V0cHV0KHtcbiAgICAgIGFkZHJlc3M6IHRlc3REYXRhLnJhd1R4Lm91dHB1dEFkZHJlc3MxLmFkZHJlc3MsXG4gICAgICBhbW91bnQ6IG91dHB1dEFtb3VudC50b1N0cmluZygpLFxuICAgIH0pO1xuICAgIGNvbnN0IHRvdGFsSW5wdXQgPSAyMTAzMjAyMztcbiAgICB0eEJ1aWxkZXIuY2hhbmdlQWRkcmVzcyh0ZXN0RGF0YS5yYXdUeC5vdXRwdXRBZGRyZXNzMi5hZGRyZXNzLCB0b3RhbElucHV0LnRvU3RyaW5nKCkpO1xuICAgIHR4QnVpbGRlci50dGwoODAwMDAwMDAwKTtcbiAgICBjb25zdCB0eCA9IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNhY3Rpb247XG4gICAgc2hvdWxkLmVxdWFsKHR4LnR5cGUsIFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcbiAgICBjb25zdCB0eERhdGEgPSB0eC50b0pzb24oKTtcbiAgICB0eERhdGEud2l0bmVzc2VzLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gICAgdHhEYXRhLmNlcnRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gICAgdHhEYXRhLndpdGhkcmF3YWxzLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gICAgdHhEYXRhLm91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcbiAgICB0eERhdGEub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5yYXdUeC5vdXRwdXRBZGRyZXNzMS5hZGRyZXNzKTtcbiAgICB0eERhdGEub3V0cHV0c1sxXS5hZGRyZXNzLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5yYXdUeC5vdXRwdXRBZGRyZXNzMi5hZGRyZXNzKTtcbiAgICBjb25zdCBmZWUgPSB0eC5nZXRGZWU7XG4gICAgdHhEYXRhLm91dHB1dHNbMV0uYW1vdW50LnNob3VsZC5lcXVhbCgodG90YWxJbnB1dCAtIG91dHB1dEFtb3VudCAtIE51bWJlcihmZWUpKS50b1N0cmluZygpKTtcbiAgICBmZWUuc2hvdWxkLmVxdWFsKCcxNjcxNzMnKTtcbiAgICB0eERhdGEuaWQuc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJhd1R4LnR4SGFzaDIpO1xuICAgIGNvbnN0IHR4QnJvYWRjYXN0ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICBzaG91bGQuZXF1YWwodHhCcm9hZGNhc3QsIHRlc3REYXRhLnJhd1R4LnVuc2lnbmVkVHgyKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBidWlsZCBhIGNvbnNvbGlkYXRlIHR4IHdpdGggbm8gYXNzZXQnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRUcmFuc2ZlckJ1aWxkZXIoKTtcbiAgICB0eEJ1aWxkZXIuaW5wdXQoe1xuICAgICAgdHJhbnNhY3Rpb25faWQ6ICczNjc3ZTc1YzdiYTY5OWJmZGM2Y2Q1N2Q0MmYyNDZmODZmNjNhZWZkNzYwMjUwMDZhYzc4MzEzZmFkMmJiYTIxJyxcbiAgICAgIHRyYW5zYWN0aW9uX2luZGV4OiAxLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgb3V0cHV0QW1vdW50ID0gMDtcbiAgICBjb25zdCB0b3RhbElucHV0ID0gMjAwMDAwMDA7XG4gICAgdHhCdWlsZGVyLmNoYW5nZUFkZHJlc3ModGVzdERhdGEucmF3VHgub3V0cHV0QWRkcmVzczEuYWRkcmVzcywgdG90YWxJbnB1dC50b1N0cmluZygpKTtcbiAgICB0eEJ1aWxkZXIudHRsKDgwMDAwMDAwMCk7XG4gICAgY29uc3QgdHggPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuICAgIHNob3VsZC5lcXVhbCh0eC50eXBlLCBUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgY29uc3QgdHhEYXRhID0gdHgudG9Kc29uKCk7XG4gICAgdHhEYXRhLndpdG5lc3Nlcy5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgIHR4RGF0YS5jZXJ0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgIHR4RGF0YS53aXRoZHJhd2Fscy5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgIHR4RGF0YS5vdXRwdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgdHhEYXRhLm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwodGVzdERhdGEucmF3VHgub3V0cHV0QWRkcmVzczEuYWRkcmVzcyk7XG4gICAgY29uc3QgZmVlID0gdHguZ2V0RmVlO1xuICAgIHR4RGF0YS5vdXRwdXRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWwoKHRvdGFsSW5wdXQgLSBvdXRwdXRBbW91bnQgLSBOdW1iZXIoZmVlKSkudG9TdHJpbmcoKSk7XG4gICAgZmVlLnNob3VsZC5lcXVhbCgnMTY1NTQ1Jyk7XG4gICAgdHhEYXRhLmlkLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5yYXdUeC50eEhhc2g1KTtcbiAgICBjb25zdCB0eEJyb2FkY2FzdCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgc2hvdWxkLmVxdWFsKHR4QnJvYWRjYXN0LCB0ZXN0RGF0YS5yYXdUeC51bnNpZ25lZFR4NSk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgaW5pdGlhbGl6ZSBhbmQgYnVpbGQgdHggd2l0aCBhc3NldCBkYXRhJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHBvbGljeUlkID0gJ2UxNmMyZGM4YWU5MzdlOGQzNzkwYzdmZDcxNjhkN2I5OTQ2MjFiYTE0Y2ExMTQxNWYzOWZlZDcyJztcbiAgICBjb25zdCBhc3NldE5hbWUgPSAnNGQ0OTRlJztcbiAgICBjb25zdCBxdWFudGl0eSA9ICcyMDAwMDAwJztcbiAgICBjb25zdCBwcmVCdWlsdFR4ID0gbmV3IFRyYW5zYWN0aW9uKGNvaW5zLmdldCgndGFkYScpKTtcbiAgICBwcmVCdWlsdFR4LmZyb21SYXdUcmFuc2FjdGlvbih0ZXN0RGF0YS5yYXdUeC51bnNpZ25lZFR4Myk7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRUcmFuc2ZlckJ1aWxkZXIoKTtcbiAgICB0eEJ1aWxkZXIuaW5pdEJ1aWxkZXIocHJlQnVpbHRUeCk7XG5cbiAgICBjb25zdCB0eCA9IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNhY3Rpb247XG4gICAgY29uc3QgdHhEYXRhID0gdHgudG9Kc29uKCk7XG4gICAgY29uc3QgZXhwZWN0ZWRBc3NldE5hbWUgPSBDYXJkYW5vV2FzbS5Bc3NldE5hbWUubmV3KEJ1ZmZlci5mcm9tKGFzc2V0TmFtZSwgJ2hleCcpKTtcbiAgICBjb25zdCBleHBlY3RlZFBvbGljeUlkID0gQ2FyZGFub1dhc20uU2NyaXB0SGFzaC5mcm9tX2J5dGVzKEJ1ZmZlci5mcm9tKHBvbGljeUlkLCAnaGV4JykpO1xuICAgIHR4RGF0YS5vdXRwdXRzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCdtdWx0aUFzc2V0cycpO1xuICAgICh0eERhdGEub3V0cHV0c1swXS5tdWx0aUFzc2V0cyBhcyBDYXJkYW5vV2FzbS5NdWx0aUFzc2V0KVxuICAgICAgLmdldF9hc3NldChleHBlY3RlZFBvbGljeUlkLCBleHBlY3RlZEFzc2V0TmFtZSlcbiAgICAgIC50b19zdHIoKVxuICAgICAgLnNob3VsZC5lcXVhbChxdWFudGl0eSk7XG4gICAgdHhEYXRhLmlkLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5yYXdUeC50eEhhc2gzKTtcbiAgICBjb25zdCB0eEJyb2FkY2FzdCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgc2hvdWxkLmVxdWFsKHR4QnJvYWRjYXN0LCB0ZXN0RGF0YS5yYXdUeC51bnNpZ25lZFR4Myk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgYnVpbGQgYSBjb25zb2xpZGF0ZSB0eCB3aXRoIHNpbmdsZSBhc3NldCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgIHR4QnVpbGRlci5pbnB1dCh7XG4gICAgICB0cmFuc2FjdGlvbl9pZDogJzM2NzdlNzVjN2JhNjk5YmZkYzZjZDU3ZDQyZjI0NmY4NmY2M2FlZmQ3NjAyNTAwNmFjNzgzMTNmYWQyYmJhMjEnLFxuICAgICAgdHJhbnNhY3Rpb25faW5kZXg6IDEsXG4gICAgfSk7XG5cbiAgICBjb25zdCBvdXRwdXRBbW91bnQgPSAwO1xuICAgIGNvbnN0IHBvbGljeUlkID0gJ2UxNmMyZGM4YWU5MzdlOGQzNzkwYzdmZDcxNjhkN2I5OTQ2MjFiYTE0Y2ExMTQxNWYzOWZlZDcyJztcbiAgICBjb25zdCBhc3NldE5hbWUgPSAnNGQ0OTRlJztcbiAgICBjb25zdCBxdWFudGl0eSA9ICcyMDAwMDAwJztcbiAgICB0eEJ1aWxkZXIuYXNzZXRzKHtcbiAgICAgIHBvbGljeV9pZDogcG9saWN5SWQsXG4gICAgICBhc3NldF9uYW1lOiBhc3NldE5hbWUsXG4gICAgICBxdWFudGl0eTogcXVhbnRpdHksXG4gICAgfSk7XG4gICAgY29uc3QgbWluQW1vdW50Rm9yU2luZ2xlQXNzZXQgPSAxNTAwMDAwO1xuICAgIGNvbnN0IHRvdGFsSW5wdXQgPSAyMDAwMDAwMDtcbiAgICB0eEJ1aWxkZXIuY2hhbmdlQWRkcmVzcyh0ZXN0RGF0YS5yYXdUeC5vdXRwdXRBZGRyZXNzMS5hZGRyZXNzLCB0b3RhbElucHV0LnRvU3RyaW5nKCkpO1xuICAgIHR4QnVpbGRlci50dGwoODAwMDAwMDAwKTtcbiAgICBjb25zdCB0eCA9IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNhY3Rpb247XG4gICAgc2hvdWxkLmVxdWFsKHR4LnR5cGUsIFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcbiAgICBjb25zdCB0eERhdGEgPSB0eC50b0pzb24oKTtcbiAgICB0eERhdGEud2l0bmVzc2VzLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gICAgdHhEYXRhLmNlcnRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gICAgdHhEYXRhLndpdGhkcmF3YWxzLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gICAgdHhEYXRhLm91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcbiAgICB0eERhdGEub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5yYXdUeC5vdXRwdXRBZGRyZXNzMS5hZGRyZXNzKTtcbiAgICB0eERhdGEub3V0cHV0c1sxXS5hZGRyZXNzLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5yYXdUeC5vdXRwdXRBZGRyZXNzMS5hZGRyZXNzKTtcblxuICAgIC8vIHRva2VuIGFzc2VydGlvblxuICAgIGNvbnN0IGV4cGVjdGVkQXNzZXROYW1lID0gQ2FyZGFub1dhc20uQXNzZXROYW1lLm5ldyhCdWZmZXIuZnJvbShhc3NldE5hbWUsICdoZXgnKSk7XG4gICAgY29uc3QgZXhwZWN0ZWRQb2xpY3lJZCA9IENhcmRhbm9XYXNtLlNjcmlwdEhhc2guZnJvbV9ieXRlcyhCdWZmZXIuZnJvbShwb2xpY3lJZCwgJ2hleCcpKTtcbiAgICB0eERhdGEub3V0cHV0c1swXS5hbW91bnQuc2hvdWxkLmVxdWFsKG1pbkFtb3VudEZvclNpbmdsZUFzc2V0LnRvU3RyaW5nKCkpO1xuICAgIHR4RGF0YS5vdXRwdXRzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCdtdWx0aUFzc2V0cycpO1xuICAgICh0eERhdGEub3V0cHV0c1swXS5tdWx0aUFzc2V0cyBhcyBDYXJkYW5vV2FzbS5NdWx0aUFzc2V0KVxuICAgICAgLmdldF9hc3NldChleHBlY3RlZFBvbGljeUlkLCBleHBlY3RlZEFzc2V0TmFtZSlcbiAgICAgIC50b19zdHIoKVxuICAgICAgLnNob3VsZC5lcXVhbChxdWFudGl0eSk7XG5cbiAgICBjb25zdCBmZWUgPSB0eC5nZXRGZWU7XG4gICAgdHhEYXRhLm91dHB1dHNbMV0uYW1vdW50LnNob3VsZC5lcXVhbChcbiAgICAgICh0b3RhbElucHV0IC0gbWluQW1vdW50Rm9yU2luZ2xlQXNzZXQgLSBvdXRwdXRBbW91bnQgLSBOdW1iZXIoZmVlKSkudG9TdHJpbmcoKVxuICAgICk7XG4gICAgZmVlLnNob3VsZC5lcXVhbCgnMTcwMjUzJyk7XG4gICAgdHhEYXRhLmlkLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5yYXdUeC50eEhhc2gzKTtcbiAgICBjb25zdCB0eEJyb2FkY2FzdCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgc2hvdWxkLmVxdWFsKHR4QnJvYWRjYXN0LCB0ZXN0RGF0YS5yYXdUeC51bnNpZ25lZFR4Myk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgYnVpbGQgYSBjb25zb2xpZGF0ZSB0eCB3aXRoIG11bHRpcGxlIGFzc2V0cycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgIHR4QnVpbGRlci5pbnB1dCh7XG4gICAgICB0cmFuc2FjdGlvbl9pZDogJzM2NzdlNzVjN2JhNjk5YmZkYzZjZDU3ZDQyZjI0NmY4NmY2M2FlZmQ3NjAyNTAwNmFjNzgzMTNmYWQyYmJhMjEnLFxuICAgICAgdHJhbnNhY3Rpb25faW5kZXg6IDEsXG4gICAgfSk7XG5cbiAgICBjb25zdCBvdXRwdXRBbW91bnQgPSAwO1xuICAgIGNvbnN0IGFzc2V0MV9wb2xpY3lJZCA9ICcyNzljOTA5ZjM0OGU1MzNkYTU4MDg4OThmODdmOWExNGJiMmMzZGZiYmFjY2NkNjMxZDkyN2EzZic7XG4gICAgY29uc3QgYXNzZXQxX2Fzc2V0TmFtZSA9ICc1MzRlNDU0Yic7XG4gICAgY29uc3QgYXNzZXQxX3F1YW50aXR5ID0gJzYwMDAwMDAnO1xuICAgIGNvbnN0IGFzc2V0Ml9wb2xpY3lJZCA9ICcxZjdhNThhMWFhMWU2YjA0N2E0MjEwOWFkZTMzMWNlMjZjOWMyY2NlMDI3ZDA0M2ZmMjY0ZmIxZic7XG4gICAgY29uc3QgYXNzZXQyX2Fzc2V0TmFtZSA9ICc0MjUyNDk0MzRiNTMnO1xuICAgIGNvbnN0IGFzc2V0Ml9xdWFudGl0eSA9ICc1MDAwMDAwJztcblxuICAgIHR4QnVpbGRlci5hc3NldHMoe1xuICAgICAgcG9saWN5X2lkOiBhc3NldDFfcG9saWN5SWQsXG4gICAgICBhc3NldF9uYW1lOiBhc3NldDFfYXNzZXROYW1lLFxuICAgICAgcXVhbnRpdHk6IGFzc2V0MV9xdWFudGl0eSxcbiAgICB9KTtcbiAgICB0eEJ1aWxkZXIuYXNzZXRzKHtcbiAgICAgIHBvbGljeV9pZDogYXNzZXQyX3BvbGljeUlkLFxuICAgICAgYXNzZXRfbmFtZTogYXNzZXQyX2Fzc2V0TmFtZSxcbiAgICAgIHF1YW50aXR5OiBhc3NldDJfcXVhbnRpdHksXG4gICAgfSk7XG5cbiAgICBjb25zdCB0b3RhbElucHV0ID0gMjAwMDAwMDA7XG4gICAgY29uc3QgbWluQW1vdW50Rm9yU2luZ2xlQXNzZXQgPSAxNTAwMDAwO1xuICAgIHR4QnVpbGRlci5jaGFuZ2VBZGRyZXNzKHRlc3REYXRhLnJhd1R4Lm91dHB1dEFkZHJlc3MxLmFkZHJlc3MsIHRvdGFsSW5wdXQudG9TdHJpbmcoKSk7XG4gICAgdHhCdWlsZGVyLnR0bCg4MDAwMDAwMDApO1xuICAgIGNvbnN0IHR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgICBzaG91bGQuZXF1YWwodHgudHlwZSwgVHJhbnNhY3Rpb25UeXBlLlNlbmQpO1xuICAgIGNvbnN0IHR4RGF0YSA9IHR4LnRvSnNvbigpO1xuICAgIHR4RGF0YS53aXRuZXNzZXMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB0eERhdGEuY2VydHMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB0eERhdGEud2l0aGRyYXdhbHMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB0eERhdGEub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDMpO1xuICAgIHR4RGF0YS5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJhd1R4Lm91dHB1dEFkZHJlc3MxLmFkZHJlc3MpO1xuICAgIHR4RGF0YS5vdXRwdXRzWzFdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJhd1R4Lm91dHB1dEFkZHJlc3MxLmFkZHJlc3MpO1xuICAgIHR4RGF0YS5vdXRwdXRzWzJdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJhd1R4Lm91dHB1dEFkZHJlc3MxLmFkZHJlc3MpO1xuXG4gICAgLy8gdG9rZW4gYXNzZXJ0aW9uXG4gICAgY29uc3QgYXNzZXQxX2V4cGVjdGVkQXNzZXROYW1lID0gQ2FyZGFub1dhc20uQXNzZXROYW1lLm5ldyhCdWZmZXIuZnJvbShhc3NldDFfYXNzZXROYW1lLCAnaGV4JykpO1xuICAgIGNvbnN0IGFzc2V0MV9leHBlY3RlZFBvbGljeUlkID0gQ2FyZGFub1dhc20uU2NyaXB0SGFzaC5mcm9tX2J5dGVzKEJ1ZmZlci5mcm9tKGFzc2V0MV9wb2xpY3lJZCwgJ2hleCcpKTtcbiAgICB0eERhdGEub3V0cHV0c1swXS5hbW91bnQuc2hvdWxkLmVxdWFsKG1pbkFtb3VudEZvclNpbmdsZUFzc2V0LnRvU3RyaW5nKCkpO1xuICAgIHR4RGF0YS5vdXRwdXRzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCdtdWx0aUFzc2V0cycpO1xuICAgICh0eERhdGEub3V0cHV0c1swXS5tdWx0aUFzc2V0cyBhcyBDYXJkYW5vV2FzbS5NdWx0aUFzc2V0KVxuICAgICAgLmdldF9hc3NldChhc3NldDFfZXhwZWN0ZWRQb2xpY3lJZCwgYXNzZXQxX2V4cGVjdGVkQXNzZXROYW1lKVxuICAgICAgLnRvX3N0cigpXG4gICAgICAuc2hvdWxkLmVxdWFsKGFzc2V0MV9xdWFudGl0eSk7XG4gICAgY29uc3QgYXNzZXQyX2V4cGVjdGVkQXNzZXROYW1lID0gQ2FyZGFub1dhc20uQXNzZXROYW1lLm5ldyhCdWZmZXIuZnJvbShhc3NldDJfYXNzZXROYW1lLCAnaGV4JykpO1xuICAgIGNvbnN0IGFzc2V0Ml9leHBlY3RlZFBvbGljeUlkID0gQ2FyZGFub1dhc20uU2NyaXB0SGFzaC5mcm9tX2J5dGVzKEJ1ZmZlci5mcm9tKGFzc2V0Ml9wb2xpY3lJZCwgJ2hleCcpKTtcbiAgICB0eERhdGEub3V0cHV0c1sxXS5hbW91bnQuc2hvdWxkLmVxdWFsKG1pbkFtb3VudEZvclNpbmdsZUFzc2V0LnRvU3RyaW5nKCkpO1xuICAgIHR4RGF0YS5vdXRwdXRzWzFdLnNob3VsZC5oYXZlLnByb3BlcnR5KCdtdWx0aUFzc2V0cycpO1xuICAgICh0eERhdGEub3V0cHV0c1sxXS5tdWx0aUFzc2V0cyBhcyBDYXJkYW5vV2FzbS5NdWx0aUFzc2V0KVxuICAgICAgLmdldF9hc3NldChhc3NldDJfZXhwZWN0ZWRQb2xpY3lJZCwgYXNzZXQyX2V4cGVjdGVkQXNzZXROYW1lKVxuICAgICAgLnRvX3N0cigpXG4gICAgICAuc2hvdWxkLmVxdWFsKGFzc2V0Ml9xdWFudGl0eSk7XG5cbiAgICBjb25zdCBmZWUgPSB0eC5nZXRGZWU7XG4gICAgdHhEYXRhLm91dHB1dHNbMl0uYW1vdW50LnNob3VsZC5lcXVhbChcbiAgICAgICh0b3RhbElucHV0IC0gbWluQW1vdW50Rm9yU2luZ2xlQXNzZXQgKiAyIC0gb3V0cHV0QW1vdW50IC0gTnVtYmVyKGZlZSkpLnRvU3RyaW5nKClcbiAgICApO1xuICAgIGZlZS5zaG91bGQuZXF1YWwoJzE3NTEzNycpO1xuICAgIHR4RGF0YS5pZC5zaG91bGQuZXF1YWwodGVzdERhdGEucmF3VHgudHhIYXNoNCk7XG4gICAgY29uc3QgdHhCcm9hZGNhc3QgPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgIHNob3VsZC5lcXVhbCh0eEJyb2FkY2FzdCwgdGVzdERhdGEucmF3VHgudW5zaWduZWRUeDQpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGZhaWwgdG8gYnVpbGQgYSBjb25zb2xpZGF0ZSB0eCB3aXRoIHNpbmdsZSBhc3NldCBhbmQgaW5zdWZmaWNpZW50IG1pbmltdW0gQURBJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgdHhCdWlsZGVyLmlucHV0KHtcbiAgICAgIHRyYW5zYWN0aW9uX2lkOiAnMzY3N2U3NWM3YmE2OTliZmRjNmNkNTdkNDJmMjQ2Zjg2ZjYzYWVmZDc2MDI1MDA2YWM3ODMxM2ZhZDJiYmEyMScsXG4gICAgICB0cmFuc2FjdGlvbl9pbmRleDogMSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHBvbGljeUlkID0gJzI3OWM5MDlmMzQ4ZTUzM2RhNTgwODg5OGY4N2Y5YTE0YmIyYzNkZmJiYWNjY2Q2MzFkOTI3YTNmJztcbiAgICBjb25zdCBhc3NldE5hbWUgPSAnNTM0ZTQ1NGInO1xuICAgIGNvbnN0IHF1YW50aXR5ID0gJzYwMDAwMDAnO1xuICAgIHR4QnVpbGRlci5hc3NldHMoe1xuICAgICAgcG9saWN5X2lkOiBwb2xpY3lJZCxcbiAgICAgIGFzc2V0X25hbWU6IGFzc2V0TmFtZSxcbiAgICAgIHF1YW50aXR5OiBxdWFudGl0eSxcbiAgICB9KTtcblxuICAgIC8vIGNoYW5nZSA9IGlucHV0IGFtdCAtIGZlZSAtIG91dHB1dCBhbXQgPT4gY2hhbmdlIHdpbGwgYmUgbGVzcyB0aGFuIDEwMDAwMDBcbiAgICAvLyBldmVuIGlmIG9uZSBvdXRwdXQgaGFzIGxlc3MgdGhhbiAxIEFEQSwgdHggd2lsbCBmYWlsXG4gICAgY29uc3QgdG90YWxJbnB1dCA9IDEwMDAwMDA7XG4gICAgdHhCdWlsZGVyLmNoYW5nZUFkZHJlc3ModGVzdERhdGEucmF3VHgub3V0cHV0QWRkcmVzczEuYWRkcmVzcywgdG90YWxJbnB1dC50b1N0cmluZygpKTtcbiAgICB0eEJ1aWxkZXIudHRsKDgwMDAwMDAwMCk7XG4gICAgYXdhaXQgdHhCdWlsZGVyXG4gICAgICAuYnVpbGQoKVxuICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ0luc3VmZmljaWVudCBmdW5kczogbmVlZCBhIG1pbmltdW0gb2YgMS41IEFEQSBwZXIgb3V0cHV0IHRvIGNvbnN0cnVjdCB0b2tlbiBjb25zb2xpZGF0aW9uJyk7XG4gIH0pO1xuXG4gIGl0KCdidWlsZCBhbmQgc2lnbiBhIHRyYW5zZmVyIHR4JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgdHhCdWlsZGVyLmlucHV0KHtcbiAgICAgIHRyYW5zYWN0aW9uX2lkOiAnMzY3N2U3NWM3YmE2OTliZmRjNmNkNTdkNDJmMjQ2Zjg2ZjYzYWVmZDc2MDI1MDA2YWM3ODMxM2ZhZDJiYmEyMScsXG4gICAgICB0cmFuc2FjdGlvbl9pbmRleDogMSxcbiAgICB9KTtcbiAgICBjb25zdCBvdXRwdXRBbW91bnQgPSA3ODIzMTIxO1xuICAgIHR4QnVpbGRlci5vdXRwdXQoe1xuICAgICAgYWRkcmVzczogdGVzdERhdGEucmF3VHgub3V0cHV0QWRkcmVzczEuYWRkcmVzcyxcbiAgICAgIGFtb3VudDogb3V0cHV0QW1vdW50LnRvU3RyaW5nKCksXG4gICAgfSk7XG4gICAgY29uc3QgdG90YWxJbnB1dCA9IDIxMDMyMDIzO1xuICAgIHR4QnVpbGRlci5jaGFuZ2VBZGRyZXNzKHRlc3REYXRhLnJhd1R4Lm91dHB1dEFkZHJlc3MyLmFkZHJlc3MsIHRvdGFsSW5wdXQudG9TdHJpbmcoKSk7XG4gICAgdHhCdWlsZGVyLnR0bCg4MDAwMDAwMDApO1xuICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB0ZXN0RGF0YS5wcml2YXRlS2V5cy5wcnZLZXk0IH0pO1xuICAgIGNvbnN0IHR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgICBzaG91bGQuZXF1YWwodHgudHlwZSwgVHJhbnNhY3Rpb25UeXBlLlNlbmQpO1xuICAgIGNvbnN0IHR4RGF0YSA9IHR4LnRvSnNvbigpO1xuICAgIHR4RGF0YS53aXRuZXNzZXMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICB0eERhdGEuY2VydHMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB0eERhdGEud2l0aGRyYXdhbHMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB0eERhdGEub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDIpO1xuICAgIHR4RGF0YS5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJhd1R4Lm91dHB1dEFkZHJlc3MxLmFkZHJlc3MpO1xuICAgIHR4RGF0YS5vdXRwdXRzWzFdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJhd1R4Lm91dHB1dEFkZHJlc3MyLmFkZHJlc3MpO1xuICAgIGNvbnN0IGZlZSA9IHR4LmdldEZlZTtcbiAgICB0eERhdGEub3V0cHV0c1sxXS5hbW91bnQuc2hvdWxkLmVxdWFsKCh0b3RhbElucHV0IC0gb3V0cHV0QW1vdW50IC0gTnVtYmVyKGZlZSkpLnRvU3RyaW5nKCkpO1xuICAgIGZlZS5zaG91bGQuZXF1YWwoJzE2NzE3MycpO1xuICAgIHR4RGF0YS5pZC5zaG91bGQuZXF1YWwodGVzdERhdGEucmF3VHgudHhIYXNoMik7XG4gICAgY29uc3QgdHhCcm9hZGNhc3QgPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgIHNob3VsZC5lcXVhbCh0eEJyb2FkY2FzdCwgdGVzdERhdGEucmF3VHguc2lnbmVkVHgyKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBpbml0aWFsaXplIGEgZmVlIHByb3Blcmx5LCBub3QgYXMgemVybycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgIHR4QnVpbGRlci5pbnB1dCh7XG4gICAgICB0cmFuc2FjdGlvbl9pZDogJzM2NzdlNzVjN2JhNjk5YmZkYzZjZDU3ZDQyZjI0NmY4NmY2M2FlZmQ3NjAyNTAwNmFjNzgzMTNmYWQyYmJhMjEnLFxuICAgICAgdHJhbnNhY3Rpb25faW5kZXg6IDEsXG4gICAgfSk7XG4gICAgdHhCdWlsZGVyLm91dHB1dCh7XG4gICAgICBhZGRyZXNzOlxuICAgICAgICAnYWRkcjFxOHJtOXo3dzR5eDVnejY1MmtuMnEyMzhlZnZtczZ0MHFlbHVyOW5sZ2x1bjhldTR0cjVrbmo0ZnU0YWRlbHpxaHhnOGFkdTV4Y2E0anJhMGd0bGxmcnBjYXd5cTlwc3oyMycsXG4gICAgICBhbW91bnQ6ICc3MzI4MzgzJyxcbiAgICB9KTtcbiAgICB0eEJ1aWxkZXIuY2hhbmdlQWRkcmVzcyh0ZXN0RGF0YS5hZGRyZXNzLmFkZHJlc3MyLCAnMTAwMDAwMDAwMCcpO1xuICAgIHR4QnVpbGRlci50dGwoODAwMDAwMDAwKTtcbiAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogdGVzdERhdGEucHJpdmF0ZUtleXMucHJ2S2V5NCB9KTtcbiAgICBjb25zdCBidWlsdFR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgICBidWlsdFR4LmdldEZlZS5zaG91bGQuZXF1YWwoJzE2ODQwNScpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIG5vdCBjYWxjdWxhdGUgZmVlIGFuZCB1c2Ugb25lIHBhc3NlZCBpbicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgIHR4QnVpbGRlci5pbnB1dCh7XG4gICAgICB0cmFuc2FjdGlvbl9pZDogJzM2NzdlNzVjN2JhNjk5YmZkYzZjZDU3ZDQyZjI0NmY4NmY2M2FlZmQ3NjAyNTAwNmFjNzgzMTNmYWQyYmJhMjEnLFxuICAgICAgdHJhbnNhY3Rpb25faW5kZXg6IDEsXG4gICAgfSk7XG4gICAgdHhCdWlsZGVyLm91dHB1dCh7XG4gICAgICBhZGRyZXNzOlxuICAgICAgICAnYWRkcjFxOHJtOXo3dzR5eDVnejY1MmtuMnEyMzhlZnZtczZ0MHFlbHVyOW5sZ2x1bjhldTR0cjVrbmo0ZnU0YWRlbHpxaHhnOGFkdTV4Y2E0anJhMGd0bGxmcnBjYXd5cTlwc3oyMycsXG4gICAgICBhbW91bnQ6ICc3MzI4MzgzJyxcbiAgICB9KTtcbiAgICB0eEJ1aWxkZXIuY2hhbmdlQWRkcmVzcyh0ZXN0RGF0YS5hZGRyZXNzLmFkZHJlc3MyLCAnMTAwMDAwMDAwMCcpO1xuICAgIHR4QnVpbGRlci50dGwoODAwMDAwMDAwKTtcbiAgICB0eEJ1aWxkZXIuZmVlKCcxNzAwMDAnKTtcbiAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogdGVzdERhdGEucHJpdmF0ZUtleXMucHJ2S2V5NCB9KTtcbiAgICBjb25zdCBidWlsdFR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgICBidWlsdFR4LmdldEZlZS5zaG91bGQuZXF1YWwoJzE3MDAwMCcpO1xuICB9KTtcblxuICBpdCgnYnVpbGQgYSBzZW5kIGZyb20gdW5zaWduZWQgcmF3VHgnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5mcm9tKHRlc3REYXRhLnJhd1R4LnVuc2lnbmVkVHgyKTtcbiAgICBjb25zdCBidWlsdFR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgc2hvdWxkLmVxdWFsKGJ1aWx0VHgudHlwZSwgVHJhbnNhY3Rpb25UeXBlLlNlbmQpO1xuICAgIHNob3VsZC5lcXVhbChidWlsdFR4LmlkLCB0ZXN0RGF0YS5yYXdUeC50eEhhc2gyKTtcbiAgICBidWlsdFR4Lm91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcbiAgICBidWlsdFR4Lm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwodGVzdERhdGEucmF3VHgub3V0cHV0QWRkcmVzczEuYWRkcmVzcyk7XG4gICAgYnVpbHRUeC5vdXRwdXRzWzFdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLnJhd1R4Lm91dHB1dEFkZHJlc3MyLmFkZHJlc3MpO1xuICB9KTtcblxuICBpdCgnbWF0Y2ggc2lnbmF0dXJlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHR4UmF3ID0gJzU4MjA3MDA4MWVlYjFmMzEyZWM3NWFmMWI0Zjk0YTc5NjNkYjNiMjY0ZjI0NTEzNjllNGVhMjQ0YTU0ZGU1ZDAnO1xuICAgIGNvbnN0IGtleVBhaXIgPSBuZXcgS2V5UGFpcigpO1xuXG4gICAgY29uc3QgcGtleSA9IENhcmRhbm9XYXNtLlByaXZhdGVLZXkuZnJvbV9ub3JtYWxfYnl0ZXMoQnVmZmVyLmZyb20oa2V5UGFpci5nZXRLZXlzKCkucHJ2ISwgJ2hleCcpKTtcbiAgICBjb25zdCB2a2V5dyA9IENhcmRhbm9XYXNtLm1ha2VfdmtleV93aXRuZXNzKFxuICAgICAgQ2FyZGFub1dhc20uVHJhbnNhY3Rpb25IYXNoLmZyb21fYnl0ZXMoQnVmZmVyLmZyb20odHhSYXcsICdoZXgnKSksXG4gICAgICBwa2V5XG4gICAgKTtcbiAgICBjb25zdCBzaWcxID0gdmtleXcuc2lnbmF0dXJlKCkudG9faGV4KCk7XG5cbiAgICBjb25zdCBzaWcyID0gQnVmZmVyLmZyb20oa2V5UGFpci5zaWduTWVzc2FnZSh0eFJhdykpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICBzaG91bGQuZXF1YWwoc2lnMSwgc2lnMik7XG4gIH0pO1xuXG4gIC8vIE5PVEU6IFRoZSB0ZXN0cyBiZWxvdyBoYXZlIGJlZW4gY29tbWVudGVkIG91dCBhcyB0aGV5IGFyZSBmb3IgdGVzdGluZyBkdXJpbmcgZGV2ZWxvcG1lbnQgY2hhbmdlcy4gV2UgZG9uJ3RcbiAgLy8gd2FudCBmdWxsIG5vZGUgdGVzdHMgYXMgcGFydCBvZiBvdXIgc2RrIHVuaXQgdGVzdHMuIElmIHlvdSBhcmUgY29tbWVudGluZyB0aGVzZSBiYWNrIGluLCBhZGQgYXhpb3MgYW5kXG4gIC8vIEFkZHJlc3NGb3JtYXQgaW1wb3J0cy5cblxuICAvLyB4aXQoJ3Nob3VsZCBzdWJtaXQgYSB0cmFuc2FjdGlvbicsIGFzeW5jICgpID0+IHtcbiAgLy8gICBjb25zdCBrZXlQYWlyID0gbmV3IEtleVBhaXIoeyBwcnY6IHRlc3REYXRhLnByaXZhdGVLZXlzLnBydktleTQgfSk7XG4gIC8vICAgY29uc3Qgc2VuZGVyQWRkcmVzcyA9IGtleVBhaXIuZ2V0QWRkcmVzcyhBZGRyZXNzRm9ybWF0LnRlc3RuZXQpO1xuICAvL1xuICAvLyAgIGNvbnN0IGF4aW9zQ29uZmlnID0ge1xuICAvLyAgICAgaGVhZGVyczoge1xuICAvLyAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2Nib3InLFxuICAvLyAgICAgfSxcbiAgLy8gICAgIHRpbWVvdXQ6IDEwMDAwLFxuICAvLyAgIH07XG4gIC8vXG4gIC8vICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRUcmFuc2ZlckJ1aWxkZXIoKTtcbiAgLy8gICBjb25zdCB1dHhvRGF0YSA9IGF3YWl0IGF4aW9zLmdldCgnaHR0cHM6Ly90ZXN0bmV0LmtvaW9zLnJlc3QvYXBpL3YwL2FkZHJlc3NfaW5mbz9fYWRkcmVzcz0nICsgc2VuZGVyQWRkcmVzcyk7XG4gIC8vICAgY29uc3Qgc2VuZGVyQmFsYW5jZSA9IHV0eG9EYXRhLmRhdGFbMF0uYmFsYW5jZTtcbiAgLy8gICB0eEJ1aWxkZXIuY2hhbmdlQWRkcmVzcyhzZW5kZXJBZGRyZXNzLCBzZW5kZXJCYWxhbmNlKTtcbiAgLy8gICBjb25zdCB1dHhvU2V0ID0gdXR4b0RhdGEuZGF0YVswXS51dHhvX3NldDtcbiAgLy8gICBmb3IgKGNvbnN0IHV0eG8gb2YgdXR4b1NldCkge1xuICAvLyAgICAgdHhCdWlsZGVyLmlucHV0KHsgdHJhbnNhY3Rpb25faWQ6IHV0eG8udHhfaGFzaCwgdHJhbnNhY3Rpb25faW5kZXg6IHV0eG8udHhfaW5kZXggfSk7XG4gIC8vICAgfVxuICAvL1xuICAvLyAgIHR4QnVpbGRlci5vdXRwdXQoe1xuICAvLyAgICAgYWRkcmVzczpcbiAgLy8gICAgICAgJ2FkZHJfdGVzdDFxejJmeHYydW15aHR0a3h5eHA4eDBkbHBkdDNrNmN3bmc1cHhqM2poc3lkemVyM2pjdTVkOHBzN3pleDJrMnh0M3VxeGdqcW5uajgzd3M4bGhybjY0OGpqeHR3cTJ5dGpxcCcsXG4gIC8vICAgICBhbW91bnQ6ICc1MDAwMDAwJyxcbiAgLy8gICB9KTtcbiAgLy9cbiAgLy8gICB0eEJ1aWxkZXIudHRsKDgwMDAwMDAwMCk7XG4gIC8vICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IGtleVBhaXIuZ2V0S2V5cygpLnBydiB9KTtcbiAgLy9cbiAgLy8gICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAvLyAgIGNvbnN0IHNlcmlhbGl6ZWRUeCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gIC8vICAgY29uc3QgYnl0ZXMgPSBVaW50OEFycmF5LmZyb20oQnVmZmVyLmZyb20oc2VyaWFsaXplZFR4LCAnaGV4JykpO1xuICAvL1xuICAvLyAgIHRyeSB7XG4gIC8vICAgICBjb25zdCByZXMgPSBhd2FpdCBheGlvcy5wb3N0KCdodHRwczovL3Rlc3RuZXQua29pb3MucmVzdC9hcGkvdjAvc3VibWl0dHgnLCBieXRlcywgYXhpb3NDb25maWcpO1xuICAvLyAgICAgY29uc29sZS5sb2cocmVzLmRhdGEpO1xuICAvLyAgIH0gY2F0Y2ggKGVycikge1xuICAvLyAgICAgY29uc29sZS5sb2coZXJyKTtcbiAgLy8gICB9XG4gIC8vIH0pO1xuICAvL1xuICAvLyB4aXQoJ3Nob3VsZCBzdWJtaXQgYSB0cmFuc2FjdGlvbiB1c2luZyBzaWduYXR1cmUgaW50ZXJmYWNlJywgYXN5bmMgKCkgPT4ge1xuICAvLyAgIGNvbnN0IGtleVBhaXIgPSBuZXcgS2V5UGFpcih7IHBydjogdGVzdERhdGEucHJpdmF0ZUtleXMucHJ2S2V5NCB9KTtcbiAgLy8gICBjb25zdCBzZW5kZXJBZGRyZXNzID0ga2V5UGFpci5nZXRBZGRyZXNzKEFkZHJlc3NGb3JtYXQudGVzdG5ldCk7XG4gIC8vICAgY29uc3QgYXhpb3NDb25maWcgPSB7XG4gIC8vICAgICBoZWFkZXJzOiB7XG4gIC8vICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vY2JvcicsXG4gIC8vICAgICB9LFxuICAvLyAgICAgdGltZW91dDogMTAwMDAsXG4gIC8vICAgfTtcbiAgLy8gICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAvLyAgIGNvbnN0IHV0eG9EYXRhID0gYXdhaXQgYXdhaXQgYXhpb3MuZ2V0KCdodHRwczovL3Rlc3RuZXQua29pb3MucmVzdC9hcGkvdjAvYWRkcmVzc19pbmZvP19hZGRyZXNzPScgKyBzZW5kZXJBZGRyZXNzKTtcbiAgLy8gICBjb25zdCBzZW5kZXJCYWxhbmNlID0gdXR4b0RhdGEuZGF0YVswXS5iYWxhbmNlO1xuICAvLyAgIHR4QnVpbGRlci5jaGFuZ2VBZGRyZXNzKHNlbmRlckFkZHJlc3MsIHNlbmRlckJhbGFuY2UpO1xuICAvLyAgIGNvbnN0IHV0eG9TZXQgPSB1dHhvRGF0YS5kYXRhWzBdLnV0eG9fc2V0O1xuICAvLyAgIGZvciAoY29uc3QgdXR4byBvZiB1dHhvU2V0KSB7XG4gIC8vICAgICB0eEJ1aWxkZXIuaW5wdXQoeyB0cmFuc2FjdGlvbl9pZDogdXR4by50eF9oYXNoLCB0cmFuc2FjdGlvbl9pbmRleDogdXR4by50eF9pbmRleCB9KTtcbiAgLy8gICB9XG4gIC8vICAgdHhCdWlsZGVyLm91dHB1dCh7XG4gIC8vICAgICBhZGRyZXNzOlxuICAvLyAgICAgICAnYWRkcl90ZXN0MXF6MmZ4djJ1bXlodHRreHl4cDh4MGRscGR0M2s2Y3duZzVweGozamhzeWR6ZXIzamN1NWQ4cHM3emV4MmsyeHQzdXF4Z2pxbm5qODN3czhsaHJuNjQ4amp4dHdxMnl0anFwJyxcbiAgLy8gICAgIGFtb3VudDogJzUwMDAwMDAnLFxuICAvLyAgIH0pO1xuICAvL1xuICAvLyAgIHR4QnVpbGRlci50dGwoODAwMDAwMDAwKTtcbiAgLy9cbiAgLy8gICBjb25zdCB1bnNpZ25lZFR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gIC8vICAgY29uc3Qgc2VyaWFsaXplZFR4ID0gdW5zaWduZWRUeC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAvL1xuICAvLyAgIGNvbnN0IHR4QnVpbGRlcjIgPSBmYWN0b3J5LmZyb20oc2VyaWFsaXplZFR4KTtcbiAgLy8gICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlcjIuYnVpbGQoKTtcbiAgLy8gICBjb25zdCBzaWduYWJsZUhleCA9IHR4LnNpZ25hYmxlUGF5bG9hZC50b1N0cmluZygnaGV4Jyk7XG4gIC8vICAgY29uc3Qgc2lnbmF0dXJlID0ga2V5UGFpci5zaWduTWVzc2FnZShzaWduYWJsZUhleCk7XG4gIC8vICAgdHhCdWlsZGVyMi5hZGRTaWduYXR1cmUoeyBwdWI6IGtleVBhaXIuZ2V0S2V5cygpLnB1YiB9LCBCdWZmZXIuZnJvbShzaWduYXR1cmUpKTtcbiAgLy8gICBjb25zdCBzaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IHR4QnVpbGRlcjIuYnVpbGQoKTtcbiAgLy8gICBjb25zdCBzZXJpYWxpemVkVHJhbnNhY3Rpb24gPSBzaWduZWRUcmFuc2FjdGlvbi50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAvLyAgIGNvbnN0IGJ5dGVzID0gVWludDhBcnJheS5mcm9tKEJ1ZmZlci5mcm9tKHNlcmlhbGl6ZWRUcmFuc2FjdGlvbiwgJ2hleCcpKTtcbiAgLy9cbiAgLy8gICB0cnkge1xuICAvLyAgICAgY29uc3QgcmVzID0gYXdhaXQgYXhpb3MucG9zdCgnaHR0cHM6Ly90ZXN0bmV0LmtvaW9zLnJlc3QvYXBpL3YwL3N1Ym1pdHR4JywgYnl0ZXMsIGF4aW9zQ29uZmlnKTtcbiAgLy8gICAgIGNvbnNvbGUubG9nKHJlcy5kYXRhKTtcbiAgLy8gICB9IGNhdGNoIChlcnIpIHtcbiAgLy8gICAgIGNvbnNvbGUubG9nKGVycik7XG4gIC8vICAgfVxuICAvLyB9KTtcbn0pO1xuIl19Выполнить команду
Для локальной разработки. Не используйте в интернете!