UNPKG

bitgo

Version:
3,850 lines • 603 kB
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//
// Tests for Wallets
//
const assert = require("assert");
const nock = require("nock");
const sinon = require("sinon");
const should = require("should");
const _ = require("lodash");
const utxoLib = require("@bitgo/utxo-lib");
const sdk_test_1 = require("@bitgo/sdk-test");
const sdk_core_1 = require("@bitgo/sdk-core");
const src_1 = require("../../../src");
const mocha_1 = require("mocha");
const moduleBitgo = require("@bitgo/sdk-core");
describe('V2 Wallets:', function () {
    const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
    let wallets;
    let ofcWallets;
    let bgUrl;
    before(function () {
        nock('https://bitgo.fakeurl').persist().get('/api/v1/client/constants').reply(200, { ttl: 3600, constants: {} });
        bitgo.initializeTestVars();
        const basecoin = bitgo.coin('tbtc');
        wallets = basecoin.wallets();
        ofcWallets = bitgo.coin('ofc').wallets();
        bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
    });
    after(function () {
        nock.cleanAll();
        nock.pendingMocks().length.should.equal(0);
    });
    describe('Add Wallet:', function () {
        it('throws on invalid arguments', async function () {
            // isCustodial flag is not a boolean
            await wallets
                .add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, isCustodial: 1 })
                .should.be.rejectedWith('invalid argument for isCustodial - boolean expected');
            // type is not a string
            await wallets
                .add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, type: 1 })
                .should.be.rejectedWith('Expecting parameter string: type but found number');
            // Address is an invalid address
            await wallets
                .add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, address: '$' })
                .should.be.rejectedWith('invalid argument for address - valid address string expected');
            // gasPrice is a number
            await wallets
                .add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, gasPrice: '17' })
                .should.be.rejectedWith('invalid argument for gasPrice - number expected');
            // walletVersion is a number
            await wallets
                .add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, walletVersion: '1' })
                .should.be.rejectedWith('invalid argument for walletVersion - number expected');
        });
        it('creates a paired custodial wallet', async function () {
            nock(bgUrl)
                .post('/api/v2/tbtc/wallet/add', function (body) {
                body.isCustodial.should.be.true();
                body.should.have.property('keys');
                body.m.should.equal(2);
                body.n.should.equal(3);
                return true;
            })
                .reply(200, {});
            await wallets.add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, isCustodial: true });
        });
        it('creates an eos wallet with custom address', async function () {
            const eosBitGo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
            eosBitGo.initializeTestVars();
            const eosWallets = eosBitGo.coin('teos').wallets();
            const address = 'testeosaddre';
            nock(bgUrl)
                .post('/api/v2/teos/wallet/add', function (body) {
                body.should.have.property('keys');
                body.m.should.equal(2);
                body.n.should.equal(3);
                body.address.should.equal(address);
                return true;
            })
                .reply(200, {});
            await eosWallets.add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, address });
        });
        it('creates a single custodial wallet', async function () {
            nock(bgUrl)
                .post('/api/v2/tbtc/wallet/add', function (body) {
                body.type.should.equal('custodial');
                body.should.not.have.property('keys');
                body.should.not.have.property('m');
                body.should.not.have.property('n');
                return true;
            })
                .reply(200, {});
            await wallets.add({ label: 'label', enterprise: 'enterprise', type: 'custodial' });
        });
        it('creates a wallet with custom gasPrice', async function () {
            const ethBitGo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
            ethBitGo.initializeTestVars();
            const ethWallets = ethBitGo.coin('teth').wallets();
            nock(bgUrl)
                .post('/api/v2/teth/wallet/add', function (body) {
                body.type.should.equal('custodial');
                body.gasPrice.should.equal(20000000000);
                body.should.not.have.property('keys');
                body.should.not.have.property('m');
                body.should.not.have.property('n');
                return true;
            })
                .reply(200, {});
            await ethWallets.add({
                label: 'label',
                enterprise: 'enterprise',
                type: 'custodial',
                gasPrice: 20000000000,
            });
        });
        it('creates a new wallet with walletVersion', async function () {
            const ethBitGo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
            ethBitGo.initializeTestVars();
            const ethWallets = ethBitGo.coin('teth').wallets();
            nock(bgUrl)
                .post('/api/v2/teth/wallet/add', function (body) {
                body.type.should.equal('custodial');
                body.walletVersion.should.equal(1);
                body.should.not.have.property('keys');
                body.should.not.have.property('m');
                body.should.not.have.property('n');
                return true;
            })
                .reply(200, {});
            await ethWallets.add({ label: 'label', enterprise: 'enterprise', type: 'custodial', walletVersion: 1 });
        });
        it('creates a new hot wallet with userKey', async function () {
            nock(bgUrl)
                .post('/api/v2/tbtc/wallet/add', function (body) {
                body.type.should.equal('hot');
                body.should.have.property('keys');
                body.should.have.property('m');
                body.should.have.property('n');
                return true;
            })
                .reply(200, {});
            await wallets.add({
                label: 'label',
                enterprise: 'enterprise',
                type: 'hot',
                keys: [],
                m: 2,
                n: 3,
                userKey: 'test123',
            });
        });
    });
    describe('Generate wallet:', function () {
        const sandbox = sinon.createSandbox();
        it('should validate parameters', async function () {
            let params = {};
            await wallets.generateWallet(params).should.be.rejectedWith('Missing parameter: label');
            params = {
                label: 'abc',
                backupXpub: 'backup',
                backupXpubProvider: 'provider',
            };
            await wallets
                .generateWallet(params)
                .should.be.rejectedWith('Cannot provide more than one backupXpub or backupXpubProvider flag');
            params = {
                label: 'abc',
                passcodeEncryptionCode: 123,
            };
            await wallets.generateWallet(params).should.be.rejectedWith('passcodeEncryptionCode must be a string');
            params = {
                label: 'abc',
                enterprise: 1234,
            };
            await wallets.generateWallet(params).should.be.rejectedWith('invalid enterprise argument, expecting string');
            params = {
                label: 'abc',
                disableTransactionNotifications: 'string',
            };
            await wallets
                .generateWallet(params)
                .should.be.rejectedWith('invalid disableTransactionNotifications argument, expecting boolean');
            params = {
                label: 'abc',
                gasPrice: 'string',
            };
            await wallets
                .generateWallet(params)
                .should.be.rejectedWith('invalid gas price argument, expecting number or number as string');
            params = {
                label: 'abc',
                gasPrice: true,
            };
            await wallets
                .generateWallet(params)
                .should.be.rejectedWith('invalid gas price argument, expecting number or number as string');
            params = {
                label: 'abc',
                gasPrice: 123,
                eip1559: {
                    maxFeePerGas: 1234,
                    maxPriorityFeePerGas: 123,
                },
            };
            await wallets.generateWallet(params).should.be.rejectedWith('can not use both eip1559 and gasPrice values');
            params = {
                label: 'abc',
                eip1559: {
                    maxFeePerGas: 'q1234',
                    maxPriorityFeePerGas: '123',
                },
            };
            await wallets
                .generateWallet(params)
                .should.be.rejectedWith('invalid max fee argument, expecting number or number as string');
            params = {
                label: 'abc',
                eip1559: {
                    maxFeePerGas: 1234,
                    maxPriorityFeePerGas: '123a',
                },
            };
            await wallets
                .generateWallet(params)
                .should.be.rejectedWith('invalid priority fee argument, expecting number or number as string');
            params = {
                label: 'abc',
                disableKRSEmail: 'string',
            };
            await wallets
                .generateWallet(params)
                .should.be.rejectedWith('invalid disableKRSEmail argument, expecting boolean');
            params = {
                label: 'abc',
                krsSpecific: {
                    malicious: {
                        javascript: {
                            code: 'bad.js',
                        },
                    },
                },
            };
            await wallets
                .generateWallet(params)
                .should.be.rejectedWith('krsSpecific object contains illegal values. values must be strings, booleans, or numbers');
        });
        it('should correctly disable krs emails when creating backup keychains', async function () {
            const params = {
                label: 'my_wallet',
                disableKRSEmail: true,
                backupXpubProvider: 'test',
                passphrase: 'test123',
                userKey: 'xpub123',
            };
            // bitgo key
            nock(bgUrl)
                .post('/api/v2/tbtc/key', _.matches({ source: 'bitgo' }))
                .reply(200);
            // user key
            nock(bgUrl)
                .post('/api/v2/tbtc/key', _.conforms({ pub: (p) => p.startsWith('xpub') }))
                .reply(200);
            // backup key
            nock(bgUrl)
                .post('/api/v2/tbtc/key', _.matches({
                source: 'backup',
                provider: params.backupXpubProvider,
                disableKRSEmail: true,
            }))
                .reply(200);
            // wallet
            nock(bgUrl).post('/api/v2/tbtc/wallet/add').reply(200);
            await wallets.generateWallet(params);
        });
        it('should correctly pass through the krsSpecific param when creating backup keychains', async function () {
            const params = {
                label: 'my_wallet',
                backupXpubProvider: 'test',
                passphrase: 'test123',
                userKey: 'xpub123',
                krsSpecific: { coverage: 'insurance', expensive: true, howExpensive: 25 },
            };
            // bitgo key
            nock(bgUrl)
                .post('/api/v2/tbtc/key', _.matches({ source: 'bitgo' }))
                .reply(200);
            // user key
            nock(bgUrl)
                .post('/api/v2/tbtc/key', _.conforms({ pub: (p) => p.startsWith('xpub') }))
                .reply(200);
            // backup key
            nock(bgUrl)
                .post('/api/v2/tbtc/key', _.matches({
                source: 'backup',
                provider: params.backupXpubProvider,
                krsSpecific: { coverage: 'insurance', expensive: true, howExpensive: 25 },
            }))
                .reply(200);
            // wallet
            nock(bgUrl).post('/api/v2/tbtc/wallet/add').reply(200);
            await wallets.generateWallet(params);
        });
        it('should send the cold derivation seed for a user key', async () => {
            const params = {
                label: 'my-cold-wallet',
                passphrase: 'test123',
                userKey: 'xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8',
                coldDerivationSeed: '123',
            };
            // bitgo key
            const bitgoKeyNock = nock(bgUrl)
                .post('/api/v2/tbtc/key', _.matches({ source: 'bitgo' }))
                .reply(200);
            // user key
            const userKeyNock = nock(bgUrl)
                .post('/api/v2/tbtc/key', _.matches({
                derivedFromParentWithSeed: params.coldDerivationSeed,
            }))
                .reply(200);
            // backup key
            const backupKeyNock = nock(bgUrl)
                .post('/api/v2/tbtc/key', _.matches({ source: 'backup' }))
                .reply(200);
            // wallet
            const walletNock = nock(bgUrl).post('/api/v2/tbtc/wallet/add').reply(200);
            await wallets.generateWallet(params);
            for (const scope of [bitgoKeyNock, userKeyNock, backupKeyNock, walletNock]) {
                scope.done();
            }
        });
        it('should generate custodial onchain wallet without passing m, n, keys, keySignatures', async () => {
            const params = {
                label: 'test wallet',
                enterprise: 'myenterprise',
                type: 'custodial',
            };
            const walletNock = nock(bgUrl)
                .post('/api/v2/tbtc/wallet/add', function (body) {
                body.type.should.equal('custodial');
                should.not.exist(body.m);
                should.not.exist(body.n);
                should.not.exist(body.keys);
                should.not.exist(body.keySignatures);
                return true;
            })
                .reply(200, { id: '123', baseCoin: bitgo.coin('tbtc'), keys: ['123', '456', '789'] });
            nock(bgUrl).get('/api/v2/tbtc/key/123').reply(200, { pub: 'bitgoPub', id: '789' });
            nock(bgUrl).get('/api/v2/tbtc/key/456', _.matches({})).reply(200);
            nock(bgUrl).get('/api/v2/tbtc/key/789').reply(200, { pub: 'backupPub', id: '789' });
            const response = await wallets.generateWallet(params);
            walletNock.isDone().should.be.true();
            assert.ok(response.encryptedWalletPassphrase === undefined);
            assert.ok(response.wallet);
        });
        it('should generate hot onchain wallet', async () => {
            const params = {
                label: 'test wallet',
                passphrase: 'multisig password',
                enterprise: 'enterprise',
                passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
            };
            const walletNock = nock(bgUrl)
                .post('/api/v2/tbtc/wallet/add', function (body) {
                body.type.should.equal('hot');
                return true;
            })
                .reply(200);
            nock(bgUrl)
                .post('/api/v2/tbtc/key', _.matches({ source: 'bitgo' }))
                .reply(200, { pub: 'bitgoPub' });
            nock(bgUrl).post('/api/v2/tbtc/key', _.matches({})).reply(200);
            nock(bgUrl)
                .post('/api/v2/tbtc/key', _.matches({ source: 'backup' }))
                .reply(200, { pub: 'backupPub' });
            const response = await wallets.generateWallet(params);
            walletNock.isDone().should.be.true();
            assert.ok(response.encryptedWalletPassphrase);
            assert.ok(response.wallet);
            assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
        });
        it('should generate hot onchain wallet without passing multisig type', async () => {
            const params = {
                label: 'test wallet',
                passphrase: 'multisig password',
                enterprise: 'enterprise',
                passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
            };
            const walletNock = nock(bgUrl)
                .post('/api/v2/tbtc/wallet/add', function (body) {
                body.type.should.equal('hot');
                return true;
            })
                .reply(200);
            nock(bgUrl)
                .post('/api/v2/tbtc/key', _.matches({ source: 'bitgo' }))
                .reply(200, { pub: 'bitgoPub' });
            nock(bgUrl).post('/api/v2/tbtc/key', _.matches({})).reply(200);
            nock(bgUrl)
                .post('/api/v2/tbtc/key', _.matches({ source: 'backup' }))
                .reply(200, { pub: 'backupPub' });
            const generateWalletSpy = sandbox.spy(wallets, 'generateWallet');
            const response = await wallets.generateWallet(params);
            walletNock.isDone().should.be.true();
            sinon.assert.calledOnce(generateWalletSpy);
            assert.equal(generateWalletSpy.firstCall?.args[0]?.multisigType, sdk_core_1.multisigTypes.onchain);
            assert.ok(response.encryptedWalletPassphrase);
            assert.ok(response.wallet);
            assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
        });
        it('should generate Go Account wallet', async () => {
            const params = {
                label: 'Go Account Wallet',
                passphrase: 'go_account_password',
                enterprise: 'enterprise-id',
                passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
                type: 'trading',
            };
            const keychainId = 'user_keychain_id';
            // Mock keychain creation and upload
            nock(bgUrl)
                .post('/api/v2/ofc/key', function (body) {
                body.should.have.property('encryptedPrv');
                body.should.have.property('originalPasscodeEncryptionCode');
                body.keyType.should.equal('independent');
                body.source.should.equal('user');
                return true;
            })
                .reply(200, { id: keychainId, pub: 'userPub', encryptedPrv: 'encryptedPrivateKey' });
            // Mock wallet creation
            const walletNock = nock(bgUrl)
                .post('/api/v2/ofc/wallet/add', function (body) {
                body.type.should.equal('trading');
                body.m.should.equal(1);
                body.n.should.equal(1);
                body.keys.should.have.length(1);
                body.keys[0].should.equal(keychainId);
                return true;
            })
                .reply(200, { id: 'wallet123', keys: [keychainId] });
            const response = await ofcWallets.generateWallet(params);
            walletNock.isDone().should.be.true();
            assert.ok(response.encryptedWalletPassphrase);
            assert.ok(response.wallet);
            assert.ok('userKeychain' in response);
        });
    });
    describe('Generate TSS wallet:', function () {
        const tsol = bitgo.coin('tsol');
        const sandbox = sinon.createSandbox();
        beforeEach(function () {
            nock('https://bitgo.fakeurl')
                .get(`/api/v2/tss/settings`)
                .times(2)
                .reply(200, {
                coinSettings: {
                    eth: {
                        walletCreationSettings: {},
                    },
                    bsc: {
                        walletCreationSettings: {},
                    },
                    polygon: {
                        walletCreationSettings: {},
                    },
                },
            });
        });
        (0, mocha_1.afterEach)(function () {
            nock.cleanAll();
            sandbox.verifyAndRestore();
        });
        it('should create a new TSS wallet', async function () {
            const stubbedKeychainsTriplet = {
                userKeychain: {
                    id: '1',
                    pub: 'userPub',
                    type: 'independent',
                    source: 'user',
                },
                backupKeychain: {
                    id: '2',
                    pub: 'userPub',
                    type: 'independent',
                    source: 'backup',
                },
                bitgoKeychain: {
                    id: '3',
                    pub: 'userPub',
                    type: 'independent',
                    source: 'bitgo',
                },
            };
            sandbox.stub(sdk_core_1.TssUtils.prototype, 'createKeychains').resolves(stubbedKeychainsTriplet);
            const walletNock = nock('https://bitgo.fakeurl').post('/api/v2/tsol/wallet/add').reply(200);
            const wallets = new sdk_core_1.Wallets(bitgo, tsol);
            const params = {
                label: 'tss wallet',
                passphrase: 'tss password',
                multisigType: 'tss',
                enterprise: 'enterprise',
                passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
            };
            const response = await wallets.generateWallet(params);
            walletNock.isDone().should.be.true();
            assert.ok(response.encryptedWalletPassphrase);
            assert.ok(response.wallet);
            assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
        });
        it('should create a new TSS wallet without passing multisig type', async function () {
            const stubbedKeychainsTriplet = {
                userKeychain: {
                    id: '1',
                    pub: 'userPub',
                    type: 'independent',
                    source: 'user',
                },
                backupKeychain: {
                    id: '2',
                    pub: 'userPub',
                    type: 'independent',
                    source: 'backup',
                },
                bitgoKeychain: {
                    id: '3',
                    pub: 'userPub',
                    type: 'independent',
                    source: 'bitgo',
                },
            };
            sandbox.stub(sdk_core_1.TssUtils.prototype, 'createKeychains').resolves(stubbedKeychainsTriplet);
            const walletNock = nock('https://bitgo.fakeurl')
                .post('/api/v2/tsol/wallet/add', function (body) {
                body.multisigType.should.equal(sdk_core_1.multisigTypes.tss);
                return true;
            })
                .reply(200);
            const wallets = new sdk_core_1.Wallets(bitgo, tsol);
            const params = {
                label: 'tss wallet',
                passphrase: 'tss password',
                enterprise: 'enterprise',
                passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
            };
            const generateWalletSpy = sandbox.spy(wallets, 'generateWallet');
            const response = await wallets.generateWallet(params);
            walletNock.isDone().should.be.true();
            sinon.assert.calledOnce(generateWalletSpy);
            assert.equal(generateWalletSpy.firstCall?.args[0]?.multisigType, sdk_core_1.multisigTypes.tss);
            assert.ok(response.encryptedWalletPassphrase);
            assert.ok(response.wallet);
            assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
        });
        it('should create a new TSS wallet without providing passcodeEncryptionCode', async function () {
            const stubbedKeychainsTriplet = {
                userKeychain: {
                    id: '1',
                    pub: 'userPub',
                    type: 'independent',
                    source: 'user',
                },
                backupKeychain: {
                    id: '2',
                    pub: 'userPub',
                    type: 'independent',
                    source: 'backup',
                },
                bitgoKeychain: {
                    id: '3',
                    pub: 'userPub',
                    type: 'independent',
                    source: 'bitgo',
                },
            };
            sandbox.stub(sdk_core_1.TssUtils.prototype, 'createKeychains').resolves(stubbedKeychainsTriplet);
            const walletNock = nock('https://bitgo.fakeurl').post('/api/v2/tsol/wallet/add').reply(200);
            const wallets = new sdk_core_1.Wallets(bitgo, tsol);
            const response = await wallets.generateWallet({
                label: 'tss wallet',
                passphrase: 'tss password',
                multisigType: 'tss',
                enterprise: 'enterprise',
            });
            walletNock.isDone().should.be.true();
            assert.ok(response.wallet);
            assert.ok(response.encryptedWalletPassphrase === undefined);
        });
        it('should fail to create TSS wallet with invalid inputs', async function () {
            const tbtc = bitgo.coin('tbtc');
            const params = {
                label: 'my-cold-wallet',
                passphrase: 'test123',
                userKey: 'xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8',
                coldDerivationSeed: '123',
            };
            const wallets = new sdk_core_1.Wallets(bitgo, tbtc);
            nock(bgUrl)
                .post('/api/v2/tbtc/key', _.matches({ source: 'bitgo' }))
                .reply(200);
            nock(bgUrl)
                .post('/api/v2/tbtc/key', _.matches({ derivedFromParentWithSeed: params.coldDerivationSeed }))
                .reply(200);
            nock(bgUrl)
                .post('/api/v2/tbtc/key', _.matches({ source: 'backup' }))
                .reply(200);
            nock(bgUrl).post('/api/v2/tbtc/wallet/add').reply(200);
            // create a non tss wallet for coin that doesn't support tss even though multisigType is set to tss
            await wallets.generateWallet({ ...params, multisigType: 'tss' });
            const tsolWallets = new sdk_core_1.Wallets(bitgo, tsol);
            await tsolWallets
                .generateWallet({
                label: 'tss cold wallet',
                passphrase: 'passphrase',
                userKey: 'user key',
                multisigType: 'tss',
            })
                .should.be.rejectedWith('enterprise is required for TSS wallet');
            await tsolWallets
                .generateWallet({
                label: 'tss cold wallet',
                userKey: 'user key',
                multisigType: 'tss',
                enterprise: 'enterpriseId',
            })
                .should.be.rejectedWith('cannot generate TSS keys without passphrase');
        });
        it('should create a new TSS custodial wallet', async function () {
            const keys = ['1', '2', '3'];
            const walletParams = {
                label: 'tss wallet',
                multisigType: 'tss',
                enterprise: 'enterprise',
                type: 'custodial',
            };
            const walletNock = nock('https://bitgo.fakeurl')
                .post('/api/v2/tsol/wallet/add')
                .times(1)
                .reply(200, { ...walletParams, keys });
            const wallets = new sdk_core_1.Wallets(bitgo, tsol);
            const res = await wallets.generateWallet(walletParams);
            if (!(0, sdk_core_1.isWalletWithKeychains)(res)) {
                throw new Error('wallet missing required keychains');
            }
            res.wallet.label().should.equal(walletParams.label);
            should.equal(res.wallet.type(), walletParams.type);
            res.wallet.toJSON().enterprise.should.equal(walletParams.enterprise);
            res.wallet.multisigType().should.equal(walletParams.multisigType);
            res.userKeychain.id.should.equal(keys[0]);
            res.backupKeychain.id.should.equal(keys[1]);
            res.bitgoKeychain.id.should.equal(keys[2]);
            walletNock.isDone().should.be.true();
        });
        it('should create a new FLRP TSS custodial wallet without requiring a passphrase', async function () {
            const keys = ['1', '2', '3'];
            const tflrp = bitgo.coin('tflrp');
            const walletParams = {
                label: 'flrp custodial wallet',
                enterprise: 'enterprise',
                type: 'custodial',
                // No multisigType specified — should default to 'tss' for FLRP
                // No passphrase — custodial wallets must not require one
            };
            // FLRP is ECDSA, so generateCustodialMpcWallet fetches TSS settings
            nock('https://bitgo.fakeurl')
                .get('/api/v2/tss/settings')
                .reply(200, { coinSettings: { flrp: { walletCreationSettings: {} } } });
            const walletNock = nock('https://bitgo.fakeurl')
                .post('/api/v2/tflrp/wallet/add')
                .times(1)
                .reply(200, { ...walletParams, multisigType: 'tss', keys });
            const flrpWallets = new sdk_core_1.Wallets(bitgo, tflrp);
            const res = await flrpWallets.generateWallet(walletParams);
            if (!(0, sdk_core_1.isWalletWithKeychains)(res)) {
                throw new Error('wallet missing required keychains');
            }
            res.wallet.label().should.equal(walletParams.label);
            should.equal(res.wallet.type(), walletParams.type);
            res.wallet.multisigType().should.equal('tss');
            res.userKeychain.id.should.equal(keys[0]);
            res.backupKeychain.id.should.equal(keys[1]);
            res.bitgoKeychain.id.should.equal(keys[2]);
            walletNock.isDone().should.be.true();
        });
        it('should create a new TSS SMC wallet', async function () {
            const commonKeychain = 'longstring';
            const seed = 'seed';
            const keys = {
                userKeychain: {
                    id: '1',
                    commonKeychain,
                    type: 'tss',
                    derivedFromParentWithSeed: seed,
                    source: 'user',
                },
                backupKeychain: {
                    id: '2',
                    commonKeychain,
                    type: 'tss',
                    derivedFromParentWithSeed: seed,
                    source: 'backup',
                },
                bitgoKeychain: {
                    id: '3',
                    commonKeychain,
                    type: 'tss',
                    source: 'bitgo',
                },
            };
            const bitgoKeyNock = nock('https://bitgo.fakeurl').get('/api/v2/tsol/key/3').reply(200, keys.bitgoKeychain);
            const userKeyExpectedBody = {
                source: 'user',
                keyType: 'tss',
                commonKeychain,
                derivedFromParentWithSeed: seed,
            };
            const userKeyNock = nock('https://bitgo.fakeurl')
                .post('/api/v2/tsol/key', userKeyExpectedBody)
                .reply(200, keys.userKeychain);
            const backupKeyExpectedBody = {
                source: 'backup',
                keyType: 'tss',
                commonKeychain,
                derivedFromParentWithSeed: seed,
            };
            const backupKeyNock = nock('https://bitgo.fakeurl')
                .post('/api/v2/tsol/key', backupKeyExpectedBody)
                .reply(200, keys.backupKeychain);
            const walletParams = {
                label: 'tss wallet',
                multisigType: 'tss',
                enterprise: 'enterprise',
                type: 'cold',
                bitgoKeyId: keys.bitgoKeychain.id,
                commonKeychain,
                coldDerivationSeed: seed,
            };
            const walletNockExpected = {
                label: walletParams.label,
                m: 2,
                n: 3,
                keys: [keys.userKeychain.id, keys.backupKeychain.id, keys.bitgoKeychain.id],
                type: walletParams.type,
                multisigType: walletParams.multisigType,
                enterprise: walletParams.enterprise,
                walletVersion: undefined,
            };
            const walletNock = nock('https://bitgo.fakeurl')
                .post('/api/v2/tsol/wallet/add', walletNockExpected)
                .reply(200, { ...walletNockExpected, responseType: 'WalletWithKeychains' });
            const wallets = new sdk_core_1.Wallets(bitgo, tsol);
            const res = await wallets.generateWallet(walletParams);
            if (!(0, sdk_core_1.isWalletWithKeychains)(res)) {
                throw new Error('wallet missing required keychains');
            }
            res.responseType.should.equal('WalletWithKeychains');
            res.wallet.label().should.equal(walletParams.label);
            should.equal(res.wallet.type(), walletParams.type);
            res.wallet.toJSON().enterprise.should.equal(walletParams.enterprise);
            res.wallet.multisigType().should.equal(walletParams.multisigType);
            res.userKeychain.should.deepEqual(keys.userKeychain);
            res.backupKeychain.should.deepEqual(keys.backupKeychain);
            res.bitgoKeychain.should.deepEqual(keys.bitgoKeychain);
            bitgoKeyNock.isDone().should.be.true();
            userKeyNock.isDone().should.be.true();
            backupKeyNock.isDone().should.be.true();
            walletNock.isDone().should.be.true();
        });
        it('should throw an error for TSS SMC wallet if the bitgoKeyId is not a bitgo key ', async function () {
            const commonKeychain = 'longstring';
            const seed = 'seed';
            const keys = {
                userKeychain: {
                    id: '1',
                    commonKeychain,
                    type: 'tss',
                    derivedFromParentWithSeed: seed,
                    source: 'user',
                },
                backupKeychain: {
                    id: '2',
                    commonKeychain,
                    type: 'tss',
                    derivedFromParentWithSeed: seed,
                    source: 'backup',
                },
                bitgoKeychain: {
                    id: '3',
                    commonKeychain,
                    type: 'tss',
                    source: 'bitgo',
                },
            };
            const bitgoKeyNock = nock('https://bitgo.fakeurl').get('/api/v2/tsol/key/1').reply(200, keys.userKeychain);
            const walletParams = {
                label: 'tss wallet',
                multisigType: 'tss',
                enterprise: 'enterprise',
                type: 'cold',
                bitgoKeyId: keys.userKeychain.id,
                commonKeychain,
                coldDerivationSeed: seed,
            };
            const wallets = new sdk_core_1.Wallets(bitgo, tsol);
            await wallets
                .generateWallet(walletParams)
                .should.be.rejectedWith('The provided bitgoKeyId is not a BitGo keychain');
            bitgoKeyNock.isDone().should.be.true();
        });
    });
    describe('Generate TSS MPCv2 wallet:', async function () {
        const sandbox = sinon.createSandbox();
        beforeEach(function () {
            const tssSettings = {
                coinSettings: {
                    eth: {
                        walletCreationSettings: {
                            multiSigTypeVersion: 'MPCv2',
                            coldMultiSigTypeVersion: 'MPCv2',
                            custodialMultiSigTypeVersion: 'MPCv2',
                        },
                    },
                    bsc: {
                        walletCreationSettings: {
                            multiSigTypeVersion: 'MPCv2',
                            coldMultiSigTypeVersion: 'MPCv2',
                            custodialMultiSigTypeVersion: 'MPCv2',
                        },
                    },
                    polygon: {
                        walletCreationSettings: {
                            multiSigTypeVersion: 'MPCv2',
                            coldMultiSigTypeVersion: 'MPCv2',
                            custodialMultiSigTypeVersion: 'MPCv2',
                        },
                    },
                    atom: {
                        walletCreationSettings: {
                            multiSigTypeVersion: 'MPCv2',
                            coldMultiSigTypeVersion: 'MPCv2',
                            custodialMultiSigTypeVersion: 'MPCv2',
                        },
                    },
                    tia: {
                        walletCreationSettings: {
                            multiSigTypeVersion: 'MPCv2',
                            coldMultiSigTypeVersion: 'MPCv2',
                            custodialMultiSigTypeVersion: 'MPCv2',
                        },
                    },
                    bera: {
                        walletCreationSettings: {
                            multiSigTypeVersion: 'MPCv2',
                            coldMultiSigTypeVersion: 'MPCv2',
                            custodialMultiSigTypeVersion: 'MPCv2',
                        },
                    },
                    arbeth: {
                        walletCreationSettings: {
                            multiSigTypeVersion: 'MPCv2',
                            coldMultiSigTypeVersion: 'MPCv2',
                            custodialMultiSigTypeVersion: 'MPCv2',
                        },
                    },
                    opeth: {
                        walletCreationSettings: {
                            multiSigTypeVersion: 'MPCv2',
                            coldMultiSigTypeVersion: 'MPCv2',
                            custodialMultiSigTypeVersion: 'MPCv2',
                        },
                    },
                },
            };
            nock('https://bitgo.fakeurl').get(`/api/v2/tss/settings`).times(2).reply(200, tssSettings);
        });
        (0, mocha_1.afterEach)(function () {
            nock.cleanAll();
            sandbox.verifyAndRestore();
        });
        ['hteth', 'tbsc', 'tpolygon', 'ttia', 'tatom', 'tbera', 'tarbeth', 'topeth'].forEach((coin) => {
            it(`should create a new ${coin} TSS MPCv2 hot wallet`, async function () {
                const testCoin = bitgo.coin(coin);
                const stubbedKeychainsTriplet = {
                    userKeychain: {
                        id: '1',
                        commonKeychain: 'userPub',
                        type: 'tss',
                        source: 'user',
                    },
                    backupKeychain: {
                        id: '2',
                        commonKeychain: 'userPub',
                        type: 'tss',
                        source: 'backup',
                    },
                    bitgoKeychain: {
                        id: '3',
                        commonKeychain: 'userPub',
                        type: 'tss',
                        source: 'bitgo',
                    },
                };
                const stubCreateKeychains = sandbox
                    .stub(sdk_core_1.ECDSAUtils.EcdsaMPCv2Utils.prototype, 'createKeychains')
                    .resolves(stubbedKeychainsTriplet);
                const walletNock = nock('https://bitgo.fakeurl').post(`/api/v2/${coin}/wallet/add`).reply(200);
                const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
                const params = {
                    label: 'tss wallet',
                    passphrase: 'tss password',
                    multisigType: 'tss',
                    enterprise: 'enterprise',
                    passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
                    walletVersion: 3,
                };
                const response = await wallets.generateWallet(params);
                walletNock.isDone().should.be.true();
                stubCreateKeychains.calledOnce.should.be.true();
                assert.ok(response.encryptedWalletPassphrase);
                assert.ok(response.wallet);
                assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
            });
            it(`should create a new ${coin} TSS MPCv2 hot wallet without passing multisig type`, async function () {
                const testCoin = bitgo.coin(coin);
                const stubbedKeychainsTriplet = {
                    userKeychain: {
                        id: '1',
                        commonKeychain: 'userPub',
                        type: 'tss',
                        source: 'user',
                    },
                    backupKeychain: {
                        id: '2',
                        commonKeychain: 'userPub',
                        type: 'tss',
                        source: 'backup',
                    },
                    bitgoKeychain: {
                        id: '3',
                        commonKeychain: 'userPub',
                        type: 'tss',
                        source: 'bitgo',
                    },
                };
                const stubCreateKeychains = sandbox
                    .stub(sdk_core_1.ECDSAUtils.EcdsaMPCv2Utils.prototype, 'createKeychains')
                    .resolves(stubbedKeychainsTriplet);
                const walletNock = nock('https://bitgo.fakeurl')
                    .post(`/api/v2/${coin}/wallet/add`, function (body) {
                    body.multisigType.should.equal(sdk_core_1.multisigTypes.tss);
                    return true;
                })
                    .reply(200);
                const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
                const params = {
                    label: 'tss wallet',
                    passphrase: 'tss password',
                    enterprise: 'enterprise',
                    passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
                    walletVersion: 3,
                };
                const response = await wallets.generateWallet(params);
                walletNock.isDone().should.be.true();
                stubCreateKeychains.calledOnce.should.be.true();
                assert.ok(response.encryptedWalletPassphrase);
                assert.ok(response.wallet);
                assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
            });
            it(`should create a new ${coin} TSS MPCv2 cold wallet`, async function () {
                const testCoin = bitgo.coin(coin);
                const bitgoKeyId = 'key123';
                const commonKeychain = '0xabc';
                const bitgoKeyNock = nock('https://bitgo.fakeurl')
                    .get(`/api/v2/${coin}/key/${bitgoKeyId}`)
                    .times(1)
                    .reply(200, {
                    id: 'key123',
                    pub: 'bitgoPub',
                    type: 'tss',
                    source: 'bitgo',
                    commonKeychain,
                });
                const userKeyNock = nock('https://bitgo.fakeurl')
                    .post(`/api/v2/${coin}/key`, {
                    source: 'user',
                    keyType: 'tss',
                    commonKeychain,
                    derivedFromParentWithSeed: '37',
                    isMPCv2: true,
                })
                    .times(1)
                    .reply(200, {
                    id: 'userKey123',
                    pub: 'userPub',
                    type: 'tss',
                    source: 'user',
                });
                const backupKeyNock = nock('https://bitgo.fakeurl')
                    .post(`/api/v2/${coin}/key`, {
                    source: 'backup',
                    keyType: 'tss',
                    commonKeychain,
                    derivedFromParentWithSeed: '37',
                    isMPCv2: true,
                })
                    .times(1)
                    .reply(200, {
                    id: 'backupKey123',
                    pub: 'backupPub',
                    type: 'tss',
                    source: 'backup',
                });
                const walletNock = nock('https://bitgo.fakeurl')
                    .post(`/api/v2/${coin}/wallet/add`, {
                    label: 'tss wallet',
                    m: 2,
                    n: 3,
                    keys: ['userKey123', 'backupKey123', 'key123'],
                    type: 'cold',
                    multisigType: 'tss',
                    enterprise: 'enterprise',
                    walletVersion: 5,
                })
                    .reply(200);
                const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
                const params = {
                    label: 'tss wallet',
                    multisigType: 'tss',
                    enterprise: 'enterprise',
                    passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
                    walletVersion: 5,
                    type: 'cold',
                    bitgoKeyId: 'key123',
                    commonKeychain: '0xabc',
                    coldDerivationSeed: '37',
                };
                const response = (await wallets.generateWallet(params));
                bitgoKeyNock.isDone().should.be.true();
                userKeyNock.isDone().should.be.true();
                backupKeyNock.isDone().should.be.true();
                walletNock.isDone().should.be.true();
                should.exist(response.wallet);
                should.exist(response.userKeychain);
                should.exist(response.backupKeychain);
                should.exist(response.bitgoKeychain);
                response.responseType.should.equal('WalletWithKeychains');
                response.userKeychain.id.should.equal('userKey123');
                response.backupKeychain.id.should.equal('backupKey123');
                response.bitgoKeychain.id.should.equal('key123');
            });
            it(`should create a new ${coin} TSS MPCv2 custody wallet`, async function () {
                const testCoin = bitgo.coin(coin);
                const keys = ['userKey', 'backupKey', 'bitgoKey'];
                const params = {
                    label: 'tss wallet',
                    passphrase: 'tss password',
                    multisigType: 'tss',
                    enterprise: 'enterprise',
                    passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
                    walletVersion: 5,
                    type: 'custodial',
                };
                const walletNock = nock('https://bitgo.fakeurl')
                    .post(`/api/v2/${coin}/wallet/add`)
                    .times(1)
                    .reply(200, { ...params, keys });
                const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
                const response = (await wallets.generateWallet(params));
                walletNock.isDone().should.be.true();
                should.exist(response.wallet);
                should.exist(response.userKeychain);
                should.exist(response.backupKeychain);
                should.exist(response.bitgoKeychain);
                response.responseType.should.equal('WalletWithKeychains');
                response.userKeychain.id.should.equal(keys[0]);
                response.backupKeychain.id.should.equal(keys[1]);
                response.bitgoKeychain.id.should.equal(keys[2]);
            });
        });
        it(`should create a new hteth TSS MPCv2 wallet with walletVersion 6`, async function () {
            const testCoin = bitgo.coin('hteth');
            const stubbedKeychainsTriplet = {
                userKeychain: {
                    id: '1',
                    commonKeychain: 'userPub',
                    type: 'tss',
                    source: 'user',
                },
                backupKeychain: {
                    id: '2',
                    commonKeychain: 'userPub',
                    type: 'tss',
                    source: 'backup',
                },
                bitgoKeychain: {
                    id: '3',
                    commonKeychain: 'userPub',
                    type: 'tss',
                    source: 'bitgo',
                },
            };
            const stubCreateKeychains = sandbox
                .stub(sdk_core_1.ECDSAUtils.EcdsaMPCv2Utils.prototype, 'createKeychains')
                .resolves(stubbedKeychainsTriplet);
            const walletNock = nock('https://bitgo.fakeurl')
                .post(`/api/v2/hteth/wallet/add`, (body) => {
                body.walletVersion.should.equal(6);
                return true;
            })
                .reply(200);
            const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
            const params = {
                label: 'tss wallet',
                passphrase: 'tss password',
                multisigType: 'tss',
                enterprise: 'enterprise',
                passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
                walletVersion: 6,
            };
            const response = await wallets.generateWallet(params);
            walletNock.isDone().should.be.true();
            stubCreateKeychains.calledOnce.should.be.true();
            assert.ok(response.encryptedWalletPassphrase);
            assert.ok(response.wallet);
            assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
        });
        it(`should create a new MPCv2 wallet with version 5 if walletVersion passed is not 5 or 6`, async function () {
            const testCoin = bitgo.coin('hteth');
            const stubbedKeychainsTriplet = {
                userKeychain: {
                    id: '1',
                    commonKeychain: 'userPub',
                    type: 'tss',
                    source: 'user',
                },
                backupKeychain: {
                    id: '2',
                    commonKeychain: 'userPub',
                    type: 'tss',
                    source: 'backup',
                },
                bitgoKeychain: {
                    id: '3',
                    commonKeychain: 'userPub',
                    type: 'tss',
                    source: 'bitgo',
                },
            };
            const stubCreateKeychains = sandbox
                .stub(sdk_core_1.ECDSAUtils.EcdsaMPCv2Utils.prototype, 'createKeychains')
                .resolves(stubbedKeychainsTriplet);
            const walletNock = nock('https://bitgo.fakeurl')
                .post(`/api/v2/hteth/wallet/add`, (body) => {
                body.walletVersion.should.equal(5);
                return true;
            })
                .reply(200);
            const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
            const params = {
                label: 'tss wallet',
                passphrase: 'tss password',
                multisigType: 'tss',
                enterprise: 'enterprise',
                passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
                walletVersion: 3,
            };
            const response = await wallets.generateWallet(params);
            walletNock.isDone().should.be.true();
            stubCreateKeychains.calledOnce.should.be.true();
            assert.ok(response.encryptedWalletPassphrase);
            assert.ok(response.wallet);
            assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
        });
    });
    describe('Generate TSS EdDSA MPCv2 wallet:', async function () {
        const sandbox = sinon.createSandbox();
        beforeEach(function () {
            const tssSettings = {
                coinSettings: {
                    sol: {
                        walletCreationSettings: {
                            multiSigTypeVersion: 'MPCv2',
                        },
                    },
                },
            };
            nock('https://bitgo.fakeurl').get(`/api/v2/tss/settings`).times(2).reply(200, tssSettings);
        });
        (0, mocha_1.afterEach)(function () {
            nock.cleanAll();
            sandbox.verifyAndRestore();
        });
        it('should create a new tsol TSS EdDSA MPCv2 hot wallet', async function () {
            const testCoin = bitgo.coin('tsol');
            const stubbedKeychainsTriplet = {
                userKeychain: {
                    id: '1',
                    commonKeychain: 'userPub',
                    type: 'tss',
                    source: 'user',
                },
                backupKeychain: {
                    id: '2',
                    commonKeychain: 'userPub',
                    type: 'tss',
                    source: 'backup',
                },
                bitgoKeychain: {
                    id: '3',
                    commonKeychain: 'userPub',
                    type: 'tss',
                    source: 'bitgo',
                },
            };
            const stubCreateKeychains = sandbox
                .stub(sdk_core_1.EDDSAUtils.EddsaMPCv2Utils.prototype, 'createKeychains')
                .resolves(stubbedKeychainsTriplet);
            const walletNock = nock('https://bitgo.fakeurl').post('/api/v2/tsol/wallet/add').reply(200);
            const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
            const params = {
                label: 'tss eddsa mpcv2 wallet',
                passphrase: 'tss password',
                multisigType: 'tss',
                enterprise: 'enterprise',
                passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
            };
            const response = await wallets.generateWallet(params);
            walletNock.isDone().should.be.true();
            stubCreateKeychains.calledOnce.should.be.true();
            assert.ok(response.encryptedWalletPassphrase);
            assert.ok(response.wallet);
            assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
        });
        it('should fall back to EddsaUtils when tss/settings does not return MPCv2 for tsol', async function () {
            nock.cleanAll();
            nock('https://bitgo.fakeurl')
                .get('/api/v2/tss/settings')
                .reply(200, { coinSettings: { sol: { walletCreationSettings: {} } } });
            const testCoin = bitgo.coin('tsol');
            const stubbedKeychainsTriplet = {
                userKeychain: {
                    id: '1',
                    commonKeychain: 'userPub',
                    type: 'tss',
                    source: 'user',
                },
                backupKeychain: {
                    id: '2',
                    commonKeychain: 'userPub',
                    type: 'tss',
                    source: 'backup',
                },
                bitgoKeychain: {
                    id: '3',
                    commonKeychain: 'userPub',
                    type: 'tss',
                    source: 'bitgo',
                },
            };
            const stubEddsaUtils = sandbox
                .stub(sdk_core_1.EDDSAUtils.default.prototype, 'createKeychains')
                .resolves(stubbedKeychainsTriplet);
            const walletNock = nock('https://bitgo.fakeurl').post('/api/v2/tsol/wallet/add').reply(200);
            const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
            const params = {
                label: 'tss eddsa wallet',
                passphrase: 'tss password',
                multisigType: 'tss',
                enterprise: 'enterprise',
                passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
            };
            const response = await wallets.generateWallet(params);
            walletNock.isDone().should.be.true();
            stubEddsaUtils.calledOnce.should.be.true();
            assert.ok(response.encryptedWalletPassphrase);
            assert.ok(response.wallet);
        });
    });
    describe('Sharing', () => {
        describe('Wallet share where keychainOverrideRequired is set true', () => {
            const sandbox = sinon.createSandbox();
            (0, mocha_1.afterEach)(function () {
                sandbox.verifyAndRestore();
            });
            it('when password not provived we should receive validation error', async function () {
                const shareId = 'test_case_1';
                const walletShareNock = nock(bgUrl)
                    .get(`/api/v2/ofc/walletshare/${shareId}`)
                    .reply(200, {
                    keychainOverrideRequired: true,
                    permissions: ['admin', 'spend', 'view'],
                });
                // Validate accept share case
                await ofcWallets
                    .acceptShare({ walletShareId: shareId })
                    .should.be.rejectedWith('userPassword param must be provided to decrypt shared key');
                walletShareNock.done();
            });
            it('when we accept share and failed to make changes, reshare should not be called', async function () {
                const shareId = 'test_case_2';
                const keychainId = 'test_case_2';
                const userPassword = 'test_case_2';
                // create a user key
                const keyChainNock = nock(bgUrl)
                    .post('/api/v2/ofc/key', _.conforms({ pub: (p) => p.startsWith('xpub') }))
                    .reply(200, (uri, requestBody) => {
                    return { id: keychainId, encryptedPrv: requestBody['encryptedPrv'], pub: requestBody['pub'] };
                });
                const walletShareInfoNock = nock(bgUrl)
                    .get(`/api/v2/ofc/walletshare/${shareId}`)
                    .reply(200, {
                    keychainOverrideRequired: true,
                    permissions: ['admin', 'spend', 'view'],
                });
                const acceptShareNock = nock(bgUrl)
                    .post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
                    // Check required fields are present (signature and payload are dynamic)
                    return (body.walletShareId === shareId &&
                        body.state === 'accepted' &&
                        body.keyId === keychainId &&
                        typeof body.signature === 'string' &&
                        typeof body.payload === 'string');
                })
                    .reply(200, { changed: false });
                // Stub wallet share wallet method
                const walletShareStub = sandbox.stub(sdk_core_1.Wallet.prototype, 'shareWallet').onCall(0).resolves('success');
                const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
                should.equal(res.changed, false);
                keyChainNock.done();
                walletShareInfoNock.done();
                acceptShareNock.done();
                should.equal(walletShareStub.called, false);
            });
            it('when we accept share but state is not valid, reshare should not be called', async function () {
                const shareId = 'test_case_3';
                const keychainId = 'test_case_3';
                const userPassword = 'test_case_3';
                // create a user key
                const keyChainNock = nock(bgUrl)
                    .post('/api/v2/ofc/key', _.conforms({ pub: (p) => p.startsWith('xpub') }))
                    .reply(200, (uri, requestBody) => {
                    return { id: keychainId, encryptedPrv: requestBody['encryptedPrv'], pub: requestBody['pub'] };
                });
                const walletShareInfoNock = nock(bgUrl)
                    .get(`/api/v2/ofc/walletshare/${shareId}`)
                    .reply(200, {
                    keychainOverrideRequired: true,
                    permissions: ['admin', 'spend', 'view'],
                });
                const acceptShareNock = nock(bgUrl)
                    .post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
                    // Check required fields are present (signature and payload are dynamic)
                    return (body.walletShareId === shareId &&
                        body.state === 'accepted' &&
                        body.keyId === keychainId &&
                        typeof body.signature === 'string' &&
                        typeof body.payload === 'string');
                })
                    .reply(200, { changed: true, state: 'not_accepted' });
                // Stub wallet share wallet method
                const walletShareStub = sandbox.stub(sdk_core_1.Wallet.prototype, 'shareWallet').onCall(0).resolves('success');
                const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
                should.equal(res.changed, true);
                should.equal(res.state, 'not_accepted');
                keyChainNock.done();
                walletShareInfoNock.done();
                acceptShareNock.done();
                should.equal(walletShareStub.called, false);
            });
            it('when we get a correct resposne from accept share method, but failed to reshare wallet with spenders', async function () {
                const shareId = 'test_case_6';
                const keychainId = 'test_case_6';
                const spenderUserOne = {
                    payload: {
                        permissions: ['spend', 'view'],
                        user: 'test_case_6',
                    },
                    email: { email: 'test_case_6' },
                    id: 'test_case_6',
                    coin: 'ofc',
                };
                const spenderUserTwo = {
                    payload: {
                        permissions: ['spend', 'view'],
                        user: 'test_case_9',
                    },
                    email: { email: 'test_case_9' },
                    id: 'test_case_9',
                    coin: 'ofc',
                };
                const adminUser = {
                    payload: {
                        permissions: ['admin', 'spend', 'view'],
                        user: 'test_case_7',
                    },
                    email: { email: 'test_case_7' },
                    id: 'test_case_7',
                    coin: 'ofc',
                };
                const viewerUser = {
                    payload: {
                        permissions: ['view'],
                        user: 'test_case_8',
                    },
                    email: { email: 'test_case_8' },
                    id: 'test_case_8',
                    coin: 'ofc',
                };
                const userPassword = 'test_case_6';
                const walletId = 'test_case_6';
                const enterpriseId = 'test_case_6';
                const walletShareNock = nock(bgUrl)
                    .get(`/api/v2/ofc/walletshare/${shareId}`)
                    .reply(200, {
                    keychainOverrideRequired: true,
                    permissions: ['admin', 'spend', 'view'],
                    wallet: walletId,
                });
                // create a user key
                const keyChainCreateNock = nock(bgUrl)
                    .post('/api/v2/ofc/key', _.conforms({ pub: (p) => p.startsWith('xpub') }))
                    .reply(200, (uri, requestBody) => {
                    return { id: keychainId, encryptedPrv: requestBody['encryptedPrv'], pub: requestBody['pub'] };
                });
                const acceptShareNock = nock(bgUrl)
                    .post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
                    // Check required fields are present (signature and payload are dynamic)
                    return (body.walletShareId === shareId &&
                        body.state === 'accepted' &&
                        body.keyId === keychainId &&
                        typeof body.signature === 'string' &&
                        typeof body.payload === 'string');
                })
                    .reply(200, { changed: true, state: 'accepted' });
                const walletInfoNock = nock(bgUrl)
                    .get(`/api/v2/ofc/wallet/${walletId}`)
                    .reply(200, {
                    users: [spenderUserOne.payload, spenderUserTwo.payload, adminUser.payload, viewerUser.payload],
                    enterprise: enterpriseId,
                    coin: spenderUserOne.coin,
                    id: walletId,
                    keys: [{}],
                });
                const enterpriseUserNock = nock(bgUrl)
                    .get(`/api/v1/enterprise/${enterpriseId}/user`)
                    .reply(200, {
                    adminUsers: [
                        { id: spenderUserOne.id, email: spenderUserOne.email },
                        { id: spenderUserTwo.id, email: spenderUserTwo.email },
                        { id: adminUser.id, email: adminUser.email },
                        { id: viewerUser.id, email: viewerUser.email },
                    ],
                    nonAdminUsers: [],
                });
                const walletShareStub = sandbox
                    .stub(sdk_core_1.Wallet.prototype, 'shareWallet')
                    .returns(new Promise((_resolve, reject) => reject(new Error('Failed to reshare wallet'))));
                const shareParamsOne = {
                    walletId: walletId,
                    user: spenderUserOne.id,
                    permissions: spenderUserOne.payload.permissions.join(','),
                    walletPassphrase: userPassword,
                    email: spenderUserOne.email.email,
                    reshare: true,
                    skipKeychain: false,
                };
                const shareParamsTwo = {
                    walletId: walletId,
                    user: spenderUserTwo.id,
                    permissions: spenderUserTwo.payload.permissions.join(','),
                    walletPassphrase: userPassword,
                    email: spenderUserTwo.email.email,
                    reshare: true,
                    skipKeychain: false,
                };
                const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
                should.equal(res.changed, true);
                should.equal(res.state, 'accepted');
                keyChainCreateNock.done();
                walletShareNock.done();
                walletInfoNock.done();
                acceptShareNock.done();
                enterpriseUserNock.done();
                should.equal(walletShareStub.calledOnce, true);
                should.equal(walletShareStub.calledWith(shareParamsOne), true);
                should.equal(walletShareStub.calledWith(shareParamsTwo), false);
            });
            it('when we get a correct resposne from accept share method and reshare wallet with spenders', async function () {
                const shareId = 'test_case_6';
                const keychainId = 'test_case_6';
                const spenderUserOne = {
                    payload: {
                        permissions: ['spend', 'view'],
                        user: 'test_case_6',
                    },
                    email: { email: 'test_case_6' },
                    id: 'test_case_6',
                    coin: 'ofc',
                };
                const spenderUserTwo = {
                    payload: {
                        permissions: ['spend', 'view'],
                        user: 'test_case_9',
                    },
                    email: { email: 'test_case_9' },
                    id: 'test_case_9',
                    coin: 'ofc',
                };
                const adminUser = {
                    payload: {
                        permissions: ['admin', 'spend', 'view'],
                        user: 'test_case_7',
                    },
                    email: { email: 'test_case_7' },
                    id: 'test_case_7',
                    coin: 'ofc',
                };
                const viewerUser = {
                    payload: {
                        permissions: ['view'],
                        user: 'test_case_8',
                    },
                    email: { email: 'test_case_8' },
                    id: 'test_case_8',
                    coin: 'ofc',
                };
                const userPassword = 'test_case_6';
                const walletId = 'test_case_6';
                const enterpriseId = 'test_case_6';
                const walletShareNock = nock(bgUrl)
                    .get(`/api/v2/tbtc/walletshare/${shareId}`)
                    .reply(200, {
                    keychainOverrideRequired: true,
                    permissions: ['admin', 'spend', 'view'],
                    wallet: walletId,
                });
                // create a user key
                const keyChainCreateNock = nock(bgUrl)
                    .post('/api/v2/tbtc/key', _.conforms({ pub: (p) => p.startsWith('xpub') }))
                    .reply(200, (uri, requestBody) => {
                    return { id: keychainId, encryptedPrv: requestBody['encryptedPrv'], pub: requestBody['pub'] };
                });
                const acceptShareNock = nock(bgUrl)
                    .post(`/api/v2/tbtc/walletshare/${shareId}`, (body) => {
                    // Check required fields are present (signature and payload are dynamic)
                    return (body.walletShareId === shareId &&
                        body.state === 'accepted' &&
                        body.keyId === keychainId &&
                        typeof body.signature === 'string' &&
                        typeof body.payload === 'string');
                })
                    .reply(200, { changed: true, state: 'accepted' });
                const walletInfoNock = nock(bgUrl)
                    .get(`/api/v2/tbtc/wallet/${walletId}`)
                    .reply(200, {
                    users: [spenderUserOne.payload, spenderUserTwo.payload, adminUser.payload, viewerUser.payload],
                    enterprise: enterpriseId,
                    coin: spenderUserOne.coin,
                    id: walletId,
                    keys: [{}],
                });
                const enterpriseUserNock = nock(bgUrl)
                    .get(`/api/v1/enterprise/${enterpriseId}/user`)
                    .reply(200, {
                    adminUsers: [
                        { id: spenderUserOne.id, email: spenderUserOne.email },
                        { id: spenderUserTwo.id, email: spenderUserTwo.email },
                        { id: adminUser.id, email: adminUser.email },
                        { id: viewerUser.id, email: viewerUser.email },
                    ],
                    nonAdminUsers: [],
                });
                const walletShareStub = sandbox
                    .stub(sdk_core_1.Wallet.prototype, 'shareWallet')
                    .returns(new Promise((resolve, _reject) => resolve('success')));
                const shareParamsOne = {
                    walletId: walletId,
                    user: spenderUserOne.id,
                    permissions: spenderUserOne.payload.permissions.join(','),
                    walletPassphrase: userPassword,
                    email: spenderUserOne.email.email,
                    reshare: true,
                    skipKeychain: false,
                };
                const shareParamsTwo = {
                    walletId: walletId,
                    user: spenderUserTwo.id,
                    permissions: spenderUserTwo.payload.permissions.join(','),
                    walletPassphrase: userPassword,
                    email: spenderUserTwo.email.email,
                    reshare: true,
                    skipKeychain: false,
                };
                const res = await wallets.acceptShare({ walletShareId: shareId, userPassword });
                should.equal(res.changed, true);
                should.equal(res.state, 'accepted');
                keyChainCreateNock.done();
                walletShareNock.done();
                walletInfoNock.done();
                acceptShareNock.done();
                enterpriseUserNock.done();
                should.equal(walletShareStub.calledTwice, true);
                should.equal(walletShareStub.calledWith(shareParamsOne), true);
                should.equal(walletShareStub.calledWith(shareParamsTwo), true);
            });
        });
        describe('Wallet share where userMultiKeyRotationRequired is set true', () => {
            const sandbox = sinon.createSandbox();
            (0, mocha_1.afterEach)(function () {
                sandbox.verifyAndRestore();
            });
            it('should throw error when password not provided', async function () {
                const shareId = 'test_multi_key_1';
                const walletShareNock = nock(bgUrl)
                    .get(`/api/v2/ofc/walletshare/${shareId}`)
                    .reply(200, {
                    userMultiKeyRotationRequired: true,
                    permissions: ['admin', 'spend', 'view'],
                });
                await ofcWallets
                    .acceptShare({ walletShareId: shareId })
                    .should.be.rejectedWith('userPassword param must be provided to generate user keychain');
                walletShareNock.done();
            });
            it('should successfully accept share with userMultiKeyRotationRequired and send pub and encryptedPrv', async function () {
                const shareId = 'test_multi_key_2';
                const userPassword = 'test_password_123';
                const walletId = 'test_wallet_123';
                // Mock wallet share response
                const walletShareNock = nock(bgUrl)
                    .get(`/api/v2/ofc/walletshare/${shareId}`)
                    .reply(200, {
                    userMultiKeyRotationRequired: true,
                    permissions: ['admin', 'spend', 'view'],
                    wallet: walletId,
                });
                // Mock keychain creation - baseCoin.keychains().create() returns { prv, pub }
                // We need to create a proper keychain object with prv property
                const testKeychain = bitgo.coin('ofc').keychains().create();
                const keychain = {
                    prv: testKeychain.prv, // OFC uses secp256k1 keys, so prv format
                    pub: testKeychain.pub,
                };
                // Stub keychains().create() and encrypt() BEFORE calculating encryptedPrv
                const keychainsInstance = ofcWallets.baseCoin.keychains();
                const keychainsStub = sandbox.stub(keychainsInstance, 'create').returns(keychain);
                const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: userPassword });
                const encryptStub = sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
                // Mock the updateShare API call
                const acceptShareNock = nock(bgUrl)
                    .post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
                    // Verify that pub and encryptedPrv are included
                    if (body.walletShareId !== shareId || body.state !== 'accepted' || !body.pub || !body.encryptedPrv) {
                        return false;
                    }
                    // Verify pub is a valid format (secp256k1 public key for OFC)
                    if (!ofcWallets.baseCoin.isValidPub(body.pub)) {
                        return false;
                    }
                    return true;
                })
                    .reply(200, { changed: true, state: 'accepted' });
                const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
                should.equal(res.changed, true);
                should.equal(res.state, 'accepted');
                // Verify keychain creation was called
                should.equal(keychainsStub.calledOnce, true);
                // Verify encrypt was called with the correct parameters
                should.equal(encryptStub.calledWith({ input: keychain.prv, password: userPassword }), true);
                walletShareNock.done();
                acceptShareNock.done();
            });
            it('should NOT trigger reshare when userMultiKeyRotationRequired is true', async function () {
                const shareId = 'test_multi_key_3';
                const userPassword = 'test_password_123';
                const walletId = 'test_wallet_123';
                const walletShareNock = nock(bgUrl)
                    .get(`/api/v2/ofc/walletshare/${shareId}`)
                    .reply(200, {
                    userMultiKeyRotationRequired: true,
                    permissions: ['admin', 'spend', 'view'],
                    wallet: walletId,
                });
                const testKeychain = bitgo.coin('ofc').keychains().create();
                const keychain = {
                    prv: testKeychain.prv,
                    pub: testKeychain.pub,
                };
                const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: userPassword });
                const acceptShareNock = nock(bgUrl)
                    .post(`/api/v2/ofc/walletshare/${shareId}`)
                    .reply(200, { changed: true, state: 'accepted' });
                const keychainsInstance = ofcWallets.baseCoin.keychains();
                sandbox.stub(keychainsInstance, 'create').returns(keychain);
                sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
                // Stub reshareWalletWithSpenders to verify it's NOT called
                const reshareStub = sandbox.stub(sdk_core_1.Wallets.prototype, 'reshareWalletWithSpenders');
                const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
                should.equal(res.changed, true);
                should.equal(res.state, 'accepted');
                // Verify reshare was NOT called (unlike keychainOverrideRequired case)
                should.equal(reshareStub.called, false);
                walletShareNock.done();
                acceptShareNock.done();
            });
            it('should handle bulk accept share with userMultiKeyRotationRequired', async function () {
                const shareId = 'test_multi_key_bulk_1';
                const userPassword = 'test_password_123';
                // Mock listSharesV2 to return a share with userMultiKeyRotationRequired
                // Note: userMultiKeyRotationRequired shares don't have a keychain, so they won't be filtered
                // by the bulkAcceptShare filter, but processAcceptShare will handle them
                sandbox.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
                    incoming: [
                        {
                            id: shareId,
                            coin: 'ofc',
                            walletLabel: 'test wallet',
                            fromUser: 'fromUser',
                            toUser: 'toUser',
                            wallet: 'wallet123',
                            permissions: ['admin', 'spend', 'view'],
                            state: 'active',
                            userMultiKeyRotationRequired: true,
                            // No keychain - this is the key difference for multi-key-user-key shares
                        },
                    ],
                    outgoing: [],
                });
                const testKeychain = bitgo.coin('ofc').keychains().create();
                const keychain = {
                    prv: testKeychain.prv,
                    pub: testKeychain.pub,
                };
                // Set up stubs first
                const keychainsInstance = ofcWallets.baseCoin.keychains();
                const keychainsStub = sandbox.stub(keychainsInstance, 'create').returns(keychain);
                const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: userPassword });
                const encryptStub = sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
                // Mock bulk update API - this is called via bulkUpdateWalletShare
                nock(bgUrl)
                    .put('/api/v2/walletshares/update', (body) => {
                    if (!body.shares || body.shares.length !== 1) {
                        return false;
                    }
                    const share = body.shares[0];
                    return (share.walletShareId === shareId &&
                        share.status === 'accept' &&
                        share.pub === keychain.pub &&
                        share.encryptedPrv === encryptedPrv);
                })
                    .reply(200, {
                    acceptedWalletShares: [{ walletShareId: shareId }],
                    rejectedWalletShares: [],
                    walletShareUpdateErrors: [],
                });
                // Note: bulkAcceptShare filters for shares WITH keychains, but userMultiKeyRotationRequired
                // shares don't have keychains, so they go through a different path
                // We need to stub the processAcceptShare path or use bulkUpdateWalletShare directly
                // For this test, we'll use bulkUpdateWalletShare which calls processAcceptShare internally
                const result = await ofcWallets.bulkUpdateWalletShare({
                    shares: [{ walletShareId: shareId, status: 'accept' }],
                    userLoginPassword: userPassword,
                });
                should.equal(result.acceptedWalletShares.length, 1);
                should.deepEqual(result.acceptedWalletShares[0], { walletShareId: 'test_multi_key_bulk_1' });
                should.equal(keychainsStub.calledOnce, true);
                should.equal(encryptStub.calledWith({ input: keychain.prv, password: userPassword }), true);
            });
            it('should handle bulk accept share with userMultiKeyRotationRequired and newWalletPassphrase', async function () {
                const shareId = 'test_multi_key_bulk_2';
                const userPassword = 'test_password_123';
                const newWalletPassphrase = 'new_wallet_passphrase_456';
                // Mock listSharesV2 to return a share with userMultiKeyRotationRequired
                sandbox.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
                    incoming: [
                        {
                            id: shareId,
                            coin: 'ofc',
                            walletLabel: 'test wallet',
                            fromUser: 'fromUser',
                            toUser: 'toUser',
                            wallet: 'wallet123',
                            permissions: ['admin', 'spend', 'view'],
                            state: 'active',
                            userMultiKeyRotationRequired: true,
                            // No keychain - this is the key difference for multi-key-user-key shares
                        },
                    ],
                    outgoing: [],
                });
                const testKeychain = bitgo.coin('ofc').keychains().create();
                const keychain = {
                    prv: testKeychain.prv,
                    pub: testKeychain.pub,
                };
                // Set up stubs first
                const keychainsInstance = ofcWallets.baseCoin.keychains();
                const keychainsStub = sandbox.stub(keychainsInstance, 'create').returns(keychain);
                // Should encrypt with newWalletPassphrase if provided (as per implementation)
                const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: newWalletPassphrase });
                const encryptStub = sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
                // Mock bulk update API - this is called via bulkUpdateWalletShare
                nock(bgUrl)
                    .put('/api/v2/walletshares/update', (body) => {
                    if (!body.shares || body.shares.length !== 1) {
                        return false;
                    }
                    const share = body.shares[0];
                    return (share.walletShareId === shareId &&
                        share.status === 'accept' &&
                        share.pub === keychain.pub &&
                        share.encryptedPrv === encryptedPrv);
                })
                    .reply(200, {
                    acceptedWalletShares: [{ walletShareId: shareId }],
                    rejectedWalletShares: [],
                    walletShareUpdateErrors: [],
                });
                const result = await ofcWallets.bulkUpdateWalletShare({
                    shares: [{ walletShareId: shareId, status: 'accept' }],
                    userLoginPassword: userPassword,
                    newWalletPassphrase: newWalletPassphrase,
                });
                should.equal(result.acceptedWalletShares.length, 1);
                should.deepEqual(result.acceptedWalletShares[0], { walletShareId: shareId });
                should.equal(keychainsStub.calledOnce, true);
                // Verify encrypt was called with newWalletPassphrase (not userPassword)
                should.equal(encryptStub.calledWith({ input: keychain.prv, password: newWalletPassphrase }), true);
            });
            it('should throw error when neither userLoginPassword nor newWalletPassphrase provided for bulk accept', async function () {
                const shareId = 'test_multi_key_bulk_3';
                // Mock listSharesV2 to return a share with userMultiKeyRotationRequired
                sandbox.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
                    incoming: [
                        {
                            id: shareId,
                            coin: 'ofc',
                            walletLabel: 'test wallet',
                            fromUser: 'fromUser',
                            toUser: 'toUser',
                            wallet: 'wallet123',
                            permissions: ['admin', 'spend', 'view'],
                            state: 'active',
                            userMultiKeyRotationRequired: true,
                        },
                    ],
                    outgoing: [],
                });
                // Mock user settings API call (required by bulkUpdateWalletShare)
                nock(bgUrl).get('/api/v1/user/settings').reply(200, {});
                // Mock bulkUpdateWalletShareRequest - when there are errors, it's called with empty array
                nock(bgUrl)
                    .put('/api/v2/walletshares/update', (body) => {
                    return body.shares && body.shares.length === 0;
                })
                    .reply(200, {
                    acceptedWalletShares: [],
                    rejectedWalletShares: [],
                    walletShareUpdateErrors: [],
                });
                // bulkUpdateWalletShare uses Promise.allSettled, so errors are caught and returned in walletShareUpdateErrors
                // We need to check the result for errors instead of expecting a rejection
                const result = await ofcWallets.bulkUpdateWalletShare({
                    shares: [{ walletShareId: shareId, status: 'accept' }],
                });
                // Verify that the error was captured in walletShareUpdateErrors
                should.equal(result.walletShareUpdateErrors.length, 1);
                should.equal(result.walletShareUpdateErrors[0].walletShareId, shareId);
                should(result.walletShareUpdateErrors[0].reason).containEql('userLoginPassword param must be provided to generate user keychain');
            });
            it('should work with newWalletPassphrase parameter', async function () {
                const shareId = 'test_multi_key_4';
                const userPassword = 'test_password_123';
                const newWalletPassphrase = 'new_wallet_passphrase_456';
                const walletId = 'test_wallet_123';
                const walletShareNock = nock(bgUrl)
                    .get(`/api/v2/ofc/walletshare/${shareId}`)
                    .reply(200, {
                    userMultiKeyRotationRequired: true,
                    permissions: ['admin', 'spend', 'view'],
                    wallet: walletId,
                });
                const testKeychain = bitgo.coin('ofc').keychains().create();
                const keychain = {
                    prv: testKeychain.prv,
                    pub: testKeychain.pub,
                };
                // Stub create() and encrypt() BEFORE calculating encryptedPrv to ensure consistency
                const keychainsInstance = ofcWallets.baseCoin.keychains();
                sandbox.stub(keychainsInstance, 'create').returns(keychain);
                // Should encrypt with newWalletPassphrase if provided (as per implementation)
                const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: newWalletPassphrase });
                const encryptStub = sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
                const acceptShareNock = nock(bgUrl)
                    .post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
                    return (body.walletShareId === shareId &&
                        body.state === 'accepted' &&
                        body.pub === keychain.pub &&
                        body.encryptedPrv === encryptedPrv);
                })
                    .reply(200, { changed: true, state: 'accepted' });
                const res = await ofcWallets.acceptShare({
                    walletShareId: shareId,
                    userPassword,
                    newWalletPassphrase,
                });
                should.equal(res.changed, true);
                should.equal(res.state, 'accepted');
                // Verify encrypt was called with newWalletPassphrase
                should.equal(encryptStub.calledWith({ input: keychain.prv, password: newWalletPassphrase }), true);
                walletShareNock.done();
                acceptShareNock.done();
            });
            it('should prioritize userMultiKeyRotationRequired over keychainOverrideRequired', async function () {
                const shareId = 'test_multi_key_5';
                const userPassword = 'test_password_123';
                const walletId = 'test_wallet_123';
                const walletShareNock = nock(bgUrl)
                    .get(`/api/v2/ofc/walletshare/${shareId}`)
                    .reply(200, {
                    userMultiKeyRotationRequired: true,
                    keychainOverrideRequired: true, // Both set, but userMultiKeyRotationRequired should take precedence
                    permissions: ['admin', 'spend', 'view'],
                    wallet: walletId,
                });
                const testKeychain = bitgo.coin('ofc').keychains().create();
                const keychain = {
                    prv: testKeychain.prv,
                    pub: testKeychain.pub,
                };
                // Set up stubs first
                const keychainsInstance = ofcWallets.baseCoin.keychains();
                sandbox.stub(keychainsInstance, 'create').returns(keychain);
                const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: userPassword });
                sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
                // Should use the multi-key-user-key flow (no signature/payload/keyId)
                const acceptShareNock = nock(bgUrl)
                    .post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
                    // Verify it's using multi-key-user-key flow (has pub and encryptedPrv, but no signature/payload/keyId)
                    return (body.walletShareId === shareId &&
                        body.state === 'accepted' &&
                        body.pub === keychain.pub &&
                        body.encryptedPrv === encryptedPrv &&
                        !body.signature &&
                        !body.payload &&
                        !body.keyId);
                })
                    .reply(200, { changed: true, state: 'accepted' });
                const reshareStub = sandbox.stub(sdk_core_1.Wallets.prototype, 'reshareWalletWithSpenders');
                const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
                should.equal(res.changed, true);
                should.equal(res.state, 'accepted');
                // Verify reshare was NOT called (multi-key-user-key flow)
                should.equal(reshareStub.called, false);
                walletShareNock.done();
                acceptShareNock.done();
            });
            it('should handle keychain creation failure', async function () {
                const shareId = 'test_multi_key_6';
                const userPassword = 'test_password_123';
                const walletShareNock = nock(bgUrl)
                    .get(`/api/v2/ofc/walletshare/${shareId}`)
                    .reply(200, {
                    userMultiKeyRotationRequired: true,
                    permissions: ['admin', 'spend', 'view'],
                });
                const keychainError = new Error('Failed to create keychain');
                const keychainsInstance = ofcWallets.baseCoin.keychains();
                sandbox.stub(keychainsInstance, 'create').throws(keychainError);
                await ofcWallets
                    .acceptShare({ walletShareId: shareId, userPassword })
                    .should.be.rejectedWith('Failed to create keychain');
                walletShareNock.done();
            });
            it('should handle encryption failure', async function () {
                const shareId = 'test_multi_key_7';
                const userPassword = 'test_password_123';
                const walletShareNock = nock(bgUrl)
                    .get(`/api/v2/ofc/walletshare/${shareId}`)
                    .reply(200, {
                    userMultiKeyRotationRequired: true,
                    permissions: ['admin', 'spend', 'view'],
                });
                const testKeychain = bitgo.coin('ofc').keychains().create();
                const keychain = {
                    prv: testKeychain.prv,
                    pub: testKeychain.pub,
                };
                const keychainsInstance = ofcWallets.baseCoin.keychains();
                sandbox.stub(keychainsInstance, 'create').returns(keychain);
                const encryptionError = new Error('Encryption failed');
                sandbox.stub(bitgo, 'encrypt').throws(encryptionError);
                await ofcWallets
                    .acceptShare({ walletShareId: shareId, userPassword })
                    .should.be.rejectedWith('Encryption failed');
                walletShareNock.done();
            });
            it('should work with view-only permissions', async function () {
                const shareId = 'test_multi_key_8';
                const userPassword = 'test_password_123';
                const walletShareNock = nock(bgUrl)
                    .get(`/api/v2/ofc/walletshare/${shareId}`)
                    .reply(200, {
                    userMultiKeyRotationRequired: true,
                    permissions: ['view'], // View-only permissions
                });
                const testKeychain = bitgo.coin('ofc').keychains().create();
                const keychain = {
                    prv: testKeychain.prv,
                    pub: testKeychain.pub,
                };
                // Set up stubs first
                const keychainsInstance = ofcWallets.baseCoin.keychains();
                sandbox.stub(keychainsInstance, 'create').returns(keychain);
                const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: userPassword });
                sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
                const acceptShareNock = nock(bgUrl)
                    .post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
                    return (body.walletShareId === shareId &&
                        body.state === 'accepted' &&
                        body.pub === keychain.pub &&
                        body.encryptedPrv === encryptedPrv);
                })
                    .reply(200, { changed: true, state: 'accepted' });
                const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
                should.equal(res.changed, true);
                should.equal(res.state, 'accepted');
                walletShareNock.done();
                acceptShareNock.done();
            });
            it('should verify exact values sent in API request', async function () {
                const shareId = 'test_multi_key_9';
                const userPassword = 'test_password_123';
                const walletId = 'test_wallet_123';
                const walletShareNock = nock(bgUrl)
                    .get(`/api/v2/ofc/walletshare/${shareId}`)
                    .reply(200, {
                    userMultiKeyRotationRequired: true,
                    permissions: ['admin', 'spend', 'view'],
                    wallet: walletId,
                });
                const testKeychain = bitgo.coin('ofc').keychains().create();
                const keychain = {
                    prv: testKeychain.prv,
                    pub: testKeychain.pub,
                };
                // Set up stubs first
                const keychainsInstance = ofcWallets.baseCoin.keychains();
                sandbox.stub(keychainsInstance, 'create').returns(keychain);
                const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: userPassword });
                sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
                let capturedBody;
                const acceptShareNock = nock(bgUrl)
                    .post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
                    capturedBody = body;
                    return true;
                })
                    .reply(200, { changed: true, state: 'accepted' });
                await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
                // Verify exact values
                should.equal(capturedBody.walletShareId, shareId);
                should.equal(capturedBody.state, 'accepted');
                should.equal(capturedBody.pub, keychain.pub);
                should.equal(capturedBody.encryptedPrv, encryptedPrv);
                should.not.exist(capturedBody.signature);
                should.not.exist(capturedBody.payload);
                should.not.exist(capturedBody.keyId);
                walletShareNock.done();
                acceptShareNock.done();
            });
        });
        it('should share a wallet to viewer', async function () {
            const shareId = '12311';
            nock(bgUrl).get(`/api/v2/tbtc/walletshare/${shareId}`).reply(200, {});
            const acceptShareNock = nock(bgUrl)
                .post(`/api/v2/tbtc/walletshare/${shareId}`, { walletShareId: shareId, state: 'accepted' })
                .reply(200, {});
            await wallets.acceptShare({ walletShareId: shareId });
            acceptShareNock.done();
        });
        describe('v2 envelope support in acceptShare', () => {
            const sandbox = sinon.createSandbox();
            (0, mocha_1.afterEach)(() => sandbox.verifyAndRestore());
            it('should accept share when ECDH sharing keychain encryptedXprv is v2-encrypted', async function () {
                const shareId = 'v2-ecdh-xprv-1';
                const userPassword = 'test_password';
                // Simulate a v2 envelope for the ECDH root key
                const v2EncryptedXprv = JSON.stringify({ v: 2, iv: 'aabbcc', ct: 'ddeeff', adata: '00' });
                const fakeXprv = 'xprvSomeBase58Value';
                const fakeSecret = 'fakeEcdhSharedSecret';
                const decryptedWalletPrv = 'walletPrivKeyPlaintext';
                const eckey = (0, sdk_core_1.makeRandomKey)();
                const v2EncryptedPrv = await bitgo.encrypt({ password: fakeSecret, input: decryptedWalletPrv });
                nock(bgUrl)
                    .get(`/api/v2/tbtc/walletshare/${shareId}`)
                    .reply(200, {
                    keychain: {
                        path: 'm/0/0/1',
                        fromPubKey: eckey.publicKey.toString('hex'),
                        toPubKey: eckey.publicKey.toString('hex'),
                        encryptedPrv: v2EncryptedPrv,
                        pub: eckey.publicKey.toString('hex'),
                    },
                });
                nock(bgUrl).post(`/api/v2/tbtc/walletshare/${shareId}`).reply(200, { changed: true, state: 'accepted' });
                sandbox.stub(bitgo, 'getECDHKeychain').resolves({ encryptedXprv: v2EncryptedXprv });
                const decryptAsyncStub = sandbox.stub(bitgo, 'decrypt');
                // First call decrypts the ECDH keychain (v2), second decrypts the shared wallet prv
                decryptAsyncStub.onFirstCall().resolves(fakeXprv);
                decryptAsyncStub.onSecondCall().resolves(decryptedWalletPrv);
                sandbox.stub(moduleBitgo, 'getSharedSecret').returns(Buffer.from(fakeSecret));
                const res = await wallets.acceptShare({ walletShareId: shareId, userPassword });
                should.equal(res.changed, true);
                should.equal(res.state, 'accepted');
                // Must have called decrypt (not the sync decrypt) for both the ECDH key and the wallet prv
                assert.equal(decryptAsyncStub.callCount, 2);
            });
            it('should accept share when wallet keychain encryptedPrv is v2-encrypted', async function () {
                const shareId = 'v2-wallet-prv-1';
                const userPassword = 'test_password';
                const v2EncryptedXprv = JSON.stringify({ v: 2, iv: 'aabbcc', ct: 'ddeeff', adata: '00' });
                const fakeXprv = 'xprvAnotherKey';
                const fakeSecret = 'ecdhSharedSecret2';
                const decryptedWalletPrv = 'walletPrivKey2';
                const v2EncryptedPrv = JSON.stringify({ v: 2, iv: '112233', ct: '445566', adata: '77' });
                const eckey = (0, sdk_core_1.makeRandomKey)();
                nock(bgUrl)
                    .get(`/api/v2/tbtc/walletshare/${shareId}`)
                    .reply(200, {
                    keychain: {
                        path: 'm/0/0/2',
                        fromPubKey: eckey.publicKey.toString('hex'),
                        toPubKey: eckey.publicKey.toString('hex'),
                        encryptedPrv: v2EncryptedPrv,
                        pub: eckey.publicKey.toString('hex'),
                    },
                });
                nock(bgUrl).post(`/api/v2/tbtc/walletshare/${shareId}`).reply(200, { changed: true, state: 'accepted' });
                sandbox.stub(bitgo, 'getECDHKeychain').resolves({ encryptedXprv: v2EncryptedXprv });
                const decryptAsyncStub = sandbox.stub(bitgo, 'decrypt');
                decryptAsyncStub.onFirstCall().resolves(fakeXprv);
                decryptAsyncStub.onSecondCall().resolves(decryptedWalletPrv);
                sandbox.stub(moduleBitgo, 'getSharedSecret').returns(Buffer.from(fakeSecret));
                const res = await wallets.acceptShare({ walletShareId: shareId, userPassword });
                should.equal(res.changed, true);
                should.equal(res.state, 'accepted');
            });
        });
        describe('bulkAcceptShare', function () {
            (0, mocha_1.afterEach)(function () {
                nock.cleanAll();
                nock.pendingMocks().length.should.equal(0);
                sinon.restore();
            });
            it('should throw validation error for userPassword empty string', async () => {
                await wallets
                    .bulkAcceptShare({ walletShareIds: [], userLoginPassword: '' })
                    .should.rejectedWith('Please provide a valid user login password');
            });
            it('should throw validation error for sending walletPassphrase empty string', async () => {
                await wallets
                    .bulkAcceptShare({ walletShareIds: [], userLoginPassword: 'password', newWalletPassphrase: 123 })
                    .should.rejectedWith('Please provide a valid wallet passphrase');
            });
            it('should throw assertion error for empty walletShareIds', async () => {
                await wallets
                    .bulkAcceptShare({ walletShareIds: [], userLoginPassword: 'dummy@123' })
                    .should.rejectedWith('Please provide at least one wallet share to accept');
            });
            it('should throw error for no valid wallet shares', async () => {
                sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
                    incoming: [
                        {
                            id: '66a229dbdccdcfb95b44fc2745a60bd4',
                            coin: 'tsol',
                            walletLabel: 'testing',
                            fromUser: 'dummyFromUser',
                            toUser: 'dummyToUser',
                            wallet: 'dummyWalletId',
                            permissions: ['spend'],
                            state: 'active',
                        },
                    ],
                    outgoing: [],
                });
                await wallets
                    .bulkAcceptShare({
                    walletShareIds: ['66a229dbdccdcfb95b44fc2745a60bd1'],
                    userLoginPassword: 'dummy@123',
                })
                    .should.rejectedWith('No valid wallet shares found to accept');
            });
            it('should throw error for no valid walletShares with keychain', async () => {
                sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
                    incoming: [
                        {
                            id: '66a229dbdccdcfb95b44fc2745a60bd4',
                            coin: 'tsol',
                            walletLabel: 'testing',
                            fromUser: 'dummyFromUser',
                            toUser: 'dummyToUser',
                            wallet: 'dummyWalletId',
                            permissions: ['spend'],
                            state: 'active',
                        },
                    ],
                    outgoing: [],
                });
                await wallets
                    .bulkAcceptShare({
                    walletShareIds: ['66a229dbdccdcfb95b44fc2745a60bd4'],
                    userLoginPassword: 'dummy@123',
                })
                    .should.rejectedWith('No valid wallet shares found to accept');
            });
            it('should throw error for ecdh keychain undefined', async () => {
                sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
                    incoming: [
                        {
                            id: '66a229dbdccdcfb95b44fc2745a60bd4',
                            coin: 'tsol',
                            walletLabel: 'testing',
                            fromUser: 'dummyFromUser',
                            toUser: 'dummyToUser',
                            wallet: 'dummyWalletId',
                            permissions: ['spend'],
                            state: 'active',
                            keychain: {
                                pub: 'pub',
                                toPubKey: 'toPubKey',
                                fromPubKey: 'fromPubKey',
                                encryptedPrv: 'encryptedPrv',
                                path: 'path',
                            },
                        },
                    ],
                    outgoing: [],
                });
                sinon.stub(bitgo, 'getECDHKeychain').resolves({
                    prv: 'private key',
                });
                await wallets
                    .bulkAcceptShare({
                    walletShareIds: ['66a229dbdccdcfb95b44fc2745a60bd4'],
                    userLoginPassword: 'dummy@123',
                })
                    .should.rejectedWith('encryptedXprv was not found on sharing keychain');
            });
            it('should successfully accept share', async () => {
                const fromUserPrv = Math.random();
                const walletPassphrase = 'bitgo1234';
                const keychainTest = {
                    encryptedPrv: await bitgo.encrypt({ input: fromUserPrv.toString(), password: walletPassphrase }),
                };
                const userPrv = await (0, sdk_core_1.decryptKeychainPrivateKey)(bitgo, keychainTest, walletPassphrase);
                if (!userPrv) {
                    throw new Error('Unable to decrypt user keychain');
                }
                const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
                const path = 'm/999999/1/1';
                const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
                const eckey = (0, sdk_core_1.makeRandomKey)();
                const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
                const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: userPrv });
                nock(bgUrl)
                    .get('/api/v2/walletshares')
                    .reply(200, {
                    incoming: [
                        {
                            id: '66a229dbdccdcfb95b44fc2745a60bd4',
                            isUMSInitiated: true,
                            keychain: {
                                path: path,
                                fromPubKey: eckey.publicKey.toString('hex'),
                                encryptedPrv: newEncryptedPrv,
                                toPubKey: pubkey,
                                pub: pubkey,
                            },
                        },
                    ],
                });
                nock(bgUrl)
                    .put('/api/v2/walletshares/accept')
                    .reply(200, {
                    acceptedWalletShares: [
                        {
                            walletShareId: '66a229dbdccdcfb95b44fc2745a60bd4',
                        },
                    ],
                });
                const myEcdhKeychain = await bitgo.keychains().create();
                sinon.stub(bitgo, 'getECDHKeychain').resolves({
                    encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
                });
                const prvKey = await bitgo.decrypt({
                    password: walletPassphrase,
                    input: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
                });
                sinon.stub(bitgo, 'decrypt').resolves(prvKey);
                sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
                const share = await wallets.bulkAcceptShare({
                    walletShareIds: ['66a229dbdccdcfb95b44fc2745a60bd4'],
                    userLoginPassword: walletPassphrase,
                });
                assert.deepEqual(share, {
                    acceptedWalletShares: [
                        {
                            walletShareId: '66a229dbdccdcfb95b44fc2745a60bd4',
                        },
                    ],
                });
            });
            it('should accept share when ECDH sharing keychain is v2-encrypted', async () => {
                const walletPassphrase = 'bitgo1234';
                const shareId = '66a229dbdccdcfb95b44fc2745a60bd4';
                const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
                const path = 'm/999999/1/1';
                const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
                const eckey = (0, sdk_core_1.makeRandomKey)();
                const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
                const decryptedPrv = 'someWalletPrivateKey';
                const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: decryptedPrv });
                // Simulate v2-encrypted ECDH keychain xprv (envelope with v:2 marker)
                const v2EncryptedXprv = JSON.stringify({ v: 2, iv: 'aaa', ct: 'bbb', adata: 'ccc' });
                const myEcdhXprv = 'xprvSomeBase58Key';
                nock(bgUrl)
                    .get('/api/v2/walletshares')
                    .reply(200, {
                    incoming: [
                        {
                            id: shareId,
                            isUMSInitiated: true,
                            keychain: {
                                path,
                                fromPubKey: eckey.publicKey.toString('hex'),
                                encryptedPrv: newEncryptedPrv,
                                toPubKey: pubkey,
                                pub: pubkey,
                            },
                        },
                    ],
                });
                nock(bgUrl)
                    .put('/api/v2/walletshares/accept')
                    .reply(200, { acceptedWalletShares: [{ walletShareId: shareId }] });
                sinon.stub(bitgo, 'getECDHKeychain').resolves({ encryptedXprv: v2EncryptedXprv });
                // decrypt resolves with the xprv regardless of whether the envelope is v1 or v2
                sinon.stub(bitgo, 'decrypt').resolves(myEcdhXprv);
                sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
                const share = await wallets.bulkAcceptShare({
                    walletShareIds: [shareId],
                    userLoginPassword: walletPassphrase,
                });
                assert.deepEqual(share, { acceptedWalletShares: [{ walletShareId: shareId }] });
            });
            it('should accept share when wallet keychain encryptedPrv is v2-encrypted', async () => {
                const walletPassphrase = 'bitgo1234';
                const shareId = 'v2-prv-share-1';
                const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
                const path = 'm/999999/1/1';
                const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
                const eckey = (0, sdk_core_1.makeRandomKey)();
                // Simulate v2-encrypted encryptedPrv in the wallet share keychain
                const v2EncryptedPrv = JSON.stringify({ v: 2, iv: 'xxx', ct: 'yyy', adata: 'zzz' });
                const v2EncryptedXprv = JSON.stringify({ v: 2, iv: 'aaa', ct: 'bbb', adata: 'ccc' });
                const myEcdhXprv = 'xprvSomeBase58Key';
                const decryptedWalletPrv = 'decryptedWalletPrivKey';
                nock(bgUrl)
                    .get('/api/v2/walletshares')
                    .reply(200, {
                    incoming: [
                        {
                            id: shareId,
                            isUMSInitiated: true,
                            keychain: {
                                path,
                                fromPubKey: eckey.publicKey.toString('hex'),
                                encryptedPrv: v2EncryptedPrv,
                                toPubKey: pubkey,
                                pub: pubkey,
                            },
                        },
                    ],
                });
                nock(bgUrl)
                    .put('/api/v2/walletshares/accept')
                    .reply(200, { acceptedWalletShares: [{ walletShareId: shareId }] });
                sinon.stub(bitgo, 'getECDHKeychain').resolves({ encryptedXprv: v2EncryptedXprv });
                // First call: decrypt ECDH keychain xprv; second call: decrypt v2 wallet share prv
                const decryptAsyncStub = sinon.stub(bitgo, 'decrypt');
                decryptAsyncStub.onFirstCall().resolves(myEcdhXprv);
                decryptAsyncStub.onSecondCall().resolves(decryptedWalletPrv);
                sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
                const share = await wallets.bulkAcceptShare({
                    walletShareIds: [shareId],
                    userLoginPassword: walletPassphrase,
                });
                assert.deepEqual(share, { acceptedWalletShares: [{ walletShareId: shareId }] });
                // Both decrypt calls must use decrypt (not the sync decrypt)
                assert.equal(decryptAsyncStub.callCount, 2);
            });
            it('should include webauthnInfo in request when provided (ECDH branch)', async () => {
                const fromUserPrv = Math.random();
                const walletPassphrase = 'bitgo1234';
                const webauthnPassphrase = 'prf-derived-secret';
                const shareId = '66a229dbdccdcfb95b44fc2745a60bd4';
                const keychainTest = {
                    encryptedPrv: await bitgo.encrypt({ input: fromUserPrv.toString(), password: walletPassphrase }),
                };
                const userPrv = await (0, sdk_core_1.decryptKeychainPrivateKey)(bitgo, keychainTest, walletPassphrase);
                if (!userPrv) {
                    throw new Error('Unable to decrypt user keychain');
                }
                const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
                const path = 'm/999999/1/1';
                const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
                const eckey = (0, sdk_core_1.makeRandomKey)();
                const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
                const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: userPrv });
                let capturedBody;
                nock(bgUrl)
                    .get('/api/v2/walletshares')
                    .reply(200, {
                    incoming: [
                        {
                            id: shareId,
                            isUMSInitiated: true,
                            keychain: {
                                path: path,
                                fromPubKey: eckey.publicKey.toString('hex'),
                                encryptedPrv: newEncryptedPrv,
                                toPubKey: pubkey,
                                pub: pubkey,
                            },
                        },
                    ],
                });
                nock(bgUrl)
                    .put('/api/v2/walletshares/accept', (body) => {
                    capturedBody = body;
                    return true;
                })
                    .reply(200, {
                    acceptedWalletShares: [{ walletShareId: shareId }],
                });
                const myEcdhKeychain = await bitgo.keychains().create();
                sinon.stub(bitgo, 'getECDHKeychain').resolves({
                    encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
                });
                const prvKey = await bitgo.decrypt({
                    password: walletPassphrase,
                    input: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
                });
                sinon.stub(bitgo, 'decrypt').resolves(prvKey);
                sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
                await wallets.bulkAcceptShare({
                    walletShareIds: [shareId],
                    userLoginPassword: walletPassphrase,
                    webauthnInfo: {
                        otpDeviceId: 'device-001',
                        prfSalt: 'salt-abc',
                        passphrase: webauthnPassphrase,
                    },
                });
                const sentEntries = capturedBody.keysForWalletShares;
                sentEntries.should.have.length(1);
                sentEntries[0].should.have.property('encryptedPrv');
                sentEntries[0].should.have.property('webauthnInfo');
                sentEntries[0].webauthnInfo.should.have.property('otpDeviceId', 'device-001');
                sentEntries[0].webauthnInfo.should.have.property('prfSalt', 'salt-abc');
                sentEntries[0].webauthnInfo.should.have.property('encryptedPrv');
                sentEntries[0].webauthnInfo.should.not.have.property('passphrase');
            });
            it('should NOT include webauthnInfo when not provided (backward compat)', async () => {
                const fromUserPrv = Math.random();
                const walletPassphrase = 'bitgo1234';
                const shareId = '66a229dbdccdcfb95b44fc2745a60bd4';
                const keychainTest = {
                    encryptedPrv: await bitgo.encrypt({ input: fromUserPrv.toString(), password: walletPassphrase }),
                };
                const userPrv = await (0, sdk_core_1.decryptKeychainPrivateKey)(bitgo, keychainTest, walletPassphrase);
                if (!userPrv) {
                    throw new Error('Unable to decrypt user keychain');
                }
                const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
                const path = 'm/999999/1/1';
                const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
                const eckey = (0, sdk_core_1.makeRandomKey)();
                const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
                const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: userPrv });
                let capturedBody;
                nock(bgUrl)
                    .get('/api/v2/walletshares')
                    .reply(200, {
                    incoming: [
                        {
                            id: shareId,
                            isUMSInitiated: true,
                            keychain: {
                                path: path,
                                fromPubKey: eckey.publicKey.toString('hex'),
                                encryptedPrv: newEncryptedPrv,
                                toPubKey: pubkey,
                                pub: pubkey,
                            },
                        },
                    ],
                });
                nock(bgUrl)
                    .put('/api/v2/walletshares/accept', (body) => {
                    capturedBody = body;
                    return true;
                })
                    .reply(200, {
                    acceptedWalletShares: [{ walletShareId: shareId }],
                });
                const myEcdhKeychain = await bitgo.keychains().create();
                sinon.stub(bitgo, 'getECDHKeychain').resolves({
                    encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
                });
                const prvKey = await bitgo.decrypt({
                    password: walletPassphrase,
                    input: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
                });
                sinon.stub(bitgo, 'decrypt').resolves(prvKey);
                sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
                await wallets.bulkAcceptShare({
                    walletShareIds: [shareId],
                    userLoginPassword: walletPassphrase,
                });
                const sentEntries = capturedBody.keysForWalletShares;
                sentEntries.should.have.length(1);
                sentEntries[0].should.have.property('encryptedPrv');
                sentEntries[0].should.not.have.property('webauthnInfo');
            });
            it('should handle 413 payload too large error with smart retry', async () => {
                const walletPassphrase = 'bitgo1234';
                const fromUserPrv = Math.random();
                const keychainTest = {
                    encryptedPrv: await bitgo.encrypt({ input: fromUserPrv.toString(), password: walletPassphrase }),
                };
                const userPrv = await (0, sdk_core_1.decryptKeychainPrivateKey)(bitgo, keychainTest, walletPassphrase);
                if (!userPrv) {
                    throw new Error('Unable to decrypt user keychain');
                }
                const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
                const path = 'm/999999/1/1';
                const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
                const eckey = (0, sdk_core_1.makeRandomKey)();
                const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
                // Pad the private key with additional data to make it larger before encrypting
                const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: userPrv });
                const keychain = {
                    path: path,
                    fromPubKey: eckey.publicKey.toString('hex'),
                    encryptedPrv: newEncryptedPrv,
                    toPubKey: pubkey,
                    pub: pubkey,
                };
                const shareIds = Array.from({ length: 20 }, (_, i) => `share${i + 1}`);
                // Mock listSharesV2 to return 25 shares
                const shares = shareIds.map((id, index) => ({
                    id,
                    coin: 'tsol',
                    walletLabel: `testing${index}`,
                    fromUser: 'dummyFromUser',
                    toUser: 'dummyToUser',
                    wallet: `wallet${index}`,
                    permissions: ['spend'],
                    state: 'active',
                    keychain: keychain,
                }));
                sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
                    incoming: shares,
                    outgoing: [],
                });
                const myEcdhKeychain = await bitgo.keychains().create();
                sinon.stub(bitgo, 'getECDHKeychain').resolves({
                    encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
                });
                const prvKey = await bitgo.decrypt({
                    password: walletPassphrase,
                    input: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
                });
                sinon.stub(bitgo, 'decrypt').resolves(prvKey);
                sinon.stub(bitgo, 'encrypt').resolves(userPrv + 'X'.repeat(100000));
                sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
                // Mock bulkAcceptShareRequestWithRetry to track batch sizes
                const batchSizes = [];
                nock(bgUrl)
                    .persist() // This ensures the interceptor remains active for multiple requests
                    .put('/api/v2/walletshares/accept')
                    .reply(function (_, requestBody, cb) {
                    const params = requestBody['keysForWalletShares'];
                    batchSizes.push(params.length);
                    if (Buffer.byteLength(JSON.stringify(requestBody), 'utf8') > 950000) {
                        // Simulate 413 error
                        return cb(null, [413, { error: 'Request Entity Too Large' }]);
                    }
                    // Return success for smaller batches
                    return cb(null, [
                        200,
                        {
                            acceptedWalletShares: params.map((param) => ({
                                walletShareId: param.walletShareId,
                            })),
                        },
                    ]);
                });
                const result = await wallets.bulkAcceptShare({
                    walletShareIds: shareIds,
                    userLoginPassword: walletPassphrase,
                });
                // Should have tried with 20 (initial batch size for 25 items), then retried with smaller batches
                batchSizes.length.should.be.greaterThan(1);
                batchSizes.should.deepEqual([9, 9, 2]); // Initial batch size// Retry batches should be smaller
                result.should.have.property('acceptedWalletShares');
                result.acceptedWalletShares.should.be.an.Array();
                result.acceptedWalletShares.length.should.equal(20);
                result.acceptedWalletShares.forEach((share) => {
                    share.should.have.property('walletShareId');
                    share.walletShareId.should.match(/^share\d+$/);
                });
            });
            it('should retry with progressively smaller batch sizes on 413 errors', async () => {
                const walletPassphrase = 'bitgo1234';
                const fromUserPrv = Math.random();
                const keychainTest = {
                    encryptedPrv: await bitgo.encrypt({ input: fromUserPrv.toString(), password: walletPassphrase }),
                };
                const userPrv = await (0, sdk_core_1.decryptKeychainPrivateKey)(bitgo, keychainTest, walletPassphrase);
                if (!userPrv) {
                    throw new Error('Unable to decrypt user keychain');
                }
                const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
                const path = 'm/999999/1/1';
                const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
                const eckey = (0, sdk_core_1.makeRandomKey)();
                const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
                const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: userPrv });
                const keychain = {
                    path: path,
                    fromPubKey: eckey.publicKey.toString('hex'),
                    encryptedPrv: newEncryptedPrv,
                    toPubKey: pubkey,
                    pub: pubkey,
                };
                const shareIds = Array.from({ length: 20 }, (_, i) => `share${i + 1}`);
                // Mock listSharesV2
                const shares = shareIds.map((id, index) => ({
                    id,
                    coin: 'tsol',
                    walletLabel: `testing${index}`,
                    fromUser: 'dummyFromUser',
                    toUser: 'dummyToUser',
                    wallet: `wallet${index}`,
                    permissions: ['spend'],
                    state: 'active',
                    keychain: keychain,
                }));
                sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
                    incoming: shares,
                    outgoing: [],
                });
                const myEcdhKeychain = await bitgo.keychains().create();
                sinon.stub(bitgo, 'getECDHKeychain').resolves({
                    encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
                });
                const prvKey = await bitgo.decrypt({
                    password: walletPassphrase,
                    input: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
                });
                sinon.stub(bitgo, 'decrypt').resolves(prvKey);
                sinon.stub(bitgo, 'encrypt').resolves(userPrv + 'X'.repeat(100000));
                sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
                // Track the sequence of batch sizes attempted
                const batchSizeAttempts = [];
                nock(bgUrl)
                    .persist() // This ensures the interceptor remains active for multiple requests
                    .put('/api/v2/walletshares/accept')
                    .reply(function (_, requestBody, cb) {
                    const params = requestBody['keysForWalletShares'];
                    batchSizeAttempts.push(params.length);
                    // Simulate 413 for batches > 5, success for batches <= 5
                    if (Buffer.byteLength(JSON.stringify(requestBody), 'utf8') > 600000) {
                        // Simulate 413 error
                        return cb(null, [413, { error: 'Request Entity Too Large' }]);
                    }
                    // Return success for smaller batches
                    return cb(null, [
                        200,
                        {
                            acceptedWalletShares: params.map((param) => ({
                                walletShareId: param.walletShareId || 'test',
                            })),
                        },
                    ]);
                });
                const result = await wallets.bulkAcceptShare({
                    walletShareIds: shareIds,
                    userLoginPassword: walletPassphrase,
                });
                // Should see progressive batch size reduction: 20 -> 10 -> 5 (success)
                batchSizeAttempts.should.containDeep([9, 4, 4, 4, 4, 4]);
                result.should.have.property('acceptedWalletShares');
                result.acceptedWalletShares.should.be.an.Array();
                result.acceptedWalletShares.length.should.equal(20);
                result.acceptedWalletShares.forEach((share) => {
                    share.should.have.property('walletShareId');
                    share.walletShareId.should.match(/^share\d+$/);
                });
            });
            it('should throw error when batch size cannot be reduced further', async () => {
                const walletPassphrase = 'bitgo1234';
                const fromUserPrv = Math.random();
                const keychainTest = {
                    encryptedPrv: await bitgo.encrypt({ input: fromUserPrv.toString(), password: walletPassphrase }),
                };
                const userPrv = await (0, sdk_core_1.decryptKeychainPrivateKey)(bitgo, keychainTest, walletPassphrase);
                if (!userPrv) {
                    throw new Error('Unable to decrypt user keychain');
                }
                const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
                const path = 'm/999999/1/1';
                const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
                const eckey = (0, sdk_core_1.makeRandomKey)();
                const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
                const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: userPrv });
                const keychain = {
                    path: path,
                    fromPubKey: eckey.publicKey.toString('hex'),
                    encryptedPrv: newEncryptedPrv,
                    toPubKey: pubkey,
                    pub: pubkey,
                };
                const shareIds = ['share1'];
                // Mock listSharesV2
                sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
                    incoming: [
                        {
                            id: 'share1',
                            coin: 'tsol',
                            walletLabel: 'testing',
                            fromUser: 'dummyFromUser',
                            toUser: 'dummyToUser',
                            wallet: 'wallet1',
                            permissions: ['spend'],
                            state: 'active',
                            keychain: keychain,
                        },
                    ],
                    outgoing: [],
                });
                const myEcdhKeychain = await bitgo.keychains().create();
                sinon.stub(bitgo, 'getECDHKeychain').resolves({
                    encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
                });
                const prvKey = await bitgo.decrypt({
                    password: walletPassphrase,
                    input: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
                });
                sinon.stub(bitgo, 'decrypt').resolves(prvKey);
                sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
                // Always throw 413 error, even for batch size 1
                nock(bgUrl)
                    .persist()
                    .put('/api/v2/walletshares/accept')
                    .reply(function (_, _requestBody, cb) {
                    // Always respond with 413 error
                    return cb(null, [413, { error: 'Request Entity Too Large' }]);
                });
                await wallets
                    .bulkAcceptShare({
                    walletShareIds: shareIds,
                    userLoginPassword: walletPassphrase,
                })
                    .should.be.rejectedWith('Request Entity Too Large');
            });
        });
        describe('bulkUpdateWalletShare', function () {
            (0, mocha_1.afterEach)(function () {
                nock.cleanAll();
                nock.pendingMocks().length.should.equal(0);
                sinon.restore();
            });
            it('should throw validation error for missing shares parameter', async () => {
                await wallets.bulkUpdateWalletShare({}).should.be.rejectedWith('Missing parameter: shares');
            });
            it('should throw validation error for non-array shares parameter', async () => {
                await wallets
                    .bulkUpdateWalletShare({ shares: 'not-an-array' })
                    .should.be.rejectedWith('Expecting parameter array: shares but found string');
            });
            it('should throw validation error for missing walletShareId in share', async () => {
                await wallets
                    .bulkUpdateWalletShare({ shares: [{ status: 'accept' }] })
                    .should.be.rejectedWith('Missing walletShareId in share');
            });
            it('should throw validation error for missing status in share', async () => {
                await wallets
                    .bulkUpdateWalletShare({ shares: [{ walletShareId: '123' }] })
                    .should.be.rejectedWith('Missing status in share');
            });
            it('should throw validation error for invalid status in share', async () => {
                await wallets
                    .bulkUpdateWalletShare({ shares: [{ walletShareId: '123', status: 'invalid' }] })
                    .should.be.rejectedWith('Invalid status in share: invalid. Must be either "accept" or "reject"');
            });
            it('should throw validation error for non-string walletShareId', async () => {
                await wallets
                    .bulkUpdateWalletShare({ shares: [{ walletShareId: 123, status: 'accept' }] })
                    .should.be.rejectedWith('Expecting walletShareId to be a string but found number');
            });
            it('should throw validation error for non-string userLoginPassword', async () => {
                await wallets
                    .bulkUpdateWalletShare({ shares: [{ walletShareId: '123', status: 'accept' }], userLoginPassword: 123 })
                    .should.be.rejectedWith('Expecting parameter string: userLoginPassword but found number');
            });
            it('should throw validation error for non-string newWalletPassphrase', async () => {
                await wallets
                    .bulkUpdateWalletShare({
                    shares: [{ walletShareId: '123', status: 'accept' }],
                    userLoginPassword: 'password',
                    newWalletPassphrase: 123,
                })
                    .should.be.rejectedWith('Expecting parameter string: newWalletPassphrase but found number');
            });
            it('should throw assertion error for empty shares array', async () => {
                await wallets.bulkUpdateWalletShare({ shares: [] }).should.be.rejectedWith('no shares are passed');
            });
            it('should throw error for no valid wallet shares', async () => {
                sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
                    incoming: [
                        {
                            id: '66a229dbdccdcfb95b44fc2745a60bd4',
                            coin: 'tsol',
                            walletLabel: 'testing',
                            fromUser: 'dummyFromUser',
                            toUser: 'dummyToUser',
                            wallet: 'dummyWalletId',
                            permissions: ['spend'],
                            state: 'active',
                        },
                    ],
                    outgoing: [],
                });
                await wallets
                    .bulkUpdateWalletShare({
                    shares: [{ walletShareId: '66a229dbdccdcfb95b44fc2745a60bd1', status: 'accept' }],
                    userLoginPassword: 'dummy@123',
                })
                    .should.be.rejectedWith('invalid wallet share provided: 66a229dbdccdcfb95b44fc2745a60bd1');
            });
            it('should throw error for ecdh keychain undefined when accepting share requiring decryption', async () => {
                sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
                    incoming: [
                        {
                            id: '66a229dbdccdcfb95b44fc2745a60bd4',
                            coin: 'tsol',
                            walletLabel: 'testing',
                            fromUser: 'dummyFromUser',
                            toUser: 'dummyToUser',
                            wallet: 'dummyWalletId',
                            permissions: ['spend'],
                            state: 'active',
                            keychain: {
                                pub: 'pub',
                                toPubKey: 'toPubKey',
                                fromPubKey: 'fromPubKey',
                                encryptedPrv: 'encryptedPrv',
                                path: 'path',
                            },
                        },
                    ],
                    outgoing: [],
                });
                sinon.stub(bitgo, 'getECDHKeychain').resolves({
                    prv: 'private key',
                });
                await wallets
                    .bulkUpdateWalletShare({
                    shares: [{ walletShareId: '66a229dbdccdcfb95b44fc2745a60bd4', status: 'accept' }],
                    userLoginPassword: 'dummy@123',
                })
                    .should.be.rejectedWith('encryptedXprv was not found on sharing keychain');
            });
            it('should successfully update shares with both accept and reject statuses', async () => {
                const walletPassphrase = 'bitgo1234';
                // Mock listSharesV2 to return two shares
                sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
                    incoming: [
                        {
                            id: 'share1',
                            coin: 'tsol',
                            walletLabel: 'testing',
                            fromUser: 'dummyFromUser',
                            toUser: 'dummyToUser',
                            wallet: 'wallet1',
                            permissions: ['spend'],
                            state: 'active',
                        },
                        {
                            id: 'share2',
                            coin: 'tsol',
                            walletLabel: 'testing2',
                            fromUser: 'dummyFromUser',
                            toUser: 'dummyToUser',
                            wallet: 'wallet2',
                            permissions: ['spend'],
                            state: 'active',
                        },
                    ],
                    outgoing: [],
                });
                // Mock bulkUpdateWalletShareRequest
                const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
                    acceptedWalletShares: ['share1'],
                    rejectedWalletShares: ['share2'],
                    walletShareUpdateErrors: [],
                });
                const result = await wallets.bulkUpdateWalletShare({
                    shares: [
                        { walletShareId: 'share1', status: 'accept' },
                        { walletShareId: 'share2', status: 'reject' },
                    ],
                    userLoginPassword: walletPassphrase,
                });
                // Verify the result
                assert.deepEqual(result, {
                    acceptedWalletShares: ['share1'],
                    rejectedWalletShares: ['share2'],
                    walletShareUpdateErrors: [],
                });
                // Verify bulkUpdateWalletShareRequest was called with correct parameters
                bulkUpdateStub.calledOnce.should.be.true();
                const updateParams = bulkUpdateStub.firstCall.args[0];
                updateParams.should.have.lengthOf(2);
                // Second param should be for share2 with reject status
                updateParams.should.containDeep([
                    {
                        walletShareId: 'share2',
                        status: 'reject',
                    },
                ]);
            });
            it('should handle keychainOverrideRequired with newWalletPassphrase in bulk operations', async () => {
                const userLoginPassword = 'bitgo1234';
                const newWalletPassphrase = 'new_wallet_passphrase_456';
                // Mock listSharesV2 to return a share with keychainOverrideRequired
                sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
                    incoming: [
                        {
                            id: 'share1',
                            coin: 'tsol',
                            walletLabel: 'testing',
                            fromUser: 'dummyFromUser',
                            toUser: 'dummyToUser',
                            wallet: 'wallet1',
                            permissions: ['admin', 'spend'],
                            state: 'active',
                            keychainOverrideRequired: true,
                        },
                    ],
                    outgoing: [],
                });
                // Mock user settings API call (required by bulkUpdateWalletShare)
                nock(bgUrl).get('/api/v1/user/settings').reply(200, {});
                // Mock getECDHKeychain (required by bulkUpdateWalletShare when userLoginPassword is provided)
                sinon.stub(bitgo, 'getECDHKeychain').resolves({
                    encryptedXprv: 'encryptedXprv',
                });
                // Setup for the baseCoin.keychains().createUserKeychain
                const userKeychain = {
                    id: 'key1',
                    pub: 'pubKey',
                    encryptedPrv: 'encryptedPrivateKey',
                };
                const createUserKeychainStub = sinon
                    .stub(wallets.baseCoin.keychains(), 'createUserKeychain')
                    .resolves(userKeychain);
                // Mock decrypt and signMessage
                sinon.stub(bitgo, 'decrypt').resolves('decryptedPrivateKey');
                sinon.stub(wallets.baseCoin, 'signMessage').resolves(Buffer.from('signature'));
                // Mock bulkUpdateWalletShareRequest
                const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
                    acceptedWalletShares: ['share1'],
                    rejectedWalletShares: [],
                    walletShareUpdateErrors: [],
                });
                // Mock reshareWalletWithSpenders (called for keychainOverrideRequired cases)
                const reshareStub = sinon.stub(sdk_core_1.Wallets.prototype, 'reshareWalletWithSpenders').resolves();
                const result = await wallets.bulkUpdateWalletShare({
                    shares: [{ walletShareId: 'share1', status: 'accept' }],
                    userLoginPassword: userLoginPassword,
                    newWalletPassphrase: newWalletPassphrase,
                });
                // Verify createUserKeychain was called with newWalletPassphrase (not userLoginPassword)
                createUserKeychainStub.calledOnce.should.be.true();
                createUserKeychainStub.calledWith(newWalletPassphrase).should.be.true();
                // Verify the result
                assert.deepEqual(result, {
                    acceptedWalletShares: ['share1'],
                    rejectedWalletShares: [],
                    walletShareUpdateErrors: [],
                });
                bulkUpdateStub.calledOnce.should.be.true();
                // Verify reshare was called for keychainOverrideRequired case
                reshareStub.calledOnce.should.be.true();
            });
            it('should handle special override cases and reshare with spenders', async () => {
                const walletPassphrase = 'bitgo1234';
                // Mock listSharesV2 to return a share with keychainOverrideRequired
                sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
                    incoming: [
                        {
                            id: 'share1',
                            coin: 'ofc',
                            walletLabel: 'testing',
                            fromUser: 'dummyFromUser',
                            toUser: 'dummyToUser',
                            wallet: 'wallet1',
                            permissions: ['admin', 'spend'],
                            state: 'active',
                            keychainOverrideRequired: true,
                        },
                    ],
                    outgoing: [],
                });
                // Setup for the baseCoin.keychains().createUserKeychain
                const userKeychain = {
                    id: 'key1',
                    pub: 'pubKey',
                    encryptedPrv: 'encryptedPrivateKey',
                };
                sinon.stub(ofcWallets.baseCoin.keychains(), 'createUserKeychain').resolves(userKeychain);
                // Mock decrypt and signMessage
                sinon.stub(bitgo, 'decrypt').resolves('decryptedPrivateKey');
                sinon.stub(ofcWallets.baseCoin, 'signMessage').resolves(Buffer.from('signature'));
                // Mock getECDHKeychain
                sinon.stub(bitgo, 'getECDHKeychain').resolves({
                    encryptedXprv: 'encryptedXprv',
                });
                // Mock bulkUpdateWalletShareRequest
                const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
                    acceptedWalletShares: ['share1'],
                    rejectedWalletShares: [],
                    walletShareUpdateErrors: [],
                });
                // Mock reshareWalletWithSpenders
                const reshareStub = sinon.stub(sdk_core_1.Wallets.prototype, 'reshareWalletWithSpenders').resolves();
                const result = await ofcWallets.bulkUpdateWalletShare({
                    shares: [{ walletShareId: 'share1', status: 'accept' }],
                    userLoginPassword: walletPassphrase,
                });
                // Verify the result
                assert.deepEqual(result, {
                    acceptedWalletShares: ['share1'],
                    rejectedWalletShares: [],
                    walletShareUpdateErrors: [],
                });
                // Verify bulkUpdateWalletShareRequest was called
                bulkUpdateStub.calledOnce.should.be.true();
                // Verify reshareWalletWithSpenders was called with correct parameters
                reshareStub.calledOnce.should.be.true();
                reshareStub.firstCall.args[0].should.equal('wallet1');
                reshareStub.firstCall.args[1].should.equal(walletPassphrase);
            });
            it('should handle shares with no keychain to decrypt', async () => {
                const walletPassphrase = 'bitgo1234';
                // Mock listSharesV2 to return a share with no keychain
                sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
                    incoming: [
                        {
                            id: 'share1',
                            coin: 'tsol',
                            walletLabel: 'testing',
                            fromUser: 'dummyFromUser',
                            toUser: 'dummyToUser',
                            wallet: 'wallet1',
                            permissions: ['view'],
                            state: 'active',
                        },
                    ],
                    outgoing: [],
                });
                // Mock bulkUpdateWalletShareRequest
                const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
                    acceptedWalletShares: ['share1'],
                    rejectedWalletShares: [],
                    walletShareUpdateErrors: [],
                });
                const result = await wallets.bulkUpdateWalletShare({
                    shares: [{ walletShareId: 'share1', status: 'accept' }],
                    userLoginPassword: walletPassphrase,
                });
                // Verify the result
                assert.deepEqual(result, {
                    acceptedWalletShares: ['share1'],
                    rejectedWalletShares: [],
                    walletShareUpdateErrors: [],
                });
                // Verify bulkUpdateWalletShareRequest was called with correct parameters
                bulkUpdateStub.calledOnce.should.be.true();
                const updateParams = bulkUpdateStub.firstCall.args[0];
                updateParams.should.have.lengthOf(1);
                // Param should be for share1 with accept status and no additional fields
                updateParams.should.containDeep([
                    {
                        walletShareId: 'share1',
                        status: 'accept',
                    },
                ]);
            });
            it('should handle shares with keychain requiring decryption', async () => {
                const walletPassphrase = 'bitgo1234';
                const path = 'm/999999/1/1';
                // Create test keychains
                const fromKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef01deadbeef01deadbeef01deadbeef01', 'hex'));
                const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
                const fromPubKey = fromKeychain.publicKey.toString('hex');
                const toPubKey = toKeychain.derivePath(path).publicKey.toString('hex');
                // Create encrypted private key
                const originalPrivKey = 'originalPrivateKey';
                const sharedSecret = (0, sdk_core_1.getSharedSecret)(fromKeychain, Buffer.from(toPubKey, 'hex')).toString('hex');
                const encryptedPrv = await bitgo.encrypt({
                    password: sharedSecret,
                    input: originalPrivKey,
                });
                // Mock listSharesV2 to return a share with keychain
                sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
                    incoming: [
                        {
                            id: 'share1',
                            coin: 'tsol',
                            walletLabel: 'testing',
                            fromUser: 'dummyFromUser',
                            toUser: 'dummyToUser',
                            wallet: 'wallet1',
                            permissions: ['spend'],
                            state: 'active',
                            keychain: {
                                pub: toPubKey,
                                toPubKey: toPubKey,
                                fromPubKey: fromPubKey,
                                encryptedPrv: encryptedPrv,
                                path: path,
                            },
                        },
                    ],
                    outgoing: [],
                });
                // Mock getECDHKeychain
                const myEcdhKeychain = await bitgo.keychains().create();
                sinon.stub(bitgo, 'getECDHKeychain').resolves({
                    encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
                });
                // Setup decrypt and encrypt stubs
                const decryptStub = sinon.stub(bitgo, 'decrypt');
                decryptStub.onFirstCall().resolves(myEcdhKeychain.xprv); // For sharing keychain
                decryptStub.onSecondCall().resolves(originalPrivKey); // For wallet keychain
                const encryptStub = sinon.stub(bitgo, 'encrypt').resolves('newEncryptedPrv');
                // Mock getSharedSecret
                sinon.stub(moduleBitgo, 'getSharedSecret').returns(Buffer.from(sharedSecret));
                // Mock bulkUpdateWalletShareRequest
                const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
                    acceptedWalletShares: ['share1'],
                    rejectedWalletShares: [],
                    walletShareUpdateErrors: [],
                });
                const result = await wallets.bulkUpdateWalletShare({
                    shares: [{ walletShareId: 'share1', status: 'accept' }],
                    userLoginPassword: walletPassphrase,
                    newWalletPassphrase: 'newPassphrase',
                });
                // Verify the result
                assert.deepEqual(result, {
                    acceptedWalletShares: ['share1'],
                    rejectedWalletShares: [],
                    walletShareUpdateErrors: [],
                });
                // Verify bulkUpdateWalletShareRequest was called with correct parameters
                bulkUpdateStub.calledOnce.should.be.true();
                const updateParams = bulkUpdateStub.firstCall.args[0];
                updateParams.should.have.lengthOf(1);
                // Param should be for share1 with accept status and encryptedPrv
                updateParams.should.containDeep([
                    {
                        walletShareId: 'share1',
                        status: 'accept',
                        encryptedPrv: 'newEncryptedPrv',
                    },
                ]);
                // Verify encrypt was called with correct parameters
                encryptStub.calledOnce.should.be.true();
                encryptStub.firstCall.args[0].should.have.property('password', 'newPassphrase');
                encryptStub.firstCall.args[0].should.have.property('input', originalPrivKey);
            });
            it('should handle rejected promises and add them to walletShareUpdateErrors', async () => {
                const walletPassphrase = 'bitgo1234';
                // Mock listSharesV2 to return two shares
                sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
                    incoming: [
                        {
                            id: 'share1',
                            coin: 'tsol',
                            walletLabel: 'testing',
                            fromUser: 'dummyFromUser',
                            toUser: 'dummyToUser',
                            wallet: 'wallet1',
                            permissions: ['spend'],
                            state: 'active',
                        },
                        {
                            id: 'share2',
                            coin: 'tsol',
                            walletLabel: 'testing2',
                            fromUser: 'dummyFromUser',
                            toUser: 'dummyToUser',
                            wallet: 'wallet2',
                            permissions: ['spend'],
                            state: 'active',
                        },
                        {
                            id: 'share3',
                            coin: 'tsol',
                            walletLabel: 'testing3',
                            fromUser: 'dummyFromUser',
                            toUser: 'dummyToUser',
                            wallet: 'wallet3',
                            permissions: ['spend'],
                            state: 'active',
                        },
                    ],
                    outgoing: [],
                });
                // Stub processAcceptShare to throw an error for share2
                // Using 'as any' to bypass TypeScript's private method restriction
                const processAcceptShareStub = sinon.stub(sdk_core_1.Wallets.prototype, 'processAcceptShare');
                processAcceptShareStub
                    .withArgs('share1', sinon.match.any, sinon.match.any, sinon.match.any, sinon.match.any)
                    .resolves([{ walletShareId: 'share1', status: 'accept' }]);
                processAcceptShareStub
                    .withArgs('share2', sinon.match.any, sinon.match.any, sinon.match.any, sinon.match.any)
                    .rejects(new Error('Failed to process share2'));
                processAcceptShareStub
                    .withArgs('share3', sinon.match.any, sinon.match.any, sinon.match.any, sinon.match.any)
                    .resolves([{ walletShareId: 'share3', status: 'accept' }]);
                // Mock bulkUpdateWalletShareRequest to return a response
                const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
                    acceptedWalletShares: ['share1', 'share3'],
                    rejectedWalletShares: [],
                    walletShareUpdateErrors: [], // Empty array that should be populated
                });
                const result = await wallets.bulkUpdateWalletShare({
                    shares: [
                        { walletShareId: 'share1', status: 'accept' },
                        { walletShareId: 'share2', status: 'accept' },
                        { walletShareId: 'share3', status: 'accept' },
                    ],
                    userLoginPassword: walletPassphrase,
                });
                // Verify bulkUpdateWalletShareRequest was called with only the successful share
                bulkUpdateStub.calledOnce.should.be.true();
                const updateParams = bulkUpdateStub.firstCall.args[0];
                updateParams.should.have.lengthOf(2);
                updateParams[0].walletShareId.should.equal('share1');
                updateParams[0].status.should.equal('accept');
                updateParams[1].walletShareId.should.equal('share3');
                updateParams[1].status.should.equal('accept');
                // Verify the result contains the error information
                result.should.have.property('walletShareUpdateErrors');
                result.walletShareUpdateErrors.should.be.an.Array();
                result.walletShareUpdateErrors.should.have.lengthOf(1);
                result.walletShareUpdateErrors[0].should.have.property('walletShareId', 'share2');
                result.walletShareUpdateErrors[0].should.have.property('reason', 'Failed to process share2');
            });
            it('should accept share with v2-encrypted ECDH keychain and wallet prv', async () => {
                const walletPassphrase = 'bitgo1234';
                const path = 'm/999999/1/1';
                const fromKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef01deadbeef01deadbeef01deadbeef01', 'hex'));
                const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
                const toPubKey = toKeychain.derivePath(path).publicKey.toString('hex');
                const fromPubKey = fromKeychain.publicKey.toString('hex');
                const originalPrivKey = 'originalPrivateKey';
                const sharedSecret = (0, sdk_core_1.getSharedSecret)(fromKeychain, Buffer.from(toPubKey, 'hex')).toString('hex');
                const encryptedPrv = await bitgo.encrypt({ password: sharedSecret, input: originalPrivKey });
                // Both the ECDH keychain and share prv are v2-encrypted in this scenario
                const v2EncryptedXprv = JSON.stringify({ v: 2, iv: 'aabbcc', ct: 'ddeeff', adata: '00' });
                sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
                    incoming: [
                        {
                            id: 'share1',
                            coin: 'tsol',
                            walletLabel: 'testing',
                            fromUser: 'dummyFromUser',
                            toUser: 'dummyToUser',
                            wallet: 'wallet1',
                            permissions: ['spend'],
                            state: 'active',
                            keychain: { pub: toPubKey, toPubKey, fromPubKey, encryptedPrv, path },
                        },
                    ],
                    outgoing: [],
                });
                const myEcdhKeychain = await bitgo.keychains().create();
                sinon.stub(bitgo, 'getECDHKeychain').resolves({ encryptedXprv: v2EncryptedXprv });
                // decrypt handles v2 transparently; stub to return expected values
                const decryptAsyncStub = sinon.stub(bitgo, 'decrypt');
                decryptAsyncStub.onFirstCall().resolves(myEcdhKeychain.xprv); // ECDH keychain
                decryptAsyncStub.onSecondCall().resolves(originalPrivKey); // wallet share prv
                const encryptStub = sinon.stub(bitgo, 'encrypt').resolves('newEncryptedPrv');
                sinon.stub(moduleBitgo, 'getSharedSecret').returns(Buffer.from(sharedSecret));
                const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
                    acceptedWalletShares: ['share1'],
                    rejectedWalletShares: [],
                    walletShareUpdateErrors: [],
                });
                const result = await wallets.bulkUpdateWalletShare({
                    shares: [{ walletShareId: 'share1', status: 'accept' }],
                    userLoginPassword: walletPassphrase,
                    newWalletPassphrase: 'newPassphrase',
                });
                assert.deepEqual(result, {
                    acceptedWalletShares: ['share1'],
                    rejectedWalletShares: [],
                    walletShareUpdateErrors: [],
                });
                // Both decrypt calls must have gone through decrypt
                assert.equal(decryptAsyncStub.callCount, 2);
                bulkUpdateStub.calledOnce.should.be.true();
                encryptStub.calledOnce.should.be.true();
                encryptStub.firstCall.args[0].should.have.property('input', originalPrivKey);
            });
        });
    });
    describe('createBulkKeyShares tests', () => {
        const walletData = {
            id: '5b34252f1bf349930e34020a00000000',
            coin: 'tbtc',
            keys: [
                '5b3424f91bf349930e34017500000000',
                '5b3424f91bf349930e34017600000000',
                '5b3424f91bf349930e34017700000000',
            ],
            coinSpecific: {},
            multisigType: 'onchain',
            type: 'hot',
        };
        const tsol = bitgo.coin('tsol');
        const wallet = new sdk_core_1.Wallet(bitgo, tsol, walletData);
        before(function () {
            nock('https://bitgo.fakeurl').persist().get('/api/v1/client/constants').reply(200, { ttl: 3600, constants: {} });
            bitgo.initializeTestVars();
        });
        beforeEach(() => {
            sinon.createSandbox();
        });
        after(function () {
            nock.cleanAll();
            nock.pendingMocks().length.should.equal(0);
        });
        (0, mocha_1.afterEach)(function () {
            sinon.restore();
        });
        it('should throw an error if shareOptions is empty', async () => {
            try {
                await wallet.createBulkKeyShares([]);
                assert.fail('Expected error not thrown');
            }
            catch (error) {
                assert.strictEqual(error.message, 'shareOptions cannot be empty');
            }
        });
        it('should skip shareoption if keychain parameters are missing', async () => {
            const params = [
                {
                    user: 'testuser@example.com',
                    permissions: ['spend'],
                    keychain: { pub: 'pubkey', encryptedPrv: '', fromPubKey: '', toPubKey: '', path: '' },
                },
            ];
            try {
                await wallet.createBulkKeyShares(params);
                assert.fail('Expected error not thrown');
            }
            catch (error) {
                // Shareoptions with invalid keychains are skipped
                assert.strictEqual(error.message, 'shareOptions cannot be empty');
            }
        });
        it('should send the correct data to BitGo API if shareOptions are valid', async () => {
            const params = {
                shareOptions: [
                    {
                        user: 'testuser@example.com',
                        permissions: ['spend'],
                        keychain: {
                            pub: 'pubkey',
                            encryptedPrv: 'encryptedPrv',
                            fromPubKey: 'fromPubKey',
                            toPubKey: 'toPubKey',
                            path: 'm/0/0',
                        },
                    },
                ],
            };
            const paramsToSend = [
                {
                    user: 'testuser@example.com',
                    permissions: ['spend'],
                    keychain: {
                        pub: 'pubkey',
                        encryptedPrv: 'encryptedPrv',
                        fromPubKey: 'fromPubKey',
                        toPubKey: 'toPubKey',
                        path: 'm/0/0',
                    },
                },
            ];
            nock(bgUrl)
                .post(`/api/v2/wallet/${walletData.id}/walletshares`, params)
                .reply(200, {
                shares: [
                    {
                        id: 'userId',
                        coin: walletData.coin,
                        wallet: walletData.id,
                        fromUser: 'fromUserId',
                        toUser: 'toUserId',
                        permissions: ['view', 'spend'],
                        keychain: {
                            pub: 'dummyPub',
                            encryptedPrv: 'dummyEncryptedPrv',
                            fromPubKey: 'dummyFromPubKey',
                            toPubKey: 'dummyToPubKey',
                            path: 'dummyPath',
                        },
                    },
                ],
            });
            const result = await wallet.createBulkKeyShares(paramsToSend);
            assert.strictEqual(result.shares[0].id, 'userId', 'The share ID should match');
            assert.strictEqual(result.shares[0].coin, walletData.coin, 'The coin should match');
            assert.strictEqual(result.shares[0].wallet, walletData.id, 'The wallet ID should match');
            assert.ok(result.shares[0].keychain);
            assert.strictEqual(result.shares[0].keychain.pub, 'dummyPub', 'The keychain pub should match');
            assert.strictEqual(result.shares[0].permissions.includes('view'), true, 'The permissions should include "view"');
            assert.strictEqual(result.shares[0].permissions.includes('spend'), true, 'The permissions should include "spend"');
        });
    });
    describe('createBulkWalletShare tests', () => {
        const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
        const walletData = {
            id: '5b34252f1bf349930e34020a00000000',
            coin: 'tbtc',
            keys: [
                '5b3424f91bf349930e34017500000000',
                '5b3424f91bf349930e34017600000000',
                '5b3424f91bf349930e34017700000000',
            ],
            coinSpecific: {},
            multisigType: 'onchain',
            type: 'hot',
        };
        const tsol = bitgo.coin('tsol');
        const wallet = new sdk_core_1.Wallet(bitgo, tsol, walletData);
        before(function () {
            nock('https://bitgo.fakeurl').persist().get('/api/v1/client/constants').reply(200, { ttl: 3600, constants: {} });
            bitgo.initializeTestVars();
        });
        after(function () {
            nock.cleanAll();
            nock.pendingMocks().length.should.equal(0);
        });
        (0, mocha_1.afterEach)(function () {
            sinon.restore();
        });
        it('should throw an error if no share options are provided', async () => {
            try {
                await wallet.createBulkWalletShare({ walletPassphrase: 'Test', keyShareOptions: [] });
                assert.fail('Expected error not thrown');
            }
            catch (error) {
                assert.strictEqual(error.message, 'No share options provided');
            }
        });
        it('should throw NeedsUserSignup error if pubkey is missing', async () => {
            const userId = 'user@example.com';
            const permissions = ['view', 'spend'];
            try {
                await wallet.createBulkWalletShare({
                    walletPassphrase: 'Test',
                    keyShareOptions: [
                        {
                            userId: userId,
                            permissions: permissions,
                            path: 'm/999999/1/1',
                        },
                    ],
                });
                assert.fail('Expected error not thrown');
            }
            catch (error) {
                assert.ok(error instanceof sdk_core_1.NeedUserSignupError);
                assert.strictEqual(error.name, 'NeedUserSignupError');
                assert.strictEqual(error.message, userId);
            }
        });
        it('should throw error if path is missing', async () => {
            const userId = 'user@example.com';
            const permissions = ['view', 'spend'];
            try {
                await wallet.createBulkWalletShare({
                    walletPassphrase: 'Test',
                    keyShareOptions: [
                        {
                            userId: userId,
                            permissions: permissions,
                            pubKey: 'm/999999/1/1',
                        },
                    ],
                });
                assert.fail('Expected error not thrown');
            }
            catch (error) {
                assert.strictEqual(error.name, 'Error');
                assert.strictEqual(error.message, 'Missing parameter: path');
            }
        });
        it('should throw NeedsUserSignup error if pubkey is empty string', async () => {
            const userId = 'user@example.com';
            const permissions = ['view', 'spend'];
            try {
                await wallet.createBulkWalletShare({
                    walletPassphrase: 'Test',
                    keyShareOptions: [
                        {
                            userId: userId,
                            pubKey: '',
                            permissions: permissions,
                            path: 'm/999999/1/1',
                        },
                    ],
                });
                assert.fail('Expected error not thrown');
            }
            catch (error) {
                assert.ok(error instanceof sdk_core_1.NeedUserSignupError);
                assert.strictEqual(error.name, 'NeedUserSignupError');
                assert.strictEqual(error.message, userId);
            }
        });
        it('should correctly process share options and call createBulkKeyShares', async () => {
            const userId = 'user@example.com';
            const permissions = ['view', 'spend'];
            const path = 'm/999999/1/1';
            const walletPassphrase = 'bitgo1234';
            const pub = 'Zo1ggzTUKMY5bYnDvT5mtVeZxzf2FaLTbKkmvGUhUQk';
            nock(bgUrl)
                .get(`/api/v2/tbtc/key/${wallet.keyIds()[0]}`)
                .reply(200, {
                id: wallet.keyIds()[0],
                pub,
                source: 'user',
                encryptedPrv: await bitgo.encrypt({ input: 'xprv1', password: walletPassphrase }),
                coinSpecific: {},
            });
            const params = {
                walletPassphrase,
                keyShareOptions: [
                    {
                        userId: userId,
                        permissions: permissions,
                        pubKey: '02705a6d33a2459feb537e7abe36aaad8c11532cdbffa3a2e4e58868467d51f532',
                        path: path,
                    },
                ],
            };
            const prv1 = Math.random().toString();
            const keychainTest = {
                encryptedPrv: await bitgo.encrypt({ input: prv1, password: walletPassphrase }),
            };
            sinon.stub(wallet, 'getEncryptedUserKeychain').resolves({
                encryptedPrv: keychainTest.encryptedPrv,
                pub,
            });
            sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
            sinon.stub(wallet, 'createBulkKeyShares').resolves({
                shares: [
                    {
                        id: userId,
                        coin: walletData.coin,
                        wallet: walletData.id,
                        fromUser: userId,
                        toUser: userId,
                        permissions: ['view', 'spend'],
                        keychain: {
                            pub: 'dummyPub',
                            encryptedPrv: 'dummyEncryptedPrv',
                            fromPubKey: 'dummyFromPubKey',
                            toPubKey: 'dummyToPubKey',
                            path: 'dummyPath',
                        },
                    },
                ],
            });
            const result = await wallet.createBulkWalletShare(params);
            assert.deepStrictEqual(result, {
                shares: [
                    {
                        id: userId,
                        coin: walletData.coin,
                        wallet: walletData.id,
                        fromUser: userId,
                        toUser: userId,
                        permissions: ['view', 'spend'],
                        keychain: {
                            pub: 'dummyPub',
                            encryptedPrv: 'dummyEncryptedPrv',
                            fromPubKey: 'dummyFromPubKey',
                            toPubKey: 'dummyToPubKey',
                            path: 'dummyPath',
                        },
                    },
                ],
            });
        });
        it('should throw error in processing share options when wallet password is incorrect', async () => {
            const userId = 'user@example.com';
            const permissions = ['view', 'spend'];
            const path = 'm/999999/1/1';
            const walletPassphrase = 'bitgo1234';
            const pub = 'Zo1ggzTUKMY5bYnDvT5mtVeZxzf2FaLTbKkmvGUhUQk';
            nock(bgUrl)
                .get(`/api/v2/tbtc/key/${wallet.keyIds()[0]}`)
                .reply(200, {
                id: wallet.keyIds()[0],
                pub,
                source: 'user',
                encryptedPrv: await bitgo.encrypt({ input: 'xprv1', password: walletPassphrase }),
                coinSpecific: {},
            });
            const params = {
                walletPassphrase: 'wrong password',
                keyShareOptions: [
                    {
                        userId: userId,
                        permissions: permissions,
                        pubKey: '02705a6d33a2459feb537e7abe36aaad8c11532cdbffa3a2e4e58868467d51f532',
                        path: path,
                    },
                ],
            };
            const prv1 = Math.random().toString();
            const keychainTest = {
                encryptedPrv: await bitgo.encrypt({ input: prv1, password: walletPassphrase }),
            };
            sinon.stub(wallet, 'getEncryptedUserKeychain').resolves({
                encryptedPrv: keychainTest.encryptedPrv,
                pub,
            });
            try {
                await wallet.createBulkWalletShare(params);
                assert.fail('Expected error not thrown');
            }
            catch (error) {
                assert.ok(error instanceof sdk_core_1.IncorrectPasswordError);
                assert.equal(error.message, 'Password shared is incorrect for this wallet');
            }
        });
        it('should fetch keychain only ONCE when sharing with multiple users', async () => {
            const walletPassphrase = 'bitgo1234';
            const pub = 'Zo1ggzTUKMY5bYnDvT5mtVeZxzf2FaLTbKkmvGUhUQk';
            const prv1 = 'xprv1';
            // Create multiple users to share with
            const users = [
                {
                    userId: 'user1@example.com',
                    permissions: ['view', 'spend'],
                    pubKey: '02705a6d33a2459feb537e7abe36aaad8c11532cdbffa3a2e4e58868467d51f532',
                    path: 'm/999999/1/1',
                },
                {
                    userId: 'user2@example.com',
                    permissions: ['view', 'spend'],
                    pubKey: '03705a6d33a2459feb537e7abe36aaad8c11532cdbffa3a2e4e58868467d51f533',
                    path: 'm/999999/1/2',
                },
                {
                    userId: 'user3@example.com',
                    permissions: ['view', 'spend'],
                    pubKey: '02815a6d33a2459feb537e7abe36aaad8c11532cdbffa3a2e4e58868467d51f534',
                    path: 'm/999999/1/3',
                },
            ];
            const params = {
                walletPassphrase,
                keyShareOptions: users,
            };
            const getDecryptedKeychainStub = sinon.stub(wallet, 'getDecryptedKeychainForSharing').resolves({
                prv: prv1,
                pub,
            });
            const encryptPrvForUserStub = sinon
                .stub(wallet, 'encryptPrvForUser')
                .callsFake(async (prv, pubKey, userPubKey, path) => {
                return {
                    pub: pubKey,
                    encryptedPrv: 'dummyEncryptedPrv',
                    fromPubKey: 'dummyFromPubKey',
                    toPubKey: userPubKey,
                    path: path,
                };
            });
            sinon.stub(wallet, 'createBulkKeyShares').resolves({
                shares: users.map((user) => ({
                    id: user.userId,
                    coin: walletData.coin,
                    wallet: walletData.id,
                    fromUser: 'fromUser',
                    toUser: user.userId,
                    permissions: user.permissions,
                    keychain: {
                        pub: 'dummyPub',
                        encryptedPrv: 'dummyEncryptedPrv',
                        fromPubKey: 'dummyFromPubKey',
                        toPubKey: user.pubKey,
                        path: user.path,
                    },
                })),
            });
            await wallet.createBulkWalletShare(params);
            // Verify keychain is fetched only ONCE, not once per user
            assert.strictEqual(getDecryptedKeychainStub.callCount, 1, 'getDecryptedKeychainForSharing should be called exactly once, not once per user');
            // Verify encryption happens for EACH user (once per user)
            assert.strictEqual(encryptPrvForUserStub.callCount, users.length, `encryptPrvForUser should be called once per user (${users.length} times)`);
            // Verify each call had the correct user's pubKey and path
            users.forEach((user, index) => {
                const call = encryptPrvForUserStub.getCall(index);
                assert.strictEqual(call.args[0], prv1, 'Should use the same decrypted private key for all users');
                assert.strictEqual(call.args[1], pub, 'Should use the same public key for all users');
                assert.strictEqual(call.args[2], user.pubKey, `Should use user${index + 1}'s public key`);
                assert.strictEqual(call.args[3], user.path, `Should use user${index + 1}'s path`);
            });
        });
    });
    describe('downloadKeycard', () => {
        const localBitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
        const walletData = {
            id: '5b34252f1bf349930e34020a00000002',
            coin: 'tbtc',
            keys: [
                '5b3424f91bf349930e34017500000000',
                '5b3424f91bf349930e34017600000000',
                '5b3424f91bf349930e34017700000000',
            ],
            coinSpecific: {},
            multisigType: 'onchain',
            type: 'hot',
        };
        const tbtc = localBitgo.coin('tbtc');
        const wallet = new sdk_core_1.Wallet(localBitgo, tbtc, walletData);
        it('should throw when called in Node.js (no browser window)', async () => {
            // In Node.js, accessing `window` throws ReferenceError; the method rejects.
            await wallet.downloadKeycard().should.be.rejected();
        });
        it('downloadKeycard (sync) should throw when called in Node.js (no browser window)', () => {
            should.throws(() => wallet.downloadKeycard());
        });
    });
    describe('encryptPrvForUser', () => {
        const localBitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
        const walletData = {
            id: '5b34252f1bf349930e34020a00000001',
            coin: 'tbtc',
            keys: [
                '5b3424f91bf349930e34017500000000',
                '5b3424f91bf349930e34017600000000',
                '5b3424f91bf349930e34017700000000',
            ],
            coinSpecific: {},
            multisigType: 'onchain',
            type: 'hot',
        };
        const tbtc = localBitgo.coin('tbtc');
        const wallet = new sdk_core_1.Wallet(localBitgo, tbtc, walletData);
        before(function () {
            nock('https://bitgo.fakeurl').persist().get('/api/v1/client/constants').reply(200, { ttl: 3600, constants: {} });
            localBitgo.initializeTestVars();
        });
        (0, mocha_1.afterEach)(function () {
            sinon.restore();
        });
        it('should encrypt prv for user and return the correct output shape', async () => {
            const decryptedPrv = 'xprv9s21ZrQH143K2fJ91S4BRsupcYrE6mmY96fcX5HkhoTrrwmwjd16Cn87cWinJjByrfpojjx7ezsJLx7TAKLT8m8hM5Kax9YcoxnBeJZ3t2k';
            const pub = 'xpub661MyMwAqRbcF9Nc7TbBo1rZAagiWEVPWKbDKThNG8zqjk76HAKLkaSbTn6dK2dQPfuD7xjicxCZVWvj67fP5nQ9W7QURmoMVAX8m6jZsGp';
            // A valid 33-byte compressed EC point on secp256k1
            const userPubkey = '0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798';
            const path = 'm/999999/0/1';
            sinon.stub(localBitgo, 'encrypt').resolves('encryptedPrvForUser');
            const result = await wallet.encryptPrvForUser(decryptedPrv, pub, userPubkey, path);
            result.should.have.property('pub', pub);
            result.should.have.property('encryptedPrv', 'encryptedPrvForUser');
            result.should.have.property('fromPubKey').which.is.a.String();
            result.should.have.property('toPubKey', userPubkey);
            result.should.have.property('path', path);
        });
    });
    describe('List Wallets:', function () {
        it('should list wallets with skipReceiveAddress = true', async function () {
            const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
            const basecoin = bitgo.coin('tbtc');
            const wallets = basecoin.wallets();
            const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
            nock(bgUrl)
                .get('/api/v2/tbtc/wallet')
                .query({ skipReceiveAddress: true })
                .reply(200, {
                wallets: [
                    { id: 'wallet1', label: 'Test Wallet 1' },
                    { id: 'wallet2', label: 'Test Wallet 2' },
                ],
            });
            const result = await wallets.list({ skipReceiveAddress: true });
            result.wallets.should.have.length(2);
            should.not.exist(result.wallets[0].receiveAddress());
            should.not.exist(result.wallets[1].receiveAddress());
        });
        it('should list wallets without skipReceiveAddress', async function () {
            const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
            const basecoin = bitgo.coin('tbtc');
            const wallets = basecoin.wallets();
            const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
            nock(bgUrl)
                .get('/api/v2/tbtc/wallet')
                .query({})
                .reply(200, {
                wallets: [
                    { id: 'wallet1', label: 'Test Wallet 1', receiveAddress: { address: 'address1' } },
                    { id: 'wallet2', label: 'Test Wallet 2', receiveAddress: { address: 'address2' } },
                ],
            });
            const result = await wallets.list();
            result.wallets.should.have.length(2);
            should.exist(result.wallets[0].receiveAddress());
            should.exist(result.wallets[1].receiveAddress());
        });
    });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FsbGV0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvdjIvdW5pdC93YWxsZXRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsRUFBRTtBQUNGLG9CQUFvQjtBQUNwQixFQUFFO0FBQ0YsaUNBQWlDO0FBQ2pDLDZCQUE4QjtBQUM5QiwrQkFBK0I7QUFDL0IsaUNBQWtDO0FBQ2xDLDRCQUE0QjtBQUM1QiwyQ0FBMkM7QUFDM0MsOENBQTRDO0FBQzVDLDhDQXFCeUI7QUFDekIsc0NBQXFDO0FBQ3JDLGlDQUFrQztBQUVsQywrQ0FBK0M7QUFFL0MsUUFBUSxDQUFDLGFBQWEsRUFBRTtJQUN0QixNQUFNLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxXQUFLLEVBQUUsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUN6RCxJQUFJLE9BQU8sQ0FBQztJQUNaLElBQUksVUFBVSxDQUFDO0lBQ2YsSUFBSSxLQUFLLENBQUM7SUFFVixNQUFNLENBQUM7UUFDTCxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqSCxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUUzQixNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3BDLE9BQU8sR0FBRyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDN0IsVUFBVSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDekMsS0FBSyxHQUFHLGlCQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFD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aUJBQU0sQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDO1lBRXRELElBQUksQ0FBQyxLQUFLLENBQUM7aUJBQ1IsR0FBRyxDQUFDLHFCQUFxQixDQUFDO2lCQUMxQixLQUFLLENBQUMsRUFBRSxDQUFDO2lCQUNULEtBQUssQ0FBQyxHQUFHLEVBQUU7Z0JBQ1YsT0FBTyxFQUFFO29CQUNQLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsRUFBRTtvQkFDbEYsRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFFLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxFQUFFO2lCQUNuRjthQUNGLENBQUMsQ0FBQztZQUVMLE1BQU0sTUFBTSxHQUFHLE1BQU0sT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3BDLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUM7WUFDakQsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUM7UUFDbkQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy9cbi8vIFRlc3RzIGZvciBXYWxsZXRzXG4vL1xuaW1wb3J0ICogYXMgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgbm9jayA9IHJlcXVpcmUoJ25vY2snKTtcbmltcG9ydCAqIGFzIHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCBzaG91bGQgPSByZXF1aXJlKCdzaG91bGQnKTtcbmltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCAqIGFzIHV0eG9MaWIgZnJvbSAnQGJpdGdvL3V0eG8tbGliJztcbmltcG9ydCB7IFRlc3RCaXRHbyB9IGZyb20gJ0BiaXRnby9zZGstdGVzdCc7XG5pbXBvcnQge1xuICBjb21tb24sXG4gIFRzc1V0aWxzLFxuICBXYWxsZXRzLFxuICBFQ0RTQVV0aWxzLFxuICBFRERTQVV0aWxzLFxuICBLZXljaGFpbnNUcmlwbGV0LFxuICBHZW5lcmF0ZVdhbGxldE9wdGlvbnMsXG4gIFdhbGxldCxcbiAgaXNXYWxsZXRXaXRoS2V5Y2hhaW5zLFxuICBPcHRpb25hbEtleWNoYWluRW5jcnlwdGVkS2V5LFxuICBkZWNyeXB0S2V5Y2hhaW5Qcml2YXRlS2V5LFxuICBtYWtlUmFuZG9tS2V5LFxuICBnZXRTaGFyZWRTZWNyZXQsXG4gIEJ1bGtXYWxsZXRTaGFyZU9wdGlvbnMsXG4gIEFjY2VwdFNoYXJlT3B0aW9uc1JlcXVlc3QsXG4gIEtleWNoYWluV2l0aEVuY3J5cHRlZFBydixcbiAgV2FsbGV0V2l0aEtleWNoYWlucyxcbiAgbXVsdGlzaWdUeXBlcyxcbiAgSW5jb3JyZWN0UGFzc3dvcmRFcnJvcixcbiAgTmVlZFVzZXJTaWdudXBFcnJvcixcbn0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCB7IEJpdEdvIH0gZnJvbSAnLi4vLi4vLi4vc3JjJztcbmltcG9ydCB7IGFmdGVyRWFjaCB9IGZyb20gJ21vY2hhJztcbmltcG9ydCB7IFRzc1NldHRpbmdzIH0gZnJvbSAnQGJpdGdvL3B1YmxpYy10eXBlcyc7XG5pbXBvcnQgKiBhcyBtb2R1bGVCaXRnbyBmcm9tICdAYml0Z28vc2RrLWNvcmUnO1xuXG5kZXNjcmliZSgnVjIgV2FsbGV0czonLCBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ21vY2snIH0pO1xuICBsZXQgd2FsbGV0cztcbiAgbGV0IG9mY1dhbGxldHM7XG4gIGxldCBiZ1VybDtcblxuICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgIG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLnBlcnNpc3QoKS5nZXQoJy9hcGkvdjEvY2xpZW50L2NvbnN0YW50cycpLnJlcGx5KDIwMCwgeyB0dGw6IDM2MDAsIGNvbnN0YW50czoge30gfSk7XG5cbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcblxuICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndGJ0YycpO1xuICAgIHdhbGxldHMgPSBiYXNlY29pbi53YWxsZXRzKCk7XG4gICAgb2ZjV2FsbGV0cyA9IGJpdGdvLmNvaW4oJ29mYycpLndhbGxldHMoKTtcbiAgICBiZ1VybCA9IGNvbW1vbi5FbnZpcm9ubWVudHNbYml0Z28uZ2V0RW52KCldLnVyaTtcbiAgfSk7XG5cbiAgYWZ0ZXIoZnVuY3Rpb24gKCkge1xuICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICBub2NrLnBlbmRpbmdNb2NrcygpLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdBZGQgV2FsbGV0OicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgndGhyb3dzIG9uIGludmFsaWQgYXJndW1lbnRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gaXNDdXN0b2RpYWwgZmxhZyBpcyBub3QgYSBib29sZWFuXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5hZGQoeyBsYWJlbDogJ2xhYmVsJywgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLCBrZXlzOiBbXSwgbTogMiwgbjogMywgaXNDdXN0b2RpYWw6IDEgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgYXJndW1lbnQgZm9yIGlzQ3VzdG9kaWFsIC0gYm9vbGVhbiBleHBlY3RlZCcpO1xuXG4gICAgICAvLyB0eXBlIGlzIG5vdCBhIHN0cmluZ1xuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuYWRkKHsgbGFiZWw6ICdsYWJlbCcsIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJywga2V5czogW10sIG06IDIsIG46IDMsIHR5cGU6IDEgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0V4cGVjdGluZyBwYXJhbWV0ZXIgc3RyaW5nOiB0eXBlIGJ1dCBmb3VuZCBudW1iZXInKTtcblxuICAgICAgLy8gQWRkcmVzcyBpcyBhbiBpbnZhbGlkIGFkZHJlc3NcbiAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgLmFkZCh7IGxhYmVsOiAnbGFiZWwnLCBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsIGtleXM6IFtdLCBtOiAyLCBuOiAzLCBhZGRyZXNzOiAnJCcgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgYXJndW1lbnQgZm9yIGFkZHJlc3MgLSB2YWxpZCBhZGRyZXNzIHN0cmluZyBleHBlY3RlZCcpO1xuXG4gICAgICAvLyBnYXNQcmljZSBpcyBhIG51bWJlclxuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuYWRkKHsgbGFiZWw6ICdsYWJlbCcsIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJywga2V5czogW10sIG06IDIsIG46IDMsIGdhc1ByaWNlOiAnMTcnIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIGFyZ3VtZW50IGZvciBnYXNQcmljZSAtIG51bWJlciBleHBlY3RlZCcpO1xuXG4gICAgICAvLyB3YWxsZXRWZXJzaW9uIGlzIGEgbnVtYmVyXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5hZGQoeyBsYWJlbDogJ2xhYmVsJywgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLCBrZXlzOiBbXSwgbTogMiwgbjogMywgd2FsbGV0VmVyc2lvbjogJzEnIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIGFyZ3VtZW50IGZvciB3YWxsZXRWZXJzaW9uIC0gbnVtYmVyIGV4cGVjdGVkJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnY3JlYXRlcyBhIHBhaXJlZCBjdXN0b2RpYWwgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy93YWxsZXQvYWRkJywgZnVuY3Rpb24gKGJvZHkpIHtcbiAgICAgICAgICBib2R5LmlzQ3VzdG9kaWFsLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgICAgYm9keS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgna2V5cycpO1xuICAgICAgICAgIGJvZHkubS5zaG91bGQuZXF1YWwoMik7XG4gICAgICAgICAgYm9keS5uLnNob3VsZC5lcXVhbCgzKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwge30pO1xuICAgICAgYXdhaXQgd2FsbGV0cy5hZGQoeyBsYWJlbDogJ2xhYmVsJywgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLCBrZXlzOiBbXSwgbTogMiwgbjogMywgaXNDdXN0b2RpYWw6IHRydWUgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnY3JlYXRlcyBhbiBlb3Mgd2FsbGV0IHdpdGggY3VzdG9tIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBlb3NCaXRHbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICAgIGVvc0JpdEdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgICAgY29uc3QgZW9zV2FsbGV0cyA9IGVvc0JpdEdvLmNvaW4oJ3Rlb3MnKS53YWxsZXRzKCk7XG4gICAgICBjb25zdCBhZGRyZXNzID0gJ3Rlc3Rlb3NhZGRyZSc7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90ZW9zL3dhbGxldC9hZGQnLCBmdW5jdGlvbiAoYm9keSkge1xuICAgICAgICAgIGJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2tleXMnKTtcbiAgICAgICAgICBib2R5Lm0uc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgICAgIGJvZHkubi5zaG91bGQuZXF1YWwoMyk7XG4gICAgICAgICAgYm9keS5hZGRyZXNzLnNob3VsZC5lcXVhbChhZGRyZXNzKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwge30pO1xuICAgICAgYXdhaXQgZW9zV2FsbGV0cy5hZGQoeyBsYWJlbDogJ2xhYmVsJywgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLCBrZXlzOiBbXSwgbTogMiwgbjogMywgYWRkcmVzcyB9IGFzIGFueSk7XG4gICAgfSk7XG5cbiAgICBpdCgnY3JlYXRlcyBhIHNpbmdsZSBjdXN0b2RpYWwgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy93YWxsZXQvYWRkJywgZnVuY3Rpb24gKGJvZHkpIHtcbiAgICAgICAgICBib2R5LnR5cGUuc2hvdWxkLmVxdWFsKCdjdXN0b2RpYWwnKTtcbiAgICAgICAgICBib2R5LnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgna2V5cycpO1xuICAgICAgICAgIGJvZHkuc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCdtJyk7XG4gICAgICAgICAgYm9keS5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ24nKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwge30pO1xuICAgICAgYXdhaXQgd2FsbGV0cy5hZGQoeyBsYWJlbDogJ2xhYmVsJywgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLCB0eXBlOiAnY3VzdG9kaWFsJyB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdjcmVhdGVzIGEgd2FsbGV0IHdpdGggY3VzdG9tIGdhc1ByaWNlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXRoQml0R28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R28sIHsgZW52OiAnbW9jaycgfSk7XG4gICAgICBldGhCaXRHby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICAgIGNvbnN0IGV0aFdhbGxldHMgPSBldGhCaXRHby5jb2luKCd0ZXRoJykud2FsbGV0cygpO1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGV0aC93YWxsZXQvYWRkJywgZnVuY3Rpb24gKGJvZHkpIHtcbiAgICAgICAgICBib2R5LnR5cGUuc2hvdWxkLmVxdWFsKCdjdXN0b2RpYWwnKTtcbiAgICAgICAgICBib2R5Lmdhc1ByaWNlLnNob3VsZC5lcXVhbCgyMDAwMDAwMDAwMCk7XG4gICAgICAgICAgYm9keS5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ2tleXMnKTtcbiAgICAgICAgICBib2R5LnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgnbScpO1xuICAgICAgICAgIGJvZHkuc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCduJyk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHt9KTtcbiAgICAgIGF3YWl0IGV0aFdhbGxldHMuYWRkKHtcbiAgICAgICAgbGFiZWw6ICdsYWJlbCcsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgdHlwZTogJ2N1c3RvZGlhbCcsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgIH0gYXMgYW55KTtcbiAgICB9KTtcblxuICAgIGl0KCdjcmVhdGVzIGEgbmV3IHdhbGxldCB3aXRoIHdhbGxldFZlcnNpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBldGhCaXRHbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICAgIGV0aEJpdEdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgICAgY29uc3QgZXRoV2FsbGV0cyA9IGV0aEJpdEdvLmNvaW4oJ3RldGgnKS53YWxsZXRzKCk7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90ZXRoL3dhbGxldC9hZGQnLCBmdW5jdGlvbiAoYm9keSkge1xuICAgICAgICAgIGJvZHkudHlwZS5zaG91bGQuZXF1YWwoJ2N1c3RvZGlhbCcpO1xuICAgICAgICAgIGJvZHkud2FsbGV0VmVyc2lvbi5zaG91bGQuZXF1YWwoMSk7XG4gICAgICAgICAgYm9keS5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ2tleXMnKTtcbiAgICAgICAgICBib2R5LnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgnbScpO1xuICAgICAgICAgIGJvZHkuc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCduJyk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHt9KTtcbiAgICAgIGF3YWl0IGV0aFdhbGxldHMuYWRkKHsgbGFiZWw6ICdsYWJlbCcsIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJywgdHlwZTogJ2N1c3RvZGlhbCcsIHdhbGxldFZlcnNpb246IDEgfSBhcyBhbnkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2NyZWF0ZXMgYSBuZXcgaG90IHdhbGxldCB3aXRoIHVzZXJLZXknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL3dhbGxldC9hZGQnLCBmdW5jdGlvbiAoYm9keSkge1xuICAgICAgICAgIGJvZHkudHlwZS5zaG91bGQuZXF1YWwoJ2hvdCcpO1xuICAgICAgICAgIGJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2tleXMnKTtcbiAgICAgICAgICBib2R5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdtJyk7XG4gICAgICAgICAgYm9keS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnbicpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAwLCB7fSk7XG4gICAgICBhd2FpdCB3YWxsZXRzLmFkZCh7XG4gICAgICAgIGxhYmVsOiAnbGFiZWwnLFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHR5cGU6ICdob3QnLFxuICAgICAgICBrZXlzOiBbXSxcbiAgICAgICAgbTogMixcbiAgICAgICAgbjogMyxcbiAgICAgICAgdXNlcktleTogJ3Rlc3QxMjMnLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdHZW5lcmF0ZSB3YWxsZXQ6JywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSBwYXJhbWV0ZXJzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IHBhcmFtcyA9IHt9O1xuICAgICAgYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ01pc3NpbmcgcGFyYW1ldGVyOiBsYWJlbCcpO1xuXG4gICAgICBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnYWJjJyxcbiAgICAgICAgYmFja3VwWHB1YjogJ2JhY2t1cCcsXG4gICAgICAgIGJhY2t1cFhwdWJQcm92aWRlcjogJ3Byb3ZpZGVyJyxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgLmdlbmVyYXRlV2FsbGV0KHBhcmFtcylcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0Nhbm5vdCBwcm92aWRlIG1vcmUgdGhhbiBvbmUgYmFja3VwWHB1YiBvciBiYWNrdXBYcHViUHJvdmlkZXIgZmxhZycpO1xuXG4gICAgICBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnYWJjJyxcbiAgICAgICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogMTIzLFxuICAgICAgfTtcbiAgICAgIGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdwYXNzY29kZUVuY3J5cHRpb25Db2RlIG11c3QgYmUgYSBzdHJpbmcnKTtcblxuICAgICAgcGFyYW1zID0ge1xuICAgICAgICBsYWJlbDogJ2FiYycsXG4gICAgICAgIGVudGVycHJpc2U6IDEyMzQsXG4gICAgICB9O1xuICAgICAgYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgZW50ZXJwcmlzZSBhcmd1bWVudCwgZXhwZWN0aW5nIHN0cmluZycpO1xuXG4gICAgICBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnYWJjJyxcbiAgICAgICAgZGlzYWJsZVRyYW5zYWN0aW9uTm90aWZpY2F0aW9uczogJ3N0cmluZycsXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldChwYXJhbXMpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIGRpc2FibGVUcmFuc2FjdGlvbk5vdGlmaWNhdGlvbnMgYXJndW1lbnQsIGV4cGVjdGluZyBib29sZWFuJyk7XG5cbiAgICAgIHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdhYmMnLFxuICAgICAgICBnYXNQcmljZTogJ3N0cmluZycsXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldChwYXJhbXMpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIGdhcyBwcmljZSBhcmd1bWVudCwgZXhwZWN0aW5nIG51bWJlciBvciBudW1iZXIgYXMgc3RyaW5nJyk7XG5cbiAgICAgIHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdhYmMnLFxuICAgICAgICBnYXNQcmljZTogdHJ1ZSxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgLmdlbmVyYXRlV2FsbGV0KHBhcmFtcylcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgZ2FzIHByaWNlIGFyZ3VtZW50LCBleHBlY3RpbmcgbnVtYmVyIG9yIG51bWJlciBhcyBzdHJpbmcnKTtcblxuICAgICAgcGFyYW1zID0ge1xuICAgICAgICBsYWJlbDogJ2FiYycsXG4gICAgICAgIGdhc1ByaWNlOiAxMjMsXG4gICAgICAgIGVpcDE1NTk6IHtcbiAgICAgICAgICBtYXhGZWVQZXJHYXM6IDEyMzQsXG4gICAgICAgICAgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEyMyxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdjYW4gbm90IHVzZSBib3RoIGVpcDE1NTkgYW5kIGdhc1ByaWNlIHZhbHVlcycpO1xuXG4gICAgICBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnYWJjJyxcbiAgICAgICAgZWlwMTU1OToge1xuICAgICAgICAgIG1heEZlZVBlckdhczogJ3ExMjM0JyxcbiAgICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogJzEyMycsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldChwYXJhbXMpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIG1heCBmZWUgYXJndW1lbnQsIGV4cGVjdGluZyBudW1iZXIgb3IgbnVtYmVyIGFzIHN0cmluZycpO1xuXG4gICAgICBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnYWJjJyxcbiAgICAgICAgZWlwMTU1OToge1xuICAgICAgICAgIG1heEZlZVBlckdhczogMTIzNCxcbiAgICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogJzEyM2EnLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnaW52YWxpZCBwcmlvcml0eSBmZWUgYXJndW1lbnQsIGV4cGVjdGluZyBudW1iZXIgb3IgbnVtYmVyIGFzIHN0cmluZycpO1xuXG4gICAgICBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnYWJjJyxcbiAgICAgICAgZGlzYWJsZUtSU0VtYWlsOiAnc3RyaW5nJyxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgLmdlbmVyYXRlV2FsbGV0KHBhcmFtcylcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgZGlzYWJsZUtSU0VtYWlsIGFyZ3VtZW50LCBleHBlY3RpbmcgYm9vbGVhbicpO1xuXG4gICAgICBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnYWJjJyxcbiAgICAgICAga3JzU3BlY2lmaWM6IHtcbiAgICAgICAgICBtYWxpY2lvdXM6IHtcbiAgICAgICAgICAgIGphdmFzY3JpcHQ6IHtcbiAgICAgICAgICAgICAgY29kZTogJ2JhZC5qcycsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldChwYXJhbXMpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdrcnNTcGVjaWZpYyBvYmplY3QgY29udGFpbnMgaWxsZWdhbCB2YWx1ZXMuIHZhbHVlcyBtdXN0IGJlIHN0cmluZ3MsIGJvb2xlYW5zLCBvciBudW1iZXJzJ1xuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb3JyZWN0bHkgZGlzYWJsZSBrcnMgZW1haWxzIHdoZW4gY3JlYXRpbmcgYmFja3VwIGtleWNoYWlucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdteV93YWxsZXQnLFxuICAgICAgICBkaXNhYmxlS1JTRW1haWw6IHRydWUsXG4gICAgICAgIGJhY2t1cFhwdWJQcm92aWRlcjogJ3Rlc3QnLFxuICAgICAgICBwYXNzcGhyYXNlOiAndGVzdDEyMycsXG4gICAgICAgIHVzZXJLZXk6ICd4cHViMTIzJyxcbiAgICAgIH07XG5cbiAgICAgIC8vIGJpdGdvIGtleVxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLm1hdGNoZXMoeyBzb3VyY2U6ICdiaXRnbycgfSkpXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAvLyB1c2VyIGtleVxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLmNvbmZvcm1zKHsgcHViOiAocCkgPT4gcC5zdGFydHNXaXRoKCd4cHViJykgfSkpXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAvLyBiYWNrdXAga2V5XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChcbiAgICAgICAgICAnL2FwaS92Mi90YnRjL2tleScsXG4gICAgICAgICAgXy5tYXRjaGVzKHtcbiAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgICBwcm92aWRlcjogcGFyYW1zLmJhY2t1cFhwdWJQcm92aWRlcixcbiAgICAgICAgICAgIGRpc2FibGVLUlNFbWFpbDogdHJ1ZSxcbiAgICAgICAgICB9KVxuICAgICAgICApXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAvLyB3YWxsZXRcbiAgICAgIG5vY2soYmdVcmwpLnBvc3QoJy9hcGkvdjIvdGJ0Yy93YWxsZXQvYWRkJykucmVwbHkoMjAwKTtcblxuICAgICAgYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb3JyZWN0bHkgcGFzcyB0aHJvdWdoIHRoZSBrcnNTcGVjaWZpYyBwYXJhbSB3aGVuIGNyZWF0aW5nIGJhY2t1cCBrZXljaGFpbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnbXlfd2FsbGV0JyxcbiAgICAgICAgYmFja3VwWHB1YlByb3ZpZGVyOiAndGVzdCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICd0ZXN0MTIzJyxcbiAgICAgICAgdXNlcktleTogJ3hwdWIxMjMnLFxuICAgICAgICBrcnNTcGVjaWZpYzogeyBjb3ZlcmFnZTogJ2luc3VyYW5jZScsIGV4cGVuc2l2ZTogdHJ1ZSwgaG93RXhwZW5zaXZlOiAyNSB9LFxuICAgICAgfTtcblxuICAgICAgLy8gYml0Z28ga2V5XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7IHNvdXJjZTogJ2JpdGdvJyB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIC8vIHVzZXIga2V5XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8uY29uZm9ybXMoeyBwdWI6IChwKSA9PiBwLnN0YXJ0c1dpdGgoJ3hwdWInKSB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIC8vIGJhY2t1cCBrZXlcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KFxuICAgICAgICAgICcvYXBpL3YyL3RidGMva2V5JyxcbiAgICAgICAgICBfLm1hdGNoZXMoe1xuICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICAgIHByb3ZpZGVyOiBwYXJhbXMuYmFja3VwWHB1YlByb3ZpZGVyLFxuICAgICAgICAgICAga3JzU3BlY2lmaWM6IHsgY292ZXJhZ2U6ICdpbnN1cmFuY2UnLCBleHBlbnNpdmU6IHRydWUsIGhvd0V4cGVuc2l2ZTogMjUgfSxcbiAgICAgICAgICB9KVxuICAgICAgICApXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAvLyB3YWxsZXRcbiAgICAgIG5vY2soYmdVcmwpLnBvc3QoJy9hcGkvdjIvdGJ0Yy93YWxsZXQvYWRkJykucmVwbHkoMjAwKTtcblxuICAgICAgYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzZW5kIHRoZSBjb2xkIGRlcml2YXRpb24gc2VlZCBmb3IgYSB1c2VyIGtleScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdteS1jb2xkLXdhbGxldCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICd0ZXN0MTIzJyxcbiAgICAgICAgdXNlcktleTpcbiAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0Z0WGdTNXNZSkFCcXFHOVlMbUM0UTFSZGFwOWdTRThOcXR3eWJHaGVQWTJnWjI5RVNGanFKb0N1MVJ1cGplOFl0R3FzZWZEMjY1VE1nN3VzVURGZHA2VzFFR01jZXQ4JyxcbiAgICAgICAgY29sZERlcml2YXRpb25TZWVkOiAnMTIzJyxcbiAgICAgIH07XG5cbiAgICAgIC8vIGJpdGdvIGtleVxuICAgICAgY29uc3QgYml0Z29LZXlOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLm1hdGNoZXMoeyBzb3VyY2U6ICdiaXRnbycgfSkpXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAvLyB1c2VyIGtleVxuICAgICAgY29uc3QgdXNlcktleU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChcbiAgICAgICAgICAnL2FwaS92Mi90YnRjL2tleScsXG4gICAgICAgICAgXy5tYXRjaGVzKHtcbiAgICAgICAgICAgIGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQ6IHBhcmFtcy5jb2xkRGVyaXZhdGlvblNlZWQsXG4gICAgICAgICAgfSlcbiAgICAgICAgKVxuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgLy8gYmFja3VwIGtleVxuICAgICAgY29uc3QgYmFja3VwS2V5Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMva2V5JywgXy5tYXRjaGVzKHsgc291cmNlOiAnYmFja3VwJyB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIC8vIHdhbGxldFxuICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soYmdVcmwpLnBvc3QoJy9hcGkvdjIvdGJ0Yy93YWxsZXQvYWRkJykucmVwbHkoMjAwKTtcblxuICAgICAgYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuICAgICAgZm9yIChjb25zdCBzY29wZSBvZiBbYml0Z29LZXlOb2NrLCB1c2VyS2V5Tm9jaywgYmFja3VwS2V5Tm9jaywgd2FsbGV0Tm9ja10pIHtcbiAgICAgICAgc2NvcGUuZG9uZSgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBjdXN0b2RpYWwgb25jaGFpbiB3YWxsZXQgd2l0aG91dCBwYXNzaW5nIG0sIG4sIGtleXMsIGtleVNpZ25hdHVyZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBwYXJhbXM6IEdlbmVyYXRlV2FsbGV0T3B0aW9ucyA9IHtcbiAgICAgICAgbGFiZWw6ICd0ZXN0IHdhbGxldCcsXG4gICAgICAgIGVudGVycHJpc2U6ICdteWVudGVycHJpc2UnLFxuICAgICAgICB0eXBlOiAnY3VzdG9kaWFsJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHdhbGxldE5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL3dhbGxldC9hZGQnLCBmdW5jdGlvbiAoYm9keSkge1xuICAgICAgICAgIGJvZHkudHlwZS5zaG91bGQuZXF1YWwoJ2N1c3RvZGlhbCcpO1xuICAgICAgICAgIHNob3VsZC5ub3QuZXhpc3QoYm9keS5tKTtcbiAgICAgICAgICBzaG91bGQubm90LmV4aXN0KGJvZHkubik7XG4gICAgICAgICAgc2hvdWxkLm5vdC5leGlzdChib2R5LmtleXMpO1xuICAgICAgICAgIHNob3VsZC5ub3QuZXhpc3QoYm9keS5rZXlTaWduYXR1cmVzKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBpZDogJzEyMycsIGJhc2VDb2luOiBiaXRnby5jb2luKCd0YnRjJyksIGtleXM6IFsnMTIzJywgJzQ1NicsICc3ODknXSB9KTtcblxuICAgICAgbm9jayhiZ1VybCkuZ2V0KCcvYXBpL3YyL3RidGMva2V5LzEyMycpLnJlcGx5KDIwMCwgeyBwdWI6ICdiaXRnb1B1YicsIGlkOiAnNzg5JyB9KTtcbiAgICAgIG5vY2soYmdVcmwpLmdldCgnL2FwaS92Mi90YnRjL2tleS80NTYnLCBfLm1hdGNoZXMoe30pKS5yZXBseSgyMDApO1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KCcvYXBpL3YyL3RidGMva2V5Lzc4OScpLnJlcGx5KDIwMCwgeyBwdWI6ICdiYWNrdXBQdWInLCBpZDogJzc4OScgfSk7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuXG4gICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlID09PSB1bmRlZmluZWQpO1xuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLndhbGxldCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGhvdCBvbmNoYWluIHdhbGxldCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHBhcmFtczogR2VuZXJhdGVXYWxsZXRPcHRpb25zID0ge1xuICAgICAgICBsYWJlbDogJ3Rlc3Qgd2FsbGV0JyxcbiAgICAgICAgcGFzc3BocmFzZTogJ211bHRpc2lnIHBhc3N3b3JkJyxcbiAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHdhbGxldE5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL3dhbGxldC9hZGQnLCBmdW5jdGlvbiAoYm9keSkge1xuICAgICAgICAgIGJvZHkudHlwZS5zaG91bGQuZXF1YWwoJ2hvdCcpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLm1hdGNoZXMoeyBzb3VyY2U6ICdiaXRnbycgfSkpXG4gICAgICAgIC5yZXBseSgyMDAsIHsgcHViOiAnYml0Z29QdWInIH0pO1xuICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7fSkpLnJlcGx5KDIwMCk7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7IHNvdXJjZTogJ2JhY2t1cCcgfSkpXG4gICAgICAgIC5yZXBseSgyMDAsIHsgcHViOiAnYmFja3VwUHViJyB9KTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG5cbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLndhbGxldCk7XG4gICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgIGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogcmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSwgcGFzc3dvcmQ6IHBhcmFtcy5wYXNzY29kZUVuY3J5cHRpb25Db2RlIH0pLFxuICAgICAgICBwYXJhbXMucGFzc3BocmFzZVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgaG90IG9uY2hhaW4gd2FsbGV0IHdpdGhvdXQgcGFzc2luZyBtdWx0aXNpZyB0eXBlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcGFyYW1zOiBHZW5lcmF0ZVdhbGxldE9wdGlvbnMgPSB7XG4gICAgICAgIGxhYmVsOiAndGVzdCB3YWxsZXQnLFxuICAgICAgICBwYXNzcGhyYXNlOiAnbXVsdGlzaWcgcGFzc3dvcmQnLFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMvd2FsbGV0L2FkZCcsIGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgYm9keS50eXBlLnNob3VsZC5lcXVhbCgnaG90Jyk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7IHNvdXJjZTogJ2JpdGdvJyB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBwdWI6ICdiaXRnb1B1YicgfSk7XG4gICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YyL3RidGMva2V5JywgXy5tYXRjaGVzKHt9KSkucmVwbHkoMjAwKTtcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMva2V5JywgXy5tYXRjaGVzKHsgc291cmNlOiAnYmFja3VwJyB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBwdWI6ICdiYWNrdXBQdWInIH0pO1xuXG4gICAgICBjb25zdCBnZW5lcmF0ZVdhbGxldFNweSA9IHNhbmRib3guc3B5KHdhbGxldHMsICdnZW5lcmF0ZVdhbGxldCcpO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG4gICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShnZW5lcmF0ZVdhbGxldFNweSk7XG4gICAgICBhc3NlcnQuZXF1YWwoZ2VuZXJhdGVXYWxsZXRTcHkuZmlyc3RDYWxsPy5hcmdzWzBdPy5tdWx0aXNpZ1R5cGUsIG11bHRpc2lnVHlwZXMub25jaGFpbik7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiByZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlLCBwYXNzd29yZDogcGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUgfSksXG4gICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBHbyBBY2NvdW50IHdhbGxldCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHBhcmFtczogR2VuZXJhdGVXYWxsZXRPcHRpb25zID0ge1xuICAgICAgICBsYWJlbDogJ0dvIEFjY291bnQgV2FsbGV0JyxcbiAgICAgICAgcGFzc3BocmFzZTogJ2dvX2FjY291bnRfcGFzc3dvcmQnLFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZS1pZCcsXG4gICAgICAgIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgICB0eXBlOiAndHJhZGluZycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBrZXljaGFpbklkID0gJ3VzZXJfa2V5Y2hhaW5faWQnO1xuXG4gICAgICAvLyBNb2NrIGtleWNoYWluIGNyZWF0aW9uIGFuZCB1cGxvYWRcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL29mYy9rZXknLCBmdW5jdGlvbiAoYm9keSkge1xuICAgICAgICAgIGJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2VuY3J5cHRlZFBydicpO1xuICAgICAgICAgIGJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ29yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZScpO1xuICAgICAgICAgIGJvZHkua2V5VHlwZS5zaG91bGQuZXF1YWwoJ2luZGVwZW5kZW50Jyk7XG4gICAgICAgICAgYm9keS5zb3VyY2Uuc2hvdWxkLmVxdWFsKCd1c2VyJyk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHsgaWQ6IGtleWNoYWluSWQsIHB1YjogJ3VzZXJQdWInLCBlbmNyeXB0ZWRQcnY6ICdlbmNyeXB0ZWRQcml2YXRlS2V5JyB9KTtcblxuICAgICAgLy8gTW9jayB3YWxsZXQgY3JlYXRpb25cbiAgICAgIGNvbnN0IHdhbGxldE5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi9vZmMvd2FsbGV0L2FkZCcsIGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgYm9keS50eXBlLnNob3VsZC5lcXVhbCgndHJhZGluZycpO1xuICAgICAgICAgIGJvZHkubS5zaG91bGQuZXF1YWwoMSk7XG4gICAgICAgICAgYm9keS5uLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgICAgICBib2R5LmtleXMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgICAgIGJvZHkua2V5c1swXS5zaG91bGQuZXF1YWwoa2V5Y2hhaW5JZCk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHsgaWQ6ICd3YWxsZXQxMjMnLCBrZXlzOiBba2V5Y2hhaW5JZF0gfSk7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgb2ZjV2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuXG4gICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS53YWxsZXQpO1xuICAgICAgYXNzZXJ0Lm9rKCd1c2VyS2V5Y2hhaW4nIGluIHJlc3BvbnNlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0dlbmVyYXRlIFRTUyB3YWxsZXQ6JywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHRzb2wgPSBiaXRnby5jb2luKCd0c29sJyk7XG4gICAgY29uc3Qgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgLmdldChgL2FwaS92Mi90c3Mvc2V0dGluZ3NgKVxuICAgICAgICAudGltZXMoMilcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGNvaW5TZXR0aW5nczoge1xuICAgICAgICAgICAgZXRoOiB7XG4gICAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHt9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGJzYzoge1xuICAgICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7fSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwb2x5Z29uOiB7XG4gICAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHt9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgICBzYW5kYm94LnZlcmlmeUFuZFJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGEgbmV3IFRTUyB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgdXNlcktleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBwdWI6ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB9LFxuICAgICAgICBiYWNrdXBLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgcHViOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0tleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBwdWI6ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBzYW5kYm94LnN0dWIoVHNzVXRpbHMucHJvdG90eXBlLCAnY3JlYXRlS2V5Y2hhaW5zJykucmVzb2x2ZXMoc3R1YmJlZEtleWNoYWluc1RyaXBsZXQpO1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJykucG9zdCgnL2FwaS92Mi90c29sL3dhbGxldC9hZGQnKS5yZXBseSgyMDApO1xuXG4gICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRzb2wpO1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAndHNzIHdhbGxldCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICd0c3MgcGFzc3dvcmQnLFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnIGFzIGFueSxcbiAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuXG4gICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS53YWxsZXQpO1xuICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICBhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UsIHBhc3N3b3JkOiBwYXJhbXMucGFzc2NvZGVFbmNyeXB0aW9uQ29kZSB9KSxcbiAgICAgICAgcGFyYW1zLnBhc3NwaHJhc2VcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIG5ldyBUU1Mgd2FsbGV0IHdpdGhvdXQgcGFzc2luZyBtdWx0aXNpZyB0eXBlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc3R1YmJlZEtleWNoYWluc1RyaXBsZXQ6IEtleWNoYWluc1RyaXBsZXQgPSB7XG4gICAgICAgIHVzZXJLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgcHViOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgfSxcbiAgICAgICAgYmFja3VwS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzInLFxuICAgICAgICAgIHB1YjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgfSxcbiAgICAgICAgYml0Z29LZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMycsXG4gICAgICAgICAgcHViOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgc2FuZGJveC5zdHViKFRzc1V0aWxzLnByb3RvdHlwZSwgJ2NyZWF0ZUtleWNoYWlucycpLnJlc29sdmVzKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcblxuICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3Rzb2wvd2FsbGV0L2FkZCcsIGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgYm9keS5tdWx0aXNpZ1R5cGUuc2hvdWxkLmVxdWFsKG11bHRpc2lnVHlwZXMudHNzKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdHNvbCk7XG5cbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICd0c3Mgd2FsbGV0JyxcbiAgICAgICAgcGFzc3BocmFzZTogJ3RzcyBwYXNzd29yZCcsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJ29yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBnZW5lcmF0ZVdhbGxldFNweSA9IHNhbmRib3guc3B5KHdhbGxldHMsICdnZW5lcmF0ZVdhbGxldCcpO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG4gICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShnZW5lcmF0ZVdhbGxldFNweSk7XG4gICAgICBhc3NlcnQuZXF1YWwoZ2VuZXJhdGVXYWxsZXRTcHkuZmlyc3RDYWxsPy5hcmdzWzBdPy5tdWx0aXNpZ1R5cGUsIG11bHRpc2lnVHlwZXMudHNzKTtcbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS53YWxsZXQpO1xuICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICBhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UsIHBhc3N3b3JkOiBwYXJhbXMucGFzc2NvZGVFbmNyeXB0aW9uQ29kZSB9KSxcbiAgICAgICAgcGFyYW1zLnBhc3NwaHJhc2VcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIG5ldyBUU1Mgd2FsbGV0IHdpdGhvdXQgcHJvdmlkaW5nIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgdXNlcktleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBwdWI6ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB9LFxuICAgICAgICBiYWNrdXBLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgcHViOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0tleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBwdWI6ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBzYW5kYm94LnN0dWIoVHNzVXRpbHMucHJvdG90eXBlLCAnY3JlYXRlS2V5Y2hhaW5zJykucmVzb2x2ZXMoc3R1YmJlZEtleWNoYWluc1RyaXBsZXQpO1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJykucG9zdCgnL2FwaS92Mi90c29sL3dhbGxldC9hZGQnKS5yZXBseSgyMDApO1xuXG4gICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRzb2wpO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQoe1xuICAgICAgICBsYWJlbDogJ3RzcyB3YWxsZXQnLFxuICAgICAgICBwYXNzcGhyYXNlOiAndHNzIHBhc3N3b3JkJyxcbiAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgfSk7XG5cbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLndhbGxldCk7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSA9PT0gdW5kZWZpbmVkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byBjcmVhdGUgVFNTIHdhbGxldCB3aXRoIGludmFsaWQgaW5wdXRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdGJ0YyA9IGJpdGdvLmNvaW4oJ3RidGMnKTtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdteS1jb2xkLXdhbGxldCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICd0ZXN0MTIzJyxcbiAgICAgICAgdXNlcktleTpcbiAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0Z0WGdTNXNZSkFCcXFHOVlMbUM0UTFSZGFwOWdTRThOcXR3eWJHaGVQWTJnWjI5RVNGanFKb0N1MVJ1cGplOFl0R3FzZWZEMjY1VE1nN3VzVURGZHA2VzFFR01jZXQ4JyxcbiAgICAgICAgY29sZERlcml2YXRpb25TZWVkOiAnMTIzJyxcbiAgICAgIH07XG4gICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRidGMpO1xuXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7IHNvdXJjZTogJ2JpdGdvJyB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMva2V5JywgXy5tYXRjaGVzKHsgZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZDogcGFyYW1zLmNvbGREZXJpdmF0aW9uU2VlZCB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7IHNvdXJjZTogJ2JhY2t1cCcgfSkpXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YyL3RidGMvd2FsbGV0L2FkZCcpLnJlcGx5KDIwMCk7XG5cbiAgICAgIC8vIGNyZWF0ZSBhIG5vbiB0c3Mgd2FsbGV0IGZvciBjb2luIHRoYXQgZG9lc24ndCBzdXBwb3J0IHRzcyBldmVuIHRob3VnaCBtdWx0aXNpZ1R5cGUgaXMgc2V0IHRvIHRzc1xuICAgICAgYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldCh7IC4uLnBhcmFtcywgbXVsdGlzaWdUeXBlOiAndHNzJyB9KTtcblxuICAgICAgY29uc3QgdHNvbFdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdHNvbCk7XG5cbiAgICAgIGF3YWl0IHRzb2xXYWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldCh7XG4gICAgICAgICAgbGFiZWw6ICd0c3MgY29sZCB3YWxsZXQnLFxuICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzcGhyYXNlJyxcbiAgICAgICAgICB1c2VyS2V5OiAndXNlciBrZXknLFxuICAgICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdlbnRlcnByaXNlIGlzIHJlcXVpcmVkIGZvciBUU1Mgd2FsbGV0Jyk7XG5cbiAgICAgIGF3YWl0IHRzb2xXYWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldCh7XG4gICAgICAgICAgbGFiZWw6ICd0c3MgY29sZCB3YWxsZXQnLFxuICAgICAgICAgIHVzZXJLZXk6ICd1c2VyIGtleScsXG4gICAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZUlkJyxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2Nhbm5vdCBnZW5lcmF0ZSBUU1Mga2V5cyB3aXRob3V0IHBhc3NwaHJhc2UnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGEgbmV3IFRTUyBjdXN0b2RpYWwgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qga2V5cyA9IFsnMScsICcyJywgJzMnXTtcblxuICAgICAgY29uc3Qgd2FsbGV0UGFyYW1zOiBHZW5lcmF0ZVdhbGxldE9wdGlvbnMgPSB7XG4gICAgICAgIGxhYmVsOiAndHNzIHdhbGxldCcsXG4gICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgdHlwZTogJ2N1c3RvZGlhbCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdHNvbC93YWxsZXQvYWRkJylcbiAgICAgICAgLnRpbWVzKDEpXG4gICAgICAgIC5yZXBseSgyMDAsIHsgLi4ud2FsbGV0UGFyYW1zLCBrZXlzIH0pO1xuXG4gICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRzb2wpO1xuXG4gICAgICBjb25zdCByZXMgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHdhbGxldFBhcmFtcyk7XG4gICAgICBpZiAoIWlzV2FsbGV0V2l0aEtleWNoYWlucyhyZXMpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignd2FsbGV0IG1pc3NpbmcgcmVxdWlyZWQga2V5Y2hhaW5zJyk7XG4gICAgICB9XG4gICAgICByZXMud2FsbGV0LmxhYmVsKCkuc2hvdWxkLmVxdWFsKHdhbGxldFBhcmFtcy5sYWJlbCk7XG4gICAgICBzaG91bGQuZXF1YWwocmVzLndhbGxldC50eXBlKCksIHdhbGxldFBhcmFtcy50eXBlKTtcbiAgICAgIHJlcy53YWxsZXQudG9KU09OKCkuZW50ZXJwcmlzZS5zaG91bGQuZXF1YWwod2FsbGV0UGFyYW1zLmVudGVycHJpc2UpO1xuICAgICAgcmVzLndhbGxldC5tdWx0aXNpZ1R5cGUoKS5zaG91bGQuZXF1YWwod2FsbGV0UGFyYW1zLm11bHRpc2lnVHlwZSk7XG4gICAgICByZXMudXNlcktleWNoYWluLmlkLnNob3VsZC5lcXVhbChrZXlzWzBdKTtcbiAgICAgIHJlcy5iYWNrdXBLZXljaGFpbi5pZC5zaG91bGQuZXF1YWwoa2V5c1sxXSk7XG4gICAgICByZXMuYml0Z29LZXljaGFpbi5pZC5zaG91bGQuZXF1YWwoa2V5c1syXSk7XG5cbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGEgbmV3IEZMUlAgVFNTIGN1c3RvZGlhbCB3YWxsZXQgd2l0aG91dCByZXF1aXJpbmcgYSBwYXNzcGhyYXNlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qga2V5cyA9IFsnMScsICcyJywgJzMnXTtcbiAgICAgIGNvbnN0IHRmbHJwID0gYml0Z28uY29pbigndGZscnAnKTtcblxuICAgICAgY29uc3Qgd2FsbGV0UGFyYW1zOiBHZW5lcmF0ZVdhbGxldE9wdGlvbnMgPSB7XG4gICAgICAgIGxhYmVsOiAnZmxycCBjdXN0b2RpYWwgd2FsbGV0JyxcbiAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICB0eXBlOiAnY3VzdG9kaWFsJyxcbiAgICAgICAgLy8gTm8gbXVsdGlzaWdUeXBlIHNwZWNpZmllZCDigJQgc2hvdWxkIGRlZmF1bHQgdG8gJ3RzcycgZm9yIEZMUlBcbiAgICAgICAgLy8gTm8gcGFzc3BocmFzZSDigJQgY3VzdG9kaWFsIHdhbGxldHMgbXVzdCBub3QgcmVxdWlyZSBvbmVcbiAgICAgIH07XG5cbiAgICAgIC8vIEZMUlAgaXMgRUNEU0EsIHNvIGdlbmVyYXRlQ3VzdG9kaWFsTXBjV2FsbGV0IGZldGNoZXMgVFNTIHNldHRpbmdzXG4gICAgICBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAuZ2V0KCcvYXBpL3YyL3Rzcy9zZXR0aW5ncycpXG4gICAgICAgIC5yZXBseSgyMDAsIHsgY29pblNldHRpbmdzOiB7IGZscnA6IHsgd2FsbGV0Q3JlYXRpb25TZXR0aW5nczoge30gfSB9IH0pO1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGZscnAvd2FsbGV0L2FkZCcpXG4gICAgICAgIC50aW1lcygxKVxuICAgICAgICAucmVwbHkoMjAwLCB7IC4uLndhbGxldFBhcmFtcywgbXVsdGlzaWdUeXBlOiAndHNzJywga2V5cyB9KTtcblxuICAgICAgY29uc3QgZmxycFdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdGZscnApO1xuXG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBmbHJwV2FsbGV0cy5nZW5lcmF0ZVdhbGxldCh3YWxsZXRQYXJhbXMpO1xuICAgICAgaWYgKCFpc1dhbGxldFdpdGhLZXljaGFpbnMocmVzKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3dhbGxldCBtaXNzaW5nIHJlcXVpcmVkIGtleWNoYWlucycpO1xuICAgICAgfVxuICAgICAgcmVzLndhbGxldC5sYWJlbCgpLnNob3VsZC5lcXVhbCh3YWxsZXRQYXJhbXMubGFiZWwpO1xuICAgICAgc2hvdWxkLmVxdWFsKHJlcy53YWxsZXQudHlwZSgpLCB3YWxsZXRQYXJhbXMudHlwZSk7XG4gICAgICByZXMud2FsbGV0Lm11bHRpc2lnVHlwZSgpLnNob3VsZC5lcXVhbCgndHNzJyk7XG4gICAgICByZXMudXNlcktleWNoYWluLmlkLnNob3VsZC5lcXVhbChrZXlzWzBdKTtcbiAgICAgIHJlcy5iYWNrdXBLZXljaGFpbi5pZC5zaG91bGQuZXF1YWwoa2V5c1sxXSk7XG4gICAgICByZXMuYml0Z29LZXljaGFpbi5pZC5zaG91bGQuZXF1YWwoa2V5c1syXSk7XG5cbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGEgbmV3IFRTUyBTTUMgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29tbW9uS2V5Y2hhaW4gPSAnbG9uZ3N0cmluZyc7XG4gICAgICBjb25zdCBzZWVkID0gJ3NlZWQnO1xuICAgICAgY29uc3Qga2V5czogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgdXNlcktleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkOiBzZWVkLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB9LFxuICAgICAgICBiYWNrdXBLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZDogc2VlZCxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0tleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBiaXRnb0tleU5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKS5nZXQoJy9hcGkvdjIvdHNvbC9rZXkvMycpLnJlcGx5KDIwMCwga2V5cy5iaXRnb0tleWNoYWluKTtcbiAgICAgIGNvbnN0IHVzZXJLZXlFeHBlY3RlZEJvZHkgPSB7XG4gICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICBrZXlUeXBlOiAndHNzJyxcbiAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgIGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQ6IHNlZWQsXG4gICAgICB9O1xuICAgICAgY29uc3QgdXNlcktleU5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90c29sL2tleScsIHVzZXJLZXlFeHBlY3RlZEJvZHkpXG4gICAgICAgIC5yZXBseSgyMDAsIGtleXMudXNlcktleWNoYWluKTtcbiAgICAgIGNvbnN0IGJhY2t1cEtleUV4cGVjdGVkQm9keSA9IHtcbiAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAga2V5VHlwZTogJ3RzcycsXG4gICAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgICBkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkOiBzZWVkLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGJhY2t1cEtleU5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90c29sL2tleScsIGJhY2t1cEtleUV4cGVjdGVkQm9keSlcbiAgICAgICAgLnJlcGx5KDIwMCwga2V5cy5iYWNrdXBLZXljaGFpbik7XG5cbiAgICAgIGNvbnN0IHdhbGxldFBhcmFtczogR2VuZXJhdGVXYWxsZXRPcHRpb25zID0ge1xuICAgICAgICBsYWJlbDogJ3RzcyB3YWxsZXQnLFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHR5cGU6ICdjb2xkJyxcbiAgICAgICAgYml0Z29LZXlJZDoga2V5cy5iaXRnb0tleWNoYWluLmlkLFxuICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgY29sZERlcml2YXRpb25TZWVkOiBzZWVkLFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgd2FsbGV0Tm9ja0V4cGVjdGVkID0ge1xuICAgICAgICBsYWJlbDogd2FsbGV0UGFyYW1zLmxhYmVsLFxuICAgICAgICBtOiAyLFxuICAgICAgICBuOiAzLFxuICAgICAgICBrZXlzOiBba2V5cy51c2VyS2V5Y2hhaW4uaWQsIGtleXMuYmFja3VwS2V5Y2hhaW4uaWQsIGtleXMuYml0Z29LZXljaGFpbi5pZF0sXG4gICAgICAgIHR5cGU6IHdhbGxldFBhcmFtcy50eXBlLFxuICAgICAgICBtdWx0aXNpZ1R5cGU6IHdhbGxldFBhcmFtcy5tdWx0aXNpZ1R5cGUsXG4gICAgICAgIGVudGVycHJpc2U6IHdhbGxldFBhcmFtcy5lbnRlcnByaXNlLFxuICAgICAgICB3YWxsZXRWZXJzaW9uOiB1bmRlZmluZWQsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdHNvbC93YWxsZXQvYWRkJywgd2FsbGV0Tm9ja0V4cGVjdGVkKVxuICAgICAgICAucmVwbHkoMjAwLCB7IC4uLndhbGxldE5vY2tFeHBlY3RlZCwgcmVzcG9uc2VUeXBlOiAnV2FsbGV0V2l0aEtleWNoYWlucycgfSk7XG5cbiAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdHNvbCk7XG5cbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQod2FsbGV0UGFyYW1zKTtcbiAgICAgIGlmICghaXNXYWxsZXRXaXRoS2V5Y2hhaW5zKHJlcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd3YWxsZXQgbWlzc2luZyByZXF1aXJlZCBrZXljaGFpbnMnKTtcbiAgICAgIH1cbiAgICAgIHJlcy5yZXNwb25zZVR5cGUuc2hvdWxkLmVxdWFsKCdXYWxsZXRXaXRoS2V5Y2hhaW5zJyk7XG4gICAgICByZXMud2FsbGV0LmxhYmVsKCkuc2hvdWxkLmVxdWFsKHdhbGxldFBhcmFtcy5sYWJlbCk7XG4gICAgICBzaG91bGQuZXF1YWwocmVzLndhbGxldC50eXBlKCksIHdhbGxldFBhcmFtcy50eXBlKTtcbiAgICAgIHJlcy53YWxsZXQudG9KU09OKCkuZW50ZXJwcmlzZS5zaG91bGQuZXF1YWwod2FsbGV0UGFyYW1zLmVudGVycHJpc2UpO1xuICAgICAgcmVzLndhbGxldC5tdWx0aXNpZ1R5cGUoKS5zaG91bGQuZXF1YWwod2FsbGV0UGFyYW1zLm11bHRpc2lnVHlwZSk7XG4gICAgICByZXMudXNlcktleWNoYWluLnNob3VsZC5kZWVwRXF1YWwoa2V5cy51c2VyS2V5Y2hhaW4pO1xuICAgICAgcmVzLmJhY2t1cEtleWNoYWluLnNob3VsZC5kZWVwRXF1YWwoa2V5cy5iYWNrdXBLZXljaGFpbik7XG4gICAgICByZXMuYml0Z29LZXljaGFpbi5zaG91bGQuZGVlcEVxdWFsKGtleXMuYml0Z29LZXljaGFpbik7XG5cbiAgICAgIGJpdGdvS2V5Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgdXNlcktleU5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIGJhY2t1cEtleU5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3IgZm9yIFRTUyBTTUMgd2FsbGV0IGlmIHRoZSBiaXRnb0tleUlkIGlzIG5vdCBhIGJpdGdvIGtleSAnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb21tb25LZXljaGFpbiA9ICdsb25nc3RyaW5nJztcbiAgICAgIGNvbnN0IHNlZWQgPSAnc2VlZCc7XG4gICAgICBjb25zdCBrZXlzOiBLZXljaGFpbnNUcmlwbGV0ID0ge1xuICAgICAgICB1c2VyS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQ6IHNlZWQsXG4gICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIH0sXG4gICAgICAgIGJhY2t1cEtleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcyJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkOiBzZWVkLFxuICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgIH0sXG4gICAgICAgIGJpdGdvS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzMnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGJpdGdvS2V5Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLmdldCgnL2FwaS92Mi90c29sL2tleS8xJykucmVwbHkoMjAwLCBrZXlzLnVzZXJLZXljaGFpbik7XG5cbiAgICAgIGNvbnN0IHdhbGxldFBhcmFtczogR2VuZXJhdGVXYWxsZXRPcHRpb25zID0ge1xuICAgICAgICBsYWJlbDogJ3RzcyB3YWxsZXQnLFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHR5cGU6ICdjb2xkJyxcbiAgICAgICAgYml0Z29LZXlJZDoga2V5cy51c2VyS2V5Y2hhaW4uaWQsXG4gICAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgICBjb2xkRGVyaXZhdGlvblNlZWQ6IHNlZWQsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRzb2wpO1xuXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldCh3YWxsZXRQYXJhbXMpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdUaGUgcHJvdmlkZWQgYml0Z29LZXlJZCBpcyBub3QgYSBCaXRHbyBrZXljaGFpbicpO1xuXG4gICAgICBiaXRnb0tleU5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0dlbmVyYXRlIFRTUyBNUEN2MiB3YWxsZXQ6JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRzc1NldHRpbmdzOiBUc3NTZXR0aW5ncyA9IHtcbiAgICAgICAgY29pblNldHRpbmdzOiB7XG4gICAgICAgICAgZXRoOiB7XG4gICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGNvbGRNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjdXN0b2RpYWxNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJzYzoge1xuICAgICAgICAgICAgd2FsbGV0Q3JlYXRpb25TZXR0aW5nczoge1xuICAgICAgICAgICAgICBtdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjb2xkTXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgICAgY3VzdG9kaWFsTXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBwb2x5Z29uOiB7XG4gICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGNvbGRNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjdXN0b2RpYWxNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGF0b206IHtcbiAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHtcbiAgICAgICAgICAgICAgbXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgICAgY29sZE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGN1c3RvZGlhbE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdGlhOiB7XG4gICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGNvbGRNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjdXN0b2RpYWxNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJlcmE6IHtcbiAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHtcbiAgICAgICAgICAgICAgbXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgICAgY29sZE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGN1c3RvZGlhbE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYXJiZXRoOiB7XG4gICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGNvbGRNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjdXN0b2RpYWxNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG9wZXRoOiB7XG4gICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGNvbGRNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjdXN0b2RpYWxNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLmdldChgL2FwaS92Mi90c3Mvc2V0dGluZ3NgKS50aW1lcygyKS5yZXBseSgyMDAsIHRzc1NldHRpbmdzKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgICBzYW5kYm94LnZlcmlmeUFuZFJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIFsnaHRldGgnLCAndGJzYycsICd0cG9seWdvbicsICd0dGlhJywgJ3RhdG9tJywgJ3RiZXJhJywgJ3RhcmJldGgnLCAndG9wZXRoJ10uZm9yRWFjaCgoY29pbikgPT4ge1xuICAgICAgaXQoYHNob3VsZCBjcmVhdGUgYSBuZXcgJHtjb2lufSBUU1MgTVBDdjIgaG90IHdhbGxldGAsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdGVzdENvaW4gPSBiaXRnby5jb2luKGNvaW4pO1xuICAgICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgICB1c2VyS2V5Y2hhaW46IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJhY2t1cEtleWNoYWluOiB7XG4gICAgICAgICAgICBpZDogJzInLFxuICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46ICd1c2VyUHViJyxcbiAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJpdGdvS2V5Y2hhaW46IHtcbiAgICAgICAgICAgIGlkOiAnMycsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgc3R1YkNyZWF0ZUtleWNoYWlucyA9IHNhbmRib3hcbiAgICAgICAgICAuc3R1YihFQ0RTQVV0aWxzLkVjZHNhTVBDdjJVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKVxuICAgICAgICAgIC5yZXNvbHZlcyhzdHViYmVkS2V5Y2hhaW5zVHJpcGxldCk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLnBvc3QoYC9hcGkvdjIvJHtjb2lufS93YWxsZXQvYWRkYCkucmVwbHkoMjAwKTtcblxuICAgICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRlc3RDb2luKTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgbGFiZWw6ICd0c3Mgd2FsbGV0JyxcbiAgICAgICAgICBwYXNzcGhyYXNlOiAndHNzIHBhc3N3b3JkJyxcbiAgICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnIGFzIGNvbnN0LFxuICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAzLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuXG4gICAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgc3R1YkNyZWF0ZUtleWNoYWlucy5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICAgIGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogcmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSwgcGFzc3dvcmQ6IHBhcmFtcy5wYXNzY29kZUVuY3J5cHRpb25Db2RlIH0pLFxuICAgICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoYHNob3VsZCBjcmVhdGUgYSBuZXcgJHtjb2lufSBUU1MgTVBDdjIgaG90IHdhbGxldCB3aXRob3V0IHBhc3NpbmcgbXVsdGlzaWcgdHlwZWAsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdGVzdENvaW4gPSBiaXRnby5jb2luKGNvaW4pO1xuICAgICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgICB1c2VyS2V5Y2hhaW46IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJhY2t1cEtleWNoYWluOiB7XG4gICAgICAgICAgICBpZDogJzInLFxuICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46ICd1c2VyUHViJyxcbiAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJpdGdvS2V5Y2hhaW46IHtcbiAgICAgICAgICAgIGlkOiAnMycsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgc3R1YkNyZWF0ZUtleWNoYWlucyA9IHNhbmRib3hcbiAgICAgICAgICAuc3R1YihFQ0RTQVV0aWxzLkVjZHNhTVBDdjJVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKVxuICAgICAgICAgIC5yZXNvbHZlcyhzdHViYmVkS2V5Y2hhaW5zVHJpcGxldCk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvJHtjb2lufS93YWxsZXQvYWRkYCwgZnVuY3Rpb24gKGJvZHkpIHtcbiAgICAgICAgICAgIGJvZHkubXVsdGlzaWdUeXBlLnNob3VsZC5lcXVhbChtdWx0aXNpZ1R5cGVzLnRzcyk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdGVzdENvaW4pO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBsYWJlbDogJ3RzcyB3YWxsZXQnLFxuICAgICAgICAgIHBhc3NwaHJhc2U6ICd0c3MgcGFzc3dvcmQnLFxuICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAzLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuXG4gICAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgc3R1YkNyZWF0ZUtleWNoYWlucy5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICAgIGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogcmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSwgcGFzc3dvcmQ6IHBhcmFtcy5wYXNzY29kZUVuY3J5cHRpb25Db2RlIH0pLFxuICAgICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoYHNob3VsZCBjcmVhdGUgYSBuZXcgJHtjb2lufSBUU1MgTVBDdjIgY29sZCB3YWxsZXRgLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHRlc3RDb2luID0gYml0Z28uY29pbihjb2luKTtcbiAgICAgICAgY29uc3QgYml0Z29LZXlJZCA9ICdrZXkxMjMnO1xuICAgICAgICBjb25zdCBjb21tb25LZXljaGFpbiA9ICcweGFiYyc7XG5cbiAgICAgICAgY29uc3QgYml0Z29LZXlOb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyLyR7Y29pbn0va2V5LyR7Yml0Z29LZXlJZH1gKVxuICAgICAgICAgIC50aW1lcygxKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGlkOiAna2V5MTIzJyxcbiAgICAgICAgICAgIHB1YjogJ2JpdGdvUHViJyxcbiAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdXNlcktleU5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyLyR7Y29pbn0va2V5YCwge1xuICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgICBrZXlUeXBlOiAndHNzJyxcbiAgICAgICAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgICAgICAgZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZDogJzM3JyxcbiAgICAgICAgICAgIGlzTVBDdjI6IHRydWUsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAudGltZXMoMSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBpZDogJ3VzZXJLZXkxMjMnLFxuICAgICAgICAgICAgcHViOiAndXNlclB1YicsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGJhY2t1cEtleU5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyLyR7Y29pbn0va2V5YCwge1xuICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICAgIGtleVR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgICBkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkOiAnMzcnLFxuICAgICAgICAgICAgaXNNUEN2MjogdHJ1ZSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC50aW1lcygxKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGlkOiAnYmFja3VwS2V5MTIzJyxcbiAgICAgICAgICAgIHB1YjogJ2JhY2t1cFB1YicsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvJHtjb2lufS93YWxsZXQvYWRkYCwge1xuICAgICAgICAgICAgbGFiZWw6ICd0c3Mgd2FsbGV0JyxcbiAgICAgICAgICAgIG06IDIsXG4gICAgICAgICAgICBuOiAzLFxuICAgICAgICAgICAga2V5czogWyd1c2VyS2V5MTIzJywgJ2JhY2t1cEtleTEyMycsICdrZXkxMjMnXSxcbiAgICAgICAgICAgIHR5cGU6ICdjb2xkJyxcbiAgICAgICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA1LFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0cyA9IG5ldyBXYWxsZXRzKGJpdGdvLCB0ZXN0Q29pbik7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zOiBHZW5lcmF0ZVdhbGxldE9wdGlvbnMgPSB7XG4gICAgICAgICAgbGFiZWw6ICd0c3Mgd2FsbGV0JyxcbiAgICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnIGFzIGNvbnN0LFxuICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA1LFxuICAgICAgICAgIHR5cGU6ICdjb2xkJyxcbiAgICAgICAgICBiaXRnb0tleUlkOiAna2V5MTIzJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJzB4YWJjJyxcbiAgICAgICAgICBjb2xkRGVyaXZhdGlvblNlZWQ6ICczNycsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSAoYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpKSBhcyBXYWxsZXRXaXRoS2V5Y2hhaW5zO1xuXG4gICAgICAgIGJpdGdvS2V5Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICB1c2VyS2V5Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICBiYWNrdXBLZXlOb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgICBzaG91bGQuZXhpc3QocmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KHJlc3BvbnNlLnVzZXJLZXljaGFpbik7XG4gICAgICAgIHNob3VsZC5leGlzdChyZXNwb25zZS5iYWNrdXBLZXljaGFpbik7XG4gICAgICAgIHNob3VsZC5leGlzdChyZXNwb25zZS5iaXRnb0tleWNoYWluKTtcbiAgICAgICAgcmVzcG9uc2UucmVzcG9uc2VUeXBlLnNob3VsZC5lcXVhbCgnV2FsbGV0V2l0aEtleWNoYWlucycpO1xuICAgICAgICByZXNwb25zZS51c2VyS2V5Y2hhaW4uaWQuc2hvdWxkLmVxdWFsKCd1c2VyS2V5MTIzJyk7XG4gICAgICAgIHJlc3BvbnNlLmJhY2t1cEtleWNoYWluLmlkLnNob3VsZC5lcXVhbCgnYmFja3VwS2V5MTIzJyk7XG4gICAgICAgIHJlc3BvbnNlLmJpdGdvS2V5Y2hhaW4uaWQuc2hvdWxkLmVxdWFsKCdrZXkxMjMnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdChgc2hvdWxkIGNyZWF0ZSBhIG5ldyAke2NvaW59IFRTUyBNUEN2MiBjdXN0b2R5IHdhbGxldGAsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdGVzdENvaW4gPSBiaXRnby5jb2luKGNvaW4pO1xuICAgICAgICBjb25zdCBrZXlzID0gWyd1c2VyS2V5JywgJ2JhY2t1cEtleScsICdiaXRnb0tleSddO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtczogR2VuZXJhdGVXYWxsZXRPcHRpb25zID0ge1xuICAgICAgICAgIGxhYmVsOiAndHNzIHdhbGxldCcsXG4gICAgICAgICAgcGFzc3BocmFzZTogJ3RzcyBwYXNzd29yZCcsXG4gICAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyBhcyBjb25zdCxcbiAgICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJ29yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZScsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogNSxcbiAgICAgICAgICB0eXBlOiAnY3VzdG9kaWFsJyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgICAucG9zdChgL2FwaS92Mi8ke2NvaW59L3dhbGxldC9hZGRgKVxuICAgICAgICAgIC50aW1lcygxKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHsgLi4ucGFyYW1zLCBrZXlzIH0pO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdGVzdENvaW4pO1xuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gKGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKSkgYXMgV2FsbGV0V2l0aEtleWNoYWlucztcblxuICAgICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIHNob3VsZC5leGlzdChyZXNwb25zZS53YWxsZXQpO1xuICAgICAgICBzaG91bGQuZXhpc3QocmVzcG9uc2UudXNlcktleWNoYWluKTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KHJlc3BvbnNlLmJhY2t1cEtleWNoYWluKTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KHJlc3BvbnNlLmJpdGdvS2V5Y2hhaW4pO1xuICAgICAgICByZXNwb25zZS5yZXNwb25zZVR5cGUuc2hvdWxkLmVxdWFsKCdXYWxsZXRXaXRoS2V5Y2hhaW5zJyk7XG4gICAgICAgIHJlc3BvbnNlLnVzZXJLZXljaGFpbi5pZC5zaG91bGQuZXF1YWwoa2V5c1swXSk7XG4gICAgICAgIHJlc3BvbnNlLmJhY2t1cEtleWNoYWluLmlkLnNob3VsZC5lcXVhbChrZXlzWzFdKTtcbiAgICAgICAgcmVzcG9uc2UuYml0Z29LZXljaGFpbi5pZC5zaG91bGQuZXF1YWwoa2V5c1syXSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KGBzaG91bGQgY3JlYXRlIGEgbmV3IGh0ZXRoIFRTUyBNUEN2MiB3YWxsZXQgd2l0aCB3YWxsZXRWZXJzaW9uIDZgLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0ZXN0Q29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJyk7XG4gICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgdXNlcktleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB9LFxuICAgICAgICBiYWNrdXBLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW46ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0tleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCBzdHViQ3JlYXRlS2V5Y2hhaW5zID0gc2FuZGJveFxuICAgICAgICAuc3R1YihFQ0RTQVV0aWxzLkVjZHNhTVBDdjJVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKVxuICAgICAgICAucmVzb2x2ZXMoc3R1YmJlZEtleWNoYWluc1RyaXBsZXQpO1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvaHRldGgvd2FsbGV0L2FkZGAsIChib2R5KSA9PiB7XG4gICAgICAgICAgYm9keS53YWxsZXRWZXJzaW9uLnNob3VsZC5lcXVhbCg2KTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdGVzdENvaW4pO1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAndHNzIHdhbGxldCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICd0c3MgcGFzc3dvcmQnLFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnIGFzIGNvbnN0LFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgICB3YWxsZXRWZXJzaW9uOiA2LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG5cbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIHN0dWJDcmVhdGVLZXljaGFpbnMuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuXG4gICAgICBhc3NlcnQub2socmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiByZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlLCBwYXNzd29yZDogcGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUgfSksXG4gICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoYHNob3VsZCBjcmVhdGUgYSBuZXcgTVBDdjIgd2FsbGV0IHdpdGggdmVyc2lvbiA1IGlmIHdhbGxldFZlcnNpb24gcGFzc2VkIGlzIG5vdCA1IG9yIDZgLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0ZXN0Q29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJyk7XG4gICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgdXNlcktleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB9LFxuICAgICAgICBiYWNrdXBLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW46ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0tleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCBzdHViQ3JlYXRlS2V5Y2hhaW5zID0gc2FuZGJveFxuICAgICAgICAuc3R1YihFQ0RTQVV0aWxzLkVjZHNhTVBDdjJVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKVxuICAgICAgICAucmVzb2x2ZXMoc3R1YmJlZEtleWNoYWluc1RyaXBsZXQpO1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvaHRldGgvd2FsbGV0L2FkZGAsIChib2R5KSA9PiB7XG4gICAgICAgICAgYm9keS53YWxsZXRWZXJzaW9uLnNob3VsZC5lcXVhbCg1KTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdGVzdENvaW4pO1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAndHNzIHdhbGxldCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICd0c3MgcGFzc3dvcmQnLFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnIGFzIGNvbnN0LFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgICB3YWxsZXRWZXJzaW9uOiAzLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG5cbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIHN0dWJDcmVhdGVLZXljaGFpbnMuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuXG4gICAgICBhc3NlcnQub2socmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiByZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlLCBwYXNzd29yZDogcGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUgfSksXG4gICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnR2VuZXJhdGUgVFNTIEVkRFNBIE1QQ3YyIHdhbGxldDonLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHNzU2V0dGluZ3M6IFRzc1NldHRpbmdzID0ge1xuICAgICAgICBjb2luU2V0dGluZ3M6IHtcbiAgICAgICAgICBzb2w6IHtcbiAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHtcbiAgICAgICAgICAgICAgbXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKS5nZXQoYC9hcGkvdjIvdHNzL3NldHRpbmdzYCkudGltZXMoMikucmVwbHkoMjAwLCB0c3NTZXR0aW5ncyk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgICAgc2FuZGJveC52ZXJpZnlBbmRSZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIG5ldyB0c29sIFRTUyBFZERTQSBNUEN2MiBob3Qgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdGVzdENvaW4gPSBiaXRnby5jb2luKCd0c29sJyk7XG4gICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgdXNlcktleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB9LFxuICAgICAgICBiYWNrdXBLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW46ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0tleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCBzdHViQ3JlYXRlS2V5Y2hhaW5zID0gc2FuZGJveFxuICAgICAgICAuc3R1YihFRERTQVV0aWxzLkVkZHNhTVBDdjJVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKVxuICAgICAgICAucmVzb2x2ZXMoc3R1YmJlZEtleWNoYWluc1RyaXBsZXQpO1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJykucG9zdCgnL2FwaS92Mi90c29sL3dhbGxldC9hZGQnKS5yZXBseSgyMDApO1xuXG4gICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRlc3RDb2luKTtcblxuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICBsYWJlbDogJ3RzcyBlZGRzYSBtcGN2MiB3YWxsZXQnLFxuICAgICAgICBwYXNzcGhyYXNlOiAndHNzIHBhc3N3b3JkJyxcbiAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyBhcyBjb25zdCxcbiAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuXG4gICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBzdHViQ3JlYXRlS2V5Y2hhaW5zLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLndhbGxldCk7XG4gICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgIGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogcmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSwgcGFzc3dvcmQ6IHBhcmFtcy5wYXNzY29kZUVuY3J5cHRpb25Db2RlIH0pLFxuICAgICAgICBwYXJhbXMucGFzc3BocmFzZVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFsbCBiYWNrIHRvIEVkZHNhVXRpbHMgd2hlbiB0c3Mvc2V0dGluZ3MgZG9lcyBub3QgcmV0dXJuIE1QQ3YyIGZvciB0c29sJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgICAgbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgLmdldCgnL2FwaS92Mi90c3Mvc2V0dGluZ3MnKVxuICAgICAgICAucmVwbHkoMjAwLCB7IGNvaW5TZXR0aW5nczogeyBzb2w6IHsgd2FsbGV0Q3JlYXRpb25TZXR0aW5nczoge30gfSB9IH0pO1xuXG4gICAgICBjb25zdCB0ZXN0Q29pbiA9IGJpdGdvLmNvaW4oJ3Rzb2wnKTtcbiAgICAgIGNvbnN0IHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0OiBLZXljaGFpbnNUcmlwbGV0ID0ge1xuICAgICAgICB1c2VyS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIH0sXG4gICAgICAgIGJhY2t1cEtleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcyJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgIH0sXG4gICAgICAgIGJpdGdvS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzMnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHN0dWJFZGRzYVV0aWxzID0gc2FuZGJveFxuICAgICAgICAuc3R1YihFRERTQVV0aWxzLmRlZmF1bHQucHJvdG90eXBlLCAnY3JlYXRlS2V5Y2hhaW5zJylcbiAgICAgICAgLnJlc29sdmVzKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcblxuICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLnBvc3QoJy9hcGkvdjIvdHNvbC93YWxsZXQvYWRkJykucmVwbHkoMjAwKTtcblxuICAgICAgY29uc3Qgd2FsbGV0cyA9IG5ldyBXYWxsZXRzKGJpdGdvLCB0ZXN0Q29pbik7XG5cbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICd0c3MgZWRkc2Egd2FsbGV0JyxcbiAgICAgICAgcGFzc3BocmFzZTogJ3RzcyBwYXNzd29yZCcsXG4gICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycgYXMgY29uc3QsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJ29yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKTtcblxuICAgICAgd2FsbGV0Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgc3R1YkVkZHNhVXRpbHMuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuXG4gICAgICBhc3NlcnQub2socmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1NoYXJpbmcnLCAoKSA9PiB7XG4gICAgZGVzY3JpYmUoJ1dhbGxldCBzaGFyZSB3aGVyZSBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQgaXMgc2V0IHRydWUnLCAoKSA9PiB7XG4gICAgICBjb25zdCBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuXG4gICAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICBzYW5kYm94LnZlcmlmeUFuZFJlc3RvcmUoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnd2hlbiBwYXNzd29yZCBub3QgcHJvdml2ZWQgd2Ugc2hvdWxkIHJlY2VpdmUgdmFsaWRhdGlvbiBlcnJvcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X2Nhc2VfMSc7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0U2hhcmVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVmFsaWRhdGUgYWNjZXB0IHNoYXJlIGNhc2VcbiAgICAgICAgYXdhaXQgb2ZjV2FsbGV0c1xuICAgICAgICAgIC5hY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgndXNlclBhc3N3b3JkIHBhcmFtIG11c3QgYmUgcHJvdmlkZWQgdG8gZGVjcnlwdCBzaGFyZWQga2V5Jyk7XG4gICAgICAgIHdhbGxldFNoYXJlTm9jay5kb25lKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3doZW4gd2UgYWNjZXB0IHNoYXJlIGFuZCBmYWlsZWQgdG8gbWFrZSBjaGFuZ2VzLCByZXNoYXJlIHNob3VsZCBub3QgYmUgY2FsbGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJ3Rlc3RfY2FzZV8yJztcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5JZCA9ICd0ZXN0X2Nhc2VfMic7XG4gICAgICAgIGNvbnN0IHVzZXJQYXNzd29yZCA9ICd0ZXN0X2Nhc2VfMic7XG4gICAgICAgIC8vIGNyZWF0ZSBhIHVzZXIga2V5XG4gICAgICAgIGNvbnN0IGtleUNoYWluTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoJy9hcGkvdjIvb2ZjL2tleScsIF8uY29uZm9ybXMoeyBwdWI6IChwKSA9PiBwLnN0YXJ0c1dpdGgoJ3hwdWInKSB9KSlcbiAgICAgICAgICAucmVwbHkoMjAwLCAodXJpLCByZXF1ZXN0Qm9keSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHsgaWQ6IGtleWNoYWluSWQsIGVuY3J5cHRlZFBydjogcmVxdWVzdEJvZHlbJ2VuY3J5cHRlZFBydiddLCBwdWI6IHJlcXVlc3RCb2R5WydwdWInXSB9O1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlSW5mb05vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBhY2NlcHRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YCwgKGJvZHk6IGFueSkgPT4ge1xuICAgICAgICAgICAgLy8gQ2hlY2sgcmVxdWlyZWQgZmllbGRzIGFyZSBwcmVzZW50IChzaWduYXR1cmUgYW5kIHBheWxvYWQgYXJlIGR5bmFtaWMpXG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICBib2R5LndhbGxldFNoYXJlSWQgPT09IHNoYXJlSWQgJiZcbiAgICAgICAgICAgICAgYm9keS5zdGF0ZSA9PT0gJ2FjY2VwdGVkJyAmJlxuICAgICAgICAgICAgICBib2R5LmtleUlkID09PSBrZXljaGFpbklkICYmXG4gICAgICAgICAgICAgIHR5cGVvZiBib2R5LnNpZ25hdHVyZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICAgICAgdHlwZW9mIGJvZHkucGF5bG9hZCA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGNoYW5nZWQ6IGZhbHNlIH0pO1xuXG4gICAgICAgIC8vIFN0dWIgd2FsbGV0IHNoYXJlIHdhbGxldCBtZXRob2RcbiAgICAgICAgY29uc3Qgd2FsbGV0U2hhcmVTdHViID0gc2FuZGJveC5zdHViKFdhbGxldC5wcm90b3R5cGUsICdzaGFyZVdhbGxldCcpLm9uQ2FsbCgwKS5yZXNvbHZlcygnc3VjY2VzcycpO1xuXG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IG9mY1dhbGxldHMuYWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkLCB1c2VyUGFzc3dvcmQgfSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuY2hhbmdlZCwgZmFsc2UpO1xuICAgICAgICBrZXlDaGFpbk5vY2suZG9uZSgpO1xuICAgICAgICB3YWxsZXRTaGFyZUluZm9Ob2NrLmRvbmUoKTtcbiAgICAgICAgYWNjZXB0U2hhcmVOb2NrLmRvbmUoKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHdhbGxldFNoYXJlU3R1Yi5jYWxsZWQsIGZhbHNlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnd2hlbiB3ZSBhY2NlcHQgc2hhcmUgYnV0IHN0YXRlIGlzIG5vdCB2YWxpZCwgcmVzaGFyZSBzaG91bGQgbm90IGJlIGNhbGxlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X2Nhc2VfMyc7XG4gICAgICAgIGNvbnN0IGtleWNoYWluSWQgPSAndGVzdF9jYXNlXzMnO1xuICAgICAgICBjb25zdCB1c2VyUGFzc3dvcmQgPSAndGVzdF9jYXNlXzMnO1xuXG4gICAgICAgIC8vIGNyZWF0ZSBhIHVzZXIga2V5XG4gICAgICAgIGNvbnN0IGtleUNoYWluTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoJy9hcGkvdjIvb2ZjL2tleScsIF8uY29uZm9ybXMoeyBwdWI6IChwKSA9PiBwLnN0YXJ0c1dpdGgoJ3hwdWInKSB9KSlcbiAgICAgICAgICAucmVwbHkoMjAwLCAodXJpLCByZXF1ZXN0Qm9keSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHsgaWQ6IGtleWNoYWluSWQsIGVuY3J5cHRlZFBydjogcmVxdWVzdEJvZHlbJ2VuY3J5cHRlZFBydiddLCBwdWI6IHJlcXVlc3RCb2R5WydwdWInXSB9O1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlSW5mb05vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBhY2NlcHRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YCwgKGJvZHk6IGFueSkgPT4ge1xuICAgICAgICAgICAgLy8gQ2hlY2sgcmVxdWlyZWQgZmllbGRzIGFyZSBwcmVzZW50IChzaWduYXR1cmUgYW5kIHBheWxvYWQgYXJlIGR5bmFtaWMpXG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICBib2R5LndhbGxldFNoYXJlSWQgPT09IHNoYXJlSWQgJiZcbiAgICAgICAgICAgICAgYm9keS5zdGF0ZSA9PT0gJ2FjY2VwdGVkJyAmJlxuICAgICAgICAgICAgICBib2R5LmtleUlkID09PSBrZXljaGFpbklkICYmXG4gICAgICAgICAgICAgIHR5cGVvZiBib2R5LnNpZ25hdHVyZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICAgICAgdHlwZW9mIGJvZHkucGF5bG9hZCA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGNoYW5nZWQ6IHRydWUsIHN0YXRlOiAnbm90X2FjY2VwdGVkJyB9KTtcblxuICAgICAgICAvLyBTdHViIHdhbGxldCBzaGFyZSB3YWxsZXQgbWV0aG9kXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlU3R1YiA9IHNhbmRib3guc3R1YihXYWxsZXQucHJvdG90eXBlLCAnc2hhcmVXYWxsZXQnKS5vbkNhbGwoMCkucmVzb2x2ZXMoJ3N1Y2Nlc3MnKTtcblxuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBvZmNXYWxsZXRzLmFjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgdXNlclBhc3N3b3JkIH0pO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzLmNoYW5nZWQsIHRydWUpO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzLnN0YXRlLCAnbm90X2FjY2VwdGVkJyk7XG4gICAgICAgIGtleUNoYWluTm9jay5kb25lKCk7XG4gICAgICAgIHdhbGxldFNoYXJlSW5mb05vY2suZG9uZSgpO1xuICAgICAgICBhY2NlcHRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgICBzaG91bGQuZXF1YWwod2FsbGV0U2hhcmVTdHViLmNhbGxlZCwgZmFsc2UpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCd3aGVuIHdlIGdldCBhIGNvcnJlY3QgcmVzcG9zbmUgZnJvbSBhY2NlcHQgc2hhcmUgbWV0aG9kLCBidXQgZmFpbGVkIHRvIHJlc2hhcmUgd2FsbGV0IHdpdGggc3BlbmRlcnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndGVzdF9jYXNlXzYnO1xuICAgICAgICBjb25zdCBrZXljaGFpbklkID0gJ3Rlc3RfY2FzZV82JztcbiAgICAgICAgY29uc3Qgc3BlbmRlclVzZXJPbmUgPSB7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgdXNlcjogJ3Rlc3RfY2FzZV82JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVtYWlsOiB7IGVtYWlsOiAndGVzdF9jYXNlXzYnIH0sXG4gICAgICAgICAgaWQ6ICd0ZXN0X2Nhc2VfNicsXG4gICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHNwZW5kZXJVc2VyVHdvID0ge1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICAgIHVzZXI6ICd0ZXN0X2Nhc2VfOScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBlbWFpbDogeyBlbWFpbDogJ3Rlc3RfY2FzZV85JyB9LFxuICAgICAgICAgIGlkOiAndGVzdF9jYXNlXzknLFxuICAgICAgICAgIGNvaW46ICdvZmMnLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBhZG1pblVzZXIgPSB7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgdXNlcjogJ3Rlc3RfY2FzZV83JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVtYWlsOiB7IGVtYWlsOiAndGVzdF9jYXNlXzcnIH0sXG4gICAgICAgICAgaWQ6ICd0ZXN0X2Nhc2VfNycsXG4gICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHZpZXdlclVzZXIgPSB7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsndmlldyddLFxuICAgICAgICAgICAgdXNlcjogJ3Rlc3RfY2FzZV84JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVtYWlsOiB7IGVtYWlsOiAndGVzdF9jYXNlXzgnIH0sXG4gICAgICAgICAgaWQ6ICd0ZXN0X2Nhc2VfOCcsXG4gICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHVzZXJQYXNzd29yZCA9ICd0ZXN0X2Nhc2VfNic7XG4gICAgICAgIGNvbnN0IHdhbGxldElkID0gJ3Rlc3RfY2FzZV82JztcbiAgICAgICAgY29uc3QgZW50ZXJwcmlzZUlkID0gJ3Rlc3RfY2FzZV82JztcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICAgIHdhbGxldDogd2FsbGV0SWQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gY3JlYXRlIGEgdXNlciBrZXlcbiAgICAgICAgY29uc3Qga2V5Q2hhaW5DcmVhdGVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAucG9zdCgnL2FwaS92Mi9vZmMva2V5JywgXy5jb25mb3Jtcyh7IHB1YjogKHApID0+IHAuc3RhcnRzV2l0aCgneHB1YicpIH0pKVxuICAgICAgICAgIC5yZXBseSgyMDAsICh1cmksIHJlcXVlc3RCb2R5KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4geyBpZDoga2V5Y2hhaW5JZCwgZW5jcnlwdGVkUHJ2OiByZXF1ZXN0Qm9keVsnZW5jcnlwdGVkUHJ2J10sIHB1YjogcmVxdWVzdEJvZHlbJ3B1YiddIH07XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgYWNjZXB0U2hhcmVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAucG9zdChgL2FwaS92Mi9vZmMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWAsIChib2R5OiBhbnkpID0+IHtcbiAgICAgICAgICAgIC8vIENoZWNrIHJlcXVpcmVkIGZpZWxkcyBhcmUgcHJlc2VudCAoc2lnbmF0dXJlIGFuZCBwYXlsb2FkIGFyZSBkeW5hbWljKVxuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgYm9keS53YWxsZXRTaGFyZUlkID09PSBzaGFyZUlkICYmXG4gICAgICAgICAgICAgIGJvZHkuc3RhdGUgPT09ICdhY2NlcHRlZCcgJiZcbiAgICAgICAgICAgICAgYm9keS5rZXlJZCA9PT0ga2V5Y2hhaW5JZCAmJlxuICAgICAgICAgICAgICB0eXBlb2YgYm9keS5zaWduYXR1cmUgPT09ICdzdHJpbmcnICYmXG4gICAgICAgICAgICAgIHR5cGVvZiBib2R5LnBheWxvYWQgPT09ICdzdHJpbmcnXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwgeyBjaGFuZ2VkOiB0cnVlLCBzdGF0ZTogJ2FjY2VwdGVkJyB9KTtcblxuICAgICAgICBjb25zdCB3YWxsZXRJbmZvTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92Mi9vZmMvd2FsbGV0LyR7d2FsbGV0SWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICB1c2VyczogW3NwZW5kZXJVc2VyT25lLnBheWxvYWQsIHNwZW5kZXJVc2VyVHdvLnBheWxvYWQsIGFkbWluVXNlci5wYXlsb2FkLCB2aWV3ZXJVc2VyLnBheWxvYWRdLFxuICAgICAgICAgICAgZW50ZXJwcmlzZTogZW50ZXJwcmlzZUlkLFxuICAgICAgICAgICAgY29pbjogc3BlbmRlclVzZXJPbmUuY29pbixcbiAgICAgICAgICAgIGlkOiB3YWxsZXRJZCxcbiAgICAgICAgICAgIGtleXM6IFt7fV0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgZW50ZXJwcmlzZVVzZXJOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL2VudGVycHJpc2UvJHtlbnRlcnByaXNlSWR9L3VzZXJgKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGFkbWluVXNlcnM6IFtcbiAgICAgICAgICAgICAgeyBpZDogc3BlbmRlclVzZXJPbmUuaWQsIGVtYWlsOiBzcGVuZGVyVXNlck9uZS5lbWFpbCB9LFxuICAgICAgICAgICAgICB7IGlkOiBzcGVuZGVyVXNlclR3by5pZCwgZW1haWw6IHNwZW5kZXJVc2VyVHdvLmVtYWlsIH0sXG4gICAgICAgICAgICAgIHsgaWQ6IGFkbWluVXNlci5pZCwgZW1haWw6IGFkbWluVXNlci5lbWFpbCB9LFxuICAgICAgICAgICAgICB7IGlkOiB2aWV3ZXJVc2VyLmlkLCBlbWFpbDogdmlld2VyVXNlci5lbWFpbCB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIG5vbkFkbWluVXNlcnM6IFtdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlU3R1YiA9IHNhbmRib3hcbiAgICAgICAgICAuc3R1YihXYWxsZXQucHJvdG90eXBlLCAnc2hhcmVXYWxsZXQnKVxuICAgICAgICAgIC5yZXR1cm5zKG5ldyBQcm9taXNlKChfcmVzb2x2ZSwgcmVqZWN0KSA9PiByZWplY3QobmV3IEVycm9yKCdGYWlsZWQgdG8gcmVzaGFyZSB3YWxsZXQnKSkpKTtcblxuICAgICAgICBjb25zdCBzaGFyZVBhcmFtc09uZSA9IHtcbiAgICAgICAgICB3YWxsZXRJZDogd2FsbGV0SWQsXG4gICAgICAgICAgdXNlcjogc3BlbmRlclVzZXJPbmUuaWQsXG4gICAgICAgICAgcGVybWlzc2lvbnM6IHNwZW5kZXJVc2VyT25lLnBheWxvYWQucGVybWlzc2lvbnMuam9pbignLCcpLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHVzZXJQYXNzd29yZCxcbiAgICAgICAgICBlbWFpbDogc3BlbmRlclVzZXJPbmUuZW1haWwuZW1haWwsXG4gICAgICAgICAgcmVzaGFyZTogdHJ1ZSxcbiAgICAgICAgICBza2lwS2V5Y2hhaW46IGZhbHNlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHNoYXJlUGFyYW1zVHdvID0ge1xuICAgICAgICAgIHdhbGxldElkOiB3YWxsZXRJZCxcbiAgICAgICAgICB1c2VyOiBzcGVuZGVyVXNlclR3by5pZCxcbiAgICAgICAgICBwZXJtaXNzaW9uczogc3BlbmRlclVzZXJUd28ucGF5bG9hZC5wZXJtaXNzaW9ucy5qb2luKCcsJyksXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdXNlclBhc3N3b3JkLFxuICAgICAgICAgIGVtYWlsOiBzcGVuZGVyVXNlclR3by5lbWFpbC5lbWFpbCxcbiAgICAgICAgICByZXNoYXJlOiB0cnVlLFxuICAgICAgICAgIHNraXBLZXljaGFpbjogZmFsc2UsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgb2ZjV2FsbGV0cy5hY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQsIHVzZXJQYXNzd29yZCB9KTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5jaGFuZ2VkLCB0cnVlKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5zdGF0ZSwgJ2FjY2VwdGVkJyk7XG4gICAgICAgIGtleUNoYWluQ3JlYXRlTm9jay5kb25lKCk7XG4gICAgICAgIHdhbGxldFNoYXJlTm9jay5kb25lKCk7XG4gICAgICAgIHdhbGxldEluZm9Ob2NrLmRvbmUoKTtcbiAgICAgICAgYWNjZXB0U2hhcmVOb2NrLmRvbmUoKTtcbiAgICAgICAgZW50ZXJwcmlzZVVzZXJOb2NrLmRvbmUoKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHdhbGxldFNoYXJlU3R1Yi5jYWxsZWRPbmNlLCB0cnVlKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHdhbGxldFNoYXJlU3R1Yi5jYWxsZWRXaXRoKHNoYXJlUGFyYW1zT25lKSwgdHJ1ZSk7XG4gICAgICAgIHNob3VsZC5lcXVhbCh3YWxsZXRTaGFyZVN0dWIuY2FsbGVkV2l0aChzaGFyZVBhcmFtc1R3byksIGZhbHNlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnd2hlbiB3ZSBnZXQgYSBjb3JyZWN0IHJlc3Bvc25lIGZyb20gYWNjZXB0IHNoYXJlIG1ldGhvZCBhbmQgcmVzaGFyZSB3YWxsZXQgd2l0aCBzcGVuZGVycycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X2Nhc2VfNic7XG4gICAgICAgIGNvbnN0IGtleWNoYWluSWQgPSAndGVzdF9jYXNlXzYnO1xuICAgICAgICBjb25zdCBzcGVuZGVyVXNlck9uZSA9IHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgICB1c2VyOiAndGVzdF9jYXNlXzYnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZW1haWw6IHsgZW1haWw6ICd0ZXN0X2Nhc2VfNicgfSxcbiAgICAgICAgICBpZDogJ3Rlc3RfY2FzZV82JyxcbiAgICAgICAgICBjb2luOiAnb2ZjJyxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgc3BlbmRlclVzZXJUd28gPSB7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgdXNlcjogJ3Rlc3RfY2FzZV85JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVtYWlsOiB7IGVtYWlsOiAndGVzdF9jYXNlXzknIH0sXG4gICAgICAgICAgaWQ6ICd0ZXN0X2Nhc2VfOScsXG4gICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGFkbWluVXNlciA9IHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgICB1c2VyOiAndGVzdF9jYXNlXzcnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZW1haWw6IHsgZW1haWw6ICd0ZXN0X2Nhc2VfNycgfSxcbiAgICAgICAgICBpZDogJ3Rlc3RfY2FzZV83JyxcbiAgICAgICAgICBjb2luOiAnb2ZjJyxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgdmlld2VyVXNlciA9IHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWyd2aWV3J10sXG4gICAgICAgICAgICB1c2VyOiAndGVzdF9jYXNlXzgnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZW1haWw6IHsgZW1haWw6ICd0ZXN0X2Nhc2VfOCcgfSxcbiAgICAgICAgICBpZDogJ3Rlc3RfY2FzZV84JyxcbiAgICAgICAgICBjb2luOiAnb2ZjJyxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgdXNlclBhc3N3b3JkID0gJ3Rlc3RfY2FzZV82JztcbiAgICAgICAgY29uc3Qgd2FsbGV0SWQgPSAndGVzdF9jYXNlXzYnO1xuICAgICAgICBjb25zdCBlbnRlcnByaXNlSWQgPSAndGVzdF9jYXNlXzYnO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92Mi90YnRjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICAgIHdhbGxldDogd2FsbGV0SWQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gY3JlYXRlIGEgdXNlciBrZXlcbiAgICAgICAgY29uc3Qga2V5Q2hhaW5DcmVhdGVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8uY29uZm9ybXMoeyBwdWI6IChwKSA9PiBwLnN0YXJ0c1dpdGgoJ3hwdWInKSB9KSlcbiAgICAgICAgICAucmVwbHkoMjAwLCAodXJpLCByZXF1ZXN0Qm9keSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHsgaWQ6IGtleWNoYWluSWQsIGVuY3J5cHRlZFBydjogcmVxdWVzdEJvZHlbJ2VuY3J5cHRlZFBydiddLCBwdWI6IHJlcXVlc3RCb2R5WydwdWInXSB9O1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGFjY2VwdFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvdGJ0Yy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YCwgKGJvZHk6IGFueSkgPT4ge1xuICAgICAgICAgICAgLy8gQ2hlY2sgcmVxdWlyZWQgZmllbGRzIGFyZSBwcmVzZW50IChzaWduYXR1cmUgYW5kIHBheWxvYWQgYXJlIGR5bmFtaWMpXG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICBib2R5LndhbGxldFNoYXJlSWQgPT09IHNoYXJlSWQgJiZcbiAgICAgICAgICAgICAgYm9keS5zdGF0ZSA9PT0gJ2FjY2VwdGVkJyAmJlxuICAgICAgICAgICAgICBib2R5LmtleUlkID09PSBrZXljaGFpbklkICYmXG4gICAgICAgICAgICAgIHR5cGVvZiBib2R5LnNpZ25hdHVyZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICAgICAgdHlwZW9mIGJvZHkucGF5bG9hZCA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGNoYW5nZWQ6IHRydWUsIHN0YXRlOiAnYWNjZXB0ZWQnIH0pO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldEluZm9Ob2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL3RidGMvd2FsbGV0LyR7d2FsbGV0SWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICB1c2VyczogW3NwZW5kZXJVc2VyT25lLnBheWxvYWQsIHNwZW5kZXJVc2VyVHdvLnBheWxvYWQsIGFkbWluVXNlci5wYXlsb2FkLCB2aWV3ZXJVc2VyLnBheWxvYWRdLFxuICAgICAgICAgICAgZW50ZXJwcmlzZTogZW50ZXJwcmlzZUlkLFxuICAgICAgICAgICAgY29pbjogc3BlbmRlclVzZXJPbmUuY29pbixcbiAgICAgICAgICAgIGlkOiB3YWxsZXRJZCxcbiAgICAgICAgICAgIGtleXM6IFt7fV0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgZW50ZXJwcmlzZVVzZXJOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL2VudGVycHJpc2UvJHtlbnRlcnByaXNlSWR9L3VzZXJgKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGFkbWluVXNlcnM6IFtcbiAgICAgICAgICAgICAgeyBpZDogc3BlbmRlclVzZXJPbmUuaWQsIGVtYWlsOiBzcGVuZGVyVXNlck9uZS5lbWFpbCB9LFxuICAgICAgICAgICAgICB7IGlkOiBzcGVuZGVyVXNlclR3by5pZCwgZW1haWw6IHNwZW5kZXJVc2VyVHdvLmVtYWlsIH0sXG4gICAgICAgICAgICAgIHsgaWQ6IGFkbWluVXNlci5pZCwgZW1haWw6IGFkbWluVXNlci5lbWFpbCB9LFxuICAgICAgICAgICAgICB7IGlkOiB2aWV3ZXJVc2VyLmlkLCBlbWFpbDogdmlld2VyVXNlci5lbWFpbCB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIG5vbkFkbWluVXNlcnM6IFtdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlU3R1YiA9IHNhbmRib3hcbiAgICAgICAgICAuc3R1YihXYWxsZXQucHJvdG90eXBlLCAnc2hhcmVXYWxsZXQnKVxuICAgICAgICAgIC5yZXR1cm5zKG5ldyBQcm9taXNlKChyZXNvbHZlLCBfcmVqZWN0KSA9PiByZXNvbHZlKCdzdWNjZXNzJykpKTtcblxuICAgICAgICBjb25zdCBzaGFyZVBhcmFtc09uZSA9IHtcbiAgICAgICAgICB3YWxsZXRJZDogd2FsbGV0SWQsXG4gICAgICAgICAgdXNlcjogc3BlbmRlclVzZXJPbmUuaWQsXG4gICAgICAgICAgcGVybWlzc2lvbnM6IHNwZW5kZXJVc2VyT25lLnBheWxvYWQucGVybWlzc2lvbnMuam9pbignLCcpLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHVzZXJQYXNzd29yZCxcbiAgICAgICAgICBlbWFpbDogc3BlbmRlclVzZXJPbmUuZW1haWwuZW1haWwsXG4gICAgICAgICAgcmVzaGFyZTogdHJ1ZSxcbiAgICAgICAgICBza2lwS2V5Y2hhaW46IGZhbHNlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHNoYXJlUGFyYW1zVHdvID0ge1xuICAgICAgICAgIHdhbGxldElkOiB3YWxsZXRJZCxcbiAgICAgICAgICB1c2VyOiBzcGVuZGVyVXNlclR3by5pZCxcbiAgICAgICAgICBwZXJtaXNzaW9uczogc3BlbmRlclVzZXJUd28ucGF5bG9hZC5wZXJtaXNzaW9ucy5qb2luKCcsJyksXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdXNlclBhc3N3b3JkLFxuICAgICAgICAgIGVtYWlsOiBzcGVuZGVyVXNlclR3by5lbWFpbC5lbWFpbCxcbiAgICAgICAgICByZXNoYXJlOiB0cnVlLFxuICAgICAgICAgIHNraXBLZXljaGFpbjogZmFsc2UsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgd2FsbGV0cy5hY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQsIHVzZXJQYXNzd29yZCB9KTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5jaGFuZ2VkLCB0cnVlKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5zdGF0ZSwgJ2FjY2VwdGVkJyk7XG4gICAgICAgIGtleUNoYWluQ3JlYXRlTm9jay5kb25lKCk7XG4gICAgICAgIHdhbGxldFNoYXJlTm9jay5kb25lKCk7XG4gICAgICAgIHdhbGxldEluZm9Ob2NrLmRvbmUoKTtcbiAgICAgICAgYWNjZXB0U2hhcmVOb2NrLmRvbmUoKTtcbiAgICAgICAgZW50ZXJwcmlzZVVzZXJOb2NrLmRvbmUoKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHdhbGxldFNoYXJlU3R1Yi5jYWxsZWRUd2ljZSwgdHJ1ZSk7XG4gICAgICAgIHNob3VsZC5lcXVhbCh3YWxsZXRTaGFyZVN0dWIuY2FsbGVkV2l0aChzaGFyZVBhcmFtc09uZSksIHRydWUpO1xuICAgICAgICBzaG91bGQuZXF1YWwod2FsbGV0U2hhcmVTdHViLmNhbGxlZFdpdGgoc2hhcmVQYXJhbXNUd28pLCB0cnVlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ1dhbGxldCBzaGFyZSB3aGVyZSB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkIGlzIHNldCB0cnVlJywgKCkgPT4ge1xuICAgICAgY29uc3Qgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcblxuICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2FuZGJveC52ZXJpZnlBbmRSZXN0b3JlKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aGVuIHBhc3N3b3JkIG5vdCBwcm92aWRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X211bHRpX2tleV8xJztcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgYXdhaXQgb2ZjV2FsbGV0c1xuICAgICAgICAgIC5hY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgndXNlclBhc3N3b3JkIHBhcmFtIG11c3QgYmUgcHJvdmlkZWQgdG8gZ2VuZXJhdGUgdXNlciBrZXljaGFpbicpO1xuICAgICAgICB3YWxsZXRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgc3VjY2Vzc2Z1bGx5IGFjY2VwdCBzaGFyZSB3aXRoIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWQgYW5kIHNlbmQgcHViIGFuZCBlbmNyeXB0ZWRQcnYnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndGVzdF9tdWx0aV9rZXlfMic7XG4gICAgICAgIGNvbnN0IHVzZXJQYXNzd29yZCA9ICd0ZXN0X3Bhc3N3b3JkXzEyMyc7XG4gICAgICAgIGNvbnN0IHdhbGxldElkID0gJ3Rlc3Rfd2FsbGV0XzEyMyc7XG5cbiAgICAgICAgLy8gTW9jayB3YWxsZXQgc2hhcmUgcmVzcG9uc2VcbiAgICAgICAgY29uc3Qgd2FsbGV0U2hhcmVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgd2FsbGV0OiB3YWxsZXRJZCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAvLyBNb2NrIGtleWNoYWluIGNyZWF0aW9uIC0gYmFzZUNvaW4ua2V5Y2hhaW5zKCkuY3JlYXRlKCkgcmV0dXJucyB7IHBydiwgcHViIH1cbiAgICAgICAgLy8gV2UgbmVlZCB0byBjcmVhdGUgYSBwcm9wZXIga2V5Y2hhaW4gb2JqZWN0IHdpdGggcHJ2IHByb3BlcnR5XG4gICAgICAgIGNvbnN0IHRlc3RLZXljaGFpbiA9IGJpdGdvLmNvaW4oJ29mYycpLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICBjb25zdCBrZXljaGFpbiA9IHtcbiAgICAgICAgICBwcnY6IHRlc3RLZXljaGFpbi5wcnYsIC8vIE9GQyB1c2VzIHNlY3AyNTZrMSBrZXlzLCBzbyBwcnYgZm9ybWF0XG4gICAgICAgICAgcHViOiB0ZXN0S2V5Y2hhaW4ucHViLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFN0dWIga2V5Y2hhaW5zKCkuY3JlYXRlKCkgYW5kIGVuY3J5cHQoKSBCRUZPUkUgY2FsY3VsYXRpbmcgZW5jcnlwdGVkUHJ2XG4gICAgICAgIGNvbnN0IGtleWNoYWluc0luc3RhbmNlID0gb2ZjV2FsbGV0cy5iYXNlQ29pbi5rZXljaGFpbnMoKTtcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zU3R1YiA9IHNhbmRib3guc3R1YihrZXljaGFpbnNJbnN0YW5jZSwgJ2NyZWF0ZScpLnJldHVybnMoa2V5Y2hhaW4pO1xuXG4gICAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDoga2V5Y2hhaW4ucHJ2LCBwYXNzd29yZDogdXNlclBhc3N3b3JkIH0pO1xuICAgICAgICBjb25zdCBlbmNyeXB0U3R1YiA9IHNhbmRib3guc3R1YihiaXRnbywgJ2VuY3J5cHQnKS5yZXNvbHZlcyhlbmNyeXB0ZWRQcnYpO1xuXG4gICAgICAgIC8vIE1vY2sgdGhlIHVwZGF0ZVNoYXJlIEFQSSBjYWxsXG4gICAgICAgIGNvbnN0IGFjY2VwdFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gLCAoYm9keTogYW55KSA9PiB7XG4gICAgICAgICAgICAvLyBWZXJpZnkgdGhhdCBwdWIgYW5kIGVuY3J5cHRlZFBydiBhcmUgaW5jbHVkZWRcbiAgICAgICAgICAgIGlmIChib2R5LndhbGxldFNoYXJlSWQgIT09IHNoYXJlSWQgfHwgYm9keS5zdGF0ZSAhPT0gJ2FjY2VwdGVkJyB8fCAhYm9keS5wdWIgfHwgIWJvZHkuZW5jcnlwdGVkUHJ2KSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFZlcmlmeSBwdWIgaXMgYSB2YWxpZCBmb3JtYXQgKHNlY3AyNTZrMSBwdWJsaWMga2V5IGZvciBPRkMpXG4gICAgICAgICAgICBpZiAoIW9mY1dhbGxldHMuYmFzZUNvaW4uaXNWYWxpZFB1Yihib2R5LnB1YikpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGNoYW5nZWQ6IHRydWUsIHN0YXRlOiAnYWNjZXB0ZWQnIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IG9mY1dhbGxldHMuYWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkLCB1c2VyUGFzc3dvcmQgfSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuY2hhbmdlZCwgdHJ1ZSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuc3RhdGUsICdhY2NlcHRlZCcpO1xuXG4gICAgICAgIC8vIFZlcmlmeSBrZXljaGFpbiBjcmVhdGlvbiB3YXMgY2FsbGVkXG4gICAgICAgIHNob3VsZC5lcXVhbChrZXljaGFpbnNTdHViLmNhbGxlZE9uY2UsIHRydWUpO1xuICAgICAgICAvLyBWZXJpZnkgZW5jcnlwdCB3YXMgY2FsbGVkIHdpdGggdGhlIGNvcnJlY3QgcGFyYW1ldGVyc1xuICAgICAgICBzaG91bGQuZXF1YWwoZW5jcnlwdFN0dWIuY2FsbGVkV2l0aCh7IGlucHV0OiBrZXljaGFpbi5wcnYsIHBhc3N3b3JkOiB1c2VyUGFzc3dvcmQgfSksIHRydWUpO1xuXG4gICAgICAgIHdhbGxldFNoYXJlTm9jay5kb25lKCk7XG4gICAgICAgIGFjY2VwdFNoYXJlTm9jay5kb25lKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBOT1QgdHJpZ2dlciByZXNoYXJlIHdoZW4gdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZCBpcyB0cnVlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJ3Rlc3RfbXVsdGlfa2V5XzMnO1xuICAgICAgICBjb25zdCB1c2VyUGFzc3dvcmQgPSAndGVzdF9wYXNzd29yZF8xMjMnO1xuICAgICAgICBjb25zdCB3YWxsZXRJZCA9ICd0ZXN0X3dhbGxldF8xMjMnO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92Mi9vZmMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICAgIHdhbGxldDogd2FsbGV0SWQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdGVzdEtleWNoYWluID0gYml0Z28uY29pbignb2ZjJykua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluID0ge1xuICAgICAgICAgIHBydjogdGVzdEtleWNoYWluLnBydixcbiAgICAgICAgICBwdWI6IHRlc3RLZXljaGFpbi5wdWIsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDoga2V5Y2hhaW4ucHJ2LCBwYXNzd29yZDogdXNlclBhc3N3b3JkIH0pO1xuXG4gICAgICAgIGNvbnN0IGFjY2VwdFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHsgY2hhbmdlZDogdHJ1ZSwgc3RhdGU6ICdhY2NlcHRlZCcgfSk7XG5cbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zSW5zdGFuY2UgPSBvZmNXYWxsZXRzLmJhc2VDb2luLmtleWNoYWlucygpO1xuICAgICAgICBzYW5kYm94LnN0dWIoa2V5Y2hhaW5zSW5zdGFuY2UsICdjcmVhdGUnKS5yZXR1cm5zKGtleWNoYWluKTtcbiAgICAgICAgc2FuZGJveC5zdHViKGJpdGdvLCAnZW5jcnlwdCcpLnJlc29sdmVzKGVuY3J5cHRlZFBydik7XG5cbiAgICAgICAgLy8gU3R1YiByZXNoYXJlV2FsbGV0V2l0aFNwZW5kZXJzIHRvIHZlcmlmeSBpdCdzIE5PVCBjYWxsZWRcbiAgICAgICAgY29uc3QgcmVzaGFyZVN0dWIgPSBzYW5kYm94LnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdyZXNoYXJlV2FsbGV0V2l0aFNwZW5kZXJzJyk7XG5cbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgb2ZjV2FsbGV0cy5hY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQsIHVzZXJQYXNzd29yZCB9KTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5jaGFuZ2VkLCB0cnVlKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5zdGF0ZSwgJ2FjY2VwdGVkJyk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IHJlc2hhcmUgd2FzIE5PVCBjYWxsZWQgKHVubGlrZSBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQgY2FzZSlcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlc2hhcmVTdHViLmNhbGxlZCwgZmFsc2UpO1xuXG4gICAgICAgIHdhbGxldFNoYXJlTm9jay5kb25lKCk7XG4gICAgICAgIGFjY2VwdFNoYXJlTm9jay5kb25lKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgYnVsayBhY2NlcHQgc2hhcmUgd2l0aCB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJ3Rlc3RfbXVsdGlfa2V5X2J1bGtfMSc7XG4gICAgICAgIGNvbnN0IHVzZXJQYXNzd29yZCA9ICd0ZXN0X3Bhc3N3b3JkXzEyMyc7XG5cbiAgICAgICAgLy8gTW9jayBsaXN0U2hhcmVzVjIgdG8gcmV0dXJuIGEgc2hhcmUgd2l0aCB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkXG4gICAgICAgIC8vIE5vdGU6IHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWQgc2hhcmVzIGRvbid0IGhhdmUgYSBrZXljaGFpbiwgc28gdGhleSB3b24ndCBiZSBmaWx0ZXJlZFxuICAgICAgICAvLyBieSB0aGUgYnVsa0FjY2VwdFNoYXJlIGZpbHRlciwgYnV0IHByb2Nlc3NBY2NlcHRTaGFyZSB3aWxsIGhhbmRsZSB0aGVtXG4gICAgICAgIHNhbmRib3guc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogc2hhcmVJZCxcbiAgICAgICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgICAgICAgIHdhbGxldExhYmVsOiAndGVzdCB3YWxsZXQnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2Zyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAndG9Vc2VyJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnd2FsbGV0MTIzJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICAgIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICAgIC8vIE5vIGtleWNoYWluIC0gdGhpcyBpcyB0aGUga2V5IGRpZmZlcmVuY2UgZm9yIG11bHRpLWtleS11c2VyLWtleSBzaGFyZXNcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHRlc3RLZXljaGFpbiA9IGJpdGdvLmNvaW4oJ29mYycpLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICBjb25zdCBrZXljaGFpbiA9IHtcbiAgICAgICAgICBwcnY6IHRlc3RLZXljaGFpbi5wcnYsXG4gICAgICAgICAgcHViOiB0ZXN0S2V5Y2hhaW4ucHViLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFNldCB1cCBzdHVicyBmaXJzdFxuICAgICAgICBjb25zdCBrZXljaGFpbnNJbnN0YW5jZSA9IG9mY1dhbGxldHMuYmFzZUNvaW4ua2V5Y2hhaW5zKCk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluc1N0dWIgPSBzYW5kYm94LnN0dWIoa2V5Y2hhaW5zSW5zdGFuY2UsICdjcmVhdGUnKS5yZXR1cm5zKGtleWNoYWluKTtcblxuICAgICAgICBjb25zdCBlbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IGtleWNoYWluLnBydiwgcGFzc3dvcmQ6IHVzZXJQYXNzd29yZCB9KTtcbiAgICAgICAgY29uc3QgZW5jcnlwdFN0dWIgPSBzYW5kYm94LnN0dWIoYml0Z28sICdlbmNyeXB0JykucmVzb2x2ZXMoZW5jcnlwdGVkUHJ2KTtcblxuICAgICAgICAvLyBNb2NrIGJ1bGsgdXBkYXRlIEFQSSAtIHRoaXMgaXMgY2FsbGVkIHZpYSBidWxrVXBkYXRlV2FsbGV0U2hhcmVcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucHV0KCcvYXBpL3YyL3dhbGxldHNoYXJlcy91cGRhdGUnLCAoYm9keTogYW55KSA9PiB7XG4gICAgICAgICAgICBpZiAoIWJvZHkuc2hhcmVzIHx8IGJvZHkuc2hhcmVzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBzaGFyZSA9IGJvZHkuc2hhcmVzWzBdO1xuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgc2hhcmUud2FsbGV0U2hhcmVJZCA9PT0gc2hhcmVJZCAmJlxuICAgICAgICAgICAgICBzaGFyZS5zdGF0dXMgPT09ICdhY2NlcHQnICYmXG4gICAgICAgICAgICAgIHNoYXJlLnB1YiA9PT0ga2V5Y2hhaW4ucHViICYmXG4gICAgICAgICAgICAgIHNoYXJlLmVuY3J5cHRlZFBydiA9PT0gZW5jcnlwdGVkUHJ2XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQgfV0sXG4gICAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gTm90ZTogYnVsa0FjY2VwdFNoYXJlIGZpbHRlcnMgZm9yIHNoYXJlcyBXSVRIIGtleWNoYWlucywgYnV0IHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWRcbiAgICAgICAgLy8gc2hhcmVzIGRvbid0IGhhdmUga2V5Y2hhaW5zLCBzbyB0aGV5IGdvIHRocm91Z2ggYSBkaWZmZXJlbnQgcGF0aFxuICAgICAgICAvLyBXZSBuZWVkIHRvIHN0dWIgdGhlIHByb2Nlc3NBY2NlcHRTaGFyZSBwYXRoIG9yIHVzZSBidWxrVXBkYXRlV2FsbGV0U2hhcmUgZGlyZWN0bHlcbiAgICAgICAgLy8gRm9yIHRoaXMgdGVzdCwgd2UnbGwgdXNlIGJ1bGtVcGRhdGVXYWxsZXRTaGFyZSB3aGljaCBjYWxscyBwcm9jZXNzQWNjZXB0U2hhcmUgaW50ZXJuYWxseVxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBvZmNXYWxsZXRzLmJ1bGtVcGRhdGVXYWxsZXRTaGFyZSh7XG4gICAgICAgICAgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkLCBzdGF0dXM6ICdhY2NlcHQnIH1dLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB1c2VyUGFzc3dvcmQsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNob3VsZC5lcXVhbChyZXN1bHQuYWNjZXB0ZWRXYWxsZXRTaGFyZXMubGVuZ3RoLCAxKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbChyZXN1bHQuYWNjZXB0ZWRXYWxsZXRTaGFyZXNbMF0sIHsgd2FsbGV0U2hhcmVJZDogJ3Rlc3RfbXVsdGlfa2V5X2J1bGtfMScgfSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChrZXljaGFpbnNTdHViLmNhbGxlZE9uY2UsIHRydWUpO1xuICAgICAgICBzaG91bGQuZXF1YWwoZW5jcnlwdFN0dWIuY2FsbGVkV2l0aCh7IGlucHV0OiBrZXljaGFpbi5wcnYsIHBhc3N3b3JkOiB1c2VyUGFzc3dvcmQgfSksIHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIGJ1bGsgYWNjZXB0IHNoYXJlIHdpdGggdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZCBhbmQgbmV3V2FsbGV0UGFzc3BocmFzZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X211bHRpX2tleV9idWxrXzInO1xuICAgICAgICBjb25zdCB1c2VyUGFzc3dvcmQgPSAndGVzdF9wYXNzd29yZF8xMjMnO1xuICAgICAgICBjb25zdCBuZXdXYWxsZXRQYXNzcGhyYXNlID0gJ25ld193YWxsZXRfcGFzc3BocmFzZV80NTYnO1xuXG4gICAgICAgIC8vIE1vY2sgbGlzdFNoYXJlc1YyIHRvIHJldHVybiBhIHNoYXJlIHdpdGggdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZFxuICAgICAgICBzYW5kYm94LnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6IHNoYXJlSWQsXG4gICAgICAgICAgICAgIGNvaW46ICdvZmMnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3Qgd2FsbGV0JyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdmcm9tVXNlcicsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ3RvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ3dhbGxldDEyMycsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgICB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgICAgICAvLyBObyBrZXljaGFpbiAtIHRoaXMgaXMgdGhlIGtleSBkaWZmZXJlbmNlIGZvciBtdWx0aS1rZXktdXNlci1rZXkgc2hhcmVzXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB0ZXN0S2V5Y2hhaW4gPSBiaXRnby5jb2luKCdvZmMnKS5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB7XG4gICAgICAgICAgcHJ2OiB0ZXN0S2V5Y2hhaW4ucHJ2LFxuICAgICAgICAgIHB1YjogdGVzdEtleWNoYWluLnB1YixcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBTZXQgdXAgc3R1YnMgZmlyc3RcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zSW5zdGFuY2UgPSBvZmNXYWxsZXRzLmJhc2VDb2luLmtleWNoYWlucygpO1xuICAgICAgICBjb25zdCBrZXljaGFpbnNTdHViID0gc2FuZGJveC5zdHViKGtleWNoYWluc0luc3RhbmNlLCAnY3JlYXRlJykucmV0dXJucyhrZXljaGFpbik7XG5cbiAgICAgICAgLy8gU2hvdWxkIGVuY3J5cHQgd2l0aCBuZXdXYWxsZXRQYXNzcGhyYXNlIGlmIHByb3ZpZGVkIChhcyBwZXIgaW1wbGVtZW50YXRpb24pXG4gICAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDoga2V5Y2hhaW4ucHJ2LCBwYXNzd29yZDogbmV3V2FsbGV0UGFzc3BocmFzZSB9KTtcbiAgICAgICAgY29uc3QgZW5jcnlwdFN0dWIgPSBzYW5kYm94LnN0dWIoYml0Z28sICdlbmNyeXB0JykucmVzb2x2ZXMoZW5jcnlwdGVkUHJ2KTtcblxuICAgICAgICAvLyBNb2NrIGJ1bGsgdXBkYXRlIEFQSSAtIHRoaXMgaXMgY2FsbGVkIHZpYSBidWxrVXBkYXRlV2FsbGV0U2hhcmVcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucHV0KCcvYXBpL3YyL3dhbGxldHNoYXJlcy91cGRhdGUnLCAoYm9keTogYW55KSA9PiB7XG4gICAgICAgICAgICBpZiAoIWJvZHkuc2hhcmVzIHx8IGJvZHkuc2hhcmVzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBzaGFyZSA9IGJvZHkuc2hhcmVzWzBdO1xuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgc2hhcmUud2FsbGV0U2hhcmVJZCA9PT0gc2hhcmVJZCAmJlxuICAgICAgICAgICAgICBzaGFyZS5zdGF0dXMgPT09ICdhY2NlcHQnICYmXG4gICAgICAgICAgICAgIHNoYXJlLnB1YiA9PT0ga2V5Y2hhaW4ucHViICYmXG4gICAgICAgICAgICAgIHNoYXJlLmVuY3J5cHRlZFBydiA9PT0gZW5jcnlwdGVkUHJ2XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQgfV0sXG4gICAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgb2ZjV2FsbGV0cy5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe1xuICAgICAgICAgIHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgc3RhdHVzOiAnYWNjZXB0JyB9XSxcbiAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogdXNlclBhc3N3b3JkLFxuICAgICAgICAgIG5ld1dhbGxldFBhc3NwaHJhc2U6IG5ld1dhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNob3VsZC5lcXVhbChyZXN1bHQuYWNjZXB0ZWRXYWxsZXRTaGFyZXMubGVuZ3RoLCAxKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbChyZXN1bHQuYWNjZXB0ZWRXYWxsZXRTaGFyZXNbMF0sIHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCB9KTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKGtleWNoYWluc1N0dWIuY2FsbGVkT25jZSwgdHJ1ZSk7XG4gICAgICAgIC8vIFZlcmlmeSBlbmNyeXB0IHdhcyBjYWxsZWQgd2l0aCBuZXdXYWxsZXRQYXNzcGhyYXNlIChub3QgdXNlclBhc3N3b3JkKVxuICAgICAgICBzaG91bGQuZXF1YWwoZW5jcnlwdFN0dWIuY2FsbGVkV2l0aCh7IGlucHV0OiBrZXljaGFpbi5wcnYsIHBhc3N3b3JkOiBuZXdXYWxsZXRQYXNzcGhyYXNlIH0pLCB0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIHdoZW4gbmVpdGhlciB1c2VyTG9naW5QYXNzd29yZCBub3IgbmV3V2FsbGV0UGFzc3BocmFzZSBwcm92aWRlZCBmb3IgYnVsayBhY2NlcHQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndGVzdF9tdWx0aV9rZXlfYnVsa18zJztcblxuICAgICAgICAvLyBNb2NrIGxpc3RTaGFyZXNWMiB0byByZXR1cm4gYSBzaGFyZSB3aXRoIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWRcbiAgICAgICAgc2FuZGJveC5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiBzaGFyZUlkLFxuICAgICAgICAgICAgICBjb2luOiAnb2ZjJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0IHdhbGxldCcsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICd0b1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICd3YWxsZXQxMjMnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgICAgdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE1vY2sgdXNlciBzZXR0aW5ncyBBUEkgY2FsbCAocmVxdWlyZWQgYnkgYnVsa1VwZGF0ZVdhbGxldFNoYXJlKVxuICAgICAgICBub2NrKGJnVXJsKS5nZXQoJy9hcGkvdjEvdXNlci9zZXR0aW5ncycpLnJlcGx5KDIwMCwge30pO1xuXG4gICAgICAgIC8vIE1vY2sgYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCAtIHdoZW4gdGhlcmUgYXJlIGVycm9ycywgaXQncyBjYWxsZWQgd2l0aCBlbXB0eSBhcnJheVxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wdXQoJy9hcGkvdjIvd2FsbGV0c2hhcmVzL3VwZGF0ZScsIChib2R5OiBhbnkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBib2R5LnNoYXJlcyAmJiBib2R5LnNoYXJlcy5sZW5ndGggPT09IDA7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gYnVsa1VwZGF0ZVdhbGxldFNoYXJlIHVzZXMgUHJvbWlzZS5hbGxTZXR0bGVkLCBzbyBlcnJvcnMgYXJlIGNhdWdodCBhbmQgcmV0dXJuZWQgaW4gd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnNcbiAgICAgICAgLy8gV2UgbmVlZCB0byBjaGVjayB0aGUgcmVzdWx0IGZvciBlcnJvcnMgaW5zdGVhZCBvZiBleHBlY3RpbmcgYSByZWplY3Rpb25cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgb2ZjV2FsbGV0cy5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe1xuICAgICAgICAgIHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgc3RhdHVzOiAnYWNjZXB0JyB9XSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IHRoYXQgdGhlIGVycm9yIHdhcyBjYXB0dXJlZCBpbiB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yc1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzdWx0LndhbGxldFNoYXJlVXBkYXRlRXJyb3JzLmxlbmd0aCwgMSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXN1bHQud2FsbGV0U2hhcmVVcGRhdGVFcnJvcnNbMF0ud2FsbGV0U2hhcmVJZCwgc2hhcmVJZCk7XG4gICAgICAgIHNob3VsZChyZXN1bHQud2FsbGV0U2hhcmVVcGRhdGVFcnJvcnNbMF0ucmVhc29uKS5jb250YWluRXFsKFxuICAgICAgICAgICd1c2VyTG9naW5QYXNzd29yZCBwYXJhbSBtdXN0IGJlIHByb3ZpZGVkIHRvIGdlbmVyYXRlIHVzZXIga2V5Y2hhaW4nXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB3b3JrIHdpdGggbmV3V2FsbGV0UGFzc3BocmFzZSBwYXJhbWV0ZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndGVzdF9tdWx0aV9rZXlfNCc7XG4gICAgICAgIGNvbnN0IHVzZXJQYXNzd29yZCA9ICd0ZXN0X3Bhc3N3b3JkXzEyMyc7XG4gICAgICAgIGNvbnN0IG5ld1dhbGxldFBhc3NwaHJhc2UgPSAnbmV3X3dhbGxldF9wYXNzcGhyYXNlXzQ1Nic7XG4gICAgICAgIGNvbnN0IHdhbGxldElkID0gJ3Rlc3Rfd2FsbGV0XzEyMyc7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0U2hhcmVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgd2FsbGV0OiB3YWxsZXRJZCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB0ZXN0S2V5Y2hhaW4gPSBiaXRnby5jb2luKCdvZmMnKS5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB7XG4gICAgICAgICAgcHJ2OiB0ZXN0S2V5Y2hhaW4ucHJ2LFxuICAgICAgICAgIHB1YjogdGVzdEtleWNoYWluLnB1YixcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBTdHViIGNyZWF0ZSgpIGFuZCBlbmNyeXB0KCkgQkVGT1JFIGNhbGN1bGF0aW5nIGVuY3J5cHRlZFBydiB0byBlbnN1cmUgY29uc2lzdGVuY3lcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zSW5zdGFuY2UgPSBvZmNXYWxsZXRzLmJhc2VDb2luLmtleWNoYWlucygpO1xuICAgICAgICBzYW5kYm94LnN0dWIoa2V5Y2hhaW5zSW5zdGFuY2UsICdjcmVhdGUnKS5yZXR1cm5zKGtleWNoYWluKTtcblxuICAgICAgICAvLyBTaG91bGQgZW5jcnlwdCB3aXRoIG5ld1dhbGxldFBhc3NwaHJhc2UgaWYgcHJvdmlkZWQgKGFzIHBlciBpbXBsZW1lbnRhdGlvbilcbiAgICAgICAgY29uc3QgZW5jcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBrZXljaGFpbi5wcnYsIHBhc3N3b3JkOiBuZXdXYWxsZXRQYXNzcGhyYXNlIH0pO1xuICAgICAgICBjb25zdCBlbmNyeXB0U3R1YiA9IHNhbmRib3guc3R1YihiaXRnbywgJ2VuY3J5cHQnKS5yZXNvbHZlcyhlbmNyeXB0ZWRQcnYpO1xuXG4gICAgICAgIGNvbnN0IGFjY2VwdFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gLCAoYm9keTogYW55KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICBib2R5LndhbGxldFNoYXJlSWQgPT09IHNoYXJlSWQgJiZcbiAgICAgICAgICAgICAgYm9keS5zdGF0ZSA9PT0gJ2FjY2VwdGVkJyAmJlxuICAgICAgICAgICAgICBib2R5LnB1YiA9PT0ga2V5Y2hhaW4ucHViICYmXG4gICAgICAgICAgICAgIGJvZHkuZW5jcnlwdGVkUHJ2ID09PSBlbmNyeXB0ZWRQcnZcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGNoYW5nZWQ6IHRydWUsIHN0YXRlOiAnYWNjZXB0ZWQnIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IG9mY1dhbGxldHMuYWNjZXB0U2hhcmUoe1xuICAgICAgICAgIHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQsXG4gICAgICAgICAgdXNlclBhc3N3b3JkLFxuICAgICAgICAgIG5ld1dhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuY2hhbmdlZCwgdHJ1ZSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuc3RhdGUsICdhY2NlcHRlZCcpO1xuICAgICAgICAvLyBWZXJpZnkgZW5jcnlwdCB3YXMgY2FsbGVkIHdpdGggbmV3V2FsbGV0UGFzc3BocmFzZVxuICAgICAgICBzaG91bGQuZXF1YWwoZW5jcnlwdFN0dWIuY2FsbGVkV2l0aCh7IGlucHV0OiBrZXljaGFpbi5wcnYsIHBhc3N3b3JkOiBuZXdXYWxsZXRQYXNzcGhyYXNlIH0pLCB0cnVlKTtcblxuICAgICAgICB3YWxsZXRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgICBhY2NlcHRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcHJpb3JpdGl6ZSB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkIG92ZXIga2V5Y2hhaW5PdmVycmlkZVJlcXVpcmVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJ3Rlc3RfbXVsdGlfa2V5XzUnO1xuICAgICAgICBjb25zdCB1c2VyUGFzc3dvcmQgPSAndGVzdF9wYXNzd29yZF8xMjMnO1xuICAgICAgICBjb25zdCB3YWxsZXRJZCA9ICd0ZXN0X3dhbGxldF8xMjMnO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92Mi9vZmMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIGtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZDogdHJ1ZSwgLy8gQm90aCBzZXQsIGJ1dCB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkIHNob3VsZCB0YWtlIHByZWNlZGVuY2VcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICAgIHdhbGxldDogd2FsbGV0SWQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdGVzdEtleWNoYWluID0gYml0Z28uY29pbignb2ZjJykua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluID0ge1xuICAgICAgICAgIHBydjogdGVzdEtleWNoYWluLnBydixcbiAgICAgICAgICBwdWI6IHRlc3RLZXljaGFpbi5wdWIsXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gU2V0IHVwIHN0dWJzIGZpcnN0XG4gICAgICAgIGNvbnN0IGtleWNoYWluc0luc3RhbmNlID0gb2ZjV2FsbGV0cy5iYXNlQ29pbi5rZXljaGFpbnMoKTtcbiAgICAgICAgc2FuZGJveC5zdHViKGtleWNoYWluc0luc3RhbmNlLCAnY3JlYXRlJykucmV0dXJucyhrZXljaGFpbik7XG5cbiAgICAgICAgY29uc3QgZW5jcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBrZXljaGFpbi5wcnYsIHBhc3N3b3JkOiB1c2VyUGFzc3dvcmQgfSk7XG4gICAgICAgIHNhbmRib3guc3R1YihiaXRnbywgJ2VuY3J5cHQnKS5yZXNvbHZlcyhlbmNyeXB0ZWRQcnYpO1xuXG4gICAgICAgIC8vIFNob3VsZCB1c2UgdGhlIG11bHRpLWtleS11c2VyLWtleSBmbG93IChubyBzaWduYXR1cmUvcGF5bG9hZC9rZXlJZClcbiAgICAgICAgY29uc3QgYWNjZXB0U2hhcmVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAucG9zdChgL2FwaS92Mi9vZmMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWAsIChib2R5OiBhbnkpID0+IHtcbiAgICAgICAgICAgIC8vIFZlcmlmeSBpdCdzIHVzaW5nIG11bHRpLWtleS11c2VyLWtleSBmbG93IChoYXMgcHViIGFuZCBlbmNyeXB0ZWRQcnYsIGJ1dCBubyBzaWduYXR1cmUvcGF5bG9hZC9rZXlJZClcbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgIGJvZHkud2FsbGV0U2hhcmVJZCA9PT0gc2hhcmVJZCAmJlxuICAgICAgICAgICAgICBib2R5LnN0YXRlID09PSAnYWNjZXB0ZWQnICYmXG4gICAgICAgICAgICAgIGJvZHkucHViID09PSBrZXljaGFpbi5wdWIgJiZcbiAgICAgICAgICAgICAgYm9keS5lbmNyeXB0ZWRQcnYgPT09IGVuY3J5cHRlZFBydiAmJlxuICAgICAgICAgICAgICAhYm9keS5zaWduYXR1cmUgJiZcbiAgICAgICAgICAgICAgIWJvZHkucGF5bG9hZCAmJlxuICAgICAgICAgICAgICAhYm9keS5rZXlJZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5yZXBseSgyMDAsIHsgY2hhbmdlZDogdHJ1ZSwgc3RhdGU6ICdhY2NlcHRlZCcgfSk7XG4gICAgICAgIGNvbnN0IHJlc2hhcmVTdHViID0gc2FuZGJveC5zdHViKFdhbGxldHMucHJvdG90eXBlLCAncmVzaGFyZVdhbGxldFdpdGhTcGVuZGVycycpO1xuXG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IG9mY1dhbGxldHMuYWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkLCB1c2VyUGFzc3dvcmQgfSk7XG5cbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5jaGFuZ2VkLCB0cnVlKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5zdGF0ZSwgJ2FjY2VwdGVkJyk7XG4gICAgICAgIC8vIFZlcmlmeSByZXNoYXJlIHdhcyBOT1QgY2FsbGVkIChtdWx0aS1rZXktdXNlci1rZXkgZmxvdylcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlc2hhcmVTdHViLmNhbGxlZCwgZmFsc2UpO1xuXG4gICAgICAgIHdhbGxldFNoYXJlTm9jay5kb25lKCk7XG4gICAgICAgIGFjY2VwdFNoYXJlTm9jay5kb25lKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUga2V5Y2hhaW4gY3JlYXRpb24gZmFpbHVyZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X211bHRpX2tleV82JztcbiAgICAgICAgY29uc3QgdXNlclBhc3N3b3JkID0gJ3Rlc3RfcGFzc3dvcmRfMTIzJztcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qga2V5Y2hhaW5FcnJvciA9IG5ldyBFcnJvcignRmFpbGVkIHRvIGNyZWF0ZSBrZXljaGFpbicpO1xuICAgICAgICBjb25zdCBrZXljaGFpbnNJbnN0YW5jZSA9IG9mY1dhbGxldHMuYmFzZUNvaW4ua2V5Y2hhaW5zKCk7XG4gICAgICAgIHNhbmRib3guc3R1YihrZXljaGFpbnNJbnN0YW5jZSwgJ2NyZWF0ZScpLnRocm93cyhrZXljaGFpbkVycm9yKTtcblxuICAgICAgICBhd2FpdCBvZmNXYWxsZXRzXG4gICAgICAgICAgLmFjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgdXNlclBhc3N3b3JkIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0ZhaWxlZCB0byBjcmVhdGUga2V5Y2hhaW4nKTtcblxuICAgICAgICB3YWxsZXRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIGVuY3J5cHRpb24gZmFpbHVyZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X211bHRpX2tleV83JztcbiAgICAgICAgY29uc3QgdXNlclBhc3N3b3JkID0gJ3Rlc3RfcGFzc3dvcmRfMTIzJztcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdGVzdEtleWNoYWluID0gYml0Z28uY29pbignb2ZjJykua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluID0ge1xuICAgICAgICAgIHBydjogdGVzdEtleWNoYWluLnBydixcbiAgICAgICAgICBwdWI6IHRlc3RLZXljaGFpbi5wdWIsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zSW5zdGFuY2UgPSBvZmNXYWxsZXRzLmJhc2VDb2luLmtleWNoYWlucygpO1xuICAgICAgICBzYW5kYm94LnN0dWIoa2V5Y2hhaW5zSW5zdGFuY2UsICdjcmVhdGUnKS5yZXR1cm5zKGtleWNoYWluKTtcbiAgICAgICAgY29uc3QgZW5jcnlwdGlvbkVycm9yID0gbmV3IEVycm9yKCdFbmNyeXB0aW9uIGZhaWxlZCcpO1xuICAgICAgICBzYW5kYm94LnN0dWIoYml0Z28sICdlbmNyeXB0JykudGhyb3dzKGVuY3J5cHRpb25FcnJvcik7XG5cbiAgICAgICAgYXdhaXQgb2ZjV2FsbGV0c1xuICAgICAgICAgIC5hY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQsIHVzZXJQYXNzd29yZCB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdFbmNyeXB0aW9uIGZhaWxlZCcpO1xuXG4gICAgICAgIHdhbGxldFNoYXJlTm9jay5kb25lKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB3b3JrIHdpdGggdmlldy1vbmx5IHBlcm1pc3Npb25zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJ3Rlc3RfbXVsdGlfa2V5XzgnO1xuICAgICAgICBjb25zdCB1c2VyUGFzc3dvcmQgPSAndGVzdF9wYXNzd29yZF8xMjMnO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92Mi9vZmMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3ZpZXcnXSwgLy8gVmlldy1vbmx5IHBlcm1pc3Npb25zXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdGVzdEtleWNoYWluID0gYml0Z28uY29pbignb2ZjJykua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluID0ge1xuICAgICAgICAgIHBydjogdGVzdEtleWNoYWluLnBydixcbiAgICAgICAgICBwdWI6IHRlc3RLZXljaGFpbi5wdWIsXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gU2V0IHVwIHN0dWJzIGZpcnN0XG4gICAgICAgIGNvbnN0IGtleWNoYWluc0luc3RhbmNlID0gb2ZjV2FsbGV0cy5iYXNlQ29pbi5rZXljaGFpbnMoKTtcbiAgICAgICAgc2FuZGJveC5zdHViKGtleWNoYWluc0luc3RhbmNlLCAnY3JlYXRlJykucmV0dXJucyhrZXljaGFpbik7XG5cbiAgICAgICAgY29uc3QgZW5jcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBrZXljaGFpbi5wcnYsIHBhc3N3b3JkOiB1c2VyUGFzc3dvcmQgfSk7XG4gICAgICAgIHNhbmRib3guc3R1YihiaXRnbywgJ2VuY3J5cHQnKS5yZXNvbHZlcyhlbmNyeXB0ZWRQcnYpO1xuXG4gICAgICAgIGNvbnN0IGFjY2VwdFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gLCAoYm9keTogYW55KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICBib2R5LndhbGxldFNoYXJlSWQgPT09IHNoYXJlSWQgJiZcbiAgICAgICAgICAgICAgYm9keS5zdGF0ZSA9PT0gJ2FjY2VwdGVkJyAmJlxuICAgICAgICAgICAgICBib2R5LnB1YiA9PT0ga2V5Y2hhaW4ucHViICYmXG4gICAgICAgICAgICAgIGJvZHkuZW5jcnlwdGVkUHJ2ID09PSBlbmNyeXB0ZWRQcnZcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGNoYW5nZWQ6IHRydWUsIHN0YXRlOiAnYWNjZXB0ZWQnIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IG9mY1dhbGxldHMuYWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkLCB1c2VyUGFzc3dvcmQgfSk7XG5cbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5jaGFuZ2VkLCB0cnVlKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5zdGF0ZSwgJ2FjY2VwdGVkJyk7XG5cbiAgICAgICAgd2FsbGV0U2hhcmVOb2NrLmRvbmUoKTtcbiAgICAgICAgYWNjZXB0U2hhcmVOb2NrLmRvbmUoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHZlcmlmeSBleGFjdCB2YWx1ZXMgc2VudCBpbiBBUEkgcmVxdWVzdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X211bHRpX2tleV85JztcbiAgICAgICAgY29uc3QgdXNlclBhc3N3b3JkID0gJ3Rlc3RfcGFzc3dvcmRfMTIzJztcbiAgICAgICAgY29uc3Qgd2FsbGV0SWQgPSAndGVzdF93YWxsZXRfMTIzJztcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgICB3YWxsZXQ6IHdhbGxldElkLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHRlc3RLZXljaGFpbiA9IGJpdGdvLmNvaW4oJ29mYycpLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICBjb25zdCBrZXljaGFpbiA9IHtcbiAgICAgICAgICBwcnY6IHRlc3RLZXljaGFpbi5wcnYsXG4gICAgICAgICAgcHViOiB0ZXN0S2V5Y2hhaW4ucHViLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFNldCB1cCBzdHVicyBmaXJzdFxuICAgICAgICBjb25zdCBrZXljaGFpbnNJbnN0YW5jZSA9IG9mY1dhbGxldHMuYmFzZUNvaW4ua2V5Y2hhaW5zKCk7XG4gICAgICAgIHNhbmRib3guc3R1YihrZXljaGFpbnNJbnN0YW5jZSwgJ2NyZWF0ZScpLnJldHVybnMoa2V5Y2hhaW4pO1xuXG4gICAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDoga2V5Y2hhaW4ucHJ2LCBwYXNzd29yZDogdXNlclBhc3N3b3JkIH0pO1xuICAgICAgICBzYW5kYm94LnN0dWIoYml0Z28sICdlbmNyeXB0JykucmVzb2x2ZXMoZW5jcnlwdGVkUHJ2KTtcblxuICAgICAgICBsZXQgY2FwdHVyZWRCb2R5OiBhbnk7XG4gICAgICAgIGNvbnN0IGFjY2VwdFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gLCAoYm9keTogYW55KSA9PiB7XG4gICAgICAgICAgICBjYXB0dXJlZEJvZHkgPSBib2R5O1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGNoYW5nZWQ6IHRydWUsIHN0YXRlOiAnYWNjZXB0ZWQnIH0pO1xuXG4gICAgICAgIGF3YWl0IG9mY1dhbGxldHMuYWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkLCB1c2VyUGFzc3dvcmQgfSk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IGV4YWN0IHZhbHVlc1xuICAgICAgICBzaG91bGQuZXF1YWwoY2FwdHVyZWRCb2R5LndhbGxldFNoYXJlSWQsIHNoYXJlSWQpO1xuICAgICAgICBzaG91bGQuZXF1YWwoY2FwdHVyZWRCb2R5LnN0YXRlLCAnYWNjZXB0ZWQnKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKGNhcHR1cmVkQm9keS5wdWIsIGtleWNoYWluLnB1Yik7XG4gICAgICAgIHNob3VsZC5lcXVhbChjYXB0dXJlZEJvZHkuZW5jcnlwdGVkUHJ2LCBlbmNyeXB0ZWRQcnYpO1xuICAgICAgICBzaG91bGQubm90LmV4aXN0KGNhcHR1cmVkQm9keS5zaWduYXR1cmUpO1xuICAgICAgICBzaG91bGQubm90LmV4aXN0KGNhcHR1cmVkQm9keS5wYXlsb2FkKTtcbiAgICAgICAgc2hvdWxkLm5vdC5leGlzdChjYXB0dXJlZEJvZHkua2V5SWQpO1xuXG4gICAgICAgIHdhbGxldFNoYXJlTm9jay5kb25lKCk7XG4gICAgICAgIGFjY2VwdFNoYXJlTm9jay5kb25lKCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2hhcmUgYSB3YWxsZXQgdG8gdmlld2VyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2hhcmVJZCA9ICcxMjMxMSc7XG5cbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi90YnRjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKS5yZXBseSgyMDAsIHt9KTtcbiAgICAgIGNvbnN0IGFjY2VwdFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyL3RidGMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWAsIHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgc3RhdGU6ICdhY2NlcHRlZCcgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwge30pO1xuXG4gICAgICBhd2FpdCB3YWxsZXRzLmFjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCB9KTtcbiAgICAgIGFjY2VwdFNoYXJlTm9jay5kb25lKCk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgndjIgZW52ZWxvcGUgc3VwcG9ydCBpbiBhY2NlcHRTaGFyZScsICgpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gICAgICBhZnRlckVhY2goKCkgPT4gc2FuZGJveC52ZXJpZnlBbmRSZXN0b3JlKCkpO1xuXG4gICAgICBpdCgnc2hvdWxkIGFjY2VwdCBzaGFyZSB3aGVuIEVDREggc2hhcmluZyBrZXljaGFpbiBlbmNyeXB0ZWRYcHJ2IGlzIHYyLWVuY3J5cHRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd2Mi1lY2RoLXhwcnYtMSc7XG4gICAgICAgIGNvbnN0IHVzZXJQYXNzd29yZCA9ICd0ZXN0X3Bhc3N3b3JkJztcblxuICAgICAgICAvLyBTaW11bGF0ZSBhIHYyIGVudmVsb3BlIGZvciB0aGUgRUNESCByb290IGtleVxuICAgICAgICBjb25zdCB2MkVuY3J5cHRlZFhwcnYgPSBKU09OLnN0cmluZ2lmeSh7IHY6IDIsIGl2OiAnYWFiYmNjJywgY3Q6ICdkZGVlZmYnLCBhZGF0YTogJzAwJyB9KTtcbiAgICAgICAgY29uc3QgZmFrZVhwcnYgPSAneHBydlNvbWVCYXNlNThWYWx1ZSc7XG4gICAgICAgIGNvbnN0IGZha2VTZWNyZXQgPSAnZmFrZUVjZGhTaGFyZWRTZWNyZXQnO1xuICAgICAgICBjb25zdCBkZWNyeXB0ZWRXYWxsZXRQcnYgPSAnd2FsbGV0UHJpdktleVBsYWludGV4dCc7XG5cbiAgICAgICAgY29uc3QgZWNrZXkgPSBtYWtlUmFuZG9tS2V5KCk7XG4gICAgICAgIGNvbnN0IHYyRW5jcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IHBhc3N3b3JkOiBmYWtlU2VjcmV0LCBpbnB1dDogZGVjcnlwdGVkV2FsbGV0UHJ2IH0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92Mi90YnRjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICAgIHBhdGg6ICdtLzAvMC8xJyxcbiAgICAgICAgICAgICAgZnJvbVB1YktleTogZWNrZXkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICAgICAgdG9QdWJLZXk6IGVja2V5LnB1YmxpY0tleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogdjJFbmNyeXB0ZWRQcnYsXG4gICAgICAgICAgICAgIHB1YjogZWNrZXkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIG5vY2soYmdVcmwpLnBvc3QoYC9hcGkvdjIvdGJ0Yy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YCkucmVwbHkoMjAwLCB7IGNoYW5nZWQ6IHRydWUsIHN0YXRlOiAnYWNjZXB0ZWQnIH0pO1xuXG4gICAgICAgIHNhbmRib3guc3R1YihiaXRnbywgJ2dldEVDREhLZXljaGFpbicpLnJlc29sdmVzKHsgZW5jcnlwdGVkWHBydjogdjJFbmNyeXB0ZWRYcHJ2IH0pO1xuICAgICAgICBjb25zdCBkZWNyeXB0QXN5bmNTdHViID0gc2FuZGJveC5zdHViKGJpdGdvLCAnZGVjcnlwdCcpO1xuICAgICAgICAvLyBGaXJzdCBjYWxsIGRlY3J5cHRzIHRoZSBFQ0RIIGtleWNoYWluICh2MiksIHNlY29uZCBkZWNyeXB0cyB0aGUgc2hhcmVkIHdhbGxldCBwcnZcbiAgICAgICAgZGVjcnlwdEFzeW5jU3R1Yi5vbkZpcnN0Q2FsbCgpLnJlc29sdmVzKGZha2VYcHJ2KTtcbiAgICAgICAgZGVjcnlwdEFzeW5jU3R1Yi5vblNlY29uZENhbGwoKS5yZXNvbHZlcyhkZWNyeXB0ZWRXYWxsZXRQcnYpO1xuICAgICAgICBzYW5kYm94LnN0dWIobW9kdWxlQml0Z28sICdnZXRTaGFyZWRTZWNyZXQnKS5yZXR1cm5zKEJ1ZmZlci5mcm9tKGZha2VTZWNyZXQpKTtcblxuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCB3YWxsZXRzLmFjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgdXNlclBhc3N3b3JkIH0pO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzLmNoYW5nZWQsIHRydWUpO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzLnN0YXRlLCAnYWNjZXB0ZWQnKTtcbiAgICAgICAgLy8gTXVzdCBoYXZlIGNhbGxlZCBkZWNyeXB0IChub3QgdGhlIHN5bmMgZGVjcnlwdCkgZm9yIGJvdGggdGhlIEVDREgga2V5IGFuZCB0aGUgd2FsbGV0IHBydlxuICAgICAgICBhc3NlcnQuZXF1YWwoZGVjcnlwdEFzeW5jU3R1Yi5jYWxsQ291bnQsIDIpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgYWNjZXB0IHNoYXJlIHdoZW4gd2FsbGV0IGtleWNoYWluIGVuY3J5cHRlZFBydiBpcyB2Mi1lbmNyeXB0ZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndjItd2FsbGV0LXBydi0xJztcbiAgICAgICAgY29uc3QgdXNlclBhc3N3b3JkID0gJ3Rlc3RfcGFzc3dvcmQnO1xuXG4gICAgICAgIGNvbnN0IHYyRW5jcnlwdGVkWHBydiA9IEpTT04uc3RyaW5naWZ5KHsgdjogMiwgaXY6ICdhYWJiY2MnLCBjdDogJ2RkZWVmZicsIGFkYXRhOiAnMDAnIH0pO1xuICAgICAgICBjb25zdCBmYWtlWHBydiA9ICd4cHJ2QW5vdGhlcktleSc7XG4gICAgICAgIGNvbnN0IGZha2VTZWNyZXQgPSAnZWNkaFNoYXJlZFNlY3JldDInO1xuICAgICAgICBjb25zdCBkZWNyeXB0ZWRXYWxsZXRQcnYgPSAnd2FsbGV0UHJpdktleTInO1xuICAgICAgICBjb25zdCB2MkVuY3J5cHRlZFBydiA9IEpTT04uc3RyaW5naWZ5KHsgdjogMiwgaXY6ICcxMTIyMzMnLCBjdDogJzQ0NTU2NicsIGFkYXRhOiAnNzcnIH0pO1xuICAgICAgICBjb25zdCBlY2tleSA9IG1ha2VSYW5kb21LZXkoKTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvdGJ0Yy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgICBwYXRoOiAnbS8wLzAvMicsXG4gICAgICAgICAgICAgIGZyb21QdWJLZXk6IGVja2V5LnB1YmxpY0tleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgICAgIHRvUHViS2V5OiBlY2tleS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IHYyRW5jcnlwdGVkUHJ2LFxuICAgICAgICAgICAgICBwdWI6IGVja2V5LnB1YmxpY0tleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICBub2NrKGJnVXJsKS5wb3N0KGAvYXBpL3YyL3RidGMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWApLnJlcGx5KDIwMCwgeyBjaGFuZ2VkOiB0cnVlLCBzdGF0ZTogJ2FjY2VwdGVkJyB9KTtcblxuICAgICAgICBzYW5kYm94LnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7IGVuY3J5cHRlZFhwcnY6IHYyRW5jcnlwdGVkWHBydiB9KTtcbiAgICAgICAgY29uc3QgZGVjcnlwdEFzeW5jU3R1YiA9IHNhbmRib3guc3R1YihiaXRnbywgJ2RlY3J5cHQnKTtcbiAgICAgICAgZGVjcnlwdEFzeW5jU3R1Yi5vbkZpcnN0Q2FsbCgpLnJlc29sdmVzKGZha2VYcHJ2KTtcbiAgICAgICAgZGVjcnlwdEFzeW5jU3R1Yi5vblNlY29uZENhbGwoKS5yZXNvbHZlcyhkZWNyeXB0ZWRXYWxsZXRQcnYpO1xuICAgICAgICBzYW5kYm94LnN0dWIobW9kdWxlQml0Z28sICdnZXRTaGFyZWRTZWNyZXQnKS5yZXR1cm5zKEJ1ZmZlci5mcm9tKGZha2VTZWNyZXQpKTtcblxuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCB3YWxsZXRzLmFjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgdXNlclBhc3N3b3JkIH0pO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzLmNoYW5nZWQsIHRydWUpO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzLnN0YXRlLCAnYWNjZXB0ZWQnKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2J1bGtBY2NlcHRTaGFyZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICAgICAgbm9jay5wZW5kaW5nTW9ja3MoKS5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgICAgICBzaW5vbi5yZXN0b3JlKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB2YWxpZGF0aW9uIGVycm9yIGZvciB1c2VyUGFzc3dvcmQgZW1wdHkgc3RyaW5nJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgICAgLmJ1bGtBY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWRzOiBbXSwgdXNlckxvZ2luUGFzc3dvcmQ6ICcnIH0pXG4gICAgICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ1BsZWFzZSBwcm92aWRlIGEgdmFsaWQgdXNlciBsb2dpbiBwYXNzd29yZCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgdmFsaWRhdGlvbiBlcnJvciBmb3Igc2VuZGluZyB3YWxsZXRQYXNzcGhyYXNlIGVtcHR5IHN0cmluZycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrQWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkczogW10sIHVzZXJMb2dpblBhc3N3b3JkOiAncGFzc3dvcmQnLCBuZXdXYWxsZXRQYXNzcGhyYXNlOiAxMjMgfSlcbiAgICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnUGxlYXNlIHByb3ZpZGUgYSB2YWxpZCB3YWxsZXQgcGFzc3BocmFzZScpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgYXNzZXJ0aW9uIGVycm9yIGZvciBlbXB0eSB3YWxsZXRTaGFyZUlkcycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrQWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkczogW10sIHVzZXJMb2dpblBhc3N3b3JkOiAnZHVtbXlAMTIzJyB9KVxuICAgICAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKCdQbGVhc2UgcHJvdmlkZSBhdCBsZWFzdCBvbmUgd2FsbGV0IHNoYXJlIHRvIGFjY2VwdCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIG5vIHZhbGlkIHdhbGxldCBzaGFyZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCcsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICdkdW1teVdhbGxldElkJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG91dGdvaW5nOiBbXSxcbiAgICAgICAgfSk7XG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa0FjY2VwdFNoYXJlKHtcbiAgICAgICAgICAgIHdhbGxldFNoYXJlSWRzOiBbJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQxJ10sXG4gICAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogJ2R1bW15QDEyMycsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnTm8gdmFsaWQgd2FsbGV0IHNoYXJlcyBmb3VuZCB0byBhY2NlcHQnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBubyB2YWxpZCB3YWxsZXRTaGFyZXMgd2l0aCBrZXljaGFpbicsIGFzeW5jICgpID0+IHtcbiAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQ0JyxcbiAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3RpbmcnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ2R1bW15V2FsbGV0SWQnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgICAgLmJ1bGtBY2NlcHRTaGFyZSh7XG4gICAgICAgICAgICB3YWxsZXRTaGFyZUlkczogWyc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCddLFxuICAgICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6ICdkdW1teUAxMjMnLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ05vIHZhbGlkIHdhbGxldCBzaGFyZXMgZm91bmQgdG8gYWNjZXB0Jyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3IgZWNkaCBrZXljaGFpbiB1bmRlZmluZWQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCcsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICdkdW1teVdhbGxldElkJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgICAgIHB1YjogJ3B1YicsXG4gICAgICAgICAgICAgICAgdG9QdWJLZXk6ICd0b1B1YktleScsXG4gICAgICAgICAgICAgICAgZnJvbVB1YktleTogJ2Zyb21QdWJLZXknLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogJ2VuY3J5cHRlZFBydicsXG4gICAgICAgICAgICAgICAgcGF0aDogJ3BhdGgnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG91dGdvaW5nOiBbXSxcbiAgICAgICAgfSk7XG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7XG4gICAgICAgICAgcHJ2OiAncHJpdmF0ZSBrZXknLFxuICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgICAgLmJ1bGtBY2NlcHRTaGFyZSh7XG4gICAgICAgICAgICB3YWxsZXRTaGFyZUlkczogWyc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCddLFxuICAgICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6ICdkdW1teUAxMjMnLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ2VuY3J5cHRlZFhwcnYgd2FzIG5vdCBmb3VuZCBvbiBzaGFyaW5nIGtleWNoYWluJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBzdWNjZXNzZnVsbHkgYWNjZXB0IHNoYXJlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBmcm9tVXNlclBydiA9IE1hdGgucmFuZG9tKCk7XG4gICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnYml0Z28xMjM0JztcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5UZXN0OiBPcHRpb25hbEtleWNoYWluRW5jcnlwdGVkS2V5ID0ge1xuICAgICAgICAgIGVuY3J5cHRlZFBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBmcm9tVXNlclBydi50b1N0cmluZygpLCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgdXNlclBydiA9IGF3YWl0IGRlY3J5cHRLZXljaGFpblByaXZhdGVLZXkoYml0Z28sIGtleWNoYWluVGVzdCwgd2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICAgIGlmICghdXNlclBydikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGRlY3J5cHQgdXNlciBrZXljaGFpbicpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdG9LZXljaGFpbiA9IHV0eG9MaWIuYmlwMzIuZnJvbVNlZWQoQnVmZmVyLmZyb20oJ2RlYWRiZWVmMDJkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDInLCAnaGV4JykpO1xuICAgICAgICBjb25zdCBwYXRoID0gJ20vOTk5OTk5LzEvMSc7XG4gICAgICAgIGNvbnN0IHB1YmtleSA9IHRvS2V5Y2hhaW4uZGVyaXZlUGF0aChwYXRoKS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICAgIGNvbnN0IGVja2V5ID0gbWFrZVJhbmRvbUtleSgpO1xuICAgICAgICBjb25zdCBzZWNyZXQgPSBnZXRTaGFyZWRTZWNyZXQoZWNrZXksIEJ1ZmZlci5mcm9tKHB1YmtleSwgJ2hleCcpKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgIGNvbnN0IG5ld0VuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBwYXNzd29yZDogc2VjcmV0LCBpbnB1dDogdXNlclBydiB9KTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KCcvYXBpL3YyL3dhbGxldHNoYXJlcycpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGlkOiAnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDQnLFxuICAgICAgICAgICAgICAgIGlzVU1TSW5pdGlhdGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICAgICAgICBwYXRoOiBwYXRoLFxuICAgICAgICAgICAgICAgICAgZnJvbVB1YktleTogZWNrZXkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogbmV3RW5jcnlwdGVkUHJ2LFxuICAgICAgICAgICAgICAgICAgdG9QdWJLZXk6IHB1YmtleSxcbiAgICAgICAgICAgICAgICAgIHB1YjogcHVia2V5LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wdXQoJy9hcGkvdjIvd2FsbGV0c2hhcmVzL2FjY2VwdCcpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHdhbGxldFNoYXJlSWQ6ICc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IG15RWNkaEtleWNoYWluID0gYXdhaXQgYml0Z28ua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7XG4gICAgICAgICAgZW5jcnlwdGVkWHBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBteUVjZGhLZXljaGFpbi54cHJ2LCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcHJ2S2V5ID0gYXdhaXQgYml0Z28uZGVjcnlwdCh7XG4gICAgICAgICAgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgaW5wdXQ6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogbXlFY2RoS2V5Y2hhaW4ueHBydiwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH0pO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZGVjcnlwdCcpLnJlc29sdmVzKHBydktleSk7XG4gICAgICAgIHNpbm9uLnN0dWIobW9kdWxlQml0Z28sICdnZXRTaGFyZWRTZWNyZXQnKS5yZXNvbHZlcygnZmFrZVNoYXJlZFNlY3JldCcpO1xuXG4gICAgICAgIGNvbnN0IHNoYXJlID0gYXdhaXQgd2FsbGV0cy5idWxrQWNjZXB0U2hhcmUoe1xuICAgICAgICAgIHdhbGxldFNoYXJlSWRzOiBbJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQ0J10sXG4gICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIH0pO1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHNoYXJlLCB7XG4gICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgd2FsbGV0U2hhcmVJZDogJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQ0JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBhY2NlcHQgc2hhcmUgd2hlbiBFQ0RIIHNoYXJpbmcga2V5Y2hhaW4gaXMgdjItZW5jcnlwdGVkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDQnO1xuXG4gICAgICAgIGNvbnN0IHRvS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyJywgJ2hleCcpKTtcbiAgICAgICAgY29uc3QgcGF0aCA9ICdtLzk5OTk5OS8xLzEnO1xuICAgICAgICBjb25zdCBwdWJrZXkgPSB0b0tleWNoYWluLmRlcml2ZVBhdGgocGF0aCkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgICAgY29uc3QgZWNrZXkgPSBtYWtlUmFuZG9tS2V5KCk7XG4gICAgICAgIGNvbnN0IHNlY3JldCA9IGdldFNoYXJlZFNlY3JldChlY2tleSwgQnVmZmVyLmZyb20ocHVia2V5LCAnaGV4JykpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgICAgY29uc3QgZGVjcnlwdGVkUHJ2ID0gJ3NvbWVXYWxsZXRQcml2YXRlS2V5JztcbiAgICAgICAgY29uc3QgbmV3RW5jcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IHBhc3N3b3JkOiBzZWNyZXQsIGlucHV0OiBkZWNyeXB0ZWRQcnYgfSk7XG5cbiAgICAgICAgLy8gU2ltdWxhdGUgdjItZW5jcnlwdGVkIEVDREgga2V5Y2hhaW4geHBydiAoZW52ZWxvcGUgd2l0aCB2OjIgbWFya2VyKVxuICAgICAgICBjb25zdCB2MkVuY3J5cHRlZFhwcnYgPSBKU09OLnN0cmluZ2lmeSh7IHY6IDIsIGl2OiAnYWFhJywgY3Q6ICdiYmInLCBhZGF0YTogJ2NjYycgfSk7XG4gICAgICAgIGNvbnN0IG15RWNkaFhwcnYgPSAneHBydlNvbWVCYXNlNThLZXknO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaS92Mi93YWxsZXRzaGFyZXMnKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpZDogc2hhcmVJZCxcbiAgICAgICAgICAgICAgICBpc1VNU0luaXRpYXRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgICAgICAgIGZyb21QdWJLZXk6IGVja2V5LnB1YmxpY0tleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IG5ld0VuY3J5cHRlZFBydixcbiAgICAgICAgICAgICAgICAgIHRvUHViS2V5OiBwdWJrZXksXG4gICAgICAgICAgICAgICAgICBwdWI6IHB1YmtleSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucHV0KCcvYXBpL3YyL3dhbGxldHNoYXJlcy9hY2NlcHQnKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHsgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQgfV0gfSk7XG5cbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2dldEVDREhLZXljaGFpbicpLnJlc29sdmVzKHsgZW5jcnlwdGVkWHBydjogdjJFbmNyeXB0ZWRYcHJ2IH0pO1xuICAgICAgICAvLyBkZWNyeXB0IHJlc29sdmVzIHdpdGggdGhlIHhwcnYgcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHRoZSBlbnZlbG9wZSBpcyB2MSBvciB2MlxuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZGVjcnlwdCcpLnJlc29sdmVzKG15RWNkaFhwcnYpO1xuICAgICAgICBzaW5vbi5zdHViKG1vZHVsZUJpdGdvLCAnZ2V0U2hhcmVkU2VjcmV0JykucmVzb2x2ZXMoJ2Zha2VTaGFyZWRTZWNyZXQnKTtcblxuICAgICAgICBjb25zdCBzaGFyZSA9IGF3YWl0IHdhbGxldHMuYnVsa0FjY2VwdFNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRTaGFyZUlkczogW3NoYXJlSWRdLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KTtcbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChzaGFyZSwgeyBhY2NlcHRlZFdhbGxldFNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCB9XSB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGFjY2VwdCBzaGFyZSB3aGVuIHdhbGxldCBrZXljaGFpbiBlbmNyeXB0ZWRQcnYgaXMgdjItZW5jcnlwdGVkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndjItcHJ2LXNoYXJlLTEnO1xuXG4gICAgICAgIGNvbnN0IHRvS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyJywgJ2hleCcpKTtcbiAgICAgICAgY29uc3QgcGF0aCA9ICdtLzk5OTk5OS8xLzEnO1xuICAgICAgICBjb25zdCBwdWJrZXkgPSB0b0tleWNoYWluLmRlcml2ZVBhdGgocGF0aCkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgICAgY29uc3QgZWNrZXkgPSBtYWtlUmFuZG9tS2V5KCk7XG5cbiAgICAgICAgLy8gU2ltdWxhdGUgdjItZW5jcnlwdGVkIGVuY3J5cHRlZFBydiBpbiB0aGUgd2FsbGV0IHNoYXJlIGtleWNoYWluXG4gICAgICAgIGNvbnN0IHYyRW5jcnlwdGVkUHJ2ID0gSlNPTi5zdHJpbmdpZnkoeyB2OiAyLCBpdjogJ3h4eCcsIGN0OiAneXl5JywgYWRhdGE6ICd6enonIH0pO1xuICAgICAgICBjb25zdCB2MkVuY3J5cHRlZFhwcnYgPSBKU09OLnN0cmluZ2lmeSh7IHY6IDIsIGl2OiAnYWFhJywgY3Q6ICdiYmInLCBhZGF0YTogJ2NjYycgfSk7XG4gICAgICAgIGNvbnN0IG15RWNkaFhwcnYgPSAneHBydlNvbWVCYXNlNThLZXknO1xuICAgICAgICBjb25zdCBkZWNyeXB0ZWRXYWxsZXRQcnYgPSAnZGVjcnlwdGVkV2FsbGV0UHJpdktleSc7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KCcvYXBpL3YyL3dhbGxldHNoYXJlcycpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGlkOiBzaGFyZUlkLFxuICAgICAgICAgICAgICAgIGlzVU1TSW5pdGlhdGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgICAgICAgZnJvbVB1YktleTogZWNrZXkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogdjJFbmNyeXB0ZWRQcnYsXG4gICAgICAgICAgICAgICAgICB0b1B1YktleTogcHVia2V5LFxuICAgICAgICAgICAgICAgICAgcHViOiBwdWJrZXksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnB1dCgnL2FwaS92Mi93YWxsZXRzaGFyZXMvYWNjZXB0JylcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkIH1dIH0pO1xuXG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7IGVuY3J5cHRlZFhwcnY6IHYyRW5jcnlwdGVkWHBydiB9KTtcbiAgICAgICAgLy8gRmlyc3QgY2FsbDogZGVjcnlwdCBFQ0RIIGtleWNoYWluIHhwcnY7IHNlY29uZCBjYWxsOiBkZWNyeXB0IHYyIHdhbGxldCBzaGFyZSBwcnZcbiAgICAgICAgY29uc3QgZGVjcnlwdEFzeW5jU3R1YiA9IHNpbm9uLnN0dWIoYml0Z28sICdkZWNyeXB0Jyk7XG4gICAgICAgIGRlY3J5cHRBc3luY1N0dWIub25GaXJzdENhbGwoKS5yZXNvbHZlcyhteUVjZGhYcHJ2KTtcbiAgICAgICAgZGVjcnlwdEFzeW5jU3R1Yi5vblNlY29uZENhbGwoKS5yZXNvbHZlcyhkZWNyeXB0ZWRXYWxsZXRQcnYpO1xuICAgICAgICBzaW5vbi5zdHViKG1vZHVsZUJpdGdvLCAnZ2V0U2hhcmVkU2VjcmV0JykucmVzb2x2ZXMoJ2Zha2VTaGFyZWRTZWNyZXQnKTtcblxuICAgICAgICBjb25zdCBzaGFyZSA9IGF3YWl0IHdhbGxldHMuYnVsa0FjY2VwdFNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRTaGFyZUlkczogW3NoYXJlSWRdLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KTtcbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChzaGFyZSwgeyBhY2NlcHRlZFdhbGxldFNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCB9XSB9KTtcbiAgICAgICAgLy8gQm90aCBkZWNyeXB0IGNhbGxzIG11c3QgdXNlIGRlY3J5cHQgKG5vdCB0aGUgc3luYyBkZWNyeXB0KVxuICAgICAgICBhc3NlcnQuZXF1YWwoZGVjcnlwdEFzeW5jU3R1Yi5jYWxsQ291bnQsIDIpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaW5jbHVkZSB3ZWJhdXRobkluZm8gaW4gcmVxdWVzdCB3aGVuIHByb3ZpZGVkIChFQ0RIIGJyYW5jaCknLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGZyb21Vc2VyUHJ2ID0gTWF0aC5yYW5kb20oKTtcbiAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuICAgICAgICBjb25zdCB3ZWJhdXRoblBhc3NwaHJhc2UgPSAncHJmLWRlcml2ZWQtc2VjcmV0JztcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCc7XG4gICAgICAgIGNvbnN0IGtleWNoYWluVGVzdDogT3B0aW9uYWxLZXljaGFpbkVuY3J5cHRlZEtleSA9IHtcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogZnJvbVVzZXJQcnYudG9TdHJpbmcoKSwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHVzZXJQcnYgPSBhd2FpdCBkZWNyeXB0S2V5Y2hhaW5Qcml2YXRlS2V5KGJpdGdvLCBrZXljaGFpblRlc3QsIHdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICBpZiAoIXVzZXJQcnYpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBkZWNyeXB0IHVzZXIga2V5Y2hhaW4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRvS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyJywgJ2hleCcpKTtcbiAgICAgICAgY29uc3QgcGF0aCA9ICdtLzk5OTk5OS8xLzEnO1xuICAgICAgICBjb25zdCBwdWJrZXkgPSB0b0tleWNoYWluLmRlcml2ZVBhdGgocGF0aCkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgICBjb25zdCBlY2tleSA9IG1ha2VSYW5kb21LZXkoKTtcbiAgICAgICAgY29uc3Qgc2VjcmV0ID0gZ2V0U2hhcmVkU2VjcmV0KGVja2V5LCBCdWZmZXIuZnJvbShwdWJrZXksICdoZXgnKSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgICBjb25zdCBuZXdFbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgcGFzc3dvcmQ6IHNlY3JldCwgaW5wdXQ6IHVzZXJQcnYgfSk7XG5cbiAgICAgICAgbGV0IGNhcHR1cmVkQm9keTogYW55O1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGkvdjIvd2FsbGV0c2hhcmVzJylcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWQ6IHNoYXJlSWQsXG4gICAgICAgICAgICAgICAgaXNVTVNJbml0aWF0ZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAga2V5Y2hhaW46IHtcbiAgICAgICAgICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgICAgICAgICBmcm9tUHViS2V5OiBlY2tleS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBuZXdFbmNyeXB0ZWRQcnYsXG4gICAgICAgICAgICAgICAgICB0b1B1YktleTogcHVia2V5LFxuICAgICAgICAgICAgICAgICAgcHViOiBwdWJrZXksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnB1dCgnL2FwaS92Mi93YWxsZXRzaGFyZXMvYWNjZXB0JywgKGJvZHkpID0+IHtcbiAgICAgICAgICAgIGNhcHR1cmVkQm9keSA9IGJvZHk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkIH1dLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IG15RWNkaEtleWNoYWluID0gYXdhaXQgYml0Z28ua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7XG4gICAgICAgICAgZW5jcnlwdGVkWHBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBteUVjZGhLZXljaGFpbi54cHJ2LCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcHJ2S2V5ID0gYXdhaXQgYml0Z28uZGVjcnlwdCh7XG4gICAgICAgICAgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgaW5wdXQ6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogbXlFY2RoS2V5Y2hhaW4ueHBydiwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH0pO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZGVjcnlwdCcpLnJlc29sdmVzKHBydktleSk7XG4gICAgICAgIHNpbm9uLnN0dWIobW9kdWxlQml0Z28sICdnZXRTaGFyZWRTZWNyZXQnKS5yZXNvbHZlcygnZmFrZVNoYXJlZFNlY3JldCcpO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldHMuYnVsa0FjY2VwdFNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRTaGFyZUlkczogW3NoYXJlSWRdLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIHdlYmF1dGhuSW5mbzoge1xuICAgICAgICAgICAgb3RwRGV2aWNlSWQ6ICdkZXZpY2UtMDAxJyxcbiAgICAgICAgICAgIHByZlNhbHQ6ICdzYWx0LWFiYycsXG4gICAgICAgICAgICBwYXNzcGhyYXNlOiB3ZWJhdXRoblBhc3NwaHJhc2UsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qgc2VudEVudHJpZXMgPSBjYXB0dXJlZEJvZHkua2V5c0ZvcldhbGxldFNoYXJlcztcbiAgICAgICAgc2VudEVudHJpZXMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgICBzZW50RW50cmllc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZW5jcnlwdGVkUHJ2Jyk7XG4gICAgICAgIHNlbnRFbnRyaWVzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3ZWJhdXRobkluZm8nKTtcbiAgICAgICAgc2VudEVudHJpZXNbMF0ud2ViYXV0aG5JbmZvLnNob3VsZC5oYXZlLnByb3BlcnR5KCdvdHBEZXZpY2VJZCcsICdkZXZpY2UtMDAxJyk7XG4gICAgICAgIHNlbnRFbnRyaWVzWzBdLndlYmF1dGhuSW5mby5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncHJmU2FsdCcsICdzYWx0LWFiYycpO1xuICAgICAgICBzZW50RW50cmllc1swXS53ZWJhdXRobkluZm8uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2VuY3J5cHRlZFBydicpO1xuICAgICAgICBzZW50RW50cmllc1swXS53ZWJhdXRobkluZm8uc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCdwYXNzcGhyYXNlJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBOT1QgaW5jbHVkZSB3ZWJhdXRobkluZm8gd2hlbiBub3QgcHJvdmlkZWQgKGJhY2t3YXJkIGNvbXBhdCknLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGZyb21Vc2VyUHJ2ID0gTWF0aC5yYW5kb20oKTtcbiAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQ0JztcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5UZXN0OiBPcHRpb25hbEtleWNoYWluRW5jcnlwdGVkS2V5ID0ge1xuICAgICAgICAgIGVuY3J5cHRlZFBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBmcm9tVXNlclBydi50b1N0cmluZygpLCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgdXNlclBydiA9IGF3YWl0IGRlY3J5cHRLZXljaGFpblByaXZhdGVLZXkoYml0Z28sIGtleWNoYWluVGVzdCwgd2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICAgIGlmICghdXNlclBydikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGRlY3J5cHQgdXNlciBrZXljaGFpbicpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdG9LZXljaGFpbiA9IHV0eG9MaWIuYmlwMzIuZnJvbVNlZWQoQnVmZmVyLmZyb20oJ2RlYWRiZWVmMDJkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDInLCAnaGV4JykpO1xuICAgICAgICBjb25zdCBwYXRoID0gJ20vOTk5OTk5LzEvMSc7XG4gICAgICAgIGNvbnN0IHB1YmtleSA9IHRvS2V5Y2hhaW4uZGVyaXZlUGF0aChwYXRoKS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICAgIGNvbnN0IGVja2V5ID0gbWFrZVJhbmRvbUtleSgpO1xuICAgICAgICBjb25zdCBzZWNyZXQgPSBnZXRTaGFyZWRTZWNyZXQoZWNrZXksIEJ1ZmZlci5mcm9tKHB1YmtleSwgJ2hleCcpKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgIGNvbnN0IG5ld0VuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBwYXNzd29yZDogc2VjcmV0LCBpbnB1dDogdXNlclBydiB9KTtcblxuICAgICAgICBsZXQgY2FwdHVyZWRCb2R5OiBhbnk7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaS92Mi93YWxsZXRzaGFyZXMnKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpZDogc2hhcmVJZCxcbiAgICAgICAgICAgICAgICBpc1VNU0luaXRpYXRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgICAgICAgICAgIGZyb21QdWJLZXk6IGVja2V5LnB1YmxpY0tleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IG5ld0VuY3J5cHRlZFBydixcbiAgICAgICAgICAgICAgICAgIHRvUHViS2V5OiBwdWJrZXksXG4gICAgICAgICAgICAgICAgICBwdWI6IHB1YmtleSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucHV0KCcvYXBpL3YyL3dhbGxldHNoYXJlcy9hY2NlcHQnLCAoYm9keSkgPT4ge1xuICAgICAgICAgICAgY2FwdHVyZWRCb2R5ID0gYm9keTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQgfV0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgbXlFY2RoS2V5Y2hhaW4gPSBhd2FpdCBiaXRnby5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2dldEVDREhLZXljaGFpbicpLnJlc29sdmVzKHtcbiAgICAgICAgICBlbmNyeXB0ZWRYcHJ2OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IG15RWNkaEtleWNoYWluLnhwcnYsIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgcHJ2S2V5ID0gYXdhaXQgYml0Z28uZGVjcnlwdCh7XG4gICAgICAgICAgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgaW5wdXQ6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogbXlFY2RoS2V5Y2hhaW4ueHBydiwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH0pO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZGVjcnlwdCcpLnJlc29sdmVzKHBydktleSk7XG4gICAgICAgIHNpbm9uLnN0dWIobW9kdWxlQml0Z28sICdnZXRTaGFyZWRTZWNyZXQnKS5yZXNvbHZlcygnZmFrZVNoYXJlZFNlY3JldCcpO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldHMuYnVsa0FjY2VwdFNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRTaGFyZUlkczogW3NoYXJlSWRdLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBzZW50RW50cmllcyA9IGNhcHR1cmVkQm9keS5rZXlzRm9yV2FsbGV0U2hhcmVzO1xuICAgICAgICBzZW50RW50cmllcy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICAgIHNlbnRFbnRyaWVzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCdlbmNyeXB0ZWRQcnYnKTtcbiAgICAgICAgc2VudEVudHJpZXNbMF0uc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCd3ZWJhdXRobkluZm8nKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSA0MTMgcGF5bG9hZCB0b28gbGFyZ2UgZXJyb3Igd2l0aCBzbWFydCByZXRyeScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuICAgICAgICBjb25zdCBmcm9tVXNlclBydiA9IE1hdGgucmFuZG9tKCk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluVGVzdDogT3B0aW9uYWxLZXljaGFpbkVuY3J5cHRlZEtleSA9IHtcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogZnJvbVVzZXJQcnYudG9TdHJpbmcoKSwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHVzZXJQcnYgPSBhd2FpdCBkZWNyeXB0S2V5Y2hhaW5Qcml2YXRlS2V5KGJpdGdvLCBrZXljaGFpblRlc3QsIHdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICBpZiAoIXVzZXJQcnYpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBkZWNyeXB0IHVzZXIga2V5Y2hhaW4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRvS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyJywgJ2hleCcpKTtcbiAgICAgICAgY29uc3QgcGF0aCA9ICdtLzk5OTk5OS8xLzEnO1xuICAgICAgICBjb25zdCBwdWJrZXkgPSB0b0tleWNoYWluLmRlcml2ZVBhdGgocGF0aCkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgICBjb25zdCBlY2tleSA9IG1ha2VSYW5kb21LZXkoKTtcbiAgICAgICAgY29uc3Qgc2VjcmV0ID0gZ2V0U2hhcmVkU2VjcmV0KGVja2V5LCBCdWZmZXIuZnJvbShwdWJrZXksICdoZXgnKSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgICAvLyBQYWQgdGhlIHByaXZhdGUga2V5IHdpdGggYWRkaXRpb25hbCBkYXRhIHRvIG1ha2UgaXQgbGFyZ2VyIGJlZm9yZSBlbmNyeXB0aW5nXG4gICAgICAgIGNvbnN0IG5ld0VuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBwYXNzd29yZDogc2VjcmV0LCBpbnB1dDogdXNlclBydiB9KTtcbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB7XG4gICAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgICBmcm9tUHViS2V5OiBlY2tleS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgIGVuY3J5cHRlZFBydjogbmV3RW5jcnlwdGVkUHJ2LFxuICAgICAgICAgIHRvUHViS2V5OiBwdWJrZXksXG4gICAgICAgICAgcHViOiBwdWJrZXksXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHNoYXJlSWRzID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogMjAgfSwgKF8sIGkpID0+IGBzaGFyZSR7aSArIDF9YCk7XG5cbiAgICAgICAgLy8gTW9jayBsaXN0U2hhcmVzVjIgdG8gcmV0dXJuIDI1IHNoYXJlc1xuICAgICAgICBjb25zdCBzaGFyZXMgPSBzaGFyZUlkcy5tYXAoKGlkLCBpbmRleCkgPT4gKHtcbiAgICAgICAgICBpZCxcbiAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgd2FsbGV0TGFiZWw6IGB0ZXN0aW5nJHtpbmRleH1gLFxuICAgICAgICAgIGZyb21Vc2VyOiAnZHVtbXlGcm9tVXNlcicsXG4gICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgIHdhbGxldDogYHdhbGxldCR7aW5kZXh9YCxcbiAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyBhcyBjb25zdCxcbiAgICAgICAgICBrZXljaGFpbjoga2V5Y2hhaW4sXG4gICAgICAgIH0pKTtcblxuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBzaGFyZXMsXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBteUVjZGhLZXljaGFpbiA9IGF3YWl0IGJpdGdvLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZ2V0RUNESEtleWNoYWluJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGVuY3J5cHRlZFhwcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogbXlFY2RoS2V5Y2hhaW4ueHBydiwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHBydktleSA9IGF3YWl0IGJpdGdvLmRlY3J5cHQoe1xuICAgICAgICAgIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGlucHV0OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IG15RWNkaEtleWNoYWluLnhwcnYsIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICB9KTtcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2RlY3J5cHQnKS5yZXNvbHZlcyhwcnZLZXkpO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZW5jcnlwdCcpLnJlc29sdmVzKHVzZXJQcnYgKyAnWCcucmVwZWF0KDEwMDAwMCkpO1xuICAgICAgICBzaW5vbi5zdHViKG1vZHVsZUJpdGdvLCAnZ2V0U2hhcmVkU2VjcmV0JykucmVzb2x2ZXMoJ2Zha2VTaGFyZWRTZWNyZXQnKTtcblxuICAgICAgICAvLyBNb2NrIGJ1bGtBY2NlcHRTaGFyZVJlcXVlc3RXaXRoUmV0cnkgdG8gdHJhY2sgYmF0Y2ggc2l6ZXNcbiAgICAgICAgY29uc3QgYmF0Y2hTaXplczogbnVtYmVyW10gPSBbXTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wZXJzaXN0KCkgLy8gVGhpcyBlbnN1cmVzIHRoZSBpbnRlcmNlcHRvciByZW1haW5zIGFjdGl2ZSBmb3IgbXVsdGlwbGUgcmVxdWVzdHNcbiAgICAgICAgICAucHV0KCcvYXBpL3YyL3dhbGxldHNoYXJlcy9hY2NlcHQnKVxuICAgICAgICAgIC5yZXBseShmdW5jdGlvbiAoXywgcmVxdWVzdEJvZHksIGNiKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSByZXF1ZXN0Qm9keVsna2V5c0ZvcldhbGxldFNoYXJlcyddIGFzIEFjY2VwdFNoYXJlT3B0aW9uc1JlcXVlc3RbXTtcbiAgICAgICAgICAgIGJhdGNoU2l6ZXMucHVzaChwYXJhbXMubGVuZ3RoKTtcbiAgICAgICAgICAgIGlmIChCdWZmZXIuYnl0ZUxlbmd0aChKU09OLnN0cmluZ2lmeShyZXF1ZXN0Qm9keSksICd1dGY4JykgPiA5NTAwMDApIHtcbiAgICAgICAgICAgICAgLy8gU2ltdWxhdGUgNDEzIGVycm9yXG4gICAgICAgICAgICAgIHJldHVybiBjYihudWxsLCBbNDEzLCB7IGVycm9yOiAnUmVxdWVzdCBFbnRpdHkgVG9vIExhcmdlJyB9XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBSZXR1cm4gc3VjY2VzcyBmb3Igc21hbGxlciBiYXRjaGVzXG4gICAgICAgICAgICByZXR1cm4gY2IobnVsbCwgW1xuICAgICAgICAgICAgICAyMDAsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogcGFyYW1zLm1hcCgocGFyYW0pID0+ICh7XG4gICAgICAgICAgICAgICAgICB3YWxsZXRTaGFyZUlkOiBwYXJhbS53YWxsZXRTaGFyZUlkLFxuICAgICAgICAgICAgICAgIH0pKSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0pO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldHMuYnVsa0FjY2VwdFNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRTaGFyZUlkczogc2hhcmVJZHMsXG4gICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNob3VsZCBoYXZlIHRyaWVkIHdpdGggMjAgKGluaXRpYWwgYmF0Y2ggc2l6ZSBmb3IgMjUgaXRlbXMpLCB0aGVuIHJldHJpZWQgd2l0aCBzbWFsbGVyIGJhdGNoZXNcbiAgICAgICAgYmF0Y2hTaXplcy5sZW5ndGguc2hvdWxkLmJlLmdyZWF0ZXJUaGFuKDEpO1xuICAgICAgICBiYXRjaFNpemVzLnNob3VsZC5kZWVwRXF1YWwoWzksIDksIDJdKTsgLy8gSW5pdGlhbCBiYXRjaCBzaXplLy8gUmV0cnkgYmF0Y2hlcyBzaG91bGQgYmUgc21hbGxlclxuXG4gICAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYWNjZXB0ZWRXYWxsZXRTaGFyZXMnKTtcbiAgICAgICAgcmVzdWx0LmFjY2VwdGVkV2FsbGV0U2hhcmVzLnNob3VsZC5iZS5hbi5BcnJheSgpO1xuICAgICAgICByZXN1bHQuYWNjZXB0ZWRXYWxsZXRTaGFyZXMubGVuZ3RoLnNob3VsZC5lcXVhbCgyMCk7XG4gICAgICAgIHJlc3VsdC5hY2NlcHRlZFdhbGxldFNoYXJlcy5mb3JFYWNoKChzaGFyZSkgPT4ge1xuICAgICAgICAgIHNoYXJlLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRTaGFyZUlkJyk7XG4gICAgICAgICAgc2hhcmUud2FsbGV0U2hhcmVJZC5zaG91bGQubWF0Y2goL15zaGFyZVxcZCskLyk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmV0cnkgd2l0aCBwcm9ncmVzc2l2ZWx5IHNtYWxsZXIgYmF0Y2ggc2l6ZXMgb24gNDEzIGVycm9ycycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuICAgICAgICBjb25zdCBmcm9tVXNlclBydiA9IE1hdGgucmFuZG9tKCk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluVGVzdDogT3B0aW9uYWxLZXljaGFpbkVuY3J5cHRlZEtleSA9IHtcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogZnJvbVVzZXJQcnYudG9TdHJpbmcoKSwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHVzZXJQcnYgPSBhd2FpdCBkZWNyeXB0S2V5Y2hhaW5Qcml2YXRlS2V5KGJpdGdvLCBrZXljaGFpblRlc3QsIHdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICBpZiAoIXVzZXJQcnYpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBkZWNyeXB0IHVzZXIga2V5Y2hhaW4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRvS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyJywgJ2hleCcpKTtcbiAgICAgICAgY29uc3QgcGF0aCA9ICdtLzk5OTk5OS8xLzEnO1xuICAgICAgICBjb25zdCBwdWJrZXkgPSB0b0tleWNoYWluLmRlcml2ZVBhdGgocGF0aCkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgICBjb25zdCBlY2tleSA9IG1ha2VSYW5kb21LZXkoKTtcbiAgICAgICAgY29uc3Qgc2VjcmV0ID0gZ2V0U2hhcmVkU2VjcmV0KGVja2V5LCBCdWZmZXIuZnJvbShwdWJrZXksICdoZXgnKSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgICBjb25zdCBuZXdFbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgcGFzc3dvcmQ6IHNlY3JldCwgaW5wdXQ6IHVzZXJQcnYgfSk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluID0ge1xuICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgZnJvbVB1YktleTogZWNrZXkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IG5ld0VuY3J5cHRlZFBydixcbiAgICAgICAgICB0b1B1YktleTogcHVia2V5LFxuICAgICAgICAgIHB1YjogcHVia2V5LFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBzaGFyZUlkcyA9IEFycmF5LmZyb20oeyBsZW5ndGg6IDIwIH0sIChfLCBpKSA9PiBgc2hhcmUke2kgKyAxfWApO1xuXG4gICAgICAgIC8vIE1vY2sgbGlzdFNoYXJlc1YyXG4gICAgICAgIGNvbnN0IHNoYXJlcyA9IHNoYXJlSWRzLm1hcCgoaWQsIGluZGV4KSA9PiAoe1xuICAgICAgICAgIGlkLFxuICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICB3YWxsZXRMYWJlbDogYHRlc3Rpbmcke2luZGV4fWAsXG4gICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgd2FsbGV0OiBgd2FsbGV0JHtpbmRleH1gLFxuICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAgc3RhdGU6ICdhY3RpdmUnIGFzIGNvbnN0LFxuICAgICAgICAgIGtleWNoYWluOiBrZXljaGFpbixcbiAgICAgICAgfSkpO1xuXG4gICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaW5jb21pbmc6IHNoYXJlcyxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IG15RWNkaEtleWNoYWluID0gYXdhaXQgYml0Z28ua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7XG4gICAgICAgICAgZW5jcnlwdGVkWHBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBteUVjZGhLZXljaGFpbi54cHJ2LCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcHJ2S2V5ID0gYXdhaXQgYml0Z28uZGVjcnlwdCh7XG4gICAgICAgICAgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgaW5wdXQ6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogbXlFY2RoS2V5Y2hhaW4ueHBydiwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH0pO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZGVjcnlwdCcpLnJlc29sdmVzKHBydktleSk7XG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdlbmNyeXB0JykucmVzb2x2ZXModXNlclBydiArICdYJy5yZXBlYXQoMTAwMDAwKSk7XG4gICAgICAgIHNpbm9uLnN0dWIobW9kdWxlQml0Z28sICdnZXRTaGFyZWRTZWNyZXQnKS5yZXNvbHZlcygnZmFrZVNoYXJlZFNlY3JldCcpO1xuXG4gICAgICAgIC8vIFRyYWNrIHRoZSBzZXF1ZW5jZSBvZiBiYXRjaCBzaXplcyBhdHRlbXB0ZWRcbiAgICAgICAgY29uc3QgYmF0Y2hTaXplQXR0ZW1wdHM6IG51bWJlcltdID0gW107XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucGVyc2lzdCgpIC8vIFRoaXMgZW5zdXJlcyB0aGUgaW50ZXJjZXB0b3IgcmVtYWlucyBhY3RpdmUgZm9yIG11bHRpcGxlIHJlcXVlc3RzXG4gICAgICAgICAgLnB1dCgnL2FwaS92Mi93YWxsZXRzaGFyZXMvYWNjZXB0JylcbiAgICAgICAgICAucmVwbHkoZnVuY3Rpb24gKF8sIHJlcXVlc3RCb2R5OiBhbnksIGNiKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSByZXF1ZXN0Qm9keVsna2V5c0ZvcldhbGxldFNoYXJlcyddIGFzIEFjY2VwdFNoYXJlT3B0aW9uc1JlcXVlc3RbXTtcbiAgICAgICAgICAgIGJhdGNoU2l6ZUF0dGVtcHRzLnB1c2gocGFyYW1zLmxlbmd0aCk7XG5cbiAgICAgICAgICAgIC8vIFNpbXVsYXRlIDQxMyBmb3IgYmF0Y2hlcyA+IDUsIHN1Y2Nlc3MgZm9yIGJhdGNoZXMgPD0gNVxuICAgICAgICAgICAgaWYgKEJ1ZmZlci5ieXRlTGVuZ3RoKEpTT04uc3RyaW5naWZ5KHJlcXVlc3RCb2R5KSwgJ3V0ZjgnKSA+IDYwMDAwMCkge1xuICAgICAgICAgICAgICAvLyBTaW11bGF0ZSA0MTMgZXJyb3JcbiAgICAgICAgICAgICAgcmV0dXJuIGNiKG51bGwsIFs0MTMsIHsgZXJyb3I6ICdSZXF1ZXN0IEVudGl0eSBUb28gTGFyZ2UnIH1dKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gUmV0dXJuIHN1Y2Nlc3MgZm9yIHNtYWxsZXIgYmF0Y2hlc1xuICAgICAgICAgICAgcmV0dXJuIGNiKG51bGwsIFtcbiAgICAgICAgICAgICAgMjAwLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IHBhcmFtcy5tYXAoKHBhcmFtKSA9PiAoe1xuICAgICAgICAgICAgICAgICAgd2FsbGV0U2hhcmVJZDogcGFyYW0ud2FsbGV0U2hhcmVJZCB8fCAndGVzdCcsXG4gICAgICAgICAgICAgICAgfSkpLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd2FsbGV0cy5idWxrQWNjZXB0U2hhcmUoe1xuICAgICAgICAgIHdhbGxldFNoYXJlSWRzOiBzaGFyZUlkcyxcbiAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2hvdWxkIHNlZSBwcm9ncmVzc2l2ZSBiYXRjaCBzaXplIHJlZHVjdGlvbjogMjAgLT4gMTAgLT4gNSAoc3VjY2VzcylcbiAgICAgICAgYmF0Y2hTaXplQXR0ZW1wdHMuc2hvdWxkLmNvbnRhaW5EZWVwKFs5LCA0LCA0LCA0LCA0LCA0XSk7XG5cbiAgICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhY2NlcHRlZFdhbGxldFNoYXJlcycpO1xuICAgICAgICByZXN1bHQuYWNjZXB0ZWRXYWxsZXRTaGFyZXMuc2hvdWxkLmJlLmFuLkFycmF5KCk7XG4gICAgICAgIHJlc3VsdC5hY2NlcHRlZFdhbGxldFNoYXJlcy5sZW5ndGguc2hvdWxkLmVxdWFsKDIwKTtcbiAgICAgICAgcmVzdWx0LmFjY2VwdGVkV2FsbGV0U2hhcmVzLmZvckVhY2goKHNoYXJlKSA9PiB7XG4gICAgICAgICAgc2hhcmUuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldFNoYXJlSWQnKTtcbiAgICAgICAgICBzaGFyZS53YWxsZXRTaGFyZUlkLnNob3VsZC5tYXRjaCgvXnNoYXJlXFxkKyQvKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aGVuIGJhdGNoIHNpemUgY2Fubm90IGJlIHJlZHVjZWQgZnVydGhlcicsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuICAgICAgICBjb25zdCBmcm9tVXNlclBydiA9IE1hdGgucmFuZG9tKCk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluVGVzdDogT3B0aW9uYWxLZXljaGFpbkVuY3J5cHRlZEtleSA9IHtcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogZnJvbVVzZXJQcnYudG9TdHJpbmcoKSwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHVzZXJQcnYgPSBhd2FpdCBkZWNyeXB0S2V5Y2hhaW5Qcml2YXRlS2V5KGJpdGdvLCBrZXljaGFpblRlc3QsIHdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICBpZiAoIXVzZXJQcnYpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBkZWNyeXB0IHVzZXIga2V5Y2hhaW4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRvS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyJywgJ2hleCcpKTtcbiAgICAgICAgY29uc3QgcGF0aCA9ICdtLzk5OTk5OS8xLzEnO1xuICAgICAgICBjb25zdCBwdWJrZXkgPSB0b0tleWNoYWluLmRlcml2ZVBhdGgocGF0aCkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgICBjb25zdCBlY2tleSA9IG1ha2VSYW5kb21LZXkoKTtcbiAgICAgICAgY29uc3Qgc2VjcmV0ID0gZ2V0U2hhcmVkU2VjcmV0KGVja2V5LCBCdWZmZXIuZnJvbShwdWJrZXksICdoZXgnKSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgICBjb25zdCBuZXdFbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgcGFzc3dvcmQ6IHNlY3JldCwgaW5wdXQ6IHVzZXJQcnYgfSk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluID0ge1xuICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgZnJvbVB1YktleTogZWNrZXkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IG5ld0VuY3J5cHRlZFBydixcbiAgICAgICAgICB0b1B1YktleTogcHVia2V5LFxuICAgICAgICAgIHB1YjogcHVia2V5LFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBzaGFyZUlkcyA9IFsnc2hhcmUxJ107XG5cbiAgICAgICAgLy8gTW9jayBsaXN0U2hhcmVzVjJcbiAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJ3NoYXJlMScsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICd3YWxsZXQxJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgICBrZXljaGFpbjoga2V5Y2hhaW4sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBteUVjZGhLZXljaGFpbiA9IGF3YWl0IGJpdGdvLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZ2V0RUNESEtleWNoYWluJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGVuY3J5cHRlZFhwcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogbXlFY2RoS2V5Y2hhaW4ueHBydiwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHBydktleSA9IGF3YWl0IGJpdGdvLmRlY3J5cHQoe1xuICAgICAgICAgIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGlucHV0OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IG15RWNkaEtleWNoYWluLnhwcnYsIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICB9KTtcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2RlY3J5cHQnKS5yZXNvbHZlcyhwcnZLZXkpO1xuICAgICAgICBzaW5vbi5zdHViKG1vZHVsZUJpdGdvLCAnZ2V0U2hhcmVkU2VjcmV0JykucmVzb2x2ZXMoJ2Zha2VTaGFyZWRTZWNyZXQnKTtcblxuICAgICAgICAvLyBBbHdheXMgdGhyb3cgNDEzIGVycm9yLCBldmVuIGZvciBiYXRjaCBzaXplIDFcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucGVyc2lzdCgpXG4gICAgICAgICAgLnB1dCgnL2FwaS92Mi93YWxsZXRzaGFyZXMvYWNjZXB0JylcbiAgICAgICAgICAucmVwbHkoZnVuY3Rpb24gKF8sIF9yZXF1ZXN0Qm9keSwgY2IpIHtcbiAgICAgICAgICAgIC8vIEFsd2F5cyByZXNwb25kIHdpdGggNDEzIGVycm9yXG4gICAgICAgICAgICByZXR1cm4gY2IobnVsbCwgWzQxMywgeyBlcnJvcjogJ1JlcXVlc3QgRW50aXR5IFRvbyBMYXJnZScgfV0pO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa0FjY2VwdFNoYXJlKHtcbiAgICAgICAgICAgIHdhbGxldFNoYXJlSWRzOiBzaGFyZUlkcyxcbiAgICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ1JlcXVlc3QgRW50aXR5IFRvbyBMYXJnZScpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnYnVsa1VwZGF0ZVdhbGxldFNoYXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgICAgICBub2NrLnBlbmRpbmdNb2NrcygpLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gICAgICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IHZhbGlkYXRpb24gZXJyb3IgZm9yIG1pc3Npbmcgc2hhcmVzIHBhcmFtZXRlcicsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0cy5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe30pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ01pc3NpbmcgcGFyYW1ldGVyOiBzaGFyZXMnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IHZhbGlkYXRpb24gZXJyb3IgZm9yIG5vbi1hcnJheSBzaGFyZXMgcGFyYW1ldGVyJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgICAgLmJ1bGtVcGRhdGVXYWxsZXRTaGFyZSh7IHNoYXJlczogJ25vdC1hbi1hcnJheScgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnRXhwZWN0aW5nIHBhcmFtZXRlciBhcnJheTogc2hhcmVzIGJ1dCBmb3VuZCBzdHJpbmcnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IHZhbGlkYXRpb24gZXJyb3IgZm9yIG1pc3Npbmcgd2FsbGV0U2hhcmVJZCBpbiBzaGFyZScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrVXBkYXRlV2FsbGV0U2hhcmUoeyBzaGFyZXM6IFt7IHN0YXR1czogJ2FjY2VwdCcgfV0gfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnTWlzc2luZyB3YWxsZXRTaGFyZUlkIGluIHNoYXJlJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB2YWxpZGF0aW9uIGVycm9yIGZvciBtaXNzaW5nIHN0YXR1cyBpbiBzaGFyZScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrVXBkYXRlV2FsbGV0U2hhcmUoeyBzaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6ICcxMjMnIH1dIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ01pc3Npbmcgc3RhdHVzIGluIHNoYXJlJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB2YWxpZGF0aW9uIGVycm9yIGZvciBpbnZhbGlkIHN0YXR1cyBpbiBzaGFyZScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrVXBkYXRlV2FsbGV0U2hhcmUoeyBzaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6ICcxMjMnLCBzdGF0dXM6ICdpbnZhbGlkJyB9XSB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIHN0YXR1cyBpbiBzaGFyZTogaW52YWxpZC4gTXVzdCBiZSBlaXRoZXIgXCJhY2NlcHRcIiBvciBcInJlamVjdFwiJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB2YWxpZGF0aW9uIGVycm9yIGZvciBub24tc3RyaW5nIHdhbGxldFNoYXJlSWQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHsgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiAxMjMsIHN0YXR1czogJ2FjY2VwdCcgfV0gfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnRXhwZWN0aW5nIHdhbGxldFNoYXJlSWQgdG8gYmUgYSBzdHJpbmcgYnV0IGZvdW5kIG51bWJlcicpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgdmFsaWRhdGlvbiBlcnJvciBmb3Igbm9uLXN0cmluZyB1c2VyTG9naW5QYXNzd29yZCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrVXBkYXRlV2FsbGV0U2hhcmUoeyBzaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6ICcxMjMnLCBzdGF0dXM6ICdhY2NlcHQnIH1dLCB1c2VyTG9naW5QYXNzd29yZDogMTIzIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0V4cGVjdGluZyBwYXJhbWV0ZXIgc3RyaW5nOiB1c2VyTG9naW5QYXNzd29yZCBidXQgZm91bmQgbnVtYmVyJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB2YWxpZGF0aW9uIGVycm9yIGZvciBub24tc3RyaW5nIG5ld1dhbGxldFBhc3NwaHJhc2UnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICAgIHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogJzEyMycsIHN0YXR1czogJ2FjY2VwdCcgfV0sXG4gICAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogJ3Bhc3N3b3JkJyxcbiAgICAgICAgICAgIG5ld1dhbGxldFBhc3NwaHJhc2U6IDEyMyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdFeHBlY3RpbmcgcGFyYW1ldGVyIHN0cmluZzogbmV3V2FsbGV0UGFzc3BocmFzZSBidXQgZm91bmQgbnVtYmVyJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBhc3NlcnRpb24gZXJyb3IgZm9yIGVtcHR5IHNoYXJlcyBhcnJheScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0cy5idWxrVXBkYXRlV2FsbGV0U2hhcmUoeyBzaGFyZXM6IFtdIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ25vIHNoYXJlcyBhcmUgcGFzc2VkJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3Igbm8gdmFsaWQgd2FsbGV0IHNoYXJlcycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQ0JyxcbiAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3RpbmcnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ2R1bW15V2FsbGV0SWQnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe1xuICAgICAgICAgICAgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiAnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDEnLCBzdGF0dXM6ICdhY2NlcHQnIH1dLFxuICAgICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6ICdkdW1teUAxMjMnLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgd2FsbGV0IHNoYXJlIHByb3ZpZGVkOiA2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkMScpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIGVjZGgga2V5Y2hhaW4gdW5kZWZpbmVkIHdoZW4gYWNjZXB0aW5nIHNoYXJlIHJlcXVpcmluZyBkZWNyeXB0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDQnLFxuICAgICAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgICAgIHdhbGxldExhYmVsOiAndGVzdGluZycsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZHVtbXlGcm9tVXNlcicsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ2R1bW15VG9Vc2VyJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnZHVtbXlXYWxsZXRJZCcsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgICAga2V5Y2hhaW46IHtcbiAgICAgICAgICAgICAgICBwdWI6ICdwdWInLFxuICAgICAgICAgICAgICAgIHRvUHViS2V5OiAndG9QdWJLZXknLFxuICAgICAgICAgICAgICAgIGZyb21QdWJLZXk6ICdmcm9tUHViS2V5JyxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6ICdlbmNyeXB0ZWRQcnYnLFxuICAgICAgICAgICAgICAgIHBhdGg6ICdwYXRoJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZ2V0RUNESEtleWNoYWluJykucmVzb2x2ZXMoe1xuICAgICAgICAgIHBydjogJ3ByaXZhdGUga2V5JyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe1xuICAgICAgICAgICAgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiAnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDQnLCBzdGF0dXM6ICdhY2NlcHQnIH1dLFxuICAgICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6ICdkdW1teUAxMjMnLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2VuY3J5cHRlZFhwcnYgd2FzIG5vdCBmb3VuZCBvbiBzaGFyaW5nIGtleWNoYWluJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBzdWNjZXNzZnVsbHkgdXBkYXRlIHNoYXJlcyB3aXRoIGJvdGggYWNjZXB0IGFuZCByZWplY3Qgc3RhdHVzZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnYml0Z28xMjM0JztcblxuICAgICAgICAvLyBNb2NrIGxpc3RTaGFyZXNWMiB0byByZXR1cm4gdHdvIHNoYXJlc1xuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnc2hhcmUxJyxcbiAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3RpbmcnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ3dhbGxldDEnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJ3NoYXJlMicsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nMicsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZHVtbXlGcm9tVXNlcicsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ2R1bW15VG9Vc2VyJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnd2FsbGV0MicsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE1vY2sgYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdFxuICAgICAgICBjb25zdCBidWxrVXBkYXRlU3R1YiA9IHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0JykucmVzb2x2ZXMoe1xuICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMSddLFxuICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMiddLFxuICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd2FsbGV0cy5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe1xuICAgICAgICAgIHNoYXJlczogW1xuICAgICAgICAgICAgeyB3YWxsZXRTaGFyZUlkOiAnc2hhcmUxJywgc3RhdHVzOiAnYWNjZXB0JyB9LFxuICAgICAgICAgICAgeyB3YWxsZXRTaGFyZUlkOiAnc2hhcmUyJywgc3RhdHVzOiAncmVqZWN0JyB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFZlcmlmeSB0aGUgcmVzdWx0XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwocmVzdWx0LCB7XG4gICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFsnc2hhcmUxJ10sXG4gICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFsnc2hhcmUyJ10sXG4gICAgICAgICAgd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnM6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBWZXJpZnkgYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCB3YXMgY2FsbGVkIHdpdGggY29ycmVjdCBwYXJhbWV0ZXJzXG4gICAgICAgIGJ1bGtVcGRhdGVTdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgY29uc3QgdXBkYXRlUGFyYW1zID0gYnVsa1VwZGF0ZVN0dWIuZmlyc3RDYWxsLmFyZ3NbMF07XG4gICAgICAgIHVwZGF0ZVBhcmFtcy5zaG91bGQuaGF2ZS5sZW5ndGhPZigyKTtcblxuICAgICAgICAvLyBTZWNvbmQgcGFyYW0gc2hvdWxkIGJlIGZvciBzaGFyZTIgd2l0aCByZWplY3Qgc3RhdHVzXG4gICAgICAgIHVwZGF0ZVBhcmFtcy5zaG91bGQuY29udGFpbkRlZXAoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHdhbGxldFNoYXJlSWQ6ICdzaGFyZTInLFxuICAgICAgICAgICAgc3RhdHVzOiAncmVqZWN0JyxcbiAgICAgICAgICB9LFxuICAgICAgICBdKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQgd2l0aCBuZXdXYWxsZXRQYXNzcGhyYXNlIGluIGJ1bGsgb3BlcmF0aW9ucycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgdXNlckxvZ2luUGFzc3dvcmQgPSAnYml0Z28xMjM0JztcbiAgICAgICAgY29uc3QgbmV3V2FsbGV0UGFzc3BocmFzZSA9ICduZXdfd2FsbGV0X3Bhc3NwaHJhc2VfNDU2JztcblxuICAgICAgICAvLyBNb2NrIGxpc3RTaGFyZXNWMiB0byByZXR1cm4gYSBzaGFyZSB3aXRoIGtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZFxuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnc2hhcmUxJyxcbiAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3RpbmcnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ3dhbGxldDEnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICAgIGtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE1vY2sgdXNlciBzZXR0aW5ncyBBUEkgY2FsbCAocmVxdWlyZWQgYnkgYnVsa1VwZGF0ZVdhbGxldFNoYXJlKVxuICAgICAgICBub2NrKGJnVXJsKS5nZXQoJy9hcGkvdjEvdXNlci9zZXR0aW5ncycpLnJlcGx5KDIwMCwge30pO1xuXG4gICAgICAgIC8vIE1vY2sgZ2V0RUNESEtleWNoYWluIChyZXF1aXJlZCBieSBidWxrVXBkYXRlV2FsbGV0U2hhcmUgd2hlbiB1c2VyTG9naW5QYXNzd29yZCBpcyBwcm92aWRlZClcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2dldEVDREhLZXljaGFpbicpLnJlc29sdmVzKHtcbiAgICAgICAgICBlbmNyeXB0ZWRYcHJ2OiAnZW5jcnlwdGVkWHBydicsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNldHVwIGZvciB0aGUgYmFzZUNvaW4ua2V5Y2hhaW5zKCkuY3JlYXRlVXNlcktleWNoYWluXG4gICAgICAgIGNvbnN0IHVzZXJLZXljaGFpbiA9IHtcbiAgICAgICAgICBpZDogJ2tleTEnLFxuICAgICAgICAgIHB1YjogJ3B1YktleScsXG4gICAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZW5jcnlwdGVkUHJpdmF0ZUtleScsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGNyZWF0ZVVzZXJLZXljaGFpblN0dWIgPSBzaW5vblxuICAgICAgICAgIC5zdHViKHdhbGxldHMuYmFzZUNvaW4ua2V5Y2hhaW5zKCksICdjcmVhdGVVc2VyS2V5Y2hhaW4nKVxuICAgICAgICAgIC5yZXNvbHZlcyh1c2VyS2V5Y2hhaW4pO1xuXG4gICAgICAgIC8vIE1vY2sgZGVjcnlwdCBhbmQgc2lnbk1lc3NhZ2VcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2RlY3J5cHQnKS5yZXNvbHZlcygnZGVjcnlwdGVkUHJpdmF0ZUtleScpO1xuICAgICAgICBzaW5vbi5zdHViKHdhbGxldHMuYmFzZUNvaW4sICdzaWduTWVzc2FnZScpLnJlc29sdmVzKEJ1ZmZlci5mcm9tKCdzaWduYXR1cmUnKSk7XG5cbiAgICAgICAgLy8gTW9jayBidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0XG4gICAgICAgIGNvbnN0IGJ1bGtVcGRhdGVTdHViID0gc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2J1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3QnKS5yZXNvbHZlcyh7XG4gICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFsnc2hhcmUxJ10sXG4gICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gTW9jayByZXNoYXJlV2FsbGV0V2l0aFNwZW5kZXJzIChjYWxsZWQgZm9yIGtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZCBjYXNlcylcbiAgICAgICAgY29uc3QgcmVzaGFyZVN0dWIgPSBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAncmVzaGFyZVdhbGxldFdpdGhTcGVuZGVycycpLnJlc29sdmVzKCk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd2FsbGV0cy5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe1xuICAgICAgICAgIHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMScsIHN0YXR1czogJ2FjY2VwdCcgfV0sXG4gICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6IHVzZXJMb2dpblBhc3N3b3JkLFxuICAgICAgICAgIG5ld1dhbGxldFBhc3NwaHJhc2U6IG5ld1dhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFZlcmlmeSBjcmVhdGVVc2VyS2V5Y2hhaW4gd2FzIGNhbGxlZCB3aXRoIG5ld1dhbGxldFBhc3NwaHJhc2UgKG5vdCB1c2VyTG9naW5QYXNzd29yZClcbiAgICAgICAgY3JlYXRlVXNlcktleWNoYWluU3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIGNyZWF0ZVVzZXJLZXljaGFpblN0dWIuY2FsbGVkV2l0aChuZXdXYWxsZXRQYXNzcGhyYXNlKS5zaG91bGQuYmUudHJ1ZSgpO1xuXG4gICAgICAgIC8vIFZlcmlmeSB0aGUgcmVzdWx0XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwocmVzdWx0LCB7XG4gICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFsnc2hhcmUxJ10sXG4gICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYnVsa1VwZGF0ZVN0dWIuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICAvLyBWZXJpZnkgcmVzaGFyZSB3YXMgY2FsbGVkIGZvciBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQgY2FzZVxuICAgICAgICByZXNoYXJlU3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgc3BlY2lhbCBvdmVycmlkZSBjYXNlcyBhbmQgcmVzaGFyZSB3aXRoIHNwZW5kZXJzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG4gICAgICAgIC8vIE1vY2sgbGlzdFNoYXJlc1YyIHRvIHJldHVybiBhIHNoYXJlIHdpdGgga2V5Y2hhaW5PdmVycmlkZVJlcXVpcmVkXG4gICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICdzaGFyZTEnLFxuICAgICAgICAgICAgICBjb2luOiAnb2ZjJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICd3YWxsZXQxJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgICBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTZXR1cCBmb3IgdGhlIGJhc2VDb2luLmtleWNoYWlucygpLmNyZWF0ZVVzZXJLZXljaGFpblxuICAgICAgICBjb25zdCB1c2VyS2V5Y2hhaW4gPSB7XG4gICAgICAgICAgaWQ6ICdrZXkxJyxcbiAgICAgICAgICBwdWI6ICdwdWJLZXknLFxuICAgICAgICAgIGVuY3J5cHRlZFBydjogJ2VuY3J5cHRlZFByaXZhdGVLZXknLFxuICAgICAgICB9O1xuICAgICAgICBzaW5vbi5zdHViKG9mY1dhbGxldHMuYmFzZUNvaW4ua2V5Y2hhaW5zKCksICdjcmVhdGVVc2VyS2V5Y2hhaW4nKS5yZXNvbHZlcyh1c2VyS2V5Y2hhaW4pO1xuXG4gICAgICAgIC8vIE1vY2sgZGVjcnlwdCBhbmQgc2lnbk1lc3NhZ2VcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2RlY3J5cHQnKS5yZXNvbHZlcygnZGVjcnlwdGVkUHJpdmF0ZUtleScpO1xuICAgICAgICBzaW5vbi5zdHViKG9mY1dhbGxldHMuYmFzZUNvaW4sICdzaWduTWVzc2FnZScpLnJlc29sdmVzKEJ1ZmZlci5mcm9tKCdzaWduYXR1cmUnKSk7XG5cbiAgICAgICAgLy8gTW9jayBnZXRFQ0RIS2V5Y2hhaW5cbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2dldEVDREhLZXljaGFpbicpLnJlc29sdmVzKHtcbiAgICAgICAgICBlbmNyeXB0ZWRYcHJ2OiAnZW5jcnlwdGVkWHBydicsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE1vY2sgYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdFxuICAgICAgICBjb25zdCBidWxrVXBkYXRlU3R1YiA9IHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0JykucmVzb2x2ZXMoe1xuICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMSddLFxuICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbXSxcbiAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE1vY2sgcmVzaGFyZVdhbGxldFdpdGhTcGVuZGVyc1xuICAgICAgICBjb25zdCByZXNoYXJlU3R1YiA9IHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdyZXNoYXJlV2FsbGV0V2l0aFNwZW5kZXJzJykucmVzb2x2ZXMoKTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBvZmNXYWxsZXRzLmJ1bGtVcGRhdGVXYWxsZXRTaGFyZSh7XG4gICAgICAgICAgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiAnc2hhcmUxJywgc3RhdHVzOiAnYWNjZXB0JyB9XSxcbiAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IHRoZSByZXN1bHRcbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChyZXN1bHQsIHtcbiAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogWydzaGFyZTEnXSxcbiAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnM6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBWZXJpZnkgYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCB3YXMgY2FsbGVkXG4gICAgICAgIGJ1bGtVcGRhdGVTdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgICAvLyBWZXJpZnkgcmVzaGFyZVdhbGxldFdpdGhTcGVuZGVycyB3YXMgY2FsbGVkIHdpdGggY29ycmVjdCBwYXJhbWV0ZXJzXG4gICAgICAgIHJlc2hhcmVTdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgcmVzaGFyZVN0dWIuZmlyc3RDYWxsLmFyZ3NbMF0uc2hvdWxkLmVxdWFsKCd3YWxsZXQxJyk7XG4gICAgICAgIHJlc2hhcmVTdHViLmZpcnN0Q2FsbC5hcmdzWzFdLnNob3VsZC5lcXVhbCh3YWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBzaGFyZXMgd2l0aCBubyBrZXljaGFpbiB0byBkZWNyeXB0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG5cbiAgICAgICAgLy8gTW9jayBsaXN0U2hhcmVzVjIgdG8gcmV0dXJuIGEgc2hhcmUgd2l0aCBubyBrZXljaGFpblxuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnc2hhcmUxJyxcbiAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3RpbmcnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ3dhbGxldDEnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWyd2aWV3J10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE1vY2sgYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdFxuICAgICAgICBjb25zdCBidWxrVXBkYXRlU3R1YiA9IHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0JykucmVzb2x2ZXMoe1xuICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMSddLFxuICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbXSxcbiAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldHMuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICBzaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6ICdzaGFyZTEnLCBzdGF0dXM6ICdhY2NlcHQnIH1dLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBWZXJpZnkgdGhlIHJlc3VsdFxuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHJlc3VsdCwge1xuICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMSddLFxuICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbXSxcbiAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFZlcmlmeSBidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0IHdhcyBjYWxsZWQgd2l0aCBjb3JyZWN0IHBhcmFtZXRlcnNcbiAgICAgICAgYnVsa1VwZGF0ZVN0dWIuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICBjb25zdCB1cGRhdGVQYXJhbXMgPSBidWxrVXBkYXRlU3R1Yi5maXJzdENhbGwuYXJnc1swXTtcbiAgICAgICAgdXBkYXRlUGFyYW1zLnNob3VsZC5oYXZlLmxlbmd0aE9mKDEpO1xuXG4gICAgICAgIC8vIFBhcmFtIHNob3VsZCBiZSBmb3Igc2hhcmUxIHdpdGggYWNjZXB0IHN0YXR1cyBhbmQgbm8gYWRkaXRpb25hbCBmaWVsZHNcbiAgICAgICAgdXBkYXRlUGFyYW1zLnNob3VsZC5jb250YWluRGVlcChbXG4gICAgICAgICAge1xuICAgICAgICAgICAgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMScsXG4gICAgICAgICAgICBzdGF0dXM6ICdhY2NlcHQnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIHNoYXJlcyB3aXRoIGtleWNoYWluIHJlcXVpcmluZyBkZWNyeXB0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG4gICAgICAgIGNvbnN0IHBhdGggPSAnbS85OTk5OTkvMS8xJztcblxuICAgICAgICAvLyBDcmVhdGUgdGVzdCBrZXljaGFpbnNcbiAgICAgICAgY29uc3QgZnJvbUtleWNoYWluID0gdXR4b0xpYi5iaXAzMi5mcm9tU2VlZChCdWZmZXIuZnJvbSgnZGVhZGJlZWYwMWRlYWRiZWVmMDFkZWFkYmVlZjAxZGVhZGJlZWYwMScsICdoZXgnKSk7XG4gICAgICAgIGNvbnN0IHRvS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyJywgJ2hleCcpKTtcblxuICAgICAgICBjb25zdCBmcm9tUHViS2V5ID0gZnJvbUtleWNoYWluLnB1YmxpY0tleS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgIGNvbnN0IHRvUHViS2V5ID0gdG9LZXljaGFpbi5kZXJpdmVQYXRoKHBhdGgpLnB1YmxpY0tleS50b1N0cmluZygnaGV4Jyk7XG5cbiAgICAgICAgLy8gQ3JlYXRlIGVuY3J5cHRlZCBwcml2YXRlIGtleVxuICAgICAgICBjb25zdCBvcmlnaW5hbFByaXZLZXkgPSAnb3JpZ2luYWxQcml2YXRlS2V5JztcbiAgICAgICAgY29uc3Qgc2hhcmVkU2VjcmV0ID0gZ2V0U2hhcmVkU2VjcmV0KGZyb21LZXljaGFpbiwgQnVmZmVyLmZyb20odG9QdWJLZXksICdoZXgnKSkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoe1xuICAgICAgICAgIHBhc3N3b3JkOiBzaGFyZWRTZWNyZXQsXG4gICAgICAgICAgaW5wdXQ6IG9yaWdpbmFsUHJpdktleSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gTW9jayBsaXN0U2hhcmVzVjIgdG8gcmV0dXJuIGEgc2hhcmUgd2l0aCBrZXljaGFpblxuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnc2hhcmUxJyxcbiAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3RpbmcnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ3dhbGxldDEnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICAgICAgcHViOiB0b1B1YktleSxcbiAgICAgICAgICAgICAgICB0b1B1YktleTogdG9QdWJLZXksXG4gICAgICAgICAgICAgICAgZnJvbVB1YktleTogZnJvbVB1YktleSxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGVuY3J5cHRlZFBydixcbiAgICAgICAgICAgICAgICBwYXRoOiBwYXRoLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG91dGdvaW5nOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gTW9jayBnZXRFQ0RIS2V5Y2hhaW5cbiAgICAgICAgY29uc3QgbXlFY2RoS2V5Y2hhaW4gPSBhd2FpdCBiaXRnby5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2dldEVDREhLZXljaGFpbicpLnJlc29sdmVzKHtcbiAgICAgICAgICBlbmNyeXB0ZWRYcHJ2OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IG15RWNkaEtleWNoYWluLnhwcnYsIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTZXR1cCBkZWNyeXB0IGFuZCBlbmNyeXB0IHN0dWJzXG4gICAgICAgIGNvbnN0IGRlY3J5cHRTdHViID0gc2lub24uc3R1YihiaXRnbywgJ2RlY3J5cHQnKTtcbiAgICAgICAgZGVjcnlwdFN0dWIub25GaXJzdENhbGwoKS5yZXNvbHZlcyhteUVjZGhLZXljaGFpbi54cHJ2KTsgLy8gRm9yIHNoYXJpbmcga2V5Y2hhaW5cbiAgICAgICAgZGVjcnlwdFN0dWIub25TZWNvbmRDYWxsKCkucmVzb2x2ZXMob3JpZ2luYWxQcml2S2V5KTsgLy8gRm9yIHdhbGxldCBrZXljaGFpblxuXG4gICAgICAgIGNvbnN0IGVuY3J5cHRTdHViID0gc2lub24uc3R1YihiaXRnbywgJ2VuY3J5cHQnKS5yZXNvbHZlcygnbmV3RW5jcnlwdGVkUHJ2Jyk7XG5cbiAgICAgICAgLy8gTW9jayBnZXRTaGFyZWRTZWNyZXRcbiAgICAgICAgc2lub24uc3R1Yihtb2R1bGVCaXRnbywgJ2dldFNoYXJlZFNlY3JldCcpLnJldHVybnMoQnVmZmVyLmZyb20oc2hhcmVkU2VjcmV0KSk7XG5cbiAgICAgICAgLy8gTW9jayBidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0XG4gICAgICAgIGNvbnN0IGJ1bGtVcGRhdGVTdHViID0gc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2J1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3QnKS5yZXNvbHZlcyh7XG4gICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFsnc2hhcmUxJ10sXG4gICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd2FsbGV0cy5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe1xuICAgICAgICAgIHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMScsIHN0YXR1czogJ2FjY2VwdCcgfV0sXG4gICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgbmV3V2FsbGV0UGFzc3BocmFzZTogJ25ld1Bhc3NwaHJhc2UnLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBWZXJpZnkgdGhlIHJlc3VsdFxuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHJlc3VsdCwge1xuICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMSddLFxuICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbXSxcbiAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFZlcmlmeSBidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0IHdhcyBjYWxsZWQgd2l0aCBjb3JyZWN0IHBhcmFtZXRlcnNcbiAgICAgICAgYnVsa1VwZGF0ZVN0dWIuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICBjb25zdCB1cGRhdGVQYXJhbXMgPSBidWxrVXBkYXRlU3R1Yi5maXJzdENhbGwuYXJnc1swXTtcbiAgICAgICAgdXBkYXRlUGFyYW1zLnNob3VsZC5oYXZlLmxlbmd0aE9mKDEpO1xuXG4gICAgICAgIC8vIFBhcmFtIHNob3VsZCBiZSBmb3Igc2hhcmUxIHdpdGggYWNjZXB0IHN0YXR1cyBhbmQgZW5jcnlwdGVkUHJ2XG4gICAgICAgIHVwZGF0ZVBhcmFtcy5zaG91bGQuY29udGFpbkRlZXAoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHdhbGxldFNoYXJlSWQ6ICdzaGFyZTEnLFxuICAgICAgICAgICAgc3RhdHVzOiAnYWNjZXB0JyxcbiAgICAgICAgICAgIGVuY3J5cHRlZFBydjogJ25ld0VuY3J5cHRlZFBydicsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IGVuY3J5cHQgd2FzIGNhbGxlZCB3aXRoIGNvcnJlY3QgcGFyYW1ldGVyc1xuICAgICAgICBlbmNyeXB0U3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIGVuY3J5cHRTdHViLmZpcnN0Q2FsbC5hcmdzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCdwYXNzd29yZCcsICduZXdQYXNzcGhyYXNlJyk7XG4gICAgICAgIGVuY3J5cHRTdHViLmZpcnN0Q2FsbC5hcmdzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCdpbnB1dCcsIG9yaWdpbmFsUHJpdktleSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgcmVqZWN0ZWQgcHJvbWlzZXMgYW5kIGFkZCB0aGVtIHRvIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG5cbiAgICAgICAgLy8gTW9jayBsaXN0U2hhcmVzVjIgdG8gcmV0dXJuIHR3byBzaGFyZXNcbiAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJ3NoYXJlMScsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICd3YWxsZXQxJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICdzaGFyZTInLFxuICAgICAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgICAgIHdhbGxldExhYmVsOiAndGVzdGluZzInLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ3dhbGxldDInLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJ3NoYXJlMycsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nMycsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZHVtbXlGcm9tVXNlcicsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ2R1bW15VG9Vc2VyJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnd2FsbGV0MycsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFN0dWIgcHJvY2Vzc0FjY2VwdFNoYXJlIHRvIHRocm93IGFuIGVycm9yIGZvciBzaGFyZTJcbiAgICAgICAgLy8gVXNpbmcgJ2FzIGFueScgdG8gYnlwYXNzIFR5cGVTY3JpcHQncyBwcml2YXRlIG1ldGhvZCByZXN0cmljdGlvblxuICAgICAgICBjb25zdCBwcm9jZXNzQWNjZXB0U2hhcmVTdHViID0gc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSBhcyBhbnksICdwcm9jZXNzQWNjZXB0U2hhcmUnKTtcbiAgICAgICAgcHJvY2Vzc0FjY2VwdFNoYXJlU3R1YlxuICAgICAgICAgIC53aXRoQXJncygnc2hhcmUxJywgc2lub24ubWF0Y2guYW55LCBzaW5vbi5tYXRjaC5hbnksIHNpbm9uLm1hdGNoLmFueSwgc2lub24ubWF0Y2guYW55KVxuICAgICAgICAgIC5yZXNvbHZlcyhbeyB3YWxsZXRTaGFyZUlkOiAnc2hhcmUxJywgc3RhdHVzOiAnYWNjZXB0JyB9XSk7XG4gICAgICAgIHByb2Nlc3NBY2NlcHRTaGFyZVN0dWJcbiAgICAgICAgICAud2l0aEFyZ3MoJ3NoYXJlMicsIHNpbm9uLm1hdGNoLmFueSwgc2lub24ubWF0Y2guYW55LCBzaW5vbi5tYXRjaC5hbnksIHNpbm9uLm1hdGNoLmFueSlcbiAgICAgICAgICAucmVqZWN0cyhuZXcgRXJyb3IoJ0ZhaWxlZCB0byBwcm9jZXNzIHNoYXJlMicpKTtcbiAgICAgICAgcHJvY2Vzc0FjY2VwdFNoYXJlU3R1YlxuICAgICAgICAgIC53aXRoQXJncygnc2hhcmUzJywgc2lub24ubWF0Y2guYW55LCBzaW5vbi5tYXRjaC5hbnksIHNpbm9uLm1hdGNoLmFueSwgc2lub24ubWF0Y2guYW55KVxuICAgICAgICAgIC5yZXNvbHZlcyhbeyB3YWxsZXRTaGFyZUlkOiAnc2hhcmUzJywgc3RhdHVzOiAnYWNjZXB0JyB9XSk7XG5cbiAgICAgICAgLy8gTW9jayBidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0IHRvIHJldHVybiBhIHJlc3BvbnNlXG4gICAgICAgIGNvbnN0IGJ1bGtVcGRhdGVTdHViID0gc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2J1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3QnKS5yZXNvbHZlcyh7XG4gICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFsnc2hhcmUxJywgJ3NoYXJlMyddLFxuICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbXSxcbiAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sIC8vIEVtcHR5IGFycmF5IHRoYXQgc2hvdWxkIGJlIHBvcHVsYXRlZFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB3YWxsZXRzLmJ1bGtVcGRhdGVXYWxsZXRTaGFyZSh7XG4gICAgICAgICAgc2hhcmVzOiBbXG4gICAgICAgICAgICB7IHdhbGxldFNoYXJlSWQ6ICdzaGFyZTEnLCBzdGF0dXM6ICdhY2NlcHQnIH0sXG4gICAgICAgICAgICB7IHdhbGxldFNoYXJlSWQ6ICdzaGFyZTInLCBzdGF0dXM6ICdhY2NlcHQnIH0sXG4gICAgICAgICAgICB7IHdhbGxldFNoYXJlSWQ6ICdzaGFyZTMnLCBzdGF0dXM6ICdhY2NlcHQnIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IGJ1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3Qgd2FzIGNhbGxlZCB3aXRoIG9ubHkgdGhlIHN1Y2Nlc3NmdWwgc2hhcmVcbiAgICAgICAgYnVsa1VwZGF0ZVN0dWIuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICBjb25zdCB1cGRhdGVQYXJhbXMgPSBidWxrVXBkYXRlU3R1Yi5maXJzdENhbGwuYXJnc1swXTtcbiAgICAgICAgdXBkYXRlUGFyYW1zLnNob3VsZC5oYXZlLmxlbmd0aE9mKDIpO1xuICAgICAgICB1cGRhdGVQYXJhbXNbMF0ud2FsbGV0U2hhcmVJZC5zaG91bGQuZXF1YWwoJ3NoYXJlMScpO1xuICAgICAgICB1cGRhdGVQYXJhbXNbMF0uc3RhdHVzLnNob3VsZC5lcXVhbCgnYWNjZXB0Jyk7XG4gICAgICAgIHVwZGF0ZVBhcmFtc1sxXS53YWxsZXRTaGFyZUlkLnNob3VsZC5lcXVhbCgnc2hhcmUzJyk7XG4gICAgICAgIHVwZGF0ZVBhcmFtc1sxXS5zdGF0dXMuc2hvdWxkLmVxdWFsKCdhY2NlcHQnKTtcblxuICAgICAgICAvLyBWZXJpZnkgdGhlIHJlc3VsdCBjb250YWlucyB0aGUgZXJyb3IgaW5mb3JtYXRpb25cbiAgICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRTaGFyZVVwZGF0ZUVycm9ycycpO1xuICAgICAgICByZXN1bHQud2FsbGV0U2hhcmVVcGRhdGVFcnJvcnMuc2hvdWxkLmJlLmFuLkFycmF5KCk7XG4gICAgICAgIHJlc3VsdC53YWxsZXRTaGFyZVVwZGF0ZUVycm9ycy5zaG91bGQuaGF2ZS5sZW5ndGhPZigxKTtcbiAgICAgICAgcmVzdWx0LndhbGxldFNoYXJlVXBkYXRlRXJyb3JzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRTaGFyZUlkJywgJ3NoYXJlMicpO1xuICAgICAgICByZXN1bHQud2FsbGV0U2hhcmVVcGRhdGVFcnJvcnNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlYXNvbicsICdGYWlsZWQgdG8gcHJvY2VzcyBzaGFyZTInKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGFjY2VwdCBzaGFyZSB3aXRoIHYyLWVuY3J5cHRlZCBFQ0RIIGtleWNoYWluIGFuZCB3YWxsZXQgcHJ2JywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG4gICAgICAgIGNvbnN0IHBhdGggPSAnbS85OTk5OTkvMS8xJztcblxuICAgICAgICBjb25zdCBmcm9tS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAxZGVhZGJlZWYwMWRlYWRiZWVmMDFkZWFkYmVlZjAxJywgJ2hleCcpKTtcbiAgICAgICAgY29uc3QgdG9LZXljaGFpbiA9IHV0eG9MaWIuYmlwMzIuZnJvbVNlZWQoQnVmZmVyLmZyb20oJ2RlYWRiZWVmMDJkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDInLCAnaGV4JykpO1xuICAgICAgICBjb25zdCB0b1B1YktleSA9IHRvS2V5Y2hhaW4uZGVyaXZlUGF0aChwYXRoKS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgICBjb25zdCBmcm9tUHViS2V5ID0gZnJvbUtleWNoYWluLnB1YmxpY0tleS50b1N0cmluZygnaGV4Jyk7XG5cbiAgICAgICAgY29uc3Qgb3JpZ2luYWxQcml2S2V5ID0gJ29yaWdpbmFsUHJpdmF0ZUtleSc7XG4gICAgICAgIGNvbnN0IHNoYXJlZFNlY3JldCA9IGdldFNoYXJlZFNlY3JldChmcm9tS2V5Y2hhaW4sIEJ1ZmZlci5mcm9tKHRvUHViS2V5LCAnaGV4JykpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgICAgY29uc3QgZW5jcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IHBhc3N3b3JkOiBzaGFyZWRTZWNyZXQsIGlucHV0OiBvcmlnaW5hbFByaXZLZXkgfSk7XG5cbiAgICAgICAgLy8gQm90aCB0aGUgRUNESCBrZXljaGFpbiBhbmQgc2hhcmUgcHJ2IGFyZSB2Mi1lbmNyeXB0ZWQgaW4gdGhpcyBzY2VuYXJpb1xuICAgICAgICBjb25zdCB2MkVuY3J5cHRlZFhwcnYgPSBKU09OLnN0cmluZ2lmeSh7IHY6IDIsIGl2OiAnYWFiYmNjJywgY3Q6ICdkZGVlZmYnLCBhZGF0YTogJzAwJyB9KTtcblxuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnc2hhcmUxJyxcbiAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3RpbmcnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ3dhbGxldDEnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICAgIGtleWNoYWluOiB7IHB1YjogdG9QdWJLZXksIHRvUHViS2V5LCBmcm9tUHViS2V5LCBlbmNyeXB0ZWRQcnYsIHBhdGggfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IG15RWNkaEtleWNoYWluID0gYXdhaXQgYml0Z28ua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7IGVuY3J5cHRlZFhwcnY6IHYyRW5jcnlwdGVkWHBydiB9KTtcblxuICAgICAgICAvLyBkZWNyeXB0IGhhbmRsZXMgdjIgdHJhbnNwYXJlbnRseTsgc3R1YiB0byByZXR1cm4gZXhwZWN0ZWQgdmFsdWVzXG4gICAgICAgIGNvbnN0IGRlY3J5cHRBc3luY1N0dWIgPSBzaW5vbi5zdHViKGJpdGdvLCAnZGVjcnlwdCcpO1xuICAgICAgICBkZWNyeXB0QXN5bmNTdHViLm9uRmlyc3RDYWxsKCkucmVzb2x2ZXMobXlFY2RoS2V5Y2hhaW4ueHBydik7IC8vIEVDREgga2V5Y2hhaW5cbiAgICAgICAgZGVjcnlwdEFzeW5jU3R1Yi5vblNlY29uZENhbGwoKS5yZXNvbHZlcyhvcmlnaW5hbFByaXZLZXkpOyAvLyB3YWxsZXQgc2hhcmUgcHJ2XG5cbiAgICAgICAgY29uc3QgZW5jcnlwdFN0dWIgPSBzaW5vbi5zdHViKGJpdGdvLCAnZW5jcnlwdCcpLnJlc29sdmVzKCduZXdFbmNyeXB0ZWRQcnYnKTtcbiAgICAgICAgc2lub24uc3R1Yihtb2R1bGVCaXRnbywgJ2dldFNoYXJlZFNlY3JldCcpLnJldHVybnMoQnVmZmVyLmZyb20oc2hhcmVkU2VjcmV0KSk7XG5cbiAgICAgICAgY29uc3QgYnVsa1VwZGF0ZVN0dWIgPSBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCcpLnJlc29sdmVzKHtcbiAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogWydzaGFyZTEnXSxcbiAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnM6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB3YWxsZXRzLmJ1bGtVcGRhdGVXYWxsZXRTaGFyZSh7XG4gICAgICAgICAgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiAnc2hhcmUxJywgc3RhdHVzOiAnYWNjZXB0JyB9XSxcbiAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBuZXdXYWxsZXRQYXNzcGhyYXNlOiAnbmV3UGFzc3BocmFzZScsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwocmVzdWx0LCB7XG4gICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFsnc2hhcmUxJ10sXG4gICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQm90aCBkZWNyeXB0IGNhbGxzIG11c3QgaGF2ZSBnb25lIHRocm91Z2ggZGVjcnlwdFxuICAgICAgICBhc3NlcnQuZXF1YWwoZGVjcnlwdEFzeW5jU3R1Yi5jYWxsQ291bnQsIDIpO1xuICAgICAgICBidWxrVXBkYXRlU3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIGVuY3J5cHRTdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgZW5jcnlwdFN0dWIuZmlyc3RDYWxsLmFyZ3NbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lucHV0Jywgb3JpZ2luYWxQcml2S2V5KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnY3JlYXRlQnVsa0tleVNoYXJlcyB0ZXN0cycsICgpID0+IHtcbiAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgaWQ6ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEwMDAwMDAwMCcsXG4gICAgICBjb2luOiAndGJ0YycsXG4gICAgICBrZXlzOiBbXG4gICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzUwMDAwMDAwMCcsXG4gICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzYwMDAwMDAwMCcsXG4gICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzcwMDAwMDAwMCcsXG4gICAgICBdLFxuICAgICAgY29pblNwZWNpZmljOiB7fSxcbiAgICAgIG11bHRpc2lnVHlwZTogJ29uY2hhaW4nLFxuICAgICAgdHlwZTogJ2hvdCcsXG4gICAgfTtcbiAgICBjb25zdCB0c29sID0gYml0Z28uY29pbigndHNvbCcpO1xuICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIHRzb2wsIHdhbGxldERhdGEpO1xuICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKS5wZXJzaXN0KCkuZ2V0KCcvYXBpL3YxL2NsaWVudC9jb25zdGFudHMnKS5yZXBseSgyMDAsIHsgdHRsOiAzNjAwLCBjb25zdGFudHM6IHt9IH0pO1xuICAgICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgfSk7XG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gICAgfSk7XG4gICAgYWZ0ZXIoZnVuY3Rpb24gKCkge1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgICAgbm9jay5wZW5kaW5nTW9ja3MoKS5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgIH0pO1xuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzaW5vbi5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIGlmIHNoYXJlT3B0aW9ucyBpcyBlbXB0eScsIGFzeW5jICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHdhbGxldC5jcmVhdGVCdWxrS2V5U2hhcmVzKFtdKTtcbiAgICAgICAgYXNzZXJ0LmZhaWwoJ0V4cGVjdGVkIGVycm9yIG5vdCB0aHJvd24nKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChlcnJvci5tZXNzYWdlLCAnc2hhcmVPcHRpb25zIGNhbm5vdCBiZSBlbXB0eScpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBza2lwIHNoYXJlb3B0aW9uIGlmIGtleWNoYWluIHBhcmFtZXRlcnMgYXJlIG1pc3NpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBwYXJhbXMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICB1c2VyOiAndGVzdHVzZXJAZXhhbXBsZS5jb20nLFxuICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAga2V5Y2hhaW46IHsgcHViOiAncHVia2V5JywgZW5jcnlwdGVkUHJ2OiAnJywgZnJvbVB1YktleTogJycsIHRvUHViS2V5OiAnJywgcGF0aDogJycgfSxcbiAgICAgICAgfSxcbiAgICAgIF07XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHdhbGxldC5jcmVhdGVCdWxrS2V5U2hhcmVzKHBhcmFtcyk7XG4gICAgICAgIGFzc2VydC5mYWlsKCdFeHBlY3RlZCBlcnJvciBub3QgdGhyb3duJyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBTaGFyZW9wdGlvbnMgd2l0aCBpbnZhbGlkIGtleWNoYWlucyBhcmUgc2tpcHBlZFxuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXJyb3IubWVzc2FnZSwgJ3NoYXJlT3B0aW9ucyBjYW5ub3QgYmUgZW1wdHknKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2VuZCB0aGUgY29ycmVjdCBkYXRhIHRvIEJpdEdvIEFQSSBpZiBzaGFyZU9wdGlvbnMgYXJlIHZhbGlkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICBzaGFyZU9wdGlvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB1c2VyOiAndGVzdHVzZXJAZXhhbXBsZS5jb20nLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICAgIHB1YjogJ3B1YmtleScsXG4gICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogJ2VuY3J5cHRlZFBydicsXG4gICAgICAgICAgICAgIGZyb21QdWJLZXk6ICdmcm9tUHViS2V5JyxcbiAgICAgICAgICAgICAgdG9QdWJLZXk6ICd0b1B1YktleScsXG4gICAgICAgICAgICAgIHBhdGg6ICdtLzAvMCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgICAgY29uc3QgcGFyYW1zVG9TZW5kID0gW1xuICAgICAgICB7XG4gICAgICAgICAgdXNlcjogJ3Rlc3R1c2VyQGV4YW1wbGUuY29tJyxcbiAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICBwdWI6ICdwdWJrZXknLFxuICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZW5jcnlwdGVkUHJ2JyxcbiAgICAgICAgICAgIGZyb21QdWJLZXk6ICdmcm9tUHViS2V5JyxcbiAgICAgICAgICAgIHRvUHViS2V5OiAndG9QdWJLZXknLFxuICAgICAgICAgICAgcGF0aDogJ20vMC8wJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgXTtcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyL3dhbGxldC8ke3dhbGxldERhdGEuaWR9L3dhbGxldHNoYXJlc2AsIHBhcmFtcylcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIHNoYXJlczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJ3VzZXJJZCcsXG4gICAgICAgICAgICAgIGNvaW46IHdhbGxldERhdGEuY29pbixcbiAgICAgICAgICAgICAgd2FsbGV0OiB3YWxsZXREYXRhLmlkLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2Zyb21Vc2VySWQnLFxuICAgICAgICAgICAgICB0b1VzZXI6ICd0b1VzZXJJZCcsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3ZpZXcnLCAnc3BlbmQnXSxcbiAgICAgICAgICAgICAga2V5Y2hhaW46IHtcbiAgICAgICAgICAgICAgICBwdWI6ICdkdW1teVB1YicsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZHVtbXlFbmNyeXB0ZWRQcnYnLFxuICAgICAgICAgICAgICAgIGZyb21QdWJLZXk6ICdkdW1teUZyb21QdWJLZXknLFxuICAgICAgICAgICAgICAgIHRvUHViS2V5OiAnZHVtbXlUb1B1YktleScsXG4gICAgICAgICAgICAgICAgcGF0aDogJ2R1bW15UGF0aCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0pO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd2FsbGV0LmNyZWF0ZUJ1bGtLZXlTaGFyZXMocGFyYW1zVG9TZW5kKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQuc2hhcmVzWzBdLmlkLCAndXNlcklkJywgJ1RoZSBzaGFyZSBJRCBzaG91bGQgbWF0Y2gnKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQuc2hhcmVzWzBdLmNvaW4sIHdhbGxldERhdGEuY29pbiwgJ1RoZSBjb2luIHNob3VsZCBtYXRjaCcpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5zaGFyZXNbMF0ud2FsbGV0LCB3YWxsZXREYXRhLmlkLCAnVGhlIHdhbGxldCBJRCBzaG91bGQgbWF0Y2gnKTtcbiAgICAgIGFzc2VydC5vayhyZXN1bHQuc2hhcmVzWzBdLmtleWNoYWluKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQuc2hhcmVzWzBdLmtleWNoYWluLnB1YiwgJ2R1bW15UHViJywgJ1RoZSBrZXljaGFpbiBwdWIgc2hvdWxkIG1hdGNoJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LnNoYXJlc1swXS5wZXJtaXNzaW9ucy5pbmNsdWRlcygndmlldycpLCB0cnVlLCAnVGhlIHBlcm1pc3Npb25zIHNob3VsZCBpbmNsdWRlIFwidmlld1wiJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICAgIHJlc3VsdC5zaGFyZXNbMF0ucGVybWlzc2lvbnMuaW5jbHVkZXMoJ3NwZW5kJyksXG4gICAgICAgIHRydWUsXG4gICAgICAgICdUaGUgcGVybWlzc2lvbnMgc2hvdWxkIGluY2x1ZGUgXCJzcGVuZFwiJ1xuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2NyZWF0ZUJ1bGtXYWxsZXRTaGFyZSB0ZXN0cycsICgpID0+IHtcbiAgICBjb25zdCBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcblxuICAgIGNvbnN0IHdhbGxldERhdGEgPSB7XG4gICAgICBpZDogJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYTAwMDAwMDAwJyxcbiAgICAgIGNvaW46ICd0YnRjJyxcbiAgICAgIGtleXM6IFtcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NTAwMDAwMDAwJyxcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NjAwMDAwMDAwJyxcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NzAwMDAwMDAwJyxcbiAgICAgIF0sXG4gICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgbXVsdGlzaWdUeXBlOiAnb25jaGFpbicsXG4gICAgICB0eXBlOiAnaG90JyxcbiAgICB9O1xuICAgIGNvbnN0IHRzb2wgPSBiaXRnby5jb2luKCd0c29sJyk7XG4gICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgdHNvbCwgd2FsbGV0RGF0YSk7XG4gICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLnBlcnNpc3QoKS5nZXQoJy9hcGkvdjEvY2xpZW50L2NvbnN0YW50cycpLnJlcGx5KDIwMCwgeyB0dGw6IDM2MDAsIGNvbnN0YW50czoge30gfSk7XG4gICAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICB9KTtcblxuICAgIGFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICAgIG5vY2sucGVuZGluZ01vY2tzKCkubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzaW5vbi5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIGlmIG5vIHNoYXJlIG9wdGlvbnMgYXJlIHByb3ZpZGVkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0LmNyZWF0ZUJ1bGtXYWxsZXRTaGFyZSh7IHdhbGxldFBhc3NwaHJhc2U6ICdUZXN0Jywga2V5U2hhcmVPcHRpb25zOiBbXSB9KTtcbiAgICAgICAgYXNzZXJ0LmZhaWwoJ0V4cGVjdGVkIGVycm9yIG5vdCB0aHJvd24nKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChlcnJvci5tZXNzYWdlLCAnTm8gc2hhcmUgb3B0aW9ucyBwcm92aWRlZCcpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBOZWVkc1VzZXJTaWdudXAgZXJyb3IgaWYgcHVia2V5IGlzIG1pc3NpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB1c2VySWQgPSAndXNlckBleGFtcGxlLmNvbSc7XG4gICAgICBjb25zdCBwZXJtaXNzaW9ucyA9IFsndmlldycsICdzcGVuZCddO1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0LmNyZWF0ZUJ1bGtXYWxsZXRTaGFyZSh7XG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ1Rlc3QnLFxuICAgICAgICAgIGtleVNoYXJlT3B0aW9uczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB1c2VySWQ6IHVzZXJJZCxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zLFxuICAgICAgICAgICAgICBwYXRoOiAnbS85OTk5OTkvMS8xJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSBhcyBCdWxrV2FsbGV0U2hhcmVPcHRpb25zKTtcbiAgICAgICAgYXNzZXJ0LmZhaWwoJ0V4cGVjdGVkIGVycm9yIG5vdCB0aHJvd24nKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGFzc2VydC5vayhlcnJvciBpbnN0YW5jZW9mIE5lZWRVc2VyU2lnbnVwRXJyb3IpO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXJyb3IubmFtZSwgJ05lZWRVc2VyU2lnbnVwRXJyb3InKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGVycm9yLm1lc3NhZ2UsIHVzZXJJZCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGlmIHBhdGggaXMgbWlzc2luZycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHVzZXJJZCA9ICd1c2VyQGV4YW1wbGUuY29tJztcbiAgICAgIGNvbnN0IHBlcm1pc3Npb25zID0gWyd2aWV3JywgJ3NwZW5kJ107XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB3YWxsZXQuY3JlYXRlQnVsa1dhbGxldFNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnVGVzdCcsXG4gICAgICAgICAga2V5U2hhcmVPcHRpb25zOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHVzZXJJZDogdXNlcklkLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogcGVybWlzc2lvbnMsXG4gICAgICAgICAgICAgIHB1YktleTogJ20vOTk5OTk5LzEvMScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0gYXMgQnVsa1dhbGxldFNoYXJlT3B0aW9ucyk7XG4gICAgICAgIGFzc2VydC5mYWlsKCdFeHBlY3RlZCBlcnJvciBub3QgdGhyb3duJyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXJyb3IubmFtZSwgJ0Vycm9yJyk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChlcnJvci5tZXNzYWdlLCAnTWlzc2luZyBwYXJhbWV0ZXI6IHBhdGgnKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgTmVlZHNVc2VyU2lnbnVwIGVycm9yIGlmIHB1YmtleSBpcyBlbXB0eSBzdHJpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB1c2VySWQgPSAndXNlckBleGFtcGxlLmNvbSc7XG4gICAgICBjb25zdCBwZXJtaXNzaW9ucyA9IFsndmlldycsICdzcGVuZCddO1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0LmNyZWF0ZUJ1bGtXYWxsZXRTaGFyZSh7XG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ1Rlc3QnLFxuICAgICAgICAgIGtleVNoYXJlT3B0aW9uczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB1c2VySWQ6IHVzZXJJZCxcbiAgICAgICAgICAgICAgcHViS2V5OiAnJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zLFxuICAgICAgICAgICAgICBwYXRoOiAnbS85OTk5OTkvMS8xJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydC5mYWlsKCdFeHBlY3RlZCBlcnJvciBub3QgdGhyb3duJyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBhc3NlcnQub2soZXJyb3IgaW5zdGFuY2VvZiBOZWVkVXNlclNpZ251cEVycm9yKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGVycm9yLm5hbWUsICdOZWVkVXNlclNpZ251cEVycm9yJyk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChlcnJvci5tZXNzYWdlLCB1c2VySWQpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb3JyZWN0bHkgcHJvY2VzcyBzaGFyZSBvcHRpb25zIGFuZCBjYWxsIGNyZWF0ZUJ1bGtLZXlTaGFyZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB1c2VySWQgPSAndXNlckBleGFtcGxlLmNvbSc7XG4gICAgICBjb25zdCBwZXJtaXNzaW9ucyA9IFsndmlldycsICdzcGVuZCddO1xuICAgICAgY29uc3QgcGF0aCA9ICdtLzk5OTk5OS8xLzEnO1xuICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuICAgICAgY29uc3QgcHViID0gJ1pvMWdnelRVS01ZNWJZbkR2VDVtdFZlWnh6ZjJGYUxUYktrbXZHVWhVUWsnO1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLmdldChgL2FwaS92Mi90YnRjL2tleS8ke3dhbGxldC5rZXlJZHMoKVswXX1gKVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgaWQ6IHdhbGxldC5rZXlJZHMoKVswXSxcbiAgICAgICAgICBwdWIsXG4gICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgZW5jcnlwdGVkUHJ2OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2MScsIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge30sXG4gICAgICAgIH0pO1xuICAgICAgY29uc3QgcGFyYW1zOiBCdWxrV2FsbGV0U2hhcmVPcHRpb25zID0ge1xuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICBrZXlTaGFyZU9wdGlvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB1c2VySWQ6IHVzZXJJZCxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBwZXJtaXNzaW9ucyxcbiAgICAgICAgICAgIHB1YktleTogJzAyNzA1YTZkMzNhMjQ1OWZlYjUzN2U3YWJlMzZhYWFkOGMxMTUzMmNkYmZmYTNhMmU0ZTU4ODY4NDY3ZDUxZjUzMicsXG4gICAgICAgICAgICBwYXRoOiBwYXRoLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwcnYxID0gTWF0aC5yYW5kb20oKS50b1N0cmluZygpO1xuICAgICAgY29uc3Qga2V5Y2hhaW5UZXN0OiBPcHRpb25hbEtleWNoYWluRW5jcnlwdGVkS2V5ID0ge1xuICAgICAgICBlbmNyeXB0ZWRQcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogcHJ2MSwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICB9O1xuXG4gICAgICBzaW5vbi5zdHViKHdhbGxldCwgJ2dldEVuY3J5cHRlZFVzZXJLZXljaGFpbicpLnJlc29sdmVzKHtcbiAgICAgICAgZW5jcnlwdGVkUHJ2OiBrZXljaGFpblRlc3QuZW5jcnlwdGVkUHJ2LFxuICAgICAgICBwdWIsXG4gICAgICB9IGFzIEtleWNoYWluV2l0aEVuY3J5cHRlZFBydik7XG5cbiAgICAgIHNpbm9uLnN0dWIobW9kdWxlQml0Z28sICdnZXRTaGFyZWRTZWNyZXQnKS5yZXNvbHZlcygnZmFrZVNoYXJlZFNlY3JldCcpO1xuXG4gICAgICBzaW5vbi5zdHViKHdhbGxldCwgJ2NyZWF0ZUJ1bGtLZXlTaGFyZXMnKS5yZXNvbHZlcyh7XG4gICAgICAgIHNoYXJlczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiB1c2VySWQsXG4gICAgICAgICAgICBjb2luOiB3YWxsZXREYXRhLmNvaW4sXG4gICAgICAgICAgICB3YWxsZXQ6IHdhbGxldERhdGEuaWQsXG4gICAgICAgICAgICBmcm9tVXNlcjogdXNlcklkLFxuICAgICAgICAgICAgdG9Vc2VyOiB1c2VySWQsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWyd2aWV3JywgJ3NwZW5kJ10sXG4gICAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgICBwdWI6ICdkdW1teVB1YicsXG4gICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogJ2R1bW15RW5jcnlwdGVkUHJ2JyxcbiAgICAgICAgICAgICAgZnJvbVB1YktleTogJ2R1bW15RnJvbVB1YktleScsXG4gICAgICAgICAgICAgIHRvUHViS2V5OiAnZHVtbXlUb1B1YktleScsXG4gICAgICAgICAgICAgIHBhdGg6ICdkdW1teVBhdGgnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldC5jcmVhdGVCdWxrV2FsbGV0U2hhcmUocGFyYW1zKTtcblxuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChyZXN1bHQsIHtcbiAgICAgICAgc2hhcmVzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6IHVzZXJJZCxcbiAgICAgICAgICAgIGNvaW46IHdhbGxldERhdGEuY29pbixcbiAgICAgICAgICAgIHdhbGxldDogd2FsbGV0RGF0YS5pZCxcbiAgICAgICAgICAgIGZyb21Vc2VyOiB1c2VySWQsXG4gICAgICAgICAgICB0b1VzZXI6IHVzZXJJZCxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3ZpZXcnLCAnc3BlbmQnXSxcbiAgICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICAgIHB1YjogJ2R1bW15UHViJyxcbiAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZHVtbXlFbmNyeXB0ZWRQcnYnLFxuICAgICAgICAgICAgICBmcm9tUHViS2V5OiAnZHVtbXlGcm9tUHViS2V5JyxcbiAgICAgICAgICAgICAgdG9QdWJLZXk6ICdkdW1teVRvUHViS2V5JyxcbiAgICAgICAgICAgICAgcGF0aDogJ2R1bW15UGF0aCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgaW4gcHJvY2Vzc2luZyBzaGFyZSBvcHRpb25zIHdoZW4gd2FsbGV0IHBhc3N3b3JkIGlzIGluY29ycmVjdCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHVzZXJJZCA9ICd1c2VyQGV4YW1wbGUuY29tJztcbiAgICAgIGNvbnN0IHBlcm1pc3Npb25zID0gWyd2aWV3JywgJ3NwZW5kJ107XG4gICAgICBjb25zdCBwYXRoID0gJ20vOTk5OTk5LzEvMSc7XG4gICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG4gICAgICBjb25zdCBwdWIgPSAnWm8xZ2d6VFVLTVk1YlluRHZUNW10VmVaeHpmMkZhTFRiS2ttdkdVaFVRayc7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KGAvYXBpL3YyL3RidGMva2V5LyR7d2FsbGV0LmtleUlkcygpWzBdfWApXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBpZDogd2FsbGV0LmtleUlkcygpWzBdLFxuICAgICAgICAgIHB1YixcbiAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogJ3hwcnYxJywgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7fSxcbiAgICAgICAgfSk7XG4gICAgICBjb25zdCBwYXJhbXM6IEJ1bGtXYWxsZXRTaGFyZU9wdGlvbnMgPSB7XG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICd3cm9uZyBwYXNzd29yZCcsXG4gICAgICAgIGtleVNoYXJlT3B0aW9uczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVzZXJJZDogdXNlcklkLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zLFxuICAgICAgICAgICAgcHViS2V5OiAnMDI3MDVhNmQzM2EyNDU5ZmViNTM3ZTdhYmUzNmFhYWQ4YzExNTMyY2RiZmZhM2EyZTRlNTg4Njg0NjdkNTFmNTMyJyxcbiAgICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHBydjEgPSBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKCk7XG4gICAgICBjb25zdCBrZXljaGFpblRlc3Q6IE9wdGlvbmFsS2V5Y2hhaW5FbmNyeXB0ZWRLZXkgPSB7XG4gICAgICAgIGVuY3J5cHRlZFBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBwcnYxLCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgIH07XG5cbiAgICAgIHNpbm9uLnN0dWIod2FsbGV0LCAnZ2V0RW5jcnlwdGVkVXNlcktleWNoYWluJykucmVzb2x2ZXMoe1xuICAgICAgICBlbmNyeXB0ZWRQcnY6IGtleWNoYWluVGVzdC5lbmNyeXB0ZWRQcnYsXG4gICAgICAgIHB1YixcbiAgICAgIH0gYXMgS2V5Y2hhaW5XaXRoRW5jcnlwdGVkUHJ2KTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0LmNyZWF0ZUJ1bGtXYWxsZXRTaGFyZShwYXJhbXMpO1xuICAgICAgICBhc3NlcnQuZmFpbCgnRXhwZWN0ZWQgZXJyb3Igbm90IHRocm93bicpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgYXNzZXJ0Lm9rKGVycm9yIGluc3RhbmNlb2YgSW5jb3JyZWN0UGFzc3dvcmRFcnJvcik7XG4gICAgICAgIGFzc2VydC5lcXVhbChlcnJvci5tZXNzYWdlLCAnUGFzc3dvcmQgc2hhcmVkIGlzIGluY29ycmVjdCBmb3IgdGhpcyB3YWxsZXQnKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmV0Y2gga2V5Y2hhaW4gb25seSBPTkNFIHdoZW4gc2hhcmluZyB3aXRoIG11bHRpcGxlIHVzZXJzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuICAgICAgY29uc3QgcHViID0gJ1pvMWdnelRVS01ZNWJZbkR2VDVtdFZlWnh6ZjJGYUxUYktrbXZHVWhVUWsnO1xuICAgICAgY29uc3QgcHJ2MSA9ICd4cHJ2MSc7XG5cbiAgICAgIC8vIENyZWF0ZSBtdWx0aXBsZSB1c2VycyB0byBzaGFyZSB3aXRoXG4gICAgICBjb25zdCB1c2VycyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIHVzZXJJZDogJ3VzZXIxQGV4YW1wbGUuY29tJyxcbiAgICAgICAgICBwZXJtaXNzaW9uczogWyd2aWV3JywgJ3NwZW5kJ10sXG4gICAgICAgICAgcHViS2V5OiAnMDI3MDVhNmQzM2EyNDU5ZmViNTM3ZTdhYmUzNmFhYWQ4YzExNTMyY2RiZmZhM2EyZTRlNTg4Njg0NjdkNTFmNTMyJyxcbiAgICAgICAgICBwYXRoOiAnbS85OTk5OTkvMS8xJyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHVzZXJJZDogJ3VzZXIyQGV4YW1wbGUuY29tJyxcbiAgICAgICAgICBwZXJtaXNzaW9uczogWyd2aWV3JywgJ3NwZW5kJ10sXG4gICAgICAgICAgcHViS2V5OiAnMDM3MDVhNmQzM2EyNDU5ZmViNTM3ZTdhYmUzNmFhYWQ4YzExNTMyY2RiZmZhM2EyZTRlNTg4Njg0NjdkNTFmNTMzJyxcbiAgICAgICAgICBwYXRoOiAnbS85OTk5OTkvMS8yJyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHVzZXJJZDogJ3VzZXIzQGV4YW1wbGUuY29tJyxcbiAgICAgICAgICBwZXJtaXNzaW9uczogWyd2aWV3JywgJ3NwZW5kJ10sXG4gICAgICAgICAgcHViS2V5OiAnMDI4MTVhNmQzM2EyNDU5ZmViNTM3ZTdhYmUzNmFhYWQ4YzExNTMyY2RiZmZhM2EyZTRlNTg4Njg0NjdkNTFmNTM0JyxcbiAgICAgICAgICBwYXRoOiAnbS85OTk5OTkvMS8zJyxcbiAgICAgICAgfSxcbiAgICAgIF07XG5cbiAgICAgIGNvbnN0IHBhcmFtczogQnVsa1dhbGxldFNoYXJlT3B0aW9ucyA9IHtcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAga2V5U2hhcmVPcHRpb25zOiB1c2VycyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGdldERlY3J5cHRlZEtleWNoYWluU3R1YiA9IHNpbm9uLnN0dWIod2FsbGV0LCAnZ2V0RGVjcnlwdGVkS2V5Y2hhaW5Gb3JTaGFyaW5nJykucmVzb2x2ZXMoe1xuICAgICAgICBwcnY6IHBydjEsXG4gICAgICAgIHB1YixcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBlbmNyeXB0UHJ2Rm9yVXNlclN0dWIgPSBzaW5vblxuICAgICAgICAuc3R1Yih3YWxsZXQsICdlbmNyeXB0UHJ2Rm9yVXNlcicpXG4gICAgICAgIC5jYWxsc0Zha2UoYXN5bmMgKHBydiwgcHViS2V5LCB1c2VyUHViS2V5LCBwYXRoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHB1YjogcHViS2V5LFxuICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZHVtbXlFbmNyeXB0ZWRQcnYnLFxuICAgICAgICAgICAgZnJvbVB1YktleTogJ2R1bW15RnJvbVB1YktleScsXG4gICAgICAgICAgICB0b1B1YktleTogdXNlclB1YktleSxcbiAgICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG5cbiAgICAgIHNpbm9uLnN0dWIod2FsbGV0LCAnY3JlYXRlQnVsa0tleVNoYXJlcycpLnJlc29sdmVzKHtcbiAgICAgICAgc2hhcmVzOiB1c2Vycy5tYXAoKHVzZXIpID0+ICh7XG4gICAgICAgICAgaWQ6IHVzZXIudXNlcklkLFxuICAgICAgICAgIGNvaW46IHdhbGxldERhdGEuY29pbixcbiAgICAgICAgICB3YWxsZXQ6IHdhbGxldERhdGEuaWQsXG4gICAgICAgICAgZnJvbVVzZXI6ICdmcm9tVXNlcicsXG4gICAgICAgICAgdG9Vc2VyOiB1c2VyLnVzZXJJZCxcbiAgICAgICAgICBwZXJtaXNzaW9uczogdXNlci5wZXJtaXNzaW9ucyxcbiAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgcHViOiAnZHVtbXlQdWInLFxuICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZHVtbXlFbmNyeXB0ZWRQcnYnLFxuICAgICAgICAgICAgZnJvbVB1YktleTogJ2R1bW15RnJvbVB1YktleScsXG4gICAgICAgICAgICB0b1B1YktleTogdXNlci5wdWJLZXksXG4gICAgICAgICAgICBwYXRoOiB1c2VyLnBhdGgsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSkpLFxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IHdhbGxldC5jcmVhdGVCdWxrV2FsbGV0U2hhcmUocGFyYW1zKTtcblxuICAgICAgLy8gVmVyaWZ5IGtleWNoYWluIGlzIGZldGNoZWQgb25seSBPTkNFLCBub3Qgb25jZSBwZXIgdXNlclxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKFxuICAgICAgICBnZXREZWNyeXB0ZWRLZXljaGFpblN0dWIuY2FsbENvdW50LFxuICAgICAgICAxLFxuICAgICAgICAnZ2V0RGVjcnlwdGVkS2V5Y2hhaW5Gb3JTaGFyaW5nIHNob3VsZCBiZSBjYWxsZWQgZXhhY3RseSBvbmNlLCBub3Qgb25jZSBwZXIgdXNlcidcbiAgICAgICk7XG5cbiAgICAgIC8vIFZlcmlmeSBlbmNyeXB0aW9uIGhhcHBlbnMgZm9yIEVBQ0ggdXNlciAob25jZSBwZXIgdXNlcilcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAgICAgZW5jcnlwdFBydkZvclVzZXJTdHViLmNhbGxDb3VudCxcbiAgICAgICAgdXNlcnMubGVuZ3RoLFxuICAgICAgICBgZW5jcnlwdFBydkZvclVzZXIgc2hvdWxkIGJlIGNhbGxlZCBvbmNlIHBlciB1c2VyICgke3VzZXJzLmxlbmd0aH0gdGltZXMpYFxuICAgICAgKTtcblxuICAgICAgLy8gVmVyaWZ5IGVhY2ggY2FsbCBoYWQgdGhlIGNvcnJlY3QgdXNlcidzIHB1YktleSBhbmQgcGF0aFxuICAgICAgdXNlcnMuZm9yRWFjaCgodXNlciwgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3QgY2FsbCA9IGVuY3J5cHRQcnZGb3JVc2VyU3R1Yi5nZXRDYWxsKGluZGV4KTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGNhbGwuYXJnc1swXSwgcHJ2MSwgJ1Nob3VsZCB1c2UgdGhlIHNhbWUgZGVjcnlwdGVkIHByaXZhdGUga2V5IGZvciBhbGwgdXNlcnMnKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGNhbGwuYXJnc1sxXSwgcHViLCAnU2hvdWxkIHVzZSB0aGUgc2FtZSBwdWJsaWMga2V5IGZvciBhbGwgdXNlcnMnKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGNhbGwuYXJnc1syXSwgdXNlci5wdWJLZXksIGBTaG91bGQgdXNlIHVzZXIke2luZGV4ICsgMX0ncyBwdWJsaWMga2V5YCk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChjYWxsLmFyZ3NbM10sIHVzZXIucGF0aCwgYFNob3VsZCB1c2UgdXNlciR7aW5kZXggKyAxfSdzIHBhdGhgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZG93bmxvYWRLZXljYXJkJywgKCkgPT4ge1xuICAgIGNvbnN0IGxvY2FsQml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R28sIHsgZW52OiAnbW9jaycgfSk7XG4gICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgIGlkOiAnNWIzNDI1MmYxYmYzNDk5MzBlMzQwMjBhMDAwMDAwMDInLFxuICAgICAgY29pbjogJ3RidGMnLFxuICAgICAga2V5czogW1xuICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc1MDAwMDAwMDAnLFxuICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc2MDAwMDAwMDAnLFxuICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc3MDAwMDAwMDAnLFxuICAgICAgXSxcbiAgICAgIGNvaW5TcGVjaWZpYzoge30sXG4gICAgICBtdWx0aXNpZ1R5cGU6ICdvbmNoYWluJyxcbiAgICAgIHR5cGU6ICdob3QnLFxuICAgIH07XG4gICAgY29uc3QgdGJ0YyA9IGxvY2FsQml0Z28uY29pbigndGJ0YycpO1xuICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQobG9jYWxCaXRnbywgdGJ0Yywgd2FsbGV0RGF0YSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gY2FsbGVkIGluIE5vZGUuanMgKG5vIGJyb3dzZXIgd2luZG93KScsIGFzeW5jICgpID0+IHtcbiAgICAgIC8vIEluIE5vZGUuanMsIGFjY2Vzc2luZyBgd2luZG93YCB0aHJvd3MgUmVmZXJlbmNlRXJyb3I7IHRoZSBtZXRob2QgcmVqZWN0cy5cbiAgICAgIGF3YWl0IHdhbGxldC5kb3dubG9hZEtleWNhcmQoKS5zaG91bGQuYmUucmVqZWN0ZWQoKTtcbiAgICB9KTtcblxuICAgIGl0KCdkb3dubG9hZEtleWNhcmQgKHN5bmMpIHNob3VsZCB0aHJvdyB3aGVuIGNhbGxlZCBpbiBOb2RlLmpzIChubyBicm93c2VyIHdpbmRvdyknLCAoKSA9PiB7XG4gICAgICBzaG91bGQudGhyb3dzKCgpID0+IHdhbGxldC5kb3dubG9hZEtleWNhcmQoKSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdlbmNyeXB0UHJ2Rm9yVXNlcicsICgpID0+IHtcbiAgICBjb25zdCBsb2NhbEJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ21vY2snIH0pO1xuICAgIGNvbnN0IHdhbGxldERhdGEgPSB7XG4gICAgICBpZDogJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYTAwMDAwMDAxJyxcbiAgICAgIGNvaW46ICd0YnRjJyxcbiAgICAgIGtleXM6IFtcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NTAwMDAwMDAwJyxcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NjAwMDAwMDAwJyxcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NzAwMDAwMDAwJyxcbiAgICAgIF0sXG4gICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgbXVsdGlzaWdUeXBlOiAnb25jaGFpbicsXG4gICAgICB0eXBlOiAnaG90JyxcbiAgICB9O1xuICAgIGNvbnN0IHRidGMgPSBsb2NhbEJpdGdvLmNvaW4oJ3RidGMnKTtcbiAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGxvY2FsQml0Z28sIHRidGMsIHdhbGxldERhdGEpO1xuXG4gICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLnBlcnNpc3QoKS5nZXQoJy9hcGkvdjEvY2xpZW50L2NvbnN0YW50cycpLnJlcGx5KDIwMCwgeyB0dGw6IDM2MDAsIGNvbnN0YW50czoge30gfSk7XG4gICAgICBsb2NhbEJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZW5jcnlwdCBwcnYgZm9yIHVzZXIgYW5kIHJldHVybiB0aGUgY29ycmVjdCBvdXRwdXQgc2hhcGUnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBkZWNyeXB0ZWRQcnYgPVxuICAgICAgICAneHBydjlzMjFaclFIMTQzSzJmSjkxUzRCUnN1cGNZckU2bW1ZOTZmY1g1SGtob1Rycndtd2pkMTZDbjg3Y1dpbkpqQnlyZnBvamp4N2V6c0pMeDdUQUtMVDhtOGhNNUtheDlZY294bkJlSlozdDJrJztcbiAgICAgIGNvbnN0IHB1YiA9XG4gICAgICAgICd4cHViNjYxTXlNd0FxUmJjRjlOYzdUYkJvMXJaQWFnaVdFVlBXS2JES1RoTkc4enFqazc2SEFLTGthU2JUbjZkSzJkUVBmdUQ3eGppY3hDWlZXdmo2N2ZQNW5ROVc3UVVSbW9NVkFYOG02alpzR3AnO1xuICAgICAgLy8gQSB2YWxpZCAzMy1ieXRlIGNvbXByZXNzZWQgRUMgcG9pbnQgb24gc2VjcDI1NmsxXG4gICAgICBjb25zdCB1c2VyUHVia2V5ID0gJzAyNzliZTY2N2VmOWRjYmJhYzU1YTA2Mjk1Y2U4NzBiMDcwMjliZmNkYjJkY2UyOGQ5NTlmMjgxNWIxNmY4MTc5OCc7XG4gICAgICBjb25zdCBwYXRoID0gJ20vOTk5OTk5LzAvMSc7XG5cbiAgICAgIHNpbm9uLnN0dWIobG9jYWxCaXRnbywgJ2VuY3J5cHQnKS5yZXNvbHZlcygnZW5jcnlwdGVkUHJ2Rm9yVXNlcicpO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB3YWxsZXQuZW5jcnlwdFBydkZvclVzZXIoZGVjcnlwdGVkUHJ2LCBwdWIsIHVzZXJQdWJrZXksIHBhdGgpO1xuXG4gICAgICByZXN1bHQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3B1YicsIHB1Yik7XG4gICAgICByZXN1bHQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2VuY3J5cHRlZFBydicsICdlbmNyeXB0ZWRQcnZGb3JVc2VyJyk7XG4gICAgICByZXN1bHQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Zyb21QdWJLZXknKS53aGljaC5pcy5hLlN0cmluZygpO1xuICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0b1B1YktleScsIHVzZXJQdWJrZXkpO1xuICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLnByb3BlcnR5KCdwYXRoJywgcGF0aCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdMaXN0IFdhbGxldHM6JywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgbGlzdCB3YWxsZXRzIHdpdGggc2tpcFJlY2VpdmVBZGRyZXNzID0gdHJ1ZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ21vY2snIH0pO1xuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0YnRjJyk7XG4gICAgICBjb25zdCB3YWxsZXRzID0gYmFzZWNvaW4ud2FsbGV0cygpO1xuICAgICAgY29uc3QgYmdVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzW2JpdGdvLmdldEVudigpXS51cmk7XG5cbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoJy9hcGkvdjIvdGJ0Yy93YWxsZXQnKVxuICAgICAgICAucXVlcnkoeyBza2lwUmVjZWl2ZUFkZHJlc3M6IHRydWUgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIHdhbGxldHM6IFtcbiAgICAgICAgICAgIHsgaWQ6ICd3YWxsZXQxJywgbGFiZWw6ICdUZXN0IFdhbGxldCAxJyB9LFxuICAgICAgICAgICAgeyBpZDogJ3dhbGxldDInLCBsYWJlbDogJ1Rlc3QgV2FsbGV0IDInIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldHMubGlzdCh7IHNraXBSZWNlaXZlQWRkcmVzczogdHJ1ZSB9KTtcbiAgICAgIHJlc3VsdC53YWxsZXRzLnNob3VsZC5oYXZlLmxlbmd0aCgyKTtcbiAgICAgIHNob3VsZC5ub3QuZXhpc3QocmVzdWx0LndhbGxldHNbMF0ucmVjZWl2ZUFkZHJlc3MoKSk7XG4gICAgICBzaG91bGQubm90LmV4aXN0KHJlc3VsdC53YWxsZXRzWzFdLnJlY2VpdmVBZGRyZXNzKCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBsaXN0IHdhbGxldHMgd2l0aG91dCBza2lwUmVjZWl2ZUFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndGJ0YycpO1xuICAgICAgY29uc3Qgd2FsbGV0cyA9IGJhc2Vjb2luLndhbGxldHMoKTtcbiAgICAgIGNvbnN0IGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpL3YyL3RidGMvd2FsbGV0JylcbiAgICAgICAgLnF1ZXJ5KHt9KVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgd2FsbGV0czogW1xuICAgICAgICAgICAgeyBpZDogJ3dhbGxldDEnLCBsYWJlbDogJ1Rlc3QgV2FsbGV0IDEnLCByZWNlaXZlQWRkcmVzczogeyBhZGRyZXNzOiAnYWRkcmVzczEnIH0gfSxcbiAgICAgICAgICAgIHsgaWQ6ICd3YWxsZXQyJywgbGFiZWw6ICdUZXN0IFdhbGxldCAyJywgcmVjZWl2ZUFkZHJlc3M6IHsgYWRkcmVzczogJ2FkZHJlc3MyJyB9IH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldHMubGlzdCgpO1xuICAgICAgcmVzdWx0LndhbGxldHMuc2hvdWxkLmhhdmUubGVuZ3RoKDIpO1xuICAgICAgc2hvdWxkLmV4aXN0KHJlc3VsdC53YWxsZXRzWzBdLnJlY2VpdmVBZGRyZXNzKCkpO1xuICAgICAgc2hvdWxkLmV4aXN0KHJlc3VsdC53YWxsZXRzWzFdLnJlY2VpdmVBZGRyZXNzKCkpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19