UNPKG

bitgo

Version:
308 lines • 46.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * @prettier */ require("should"); const nock = require("nock"); 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"); describe('Pending Approvals:', () => { let sandbox; let bitgo; let basecoin; let wallet; let bgUrl; const coin = 'tbtc'; const walletId = 'wallet_id'; const pendingApprovalData = { id: 'pa0', info: { type: sdk_core_1.Type.TRANSACTION_REQUEST, transactionRequest: { coinSpecific: { [coin]: {}, }, recipients: [], buildParams: { type: 'consolidate', }, sourceWallet: walletId, }, }, state: sdk_core_1.State.PENDING, creator: 'test', }; const walletData = { id: walletId, coin, pendingApprovals: [pendingApprovalData], }; beforeEach(function () { sandbox = sinon.createSandbox(); nock.disableNetConnect(); }); afterEach(function () { sandbox.restore(); }); before(async () => { // create wallet bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' }); bitgo.initializeTestVars(); basecoin = bitgo.coin(coin); wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData); bgUrl = sdk_core_1.Environments[bitgo.getEnv()].uri; pendingApprovalData.wallet = wallet; }); ['tsol', 'teth', 'tbtc'].forEach((coinName) => { it(`should use correct tssUtils for ${coinName}`, () => { const coin = bitgo.coin(coinName); const pendingAproval = new sdk_core_1.PendingApproval(bitgo, coin, {}); if (coin.supportsTss()) { if (coin.getMPCAlgorithm() === 'ecdsa') { pendingAproval['tssUtils'].should.be.instanceOf(sdk_core_1.ECDSAUtils.EcdsaUtils); } else if (coin.getMPCAlgorithm() === 'eddsa') { pendingAproval['tssUtils'].should.be.instanceOf(sdk_core_1.EddsaUtils); } } else { (pendingAproval['tssUtils'] === undefined).should.be.true(); } }); }); ['MPCv2', undefined].forEach((multisigTypeVersion) => { it(`should use correct tssUtils for multisigTypeVersion: ${multisigTypeVersion}`, () => { const coin = bitgo.coin('hteth'); const walletDataMpcV2 = { ...walletData, multisigTypeVersion: multisigTypeVersion, }; const walletMPCv2 = new sdk_core_1.Wallet(bitgo, basecoin, walletDataMpcV2); const pendingAproval = new sdk_core_1.PendingApproval(bitgo, coin, {}, walletMPCv2); if (walletMPCv2.multisigTypeVersion() === 'MPCv2') { pendingAproval['tssUtils'].should.be.instanceOf(sdk_core_1.ECDSAUtils.EcdsaMPCv2Utils); } else { pendingAproval['tssUtils'].should.be.instanceOf(sdk_core_1.ECDSAUtils.EcdsaUtils); } }); }); it('should call consolidate instead of build when rebuilding consolidation pending approvals', async () => { const scope = nock(bgUrl).post(`/api/v2/${coin}/wallet/${walletId}/consolidateUnspents`).reply(200); const pendingApprovals = wallet.pendingApprovals(); pendingApprovals.should.have.length(1); const pendingApproval = pendingApprovals[0]; // approval will fail when attempting to resign. This is ok - we just want to make sure // the consolidateUnspents endpoint was called already before failing await pendingApproval.approve({ xprv: 'nonsense' }).should.be.rejected(); scope.done(); }); it('should approve for transactionRequestLite if we cannot recreate transaction', async () => { const pendingApprovalData2 = { ...pendingApprovalData, txRequestId: '1234-4567-6789' }; const pendingApproval = new sdk_core_1.PendingApproval(bitgo, basecoin, pendingApprovalData2, wallet); const paScope = nock(bgUrl) .put(`/api/v2/${coin}/pendingapprovals/${pendingApprovalData.id}`, { state: 'approved', otp: undefined, }) .reply(200, { ...pendingApprovalData2, state: 'approved', }); const recreateTransactionTssStub = sandbox.stub(sdk_core_1.PendingApproval.prototype, 'recreateAndSignTSSTransaction'); const recreateTransactionStub = sandbox.stub(sdk_core_1.PendingApproval.prototype, 'recreateAndSignTransaction'); pendingApproval.type().should.equal(sdk_core_1.Type.TRANSACTION_REQUEST); await pendingApproval.approve({}); recreateTransactionTssStub.notCalled.should.be.true(); recreateTransactionStub.notCalled.should.be.true(); paScope.isDone().should.be.true(); }); function testRecreateTransaction(coinName, recreateTransaction, type) { it(`[${coinName}] should ${recreateTransaction ? 'not ' : ''}recreate the transaction during approving a pending approval if there are no recipients for PA type ${type}`, async () => { const coin = bitgo.coin(coinName); const txRequestId = coin.supportsTss() ? 'requestTxIdTest' : undefined; const pendingApprovalInfo = type === 'transactionRequest' ? { type, transactionRequest: { coinSpecific: { [coinName]: { txHex: 'gabagool' }, }, recipients: [], buildParams: {}, sourceWallet: walletId, }, } : { type }; const pendingApprovalDataTemp = { id: 'pa0', info: pendingApprovalInfo, wallet: walletId, state: sdk_core_1.State.PENDING, creator: 'test', txRequestId, }; const walletDataTemp = { id: walletId, coinName, pendingApprovals: [pendingApprovalDataTemp], }; const walletTemp = new sdk_core_1.Wallet(bitgo, coin, walletDataTemp); pendingApprovalDataTemp.wallet = walletTemp.id(); const pendingApprovals = walletTemp.pendingApprovals(); pendingApprovals.should.have.length(1); const pendingApproval = pendingApprovals[0]; let stub; if (coin.supportsTss()) { stub = sandbox.stub(sdk_core_1.PendingApproval.prototype, 'recreateAndSignTSSTransaction').resolves({ txHex: 'gabagool', }); } else { stub = sandbox.stub(sdk_core_1.PendingApproval.prototype, 'recreateAndSignTransaction').resolves({ state: 'approved', halfSigned: { txHex: 'gabagool' }, }); } const paScope = nock(bgUrl) .put(`/api/v2/${coinName}/pendingapprovals/${pendingApprovalDataTemp.id}`, { state: 'approved', halfSigned: type === sdk_core_1.Type.TRANSACTION_REQUEST ? { txHex: 'gabagool' } : undefined, }) .reply(200, { ...pendingApprovalDataTemp, state: 'approved', }); await pendingApproval.approve({ xprv: 'nonsense', walletPassphrase: 'gabagoolio' }); // Should not call build and should call pa paScope.isDone().should.be.true(); stub.calledOnce.should.equal(recreateTransaction); }); } testRecreateTransaction('tbtc', false, sdk_core_1.Type.TRANSACTION_REQUEST); testRecreateTransaction('tsol', true, sdk_core_1.Type.TRANSACTION_REQUEST); testRecreateTransaction('tsol', true, sdk_core_1.Type.TRANSACTION_REQUEST_FULL); testRecreateTransaction('teth', true, sdk_core_1.Type.TRANSACTION_REQUEST_FULL); describe('recreateAndSignTSSTransaction', function () { let coin; before(() => { coin = bitgo.coin('tsol'); }); it('should call approve and do the TSS flow and fail if the txRequestId is missing', async () => { const pendingApproval = wallet.pendingApprovals()[0]; const reqId = new sdk_core_1.RequestTracer(); const params = { walletPassphrase: 'test' }; await pendingApproval .recreateAndSignTSSTransaction(params, reqId) .should.be.rejectedWith('txRequestId not found'); }); it('should call approve and do the TSS flow and fail if the walletPassphrase is missing', async () => { const pendingApproval = wallet.pendingApprovals()[0]; pendingApprovalData['txRequestId'] = 'requestTxIdTest'; const reqId = new sdk_core_1.RequestTracer(); const params = {}; await pendingApproval .recreateAndSignTSSTransaction(params, reqId) .should.be.rejectedWith('walletPassphrase not found'); }); it('should call approve and do the TSS flow and fail if the wallet is missing', async () => { const pendingApproval = new sdk_core_1.PendingApproval(bitgo, coin, pendingApprovalData); const reqId = new sdk_core_1.RequestTracer(); const params = { walletPassphrase: 'test' }; await pendingApproval.recreateAndSignTSSTransaction(params, reqId).should.be.rejectedWith('Wallet not found'); }); it('should get txHex for transactionRequestLite', async () => { pendingApprovalData['txRequestId'] = 'requestTxIdTest'; const pendingApproval = new sdk_core_1.PendingApproval(bitgo, coin, pendingApprovalData, wallet); const reqId = new sdk_core_1.RequestTracer(); const txRequestId = 'test'; const walletPassphrase = 'test'; const decryptedPrvResponse = 'decryptedPrv'; const params = { txRequestId, walletPassphrase }; const txRequest = { apiVersion: 'lite', txRequestId: txRequestId, unsignedTxs: [{ signableHex: 'randomhex', serializedTxHex: 'randomhex2', derivationPath: 'm/0' }], signatureShares: [ { from: sdk_core_1.SignatureShareType.BITGO, to: sdk_core_1.SignatureShareType.USER, share: '9d7159a76700635TEST', }, ], transactions: [], userId: 'userId', date: new Date().toISOString(), intent: { intentType: 'payment', }, latest: true, walletId: 'walletId', version: 1, policiesChecked: false, walletType: 'hot', state: 'pendingUserSignature', }; const decryptedPrv = sandbox.stub(sdk_core_1.Wallet.prototype, 'getPrv'); decryptedPrv.calledOnceWithExactly({ walletPassphrase }); decryptedPrv.resolves(decryptedPrvResponse); const recreateTxRequest = sandbox.stub(sdk_core_1.TssUtils.prototype, 'recreateTxRequest'); recreateTxRequest.calledOnceWithExactly(txRequest.txRequestId, decryptedPrvResponse, reqId); recreateTxRequest.resolves(txRequest); const recreatedTx = await pendingApproval.recreateAndSignTSSTransaction(params, reqId); recreatedTx.should.be.deepEqual({ txHex: txRequest.unsignedTxs[0].serializedTxHex }); sandbox.verify(); }); it('should get txHex for transactionRequestFull ', async () => { pendingApprovalData['txRequestId'] = 'requestTxIdTest'; const pendingApproval = new sdk_core_1.PendingApproval(bitgo, coin, pendingApprovalData, wallet); const reqId = new sdk_core_1.RequestTracer(); const txRequestId = 'test'; const walletPassphrase = 'test'; const decryptedPrvResponse = 'decryptedPrv'; const params = { txRequestId, walletPassphrase }; const txRequest = { txRequestId: txRequestId, apiVersion: 'full', unsignedTxs: [], transactions: [ { unsignedTx: { signableHex: 'randomhex', serializedTxHex: 'randomhex2', derivationPath: 'm/0' }, signatureShares: [ { from: sdk_core_1.SignatureShareType.BITGO, to: sdk_core_1.SignatureShareType.USER, share: '9d7159a76700635TEST', }, ], state: 'initialized', }, ], userId: 'userId', date: new Date().toISOString(), intent: { intentType: 'payment', }, latest: true, walletId: 'walletId', version: 1, policiesChecked: false, walletType: 'hot', state: 'pendingDelivery', }; const decryptedPrv = sandbox.stub(sdk_core_1.Wallet.prototype, 'getPrv'); decryptedPrv.calledOnceWithExactly({ walletPassphrase }); decryptedPrv.resolves(decryptedPrvResponse); const recreateTxRequest = sandbox.stub(sdk_core_1.TssUtils.prototype, 'recreateTxRequest'); recreateTxRequest.calledOnceWithExactly(txRequest.txRequestId, decryptedPrvResponse, reqId); recreateTxRequest.resolves(txRequest); const recreatedTx = await pendingApproval.recreateAndSignTSSTransaction(params, reqId); recreatedTx.should.be.deepEqual({ txHex: txRequest.transactions[0].unsignedTx.serializedTxHex }); sandbox.verify(); }); }); }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVuZGluZ0FwcHJvdmFsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC92Mi91bml0L3BlbmRpbmdBcHByb3ZhbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBOztHQUVHO0FBQ0gsa0JBQWdCO0FBQ2hCLDZCQUE4QjtBQUM5QiwrQkFBK0I7QUFDL0IsOENBQXdEO0FBQ3hELHNDQUFxQztBQUVyQyw4Q0FleUI7QUFFekIsUUFBUSxDQUFDLG9CQUFvQixFQUFFLEdBQUcsRUFBRTtJQUNsQyxJQUFJLE9BQTJCLENBQUM7SUFDaEMsSUFBSSxLQUF5QixDQUFDO0lBQzlCLElBQUksUUFBa0IsQ0FBQztJQUN2QixJQUFJLE1BQWMsQ0FBQztJQUNuQixJQUFJLEtBQWEsQ0FBQztJQUVsQixNQUFNLElBQUksR0FBRyxNQUFNLENBQUM7SUFDcEIsTUFBTSxRQUFRLEdBQUcsV0FBVyxDQUFDO0lBRTdCLE1BQU0sbUJBQW1CLEdBQXdCO1FBQy9DLEVBQUUsRUFBRSxLQUFLO1FBQ1QsSUFBSSxFQUFFO1lBQ0osSUFBSSxFQUFFLGVBQUksQ0FBQyxtQkFBbUI7WUFDOUIsa0JBQWtCLEVBQUU7Z0JBQ2xCLFlBQVksRUFBRTtvQkFDWixDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUU7aUJBQ1g7Z0JBQ0QsVUFBVSxFQUFFLEVBQUU7Z0JBQ2QsV0FBVyxFQUFFO29CQUNYLElBQUksRUFBRSxhQUFhO2lCQUNwQjtnQkFDRCxZQUFZLEVBQUUsUUFBUTthQUN2QjtTQUNGO1FBQ0QsS0FBSyxFQUFFLGdCQUFLLENBQUMsT0FBTztRQUNwQixPQUFPLEVBQUUsTUFBTTtLQUNoQixDQUFDO0lBQ0YsTUFBTSxVQUFVLEdBQUc7UUFDakIsRUFBRSxFQUFFLFFBQVE7UUFDWixJQUFJO1FBQ0osZ0JBQWdCLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQztLQUN4QyxDQUFDO0lBRUYsVUFBVSxDQUFDO1FBQ1QsT0FBTyxHQUFHLEtBQUssQ0FBQyxhQUFh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QUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsRUFBRSxLQUFLLEVBQUUsU0FBUyxDQUFDLFlBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQztZQUVsRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDbkIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAcHJldHRpZXJcbiAqL1xuaW1wb3J0ICdzaG91bGQnO1xuaW1wb3J0IG5vY2sgPSByZXF1aXJlKCdub2NrJyk7XG5pbXBvcnQgKiBhcyBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgeyBUZXN0YWJsZUJHLCBUZXN0Qml0R28gfSBmcm9tICdAYml0Z28vc2RrLXRlc3QnO1xuaW1wb3J0IHsgQml0R28gfSBmcm9tICcuLi8uLi8uLi9zcmMnO1xuXG5pbXBvcnQge1xuICBCYXNlQ29pbixcbiAgRUNEU0FVdGlscyxcbiAgRWRkc2FVdGlscyxcbiAgRW52aXJvbm1lbnRzLFxuICBQZW5kaW5nQXBwcm92YWwsXG4gIFBlbmRpbmdBcHByb3ZhbERhdGEsXG4gIFBlbmRpbmdBcHByb3ZhbEluZm8sXG4gIFJlcXVlc3RUcmFjZXIsXG4gIFNpZ25hdHVyZVNoYXJlVHlwZSxcbiAgU3RhdGUsXG4gIFRzc1V0aWxzLFxuICBUeFJlcXVlc3QsXG4gIFR5cGUsXG4gIFdhbGxldCxcbn0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcblxuZGVzY3JpYmUoJ1BlbmRpbmcgQXBwcm92YWxzOicsICgpID0+IHtcbiAgbGV0IHNhbmRib3g6IHNpbm9uLlNpbm9uU2FuZGJveDtcbiAgbGV0IGJpdGdvOiBUZXN0YWJsZUJHICYgQml0R287XG4gIGxldCBiYXNlY29pbjogQmFzZUNvaW47XG4gIGxldCB3YWxsZXQ6IFdhbGxldDtcbiAgbGV0IGJnVXJsOiBzdHJpbmc7XG5cbiAgY29uc3QgY29pbiA9ICd0YnRjJztcbiAgY29uc3Qgd2FsbGV0SWQgPSAnd2FsbGV0X2lkJztcblxuICBjb25zdCBwZW5kaW5nQXBwcm92YWxEYXRhOiBQZW5kaW5nQXBwcm92YWxEYXRhID0ge1xuICAgIGlkOiAncGEwJyxcbiAgICBpbmZvOiB7XG4gICAgICB0eXBlOiBUeXBlLlRSQU5TQUNUSU9OX1JFUVVFU1QsXG4gICAgICB0cmFuc2FjdGlvblJlcXVlc3Q6IHtcbiAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgW2NvaW5dOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAgcmVjaXBpZW50czogW10sXG4gICAgICAgIGJ1aWxkUGFyYW1zOiB7XG4gICAgICAgICAgdHlwZTogJ2NvbnNvbGlkYXRlJyxcbiAgICAgICAgfSxcbiAgICAgICAgc291cmNlV2FsbGV0OiB3YWxsZXRJZCxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBzdGF0ZTogU3RhdGUuUEVORElORyxcbiAgICBjcmVhdG9yOiAndGVzdCcsXG4gIH07XG4gIGNvbnN0IHdhbGxldERhdGEgPSB7XG4gICAgaWQ6IHdhbGxldElkLFxuICAgIGNvaW4sXG4gICAgcGVuZGluZ0FwcHJvdmFsczogW3BlbmRpbmdBcHByb3ZhbERhdGFdLFxuICB9O1xuXG4gIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgIHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gICAgbm9jay5kaXNhYmxlTmV0Q29ubmVjdCgpO1xuICB9KTtcblxuICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgIHNhbmRib3gucmVzdG9yZSgpO1xuICB9KTtcblxuICBiZWZvcmUoYXN5bmMgKCkgPT4ge1xuICAgIC8vIGNyZWF0ZSB3YWxsZXRcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICBiYXNlY29pbiA9IGJpdGdvLmNvaW4oY29pbik7XG5cbiAgICB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwgd2FsbGV0RGF0YSk7XG4gICAgYmdVcmwgPSBFbnZpcm9ubWVudHNbYml0Z28uZ2V0RW52KCldLnVyaTtcbiAgICAocGVuZGluZ0FwcHJvdmFsRGF0YSBhcyBhbnkpLndhbGxldCA9IHdhbGxldDtcbiAgfSk7XG5cbiAgWyd0c29sJywgJ3RldGgnLCAndGJ0YyddLmZvckVhY2goKGNvaW5OYW1lKSA9PiB7XG4gICAgaXQoYHNob3VsZCB1c2UgY29ycmVjdCB0c3NVdGlscyBmb3IgICR7Y29pbk5hbWV9YCwgKCkgPT4ge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oY29pbk5hbWUpO1xuICAgICAgY29uc3QgcGVuZGluZ0Fwcm92YWwgPSBuZXcgUGVuZGluZ0FwcHJvdmFsKGJpdGdvLCBjb2luLCB7fSBhcyB1bmtub3duIGFzIFBlbmRpbmdBcHByb3ZhbERhdGEpO1xuICAgICAgaWYgKGNvaW4uc3VwcG9ydHNUc3MoKSkge1xuICAgICAgICBpZiAoY29pbi5nZXRNUENBbGdvcml0aG0oKSA9PT0gJ2VjZHNhJykge1xuICAgICAgICAgIHBlbmRpbmdBcHJvdmFsWyd0c3NVdGlscyddLnNob3VsZC5iZS5pbnN0YW5jZU9mKEVDRFNBVXRpbHMuRWNkc2FVdGlscyk7XG4gICAgICAgIH0gZWxzZSBpZiAoY29pbi5nZXRNUENBbGdvcml0aG0oKSA9PT0gJ2VkZHNhJykge1xuICAgICAgICAgIHBlbmRpbmdBcHJvdmFsWyd0c3NVdGlscyddLnNob3VsZC5iZS5pbnN0YW5jZU9mKEVkZHNhVXRpbHMpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAocGVuZGluZ0Fwcm92YWxbJ3Rzc1V0aWxzJ10gPT09IHVuZGVmaW5lZCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgWydNUEN2MicsIHVuZGVmaW5lZF0uZm9yRWFjaCgobXVsdGlzaWdUeXBlVmVyc2lvbikgPT4ge1xuICAgIGl0KGBzaG91bGQgdXNlIGNvcnJlY3QgdHNzVXRpbHMgZm9yIG11bHRpc2lnVHlwZVZlcnNpb246ICR7bXVsdGlzaWdUeXBlVmVyc2lvbn1gLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKTtcbiAgICAgIGNvbnN0IHdhbGxldERhdGFNcGNWMiA9IHtcbiAgICAgICAgLi4ud2FsbGV0RGF0YSxcbiAgICAgICAgbXVsdGlzaWdUeXBlVmVyc2lvbjogbXVsdGlzaWdUeXBlVmVyc2lvbixcbiAgICAgIH07XG4gICAgICBjb25zdCB3YWxsZXRNUEN2MiA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB3YWxsZXREYXRhTXBjVjIpO1xuXG4gICAgICBjb25zdCBwZW5kaW5nQXByb3ZhbCA9IG5ldyBQZW5kaW5nQXBwcm92YWwoYml0Z28sIGNvaW4sIHt9IGFzIHVua25vd24gYXMgUGVuZGluZ0FwcHJvdmFsRGF0YSwgd2FsbGV0TVBDdjIpO1xuICAgICAgaWYgKHdhbGxldE1QQ3YyLm11bHRpc2lnVHlwZVZlcnNpb24oKSA9PT0gJ01QQ3YyJykge1xuICAgICAgICBwZW5kaW5nQXByb3ZhbFsndHNzVXRpbHMnXS5zaG91bGQuYmUuaW5zdGFuY2VPZihFQ0RTQVV0aWxzLkVjZHNhTVBDdjJVdGlscyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwZW5kaW5nQXByb3ZhbFsndHNzVXRpbHMnXS5zaG91bGQuYmUuaW5zdGFuY2VPZihFQ0RTQVV0aWxzLkVjZHNhVXRpbHMpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGNhbGwgY29uc29saWRhdGUgaW5zdGVhZCBvZiBidWlsZCB3aGVuIHJlYnVpbGRpbmcgY29uc29saWRhdGlvbiBwZW5kaW5nIGFwcHJvdmFscycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpLnBvc3QoYC9hcGkvdjIvJHtjb2lufS93YWxsZXQvJHt3YWxsZXRJZH0vY29uc29saWRhdGVVbnNwZW50c2ApLnJlcGx5KDIwMCk7XG4gICAgY29uc3QgcGVuZGluZ0FwcHJvdmFscyA9IHdhbGxldC5wZW5kaW5nQXBwcm92YWxzKCk7XG4gICAgcGVuZGluZ0FwcHJvdmFscy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgY29uc3QgcGVuZGluZ0FwcHJvdmFsID0gcGVuZGluZ0FwcHJvdmFsc1swXTtcblxuICAgIC8vIGFwcHJvdmFsIHdpbGwgZmFpbCB3aGVuIGF0dGVtcHRpbmcgdG8gcmVzaWduLiBUaGlzIGlzIG9rIC0gd2UganVzdCB3YW50IHRvIG1ha2Ugc3VyZVxuICAgIC8vIHRoZSBjb25zb2xpZGF0ZVVuc3BlbnRzIGVuZHBvaW50IHdhcyBjYWxsZWQgYWxyZWFkeSBiZWZvcmUgZmFpbGluZ1xuICAgIGF3YWl0IHBlbmRpbmdBcHByb3ZhbC5hcHByb3ZlKHsgeHBydjogJ25vbnNlbnNlJyB9KS5zaG91bGQuYmUucmVqZWN0ZWQoKTtcblxuICAgIHNjb3BlLmRvbmUoKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBhcHByb3ZlIGZvciB0cmFuc2FjdGlvblJlcXVlc3RMaXRlIGlmIHdlIGNhbm5vdCByZWNyZWF0ZSB0cmFuc2FjdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBwZW5kaW5nQXBwcm92YWxEYXRhMiA9IHsgLi4ucGVuZGluZ0FwcHJvdmFsRGF0YSwgdHhSZXF1ZXN0SWQ6ICcxMjM0LTQ1NjctNjc4OScgfTtcbiAgICBjb25zdCBwZW5kaW5nQXBwcm92YWwgPSBuZXcgUGVuZGluZ0FwcHJvdmFsKGJpdGdvLCBiYXNlY29pbiwgcGVuZGluZ0FwcHJvdmFsRGF0YTIsIHdhbGxldCk7XG5cbiAgICBjb25zdCBwYVNjb3BlID0gbm9jayhiZ1VybClcbiAgICAgIC5wdXQoYC9hcGkvdjIvJHtjb2lufS9wZW5kaW5nYXBwcm92YWxzLyR7cGVuZGluZ0FwcHJvdmFsRGF0YS5pZH1gLCB7XG4gICAgICAgIHN0YXRlOiAnYXBwcm92ZWQnLFxuICAgICAgICBvdHA6IHVuZGVmaW5lZCxcbiAgICAgIH0pXG4gICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgIC4uLnBlbmRpbmdBcHByb3ZhbERhdGEyLFxuICAgICAgICBzdGF0ZTogJ2FwcHJvdmVkJyxcbiAgICAgIH0pO1xuICAgIGNvbnN0IHJlY3JlYXRlVHJhbnNhY3Rpb25Uc3NTdHViID0gc2FuZGJveC5zdHViKFBlbmRpbmdBcHByb3ZhbC5wcm90b3R5cGUsICdyZWNyZWF0ZUFuZFNpZ25UU1NUcmFuc2FjdGlvbicpO1xuICAgIGNvbnN0IHJlY3JlYXRlVHJhbnNhY3Rpb25TdHViID0gc2FuZGJveC5zdHViKFBlbmRpbmdBcHByb3ZhbC5wcm90b3R5cGUsICdyZWNyZWF0ZUFuZFNpZ25UcmFuc2FjdGlvbicpO1xuXG4gICAgcGVuZGluZ0FwcHJvdmFsLnR5cGUoKS5zaG91bGQuZXF1YWwoVHlwZS5UUkFOU0FDVElPTl9SRVFVRVNUKTtcbiAgICBhd2FpdCBwZW5kaW5nQXBwcm92YWwuYXBwcm92ZSh7fSk7XG4gICAgcmVjcmVhdGVUcmFuc2FjdGlvblRzc1N0dWIubm90Q2FsbGVkLnNob3VsZC5iZS50cnVlKCk7XG4gICAgcmVjcmVhdGVUcmFuc2FjdGlvblN0dWIubm90Q2FsbGVkLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICBwYVNjb3BlLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gIH0pO1xuXG4gIGZ1bmN0aW9uIHRlc3RSZWNyZWF0ZVRyYW5zYWN0aW9uKGNvaW5OYW1lOiBzdHJpbmcsIHJlY3JlYXRlVHJhbnNhY3Rpb246IGJvb2xlYW4sIHR5cGU6IFR5cGUpIHtcbiAgICBpdChgWyR7Y29pbk5hbWV9XSBzaG91bGQgJHtcbiAgICAgIHJlY3JlYXRlVHJhbnNhY3Rpb24gPyAnbm90ICcgOiAnJ1xuICAgIH1yZWNyZWF0ZSB0aGUgdHJhbnNhY3Rpb24gZHVyaW5nIGFwcHJvdmluZyBhIHBlbmRpbmcgYXBwcm92YWwgaWYgdGhlcmUgYXJlIG5vIHJlY2lwaWVudHMgZm9yIFBBIHR5cGUgJHt0eXBlfWAsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKGNvaW5OYW1lKTtcbiAgICAgIGNvbnN0IHR4UmVxdWVzdElkID0gY29pbi5zdXBwb3J0c1RzcygpID8gJ3JlcXVlc3RUeElkVGVzdCcgOiB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBwZW5kaW5nQXBwcm92YWxJbmZvID1cbiAgICAgICAgdHlwZSA9PT0gJ3RyYW5zYWN0aW9uUmVxdWVzdCdcbiAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgICAgdHJhbnNhY3Rpb25SZXF1ZXN0OiB7XG4gICAgICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgICAgICBbY29pbk5hbWVdOiB7IHR4SGV4OiAnZ2FiYWdvb2wnIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWNpcGllbnRzOiBbXSxcbiAgICAgICAgICAgICAgICBidWlsZFBhcmFtczoge30sXG4gICAgICAgICAgICAgICAgc291cmNlV2FsbGV0OiB3YWxsZXRJZCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICA6ICh7IHR5cGUgfSBhcyB1bmtub3duIGFzIFBlbmRpbmdBcHByb3ZhbEluZm8pO1xuICAgICAgY29uc3QgcGVuZGluZ0FwcHJvdmFsRGF0YVRlbXA6IFBlbmRpbmdBcHByb3ZhbERhdGEgPSB7XG4gICAgICAgIGlkOiAncGEwJyxcbiAgICAgICAgaW5mbzogcGVuZGluZ0FwcHJvdmFsSW5mbyxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXRJZCxcbiAgICAgICAgc3RhdGU6IFN0YXRlLlBFTkRJTkcsXG4gICAgICAgIGNyZWF0b3I6ICd0ZXN0JyxcbiAgICAgICAgdHhSZXF1ZXN0SWQsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB3YWxsZXREYXRhVGVtcCA9IHtcbiAgICAgICAgaWQ6IHdhbGxldElkLFxuICAgICAgICBjb2luTmFtZSxcbiAgICAgICAgcGVuZGluZ0FwcHJvdmFsczogW3BlbmRpbmdBcHByb3ZhbERhdGFUZW1wXSxcbiAgICAgIH07XG4gICAgICBjb25zdCB3YWxsZXRUZW1wID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwgd2FsbGV0RGF0YVRlbXApO1xuICAgICAgcGVuZGluZ0FwcHJvdmFsRGF0YVRlbXAud2FsbGV0ID0gd2FsbGV0VGVtcC5pZCgpO1xuXG4gICAgICBjb25zdCBwZW5kaW5nQXBwcm92YWxzID0gd2FsbGV0VGVtcC5wZW5kaW5nQXBwcm92YWxzKCk7XG4gICAgICBwZW5kaW5nQXBwcm92YWxzLnNob3VsZC5oYXZlLmxlbmd0aCgxKTtcbiAgICAgIGNvbnN0IHBlbmRpbmdBcHByb3ZhbCA9IHBlbmRpbmdBcHByb3ZhbHNbMF07XG5cbiAgICAgIGxldCBzdHViOiBzaW5vbi5TaW5vblN0dWI7XG4gICAgICBpZiAoY29pbi5zdXBwb3J0c1RzcygpKSB7XG4gICAgICAgIHN0dWIgPSBzYW5kYm94LnN0dWIoUGVuZGluZ0FwcHJvdmFsLnByb3RvdHlwZSwgJ3JlY3JlYXRlQW5kU2lnblRTU1RyYW5zYWN0aW9uJykucmVzb2x2ZXMoe1xuICAgICAgICAgIHR4SGV4OiAnZ2FiYWdvb2wnLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0dWIgPSBzYW5kYm94LnN0dWIoUGVuZGluZ0FwcHJvdmFsLnByb3RvdHlwZSwgJ3JlY3JlYXRlQW5kU2lnblRyYW5zYWN0aW9uJykucmVzb2x2ZXMoe1xuICAgICAgICAgIHN0YXRlOiAnYXBwcm92ZWQnLFxuICAgICAgICAgIGhhbGZTaWduZWQ6IHsgdHhIZXg6ICdnYWJhZ29vbCcgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBhU2NvcGUgPSBub2NrKGJnVXJsKVxuICAgICAgICAucHV0KGAvYXBpL3YyLyR7Y29pbk5hbWV9L3BlbmRpbmdhcHByb3ZhbHMvJHtwZW5kaW5nQXBwcm92YWxEYXRhVGVtcC5pZH1gLCB7XG4gICAgICAgICAgc3RhdGU6ICdhcHByb3ZlZCcsXG4gICAgICAgICAgaGFsZlNpZ25lZDogdHlwZSA9PT0gVHlwZS5UUkFOU0FDVElPTl9SRVFVRVNUID8geyB0eEhleDogJ2dhYmFnb29sJyB9IDogdW5kZWZpbmVkLFxuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgLi4ucGVuZGluZ0FwcHJvdmFsRGF0YVRlbXAsXG4gICAgICAgICAgc3RhdGU6ICdhcHByb3ZlZCcsXG4gICAgICAgIH0pO1xuXG4gICAgICBhd2FpdCBwZW5kaW5nQXBwcm92YWwuYXBwcm92ZSh7IHhwcnY6ICdub25zZW5zZScsIHdhbGxldFBhc3NwaHJhc2U6ICdnYWJhZ29vbGlvJyB9KTtcblxuICAgICAgLy8gU2hvdWxkIG5vdCBjYWxsIGJ1aWxkIGFuZCBzaG91bGQgY2FsbCBwYVxuICAgICAgcGFTY29wZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgc3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5lcXVhbChyZWNyZWF0ZVRyYW5zYWN0aW9uKTtcbiAgICB9KTtcbiAgfVxuXG4gIHRlc3RSZWNyZWF0ZVRyYW5zYWN0aW9uKCd0YnRjJywgZmFsc2UsIFR5cGUuVFJBTlNBQ1RJT05fUkVRVUVTVCk7XG4gIHRlc3RSZWNyZWF0ZVRyYW5zYWN0aW9uKCd0c29sJywgdHJ1ZSwgVHlwZS5UUkFOU0FDVElPTl9SRVFVRVNUKTtcbiAgdGVzdFJlY3JlYXRlVHJhbnNhY3Rpb24oJ3Rzb2wnLCB0cnVlLCBUeXBlLlRSQU5TQUNUSU9OX1JFUVVFU1RfRlVMTCk7XG4gIHRlc3RSZWNyZWF0ZVRyYW5zYWN0aW9uKCd0ZXRoJywgdHJ1ZSwgVHlwZS5UUkFOU0FDVElPTl9SRVFVRVNUX0ZVTEwpO1xuXG4gIGRlc2NyaWJlKCdyZWNyZWF0ZUFuZFNpZ25UU1NUcmFuc2FjdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgY29pbjogQmFzZUNvaW47XG5cbiAgICBiZWZvcmUoKCkgPT4ge1xuICAgICAgY29pbiA9IGJpdGdvLmNvaW4oJ3Rzb2wnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY2FsbCBhcHByb3ZlIGFuZCBkbyB0aGUgVFNTIGZsb3cgYW5kIGZhaWwgaWYgdGhlIHR4UmVxdWVzdElkIGlzIG1pc3NpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBwZW5kaW5nQXBwcm92YWwgPSB3YWxsZXQucGVuZGluZ0FwcHJvdmFscygpWzBdO1xuICAgICAgY29uc3QgcmVxSWQgPSBuZXcgUmVxdWVzdFRyYWNlcigpO1xuICAgICAgY29uc3QgcGFyYW1zID0geyB3YWxsZXRQYXNzcGhyYXNlOiAndGVzdCcgfTtcbiAgICAgIGF3YWl0IHBlbmRpbmdBcHByb3ZhbFxuICAgICAgICAucmVjcmVhdGVBbmRTaWduVFNTVHJhbnNhY3Rpb24ocGFyYW1zLCByZXFJZClcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3R4UmVxdWVzdElkIG5vdCBmb3VuZCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjYWxsIGFwcHJvdmUgYW5kIGRvIHRoZSBUU1MgZmxvdyBhbmQgZmFpbCBpZiB0aGUgd2FsbGV0UGFzc3BocmFzZSBpcyBtaXNzaW5nJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcGVuZGluZ0FwcHJvdmFsID0gd2FsbGV0LnBlbmRpbmdBcHByb3ZhbHMoKVswXTtcbiAgICAgIHBlbmRpbmdBcHByb3ZhbERhdGFbJ3R4UmVxdWVzdElkJ10gPSAncmVxdWVzdFR4SWRUZXN0JztcbiAgICAgIGNvbnN0IHJlcUlkID0gbmV3IFJlcXVlc3RUcmFjZXIoKTtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHt9O1xuICAgICAgYXdhaXQgcGVuZGluZ0FwcHJvdmFsXG4gICAgICAgIC5yZWNyZWF0ZUFuZFNpZ25UU1NUcmFuc2FjdGlvbihwYXJhbXMsIHJlcUlkKVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnd2FsbGV0UGFzc3BocmFzZSBub3QgZm91bmQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY2FsbCBhcHByb3ZlIGFuZCBkbyB0aGUgVFNTIGZsb3cgYW5kIGZhaWwgaWYgdGhlIHdhbGxldCBpcyBtaXNzaW5nJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcGVuZGluZ0FwcHJvdmFsID0gbmV3IFBlbmRpbmdBcHByb3ZhbChiaXRnbywgY29pbiwgcGVuZGluZ0FwcHJvdmFsRGF0YSk7XG4gICAgICBjb25zdCByZXFJZCA9IG5ldyBSZXF1ZXN0VHJhY2VyKCk7XG4gICAgICBjb25zdCBwYXJhbXMgPSB7IHdhbGxldFBhc3NwaHJhc2U6ICd0ZXN0JyB9O1xuICAgICAgYXdhaXQgcGVuZGluZ0FwcHJvdmFsLnJlY3JlYXRlQW5kU2lnblRTU1RyYW5zYWN0aW9uKHBhcmFtcywgcmVxSWQpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ1dhbGxldCBub3QgZm91bmQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2V0IHR4SGV4IGZvciB0cmFuc2FjdGlvblJlcXVlc3RMaXRlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgcGVuZGluZ0FwcHJvdmFsRGF0YVsndHhSZXF1ZXN0SWQnXSA9ICdyZXF1ZXN0VHhJZFRlc3QnO1xuICAgICAgY29uc3QgcGVuZGluZ0FwcHJvdmFsID0gbmV3IFBlbmRpbmdBcHByb3ZhbChiaXRnbywgY29pbiwgcGVuZGluZ0FwcHJvdmFsRGF0YSwgd2FsbGV0KTtcbiAgICAgIGNvbnN0IHJlcUlkID0gbmV3IFJlcXVlc3RUcmFjZXIoKTtcbiAgICAgIGNvbnN0IHR4UmVxdWVzdElkID0gJ3Rlc3QnO1xuICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICd0ZXN0JztcbiAgICAgIGNvbnN0IGRlY3J5cHRlZFBydlJlc3BvbnNlID0gJ2RlY3J5cHRlZFBydic7XG4gICAgICBjb25zdCBwYXJhbXMgPSB7IHR4UmVxdWVzdElkLCB3YWxsZXRQYXNzcGhyYXNlIH07XG4gICAgICBjb25zdCB0eFJlcXVlc3Q6IFR4UmVxdWVzdCA9IHtcbiAgICAgICAgYXBpVmVyc2lvbjogJ2xpdGUnLFxuICAgICAgICB0eFJlcXVlc3RJZDogdHhSZXF1ZXN0SWQsXG4gICAgICAgIHVuc2lnbmVkVHhzOiBbeyBzaWduYWJsZUhleDogJ3JhbmRvbWhleCcsIHNlcmlhbGl6ZWRUeEhleDogJ3JhbmRvbWhleDInLCBkZXJpdmF0aW9uUGF0aDogJ20vMCcgfV0sXG4gICAgICAgIHNpZ25hdHVyZVNoYXJlczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGZyb206IFNpZ25hdHVyZVNoYXJlVHlwZS5CSVRHTyxcbiAgICAgICAgICAgIHRvOiBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUixcbiAgICAgICAgICAgIHNoYXJlOiAnOWQ3MTU5YTc2NzAwNjM1VEVTVCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgdHJhbnNhY3Rpb25zOiBbXSxcbiAgICAgICAgdXNlcklkOiAndXNlcklkJyxcbiAgICAgICAgZGF0ZTogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICBpbnRlbnQ6IHtcbiAgICAgICAgICBpbnRlbnRUeXBlOiAncGF5bWVudCcsXG4gICAgICAgIH0sXG4gICAgICAgIGxhdGVzdDogdHJ1ZSxcbiAgICAgICAgd2FsbGV0SWQ6ICd3YWxsZXRJZCcsXG4gICAgICAgIHZlcnNpb246IDEsXG4gICAgICAgIHBvbGljaWVzQ2hlY2tlZDogZmFsc2UsXG4gICAgICAgIHdhbGxldFR5cGU6ICdob3QnLFxuICAgICAgICBzdGF0ZTogJ3BlbmRpbmdVc2VyU2lnbmF0dXJlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGRlY3J5cHRlZFBydiA9IHNhbmRib3guc3R1YihXYWxsZXQucHJvdG90eXBlLCAnZ2V0UHJ2Jyk7XG4gICAgICBkZWNyeXB0ZWRQcnYuY2FsbGVkT25jZVdpdGhFeGFjdGx5KHsgd2FsbGV0UGFzc3BocmFzZSB9KTtcbiAgICAgIGRlY3J5cHRlZFBydi5yZXNvbHZlcyhkZWNyeXB0ZWRQcnZSZXNwb25zZSk7XG5cbiAgICAgIGNvbnN0IHJlY3JlYXRlVHhSZXF1ZXN0ID0gc2FuZGJveC5zdHViKFRzc1V0aWxzLnByb3RvdHlwZSwgJ3JlY3JlYXRlVHhSZXF1ZXN0Jyk7XG4gICAgICByZWNyZWF0ZVR4UmVxdWVzdC5jYWxsZWRPbmNlV2l0aEV4YWN0bHkodHhSZXF1ZXN0LnR4UmVxdWVzdElkLCBkZWNyeXB0ZWRQcnZSZXNwb25zZSwgcmVxSWQpO1xuICAgICAgcmVjcmVhdGVUeFJlcXVlc3QucmVzb2x2ZXModHhSZXF1ZXN0KTtcblxuICAgICAgY29uc3QgcmVjcmVhdGVkVHggPSBhd2FpdCBwZW5kaW5nQXBwcm92YWwucmVjcmVhdGVBbmRTaWduVFNTVHJhbnNhY3Rpb24ocGFyYW1zLCByZXFJZCk7XG4gICAgICByZWNyZWF0ZWRUeC5zaG91bGQuYmUuZGVlcEVxdWFsKHsgdHhIZXg6IHR4UmVxdWVzdC51bnNpZ25lZFR4c1swXS5zZXJpYWxpemVkVHhIZXggfSk7XG5cbiAgICAgIHNhbmRib3gudmVyaWZ5KCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdldCB0eEhleCBmb3IgdHJhbnNhY3Rpb25SZXF1ZXN0RnVsbCAnLCBhc3luYyAoKSA9PiB7XG4gICAgICBwZW5kaW5nQXBwcm92YWxEYXRhWyd0eFJlcXVlc3RJZCddID0gJ3JlcXVlc3RUeElkVGVzdCc7XG4gICAgICBjb25zdCBwZW5kaW5nQXBwcm92YWwgPSBuZXcgUGVuZGluZ0FwcHJvdmFsKGJpdGdvLCBjb2luLCBwZW5kaW5nQXBwcm92YWxEYXRhLCB3YWxsZXQpO1xuICAgICAgY29uc3QgcmVxSWQgPSBuZXcgUmVxdWVzdFRyYWNlcigpO1xuICAgICAgY29uc3QgdHhSZXF1ZXN0SWQgPSAndGVzdCc7XG4gICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ3Rlc3QnO1xuICAgICAgY29uc3QgZGVjcnlwdGVkUHJ2UmVzcG9uc2UgPSAnZGVjcnlwdGVkUHJ2JztcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHsgdHhSZXF1ZXN0SWQsIHdhbGxldFBhc3NwaHJhc2UgfTtcbiAgICAgIGNvbnN0IHR4UmVxdWVzdDogVHhSZXF1ZXN0ID0ge1xuICAgICAgICB0eFJlcXVlc3RJZDogdHhSZXF1ZXN0SWQsXG4gICAgICAgIGFwaVZlcnNpb246ICdmdWxsJyxcbiAgICAgICAgdW5zaWduZWRUeHM6IFtdLFxuICAgICAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB1bnNpZ25lZFR4OiB7IHNpZ25hYmxlSGV4OiAncmFuZG9taGV4Jywgc2VyaWFsaXplZFR4SGV4OiAncmFuZG9taGV4MicsIGRlcml2YXRpb25QYXRoOiAnbS8wJyB9LFxuICAgICAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgICAgICAgICAgICAgdG86IFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSLFxuICAgICAgICAgICAgICAgIHNoYXJlOiAnOWQ3MTU5YTc2NzAwNjM1VEVTVCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgc3RhdGU6ICdpbml0aWFsaXplZCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgdXNlcklkOiAndXNlcklkJyxcbiAgICAgICAgZGF0ZTogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICBpbnRlbnQ6IHtcbiAgICAgICAgICBpbnRlbnRUeXBlOiAncGF5bWVudCcsXG4gICAgICAgIH0sXG4gICAgICAgIGxhdGVzdDogdHJ1ZSxcbiAgICAgICAgd2FsbGV0SWQ6ICd3YWxsZXRJZCcsXG4gICAgICAgIHZlcnNpb246IDEsXG4gICAgICAgIHBvbGljaWVzQ2hlY2tlZDogZmFsc2UsXG4gICAgICAgIHdhbGxldFR5cGU6ICdob3QnLFxuICAgICAgICBzdGF0ZTogJ3BlbmRpbmdEZWxpdmVyeScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBkZWNyeXB0ZWRQcnYgPSBzYW5kYm94LnN0dWIoV2FsbGV0LnByb3RvdHlwZSwgJ2dldFBydicpO1xuICAgICAgZGVjcnlwdGVkUHJ2LmNhbGxlZE9uY2VXaXRoRXhhY3RseSh7IHdhbGxldFBhc3NwaHJhc2UgfSk7XG4gICAgICBkZWNyeXB0ZWRQcnYucmVzb2x2ZXMoZGVjcnlwdGVkUHJ2UmVzcG9uc2UpO1xuXG4gICAgICBjb25zdCByZWNyZWF0ZVR4UmVxdWVzdCA9IHNhbmRib3guc3R1YihUc3NVdGlscy5wcm90b3R5cGUsICdyZWNyZWF0ZVR4UmVxdWVzdCcpO1xuICAgICAgcmVjcmVhdGVUeFJlcXVlc3QuY2FsbGVkT25jZVdpdGhFeGFjdGx5KHR4UmVxdWVzdC50eFJlcXVlc3RJZCwgZGVjcnlwdGVkUHJ2UmVzcG9uc2UsIHJlcUlkKTtcbiAgICAgIHJlY3JlYXRlVHhSZXF1ZXN0LnJlc29sdmVzKHR4UmVxdWVzdCk7XG5cbiAgICAgIGNvbnN0IHJlY3JlYXRlZFR4ID0gYXdhaXQgcGVuZGluZ0FwcHJvdmFsLnJlY3JlYXRlQW5kU2lnblRTU1RyYW5zYWN0aW9uKHBhcmFtcywgcmVxSWQpO1xuICAgICAgcmVjcmVhdGVkVHguc2hvdWxkLmJlLmRlZXBFcXVhbCh7IHR4SGV4OiB0eFJlcXVlc3QudHJhbnNhY3Rpb25zIVswXS51bnNpZ25lZFR4LnNlcmlhbGl6ZWRUeEhleCB9KTtcblxuICAgICAgc2FuZGJveC52ZXJpZnkoKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==