PHP WebShell

Текущая директория: /opt/BitGoJS/modules/bitgo/dist/test/v2/unit

Просмотр файла: wallet.js

"use strict";
//
// Tests for Wallet
//
Object.defineProperty(exports, "__esModule", { value: true });
const should = require("should");
const sinon = require("sinon");
require("../lib/asserts");
const nock = require("nock");
const _ = require("lodash");
const sdk_core_1 = require("@bitgo/sdk-core");
const sdk_test_1 = require("@bitgo/sdk-test");
const src_1 = require("../../../src");
const utxoLib = require("@bitgo/utxo-lib");
const crypto_1 = require("crypto");
const util_1 = require("./coins/utxo/util");
const sdk_coin_sol_1 = require("@bitgo/sdk-coin-sol");
const sdk_coin_eth_1 = require("@bitgo/sdk-coin-eth");
const nftResponses_1 = require("../fixtures/nfts/nftResponses");
require('should-sinon');
nock.disableNetConnect();
describe('V2 Wallet:', function () {
    const reqId = new sdk_core_1.RequestTracer();
    const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'test' });
    bitgo.initializeTestVars();
    const basecoin = bitgo.coin('tbtc');
    const walletData = {
        id: '5b34252f1bf349930e34020a00000000',
        coin: 'tbtc',
        keys: ['5b3424f91bf349930e34017500000000', '5b3424f91bf349930e34017600000000', '5b3424f91bf349930e34017700000000'],
        coinSpecific: {},
        multisigType: 'onchain',
        type: 'hot',
    };
    const coldWalletData = {
        id: '65774419fb4d9690847fbe4b00000000',
        coin: 'tbtc',
        keys: ['65774412e54b7516393c9df800000000', '6577442428664ffe791af7ea00000000', '6577442b7317a945756c2fd900000000'],
        coinSpecific: {},
        multisigType: 'onchain',
        type: 'cold',
    };
    const wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
    const coldWallet = new sdk_core_1.Wallet(bitgo, basecoin, coldWalletData);
    const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
    const address1 = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
    const address2 = '0x7e85bdc27c050e3905ebf4b8e634d9ad6edd0de6';
    const tbtcHotWalletDefaultParams = {
        txFormat: 'psbt',
        changeAddressType: ['p2trMusig2', 'p2wsh', 'p2shP2wsh', 'p2sh', 'p2tr'],
    };
    afterEach(function () {
        sinon.restore();
        sinon.reset();
    });
    describe('Wallet transfers', function () {
        it('should search in wallet for a transfer', async function () {
            const params = { limit: 1, searchLabel: 'test' };
            const scope = nock(bgUrl)
                .get(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/transfer`)
                .query(params)
                .reply(200, {
                coin: 'tbch',
                transfers: [
                    {
                        wallet: wallet.id(),
                        comment: 'tests',
                    },
                ],
            });
            try {
                await wallet.transfers(params);
            }
            catch (e) {
                // test is successful if nock is consumed, HMAC errors expected
            }
            scope.isDone().should.be.True();
        });
        it('should forward all valid parameters', async function () {
            const params = {
                limit: 1,
                address: ['address1', 'address2'],
                dateGte: 'dateString0',
                dateLt: 'dateString1',
                valueGte: 0,
                valueLt: 300000000,
                allTokens: true,
                searchLabel: 'abc',
                includeHex: true,
                type: 'transfer_type',
                state: 'transfer_state',
            };
            // The actual api request will only send strings, but the SDK function expects numbers for some values
            const apiParams = _.mapValues(params, (param) => (Array.isArray(param) ? param : String(param)));
            const scope = nock(bgUrl)
                .get(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/transfer`)
                .query(_.matches(apiParams))
                .reply(200);
            await wallet.transfers(params);
            scope.isDone().should.be.True();
        });
        it('should accept a string argument for address', async function () {
            const params = {
                limit: 1,
                address: 'stringAddress',
            };
            const apiParams = {
                limit: '1',
                address: 'stringAddress',
            };
            const scope = nock(bgUrl)
                .get(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/transfer`)
                .query(_.matches(apiParams))
                .reply(200);
            try {
                await wallet.transfers(params);
            }
            catch (e) {
                // test is successful if nock is consumed, HMAC errors expected
            }
            scope.isDone().should.be.True();
        });
        it('should throw errors for invalid expected parameters', async function () {
            await wallet
                // @ts-expect-error checking type mismatch
                .transfers({ address: 13375 })
                .should.be.rejectedWith('invalid address argument, expecting string or array');
            await wallet
                // @ts-expect-error checking type mismatch
                .transfers({ address: [null] })
                .should.be.rejectedWith('invalid address argument, expecting array of address strings');
            await wallet
                // @ts-expect-error checking type mismatch
                .transfers({ dateGte: 20101904 })
                .should.be.rejectedWith('invalid dateGte argument, expecting string');
            // @ts-expect-error checking type mismatch
            await wallet.transfers({ dateLt: 20101904 }).should.be.rejectedWith('invalid dateLt argument, expecting string');
            await wallet
                // @ts-expect-error checking type mismatch
                .transfers({ valueGte: '10230005' })
                .should.be.rejectedWith('invalid valueGte argument, expecting number');
            // @ts-expect-error checking type mismatch
            await wallet.transfers({ valueLt: '-5e8' }).should.be.rejectedWith('invalid valueLt argument, expecting number');
            await wallet
                // @ts-expect-error checking type mismatch
                .transfers({ includeHex: '123' })
                .should.be.rejectedWith('invalid includeHex argument, expecting boolean');
            await wallet
                // @ts-expect-error checking type mismatch
                .transfers({ state: 123 })
                .should.be.rejectedWith('invalid state argument, expecting string or array');
            await wallet
                // @ts-expect-error checking type mismatch
                .transfers({ state: [123, 456] })
                .should.be.rejectedWith('invalid state argument, expecting array of state strings');
            // @ts-expect-error checking type mismatch
            await wallet.transfers({ type: 123 }).should.be.rejectedWith('invalid type argument, expecting string');
        });
    });
    describe('Wallet addresses', function () {
        it('should search in wallet addresses', async function () {
            const params = { limit: 1, labelContains: 'test' };
            const scope = nock(bgUrl)
                .get(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/addresses`)
                .query(params)
                .reply(200, {
                coin: 'tbch',
                transfers: [
                    {
                        wallet: wallet.id(),
                        comment: 'tests',
                    },
                ],
            });
            try {
                await wallet.addresses(params);
            }
            catch (e) {
                // test is successful if nock is consumed, HMAC errors expected
            }
            scope.isDone().should.be.True();
        });
    });
    it('should verify bch cashaddr format as valid', async function () {
        const coin = bitgo.coin('tbch');
        const valid = coin.isValidAddress('bchtest:pzfkxv532t0q5zchck2mhmmf2y02cdejyssq5qrz7a');
        valid.should.be.True();
    });
    it('should verify bch legacy format as valid', async function () {
        const coin = bitgo.coin('tbch');
        const valid = coin.isValidAddress('2N6gY9r9iuXQQzZiSyngWJeoUuL5mC1x4Ac');
        valid.should.be.True();
    });
    describe('TETH Wallet Addresses', function () {
        let ethWallet;
        before(async function () {
            const walletData = {
                id: '598f606cd8fc24710d2ebadb1d9459bb',
                coin: 'teth',
                keys: [
                    '598f606cd8fc24710d2ebad89dce86c2',
                    '598f606cc8e43aef09fcb785221d9dd2',
                    '5935d59cf660764331bafcade1855fd7',
                ],
            };
            ethWallet = new sdk_core_1.Wallet(bitgo, bitgo.coin('teth'), walletData);
        });
        it('search list addresses should return success', async function () {
            const params = {
                includeBalances: true,
                includeTokens: true,
                returnBalancesForToken: 'gterc6dp',
                pendingDeployment: false,
                includeTotalAddressCount: true,
            };
            const scope = nock(bgUrl)
                .get(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/addresses`)
                .query(params)
                .reply(200);
            try {
                await wallet.addresses(params);
                throw '';
            }
            catch (error) {
                // test is successful if nock is consumed, HMAC errors expected
            }
            scope.isDone().should.be.True();
        });
        it('should throw errors for invalid expected parameters', async function () {
            await ethWallet
                .addresses({ includeBalances: true, returnBalancesForToken: 1 })
                .should.be.rejectedWith('invalid returnBalancesForToken argument, expecting string');
            await ethWallet
                .addresses({ pendingDeployment: 1 })
                .should.be.rejectedWith('invalid pendingDeployment argument, expecting boolean');
            await ethWallet
                .addresses({ includeBalances: 1 })
                .should.be.rejectedWith('invalid includeBalances argument, expecting boolean');
            await ethWallet
                .addresses({ includeTokens: 1 })
                .should.be.rejectedWith('invalid includeTokens argument, expecting boolean');
            await ethWallet
                .addresses({ includeTotalAddressCount: 1 })
                .should.be.rejectedWith('invalid includeTotalAddressCount argument, expecting boolean');
        });
        it('get forwarder balance', async function () {
            const forwarders = [
                {
                    address: '0xbfbcc0fe2b865de877134246af09378e9bc3c91d',
                    balance: '200000',
                },
                {
                    address: '0xe59524ed8b47165f4cb0850c9428069a6002e5eb',
                    balance: '10000000000000000',
                },
            ];
            nock(bgUrl).get(`/api/v2/${ethWallet.coin()}/wallet/${ethWallet.id()}/forwarders/balances`).reply(200, {
                forwarders,
            });
            const forwarderBalance = await ethWallet.getForwarderBalance();
            forwarderBalance.forwarders[0].address.should.eql(forwarders[0].address);
            forwarderBalance.forwarders[0].balance.should.eql(forwarders[0].balance);
            forwarderBalance.forwarders[1].address.should.eql(forwarders[1].address);
            forwarderBalance.forwarders[1].balance.should.eql(forwarders[1].balance);
        });
    });
    describe('Get User Prv', () => {
        const prv = 'xprv9s21ZrQH143K3hekyNj7TciR4XNYe1kMj68W2ipjJGNHETWP7o42AjDnSPgKhdZ4x8NBAvaL72RrXjuXNdmkMqLERZza73oYugGtbLFXG8g';
        const derivedPrv = 'xprv9yoG67Td11uwjXwbV8zEmrySVXERu5FZAsLD9suBeEJbgJqANs8Yng5dEJoii7hag5JermK6PbfxgDmSzW7ewWeLmeJEkmPfmZUSLdETtHx';
        it('should use the cold derivation seed to derive the proper user private key', async () => {
            const userPrvOptions = {
                prv,
                coldDerivationSeed: '123',
            };
            wallet.getUserPrv(userPrvOptions).should.eql(derivedPrv);
        });
        it('should use the user keychain derivedFromParentWithSeed as the cold derivation seed if none is provided', async () => {
            const userPrvOptions = {
                prv,
                keychain: {
                    derivedFromParentWithSeed: '123',
                    id: '456',
                    pub: '789',
                    type: 'independent',
                },
            };
            wallet.getUserPrv(userPrvOptions).should.eql(derivedPrv);
        });
        it('should prefer the explicit cold derivation seed to the user keychain derivedFromParentWithSeed', async () => {
            const userPrvOptions = {
                prv,
                coldDerivationSeed: '123',
                keychain: {
                    derivedFromParentWithSeed: '456',
                    id: '789',
                    pub: '012',
                    type: 'independent',
                },
            };
            wallet.getUserPrv(userPrvOptions).should.eql(derivedPrv);
        });
        it('should return the prv provided for TSS SMC', async () => {
            const tssWalletData = {
                id: '5b34252f1bf349930e34020a00000000',
                coin: 'tsol',
                keys: [
                    '5b3424f91bf349930e34017500000000',
                    '5b3424f91bf349930e34017600000000',
                    '5b3424f91bf349930e34017700000000',
                ],
                coinSpecific: {},
                multisigType: 'tss',
            };
            const tsolcoin = bitgo.coin('tsol');
            const wallet = new sdk_core_1.Wallet(bitgo, tsolcoin, tssWalletData);
            const prv = 'longstringifiedjson';
            const keychain = {
                derivedFromParentWithSeed: 'random seed',
                id: '123',
                commonKeychain: 'longstring',
                type: 'tss',
            };
            const userPrvOptions = {
                prv,
                keychain,
            };
            wallet.getUserPrv(userPrvOptions).should.eql(prv);
        });
    });
    describe('UTXO Custom Signer Function', function () {
        const recipients = [
            { address: 'abc', amount: 123 },
            { address: 'def', amount: 456 },
        ];
        const rootWalletKey = (0, util_1.getDefaultWalletKeys)();
        let customSigningFunction;
        let stubs;
        beforeEach(function () {
            customSigningFunction = sinon.stub().returns({
                txHex: 'this-is-a-tx',
            });
            stubs = [
                sinon.stub(wallet.baseCoin, 'postProcessPrebuild').returnsArg(0),
                sinon.stub(wallet.baseCoin, 'verifyTransaction').resolves(true),
                sinon.stub(wallet.baseCoin, 'signTransaction').resolves({ txHex: 'this-is-a-tx' }),
            ];
        });
        function nocks(txPrebuild) {
            return nock(bgUrl)
                .post(wallet.url('/tx/build').replace(bgUrl, ''))
                .reply(200, txPrebuild)
                .get(wallet.baseCoin.url('/public/block/latest').replace(bgUrl, ''))
                .reply(200)
                .get(wallet.baseCoin.url(`/key/${wallet.keyIds()[0]}`).replace(bgUrl, ''))
                .reply(200, { pub: 'pub' })
                .get(wallet.baseCoin.url(`/key/${wallet.keyIds()[1]}`).replace(bgUrl, ''))
                .reply(200, { pub: 'pub' })
                .get(wallet.baseCoin.url(`/key/${wallet.keyIds()[2]}`).replace(bgUrl, ''))
                .reply(200, { pub: 'pub' })
                .post(wallet.url('/tx/send').replace(bgUrl, ''))
                .reply(200, { ok: true });
        }
        it('should use a custom signing function if provided for PSBT with taprootKeyPathSpend input', async function () {
            const psbt = utxoLib.testutil.constructPsbt([{ scriptType: 'taprootKeyPathSpend', value: BigInt(1000) }], [{ scriptType: 'p2sh', value: BigInt(900) }], basecoin.network, rootWalletKey, 'unsigned');
            const scope = nocks({ txHex: psbt.toHex() });
            const result = await wallet.sendMany({ recipients, customSigningFunction });
            result.should.have.property('ok', true);
            customSigningFunction.should.have.been.calledTwice();
            scope.done();
            stubs.forEach((s) => s.restore());
        });
        it('should use a custom signing function if provided for PSBT without taprootKeyPathSpend input', async function () {
            const psbt = utxoLib.testutil.constructPsbt([{ scriptType: 'p2wsh', value: BigInt(1000) }], [{ scriptType: 'p2sh', value: BigInt(900) }], basecoin.network, rootWalletKey, 'unsigned');
            const scope = nocks({ txHex: psbt.toHex() });
            const result = await wallet.sendMany({ recipients, customSigningFunction });
            result.should.have.property('ok', true);
            customSigningFunction.should.have.been.calledOnce();
            scope.done();
            stubs.forEach((s) => s.restore());
        });
        it('should use a custom signing function if provided for Tx without taprootKeyPathSpend input', async function () {
            const tx = utxoLib.testutil.constructTxnBuilder([{ scriptType: 'p2wsh', value: BigInt(1000) }], [{ scriptType: 'p2sh', value: BigInt(900) }], basecoin.network, rootWalletKey, 'unsigned');
            const scope = nocks({ txHex: tx.buildIncomplete().toHex() });
            const result = await wallet.sendMany({ recipients, customSigningFunction });
            result.should.have.property('ok', true);
            customSigningFunction.should.have.been.calledOnce();
            scope.done();
            stubs.forEach((s) => s.restore());
        });
    });
    describe('TETH Wallet Transactions', function () {
        let ethWallet;
        before(async function () {
            const walletData = {
                id: '598f606cd8fc24710d2ebadb1d9459bb',
                coin: 'teth',
                keys: [
                    '598f606cd8fc24710d2ebad89dce86c2',
                    '598f606cc8e43aef09fcb785221d9dd2',
                    '5935d59cf660764331bafcade1855fd7',
                ],
                multisigType: 'onchain',
            };
            ethWallet = new sdk_core_1.Wallet(bitgo, bitgo.coin('teth'), walletData);
        });
        afterEach(async function () {
            nock.cleanAll();
        });
        it('should error eip1559 and gasPrice are passed', async function () {
            const params = {
                gasPrice: 100,
                eip1559: {
                    maxPriorityFeePerGas: 10,
                    maxFeePerGas: 10,
                },
                amount: 10,
                address: sdk_test_1.TestBitGo.V2.TEST_WALLET1_ADDRESS,
                walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_WALLET1_PASSCODE,
            };
            await ethWallet.send(params).should.be.rejected();
        });
        it('should search for pending transaction correctly', async function () {
            const params = { walletId: wallet.id() };
            const scope = nock(bgUrl).get(`/api/v2/${wallet.coin()}/tx/pending/first`).query(params).reply(200);
            try {
                await wallet.getFirstPendingTransaction();
                throw '';
            }
            catch (error) {
                // test is successful if nock is consumed, HMAC errors expected
            }
            scope.isDone().should.be.True();
        });
        it('should try to change the fee correctly', async function () {
            const params = { txid: '0xffffffff', fee: '10000000' };
            const scope = nock(bgUrl).post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/changeFee`, params).reply(200);
            try {
                await wallet.changeFee({ txid: '0xffffffff', fee: '10000000' });
                throw '';
            }
            catch (error) {
                // test is successful if nock is consumed, HMAC errors expected
            }
            scope.isDone().should.be.True();
        });
        it('should try to change the fee correctly using eip1559', async function () {
            const params = {
                txid: '0xffffffff',
                eip1559: {
                    maxPriorityFeePerGas: '1000000000',
                    maxFeePerGas: '25000000000',
                },
            };
            const scope = nock(bgUrl).post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/changeFee`, params).reply(200);
            try {
                await wallet.changeFee(params);
                throw '';
            }
            catch (error) {
                // test is successful if nock is consumed, HMAC errors expected
            }
            scope.isDone().should.be.True();
        });
        it('should pass data parameter and amount: 0 when using sendTransaction', async function () {
            const path = `/api/v2/${ethWallet.coin()}/wallet/${ethWallet.id()}/tx/build`;
            const recipientAddress = '0x7db562c4dd465cc895761c56f83b6af0e32689ba';
            const recipients = [
                {
                    address: recipientAddress,
                    amount: 0,
                    data: '0x00110011',
                },
            ];
            const response = nock(bgUrl)
                .post(path, _.matches({ recipients })) // use _.matches to do a partial match on request body object instead of strict matching
                .reply(200);
            const nockKeyChain = nock(bgUrl).get(`/api/v2/${ethWallet.coin()}/key/${ethWallet.keyIds()[0]}`).reply(200, {});
            try {
                await ethWallet.send({
                    address: recipients[0].address,
                    data: recipients[0].data,
                    amount: recipients[0].amount,
                });
            }
            catch (e) {
                // test is successful if nock is consumed, HMAC errors expected
            }
            response.isDone().should.be.true();
            nockKeyChain.isDone().should.be.true();
        });
        it('should pass data parameter and amount: 0 when using sendMany', async function () {
            const path = `/api/v2/${ethWallet.coin()}/wallet/${ethWallet.id()}/tx/build`;
            const recipientAddress = '0x7db562c4dd465cc895761c56f83b6af0e32689ba';
            const recipients = [
                {
                    address: recipientAddress,
                    amount: 0,
                    data: '0x00110011',
                },
            ];
            const response = nock(bgUrl)
                .post(path, _.matches({ recipients })) // use _.matches to do a partial match on request body object instead of strict matching
                .reply(200);
            const nockKeyChain = nock(bgUrl).get(`/api/v2/${ethWallet.coin()}/key/${ethWallet.keyIds()[0]}`).reply(200, {});
            try {
                await ethWallet.sendMany({ recipients });
            }
            catch (e) {
                // test is successful if nock is consumed, HMAC errors expected
            }
            response.isDone().should.be.true();
            nockKeyChain.isDone().should.be.true();
        });
        it('should not pass recipients in sendMany when transaction type is fillNonce', async function () {
            const recipientAddress = '0x7db562c4dd465cc895761c56f83b6af0e32689ba';
            const recipients = [
                {
                    address: recipientAddress,
                    amount: 0,
                },
            ];
            const sendManyParams = { recipients, type: 'fillNonce', isTss: true, nonce: '13' };
            try {
                await ethWallet.sendMany(sendManyParams);
            }
            catch (e) {
                e.message.should.equal('cannot provide recipients for transaction type fillNonce');
                // test is successful if nock is consumed, HMAC errors expected
            }
        });
        it('should not pass receiveAddress in sendMany when TSS transaction type is transfer or transferToken', async function () {
            const recipientAddress = '0x7db562c4dd465cc895761c56f83b6af0e32689ba';
            const recipients = [
                {
                    address: recipientAddress,
                    amount: 0,
                },
            ];
            const errorMessage = 'cannot use receive address for TSS transactions of type transfer';
            const sendManyParamsReceiveAddressError = {
                receiveAddress: 'throw',
                recipients,
                type: 'transfer',
                isTss: true,
                nonce: '13',
            };
            const sendManyParams = { recipients, type: 'transfer', isTss: true, nonce: '13' };
            try {
                await ethWallet.sendMany(sendManyParamsReceiveAddressError);
            }
            catch (e) {
                e.message.should.equal(errorMessage);
            }
            try {
                await ethWallet.sendMany(sendManyParams);
            }
            catch (e) {
                e.message.should.not.equal(errorMessage);
            }
        });
        it('should throw error early if password is wrong', async function () {
            const recipientAddress = '0x7db562c4dd465cc895761c56f83b6af0e32689ba';
            const recipients = [
                {
                    address: recipientAddress,
                    amount: 0,
                },
            ];
            const errorMessage = `unable to decrypt keychain with the given wallet passphrase`;
            const sendManyParamsCorrectPassPhrase = {
                recipients,
                type: 'transfer',
                isTss: true,
                nonce: '13',
                walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_PASSPHRASE,
            };
            const nockKeychain = nock(bgUrl)
                .get(`/api/v2/${ethWallet.coin()}/key/${ethWallet.keyIds()[0]}`)
                .times(2)
                .reply(200, {
                id: '598f606cd8fc24710d2ebad89dce86c2',
                pub: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
                ethAddress: '0x26a163ba9739529720c0914c583865dec0d37278',
                source: 'user',
                encryptedPrv: '{"iv":"15FsbDVI1zG9OggD8YX+Hg==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"hHbNH3Sz/aU=","ct":"WoNVKz7afiRxXI2w/YkzMdMyoQg/B15u1Q8aQgi96jJZ9wk6TIaSEc6bXFH3AHzD9MdJCWJQUpRhoQc/rgytcn69scPTjKeeyVMElGCxZdFVS/psQcNE+lue3//2Zlxj+6t1NkvYO+8yAezSMRBK5OdftXEjNQI="}',
                coinSpecific: {},
            });
            await ethWallet
                .sendMany({ ...sendManyParamsCorrectPassPhrase, walletPassphrase: 'wrongPassphrase' })
                .should.be.rejectedWith(errorMessage);
            try {
                const customSigningFunction = () => {
                    return 'mock';
                };
                // Should not validate passphrase if custom signing function is provided
                await ethWallet.sendMany({
                    ...sendManyParamsCorrectPassPhrase,
                    walletPassphrase: 'wrongPassphrase',
                    customSigningFunction,
                });
            }
            catch (e) {
                e.message.should.not.equal(errorMessage);
            }
            try {
                await ethWallet.sendMany({ ...sendManyParamsCorrectPassPhrase });
            }
            catch (e) {
                e.message.should.not.equal(errorMessage);
            }
            nockKeychain.isDone().should.be.true();
        });
    });
    describe('OFC Create Address', () => {
        let ofcWallet;
        let nocks;
        before(async function () {
            const walletDataOfc = {
                id: '5b34252f1bf349930e3400b00000000',
                coin: 'ofc',
                keys: [
                    '5b3424f91bf349930e34017800000000',
                    '5b3424f91bf349930e34017900000000',
                    '5b3424f91bf349930e34018000000000',
                ],
                coinSpecific: {},
                multisigType: 'onchain',
            };
            ofcWallet = new sdk_core_1.Wallet(bitgo, bitgo.coin('ofc'), walletDataOfc);
        });
        beforeEach(async function () {
            nocks = [
                nock(bgUrl).get(`/api/v2/ofc/key/${ofcWallet.keyIds()[0]}`).reply(200, {
                    id: ofcWallet.keyIds()[0],
                    pub: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
                    source: 'user',
                    encryptedPrv: '{"iv":"15FsbDVI1zG9OggD8YX+Hg==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"hHbNH3Sz/aU=","ct":"WoNVKz7afiRxXI2w/YkzMdMyoQg/B15u1Q8aQgi96jJZ9wk6TIaSEc6bXFH3AHzD9MdJCWJQUpRhoQc/rgytcn69scPTjKeeyVMElGCxZdFVS/psQcNE+lue3//2Zlxj+6t1NkvYO+8yAezSMRBK5OdftXEjNQI="}',
                    coinSpecific: {},
                }),
                nock(bgUrl).get(`/api/v2/ofc/key/${ofcWallet.keyIds()[1]}`).reply(200, {
                    id: ofcWallet.keyIds()[1],
                    pub: 'xpub661MyMwAqRbcGhSaXikpuTC9KU88Xx9LrjKSw1JKsvXNgabpTdgjy7LSovh9ZHhcqhAHQu7uthu7FguNGdcC4aXTKK5gqTcPe4WvLYRbCSG',
                    source: 'backup',
                    coinSpecific: {},
                }),
                nock(bgUrl).get(`/api/v2/ofc/key/${ofcWallet.keyIds()[2]}`).reply(200, {
                    id: ofcWallet.keyIds()[2],
                    pub: 'xpub661MyMwAqRbcFsXShW8R3hJsHNTYTUwzcejnLkY7KCtaJbDqcGkcBF99BrEJSjNZHeHveiYUrsAdwnjUMGwpgmEbiKcZWRuVA9HxnRaA3r3',
                    source: 'bitgo',
                    coinSpecific: {},
                }),
            ];
        });
        afterEach(async function () {
            nock.cleanAll();
            nocks.forEach((scope) => scope.isDone().should.be.true());
        });
        it('should correctly validate arguments to create address on OFC wallet', async function () {
            await ofcWallet.createAddress().should.be.rejectedWith('onToken is a mandatory parameter for OFC wallets');
            // @ts-expect-error test passing invalid number argument
            await ofcWallet.createAddress({ onToken: 42 }).should.be.rejectedWith('onToken has to be a string');
        });
        it('address creation with valid onToken argument succeeds', async function () {
            const scope = nock(bgUrl)
                .post(`/api/v2/ofc/wallet/${ofcWallet.id()}/address`, { onToken: 'ofctbtc' })
                .reply(200, {
                id: '638a48c6c3dba40007a3497fa49a080c',
                address: 'generated address',
                chain: 0,
                index: 1,
                coin: 'tbtc',
                wallet: ofcWallet.id,
            });
            const address = await ofcWallet.createAddress({ onToken: 'ofctbtc' });
            address.address.should.equal('generated address');
            scope.isDone().should.be.true();
        });
    });
    describe('TETH Create Address', () => {
        let ethWallet, nocks;
        const walletData = {
            id: '598f606cd8fc24710d2ebadb1d9459bb',
            coinSpecific: {
                baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
            },
            coin: 'teth',
            keys: [
                '598f606cd8fc24710d2ebad89dce86c2',
                '598f606cc8e43aef09fcb785221d9dd2',
                '5935d59cf660764331bafcade1855fd7',
            ],
        };
        beforeEach(async function () {
            ethWallet = new sdk_core_1.Wallet(bitgo, bitgo.coin('teth'), walletData);
            nocks = [
                nock(bgUrl).get(`/api/v2/${ethWallet.coin()}/key/${ethWallet.keyIds()[0]}`).reply(200, {
                    id: '598f606cd8fc24710d2ebad89dce86c2',
                    pub: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
                    ethAddress: '0x26a163ba9739529720c0914c583865dec0d37278',
                    source: 'user',
                    encryptedPrv: '{"iv":"15FsbDVI1zG9OggD8YX+Hg==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"hHbNH3Sz/aU=","ct":"WoNVKz7afiRxXI2w/YkzMdMyoQg/B15u1Q8aQgi96jJZ9wk6TIaSEc6bXFH3AHzD9MdJCWJQUpRhoQc/rgytcn69scPTjKeeyVMElGCxZdFVS/psQcNE+lue3//2Zlxj+6t1NkvYO+8yAezSMRBK5OdftXEjNQI="}',
                    coinSpecific: {},
                }),
                nock(bgUrl).get(`/api/v2/${ethWallet.coin()}/key/${ethWallet.keyIds()[1]}`).reply(200, {
                    id: '598f606cc8e43aef09fcb785221d9dd2',
                    pub: 'xpub661MyMwAqRbcGhSaXikpuTC9KU88Xx9LrjKSw1JKsvXNgabpTdgjy7LSovh9ZHhcqhAHQu7uthu7FguNGdcC4aXTKK5gqTcPe4WvLYRbCSG',
                    ethAddress: '0xa1a88a502274073b1bc4fe06ea0f5fe77e151b91',
                    source: 'backup',
                    coinSpecific: {},
                }),
                nock(bgUrl).get(`/api/v2/${ethWallet.coin()}/key/${ethWallet.keyIds()[2]}`).reply(200, {
                    id: '5935d59cf660764331bafcade1855fd7',
                    pub: 'xpub661MyMwAqRbcFsXShW8R3hJsHNTYTUwzcejnLkY7KCtaJbDqcGkcBF99BrEJSjNZHeHveiYUrsAdwnjUMGwpgmEbiKcZWRuVA9HxnRaA3r3',
                    ethAddress: '0x032821b7ea40ea5d446f47c29a0f777ee035aa10',
                    source: 'bitgo',
                    coinSpecific: {},
                }),
            ];
        });
        afterEach(async function () {
            nock.cleanAll();
            nocks.forEach((scope) => scope.isDone().should.be.true());
        });
        it('should correctly validate arguments to create address', async function () {
            let message = 'gasPrice has to be an integer or numeric string';
            // @ts-expect-error checking type mismatch
            await wallet.createAddress({ gasPrice: {} }).should.be.rejectedWith(message);
            await wallet.createAddress({ gasPrice: 'abc' }).should.be.rejectedWith(message);
            // @ts-expect-error checking type mismatch
            await wallet.createAddress({ gasPrice: null }).should.be.rejectedWith(message);
            message = 'chain has to be an integer';
            // @ts-expect-error checking type mismatch
            await wallet.createAddress({ chain: {} }).should.be.rejectedWith(message);
            // @ts-expect-error checking type mismatch
            await wallet.createAddress({ chain: 'abc' }).should.be.rejectedWith(message);
            // @ts-expect-error checking type mismatch
            await wallet.createAddress({ chain: null }).should.be.rejectedWith(message);
            message = 'count has to be a number between 1 and 250';
            // @ts-expect-error checking type mismatch
            await wallet.createAddress({ count: {} }).should.be.rejectedWith(message);
            // @ts-expect-error checking type mismatch
            await wallet.createAddress({ count: 'abc' }).should.be.rejectedWith(message);
            // @ts-expect-error checking type mismatch
            await wallet.createAddress({ count: null }).should.be.rejectedWith(message);
            await wallet.createAddress({ count: -1 }).should.be.rejectedWith(message);
            await wallet.createAddress({ count: 0 }).should.be.rejectedWith(message);
            await wallet.createAddress({ count: 251 }).should.be.rejectedWith(message);
            message = 'baseAddress has to be a string';
            // @ts-expect-error checking type mismatch
            await wallet.createAddress({ baseAddress: {} }).should.be.rejectedWith(message);
            // @ts-expect-error checking type mismatch
            await wallet.createAddress({ baseAddress: 123 }).should.be.rejectedWith(message);
            // @ts-expect-error checking type mismatch
            await wallet.createAddress({ baseAddress: null }).should.be.rejectedWith(message);
            message = 'allowSkipVerifyAddress has to be a boolean';
            // @ts-expect-error checking type mismatch
            await wallet.createAddress({ allowSkipVerifyAddress: {} }).should.be.rejectedWith(message);
            // @ts-expect-error checking type mismatch
            await wallet.createAddress({ allowSkipVerifyAddress: 123 }).should.be.rejectedWith(message);
            // @ts-expect-error checking type mismatch
            await wallet.createAddress({ allowSkipVerifyAddress: 'abc' }).should.be.rejectedWith(message);
            // @ts-expect-error checking type mismatch
            await wallet.createAddress({ allowSkipVerifyAddress: null }).should.be.rejectedWith(message);
            message = 'forwarderVersion has to be an integer 0, 1, 2, 3 or 4';
            await wallet.createAddress({ forwarderVersion: 5 }).should.be.rejectedWith(message);
            await wallet.createAddress({ forwarderVersion: -1 }).should.be.rejectedWith(message);
        });
        it('address creation with forwarder version 3 succeeds', async function () {
            const scope = nock(bgUrl)
                .post(`/api/v2/${ethWallet.coin()}/wallet/${ethWallet.id()}/address`, { chain: 0, forwarderVersion: 3 })
                .reply(200, {
                id: '638a48c6c3dba40007a3497fa49a080c',
                address: '0x5e61b64f38f1b5f85078fb84b27394830b4c8e80',
                chain: 0,
                index: 1,
                coin: 'tpolygon',
                lastNonce: 0,
                wallet: '63785f95af7c760007cfae068c2f31ae',
                coinSpecific: {
                    nonce: -1,
                    updateTime: '2022-12-02T18:49:42.348Z',
                    txCount: 0,
                    pendingChainInitialization: false,
                    creationFailure: [],
                    salt: '0x1',
                    pendingDeployment: true,
                    forwarderVersion: 3,
                    isTss: true,
                },
            });
            const address = await ethWallet.createAddress({ chain: 0, forwarderVersion: 3 });
            address.coinSpecific.forwarderVersion.should.equal(3);
            scope.isDone().should.be.true();
        });
        it('address creation with forwarder version 3 fails due invalid address', async function () {
            const address = '0x5e61b6'; // invalid address
            nock(bgUrl)
                .post(`/api/v2/${ethWallet.coin()}/wallet/${ethWallet.id()}/address`, { chain: 0, forwarderVersion: 3 })
                .reply(200, {
                id: '638a48c6c3dba40007a3497fa49a080c',
                address: address,
                chain: 0,
                index: 1,
                coin: 'tpolygon',
                lastNonce: 0,
                wallet: '63785f95af7c760007cfae068c2f31ae',
                coinSpecific: {
                    nonce: -1,
                    updateTime: '2022-12-02T18:49:42.348Z',
                    txCount: 0,
                    pendingChainInitialization: false,
                    creationFailure: [],
                    salt: '0x1',
                    pendingDeployment: true,
                    forwarderVersion: 3,
                    isTss: true,
                },
            });
            await ethWallet
                .createAddress({ chain: 0, forwarderVersion: 3 })
                .should.be.rejectedWith(`invalid address: ${address}`);
        });
        it('address creation with forwarder version 2 succeeds', async function () {
            const scope = nock(bgUrl)
                .post(`/api/v2/${ethWallet.coin()}/wallet/${ethWallet.id()}/address`, { chain: 0, forwarderVersion: 2 })
                .reply(200, {
                id: '638a48c6c3dba40007a3497fa49a080c',
                address: '0x5e61b64f38f1b5f85078fb84b27394830b4c8e80',
                chain: 0,
                index: 1,
                coin: 'tpolygon',
                lastNonce: 0,
                wallet: '63785f95af7c760007cfae068c2f31ae',
                coinSpecific: {
                    nonce: -1,
                    updateTime: '2022-12-02T18:49:42.348Z',
                    txCount: 0,
                    pendingChainInitialization: true,
                    creationFailure: [],
                    salt: '0x1',
                    pendingDeployment: true,
                    forwarderVersion: 2,
                    isTss: true,
                },
            });
            const address = await ethWallet.createAddress({ chain: 0, forwarderVersion: 2 });
            address.coinSpecific.forwarderVersion.should.equal(2);
            scope.isDone().should.be.true();
        });
        it('verify address when pendingChainInitialization is true in case of eth v1 forwarder', async function () {
            const scope = nock(bgUrl)
                .post(`/api/v2/${ethWallet.coin()}/wallet/${ethWallet.id()}/address`, { chain: 0, forwarderVersion: 1 })
                .reply(200, {
                id: '615c643a98a2a100068e023c639c0f74',
                address: '0x8c13cd0bb198858f628d5631ba4b2293fc08df49',
                baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
                chain: 0,
                index: 3179,
                coin: 'teth',
                lastNonce: 0,
                wallet: '598f606cd8fc24710d2ebadb1d9459bb',
                coinSpecific: {
                    nonce: -1,
                    updateTime: '2021-10-05T14:42:02.399Z',
                    txCount: 0,
                    pendingChainInitialization: true,
                    creationFailure: [],
                    salt: '0xc6b',
                    pendingDeployment: true,
                    forwarderVersion: 1,
                },
            });
            await ethWallet
                .createAddress({ chain: 0, forwarderVersion: 1 })
                .should.be.rejectedWith('address validation failure: expected 0x32a226cda14e352a47bf4b1658648d8037736f80 but got 0x8c13cd0bb198858f628d5631ba4b2293fc08df49');
            scope.isDone().should.be.true();
        });
        it('verify address when invalid baseAddress is passed', async function () {
            const scope = nock(bgUrl)
                .post(`/api/v2/${ethWallet.coin()}/wallet/${ethWallet.id()}/address`, { chain: 0, forwarderVersion: 1 })
                .reply(200, {
                id: '615c643a98a2a100068e023c639c0f74',
                address: '0x32a226cda14e352a47bf4b1658648d8037736f80',
                baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
                chain: 0,
                index: 3179,
                coin: 'teth',
                lastNonce: 0,
                wallet: '598f606cd8fc24710d2ebadb1d9459bb',
                coinSpecific: {
                    nonce: -1,
                    updateTime: '2021-10-05T14:42:02.399Z',
                    txCount: 0,
                    pendingChainInitialization: true,
                    creationFailure: [],
                    salt: '0xc6b',
                    pendingDeployment: true,
                    forwarderVersion: 1,
                },
            });
            await ethWallet
                .createAddress({ chain: 0, forwarderVersion: 1, baseAddress: 'asgf' })
                .should.be.rejectedWith('invalid base address');
            scope.isDone().should.be.true();
        });
        it('verify address when incorrect baseAddress is passed', async function () {
            const scope = nock(bgUrl)
                .post(`/api/v2/${ethWallet.coin()}/wallet/${ethWallet.id()}/address`, { chain: 0, forwarderVersion: 1 })
                .reply(200, {
                id: '615c643a98a2a100068e023c639c0f74',
                address: '0x32a226cda14e352a47bf4b1658648d8037736f80',
                baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
                chain: 0,
                index: 3179,
                coin: 'teth',
                lastNonce: 0,
                wallet: '598f606cd8fc24710d2ebadb1d9459bb',
                coinSpecific: {
                    nonce: -1,
                    updateTime: '2021-10-05T14:42:02.399Z',
                    txCount: 0,
                    pendingChainInitialization: true,
                    creationFailure: [],
                    salt: '0xc6b',
                    pendingDeployment: true,
                    forwarderVersion: 1,
                },
            });
            // incorrect address is generated while validating due to incorrect baseAddress
            await ethWallet
                .createAddress({ chain: 0, forwarderVersion: 1, baseAddress: '0x8c13cd0bb198858f628d5631ba4b2293fc08df49' })
                .should.be.rejectedWith('address validation failure: expected 0x36748926007790e7ee416c6485b32e00cfb177a3 but got 0x32a226cda14e352a47bf4b1658648d8037736f80');
            scope.isDone().should.be.true();
        });
        it('verify address when pendingChainInitialization is true  and allowSkipVerifyAddress is false in case of eth v0 forwarder', async function () {
            const scope = nock(bgUrl)
                .post(`/api/v2/${ethWallet.coin()}/wallet/${ethWallet.id()}/address`, { chain: 0, forwarderVersion: 0 })
                .reply(200, {
                id: '615c643a98a2a100068e023c639c0f74',
                address: '0x32a26cda14e352a47bf4b1658648d8037736f80',
                baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
                chain: 0,
                index: 3179,
                coin: 'teth',
                lastNonce: 0,
                wallet: '598f606cd8fc24710d2ebadb1d9459bb',
                coinSpecific: {
                    nonce: -1,
                    updateTime: '2021-10-05T14:42:02.399Z',
                    txCount: 0,
                    pendingChainInitialization: true,
                    creationFailure: [],
                    salt: '0xc6b',
                    pendingDeployment: true,
                    forwarderVersion: 1,
                },
            });
            await ethWallet
                .createAddress({ chain: 0, forwarderVersion: 0, allowSkipVerifyAddress: false })
                .should.be.rejectedWith('address verification skipped for count = 1');
            scope.isDone().should.be.true();
        });
        it('verify address with allowSkipVerifyAddress set to false and eth v1 forwarder', async function () {
            const scope = nock(bgUrl)
                .post(`/api/v2/${ethWallet.coin()}/wallet/${ethWallet.id()}/address`, { chain: 0, forwarderVersion: 1 })
                .reply(200, {
                id: '615c643a98a2a100068e023c639c0f74',
                address: '0x32a226cda14e352a47bf4b1658648d8037736f80',
                baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
                chain: 0,
                index: 3179,
                coin: 'teth',
                lastNonce: 0,
                wallet: '598f606cd8fc24710d2ebadb1d9459bb',
                coinSpecific: {
                    nonce: -1,
                    updateTime: '2021-10-05T14:42:02.399Z',
                    txCount: 0,
                    pendingChainInitialization: true,
                    creationFailure: [],
                    salt: '0xc6b',
                    pendingDeployment: true,
                    forwarderVersion: 0,
                },
            });
            const newAddress = await ethWallet.createAddress({
                chain: 0,
                forwarderVersion: 1,
                allowSkipVerifyAddress: false,
            });
            newAddress.index.should.equal(3179);
            scope.isDone().should.be.true();
        });
    });
    describe('Algorand tests', () => {
        let algoWallet;
        before(async () => {
            // This is not a real TALGO wallet
            const walletData = {
                id: '650204cf43d8b40007cd9e11a872ce65',
                coin: 'talgo',
                keys: [
                    '650204b78a75c90007790bce979ae34d',
                    '650204b766c56a00072956c08fb9cdf1',
                    '650204b8ccf1370007b32bb8155dfbec',
                ],
                coinSpecific: {
                    rootAddress: '2ULRGE64U7LTMT5M6REB7ORHX5GLJYWHTIV5EAXVLWQTTATVJDGM5KJMII',
                },
            };
            algoWallet = new sdk_core_1.Wallet(bitgo, bitgo.coin('talgo'), walletData);
        });
        it('Should build token enablement transactions', async () => {
            const params = {
                enableTokens: [
                    {
                        name: 'talgo:USDt-180447',
                    },
                ],
            };
            const txRequestNock = nock(bgUrl)
                .post(`/api/v2/${algoWallet.coin()}/wallet/${algoWallet.id()}/tx/build`)
                .reply((uri, body) => {
                const params = body;
                params.recipients.length.should.equal(1);
                params.recipients[0].tokenName.should.equal('talgo:USDt-180447');
                params.type.should.equal('enabletoken');
                should.not.exist(params.enableTokens);
                return [200, params];
            });
            await algoWallet.buildTokenEnablements(params);
            txRequestNock.isDone().should.equal(true);
        });
        afterEach(() => {
            nock.cleanAll();
        });
    });
    describe('Hedera tests', () => {
        let hbarWallet;
        before(async () => {
            // This is not a real THBAR wallet
            const walletData = {
                id: '598f606cd8fc24710d2ebadb1d9459bb',
                coin: 'thbar',
                keys: [
                    '598f606cd8fc24710d2ebad89dce86c2',
                    '598f606cc8e43aef09fcb785221d9dd2',
                    '5935d59cf660764331bafcade1855fd7',
                ],
                coinSpecific: {
                    baseAddress: '0.0.47841511',
                },
            };
            hbarWallet = new sdk_core_1.Wallet(bitgo, bitgo.coin('thbar'), walletData);
        });
        it('Should build token enablement transactions', async () => {
            const params = {
                enableTokens: [
                    {
                        name: 'thbar:usdc',
                    },
                ],
            };
            const txRequestNock = nock(bgUrl)
                .post(`/api/v2/${hbarWallet.coin()}/wallet/${hbarWallet.id()}/tx/build`)
                .reply((uri, body) => {
                const params = body;
                params.recipients.length.should.equal(1);
                params.recipients[0].tokenName.should.equal('thbar:usdc');
                params.type.should.equal('enabletoken');
                should.not.exist(params.enableTokens);
                return [200, params];
            });
            await hbarWallet.buildTokenEnablements(params);
            txRequestNock.isDone().should.equal(true);
        });
        afterEach(() => {
            nock.cleanAll();
        });
    });
    describe('Solana tests: ', () => {
        let solWallet;
        const passphrase = '#Bondiola1234';
        const solBitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
        solBitgo.initializeTestVars();
        const walletData = {
            id: '598f606cd8fc24710d2ebadb1d9459bb',
            coinSpecific: {
                baseAddress: '5f8WmC2uW9SAk7LMX2r4G1Bx8MMwx8sdgpotyHGodiZo',
                pendingChainInitialization: false,
                minimumFunding: 2447136,
                lastChainIndex: { 0: 0 },
            },
            coin: 'tsol',
            keys: [
                '598f606cd8fc24710d2ebad89dce86c2',
                '598f606cc8e43aef09fcb785221d9dd2',
                '5935d59cf660764331bafcade1855fd7',
            ],
            multisigType: 'tss',
        };
        before(async function () {
            solWallet = new sdk_core_1.Wallet(bitgo, bitgo.coin('tsol'), walletData);
            nock(bgUrl).get(`/api/v2/${solWallet.coin()}/key/${solWallet.keyIds()[0]}`).times(3).reply(200, {
                id: '598f606cd8fc24710d2ebad89dce86c2',
                pub: '5f8WmC2uW9SAk7LMX2r4G1Bx8MMwx8sdgpotyHGodiZo',
                source: 'user',
                encryptedPrv: '{"iv":"hNK3rg82P1T94MaueXFAbA==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"cV4wU4EzPjs=","ct":"9VZX99Ztsb6p75Cxl2lrcXBplmssIAQ9k7ZA81vdDYG4N5dZ36BQNWVfDoelj9O31XyJ+Xri0XKIWUzl0KKLfUERplmtNoOCn5ifJcZwCrOxpHZQe3AJ700o8Wmsrk5H"}',
                coinSpecific: {},
            });
            nock(bgUrl).get(`/api/v2/${solWallet.coin()}/key/${solWallet.keyIds()[1]}`).times(2).reply(200, {
                id: '598f606cc8e43aef09fcb785221d9dd2',
                pub: 'G1s43JTzNZzqhUn4aNpwgcc6wb9FUsZQD5JjffG6isyd',
                encryptedPrv: '{"iv":"UFrt/QlIUR1XeQafPBaAlw==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"7VPBYaJXPm8=","ct":"ajFKv2y8yaIBXQ39sAbBWcnbiEEzbjS4AoQtp5cXYqjeDRxt3aCxemPm22pnkJaCijFjJrMHbkmsNhNYzHg5aHFukN+nEAVssyNwHbzlhSnm8/BVN50yAdAAtWreh8cp"}',
                source: 'backup',
                coinSpecific: {},
            });
            nock(bgUrl).get(`/api/v2/${solWallet.coin()}/key/${solWallet.keyIds()[2]}`).times(2).reply(200, {
                id: '5935d59cf660764331bafcade1855fd7',
                pub: 'GH1LV1e9FdqGe8U2c8PMEcma3fDeh1ktcGVBrD3AuFqx',
                encryptedPrv: '{"iv":"iIuWOHIOErEDdiJn6g46mg==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"Rzh7RRJksj0=","ct":"rcNICUfp9FakT53l+adB6XKzS1vNTc0Qq9jAtqnxA+ScssiS4Q0l3sgG/0gDy5DaZKtXryKBDUvGsi7b/fYaFCUpAoZn/VZTOhOUN/mo7ZHb4OhOXL29YPPkiryAq9Cr"}',
                source: 'bitgo',
                coinSpecific: {},
            });
        });
        after(async function () {
            nock.cleanAll();
        });
        describe('prebuildAndSignTransaction: ', function () {
            // TODO (STLX-15018): fix test
            xit('should successfully sign a consolidation transfer', async function () {
                const txParams = {
                    prebuildTx: {
                        walletId: walletData.id,
                        txHex: 'AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAIE9MWWV2ct01mg5Gm4EqcJ9SAn2XuD+FuAHcHFTkc1Tgut3DgTsiSgTQ0dmzj5JJg6qYTpn8FxOYPFCFTMoZi46gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUpTWpkpIQZNJOhxYNo4fHw1td28kruB5B+oQEEFRI0Qc+q0Zg6OOpV8eCDVLfYziox7YBA7+QPLX4IRhDCSKwICAgABDAIAAACghgEAAAAAAAMAFVRlc3QgaW50ZWdyYXRpb24gbWVtbw==',
                        txInfo: {
                            feePayer: 'HUVE5NfJyGfU1djZsVLA6fxSTS1E2iRqcTRVNC9K2z7c',
                            lamportsPerSignature: 5000,
                            nonce: '27E3MXFvXMUNYeMJeX1pAbERGsJfUbkaZTfgMgpmNN5g',
                            numSignatures: 0,
                            instructionsData: [
                                {
                                    type: 'Transfer',
                                    params: {
                                        fromAddress: 'HUVE5NfJyGfU1djZsVLA6fxSTS1E2iRqcTRVNC9K2z7c',
                                        toAddress: 'ChgJ5tgDwBUsk9RNMm2iLiwP8RodwgZ6uqrC5paJsXVT',
                                        amount: '100000',
                                    },
                                },
                                {
                                    type: 'Memo',
                                    params: {
                                        memo: 'Test integration memo',
                                    },
                                },
                            ],
                        },
                        buildParams: {
                            memo: {
                                type: 'Memo',
                                value: 'Test integration memo',
                            },
                            recipients: [
                                {
                                    address: 'ChgJ5tgDwBUsk9RNMm2iLiwP8RodwgZ6uqrC5paJsXVT',
                                    amount: '100000',
                                },
                            ],
                            type: 'transfer',
                        },
                        consolidateId: '1234',
                        consolidationDetails: {
                            senderAddressIndex: 1,
                        },
                    },
                    walletPassphrase: passphrase,
                };
                // Build and sign the transaction
                const preBuiltSignedTx = await solWallet.prebuildAndSignTransaction(txParams);
                preBuiltSignedTx.should.have.property('txHex');
            });
        });
        it('Should build token enablement transactions correctly', async function () {
            const params = {
                enableTokens: [{ name: 'tsol:usdc' }, { name: 'tsol:srm' }, { name: 'tsol:gmt' }],
            };
            const txRequestNock = nock(bgUrl)
                .post(`/api/v2/wallet/${solWallet.id()}/txrequests`)
                .reply((url, body) => {
                const bodyParams = body;
                bodyParams.intent.intentType.should.equal('enableToken');
                bodyParams.intent.recipients.length.should.equal(0);
                bodyParams.intent.enableTokens.should.deepEqual(params.enableTokens);
                return [
                    200,
                    {
                        apiVersion: 'full',
                        transactions: [
                            {
                                unsignedTx: {
                                    serializedTxHex: 'fake transaction',
                                    feeInfo: 'fake fee info',
                                },
                            },
                        ],
                    },
                ];
            });
            await solWallet.buildTokenEnablements(params);
            txRequestNock.isDone().should.equal(true);
        });
    });
    describe('Accelerate Transaction', function () {
        it('fails if acceleration ids are not passed', async function () {
            await wallet.accelerateTransaction({}).should.be.rejectedWith({ code: 'cpfptxids_or_rbftxids_required' });
        });
        it('fails if cpfpTxIds is not an array', async function () {
            // @ts-expect-error checking type mismatch
            await wallet.accelerateTransaction({ cpfpTxIds: {} }).should.be.rejectedWith({ code: 'cpfptxids_not_array' });
        });
        it('fails if cpfpTxIds is not of length 1', async function () {
            await wallet.accelerateTransaction({ cpfpTxIds: [] }).should.be.rejectedWith({ code: 'cpfptxids_not_array' });
            await wallet
                .accelerateTransaction({ cpfpTxIds: ['id1', 'id2'] })
                .should.be.rejectedWith({ code: 'cpfptxids_not_array' });
        });
        it('fails if cpfpFeeRate is not passed and neither is noCpfpFeeRate', async function () {
            await wallet.accelerateTransaction({ cpfpTxIds: ['id'] }).should.be.rejectedWith({ code: 'cpfpfeerate_not_set' });
        });
        it('fails if cpfpFeeRate is not an integer', async function () {
            await wallet
                // @ts-expect-error checking type mismatch
                .accelerateTransaction({ cpfpTxIds: ['id'], cpfpFeeRate: 'one' })
                .should.be.rejectedWith({ code: 'cpfpfeerate_not_nonnegative_integer' });
        });
        it('fails if cpfpFeeRate is negative', async function () {
            await wallet
                .accelerateTransaction({ cpfpTxIds: ['id'], cpfpFeeRate: -1 })
                .should.be.rejectedWith({ code: 'cpfpfeerate_not_nonnegative_integer' });
        });
        it('fails if maxFee is not passed and neither is noMaxFee', async function () {
            await wallet
                .accelerateTransaction({ cpfpTxIds: ['id'], noCpfpFeeRate: true })
                .should.be.rejectedWith({ code: 'maxfee_not_set' });
        });
        it('fails if maxFee is not an integer', async function () {
            await wallet
                // @ts-expect-error checking type mismatch
                .accelerateTransaction({ cpfpTxIds: ['id'], noCpfpFeeRate: true, maxFee: 'one' })
                .should.be.rejectedWith({ code: 'maxfee_not_nonnegative_integer' });
        });
        it('fails if maxFee is negative', async function () {
            await wallet
                .accelerateTransaction({ cpfpTxIds: ['id'], noCpfpFeeRate: true, maxFee: -1 })
                .should.be.rejectedWith({ code: 'maxfee_not_nonnegative_integer' });
        });
        it('fails if both rbfTxids and cpfpTxids is set', async function () {
            await wallet
                .accelerateTransaction({ cpfpTxIds: ['id1'], rbfTxIds: ['id2'] })
                .should.be.rejectedWith({ code: 'cannot_specify_both_cpfp_and_rbf_txids' });
        });
        it('fails if rbfTxIds is set but feeMultiplier is missing', async function () {
            await wallet
                .accelerateTransaction({ rbfTxIds: ['id'] })
                .should.be.rejectedWith({ code: 'feemultiplier_not_set' });
        });
        it('fails if fee multiplier is less than or equal to 1', async function () {
            await wallet
                .accelerateTransaction({ rbfTxIds: ['id'], feeMultiplier: 1 })
                .should.be.rejectedWith({ code: 'feemultiplier_greater_than_one' });
            await wallet
                .accelerateTransaction({ rbfTxIds: ['id2'], feeMultiplier: 0.5 })
                .should.be.rejectedWith({ code: 'feemultiplier_greater_than_one' });
        });
        it('submits a transaction with all cpfp specific parameters', async function () {
            const params = {
                cpfpTxIds: ['id'],
                cpfpFeeRate: 1,
                maxFee: 1,
            };
            const prebuildReturn = Object.assign({ txHex: '123' }, params);
            const prebuildStub = sinon.stub(wallet, 'prebuildAndSignTransaction').resolves(prebuildReturn);
            const path = `/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/send`;
            nock(bgUrl).post(path, _.matches(prebuildReturn)).reply(200);
            await wallet.accelerateTransaction(params);
            prebuildStub.should.have.been.calledOnceWith(params);
            sinon.restore();
        });
    });
    describe('fanout input maxNumInputsToUse and unspents verification', function () {
        const address = '5b34252f1bf349930e34020a';
        const maxNumInputsToUse = 2;
        const unspents = [
            'cc30565750e2aeb818625aaedaf89db5c614e5977b9645cee1d7289f616fb1d8:0',
            '8c45164787a954ab07864af9b05b34fbde3a8e430a8c65b0e60e4e543d8e1b6c:2',
        ];
        let basecoin;
        let wallet;
        before(async function () {
            basecoin = bitgo.coin('tbtc');
            const walletData = {
                id: '5b34252f1bf349930e34020a',
                coin: 'tbtc',
                keys: ['5b3424f91bf349930e340175'],
            };
            wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
        });
        it('should pass maxNumInputsToUse parameter when calling fanout unspents', async function () {
            const path = `/api/v2/${wallet.coin()}/wallet/${wallet.id()}/fanoutUnspents`;
            const response = nock(bgUrl)
                .post(path, _.matches({ maxNumInputsToUse })) // use _.matches to do a partial match on request body object instead of strict matching
                .reply(200);
            try {
                await wallet.fanoutUnspents({ address, maxNumInputsToUse });
            }
            catch (e) {
                // the fanoutUnspents method will probably throw an exception for not having all of the correct nocks
                // we only care about /fanoutUnspents and whether maxNumInputsToUse is an allowed parameter
            }
            response.isDone().should.be.true();
        });
        it('should pass unspents parameter when calling fanout unspents', async function () {
            const path = `/api/v2/${wallet.coin()}/wallet/${wallet.id()}/fanoutUnspents`;
            const response = nock(bgUrl)
                .post(path, _.matches({ unspents })) // use _.matches to do a partial match on request body object instead of strict matching
                .reply(200);
            try {
                await wallet.fanoutUnspents({ address, unspents });
            }
            catch (e) {
                // the fanoutUnspents method will probably throw an exception for not having all of the correct nocks
                // we only care about /fanoutUnspents and whether unspents is an allowed parameter
            }
            response.isDone().should.be.true();
        });
        it('should only build tx (not sign/send) while fanning out unspents', async function () {
            const path = `/api/v2/${wallet.coin()}/wallet/${wallet.id()}/fanoutUnspents`;
            const response = nock(bgUrl).post(path, _.matches({ unspents })).reply(200);
            const unusedNocks = nock(bgUrl);
            unusedNocks.get(`/api/v2/${wallet.coin()}/key/${wallet.keyIds()[0]}`).reply(200);
            unusedNocks.post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/send`).reply(200);
            try {
                await wallet.fanoutUnspents({ address, unspents }, sdk_core_1.ManageUnspentsOptions.BUILD_ONLY);
            }
            catch (e) {
                // the fanoutUnspents method will probably throw an exception for not having all of the correct nocks
                // we only care about /fanoutUnspents and whether unspents is an allowed parameter
            }
            response.isDone().should.be.true();
            unusedNocks.pendingMocks().length.should.eql(2);
            nock.cleanAll();
        });
    });
    describe('manage unspents', function () {
        let rootWalletKey;
        let walletPassphrase;
        let basecoin;
        let wallet;
        let keysObj;
        before(async function () {
            rootWalletKey = (0, util_1.getDefaultWalletKeys)();
            walletPassphrase = 'fixthemoneyfixtheworld';
            keysObj = (0, util_1.toKeychainObjects)(rootWalletKey, walletPassphrase);
            basecoin = bitgo.coin('tbtc');
            const walletData = {
                id: '5b34252f1bf349930e34020a',
                coin: 'tbtc',
                keys: keysObj.map((k) => k.id),
            };
            wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
        });
        it('should pass for bulk consolidating unspents', async function () {
            const psbts = ['p2wsh', 'p2shP2wsh'].map((scriptType) => utxoLib.testutil.constructPsbt([{ scriptType, value: BigInt(1000) }], [{ scriptType, value: BigInt(900) }], basecoin.network, rootWalletKey, 'unsigned'));
            const txHexes = psbts.map((psbt) => ({ txHex: psbt.toHex() }));
            const nocks = [];
            nocks.push(nock(bgUrl).post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/consolidateUnspents`).reply(200, txHexes));
            nocks.push(...keysObj.map((k, i) => nock(bgUrl).get(`/api/v2/${wallet.coin()}/key/${wallet.keyIds()[i]}`).reply(200, k)));
            nocks.push(...psbts.map((psbt) => nock(bgUrl)
                .post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/send`, _.matches({ txHex: psbt.signAllInputsHD(rootWalletKey.user).toHex() }))
                .reply(200)));
            await wallet.consolidateUnspents({ bulk: true, walletPassphrase });
            nocks.forEach((n) => {
                console.log(n);
                n.isDone().should.be.true();
            });
        });
        it('should pass for single consolidating unspents', async function () {
            const psbt = utxoLib.testutil.constructPsbt([{ scriptType: 'p2wsh', value: BigInt(1000) }], [{ scriptType: 'p2shP2wsh', value: BigInt(900) }], basecoin.network, rootWalletKey, 'unsigned');
            const nocks = [];
            nocks.push(nock(bgUrl)
                .post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/consolidateUnspents`)
                .reply(200, { txHex: psbt.toHex() }));
            nocks.push(...keysObj.map((k, i) => nock(bgUrl).get(`/api/v2/${wallet.coin()}/key/${wallet.keyIds()[i]}`).reply(200, k)));
            nocks.push(nock(bgUrl)
                .post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/send`, _.matches({ txHex: psbt.signAllInputsHD(rootWalletKey.user).toHex() }))
                .reply(200));
            await wallet.consolidateUnspents({ walletPassphrase });
            nocks.forEach((n) => {
                n.isDone().should.be.true();
            });
        });
    });
    describe('max recipient', function () {
        const address = '5b34252f1bf349930e34020a';
        const recipients = [
            {
                address,
                amount: 'max',
            },
        ];
        let basecoin;
        let wallet;
        before(async function () {
            basecoin = bitgo.coin('tbtc');
            const walletData = {
                id: '5b34252f1bf349930e34020a',
                coin: 'tbtc',
                keys: ['5b3424f91bf349930e340175'],
            };
            wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
        });
        it('should pass maxFeeRate parameter when building transactions', async function () {
            const path = `/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/build`;
            const response = nock(bgUrl)
                .post(path, _.matches({
                recipients,
            })) // use _.matches to do a partial match on request body object instead of strict matching
                .reply(200);
            try {
                await wallet.prebuildTransaction({ recipients });
            }
            catch (e) {
                // the prebuildTransaction method will probably throw an exception for not having all of the correct nocks
                // we only care about /tx/build and whether maxFeeRate is an allowed parameter
            }
            response.isDone().should.be.true();
        });
    });
    describe('maxFeeRate verification', function () {
        const address = '5b34252f1bf349930e34020a';
        const recipients = [
            {
                address,
                amount: 0,
            },
        ];
        const maxFeeRate = 10000;
        let basecoin;
        let wallet;
        before(async function () {
            basecoin = bitgo.coin('tbtc');
            const walletData = {
                id: '5b34252f1bf349930e34020a',
                coin: 'tbtc',
                keys: ['5b3424f91bf349930e340175'],
            };
            wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
        });
        it('should pass maxFeeRate parameter when building transactions', async function () {
            const path = `/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/build`;
            const response = nock(bgUrl)
                .post(path, _.matches({ recipients, maxFeeRate })) // use _.matches to do a partial match on request body object instead of strict matching
                .reply(200);
            try {
                await wallet.prebuildTransaction({ recipients, maxFeeRate });
            }
            catch (e) {
                // the prebuildTransaction method will probably throw an exception for not having all of the correct nocks
                // we only care about /tx/build and whether maxFeeRate is an allowed parameter
            }
            response.isDone().should.be.true();
        });
        it('should pass maxFeeRate parameter when consolidating unspents', async function () {
            const path = `/api/v2/${wallet.coin()}/wallet/${wallet.id()}/consolidateUnspents`;
            const response = nock(bgUrl)
                .post(path, _.matches({ maxFeeRate })) // use _.matches to do a partial match on request body object instead of strict matching
                .reply(200);
            nock(bgUrl).get(`/api/v2/${wallet.coin()}/key/${wallet.keyIds()[0]}`).reply(200);
            try {
                await wallet.consolidateUnspents({ recipients, maxFeeRate });
            }
            catch (e) {
                // the consolidateUnspents method will probably throw an exception for not having all of the correct nocks
                // we only care about /consolidateUnspents and whether maxFeeRate is an allowed parameter
            }
            response.isDone().should.be.true();
        });
        it('should only build tx (not sign/send) while consolidating unspents', async function () {
            const toBeUsedNock = nock(bgUrl);
            toBeUsedNock.post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/consolidateUnspents`).reply(200);
            const unusedNocks = nock(bgUrl);
            unusedNocks.get(`/api/v2/${wallet.coin()}/key/${wallet.keyIds()[0]}`).reply(200);
            unusedNocks.post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/send`).reply(200);
            await wallet.consolidateUnspents({ recipients }, sdk_core_1.ManageUnspentsOptions.BUILD_ONLY);
            toBeUsedNock.isDone().should.be.true();
            unusedNocks.pendingMocks().length.should.eql(2);
            nock.cleanAll();
        });
        it('should pass maxFeeRate parameter when calling sweep wallets', async function () {
            const path = `/api/v2/${wallet.coin()}/wallet/${wallet.id()}/sweepWallet`;
            const response = nock(bgUrl)
                .post(path, _.matches({ address, maxFeeRate })) // use _.matches to do a partial match on request body object instead of strict matching
                .reply(200);
            try {
                await wallet.sweep({ address, maxFeeRate });
            }
            catch (e) {
                // the sweep method will probably throw an exception for not having all of the correct nocks
                // we only care about /sweepWallet and whether maxFeeRate is an allowed parameter
            }
            response.isDone().should.be.true();
        });
        it('should pass maxFeeRate parameter when calling fanout unspents', async function () {
            const path = `/api/v2/${wallet.coin()}/wallet/${wallet.id()}/fanoutUnspents`;
            const response = nock(bgUrl)
                .post(path, _.matches({ maxFeeRate })) // use _.matches to do a partial match on request body object instead of strict matching
                .reply(200);
            try {
                await wallet.fanoutUnspents({ address, maxFeeRate });
            }
            catch (e) {
                // the fanoutUnspents method will probably throw an exception for not having all of the correct nocks
                // we only care about /fanoutUnspents and whether maxFeeRate is an allowed parameter
            }
            response.isDone().should.be.true();
        });
    });
    describe('allowPartialSweep verification', function () {
        const address = '5b34252f1bf349930e34020a';
        const allowPartialSweep = true;
        let basecoin;
        let wallet;
        before(async function () {
            basecoin = bitgo.coin('tbtc');
            const walletData = {
                id: '5b34252f1bf349930e34020a',
                coin: 'tbtc',
                keys: ['5b3424f91bf349930e340175'],
            };
            wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
        });
        it('should pass allowPartialSweep parameter when calling sweep wallets', async function () {
            const path = `/api/v2/${wallet.coin()}/wallet/${wallet.id()}/sweepWallet`;
            const response = nock(bgUrl)
                .post(path, _.matches({ address, allowPartialSweep })) // use _.matches to do a partial match on request body object instead of strict matching
                .reply(200);
            try {
                await wallet.sweep({ address, allowPartialSweep });
            }
            catch (e) {
                // the sweep method will probably throw an exception for not having all of the correct nocks
                // we only care about /sweepWallet and whether allowPartialSweep is an allowed parameter
            }
            response.isDone().should.be.true();
        });
    });
    describe('sweep wallet', function () {
        let basecoin;
        let wallet;
        before(async function () {
            basecoin = bitgo.coin('ttrx');
            const walletData = {
                id: '5b34252f1bf349930e34020a',
                coin: 'ttrx',
                keys: ['5b3424f91bf349930e340175'],
            };
            wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
        });
        it('should use maximum spendable balance of wallet to sweep funds ', async function () {
            const path = `/api/v2/${wallet.coin()}/wallet/${wallet.id()}/maximumSpendable`;
            const response = nock(bgUrl).get(path).reply(200, {
                coin: 'ttrx',
                maximumSpendable: 65000,
            });
            const body = {
                coin: 'ttrx',
                address: '2MwvR24yqym2CgHMp7zwvdeqBa4F8KTqunS',
            };
            try {
                await wallet.sweep(body);
            }
            catch (e) {
                // the sweep method will probably throw an exception for not having all of the correct nocks
                // we only care about maximum spendable balance being used to sweep funds
            }
            response.isDone().should.be.true();
        });
    });
    describe('Transaction prebuilds', function () {
        let ethWallet;
        before(async function () {
            const walletData = {
                id: '598f606cd8fc24710d2ebadb1d9459bb',
                coin: 'teth',
                keys: [
                    '598f606cd8fc24710d2ebad89dce86c2',
                    '598f606cc8e43aef09fcb785221d9dd2',
                    '5935d59cf660764331bafcade1855fd7',
                ],
            };
            ethWallet = new sdk_core_1.Wallet(bitgo, bitgo.coin('teth'), walletData);
        });
        it('should return reqId if it was passed in the params', async function () {
            const params = { offlineVerification: true };
            const scope = nock(bgUrl)
                .post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/build`, tbtcHotWalletDefaultParams)
                .query(params)
                .reply(200, {});
            const blockHeight = 100;
            sinon.stub(basecoin, 'getLatestBlockHeight').resolves(blockHeight);
            sinon.stub(basecoin, 'postProcessPrebuild').resolves({});
            const txRequest = await wallet.prebuildTransaction({ ...params, reqId: reqId });
            txRequest.reqId?.should.containEql(reqId);
            scope.done();
        });
        it('should pass offlineVerification=true query param if passed truthy value', async function () {
            const params = { offlineVerification: true };
            const scope = nock(bgUrl)
                .post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/build`, tbtcHotWalletDefaultParams)
                .query(params)
                .reply(200, {});
            const blockHeight = 100;
            const blockHeightStub = sinon.stub(basecoin, 'getLatestBlockHeight').resolves(blockHeight);
            const postProcessStub = sinon.stub(basecoin, 'postProcessPrebuild').resolves({});
            await wallet.prebuildTransaction(params);
            blockHeightStub.should.have.been.calledOnce();
            postProcessStub.should.have.been.calledOnceWith({
                blockHeight: 100,
                wallet: wallet,
                buildParams: tbtcHotWalletDefaultParams,
            });
            scope.done();
            blockHeightStub.restore();
            postProcessStub.restore();
        });
        it('should not pass the offlineVerification query param if passed a falsey value', async function () {
            const params = { offlineVerification: false };
            nock(bgUrl)
                .post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/build`, tbtcHotWalletDefaultParams)
                .query({})
                .reply(200, {});
            const blockHeight = 100;
            const blockHeightStub = sinon.stub(basecoin, 'getLatestBlockHeight').resolves(blockHeight);
            const postProcessStub = sinon.stub(basecoin, 'postProcessPrebuild').resolves({});
            await wallet.prebuildTransaction(params);
            blockHeightStub.should.have.been.calledOnce();
            postProcessStub.should.have.been.calledOnceWith({
                blockHeight: 100,
                wallet: wallet,
                buildParams: tbtcHotWalletDefaultParams,
            });
            blockHeightStub.restore();
            postProcessStub.restore();
        });
        it('should pass script outputs with the proper structure to wallet platform', async function () {
            const script = '6a11223344556677889900';
            nock(bgUrl)
                .post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/build`, {
                ...tbtcHotWalletDefaultParams,
                recipients: [{ script, amount: 1e6 }],
            })
                .query({})
                .reply(200, {});
            const blockHeight = 100;
            const blockHeightStub = sinon.stub(basecoin, 'getLatestBlockHeight').resolves(blockHeight);
            const postProcessStub = sinon.stub(basecoin, 'postProcessPrebuild').resolves({});
            await wallet.prebuildTransaction({ recipients: [{ address: `scriptPubKey:${script}`, amount: 1e6 }] });
            blockHeightStub.should.have.been.calledOnce();
            postProcessStub.should.have.been.calledOnceWith({
                blockHeight: 100,
                wallet: wallet,
                buildParams: { ...tbtcHotWalletDefaultParams, recipients: [{ script, amount: 1e6 }] },
            });
            blockHeightStub.restore();
            postProcessStub.restore();
        });
        it('prebuild should call build and getLatestBlockHeight for utxo coins', async function () {
            const params = {};
            nock(bgUrl)
                .post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/build`, tbtcHotWalletDefaultParams)
                .query(params)
                .reply(200, {});
            const blockHeight = 100;
            const blockHeightStub = sinon.stub(basecoin, 'getLatestBlockHeight').resolves(blockHeight);
            const postProcessStub = sinon.stub(basecoin, 'postProcessPrebuild').resolves({});
            await wallet.prebuildTransaction(params);
            blockHeightStub.should.have.been.calledOnce();
            postProcessStub.should.have.been.calledOnceWith({
                blockHeight: 100,
                wallet: wallet,
                buildParams: tbtcHotWalletDefaultParams,
            });
            blockHeightStub.restore();
            postProcessStub.restore();
        });
        it('prebuild should not have changeAddressType array in post body when changeAddressType is defined', async function () {
            const expectedBuildPostBodyParams = {
                changeAddressType: 'p2trMusig2',
                txFormat: 'psbt',
            };
            nock(bgUrl)
                .post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/build`, expectedBuildPostBodyParams)
                .query({})
                .reply(200, {});
            const blockHeight = 100;
            const blockHeightStub = sinon.stub(basecoin, 'getLatestBlockHeight').resolves(blockHeight);
            const postProcessStub = sinon.stub(basecoin, 'postProcessPrebuild').resolves({});
            await wallet.prebuildTransaction({ changeAddressType: 'p2trMusig2' });
            blockHeightStub.should.have.been.calledOnce();
            postProcessStub.should.have.been.calledOnceWith({
                blockHeight: 100,
                wallet: wallet,
                buildParams: expectedBuildPostBodyParams,
            });
            blockHeightStub.restore();
            postProcessStub.restore();
        });
        it('prebuild should call build but not getLatestBlockHeight for account coins', async function () {
            ['txrp', 'txlm', 'teth'].forEach(async function (coin) {
                const accountcoin = bitgo.coin(coin);
                const walletData = {
                    id: '5b34252f1bf349930e34021a',
                    coin,
                    keys: ['5b3424f91bf349930e340175'],
                };
                const accountWallet = new sdk_core_1.Wallet(bitgo, accountcoin, walletData);
                const params = {};
                nock(bgUrl)
                    .post(`/api/v2/${accountWallet.coin()}/wallet/${accountWallet.id()}/tx/build`)
                    .query(params)
                    .reply(200, {});
                const postProcessStub = sinon.stub(accountcoin, 'postProcessPrebuild').resolves({});
                await accountWallet.prebuildTransaction(params);
                postProcessStub.should.have.been.calledOnceWith({
                    wallet: accountWallet,
                    buildParams: {},
                });
                postProcessStub.restore();
            });
        });
        it('should have isBatch = true in the txPrebuild if txParams has more than one recipient', async function () {
            const txParams = {
                recipients: [
                    { amount: '1000000000000000', address: address1 },
                    { amount: '1000000000000000', address: address2 },
                ],
                walletContractAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
                walletPassphrase: 'moon',
            };
            const totalAmount = '2000000000000000';
            nock(bgUrl)
                .post(`/api/v2/${ethWallet.coin()}/wallet/${ethWallet.id()}/tx/build`, _.matches({ recipients: txParams.recipients }))
                .reply(200, {
                recipients: [
                    {
                        address: '0xc0aaf2649e7b0f3950164681eca2b1a8f654a478',
                        amount: '2000000000000000',
                        data: '0xc00c4e9e000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000174cfd823af8ce27ed0afee3fcf3c3ba259116be0000000000000000000000007e85bdc27c050e3905ebf4b8e634d9ad6edd0de6000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000038d7ea4c68000',
                    },
                ],
                nextContractSequenceId: 10896,
                gasPrice: 20000000000,
                gasLimit: 500000,
                isBatch: true,
                coin: 'teth',
            });
            const txPrebuild = await ethWallet.prebuildTransaction(txParams);
            txPrebuild.isBatch.should.equal(true);
            txPrebuild.recipients[0].address.should.equal(bitgo.coin('teth').staticsCoin.network.batcherContractAddress);
            txPrebuild.recipients[0].amount.should.equal(totalAmount);
        });
        it('should have isBatch = false and hopTransaction field should not be there in the txPrebuild  for normal eth tx', async function () {
            const txParams = {
                recipients: [{ amount: '1000000000000000', address: address1 }],
                walletContractAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
                walletPassphrase: 'moon',
            };
            nock(bgUrl)
                .post(`/api/v2/${ethWallet.coin()}/wallet/${ethWallet.id()}/tx/build`, _.matches({ recipients: txParams.recipients }))
                .reply(200, {
                recipients: [
                    {
                        amount: '1000000000000000',
                        address: '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be',
                    },
                ],
                nextContractSequenceId: 10897,
                gasPrice: 20000000000,
                gasLimit: 500000,
                isBatch: false,
                coin: 'teth',
            });
            const txPrebuild = await ethWallet.prebuildTransaction(txParams);
            txPrebuild.isBatch.should.equal(false);
            txPrebuild.should.not.have.property('hopTransaction');
            txPrebuild.recipients[0].address.should.equal(address1);
            txPrebuild.recipients[0].amount.should.equal('1000000000000000');
        });
        it('should pass unspent reservation parameter through when building transactions', async function () {
            const reservation = {
                expireTime: '2029-08-12',
            };
            const recipients = [
                {
                    address: 'aaa',
                    amount: '1000',
                },
            ];
            const path = `/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/build`;
            const response = nock(bgUrl)
                .post(path, _.matches({ recipients, reservation })) // use _.matches to do a partial match on request body object instead of strict matching
                .reply(200);
            try {
                await wallet.prebuildTransaction({ recipients, reservation });
            }
            catch (e) {
                // the prebuildTransaction method will probably throw an exception for not having all of the correct nocks
                // we only care about /tx/build and whether reservation is an allowed parameter
            }
            response.isDone().should.be.true();
        });
        it('should pass gas limit parameter through when building transaction for sui', async function () {
            const params = { gasLimit: 100 };
            const path = `/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/build`;
            const response = nock(bgUrl)
                .post(path, _.matches(params)) // use _.matches to do a partial match on request body object instead of strict matching
                .reply(200);
            try {
                await wallet.prebuildTransaction(params);
            }
            catch (e) {
                // the prebuildTransaction method will probably throw an exception for not having all of the correct nocks
                // we only care about /tx/build and whether reservation is an allowed parameter
            }
            response.isDone().should.be.true();
        });
    });
    describe('Maximum Spendable', function maximumSpendable() {
        let bgUrl;
        before(async function () {
            nock.pendingMocks().should.be.empty();
            bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
        });
        it('arguments', async function () {
            const optionalParams = {
                limit: 25,
                minValue: '0',
                maxValue: '9999999999999',
                minHeight: 0,
                minConfirms: 2,
                enforceMinConfirmsForChange: false,
                feeRate: 10000,
                maxFeeRate: 100000,
                recipientAddress: '2NCUFDLiUz9CVnmdVqQe9acVonoM89e76df',
            };
            // The actual api request will only send strings, but the SDK function expects numbers for some values
            const apiParams = _.mapValues(optionalParams, (param) => String(param));
            const path = `/api/v2/${wallet.coin()}/wallet/${wallet.id()}/maximumSpendable`;
            const response = nock(bgUrl)
                .get(path)
                .query(_.matches(apiParams)) // use _.matches to do a partial match on request body object instead of strict matching
                .reply(200, {
                coin: 'tbch',
                maximumSpendable: 65000,
            });
            try {
                await wallet.maximumSpendable(optionalParams);
            }
            catch (e) {
                // test is successful if nock is consumed
            }
            response.isDone().should.be.true();
        });
    });
    describe('Wallet Sharing', function () {
        it('should share to cold wallet without passing skipKeychain', async function () {
            const userId = '123';
            const email = 'shareto@sdktest.com';
            const permissions = 'view,spend';
            const getSharingKeyNock = nock(bgUrl).post('/api/v1/user/sharingkey', { email }).reply(200, { userId });
            const getKeyNock = nock(bgUrl)
                .get(`/api/v2/tbtc/key/${coldWallet.keyIds()[0]}`)
                .reply(200, {})
                .get(`/api/v2/tbtc/key/${coldWallet.keyIds()[1]}`)
                .reply(200, {})
                .get(`/api/v2/tbtc/key/${coldWallet.keyIds()[2]}`)
                .reply(200, {});
            const createShareNock = nock(bgUrl)
                .post(`/api/v2/tbtc/wallet/${coldWallet.id()}/share`, {
                user: userId,
                permissions,
                skipKeychain: true,
            })
                .reply(200, {});
            await coldWallet.shareWallet({ email, permissions });
            getSharingKeyNock.isDone().should.be.True();
            getKeyNock.isDone().should.be.True();
            createShareNock.isDone().should.be.True();
        });
        describe('Hot Wallet Sharing', function () {
            const userId = '123';
            const email = 'shareto@sdktest.com';
            const permissions = 'view,spend';
            const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
            const path = 'm/999999/1/1';
            const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
            const walletPassphrase = 'bitgo1234';
            const pub = 'Zo1ggzTUKMY5bYnDvT5mtVeZxzf2FaLTbKkmvGUhUQk';
            const lightningCoin = bitgo.coin('tlnbtc');
            const lightningWalletData = {
                id: '5b34252f1bf349930e34020a00000001',
                coin: 'tlnbtc',
                keys: ['5b3424f91bf349930e34017500000001'],
                coinSpecific: { keys: ['5b3424f91bf349930e34017600000000', '5b3424f91bf349930e34017700000000'] },
                type: 'hot',
            };
            const lightningWallet = new sdk_core_1.Wallet(bitgo, lightningCoin, lightningWalletData);
            for (const hotWallet of [wallet, lightningWallet]) {
                it(`should use keychain pub to share ${hotWallet.coin()} hot wallet`, async function () {
                    const getSharingKeyNock = nock(bgUrl)
                        .post('/api/v1/user/sharingkey', { email })
                        .reply(200, { userId, pubkey, path });
                    const getKeyNocks = [];
                    if (hotWallet.baseCoin.getFamily() === 'lnbtc') {
                        for (let i = 0; i < 2; i++) {
                            const keyId = lightningWalletData.coinSpecific.keys[i];
                            const getKeyNock = nock(bgUrl)
                                .get(`/api/v2/tlnbtc/key/${keyId}`)
                                .reply(200, {
                                id: keyId,
                                pub: i === 0 ? pub : 'Zo1ggzTUKMY5bYnDvT5mtVeZxzf2FaLTbKkmvGUhUQm',
                                source: 'user',
                                encryptedPrv: bitgo.encrypt({ input: 'xprv' + i, password: walletPassphrase }),
                                coinSpecific: i === 0
                                    ? { [hotWallet.baseCoin.getChain()]: { purpose: 'userAuth' } }
                                    : { [hotWallet.baseCoin.getChain()]: { purpose: 'nodeAuth' } },
                            });
                            getKeyNocks.push(getKeyNock);
                        }
                    }
                    else {
                        const getKeyNock = nock(bgUrl)
                            .get(`/api/v2/tbtc/key/${wallet.keyIds()[0]}`)
                            .reply(200, {
                            id: wallet.keyIds()[0],
                            pub,
                            source: 'user',
                            encryptedPrv: bitgo.encrypt({ input: 'xprv1', password: walletPassphrase }),
                            coinSpecific: {},
                        });
                        getKeyNocks.push(getKeyNock);
                    }
                    const stub = sinon.stub(hotWallet, 'createShare').callsFake(async (options) => {
                        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
                        options.keychain.pub.should.not.be.undefined();
                        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
                        options.keychain.pub.should.equal(pub);
                        return undefined;
                    });
                    await hotWallet.shareWallet({ email, permissions, walletPassphrase });
                    stub.calledOnce.should.be.true();
                    getSharingKeyNock.isDone().should.be.True();
                    getKeyNocks.every((v) => v.isDone().should.be.True());
                });
            }
        });
        it('should provide skipKeychain to wallet share api for hot wallet', async function () {
            const userId = '123';
            const email = 'shareto@sdktest.com';
            const permissions = 'view,spend';
            const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
            const path = 'm/999999/1/1';
            const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
            const getSharingKeyNock = nock(bgUrl)
                .post('/api/v1/user/sharingkey', { email })
                .reply(200, { userId, pubkey, path });
            const createShareNock = nock(bgUrl)
                .post(`/api/v2/tbtc/wallet/${wallet.id()}/share`, {
                user: userId,
                permissions,
                skipKeychain: true,
            })
                .reply(200, {});
            await wallet.shareWallet({ email, permissions, skipKeychain: true });
            createShareNock.isDone().should.be.True();
            getSharingKeyNock.isDone().should.be.True();
        });
        it('should decrypt webauthn encryptedPrv for wallet share (spend)', async function () {
            const userId = '123';
            const email = 'shareto@sdktest.com';
            const permissions = 'view,spend';
            const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
            const path = 'm/999999/1/1';
            const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
            const privateKey = 'xprv1';
            const walletPassphrase1 = 'bitgo1234';
            const walletPassphrase2 = 'bitgo5678';
            const getSharingKeyNock = nock(bgUrl)
                .post('/api/v1/user/sharingkey', { email })
                .reply(200, { userId, pubkey, path });
            const pub = 'Zo1ggzTUKMY5bYnDvT5mtVeZxzf2FaLTbKkmvGUhUQk';
            const getKeyNock = nock(bgUrl)
                .get(`/api/v2/tbtc/key/${wallet.keyIds()[0]}`)
                .reply(200, {
                id: wallet.keyIds()[0],
                pub,
                source: 'user',
                encryptedPrv: bitgo.encrypt({ input: privateKey, password: walletPassphrase1 }),
                webauthnDevices: [
                    {
                        otpDeviceId: '123',
                        authenticatorInfo: {
                            credID: 'credID',
                            fmt: 'packed',
                            publicKey: 'some value',
                        },
                        prfSalt: '456',
                        encryptedPrv: bitgo.encrypt({ input: privateKey, password: walletPassphrase2 }),
                    },
                ],
                coinSpecific: {},
            });
            const stub = sinon.stub(wallet, 'createShare').callsFake(async (options) => {
                options.keychain.encryptedPrv.should.not.be.undefined();
                return undefined;
            });
            await wallet.shareWallet({ email, permissions, walletPassphrase: walletPassphrase2 });
            stub.calledOnce.should.be.true();
            getSharingKeyNock.isDone().should.be.True();
            getKeyNock.isDone().should.be.True();
        });
    });
    describe('Wallet Freezing', function () {
        it('should freeze wallet for specified duration in seconds', async function () {
            const params = { duration: 60 };
            const scope = nock(bgUrl).post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/freeze`, params).reply(200, {});
            await wallet.freeze(params);
            scope.isDone().should.be.True();
        });
    });
    describe('TSS Wallets', function () {
        const sandbox = sinon.createSandbox();
        const tsol = bitgo.coin('tsol');
        const walletData = {
            id: '5b34252f1bf349930e34020a00000000',
            coin: 'tsol',
            keys: [
                '598f606cd8fc24710d2ebad89dce86c2',
                '598f606cc8e43aef09fcb785221d9dd2',
                '5935d59cf660764331bafcade1855fd7',
            ],
            coinSpecific: {},
            multisigType: 'tss',
        };
        const ethWalletData = {
            id: '598f606cd8fc24710d2ebadb1d9459bb',
            coin: 'teth',
            keys: [
                '598f606cd8fc24710d2ebad89dce86c2',
                '598f606cc8e43aef09fcb785221d9dd2',
                '5935d59cf660764331bafcade1855fd7',
            ],
            multisigType: 'tss',
            coinSpecific: { addressVersion: 1 },
            type: 'hot',
        };
        const polygonWalletData = {
            id: '632826520ee1e5000729017354acaeab',
            coin: 'tpolygon',
            keys: [
                '598f606cd8fc24710d2ebad89dce86c2',
                '598f606cc8e43aef09fcb785221d9dd2',
                '5935d59cf660764331bafcade1855fd7',
            ],
            multisigType: 'tss',
        };
        const tssSolWallet = new sdk_core_1.Wallet(bitgo, tsol, walletData);
        let tssEthWallet = new sdk_core_1.Wallet(bitgo, bitgo.coin('teth'), ethWalletData);
        const tssPolygonWallet = new sdk_core_1.Wallet(bitgo, bitgo.coin('tpolygon'), polygonWalletData);
        const custodialTssSolWallet = new sdk_core_1.Wallet(bitgo, tsol, {
            ...walletData,
            type: 'custodial',
        });
        const txRequest = {
            txRequestId: 'id',
            transactions: [],
            intent: {
                intentType: 'payment',
            },
            date: new Date().toISOString(),
            latest: true,
            state: 'pendingUserSignature',
            userId: 'userId',
            walletType: 'hot',
            policiesChecked: false,
            version: 1,
            walletId: 'walletId',
            unsignedTxs: [
                {
                    serializedTxHex: 'ababcdcd',
                    signableHex: 'deadbeef',
                    feeInfo: {
                        fee: 5000,
                        feeString: '5000',
                    },
                    derivationPath: 'm/0',
                },
            ],
        };
        const txRequestFull = {
            txRequestId: 'id',
            intent: {
                intentType: 'payment',
            },
            date: new Date().toISOString(),
            latest: true,
            state: 'pendingUserSignature',
            userId: 'userId',
            walletId: 'walletId',
            signatureShares: [],
            version: 1,
            policiesChecked: false,
            walletType: 'hot',
            transactions: [
                {
                    state: 'pendingSignature',
                    unsignedTx: {
                        serializedTxHex: 'ababcdcd',
                        signableHex: 'deadbeef',
                        feeInfo: {
                            fee: 5000,
                            feeString: '5000',
                        },
                        derivationPath: 'm/0',
                    },
                    signatureShares: [],
                    commitmentShares: [],
                },
            ],
            unsignedTxs: [],
            apiVersion: 'full',
        };
        afterEach(function () {
            sandbox.verifyAndRestore();
        });
        describe('preBuildAndSignTransaction', async function () {
            const params = {
                walletPassphrase: 'passphrase12345',
                prebuildTx: { walletId: tssEthWallet.id(), txRequestId: 'randomId' },
                type: 'transfer',
            };
            ['eddsa', 'ecdsa'].forEach((keyCurve) => {
                describe(keyCurve, () => {
                    const wallet = keyCurve === 'eddsa' ? tssSolWallet : tssEthWallet;
                    beforeEach(function () {
                        sandbox
                            .stub(sdk_core_1.Keychains.prototype, 'getKeysForSigning')
                            .resolves([{ commonKeychain: 'test', id: '', pub: '', type: 'independent' }]);
                        if (keyCurve === 'eddsa') {
                            sandbox.stub(sdk_coin_sol_1.Tsol.prototype, 'verifyTransaction').resolves(true);
                        }
                        else {
                            sandbox.stub(sdk_coin_eth_1.Teth.prototype, 'verifyTransaction').resolves(true);
                        }
                    });
                    afterEach(function () {
                        sandbox.verifyAndRestore();
                    });
                    it('it should succeed but not sign if the txRequest is pending approval', async function () {
                        const getTxRequestStub = sandbox.stub(sdk_core_1.BaseTssUtils.default.prototype, 'getTxRequest').resolves({
                            ...txRequestFull,
                            state: 'pendingApproval',
                        });
                        const signTransactionSpy = sandbox.spy(sdk_core_1.Wallet.prototype, 'signTransaction');
                        const result = (await wallet.prebuildAndSignTransaction(params));
                        result.should.have.property('state');
                        result.state.should.equal('pendingApproval');
                        getTxRequestStub.calledOnce.should.be.true();
                        signTransactionSpy.notCalled.should.be.true();
                    });
                    it('it should succeed and sign if the txRequest is not pending approval', async function () {
                        const getTxRequestStub = sandbox.stub(sdk_core_1.BaseTssUtils.default.prototype, 'getTxRequest');
                        getTxRequestStub.resolves(txRequestFull);
                        const signTransactionStub = sandbox.stub(sdk_core_1.Wallet.prototype, 'signTransaction');
                        signTransactionStub.resolves({ ...txRequestFull, state: 'signed' });
                        const result = (await wallet.prebuildAndSignTransaction(params));
                        result.should.have.property('state');
                        result.state.should.equal('signed');
                        getTxRequestStub.calledOnce.should.be.true();
                        signTransactionStub.calledOnce.should.be.true();
                    });
                });
            });
        });
        describe('Transaction prebuilds', function () {
            it('should build a single recipient transfer transaction', async function () {
                const recipients = [
                    {
                        address: '6DadkZcx9JZgeQUDbHh12cmqCpaqehmVxv6sGy49jrah',
                        amount: '1000',
                    },
                ];
                const prebuildTxWithIntent = sandbox.stub(sdk_core_1.TssUtils.prototype, 'prebuildTxWithIntent');
                prebuildTxWithIntent.resolves(txRequest);
                // TODO(BG-59686): this is not doing anything if we don't check the return value, we should also move this check to happen after we invoke prebuildTransaction
                prebuildTxWithIntent.calledOnceWithExactly({
                    reqId,
                    recipients,
                    intentType: 'payment',
                });
                const txPrebuild = await tssSolWallet.prebuildTransaction({
                    reqId,
                    recipients,
                    type: 'transfer',
                });
                txPrebuild.should.deepEqual({
                    walletId: tssSolWallet.id(),
                    wallet: tssSolWallet,
                    txRequestId: 'id',
                    txHex: 'ababcdcd',
                    buildParams: {
                        recipients,
                        type: 'transfer',
                    },
                    feeInfo: {
                        fee: 5000,
                        feeString: '5000',
                    },
                });
            });
            it('should build a single recipient transfer with pending approval id if transaction is having one', async function () {
                const recipients = [
                    {
                        address: '6DadkZcx9JZgeQUDbHh12cmqCpaqehmVxv6sGy49jrah',
                        amount: '1000',
                    },
                ];
                const prebuildTxWithIntent = sandbox.stub(sdk_core_1.TssUtils.prototype, 'prebuildTxWithIntent');
                prebuildTxWithIntent.resolves({ ...txRequest, state: 'pendingApproval', pendingApprovalId: 'some-id' });
                prebuildTxWithIntent.calledOnceWithExactly({
                    reqId,
                    recipients,
                    intentType: 'payment',
                });
                const txPrebuild = await custodialTssSolWallet.prebuildTransaction({
                    reqId,
                    recipients,
                    type: 'transfer',
                });
                txPrebuild.should.deepEqual({
                    walletId: custodialTssSolWallet.id(),
                    wallet: custodialTssSolWallet,
                    txRequestId: 'id',
                    txHex: 'ababcdcd',
                    pendingApprovalId: 'some-id',
                    buildParams: {
                        recipients,
                        type: 'transfer',
                    },
                    feeInfo: {
                        fee: 5000,
                        feeString: '5000',
                    },
                });
            });
            it('should build a multiple recipient transfer transaction with memo', async function () {
                const recipients = [
                    {
                        address: '6DadkZcx9JZgeQUDbHh12cmqCpaqehmVxv6sGy49jrah',
                        amount: '1000',
                    },
                    {
                        address: '6DadkZcx9JZgeQUDbHh12cmqCpaqehmVxv6sGy49jrah',
                        amount: '2000',
                    },
                ];
                const prebuildTxWithIntent = sandbox.stub(sdk_core_1.TssUtils.prototype, 'prebuildTxWithIntent');
                prebuildTxWithIntent.resolves(txRequest);
                // TODO(BG-59686): this is not doing anything if we don't check the return value, we should also move this check to happen after we invoke prebuildTransaction
                prebuildTxWithIntent.calledOnceWithExactly({
                    reqId,
                    recipients,
                    intentType: 'payment',
                    memo: {
                        type: 'type',
                        value: 'test memo',
                    },
                });
                const txPrebuild = await tssSolWallet.prebuildTransaction({
                    reqId,
                    recipients,
                    type: 'transfer',
                    memo: {
                        type: 'type',
                        value: 'test memo',
                    },
                });
                txPrebuild.should.deepEqual({
                    walletId: tssSolWallet.id(),
                    wallet: tssSolWallet,
                    txRequestId: 'id',
                    txHex: 'ababcdcd',
                    buildParams: {
                        recipients,
                        memo: {
                            type: 'type',
                            value: 'test memo',
                        },
                        type: 'transfer',
                    },
                    feeInfo: {
                        fee: 5000,
                        feeString: '5000',
                    },
                });
            });
            it('should build an enable token transaction', async function () {
                const recipients = [];
                const tokenName = 'tcoin:tokenName';
                const prebuildTxWithIntent = sandbox.stub(sdk_core_1.TssUtils.prototype, 'prebuildTxWithIntent');
                prebuildTxWithIntent.resolves(txRequest);
                // TODO(BG-59686): this is not doing anything if we don't check the return value, we should also move this check to happen after we invoke prebuildTransaction
                prebuildTxWithIntent.calledOnceWithExactly({
                    reqId,
                    recipients,
                    intentType: 'createAccount',
                    memo: {
                        type: 'type',
                        value: 'test memo',
                    },
                    tokenName,
                });
                const txPrebuild = await tssSolWallet.prebuildTransaction({
                    reqId,
                    recipients,
                    type: 'enabletoken',
                    memo: {
                        type: 'type',
                        value: 'test memo',
                    },
                    tokenName,
                });
                txPrebuild.should.deepEqual({
                    walletId: tssSolWallet.id(),
                    wallet: tssSolWallet,
                    txRequestId: 'id',
                    txHex: 'ababcdcd',
                    buildParams: {
                        recipients,
                        memo: {
                            type: 'type',
                            value: 'test memo',
                        },
                        type: 'enabletoken',
                        tokenName,
                    },
                    feeInfo: {
                        fee: 5000,
                        feeString: '5000',
                    },
                });
            });
            it('should build an enable token transaction for cold wallets', async function () {
                const recipients = [];
                const tokenName = 'tcoin:tokenName';
                const prebuildTxWithIntent = sandbox.stub(sdk_core_1.TssUtils.prototype, 'prebuildTxWithIntent');
                txRequest.walletType = 'cold';
                prebuildTxWithIntent.resolves(txRequest);
                prebuildTxWithIntent.calledOnceWithExactly({
                    reqId,
                    recipients,
                    intentType: 'createAccount',
                    memo: {
                        type: 'type',
                        value: 'test memo',
                    },
                    tokenName,
                });
                const txPrebuild = await tssSolWallet.prebuildTransaction({
                    reqId,
                    recipients,
                    type: 'enabletoken',
                    memo: {
                        type: 'type',
                        value: 'test memo',
                    },
                    tokenName,
                });
                txPrebuild.should.deepEqual({
                    walletId: tssSolWallet.id(),
                    wallet: tssSolWallet,
                    txRequestId: 'id',
                    txHex: 'ababcdcd',
                    buildParams: {
                        recipients,
                        memo: {
                            type: 'type',
                            value: 'test memo',
                        },
                        type: 'enabletoken',
                        tokenName,
                    },
                    feeInfo: {
                        fee: 5000,
                        feeString: '5000',
                    },
                });
            });
            it('should fail for non-transfer transaction types', async function () {
                await tssSolWallet
                    .prebuildTransaction({
                    reqId,
                    recipients: [
                        {
                            address: '6DadkZcx9JZgeQUDbHh12cmqCpaqehmVxv6sGy49jrah',
                            amount: '1000',
                        },
                    ],
                    type: 'stake',
                })
                    .should.be.rejectedWith('transaction type not supported: stake');
            });
            it('should fail for full api version compatibility', async function () {
                await custodialTssSolWallet
                    .prebuildTransaction({
                    reqId,
                    apiVersion: 'lite',
                    recipients: [
                        {
                            address: '6DadkZcx9JZgeQUDbHh12cmqCpaqehmVxv6sGy49jrah',
                            amount: '1000',
                        },
                    ],
                    type: 'transfer',
                })
                    .should.be.rejectedWith('For non self-custodial (hot) tss wallets, parameter `apiVersion` must be `full`.');
            });
            it('should build a single recipient transfer transaction for full', async function () {
                const recipients = [
                    {
                        address: '6DadkZcx9JZgeQUDbHh12cmqCpaqehmVxv6sGy49jrah',
                        amount: '1000',
                    },
                ];
                const prebuildTxWithIntent = sandbox.stub(sdk_core_1.TssUtils.prototype, 'prebuildTxWithIntent');
                prebuildTxWithIntent.resolves(txRequestFull);
                // TODO(BG-59686): this is not doing anything if we don't check the return value, we should also move this check to happen after we invoke prebuildTransaction
                prebuildTxWithIntent.calledOnceWithExactly({
                    reqId,
                    recipients,
                    intentType: 'payment',
                }, 'full');
                const txPrebuild = await custodialTssSolWallet.prebuildTransaction({
                    reqId,
                    recipients,
                    type: 'transfer',
                });
                txPrebuild.should.deepEqual({
                    walletId: tssSolWallet.id(),
                    wallet: custodialTssSolWallet,
                    txRequestId: 'id',
                    txHex: 'ababcdcd',
                    buildParams: {
                        recipients,
                        type: 'transfer',
                    },
                    feeInfo: {
                        fee: 5000,
                        feeString: '5000',
                    },
                });
            });
            it('should call prebuildTxWithIntent with the correct params for eth transfers', async function () {
                const recipients = [
                    {
                        address: '0xAB100912e133AA06cEB921459aaDdBd62381F5A3',
                        amount: '1000',
                    },
                ];
                const feeOptions = {
                    maxFeePerGas: 3000000000,
                    maxPriorityFeePerGas: 2000000000,
                };
                const prebuildTxWithIntent = sandbox.stub(sdk_core_1.ECDSAUtils.EcdsaUtils.prototype, 'prebuildTxWithIntent');
                prebuildTxWithIntent.resolves(txRequestFull);
                await tssEthWallet.prebuildTransaction({
                    reqId,
                    recipients,
                    type: 'transfer',
                    feeOptions,
                });
                sinon.assert.calledOnce(prebuildTxWithIntent);
                const args = prebuildTxWithIntent.args[0];
                args[0].recipients.should.deepEqual(recipients);
                args[0].feeOptions.should.deepEqual(feeOptions);
                args[0].intentType.should.equal('payment');
                args[1].should.equal('full');
            });
            it('should call prebuildTxWithIntent with the correct params for eth transfertokens', async function () {
                const recipients = [
                    {
                        address: '0xAB100912e133AA06cEB921459aaDdBd62381F5A3',
                        amount: '1000',
                        tokenName: 'gterc18dp',
                    },
                ];
                const feeOptions = {
                    maxFeePerGas: 3000000000,
                    maxPriorityFeePerGas: 2000000000,
                };
                const prebuildTxWithIntent = sandbox.stub(sdk_core_1.ECDSAUtils.EcdsaUtils.prototype, 'prebuildTxWithIntent');
                prebuildTxWithIntent.resolves(txRequestFull);
                await tssEthWallet.prebuildTransaction({
                    reqId,
                    recipients,
                    type: 'transfertoken',
                    isTss: true,
                    feeOptions,
                });
                sinon.assert.calledOnce(prebuildTxWithIntent);
                const args = prebuildTxWithIntent.args[0];
                args[0].recipients.should.deepEqual(recipients);
                args[0].feeOptions.should.deepEqual(feeOptions);
                args[0].isTss.should.equal(true);
                args[0].intentType.should.equal('transferToken');
                args[1].should.equal('full');
            });
            it('should call prebuildTxWithIntent with the correct params for eth accelerations', async function () {
                const recipients = [
                    {
                        address: '0xAB100912e133AA06cEB921459aaDdBd62381F5A3',
                        amount: '1000',
                        tokenName: 'gterc18dp',
                    },
                ];
                const feeOptions = {
                    maxFeePerGas: 3000000000,
                    maxPriorityFeePerGas: 2000000000,
                };
                const lowFeeTxid = '0x6ea07f9420f4676be6478ab1660eb92444a7c663e0e24bece929f715e882e0cf';
                const prebuildTxWithIntent = sandbox.stub(sdk_core_1.ECDSAUtils.EcdsaUtils.prototype, 'prebuildTxWithIntent');
                prebuildTxWithIntent.resolves(txRequestFull);
                await tssEthWallet.prebuildTransaction({
                    reqId,
                    recipients,
                    type: 'acceleration',
                    feeOptions,
                    lowFeeTxid,
                });
                sinon.assert.calledOnce(prebuildTxWithIntent);
                const args = prebuildTxWithIntent.args[0];
                args[0].should.not.have.property('recipients');
                args[0].feeOptions.should.deepEqual(feeOptions);
                args[0].lowFeeTxid.should.equal(lowFeeTxid);
                args[0].intentType.should.equal('acceleration');
                args[1].should.equal('full');
            });
            it('should call prebuildTxWithIntent with the correct params for eth accelerations for receive address', async function () {
                const recipients = [
                    {
                        address: '0xAB100912e133AA06cEB921459aaDdBd62381F5A3',
                        amount: '1000',
                        tokenName: 'gterc18dp',
                    },
                ];
                const feeOptions = {
                    maxFeePerGas: 3000000000,
                    maxPriorityFeePerGas: 2000000000,
                };
                const lowFeeTxid = '0x6ea07f9420f4676be6478ab1660eb92444a7c663e0e24bece929f715e882e0cf';
                const receiveAddress = '0x062176bc9345da3e8ee90361b0cf6ff883ba7206';
                const prebuildTxWithIntent = sandbox.stub(sdk_core_1.ECDSAUtils.EcdsaUtils.prototype, 'prebuildTxWithIntent');
                prebuildTxWithIntent.resolves(txRequestFull);
                await tssEthWallet.prebuildTransaction({
                    reqId,
                    recipients,
                    type: 'acceleration',
                    feeOptions,
                    lowFeeTxid,
                    receiveAddress,
                });
                sinon.assert.calledOnce(prebuildTxWithIntent);
                const args = prebuildTxWithIntent.args[0];
                args[0].should.not.have.property('recipients');
                args[0].feeOptions.should.deepEqual(feeOptions);
                args[0].lowFeeTxid.should.equal(lowFeeTxid);
                args[0].receiveAddress.should.equal(receiveAddress);
                args[0].intentType.should.equal('acceleration');
                args[1].should.equal('full');
            });
            it('should call prebuildTxWithIntent with the correct params for eth fillNonce', async function () {
                const feeOptions = {
                    maxFeePerGas: 3000000000,
                    maxPriorityFeePerGas: 2000000000,
                };
                const prebuildTxWithIntent = sandbox.stub(sdk_core_1.ECDSAUtils.EcdsaUtils.prototype, 'prebuildTxWithIntent');
                prebuildTxWithIntent.resolves(txRequestFull);
                const nonce = '1';
                const comment = 'fillNonce comment';
                await tssEthWallet.prebuildTransaction({
                    reqId,
                    type: 'fillNonce',
                    feeOptions,
                    nonce,
                    comment,
                });
                sinon.assert.calledOnce(prebuildTxWithIntent);
                const args = prebuildTxWithIntent.args[0];
                args[0].should.not.have.property('recipients');
                args[0].feeOptions.should.deepEqual(feeOptions);
                args[0].nonce.should.equal(nonce);
                args[0].intentType.should.equal('fillNonce');
                args[0].comment.should.equal(comment);
                args[1].should.equal('full');
            });
            it('should call prebuildTxWithIntent with the correct params for eth fillNonce for receive address nonce filling tx', async function () {
                const feeOptions = {
                    maxFeePerGas: 3000000000,
                    maxPriorityFeePerGas: 2000000000,
                };
                const prebuildTxWithIntent = sandbox.stub(sdk_core_1.ECDSAUtils.EcdsaUtils.prototype, 'prebuildTxWithIntent');
                prebuildTxWithIntent.resolves(txRequestFull);
                const nonce = '1';
                const comment = 'fillNonce comment';
                const receiveAddress = '0x062176bc9345da3e8ee90361b0cf6ff883ba7206';
                await tssEthWallet.prebuildTransaction({
                    reqId,
                    type: 'fillNonce',
                    feeOptions,
                    nonce,
                    receiveAddress,
                    comment,
                });
                sinon.assert.calledOnce(prebuildTxWithIntent);
                const args = prebuildTxWithIntent.args[0];
                args[0].should.not.have.property('recipients');
                args[0].feeOptions.should.deepEqual(feeOptions);
                args[0].nonce.should.equal(nonce);
                args[0].intentType.should.equal('fillNonce');
                args[0].comment.should.equal(comment);
                args[0].receiveAddress.should.equal(receiveAddress);
                args[1].should.equal('full');
            });
            it('should call prebuildTxWithIntent with the correct feeOptions when passing using the legacy format', async function () {
                const recipients = [
                    {
                        address: '0xAB100912e133AA06cEB921459aaDdBd62381F5A3',
                        amount: '1000',
                    },
                ];
                const expectedFeeOptions = {
                    maxFeePerGas: 3000000000,
                    maxPriorityFeePerGas: 2000000000,
                    gasLimit: undefined,
                };
                const prebuildTxWithIntent = sandbox.stub(sdk_core_1.ECDSAUtils.EcdsaUtils.prototype, 'prebuildTxWithIntent');
                prebuildTxWithIntent.resolves(txRequestFull);
                await tssEthWallet.prebuildTransaction({
                    reqId,
                    recipients,
                    type: 'transfer',
                    eip1559: {
                        maxFeePerGas: expectedFeeOptions.maxFeePerGas.toString(),
                        maxPriorityFeePerGas: expectedFeeOptions.maxPriorityFeePerGas.toString(),
                    },
                });
                sinon.assert.calledOnce(prebuildTxWithIntent);
                const args = prebuildTxWithIntent.args[0];
                args[0].feeOptions.should.deepEqual(expectedFeeOptions);
            });
            it('populate intent should return valid eth acceleration intent', async function () {
                const mpcUtils = new sdk_core_1.ECDSAUtils.EcdsaUtils(bitgo, bitgo.coin('hteth'));
                const feeOptions = {
                    maxFeePerGas: 3000000000,
                    maxPriorityFeePerGas: 2000000000,
                };
                const lowFeeTxid = '0x6ea07f9420f4676be6478ab1660eb92444a7c663e0e24bece929f715e882e0cf';
                const intent = mpcUtils.populateIntent(bitgo.coin('hteth'), {
                    reqId,
                    intentType: 'acceleration',
                    lowFeeTxid,
                    feeOptions,
                });
                intent.should.have.property('recipients', undefined);
                intent.feeOptions.should.deepEqual(feeOptions);
                intent.txid.should.equal(lowFeeTxid);
                intent.intentType.should.equal('acceleration');
            });
            it('populate intent should return valid eth acceleration intent for receive address', async function () {
                const mpcUtils = new sdk_core_1.ECDSAUtils.EcdsaUtils(bitgo, bitgo.coin('hteth'));
                const feeOptions = {
                    maxFeePerGas: 3000000000,
                    maxPriorityFeePerGas: 2000000000,
                };
                const lowFeeTxid = '0x6ea07f9420f4676be6478ab1660eb92444a7c663e0e24bece929f715e882e0cf';
                const receiveAddress = '0x062176bc9345da3e8ee90361b0cf6ff883ba7206';
                const intent = mpcUtils.populateIntent(bitgo.coin('hteth'), {
                    reqId,
                    intentType: 'acceleration',
                    lowFeeTxid,
                    receiveAddress,
                    feeOptions,
                });
                intent.should.have.property('recipients', undefined);
                intent.feeOptions.should.deepEqual(feeOptions);
                intent.txid.should.equal(lowFeeTxid);
                intent.receiveAddress.should.equal(receiveAddress);
                intent.intentType.should.equal('acceleration');
            });
            it('populate intent should return valid eth fillNonce intent', async function () {
                const mpcUtils = new sdk_core_1.ECDSAUtils.EcdsaUtils(bitgo, bitgo.coin('hteth'));
                const feeOptions = {
                    maxFeePerGas: 3000000000,
                    maxPriorityFeePerGas: 2000000000,
                };
                const nonce = '1';
                const intent = mpcUtils.populateIntent(bitgo.coin('hteth'), {
                    reqId,
                    intentType: 'fillNonce',
                    nonce,
                    feeOptions,
                });
                intent.should.have.property('recipients', undefined);
                intent.feeOptions.should.deepEqual(feeOptions);
                intent.nonce.should.equal(nonce);
                intent.intentType.should.equal('fillNonce');
            });
            it('populate intent should return valid eth fillNonce intent for receive address nonce filling tx', async function () {
                const mpcUtils = new sdk_core_1.ECDSAUtils.EcdsaUtils(bitgo, bitgo.coin('hteth'));
                const feeOptions = {
                    maxFeePerGas: 3000000000,
                    maxPriorityFeePerGas: 2000000000,
                };
                const nonce = '1';
                const receiveAddress = '0x062176bc9345da3e8ee90361b0cf6ff883ba7206';
                const intent = mpcUtils.populateIntent(bitgo.coin('hteth'), {
                    reqId,
                    intentType: 'fillNonce',
                    nonce,
                    receiveAddress,
                    feeOptions,
                });
                intent.should.have.property('recipients', undefined);
                intent.feeOptions.should.deepEqual(feeOptions);
                intent.nonce.should.equal(nonce);
                intent.receiveAddress.should.equal(receiveAddress);
                intent.intentType.should.equal('fillNonce');
            });
            it('should populate intent with custodianTransactionId', async function () {
                const mpcUtils = new sdk_core_1.ECDSAUtils.EcdsaUtils(bitgo, bitgo.coin('hteth'));
                const feeOptions = {
                    maxFeePerGas: 3000000000,
                    maxPriorityFeePerGas: 2000000000,
                };
                const nonce = '1';
                const intent = mpcUtils.populateIntent(bitgo.coin('hteth'), {
                    custodianTransactionId: 'unittest',
                    reqId,
                    intentType: 'fillNonce',
                    nonce,
                    feeOptions,
                    isTss: true,
                });
                intent.custodianTransactionId.should.equal('unittest');
                intent.should.have.property('recipients', undefined);
                intent.feeOptions.should.deepEqual(feeOptions);
                intent.nonce.should.equal(nonce);
                intent.isTss.should.equal(true);
                intent.intentType.should.equal('fillNonce');
            });
            it('should build a single recipient transfer transaction providing apiVersion parameter as "full" ', async function () {
                const recipients = [
                    {
                        address: '6DadkZcx9JZgeQUDbHh12cmqCpaqehmVxv6sGy49jrah',
                        amount: '1000',
                    },
                ];
                const prebuildTxWithIntent = sandbox.stub(sdk_core_1.TssUtils.prototype, 'prebuildTxWithIntent');
                prebuildTxWithIntent.resolves(txRequestFull);
                prebuildTxWithIntent.calledOnceWithExactly({
                    reqId,
                    recipients,
                    intentType: 'payment',
                }, 'full');
                const txPrebuild = await custodialTssSolWallet.prebuildTransaction({
                    reqId,
                    apiVersion: 'full',
                    recipients,
                    type: 'transfer',
                });
                txPrebuild.should.deepEqual({
                    walletId: tssSolWallet.id(),
                    wallet: custodialTssSolWallet,
                    txRequestId: 'id',
                    txHex: 'ababcdcd',
                    buildParams: {
                        apiVersion: 'full',
                        recipients,
                        type: 'transfer',
                    },
                    feeInfo: {
                        fee: 5000,
                        feeString: '5000',
                    },
                });
            });
        });
        describe('Transaction signing', function () {
            it('should sign transaction', async function () {
                const signTxRequest = sandbox.stub(sdk_core_1.TssUtils.prototype, 'signTxRequest');
                signTxRequest.resolves(txRequest);
                // TODO(BG-59686): this is not doing anything if we don't check the return value, we should also move this check to happen after we invoke signTransaction
                signTxRequest.calledOnceWithExactly({ txRequest, prv: 'secretKey', reqId });
                const txPrebuild = {
                    walletId: tssSolWallet.id(),
                    wallet: tssSolWallet,
                    txRequestId: 'id',
                    txHex: 'ababcdcd',
                };
                const signedTransaction = await tssSolWallet.signTransaction({
                    reqId,
                    txPrebuild,
                    prv: 'sercretKey',
                });
                signedTransaction.should.deepEqual(txRequest);
            });
            it('should fail to sign transaction without txRequestId', async function () {
                const txPrebuild = {
                    walletId: tssSolWallet.id(),
                    wallet: tssSolWallet,
                    txHex: 'ababcdcd',
                };
                await tssSolWallet
                    .signTransaction({
                    reqId,
                    txPrebuild,
                    prv: 'sercretKey',
                })
                    .should.be.rejectedWith('txRequestId required to sign transactions with TSS');
            });
        });
        describe('getUserKeyAndSignTssTransaction', function () {
            ['eddsa', 'ecdsa'].forEach((keyCurve) => {
                describe(keyCurve, () => {
                    const wallet = keyCurve === 'eddsa' ? tssSolWallet : tssEthWallet;
                    let getKeysStub;
                    let signTransactionStub;
                    beforeEach(function () {
                        getKeysStub = sandbox.stub(sdk_core_1.Keychains.prototype, 'getKeysForSigning');
                        signTransactionStub = sandbox
                            .stub(sdk_core_1.Wallet.prototype, 'signTransaction')
                            .resolves({ ...txRequestFull, state: 'signed' });
                    });
                    afterEach(function () {
                        sandbox.verifyAndRestore();
                    });
                    it('should sign transaction', async function () {
                        getKeysStub.resolves([
                            {
                                commonKeychain: 'test',
                                id: '',
                                pub: '',
                                type: 'tss',
                                encryptedPrv: '{"iv":"15FsbDVI1zG9OggD8YX+Hg==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"hHbNH3Sz/aU=","ct":"WoNVKz7afiRxXI2w/YkzMdMyoQg/B15u1Q8aQgi96jJZ9wk6TIaSEc6bXFH3AHzD9MdJCWJQUpRhoQc/rgytcn69scPTjKeeyVMElGCxZdFVS/psQcNE+lue3//2Zlxj+6t1NkvYO+8yAezSMRBK5OdftXEjNQI="}',
                            },
                        ]);
                        const params = {
                            walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_PASSPHRASE,
                            txRequestId: 'id',
                        };
                        const response = await wallet.getUserKeyAndSignTssTransaction(params);
                        response.should.deepEqual({ ...txRequestFull, state: 'signed' });
                        getKeysStub.calledOnce.should.be.true();
                        signTransactionStub.calledOnce.should.be.true();
                    });
                    it('should throw if the keychain doesnt have the encryptedKey', async function () {
                        getKeysStub.resolves([{ commonKeychain: 'test', id: '', pub: '', type: 'tss' }]);
                        const params = {
                            walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_PASSPHRASE,
                            txRequestId: 'id',
                        };
                        await wallet
                            .getUserKeyAndSignTssTransaction(params)
                            .should.be.rejectedWith('the user keychain does not have property encryptedPrv');
                        getKeysStub.calledOnce.should.be.true();
                        signTransactionStub.notCalled.should.be.true();
                    });
                    it('should throw if password is invalid', async function () {
                        getKeysStub.resolves([
                            {
                                commonKeychain: 'test',
                                id: '',
                                pub: '',
                                type: 'tss',
                                encryptedPrv: '{"iv":"15FsbDVI1zG9OggD8YX+Hg==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"hHbNH3Sz/aU=","ct":"WoNVKz7afiRxXI2w/YkzMdMyoQg/B15u1Q8aQgi96jJZ9wk6TIaSEc6bXFH3AHzD9MdJCWJQUpRhoQc/rgytcn69scPTjKeeyVMElGCxZdFVS/psQcNE+lue3//2Zlxj+6t1NkvYO+8yAezSMRBK5OdftXEjNQI="}',
                            },
                        ]);
                        const params = {
                            walletPassphrase: 'randompass',
                            txRequestId: 'id',
                        };
                        await wallet
                            .getUserKeyAndSignTssTransaction(params)
                            .should.be.rejectedWith(`unable to decrypt keychain with the given wallet passphrase`);
                        getKeysStub.calledOnce.should.be.true();
                        signTransactionStub.notCalled.should.be.true();
                    });
                });
            });
        });
        describe('signAndSendTxRequest', function () {
            const exampleSignedTx = {
                txHex: '0x123',
                txid: '0x456',
                status: 'signed',
            };
            afterEach(async function () {
                sandbox.restore();
            });
            it('should sign lite transaction', async function () {
                const getUserKeyAndSignTssTxSpy = sandbox.stub(tssSolWallet, 'getUserKeyAndSignTssTransaction');
                getUserKeyAndSignTssTxSpy.resolves(exampleSignedTx);
                const submitTxSpy = sandbox.stub(tssSolWallet, 'submitTransaction');
                submitTxSpy.resolves(exampleSignedTx);
                const signedTx = await tssSolWallet.signAndSendTxRequest({
                    walletPassphrase: 'passphrase',
                    txRequestId: 'id',
                    isTxRequestFull: false,
                });
                sandbox.assert.calledOnce(getUserKeyAndSignTssTxSpy);
                sandbox.assert.calledOnce(submitTxSpy);
                signedTx.should.deepEqual(exampleSignedTx);
            });
            it('should sign full transaction', async function () {
                const deleteSignatureSharesSpy = sandbox.stub(sdk_core_1.TssUtils.prototype, 'deleteSignatureShares');
                const getUserKeyAndSignTssTxSpy = sandbox.stub(tssSolWallet, 'getUserKeyAndSignTssTransaction');
                getUserKeyAndSignTssTxSpy.resolves(exampleSignedTx);
                const signedTx = await tssSolWallet.signAndSendTxRequest({
                    walletPassphrase: 'passphrase',
                    txRequestId: 'id',
                    isTxRequestFull: true,
                });
                sandbox.assert.calledOnce(deleteSignatureSharesSpy);
                sandbox.assert.calledOnce(getUserKeyAndSignTssTxSpy);
                signedTx.should.deepEqual(exampleSignedTx);
            });
        });
        describe('Message Signing', function () {
            const txHash = '0xrrrsss1b';
            const txRequestForMessageSigning = {
                txRequestId: reqId.toString(),
                transactions: [],
                intent: {
                    intentType: 'signMessage',
                },
                date: new Date().toISOString(),
                latest: true,
                state: 'pendingUserSignature',
                userId: 'userId',
                walletType: 'hot',
                policiesChecked: false,
                version: 1,
                walletId: 'walletId',
                unsignedTxs: [],
                unsignedMessages: [],
                messages: [
                    {
                        state: 'signed',
                        messageRaw: 'hello world',
                        derivationPath: 'm/0',
                        signatureShares: [{ from: sdk_core_1.SignatureShareType.USER, to: sdk_core_1.SignatureShareType.USER, share: '' }],
                        combineSigShare: '0:rrr:sss:3',
                        txHash,
                    },
                ],
            };
            let signTxRequestForMessage;
            const messageSigningCoins = ['teth', 'tpolygon'];
            const messageRaw = 'test';
            const expected = {
                txRequestId: reqId.toString(),
                txHash,
                signature: txHash,
                messageRaw,
                coin: 'teth',
                messageEncoded: Buffer.from('\u0019Ethereum Signed Message:\n4test').toString('hex'),
            };
            beforeEach(async function () {
                signTxRequestForMessage = sandbox.stub(sdk_core_1.ECDSAUtils.EcdsaUtils.prototype, 'signTxRequestForMessage');
                signTxRequestForMessage.resolves(txRequestForMessageSigning);
                sandbox
                    .stub(sdk_core_1.Keychains.prototype, 'getKeysForSigning')
                    .resolves([{ commonKeychain: 'test', id: '', pub: '', type: 'independent' }]);
                sinon.stub(sdk_core_1.Ecdsa.prototype, 'verify').resolves(true);
            });
            afterEach(async function () {
                sinon.restore();
                nock.cleanAll();
            });
            it('should throw error for unsupported coins', async function () {
                await tssSolWallet
                    .signMessage({
                    reqId,
                    message: { messageRaw },
                    prv: 'secretKey',
                })
                    .should.be.rejectedWith('Message signing not supported for Testnet Solana');
            });
            messageSigningCoins.map((coinName) => {
                const expectedWithCoinField = { ...expected, coin: 'teth' };
                tssEthWallet = new sdk_core_1.Wallet(bitgo, bitgo.coin(coinName), ethWalletData);
                const txRequestId = txRequestForMessageSigning.txRequestId;
                it('should sign message', async function () {
                    const signMessageTssSpy = sinon.spy(tssEthWallet, 'signMessageTss');
                    nock(bgUrl)
                        .get(`/api/v2/wallet/${tssEthWallet.id()}/txrequests?txRequestIds=${txRequestForMessageSigning.txRequestId}&latest=true`)
                        .reply(200, { txRequests: [txRequestForMessageSigning] });
                    const signMessage = await tssEthWallet.signMessage({
                        reqId,
                        message: { messageRaw, txRequestId },
                        prv: 'secretKey',
                    });
                    signMessage.should.deepEqual(expectedWithCoinField);
                    const actualArg = signMessageTssSpy.getCalls()[0].args[0];
                    actualArg.message?.messageEncoded?.should.equal(Buffer.from(`\u0019Ethereum Signed Message:\n${messageRaw.length}${messageRaw}`).toString('hex'));
                });
                it('should sign message when custodianMessageId is provided', async function () {
                    const signMessageTssSpy = sinon.spy(tssEthWallet, 'signMessageTss');
                    nock(bgUrl).post(`/api/v2/wallet/${tssEthWallet.id()}/txrequests`).reply(200, txRequestForMessageSigning);
                    const signMessage = await tssEthWallet.signMessage({
                        custodianMessageId: 'unittest',
                        reqId,
                        message: { messageRaw },
                        prv: 'secretKey',
                    });
                    signMessage.should.deepEqual(expectedWithCoinField);
                    const actualArg = signMessageTssSpy.getCalls()[0].args[0];
                    actualArg.message?.messageEncoded?.should.equal(Buffer.from(`\u0019Ethereum Signed Message:\n${messageRaw.length}${messageRaw}`).toString('hex'));
                });
                it('should sign message when txRequestId not provided', async function () {
                    const signMessageTssSpy = sinon.spy(tssEthWallet, 'signMessageTss');
                    nock(bgUrl).post(`/api/v2/wallet/${tssEthWallet.id()}/txrequests`).reply(200, txRequestForMessageSigning);
                    const signMessage = await tssEthWallet.signMessage({
                        reqId,
                        message: { messageRaw },
                        prv: 'secretKey',
                    });
                    signMessage.should.deepEqual(expectedWithCoinField);
                    const actualArg = signMessageTssSpy.getCalls()[0].args[0];
                    actualArg.message?.messageEncoded?.should.equal(Buffer.from(`\u0019Ethereum Signed Message:\n${messageRaw.length}${messageRaw}`).toString('hex'));
                });
                it('should fail to sign message with empty prv', async function () {
                    await tssEthWallet
                        .signMessage({
                        reqId,
                        message: { messageRaw, txRequestId },
                        prv: '',
                    })
                        .should.be.rejectedWith('keychain does not have property encryptedPrv');
                });
            });
        });
        describe('Typed Data Signing', function () {
            const txHash = '1901493fbf2ae1c27c3ced26a89070c6ab5d3fbf37ed778de9378e7703b7d1f116b3883077a61826129b98b622e54fc68c5008d1b1c16552e1eda6916f870d719220';
            const txRequestForTypedDataSigning = {
                txRequestId: reqId.toString(),
                transactions: [],
                intent: {
                    intentType: 'signMessage',
                },
                date: new Date().toISOString(),
                latest: true,
                state: 'pendingUserSignature',
                userId: 'userId',
                walletType: 'hot',
                policiesChecked: false,
                version: 1,
                walletId: 'walletId',
                unsignedTxs: [],
                unsignedMessages: [],
                messages: [
                    {
                        state: 'signed',
                        messageRaw: 'hello world',
                        derivationPath: 'm/0',
                        signatureShares: [{ from: sdk_core_1.SignatureShareType.USER, to: sdk_core_1.SignatureShareType.USER, share: '' }],
                        combineSigShare: '0:rrr:sss:3',
                        txHash,
                    },
                ],
            };
            let signTxRequestForMessage;
            const messageSigningCoins = ['teth', 'tpolygon'];
            const types = {
                EIP712Domain: [
                    {
                        name: 'name',
                        type: 'string',
                    },
                    {
                        name: 'version',
                        type: 'string',
                    },
                    {
                        name: 'chainId',
                        type: 'uint256',
                    },
                    {
                        name: 'verifyingContract',
                        type: 'address',
                    },
                ],
                Message: [{ name: 'data', type: 'string' }],
            };
            const typedMessage = {
                domain: {
                    name: 'bitgo',
                    version: '1',
                    chainId: 1,
                    verifyingContract: '0x0000000000000000000000000000000000000000',
                },
                primaryType: 'Message',
                types,
                message: { data: 'bitgo says hello!' },
            };
            const typedDataBase = {
                typedDataRaw: JSON.stringify(typedMessage),
                version: sdk_core_1.SignTypedDataVersion.V3,
            };
            beforeEach(async function () {
                signTxRequestForMessage = sandbox.stub(sdk_core_1.ECDSAUtils.EcdsaUtils.prototype, 'signTxRequestForMessage');
                signTxRequestForMessage.resolves(txRequestForTypedDataSigning);
                sandbox
                    .stub(sdk_core_1.Keychains.prototype, 'getKeysForSigning')
                    .resolves([{ commonKeychain: 'test', id: '', pub: '', type: 'independent' }]);
                sinon.stub(sdk_core_1.Ecdsa.prototype, 'verify').resolves(true);
            });
            afterEach(async function () {
                sinon.restore();
                nock.cleanAll();
            });
            it('should throw error for unsupported coins', async function () {
                await tssSolWallet
                    .signTypedData({
                    reqId,
                    typedData: typedDataBase,
                    prv: 'secretKey',
                })
                    .should.be.rejectedWith('Sign typed data not supported for Testnet Solana');
            });
            it('should throw error for sign typed data V1', async function () {
                const typedData = { ...typedDataBase };
                typedData.version = sdk_core_1.SignTypedDataVersion.V1;
                nock(bgUrl)
                    .get(`/api/v2/wallet/${tssEthWallet.id()}/txrequests?txRequestIds=${txRequestForTypedDataSigning.txRequestId}&latest=true`)
                    .reply(200, { txRequests: [txRequestForTypedDataSigning] });
                await tssEthWallet
                    .signTypedData({
                    reqId,
                    typedData,
                    prv: 'secretKey',
                })
                    .should.be.rejectedWith('SignTypedData v1 is not supported due to security concerns');
            });
            messageSigningCoins.map((coinName) => {
                tssEthWallet = new sdk_core_1.Wallet(bitgo, bitgo.coin(coinName), ethWalletData);
                const txRequestId = txRequestForTypedDataSigning.txRequestId;
                typedDataBase.txRequestId = txRequestId;
                const expected = {
                    txRequestId,
                    messageRaw: JSON.stringify(typedMessage),
                    signature: txHash,
                    txHash,
                    coin: 'teth',
                    messageEncoded: txHash,
                };
                describe(`sign typed data V3 for ${coinName}`, async function () {
                    const typedData = { ...typedDataBase };
                    typedData.version = sdk_core_1.SignTypedDataVersion.V3;
                    it('should sign typed data V3', async function () {
                        const signTypedDataTssSpy = sinon.spy(tssEthWallet, 'signTypedDataTss');
                        nock(bgUrl)
                            .get(`/api/v2/wallet/${tssEthWallet.id()}/txrequests?txRequestIds=${txRequestForTypedDataSigning.txRequestId}&latest=true`)
                            .reply(200, { txRequests: [txRequestForTypedDataSigning] });
                        const signedTypedData = await tssEthWallet.signTypedData({
                            reqId,
                            typedData,
                            prv: 'secretKey',
                        });
                        signedTypedData.should.deepEqual(expected);
                        const actualArg = signTypedDataTssSpy.getCalls()[0].args[0];
                        actualArg.typedData?.typedDataEncoded?.toString('hex').should.equal(txHash);
                    });
                    it('should sign typed data V3 when custodianMessageID is provided', async function () {
                        typedData.txRequestId = txRequestId;
                        const signTypedDataTssSpy = sinon.spy(tssEthWallet, 'signTypedDataTss');
                        nock(bgUrl)
                            .get(`/api/v2/wallet/${tssEthWallet.id()}/txrequests?txRequestIds=${txRequestForTypedDataSigning.txRequestId}&latest=true`)
                            .reply(200, { txRequests: [txRequestForTypedDataSigning] });
                        const signedTypedData = await tssEthWallet.signTypedData({
                            custodianMessageId: 'unittest',
                            reqId,
                            typedData,
                            prv: 'secretKey',
                        });
                        signedTypedData.should.deepEqual(expected);
                        const actualArg = signTypedDataTssSpy.getCalls()[0].args[0];
                        actualArg.typedData?.typedDataEncoded?.toString('hex').should.equal(txHash);
                    });
                    it('should fail to sign typed data V3 with empty prv', async function () {
                        await tssEthWallet
                            .signTypedData({
                            reqId,
                            typedData: typedDataBase,
                            prv: '',
                        })
                            .should.be.rejectedWith('keychain does not have property encryptedPrv');
                    });
                    it('should sign typed data V3 when txRequestId not provided ', async function () {
                        delete typedData.txRequestId;
                        const signedTypedDataTssSpy = sinon.spy(tssEthWallet, 'signTypedDataTss');
                        nock(bgUrl).post(`/api/v2/wallet/${tssEthWallet.id()}/txrequests`).reply(200, txRequestForTypedDataSigning);
                        const signedTypedData = await tssEthWallet.signTypedData({
                            reqId,
                            typedData,
                            prv: 'secretKey',
                        });
                        signedTypedData.should.deepEqual(expected);
                        const actualArg = signedTypedDataTssSpy.getCalls()[0].args[0];
                        actualArg.typedData?.typedDataEncoded?.toString('hex').should.equal(txHash);
                    });
                });
                describe(`sign typed data V4 for ${coinName}`, async function () {
                    const typedData = { ...typedDataBase };
                    typedData.version = sdk_core_1.SignTypedDataVersion.V4;
                    it('should sign typed data V4', async function () {
                        typedData.txRequestId = txRequestId;
                        nock(bgUrl)
                            .get(`/api/v2/wallet/${tssEthWallet.id()}/txrequests?txRequestIds=${txRequestForTypedDataSigning.txRequestId}&latest=true`)
                            .reply(200, { txRequests: [txRequestForTypedDataSigning] });
                        const signedTypedData = await tssEthWallet.signTypedData({
                            reqId,
                            typedData,
                            prv: 'secretKey',
                        });
                        signedTypedData.should.deepEqual(expected);
                    });
                    it('should sign typed data V4 when custodianMessageID is provided', async function () {
                        typedData.txRequestId = txRequestId;
                        nock(bgUrl)
                            .get(`/api/v2/wallet/${tssEthWallet.id()}/txrequests?txRequestIds=${txRequestForTypedDataSigning.txRequestId}&latest=true`)
                            .reply(200, { txRequests: [txRequestForTypedDataSigning] });
                        const signedTypedData = await tssEthWallet.signTypedData({
                            custodianMessageId: 'unittest',
                            reqId,
                            typedData,
                            prv: 'secretKey',
                        });
                        signedTypedData.should.deepEqual(expected);
                    });
                    it('should fail to sign typed data V4 with empty prv', async function () {
                        await tssEthWallet
                            .signTypedData({
                            reqId,
                            typedData: typedDataBase,
                            prv: '',
                        })
                            .should.be.rejectedWith('keychain does not have property encryptedPrv');
                    });
                    it('should sign typed data V4 when txRequestId not provided ', async function () {
                        delete typedData.txRequestId;
                        const signedTypedDataTssSpy = sinon.spy(tssEthWallet, 'signTypedDataTss');
                        nock(bgUrl).post(`/api/v2/wallet/${tssEthWallet.id()}/txrequests`).reply(200, txRequestForTypedDataSigning);
                        const signedTypedData = await tssEthWallet.signTypedData({
                            reqId,
                            typedData,
                            prv: 'secretKey',
                        });
                        signedTypedData.should.deepEqual(expected);
                        const actualArg = signedTypedDataTssSpy.getCalls()[0].args[0];
                        actualArg.typedData?.typedDataEncoded?.toString('hex').should.equal(txHash);
                    });
                });
            });
        });
        describe('Send Many', function () {
            const sendManyInput = {
                type: 'transfer',
                recipients: [
                    {
                        address: 'address',
                        amount: '1000',
                    },
                ],
                reqId: new sdk_core_1.RequestTracer(),
            };
            afterEach(function () {
                nock.cleanAll();
            });
            it('should send many', async function () {
                const signedTransaction = {
                    txRequestId: 'txRequestId',
                };
                const prebuildAndSignTransaction = sandbox.stub(tssSolWallet, 'prebuildAndSignTransaction');
                prebuildAndSignTransaction.resolves(signedTransaction);
                // TODO(BG-59686): this is not doing anything if we don't check the return value, we should also move this check to happen after we invoke sendMany
                prebuildAndSignTransaction.calledOnceWithExactly(sendManyInput);
                const sendTxRequest = sandbox.stub(sdk_core_1.TssUtils.prototype, 'sendTxRequest');
                sendTxRequest.resolves('sendTxResponse');
                // TODO(BG-59686): this is not doing anything if we don't check the return value, we should also move this check to happen after we invoke sendMany
                sendTxRequest.calledOnceWithExactly(signedTransaction.txRequestId);
                const sendMany = await tssSolWallet.sendMany(sendManyInput);
                sendMany.should.deepEqual('sendTxResponse');
            });
            it('should send many and call setRequestTracer', async function () {
                const signedTransaction = {
                    txRequestId: 'txRequestId',
                };
                const prebuildAndSignTransaction = sandbox.stub(tssSolWallet, 'prebuildAndSignTransaction');
                prebuildAndSignTransaction.resolves(signedTransaction);
                prebuildAndSignTransaction.calledOnceWithExactly(sendManyInput);
                const sendTxRequest = sandbox.stub(sdk_core_1.TssUtils.prototype, 'sendTxRequest');
                sendTxRequest.resolves('sendTxResponse');
                sendTxRequest.calledOnceWithExactly(signedTransaction.txRequestId);
                const setRequestTracerSpy = sinon.spy(bitgo, 'setRequestTracer');
                setRequestTracerSpy.withArgs(sendManyInput.reqId);
                const sendMany = await tssSolWallet.sendMany(sendManyInput);
                sendMany.should.deepEqual('sendTxResponse');
                sinon.assert.calledOnce(setRequestTracerSpy);
                setRequestTracerSpy.restore();
            });
            it('should return transfer from sendMany for apiVersion=full', async function () {
                const wallet = new sdk_core_1.Wallet(bitgo, tsol, {
                    ...walletData,
                    type: 'custodial',
                });
                const signedTxResult = {
                    txRequestId: 'txRequestId',
                };
                const txRequest = {
                    date: new Date().toString(),
                    intent: 'payment',
                    latest: false,
                    policiesChecked: false,
                    state: 'delivered',
                    unsignedTxs: [],
                    userId: 'unit-test',
                    version: 0,
                    walletId: wallet.id(),
                    walletType: wallet.type() ?? 'hot',
                    txRequestId: signedTxResult.txRequestId,
                    transactions: [
                        {
                            state: 'delivered',
                            signedTx: {
                                id: 'txid',
                                tx: 'tx',
                            },
                            unsignedTx: 'something',
                            signatureShares: [],
                        },
                    ],
                };
                const transfer = {
                    id: 'transferId',
                    state: 'signed',
                    txid: 'txid',
                };
                const prebuildAndSignTransaction = sandbox.stub(wallet, 'prebuildAndSignTransaction').resolves(signedTxResult);
                const txRequestNock = nock(bgUrl)
                    .persist()
                    .get(`/api/v2/wallet/${walletData.id}/txrequests?txRequestIds=${signedTxResult.txRequestId}&latest=true`)
                    .reply(200, { txRequests: [txRequest] });
                const createTransferNock = nock(bgUrl)
                    .persist()
                    .post(`/api/v2/wallet/${walletData.id}/txrequests/${signedTxResult.txRequestId}/transfers`)
                    .reply(200, transfer);
                const input = {
                    type: 'transfer',
                    recipients: [
                        {
                            address: 'address',
                            amount: '1000',
                        },
                    ],
                    apiVersion: 'full',
                };
                const sendManyResult = await wallet.sendMany(input);
                prebuildAndSignTransaction.calledOnceWithExactly(input);
                txRequestNock.isDone().should.be.true();
                createTransferNock.isDone().should.be.true();
                sendManyResult.should.deepEqual({
                    txRequest,
                    transfer,
                    txid: 'txid',
                    tx: 'tx',
                    status: 'signed',
                });
            });
            it('should return pendingApproval from sendMany for apiVersion=full', async function () {
                const wallet = new sdk_core_1.Wallet(bitgo, tsol, {
                    ...walletData,
                    type: 'hot',
                });
                const signedTxResult = {
                    txRequestId: 'txRequestId',
                };
                const txRequest = {
                    txRequestId: signedTxResult.txRequestId,
                    date: new Date().toString(),
                    intent: 'payment',
                    latest: false,
                    policiesChecked: false,
                    state: 'pendingApproval',
                    unsignedTxs: [],
                    userId: 'unit-test',
                    version: 0,
                    walletId: wallet.id(),
                    walletType: wallet.type() ?? 'hot',
                    pendingApprovalId: 'some-pending-approval-id',
                    transactions: [
                        {
                            state: 'initialized',
                            unsignedTx: 'something',
                            signatureShares: [],
                        },
                    ],
                };
                const transfer = {
                    id: 'transferId',
                    state: 'signed',
                    txid: 'txid',
                };
                const pendingApproval = {
                    id: 'some-pending-approval-id',
                    wallet: wallet.id(),
                    info: {
                        type: 'transactionRequestFull',
                    },
                    txRequestId: txRequest.txRequestId,
                };
                const prebuildAndSignTransaction = sandbox.stub(wallet, 'prebuildAndSignTransaction').resolves(signedTxResult);
                const txRequestNock = nock(bgUrl)
                    .persist()
                    .get(`/api/v2/wallet/${walletData.id}/txrequests?txRequestIds=${txRequest.txRequestId}&latest=true`)
                    .reply(200, { txRequests: [txRequest] });
                const createTransferNock = nock(bgUrl)
                    .persist()
                    .post(`/api/v2/wallet/${walletData.id}/txrequests/${txRequest.txRequestId}/transfers`)
                    .reply(200, transfer);
                const getPendingApprovalNock = nock(bgUrl)
                    .persist()
                    .get(`/api/v2/${wallet.coin()}/pendingapprovals/${txRequest.pendingApprovalId}`)
                    .reply(200, pendingApproval);
                const input = {
                    type: 'transfer',
                    recipients: [
                        {
                            address: 'address',
                            amount: '1000',
                        },
                    ],
                    apiVersion: 'full',
                };
                const sendManyResult = await wallet.sendMany(input);
                prebuildAndSignTransaction.calledOnceWithExactly(input);
                txRequestNock.isDone().should.be.true();
                createTransferNock.isDone().should.be.true();
                getPendingApprovalNock.isDone().should.be.true();
                sendManyResult.should.deepEqual({ pendingApproval, txRequest });
            });
            it('should fail if txRequestId is missing from prebuild', async function () {
                const signedTransaction = {
                    txHex: 'deadbeef',
                };
                const prebuildAndSignTransaction = sandbox.stub(tssSolWallet, 'prebuildAndSignTransaction');
                prebuildAndSignTransaction.resolves(signedTransaction);
                // TODO(BG-59686): this is not doing anything if we don't check the return value, we should also move this check to happen after we invoke sendMany
                prebuildAndSignTransaction.calledOnceWithExactly(sendManyInput);
                await tssSolWallet
                    .sendMany(sendManyInput)
                    .should.be.rejectedWith('txRequestId missing from signed transaction');
            });
        });
        describe('Submit transaction', function () {
            it('should submit transaction with txRequestId', async function () {
                const nockSendTx = nock(bgUrl)
                    .persist(false)
                    .post(tssSolWallet.url('/tx/send').replace(bgUrl, ''))
                    .reply(200, { message: 'success' });
                const submittedTx = await tssSolWallet.submitTransaction({
                    txRequestId: 'id',
                });
                submittedTx.should.deepEqual({ message: 'success' });
                nockSendTx.isDone().should.be.true();
            });
            it('should fail when txRequestId and txHex are both provided', async function () {
                await tssSolWallet
                    .submitTransaction({
                    txRequestId: 'id',
                    txHex: 'beef',
                })
                    .should.be.rejectedWith('must supply exactly one of txRequestId, txHex, or halfSigned');
            });
            it('should fail when txRequestId and halfSigned are both provided', async function () {
                await tssSolWallet
                    .submitTransaction({
                    txRequestId: 'id',
                    halfSigned: {
                        txHex: 'beef',
                    },
                })
                    .should.be.rejectedWith('must supply exactly one of txRequestId, txHex, or halfSigned');
            });
            it('should fail when txHex and halfSigned are both provided', async function () {
                await tssSolWallet
                    .submitTransaction({
                    txHex: 'beef',
                    halfSigned: {
                        txHex: 'beef',
                    },
                })
                    .should.be.rejectedWith('must supply either txHex or halfSigned, but not both');
            });
        });
        describe('Transfer tokens', function () {
            const recipients = [
                {
                    address: '0x101c3928946b2e1d99759e8e5d34b5e94c1a8e2f',
                    amount: '0',
                    tokenData: {
                        tokenName: 'erc721:bitgoerc721',
                        tokenContractAddress: '0x8397b091514c1f7bebb9dea6ac267ea23b570605',
                        tokenId: '38',
                        tokenQuantity: '1',
                        decimalPlaces: 0,
                        tokenType: sdk_core_1.TokenType.ERC721,
                    },
                },
            ];
            const feeOptions = {
                maxFeePerGas: 2000000000,
                maxPriorityFeePerGas: 1000000000,
            };
            it('calling prebuildxTransaction should execute prebuildTxWithIntent with proper params', async function () {
                const txRequestFullTokenTransfer = { ...txRequestFull, intent: 'transferToken' };
                const prebuildTxWithIntent = sandbox.stub(sdk_core_1.ECDSAUtils.EcdsaUtils.prototype, 'prebuildTxWithIntent');
                prebuildTxWithIntent.resolves(txRequestFullTokenTransfer);
                // TODO(BG-59686): this is not doing anything if we don't check the return value, we should also move this check to happen after we invoke prebuildTransaction
                prebuildTxWithIntent.calledOnceWithExactly({
                    reqId,
                    recipients,
                    intentType: 'transferToken',
                    feeOptions,
                }, 'full');
                const txPrebuild = await tssPolygonWallet.prebuildTransaction({
                    isTss: true,
                    recipients,
                    type: 'transfertoken',
                    walletPassphrase: 'passphrase12345',
                    feeOptions,
                });
                txPrebuild.should.deepEqual({
                    walletId: tssPolygonWallet.id(),
                    wallet: tssPolygonWallet,
                    txRequestId: 'id',
                    txHex: 'ababcdcd',
                    buildParams: {
                        recipients,
                        type: 'transfertoken',
                    },
                    feeInfo: {
                        fee: 5000,
                        feeString: '5000',
                    },
                });
            });
            it('should populate intent with EVM-like params', async function () {
                const mpcUtils = new sdk_core_1.ECDSAUtils.EcdsaUtils(bitgo, bitgo.coin('tpolygon'));
                // @ts-expect-error only pass in params being tested
                const intent = mpcUtils.populateIntent(bitgo.coin('tpolygon'), {
                    intentType: 'transferToken',
                    recipients,
                    feeOptions,
                });
                intent.should.have.property('feeOptions');
                intent.feeOptions.should.have.property('maxFeePerGas', 2000000000);
                intent.feeOptions.should.have.property('maxPriorityFeePerGas', 1000000000);
                intent.should.have.property('recipients');
                intent.recipients.should.have.property('length', 1);
                intent.recipients[0].should.have.property('tokenData');
                intent.recipients[0].tokenData.should.have.property('tokenQuantity', recipients[0].tokenData.tokenQuantity);
                intent.recipients[0].tokenData.should.have.property('tokenType', recipients[0].tokenData.tokenType);
                intent.recipients[0].tokenData.should.have.property('tokenName', recipients[0].tokenData.tokenName);
                intent.recipients[0].tokenData.should.have.property('tokenContractAddress', recipients[0].tokenData.tokenContractAddress);
                intent.recipients[0].tokenData.should.have.property('tokenId', recipients[0].tokenData.tokenId);
                intent.recipients[0].tokenData.should.have.property('decimalPlaces', recipients[0].tokenData.decimalPlaces);
            });
            it('should populate intent with calldata', async function () {
                const recipients = [
                    {
                        address: '0x101c3928946b2e1d99759e8e5d34b5e94c1a8e2f',
                        amount: '0',
                        data: '0x000011112222',
                    },
                ];
                const mpcUtils = new sdk_core_1.ECDSAUtils.EcdsaUtils(bitgo, bitgo.coin('hteth'));
                // @ts-expect-error only pass in params being tested
                const intent = mpcUtils.populateIntent(bitgo.coin('hteth'), {
                    intentType: 'payment',
                    recipients,
                    feeOptions,
                });
                intent.should.have.property('feeOptions');
                intent.feeOptions.should.have.property('maxFeePerGas', 2000000000);
                intent.feeOptions.should.have.property('maxPriorityFeePerGas', 1000000000);
                intent.should.have.property('recipients');
                intent.recipients.should.have.property('length', 1);
                intent.recipients[0].data.should.equal('0x000011112222');
            });
            it('should not populate intent with tokenData if certain params are undefined', async function () {
                const mpcUtils = new sdk_core_1.ECDSAUtils.EcdsaUtils(bitgo, bitgo.coin('tpolygon'));
                const recipients = [
                    {
                        address: '0x101c3928946b2e1d99759e8e5d34b5e94c1a8e2f',
                        amount: '0',
                        tokenData: {
                            tokenName: 'erc721:bitgoerc721',
                            tokenContractAddress: '0x8397b091514c1f7bebb9dea6ac267ea23b570605',
                            tokenId: '38',
                            tokenQuantity: '1',
                            decimalPlaces: 0,
                        },
                    },
                ];
                let intent;
                try {
                    intent = mpcUtils.populateIntent(bitgo.coin('tpolygon'), {
                        intentType: 'transferToken',
                        // @ts-expect-error only pass in params be tested for
                        recipients,
                        feeOptions,
                    });
                    intent.should.equal(undefined);
                }
                catch (e) {
                    e.message.should.equal('token type and quantity is required to request a transaction with intent to transfer a token');
                }
            });
        });
        describe('Transfer NFTs', function () {
            it('should populate intent with NFT token details', async function () {
                const params = {
                    reqId,
                    intentType: 'payment',
                    recipients: [
                        {
                            address: '0x9fef749050644625012a2c866973775e7123753b3eef0a1a4037453ac26d79bf',
                            amount: '1',
                            tokenData: {
                                tokenType: sdk_core_1.TokenType.DIGITAL_ASSET,
                                tokenQuantity: '1',
                                tokenContractAddress: '0xbbc561fbfa5d105efd8dfb06ae3e7e5be46331165b99d518f094c701e40603b5',
                                tokenId: '0x675b053d72c24dcc6bc7f38cdd45b4843cfb7af69a25ad21d002c376357e9d69',
                            },
                        },
                    ],
                };
                const baseCoin = bitgo.coin('tapt');
                const mpcUtils = new sdk_core_1.EDDSAUtils.default(bitgo, baseCoin);
                const intent = mpcUtils.populateIntent(baseCoin, params);
                intent.should.have.property('intentType', 'payment');
                intent.recipients.should.deepEqual([
                    {
                        address: {
                            address: '0x9fef749050644625012a2c866973775e7123753b3eef0a1a4037453ac26d79bf',
                        },
                        amount: {
                            value: '1',
                            symbol: 'tapt:nftcollection1',
                        },
                        tokenData: {
                            tokenType: 'Digital Asset',
                            tokenQuantity: '1',
                            tokenContractAddress: '0xbbc561fbfa5d105efd8dfb06ae3e7e5be46331165b99d518f094c701e40603b5',
                            tokenId: '0x675b053d72c24dcc6bc7f38cdd45b4843cfb7af69a25ad21d002c376357e9d69',
                            tokenName: 'tapt:nftcollection1',
                        },
                    },
                ]);
            });
        });
        describe('Wallet Sharing', function () {
            it('should use keychain pub to share tss wallet', async function () {
                const userId = '123';
                const email = 'shareto@sdktest.com';
                const permissions = 'view,spend';
                const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
                const path = 'm/999999/1/1';
                const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
                const walletPassphrase = 'bitgo1234';
                const getSharingKeyNock = nock(bgUrl)
                    .post('/api/v1/user/sharingkey', { email })
                    .reply(200, { userId, pubkey, path });
                // commonPub + commonChaincode
                const commonKeychain = (0, crypto_1.randomBytes)(32).toString('hex') + (0, crypto_1.randomBytes)(32).toString('hex');
                const getKeyNock = nock(bgUrl)
                    .get(`/api/v2/tsol/key/${tssSolWallet.keyIds()[0]}`)
                    .reply(200, {
                    id: tssSolWallet.keyIds()[0],
                    commonKeychain: commonKeychain,
                    source: 'user',
                    encryptedPrv: bitgo.encrypt({ input: 'xprv1', password: walletPassphrase }),
                    coinSpecific: {},
                });
                const stub = sinon.stub(tssSolWallet, 'createShare').callsFake(async (options) => {
                    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
                    options.keychain.pub.should.not.be.undefined();
                    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
                    options.keychain.pub.should.equal(sdk_core_1.TssUtils.getPublicKeyFromCommonKeychain(commonKeychain));
                    return undefined;
                });
                await tssSolWallet.shareWallet({ email, permissions, walletPassphrase });
                stub.calledOnce.should.be.true();
                getSharingKeyNock.isDone().should.be.True();
                getKeyNock.isDone().should.be.True();
            });
        });
    });
    describe('AVAX tests', function () {
        let bgUrl;
        let basecoin;
        let walletData;
        let wallet;
        before(async function () {
            nock.pendingMocks().should.be.empty();
            bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
            walletData = {
                id: '5b34252f1bf349930e34020a00000000',
                keys: [
                    '5b3424f91bf349930e34017500000000',
                    '5b3424f91bf349930e34017600000000',
                    '5b3424f91bf349930e34017700000000',
                ],
                coinSpecific: {},
            };
        });
        it('should fetch cross-chain utxos', async function () {
            basecoin = bitgo.coin('tavaxp');
            walletData.coin = 'tavaxp';
            wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
            const params = { sourceChain: 'C' };
            const path = `/api/v2/${wallet.coin()}/wallet/${wallet.id()}/crossChainUnspents`;
            const scope = nock(bgUrl)
                .get(path)
                .query(params)
                .reply(200, {
                unspent: {
                    outputID: 7,
                    amount: '10000000',
                    txid: 'V3UBZTQj364zNWqt8uMHD5NjxxX8T8qkbeZXURmjnVmLEqzab',
                    threshold: 2,
                    addresses: [
                        'C-fuji199fluegrthqs4tvz40zajfrsx5m7dvy75ajfm6',
                        'C-fuji1gk3m444893ynl0gfvxahjgw3vftnn8sptyd9g5',
                        'C-fuji1ujfzjgwzfygl60qp2l8rmglg3lnm7w4059nca5',
                    ],
                    outputidx: '1111XiaYg',
                    locktime: '0',
                },
                fromWallet: '635092fd4ff3316142df6e6b7a078b92',
                toWallet: '635092fd4ff3316142df6e891f6a7ee6',
                toAddress: '0x125c4451c870f753265b0b1af3cf6ab88ffe4657',
            });
            try {
                await wallet.fetchCrossChainUTXOs(params);
            }
            catch (e) {
                // test is successful if nock is consumed, HMAC errors expected
            }
            scope.isDone().should.be.True();
        });
        it('sendMany should work for C > P export with custodial wallet', async function () {
            basecoin = bitgo.coin('tavaxc');
            walletData.coin = 'tavaxc';
            walletData.type = 'custodial';
            wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
            const address = 'P-fuji1e56pc4966qsevzhwgkym5l0jfma9llkqnrr4gh~P-fuji1kq05zm9nmlq8p3ld55k79dl3qay6c0e3atj56v~P-fuji1rp46z30qg457xc3dpffyxcgzpflxc85mhkjme3';
            const initiateTxParams = {
                recipients: [
                    {
                        amount: '10000000000000000', // 0.01 AVAX
                        address,
                    },
                ],
                hop: true,
                type: 'Export',
            };
            const initiateTxPath = `/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/initiate`;
            let initiateTxBody;
            const response = nock(bgUrl)
                .post(initiateTxPath, (body) => {
                initiateTxBody = body;
                return true;
            })
                .reply(200);
            const feeEstimationPath = `/api/v2/${wallet.coin()}/tx/fee?hop=true&recipient=${address}&amount=10000000000000000&type=Export`;
            nock(bgUrl).get(feeEstimationPath).reply(200, {
                feeEstimate: '718750000000000',
                gasLimitEstimate: 500000,
            });
            try {
                await wallet.sendMany(initiateTxParams);
            }
            catch (e) {
                console.log(e);
                // test is successful if nock is consumed, HMAC errors expected
            }
            _.isMatch(initiateTxBody, {
                hopParams: {
                    gasPriceMax: 7187500000,
                    gasLimit: 500000,
                },
                type: 'Export',
                recipients: [
                    {
                        amount: '10000000000000000',
                        address,
                    },
                ],
            }).should.be.true();
            response.isDone().should.be.true();
        });
    });
    describe('NFT Tests', function () {
        let ethWallet;
        before(async function () {
            const walletData = {
                id: '598f606cd8fc24710d2ebadb1d9459bb',
                coin: 'hteth',
                keys: [
                    '598f606cd8fc24710d2ebad89dce86c2',
                    '598f606cc8e43aef09fcb785221d9dd2',
                    '5935d59cf660764331bafcade1855fd7',
                ],
                multisigType: 'onchain',
                coinSpecific: {
                    baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
                },
            };
            ethWallet = new sdk_core_1.Wallet(bitgo, bitgo.coin('hteth'), walletData);
        });
        afterEach(async function () {
            nock.cleanAll();
        });
        it('Should return all nfts in the wallet', async function () {
            const getTokenBalanceNock = nock(bgUrl)
                .get(`/api/v2/hteth/wallet/${ethWallet.id()}?allTokens=true`)
                .reply(200, {
                ...walletData,
                ...nftResponses_1.nftResponse,
            });
            const nfts = await ethWallet.getNftBalances();
            getTokenBalanceNock.isDone().should.be.true();
            nfts.should.length(5);
            nfts.should.containEql({
                type: 'ERC721',
                metadata: {
                    name: 'terc721:bitgoerc721',
                    tokenContractAddress: '0x8397b091514c1f7bebb9dea6ac267ea23b570605',
                },
                collections: {},
                balanceString: '0',
                confirmedBalanceString: '0',
                spendableBalanceString: '0',
                transferCount: 0,
            });
        });
        it('Should throw when attempting to transfer a nft collection not in the wallet', async function () {
            const getTokenBalanceNock = nock(bgUrl)
                .get(`/api/v2/hteth/wallet/${ethWallet.id()}?allTokens=true`)
                .reply(200, {
                ...walletData,
                ...nftResponses_1.nftResponse,
            });
            await ethWallet
                .sendNft({
                walletPassphrase: '123abc',
                otp: '000000',
            }, {
                tokenId: '123',
                type: 'ERC721',
                tokenContractAddress: '0x123badaddress',
                recipientAddress: '0xc15acc27ee41f266877c8f0c61df5bcbc7997df6',
            })
                .should.be.rejectedWith('Collection not found for token contract 0x123badaddress');
            getTokenBalanceNock.isDone().should.be.true();
        });
        it('Should throw when attempting to transfer a ERC-721 nft not owned by the wallet', async function () {
            const getTokenBalanceNock = nock(bgUrl)
                .get(`/api/v2/hteth/wallet/${ethWallet.id()}?allTokens=true`)
                .reply(200, {
                ...walletData,
                ...nftResponses_1.nftResponse,
                ...nftResponses_1.unsupportedNftResponse,
            });
            await ethWallet
                .sendNft({
                walletPassphrase: '123abc',
                otp: '000000',
            }, {
                tokenId: '123',
                type: 'ERC721',
                tokenContractAddress: '0xf5de760f2e916647fd766b4ad9e85ff943ce3a2b',
                recipientAddress: '0xc15acc27ee41f266877c8f0c61df5bcbc7997df6',
            })
                .should.be.rejectedWith('Token 123 not found in collection 0xf5de760f2e916647fd766b4ad9e85ff943ce3a2b or does not have a spendable balance');
            getTokenBalanceNock.isDone().should.be.true();
        });
        it('Should throw when attempting to transfer ERC-1155 tokens when the amount transferred is more than the spendable balance', async function () {
            const getTokenBalanceNock = nock(bgUrl)
                .get(`/api/v2/hteth/wallet/${ethWallet.id()}?allTokens=true`)
                .reply(200, {
                ...walletData,
                ...{
                    unsupportedNfts: {
                        '0xf5de760f2e916647fd766b4ad9e85ff943ce3a2b': {
                            type: 'ERC1155',
                            collections: {
                                1186703: '9',
                                1186705: '1',
                                1294856: '1',
                                1294857: '1',
                                1294858: '1',
                                1294859: '1',
                                1294860: '1',
                            },
                            metadata: {
                                name: 'MultiFaucet NFT',
                                tokenContractAddress: '0xf5de760f2e916647fd766b4ad9e85ff943ce3a2b',
                            },
                        },
                    },
                },
            });
            await ethWallet
                .sendNft({
                walletPassphrase: '123abc',
                otp: '000000',
            }, {
                entries: [
                    {
                        amount: 10,
                        tokenId: '1186703',
                    },
                    {
                        amount: 1,
                        tokenId: '1186705',
                    },
                ],
                type: 'ERC1155',
                tokenContractAddress: '0xf5de760f2e916647fd766b4ad9e85ff943ce3a2b',
                recipientAddress: '0xc15acc27ee41f266877c8f0c61df5bcbc7997df6',
            })
                .should.be.rejectedWith('Amount 10 exceeds spendable balance of 9 for token 1186703');
            getTokenBalanceNock.isDone().should.be.true();
        });
    });
    describe('Ada tests: ', () => {
        let adaWallet;
        const adaBitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
        adaBitgo.initializeTestVars();
        const walletData = {
            id: '598f606cd8fc24710d2ebadb1d9459bb',
            coinSpecific: {
                baseAddress: 'addr_test1q9faa5q3zr38wkd4kd3u8jfshx97jxvwsyvjg3tac826502nmmgpzy8zwavmtvmrc0ynpwvtayvcaqgey3zhmsw44g7shrfrh9',
                pendingChainInitialization: false,
                minimumFunding: 1000000,
                lastChainIndex: { 0: 0 },
            },
            coin: 'tada',
            keys: [
                '598f606cd8fc24710d2ebad89dce86c2',
                '598f606cc8e43aef09fcb785221d9dd2',
                '5935d59cf660764331bafcade1855fd7',
            ],
            multisigType: 'tss',
        };
        before(async function () {
            adaWallet = new sdk_core_1.Wallet(bitgo, bitgo.coin('tada'), walletData);
            nock(bgUrl).get(`/api/v2/${adaWallet.coin()}/key/${adaWallet.keyIds()[0]}`).times(3).reply(200, {
                id: '598f606cd8fc24710d2ebad89dce86c2',
                pub: '5f8WmC2uW9SAk7LMX2r4G1Bx8MMwx8sdgpotyHGodiZo',
                source: 'user',
                encryptedPrv: '{"iv":"hNK3rg82P1T94MaueXFAbA==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"cV4wU4EzPjs=","ct":"9VZX99Ztsb6p75Cxl2lrcXBplmssIAQ9k7ZA81vdDYG4N5dZ36BQNWVfDoelj9O31XyJ+Xri0XKIWUzl0KKLfUERplmtNoOCn5ifJcZwCrOxpHZQe3AJ700o8Wmsrk5H"}',
                coinSpecific: {},
            });
            nock(bgUrl).get(`/api/v2/${adaWallet.coin()}/key/${adaWallet.keyIds()[1]}`).times(2).reply(200, {
                id: '598f606cc8e43aef09fcb785221d9dd2',
                pub: 'G1s43JTzNZzqhUn4aNpwgcc6wb9FUsZQD5JjffG6isyd',
                encryptedPrv: '{"iv":"UFrt/QlIUR1XeQafPBaAlw==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"7VPBYaJXPm8=","ct":"ajFKv2y8yaIBXQ39sAbBWcnbiEEzbjS4AoQtp5cXYqjeDRxt3aCxemPm22pnkJaCijFjJrMHbkmsNhNYzHg5aHFukN+nEAVssyNwHbzlhSnm8/BVN50yAdAAtWreh8cp"}',
                source: 'backup',
                coinSpecific: {},
            });
            nock(bgUrl).get(`/api/v2/${adaWallet.coin()}/key/${adaWallet.keyIds()[2]}`).times(2).reply(200, {
                id: '5935d59cf660764331bafcade1855fd7',
                pub: 'GH1LV1e9FdqGe8U2c8PMEcma3fDeh1ktcGVBrD3AuFqx',
                encryptedPrv: '{"iv":"iIuWOHIOErEDdiJn6g46mg==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"Rzh7RRJksj0=","ct":"rcNICUfp9FakT53l+adB6XKzS1vNTc0Qq9jAtqnxA+ScssiS4Q0l3sgG/0gDy5DaZKtXryKBDUvGsi7b/fYaFCUpAoZn/VZTOhOUN/mo7ZHb4OhOXL29YPPkiryAq9Cr"}',
                source: 'bitgo',
                coinSpecific: {},
            });
        });
        after(async function () {
            sinon.restore();
            nock.cleanAll();
        });
        it('Should send unspents in payment intent when using sendmany', async function () {
            const sendManyParams = {
                type: 'transfer',
                recipients: [
                    {
                        address: 'address',
                        amount: '1000',
                    },
                ],
                unspents: ['unspent1', 'unspent2'],
            };
            nock(bgUrl)
                .post(`/api/v2/wallet/${adaWallet.id()}/txrequests`)
                .reply((url, body) => {
                // validate that the populated intent has unspents
                body.intent.intentType.should.equal('payment');
                body.intent.unspents.should.deepEqual(['unspent1', 'unspent2']);
                return [
                    200,
                    {
                        apiVersion: 'lite',
                        unsignedTxs: [
                            {
                                unsignedTx: {
                                    serializedTxHex: 'serializedTxHex',
                                    feeInfo: 'fee info',
                                },
                            },
                        ],
                    },
                ];
            });
            // stub all steps after txrequest creation
            sinon.stub(adaWallet.baseCoin, 'verifyTransaction').resolves(true);
            sinon.stub(adaWallet, 'signTransaction').resolves({ txRequestId: 'txRequestId' });
            sinon.stub(sdk_core_1.BaseTssUtils.default.prototype, 'sendTxRequest').resolves('sendTxResponse');
            await adaWallet.sendMany(sendManyParams);
        });
        it('Should send senderAddress in payment intent when using sendmany', async function () {
            const sendManyParams = {
                type: 'transfer',
                recipients: [
                    {
                        address: 'address',
                        amount: '1000',
                    },
                ],
                senderAddress: 'senderAddr1',
            };
            nock(bgUrl)
                .post(`/api/v2/wallet/${adaWallet.id()}/txrequests`)
                .reply((url, body) => {
                const createTxRequestBody = body;
                createTxRequestBody.intent.intentType.should.equal('payment');
                createTxRequestBody.intent.senderAddress?.should.equal('senderAddr1');
                return [
                    200,
                    {
                        apiVersion: 'lite',
                        unsignedTxs: [
                            {
                                unsignedTx: {
                                    serializedTxHex: 'serializedTxHex',
                                    feeInfo: 'fee info',
                                },
                            },
                        ],
                    },
                ];
            });
            sinon.stub(adaWallet.baseCoin, 'verifyTransaction').resolves(true);
            sinon.stub(adaWallet, 'signTransaction').resolves({ txRequestId: 'txRequestId' });
            sinon.stub(sdk_core_1.BaseTssUtils.default.prototype, 'sendTxRequest').resolves('sendTxResponse');
            await adaWallet.sendMany(sendManyParams).should.be.resolved();
        });
    });
    describe('ERC20 Token Approval', function () {
        let wallet;
        const walletId = '5b34252f1bf349930e34020a00000000';
        let topethCoin;
        const tokenName = 'topeth:terc18dp';
        const coin = 'topeth';
        beforeEach(function () {
            topethCoin = bitgo.coin('topeth');
            wallet = new sdk_core_1.Wallet(bitgo, topethCoin, {
                id: walletId,
                coin: coin,
                keys: ['keyid1', 'keyid2', 'keyid3'],
            });
        });
        afterEach(function () {
            sinon.restore();
        });
        it('should successfully approve a token', async function () {
            const walletPassphrase = 'password123';
            const expectedApprovalBuild = {
                txHex: '0x123456',
                feeInfo: {
                    fee: '1000000000',
                },
            };
            const expectedSignedTx = {
                txHex: '0x123456signed',
            };
            const expectedSendResult = {
                txid: '0xabcdef',
                tx: '0x123456signed',
                status: 'signed',
            };
            // Mock the token approval build API
            const ethUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
            nock(ethUrl).post(`/api/v2/${coin}/wallet/${walletId}/token/approval/build`).reply(200, expectedApprovalBuild);
            // Mock the getKeychainsAndValidatePassphrase method
            sinon.stub(wallet, 'getKeychainsAndValidatePassphrase').resolves([
                {
                    id: 'keyid1',
                    pub: 'pub1',
                    encryptedPrv: 'encryptedPrv',
                },
            ]);
            // Mock the sign transaction method
            sinon.stub(wallet, 'signTransaction').resolves(expectedSignedTx);
            // Mock the send transaction method
            sinon.stub(wallet, 'sendTransaction').resolves(expectedSendResult);
            const result = await wallet.approveErc20Token(walletPassphrase, tokenName);
            should.exist(result);
            result.should.deepEqual(expectedSendResult);
            // Verify the parameters passed to signTransaction
            const signParams = wallet.signTransaction.firstCall.args[0];
            signParams.should.have.property('txPrebuild', expectedApprovalBuild);
            signParams.should.have.property('keychain');
            signParams.should.have.property('walletPassphrase', walletPassphrase);
        });
        it('should handle token approval build API errors', async function () {
            const walletPassphrase = 'password123';
            const errorMessage = 'token approval build failed';
            // Mock the token approval build API to return an error
            nock(bgUrl).post(`/api/v2/${coin}/wallet/${walletId}/token/approval/build`).replyWithError(errorMessage);
            await wallet.approveErc20Token(walletPassphrase, tokenName).should.be.rejectedWith(errorMessage);
        });
        it('should handle wallet passphrase validation errors', async function () {
            const walletPassphrase = 'wrong-password';
            const expectedApprovalBuild = {
                txHex: '0x123456',
                feeInfo: {
                    fee: '1000000000',
                },
            };
            // Mock the token approval build API
            nock(bgUrl).post(`/api/v2/${coin}/wallet/${walletId}/token/approval/build`).reply(200, expectedApprovalBuild);
            // Mock the getKeychainsAndValidatePassphrase method to throw an error
            const error = new Error('unable to decrypt keychain with the given wallet passphrase');
            error.name = 'wallet_passphrase_incorrect';
            sinon.stub(wallet, 'getKeychainsAndValidatePassphrase').rejects(error);
            await wallet
                .approveErc20Token(walletPassphrase, tokenName)
                .should.be.rejectedWith('unable to decrypt keychain with the given wallet passphrase');
        });
        it('should handle signing errors', async function () {
            const walletPassphrase = 'password123';
            const expectedApprovalBuild = {
                txHex: '0x123456',
                feeInfo: {
                    fee: '1000000000',
                },
            };
            const signingError = new Error('signing failed');
            // Mock the token approval build API
            nock(bgUrl).post(`/api/v2/${coin}/wallet/${walletId}/token/approval/build`).reply(200, expectedApprovalBuild);
            // Mock the getKeychainsAndValidatePassphrase method
            sinon.stub(wallet, 'getKeychainsAndValidatePassphrase').resolves([
                {
                    id: 'keyid1',
                    pub: 'pub1',
                    encryptedPrv: 'encryptedPrv',
                },
            ]);
            // Mock the sign transaction method to throw an error
            sinon.stub(wallet, 'signTransaction').rejects(signingError);
            await wallet.approveErc20Token(walletPassphrase, tokenName).should.be.rejectedWith(signingError);
        });
        it('should handle send transaction errors', async function () {
            const walletPassphrase = 'password123';
            const expectedApprovalBuild = {
                txHex: '0x123456',
                feeInfo: {
                    fee: '1000000000',
                },
            };
            const expectedSignedTx = {
                txHex: '0x123456signed',
            };
            const sendError = new Error('send failed');
            // Mock the token approval build API
            nock(bgUrl).post(`/api/v2/${coin}/wallet/${walletId}/token/approval/build`).reply(200, expectedApprovalBuild);
            // Mock the getKeychainsAndValidatePassphrase method
            sinon.stub(wallet, 'getKeychainsAndValidatePassphrase').resolves([
                {
                    id: 'keyid1',
                    pub: 'pub1',
                    encryptedPrv: 'encryptedPrv',
                },
            ]);
            // Mock the sign transaction method
            sinon.stub(wallet, 'signTransaction').resolves(expectedSignedTx);
            // Mock the send transaction method to throw an error
            sinon.stub(wallet, 'sendTransaction').rejects(sendError);
            await wallet.approveErc20Token(walletPassphrase, tokenName).should.be.rejectedWith(sendError);
        });
    });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FsbGV0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC92Mi91bml0L3dhbGxldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsRUFBRTtBQUNGLG1CQUFtQjtBQUNuQixFQUFFOztBQUVGLGlDQUFpQztBQUNqQywrQkFBK0I7QUFDL0IsMEJBQXdCO0FBQ3hCLDZCQUE2QjtBQUM3Qiw0QkFBNEI7QUFFNUIsOENBNEJ5QjtBQUV6Qiw4Q0FBNEM7QUFDNUMsc0NBQXFDO0FBQ3JDLDJDQUEyQztBQUMzQyxtQ0FBcUM7QUFDckMsNENBQTRFO0FBQzVFLHNEQUEyQztBQUMzQyxzREFBMkM7QUFFM0MsZ0VBQW9GO0FBRXBGLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQztBQUV4QixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztBQVF6QixRQUFRLENBQUMsWUFBWSxFQUFFO0lBQ3JCLE1BQU0sS0FBSyxHQUFHLElBQUksd0JBQWEsRUFBRSxDQUFDO0lBQ2xDLE1BQU0sS0FBSyxHQUFHLG9CQUFTLENBQUMsUUFBUSxDQUFDLFdBQUssRUFBRSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQ3pELEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO0lBQzNCLE1BQU0sUUFBUSxHQUFRLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDekMsTUFBTSxVQUFVLEdBQUc7UUFDakIsRUFBRSxFQUFFLGtDQUFrQztRQUN0QyxJQUFJLEVBQUUsTUFBTTtRQUNaLElBQUksRUFBRSxDQUFDLGtDQUFrQyxFQUFFLGtDQUFrQyxFQUFFLGtDQUFrQyxDQUFDO1FBQ2xILFlBQVksRUFBRSxFQUFFO1FBQ2hCLFlBQVksRUFBRSxTQUFTO1FBQ3ZCLElBQUksRUFBRSxLQUFLO0tBQ1osQ0FBQztJQUNGLE1BQU0sY0FBYyxHQUFHO1FBQ3JCLEVBQUUsRUFBRSxrQ0FBa0M7UUFDdEMsSUFBSSxFQUFFLE1B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QUMxQyxNQUFNLE1BQU0sQ0FBQyxhQUFhLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUM3RSwwQ0FBMEM7WUFDMUMsTUFBTSxNQUFNLENBQUMsYUFBYSxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7WUFFNUUsT0FBTyxHQUFHLDRDQUE0QyxDQUFDO1lBQ3ZELDBDQUEwQztZQUMxQyxNQUFNLE1BQU0sQ0FBQyxhQUFhLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMxRSwwQ0FBMEM7WUFDMUMsTUFBTSxNQUFNLENBQUMsYUFBYSxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDN0UsMENBQTBDO1lBQzFDLE1BQU0sTUFBTSxDQUFDLGFBQWEsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzVFLE1BQU0sTUFBTSxDQUFDLGFBQWEsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDMUUsTUFBTSxNQUFNLENBQUMsYUFBYSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDekUsTUFBTSxNQUFNLENBQUMsYUFBYSxDQUFDLEVBQUUsS0FB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SSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLElBQUksV0FBVyxRQUFRLHVCQUF1QixDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO1lBRTlHLG9EQUFvRDtZQUNwRCxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxtQ0FBbUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztnQkFDL0Q7b0JBQ0UsRUFBRSxFQUFFLFFBQVE7b0JBQ1osR0FBRyxFQUFFLE1BQU07b0JBQ1gsWUFBWSxFQUFFLGNBQWM7aUJBQzdCO2FBQ0YsQ0FBQyxDQUFDO1lBRUgsbUNBQW1DO1lBQ25DLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLGlCQUFpQixDQUFDLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFFakUscURBQXFEO1lBQ3JELEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLGlCQUFpQixDQUFDLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBRXpELE1BQU0sTUFBTSxDQUFDLGlCQUFpQixDQUFDLGdCQUFnQixFQUFFLFNBQVMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2hHLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vXG4vLyBUZXN0cyBmb3IgV2FsbGV0XG4vL1xuXG5pbXBvcnQgKiBhcyBzaG91bGQgZnJvbSAnc2hvdWxkJztcbmltcG9ydCAqIGFzIHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCAnLi4vbGliL2Fzc2VydHMnO1xuaW1wb3J0ICogYXMgbm9jayBmcm9tICdub2NrJztcbmltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoJztcblxuaW1wb3J0IHtcbiAgY29tbW9uLFxuICBDdXN0b21TaWduaW5nRnVuY3Rpb24sXG4gIEVDRFNBVXRpbHMsXG4gIEVERFNBVXRpbHMsXG4gIFJlcXVlc3RUcmFjZXIsXG4gIFRva2VuVHlwZSxcbiAgVHNzVXRpbHMsXG4gIFR4UmVxdWVzdCxcbiAgV2FsbGV0LFxuICBTaWduYXR1cmVTaGFyZVR5cGUsXG4gIEVjZHNhLFxuICBLZXljaGFpbnMsXG4gIFR5cGVkRGF0YSxcbiAgVHlwZWRNZXNzYWdlLFxuICBNZXNzYWdlVHlwZXMsXG4gIFNpZ25UeXBlZERhdGFWZXJzaW9uLFxuICBHZXRVc2VyUHJ2T3B0aW9ucyxcbiAgTWFuYWdlVW5zcGVudHNPcHRpb25zLFxuICBTaWduZWRNZXNzYWdlLFxuICBCYXNlVHNzVXRpbHMsXG4gIEtleVR5cGUsXG4gIFNlbmRNYW55T3B0aW9ucyxcbiAgUG9wdWxhdGVkSW50ZW50LFxuICBUeFJlcXVlc3RWZXJzaW9uLFxuICBXYWxsZXRTaWduTWVzc2FnZU9wdGlvbnMsXG4gIFdhbGxldFNpZ25UeXBlZERhdGFPcHRpb25zLFxuICBQcmVidWlsZFRyYW5zYWN0aW9uV2l0aEludGVudE9wdGlvbnMsXG59IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5cbmltcG9ydCB7IFRlc3RCaXRHbyB9IGZyb20gJ0BiaXRnby9zZGstdGVzdCc7XG5pbXBvcnQgeyBCaXRHbyB9IGZyb20gJy4uLy4uLy4uL3NyYyc7XG5pbXBvcnQgKiBhcyB1dHhvTGliIGZyb20gJ0BiaXRnby91dHhvLWxpYic7XG5pbXBvcnQgeyByYW5kb21CeXRlcyB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBnZXREZWZhdWx0V2FsbGV0S2V5cywgdG9LZXljaGFpbk9iamVjdHMgfSBmcm9tICcuL2NvaW5zL3V0eG8vdXRpbCc7XG5pbXBvcnQgeyBUc29sIH0gZnJvbSAnQGJpdGdvL3Nkay1jb2luLXNvbCc7XG5pbXBvcnQgeyBUZXRoIH0gZnJvbSAnQGJpdGdvL3Nkay1jb2luLWV0aCc7XG5cbmltcG9ydCB7IG5mdFJlc3BvbnNlLCB1bnN1cHBvcnRlZE5mdFJlc3BvbnNlIH0gZnJvbSAnLi4vZml4dHVyZXMvbmZ0cy9uZnRSZXNwb25zZXMnO1xuXG5yZXF1aXJlKCdzaG91bGQtc2lub24nKTtcblxubm9jay5kaXNhYmxlTmV0Q29ubmVjdCgpO1xuXG50eXBlIENyZWF0ZVR4UmVxdWVzdEJvZHkgPSB7XG4gIGludGVudDogUG9wdWxhdGVkSW50ZW50O1xuICBhcGl2ZXJzaW9uOiBUeFJlcXVlc3RWZXJzaW9uO1xuICBwcmV2aWV3PzogYm9vbGVhbjtcbn07XG5cbmRlc2NyaWJlKCdWMiBXYWxsZXQ6JywgZnVuY3Rpb24gKCkge1xuICBjb25zdCByZXFJZCA9IG5ldyBSZXF1ZXN0VHJhY2VyKCk7XG4gIGNvbnN0IGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ3Rlc3QnIH0pO1xuICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgY29uc3QgYmFzZWNvaW46IGFueSA9IGJpdGdvLmNvaW4oJ3RidGMnKTtcbiAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICBpZDogJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYTAwMDAwMDAwJyxcbiAgICBjb2luOiAndGJ0YycsXG4gICAga2V5czogWyc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzUwMDAwMDAwMCcsICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzYwMDAwMDAwMCcsICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzcwMDAwMDAwMCddLFxuICAgIGNvaW5TcGVjaWZpYzoge30sXG4gICAgbXVsdGlzaWdUeXBlOiAnb25jaGFpbicsXG4gICAgdHlwZTogJ2hvdCcsXG4gIH07XG4gIGNvbnN0IGNvbGRXYWxsZXREYXRhID0ge1xuICAgIGlkOiAnNjU3NzQ0MTlmYjRkOTY5MDg0N2ZiZTRiMDAwMDAwMDAnLFxuICAgIGNvaW46ICd0YnRjJyxcbiAgICBrZXlzOiBbJzY1Nzc0NDEyZTU0Yjc1MTYzOTNjOWRmODAwMDAwMDAwJywgJzY1Nzc0NDI0Mjg2NjRmZmU3OTFhZjdlYTAwMDAwMDAwJywgJzY1Nzc0NDJiNzMxN2E5NDU3NTZjMmZkOTAwMDAwMDAwJ10sXG4gICAgY29pblNwZWNpZmljOiB7fSxcbiAgICBtdWx0aXNpZ1R5cGU6ICdvbmNoYWluJyxcbiAgICB0eXBlOiAnY29sZCcsXG4gIH07XG4gIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB3YWxsZXREYXRhKTtcbiAgY29uc3QgY29sZFdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCBjb2xkV2FsbGV0RGF0YSk7XG4gIGNvbnN0IGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuICBjb25zdCBhZGRyZXNzMSA9ICcweDE3NGNmZDgyM2FmOGNlMjdlZDBhZmVlM2ZjZjNjM2JhMjU5MTE2YmUnO1xuICBjb25zdCBhZGRyZXNzMiA9ICcweDdlODViZGMyN2MwNTBlMzkwNWViZjRiOGU2MzRkOWFkNmVkZDBkZTYnO1xuICBjb25zdCB0YnRjSG90V2FsbGV0RGVmYXVsdFBhcmFtcyA9IHtcbiAgICB0eEZvcm1hdDogJ3BzYnQnLFxuICAgIGNoYW5nZUFkZHJlc3NUeXBlOiBbJ3AydHJNdXNpZzInLCAncDJ3c2gnLCAncDJzaFAyd3NoJywgJ3Ayc2gnLCAncDJ0ciddLFxuICB9O1xuXG4gIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgc2lub24ucmVzdG9yZSgpO1xuICAgIHNpbm9uLnJlc2V0KCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdXYWxsZXQgdHJhbnNmZXJzJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgc2VhcmNoIGluIHdhbGxldCBmb3IgYSB0cmFuc2ZlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHsgbGltaXQ6IDEsIHNlYXJjaExhYmVsOiAndGVzdCcgfTtcblxuICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3RyYW5zZmVyYClcbiAgICAgICAgLnF1ZXJ5KHBhcmFtcylcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGNvaW46ICd0YmNoJyxcbiAgICAgICAgICB0cmFuc2ZlcnM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgd2FsbGV0OiB3YWxsZXQuaWQoKSxcbiAgICAgICAgICAgICAgY29tbWVudDogJ3Rlc3RzJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHdhbGxldC50cmFuc2ZlcnMocGFyYW1zKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gdGVzdCBpcyBzdWNjZXNzZnVsIGlmIG5vY2sgaXMgY29uc3VtZWQsIEhNQUMgZXJyb3JzIGV4cGVjdGVkXG4gICAgICB9XG5cbiAgICAgIHNjb3BlLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZvcndhcmQgYWxsIHZhbGlkIHBhcmFtZXRlcnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGxpbWl0OiAxLFxuICAgICAgICBhZGRyZXNzOiBbJ2FkZHJlc3MxJywgJ2FkZHJlc3MyJ10sXG4gICAgICAgIGRhdGVHdGU6ICdkYXRlU3RyaW5nMCcsXG4gICAgICAgIGRhdGVMdDogJ2RhdGVTdHJpbmcxJyxcbiAgICAgICAgdmFsdWVHdGU6IDAsXG4gICAgICAgIHZhbHVlTHQ6IDMwMDAwMDAwMCxcbiAgICAgICAgYWxsVG9rZW5zOiB0cnVlLFxuICAgICAgICBzZWFyY2hMYWJlbDogJ2FiYycsXG4gICAgICAgIGluY2x1ZGVIZXg6IHRydWUsXG4gICAgICAgIHR5cGU6ICd0cmFuc2Zlcl90eXBlJyxcbiAgICAgICAgc3RhdGU6ICd0cmFuc2Zlcl9zdGF0ZScsXG4gICAgICB9O1xuXG4gICAgICAvLyBUaGUgYWN0dWFsIGFwaSByZXF1ZXN0IHdpbGwgb25seSBzZW5kIHN0cmluZ3MsIGJ1dCB0aGUgU0RLIGZ1bmN0aW9uIGV4cGVjdHMgbnVtYmVycyBmb3Igc29tZSB2YWx1ZXNcbiAgICAgIGNvbnN0IGFwaVBhcmFtcyA9IF8ubWFwVmFsdWVzKHBhcmFtcywgKHBhcmFtKSA9PiAoQXJyYXkuaXNBcnJheShwYXJhbSkgPyBwYXJhbSA6IFN0cmluZyhwYXJhbSkpKTtcblxuICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3RyYW5zZmVyYClcbiAgICAgICAgLnF1ZXJ5KF8ubWF0Y2hlcyhhcGlQYXJhbXMpKVxuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgYXdhaXQgd2FsbGV0LnRyYW5zZmVycyhwYXJhbXMpO1xuICAgICAgc2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYWNjZXB0IGEgc3RyaW5nIGFyZ3VtZW50IGZvciBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICBsaW1pdDogMSxcbiAgICAgICAgYWRkcmVzczogJ3N0cmluZ0FkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgYXBpUGFyYW1zID0ge1xuICAgICAgICBsaW1pdDogJzEnLFxuICAgICAgICBhZGRyZXNzOiAnc3RyaW5nQWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHJhbnNmZXJgKVxuICAgICAgICAucXVlcnkoXy5tYXRjaGVzKGFwaVBhcmFtcykpXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB3YWxsZXQudHJhbnNmZXJzKHBhcmFtcyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIHRlc3QgaXMgc3VjY2Vzc2Z1bCBpZiBub2NrIGlzIGNvbnN1bWVkLCBITUFDIGVycm9ycyBleHBlY3RlZFxuICAgICAgfVxuXG4gICAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvcnMgZm9yIGludmFsaWQgZXhwZWN0ZWQgcGFyYW1ldGVycycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGNoZWNraW5nIHR5cGUgbWlzbWF0Y2hcbiAgICAgICAgLnRyYW5zZmVycyh7IGFkZHJlc3M6IDEzMzc1IH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIGFkZHJlc3MgYXJndW1lbnQsIGV4cGVjdGluZyBzdHJpbmcgb3IgYXJyYXknKTtcblxuICAgICAgYXdhaXQgd2FsbGV0XG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgY2hlY2tpbmcgdHlwZSBtaXNtYXRjaFxuICAgICAgICAudHJhbnNmZXJzKHsgYWRkcmVzczogW251bGxdIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIGFkZHJlc3MgYXJndW1lbnQsIGV4cGVjdGluZyBhcnJheSBvZiBhZGRyZXNzIHN0cmluZ3MnKTtcblxuICAgICAgYXdhaXQgd2FsbGV0XG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgY2hlY2tpbmcgdHlwZSBtaXNtYXRjaFxuICAgICAgICAudHJhbnNmZXJzKHsgZGF0ZUd0ZTogMjAxMDE5MDQgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgZGF0ZUd0ZSBhcmd1bWVudCwgZXhwZWN0aW5nIHN0cmluZycpO1xuXG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGNoZWNraW5nIHR5cGUgbWlzbWF0Y2hcbiAgICAgIGF3YWl0IHdhbGxldC50cmFuc2ZlcnMoeyBkYXRlTHQ6IDIwMTAxOTA0IH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgZGF0ZUx0IGFyZ3VtZW50LCBleHBlY3Rpbmcgc3RyaW5nJyk7XG5cbiAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGNoZWNraW5nIHR5cGUgbWlzbWF0Y2hcbiAgICAgICAgLnRyYW5zZmVycyh7IHZhbHVlR3RlOiAnMTAyMzAwMDUnIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIHZhbHVlR3RlIGFyZ3VtZW50LCBleHBlY3RpbmcgbnVtYmVyJyk7XG5cbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgY2hlY2tpbmcgdHlwZSBtaXNtYXRjaFxuICAgICAgYXdhaXQgd2FsbGV0LnRyYW5zZmVycyh7IHZhbHVlTHQ6ICctNWU4JyB9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIHZhbHVlTHQgYXJndW1lbnQsIGV4cGVjdGluZyBudW1iZXInKTtcblxuICAgICAgYXdhaXQgd2FsbGV0XG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgY2hlY2tpbmcgdHlwZSBtaXNtYXRjaFxuICAgICAgICAudHJhbnNmZXJzKHsgaW5jbHVkZUhleDogJzEyMycgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgaW5jbHVkZUhleCBhcmd1bWVudCwgZXhwZWN0aW5nIGJvb2xlYW4nKTtcblxuICAgICAgYXdhaXQgd2FsbGV0XG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgY2hlY2tpbmcgdHlwZSBtaXNtYXRjaFxuICAgICAgICAudHJhbnNmZXJzKHsgc3RhdGU6IDEyMyB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnaW52YWxpZCBzdGF0ZSBhcmd1bWVudCwgZXhwZWN0aW5nIHN0cmluZyBvciBhcnJheScpO1xuXG4gICAgICBhd2FpdCB3YWxsZXRcbiAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBjaGVja2luZyB0eXBlIG1pc21hdGNoXG4gICAgICAgIC50cmFuc2ZlcnMoeyBzdGF0ZTogWzEyMywgNDU2XSB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnaW52YWxpZCBzdGF0ZSBhcmd1bWVudCwgZXhwZWN0aW5nIGFycmF5IG9mIHN0YXRlIHN0cmluZ3MnKTtcblxuICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBjaGVja2luZyB0eXBlIG1pc21hdGNoXG4gICAgICBhd2FpdCB3YWxsZXQudHJhbnNmZXJzKHsgdHlwZTogMTIzIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgdHlwZSBhcmd1bWVudCwgZXhwZWN0aW5nIHN0cmluZycpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnV2FsbGV0IGFkZHJlc3NlcycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHNlYXJjaCBpbiB3YWxsZXQgYWRkcmVzc2VzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zID0geyBsaW1pdDogMSwgbGFiZWxDb250YWluczogJ3Rlc3QnIH07XG5cbiAgICAgIGNvbnN0IHNjb3BlID0gbm9jayhiZ1VybClcbiAgICAgICAgLmdldChgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS9hZGRyZXNzZXNgKVxuICAgICAgICAucXVlcnkocGFyYW1zKVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgY29pbjogJ3RiY2gnLFxuICAgICAgICAgIHRyYW5zZmVyczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB3YWxsZXQ6IHdhbGxldC5pZCgpLFxuICAgICAgICAgICAgICBjb21tZW50OiAndGVzdHMnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9KTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0LmFkZHJlc3NlcyhwYXJhbXMpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyB0ZXN0IGlzIHN1Y2Nlc3NmdWwgaWYgbm9jayBpcyBjb25zdW1lZCwgSE1BQyBlcnJvcnMgZXhwZWN0ZWRcbiAgICAgIH1cblxuICAgICAgc2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB2ZXJpZnkgYmNoIGNhc2hhZGRyIGZvcm1hdCBhcyB2YWxpZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGJjaCcpO1xuICAgIGNvbnN0IHZhbGlkID0gY29pbi5pc1ZhbGlkQWRkcmVzcygnYmNodGVzdDpwemZreHY1MzJ0MHE1emNoY2sybWhtbWYyeTAyY2Rlanlzc3E1cXJ6N2EnKTtcbiAgICB2YWxpZC5zaG91bGQuYmUuVHJ1ZSgpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHZlcmlmeSBiY2ggbGVnYWN5IGZvcm1hdCBhcyB2YWxpZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGJjaCcpO1xuICAgIGNvbnN0IHZhbGlkID0gY29pbi5pc1ZhbGlkQWRkcmVzcygnMk42Z1k5cjlpdVhRUXpaaVN5bmdXSmVvVXVMNW1DMXg0QWMnKTtcbiAgICB2YWxpZC5zaG91bGQuYmUuVHJ1ZSgpO1xuICB9KTtcblxuICBkZXNjcmliZSgnVEVUSCBXYWxsZXQgQWRkcmVzc2VzJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBldGhXYWxsZXQ7XG5cbiAgICBiZWZvcmUoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgICAgaWQ6ICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZGIxZDk0NTliYicsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAga2V5czogW1xuICAgICAgICAgICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMicsXG4gICAgICAgICAgJzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyJyxcbiAgICAgICAgICAnNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDcnLFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICAgIGV0aFdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJpdGdvLmNvaW4oJ3RldGgnKSwgd2FsbGV0RGF0YSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2VhcmNoIGxpc3QgYWRkcmVzc2VzIHNob3VsZCByZXR1cm4gc3VjY2VzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgaW5jbHVkZUJhbGFuY2VzOiB0cnVlLFxuICAgICAgICBpbmNsdWRlVG9rZW5zOiB0cnVlLFxuICAgICAgICByZXR1cm5CYWxhbmNlc0ZvclRva2VuOiAnZ3RlcmM2ZHAnLFxuICAgICAgICBwZW5kaW5nRGVwbG95bWVudDogZmFsc2UsXG4gICAgICAgIGluY2x1ZGVUb3RhbEFkZHJlc3NDb3VudDogdHJ1ZSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHNjb3BlID0gbm9jayhiZ1VybClcbiAgICAgICAgLmdldChgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS9hZGRyZXNzZXNgKVxuICAgICAgICAucXVlcnkocGFyYW1zKVxuICAgICAgICAucmVwbHkoMjAwKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHdhbGxldC5hZGRyZXNzZXMocGFyYW1zKTtcbiAgICAgICAgdGhyb3cgJyc7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyB0ZXN0IGlzIHN1Y2Nlc3NmdWwgaWYgbm9jayBpcyBjb25zdW1lZCwgSE1BQyBlcnJvcnMgZXhwZWN0ZWRcbiAgICAgIH1cbiAgICAgIHNjb3BlLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9ycyBmb3IgaW52YWxpZCBleHBlY3RlZCBwYXJhbWV0ZXJzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgZXRoV2FsbGV0XG4gICAgICAgIC5hZGRyZXNzZXMoeyBpbmNsdWRlQmFsYW5jZXM6IHRydWUsIHJldHVybkJhbGFuY2VzRm9yVG9rZW46IDEgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgcmV0dXJuQmFsYW5jZXNGb3JUb2tlbiBhcmd1bWVudCwgZXhwZWN0aW5nIHN0cmluZycpO1xuXG4gICAgICBhd2FpdCBldGhXYWxsZXRcbiAgICAgICAgLmFkZHJlc3Nlcyh7IHBlbmRpbmdEZXBsb3ltZW50OiAxIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIHBlbmRpbmdEZXBsb3ltZW50IGFyZ3VtZW50LCBleHBlY3RpbmcgYm9vbGVhbicpO1xuXG4gICAgICBhd2FpdCBldGhXYWxsZXRcbiAgICAgICAgLmFkZHJlc3Nlcyh7IGluY2x1ZGVCYWxhbmNlczogMSB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnaW52YWxpZCBpbmNsdWRlQmFsYW5jZXMgYXJndW1lbnQsIGV4cGVjdGluZyBib29sZWFuJyk7XG5cbiAgICAgIGF3YWl0IGV0aFdhbGxldFxuICAgICAgICAuYWRkcmVzc2VzKHsgaW5jbHVkZVRva2VuczogMSB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnaW52YWxpZCBpbmNsdWRlVG9rZW5zIGFyZ3VtZW50LCBleHBlY3RpbmcgYm9vbGVhbicpO1xuXG4gICAgICBhd2FpdCBldGhXYWxsZXRcbiAgICAgICAgLmFkZHJlc3Nlcyh7IGluY2x1ZGVUb3RhbEFkZHJlc3NDb3VudDogMSB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnaW52YWxpZCBpbmNsdWRlVG90YWxBZGRyZXNzQ291bnQgYXJndW1lbnQsIGV4cGVjdGluZyBib29sZWFuJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnZ2V0IGZvcndhcmRlciBiYWxhbmNlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZm9yd2FyZGVycyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIGFkZHJlc3M6ICcweGJmYmNjMGZlMmI4NjVkZTg3NzEzNDI0NmFmMDkzNzhlOWJjM2M5MWQnLFxuICAgICAgICAgIGJhbGFuY2U6ICcyMDAwMDAnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgYWRkcmVzczogJzB4ZTU5NTI0ZWQ4YjQ3MTY1ZjRjYjA4NTBjOTQyODA2OWE2MDAyZTVlYicsXG4gICAgICAgICAgYmFsYW5jZTogJzEwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAgICAgfSxcbiAgICAgIF07XG5cbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi8ke2V0aFdhbGxldC5jb2luKCl9L3dhbGxldC8ke2V0aFdhbGxldC5pZCgpfS9mb3J3YXJkZXJzL2JhbGFuY2VzYCkucmVwbHkoMjAwLCB7XG4gICAgICAgIGZvcndhcmRlcnMsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgZm9yd2FyZGVyQmFsYW5jZSA9IGF3YWl0IGV0aFdhbGxldC5nZXRGb3J3YXJkZXJCYWxhbmNlKCk7XG4gICAgICBmb3J3YXJkZXJCYWxhbmNlLmZvcndhcmRlcnNbMF0uYWRkcmVzcy5zaG91bGQuZXFsKGZvcndhcmRlcnNbMF0uYWRkcmVzcyk7XG4gICAgICBmb3J3YXJkZXJCYWxhbmNlLmZvcndhcmRlcnNbMF0uYmFsYW5jZS5zaG91bGQuZXFsKGZvcndhcmRlcnNbMF0uYmFsYW5jZSk7XG4gICAgICBmb3J3YXJkZXJCYWxhbmNlLmZvcndhcmRlcnNbMV0uYWRkcmVzcy5zaG91bGQuZXFsKGZvcndhcmRlcnNbMV0uYWRkcmVzcyk7XG4gICAgICBmb3J3YXJkZXJCYWxhbmNlLmZvcndhcmRlcnNbMV0uYmFsYW5jZS5zaG91bGQuZXFsKGZvcndhcmRlcnNbMV0uYmFsYW5jZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdHZXQgVXNlciBQcnYnLCAoKSA9PiB7XG4gICAgY29uc3QgcHJ2ID1cbiAgICAgICd4cHJ2OXMyMVpyUUgxNDNLM2hla3lOajdUY2lSNFhOWWUxa01qNjhXMmlwakpHTkhFVFdQN280MkFqRG5TUGdLaGRaNHg4TkJBdmFMNzJSclhqdVhOZG1rTXFMRVJaemE3M29ZdWdHdGJMRlhHOGcnO1xuICAgIGNvbnN0IGRlcml2ZWRQcnYgPVxuICAgICAgJ3hwcnY5eW9HNjdUZDExdXdqWHdiVjh6RW1yeVNWWEVSdTVGWkFzTEQ5c3VCZUVKYmdKcUFOczhZbmc1ZEVKb2lpN2hhZzVKZXJtSzZQYmZ4Z0RtU3pXN2V3V2VMbWVKRWttUGZtWlVTTGRFVHRIeCc7XG4gICAgaXQoJ3Nob3VsZCB1c2UgdGhlIGNvbGQgZGVyaXZhdGlvbiBzZWVkIHRvIGRlcml2ZSB0aGUgcHJvcGVyIHVzZXIgcHJpdmF0ZSBrZXknLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB1c2VyUHJ2T3B0aW9ucyA9IHtcbiAgICAgICAgcHJ2LFxuICAgICAgICBjb2xkRGVyaXZhdGlvblNlZWQ6ICcxMjMnLFxuICAgICAgfTtcbiAgICAgIHdhbGxldC5nZXRVc2VyUHJ2KHVzZXJQcnZPcHRpb25zKS5zaG91bGQuZXFsKGRlcml2ZWRQcnYpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB1c2UgdGhlIHVzZXIga2V5Y2hhaW4gZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZCBhcyB0aGUgY29sZCBkZXJpdmF0aW9uIHNlZWQgaWYgbm9uZSBpcyBwcm92aWRlZCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHVzZXJQcnZPcHRpb25zOiBHZXRVc2VyUHJ2T3B0aW9ucyA9IHtcbiAgICAgICAgcHJ2LFxuICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgIGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQ6ICcxMjMnLFxuICAgICAgICAgIGlkOiAnNDU2JyxcbiAgICAgICAgICBwdWI6ICc3ODknLFxuICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgd2FsbGV0LmdldFVzZXJQcnYodXNlclBydk9wdGlvbnMpLnNob3VsZC5lcWwoZGVyaXZlZFBydik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByZWZlciB0aGUgZXhwbGljaXQgY29sZCBkZXJpdmF0aW9uIHNlZWQgdG8gdGhlIHVzZXIga2V5Y2hhaW4gZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHVzZXJQcnZPcHRpb25zOiBHZXRVc2VyUHJ2T3B0aW9ucyA9IHtcbiAgICAgICAgcHJ2LFxuICAgICAgICBjb2xkRGVyaXZhdGlvblNlZWQ6ICcxMjMnLFxuICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgIGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQ6ICc0NTYnLFxuICAgICAgICAgIGlkOiAnNzg5JyxcbiAgICAgICAgICBwdWI6ICcwMTInLFxuICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgd2FsbGV0LmdldFVzZXJQcnYodXNlclBydk9wdGlvbnMpLnNob3VsZC5lcWwoZGVyaXZlZFBydik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0aGUgcHJ2IHByb3ZpZGVkIGZvciBUU1MgU01DJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHNzV2FsbGV0RGF0YSA9IHtcbiAgICAgICAgaWQ6ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEwMDAwMDAwMCcsXG4gICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAga2V5czogW1xuICAgICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzUwMDAwMDAwMCcsXG4gICAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NjAwMDAwMDAwJyxcbiAgICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc3MDAwMDAwMDAnLFxuICAgICAgICBdLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHRzb2xjb2luOiBhbnkgPSBiaXRnby5jb2luKCd0c29sJyk7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCB0c29sY29pbiwgdHNzV2FsbGV0RGF0YSk7XG4gICAgICBjb25zdCBwcnYgPSAnbG9uZ3N0cmluZ2lmaWVkanNvbic7XG4gICAgICBjb25zdCBrZXljaGFpbiA9IHtcbiAgICAgICAgZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZDogJ3JhbmRvbSBzZWVkJyxcbiAgICAgICAgaWQ6ICcxMjMnLFxuICAgICAgICBjb21tb25LZXljaGFpbjogJ2xvbmdzdHJpbmcnLFxuICAgICAgICB0eXBlOiAndHNzJyBhcyBLZXlUeXBlLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHVzZXJQcnZPcHRpb25zID0ge1xuICAgICAgICBwcnYsXG4gICAgICAgIGtleWNoYWluLFxuICAgICAgfTtcbiAgICAgIHdhbGxldC5nZXRVc2VyUHJ2KHVzZXJQcnZPcHRpb25zKS5zaG91bGQuZXFsKHBydik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdVVFhPIEN1c3RvbSBTaWduZXIgRnVuY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgcmVjaXBpZW50cyA9IFtcbiAgICAgIHsgYWRkcmVzczogJ2FiYycsIGFtb3VudDogMTIzIH0sXG4gICAgICB7IGFkZHJlc3M6ICdkZWYnLCBhbW91bnQ6IDQ1NiB9LFxuICAgIF07XG4gICAgY29uc3Qgcm9vdFdhbGxldEtleSA9IGdldERlZmF1bHRXYWxsZXRLZXlzKCk7XG4gICAgbGV0IGN1c3RvbVNpZ25pbmdGdW5jdGlvbjogQ3VzdG9tU2lnbmluZ0Z1bmN0aW9uO1xuICAgIGxldCBzdHViczogc2lub24uU2lub25TdHViW107XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGN1c3RvbVNpZ25pbmdGdW5jdGlvbiA9IHNpbm9uLnN0dWIoKS5yZXR1cm5zKHtcbiAgICAgICAgdHhIZXg6ICd0aGlzLWlzLWEtdHgnLFxuICAgICAgfSk7XG4gICAgICBzdHVicyA9IFtcbiAgICAgICAgc2lub24uc3R1Yih3YWxsZXQuYmFzZUNvaW4sICdwb3N0UHJvY2Vzc1ByZWJ1aWxkJykucmV0dXJuc0FyZygwKSxcbiAgICAgICAgc2lub24uc3R1Yih3YWxsZXQuYmFzZUNvaW4sICd2ZXJpZnlUcmFuc2FjdGlvbicpLnJlc29sdmVzKHRydWUpLFxuICAgICAgICBzaW5vbi5zdHViKHdhbGxldC5iYXNlQ29pbiwgJ3NpZ25UcmFuc2FjdGlvbicpLnJlc29sdmVzKHsgdHhIZXg6ICd0aGlzLWlzLWEtdHgnIH0pLFxuICAgICAgXTtcbiAgICB9KTtcblxuICAgIGZ1bmN0aW9uIG5vY2tzKHR4UHJlYnVpbGQ6IHsgdHhIZXg6IHN0cmluZyB9KSB7XG4gICAgICByZXR1cm4gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3Qod2FsbGV0LnVybCgnL3R4L2J1aWxkJykucmVwbGFjZShiZ1VybCwgJycpKVxuICAgICAgICAucmVwbHkoMjAwLCB0eFByZWJ1aWxkKVxuICAgICAgICAuZ2V0KHdhbGxldC5iYXNlQ29pbi51cmwoJy9wdWJsaWMvYmxvY2svbGF0ZXN0JykucmVwbGFjZShiZ1VybCwgJycpKVxuICAgICAgICAucmVwbHkoMjAwKVxuICAgICAgICAuZ2V0KHdhbGxldC5iYXNlQ29pbi51cmwoYC9rZXkvJHt3YWxsZXQua2V5SWRzKClbMF19YCkucmVwbGFjZShiZ1VybCwgJycpKVxuICAgICAgICAucmVwbHkoMjAwLCB7IHB1YjogJ3B1YicgfSlcbiAgICAgICAgLmdldCh3YWxsZXQuYmFzZUNvaW4udXJsKGAva2V5LyR7d2FsbGV0LmtleUlkcygpWzFdfWApLnJlcGxhY2UoYmdVcmwsICcnKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBwdWI6ICdwdWInIH0pXG4gICAgICAgIC5nZXQod2FsbGV0LmJhc2VDb2luLnVybChgL2tleS8ke3dhbGxldC5rZXlJZHMoKVsyXX1gKS5yZXBsYWNlKGJnVXJsLCAnJykpXG4gICAgICAgIC5yZXBseSgyMDAsIHsgcHViOiAncHViJyB9KVxuICAgICAgICAucG9zdCh3YWxsZXQudXJsKCcvdHgvc2VuZCcpLnJlcGxhY2UoYmdVcmwsICcnKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBvazogdHJ1ZSB9KTtcbiAgICB9XG5cbiAgICBpdCgnc2hvdWxkIHVzZSBhIGN1c3RvbSBzaWduaW5nIGZ1bmN0aW9uIGlmIHByb3ZpZGVkIGZvciBQU0JUIHdpdGggdGFwcm9vdEtleVBhdGhTcGVuZCBpbnB1dCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBzYnQgPSB1dHhvTGliLnRlc3R1dGlsLmNvbnN0cnVjdFBzYnQoXG4gICAgICAgIFt7IHNjcmlwdFR5cGU6ICd0YXByb290S2V5UGF0aFNwZW5kJywgdmFsdWU6IEJpZ0ludCgxMDAwKSB9XSxcbiAgICAgICAgW3sgc2NyaXB0VHlwZTogJ3Ayc2gnLCB2YWx1ZTogQmlnSW50KDkwMCkgfV0sXG4gICAgICAgIGJhc2Vjb2luLm5ldHdvcmssXG4gICAgICAgIHJvb3RXYWxsZXRLZXksXG4gICAgICAgICd1bnNpZ25lZCdcbiAgICAgICk7XG4gICAgICBjb25zdCBzY29wZSA9IG5vY2tzKHsgdHhIZXg6IHBzYnQudG9IZXgoKSB9KTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldC5zZW5kTWFueSh7IHJlY2lwaWVudHMsIGN1c3RvbVNpZ25pbmdGdW5jdGlvbiB9KTtcblxuICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLnByb3BlcnR5KCdvaycsIHRydWUpO1xuICAgICAgY3VzdG9tU2lnbmluZ0Z1bmN0aW9uLnNob3VsZC5oYXZlLmJlZW4uY2FsbGVkVHdpY2UoKTtcbiAgICAgIHNjb3BlLmRvbmUoKTtcbiAgICAgIHN0dWJzLmZvckVhY2goKHMpID0+IHMucmVzdG9yZSgpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdXNlIGEgY3VzdG9tIHNpZ25pbmcgZnVuY3Rpb24gaWYgcHJvdmlkZWQgZm9yIFBTQlQgd2l0aG91dCB0YXByb290S2V5UGF0aFNwZW5kIGlucHV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHNidCA9IHV0eG9MaWIudGVzdHV0aWwuY29uc3RydWN0UHNidChcbiAgICAgICAgW3sgc2NyaXB0VHlwZTogJ3Ayd3NoJywgdmFsdWU6IEJpZ0ludCgxMDAwKSB9XSxcbiAgICAgICAgW3sgc2NyaXB0VHlwZTogJ3Ayc2gnLCB2YWx1ZTogQmlnSW50KDkwMCkgfV0sXG4gICAgICAgIGJhc2Vjb2luLm5ldHdvcmssXG4gICAgICAgIHJvb3RXYWxsZXRLZXksXG4gICAgICAgICd1bnNpZ25lZCdcbiAgICAgICk7XG4gICAgICBjb25zdCBzY29wZSA9IG5vY2tzKHsgdHhIZXg6IHBzYnQudG9IZXgoKSB9KTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldC5zZW5kTWFueSh7IHJlY2lwaWVudHMsIGN1c3RvbVNpZ25pbmdGdW5jdGlvbiB9KTtcblxuICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLnByb3BlcnR5KCdvaycsIHRydWUpO1xuICAgICAgY3VzdG9tU2lnbmluZ0Z1bmN0aW9uLnNob3VsZC5oYXZlLmJlZW4uY2FsbGVkT25jZSgpO1xuICAgICAgc2NvcGUuZG9uZSgpO1xuICAgICAgc3R1YnMuZm9yRWFjaCgocykgPT4gcy5yZXN0b3JlKCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB1c2UgYSBjdXN0b20gc2lnbmluZyBmdW5jdGlvbiBpZiBwcm92aWRlZCBmb3IgVHggd2l0aG91dCB0YXByb290S2V5UGF0aFNwZW5kIGlucHV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHggPSB1dHhvTGliLnRlc3R1dGlsLmNvbnN0cnVjdFR4bkJ1aWxkZXIoXG4gICAgICAgIFt7IHNjcmlwdFR5cGU6ICdwMndzaCcsIHZhbHVlOiBCaWdJbnQoMTAwMCkgfV0sXG4gICAgICAgIFt7IHNjcmlwdFR5cGU6ICdwMnNoJywgdmFsdWU6IEJpZ0ludCg5MDApIH1dLFxuICAgICAgICBiYXNlY29pbi5uZXR3b3JrLFxuICAgICAgICByb290V2FsbGV0S2V5LFxuICAgICAgICAndW5zaWduZWQnXG4gICAgICApO1xuICAgICAgY29uc3Qgc2NvcGUgPSBub2Nrcyh7IHR4SGV4OiB0eC5idWlsZEluY29tcGxldGUoKS50b0hleCgpIH0pO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd2FsbGV0LnNlbmRNYW55KHsgcmVjaXBpZW50cywgY3VzdG9tU2lnbmluZ0Z1bmN0aW9uIH0pO1xuXG4gICAgICByZXN1bHQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ29rJywgdHJ1ZSk7XG4gICAgICBjdXN0b21TaWduaW5nRnVuY3Rpb24uc2hvdWxkLmhhdmUuYmVlbi5jYWxsZWRPbmNlKCk7XG4gICAgICBzY29wZS5kb25lKCk7XG4gICAgICBzdHVicy5mb3JFYWNoKChzKSA9PiBzLnJlc3RvcmUoKSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdURVRIIFdhbGxldCBUcmFuc2FjdGlvbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGV0aFdhbGxldDtcblxuICAgIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgICBpZDogJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkYjFkOTQ1OWJiJyxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkODlkY2U4NmMyJyxcbiAgICAgICAgICAnNTk4ZjYwNmNjOGU0M2FlZjA5ZmNiNzg1MjIxZDlkZDInLFxuICAgICAgICAgICc1OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkNycsXG4gICAgICAgIF0sXG4gICAgICAgIG11bHRpc2lnVHlwZTogJ29uY2hhaW4nLFxuICAgICAgfTtcbiAgICAgIGV0aFdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJpdGdvLmNvaW4oJ3RldGgnKSwgd2FsbGV0RGF0YSk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBlcnJvciBlaXAxNTU5IGFuZCBnYXNQcmljZSBhcmUgcGFzc2VkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICBnYXNQcmljZTogMTAwLFxuICAgICAgICBlaXAxNTU5OiB7XG4gICAgICAgICAgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwLFxuICAgICAgICAgIG1heEZlZVBlckdhczogMTAsXG4gICAgICAgIH0sXG4gICAgICAgIGFtb3VudDogMTAsXG4gICAgICAgIGFkZHJlc3M6IFRlc3RCaXRHby5WMi5URVNUX1dBTExFVDFfQUREUkVTUyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlYyLlRFU1RfV0FMTEVUMV9QQVNTQ09ERSxcbiAgICAgIH07XG4gICAgICBhd2FpdCBldGhXYWxsZXQuc2VuZChwYXJhbXMpLnNob3VsZC5iZS5yZWplY3RlZCgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzZWFyY2ggZm9yIHBlbmRpbmcgdHJhbnNhY3Rpb24gY29ycmVjdGx5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zID0geyB3YWxsZXRJZDogd2FsbGV0LmlkKCkgfTtcblxuICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS90eC9wZW5kaW5nL2ZpcnN0YCkucXVlcnkocGFyYW1zKS5yZXBseSgyMDApO1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0LmdldEZpcnN0UGVuZGluZ1RyYW5zYWN0aW9uKCk7XG4gICAgICAgIHRocm93ICcnO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgLy8gdGVzdCBpcyBzdWNjZXNzZnVsIGlmIG5vY2sgaXMgY29uc3VtZWQsIEhNQUMgZXJyb3JzIGV4cGVjdGVkXG4gICAgICB9XG4gICAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0cnkgdG8gY2hhbmdlIHRoZSBmZWUgY29ycmVjdGx5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zID0geyB0eGlkOiAnMHhmZmZmZmZmZicsIGZlZTogJzEwMDAwMDAwJyB9O1xuXG4gICAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpLnBvc3QoYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvY2hhbmdlRmVlYCwgcGFyYW1zKS5yZXBseSgyMDApO1xuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB3YWxsZXQuY2hhbmdlRmVlKHsgdHhpZDogJzB4ZmZmZmZmZmYnLCBmZWU6ICcxMDAwMDAwMCcgfSk7XG4gICAgICAgIHRocm93ICcnO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgLy8gdGVzdCBpcyBzdWNjZXNzZnVsIGlmIG5vY2sgaXMgY29uc3VtZWQsIEhNQUMgZXJyb3JzIGV4cGVjdGVkXG4gICAgICB9XG4gICAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0cnkgdG8gY2hhbmdlIHRoZSBmZWUgY29ycmVjdGx5IHVzaW5nIGVpcDE1NTknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIHR4aWQ6ICcweGZmZmZmZmZmJyxcbiAgICAgICAgZWlwMTU1OToge1xuICAgICAgICAgIG1heFByaW9yaXR5RmVlUGVyR2FzOiAnMTAwMDAwMDAwMCcsXG4gICAgICAgICAgbWF4RmVlUGVyR2FzOiAnMjUwMDAwMDAwMDAnLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKGJnVXJsKS5wb3N0KGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4L2NoYW5nZUZlZWAsIHBhcmFtcykucmVwbHkoMjAwKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0LmNoYW5nZUZlZShwYXJhbXMpO1xuICAgICAgICB0aHJvdyAnJztcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIC8vIHRlc3QgaXMgc3VjY2Vzc2Z1bCBpZiBub2NrIGlzIGNvbnN1bWVkLCBITUFDIGVycm9ycyBleHBlY3RlZFxuICAgICAgfVxuICAgICAgc2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFzcyBkYXRhIHBhcmFtZXRlciBhbmQgYW1vdW50OiAwIHdoZW4gdXNpbmcgc2VuZFRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGF0aCA9IGAvYXBpL3YyLyR7ZXRoV2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7ZXRoV2FsbGV0LmlkKCl9L3R4L2J1aWxkYDtcbiAgICAgIGNvbnN0IHJlY2lwaWVudEFkZHJlc3MgPSAnMHg3ZGI1NjJjNGRkNDY1Y2M4OTU3NjFjNTZmODNiNmFmMGUzMjY4OWJhJztcbiAgICAgIGNvbnN0IHJlY2lwaWVudHMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBhZGRyZXNzOiByZWNpcGllbnRBZGRyZXNzLFxuICAgICAgICAgIGFtb3VudDogMCxcbiAgICAgICAgICBkYXRhOiAnMHgwMDExMDAxMScsXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChwYXRoLCBfLm1hdGNoZXMoeyByZWNpcGllbnRzIH0pKSAvLyB1c2UgXy5tYXRjaGVzIHRvIGRvIGEgcGFydGlhbCBtYXRjaCBvbiByZXF1ZXN0IGJvZHkgb2JqZWN0IGluc3RlYWQgb2Ygc3RyaWN0IG1hdGNoaW5nXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICBjb25zdCBub2NrS2V5Q2hhaW4gPSBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvJHtldGhXYWxsZXQuY29pbigpfS9rZXkvJHtldGhXYWxsZXQua2V5SWRzKClbMF19YCkucmVwbHkoMjAwLCB7fSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGV0aFdhbGxldC5zZW5kKHtcbiAgICAgICAgICBhZGRyZXNzOiByZWNpcGllbnRzWzBdLmFkZHJlc3MsXG4gICAgICAgICAgZGF0YTogcmVjaXBpZW50c1swXS5kYXRhLFxuICAgICAgICAgIGFtb3VudDogcmVjaXBpZW50c1swXS5hbW91bnQsXG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyB0ZXN0IGlzIHN1Y2Nlc3NmdWwgaWYgbm9jayBpcyBjb25zdW1lZCwgSE1BQyBlcnJvcnMgZXhwZWN0ZWRcbiAgICAgIH1cbiAgICAgIHJlc3BvbnNlLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBub2NrS2V5Q2hhaW4uaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFzcyBkYXRhIHBhcmFtZXRlciBhbmQgYW1vdW50OiAwIHdoZW4gdXNpbmcgc2VuZE1hbnknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXRoID0gYC9hcGkvdjIvJHtldGhXYWxsZXQuY29pbigpfS93YWxsZXQvJHtldGhXYWxsZXQuaWQoKX0vdHgvYnVpbGRgO1xuICAgICAgY29uc3QgcmVjaXBpZW50QWRkcmVzcyA9ICcweDdkYjU2MmM0ZGQ0NjVjYzg5NTc2MWM1NmY4M2I2YWYwZTMyNjg5YmEnO1xuICAgICAgY29uc3QgcmVjaXBpZW50cyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIGFkZHJlc3M6IHJlY2lwaWVudEFkZHJlc3MsXG4gICAgICAgICAgYW1vdW50OiAwLFxuICAgICAgICAgIGRhdGE6ICcweDAwMTEwMDExJyxcbiAgICAgICAgfSxcbiAgICAgIF07XG4gICAgICBjb25zdCByZXNwb25zZSA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KHBhdGgsIF8ubWF0Y2hlcyh7IHJlY2lwaWVudHMgfSkpIC8vIHVzZSBfLm1hdGNoZXMgdG8gZG8gYSBwYXJ0aWFsIG1hdGNoIG9uIHJlcXVlc3QgYm9keSBvYmplY3QgaW5zdGVhZCBvZiBzdHJpY3QgbWF0Y2hpbmdcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIGNvbnN0IG5vY2tLZXlDaGFpbiA9IG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi8ke2V0aFdhbGxldC5jb2luKCl9L2tleS8ke2V0aFdhbGxldC5rZXlJZHMoKVswXX1gKS5yZXBseSgyMDAsIHt9KTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgZXRoV2FsbGV0LnNlbmRNYW55KHsgcmVjaXBpZW50cyB9KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gdGVzdCBpcyBzdWNjZXNzZnVsIGlmIG5vY2sgaXMgY29uc3VtZWQsIEhNQUMgZXJyb3JzIGV4cGVjdGVkXG4gICAgICB9XG4gICAgICByZXNwb25zZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgbm9ja0tleUNoYWluLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCBwYXNzIHJlY2lwaWVudHMgaW4gc2VuZE1hbnkgd2hlbiB0cmFuc2FjdGlvbiB0eXBlIGlzIGZpbGxOb25jZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlY2lwaWVudEFkZHJlc3MgPSAnMHg3ZGI1NjJjNGRkNDY1Y2M4OTU3NjFjNTZmODNiNmFmMGUzMjY4OWJhJztcbiAgICAgIGNvbnN0IHJlY2lwaWVudHMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBhZGRyZXNzOiByZWNpcGllbnRBZGRyZXNzLFxuICAgICAgICAgIGFtb3VudDogMCxcbiAgICAgICAgfSxcbiAgICAgIF07XG4gICAgICBjb25zdCBzZW5kTWFueVBhcmFtcyA9IHsgcmVjaXBpZW50cywgdHlwZTogJ2ZpbGxOb25jZScsIGlzVHNzOiB0cnVlLCBub25jZTogJzEzJyB9O1xuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBldGhXYWxsZXQuc2VuZE1hbnkoc2VuZE1hbnlQYXJhbXMpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBlLm1lc3NhZ2Uuc2hvdWxkLmVxdWFsKCdjYW5ub3QgcHJvdmlkZSByZWNpcGllbnRzIGZvciB0cmFuc2FjdGlvbiB0eXBlIGZpbGxOb25jZScpO1xuICAgICAgICAvLyB0ZXN0IGlzIHN1Y2Nlc3NmdWwgaWYgbm9jayBpcyBjb25zdW1lZCwgSE1BQyBlcnJvcnMgZXhwZWN0ZWRcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IHBhc3MgcmVjZWl2ZUFkZHJlc3MgaW4gc2VuZE1hbnkgd2hlbiBUU1MgdHJhbnNhY3Rpb24gdHlwZSBpcyB0cmFuc2ZlciBvciB0cmFuc2ZlclRva2VuJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmVjaXBpZW50QWRkcmVzcyA9ICcweDdkYjU2MmM0ZGQ0NjVjYzg5NTc2MWM1NmY4M2I2YWYwZTMyNjg5YmEnO1xuICAgICAgY29uc3QgcmVjaXBpZW50cyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIGFkZHJlc3M6IHJlY2lwaWVudEFkZHJlc3MsXG4gICAgICAgICAgYW1vdW50OiAwLFxuICAgICAgICB9LFxuICAgICAgXTtcbiAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9ICdjYW5ub3QgdXNlIHJlY2VpdmUgYWRkcmVzcyBmb3IgVFNTIHRyYW5zYWN0aW9ucyBvZiB0eXBlIHRyYW5zZmVyJztcbiAgICAgIGNvbnN0IHNlbmRNYW55UGFyYW1zUmVjZWl2ZUFkZHJlc3NFcnJvciA9IHtcbiAgICAgICAgcmVjZWl2ZUFkZHJlc3M6ICd0aHJvdycsXG4gICAgICAgIHJlY2lwaWVudHMsXG4gICAgICAgIHR5cGU6ICd0cmFuc2ZlcicsXG4gICAgICAgIGlzVHNzOiB0cnVlLFxuICAgICAgICBub25jZTogJzEzJyxcbiAgICAgIH07XG4gICAgICBjb25zdCBzZW5kTWFueVBhcmFtcyA9IHsgcmVjaXBpZW50cywgdHlwZTogJ3RyYW5zZmVyJywgaXNUc3M6IHRydWUsIG5vbmNlOiAnMTMnIH07XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGV0aFdhbGxldC5zZW5kTWFueShzZW5kTWFueVBhcmFtc1JlY2VpdmVBZGRyZXNzRXJyb3IpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBlLm1lc3NhZ2Uuc2hvdWxkLmVxdWFsKGVycm9yTWVzc2FnZSk7XG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGV0aFdhbGxldC5zZW5kTWFueShzZW5kTWFueVBhcmFtcyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGUubWVzc2FnZS5zaG91bGQubm90LmVxdWFsKGVycm9yTWVzc2FnZSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGVhcmx5IGlmIHBhc3N3b3JkIGlzIHdyb25nJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmVjaXBpZW50QWRkcmVzcyA9ICcweDdkYjU2MmM0ZGQ0NjVjYzg5NTc2MWM1NmY4M2I2YWYwZTMyNjg5YmEnO1xuICAgICAgY29uc3QgcmVjaXBpZW50cyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIGFkZHJlc3M6IHJlY2lwaWVudEFkZHJlc3MsXG4gICAgICAgICAgYW1vdW50OiAwLFxuICAgICAgICB9LFxuICAgICAgXTtcbiAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGB1bmFibGUgdG8gZGVjcnlwdCBrZXljaGFpbiB3aXRoIHRoZSBnaXZlbiB3YWxsZXQgcGFzc3BocmFzZWA7XG4gICAgICBjb25zdCBzZW5kTWFueVBhcmFtc0NvcnJlY3RQYXNzUGhyYXNlID0ge1xuICAgICAgICByZWNpcGllbnRzLFxuICAgICAgICB0eXBlOiAndHJhbnNmZXInLFxuICAgICAgICBpc1RzczogdHJ1ZSxcbiAgICAgICAgbm9uY2U6ICcxMycsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IFRlc3RCaXRHby5WMi5URVNUX0VUSF9XQUxMRVRfUEFTU1BIUkFTRSxcbiAgICAgIH07XG4gICAgICBjb25zdCBub2NrS2V5Y2hhaW4gPSBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KGAvYXBpL3YyLyR7ZXRoV2FsbGV0LmNvaW4oKX0va2V5LyR7ZXRoV2FsbGV0LmtleUlkcygpWzBdfWApXG4gICAgICAgIC50aW1lcygyKVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgaWQ6ICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMicsXG4gICAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0ZYRGNXRDJ2eHVlYmNUMVpwVEY0VmtlNnFtTVc4eXpkZHdOWXBBUGp2WUVFTDVqTGZ5WVhXMmZ1eHRBeFk4VGdqUFVKTGNmMUM4cXo5TjZWZ1p4QXJLWDRFd0I4ckg1JyxcbiAgICAgICAgICBldGhBZGRyZXNzOiAnMHgyNmExNjNiYTk3Mzk1Mjk3MjBjMDkxNGM1ODM4NjVkZWMwZDM3Mjc4JyxcbiAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6XG4gICAgICAgICAgICAne1wiaXZcIjpcIjE1RnNiRFZJMXpHOU9nZ0Q4WVgrSGc9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJoSGJOSDNTei9hVT1cIixcImN0XCI6XCJXb05WS3o3YWZpUnhYSTJ3L1lrek1kTXlvUWcvQjE1dTFROGFRZ2k5NmpKWjl3azZUSWFTRWM2YlhGSDNBSHpEOU1kSkNXSlFVcFJob1FjL3JneXRjbjY5c2NQVGpLZWV5Vk1FbEdDeFpkRlZTL3BzUWNORStsdWUzLy8yWmx4ais2dDFOa3ZZTys4eUFlelNNUkJLNU9kZnRYRWpOUUk9XCJ9JyxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgICB9KTtcblxuICAgICAgYXdhaXQgZXRoV2FsbGV0XG4gICAgICAgIC5zZW5kTWFueSh7IC4uLnNlbmRNYW55UGFyYW1zQ29ycmVjdFBhc3NQaHJhc2UsIHdhbGxldFBhc3NwaHJhc2U6ICd3cm9uZ1Bhc3NwaHJhc2UnIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKGVycm9yTWVzc2FnZSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGN1c3RvbVNpZ25pbmdGdW5jdGlvbiA9ICgpID0+IHtcbiAgICAgICAgICByZXR1cm4gJ21vY2snO1xuICAgICAgICB9O1xuICAgICAgICAvLyBTaG91bGQgbm90IHZhbGlkYXRlIHBhc3NwaHJhc2UgaWYgY3VzdG9tIHNpZ25pbmcgZnVuY3Rpb24gaXMgcHJvdmlkZWRcbiAgICAgICAgYXdhaXQgZXRoV2FsbGV0LnNlbmRNYW55KHtcbiAgICAgICAgICAuLi5zZW5kTWFueVBhcmFtc0NvcnJlY3RQYXNzUGhyYXNlLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICd3cm9uZ1Bhc3NwaHJhc2UnLFxuICAgICAgICAgIGN1c3RvbVNpZ25pbmdGdW5jdGlvbixcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGUubWVzc2FnZS5zaG91bGQubm90LmVxdWFsKGVycm9yTWVzc2FnZSk7XG4gICAgICB9XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBldGhXYWxsZXQuc2VuZE1hbnkoeyAuLi5zZW5kTWFueVBhcmFtc0NvcnJlY3RQYXNzUGhyYXNlIH0pO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBlLm1lc3NhZ2Uuc2hvdWxkLm5vdC5lcXVhbChlcnJvck1lc3NhZ2UpO1xuICAgICAgfVxuICAgICAgbm9ja0tleWNoYWluLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdPRkMgQ3JlYXRlIEFkZHJlc3MnLCAoKSA9PiB7XG4gICAgbGV0IG9mY1dhbGxldDogV2FsbGV0O1xuICAgIGxldCBub2NrcztcbiAgICBiZWZvcmUoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0RGF0YU9mYyA9IHtcbiAgICAgICAgaWQ6ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAwYjAwMDAwMDAwJyxcbiAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgIGtleXM6IFtcbiAgICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc4MDAwMDAwMDAnLFxuICAgICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzkwMDAwMDAwMCcsXG4gICAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE4MDAwMDAwMDAwJyxcbiAgICAgICAgXSxcbiAgICAgICAgY29pblNwZWNpZmljOiB7fSxcbiAgICAgICAgbXVsdGlzaWdUeXBlOiAnb25jaGFpbicsXG4gICAgICB9O1xuICAgICAgb2ZjV2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYml0Z28uY29pbignb2ZjJyksIHdhbGxldERhdGFPZmMpO1xuICAgIH0pO1xuXG4gICAgYmVmb3JlRWFjaChhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrcyA9IFtcbiAgICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL29mYy9rZXkvJHtvZmNXYWxsZXQua2V5SWRzKClbMF19YCkucmVwbHkoMjAwLCB7XG4gICAgICAgICAgaWQ6IG9mY1dhbGxldC5rZXlJZHMoKVswXSxcbiAgICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjRlhEY1dEMnZ4dWViY1QxWnBURjRWa2U2cW1NVzh5emRkd05ZcEFQanZZRUVMNWpMZnlZWFcyZnV4dEF4WThUZ2pQVUpMY2YxQzhxejlONlZnWnhBcktYNEV3QjhySDUnLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgIGVuY3J5cHRlZFBydjpcbiAgICAgICAgICAgICd7XCJpdlwiOlwiMTVGc2JEVkkxekc5T2dnRDhZWCtIZz09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcImhIYk5IM1N6L2FVPVwiLFwiY3RcIjpcIldvTlZLejdhZmlSeFhJMncvWWt6TWRNeW9RZy9CMTV1MVE4YVFnaTk2akpaOXdrNlRJYVNFYzZiWEZIM0FIekQ5TWRKQ1dKUVVwUmhvUWMvcmd5dGNuNjlzY1BUaktlZXlWTUVsR0N4WmRGVlMvcHNRY05FK2x1ZTMvLzJabHhqKzZ0MU5rdllPKzh5QWV6U01SQks1T2RmdFhFak5RST1cIn0nLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge30sXG4gICAgICAgIH0pLFxuXG4gICAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9vZmMva2V5LyR7b2ZjV2FsbGV0LmtleUlkcygpWzFdfWApLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGlkOiBvZmNXYWxsZXQua2V5SWRzKClbMV0sXG4gICAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0doU2FYaWtwdVRDOUtVODhYeDlMcmpLU3cxSktzdlhOZ2FicFRkZ2p5N0xTb3ZoOVpIaGNxaEFIUXU3dXRodTdGZ3VOR2RjQzRhWFRLSzVncVRjUGU0V3ZMWVJiQ1NHJyxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge30sXG4gICAgICAgIH0pLFxuXG4gICAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9vZmMva2V5LyR7b2ZjV2FsbGV0LmtleUlkcygpWzJdfWApLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGlkOiBvZmNXYWxsZXQua2V5SWRzKClbMl0sXG4gICAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0ZzWFNoVzhSM2hKc0hOVFlUVXd6Y2VqbkxrWTdLQ3RhSmJEcWNHa2NCRjk5QnJFSlNqTlpIZUh2ZWlZVXJzQWR3bmpVTUd3cGdtRWJpS2NaV1J1VkE5SHhuUmFBM3IzJyxcbiAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7fSxcbiAgICAgICAgfSksXG4gICAgICBdO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICAgIG5vY2tzLmZvckVhY2goKHNjb3BlKSA9PiBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29ycmVjdGx5IHZhbGlkYXRlIGFyZ3VtZW50cyB0byBjcmVhdGUgYWRkcmVzcyBvbiBPRkMgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgb2ZjV2FsbGV0LmNyZWF0ZUFkZHJlc3MoKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdvblRva2VuIGlzIGEgbWFuZGF0b3J5IHBhcmFtZXRlciBmb3IgT0ZDIHdhbGxldHMnKTtcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgdGVzdCBwYXNzaW5nIGludmFsaWQgbnVtYmVyIGFyZ3VtZW50XG4gICAgICBhd2FpdCBvZmNXYWxsZXQuY3JlYXRlQWRkcmVzcyh7IG9uVG9rZW46IDQyIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ29uVG9rZW4gaGFzIHRvIGJlIGEgc3RyaW5nJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnYWRkcmVzcyBjcmVhdGlvbiB3aXRoIHZhbGlkIG9uVG9rZW4gYXJndW1lbnQgc3VjY2VlZHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyL29mYy93YWxsZXQvJHtvZmNXYWxsZXQuaWQoKX0vYWRkcmVzc2AsIHsgb25Ub2tlbjogJ29mY3RidGMnIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBpZDogJzYzOGE0OGM2YzNkYmE0MDAwN2EzNDk3ZmE0OWEwODBjJyxcbiAgICAgICAgICBhZGRyZXNzOiAnZ2VuZXJhdGVkIGFkZHJlc3MnLFxuICAgICAgICAgIGNoYWluOiAwLFxuICAgICAgICAgIGluZGV4OiAxLFxuICAgICAgICAgIGNvaW46ICd0YnRjJyxcbiAgICAgICAgICB3YWxsZXQ6IG9mY1dhbGxldC5pZCxcbiAgICAgICAgfSk7XG4gICAgICBjb25zdCBhZGRyZXNzID0gYXdhaXQgb2ZjV2FsbGV0LmNyZWF0ZUFkZHJlc3MoeyBvblRva2VuOiAnb2ZjdGJ0YycgfSk7XG4gICAgICBhZGRyZXNzLmFkZHJlc3Muc2hvdWxkLmVxdWFsKCdnZW5lcmF0ZWQgYWRkcmVzcycpO1xuICAgICAgc2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1RFVEggQ3JlYXRlIEFkZHJlc3MnLCAoKSA9PiB7XG4gICAgbGV0IGV0aFdhbGxldCwgbm9ja3M7XG4gICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgIGlkOiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWRiMWQ5NDU5YmInLFxuICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgIGJhc2VBZGRyZXNzOiAnMHhkZjA3MTE3NzA1YTlmOGRjNGMyYTc4ZGU2NmI3ZjE3OTdkYmE5ZDRlJyxcbiAgICAgIH0sXG4gICAgICBjb2luOiAndGV0aCcsXG4gICAgICBrZXlzOiBbXG4gICAgICAgICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMicsXG4gICAgICAgICc1OThmNjA2Y2M4ZTQzYWVmMDlmY2I3ODUyMjFkOWRkMicsXG4gICAgICAgICc1OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkNycsXG4gICAgICBdLFxuICAgIH07XG5cbiAgICBiZWZvcmVFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGV0aFdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJpdGdvLmNvaW4oJ3RldGgnKSwgd2FsbGV0RGF0YSk7XG4gICAgICBub2NrcyA9IFtcbiAgICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyLyR7ZXRoV2FsbGV0LmNvaW4oKX0va2V5LyR7ZXRoV2FsbGV0LmtleUlkcygpWzBdfWApLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGlkOiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWQ4OWRjZTg2YzInLFxuICAgICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNGWERjV0Qydnh1ZWJjVDFacFRGNFZrZTZxbU1XOHl6ZGR3TllwQVBqdllFRUw1akxmeVlYVzJmdXh0QXhZOFRnalBVSkxjZjFDOHF6OU42VmdaeEFyS1g0RXdCOHJINScsXG4gICAgICAgICAgZXRoQWRkcmVzczogJzB4MjZhMTYzYmE5NzM5NTI5NzIwYzA5MTRjNTgzODY1ZGVjMGQzNzI3OCcsXG4gICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgZW5jcnlwdGVkUHJ2OlxuICAgICAgICAgICAgJ3tcIml2XCI6XCIxNUZzYkRWSTF6RzlPZ2dEOFlYK0hnPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiaEhiTkgzU3ovYVU9XCIsXCJjdFwiOlwiV29OVkt6N2FmaVJ4WEkydy9Za3pNZE15b1FnL0IxNXUxUThhUWdpOTZqSlo5d2s2VElhU0VjNmJYRkgzQUh6RDlNZEpDV0pRVXBSaG9RYy9yZ3l0Y242OXNjUFRqS2VleVZNRWxHQ3haZEZWUy9wc1FjTkUrbHVlMy8vMlpseGorNnQxTmt2WU8rOHlBZXpTTVJCSzVPZGZ0WEVqTlFJPVwifScsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7fSxcbiAgICAgICAgfSksXG5cbiAgICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyLyR7ZXRoV2FsbGV0LmNvaW4oKX0va2V5LyR7ZXRoV2FsbGV0LmtleUlkcygpWzFdfWApLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGlkOiAnNTk4ZjYwNmNjOGU0M2FlZjA5ZmNiNzg1MjIxZDlkZDInLFxuICAgICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHaFNhWGlrcHVUQzlLVTg4WHg5THJqS1N3MUpLc3ZYTmdhYnBUZGdqeTdMU292aDlaSGhjcWhBSFF1N3V0aHU3Rmd1TkdkY0M0YVhUS0s1Z3FUY1BlNFd2TFlSYkNTRycsXG4gICAgICAgICAgZXRoQWRkcmVzczogJzB4YTFhODhhNTAyMjc0MDczYjFiYzRmZTA2ZWEwZjVmZTc3ZTE1MWI5MScsXG4gICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgICB9KSxcblxuICAgICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvJHtldGhXYWxsZXQuY29pbigpfS9rZXkvJHtldGhXYWxsZXQua2V5SWRzKClbMl19YCkucmVwbHkoMjAwLCB7XG4gICAgICAgICAgaWQ6ICc1OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkNycsXG4gICAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0ZzWFNoVzhSM2hKc0hOVFlUVXd6Y2VqbkxrWTdLQ3RhSmJEcWNHa2NCRjk5QnJFSlNqTlpIZUh2ZWlZVXJzQWR3bmpVTUd3cGdtRWJpS2NaV1J1VkE5SHhuUmFBM3IzJyxcbiAgICAgICAgICBldGhBZGRyZXNzOiAnMHgwMzI4MjFiN2VhNDBlYTVkNDQ2ZjQ3YzI5YTBmNzc3ZWUwMzVhYTEwJyxcbiAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7fSxcbiAgICAgICAgfSksXG4gICAgICBdO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICAgIG5vY2tzLmZvckVhY2goKHNjb3BlKSA9PiBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29ycmVjdGx5IHZhbGlkYXRlIGFyZ3VtZW50cyB0byBjcmVhdGUgYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBtZXNzYWdlID0gJ2dhc1ByaWNlIGhhcyB0byBiZSBhbiBpbnRlZ2VyIG9yIG51bWVyaWMgc3RyaW5nJztcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgY2hlY2tpbmcgdHlwZSBtaXNtYXRjaFxuICAgICAgYXdhaXQgd2FsbGV0LmNyZWF0ZUFkZHJlc3MoeyBnYXNQcmljZToge30gfSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChtZXNzYWdlKTtcbiAgICAgIGF3YWl0IHdhbGxldC5jcmVhdGVBZGRyZXNzKHsgZ2FzUHJpY2U6ICdhYmMnIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgobWVzc2FnZSk7XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGNoZWNraW5nIHR5cGUgbWlzbWF0Y2hcbiAgICAgIGF3YWl0IHdhbGxldC5jcmVhdGVBZGRyZXNzKHsgZ2FzUHJpY2U6IG51bGwgfSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChtZXNzYWdlKTtcblxuICAgICAgbWVzc2FnZSA9ICdjaGFpbiBoYXMgdG8gYmUgYW4gaW50ZWdlcic7XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGNoZWNraW5nIHR5cGUgbWlzbWF0Y2hcbiAgICAgIGF3YWl0IHdhbGxldC5jcmVhdGVBZGRyZXNzKHsgY2hhaW46IHt9IH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgobWVzc2FnZSk7XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGNoZWNraW5nIHR5cGUgbWlzbWF0Y2hcbiAgICAgIGF3YWl0IHdhbGxldC5jcmVhdGVBZGRyZXNzKHsgY2hhaW46ICdhYmMnIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgobWVzc2FnZSk7XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGNoZWNraW5nIHR5cGUgbWlzbWF0Y2hcbiAgICAgIGF3YWl0IHdhbGxldC5jcmVhdGVBZGRyZXNzKHsgY2hhaW46IG51bGwgfSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChtZXNzYWdlKTtcblxuICAgICAgbWVzc2FnZSA9ICdjb3VudCBoYXMgdG8gYmUgYSBudW1iZXIgYmV0d2VlbiAxIGFuZCAyNTAnO1xuICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBjaGVja2luZyB0eXBlIG1pc21hdGNoXG4gICAgICBhd2FpdCB3YWxsZXQuY3JlYXRlQWRkcmVzcyh7IGNvdW50OiB7fSB9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKG1lc3NhZ2UpO1xuICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBjaGVja2luZyB0eXBlIG1pc21hdGNoXG4gICAgICBhd2FpdCB3YWxsZXQuY3JlYXRlQWRkcmVzcyh7IGNvdW50OiAnYWJjJyB9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKG1lc3NhZ2UpO1xuICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBjaGVja2luZyB0eXBlIG1pc21hdGNoXG4gICAgICBhd2FpdCB3YWxsZXQuY3JlYXRlQWRkcmVzcyh7IGNvdW50OiBudWxsIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgobWVzc2FnZSk7XG4gICAgICBhd2FpdCB3YWxsZXQuY3JlYXRlQWRkcmVzcyh7IGNvdW50OiAtMSB9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKG1lc3NhZ2UpO1xuICAgICAgYXdhaXQgd2FsbGV0LmNyZWF0ZUFkZHJlc3MoeyBjb3VudDogMCB9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKG1lc3NhZ2UpO1xuICAgICAgYXdhaXQgd2FsbGV0LmNyZWF0ZUFkZHJlc3MoeyBjb3VudDogMjUxIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgobWVzc2FnZSk7XG5cbiAgICAgIG1lc3NhZ2UgPSAnYmFzZUFkZHJlc3MgaGFzIHRvIGJlIGEgc3RyaW5nJztcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgY2hlY2tpbmcgdHlwZSBtaXNtYXRjaFxuICAgICAgYXdhaXQgd2FsbGV0LmNyZWF0ZUFkZHJlc3MoeyBiYXNlQWRkcmVzczoge30gfSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChtZXNzYWdlKTtcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgY2hlY2tpbmcgdHlwZSBtaXNtYXRjaFxuICAgICAgYXdhaXQgd2FsbGV0LmNyZWF0ZUFkZHJlc3MoeyBiYXNlQWRkcmVzczogMTIzIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgobWVzc2FnZSk7XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGNoZWNraW5nIHR5cGUgbWlzbWF0Y2hcbiAgICAgIGF3YWl0IHdhbGxldC5jcmVhdGVBZGRyZXNzKHsgYmFzZUFkZHJlc3M6IG51bGwgfSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChtZXNzYWdlKTtcblxuICAgICAgbWVzc2FnZSA9ICdhbGxvd1NraXBWZXJpZnlBZGRyZXNzIGhhcyB0byBiZSBhIGJvb2xlYW4nO1xuICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBjaGVja2luZyB0eXBlIG1pc21hdGNoXG4gICAgICBhd2FpdCB3YWxsZXQuY3JlYXRlQWRkcmVzcyh7IGFsbG93U2tpcFZlcmlmeUFkZHJlc3M6IHt9IH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgobWVzc2FnZSk7XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGNoZWNraW5nIHR5cGUgbWlzbWF0Y2hcbiAgICAgIGF3YWl0IHdhbGxldC5jcmVhdGVBZGRyZXNzKHsgYWxsb3dTa2lwVmVyaWZ5QWRkcmVzczogMTIzIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgobWVzc2FnZSk7XG4gICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGNoZWNraW5nIHR5cGUgbWlzbWF0Y2hcbiAgICAgIGF3YWl0IHdhbGxldC5jcmVhdGVBZGRyZXNzKHsgYWxsb3dTa2lwVmVyaWZ5QWRkcmVzczogJ2FiYycgfSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChtZXNzYWdlKTtcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgY2hlY2tpbmcgdHlwZSBtaXNtYXRjaFxuICAgICAgYXdhaXQgd2FsbGV0LmNyZWF0ZUFkZHJlc3MoeyBhbGxvd1NraXBWZXJpZnlBZGRyZXNzOiBudWxsIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgobWVzc2FnZSk7XG5cbiAgICAgIG1lc3NhZ2UgPSAnZm9yd2FyZGVyVmVyc2lvbiBoYXMgdG8gYmUgYW4gaW50ZWdlciAwLCAxLCAyLCAzIG9yIDQnO1xuICAgICAgYXdhaXQgd2FsbGV0LmNyZWF0ZUFkZHJlc3MoeyBmb3J3YXJkZXJWZXJzaW9uOiA1IH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgobWVzc2FnZSk7XG4gICAgICBhd2FpdCB3YWxsZXQuY3JlYXRlQWRkcmVzcyh7IGZvcndhcmRlclZlcnNpb246IC0xIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgobWVzc2FnZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnYWRkcmVzcyBjcmVhdGlvbiB3aXRoIGZvcndhcmRlciB2ZXJzaW9uIDMgc3VjY2VlZHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyLyR7ZXRoV2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7ZXRoV2FsbGV0LmlkKCl9L2FkZHJlc3NgLCB7IGNoYWluOiAwLCBmb3J3YXJkZXJWZXJzaW9uOiAzIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBpZDogJzYzOGE0OGM2YzNkYmE0MDAwN2EzNDk3ZmE0OWEwODBjJyxcbiAgICAgICAgICBhZGRyZXNzOiAnMHg1ZTYxYjY0ZjM4ZjFiNWY4NTA3OGZiODRiMjczOTQ4MzBiNGM4ZTgwJyxcbiAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICBpbmRleDogMSxcbiAgICAgICAgICBjb2luOiAndHBvbHlnb24nLFxuICAgICAgICAgIGxhc3ROb25jZTogMCxcbiAgICAgICAgICB3YWxsZXQ6ICc2Mzc4NWY5NWFmN2M3NjAwMDdjZmFlMDY4YzJmMzFhZScsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBub25jZTogLTEsXG4gICAgICAgICAgICB1cGRhdGVUaW1lOiAnMjAyMi0xMi0wMlQxODo0OTo0Mi4zNDhaJyxcbiAgICAgICAgICAgIHR4Q291bnQ6IDAsXG4gICAgICAgICAgICBwZW5kaW5nQ2hhaW5Jbml0aWFsaXphdGlvbjogZmFsc2UsXG4gICAgICAgICAgICBjcmVhdGlvbkZhaWx1cmU6IFtdLFxuICAgICAgICAgICAgc2FsdDogJzB4MScsXG4gICAgICAgICAgICBwZW5kaW5nRGVwbG95bWVudDogdHJ1ZSxcbiAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDMsXG4gICAgICAgICAgICBpc1RzczogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBhd2FpdCBldGhXYWxsZXQuY3JlYXRlQWRkcmVzcyh7IGNoYWluOiAwLCBmb3J3YXJkZXJWZXJzaW9uOiAzIH0pO1xuICAgICAgYWRkcmVzcy5jb2luU3BlY2lmaWMuZm9yd2FyZGVyVmVyc2lvbi5zaG91bGQuZXF1YWwoMyk7XG4gICAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2FkZHJlc3MgY3JlYXRpb24gd2l0aCBmb3J3YXJkZXIgdmVyc2lvbiAzIGZhaWxzIGR1ZSBpbnZhbGlkIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhZGRyZXNzID0gJzB4NWU2MWI2JzsgLy8gaW52YWxpZCBhZGRyZXNzXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChgL2FwaS92Mi8ke2V0aFdhbGxldC5jb2luKCl9L3dhbGxldC8ke2V0aFdhbGxldC5pZCgpfS9hZGRyZXNzYCwgeyBjaGFpbjogMCwgZm9yd2FyZGVyVmVyc2lvbjogMyB9KVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgaWQ6ICc2MzhhNDhjNmMzZGJhNDAwMDdhMzQ5N2ZhNDlhMDgwYycsXG4gICAgICAgICAgYWRkcmVzczogYWRkcmVzcyxcbiAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICBpbmRleDogMSxcbiAgICAgICAgICBjb2luOiAndHBvbHlnb24nLFxuICAgICAgICAgIGxhc3ROb25jZTogMCxcbiAgICAgICAgICB3YWxsZXQ6ICc2Mzc4NWY5NWFmN2M3NjAwMDdjZmFlMDY4YzJmMzFhZScsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBub25jZTogLTEsXG4gICAgICAgICAgICB1cGRhdGVUaW1lOiAnMjAyMi0xMi0wMlQxODo0OTo0Mi4zNDhaJyxcbiAgICAgICAgICAgIHR4Q291bnQ6IDAsXG4gICAgICAgICAgICBwZW5kaW5nQ2hhaW5Jbml0aWFsaXphdGlvbjogZmFsc2UsXG4gICAgICAgICAgICBjcmVhdGlvbkZhaWx1cmU6IFtdLFxuICAgICAgICAgICAgc2FsdDogJzB4MScsXG4gICAgICAgICAgICBwZW5kaW5nRGVwbG95bWVudDogdHJ1ZSxcbiAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDMsXG4gICAgICAgICAgICBpc1RzczogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIGF3YWl0IGV0aFdhbGxldFxuICAgICAgICAuY3JlYXRlQWRkcmVzcyh7IGNoYWluOiAwLCBmb3J3YXJkZXJWZXJzaW9uOiAzIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKGBpbnZhbGlkIGFkZHJlc3M6ICR7YWRkcmVzc31gKTtcbiAgICB9KTtcblxuICAgIGl0KCdhZGRyZXNzIGNyZWF0aW9uIHdpdGggZm9yd2FyZGVyIHZlcnNpb24gMiBzdWNjZWVkcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNjb3BlID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvJHtldGhXYWxsZXQuY29pbigpfS93YWxsZXQvJHtldGhXYWxsZXQuaWQoKX0vYWRkcmVzc2AsIHsgY2hhaW46IDAsIGZvcndhcmRlclZlcnNpb246IDIgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGlkOiAnNjM4YTQ4YzZjM2RiYTQwMDA3YTM0OTdmYTQ5YTA4MGMnLFxuICAgICAgICAgIGFkZHJlc3M6ICcweDVlNjFiNjRmMzhmMWI1Zjg1MDc4ZmI4NGIyNzM5NDgzMGI0YzhlODAnLFxuICAgICAgICAgIGNoYWluOiAwLFxuICAgICAgICAgIGluZGV4OiAxLFxuICAgICAgICAgIGNvaW46ICd0cG9seWdvbicsXG4gICAgICAgICAgbGFzdE5vbmNlOiAwLFxuICAgICAgICAgIHdhbGxldDogJzYzNzg1Zjk1YWY3Yzc2MDAwN2NmYWUwNjhjMmYzMWFlJyxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgIG5vbmNlOiAtMSxcbiAgICAgICAgICAgIHVwZGF0ZVRpbWU6ICcyMDIyLTEyLTAyVDE4OjQ5OjQyLjM0OFonLFxuICAgICAgICAgICAgdHhDb3VudDogMCxcbiAgICAgICAgICAgIHBlbmRpbmdDaGFpbkluaXRpYWxpemF0aW9uOiB0cnVlLFxuICAgICAgICAgICAgY3JlYXRpb25GYWlsdXJlOiBbXSxcbiAgICAgICAgICAgIHNhbHQ6ICcweDEnLFxuICAgICAgICAgICAgcGVuZGluZ0RlcGxveW1lbnQ6IHRydWUsXG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAyLFxuICAgICAgICAgICAgaXNUc3M6IHRydWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICBjb25zdCBhZGRyZXNzID0gYXdhaXQgZXRoV2FsbGV0LmNyZWF0ZUFkZHJlc3MoeyBjaGFpbjogMCwgZm9yd2FyZGVyVmVyc2lvbjogMiB9KTtcbiAgICAgIGFkZHJlc3MuY29pblNwZWNpZmljLmZvcndhcmRlclZlcnNpb24uc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgc2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCd2ZXJpZnkgYWRkcmVzcyB3aGVuIHBlbmRpbmdDaGFpbkluaXRpYWxpemF0aW9uIGlzIHRydWUgaW4gY2FzZSBvZiBldGggdjEgZm9yd2FyZGVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChgL2FwaS92Mi8ke2V0aFdhbGxldC5jb2luKCl9L3dhbGxldC8ke2V0aFdhbGxldC5pZCgpfS9hZGRyZXNzYCwgeyBjaGFpbjogMCwgZm9yd2FyZGVyVmVyc2lvbjogMSB9KVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgaWQ6ICc2MTVjNjQzYTk4YTJhMTAwMDY4ZTAyM2M2MzljMGY3NCcsXG4gICAgICAgICAgYWRkcmVzczogJzB4OGMxM2NkMGJiMTk4ODU4ZjYyOGQ1NjMxYmE0YjIyOTNmYzA4ZGY0OScsXG4gICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGRmMDcxMTc3MDVhOWY4ZGM0YzJhNzhkZTY2YjdmMTc5N2RiYTlkNGUnLFxuICAgICAgICAgIGNoYWluOiAwLFxuICAgICAgICAgIGluZGV4OiAzMTc5LFxuICAgICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgICBsYXN0Tm9uY2U6IDAsXG4gICAgICAgICAgd2FsbGV0OiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWRiMWQ5NDU5YmInLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgbm9uY2U6IC0xLFxuICAgICAgICAgICAgdXBkYXRlVGltZTogJzIwMjEtMTAtMDVUMTQ6NDI6MDIuMzk5WicsXG4gICAgICAgICAgICB0eENvdW50OiAwLFxuICAgICAgICAgICAgcGVuZGluZ0NoYWluSW5pdGlhbGl6YXRpb246IHRydWUsXG4gICAgICAgICAgICBjcmVhdGlvbkZhaWx1cmU6IFtdLFxuICAgICAgICAgICAgc2FsdDogJzB4YzZiJyxcbiAgICAgICAgICAgIHBlbmRpbmdEZXBsb3ltZW50OiB0cnVlLFxuICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIGF3YWl0IGV0aFdhbGxldFxuICAgICAgICAuY3JlYXRlQWRkcmVzcyh7IGNoYWluOiAwLCBmb3J3YXJkZXJWZXJzaW9uOiAxIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdhZGRyZXNzIHZhbGlkYXRpb24gZmFpbHVyZTogZXhwZWN0ZWQgMHgzMmEyMjZjZGExNGUzNTJhNDdiZjRiMTY1ODY0OGQ4MDM3NzM2ZjgwIGJ1dCBnb3QgMHg4YzEzY2QwYmIxOTg4NThmNjI4ZDU2MzFiYTRiMjI5M2ZjMDhkZjQ5J1xuICAgICAgICApO1xuICAgICAgc2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCd2ZXJpZnkgYWRkcmVzcyB3aGVuIGludmFsaWQgYmFzZUFkZHJlc3MgaXMgcGFzc2VkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChgL2FwaS92Mi8ke2V0aFdhbGxldC5jb2luKCl9L3dhbGxldC8ke2V0aFdhbGxldC5pZCgpfS9hZGRyZXNzYCwgeyBjaGFpbjogMCwgZm9yd2FyZGVyVmVyc2lvbjogMSB9KVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgaWQ6ICc2MTVjNjQzYTk4YTJhMTAwMDY4ZTAyM2M2MzljMGY3NCcsXG4gICAgICAgICAgYWRkcmVzczogJzB4MzJhMjI2Y2RhMTRlMzUyYTQ3YmY0YjE2NTg2NDhkODAzNzczNmY4MCcsXG4gICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGRmMDcxMTc3MDVhOWY4ZGM0YzJhNzhkZTY2YjdmMTc5N2RiYTlkNGUnLFxuICAgICAgICAgIGNoYWluOiAwLFxuICAgICAgICAgIGluZGV4OiAzMTc5LFxuICAgICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgICBsYXN0Tm9uY2U6IDAsXG4gICAgICAgICAgd2FsbGV0OiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWRiMWQ5NDU5YmInLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgbm9uY2U6IC0xLFxuICAgICAgICAgICAgdXBkYXRlVGltZTogJzIwMjEtMTAtMDVUMTQ6NDI6MDIuMzk5WicsXG4gICAgICAgICAgICB0eENvdW50OiAwLFxuICAgICAgICAgICAgcGVuZGluZ0NoYWluSW5pdGlhbGl6YXRpb246IHRydWUsXG4gICAgICAgICAgICBjcmVhdGlvbkZhaWx1cmU6IFtdLFxuICAgICAgICAgICAgc2FsdDogJzB4YzZiJyxcbiAgICAgICAgICAgIHBlbmRpbmdEZXBsb3ltZW50OiB0cnVlLFxuICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIGF3YWl0IGV0aFdhbGxldFxuICAgICAgICAuY3JlYXRlQWRkcmVzcyh7IGNoYWluOiAwLCBmb3J3YXJkZXJWZXJzaW9uOiAxLCBiYXNlQWRkcmVzczogJ2FzZ2YnIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIGJhc2UgYWRkcmVzcycpO1xuICAgICAgc2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCd2ZXJpZnkgYWRkcmVzcyB3aGVuIGluY29ycmVjdCBiYXNlQWRkcmVzcyBpcyBwYXNzZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyLyR7ZXRoV2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7ZXRoV2FsbGV0LmlkKCl9L2FkZHJlc3NgLCB7IGNoYWluOiAwLCBmb3J3YXJkZXJWZXJzaW9uOiAxIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBpZDogJzYxNWM2NDNhOThhMmExMDAwNjhlMDIzYzYzOWMwZjc0JyxcbiAgICAgICAgICBhZGRyZXNzOiAnMHgzMmEyMjZjZGExNGUzNTJhNDdiZjRiMTY1ODY0OGQ4MDM3NzM2ZjgwJyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgICAgY2hhaW46IDAsXG4gICAgICAgICAgaW5kZXg6IDMxNzksXG4gICAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICAgIGxhc3ROb25jZTogMCxcbiAgICAgICAgICB3YWxsZXQ6ICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZGIxZDk0NTliYicsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBub25jZTogLTEsXG4gICAgICAgICAgICB1cGRhdGVUaW1lOiAnMjAyMS0xMC0wNVQxNDo0MjowMi4zOTlaJyxcbiAgICAgICAgICAgIHR4Q291bnQ6IDAsXG4gICAgICAgICAgICBwZW5kaW5nQ2hhaW5Jbml0aWFsaXphdGlvbjogdHJ1ZSxcbiAgICAgICAgICAgIGNyZWF0aW9uRmFpbHVyZTogW10sXG4gICAgICAgICAgICBzYWx0OiAnMHhjNmInLFxuICAgICAgICAgICAgcGVuZGluZ0RlcGxveW1lbnQ6IHRydWUsXG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAxLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgLy8gaW5jb3JyZWN0IGFkZHJlc3MgaXMgZ2VuZXJhdGVkIHdoaWxlIHZhbGlkYXRpbmcgZHVlIHRvIGluY29ycmVjdCBiYXNlQWRkcmVzc1xuICAgICAgYXdhaXQgZXRoV2FsbGV0XG4gICAgICAgIC5jcmVhdGVBZGRyZXNzKHsgY2hhaW46IDAsIGZvcndhcmRlclZlcnNpb246IDEsIGJhc2VBZGRyZXNzOiAnMHg4YzEzY2QwYmIxOTg4NThmNjI4ZDU2MzFiYTRiMjI5M2ZjMDhkZjQ5JyB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAnYWRkcmVzcyB2YWxpZGF0aW9uIGZhaWx1cmU6IGV4cGVjdGVkIDB4MzY3NDg5MjYwMDc3OTBlN2VlNDE2YzY0ODViMzJlMDBjZmIxNzdhMyBidXQgZ290IDB4MzJhMjI2Y2RhMTRlMzUyYTQ3YmY0YjE2NTg2NDhkODAzNzczNmY4MCdcbiAgICAgICAgKTtcbiAgICAgIHNjb3BlLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgndmVyaWZ5IGFkZHJlc3Mgd2hlbiBwZW5kaW5nQ2hhaW5Jbml0aWFsaXphdGlvbiBpcyB0cnVlICBhbmQgYWxsb3dTa2lwVmVyaWZ5QWRkcmVzcyBpcyBmYWxzZSBpbiBjYXNlIG9mIGV0aCB2MCBmb3J3YXJkZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyLyR7ZXRoV2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7ZXRoV2FsbGV0LmlkKCl9L2FkZHJlc3NgLCB7IGNoYWluOiAwLCBmb3J3YXJkZXJWZXJzaW9uOiAwIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBpZDogJzYxNWM2NDNhOThhMmExMDAwNjhlMDIzYzYzOWMwZjc0JyxcbiAgICAgICAgICBhZGRyZXNzOiAnMHgzMmEyNmNkYTE0ZTM1MmE0N2JmNGIxNjU4NjQ4ZDgwMzc3MzZmODAnLFxuICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhkZjA3MTE3NzA1YTlmOGRjNGMyYTc4ZGU2NmI3ZjE3OTdkYmE5ZDRlJyxcbiAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICBpbmRleDogMzE3OSxcbiAgICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgICAgbGFzdE5vbmNlOiAwLFxuICAgICAgICAgIHdhbGxldDogJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkYjFkOTQ1OWJiJyxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgIG5vbmNlOiAtMSxcbiAgICAgICAgICAgIHVwZGF0ZVRpbWU6ICcyMDIxLTEwLTA1VDE0OjQyOjAyLjM5OVonLFxuICAgICAgICAgICAgdHhDb3VudDogMCxcbiAgICAgICAgICAgIHBlbmRpbmdDaGFpbkluaXRpYWxpemF0aW9uOiB0cnVlLFxuICAgICAgICAgICAgY3JlYXRpb25GYWlsdXJlOiBbXSxcbiAgICAgICAgICAgIHNhbHQ6ICcweGM2YicsXG4gICAgICAgICAgICBwZW5kaW5nRGVwbG95bWVudDogdHJ1ZSxcbiAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDEsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICBhd2FpdCBldGhXYWxsZXRcbiAgICAgICAgLmNyZWF0ZUFkZHJlc3MoeyBjaGFpbjogMCwgZm9yd2FyZGVyVmVyc2lvbjogMCwgYWxsb3dTa2lwVmVyaWZ5QWRkcmVzczogZmFsc2UgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2FkZHJlc3MgdmVyaWZpY2F0aW9uIHNraXBwZWQgZm9yIGNvdW50ID0gMScpO1xuICAgICAgc2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCd2ZXJpZnkgYWRkcmVzcyB3aXRoIGFsbG93U2tpcFZlcmlmeUFkZHJlc3Mgc2V0IHRvIGZhbHNlIGFuZCBldGggdjEgZm9yd2FyZGVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChgL2FwaS92Mi8ke2V0aFdhbGxldC5jb2luKCl9L3dhbGxldC8ke2V0aFdhbGxldC5pZCgpfS9hZGRyZXNzYCwgeyBjaGFpbjogMCwgZm9yd2FyZGVyVmVyc2lvbjogMSB9KVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgaWQ6ICc2MTVjNjQzYTk4YTJhMTAwMDY4ZTAyM2M2MzljMGY3NCcsXG4gICAgICAgICAgYWRkcmVzczogJzB4MzJhMjI2Y2RhMTRlMzUyYTQ3YmY0YjE2NTg2NDhkODAzNzczNmY4MCcsXG4gICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGRmMDcxMTc3MDVhOWY4ZGM0YzJhNzhkZTY2YjdmMTc5N2RiYTlkNGUnLFxuICAgICAgICAgIGNoYWluOiAwLFxuICAgICAgICAgIGluZGV4OiAzMTc5LFxuICAgICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgICBsYXN0Tm9uY2U6IDAsXG4gICAgICAgICAgd2FsbGV0OiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWRiMWQ5NDU5YmInLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgbm9uY2U6IC0xLFxuICAgICAgICAgICAgdXBkYXRlVGltZTogJzIwMjEtMTAtMDVUMTQ6NDI6MDIuMzk5WicsXG4gICAgICAgICAgICB0eENvdW50OiAwLFxuICAgICAgICAgICAgcGVuZGluZ0NoYWluSW5pdGlhbGl6YXRpb246IHRydWUsXG4gICAgICAgICAgICBjcmVhdGlvbkZhaWx1cmU6IFtdLFxuICAgICAgICAgICAgc2FsdDogJzB4YzZiJyxcbiAgICAgICAgICAgIHBlbmRpbmdEZXBsb3ltZW50OiB0cnVlLFxuICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIGNvbnN0IG5ld0FkZHJlc3MgPSBhd2FpdCBldGhXYWxsZXQuY3JlYXRlQWRkcmVzcyh7XG4gICAgICAgIGNoYWluOiAwLFxuICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAxLFxuICAgICAgICBhbGxvd1NraXBWZXJpZnlBZGRyZXNzOiBmYWxzZSxcbiAgICAgIH0pO1xuICAgICAgbmV3QWRkcmVzcy5pbmRleC5zaG91bGQuZXF1YWwoMzE3OSk7XG4gICAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQWxnb3JhbmQgdGVzdHMnLCAoKSA9PiB7XG4gICAgbGV0IGFsZ29XYWxsZXQ6IFdhbGxldDtcblxuICAgIGJlZm9yZShhc3luYyAoKSA9PiB7XG4gICAgICAvLyBUaGlzIGlzIG5vdCBhIHJlYWwgVEFMR08gd2FsbGV0XG4gICAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgICBpZDogJzY1MDIwNGNmNDNkOGI0MDAwN2NkOWUxMWE4NzJjZTY1JyxcbiAgICAgICAgY29pbjogJ3RhbGdvJyxcbiAgICAgICAga2V5czogW1xuICAgICAgICAgICc2NTAyMDRiNzhhNzVjOTAwMDc3OTBiY2U5NzlhZTM0ZCcsXG4gICAgICAgICAgJzY1MDIwNGI3NjZjNTZhMDAwNzI5NTZjMDhmYjljZGYxJyxcbiAgICAgICAgICAnNjUwMjA0YjhjY2YxMzcwMDA3YjMyYmI4MTU1ZGZiZWMnLFxuICAgICAgICBdLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICByb290QWRkcmVzczogJzJVTFJHRTY0VTdMVE1UNU02UkVCN09SSFg1R0xKWVdIVElWNUVBWFZMV1FUVEFUVkpER001S0pNSUknLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGFsZ29XYWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiaXRnby5jb2luKCd0YWxnbycpLCB3YWxsZXREYXRhKTtcbiAgICB9KTtcblxuICAgIGl0KCdTaG91bGQgYnVpbGQgdG9rZW4gZW5hYmxlbWVudCB0cmFuc2FjdGlvbnMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGVuYWJsZVRva2VuczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICd0YWxnbzpVU0R0LTE4MDQ0NycsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgICBjb25zdCB0eFJlcXVlc3ROb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvJHthbGdvV2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7YWxnb1dhbGxldC5pZCgpfS90eC9idWlsZGApXG4gICAgICAgIC5yZXBseSgodXJpLCBib2R5KSA9PiB7XG4gICAgICAgICAgY29uc3QgcGFyYW1zID0gYm9keSBhcyBhbnk7XG4gICAgICAgICAgcGFyYW1zLnJlY2lwaWVudHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgICAgICBwYXJhbXMucmVjaXBpZW50c1swXS50b2tlbk5hbWUuc2hvdWxkLmVxdWFsKCd0YWxnbzpVU0R0LTE4MDQ0NycpO1xuICAgICAgICAgIHBhcmFtcy50eXBlLnNob3VsZC5lcXVhbCgnZW5hYmxldG9rZW4nKTtcbiAgICAgICAgICBzaG91bGQubm90LmV4aXN0KHBhcmFtcy5lbmFibGVUb2tlbnMpO1xuICAgICAgICAgIHJldHVybiBbMjAwLCBwYXJhbXNdO1xuICAgICAgICB9KTtcbiAgICAgIGF3YWl0IGFsZ29XYWxsZXQuYnVpbGRUb2tlbkVuYWJsZW1lbnRzKHBhcmFtcyk7XG4gICAgICB0eFJlcXVlc3ROb2NrLmlzRG9uZSgpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdIZWRlcmEgdGVzdHMnLCAoKSA9PiB7XG4gICAgbGV0IGhiYXJXYWxsZXQ6IFdhbGxldDtcblxuICAgIGJlZm9yZShhc3luYyAoKSA9PiB7XG4gICAgICAvLyBUaGlzIGlzIG5vdCBhIHJlYWwgVEhCQVIgd2FsbGV0XG4gICAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgICBpZDogJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkYjFkOTQ1OWJiJyxcbiAgICAgICAgY29pbjogJ3RoYmFyJyxcbiAgICAgICAga2V5czogW1xuICAgICAgICAgICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMicsXG4gICAgICAgICAgJzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyJyxcbiAgICAgICAgICAnNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDcnLFxuICAgICAgICBdLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzAuMC40Nzg0MTUxMScsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgaGJhcldhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJpdGdvLmNvaW4oJ3RoYmFyJyksIHdhbGxldERhdGEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ1Nob3VsZCBidWlsZCB0b2tlbiBlbmFibGVtZW50IHRyYW5zYWN0aW9ucycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgZW5hYmxlVG9rZW5zOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbmFtZTogJ3RoYmFyOnVzZGMnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgICAgY29uc3QgdHhSZXF1ZXN0Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyLyR7aGJhcldhbGxldC5jb2luKCl9L3dhbGxldC8ke2hiYXJXYWxsZXQuaWQoKX0vdHgvYnVpbGRgKVxuICAgICAgICAucmVwbHkoKHVyaSwgYm9keSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IGJvZHkgYXMgYW55O1xuICAgICAgICAgIHBhcmFtcy5yZWNpcGllbnRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICAgICAgcGFyYW1zLnJlY2lwaWVudHNbMF0udG9rZW5OYW1lLnNob3VsZC5lcXVhbCgndGhiYXI6dXNkYycpO1xuICAgICAgICAgIHBhcmFtcy50eXBlLnNob3VsZC5lcXVhbCgnZW5hYmxldG9rZW4nKTtcbiAgICAgICAgICBzaG91bGQubm90LmV4aXN0KHBhcmFtcy5lbmFibGVUb2tlbnMpO1xuICAgICAgICAgIHJldHVybiBbMjAwLCBwYXJhbXNdO1xuICAgICAgICB9KTtcbiAgICAgIGF3YWl0IGhiYXJXYWxsZXQuYnVpbGRUb2tlbkVuYWJsZW1lbnRzKHBhcmFtcyk7XG4gICAgICB0eFJlcXVlc3ROb2NrLmlzRG9uZSgpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdTb2xhbmEgdGVzdHM6ICcsICgpID0+IHtcbiAgICBsZXQgc29sV2FsbGV0OiBXYWxsZXQ7XG4gICAgY29uc3QgcGFzc3BocmFzZSA9ICcjQm9uZGlvbGExMjM0JztcbiAgICBjb25zdCBzb2xCaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBzb2xCaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgaWQ6ICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZGIxZDk0NTliYicsXG4gICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgYmFzZUFkZHJlc3M6ICc1ZjhXbUMydVc5U0FrN0xNWDJyNEcxQng4TU13eDhzZGdwb3R5SEdvZGlabycsXG4gICAgICAgIHBlbmRpbmdDaGFpbkluaXRpYWxpemF0aW9uOiBmYWxzZSxcbiAgICAgICAgbWluaW11bUZ1bmRpbmc6IDI0NDcxMzYsXG4gICAgICAgIGxhc3RDaGFpbkluZGV4OiB7IDA6IDAgfSxcbiAgICAgIH0sXG4gICAgICBjb2luOiAndHNvbCcsXG4gICAgICBrZXlzOiBbXG4gICAgICAgICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMicsXG4gICAgICAgICc1OThmNjA2Y2M4ZTQzYWVmMDlmY2I3ODUyMjFkOWRkMicsXG4gICAgICAgICc1OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkNycsXG4gICAgICBdLFxuICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICB9O1xuXG4gICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHNvbFdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJpdGdvLmNvaW4oJ3Rzb2wnKSwgd2FsbGV0RGF0YSk7XG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvJHtzb2xXYWxsZXQuY29pbigpfS9rZXkvJHtzb2xXYWxsZXQua2V5SWRzKClbMF19YCkudGltZXMoMykucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWQ4OWRjZTg2YzInLFxuICAgICAgICBwdWI6ICc1ZjhXbUMydVc5U0FrN0xNWDJyNEcxQng4TU13eDhzZGdwb3R5SEdvZGlabycsXG4gICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICBlbmNyeXB0ZWRQcnY6XG4gICAgICAgICAgJ3tcIml2XCI6XCJoTkszcmc4MlAxVDk0TWF1ZVhGQWJBPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiY1Y0d1U0RXpQanM9XCIsXCJjdFwiOlwiOVZaWDk5WnRzYjZwNzVDeGwybHJjWEJwbG1zc0lBUTlrN1pBODF2ZERZRzRONWRaMzZCUU5XVmZEb2VsajlPMzFYeUorWHJpMFhLSVdVemwwS0tMZlVFUnBsbXROb09DbjVpZkpjWndDck94cEhaUWUzQUo3MDBvOFdtc3JrNUhcIn0nLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgfSk7XG5cbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi8ke3NvbFdhbGxldC5jb2luKCl9L2tleS8ke3NvbFdhbGxldC5rZXlJZHMoKVsxXX1gKS50aW1lcygyKS5yZXBseSgyMDAsIHtcbiAgICAgICAgaWQ6ICc1OThmNjA2Y2M4ZTQzYWVmMDlmY2I3ODUyMjFkOWRkMicsXG4gICAgICAgIHB1YjogJ0cxczQzSlR6Tlp6cWhVbjRhTnB3Z2NjNndiOUZVc1pRRDVKamZmRzZpc3lkJyxcbiAgICAgICAgZW5jcnlwdGVkUHJ2OlxuICAgICAgICAgICd7XCJpdlwiOlwiVUZydC9RbElVUjFYZVFhZlBCYUFsdz09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIjdWUEJZYUpYUG04PVwiLFwiY3RcIjpcImFqRkt2Mnk4eWFJQlhRMzlzQWJCV2NuYmlFRXpialM0QW9RdHA1Y1hZcWplRFJ4dDNhQ3hlbVBtMjJwbmtKYUNpakZqSnJNSGJrbXNOaE5ZekhnNWFIRnVrTituRUFWc3N5TndIYnpsaFNubTgvQlZONTB5QWRBQXRXcmVoOGNwXCJ9JyxcbiAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgY29pblNwZWNpZmljOiB7fSxcbiAgICAgIH0pO1xuXG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvJHtzb2xXYWxsZXQuY29pbigpfS9rZXkvJHtzb2xXYWxsZXQua2V5SWRzKClbMl19YCkudGltZXMoMikucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiAnNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDcnLFxuICAgICAgICBwdWI6ICdHSDFMVjFlOUZkcUdlOFUyYzhQTUVjbWEzZkRlaDFrdGNHVkJyRDNBdUZxeCcsXG4gICAgICAgIGVuY3J5cHRlZFBydjpcbiAgICAgICAgICAne1wiaXZcIjpcImlJdVdPSElPRXJFRGRpSm42ZzQ2bWc9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJSemg3UlJKa3NqMD1cIixcImN0XCI6XCJyY05JQ1VmcDlGYWtUNTNsK2FkQjZYS3pTMXZOVGMwUXE5akF0cW54QStTY3NzaVM0UTBsM3NnRy8wZ0R5NURhWkt0WHJ5S0JEVXZHc2k3Yi9mWWFGQ1VwQW9abi9WWlRPaE9VTi9tbzdaSGI0T2hPWEwyOVlQUGtpcnlBcTlDclwifScsXG4gICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgY29pblNwZWNpZmljOiB7fSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXIoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3ByZWJ1aWxkQW5kU2lnblRyYW5zYWN0aW9uOiAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBUT0RPIChTVExYLTE1MDE4KTogZml4IHRlc3RcbiAgICAgIHhpdCgnc2hvdWxkIHN1Y2Nlc3NmdWxseSBzaWduIGEgY29uc29saWRhdGlvbiB0cmFuc2ZlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgICAgcHJlYnVpbGRUeDoge1xuICAgICAgICAgICAgd2FsbGV0SWQ6IHdhbGxldERhdGEuaWQsXG4gICAgICAgICAgICB0eEhleDpcbiAgICAgICAgICAgICAgJ0FRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUJBQUlFOU1XV1YyY3QwMW1nNUdtNEVxY0o5U0FuMlh1RCtGdUFIY0hGVGtjMVRndXQzRGdUc2lTZ1RRMGRtemo1SkpnNnFZVHBuOEZ4T1lQRkNGVE1vWmk0NmdBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCVXBUV3BrcElRWk5KT2h4WU5vNGZIdzF0ZDI4a3J1QjVCK29RRUVGUkkwUWMrcTBaZzZPT3BWOGVDRFZMZll6aW94N1lCQTcrUVBMWDRJUmhEQ1NLd0lDQWdBQkRBSUFBQUNnaGdFQUFBQUFBQU1BRlZSbGMzUWdhVzUwWldkeVlYUnBiMjRnYldWdGJ3PT0nLFxuICAgICAgICAgICAgdHhJbmZvOiB7XG4gICAgICAgICAgICAgIGZlZVBheWVyOiAnSFVWRTVOZkp5R2ZVMWRqWnNWTEE2ZnhTVFMxRTJpUnFjVFJWTkM5SzJ6N2MnLFxuICAgICAgICAgICAgICBsYW1wb3J0c1BlclNpZ25hdHVyZTogNTAwMCxcbiAgICAgICAgICAgICAgbm9uY2U6ICcyN0UzTVhGdlhNVU5ZZU1KZVgxcEFiRVJHc0pmVWJrYVpUZmdNZ3BtTk41ZycsXG4gICAgICAgICAgICAgIG51bVNpZ25hdHVyZXM6IDAsXG4gICAgICAgICAgICAgIGluc3RydWN0aW9uc0RhdGE6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICB0eXBlOiAnVHJhbnNmZXInLFxuICAgICAgICAgICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICAgICAgICAgIGZyb21BZGRyZXNzOiAnSFVWRTVOZkp5R2ZVMWRqWnNWTEE2ZnhTVFMxRTJpUnFjVFJWTkM5SzJ6N2MnLFxuICAgICAgICAgICAgICAgICAgICB0b0FkZHJlc3M6ICdDaGdKNXRnRHdCVXNrOVJOTW0yaUxpd1A4Um9kd2daNnVxckM1cGFKc1hWVCcsXG4gICAgICAgICAgICAgICAgICAgIGFtb3VudDogJzEwMDAwMCcsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgdHlwZTogJ01lbW8nLFxuICAgICAgICAgICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICAgICAgICAgIG1lbW86ICdUZXN0IGludGVncmF0aW9uIG1lbW8nLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGJ1aWxkUGFyYW1zOiB7XG4gICAgICAgICAgICAgIG1lbW86IHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnTWVtbycsXG4gICAgICAgICAgICAgICAgdmFsdWU6ICdUZXN0IGludGVncmF0aW9uIG1lbW8nLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgYWRkcmVzczogJ0NoZ0o1dGdEd0JVc2s5Uk5NbTJpTGl3UDhSb2R3Z1o2dXFyQzVwYUpzWFZUJyxcbiAgICAgICAgICAgICAgICAgIGFtb3VudDogJzEwMDAwMCcsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgdHlwZTogJ3RyYW5zZmVyJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb25zb2xpZGF0ZUlkOiAnMTIzNCcsXG4gICAgICAgICAgICBjb25zb2xpZGF0aW9uRGV0YWlsczoge1xuICAgICAgICAgICAgICBzZW5kZXJBZGRyZXNzSW5kZXg6IDEsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogcGFzc3BocmFzZSxcbiAgICAgICAgfTtcbiAgICAgICAgLy8gQnVpbGQgYW5kIHNpZ24gdGhlIHRyYW5zYWN0aW9uXG4gICAgICAgIGNvbnN0IHByZUJ1aWx0U2lnbmVkVHggPSBhd2FpdCBzb2xXYWxsZXQucHJlYnVpbGRBbmRTaWduVHJhbnNhY3Rpb24odHhQYXJhbXMpO1xuICAgICAgICBwcmVCdWlsdFNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEhleCcpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnU2hvdWxkIGJ1aWxkIHRva2VuIGVuYWJsZW1lbnQgdHJhbnNhY3Rpb25zIGNvcnJlY3RseScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgZW5hYmxlVG9rZW5zOiBbeyBuYW1lOiAndHNvbDp1c2RjJyB9LCB7IG5hbWU6ICd0c29sOnNybScgfSwgeyBuYW1lOiAndHNvbDpnbXQnIH1dLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHR4UmVxdWVzdE5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChgL2FwaS92Mi93YWxsZXQvJHtzb2xXYWxsZXQuaWQoKX0vdHhyZXF1ZXN0c2ApXG4gICAgICAgIC5yZXBseSgodXJsLCBib2R5KSA9PiB7XG4gICAgICAgICAgY29uc3QgYm9keVBhcmFtcyA9IGJvZHkgYXMgYW55O1xuICAgICAgICAgIGJvZHlQYXJhbXMuaW50ZW50LmludGVudFR5cGUuc2hvdWxkLmVxdWFsKCdlbmFibGVUb2tlbicpO1xuICAgICAgICAgIGJvZHlQYXJhbXMuaW50ZW50LnJlY2lwaWVudHMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICAgICAgICBib2R5UGFyYW1zLmludGVudC5lbmFibGVUb2tlbnMuc2hvdWxkLmRlZXBFcXVhbChwYXJhbXMuZW5hYmxlVG9rZW5zKTtcbiAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgMjAwLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhcGlWZXJzaW9uOiAnZnVsbCcsXG4gICAgICAgICAgICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIHVuc2lnbmVkVHg6IHtcbiAgICAgICAgICAgICAgICAgICAgc2VyaWFsaXplZFR4SGV4OiAnZmFrZSB0cmFuc2FjdGlvbicsXG4gICAgICAgICAgICAgICAgICAgIGZlZUluZm86ICdmYWtlIGZlZSBpbmZvJyxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXTtcbiAgICAgICAgfSk7XG4gICAgICBhd2FpdCBzb2xXYWxsZXQuYnVpbGRUb2tlbkVuYWJsZW1lbnRzKHBhcmFtcyk7XG4gICAgICB0eFJlcXVlc3ROb2NrLmlzRG9uZSgpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0FjY2VsZXJhdGUgVHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ2ZhaWxzIGlmIGFjY2VsZXJhdGlvbiBpZHMgYXJlIG5vdCBwYXNzZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCB3YWxsZXQuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHt9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKHsgY29kZTogJ2NwZnB0eGlkc19vcl9yYmZ0eGlkc19yZXF1aXJlZCcgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnZmFpbHMgaWYgY3BmcFR4SWRzIGlzIG5vdCBhbiBhcnJheScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgY2hlY2tpbmcgdHlwZSBtaXNtYXRjaFxuICAgICAgYXdhaXQgd2FsbGV0LmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7IGNwZnBUeElkczoge30gfSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCh7IGNvZGU6ICdjcGZwdHhpZHNfbm90X2FycmF5JyB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdmYWlscyBpZiBjcGZwVHhJZHMgaXMgbm90IG9mIGxlbmd0aCAxJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgd2FsbGV0LmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7IGNwZnBUeElkczogW10gfSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCh7IGNvZGU6ICdjcGZwdHhpZHNfbm90X2FycmF5JyB9KTtcbiAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHsgY3BmcFR4SWRzOiBbJ2lkMScsICdpZDInXSB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCh7IGNvZGU6ICdjcGZwdHhpZHNfbm90X2FycmF5JyB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdmYWlscyBpZiBjcGZwRmVlUmF0ZSBpcyBub3QgcGFzc2VkIGFuZCBuZWl0aGVyIGlzIG5vQ3BmcEZlZVJhdGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCB3YWxsZXQuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHsgY3BmcFR4SWRzOiBbJ2lkJ10gfSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCh7IGNvZGU6ICdjcGZwZmVlcmF0ZV9ub3Rfc2V0JyB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdmYWlscyBpZiBjcGZwRmVlUmF0ZSBpcyBub3QgYW4gaW50ZWdlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGNoZWNraW5nIHR5cGUgbWlzbWF0Y2hcbiAgICAgICAgLmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7IGNwZnBUeElkczogWydpZCddLCBjcGZwRmVlUmF0ZTogJ29uZScgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoeyBjb2RlOiAnY3BmcGZlZXJhdGVfbm90X25vbm5lZ2F0aXZlX2ludGVnZXInIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2ZhaWxzIGlmIGNwZnBGZWVSYXRlIGlzIG5lZ2F0aXZlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgd2FsbGV0XG4gICAgICAgIC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oeyBjcGZwVHhJZHM6IFsnaWQnXSwgY3BmcEZlZVJhdGU6IC0xIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKHsgY29kZTogJ2NwZnBmZWVyYXRlX25vdF9ub25uZWdhdGl2ZV9pbnRlZ2VyJyB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdmYWlscyBpZiBtYXhGZWUgaXMgbm90IHBhc3NlZCBhbmQgbmVpdGhlciBpcyBub01heEZlZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHsgY3BmcFR4SWRzOiBbJ2lkJ10sIG5vQ3BmcEZlZVJhdGU6IHRydWUgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoeyBjb2RlOiAnbWF4ZmVlX25vdF9zZXQnIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2ZhaWxzIGlmIG1heEZlZSBpcyBub3QgYW4gaW50ZWdlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGNoZWNraW5nIHR5cGUgbWlzbWF0Y2hcbiAgICAgICAgLmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7IGNwZnBUeElkczogWydpZCddLCBub0NwZnBGZWVSYXRlOiB0cnVlLCBtYXhGZWU6ICdvbmUnIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKHsgY29kZTogJ21heGZlZV9ub3Rfbm9ubmVnYXRpdmVfaW50ZWdlcicgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnZmFpbHMgaWYgbWF4RmVlIGlzIG5lZ2F0aXZlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgd2FsbGV0XG4gICAgICAgIC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oeyBjcGZwVHhJZHM6IFsnaWQnXSwgbm9DcGZwRmVlUmF0ZTogdHJ1ZSwgbWF4RmVlOiAtMSB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCh7IGNvZGU6ICdtYXhmZWVfbm90X25vbm5lZ2F0aXZlX2ludGVnZXInIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2ZhaWxzIGlmIGJvdGggcmJmVHhpZHMgYW5kIGNwZnBUeGlkcyBpcyBzZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCB3YWxsZXRcbiAgICAgICAgLmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7IGNwZnBUeElkczogWydpZDEnXSwgcmJmVHhJZHM6IFsnaWQyJ10gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoeyBjb2RlOiAnY2Fubm90X3NwZWNpZnlfYm90aF9jcGZwX2FuZF9yYmZfdHhpZHMnIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2ZhaWxzIGlmIHJiZlR4SWRzIGlzIHNldCBidXQgZmVlTXVsdGlwbGllciBpcyBtaXNzaW5nJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgd2FsbGV0XG4gICAgICAgIC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oeyByYmZUeElkczogWydpZCddIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKHsgY29kZTogJ2ZlZW11bHRpcGxpZXJfbm90X3NldCcgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnZmFpbHMgaWYgZmVlIG11bHRpcGxpZXIgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDEnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCB3YWxsZXRcbiAgICAgICAgLmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7IHJiZlR4SWRzOiBbJ2lkJ10sIGZlZU11bHRpcGxpZXI6IDEgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoeyBjb2RlOiAnZmVlbXVsdGlwbGllcl9ncmVhdGVyX3RoYW5fb25lJyB9KTtcblxuICAgICAgYXdhaXQgd2FsbGV0XG4gICAgICAgIC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oeyByYmZUeElkczogWydpZDInXSwgZmVlTXVsdGlwbGllcjogMC41IH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKHsgY29kZTogJ2ZlZW11bHRpcGxpZXJfZ3JlYXRlcl90aGFuX29uZScgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc3VibWl0cyBhIHRyYW5zYWN0aW9uIHdpdGggYWxsIGNwZnAgc3BlY2lmaWMgcGFyYW1ldGVycycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgY3BmcFR4SWRzOiBbJ2lkJ10sXG4gICAgICAgIGNwZnBGZWVSYXRlOiAxLFxuICAgICAgICBtYXhGZWU6IDEsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwcmVidWlsZFJldHVybiA9IE9iamVjdC5hc3NpZ24oeyB0eEhleDogJzEyMycgfSwgcGFyYW1zKTtcbiAgICAgIGNvbnN0IHByZWJ1aWxkU3R1YiA9IHNpbm9uLnN0dWIod2FsbGV0LCAncHJlYnVpbGRBbmRTaWduVHJhbnNhY3Rpb24nKS5yZXNvbHZlcyhwcmVidWlsZFJldHVybik7XG5cbiAgICAgIGNvbnN0IHBhdGggPSBgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC9zZW5kYDtcbiAgICAgIG5vY2soYmdVcmwpLnBvc3QocGF0aCwgXy5tYXRjaGVzKHByZWJ1aWxkUmV0dXJuKSkucmVwbHkoMjAwKTtcblxuICAgICAgYXdhaXQgd2FsbGV0LmFjY2VsZXJhdGVUcmFuc2FjdGlvbihwYXJhbXMpO1xuXG4gICAgICBwcmVidWlsZFN0dWIuc2hvdWxkLmhhdmUuYmVlbi5jYWxsZWRPbmNlV2l0aChwYXJhbXMpO1xuXG4gICAgICBzaW5vbi5yZXN0b3JlKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdmYW5vdXQgaW5wdXQgbWF4TnVtSW5wdXRzVG9Vc2UgYW5kIHVuc3BlbnRzIHZlcmlmaWNhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBhZGRyZXNzID0gJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYSc7XG4gICAgY29uc3QgbWF4TnVtSW5wdXRzVG9Vc2UgPSAyO1xuICAgIGNvbnN0IHVuc3BlbnRzID0gW1xuICAgICAgJ2NjMzA1NjU3NTBlMmFlYjgxODYyNWFhZWRhZjg5ZGI1YzYxNGU1OTc3Yjk2NDVjZWUxZDcyODlmNjE2ZmIxZDg6MCcsXG4gICAgICAnOGM0NTE2NDc4N2E5NTRhYjA3ODY0YWY5YjA1YjM0ZmJkZTNhOGU0MzBhOGM2NWIwZTYwZTRlNTQzZDhlMWI2YzoyJyxcbiAgICBdO1xuICAgIGxldCBiYXNlY29pbjtcbiAgICBsZXQgd2FsbGV0O1xuXG4gICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGJhc2Vjb2luID0gYml0Z28uY29pbigndGJ0YycpO1xuICAgICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgICAgaWQ6ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEnLFxuICAgICAgICBjb2luOiAndGJ0YycsXG4gICAgICAgIGtleXM6IFsnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc1J10sXG4gICAgICB9O1xuICAgICAgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHdhbGxldERhdGEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXNzIG1heE51bUlucHV0c1RvVXNlIHBhcmFtZXRlciB3aGVuIGNhbGxpbmcgZmFub3V0IHVuc3BlbnRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGF0aCA9IGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L2Zhbm91dFVuc3BlbnRzYDtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QocGF0aCwgXy5tYXRjaGVzKHsgbWF4TnVtSW5wdXRzVG9Vc2UgfSkpIC8vIHVzZSBfLm1hdGNoZXMgdG8gZG8gYSBwYXJ0aWFsIG1hdGNoIG9uIHJlcXVlc3QgYm9keSBvYmplY3QgaW5zdGVhZCBvZiBzdHJpY3QgbWF0Y2hpbmdcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHdhbGxldC5mYW5vdXRVbnNwZW50cyh7IGFkZHJlc3MsIG1heE51bUlucHV0c1RvVXNlIH0pO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyB0aGUgZmFub3V0VW5zcGVudHMgbWV0aG9kIHdpbGwgcHJvYmFibHkgdGhyb3cgYW4gZXhjZXB0aW9uIGZvciBub3QgaGF2aW5nIGFsbCBvZiB0aGUgY29ycmVjdCBub2Nrc1xuICAgICAgICAvLyB3ZSBvbmx5IGNhcmUgYWJvdXQgL2Zhbm91dFVuc3BlbnRzIGFuZCB3aGV0aGVyIG1heE51bUlucHV0c1RvVXNlIGlzIGFuIGFsbG93ZWQgcGFyYW1ldGVyXG4gICAgICB9XG5cbiAgICAgIHJlc3BvbnNlLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhc3MgdW5zcGVudHMgcGFyYW1ldGVyIHdoZW4gY2FsbGluZyBmYW5vdXQgdW5zcGVudHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXRoID0gYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vZmFub3V0VW5zcGVudHNgO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChwYXRoLCBfLm1hdGNoZXMoeyB1bnNwZW50cyB9KSkgLy8gdXNlIF8ubWF0Y2hlcyB0byBkbyBhIHBhcnRpYWwgbWF0Y2ggb24gcmVxdWVzdCBib2R5IG9iamVjdCBpbnN0ZWFkIG9mIHN0cmljdCBtYXRjaGluZ1xuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0LmZhbm91dFVuc3BlbnRzKHsgYWRkcmVzcywgdW5zcGVudHMgfSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIHRoZSBmYW5vdXRVbnNwZW50cyBtZXRob2Qgd2lsbCBwcm9iYWJseSB0aHJvdyBhbiBleGNlcHRpb24gZm9yIG5vdCBoYXZpbmcgYWxsIG9mIHRoZSBjb3JyZWN0IG5vY2tzXG4gICAgICAgIC8vIHdlIG9ubHkgY2FyZSBhYm91dCAvZmFub3V0VW5zcGVudHMgYW5kIHdoZXRoZXIgdW5zcGVudHMgaXMgYW4gYWxsb3dlZCBwYXJhbWV0ZXJcbiAgICAgIH1cblxuICAgICAgcmVzcG9uc2UuaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgb25seSBidWlsZCB0eCAobm90IHNpZ24vc2VuZCkgd2hpbGUgZmFubmluZyBvdXQgdW5zcGVudHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXRoID0gYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vZmFub3V0VW5zcGVudHNgO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBub2NrKGJnVXJsKS5wb3N0KHBhdGgsIF8ubWF0Y2hlcyh7IHVuc3BlbnRzIH0pKS5yZXBseSgyMDApO1xuXG4gICAgICBjb25zdCB1bnVzZWROb2NrcyA9IG5vY2soYmdVcmwpO1xuICAgICAgdW51c2VkTm9ja3MuZ2V0KGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0va2V5LyR7d2FsbGV0LmtleUlkcygpWzBdfWApLnJlcGx5KDIwMCk7XG4gICAgICB1bnVzZWROb2Nrcy5wb3N0KGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4L3NlbmRgKS5yZXBseSgyMDApO1xuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB3YWxsZXQuZmFub3V0VW5zcGVudHMoeyBhZGRyZXNzLCB1bnNwZW50cyB9LCBNYW5hZ2VVbnNwZW50c09wdGlvbnMuQlVJTERfT05MWSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIHRoZSBmYW5vdXRVbnNwZW50cyBtZXRob2Qgd2lsbCBwcm9iYWJseSB0aHJvdyBhbiBleGNlcHRpb24gZm9yIG5vdCBoYXZpbmcgYWxsIG9mIHRoZSBjb3JyZWN0IG5vY2tzXG4gICAgICAgIC8vIHdlIG9ubHkgY2FyZSBhYm91dCAvZmFub3V0VW5zcGVudHMgYW5kIHdoZXRoZXIgdW5zcGVudHMgaXMgYW4gYWxsb3dlZCBwYXJhbWV0ZXJcbiAgICAgIH1cblxuICAgICAgcmVzcG9uc2UuaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIHVudXNlZE5vY2tzLnBlbmRpbmdNb2NrcygpLmxlbmd0aC5zaG91bGQuZXFsKDIpO1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnbWFuYWdlIHVuc3BlbnRzJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCByb290V2FsbGV0S2V5O1xuICAgIGxldCB3YWxsZXRQYXNzcGhyYXNlO1xuICAgIGxldCBiYXNlY29pbjtcbiAgICBsZXQgd2FsbGV0O1xuICAgIGxldCBrZXlzT2JqO1xuXG4gICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJvb3RXYWxsZXRLZXkgPSBnZXREZWZhdWx0V2FsbGV0S2V5cygpO1xuICAgICAgd2FsbGV0UGFzc3BocmFzZSA9ICdmaXh0aGVtb25leWZpeHRoZXdvcmxkJztcbiAgICAgIGtleXNPYmogPSB0b0tleWNoYWluT2JqZWN0cyhyb290V2FsbGV0S2V5LCB3YWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgIGJhc2Vjb2luID0gYml0Z28uY29pbigndGJ0YycpO1xuICAgICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgICAgaWQ6ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEnLFxuICAgICAgICBjb2luOiAndGJ0YycsXG4gICAgICAgIGtleXM6IGtleXNPYmoubWFwKChrKSA9PiBrLmlkKSxcbiAgICAgIH07XG4gICAgICB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwgd2FsbGV0RGF0YSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhc3MgZm9yIGJ1bGsgY29uc29saWRhdGluZyB1bnNwZW50cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBzYnRzID0gKFsncDJ3c2gnLCAncDJzaFAyd3NoJ10gYXMgY29uc3QpLm1hcCgoc2NyaXB0VHlwZSkgPT5cbiAgICAgICAgdXR4b0xpYi50ZXN0dXRpbC5jb25zdHJ1Y3RQc2J0KFxuICAgICAgICAgIFt7IHNjcmlwdFR5cGUsIHZhbHVlOiBCaWdJbnQoMTAwMCkgfV0sXG4gICAgICAgICAgW3sgc2NyaXB0VHlwZSwgdmFsdWU6IEJpZ0ludCg5MDApIH1dLFxuICAgICAgICAgIGJhc2Vjb2luLm5ldHdvcmssXG4gICAgICAgICAgcm9vdFdhbGxldEtleSxcbiAgICAgICAgICAndW5zaWduZWQnXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgICBjb25zdCB0eEhleGVzID0gcHNidHMubWFwKChwc2J0KSA9PiAoeyB0eEhleDogcHNidC50b0hleCgpIH0pKTtcblxuICAgICAgY29uc3Qgbm9ja3M6IG5vY2suU2NvcGVbXSA9IFtdO1xuICAgICAgbm9ja3MucHVzaChcbiAgICAgICAgbm9jayhiZ1VybCkucG9zdChgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS9jb25zb2xpZGF0ZVVuc3BlbnRzYCkucmVwbHkoMjAwLCB0eEhleGVzKVxuICAgICAgKTtcblxuICAgICAgbm9ja3MucHVzaChcbiAgICAgICAgLi4ua2V5c09iai5tYXAoKGssIGkpID0+IG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L2tleS8ke3dhbGxldC5rZXlJZHMoKVtpXX1gKS5yZXBseSgyMDAsIGspKVxuICAgICAgKTtcblxuICAgICAgbm9ja3MucHVzaChcbiAgICAgICAgLi4ucHNidHMubWFwKChwc2J0KSA9PlxuICAgICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgICAucG9zdChcbiAgICAgICAgICAgICAgYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvc2VuZGAsXG4gICAgICAgICAgICAgIF8ubWF0Y2hlcyh7IHR4SGV4OiBwc2J0LnNpZ25BbGxJbnB1dHNIRChyb290V2FsbGV0S2V5LnVzZXIpLnRvSGV4KCkgfSlcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5yZXBseSgyMDApXG4gICAgICAgIClcbiAgICAgICk7XG5cbiAgICAgIGF3YWl0IHdhbGxldC5jb25zb2xpZGF0ZVVuc3BlbnRzKHsgYnVsazogdHJ1ZSwgd2FsbGV0UGFzc3BocmFzZSB9KTtcblxuICAgICAgbm9ja3MuZm9yRWFjaCgobikgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZyhuKTtcbiAgICAgICAgbi5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhc3MgZm9yIHNpbmdsZSBjb25zb2xpZGF0aW5nIHVuc3BlbnRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHNidCA9IHV0eG9MaWIudGVzdHV0aWwuY29uc3RydWN0UHNidChcbiAgICAgICAgW3sgc2NyaXB0VHlwZTogJ3Ayd3NoJywgdmFsdWU6IEJpZ0ludCgxMDAwKSB9XSxcbiAgICAgICAgW3sgc2NyaXB0VHlwZTogJ3Ayc2hQMndzaCcsIHZhbHVlOiBCaWdJbnQoOTAwKSB9XSxcbiAgICAgICAgYmFzZWNvaW4ubmV0d29yayxcbiAgICAgICAgcm9vdFdhbGxldEtleSxcbiAgICAgICAgJ3Vuc2lnbmVkJ1xuICAgICAgKTtcblxuICAgICAgY29uc3Qgbm9ja3M6IG5vY2suU2NvcGVbXSA9IFtdO1xuICAgICAgbm9ja3MucHVzaChcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucG9zdChgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS9jb25zb2xpZGF0ZVVuc3BlbnRzYClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IHR4SGV4OiBwc2J0LnRvSGV4KCkgfSlcbiAgICAgICk7XG5cbiAgICAgIG5vY2tzLnB1c2goXG4gICAgICAgIC4uLmtleXNPYmoubWFwKChrLCBpKSA9PiBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS9rZXkvJHt3YWxsZXQua2V5SWRzKClbaV19YCkucmVwbHkoMjAwLCBrKSlcbiAgICAgICk7XG5cbiAgICAgIG5vY2tzLnB1c2goXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoXG4gICAgICAgICAgICBgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC9zZW5kYCxcbiAgICAgICAgICAgIF8ubWF0Y2hlcyh7IHR4SGV4OiBwc2J0LnNpZ25BbGxJbnB1dHNIRChyb290V2FsbGV0S2V5LnVzZXIpLnRvSGV4KCkgfSlcbiAgICAgICAgICApXG4gICAgICAgICAgLnJlcGx5KDIwMClcbiAgICAgICk7XG5cbiAgICAgIGF3YWl0IHdhbGxldC5jb25zb2xpZGF0ZVVuc3BlbnRzKHsgd2FsbGV0UGFzc3BocmFzZSB9KTtcblxuICAgICAgbm9ja3MuZm9yRWFjaCgobikgPT4ge1xuICAgICAgICBuLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG4gIGRlc2NyaWJlKCdtYXggcmVjaXBpZW50JywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGFkZHJlc3MgPSAnNWIzNDI1MmYxYmYzNDk5MzBlMzQwMjBhJztcbiAgICBjb25zdCByZWNpcGllbnRzID0gW1xuICAgICAge1xuICAgICAgICBhZGRyZXNzLFxuICAgICAgICBhbW91bnQ6ICdtYXgnLFxuICAgICAgfSxcbiAgICBdO1xuICAgIGxldCBiYXNlY29pbjtcbiAgICBsZXQgd2FsbGV0O1xuXG4gICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGJhc2Vjb2luID0gYml0Z28uY29pbigndGJ0YycpO1xuICAgICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgICAgaWQ6ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEnLFxuICAgICAgICBjb2luOiAndGJ0YycsXG4gICAgICAgIGtleXM6IFsnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc1J10sXG4gICAgICB9O1xuICAgICAgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHdhbGxldERhdGEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXNzIG1heEZlZVJhdGUgcGFyYW1ldGVyIHdoZW4gYnVpbGRpbmcgdHJhbnNhY3Rpb25zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGF0aCA9IGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4L2J1aWxkYDtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoXG4gICAgICAgICAgcGF0aCxcbiAgICAgICAgICBfLm1hdGNoZXMoe1xuICAgICAgICAgICAgcmVjaXBpZW50cyxcbiAgICAgICAgICB9KVxuICAgICAgICApIC8vIHVzZSBfLm1hdGNoZXMgdG8gZG8gYSBwYXJ0aWFsIG1hdGNoIG9uIHJlcXVlc3QgYm9keSBvYmplY3QgaW5zdGVhZCBvZiBzdHJpY3QgbWF0Y2hpbmdcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHdhbGxldC5wcmVidWlsZFRyYW5zYWN0aW9uKHsgcmVjaXBpZW50cyB9KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gdGhlIHByZWJ1aWxkVHJhbnNhY3Rpb24gbWV0aG9kIHdpbGwgcHJvYmFibHkgdGhyb3cgYW4gZXhjZXB0aW9uIGZvciBub3QgaGF2aW5nIGFsbCBvZiB0aGUgY29ycmVjdCBub2Nrc1xuICAgICAgICAvLyB3ZSBvbmx5IGNhcmUgYWJvdXQgL3R4L2J1aWxkIGFuZCB3aGV0aGVyIG1heEZlZVJhdGUgaXMgYW4gYWxsb3dlZCBwYXJhbWV0ZXJcbiAgICAgIH1cblxuICAgICAgcmVzcG9uc2UuaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ21heEZlZVJhdGUgdmVyaWZpY2F0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGFkZHJlc3MgPSAnNWIzNDI1MmYxYmYzNDk5MzBlMzQwMjBhJztcbiAgICBjb25zdCByZWNpcGllbnRzID0gW1xuICAgICAge1xuICAgICAgICBhZGRyZXNzLFxuICAgICAgICBhbW91bnQ6IDAsXG4gICAgICB9LFxuICAgIF07XG4gICAgY29uc3QgbWF4RmVlUmF0ZSA9IDEwMDAwO1xuICAgIGxldCBiYXNlY29pbjtcbiAgICBsZXQgd2FsbGV0O1xuXG4gICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGJhc2Vjb2luID0gYml0Z28uY29pbigndGJ0YycpO1xuICAgICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgICAgaWQ6ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEnLFxuICAgICAgICBjb2luOiAndGJ0YycsXG4gICAgICAgIGtleXM6IFsnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc1J10sXG4gICAgICB9O1xuICAgICAgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHdhbGxldERhdGEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXNzIG1heEZlZVJhdGUgcGFyYW1ldGVyIHdoZW4gYnVpbGRpbmcgdHJhbnNhY3Rpb25zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGF0aCA9IGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4L2J1aWxkYDtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QocGF0aCwgXy5tYXRjaGVzKHsgcmVjaXBpZW50cywgbWF4RmVlUmF0ZSB9KSkgLy8gdXNlIF8ubWF0Y2hlcyB0byBkbyBhIHBhcnRpYWwgbWF0Y2ggb24gcmVxdWVzdCBib2R5IG9iamVjdCBpbnN0ZWFkIG9mIHN0cmljdCBtYXRjaGluZ1xuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0LnByZWJ1aWxkVHJhbnNhY3Rpb24oeyByZWNpcGllbnRzLCBtYXhGZWVSYXRlIH0pO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyB0aGUgcHJlYnVpbGRUcmFuc2FjdGlvbiBtZXRob2Qgd2lsbCBwcm9iYWJseSB0aHJvdyBhbiBleGNlcHRpb24gZm9yIG5vdCBoYXZpbmcgYWxsIG9mIHRoZSBjb3JyZWN0IG5vY2tzXG4gICAgICAgIC8vIHdlIG9ubHkgY2FyZSBhYm91dCAvdHgvYnVpbGQgYW5kIHdoZXRoZXIgbWF4RmVlUmF0ZSBpcyBhbiBhbGxvd2VkIHBhcmFtZXRlclxuICAgICAgfVxuXG4gICAgICByZXNwb25zZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXNzIG1heEZlZVJhdGUgcGFyYW1ldGVyIHdoZW4gY29uc29saWRhdGluZyB1bnNwZW50cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhdGggPSBgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS9jb25zb2xpZGF0ZVVuc3BlbnRzYDtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QocGF0aCwgXy5tYXRjaGVzKHsgbWF4RmVlUmF0ZSB9KSkgLy8gdXNlIF8ubWF0Y2hlcyB0byBkbyBhIHBhcnRpYWwgbWF0Y2ggb24gcmVxdWVzdCBib2R5IG9iamVjdCBpbnN0ZWFkIG9mIHN0cmljdCBtYXRjaGluZ1xuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0va2V5LyR7d2FsbGV0LmtleUlkcygpWzBdfWApLnJlcGx5KDIwMCk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHdhbGxldC5jb25zb2xpZGF0ZVVuc3BlbnRzKHsgcmVjaXBpZW50cywgbWF4RmVlUmF0ZSB9KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gdGhlIGNvbnNvbGlkYXRlVW5zcGVudHMgbWV0aG9kIHdpbGwgcHJvYmFibHkgdGhyb3cgYW4gZXhjZXB0aW9uIGZvciBub3QgaGF2aW5nIGFsbCBvZiB0aGUgY29ycmVjdCBub2Nrc1xuICAgICAgICAvLyB3ZSBvbmx5IGNhcmUgYWJvdXQgL2NvbnNvbGlkYXRlVW5zcGVudHMgYW5kIHdoZXRoZXIgbWF4RmVlUmF0ZSBpcyBhbiBhbGxvd2VkIHBhcmFtZXRlclxuICAgICAgfVxuXG4gICAgICByZXNwb25zZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBvbmx5IGJ1aWxkIHR4IChub3Qgc2lnbi9zZW5kKSB3aGlsZSBjb25zb2xpZGF0aW5nIHVuc3BlbnRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdG9CZVVzZWROb2NrID0gbm9jayhiZ1VybCk7XG4gICAgICB0b0JlVXNlZE5vY2sucG9zdChgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS9jb25zb2xpZGF0ZVVuc3BlbnRzYCkucmVwbHkoMjAwKTtcblxuICAgICAgY29uc3QgdW51c2VkTm9ja3MgPSBub2NrKGJnVXJsKTtcbiAgICAgIHVudXNlZE5vY2tzLmdldChgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L2tleS8ke3dhbGxldC5rZXlJZHMoKVswXX1gKS5yZXBseSgyMDApO1xuICAgICAgdW51c2VkTm9ja3MucG9zdChgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC9zZW5kYCkucmVwbHkoMjAwKTtcblxuICAgICAgYXdhaXQgd2FsbGV0LmNvbnNvbGlkYXRlVW5zcGVudHMoeyByZWNpcGllbnRzIH0sIE1hbmFnZVVuc3BlbnRzT3B0aW9ucy5CVUlMRF9PTkxZKTtcblxuICAgICAgdG9CZVVzZWROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICB1bnVzZWROb2Nrcy5wZW5kaW5nTW9ja3MoKS5sZW5ndGguc2hvdWxkLmVxbCgyKTtcbiAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFzcyBtYXhGZWVSYXRlIHBhcmFtZXRlciB3aGVuIGNhbGxpbmcgc3dlZXAgd2FsbGV0cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhdGggPSBgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS9zd2VlcFdhbGxldGA7XG4gICAgICBjb25zdCByZXNwb25zZSA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KHBhdGgsIF8ubWF0Y2hlcyh7IGFkZHJlc3MsIG1heEZlZVJhdGUgfSkpIC8vIHVzZSBfLm1hdGNoZXMgdG8gZG8gYSBwYXJ0aWFsIG1hdGNoIG9uIHJlcXVlc3QgYm9keSBvYmplY3QgaW5zdGVhZCBvZiBzdHJpY3QgbWF0Y2hpbmdcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHdhbGxldC5zd2VlcCh7IGFkZHJlc3MsIG1heEZlZVJhdGUgfSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIHRoZSBzd2VlcCBtZXRob2Qgd2lsbCBwcm9iYWJseSB0aHJvdyBhbiBleGNlcHRpb24gZm9yIG5vdCBoYXZpbmcgYWxsIG9mIHRoZSBjb3JyZWN0IG5vY2tzXG4gICAgICAgIC8vIHdlIG9ubHkgY2FyZSBhYm91dCAvc3dlZXBXYWxsZXQgYW5kIHdoZXRoZXIgbWF4RmVlUmF0ZSBpcyBhbiBhbGxvd2VkIHBhcmFtZXRlclxuICAgICAgfVxuXG4gICAgICByZXNwb25zZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXNzIG1heEZlZVJhdGUgcGFyYW1ldGVyIHdoZW4gY2FsbGluZyBmYW5vdXQgdW5zcGVudHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXRoID0gYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vZmFub3V0VW5zcGVudHNgO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChwYXRoLCBfLm1hdGNoZXMoeyBtYXhGZWVSYXRlIH0pKSAvLyB1c2UgXy5tYXRjaGVzIHRvIGRvIGEgcGFydGlhbCBtYXRjaCBvbiByZXF1ZXN0IGJvZHkgb2JqZWN0IGluc3RlYWQgb2Ygc3RyaWN0IG1hdGNoaW5nXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB3YWxsZXQuZmFub3V0VW5zcGVudHMoeyBhZGRyZXNzLCBtYXhGZWVSYXRlIH0pO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyB0aGUgZmFub3V0VW5zcGVudHMgbWV0aG9kIHdpbGwgcHJvYmFibHkgdGhyb3cgYW4gZXhjZXB0aW9uIGZvciBub3QgaGF2aW5nIGFsbCBvZiB0aGUgY29ycmVjdCBub2Nrc1xuICAgICAgICAvLyB3ZSBvbmx5IGNhcmUgYWJvdXQgL2Zhbm91dFVuc3BlbnRzIGFuZCB3aGV0aGVyIG1heEZlZVJhdGUgaXMgYW4gYWxsb3dlZCBwYXJhbWV0ZXJcbiAgICAgIH1cblxuICAgICAgcmVzcG9uc2UuaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2FsbG93UGFydGlhbFN3ZWVwIHZlcmlmaWNhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBhZGRyZXNzID0gJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYSc7XG4gICAgY29uc3QgYWxsb3dQYXJ0aWFsU3dlZXAgPSB0cnVlO1xuICAgIGxldCBiYXNlY29pbjtcbiAgICBsZXQgd2FsbGV0O1xuXG4gICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGJhc2Vjb2luID0gYml0Z28uY29pbigndGJ0YycpO1xuICAgICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgICAgaWQ6ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEnLFxuICAgICAgICBjb2luOiAndGJ0YycsXG4gICAgICAgIGtleXM6IFsnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc1J10sXG4gICAgICB9O1xuICAgICAgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHdhbGxldERhdGEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXNzIGFsbG93UGFydGlhbFN3ZWVwIHBhcmFtZXRlciB3aGVuIGNhbGxpbmcgc3dlZXAgd2FsbGV0cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhdGggPSBgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS9zd2VlcFdhbGxldGA7XG4gICAgICBjb25zdCByZXNwb25zZSA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KHBhdGgsIF8ubWF0Y2hlcyh7IGFkZHJlc3MsIGFsbG93UGFydGlhbFN3ZWVwIH0pKSAvLyB1c2UgXy5tYXRjaGVzIHRvIGRvIGEgcGFydGlhbCBtYXRjaCBvbiByZXF1ZXN0IGJvZHkgb2JqZWN0IGluc3RlYWQgb2Ygc3RyaWN0IG1hdGNoaW5nXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB3YWxsZXQuc3dlZXAoeyBhZGRyZXNzLCBhbGxvd1BhcnRpYWxTd2VlcCB9KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gdGhlIHN3ZWVwIG1ldGhvZCB3aWxsIHByb2JhYmx5IHRocm93IGFuIGV4Y2VwdGlvbiBmb3Igbm90IGhhdmluZyBhbGwgb2YgdGhlIGNvcnJlY3Qgbm9ja3NcbiAgICAgICAgLy8gd2Ugb25seSBjYXJlIGFib3V0IC9zd2VlcFdhbGxldCBhbmQgd2hldGhlciBhbGxvd1BhcnRpYWxTd2VlcCBpcyBhbiBhbGxvd2VkIHBhcmFtZXRlclxuICAgICAgfVxuXG4gICAgICByZXNwb25zZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnc3dlZXAgd2FsbGV0JywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBiYXNlY29pbjtcbiAgICBsZXQgd2FsbGV0O1xuXG4gICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGJhc2Vjb2luID0gYml0Z28uY29pbigndHRyeCcpO1xuICAgICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgICAgaWQ6ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEnLFxuICAgICAgICBjb2luOiAndHRyeCcsXG4gICAgICAgIGtleXM6IFsnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc1J10sXG4gICAgICB9O1xuICAgICAgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHdhbGxldERhdGEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB1c2UgbWF4aW11bSBzcGVuZGFibGUgYmFsYW5jZSBvZiB3YWxsZXQgdG8gc3dlZXAgZnVuZHMgJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGF0aCA9IGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L21heGltdW1TcGVuZGFibGVgO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBub2NrKGJnVXJsKS5nZXQocGF0aCkucmVwbHkoMjAwLCB7XG4gICAgICAgIGNvaW46ICd0dHJ4JyxcbiAgICAgICAgbWF4aW11bVNwZW5kYWJsZTogNjUwMDAsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGJvZHkgPSB7XG4gICAgICAgIGNvaW46ICd0dHJ4JyxcbiAgICAgICAgYWRkcmVzczogJzJNd3ZSMjR5cXltMkNnSE1wN3p3dmRlcUJhNEY4S1RxdW5TJyxcbiAgICAgIH07XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB3YWxsZXQuc3dlZXAoYm9keSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIHRoZSBzd2VlcCBtZXRob2Qgd2lsbCBwcm9iYWJseSB0aHJvdyBhbiBleGNlcHRpb24gZm9yIG5vdCBoYXZpbmcgYWxsIG9mIHRoZSBjb3JyZWN0IG5vY2tzXG4gICAgICAgIC8vIHdlIG9ubHkgY2FyZSBhYm91dCBtYXhpbXVtIHNwZW5kYWJsZSBiYWxhbmNlIGJlaW5nIHVzZWQgdG8gc3dlZXAgZnVuZHNcbiAgICAgIH1cblxuICAgICAgcmVzcG9uc2UuaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1RyYW5zYWN0aW9uIHByZWJ1aWxkcycsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgZXRoV2FsbGV0O1xuXG4gICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldERhdGEgPSB7XG4gICAgICAgIGlkOiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWRiMWQ5NDU5YmInLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIGtleXM6IFtcbiAgICAgICAgICAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWQ4OWRjZTg2YzInLFxuICAgICAgICAgICc1OThmNjA2Y2M4ZTQzYWVmMDlmY2I3ODUyMjFkOWRkMicsXG4gICAgICAgICAgJzU5MzVkNTljZjY2MDc2NDMzMWJhZmNhZGUxODU1ZmQ3JyxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgICBldGhXYWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiaXRnby5jb2luKCd0ZXRoJyksIHdhbGxldERhdGEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gcmVxSWQgaWYgaXQgd2FzIHBhc3NlZCBpbiB0aGUgcGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zID0geyBvZmZsaW5lVmVyaWZpY2F0aW9uOiB0cnVlIH07XG4gICAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4L2J1aWxkYCwgdGJ0Y0hvdFdhbGxldERlZmF1bHRQYXJhbXMpXG4gICAgICAgIC5xdWVyeShwYXJhbXMpXG4gICAgICAgIC5yZXBseSgyMDAsIHt9KTtcbiAgICAgIGNvbnN0IGJsb2NrSGVpZ2h0ID0gMTAwO1xuICAgICAgc2lub24uc3R1YihiYXNlY29pbiwgJ2dldExhdGVzdEJsb2NrSGVpZ2h0JykucmVzb2x2ZXMoYmxvY2tIZWlnaHQpO1xuICAgICAgc2lub24uc3R1YihiYXNlY29pbiwgJ3Bvc3RQcm9jZXNzUHJlYnVpbGQnKS5yZXNvbHZlcyh7fSk7XG4gICAgICBjb25zdCB0eFJlcXVlc3QgPSBhd2FpdCB3YWxsZXQucHJlYnVpbGRUcmFuc2FjdGlvbih7IC4uLnBhcmFtcywgcmVxSWQ6IHJlcUlkIH0pO1xuICAgICAgdHhSZXF1ZXN0LnJlcUlkPy5zaG91bGQuY29udGFpbkVxbChyZXFJZCk7XG4gICAgICBzY29wZS5kb25lKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhc3Mgb2ZmbGluZVZlcmlmaWNhdGlvbj10cnVlIHF1ZXJ5IHBhcmFtIGlmIHBhc3NlZCB0cnV0aHkgdmFsdWUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJhbXMgPSB7IG9mZmxpbmVWZXJpZmljYXRpb246IHRydWUgfTtcbiAgICAgIGNvbnN0IHNjb3BlID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvYnVpbGRgLCB0YnRjSG90V2FsbGV0RGVmYXVsdFBhcmFtcylcbiAgICAgICAgLnF1ZXJ5KHBhcmFtcylcbiAgICAgICAgLnJlcGx5KDIwMCwge30pO1xuICAgICAgY29uc3QgYmxvY2tIZWlnaHQgPSAxMDA7XG4gICAgICBjb25zdCBibG9ja0hlaWdodFN0dWIgPSBzaW5vbi5zdHViKGJhc2Vjb2luLCAnZ2V0TGF0ZXN0QmxvY2tIZWlnaHQnKS5yZXNvbHZlcyhibG9ja0hlaWdodCk7XG4gICAgICBjb25zdCBwb3N0UHJvY2Vzc1N0dWIgPSBzaW5vbi5zdHViKGJhc2Vjb2luLCAncG9zdFByb2Nlc3NQcmVidWlsZCcpLnJlc29sdmVzKHt9KTtcbiAgICAgIGF3YWl0IHdhbGxldC5wcmVidWlsZFRyYW5zYWN0aW9uKHBhcmFtcyk7XG4gICAgICBibG9ja0hlaWdodFN0dWIuc2hvdWxkLmhhdmUuYmVlbi5jYWxsZWRPbmNlKCk7XG4gICAgICBwb3N0UHJvY2Vzc1N0dWIuc2hvdWxkLmhhdmUuYmVlbi5jYWxsZWRPbmNlV2l0aCh7XG4gICAgICAgIGJsb2NrSGVpZ2h0OiAxMDAsXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICBidWlsZFBhcmFtczogdGJ0Y0hvdFdhbGxldERlZmF1bHRQYXJhbXMsXG4gICAgICB9KTtcbiAgICAgIHNjb3BlLmRvbmUoKTtcbiAgICAgIGJsb2NrSGVpZ2h0U3R1Yi5yZXN0b3JlKCk7XG4gICAgICBwb3N0UHJvY2Vzc1N0dWIucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBub3QgcGFzcyB0aGUgb2ZmbGluZVZlcmlmaWNhdGlvbiBxdWVyeSBwYXJhbSBpZiBwYXNzZWQgYSBmYWxzZXkgdmFsdWUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJhbXMgPSB7IG9mZmxpbmVWZXJpZmljYXRpb246IGZhbHNlIH07XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC9idWlsZGAsIHRidGNIb3RXYWxsZXREZWZhdWx0UGFyYW1zKVxuICAgICAgICAucXVlcnkoe30pXG4gICAgICAgIC5yZXBseSgyMDAsIHt9KTtcbiAgICAgIGNvbnN0IGJsb2NrSGVpZ2h0ID0gMTAwO1xuICAgICAgY29uc3QgYmxvY2tIZWlnaHRTdHViID0gc2lub24uc3R1YihiYXNlY29pbiwgJ2dldExhdGVzdEJsb2NrSGVpZ2h0JykucmVzb2x2ZXMoYmxvY2tIZWlnaHQpO1xuICAgICAgY29uc3QgcG9zdFByb2Nlc3NTdHViID0gc2lub24uc3R1YihiYXNlY29pbiwgJ3Bvc3RQcm9jZXNzUHJlYnVpbGQnKS5yZXNvbHZlcyh7fSk7XG4gICAgICBhd2FpdCB3YWxsZXQucHJlYnVpbGRUcmFuc2FjdGlvbihwYXJhbXMpO1xuICAgICAgYmxvY2tIZWlnaHRTdHViLnNob3VsZC5oYXZlLmJlZW4uY2FsbGVkT25jZSgpO1xuICAgICAgcG9zdFByb2Nlc3NTdHViLnNob3VsZC5oYXZlLmJlZW4uY2FsbGVkT25jZVdpdGgoe1xuICAgICAgICBibG9ja0hlaWdodDogMTAwLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgYnVpbGRQYXJhbXM6IHRidGNIb3RXYWxsZXREZWZhdWx0UGFyYW1zLFxuICAgICAgfSk7XG4gICAgICBibG9ja0hlaWdodFN0dWIucmVzdG9yZSgpO1xuICAgICAgcG9zdFByb2Nlc3NTdHViLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFzcyBzY3JpcHQgb3V0cHV0cyB3aXRoIHRoZSBwcm9wZXIgc3RydWN0dXJlIHRvIHdhbGxldCBwbGF0Zm9ybScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNjcmlwdCA9ICc2YTExMjIzMzQ0NTU2Njc3ODg5OTAwJztcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4L2J1aWxkYCwge1xuICAgICAgICAgIC4uLnRidGNIb3RXYWxsZXREZWZhdWx0UGFyYW1zLFxuICAgICAgICAgIHJlY2lwaWVudHM6IFt7IHNjcmlwdCwgYW1vdW50OiAxZTYgfV0sXG4gICAgICAgIH0pXG4gICAgICAgIC5xdWVyeSh7fSlcbiAgICAgICAgLnJlcGx5KDIwMCwge30pO1xuXG4gICAgICBjb25zdCBibG9ja0hlaWdodCA9IDEwMDtcbiAgICAgIGNvbnN0IGJsb2NrSGVpZ2h0U3R1YiA9IHNpbm9uLnN0dWIoYmFzZWNvaW4sICdnZXRMYXRlc3RCbG9ja0hlaWdodCcpLnJlc29sdmVzKGJsb2NrSGVpZ2h0KTtcbiAgICAgIGNvbnN0IHBvc3RQcm9jZXNzU3R1YiA9IHNpbm9uLnN0dWIoYmFzZWNvaW4sICdwb3N0UHJvY2Vzc1ByZWJ1aWxkJykucmVzb2x2ZXMoe30pO1xuICAgICAgYXdhaXQgd2FsbGV0LnByZWJ1aWxkVHJhbnNhY3Rpb24oeyByZWNpcGllbnRzOiBbeyBhZGRyZXNzOiBgc2NyaXB0UHViS2V5OiR7c2NyaXB0fWAsIGFtb3VudDogMWU2IH1dIH0pO1xuICAgICAgYmxvY2tIZWlnaHRTdHViLnNob3VsZC5oYXZlLmJlZW4uY2FsbGVkT25jZSgpO1xuICAgICAgcG9zdFByb2Nlc3NTdHViLnNob3VsZC5oYXZlLmJlZW4uY2FsbGVkT25jZVdpdGgoe1xuICAgICAgICBibG9ja0hlaWdodDogMTAwLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgYnVpbGRQYXJhbXM6IHsgLi4udGJ0Y0hvdFdhbGxldERlZmF1bHRQYXJhbXMsIHJlY2lwaWVudHM6IFt7IHNjcmlwdCwgYW1vdW50OiAxZTYgfV0gfSxcbiAgICAgIH0pO1xuICAgICAgYmxvY2tIZWlnaHRTdHViLnJlc3RvcmUoKTtcbiAgICAgIHBvc3RQcm9jZXNzU3R1Yi5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgncHJlYnVpbGQgc2hvdWxkIGNhbGwgYnVpbGQgYW5kIGdldExhdGVzdEJsb2NrSGVpZ2h0IGZvciB1dHhvIGNvaW5zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zID0ge307XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC9idWlsZGAsIHRidGNIb3RXYWxsZXREZWZhdWx0UGFyYW1zKVxuICAgICAgICAucXVlcnkocGFyYW1zKVxuICAgICAgICAucmVwbHkoMjAwLCB7fSk7XG4gICAgICBjb25zdCBibG9ja0hlaWdodCA9IDEwMDtcbiAgICAgIGNvbnN0IGJsb2NrSGVpZ2h0U3R1YiA9IHNpbm9uLnN0dWIoYmFzZWNvaW4sICdnZXRMYXRlc3RCbG9ja0hlaWdodCcpLnJlc29sdmVzKGJsb2NrSGVpZ2h0KTtcbiAgICAgIGNvbnN0IHBvc3RQcm9jZXNzU3R1YiA9IHNpbm9uLnN0dWIoYmFzZWNvaW4sICdwb3N0UHJvY2Vzc1ByZWJ1aWxkJykucmVzb2x2ZXMoe30pO1xuICAgICAgYXdhaXQgd2FsbGV0LnByZWJ1aWxkVHJhbnNhY3Rpb24ocGFyYW1zKTtcbiAgICAgIGJsb2NrSGVpZ2h0U3R1Yi5zaG91bGQuaGF2ZS5iZWVuLmNhbGxlZE9uY2UoKTtcbiAgICAgIHBvc3RQcm9jZXNzU3R1Yi5zaG91bGQuaGF2ZS5iZWVuLmNhbGxlZE9uY2VXaXRoKHtcbiAgICAgICAgYmxvY2tIZWlnaHQ6IDEwMCxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIGJ1aWxkUGFyYW1zOiB0YnRjSG90V2FsbGV0RGVmYXVsdFBhcmFtcyxcbiAgICAgIH0pO1xuICAgICAgYmxvY2tIZWlnaHRTdHViLnJlc3RvcmUoKTtcbiAgICAgIHBvc3RQcm9jZXNzU3R1Yi5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgncHJlYnVpbGQgc2hvdWxkIG5vdCBoYXZlIGNoYW5nZUFkZHJlc3NUeXBlIGFycmF5IGluIHBvc3QgYm9keSB3aGVuIGNoYW5nZUFkZHJlc3NUeXBlIGlzIGRlZmluZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBlY3RlZEJ1aWxkUG9zdEJvZHlQYXJhbXMgPSB7XG4gICAgICAgIGNoYW5nZUFkZHJlc3NUeXBlOiAncDJ0ck11c2lnMicsXG4gICAgICAgIHR4Rm9ybWF0OiAncHNidCcsXG4gICAgICB9O1xuXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC9idWlsZGAsIGV4cGVjdGVkQnVpbGRQb3N0Qm9keVBhcmFtcylcbiAgICAgICAgLnF1ZXJ5KHt9KVxuICAgICAgICAucmVwbHkoMjAwLCB7fSk7XG4gICAgICBjb25zdCBibG9ja0hlaWdodCA9IDEwMDtcbiAgICAgIGNvbnN0IGJsb2NrSGVpZ2h0U3R1YiA9IHNpbm9uLnN0dWIoYmFzZWNvaW4sICdnZXRMYXRlc3RCbG9ja0hlaWdodCcpLnJlc29sdmVzKGJsb2NrSGVpZ2h0KTtcbiAgICAgIGNvbnN0IHBvc3RQcm9jZXNzU3R1YiA9IHNpbm9uLnN0dWIoYmFzZWNvaW4sICdwb3N0UHJvY2Vzc1ByZWJ1aWxkJykucmVzb2x2ZXMoe30pO1xuICAgICAgYXdhaXQgd2FsbGV0LnByZWJ1aWxkVHJhbnNhY3Rpb24oeyBjaGFuZ2VBZGRyZXNzVHlwZTogJ3AydHJNdXNpZzInIH0pO1xuICAgICAgYmxvY2tIZWlnaHRTdHViLnNob3VsZC5oYXZlLmJlZW4uY2FsbGVkT25jZSgpO1xuICAgICAgcG9zdFByb2Nlc3NTdHViLnNob3VsZC5oYXZlLmJlZW4uY2FsbGVkT25jZVdpdGgoe1xuICAgICAgICBibG9ja0hlaWdodDogMTAwLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgYnVpbGRQYXJhbXM6IGV4cGVjdGVkQnVpbGRQb3N0Qm9keVBhcmFtcyxcbiAgICAgIH0pO1xuICAgICAgYmxvY2tIZWlnaHRTdHViLnJlc3RvcmUoKTtcbiAgICAgIHBvc3RQcm9jZXNzU3R1Yi5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgncHJlYnVpbGQgc2hvdWxkIGNhbGwgYnVpbGQgYnV0IG5vdCBnZXRMYXRlc3RCbG9ja0hlaWdodCBmb3IgYWNjb3VudCBjb2lucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIFsndHhycCcsICd0eGxtJywgJ3RldGgnXS5mb3JFYWNoKGFzeW5jIGZ1bmN0aW9uIChjb2luKSB7XG4gICAgICAgIGNvbnN0IGFjY291bnRjb2luID0gYml0Z28uY29pbihjb2luKTtcbiAgICAgICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgICAgICBpZDogJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIxYScsXG4gICAgICAgICAgY29pbixcbiAgICAgICAgICBrZXlzOiBbJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NSddLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBhY2NvdW50V2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYWNjb3VudGNvaW4sIHdhbGxldERhdGEpO1xuICAgICAgICBjb25zdCBwYXJhbXMgPSB7fTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucG9zdChgL2FwaS92Mi8ke2FjY291bnRXYWxsZXQuY29pbigpfS93YWxsZXQvJHthY2NvdW50V2FsbGV0LmlkKCl9L3R4L2J1aWxkYClcbiAgICAgICAgICAucXVlcnkocGFyYW1zKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHt9KTtcbiAgICAgICAgY29uc3QgcG9zdFByb2Nlc3NTdHViID0gc2lub24uc3R1YihhY2NvdW50Y29pbiwgJ3Bvc3RQcm9jZXNzUHJlYnVpbGQnKS5yZXNvbHZlcyh7fSk7XG4gICAgICAgIGF3YWl0IGFjY291bnRXYWxsZXQucHJlYnVpbGRUcmFuc2FjdGlvbihwYXJhbXMpO1xuICAgICAgICBwb3N0UHJvY2Vzc1N0dWIuc2hvdWxkLmhhdmUuYmVlbi5jYWxsZWRPbmNlV2l0aCh7XG4gICAgICAgICAgd2FsbGV0OiBhY2NvdW50V2FsbGV0LFxuICAgICAgICAgIGJ1aWxkUGFyYW1zOiB7fSxcbiAgICAgICAgfSk7XG4gICAgICAgIHBvc3RQcm9jZXNzU3R1Yi5yZXN0b3JlKCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSBpc0JhdGNoID0gdHJ1ZSBpbiB0aGUgdHhQcmVidWlsZCBpZiB0eFBhcmFtcyBoYXMgbW9yZSB0aGFuIG9uZSByZWNpcGllbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHsgYW1vdW50OiAnMTAwMDAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH0sXG4gICAgICAgICAgeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnMHhkZjA3MTE3NzA1YTlmOGRjNGMyYTc4ZGU2NmI3ZjE3OTdkYmE5ZDRlJyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ21vb24nLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdG90YWxBbW91bnQgPSAnMjAwMDAwMDAwMDAwMDAwMCc7XG5cbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KFxuICAgICAgICAgIGAvYXBpL3YyLyR7ZXRoV2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7ZXRoV2FsbGV0LmlkKCl9L3R4L2J1aWxkYCxcbiAgICAgICAgICBfLm1hdGNoZXMoeyByZWNpcGllbnRzOiB0eFBhcmFtcy5yZWNpcGllbnRzIH0pXG4gICAgICAgIClcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYWRkcmVzczogJzB4YzBhYWYyNjQ5ZTdiMGYzOTUwMTY0NjgxZWNhMmIxYThmNjU0YTQ3OCcsXG4gICAgICAgICAgICAgIGFtb3VudDogJzIwMDAwMDAwMDAwMDAwMDAnLFxuICAgICAgICAgICAgICBkYXRhOiAnMHhjMDBjNGU5ZTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMGEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDE3NGNmZDgyM2FmOGNlMjdlZDBhZmVlM2ZjZjNjM2JhMjU5MTE2YmUwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA3ZTg1YmRjMjdjMDUwZTM5MDVlYmY0YjhlNjM0ZDlhZDZlZGQwZGU2MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDM4ZDdlYTRjNjgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzOGQ3ZWE0YzY4MDAwJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAxMDg5NixcbiAgICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgICBpc0JhdGNoOiB0cnVlLFxuICAgICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBhd2FpdCBldGhXYWxsZXQucHJlYnVpbGRUcmFuc2FjdGlvbih0eFBhcmFtcyk7XG4gICAgICB0eFByZWJ1aWxkLmlzQmF0Y2guc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgdHhQcmVidWlsZC5yZWNpcGllbnRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKFxuICAgICAgICAoYml0Z28uY29pbigndGV0aCcpIGFzIGFueSkuc3RhdGljc0NvaW4ubmV0d29yay5iYXRjaGVyQ29udHJhY3RBZGRyZXNzXG4gICAgICApO1xuICAgICAgdHhQcmVidWlsZC5yZWNpcGllbnRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWwodG90YWxBbW91bnQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIGlzQmF0Y2ggPSBmYWxzZSBhbmQgaG9wVHJhbnNhY3Rpb24gZmllbGQgc2hvdWxkIG5vdCBiZSB0aGVyZSBpbiB0aGUgdHhQcmVidWlsZCAgZm9yIG5vcm1hbCBldGggdHgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICcweGRmMDcxMTc3MDVhOWY4ZGM0YzJhNzhkZTY2YjdmMTc5N2RiYTlkNGUnLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnbW9vbicsXG4gICAgICB9O1xuXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChcbiAgICAgICAgICBgL2FwaS92Mi8ke2V0aFdhbGxldC5jb2luKCl9L3dhbGxldC8ke2V0aFdhbGxldC5pZCgpfS90eC9idWlsZGAsXG4gICAgICAgICAgXy5tYXRjaGVzKHsgcmVjaXBpZW50czogdHhQYXJhbXMucmVjaXBpZW50cyB9KVxuICAgICAgICApXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFtb3VudDogJzEwMDAwMDAwMDAwMDAwMDAnLFxuICAgICAgICAgICAgICBhZGRyZXNzOiAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAxMDg5NyxcbiAgICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gYXdhaXQgZXRoV2FsbGV0LnByZWJ1aWxkVHJhbnNhY3Rpb24odHhQYXJhbXMpO1xuICAgICAgdHhQcmVidWlsZC5pc0JhdGNoLnNob3VsZC5lcXVhbChmYWxzZSk7XG4gICAgICB0eFByZWJ1aWxkLnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgnaG9wVHJhbnNhY3Rpb24nKTtcbiAgICAgIHR4UHJlYnVpbGQucmVjaXBpZW50c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbChhZGRyZXNzMSk7XG4gICAgICB0eFByZWJ1aWxkLnJlY2lwaWVudHNbMF0uYW1vdW50LnNob3VsZC5lcXVhbCgnMTAwMDAwMDAwMDAwMDAwMCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXNzIHVuc3BlbnQgcmVzZXJ2YXRpb24gcGFyYW1ldGVyIHRocm91Z2ggd2hlbiBidWlsZGluZyB0cmFuc2FjdGlvbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZXNlcnZhdGlvbiA9IHtcbiAgICAgICAgZXhwaXJlVGltZTogJzIwMjktMDgtMTInLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlY2lwaWVudHMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBhZGRyZXNzOiAnYWFhJyxcbiAgICAgICAgICBhbW91bnQ6ICcxMDAwJyxcbiAgICAgICAgfSxcbiAgICAgIF07XG4gICAgICBjb25zdCBwYXRoID0gYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvYnVpbGRgO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChwYXRoLCBfLm1hdGNoZXMoeyByZWNpcGllbnRzLCByZXNlcnZhdGlvbiB9KSkgLy8gdXNlIF8ubWF0Y2hlcyB0byBkbyBhIHBhcnRpYWwgbWF0Y2ggb24gcmVxdWVzdCBib2R5IG9iamVjdCBpbnN0ZWFkIG9mIHN0cmljdCBtYXRjaGluZ1xuICAgICAgICAucmVwbHkoMjAwKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHdhbGxldC5wcmVidWlsZFRyYW5zYWN0aW9uKHsgcmVjaXBpZW50cywgcmVzZXJ2YXRpb24gfSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIHRoZSBwcmVidWlsZFRyYW5zYWN0aW9uIG1ldGhvZCB3aWxsIHByb2JhYmx5IHRocm93IGFuIGV4Y2VwdGlvbiBmb3Igbm90IGhhdmluZyBhbGwgb2YgdGhlIGNvcnJlY3Qgbm9ja3NcbiAgICAgICAgLy8gd2Ugb25seSBjYXJlIGFib3V0IC90eC9idWlsZCBhbmQgd2hldGhlciByZXNlcnZhdGlvbiBpcyBhbiBhbGxvd2VkIHBhcmFtZXRlclxuICAgICAgfVxuXG4gICAgICByZXNwb25zZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXNzIGdhcyBsaW1pdCBwYXJhbWV0ZXIgdGhyb3VnaCB3aGVuIGJ1aWxkaW5nIHRyYW5zYWN0aW9uIGZvciBzdWknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJhbXMgPSB7IGdhc0xpbWl0OiAxMDAgfTtcbiAgICAgIGNvbnN0IHBhdGggPSBgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC9idWlsZGA7XG4gICAgICBjb25zdCByZXNwb25zZSA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KHBhdGgsIF8ubWF0Y2hlcyhwYXJhbXMpKSAvLyB1c2UgXy5tYXRjaGVzIHRvIGRvIGEgcGFydGlhbCBtYXRjaCBvbiByZXF1ZXN0IGJvZHkgb2JqZWN0IGluc3RlYWQgb2Ygc3RyaWN0IG1hdGNoaW5nXG4gICAgICAgIC5yZXBseSgyMDApO1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0LnByZWJ1aWxkVHJhbnNhY3Rpb24ocGFyYW1zKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gdGhlIHByZWJ1aWxkVHJhbnNhY3Rpb24gbWV0aG9kIHdpbGwgcHJvYmFibHkgdGhyb3cgYW4gZXhjZXB0aW9uIGZvciBub3QgaGF2aW5nIGFsbCBvZiB0aGUgY29ycmVjdCBub2Nrc1xuICAgICAgICAvLyB3ZSBvbmx5IGNhcmUgYWJvdXQgL3R4L2J1aWxkIGFuZCB3aGV0aGVyIHJlc2VydmF0aW9uIGlzIGFuIGFsbG93ZWQgcGFyYW1ldGVyXG4gICAgICB9XG5cbiAgICAgIHJlc3BvbnNlLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdNYXhpbXVtIFNwZW5kYWJsZScsIGZ1bmN0aW9uIG1heGltdW1TcGVuZGFibGUoKSB7XG4gICAgbGV0IGJnVXJsO1xuXG4gICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2sucGVuZGluZ01vY2tzKCkuc2hvdWxkLmJlLmVtcHR5KCk7XG4gICAgICBiZ1VybCA9IGNvbW1vbi5FbnZpcm9ubWVudHNbYml0Z28uZ2V0RW52KCldLnVyaTtcbiAgICB9KTtcblxuICAgIGl0KCdhcmd1bWVudHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBvcHRpb25hbFBhcmFtcyA9IHtcbiAgICAgICAgbGltaXQ6IDI1LFxuICAgICAgICBtaW5WYWx1ZTogJzAnLFxuICAgICAgICBtYXhWYWx1ZTogJzk5OTk5OTk5OTk5OTknLFxuICAgICAgICBtaW5IZWlnaHQ6IDAsXG4gICAgICAgIG1pbkNvbmZpcm1zOiAyLFxuICAgICAgICBlbmZvcmNlTWluQ29uZmlybXNGb3JDaGFuZ2U6IGZhbHNlLFxuICAgICAgICBmZWVSYXRlOiAxMDAwMCxcbiAgICAgICAgbWF4RmVlUmF0ZTogMTAwMDAwLFxuICAgICAgICByZWNpcGllbnRBZGRyZXNzOiAnMk5DVUZETGlVejlDVm5tZFZxUWU5YWNWb25vTTg5ZTc2ZGYnLFxuICAgICAgfTtcblxuICAgICAgLy8gVGhlIGFjdHVhbCBhcGkgcmVxdWVzdCB3aWxsIG9ubHkgc2VuZCBzdHJpbmdzLCBidXQgdGhlIFNESyBmdW5jdGlvbiBleHBlY3RzIG51bWJlcnMgZm9yIHNvbWUgdmFsdWVzXG4gICAgICBjb25zdCBhcGlQYXJhbXMgPSBfLm1hcFZhbHVlcyhvcHRpb25hbFBhcmFtcywgKHBhcmFtKSA9PiBTdHJpbmcocGFyYW0pKTtcblxuICAgICAgY29uc3QgcGF0aCA9IGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L21heGltdW1TcGVuZGFibGVgO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KHBhdGgpXG4gICAgICAgIC5xdWVyeShfLm1hdGNoZXMoYXBpUGFyYW1zKSkgLy8gdXNlIF8ubWF0Y2hlcyB0byBkbyBhIHBhcnRpYWwgbWF0Y2ggb24gcmVxdWVzdCBib2R5IG9iamVjdCBpbnN0ZWFkIG9mIHN0cmljdCBtYXRjaGluZ1xuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgY29pbjogJ3RiY2gnLFxuICAgICAgICAgIG1heGltdW1TcGVuZGFibGU6IDY1MDAwLFxuICAgICAgICB9KTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0Lm1heGltdW1TcGVuZGFibGUob3B0aW9uYWxQYXJhbXMpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyB0ZXN0IGlzIHN1Y2Nlc3NmdWwgaWYgbm9jayBpcyBjb25zdW1lZFxuICAgICAgfVxuXG4gICAgICByZXNwb25zZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnV2FsbGV0IFNoYXJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBzaGFyZSB0byBjb2xkIHdhbGxldCB3aXRob3V0IHBhc3Npbmcgc2tpcEtleWNoYWluJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdXNlcklkID0gJzEyMyc7XG4gICAgICBjb25zdCBlbWFpbCA9ICdzaGFyZXRvQHNka3Rlc3QuY29tJztcbiAgICAgIGNvbnN0IHBlcm1pc3Npb25zID0gJ3ZpZXcsc3BlbmQnO1xuXG4gICAgICBjb25zdCBnZXRTaGFyaW5nS2V5Tm9jayA9IG5vY2soYmdVcmwpLnBvc3QoJy9hcGkvdjEvdXNlci9zaGFyaW5na2V5JywgeyBlbWFpbCB9KS5yZXBseSgyMDAsIHsgdXNlcklkIH0pO1xuXG4gICAgICBjb25zdCBnZXRLZXlOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLmdldChgL2FwaS92Mi90YnRjL2tleS8ke2NvbGRXYWxsZXQua2V5SWRzKClbMF19YClcbiAgICAgICAgLnJlcGx5KDIwMCwge30pXG4gICAgICAgIC5nZXQoYC9hcGkvdjIvdGJ0Yy9rZXkvJHtjb2xkV2FsbGV0LmtleUlkcygpWzFdfWApXG4gICAgICAgIC5yZXBseSgyMDAsIHt9KVxuICAgICAgICAuZ2V0KGAvYXBpL3YyL3RidGMva2V5LyR7Y29sZFdhbGxldC5rZXlJZHMoKVsyXX1gKVxuICAgICAgICAucmVwbHkoMjAwLCB7fSk7XG5cbiAgICAgIGNvbnN0IGNyZWF0ZVNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyL3RidGMvd2FsbGV0LyR7Y29sZFdhbGxldC5pZCgpfS9zaGFyZWAsIHtcbiAgICAgICAgICB1c2VyOiB1c2VySWQsXG4gICAgICAgICAgcGVybWlzc2lvbnMsXG4gICAgICAgICAgc2tpcEtleWNoYWluOiB0cnVlLFxuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAwLCB7fSk7XG5cbiAgICAgIGF3YWl0IGNvbGRXYWxsZXQuc2hhcmVXYWxsZXQoeyBlbWFpbCwgcGVybWlzc2lvbnMgfSk7XG5cbiAgICAgIGdldFNoYXJpbmdLZXlOb2NrLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgICBnZXRLZXlOb2NrLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgICBjcmVhdGVTaGFyZU5vY2suaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdIb3QgV2FsbGV0IFNoYXJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB1c2VySWQgPSAnMTIzJztcbiAgICAgIGNvbnN0IGVtYWlsID0gJ3NoYXJldG9Ac2RrdGVzdC5jb20nO1xuICAgICAgY29uc3QgcGVybWlzc2lvbnMgPSAndmlldyxzcGVuZCc7XG4gICAgICBjb25zdCB0b0tleWNoYWluID0gdXR4b0xpYi5iaXAzMi5mcm9tU2VlZChCdWZmZXIuZnJvbSgnZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyZGVhZGJlZWYwMicsICdoZXgnKSk7XG4gICAgICBjb25zdCBwYXRoID0gJ20vOTk5OTk5LzEvMSc7XG4gICAgICBjb25zdCBwdWJrZXkgPSB0b0tleWNoYWluLmRlcml2ZVBhdGgocGF0aCkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnYml0Z28xMjM0JztcbiAgICAgIGNvbnN0IHB1YiA9ICdabzFnZ3pUVUtNWTViWW5EdlQ1bXRWZVp4emYyRmFMVGJLa212R1VoVVFrJztcblxuICAgICAgY29uc3QgbGlnaHRuaW5nQ29pbjogYW55ID0gYml0Z28uY29pbigndGxuYnRjJyk7XG4gICAgICBjb25zdCBsaWdodG5pbmdXYWxsZXREYXRhID0ge1xuICAgICAgICBpZDogJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYTAwMDAwMDAxJyxcbiAgICAgICAgY29pbjogJ3RsbmJ0YycsXG4gICAgICAgIGtleXM6IFsnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc1MDAwMDAwMDEnXSxcbiAgICAgICAgY29pblNwZWNpZmljOiB7IGtleXM6IFsnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc2MDAwMDAwMDAnLCAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc3MDAwMDAwMDAnXSB9LFxuICAgICAgICB0eXBlOiAnaG90JyxcbiAgICAgIH07XG4gICAgICBjb25zdCBsaWdodG5pbmdXYWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBsaWdodG5pbmdDb2luLCBsaWdodG5pbmdXYWxsZXREYXRhKTtcblxuICAgICAgZm9yIChjb25zdCBob3RXYWxsZXQgb2YgW3dhbGxldCwgbGlnaHRuaW5nV2FsbGV0XSBhcyBjb25zdCkge1xuICAgICAgICBpdChgc2hvdWxkIHVzZSBrZXljaGFpbiBwdWIgdG8gc2hhcmUgJHtob3RXYWxsZXQuY29pbigpfSBob3Qgd2FsbGV0YCwgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGdldFNoYXJpbmdLZXlOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAgIC5wb3N0KCcvYXBpL3YxL3VzZXIvc2hhcmluZ2tleScsIHsgZW1haWwgfSlcbiAgICAgICAgICAgIC5yZXBseSgyMDAsIHsgdXNlcklkLCBwdWJrZXksIHBhdGggfSk7XG5cbiAgICAgICAgICBjb25zdCBnZXRLZXlOb2Nrczogbm9jay5TY29wZVtdID0gW107XG4gICAgICAgICAgaWYgKGhvdFdhbGxldC5iYXNlQ29pbi5nZXRGYW1pbHkoKSA9PT0gJ2xuYnRjJykge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAyOyBpKyspIHtcbiAgICAgICAgICAgICAgY29uc3Qga2V5SWQgPSBsaWdodG5pbmdXYWxsZXREYXRhLmNvaW5TcGVjaWZpYy5rZXlzW2ldO1xuICAgICAgICAgICAgICBjb25zdCBnZXRLZXlOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAgICAgICAuZ2V0KGAvYXBpL3YyL3RsbmJ0Yy9rZXkvJHtrZXlJZH1gKVxuICAgICAgICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgICAgICAgIGlkOiBrZXlJZCxcbiAgICAgICAgICAgICAgICAgIHB1YjogaSA9PT0gMCA/IHB1YiA6ICdabzFnZ3pUVUtNWTViWW5EdlQ1bXRWZVp4emYyRmFMVGJLa212R1VoVVFtJyxcbiAgICAgICAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2JyArIGksIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICAgICAgICAgICAgY29pblNwZWNpZmljOlxuICAgICAgICAgICAgICAgICAgICBpID09PSAwXG4gICAgICAgICAgICAgICAgICAgICAgPyB7IFtob3RXYWxsZXQuYmFzZUNvaW4uZ2V0Q2hhaW4oKV06IHsgcHVycG9zZTogJ3VzZXJBdXRoJyB9IH1cbiAgICAgICAgICAgICAgICAgICAgICA6IHsgW2hvdFdhbGxldC5iYXNlQ29pbi5nZXRDaGFpbigpXTogeyBwdXJwb3NlOiAnbm9kZUF1dGgnIH0gfSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgZ2V0S2V5Tm9ja3MucHVzaChnZXRLZXlOb2NrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgZ2V0S2V5Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgICAgIC5nZXQoYC9hcGkvdjIvdGJ0Yy9rZXkvJHt3YWxsZXQua2V5SWRzKClbMF19YClcbiAgICAgICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgICAgIGlkOiB3YWxsZXQua2V5SWRzKClbMF0sXG4gICAgICAgICAgICAgICAgcHViLFxuICAgICAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjEnLCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgICAgICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGdldEtleU5vY2tzLnB1c2goZ2V0S2V5Tm9jayk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3Qgc3R1YiA9IHNpbm9uLnN0dWIoaG90V2FsbGV0LCAnY3JlYXRlU2hhcmUnKS5jYWxsc0Zha2UoYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgICAgICBvcHRpb25zIS5rZXljaGFpbiEucHViIS5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgICAgIG9wdGlvbnMhLmtleWNoYWluIS5wdWIhLnNob3VsZC5lcXVhbChwdWIpO1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBhd2FpdCBob3RXYWxsZXQuc2hhcmVXYWxsZXQoeyBlbWFpbCwgcGVybWlzc2lvbnMsIHdhbGxldFBhc3NwaHJhc2UgfSk7XG5cbiAgICAgICAgICBzdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgICBnZXRTaGFyaW5nS2V5Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgICAgICAgIGdldEtleU5vY2tzLmV2ZXJ5KCh2KSA9PiB2LmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCkpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcHJvdmlkZSBza2lwS2V5Y2hhaW4gdG8gd2FsbGV0IHNoYXJlIGFwaSBmb3IgaG90IHdhbGxldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHVzZXJJZCA9ICcxMjMnO1xuICAgICAgY29uc3QgZW1haWwgPSAnc2hhcmV0b0BzZGt0ZXN0LmNvbSc7XG4gICAgICBjb25zdCBwZXJtaXNzaW9ucyA9ICd2aWV3LHNwZW5kJztcbiAgICAgIGNvbnN0IHRvS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyJywgJ2hleCcpKTtcbiAgICAgIGNvbnN0IHBhdGggPSAnbS85OTk5OTkvMS8xJztcbiAgICAgIGNvbnN0IHB1YmtleSA9IHRvS2V5Y2hhaW4uZGVyaXZlUGF0aChwYXRoKS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICBjb25zdCBnZXRTaGFyaW5nS2V5Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YxL3VzZXIvc2hhcmluZ2tleScsIHsgZW1haWwgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyB1c2VySWQsIHB1YmtleSwgcGF0aCB9KTtcbiAgICAgIGNvbnN0IGNyZWF0ZVNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyL3RidGMvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3NoYXJlYCwge1xuICAgICAgICAgIHVzZXI6IHVzZXJJZCxcbiAgICAgICAgICBwZXJtaXNzaW9ucyxcbiAgICAgICAgICBza2lwS2V5Y2hhaW46IHRydWUsXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHt9KTtcblxuICAgICAgYXdhaXQgd2FsbGV0LnNoYXJlV2FsbGV0KHsgZW1haWwsIHBlcm1pc3Npb25zLCBza2lwS2V5Y2hhaW46IHRydWUgfSk7XG5cbiAgICAgIGNyZWF0ZVNoYXJlTm9jay5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgICAgZ2V0U2hhcmluZ0tleU5vY2suaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZGVjcnlwdCB3ZWJhdXRobiBlbmNyeXB0ZWRQcnYgZm9yIHdhbGxldCBzaGFyZSAoc3BlbmQpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdXNlcklkID0gJzEyMyc7XG4gICAgICBjb25zdCBlbWFpbCA9ICdzaGFyZXRvQHNka3Rlc3QuY29tJztcbiAgICAgIGNvbnN0IHBlcm1pc3Npb25zID0gJ3ZpZXcsc3BlbmQnO1xuICAgICAgY29uc3QgdG9LZXljaGFpbiA9IHV0eG9MaWIuYmlwMzIuZnJvbVNlZWQoQnVmZmVyLmZyb20oJ2RlYWRiZWVmMDJkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDInLCAnaGV4JykpO1xuICAgICAgY29uc3QgcGF0aCA9ICdtLzk5OTk5OS8xLzEnO1xuICAgICAgY29uc3QgcHVia2V5ID0gdG9LZXljaGFpbi5kZXJpdmVQYXRoKHBhdGgpLnB1YmxpY0tleS50b1N0cmluZygnaGV4Jyk7XG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gJ3hwcnYxJztcbiAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UxID0gJ2JpdGdvMTIzNCc7XG4gICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlMiA9ICdiaXRnbzU2NzgnO1xuXG4gICAgICBjb25zdCBnZXRTaGFyaW5nS2V5Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YxL3VzZXIvc2hhcmluZ2tleScsIHsgZW1haWwgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyB1c2VySWQsIHB1YmtleSwgcGF0aCB9KTtcblxuICAgICAgY29uc3QgcHViID0gJ1pvMWdnelRVS01ZNWJZbkR2VDVtdFZlWnh6ZjJGYUxUYktrbXZHVWhVUWsnO1xuICAgICAgY29uc3QgZ2V0S2V5Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoYC9hcGkvdjIvdGJ0Yy9rZXkvJHt3YWxsZXQua2V5SWRzKClbMF19YClcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGlkOiB3YWxsZXQua2V5SWRzKClbMF0sXG4gICAgICAgICAgcHViLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgIGVuY3J5cHRlZFBydjogYml0Z28uZW5jcnlwdCh7IGlucHV0OiBwcml2YXRlS2V5LCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZTEgfSksXG4gICAgICAgICAgd2ViYXV0aG5EZXZpY2VzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIG90cERldmljZUlkOiAnMTIzJyxcbiAgICAgICAgICAgICAgYXV0aGVudGljYXRvckluZm86IHtcbiAgICAgICAgICAgICAgICBjcmVkSUQ6ICdjcmVkSUQnLFxuICAgICAgICAgICAgICAgIGZtdDogJ3BhY2tlZCcsXG4gICAgICAgICAgICAgICAgcHVibGljS2V5OiAnc29tZSB2YWx1ZScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHByZlNhbHQ6ICc0NTYnLFxuICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogcHJpdmF0ZUtleSwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UyIH0pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge30sXG4gICAgICAgIH0pO1xuXG4gICAgICBjb25zdCBzdHViID0gc2lub24uc3R1Yih3YWxsZXQsICdjcmVhdGVTaGFyZScpLmNhbGxzRmFrZShhc3luYyAob3B0aW9ucykgPT4ge1xuICAgICAgICBvcHRpb25zIS5rZXljaGFpbiEuZW5jcnlwdGVkUHJ2IS5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfSk7XG4gICAgICBhd2FpdCB3YWxsZXQuc2hhcmVXYWxsZXQoeyBlbWFpbCwgcGVybWlzc2lvbnMsIHdhbGxldFBhc3NwaHJhc2U6IHdhbGxldFBhc3NwaHJhc2UyIH0pO1xuICAgICAgc3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBnZXRTaGFyaW5nS2V5Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgICAgZ2V0S2V5Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnV2FsbGV0IEZyZWV6aW5nJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgZnJlZXplIHdhbGxldCBmb3Igc3BlY2lmaWVkIGR1cmF0aW9uIGluIHNlY29uZHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJhbXMgPSB7IGR1cmF0aW9uOiA2MCB9O1xuICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKGJnVXJsKS5wb3N0KGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L2ZyZWV6ZWAsIHBhcmFtcykucmVwbHkoMjAwLCB7fSk7XG4gICAgICBhd2FpdCB3YWxsZXQuZnJlZXplKHBhcmFtcyk7XG4gICAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnVFNTIFdhbGxldHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICBjb25zdCB0c29sID0gYml0Z28uY29pbigndHNvbCcpO1xuICAgIGNvbnN0IHdhbGxldERhdGEgPSB7XG4gICAgICBpZDogJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYTAwMDAwMDAwJyxcbiAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgIGtleXM6IFtcbiAgICAgICAgJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkODlkY2U4NmMyJyxcbiAgICAgICAgJzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyJyxcbiAgICAgICAgJzU5MzVkNTljZjY2MDc2NDMzMWJhZmNhZGUxODU1ZmQ3JyxcbiAgICAgIF0sXG4gICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICB9O1xuXG4gICAgY29uc3QgZXRoV2FsbGV0RGF0YSA9IHtcbiAgICAgIGlkOiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWRiMWQ5NDU5YmInLFxuICAgICAgY29pbjogJ3RldGgnLFxuICAgICAga2V5czogW1xuICAgICAgICAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWQ4OWRjZTg2YzInLFxuICAgICAgICAnNTk4ZjYwNmNjOGU0M2FlZjA5ZmNiNzg1MjIxZDlkZDInLFxuICAgICAgICAnNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDcnLFxuICAgICAgXSxcbiAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICBjb2luU3BlY2lmaWM6IHsgYWRkcmVzc1ZlcnNpb246IDEgfSxcbiAgICAgIHR5cGU6ICdob3QnLFxuICAgIH07XG5cbiAgICBjb25zdCBwb2x5Z29uV2FsbGV0RGF0YSA9IHtcbiAgICAgIGlkOiAnNjMyODI2NTIwZWUxZTUwMDA3MjkwMTczNTRhY2FlYWInLFxuICAgICAgY29pbjogJ3Rwb2x5Z29uJyxcbiAgICAgIGtleXM6IFtcbiAgICAgICAgJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkODlkY2U4NmMyJyxcbiAgICAgICAgJzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyJyxcbiAgICAgICAgJzU5MzVkNTljZjY2MDc2NDMzMWJhZmNhZGUxODU1ZmQ3JyxcbiAgICAgIF0sXG4gICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgIH07XG5cbiAgICBjb25zdCB0c3NTb2xXYWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCB0c29sLCB3YWxsZXREYXRhKTtcblxuICAgIGxldCB0c3NFdGhXYWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiaXRnby5jb2luKCd0ZXRoJyksIGV0aFdhbGxldERhdGEpO1xuICAgIGNvbnN0IHRzc1BvbHlnb25XYWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiaXRnby5jb2luKCd0cG9seWdvbicpLCBwb2x5Z29uV2FsbGV0RGF0YSk7XG4gICAgY29uc3QgY3VzdG9kaWFsVHNzU29sV2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgdHNvbCwge1xuICAgICAgLi4ud2FsbGV0RGF0YSxcbiAgICAgIHR5cGU6ICdjdXN0b2RpYWwnLFxuICAgIH0pO1xuXG4gICAgY29uc3QgdHhSZXF1ZXN0OiBUeFJlcXVlc3QgPSB7XG4gICAgICB0eFJlcXVlc3RJZDogJ2lkJyxcbiAgICAgIHRyYW5zYWN0aW9uczogW10sXG4gICAgICBpbnRlbnQ6IHtcbiAgICAgICAgaW50ZW50VHlwZTogJ3BheW1lbnQnLFxuICAgICAgfSxcbiAgICAgIGRhdGU6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgIGxhdGVzdDogdHJ1ZSxcbiAgICAgIHN0YXRlOiAncGVuZGluZ1VzZXJTaWduYXR1cmUnLFxuICAgICAgdXNlcklkOiAndXNlcklkJyxcbiAgICAgIHdhbGxldFR5cGU6ICdob3QnLFxuICAgICAgcG9saWNpZXNDaGVja2VkOiBmYWxzZSxcbiAgICAgIHZlcnNpb246IDEsXG4gICAgICB3YWxsZXRJZDogJ3dhbGxldElkJyxcbiAgICAgIHVuc2lnbmVkVHhzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBzZXJpYWxpemVkVHhIZXg6ICdhYmFiY2RjZCcsXG4gICAgICAgICAgc2lnbmFibGVIZXg6ICdkZWFkYmVlZicsXG4gICAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgICAgZmVlOiA1MDAwLFxuICAgICAgICAgICAgZmVlU3RyaW5nOiAnNTAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBkZXJpdmF0aW9uUGF0aDogJ20vMCcsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH07XG5cbiAgICBjb25zdCB0eFJlcXVlc3RGdWxsOiBUeFJlcXVlc3QgPSB7XG4gICAgICB0eFJlcXVlc3RJZDogJ2lkJyxcbiAgICAgIGludGVudDoge1xuICAgICAgICBpbnRlbnRUeXBlOiAncGF5bWVudCcsXG4gICAgICB9LFxuICAgICAgZGF0ZTogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgbGF0ZXN0OiB0cnVlLFxuICAgICAgc3RhdGU6ICdwZW5kaW5nVXNlclNpZ25hdHVyZScsXG4gICAgICB1c2VySWQ6ICd1c2VySWQnLFxuICAgICAgd2FsbGV0SWQ6ICd3YWxsZXRJZCcsXG4gICAgICBzaWduYXR1cmVTaGFyZXM6IFtdLFxuICAgICAgdmVyc2lvbjogMSxcbiAgICAgIHBvbGljaWVzQ2hlY2tlZDogZmFsc2UsXG4gICAgICB3YWxsZXRUeXBlOiAnaG90JyxcbiAgICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAgICB7XG4gICAgICAgICAgc3RhdGU6ICdwZW5kaW5nU2lnbmF0dXJlJyxcbiAgICAgICAgICB1bnNpZ25lZFR4OiB7XG4gICAgICAgICAgICBzZXJpYWxpemVkVHhIZXg6ICdhYmFiY2RjZCcsXG4gICAgICAgICAgICBzaWduYWJsZUhleDogJ2RlYWRiZWVmJyxcbiAgICAgICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICAgICAgZmVlOiA1MDAwLFxuICAgICAgICAgICAgICBmZWVTdHJpbmc6ICc1MDAwJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkZXJpdmF0aW9uUGF0aDogJ20vMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzaWduYXR1cmVTaGFyZXM6IFtdLFxuICAgICAgICAgIGNvbW1pdG1lbnRTaGFyZXM6IFtdLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIHVuc2lnbmVkVHhzOiBbXSxcbiAgICAgIGFwaVZlcnNpb246ICdmdWxsJyxcbiAgICB9O1xuXG4gICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHNhbmRib3gudmVyaWZ5QW5kUmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3ByZUJ1aWxkQW5kU2lnblRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAncGFzc3BocmFzZTEyMzQ1JyxcbiAgICAgICAgcHJlYnVpbGRUeDogeyB3YWxsZXRJZDogdHNzRXRoV2FsbGV0LmlkKCksIHR4UmVxdWVzdElkOiAncmFuZG9tSWQnIH0sXG4gICAgICAgIHR5cGU6ICd0cmFuc2ZlcicsXG4gICAgICB9O1xuXG4gICAgICBbJ2VkZHNhJywgJ2VjZHNhJ10uZm9yRWFjaCgoa2V5Q3VydmU6IHN0cmluZykgPT4ge1xuICAgICAgICBkZXNjcmliZShrZXlDdXJ2ZSwgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHdhbGxldCA9IGtleUN1cnZlID09PSAnZWRkc2EnID8gdHNzU29sV2FsbGV0IDogdHNzRXRoV2FsbGV0O1xuXG4gICAgICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBzYW5kYm94XG4gICAgICAgICAgICAgIC5zdHViKEtleWNoYWlucy5wcm90b3R5cGUsICdnZXRLZXlzRm9yU2lnbmluZycpXG4gICAgICAgICAgICAgIC5yZXNvbHZlcyhbeyBjb21tb25LZXljaGFpbjogJ3Rlc3QnLCBpZDogJycsIHB1YjogJycsIHR5cGU6ICdpbmRlcGVuZGVudCcgfV0pO1xuICAgICAgICAgICAgaWYgKGtleUN1cnZlID09PSAnZWRkc2EnKSB7XG4gICAgICAgICAgICAgIHNhbmRib3guc3R1YihUc29sLnByb3RvdHlwZSwgJ3ZlcmlmeVRyYW5zYWN0aW9uJykucmVzb2x2ZXModHJ1ZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBzYW5kYm94LnN0dWIoVGV0aC5wcm90b3R5cGUsICd2ZXJpZnlUcmFuc2FjdGlvbicpLnJlc29sdmVzKHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNhbmRib3gudmVyaWZ5QW5kUmVzdG9yZSgpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ2l0IHNob3VsZCBzdWNjZWVkIGJ1dCBub3Qgc2lnbiBpZiB0aGUgdHhSZXF1ZXN0IGlzIHBlbmRpbmcgYXBwcm92YWwnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBnZXRUeFJlcXVlc3RTdHViID0gc2FuZGJveC5zdHViKEJhc2VUc3NVdGlscy5kZWZhdWx0LnByb3RvdHlwZSwgJ2dldFR4UmVxdWVzdCcpLnJlc29sdmVzKHtcbiAgICAgICAgICAgICAgLi4udHhSZXF1ZXN0RnVsbCxcbiAgICAgICAgICAgICAgc3RhdGU6ICdwZW5kaW5nQXBwcm92YWwnLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHNpZ25UcmFuc2FjdGlvblNweSA9IHNhbmRib3guc3B5KFdhbGxldC5wcm90b3R5cGUsICdzaWduVHJhbnNhY3Rpb24nKTtcblxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gKGF3YWl0IHdhbGxldC5wcmVidWlsZEFuZFNpZ25UcmFuc2FjdGlvbihwYXJhbXMpKSBhcyBUeFJlcXVlc3Q7XG4gICAgICAgICAgICByZXN1bHQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3N0YXRlJyk7XG4gICAgICAgICAgICByZXN1bHQuc3RhdGUuc2hvdWxkLmVxdWFsKCdwZW5kaW5nQXBwcm92YWwnKTtcbiAgICAgICAgICAgIGdldFR4UmVxdWVzdFN0dWIuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICAgICAgc2lnblRyYW5zYWN0aW9uU3B5Lm5vdENhbGxlZC5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ2l0IHNob3VsZCBzdWNjZWVkIGFuZCBzaWduIGlmIHRoZSB0eFJlcXVlc3QgaXMgbm90IHBlbmRpbmcgYXBwcm92YWwnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBnZXRUeFJlcXVlc3RTdHViID0gc2FuZGJveC5zdHViKEJhc2VUc3NVdGlscy5kZWZhdWx0LnByb3RvdHlwZSwgJ2dldFR4UmVxdWVzdCcpO1xuICAgICAgICAgICAgZ2V0VHhSZXF1ZXN0U3R1Yi5yZXNvbHZlcyh0eFJlcXVlc3RGdWxsKTtcblxuICAgICAgICAgICAgY29uc3Qgc2lnblRyYW5zYWN0aW9uU3R1YiA9IHNhbmRib3guc3R1YihXYWxsZXQucHJvdG90eXBlLCAnc2lnblRyYW5zYWN0aW9uJyk7XG4gICAgICAgICAgICBzaWduVHJhbnNhY3Rpb25TdHViLnJlc29sdmVzKHsgLi4udHhSZXF1ZXN0RnVsbCwgc3RhdGU6ICdzaWduZWQnIH0pO1xuXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSAoYXdhaXQgd2FsbGV0LnByZWJ1aWxkQW5kU2lnblRyYW5zYWN0aW9uKHBhcmFtcykpIGFzIFR4UmVxdWVzdDtcbiAgICAgICAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc3RhdGUnKTtcbiAgICAgICAgICAgIHJlc3VsdC5zdGF0ZS5zaG91bGQuZXF1YWwoJ3NpZ25lZCcpO1xuICAgICAgICAgICAgZ2V0VHhSZXF1ZXN0U3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgICAgICBzaWduVHJhbnNhY3Rpb25TdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdUcmFuc2FjdGlvbiBwcmVidWlsZHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIGJ1aWxkIGEgc2luZ2xlIHJlY2lwaWVudCB0cmFuc2ZlciB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcmVjaXBpZW50cyA9IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnNkRhZGtaY3g5SlpnZVFVRGJIaDEyY21xQ3BhcWVobVZ4djZzR3k0OWpyYWgnLFxuICAgICAgICAgICAgYW1vdW50OiAnMTAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXTtcblxuICAgICAgICBjb25zdCBwcmVidWlsZFR4V2l0aEludGVudCA9IHNhbmRib3guc3R1YihUc3NVdGlscy5wcm90b3R5cGUsICdwcmVidWlsZFR4V2l0aEludGVudCcpO1xuICAgICAgICBwcmVidWlsZFR4V2l0aEludGVudC5yZXNvbHZlcyh0eFJlcXVlc3QpO1xuICAgICAgICAvLyBUT0RPKEJHLTU5Njg2KTogdGhpcyBpcyBub3QgZG9pbmcgYW55dGhpbmcgaWYgd2UgZG9uJ3QgY2hlY2sgdGhlIHJldHVybiB2YWx1ZSwgd2Ugc2hvdWxkIGFsc28gbW92ZSB0aGlzIGNoZWNrIHRvIGhhcHBlbiBhZnRlciB3ZSBpbnZva2UgcHJlYnVpbGRUcmFuc2FjdGlvblxuICAgICAgICBwcmVidWlsZFR4V2l0aEludGVudC5jYWxsZWRPbmNlV2l0aEV4YWN0bHkoe1xuICAgICAgICAgIHJlcUlkLFxuICAgICAgICAgIHJlY2lwaWVudHMsXG4gICAgICAgICAgaW50ZW50VHlwZTogJ3BheW1lbnQnLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB0eFByZWJ1aWxkID0gYXdhaXQgdHNzU29sV2FsbGV0LnByZWJ1aWxkVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHJlcUlkLFxuICAgICAgICAgIHJlY2lwaWVudHMsXG4gICAgICAgICAgdHlwZTogJ3RyYW5zZmVyJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdHhQcmVidWlsZC5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgICB3YWxsZXRJZDogdHNzU29sV2FsbGV0LmlkKCksXG4gICAgICAgICAgd2FsbGV0OiB0c3NTb2xXYWxsZXQsXG4gICAgICAgICAgdHhSZXF1ZXN0SWQ6ICdpZCcsXG4gICAgICAgICAgdHhIZXg6ICdhYmFiY2RjZCcsXG4gICAgICAgICAgYnVpbGRQYXJhbXM6IHtcbiAgICAgICAgICAgIHJlY2lwaWVudHMsXG4gICAgICAgICAgICB0eXBlOiAndHJhbnNmZXInLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgICAgZmVlOiA1MDAwLFxuICAgICAgICAgICAgZmVlU3RyaW5nOiAnNTAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBidWlsZCBhIHNpbmdsZSByZWNpcGllbnQgdHJhbnNmZXIgd2l0aCBwZW5kaW5nIGFwcHJvdmFsIGlkIGlmIHRyYW5zYWN0aW9uIGlzIGhhdmluZyBvbmUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHJlY2lwaWVudHMgPSBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzZEYWRrWmN4OUpaZ2VRVURiSGgxMmNtcUNwYXFlaG1WeHY2c0d5NDlqcmFoJyxcbiAgICAgICAgICAgIGFtb3VudDogJzEwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF07XG5cbiAgICAgICAgY29uc3QgcHJlYnVpbGRUeFdpdGhJbnRlbnQgPSBzYW5kYm94LnN0dWIoVHNzVXRpbHMucHJvdG90eXBlLCAncHJlYnVpbGRUeFdpdGhJbnRlbnQnKTtcbiAgICAgICAgcHJlYnVpbGRUeFdpdGhJbnRlbnQucmVzb2x2ZXMoeyAuLi50eFJlcXVlc3QsIHN0YXRlOiAncGVuZGluZ0FwcHJvdmFsJywgcGVuZGluZ0FwcHJvdmFsSWQ6ICdzb21lLWlkJyB9KTtcbiAgICAgICAgcHJlYnVpbGRUeFdpdGhJbnRlbnQuY2FsbGVkT25jZVdpdGhFeGFjdGx5KHtcbiAgICAgICAgICByZXFJZCxcbiAgICAgICAgICByZWNpcGllbnRzLFxuICAgICAgICAgIGludGVudFR5cGU6ICdwYXltZW50JyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdHhQcmVidWlsZCA9IGF3YWl0IGN1c3RvZGlhbFRzc1NvbFdhbGxldC5wcmVidWlsZFRyYW5zYWN0aW9uKHtcbiAgICAgICAgICByZXFJZCxcbiAgICAgICAgICByZWNpcGllbnRzLFxuICAgICAgICAgIHR5cGU6ICd0cmFuc2ZlcicsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHR4UHJlYnVpbGQuc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgICAgd2FsbGV0SWQ6IGN1c3RvZGlhbFRzc1NvbFdhbGxldC5pZCgpLFxuICAgICAgICAgIHdhbGxldDogY3VzdG9kaWFsVHNzU29sV2FsbGV0LFxuICAgICAgICAgIHR4UmVxdWVzdElkOiAnaWQnLFxuICAgICAgICAgIHR4SGV4OiAnYWJhYmNkY2QnLFxuICAgICAgICAgIHBlbmRpbmdBcHByb3ZhbElkOiAnc29tZS1pZCcsXG4gICAgICAgICAgYnVpbGRQYXJhbXM6IHtcbiAgICAgICAgICAgIHJlY2lwaWVudHMsXG4gICAgICAgICAgICB0eXBlOiAndHJhbnNmZXInLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgICAgZmVlOiA1MDAwLFxuICAgICAgICAgICAgZmVlU3RyaW5nOiAnNTAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBidWlsZCBhIG11bHRpcGxlIHJlY2lwaWVudCB0cmFuc2ZlciB0cmFuc2FjdGlvbiB3aXRoIG1lbW8nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHJlY2lwaWVudHMgPSBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzZEYWRrWmN4OUpaZ2VRVURiSGgxMmNtcUNwYXFlaG1WeHY2c0d5NDlqcmFoJyxcbiAgICAgICAgICAgIGFtb3VudDogJzEwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzZEYWRrWmN4OUpaZ2VRVURiSGgxMmNtcUNwYXFlaG1WeHY2c0d5NDlqcmFoJyxcbiAgICAgICAgICAgIGFtb3VudDogJzIwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF07XG5cbiAgICAgICAgY29uc3QgcHJlYnVpbGRUeFdpdGhJbnRlbnQgPSBzYW5kYm94LnN0dWIoVHNzVXRpbHMucHJvdG90eXBlLCAncHJlYnVpbGRUeFdpdGhJbnRlbnQnKTtcbiAgICAgICAgcHJlYnVpbGRUeFdpdGhJbnRlbnQucmVzb2x2ZXModHhSZXF1ZXN0KTtcbiAgICAgICAgLy8gVE9ETyhCRy01OTY4Nik6IHRoaXMgaXMgbm90IGRvaW5nIGFueXRoaW5nIGlmIHdlIGRvbid0IGNoZWNrIHRoZSByZXR1cm4gdmFsdWUsIHdlIHNob3VsZCBhbHNvIG1vdmUgdGhpcyBjaGVjayB0byBoYXBwZW4gYWZ0ZXIgd2UgaW52b2tlIHByZWJ1aWxkVHJhbnNhY3Rpb25cbiAgICAgICAgcHJlYnVpbGRUeFdpdGhJbnRlbnQuY2FsbGVkT25jZVdpdGhFeGFjdGx5KHtcbiAgICAgICAgICByZXFJZCxcbiAgICAgICAgICByZWNpcGllbnRzLFxuICAgICAgICAgIGludGVudFR5cGU6ICdwYXltZW50JyxcbiAgICAgICAgICBtZW1vOiB7XG4gICAgICAgICAgICB0eXBlOiAndHlwZScsXG4gICAgICAgICAgICB2YWx1ZTogJ3Rlc3QgbWVtbycsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdHhQcmVidWlsZCA9IGF3YWl0IHRzc1NvbFdhbGxldC5wcmVidWlsZFRyYW5zYWN0aW9uKHtcbiAgICAgICAgICByZXFJZCxcbiAgICAgICAgICByZWNpcGllbnRzLFxuICAgICAgICAgIHR5cGU6ICd0cmFuc2ZlcicsXG4gICAgICAgICAgbWVtbzoge1xuICAgICAgICAgICAgdHlwZTogJ3R5cGUnLFxuICAgICAgICAgICAgdmFsdWU6ICd0ZXN0IG1lbW8nLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHR4UHJlYnVpbGQuc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgICAgd2FsbGV0SWQ6IHRzc1NvbFdhbGxldC5pZCgpLFxuICAgICAgICAgIHdhbGxldDogdHNzU29sV2FsbGV0LFxuICAgICAgICAgIHR4UmVxdWVzdElkOiAnaWQnLFxuICAgICAgICAgIHR4SGV4OiAnYWJhYmNkY2QnLFxuICAgICAgICAgIGJ1aWxkUGFyYW1zOiB7XG4gICAgICAgICAgICByZWNpcGllbnRzLFxuICAgICAgICAgICAgbWVtbzoge1xuICAgICAgICAgICAgICB0eXBlOiAndHlwZScsXG4gICAgICAgICAgICAgIHZhbHVlOiAndGVzdCBtZW1vJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0eXBlOiAndHJhbnNmZXInLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgICAgZmVlOiA1MDAwLFxuICAgICAgICAgICAgZmVlU3RyaW5nOiAnNTAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBidWlsZCBhbiBlbmFibGUgdG9rZW4gdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHJlY2lwaWVudHMgPSBbXTtcbiAgICAgICAgY29uc3QgdG9rZW5OYW1lID0gJ3Rjb2luOnRva2VuTmFtZSc7XG4gICAgICAgIGNvbnN0IHByZWJ1aWxkVHhXaXRoSW50ZW50ID0gc2FuZGJveC5zdHViKFRzc1V0aWxzLnByb3RvdHlwZSwgJ3ByZWJ1aWxkVHhXaXRoSW50ZW50Jyk7XG4gICAgICAgIHByZWJ1aWxkVHhXaXRoSW50ZW50LnJlc29sdmVzKHR4UmVxdWVzdCk7XG4gICAgICAgIC8vIFRPRE8oQkctNTk2ODYpOiB0aGlzIGlzIG5vdCBkb2luZyBhbnl0aGluZyBpZiB3ZSBkb24ndCBjaGVjayB0aGUgcmV0dXJuIHZhbHVlLCB3ZSBzaG91bGQgYWxzbyBtb3ZlIHRoaXMgY2hlY2sgdG8gaGFwcGVuIGFmdGVyIHdlIGludm9rZSBwcmVidWlsZFRyYW5zYWN0aW9uXG4gICAgICAgIHByZWJ1aWxkVHhXaXRoSW50ZW50LmNhbGxlZE9uY2VXaXRoRXhhY3RseSh7XG4gICAgICAgICAgcmVxSWQsXG4gICAgICAgICAgcmVjaXBpZW50cyxcbiAgICAgICAgICBpbnRlbnRUeXBlOiAnY3JlYXRlQWNjb3VudCcsXG4gICAgICAgICAgbWVtbzoge1xuICAgICAgICAgICAgdHlwZTogJ3R5cGUnLFxuICAgICAgICAgICAgdmFsdWU6ICd0ZXN0IG1lbW8nLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdG9rZW5OYW1lLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB0eFByZWJ1aWxkID0gYXdhaXQgdHNzU29sV2FsbGV0LnByZWJ1aWxkVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHJlcUlkLFxuICAgICAgICAgIHJlY2lwaWVudHMsXG4gICAgICAgICAgdHlwZTogJ2VuYWJsZXRva2VuJyxcbiAgICAgICAgICBtZW1vOiB7XG4gICAgICAgICAgICB0eXBlOiAndHlwZScsXG4gICAgICAgICAgICB2YWx1ZTogJ3Rlc3QgbWVtbycsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0b2tlbk5hbWUsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHR4UHJlYnVpbGQuc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgICAgd2FsbGV0SWQ6IHRzc1NvbFdhbGxldC5pZCgpLFxuICAgICAgICAgIHdhbGxldDogdHNzU29sV2FsbGV0LFxuICAgICAgICAgIHR4UmVxdWVzdElkOiAnaWQnLFxuICAgICAgICAgIHR4SGV4OiAnYWJhYmNkY2QnLFxuICAgICAgICAgIGJ1aWxkUGFyYW1zOiB7XG4gICAgICAgICAgICByZWNpcGllbnRzLFxuICAgICAgICAgICAgbWVtbzoge1xuICAgICAgICAgICAgICB0eXBlOiAndHlwZScsXG4gICAgICAgICAgICAgIHZhbHVlOiAndGVzdCBtZW1vJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0eXBlOiAnZW5hYmxldG9rZW4nLFxuICAgICAgICAgICAgdG9rZW5OYW1lLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgICAgZmVlOiA1MDAwLFxuICAgICAgICAgICAgZmVlU3RyaW5nOiAnNTAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBidWlsZCBhbiBlbmFibGUgdG9rZW4gdHJhbnNhY3Rpb24gZm9yIGNvbGQgd2FsbGV0cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcmVjaXBpZW50cyA9IFtdO1xuICAgICAgICBjb25zdCB0b2tlbk5hbWUgPSAndGNvaW46dG9rZW5OYW1lJztcbiAgICAgICAgY29uc3QgcHJlYnVpbGRUeFdpdGhJbnRlbnQgPSBzYW5kYm94LnN0dWIoVHNzVXRpbHMucHJvdG90eXBlLCAncHJlYnVpbGRUeFdpdGhJbnRlbnQnKTtcbiAgICAgICAgdHhSZXF1ZXN0LndhbGxldFR5cGUgPSAnY29sZCc7XG4gICAgICAgIHByZWJ1aWxkVHhXaXRoSW50ZW50LnJlc29sdmVzKHR4UmVxdWVzdCk7XG4gICAgICAgIHByZWJ1aWxkVHhXaXRoSW50ZW50LmNhbGxlZE9uY2VXaXRoRXhhY3RseSh7XG4gICAgICAgICAgcmVxSWQsXG4gICAgICAgICAgcmVjaXBpZW50cyxcbiAgICAgICAgICBpbnRlbnRUeXBlOiAnY3JlYXRlQWNjb3VudCcsXG4gICAgICAgICAgbWVtbzoge1xuICAgICAgICAgICAgdHlwZTogJ3R5cGUnLFxuICAgICAgICAgICAgdmFsdWU6ICd0ZXN0IG1lbW8nLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdG9rZW5OYW1lLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB0eFByZWJ1aWxkID0gYXdhaXQgdHNzU29sV2FsbGV0LnByZWJ1aWxkVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHJlcUlkLFxuICAgICAgICAgIHJlY2lwaWVudHMsXG4gICAgICAgICAgdHlwZTogJ2VuYWJsZXRva2VuJyxcbiAgICAgICAgICBtZW1vOiB7XG4gICAgICAgICAgICB0eXBlOiAndHlwZScsXG4gICAgICAgICAgICB2YWx1ZTogJ3Rlc3QgbWVtbycsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0b2tlbk5hbWUsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHR4UHJlYnVpbGQuc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgICAgd2FsbGV0SWQ6IHRzc1NvbFdhbGxldC5pZCgpLFxuICAgICAgICAgIHdhbGxldDogdHNzU29sV2FsbGV0LFxuICAgICAgICAgIHR4UmVxdWVzdElkOiAnaWQnLFxuICAgICAgICAgIHR4SGV4OiAnYWJhYmNkY2QnLFxuICAgICAgICAgIGJ1aWxkUGFyYW1zOiB7XG4gICAgICAgICAgICByZWNpcGllbnRzLFxuICAgICAgICAgICAgbWVtbzoge1xuICAgICAgICAgICAgICB0eXBlOiAndHlwZScsXG4gICAgICAgICAgICAgIHZhbHVlOiAndGVzdCBtZW1vJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0eXBlOiAnZW5hYmxldG9rZW4nLFxuICAgICAgICAgICAgdG9rZW5OYW1lLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgICAgZmVlOiA1MDAwLFxuICAgICAgICAgICAgZmVlU3RyaW5nOiAnNTAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBmYWlsIGZvciBub24tdHJhbnNmZXIgdHJhbnNhY3Rpb24gdHlwZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGF3YWl0IHRzc1NvbFdhbGxldFxuICAgICAgICAgIC5wcmVidWlsZFRyYW5zYWN0aW9uKHtcbiAgICAgICAgICAgIHJlcUlkLFxuICAgICAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYWRkcmVzczogJzZEYWRrWmN4OUpaZ2VRVURiSGgxMmNtcUNwYXFlaG1WeHY2c0d5NDlqcmFoJyxcbiAgICAgICAgICAgICAgICBhbW91bnQ6ICcxMDAwJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICB0eXBlOiAnc3Rha2UnLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3RyYW5zYWN0aW9uIHR5cGUgbm90IHN1cHBvcnRlZDogc3Rha2UnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgZm9yIGZ1bGwgYXBpIHZlcnNpb24gY29tcGF0aWJpbGl0eScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgY3VzdG9kaWFsVHNzU29sV2FsbGV0XG4gICAgICAgICAgLnByZWJ1aWxkVHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgcmVxSWQsXG4gICAgICAgICAgICBhcGlWZXJzaW9uOiAnbGl0ZScsXG4gICAgICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhZGRyZXNzOiAnNkRhZGtaY3g5SlpnZVFVRGJIaDEyY21xQ3BhcWVobVZ4djZzR3k0OWpyYWgnLFxuICAgICAgICAgICAgICAgIGFtb3VudDogJzEwMDAnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHR5cGU6ICd0cmFuc2ZlcicsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnRm9yIG5vbiBzZWxmLWN1c3RvZGlhbCAoaG90KSB0c3Mgd2FsbGV0cywgcGFyYW1ldGVyIGBhcGlWZXJzaW9uYCBtdXN0IGJlIGBmdWxsYC4nKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGJ1aWxkIGEgc2luZ2xlIHJlY2lwaWVudCB0cmFuc2ZlciB0cmFuc2FjdGlvbiBmb3IgZnVsbCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcmVjaXBpZW50cyA9IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnNkRhZGtaY3g5SlpnZVFVRGJIaDEyY21xQ3BhcWVobVZ4djZzR3k0OWpyYWgnLFxuICAgICAgICAgICAgYW1vdW50OiAnMTAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXTtcblxuICAgICAgICBjb25zdCBwcmVidWlsZFR4V2l0aEludGVudCA9IHNhbmRib3guc3R1YihUc3NVdGlscy5wcm90b3R5cGUsICdwcmVidWlsZFR4V2l0aEludGVudCcpO1xuICAgICAgICBwcmVidWlsZFR4V2l0aEludGVudC5yZXNvbHZlcyh0eFJlcXVlc3RGdWxsKTtcbiAgICAgICAgLy8gVE9ETyhCRy01OTY4Nik6IHRoaXMgaXMgbm90IGRvaW5nIGFueXRoaW5nIGlmIHdlIGRvbid0IGNoZWNrIHRoZSByZXR1cm4gdmFsdWUsIHdlIHNob3VsZCBhbHNvIG1vdmUgdGhpcyBjaGVjayB0byBoYXBwZW4gYWZ0ZXIgd2UgaW52b2tlIHByZWJ1aWxkVHJhbnNhY3Rpb25cbiAgICAgICAgcHJlYnVpbGRUeFdpdGhJbnRlbnQuY2FsbGVkT25jZVdpdGhFeGFjdGx5KFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHJlcUlkLFxuICAgICAgICAgICAgcmVjaXBpZW50cyxcbiAgICAgICAgICAgIGludGVudFR5cGU6ICdwYXltZW50JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgICdmdWxsJ1xuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBhd2FpdCBjdXN0b2RpYWxUc3NTb2xXYWxsZXQucHJlYnVpbGRUcmFuc2FjdGlvbih7XG4gICAgICAgICAgcmVxSWQsXG4gICAgICAgICAgcmVjaXBpZW50cyxcbiAgICAgICAgICB0eXBlOiAndHJhbnNmZXInLFxuICAgICAgICB9KTtcblxuICAgICAgICB0eFByZWJ1aWxkLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICAgIHdhbGxldElkOiB0c3NTb2xXYWxsZXQuaWQoKSxcbiAgICAgICAgICB3YWxsZXQ6IGN1c3RvZGlhbFRzc1NvbFdhbGxldCxcbiAgICAgICAgICB0eFJlcXVlc3RJZDogJ2lkJyxcbiAgICAgICAgICB0eEhleDogJ2FiYWJjZGNkJyxcbiAgICAgICAgICBidWlsZFBhcmFtczoge1xuICAgICAgICAgICAgcmVjaXBpZW50cyxcbiAgICAgICAgICAgIHR5cGU6ICd0cmFuc2ZlcicsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgICBmZWU6IDUwMDAsXG4gICAgICAgICAgICBmZWVTdHJpbmc6ICc1MDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGNhbGwgcHJlYnVpbGRUeFdpdGhJbnRlbnQgd2l0aCB0aGUgY29ycmVjdCBwYXJhbXMgZm9yIGV0aCB0cmFuc2ZlcnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHJlY2lwaWVudHMgPSBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzB4QUIxMDA5MTJlMTMzQUEwNmNFQjkyMTQ1OWFhRGRCZDYyMzgxRjVBMycsXG4gICAgICAgICAgICBhbW91bnQ6ICcxMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdO1xuXG4gICAgICAgIGNvbnN0IGZlZU9wdGlvbnMgPSB7XG4gICAgICAgICAgbWF4RmVlUGVyR2FzOiAzMDAwMDAwMDAwLFxuICAgICAgICAgIG1heFByaW9yaXR5RmVlUGVyR2FzOiAyMDAwMDAwMDAwLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHByZWJ1aWxkVHhXaXRoSW50ZW50ID0gc2FuZGJveC5zdHViKEVDRFNBVXRpbHMuRWNkc2FVdGlscy5wcm90b3R5cGUsICdwcmVidWlsZFR4V2l0aEludGVudCcpO1xuICAgICAgICBwcmVidWlsZFR4V2l0aEludGVudC5yZXNvbHZlcyh0eFJlcXVlc3RGdWxsKTtcblxuICAgICAgICBhd2FpdCB0c3NFdGhXYWxsZXQucHJlYnVpbGRUcmFuc2FjdGlvbih7XG4gICAgICAgICAgcmVxSWQsXG4gICAgICAgICAgcmVjaXBpZW50cyxcbiAgICAgICAgICB0eXBlOiAndHJhbnNmZXInLFxuICAgICAgICAgIGZlZU9wdGlvbnMsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNpbm9uLmFzc2VydC5jYWxsZWRPbmNlKHByZWJ1aWxkVHhXaXRoSW50ZW50KTtcbiAgICAgICAgY29uc3QgYXJncyA9IHByZWJ1aWxkVHhXaXRoSW50ZW50LmFyZ3NbMF07XG4gICAgICAgIGFyZ3NbMF0hLnJlY2lwaWVudHMhLnNob3VsZC5kZWVwRXF1YWwocmVjaXBpZW50cyk7XG4gICAgICAgIGFyZ3NbMF0hLmZlZU9wdGlvbnMhLnNob3VsZC5kZWVwRXF1YWwoZmVlT3B0aW9ucyk7XG4gICAgICAgIGFyZ3NbMF0hLmludGVudFR5cGUuc2hvdWxkLmVxdWFsKCdwYXltZW50Jyk7XG4gICAgICAgIGFyZ3NbMV0hLnNob3VsZC5lcXVhbCgnZnVsbCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgY2FsbCBwcmVidWlsZFR4V2l0aEludGVudCB3aXRoIHRoZSBjb3JyZWN0IHBhcmFtcyBmb3IgZXRoIHRyYW5zZmVydG9rZW5zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCByZWNpcGllbnRzID0gW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcweEFCMTAwOTEyZTEzM0FBMDZjRUI5MjE0NTlhYURkQmQ2MjM4MUY1QTMnLFxuICAgICAgICAgICAgYW1vdW50OiAnMTAwMCcsXG4gICAgICAgICAgICB0b2tlbk5hbWU6ICdndGVyYzE4ZHAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF07XG5cbiAgICAgICAgY29uc3QgZmVlT3B0aW9ucyA9IHtcbiAgICAgICAgICBtYXhGZWVQZXJHYXM6IDMwMDAwMDAwMDAsXG4gICAgICAgICAgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDIwMDAwMDAwMDAsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcHJlYnVpbGRUeFdpdGhJbnRlbnQgPSBzYW5kYm94LnN0dWIoRUNEU0FVdGlscy5FY2RzYVV0aWxzLnByb3RvdHlwZSwgJ3ByZWJ1aWxkVHhXaXRoSW50ZW50Jyk7XG4gICAgICAgIHByZWJ1aWxkVHhXaXRoSW50ZW50LnJlc29sdmVzKHR4UmVxdWVzdEZ1bGwpO1xuXG4gICAgICAgIGF3YWl0IHRzc0V0aFdhbGxldC5wcmVidWlsZFRyYW5zYWN0aW9uKHtcbiAgICAgICAgICByZXFJZCxcbiAgICAgICAgICByZWNpcGllbnRzLFxuICAgICAgICAgIHR5cGU6ICd0cmFuc2ZlcnRva2VuJyxcbiAgICAgICAgICBpc1RzczogdHJ1ZSxcbiAgICAgICAgICBmZWVPcHRpb25zLFxuICAgICAgICB9KTtcblxuICAgICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShwcmVidWlsZFR4V2l0aEludGVudCk7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSBwcmVidWlsZFR4V2l0aEludGVudC5hcmdzWzBdO1xuICAgICAgICBhcmdzWzBdIS5yZWNpcGllbnRzIS5zaG91bGQuZGVlcEVxdWFsKHJlY2lwaWVudHMpO1xuICAgICAgICBhcmdzWzBdIS5mZWVPcHRpb25zIS5zaG91bGQuZGVlcEVxdWFsKGZlZU9wdGlvbnMpO1xuICAgICAgICBhcmdzWzBdIS5pc1RzcyEuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgICBhcmdzWzBdIS5pbnRlbnRUeXBlLnNob3VsZC5lcXVhbCgndHJhbnNmZXJUb2tlbicpO1xuICAgICAgICBhcmdzWzFdIS5zaG91bGQuZXF1YWwoJ2Z1bGwnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGNhbGwgcHJlYnVpbGRUeFdpdGhJbnRlbnQgd2l0aCB0aGUgY29ycmVjdCBwYXJhbXMgZm9yIGV0aCBhY2NlbGVyYXRpb25zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCByZWNpcGllbnRzID0gW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcweEFCMTAwOTEyZTEzM0FBMDZjRUI5MjE0NTlhYURkQmQ2MjM4MUY1QTMnLFxuICAgICAgICAgICAgYW1vdW50OiAnMTAwMCcsXG4gICAgICAgICAgICB0b2tlbk5hbWU6ICdndGVyYzE4ZHAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF07XG5cbiAgICAgICAgY29uc3QgZmVlT3B0aW9ucyA9IHtcbiAgICAgICAgICBtYXhGZWVQZXJHYXM6IDMwMDAwMDAwMDAsXG4gICAgICAgICAgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDIwMDAwMDAwMDAsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgbG93RmVlVHhpZCA9ICcweDZlYTA3Zjk0MjBmNDY3NmJlNjQ3OGFiMTY2MGViOTI0NDRhN2M2NjNlMGUyNGJlY2U5MjlmNzE1ZTg4MmUwY2YnO1xuXG4gICAgICAgIGNvbnN0IHByZWJ1aWxkVHhXaXRoSW50ZW50ID0gc2FuZGJveC5zdHViKEVDRFNBVXRpbHMuRWNkc2FVdGlscy5wcm90b3R5cGUsICdwcmVidWlsZFR4V2l0aEludGVudCcpO1xuICAgICAgICBwcmVidWlsZFR4V2l0aEludGVudC5yZXNvbHZlcyh0eFJlcXVlc3RGdWxsKTtcblxuICAgICAgICBhd2FpdCB0c3NFdGhXYWxsZXQucHJlYnVpbGRUcmFuc2FjdGlvbih7XG4gICAgICAgICAgcmVxSWQsXG4gICAgICAgICAgcmVjaXBpZW50cyxcbiAgICAgICAgICB0eXBlOiAnYWNjZWxlcmF0aW9uJyxcbiAgICAgICAgICBmZWVPcHRpb25zLFxuICAgICAgICAgIGxvd0ZlZVR4aWQsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNpbm9uLmFzc2VydC5jYWxsZWRPbmNlKHByZWJ1aWxkVHhXaXRoSW50ZW50KTtcbiAgICAgICAgY29uc3QgYXJncyA9IHByZWJ1aWxkVHhXaXRoSW50ZW50LmFyZ3NbMF07XG4gICAgICAgIGFyZ3NbMF0hLnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgncmVjaXBpZW50cycpO1xuICAgICAgICBhcmdzWzBdIS5mZWVPcHRpb25zIS5zaG91bGQuZGVlcEVxdWFsKGZlZU9wdGlvbnMpO1xuICAgICAgICBhcmdzWzBdIS5sb3dGZWVUeGlkIS5zaG91bGQuZXF1YWwobG93RmVlVHhpZCk7XG4gICAgICAgIGFyZ3NbMF0hLmludGVudFR5cGUuc2hvdWxkLmVxdWFsKCdhY2NlbGVyYXRpb24nKTtcbiAgICAgICAgYXJnc1sxXSEuc2hvdWxkLmVxdWFsKCdmdWxsJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBjYWxsIHByZWJ1aWxkVHhXaXRoSW50ZW50IHdpdGggdGhlIGNvcnJlY3QgcGFyYW1zIGZvciBldGggYWNjZWxlcmF0aW9ucyBmb3IgcmVjZWl2ZSBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCByZWNpcGllbnRzID0gW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcweEFCMTAwOTEyZTEzM0FBMDZjRUI5MjE0NTlhYURkQmQ2MjM4MUY1QTMnLFxuICAgICAgICAgICAgYW1vdW50OiAnMTAwMCcsXG4gICAgICAgICAgICB0b2tlbk5hbWU6ICdndGVyYzE4ZHAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF07XG5cbiAgICAgICAgY29uc3QgZmVlT3B0aW9ucyA9IHtcbiAgICAgICAgICBtYXhGZWVQZXJHYXM6IDMwMDAwMDAwMDAsXG4gICAgICAgICAgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDIwMDAwMDAwMDAsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgbG93RmVlVHhpZCA9ICcweDZlYTA3Zjk0MjBmNDY3NmJlNjQ3OGFiMTY2MGViOTI0NDRhN2M2NjNlMGUyNGJlY2U5MjlmNzE1ZTg4MmUwY2YnO1xuICAgICAgICBjb25zdCByZWNlaXZlQWRkcmVzcyA9ICcweDA2MjE3NmJjOTM0NWRhM2U4ZWU5MDM2MWIwY2Y2ZmY4ODNiYTcyMDYnO1xuXG4gICAgICAgIGNvbnN0IHByZWJ1aWxkVHhXaXRoSW50ZW50ID0gc2FuZGJveC5zdHViKEVDRFNBVXRpbHMuRWNkc2FVdGlscy5wcm90b3R5cGUsICdwcmVidWlsZFR4V2l0aEludGVudCcpO1xuICAgICAgICBwcmVidWlsZFR4V2l0aEludGVudC5yZXNvbHZlcyh0eFJlcXVlc3RGdWxsKTtcblxuICAgICAgICBhd2FpdCB0c3NFdGhXYWxsZXQucHJlYnVpbGRUcmFuc2FjdGlvbih7XG4gICAgICAgICAgcmVxSWQsXG4gICAgICAgICAgcmVjaXBpZW50cyxcbiAgICAgICAgICB0eXBlOiAnYWNjZWxlcmF0aW9uJyxcbiAgICAgICAgICBmZWVPcHRpb25zLFxuICAgICAgICAgIGxvd0ZlZVR4aWQsXG4gICAgICAgICAgcmVjZWl2ZUFkZHJlc3MsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNpbm9uLmFzc2VydC5jYWxsZWRPbmNlKHByZWJ1aWxkVHhXaXRoSW50ZW50KTtcbiAgICAgICAgY29uc3QgYXJncyA9IHByZWJ1aWxkVHhXaXRoSW50ZW50LmFyZ3NbMF07XG4gICAgICAgIGFyZ3NbMF0hLnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgncmVjaXBpZW50cycpO1xuICAgICAgICBhcmdzWzBdIS5mZWVPcHRpb25zIS5zaG91bGQuZGVlcEVxdWFsKGZlZU9wdGlvbnMpO1xuICAgICAgICBhcmdzWzBdIS5sb3dGZWVUeGlkIS5zaG91bGQuZXF1YWwobG93RmVlVHhpZCk7XG4gICAgICAgIGFyZ3NbMF0hLnJlY2VpdmVBZGRyZXNzIS5zaG91bGQuZXF1YWwocmVjZWl2ZUFkZHJlc3MpO1xuICAgICAgICBhcmdzWzBdIS5pbnRlbnRUeXBlLnNob3VsZC5lcXVhbCgnYWNjZWxlcmF0aW9uJyk7XG4gICAgICAgIGFyZ3NbMV0hLnNob3VsZC5lcXVhbCgnZnVsbCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgY2FsbCBwcmVidWlsZFR4V2l0aEludGVudCB3aXRoIHRoZSBjb3JyZWN0IHBhcmFtcyBmb3IgZXRoIGZpbGxOb25jZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZmVlT3B0aW9ucyA9IHtcbiAgICAgICAgICBtYXhGZWVQZXJHYXM6IDMwMDAwMDAwMDAsXG4gICAgICAgICAgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDIwMDAwMDAwMDAsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcHJlYnVpbGRUeFdpdGhJbnRlbnQgPSBzYW5kYm94LnN0dWIoRUNEU0FVdGlscy5FY2RzYVV0aWxzLnByb3RvdHlwZSwgJ3ByZWJ1aWxkVHhXaXRoSW50ZW50Jyk7XG4gICAgICAgIHByZWJ1aWxkVHhXaXRoSW50ZW50LnJlc29sdmVzKHR4UmVxdWVzdEZ1bGwpO1xuXG4gICAgICAgIGNvbnN0IG5vbmNlID0gJzEnO1xuICAgICAgICBjb25zdCBjb21tZW50ID0gJ2ZpbGxOb25jZSBjb21tZW50JztcblxuICAgICAgICBhd2FpdCB0c3NFdGhXYWxsZXQucHJlYnVpbGRUcmFuc2FjdGlvbih7XG4gICAgICAgICAgcmVxSWQsXG4gICAgICAgICAgdHlwZTogJ2ZpbGxOb25jZScsXG4gICAgICAgICAgZmVlT3B0aW9ucyxcbiAgICAgICAgICBub25jZSxcbiAgICAgICAgICBjb21tZW50LFxuICAgICAgICB9KTtcblxuICAgICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShwcmVidWlsZFR4V2l0aEludGVudCk7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSBwcmVidWlsZFR4V2l0aEludGVudC5hcmdzWzBdO1xuICAgICAgICBhcmdzWzBdIS5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ3JlY2lwaWVudHMnKTtcbiAgICAgICAgYXJnc1swXSEuZmVlT3B0aW9ucyEuc2hvdWxkLmRlZXBFcXVhbChmZWVPcHRpb25zKTtcbiAgICAgICAgYXJnc1swXSEubm9uY2UhLnNob3VsZC5lcXVhbChub25jZSk7XG4gICAgICAgIGFyZ3NbMF0hLmludGVudFR5cGUuc2hvdWxkLmVxdWFsKCdmaWxsTm9uY2UnKTtcbiAgICAgICAgYXJnc1swXSEuY29tbWVudCEuc2hvdWxkLmVxdWFsKGNvbW1lbnQpO1xuICAgICAgICBhcmdzWzFdIS5zaG91bGQuZXF1YWwoJ2Z1bGwnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGNhbGwgcHJlYnVpbGRUeFdpdGhJbnRlbnQgd2l0aCB0aGUgY29ycmVjdCBwYXJhbXMgZm9yIGV0aCBmaWxsTm9uY2UgZm9yIHJlY2VpdmUgYWRkcmVzcyBub25jZSBmaWxsaW5nIHR4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBmZWVPcHRpb25zID0ge1xuICAgICAgICAgIG1heEZlZVBlckdhczogMzAwMDAwMDAwMCxcbiAgICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogMjAwMDAwMDAwMCxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBwcmVidWlsZFR4V2l0aEludGVudCA9IHNhbmRib3guc3R1YihFQ0RTQVV0aWxzLkVjZHNhVXRpbHMucHJvdG90eXBlLCAncHJlYnVpbGRUeFdpdGhJbnRlbnQnKTtcbiAgICAgICAgcHJlYnVpbGRUeFdpdGhJbnRlbnQucmVzb2x2ZXModHhSZXF1ZXN0RnVsbCk7XG5cbiAgICAgICAgY29uc3Qgbm9uY2UgPSAnMSc7XG4gICAgICAgIGNvbnN0IGNvbW1lbnQgPSAnZmlsbE5vbmNlIGNvbW1lbnQnO1xuICAgICAgICBjb25zdCByZWNlaXZlQWRkcmVzcyA9ICcweDA2MjE3NmJjOTM0NWRhM2U4ZWU5MDM2MWIwY2Y2ZmY4ODNiYTcyMDYnO1xuXG4gICAgICAgIGF3YWl0IHRzc0V0aFdhbGxldC5wcmVidWlsZFRyYW5zYWN0aW9uKHtcbiAgICAgICAgICByZXFJZCxcbiAgICAgICAgICB0eXBlOiAnZmlsbE5vbmNlJyxcbiAgICAgICAgICBmZWVPcHRpb25zLFxuICAgICAgICAgIG5vbmNlLFxuICAgICAgICAgIHJlY2VpdmVBZGRyZXNzLFxuICAgICAgICAgIGNvbW1lbnQsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNpbm9uLmFzc2VydC5jYWxsZWRPbmNlKHByZWJ1aWxkVHhXaXRoSW50ZW50KTtcbiAgICAgICAgY29uc3QgYXJncyA9IHByZWJ1aWxkVHhXaXRoSW50ZW50LmFyZ3NbMF07XG4gICAgICAgIGFyZ3NbMF0hLnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgncmVjaXBpZW50cycpO1xuICAgICAgICBhcmdzWzBdIS5mZWVPcHRpb25zIS5zaG91bGQuZGVlcEVxdWFsKGZlZU9wdGlvbnMpO1xuICAgICAgICBhcmdzWzBdIS5ub25jZSEuc2hvdWxkLmVxdWFsKG5vbmNlKTtcbiAgICAgICAgYXJnc1swXSEuaW50ZW50VHlwZS5zaG91bGQuZXF1YWwoJ2ZpbGxOb25jZScpO1xuICAgICAgICBhcmdzWzBdIS5jb21tZW50IS5zaG91bGQuZXF1YWwoY29tbWVudCk7XG4gICAgICAgIGFyZ3NbMF0hLnJlY2VpdmVBZGRyZXNzIS5zaG91bGQuZXF1YWwocmVjZWl2ZUFkZHJlc3MpO1xuICAgICAgICBhcmdzWzFdIS5zaG91bGQuZXF1YWwoJ2Z1bGwnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGNhbGwgcHJlYnVpbGRUeFdpdGhJbnRlbnQgd2l0aCB0aGUgY29ycmVjdCBmZWVPcHRpb25zIHdoZW4gcGFzc2luZyB1c2luZyB0aGUgbGVnYWN5IGZvcm1hdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcmVjaXBpZW50cyA9IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnMHhBQjEwMDkxMmUxMzNBQTA2Y0VCOTIxNDU5YWFEZEJkNjIzODFGNUEzJyxcbiAgICAgICAgICAgIGFtb3VudDogJzEwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF07XG5cbiAgICAgICAgY29uc3QgZXhwZWN0ZWRGZWVPcHRpb25zID0ge1xuICAgICAgICAgIG1heEZlZVBlckdhczogMzAwMDAwMDAwMCxcbiAgICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogMjAwMDAwMDAwMCxcbiAgICAgICAgICBnYXNMaW1pdDogdW5kZWZpbmVkLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHByZWJ1aWxkVHhXaXRoSW50ZW50ID0gc2FuZGJveC5zdHViKEVDRFNBVXRpbHMuRWNkc2FVdGlscy5wcm90b3R5cGUsICdwcmVidWlsZFR4V2l0aEludGVudCcpO1xuICAgICAgICBwcmVidWlsZFR4V2l0aEludGVudC5yZXNvbHZlcyh0eFJlcXVlc3RGdWxsKTtcblxuICAgICAgICBhd2FpdCB0c3NFdGhXYWxsZXQucHJlYnVpbGRUcmFuc2FjdGlvbih7XG4gICAgICAgICAgcmVxSWQsXG4gICAgICAgICAgcmVjaXBpZW50cyxcbiAgICAgICAgICB0eXBlOiAndHJhbnNmZXInLFxuICAgICAgICAgIGVpcDE1NTk6IHtcbiAgICAgICAgICAgIG1heEZlZVBlckdhczogZXhwZWN0ZWRGZWVPcHRpb25zLm1heEZlZVBlckdhcy50b1N0cmluZygpLFxuICAgICAgICAgICAgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IGV4cGVjdGVkRmVlT3B0aW9ucy5tYXhQcmlvcml0eUZlZVBlckdhcy50b1N0cmluZygpLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNpbm9uLmFzc2VydC5jYWxsZWRPbmNlKHByZWJ1aWxkVHhXaXRoSW50ZW50KTtcbiAgICAgICAgY29uc3QgYXJncyA9IHByZWJ1aWxkVHhXaXRoSW50ZW50LmFyZ3NbMF07XG4gICAgICAgIGFyZ3NbMF0hLmZlZU9wdGlvbnMhLnNob3VsZC5kZWVwRXF1YWwoZXhwZWN0ZWRGZWVPcHRpb25zKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgncG9wdWxhdGUgaW50ZW50IHNob3VsZCByZXR1cm4gdmFsaWQgZXRoIGFjY2VsZXJhdGlvbiBpbnRlbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IG1wY1V0aWxzID0gbmV3IEVDRFNBVXRpbHMuRWNkc2FVdGlscyhiaXRnbywgYml0Z28uY29pbignaHRldGgnKSk7XG5cbiAgICAgICAgY29uc3QgZmVlT3B0aW9ucyA9IHtcbiAgICAgICAgICBtYXhGZWVQZXJHYXM6IDMwMDAwMDAwMDAsXG4gICAgICAgICAgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDIwMDAwMDAwMDAsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGxvd0ZlZVR4aWQgPSAnMHg2ZWEwN2Y5NDIwZjQ2NzZiZTY0NzhhYjE2NjBlYjkyNDQ0YTdjNjYzZTBlMjRiZWNlOTI5ZjcxNWU4ODJlMGNmJztcblxuICAgICAgICBjb25zdCBpbnRlbnQgPSBtcGNVdGlscy5wb3B1bGF0ZUludGVudChiaXRnby5jb2luKCdodGV0aCcpLCB7XG4gICAgICAgICAgcmVxSWQsXG4gICAgICAgICAgaW50ZW50VHlwZTogJ2FjY2VsZXJhdGlvbicsXG4gICAgICAgICAgbG93RmVlVHhpZCxcbiAgICAgICAgICBmZWVPcHRpb25zLFxuICAgICAgICB9KTtcblxuICAgICAgICBpbnRlbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY2lwaWVudHMnLCB1bmRlZmluZWQpO1xuICAgICAgICBpbnRlbnQuZmVlT3B0aW9ucyEuc2hvdWxkLmRlZXBFcXVhbChmZWVPcHRpb25zKTtcbiAgICAgICAgaW50ZW50LnR4aWQhLnNob3VsZC5lcXVhbChsb3dGZWVUeGlkKTtcbiAgICAgICAgaW50ZW50LmludGVudFR5cGUuc2hvdWxkLmVxdWFsKCdhY2NlbGVyYXRpb24nKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgncG9wdWxhdGUgaW50ZW50IHNob3VsZCByZXR1cm4gdmFsaWQgZXRoIGFjY2VsZXJhdGlvbiBpbnRlbnQgZm9yIHJlY2VpdmUgYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgbXBjVXRpbHMgPSBuZXcgRUNEU0FVdGlscy5FY2RzYVV0aWxzKGJpdGdvLCBiaXRnby5jb2luKCdodGV0aCcpKTtcblxuICAgICAgICBjb25zdCBmZWVPcHRpb25zID0ge1xuICAgICAgICAgIG1heEZlZVBlckdhczogMzAwMDAwMDAwMCxcbiAgICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogMjAwMDAwMDAwMCxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgbG93RmVlVHhpZCA9ICcweDZlYTA3Zjk0MjBmNDY3NmJlNjQ3OGFiMTY2MGViOTI0NDRhN2M2NjNlMGUyNGJlY2U5MjlmNzE1ZTg4MmUwY2YnO1xuICAgICAgICBjb25zdCByZWNlaXZlQWRkcmVzcyA9ICcweDA2MjE3NmJjOTM0NWRhM2U4ZWU5MDM2MWIwY2Y2ZmY4ODNiYTcyMDYnO1xuXG4gICAgICAgIGNvbnN0IGludGVudCA9IG1wY1V0aWxzLnBvcHVsYXRlSW50ZW50KGJpdGdvLmNvaW4oJ2h0ZXRoJyksIHtcbiAgICAgICAgICByZXFJZCxcbiAgICAgICAgICBpbnRlbnRUeXBlOiAnYWNjZWxlcmF0aW9uJyxcbiAgICAgICAgICBsb3dGZWVUeGlkLFxuICAgICAgICAgIHJlY2VpdmVBZGRyZXNzLFxuICAgICAgICAgIGZlZU9wdGlvbnMsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGludGVudC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncmVjaXBpZW50cycsIHVuZGVmaW5lZCk7XG4gICAgICAgIGludGVudC5mZWVPcHRpb25zIS5zaG91bGQuZGVlcEVxdWFsKGZlZU9wdGlvbnMpO1xuICAgICAgICBpbnRlbnQudHhpZCEuc2hvdWxkLmVxdWFsKGxvd0ZlZVR4aWQpO1xuICAgICAgICBpbnRlbnQucmVjZWl2ZUFkZHJlc3MhLnNob3VsZC5lcXVhbChyZWNlaXZlQWRkcmVzcyk7XG4gICAgICAgIGludGVudC5pbnRlbnRUeXBlLnNob3VsZC5lcXVhbCgnYWNjZWxlcmF0aW9uJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3BvcHVsYXRlIGludGVudCBzaG91bGQgcmV0dXJuIHZhbGlkIGV0aCBmaWxsTm9uY2UgaW50ZW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBtcGNVdGlscyA9IG5ldyBFQ0RTQVV0aWxzLkVjZHNhVXRpbHMoYml0Z28sIGJpdGdvLmNvaW4oJ2h0ZXRoJykpO1xuICAgICAgICBjb25zdCBmZWVPcHRpb25zID0ge1xuICAgICAgICAgIG1heEZlZVBlckdhczogMzAwMDAwMDAwMCxcbiAgICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogMjAwMDAwMDAwMCxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgbm9uY2UgPSAnMSc7XG5cbiAgICAgICAgY29uc3QgaW50ZW50ID0gbXBjVXRpbHMucG9wdWxhdGVJbnRlbnQoYml0Z28uY29pbignaHRldGgnKSwge1xuICAgICAgICAgIHJlcUlkLFxuICAgICAgICAgIGludGVudFR5cGU6ICdmaWxsTm9uY2UnLFxuICAgICAgICAgIG5vbmNlLFxuICAgICAgICAgIGZlZU9wdGlvbnMsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGludGVudC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncmVjaXBpZW50cycsIHVuZGVmaW5lZCk7XG4gICAgICAgIGludGVudC5mZWVPcHRpb25zIS5zaG91bGQuZGVlcEVxdWFsKGZlZU9wdGlvbnMpO1xuICAgICAgICBpbnRlbnQubm9uY2UhLnNob3VsZC5lcXVhbChub25jZSk7XG4gICAgICAgIGludGVudC5pbnRlbnRUeXBlLnNob3VsZC5lcXVhbCgnZmlsbE5vbmNlJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3BvcHVsYXRlIGludGVudCBzaG91bGQgcmV0dXJuIHZhbGlkIGV0aCBmaWxsTm9uY2UgaW50ZW50IGZvciByZWNlaXZlIGFkZHJlc3Mgbm9uY2UgZmlsbGluZyB0eCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgbXBjVXRpbHMgPSBuZXcgRUNEU0FVdGlscy5FY2RzYVV0aWxzKGJpdGdvLCBiaXRnby5jb2luKCdodGV0aCcpKTtcbiAgICAgICAgY29uc3QgZmVlT3B0aW9ucyA9IHtcbiAgICAgICAgICBtYXhGZWVQZXJHYXM6IDMwMDAwMDAwMDAsXG4gICAgICAgICAgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDIwMDAwMDAwMDAsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IG5vbmNlID0gJzEnO1xuICAgICAgICBjb25zdCByZWNlaXZlQWRkcmVzcyA9ICcweDA2MjE3NmJjOTM0NWRhM2U4ZWU5MDM2MWIwY2Y2ZmY4ODNiYTcyMDYnO1xuXG4gICAgICAgIGNvbnN0IGludGVudCA9IG1wY1V0aWxzLnBvcHVsYXRlSW50ZW50KGJpdGdvLmNvaW4oJ2h0ZXRoJyksIHtcbiAgICAgICAgICByZXFJZCxcbiAgICAgICAgICBpbnRlbnRUeXBlOiAnZmlsbE5vbmNlJyxcbiAgICAgICAgICBub25jZSxcbiAgICAgICAgICByZWNlaXZlQWRkcmVzcyxcbiAgICAgICAgICBmZWVPcHRpb25zLFxuICAgICAgICB9KTtcblxuICAgICAgICBpbnRlbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY2lwaWVudHMnLCB1bmRlZmluZWQpO1xuICAgICAgICBpbnRlbnQuZmVlT3B0aW9ucyEuc2hvdWxkLmRlZXBFcXVhbChmZWVPcHRpb25zKTtcbiAgICAgICAgaW50ZW50Lm5vbmNlIS5zaG91bGQuZXF1YWwobm9uY2UpO1xuICAgICAgICBpbnRlbnQucmVjZWl2ZUFkZHJlc3MhLnNob3VsZC5lcXVhbChyZWNlaXZlQWRkcmVzcyk7XG4gICAgICAgIGludGVudC5pbnRlbnRUeXBlLnNob3VsZC5lcXVhbCgnZmlsbE5vbmNlJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBwb3B1bGF0ZSBpbnRlbnQgd2l0aCBjdXN0b2RpYW5UcmFuc2FjdGlvbklkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBtcGNVdGlscyA9IG5ldyBFQ0RTQVV0aWxzLkVjZHNhVXRpbHMoYml0Z28sIGJpdGdvLmNvaW4oJ2h0ZXRoJykpO1xuICAgICAgICBjb25zdCBmZWVPcHRpb25zID0ge1xuICAgICAgICAgIG1heEZlZVBlckdhczogMzAwMDAwMDAwMCxcbiAgICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogMjAwMDAwMDAwMCxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgbm9uY2UgPSAnMSc7XG5cbiAgICAgICAgY29uc3QgaW50ZW50ID0gbXBjVXRpbHMucG9wdWxhdGVJbnRlbnQoYml0Z28uY29pbignaHRldGgnKSwge1xuICAgICAgICAgIGN1c3RvZGlhblRyYW5zYWN0aW9uSWQ6ICd1bml0dGVzdCcsXG4gICAgICAgICAgcmVxSWQsXG4gICAgICAgICAgaW50ZW50VHlwZTogJ2ZpbGxOb25jZScsXG4gICAgICAgICAgbm9uY2UsXG4gICAgICAgICAgZmVlT3B0aW9ucyxcbiAgICAgICAgICBpc1RzczogdHJ1ZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaW50ZW50LmN1c3RvZGlhblRyYW5zYWN0aW9uSWQhLnNob3VsZC5lcXVhbCgndW5pdHRlc3QnKTtcbiAgICAgICAgaW50ZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNpcGllbnRzJywgdW5kZWZpbmVkKTtcbiAgICAgICAgaW50ZW50LmZlZU9wdGlvbnMhLnNob3VsZC5kZWVwRXF1YWwoZmVlT3B0aW9ucyk7XG4gICAgICAgIGludGVudC5ub25jZSEuc2hvdWxkLmVxdWFsKG5vbmNlKTtcbiAgICAgICAgaW50ZW50LmlzVHNzIS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICAgIGludGVudC5pbnRlbnRUeXBlLnNob3VsZC5lcXVhbCgnZmlsbE5vbmNlJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBidWlsZCBhIHNpbmdsZSByZWNpcGllbnQgdHJhbnNmZXIgdHJhbnNhY3Rpb24gcHJvdmlkaW5nIGFwaVZlcnNpb24gcGFyYW1ldGVyIGFzIFwiZnVsbFwiICcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcmVjaXBpZW50cyA9IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnNkRhZGtaY3g5SlpnZVFVRGJIaDEyY21xQ3BhcWVobVZ4djZzR3k0OWpyYWgnLFxuICAgICAgICAgICAgYW1vdW50OiAnMTAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXTtcblxuICAgICAgICBjb25zdCBwcmVidWlsZFR4V2l0aEludGVudCA9IHNhbmRib3guc3R1YihUc3NVdGlscy5wcm90b3R5cGUsICdwcmVidWlsZFR4V2l0aEludGVudCcpO1xuICAgICAgICBwcmVidWlsZFR4V2l0aEludGVudC5yZXNvbHZlcyh0eFJlcXVlc3RGdWxsKTtcbiAgICAgICAgcHJlYnVpbGRUeFdpdGhJbnRlbnQuY2FsbGVkT25jZVdpdGhFeGFjdGx5KFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHJlcUlkLFxuICAgICAgICAgICAgcmVjaXBpZW50cyxcbiAgICAgICAgICAgIGludGVudFR5cGU6ICdwYXltZW50JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgICdmdWxsJ1xuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBhd2FpdCBjdXN0b2RpYWxUc3NTb2xXYWxsZXQucHJlYnVpbGRUcmFuc2FjdGlvbih7XG4gICAgICAgICAgcmVxSWQsXG4gICAgICAgICAgYXBpVmVyc2lvbjogJ2Z1bGwnLFxuICAgICAgICAgIHJlY2lwaWVudHMsXG4gICAgICAgICAgdHlwZTogJ3RyYW5zZmVyJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdHhQcmVidWlsZC5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgICB3YWxsZXRJZDogdHNzU29sV2FsbGV0LmlkKCksXG4gICAgICAgICAgd2FsbGV0OiBjdXN0b2RpYWxUc3NTb2xXYWxsZXQsXG4gICAgICAgICAgdHhSZXF1ZXN0SWQ6ICdpZCcsXG4gICAgICAgICAgdHhIZXg6ICdhYmFiY2RjZCcsXG4gICAgICAgICAgYnVpbGRQYXJhbXM6IHtcbiAgICAgICAgICAgIGFwaVZlcnNpb246ICdmdWxsJyxcbiAgICAgICAgICAgIHJlY2lwaWVudHMsXG4gICAgICAgICAgICB0eXBlOiAndHJhbnNmZXInLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgICAgZmVlOiA1MDAwLFxuICAgICAgICAgICAgZmVlU3RyaW5nOiAnNTAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdUcmFuc2FjdGlvbiBzaWduaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCBzaWduIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaWduVHhSZXF1ZXN0ID0gc2FuZGJveC5zdHViKFRzc1V0aWxzLnByb3RvdHlwZSwgJ3NpZ25UeFJlcXVlc3QnKTtcbiAgICAgICAgc2lnblR4UmVxdWVzdC5yZXNvbHZlcyh0eFJlcXVlc3QpO1xuICAgICAgICAvLyBUT0RPKEJHLTU5Njg2KTogdGhpcyBpcyBub3QgZG9pbmcgYW55dGhpbmcgaWYgd2UgZG9uJ3QgY2hlY2sgdGhlIHJldHVybiB2YWx1ZSwgd2Ugc2hvdWxkIGFsc28gbW92ZSB0aGlzIGNoZWNrIHRvIGhhcHBlbiBhZnRlciB3ZSBpbnZva2Ugc2lnblRyYW5zYWN0aW9uXG4gICAgICAgIHNpZ25UeFJlcXVlc3QuY2FsbGVkT25jZVdpdGhFeGFjdGx5KHsgdHhSZXF1ZXN0LCBwcnY6ICdzZWNyZXRLZXknLCByZXFJZCB9KTtcblxuICAgICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICAgIHdhbGxldElkOiB0c3NTb2xXYWxsZXQuaWQoKSxcbiAgICAgICAgICB3YWxsZXQ6IHRzc1NvbFdhbGxldCxcbiAgICAgICAgICB0eFJlcXVlc3RJZDogJ2lkJyxcbiAgICAgICAgICB0eEhleDogJ2FiYWJjZGNkJyxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgc2lnbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCB0c3NTb2xXYWxsZXQuc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgICByZXFJZCxcbiAgICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICAgIHBydjogJ3NlcmNyZXRLZXknLFxuICAgICAgICB9KTtcbiAgICAgICAgc2lnbmVkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh0eFJlcXVlc3QpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZmFpbCB0byBzaWduIHRyYW5zYWN0aW9uIHdpdGhvdXQgdHhSZXF1ZXN0SWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgICAgd2FsbGV0SWQ6IHRzc1NvbFdhbGxldC5pZCgpLFxuICAgICAgICAgIHdhbGxldDogdHNzU29sV2FsbGV0LFxuICAgICAgICAgIHR4SGV4OiAnYWJhYmNkY2QnLFxuICAgICAgICB9O1xuICAgICAgICBhd2FpdCB0c3NTb2xXYWxsZXRcbiAgICAgICAgICAuc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgICAgIHJlcUlkLFxuICAgICAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgICAgIHBydjogJ3NlcmNyZXRLZXknLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3R4UmVxdWVzdElkIHJlcXVpcmVkIHRvIHNpZ24gdHJhbnNhY3Rpb25zIHdpdGggVFNTJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdnZXRVc2VyS2V5QW5kU2lnblRzc1RyYW5zYWN0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgWydlZGRzYScsICdlY2RzYSddLmZvckVhY2goKGtleUN1cnZlOiBzdHJpbmcpID0+IHtcbiAgICAgICAgZGVzY3JpYmUoa2V5Q3VydmUsICgpID0+IHtcbiAgICAgICAgICBjb25zdCB3YWxsZXQgPSBrZXlDdXJ2ZSA9PT0gJ2VkZHNhJyA/IHRzc1NvbFdhbGxldCA6IHRzc0V0aFdhbGxldDtcbiAgICAgICAgICBsZXQgZ2V0S2V5c1N0dWI6IHNpbm9uLlNpbm9uU3R1YjtcbiAgICAgICAgICBsZXQgc2lnblRyYW5zYWN0aW9uU3R1Yjogc2lub24uU2lub25TdHViO1xuICAgICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZ2V0S2V5c1N0dWIgPSBzYW5kYm94LnN0dWIoS2V5Y2hhaW5zLnByb3RvdHlwZSwgJ2dldEtleXNGb3JTaWduaW5nJyk7XG5cbiAgICAgICAgICAgIHNpZ25UcmFuc2FjdGlvblN0dWIgPSBzYW5kYm94XG4gICAgICAgICAgICAgIC5zdHViKFdhbGxldC5wcm90b3R5cGUsICdzaWduVHJhbnNhY3Rpb24nKVxuICAgICAgICAgICAgICAucmVzb2x2ZXMoeyAuLi50eFJlcXVlc3RGdWxsLCBzdGF0ZTogJ3NpZ25lZCcgfSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2FuZGJveC52ZXJpZnlBbmRSZXN0b3JlKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaXQoJ3Nob3VsZCBzaWduIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZ2V0S2V5c1N0dWIucmVzb2x2ZXMoW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46ICd0ZXN0JyxcbiAgICAgICAgICAgICAgICBpZDogJycsXG4gICAgICAgICAgICAgICAgcHViOiAnJyxcbiAgICAgICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6XG4gICAgICAgICAgICAgICAgICAne1wiaXZcIjpcIjE1RnNiRFZJMXpHOU9nZ0Q4WVgrSGc9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJoSGJOSDNTei9hVT1cIixcImN0XCI6XCJXb05WS3o3YWZpUnhYSTJ3L1lrek1kTXlvUWcvQjE1dTFROGFRZ2k5NmpKWjl3azZUSWFTRWM2YlhGSDNBSHpEOU1kSkNXSlFVcFJob1FjL3JneXRjbjY5c2NQVGpLZWV5Vk1FbEdDeFpkRlZTL3BzUWNORStsdWUzLy8yWmx4ais2dDFOa3ZZTys4eUFlelNNUkJLNU9kZnRYRWpOUUk9XCJ9JyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX1BBU1NQSFJBU0UgYXMgc3RyaW5nLFxuICAgICAgICAgICAgICB0eFJlcXVlc3RJZDogJ2lkJyxcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2FsbGV0LmdldFVzZXJLZXlBbmRTaWduVHNzVHJhbnNhY3Rpb24ocGFyYW1zKTtcbiAgICAgICAgICAgIHJlc3BvbnNlLnNob3VsZC5kZWVwRXF1YWwoeyAuLi50eFJlcXVlc3RGdWxsLCBzdGF0ZTogJ3NpZ25lZCcgfSk7XG5cbiAgICAgICAgICAgIGdldEtleXNTdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgICAgIHNpZ25UcmFuc2FjdGlvblN0dWIuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBpZiB0aGUga2V5Y2hhaW4gZG9lc250IGhhdmUgdGhlIGVuY3J5cHRlZEtleScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGdldEtleXNTdHViLnJlc29sdmVzKFt7IGNvbW1vbktleWNoYWluOiAndGVzdCcsIGlkOiAnJywgcHViOiAnJywgdHlwZTogJ3RzcycgfV0pO1xuICAgICAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX1BBU1NQSFJBU0UgYXMgc3RyaW5nLFxuICAgICAgICAgICAgICB0eFJlcXVlc3RJZDogJ2lkJyxcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAgICAgICAuZ2V0VXNlcktleUFuZFNpZ25Uc3NUcmFuc2FjdGlvbihwYXJhbXMpXG4gICAgICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCd0aGUgdXNlciBrZXljaGFpbiBkb2VzIG5vdCBoYXZlIHByb3BlcnR5IGVuY3J5cHRlZFBydicpO1xuXG4gICAgICAgICAgICBnZXRLZXlzU3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgICAgICBzaWduVHJhbnNhY3Rpb25TdHViLm5vdENhbGxlZC5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBpZiBwYXNzd29yZCBpcyBpbnZhbGlkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZ2V0S2V5c1N0dWIucmVzb2x2ZXMoW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46ICd0ZXN0JyxcbiAgICAgICAgICAgICAgICBpZDogJycsXG4gICAgICAgICAgICAgICAgcHViOiAnJyxcbiAgICAgICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6XG4gICAgICAgICAgICAgICAgICAne1wiaXZcIjpcIjE1RnNiRFZJMXpHOU9nZ0Q4WVgrSGc9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJoSGJOSDNTei9hVT1cIixcImN0XCI6XCJXb05WS3o3YWZpUnhYSTJ3L1lrek1kTXlvUWcvQjE1dTFROGFRZ2k5NmpKWjl3azZUSWFTRWM2YlhGSDNBSHpEOU1kSkNXSlFVcFJob1FjL3JneXRjbjY5c2NQVGpLZWV5Vk1FbEdDeFpkRlZTL3BzUWNORStsdWUzLy8yWmx4ais2dDFOa3ZZTys4eUFlelNNUkJLNU9kZnRYRWpOUUk9XCJ9JyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAncmFuZG9tcGFzcycsXG4gICAgICAgICAgICAgIHR4UmVxdWVzdElkOiAnaWQnLFxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgYXdhaXQgd2FsbGV0XG4gICAgICAgICAgICAgIC5nZXRVc2VyS2V5QW5kU2lnblRzc1RyYW5zYWN0aW9uKHBhcmFtcylcbiAgICAgICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoYHVuYWJsZSB0byBkZWNyeXB0IGtleWNoYWluIHdpdGggdGhlIGdpdmVuIHdhbGxldCBwYXNzcGhyYXNlYCk7XG5cbiAgICAgICAgICAgIGdldEtleXNTdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgICAgIHNpZ25UcmFuc2FjdGlvblN0dWIubm90Q2FsbGVkLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnc2lnbkFuZFNlbmRUeFJlcXVlc3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleGFtcGxlU2lnbmVkVHggPSB7XG4gICAgICAgIHR4SGV4OiAnMHgxMjMnLFxuICAgICAgICB0eGlkOiAnMHg0NTYnLFxuICAgICAgICBzdGF0dXM6ICdzaWduZWQnLFxuICAgICAgfTtcblxuICAgICAgYWZ0ZXJFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2FuZGJveC5yZXN0b3JlKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBzaWduIGxpdGUgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGdldFVzZXJLZXlBbmRTaWduVHNzVHhTcHkgPSBzYW5kYm94LnN0dWIodHNzU29sV2FsbGV0LCAnZ2V0VXNlcktleUFuZFNpZ25Uc3NUcmFuc2FjdGlvbicpO1xuICAgICAgICBnZXRVc2VyS2V5QW5kU2lnblRzc1R4U3B5LnJlc29sdmVzKGV4YW1wbGVTaWduZWRUeCk7XG4gICAgICAgIGNvbnN0IHN1Ym1pdFR4U3B5ID0gc2FuZGJveC5zdHViKHRzc1NvbFdhbGxldCwgJ3N1Ym1pdFRyYW5zYWN0aW9uJyk7XG4gICAgICAgIHN1Ym1pdFR4U3B5LnJlc29sdmVzKGV4YW1wbGVTaWduZWRUeCk7XG5cbiAgICAgICAgY29uc3Qgc2lnbmVkVHggPSBhd2FpdCB0c3NTb2xXYWxsZXQuc2lnbkFuZFNlbmRUeFJlcXVlc3Qoe1xuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdwYXNzcGhyYXNlJyxcbiAgICAgICAgICB0eFJlcXVlc3RJZDogJ2lkJyxcbiAgICAgICAgICBpc1R4UmVxdWVzdEZ1bGw6IGZhbHNlLFxuICAgICAgICB9KTtcblxuICAgICAgICBzYW5kYm94LmFzc2VydC5jYWxsZWRPbmNlKGdldFVzZXJLZXlBbmRTaWduVHNzVHhTcHkpO1xuICAgICAgICBzYW5kYm94LmFzc2VydC5jYWxsZWRPbmNlKHN1Ym1pdFR4U3B5KTtcbiAgICAgICAgc2lnbmVkVHguc2hvdWxkLmRlZXBFcXVhbChleGFtcGxlU2lnbmVkVHgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgc2lnbiBmdWxsIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBkZWxldGVTaWduYXR1cmVTaGFyZXNTcHkgPSBzYW5kYm94LnN0dWIoVHNzVXRpbHMucHJvdG90eXBlLCAnZGVsZXRlU2lnbmF0dXJlU2hhcmVzJyk7XG4gICAgICAgIGNvbnN0IGdldFVzZXJLZXlBbmRTaWduVHNzVHhTcHkgPSBzYW5kYm94LnN0dWIodHNzU29sV2FsbGV0LCAnZ2V0VXNlcktleUFuZFNpZ25Uc3NUcmFuc2FjdGlvbicpO1xuICAgICAgICBnZXRVc2VyS2V5QW5kU2lnblRzc1R4U3B5LnJlc29sdmVzKGV4YW1wbGVTaWduZWRUeCk7XG5cbiAgICAgICAgY29uc3Qgc2lnbmVkVHggPSBhd2FpdCB0c3NTb2xXYWxsZXQuc2lnbkFuZFNlbmRUeFJlcXVlc3Qoe1xuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdwYXNzcGhyYXNlJyxcbiAgICAgICAgICB0eFJlcXVlc3RJZDogJ2lkJyxcbiAgICAgICAgICBpc1R4UmVxdWVzdEZ1bGw6IHRydWUsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNhbmRib3guYXNzZXJ0LmNhbGxlZE9uY2UoZGVsZXRlU2lnbmF0dXJlU2hhcmVzU3B5KTtcbiAgICAgICAgc2FuZGJveC5hc3NlcnQuY2FsbGVkT25jZShnZXRVc2VyS2V5QW5kU2lnblRzc1R4U3B5KTtcbiAgICAgICAgc2lnbmVkVHguc2hvdWxkLmRlZXBFcXVhbChleGFtcGxlU2lnbmVkVHgpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnTWVzc2FnZSBTaWduaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhIYXNoID0gJzB4cnJyc3NzMWInO1xuICAgICAgY29uc3QgdHhSZXF1ZXN0Rm9yTWVzc2FnZVNpZ25pbmc6IFR4UmVxdWVzdCA9IHtcbiAgICAgICAgdHhSZXF1ZXN0SWQ6IHJlcUlkLnRvU3RyaW5nKCksXG4gICAgICAgIHRyYW5zYWN0aW9uczogW10sXG4gICAgICAgIGludGVudDoge1xuICAgICAgICAgIGludGVudFR5cGU6ICdzaWduTWVzc2FnZScsXG4gICAgICAgIH0sXG4gICAgICAgIGRhdGU6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgbGF0ZXN0OiB0cnVlLFxuICAgICAgICBzdGF0ZTogJ3BlbmRpbmdVc2VyU2lnbmF0dXJlJyxcbiAgICAgICAgdXNlcklkOiAndXNlcklkJyxcbiAgICAgICAgd2FsbGV0VHlwZTogJ2hvdCcsXG4gICAgICAgIHBvbGljaWVzQ2hlY2tlZDogZmFsc2UsXG4gICAgICAgIHZlcnNpb246IDEsXG4gICAgICAgIHdhbGxldElkOiAnd2FsbGV0SWQnLFxuICAgICAgICB1bnNpZ25lZFR4czogW10sXG4gICAgICAgIHVuc2lnbmVkTWVzc2FnZXM6IFtdLFxuICAgICAgICBtZXNzYWdlczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHN0YXRlOiAnc2lnbmVkJyxcbiAgICAgICAgICAgIG1lc3NhZ2VSYXc6ICdoZWxsbyB3b3JsZCcsXG4gICAgICAgICAgICBkZXJpdmF0aW9uUGF0aDogJ20vMCcsXG4gICAgICAgICAgICBzaWduYXR1cmVTaGFyZXM6IFt7IGZyb206IFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSLCB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsIHNoYXJlOiAnJyB9XSxcbiAgICAgICAgICAgIGNvbWJpbmVTaWdTaGFyZTogJzA6cnJyOnNzczozJyxcbiAgICAgICAgICAgIHR4SGFzaCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICAgIGxldCBzaWduVHhSZXF1ZXN0Rm9yTWVzc2FnZTtcbiAgICAgIGNvbnN0IG1lc3NhZ2VTaWduaW5nQ29pbnMgPSBbJ3RldGgnLCAndHBvbHlnb24nXTtcbiAgICAgIGNvbnN0IG1lc3NhZ2VSYXcgPSAndGVzdCc7XG4gICAgICBjb25zdCBleHBlY3RlZDogU2lnbmVkTWVzc2FnZSA9IHtcbiAgICAgICAgdHhSZXF1ZXN0SWQ6IHJlcUlkLnRvU3RyaW5nKCksXG4gICAgICAgIHR4SGFzaCxcbiAgICAgICAgc2lnbmF0dXJlOiB0eEhhc2gsXG4gICAgICAgIG1lc3NhZ2VSYXcsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgbWVzc2FnZUVuY29kZWQ6IEJ1ZmZlci5mcm9tKCdcXHUwMDE5RXRoZXJldW0gU2lnbmVkIE1lc3NhZ2U6XFxuNHRlc3QnKS50b1N0cmluZygnaGV4JyksXG4gICAgICB9O1xuXG4gICAgICBiZWZvcmVFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2lnblR4UmVxdWVzdEZvck1lc3NhZ2UgPSBzYW5kYm94LnN0dWIoRUNEU0FVdGlscy5FY2RzYVV0aWxzLnByb3RvdHlwZSwgJ3NpZ25UeFJlcXVlc3RGb3JNZXNzYWdlJyk7XG4gICAgICAgIHNpZ25UeFJlcXVlc3RGb3JNZXNzYWdlLnJlc29sdmVzKHR4UmVxdWVzdEZvck1lc3NhZ2VTaWduaW5nKTtcbiAgICAgICAgc2FuZGJveFxuICAgICAgICAgIC5zdHViKEtleWNoYWlucy5wcm90b3R5cGUsICdnZXRLZXlzRm9yU2lnbmluZycpXG4gICAgICAgICAgLnJlc29sdmVzKFt7IGNvbW1vbktleWNoYWluOiAndGVzdCcsIGlkOiAnJywgcHViOiAnJywgdHlwZTogJ2luZGVwZW5kZW50JyB9XSk7XG4gICAgICAgIHNpbm9uLnN0dWIoRWNkc2EucHJvdG90eXBlLCAndmVyaWZ5JykucmVzb2x2ZXModHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgYWZ0ZXJFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2lub24ucmVzdG9yZSgpO1xuICAgICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3IgdW5zdXBwb3J0ZWQgY29pbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGF3YWl0IHRzc1NvbFdhbGxldFxuICAgICAgICAgIC5zaWduTWVzc2FnZSh7XG4gICAgICAgICAgICByZXFJZCxcbiAgICAgICAgICAgIG1lc3NhZ2U6IHsgbWVzc2FnZVJhdyB9LFxuICAgICAgICAgICAgcHJ2OiAnc2VjcmV0S2V5JyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdNZXNzYWdlIHNpZ25pbmcgbm90IHN1cHBvcnRlZCBmb3IgVGVzdG5ldCBTb2xhbmEnKTtcbiAgICAgIH0pO1xuXG4gICAgICBtZXNzYWdlU2lnbmluZ0NvaW5zLm1hcCgoY29pbk5hbWUpID0+IHtcbiAgICAgICAgY29uc3QgZXhwZWN0ZWRXaXRoQ29pbkZpZWxkID0geyAuLi5leHBlY3RlZCwgY29pbjogJ3RldGgnIH07XG5cbiAgICAgICAgdHNzRXRoV2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYml0Z28uY29pbihjb2luTmFtZSksIGV0aFdhbGxldERhdGEpO1xuICAgICAgICBjb25zdCB0eFJlcXVlc3RJZCA9IHR4UmVxdWVzdEZvck1lc3NhZ2VTaWduaW5nLnR4UmVxdWVzdElkO1xuXG4gICAgICAgIGl0KCdzaG91bGQgc2lnbiBtZXNzYWdlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHNpZ25NZXNzYWdlVHNzU3B5ID0gc2lub24uc3B5KHRzc0V0aFdhbGxldCwgJ3NpZ25NZXNzYWdlVHNzJyBhcyBhbnkpO1xuICAgICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgICAuZ2V0KFxuICAgICAgICAgICAgICBgL2FwaS92Mi93YWxsZXQvJHt0c3NFdGhXYWxsZXQuaWQoKX0vdHhyZXF1ZXN0cz90eFJlcXVlc3RJZHM9JHtcbiAgICAgICAgICAgICAgICB0eFJlcXVlc3RGb3JNZXNzYWdlU2lnbmluZy50eFJlcXVlc3RJZFxuICAgICAgICAgICAgICB9JmxhdGVzdD10cnVlYFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnJlcGx5KDIwMCwgeyB0eFJlcXVlc3RzOiBbdHhSZXF1ZXN0Rm9yTWVzc2FnZVNpZ25pbmddIH0pO1xuXG4gICAgICAgICAgY29uc3Qgc2lnbk1lc3NhZ2UgPSBhd2FpdCB0c3NFdGhXYWxsZXQuc2lnbk1lc3NhZ2Uoe1xuICAgICAgICAgICAgcmVxSWQsXG4gICAgICAgICAgICBtZXNzYWdlOiB7IG1lc3NhZ2VSYXcsIHR4UmVxdWVzdElkIH0sXG4gICAgICAgICAgICBwcnY6ICdzZWNyZXRLZXknLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHNpZ25NZXNzYWdlLnNob3VsZC5kZWVwRXF1YWwoZXhwZWN0ZWRXaXRoQ29pbkZpZWxkKTtcbiAgICAgICAgICBjb25zdCBhY3R1YWxBcmcgPSBzaWduTWVzc2FnZVRzc1NweS5nZXRDYWxscygpWzBdLmFyZ3NbMF0gYXMgV2FsbGV0U2lnbk1lc3NhZ2VPcHRpb25zO1xuICAgICAgICAgIGFjdHVhbEFyZy5tZXNzYWdlPy5tZXNzYWdlRW5jb2RlZD8uc2hvdWxkLmVxdWFsKFxuICAgICAgICAgICAgQnVmZmVyLmZyb20oYFxcdTAwMTlFdGhlcmV1bSBTaWduZWQgTWVzc2FnZTpcXG4ke21lc3NhZ2VSYXcubGVuZ3RofSR7bWVzc2FnZVJhd31gKS50b1N0cmluZygnaGV4JylcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHNpZ24gbWVzc2FnZSB3aGVuIGN1c3RvZGlhbk1lc3NhZ2VJZCBpcyBwcm92aWRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBzaWduTWVzc2FnZVRzc1NweSA9IHNpbm9uLnNweSh0c3NFdGhXYWxsZXQsICdzaWduTWVzc2FnZVRzcycgYXMgYW55KTtcbiAgICAgICAgICBub2NrKGJnVXJsKS5wb3N0KGAvYXBpL3YyL3dhbGxldC8ke3Rzc0V0aFdhbGxldC5pZCgpfS90eHJlcXVlc3RzYCkucmVwbHkoMjAwLCB0eFJlcXVlc3RGb3JNZXNzYWdlU2lnbmluZyk7XG5cbiAgICAgICAgICBjb25zdCBzaWduTWVzc2FnZSA9IGF3YWl0IHRzc0V0aFdhbGxldC5zaWduTWVzc2FnZSh7XG4gICAgICAgICAgICBjdXN0b2RpYW5NZXNzYWdlSWQ6ICd1bml0dGVzdCcsXG4gICAgICAgICAgICByZXFJZCxcbiAgICAgICAgICAgIG1lc3NhZ2U6IHsgbWVzc2FnZVJhdyB9LFxuICAgICAgICAgICAgcHJ2OiAnc2VjcmV0S2V5JyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBzaWduTWVzc2FnZS5zaG91bGQuZGVlcEVxdWFsKGV4cGVjdGVkV2l0aENvaW5GaWVsZCk7XG4gICAgICAgICAgY29uc3QgYWN0dWFsQXJnID0gc2lnbk1lc3NhZ2VUc3NTcHkuZ2V0Q2FsbHMoKVswXS5hcmdzWzBdIGFzIFdhbGxldFNpZ25NZXNzYWdlT3B0aW9ucztcbiAgICAgICAgICBhY3R1YWxBcmcubWVzc2FnZT8ubWVzc2FnZUVuY29kZWQ/LnNob3VsZC5lcXVhbChcbiAgICAgICAgICAgIEJ1ZmZlci5mcm9tKGBcXHUwMDE5RXRoZXJldW0gU2lnbmVkIE1lc3NhZ2U6XFxuJHttZXNzYWdlUmF3Lmxlbmd0aH0ke21lc3NhZ2VSYXd9YCkudG9TdHJpbmcoJ2hleCcpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBzaWduIG1lc3NhZ2Ugd2hlbiB0eFJlcXVlc3RJZCBub3QgcHJvdmlkZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qgc2lnbk1lc3NhZ2VUc3NTcHkgPSBzaW5vbi5zcHkodHNzRXRoV2FsbGV0LCAnc2lnbk1lc3NhZ2VUc3MnIGFzIGFueSk7XG4gICAgICAgICAgbm9jayhiZ1VybCkucG9zdChgL2FwaS92Mi93YWxsZXQvJHt0c3NFdGhXYWxsZXQuaWQoKX0vdHhyZXF1ZXN0c2ApLnJlcGx5KDIwMCwgdHhSZXF1ZXN0Rm9yTWVzc2FnZVNpZ25pbmcpO1xuXG4gICAgICAgICAgY29uc3Qgc2lnbk1lc3NhZ2UgPSBhd2FpdCB0c3NFdGhXYWxsZXQuc2lnbk1lc3NhZ2Uoe1xuICAgICAgICAgICAgcmVxSWQsXG4gICAgICAgICAgICBtZXNzYWdlOiB7IG1lc3NhZ2VSYXcgfSxcbiAgICAgICAgICAgIHBydjogJ3NlY3JldEtleScsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgc2lnbk1lc3NhZ2Uuc2hvdWxkLmRlZXBFcXVhbChleHBlY3RlZFdpdGhDb2luRmllbGQpO1xuICAgICAgICAgIGNvbnN0IGFjdHVhbEFyZyA9IHNpZ25NZXNzYWdlVHNzU3B5LmdldENhbGxzKClbMF0uYXJnc1swXSBhcyBXYWxsZXRTaWduTWVzc2FnZU9wdGlvbnM7XG4gICAgICAgICAgYWN0dWFsQXJnLm1lc3NhZ2U/Lm1lc3NhZ2VFbmNvZGVkPy5zaG91bGQuZXF1YWwoXG4gICAgICAgICAgICBCdWZmZXIuZnJvbShgXFx1MDAxOUV0aGVyZXVtIFNpZ25lZCBNZXNzYWdlOlxcbiR7bWVzc2FnZVJhdy5sZW5ndGh9JHttZXNzYWdlUmF3fWApLnRvU3RyaW5nKCdoZXgnKVxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgZmFpbCB0byBzaWduIG1lc3NhZ2Ugd2l0aCBlbXB0eSBwcnYnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYXdhaXQgdHNzRXRoV2FsbGV0XG4gICAgICAgICAgICAuc2lnbk1lc3NhZ2Uoe1xuICAgICAgICAgICAgICByZXFJZCxcbiAgICAgICAgICAgICAgbWVzc2FnZTogeyBtZXNzYWdlUmF3LCB0eFJlcXVlc3RJZCB9LFxuICAgICAgICAgICAgICBwcnY6ICcnLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdrZXljaGFpbiBkb2VzIG5vdCBoYXZlIHByb3BlcnR5IGVuY3J5cHRlZFBydicpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ1R5cGVkIERhdGEgU2lnbmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4SGFzaCA9XG4gICAgICAgICcxOTAxNDkzZmJmMmFlMWMyN2MzY2VkMjZhODkwNzBjNmFiNWQzZmJmMzdlZDc3OGRlOTM3OGU3NzAzYjdkMWYxMTZiMzg4MzA3N2E2MTgyNjEyOWI5OGI2MjJlNTRmYzY4YzUwMDhkMWIxYzE2NTUyZTFlZGE2OTE2Zjg3MGQ3MTkyMjAnO1xuICAgICAgY29uc3QgdHhSZXF1ZXN0Rm9yVHlwZWREYXRhU2lnbmluZzogVHhSZXF1ZXN0ID0ge1xuICAgICAgICB0eFJlcXVlc3RJZDogcmVxSWQudG9TdHJpbmcoKSxcbiAgICAgICAgdHJhbnNhY3Rpb25zOiBbXSxcbiAgICAgICAgaW50ZW50OiB7XG4gICAgICAgICAgaW50ZW50VHlwZTogJ3NpZ25NZXNzYWdlJyxcbiAgICAgICAgfSxcbiAgICAgICAgZGF0ZTogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICBsYXRlc3Q6IHRydWUsXG4gICAgICAgIHN0YXRlOiAncGVuZGluZ1VzZXJTaWduYXR1cmUnLFxuICAgICAgICB1c2VySWQ6ICd1c2VySWQnLFxuICAgICAgICB3YWxsZXRUeXBlOiAnaG90JyxcbiAgICAgICAgcG9saWNpZXNDaGVja2VkOiBmYWxzZSxcbiAgICAgICAgdmVyc2lvbjogMSxcbiAgICAgICAgd2FsbGV0SWQ6ICd3YWxsZXRJZCcsXG4gICAgICAgIHVuc2lnbmVkVHhzOiBbXSxcbiAgICAgICAgdW5zaWduZWRNZXNzYWdlczogW10sXG4gICAgICAgIG1lc3NhZ2VzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgc3RhdGU6ICdzaWduZWQnLFxuICAgICAgICAgICAgbWVzc2FnZVJhdzogJ2hlbGxvIHdvcmxkJyxcbiAgICAgICAgICAgIGRlcml2YXRpb25QYXRoOiAnbS8wJyxcbiAgICAgICAgICAgIHNpZ25hdHVyZVNoYXJlczogW3sgZnJvbTogU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsIHRvOiBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUiwgc2hhcmU6ICcnIH1dLFxuICAgICAgICAgICAgY29tYmluZVNpZ1NoYXJlOiAnMDpycnI6c3NzOjMnLFxuICAgICAgICAgICAgdHhIYXNoLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgICAgbGV0IHNpZ25UeFJlcXVlc3RGb3JNZXNzYWdlO1xuICAgICAgY29uc3QgbWVzc2FnZVNpZ25pbmdDb2lucyA9IFsndGV0aCcsICd0cG9seWdvbiddO1xuICAgICAgY29uc3QgdHlwZXM6IE1lc3NhZ2VUeXBlcyA9IHtcbiAgICAgICAgRUlQNzEyRG9tYWluOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbmFtZTogJ25hbWUnLFxuICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBuYW1lOiAndmVyc2lvbicsXG4gICAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICdjaGFpbklkJyxcbiAgICAgICAgICAgIHR5cGU6ICd1aW50MjU2JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICd2ZXJpZnlpbmdDb250cmFjdCcsXG4gICAgICAgICAgICB0eXBlOiAnYWRkcmVzcycsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgTWVzc2FnZTogW3sgbmFtZTogJ2RhdGEnLCB0eXBlOiAnc3RyaW5nJyB9XSxcbiAgICAgIH07XG4gICAgICBjb25zdCB0eXBlZE1lc3NhZ2U6IFR5cGVkTWVzc2FnZTxNZXNzYWdlVHlwZXM+ID0ge1xuICAgICAgICBkb21haW46IHtcbiAgICAgICAgICBuYW1lOiAnYml0Z28nLFxuICAgICAgICAgIHZlcnNpb246ICcxJyxcbiAgICAgICAgICBjaGFpbklkOiAxLFxuICAgICAgICAgIHZlcmlmeWluZ0NvbnRyYWN0OiAnMHgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAgICAgfSxcbiAgICAgICAgcHJpbWFyeVR5cGU6ICdNZXNzYWdlJyxcbiAgICAgICAgdHlwZXMsXG4gICAgICAgIG1lc3NhZ2U6IHsgZGF0YTogJ2JpdGdvIHNheXMgaGVsbG8hJyB9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHR5cGVkRGF0YUJhc2U6IFR5cGVkRGF0YSA9IHtcbiAgICAgICAgdHlwZWREYXRhUmF3OiBKU09OLnN0cmluZ2lmeSh0eXBlZE1lc3NhZ2UpLFxuICAgICAgICB2ZXJzaW9uOiBTaWduVHlwZWREYXRhVmVyc2lvbi5WMyxcbiAgICAgIH07XG5cbiAgICAgIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBzaWduVHhSZXF1ZXN0Rm9yTWVzc2FnZSA9IHNhbmRib3guc3R1YihFQ0RTQVV0aWxzLkVjZHNhVXRpbHMucHJvdG90eXBlLCAnc2lnblR4UmVxdWVzdEZvck1lc3NhZ2UnKTtcbiAgICAgICAgc2lnblR4UmVxdWVzdEZvck1lc3NhZ2UucmVzb2x2ZXModHhSZXF1ZXN0Rm9yVHlwZWREYXRhU2lnbmluZyk7XG4gICAgICAgIHNhbmRib3hcbiAgICAgICAgICAuc3R1YihLZXljaGFpbnMucHJvdG90eXBlLCAnZ2V0S2V5c0ZvclNpZ25pbmcnKVxuICAgICAgICAgIC5yZXNvbHZlcyhbeyBjb21tb25LZXljaGFpbjogJ3Rlc3QnLCBpZDogJycsIHB1YjogJycsIHR5cGU6ICdpbmRlcGVuZGVudCcgfV0pO1xuICAgICAgICBzaW5vbi5zdHViKEVjZHNhLnByb3RvdHlwZSwgJ3ZlcmlmeScpLnJlc29sdmVzKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGFmdGVyRWFjaChhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIHVuc3VwcG9ydGVkIGNvaW5zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCB0c3NTb2xXYWxsZXRcbiAgICAgICAgICAuc2lnblR5cGVkRGF0YSh7XG4gICAgICAgICAgICByZXFJZCxcbiAgICAgICAgICAgIHR5cGVkRGF0YTogdHlwZWREYXRhQmFzZSxcbiAgICAgICAgICAgIHBydjogJ3NlY3JldEtleScsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnU2lnbiB0eXBlZCBkYXRhIG5vdCBzdXBwb3J0ZWQgZm9yIFRlc3RuZXQgU29sYW5hJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3Igc2lnbiB0eXBlZCBkYXRhIFYxJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB0eXBlZERhdGEgPSB7IC4uLnR5cGVkRGF0YUJhc2UgfTtcbiAgICAgICAgdHlwZWREYXRhLnZlcnNpb24gPSBTaWduVHlwZWREYXRhVmVyc2lvbi5WMTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KFxuICAgICAgICAgICAgYC9hcGkvdjIvd2FsbGV0LyR7dHNzRXRoV2FsbGV0LmlkKCl9L3R4cmVxdWVzdHM/dHhSZXF1ZXN0SWRzPSR7XG4gICAgICAgICAgICAgIHR4UmVxdWVzdEZvclR5cGVkRGF0YVNpZ25pbmcudHhSZXF1ZXN0SWRcbiAgICAgICAgICAgIH0mbGF0ZXN0PXRydWVgXG4gICAgICAgICAgKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHsgdHhSZXF1ZXN0czogW3R4UmVxdWVzdEZvclR5cGVkRGF0YVNpZ25pbmddIH0pO1xuXG4gICAgICAgIGF3YWl0IHRzc0V0aFdhbGxldFxuICAgICAgICAgIC5zaWduVHlwZWREYXRhKHtcbiAgICAgICAgICAgIHJlcUlkLFxuICAgICAgICAgICAgdHlwZWREYXRhLFxuICAgICAgICAgICAgcHJ2OiAnc2VjcmV0S2V5JyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdTaWduVHlwZWREYXRhIHYxIGlzIG5vdCBzdXBwb3J0ZWQgZHVlIHRvIHNlY3VyaXR5IGNvbmNlcm5zJyk7XG4gICAgICB9KTtcbiAgICAgIG1lc3NhZ2VTaWduaW5nQ29pbnMubWFwKChjb2luTmFtZSkgPT4ge1xuICAgICAgICB0c3NFdGhXYWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiaXRnby5jb2luKGNvaW5OYW1lKSwgZXRoV2FsbGV0RGF0YSk7XG4gICAgICAgIGNvbnN0IHR4UmVxdWVzdElkID0gdHhSZXF1ZXN0Rm9yVHlwZWREYXRhU2lnbmluZy50eFJlcXVlc3RJZDtcbiAgICAgICAgdHlwZWREYXRhQmFzZS50eFJlcXVlc3RJZCA9IHR4UmVxdWVzdElkO1xuICAgICAgICBjb25zdCBleHBlY3RlZDogU2lnbmVkTWVzc2FnZSA9IHtcbiAgICAgICAgICB0eFJlcXVlc3RJZCxcbiAgICAgICAgICBtZXNzYWdlUmF3OiBKU09OLnN0cmluZ2lmeSh0eXBlZE1lc3NhZ2UpLFxuICAgICAgICAgIHNpZ25hdHVyZTogdHhIYXNoLFxuICAgICAgICAgIHR4SGFzaCxcbiAgICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgICAgbWVzc2FnZUVuY29kZWQ6IHR4SGFzaCxcbiAgICAgICAgfTtcblxuICAgICAgICBkZXNjcmliZShgc2lnbiB0eXBlZCBkYXRhIFYzIGZvciAke2NvaW5OYW1lfWAsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCB0eXBlZERhdGEgPSB7IC4uLnR5cGVkRGF0YUJhc2UgfTtcbiAgICAgICAgICB0eXBlZERhdGEudmVyc2lvbiA9IFNpZ25UeXBlZERhdGFWZXJzaW9uLlYzO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCBzaWduIHR5cGVkIGRhdGEgVjMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBzaWduVHlwZWREYXRhVHNzU3B5ID0gc2lub24uc3B5KHRzc0V0aFdhbGxldCwgJ3NpZ25UeXBlZERhdGFUc3MnIGFzIGFueSk7XG4gICAgICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgICAgICAuZ2V0KFxuICAgICAgICAgICAgICAgIGAvYXBpL3YyL3dhbGxldC8ke3Rzc0V0aFdhbGxldC5pZCgpfS90eHJlcXVlc3RzP3R4UmVxdWVzdElkcz0ke1xuICAgICAgICAgICAgICAgICAgdHhSZXF1ZXN0Rm9yVHlwZWREYXRhU2lnbmluZy50eFJlcXVlc3RJZFxuICAgICAgICAgICAgICAgIH0mbGF0ZXN0PXRydWVgXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgLnJlcGx5KDIwMCwgeyB0eFJlcXVlc3RzOiBbdHhSZXF1ZXN0Rm9yVHlwZWREYXRhU2lnbmluZ10gfSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHNpZ25lZFR5cGVkRGF0YSA9IGF3YWl0IHRzc0V0aFdhbGxldC5zaWduVHlwZWREYXRhKHtcbiAgICAgICAgICAgICAgcmVxSWQsXG4gICAgICAgICAgICAgIHR5cGVkRGF0YSxcbiAgICAgICAgICAgICAgcHJ2OiAnc2VjcmV0S2V5JyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc2lnbmVkVHlwZWREYXRhLnNob3VsZC5kZWVwRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgICAgICAgY29uc3QgYWN0dWFsQXJnID0gc2lnblR5cGVkRGF0YVRzc1NweS5nZXRDYWxscygpWzBdLmFyZ3NbMF0gYXMgV2FsbGV0U2lnblR5cGVkRGF0YU9wdGlvbnM7XG4gICAgICAgICAgICBhY3R1YWxBcmcudHlwZWREYXRhPy50eXBlZERhdGFFbmNvZGVkPy50b1N0cmluZygnaGV4Jykuc2hvdWxkLmVxdWFsKHR4SGFzaCk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdCgnc2hvdWxkIHNpZ24gdHlwZWQgZGF0YSBWMyB3aGVuIGN1c3RvZGlhbk1lc3NhZ2VJRCBpcyBwcm92aWRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHR5cGVkRGF0YS50eFJlcXVlc3RJZCA9IHR4UmVxdWVzdElkO1xuICAgICAgICAgICAgY29uc3Qgc2lnblR5cGVkRGF0YVRzc1NweSA9IHNpbm9uLnNweSh0c3NFdGhXYWxsZXQsICdzaWduVHlwZWREYXRhVHNzJyBhcyBhbnkpO1xuICAgICAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAgICAgLmdldChcbiAgICAgICAgICAgICAgICBgL2FwaS92Mi93YWxsZXQvJHt0c3NFdGhXYWxsZXQuaWQoKX0vdHhyZXF1ZXN0cz90eFJlcXVlc3RJZHM9JHtcbiAgICAgICAgICAgICAgICAgIHR4UmVxdWVzdEZvclR5cGVkRGF0YVNpZ25pbmcudHhSZXF1ZXN0SWRcbiAgICAgICAgICAgICAgICB9JmxhdGVzdD10cnVlYFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIC5yZXBseSgyMDAsIHsgdHhSZXF1ZXN0czogW3R4UmVxdWVzdEZvclR5cGVkRGF0YVNpZ25pbmddIH0pO1xuXG4gICAgICAgICAgICBjb25zdCBzaWduZWRUeXBlZERhdGEgPSBhd2FpdCB0c3NFdGhXYWxsZXQuc2lnblR5cGVkRGF0YSh7XG4gICAgICAgICAgICAgIGN1c3RvZGlhbk1lc3NhZ2VJZDogJ3VuaXR0ZXN0JyxcbiAgICAgICAgICAgICAgcmVxSWQsXG4gICAgICAgICAgICAgIHR5cGVkRGF0YSxcbiAgICAgICAgICAgICAgcHJ2OiAnc2VjcmV0S2V5JyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc2lnbmVkVHlwZWREYXRhLnNob3VsZC5kZWVwRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgICAgICAgY29uc3QgYWN0dWFsQXJnID0gc2lnblR5cGVkRGF0YVRzc1NweS5nZXRDYWxscygpWzBdLmFyZ3NbMF0gYXMgV2FsbGV0U2lnblR5cGVkRGF0YU9wdGlvbnM7XG4gICAgICAgICAgICBhY3R1YWxBcmcudHlwZWREYXRhPy50eXBlZERhdGFFbmNvZGVkPy50b1N0cmluZygnaGV4Jykuc2hvdWxkLmVxdWFsKHR4SGFzaCk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdCgnc2hvdWxkIGZhaWwgdG8gc2lnbiB0eXBlZCBkYXRhIFYzIHdpdGggZW1wdHkgcHJ2JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgYXdhaXQgdHNzRXRoV2FsbGV0XG4gICAgICAgICAgICAgIC5zaWduVHlwZWREYXRhKHtcbiAgICAgICAgICAgICAgICByZXFJZCxcbiAgICAgICAgICAgICAgICB0eXBlZERhdGE6IHR5cGVkRGF0YUJhc2UsXG4gICAgICAgICAgICAgICAgcHJ2OiAnJyxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2tleWNoYWluIGRvZXMgbm90IGhhdmUgcHJvcGVydHkgZW5jcnlwdGVkUHJ2Jyk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdCgnc2hvdWxkIHNpZ24gdHlwZWQgZGF0YSBWMyB3aGVuIHR4UmVxdWVzdElkIG5vdCBwcm92aWRlZCAnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBkZWxldGUgdHlwZWREYXRhLnR4UmVxdWVzdElkO1xuICAgICAgICAgICAgY29uc3Qgc2lnbmVkVHlwZWREYXRhVHNzU3B5ID0gc2lub24uc3B5KHRzc0V0aFdhbGxldCwgJ3NpZ25UeXBlZERhdGFUc3MnIGFzIGFueSk7XG4gICAgICAgICAgICBub2NrKGJnVXJsKS5wb3N0KGAvYXBpL3YyL3dhbGxldC8ke3Rzc0V0aFdhbGxldC5pZCgpfS90eHJlcXVlc3RzYCkucmVwbHkoMjAwLCB0eFJlcXVlc3RGb3JUeXBlZERhdGFTaWduaW5nKTtcblxuICAgICAgICAgICAgY29uc3Qgc2lnbmVkVHlwZWREYXRhID0gYXdhaXQgdHNzRXRoV2FsbGV0LnNpZ25UeXBlZERhdGEoe1xuICAgICAgICAgICAgICByZXFJZCxcbiAgICAgICAgICAgICAgdHlwZWREYXRhLFxuICAgICAgICAgICAgICBwcnY6ICdzZWNyZXRLZXknLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBzaWduZWRUeXBlZERhdGEuc2hvdWxkLmRlZXBFcXVhbChleHBlY3RlZCk7XG4gICAgICAgICAgICBjb25zdCBhY3R1YWxBcmcgPSBzaWduZWRUeXBlZERhdGFUc3NTcHkuZ2V0Q2FsbHMoKVswXS5hcmdzWzBdIGFzIFdhbGxldFNpZ25UeXBlZERhdGFPcHRpb25zO1xuICAgICAgICAgICAgYWN0dWFsQXJnLnR5cGVkRGF0YT8udHlwZWREYXRhRW5jb2RlZD8udG9TdHJpbmcoJ2hleCcpLnNob3VsZC5lcXVhbCh0eEhhc2gpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZShgc2lnbiB0eXBlZCBkYXRhIFY0IGZvciAke2NvaW5OYW1lfWAsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCB0eXBlZERhdGEgPSB7IC4uLnR5cGVkRGF0YUJhc2UgfTtcbiAgICAgICAgICB0eXBlZERhdGEudmVyc2lvbiA9IFNpZ25UeXBlZERhdGFWZXJzaW9uLlY0O1xuICAgICAgICAgIGl0KCdzaG91bGQgc2lnbiB0eXBlZCBkYXRhIFY0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdHlwZWREYXRhLnR4UmVxdWVzdElkID0gdHhSZXF1ZXN0SWQ7XG4gICAgICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgICAgICAuZ2V0KFxuICAgICAgICAgICAgICAgIGAvYXBpL3YyL3dhbGxldC8ke3Rzc0V0aFdhbGxldC5pZCgpfS90eHJlcXVlc3RzP3R4UmVxdWVzdElkcz0ke1xuICAgICAgICAgICAgICAgICAgdHhSZXF1ZXN0Rm9yVHlwZWREYXRhU2lnbmluZy50eFJlcXVlc3RJZFxuICAgICAgICAgICAgICAgIH0mbGF0ZXN0PXRydWVgXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgLnJlcGx5KDIwMCwgeyB0eFJlcXVlc3RzOiBbdHhSZXF1ZXN0Rm9yVHlwZWREYXRhU2lnbmluZ10gfSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHNpZ25lZFR5cGVkRGF0YSA9IGF3YWl0IHRzc0V0aFdhbGxldC5zaWduVHlwZWREYXRhKHtcbiAgICAgICAgICAgICAgcmVxSWQsXG4gICAgICAgICAgICAgIHR5cGVkRGF0YSxcbiAgICAgICAgICAgICAgcHJ2OiAnc2VjcmV0S2V5JyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc2lnbmVkVHlwZWREYXRhLnNob3VsZC5kZWVwRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCBzaWduIHR5cGVkIGRhdGEgVjQgd2hlbiBjdXN0b2RpYW5NZXNzYWdlSUQgaXMgcHJvdmlkZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0eXBlZERhdGEudHhSZXF1ZXN0SWQgPSB0eFJlcXVlc3RJZDtcbiAgICAgICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgICAgIC5nZXQoXG4gICAgICAgICAgICAgICAgYC9hcGkvdjIvd2FsbGV0LyR7dHNzRXRoV2FsbGV0LmlkKCl9L3R4cmVxdWVzdHM/dHhSZXF1ZXN0SWRzPSR7XG4gICAgICAgICAgICAgICAgICB0eFJlcXVlc3RGb3JUeXBlZERhdGFTaWduaW5nLnR4UmVxdWVzdElkXG4gICAgICAgICAgICAgICAgfSZsYXRlc3Q9dHJ1ZWBcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAucmVwbHkoMjAwLCB7IHR4UmVxdWVzdHM6IFt0eFJlcXVlc3RGb3JUeXBlZERhdGFTaWduaW5nXSB9KTtcblxuICAgICAgICAgICAgY29uc3Qgc2lnbmVkVHlwZWREYXRhID0gYXdhaXQgdHNzRXRoV2FsbGV0LnNpZ25UeXBlZERhdGEoe1xuICAgICAgICAgICAgICBjdXN0b2RpYW5NZXNzYWdlSWQ6ICd1bml0dGVzdCcsXG4gICAgICAgICAgICAgIHJlcUlkLFxuICAgICAgICAgICAgICB0eXBlZERhdGEsXG4gICAgICAgICAgICAgIHBydjogJ3NlY3JldEtleScsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHNpZ25lZFR5cGVkRGF0YS5zaG91bGQuZGVlcEVxdWFsKGV4cGVjdGVkKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGl0KCdzaG91bGQgZmFpbCB0byBzaWduIHR5cGVkIGRhdGEgVjQgd2l0aCBlbXB0eSBwcnYnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBhd2FpdCB0c3NFdGhXYWxsZXRcbiAgICAgICAgICAgICAgLnNpZ25UeXBlZERhdGEoe1xuICAgICAgICAgICAgICAgIHJlcUlkLFxuICAgICAgICAgICAgICAgIHR5cGVkRGF0YTogdHlwZWREYXRhQmFzZSxcbiAgICAgICAgICAgICAgICBwcnY6ICcnLFxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgna2V5Y2hhaW4gZG9lcyBub3QgaGF2ZSBwcm9wZXJ0eSBlbmNyeXB0ZWRQcnYnKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGl0KCdzaG91bGQgc2lnbiB0eXBlZCBkYXRhIFY0IHdoZW4gdHhSZXF1ZXN0SWQgbm90IHByb3ZpZGVkICcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0eXBlZERhdGEudHhSZXF1ZXN0SWQ7XG4gICAgICAgICAgICBjb25zdCBzaWduZWRUeXBlZERhdGFUc3NTcHkgPSBzaW5vbi5zcHkodHNzRXRoV2FsbGV0LCAnc2lnblR5cGVkRGF0YVRzcycgYXMgYW55KTtcbiAgICAgICAgICAgIG5vY2soYmdVcmwpLnBvc3QoYC9hcGkvdjIvd2FsbGV0LyR7dHNzRXRoV2FsbGV0LmlkKCl9L3R4cmVxdWVzdHNgKS5yZXBseSgyMDAsIHR4UmVxdWVzdEZvclR5cGVkRGF0YVNpZ25pbmcpO1xuXG4gICAgICAgICAgICBjb25zdCBzaWduZWRUeXBlZERhdGEgPSBhd2FpdCB0c3NFdGhXYWxsZXQuc2lnblR5cGVkRGF0YSh7XG4gICAgICAgICAgICAgIHJlcUlkLFxuICAgICAgICAgICAgICB0eXBlZERhdGEsXG4gICAgICAgICAgICAgIHBydjogJ3NlY3JldEtleScsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHNpZ25lZFR5cGVkRGF0YS5zaG91bGQuZGVlcEVxdWFsKGV4cGVjdGVkKTtcbiAgICAgICAgICAgIGNvbnN0IGFjdHVhbEFyZyA9IHNpZ25lZFR5cGVkRGF0YVRzc1NweS5nZXRDYWxscygpWzBdLmFyZ3NbMF0gYXMgV2FsbGV0U2lnblR5cGVkRGF0YU9wdGlvbnM7XG4gICAgICAgICAgICBhY3R1YWxBcmcudHlwZWREYXRhPy50eXBlZERhdGFFbmNvZGVkPy50b1N0cmluZygnaGV4Jykuc2hvdWxkLmVxdWFsKHR4SGFzaCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnU2VuZCBNYW55JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VuZE1hbnlJbnB1dCA9IHtcbiAgICAgICAgdHlwZTogJ3RyYW5zZmVyJyxcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICdhZGRyZXNzJyxcbiAgICAgICAgICAgIGFtb3VudDogJzEwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIHJlcUlkOiBuZXcgUmVxdWVzdFRyYWNlcigpLFxuICAgICAgfTtcblxuICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgc2VuZCBtYW55JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaWduZWRUcmFuc2FjdGlvbiA9IHtcbiAgICAgICAgICB0eFJlcXVlc3RJZDogJ3R4UmVxdWVzdElkJyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBwcmVidWlsZEFuZFNpZ25UcmFuc2FjdGlvbiA9IHNhbmRib3guc3R1Yih0c3NTb2xXYWxsZXQsICdwcmVidWlsZEFuZFNpZ25UcmFuc2FjdGlvbicpO1xuICAgICAgICBwcmVidWlsZEFuZFNpZ25UcmFuc2FjdGlvbi5yZXNvbHZlcyhzaWduZWRUcmFuc2FjdGlvbik7XG4gICAgICAgIC8vIFRPRE8oQkctNTk2ODYpOiB0aGlzIGlzIG5vdCBkb2luZyBhbnl0aGluZyBpZiB3ZSBkb24ndCBjaGVjayB0aGUgcmV0dXJuIHZhbHVlLCB3ZSBzaG91bGQgYWxzbyBtb3ZlIHRoaXMgY2hlY2sgdG8gaGFwcGVuIGFmdGVyIHdlIGludm9rZSBzZW5kTWFueVxuICAgICAgICBwcmVidWlsZEFuZFNpZ25UcmFuc2FjdGlvbi5jYWxsZWRPbmNlV2l0aEV4YWN0bHkoc2VuZE1hbnlJbnB1dCk7XG5cbiAgICAgICAgY29uc3Qgc2VuZFR4UmVxdWVzdCA9IHNhbmRib3guc3R1YihUc3NVdGlscy5wcm90b3R5cGUsICdzZW5kVHhSZXF1ZXN0Jyk7XG4gICAgICAgIHNlbmRUeFJlcXVlc3QucmVzb2x2ZXMoJ3NlbmRUeFJlc3BvbnNlJyk7XG4gICAgICAgIC8vIFRPRE8oQkctNTk2ODYpOiB0aGlzIGlzIG5vdCBkb2luZyBhbnl0aGluZyBpZiB3ZSBkb24ndCBjaGVjayB0aGUgcmV0dXJuIHZhbHVlLCB3ZSBzaG91bGQgYWxzbyBtb3ZlIHRoaXMgY2hlY2sgdG8gaGFwcGVuIGFmdGVyIHdlIGludm9rZSBzZW5kTWFueVxuICAgICAgICBzZW5kVHhSZXF1ZXN0LmNhbGxlZE9uY2VXaXRoRXhhY3RseShzaWduZWRUcmFuc2FjdGlvbi50eFJlcXVlc3RJZCk7XG5cbiAgICAgICAgY29uc3Qgc2VuZE1hbnkgPSBhd2FpdCB0c3NTb2xXYWxsZXQuc2VuZE1hbnkoc2VuZE1hbnlJbnB1dCk7XG4gICAgICAgIHNlbmRNYW55LnNob3VsZC5kZWVwRXF1YWwoJ3NlbmRUeFJlc3BvbnNlJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBzZW5kIG1hbnkgYW5kIGNhbGwgc2V0UmVxdWVzdFRyYWNlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2lnbmVkVHJhbnNhY3Rpb24gPSB7XG4gICAgICAgICAgdHhSZXF1ZXN0SWQ6ICd0eFJlcXVlc3RJZCcsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcHJlYnVpbGRBbmRTaWduVHJhbnNhY3Rpb24gPSBzYW5kYm94LnN0dWIodHNzU29sV2FsbGV0LCAncHJlYnVpbGRBbmRTaWduVHJhbnNhY3Rpb24nKTtcbiAgICAgICAgcHJlYnVpbGRBbmRTaWduVHJhbnNhY3Rpb24ucmVzb2x2ZXMoc2lnbmVkVHJhbnNhY3Rpb24pO1xuICAgICAgICBwcmVidWlsZEFuZFNpZ25UcmFuc2FjdGlvbi5jYWxsZWRPbmNlV2l0aEV4YWN0bHkoc2VuZE1hbnlJbnB1dCk7XG5cbiAgICAgICAgY29uc3Qgc2VuZFR4UmVxdWVzdCA9IHNhbmRib3guc3R1YihUc3NVdGlscy5wcm90b3R5cGUsICdzZW5kVHhSZXF1ZXN0Jyk7XG4gICAgICAgIHNlbmRUeFJlcXVlc3QucmVzb2x2ZXMoJ3NlbmRUeFJlc3BvbnNlJyk7XG4gICAgICAgIHNlbmRUeFJlcXVlc3QuY2FsbGVkT25jZVdpdGhFeGFjdGx5KHNpZ25lZFRyYW5zYWN0aW9uLnR4UmVxdWVzdElkKTtcblxuICAgICAgICBjb25zdCBzZXRSZXF1ZXN0VHJhY2VyU3B5ID0gc2lub24uc3B5KGJpdGdvLCAnc2V0UmVxdWVzdFRyYWNlcicpO1xuICAgICAgICBzZXRSZXF1ZXN0VHJhY2VyU3B5LndpdGhBcmdzKHNlbmRNYW55SW5wdXQucmVxSWQpO1xuXG4gICAgICAgIGNvbnN0IHNlbmRNYW55ID0gYXdhaXQgdHNzU29sV2FsbGV0LnNlbmRNYW55KHNlbmRNYW55SW5wdXQpO1xuICAgICAgICBzZW5kTWFueS5zaG91bGQuZGVlcEVxdWFsKCdzZW5kVHhSZXNwb25zZScpO1xuICAgICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShzZXRSZXF1ZXN0VHJhY2VyU3B5KTtcbiAgICAgICAgc2V0UmVxdWVzdFRyYWNlclNweS5yZXN0b3JlKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJhbnNmZXIgZnJvbSBzZW5kTWFueSBmb3IgYXBpVmVyc2lvbj1mdWxsJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCB0c29sLCB7XG4gICAgICAgICAgLi4ud2FsbGV0RGF0YSxcbiAgICAgICAgICB0eXBlOiAnY3VzdG9kaWFsJyxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHNpZ25lZFR4UmVzdWx0ID0ge1xuICAgICAgICAgIHR4UmVxdWVzdElkOiAndHhSZXF1ZXN0SWQnLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB0eFJlcXVlc3Q6IFR4UmVxdWVzdCA9IHtcbiAgICAgICAgICBkYXRlOiBuZXcgRGF0ZSgpLnRvU3RyaW5nKCksXG4gICAgICAgICAgaW50ZW50OiAncGF5bWVudCcsXG4gICAgICAgICAgbGF0ZXN0OiBmYWxzZSxcbiAgICAgICAgICBwb2xpY2llc0NoZWNrZWQ6IGZhbHNlLFxuICAgICAgICAgIHN0YXRlOiAnZGVsaXZlcmVkJyxcbiAgICAgICAgICB1bnNpZ25lZFR4czogW10sXG4gICAgICAgICAgdXNlcklkOiAndW5pdC10ZXN0JyxcbiAgICAgICAgICB2ZXJzaW9uOiAwLFxuICAgICAgICAgIHdhbGxldElkOiB3YWxsZXQuaWQoKSxcbiAgICAgICAgICB3YWxsZXRUeXBlOiB3YWxsZXQudHlwZSgpID8/ICdob3QnLFxuICAgICAgICAgIHR4UmVxdWVzdElkOiBzaWduZWRUeFJlc3VsdC50eFJlcXVlc3RJZCxcbiAgICAgICAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgc3RhdGU6ICdkZWxpdmVyZWQnLFxuICAgICAgICAgICAgICBzaWduZWRUeDoge1xuICAgICAgICAgICAgICAgIGlkOiAndHhpZCcsXG4gICAgICAgICAgICAgICAgdHg6ICd0eCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHVuc2lnbmVkVHg6ICdzb21ldGhpbmcnIGFzIGFueSxcbiAgICAgICAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgdHJhbnNmZXIgPSB7XG4gICAgICAgICAgaWQ6ICd0cmFuc2ZlcklkJyxcbiAgICAgICAgICBzdGF0ZTogJ3NpZ25lZCcsXG4gICAgICAgICAgdHhpZDogJ3R4aWQnLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHByZWJ1aWxkQW5kU2lnblRyYW5zYWN0aW9uID0gc2FuZGJveC5zdHViKHdhbGxldCwgJ3ByZWJ1aWxkQW5kU2lnblRyYW5zYWN0aW9uJykucmVzb2x2ZXMoc2lnbmVkVHhSZXN1bHQpO1xuXG4gICAgICAgIGNvbnN0IHR4UmVxdWVzdE5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wZXJzaXN0KClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL3dhbGxldC8ke3dhbGxldERhdGEuaWR9L3R4cmVxdWVzdHM/dHhSZXF1ZXN0SWRzPSR7c2lnbmVkVHhSZXN1bHQudHhSZXF1ZXN0SWR9JmxhdGVzdD10cnVlYClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IHR4UmVxdWVzdHM6IFt0eFJlcXVlc3RdIH0pO1xuXG4gICAgICAgIGNvbnN0IGNyZWF0ZVRyYW5zZmVyTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBlcnNpc3QoKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyL3dhbGxldC8ke3dhbGxldERhdGEuaWR9L3R4cmVxdWVzdHMvJHtzaWduZWRUeFJlc3VsdC50eFJlcXVlc3RJZH0vdHJhbnNmZXJzYClcbiAgICAgICAgICAucmVwbHkoMjAwLCB0cmFuc2Zlcik7XG5cbiAgICAgICAgY29uc3QgaW5wdXQ6IFNlbmRNYW55T3B0aW9ucyA9IHtcbiAgICAgICAgICB0eXBlOiAndHJhbnNmZXInLFxuICAgICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYWRkcmVzczogJ2FkZHJlc3MnLFxuICAgICAgICAgICAgICBhbW91bnQ6ICcxMDAwJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBhcGlWZXJzaW9uOiAnZnVsbCcsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHNlbmRNYW55UmVzdWx0ID0gYXdhaXQgd2FsbGV0LnNlbmRNYW55KGlucHV0KTtcbiAgICAgICAgcHJlYnVpbGRBbmRTaWduVHJhbnNhY3Rpb24uY2FsbGVkT25jZVdpdGhFeGFjdGx5KGlucHV0KTtcbiAgICAgICAgdHhSZXF1ZXN0Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICBjcmVhdGVUcmFuc2Zlck5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgICBzZW5kTWFueVJlc3VsdC5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgICB0eFJlcXVlc3QsXG4gICAgICAgICAgdHJhbnNmZXIsXG4gICAgICAgICAgdHhpZDogJ3R4aWQnLFxuICAgICAgICAgIHR4OiAndHgnLFxuICAgICAgICAgIHN0YXR1czogJ3NpZ25lZCcsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIHBlbmRpbmdBcHByb3ZhbCBmcm9tIHNlbmRNYW55IGZvciBhcGlWZXJzaW9uPWZ1bGwnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIHRzb2wsIHtcbiAgICAgICAgICAuLi53YWxsZXREYXRhLFxuICAgICAgICAgIHR5cGU6ICdob3QnLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgc2lnbmVkVHhSZXN1bHQgPSB7XG4gICAgICAgICAgdHhSZXF1ZXN0SWQ6ICd0eFJlcXVlc3RJZCcsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHR4UmVxdWVzdDogVHhSZXF1ZXN0ID0ge1xuICAgICAgICAgIHR4UmVxdWVzdElkOiBzaWduZWRUeFJlc3VsdC50eFJlcXVlc3RJZCxcbiAgICAgICAgICBkYXRlOiBuZXcgRGF0ZSgpLnRvU3RyaW5nKCksXG4gICAgICAgICAgaW50ZW50OiAncGF5bWVudCcsXG4gICAgICAgICAgbGF0ZXN0OiBmYWxzZSxcbiAgICAgICAgICBwb2xpY2llc0NoZWNrZWQ6IGZhbHNlLFxuICAgICAgICAgIHN0YXRlOiAncGVuZGluZ0FwcHJvdmFsJyxcbiAgICAgICAgICB1bnNpZ25lZFR4czogW10sXG4gICAgICAgICAgdXNlcklkOiAndW5pdC10ZXN0JyxcbiAgICAgICAgICB2ZXJzaW9uOiAwLFxuICAgICAgICAgIHdhbGxldElkOiB3YWxsZXQuaWQoKSxcbiAgICAgICAgICB3YWxsZXRUeXBlOiB3YWxsZXQudHlwZSgpID8/ICdob3QnLFxuICAgICAgICAgIHBlbmRpbmdBcHByb3ZhbElkOiAnc29tZS1wZW5kaW5nLWFwcHJvdmFsLWlkJyxcbiAgICAgICAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgc3RhdGU6ICdpbml0aWFsaXplZCcsXG4gICAgICAgICAgICAgIHVuc2lnbmVkVHg6ICdzb21ldGhpbmcnIGFzIGFueSxcbiAgICAgICAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgdHJhbnNmZXIgPSB7XG4gICAgICAgICAgaWQ6ICd0cmFuc2ZlcklkJyxcbiAgICAgICAgICBzdGF0ZTogJ3NpZ25lZCcsXG4gICAgICAgICAgdHhpZDogJ3R4aWQnLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBwZW5kaW5nQXBwcm92YWwgPSB7XG4gICAgICAgICAgaWQ6ICdzb21lLXBlbmRpbmctYXBwcm92YWwtaWQnLFxuICAgICAgICAgIHdhbGxldDogd2FsbGV0LmlkKCksXG4gICAgICAgICAgaW5mbzoge1xuICAgICAgICAgICAgdHlwZTogJ3RyYW5zYWN0aW9uUmVxdWVzdEZ1bGwnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdHhSZXF1ZXN0SWQ6IHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBwcmVidWlsZEFuZFNpZ25UcmFuc2FjdGlvbiA9IHNhbmRib3guc3R1Yih3YWxsZXQsICdwcmVidWlsZEFuZFNpZ25UcmFuc2FjdGlvbicpLnJlc29sdmVzKHNpZ25lZFR4UmVzdWx0KTtcblxuICAgICAgICBjb25zdCB0eFJlcXVlc3ROb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAucGVyc2lzdCgpXG4gICAgICAgICAgLmdldChgL2FwaS92Mi93YWxsZXQvJHt3YWxsZXREYXRhLmlkfS90eHJlcXVlc3RzP3R4UmVxdWVzdElkcz0ke3R4UmVxdWVzdC50eFJlcXVlc3RJZH0mbGF0ZXN0PXRydWVgKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHsgdHhSZXF1ZXN0czogW3R4UmVxdWVzdF0gfSk7XG5cbiAgICAgICAgY29uc3QgY3JlYXRlVHJhbnNmZXJOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAucGVyc2lzdCgpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvd2FsbGV0LyR7d2FsbGV0RGF0YS5pZH0vdHhyZXF1ZXN0cy8ke3R4UmVxdWVzdC50eFJlcXVlc3RJZH0vdHJhbnNmZXJzYClcbiAgICAgICAgICAucmVwbHkoMjAwLCB0cmFuc2Zlcik7XG5cbiAgICAgICAgY29uc3QgZ2V0UGVuZGluZ0FwcHJvdmFsTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBlcnNpc3QoKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS9wZW5kaW5nYXBwcm92YWxzLyR7dHhSZXF1ZXN0LnBlbmRpbmdBcHByb3ZhbElkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwgcGVuZGluZ0FwcHJvdmFsKTtcblxuICAgICAgICBjb25zdCBpbnB1dDogU2VuZE1hbnlPcHRpb25zID0ge1xuICAgICAgICAgIHR5cGU6ICd0cmFuc2ZlcicsXG4gICAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhZGRyZXNzOiAnYWRkcmVzcycsXG4gICAgICAgICAgICAgIGFtb3VudDogJzEwMDAnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGFwaVZlcnNpb246ICdmdWxsJyxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgc2VuZE1hbnlSZXN1bHQgPSBhd2FpdCB3YWxsZXQuc2VuZE1hbnkoaW5wdXQpO1xuICAgICAgICBwcmVidWlsZEFuZFNpZ25UcmFuc2FjdGlvbi5jYWxsZWRPbmNlV2l0aEV4YWN0bHkoaW5wdXQpO1xuICAgICAgICB0eFJlcXVlc3ROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIGNyZWF0ZVRyYW5zZmVyTm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICBnZXRQZW5kaW5nQXBwcm92YWxOb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgICAgc2VuZE1hbnlSZXN1bHQuc2hvdWxkLmRlZXBFcXVhbCh7IHBlbmRpbmdBcHByb3ZhbCwgdHhSZXF1ZXN0IH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZmFpbCBpZiB0eFJlcXVlc3RJZCBpcyBtaXNzaW5nIGZyb20gcHJlYnVpbGQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNpZ25lZFRyYW5zYWN0aW9uID0ge1xuICAgICAgICAgIHR4SGV4OiAnZGVhZGJlZWYnLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHByZWJ1aWxkQW5kU2lnblRyYW5zYWN0aW9uID0gc2FuZGJveC5zdHViKHRzc1NvbFdhbGxldCwgJ3ByZWJ1aWxkQW5kU2lnblRyYW5zYWN0aW9uJyk7XG4gICAgICAgIHByZWJ1aWxkQW5kU2lnblRyYW5zYWN0aW9uLnJlc29sdmVzKHNpZ25lZFRyYW5zYWN0aW9uKTtcbiAgICAgICAgLy8gVE9ETyhCRy01OTY4Nik6IHRoaXMgaXMgbm90IGRvaW5nIGFueXRoaW5nIGlmIHdlIGRvbid0IGNoZWNrIHRoZSByZXR1cm4gdmFsdWUsIHdlIHNob3VsZCBhbHNvIG1vdmUgdGhpcyBjaGVjayB0byBoYXBwZW4gYWZ0ZXIgd2UgaW52b2tlIHNlbmRNYW55XG4gICAgICAgIHByZWJ1aWxkQW5kU2lnblRyYW5zYWN0aW9uLmNhbGxlZE9uY2VXaXRoRXhhY3RseShzZW5kTWFueUlucHV0KTtcblxuICAgICAgICBhd2FpdCB0c3NTb2xXYWxsZXRcbiAgICAgICAgICAuc2VuZE1hbnkoc2VuZE1hbnlJbnB1dClcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgndHhSZXF1ZXN0SWQgbWlzc2luZyBmcm9tIHNpZ25lZCB0cmFuc2FjdGlvbicpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnU3VibWl0IHRyYW5zYWN0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCBzdWJtaXQgdHJhbnNhY3Rpb24gd2l0aCB0eFJlcXVlc3RJZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgbm9ja1NlbmRUeCA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBlcnNpc3QoZmFsc2UpXG4gICAgICAgICAgLnBvc3QodHNzU29sV2FsbGV0LnVybCgnL3R4L3NlbmQnKS5yZXBsYWNlKGJnVXJsLCAnJykpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgeyBtZXNzYWdlOiAnc3VjY2VzcycgfSk7XG5cbiAgICAgICAgY29uc3Qgc3VibWl0dGVkVHggPSBhd2FpdCB0c3NTb2xXYWxsZXQuc3VibWl0VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UmVxdWVzdElkOiAnaWQnLFxuICAgICAgICB9KTtcbiAgICAgICAgc3VibWl0dGVkVHguc2hvdWxkLmRlZXBFcXVhbCh7IG1lc3NhZ2U6ICdzdWNjZXNzJyB9KTtcbiAgICAgICAgbm9ja1NlbmRUeC5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZmFpbCB3aGVuIHR4UmVxdWVzdElkIGFuZCB0eEhleCBhcmUgYm90aCBwcm92aWRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgdHNzU29sV2FsbGV0XG4gICAgICAgICAgLnN1Ym1pdFRyYW5zYWN0aW9uKHtcbiAgICAgICAgICAgIHR4UmVxdWVzdElkOiAnaWQnLFxuICAgICAgICAgICAgdHhIZXg6ICdiZWVmJyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtdXN0IHN1cHBseSBleGFjdGx5IG9uZSBvZiB0eFJlcXVlc3RJZCwgdHhIZXgsIG9yIGhhbGZTaWduZWQnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgd2hlbiB0eFJlcXVlc3RJZCBhbmQgaGFsZlNpZ25lZCBhcmUgYm90aCBwcm92aWRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgdHNzU29sV2FsbGV0XG4gICAgICAgICAgLnN1Ym1pdFRyYW5zYWN0aW9uKHtcbiAgICAgICAgICAgIHR4UmVxdWVzdElkOiAnaWQnLFxuICAgICAgICAgICAgaGFsZlNpZ25lZDoge1xuICAgICAgICAgICAgICB0eEhleDogJ2JlZWYnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtdXN0IHN1cHBseSBleGFjdGx5IG9uZSBvZiB0eFJlcXVlc3RJZCwgdHhIZXgsIG9yIGhhbGZTaWduZWQnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgd2hlbiB0eEhleCBhbmQgaGFsZlNpZ25lZCBhcmUgYm90aCBwcm92aWRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgdHNzU29sV2FsbGV0XG4gICAgICAgICAgLnN1Ym1pdFRyYW5zYWN0aW9uKHtcbiAgICAgICAgICAgIHR4SGV4OiAnYmVlZicsXG4gICAgICAgICAgICBoYWxmU2lnbmVkOiB7XG4gICAgICAgICAgICAgIHR4SGV4OiAnYmVlZicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ211c3Qgc3VwcGx5IGVpdGhlciB0eEhleCBvciBoYWxmU2lnbmVkLCBidXQgbm90IGJvdGgnKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ1RyYW5zZmVyIHRva2VucycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlY2lwaWVudHMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHgxMDFjMzkyODk0NmIyZTFkOTk3NTllOGU1ZDM0YjVlOTRjMWE4ZTJmJyxcbiAgICAgICAgICBhbW91bnQ6ICcwJyxcbiAgICAgICAgICB0b2tlbkRhdGE6IHtcbiAgICAgICAgICAgIHRva2VuTmFtZTogJ2VyYzcyMTpiaXRnb2VyYzcyMScsXG4gICAgICAgICAgICB0b2tlbkNvbnRyYWN0QWRkcmVzczogJzB4ODM5N2IwOTE1MTRjMWY3YmViYjlkZWE2YWMyNjdlYTIzYjU3MDYwNScsXG4gICAgICAgICAgICB0b2tlbklkOiAnMzgnLFxuICAgICAgICAgICAgdG9rZW5RdWFudGl0eTogJzEnLFxuICAgICAgICAgICAgZGVjaW1hbFBsYWNlczogMCxcbiAgICAgICAgICAgIHRva2VuVHlwZTogVG9rZW5UeXBlLkVSQzcyMSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgXTtcblxuICAgICAgY29uc3QgZmVlT3B0aW9ucyA9IHtcbiAgICAgICAgbWF4RmVlUGVyR2FzOiAyMDAwMDAwMDAwLFxuICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMCxcbiAgICAgIH07XG5cbiAgICAgIGl0KCdjYWxsaW5nIHByZWJ1aWxkeFRyYW5zYWN0aW9uIHNob3VsZCBleGVjdXRlIHByZWJ1aWxkVHhXaXRoSW50ZW50IHdpdGggcHJvcGVyIHBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdHhSZXF1ZXN0RnVsbFRva2VuVHJhbnNmZXIgPSB7IC4uLnR4UmVxdWVzdEZ1bGwsIGludGVudDogJ3RyYW5zZmVyVG9rZW4nIH07XG4gICAgICAgIGNvbnN0IHByZWJ1aWxkVHhXaXRoSW50ZW50ID0gc2FuZGJveC5zdHViKEVDRFNBVXRpbHMuRWNkc2FVdGlscy5wcm90b3R5cGUsICdwcmVidWlsZFR4V2l0aEludGVudCcpO1xuICAgICAgICBwcmVidWlsZFR4V2l0aEludGVudC5yZXNvbHZlcyh0eFJlcXVlc3RGdWxsVG9rZW5UcmFuc2Zlcik7XG4gICAgICAgIC8vIFRPRE8oQkctNTk2ODYpOiB0aGlzIGlzIG5vdCBkb2luZyBhbnl0aGluZyBpZiB3ZSBkb24ndCBjaGVjayB0aGUgcmV0dXJuIHZhbHVlLCB3ZSBzaG91bGQgYWxzbyBtb3ZlIHRoaXMgY2hlY2sgdG8gaGFwcGVuIGFmdGVyIHdlIGludm9rZSBwcmVidWlsZFRyYW5zYWN0aW9uXG4gICAgICAgIHByZWJ1aWxkVHhXaXRoSW50ZW50LmNhbGxlZE9uY2VXaXRoRXhhY3RseShcbiAgICAgICAgICB7XG4gICAgICAgICAgICByZXFJZCxcbiAgICAgICAgICAgIHJlY2lwaWVudHMsXG4gICAgICAgICAgICBpbnRlbnRUeXBlOiAndHJhbnNmZXJUb2tlbicsXG4gICAgICAgICAgICBmZWVPcHRpb25zLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgJ2Z1bGwnXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgdHhQcmVidWlsZCA9IGF3YWl0IHRzc1BvbHlnb25XYWxsZXQucHJlYnVpbGRUcmFuc2FjdGlvbih7XG4gICAgICAgICAgaXNUc3M6IHRydWUsXG4gICAgICAgICAgcmVjaXBpZW50cyxcbiAgICAgICAgICB0eXBlOiAndHJhbnNmZXJ0b2tlbicsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ3Bhc3NwaHJhc2UxMjM0NScsXG4gICAgICAgICAgZmVlT3B0aW9ucyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdHhQcmVidWlsZC5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgICB3YWxsZXRJZDogdHNzUG9seWdvbldhbGxldC5pZCgpLFxuICAgICAgICAgIHdhbGxldDogdHNzUG9seWdvbldhbGxldCxcbiAgICAgICAgICB0eFJlcXVlc3RJZDogJ2lkJyxcbiAgICAgICAgICB0eEhleDogJ2FiYWJjZGNkJyxcbiAgICAgICAgICBidWlsZFBhcmFtczoge1xuICAgICAgICAgICAgcmVjaXBpZW50cyxcbiAgICAgICAgICAgIHR5cGU6ICd0cmFuc2ZlcnRva2VuJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICAgIGZlZTogNTAwMCxcbiAgICAgICAgICAgIGZlZVN0cmluZzogJzUwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcG9wdWxhdGUgaW50ZW50IHdpdGggRVZNLWxpa2UgcGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBtcGNVdGlscyA9IG5ldyBFQ0RTQVV0aWxzLkVjZHNhVXRpbHMoYml0Z28sIGJpdGdvLmNvaW4oJ3Rwb2x5Z29uJykpO1xuICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIG9ubHkgcGFzcyBpbiBwYXJhbXMgYmVpbmcgdGVzdGVkXG4gICAgICAgIGNvbnN0IGludGVudCA9IG1wY1V0aWxzLnBvcHVsYXRlSW50ZW50KGJpdGdvLmNvaW4oJ3Rwb2x5Z29uJyksIHtcbiAgICAgICAgICBpbnRlbnRUeXBlOiAndHJhbnNmZXJUb2tlbicsXG4gICAgICAgICAgcmVjaXBpZW50cyxcbiAgICAgICAgICBmZWVPcHRpb25zLFxuICAgICAgICB9KTtcbiAgICAgICAgaW50ZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdmZWVPcHRpb25zJyk7XG4gICAgICAgIGludGVudC5mZWVPcHRpb25zIS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnbWF4RmVlUGVyR2FzJywgMjAwMDAwMDAwMCk7XG4gICAgICAgIGludGVudC5mZWVPcHRpb25zIS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnbWF4UHJpb3JpdHlGZWVQZXJHYXMnLCAxMDAwMDAwMDAwKTtcbiAgICAgICAgaW50ZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNpcGllbnRzJyk7XG4gICAgICAgIGludGVudC5yZWNpcGllbnRzIS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnbGVuZ3RoJywgMSk7XG4gICAgICAgIGludGVudC5yZWNpcGllbnRzIVswXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndG9rZW5EYXRhJyk7XG4gICAgICAgIGludGVudC5yZWNpcGllbnRzIVswXS50b2tlbkRhdGEhLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0b2tlblF1YW50aXR5JywgcmVjaXBpZW50c1swXS50b2tlbkRhdGEudG9rZW5RdWFudGl0eSk7XG4gICAgICAgIGludGVudC5yZWNpcGllbnRzIVswXS50b2tlbkRhdGEhLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0b2tlblR5cGUnLCByZWNpcGllbnRzWzBdLnRva2VuRGF0YS50b2tlblR5cGUpO1xuICAgICAgICBpbnRlbnQucmVjaXBpZW50cyFbMF0udG9rZW5EYXRhIS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndG9rZW5OYW1lJywgcmVjaXBpZW50c1swXS50b2tlbkRhdGEudG9rZW5OYW1lKTtcbiAgICAgICAgaW50ZW50LnJlY2lwaWVudHMhWzBdLnRva2VuRGF0YSEuc2hvdWxkLmhhdmUucHJvcGVydHkoXG4gICAgICAgICAgJ3Rva2VuQ29udHJhY3RBZGRyZXNzJyxcbiAgICAgICAgICByZWNpcGllbnRzWzBdLnRva2VuRGF0YS50b2tlbkNvbnRyYWN0QWRkcmVzc1xuICAgICAgICApO1xuICAgICAgICBpbnRlbnQucmVjaXBpZW50cyFbMF0udG9rZW5EYXRhIS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndG9rZW5JZCcsIHJlY2lwaWVudHNbMF0udG9rZW5EYXRhLnRva2VuSWQpO1xuICAgICAgICBpbnRlbnQucmVjaXBpZW50cyFbMF0udG9rZW5EYXRhIS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZGVjaW1hbFBsYWNlcycsIHJlY2lwaWVudHNbMF0udG9rZW5EYXRhLmRlY2ltYWxQbGFjZXMpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcG9wdWxhdGUgaW50ZW50IHdpdGggY2FsbGRhdGEnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHJlY2lwaWVudHMgPSBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzB4MTAxYzM5Mjg5NDZiMmUxZDk5NzU5ZThlNWQzNGI1ZTk0YzFhOGUyZicsXG4gICAgICAgICAgICBhbW91bnQ6ICcwJyxcbiAgICAgICAgICAgIGRhdGE6ICcweDAwMDAxMTExMjIyMicsXG4gICAgICAgICAgfSxcbiAgICAgICAgXTtcblxuICAgICAgICBjb25zdCBtcGNVdGlscyA9IG5ldyBFQ0RTQVV0aWxzLkVjZHNhVXRpbHMoYml0Z28sIGJpdGdvLmNvaW4oJ2h0ZXRoJykpO1xuICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIG9ubHkgcGFzcyBpbiBwYXJhbXMgYmVpbmcgdGVzdGVkXG4gICAgICAgIGNvbnN0IGludGVudCA9IG1wY1V0aWxzLnBvcHVsYXRlSW50ZW50KGJpdGdvLmNvaW4oJ2h0ZXRoJyksIHtcbiAgICAgICAgICBpbnRlbnRUeXBlOiAncGF5bWVudCcsXG4gICAgICAgICAgcmVjaXBpZW50cyxcbiAgICAgICAgICBmZWVPcHRpb25zLFxuICAgICAgICB9KTtcblxuICAgICAgICBpbnRlbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2ZlZU9wdGlvbnMnKTtcbiAgICAgICAgaW50ZW50LmZlZU9wdGlvbnMhLnNob3VsZC5oYXZlLnByb3BlcnR5KCdtYXhGZWVQZXJHYXMnLCAyMDAwMDAwMDAwKTtcbiAgICAgICAgaW50ZW50LmZlZU9wdGlvbnMhLnNob3VsZC5oYXZlLnByb3BlcnR5KCdtYXhQcmlvcml0eUZlZVBlckdhcycsIDEwMDAwMDAwMDApO1xuICAgICAgICBpbnRlbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY2lwaWVudHMnKTtcbiAgICAgICAgaW50ZW50LnJlY2lwaWVudHMhLnNob3VsZC5oYXZlLnByb3BlcnR5KCdsZW5ndGgnLCAxKTtcbiAgICAgICAgaW50ZW50LnJlY2lwaWVudHMhWzBdLmRhdGEhLnNob3VsZC5lcXVhbCgnMHgwMDAwMTExMTIyMjInKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIG5vdCBwb3B1bGF0ZSBpbnRlbnQgd2l0aCB0b2tlbkRhdGEgaWYgY2VydGFpbiBwYXJhbXMgYXJlIHVuZGVmaW5lZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgbXBjVXRpbHMgPSBuZXcgRUNEU0FVdGlscy5FY2RzYVV0aWxzKGJpdGdvLCBiaXRnby5jb2luKCd0cG9seWdvbicpKTtcbiAgICAgICAgY29uc3QgcmVjaXBpZW50cyA9IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnMHgxMDFjMzkyODk0NmIyZTFkOTk3NTllOGU1ZDM0YjVlOTRjMWE4ZTJmJyxcbiAgICAgICAgICAgIGFtb3VudDogJzAnLFxuICAgICAgICAgICAgdG9rZW5EYXRhOiB7XG4gICAgICAgICAgICAgIHRva2VuTmFtZTogJ2VyYzcyMTpiaXRnb2VyYzcyMScsXG4gICAgICAgICAgICAgIHRva2VuQ29udHJhY3RBZGRyZXNzOiAnMHg4Mzk3YjA5MTUxNGMxZjdiZWJiOWRlYTZhYzI2N2VhMjNiNTcwNjA1JyxcbiAgICAgICAgICAgICAgdG9rZW5JZDogJzM4JyxcbiAgICAgICAgICAgICAgdG9rZW5RdWFudGl0eTogJzEnLFxuICAgICAgICAgICAgICBkZWNpbWFsUGxhY2VzOiAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICBdO1xuICAgICAgICBsZXQgaW50ZW50O1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGludGVudCA9IG1wY1V0aWxzLnBvcHVsYXRlSW50ZW50KGJpdGdvLmNvaW4oJ3Rwb2x5Z29uJyksIHtcbiAgICAgICAgICAgIGludGVudFR5cGU6ICd0cmFuc2ZlclRva2VuJyxcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3Igb25seSBwYXNzIGluIHBhcmFtcyBiZSB0ZXN0ZWQgZm9yXG4gICAgICAgICAgICByZWNpcGllbnRzLFxuICAgICAgICAgICAgZmVlT3B0aW9ucyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBpbnRlbnQuc2hvdWxkLmVxdWFsKHVuZGVmaW5lZCk7XG4gICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAgIGUubWVzc2FnZS5zaG91bGQuZXF1YWwoXG4gICAgICAgICAgICAndG9rZW4gdHlwZSBhbmQgcXVhbnRpdHkgaXMgcmVxdWlyZWQgdG8gcmVxdWVzdCBhIHRyYW5zYWN0aW9uIHdpdGggaW50ZW50IHRvIHRyYW5zZmVyIGEgdG9rZW4nXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnVHJhbnNmZXIgTkZUcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgcG9wdWxhdGUgaW50ZW50IHdpdGggTkZUIHRva2VuIGRldGFpbHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBhcmFtczogUHJlYnVpbGRUcmFuc2FjdGlvbldpdGhJbnRlbnRPcHRpb25zID0ge1xuICAgICAgICAgIHJlcUlkLFxuICAgICAgICAgIGludGVudFR5cGU6ICdwYXltZW50JyxcbiAgICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFkZHJlc3M6ICcweDlmZWY3NDkwNTA2NDQ2MjUwMTJhMmM4NjY5NzM3NzVlNzEyMzc1M2IzZWVmMGExYTQwMzc0NTNhYzI2ZDc5YmYnLFxuICAgICAgICAgICAgICBhbW91bnQ6ICcxJyxcbiAgICAgICAgICAgICAgdG9rZW5EYXRhOiB7XG4gICAgICAgICAgICAgICAgdG9rZW5UeXBlOiBUb2tlblR5cGUuRElHSVRBTF9BU1NFVCxcbiAgICAgICAgICAgICAgICB0b2tlblF1YW50aXR5OiAnMScsXG4gICAgICAgICAgICAgICAgdG9rZW5Db250cmFjdEFkZHJlc3M6ICcweGJiYzU2MWZiZmE1ZDEwNWVmZDhkZmIwNmFlM2U3ZTViZTQ2MzMxMTY1Yjk5ZDUxOGYwOTRjNzAxZTQwNjAzYjUnLFxuICAgICAgICAgICAgICAgIHRva2VuSWQ6ICcweDY3NWIwNTNkNzJjMjRkY2M2YmM3ZjM4Y2RkNDViNDg0M2NmYjdhZjY5YTI1YWQyMWQwMDJjMzc2MzU3ZTlkNjknLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGJhc2VDb2luID0gYml0Z28uY29pbigndGFwdCcpO1xuICAgICAgICBjb25zdCBtcGNVdGlscyA9IG5ldyBFRERTQVV0aWxzLmRlZmF1bHQoYml0Z28sIGJhc2VDb2luKTtcbiAgICAgICAgY29uc3QgaW50ZW50ID0gbXBjVXRpbHMucG9wdWxhdGVJbnRlbnQoYmFzZUNvaW4sIHBhcmFtcyk7XG5cbiAgICAgICAgaW50ZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdpbnRlbnRUeXBlJywgJ3BheW1lbnQnKTtcbiAgICAgICAgaW50ZW50LnJlY2lwaWVudHMhLnNob3VsZC5kZWVwRXF1YWwoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6IHtcbiAgICAgICAgICAgICAgYWRkcmVzczogJzB4OWZlZjc0OTA1MDY0NDYyNTAxMmEyYzg2Njk3Mzc3NWU3MTIzNzUzYjNlZWYwYTFhNDAzNzQ1M2FjMjZkNzliZicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYW1vdW50OiB7XG4gICAgICAgICAgICAgIHZhbHVlOiAnMScsXG4gICAgICAgICAgICAgIHN5bWJvbDogJ3RhcHQ6bmZ0Y29sbGVjdGlvbjEnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRva2VuRGF0YToge1xuICAgICAgICAgICAgICB0b2tlblR5cGU6ICdEaWdpdGFsIEFzc2V0JyxcbiAgICAgICAgICAgICAgdG9rZW5RdWFudGl0eTogJzEnLFxuICAgICAgICAgICAgICB0b2tlbkNvbnRyYWN0QWRkcmVzczogJzB4YmJjNTYxZmJmYTVkMTA1ZWZkOGRmYjA2YWUzZTdlNWJlNDYzMzExNjViOTlkNTE4ZjA5NGM3MDFlNDA2MDNiNScsXG4gICAgICAgICAgICAgIHRva2VuSWQ6ICcweDY3NWIwNTNkNzJjMjRkY2M2YmM3ZjM4Y2RkNDViNDg0M2NmYjdhZjY5YTI1YWQyMWQwMDJjMzc2MzU3ZTlkNjknLFxuICAgICAgICAgICAgICB0b2tlbk5hbWU6ICd0YXB0Om5mdGNvbGxlY3Rpb24xJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdXYWxsZXQgU2hhcmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgdXNlIGtleWNoYWluIHB1YiB0byBzaGFyZSB0c3Mgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB1c2VySWQgPSAnMTIzJztcbiAgICAgICAgY29uc3QgZW1haWwgPSAnc2hhcmV0b0BzZGt0ZXN0LmNvbSc7XG4gICAgICAgIGNvbnN0IHBlcm1pc3Npb25zID0gJ3ZpZXcsc3BlbmQnO1xuICAgICAgICBjb25zdCB0b0tleWNoYWluID0gdXR4b0xpYi5iaXAzMi5mcm9tU2VlZChCdWZmZXIuZnJvbSgnZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyZGVhZGJlZWYwMicsICdoZXgnKSk7XG4gICAgICAgIGNvbnN0IHBhdGggPSAnbS85OTk5OTkvMS8xJztcbiAgICAgICAgY29uc3QgcHVia2V5ID0gdG9LZXljaGFpbi5kZXJpdmVQYXRoKHBhdGgpLnB1YmxpY0tleS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnYml0Z28xMjM0JztcblxuICAgICAgICBjb25zdCBnZXRTaGFyaW5nS2V5Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoJy9hcGkvdjEvdXNlci9zaGFyaW5na2V5JywgeyBlbWFpbCB9KVxuICAgICAgICAgIC5yZXBseSgyMDAsIHsgdXNlcklkLCBwdWJrZXksIHBhdGggfSk7XG5cbiAgICAgICAgLy8gY29tbW9uUHViICsgY29tbW9uQ2hhaW5jb2RlXG4gICAgICAgIGNvbnN0IGNvbW1vbktleWNoYWluID0gcmFuZG9tQnl0ZXMoMzIpLnRvU3RyaW5nKCdoZXgnKSArIHJhbmRvbUJ5dGVzKDMyKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgIGNvbnN0IGdldEtleU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvdHNvbC9rZXkvJHt0c3NTb2xXYWxsZXQua2V5SWRzKClbMF19YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBpZDogdHNzU29sV2FsbGV0LmtleUlkcygpWzBdLFxuICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46IGNvbW1vbktleWNoYWluLFxuICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogJ3hwcnYxJywgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHN0dWIgPSBzaW5vbi5zdHViKHRzc1NvbFdhbGxldCwgJ2NyZWF0ZVNoYXJlJykuY2FsbHNGYWtlKGFzeW5jIChvcHRpb25zKSA9PiB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgICBvcHRpb25zIS5rZXljaGFpbiEucHViIS5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgICAgb3B0aW9ucyEua2V5Y2hhaW4hLnB1YiEuc2hvdWxkLmVxdWFsKFRzc1V0aWxzLmdldFB1YmxpY0tleUZyb21Db21tb25LZXljaGFpbihjb21tb25LZXljaGFpbikpO1xuICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH0pO1xuICAgICAgICBhd2FpdCB0c3NTb2xXYWxsZXQuc2hhcmVXYWxsZXQoeyBlbWFpbCwgcGVybWlzc2lvbnMsIHdhbGxldFBhc3NwaHJhc2UgfSk7XG5cbiAgICAgICAgc3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIGdldFNoYXJpbmdLZXlOb2NrLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgICAgIGdldEtleU5vY2suaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQVZBWCB0ZXN0cycsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgYmdVcmw7XG4gICAgbGV0IGJhc2Vjb2luO1xuICAgIGxldCB3YWxsZXREYXRhO1xuICAgIGxldCB3YWxsZXQ7XG5cbiAgICBiZWZvcmUoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbm9jay5wZW5kaW5nTW9ja3MoKS5zaG91bGQuYmUuZW1wdHkoKTtcbiAgICAgIGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuICAgICAgd2FsbGV0RGF0YSA9IHtcbiAgICAgICAgaWQ6ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEwMDAwMDAwMCcsXG4gICAgICAgIGtleXM6IFtcbiAgICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc1MDAwMDAwMDAnLFxuICAgICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzYwMDAwMDAwMCcsXG4gICAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NzAwMDAwMDAwJyxcbiAgICAgICAgXSxcbiAgICAgICAgY29pblNwZWNpZmljOiB7fSxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZldGNoIGNyb3NzLWNoYWluIHV0eG9zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0YXZheHAnKTtcbiAgICAgIHdhbGxldERhdGEuY29pbiA9ICd0YXZheHAnO1xuICAgICAgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHdhbGxldERhdGEpO1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7IHNvdXJjZUNoYWluOiAnQycgfTtcbiAgICAgIGNvbnN0IHBhdGggPSBgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS9jcm9zc0NoYWluVW5zcGVudHNgO1xuICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KHBhdGgpXG4gICAgICAgIC5xdWVyeShwYXJhbXMpXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICB1bnNwZW50OiB7XG4gICAgICAgICAgICBvdXRwdXRJRDogNyxcbiAgICAgICAgICAgIGFtb3VudDogJzEwMDAwMDAwJyxcbiAgICAgICAgICAgIHR4aWQ6ICdWM1VCWlRRajM2NHpOV3F0OHVNSEQ1Tmp4eFg4VDhxa2JlWlhVUm1qblZtTEVxemFiJyxcbiAgICAgICAgICAgIHRocmVzaG9sZDogMixcbiAgICAgICAgICAgIGFkZHJlc3NlczogW1xuICAgICAgICAgICAgICAnQy1mdWppMTk5Zmx1ZWdydGhxczR0dno0MHphamZyc3g1bTdkdnk3NWFqZm02JyxcbiAgICAgICAgICAgICAgJ0MtZnVqaTFnazNtNDQ0ODkzeW5sMGdmdnhhaGpndzN2ZnRubjhzcHR5ZDlnNScsXG4gICAgICAgICAgICAgICdDLWZ1amkxdWpmempnd3pmeWdsNjBxcDJsOHJtZ2xnM2xubTd3NDA1OW5jYTUnLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIG91dHB1dGlkeDogJzExMTFYaWFZZycsXG4gICAgICAgICAgICBsb2NrdGltZTogJzAnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZnJvbVdhbGxldDogJzYzNTA5MmZkNGZmMzMxNjE0MmRmNmU2YjdhMDc4YjkyJyxcbiAgICAgICAgICB0b1dhbGxldDogJzYzNTA5MmZkNGZmMzMxNjE0MmRmNmU4OTFmNmE3ZWU2JyxcbiAgICAgICAgICB0b0FkZHJlc3M6ICcweDEyNWM0NDUxYzg3MGY3NTMyNjViMGIxYWYzY2Y2YWI4OGZmZTQ2NTcnLFxuICAgICAgICB9KTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0LmZldGNoQ3Jvc3NDaGFpblVUWE9zKHBhcmFtcyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIHRlc3QgaXMgc3VjY2Vzc2Z1bCBpZiBub2NrIGlzIGNvbnN1bWVkLCBITUFDIGVycm9ycyBleHBlY3RlZFxuICAgICAgfVxuXG4gICAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3NlbmRNYW55IHNob3VsZCB3b3JrIGZvciBDID4gUCBleHBvcnQgd2l0aCBjdXN0b2RpYWwgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0YXZheGMnKTtcbiAgICAgIHdhbGxldERhdGEuY29pbiA9ICd0YXZheGMnO1xuICAgICAgd2FsbGV0RGF0YS50eXBlID0gJ2N1c3RvZGlhbCc7XG4gICAgICB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwgd2FsbGV0RGF0YSk7XG5cbiAgICAgIGNvbnN0IGFkZHJlc3MgPVxuICAgICAgICAnUC1mdWppMWU1NnBjNDk2NnFzZXZ6aHdna3ltNWwwamZtYTlsbGtxbnJyNGdoflAtZnVqaTFrcTA1em05bm1scThwM2xkNTVrNzlkbDNxYXk2YzBlM2F0ajU2dn5QLWZ1amkxcnA0NnozMHFnNDU3eGMzZHBmZnl4Y2d6cGZseGM4NW1oa2ptZTMnO1xuICAgICAgY29uc3QgaW5pdGlhdGVUeFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFtb3VudDogJzEwMDAwMDAwMDAwMDAwMDAwJywgLy8gMC4wMSBBVkFYXG4gICAgICAgICAgICBhZGRyZXNzLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGhvcDogdHJ1ZSxcbiAgICAgICAgdHlwZTogJ0V4cG9ydCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBpbml0aWF0ZVR4UGF0aCA9IGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4L2luaXRpYXRlYDtcbiAgICAgIGxldCBpbml0aWF0ZVR4Qm9keTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoaW5pdGlhdGVUeFBhdGgsIChib2R5KSA9PiB7XG4gICAgICAgICAgaW5pdGlhdGVUeEJvZHkgPSBib2R5O1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgY29uc3QgZmVlRXN0aW1hdGlvblBhdGggPSBgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3R4L2ZlZT9ob3A9dHJ1ZSZyZWNpcGllbnQ9JHthZGRyZXNzfSZhbW91bnQ9MTAwMDAwMDAwMDAwMDAwMDAmdHlwZT1FeHBvcnRgO1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KGZlZUVzdGltYXRpb25QYXRoKS5yZXBseSgyMDAsIHtcbiAgICAgICAgZmVlRXN0aW1hdGU6ICc3MTg3NTAwMDAwMDAwMDAnLFxuICAgICAgICBnYXNMaW1pdEVzdGltYXRlOiA1MDAwMDAsXG4gICAgICB9KTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0LnNlbmRNYW55KGluaXRpYXRlVHhQYXJhbXMpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zb2xlLmxvZyhlKTtcbiAgICAgICAgLy8gdGVzdCBpcyBzdWNjZXNzZnVsIGlmIG5vY2sgaXMgY29uc3VtZWQsIEhNQUMgZXJyb3JzIGV4cGVjdGVkXG4gICAgICB9XG4gICAgICBfLmlzTWF0Y2goaW5pdGlhdGVUeEJvZHksIHtcbiAgICAgICAgaG9wUGFyYW1zOiB7XG4gICAgICAgICAgZ2FzUHJpY2VNYXg6IDcxODc1MDAwMDAsXG4gICAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgfSxcbiAgICAgICAgdHlwZTogJ0V4cG9ydCcsXG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgICAgICAgICBhZGRyZXNzLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KS5zaG91bGQuYmUudHJ1ZSgpO1xuXG4gICAgICByZXNwb25zZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnTkZUIFRlc3RzJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBldGhXYWxsZXQ6IFdhbGxldDtcblxuICAgIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgICBpZDogJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkYjFkOTQ1OWJiJyxcbiAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAga2V5czogW1xuICAgICAgICAgICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMicsXG4gICAgICAgICAgJzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyJyxcbiAgICAgICAgICAnNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDcnLFxuICAgICAgICBdLFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICdvbmNoYWluJyxcbiAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGRmMDcxMTc3MDVhOWY4ZGM0YzJhNzhkZTY2YjdmMTc5N2RiYTlkNGUnLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGV0aFdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJpdGdvLmNvaW4oJ2h0ZXRoJyksIHdhbGxldERhdGEpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICB9KTtcblxuICAgIGl0KCdTaG91bGQgcmV0dXJuIGFsbCBuZnRzIGluIHRoZSB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBnZXRUb2tlbkJhbGFuY2VOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLmdldChgL2FwaS92Mi9odGV0aC93YWxsZXQvJHtldGhXYWxsZXQuaWQoKX0/YWxsVG9rZW5zPXRydWVgKVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgLi4ud2FsbGV0RGF0YSxcbiAgICAgICAgICAuLi5uZnRSZXNwb25zZSxcbiAgICAgICAgfSk7XG4gICAgICBjb25zdCBuZnRzID0gYXdhaXQgZXRoV2FsbGV0LmdldE5mdEJhbGFuY2VzKCk7XG4gICAgICBnZXRUb2tlbkJhbGFuY2VOb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgIG5mdHMuc2hvdWxkLmxlbmd0aCg1KTtcbiAgICAgIG5mdHMuc2hvdWxkLmNvbnRhaW5FcWwoe1xuICAgICAgICB0eXBlOiAnRVJDNzIxJyxcbiAgICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgICBuYW1lOiAndGVyYzcyMTpiaXRnb2VyYzcyMScsXG4gICAgICAgICAgdG9rZW5Db250cmFjdEFkZHJlc3M6ICcweDgzOTdiMDkxNTE0YzFmN2JlYmI5ZGVhNmFjMjY3ZWEyM2I1NzA2MDUnLFxuICAgICAgICB9LFxuICAgICAgICBjb2xsZWN0aW9uczoge30sXG4gICAgICAgIGJhbGFuY2VTdHJpbmc6ICcwJyxcbiAgICAgICAgY29uZmlybWVkQmFsYW5jZVN0cmluZzogJzAnLFxuICAgICAgICBzcGVuZGFibGVCYWxhbmNlU3RyaW5nOiAnMCcsXG4gICAgICAgIHRyYW5zZmVyQ291bnQ6IDAsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdTaG91bGQgdGhyb3cgd2hlbiBhdHRlbXB0aW5nIHRvIHRyYW5zZmVyIGEgbmZ0IGNvbGxlY3Rpb24gbm90IGluIHRoZSB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBnZXRUb2tlbkJhbGFuY2VOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLmdldChgL2FwaS92Mi9odGV0aC93YWxsZXQvJHtldGhXYWxsZXQuaWQoKX0/YWxsVG9rZW5zPXRydWVgKVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgLi4ud2FsbGV0RGF0YSxcbiAgICAgICAgICAuLi5uZnRSZXNwb25zZSxcbiAgICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IGV0aFdhbGxldFxuICAgICAgICAuc2VuZE5mdChcbiAgICAgICAgICB7XG4gICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnMTIzYWJjJyxcbiAgICAgICAgICAgIG90cDogJzAwMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0b2tlbklkOiAnMTIzJyxcbiAgICAgICAgICAgIHR5cGU6ICdFUkM3MjEnLFxuICAgICAgICAgICAgdG9rZW5Db250cmFjdEFkZHJlc3M6ICcweDEyM2JhZGFkZHJlc3MnLFxuICAgICAgICAgICAgcmVjaXBpZW50QWRkcmVzczogJzB4YzE1YWNjMjdlZTQxZjI2Njg3N2M4ZjBjNjFkZjViY2JjNzk5N2RmNicsXG4gICAgICAgICAgfVxuICAgICAgICApXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdDb2xsZWN0aW9uIG5vdCBmb3VuZCBmb3IgdG9rZW4gY29udHJhY3QgMHgxMjNiYWRhZGRyZXNzJyk7XG4gICAgICBnZXRUb2tlbkJhbGFuY2VOb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnU2hvdWxkIHRocm93IHdoZW4gYXR0ZW1wdGluZyB0byB0cmFuc2ZlciBhIEVSQy03MjEgbmZ0IG5vdCBvd25lZCBieSB0aGUgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZ2V0VG9rZW5CYWxhbmNlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoYC9hcGkvdjIvaHRldGgvd2FsbGV0LyR7ZXRoV2FsbGV0LmlkKCl9P2FsbFRva2Vucz10cnVlYClcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIC4uLndhbGxldERhdGEsXG4gICAgICAgICAgLi4ubmZ0UmVzcG9uc2UsXG4gICAgICAgICAgLi4udW5zdXBwb3J0ZWROZnRSZXNwb25zZSxcbiAgICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IGV0aFdhbGxldFxuICAgICAgICAuc2VuZE5mdChcbiAgICAgICAgICB7XG4gICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnMTIzYWJjJyxcbiAgICAgICAgICAgIG90cDogJzAwMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0b2tlbklkOiAnMTIzJyxcbiAgICAgICAgICAgIHR5cGU6ICdFUkM3MjEnLFxuICAgICAgICAgICAgdG9rZW5Db250cmFjdEFkZHJlc3M6ICcweGY1ZGU3NjBmMmU5MTY2NDdmZDc2NmI0YWQ5ZTg1ZmY5NDNjZTNhMmInLFxuICAgICAgICAgICAgcmVjaXBpZW50QWRkcmVzczogJzB4YzE1YWNjMjdlZTQxZjI2Njg3N2M4ZjBjNjFkZjViY2JjNzk5N2RmNicsXG4gICAgICAgICAgfVxuICAgICAgICApXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdUb2tlbiAxMjMgbm90IGZvdW5kIGluIGNvbGxlY3Rpb24gMHhmNWRlNzYwZjJlOTE2NjQ3ZmQ3NjZiNGFkOWU4NWZmOTQzY2UzYTJiIG9yIGRvZXMgbm90IGhhdmUgYSBzcGVuZGFibGUgYmFsYW5jZSdcbiAgICAgICAgKTtcbiAgICAgIGdldFRva2VuQmFsYW5jZU5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdTaG91bGQgdGhyb3cgd2hlbiBhdHRlbXB0aW5nIHRvIHRyYW5zZmVyIEVSQy0xMTU1IHRva2VucyB3aGVuIHRoZSBhbW91bnQgdHJhbnNmZXJyZWQgaXMgbW9yZSB0aGFuIHRoZSBzcGVuZGFibGUgYmFsYW5jZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGdldFRva2VuQmFsYW5jZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KGAvYXBpL3YyL2h0ZXRoL3dhbGxldC8ke2V0aFdhbGxldC5pZCgpfT9hbGxUb2tlbnM9dHJ1ZWApXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAuLi53YWxsZXREYXRhLFxuICAgICAgICAgIC4uLntcbiAgICAgICAgICAgIHVuc3VwcG9ydGVkTmZ0czoge1xuICAgICAgICAgICAgICAnMHhmNWRlNzYwZjJlOTE2NjQ3ZmQ3NjZiNGFkOWU4NWZmOTQzY2UzYTJiJzoge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdFUkMxMTU1JyxcbiAgICAgICAgICAgICAgICBjb2xsZWN0aW9uczoge1xuICAgICAgICAgICAgICAgICAgMTE4NjcwMzogJzknLFxuICAgICAgICAgICAgICAgICAgMTE4NjcwNTogJzEnLFxuICAgICAgICAgICAgICAgICAgMTI5NDg1NjogJzEnLFxuICAgICAgICAgICAgICAgICAgMTI5NDg1NzogJzEnLFxuICAgICAgICAgICAgICAgICAgMTI5NDg1ODogJzEnLFxuICAgICAgICAgICAgICAgICAgMTI5NDg1OTogJzEnLFxuICAgICAgICAgICAgICAgICAgMTI5NDg2MDogJzEnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgICAgICAgICAgIG5hbWU6ICdNdWx0aUZhdWNldCBORlQnLFxuICAgICAgICAgICAgICAgICAgdG9rZW5Db250cmFjdEFkZHJlc3M6ICcweGY1ZGU3NjBmMmU5MTY2NDdmZDc2NmI0YWQ5ZTg1ZmY5NDNjZTNhMmInLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICBhd2FpdCBldGhXYWxsZXRcbiAgICAgICAgLnNlbmROZnQoXG4gICAgICAgICAge1xuICAgICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJzEyM2FiYycsXG4gICAgICAgICAgICBvdHA6ICcwMDAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgZW50cmllczogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYW1vdW50OiAxMCxcbiAgICAgICAgICAgICAgICB0b2tlbklkOiAnMTE4NjcwMycsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhbW91bnQ6IDEsXG4gICAgICAgICAgICAgICAgdG9rZW5JZDogJzExODY3MDUnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHR5cGU6ICdFUkMxMTU1JyxcbiAgICAgICAgICAgIHRva2VuQ29udHJhY3RBZGRyZXNzOiAnMHhmNWRlNzYwZjJlOTE2NjQ3ZmQ3NjZiNGFkOWU4NWZmOTQzY2UzYTJiJyxcbiAgICAgICAgICAgIHJlY2lwaWVudEFkZHJlc3M6ICcweGMxNWFjYzI3ZWU0MWYyNjY4NzdjOGYwYzYxZGY1YmNiYzc5OTdkZjYnLFxuICAgICAgICAgIH1cbiAgICAgICAgKVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnQW1vdW50IDEwIGV4Y2VlZHMgc3BlbmRhYmxlIGJhbGFuY2Ugb2YgOSBmb3IgdG9rZW4gMTE4NjcwMycpO1xuICAgICAgZ2V0VG9rZW5CYWxhbmNlTm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQWRhIHRlc3RzOiAnLCAoKSA9PiB7XG4gICAgbGV0IGFkYVdhbGxldDogV2FsbGV0O1xuICAgIGNvbnN0IGFkYUJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ21vY2snIH0pO1xuICAgIGFkYUJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgIGNvbnN0IHdhbGxldERhdGEgPSB7XG4gICAgICBpZDogJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkYjFkOTQ1OWJiJyxcbiAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICBiYXNlQWRkcmVzczpcbiAgICAgICAgICAnYWRkcl90ZXN0MXE5ZmFhNXEzenIzOHdrZDRrZDN1OGpmc2h4OTdqeHZ3c3l2amczdGFjODI2NTAybm1tZ3B6eTh6d2F2bXR2bXJjMHlucHd2dGF5dmNhcWdleTN6aG1zdzQ0ZzdzaHJmcmg5JyxcbiAgICAgICAgcGVuZGluZ0NoYWluSW5pdGlhbGl6YXRpb246IGZhbHNlLFxuICAgICAgICBtaW5pbXVtRnVuZGluZzogMTAwMDAwMCxcbiAgICAgICAgbGFzdENoYWluSW5kZXg6IHsgMDogMCB9LFxuICAgICAgfSxcbiAgICAgIGNvaW46ICd0YWRhJyxcbiAgICAgIGtleXM6IFtcbiAgICAgICAgJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkODlkY2U4NmMyJyxcbiAgICAgICAgJzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyJyxcbiAgICAgICAgJzU5MzVkNTljZjY2MDc2NDMzMWJhZmNhZGUxODU1ZmQ3JyxcbiAgICAgIF0sXG4gICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgIH07XG5cbiAgICBiZWZvcmUoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYWRhV2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYml0Z28uY29pbigndGFkYScpLCB3YWxsZXREYXRhKTtcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi8ke2FkYVdhbGxldC5jb2luKCl9L2tleS8ke2FkYVdhbGxldC5rZXlJZHMoKVswXX1gKS50aW1lcygzKS5yZXBseSgyMDAsIHtcbiAgICAgICAgaWQ6ICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMicsXG4gICAgICAgIHB1YjogJzVmOFdtQzJ1VzlTQWs3TE1YMnI0RzFCeDhNTXd4OHNkZ3BvdHlIR29kaVpvJyxcbiAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIGVuY3J5cHRlZFBydjpcbiAgICAgICAgICAne1wiaXZcIjpcImhOSzNyZzgyUDFUOTRNYXVlWEZBYkE9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJjVjR3VTRFelBqcz1cIixcImN0XCI6XCI5VlpYOTladHNiNnA3NUN4bDJscmNYQnBsbXNzSUFROWs3WkE4MXZkRFlHNE41ZFozNkJRTldWZkRvZWxqOU8zMVh5SitYcmkwWEtJV1V6bDBLS0xmVUVScGxtdE5vT0NuNWlmSmNad0NyT3hwSFpRZTNBSjcwMG84V21zcms1SFwifScsXG4gICAgICAgIGNvaW5TcGVjaWZpYzoge30sXG4gICAgICB9KTtcblxuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyLyR7YWRhV2FsbGV0LmNvaW4oKX0va2V5LyR7YWRhV2FsbGV0LmtleUlkcygpWzFdfWApLnRpbWVzKDIpLnJlcGx5KDIwMCwge1xuICAgICAgICBpZDogJzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyJyxcbiAgICAgICAgcHViOiAnRzFzNDNKVHpOWnpxaFVuNGFOcHdnY2M2d2I5RlVzWlFENUpqZmZHNmlzeWQnLFxuICAgICAgICBlbmNyeXB0ZWRQcnY6XG4gICAgICAgICAgJ3tcIml2XCI6XCJVRnJ0L1FsSVVSMVhlUWFmUEJhQWx3PT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiN1ZQQllhSlhQbTg9XCIsXCJjdFwiOlwiYWpGS3YyeTh5YUlCWFEzOXNBYkJXY25iaUVFemJqUzRBb1F0cDVjWFlxamVEUnh0M2FDeGVtUG0yMnBua0phQ2lqRmpKck1IYmttc05oTll6SGc1YUhGdWtOK25FQVZzc3lOd0hiemxoU25tOC9CVk41MHlBZEFBdFdyZWg4Y3BcIn0nLFxuICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgfSk7XG5cbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi8ke2FkYVdhbGxldC5jb2luKCl9L2tleS8ke2FkYVdhbGxldC5rZXlJZHMoKVsyXX1gKS50aW1lcygyKS5yZXBseSgyMDAsIHtcbiAgICAgICAgaWQ6ICc1OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkNycsXG4gICAgICAgIHB1YjogJ0dIMUxWMWU5RmRxR2U4VTJjOFBNRWNtYTNmRGVoMWt0Y0dWQnJEM0F1RnF4JyxcbiAgICAgICAgZW5jcnlwdGVkUHJ2OlxuICAgICAgICAgICd7XCJpdlwiOlwiaUl1V09ISU9FckVEZGlKbjZnNDZtZz09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIlJ6aDdSUkprc2owPVwiLFwiY3RcIjpcInJjTklDVWZwOUZha1Q1M2wrYWRCNlhLelMxdk5UYzBRcTlqQXRxbnhBK1Njc3NpUzRRMGwzc2dHLzBnRHk1RGFaS3RYcnlLQkRVdkdzaTdiL2ZZYUZDVXBBb1puL1ZaVE9oT1VOL21vN1pIYjRPaE9YTDI5WVBQa2lyeUFxOUNyXCJ9JyxcbiAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBhZnRlcihhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBzaW5vbi5yZXN0b3JlKCk7XG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnU2hvdWxkIHNlbmQgdW5zcGVudHMgaW4gcGF5bWVudCBpbnRlbnQgd2hlbiB1c2luZyBzZW5kbWFueScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNlbmRNYW55UGFyYW1zID0ge1xuICAgICAgICB0eXBlOiAndHJhbnNmZXInLFxuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJ2FkZHJlc3MnLFxuICAgICAgICAgICAgYW1vdW50OiAnMTAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgdW5zcGVudHM6IFsndW5zcGVudDEnLCAndW5zcGVudDInXSxcbiAgICAgIH07XG5cbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyL3dhbGxldC8ke2FkYVdhbGxldC5pZCgpfS90eHJlcXVlc3RzYClcbiAgICAgICAgLnJlcGx5KCh1cmwsIGJvZHk6IGFueSkgPT4ge1xuICAgICAgICAgIC8vIHZhbGlkYXRlIHRoYXQgdGhlIHBvcHVsYXRlZCBpbnRlbnQgaGFzIHVuc3BlbnRzXG4gICAgICAgICAgYm9keS5pbnRlbnQuaW50ZW50VHlwZS5zaG91bGQuZXF1YWwoJ3BheW1lbnQnKTtcbiAgICAgICAgICBib2R5LmludGVudC51bnNwZW50cy5zaG91bGQuZGVlcEVxdWFsKFsndW5zcGVudDEnLCAndW5zcGVudDInXSk7XG5cbiAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgMjAwLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhcGlWZXJzaW9uOiAnbGl0ZScsXG4gICAgICAgICAgICAgIHVuc2lnbmVkVHhzOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgdW5zaWduZWRUeDoge1xuICAgICAgICAgICAgICAgICAgICBzZXJpYWxpemVkVHhIZXg6ICdzZXJpYWxpemVkVHhIZXgnLFxuICAgICAgICAgICAgICAgICAgICBmZWVJbmZvOiAnZmVlIGluZm8nLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdO1xuICAgICAgICB9KTtcblxuICAgICAgLy8gc3R1YiBhbGwgc3RlcHMgYWZ0ZXIgdHhyZXF1ZXN0IGNyZWF0aW9uXG4gICAgICBzaW5vbi5zdHViKGFkYVdhbGxldC5iYXNlQ29pbiwgJ3ZlcmlmeVRyYW5zYWN0aW9uJykucmVzb2x2ZXModHJ1ZSk7XG4gICAgICBzaW5vbi5zdHViKGFkYVdhbGxldCwgJ3NpZ25UcmFuc2FjdGlvbicpLnJlc29sdmVzKHsgdHhSZXF1ZXN0SWQ6ICd0eFJlcXVlc3RJZCcgfSk7XG4gICAgICBzaW5vbi5zdHViKEJhc2VUc3NVdGlscy5kZWZhdWx0LnByb3RvdHlwZSwgJ3NlbmRUeFJlcXVlc3QnKS5yZXNvbHZlcygnc2VuZFR4UmVzcG9uc2UnKTtcbiAgICAgIGF3YWl0IGFkYVdhbGxldC5zZW5kTWFueShzZW5kTWFueVBhcmFtcyk7XG4gICAgfSk7XG5cbiAgICBpdCgnU2hvdWxkIHNlbmQgc2VuZGVyQWRkcmVzcyBpbiBwYXltZW50IGludGVudCB3aGVuIHVzaW5nIHNlbmRtYW55JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VuZE1hbnlQYXJhbXMgPSB7XG4gICAgICAgIHR5cGU6ICd0cmFuc2ZlcicsXG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnYWRkcmVzcycsXG4gICAgICAgICAgICBhbW91bnQ6ICcxMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBzZW5kZXJBZGRyZXNzOiAnc2VuZGVyQWRkcjEnLFxuICAgICAgfTtcblxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvd2FsbGV0LyR7YWRhV2FsbGV0LmlkKCl9L3R4cmVxdWVzdHNgKVxuICAgICAgICAucmVwbHkoKHVybCwgYm9keTogbm9jay5Cb2R5KSA9PiB7XG4gICAgICAgICAgY29uc3QgY3JlYXRlVHhSZXF1ZXN0Qm9keSA9IGJvZHkgYXMgQ3JlYXRlVHhSZXF1ZXN0Qm9keTtcbiAgICAgICAgICBjcmVhdGVUeFJlcXVlc3RCb2R5LmludGVudC5pbnRlbnRUeXBlLnNob3VsZC5lcXVhbCgncGF5bWVudCcpO1xuICAgICAgICAgIGNyZWF0ZVR4UmVxdWVzdEJvZHkuaW50ZW50LnNlbmRlckFkZHJlc3M/LnNob3VsZC5lcXVhbCgnc2VuZGVyQWRkcjEnKTtcblxuICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICAyMDAsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFwaVZlcnNpb246ICdsaXRlJyxcbiAgICAgICAgICAgICAgdW5zaWduZWRUeHM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICB1bnNpZ25lZFR4OiB7XG4gICAgICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWRUeEhleDogJ3NlcmlhbGl6ZWRUeEhleCcsXG4gICAgICAgICAgICAgICAgICAgIGZlZUluZm86ICdmZWUgaW5mbycsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF07XG4gICAgICAgIH0pO1xuXG4gICAgICBzaW5vbi5zdHViKGFkYVdhbGxldC5iYXNlQ29pbiwgJ3ZlcmlmeVRyYW5zYWN0aW9uJykucmVzb2x2ZXModHJ1ZSk7XG4gICAgICBzaW5vbi5zdHViKGFkYVdhbGxldCwgJ3NpZ25UcmFuc2FjdGlvbicpLnJlc29sdmVzKHsgdHhSZXF1ZXN0SWQ6ICd0eFJlcXVlc3RJZCcgfSk7XG4gICAgICBzaW5vbi5zdHViKEJhc2VUc3NVdGlscy5kZWZhdWx0LnByb3RvdHlwZSwgJ3NlbmRUeFJlcXVlc3QnKS5yZXNvbHZlcygnc2VuZFR4UmVzcG9uc2UnKTtcbiAgICAgIGF3YWl0IGFkYVdhbGxldC5zZW5kTWFueShzZW5kTWFueVBhcmFtcykuc2hvdWxkLmJlLnJlc29sdmVkKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdFUkMyMCBUb2tlbiBBcHByb3ZhbCcsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgd2FsbGV0O1xuICAgIGNvbnN0IHdhbGxldElkID0gJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYTAwMDAwMDAwJztcbiAgICBsZXQgdG9wZXRoQ29pbjtcbiAgICBjb25zdCB0b2tlbk5hbWUgPSAndG9wZXRoOnRlcmMxOGRwJztcbiAgICBjb25zdCBjb2luID0gJ3RvcGV0aCc7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHRvcGV0aENvaW4gPSBiaXRnby5jb2luKCd0b3BldGgnKTtcbiAgICAgIHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIHRvcGV0aENvaW4sIHtcbiAgICAgICAgaWQ6IHdhbGxldElkLFxuICAgICAgICBjb2luOiBjb2luLFxuICAgICAgICBrZXlzOiBbJ2tleWlkMScsICdrZXlpZDInLCAna2V5aWQzJ10sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzaW5vbi5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHN1Y2Nlc3NmdWxseSBhcHByb3ZlIGEgdG9rZW4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ3Bhc3N3b3JkMTIzJztcbiAgICAgIGNvbnN0IGV4cGVjdGVkQXBwcm92YWxCdWlsZCA9IHtcbiAgICAgICAgdHhIZXg6ICcweDEyMzQ1NicsXG4gICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICBmZWU6ICcxMDAwMDAwMDAwJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGV4cGVjdGVkU2lnbmVkVHggPSB7XG4gICAgICAgIHR4SGV4OiAnMHgxMjM0NTZzaWduZWQnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgZXhwZWN0ZWRTZW5kUmVzdWx0ID0ge1xuICAgICAgICB0eGlkOiAnMHhhYmNkZWYnLFxuICAgICAgICB0eDogJzB4MTIzNDU2c2lnbmVkJyxcbiAgICAgICAgc3RhdHVzOiAnc2lnbmVkJyxcbiAgICAgIH07XG5cbiAgICAgIC8vIE1vY2sgdGhlIHRva2VuIGFwcHJvdmFsIGJ1aWxkIEFQSVxuICAgICAgY29uc3QgZXRoVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuICAgICAgbm9jayhldGhVcmwpLnBvc3QoYC9hcGkvdjIvJHtjb2lufS93YWxsZXQvJHt3YWxsZXRJZH0vdG9rZW4vYXBwcm92YWwvYnVpbGRgKS5yZXBseSgyMDAsIGV4cGVjdGVkQXBwcm92YWxCdWlsZCk7XG5cbiAgICAgIC8vIE1vY2sgdGhlIGdldEtleWNoYWluc0FuZFZhbGlkYXRlUGFzc3BocmFzZSBtZXRob2RcbiAgICAgIHNpbm9uLnN0dWIod2FsbGV0LCAnZ2V0S2V5Y2hhaW5zQW5kVmFsaWRhdGVQYXNzcGhyYXNlJykucmVzb2x2ZXMoW1xuICAgICAgICB7XG4gICAgICAgICAgaWQ6ICdrZXlpZDEnLFxuICAgICAgICAgIHB1YjogJ3B1YjEnLFxuICAgICAgICAgIGVuY3J5cHRlZFBydjogJ2VuY3J5cHRlZFBydicsXG4gICAgICAgIH0sXG4gICAgICBdKTtcblxuICAgICAgLy8gTW9jayB0aGUgc2lnbiB0cmFuc2FjdGlvbiBtZXRob2RcbiAgICAgIHNpbm9uLnN0dWIod2FsbGV0LCAnc2lnblRyYW5zYWN0aW9uJykucmVzb2x2ZXMoZXhwZWN0ZWRTaWduZWRUeCk7XG5cbiAgICAgIC8vIE1vY2sgdGhlIHNlbmQgdHJhbnNhY3Rpb24gbWV0aG9kXG4gICAgICBzaW5vbi5zdHViKHdhbGxldCwgJ3NlbmRUcmFuc2FjdGlvbicpLnJlc29sdmVzKGV4cGVjdGVkU2VuZFJlc3VsdCk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldC5hcHByb3ZlRXJjMjBUb2tlbih3YWxsZXRQYXNzcGhyYXNlLCB0b2tlbk5hbWUpO1xuXG4gICAgICBzaG91bGQuZXhpc3QocmVzdWx0KTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZGVlcEVxdWFsKGV4cGVjdGVkU2VuZFJlc3VsdCk7XG5cbiAgICAgIC8vIFZlcmlmeSB0aGUgcGFyYW1ldGVycyBwYXNzZWQgdG8gc2lnblRyYW5zYWN0aW9uXG4gICAgICBjb25zdCBzaWduUGFyYW1zID0gd2FsbGV0LnNpZ25UcmFuc2FjdGlvbi5maXJzdENhbGwuYXJnc1swXTtcbiAgICAgIHNpZ25QYXJhbXMuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4UHJlYnVpbGQnLCBleHBlY3RlZEFwcHJvdmFsQnVpbGQpO1xuICAgICAgc2lnblBhcmFtcy5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgna2V5Y2hhaW4nKTtcbiAgICAgIHNpZ25QYXJhbXMuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldFBhc3NwaHJhc2UnLCB3YWxsZXRQYXNzcGhyYXNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIHRva2VuIGFwcHJvdmFsIGJ1aWxkIEFQSSBlcnJvcnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ3Bhc3N3b3JkMTIzJztcbiAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9ICd0b2tlbiBhcHByb3ZhbCBidWlsZCBmYWlsZWQnO1xuXG4gICAgICAvLyBNb2NrIHRoZSB0b2tlbiBhcHByb3ZhbCBidWlsZCBBUEkgdG8gcmV0dXJuIGFuIGVycm9yXG4gICAgICBub2NrKGJnVXJsKS5wb3N0KGAvYXBpL3YyLyR7Y29pbn0vd2FsbGV0LyR7d2FsbGV0SWR9L3Rva2VuL2FwcHJvdmFsL2J1aWxkYCkucmVwbHlXaXRoRXJyb3IoZXJyb3JNZXNzYWdlKTtcblxuICAgICAgYXdhaXQgd2FsbGV0LmFwcHJvdmVFcmMyMFRva2VuKHdhbGxldFBhc3NwaHJhc2UsIHRva2VuTmFtZSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChlcnJvck1lc3NhZ2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgd2FsbGV0IHBhc3NwaHJhc2UgdmFsaWRhdGlvbiBlcnJvcnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ3dyb25nLXBhc3N3b3JkJztcbiAgICAgIGNvbnN0IGV4cGVjdGVkQXBwcm92YWxCdWlsZCA9IHtcbiAgICAgICAgdHhIZXg6ICcweDEyMzQ1NicsXG4gICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICBmZWU6ICcxMDAwMDAwMDAwJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIC8vIE1vY2sgdGhlIHRva2VuIGFwcHJvdmFsIGJ1aWxkIEFQSVxuICAgICAgbm9jayhiZ1VybCkucG9zdChgL2FwaS92Mi8ke2NvaW59L3dhbGxldC8ke3dhbGxldElkfS90b2tlbi9hcHByb3ZhbC9idWlsZGApLnJlcGx5KDIwMCwgZXhwZWN0ZWRBcHByb3ZhbEJ1aWxkKTtcblxuICAgICAgLy8gTW9jayB0aGUgZ2V0S2V5Y2hhaW5zQW5kVmFsaWRhdGVQYXNzcGhyYXNlIG1ldGhvZCB0byB0aHJvdyBhbiBlcnJvclxuICAgICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoJ3VuYWJsZSB0byBkZWNyeXB0IGtleWNoYWluIHdpdGggdGhlIGdpdmVuIHdhbGxldCBwYXNzcGhyYXNlJyk7XG4gICAgICBlcnJvci5uYW1lID0gJ3dhbGxldF9wYXNzcGhyYXNlX2luY29ycmVjdCc7XG4gICAgICBzaW5vbi5zdHViKHdhbGxldCwgJ2dldEtleWNoYWluc0FuZFZhbGlkYXRlUGFzc3BocmFzZScpLnJlamVjdHMoZXJyb3IpO1xuXG4gICAgICBhd2FpdCB3YWxsZXRcbiAgICAgICAgLmFwcHJvdmVFcmMyMFRva2VuKHdhbGxldFBhc3NwaHJhc2UsIHRva2VuTmFtZSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3VuYWJsZSB0byBkZWNyeXB0IGtleWNoYWluIHdpdGggdGhlIGdpdmVuIHdhbGxldCBwYXNzcGhyYXNlJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBzaWduaW5nIGVycm9ycycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAncGFzc3dvcmQxMjMnO1xuICAgICAgY29uc3QgZXhwZWN0ZWRBcHByb3ZhbEJ1aWxkID0ge1xuICAgICAgICB0eEhleDogJzB4MTIzNDU2JyxcbiAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgIGZlZTogJzEwMDAwMDAwMDAnLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHNpZ25pbmdFcnJvciA9IG5ldyBFcnJvcignc2lnbmluZyBmYWlsZWQnKTtcblxuICAgICAgLy8gTW9jayB0aGUgdG9rZW4gYXBwcm92YWwgYnVpbGQgQVBJXG4gICAgICBub2NrKGJnVXJsKS5wb3N0KGAvYXBpL3YyLyR7Y29pbn0vd2FsbGV0LyR7d2FsbGV0SWR9L3Rva2VuL2FwcHJvdmFsL2J1aWxkYCkucmVwbHkoMjAwLCBleHBlY3RlZEFwcHJvdmFsQnVpbGQpO1xuXG4gICAgICAvLyBNb2NrIHRoZSBnZXRLZXljaGFpbnNBbmRWYWxpZGF0ZVBhc3NwaHJhc2UgbWV0aG9kXG4gICAgICBzaW5vbi5zdHViKHdhbGxldCwgJ2dldEtleWNoYWluc0FuZFZhbGlkYXRlUGFzc3BocmFzZScpLnJlc29sdmVzKFtcbiAgICAgICAge1xuICAgICAgICAgIGlkOiAna2V5aWQxJyxcbiAgICAgICAgICBwdWI6ICdwdWIxJyxcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6ICdlbmNyeXB0ZWRQcnYnLFxuICAgICAgICB9LFxuICAgICAgXSk7XG5cbiAgICAgIC8vIE1vY2sgdGhlIHNpZ24gdHJhbnNhY3Rpb24gbWV0aG9kIHRvIHRocm93IGFuIGVycm9yXG4gICAgICBzaW5vbi5zdHViKHdhbGxldCwgJ3NpZ25UcmFuc2FjdGlvbicpLnJlamVjdHMoc2lnbmluZ0Vycm9yKTtcblxuICAgICAgYXdhaXQgd2FsbGV0LmFwcHJvdmVFcmMyMFRva2VuKHdhbGxldFBhc3NwaHJhc2UsIHRva2VuTmFtZSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChzaWduaW5nRXJyb3IpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgc2VuZCB0cmFuc2FjdGlvbiBlcnJvcnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ3Bhc3N3b3JkMTIzJztcbiAgICAgIGNvbnN0IGV4cGVjdGVkQXBwcm92YWxCdWlsZCA9IHtcbiAgICAgICAgdHhIZXg6ICcweDEyMzQ1NicsXG4gICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICBmZWU6ICcxMDAwMDAwMDAwJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCBleHBlY3RlZFNpZ25lZFR4ID0ge1xuICAgICAgICB0eEhleDogJzB4MTIzNDU2c2lnbmVkJyxcbiAgICAgIH07XG4gICAgICBjb25zdCBzZW5kRXJyb3IgPSBuZXcgRXJyb3IoJ3NlbmQgZmFpbGVkJyk7XG5cbiAgICAgIC8vIE1vY2sgdGhlIHRva2VuIGFwcHJvdmFsIGJ1aWxkIEFQSVxuICAgICAgbm9jayhiZ1VybCkucG9zdChgL2FwaS92Mi8ke2NvaW59L3dhbGxldC8ke3dhbGxldElkfS90b2tlbi9hcHByb3ZhbC9idWlsZGApLnJlcGx5KDIwMCwgZXhwZWN0ZWRBcHByb3ZhbEJ1aWxkKTtcblxuICAgICAgLy8gTW9jayB0aGUgZ2V0S2V5Y2hhaW5zQW5kVmFsaWRhdGVQYXNzcGhyYXNlIG1ldGhvZFxuICAgICAgc2lub24uc3R1Yih3YWxsZXQsICdnZXRLZXljaGFpbnNBbmRWYWxpZGF0ZVBhc3NwaHJhc2UnKS5yZXNvbHZlcyhbXG4gICAgICAgIHtcbiAgICAgICAgICBpZDogJ2tleWlkMScsXG4gICAgICAgICAgcHViOiAncHViMScsXG4gICAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZW5jcnlwdGVkUHJ2JyxcbiAgICAgICAgfSxcbiAgICAgIF0pO1xuXG4gICAgICAvLyBNb2NrIHRoZSBzaWduIHRyYW5zYWN0aW9uIG1ldGhvZFxuICAgICAgc2lub24uc3R1Yih3YWxsZXQsICdzaWduVHJhbnNhY3Rpb24nKS5yZXNvbHZlcyhleHBlY3RlZFNpZ25lZFR4KTtcblxuICAgICAgLy8gTW9jayB0aGUgc2VuZCB0cmFuc2FjdGlvbiBtZXRob2QgdG8gdGhyb3cgYW4gZXJyb3JcbiAgICAgIHNpbm9uLnN0dWIod2FsbGV0LCAnc2VuZFRyYW5zYWN0aW9uJykucmVqZWN0cyhzZW5kRXJyb3IpO1xuXG4gICAgICBhd2FpdCB3YWxsZXQuYXBwcm92ZUVyYzIwVG9rZW4od2FsbGV0UGFzc3BocmFzZSwgdG9rZW5OYW1lKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKHNlbmRFcnJvcik7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=

Выполнить команду


Для локальной разработки. Не используйте в интернете!