UNPKG

bitgo

Version:
622 lines • 99.8 kB
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const sinon = require("sinon");
const sdk_core_1 = require("@bitgo/sdk-core");
const sdk_lib_mpc_1 = require("@bitgo/sdk-lib-mpc");
const openpgp = require("openpgp");
const nock = require("nock");
const sdk_test_1 = require("@bitgo/sdk-test");
const src_1 = require("../../../../../../src");
const MPCv2PartiesEnum = sdk_core_1.ECDSAUtils.MPCv2PartiesEnum;
describe('signTxRequest:', function () {
    let tssUtils;
    let wallet;
    let bitgo;
    let baseCoin;
    let bitgoGpgKey;
    let bitgoPrvKeyObj;
    const coinName = 'sol';
    const reqId = new sdk_core_1.RequestTracer();
    const txRequestId = 'randomTxReqId';
    const signableHex = '02010206c2d5b5f4fb9a9bcd8a2f303e4d06f78d8ded300713f456da2abff0b3ea0185aa051a34bc8acd438763976f96876115050f73828553566d111d7ac8bffebf587c4f5f5987bfe26aa66013efd96d36360f2b4336c91f993259fb56051305614d42f2ea13f8ff9d7958dbf269c6e36bfdf5cb5c43de4b4e1d3efb7dab3d5d028604000000000000000000000000000000000000000000000000000000000000000006a7d517192c568ee08a845f73d29788cf035c3145b21ab344d8062ea94000003a621f6d1cc4b8fb2a739aa08e4034da0fc588ece3bd857630de30f7edde45dd0204030205010404000000040200030c02000000f0a29a3b00000000';
    const serializedTxHex = `02000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003bc9df0b397bec2ed3b6444a8c33f38267cc08b5fb2a7d37e26b6c487e26d15b7c07830eb78e26a88db5de4aa6986a327f09aed8c01533e5b972748ddf60b80f${signableHex}`;
    const messageRaw = 'TOO MANY SECRETS';
    const messageEncoded = Buffer.from(messageRaw).toString('hex');
    const txParams = {
        recipients: [
            {
                address: 'HMEgbR4S2hLKfst2VZUVpHVUu4FioFPyW5iUuJvZdMvs',
                amount: '999990000',
            },
        ],
    };
    const txRequest = {
        txRequestId,
        enterpriseId: '4517abfb-f567-4b7a-9f91-407509d29403',
        transactions: [
            {
                unsignedTx: {
                    serializedTxHex,
                    signableHex,
                    derivationPath: 'm/0', // Needs this when key derivation is supported
                },
                state: 'pendingSignature',
                signatureShares: [],
            },
        ],
        unsignedTxs: [],
        date: new Date().toISOString(),
        intent: { intentType: 'payment' },
        latest: true,
        state: 'pendingUserSignature',
        walletType: 'hot',
        walletId: 'walletId',
        policiesChecked: true,
        version: 1,
        userId: 'userId',
        apiVersion: 'full',
    };
    const txRequestForMessageSigning = {
        txRequestId,
        enterpriseId: '4517abfb-f567-4b7a-9f91-407509d29403',
        messages: [
            {
                messageRaw,
                messageEncoded,
                derivationPath: 'm/0',
                state: 'pendingSignature',
                signatureShares: [],
            },
        ],
        unsignedTxs: [],
        date: new Date().toISOString(),
        intent: { intentType: 'payment' },
        latest: true,
        state: 'pendingUserSignature',
        walletType: 'hot',
        walletId: 'walletId',
        policiesChecked: true,
        version: 1,
        userId: 'userId',
        apiVersion: 'full',
    };
    let userKeyShare;
    let backupKeyShare;
    let bitgoKeyShare;
    before(async () => {
        bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
        bitgo.initializeTestVars();
        const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
        bitgoGpgKey = await openpgp.generateKey({
            userIDs: [{ name: 'bitgo', email: 'bitgo@test.com' }],
            curve: 'ed25519',
            format: 'armored',
        });
        bitgoPrvKeyObj = await openpgp.readPrivateKey({ armoredKey: bitgoGpgKey.privateKey });
        const constants = {
            mpc: {
                bitgoPublicKey: bitgoGpgKey.publicKey,
                bitgoEddsaMpcv2PublicKey: bitgoGpgKey.publicKey,
            },
        };
        nock(bgUrl).get('/api/v1/client/constants').times(20).reply(200, { ttl: 3600, constants });
        const [userDkg, backupDkg, bitgoDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
        userKeyShare = userDkg.getKeyShare();
        backupKeyShare = backupDkg.getKeyShare();
        bitgoKeyShare = bitgoDkg.getKeyShare();
        baseCoin = bitgo.coin(coinName);
        const walletData = {
            id: txRequest.walletId,
            enterprise: txRequest.enterpriseId,
            coin: coinName,
            coinSpecific: {
                rootAddress: 'E7Z6pFfUhjx2dFjdB9Ws2KnKepXoq62TeF5uaCVSvqQV',
            },
            multisigType: 'tss',
            multisigTypeVersion: 'MPCv2',
        };
        wallet = new sdk_core_1.Wallet(bitgo, baseCoin, walletData);
        tssUtils = new sdk_core_1.EDDSAUtils.EddsaMPCv2Utils(bitgo, baseCoin, wallet);
    });
    beforeEach(async function () {
        await nockGetBitgoPublicKeyBasedOnFeatureFlags(coinName, txRequest.enterpriseId, bitgoGpgKey);
    });
    after(function () {
        nock.cleanAll();
    });
    afterEach(function () {
        nock.cleanAll();
    });
    it('successfully signs a txRequest with user key for an mps hot wallet with WP', async function () {
        const nockPromises = await getNockPromisesForEddsaSigning(txRequest);
        await Promise.all(nockPromises);
        const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
        await tssUtils.signTxRequest({
            txRequest,
            prv: userPrvBase64,
            reqId,
            txParams,
        });
        nockPromises[0].isDone().should.be.true();
        nockPromises[1].isDone().should.be.true();
        nockPromises[2].isDone().should.be.true();
        nockPromises[3].isDone().should.be.true();
    });
    it('successfully signs a txRequest with backup key for an mps hot wallet with WP', async function () {
        const nockPromises = await getNockPromisesForEddsaSigning(txRequest, sdk_core_1.RequestType.tx, 0, MPCv2PartiesEnum.BACKUP);
        await Promise.all(nockPromises);
        const backupPrvBase64 = Buffer.from(backupKeyShare).toString('base64');
        await tssUtils.signTxRequest({
            txRequest,
            prv: backupPrvBase64,
            mpcv2PartyId: MPCv2PartiesEnum.BACKUP,
            reqId,
            txParams,
        });
        nockPromises[0].isDone().should.be.true();
        nockPromises[1].isDone().should.be.true();
        nockPromises[2].isDone().should.be.true();
        nockPromises[3].isDone().should.be.true();
    });
    it('successfully signs a txRequest with a message for an mps hot wallet with WP', async function () {
        const nockPromises = await getNockPromisesForEddsaSigning(txRequestForMessageSigning, sdk_core_1.RequestType.message);
        await Promise.all(nockPromises);
        const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
        await tssUtils.signTxRequestForMessage({
            txRequest: txRequestForMessageSigning,
            prv: userPrvBase64,
            reqId,
            messageRaw: txRequestForMessageSigning.messages[0].messageRaw,
            bufferToSign: Buffer.from(messageEncoded, 'hex'),
        });
        nockPromises[0].isDone().should.be.true();
        nockPromises[1].isDone().should.be.true();
        nockPromises[2].isDone().should.be.true();
        nockPromises[3].isDone().should.be.true();
    });
    it('should throw if round 1 response has wrong type', async function () {
        nock('https://bitgo.fakeurl')
            .post(`/api/v2/wallet/${txRequest.walletId}/txrequests/${txRequest.txRequestId}/transactions/0/sign`)
            .reply(200, {
            txRequestId,
            transactions: [
                {
                    signatureShares: [
                        {
                            from: sdk_core_1.SignatureShareType.BITGO,
                            to: sdk_core_1.SignatureShareType.USER,
                            share: JSON.stringify({ type: 'round2Output', data: {} }),
                        },
                    ],
                },
            ],
        });
        const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
        await tssUtils
            .signTxRequest({ txRequest, prv: userPrvBase64, reqId, txParams })
            .should.be.rejectedWith(/Unexpected signature share response/);
    });
    it('should throw if round 2 response has wrong type', async function () {
        const messageBuffer = Buffer.from(signableHex, 'hex');
        const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(MPCv2PartiesEnum.BITGO);
        await bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, txRequest.transactions[0].unsignedTx.derivationPath, MPCv2PartiesEnum.USER);
        const bitgoMsg1 = bitgoDsg.getFirstMessage();
        // Round 1: return a valid round1Output so the orchestration can proceed
        nock('https://bitgo.fakeurl')
            .post(`/api/v2/wallet/${txRequest.walletId}/txrequests/${txRequest.txRequestId}/transactions/0/sign`, (body) => JSON.parse(body.signatureShares[0].share).type === 'round1Input')
            .reply(200, async (_uri, body) => {
            const parsedShare = JSON.parse(body.signatureShares[0].share);
            const userMsg1Bytes = Buffer.from(parsedShare.data.msg1.message, 'base64');
            const userDeserializedMsg1 = {
                from: MPCv2PartiesEnum.USER,
                payload: new Uint8Array(userMsg1Bytes),
            };
            // Advance bitgo session (we don't need bitgoMsg2 for this test)
            bitgoDsg.handleIncomingMessages([bitgoMsg1, userDeserializedMsg1]);
            const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoPrvKeyObj);
            const round1Output = {
                type: 'round1Output',
                data: { msg1: bitgoSignedMsg1 },
            };
            return {
                txRequestId,
                transactions: [
                    {
                        signatureShares: [
                            {
                                from: sdk_core_1.SignatureShareType.BITGO,
                                to: sdk_core_1.SignatureShareType.USER,
                                share: JSON.stringify(round1Output),
                            },
                        ],
                    },
                ],
            };
        });
        // Round 2: return a share with wrong type (round3Output instead of round2Output)
        nock('https://bitgo.fakeurl')
            .post(`/api/v2/wallet/${txRequest.walletId}/txrequests/${txRequest.txRequestId}/transactions/0/sign`, (body) => JSON.parse(body.signatureShares[0].share).type === 'round2Input')
            .reply(200, {
            txRequestId,
            transactions: [
                {
                    signatureShares: [
                        {
                            from: sdk_core_1.SignatureShareType.USER,
                            to: sdk_core_1.SignatureShareType.BITGO,
                            share: 'placeholder',
                        },
                        {
                            from: sdk_core_1.SignatureShareType.BITGO,
                            to: sdk_core_1.SignatureShareType.USER,
                            share: JSON.stringify({ type: 'round3Output', data: {} }),
                        },
                    ],
                },
            ],
        });
        const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
        await tssUtils
            .signTxRequest({ txRequest, prv: userPrvBase64, reqId, txParams })
            .should.be.rejectedWith(/Unexpected signature share response. Unable to parse data./);
    });
    it('successfully signs a txRequest after receiving multiple 429 errors in round 2', async function () {
        const nockPromises = await getNockPromisesForEddsaSigning(txRequest, sdk_core_1.RequestType.tx, 3);
        await Promise.all(nockPromises);
        const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
        await tssUtils.signTxRequest({
            txRequest,
            prv: userPrvBase64,
            reqId,
            txParams,
        });
        nockPromises[0].isDone().should.be.true();
        nockPromises[1].isDone().should.be.true();
        nockPromises[2].isDone().should.be.true();
        nockPromises[3].isDone().should.be.true();
    });
    it('successfully signs a txRequest after receiving multiple 429 errors in round 1', async function () {
        const nockPromises = await getNockPromisesForEddsaSigning(txRequest, sdk_core_1.RequestType.tx, 3, MPCv2PartiesEnum.USER, 1);
        await Promise.all(nockPromises);
        const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
        await tssUtils.signTxRequest({
            txRequest,
            prv: userPrvBase64,
            reqId,
            txParams,
        });
        nockPromises[0].isDone().should.be.true();
        nockPromises[1].isDone().should.be.true();
        nockPromises[2].isDone().should.be.true();
        nockPromises[3].isDone().should.be.true();
    });
    it('successfully signs a txRequest after receiving multiple 429 errors in round 3', async function () {
        const nockPromises = await getNockPromisesForEddsaSigning(txRequest, sdk_core_1.RequestType.tx, 3, MPCv2PartiesEnum.USER, 3);
        await Promise.all(nockPromises);
        const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
        await tssUtils.signTxRequest({
            txRequest,
            prv: userPrvBase64,
            reqId,
            txParams,
        });
        nockPromises[0].isDone().should.be.true();
        nockPromises[1].isDone().should.be.true();
        nockPromises[2].isDone().should.be.true();
        nockPromises[3].isDone().should.be.true();
    });
    it('fails to sign a txRequest after receiving over 3 429 errors in round 2', async function () {
        const nockPromises = await getNockPromisesForEddsaSigning(txRequest, sdk_core_1.RequestType.tx, 4);
        await Promise.all(nockPromises);
        const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
        await tssUtils
            .signTxRequest({
            txRequest,
            prv: userPrvBase64,
            reqId,
            txParams,
        })
            .should.be.rejectedWith('Too many requests, slow down!');
        nockPromises[0].isDone().should.be.true();
        nockPromises[1].isDone().should.be.false();
        nockPromises[2].isDone().should.be.false();
        nockPromises[3].isDone().should.be.false();
    });
    it('should throw if round 3 response is malformed', async function () {
        const nockPromises = await getNockPromisesForEddsaSigning(txRequest, sdk_core_1.RequestType.tx, 0, MPCv2PartiesEnum.USER, 2, true);
        await Promise.all(nockPromises);
        const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
        await tssUtils
            .signTxRequest({
            txRequest,
            prv: userPrvBase64,
            reqId,
            txParams,
        })
            .should.be.rejectedWith('Invalid txRequest object after round 3');
        nockPromises[0].isDone().should.be.true();
        nockPromises[1].isDone().should.be.true();
        nockPromises[2].isDone().should.be.true();
        nockPromises[3].isDone().should.be.false();
    });
    describe('resolveEffectiveTxParams guard (WCI-1111)', function () {
        let sandbox;
        beforeEach(function () {
            sandbox = sinon.createSandbox();
        });
        afterEach(function () {
            sandbox.restore();
        });
        it('throws InvalidTransactionError when txParams is absent and intent has no recipients (malicious/empty-recipient path)', async function () {
            // Simulate the stakingAuthorize attack vector: intent has no recipients
            // and intentType is not on the NO_RECIPIENT_TX_TYPES allowlist.
            const maliciousTxRequest = {
                ...txRequest,
                intent: { intentType: 'stakingAuthorize' },
            };
            const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
            await tssUtils
                .signTxRequest({
                txRequest: maliciousTxRequest,
                prv: userPrvBase64,
                reqId,
                // No txParams — the re-sign path that was previously vulnerable
            })
                .should.be.rejectedWith(sdk_core_1.InvalidTransactionError);
        });
        it('throws InvalidTransactionError when txParams has empty recipients and intentType is not allowlisted', async function () {
            const maliciousTxRequest = {
                ...txRequest,
                intent: { intentType: 'payment' },
            };
            const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
            await tssUtils
                .signTxRequest({
                txRequest: maliciousTxRequest,
                prv: userPrvBase64,
                reqId,
                txParams: { recipients: [] },
            })
                .should.be.rejectedWith(sdk_core_1.InvalidTransactionError);
        });
        it('does not throw for allowlisted no-recipient intentType (deactivate)', async function () {
            sandbox.stub(baseCoin, 'verifyTransaction').resolves(true);
            const nockPromises = await getNockPromisesForEddsaSigning(txRequest);
            await Promise.all(nockPromises);
            const noRecipientTxRequest = {
                ...txRequest,
                intent: { intentType: 'deactivate' },
            };
            const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
            await tssUtils.signTxRequest({
                txRequest: noRecipientTxRequest,
                prv: userPrvBase64,
                reqId,
                // No txParams — legitimate no-recipient flow
            });
        });
        it('does not throw for allowlisted no-recipient intentType (consolidate)', async function () {
            sandbox.stub(baseCoin, 'verifyTransaction').resolves(true);
            const nockPromises = await getNockPromisesForEddsaSigning(txRequest);
            await Promise.all(nockPromises);
            const consolidateTxRequest = {
                ...txRequest,
                intent: { intentType: 'consolidate' },
            };
            const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
            await tssUtils.signTxRequest({
                txRequest: consolidateTxRequest,
                prv: userPrvBase64,
                reqId,
            });
        });
        it('uses intent recipients when txParams is absent and intent has recipients', async function () {
            sandbox.stub(baseCoin, 'verifyTransaction').resolves(true);
            const nockPromises = await getNockPromisesForEddsaSigning(txRequest);
            await Promise.all(nockPromises);
            const intentRecipientTxRequest = {
                ...txRequest,
                intent: {
                    intentType: 'payment',
                    recipients: [
                        {
                            address: { address: 'HMEgbR4S2hLKfst2VZUVpHVUu4FioFPyW5iUuJvZdMvs' },
                            amount: { value: '999990000', symbol: 'sol' },
                        },
                    ],
                },
            };
            const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
            // Should not throw — intent provides the recipients
            await tssUtils.signTxRequest({
                txRequest: intentRecipientTxRequest,
                prv: userPrvBase64,
                reqId,
            });
        });
        it('does not throw for staking intent with stakingRequestId (generic staking signal)', async function () {
            sandbox.stub(baseCoin, 'verifyTransaction').resolves(true);
            const nockPromises = await getNockPromisesForEddsaSigning(txRequest);
            await Promise.all(nockPromises);
            const stakingTxRequest = {
                ...txRequest,
                intent: {
                    intentType: 'delegate',
                    stakingRequestId: 'staking-req-id-123',
                },
            };
            const userPrvBase64 = Buffer.from(userKeyShare).toString('base64');
            await tssUtils.signTxRequest({
                txRequest: stakingTxRequest,
                prv: userPrvBase64,
                reqId,
            });
        });
    });
    async function getNockPromisesForEddsaSigning(txRequest, requestType = sdk_core_1.RequestType.tx, rateLimitErrorCount = 0, signerPartyId = MPCv2PartiesEnum.USER, rateLimitRound = 2, malformedRound3Response = false) {
        const txOrMessageToSign = requestType === sdk_core_1.RequestType.message
            ? txRequest.messages[0].messageEncoded
            : txRequest.transactions[0].unsignedTx.signableHex;
        const messageBuffer = Buffer.from(txOrMessageToSign, 'hex');
        const bitgoSession = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(MPCv2PartiesEnum.BITGO);
        await bitgoSession.initDsg(bitgoKeyShare, messageBuffer, txRequest.transactions?.[0].unsignedTx.derivationPath || 'm/0', signerPartyId);
        const bitgoMsg1 = bitgoSession.getFirstMessage();
        let bitgoMsg2;
        return [
            await nockTxRequestResponseSignatureShareRoundOne(bitgoSession, txRequest, bitgoMsg1, bitgoPrvKeyObj, (msg) => {
                bitgoMsg2 = msg;
            }, requestType, signerPartyId, rateLimitRound === 1 ? rateLimitErrorCount : 0),
            await nockTxRequestResponseSignatureShareRoundTwo(txRequest, () => bitgoMsg2, bitgoPrvKeyObj, requestType, rateLimitRound === 2 ? rateLimitErrorCount : 0, signerPartyId),
            await nockTxRequestResponseSignatureShareRoundThree(txRequest, requestType, signerPartyId, rateLimitRound === 3 ? rateLimitErrorCount : 0, malformedRound3Response),
            await nockSendTxRequest(txRequest, requestType),
        ];
    }
});
async function nockGetBitgoPublicKeyBasedOnFeatureFlags(coin, enterpriseId, bitgoGpgKeyPair) {
    const bitgoGPGPublicKeyResponse = {
        name: 'irrelevant',
        publicKey: bitgoGpgKeyPair.publicKey,
        mpcv2PublicKey: bitgoGpgKeyPair.publicKey,
        eddsaMpcv2PublicKey: bitgoGpgKeyPair.publicKey,
        enterpriseId,
    };
    nock('https://bitgo.fakeurl')
        .get(`/api/v2/${coin}/tss/pubkey`)
        .times(4)
        .query({ enterpriseId })
        .reply(200, bitgoGPGPublicKeyResponse);
    return bitgoGPGPublicKeyResponse;
}
async function nockTxRequestResponseSignatureShareRoundOne(bitgoSession, txRequest, bitgoMsg1, bitgoGpgPrivKey, saveBitgoMsg2, requestType = sdk_core_1.RequestType.tx, signerPartyId = MPCv2PartiesEnum.USER, rateLimitErrorCount = 0) {
    const route = requestType === sdk_core_1.RequestType.message ? '/messages/0' : '/transactions/0';
    const signerShareType = signerPartyId === MPCv2PartiesEnum.USER ? sdk_core_1.SignatureShareType.USER : sdk_core_1.SignatureShareType.BACKUP;
    const scope = nock('https://bitgo.fakeurl');
    if (rateLimitErrorCount > 0) {
        scope
            .post(`/api/v2/wallet/${txRequest.walletId}/txrequests/${txRequest.txRequestId}${route}/sign`, (body) => JSON.parse(body.signatureShares[0].share).type === 'round1Input')
            .times(rateLimitErrorCount)
            .reply(429, {
            error: 'Too many requests, slow down!',
            name: 'TooManyRequests',
            requestId: 'cm5qx01lh0013b2ek2sxl4w00',
            context: {},
        });
    }
    return scope
        .post(`/api/v2/wallet/${txRequest.walletId}/txrequests/${txRequest.txRequestId}${route}/sign`, (body) => JSON.parse(body.signatureShares[0].share).type === 'round1Input')
        .reply(200, async (_uri, body) => {
        const parsedShare = JSON.parse(body.signatureShares[0].share);
        const userMsg1Bytes = Buffer.from(parsedShare.data.msg1.message, 'base64');
        const userDeserializedMsg1 = {
            from: signerPartyId,
            payload: new Uint8Array(userMsg1Bytes),
        };
        const [bitgoMsg2] = bitgoSession.handleIncomingMessages([bitgoMsg1, userDeserializedMsg1]);
        saveBitgoMsg2(bitgoMsg2);
        const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoGpgPrivKey);
        const round1Output = {
            type: 'round1Output',
            data: { msg1: bitgoSignedMsg1 },
        };
        const resource = requestType === sdk_core_1.RequestType.message ? 'messages' : 'transactions';
        return {
            txRequestId: txRequest.txRequestId,
            [resource]: [
                {
                    signatureShares: [
                        {
                            from: sdk_core_1.SignatureShareType.BITGO,
                            to: signerShareType,
                            share: JSON.stringify(round1Output),
                        },
                    ],
                },
            ],
        };
    });
}
async function nockTxRequestResponseSignatureShareRoundTwo(txRequest, getBitgoMsg2, bitgoGpgPrivKey, requestType = sdk_core_1.RequestType.tx, rateLimitErrorCount = 0, signerPartyId = MPCv2PartiesEnum.USER) {
    const route = requestType === sdk_core_1.RequestType.message ? '/messages/0' : '/transactions/0';
    const scope = nock('https://bitgo.fakeurl');
    const signerShareType = signerPartyId === MPCv2PartiesEnum.USER ? sdk_core_1.SignatureShareType.USER : sdk_core_1.SignatureShareType.BACKUP;
    if (rateLimitErrorCount > 0) {
        scope
            .post(`/api/v2/wallet/${txRequest.walletId}/txrequests/${txRequest.txRequestId}${route}/sign`, (body) => JSON.parse(body.signatureShares[0].share).type === 'round2Input')
            .times(rateLimitErrorCount)
            .reply(429, {
            error: 'Too many requests, slow down!',
            name: 'TooManyRequests',
            requestId: 'cm5qx01lh0013b2ek2sxl4w00',
            context: {},
        });
    }
    return scope
        .post(`/api/v2/wallet/${txRequest.walletId}/txrequests/${txRequest.txRequestId}${route}/sign`, (body) => JSON.parse(body.signatureShares[0].share).type === 'round2Input')
        .reply(200, async () => {
        const bitgoMsg2 = getBitgoMsg2();
        const bitgoSignedMsg2 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg2.payload), bitgoGpgPrivKey);
        const round2Output = {
            type: 'round2Output',
            data: { msg2: bitgoSignedMsg2 },
        };
        const resource = requestType === sdk_core_1.RequestType.message ? 'messages' : 'transactions';
        return {
            txRequestId: txRequest.txRequestId,
            [resource]: [
                {
                    signatureShares: [
                        {
                            from: signerShareType,
                            to: sdk_core_1.SignatureShareType.BITGO,
                            share: 'placeholder',
                        },
                        {
                            from: sdk_core_1.SignatureShareType.BITGO,
                            to: signerShareType,
                            share: JSON.stringify(round2Output),
                        },
                    ],
                },
            ],
        };
    });
}
async function nockTxRequestResponseSignatureShareRoundThree(txRequest, requestType = sdk_core_1.RequestType.tx, signerPartyId = MPCv2PartiesEnum.USER, rateLimitErrorCount = 0, malformedResponse = false) {
    const route = requestType === sdk_core_1.RequestType.message ? '/messages/0' : '/transactions/0';
    const signerShareType = signerPartyId === MPCv2PartiesEnum.USER ? sdk_core_1.SignatureShareType.USER : sdk_core_1.SignatureShareType.BACKUP;
    const scope = nock('https://bitgo.fakeurl');
    if (rateLimitErrorCount > 0) {
        scope
            .post(`/api/v2/wallet/${txRequest.walletId}/txrequests/${txRequest.txRequestId}${route}/sign`, (body) => JSON.parse(body.signatureShares[0].share).type === 'round3Input')
            .times(rateLimitErrorCount)
            .reply(429, {
            error: 'Too many requests, slow down!',
            name: 'TooManyRequests',
            requestId: 'cm5qx01lh0013b2ek2sxl4w00',
            context: {},
        });
    }
    return scope
        .post(`/api/v2/wallet/${txRequest.walletId}/txrequests/${txRequest.txRequestId}${route}/sign`, (body) => JSON.parse(body.signatureShares[0].share).type === 'round3Input')
        .reply(200, malformedResponse
        ? { txRequestId: `${txRequest.txRequestId}-unexpected` }
        : {
            txRequestId: txRequest.txRequestId,
            signatureShares: [
                {
                    from: signerShareType,
                    to: sdk_core_1.SignatureShareType.BITGO,
                    share: 'placeholder',
                },
            ],
        });
}
async function nockSendTxRequest(txRequest, requestType = sdk_core_1.RequestType.tx) {
    const route = requestType === sdk_core_1.RequestType.message ? '/messages/0' : '/transactions/0';
    return nock('https://bitgo.fakeurl')
        .post(`/api/v2/wallet/${txRequest.walletId}/txrequests/${txRequest.txRequestId}${route}/send`)
        .reply(200, {
        txRequestId: txRequest.txRequestId,
    });
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnblR4UmVxdWVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Rlc3QvdjIvdW5pdC9pbnRlcm5hbC90c3NVdGlscy9lZGRzYU1QQ3YyL3NpZ25UeFJlcXVlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwrQkFBK0I7QUFDL0IsOENBYXlCO0FBQ3pCLG9EQUE4RTtBQUM5RSxtQ0FBbUM7QUFDbkMsNkJBQThCO0FBQzlCLDhDQUF3RDtBQVF4RCwrQ0FBOEM7QUFFOUMsTUFBTSxnQkFBZ0IsR0FBRyxxQkFBVSxDQUFDLGdCQUFnQixDQUFDO0FBT3JELFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtJQUN6QixJQUFJLFFBQW9DLENBQUM7SUFDekMsSUFBSSxNQUFjLENBQUM7SUFDbkIsSUFBSSxLQUF5QixDQUFDO0lBQzlCLElBQUksUUFBa0IsQ0FBQztJQUN2QixJQUFJLFdBQWtGLENBQUM7SUFDdkYsSUFBSSxjQUFrQyxDQUFDO0lBQ3ZDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQztJQUV2QixNQUFNLEtBQUssR0FBRyxJQUFJLHdCQUFhLEVBQUUsQ0FBQztJQUNsQyxNQUFNLFdBQVcsR0FBRyxlQUFlLENBQUM7SUFDcEMsTUFBTSxXQUFXLEdBQ2Ysa2dCQUFrZ0IsQ0FBQztJQUNyZ0IsTUFBTSxlQUFlLEdBQUcscVFBQXFRLFdBQVcsRUFBRSxDQUFDO0lBQzNTLE1BQU0sVUFBVSxHQUFHLGtCQUFrQixDQUFDO0lBQ3RDLE1BQU0sY0FBYyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQy9ELE1BQU0sUUFBUSxHQUFHO1FBQ2YsVUFBVSxFQUFFO1lBQ1Y7Z0JBQ0UsT0FBTyxFQUFFLDhDQUE4QztnQkFDdkQsTUFBTSxFQUFFLFdBQVc7YUFDcEI7U0FDRjtLQUNGLENBQUM7SUFDRixNQUFNLFNBQVMsR0FBYztRQUMzQixX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Qyx1QkFBdUIsQ0FBQztTQUNqQyxJQUFJLENBQUMsa0JBQWtCLFNBQVMsQ0FBQyxRQUFRLGVBQWUsU0FBUyxDQUFDLFdBQVcsR0FBRyxLQUFLLE9BQU8sQ0FBQztTQUM3RixLQUFLLENBQUMsR0FBRyxFQUFFO1FBQ1YsV0FBVyxFQUFFLFNBQVMsQ0FBQyxXQUFXO0tBQ25DLENBQUMsQ0FBQztBQUNQLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQge1xuICBCYXNlQ29pbixcbiAgQml0Z29HUEdQdWJsaWNLZXksXG4gIGNvbW1vbixcbiAgRUNEU0FVdGlscyxcbiAgRUREU0FVdGlscyxcbiAgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IsXG4gIFJlcXVlc3RUcmFjZXIsXG4gIFJlcXVlc3RUeXBlLFxuICBTaWduYXR1cmVTaGFyZVJlY29yZCxcbiAgU2lnbmF0dXJlU2hhcmVUeXBlLFxuICBUeFJlcXVlc3QsXG4gIFdhbGxldCxcbn0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCB7IEVkZHNhTVBTRHNnLCBNUFNDb21tcywgTVBTVHlwZXMsIE1QU1V0aWwgfSBmcm9tICdAYml0Z28vc2RrLWxpYi1tcGMnO1xuaW1wb3J0ICogYXMgb3BlbnBncCBmcm9tICdvcGVucGdwJztcbmltcG9ydCBub2NrID0gcmVxdWlyZSgnbm9jaycpO1xuaW1wb3J0IHsgVGVzdGFibGVCRywgVGVzdEJpdEdvIH0gZnJvbSAnQGJpdGdvL3Nkay10ZXN0JztcbmltcG9ydCB7XG4gIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMUlucHV0LFxuICBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFPdXRwdXQsXG4gIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMklucHV0LFxuICBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJPdXRwdXQsXG4gIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kM0lucHV0LFxufSBmcm9tICdAYml0Z28vcHVibGljLXR5cGVzJztcbmltcG9ydCB7IEJpdEdvIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vLi4vc3JjJztcblxuY29uc3QgTVBDdjJQYXJ0aWVzRW51bSA9IEVDRFNBVXRpbHMuTVBDdjJQYXJ0aWVzRW51bTtcblxuaW50ZXJmYWNlIFNpZ25hdHVyZVNoYXJlQXBpQm9keSB7XG4gIHNpZ25hdHVyZVNoYXJlczogU2lnbmF0dXJlU2hhcmVSZWNvcmRbXTtcbiAgc2lnbmVyR3BnUHVibGljS2V5OiBzdHJpbmc7XG59XG5cbmRlc2NyaWJlKCdzaWduVHhSZXF1ZXN0OicsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IHRzc1V0aWxzOiBFRERTQVV0aWxzLkVkZHNhTVBDdjJVdGlscztcbiAgbGV0IHdhbGxldDogV2FsbGV0O1xuICBsZXQgYml0Z286IFRlc3RhYmxlQkcgJiBCaXRHbztcbiAgbGV0IGJhc2VDb2luOiBCYXNlQ29pbjtcbiAgbGV0IGJpdGdvR3BnS2V5OiBvcGVucGdwLlNlcmlhbGl6ZWRLZXlQYWlyPHN0cmluZz4gJiB7IHJldm9jYXRpb25DZXJ0aWZpY2F0ZTogc3RyaW5nIH07XG4gIGxldCBiaXRnb1BydktleU9iajogb3BlbnBncC5Qcml2YXRlS2V5O1xuICBjb25zdCBjb2luTmFtZSA9ICdzb2wnO1xuXG4gIGNvbnN0IHJlcUlkID0gbmV3IFJlcXVlc3RUcmFjZXIoKTtcbiAgY29uc3QgdHhSZXF1ZXN0SWQgPSAncmFuZG9tVHhSZXFJZCc7XG4gIGNvbnN0IHNpZ25hYmxlSGV4ID1cbiAgICAnMDIwMTAyMDZjMmQ1YjVmNGZiOWE5YmNkOGEyZjMwM2U0ZDA2Zjc4ZDhkZWQzMDA3MTNmNDU2ZGEyYWJmZjBiM2VhMDE4NWFhMDUxYTM0YmM4YWNkNDM4NzYzOTc2Zjk2ODc2MTE1MDUwZjczODI4NTUzNTY2ZDExMWQ3YWM4YmZmZWJmNTg3YzRmNWY1OTg3YmZlMjZhYTY2MDEzZWZkOTZkMzYzNjBmMmI0MzM2YzkxZjk5MzI1OWZiNTYwNTEzMDU2MTRkNDJmMmVhMTNmOGZmOWQ3OTU4ZGJmMjY5YzZlMzZiZmRmNWNiNWM0M2RlNGI0ZTFkM2VmYjdkYWIzZDVkMDI4NjA0MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA2YTdkNTE3MTkyYzU2OGVlMDhhODQ1ZjczZDI5Nzg4Y2YwMzVjMzE0NWIyMWFiMzQ0ZDgwNjJlYTk0MDAwMDAzYTYyMWY2ZDFjYzRiOGZiMmE3MzlhYTA4ZTQwMzRkYTBmYzU4OGVjZTNiZDg1NzYzMGRlMzBmN2VkZGU0NWRkMDIwNDAzMDIwNTAxMDQwNDAwMDAwMDA0MDIwMDAzMGMwMjAwMDAwMGYwYTI5YTNiMDAwMDAwMDAnO1xuICBjb25zdCBzZXJpYWxpemVkVHhIZXggPSBgMDIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDNiYzlkZjBiMzk3YmVjMmVkM2I2NDQ0YThjMzNmMzgyNjdjYzA4YjVmYjJhN2QzN2UyNmI2YzQ4N2UyNmQxNWI3YzA3ODMwZWI3OGUyNmE4OGRiNWRlNGFhNjk4NmEzMjdmMDlhZWQ4YzAxNTMzZTViOTcyNzQ4ZGRmNjBiODBmJHtzaWduYWJsZUhleH1gO1xuICBjb25zdCBtZXNzYWdlUmF3ID0gJ1RPTyBNQU5ZIFNFQ1JFVFMnO1xuICBjb25zdCBtZXNzYWdlRW5jb2RlZCA9IEJ1ZmZlci5mcm9tKG1lc3NhZ2VSYXcpLnRvU3RyaW5nKCdoZXgnKTtcbiAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgcmVjaXBpZW50czogW1xuICAgICAge1xuICAgICAgICBhZGRyZXNzOiAnSE1FZ2JSNFMyaExLZnN0MlZaVVZwSFZVdTRGaW9GUHlXNWlVdUp2WmRNdnMnLFxuICAgICAgICBhbW91bnQ6ICc5OTk5OTAwMDAnLFxuICAgICAgfSxcbiAgICBdLFxuICB9O1xuICBjb25zdCB0eFJlcXVlc3Q6IFR4UmVxdWVzdCA9IHtcbiAgICB0eFJlcXVlc3RJZCxcbiAgICBlbnRlcnByaXNlSWQ6ICc0NTE3YWJmYi1mNTY3LTRiN2EtOWY5MS00MDc1MDlkMjk0MDMnLFxuICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAge1xuICAgICAgICB1bnNpZ25lZFR4OiB7XG4gICAgICAgICAgc2VyaWFsaXplZFR4SGV4LFxuICAgICAgICAgIHNpZ25hYmxlSGV4LFxuICAgICAgICAgIGRlcml2YXRpb25QYXRoOiAnbS8wJywgLy8gTmVlZHMgdGhpcyB3aGVuIGtleSBkZXJpdmF0aW9uIGlzIHN1cHBvcnRlZFxuICAgICAgICB9LFxuICAgICAgICBzdGF0ZTogJ3BlbmRpbmdTaWduYXR1cmUnLFxuICAgICAgICBzaWduYXR1cmVTaGFyZXM6IFtdLFxuICAgICAgfSxcbiAgICBdLFxuICAgIHVuc2lnbmVkVHhzOiBbXSxcbiAgICBkYXRlOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgaW50ZW50OiB7IGludGVudFR5cGU6ICdwYXltZW50JyB9LFxuICAgIGxhdGVzdDogdHJ1ZSxcbiAgICBzdGF0ZTogJ3BlbmRpbmdVc2VyU2lnbmF0dXJlJyxcbiAgICB3YWxsZXRUeXBlOiAnaG90JyxcbiAgICB3YWxsZXRJZDogJ3dhbGxldElkJyxcbiAgICBwb2xpY2llc0NoZWNrZWQ6IHRydWUsXG4gICAgdmVyc2lvbjogMSxcbiAgICB1c2VySWQ6ICd1c2VySWQnLFxuICAgIGFwaVZlcnNpb246ICdmdWxsJyxcbiAgfTtcblxuICBjb25zdCB0eFJlcXVlc3RGb3JNZXNzYWdlU2lnbmluZzogVHhSZXF1ZXN0ID0ge1xuICAgIHR4UmVxdWVzdElkLFxuICAgIGVudGVycHJpc2VJZDogJzQ1MTdhYmZiLWY1NjctNGI3YS05ZjkxLTQwNzUwOWQyOTQwMycsXG4gICAgbWVzc2FnZXM6IFtcbiAgICAgIHtcbiAgICAgICAgbWVzc2FnZVJhdyxcbiAgICAgICAgbWVzc2FnZUVuY29kZWQsXG4gICAgICAgIGRlcml2YXRpb25QYXRoOiAnbS8wJyxcbiAgICAgICAgc3RhdGU6ICdwZW5kaW5nU2lnbmF0dXJlJyxcbiAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXSxcbiAgICAgIH0sXG4gICAgXSxcbiAgICB1bnNpZ25lZFR4czogW10sXG4gICAgZGF0ZTogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgIGludGVudDogeyBpbnRlbnRUeXBlOiAncGF5bWVudCcgfSxcbiAgICBsYXRlc3Q6IHRydWUsXG4gICAgc3RhdGU6ICdwZW5kaW5nVXNlclNpZ25hdHVyZScsXG4gICAgd2FsbGV0VHlwZTogJ2hvdCcsXG4gICAgd2FsbGV0SWQ6ICd3YWxsZXRJZCcsXG4gICAgcG9saWNpZXNDaGVja2VkOiB0cnVlLFxuICAgIHZlcnNpb246IDEsXG4gICAgdXNlcklkOiAndXNlcklkJyxcbiAgICBhcGlWZXJzaW9uOiAnZnVsbCcsXG4gIH07XG5cbiAgbGV0IHVzZXJLZXlTaGFyZTogQnVmZmVyO1xuICBsZXQgYmFja3VwS2V5U2hhcmU6IEJ1ZmZlcjtcbiAgbGV0IGJpdGdvS2V5U2hhcmU6IEJ1ZmZlcjtcblxuICBiZWZvcmUoYXN5bmMgKCkgPT4ge1xuICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ21vY2snIH0pO1xuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgIGNvbnN0IGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuICAgIGJpdGdvR3BnS2V5ID0gYXdhaXQgb3BlbnBncC5nZW5lcmF0ZUtleSh7XG4gICAgICB1c2VySURzOiBbeyBuYW1lOiAnYml0Z28nLCBlbWFpbDogJ2JpdGdvQHRlc3QuY29tJyB9XSxcbiAgICAgIGN1cnZlOiAnZWQyNTUxOScsXG4gICAgICBmb3JtYXQ6ICdhcm1vcmVkJyxcbiAgICB9KTtcbiAgICBiaXRnb1BydktleU9iaiA9IGF3YWl0IG9wZW5wZ3AucmVhZFByaXZhdGVLZXkoeyBhcm1vcmVkS2V5OiBiaXRnb0dwZ0tleS5wcml2YXRlS2V5IH0pO1xuICAgIGNvbnN0IGNvbnN0YW50cyA9IHtcbiAgICAgIG1wYzoge1xuICAgICAgICBiaXRnb1B1YmxpY0tleTogYml0Z29HcGdLZXkucHVibGljS2V5LFxuICAgICAgICBiaXRnb0VkZHNhTXBjdjJQdWJsaWNLZXk6IGJpdGdvR3BnS2V5LnB1YmxpY0tleSxcbiAgICAgIH0sXG4gICAgfTtcbiAgICBub2NrKGJnVXJsKS5nZXQoJy9hcGkvdjEvY2xpZW50L2NvbnN0YW50cycpLnRpbWVzKDIwKS5yZXBseSgyMDAsIHsgdHRsOiAzNjAwLCBjb25zdGFudHMgfSk7XG5cbiAgICBjb25zdCBbdXNlckRrZywgYmFja3VwRGtnLCBiaXRnb0RrZ10gPSBhd2FpdCBNUFNVdGlsLmdlbmVyYXRlRWREc2FES0dLZXlTaGFyZXMoKTtcbiAgICB1c2VyS2V5U2hhcmUgPSB1c2VyRGtnLmdldEtleVNoYXJlKCk7XG4gICAgYmFja3VwS2V5U2hhcmUgPSBiYWNrdXBEa2cuZ2V0S2V5U2hhcmUoKTtcbiAgICBiaXRnb0tleVNoYXJlID0gYml0Z29Ea2cuZ2V0S2V5U2hhcmUoKTtcblxuICAgIGJhc2VDb2luID0gYml0Z28uY29pbihjb2luTmFtZSk7XG5cbiAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgaWQ6IHR4UmVxdWVzdC53YWxsZXRJZCxcbiAgICAgIGVudGVycHJpc2U6IHR4UmVxdWVzdC5lbnRlcnByaXNlSWQsXG4gICAgICBjb2luOiBjb2luTmFtZSxcbiAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICByb290QWRkcmVzczogJ0U3WjZwRmZVaGp4MmRGamRCOVdzMktuS2VwWG9xNjJUZUY1dWFDVlN2cVFWJyxcbiAgICAgIH0sXG4gICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgbXVsdGlzaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICB9O1xuICAgIHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2VDb2luLCB3YWxsZXREYXRhKTtcbiAgICB0c3NVdGlscyA9IG5ldyBFRERTQVV0aWxzLkVkZHNhTVBDdjJVdGlscyhiaXRnbywgYmFzZUNvaW4sIHdhbGxldCk7XG4gIH0pO1xuXG4gIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGF3YWl0IG5vY2tHZXRCaXRnb1B1YmxpY0tleUJhc2VkT25GZWF0dXJlRmxhZ3MoY29pbk5hbWUsIHR4UmVxdWVzdC5lbnRlcnByaXNlSWQhLCBiaXRnb0dwZ0tleSk7XG4gIH0pO1xuXG4gIGFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICBub2NrLmNsZWFuQWxsKCk7XG4gIH0pO1xuXG4gIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgbm9jay5jbGVhbkFsbCgpO1xuICB9KTtcblxuICBpdCgnc3VjY2Vzc2Z1bGx5IHNpZ25zIGEgdHhSZXF1ZXN0IHdpdGggdXNlciBrZXkgZm9yIGFuIG1wcyBob3Qgd2FsbGV0IHdpdGggV1AnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgbm9ja1Byb21pc2VzID0gYXdhaXQgZ2V0Tm9ja1Byb21pc2VzRm9yRWRkc2FTaWduaW5nKHR4UmVxdWVzdCk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwobm9ja1Byb21pc2VzKTtcblxuICAgIGNvbnN0IHVzZXJQcnZCYXNlNjQgPSBCdWZmZXIuZnJvbSh1c2VyS2V5U2hhcmUpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICBhd2FpdCB0c3NVdGlscy5zaWduVHhSZXF1ZXN0KHtcbiAgICAgIHR4UmVxdWVzdCxcbiAgICAgIHBydjogdXNlclBydkJhc2U2NCxcbiAgICAgIHJlcUlkLFxuICAgICAgdHhQYXJhbXMsXG4gICAgfSk7XG4gICAgbm9ja1Byb21pc2VzWzBdLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgbm9ja1Byb21pc2VzWzFdLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgbm9ja1Byb21pc2VzWzJdLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgbm9ja1Byb21pc2VzWzNdLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gIH0pO1xuXG4gIGl0KCdzdWNjZXNzZnVsbHkgc2lnbnMgYSB0eFJlcXVlc3Qgd2l0aCBiYWNrdXAga2V5IGZvciBhbiBtcHMgaG90IHdhbGxldCB3aXRoIFdQJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IG5vY2tQcm9taXNlcyA9IGF3YWl0IGdldE5vY2tQcm9taXNlc0ZvckVkZHNhU2lnbmluZyh0eFJlcXVlc3QsIFJlcXVlc3RUeXBlLnR4LCAwLCBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwobm9ja1Byb21pc2VzKTtcblxuICAgIGNvbnN0IGJhY2t1cFBydkJhc2U2NCA9IEJ1ZmZlci5mcm9tKGJhY2t1cEtleVNoYXJlKS50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgYXdhaXQgdHNzVXRpbHMuc2lnblR4UmVxdWVzdCh7XG4gICAgICB0eFJlcXVlc3QsXG4gICAgICBwcnY6IGJhY2t1cFBydkJhc2U2NCxcbiAgICAgIG1wY3YyUGFydHlJZDogTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVAsXG4gICAgICByZXFJZCxcbiAgICAgIHR4UGFyYW1zLFxuICAgIH0pO1xuICAgIG5vY2tQcm9taXNlc1swXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIG5vY2tQcm9taXNlc1sxXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIG5vY2tQcm9taXNlc1syXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIG5vY2tQcm9taXNlc1szXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICB9KTtcblxuICBpdCgnc3VjY2Vzc2Z1bGx5IHNpZ25zIGEgdHhSZXF1ZXN0IHdpdGggYSBtZXNzYWdlIGZvciBhbiBtcHMgaG90IHdhbGxldCB3aXRoIFdQJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IG5vY2tQcm9taXNlcyA9IGF3YWl0IGdldE5vY2tQcm9taXNlc0ZvckVkZHNhU2lnbmluZyh0eFJlcXVlc3RGb3JNZXNzYWdlU2lnbmluZywgUmVxdWVzdFR5cGUubWVzc2FnZSk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwobm9ja1Byb21pc2VzKTtcblxuICAgIGNvbnN0IHVzZXJQcnZCYXNlNjQgPSBCdWZmZXIuZnJvbSh1c2VyS2V5U2hhcmUpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICBhd2FpdCB0c3NVdGlscy5zaWduVHhSZXF1ZXN0Rm9yTWVzc2FnZSh7XG4gICAgICB0eFJlcXVlc3Q6IHR4UmVxdWVzdEZvck1lc3NhZ2VTaWduaW5nLFxuICAgICAgcHJ2OiB1c2VyUHJ2QmFzZTY0LFxuICAgICAgcmVxSWQsXG4gICAgICBtZXNzYWdlUmF3OiB0eFJlcXVlc3RGb3JNZXNzYWdlU2lnbmluZy5tZXNzYWdlcyFbMF0ubWVzc2FnZVJhdyxcbiAgICAgIGJ1ZmZlclRvU2lnbjogQnVmZmVyLmZyb20obWVzc2FnZUVuY29kZWQsICdoZXgnKSxcbiAgICB9KTtcbiAgICBub2NrUHJvbWlzZXNbMF0uaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICBub2NrUHJvbWlzZXNbMV0uaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICBub2NrUHJvbWlzZXNbMl0uaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICBub2NrUHJvbWlzZXNbM10uaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB0aHJvdyBpZiByb3VuZCAxIHJlc3BvbnNlIGhhcyB3cm9uZyB0eXBlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpXG4gICAgICAucG9zdChgL2FwaS92Mi93YWxsZXQvJHt0eFJlcXVlc3Qud2FsbGV0SWR9L3R4cmVxdWVzdHMvJHt0eFJlcXVlc3QudHhSZXF1ZXN0SWR9L3RyYW5zYWN0aW9ucy8wL3NpZ25gKVxuICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICB0eFJlcXVlc3RJZCxcbiAgICAgICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgICAgICAgICAgICAgdG86IFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSLFxuICAgICAgICAgICAgICAgIHNoYXJlOiBKU09OLnN0cmluZ2lmeSh7IHR5cGU6ICdyb3VuZDJPdXRwdXQnLCBkYXRhOiB7fSB9KSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuXG4gICAgY29uc3QgdXNlclBydkJhc2U2NCA9IEJ1ZmZlci5mcm9tKHVzZXJLZXlTaGFyZSkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgIGF3YWl0IHRzc1V0aWxzXG4gICAgICAuc2lnblR4UmVxdWVzdCh7IHR4UmVxdWVzdCwgcHJ2OiB1c2VyUHJ2QmFzZTY0LCByZXFJZCwgdHhQYXJhbXMgfSlcbiAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9VbmV4cGVjdGVkIHNpZ25hdHVyZSBzaGFyZSByZXNwb25zZS8pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHRocm93IGlmIHJvdW5kIDIgcmVzcG9uc2UgaGFzIHdyb25nIHR5cGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgbWVzc2FnZUJ1ZmZlciA9IEJ1ZmZlci5mcm9tKHNpZ25hYmxlSGV4LCAnaGV4Jyk7XG4gICAgY29uc3QgYml0Z29Ec2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGF3YWl0IGJpdGdvRHNnLmluaXREc2coXG4gICAgICBiaXRnb0tleVNoYXJlLFxuICAgICAgbWVzc2FnZUJ1ZmZlcixcbiAgICAgIHR4UmVxdWVzdC50cmFuc2FjdGlvbnMhWzBdLnVuc2lnbmVkVHguZGVyaXZhdGlvblBhdGgsXG4gICAgICBNUEN2MlBhcnRpZXNFbnVtLlVTRVJcbiAgICApO1xuICAgIGNvbnN0IGJpdGdvTXNnMSA9IGJpdGdvRHNnLmdldEZpcnN0TWVzc2FnZSgpO1xuXG4gICAgLy8gUm91bmQgMTogcmV0dXJuIGEgdmFsaWQgcm91bmQxT3V0cHV0IHNvIHRoZSBvcmNoZXN0cmF0aW9uIGNhbiBwcm9jZWVkXG4gICAgbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgIC5wb3N0KFxuICAgICAgICBgL2FwaS92Mi93YWxsZXQvJHt0eFJlcXVlc3Qud2FsbGV0SWR9L3R4cmVxdWVzdHMvJHt0eFJlcXVlc3QudHhSZXF1ZXN0SWR9L3RyYW5zYWN0aW9ucy8wL3NpZ25gLFxuICAgICAgICAoYm9keSkgPT5cbiAgICAgICAgICAoSlNPTi5wYXJzZShib2R5LnNpZ25hdHVyZVNoYXJlc1swXS5zaGFyZSkgYXMgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxSW5wdXQpLnR5cGUgPT09ICdyb3VuZDFJbnB1dCdcbiAgICAgIClcbiAgICAgIC5yZXBseShcbiAgICAgICAgMjAwLFxuICAgICAgICBhc3luYyAoX3VyaTogc3RyaW5nLCBib2R5OiB7IHNpZ25hdHVyZVNoYXJlczogU2lnbmF0dXJlU2hhcmVSZWNvcmRbXTsgc2lnbmVyR3BnUHVibGljS2V5OiBzdHJpbmcgfSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHBhcnNlZFNoYXJlID0gSlNPTi5wYXJzZShib2R5LnNpZ25hdHVyZVNoYXJlc1swXS5zaGFyZSkgYXMgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxSW5wdXQ7XG4gICAgICAgICAgY29uc3QgdXNlck1zZzFCeXRlcyA9IEJ1ZmZlci5mcm9tKHBhcnNlZFNoYXJlLmRhdGEubXNnMS5tZXNzYWdlLCAnYmFzZTY0Jyk7XG4gICAgICAgICAgY29uc3QgdXNlckRlc2VyaWFsaXplZE1zZzE6IE1QU1R5cGVzLkRlc2VyaWFsaXplZE1lc3NhZ2UgPSB7XG4gICAgICAgICAgICBmcm9tOiBNUEN2MlBhcnRpZXNFbnVtLlVTRVIsXG4gICAgICAgICAgICBwYXlsb2FkOiBuZXcgVWludDhBcnJheSh1c2VyTXNnMUJ5dGVzKSxcbiAgICAgICAgICB9O1xuICAgICAgICAgIC8vIEFkdmFuY2UgYml0Z28gc2Vzc2lvbiAod2UgZG9uJ3QgbmVlZCBiaXRnb01zZzIgZm9yIHRoaXMgdGVzdClcbiAgICAgICAgICBiaXRnb0RzZy5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKFtiaXRnb01zZzEsIHVzZXJEZXNlcmlhbGl6ZWRNc2cxXSk7XG4gICAgICAgICAgY29uc3QgYml0Z29TaWduZWRNc2cxID0gYXdhaXQgTVBTQ29tbXMuZGV0YWNoU2lnbk1wc01lc3NhZ2UoQnVmZmVyLmZyb20oYml0Z29Nc2cxLnBheWxvYWQpLCBiaXRnb1BydktleU9iaik7XG4gICAgICAgICAgY29uc3Qgcm91bmQxT3V0cHV0OiBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFPdXRwdXQgPSB7XG4gICAgICAgICAgICB0eXBlOiAncm91bmQxT3V0cHV0JyxcbiAgICAgICAgICAgIGRhdGE6IHsgbXNnMTogYml0Z29TaWduZWRNc2cxIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHhSZXF1ZXN0SWQsXG4gICAgICAgICAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHNpZ25hdHVyZVNoYXJlczogW1xuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgICAgICAgICAgICAgICAgIHRvOiBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUixcbiAgICAgICAgICAgICAgICAgICAgc2hhcmU6IEpTT04uc3RyaW5naWZ5KHJvdW5kMU91dHB1dCksXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICk7XG5cbiAgICAvLyBSb3VuZCAyOiByZXR1cm4gYSBzaGFyZSB3aXRoIHdyb25nIHR5cGUgKHJvdW5kM091dHB1dCBpbnN0ZWFkIG9mIHJvdW5kMk91dHB1dClcbiAgICBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgLnBvc3QoXG4gICAgICAgIGAvYXBpL3YyL3dhbGxldC8ke3R4UmVxdWVzdC53YWxsZXRJZH0vdHhyZXF1ZXN0cy8ke3R4UmVxdWVzdC50eFJlcXVlc3RJZH0vdHJhbnNhY3Rpb25zLzAvc2lnbmAsXG4gICAgICAgIChib2R5KSA9PlxuICAgICAgICAgIChKU09OLnBhcnNlKGJvZHkuc2lnbmF0dXJlU2hhcmVzWzBdLnNoYXJlKSBhcyBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJJbnB1dCkudHlwZSA9PT0gJ3JvdW5kMklucHV0J1xuICAgICAgKVxuICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICB0eFJlcXVlc3RJZCxcbiAgICAgICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUixcbiAgICAgICAgICAgICAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPLFxuICAgICAgICAgICAgICAgIHNoYXJlOiAncGxhY2Vob2xkZXInLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZnJvbTogU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPLFxuICAgICAgICAgICAgICAgIHRvOiBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUixcbiAgICAgICAgICAgICAgICBzaGFyZTogSlNPTi5zdHJpbmdpZnkoeyB0eXBlOiAncm91bmQzT3V0cHV0JywgZGF0YToge30gfSksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcblxuICAgIGNvbnN0IHVzZXJQcnZCYXNlNjQgPSBCdWZmZXIuZnJvbSh1c2VyS2V5U2hhcmUpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICBhd2FpdCB0c3NVdGlsc1xuICAgICAgLnNpZ25UeFJlcXVlc3QoeyB0eFJlcXVlc3QsIHBydjogdXNlclBydkJhc2U2NCwgcmVxSWQsIHR4UGFyYW1zIH0pXG4gICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvVW5leHBlY3RlZCBzaWduYXR1cmUgc2hhcmUgcmVzcG9uc2UuIFVuYWJsZSB0byBwYXJzZSBkYXRhLi8pO1xuICB9KTtcblxuICBpdCgnc3VjY2Vzc2Z1bGx5IHNpZ25zIGEgdHhSZXF1ZXN0IGFmdGVyIHJlY2VpdmluZyBtdWx0aXBsZSA0MjkgZXJyb3JzIGluIHJvdW5kIDInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgbm9ja1Byb21pc2VzID0gYXdhaXQgZ2V0Tm9ja1Byb21pc2VzRm9yRWRkc2FTaWduaW5nKHR4UmVxdWVzdCwgUmVxdWVzdFR5cGUudHgsIDMpO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKG5vY2tQcm9taXNlcyk7XG5cbiAgICBjb25zdCB1c2VyUHJ2QmFzZTY0ID0gQnVmZmVyLmZyb20odXNlcktleVNoYXJlKS50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgYXdhaXQgdHNzVXRpbHMuc2lnblR4UmVxdWVzdCh7XG4gICAgICB0eFJlcXVlc3QsXG4gICAgICBwcnY6IHVzZXJQcnZCYXNlNjQsXG4gICAgICByZXFJZCxcbiAgICAgIHR4UGFyYW1zLFxuICAgIH0pO1xuICAgIG5vY2tQcm9taXNlc1swXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIG5vY2tQcm9taXNlc1sxXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIG5vY2tQcm9taXNlc1syXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIG5vY2tQcm9taXNlc1szXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICB9KTtcblxuICBpdCgnc3VjY2Vzc2Z1bGx5IHNpZ25zIGEgdHhSZXF1ZXN0IGFmdGVyIHJlY2VpdmluZyBtdWx0aXBsZSA0MjkgZXJyb3JzIGluIHJvdW5kIDEnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgbm9ja1Byb21pc2VzID0gYXdhaXQgZ2V0Tm9ja1Byb21pc2VzRm9yRWRkc2FTaWduaW5nKHR4UmVxdWVzdCwgUmVxdWVzdFR5cGUudHgsIDMsIE1QQ3YyUGFydGllc0VudW0uVVNFUiwgMSk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwobm9ja1Byb21pc2VzKTtcblxuICAgIGNvbnN0IHVzZXJQcnZCYXNlNjQgPSBCdWZmZXIuZnJvbSh1c2VyS2V5U2hhcmUpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICBhd2FpdCB0c3NVdGlscy5zaWduVHhSZXF1ZXN0KHtcbiAgICAgIHR4UmVxdWVzdCxcbiAgICAgIHBydjogdXNlclBydkJhc2U2NCxcbiAgICAgIHJlcUlkLFxuICAgICAgdHhQYXJhbXMsXG4gICAgfSk7XG4gICAgbm9ja1Byb21pc2VzWzBdLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgbm9ja1Byb21pc2VzWzFdLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgbm9ja1Byb21pc2VzWzJdLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgbm9ja1Byb21pc2VzWzNdLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gIH0pO1xuXG4gIGl0KCdzdWNjZXNzZnVsbHkgc2lnbnMgYSB0eFJlcXVlc3QgYWZ0ZXIgcmVjZWl2aW5nIG11bHRpcGxlIDQyOSBlcnJvcnMgaW4gcm91bmQgMycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBub2NrUHJvbWlzZXMgPSBhd2FpdCBnZXROb2NrUHJvbWlzZXNGb3JFZGRzYVNpZ25pbmcodHhSZXF1ZXN0LCBSZXF1ZXN0VHlwZS50eCwgMywgTVBDdjJQYXJ0aWVzRW51bS5VU0VSLCAzKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChub2NrUHJvbWlzZXMpO1xuXG4gICAgY29uc3QgdXNlclBydkJhc2U2NCA9IEJ1ZmZlci5mcm9tKHVzZXJLZXlTaGFyZSkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgIGF3YWl0IHRzc1V0aWxzLnNpZ25UeFJlcXVlc3Qoe1xuICAgICAgdHhSZXF1ZXN0LFxuICAgICAgcHJ2OiB1c2VyUHJ2QmFzZTY0LFxuICAgICAgcmVxSWQsXG4gICAgICB0eFBhcmFtcyxcbiAgICB9KTtcbiAgICBub2NrUHJvbWlzZXNbMF0uaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICBub2NrUHJvbWlzZXNbMV0uaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICBub2NrUHJvbWlzZXNbMl0uaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICBub2NrUHJvbWlzZXNbM10uaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgfSk7XG5cbiAgaXQoJ2ZhaWxzIHRvIHNpZ24gYSB0eFJlcXVlc3QgYWZ0ZXIgcmVjZWl2aW5nIG92ZXIgMyA0MjkgZXJyb3JzIGluIHJvdW5kIDInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgbm9ja1Byb21pc2VzID0gYXdhaXQgZ2V0Tm9ja1Byb21pc2VzRm9yRWRkc2FTaWduaW5nKHR4UmVxdWVzdCwgUmVxdWVzdFR5cGUudHgsIDQpO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKG5vY2tQcm9taXNlcyk7XG5cbiAgICBjb25zdCB1c2VyUHJ2QmFzZTY0ID0gQnVmZmVyLmZyb20odXNlcktleVNoYXJlKS50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgYXdhaXQgdHNzVXRpbHNcbiAgICAgIC5zaWduVHhSZXF1ZXN0KHtcbiAgICAgICAgdHhSZXF1ZXN0LFxuICAgICAgICBwcnY6IHVzZXJQcnZCYXNlNjQsXG4gICAgICAgIHJlcUlkLFxuICAgICAgICB0eFBhcmFtcyxcbiAgICAgIH0pXG4gICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnVG9vIG1hbnkgcmVxdWVzdHMsIHNsb3cgZG93biEnKTtcbiAgICBub2NrUHJvbWlzZXNbMF0uaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICBub2NrUHJvbWlzZXNbMV0uaXNEb25lKCkuc2hvdWxkLmJlLmZhbHNlKCk7XG4gICAgbm9ja1Byb21pc2VzWzJdLmlzRG9uZSgpLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgIG5vY2tQcm9taXNlc1szXS5pc0RvbmUoKS5zaG91bGQuYmUuZmFsc2UoKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB0aHJvdyBpZiByb3VuZCAzIHJlc3BvbnNlIGlzIG1hbGZvcm1lZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBub2NrUHJvbWlzZXMgPSBhd2FpdCBnZXROb2NrUHJvbWlzZXNGb3JFZGRzYVNpZ25pbmcoXG4gICAgICB0eFJlcXVlc3QsXG4gICAgICBSZXF1ZXN0VHlwZS50eCxcbiAgICAgIDAsXG4gICAgICBNUEN2MlBhcnRpZXNFbnVtLlVTRVIsXG4gICAgICAyLFxuICAgICAgdHJ1ZVxuICAgICk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwobm9ja1Byb21pc2VzKTtcblxuICAgIGNvbnN0IHVzZXJQcnZCYXNlNjQgPSBCdWZmZXIuZnJvbSh1c2VyS2V5U2hhcmUpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICBhd2FpdCB0c3NVdGlsc1xuICAgICAgLnNpZ25UeFJlcXVlc3Qoe1xuICAgICAgICB0eFJlcXVlc3QsXG4gICAgICAgIHBydjogdXNlclBydkJhc2U2NCxcbiAgICAgICAgcmVxSWQsXG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgfSlcbiAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIHR4UmVxdWVzdCBvYmplY3QgYWZ0ZXIgcm91bmQgMycpO1xuICAgIG5vY2tQcm9taXNlc1swXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIG5vY2tQcm9taXNlc1sxXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIG5vY2tQcm9taXNlc1syXS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIG5vY2tQcm9taXNlc1szXS5pc0RvbmUoKS5zaG91bGQuYmUuZmFsc2UoKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3Jlc29sdmVFZmZlY3RpdmVUeFBhcmFtcyBndWFyZCAoV0NJLTExMTEpJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBzYW5kYm94OiBzaW5vbi5TaW5vblNhbmRib3g7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgc2FuZGJveC5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgndGhyb3dzIEludmFsaWRUcmFuc2FjdGlvbkVycm9yIHdoZW4gdHhQYXJhbXMgaXMgYWJzZW50IGFuZCBpbnRlbnQgaGFzIG5vIHJlY2lwaWVudHMgKG1hbGljaW91cy9lbXB0eS1yZWNpcGllbnQgcGF0aCknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBTaW11bGF0ZSB0aGUgc3Rha2luZ0F1dGhvcml6ZSBhdHRhY2sgdmVjdG9yOiBpbnRlbnQgaGFzIG5vIHJlY2lwaWVudHNcbiAgICAgIC8vIGFuZCBpbnRlbnRUeXBlIGlzIG5vdCBvbiB0aGUgTk9fUkVDSVBJRU5UX1RYX1RZUEVTIGFsbG93bGlzdC5cbiAgICAgIGNvbnN0IG1hbGljaW91c1R4UmVxdWVzdDogVHhSZXF1ZXN0ID0ge1xuICAgICAgICAuLi50eFJlcXVlc3QsXG4gICAgICAgIGludGVudDogeyBpbnRlbnRUeXBlOiAnc3Rha2luZ0F1dGhvcml6ZScgfSBhcyBhbnksXG4gICAgICB9O1xuICAgICAgY29uc3QgdXNlclBydkJhc2U2NCA9IEJ1ZmZlci5mcm9tKHVzZXJLZXlTaGFyZSkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgICAgYXdhaXQgdHNzVXRpbHNcbiAgICAgICAgLnNpZ25UeFJlcXVlc3Qoe1xuICAgICAgICAgIHR4UmVxdWVzdDogbWFsaWNpb3VzVHhSZXF1ZXN0LFxuICAgICAgICAgIHBydjogdXNlclBydkJhc2U2NCxcbiAgICAgICAgICByZXFJZCxcbiAgICAgICAgICAvLyBObyB0eFBhcmFtcyDigJQgdGhlIHJlLXNpZ24gcGF0aCB0aGF0IHdhcyBwcmV2aW91c2x5IHZ1bG5lcmFibGVcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Rocm93cyBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvciB3aGVuIHR4UGFyYW1zIGhhcyBlbXB0eSByZWNpcGllbnRzIGFuZCBpbnRlbnRUeXBlIGlzIG5vdCBhbGxvd2xpc3RlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1hbGljaW91c1R4UmVxdWVzdDogVHhSZXF1ZXN0ID0ge1xuICAgICAgICAuLi50eFJlcXVlc3QsXG4gICAgICAgIGludGVudDogeyBpbnRlbnRUeXBlOiAncGF5bWVudCcgfSBhcyBhbnksXG4gICAgICB9O1xuICAgICAgY29uc3QgdXNlclBydkJhc2U2NCA9IEJ1ZmZlci5mcm9tKHVzZXJLZXlTaGFyZSkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgICAgYXdhaXQgdHNzVXRpbHNcbiAgICAgICAgLnNpZ25UeFJlcXVlc3Qoe1xuICAgICAgICAgIHR4UmVxdWVzdDogbWFsaWNpb3VzVHhSZXF1ZXN0LFxuICAgICAgICAgIHBydjogdXNlclBydkJhc2U2NCxcbiAgICAgICAgICByZXFJZCxcbiAgICAgICAgICB0eFBhcmFtczogeyByZWNpcGllbnRzOiBbXSB9LFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcik7XG4gICAgfSk7XG5cbiAgICBpdCgnZG9lcyBub3QgdGhyb3cgZm9yIGFsbG93bGlzdGVkIG5vLXJlY2lwaWVudCBpbnRlbnRUeXBlIChkZWFjdGl2YXRlKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHNhbmRib3guc3R1YihiYXNlQ29pbiwgJ3ZlcmlmeVRyYW5zYWN0aW9uJykucmVzb2x2ZXModHJ1ZSk7XG4gICAgICBjb25zdCBub2NrUHJvbWlzZXMgPSBhd2FpdCBnZXROb2NrUHJvbWlzZXNGb3JFZGRzYVNpZ25pbmcodHhSZXF1ZXN0KTtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKG5vY2tQcm9taXNlcyk7XG5cbiAgICAgIGNvbnN0IG5vUmVjaXBpZW50VHhSZXF1ZXN0OiBUeFJlcXVlc3QgPSB7XG4gICAgICAgIC4uLnR4UmVxdWVzdCxcbiAgICAgICAgaW50ZW50OiB7IGludGVudFR5cGU6ICdkZWFjdGl2YXRlJyB9IGFzIGFueSxcbiAgICAgIH07XG4gICAgICBjb25zdCB1c2VyUHJ2QmFzZTY0ID0gQnVmZmVyLmZyb20odXNlcktleVNoYXJlKS50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgICBhd2FpdCB0c3NVdGlscy5zaWduVHhSZXF1ZXN0KHtcbiAgICAgICAgdHhSZXF1ZXN0OiBub1JlY2lwaWVudFR4UmVxdWVzdCxcbiAgICAgICAgcHJ2OiB1c2VyUHJ2QmFzZTY0LFxuICAgICAgICByZXFJZCxcbiAgICAgICAgLy8gTm8gdHhQYXJhbXMg4oCUIGxlZ2l0aW1hdGUgbm8tcmVjaXBpZW50IGZsb3dcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2RvZXMgbm90IHRocm93IGZvciBhbGxvd2xpc3RlZCBuby1yZWNpcGllbnQgaW50ZW50VHlwZSAoY29uc29saWRhdGUpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgc2FuZGJveC5zdHViKGJhc2VDb2luLCAndmVyaWZ5VHJhbnNhY3Rpb24nKS5yZXNvbHZlcyh0cnVlKTtcbiAgICAgIGNvbnN0IG5vY2tQcm9taXNlcyA9IGF3YWl0IGdldE5vY2tQcm9taXNlc0ZvckVkZHNhU2lnbmluZyh0eFJlcXVlc3QpO1xuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwobm9ja1Byb21pc2VzKTtcblxuICAgICAgY29uc3QgY29uc29saWRhdGVUeFJlcXVlc3Q6IFR4UmVxdWVzdCA9IHtcbiAgICAgICAgLi4udHhSZXF1ZXN0LFxuICAgICAgICBpbnRlbnQ6IHsgaW50ZW50VHlwZTogJ2NvbnNvbGlkYXRlJyB9IGFzIGFueSxcbiAgICAgIH07XG4gICAgICBjb25zdCB1c2VyUHJ2QmFzZTY0ID0gQnVmZmVyLmZyb20odXNlcktleVNoYXJlKS50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgICBhd2FpdCB0c3NVdGlscy5zaWduVHhSZXF1ZXN0KHtcbiAgICAgICAgdHhSZXF1ZXN0OiBjb25zb2xpZGF0ZVR4UmVxdWVzdCxcbiAgICAgICAgcHJ2OiB1c2VyUHJ2QmFzZTY0LFxuICAgICAgICByZXFJZCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3VzZXMgaW50ZW50IHJlY2lwaWVudHMgd2hlbiB0eFBhcmFtcyBpcyBhYnNlbnQgYW5kIGludGVudCBoYXMgcmVjaXBpZW50cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHNhbmRib3guc3R1YihiYXNlQ29pbiwgJ3ZlcmlmeVRyYW5zYWN0aW9uJykucmVzb2x2ZXModHJ1ZSk7XG4gICAgICBjb25zdCBub2NrUHJvbWlzZXMgPSBhd2FpdCBnZXROb2NrUHJvbWlzZXNGb3JFZGRzYVNpZ25pbmcodHhSZXF1ZXN0KTtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKG5vY2tQcm9taXNlcyk7XG5cbiAgICAgIGNvbnN0IGludGVudFJlY2lwaWVudFR4UmVxdWVzdDogVHhSZXF1ZXN0ID0ge1xuICAgICAgICAuLi50eFJlcXVlc3QsXG4gICAgICAgIGludGVudDoge1xuICAgICAgICAgIGludGVudFR5cGU6ICdwYXltZW50JyxcbiAgICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFkZHJlc3M6IHsgYWRkcmVzczogJ0hNRWdiUjRTMmhMS2ZzdDJWWlVWcEhWVXU0RmlvRlB5VzVpVXVKdlpkTXZzJyB9LFxuICAgICAgICAgICAgICBhbW91bnQ6IHsgdmFsdWU6ICc5OTk5OTAwMDAnLCBzeW1ib2w6ICdzb2wnIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0gYXMgYW55LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHVzZXJQcnZCYXNlNjQgPSBCdWZmZXIuZnJvbSh1c2VyS2V5U2hhcmUpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICAgIC8vIFNob3VsZCBub3QgdGhyb3cg4oCUIGludGVudCBwcm92aWRlcyB0aGUgcmVjaXBpZW50c1xuICAgICAgYXdhaXQgdHNzVXRpbHMuc2lnblR4UmVxdWVzdCh7XG4gICAgICAgIHR4UmVxdWVzdDogaW50ZW50UmVjaXBpZW50VHhSZXF1ZXN0LFxuICAgICAgICBwcnY6IHVzZXJQcnZCYXNlNjQsXG4gICAgICAgIHJlcUlkLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnZG9lcyBub3QgdGhyb3cgZm9yIHN0YWtpbmcgaW50ZW50IHdpdGggc3Rha2luZ1JlcXVlc3RJZCAoZ2VuZXJpYyBzdGFraW5nIHNpZ25hbCknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBzYW5kYm94LnN0dWIoYmFzZUNvaW4sICd2ZXJpZnlUcmFuc2FjdGlvbicpLnJlc29sdmVzKHRydWUpO1xuICAgICAgY29uc3Qgbm9ja1Byb21pc2VzID0gYXdhaXQgZ2V0Tm9ja1Byb21pc2VzRm9yRWRkc2FTaWduaW5nKHR4UmVxdWVzdCk7XG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChub2NrUHJvbWlzZXMpO1xuXG4gICAgICBjb25zdCBzdGFraW5nVHhSZXF1ZXN0OiBUeFJlcXVlc3QgPSB7XG4gICAgICAgIC4uLnR4UmVxdWVzdCxcbiAgICAgICAgaW50ZW50OiB7XG4gICAgICAgICAgaW50ZW50VHlwZTogJ2RlbGVnYXRlJyxcbiAgICAgICAgICBzdGFraW5nUmVxdWVzdElkOiAnc3Rha2luZy1yZXEtaWQtMTIzJyxcbiAgICAgICAgfSBhcyBhbnksXG4gICAgICB9O1xuICAgICAgY29uc3QgdXNlclBydkJhc2U2NCA9IEJ1ZmZlci5mcm9tKHVzZXJLZXlTaGFyZSkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgICAgYXdhaXQgdHNzVXRpbHMuc2lnblR4UmVxdWVzdCh7XG4gICAgICAgIHR4UmVxdWVzdDogc3Rha2luZ1R4UmVxdWVzdCxcbiAgICAgICAgcHJ2OiB1c2VyUHJ2QmFzZTY0LFxuICAgICAgICByZXFJZCxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBhc3luYyBmdW5jdGlvbiBnZXROb2NrUHJvbWlzZXNGb3JFZGRzYVNpZ25pbmcoXG4gICAgdHhSZXF1ZXN0OiBUeFJlcXVlc3QsXG4gICAgcmVxdWVzdFR5cGU6IFJlcXVlc3RUeXBlID0gUmVxdWVzdFR5cGUudHgsXG4gICAgcmF0ZUxpbWl0RXJyb3JDb3VudCA9IDAsXG4gICAgc2lnbmVyUGFydHlJZDogRUNEU0FVdGlscy5NUEN2MlBhcnRpZXNFbnVtID0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSLFxuICAgIHJhdGVMaW1pdFJvdW5kID0gMixcbiAgICBtYWxmb3JtZWRSb3VuZDNSZXNwb25zZSA9IGZhbHNlXG4gICk6IFByb21pc2U8bm9jay5TY29wZVtdPiB7XG4gICAgY29uc3QgdHhPck1lc3NhZ2VUb1NpZ24gPVxuICAgICAgcmVxdWVzdFR5cGUgPT09IFJlcXVlc3RUeXBlLm1lc3NhZ2VcbiAgICAgICAgPyB0eFJlcXVlc3QubWVzc2FnZXMhWzBdLm1lc3NhZ2VFbmNvZGVkIVxuICAgICAgICA6IHR4UmVxdWVzdC50cmFuc2FjdGlvbnMhWzBdLnVuc2lnbmVkVHguc2lnbmFibGVIZXg7XG4gICAgY29uc3QgbWVzc2FnZUJ1ZmZlciA9IEJ1ZmZlci5mcm9tKHR4T3JNZXNzYWdlVG9TaWduLCAnaGV4Jyk7XG4gICAgY29uc3QgYml0Z29TZXNzaW9uID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBhd2FpdCBiaXRnb1Nlc3Npb24uaW5pdERzZyhcbiAgICAgIGJpdGdvS2V5U2hhcmUsXG4gICAgICBtZXNzYWdlQnVmZmVyLFxuICAgICAgdHhSZXF1ZXN0LnRyYW5zYWN0aW9ucz8uWzBdLnVuc2lnbmVkVHguZGVyaXZhdGlvblBhdGggfHwgJ20vMCcsXG4gICAgICBzaWduZXJQYXJ0eUlkXG4gICAgKTtcbiAgICBjb25zdCBiaXRnb01zZzEgPSBiaXRnb1Nlc3Npb24uZ2V0Rmlyc3RNZXNzYWdlKCk7XG4gICAgbGV0IGJpdGdvTXNnMjogTVBTVHlwZXMuRGVzZXJpYWxpemVkTWVzc2FnZSB8IHVuZGVmaW5lZDtcblxuICAgIHJldHVybiBbXG4gICAgICBhd2FpdCBub2NrVHhSZXF1ZXN0UmVzcG9uc2VTaWduYXR1cmVTaGFyZVJvdW5kT25lKFxuICAgICAgICBiaXRnb1Nlc3Npb24sXG4gICAgICAgIHR4UmVxdWVzdCxcbiAgICAgICAgYml0Z29Nc2cxLFxuICAgICAgICBiaXRnb1BydktleU9iaixcbiAgICAgICAgKG1zZykgPT4ge1xuICAgICAgICAgIGJpdGdvTXNnMiA9IG1zZztcbiAgICAgICAgfSxcbiAgICAgICAgcmVxdWVzdFR5cGUsXG4gICAgICAgIHNpZ25lclBhcnR5SWQsXG4gICAgICAgIHJhdGVMaW1pdFJvdW5kID09PSAxID8gcmF0ZUxpbWl0RXJyb3JDb3VudCA6IDBcbiAgICAgICksXG4gICAgICBhd2FpdCBub2NrVHhSZXF1ZXN0UmVzcG9uc2VTaWduYXR1cmVTaGFyZVJvdW5kVHdvKFxuICAgICAgICB0eFJlcXVlc3QsXG4gICAgICAgICgpID0+IGJpdGdvTXNnMiEsXG4gICAgICAgIGJpdGdvUHJ2S2V5T2JqLFxuICAgICAgICByZXF1ZXN0VHlwZSxcbiAgICAgICAgcmF0ZUxpbWl0Um91bmQgPT09IDIgPyByYXRlTGltaXRFcnJvckNvdW50IDogMCxcbiAgICAgICAgc2lnbmVyUGFydHlJZFxuICAgICAgKSxcbiAgICAgIGF3YWl0IG5vY2tUeFJlcXVlc3RSZXNwb25zZVNpZ25hdHVyZVNoYXJlUm91bmRUaHJlZShcbiAgICAgICAgdHhSZXF1ZXN0LFxuICAgICAgICByZXF1ZXN0VHlwZSxcbiAgICAgICAgc2lnbmVyUGFydHlJZCxcbiAgICAgICAgcmF0ZUxpbWl0Um91bmQgPT09IDMgPyByYXRlTGltaXRFcnJvckNvdW50IDogMCxcbiAgICAgICAgbWFsZm9ybWVkUm91bmQzUmVzcG9uc2VcbiAgICAgICksXG4gICAgICBhd2FpdCBub2NrU2VuZFR4UmVxdWVzdCh0eFJlcXVlc3QsIHJlcXVlc3RUeXBlKSxcbiAgICBdO1xuICB9XG59KTtcblxuYXN5bmMgZnVuY3Rpb24gbm9ja0dldEJpdGdvUHVibGljS2V5QmFzZWRPbkZlYXR1cmVGbGFncyhcbiAgY29pbjogc3RyaW5nLFxuICBlbnRlcnByaXNlSWQ6IHN0cmluZyxcbiAgYml0Z29HcGdLZXlQYWlyOiBvcGVucGdwLlNlcmlhbGl6ZWRLZXlQYWlyPHN0cmluZz5cbik6IFByb21pc2U8Qml0Z29HUEdQdWJsaWNLZXk+IHtcbiAgY29uc3QgYml0Z29HUEdQdWJsaWNLZXlSZXNwb25zZTogQml0Z29HUEdQdWJsaWNLZXkgPSB7XG4gICAgbmFtZTogJ2lycmVsZXZhbnQnLFxuICAgIHB1YmxpY0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICBtcGN2MlB1YmxpY0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICBlZGRzYU1wY3YyUHVibGljS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgIGVudGVycHJpc2VJZCxcbiAgfTtcbiAgbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAuZ2V0KGAvYXBpL3YyLyR7Y29pbn0vdHNzL3B1YmtleWApXG4gICAgLnRpbWVzKDQpXG4gICAgLnF1ZXJ5KHsgZW50ZXJwcmlzZUlkIH0pXG4gICAgLnJlcGx5KDIwMCwgYml0Z29HUEdQdWJsaWNLZXlSZXNwb25zZSk7XG4gIHJldHVybiBiaXRnb0dQR1B1YmxpY0tleVJlc3BvbnNlO1xufVxuXG5hc3luYyBmdW5jdGlvbiBub2NrVHhSZXF1ZXN0UmVzcG9uc2VTaWduYXR1cmVTaGFyZVJvdW5kT25lKFxuICBiaXRnb1Nlc3Npb246IEVkZHNhTVBTRHNnLkRTRyxcbiAgdHhSZXF1ZXN0OiBUeFJlcXVlc3QsXG4gIGJpdGdvTXNnMTogTVBTVHlwZXMuRGVzZXJpYWxpemVkTWVzc2FnZSxcbiAgYml0Z29HcGdQcml2S2V5OiBvcGVucGdwLlByaXZhdGVLZXksXG4gIHNhdmVCaXRnb01zZzI6IChtc2c6IE1QU1R5cGVzLkRlc2VyaWFsaXplZE1lc3NhZ2UpID0+IHZvaWQsXG4gIHJlcXVlc3RUeXBlOiBSZXF1ZXN0VHlwZSA9IFJlcXVlc3RUeXBlLnR4LFxuICBzaWduZXJQYXJ0eUlkOiBFQ0RTQVV0aWxzLk1QQ3YyUGFydGllc0VudW0gPSBNUEN2MlBhcnRpZXNFbnVtLlVTRVIsXG4gIHJhdGVMaW1pdEVycm9yQ291bnQgPSAwXG4pOiBQcm9taXNlPG5vY2suU2NvcGU+IHtcbiAgY29uc3Qgcm91dGUgPSByZXF1ZXN0VHlwZSA9PT0gUmVxdWVzdFR5cGUubWVzc2FnZSA/ICcvbWVzc2FnZXMvMCcgOiAnL3RyYW5zYWN0aW9ucy8wJztcbiAgY29uc3Qgc2lnbmVyU2hhcmVUeXBlID0gc2lnbmVyUGFydHlJZCA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSID8gU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIgOiBTaWduYXR1cmVTaGFyZVR5cGUuQkFDS1VQO1xuICBjb25zdCBzY29wZSA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpO1xuXG4gIGlmIChyYXRlTGltaXRFcnJvckNvdW50ID4gMCkge1xuICAgIHNjb3BlXG4gICAgICAucG9zdChcbiAgICAgICAgYC9hcGkvdjIvd2FsbGV0LyR7dHhSZXF1ZXN0LndhbGxldElkfS90eHJlcXVlc3RzLyR7dHhSZXF1ZXN0LnR4UmVxdWVzdElkfSR7cm91dGV9L3NpZ25gLFxuICAgICAgICAoYm9keSkgPT5cbiAgICAgICAgICAoSlNPTi5wYXJzZShib2R5LnNpZ25hdHVyZVNoYXJlc1swXS5zaGFyZSkgYXMgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxSW5wdXQpLnR5cGUgPT09ICdyb3VuZDFJbnB1dCdcbiAgICAgIClcbiAgICAgIC50aW1lcyhyYXRlTGltaXRFcnJvckNvdW50KVxuICAgICAgLnJlcGx5KDQyOSwge1xuICAgICAgICBlcnJvcjogJ1RvbyBtYW55IHJlcXVlc3RzLCBzbG93IGRvd24hJyxcbiAgICAgICAgbmFtZTogJ1Rvb01hbnlSZXF1ZXN0cycsXG4gICAgICAgIHJlcXVlc3RJZDogJ2NtNXF4MDFsaDAwMTNiMmVrMnN4bDR3MDAnLFxuICAgICAgICBjb250ZXh0OiB7fSxcbiAgICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHNjb3BlXG4gICAgLnBvc3QoXG4gICAgICBgL2FwaS92Mi93YWxsZXQvJHt0eFJlcXVlc3Qud2FsbGV0SWR9L3R4cmVxdWVzdHMvJHt0eFJlcXVlc3QudHhSZXF1ZXN0SWR9JHtyb3V0ZX0vc2lnbmAsXG4gICAgICAoYm9keSkgPT5cbiAgICAgICAgKEpTT04ucGFyc2UoYm9keS5zaWduYXR1cmVTaGFyZXNbMF0uc2hhcmUpIGFzIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMUlucHV0KS50eXBlID09PSAncm91bmQxSW5wdXQnXG4gICAgKVxuICAgIC5yZXBseSgyMDAsIGFzeW5jIChfdXJpOiBzdHJpbmcsIGJvZHk6IFNpZ25hdHVyZVNoYXJlQXBpQm9keSkgPT4ge1xuICAgICAgY29uc3QgcGFyc2VkU2hhcmUgPSBKU09OLnBhcnNlKGJvZHkuc2lnbmF0dXJlU2hhcmVzWzBdLnNoYXJlKSBhcyBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFJbnB1dDtcbiAgICAgIGNvbnN0IHVzZXJNc2cxQnl0ZXMgPSBCdWZmZXIuZnJvbShwYXJzZWRTaGFyZS5kYXRhLm1zZzEubWVzc2FnZSwgJ2Jhc2U2NCcpO1xuICAgICAgY29uc3QgdXNlckRlc2VyaWFsaXplZE1zZzE6IE1QU1R5cGVzLkRlc2VyaWFsaXplZE1lc3NhZ2UgPSB7XG4gICAgICAgIGZyb206IHNpZ25lclBhcnR5SWQsXG4gICAgICAgIHBheWxvYWQ6IG5ldyBVaW50OEFycmF5KHVzZXJNc2cxQnl0ZXMpLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IFtiaXRnb01zZzJdID0gYml0Z29TZXNzaW9uLmhhbmRsZUluY29taW5nTWVzc2FnZXMoW2JpdGdvTXNnMSwgdXNlckRlc2VyaWFsaXplZE1zZzFdKTtcbiAgICAgIHNhdmVCaXRnb01zZzIoYml0Z29Nc2cyKTtcblxuICAgICAgY29uc3QgYml0Z29TaWduZWRNc2cxID0gYXdhaXQgTVBTQ29tbXMuZGV0YWNoU2lnbk1wc01lc3NhZ2UoQnVmZmVyLmZyb20oYml0Z29Nc2cxLnBheWxvYWQpLCBiaXRnb0dwZ1ByaXZLZXkpO1xuICAgICAgY29uc3Qgcm91bmQxT3V0cHV0OiBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFPdXRwdXQgPSB7XG4gICAgICAgIHR5cGU6ICdyb3VuZDFPdXRwdXQnLFxuICAgICAgICBkYXRhOiB7IG1zZzE6IGJpdGdvU2lnbmVkTXNnMSB9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlc291cmNlID0gcmVxdWVzdFR5cGUgPT09IFJlcXVlc3RUeXBlLm1lc3NhZ2UgPyAnbWVzc2FnZXMnIDogJ3RyYW5zYWN0aW9ucyc7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eFJlcXVlc3RJZDogdHhSZXF1ZXN0LnR4UmVxdWVzdElkLFxuICAgICAgICBbcmVzb3VyY2VdOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgICAgICAgICAgICAgdG86IHNpZ25lclNoYXJlVHlwZSxcbiAgICAgICAgICAgICAgICBzaGFyZTogSlNPTi5zdHJpbmdpZnkocm91bmQxT3V0cHV0KSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIG5vY2tUeFJlcXVlc3RSZXNwb25zZVNpZ25hdHVyZVNoYXJlUm91bmRUd28oXG4gIHR4UmVxdWVzdDogVHhSZXF1ZXN0LFxuICBnZXRCaXRnb01zZzI6ICgpID0+IE1QU1R5cGVzLkRlc2VyaWFsaXplZE1lc3NhZ2UsXG4gIGJpdGdvR3BnUHJpdktleTogb3BlbnBncC5Qcml2YXRlS2V5LFxuICByZXF1ZXN0VHlwZTogUmVxdWVzdFR5cGUgPSBSZXF1ZXN0VHlwZS50eCxcbiAgcmF0ZUxpbWl0RXJyb3JDb3VudCA9IDAsXG4gIHNpZ25lclBhcnR5SWQ6IEVDRFNBVXRpbHMuTVBDdjJQYXJ0aWVzRW51bSA9IE1QQ3YyUGFydGllc0VudW0uVVNFUlxuKTogUHJvbWlzZTxub2NrLlNjb3BlPiB7XG4gIGNvbnN0IHJvdXRlID0gcmVxdWVzdFR5cGUgPT09IFJlcXVlc3RUeXBlLm1lc3NhZ2UgPyAnL21lc3NhZ2VzLzAnIDogJy90cmFuc2FjdGlvbnMvMCc7XG4gIGNvbnN0IHNjb3BlID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJyk7XG4gIGNvbnN0IHNpZ25lclNoYXJlVHlwZSA9IHNpZ25lclBhcnR5SWQgPT09IE1QQ3YyUGFydGllc0VudW0uVVNFUiA/IFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSIDogU2lnbmF0dXJlU2hhcmVUeXBlLkJBQ0tVUDtcblxuICBpZiAocmF0ZUxpbWl0RXJyb3JDb3VudCA+IDApIHtcbiAgICBzY29wZVxuICAgICAgLnBvc3QoXG4gICAgICAgIGAvYXBpL3YyL3dhbGxldC8ke3R4UmVxdWVzdC53YWxsZXRJZH0vdHhyZXF1ZXN0cy8ke3R4UmVxdWVzdC50eFJlcXVlc3RJZH0ke3JvdXRlfS9zaWduYCxcbiAgICAgICAgKGJvZHkpID0+XG4gICAgICAgICAgKEpTT04ucGFyc2UoYm9keS5zaWduYXR1cmVTaGFyZXNbMF0uc2hhcmUpIGFzIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMklucHV0KS50eXBlID09PSAncm91bmQySW5wdXQnXG4gICAgICApXG4gICAgICAudGltZXMocmF0ZUxpbWl0RXJyb3JDb3VudClcbiAgICAgIC5yZXBseSg0MjksIHtcbiAgICAgICAgZXJyb3I6ICdUb28gbWFueSByZXF1ZXN0cywgc2xvdyBkb3duIScsXG4gICAgICAgIG5hbWU6ICdUb29NYW55UmVxdWVzdHMnLFxuICAgICAgICByZXF1ZXN0SWQ6ICdjbTVxeDAxbGgwMDEzYjJlazJzeGw0dzAwJyxcbiAgICAgICAgY29udGV4dDoge30sXG4gICAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBzY29wZVxuICAgIC5wb3N0KFxuICAgICAgYC9hcGkvdjIvd2FsbGV0LyR7dHhSZXF1ZXN0LndhbGxldElkfS90eHJlcXVlc3RzLyR7dHhSZXF1ZXN0LnR4UmVxdWVzdElkfSR7cm91dGV9L3NpZ25gLFxuICAgICAgKGJvZHkpID0+XG4gICAgICAgIChKU09OLnBhcnNlKGJvZHkuc2lnbmF0dXJlU2hhcmVzWzBdLnNoYXJlKSBhcyBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJJbnB1dCkudHlwZSA9PT0gJ3JvdW5kMklucHV0J1xuICAgIClcbiAgICAucmVwbHkoMjAwLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBiaXRnb01zZzIgPSBnZXRCaXRnb01zZzIoKTtcbiAgICAgIGNvbnN0IGJpdGdvU2lnbmVkTXNnMiA9IGF3YWl0IE1QU0NvbW1zLmRldGFjaFNpZ25NcHNNZXNzYWdlKEJ1ZmZlci5mcm9tKGJpdGdvTXNnMi5wYXlsb2FkKSwgYml0Z29HcGdQcml2S2V5KTtcbiAgICAgIGNvbnN0IHJvdW5kMk91dHB1dDogRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQyT3V0cHV0ID0ge1xuICAgICAgICB0eXBlOiAncm91bmQyT3V0cHV0JyxcbiAgICAgICAgZGF0YTogeyBtc2cyOiBiaXRnb1NpZ25lZE1zZzIgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXNvdXJjZSA9IHJlcXVlc3RUeXBlID09PSBSZXF1ZXN0VHlwZS5tZXNzYWdlID8gJ21lc3NhZ2VzJyA6ICd0cmFuc2FjdGlvbnMnO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHhSZXF1ZXN0SWQ6IHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgICAgW3Jlc291cmNlXTogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNpZ25hdHVyZVNoYXJlczogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZnJvbTogc2lnbmVyU2hhcmVUeXBlLFxuICAgICAgICAgICAgICAgIHRvOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgICAgICAgICAgICAgc2hhcmU6ICdwbGFjZWhvbGRlcicsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgICAgICAgICAgICAgdG86IHNpZ25lclNoYXJlVHlwZSxcbiAgICAgICAgICAgICAgICBzaGFyZTogSlNPTi5zdHJpbmdpZnkocm91bmQyT3V0cHV0KSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIG5vY2tUeFJlcXVlc3RSZXNwb25zZVNpZ25hdHVyZVNoYXJlUm91bmRUaHJlZShcbiAgdHhSZXF1ZXN0OiBUeFJlcXVlc3QsXG4gIHJlcXVlc3RUeXBlOiBSZXF1ZXN0VHlwZSA9IFJlcXVlc3RUeXBlLnR4LFxuICBzaWduZXJQYXJ0eUlkOiBFQ0RTQVV0aWxzLk1QQ3YyUGFydGllc0VudW0gPSBNUEN2MlBhcnRpZXNFbnVtLlVTRVIsXG4gIHJhdGVMaW1pdEVycm9yQ291bnQgPSAwLFxuICBtYWxmb3JtZWRSZXNwb25zZSA9IGZhbHNlXG4pOiBQcm9taXNlPG5vY2suU2NvcGU+IHtcbiAgY29uc3Qgcm91dGUgPSByZXF1ZXN0VHlwZSA9PT0gUmVxdWVzdFR5cGUubWVzc2FnZSA/ICcvbWVzc2FnZXMvMCcgOiAnL3RyYW5zYWN0aW9ucy8wJztcbiAgY29uc3Qgc2lnbmVyU2hhcmVUeXBlID0gc2lnbmVyUGFydHlJZCA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSID8gU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIgOiBTaWduYXR1cmVTaGFyZVR5cGUuQkFDS1VQO1xuICBjb25zdCBzY29wZSA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpO1xuXG4gIGlmIChyYXRlTGltaXRFcnJvckNvdW50ID4gMCkge1xuICAgIHNjb3BlXG4gICAgICAucG9zdChcbiAgICAgICAgYC9hcGkvdjIvd2FsbGV0LyR7dHhSZXF1ZXN0LndhbGxldElkfS90eHJlcXVlc3RzLyR7dHhSZXF1ZXN0LnR4UmVxdWVzdElkfSR7cm91dGV9L3NpZ25gLFxuICAgICAgICAoYm9keTogU2lnbmF0dXJlU2hhcmVBcGlCb2R5KSA9PlxuICAgICAgICAgIChKU09OLnBhcnNlKGJvZHkuc2lnbmF0dXJlU2hhcmVzWzBdLnNoYXJlKSBhcyBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDNJbnB1dCkudHlwZSA9PT0gJ3JvdW5kM0lucHV0J1xuICAgICAgKVxuICAgICAgLnRpbWVzKHJhdGVMaW1pdEVycm9yQ291bnQpXG4gICAgICAucmVwbHkoNDI5LCB7XG4gICAgICAgIGVycm9yOiAnVG9vIG1hbnkgcmVxdWVzdHMsIHNsb3cgZG93biEnLFxuICAgICAgICBuYW1lOiAnVG9vTWFueVJlcXVlc3RzJyxcbiAgICAgICAgcmVxdWVzdElkOiAnY201cXgwMWxoMDAxM2IyZWsyc3hsNHcwMCcsXG4gICAgICAgIGNvbnRleHQ6IHt9LFxuICAgICAgfSk7XG4gIH1cblxuICByZXR1cm4gc2NvcGVcbiAgICAucG9zdChcbiAgICAgIGAvYXBpL3YyL3dhbGxldC8ke3R4UmVxdWVzdC53YWxsZXRJZH0vdHhyZXF1ZXN0cy8ke3R4UmVxdWVzdC50eFJlcXVlc3RJZH0ke3JvdXRlfS9zaWduYCxcbiAgICAgIChib2R5OiBTaWduYXR1cmVTaGFyZUFwaUJvZHkpID0+XG4gICAgICAgIChKU09OLnBhcnNlKGJvZHkuc2lnbmF0dXJlU2hhcmVzWzBdLnNoYXJlKSBhcyBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDNJbnB1dCkudHlwZSA9PT0gJ3JvdW5kM0lucHV0J1xuICAgIClcbiAgICAucmVwbHkoXG4gICAgICAyMDAsXG4gICAgICBtYWxmb3JtZWRSZXNwb25zZVxuICAgICAgICA/IHsgdHhSZXF1ZXN0SWQ6IGAke3R4UmVxdWVzdC50eFJlcXVlc3RJZH0tdW5leHBlY3RlZGAgfVxuICAgICAgICA6IHtcbiAgICAgICAgICAgIHR4UmVxdWVzdElkOiB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsXG4gICAgICAgICAgICBzaWduYXR1cmVTaGFyZXM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGZyb206IHNpZ25lclNoYXJlVHlwZSxcbiAgICAgICAgICAgICAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPLFxuICAgICAgICAgICAgICAgIHNoYXJlOiAncGxhY2Vob2xkZXInLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9XG4gICAgKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gbm9ja1NlbmRUeFJlcXVlc3QodHhSZXF1ZXN0OiBUeFJlcXVlc3QsIHJlcXVlc3RUeXBlOiBSZXF1ZXN0VHlwZSA9IFJlcXVlc3RUeXBlLnR4KTogUHJvbWlzZTxub2NrLlNjb3BlPiB7XG4gIGNvbnN0IHJvdXRlID0gcmVxdWVzdFR5cGUgPT09IFJlcXVlc3RUeXBlLm1lc3NhZ2UgPyAnL21lc3NhZ2VzLzAnIDogJy90cmFuc2FjdGlvbnMvMCc7XG4gIHJldHVybiBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgIC5wb3N0KGAvYXBpL3YyL3dhbGxldC8ke3R4UmVxdWVzdC53YWxsZXRJZH0vdHhyZXF1ZXN0cy8ke3R4UmVxdWVzdC50eFJlcXVlc3RJZH0ke3JvdXRlfS9zZW5kYClcbiAgICAucmVwbHkoMjAwLCB7XG4gICAgICB0eFJlcXVlc3RJZDogdHhSZXF1ZXN0LnR4UmVxdWVzdElkLFxuICAgIH0pO1xufVxuIl19