PHP WebShell
Текущая директория: /opt/BitGoJS/modules/bitgo/dist/test/v2/unit
Просмотр файла: recovery.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const should = require("should");
const nock = require("nock");
const sdk_test_1 = require("@bitgo/sdk-test");
const src_1 = require("../../../src");
const sdk_core_1 = require("@bitgo/sdk-core");
const sdk_lib_mpc_1 = require("@bitgo/sdk-lib-mpc");
const tx_1 = require("@ethereumjs/tx");
const sinon = require("sinon");
const recoveryFixtures_1 = require("../fixtures/tss/recoveryFixtures");
const sdk_coin_xrp_1 = require("@bitgo/sdk-coin-xrp");
const recoveryNocks = require('../lib/recovery-nocks');
nock.disableNetConnect();
describe('Recovery:', function () {
let bitgo;
before(function () {
bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'test' });
bitgo.initializeTestVars();
// pretend that Keyternal accepts recoveries for all coins
sdk_core_1.krsProviders.keyternal.supportedCoins = ['btc', 'eth', 'xrp', 'bch', 'bcha', 'ltc', 'zec', 'dash', 'xlm', 'bsv'];
sdk_core_1.krsProviders.keyternal.feeAddresses = {
tbtc: '2Mujz9eicmgpPcdScRJTywVK3EQNHDJG3yN',
tbch: '2Mujz9eicmgpPcdScRJTywVK3EQNHDJG3yN',
tbsv: '2Mujz9eicmgpPcdScRJTywVK3EQNHDJG3yN',
tbcha: '2Mujz9eicmgpPcdScRJTywVK3EQNHDJG3yN',
tltc: 'QffXMViM8DYgPRf1Hoczjw7BS5CVdSWaBL',
tzec: 't2ATLAhBP1uTuyiWs5DY5CPH1VuYkGUindt',
tdash: '8euHug4dbmPy3CLawwWdeTjGLqPYEGz3Kt',
};
});
after(function () {
nock.cleanAll();
});
describe('Recover Ripple', function () {
it('should generate XRP recovery tx', function () {
recoveryNocks.nockXrpRecovery();
const basecoin = bitgo.coin('txrp');
return basecoin
.recover({
userKey: '{"iv":"rU++mEtIHtbp3d4jg5EulA==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"ip1rb59uYnM=","ct":"ssmP9abPoVyXkW4Io0SUy+AAS8lr+wgIerTMw+lDYnkUh0sjlI4A6Fpve0q1riQ3Dy/J0bNu7dgoZkO4xs/X6dzwEwlmPhk3pEQ7Yd4CXa1zA01y0Geu900FLe4LdaS8jt6fixui2tTd4Vi3JYglF1/HmCjG1Ug="}',
backupKey: '{"iv":"uB/BTcn1rXmgYGfncXOowg==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"I3WrumxkuMQ=","ct":"sgyDNAzNsBruTRm0d04oBTBf8lheHNKS+dRgl8FeMEhodKsiyjtRVHG0CHPf5rV3g5ixVnZ+iwsSCv3PKyyeoy7RGnT0AG9YYpi0me+OvP8331iO+n5quzstrGbV1j8uEh5IMW78S+YUZKSx6zbbdZ0xNu8D5WM="}',
rootAddress: 'raGZWRkRBUWdQJsKYEzwXJNbCZMTqX56aA',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_WALLET1_PASSCODE,
recoveryDestination: 'rsv2kremJSSFbbaLqrf8fWxxN5QnsynNm2?dt=12345',
})
.then(function (recovery) {
recovery.txHex.should.equal('120000228000000024000000042E00003039201B0015519161400000024E06C0C068400000000000001E7300811439CA010E0E0198150F8DDD5768CCD2B095701D8C8314201276ADC469C4F10D1369E0F5C5A7DEF37B2267F3E0107321026C91974146427889C801BD26CE31CE0E10307A69DFE4139DE45E5E35933A6B037446304402204AA3D2F344729B0BB9075C4AEA07EBB2EAF6D3F36309BCAEF10B2C9734AC943E022032D55EC19E27B2E90E3D9444FD26CC06FD47BB3E3D85B0FCC0CC4DE7038563FD8114ABB5B7C843F3AA8D8EFACC3C5A7D9B0484C17442E1E010732102F4E376133012F5404990C7E1DF83A9F943B30D55F0D856632C8E8378FCEB70D2744630440220568F1D49F5810458E7204A1D2D23B86B694505327E8410A215AB9C9324EA8A3102207A93211ACFB5E9C1441B701A7954B72A3054265BA3FD61965D709E4C4E9080F38114ACEF9F0A2FCEC44A9A213444A9E6C57E2D02856AE1F1');
recovery.id.should.equal('F2005B392E9454FF1E8217B816C87866A56770382B8FCAC0AAE2FA8D12A53B98');
recovery.outputAmount.should.equal('9899000000');
recovery.outputs.length.should.equal(1);
recovery.outputs[0].address.should.equal('rsv2kremJSSFbbaLqrf8fWxxN5QnsynNm2?dt=12345');
recovery.outputs[0].amount.should.equal('9899000000');
recovery.fee.fee.should.equal('30');
});
});
it('should generate XRP recovery tx with KRS', function () {
recoveryNocks.nockXrpRecovery();
const basecoin = bitgo.coin('txrp');
return basecoin
.recover({
userKey: '{"iv":"rU++mEtIHtbp3d4jg5EulA==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"ip1rb59uYnM=","ct":"ssmP9abPoVyXkW4Io0SUy+AAS8lr+wgIerTMw+lDYnkUh0sjlI4A6Fpve0q1riQ3Dy/J0bNu7dgoZkO4xs/X6dzwEwlmPhk3pEQ7Yd4CXa1zA01y0Geu900FLe4LdaS8jt6fixui2tTd4Vi3JYglF1/HmCjG1Ug="}',
backupKey: 'xpub661MyMwAqRbcFtWdmWHKZEh9pYiJrAGTu1NNSwxY2S63tU9nGcfCAbNUKQuFqXRTRk8KkuBabxo6YjeBri8Q7dkMsmths6MVxSd6MTaeCmd',
rootAddress: 'raGZWRkRBUWdQJsKYEzwXJNbCZMTqX56aA',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_WALLET1_PASSCODE,
krsProvider: 'keyternal',
recoveryDestination: 'rsv2kremJSSFbbaLqrf8fWxxN5QnsynNm2?dt=12345',
})
.then(function (recovery) {
recovery.txHex.should.equal('120000228000000024000000042E00003039201B0015519161400000024E06C0C068400000000000001E7300811439CA010E0E0198150F8DDD5768CCD2B095701D8C8314201276ADC469C4F10D1369E0F5C5A7DEF37B2267F3E010732102F4E376133012F5404990C7E1DF83A9F943B30D55F0D856632C8E8378FCEB70D2744630440220568F1D49F5810458E7204A1D2D23B86B694505327E8410A215AB9C9324EA8A3102207A93211ACFB5E9C1441B701A7954B72A3054265BA3FD61965D709E4C4E9080F38114ACEF9F0A2FCEC44A9A213444A9E6C57E2D02856AE1F1');
recovery.id.should.equal('6EA1728B0CC0C047E54AAF578D81822EDE1107908B979868299657E74A8E18C0');
recovery.outputAmount.should.equal('9899000000');
recovery.outputs.length.should.equal(1);
recovery.outputs[0].address.should.equal('rsv2kremJSSFbbaLqrf8fWxxN5QnsynNm2?dt=12345');
recovery.outputs[0].amount.should.equal('9899000000');
recovery.fee.fee.should.equal('30');
});
});
it('should generate an XRP unsigned sweep', function () {
recoveryNocks.nockXrpRecovery();
const basecoin = bitgo.coin('txrp');
return basecoin
.recover({
userKey: 'xpub661MyMwAqRbcF9Ya4zDHGzDtJz3NaaeEGbQ6rnqnNxL9RXDJNHcfzAyPUBXuKXjytvJNzQxqbjBwmPveiYX323Zp8Zx2RYQN9gGM7ntiXxr',
backupKey: 'xpub661MyMwAqRbcFtWdmWHKZEh9pYiJrAGTu1NNSwxY2S63tU9nGcfCAbNUKQuFqXRTRk8KkuBabxo6YjeBri8Q7dkMsmths6MVxSd6MTaeCmd',
rootAddress: 'raGZWRkRBUWdQJsKYEzwXJNbCZMTqX56aA',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_WALLET1_PASSCODE,
krsProvider: 'keyternal',
recoveryDestination: 'rsv2kremJSSFbbaLqrf8fWxxN5QnsynNm2?dt=12345',
})
.then(function (recovery) {
recovery.txHex.should.equal('120000228000000024000000042E00003039201B0015519161400000024E06C0C068400000000000001E811439CA010E0E0198150F8DDD5768CCD2B095701D8C8314201276ADC469C4F10D1369E0F5C5A7DEF37B2267');
const tx = sdk_coin_xrp_1.Utils.decodeTransaction(recovery.txHex);
tx.TransactionType.should.equal('Payment');
tx.Account.should.equal('raGZWRkRBUWdQJsKYEzwXJNbCZMTqX56aA');
tx.Destination.should.equal('rsv2kremJSSFbbaLqrf8fWxxN5QnsynNm2');
tx.DestinationTag.should.equal(12345);
tx.Amount.should.equal('9899000000');
tx.Flags.should.equal(2147483648);
tx.LastLedgerSequence.should.equal(1397137);
tx.Fee.should.equal('30');
tx.Sequence.should.equal(4);
});
});
});
describe('Recover Stellar', function () {
async function checkRecoveryTxExplanation(basecoin, tx, recoveryAmount, recoveryDestination) {
const explanation = await basecoin.explainTransaction({ txBase64: tx });
explanation.should.have.property('outputs');
explanation.outputs.should.containEql({
amount: recoveryAmount.toFixed(),
address: recoveryDestination,
coin: basecoin.getChain(),
});
explanation.should.have.property('changeOutputs', []);
explanation.should.have.property('changeAmount', '0');
explanation.should.have.property('fee', { fee: '100', feeRate: null, size: null });
explanation.should.have.property('operations', []);
}
it('should generate XLM recovery tx', async function () {
recoveryNocks.nockXlmRecovery();
const recoveryParams = {
userKey: `{"iv":"PiLveA+5AFPURwaU7iijBQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"KlJc8NSKHpw=","ct":"YcdNOFpzXgDnRqjlR3W9R+5eztysyhpCTuRBHsnPyPDst9nvL+GeSORbLY9xVThTdyV6llRgfUr5O7y4l9s9Fg=="}`,
backupKey: `{"iv":"TmiAIHr0vCX6g2BKkc6/7g==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"wOkMJEm5B6U=","ct":"HJPS56/FuMieiH6K2s5k5jFp8RPHQqZa9qi8hDkjOqNUFjD4XKq8Sy3BDhpwzozTBW6EmQGSF0kpc7eZ9CucKw=="}`,
rootAddress: 'GAUAGTL3NBZ7NP3UIMZCVJYM6O2NKUP6XRTK4E5VZDVIQX3CBYIVMDIB',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
recoveryDestination: 'GASW277S2ZOE7H7A5EQ5H5AKLP6UA6Z5AKOSWV6ARBEGTSIGMZMC7AIZ',
};
const recoveryAmount = 74999500;
const basecoin = bitgo.coin('txlm');
const recovery = await basecoin.recover(recoveryParams);
recovery.should.have.property('txBase64');
recovery.should.have.property('recoveryAmount', recoveryAmount);
await checkRecoveryTxExplanation(basecoin, recovery.txBase64, recoveryAmount, recoveryParams.recoveryDestination);
});
it('should recover to an unfunded XLM wallet', async function () {
recoveryNocks.nockXlmRecovery();
const recoveryParams = {
userKey: `{"iv":"PiLveA+5AFPURwaU7iijBQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"KlJc8NSKHpw=","ct":"YcdNOFpzXgDnRqjlR3W9R+5eztysyhpCTuRBHsnPyPDst9nvL+GeSORbLY9xVThTdyV6llRgfUr5O7y4l9s9Fg=="}`,
backupKey: `{"iv":"TmiAIHr0vCX6g2BKkc6/7g==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"wOkMJEm5B6U=","ct":"HJPS56/FuMieiH6K2s5k5jFp8RPHQqZa9qi8hDkjOqNUFjD4XKq8Sy3BDhpwzozTBW6EmQGSF0kpc7eZ9CucKw=="}`,
rootAddress: 'GAUAGTL3NBZ7NP3UIMZCVJYM6O2NKUP6XRTK4E5VZDVIQX3CBYIVMDIB',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
recoveryDestination: 'GAGCQLUGMX76XC24JRCRJWOHXK23ONURH4433JOEPU6CH7Z44CCYUCEL',
};
const recoveryAmount = 74999500;
const basecoin = bitgo.coin('txlm');
const recovery = await basecoin.recover(recoveryParams);
recovery.should.have.property('txBase64');
recovery.should.have.property('recoveryAmount', recoveryAmount);
await checkRecoveryTxExplanation(basecoin, recovery.txBase64, recoveryAmount, recoveryParams.recoveryDestination);
});
it('should generate XLM recovery tx with unencrypted keys', async function () {
recoveryNocks.nockXlmRecovery();
const recoveryParams = {
userKey: `SAMF5XS7O5BL4OOTB625DELCVNW5JMHF2DDM7NSIVPNQQEKPKLBQFNJ3`,
backupKey: `SCXZ7UFVSIFIYJVPLWEAY22TZJOR4L2Z4HE6BMZGZHBBJ4UAABTFMK3V`,
rootAddress: 'GAUAGTL3NBZ7NP3UIMZCVJYM6O2NKUP6XRTK4E5VZDVIQX3CBYIVMDIB',
recoveryDestination: 'GASW277S2ZOE7H7A5EQ5H5AKLP6UA6Z5AKOSWV6ARBEGTSIGMZMC7AIZ',
};
const recoveryAmount = 74999500;
const basecoin = bitgo.coin('txlm');
const recovery = await basecoin.recover(recoveryParams);
recovery.should.have.property('txBase64');
recovery.should.have.property('recoveryAmount', recoveryAmount);
await checkRecoveryTxExplanation(basecoin, recovery.txBase64, recoveryAmount, recoveryParams.recoveryDestination);
});
it('should generate XLM recovery tx with unencrypted root private keys', async function () {
recoveryNocks.nockXlmRecovery();
// userKey and backupKey are in prv + pub representation
// first 64 characters (32 bytes) are the private key, the rest is the public key
const recoveryParams = {
userKey: `185ede5f7742be39d30fb5d19162ab6dd4b0e5d0c6cfb648abdb08114f52c3025aae152ef1470686aba3fec40889a550d7b53910c739e25b5d4a2f27eb512eb7`,
backupKey: `af9fd0b5920a8c26af5d880c6b53ca5d1e2f59e1c9e0b326c9c214f2800066568200a5e4dd279da5f422324b8210e898dbf68fc29c1f9cf791c224187fad7dc3`,
rootAddress: 'GAUAGTL3NBZ7NP3UIMZCVJYM6O2NKUP6XRTK4E5VZDVIQX3CBYIVMDIB',
recoveryDestination: 'GASW277S2ZOE7H7A5EQ5H5AKLP6UA6Z5AKOSWV6ARBEGTSIGMZMC7AIZ',
};
const recoveryAmount = 74999500;
const basecoin = bitgo.coin('txlm');
const recovery = await basecoin.recover(recoveryParams);
recovery.should.have.property('txBase64');
recovery.should.have.property('recoveryAmount', recoveryAmount);
await checkRecoveryTxExplanation(basecoin, recovery.txBase64, recoveryAmount, recoveryParams.recoveryDestination);
});
it('should generate XLM recovery tx with encrypted root keys', async function () {
recoveryNocks.nockXlmRecovery();
// userKey and backupKey are in encrypted prv + pub representation
const recoveryParams = {
userKey: `{"iv":"bUHw53Oa8tSrFRzidPi8ag==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"QHNZFlDnCW0=","ct":"AQSABvUmCMsD3rJQzyg29TnLPnDVCZFXZkg9hJ2ReYaXWWkSb8Bw0nn3LW/GIGi3ZbOgPivJ4LhCbO9A2pp4aVOhbsbqCNBWxpmHzneVS3FPrLebQixH1Rn0X+ft2I9XcNNEklEw5cH3pf9I1vqLmwEHpF8DWx0OgGnlh/Qq0r5ZaEt5tbTDPA=="}`,
backupKey: `{"iv":"19SQ3SlLzuTbEfU7s8lTHQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"jLM2oWyO8Wg=","ct":"iXUdNcqhsbykfyLKYrcEegSHooAJt82krdSWhQhs/cUAoA6tX4j+HfOutQhSPDtJkIpbz19ynoTo8VVpxp/Ga+ubQVlClbZPyhC8YkCRvJBvWKg41EEGlyduK7esVrnnv1c4Xk4a4BaXszOEdGw/1aQB9AOQMMVsv6z8Yhu55QqVz6zN49PmaQ=="}`,
rootAddress: 'GAUAGTL3NBZ7NP3UIMZCVJYM6O2NKUP6XRTK4E5VZDVIQX3CBYIVMDIB',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
recoveryDestination: 'GASW277S2ZOE7H7A5EQ5H5AKLP6UA6Z5AKOSWV6ARBEGTSIGMZMC7AIZ',
};
const recoveryAmount = 74999500;
const basecoin = bitgo.coin('txlm');
const recovery = await basecoin.recover(recoveryParams);
recovery.should.have.property('txBase64');
recovery.should.have.property('recoveryAmount', recoveryAmount);
await checkRecoveryTxExplanation(basecoin, recovery.txBase64, recoveryAmount, recoveryParams.recoveryDestination);
});
it('should generate XLM recovery tx with KRS', async function () {
recoveryNocks.nockXlmRecovery();
const recoveryParams = {
userKey: `{"iv":"PiLveA+5AFPURwaU7iijBQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"KlJc8NSKHpw=","ct":"YcdNOFpzXgDnRqjlR3W9R+5eztysyhpCTuRBHsnPyPDst9nvL+GeSORbLY9xVThTdyV6llRgfUr5O7y4l9s9Fg=="}`,
backupKey: 'GCBABJPE3UTZ3JPUEIZEXAQQ5CMNX5UPYKOB7HHXSHBCIGD7VV64H6KU',
rootAddress: 'GAUAGTL3NBZ7NP3UIMZCVJYM6O2NKUP6XRTK4E5VZDVIQX3CBYIVMDIB',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
recoveryDestination: 'GASW277S2ZOE7H7A5EQ5H5AKLP6UA6Z5AKOSWV6ARBEGTSIGMZMC7AIZ',
krsProvider: 'keyternal',
};
const recoveryAmount = 74999500;
const basecoin = bitgo.coin('txlm');
const recovery = await basecoin.recover(recoveryParams);
recovery.should.have.property('txBase64');
recovery.should.have.property('recoveryAmount', 74999500);
await checkRecoveryTxExplanation(basecoin, recovery.txBase64, recoveryAmount, recoveryParams.recoveryDestination);
});
it('should generate XLM recovery tx with KRS using root keys', async function () {
recoveryNocks.nockXlmRecovery();
// userKey is in encrypted prv + pub representation
const recoveryParams = {
userKey: `{"iv":"bUHw53Oa8tSrFRzidPi8ag==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"QHNZFlDnCW0=","ct":"AQSABvUmCMsD3rJQzyg29TnLPnDVCZFXZkg9hJ2ReYaXWWkSb8Bw0nn3LW/GIGi3ZbOgPivJ4LhCbO9A2pp4aVOhbsbqCNBWxpmHzneVS3FPrLebQixH1Rn0X+ft2I9XcNNEklEw5cH3pf9I1vqLmwEHpF8DWx0OgGnlh/Qq0r5ZaEt5tbTDPA=="}`,
backupKey: '8200a5e4dd279da5f422324b8210e898dbf68fc29c1f9cf791c224187fad7dc3', // this is a pub root key, note it is 32 bytes
rootAddress: 'GAUAGTL3NBZ7NP3UIMZCVJYM6O2NKUP6XRTK4E5VZDVIQX3CBYIVMDIB',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
recoveryDestination: 'GASW277S2ZOE7H7A5EQ5H5AKLP6UA6Z5AKOSWV6ARBEGTSIGMZMC7AIZ',
krsProvider: 'keyternal',
};
const recoveryAmount = 74999500;
const basecoin = bitgo.coin('txlm');
const recovery = await basecoin.recover(recoveryParams);
recovery.should.have.property('txBase64');
recovery.should.have.property('recoveryAmount', 74999500);
await checkRecoveryTxExplanation(basecoin, recovery.txBase64, recoveryAmount, recoveryParams.recoveryDestination);
});
it('should generate an XLM unsigned sweep', async function () {
recoveryNocks.nockXlmRecovery();
const recoveryParams = {
userKey: 'GBNK4FJO6FDQNBVLUP7MICEJUVINPNJZCDDTTYS3LVFC6J7LKEXLOBKM',
backupKey: 'GCBABJPE3UTZ3JPUEIZEXAQQ5CMNX5UPYKOB7HHXSHBCIGD7VV64H6KU',
rootAddress: 'GAUAGTL3NBZ7NP3UIMZCVJYM6O2NKUP6XRTK4E5VZDVIQX3CBYIVMDIB',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
recoveryDestination: 'GASW277S2ZOE7H7A5EQ5H5AKLP6UA6Z5AKOSWV6ARBEGTSIGMZMC7AIZ',
krsProvider: 'keyternal',
};
const recoveryAmount = 74999500;
const basecoin = bitgo.coin('txlm');
const recovery = await basecoin.recover(recoveryParams);
recovery.should.have.property('txBase64');
recovery.should.have.property('recoveryAmount', 74999500);
await checkRecoveryTxExplanation(basecoin, recovery.txBase64, recoveryAmount, recoveryParams.recoveryDestination);
});
it('should generate an XLM unsigned sweep using root keys', async function () {
recoveryNocks.nockXlmRecovery();
const recoveryParams = {
userKey: '5aae152ef1470686aba3fec40889a550d7b53910c739e25b5d4a2f27eb512eb7', // this is a pub key, note it is 32 bytes
backupKey: '8200a5e4dd279da5f422324b8210e898dbf68fc29c1f9cf791c224187fad7dc3', // this is a pub root key, note it is 32 bytes
rootAddress: 'GAUAGTL3NBZ7NP3UIMZCVJYM6O2NKUP6XRTK4E5VZDVIQX3CBYIVMDIB',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
recoveryDestination: 'GASW277S2ZOE7H7A5EQ5H5AKLP6UA6Z5AKOSWV6ARBEGTSIGMZMC7AIZ',
krsProvider: 'keyternal',
};
const recoveryAmount = 74999500;
const basecoin = bitgo.coin('txlm');
const recovery = await basecoin.recover(recoveryParams);
recovery.should.have.property('txBase64');
recovery.should.have.property('recoveryAmount', 74999500);
await checkRecoveryTxExplanation(basecoin, recovery.txBase64, recoveryAmount, recoveryParams.recoveryDestination);
});
});
describe('Recover TRON', function () {
let baseCoin;
before(function () {
baseCoin = bitgo.coin('ttrx');
});
afterEach(function () {
nock.cleanAll();
});
it('should generate recovery tx from encrypted user and backup keys', async function () {
recoveryNocks.nockTronRecovery();
const recoveryTx = await baseCoin.recover({
userKey: '{"iv":"eXwYIygDyRy1R1lw9EwEgQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"NNOxF+LR7aU=","ct":"qX/G+AiZJ35XwUmL9alYitRwvYgE/bS24DSAVV7tBaoTs40tsVB/kWx+hV/J5acKIA6Z/wSucxbKrQlJB69xJJl/OirYqmXRBirH+rag1aC1zj7ZVnbO+h+P5GHqHJltLc4UyDf+p22+NjoDLfR+fEPtG8c4v5o="}',
backupKey: '{"iv":"QaoXCEkibo4VMEyo3fSUUQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"iqqtrBtC5vY=","ct":"JHbHJ8U2Ala2cRFcoqTAftLYmDDSOTfhdVmZkmW/ORJeP60Vf5T1m661yWQT3ADKSsq2CSRV49OqSfH2lIOBU3EfXdFXkWQeTNX+bhzC6E2o/us3SnwlXhO659DQMPmLthvgCTX8xM+5UzgV/PYnqFpSuxl379s="}',
bitgoKey: 'xpub661MyMwAqRbcEx6zKTBrgZkWPBGvx8qguEd1NqEDp6yW3srBGhTUdFkcdcBjp5FQgXkDNiQBdj6Fsgka8D9VFYt32M2GsCTRuffnXMhq1ho',
walletPassphrase: 'test_wallet_passphrase',
recoveryDestination: 'TYPgx8NfDxB8pyiyTeiMkYzem1dNA6G12i',
});
should.exist(recoveryTx);
recoveryTx.coin.should.equal('ttrx');
recoveryTx.feeInfo.fee.should.equal('2100000');
recoveryTx.recoveryAmount.should.equal(899047400);
recoveryTx.txHex.should.equal('{"visible":false,"txID":"98b398e3027e601870a86b0785f1f1d301f087dbaafe44337507b5001bae0d49","raw_data":{"contract":[{"parameter":{"value":{"amount":10000000,"owner_address":"41e7e11df2c5704888c3cb63fb43a9498bd1812cb2","to_address":"41f5f414d447aafe70bb9b9d93912cbc4c54f0c014"},"type_url":"type.googleapis.com/protocol.TransferContract"},"type":"TransferContract"}],"ref_block_bytes":"a762","ref_block_hash":"18dfe946fbf7a0ac","expiration":1676746443000,"timestamp":1676659983799},"raw_data_hex":"0a02a762220818dfe946fbf7a0ac40f89181afe6305a69080112650a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412340a1541e7e11df2c5704888c3cb63fb43a9498bd1812cb2121541f5f414d447aafe70bb9b9d93912cbc4c54f0c01418c8d19cad0370b78be485e630","signature":["79a110116657e75be81400ad4a9f738fd098695fc5fc6009176aa1c27924c4cdb2989fe2052b70c739b10cd3881c9872660b83998dc9316e6c8d11fb588d731d00","250d0bae2491596bd800d830aa9d4c6d25e1d01a4c860b856d6000a8ab8fa2082a1ae20168e0ab97c9ffd64824b483b9843db74e9553d5d9e68a3a64d414dd1201"]}');
recoveryTx.tx.signature[0].should.equal('79a110116657e75be81400ad4a9f738fd098695fc5fc6009176aa1c27924c4cdb2989fe2052b70c739b10cd3881c9872660b83998dc9316e6c8d11fb588d731d00');
recoveryTx.tx.signature[1].should.equal('250d0bae2491596bd800d830aa9d4c6d25e1d01a4c860b856d6000a8ab8fa2082a1ae20168e0ab97c9ffd64824b483b9843db74e9553d5d9e68a3a64d414dd1201');
recoveryTx.tx.txID.should.equal('98b398e3027e601870a86b0785f1f1d301f087dbaafe44337507b5001bae0d49');
recoveryTx.tx.raw_data_hex.should.equal('0a02a762220818dfe946fbf7a0ac40f89181afe6305a69080112650a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412340a1541e7e11df2c5704888c3cb63fb43a9498bd1812cb2121541f5f414d447aafe70bb9b9d93912cbc4c54f0c01418c8d19cad0370b78be485e630');
});
it('should generate recovery tx from encrypted user and backup keys from a receive address', async function () {
nock.cleanAll();
recoveryNocks.nockTronReceiveRecovery();
const recoveryTx = await baseCoin.recover({
userKey: '{"iv":"eXwYIygDyRy1R1lw9EwEgQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"NNOxF+LR7aU=","ct":"qX/G+AiZJ35XwUmL9alYitRwvYgE/bS24DSAVV7tBaoTs40tsVB/kWx+hV/J5acKIA6Z/wSucxbKrQlJB69xJJl/OirYqmXRBirH+rag1aC1zj7ZVnbO+h+P5GHqHJltLc4UyDf+p22+NjoDLfR+fEPtG8c4v5o="}',
backupKey: '{"iv":"QaoXCEkibo4VMEyo3fSUUQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"iqqtrBtC5vY=","ct":"JHbHJ8U2Ala2cRFcoqTAftLYmDDSOTfhdVmZkmW/ORJeP60Vf5T1m661yWQT3ADKSsq2CSRV49OqSfH2lIOBU3EfXdFXkWQeTNX+bhzC6E2o/us3SnwlXhO659DQMPmLthvgCTX8xM+5UzgV/PYnqFpSuxl379s="}',
bitgoKey: 'xpub661MyMwAqRbcEx6zKTBrgZkWPBGvx8qguEd1NqEDp6yW3srBGhTUdFkcdcBjp5FQgXkDNiQBdj6Fsgka8D9VFYt32M2GsCTRuffnXMhq1ho',
walletPassphrase: 'test_wallet_passphrase',
recoveryDestination: 'TEbha9FhQMZ3FRtZgok8QBunPQU4pZvBxX',
});
should.exist(recoveryTx);
recoveryTx.coin.should.equal('ttrx');
recoveryTx.feeInfo.fee.should.equal('2100000');
recoveryTx.recoveryAmount.should.equal(197900000);
recoveryTx.addressInfo.address.should.equal('TNeGpwAurk7kjQLdcdWhFr8YP8E9Za8w1x');
recoveryTx.addressInfo.chain.should.equal(0);
recoveryTx.addressInfo.index.should.equal(1);
recoveryTx.txHex.should.equal('{"visible":false,"txID":"da67e32e9ea3bd022f3d93ed259771dda9b444d41d1e63e54c8254a6ebb6332f","raw_data":{"contract":[{"parameter":{"value":{"amount":199000000,"owner_address":"418b04ecdc3db7e8da7cd838492f66e424a051e2cd","to_address":"4132c753bf8d3de7358748a75fcf299f146dff6e4e"},"type_url":"type.googleapis.com/protocol.TransferContract"},"type":"TransferContract"}],"ref_block_bytes":"81e0","ref_block_hash":"5b1b20e9ebeaa4f8","expiration":1686038682000,"timestamp":1685952224483},"raw_data_hex":"0a0281e022085b1b20e9ebeaa4f84090b3f2fd88315a68080112640a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412330a15418b04ecdc3db7e8da7cd838492f66e424a051e2cd12154132c753bf8d3de7358748a75fcf299f146dff6e4e18c0fff15e70e3b9d5d48831","signature":["94a31cdd64e93e375c3eebae5db4f66761cb49550f2cee9388b618e6836bc471ecf33e14122d62244737358e33a9d14a056ce8c7dc34dcfcb8ef2db15d40d83600"]}');
recoveryTx.tx.signature[0].should.equal('94a31cdd64e93e375c3eebae5db4f66761cb49550f2cee9388b618e6836bc471ecf33e14122d62244737358e33a9d14a056ce8c7dc34dcfcb8ef2db15d40d83600');
recoveryTx.tx.txID.should.equal('da67e32e9ea3bd022f3d93ed259771dda9b444d41d1e63e54c8254a6ebb6332f');
recoveryTx.tx.raw_data_hex.should.equal('0a0281e022085b1b20e9ebeaa4f84090b3f2fd88315a68080112640a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412330a15418b04ecdc3db7e8da7cd838492f66e424a051e2cd12154132c753bf8d3de7358748a75fcf299f146dff6e4e18c0fff15e70e3b9d5d48831');
});
it('should throw an error when there is no funds to flush', async function () {
recoveryNocks.nockTronReceiveRecoveryZeroFunds();
await baseCoin
.recover({
userKey: '{"iv":"eXwYIygDyRy1R1lw9EwEgQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"NNOxF+LR7aU=","ct":"qX/G+AiZJ35XwUmL9alYitRwvYgE/bS24DSAVV7tBaoTs40tsVB/kWx+hV/J5acKIA6Z/wSucxbKrQlJB69xJJl/OirYqmXRBirH+rag1aC1zj7ZVnbO+h+P5GHqHJltLc4UyDf+p22+NjoDLfR+fEPtG8c4v5o="}',
backupKey: '{"iv":"QaoXCEkibo4VMEyo3fSUUQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"iqqtrBtC5vY=","ct":"JHbHJ8U2Ala2cRFcoqTAftLYmDDSOTfhdVmZkmW/ORJeP60Vf5T1m661yWQT3ADKSsq2CSRV49OqSfH2lIOBU3EfXdFXkWQeTNX+bhzC6E2o/us3SnwlXhO659DQMPmLthvgCTX8xM+5UzgV/PYnqFpSuxl379s="}',
bitgoKey: 'xpub661MyMwAqRbcEx6zKTBrgZkWPBGvx8qguEd1NqEDp6yW3srBGhTUdFkcdcBjp5FQgXkDNiQBdj6Fsgka8D9VFYt32M2GsCTRuffnXMhq1ho',
walletPassphrase: 'test_wallet_passphrase',
recoveryDestination: 'TEbha9FhQMZ3FRtZgok8QBunPQU4pZvBxX',
})
.should.be.rejectedWith("Amount of funds to recover undefined is less than 2100000 and wouldn't be able to fund a send");
});
it('should generate recovery tx with unencrypted keys', async function () {
recoveryNocks.nockTronRecovery();
const recoveryTx = await baseCoin.recover({
userKey: 'xpub661MyMwAqRbcGKN3UxRqwKdVNRbJvqxiNaWBCfXcUJaEf56wqRsGR6R7tmWrpnjbdQLryb6hzx8RfXXsvRqBuB2idGg1NeD1yueWcsBoq7A',
backupKey: 'xpub661MyMwAqRbcF5b9fJAfJp6P9p2LmeZV7YbfgDkttGJrGdmLtsLxyHTQaoPE1pJr5EA7SBwMSzFmv2TvsDLtG42FeesyaVQazBX4YmD28bh',
bitgoKey: 'xpub661MyMwAqRbcEx6zKTBrgZkWPBGvx8qguEd1NqEDp6yW3srBGhTUdFkcdcBjp5FQgXkDNiQBdj6Fsgka8D9VFYt32M2GsCTRuffnXMhq1ho',
recoveryDestination: 'TYPgx8NfDxB8pyiyTeiMkYzem1dNA6G12i',
});
should.exist(recoveryTx);
recoveryTx.coin.should.equal('ttrx');
recoveryTx.feeInfo.fee.should.equal('2100000');
recoveryTx.recoveryAmount.should.equal(899047400);
recoveryTx.tx.txID.should.equal('98b398e3027e601870a86b0785f1f1d301f087dbaafe44337507b5001bae0d49');
recoveryTx.tx.raw_data_hex.should.equal('0a02a762220818dfe946fbf7a0ac40f89181afe6305a69080112650a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412340a1541e7e11df2c5704888c3cb63fb43a9498bd1812cb2121541f5f414d447aafe70bb9b9d93912cbc4c54f0c01418c8d19cad0370b78be485e630');
});
it('should generate an unsigned sweep', async function () {
recoveryNocks.nockTronRecovery();
const recoveryTx = await baseCoin.recover({
userKey: '{"iv":"eXwYIygDyRy1R1lw9EwEgQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"NNOxF+LR7aU=","ct":"qX/G+AiZJ35XwUmL9alYitRwvYgE/bS24DSAVV7tBaoTs40tsVB/kWx+hV/J5acKIA6Z/wSucxbKrQlJB69xJJl/OirYqmXRBirH+rag1aC1zj7ZVnbO+h+P5GHqHJltLc4UyDf+p22+NjoDLfR+fEPtG8c4v5o="}',
backupKey: 'xpub661MyMwAqRbcF5b9fJAfJp6P9p2LmeZV7YbfgDkttGJrGdmLtsLxyHTQaoPE1pJr5EA7SBwMSzFmv2TvsDLtG42FeesyaVQazBX4YmD28bh',
bitgoKey: 'xpub661MyMwAqRbcEx6zKTBrgZkWPBGvx8qguEd1NqEDp6yW3srBGhTUdFkcdcBjp5FQgXkDNiQBdj6Fsgka8D9VFYt32M2GsCTRuffnXMhq1ho',
walletPassphrase: 'test_wallet_passphrase',
recoveryDestination: 'TYPgx8NfDxB8pyiyTeiMkYzem1dNA6G12i',
});
should.exist(recoveryTx);
recoveryTx.coin.should.equal('ttrx');
recoveryTx.feeInfo.fee.should.equal('2100000');
recoveryTx.recoveryAmount.should.equal(899047400);
recoveryTx.tx.txID.should.equal('98b398e3027e601870a86b0785f1f1d301f087dbaafe44337507b5001bae0d49');
recoveryTx.tx.raw_data_hex.should.equal('0a02a762220818dfe946fbf7a0ac40f89181afe6305a69080112650a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412340a1541e7e11df2c5704888c3cb63fb43a9498bd1812cb2121541f5f414d447aafe70bb9b9d93912cbc4c54f0c01418c8d19cad0370b78be485e630');
});
it('should generate a token recovery tx from encrypted user and backup keys', async function () {
recoveryNocks.nockTronTokenRecovery();
const recoveryTx = await baseCoin.recover({
userKey: '{"iv":"RyjTV4B09tQT576jAM2nLg==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"nJdtmecHNME=","ct":"5rCeihO3pZmd+vMYStP0f0zLbJkHhdvax+6ZAr5R4VmvjJnQqWjKkz4iqV2F1dSZVzNTU97hHjZE5d3DpJhy7rFsFFIFVutjORSZv8Wnr0g99XOiEDbuDENE2BQyTkOzSYLLGIi71myuwgAjBuQMomk0+7gtfjY="}',
backupKey: '{"iv":"vnbzx3YnSRHRMUnEOTmHLw==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"2D32eMOgkZc=","ct":"yKP0jnRkv/XnMHP6mJMQGozvtkkiHJpYxD6o1n7FcN44oOJHoQAI0xrew7WyGTzOpzoA0E0BH00Abi9XINNnQ5LLgJRdIF0HbJxfkj1QvElckMH94DMxn14s9cYQgIkI676vhwFBhAAwvbN8458wqtXsl+0Lnrs="}',
bitgoKey: 'xpub661MyMwAqRbcGYq9RtWYzKuvqba2EHr9vAkDbPsNi1L9TmiHSRUXHqxe18P4DHXtDFtUy4Sb9bhpShHEWW9h3LwHM9bB2qoP2cwWTduV9nP',
walletPassphrase: 'test_wallet_passphrase',
tokenContractAddress: 'TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs',
recoveryDestination: 'TYPgx8NfDxB8pyiyTeiMkYzem1dNA6G12i',
});
should.exist(recoveryTx);
recoveryTx.tx.signature[0].should.equal('3a67eee7ae067cd85cae86530be338af2cff4034a30f39656e2d8117ff7915ad256176afcfbe8177c4195ea887d79740420b12f9ea7c5698a6d2eeec260f34df01');
recoveryTx.tx.signature[1].should.equal('551d41e007b8b36b2ac50297fd53678f196067848731f4340f7ee0eb6d963c24b11dde96727f3cf4d051af586869daa51394db0853e6d4c80e41fee414a9c95201');
recoveryTx.tx.txID.should.equal('28117d9f0c3ac1fe22fa2cb10412537763fea8ad6b4b8d0504d8f25c6141f43c');
recoveryTx.tx.raw_data_hex.should.equal('0a02a71c2208d0ecb53aa03882a640d89cf3aee6305aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a15416a0a05e098c628f7f3ca63dbb5756e5c0c01852112154142a1e39aefa49290f2b3f9ed688d7cecf86cd6e02244a9059cbb000000000000000000000000f5f414d447aafe70bb9b9d93912cbc4c54f0c014000000000000000000000000000000000000000000000000000000012410110070a2a9d685e630900180c2d72f');
});
});
describe('Recover EOS', function () {
let baseCoin;
const expectedPackedTrx = '7122315d5e91d408e1b3000000000100a6823403ea3055000000572d3ccdcd0150f3ea2e4cf4bc8300000000a8ed32322150f3ea2e4cf4bc83e0f27c27cc0adf7f40420f000000000004454f53000000000000';
const expectedTxId = '99c6a4eedf5cff246314bdc0a053c12d75488df3aa09474bad4ceca88d8b2498';
before(function () {
baseCoin = bitgo.coin('teos');
});
beforeEach(function () {
recoveryNocks.nockEosRecovery();
});
it('should generate EOS recovery tx with correct expiration date', async function () {
const recoveryTx = await baseCoin.recover({
userKey: '{"iv":"jRBZi43c7t4tvx7SgP8h0g==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"TgZqHtZrmLU=","ct":"hRntzrbcH81dOzlyr49nbAIJdHWqEKKVJx0s55kNV+fqUjKKoEuWqVGF1dPfQkkTkcIjFTNvuHsiGicVGSRf5RI3Q0ZD6YtCqO2bWX6t7HgBio5yYMaPy+cNJHmp6jHBQFZ9cCjqwAam/V+1mRvpJpn2dSWPotw="}',
backupKey: '{"iv":"qE+D+C6KXaZKFXXTM/AF5w==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"a/YD7/8gJFw=","ct":"tc2c1PfSjDS9TshXEIKKlToDcdCeL45fpGUWEPIM2+6CrvIuaXZC6/Hx9bza7VIoEPhJWHmgvoeAouto4PUpnyKJUuz+T46RY09XJs2rcDvbfMKblRsh6lzUc8O7ubTzJRNgFOUqkZM6qGB22A0FtL8yNlFqc3c="}',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
rootAddress: 'kiyjcn1ixftp',
recoveryDestination: 'jzjkpn1bjnti',
});
recoveryTx.should.have.property('transaction');
recoveryTx.transaction.compression.should.equal('none');
recoveryTx.transaction.packed_trx.should.equal(expectedPackedTrx);
recoveryTx.transaction.signatures.length.should.equal(2);
recoveryTx.txid.should.equal(expectedTxId);
const deserializeTransactionParams = {
transaction: {
packed_trx: recoveryTx.transaction.packed_trx,
},
};
const deserializedTx = await baseCoin.deserializeTransaction(deserializeTransactionParams);
const mockedHeadBlockTime = '2019-07-18T17:52:49.000';
const hoursUntilExpiration = 8;
const hourDiff = (new Date(deserializedTx.expiration).getTime() - new Date(mockedHeadBlockTime).getTime()) / 36e5;
hourDiff.should.equal(hoursUntilExpiration);
});
it('should generate EOS recovery tx with unencrypted keys', async function () {
const recoveryTx = await baseCoin.recover({
userKey: 'xprv9s21ZrQH143K4NDgnKH8zTTLpJuCmv6dtykRJwapBH73bvcvTvCQAMmQLxRGqg5YbvXBN5VGD3y2cPGUGyrVcjWDJM573RVseHg4oL64AXx',
backupKey: 'xprv9s21ZrQH143K4Gh3snX8z5d24djEVwCwVwdHGEssUpKwHqKDtAz8gRPw7Fi12NC3ur94CsJ2KormunQQm3gNkXQiTy534NdfuQ4C2EpdmRp',
rootAddress: 'kiyjcn1ixftp',
recoveryDestination: 'jzjkpn1bjnti',
});
recoveryTx.should.have.property('transaction');
recoveryTx.transaction.compression.should.equal('none');
recoveryTx.transaction.packed_trx.should.equal(expectedPackedTrx);
recoveryTx.transaction.signatures.length.should.equal(2);
recoveryTx.txid.should.equal(expectedTxId);
});
it('should generate an EOS unsigned sweep', async function () {
const recoveryTx = await baseCoin.recover({
userKey: 'xpub661MyMwAqRbcGrJ9tLp9MbQ5NLjhBNpVGCg27KzRjce2Uix51TWeiA5tCDyBFHENmKSf6BiWg3tAjYgrhTz9bZGdXj7pfksXaEpVLQqzYEE',
backupKey: 'xpub661MyMwAqRbcGkmWyp49MDZkcfZiuPvnsAYt4dHV39rvAdeNRiJPEDiQxYTNrbFEHJVBJWBdxW7DgCqRUyVpYAbT3D6LGsZpynYpMFAgAZr',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
rootAddress: 'kiyjcn1ixftp',
recoveryDestination: 'jzjkpn1bjnti',
});
recoveryTx.should.have.property('transaction');
recoveryTx.transaction.compression.should.equal('none');
recoveryTx.transaction.packed_trx.should.equal(expectedPackedTrx);
recoveryTx.transaction.signatures.length.should.equal(0);
recoveryTx.txid.should.equal(expectedTxId);
});
});
describe('Recover ERC20', function () {
it('should successfully construct a recovery transaction for tokens stuck in a wallet', async function () {
const wallet = bitgo.nockEthWallet();
// There should be 24 Potatokens stuck in our test wallet (based on nock)
const tx = await wallet.recoverToken({
tokenContractAddress: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_ADDRESS,
recipient: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT,
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_PASSPHRASE,
});
should.exist(tx);
tx.should.have.property('halfSigned');
const txInfo = tx.halfSigned;
txInfo.should.have.property('contractSequenceId');
txInfo.contractSequenceId.should.equal(1101);
txInfo.should.have.property('expireTime');
txInfo.should.have.property('gasLimit');
txInfo.gasLimit.should.equal(500000);
txInfo.should.have.property('gasPrice');
txInfo.gasPrice.should.equal(20000000000);
txInfo.should.have.property('operationHash');
txInfo.should.have.property('signature');
txInfo.should.have.property('tokenContractAddress');
txInfo.tokenContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_ADDRESS);
txInfo.should.have.property('walletId');
txInfo.walletId.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_ID);
txInfo.should.have.property('recipient');
txInfo.recipient.should.have.property('address');
txInfo.recipient.address.should.equal(sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT);
txInfo.recipient.should.have.property('amount');
txInfo.recipient.amount.should.equal('2400');
});
it('should successfully generate an ERC20 unsigned sweep', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo);
const basecoin = bitgo.coin('tdai');
// There should be 1 TDAI token in our test wallet (based on nock)
const transaction = await basecoin.recover({
userKey: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
backupKey: 'xpub661MyMwAqRbcGhSaXikpuTC9KU88Xx9LrjKSw1JKsvXNgabpTdgjy7LSovh9ZHhcqhAHQu7uthu7FguNGdcC4aXTKK5gqTcPe4WvLYRbCSG',
walletContractAddress: sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS,
tokenContractAddress: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_ADDRESS,
recoveryDestination: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT,
});
should.exist(transaction);
transaction.should.have.property('tx');
transaction.should.have.property('contractSequenceId');
transaction.should.have.property('expireTime');
transaction.should.have.property('gasLimit');
transaction.gasLimit.should.equal('500000');
transaction.should.have.property('gasPrice');
transaction.gasPrice.should.equal('20000000000');
transaction.should.have.property('tokenContractAddress');
transaction.tokenContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_TDAI_TOKEN_ADDRESS);
transaction.should.have.property('walletContractAddress');
transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
transaction.should.have.property('recipient');
transaction.recipient.should.have.property('address');
transaction.recipient.address.should.equal(sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT);
transaction.recipient.should.have.property('amount');
transaction.recipient.amount.should.equal('1000000000000000000');
});
it('should use user provided gas params when building recovery transaction', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo);
const basecoin = bitgo.coin('tdai');
// There should be 1 TDAI token in our test wallet (based on nock)
const transaction = await basecoin.recover({
userKey: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
backupKey: 'xpub661MyMwAqRbcGhSaXikpuTC9KU88Xx9LrjKSw1JKsvXNgabpTdgjy7LSovh9ZHhcqhAHQu7uthu7FguNGdcC4aXTKK5gqTcPe4WvLYRbCSG',
walletContractAddress: sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS,
tokenContractAddress: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_ADDRESS,
recoveryDestination: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT,
gasLimit: '400000',
eip1559: {
maxFeePerGas: '10000000000',
maxPriorityFeePerGas: '5000',
},
});
should.exist(transaction);
transaction.should.have.property('tx');
transaction.should.have.property('contractSequenceId');
transaction.should.have.property('expireTime');
transaction.should.have.property('gasLimit');
transaction.should.have.property('eip1559');
transaction.gasLimit.should.equal('400000');
transaction.should.have.property('gasPrice');
transaction.gasPrice.should.equal('10000000000');
transaction.should.have.property('tokenContractAddress');
transaction.tokenContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_TDAI_TOKEN_ADDRESS);
transaction.should.have.property('walletContractAddress');
transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
transaction.should.have.property('recipient');
transaction.recipient.should.have.property('address');
transaction.recipient.address.should.equal(sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT);
transaction.recipient.should.have.property('amount');
transaction.recipient.amount.should.equal('1000000000000000000');
});
});
describe('Recover Ethereum', function () {
beforeEach(() => {
nock.cleanAll();
});
let recoveryParams;
const nockTSSData = [
{
params: {
module: 'account',
action: 'txlist',
address: '0xe7406dc43d13f698fb41a345c7783d39a4c2d191',
},
response: {
status: '0',
message: 'No transactions found',
result: [],
},
},
{
params: {
module: 'account',
action: 'balance',
address: '0xe7406dc43d13f698fb41a345c7783d39a4c2d191',
},
response: {
status: '1',
message: 'OK',
result: '1000000000000000000',
},
},
];
const nockUnsignedSweepTSSData = [
{
params: {
module: 'account',
action: 'txlist',
address: '0xa91e1059953d7ef2adbbca4b688bfe22866fbcee',
},
response: {
status: '0',
message: 'No transactions found',
result: [],
},
},
{
params: {
module: 'account',
action: 'balance',
address: '0xa91e1059953d7ef2adbbca4b688bfe22866fbcee',
},
response: {
status: '1',
message: 'OK',
result: '1000000000000000000',
},
},
];
let recoverEthSandbox;
before(() => {
recoveryParams = {
userKey: '{"iv":"+TkmT3GJ5msVWQjBrt3lsw==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
':"ccm","adata":"","cipher":"aes","salt":"cCE20fGIobs=","ct":"NVIdYIh91J3aRI\n' +
'8GG0JE3DhXW3AUmz2G5RqMejdz1+t4/vovIP7lleegI7VYyWiiLvlM0OCFf3EVvV/RyXr8+2vsn\n' +
'Q0Vn8c2CV5FRZ80OjGYrW3A/6T/zpOz6E8CMvnD++iIpeO4r2eZJavejZxdzlxF0BRz7VI="}',
backupKey: '{"iv":"asB356ofC7nZtg4NBvQkiQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
':"ccm","adata":"","cipher":"aes","salt":"1hr2HhBbBIk=","ct":"8CZc6upt+XNOto\n' +
'KDD38TUg3ZUjzW+DraZlkcku2bNp0JS2s1g/iC6YTGUGtPoxDxumDlXwlWQx+5WPjZu79M8DCrI\n' +
't9aZaOvHkGH9aFtMbavFX419TcrwDmpUeQFN0hRkfrIHXyHNbTpGSVAjHvHMtzDMaw+ACg="}',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
walletContractAddress: '0x5df5a96b478bb1808140d87072143e60262e8670',
recoveryDestination: '0xac05da78464520aa7c9d4c19bd7a440b111b3054',
replayProtectionOptions: {
chain: 42,
hardfork: 'london',
},
};
recoverEthSandbox = sinon.createSandbox();
recoverEthSandbox
.stub(sdk_lib_mpc_1.EcdsaRangeProof, 'generateNtilde')
.resolves(sdk_lib_mpc_1.EcdsaTypes.deserializeNtildeWithProofs(sdk_test_1.mockSerializedChallengeWithProofs));
});
after(() => {
recoverEthSandbox.restore();
});
it('should throw on invalid gasLimit', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo);
const basecoin = bitgo.coin('hteth');
await basecoin
.recover({
...recoveryParams,
gasLimit: -400000,
gasPrice: 25000000000,
})
.should.be.rejectedWith('Gas limit must be between 30000 and 20000000');
});
it('should throw if etherscan errs', async function () {
const nockUnsuccessfulEtherscanData = [
{
params: {
module: 'account',
action: 'txlist',
address: '0x74c2137d54b0fc9f907e13f14e0dd18485fee924',
},
response: {
status: '0',
message: 'No transactions found',
result: [],
},
},
{
params: {
module: 'account',
action: 'balance',
address: '0x74c2137d54b0fc9f907e13f14e0dd18485fee924',
},
response: {
status: '1',
message: 'NOTOK',
result: 'Rate limit exceeded',
},
},
];
recoveryNocks.nockEthLikeRecovery(bitgo, nockUnsuccessfulEtherscanData);
const basecoin = bitgo.coin('hteth');
await basecoin
.recover(recoveryParams)
.should.be.rejectedWith('Could not obtain address balance for 0x74c2137d54b0fc9f907e13f14e0dd18485fee924 from the explorer, got: Rate limit exceeded');
});
it('should throw if backup key address has insufficient balance', async function () {
const insufficientFeeData = [
{
params: {
module: 'account',
action: 'txlist',
address: '0x74c2137d54b0fc9f907e13f14e0dd18485fee924',
},
response: {
status: '0',
message: 'No transactions found',
result: [],
},
},
{
params: {
module: 'account',
action: 'balance',
address: '0x74c2137d54b0fc9f907e13f14e0dd18485fee924',
},
response: {
status: '1',
message: 'OK',
result: '1234',
},
},
];
recoveryNocks.nockEthLikeRecovery(bitgo, insufficientFeeData);
const basecoin = bitgo.coin('hteth');
await basecoin
.recover({
...recoveryParams,
gasLimit: 300000,
gasPrice: 1000000000,
})
.should.be.rejectedWith('Backup key address 0x74c2137d54b0fc9f907e13f14e0dd18485fee924 has balance 0.000001234 Gwei.' +
'This address must have a balance of at least 300000 Gwei to perform recoveries. Try sending some ETH to this address then retry.');
});
it('should throw on invalid gasPrice', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo);
const basecoin = bitgo.coin('hteth');
await basecoin
.recover({
...recoveryParams,
gasLimit: 400000,
gasPrice: 2500000,
})
.should.be.rejectedWith('Gas price must be between 1000000000 and 2500000000000');
});
it('should successfully construct a tx with custom gas price and limit', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo);
const basecoin = bitgo.coin('hteth');
const recovery = await basecoin.recover({
...recoveryParams,
gasLimit: 400000,
gasPrice: 1000000000,
});
// id and tx will always be different because of expireTime
should.exist(recovery);
recovery.should.have.property('id');
recovery.should.have.property('tx');
});
it('should construct a recovery transaction without BitGo', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo);
const basecoin = bitgo.coin('hteth');
const recovery = await basecoin.recover(recoveryParams);
// id and tx will always be different because of expireTime
should.exist(recovery);
recovery.should.have.property('id');
recovery.should.have.property('tx');
});
it('should construct an eip1559 recovery transaction without BitGo', async function () {
const eip1559RecoveryParams = {
...recoveryParams,
eip1559: {
maxPriorityFeePerGas: 3,
maxFeePerGas: 20,
},
};
recoveryNocks.nockEthLikeRecovery(bitgo);
const basecoin = bitgo.coin('hteth');
const recovery = await basecoin.recover(eip1559RecoveryParams);
// id and tx will always be different because of expireTime
should.exist(recovery);
recovery.should.have.property('id');
recovery.should.have.property('tx');
});
it('should construct a recovery transaction without BitGo and with KRS', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo);
const basecoin = bitgo.coin('hteth');
const recovery = await basecoin.recover({
...recoveryParams,
backupKey: 'xpub661MyMwAqRbcGsCNiG4BzbxLmXnJFo4K5gVSE2b9AxufAtpuTun1SYwg9Uykqqf4DrKrDZ6KqPm9ehthWbCma7pnaMrtXY11nY7MeFbEDPm',
krsProvider: 'keyternal',
});
// id and tx will always be different because of expireTime
should.exist(recovery);
recovery.should.have.property('id');
recovery.should.have.property('tx');
});
it('should error when the backup key is unfunded (cannot pay gas)', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo);
const basecoin = bitgo.coin('hteth');
await basecoin
.recover({
userKey: '{"iv":"VNvG6t3fHfxMcfvNuafYYA==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
':"ccm","adata":"","cipher":"aes","salt":"mc9pCk3H43w=","ct":"Qe4Z1evaXcrOMC\n' +
'cQ/XMVVBO9M/99D1QQ6LxkG8z3fQtwwOVXM3/6doNrriprUqs+adpFC93KRcAaDroL1E6o17J2k\n' +
'mcpXRd2CuXRFORZmZ/6QBfjKfCJ3aq0kEkDVv37gZNVT3aNtGkNSQdCEWKQLwd1++r5AkA="}\n',
backupKey: '{"iv":"EjD7x0OJX9kNM/C3yEDvyQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
':"ccm","adata":"","cipher":"aes","salt":"Na9NvRRe3n8=","ct":"B/AtSLHolsdNLr\n' +
'4Dlij4kQ0E6NyUUs6wo6T2HtPDAPO0hyhPPbh1OAYqIS7VlL9xmJRFC2zPxwRJvzf6OWC/m48HX\n' +
'vgLoXYgahArhalzJVlRxcXUz4HOhozRWfv/eK3t5HJfm+25+WBOiW8YgSE7hVEYTbeBRD4="}',
walletContractAddress: '0x22ff743216b58aeb3efc46985406b50112e9e176',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
recoveryDestination: '0xac05da78464520aa7c9d4c19bd7a440b111b3054',
})
.should.be.rejectedWith('Backup key address 0xba6d9d82cf2920c544b834b72f4c6d11a3ef3de6 has balance 0 Gwei.This address must have a balance of at least 10000000 Gwei to perform recoveries. Try sending some ETH to this address then retry.');
});
it('should throw error when the etherscan rate limit is reached', async function () {
const basecoin = bitgo.coin('hteth');
recoveryNocks.nockEtherscanRateLimitError();
await basecoin.recover(recoveryParams).should.be.rejectedWith('Etherscan rate limit reached');
});
it('should generate an ETH unsigned sweep', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo);
const basecoin = bitgo.coin('hteth');
const transaction = await basecoin.recover({
userKey: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
backupKey: 'xpub661MyMwAqRbcGhSaXikpuTC9KU88Xx9LrjKSw1JKsvXNgabpTdgjy7LSovh9ZHhcqhAHQu7uthu7FguNGdcC4aXTKK5gqTcPe4WvLYRbCSG',
walletContractAddress: sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS,
recoveryDestination: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT,
gasPrice: '20000000000',
gasLimit: '500000',
});
should.exist(transaction);
transaction.should.have.property('tx');
transaction.should.have.property('contractSequenceId');
transaction.should.have.property('expireTime');
transaction.should.have.property('gasLimit');
transaction.gasLimit.should.equal('500000');
transaction.should.have.property('gasPrice');
transaction.gasPrice.should.equal('20000000000');
transaction.should.have.property('walletContractAddress');
transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
transaction.should.have.property('recipient');
transaction.recipient.should.have.property('address');
transaction.recipient.address.should.equal(sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT);
transaction.recipient.should.have.property('amount');
transaction.recipient.amount.should.equal('9999999999999999928');
});
it('should construct a recovery tx with TSS', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo, nockTSSData);
const basecoin = bitgo.coin('hteth');
const baseAddress = recoveryFixtures_1.ethLikeGG18Keycard.senderAddress;
const nockTSSDataWithBaseAddress = nockTSSData.map((data) => {
return {
...data,
params: {
...data.params,
address: baseAddress,
},
};
});
recoveryNocks.nockEthLikeRecovery(bitgo, nockTSSDataWithBaseAddress);
recoveryParams = {
userKey: recoveryFixtures_1.ethLikeGG18Keycard.userKey,
backupKey: recoveryFixtures_1.ethLikeGG18Keycard.backupKey,
walletContractAddress: recoveryFixtures_1.ethLikeGG18Keycard.senderAddress,
recoveryDestination: recoveryFixtures_1.ethLikeGG18Keycard.destinationAddress,
walletPassphrase: recoveryFixtures_1.ethLikeGG18Keycard.walletPassphrase,
eip1559: {
maxPriorityFeePerGas: 3,
maxFeePerGas: 20,
},
isTss: true,
replayProtectionOptions: {
chain: 5,
hardfork: 'london',
},
};
const recovery = await basecoin.recover(recoveryParams);
should.exist(recovery);
recovery.should.have.property('id');
recovery.should.have.property('tx');
// verify data after signing is correct
const finalTx = tx_1.TransactionFactory.fromSerializedData(Buffer.from(recovery.tx.substr(2), 'hex'));
const senderAddress = finalTx.getSenderAddress().toString();
baseAddress.should.equal(senderAddress);
recoveryParams.recoveryDestination.should.equal(finalTx.to?.toString());
Number(finalTx.value).should.equal(999999999990000000);
});
it('should construct a recovery tx with MPCv2 TSS', async function () {
for (const { coin, chain } of [
{ coin: 'hteth', chain: 17000 },
{ coin: 'tpolygon', chain: 80002 },
{ coin: 'tbsc', chain: 97 },
]) {
recoveryNocks.nockEthLikeRecovery(bitgo, nockTSSData);
const basecoin = bitgo.coin(coin);
const baseAddress = recoveryFixtures_1.ethLikeDKLSKeycard.senderAddress;
const nockTSSDataWithBaseAddress = nockTSSData.map((data) => {
return {
...data,
params: {
...data.params,
address: baseAddress,
},
};
});
recoveryNocks.nockEthLikeRecovery(bitgo, nockTSSDataWithBaseAddress);
recoveryParams = {
userKey: recoveryFixtures_1.ethLikeDKLSKeycard.userKey,
backupKey: recoveryFixtures_1.ethLikeDKLSKeycard.backupKey,
walletContractAddress: baseAddress,
recoveryDestination: recoveryFixtures_1.ethLikeDKLSKeycard.destinationAddress,
walletPassphrase: recoveryFixtures_1.ethLikeDKLSKeycard.walletPassphrase,
eip1559: {
maxPriorityFeePerGas: 3,
maxFeePerGas: 20,
},
isTss: true,
replayProtectionOptions: {
chain: chain,
},
};
const recovery = await basecoin.recover(recoveryParams);
should.exist(recovery);
recovery.should.have.property('id');
recovery.should.have.property('tx');
// verify data after signing is correct
const finalTx = tx_1.TransactionFactory.fromSerializedData(Buffer.from(recovery.tx.substr(2), 'hex'));
const senderAddress = finalTx.getSenderAddress().toString();
finalTx.common.chainIdBN().toNumber().should.equal(chain);
baseAddress.should.equal(senderAddress);
recoveryParams.recoveryDestination.should.equal(finalTx.to?.toString());
Number(finalTx.value).should.equal(999999999990000000);
}
});
it('should construct an unsigned sweep tx with TSS', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo, nockUnsignedSweepTSSData);
const basecoin = bitgo.coin('hteth');
const userKey = '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
const backupKey = '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
recoveryParams = {
userKey: userKey,
backupKey: backupKey,
walletContractAddress: '0xe7406dc43d13f698fb41a345c7783d39a4c2d191',
recoveryDestination: '0xac05da78464520aa7c9d4c19bd7a440b111b3054',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
isTss: true,
gasPrice: '20000000000',
gasLimit: '500000',
replayProtectionOptions: {
chain: 42,
hardfork: 'london',
},
};
const transaction = await basecoin.recover(recoveryParams);
should.exist(transaction);
const output = transaction;
output.should.have.property('txRequests');
output.txRequests.should.have.length(1);
output.txRequests[0].should.have.property('transactions');
output.txRequests[0].transactions.should.have.length(1);
output.txRequests[0].should.have.property('walletCoin');
output.txRequests[0].transactions[0].should.have.property('unsignedTx');
output.txRequests[0].transactions[0].unsignedTx.should.have.property('serializedTxHex');
output.txRequests[0].transactions[0].unsignedTx.should.have.property('signableHex');
output.txRequests[0].transactions[0].unsignedTx.should.have.property('derivationPath');
output.txRequests[0].transactions[0].unsignedTx.should.have.property('feeInfo');
output.txRequests[0].transactions[0].unsignedTx.should.have.property('parsedTx');
const parsedTx = output.txRequests[0].transactions[0].unsignedTx.parsedTx;
parsedTx.should.have.property('spendAmount');
output.txRequests[0].transactions[0].unsignedTx.parsedTx.should.have.property('outputs');
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3ZlcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L3YyL3VuaXQvcmVjb3ZlcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxpQ0FBaUM7QUFDakMsNkJBQTZCO0FBRTdCLDhDQUErRTtBQUMvRSxzQ0FBcUM7QUFDckMsOENBQStDO0FBQy9DLG9EQUFpRTtBQUNqRSx1Q0FBb0Q7QUFDcEQsK0JBQStCO0FBQy9CLHVFQUEwRjtBQUMxRixzREFBNEM7QUFHNUMsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLHVCQUF1QixDQUFDLENBQUM7QUFFdkQsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7QUFFekIsUUFBUSxDQUFDLFdBQVcsRUFBRTtJQUNwQixJQUFJLEtBQUssQ0FBQztJQUVWLE1BQU0sQ0FBQztRQUNMLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxXQUFLLEVBQUUsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUNuRCxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUUzQiwwREFBMEQ7UUFDMUQsdUJBQVksQ0FBQyxTQUFTLENBQUMsY0FBYyxHQUFHLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDaEgsdUJBQVksQ0FBQyxTQUFTLENBQUMsWUFBb0IsR0FBRztZQUM3QyxJQUFJLEVBQUUscUNBQXFDO1lBQzNDLElBQUksRUFBRSxxQ0FBcUM7WUFDM0MsSUFBSSxFQUFFLHFDQUFxQztZQUMzQyxLQUFLLEVBQUUscUNBQXFDO1lBQzVDLElBQUksRUFBRSxvQ0FBb0M7WUFDMUMsSUFBSSxFQUFFLHFDQUFxQztZQUMzQyxLQUFLLEVBQUUsb0NBQW9DO1NBQzVDLENBQUM7SUFDSixDQUFDLENBQUMsQ0FB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QUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgc2hvdWxkIGZyb20gJ3Nob3VsZCc7XG5pbXBvcnQgKiBhcyBub2NrIGZyb20gJ25vY2snO1xuXG5pbXBvcnQgeyBtb2NrU2VyaWFsaXplZENoYWxsZW5nZVdpdGhQcm9vZnMsIFRlc3RCaXRHbyB9IGZyb20gJ0BiaXRnby9zZGstdGVzdCc7XG5pbXBvcnQgeyBCaXRHbyB9IGZyb20gJy4uLy4uLy4uL3NyYyc7XG5pbXBvcnQgeyBrcnNQcm92aWRlcnMgfSBmcm9tICdAYml0Z28vc2RrLWNvcmUnO1xuaW1wb3J0IHsgRWNkc2FSYW5nZVByb29mLCBFY2RzYVR5cGVzIH0gZnJvbSAnQGJpdGdvL3Nkay1saWItbXBjJztcbmltcG9ydCB7IFRyYW5zYWN0aW9uRmFjdG9yeSB9IGZyb20gJ0BldGhlcmV1bWpzL3R4JztcbmltcG9ydCAqIGFzIHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCB7IGV0aExpa2VES0xTS2V5Y2FyZCwgZXRoTGlrZUdHMThLZXljYXJkIH0gZnJvbSAnLi4vZml4dHVyZXMvdHNzL3JlY292ZXJ5Rml4dHVyZXMnO1xuaW1wb3J0IHsgVXRpbHMgfSBmcm9tICdAYml0Z28vc2RrLWNvaW4teHJwJztcbmltcG9ydCB7IFVuc2lnbmVkU3dlZXBUeE1QQ3YyIH0gZnJvbSAnQGJpdGdvL3Nkay1jb2luLWV0aCc7XG5cbmNvbnN0IHJlY292ZXJ5Tm9ja3MgPSByZXF1aXJlKCcuLi9saWIvcmVjb3Zlcnktbm9ja3MnKTtcblxubm9jay5kaXNhYmxlTmV0Q29ubmVjdCgpO1xuXG5kZXNjcmliZSgnUmVjb3Zlcnk6JywgZnVuY3Rpb24gKCkge1xuICBsZXQgYml0Z287XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICd0ZXN0JyB9KTtcbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcblxuICAgIC8vIHByZXRlbmQgdGhhdCBLZXl0ZXJuYWwgYWNjZXB0cyByZWNvdmVyaWVzIGZvciBhbGwgY29pbnNcbiAgICBrcnNQcm92aWRlcnMua2V5dGVybmFsLnN1cHBvcnRlZENvaW5zID0gWydidGMnLCAnZXRoJywgJ3hycCcsICdiY2gnLCAnYmNoYScsICdsdGMnLCAnemVjJywgJ2Rhc2gnLCAneGxtJywgJ2JzdiddO1xuICAgIChrcnNQcm92aWRlcnMua2V5dGVybmFsLmZlZUFkZHJlc3NlcyBhcyBhbnkpID0ge1xuICAgICAgdGJ0YzogJzJNdWp6OWVpY21ncFBjZFNjUkpUeXdWSzNFUU5IREpHM3lOJyxcbiAgICAgIHRiY2g6ICcyTXVqejllaWNtZ3BQY2RTY1JKVHl3VkszRVFOSERKRzN5TicsXG4gICAgICB0YnN2OiAnMk11ano5ZWljbWdwUGNkU2NSSlR5d1ZLM0VRTkhESkczeU4nLFxuICAgICAgdGJjaGE6ICcyTXVqejllaWNtZ3BQY2RTY1JKVHl3VkszRVFOSERKRzN5TicsXG4gICAgICB0bHRjOiAnUWZmWE1WaU04RFlnUFJmMUhvY3pqdzdCUzVDVmRTV2FCTCcsXG4gICAgICB0emVjOiAndDJBVExBaEJQMXVUdXlpV3M1RFk1Q1BIMVZ1WWtHVWluZHQnLFxuICAgICAgdGRhc2g6ICc4ZXVIdWc0ZGJtUHkzQ0xhd3dXZGVUakdMcVBZRUd6M0t0JyxcbiAgICB9O1xuICB9KTtcblxuICBhZnRlcihmdW5jdGlvbiAoKSB7XG4gICAgbm9jay5jbGVhbkFsbCgpO1xuICB9KTtcblxuICBkZXNjcmliZSgnUmVjb3ZlciBSaXBwbGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBYUlAgcmVjb3ZlcnkgdHgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tYcnBSZWNvdmVyeSgpO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3R4cnAnKTtcbiAgICAgIHJldHVybiBiYXNlY29pblxuICAgICAgICAucmVjb3Zlcih7XG4gICAgICAgICAgdXNlcktleTpcbiAgICAgICAgICAgICd7XCJpdlwiOlwiclUrK21FdElIdGJwM2Q0amc1RXVsQT09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcImlwMXJiNTl1WW5NPVwiLFwiY3RcIjpcInNzbVA5YWJQb1Z5WGtXNElvMFNVeStBQVM4bHIrd2dJZXJUTXcrbERZbmtVaDBzamxJNEE2RnB2ZTBxMXJpUTNEeS9KMGJOdTdkZ29aa080eHMvWDZkendFd2xtUGhrM3BFUTdZZDRDWGExekEwMXkwR2V1OTAwRkxlNExkYVM4anQ2Zml4dWkydFRkNFZpM0pZZ2xGMS9IbUNqRzFVZz1cIn0nLFxuICAgICAgICAgIGJhY2t1cEtleTpcbiAgICAgICAgICAgICd7XCJpdlwiOlwidUIvQlRjbjFyWG1nWUdmbmNYT293Zz09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIkkzV3J1bXhrdU1RPVwiLFwiY3RcIjpcInNneUROQXpOc0JydVRSbTBkMDRvQlRCZjhsaGVITktTK2RSZ2w4RmVNRWhvZEtzaXlqdFJWSEcwQ0hQZjVyVjNnNWl4Vm5aK2l3c1NDdjNQS3l5ZW95N1JHblQwQUc5WVlwaTBtZStPdlA4MzMxaU8rbjVxdXpzdHJHYlYxajh1RWg1SU1XNzhTK1lVWktTeDZ6YmJkWjB4TnU4RDVXTT1cIn0nLFxuICAgICAgICAgIHJvb3RBZGRyZXNzOiAncmFHWldSa1JCVVdkUUpzS1lFendYSk5iQ1pNVHFYNTZhQScsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlYyLlRFU1RfV0FMTEVUMV9QQVNTQ09ERSxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiAncnN2MmtyZW1KU1NGYmJhTHFyZjhmV3h4TjVRbnN5bk5tMj9kdD0xMjM0NScsXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uIChyZWNvdmVyeSkge1xuICAgICAgICAgIHJlY292ZXJ5LnR4SGV4LnNob3VsZC5lcXVhbChcbiAgICAgICAgICAgICcxMjAwMDAyMjgwMDAwMDAwMjQwMDAwMDAwNDJFMDAwMDMwMzkyMDFCMDAxNTUxOTE2MTQwMDAwMDAyNEUwNkMwQzA2ODQwMDAwMDAwMDAwMDAwMUU3MzAwODExNDM5Q0EwMTBFMEUwMTk4MTUwRjhEREQ1NzY4Q0NEMkIwOTU3MDFEOEM4MzE0MjAxMjc2QURDNDY5QzRGMTBEMTM2OUUwRjVDNUE3REVGMzdCMjI2N0YzRTAxMDczMjEwMjZDOTE5NzQxNDY0Mjc4ODlDODAxQkQyNkNFMzFDRTBFMTAzMDdBNjlERkU0MTM5REU0NUU1RTM1OTMzQTZCMDM3NDQ2MzA0NDAyMjA0QUEzRDJGMzQ0NzI5QjBCQjkwNzVDNEFFQTA3RUJCMkVBRjZEM0YzNjMwOUJDQUVGMTBCMkM5NzM0QUM5NDNFMDIyMDMyRDU1RUMxOUUyN0IyRTkwRTNEOTQ0NEZEMjZDQzA2RkQ0N0JCM0UzRDg1QjBGQ0MwQ0M0REU3MDM4NTYzRkQ4MTE0QUJCNUI3Qzg0M0YzQUE4RDhFRkFDQzNDNUE3RDlCMDQ4NEMxNzQ0MkUxRTAxMDczMjEwMkY0RTM3NjEzMzAxMkY1NDA0OTkwQzdFMURGODNBOUY5NDNCMzBENTVGMEQ4NTY2MzJDOEU4Mzc4RkNFQjcwRDI3NDQ2MzA0NDAyMjA1NjhGMUQ0OUY1ODEwNDU4RTcyMDRBMUQyRDIzQjg2QjY5NDUwNTMyN0U4NDEwQTIxNUFCOUM5MzI0RUE4QTMxMDIyMDdBOTMyMTFBQ0ZCNUU5QzE0NDFCNzAxQTc5NTRCNzJBMzA1NDI2NUJBM0ZENjE5NjVENzA5RTRDNEU5MDgwRjM4MTE0QUNFRjlGMEEyRkNFQzQ0QTlBMjEzNDQ0QTlFNkM1N0UyRDAyODU2QUUxRjEnXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZWNvdmVyeS5pZC5zaG91bGQuZXF1YWwoJ0YyMDA1QjM5MkU5NDU0RkYxRTgyMTdCODE2Qzg3ODY2QTU2NzcwMzgyQjhGQ0FDMEFBRTJGQThEMTJBNTNCOTgnKTtcbiAgICAgICAgICByZWNvdmVyeS5vdXRwdXRBbW91bnQuc2hvdWxkLmVxdWFsKCc5ODk5MDAwMDAwJyk7XG4gICAgICAgICAgcmVjb3Zlcnkub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICAgIHJlY292ZXJ5Lm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwoJ3JzdjJrcmVtSlNTRmJiYUxxcmY4Zld4eE41UW5zeW5ObTI/ZHQ9MTIzNDUnKTtcbiAgICAgICAgICByZWNvdmVyeS5vdXRwdXRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWwoJzk4OTkwMDAwMDAnKTtcbiAgICAgICAgICByZWNvdmVyeS5mZWUuZmVlLnNob3VsZC5lcXVhbCgnMzAnKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIFhSUCByZWNvdmVyeSB0eCB3aXRoIEtSUycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja1hycFJlY292ZXJ5KCk7XG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndHhycCcpO1xuICAgICAgcmV0dXJuIGJhc2Vjb2luXG4gICAgICAgIC5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5OlxuICAgICAgICAgICAgJ3tcIml2XCI6XCJyVSsrbUV0SUh0YnAzZDRqZzVFdWxBPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiaXAxcmI1OXVZbk09XCIsXCJjdFwiOlwic3NtUDlhYlBvVnlYa1c0SW8wU1V5K0FBUzhscit3Z0llclRNdytsRFlua1VoMHNqbEk0QTZGcHZlMHExcmlRM0R5L0owYk51N2Rnb1prTzR4cy9YNmR6d0V3bG1QaGszcEVRN1lkNENYYTF6QTAxeTBHZXU5MDBGTGU0TGRhUzhqdDZmaXh1aTJ0VGQ0VmkzSllnbEYxL0htQ2pHMVVnPVwifScsXG4gICAgICAgICAgYmFja3VwS2V5OlxuICAgICAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNGdFdkbVdIS1pFaDlwWWlKckFHVHUxTk5Td3hZMlM2M3RVOW5HY2ZDQWJOVUtRdUZxWFJUUms4S2t1QmFieG82WWplQnJpOFE3ZGtNc210aHM2TVZ4U2Q2TVRhZUNtZCcsXG4gICAgICAgICAgcm9vdEFkZHJlc3M6ICdyYUdaV1JrUkJVV2RRSnNLWUV6d1hKTmJDWk1UcVg1NmFBJyxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVjIuVEVTVF9XQUxMRVQxX1BBU1NDT0RFLFxuICAgICAgICAgIGtyc1Byb3ZpZGVyOiAna2V5dGVybmFsJyxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiAncnN2MmtyZW1KU1NGYmJhTHFyZjhmV3h4TjVRbnN5bk5tMj9kdD0xMjM0NScsXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uIChyZWNvdmVyeSkge1xuICAgICAgICAgIHJlY292ZXJ5LnR4SGV4LnNob3VsZC5lcXVhbChcbiAgICAgICAgICAgICcxMjAwMDAyMjgwMDAwMDAwMjQwMDAwMDAwNDJFMDAwMDMwMzkyMDFCMDAxNTUxOTE2MTQwMDAwMDAyNEUwNkMwQzA2ODQwMDAwMDAwMDAwMDAwMUU3MzAwODExNDM5Q0EwMTBFMEUwMTk4MTUwRjhEREQ1NzY4Q0NEMkIwOTU3MDFEOEM4MzE0MjAxMjc2QURDNDY5QzRGMTBEMTM2OUUwRjVDNUE3REVGMzdCMjI2N0YzRTAxMDczMjEwMkY0RTM3NjEzMzAxMkY1NDA0OTkwQzdFMURGODNBOUY5NDNCMzBENTVGMEQ4NTY2MzJDOEU4Mzc4RkNFQjcwRDI3NDQ2MzA0NDAyMjA1NjhGMUQ0OUY1ODEwNDU4RTcyMDRBMUQyRDIzQjg2QjY5NDUwNTMyN0U4NDEwQTIxNUFCOUM5MzI0RUE4QTMxMDIyMDdBOTMyMTFBQ0ZCNUU5QzE0NDFCNzAxQTc5NTRCNzJBMzA1NDI2NUJBM0ZENjE5NjVENzA5RTRDNEU5MDgwRjM4MTE0QUNFRjlGMEEyRkNFQzQ0QTlBMjEzNDQ0QTlFNkM1N0UyRDAyODU2QUUxRjEnXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZWNvdmVyeS5pZC5zaG91bGQuZXF1YWwoJzZFQTE3MjhCMENDMEMwNDdFNTRBQUY1NzhEODE4MjJFREUxMTA3OTA4Qjk3OTg2ODI5OTY1N0U3NEE4RTE4QzAnKTtcbiAgICAgICAgICByZWNvdmVyeS5vdXRwdXRBbW91bnQuc2hvdWxkLmVxdWFsKCc5ODk5MDAwMDAwJyk7XG4gICAgICAgICAgcmVjb3Zlcnkub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICAgIHJlY292ZXJ5Lm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwoJ3JzdjJrcmVtSlNTRmJiYUxxcmY4Zld4eE41UW5zeW5ObTI/ZHQ9MTIzNDUnKTtcbiAgICAgICAgICByZWNvdmVyeS5vdXRwdXRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWwoJzk4OTkwMDAwMDAnKTtcbiAgICAgICAgICByZWNvdmVyeS5mZWUuZmVlLnNob3VsZC5lcXVhbCgnMzAnKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGFuIFhSUCB1bnNpZ25lZCBzd2VlcCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja1hycFJlY292ZXJ5KCk7XG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndHhycCcpO1xuICAgICAgcmV0dXJuIGJhc2Vjb2luXG4gICAgICAgIC5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5OlxuICAgICAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNGOVlhNHpESEd6RHRKejNOYWFlRUdiUTZybnFuTnhMOVJYREpOSGNmekF5UFVCWHVLWGp5dHZKTnpReHFiakJ3bVB2ZWlZWDMyM1pwOFp4MlJZUU45Z0dNN250aVh4cicsXG4gICAgICAgICAgYmFja3VwS2V5OlxuICAgICAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNGdFdkbVdIS1pFaDlwWWlKckFHVHUxTk5Td3hZMlM2M3RVOW5HY2ZDQWJOVUtRdUZxWFJUUms4S2t1QmFieG82WWplQnJpOFE3ZGtNc210aHM2TVZ4U2Q2TVRhZUNtZCcsXG4gICAgICAgICAgcm9vdEFkZHJlc3M6ICdyYUdaV1JrUkJVV2RRSnNLWUV6d1hKTmJDWk1UcVg1NmFBJyxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVjIuVEVTVF9XQUxMRVQxX1BBU1NDT0RFLFxuICAgICAgICAgIGtyc1Byb3ZpZGVyOiAna2V5dGVybmFsJyxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiAncnN2MmtyZW1KU1NGYmJhTHFyZjhmV3h4TjVRbnN5bk5tMj9kdD0xMjM0NScsXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uIChyZWNvdmVyeSkge1xuICAgICAgICAgIHJlY292ZXJ5LnR4SGV4LnNob3VsZC5lcXVhbChcbiAgICAgICAgICAgICcxMjAwMDAyMjgwMDAwMDAwMjQwMDAwMDAwNDJFMDAwMDMwMzkyMDFCMDAxNTUxOTE2MTQwMDAwMDAyNEUwNkMwQzA2ODQwMDAwMDAwMDAwMDAwMUU4MTE0MzlDQTAxMEUwRTAxOTgxNTBGOERERDU3NjhDQ0QyQjA5NTcwMUQ4QzgzMTQyMDEyNzZBREM0NjlDNEYxMEQxMzY5RTBGNUM1QTdERUYzN0IyMjY3J1xuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3QgdHg6IGFueSA9IFV0aWxzLmRlY29kZVRyYW5zYWN0aW9uKHJlY292ZXJ5LnR4SGV4KTtcbiAgICAgICAgICB0eC5UcmFuc2FjdGlvblR5cGUuc2hvdWxkLmVxdWFsKCdQYXltZW50Jyk7XG4gICAgICAgICAgdHguQWNjb3VudC5zaG91bGQuZXF1YWwoJ3JhR1pXUmtSQlVXZFFKc0tZRXp3WEpOYkNaTVRxWDU2YUEnKTtcbiAgICAgICAgICB0eC5EZXN0aW5hdGlvbi5zaG91bGQuZXF1YWwoJ3JzdjJrcmVtSlNTRmJiYUxxcmY4Zld4eE41UW5zeW5ObTInKTtcbiAgICAgICAgICB0eC5EZXN0aW5hdGlvblRhZy5zaG91bGQuZXF1YWwoMTIzNDUpO1xuICAgICAgICAgIHR4LkFtb3VudC5zaG91bGQuZXF1YWwoJzk4OTkwMDAwMDAnKTtcbiAgICAgICAgICB0eC5GbGFncy5zaG91bGQuZXF1YWwoMjE0NzQ4MzY0OCk7XG4gICAgICAgICAgdHguTGFzdExlZGdlclNlcXVlbmNlLnNob3VsZC5lcXVhbCgxMzk3MTM3KTtcbiAgICAgICAgICB0eC5GZWUuc2hvdWxkLmVxdWFsKCczMCcpO1xuICAgICAgICAgIHR4LlNlcXVlbmNlLnNob3VsZC5lcXVhbCg0KTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdSZWNvdmVyIFN0ZWxsYXInLCBmdW5jdGlvbiAoKSB7XG4gICAgYXN5bmMgZnVuY3Rpb24gY2hlY2tSZWNvdmVyeVR4RXhwbGFuYXRpb24oYmFzZWNvaW4sIHR4LCByZWNvdmVyeUFtb3VudCwgcmVjb3ZlcnlEZXN0aW5hdGlvbikge1xuICAgICAgY29uc3QgZXhwbGFuYXRpb24gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oeyB0eEJhc2U2NDogdHggfSk7XG4gICAgICBleHBsYW5hdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnb3V0cHV0cycpO1xuICAgICAgZXhwbGFuYXRpb24ub3V0cHV0cy5zaG91bGQuY29udGFpbkVxbCh7XG4gICAgICAgIGFtb3VudDogcmVjb3ZlcnlBbW91bnQudG9GaXhlZCgpLFxuICAgICAgICBhZGRyZXNzOiByZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgICBjb2luOiBiYXNlY29pbi5nZXRDaGFpbigpLFxuICAgICAgfSk7XG4gICAgICBleHBsYW5hdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY2hhbmdlT3V0cHV0cycsIFtdKTtcbiAgICAgIGV4cGxhbmF0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdjaGFuZ2VBbW91bnQnLCAnMCcpO1xuICAgICAgZXhwbGFuYXRpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2ZlZScsIHsgZmVlOiAnMTAwJywgZmVlUmF0ZTogbnVsbCwgc2l6ZTogbnVsbCB9KTtcbiAgICAgIGV4cGxhbmF0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdvcGVyYXRpb25zJywgW10pO1xuICAgIH1cblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgWExNIHJlY292ZXJ5IHR4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrWGxtUmVjb3ZlcnkoKTtcblxuICAgICAgY29uc3QgcmVjb3ZlcnlQYXJhbXMgPSB7XG4gICAgICAgIHVzZXJLZXk6IGB7XCJpdlwiOlwiUGlMdmVBKzVBRlBVUndhVTdpaWpCUT09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIktsSmM4TlNLSHB3PVwiLFwiY3RcIjpcIlljZE5PRnB6WGdEblJxamxSM1c5Uis1ZXp0eXN5aHBDVHVSQkhzblB5UERzdDludkwrR2VTT1JiTFk5eFZUaFRkeVY2bGxSZ2ZVcjVPN3k0bDlzOUZnPT1cIn1gLFxuICAgICAgICBiYWNrdXBLZXk6IGB7XCJpdlwiOlwiVG1pQUlIcjB2Q1g2ZzJCS2tjNi83Zz09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIndPa01KRW01QjZVPVwiLFwiY3RcIjpcIkhKUFM1Ni9GdU1pZWlINksyczVrNWpGcDhSUEhRcVphOXFpOGhEa2pPcU5VRmpENFhLcThTeTNCRGhwd3pvelRCVzZFbVFHU0Ywa3BjN2VaOUN1Y0t3PT1cIn1gLFxuICAgICAgICByb290QWRkcmVzczogJ0dBVUFHVEwzTkJaN05QM1VJTVpDVkpZTTZPMk5LVVA2WFJUSzRFNVZaRFZJUVgzQ0JZSVZNRElCJyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlYyLlRFU1RfUkVDT1ZFUllfUEFTU0NPREUsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdHQVNXMjc3UzJaT0U3SDdBNUVRNUg1QUtMUDZVQTZaNUFLT1NXVjZBUkJFR1RTSUdNWk1DN0FJWicsXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVjb3ZlcnlBbW91bnQgPSA3NDk5OTUwMDtcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0eGxtJyk7XG4gICAgICBjb25zdCByZWNvdmVyeSA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIocmVjb3ZlcnlQYXJhbXMpO1xuXG4gICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhCYXNlNjQnKTtcbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNvdmVyeUFtb3VudCcsIHJlY292ZXJ5QW1vdW50KTtcblxuICAgICAgYXdhaXQgY2hlY2tSZWNvdmVyeVR4RXhwbGFuYXRpb24oYmFzZWNvaW4sIHJlY292ZXJ5LnR4QmFzZTY0LCByZWNvdmVyeUFtb3VudCwgcmVjb3ZlcnlQYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlY292ZXIgdG8gYW4gdW5mdW5kZWQgWExNIHdhbGxldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja1hsbVJlY292ZXJ5KCk7XG5cbiAgICAgIGNvbnN0IHJlY292ZXJ5UGFyYW1zID0ge1xuICAgICAgICB1c2VyS2V5OiBge1wiaXZcIjpcIlBpTHZlQSs1QUZQVVJ3YVU3aWlqQlE9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJLbEpjOE5TS0hwdz1cIixcImN0XCI6XCJZY2ROT0ZwelhnRG5ScWpsUjNXOVIrNWV6dHlzeWhwQ1R1UkJIc25QeVBEc3Q5bnZMK0dlU09SYkxZOXhWVGhUZHlWNmxsUmdmVXI1Tzd5NGw5czlGZz09XCJ9YCxcbiAgICAgICAgYmFja3VwS2V5OiBge1wiaXZcIjpcIlRtaUFJSHIwdkNYNmcyQktrYzYvN2c9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJ3T2tNSkVtNUI2VT1cIixcImN0XCI6XCJISlBTNTYvRnVNaWVpSDZLMnM1azVqRnA4UlBIUXFaYTlxaThoRGtqT3FOVUZqRDRYS3E4U3kzQkRocHd6b3pUQlc2RW1RR1NGMGtwYzdlWjlDdWNLdz09XCJ9YCxcbiAgICAgICAgcm9vdEFkZHJlc3M6ICdHQVVBR1RMM05CWjdOUDNVSU1aQ1ZKWU02TzJOS1VQNlhSVEs0RTVWWkRWSVFYM0NCWUlWTURJQicsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IFRlc3RCaXRHby5WMi5URVNUX1JFQ09WRVJZX1BBU1NDT0RFLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiAnR0FHQ1FMVUdNWDc2WEMyNEpSQ1JKV09IWEsyM09OVVJINDQzM0pPRVBVNkNIN1o0NENDWVVDRUwnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlY292ZXJ5QW1vdW50ID0gNzQ5OTk1MDA7XG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndHhsbScpO1xuICAgICAgY29uc3QgcmVjb3ZlcnkgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHJlY292ZXJ5UGFyYW1zKTtcblxuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4QmFzZTY0Jyk7XG4gICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncmVjb3ZlcnlBbW91bnQnLCByZWNvdmVyeUFtb3VudCk7XG5cbiAgICAgIGF3YWl0IGNoZWNrUmVjb3ZlcnlUeEV4cGxhbmF0aW9uKGJhc2Vjb2luLCByZWNvdmVyeS50eEJhc2U2NCwgcmVjb3ZlcnlBbW91bnQsIHJlY292ZXJ5UGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBYTE0gcmVjb3ZlcnkgdHggd2l0aCB1bmVuY3J5cHRlZCBrZXlzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrWGxtUmVjb3ZlcnkoKTtcblxuICAgICAgY29uc3QgcmVjb3ZlcnlQYXJhbXMgPSB7XG4gICAgICAgIHVzZXJLZXk6IGBTQU1GNVhTN081Qkw0T09UQjYyNURFTENWTlc1Sk1IRjJERE03TlNJVlBOUVFFS1BLTEJRRk5KM2AsXG4gICAgICAgIGJhY2t1cEtleTogYFNDWFo3VUZWU0lGSVlKVlBMV0VBWTIyVFpKT1I0TDJaNEhFNkJNWkdaSEJCSjRVQUFCVEZNSzNWYCxcbiAgICAgICAgcm9vdEFkZHJlc3M6ICdHQVVBR1RMM05CWjdOUDNVSU1aQ1ZKWU02TzJOS1VQNlhSVEs0RTVWWkRWSVFYM0NCWUlWTURJQicsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdHQVNXMjc3UzJaT0U3SDdBNUVRNUg1QUtMUDZVQTZaNUFLT1NXVjZBUkJFR1RTSUdNWk1DN0FJWicsXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVjb3ZlcnlBbW91bnQgPSA3NDk5OTUwMDtcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0eGxtJyk7XG4gICAgICBjb25zdCByZWNvdmVyeSA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIocmVjb3ZlcnlQYXJhbXMpO1xuXG4gICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhCYXNlNjQnKTtcbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNvdmVyeUFtb3VudCcsIHJlY292ZXJ5QW1vdW50KTtcblxuICAgICAgYXdhaXQgY2hlY2tSZWNvdmVyeVR4RXhwbGFuYXRpb24oYmFzZWNvaW4sIHJlY292ZXJ5LnR4QmFzZTY0LCByZWNvdmVyeUFtb3VudCwgcmVjb3ZlcnlQYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIFhMTSByZWNvdmVyeSB0eCB3aXRoIHVuZW5jcnlwdGVkIHJvb3QgcHJpdmF0ZSBrZXlzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrWGxtUmVjb3ZlcnkoKTtcblxuICAgICAgLy8gdXNlcktleSBhbmQgYmFja3VwS2V5IGFyZSBpbiBwcnYgKyBwdWIgcmVwcmVzZW50YXRpb25cbiAgICAgIC8vIGZpcnN0IDY0IGNoYXJhY3RlcnMgKDMyIGJ5dGVzKSBhcmUgdGhlIHByaXZhdGUga2V5LCB0aGUgcmVzdCBpcyB0aGUgcHVibGljIGtleVxuICAgICAgY29uc3QgcmVjb3ZlcnlQYXJhbXMgPSB7XG4gICAgICAgIHVzZXJLZXk6IGAxODVlZGU1Zjc3NDJiZTM5ZDMwZmI1ZDE5MTYyYWI2ZGQ0YjBlNWQwYzZjZmI2NDhhYmRiMDgxMTRmNTJjMzAyNWFhZTE1MmVmMTQ3MDY4NmFiYTNmZWM0MDg4OWE1NTBkN2I1MzkxMGM3MzllMjViNWQ0YTJmMjdlYjUxMmViN2AsXG4gICAgICAgIGJhY2t1cEtleTogYGFmOWZkMGI1OTIwYThjMjZhZjVkODgwYzZiNTNjYTVkMWUyZjU5ZTFjOWUwYjMyNmM5YzIxNGYyODAwMDY2NTY4MjAwYTVlNGRkMjc5ZGE1ZjQyMjMyNGI4MjEwZTg5OGRiZjY4ZmMyOWMxZjljZjc5MWMyMjQxODdmYWQ3ZGMzYCxcbiAgICAgICAgcm9vdEFkZHJlc3M6ICdHQVVBR1RMM05CWjdOUDNVSU1aQ1ZKWU02TzJOS1VQNlhSVEs0RTVWWkRWSVFYM0NCWUlWTURJQicsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdHQVNXMjc3UzJaT0U3SDdBNUVRNUg1QUtMUDZVQTZaNUFLT1NXVjZBUkJFR1RTSUdNWk1DN0FJWicsXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVjb3ZlcnlBbW91bnQgPSA3NDk5OTUwMDtcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0eGxtJyk7XG4gICAgICBjb25zdCByZWNvdmVyeSA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIocmVjb3ZlcnlQYXJhbXMpO1xuXG4gICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhCYXNlNjQnKTtcbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNvdmVyeUFtb3VudCcsIHJlY292ZXJ5QW1vdW50KTtcblxuICAgICAgYXdhaXQgY2hlY2tSZWNvdmVyeVR4RXhwbGFuYXRpb24oYmFzZWNvaW4sIHJlY292ZXJ5LnR4QmFzZTY0LCByZWNvdmVyeUFtb3VudCwgcmVjb3ZlcnlQYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIFhMTSByZWNvdmVyeSB0eCB3aXRoIGVuY3J5cHRlZCByb290IGtleXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tYbG1SZWNvdmVyeSgpO1xuXG4gICAgICAvLyB1c2VyS2V5IGFuZCBiYWNrdXBLZXkgYXJlIGluIGVuY3J5cHRlZCBwcnYgKyBwdWIgcmVwcmVzZW50YXRpb25cbiAgICAgIGNvbnN0IHJlY292ZXJ5UGFyYW1zID0ge1xuICAgICAgICB1c2VyS2V5OiBge1wiaXZcIjpcImJVSHc1M09hOHRTckZSemlkUGk4YWc9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJRSE5aRmxEbkNXMD1cIixcImN0XCI6XCJBUVNBQnZVbUNNc0QzckpRenlnMjlUbkxQbkRWQ1pGWFprZzloSjJSZVlhWFdXa1NiOEJ3MG5uM0xXL0dJR2kzWmJPZ1Bpdko0TGhDYk85QTJwcDRhVk9oYnNicUNOQld4cG1Iem5lVlMzRlByTGViUWl4SDFSbjBYK2Z0Mkk5WGNOTkVrbEV3NWNIM3BmOUkxdnFMbXdFSHBGOERXeDBPZ0dubGgvUXEwcjVaYUV0NXRiVERQQT09XCJ9YCxcbiAgICAgICAgYmFja3VwS2V5OiBge1wiaXZcIjpcIjE5U1EzU2xMenVUYkVmVTdzOGxUSFE9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJqTE0yb1d5TzhXZz1cIixcImN0XCI6XCJpWFVkTmNxaHNieWtmeUxLWXJjRWVnU0hvb0FKdDgya3JkU1doUWhzL2NVQW9BNnRYNGorSGZPdXRRaFNQRHRKa0lwYnoxOXlub1RvOFZWcHhwL0dhK3ViUVZsQ2xiWlB5aEM4WWtDUnZKQnZXS2c0MUVFR2x5ZHVLN2VzVnJubnYxYzRYazRhNEJhWHN6T0VkR3cvMWFRQjlBT1FNTVZzdjZ6OFlodTU1UXFWejZ6TjQ5UG1hUT09XCJ9YCxcbiAgICAgICAgcm9vdEFkZHJlc3M6ICdHQVVBR1RMM05CWjdOUDNVSU1aQ1ZKWU02TzJOS1VQNlhSVEs0RTVWWkRWSVFYM0NCWUlWTURJQicsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IFRlc3RCaXRHby5WMi5URVNUX1JFQ09WRVJZX1BBU1NDT0RFLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiAnR0FTVzI3N1MyWk9FN0g3QTVFUTVINUFLTFA2VUE2WjVBS09TV1Y2QVJCRUdUU0lHTVpNQzdBSVonLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVjb3ZlcnlBbW91bnQgPSA3NDk5OTUwMDtcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0eGxtJyk7XG4gICAgICBjb25zdCByZWNvdmVyeSA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIocmVjb3ZlcnlQYXJhbXMpO1xuXG4gICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhCYXNlNjQnKTtcbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNvdmVyeUFtb3VudCcsIHJlY292ZXJ5QW1vdW50KTtcblxuICAgICAgYXdhaXQgY2hlY2tSZWNvdmVyeVR4RXhwbGFuYXRpb24oYmFzZWNvaW4sIHJlY292ZXJ5LnR4QmFzZTY0LCByZWNvdmVyeUFtb3VudCwgcmVjb3ZlcnlQYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIFhMTSByZWNvdmVyeSB0eCB3aXRoIEtSUycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja1hsbVJlY292ZXJ5KCk7XG5cbiAgICAgIGNvbnN0IHJlY292ZXJ5UGFyYW1zID0ge1xuICAgICAgICB1c2VyS2V5OiBge1wiaXZcIjpcIlBpTHZlQSs1QUZQVVJ3YVU3aWlqQlE9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJLbEpjOE5TS0hwdz1cIixcImN0XCI6XCJZY2ROT0ZwelhnRG5ScWpsUjNXOVIrNWV6dHlzeWhwQ1R1UkJIc25QeVBEc3Q5bnZMK0dlU09SYkxZOXhWVGhUZHlWNmxsUmdmVXI1Tzd5NGw5czlGZz09XCJ9YCxcbiAgICAgICAgYmFja3VwS2V5OiAnR0NCQUJKUEUzVVRaM0pQVUVJWkVYQVFRNUNNTlg1VVBZS09CN0hIWFNIQkNJR0Q3VlY2NEg2S1UnLFxuICAgICAgICByb290QWRkcmVzczogJ0dBVUFHVEwzTkJaN05QM1VJTVpDVkpZTTZPMk5LVVA2WFJUSzRFNVZaRFZJUVgzQ0JZSVZNRElCJyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlYyLlRFU1RfUkVDT1ZFUllfUEFTU0NPREUsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdHQVNXMjc3UzJaT0U3SDdBNUVRNUg1QUtMUDZVQTZaNUFLT1NXVjZBUkJFR1RTSUdNWk1DN0FJWicsXG4gICAgICAgIGtyc1Byb3ZpZGVyOiAna2V5dGVybmFsJyxcbiAgICAgIH07XG4gICAgICBjb25zdCByZWNvdmVyeUFtb3VudCA9IDc0OTk5NTAwO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3R4bG0nKTtcbiAgICAgIGNvbnN0IHJlY292ZXJ5ID0gYXdhaXQgYmFzZWNvaW4ucmVjb3ZlcihyZWNvdmVyeVBhcmFtcyk7XG5cbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEJhc2U2NCcpO1xuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY292ZXJ5QW1vdW50JywgNzQ5OTk1MDApO1xuXG4gICAgICBhd2FpdCBjaGVja1JlY292ZXJ5VHhFeHBsYW5hdGlvbihiYXNlY29pbiwgcmVjb3ZlcnkudHhCYXNlNjQsIHJlY292ZXJ5QW1vdW50LCByZWNvdmVyeVBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgWExNIHJlY292ZXJ5IHR4IHdpdGggS1JTIHVzaW5nIHJvb3Qga2V5cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja1hsbVJlY292ZXJ5KCk7XG5cbiAgICAgIC8vIHVzZXJLZXkgaXMgaW4gZW5jcnlwdGVkIHBydiArIHB1YiByZXByZXNlbnRhdGlvblxuICAgICAgY29uc3QgcmVjb3ZlcnlQYXJhbXMgPSB7XG4gICAgICAgIHVzZXJLZXk6IGB7XCJpdlwiOlwiYlVIdzUzT2E4dFNyRlJ6aWRQaThhZz09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIlFITlpGbERuQ1cwPVwiLFwiY3RcIjpcIkFRU0FCdlVtQ01zRDNySlF6eWcyOVRuTFBuRFZDWkZYWmtnOWhKMlJlWWFYV1drU2I4Qncwbm4zTFcvR0lHaTNaYk9nUGl2SjRMaENiTzlBMnBwNGFWT2hic2JxQ05CV3hwbUh6bmVWUzNGUHJMZWJRaXhIMVJuMFgrZnQySTlYY05ORWtsRXc1Y0gzcGY5STF2cUxtd0VIcEY4RFd4ME9nR25saC9RcTByNVphRXQ1dGJURFBBPT1cIn1gLFxuICAgICAgICBiYWNrdXBLZXk6ICc4MjAwYTVlNGRkMjc5ZGE1ZjQyMjMyNGI4MjEwZTg5OGRiZjY4ZmMyOWMxZjljZjc5MWMyMjQxODdmYWQ3ZGMzJywgLy8gdGhpcyBpcyBhIHB1YiByb290IGtleSwgbm90ZSBpdCBpcyAzMiBieXRlc1xuICAgICAgICByb290QWRkcmVzczogJ0dBVUFHVEwzTkJaN05QM1VJTVpDVkpZTTZPMk5LVVA2WFJUSzRFNVZaRFZJUVgzQ0JZSVZNRElCJyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlYyLlRFU1RfUkVDT1ZFUllfUEFTU0NPREUsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdHQVNXMjc3UzJaT0U3SDdBNUVRNUg1QUtMUDZVQTZaNUFLT1NXVjZBUkJFR1RTSUdNWk1DN0FJWicsXG4gICAgICAgIGtyc1Byb3ZpZGVyOiAna2V5dGVybmFsJyxcbiAgICAgIH07XG4gICAgICBjb25zdCByZWNvdmVyeUFtb3VudCA9IDc0OTk5NTAwO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3R4bG0nKTtcbiAgICAgIGNvbnN0IHJlY292ZXJ5ID0gYXdhaXQgYmFzZWNvaW4ucmVjb3ZlcihyZWNvdmVyeVBhcmFtcyk7XG5cbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEJhc2U2NCcpO1xuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY292ZXJ5QW1vdW50JywgNzQ5OTk1MDApO1xuXG4gICAgICBhd2FpdCBjaGVja1JlY292ZXJ5VHhFeHBsYW5hdGlvbihiYXNlY29pbiwgcmVjb3ZlcnkudHhCYXNlNjQsIHJlY292ZXJ5QW1vdW50LCByZWNvdmVyeVBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYW4gWExNIHVuc2lnbmVkIHN3ZWVwJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrWGxtUmVjb3ZlcnkoKTtcblxuICAgICAgY29uc3QgcmVjb3ZlcnlQYXJhbXMgPSB7XG4gICAgICAgIHVzZXJLZXk6ICdHQk5LNEZKTzZGRFFOQlZMVVA3TUlDRUpVVklOUE5KWkNERFRUWVMzTFZGQzZKN0xLRVhMT0JLTScsXG4gICAgICAgIGJhY2t1cEtleTogJ0dDQkFCSlBFM1VUWjNKUFVFSVpFWEFRUTVDTU5YNVVQWUtPQjdISFhTSEJDSUdEN1ZWNjRINktVJyxcbiAgICAgICAgcm9vdEFkZHJlc3M6ICdHQVVBR1RMM05CWjdOUDNVSU1aQ1ZKWU02TzJOS1VQNlhSVEs0RTVWWkRWSVFYM0NCWUlWTURJQicsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IFRlc3RCaXRHby5WMi5URVNUX1JFQ09WRVJZX1BBU1NDT0RFLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiAnR0FTVzI3N1MyWk9FN0g3QTVFUTVINUFLTFA2VUE2WjVBS09TV1Y2QVJCRUdUU0lHTVpNQzdBSVonLFxuICAgICAgICBrcnNQcm92aWRlcjogJ2tleXRlcm5hbCcsXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVjb3ZlcnlBbW91bnQgPSA3NDk5OTUwMDtcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0eGxtJyk7XG4gICAgICBjb25zdCByZWNvdmVyeSA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIocmVjb3ZlcnlQYXJhbXMpO1xuXG4gICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhCYXNlNjQnKTtcbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNvdmVyeUFtb3VudCcsIDc0OTk5NTAwKTtcblxuICAgICAgYXdhaXQgY2hlY2tSZWNvdmVyeVR4RXhwbGFuYXRpb24oYmFzZWNvaW4sIHJlY292ZXJ5LnR4QmFzZTY0LCByZWNvdmVyeUFtb3VudCwgcmVjb3ZlcnlQYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGFuIFhMTSB1bnNpZ25lZCBzd2VlcCB1c2luZyByb290IGtleXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tYbG1SZWNvdmVyeSgpO1xuXG4gICAgICBjb25zdCByZWNvdmVyeVBhcmFtcyA9IHtcbiAgICAgICAgdXNlcktleTogJzVhYWUxNTJlZjE0NzA2ODZhYmEzZmVjNDA4ODlhNTUwZDdiNTM5MTBjNzM5ZTI1YjVkNGEyZjI3ZWI1MTJlYjcnLCAvLyB0aGlzIGlzIGEgcHViIGtleSwgbm90ZSBpdCBpcyAzMiBieXRlc1xuICAgICAgICBiYWNrdXBLZXk6ICc4MjAwYTVlNGRkMjc5ZGE1ZjQyMjMyNGI4MjEwZTg5OGRiZjY4ZmMyOWMxZjljZjc5MWMyMjQxODdmYWQ3ZGMzJywgLy8gdGhpcyBpcyBhIHB1YiByb290IGtleSwgbm90ZSBpdCBpcyAzMiBieXRlc1xuICAgICAgICByb290QWRkcmVzczogJ0dBVUFHVEwzTkJaN05QM1VJTVpDVkpZTTZPMk5LVVA2WFJUSzRFNVZaRFZJUVgzQ0JZSVZNRElCJyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlYyLlRFU1RfUkVDT1ZFUllfUEFTU0NPREUsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdHQVNXMjc3UzJaT0U3SDdBNUVRNUg1QUtMUDZVQTZaNUFLT1NXVjZBUkJFR1RTSUdNWk1DN0FJWicsXG4gICAgICAgIGtyc1Byb3ZpZGVyOiAna2V5dGVybmFsJyxcbiAgICAgIH07XG4gICAgICBjb25zdCByZWNvdmVyeUFtb3VudCA9IDc0OTk5NTAwO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3R4bG0nKTtcbiAgICAgIGNvbnN0IHJlY292ZXJ5ID0gYXdhaXQgYmFzZWNvaW4ucmVjb3ZlcihyZWNvdmVyeVBhcmFtcyk7XG5cbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEJhc2U2NCcpO1xuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY292ZXJ5QW1vdW50JywgNzQ5OTk1MDApO1xuXG4gICAgICBhd2FpdCBjaGVja1JlY292ZXJ5VHhFeHBsYW5hdGlvbihiYXNlY29pbiwgcmVjb3ZlcnkudHhCYXNlNjQsIHJlY292ZXJ5QW1vdW50LCByZWNvdmVyeVBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1JlY292ZXIgVFJPTicsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgYmFzZUNvaW47XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgYmFzZUNvaW4gPSBiaXRnby5jb2luKCd0dHJ4Jyk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSByZWNvdmVyeSB0eCBmcm9tIGVuY3J5cHRlZCB1c2VyIGFuZCBiYWNrdXAga2V5cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja1Ryb25SZWNvdmVyeSgpO1xuICAgICAgY29uc3QgcmVjb3ZlcnlUeCA9IGF3YWl0IGJhc2VDb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OlxuICAgICAgICAgICd7XCJpdlwiOlwiZVh3WUl5Z0R5UnkxUjFsdzlFd0VnUT09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIk5OT3hGK0xSN2FVPVwiLFwiY3RcIjpcInFYL0crQWlaSjM1WHdVbUw5YWxZaXRSd3ZZZ0UvYlMyNERTQVZWN3RCYW9UczQwdHNWQi9rV3graFYvSjVhY0tJQTZaL3dTdWN4YktyUWxKQjY5eEpKbC9PaXJZcW1YUkJpckgrcmFnMWFDMXpqN1pWbmJPK2grUDVHSHFISmx0TGM0VXlEZitwMjIrTmpvRExmUitmRVB0RzhjNHY1bz1cIn0nLFxuICAgICAgICBiYWNrdXBLZXk6XG4gICAgICAgICAgJ3tcIml2XCI6XCJRYW9YQ0VraWJvNFZNRXlvM2ZTVVVRPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiaXFxdHJCdEM1dlk9XCIsXCJjdFwiOlwiSkhiSEo4VTJBbGEyY1JGY29xVEFmdExZbUREU09UZmhkVm1aa21XL09SSmVQNjBWZjVUMW02NjF5V1FUM0FES1NzcTJDU1JWNDlPcVNmSDJsSU9CVTNFZlhkRlhrV1FlVE5YK2JoekM2RTJvL3VzM1Nud2xYaE82NTlEUU1QbUx0aHZnQ1RYOHhNKzVVemdWL1BZbnFGcFN1eGwzNzlzPVwifScsXG4gICAgICAgIGJpdGdvS2V5OlxuICAgICAgICAgICd4cHViNjYxTXlNd0FxUmJjRXg2ektUQnJnWmtXUEJHdng4cWd1RWQxTnFFRHA2eVczc3JCR2hUVWRGa2NkY0JqcDVGUWdYa0ROaVFCZGo2RnNna2E4RDlWRll0MzJNMkdzQ1RSdWZmblhNaHExaG8nLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAndGVzdF93YWxsZXRfcGFzc3BocmFzZScsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdUWVBneDhOZkR4QjhweWl5VGVpTWtZemVtMWROQTZHMTJpJyxcbiAgICAgIH0pO1xuXG4gICAgICBzaG91bGQuZXhpc3QocmVjb3ZlcnlUeCk7XG5cbiAgICAgIHJlY292ZXJ5VHguY29pbi5zaG91bGQuZXF1YWwoJ3R0cngnKTtcbiAgICAgIHJlY292ZXJ5VHguZmVlSW5mby5mZWUuc2hvdWxkLmVxdWFsKCcyMTAwMDAwJyk7XG4gICAgICByZWNvdmVyeVR4LnJlY292ZXJ5QW1vdW50LnNob3VsZC5lcXVhbCg4OTkwNDc0MDApO1xuICAgICAgcmVjb3ZlcnlUeC50eEhleC5zaG91bGQuZXF1YWwoXG4gICAgICAgICd7XCJ2aXNpYmxlXCI6ZmFsc2UsXCJ0eElEXCI6XCI5OGIzOThlMzAyN2U2MDE4NzBhODZiMDc4NWYxZjFkMzAxZjA4N2RiYWFmZTQ0MzM3NTA3YjUwMDFiYWUwZDQ5XCIsXCJyYXdfZGF0YVwiOntcImNvbnRyYWN0XCI6W3tcInBhcmFtZXRlclwiOntcInZhbHVlXCI6e1wiYW1vdW50XCI6MTAwMDAwMDAsXCJvd25lcl9hZGRyZXNzXCI6XCI0MWU3ZTExZGYyYzU3MDQ4ODhjM2NiNjNmYjQzYTk0OThiZDE4MTJjYjJcIixcInRvX2FkZHJlc3NcIjpcIjQxZjVmNDE0ZDQ0N2FhZmU3MGJiOWI5ZDkzOTEyY2JjNGM1NGYwYzAxNFwifSxcInR5cGVfdXJsXCI6XCJ0eXBlLmdvb2dsZWFwaXMuY29tL3Byb3RvY29sLlRyYW5zZmVyQ29udHJhY3RcIn0sXCJ0eXBlXCI6XCJUcmFuc2ZlckNvbnRyYWN0XCJ9XSxcInJlZl9ibG9ja19ieXRlc1wiOlwiYTc2MlwiLFwicmVmX2Jsb2NrX2hhc2hcIjpcIjE4ZGZlOTQ2ZmJmN2EwYWNcIixcImV4cGlyYXRpb25cIjoxNjc2NzQ2NDQzMDAwLFwidGltZXN0YW1wXCI6MTY3NjY1OTk4Mzc5OX0sXCJyYXdfZGF0YV9oZXhcIjpcIjBhMDJhNzYyMjIwODE4ZGZlOTQ2ZmJmN2EwYWM0MGY4OTE4MWFmZTYzMDVhNjkwODAxMTI2NTBhMmQ3NDc5NzA2NTJlNjc2ZjZmNjc2YzY1NjE3MDY5NzMyZTYzNmY2ZDJmNzA3MjZmNzQ2ZjYzNmY2YzJlNTQ3MjYxNmU3MzY2NjU3MjQzNmY2ZTc0NzI2MTYzNzQxMjM0MGExNTQxZTdlMTFkZjJjNTcwNDg4OGMzY2I2M2ZiNDNhOTQ5OGJkMTgxMmNiMjEyMTU0MWY1ZjQxNGQ0NDdhYWZlNzBiYjliOWQ5MzkxMmNiYzRjNTRmMGMwMTQxOGM4ZDE5Y2FkMDM3MGI3OGJlNDg1ZTYzMFwiLFwic2lnbmF0dXJlXCI6W1wiNzlhMTEwMTE2NjU3ZTc1YmU4MTQwMGFkNGE5ZjczOGZkMDk4Njk1ZmM1ZmM2MDA5MTc2YWExYzI3OTI0YzRjZGIyOTg5ZmUyMDUyYjcwYzczOWIxMGNkMzg4MWM5ODcyNjYwYjgzOTk4ZGM5MzE2ZTZjOGQxMWZiNTg4ZDczMWQwMFwiLFwiMjUwZDBiYWUyNDkxNTk2YmQ4MDBkODMwYWE5ZDRjNmQyNWUxZDAxYTRjODYwYjg1NmQ2MDAwYThhYjhmYTIwODJhMWFlMjAxNjhlMGFiOTdjOWZmZDY0ODI0YjQ4M2I5ODQzZGI3NGU5NTUzZDVkOWU2OGEzYTY0ZDQxNGRkMTIwMVwiXX0nXG4gICAgICApO1xuICAgICAgcmVjb3ZlcnlUeC50eC5zaWduYXR1cmVbMF0uc2hvdWxkLmVxdWFsKFxuICAgICAgICAnNzlhMTEwMTE2NjU3ZTc1YmU4MTQwMGFkNGE5ZjczOGZkMDk4Njk1ZmM1ZmM2MDA5MTc2YWExYzI3OTI0YzRjZGIyOTg5ZmUyMDUyYjcwYzczOWIxMGNkMzg4MWM5ODcyNjYwYjgzOTk4ZGM5MzE2ZTZjOGQxMWZiNTg4ZDczMWQwMCdcbiAgICAgICk7XG4gICAgICByZWNvdmVyeVR4LnR4LnNpZ25hdHVyZVsxXS5zaG91bGQuZXF1YWwoXG4gICAgICAgICcyNTBkMGJhZTI0OTE1OTZiZDgwMGQ4MzBhYTlkNGM2ZDI1ZTFkMDFhNGM4NjBiODU2ZDYwMDBhOGFiOGZhMjA4MmExYWUyMDE2OGUwYWI5N2M5ZmZkNjQ4MjRiNDgzYjk4NDNkYjc0ZTk1NTNkNWQ5ZTY4YTNhNjRkNDE0ZGQxMjAxJ1xuICAgICAgKTtcbiAgICAgIHJlY292ZXJ5VHgudHgudHhJRC5zaG91bGQuZXF1YWwoJzk4YjM5OGUzMDI3ZTYwMTg3MGE4NmIwNzg1ZjFmMWQzMDFmMDg3ZGJhYWZlNDQzMzc1MDdiNTAwMWJhZTBkNDknKTtcbiAgICAgIHJlY292ZXJ5VHgudHgucmF3X2RhdGFfaGV4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzBhMDJhNzYyMjIwODE4ZGZlOTQ2ZmJmN2EwYWM0MGY4OTE4MWFmZTYzMDVhNjkwODAxMTI2NTBhMmQ3NDc5NzA2NTJlNjc2ZjZmNjc2YzY1NjE3MDY5NzMyZTYzNmY2ZDJmNzA3MjZmNzQ2ZjYzNmY2YzJlNTQ3MjYxNmU3MzY2NjU3MjQzNmY2ZTc0NzI2MTYzNzQxMjM0MGExNTQxZTdlMTFkZjJjNTcwNDg4OGMzY2I2M2ZiNDNhOTQ5OGJkMTgxMmNiMjEyMTU0MWY1ZjQxNGQ0NDdhYWZlNzBiYjliOWQ5MzkxMmNiYzRjNTRmMGMwMTQxOGM4ZDE5Y2FkMDM3MGI3OGJlNDg1ZTYzMCdcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIHJlY292ZXJ5IHR4IGZyb20gZW5jcnlwdGVkIHVzZXIgYW5kIGJhY2t1cCBrZXlzIGZyb20gYSByZWNlaXZlIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tUcm9uUmVjZWl2ZVJlY292ZXJ5KCk7XG4gICAgICBjb25zdCByZWNvdmVyeVR4ID0gYXdhaXQgYmFzZUNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6XG4gICAgICAgICAgJ3tcIml2XCI6XCJlWHdZSXlnRHlSeTFSMWx3OUV3RWdRPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiTk5PeEYrTFI3YVU9XCIsXCJjdFwiOlwicVgvRytBaVpKMzVYd1VtTDlhbFlpdFJ3dllnRS9iUzI0RFNBVlY3dEJhb1RzNDB0c1ZCL2tXeCtoVi9KNWFjS0lBNlovd1N1Y3hiS3JRbEpCNjl4SkpsL09pcllxbVhSQmlySCtyYWcxYUMxemo3WlZuYk8raCtQNUdIcUhKbHRMYzRVeURmK3AyMitOam9ETGZSK2ZFUHRHOGM0djVvPVwifScsXG4gICAgICAgIGJhY2t1cEtleTpcbiAgICAgICAgICAne1wiaXZcIjpcIlFhb1hDRWtpYm80Vk1FeW8zZlNVVVE9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJpcXF0ckJ0QzV2WT1cIixcImN0XCI6XCJKSGJISjhVMkFsYTJjUkZjb3FUQWZ0TFltRERTT1RmaGRWbVprbVcvT1JKZVA2MFZmNVQxbTY2MXlXUVQzQURLU3NxMkNTUlY0OU9xU2ZIMmxJT0JVM0VmWGRGWGtXUWVUTlgrYmh6QzZFMm8vdXMzU253bFhoTzY1OURRTVBtTHRodmdDVFg4eE0rNVV6Z1YvUFlucUZwU3V4bDM3OXM9XCJ9JyxcbiAgICAgICAgYml0Z29LZXk6XG4gICAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNFeDZ6S1RCcmdaa1dQQkd2eDhxZ3VFZDFOcUVEcDZ5VzNzckJHaFRVZEZrY2RjQmpwNUZRZ1hrRE5pUUJkajZGc2drYThEOVZGWXQzMk0yR3NDVFJ1ZmZuWE1ocTFobycsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICd0ZXN0X3dhbGxldF9wYXNzcGhyYXNlJyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogJ1RFYmhhOUZoUU1aM0ZSdFpnb2s4UUJ1blBRVTRwWnZCeFgnLFxuICAgICAgfSk7XG5cbiAgICAgIHNob3VsZC5leGlzdChyZWNvdmVyeVR4KTtcblxuICAgICAgcmVjb3ZlcnlUeC5jb2luLnNob3VsZC5lcXVhbCgndHRyeCcpO1xuICAgICAgcmVjb3ZlcnlUeC5mZWVJbmZvLmZlZS5zaG91bGQuZXF1YWwoJzIxMDAwMDAnKTtcbiAgICAgIHJlY292ZXJ5VHgucmVjb3ZlcnlBbW91bnQuc2hvdWxkLmVxdWFsKDE5NzkwMDAwMCk7XG4gICAgICByZWNvdmVyeVR4LmFkZHJlc3NJbmZvLmFkZHJlc3Muc2hvdWxkLmVxdWFsKCdUTmVHcHdBdXJrN2tqUUxkY2RXaEZyOFlQOEU5WmE4dzF4Jyk7XG4gICAgICByZWNvdmVyeVR4LmFkZHJlc3NJbmZvLmNoYWluLnNob3VsZC5lcXVhbCgwKTtcbiAgICAgIHJlY292ZXJ5VHguYWRkcmVzc0luZm8uaW5kZXguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgcmVjb3ZlcnlUeC50eEhleC5zaG91bGQuZXF1YWwoXG4gICAgICAgICd7XCJ2aXNpYmxlXCI6ZmFsc2UsXCJ0eElEXCI6XCJkYTY3ZTMyZTllYTNiZDAyMmYzZDkzZWQyNTk3NzFkZGE5YjQ0NGQ0MWQxZTYzZTU0YzgyNTRhNmViYjYzMzJmXCIsXCJyYXdfZGF0YVwiOntcImNvbnRyYWN0XCI6W3tcInBhcmFtZXRlclwiOntcInZhbHVlXCI6e1wiYW1vdW50XCI6MTk5MDAwMDAwLFwib3duZXJfYWRkcmVzc1wiOlwiNDE4YjA0ZWNkYzNkYjdlOGRhN2NkODM4NDkyZjY2ZTQyNGEwNTFlMmNkXCIsXCJ0b19hZGRyZXNzXCI6XCI0MTMyYzc1M2JmOGQzZGU3MzU4NzQ4YTc1ZmNmMjk5ZjE0NmRmZjZlNGVcIn0sXCJ0eXBlX3VybFwiOlwidHlwZS5nb29nbGVhcGlzLmNvbS9wcm90b2NvbC5UcmFuc2ZlckNvbnRyYWN0XCJ9LFwidHlwZVwiOlwiVHJhbnNmZXJDb250cmFjdFwifV0sXCJyZWZfYmxvY2tfYnl0ZXNcIjpcIjgxZTBcIixcInJlZl9ibG9ja19oYXNoXCI6XCI1YjFiMjBlOWViZWFhNGY4XCIsXCJleHBpcmF0aW9uXCI6MTY4NjAzODY4MjAwMCxcInRpbWVzdGFtcFwiOjE2ODU5NTIyMjQ0ODN9LFwicmF3X2RhdGFfaGV4XCI6XCIwYTAyODFlMDIyMDg1YjFiMjBlOWViZWFhNGY4NDA5MGIzZjJmZDg4MzE1YTY4MDgwMTEyNjQwYTJkNzQ3OTcwNjUyZTY3NmY2ZjY3NmM2NTYxNzA2OTczMmU2MzZmNmQyZjcwNzI2Zjc0NmY2MzZmNmMyZTU0NzI2MTZlNzM2NjY1NzI0MzZmNmU3NDcyNjE2Mzc0MTIzMzBhMTU0MThiMDRlY2RjM2RiN2U4ZGE3Y2Q4Mzg0OTJmNjZlNDI0YTA1MWUyY2QxMjE1NDEzMmM3NTNiZjhkM2RlNzM1ODc0OGE3NWZjZjI5OWYxNDZkZmY2ZTRlMThjMGZmZjE1ZTcwZTNiOWQ1ZDQ4ODMxXCIsXCJzaWduYXR1cmVcIjpbXCI5NGEzMWNkZDY0ZTkzZTM3NWMzZWViYWU1ZGI0ZjY2NzYxY2I0OTU1MGYyY2VlOTM4OGI2MThlNjgzNmJjNDcxZWNmMzNlMTQxMjJkNjIyNDQ3MzczNThlMzNhOWQxNGEwNTZjZThjN2RjMzRkY2ZjYjhlZjJkYjE1ZDQwZDgzNjAwXCJdfSdcbiAgICAgICk7XG4gICAgICByZWNvdmVyeVR4LnR4LnNpZ25hdHVyZVswXS5zaG91bGQuZXF1YWwoXG4gICAgICAgICc5NGEzMWNkZDY0ZTkzZTM3NWMzZWViYWU1ZGI0ZjY2NzYxY2I0OTU1MGYyY2VlOTM4OGI2MThlNjgzNmJjNDcxZWNmMzNlMTQxMjJkNjIyNDQ3MzczNThlMzNhOWQxNGEwNTZjZThjN2RjMzRkY2ZjYjhlZjJkYjE1ZDQwZDgzNjAwJ1xuICAgICAgKTtcbiAgICAgIHJlY292ZXJ5VHgudHgudHhJRC5zaG91bGQuZXF1YWwoJ2RhNjdlMzJlOWVhM2JkMDIyZjNkOTNlZDI1OTc3MWRkYTliNDQ0ZDQxZDFlNjNlNTRjODI1NGE2ZWJiNjMzMmYnKTtcbiAgICAgIHJlY292ZXJ5VHgudHgucmF3X2RhdGFfaGV4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzBhMDI4MWUwMjIwODViMWIyMGU5ZWJlYWE0Zjg0MDkwYjNmMmZkODgzMTVhNjgwODAxMTI2NDBhMmQ3NDc5NzA2NTJlNjc2ZjZmNjc2YzY1NjE3MDY5NzMyZTYzNmY2ZDJmNzA3MjZmNzQ2ZjYzNmY2YzJlNTQ3MjYxNmU3MzY2NjU3MjQzNmY2ZTc0NzI2MTYzNzQxMjMzMGExNTQxOGIwNGVjZGMzZGI3ZThkYTdjZDgzODQ5MmY2NmU0MjRhMDUxZTJjZDEyMTU0MTMyYzc1M2JmOGQzZGU3MzU4NzQ4YTc1ZmNmMjk5ZjE0NmRmZjZlNGUxOGMwZmZmMTVlNzBlM2I5ZDVkNDg4MzEnXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBhbiBlcnJvciB3aGVuIHRoZXJlIGlzIG5vIGZ1bmRzIHRvIGZsdXNoJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrVHJvblJlY2VpdmVSZWNvdmVyeVplcm9GdW5kcygpO1xuICAgICAgYXdhaXQgYmFzZUNvaW5cbiAgICAgICAgLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXk6XG4gICAgICAgICAgICAne1wiaXZcIjpcImVYd1lJeWdEeVJ5MVIxbHc5RXdFZ1E9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJOTk94RitMUjdhVT1cIixcImN0XCI6XCJxWC9HK0FpWkozNVh3VW1MOWFsWWl0Und2WWdFL2JTMjREU0FWVjd0QmFvVHM0MHRzVkIva1d4K2hWL0o1YWNLSUE2Wi93U3VjeGJLclFsSkI2OXhKSmwvT2lyWXFtWFJCaXJIK3JhZzFhQzF6ajdaVm5iTytoK1A1R0hxSEpsdExjNFV5RGYrcDIyK05qb0RMZlIrZkVQdEc4YzR2NW89XCJ9JyxcbiAgICAgICAgICBiYWNrdXBLZXk6XG4gICAgICAgICAgICAne1wiaXZcIjpcIlFhb1hDRWtpYm80Vk1FeW8zZlNVVVE9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJpcXF0ckJ0QzV2WT1cIixcImN0XCI6XCJKSGJISjhVMkFsYTJjUkZjb3FUQWZ0TFltRERTT1RmaGRWbVprbVcvT1JKZVA2MFZmNVQxbTY2MXlXUVQzQURLU3NxMkNTUlY0OU9xU2ZIMmxJT0JVM0VmWGRGWGtXUWVUTlgrYmh6QzZFMm8vdXMzU253bFhoTzY1OURRTVBtTHRodmdDVFg4eE0rNVV6Z1YvUFlucUZwU3V4bDM3OXM9XCJ9JyxcbiAgICAgICAgICBiaXRnb0tleTpcbiAgICAgICAgICAgICd4cHViNjYxTXlNd0FxUmJjRXg2ektUQnJnWmtXUEJHdng4cWd1RWQxTnFFRHA2eVczc3JCR2hUVWRGa2NkY0JqcDVGUWdYa0ROaVFCZGo2RnNna2E4RDlWRll0MzJNMkdzQ1RSdWZmblhNaHExaG8nLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICd0ZXN0X3dhbGxldF9wYXNzcGhyYXNlJyxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiAnVEViaGE5RmhRTVozRlJ0WmdvazhRQnVuUFFVNHBadkJ4WCcsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgIFwiQW1vdW50IG9mIGZ1bmRzIHRvIHJlY292ZXIgdW5kZWZpbmVkIGlzIGxlc3MgdGhhbiAyMTAwMDAwIGFuZCB3b3VsZG4ndCBiZSBhYmxlIHRvIGZ1bmQgYSBzZW5kXCJcbiAgICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgcmVjb3ZlcnkgdHggd2l0aCB1bmVuY3J5cHRlZCBrZXlzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrVHJvblJlY292ZXJ5KCk7XG4gICAgICBjb25zdCByZWNvdmVyeVR4ID0gYXdhaXQgYmFzZUNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6XG4gICAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNHS04zVXhScXdLZFZOUmJKdnF4aU5hV0JDZlhjVUphRWY1NndxUnNHUjZSN3RtV3JwbmpiZFFMcnliNmh6eDhSZlhYc3ZScUJ1QjJpZEdnMU5lRDF5dWVXY3NCb3E3QScsXG4gICAgICAgIGJhY2t1cEtleTpcbiAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0Y1YjlmSkFmSnA2UDlwMkxtZVpWN1liZmdEa3R0R0pyR2RtTHRzTHh5SFRRYW9QRTFwSnI1RUE3U0J3TVN6Rm12MlR2c0RMdEc0MkZlZXN5YVZRYXpCWDRZbUQyOGJoJyxcbiAgICAgICAgYml0Z29LZXk6XG4gICAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNFeDZ6S1RCcmdaa1dQQkd2eDhxZ3VFZDFOcUVEcDZ5VzNzckJHaFRVZEZrY2RjQmpwNUZRZ1hrRE5pUUJkajZGc2drYThEOVZGWXQzMk0yR3NDVFJ1ZmZuWE1ocTFobycsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdUWVBneDhOZkR4QjhweWl5VGVpTWtZemVtMWROQTZHMTJpJyxcbiAgICAgIH0pO1xuXG4gICAgICBzaG91bGQuZXhpc3QocmVjb3ZlcnlUeCk7XG5cbiAgICAgIHJlY292ZXJ5VHguY29pbi5zaG91bGQuZXF1YWwoJ3R0cngnKTtcbiAgICAgIHJlY292ZXJ5VHguZmVlSW5mby5mZWUuc2hvdWxkLmVxdWFsKCcyMTAwMDAwJyk7XG4gICAgICByZWNvdmVyeVR4LnJlY292ZXJ5QW1vdW50LnNob3VsZC5lcXVhbCg4OTkwNDc0MDApO1xuICAgICAgcmVjb3ZlcnlUeC50eC50eElELnNob3VsZC5lcXVhbCgnOThiMzk4ZTMwMjdlNjAxODcwYTg2YjA3ODVmMWYxZDMwMWYwODdkYmFhZmU0NDMzNzUwN2I1MDAxYmFlMGQ0OScpO1xuICAgICAgcmVjb3ZlcnlUeC50eC5yYXdfZGF0YV9oZXguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMGEwMmE3NjIyMjA4MThkZmU5NDZmYmY3YTBhYzQwZjg5MTgxYWZlNjMwNWE2OTA4MDExMjY1MGEyZDc0Nzk3MDY1MmU2NzZmNmY2NzZjNjU2MTcwNjk3MzJlNjM2ZjZkMmY3MDcyNmY3NDZmNjM2ZjZjMmU1NDcyNjE2ZTczNjY2NTcyNDM2ZjZlNzQ3MjYxNjM3NDEyMzQwYTE1NDFlN2UxMWRmMmM1NzA0ODg4YzNjYjYzZmI0M2E5NDk4YmQxODEyY2IyMTIxNTQxZjVmNDE0ZDQ0N2FhZmU3MGJiOWI5ZDkzOTEyY2JjNGM1NGYwYzAxNDE4YzhkMTljYWQwMzcwYjc4YmU0ODVlNjMwJ1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYW4gdW5zaWduZWQgc3dlZXAnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tUcm9uUmVjb3ZlcnkoKTtcbiAgICAgIGNvbnN0IHJlY292ZXJ5VHggPSBhd2FpdCBiYXNlQ29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTpcbiAgICAgICAgICAne1wiaXZcIjpcImVYd1lJeWdEeVJ5MVIxbHc5RXdFZ1E9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJOTk94RitMUjdhVT1cIixcImN0XCI6XCJxWC9HK0FpWkozNVh3VW1MOWFsWWl0Und2WWdFL2JTMjREU0FWVjd0QmFvVHM0MHRzVkIva1d4K2hWL0o1YWNLSUE2Wi93U3VjeGJLclFsSkI2OXhKSmwvT2lyWXFtWFJCaXJIK3JhZzFhQzF6ajdaVm5iTytoK1A1R0hxSEpsdExjNFV5RGYrcDIyK05qb0RMZlIrZkVQdEc4YzR2NW89XCJ9JyxcbiAgICAgICAgYmFja3VwS2V5OlxuICAgICAgICAgICd4cHViNjYxTXlNd0FxUmJjRjViOWZKQWZKcDZQOXAyTG1lWlY3WWJmZ0RrdHRHSnJHZG1MdHNMeHlIVFFhb1BFMXBKcjVFQTdTQndNU3pGbXYyVHZzREx0RzQyRmVlc3lhVlFhekJYNFltRDI4YmgnLFxuICAgICAgICBiaXRnb0tleTpcbiAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0V4NnpLVEJyZ1prV1BCR3Z4OHFndUVkMU5xRURwNnlXM3NyQkdoVFVkRmtjZGNCanA1RlFnWGtETmlRQmRqNkZzZ2thOEQ5VkZZdDMyTTJHc0NUUnVmZm5YTWhxMWhvJyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ3Rlc3Rfd2FsbGV0X3Bhc3NwaHJhc2UnLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiAnVFlQZ3g4TmZEeEI4cHlpeVRlaU1rWXplbTFkTkE2RzEyaScsXG4gICAgICB9KTtcblxuICAgICAgc2hvdWxkLmV4aXN0KHJlY292ZXJ5VHgpO1xuXG4gICAgICByZWNvdmVyeVR4LmNvaW4uc2hvdWxkLmVxdWFsKCd0dHJ4Jyk7XG4gICAgICByZWNvdmVyeVR4LmZlZUluZm8uZmVlLnNob3VsZC5lcXVhbCgnMjEwMDAwMCcpO1xuICAgICAgcmVjb3ZlcnlUeC5yZWNvdmVyeUFtb3VudC5zaG91bGQuZXF1YWwoODk5MDQ3NDAwKTtcbiAgICAgIHJlY292ZXJ5VHgudHgudHhJRC5zaG91bGQuZXF1YWwoJzk4YjM5OGUzMDI3ZTYwMTg3MGE4NmIwNzg1ZjFmMWQzMDFmMDg3ZGJhYWZlNDQzMzc1MDdiNTAwMWJhZTBkNDknKTtcbiAgICAgIHJlY292ZXJ5VHgudHgucmF3X2RhdGFfaGV4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzBhMDJhNzYyMjIwODE4ZGZlOTQ2ZmJmN2EwYWM0MGY4OTE4MWFmZTYzMDVhNjkwODAxMTI2NTBhMmQ3NDc5NzA2NTJlNjc2ZjZmNjc2YzY1NjE3MDY5NzMyZTYzNmY2ZDJmNzA3MjZmNzQ2ZjYzNmY2YzJlNTQ3MjYxNmU3MzY2NjU3MjQzNmY2ZTc0NzI2MTYzNzQxMjM0MGExNTQxZTdlMTFkZjJjNTcwNDg4OGMzY2I2M2ZiNDNhOTQ5OGJkMTgxMmNiMjEyMTU0MWY1ZjQxNGQ0NDdhYWZlNzBiYjliOWQ5MzkxMmNiYzRjNTRmMGMwMTQxOGM4ZDE5Y2FkMDM3MGI3OGJlNDg1ZTYzMCdcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGEgdG9rZW4gcmVjb3ZlcnkgdHggZnJvbSBlbmNyeXB0ZWQgdXNlciBhbmQgYmFja3VwIGtleXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tUcm9uVG9rZW5SZWNvdmVyeSgpO1xuICAgICAgY29uc3QgcmVjb3ZlcnlUeCA9IGF3YWl0IGJhc2VDb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OlxuICAgICAgICAgICd7XCJpdlwiOlwiUnlqVFY0QjA5dFFUNTc2akFNMm5MZz09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIm5KZHRtZWNITk1FPVwiLFwiY3RcIjpcIjVyQ2VpaE8zcFptZCt2TVlTdFAwZjB6TGJKa0hoZHZheCs2WkFyNVI0Vm12akpuUXFXaktrejRpcVYyRjFkU1pWek5UVTk3aEhqWkU1ZDNEcEpoeTdyRnNGRklGVnV0ak9SU1p2OFducjBnOTlYT2lFRGJ1REVORTJCUXlUa096U1lMTEdJaTcxbXl1d2dBakJ1UU1vbWswKzdndGZqWT1cIn0nLFxuICAgICAgICBiYWNrdXBLZXk6XG4gICAgICAgICAgJ3tcIml2XCI6XCJ2bmJ6eDNZblNSSFJNVW5FT1RtSEx3PT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiMkQzMmVNT2drWmM9XCIsXCJjdFwiOlwieUtQMGpuUmt2L1huTUhQNm1KTVFHb3p2dGtraUhKcFl4RDZvMW43RmNONDRvT0pIb1FBSTB4cmV3N1d5R1R6T3B6b0EwRTBCSDAwQWJpOVhJTk5uUTVMTGdKUmRJRjBIYkp4ZmtqMVF2RWxja01IOTRETXhuMTRzOWNZUWdJa0k2NzZ2aHdGQmhBQXd2Yk44NDU4d3F0WHNsKzBMbnJzPVwifScsXG4gICAgICAgIGJpdGdvS2V5OlxuICAgICAgICAgICd4cHViNjYxTXlNd0FxUmJjR1lxOVJ0V1l6S3V2cWJhMkVIcjl2QWtEYlBzTmkxTDlUbWlIU1JVWEhxeGUxOFA0REhYdERGdFV5NFNiOWJocFNoSEVXVzloM0x3SE05YkIycW9QMmN3V1RkdVY5blAnLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAndGVzdF93YWxsZXRfcGFzc3BocmFzZScsXG4gICAgICAgIHRva2VuQ29udHJhY3RBZGRyZXNzOiAnVEczWFh5RXhCa1BwOW56ZGFqRFpzb3pFdTRCa2FTSm96cycsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdUWVBneDhOZkR4QjhweWl5VGVpTWtZemVtMWROQTZHMTJpJyxcbiAgICAgIH0pO1xuXG4gICAgICBzaG91bGQuZXhpc3QocmVjb3ZlcnlUeCk7XG5cbiAgICAgIHJlY292ZXJ5VHgudHguc2lnbmF0dXJlWzBdLnNob3VsZC5lcXVhbChcbiAgICAgICAgJzNhNjdlZWU3YWUwNjdjZDg1Y2FlODY1MzBiZTMzOGFmMmNmZjQwMzRhMzBmMzk2NTZlMmQ4MTE3ZmY3OTE1YWQyNTYxNzZhZmNmYmU4MTc3YzQxOTVlYTg4N2Q3OTc0MDQyMGIxMmY5ZWE3YzU2OThhNmQyZWVlYzI2MGYzNGRmMDEnXG4gICAgICApO1xuICAgICAgcmVjb3ZlcnlUeC50eC5zaWduYXR1cmVbMV0uc2hvdWxkLmVxdWFsKFxuICAgICAgICAnNTUxZDQxZTAwN2I4YjM2YjJhYzUwMjk3ZmQ1MzY3OGYxOTYwNjc4NDg3MzFmNDM0MGY3ZWUwZWI2ZDk2M2MyNGIxMWRkZTk2NzI3ZjNjZjRkMDUxYWY1ODY4NjlkYWE1MTM5NGRiMDg1M2U2ZDRjODBlNDFmZWU0MTRhOWM5NTIwMSdcbiAgICAgICk7XG4gICAgICByZWNvdmVyeVR4LnR4LnR4SUQuc2hvdWxkLmVxdWFsKCcyODExN2Q5ZjBjM2FjMWZlMjJmYTJjYjEwNDEyNTM3NzYzZmVhOGFkNmI0YjhkMDUwNGQ4ZjI1YzYxNDFmNDNjJyk7XG4gICAgICByZWNvdmVyeVR4LnR4LnJhd19kYXRhX2hleC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwYTAyYTcxYzIyMDhkMGVjYjUzYWEwMzg4MmE2NDBkODljZjNhZWU2MzA1YWFlMDEwODFmMTJhOTAxMGEzMTc0Nzk3MDY1MmU2NzZmNmY2NzZjNjU2MTcwNjk3MzJlNjM2ZjZkMmY3MDcyNmY3NDZmNjM2ZjZjMmU1NDcyNjk2NzY3NjU3MjUzNmQ2MTcyNzQ0MzZmNmU3NDcyNjE2Mzc0MTI3NDBhMTU0MTZhMGEwNWUwOThjNjI4ZjdmM2NhNjNkYmI1NzU2ZTVjMGMwMTg1MjExMjE1NDE0MmExZTM5YWVmYTQ5MjkwZjJiM2Y5ZWQ2ODhkN2NlY2Y4NmNkNmUwMjI0NGE5MDU5Y2JiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwZjVmNDE0ZDQ0N2FhZmU3MGJiOWI5ZDkzOTEyY2JjNGM1NGYwYzAxNDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxMjQxMDExMDA3MGEyYTlkNjg1ZTYzMDkwMDE4MGMyZDcyZidcbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdSZWNvdmVyIEVPUycsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgYmFzZUNvaW47XG4gICAgY29uc3QgZXhwZWN0ZWRQYWNrZWRUcnggPVxuICAgICAgJzcxMjIzMTVkNWU5MWQ0MDhlMWIzMDAwMDAwMDAwMTAwYTY4MjM0MDNlYTMwNTUwMDAwMDA1NzJkM2NjZGNkMDE1MGYzZWEyZTRjZjRiYzgzMDAwMDAwMDBhOGVkMzIzMjIxNTBmM2VhMmU0Y2Y0YmM4M2UwZjI3YzI3Y2MwYWRmN2Y0MDQyMGYwMDAwMDAwMDAwMDQ0NTRmNTMwMDAwMDAwMDAwMDAnO1xuICAgIGNvbnN0IGV4cGVjdGVkVHhJZCA9ICc5OWM2YTRlZWRmNWNmZjI0NjMxNGJkYzBhMDUzYzEyZDc1NDg4ZGYzYWEwOTQ3NGJhZDRjZWNhODhkOGIyNDk4JztcbiAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgYmFzZUNvaW4gPSBiaXRnby5jb2luKCd0ZW9zJyk7XG4gICAgfSk7XG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tFb3NSZWNvdmVyeSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBFT1MgcmVjb3ZlcnkgdHggd2l0aCBjb3JyZWN0IGV4cGlyYXRpb24gZGF0ZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlY292ZXJ5VHggPSBhd2FpdCBiYXNlQ29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTpcbiAgICAgICAgICAne1wiaXZcIjpcImpSQlppNDNjN3Q0dHZ4N1NnUDhoMGc9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJUZ1pxSHRacm1MVT1cIixcImN0XCI6XCJoUm50enJiY0g4MWRPemx5cjQ5bmJBSUpkSFdxRUtLVkp4MHM1NWtOVitmcVVqS0tvRXVXcVZHRjFkUGZRa2tUa2NJakZUTnZ1SHNpR2ljVkdTUmY1UkkzUTBaRDZZdENxTzJiV1g2dDdIZ0JpbzV5WU1hUHkrY05KSG1wNmpIQlFGWjljQ2pxd0FhbS9WKzFtUnZwSnBuMmRTV1BvdHc9XCJ9JyxcbiAgICAgICAgYmFja3VwS2V5OlxuICAgICAgICAgICd7XCJpdlwiOlwicUUrRCtDNktYYVpLRlhYVE0vQUY1dz09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcImEvWUQ3LzhnSkZ3PVwiLFwiY3RcIjpcInRjMmMxUGZTakRTOVRzaFhFSUtLbFRvRGNkQ2VMNDVmcEdVV0VQSU0yKzZDcnZJdWFYWkM2L0h4OWJ6YTdWSW9FUGhKV0htZ3ZvZUFvdXRvNFBVcG55S0pVdXorVDQ2UlkwOVhKczJyY0R2YmZNS2JsUnNoNmx6VWM4Tzd1YlR6SlJOZ0ZPVXFrWk02cUdCMjJBMEZ0TDh5TmxGcWMzYz1cIn0nLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVjIuVEVTVF9SRUNPVkVSWV9QQVNTQ09ERSxcbiAgICAgICAgcm9vdEFkZHJlc3M6ICdraXlqY24xaXhmdHAnLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiAnanpqa3BuMWJqbnRpJyxcbiAgICAgIH0pO1xuXG4gICAgICByZWNvdmVyeVR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0cmFuc2FjdGlvbicpO1xuICAgICAgcmVjb3ZlcnlUeC50cmFuc2FjdGlvbi5jb21wcmVzc2lvbi5zaG91bGQuZXF1YWwoJ25vbmUnKTtcbiAgICAgIHJlY292ZXJ5VHgudHJhbnNhY3Rpb24ucGFja2VkX3RyeC5zaG91bGQuZXF1YWwoZXhwZWN0ZWRQYWNrZWRUcngpO1xuICAgICAgcmVjb3ZlcnlUeC50cmFuc2FjdGlvbi5zaWduYXR1cmVzLmxlbmd0aC5zaG91bGQuZXF1YWwoMik7XG4gICAgICByZWNvdmVyeVR4LnR4aWQuc2hvdWxkLmVxdWFsKGV4cGVjdGVkVHhJZCk7XG5cbiAgICAgIGNvbnN0IGRlc2VyaWFsaXplVHJhbnNhY3Rpb25QYXJhbXMgPSB7XG4gICAgICAgIHRyYW5zYWN0aW9uOiB7XG4gICAgICAgICAgcGFja2VkX3RyeDogcmVjb3ZlcnlUeC50cmFuc2FjdGlvbi5wYWNrZWRfdHJ4LFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgZGVzZXJpYWxpemVkVHggPSBhd2FpdCBiYXNlQ29pbi5kZXNlcmlhbGl6ZVRyYW5zYWN0aW9uKGRlc2VyaWFsaXplVHJhbnNhY3Rpb25QYXJhbXMpO1xuICAgICAgY29uc3QgbW9ja2VkSGVhZEJsb2NrVGltZSA9ICcyMDE5LTA3LTE4VDE3OjUyOjQ5LjAwMCc7XG4gICAgICBjb25zdCBob3Vyc1VudGlsRXhwaXJhdGlvbiA9IDg7XG4gICAgICBjb25zdCBob3VyRGlmZiA9IChuZXcgRGF0ZShkZXNlcmlhbGl6ZWRUeC5leHBpcmF0aW9uKS5nZXRUaW1lKCkgLSBuZXcgRGF0ZShtb2NrZWRIZWFkQmxvY2tUaW1lKS5nZXRUaW1lKCkpIC8gMzZlNTtcbiAgICAgIGhvdXJEaWZmLnNob3VsZC5lcXVhbChob3Vyc1VudGlsRXhwaXJhdGlvbik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIEVPUyByZWNvdmVyeSB0eCB3aXRoIHVuZW5jcnlwdGVkIGtleXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZWNvdmVyeVR4ID0gYXdhaXQgYmFzZUNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6XG4gICAgICAgICAgJ3hwcnY5czIxWnJRSDE0M0s0TkRnbktIOHpUVExwSnVDbXY2ZHR5a1JKd2FwQkg3M2J2Y3ZUdkNRQU1tUUx4UkdxZzVZYnZYQk41VkdEM3kyY1BHVUd5clZjaldESk01NzNSVnNlSGc0b0w2NEFYeCcsXG4gICAgICAgIGJhY2t1cEtleTpcbiAgICAgICAgICAneHBydjlzMjFaclFIMTQzSzRHaDNzblg4ejVkMjRkakVWd0N3VndkSEdFc3NVcEt3SHFLRHRBejhnUlB3N0ZpMTJOQzN1cjk0Q3NKMktvcm11blFRbTNnTmtYUWlUeTUzNE5kZnVRNEMyRXBkbVJwJyxcbiAgICAgICAgcm9vdEFkZHJlc3M6ICdraXlqY24xaXhmdHAnLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiAnanpqa3BuMWJqbnRpJyxcbiAgICAgIH0pO1xuXG4gICAgICByZWNvdmVyeVR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0cmFuc2FjdGlvbicpO1xuICAgICAgcmVjb3ZlcnlUeC50cmFuc2FjdGlvbi5jb21wcmVzc2lvbi5zaG91bGQuZXF1YWwoJ25vbmUnKTtcbiAgICAgIHJlY292ZXJ5VHgudHJhbnNhY3Rpb24ucGFja2VkX3RyeC5zaG91bGQuZXF1YWwoZXhwZWN0ZWRQYWNrZWRUcngpO1xuICAgICAgcmVjb3ZlcnlUeC50cmFuc2FjdGlvbi5zaWduYXR1cmVzLmxlbmd0aC5zaG91bGQuZXF1YWwoMik7XG4gICAgICByZWNvdmVyeVR4LnR4aWQuc2hvdWxkLmVxdWFsKGV4cGVjdGVkVHhJZCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGFuIEVPUyB1bnNpZ25lZCBzd2VlcCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlY292ZXJ5VHggPSBhd2FpdCBiYXNlQ29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTpcbiAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0dySjl0THA5TWJRNU5MamhCTnBWR0NnMjdLelJqY2UyVWl4NTFUV2VpQTV0Q0R5QkZIRU5tS1NmNkJpV2czdEFqWWdyaFR6OWJaR2RYajdwZmtzWGFFcFZMUXF6WUVFJyxcbiAgICAgICAgYmFja3VwS2V5OlxuICAgICAgICAgICd4cHViNjYxTXlNd0FxUmJjR2ttV3lwNDlNRFprY2ZaaXVQdm5zQVl0NGRIVjM5cnZBZGVOUmlKUEVEaVF4WVROcmJGRUhKVkJKV0JkeFc3RGdDcVJVeVZwWUFiVDNENkxHc1pweW5ZcE1GQWdBWnInLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVjIuVEVTVF9SRUNPVkVSWV9QQVNTQ09ERSxcbiAgICAgICAgcm9vdEFkZHJlc3M6ICdraXlqY24xaXhmdHAnLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiAnanpqa3BuMWJqbnRpJyxcbiAgICAgIH0pO1xuXG4gICAgICByZWNvdmVyeVR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0cmFuc2FjdGlvbicpO1xuICAgICAgcmVjb3ZlcnlUeC50cmFuc2FjdGlvbi5jb21wcmVzc2lvbi5zaG91bGQuZXF1YWwoJ25vbmUnKTtcbiAgICAgIHJlY292ZXJ5VHgudHJhbnNhY3Rpb24ucGFja2VkX3RyeC5zaG91bGQuZXF1YWwoZXhwZWN0ZWRQYWNrZWRUcngpO1xuICAgICAgcmVjb3ZlcnlUeC50cmFuc2FjdGlvbi5zaWduYXR1cmVzLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gICAgICByZWNvdmVyeVR4LnR4aWQuc2hvdWxkLmVxdWFsKGV4cGVjdGVkVHhJZCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdSZWNvdmVyIEVSQzIwJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgc3VjY2Vzc2Z1bGx5IGNvbnN0cnVjdCBhIHJlY292ZXJ5IHRyYW5zYWN0aW9uIGZvciB0b2tlbnMgc3R1Y2sgaW4gYSB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXQgPSBiaXRnby5ub2NrRXRoV2FsbGV0KCk7XG5cbiAgICAgIC8vIFRoZXJlIHNob3VsZCBiZSAyNCBQb3RhdG9rZW5zIHN0dWNrIGluIG91ciB0ZXN0IHdhbGxldCAoYmFzZWQgb24gbm9jaylcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgd2FsbGV0LnJlY292ZXJUb2tlbih7XG4gICAgICAgIHRva2VuQ29udHJhY3RBZGRyZXNzOiBUZXN0Qml0R28uVjIuVEVTVF9FUkMyMF9UT0tFTl9BRERSRVNTLFxuICAgICAgICByZWNpcGllbnQ6IFRlc3RCaXRHby5WMi5URVNUX0VSQzIwX1RPS0VOX1JFQ0lQSUVOVCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlYyLlRFU1RfRVRIX1dBTExFVF9QQVNTUEhSQVNFLFxuICAgICAgfSk7XG5cbiAgICAgIHNob3VsZC5leGlzdCh0eCk7XG4gICAgICB0eC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaGFsZlNpZ25lZCcpO1xuXG4gICAgICBjb25zdCB0eEluZm8gPSB0eC5oYWxmU2lnbmVkO1xuICAgICAgdHhJbmZvLnNob3VsZC5oYXZlLnByb3BlcnR5KCdjb250cmFjdFNlcXVlbmNlSWQnKTtcbiAgICAgIHR4SW5mby5jb250cmFjdFNlcXVlbmNlSWQuc2hvdWxkLmVxdWFsKDExMDEpO1xuICAgICAgdHhJbmZvLnNob3VsZC5oYXZlLnByb3BlcnR5KCdleHBpcmVUaW1lJyk7XG4gICAgICB0eEluZm8uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2dhc0xpbWl0Jyk7XG4gICAgICB0eEluZm8uZ2FzTGltaXQuc2hvdWxkLmVxdWFsKDUwMDAwMCk7XG4gICAgICB0eEluZm8uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2dhc1ByaWNlJyk7XG4gICAgICB0eEluZm8uZ2FzUHJpY2Uuc2hvdWxkLmVxdWFsKDIwMDAwMDAwMDAwKTtcbiAgICAgIHR4SW5mby5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnb3BlcmF0aW9uSGFzaCcpO1xuICAgICAgdHhJbmZvLnNob3VsZC5oYXZlLnByb3BlcnR5KCdzaWduYXR1cmUnKTtcbiAgICAgIHR4SW5mby5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndG9rZW5Db250cmFjdEFkZHJlc3MnKTtcbiAgICAgIHR4SW5mby50b2tlbkNvbnRyYWN0QWRkcmVzcy5zaG91bGQuZXF1YWwoVGVzdEJpdEdvLlYyLlRFU1RfRVJDMjBfVE9LRU5fQUREUkVTUyk7XG4gICAgICB0eEluZm8uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldElkJyk7XG4gICAgICB0eEluZm8ud2FsbGV0SWQuc2hvdWxkLmVxdWFsKFRlc3RCaXRHby5WMi5URVNUX0VUSF9XQUxMRVRfSUQpO1xuICAgICAgdHhJbmZvLnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNpcGllbnQnKTtcbiAgICAgIHR4SW5mby5yZWNpcGllbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2FkZHJlc3MnKTtcbiAgICAgIHR4SW5mby5yZWNpcGllbnQuYWRkcmVzcy5zaG91bGQuZXF1YWwoVGVzdEJpdEdvLlYyLlRFU1RfRVJDMjBfVE9LRU5fUkVDSVBJRU5UKTtcbiAgICAgIHR4SW5mby5yZWNpcGllbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Ftb3VudCcpO1xuICAgICAgdHhJbmZvLnJlY2lwaWVudC5hbW91bnQuc2hvdWxkLmVxdWFsKCcyNDAwJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHN1Y2Nlc3NmdWxseSBnZW5lcmF0ZSBhbiBFUkMyMCB1bnNpZ25lZCBzd2VlcCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja0V0aExpa2VSZWNvdmVyeShiaXRnbyk7XG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndGRhaScpO1xuXG4gICAgICAvLyBUaGVyZSBzaG91bGQgYmUgMSBUREFJIHRva2VuIGluIG91ciB0ZXN0IHdhbGxldCAoYmFzZWQgb24gbm9jaylcbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6XG4gICAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNGWERjV0Qydnh1ZWJjVDFacFRGNFZrZTZxbU1XOHl6ZGR3TllwQVBqdllFRUw1akxmeVlYVzJmdXh0QXhZOFRnalBVSkxjZjFDOHF6OU42VmdaeEFyS1g0RXdCOHJINScsXG4gICAgICAgIGJhY2t1cEtleTpcbiAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0doU2FYaWtwdVRDOUtVODhYeDlMcmpLU3cxSktzdlhOZ2FicFRkZ2p5N0xTb3ZoOVpIaGNxaEFIUXU3dXRodTdGZ3VOR2RjQzRhWFRLSzVncVRjUGU0V3ZMWVJiQ1NHJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiBUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MsXG4gICAgICAgIHRva2VuQ29udHJhY3RBZGRyZXNzOiBUZXN0Qml0R28uVjIuVEVTVF9FUkMyMF9UT0tFTl9BRERSRVNTLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBUZXN0Qml0R28uVjIuVEVTVF9FUkMyMF9UT0tFTl9SRUNJUElFTlQsXG4gICAgICB9KTtcbiAgICAgIHNob3VsZC5leGlzdCh0cmFuc2FjdGlvbik7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHgnKTtcblxuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NvbnRyYWN0U2VxdWVuY2VJZCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2V4cGlyZVRpbWUnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdnYXNMaW1pdCcpO1xuICAgICAgdHJhbnNhY3Rpb24uZ2FzTGltaXQuc2hvdWxkLmVxdWFsKCc1MDAwMDAnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdnYXNQcmljZScpO1xuICAgICAgdHJhbnNhY3Rpb24uZ2FzUHJpY2Uuc2hvdWxkLmVxdWFsKCcyMDAwMDAwMDAwMCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3Rva2VuQ29udHJhY3RBZGRyZXNzJyk7XG4gICAgICB0cmFuc2FjdGlvbi50b2tlbkNvbnRyYWN0QWRkcmVzcy5zaG91bGQuZXF1YWwoVGVzdEJpdEdvLlYyLlRFU1RfVERBSV9UT0tFTl9BRERSRVNTKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRDb250cmFjdEFkZHJlc3MnKTtcbiAgICAgIHRyYW5zYWN0aW9uLndhbGxldENvbnRyYWN0QWRkcmVzcy5zaG91bGQuZXF1YWwoVGVzdEJpdEdvLlYyLlRFU1RfRVRIX1dBTExFVF9GSVJTVF9BRERSRVNTKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNpcGllbnQnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnJlY2lwaWVudC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYWRkcmVzcycpO1xuICAgICAgdHJhbnNhY3Rpb24ucmVjaXBpZW50LmFkZHJlc3Muc2hvdWxkLmVxdWFsKFRlc3RCaXRHby5WMi5URVNUX0VSQzIwX1RPS0VOX1JFQ0lQSUVOVCk7XG4gICAgICB0cmFuc2FjdGlvbi5yZWNpcGllbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Ftb3VudCcpO1xuICAgICAgdHJhbnNhY3Rpb24ucmVjaXBpZW50LmFtb3VudC5zaG91bGQuZXF1YWwoJzEwMDAwMDAwMDAwMDAwMDAwMDAnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdXNlIHVzZXIgcHJvdmlkZWQgZ2FzIHBhcmFtcyB3aGVuIGJ1aWxkaW5nIHJlY292ZXJ5IHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrRXRoTGlrZVJlY292ZXJ5KGJpdGdvKTtcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0ZGFpJyk7XG5cbiAgICAgIC8vIFRoZXJlIHNob3VsZCBiZSAxIFREQUkgdG9rZW4gaW4gb3VyIHRlc3Qgd2FsbGV0IChiYXNlZCBvbiBub2NrKVxuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTpcbiAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0ZYRGNXRDJ2eHVlYmNUMVpwVEY0VmtlNnFtTVc4eXpkZHdOWXBBUGp2WUVFTDVqTGZ5WVhXMmZ1eHRBeFk4VGdqUFVKTGNmMUM4cXo5TjZWZ1p4QXJLWDRFd0I4ckg1JyxcbiAgICAgICAgYmFja3VwS2V5OlxuICAgICAgICAgICd4cHViNjYxTXlNd0FxUmJjR2hTYVhpa3B1VEM5S1U4OFh4OUxyaktTdzFKS3N2WE5nYWJwVGRnank3TFNvdmg5WkhoY3FoQUhRdTd1dGh1N0ZndU5HZGNDNGFYVEtLNWdxVGNQZTRXdkxZUmJDU0cnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IFRlc3RCaXRHby5WMi5URVNUX0VUSF9XQUxMRVRfRklSU1RfQUREUkVTUyxcbiAgICAgICAgdG9rZW5Db250cmFjdEFkZHJlc3M6IFRlc3RCaXRHby5WMi5URVNUX0VSQzIwX1RPS0VOX0FERFJFU1MsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IFRlc3RCaXRHby5WMi5URVNUX0VSQzIwX1RPS0VOX1JFQ0lQSUVOVCxcbiAgICAgICAgZ2FzTGltaXQ6ICc0MDAwMDAnLFxuICAgICAgICBlaXAxNTU5OiB7XG4gICAgICAgICAgbWF4RmVlUGVyR2FzOiAnMTAwMDAwMDAwMDAnLFxuICAgICAgICAgIG1heFByaW9yaXR5RmVlUGVyR2FzOiAnNTAwMCcsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIHNob3VsZC5leGlzdCh0cmFuc2FjdGlvbik7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHgnKTtcblxuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NvbnRyYWN0U2VxdWVuY2VJZCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2V4cGlyZVRpbWUnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdnYXNMaW1pdCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2VpcDE1NTknKTtcbiAgICAgIHRyYW5zYWN0aW9uLmdhc0xpbWl0LnNob3VsZC5lcXVhbCgnNDAwMDAwJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZ2FzUHJpY2UnKTtcbiAgICAgIHRyYW5zYWN0aW9uLmdhc1ByaWNlLnNob3VsZC5lcXVhbCgnMTAwMDAwMDAwMDAnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0b2tlbkNvbnRyYWN0QWRkcmVzcycpO1xuICAgICAgdHJhbnNhY3Rpb24udG9rZW5Db250cmFjdEFkZHJlc3Muc2hvdWxkLmVxdWFsKFRlc3RCaXRHby5WMi5URVNUX1REQUlfVE9LRU5fQUREUkVTUyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0Q29udHJhY3RBZGRyZXNzJyk7XG4gICAgICB0cmFuc2FjdGlvbi53YWxsZXRDb250cmFjdEFkZHJlc3Muc2hvdWxkLmVxdWFsKFRlc3RCaXRHby5WMi5URVNUX0VUSF9XQUxMRVRfRklSU1RfQUREUkVTUyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncmVjaXBpZW50Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5yZWNpcGllbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2FkZHJlc3MnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnJlY2lwaWVudC5hZGRyZXNzLnNob3VsZC5lcXVhbChUZXN0Qml0R28uVjIuVEVTVF9FUkMyMF9UT0tFTl9SRUNJUElFTlQpO1xuICAgICAgdHJhbnNhY3Rpb24ucmVjaXBpZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhbW91bnQnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnJlY2lwaWVudC5hbW91bnQuc2hvdWxkLmVxdWFsKCcxMDAwMDAwMDAwMDAwMDAwMDAwJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdSZWNvdmVyIEV0aGVyZXVtJywgZnVuY3Rpb24gKCkge1xuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIH0pO1xuICAgIGxldCByZWNvdmVyeVBhcmFtcztcblxuICAgIGNvbnN0IG5vY2tUU1NEYXRhOiBhbnlbXSA9IFtcbiAgICAgIHtcbiAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgbW9kdWxlOiAnYWNjb3VudCcsXG4gICAgICAgICAgYWN0aW9uOiAndHhsaXN0JyxcbiAgICAgICAgICBhZGRyZXNzOiAnMHhlNzQwNmRjNDNkMTNmNjk4ZmI0MWEzNDVjNzc4M2QzOWE0YzJkMTkxJyxcbiAgICAgICAgfSxcbiAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICBzdGF0dXM6ICcwJyxcbiAgICAgICAgICBtZXNzYWdlOiAnTm8gdHJhbnNhY3Rpb25zIGZvdW5kJyxcbiAgICAgICAgICByZXN1bHQ6IFtdLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgbW9kdWxlOiAnYWNjb3VudCcsXG4gICAgICAgICAgYWN0aW9uOiAnYmFsYW5jZScsXG4gICAgICAgICAgYWRkcmVzczogJzB4ZTc0MDZkYzQzZDEzZjY5OGZiNDFhMzQ1Yzc3ODNkMzlhNGMyZDE5MScsXG4gICAgICAgIH0sXG4gICAgICAgIHJlc3BvbnNlOiB7XG4gICAgICAgICAgc3RhdHVzOiAnMScsXG4gICAgICAgICAgbWVzc2FnZTogJ09LJyxcbiAgICAgICAgICByZXN1bHQ6ICcxMDAwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgXTtcbiAgICBjb25zdCBub2NrVW5zaWduZWRTd2VlcFRTU0RhdGE6IGFueVtdID0gW1xuICAgICAge1xuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBtb2R1bGU6ICdhY2NvdW50JyxcbiAgICAgICAgICBhY3Rpb246ICd0eGxpc3QnLFxuICAgICAgICAgIGFkZHJlc3M6ICcweGE5MWUxMDU5OTUzZDdlZjJhZGJiY2E0YjY4OGJmZTIyODY2ZmJjZWUnLFxuICAgICAgICB9LFxuICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgIHN0YXR1czogJzAnLFxuICAgICAgICAgIG1lc3NhZ2U6ICdObyB0cmFuc2FjdGlvbnMgZm91bmQnLFxuICAgICAgICAgIHJlc3VsdDogW10sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBtb2R1bGU6ICdhY2NvdW50JyxcbiAgICAgICAgICBhY3Rpb246ICdiYWxhbmNlJyxcbiAgICAgICAgICBhZGRyZXNzOiAnMHhhOTFlMTA1OTk1M2Q3ZWYyYWRiYmNhNGI2ODhiZmUyMjg2NmZiY2VlJyxcbiAgICAgICAgfSxcbiAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICBzdGF0dXM6ICcxJyxcbiAgICAgICAgICBtZXNzYWdlOiAnT0snLFxuICAgICAgICAgIHJlc3VsdDogJzEwMDAwMDAwMDAwMDAwMDAwMDAnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICBdO1xuICAgIGxldCByZWNvdmVyRXRoU2FuZGJveDogc2lub24uU2lub25TYW5kYm94O1xuXG4gICAgYmVmb3JlKCgpID0+IHtcbiAgICAgIHJlY292ZXJ5UGFyYW1zID0ge1xuICAgICAgICB1c2VyS2V5OlxuICAgICAgICAgICd7XCJpdlwiOlwiK1RrbVQzR0o1bXNWV1FqQnJ0M2xzdz09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIlxcbicgK1xuICAgICAgICAgICc6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJjQ0UyMGZHSW9icz1cIixcImN0XCI6XCJOVklkWUloOTFKM2FSSVxcbicgK1xuICAgICAgICAgICc4R0cwSkUzRGhYVzNBVW16Mkc1UnFNZWpkejErdDQvdm92SVA3bGxlZWdJN1ZZeVdpaUx2bE0wT0NGZjNFVnZWL1J5WHI4KzJ2c25cXG4nICtcbiAgICAgICAgICAnUTBWbjhjMkNWNUZSWjgwT2pHWXJXM0EvNlQvenBPejZFOENNdm5EKytpSXBlTzRyMmVaSmF2ZWpaeGR6bHhGMEJSejdWST1cIn0nLFxuICAgICAgICBiYWNrdXBLZXk6XG4gICAgICAgICAgJ3tcIml2XCI6XCJhc0IzNTZvZkM3blp0ZzROQnZRa2lRPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiXFxuJyArXG4gICAgICAgICAgJzpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIjFocjJIaEJiQklrPVwiLFwiY3RcIjpcIjhDWmM2dXB0K1hOT3RvXFxuJyArXG4gICAgICAgICAgJ0tERDM4VFVnM1pVanpXK0RyYVpsa2NrdTJiTnAwSlMyczFnL2lDNllUR1VHdFBveER4dW1EbFh3bFdReCs1V1BqWnU3OU04RENySVxcbicgK1xuICAgICAgICAgICd0OWFaYU92SGtHSDlhRnRNYmF2Rlg0MTlUY3J3RG1wVWVRRk4waFJrZnJJSFh5SE5iVHBHU1ZBakh2SE10ekRNYXcrQUNnPVwifScsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IFRlc3RCaXRHby5WMi5URVNUX1JFQ09WRVJZX1BBU1NDT0RFLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICcweDVkZjVhOTZiNDc4YmIxODA4MTQwZDg3MDcyMTQzZTYwMjYyZTg2NzAnLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiAnMHhhYzA1ZGE3ODQ2NDUyMGFhN2M5ZDRjMTliZDdhNDQwYjExMWIzMDU0JyxcbiAgICAgICAgcmVwbGF5UHJvdGVjdGlvbk9wdGlvbnM6IHtcbiAgICAgICAgICBjaGFpbjogNDIsXG4gICAgICAgICAgaGFyZGZvcms6ICdsb25kb24nLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIHJlY292ZXJFdGhTYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgICAgcmVjb3ZlckV0aFNhbmRib3hcbiAgICAgICAgLnN0dWIoRWNkc2FSYW5nZVByb29mLCAnZ2VuZXJhdGVOdGlsZGUnKVxuICAgICAgICAucmVzb2x2ZXMoRWNkc2FUeXBlcy5kZXNlcmlhbGl6ZU50aWxkZVdpdGhQcm9vZnMobW9ja1NlcmlhbGl6ZWRDaGFsbGVuZ2VXaXRoUHJvb2ZzKSk7XG4gICAgfSk7XG5cbiAgICBhZnRlcigoKSA9PiB7XG4gICAgICByZWNvdmVyRXRoU2FuZGJveC5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IG9uIGludmFsaWQgZ2FzTGltaXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tFdGhMaWtlUmVjb3ZlcnkoYml0Z28pO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJyk7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucmVjb3Zlcih7XG4gICAgICAgICAgLi4ucmVjb3ZlcnlQYXJhbXMsXG4gICAgICAgICAgZ2FzTGltaXQ6IC00MDAwMDAsXG4gICAgICAgICAgZ2FzUHJpY2U6IDI1MDAwMDAwMDAwLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnR2FzIGxpbWl0IG11c3QgYmUgYmV0d2VlbiAzMDAwMCBhbmQgMjAwMDAwMDAnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgaWYgZXRoZXJzY2FuIGVycnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBub2NrVW5zdWNjZXNzZnVsRXRoZXJzY2FuRGF0YTogYW55W10gPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgIG1vZHVsZTogJ2FjY291bnQnLFxuICAgICAgICAgICAgYWN0aW9uOiAndHhsaXN0JyxcbiAgICAgICAgICAgIGFkZHJlc3M6ICcweDc0YzIxMzdkNTRiMGZjOWY5MDdlMTNmMTRlMGRkMTg0ODVmZWU5MjQnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICAgIHN0YXR1czogJzAnLFxuICAgICAgICAgICAgbWVzc2FnZTogJ05vIHRyYW5zYWN0aW9ucyBmb3VuZCcsXG4gICAgICAgICAgICByZXN1bHQ6IFtdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgIG1vZHVsZTogJ2FjY291bnQnLFxuICAgICAgICAgICAgYWN0aW9uOiAnYmFsYW5jZScsXG4gICAgICAgICAgICBhZGRyZXNzOiAnMHg3NGMyMTM3ZDU0YjBmYzlmOTA3ZTEzZjE0ZTBkZDE4NDg1ZmVlOTI0JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJlc3BvbnNlOiB7XG4gICAgICAgICAgICBzdGF0dXM6ICcxJyxcbiAgICAgICAgICAgIG1lc3NhZ2U6ICdOT1RPSycsXG4gICAgICAgICAgICByZXN1bHQ6ICdSYXRlIGxpbWl0IGV4Y2VlZGVkJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgXTtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja0V0aExpa2VSZWNvdmVyeShiaXRnbywgbm9ja1Vuc3VjY2Vzc2Z1bEV0aGVyc2NhbkRhdGEpO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJyk7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucmVjb3ZlcihyZWNvdmVyeVBhcmFtcylcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ0NvdWxkIG5vdCBvYnRhaW4gYWRkcmVzcyBiYWxhbmNlIGZvciAweDc0YzIxMzdkNTRiMGZjOWY5MDdlMTNmMTRlMGRkMTg0ODVmZWU5MjQgZnJvbSB0aGUgZXhwbG9yZXIsIGdvdDogUmF0ZSBsaW1pdCBleGNlZWRlZCdcbiAgICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgaWYgYmFja3VwIGtleSBhZGRyZXNzIGhhcyBpbnN1ZmZpY2llbnQgYmFsYW5jZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGluc3VmZmljaWVudEZlZURhdGE6IGFueVtdID0gW1xuICAgICAgICB7XG4gICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICBtb2R1bGU6ICdhY2NvdW50JyxcbiAgICAgICAgICAgIGFjdGlvbjogJ3R4bGlzdCcsXG4gICAgICAgICAgICBhZGRyZXNzOiAnMHg3NGMyMTM3ZDU0YjBmYzlmOTA3ZTEzZjE0ZTBkZDE4NDg1ZmVlOTI0JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJlc3BvbnNlOiB7XG4gICAgICAgICAgICBzdGF0dXM6ICcwJyxcbiAgICAgICAgICAgIG1lc3NhZ2U6ICdObyB0cmFuc2FjdGlvbnMgZm91bmQnLFxuICAgICAgICAgICAgcmVzdWx0OiBbXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICBtb2R1bGU6ICdhY2NvdW50JyxcbiAgICAgICAgICAgIGFjdGlvbjogJ2JhbGFuY2UnLFxuICAgICAgICAgICAgYWRkcmVzczogJzB4NzRjMjEzN2Q1NGIwZmM5ZjkwN2UxM2YxNGUwZGQxODQ4NWZlZTkyNCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgICAgc3RhdHVzOiAnMScsXG4gICAgICAgICAgICBtZXNzYWdlOiAnT0snLFxuICAgICAgICAgICAgcmVzdWx0OiAnMTIzNCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIF07XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tFdGhMaWtlUmVjb3ZlcnkoYml0Z28sIGluc3VmZmljaWVudEZlZURhdGEpO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJyk7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucmVjb3Zlcih7XG4gICAgICAgICAgLi4ucmVjb3ZlcnlQYXJhbXMsXG4gICAgICAgICAgZ2FzTGltaXQ6IDMwMDAwMCxcbiAgICAgICAgICBnYXNQcmljZTogMTAwMDAwMDAwMCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ0JhY2t1cCBrZXkgYWRkcmVzcyAweDc0YzIxMzdkNTRiMGZjOWY5MDdlMTNmMTRlMGRkMTg0ODVmZWU5MjQgaGFzIGJhbGFuY2UgMC4wMDAwMDEyMzQgR3dlaS4nICtcbiAgICAgICAgICAgICdUaGlzIGFkZHJlc3MgbXVzdCBoYXZlIGEgYmFsYW5jZSBvZiBhdCBsZWFzdCAzMDAwMDAgR3dlaSB0byBwZXJmb3JtIHJlY292ZXJpZXMuIFRyeSBzZW5kaW5nIHNvbWUgRVRIIHRvIHRoaXMgYWRkcmVzcyB0aGVuIHJldHJ5LidcbiAgICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgb24gaW52YWxpZCBnYXNQcmljZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja0V0aExpa2VSZWNvdmVyeShiaXRnbyk7XG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbignaHRldGgnKTtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5yZWNvdmVyKHtcbiAgICAgICAgICAuLi5yZWNvdmVyeVBhcmFtcyxcbiAgICAgICAgICBnYXNMaW1pdDogNDAwMDAwLFxuICAgICAgICAgIGdhc1ByaWNlOiAyNTAwMDAwLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnR2FzIHByaWNlIG11c3QgYmUgYmV0d2VlbiAxMDAwMDAwMDAwIGFuZCAyNTAwMDAwMDAwMDAwJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHN1Y2Nlc3NmdWxseSBjb25zdHJ1Y3QgYSB0eCB3aXRoIGN1c3RvbSBnYXMgcHJpY2UgYW5kIGxpbWl0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrRXRoTGlrZVJlY292ZXJ5KGJpdGdvKTtcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpO1xuICAgICAgY29uc3QgcmVjb3ZlcnkgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgLi4ucmVjb3ZlcnlQYXJhbXMsXG4gICAgICAgIGdhc0xpbWl0OiA0MDAwMDAsXG4gICAgICAgIGdhc1ByaWNlOiAxMDAwMDAwMDAwLFxuICAgICAgfSk7XG4gICAgICAvLyBpZCBhbmQgdHggd2lsbCBhbHdheXMgYmUgZGlmZmVyZW50IGJlY2F1c2Ugb2YgZXhwaXJlVGltZVxuICAgICAgc2hvdWxkLmV4aXN0KHJlY292ZXJ5KTtcbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdpZCcpO1xuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNvbnN0cnVjdCBhIHJlY292ZXJ5IHRyYW5zYWN0aW9uIHdpdGhvdXQgQml0R28nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tFdGhMaWtlUmVjb3ZlcnkoYml0Z28pO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJyk7XG4gICAgICBjb25zdCByZWNvdmVyeSA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIocmVjb3ZlcnlQYXJhbXMpO1xuICAgICAgLy8gaWQgYW5kIHR4IHdpbGwgYWx3YXlzIGJlIGRpZmZlcmVudCBiZWNhdXNlIG9mIGV4cGlyZVRpbWVcbiAgICAgIHNob3VsZC5leGlzdChyZWNvdmVyeSk7XG4gICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaWQnKTtcbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb25zdHJ1Y3QgYW4gZWlwMTU1OSByZWNvdmVyeSB0cmFuc2FjdGlvbiB3aXRob3V0IEJpdEdvJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZWlwMTU1OVJlY292ZXJ5UGFyYW1zID0ge1xuICAgICAgICAuLi5yZWNvdmVyeVBhcmFtcyxcbiAgICAgICAgZWlwMTU1OToge1xuICAgICAgICAgIG1heFByaW9yaXR5RmVlUGVyR2FzOiAzLFxuICAgICAgICAgIG1heEZlZVBlckdhczogMjAsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrRXRoTGlrZVJlY292ZXJ5KGJpdGdvKTtcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpO1xuICAgICAgY29uc3QgcmVjb3ZlcnkgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKGVpcDE1NTlSZWNvdmVyeVBhcmFtcyk7XG4gICAgICAvLyBpZCBhbmQgdHggd2lsbCBhbHdheXMgYmUgZGlmZmVyZW50IGJlY2F1c2Ugb2YgZXhwaXJlVGltZVxuICAgICAgc2hvdWxkLmV4aXN0KHJlY292ZXJ5KTtcbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdpZCcpO1xuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNvbnN0cnVjdCBhIHJlY292ZXJ5IHRyYW5zYWN0aW9uIHdpdGhvdXQgQml0R28gYW5kIHdpdGggS1JTJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrRXRoTGlrZVJlY292ZXJ5KGJpdGdvKTtcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpO1xuICAgICAgY29uc3QgcmVjb3ZlcnkgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgLi4ucmVjb3ZlcnlQYXJhbXMsXG4gICAgICAgIGJhY2t1cEtleTpcbiAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0dzQ05pRzRCemJ4TG1YbkpGbzRLNWdWU0UyYjlBeHVmQXRwdVR1bjFTWXdnOVV5a3FxZjREcktyRFo2S3FQbTllaHRoV2JDbWE3cG5hTXJ0WFkxMW5ZN01lRmJFRFBtJyxcbiAgICAgICAga3JzUHJvdmlkZXI6ICdrZXl0ZXJuYWwnLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIGlkIGFuZCB0eCB3aWxsIGFsd2F5cyBiZSBkaWZmZXJlbnQgYmVjYXVzZSBvZiBleHBpcmVUaW1lXG4gICAgICBzaG91bGQuZXhpc3QocmVjb3ZlcnkpO1xuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lkJyk7XG4gICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHgnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXJyb3Igd2hlbiB0aGUgYmFja3VwIGtleSBpcyB1bmZ1bmRlZCAoY2Fubm90IHBheSBnYXMpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrRXRoTGlrZVJlY292ZXJ5KGJpdGdvKTtcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpO1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXk6XG4gICAgICAgICAgICAne1wiaXZcIjpcIlZOdkc2dDNmSGZ4TWNmdk51YWZZWUE9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCJcXG4nICtcbiAgICAgICAgICAgICc6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJtYzlwQ2szSDQzdz1cIixcImN0XCI6XCJRZTRaMWV2YVhjck9NQ1xcbicgK1xuICAgICAgICAgICAgJ2NRL1hNVlZCTzlNLzk5RDFRUTZMeGtHOHozZlF0d3dPVlhNMy82ZG9OcnJpcHJVcXMrYWRwRkM5M0tSY0FhRHJvTDFFNm8xN0oya1xcbicgK1xuICAgICAgICAgICAgJ21jcFhSZDJDdVhSRk9SWm1aLzZRQmZqS2ZDSjNhcTBrRWtEVnYzN2daTlZUM2FOdEdrTlNRZENFV0tRTHdkMSsrcjVBa0E9XCJ9XFxuJyxcbiAgICAgICAgICBiYWNrdXBLZXk6XG4gICAgICAgICAgICAne1wiaXZcIjpcIkVqRDd4ME9KWDlrTk0vQzN5RUR2eVE9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCJcXG4nICtcbiAgICAgICAgICAgICc6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJOYTlOdlJSZTNuOD1cIixcImN0XCI6XCJCL0F0U0xIb2xzZE5MclxcbicgK1xuICAgICAgICAgICAgJzREbGlqNGtRMEU2TnlVVXM2d282VDJIdFBEQVBPMGh5aFBQYmgxT0FZcUlTN1ZsTDl4bUpSRkMyelB4d1JKdnpmNk9XQy9tNDhIWFxcbicgK1xuICAgICAgICAgICAgJ3ZnTG9YWWdhaEFyaGFsekpWbFJ4Y1hVejRIT2hvelJXZnYvZUszdDVISmZtKzI1K1dCT2lXOFlnU0U3aFZFWVRiZUJSRDQ9XCJ9JyxcbiAgICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICcweDIyZmY3NDMyMTZiNThhZWIzZWZjNDY5ODU0MDZiNTAxMTJlOWUxNzYnLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IFRlc3RCaXRHby5WMi5URVNUX1JFQ09WRVJZX1BBU1NDT0RFLFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICcweGFjMDVkYTc4NDY0NTIwYWE3YzlkNGMxOWJkN2E0NDBiMTExYjMwNTQnLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAnQmFja3VwIGtleSBhZGRyZXNzIDB4YmE2ZDlkODJjZjI5MjBjNTQ0YjgzNGI3MmY0YzZkMTFhM2VmM2RlNiBoYXMgYmFsYW5jZSAwIEd3ZWkuVGhpcyBhZGRyZXNzIG11c3QgaGF2ZSBhIGJhbGFuY2Ugb2YgYXQgbGVhc3QgMTAwMDAwMDAgR3dlaSB0byBwZXJmb3JtIHJlY292ZXJpZXMuIFRyeSBzZW5kaW5nIHNvbWUgRVRIIHRvIHRoaXMgYWRkcmVzcyB0aGVuIHJldHJ5LidcbiAgICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3Igd2hlbiB0aGUgZXRoZXJzY2FuIHJhdGUgbGltaXQgaXMgcmVhY2hlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbignaHRldGgnKTtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja0V0aGVyc2NhblJhdGVMaW1pdEVycm9yKCk7XG4gICAgICBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHJlY292ZXJ5UGFyYW1zKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdFdGhlcnNjYW4gcmF0ZSBsaW1pdCByZWFjaGVkJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGFuIEVUSCB1bnNpZ25lZCBzd2VlcCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja0V0aExpa2VSZWNvdmVyeShiaXRnbyk7XG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbignaHRldGgnKTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTpcbiAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0ZYRGNXRDJ2eHVlYmNUMVpwVEY0VmtlNnFtTVc4eXpkZHdOWXBBUGp2WUVFTDVqTGZ5WVhXMmZ1eHRBeFk4VGdqUFVKTGNmMUM4cXo5TjZWZ1p4QXJLWDRFd0I4ckg1JyxcbiAgICAgICAgYmFja3VwS2V5OlxuICAgICAgICAgICd4cHViNjYxTXlNd0FxUmJjR2hTYVhpa3B1VEM5S1U4OFh4OUxyaktTdzFKS3N2WE5nYWJwVGRnank3TFNvdmg5WkhoY3FoQUhRdTd1dGh1N0ZndU5HZGNDNGFYVEtLNWdxVGNQZTRXdkxZUmJDU0cnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IFRlc3RCaXRHby5WMi5URVNUX0VUSF9XQUxMRVRfRklSU1RfQUREUkVTUyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogVGVzdEJpdEdvLlYyLlRFU1RfRVJDMjBfVE9LRU5fUkVDSVBJRU5ULFxuICAgICAgICBnYXNQcmljZTogJzIwMDAwMDAwMDAwJyxcbiAgICAgICAgZ2FzTGltaXQ6ICc1MDAwMDAnLFxuICAgICAgfSk7XG4gICAgICBzaG91bGQuZXhpc3QodHJhbnNhY3Rpb24pO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY29udHJhY3RTZXF1ZW5jZUlkJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZXhwaXJlVGltZScpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2dhc0xpbWl0Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5nYXNMaW1pdC5zaG91bGQuZXF1YWwoJzUwMDAwMCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2dhc1ByaWNlJyk7XG4gICAgICB0cmFuc2FjdGlvbi5nYXNQcmljZS5zaG91bGQuZXF1YWwoJzIwMDAwMDAwMDAwJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0Q29udHJhY3RBZGRyZXNzJyk7XG4gICAgICB0cmFuc2FjdGlvbi53YWxsZXRDb250cmFjdEFkZHJlc3Muc2hvdWxkLmVxdWFsKFRlc3RCaXRHby5WMi5URVNUX0VUSF9XQUxMRVRfRklSU1RfQUREUkVTUyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncmVjaXBpZW50Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5yZWNpcGllbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2FkZHJlc3MnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnJlY2lwaWVudC5hZGRyZXNzLnNob3VsZC5lcXVhbChUZXN0Qml0R28uVjIuVEVTVF9FUkMyMF9UT0tFTl9SRUNJUElFTlQpO1xuICAgICAgdHJhbnNhY3Rpb24ucmVjaXBpZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhbW91bnQnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnJlY2lwaWVudC5hbW91bnQuc2hvdWxkLmVxdWFsKCc5OTk5OTk5OTk5OTk5OTk5OTI4Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNvbnN0cnVjdCBhIHJlY292ZXJ5IHR4IHdpdGggVFNTJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrRXRoTGlrZVJlY292ZXJ5KGJpdGdvLCBub2NrVFNTRGF0YSk7XG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJyk7XG4gICAgICBjb25zdCBiYXNlQWRkcmVzcyA9IGV0aExpa2VHRzE4S2V5Y2FyZC5zZW5kZXJBZGRyZXNzO1xuXG4gICAgICBjb25zdCBub2NrVFNTRGF0YVdpdGhCYXNlQWRkcmVzcyA9IG5vY2tUU1NEYXRhLm1hcCgoZGF0YSkgPT4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLmRhdGEsXG4gICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICAuLi5kYXRhLnBhcmFtcyxcbiAgICAgICAgICAgIGFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9KTtcblxuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrRXRoTGlrZVJlY292ZXJ5KGJpdGdvLCBub2NrVFNTRGF0YVdpdGhCYXNlQWRkcmVzcyk7XG4gICAgICByZWNvdmVyeVBhcmFtcyA9IHtcbiAgICAgICAgdXNlcktleTogZXRoTGlrZUdHMThLZXljYXJkLnVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogZXRoTGlrZUdHMThLZXljYXJkLmJhY2t1cEtleSxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiBldGhMaWtlR0cxOEtleWNhcmQuc2VuZGVyQWRkcmVzcyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogZXRoTGlrZUdHMThLZXljYXJkLmRlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogZXRoTGlrZUdHMThLZXljYXJkLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIGVpcDE1NTk6IHtcbiAgICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogMyxcbiAgICAgICAgICBtYXhGZWVQZXJHYXM6IDIwLFxuICAgICAgICB9LFxuICAgICAgICBpc1RzczogdHJ1ZSxcbiAgICAgICAgcmVwbGF5UHJvdGVjdGlvbk9wdGlvbnM6IHtcbiAgICAgICAgICBjaGFpbjogNSxcbiAgICAgICAgICBoYXJkZm9yazogJ2xvbmRvbicsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZWNvdmVyeSA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIocmVjb3ZlcnlQYXJhbXMpO1xuXG4gICAgICBzaG91bGQuZXhpc3QocmVjb3ZlcnkpO1xuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lkJyk7XG4gICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHgnKTtcblxuICAgICAgLy8gdmVyaWZ5IGRhdGEgYWZ0ZXIgc2lnbmluZyBpcyBjb3JyZWN0XG4gICAgICBjb25zdCBmaW5hbFR4ID0gVHJhbnNhY3Rpb25GYWN0b3J5LmZyb21TZXJpYWxpemVkRGF0YShCdWZmZXIuZnJvbShyZWNvdmVyeS50eC5zdWJzdHIoMiksICdoZXgnKSk7XG5cbiAgICAgIGNvbnN0IHNlbmRlckFkZHJlc3MgPSBmaW5hbFR4LmdldFNlbmRlckFkZHJlc3MoKS50b1N0cmluZygpO1xuXG4gICAgICBiYXNlQWRkcmVzcy5zaG91bGQuZXF1YWwoc2VuZGVyQWRkcmVzcyk7XG4gICAgICByZWNvdmVyeVBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uLnNob3VsZC5lcXVhbChmaW5hbFR4LnRvPy50b1N0cmluZygpKTtcbiAgICAgIE51bWJlcihmaW5hbFR4LnZhbHVlKS5zaG91bGQuZXF1YWwoOTk5OTk5OTk5OTkwMDAwMDAwKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29uc3RydWN0IGEgcmVjb3ZlcnkgdHggd2l0aCBNUEN2MiBUU1MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBmb3IgKGNvbnN0IHsgY29pbiwgY2hhaW4gfSBvZiBbXG4gICAgICAgIHsgY29pbjogJ2h0ZXRoJywgY2hhaW46IDE3MDAwIH0sXG4gICAgICAgIHsgY29pbjogJ3Rwb2x5Z29uJywgY2hhaW46IDgwMDAyIH0sXG4gICAgICAgIHsgY29pbjogJ3Ric2MnLCBjaGFpbjogOTcgfSxcbiAgICAgIF0pIHtcbiAgICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrRXRoTGlrZVJlY292ZXJ5KGJpdGdvLCBub2NrVFNTRGF0YSk7XG4gICAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbihjb2luKTtcbiAgICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSBldGhMaWtlREtMU0tleWNhcmQuc2VuZGVyQWRkcmVzcztcbiAgICAgICAgY29uc3Qgbm9ja1RTU0RhdGFXaXRoQmFzZUFkZHJlc3MgPSBub2NrVFNTRGF0YS5tYXAoKGRhdGEpID0+IHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uZGF0YSxcbiAgICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgICAuLi5kYXRhLnBhcmFtcyxcbiAgICAgICAgICAgICAgYWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja0V0aExpa2VSZWNvdmVyeShiaXRnbywgbm9ja1RTU0RhdGFXaXRoQmFzZUFkZHJlc3MpO1xuICAgICAgICByZWNvdmVyeVBhcmFtcyA9IHtcbiAgICAgICAgICB1c2VyS2V5OiBldGhMaWtlREtMU0tleWNhcmQudXNlcktleSxcbiAgICAgICAgICBiYWNrdXBLZXk6IGV0aExpa2VES0xTS2V5Y2FyZC5iYWNrdXBLZXksXG4gICAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBldGhMaWtlREtMU0tleWNhcmQuZGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IGV0aExpa2VES0xTS2V5Y2FyZC53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGVpcDE1NTk6IHtcbiAgICAgICAgICAgIG1heFByaW9yaXR5RmVlUGVyR2FzOiAzLFxuICAgICAgICAgICAgbWF4RmVlUGVyR2FzOiAyMCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGlzVHNzOiB0cnVlLFxuICAgICAgICAgIHJlcGxheVByb3RlY3Rpb25PcHRpb25zOiB7XG4gICAgICAgICAgICBjaGFpbjogY2hhaW4sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCByZWNvdmVyeSA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIocmVjb3ZlcnlQYXJhbXMpO1xuXG4gICAgICAgIHNob3VsZC5leGlzdChyZWNvdmVyeSk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdpZCcpO1xuICAgICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHgnKTtcblxuICAgICAgICAvLyB2ZXJpZnkgZGF0YSBhZnRlciBzaWduaW5nIGlzIGNvcnJlY3RcbiAgICAgICAgY29uc3QgZmluYWxUeCA9IFRyYW5zYWN0aW9uRmFjdG9yeS5mcm9tU2VyaWFsaXplZERhdGEoQnVmZmVyLmZyb20ocmVjb3ZlcnkudHguc3Vic3RyKDIpLCAnaGV4JykpO1xuXG4gICAgICAgIGNvbnN0IHNlbmRlckFkZHJlc3MgPSBmaW5hbFR4LmdldFNlbmRlckFkZHJlc3MoKS50b1N0cmluZygpO1xuICAgICAgICBmaW5hbFR4LmNvbW1vbi5jaGFpbklkQk4oKS50b051bWJlcigpLnNob3VsZC5lcXVhbChjaGFpbik7XG4gICAgICAgIGJhc2VBZGRyZXNzLnNob3VsZC5lcXVhbChzZW5kZXJBZGRyZXNzKTtcbiAgICAgICAgcmVjb3ZlcnlQYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbi5zaG91bGQuZXF1YWwoZmluYWxUeC50bz8udG9TdHJpbmcoKSk7XG4gICAgICAgIE51bWJlcihmaW5hbFR4LnZhbHVlKS5zaG91bGQuZXF1YWwoOTk5OTk5OTk5OTkwMDAwMDAwKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29uc3RydWN0IGFuIHVuc2lnbmVkIHN3ZWVwIHR4IHdpdGggVFNTJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrRXRoTGlrZVJlY292ZXJ5KGJpdGdvLCBub2NrVW5zaWduZWRTd2VlcFRTU0RhdGEpO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJyk7XG5cbiAgICAgIGNvbnN0IHVzZXJLZXkgPVxuICAgICAgICAnMDIzNGViMzliMjJmZWQ1MjNlY2U3Yzc4ZGEyOWJhMWYxZGU1YjY0YTZlNDgwMTNlMDkxNGRlNzkzYmMxZGYwNTcwZTc3OWRlMDQ3NTg3MzI3MzRkOTdlNTRiNzgyYzhiMzM2MjgzODExYWY2YTJjNTdiZDgxNDM4Nzk4ZTFjMjQ0Nic7XG4gICAgICBjb25zdCBiYWNrdXBLZXkgPVxuICAgICAgICAnMDIzNGViMzliMjJmZWQ1MjNlY2U3Yzc4ZGEyOWJhMWYxZGU1YjY0YTZlNDgwMTNlMDkxNGRlNzkzYmMxZGYwNTcwZTc3OWRlMDQ3NTg3MzI3MzRkOTdlNTRiNzgyYzhiMzM2MjgzODExYWY2YTJjNTdiZDgxNDM4Nzk4ZTFjMjQ0Nic7XG5cbiAgICAgIHJlY292ZXJ5UGFyYW1zID0ge1xuICAgICAgICB1c2VyS2V5OiB1c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6IGJhY2t1cEtleSxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnMHhlNzQwNmRjNDNkMTNmNjk4ZmI0MWEzNDVjNzc4M2QzOWE0YzJkMTkxJyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogJzB4YWMwNWRhNzg0NjQ1MjBhYTdjOWQ0YzE5YmQ3YTQ0MGIxMTFiMzA1NCcsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IFRlc3RCaXRHby5WMi5URVNUX1JFQ09WRVJZX1BBU1NDT0RFLFxuICAgICAgICBpc1RzczogdHJ1ZSxcbiAgICAgICAgZ2FzUHJpY2U6ICcyMDAwMDAwMDAwMCcsXG4gICAgICAgIGdhc0xpbWl0OiAnNTAwMDAwJyxcbiAgICAgICAgcmVwbGF5UHJvdGVjdGlvbk9wdGlvbnM6IHtcbiAgICAgICAgICBjaGFpbjogNDIsXG4gICAgICAgICAgaGFyZGZvcms6ICdsb25kb24nLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHJlY292ZXJ5UGFyYW1zKTtcbiAgICAgIHNob3VsZC5leGlzdCh0cmFuc2FjdGlvbik7XG4gICAgICBjb25zdCBvdXRwdXQgPSB0cmFuc2FjdGlvbiBhcyB1bmtub3duIGFzIFVuc2lnbmVkU3dlZXBUeE1QQ3YyO1xuICAgICAgb3V0cHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eFJlcXVlc3RzJyk7XG4gICAgICBvdXRwdXQudHhSZXF1ZXN0cy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHJhbnNhY3Rpb25zJyk7XG4gICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldENvaW4nKTtcbiAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndW5zaWduZWRUeCcpO1xuICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NlcmlhbGl6ZWRUeEhleCcpO1xuICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NpZ25hYmxlSGV4Jyk7XG4gICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZGVyaXZhdGlvblBhdGgnKTtcbiAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdmZWVJbmZvJyk7XG4gICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncGFyc2VkVHgnKTtcbiAgICAgIGNvbnN0IHBhcnNlZFR4ID0gb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHggYXMgeyBzcGVuZEFtb3VudDogc3RyaW5nIH07XG4gICAgICBwYXJzZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc3BlbmRBbW91bnQnKTtcbiAgICAgIChvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeCBhcyB7IG91dHB1dHM6IGFueVtdIH0pLnNob3VsZC5oYXZlLnByb3BlcnR5KCdvdXRwdXRzJyk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=Выполнить команду
Для локальной разработки. Не используйте в интернете!