PHP WebShell

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

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

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
const _ = require("lodash");
const nock = require("nock");
const openpgp = require("openpgp");
const should = require("should");
const sinon = require("sinon");
const sdk_test_1 = require("@bitgo/sdk-test");
const src_1 = require("../../../../../src");
const sdk_core_1 = require("@bitgo/sdk-core");
const sdk_lib_mpc_1 = require("@bitgo/sdk-lib-mpc");
const ecdsaFixtures_1 = require("../../../fixtures/tss/ecdsaFixtures");
const common_1 = require("./common");
const helpers_1 = require("../../tss/helpers");
const utxo_lib_1 = require("@bitgo/utxo-lib");
const ecdsaNtilde_1 = require("./mocks/ecdsaNtilde");
const sdk_opensslbytes_1 = require("@bitgo/sdk-opensslbytes");
const openSSLBytes = (0, sdk_opensslbytes_1.loadWebAssembly)().buffer;
const createKeccakHash = require('keccak');
const encryptNShare = sdk_core_1.ECDSAMethods.encryptNShare;
openpgp.config.rejectCurves = new Set();
describe('TSS Ecdsa Utils:', async function () {
    const coinName = 'hteth';
    const reqId = new sdk_core_1.RequestTracer();
    const walletId = '5b34252f1bf349930e34020a00000000';
    const enterpriseId = '6449153a6f6bc20006d66771cdbe15d3';
    const enterpriseData = { id: enterpriseId, name: 'Test Enterprise' };
    let sandbox;
    let MPC;
    let bgUrl;
    let tssUtils;
    let wallet;
    let bitgo;
    let baseCoin;
    let bitgoKeyShare;
    let userKeyShare;
    let backupKeyShare;
    let bitgoPublicKey;
    let userGpgKey;
    let userLocalBackupGpgKey;
    let bitGoGPGKeyPair;
    let nockedBitGoKeychain;
    let nockedUserKeychain;
    beforeEach(async function () {
        sandbox = sinon.createSandbox();
    });
    afterEach(function () {
        sandbox.restore();
    });
    before(async function () {
        nock.cleanAll();
        MPC = new sdk_core_1.Ecdsa();
        userKeyShare = ecdsaFixtures_1.keyShares.userKeyShare;
        backupKeyShare = ecdsaFixtures_1.keyShares.backupKeyShare;
        bitgoKeyShare = ecdsaFixtures_1.keyShares.bitgoKeyShare;
        const gpgKeyPromises = [
            openpgp.generateKey({
                userIDs: [
                    {
                        name: 'test',
                        email: 'test@test.com',
                    },
                ],
                curve: 'secp256k1',
            }),
            openpgp.generateKey({
                userIDs: [
                    {
                        name: 'backup',
                        email: 'backup@test.com',
                    },
                ],
                curve: 'secp256k1',
            }),
            openpgp.generateKey({
                userIDs: [
                    {
                        name: 'bitgo',
                        email: 'bitgo@test.com',
                    },
                ],
                curve: 'secp256k1',
            }),
        ];
        [userGpgKey, userLocalBackupGpgKey, bitGoGPGKeyPair] = await Promise.all(gpgKeyPromises);
        bitgoPublicKey = await openpgp.readKey({ armoredKey: bitGoGPGKeyPair.publicKey });
        const constants = {
            mpc: {
                bitgoPublicKey: bitGoGPGKeyPair.publicKey,
            },
        };
        bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
        bitgo.initializeTestVars();
        baseCoin = bitgo.coin(coinName);
        bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
        // TODO(WP-346): sdk-test mocks conflict so we can't use persist
        nock(bgUrl).get('/api/v1/client/constants').times(16).reply(200, { ttl: 3600, constants });
        const nockPromises = [
            nockBitgoKeychain({
                coin: coinName,
                userKeyShare,
                backupKeyShare,
                bitgoKeyShare,
                userGpgKey,
                userLocalBackupGpgKey,
                bitgoGpgKey: bitGoGPGKeyPair,
            }),
            nockKeychain({ coin: coinName, keyChain: { id: '1', pub: '', type: 'tss' }, source: 'user' }),
            nockKeychain({ coin: coinName, keyChain: { id: '2', pub: '', type: 'tss' }, source: 'backup' }),
        ];
        [nockedBitGoKeychain, nockedUserKeychain] = await Promise.all(nockPromises);
        const walletData = {
            id: walletId,
            enterprise: enterpriseId,
            coin: coinName,
            coinSpecific: {},
            multisigType: 'tss',
        };
        wallet = new sdk_core_1.Wallet(bitgo, baseCoin, walletData);
        tssUtils = new sdk_core_1.ECDSAUtils.EcdsaUtils(bitgo, baseCoin, wallet);
    });
    after(function () {
        nock.cleanAll();
    });
    describe('TSS key chains', async function () {
        it('should create backup key share held by BitGo', async function () {
            const enterpriseId = 'enterprise id';
            const expectedKeyShare = await nockCreateBitgoHeldBackupKeyShare(coinName, enterpriseId, userGpgKey, backupKeyShare, bitGoGPGKeyPair);
            const result = await tssUtils.createBitgoHeldBackupKeyShare(userGpgKey, enterpriseId);
            result.should.eql(expectedKeyShare);
        });
        it('should finalize backup key share held by BitGo', async function () {
            const commonKeychain = '4428';
            const originalKeyShare = await createIncompleteBitgoHeldBackupKeyShare(userGpgKey, backupKeyShare, bitGoGPGKeyPair);
            const expectedFinalKeyShare = await nockFinalizeBitgoHeldBackupKeyShare(coinName, originalKeyShare, commonKeychain, userKeyShare, bitGoGPGKeyPair, nockedBitGoKeychain);
            const result = await tssUtils.finalizeBitgoHeldBackupKeyShare(originalKeyShare.id, commonKeychain, userKeyShare, nockedBitGoKeychain, userGpgKey, bitgoPublicKey);
            result.should.eql(expectedFinalKeyShare);
        });
        it('should get the respective backup key shares based on provider', async function () {
            const enterpriseId = 'enterprise id';
            await nockCreateBitgoHeldBackupKeyShare(coinName, enterpriseId, userGpgKey, backupKeyShare, bitGoGPGKeyPair);
            const backupKeyShares = await tssUtils.createBackupKeyShares();
            should.exist(backupKeyShares.userHeldKeyShare);
            should.not.exist(backupKeyShares.bitGoHeldKeyShares);
        });
        it('should get the correct bitgo gpg key based on coin and feature flags', async function () {
            const nitroGPGKeypair = await openpgp.generateKey({
                userIDs: [
                    {
                        name: 'bitgo nitro',
                        email: 'bitgo@test.com',
                    },
                ],
            });
            const nockGPGKey = await nockGetBitgoPublicKeyBasedOnFeatureFlags(coinName, 'enterprise_id', nitroGPGKeypair);
            const bitgoGpgPublicKey = await tssUtils.getBitgoGpgPubkeyBasedOnFeatureFlags('enterprise_id');
            should.equal(nockGPGKey.publicKey, bitgoGpgPublicKey.armor());
        });
        it('getBackupEncryptedNShare should get valid encrypted n shares based on provider', async function () {
            const bitgoGpgKeyPubKey = await tssUtils.getBitgoPublicGpgKey();
            // Backup key held by user
            const backupShareHolderNew = {
                userHeldKeyShare: backupKeyShare,
            };
            const backupToBitgoEncryptedNShare = await tssUtils.getBackupEncryptedNShare(backupShareHolderNew, 3, bitgoGpgKeyPubKey.armor(), userGpgKey);
            const encryptedNShare = await encryptNShare(backupKeyShare, 3, bitgoGpgKeyPubKey.armor(), userGpgKey);
            // cant verify the encrypted shares, since they will be encrypted with diff. values
            should.equal(backupToBitgoEncryptedNShare.publicShare, encryptedNShare.publicShare);
        });
        it('should generate TSS key chains', async function () {
            const backupShareHolder = {
                userHeldKeyShare: backupKeyShare,
            };
            const backupGpgKey = userLocalBackupGpgKey;
            const bitgoKeychain = await tssUtils.createBitgoKeychain({
                userGpgKey,
                backupGpgKey,
                userKeyShare,
                backupKeyShare: backupShareHolder,
                bitgoPublicGpgKey: bitgoPublicKey,
            });
            const usersKeyChainPromises = [
                tssUtils.createParticipantKeychain(userGpgKey, userLocalBackupGpgKey, bitgoPublicKey, 1, userKeyShare, backupKeyShare, bitgoKeychain, 'passphrase'),
                tssUtils.createParticipantKeychain(userGpgKey, userLocalBackupGpgKey, bitgoPublicKey, 2, userKeyShare, backupKeyShare, bitgoKeychain, 'passphrase'),
            ];
            const [userKeychain, backupKeychain] = await Promise.all(usersKeyChainPromises);
            bitgoKeychain.should.deepEqual(nockedBitGoKeychain);
            userKeychain.should.deepEqual(nockedUserKeychain);
            // unencrypted `prv` property should exist on backup keychain
            const keyChainPrv = JSON.parse(backupKeychain.prv ?? '');
            _.isEqual(keyChainPrv.pShare, backupKeyShare.pShare).should.be.true();
            _.isEqual(keyChainPrv.bitgoNShare, bitgoKeyShare.nShares[2]).should.be.true();
            _.isEqual(keyChainPrv.userNShare, userKeyShare.nShares[2]).should.be.true();
            should.exist(backupKeychain.encryptedPrv);
        });
        it('should generate TSS key chains with optional params', async function () {
            const enterprise = 'enterprise_id';
            const backupShareHolder = {
                userHeldKeyShare: backupKeyShare,
            };
            const backupGpgKey = userLocalBackupGpgKey;
            const bitgoKeychain = await tssUtils.createBitgoKeychain({
                userGpgKey,
                backupGpgKey,
                userKeyShare,
                backupKeyShare: backupShareHolder,
                enterprise,
                bitgoPublicGpgKey: bitgoPublicKey,
            });
            const usersKeyChainPromises = [
                tssUtils.createParticipantKeychain(userGpgKey, userLocalBackupGpgKey, bitgoPublicKey, 1, userKeyShare, backupKeyShare, bitgoKeychain, 'passphrase', 'originalPasscodeEncryptionCode'),
                tssUtils.createParticipantKeychain(userGpgKey, userLocalBackupGpgKey, bitgoPublicKey, 2, userKeyShare, backupKeyShare, bitgoKeychain, 'passphrase'),
            ];
            const [userKeychain, backupKeychain] = await Promise.all(usersKeyChainPromises);
            bitgoKeychain.should.deepEqual(nockedBitGoKeychain);
            userKeychain.should.deepEqual(nockedUserKeychain);
            // unencrypted `prv` property should exist on backup keychain
            const keyChainPrv = JSON.parse(backupKeychain.prv ?? '');
            _.isEqual(keyChainPrv.pShare, backupKeyShare.pShare).should.be.true();
            _.isEqual(keyChainPrv.bitgoNShare, bitgoKeyShare.nShares[2]).should.be.true();
            _.isEqual(keyChainPrv.userNShare, userKeyShare.nShares[2]).should.be.true();
            should.exist(backupKeychain.encryptedPrv);
        });
        it('should fail to generate TSS key chains', async function () {
            const backupShareHolder = {
                userHeldKeyShare: backupKeyShare,
            };
            const backupGpgKey = userLocalBackupGpgKey;
            const bitgoKeychain = await tssUtils.createBitgoKeychain({
                userGpgKey,
                backupGpgKey,
                userKeyShare,
                backupKeyShare: backupShareHolder,
                bitgoPublicGpgKey: bitgoPublicKey,
            });
            bitgoKeychain.should.deepEqual(nockedBitGoKeychain);
            const testKeyShares = ecdsaFixtures_1.otherKeyShares;
            const testCasesPromises = [
                tssUtils
                    .createParticipantKeychain(userGpgKey, userLocalBackupGpgKey, bitgoPublicKey, 1, userKeyShare, testKeyShares[0], bitgoKeychain, 'passphrase')
                    .should.be.rejectedWith('Common keychains do not match'),
                tssUtils
                    .createParticipantKeychain(userGpgKey, userLocalBackupGpgKey, bitgoPublicKey, 1, testKeyShares[1], backupKeyShare, bitgoKeychain, 'passphrase')
                    .should.be.rejectedWith('Common keychains do not match'),
                tssUtils
                    .createParticipantKeychain(userGpgKey, userLocalBackupGpgKey, bitgoPublicKey, 2, testKeyShares[2], backupKeyShare, bitgoKeychain, 'passphrase')
                    .should.be.rejectedWith('Common keychains do not match'),
                tssUtils
                    .createParticipantKeychain(userGpgKey, userLocalBackupGpgKey, bitgoPublicKey, 2, userKeyShare, testKeyShares[3], bitgoKeychain, 'passphrase')
                    .should.be.rejectedWith('Common keychains do not match'),
            ];
            await Promise.all(testCasesPromises);
        });
        it('should fail to generate TSS keychains when received invalid number of wallet signatures', async function () {
            const bitgoKeychain = await generateBitgoKeychain({
                coin: coinName,
                userKeyShare,
                backupKeyShare,
                bitgoKeyShare,
                userGpgKey,
                userLocalBackupGpgKey,
                bitgoGpgKey: bitGoGPGKeyPair,
            });
            const certsString = await (0, src_1.createSharedDataProof)(bitGoGPGKeyPair.privateKey, userGpgKey.publicKey, []);
            const certsKey = await openpgp.readKey({ armoredKey: certsString });
            const finalKey = new openpgp.PacketList();
            certsKey.toPacketList().forEach((packet) => finalKey.push(packet));
            // Once the following PR has been merged and released we no longer need the ts-ignore:
            // https://github.com/openpgpjs/openpgpjs/pull/1576
            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
            // @ts-ignore
            bitgoKeychain.walletHSMGPGPublicKeySigs = openpgp.armor(openpgp.enums.armor.publicKey, finalKey.write());
            await tssUtils
                .verifyWalletSignatures(userLocalBackupGpgKey.publicKey, userLocalBackupGpgKey.publicKey, bitgoKeychain, '', 1)
                .should.be.rejectedWith(`Invalid wallet signatures`);
        });
        it('should fail to generate TSS keychains when wallet signature fingerprints do not match passed user/backup fingerprints', async function () {
            const customUserKeyShare = await MPC.keyShare(1, 2, 3);
            const customBackupKeyShare = await MPC.keyShare(2, 2, 3);
            const backupShareHolder = {
                userHeldKeyShare: customBackupKeyShare,
            };
            const backupGpgKey = userLocalBackupGpgKey;
            const bitgoKeychain = await tssUtils.createBitgoKeychain({
                userGpgKey,
                backupGpgKey,
                userKeyShare: customUserKeyShare,
                backupKeyShare: backupShareHolder,
                bitgoPublicGpgKey: bitgoPublicKey,
            });
            // using the backup gpg here instead of the user gpg key to simulate that the first signature has a different
            // fingerprint from the passed in first gpg key
            await tssUtils
                .verifyWalletSignatures(userLocalBackupGpgKey.publicKey, userLocalBackupGpgKey.publicKey, bitgoKeychain, '', 1)
                .should.be.rejectedWith(`first wallet signature's fingerprint does not match passed user gpg key's fingerprint`);
            // using the user gpg here instead of the backup gpg key to simulate that the second signature has a different
            // fingerprint from the passed in second gpg key
            await tssUtils
                .verifyWalletSignatures(userGpgKey.publicKey, userGpgKey.publicKey, bitgoKeychain, '', 1)
                .should.be.rejectedWith(`second wallet signature's fingerprint does not match passed backup gpg key's fingerprint`);
        });
    });
    describe('signTxRequest:', () => {
        const txRequestId = 'randomidEcdsa';
        const txRequest = {
            txRequestId,
            transactions: [
                {
                    unsignedTx: {
                        // hteth txid: 0xc5a7bfe6b13ceae563da0f9feaa9c4ad1c101a15366a2a488828a5dd27cb9da3
                        serializedTxHex: '02f38242688084448b9b8084448b9b908301637894a1cfb9d51c0af191ff21c5f0f01723e056f7dc12865af3107a400080c0808080',
                        signableHex: '02f08242688084448b9b8084448b9b908301637894a1cfb9d51c0af191ff21c5f0f01723e056f7dc12865af3107a400080c0',
                        derivationPath: '', // Needs this when key derivation is supported
                    },
                    state: 'pendingSignature',
                    signatureShares: [],
                },
            ],
            unsignedTxs: [
                {
                    // hteth txid: 0xc5a7bfe6b13ceae563da0f9feaa9c4ad1c101a15366a2a488828a5dd27cb9da3
                    serializedTxHex: '02f38242688084448b9b8084448b9b908301637894a1cfb9d51c0af191ff21c5f0f01723e056f7dc12865af3107a400080c0808080',
                    signableHex: '02f38242688084448b9b8084448b9b908301637894a1cfb9d51c0af191ff21c5f0f01723e056f7dc12865af3107a400080c0808080',
                    derivationPath: '', // Needs this when key derivation is supported
                },
            ],
            date: new Date().toISOString(),
            intent: {
                intentType: 'payment',
            },
            latest: true,
            state: 'pendingUserSignature',
            walletType: 'hot',
            walletId: 'walletId',
            policiesChecked: true,
            version: 1,
            userId: 'userId',
        };
        let aShare, dShare, wShare, oShare, userSignShare, bitgoChallenges, enterpriseChallenges;
        beforeEach(async () => {
            // Initializing user and bitgo for creating shares for nocks
            const userSigningKey = MPC.keyCombine(userKeyShare.pShare, [bitgoKeyShare.nShares[1], backupKeyShare.nShares[1]]);
            const bitgoSigningKey = MPC.keyCombine(bitgoKeyShare.pShare, [
                userKeyShare.nShares[3],
                backupKeyShare.nShares[3],
            ]);
            const serializedEntChallenge = ecdsaNtilde_1.mockChallengeA;
            const serializedBitgoChallenge = ecdsaNtilde_1.mockChallengeB;
            const deserializedEntChallenge = sdk_lib_mpc_1.EcdsaTypes.deserializeNtildeWithProofs(serializedEntChallenge);
            sinon.stub(sdk_lib_mpc_1.EcdsaRangeProof, 'generateNtilde').resolves(deserializedEntChallenge);
            const [userToBitgoPaillierChallenge, bitgoToUserPaillierChallenge] = await Promise.all([
                sdk_lib_mpc_1.EcdsaPaillierProof.generateP((0, sdk_lib_mpc_1.hexToBigInt)(userSigningKey.yShares[3].n)),
                sdk_lib_mpc_1.EcdsaPaillierProof.generateP((0, sdk_lib_mpc_1.hexToBigInt)(bitgoSigningKey.yShares[1].n)),
            ]);
            bitgoChallenges = {
                ...serializedBitgoChallenge,
                p: sdk_lib_mpc_1.EcdsaTypes.serializePaillierChallenge({ p: bitgoToUserPaillierChallenge }).p,
                n: bitgoSigningKey.xShare.n,
            };
            enterpriseChallenges = {
                ...serializedEntChallenge,
                p: sdk_lib_mpc_1.EcdsaTypes.serializePaillierChallenge({ p: userToBitgoPaillierChallenge }).p,
                n: bitgoSigningKey.xShare.n,
            };
            sinon.stub(sdk_core_1.ECDSAUtils.EcdsaUtils.prototype, 'getEcdsaSigningChallenges').resolves({
                enterpriseChallenge: enterpriseChallenges,
                bitgoChallenge: bitgoChallenges,
            });
            const [userXShare, bitgoXShare] = [
                MPC.appendChallenge(userSigningKey.xShare, serializedEntChallenge, sdk_lib_mpc_1.EcdsaTypes.serializePaillierChallenge({ p: userToBitgoPaillierChallenge })),
                MPC.appendChallenge(bitgoSigningKey.xShare, serializedBitgoChallenge, sdk_lib_mpc_1.EcdsaTypes.serializePaillierChallenge({ p: bitgoToUserPaillierChallenge })),
            ];
            const bitgoYShare = MPC.appendChallenge(userSigningKey.yShares[3], serializedBitgoChallenge, sdk_lib_mpc_1.EcdsaTypes.serializePaillierChallenge({ p: bitgoToUserPaillierChallenge }));
            /**
             * START STEP ONE
             * 1) User creates signShare, saves wShare and sends kShare to bitgo
             * 2) Bitgo performs signConvert operation using its private xShare , yShare
             *  and KShare from user and responds back with aShare and saves bShare for later use
             */
            userSignShare = await sdk_core_1.ECDSAMethods.createUserSignShare(userXShare, bitgoYShare);
            wShare = userSignShare.wShare;
            const signatureShareOneFromUser = {
                from: sdk_core_1.SignatureShareType.USER,
                to: sdk_core_1.SignatureShareType.BITGO,
                share: sdk_core_1.ECDSAMethods.convertKShare(userSignShare.kShare).share.replace(sdk_core_1.ECDSAMethods.delimeter, ''),
            };
            const getBitgoAandBShare = await MPC.signConvertStep1({
                xShare: bitgoXShare,
                yShare: bitgoSigningKey.yShares[1], // corresponds to the user
                kShare: userSignShare.kShare,
            });
            const bitgoAshare = getBitgoAandBShare.aShare;
            aShare = bitgoAshare;
            const aShareBitgoResponse = sdk_core_1.ECDSAMethods.convertAShare(bitgoAshare).share.replace(sdk_core_1.ECDSAMethods.delimeter, '');
            const signatureShareOneFromBitgo = {
                from: sdk_core_1.SignatureShareType.BITGO,
                to: sdk_core_1.SignatureShareType.USER,
                share: aShareBitgoResponse,
            };
            await (0, common_1.nockSendSignatureShareWithResponse)({
                walletId: wallet.id(),
                txRequestId: txRequest.txRequestId,
                signatureShare: signatureShareOneFromUser,
                response: signatureShareOneFromBitgo,
                tssType: 'ecdsa',
            });
            /**  END STEP ONE */
            /**
             * START STEP TWO
             * 1) Using the aShare got from bitgo and wShare from previous step,
             * user creates gShare and muShare and sends muShare to bitgo
             * 2) Bitgo using the signConvert step using bShare from previous step
             * and muShare from user generates its gShare.
             * 3) Using the signCombine operation using gShare, Bitgo generates oShare
             * which it saves and dShare which is send back to the user.
             */
            const userGammaAndMuShares = await sdk_core_1.ECDSAMethods.createUserGammaAndMuShare(userSignShare.wShare, bitgoAshare);
            const signatureShareTwoFromUser = {
                from: sdk_core_1.SignatureShareType.USER,
                to: sdk_core_1.SignatureShareType.BITGO,
                share: sdk_core_1.ECDSAMethods.convertMuShare(userGammaAndMuShares.muShare).share.replace(sdk_core_1.ECDSAMethods.delimeter, ''),
            };
            const getBitGoGShareAndSignerIndexes = await MPC.signConvertStep3({
                bShare: getBitgoAandBShare.bShare,
                muShare: userGammaAndMuShares.muShare,
            });
            const getBitgoOShareAndDShares = MPC.signCombine({
                gShare: getBitGoGShareAndSignerIndexes.gShare,
                signIndex: {
                    i: 1,
                    j: 3,
                },
            });
            const bitgoDshare = getBitgoOShareAndDShares.dShare;
            dShare = bitgoDshare;
            const dShareBitgoResponse = bitgoDshare.delta + bitgoDshare.Gamma;
            const signatureShareTwoFromBitgo = {
                from: sdk_core_1.SignatureShareType.BITGO,
                to: sdk_core_1.SignatureShareType.USER,
                share: dShareBitgoResponse,
            };
            await (0, common_1.nockSendSignatureShareWithResponse)({
                walletId: wallet.id(),
                txRequestId: txRequest.txRequestId,
                signatureShare: signatureShareTwoFromUser,
                response: signatureShareTwoFromBitgo,
                tssType: 'ecdsa',
            });
            /**  END STEP TWO */
            /**
             * START STEP THREE
             * 1) User creates its oShare and  dShare using the  private gShare
             * from step two
             * 2) User uses the private oShare and dShare from bitgo from step
             * two to generate its signature share which it sends back along with dShare that
             * user generated from the above step
             * 3) Bitgo using its private oShare from step two and dShare from bitgo creates
             * its signature share. Using the Signature Share received from user from the above
             * step, bitgo constructs the final signature and is returned to the user
             */
            const userOmicronAndDeltaShare = await sdk_core_1.ECDSAMethods.createUserOmicronAndDeltaShare(userGammaAndMuShares.gShare);
            oShare = userOmicronAndDeltaShare.oShare;
            const signablePayload = Buffer.from(txRequest.unsignedTxs[0].signableHex, 'hex');
            const userSShare = await sdk_core_1.ECDSAMethods.createUserSignatureShare(userOmicronAndDeltaShare.oShare, bitgoDshare, signablePayload);
            const signatureShareThreeFromUser = {
                from: sdk_core_1.SignatureShareType.USER,
                to: sdk_core_1.SignatureShareType.BITGO,
                share: userSShare.R +
                    userSShare.s +
                    userSShare.y +
                    userOmicronAndDeltaShare.dShare.delta +
                    userOmicronAndDeltaShare.dShare.Gamma,
            };
            const getBitGoSShare = MPC.sign(signablePayload, getBitgoOShareAndDShares.oShare, userOmicronAndDeltaShare.dShare, createKeccakHash('keccak256'));
            const getBitGoFinalSignature = MPC.constructSignature([getBitGoSShare, userSShare]);
            const finalSigantureBitgoResponse = getBitGoFinalSignature.r + getBitGoFinalSignature.s + getBitGoFinalSignature.y;
            const signatureShareThreeFromBitgo = {
                from: sdk_core_1.SignatureShareType.BITGO,
                to: sdk_core_1.SignatureShareType.USER,
                share: finalSigantureBitgoResponse,
            };
            await (0, common_1.nockSendSignatureShareWithResponse)({
                walletId: wallet.id(),
                txRequestId: txRequest.txRequestId,
                signatureShare: signatureShareThreeFromUser,
                response: signatureShareThreeFromBitgo,
                tssType: 'ecdsa',
            });
            /* END STEP THREE */
            const signature = MPC.constructSignature([userSShare, getBitGoSShare]);
            MPC.verify(signablePayload, signature, createKeccakHash('keccak256')).should.be.true;
        });
        afterEach(async () => {
            sinon.restore();
        });
        it('signTxRequest should fail if wallet is in pendingEcdsaTssInitialization', async function () {
            sandbox.stub(wallet, 'coinSpecific').returns({
                customChangeWalletId: '',
                pendingEcdsaTssInitialization: true,
            });
            await tssUtils
                .signTxRequest({
                txRequest,
                prv: JSON.stringify({
                    pShare: userKeyShare.pShare,
                    bitgoNShare: bitgoKeyShare.nShares[1],
                    backupNShare: backupKeyShare.nShares[1],
                }),
                reqId,
            })
                .should.be.rejectedWith('Wallet is not ready for TSS ECDSA signing. Please contact your enterprise admin to finish the enterprise TSS initialization.');
        });
        it('signTxRequest should succeed with txRequest object as input', async function () {
            const sendShareSpy = sinon.spy(sdk_core_1.ECDSAMethods, 'sendShareToBitgo');
            await setupSignTxRequestNocks(false, userSignShare, aShare, dShare, enterpriseData);
            const signedTxRequest = await tssUtils.signTxRequest({
                txRequest,
                prv: JSON.stringify({
                    pShare: userKeyShare.pShare,
                    bitgoNShare: bitgoKeyShare.nShares[1],
                    backupNShare: backupKeyShare.nShares[1],
                }),
                reqId,
            });
            signedTxRequest.unsignedTxs.should.deepEqual(txRequest.unsignedTxs);
            const userGpgActual = sendShareSpy.getCalls()[0].args[10];
            userGpgActual.should.startWith('-----BEGIN PGP PUBLIC KEY BLOCK-----');
        });
        it('signTxRequest should succeed with txRequest id as input', async function () {
            const sendShareSpy = sinon.spy(sdk_core_1.ECDSAMethods, 'sendShareToBitgo');
            await setupSignTxRequestNocks(true, userSignShare, aShare, dShare, enterpriseData);
            const signedTxRequest = await tssUtils.signTxRequest({
                txRequest: txRequestId,
                prv: JSON.stringify({
                    pShare: userKeyShare.pShare,
                    bitgoNShare: bitgoKeyShare.nShares[1],
                    backupNShare: backupKeyShare.nShares[1],
                }),
                reqId,
            });
            signedTxRequest.unsignedTxs.should.deepEqual(txRequest.unsignedTxs);
            const userGpgActual = sendShareSpy.getCalls()[0].args[10];
            userGpgActual.should.startWith('-----BEGIN PGP PUBLIC KEY BLOCK-----');
        });
        it('signTxRequest should fail with wrong recipient', async function () {
            await setupSignTxRequestNocks(true, userSignShare, aShare, dShare, enterpriseData);
            await tssUtils
                .signTxRequest({
                txRequest: txRequestId,
                prv: JSON.stringify({
                    pShare: userKeyShare.pShare,
                    bitgoNShare: bitgoKeyShare.nShares[1],
                    backupNShare: backupKeyShare.nShares[1],
                }),
                reqId,
                txParams: { recipients: [{ address: '0x1234', amount: '100000000000000' }], type: 'transfer' },
            })
                .should.be.rejectedWith('destination address does not match with the recipient address');
        });
        it('signTxRequest should fail with incorrect value', async function () {
            await setupSignTxRequestNocks(true, userSignShare, aShare, dShare, enterpriseData);
            await tssUtils
                .signTxRequest({
                txRequest: txRequestId,
                prv: JSON.stringify({
                    pShare: userKeyShare.pShare,
                    bitgoNShare: bitgoKeyShare.nShares[1],
                    backupNShare: backupKeyShare.nShares[1],
                }),
                reqId,
                txParams: {
                    recipients: [{ address: '0xa1cfb9d51c0af191ff21c5f0f01723e056f7dc12', amount: '1' }],
                    type: 'transfer',
                },
            })
                .should.be.rejectedWith('the transaction amount in txPrebuild does not match the value given by client');
        });
        it('signTxRequest should fail with incorrect value for token txn', async function () {
            const signableHex = '02f86d8242681083122c9e83122cae8301e04994ebe8b46a42f05072b723b00013ff822b2af1b5cb80b844a9059cbb0000000000000000000000002b0d6cb2f8c388757f4d7ad857fccab18290dbc900000000000000000000000000000000000000000000000000000000000186a0c0';
            const serializedTxHex = '02f8708242681083122c9e83122cae8301e04994ebe8b46a42f05072b723b00013ff822b2af1b5cb80b844a9059cbb0000000000000000000000002b0d6cb2f8c388757f4d7ad857fccab18290dbc900000000000000000000000000000000000000000000000000000000000186a0c0808080';
            await setupSignTxRequestNocks(true, userSignShare, aShare, dShare, enterpriseData, {
                signableHex,
                serializedTxHex,
                apiVersion: 'full',
            });
            await tssUtils
                .signTxRequest({
                txRequest: txRequestId,
                prv: JSON.stringify({
                    pShare: userKeyShare.pShare,
                    bitgoNShare: bitgoKeyShare.nShares[1],
                    backupNShare: backupKeyShare.nShares[1],
                }),
                reqId,
                txParams: {
                    recipients: [{ address: '0x2b0d6cb2f8c388757f4d7ad857fccab18290dbc9', amount: '707' }],
                    type: 'transfer',
                },
            })
                .should.be.rejectedWith('the transaction amount in txPrebuild does not match the value given by client');
        });
        it('getOfflineSignerPaillierModulus should succeed', async function () {
            const paillierModulus = tssUtils.getOfflineSignerPaillierModulus({
                prv: JSON.stringify({
                    pShare: userKeyShare.pShare,
                    bitgoNShare: bitgoKeyShare.nShares[1],
                    backupNShare: backupKeyShare.nShares[1],
                }),
            });
            paillierModulus.userPaillierModulus.should.equal(userKeyShare.pShare.n);
        });
        it('createOfflineKShare should succeed', async function () {
            const mockPassword = 'password';
            const step1SigningMaterial = await tssUtils.createOfflineKShare({
                tssParams: {
                    txRequest,
                    reqId: reqId,
                },
                challenges: {
                    enterpriseChallenge: enterpriseChallenges,
                    bitgoChallenge: bitgoChallenges,
                },
                prv: JSON.stringify({
                    pShare: userKeyShare.pShare,
                    bitgoNShare: bitgoKeyShare.nShares[1],
                    backupNShare: backupKeyShare.nShares[1],
                }),
                requestType: src_1.RequestType.tx,
                walletPassphrase: mockPassword,
            });
            step1SigningMaterial.privateShareProof.should.startWith('-----BEGIN PGP PUBLIC KEY BLOCK-----');
            step1SigningMaterial.vssProof?.length.should.equal(userKeyShare.nShares[3].v?.length);
            step1SigningMaterial.publicShare.length.should.equal(userKeyShare.nShares[3].y.length + userKeyShare.nShares[3].chaincode.length);
            step1SigningMaterial.encryptedSignerOffsetShare.should.startWith('-----BEGIN PGP MESSAGE-----');
            step1SigningMaterial.userPublicGpgKey.should.startWith('-----BEGIN PGP PUBLIC KEY BLOCK-----');
            step1SigningMaterial.kShare.n.should.equal(userKeyShare.pShare.n);
            step1SigningMaterial.wShare.should.startWith('{"iv":');
        });
        it('createOfflineKShare should fail with txId passed', async function () {
            const mockPassword = 'password';
            await tssUtils
                .createOfflineKShare({
                tssParams: {
                    txRequest: txRequest.txRequestId,
                    reqId: reqId,
                },
                challenges: {
                    enterpriseChallenge: enterpriseChallenges,
                    bitgoChallenge: bitgoChallenges,
                },
                prv: JSON.stringify({
                    pShare: userKeyShare.pShare,
                    bitgoNShare: bitgoKeyShare.nShares[1],
                    backupNShare: backupKeyShare.nShares[1],
                }),
                requestType: src_1.RequestType.tx,
                walletPassphrase: mockPassword,
            })
                .should.be.rejectedWith('Invalid txRequest type');
        });
        // Seems to be flaky on CI, failed here: https://github.com/BitGo/BitGoJS/actions/runs/5902489990/job/16010623888?pr=3822
        xit('createOfflineMuDeltaShare should succeed', async function () {
            const mockPassword = 'password';
            const alphaLength = 1536;
            const deltaLength = 64;
            const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
            const step2SigningMaterial = await tssUtils.createOfflineMuDeltaShare({
                aShareFromBitgo: aShare,
                bitgoChallenge: bitgoChallenges,
                encryptedWShare: bitgo.encrypt({ input: JSON.stringify(wShare), password: mockPassword }),
                walletPassphrase: mockPassword,
            });
            step2SigningMaterial.muDShare.muShare.alpha.length.should.equal(alphaLength);
            step2SigningMaterial.muDShare.dShare.delta.length.should.equal(deltaLength);
            step2SigningMaterial.oShare.should.startWith('{"iv":');
        });
        it('createOfflineMuDeltaShare should fail with incorrect password', async function () {
            const mockPassword = 'password';
            const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
            await tssUtils
                .createOfflineMuDeltaShare({
                aShareFromBitgo: aShare,
                bitgoChallenge: bitgoChallenges,
                encryptedWShare: bitgo.encrypt({ input: JSON.stringify(wShare), password: mockPassword }),
                walletPassphrase: 'password1',
            })
                .should.be.rejectedWith("password error - ccm: tag doesn't match");
        });
        it('createOfflineSShare should succeed', async function () {
            const mockPassword = 'password';
            const pubKeyLength = 66;
            const privKeyLength = 64;
            const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
            const step3SigningMaterial = await tssUtils.createOfflineSShare({
                tssParams: {
                    txRequest: txRequest,
                    reqId: reqId,
                },
                dShareFromBitgo: dShare,
                encryptedOShare: bitgo.encrypt({ input: JSON.stringify(oShare), password: mockPassword }),
                walletPassphrase: mockPassword,
                requestType: src_1.RequestType.tx,
            });
            step3SigningMaterial.R.length.should.equal(pubKeyLength);
            step3SigningMaterial.y.length.should.equal(pubKeyLength);
            step3SigningMaterial.s.length.should.equal(privKeyLength);
        });
        it('createOfflineSShare should fail with txId passed', async function () {
            const mockPassword = 'password';
            const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
            await tssUtils
                .createOfflineSShare({
                tssParams: {
                    txRequest: txRequest.txRequestId,
                    reqId: reqId,
                },
                dShareFromBitgo: dShare,
                encryptedOShare: bitgo.encrypt({ input: JSON.stringify(oShare), password: mockPassword }),
                walletPassphrase: mockPassword,
                requestType: src_1.RequestType.tx,
            })
                .should.be.rejectedWith('Invalid txRequest type');
        });
        it('signTxRequest should fail with invalid user prv', async function () {
            const invalidUserKey = { ...userKeyShare, pShare: { ...userKeyShare.pShare, i: 2 } };
            await tssUtils
                .signTxRequest({
                txRequest: txRequestId,
                prv: JSON.stringify({
                    pShare: invalidUserKey.pShare,
                    bitgoNShare: bitgoKeyShare.nShares[1],
                    backupNShare: backupKeyShare.nShares[1],
                }),
                reqId,
            })
                .should.be.rejectedWith('Invalid user key');
        });
        it('signTxRequest should fail with no backupNShares', async function () {
            const getTxRequest = sandbox.stub(tssUtils, 'getTxRequest');
            getTxRequest.resolves(txRequest);
            getTxRequest.calledWith(txRequestId);
            setupSignTxRequestNocks(false, userSignShare, aShare, dShare, enterpriseData);
            await tssUtils
                .signTxRequest({
                txRequest: txRequestId,
                prv: JSON.stringify({
                    pShare: userKeyShare.pShare,
                    bitgoNShare: bitgoKeyShare.nShares[1],
                }),
                reqId,
            })
                .should.be.rejectedWith('Invalid user key - missing backupNShare');
        });
        async function setupSignTxRequestNocks(isTxRequest = true, userSignShare, aShare, dShare, enterpriseData, { signableHex, serializedTxHex, apiVersion, } = {}) {
            if (enterpriseData) {
                await (0, helpers_1.nockGetEnterprise)({ enterpriseId: enterpriseData.id, response: enterpriseData, times: 1 });
            }
            const derivationPath = '';
            sinon.stub(sdk_core_1.ECDSAMethods, 'createUserSignShare').resolves(userSignShare);
            let response = {
                txRequests: [
                    {
                        ...txRequest,
                        transactions: [
                            {
                                ...txRequest,
                                unsignedTx: {
                                    signableHex: signableHex ?? txRequest.unsignedTxs[0].signableHex,
                                    serializedTxHex: serializedTxHex ?? txRequest.unsignedTxs[0].serializedTxHex,
                                    derivationPath,
                                },
                            },
                        ],
                        apiVersion: apiVersion,
                    },
                ],
            };
            if (isTxRequest) {
                await (0, helpers_1.nockGetTxRequest)({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response: response });
            }
            const aRecord = sdk_core_1.ECDSAMethods.convertAShare(aShare);
            const signatureShares = [aRecord];
            txRequest.signatureShares = signatureShares;
            response = {
                txRequests: [
                    {
                        ...txRequest,
                        transactions: [
                            {
                                ...txRequest,
                                unsignedTx: {
                                    signableHex: txRequest.unsignedTxs[0].signableHex,
                                    serializedTxHex: txRequest.unsignedTxs[0].serializedTxHex,
                                    derivationPath,
                                },
                            },
                        ],
                        apiVersion: apiVersion,
                    },
                ],
            };
            await (0, helpers_1.nockGetTxRequest)({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response: response });
            const dRecord = sdk_core_1.ECDSAMethods.convertDShare(dShare);
            signatureShares.push(dRecord);
            response = {
                txRequests: [
                    {
                        ...txRequest,
                        transactions: [
                            {
                                ...txRequest,
                                unsignedTx: {
                                    signableHex: txRequest.unsignedTxs[0].signableHex,
                                    serializedTxHex: txRequest.unsignedTxs[0].serializedTxHex,
                                    derivationPath,
                                },
                            },
                        ],
                        apiVersion: apiVersion,
                    },
                ],
            };
            await (0, helpers_1.nockGetTxRequest)({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response: response });
            await (0, helpers_1.nockGetTxRequest)({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response: response });
        }
    });
    describe('getEcdsaSigningChallenges', function () {
        const mockWalletPaillierKey = {
            n: 'f47be4c2d8bc1e28f88c6c4da634da97d92a1c279a7b0fe7b87c337c36a27b32ce0ff0c45f16e4e15bbd20e4e640de12047eff9b1a2b98144f9a268d406bd000d192a35b6847a17e40fb85f55b314d001ff87393481cafe391807d0eb83eff9e38614b38e5f25fc4449cb01caed805584d026b5d866c723f3d4d4f1e462662f2113b1561eb2bf755b4b91d0308d8eacc439167da8b7d6e108524f226960360af00215d9614457414ebdbe8834999689e2e903208c8713ff5d9901f9eaba3aa81d705323cbbba61ba7fa9f3228f30853fb55da1b3d3ed7db1dfc6545bc96aa8d2eb848931c1b807fdfe8f65af72f68638a82fe9e22ac1f0f032e621066806a1f144b5719a5f091986867b384be6c34146c8241cbfbd781966ebbcd19e6caa27fab040e62e5a162888aa8624d046c8fe3b72244f04a7264c4a36b6366dbe7da98afb201d34be2c0d6dd11982af35bf7535582b263914725aaec280d52290527382d3ab297d746c41aacd8de98c09fcfb85a95e02de1b34d4933e51045e2f1ce8af',
            lambda: 'f47be4c2d8bc1e28f88c6c4da634da97d92a1c279a7b0fe7b87c337c36a27b32ce0ff0c45f16e4e15bbd20e4e640de12047eff9b1a2b98144f9a268d406bd000d192a35b6847a17e40fb85f55b314d001ff87393481cafe391807d0eb83eff9e38614b38e5f25fc4449cb01caed805584d026b5d866c723f3d4d4f1e462662f2113b1561eb2bf755b4b91d0308d8eacc439167da8b7d6e108524f226960360af00215d9614457414ebdbe8834999689e2e903208c8713ff5d9901f9eaba3aa7fc3d0c0bcc5bff644156ab887146d51bcee1eef70f45c486147d687ee37def1f8a16bc945eff22dd4dca3614a99158823acd9492e347f7ec79a7771024205d07f27b30cd20340e330411da8fa2da209e5cc688da94d1dbef54bfd9c69b4e99cf06d67309a3420b82c78a0fe0dd0b9c31382eae38746cfdd27fa90022a50532246c8ae1339c93e183c03bf6fd7014be3658abc73baae1fa5b86dab94b9f125395a818e54dde6235c45d3dbc032b3078e9df1cad69d8ac19a7cb6405a558b7bfba8',
        };
        const mockBitgoPaillierKey = {
            n: 'f010d294effceb8c4f96af1978ab367c4fbb272c2169317e41ae87220652cae2ce929696ee55ec6831aa6b4b3b931babc2bac9c1a20fddbca925cc99680791f7c3157b3d31256ee72c47d47db567e0f070dce121c3a4d9e003c1f1389073acb252c65d2b0723e86e3265f67a137cb1e23f4551544405644d0ae63d35f25f40becd2b693879f3bdbec3f7250791a3f3c975a5ac78a0e81dcd1a87eb2ca67010dff880b2338556275de23d9e88d21b77da0d524ddc2b394f8de00b1af0ce85f6eee2e05a184e05494d66d2c636045bf70ed15ebd0f41a8eea2920af85e6d68a0ce11fc2abbcb3cebcc3c23ec2e148c318683a5426e15b5207efd3b9b05cb919ec4340f74dff336986d0c923df10a789007b1da9daddf8edf3014e93989f30243f27f9a307d55d630cbfcd16cd6a95a41dee10c31acc293df6834ce0e3ea5b68f170bd7938ea0c2eeb788e16f30af57b3f0888fb44d3610e7eeba60e7fd8cc4a8f044718dfc6174bf4a380690dc1dc77472a48892eb3e81775540ea0acc9e89b639',
            lambda: 'f010d294effceb8c4f96af1978ab367c4fbb272c2169317e41ae87220652cae2ce929696ee55ec6831aa6b4b3b931babc2bac9c1a20fddbca925cc99680791f7c3157b3d31256ee72c47d47db567e0f070dce121c3a4d9e003c1f1389073acb252c65d2b0723e86e3265f67a137cb1e23f4551544405644d0ae63d35f25f40becd2b693879f3bdbec3f7250791a3f3c975a5ac78a0e81dcd1a87eb2ca67010dff880b2338556275de23d9e88d21b77da0d524ddc2b394f8de00b1af0ce85f6ecdef8a4bc955a28ecef7d97cded079d390e77c80998d78ad9510cbabfeb8f0a157dbfc590b4d59ee8c0b088f9d89473b557320078a117478624f5d1df36e30f320b6722a4217dcb46b978cc6c8f1a21c8a6c74bce84d82c481402c99a69b798e3c05f23350b4aade4f79784b1c09692b6a33cfba7f145597d82b799cccef620c36f1fbbe2cb4ac0ea395c476e381bc475d41722320f541ae9bf56aa4a12dff3ea7ab11174fb5b8df7429c9f57d36f8fc51e1a8c647d5b8fa0189fb8acdbd0a780',
        };
        const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
        const txRequestId = 'fakeTxRequestId';
        const rawEntChallengeWithProofs = sdk_test_1.mockSerializedChallengeWithProofs;
        let rawBitgoChallenge;
        const adminEcdhKey = bitgo.keychains().create();
        const fakeAdminEcdhKey = bitgo.keychains().create();
        const derivationPath = 'm/0/0';
        const mockedSigningKey = {
            userId: 'id',
            userEmail: 'user@bitgo.com',
            derivedPubkey: utxo_lib_1.bip32.fromBase58(adminEcdhKey.xpub).derivePath(derivationPath).publicKey.toString('hex'),
            derivationPath: derivationPath,
            ecdhKeychain: 'my keychain',
        };
        before(async function () {
            const p = await sdk_lib_mpc_1.EcdsaPaillierProof.generateP((0, sdk_lib_mpc_1.hexToBigInt)(mockWalletPaillierKey.n));
            rawBitgoChallenge = {
                ...sdk_lib_mpc_1.EcdsaTypes.serializeNtilde(sdk_lib_mpc_1.EcdsaTypes.deserializeNtilde(sdk_test_1.mockSerializedChallengeWithProofs2)),
                p: sdk_lib_mpc_1.EcdsaTypes.serializePaillierChallenge({ p }).p,
                n: mockBitgoPaillierKey.n,
            };
        });
        afterEach(function () {
            sinon.restore();
            nock.cleanAll();
        });
        it('should fetch static ent and bitgo challenges with the ent feature flag and verify them', async function () {
            await (0, helpers_1.nockGetChallenge)({ walletId, txRequestId, addendum: '/transactions/0', response: rawBitgoChallenge });
            await (0, helpers_1.nockGetSigningKey)({ enterpriseId, userId: mockedSigningKey.userId, response: mockedSigningKey, times: 1 });
            const adminSignatureEntChallenge = sdk_core_1.ECDSAUtils.EcdsaUtils.signChallenge(rawEntChallengeWithProofs, adminEcdhKey.xprv, derivationPath);
            const adminSignatureBitGoChallenge = sdk_core_1.ECDSAUtils.EcdsaUtils.signChallenge(rawBitgoChallenge, adminEcdhKey.xprv, derivationPath);
            const mockChallengesResponse = {
                enterpriseChallenge: {
                    ...rawEntChallengeWithProofs,
                    verifiers: {
                        adminSignature: adminSignatureEntChallenge.toString('hex'),
                    },
                },
                bitgoChallenge: {
                    ...rawBitgoChallenge,
                    verifiers: {
                        adminSignature: adminSignatureBitGoChallenge.toString('hex'),
                    },
                },
                createdBy: 'id',
            };
            await (0, helpers_1.nockGetChallenges)({ walletId: walletId, response: mockChallengesResponse });
            const challenges = await tssUtils.getEcdsaSigningChallenges(txRequestId, 0, mockWalletPaillierKey.n, 0);
            should.exist(challenges);
            const expectedRangeProofChallenges = {
                enterpriseChallenge: {
                    ntilde: challenges.enterpriseChallenge.ntilde,
                    h1: challenges.enterpriseChallenge.h1,
                    h2: challenges.enterpriseChallenge.h2,
                },
                bitgoChallenge: rawBitgoChallenge,
            };
            expectedRangeProofChallenges.should.deepEqual({
                enterpriseChallenge: {
                    ntilde: rawEntChallengeWithProofs.ntilde,
                    h1: rawEntChallengeWithProofs.h1,
                    h2: rawEntChallengeWithProofs.h2,
                },
                bitgoChallenge: rawBitgoChallenge,
            });
        });
        it('Fails if the enterprise challenge signature is different from the admin ecdh key', async function () {
            await (0, helpers_1.nockGetChallenge)({ walletId, txRequestId, addendum: '/transactions/0', response: rawBitgoChallenge });
            await (0, helpers_1.nockGetEnterprise)({
                enterpriseId: enterpriseData.id,
                response: {
                    ...enterpriseData,
                    featureFlags: ['useEnterpriseEcdsaTssChallenge'],
                },
                times: 1,
            });
            await (0, helpers_1.nockGetSigningKey)({ enterpriseId, userId: mockedSigningKey.userId, response: mockedSigningKey, times: 1 });
            // Bad sign
            const adminSignedEntChallenge = sdk_core_1.ECDSAUtils.EcdsaUtils.signChallenge(rawEntChallengeWithProofs, fakeAdminEcdhKey.xprv, derivationPath);
            const adminSignedBitGoChallenge = sdk_core_1.ECDSAUtils.EcdsaUtils.signChallenge(rawBitgoChallenge, adminEcdhKey.xprv, derivationPath);
            const mockChallengesResponse = {
                enterpriseChallenge: {
                    ...rawEntChallengeWithProofs,
                    verifiers: {
                        adminSignature: adminSignedEntChallenge.toString('hex'),
                    },
                },
                bitgoChallenge: {
                    ...rawBitgoChallenge,
                    verifiers: {
                        adminSignature: adminSignedBitGoChallenge.toString('hex'),
                    },
                },
                createdBy: 'id',
            };
            await (0, helpers_1.nockGetChallenges)({ walletId: walletId, response: mockChallengesResponse });
            await tssUtils
                .getEcdsaSigningChallenges(txRequestId, 0, mockWalletPaillierKey.n)
                .should.be.rejectedWith('Admin signature for enterprise challenge is not valid. Please contact your enterprise admin.');
        });
        it('Fails if the bitgo challenge signature is different from the admin ecdh key', async function () {
            await (0, helpers_1.nockGetChallenge)({ walletId, txRequestId, addendum: '/transactions/0', response: rawBitgoChallenge });
            await (0, helpers_1.nockGetEnterprise)({
                enterpriseId: enterpriseData.id,
                response: {
                    ...enterpriseData,
                    featureFlags: ['useEnterpriseEcdsaTssChallenge'],
                },
                times: 1,
            });
            await (0, helpers_1.nockGetSigningKey)({ enterpriseId, userId: mockedSigningKey.userId, response: mockedSigningKey, times: 1 });
            const adminSignedEntChallenge = sdk_core_1.ECDSAUtils.EcdsaUtils.signChallenge(rawEntChallengeWithProofs, adminEcdhKey.xprv, derivationPath);
            // Bad sign
            const adminSignedBitGoChallenge = sdk_core_1.ECDSAUtils.EcdsaUtils.signChallenge(rawBitgoChallenge, fakeAdminEcdhKey.xprv, derivationPath);
            const mockChallengesResponse = {
                enterpriseChallenge: {
                    ...rawEntChallengeWithProofs,
                    verifiers: {
                        adminSignature: adminSignedEntChallenge.toString('hex'),
                    },
                },
                bitgoChallenge: {
                    ...rawBitgoChallenge,
                    verifiers: {
                        adminSignature: adminSignedBitGoChallenge.toString('hex'),
                    },
                },
                createdBy: 'id',
            };
            await (0, helpers_1.nockGetChallenges)({ walletId: walletId, response: mockChallengesResponse });
            await tssUtils
                .getEcdsaSigningChallenges(txRequestId, 0, mockWalletPaillierKey.n)
                .should.be.rejectedWith("Admin signature for BitGo's challenge is not valid. Please contact your enterprise admin.");
        });
    });
    describe('getVerifyAndSignBitGoChallenges', function () {
        const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
        const adminEcdhKey = bitgo.keychains().create();
        const derivationPath = 'm/0/0';
        const bitgoInstChallenge = ecdsaNtilde_1.mockChallengeA;
        const bitgoNitroChallenge = ecdsaNtilde_1.mockChallengeB;
        const userPassword = 'password123';
        const encryptedXprv = bitgo.encrypt({
            password: userPassword,
            input: adminEcdhKey.xprv,
        });
        beforeEach(async function () {
            sinon.stub(bitgo, 'getSigningKeyForUser').resolves({
                userId: 'id',
                userEmail: 'user@bitgo.com',
                derivedPubkey: utxo_lib_1.bip32.fromBase58(adminEcdhKey.xpub).derivePath(derivationPath).publicKey.toString('hex'),
                derivationPath: derivationPath,
                ecdhKeychain: 'my keychain',
            });
            sinon.stub(bitgo, 'getECDHKeychain').resolves({
                encryptedXprv: encryptedXprv,
            });
        });
        afterEach(async function () {
            sinon.restore();
            nock.cleanAll();
        });
        function nockGetBitgoChallenges(response) {
            return nock(bgUrl)
                .get(`/api/v2/tss/ecdsa/challenges`)
                .times(1)
                .reply(() => [200, response]);
        }
        it('succeeds for valid bitgo proofs', async function () {
            const nockGetBitgoChallengesApi = nockGetBitgoChallenges({
                bitgoNitroHsm: bitgoNitroChallenge,
                bitgoInstitutionalHsm: bitgoInstChallenge,
            });
            await sdk_core_1.ECDSAUtils.EcdsaUtils.getVerifyAndSignBitGoChallenges(bitgo, 'ent_id', userPassword).should.not.be.rejected();
            nockGetBitgoChallengesApi.isDone().should.be.true();
        });
        it('Fails if bitgo challenge proofs are not present', async function () {
            const nockGetBitgoChallengesApi = nockGetBitgoChallenges({
                bitgoNitroHsm: {
                    ...bitgoNitroChallenge,
                    ntildeProof: undefined,
                },
                bitgoInstitutionalHsm: bitgoInstChallenge,
            });
            await sdk_core_1.ECDSAUtils.EcdsaUtils.getVerifyAndSignBitGoChallenges(bitgo, 'ent_id', userPassword).should.be.rejectedWith('Expected BitGo challenge proof to be present. Contact support@bitgo.com.');
            nockGetBitgoChallengesApi.isDone().should.be.true();
        });
        it('Fails if the user password to decrypt the ecdhkeychain is wrong', async function () {
            const nockGetBitgoChallengesApi = nockGetBitgoChallenges({
                bitgoNitroHsm: bitgoNitroChallenge,
                bitgoInstitutionalHsm: bitgoInstChallenge,
            });
            await sdk_core_1.ECDSAUtils.EcdsaUtils.getVerifyAndSignBitGoChallenges(bitgo, 'ent_id', 'bro').should.be.rejectedWith('Incorrect password. Please try again.');
            nockGetBitgoChallengesApi.isDone().should.be.true();
        });
        it('Fails bitgo challenge proofs for faulty nitro h2WrtH1 proof', async function () {
            const nockGetBitgoChallengesApi = nockGetBitgoChallenges({
                bitgoNitroHsm: {
                    ...bitgoNitroChallenge,
                    ntildeProof: {
                        ...bitgoNitroChallenge.ntildeProof,
                        h2WrtH1: bitgoNitroChallenge.ntildeProof.h1WrtH2,
                    },
                },
                bitgoInstitutionalHsm: bitgoInstChallenge,
            });
            await sdk_core_1.ECDSAUtils.EcdsaUtils.getVerifyAndSignBitGoChallenges(bitgo, 'ent_id', userPassword).should.be.rejectedWith("Failed to verify BitGo's challenge needed to enable ECDSA signing. Please contact support@bitgo.com");
            nockGetBitgoChallengesApi.isDone().should.be.true();
        });
        it('Fails bitgo challenge proofs for faulty nitro h1WrtH2 proof', async function () {
            const nockGetBitgoChallengesApi = nockGetBitgoChallenges({
                bitgoNitroHsm: {
                    ...bitgoNitroChallenge,
                    ntildeProof: {
                        ...bitgoNitroChallenge.ntildeProof,
                        h1WrtH2: bitgoNitroChallenge.ntildeProof.h2WrtH1,
                    },
                },
                bitgoInstitutionalHsm: bitgoInstChallenge,
            });
            await sdk_core_1.ECDSAUtils.EcdsaUtils.getVerifyAndSignBitGoChallenges(bitgo, 'ent_id', userPassword).should.be.rejectedWith("Failed to verify BitGo's challenge needed to enable ECDSA signing. Please contact support@bitgo.com");
            nockGetBitgoChallengesApi.isDone().should.be.true();
        });
        it('Fails bitgo challenge proofs for faulty inst h2WrtH1 proof', async function () {
            const nockGetBitgoChallengesApi = nock(bgUrl)
                .get(`/api/v2/tss/ecdsa/challenges`)
                .times(1)
                .reply(200, {
                bitgoNitroHsm: bitgoNitroChallenge,
                bitgoInstitutionalHsm: {
                    ...bitgoInstChallenge,
                    ntildeProof: {
                        ...bitgoInstChallenge.ntildeProof,
                        h2WrtH1: bitgoInstChallenge.ntildeProof.h1WrtH2,
                    },
                },
            });
            await sdk_core_1.ECDSAUtils.EcdsaUtils.getVerifyAndSignBitGoChallenges(bitgo, 'ent_id', userPassword).should.be.rejectedWith("Failed to verify BitGo's challenge needed to enable ECDSA signing. Please contact support@bitgo.com");
            nockGetBitgoChallengesApi.isDone().should.be.true();
        });
        it('Fails bitgo challenge proofs for faulty inst h1WrtH2 proof', async function () {
            const nockGetBitgoChallengesApi = nock(bgUrl)
                .get(`/api/v2/tss/ecdsa/challenges`)
                .times(1)
                .reply(200, {
                bitgoNitroHsm: bitgoNitroChallenge,
                bitgoInstitutionalHsm: {
                    ...bitgoInstChallenge,
                    ntildeProof: {
                        ...bitgoInstChallenge.ntildeProof,
                        h1WrtH2: bitgoInstChallenge.ntildeProof.h2WrtH1,
                    },
                },
            });
            await sdk_core_1.ECDSAUtils.EcdsaUtils.getVerifyAndSignBitGoChallenges(bitgo, 'ent_id', userPassword).should.be.rejectedWith("Failed to verify BitGo's challenge needed to enable ECDSA signing. Please contact support@bitgo.com");
            nockGetBitgoChallengesApi.isDone().should.be.true();
        });
    });
    describe('supportedTxRequestVersions', function () {
        it('returns only full for hot wallets', function () {
            const hotWallet = new sdk_core_1.Wallet(bitgo, baseCoin, { type: 'hot', multisigType: 'tss' });
            const hotWalletTssUtils = new sdk_core_1.ECDSAUtils.EcdsaUtils(bitgo, baseCoin, hotWallet);
            hotWalletTssUtils.supportedTxRequestVersions().should.deepEqual(['full']);
        });
        it('returns only full for cold wallets', function () {
            const coldWallet = new sdk_core_1.Wallet(bitgo, baseCoin, {
                type: 'cold',
                multisigType: 'tss',
            });
            const coldWalletTssUtils = new sdk_core_1.ECDSAUtils.EcdsaUtils(bitgo, baseCoin, coldWallet);
            coldWalletTssUtils.supportedTxRequestVersions().should.deepEqual(['full']);
        });
        it('returns only full for custodial wallets', function () {
            const custodialWallet = new sdk_core_1.Wallet(bitgo, baseCoin, { type: 'custodial', multisigType: 'tss' });
            const custodialWalletTssUtils = new sdk_core_1.ECDSAUtils.EcdsaUtils(bitgo, baseCoin, custodialWallet);
            custodialWalletTssUtils.supportedTxRequestVersions().should.deepEqual(['full']);
        });
        it('returns empty for trading wallets', function () {
            const tradingWallet = new sdk_core_1.Wallet(bitgo, baseCoin, { type: 'trading', multisigType: 'tss' });
            const tradingWalletTssUtils = new sdk_core_1.ECDSAUtils.EcdsaUtils(bitgo, baseCoin, tradingWallet);
            tradingWalletTssUtils.supportedTxRequestVersions().should.deepEqual([]);
        });
        it('returns empty for non-tss wallets', function () {
            const nonTssWalletData = { coin: 'tbtc', multisigType: 'onchain' };
            const btcCoin = bitgo.coin('tbtc');
            const nonTssWallet = new sdk_core_1.Wallet(bitgo, btcCoin, nonTssWalletData);
            const nonTssWalletTssUtils = new src_1.TssUtils(bitgo, btcCoin, nonTssWallet);
            nonTssWalletTssUtils.supportedTxRequestVersions().should.deepEqual([]);
        });
    });
    describe('initiateChallengesForEnterprise', function () {
        const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
        const adminEcdhKey = bitgo.keychains().create();
        const derivationPath = 'm/0/0';
        const bitgoInstChallenge = ecdsaNtilde_1.mockChallengeA;
        const bitgoNitroChallenge = ecdsaNtilde_1.mockChallengeB;
        const serializedEntChallenge = ecdsaNtilde_1.mockChallengeC;
        const userPassword = 'password123';
        const encryptedXprv = bitgo.encrypt({
            password: userPassword,
            input: adminEcdhKey.xprv,
        });
        beforeEach(async function () {
            sinon.stub(bitgo, 'getSigningKeyForUser').resolves({
                userId: 'id',
                userEmail: 'user@bitgo.com',
                derivedPubkey: utxo_lib_1.bip32.fromBase58(adminEcdhKey.xpub).derivePath(derivationPath).publicKey.toString('hex'),
                derivationPath: derivationPath,
                ecdhKeychain: 'my keychain',
            });
            sinon.stub(bitgo, 'getECDHKeychain').resolves({
                encryptedXprv: encryptedXprv,
            });
        });
        afterEach(async function () {
            sinon.restore();
        });
        it('should upload challenge without generating if passed in', async function () {
            const stubUploadChallenge = sinon.stub(sdk_core_1.ECDSAUtils.EcdsaUtils, 'uploadChallengesToEnterprise');
            const deserializedEntChallenge = sdk_lib_mpc_1.EcdsaTypes.deserializeNtildeWithProofs(serializedEntChallenge);
            const signedEntChallenge = sdk_core_1.ECDSAUtils.EcdsaUtils.signChallenge(serializedEntChallenge, adminEcdhKey.xprv, derivationPath);
            const signedInstChallenge = sdk_core_1.ECDSAUtils.EcdsaUtils.signChallenge(bitgoInstChallenge, adminEcdhKey.xprv, derivationPath);
            const signedNitroChallenge = sdk_core_1.ECDSAUtils.EcdsaUtils.signChallenge(bitgoNitroChallenge, adminEcdhKey.xprv, derivationPath);
            await sdk_core_1.ECDSAUtils.EcdsaUtils.initiateChallengesForEnterprise(bitgo, 'ent_id', userPassword, signedInstChallenge, signedNitroChallenge, openSSLBytes, deserializedEntChallenge).should.not.be.rejected();
            stubUploadChallenge.calledWith(bitgo, 'ent_id', serializedEntChallenge, signedEntChallenge.toString('hex'), signedInstChallenge.toString('hex'), signedNitroChallenge.toString('hex'));
        });
        it('should generate a challenge and if one is not provided', async function () {
            const stubUploadChallenge = sinon.stub(sdk_core_1.ECDSAUtils.EcdsaUtils, 'uploadChallengesToEnterprise');
            const deserializedEntChallenge = sdk_lib_mpc_1.EcdsaTypes.deserializeNtildeWithProofs(serializedEntChallenge);
            sinon.stub(sdk_lib_mpc_1.EcdsaRangeProof, 'generateNtilde').resolves(deserializedEntChallenge);
            const signedEntChallenge = sdk_core_1.ECDSAUtils.EcdsaUtils.signChallenge(serializedEntChallenge, adminEcdhKey.xprv, derivationPath);
            const signedInstChallenge = sdk_core_1.ECDSAUtils.EcdsaUtils.signChallenge(bitgoInstChallenge, adminEcdhKey.xprv, derivationPath);
            const signedNitroChallenge = sdk_core_1.ECDSAUtils.EcdsaUtils.signChallenge(bitgoNitroChallenge, adminEcdhKey.xprv, derivationPath);
            await sdk_core_1.ECDSAUtils.EcdsaUtils.initiateChallengesForEnterprise(bitgo, 'ent_id', userPassword, signedInstChallenge, signedNitroChallenge, openSSLBytes).should.not.be.rejected();
            stubUploadChallenge.calledWith(bitgo, 'ent_id', serializedEntChallenge, signedEntChallenge.toString('hex'), signedInstChallenge.toString('hex'), signedNitroChallenge.toString('hex'));
        });
    });
    it('getMessageToSignFromChallenge concatenates the challenge values only', function () {
        const challenge = ecdsaNtilde_1.mockChallengeA;
        const expectedMessageToSign = challenge.ntilde.concat(challenge.h1).concat(challenge.h2);
        const message = sdk_core_1.ECDSAUtils.EcdsaUtils.getMessageToSignFromChallenge(challenge);
        message.should.equal(expectedMessageToSign);
    });
    describe('validateCommonKeychainPublicKey', function () {
        it('validateCommonKeychainPublicKey returns correct public key', function () {
            const commonKeychain = '03f40c70545b519bb7bbc7195fd4b7d5bbfc873bfd38b18596e4b47a05b6a88d552e2e8319cb31e279b99dbe54115a983d35e86679af96d81b7478d1df368f76a8';
            const expectedPubKeyResult = `f40c70545b519bb7bbc7195fd4b7d5bbfc873bfd38b18596e4b47a05b6a88d556a10d6ab8055dc0b3a9af9dc4e42f4f9773c590afcc298d017c1b1ce29a88041`;
            const actualPubKey = sdk_core_1.ECDSAUtils.EcdsaUtils.validateCommonKeychainPublicKey(commonKeychain);
            actualPubKey.should.equal(expectedPubKeyResult);
        });
        it('validateCommonKeychainPublicKey throws correctly with invalid length', function () {
            const commonKeychain = '03f40c70548';
            should(() => sdk_core_1.ECDSAUtils.EcdsaUtils.validateCommonKeychainPublicKey(commonKeychain)).throwError('Invalid commonKeychain length, expected 130, got 11');
        });
        it('validateCommonKeychainPublicKey throws correctly with invalid commonKeychain', function () {
            const commonKeychainWithInvalidCharacters = '!@#$^0c70545b519bb7bbc7195fd4b7d5bfc873bfd38b18596e4b47a05b6a88d552e2e8319cb31e279b99dbe54115a983d35e86679af96d81b7478d1df368f76a8'; // 129 chars
            should(() => sdk_core_1.ECDSAUtils.EcdsaUtils.validateCommonKeychainPublicKey(commonKeychainWithInvalidCharacters)).throwError(/^Invalid commonKeychain, error:/);
        });
    });
    // #region Nock helpers
    async function createIncompleteBitgoHeldBackupKeyShare(userGpgKey, backupKeyShare, bitgoGpgKey) {
        const nSharePromises = [
            encryptNShare(backupKeyShare, 1, userGpgKey.publicKey, userGpgKey, false),
            encryptNShare(backupKeyShare, 3, bitgoGpgKey.publicKey, userGpgKey, false),
        ];
        const backupToUserPublicShare = Buffer.concat([
            Buffer.from(backupKeyShare.nShares[1].y, 'hex'),
            Buffer.from(backupKeyShare.nShares[1].chaincode, 'hex'),
        ]).toString('hex');
        const backupToBitgoPublicShare = Buffer.concat([
            Buffer.from(backupKeyShare.nShares[3].y, 'hex'),
            Buffer.from(backupKeyShare.nShares[3].chaincode, 'hex'),
        ]).toString('hex');
        return {
            id: '4711',
            keyShares: [
                {
                    from: 'backup',
                    to: 'user',
                    publicShare: backupToUserPublicShare,
                    privateShare: (await nSharePromises[0]).encryptedPrivateShare,
                },
                {
                    from: 'backup',
                    to: 'bitgo',
                    publicShare: backupToBitgoPublicShare,
                    privateShare: (await nSharePromises[1]).encryptedPrivateShare,
                },
            ],
        };
    }
    async function nockGetBitgoPublicKeyBasedOnFeatureFlags(coin, enterpriseId, bitgoGpgKeyPair) {
        const bitgoGPGPublicKeyResponse = {
            name: 'irrelevant',
            publicKey: bitgoGpgKeyPair.publicKey,
            enterpriseId,
        };
        nock(bgUrl).get(`/api/v2/${coin}/tss/pubkey`).query({ enterpriseId }).reply(200, bitgoGPGPublicKeyResponse);
        return bitgoGPGPublicKeyResponse;
    }
    async function nockCreateBitgoHeldBackupKeyShare(coin, enterpriseId, userGpgKey, backupKeyShare, bitgoGpgKey) {
        const keyShare = await createIncompleteBitgoHeldBackupKeyShare(userGpgKey, backupKeyShare, bitgoGpgKey);
        nock(bgUrl)
            .post(`/api/v2/${coin}/krs/backupkeys`, _.matches({ enterprise: enterpriseId, userGPGPublicKey: userGpgKey.publicKey }))
            .reply(201, keyShare);
        return keyShare;
    }
    async function nockFinalizeBitgoHeldBackupKeyShare(coin, originalKeyShare, commonKeychain, userKeyShare, userLocalBackupGpgKey, bitgoKeychain) {
        const encryptedUserToBackupKeyShare = await encryptNShare(userKeyShare, 2, userLocalBackupGpgKey.publicKey, userGpgKey, false);
        assert(bitgoKeychain.keyShares);
        const bitgoToBackupKeyShare = bitgoKeychain.keyShares.find((keyShare) => keyShare.from === 'bitgo' && keyShare.to === 'backup');
        assert(bitgoToBackupKeyShare);
        const userPublicShare = Buffer.concat([
            Buffer.from(userKeyShare.nShares[2].y, 'hex'),
            Buffer.from(userKeyShare.nShares[2].chaincode, 'hex'),
        ]).toString('hex');
        const expectedKeyShares = [
            {
                from: 'user',
                to: 'backup',
                publicShare: userPublicShare,
                // Omitting the private share, the actual encryption happens inside the function where we make the matching call
                // to this nock. We cannot recreate the same encrypted value here because gpg encryption is not deterministic
            },
            bitgoToBackupKeyShare,
        ];
        const updatedKeyShare = {
            id: originalKeyShare.id,
            commonKeychain,
            keyShares: [
                ...originalKeyShare.keyShares,
                {
                    from: 'user',
                    to: 'backup',
                    publicShare: userPublicShare,
                    privateShare: encryptedUserToBackupKeyShare.encryptedPrivateShare,
                },
                bitgoToBackupKeyShare,
            ],
        };
        nock(bgUrl)
            .put(`/api/v2/${coin}/krs/backupkeys/${originalKeyShare.id}`, _.matches({ commonKeychain, keyShares: expectedKeyShares }))
            .reply(200, updatedKeyShare);
        return updatedKeyShare;
    }
    /**
     * Helper function to generate a bitgo keychain given the full set of keyshares and GPG keys.
     * Also mocks the wallet signatures added by the HSM.
     * @param params
     */
    async function generateBitgoKeychain(params) {
        const bitgoCombined = MPC.keyCombine(params.bitgoKeyShare.pShare, [
            params.userKeyShare.nShares[3],
            params.backupKeyShare.nShares[3],
        ]);
        const userGpgKeyActual = await openpgp.readKey({ armoredKey: params.userGpgKey.publicKey });
        const backupGpgKeyActual = await openpgp.readKey({ armoredKey: params.userLocalBackupGpgKey.publicKey });
        const nSharePromises = [
            encryptNShare(params.bitgoKeyShare, 1, params.userGpgKey.publicKey, params.userGpgKey, false),
            encryptNShare(params.bitgoKeyShare, 2, params.userLocalBackupGpgKey.publicKey, params.userLocalBackupGpgKey, false),
        ];
        const [userToBitgoShare, backupToBitgoShare] = await Promise.all(nSharePromises);
        const bitgoKeychain = {
            id: '3',
            pub: '',
            commonKeychain: bitgoCombined.xShare.y + bitgoCombined.xShare.chaincode,
            keyShares: [
                {
                    from: 'bitgo',
                    to: 'user',
                    publicShare: userToBitgoShare.publicShare,
                    privateShare: userToBitgoShare.encryptedPrivateShare,
                    n: userToBitgoShare.n,
                    vssProof: userToBitgoShare.vssProof,
                    privateShareProof: userToBitgoShare.privateShareProof,
                },
                {
                    from: 'bitgo',
                    to: 'backup',
                    publicShare: backupToBitgoShare.publicShare,
                    privateShare: backupToBitgoShare.encryptedPrivateShare,
                    n: backupToBitgoShare.n,
                    vssProof: backupToBitgoShare.vssProof,
                    privateShareProof: backupToBitgoShare.privateShareProof,
                },
            ],
            type: 'tss',
        };
        const userKeyId = userGpgKeyActual.keyPacket.getFingerprint();
        const backupKeyId = backupGpgKeyActual.keyPacket.getFingerprint();
        const bitgoToUserPublicU = Buffer.from(utxo_lib_1.ecc.pointFromScalar(Buffer.from(params.bitgoKeyShare.nShares[1].u, 'hex'), true)).toString('hex') + params.bitgoKeyShare.nShares[1].chaincode;
        const bitgoToBackupPublicU = Buffer.from(utxo_lib_1.ecc.pointFromScalar(Buffer.from(params.bitgoKeyShare.nShares[2].u, 'hex'), true)).toString('hex') + params.bitgoKeyShare.nShares[2].chaincode;
        bitgoKeychain.walletHSMGPGPublicKeySigs = await (0, helpers_1.createWalletSignatures)(params.bitgoGpgKey.privateKey, params.userGpgKey.publicKey, params.userLocalBackupGpgKey.publicKey, [
            { name: 'commonKeychain', value: bitgoCombined.xShare.y + bitgoCombined.xShare.chaincode },
            { name: 'userKeyId', value: userKeyId },
            { name: 'backupKeyId', value: backupKeyId },
            { name: 'bitgoToUserPublicShare', value: bitgoToUserPublicU },
            { name: 'bitgoToBackupPublicShare', value: bitgoToBackupPublicU },
        ]);
        return bitgoKeychain;
    }
    async function nockBitgoKeychain(params) {
        const bitgoKeychain = await generateBitgoKeychain(params);
        nock(bgUrl)
            .persist()
            .post(`/api/v2/${params.coin}/key`, _.matches({ keyType: 'tss', source: 'bitgo' }))
            .reply(200, bitgoKeychain);
        return bitgoKeychain;
    }
    async function nockKeychain(params) {
        nock('https://bitgo.fakeurl')
            .persist()
            .post(`/api/v2/${params.coin}/key`, _.matches({ keyType: 'tss', source: params.source }))
            .reply(200, params.keyChain);
        return params.keyChain;
    }
    // #endregion Nock helpers
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWNkc2EuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi90ZXN0L3YyL3VuaXQvaW50ZXJuYWwvdHNzVXRpbHMvZWNkc2EudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxpQ0FBaUM7QUFDakMsNEJBQTRCO0FBQzVCLDZCQUE2QjtBQUM3QixtQ0FBbUM7QUFDbkMsaUNBQWlDO0FBQ2pDLCtCQUErQjtBQUUvQiw4Q0FLeUI7QUFDekIsNENBQXlGO0FBQ3pGLDhDQWtCeUI7QUFDekIsb0RBQWtHO0FBQ2xHLHVFQUFnRjtBQUNoRixxQ0FBOEQ7QUFDOUQsK0NBTzJCO0FBQzNCLDhDQUE2QztBQUU3QyxxREFBcUY7QUFFckYsOERBQTBEO0FBRTFELE1BQU0sWUFBWSxHQUFHLElBQUEsa0NBQWUsR0FBRSxDQUFDLE1BQU0sQ0FBQztBQUU5QyxNQUFNLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUUzQyxNQUFNLGFBQWEsR0FBRyx1QkFBWSxDQUFDLGFBQWEsQ0FBQztBQUdqRCxPQUFPLENBQUMsTUFBTSxDQUFDLFlBQVksR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO0FBRXhDLFFBQVEsQ0FBQyxrQkFBa0IsRUFBRSxLQUFLO0lBQ2hDLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQztJQUN6QixNQUFNLEtBQUssR0FBRyxJQUFJLHdCQUFhLEVBQUUsQ0FBQztJQUNsQyxNQUFNLFFBQVEsR0FBRyxrQ0FBa0MsQ0FBQztJQUNwRCxNQUFNLFlBQVksR0FBRyxrQ0FBa0MsQ0FBQztJQUN4RCxNQUFNLGNBQWMsR0FBRyxFQUFFLEVBQUUsRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLGlCQUFpQixFQUFFLENBQUM7SUFFckUsSUFBSSxPQUEyQixDQUFDO0lBQ2hDLElBQUksR0FBVSxDQUFDO0lBQ2YsSUFBSSxLQUFhLENBQUM7SUFDbEIsSUFBSSxRQUErQixDQUFDO0lBQ3BDLElBQUksTUFBYyxDQUFD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QWEsQ0FBQztJQUN2QixDQUFDO0lBRUQsS0FBSyxVQUFVLGlCQUFpQixDQUFDLE1BUWhDO1FBQ0MsTUFBTSxhQUFhLEdBQUcsTUFBTSxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUUxRCxJQUFJLENBQUMsS0FBSyxDQUFDO2FBQ1IsT0FBTyxFQUFFO2FBQ1QsSUFBSSxDQUFDLFdBQVcsTUFBTSxDQUFDLElBQUksTUFBTSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO2FBQ2xGLEtBQUssQ0FBQyxHQUFHLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFFN0IsT0FBTyxhQUFhLENBQUM7SUFDdkIsQ0FBQztJQUVELEtBQUssVUFBVSxZQUFZLENBQUMsTUFJM0I7UUFDQyxJQUFJLENBQUMsdUJBQXVCLENBQUM7YUFDMUIsT0FBTyxFQUFFO2FBQ1QsSUFBSSxDQUFDLFdBQVcsTUFBTSxDQUFDLElBQUksTUFBTSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQzthQUN4RixLQUFLLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUUvQixPQUFPLE1BQU0sQ0FBQyxRQUFRLENBQUM7SUFDekIsQ0FBQztJQUNELDBCQUEwQjtBQUM1QixDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0ICogYXMgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0ICogYXMgbm9jayBmcm9tICdub2NrJztcbmltcG9ydCAqIGFzIG9wZW5wZ3AgZnJvbSAnb3BlbnBncCc7XG5pbXBvcnQgKiBhcyBzaG91bGQgZnJvbSAnc2hvdWxkJztcbmltcG9ydCAqIGFzIHNpbm9uIGZyb20gJ3Npbm9uJztcblxuaW1wb3J0IHtcbiAgbW9ja1NlcmlhbGl6ZWRDaGFsbGVuZ2VXaXRoUHJvb2ZzLFxuICBtb2NrU2VyaWFsaXplZENoYWxsZW5nZVdpdGhQcm9vZnMyLFxuICBUZXN0YWJsZUJHLFxuICBUZXN0Qml0R28sXG59IGZyb20gJ0BiaXRnby9zZGstdGVzdCc7XG5pbXBvcnQgeyBCaXRHbywgY3JlYXRlU2hhcmVkRGF0YVByb29mLCBUc3NVdGlscywgUmVxdWVzdFR5cGUgfSBmcm9tICcuLi8uLi8uLi8uLi8uLi9zcmMnO1xuaW1wb3J0IHtcbiAgQmFja3VwR3BnS2V5LFxuICBCYWNrdXBLZXlTaGFyZSxcbiAgQmFzZUNvaW4sXG4gIEJpdGdvR1BHUHVibGljS2V5LFxuICBCaXRnb0hlbGRCYWNrdXBLZXlTaGFyZSxcbiAgY29tbW9uLFxuICBFY2RzYSxcbiAgRUNEU0EsXG4gIEVDRFNBTWV0aG9kcyxcbiAgRUNEU0FVdGlscyxcbiAgRW50ZXJwcmlzZURhdGEsXG4gIEtleWNoYWluLFxuICBSZXF1ZXN0VHJhY2VyLFxuICBTaWduYXR1cmVTaGFyZVJlY29yZCxcbiAgU2lnbmF0dXJlU2hhcmVUeXBlLFxuICBUeFJlcXVlc3QsXG4gIFdhbGxldCxcbn0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCB7IEVjZHNhUGFpbGxpZXJQcm9vZiwgRWNkc2FSYW5nZVByb29mLCBFY2RzYVR5cGVzLCBoZXhUb0JpZ0ludCB9IGZyb20gJ0BiaXRnby9zZGstbGliLW1wYyc7XG5pbXBvcnQgeyBrZXlTaGFyZXMsIG90aGVyS2V5U2hhcmVzIH0gZnJvbSAnLi4vLi4vLi4vZml4dHVyZXMvdHNzL2VjZHNhRml4dHVyZXMnO1xuaW1wb3J0IHsgbm9ja1NlbmRTaWduYXR1cmVTaGFyZVdpdGhSZXNwb25zZSB9IGZyb20gJy4vY29tbW9uJztcbmltcG9ydCB7XG4gIGNyZWF0ZVdhbGxldFNpZ25hdHVyZXMsXG4gIG5vY2tHZXRDaGFsbGVuZ2UsXG4gIG5vY2tHZXRDaGFsbGVuZ2VzLFxuICBub2NrR2V0RW50ZXJwcmlzZSxcbiAgbm9ja0dldFNpZ25pbmdLZXksXG4gIG5vY2tHZXRUeFJlcXVlc3QsXG59IGZyb20gJy4uLy4uL3Rzcy9oZWxwZXJzJztcbmltcG9ydCB7IGJpcDMyLCBlY2MgfSBmcm9tICdAYml0Z28vdXR4by1saWInO1xuaW1wb3J0IHsgSGFzaCB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBtb2NrQ2hhbGxlbmdlQSwgbW9ja0NoYWxsZW5nZUIsIG1vY2tDaGFsbGVuZ2VDIH0gZnJvbSAnLi9tb2Nrcy9lY2RzYU50aWxkZSc7XG5cbmltcG9ydCB7IGxvYWRXZWJBc3NlbWJseSB9IGZyb20gJ0BiaXRnby9zZGstb3BlbnNzbGJ5dGVzJztcblxuY29uc3Qgb3BlblNTTEJ5dGVzID0gbG9hZFdlYkFzc2VtYmx5KCkuYnVmZmVyO1xuXG5jb25zdCBjcmVhdGVLZWNjYWtIYXNoID0gcmVxdWlyZSgna2VjY2FrJyk7XG5cbmNvbnN0IGVuY3J5cHROU2hhcmUgPSBFQ0RTQU1ldGhvZHMuZW5jcnlwdE5TaGFyZTtcbnR5cGUgS2V5U2hhcmUgPSBFQ0RTQS5LZXlTaGFyZTtcblxub3BlbnBncC5jb25maWcucmVqZWN0Q3VydmVzID0gbmV3IFNldCgpO1xuXG5kZXNjcmliZSgnVFNTIEVjZHNhIFV0aWxzOicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgY29pbk5hbWUgPSAnaHRldGgnO1xuICBjb25zdCByZXFJZCA9IG5ldyBSZXF1ZXN0VHJhY2VyKCk7XG4gIGNvbnN0IHdhbGxldElkID0gJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYTAwMDAwMDAwJztcbiAgY29uc3QgZW50ZXJwcmlzZUlkID0gJzY0NDkxNTNhNmY2YmMyMDAwNmQ2Njc3MWNkYmUxNWQzJztcbiAgY29uc3QgZW50ZXJwcmlzZURhdGEgPSB7IGlkOiBlbnRlcnByaXNlSWQsIG5hbWU6ICdUZXN0IEVudGVycHJpc2UnIH07XG5cbiAgbGV0IHNhbmRib3g6IHNpbm9uLlNpbm9uU2FuZGJveDtcbiAgbGV0IE1QQzogRWNkc2E7XG4gIGxldCBiZ1VybDogc3RyaW5nO1xuICBsZXQgdHNzVXRpbHM6IEVDRFNBVXRpbHMuRWNkc2FVdGlscztcbiAgbGV0IHdhbGxldDogV2FsbGV0O1xuICBsZXQgYml0Z286IFRlc3RhYmxlQkcgJiBCaXRHbztcbiAgbGV0IGJhc2VDb2luOiBCYXNlQ29pbjtcbiAgbGV0IGJpdGdvS2V5U2hhcmU7XG4gIGxldCB1c2VyS2V5U2hhcmU6IEtleVNoYXJlO1xuICBsZXQgYmFja3VwS2V5U2hhcmU6IEtleVNoYXJlO1xuICBsZXQgYml0Z29QdWJsaWNLZXk6IG9wZW5wZ3AuS2V5O1xuXG4gIGxldCB1c2VyR3BnS2V5OiBvcGVucGdwLlNlcmlhbGl6ZWRLZXlQYWlyPHN0cmluZz4gJiB7XG4gICAgcmV2b2NhdGlvbkNlcnRpZmljYXRlOiBzdHJpbmc7XG4gIH07XG4gIGxldCB1c2VyTG9jYWxCYWNrdXBHcGdLZXk6IG9wZW5wZ3AuU2VyaWFsaXplZEtleVBhaXI8c3RyaW5nPiAmIHtcbiAgICByZXZvY2F0aW9uQ2VydGlmaWNhdGU6IHN0cmluZztcbiAgfTtcbiAgbGV0IGJpdEdvR1BHS2V5UGFpcjogb3BlbnBncC5TZXJpYWxpemVkS2V5UGFpcjxzdHJpbmc+ICYge1xuICAgIHJldm9jYXRpb25DZXJ0aWZpY2F0ZTogc3RyaW5nO1xuICB9O1xuICBsZXQgbm9ja2VkQml0R29LZXljaGFpbjogS2V5Y2hhaW47XG4gIGxldCBub2NrZWRVc2VyS2V5Y2hhaW46IEtleWNoYWluO1xuXG4gIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gIH0pO1xuXG4gIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgc2FuZGJveC5yZXN0b3JlKCk7XG4gIH0pO1xuXG4gIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIE1QQyA9IG5ldyBFY2RzYSgpO1xuICAgIHVzZXJLZXlTaGFyZSA9IGtleVNoYXJlcy51c2VyS2V5U2hhcmU7XG4gICAgYmFja3VwS2V5U2hhcmUgPSBrZXlTaGFyZXMuYmFja3VwS2V5U2hhcmU7XG4gICAgYml0Z29LZXlTaGFyZSA9IGtleVNoYXJlcy5iaXRnb0tleVNoYXJlO1xuXG4gICAgY29uc3QgZ3BnS2V5UHJvbWlzZXMgPSBbXG4gICAgICBvcGVucGdwLmdlbmVyYXRlS2V5KHtcbiAgICAgICAgdXNlcklEczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICd0ZXN0JyxcbiAgICAgICAgICAgIGVtYWlsOiAndGVzdEB0ZXN0LmNvbScsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgY3VydmU6ICdzZWNwMjU2azEnLFxuICAgICAgfSksXG4gICAgICBvcGVucGdwLmdlbmVyYXRlS2V5KHtcbiAgICAgICAgdXNlcklEczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICdiYWNrdXAnLFxuICAgICAgICAgICAgZW1haWw6ICdiYWNrdXBAdGVzdC5jb20nLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGN1cnZlOiAnc2VjcDI1NmsxJyxcbiAgICAgIH0pLFxuICAgICAgb3BlbnBncC5nZW5lcmF0ZUtleSh7XG4gICAgICAgIHVzZXJJRHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBuYW1lOiAnYml0Z28nLFxuICAgICAgICAgICAgZW1haWw6ICdiaXRnb0B0ZXN0LmNvbScsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgY3VydmU6ICdzZWNwMjU2azEnLFxuICAgICAgfSksXG4gICAgXTtcbiAgICBbdXNlckdwZ0tleSwgdXNlckxvY2FsQmFja3VwR3BnS2V5LCBiaXRHb0dQR0tleVBhaXJdID0gYXdhaXQgUHJvbWlzZS5hbGwoZ3BnS2V5UHJvbWlzZXMpO1xuICAgIGJpdGdvUHVibGljS2V5ID0gYXdhaXQgb3BlbnBncC5yZWFkS2V5KHsgYXJtb3JlZEtleTogYml0R29HUEdLZXlQYWlyLnB1YmxpY0tleSB9KTtcbiAgICBjb25zdCBjb25zdGFudHMgPSB7XG4gICAgICBtcGM6IHtcbiAgICAgICAgYml0Z29QdWJsaWNLZXk6IGJpdEdvR1BHS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICB9LFxuICAgIH07XG5cbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcblxuICAgIGJhc2VDb2luID0gYml0Z28uY29pbihjb2luTmFtZSk7XG5cbiAgICBiZ1VybCA9IGNvbW1vbi5FbnZpcm9ubWVudHNbYml0Z28uZ2V0RW52KCldLnVyaTtcblxuICAgIC8vIFRPRE8oV1AtMzQ2KTogc2RrLXRlc3QgbW9ja3MgY29uZmxpY3Qgc28gd2UgY2FuJ3QgdXNlIHBlcnNpc3RcbiAgICBub2NrKGJnVXJsKS5nZXQoJy9hcGkvdjEvY2xpZW50L2NvbnN0YW50cycpLnRpbWVzKDE2KS5yZXBseSgyMDAsIHsgdHRsOiAzNjAwLCBjb25zdGFudHMgfSk7XG5cbiAgICBjb25zdCBub2NrUHJvbWlzZXMgPSBbXG4gICAgICBub2NrQml0Z29LZXljaGFpbih7XG4gICAgICAgIGNvaW46IGNvaW5OYW1lLFxuICAgICAgICB1c2VyS2V5U2hhcmUsXG4gICAgICAgIGJhY2t1cEtleVNoYXJlLFxuICAgICAgICBiaXRnb0tleVNoYXJlLFxuICAgICAgICB1c2VyR3BnS2V5LFxuICAgICAgICB1c2VyTG9jYWxCYWNrdXBHcGdLZXksXG4gICAgICAgIGJpdGdvR3BnS2V5OiBiaXRHb0dQR0tleVBhaXIsXG4gICAgICB9KSxcbiAgICAgIG5vY2tLZXljaGFpbih7IGNvaW46IGNvaW5OYW1lLCBrZXlDaGFpbjogeyBpZDogJzEnLCBwdWI6ICcnLCB0eXBlOiAndHNzJyB9LCBzb3VyY2U6ICd1c2VyJyB9KSxcbiAgICAgIG5vY2tLZXljaGFpbih7IGNvaW46IGNvaW5OYW1lLCBrZXlDaGFpbjogeyBpZDogJzInLCBwdWI6ICcnLCB0eXBlOiAndHNzJyB9LCBzb3VyY2U6ICdiYWNrdXAnIH0pLFxuICAgIF07XG4gICAgW25vY2tlZEJpdEdvS2V5Y2hhaW4sIG5vY2tlZFVzZXJLZXljaGFpbl0gPSBhd2FpdCBQcm9taXNlLmFsbChub2NrUHJvbWlzZXMpO1xuXG4gICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgIGlkOiB3YWxsZXRJZCxcbiAgICAgIGVudGVycHJpc2U6IGVudGVycHJpc2VJZCxcbiAgICAgIGNvaW46IGNvaW5OYW1lLFxuICAgICAgY29pblNwZWNpZmljOiB7fSxcbiAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgfTtcbiAgICB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlQ29pbiwgd2FsbGV0RGF0YSk7XG4gICAgdHNzVXRpbHMgPSBuZXcgRUNEU0FVdGlscy5FY2RzYVV0aWxzKGJpdGdvLCBiYXNlQ29pbiwgd2FsbGV0KTtcbiAgfSk7XG5cbiAgYWZ0ZXIoZnVuY3Rpb24gKCkge1xuICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1RTUyBrZXkgY2hhaW5zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY3JlYXRlIGJhY2t1cCBrZXkgc2hhcmUgaGVsZCBieSBCaXRHbycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGVudGVycHJpc2VJZCA9ICdlbnRlcnByaXNlIGlkJztcbiAgICAgIGNvbnN0IGV4cGVjdGVkS2V5U2hhcmUgPSBhd2FpdCBub2NrQ3JlYXRlQml0Z29IZWxkQmFja3VwS2V5U2hhcmUoXG4gICAgICAgIGNvaW5OYW1lLFxuICAgICAgICBlbnRlcnByaXNlSWQsXG4gICAgICAgIHVzZXJHcGdLZXksXG4gICAgICAgIGJhY2t1cEtleVNoYXJlLFxuICAgICAgICBiaXRHb0dQR0tleVBhaXJcbiAgICAgICk7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0c3NVdGlscy5jcmVhdGVCaXRnb0hlbGRCYWNrdXBLZXlTaGFyZSh1c2VyR3BnS2V5LCBlbnRlcnByaXNlSWQpO1xuICAgICAgcmVzdWx0LnNob3VsZC5lcWwoZXhwZWN0ZWRLZXlTaGFyZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZpbmFsaXplIGJhY2t1cCBrZXkgc2hhcmUgaGVsZCBieSBCaXRHbycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvbW1vbktleWNoYWluID0gJzQ0MjgnO1xuICAgICAgY29uc3Qgb3JpZ2luYWxLZXlTaGFyZSA9IGF3YWl0IGNyZWF0ZUluY29tcGxldGVCaXRnb0hlbGRCYWNrdXBLZXlTaGFyZShcbiAgICAgICAgdXNlckdwZ0tleSxcbiAgICAgICAgYmFja3VwS2V5U2hhcmUsXG4gICAgICAgIGJpdEdvR1BHS2V5UGFpclxuICAgICAgKTtcbiAgICAgIGNvbnN0IGV4cGVjdGVkRmluYWxLZXlTaGFyZSA9IGF3YWl0IG5vY2tGaW5hbGl6ZUJpdGdvSGVsZEJhY2t1cEtleVNoYXJlKFxuICAgICAgICBjb2luTmFtZSxcbiAgICAgICAgb3JpZ2luYWxLZXlTaGFyZSxcbiAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgIHVzZXJLZXlTaGFyZSxcbiAgICAgICAgYml0R29HUEdLZXlQYWlyLFxuICAgICAgICBub2NrZWRCaXRHb0tleWNoYWluXG4gICAgICApO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0c3NVdGlscy5maW5hbGl6ZUJpdGdvSGVsZEJhY2t1cEtleVNoYXJlKFxuICAgICAgICBvcmlnaW5hbEtleVNoYXJlLmlkLFxuICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgdXNlcktleVNoYXJlLFxuICAgICAgICBub2NrZWRCaXRHb0tleWNoYWluLFxuICAgICAgICB1c2VyR3BnS2V5LFxuICAgICAgICBiaXRnb1B1YmxpY0tleVxuICAgICAgKTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXFsKGV4cGVjdGVkRmluYWxLZXlTaGFyZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdldCB0aGUgcmVzcGVjdGl2ZSBiYWNrdXAga2V5IHNoYXJlcyBiYXNlZCBvbiBwcm92aWRlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGVudGVycHJpc2VJZCA9ICdlbnRlcnByaXNlIGlkJztcbiAgICAgIGF3YWl0IG5vY2tDcmVhdGVCaXRnb0hlbGRCYWNrdXBLZXlTaGFyZShjb2luTmFtZSwgZW50ZXJwcmlzZUlkLCB1c2VyR3BnS2V5LCBiYWNrdXBLZXlTaGFyZSwgYml0R29HUEdLZXlQYWlyKTtcbiAgICAgIGNvbnN0IGJhY2t1cEtleVNoYXJlcyA9IGF3YWl0IHRzc1V0aWxzLmNyZWF0ZUJhY2t1cEtleVNoYXJlcygpO1xuICAgICAgc2hvdWxkLmV4aXN0KGJhY2t1cEtleVNoYXJlcy51c2VySGVsZEtleVNoYXJlKTtcbiAgICAgIHNob3VsZC5ub3QuZXhpc3QoYmFja3VwS2V5U2hhcmVzLmJpdEdvSGVsZEtleVNoYXJlcyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdldCB0aGUgY29ycmVjdCBiaXRnbyBncGcga2V5IGJhc2VkIG9uIGNvaW4gYW5kIGZlYXR1cmUgZmxhZ3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBuaXRyb0dQR0tleXBhaXIgPSBhd2FpdCBvcGVucGdwLmdlbmVyYXRlS2V5KHtcbiAgICAgICAgdXNlcklEczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICdiaXRnbyBuaXRybycsXG4gICAgICAgICAgICBlbWFpbDogJ2JpdGdvQHRlc3QuY29tJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBub2NrR1BHS2V5ID0gYXdhaXQgbm9ja0dldEJpdGdvUHVibGljS2V5QmFzZWRPbkZlYXR1cmVGbGFncyhjb2luTmFtZSwgJ2VudGVycHJpc2VfaWQnLCBuaXRyb0dQR0tleXBhaXIpO1xuICAgICAgY29uc3QgYml0Z29HcGdQdWJsaWNLZXkgPSBhd2FpdCB0c3NVdGlscy5nZXRCaXRnb0dwZ1B1YmtleUJhc2VkT25GZWF0dXJlRmxhZ3MoJ2VudGVycHJpc2VfaWQnKTtcbiAgICAgIHNob3VsZC5lcXVhbChub2NrR1BHS2V5LnB1YmxpY0tleSwgYml0Z29HcGdQdWJsaWNLZXkuYXJtb3IoKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnZ2V0QmFja3VwRW5jcnlwdGVkTlNoYXJlIHNob3VsZCBnZXQgdmFsaWQgZW5jcnlwdGVkIG4gc2hhcmVzIGJhc2VkIG9uIHByb3ZpZGVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYml0Z29HcGdLZXlQdWJLZXkgPSBhd2FpdCB0c3NVdGlscy5nZXRCaXRnb1B1YmxpY0dwZ0tleSgpO1xuICAgICAgLy8gQmFja3VwIGtleSBoZWxkIGJ5IHVzZXJcbiAgICAgIGNvbnN0IGJhY2t1cFNoYXJlSG9sZGVyTmV3OiBCYWNrdXBLZXlTaGFyZSA9IHtcbiAgICAgICAgdXNlckhlbGRLZXlTaGFyZTogYmFja3VwS2V5U2hhcmUsXG4gICAgICB9O1xuICAgICAgY29uc3QgYmFja3VwVG9CaXRnb0VuY3J5cHRlZE5TaGFyZSA9IGF3YWl0IHRzc1V0aWxzLmdldEJhY2t1cEVuY3J5cHRlZE5TaGFyZShcbiAgICAgICAgYmFja3VwU2hhcmVIb2xkZXJOZXcsXG4gICAgICAgIDMsXG4gICAgICAgIGJpdGdvR3BnS2V5UHViS2V5LmFybW9yKCksXG4gICAgICAgIHVzZXJHcGdLZXlcbiAgICAgICk7XG4gICAgICBjb25zdCBlbmNyeXB0ZWROU2hhcmUgPSBhd2FpdCBlbmNyeXB0TlNoYXJlKGJhY2t1cEtleVNoYXJlLCAzLCBiaXRnb0dwZ0tleVB1YktleS5hcm1vcigpLCB1c2VyR3BnS2V5KTtcbiAgICAgIC8vIGNhbnQgdmVyaWZ5IHRoZSBlbmNyeXB0ZWQgc2hhcmVzLCBzaW5jZSB0aGV5IHdpbGwgYmUgZW5jcnlwdGVkIHdpdGggZGlmZi4gdmFsdWVzXG4gICAgICBzaG91bGQuZXF1YWwoYmFja3VwVG9CaXRnb0VuY3J5cHRlZE5TaGFyZS5wdWJsaWNTaGFyZSwgZW5jcnlwdGVkTlNoYXJlLnB1YmxpY1NoYXJlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgVFNTIGtleSBjaGFpbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiYWNrdXBTaGFyZUhvbGRlcjogQmFja3VwS2V5U2hhcmUgPSB7XG4gICAgICAgIHVzZXJIZWxkS2V5U2hhcmU6IGJhY2t1cEtleVNoYXJlLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGJhY2t1cEdwZ0tleTogQmFja3VwR3BnS2V5ID0gdXNlckxvY2FsQmFja3VwR3BnS2V5O1xuICAgICAgY29uc3QgYml0Z29LZXljaGFpbiA9IGF3YWl0IHRzc1V0aWxzLmNyZWF0ZUJpdGdvS2V5Y2hhaW4oe1xuICAgICAgICB1c2VyR3BnS2V5LFxuICAgICAgICBiYWNrdXBHcGdLZXksXG4gICAgICAgIHVzZXJLZXlTaGFyZSxcbiAgICAgICAgYmFja3VwS2V5U2hhcmU6IGJhY2t1cFNoYXJlSG9sZGVyLFxuICAgICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29QdWJsaWNLZXksXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHVzZXJzS2V5Q2hhaW5Qcm9taXNlcyA9IFtcbiAgICAgICAgdHNzVXRpbHMuY3JlYXRlUGFydGljaXBhbnRLZXljaGFpbihcbiAgICAgICAgICB1c2VyR3BnS2V5LFxuICAgICAgICAgIHVzZXJMb2NhbEJhY2t1cEdwZ0tleSxcbiAgICAgICAgICBiaXRnb1B1YmxpY0tleSxcbiAgICAgICAgICAxLFxuICAgICAgICAgIHVzZXJLZXlTaGFyZSxcbiAgICAgICAgICBiYWNrdXBLZXlTaGFyZSxcbiAgICAgICAgICBiaXRnb0tleWNoYWluLFxuICAgICAgICAgICdwYXNzcGhyYXNlJ1xuICAgICAgICApLFxuICAgICAgICB0c3NVdGlscy5jcmVhdGVQYXJ0aWNpcGFudEtleWNoYWluKFxuICAgICAgICAgIHVzZXJHcGdLZXksXG4gICAgICAgICAgdXNlckxvY2FsQmFja3VwR3BnS2V5LFxuICAgICAgICAgIGJpdGdvUHVibGljS2V5LFxuICAgICAgICAgIDIsXG4gICAgICAgICAgdXNlcktleVNoYXJlLFxuICAgICAgICAgIGJhY2t1cEtleVNoYXJlLFxuICAgICAgICAgIGJpdGdvS2V5Y2hhaW4sXG4gICAgICAgICAgJ3Bhc3NwaHJhc2UnXG4gICAgICAgICksXG4gICAgICBdO1xuICAgICAgY29uc3QgW3VzZXJLZXljaGFpbiwgYmFja3VwS2V5Y2hhaW5dID0gYXdhaXQgUHJvbWlzZS5hbGwodXNlcnNLZXlDaGFpblByb21pc2VzKTtcblxuICAgICAgYml0Z29LZXljaGFpbi5zaG91bGQuZGVlcEVxdWFsKG5vY2tlZEJpdEdvS2V5Y2hhaW4pO1xuICAgICAgdXNlcktleWNoYWluLnNob3VsZC5kZWVwRXF1YWwobm9ja2VkVXNlcktleWNoYWluKTtcblxuICAgICAgLy8gdW5lbmNyeXB0ZWQgYHBydmAgcHJvcGVydHkgc2hvdWxkIGV4aXN0IG9uIGJhY2t1cCBrZXljaGFpblxuICAgICAgY29uc3Qga2V5Q2hhaW5QcnYgPSBKU09OLnBhcnNlKGJhY2t1cEtleWNoYWluLnBydiA/PyAnJyk7XG4gICAgICBfLmlzRXF1YWwoa2V5Q2hhaW5QcnYucFNoYXJlLCBiYWNrdXBLZXlTaGFyZS5wU2hhcmUpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBfLmlzRXF1YWwoa2V5Q2hhaW5QcnYuYml0Z29OU2hhcmUsIGJpdGdvS2V5U2hhcmUublNoYXJlc1syXSkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIF8uaXNFcXVhbChrZXlDaGFpblBydi51c2VyTlNoYXJlLCB1c2VyS2V5U2hhcmUublNoYXJlc1syXSkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIHNob3VsZC5leGlzdChiYWNrdXBLZXljaGFpbi5lbmNyeXB0ZWRQcnYpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBUU1Mga2V5IGNoYWlucyB3aXRoIG9wdGlvbmFsIHBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGVudGVycHJpc2UgPSAnZW50ZXJwcmlzZV9pZCc7XG4gICAgICBjb25zdCBiYWNrdXBTaGFyZUhvbGRlcjogQmFja3VwS2V5U2hhcmUgPSB7XG4gICAgICAgIHVzZXJIZWxkS2V5U2hhcmU6IGJhY2t1cEtleVNoYXJlLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGJhY2t1cEdwZ0tleTogQmFja3VwR3BnS2V5ID0gdXNlckxvY2FsQmFja3VwR3BnS2V5O1xuICAgICAgY29uc3QgYml0Z29LZXljaGFpbiA9IGF3YWl0IHRzc1V0aWxzLmNyZWF0ZUJpdGdvS2V5Y2hhaW4oe1xuICAgICAgICB1c2VyR3BnS2V5LFxuICAgICAgICBiYWNrdXBHcGdLZXksXG4gICAgICAgIHVzZXJLZXlTaGFyZSxcbiAgICAgICAgYmFja3VwS2V5U2hhcmU6IGJhY2t1cFNoYXJlSG9sZGVyLFxuICAgICAgICBlbnRlcnByaXNlLFxuICAgICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29QdWJsaWNLZXksXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHVzZXJzS2V5Q2hhaW5Qcm9taXNlcyA9IFtcbiAgICAgICAgdHNzVXRpbHMuY3JlYXRlUGFydGljaXBhbnRLZXljaGFpbihcbiAgICAgICAgICB1c2VyR3BnS2V5LFxuICAgICAgICAgIHVzZXJMb2NhbEJhY2t1cEdwZ0tleSxcbiAgICAgICAgICBiaXRnb1B1YmxpY0tleSxcbiAgICAgICAgICAxLFxuICAgICAgICAgIHVzZXJLZXlTaGFyZSxcbiAgICAgICAgICBiYWNrdXBLZXlTaGFyZSxcbiAgICAgICAgICBiaXRnb0tleWNoYWluLFxuICAgICAgICAgICdwYXNzcGhyYXNlJyxcbiAgICAgICAgICAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJ1xuICAgICAgICApLFxuICAgICAgICB0c3NVdGlscy5jcmVhdGVQYXJ0aWNpcGFudEtleWNoYWluKFxuICAgICAgICAgIHVzZXJHcGdLZXksXG4gICAgICAgICAgdXNlckxvY2FsQmFja3VwR3BnS2V5LFxuICAgICAgICAgIGJpdGdvUHVibGljS2V5LFxuICAgICAgICAgIDIsXG4gICAgICAgICAgdXNlcktleVNoYXJlLFxuICAgICAgICAgIGJhY2t1cEtleVNoYXJlLFxuICAgICAgICAgIGJpdGdvS2V5Y2hhaW4sXG4gICAgICAgICAgJ3Bhc3NwaHJhc2UnXG4gICAgICAgICksXG4gICAgICBdO1xuXG4gICAgICBjb25zdCBbdXNlcktleWNoYWluLCBiYWNrdXBLZXljaGFpbl0gPSBhd2FpdCBQcm9taXNlLmFsbCh1c2Vyc0tleUNoYWluUHJvbWlzZXMpO1xuICAgICAgYml0Z29LZXljaGFpbi5zaG91bGQuZGVlcEVxdWFsKG5vY2tlZEJpdEdvS2V5Y2hhaW4pO1xuICAgICAgdXNlcktleWNoYWluLnNob3VsZC5kZWVwRXF1YWwobm9ja2VkVXNlcktleWNoYWluKTtcblxuICAgICAgLy8gdW5lbmNyeXB0ZWQgYHBydmAgcHJvcGVydHkgc2hvdWxkIGV4aXN0IG9uIGJhY2t1cCBrZXljaGFpblxuICAgICAgY29uc3Qga2V5Q2hhaW5QcnYgPSBKU09OLnBhcnNlKGJhY2t1cEtleWNoYWluLnBydiA/PyAnJyk7XG4gICAgICBfLmlzRXF1YWwoa2V5Q2hhaW5QcnYucFNoYXJlLCBiYWNrdXBLZXlTaGFyZS5wU2hhcmUpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBfLmlzRXF1YWwoa2V5Q2hhaW5QcnYuYml0Z29OU2hhcmUsIGJpdGdvS2V5U2hhcmUublNoYXJlc1syXSkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIF8uaXNFcXVhbChrZXlDaGFpblBydi51c2VyTlNoYXJlLCB1c2VyS2V5U2hhcmUublNoYXJlc1syXSkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIHNob3VsZC5leGlzdChiYWNrdXBLZXljaGFpbi5lbmNyeXB0ZWRQcnYpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIGdlbmVyYXRlIFRTUyBrZXkgY2hhaW5zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmFja3VwU2hhcmVIb2xkZXI6IEJhY2t1cEtleVNoYXJlID0ge1xuICAgICAgICB1c2VySGVsZEtleVNoYXJlOiBiYWNrdXBLZXlTaGFyZSxcbiAgICAgIH07XG4gICAgICBjb25zdCBiYWNrdXBHcGdLZXk6IEJhY2t1cEdwZ0tleSA9IHVzZXJMb2NhbEJhY2t1cEdwZ0tleTtcbiAgICAgIGNvbnN0IGJpdGdvS2V5Y2hhaW4gPSBhd2FpdCB0c3NVdGlscy5jcmVhdGVCaXRnb0tleWNoYWluKHtcbiAgICAgICAgdXNlckdwZ0tleSxcbiAgICAgICAgYmFja3VwR3BnS2V5LFxuICAgICAgICB1c2VyS2V5U2hhcmUsXG4gICAgICAgIGJhY2t1cEtleVNoYXJlOiBiYWNrdXBTaGFyZUhvbGRlcixcbiAgICAgICAgYml0Z29QdWJsaWNHcGdLZXk6IGJpdGdvUHVibGljS2V5LFxuICAgICAgfSk7XG4gICAgICBiaXRnb0tleWNoYWluLnNob3VsZC5kZWVwRXF1YWwobm9ja2VkQml0R29LZXljaGFpbik7XG4gICAgICBjb25zdCB0ZXN0S2V5U2hhcmVzID0gb3RoZXJLZXlTaGFyZXM7XG4gICAgICBjb25zdCB0ZXN0Q2FzZXNQcm9taXNlcyA9IFtcbiAgICAgICAgdHNzVXRpbHNcbiAgICAgICAgICAuY3JlYXRlUGFydGljaXBhbnRLZXljaGFpbihcbiAgICAgICAgICAgIHVzZXJHcGdLZXksXG4gICAgICAgICAgICB1c2VyTG9jYWxCYWNrdXBHcGdLZXksXG4gICAgICAgICAgICBiaXRnb1B1YmxpY0tleSxcbiAgICAgICAgICAgIDEsXG4gICAgICAgICAgICB1c2VyS2V5U2hhcmUsXG4gICAgICAgICAgICB0ZXN0S2V5U2hhcmVzWzBdLFxuICAgICAgICAgICAgYml0Z29LZXljaGFpbixcbiAgICAgICAgICAgICdwYXNzcGhyYXNlJ1xuICAgICAgICAgIClcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnQ29tbW9uIGtleWNoYWlucyBkbyBub3QgbWF0Y2gnKSxcbiAgICAgICAgdHNzVXRpbHNcbiAgICAgICAgICAuY3JlYXRlUGFydGljaXBhbnRLZXljaGFpbihcbiAgICAgICAgICAgIHVzZXJHcGdLZXksXG4gICAgICAgICAgICB1c2VyTG9jYWxCYWNrdXBHcGdLZXksXG4gICAgICAgICAgICBiaXRnb1B1YmxpY0tleSxcbiAgICAgICAgICAgIDEsXG4gICAgICAgICAgICB0ZXN0S2V5U2hhcmVzWzFdLFxuICAgICAgICAgICAgYmFja3VwS2V5U2hhcmUsXG4gICAgICAgICAgICBiaXRnb0tleWNoYWluLFxuICAgICAgICAgICAgJ3Bhc3NwaHJhc2UnXG4gICAgICAgICAgKVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdDb21tb24ga2V5Y2hhaW5zIGRvIG5vdCBtYXRjaCcpLFxuICAgICAgICB0c3NVdGlsc1xuICAgICAgICAgIC5jcmVhdGVQYXJ0aWNpcGFudEtleWNoYWluKFxuICAgICAgICAgICAgdXNlckdwZ0tleSxcbiAgICAgICAgICAgIHVzZXJMb2NhbEJhY2t1cEdwZ0tleSxcbiAgICAgICAgICAgIGJpdGdvUHVibGljS2V5LFxuICAgICAgICAgICAgMixcbiAgICAgICAgICAgIHRlc3RLZXlTaGFyZXNbMl0sXG4gICAgICAgICAgICBiYWNrdXBLZXlTaGFyZSxcbiAgICAgICAgICAgIGJpdGdvS2V5Y2hhaW4sXG4gICAgICAgICAgICAncGFzc3BocmFzZSdcbiAgICAgICAgICApXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0NvbW1vbiBrZXljaGFpbnMgZG8gbm90IG1hdGNoJyksXG4gICAgICAgIHRzc1V0aWxzXG4gICAgICAgICAgLmNyZWF0ZVBhcnRpY2lwYW50S2V5Y2hhaW4oXG4gICAgICAgICAgICB1c2VyR3BnS2V5LFxuICAgICAgICAgICAgdXNlckxvY2FsQmFja3VwR3BnS2V5LFxuICAgICAgICAgICAgYml0Z29QdWJsaWNLZXksXG4gICAgICAgICAgICAyLFxuICAgICAgICAgICAgdXNlcktleVNoYXJlLFxuICAgICAgICAgICAgdGVzdEtleVNoYXJlc1szXSxcbiAgICAgICAgICAgIGJpdGdvS2V5Y2hhaW4sXG4gICAgICAgICAgICAncGFzc3BocmFzZSdcbiAgICAgICAgICApXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0NvbW1vbiBrZXljaGFpbnMgZG8gbm90IG1hdGNoJyksXG4gICAgICBdO1xuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwodGVzdENhc2VzUHJvbWlzZXMpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIGdlbmVyYXRlIFRTUyBrZXljaGFpbnMgd2hlbiByZWNlaXZlZCBpbnZhbGlkIG51bWJlciBvZiB3YWxsZXQgc2lnbmF0dXJlcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJpdGdvS2V5Y2hhaW4gPSBhd2FpdCBnZW5lcmF0ZUJpdGdvS2V5Y2hhaW4oe1xuICAgICAgICBjb2luOiBjb2luTmFtZSxcbiAgICAgICAgdXNlcktleVNoYXJlLFxuICAgICAgICBiYWNrdXBLZXlTaGFyZSxcbiAgICAgICAgYml0Z29LZXlTaGFyZSxcbiAgICAgICAgdXNlckdwZ0tleSxcbiAgICAgICAgdXNlckxvY2FsQmFja3VwR3BnS2V5LFxuICAgICAgICBiaXRnb0dwZ0tleTogYml0R29HUEdLZXlQYWlyLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGNlcnRzU3RyaW5nID0gYXdhaXQgY3JlYXRlU2hhcmVkRGF0YVByb29mKGJpdEdvR1BHS2V5UGFpci5wcml2YXRlS2V5LCB1c2VyR3BnS2V5LnB1YmxpY0tleSwgW10pO1xuICAgICAgY29uc3QgY2VydHNLZXkgPSBhd2FpdCBvcGVucGdwLnJlYWRLZXkoeyBhcm1vcmVkS2V5OiBjZXJ0c1N0cmluZyB9KTtcbiAgICAgIGNvbnN0IGZpbmFsS2V5ID0gbmV3IG9wZW5wZ3AuUGFja2V0TGlzdCgpO1xuICAgICAgY2VydHNLZXkudG9QYWNrZXRMaXN0KCkuZm9yRWFjaCgocGFja2V0KSA9PiBmaW5hbEtleS5wdXNoKHBhY2tldCkpO1xuICAgICAgLy8gT25jZSB0aGUgZm9sbG93aW5nIFBSIGhhcyBiZWVuIG1lcmdlZCBhbmQgcmVsZWFzZWQgd2Ugbm8gbG9uZ2VyIG5lZWQgdGhlIHRzLWlnbm9yZTpcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9vcGVucGdwanMvb3BlbnBncGpzL3B1bGwvMTU3NlxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9iYW4tdHMtY29tbWVudFxuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgYml0Z29LZXljaGFpbi53YWxsZXRIU01HUEdQdWJsaWNLZXlTaWdzID0gb3BlbnBncC5hcm1vcihvcGVucGdwLmVudW1zLmFybW9yLnB1YmxpY0tleSwgZmluYWxLZXkud3JpdGUoKSk7XG4gICAgICBhd2FpdCB0c3NVdGlsc1xuICAgICAgICAudmVyaWZ5V2FsbGV0U2lnbmF0dXJlcyh1c2VyTG9jYWxCYWNrdXBHcGdLZXkucHVibGljS2V5LCB1c2VyTG9jYWxCYWNrdXBHcGdLZXkucHVibGljS2V5LCBiaXRnb0tleWNoYWluLCAnJywgMSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoYEludmFsaWQgd2FsbGV0IHNpZ25hdHVyZXNgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byBnZW5lcmF0ZSBUU1Mga2V5Y2hhaW5zIHdoZW4gd2FsbGV0IHNpZ25hdHVyZSBmaW5nZXJwcmludHMgZG8gbm90IG1hdGNoIHBhc3NlZCB1c2VyL2JhY2t1cCBmaW5nZXJwcmludHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjdXN0b21Vc2VyS2V5U2hhcmUgPSBhd2FpdCBNUEMua2V5U2hhcmUoMSwgMiwgMyk7XG4gICAgICBjb25zdCBjdXN0b21CYWNrdXBLZXlTaGFyZSA9IGF3YWl0IE1QQy5rZXlTaGFyZSgyLCAyLCAzKTtcbiAgICAgIGNvbnN0IGJhY2t1cFNoYXJlSG9sZGVyOiBCYWNrdXBLZXlTaGFyZSA9IHtcbiAgICAgICAgdXNlckhlbGRLZXlTaGFyZTogY3VzdG9tQmFja3VwS2V5U2hhcmUsXG4gICAgICB9O1xuICAgICAgY29uc3QgYmFja3VwR3BnS2V5OiBCYWNrdXBHcGdLZXkgPSB1c2VyTG9jYWxCYWNrdXBHcGdLZXk7XG5cbiAgICAgIGNvbnN0IGJpdGdvS2V5Y2hhaW4gPSBhd2FpdCB0c3NVdGlscy5jcmVhdGVCaXRnb0tleWNoYWluKHtcbiAgICAgICAgdXNlckdwZ0tleSxcbiAgICAgICAgYmFja3VwR3BnS2V5LFxuICAgICAgICB1c2VyS2V5U2hhcmU6IGN1c3RvbVVzZXJLZXlTaGFyZSxcbiAgICAgICAgYmFja3VwS2V5U2hhcmU6IGJhY2t1cFNoYXJlSG9sZGVyLFxuICAgICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29QdWJsaWNLZXksXG4gICAgICB9KTtcblxuICAgICAgLy8gdXNpbmcgdGhlIGJhY2t1cCBncGcgaGVyZSBpbnN0ZWFkIG9mIHRoZSB1c2VyIGdwZyBrZXkgdG8gc2ltdWxhdGUgdGhhdCB0aGUgZmlyc3Qgc2lnbmF0dXJlIGhhcyBhIGRpZmZlcmVudFxuICAgICAgLy8gZmluZ2VycHJpbnQgZnJvbSB0aGUgcGFzc2VkIGluIGZpcnN0IGdwZyBrZXlcbiAgICAgIGF3YWl0IHRzc1V0aWxzXG4gICAgICAgIC52ZXJpZnlXYWxsZXRTaWduYXR1cmVzKHVzZXJMb2NhbEJhY2t1cEdwZ0tleS5wdWJsaWNLZXksIHVzZXJMb2NhbEJhY2t1cEdwZ0tleS5wdWJsaWNLZXksIGJpdGdvS2V5Y2hhaW4sICcnLCAxKVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICBgZmlyc3Qgd2FsbGV0IHNpZ25hdHVyZSdzIGZpbmdlcnByaW50IGRvZXMgbm90IG1hdGNoIHBhc3NlZCB1c2VyIGdwZyBrZXkncyBmaW5nZXJwcmludGBcbiAgICAgICAgKTtcblxuICAgICAgLy8gdXNpbmcgdGhlIHVzZXIgZ3BnIGhlcmUgaW5zdGVhZCBvZiB0aGUgYmFja3VwIGdwZyBrZXkgdG8gc2ltdWxhdGUgdGhhdCB0aGUgc2Vjb25kIHNpZ25hdHVyZSBoYXMgYSBkaWZmZXJlbnRcbiAgICAgIC8vIGZpbmdlcnByaW50IGZyb20gdGhlIHBhc3NlZCBpbiBzZWNvbmQgZ3BnIGtleVxuICAgICAgYXdhaXQgdHNzVXRpbHNcbiAgICAgICAgLnZlcmlmeVdhbGxldFNpZ25hdHVyZXModXNlckdwZ0tleS5wdWJsaWNLZXksIHVzZXJHcGdLZXkucHVibGljS2V5LCBiaXRnb0tleWNoYWluLCAnJywgMSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgYHNlY29uZCB3YWxsZXQgc2lnbmF0dXJlJ3MgZmluZ2VycHJpbnQgZG9lcyBub3QgbWF0Y2ggcGFzc2VkIGJhY2t1cCBncGcga2V5J3MgZmluZ2VycHJpbnRgXG4gICAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdzaWduVHhSZXF1ZXN0OicsICgpID0+IHtcbiAgICBjb25zdCB0eFJlcXVlc3RJZCA9ICdyYW5kb21pZEVjZHNhJztcbiAgICBjb25zdCB0eFJlcXVlc3Q6IFR4UmVxdWVzdCA9IHtcbiAgICAgIHR4UmVxdWVzdElkLFxuICAgICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB1bnNpZ25lZFR4OiB7XG4gICAgICAgICAgICAvLyBodGV0aCB0eGlkOiAweGM1YTdiZmU2YjEzY2VhZTU2M2RhMGY5ZmVhYTljNGFkMWMxMDFhMTUzNjZhMmE0ODg4MjhhNWRkMjdjYjlkYTNcbiAgICAgICAgICAgIHNlcmlhbGl6ZWRUeEhleDpcbiAgICAgICAgICAgICAgJzAyZjM4MjQyNjg4MDg0NDQ4YjliODA4NDQ0OGI5YjkwODMwMTYzNzg5NGExY2ZiOWQ1MWMwYWYxOTFmZjIxYzVmMGYwMTcyM2UwNTZmN2RjMTI4NjVhZjMxMDdhNDAwMDgwYzA4MDgwODAnLFxuICAgICAgICAgICAgc2lnbmFibGVIZXg6XG4gICAgICAgICAgICAgICcwMmYwODI0MjY4ODA4NDQ0OGI5YjgwODQ0NDhiOWI5MDgzMDE2Mzc4OTRhMWNmYjlkNTFjMGFmMTkxZmYyMWM1ZjBmMDE3MjNlMDU2ZjdkYzEyODY1YWYzMTA3YTQwMDA4MGMwJyxcbiAgICAgICAgICAgIGRlcml2YXRpb25QYXRoOiAnJywgLy8gTmVlZHMgdGhpcyB3aGVuIGtleSBkZXJpdmF0aW9uIGlzIHN1cHBvcnRlZFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc3RhdGU6ICdwZW5kaW5nU2lnbmF0dXJlJyxcbiAgICAgICAgICBzaWduYXR1cmVTaGFyZXM6IFtdLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIHVuc2lnbmVkVHhzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICAvLyBodGV0aCB0eGlkOiAweGM1YTdiZmU2YjEzY2VhZTU2M2RhMGY5ZmVhYTljNGFkMWMxMDFhMTUzNjZhMmE0ODg4MjhhNWRkMjdjYjlkYTNcbiAgICAgICAgICBzZXJpYWxpemVkVHhIZXg6XG4gICAgICAgICAgICAnMDJmMzgyNDI2ODgwODQ0NDhiOWI4MDg0NDQ4YjliOTA4MzAxNjM3ODk0YTFjZmI5ZDUxYzBhZjE5MWZmMjFjNWYwZjAxNzIzZTA1NmY3ZGMxMjg2NWFmMzEwN2E0MDAwODBjMDgwODA4MCcsXG4gICAgICAgICAgc2lnbmFibGVIZXg6XG4gICAgICAgICAgICAnMDJmMzgyNDI2ODgwODQ0NDhiOWI4MDg0NDQ4YjliOTA4MzAxNjM3ODk0YTFjZmI5ZDUxYzBhZjE5MWZmMjFjNWYwZjAxNzIzZTA1NmY3ZGMxMjg2NWFmMzEwN2E0MDAwODBjMDgwODA4MCcsXG4gICAgICAgICAgZGVyaXZhdGlvblBhdGg6ICcnLCAvLyBOZWVkcyB0aGlzIHdoZW4ga2V5IGRlcml2YXRpb24gaXMgc3VwcG9ydGVkXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgZGF0ZTogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgaW50ZW50OiB7XG4gICAgICAgIGludGVudFR5cGU6ICdwYXltZW50JyxcbiAgICAgIH0sXG4gICAgICBsYXRlc3Q6IHRydWUsXG4gICAgICBzdGF0ZTogJ3BlbmRpbmdVc2VyU2lnbmF0dXJlJyxcbiAgICAgIHdhbGxldFR5cGU6ICdob3QnLFxuICAgICAgd2FsbGV0SWQ6ICd3YWxsZXRJZCcsXG4gICAgICBwb2xpY2llc0NoZWNrZWQ6IHRydWUsXG4gICAgICB2ZXJzaW9uOiAxLFxuICAgICAgdXNlcklkOiAndXNlcklkJyxcbiAgICB9O1xuICAgIGxldCBhU2hhcmUsIGRTaGFyZSwgd1NoYXJlLCBvU2hhcmUsIHVzZXJTaWduU2hhcmUsIGJpdGdvQ2hhbGxlbmdlcywgZW50ZXJwcmlzZUNoYWxsZW5nZXM7XG5cbiAgICBiZWZvcmVFYWNoKGFzeW5jICgpID0+IHtcbiAgICAgIC8vIEluaXRpYWxpemluZyB1c2VyIGFuZCBiaXRnbyBmb3IgY3JlYXRpbmcgc2hhcmVzIGZvciBub2Nrc1xuICAgICAgY29uc3QgdXNlclNpZ25pbmdLZXkgPSBNUEMua2V5Q29tYmluZSh1c2VyS2V5U2hhcmUucFNoYXJlLCBbYml0Z29LZXlTaGFyZS5uU2hhcmVzWzFdLCBiYWNrdXBLZXlTaGFyZS5uU2hhcmVzWzFdXSk7XG4gICAgICBjb25zdCBiaXRnb1NpZ25pbmdLZXkgPSBNUEMua2V5Q29tYmluZShiaXRnb0tleVNoYXJlLnBTaGFyZSwgW1xuICAgICAgICB1c2VyS2V5U2hhcmUublNoYXJlc1szXSxcbiAgICAgICAgYmFja3VwS2V5U2hhcmUublNoYXJlc1szXSxcbiAgICAgIF0pO1xuXG4gICAgICBjb25zdCBzZXJpYWxpemVkRW50Q2hhbGxlbmdlID0gbW9ja0NoYWxsZW5nZUE7XG4gICAgICBjb25zdCBzZXJpYWxpemVkQml0Z29DaGFsbGVuZ2UgPSBtb2NrQ2hhbGxlbmdlQjtcblxuICAgICAgY29uc3QgZGVzZXJpYWxpemVkRW50Q2hhbGxlbmdlID0gRWNkc2FUeXBlcy5kZXNlcmlhbGl6ZU50aWxkZVdpdGhQcm9vZnMoc2VyaWFsaXplZEVudENoYWxsZW5nZSk7XG4gICAgICBzaW5vbi5zdHViKEVjZHNhUmFuZ2VQcm9vZiwgJ2dlbmVyYXRlTnRpbGRlJykucmVzb2x2ZXMoZGVzZXJpYWxpemVkRW50Q2hhbGxlbmdlKTtcblxuICAgICAgY29uc3QgW3VzZXJUb0JpdGdvUGFpbGxpZXJDaGFsbGVuZ2UsIGJpdGdvVG9Vc2VyUGFpbGxpZXJDaGFsbGVuZ2VdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBFY2RzYVBhaWxsaWVyUHJvb2YuZ2VuZXJhdGVQKGhleFRvQmlnSW50KHVzZXJTaWduaW5nS2V5LnlTaGFyZXNbM10ubikpLFxuICAgICAgICBFY2RzYVBhaWxsaWVyUHJvb2YuZ2VuZXJhdGVQKGhleFRvQmlnSW50KGJpdGdvU2lnbmluZ0tleS55U2hhcmVzWzFdLm4pKSxcbiAgICAgIF0pO1xuXG4gICAgICBiaXRnb0NoYWxsZW5nZXMgPSB7XG4gICAgICAgIC4uLnNlcmlhbGl6ZWRCaXRnb0NoYWxsZW5nZSxcbiAgICAgICAgcDogRWNkc2FUeXBlcy5zZXJpYWxpemVQYWlsbGllckNoYWxsZW5nZSh7IHA6IGJpdGdvVG9Vc2VyUGFpbGxpZXJDaGFsbGVuZ2UgfSkucCxcbiAgICAgICAgbjogYml0Z29TaWduaW5nS2V5LnhTaGFyZS5uLFxuICAgICAgfTtcbiAgICAgIGVudGVycHJpc2VDaGFsbGVuZ2VzID0ge1xuICAgICAgICAuLi5zZXJpYWxpemVkRW50Q2hhbGxlbmdlLFxuICAgICAgICBwOiBFY2RzYVR5cGVzLnNlcmlhbGl6ZVBhaWxsaWVyQ2hhbGxlbmdlKHsgcDogdXNlclRvQml0Z29QYWlsbGllckNoYWxsZW5nZSB9KS5wLFxuICAgICAgICBuOiBiaXRnb1NpZ25pbmdLZXkueFNoYXJlLm4sXG4gICAgICB9O1xuICAgICAgc2lub24uc3R1YihFQ0RTQVV0aWxzLkVjZHNhVXRpbHMucHJvdG90eXBlLCAnZ2V0RWNkc2FTaWduaW5nQ2hhbGxlbmdlcycpLnJlc29sdmVzKHtcbiAgICAgICAgZW50ZXJwcmlzZUNoYWxsZW5nZTogZW50ZXJwcmlzZUNoYWxsZW5nZXMsXG4gICAgICAgIGJpdGdvQ2hhbGxlbmdlOiBiaXRnb0NoYWxsZW5nZXMsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgW3VzZXJYU2hhcmUsIGJpdGdvWFNoYXJlXSA9IFtcbiAgICAgICAgTVBDLmFwcGVuZENoYWxsZW5nZShcbiAgICAgICAgICB1c2VyU2lnbmluZ0tleS54U2hhcmUsXG4gICAgICAgICAgc2VyaWFsaXplZEVudENoYWxsZW5nZSxcbiAgICAgICAgICBFY2RzYVR5cGVzLnNlcmlhbGl6ZVBhaWxsaWVyQ2hhbGxlbmdlKHsgcDogdXNlclRvQml0Z29QYWlsbGllckNoYWxsZW5nZSB9KVxuICAgICAgICApLFxuICAgICAgICBNUEMuYXBwZW5kQ2hhbGxlbmdlKFxuICAgICAgICAgIGJpdGdvU2lnbmluZ0tleS54U2hhcmUsXG4gICAgICAgICAgc2VyaWFsaXplZEJpdGdvQ2hhbGxlbmdlLFxuICAgICAgICAgIEVjZHNhVHlwZXMuc2VyaWFsaXplUGFpbGxpZXJDaGFsbGVuZ2UoeyBwOiBiaXRnb1RvVXNlclBhaWxsaWVyQ2hhbGxlbmdlIH0pXG4gICAgICAgICksXG4gICAgICBdO1xuICAgICAgY29uc3QgYml0Z29ZU2hhcmUgPSBNUEMuYXBwZW5kQ2hhbGxlbmdlKFxuICAgICAgICB1c2VyU2lnbmluZ0tleS55U2hhcmVzWzNdLFxuICAgICAgICBzZXJpYWxpemVkQml0Z29DaGFsbGVuZ2UsXG4gICAgICAgIEVjZHNhVHlwZXMuc2VyaWFsaXplUGFpbGxpZXJDaGFsbGVuZ2UoeyBwOiBiaXRnb1RvVXNlclBhaWxsaWVyQ2hhbGxlbmdlIH0pXG4gICAgICApO1xuICAgICAgLyoqXG4gICAgICAgKiBTVEFSVCBTVEVQIE9ORVxuICAgICAgICogMSkgVXNlciBjcmVhdGVzIHNpZ25TaGFyZSwgc2F2ZXMgd1NoYXJlIGFuZCBzZW5kcyBrU2hhcmUgdG8gYml0Z29cbiAgICAgICAqIDIpIEJpdGdvIHBlcmZvcm1zIHNpZ25Db252ZXJ0IG9wZXJhdGlvbiB1c2luZyBpdHMgcHJpdmF0ZSB4U2hhcmUgLCB5U2hhcmVcbiAgICAgICAqICBhbmQgS1NoYXJlIGZyb20gdXNlciBhbmQgcmVzcG9uZHMgYmFjayB3aXRoIGFTaGFyZSBhbmQgc2F2ZXMgYlNoYXJlIGZvciBsYXRlciB1c2VcbiAgICAgICAqL1xuICAgICAgdXNlclNpZ25TaGFyZSA9IGF3YWl0IEVDRFNBTWV0aG9kcy5jcmVhdGVVc2VyU2lnblNoYXJlKHVzZXJYU2hhcmUsIGJpdGdvWVNoYXJlKTtcbiAgICAgIHdTaGFyZSA9IHVzZXJTaWduU2hhcmUud1NoYXJlO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlU2hhcmVPbmVGcm9tVXNlcjogU2lnbmF0dXJlU2hhcmVSZWNvcmQgPSB7XG4gICAgICAgIGZyb206IFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSLFxuICAgICAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPLFxuICAgICAgICBzaGFyZTogRUNEU0FNZXRob2RzLmNvbnZlcnRLU2hhcmUodXNlclNpZ25TaGFyZS5rU2hhcmUpLnNoYXJlLnJlcGxhY2UoRUNEU0FNZXRob2RzLmRlbGltZXRlciwgJycpLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGdldEJpdGdvQWFuZEJTaGFyZSA9IGF3YWl0IE1QQy5zaWduQ29udmVydFN0ZXAxKHtcbiAgICAgICAgeFNoYXJlOiBiaXRnb1hTaGFyZSxcbiAgICAgICAgeVNoYXJlOiBiaXRnb1NpZ25pbmdLZXkueVNoYXJlc1sxXSwgLy8gY29ycmVzcG9uZHMgdG8gdGhlIHVzZXJcbiAgICAgICAga1NoYXJlOiB1c2VyU2lnblNoYXJlLmtTaGFyZSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgYml0Z29Bc2hhcmUgPSBnZXRCaXRnb0FhbmRCU2hhcmUuYVNoYXJlO1xuICAgICAgYVNoYXJlID0gYml0Z29Bc2hhcmU7XG4gICAgICBjb25zdCBhU2hhcmVCaXRnb1Jlc3BvbnNlID0gRUNEU0FNZXRob2RzLmNvbnZlcnRBU2hhcmUoYml0Z29Bc2hhcmUpLnNoYXJlLnJlcGxhY2UoRUNEU0FNZXRob2RzLmRlbGltZXRlciwgJycpO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlU2hhcmVPbmVGcm9tQml0Z286IFNpZ25hdHVyZVNoYXJlUmVjb3JkID0ge1xuICAgICAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgICAgIHRvOiBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUixcbiAgICAgICAgc2hhcmU6IGFTaGFyZUJpdGdvUmVzcG9uc2UsXG4gICAgICB9O1xuICAgICAgYXdhaXQgbm9ja1NlbmRTaWduYXR1cmVTaGFyZVdpdGhSZXNwb25zZSh7XG4gICAgICAgIHdhbGxldElkOiB3YWxsZXQuaWQoKSxcbiAgICAgICAgdHhSZXF1ZXN0SWQ6IHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgICAgc2lnbmF0dXJlU2hhcmU6IHNpZ25hdHVyZVNoYXJlT25lRnJvbVVzZXIsXG4gICAgICAgIHJlc3BvbnNlOiBzaWduYXR1cmVTaGFyZU9uZUZyb21CaXRnbyxcbiAgICAgICAgdHNzVHlwZTogJ2VjZHNhJyxcbiAgICAgIH0pO1xuICAgICAgLyoqICBFTkQgU1RFUCBPTkUgKi9cblxuICAgICAgLyoqXG4gICAgICAgKiBTVEFSVCBTVEVQIFRXT1xuICAgICAgICogMSkgVXNpbmcgdGhlIGFTaGFyZSBnb3QgZnJvbSBiaXRnbyBhbmQgd1NoYXJlIGZyb20gcHJldmlvdXMgc3RlcCxcbiAgICAgICAqIHVzZXIgY3JlYXRlcyBnU2hhcmUgYW5kIG11U2hhcmUgYW5kIHNlbmRzIG11U2hhcmUgdG8gYml0Z29cbiAgICAgICAqIDIpIEJpdGdvIHVzaW5nIHRoZSBzaWduQ29udmVydCBzdGVwIHVzaW5nIGJTaGFyZSBmcm9tIHByZXZpb3VzIHN0ZXBcbiAgICAgICAqIGFuZCBtdVNoYXJlIGZyb20gdXNlciBnZW5lcmF0ZXMgaXRzIGdTaGFyZS5cbiAgICAgICAqIDMpIFVzaW5nIHRoZSBzaWduQ29tYmluZSBvcGVyYXRpb24gdXNpbmcgZ1NoYXJlLCBCaXRnbyBnZW5lcmF0ZXMgb1NoYXJlXG4gICAgICAgKiB3aGljaCBpdCBzYXZlcyBhbmQgZFNoYXJlIHdoaWNoIGlzIHNlbmQgYmFjayB0byB0aGUgdXNlci5cbiAgICAgICAqL1xuICAgICAgY29uc3QgdXNlckdhbW1hQW5kTXVTaGFyZXMgPSBhd2FpdCBFQ0RTQU1ldGhvZHMuY3JlYXRlVXNlckdhbW1hQW5kTXVTaGFyZSh1c2VyU2lnblNoYXJlLndTaGFyZSwgYml0Z29Bc2hhcmUpO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlU2hhcmVUd29Gcm9tVXNlcjogU2lnbmF0dXJlU2hhcmVSZWNvcmQgPSB7XG4gICAgICAgIGZyb206IFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSLFxuICAgICAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPLFxuICAgICAgICBzaGFyZTogRUNEU0FNZXRob2RzLmNvbnZlcnRNdVNoYXJlKHVzZXJHYW1tYUFuZE11U2hhcmVzLm11U2hhcmUhKS5zaGFyZS5yZXBsYWNlKEVDRFNBTWV0aG9kcy5kZWxpbWV0ZXIsICcnKSxcbiAgICAgIH07XG4gICAgICBjb25zdCBnZXRCaXRHb0dTaGFyZUFuZFNpZ25lckluZGV4ZXMgPSBhd2FpdCBNUEMuc2lnbkNvbnZlcnRTdGVwMyh7XG4gICAgICAgIGJTaGFyZTogZ2V0Qml0Z29BYW5kQlNoYXJlLmJTaGFyZSxcbiAgICAgICAgbXVTaGFyZTogdXNlckdhbW1hQW5kTXVTaGFyZXMubXVTaGFyZSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBnZXRCaXRnb09TaGFyZUFuZERTaGFyZXMgPSBNUEMuc2lnbkNvbWJpbmUoe1xuICAgICAgICBnU2hhcmU6IGdldEJpdEdvR1NoYXJlQW5kU2lnbmVySW5kZXhlcy5nU2hhcmUgYXMgRUNEU0EuR1NoYXJlLFxuICAgICAgICBzaWduSW5kZXg6IHtcbiAgICAgICAgICBpOiAxLFxuICAgICAgICAgIGo6IDMsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGJpdGdvRHNoYXJlID0gZ2V0Qml0Z29PU2hhcmVBbmREU2hhcmVzLmRTaGFyZSBhcyBFQ0RTQS5EU2hhcmU7XG4gICAgICBkU2hhcmUgPSBiaXRnb0RzaGFyZTtcbiAgICAgIGNvbnN0IGRTaGFyZUJpdGdvUmVzcG9uc2UgPSAoYml0Z29Ec2hhcmUuZGVsdGEgYXMgc3RyaW5nKSArIChiaXRnb0RzaGFyZS5HYW1tYSBhcyBzdHJpbmcpO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlU2hhcmVUd29Gcm9tQml0Z286IFNpZ25hdHVyZVNoYXJlUmVjb3JkID0ge1xuICAgICAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgICAgIHRvOiBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUixcbiAgICAgICAgc2hhcmU6IGRTaGFyZUJpdGdvUmVzcG9uc2UsXG4gICAgICB9O1xuICAgICAgYXdhaXQgbm9ja1NlbmRTaWduYXR1cmVTaGFyZVdpdGhSZXNwb25zZSh7XG4gICAgICAgIHdhbGxldElkOiB3YWxsZXQuaWQoKSxcbiAgICAgICAgdHhSZXF1ZXN0SWQ6IHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgICAgc2lnbmF0dXJlU2hhcmU6IHNpZ25hdHVyZVNoYXJlVHdvRnJvbVVzZXIsXG4gICAgICAgIHJlc3BvbnNlOiBzaWduYXR1cmVTaGFyZVR3b0Zyb21CaXRnbyxcbiAgICAgICAgdHNzVHlwZTogJ2VjZHNhJyxcbiAgICAgIH0pO1xuICAgICAgLyoqICBFTkQgU1RFUCBUV08gKi9cblxuICAgICAgLyoqXG4gICAgICAgKiBTVEFSVCBTVEVQIFRIUkVFXG4gICAgICAgKiAxKSBVc2VyIGNyZWF0ZXMgaXRzIG9TaGFyZSBhbmQgIGRTaGFyZSB1c2luZyB0aGUgIHByaXZhdGUgZ1NoYXJlXG4gICAgICAgKiBmcm9tIHN0ZXAgdHdvXG4gICAgICAgKiAyKSBVc2VyIHVzZXMgdGhlIHByaXZhdGUgb1NoYXJlIGFuZCBkU2hhcmUgZnJvbSBiaXRnbyBmcm9tIHN0ZXBcbiAgICAgICAqIHR3byB0byBnZW5lcmF0ZSBpdHMgc2lnbmF0dXJlIHNoYXJlIHdoaWNoIGl0IHNlbmRzIGJhY2sgYWxvbmcgd2l0aCBkU2hhcmUgdGhhdFxuICAgICAgICogdXNlciBnZW5lcmF0ZWQgZnJvbSB0aGUgYWJvdmUgc3RlcFxuICAgICAgICogMykgQml0Z28gdXNpbmcgaXRzIHByaXZhdGUgb1NoYXJlIGZyb20gc3RlcCB0d28gYW5kIGRTaGFyZSBmcm9tIGJpdGdvIGNyZWF0ZXNcbiAgICAgICAqIGl0cyBzaWduYXR1cmUgc2hhcmUuIFVzaW5nIHRoZSBTaWduYXR1cmUgU2hhcmUgcmVjZWl2ZWQgZnJvbSB1c2VyIGZyb20gdGhlIGFib3ZlXG4gICAgICAgKiBzdGVwLCBiaXRnbyBjb25zdHJ1Y3RzIHRoZSBmaW5hbCBzaWduYXR1cmUgYW5kIGlzIHJldHVybmVkIHRvIHRoZSB1c2VyXG4gICAgICAgKi9cbiAgICAgIGNvbnN0IHVzZXJPbWljcm9uQW5kRGVsdGFTaGFyZSA9IGF3YWl0IEVDRFNBTWV0aG9kcy5jcmVhdGVVc2VyT21pY3JvbkFuZERlbHRhU2hhcmUoXG4gICAgICAgIHVzZXJHYW1tYUFuZE11U2hhcmVzLmdTaGFyZSBhcyBFQ0RTQS5HU2hhcmVcbiAgICAgICk7XG4gICAgICBvU2hhcmUgPSB1c2VyT21pY3JvbkFuZERlbHRhU2hhcmUub1NoYXJlO1xuICAgICAgY29uc3Qgc2lnbmFibGVQYXlsb2FkID0gQnVmZmVyLmZyb20odHhSZXF1ZXN0LnVuc2lnbmVkVHhzWzBdLnNpZ25hYmxlSGV4LCAnaGV4Jyk7XG4gICAgICBjb25zdCB1c2VyU1NoYXJlID0gYXdhaXQgRUNEU0FNZXRob2RzLmNyZWF0ZVVzZXJTaWduYXR1cmVTaGFyZShcbiAgICAgICAgdXNlck9taWNyb25BbmREZWx0YVNoYXJlLm9TaGFyZSxcbiAgICAgICAgYml0Z29Ec2hhcmUsXG4gICAgICAgIHNpZ25hYmxlUGF5bG9hZFxuICAgICAgKTtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZVNoYXJlVGhyZWVGcm9tVXNlcjogU2lnbmF0dXJlU2hhcmVSZWNvcmQgPSB7XG4gICAgICAgIGZyb206IFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSLFxuICAgICAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPLFxuICAgICAgICBzaGFyZTpcbiAgICAgICAgICB1c2VyU1NoYXJlLlIgK1xuICAgICAgICAgIHVzZXJTU2hhcmUucyArXG4gICAgICAgICAgdXNlclNTaGFyZS55ICtcbiAgICAgICAgICB1c2VyT21pY3JvbkFuZERlbHRhU2hhcmUuZFNoYXJlLmRlbHRhICtcbiAgICAgICAgICB1c2VyT21pY3JvbkFuZERlbHRhU2hhcmUuZFNoYXJlLkdhbW1hLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGdldEJpdEdvU1NoYXJlID0gTVBDLnNpZ24oXG4gICAgICAgIHNpZ25hYmxlUGF5bG9hZCxcbiAgICAgICAgZ2V0Qml0Z29PU2hhcmVBbmREU2hhcmVzLm9TaGFyZSxcbiAgICAgICAgdXNlck9taWNyb25BbmREZWx0YVNoYXJlLmRTaGFyZSxcbiAgICAgICAgY3JlYXRlS2VjY2FrSGFzaCgna2VjY2FrMjU2JykgYXMgSGFzaFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGdldEJpdEdvRmluYWxTaWduYXR1cmUgPSBNUEMuY29uc3RydWN0U2lnbmF0dXJlKFtnZXRCaXRHb1NTaGFyZSwgdXNlclNTaGFyZV0pO1xuICAgICAgY29uc3QgZmluYWxTaWdhbnR1cmVCaXRnb1Jlc3BvbnNlID1cbiAgICAgICAgZ2V0Qml0R29GaW5hbFNpZ25hdHVyZS5yICsgZ2V0Qml0R29GaW5hbFNpZ25hdHVyZS5zICsgZ2V0Qml0R29GaW5hbFNpZ25hdHVyZS55O1xuICAgICAgY29uc3Qgc2lnbmF0dXJlU2hhcmVUaHJlZUZyb21CaXRnbzogU2lnbmF0dXJlU2hhcmVSZWNvcmQgPSB7XG4gICAgICAgIGZyb206IFNpZ25hdHVyZVNoYXJlVHlwZS5CSVRHTyxcbiAgICAgICAgdG86IFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSLFxuICAgICAgICBzaGFyZTogZmluYWxTaWdhbnR1cmVCaXRnb1Jlc3BvbnNlLFxuICAgICAgfTtcbiAgICAgIGF3YWl0IG5vY2tTZW5kU2lnbmF0dXJlU2hhcmVXaXRoUmVzcG9uc2Uoe1xuICAgICAgICB3YWxsZXRJZDogd2FsbGV0LmlkKCksXG4gICAgICAgIHR4UmVxdWVzdElkOiB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsXG4gICAgICAgIHNpZ25hdHVyZVNoYXJlOiBzaWduYXR1cmVTaGFyZVRocmVlRnJvbVVzZXIsXG4gICAgICAgIHJlc3BvbnNlOiBzaWduYXR1cmVTaGFyZVRocmVlRnJvbUJpdGdvLFxuICAgICAgICB0c3NUeXBlOiAnZWNkc2EnLFxuICAgICAgfSk7XG4gICAgICAvKiBFTkQgU1RFUCBUSFJFRSAqL1xuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gTVBDLmNvbnN0cnVjdFNpZ25hdHVyZShbdXNlclNTaGFyZSwgZ2V0Qml0R29TU2hhcmVdKTtcbiAgICAgIE1QQy52ZXJpZnkoc2lnbmFibGVQYXlsb2FkLCBzaWduYXR1cmUsIGNyZWF0ZUtlY2Nha0hhc2goJ2tlY2NhazI1NicpIGFzIEhhc2gpLnNob3VsZC5iZS50cnVlO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKGFzeW5jICgpID0+IHtcbiAgICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaWduVHhSZXF1ZXN0IHNob3VsZCBmYWlsIGlmIHdhbGxldCBpcyBpbiBwZW5kaW5nRWNkc2FUc3NJbml0aWFsaXphdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHNhbmRib3guc3R1Yih3YWxsZXQsICdjb2luU3BlY2lmaWMnKS5yZXR1cm5zKHtcbiAgICAgICAgY3VzdG9tQ2hhbmdlV2FsbGV0SWQ6ICcnLFxuICAgICAgICBwZW5kaW5nRWNkc2FUc3NJbml0aWFsaXphdGlvbjogdHJ1ZSxcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgdHNzVXRpbHNcbiAgICAgICAgLnNpZ25UeFJlcXVlc3Qoe1xuICAgICAgICAgIHR4UmVxdWVzdCxcbiAgICAgICAgICBwcnY6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgIHBTaGFyZTogdXNlcktleVNoYXJlLnBTaGFyZSxcbiAgICAgICAgICAgIGJpdGdvTlNoYXJlOiBiaXRnb0tleVNoYXJlLm5TaGFyZXNbMV0sXG4gICAgICAgICAgICBiYWNrdXBOU2hhcmU6IGJhY2t1cEtleVNoYXJlLm5TaGFyZXNbMV0sXG4gICAgICAgICAgfSksXG4gICAgICAgICAgcmVxSWQsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdXYWxsZXQgaXMgbm90IHJlYWR5IGZvciBUU1MgRUNEU0Egc2lnbmluZy4gUGxlYXNlIGNvbnRhY3QgeW91ciBlbnRlcnByaXNlIGFkbWluIHRvIGZpbmlzaCB0aGUgZW50ZXJwcmlzZSBUU1MgaW5pdGlhbGl6YXRpb24uJ1xuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3NpZ25UeFJlcXVlc3Qgc2hvdWxkIHN1Y2NlZWQgd2l0aCB0eFJlcXVlc3Qgb2JqZWN0IGFzIGlucHV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VuZFNoYXJlU3B5ID0gc2lub24uc3B5KEVDRFNBTWV0aG9kcywgJ3NlbmRTaGFyZVRvQml0Z28nIGFzIGFueSk7XG4gICAgICBhd2FpdCBzZXR1cFNpZ25UeFJlcXVlc3ROb2NrcyhmYWxzZSwgdXNlclNpZ25TaGFyZSwgYVNoYXJlLCBkU2hhcmUsIGVudGVycHJpc2VEYXRhKTtcbiAgICAgIGNvbnN0IHNpZ25lZFR4UmVxdWVzdCA9IGF3YWl0IHRzc1V0aWxzLnNpZ25UeFJlcXVlc3Qoe1xuICAgICAgICB0eFJlcXVlc3QsXG4gICAgICAgIHBydjogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgIHBTaGFyZTogdXNlcktleVNoYXJlLnBTaGFyZSxcbiAgICAgICAgICBiaXRnb05TaGFyZTogYml0Z29LZXlTaGFyZS5uU2hhcmVzWzFdLFxuICAgICAgICAgIGJhY2t1cE5TaGFyZTogYmFja3VwS2V5U2hhcmUublNoYXJlc1sxXSxcbiAgICAgICAgfSksXG4gICAgICAgIHJlcUlkLFxuICAgICAgfSk7XG4gICAgICBzaWduZWRUeFJlcXVlc3QudW5zaWduZWRUeHMuc2hvdWxkLmRlZXBFcXVhbCh0eFJlcXVlc3QudW5zaWduZWRUeHMpO1xuICAgICAgY29uc3QgdXNlckdwZ0FjdHVhbCA9IHNlbmRTaGFyZVNweS5nZXRDYWxscygpWzBdLmFyZ3NbMTBdIGFzIHN0cmluZztcbiAgICAgIHVzZXJHcGdBY3R1YWwuc2hvdWxkLnN0YXJ0V2l0aCgnLS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2lnblR4UmVxdWVzdCBzaG91bGQgc3VjY2VlZCB3aXRoIHR4UmVxdWVzdCBpZCBhcyBpbnB1dCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNlbmRTaGFyZVNweSA9IHNpbm9uLnNweShFQ0RTQU1ldGhvZHMsICdzZW5kU2hhcmVUb0JpdGdvJyBhcyBhbnkpO1xuICAgICAgYXdhaXQgc2V0dXBTaWduVHhSZXF1ZXN0Tm9ja3ModHJ1ZSwgdXNlclNpZ25TaGFyZSwgYVNoYXJlLCBkU2hhcmUsIGVudGVycHJpc2VEYXRhKTtcbiAgICAgIGNvbnN0IHNpZ25lZFR4UmVxdWVzdCA9IGF3YWl0IHRzc1V0aWxzLnNpZ25UeFJlcXVlc3Qoe1xuICAgICAgICB0eFJlcXVlc3Q6IHR4UmVxdWVzdElkLFxuICAgICAgICBwcnY6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICBwU2hhcmU6IHVzZXJLZXlTaGFyZS5wU2hhcmUsXG4gICAgICAgICAgYml0Z29OU2hhcmU6IGJpdGdvS2V5U2hhcmUublNoYXJlc1sxXSxcbiAgICAgICAgICBiYWNrdXBOU2hhcmU6IGJhY2t1cEtleVNoYXJlLm5TaGFyZXNbMV0sXG4gICAgICAgIH0pLFxuICAgICAgICByZXFJZCxcbiAgICAgIH0pO1xuICAgICAgc2lnbmVkVHhSZXF1ZXN0LnVuc2lnbmVkVHhzLnNob3VsZC5kZWVwRXF1YWwodHhSZXF1ZXN0LnVuc2lnbmVkVHhzKTtcbiAgICAgIGNvbnN0IHVzZXJHcGdBY3R1YWwgPSBzZW5kU2hhcmVTcHkuZ2V0Q2FsbHMoKVswXS5hcmdzWzEwXSBhcyBzdHJpbmc7XG4gICAgICB1c2VyR3BnQWN0dWFsLnNob3VsZC5zdGFydFdpdGgoJy0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3NpZ25UeFJlcXVlc3Qgc2hvdWxkIGZhaWwgd2l0aCB3cm9uZyByZWNpcGllbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBzZXR1cFNpZ25UeFJlcXVlc3ROb2Nrcyh0cnVlLCB1c2VyU2lnblNoYXJlLCBhU2hhcmUsIGRTaGFyZSwgZW50ZXJwcmlzZURhdGEpO1xuICAgICAgYXdhaXQgdHNzVXRpbHNcbiAgICAgICAgLnNpZ25UeFJlcXVlc3Qoe1xuICAgICAgICAgIHR4UmVxdWVzdDogdHhSZXF1ZXN0SWQsXG4gICAgICAgICAgcHJ2OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICBwU2hhcmU6IHVzZXJLZXlTaGFyZS5wU2hhcmUsXG4gICAgICAgICAgICBiaXRnb05TaGFyZTogYml0Z29LZXlTaGFyZS5uU2hhcmVzWzFdLFxuICAgICAgICAgICAgYmFja3VwTlNoYXJlOiBiYWNrdXBLZXlTaGFyZS5uU2hhcmVzWzFdLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIHJlcUlkLFxuICAgICAgICAgIHR4UGFyYW1zOiB7IHJlY2lwaWVudHM6IFt7IGFkZHJlc3M6ICcweDEyMzQnLCBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwMDAnIH1dLCB0eXBlOiAndHJhbnNmZXInIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdkZXN0aW5hdGlvbiBhZGRyZXNzIGRvZXMgbm90IG1hdGNoIHdpdGggdGhlIHJlY2lwaWVudCBhZGRyZXNzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2lnblR4UmVxdWVzdCBzaG91bGQgZmFpbCB3aXRoIGluY29ycmVjdCB2YWx1ZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IHNldHVwU2lnblR4UmVxdWVzdE5vY2tzKHRydWUsIHVzZXJTaWduU2hhcmUsIGFTaGFyZSwgZFNoYXJlLCBlbnRlcnByaXNlRGF0YSk7XG4gICAgICBhd2FpdCB0c3NVdGlsc1xuICAgICAgICAuc2lnblR4UmVxdWVzdCh7XG4gICAgICAgICAgdHhSZXF1ZXN0OiB0eFJlcXVlc3RJZCxcbiAgICAgICAgICBwcnY6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgIHBTaGFyZTogdXNlcktleVNoYXJlLnBTaGFyZSxcbiAgICAgICAgICAgIGJpdGdvTlNoYXJlOiBiaXRnb0tleVNoYXJlLm5TaGFyZXNbMV0sXG4gICAgICAgICAgICBiYWNrdXBOU2hhcmU6IGJhY2t1cEtleVNoYXJlLm5TaGFyZXNbMV0sXG4gICAgICAgICAgfSksXG4gICAgICAgICAgcmVxSWQsXG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIHJlY2lwaWVudHM6IFt7IGFkZHJlc3M6ICcweGExY2ZiOWQ1MWMwYWYxOTFmZjIxYzVmMGYwMTcyM2UwNTZmN2RjMTInLCBhbW91bnQ6ICcxJyB9XSxcbiAgICAgICAgICAgIHR5cGU6ICd0cmFuc2ZlcicsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3RoZSB0cmFuc2FjdGlvbiBhbW91bnQgaW4gdHhQcmVidWlsZCBkb2VzIG5vdCBtYXRjaCB0aGUgdmFsdWUgZ2l2ZW4gYnkgY2xpZW50Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2lnblR4UmVxdWVzdCBzaG91bGQgZmFpbCB3aXRoIGluY29ycmVjdCB2YWx1ZSBmb3IgdG9rZW4gdHhuJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2lnbmFibGVIZXggPVxuICAgICAgICAnMDJmODZkODI0MjY4MTA4MzEyMmM5ZTgzMTIyY2FlODMwMWUwNDk5NGViZThiNDZhNDJmMDUwNzJiNzIzYjAwMDEzZmY4MjJiMmFmMWI1Y2I4MGI4NDRhOTA1OWNiYjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDJiMGQ2Y2IyZjhjMzg4NzU3ZjRkN2FkODU3ZmNjYWIxODI5MGRiYzkwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDE4NmEwYzAnO1xuICAgICAgY29uc3Qgc2VyaWFsaXplZFR4SGV4ID1cbiAgICAgICAgJzAyZjg3MDgyNDI2ODEwODMxMjJjOWU4MzEyMmNhZTgzMDFlMDQ5OTRlYmU4YjQ2YTQyZjA1MDcyYjcyM2IwMDAxM2ZmODIyYjJhZjFiNWNiODBiODQ0YTkwNTljYmIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAyYjBkNmNiMmY4YzM4ODc1N2Y0ZDdhZDg1N2ZjY2FiMTgyOTBkYmM5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxODZhMGMwODA4MDgwJztcbiAgICAgIGF3YWl0IHNldHVwU2lnblR4UmVxdWVzdE5vY2tzKHRydWUsIHVzZXJTaWduU2hhcmUsIGFTaGFyZSwgZFNoYXJlLCBlbnRlcnByaXNlRGF0YSwge1xuICAgICAgICBzaWduYWJsZUhleCxcbiAgICAgICAgc2VyaWFsaXplZFR4SGV4LFxuICAgICAgICBhcGlWZXJzaW9uOiAnZnVsbCcsXG4gICAgICB9KTtcbiAgICAgIGF3YWl0IHRzc1V0aWxzXG4gICAgICAgIC5zaWduVHhSZXF1ZXN0KHtcbiAgICAgICAgICB0eFJlcXVlc3Q6IHR4UmVxdWVzdElkLFxuICAgICAgICAgIHBydjogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgcFNoYXJlOiB1c2VyS2V5U2hhcmUucFNoYXJlLFxuICAgICAgICAgICAgYml0Z29OU2hhcmU6IGJpdGdvS2V5U2hhcmUublNoYXJlc1sxXSxcbiAgICAgICAgICAgIGJhY2t1cE5TaGFyZTogYmFja3VwS2V5U2hhcmUublNoYXJlc1sxXSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICByZXFJZCxcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgcmVjaXBpZW50czogW3sgYWRkcmVzczogJzB4MmIwZDZjYjJmOGMzODg3NTdmNGQ3YWQ4NTdmY2NhYjE4MjkwZGJjOScsIGFtb3VudDogJzcwNycgfV0sXG4gICAgICAgICAgICB0eXBlOiAndHJhbnNmZXInLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCd0aGUgdHJhbnNhY3Rpb24gYW1vdW50IGluIHR4UHJlYnVpbGQgZG9lcyBub3QgbWF0Y2ggdGhlIHZhbHVlIGdpdmVuIGJ5IGNsaWVudCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2dldE9mZmxpbmVTaWduZXJQYWlsbGllck1vZHVsdXMgc2hvdWxkIHN1Y2NlZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYWlsbGllck1vZHVsdXMgPSB0c3NVdGlscy5nZXRPZmZsaW5lU2lnbmVyUGFpbGxpZXJNb2R1bHVzKHtcbiAgICAgICAgcHJ2OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgcFNoYXJlOiB1c2VyS2V5U2hhcmUucFNoYXJlLFxuICAgICAgICAgIGJpdGdvTlNoYXJlOiBiaXRnb0tleVNoYXJlLm5TaGFyZXNbMV0sXG4gICAgICAgICAgYmFja3VwTlNoYXJlOiBiYWNrdXBLZXlTaGFyZS5uU2hhcmVzWzFdLFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuICAgICAgcGFpbGxpZXJNb2R1bHVzLnVzZXJQYWlsbGllck1vZHVsdXMuc2hvdWxkLmVxdWFsKHVzZXJLZXlTaGFyZS5wU2hhcmUubik7XG4gICAgfSk7XG5cbiAgICBpdCgnY3JlYXRlT2ZmbGluZUtTaGFyZSBzaG91bGQgc3VjY2VlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1vY2tQYXNzd29yZCA9ICdwYXNzd29yZCc7XG4gICAgICBjb25zdCBzdGVwMVNpZ25pbmdNYXRlcmlhbCA9IGF3YWl0IHRzc1V0aWxzLmNyZWF0ZU9mZmxpbmVLU2hhcmUoe1xuICAgICAgICB0c3NQYXJhbXM6IHtcbiAgICAgICAgICB0eFJlcXVlc3QsXG4gICAgICAgICAgcmVxSWQ6IHJlcUlkLFxuICAgICAgICB9LFxuICAgICAgICBjaGFsbGVuZ2VzOiB7XG4gICAgICAgICAgZW50ZXJwcmlzZUNoYWxsZW5nZTogZW50ZXJwcmlzZUNoYWxsZW5nZXMsXG4gICAgICAgICAgYml0Z29DaGFsbGVuZ2U6IGJpdGdvQ2hhbGxlbmdlcyxcbiAgICAgICAgfSxcbiAgICAgICAgcHJ2OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgcFNoYXJlOiB1c2VyS2V5U2hhcmUucFNoYXJlLFxuICAgICAgICAgIGJpdGdvTlNoYXJlOiBiaXRnb0tleVNoYXJlLm5TaGFyZXNbMV0sXG4gICAgICAgICAgYmFja3VwTlNoYXJlOiBiYWNrdXBLZXlTaGFyZS5uU2hhcmVzWzFdLFxuICAgICAgICB9KSxcbiAgICAgICAgcmVxdWVzdFR5cGU6IFJlcXVlc3RUeXBlLnR4LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBtb2NrUGFzc3dvcmQsXG4gICAgICB9KTtcbiAgICAgIHN0ZXAxU2lnbmluZ01hdGVyaWFsLnByaXZhdGVTaGFyZVByb29mLnNob3VsZC5zdGFydFdpdGgoJy0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLScpO1xuICAgICAgc3RlcDFTaWduaW5nTWF0ZXJpYWwudnNzUHJvb2Y/Lmxlbmd0aC5zaG91bGQuZXF1YWwodXNlcktleVNoYXJlLm5TaGFyZXNbM10udj8ubGVuZ3RoKTtcbiAgICAgIHN0ZXAxU2lnbmluZ01hdGVyaWFsLnB1YmxpY1NoYXJlLmxlbmd0aC5zaG91bGQuZXF1YWwoXG4gICAgICAgIHVzZXJLZXlTaGFyZS5uU2hhcmVzWzNdLnkubGVuZ3RoICsgdXNlcktleVNoYXJlLm5TaGFyZXNbM10uY2hhaW5jb2RlLmxlbmd0aFxuICAgICAgKTtcbiAgICAgIHN0ZXAxU2lnbmluZ01hdGVyaWFsLmVuY3J5cHRlZFNpZ25lck9mZnNldFNoYXJlLnNob3VsZC5zdGFydFdpdGgoJy0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLScpO1xuICAgICAgc3RlcDFTaWduaW5nTWF0ZXJpYWwudXNlclB1YmxpY0dwZ0tleS5zaG91bGQuc3RhcnRXaXRoKCctLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS0nKTtcbiAgICAgIHN0ZXAxU2lnbmluZ01hdGVyaWFsLmtTaGFyZS5uLnNob3VsZC5lcXVhbCh1c2VyS2V5U2hhcmUucFNoYXJlLm4pO1xuICAgICAgc3RlcDFTaWduaW5nTWF0ZXJpYWwud1NoYXJlLnNob3VsZC5zdGFydFdpdGgoJ3tcIml2XCI6Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnY3JlYXRlT2ZmbGluZUtTaGFyZSBzaG91bGQgZmFpbCB3aXRoIHR4SWQgcGFzc2VkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbW9ja1Bhc3N3b3JkID0gJ3Bhc3N3b3JkJztcbiAgICAgIGF3YWl0IHRzc1V0aWxzXG4gICAgICAgIC5jcmVhdGVPZmZsaW5lS1NoYXJlKHtcbiAgICAgICAgICB0c3NQYXJhbXM6IHtcbiAgICAgICAgICAgIHR4UmVxdWVzdDogdHhSZXF1ZXN0LnR4UmVxdWVzdElkLFxuICAgICAgICAgICAgcmVxSWQ6IHJlcUlkLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgY2hhbGxlbmdlczoge1xuICAgICAgICAgICAgZW50ZXJwcmlzZUNoYWxsZW5nZTogZW50ZXJwcmlzZUNoYWxsZW5nZXMsXG4gICAgICAgICAgICBiaXRnb0NoYWxsZW5nZTogYml0Z29DaGFsbGVuZ2VzLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcHJ2OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICBwU2hhcmU6IHVzZXJLZXlTaGFyZS5wU2hhcmUsXG4gICAgICAgICAgICBiaXRnb05TaGFyZTogYml0Z29LZXlTaGFyZS5uU2hhcmVzWzFdLFxuICAgICAgICAgICAgYmFja3VwTlNoYXJlOiBiYWNrdXBLZXlTaGFyZS5uU2hhcmVzWzFdLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIHJlcXVlc3RUeXBlOiBSZXF1ZXN0VHlwZS50eCxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBtb2NrUGFzc3dvcmQsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIHR4UmVxdWVzdCB0eXBlJyk7XG4gICAgfSk7XG5cbiAgICAvLyBTZWVtcyB0byBiZSBmbGFreSBvbiBDSSwgZmFpbGVkIGhlcmU6IGh0dHBzOi8vZ2l0aHViLmNvbS9CaXRHby9CaXRHb0pTL2FjdGlvbnMvcnVucy81OTAyNDg5OTkwL2pvYi8xNjAxMDYyMzg4OD9wcj0zODIyXG4gICAgeGl0KCdjcmVhdGVPZmZsaW5lTXVEZWx0YVNoYXJlIHNob3VsZCBzdWNjZWVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbW9ja1Bhc3N3b3JkID0gJ3Bhc3N3b3JkJztcbiAgICAgIGNvbnN0IGFscGhhTGVuZ3RoID0gMTUzNjtcbiAgICAgIGNvbnN0IGRlbHRhTGVuZ3RoID0gNjQ7XG4gICAgICBjb25zdCBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICAgIGNvbnN0IHN0ZXAyU2lnbmluZ01hdGVyaWFsID0gYXdhaXQgdHNzVXRpbHMuY3JlYXRlT2ZmbGluZU11RGVsdGFTaGFyZSh7XG4gICAgICAgIGFTaGFyZUZyb21CaXRnbzogYVNoYXJlLFxuICAgICAgICBiaXRnb0NoYWxsZW5nZTogYml0Z29DaGFsbGVuZ2VzLFxuICAgICAgICBlbmNyeXB0ZWRXU2hhcmU6IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogSlNPTi5zdHJpbmdpZnkod1NoYXJlKSwgcGFzc3dvcmQ6IG1vY2tQYXNzd29yZCB9KSxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogbW9ja1Bhc3N3b3JkLFxuICAgICAgfSk7XG4gICAgICBzdGVwMlNpZ25pbmdNYXRlcmlhbC5tdURTaGFyZS5tdVNoYXJlLmFscGhhLmxlbmd0aC5zaG91bGQuZXF1YWwoYWxwaGFMZW5ndGgpO1xuICAgICAgc3RlcDJTaWduaW5nTWF0ZXJpYWwubXVEU2hhcmUuZFNoYXJlLmRlbHRhLmxlbmd0aC5zaG91bGQuZXF1YWwoZGVsdGFMZW5ndGgpO1xuICAgICAgc3RlcDJTaWduaW5nTWF0ZXJpYWwub1NoYXJlLnNob3VsZC5zdGFydFdpdGgoJ3tcIml2XCI6Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnY3JlYXRlT2ZmbGluZU11RGVsdGFTaGFyZSBzaG91bGQgZmFpbCB3aXRoIGluY29ycmVjdCBwYXNzd29yZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1vY2tQYXNzd29yZCA9ICdwYXNzd29yZCc7XG4gICAgICBjb25zdCBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICAgIGF3YWl0IHRzc1V0aWxzXG4gICAgICAgIC5jcmVhdGVPZmZsaW5lTXVEZWx0YVNoYXJlKHtcbiAgICAgICAgICBhU2hhcmVGcm9tQml0Z286IGFTaGFyZSxcbiAgICAgICAgICBiaXRnb0NoYWxsZW5nZTogYml0Z29DaGFsbGVuZ2VzLFxuICAgICAgICAgIGVuY3J5cHRlZFdTaGFyZTogYml0Z28uZW5jcnlwdCh7IGlucHV0OiBKU09OLnN0cmluZ2lmeSh3U2hhcmUpLCBwYXNzd29yZDogbW9ja1Bhc3N3b3JkIH0pLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdwYXNzd29yZDEnLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcInBhc3N3b3JkIGVycm9yIC0gY2NtOiB0YWcgZG9lc24ndCBtYXRjaFwiKTtcbiAgICB9KTtcblxuICAgIGl0KCdjcmVhdGVPZmZsaW5lU1NoYXJlIHNob3VsZCBzdWNjZWVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbW9ja1Bhc3N3b3JkID0gJ3Bhc3N3b3JkJztcbiAgICAgIGNvbnN0IHB1YktleUxlbmd0aCA9IDY2O1xuICAgICAgY29uc3QgcHJpdktleUxlbmd0aCA9IDY0O1xuICAgICAgY29uc3QgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R28sIHsgZW52OiAnbW9jaycgfSk7XG4gICAgICBjb25zdCBzdGVwM1NpZ25pbmdNYXRlcmlhbCA9IGF3YWl0IHRzc1V0aWxzLmNyZWF0ZU9mZmxpbmVTU2hhcmUoe1xuICAgICAgICB0c3NQYXJhbXM6IHtcbiAgICAgICAgICB0eFJlcXVlc3Q6IHR4UmVxdWVzdCxcbiAgICAgICAgICByZXFJZDogcmVxSWQsXG4gICAgICAgIH0sXG4gICAgICAgIGRTaGFyZUZyb21CaXRnbzogZFNoYXJlLFxuICAgICAgICBlbmNyeXB0ZWRPU2hhcmU6IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogSlNPTi5zdHJpbmdpZnkob1NoYXJlKSwgcGFzc3dvcmQ6IG1vY2tQYXNzd29yZCB9KSxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogbW9ja1Bhc3N3b3JkLFxuICAgICAgICByZXF1ZXN0VHlwZTogUmVxdWVzdFR5cGUudHgsXG4gICAgICB9KTtcbiAgICAgIHN0ZXAzU2lnbmluZ01hdGVyaWFsLlIubGVuZ3RoLnNob3VsZC5lcXVhbChwdWJLZXlMZW5ndGgpO1xuICAgICAgc3RlcDNTaWduaW5nTWF0ZXJpYWwueS5sZW5ndGguc2hvdWxkLmVxdWFsKHB1YktleUxlbmd0aCk7XG4gICAgICBzdGVwM1NpZ25pbmdNYXRlcmlhbC5zLmxlbmd0aC5zaG91bGQuZXF1YWwocHJpdktleUxlbmd0aCk7XG4gICAgfSk7XG5cbiAgICBpdCgnY3JlYXRlT2ZmbGluZVNTaGFyZSBzaG91bGQgZmFpbCB3aXRoIHR4SWQgcGFzc2VkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbW9ja1Bhc3N3b3JkID0gJ3Bhc3N3b3JkJztcbiAgICAgIGNvbnN0IGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ21vY2snIH0pO1xuICAgICAgYXdhaXQgdHNzVXRpbHNcbiAgICAgICAgLmNyZWF0ZU9mZmxpbmVTU2hhcmUoe1xuICAgICAgICAgIHRzc1BhcmFtczoge1xuICAgICAgICAgICAgdHhSZXF1ZXN0OiB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsXG4gICAgICAgICAgICByZXFJZDogcmVxSWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBkU2hhcmVGcm9tQml0Z286IGRTaGFyZSxcbiAgICAgICAgICBlbmNyeXB0ZWRPU2hhcmU6IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogSlNPTi5zdHJpbmdpZnkob1NoYXJlKSwgcGFzc3dvcmQ6IG1vY2tQYXNzd29yZCB9KSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBtb2NrUGFzc3dvcmQsXG4gICAgICAgICAgcmVxdWVzdFR5cGU6IFJlcXVlc3RUeXBlLnR4LFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnSW52YWxpZCB0eFJlcXVlc3QgdHlwZScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3NpZ25UeFJlcXVlc3Qgc2hvdWxkIGZhaWwgd2l0aCBpbnZhbGlkIHVzZXIgcHJ2JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaW52YWxpZFVzZXJLZXkgPSB7IC4uLnVzZXJLZXlTaGFyZSwgcFNoYXJlOiB7IC4uLnVzZXJLZXlTaGFyZS5wU2hhcmUsIGk6IDIgfSB9O1xuICAgICAgYXdhaXQgdHNzVXRpbHNcbiAgICAgICAgLnNpZ25UeFJlcXVlc3Qoe1xuICAgICAgICAgIHR4UmVxdWVzdDogdHhSZXF1ZXN0SWQsXG4gICAgICAgICAgcHJ2OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICBwU2hhcmU6IGludmFsaWRVc2VyS2V5LnBTaGFyZSxcbiAgICAgICAgICAgIGJpdGdvTlNoYXJlOiBiaXRnb0tleVNoYXJlLm5TaGFyZXNbMV0sXG4gICAgICAgICAgICBiYWNrdXBOU2hhcmU6IGJhY2t1cEtleVNoYXJlLm5TaGFyZXNbMV0sXG4gICAgICAgICAgfSksXG4gICAgICAgICAgcmVxSWQsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIHVzZXIga2V5Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2lnblR4UmVxdWVzdCBzaG91bGQgZmFpbCB3aXRoIG5vIGJhY2t1cE5TaGFyZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBnZXRUeFJlcXVlc3QgPSBzYW5kYm94LnN0dWIodHNzVXRpbHMsICdnZXRUeFJlcXVlc3QnKTtcbiAgICAgIGdldFR4UmVxdWVzdC5yZXNvbHZlcyh0eFJlcXVlc3QpO1xuICAgICAgZ2V0VHhSZXF1ZXN0LmNhbGxlZFdpdGgodHhSZXF1ZXN0SWQpO1xuICAgICAgc2V0dXBTaWduVHhSZXF1ZXN0Tm9ja3MoZmFsc2UsIHVzZXJTaWduU2hhcmUsIGFTaGFyZSwgZFNoYXJlLCBlbnRlcnByaXNlRGF0YSk7XG4gICAgICBhd2FpdCB0c3NVdGlsc1xuICAgICAgICAuc2lnblR4UmVxdWVzdCh7XG4gICAgICAgICAgdHhSZXF1ZXN0OiB0eFJlcXVlc3RJZCxcbiAgICAgICAgICBwcnY6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgIHBTaGFyZTogdXNlcktleVNoYXJlLnBTaGFyZSxcbiAgICAgICAgICAgIGJpdGdvTlNoYXJlOiBiaXRnb0tleVNoYXJlLm5TaGFyZXNbMV0sXG4gICAgICAgICAgfSksXG4gICAgICAgICAgcmVxSWQsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIHVzZXIga2V5IC0gbWlzc2luZyBiYWNrdXBOU2hhcmUnKTtcbiAgICB9KTtcblxuICAgIGFzeW5jIGZ1bmN0aW9uIHNldHVwU2lnblR4UmVxdWVzdE5vY2tzKFxuICAgICAgaXNUeFJlcXVlc3QgPSB0cnVlLFxuICAgICAgdXNlclNpZ25TaGFyZTogRUNEU0EuU2lnblNoYXJlUlQsXG4gICAgICBhU2hhcmU6IEVDRFNBLkFTaGFyZSxcbiAgICAgIGRTaGFyZTogRUNEU0EuRFNoYXJlLFxuICAgICAgZW50ZXJwcmlzZURhdGE6IEVudGVycHJpc2VEYXRhLFxuICAgICAge1xuICAgICAgICBzaWduYWJsZUhleCxcbiAgICAgICAgc2VyaWFsaXplZFR4SGV4LFxuICAgICAgICBhcGlWZXJzaW9uLFxuICAgICAgfTogeyBzaWduYWJsZUhleD86IHN0cmluZzsgc2VyaWFsaXplZFR4SGV4Pzogc3RyaW5nOyBhcGlWZXJzaW9uPzogJ2Z1bGwnIHwgJ2xpdGUnIH0gPSB7fVxuICAgICkge1xuICAgICAgaWYgKGVudGVycHJpc2VEYXRhKSB7XG4gICAgICAgIGF3YWl0IG5vY2tHZXRFbnRlcnByaXNlKHsgZW50ZXJwcmlzZUlkOiBlbnRlcnByaXNlRGF0YS5pZCwgcmVzcG9uc2U6IGVudGVycHJpc2VEYXRhLCB0aW1lczogMSB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRlcml2YXRpb25QYXRoID0gJyc7XG4gICAgICBzaW5vbi5zdHViKEVDRFNBTWV0aG9kcywgJ2NyZWF0ZVVzZXJTaWduU2hhcmUnKS5yZXNvbHZlcyh1c2VyU2lnblNoYXJlKTtcbiAgICAgIGxldCByZXNwb25zZSA9IHtcbiAgICAgICAgdHhSZXF1ZXN0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLnR4UmVxdWVzdCxcbiAgICAgICAgICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgLi4udHhSZXF1ZXN0LFxuICAgICAgICAgICAgICAgIHVuc2lnbmVkVHg6IHtcbiAgICAgICAgICAgICAgICAgIHNpZ25hYmxlSGV4OiBzaWduYWJsZUhleCA/PyB0eFJlcXVlc3QudW5zaWduZWRUeHNbMF0uc2lnbmFibGVIZXgsXG4gICAgICAgICAgICAgICAgICBzZXJpYWxpemVkVHhIZXg6IHNlcmlhbGl6ZWRUeEhleCA/PyB0eFJlcXVlc3QudW5zaWduZWRUeHNbMF0uc2VyaWFsaXplZFR4SGV4LFxuICAgICAgICAgICAgICAgICAgZGVyaXZhdGlvblBhdGgsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBhcGlWZXJzaW9uOiBhcGlWZXJzaW9uLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgICAgaWYgKGlzVHhSZXF1ZXN0KSB7XG4gICAgICAgIGF3YWl0IG5vY2tHZXRUeFJlcXVlc3QoeyB3YWxsZXRJZDogd2FsbGV0LmlkKCksIHR4UmVxdWVzdElkOiB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsIHJlc3BvbnNlOiByZXNwb25zZSB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGFSZWNvcmQgPSBFQ0RTQU1ldGhvZHMuY29udmVydEFTaGFyZShhU2hhcmUpO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlU2hhcmVzID0gW2FSZWNvcmRdO1xuICAgICAgdHhSZXF1ZXN0LnNpZ25hdHVyZVNoYXJlcyA9IHNpZ25hdHVyZVNoYXJlcztcbiAgICAgIHJlc3BvbnNlID0ge1xuICAgICAgICB0eFJlcXVlc3RzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgLi4udHhSZXF1ZXN0LFxuICAgICAgICAgICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAuLi50eFJlcXVlc3QsXG4gICAgICAgICAgICAgICAgdW5zaWduZWRUeDoge1xuICAgICAgICAgICAgICAgICAgc2lnbmFibGVIZXg6IHR4UmVxdWVzdC51bnNpZ25lZFR4c1swXS5zaWduYWJsZUhleCxcbiAgICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWRUeEhleDogdHhSZXF1ZXN0LnVuc2lnbmVkVHhzWzBdLnNlcmlhbGl6ZWRUeEhleCxcbiAgICAgICAgICAgICAgICAgIGRlcml2YXRpb25QYXRoLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgYXBpVmVyc2lvbjogYXBpVmVyc2lvbixcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICAgIGF3YWl0IG5vY2tHZXRUeFJlcXVlc3QoeyB3YWxsZXRJZDogd2FsbGV0LmlkKCksIHR4UmVxdWVzdElkOiB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsIHJlc3BvbnNlOiByZXNwb25zZSB9KTtcbiAgICAgIGNvbnN0IGRSZWNvcmQgPSBFQ0RTQU1ldGhvZHMuY29udmVydERTaGFyZShkU2hhcmUpO1xuICAgICAgc2lnbmF0dXJlU2hhcmVzLnB1c2goZFJlY29yZCk7XG4gICAgICByZXNwb25zZSA9IHtcbiAgICAgICAgdHhSZXF1ZXN0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLnR4UmVxdWVzdCxcbiAgICAgICAgICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgLi4udHhSZXF1ZXN0LFxuICAgICAgICAgICAgICAgIHVuc2lnbmVkVHg6IHtcbiAgICAgICAgICAgICAgICAgIHNpZ25hYmxlSGV4OiB0eFJlcXVlc3QudW5zaWduZWRUeHNbMF0uc2lnbmFibGVIZXgsXG4gICAgICAgICAgICAgICAgICBzZXJpYWxpemVkVHhIZXg6IHR4UmVxdWVzdC51bnNpZ25lZFR4c1swXS5zZXJpYWxpemVkVHhIZXgsXG4gICAgICAgICAgICAgICAgICBkZXJpdmF0aW9uUGF0aCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGFwaVZlcnNpb246IGFwaVZlcnNpb24sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgICBhd2FpdCBub2NrR2V0VHhSZXF1ZXN0KHsgd2FsbGV0SWQ6IHdhbGxldC5pZCgpLCB0eFJlcXVlc3RJZDogdHhSZXF1ZXN0LnR4UmVxdWVzdElkLCByZXNwb25zZTogcmVzcG9uc2UgfSk7XG4gICAgICBhd2FpdCBub2NrR2V0VHhSZXF1ZXN0KHsgd2FsbGV0SWQ6IHdhbGxldC5pZCgpLCB0eFJlcXVlc3RJZDogdHhSZXF1ZXN0LnR4UmVxdWVzdElkLCByZXNwb25zZTogcmVzcG9uc2UgfSk7XG4gICAgfVxuICB9KTtcblxuICBkZXNjcmliZSgnZ2V0RWNkc2FTaWduaW5nQ2hhbGxlbmdlcycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBtb2NrV2FsbGV0UGFpbGxpZXJLZXkgPSB7XG4gICAgICBuOiAnZjQ3YmU0YzJkOGJjMWUyOGY4OGM2YzRkYTYzNGRhOTdkOTJhMWMyNzlhN2IwZmU3Yjg3YzMzN2MzNmEyN2IzMmNlMGZmMGM0NWYxNmU0ZTE1YmJkMjBlNGU2NDBkZTEyMDQ3ZWZmOWIxYTJiOTgxNDRmOWEyNjhkNDA2YmQwMDBkMTkyYTM1YjY4NDdhMTdlNDBmYjg1ZjU1YjMxNGQwMDFmZjg3MzkzNDgxY2FmZTM5MTgwN2QwZWI4M2VmZjllMzg2MTRiMzhlNWYyNWZjNDQ0OWNiMDFjYWVkODA1NTg0ZDAyNmI1ZDg2NmM3MjNmM2Q0ZDRmMWU0NjI2NjJmMjExM2IxNTYxZWIyYmY3NTViNGI5MWQwMzA4ZDhlYWNjNDM5MTY3ZGE4YjdkNmUxMDg1MjRmMjI2OTYwMzYwYWYwMDIxNWQ5NjE0NDU3NDE0ZWJkYmU4ODM0OTk5Njg5ZTJlOTAzMjA4Yzg3MTNmZjVkOTkwMWY5ZWFiYTNhYTgxZDcwNTMyM2NiYmJhNjFiYTdmYTlmMzIyOGYzMDg1M2ZiNTVkYTFiM2QzZWQ3ZGIxZGZjNjU0NWJjOTZhYThkMmViODQ4OTMxYzFiODA3ZmRmZThmNjVhZjcyZjY4NjM4YTgyZmU5ZTIyYWMxZjBmMDMyZTYyMTA2NjgwNmExZjE0NGI1NzE5YTVmMDkxOTg2ODY3YjM4NGJlNmMzNDE0NmM4MjQxY2JmYmQ3ODE5NjZlYmJjZDE5ZTZjYWEyN2ZhYjA0MGU2MmU1YTE2Mjg4OGFhODYyNGQwNDZjOGZlM2I3MjI0NGYwNGE3MjY0YzRhMzZiNjM2NmRiZTdkYTk4YWZiMjAxZDM0YmUyYzBkNmRkMTE5ODJhZjM1YmY3NTM1NTgyYjI2MzkxNDcyNWFhZWMyODBkNTIyOTA1MjczODJkM2FiMjk3ZDc0NmM0MWFhY2Q4ZGU5OGMwOWZjZmI4NWE5NWUwMmRlMWIzNGQ0OTMzZTUxMDQ1ZTJmMWNlOGFmJyxcbiAgICAgIGxhbWJkYTpcbiAgICAgICAgJ2Y0N2JlNGMyZDhiYzFlMjhmODhjNmM0ZGE2MzRkYTk3ZDkyYTFjMjc5YTdiMGZlN2I4N2MzMzdjMzZhMjdiMzJjZTBmZjBjNDVmMTZlNGUxNWJiZDIwZTRlNjQwZGUxMjA0N2VmZjliMWEyYjk4MTQ0ZjlhMjY4ZDQwNmJkMDAwZDE5MmEzNWI2ODQ3YTE3ZTQwZmI4NWY1NWIzMTRkMDAxZmY4NzM5MzQ4MWNhZmUzOTE4MDdkMGViODNlZmY5ZTM4NjE0YjM4ZTVmMjVmYzQ0NDljYjAxY2FlZDgwNTU4NGQwMjZiNWQ4NjZjNzIzZjNkNGQ0ZjFlNDYyNjYyZjIxMTNiMTU2MWViMmJmNzU1YjRiOTFkMDMwOGQ4ZWFjYzQzOTE2N2RhOGI3ZDZlMTA4NTI0ZjIyNjk2MDM2MGFmMDAyMTVkOTYxNDQ1NzQxNGViZGJlODgzNDk5OTY4OWUyZTkwMzIwOGM4NzEzZmY1ZDk5MDFmOWVhYmEzYWE3ZmMzZDBjMGJjYzViZmY2NDQxNTZhYjg4NzE0NmQ1MWJjZWUxZWVmNzBmNDVjNDg2MTQ3ZDY4N2VlMzdkZWYxZjhhMTZiYzk0NWVmZjIyZGQ0ZGNhMzYxNGE5OTE1ODgyM2FjZDk0OTJlMzQ3ZjdlYzc5YTc3NzEwMjQyMDVkMDdmMjdiMzBjZDIwMzQwZTMzMDQxMWRhOGZhMmRhMjA5ZTVjYzY4OGRhOTRkMWRiZWY1NGJmZDljNjliNGU5OWNmMDZkNjczMDlhMzQyMGI4MmM3OGEwZmUwZGQwYjljMzEzODJlYWUzODc0NmNmZGQyN2ZhOTAwMjJhNTA1MzIyNDZjOGFlMTMzOWM5M2UxODNjMDNiZjZmZDcwMTRiZTM2NThhYmM3M2JhYWUxZmE1Yjg2ZGFiOTRiOWYxMjUzOTVhODE4ZTU0ZGRlNjIzNWM0NWQzZGJjMDMyYjMwNzhlOWRmMWNhZDY5ZDhhYzE5YTdjYjY0MDVhNTU4YjdiZmJhOCcsXG4gICAgfTtcbiAgICBjb25zdCBtb2NrQml0Z29QYWlsbGllcktleSA9IHtcbiAgICAgIG46ICdmMDEwZDI5NGVmZmNlYjhjNGY5NmFmMTk3OGFiMzY3YzRmYmIyNzJjMjE2OTMxN2U0MWFlODcyMjA2NTJjYWUyY2U5Mjk2OTZlZTU1ZWM2ODMxYWE2YjRiM2I5MzFiYWJjMmJhYzljMWEyMGZkZGJjYTkyNWNjOTk2ODA3OTFmN2MzMTU3YjNkMzEyNTZlZTcyYzQ3ZDQ3ZGI1NjdlMGYwNzBkY2UxMjFjM2E0ZDllMDAzYzFmMTM4OTA3M2FjYjI1MmM2NWQyYjA3MjNlODZlMzI2NWY2N2ExMzdjYjFlMjNmNDU1MTU0NDQwNTY0NGQwYWU2M2QzNWYyNWY0MGJlY2QyYjY5Mzg3OWYzYmRiZWMzZjcyNTA3OTFhM2YzYzk3NWE1YWM3OGEwZTgxZGNkMWE4N2ViMmNhNjcwMTBkZmY4ODBiMjMzODU1NjI3NWRlMjNkOWU4OGQyMWI3N2RhMGQ1MjRkZGMyYjM5NGY4ZGUwMGIxYWYwY2U4NWY2ZWVlMmUwNWExODRlMDU0OTRkNjZkMmM2MzYwNDViZjcwZWQxNWViZDBmNDFhOGVlYTI5MjBhZjg1ZTZkNjhhMGNlMTFmYzJhYmJjYjNjZWJjYzNjMjNlYzJlMTQ4YzMxODY4M2E1NDI2ZTE1YjUyMDdlZmQzYjliMDVjYjkxOWVjNDM0MGY3NGRmZjMzNjk4NmQwYzkyM2RmMTBhNzg5MDA3YjFkYTlkYWRkZjhlZGYzMDE0ZTkzOTg5ZjMwMjQzZjI3ZjlhMzA3ZDU1ZDYzMGNiZmNkMTZjZDZhOTVhNDFkZWUxMGMzMWFjYzI5M2RmNjgzNGNlMGUzZWE1YjY4ZjE3MGJkNzkzOGVhMGMyZWViNzg4ZTE2ZjMwYWY1N2IzZjA4ODhmYjQ0ZDM2MTBlN2VlYmE2MGU3ZmQ4Y2M0YThmMDQ0NzE4ZGZjNjE3NGJmNGEzODA2OTBkYzFkYzc3NDcyYTQ4ODkyZWIzZTgxNzc1NTQwZWEwYWNjOWU4OWI2MzknLFxuICAgICAgbGFtYmRhOlxuICAgICAgICAnZjAxMGQyOTRlZmZjZWI4YzRmOTZhZjE5NzhhYjM2N2M0ZmJiMjcyYzIxNjkzMTdlNDFhZTg3MjIwNjUyY2FlMmNlOTI5Njk2ZWU1NWVjNjgzMWFhNmI0YjNiOTMxYmFiYzJiYWM5YzFhMjBmZGRiY2E5MjVjYzk5NjgwNzkxZjdjMzE1N2IzZDMxMjU2ZWU3MmM0N2Q0N2RiNTY3ZTBmMDcwZGNlMTIxYzNhNGQ5ZTAwM2MxZjEzODkwNzNhY2IyNTJjNjVkMmIwNzIzZTg2ZTMyNjVmNjdhMTM3Y2IxZTIzZjQ1NTE1NDQ0MDU2NDRkMGFlNjNkMzVmMjVmNDBiZWNkMmI2OTM4NzlmM2JkYmVjM2Y3MjUwNzkxYTNmM2M5NzVhNWFjNzhhMGU4MWRjZDFhODdlYjJjYTY3MDEwZGZmODgwYjIzMzg1NTYyNzVkZTIzZDllODhkMjFiNzdkYTBkNTI0ZGRjMmIzOTRmOGRlMDBiMWFmMGNlODVmNmVjZGVmOGE0YmM5NTVhMjhlY2VmN2Q5N2NkZWQwNzlkMzkwZTc3YzgwOTk4ZDc4YWQ5NTEwY2JhYmZlYjhmMGExNTdkYmZjNTkwYjRkNTllZThjMGIwODhmOWQ4OTQ3M2I1NTczMjAwNzhhMTE3NDc4NjI0ZjVkMWRmMzZlMzBmMzIwYjY3MjJhNDIxN2RjYjQ2Yjk3OGNjNmM4ZjFhMjFjOGE2Yzc0YmNlODRkODJjNDgxNDAyYzk5YTY5Yjc5OGUzYzA1ZjIzMzUwYjRhYWRlNGY3OTc4NGIxYzA5NjkyYjZhMzNjZmJhN2YxNDU1OTdkODJiNzk5Y2NjZWY2MjBjMzZmMWZiYmUyY2I0YWMwZWEzOTVjNDc2ZTM4MWJjNDc1ZDQxNzIyMzIwZjU0MWFlOWJmNTZhYTRhMTJkZmYzZWE3YWIxMTE3NGZiNWI4ZGY3NDI5YzlmNTdkMzZmOGZjNTFlMWE4YzY0N2Q1YjhmYTAxODlmYjhhY2RiZDBhNzgwJyxcbiAgICB9O1xuICAgIGNvbnN0IGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ21vY2snIH0pO1xuICAgIGNvbnN0IHR4UmVxdWVzdElkID0gJ2Zha2VUeFJlcXVlc3RJZCc7XG4gICAgY29uc3QgcmF3RW50Q2hhbGxlbmdlV2l0aFByb29mczogRWNkc2FUeXBlcy5TZXJpYWxpemVkTnRpbGRlV2l0aFByb29mcyA9IG1vY2tTZXJpYWxpemVkQ2hhbGxlbmdlV2l0aFByb29mcztcbiAgICBsZXQgcmF3Qml0Z29DaGFsbGVuZ2U6IEVjZHNhVHlwZXMuU2VyaWFsaXplZEVjZHNhQ2hhbGxlbmdlcyAmIHsgbjogc3RyaW5nIH07XG4gICAgY29uc3QgYWRtaW5FY2RoS2V5ID0gYml0Z28ua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgY29uc3QgZmFrZUFkbWluRWNkaEtleSA9IGJpdGdvLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgIGNvbnN0IGRlcml2YXRpb25QYXRoID0gJ20vMC8wJztcbiAgICBjb25zdCBtb2NrZWRTaWduaW5nS2V5ID0ge1xuICAgICAgdXNlcklkOiAnaWQnLFxuICAgICAgdXNlckVtYWlsOiAndXNlckBiaXRnby5jb20nLFxuICAgICAgZGVyaXZlZFB1YmtleTogYmlwMzIuZnJvbUJhc2U1OChhZG1pbkVjZGhLZXkueHB1YikuZGVyaXZlUGF0aChkZXJpdmF0aW9uUGF0aCkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgIGRlcml2YXRpb25QYXRoOiBkZXJpdmF0aW9uUGF0aCxcbiAgICAgIGVjZGhLZXljaGFpbjogJ215IGtleWNoYWluJyxcbiAgICB9O1xuXG4gICAgYmVmb3JlKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHAgPSBhd2FpdCBFY2RzYVBhaWxsaWVyUHJvb2YuZ2VuZXJhdGVQKGhleFRvQmlnSW50KG1vY2tXYWxsZXRQYWlsbGllcktleS5uKSk7XG4gICAgICByYXdCaXRnb0NoYWxsZW5nZSA9IHtcbiAgICAgICAgLi4uRWNkc2FUeXBlcy5zZXJpYWxpemVOdGlsZGUoRWNkc2FUeXBlcy5kZXNlcmlhbGl6ZU50aWxkZShtb2NrU2VyaWFsaXplZENoYWxsZW5nZVdpdGhQcm9vZnMyKSksXG4gICAgICAgIHA6IEVjZHNhVHlwZXMuc2VyaWFsaXplUGFpbGxpZXJDaGFsbGVuZ2UoeyBwIH0pLnAsXG4gICAgICAgIG46IG1vY2tCaXRnb1BhaWxsaWVyS2V5Lm4sXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmV0Y2ggc3RhdGljIGVudCBhbmQgYml0Z28gY2hhbGxlbmdlcyB3aXRoIHRoZSBlbnQgZmVhdHVyZSBmbGFnIGFuZCB2ZXJpZnkgdGhlbScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IG5vY2tHZXRDaGFsbGVuZ2UoeyB3YWxsZXRJZCwgdHhSZXF1ZXN0SWQsIGFkZGVuZHVtOiAnL3RyYW5zYWN0aW9ucy8wJywgcmVzcG9uc2U6IHJhd0JpdGdvQ2hhbGxlbmdlIH0pO1xuICAgICAgYXdhaXQgbm9ja0dldFNpZ25pbmdLZXkoeyBlbnRlcnByaXNlSWQsIHVzZXJJZDogbW9ja2VkU2lnbmluZ0tleS51c2VySWQsIHJlc3BvbnNlOiBtb2NrZWRTaWduaW5nS2V5LCB0aW1lczogMSB9KTtcbiAgICAgIGNvbnN0IGFkbWluU2lnbmF0dXJlRW50Q2hhbGxlbmdlID0gRUNEU0FVdGlscy5FY2RzYVV0aWxzLnNpZ25DaGFsbGVuZ2UoXG4gICAgICAgIHJhd0VudENoYWxsZW5nZVdpdGhQcm9vZnMsXG4gICAgICAgIGFkbWluRWNkaEtleS54cHJ2LFxuICAgICAgICBkZXJpdmF0aW9uUGF0aFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGFkbWluU2lnbmF0dXJlQml0R29DaGFsbGVuZ2UgPSBFQ0RTQVV0aWxzLkVjZHNhVXRpbHMuc2lnbkNoYWxsZW5nZShcbiAgICAgICAgcmF3Qml0Z29DaGFsbGVuZ2UsXG4gICAgICAgIGFkbWluRWNkaEtleS54cHJ2LFxuICAgICAgICBkZXJpdmF0aW9uUGF0aFxuICAgICAgKTtcbiAgICAgIGNvbnN0IG1vY2tDaGFsbGVuZ2VzUmVzcG9uc2UgPSB7XG4gICAgICAgIGVudGVycHJpc2VDaGFsbGVuZ2U6IHtcbiAgICAgICAgICAuLi5yYXdFbnRDaGFsbGVuZ2VXaXRoUHJvb2ZzLFxuICAgICAgICAgIHZlcmlmaWVyczoge1xuICAgICAgICAgICAgYWRtaW5TaWduYXR1cmU6IGFkbWluU2lnbmF0dXJlRW50Q2hhbGxlbmdlLnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0NoYWxsZW5nZToge1xuICAgICAgICAgIC4uLnJhd0JpdGdvQ2hhbGxlbmdlLFxuICAgICAgICAgIHZlcmlmaWVyczoge1xuICAgICAgICAgICAgYWRtaW5TaWduYXR1cmU6IGFkbWluU2lnbmF0dXJlQml0R29DaGFsbGVuZ2UudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGNyZWF0ZWRCeTogJ2lkJyxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IG5vY2tHZXRDaGFsbGVuZ2VzKHsgd2FsbGV0SWQ6IHdhbGxldElkLCByZXNwb25zZTogbW9ja0NoYWxsZW5nZXNSZXNwb25zZSB9KTtcbiAgICAgIGNvbnN0IGNoYWxsZW5nZXMgPSBhd2FpdCB0c3NVdGlscy5nZXRFY2RzYVNpZ25pbmdDaGFsbGVuZ2VzKHR4UmVxdWVzdElkLCAwLCBtb2NrV2FsbGV0UGFpbGxpZXJLZXkubiwgMCk7XG4gICAgICBzaG91bGQuZXhpc3QoY2hhbGxlbmdlcyk7XG4gICAgICBjb25zdCBleHBlY3RlZFJhbmdlUHJvb2ZDaGFsbGVuZ2VzID0ge1xuICAgICAgICBlbnRlcnByaXNlQ2hhbGxlbmdlOiB7XG4gICAgICAgICAgbnRpbGRlOiBjaGFsbGVuZ2VzLmVudGVycHJpc2VDaGFsbGVuZ2UubnRpbGRlLFxuICAgICAgICAgIGgxOiBjaGFsbGVuZ2VzLmVudGVycHJpc2VDaGFsbGVuZ2UuaDEsXG4gICAgICAgICAgaDI6IGNoYWxsZW5nZXMuZW50ZXJwcmlzZUNoYWxsZW5nZS5oMixcbiAgICAgICAgfSxcbiAgICAgICAgYml0Z29DaGFsbGVuZ2U6IHJhd0JpdGdvQ2hhbGxlbmdlLFxuICAgICAgfTtcbiAgICAgIGV4cGVjdGVkUmFuZ2VQcm9vZkNoYWxsZW5nZXMuc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGVudGVycHJpc2VDaGFsbGVuZ2U6IHtcbiAgICAgICAgICBudGlsZGU6IHJhd0VudENoYWxsZW5nZVdpdGhQcm9vZnMubnRpbGRlLFxuICAgICAgICAgIGgxOiByYXdFbnRDaGFsbGVuZ2VXaXRoUHJvb2ZzLmgxLFxuICAgICAgICAgIGgyOiByYXdFbnRDaGFsbGVuZ2VXaXRoUHJvb2ZzLmgyLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0NoYWxsZW5nZTogcmF3Qml0Z29DaGFsbGVuZ2UsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdGYWlscyBpZiB0aGUgZW50ZXJwcmlzZSBjaGFsbGVuZ2Ugc2lnbmF0dXJlIGlzIGRpZmZlcmVudCBmcm9tIHRoZSBhZG1pbiBlY2RoIGtleScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IG5vY2tHZXRDaGFsbGVuZ2UoeyB3YWxsZXRJZCwgdHhSZXF1ZXN0SWQsIGFkZGVuZHVtOiAnL3RyYW5zYWN0aW9ucy8wJywgcmVzcG9uc2U6IHJhd0JpdGdvQ2hhbGxlbmdlIH0pO1xuICAgICAgYXdhaXQgbm9ja0dldEVudGVycHJpc2Uoe1xuICAgICAgICBlbnRlcnByaXNlSWQ6IGVudGVycHJpc2VEYXRhLmlkLFxuICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgIC4uLmVudGVycHJpc2VEYXRhLFxuICAgICAgICAgIGZlYXR1cmVGbGFnczogWyd1c2VFbnRlcnByaXNlRWNkc2FUc3NDaGFsbGVuZ2UnXSxcbiAgICAgICAgfSxcbiAgICAgICAgdGltZXM6IDEsXG4gICAgICB9KTtcbiAgICAgIGF3YWl0IG5vY2tHZXRTaWduaW5nS2V5KHsgZW50ZXJwcmlzZUlkLCB1c2VySWQ6IG1vY2tlZFNpZ25pbmdLZXkudXNlcklkLCByZXNwb25zZTogbW9ja2VkU2lnbmluZ0tleSwgdGltZXM6IDEgfSk7XG4gICAgICAvLyBCYWQgc2lnblxuICAgICAgY29uc3QgYWRtaW5TaWduZWRFbnRDaGFsbGVuZ2UgPSBFQ0RTQVV0aWxzLkVjZHNhVXRpbHMuc2lnbkNoYWxsZW5nZShcbiAgICAgICAgcmF3RW50Q2hhbGxlbmdlV2l0aFByb29mcyxcbiAgICAgICAgZmFrZUFkbWluRWNkaEtleS54cHJ2LFxuICAgICAgICBkZXJpdmF0aW9uUGF0aFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGFkbWluU2lnbmVkQml0R29DaGFsbGVuZ2UgPSBFQ0RTQVV0aWxzLkVjZHNhVXRpbHMuc2lnbkNoYWxsZW5nZShcbiAgICAgICAgcmF3Qml0Z29DaGFsbGVuZ2UsXG4gICAgICAgIGFkbWluRWNkaEtleS54cHJ2LFxuICAgICAgICBkZXJpdmF0aW9uUGF0aFxuICAgICAgKTtcbiAgICAgIGNvbnN0IG1vY2tDaGFsbGVuZ2VzUmVzcG9uc2UgPSB7XG4gICAgICAgIGVudGVycHJpc2VDaGFsbGVuZ2U6IHtcbiAgICAgICAgICAuLi5yYXdFbnRDaGFsbGVuZ2VXaXRoUHJvb2ZzLFxuICAgICAgICAgIHZlcmlmaWVyczoge1xuICAgICAgICAgICAgYWRtaW5TaWduYXR1cmU6IGFkbWluU2lnbmVkRW50Q2hhbGxlbmdlLnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0NoYWxsZW5nZToge1xuICAgICAgICAgIC4uLnJhd0JpdGdvQ2hhbGxlbmdlLFxuICAgICAgICAgIHZlcmlmaWVyczoge1xuICAgICAgICAgICAgYWRtaW5TaWduYXR1cmU6IGFkbWluU2lnbmVkQml0R29DaGFsbGVuZ2UudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGNyZWF0ZWRCeTogJ2lkJyxcbiAgICAgIH07XG4gICAgICBhd2FpdCBub2NrR2V0Q2hhbGxlbmdlcyh7IHdhbGxldElkOiB3YWxsZXRJZCwgcmVzcG9uc2U6IG1vY2tDaGFsbGVuZ2VzUmVzcG9uc2UgfSk7XG4gICAgICBhd2FpdCB0c3NVdGlsc1xuICAgICAgICAuZ2V0RWNkc2FTaWduaW5nQ2hhbGxlbmdlcyh0eFJlcXVlc3RJZCwgMCwgbW9ja1dhbGxldFBhaWxsaWVyS2V5Lm4pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdBZG1pbiBzaWduYXR1cmUgZm9yIGVudGVycHJpc2UgY2hhbGxlbmdlIGlzIG5vdCB2YWxpZC4gUGxlYXNlIGNvbnRhY3QgeW91ciBlbnRlcnByaXNlIGFkbWluLidcbiAgICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdGYWlscyBpZiB0aGUgYml0Z28gY2hhbGxlbmdlIHNpZ25hdHVyZSBpcyBkaWZmZXJlbnQgZnJvbSB0aGUgYWRtaW4gZWNkaCBrZXknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBub2NrR2V0Q2hhbGxlbmdlKHsgd2FsbGV0SWQsIHR4UmVxdWVzdElkLCBhZGRlbmR1bTogJy90cmFuc2FjdGlvbnMvMCcsIHJlc3BvbnNlOiByYXdCaXRnb0NoYWxsZW5nZSB9KTtcbiAgICAgIGF3YWl0IG5vY2tHZXRFbnRlcnByaXNlKHtcbiAgICAgICAgZW50ZXJwcmlzZUlkOiBlbnRlcnByaXNlRGF0YS5pZCxcbiAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICAuLi5lbnRlcnByaXNlRGF0YSxcbiAgICAgICAgICBmZWF0dXJlRmxhZ3M6IFsndXNlRW50ZXJwcmlzZUVjZHNhVHNzQ2hhbGxlbmdlJ10sXG4gICAgICAgIH0sXG4gICAgICAgIHRpbWVzOiAxLFxuICAgICAgfSk7XG4gICAgICBhd2FpdCBub2NrR2V0U2lnbmluZ0tleSh7IGVudGVycHJpc2VJZCwgdXNlcklkOiBtb2NrZWRTaWduaW5nS2V5LnVzZXJJZCwgcmVzcG9uc2U6IG1vY2tlZFNpZ25pbmdLZXksIHRpbWVzOiAxIH0pO1xuICAgICAgY29uc3QgYWRtaW5TaWduZWRFbnRDaGFsbGVuZ2UgPSBFQ0RTQVV0aWxzLkVjZHNhVXRpbHMuc2lnbkNoYWxsZW5nZShcbiAgICAgICAgcmF3RW50Q2hhbGxlbmdlV2l0aFByb29mcyxcbiAgICAgICAgYWRtaW5FY2RoS2V5LnhwcnYsXG4gICAgICAgIGRlcml2YXRpb25QYXRoXG4gICAgICApO1xuICAgICAgLy8gQmFkIHNpZ25cbiAgICAgIGNvbnN0IGFkbWluU2lnbmVkQml0R29DaGFsbGVuZ2UgPSBFQ0RTQVV0aWxzLkVjZHNhVXRpbHMuc2lnbkNoYWxsZW5nZShcbiAgICAgICAgcmF3Qml0Z29DaGFsbGVuZ2UsXG4gICAgICAgIGZha2VBZG1pbkVjZGhLZXkueHBydixcbiAgICAgICAgZGVyaXZhdGlvblBhdGhcbiAgICAgICk7XG4gICAgICBjb25zdCBtb2NrQ2hhbGxlbmdlc1Jlc3BvbnNlID0ge1xuICAgICAgICBlbnRlcnByaXNlQ2hhbGxlbmdlOiB7XG4gICAgICAgICAgLi4ucmF3RW50Q2hhbGxlbmdlV2l0aFByb29mcyxcbiAgICAgICAgICB2ZXJpZmllcnM6IHtcbiAgICAgICAgICAgIGFkbWluU2lnbmF0dXJlOiBhZG1pblNpZ25lZEVudENoYWxsZW5nZS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgYml0Z29DaGFsbGVuZ2U6IHtcbiAgICAgICAgICAuLi5yYXdCaXRnb0NoYWxsZW5nZSxcbiAgICAgICAgICB2ZXJpZmllcnM6IHtcbiAgICAgICAgICAgIGFkbWluU2lnbmF0dXJlOiBhZG1pblNpZ25lZEJpdEdvQ2hhbGxlbmdlLnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBjcmVhdGVkQnk6ICdpZCcsXG4gICAgICB9O1xuICAgICAgYXdhaXQgbm9ja0dldENoYWxsZW5nZXMoeyB3YWxsZXRJZDogd2FsbGV0SWQsIHJlc3BvbnNlOiBtb2NrQ2hhbGxlbmdlc1Jlc3BvbnNlIH0pO1xuICAgICAgYXdhaXQgdHNzVXRpbHNcbiAgICAgICAgLmdldEVjZHNhU2lnbmluZ0NoYWxsZW5nZXModHhSZXF1ZXN0SWQsIDAsIG1vY2tXYWxsZXRQYWlsbGllcktleS5uKVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICBcIkFkbWluIHNpZ25hdHVyZSBmb3IgQml0R28ncyBjaGFsbGVuZ2UgaXMgbm90IHZhbGlkLiBQbGVhc2UgY29udGFjdCB5b3VyIGVudGVycHJpc2UgYWRtaW4uXCJcbiAgICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2dldFZlcmlmeUFuZFNpZ25CaXRHb0NoYWxsZW5nZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R28sIHsgZW52OiAnbW9jaycgfSk7XG4gICAgY29uc3QgYWRtaW5FY2RoS2V5ID0gYml0Z28ua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgY29uc3QgZGVyaXZhdGlvblBhdGggPSAnbS8wLzAnO1xuICAgIGNvbnN0IGJpdGdvSW5zdENoYWxsZW5nZSA9IG1vY2tDaGFsbGVuZ2VBO1xuICAgIGNvbnN0IGJpdGdvTml0cm9DaGFsbGVuZ2UgPSBtb2NrQ2hhbGxlbmdlQjtcbiAgICBjb25zdCB1c2VyUGFzc3dvcmQgPSAncGFzc3dvcmQxMjMnO1xuICAgIGNvbnN0IGVuY3J5cHRlZFhwcnYgPSBiaXRnby5lbmNyeXB0KHtcbiAgICAgIHBhc3N3b3JkOiB1c2VyUGFzc3dvcmQsXG4gICAgICBpbnB1dDogYWRtaW5FY2RoS2V5LnhwcnYsXG4gICAgfSk7XG5cbiAgICBiZWZvcmVFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRTaWduaW5nS2V5Rm9yVXNlcicpLnJlc29sdmVzKHtcbiAgICAgICAgdXNlcklkOiAnaWQnLFxuICAgICAgICB1c2VyRW1haWw6ICd1c2VyQGJpdGdvLmNvbScsXG4gICAgICAgIGRlcml2ZWRQdWJrZXk6IGJpcDMyLmZyb21CYXNlNTgoYWRtaW5FY2RoS2V5LnhwdWIpLmRlcml2ZVBhdGgoZGVyaXZhdGlvblBhdGgpLnB1YmxpY0tleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgIGRlcml2YXRpb25QYXRoOiBkZXJpdmF0aW9uUGF0aCxcbiAgICAgICAgZWNkaEtleWNoYWluOiAnbXkga2V5Y2hhaW4nLFxuICAgICAgfSk7XG4gICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZ2V0RUNESEtleWNoYWluJykucmVzb2x2ZXMoe1xuICAgICAgICBlbmNyeXB0ZWRYcHJ2OiBlbmNyeXB0ZWRYcHJ2LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgc2lub24ucmVzdG9yZSgpO1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gbm9ja0dldEJpdGdvQ2hhbGxlbmdlcyhyZXNwb25zZTogdW5rbm93bik6IG5vY2suU2NvcGUge1xuICAgICAgcmV0dXJuIG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoYC9hcGkvdjIvdHNzL2VjZHNhL2NoYWxsZW5nZXNgKVxuICAgICAgICAudGltZXMoMSlcbiAgICAgICAgLnJlcGx5KCgpID0+IFsyMDAsIHJlc3BvbnNlXSk7XG4gICAgfVxuXG4gICAgaXQoJ3N1Y2NlZWRzIGZvciB2YWxpZCBiaXRnbyBwcm9vZnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBub2NrR2V0Qml0Z29DaGFsbGVuZ2VzQXBpID0gbm9ja0dldEJpdGdvQ2hhbGxlbmdlcyh7XG4gICAgICAgIGJpdGdvTml0cm9Ic206IGJpdGdvTml0cm9DaGFsbGVuZ2UsXG4gICAgICAgIGJpdGdvSW5zdGl0dXRpb25hbEhzbTogYml0Z29JbnN0Q2hhbGxlbmdlLFxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IEVDRFNBVXRpbHMuRWNkc2FVdGlscy5nZXRWZXJpZnlBbmRTaWduQml0R29DaGFsbGVuZ2VzKFxuICAgICAgICBiaXRnbyxcbiAgICAgICAgJ2VudF9pZCcsXG4gICAgICAgIHVzZXJQYXNzd29yZFxuICAgICAgKS5zaG91bGQubm90LmJlLnJlamVjdGVkKCk7XG4gICAgICBub2NrR2V0Qml0Z29DaGFsbGVuZ2VzQXBpLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnRmFpbHMgaWYgYml0Z28gY2hhbGxlbmdlIHByb29mcyBhcmUgbm90IHByZXNlbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBub2NrR2V0Qml0Z29DaGFsbGVuZ2VzQXBpID0gbm9ja0dldEJpdGdvQ2hhbGxlbmdlcyh7XG4gICAgICAgIGJpdGdvTml0cm9Ic206IHtcbiAgICAgICAgICAuLi5iaXRnb05pdHJvQ2hhbGxlbmdlLFxuICAgICAgICAgIG50aWxkZVByb29mOiB1bmRlZmluZWQsXG4gICAgICAgIH0sXG4gICAgICAgIGJpdGdvSW5zdGl0dXRpb25hbEhzbTogYml0Z29JbnN0Q2hhbGxlbmdlLFxuICAgICAgfSk7XG4gICAgICBhd2FpdCBFQ0RTQVV0aWxzLkVjZHNhVXRpbHMuZ2V0VmVyaWZ5QW5kU2lnbkJpdEdvQ2hhbGxlbmdlcyhiaXRnbywgJ2VudF9pZCcsIHVzZXJQYXNzd29yZCkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgJ0V4cGVjdGVkIEJpdEdvIGNoYWxsZW5nZSBwcm9vZiB0byBiZSBwcmVzZW50LiBDb250YWN0IHN1cHBvcnRAYml0Z28uY29tLidcbiAgICAgICk7XG4gICAgICBub2NrR2V0Qml0Z29DaGFsbGVuZ2VzQXBpLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnRmFpbHMgaWYgdGhlIHVzZXIgcGFzc3dvcmQgdG8gZGVjcnlwdCB0aGUgZWNkaGtleWNoYWluIGlzIHdyb25nJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgbm9ja0dldEJpdGdvQ2hhbGxlbmdlc0FwaSA9IG5vY2tHZXRCaXRnb0NoYWxsZW5nZXMoe1xuICAgICAgICBiaXRnb05pdHJvSHNtOiBiaXRnb05pdHJvQ2hhbGxlbmdlLFxuICAgICAgICBiaXRnb0luc3RpdHV0aW9uYWxIc206IGJpdGdvSW5zdENoYWxsZW5nZSxcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgRUNEU0FVdGlscy5FY2RzYVV0aWxzLmdldFZlcmlmeUFuZFNpZ25CaXRHb0NoYWxsZW5nZXMoYml0Z28sICdlbnRfaWQnLCAnYnJvJykuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgJ0luY29ycmVjdCBwYXNzd29yZC4gUGxlYXNlIHRyeSBhZ2Fpbi4nXG4gICAgICApO1xuICAgICAgbm9ja0dldEJpdGdvQ2hhbGxlbmdlc0FwaS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ0ZhaWxzIGJpdGdvIGNoYWxsZW5nZSBwcm9vZnMgZm9yIGZhdWx0eSBuaXRybyBoMldydEgxIHByb29mJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgbm9ja0dldEJpdGdvQ2hhbGxlbmdlc0FwaSA9IG5vY2tHZXRCaXRnb0NoYWxsZW5nZXMoe1xuICAgICAgICBiaXRnb05pdHJvSHNtOiB7XG4gICAgICAgICAgLi4uYml0Z29OaXRyb0NoYWxsZW5nZSxcbiAgICAgICAgICBudGlsZGVQcm9vZjoge1xuICAgICAgICAgICAgLi4uYml0Z29OaXRyb0NoYWxsZW5nZS5udGlsZGVQcm9vZixcbiAgICAgICAgICAgIGgyV3J0SDE6IGJpdGdvTml0cm9DaGFsbGVuZ2UubnRpbGRlUHJvb2YuaDFXcnRIMixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0luc3RpdHV0aW9uYWxIc206IGJpdGdvSW5zdENoYWxsZW5nZSxcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgRUNEU0FVdGlscy5FY2RzYVV0aWxzLmdldFZlcmlmeUFuZFNpZ25CaXRHb0NoYWxsZW5nZXMoYml0Z28sICdlbnRfaWQnLCB1c2VyUGFzc3dvcmQpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgIFwiRmFpbGVkIHRvIHZlcmlmeSBCaXRHbydzIGNoYWxsZW5nZSBuZWVkZWQgdG8gZW5hYmxlIEVDRFNBIHNpZ25pbmcuIFBsZWFzZSBjb250YWN0IHN1cHBvcnRAYml0Z28uY29tXCJcbiAgICAgICk7XG4gICAgICBub2NrR2V0Qml0Z29DaGFsbGVuZ2VzQXBpLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnRmFpbHMgYml0Z28gY2hhbGxlbmdlIHByb29mcyBmb3IgZmF1bHR5IG5pdHJvIGgxV3J0SDIgcHJvb2YnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBub2NrR2V0Qml0Z29DaGFsbGVuZ2VzQXBpID0gbm9ja0dldEJpdGdvQ2hhbGxlbmdlcyh7XG4gICAgICAgIGJpdGdvTml0cm9Ic206IHtcbiAgICAgICAgICAuLi5iaXRnb05pdHJvQ2hhbGxlbmdlLFxuICAgICAgICAgIG50aWxkZVByb29mOiB7XG4gICAgICAgICAgICAuLi5iaXRnb05pdHJvQ2hhbGxlbmdlLm50aWxkZVByb29mLFxuICAgICAgICAgICAgaDFXcnRIMjogYml0Z29OaXRyb0NoYWxsZW5nZS5udGlsZGVQcm9vZi5oMldydEgxLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGJpdGdvSW5zdGl0dXRpb25hbEhzbTogYml0Z29JbnN0Q2hhbGxlbmdlLFxuICAgICAgfSk7XG4gICAgICBhd2FpdCBFQ0RTQVV0aWxzLkVjZHNhVXRpbHMuZ2V0VmVyaWZ5QW5kU2lnbkJpdEdvQ2hhbGxlbmdlcyhiaXRnbywgJ2VudF9pZCcsIHVzZXJQYXNzd29yZCkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgXCJGYWlsZWQgdG8gdmVyaWZ5IEJpdEdvJ3MgY2hhbGxlbmdlIG5lZWRlZCB0byBlbmFibGUgRUNEU0Egc2lnbmluZy4gUGxlYXNlIGNvbnRhY3Qgc3VwcG9ydEBiaXRnby5jb21cIlxuICAgICAgKTtcbiAgICAgIG5vY2tHZXRCaXRnb0NoYWxsZW5nZXNBcGkuaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdGYWlscyBiaXRnbyBjaGFsbGVuZ2UgcHJvb2ZzIGZvciBmYXVsdHkgaW5zdCBoMldydEgxIHByb29mJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgbm9ja0dldEJpdGdvQ2hhbGxlbmdlc0FwaSA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoYC9hcGkvdjIvdHNzL2VjZHNhL2NoYWxsZW5nZXNgKVxuICAgICAgICAudGltZXMoMSlcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGJpdGdvTml0cm9Ic206IGJpdGdvTml0cm9DaGFsbGVuZ2UsXG4gICAgICAgICAgYml0Z29JbnN0aXR1dGlvbmFsSHNtOiB7XG4gICAgICAgICAgICAuLi5iaXRnb0luc3RDaGFsbGVuZ2UsXG4gICAgICAgICAgICBudGlsZGVQcm9vZjoge1xuICAgICAgICAgICAgICAuLi5iaXRnb0luc3RDaGFsbGVuZ2UubnRpbGRlUHJvb2YsXG4gICAgICAgICAgICAgIGgyV3J0SDE6IGJpdGdvSW5zdENoYWxsZW5nZS5udGlsZGVQcm9vZi5oMVdydEgyLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIGF3YWl0IEVDRFNBVXRpbHMuRWNkc2FVdGlscy5nZXRWZXJpZnlBbmRTaWduQml0R29DaGFsbGVuZ2VzKGJpdGdvLCAnZW50X2lkJywgdXNlclBhc3N3b3JkKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICBcIkZhaWxlZCB0byB2ZXJpZnkgQml0R28ncyBjaGFsbGVuZ2UgbmVlZGVkIHRvIGVuYWJsZSBFQ0RTQSBzaWduaW5nLiBQbGVhc2UgY29udGFjdCBzdXBwb3J0QGJpdGdvLmNvbVwiXG4gICAgICApO1xuICAgICAgbm9ja0dldEJpdGdvQ2hhbGxlbmdlc0FwaS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ0ZhaWxzIGJpdGdvIGNoYWxsZW5nZSBwcm9vZnMgZm9yIGZhdWx0eSBpbnN0IGgxV3J0SDIgcHJvb2YnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBub2NrR2V0Qml0Z29DaGFsbGVuZ2VzQXBpID0gbm9jayhiZ1VybClcbiAgICAgICAgLmdldChgL2FwaS92Mi90c3MvZWNkc2EvY2hhbGxlbmdlc2ApXG4gICAgICAgIC50aW1lcygxKVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgYml0Z29OaXRyb0hzbTogYml0Z29OaXRyb0NoYWxsZW5nZSxcbiAgICAgICAgICBiaXRnb0luc3RpdHV0aW9uYWxIc206IHtcbiAgICAgICAgICAgIC4uLmJpdGdvSW5zdENoYWxsZW5nZSxcbiAgICAgICAgICAgIG50aWxkZVByb29mOiB7XG4gICAgICAgICAgICAgIC4uLmJpdGdvSW5zdENoYWxsZW5nZS5udGlsZGVQcm9vZixcbiAgICAgICAgICAgICAgaDFXcnRIMjogYml0Z29JbnN0Q2hhbGxlbmdlLm50aWxkZVByb29mLmgyV3J0SDEsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgYXdhaXQgRUNEU0FVdGlscy5FY2RzYVV0aWxzLmdldFZlcmlmeUFuZFNpZ25CaXRHb0NoYWxsZW5nZXMoYml0Z28sICdlbnRfaWQnLCB1c2VyUGFzc3dvcmQpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgIFwiRmFpbGVkIHRvIHZlcmlmeSBCaXRHbydzIGNoYWxsZW5nZSBuZWVkZWQgdG8gZW5hYmxlIEVDRFNBIHNpZ25pbmcuIFBsZWFzZSBjb250YWN0IHN1cHBvcnRAYml0Z28uY29tXCJcbiAgICAgICk7XG4gICAgICBub2NrR2V0Qml0Z29DaGFsbGVuZ2VzQXBpLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdzdXBwb3J0ZWRUeFJlcXVlc3RWZXJzaW9ucycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgncmV0dXJucyBvbmx5IGZ1bGwgZm9yIGhvdCB3YWxsZXRzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaG90V2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZUNvaW4sIHsgdHlwZTogJ2hvdCcsIG11bHRpc2lnVHlwZTogJ3RzcycgfSk7XG4gICAgICBjb25zdCBob3RXYWxsZXRUc3NVdGlscyA9IG5ldyBFQ0RTQVV0aWxzLkVjZHNhVXRpbHMoYml0Z28sIGJhc2VDb2luLCBob3RXYWxsZXQpO1xuICAgICAgaG90V2FsbGV0VHNzVXRpbHMuc3VwcG9ydGVkVHhSZXF1ZXN0VmVyc2lvbnMoKS5zaG91bGQuZGVlcEVxdWFsKFsnZnVsbCddKTtcbiAgICB9KTtcbiAgICBpdCgncmV0dXJucyBvbmx5IGZ1bGwgZm9yIGNvbGQgd2FsbGV0cycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvbGRXYWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlQ29pbiwge1xuICAgICAgICB0eXBlOiAnY29sZCcsXG4gICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGNvbGRXYWxsZXRUc3NVdGlscyA9IG5ldyBFQ0RTQVV0aWxzLkVjZHNhVXRpbHMoYml0Z28sIGJhc2VDb2luLCBjb2xkV2FsbGV0KTtcblxuICAgICAgY29sZFdhbGxldFRzc1V0aWxzLnN1cHBvcnRlZFR4UmVxdWVzdFZlcnNpb25zKCkuc2hvdWxkLmRlZXBFcXVhbChbJ2Z1bGwnXSk7XG4gICAgfSk7XG4gICAgaXQoJ3JldHVybnMgb25seSBmdWxsIGZvciBjdXN0b2RpYWwgd2FsbGV0cycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGN1c3RvZGlhbFdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2VDb2luLCB7IHR5cGU6ICdjdXN0b2RpYWwnLCBtdWx0aXNpZ1R5cGU6ICd0c3MnIH0pO1xuICAgICAgY29uc3QgY3VzdG9kaWFsV2FsbGV0VHNzVXRpbHMgPSBuZXcgRUNEU0FVdGlscy5FY2RzYVV0aWxzKGJpdGdvLCBiYXNlQ29pbiwgY3VzdG9kaWFsV2FsbGV0KTtcbiAgICAgIGN1c3RvZGlhbFdhbGxldFRzc1V0aWxzLnN1cHBvcnRlZFR4UmVxdWVzdFZlcnNpb25zKCkuc2hvdWxkLmRlZXBFcXVhbChbJ2Z1bGwnXSk7XG4gICAgfSk7XG4gICAgaXQoJ3JldHVybnMgZW1wdHkgZm9yIHRyYWRpbmcgd2FsbGV0cycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRyYWRpbmdXYWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlQ29pbiwgeyB0eXBlOiAndHJhZGluZycsIG11bHRpc2lnVHlwZTogJ3RzcycgfSk7XG4gICAgICBjb25zdCB0cmFkaW5nV2FsbGV0VHNzVXRpbHMgPSBuZXcgRUNEU0FVdGlscy5FY2RzYVV0aWxzKGJpdGdvLCBiYXNlQ29pbiwgdHJhZGluZ1dhbGxldCk7XG4gICAgICB0cmFkaW5nV2FsbGV0VHNzVXRpbHMuc3VwcG9ydGVkVHhSZXF1ZXN0VmVyc2lvbnMoKS5zaG91bGQuZGVlcEVxdWFsKFtdKTtcbiAgICB9KTtcbiAgICBpdCgncmV0dXJucyBlbXB0eSBmb3Igbm9uLXRzcyB3YWxsZXRzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgbm9uVHNzV2FsbGV0RGF0YSA9IHsgY29pbjogJ3RidGMnLCBtdWx0aXNpZ1R5cGU6ICdvbmNoYWluJyB9O1xuICAgICAgY29uc3QgYnRjQ29pbiA9IGJpdGdvLmNvaW4oJ3RidGMnKTtcbiAgICAgIGNvbnN0IG5vblRzc1dhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJ0Y0NvaW4sIG5vblRzc1dhbGxldERhdGEpO1xuICAgICAgY29uc3Qgbm9uVHNzV2FsbGV0VHNzVXRpbHMgPSBuZXcgVHNzVXRpbHMoYml0Z28sIGJ0Y0NvaW4sIG5vblRzc1dhbGxldCk7XG4gICAgICBub25Uc3NXYWxsZXRUc3NVdGlscy5zdXBwb3J0ZWRUeFJlcXVlc3RWZXJzaW9ucygpLnNob3VsZC5kZWVwRXF1YWwoW10pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaW5pdGlhdGVDaGFsbGVuZ2VzRm9yRW50ZXJwcmlzZScsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBjb25zdCBhZG1pbkVjZGhLZXkgPSBiaXRnby5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9ICdtLzAvMCc7XG4gICAgY29uc3QgYml0Z29JbnN0Q2hhbGxlbmdlID0gbW9ja0NoYWxsZW5nZUE7XG4gICAgY29uc3QgYml0Z29OaXRyb0NoYWxsZW5nZSA9IG1vY2tDaGFsbGVuZ2VCO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRFbnRDaGFsbGVuZ2UgPSBtb2NrQ2hhbGxlbmdlQztcbiAgICBjb25zdCB1c2VyUGFzc3dvcmQgPSAncGFzc3dvcmQxMjMnO1xuICAgIGNvbnN0IGVuY3J5cHRlZFhwcnYgPSBiaXRnby5lbmNyeXB0KHtcbiAgICAgIHBhc3N3b3JkOiB1c2VyUGFzc3dvcmQsXG4gICAgICBpbnB1dDogYWRtaW5FY2RoS2V5LnhwcnYsXG4gICAgfSk7XG5cbiAgICBiZWZvcmVFYWNoKGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRTaWduaW5nS2V5Rm9yVXNlcicpLnJlc29sdmVzKHtcbiAgICAgICAgdXNlcklkOiAnaWQnLFxuICAgICAgICB1c2VyRW1haWw6ICd1c2VyQGJpdGdvLmNvbScsXG4gICAgICAgIGRlcml2ZWRQdWJrZXk6IGJpcDMyLmZyb21CYXNlNTgoYWRtaW5FY2RoS2V5LnhwdWIpLmRlcml2ZVBhdGgoZGVyaXZhdGlvblBhdGgpLnB1YmxpY0tleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgIGRlcml2YXRpb25QYXRoOiBkZXJpdmF0aW9uUGF0aCxcbiAgICAgICAgZWNkaEtleWNoYWluOiAnbXkga2V5Y2hhaW4nLFxuICAgICAgfSk7XG5cbiAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7XG4gICAgICAgIGVuY3J5cHRlZFhwcnY6IGVuY3J5cHRlZFhwcnYsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBzaW5vbi5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHVwbG9hZCBjaGFsbGVuZ2Ugd2l0aG91dCBnZW5lcmF0aW5nIGlmIHBhc3NlZCBpbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHN0dWJVcGxvYWRDaGFsbGVuZ2UgPSBzaW5vbi5zdHViKEVDRFNBVXRpbHMuRWNkc2FVdGlscywgJ3VwbG9hZENoYWxsZW5nZXNUb0VudGVycHJpc2UnKTtcbiAgICAgIGNvbnN0IGRlc2VyaWFsaXplZEVudENoYWxsZW5nZSA9IEVjZHNhVHlwZXMuZGVzZXJpYWxpemVOdGlsZGVXaXRoUHJvb2ZzKHNlcmlhbGl6ZWRFbnRDaGFsbGVuZ2UpO1xuXG4gICAgICBjb25zdCBzaWduZWRFbnRDaGFsbGVuZ2UgPSBFQ0RTQVV0aWxzLkVjZHNhVXRpbHMuc2lnbkNoYWxsZW5nZShcbiAgICAgICAgc2VyaWFsaXplZEVudENoYWxsZW5nZSxcbiAgICAgICAgYWRtaW5FY2RoS2V5LnhwcnYsXG4gICAgICAgIGRlcml2YXRpb25QYXRoXG4gICAgICApO1xuICAgICAgY29uc3Qgc2lnbmVkSW5zdENoYWxsZW5nZSA9IEVDRFNBVXRpbHMuRWNkc2FVdGlscy5zaWduQ2hhbGxlbmdlKFxuICAgICAgICBiaXRnb0luc3RDaGFsbGVuZ2UsXG4gICAgICAgIGFkbWluRWNkaEtleS54cHJ2LFxuICAgICAgICBkZXJpdmF0aW9uUGF0aFxuICAgICAgKTtcbiAgICAgIGNvbnN0IHNpZ25lZE5pdHJvQ2hhbGxlbmdlID0gRUNEU0FVdGlscy5FY2RzYVV0aWxzLnNpZ25DaGFsbGVuZ2UoXG4gICAgICAgIGJpdGdvTml0cm9DaGFsbGVuZ2UsXG4gICAgICAgIGFkbWluRWNkaEtleS54cHJ2LFxuICAgICAgICBkZXJpdmF0aW9uUGF0aFxuICAgICAgKTtcblxuICAgICAgYXdhaXQgRUNEU0FVdGlscy5FY2RzYVV0aWxzLmluaXRpYXRlQ2hhbGxlbmdlc0ZvckVudGVycHJpc2UoXG4gICAgICAgIGJpdGdvLFxuICAgICAgICAnZW50X2lkJyxcbiAgICAgICAgdXNlclBhc3N3b3JkLFxuICAgICAgICBzaWduZWRJbnN0Q2hhbGxlbmdlLFxuICAgICAgICBzaWduZWROaXRyb0NoYWxsZW5nZSxcbiAgICAgICAgb3BlblNTTEJ5dGVzLFxuICAgICAgICBkZXNlcmlhbGl6ZWRFbnRDaGFsbGVuZ2VcbiAgICAgICkuc2hvdWxkLm5vdC5iZS5yZWplY3RlZCgpO1xuICAgICAgc3R1YlVwbG9hZENoYWxsZW5nZS5jYWxsZWRXaXRoKFxuICAgICAgICBiaXRnbyxcbiAgICAgICAgJ2VudF9pZCcsXG4gICAgICAgIHNlcmlhbGl6ZWRFbnRDaGFsbGVuZ2UsXG4gICAgICAgIHNpZ25lZEVudENoYWxsZW5nZS50b1N0cmluZygnaGV4JyksXG4gICAgICAgIHNpZ25lZEluc3RDaGFsbGVuZ2UudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICBzaWduZWROaXRyb0NoYWxsZW5nZS50b1N0cmluZygnaGV4JylcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGEgY2hhbGxlbmdlIGFuZCBpZiBvbmUgaXMgbm90IHByb3ZpZGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc3R1YlVwbG9hZENoYWxsZW5nZSA9IHNpbm9uLnN0dWIoRUNEU0FVdGlscy5FY2RzYVV0aWxzLCAndXBsb2FkQ2hhbGxlbmdlc1RvRW50ZXJwcmlzZScpO1xuICAgICAgY29uc3QgZGVzZXJpYWxpemVkRW50Q2hhbGxlbmdlID0gRWNkc2FUeXBlcy5kZXNlcmlhbGl6ZU50aWxkZVdpdGhQcm9vZnMoc2VyaWFsaXplZEVudENoYWxsZW5nZSk7XG4gICAgICBzaW5vbi5zdHViKEVjZHNhUmFuZ2VQcm9vZiwgJ2dlbmVyYXRlTnRpbGRlJykucmVzb2x2ZXMoZGVzZXJpYWxpemVkRW50Q2hhbGxlbmdlKTtcblxuICAgICAgY29uc3Qgc2lnbmVkRW50Q2hhbGxlbmdlID0gRUNEU0FVdGlscy5FY2RzYVV0aWxzLnNpZ25DaGFsbGVuZ2UoXG4gICAgICAgIHNlcmlhbGl6ZWRFbnRDaGFsbGVuZ2UsXG4gICAgICAgIGFkbWluRWNkaEtleS54cHJ2LFxuICAgICAgICBkZXJpdmF0aW9uUGF0aFxuICAgICAgKTtcbiAgICAgIGNvbnN0IHNpZ25lZEluc3RDaGFsbGVuZ2UgPSBFQ0RTQVV0aWxzLkVjZHNhVXRpbHMuc2lnbkNoYWxsZW5nZShcbiAgICAgICAgYml0Z29JbnN0Q2hhbGxlbmdlLFxuICAgICAgICBhZG1pbkVjZGhLZXkueHBydixcbiAgICAgICAgZGVyaXZhdGlvblBhdGhcbiAgICAgICk7XG4gICAgICBjb25zdCBzaWduZWROaXRyb0NoYWxsZW5nZSA9IEVDRFNBVXRpbHMuRWNkc2FVdGlscy5zaWduQ2hhbGxlbmdlKFxuICAgICAgICBiaXRnb05pdHJvQ2hhbGxlbmdlLFxuICAgICAgICBhZG1pbkVjZGhLZXkueHBydixcbiAgICAgICAgZGVyaXZhdGlvblBhdGhcbiAgICAgICk7XG5cbiAgICAgIGF3YWl0IEVDRFNBVXRpbHMuRWNkc2FVdGlscy5pbml0aWF0ZUNoYWxsZW5nZXNGb3JFbnRlcnByaXNlKFxuICAgICAgICBiaXRnbyxcbiAgICAgICAgJ2VudF9pZCcsXG4gICAgICAgIHVzZXJQYXNzd29yZCxcbiAgICAgICAgc2lnbmVkSW5zdENoYWxsZW5nZSxcbiAgICAgICAgc2lnbmVkTml0cm9DaGFsbGVuZ2UsXG4gICAgICAgIG9wZW5TU0xCeXRlc1xuICAgICAgKS5zaG91bGQubm90LmJlLnJlamVjdGVkKCk7XG4gICAgICBzdHViVXBsb2FkQ2hhbGxlbmdlLmNhbGxlZFdpdGgoXG4gICAgICAgIGJpdGdvLFxuICAgICAgICAnZW50X2lkJyxcbiAgICAgICAgc2VyaWFsaXplZEVudENoYWxsZW5nZSxcbiAgICAgICAgc2lnbmVkRW50Q2hhbGxlbmdlLnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgc2lnbmVkSW5zdENoYWxsZW5nZS50b1N0cmluZygnaGV4JyksXG4gICAgICAgIHNpZ25lZE5pdHJvQ2hhbGxlbmdlLnRvU3RyaW5nKCdoZXgnKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgaXQoJ2dldE1lc3NhZ2VUb1NpZ25Gcm9tQ2hhbGxlbmdlIGNvbmNhdGVuYXRlcyB0aGUgY2hhbGxlbmdlIHZhbHVlcyBvbmx5JywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGNoYWxsZW5nZSA9IG1vY2tDaGFsbGVuZ2VBO1xuICAgIGNvbnN0IGV4cGVjdGVkTWVzc2FnZVRvU2lnbiA9IGNoYWxsZW5nZS5udGlsZGUuY29uY2F0KGNoYWxsZW5nZS5oMSkuY29uY2F0KGNoYWxsZW5nZS5oMik7XG4gICAgY29uc3QgbWVzc2FnZSA9IEVDRFNBVXRpbHMuRWNkc2FVdGlscy5nZXRNZXNzYWdlVG9TaWduRnJvbUNoYWxsZW5nZShjaGFsbGVuZ2UpO1xuICAgIG1lc3NhZ2Uuc2hvdWxkLmVxdWFsKGV4cGVjdGVkTWVzc2FnZVRvU2lnbik7XG4gIH0pO1xuICBkZXNjcmliZSgndmFsaWRhdGVDb21tb25LZXljaGFpblB1YmxpY0tleScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgndmFsaWRhdGVDb21tb25LZXljaGFpblB1YmxpY0tleSByZXR1cm5zIGNvcnJlY3QgcHVibGljIGtleScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvbW1vbktleWNoYWluID1cbiAgICAgICAgJzAzZjQwYzcwNTQ1YjUxOWJiN2JiYzcxOTVmZDRiN2Q1YmJmYzg3M2JmZDM4YjE4NTk2ZTRiNDdhMDViNmE4OGQ1NTJlMmU4MzE5Y2IzMWUyNzliOTlkYmU1NDExNWE5ODNkMzVlODY2NzlhZjk2ZDgxYjc0NzhkMWRmMzY4Zjc2YTgnO1xuICAgICAgY29uc3QgZXhwZWN0ZWRQdWJLZXlSZXN1bHQgPSBgZjQwYzcwNTQ1YjUxOWJiN2JiYzcxOTVmZDRiN2Q1YmJmYzg3M2JmZDM4YjE4NTk2ZTRiNDdhMDViNmE4OGQ1NTZhMTBkNmFiODA1NWRjMGIzYTlhZjlkYzRlNDJmNGY5NzczYzU5MGFmY2MyOThkMDE3YzFiMWNlMjlhODgwNDFgO1xuICAgICAgY29uc3QgYWN0dWFsUHViS2V5ID0gRUNEU0FVdGlscy5FY2RzYVV0aWxzLnZhbGlkYXRlQ29tbW9uS2V5Y2hhaW5QdWJsaWNLZXkoY29tbW9uS2V5Y2hhaW4pO1xuICAgICAgYWN0dWFsUHViS2V5LnNob3VsZC5lcXVhbChleHBlY3RlZFB1YktleVJlc3VsdCk7XG4gICAgfSk7XG4gICAgaXQoJ3ZhbGlkYXRlQ29tbW9uS2V5Y2hhaW5QdWJsaWNLZXkgdGhyb3dzIGNvcnJlY3RseSB3aXRoIGludmFsaWQgbGVuZ3RoJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29tbW9uS2V5Y2hhaW4gPSAnMDNmNDBjNzA1NDgnO1xuICAgICAgc2hvdWxkKCgpID0+IEVDRFNBVXRpbHMuRWNkc2FVdGlscy52YWxpZGF0ZUNvbW1vbktleWNoYWluUHVibGljS2V5KGNvbW1vbktleWNoYWluKSkudGhyb3dFcnJvcihcbiAgICAgICAgJ0ludmFsaWQgY29tbW9uS2V5Y2hhaW4gbGVuZ3RoLCBleHBlY3RlZCAxMzAsIGdvdCAxMSdcbiAgICAgICk7XG4gICAgfSk7XG4gICAgaXQoJ3ZhbGlkYXRlQ29tbW9uS2V5Y2hhaW5QdWJsaWNLZXkgdGhyb3dzIGNvcnJlY3RseSB3aXRoIGludmFsaWQgY29tbW9uS2V5Y2hhaW4nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb21tb25LZXljaGFpbldpdGhJbnZhbGlkQ2hhcmFjdGVycyA9XG4gICAgICAgICchQCMkXjBjNzA1NDViNTE5YmI3YmJjNzE5NWZkNGI3ZDViZmM4NzNiZmQzOGIxODU5NmU0YjQ3YTA1YjZhODhkNTUyZTJlODMxOWNiMzFlMjc5Yjk5ZGJlNTQxMTVhOTgzZDM1ZTg2Njc5YWY5NmQ4MWI3NDc4ZDFkZjM2OGY3NmE4JzsgLy8gMTI5IGNoYXJzXG4gICAgICBzaG91bGQoKCkgPT5cbiAgICAgICAgRUNEU0FVdGlscy5FY2RzYVV0aWxzLnZhbGlkYXRlQ29tbW9uS2V5Y2hhaW5QdWJsaWNLZXkoY29tbW9uS2V5Y2hhaW5XaXRoSW52YWxpZENoYXJhY3RlcnMpXG4gICAgICApLnRocm93RXJyb3IoL15JbnZhbGlkIGNvbW1vbktleWNoYWluLCBlcnJvcjovKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gI3JlZ2lvbiBOb2NrIGhlbHBlcnNcbiAgYXN5bmMgZnVuY3Rpb24gY3JlYXRlSW5jb21wbGV0ZUJpdGdvSGVsZEJhY2t1cEtleVNoYXJlKFxuICAgIHVzZXJHcGdLZXk6IG9wZW5wZ3AuU2VyaWFsaXplZEtleVBhaXI8c3RyaW5nPixcbiAgICBiYWNrdXBLZXlTaGFyZTogS2V5U2hhcmUsXG4gICAgYml0Z29HcGdLZXk6IG9wZW5wZ3AuU2VyaWFsaXplZEtleVBhaXI8c3RyaW5nPlxuICApOiBQcm9taXNlPEJpdGdvSGVsZEJhY2t1cEtleVNoYXJlPiB7XG4gICAgY29uc3QgblNoYXJlUHJvbWlzZXMgPSBbXG4gICAgICBlbmNyeXB0TlNoYXJlKGJhY2t1cEtleVNoYXJlLCAxLCB1c2VyR3BnS2V5LnB1YmxpY0tleSwgdXNlckdwZ0tleSwgZmFsc2UpLFxuICAgICAgZW5jcnlwdE5TaGFyZShiYWNrdXBLZXlTaGFyZSwgMywgYml0Z29HcGdLZXkucHVibGljS2V5LCB1c2VyR3BnS2V5LCBmYWxzZSksXG4gICAgXTtcblxuICAgIGNvbnN0IGJhY2t1cFRvVXNlclB1YmxpY1NoYXJlID0gQnVmZmVyLmNvbmNhdChbXG4gICAgICBCdWZmZXIuZnJvbShiYWNrdXBLZXlTaGFyZS5uU2hhcmVzWzFdLnksICdoZXgnKSxcbiAgICAgIEJ1ZmZlci5mcm9tKGJhY2t1cEtleVNoYXJlLm5TaGFyZXNbMV0uY2hhaW5jb2RlLCAnaGV4JyksXG4gICAgXSkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgY29uc3QgYmFja3VwVG9CaXRnb1B1YmxpY1NoYXJlID0gQnVmZmVyLmNvbmNhdChbXG4gICAgICBCdWZmZXIuZnJvbShiYWNrdXBLZXlTaGFyZS5uU2hhcmVzWzNdLnksICdoZXgnKSxcbiAgICAgIEJ1ZmZlci5mcm9tKGJhY2t1cEtleVNoYXJlLm5TaGFyZXNbM10uY2hhaW5jb2RlLCAnaGV4JyksXG4gICAgXSkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiAnNDcxMScsXG4gICAgICBrZXlTaGFyZXM6IFtcbiAgICAgICAge1xuICAgICAgICAgIGZyb206ICdiYWNrdXAnLFxuICAgICAgICAgIHRvOiAndXNlcicsXG4gICAgICAgICAgcHVibGljU2hhcmU6IGJhY2t1cFRvVXNlclB1YmxpY1NoYXJlLFxuICAgICAgICAgIHByaXZhdGVTaGFyZTogKGF3YWl0IG5TaGFyZVByb21pc2VzWzBdKS5lbmNyeXB0ZWRQcml2YXRlU2hhcmUsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBmcm9tOiAnYmFja3VwJyxcbiAgICAgICAgICB0bzogJ2JpdGdvJyxcbiAgICAgICAgICBwdWJsaWNTaGFyZTogYmFja3VwVG9CaXRnb1B1YmxpY1NoYXJlLFxuICAgICAgICAgIHByaXZhdGVTaGFyZTogKGF3YWl0IG5TaGFyZVByb21pc2VzWzFdKS5lbmNyeXB0ZWRQcml2YXRlU2hhcmUsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBub2NrR2V0Qml0Z29QdWJsaWNLZXlCYXNlZE9uRmVhdHVyZUZsYWdzKFxuICAgIGNvaW46IHN0cmluZyxcbiAgICBlbnRlcnByaXNlSWQ6IHN0cmluZyxcbiAgICBiaXRnb0dwZ0tleVBhaXI6IG9wZW5wZ3AuU2VyaWFsaXplZEtleVBhaXI8c3RyaW5nPlxuICApOiBQcm9taXNlPEJpdGdvR1BHUHVibGljS2V5PiB7XG4gICAgY29uc3QgYml0Z29HUEdQdWJsaWNLZXlSZXNwb25zZTogQml0Z29HUEdQdWJsaWNLZXkgPSB7XG4gICAgICBuYW1lOiAnaXJyZWxldmFudCcsXG4gICAgICBwdWJsaWNLZXk6IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICBlbnRlcnByaXNlSWQsXG4gICAgfTtcbiAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvJHtjb2lufS90c3MvcHVia2V5YCkucXVlcnkoeyBlbnRlcnByaXNlSWQgfSkucmVwbHkoMjAwLCBiaXRnb0dQR1B1YmxpY0tleVJlc3BvbnNlKTtcblxuICAgIHJldHVybiBiaXRnb0dQR1B1YmxpY0tleVJlc3BvbnNlO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gbm9ja0NyZWF0ZUJpdGdvSGVsZEJhY2t1cEtleVNoYXJlKFxuICAgIGNvaW46IHN0cmluZyxcbiAgICBlbnRlcnByaXNlSWQ6IHN0cmluZyxcbiAgICB1c2VyR3BnS2V5OiBvcGVucGdwLlNlcmlhbGl6ZWRLZXlQYWlyPHN0cmluZz4sXG4gICAgYmFja3VwS2V5U2hhcmU6IEtleVNoYXJlLFxuICAgIGJpdGdvR3BnS2V5OiBvcGVucGdwLlNlcmlhbGl6ZWRLZXlQYWlyPHN0cmluZz5cbiAgKTogUHJvbWlzZTxCaXRnb0hlbGRCYWNrdXBLZXlTaGFyZT4ge1xuICAgIGNvbnN0IGtleVNoYXJlID0gYXdhaXQgY3JlYXRlSW5jb21wbGV0ZUJpdGdvSGVsZEJhY2t1cEtleVNoYXJlKHVzZXJHcGdLZXksIGJhY2t1cEtleVNoYXJlLCBiaXRnb0dwZ0tleSk7XG5cbiAgICBub2NrKGJnVXJsKVxuICAgICAgLnBvc3QoXG4gICAgICAgIGAvYXBpL3YyLyR7Y29pbn0va3JzL2JhY2t1cGtleXNgLFxuICAgICAgICBfLm1hdGNoZXMoeyBlbnRlcnByaXNlOiBlbnRlcnByaXNlSWQsIHVzZXJHUEdQdWJsaWNLZXk6IHVzZXJHcGdLZXkucHVibGljS2V5IH0pXG4gICAgICApXG4gICAgICAucmVwbHkoMjAxLCBrZXlTaGFyZSk7XG5cbiAgICByZXR1cm4ga2V5U2hhcmU7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBub2NrRmluYWxpemVCaXRnb0hlbGRCYWNrdXBLZXlTaGFyZShcbiAgICBjb2luOiBzdHJpbmcsXG4gICAgb3JpZ2luYWxLZXlTaGFyZTogQml0Z29IZWxkQmFja3VwS2V5U2hhcmUsXG4gICAgY29tbW9uS2V5Y2hhaW46IHN0cmluZyxcbiAgICB1c2VyS2V5U2hhcmU6IEtleVNoYXJlLFxuICAgIHVzZXJMb2NhbEJhY2t1cEdwZ0tleTogb3BlbnBncC5TZXJpYWxpemVkS2V5UGFpcjxzdHJpbmc+LFxuICAgIGJpdGdvS2V5Y2hhaW46IEtleWNoYWluXG4gICk6IFByb21pc2U8Qml0Z29IZWxkQmFja3VwS2V5U2hhcmU+IHtcbiAgICBjb25zdCBlbmNyeXB0ZWRVc2VyVG9CYWNrdXBLZXlTaGFyZSA9IGF3YWl0IGVuY3J5cHROU2hhcmUoXG4gICAgICB1c2VyS2V5U2hhcmUsXG4gICAgICAyLFxuICAgICAgdXNlckxvY2FsQmFja3VwR3BnS2V5LnB1YmxpY0tleSxcbiAgICAgIHVzZXJHcGdLZXksXG4gICAgICBmYWxzZVxuICAgICk7XG5cbiAgICBhc3NlcnQoYml0Z29LZXljaGFpbi5rZXlTaGFyZXMpO1xuICAgIGNvbnN0IGJpdGdvVG9CYWNrdXBLZXlTaGFyZSA9IGJpdGdvS2V5Y2hhaW4ua2V5U2hhcmVzLmZpbmQoXG4gICAgICAoa2V5U2hhcmUpID0+IGtleVNoYXJlLmZyb20gPT09ICdiaXRnbycgJiYga2V5U2hhcmUudG8gPT09ICdiYWNrdXAnXG4gICAgKTtcbiAgICBhc3NlcnQoYml0Z29Ub0JhY2t1cEtleVNoYXJlKTtcblxuICAgIGNvbnN0IHVzZXJQdWJsaWNTaGFyZSA9IEJ1ZmZlci5jb25jYXQoW1xuICAgICAgQnVmZmVyLmZyb20odXNlcktleVNoYXJlLm5TaGFyZXNbMl0ueSwgJ2hleCcpLFxuICAgICAgQnVmZmVyLmZyb20odXNlcktleVNoYXJlLm5TaGFyZXNbMl0uY2hhaW5jb2RlLCAnaGV4JyksXG4gICAgXSkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgY29uc3QgZXhwZWN0ZWRLZXlTaGFyZXMgPSBbXG4gICAgICB7XG4gICAgICAgIGZyb206ICd1c2VyJyxcbiAgICAgICAgdG86ICdiYWNrdXAnLFxuICAgICAgICBwdWJsaWNTaGFyZTogdXNlclB1YmxpY1NoYXJlLFxuICAgICAgICAvLyBPbWl0dGluZyB0aGUgcHJpdmF0ZSBzaGFyZSwgdGhlIGFjdHVhbCBlbmNyeXB0aW9uIGhhcHBlbnMgaW5zaWRlIHRoZSBmdW5jdGlvbiB3aGVyZSB3ZSBtYWtlIHRoZSBtYXRjaGluZyBjYWxsXG4gICAgICAgIC8vIHRvIHRoaXMgbm9jay4gV2UgY2Fubm90IHJlY3JlYXRlIHRoZSBzYW1lIGVuY3J5cHRlZCB2YWx1ZSBoZXJlIGJlY2F1c2UgZ3BnIGVuY3J5cHRpb24gaXMgbm90IGRldGVybWluaXN0aWNcbiAgICAgIH0sXG4gICAgICBiaXRnb1RvQmFja3VwS2V5U2hhcmUsXG4gICAgXTtcblxuICAgIGNvbnN0IHVwZGF0ZWRLZXlTaGFyZTogQml0Z29IZWxkQmFja3VwS2V5U2hhcmUgPSB7XG4gICAgICBpZDogb3JpZ2luYWxLZXlTaGFyZS5pZCxcbiAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAga2V5U2hhcmVzOiBbXG4gICAgICAgIC4uLm9yaWdpbmFsS2V5U2hhcmUua2V5U2hhcmVzLFxuICAgICAgICB7XG4gICAgICAgICAgZnJvbTogJ3VzZXInLFxuICAgICAgICAgIHRvOiAnYmFja3VwJyxcbiAgICAgICAgICBwdWJsaWNTaGFyZTogdXNlclB1YmxpY1NoYXJlLFxuICAgICAgICAgIHByaXZhdGVTaGFyZTogZW5jcnlwdGVkVXNlclRvQmFja3VwS2V5U2hhcmUuZW5jcnlwdGVkUHJpdmF0ZVNoYXJlLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb1RvQmFja3VwS2V5U2hhcmUsXG4gICAgICBdLFxuICAgIH07XG5cbiAgICBub2NrKGJnVXJsKVxuICAgICAgLnB1dChcbiAgICAgICAgYC9hcGkvdjIvJHtjb2lufS9rcnMvYmFja3Vwa2V5cy8ke29yaWdpbmFsS2V5U2hhcmUuaWR9YCxcbiAgICAgICAgXy5tYXRjaGVzKHsgY29tbW9uS2V5Y2hhaW4sIGtleVNoYXJlczogZXhwZWN0ZWRLZXlTaGFyZXMgfSlcbiAgICAgIClcbiAgICAgIC5yZXBseSgyMDAsIHVwZGF0ZWRLZXlTaGFyZSk7XG5cbiAgICByZXR1cm4gdXBkYXRlZEtleVNoYXJlO1xuICB9XG5cbiAgLyoqXG4gICAqIEhlbHBlciBmdW5jdGlvbiB0byBnZW5lcmF0ZSBhIGJpdGdvIGtleWNoYWluIGdpdmVuIHRoZSBmdWxsIHNldCBvZiBrZXlzaGFyZXMgYW5kIEdQRyBrZXlzLlxuICAgKiBBbHNvIG1vY2tzIHRoZSB3YWxsZXQgc2lnbmF0dXJlcyBhZGRlZCBieSB0aGUgSFNNLlxuICAgKiBAcGFyYW0gcGFyYW1zXG4gICAqL1xuICBhc3luYyBmdW5jdGlvbiBnZW5lcmF0ZUJpdGdvS2V5Y2hhaW4ocGFyYW1zOiB7XG4gICAgY29pbjogc3RyaW5nO1xuICAgIHVzZXJLZXlTaGFyZTogS2V5U2hhcmU7XG4gICAgYmFja3VwS2V5U2hhcmU6IEtleVNoYXJlO1xuICAgIGJpdGdvS2V5U2hhcmU6IEtleVNoYXJlO1xuICAgIHVzZXJHcGdLZXk6IG9wZW5wZ3AuU2VyaWFsaXplZEtleVBhaXI8c3RyaW5nPjtcbiAgICB1c2VyTG9jYWxCYWNrdXBHcGdLZXk6IG9wZW5wZ3AuU2VyaWFsaXplZEtleVBhaXI8c3RyaW5nPjtcbiAgICBiaXRnb0dwZ0tleTogb3BlbnBncC5TZXJpYWxpemVkS2V5UGFpcjxzdHJpbmc+O1xuICB9KTogUHJvbWlzZTxLZXljaGFpbj4ge1xuICAgIGNvbnN0IGJpdGdvQ29tYmluZWQgPSBNUEMua2V5Q29tYmluZShwYXJhbXMuYml0Z29LZXlTaGFyZS5wU2hhcmUsIFtcbiAgICAgIHBhcmFtcy51c2VyS2V5U2hhcmUublNoYXJlc1szXSxcbiAgICAgIHBhcmFtcy5iYWNrdXBLZXlTaGFyZS5uU2hhcmVzWzNdLFxuICAgIF0pO1xuICAgIGNvbnN0IHVzZXJHcGdLZXlBY3R1YWwgPSBhd2FpdCBvcGVucGdwLnJlYWRLZXkoeyBhcm1vcmVkS2V5OiBwYXJhbXMudXNlckdwZ0tleS5wdWJsaWNLZXkgfSk7XG4gICAgY29uc3QgYmFja3VwR3BnS2V5QWN0dWFsID0gYXdhaXQgb3BlbnBncC5yZWFkS2V5KHsgYXJtb3JlZEtleTogcGFyYW1zLnVzZXJMb2NhbEJhY2t1cEdwZ0tleS5wdWJsaWNLZXkgfSk7XG5cbiAgICBjb25zdCBuU2hhcmVQcm9taXNlcyA9IFtcbiAgICAgIGVuY3J5cHROU2hhcmUocGFyYW1zLmJpdGdvS2V5U2hhcmUsIDEsIHBhcmFtcy51c2VyR3BnS2V5LnB1YmxpY0tleSwgcGFyYW1zLnVzZXJHcGdLZXksIGZhbHNlKSxcbiAgICAgIGVuY3J5cHROU2hhcmUoXG4gICAgICAgIHBhcmFtcy5iaXRnb0tleVNoYXJlLFxuICAgICAgICAyLFxuICAgICAgICBwYXJhbXMudXNlckxvY2FsQmFja3VwR3BnS2V5LnB1YmxpY0tleSxcbiAgICAgICAgcGFyYW1zLnVzZXJMb2NhbEJhY2t1cEdwZ0tleSxcbiAgICAgICAgZmFsc2VcbiAgICAgICksXG4gICAgXTtcbiAgICBjb25zdCBbdXNlclRvQml0Z29TaGFyZSwgYmFja3VwVG9CaXRnb1NoYXJlXSA9IGF3YWl0IFByb21pc2UuYWxsKG5TaGFyZVByb21pc2VzKTtcbiAgICBjb25zdCBiaXRnb0tleWNoYWluOiBLZXljaGFpbiA9IHtcbiAgICAgIGlkOiAnMycsXG4gICAgICBwdWI6ICcnLFxuICAgICAgY29tbW9uS2V5Y2hhaW46IGJpdGdvQ29tYmluZWQueFNoYXJlLnkgKyBiaXRnb0NvbWJpbmVkLnhTaGFyZS5jaGFpbmNvZGUsXG4gICAgICBrZXlTaGFyZXM6IFtcbiAgICAgICAge1xuICAgICAgICAgIGZyb206ICdiaXRnbycsXG4gICAgICAgICAgdG86ICd1c2VyJyxcbiAgICAgICAgICBwdWJsaWNTaGFyZTogdXNlclRvQml0Z29TaGFyZS5wdWJsaWNTaGFyZSxcbiAgICAgICAgICBwcml2YXRlU2hhcmU6IHVzZXJUb0JpdGdvU2hhcmUuZW5jcnlwdGVkUHJpdmF0ZVNoYXJlLFxuICAgICAgICAgIG46IHVzZXJUb0JpdGdvU2hhcmUubixcbiAgICAgICAgICB2c3NQcm9vZjogdXNlclRvQml0Z29TaGFyZS52c3NQcm9vZixcbiAgICAgICAgICBwcml2YXRlU2hhcmVQcm9vZjogdXNlclRvQml0Z29TaGFyZS5wcml2YXRlU2hhcmVQcm9vZixcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGZyb206ICdiaXRnbycsXG4gICAgICAgICAgdG86ICdiYWNrdXAnLFxuICAgICAgICAgIHB1YmxpY1NoYXJlOiBiYWNrdXBUb0JpdGdvU2hhcmUucHVibGljU2hhcmUsXG4gICAgICAgICAgcHJpdmF0ZVNoYXJlOiBiYWNrdXBUb0JpdGdvU2hhcmUuZW5jcnlwdGVkUHJpdmF0ZVNoYXJlLFxuICAgICAgICAgIG46IGJhY2t1cFRvQml0Z29TaGFyZS5uLFxuICAgICAgICAgIHZzc1Byb29mOiBiYWNrdXBUb0JpdGdvU2hhcmUudnNzUHJvb2YsXG4gICAgICAgICAgcHJpdmF0ZVNoYXJlUHJvb2Y6IGJhY2t1cFRvQml0Z29TaGFyZS5wcml2YXRlU2hhcmVQcm9vZixcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICB0eXBlOiAndHNzJyxcbiAgICB9O1xuXG4gICAgY29uc3QgdXNlcktleUlkID0gdXNlckdwZ0tleUFjdHVhbC5rZXlQYWNrZXQuZ2V0RmluZ2VycHJpbnQoKTtcbiAgICBjb25zdCBiYWNrdXBLZXlJZCA9IGJhY2t1cEdwZ0tleUFjdHVhbC5rZXlQYWNrZXQuZ2V0RmluZ2VycHJpbnQoKTtcbiAgICBjb25zdCBiaXRnb1RvVXNlclB1YmxpY1UgPVxuICAgICAgQnVmZmVyLmZyb20oXG4gICAgICAgIGVjYy5wb2ludEZyb21TY2FsYXIoQnVmZmVyLmZyb20ocGFyYW1zLmJpdGdvS2V5U2hhcmUublNoYXJlc1sxXS51LCAnaGV4JyksIHRydWUpIGFzIFVpbnQ4QXJyYXlcbiAgICAgICkudG9TdHJpbmcoJ2hleCcpICsgcGFyYW1zLmJpdGdvS2V5U2hhcmUublNoYXJlc1sxXS5jaGFpbmNvZGU7XG4gICAgY29uc3QgYml0Z29Ub0JhY2t1cFB1YmxpY1UgPVxuICAgICAgQnVmZmVyLmZyb20oXG4gICAgICAgIGVjYy5wb2ludEZyb21TY2FsYXIoQnVmZmVyLmZyb20ocGFyYW1zLmJpdGdvS2V5U2hhcmUublNoYXJlc1syXS51LCAnaGV4JyksIHRydWUpIGFzIFVpbnQ4QXJyYXlcbiAgICAgICkudG9TdHJpbmcoJ2hleCcpICsgcGFyYW1zLmJpdGdvS2V5U2hhcmUublNoYXJlc1syXS5jaGFpbmNvZGU7XG5cbiAgICBiaXRnb0tleWNoYWluLndhbGxldEhTTUdQR1B1YmxpY0tleVNpZ3MgPSBhd2FpdCBjcmVhdGVXYWxsZXRTaWduYXR1cmVzKFxuICAgICAgcGFyYW1zLmJpdGdvR3BnS2V5LnByaXZhdGVLZXksXG4gICAgICBwYXJhbXMudXNlckdwZ0tleS5wdWJsaWNLZXksXG4gICAgICBwYXJhbXMudXNlckxvY2FsQmFja3VwR3BnS2V5LnB1YmxpY0tleSxcbiAgICAgIFtcbiAgICAgICAgeyBuYW1lOiAnY29tbW9uS2V5Y2hhaW4nLCB2YWx1ZTogYml0Z29Db21iaW5lZC54U2hhcmUueSArIGJpdGdvQ29tYmluZWQueFNoYXJlLmNoYWluY29kZSB9LFxuICAgICAgICB7IG5hbWU6ICd1c2VyS2V5SWQnLCB2YWx1ZTogdXNlcktleUlkIH0sXG4gICAgICAgIHsgbmFtZTogJ2JhY2t1cEtleUlkJywgdmFsdWU6IGJhY2t1cEtleUlkIH0sXG4gICAgICAgIHsgbmFtZTogJ2JpdGdvVG9Vc2VyUHVibGljU2hhcmUnLCB2YWx1ZTogYml0Z29Ub1VzZXJQdWJsaWNVIH0sXG4gICAgICAgIHsgbmFtZTogJ2JpdGdvVG9CYWNrdXBQdWJsaWNTaGFyZScsIHZhbHVlOiBiaXRnb1RvQmFja3VwUHVibGljVSB9LFxuICAgICAgXVxuICAgICk7XG5cbiAgICByZXR1cm4gYml0Z29LZXljaGFpbjtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIG5vY2tCaXRnb0tleWNoYWluKHBhcmFtczoge1xuICAgIGNvaW46IHN0cmluZztcbiAgICB1c2VyS2V5U2hhcmU6IEtleVNoYXJlO1xuICAgIGJhY2t1cEtleVNoYXJlOiBLZXlTaGFyZTtcbiAgICBiaXRnb0tleVNoYXJlOiBLZXlTaGFyZTtcbiAgICB1c2VyR3BnS2V5OiBvcGVucGdwLlNlcmlhbGl6ZWRLZXlQYWlyPHN0cmluZz47XG4gICAgdXNlckxvY2FsQmFja3VwR3BnS2V5OiBvcGVucGdwLlNlcmlhbGl6ZWRLZXlQYWlyPHN0cmluZz47XG4gICAgYml0Z29HcGdLZXk6IG9wZW5wZ3AuU2VyaWFsaXplZEtleVBhaXI8c3RyaW5nPjtcbiAgfSk6IFByb21pc2U8S2V5Y2hhaW4+IHtcbiAgICBjb25zdCBiaXRnb0tleWNoYWluID0gYXdhaXQgZ2VuZXJhdGVCaXRnb0tleWNoYWluKHBhcmFtcyk7XG5cbiAgICBub2NrKGJnVXJsKVxuICAgICAgLnBlcnNpc3QoKVxuICAgICAgLnBvc3QoYC9hcGkvdjIvJHtwYXJhbXMuY29pbn0va2V5YCwgXy5tYXRjaGVzKHsga2V5VHlwZTogJ3RzcycsIHNvdXJjZTogJ2JpdGdvJyB9KSlcbiAgICAgIC5yZXBseSgyMDAsIGJpdGdvS2V5Y2hhaW4pO1xuXG4gICAgcmV0dXJuIGJpdGdvS2V5Y2hhaW47XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBub2NrS2V5Y2hhaW4ocGFyYW1zOiB7XG4gICAgY29pbjogc3RyaW5nO1xuICAgIGtleUNoYWluOiBLZXljaGFpbjtcbiAgICBzb3VyY2U6ICd1c2VyJyB8ICdiYWNrdXAnO1xuICB9KTogUHJvbWlzZTxLZXljaGFpbj4ge1xuICAgIG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpXG4gICAgICAucGVyc2lzdCgpXG4gICAgICAucG9zdChgL2FwaS92Mi8ke3BhcmFtcy5jb2lufS9rZXlgLCBfLm1hdGNoZXMoeyBrZXlUeXBlOiAndHNzJywgc291cmNlOiBwYXJhbXMuc291cmNlIH0pKVxuICAgICAgLnJlcGx5KDIwMCwgcGFyYW1zLmtleUNoYWluKTtcblxuICAgIHJldHVybiBwYXJhbXMua2V5Q2hhaW47XG4gIH1cbiAgLy8gI2VuZHJlZ2lvbiBOb2NrIGhlbHBlcnNcbn0pO1xuIl19

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


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