UNPKG

bitgo

Version:
249 lines • 40.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const nock = require("nock"); const should = require("should"); const goStakingWallet_1 = require("../../fixtures/staking/goStakingWallet"); const sdk_core_1 = require("@bitgo/sdk-core"); const sdk_test_1 = require("@bitgo/sdk-test"); const src_1 = require("../../../../src"); const sinon = require("sinon"); const coins_1 = require("../../../../src/v2/coins"); const statics_1 = require("@bitgo/statics"); describe('Go Staking Wallet Common', function () { const microservicesUri = sdk_core_1.Environments['mock'].uri; let bitgo; let baseCoin; let enterprise; let stakingWallet; const coin = 'tsol'; const ofcCoin = `ofc${coin}`; before(async function () { bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock', microservicesUri }); bitgo.initializeTestVars(); baseCoin = bitgo.coin(ofcCoin); baseCoin.keychains(); const ofcToken = statics_1.tokens.testnet.ofc.tokens.filter((token) => token.type === `ofc${coin}`)[0]; const tokenConstructor = coins_1.OfcToken.createTokenConstructor(ofcToken); bitgo.register(ofcToken.type, tokenConstructor); enterprise = new sdk_core_1.Enterprise(bitgo, baseCoin, { id: '5cf940949449412d00f53b3d92dbcaa3', name: 'Test Enterprise' }); const walletData = { id: 'walletId', coin: ofcCoin, enterprise: enterprise.id, keys: ['5b3424f91bf349930e340175', '5b3424f91bf349930e340174', '5b3424f91bf349930e340173'], }; const wallet = new sdk_core_1.Wallet(bitgo, baseCoin, walletData); stakingWallet = wallet.toGoStakingWallet(); nock(microservicesUri) .get(`/api/v2/${ofcCoin}/key/${stakingWallet.wallet.keyIds()[0]}`) .reply(200, { id: stakingWallet.wallet.keyIds()[0], pub: 'xpub661MyMwAqRbcFq65dvGMeEVb81KKDRRkWkawSVesWcyevGc5gr8V27LjNfkktaMuKtM362jhgKy2eu35RdArcmmEAoULzAvgKkJpWQPvLXM', source: 'user', encryptedPrv: bitgo.encrypt({ input: 'xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76', password: 'passphrase', }), coinSpecific: {}, }); nock(microservicesUri) .get(`/api/v2/${ofcCoin}/key/${stakingWallet.wallet.keyIds()[1]}`) .reply(200, { id: stakingWallet.wallet.keyIds()[1], pub: 'xpub661MyMwAqRbcFq65dvGMeEVb81KKDRRkWkawSVesWcyevGc5gr8V27LjNfkktaMuKtM362jhgKy2eu35RdArcmmEAoULzAvgKkJpWQPvLXM', source: 'user', encryptedPrv: bitgo.encrypt({ input: 'xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76', password: 'passphrase', }), coinSpecific: {}, }); nock(microservicesUri) .get(`/api/v2/${ofcCoin}/key/${stakingWallet.wallet.keyIds()[2]}`) .reply(200, { id: stakingWallet.wallet.keyIds()[2], pub: 'xpub661MyMwAqRbcFq65dvGMeEVb81KKDRRkWkawSVesWcyevGc5gr8V27LjNfkktaMuKtM362jhgKy2eu35RdArcmmEAoULzAvgKkJpWQPvLXM', source: 'user', encryptedPrv: bitgo.encrypt({ input: 'xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76', password: 'passphrase', }), coinSpecific: {}, }); }); const sandbox = sinon.createSandbox(); afterEach(function () { sandbox.verifyAndRestore(); }); describe('stake', function () { it('should call go-staking-service to stake', async function () { const preview = goStakingWallet_1.default.previewGoStakingRequest(coin); const msScope1 = nock(microservicesUri) .post(`/api/go-staking/v1/${ofcCoin}/accounts/${stakingWallet.accountId}/requests/preview`, { amount: '1', clientId: 'clientId', type: 'STAKE', }) .reply(201, preview); const expected = goStakingWallet_1.default.finalizeGoStakingRequest(coin, 'STAKE'); const msScope2 = nock(microservicesUri) .post(`/api/go-staking/v1/${ofcCoin}/accounts/${stakingWallet.accountId}/requests/finalize`, { amount: '1', clientId: 'clientId', frontTransferSendRequest: { halfSigned: { payload: preview.payload, signature: '1f4f7e789ef485363b33dca7273717a4a4413330f2badbcaf302758bc404ff8e930943db81aa2c77007738afa23166934c2a3136bae281bea037095be7183c0602', }, }, type: 'STAKE', }) .reply(201, expected); const stakingRequest = await stakingWallet.stake({ amount: '1', clientId: 'clientId', walletPassphrase: 'passphrase', }); should.exist(stakingRequest); stakingRequest.should.deepEqual(expected); msScope1.isDone().should.be.True(); msScope2.isDone().should.be.True(); }); it('should stake without a wallet passphrase for an OFC wallet that signs remotely (userKeySigningRequired === false)', async function () { // OFC wallet signs remotely via the BitGo key instead of decrypting the user key locally. const remoteWallet = new sdk_core_1.Wallet(bitgo, baseCoin, { id: 'remoteWalletId', coin: ofcCoin, enterprise: enterprise.id, keys: ['5b3424f91bf349930e340175', '5b3424f91bf349930e340174', '5b3424f91bf349930e340173'], coinSpecific: { userKeySigningRequired: false }, }); const remoteStakingWallet = remoteWallet.toGoStakingWallet(); // prebuildAndSignTransaction still fetches the user keychain (index 0), but with no passphrase // the decrypt check is skipped and the key is never used to sign. nock(microservicesUri).get(`/api/v2/${ofcCoin}/key/${remoteStakingWallet.wallet.keyIds()[0]}`).reply(200, { id: remoteStakingWallet.wallet.keyIds()[0], pub: 'xpub661MyMwAqRbcFq65dvGMeEVb81KKDRRkWkawSVesWcyevGc5gr8V27LjNfkktaMuKtM362jhgKy2eu35RdArcmmEAoULzAvgKkJpWQPvLXM', source: 'user', coinSpecific: {}, }); const preview = goStakingWallet_1.default.previewGoStakingRequest(coin); const msScope1 = nock(microservicesUri) .post(`/api/go-staking/v1/${ofcCoin}/accounts/${remoteStakingWallet.accountId}/requests/preview`, { amount: '1', clientId: 'clientId', type: 'STAKE', }) .reply(201, preview); // remote signing: the BitGo key signs the payload and returns the signature const signature = '1f4f7e789ef485363b33dca7273717a4a4413330f2badbcaf302758bc404ff8e930943db81aa2c77007738afa23166934c2a3136bae281bea037095be7183c0602'; const signScope = nock(microservicesUri) .post(`/api/v2/ofc/wallet/${remoteWallet.id()}/tx/sign`, { payload: preview.payload }) .reply(200, { signature }); const expected = goStakingWallet_1.default.finalizeGoStakingRequest(coin, 'STAKE'); const msScope2 = nock(microservicesUri) .post(`/api/go-staking/v1/${ofcCoin}/accounts/${remoteStakingWallet.accountId}/requests/finalize`, { amount: '1', clientId: 'clientId', frontTransferSendRequest: { halfSigned: { payload: preview.payload, signature, }, }, type: 'STAKE', }) .reply(201, expected); const stakingRequest = await remoteStakingWallet.stake({ amount: '1', clientId: 'clientId', }); should.exist(stakingRequest); stakingRequest.should.deepEqual(expected); msScope1.isDone().should.be.True(); signScope.isDone().should.be.True(); msScope2.isDone().should.be.True(); }); }); describe('unstake', function () { it('should call go-staking-service to unstake', async function () { const expected = goStakingWallet_1.default.finalizeGoStakingRequest(coin, 'UNSTAKE'); const msScope = nock(microservicesUri) .post(`/api/go-staking/v1/${ofcCoin}/accounts/${stakingWallet.accountId}/requests/finalize`, { amount: '1', clientId: 'clientId', type: 'UNSTAKE', }) .reply(201, expected); const stakingRequest = await stakingWallet.unstake({ amount: '1', clientId: 'clientId', }); should.exist(stakingRequest); stakingRequest.should.deepEqual(expected); msScope.isDone().should.be.True(); }); }); describe('getGoStakingRequest', function () { it('should call go-staking-service to get go staking request', async function () { const stakingRequestId = '8638284a-dab2-46b9-b07f-21109a6e7220'; const expected = goStakingWallet_1.default.finalizeGoStakingRequest(coin, 'STAKE'); const msScope = nock(microservicesUri) .get(`/api/go-staking/v1/${ofcCoin}/accounts/${stakingWallet.accountId}/requests/${stakingRequestId}`) .reply(200, expected); const stakingRequest = await stakingWallet.getGoStakingRequest(stakingRequestId); should.exist(stakingRequest); stakingRequest.should.deepEqual(expected); msScope.isDone().should.be.True(); }); }); describe('getGoStakingRequestsByCoin', function () { it('should call go-staking-service to get go staking requests by coin', async function () { const expected = goStakingWallet_1.default.getGoStakingRequestsByCoin(ofcCoin); const msScope = nock(microservicesUri) .get(`/api/go-staking/v1/${ofcCoin}/accounts/${stakingWallet.accountId}/requests`) .reply(200, expected); const stakingRequests = await stakingWallet.getGoStakingRequestsByWalletCoin(); should.exist(stakingRequests); stakingRequests.should.deepEqual(expected); msScope.isDone().should.be.True(); }); }); describe('getGoStakingRequests', function () { it('should call go-staking-service to get go staking requests', async function () { const expected = goStakingWallet_1.default.getGoStakingRequests([ofcCoin]); const msScope = nock(microservicesUri) .get(`/api/go-staking/v1/accounts/${stakingWallet.accountId}/requests`) .reply(200, expected); const stakingRequests = await stakingWallet.getGoStakingRequests(); should.exist(stakingRequests); stakingRequests.should.deepEqual(expected); msScope.isDone().should.be.True(); }); }); describe('getGoStakingWallets', function () { it('should call go-staking-service to get go staking wallets', async function () { const expected = goStakingWallet_1.default.getGoStakingWallets([ofcCoin]); const msScope = nock(microservicesUri) .get(`/api/go-staking/v1/accounts/${stakingWallet.accountId}/coins`) .reply(200, expected); const goStakingWallets = await stakingWallet.getGoStakingWallets(); should.exist(goStakingWallets); goStakingWallets.should.deepEqual(expected); msScope.isDone().should.be.True(); }); }); describe('getGoStakingWallet', function () { it('should call go-staking-service to get go staking wallet', async function () { const expected = goStakingWallet_1.default.getGoStakingWallet(ofcCoin); const msScope = nock(microservicesUri) .get(`/api/go-staking/v1/${ofcCoin}/accounts/${stakingWallet.accountId}/coins`) .reply(200, expected); const goStakingWallet = await stakingWallet.getGoStakingWallet(); should.exist(goStakingWallet); goStakingWallet.should.deepEqual(expected); msScope.isDone().should.be.True(); }); }); }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ29TdGFraW5nV2FsbGV0Q29tbW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vdGVzdC92Mi91bml0L3N0YWtpbmcvZ29TdGFraW5nV2FsbGV0Q29tbW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkJBQThCO0FBQzlCLGlDQUFrQztBQUNsQyw0RUFBOEQ7QUFFOUQsOENBQW9GO0FBQ3BGLDhDQUE0QztBQUM1Qyx5Q0FBd0M7QUFDeEMsK0JBQStCO0FBQy9CLG9EQUFvRDtBQUNwRCw0Q0FBd0M7QUFFeEMsUUFBUSxDQUFDLDBCQUEwQixFQUFFO0lBQ25DLE1BQU0sZ0JBQWdCLEdBQUcsdUJBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDbEQsSUFBSSxLQUFLLENBQUM7SUFDVixJQUFJLFFBQVEsQ0FBQztJQUNiLElBQUksVUFBVSxDQUFDO0lBQ2YsSUFBSSxhQUE4QixDQUFDO0lBQ25DLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQztJQUNwQixNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksRUFBRSxDQUFDO0lBRTdCLE1BQU0sQ0FBQyxLQUFLO1FBQ1YsS0FBSyxHQUFHLG9CQUFTLENBQUMsUUFBUSxDQUFDLFdBQUssRUFBRSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsZ0JBQWdCLEVBQVMsQ0FBQyxDQUFDO1FBQzVFLEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQzNCLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQy9CLFFBQVEsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNyQixNQUFNLFFBQVEsR0FBRyxnQkFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxNQUFNLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFD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QyxJQUFJLEVBQUUsQ0FBQztRQUNwQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgbm9jayA9IHJlcXVpcmUoJ25vY2snKTtcbmltcG9ydCBzaG91bGQgPSByZXF1aXJlKCdzaG91bGQnKTtcbmltcG9ydCBmaXh0dXJlcyBmcm9tICcuLi8uLi9maXh0dXJlcy9zdGFraW5nL2dvU3Rha2luZ1dhbGxldCc7XG5cbmltcG9ydCB7IEVudGVycHJpc2UsIEVudmlyb25tZW50cywgR29TdGFraW5nV2FsbGV0LCBXYWxsZXQgfSBmcm9tICdAYml0Z28vc2RrLWNvcmUnO1xuaW1wb3J0IHsgVGVzdEJpdEdvIH0gZnJvbSAnQGJpdGdvL3Nkay10ZXN0JztcbmltcG9ydCB7IEJpdEdvIH0gZnJvbSAnLi4vLi4vLi4vLi4vc3JjJztcbmltcG9ydCAqIGFzIHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCB7IE9mY1Rva2VuIH0gZnJvbSAnLi4vLi4vLi4vLi4vc3JjL3YyL2NvaW5zJztcbmltcG9ydCB7IHRva2VucyB9IGZyb20gJ0BiaXRnby9zdGF0aWNzJztcblxuZGVzY3JpYmUoJ0dvIFN0YWtpbmcgV2FsbGV0IENvbW1vbicsIGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgbWljcm9zZXJ2aWNlc1VyaSA9IEVudmlyb25tZW50c1snbW9jayddLnVyaTtcbiAgbGV0IGJpdGdvO1xuICBsZXQgYmFzZUNvaW47XG4gIGxldCBlbnRlcnByaXNlO1xuICBsZXQgc3Rha2luZ1dhbGxldDogR29TdGFraW5nV2FsbGV0O1xuICBjb25zdCBjb2luID0gJ3Rzb2wnO1xuICBjb25zdCBvZmNDb2luID0gYG9mYyR7Y29pbn1gO1xuXG4gIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R28sIHsgZW52OiAnbW9jaycsIG1pY3Jvc2VydmljZXNVcmkgfSBhcyBhbnkpO1xuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgIGJhc2VDb2luID0gYml0Z28uY29pbihvZmNDb2luKTtcbiAgICBiYXNlQ29pbi5rZXljaGFpbnMoKTtcbiAgICBjb25zdCBvZmNUb2tlbiA9IHRva2Vucy50ZXN0bmV0Lm9mYy50b2tlbnMuZmlsdGVyKCh0b2tlbikgPT4gdG9rZW4udHlwZSA9PT0gYG9mYyR7Y29pbn1gKVswXTtcbiAgICBjb25zdCB0b2tlbkNvbnN0cnVjdG9yID0gT2ZjVG9rZW4uY3JlYXRlVG9rZW5Db25zdHJ1Y3RvcihvZmNUb2tlbik7XG4gICAgYml0Z28ucmVnaXN0ZXIob2ZjVG9rZW4udHlwZSwgdG9rZW5Db25zdHJ1Y3Rvcik7XG5cbiAgICBlbnRlcnByaXNlID0gbmV3IEVudGVycHJpc2UoYml0Z28sIGJhc2VDb2luLCB7IGlkOiAnNWNmOTQwOTQ5NDQ5NDEyZDAwZjUzYjNkOTJkYmNhYTMnLCBuYW1lOiAnVGVzdCBFbnRlcnByaXNlJyB9KTtcbiAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgaWQ6ICd3YWxsZXRJZCcsXG4gICAgICBjb2luOiBvZmNDb2luLFxuICAgICAgZW50ZXJwcmlzZTogZW50ZXJwcmlzZS5pZCxcbiAgICAgIGtleXM6IFsnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc1JywgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NCcsICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzMnXSxcbiAgICB9O1xuICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2VDb2luLCB3YWxsZXREYXRhKTtcbiAgICBzdGFraW5nV2FsbGV0ID0gd2FsbGV0LnRvR29TdGFraW5nV2FsbGV0KCk7XG4gICAgbm9jayhtaWNyb3NlcnZpY2VzVXJpKVxuICAgICAgLmdldChgL2FwaS92Mi8ke29mY0NvaW59L2tleS8ke3N0YWtpbmdXYWxsZXQud2FsbGV0LmtleUlkcygpWzBdfWApXG4gICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiBzdGFraW5nV2FsbGV0LndhbGxldC5rZXlJZHMoKVswXSxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0ZxNjVkdkdNZUVWYjgxS0tEUlJrV2thd1NWZXNXY3lldkdjNWdyOFYyN0xqTmZra3RhTXVLdE0zNjJqaGdLeTJldTM1UmRBcmNtbUVBb1VMekF2Z0trSnBXUVB2TFhNJyxcbiAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIGVuY3J5cHRlZFBydjogYml0Z28uZW5jcnlwdCh7XG4gICAgICAgICAgaW5wdXQ6XG4gICAgICAgICAgICAneHBydkE0MXo3em9nVlZ3eFZTZ2RLVUhEeTFTS21kYjUzM1BqRHo3SjZONm1WNnVTM3plMWFpOEZIYThrbUhTY0dwV21qNFdnZ0x5UWpnUGllMXJGU3J1b1VpaFVaUkVQU0wzOVVOZEUzQkJEdTc2JyxcbiAgICAgICAgICBwYXNzd29yZDogJ3Bhc3NwaHJhc2UnLFxuICAgICAgICB9KSxcbiAgICAgICAgY29pblNwZWNpZmljOiB7fSxcbiAgICAgIH0pO1xuXG4gICAgbm9jayhtaWNyb3NlcnZpY2VzVXJpKVxuICAgICAgLmdldChgL2FwaS92Mi8ke29mY0NvaW59L2tleS8ke3N0YWtpbmdXYWxsZXQud2FsbGV0LmtleUlkcygpWzFdfWApXG4gICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiBzdGFraW5nV2FsbGV0LndhbGxldC5rZXlJZHMoKVsxXSxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0ZxNjVkdkdNZUVWYjgxS0tEUlJrV2thd1NWZXNXY3lldkdjNWdyOFYyN0xqTmZra3RhTXVLdE0zNjJqaGdLeTJldTM1UmRBcmNtbUVBb1VMekF2Z0trSnBXUVB2TFhNJyxcbiAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIGVuY3J5cHRlZFBydjogYml0Z28uZW5jcnlwdCh7XG4gICAgICAgICAgaW5wdXQ6XG4gICAgICAgICAgICAneHBydkE0MXo3em9nVlZ3eFZTZ2RLVUhEeTFTS21kYjUzM1BqRHo3SjZONm1WNnVTM3plMWFpOEZIYThrbUhTY0dwV21qNFdnZ0x5UWpnUGllMXJGU3J1b1VpaFVaUkVQU0wzOVVOZEUzQkJEdTc2JyxcbiAgICAgICAgICBwYXNzd29yZDogJ3Bhc3NwaHJhc2UnLFxuICAgICAgICB9KSxcbiAgICAgICAgY29pblNwZWNpZmljOiB7fSxcbiAgICAgIH0pO1xuXG4gICAgbm9jayhtaWNyb3NlcnZpY2VzVXJpKVxuICAgICAgLmdldChgL2FwaS92Mi8ke29mY0NvaW59L2tleS8ke3N0YWtpbmdXYWxsZXQud2FsbGV0LmtleUlkcygpWzJdfWApXG4gICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiBzdGFraW5nV2FsbGV0LndhbGxldC5rZXlJZHMoKVsyXSxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0ZxNjVkdkdNZUVWYjgxS0tEUlJrV2thd1NWZXNXY3lldkdjNWdyOFYyN0xqTmZra3RhTXVLdE0zNjJqaGdLeTJldTM1UmRBcmNtbUVBb1VMekF2Z0trSnBXUVB2TFhNJyxcbiAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIGVuY3J5cHRlZFBydjogYml0Z28uZW5jcnlwdCh7XG4gICAgICAgICAgaW5wdXQ6XG4gICAgICAgICAgICAneHBydkE0MXo3em9nVlZ3eFZTZ2RLVUhEeTFTS21kYjUzM1BqRHo3SjZONm1WNnVTM3plMWFpOEZIYThrbUhTY0dwV21qNFdnZ0x5UWpnUGllMXJGU3J1b1VpaFVaUkVQU0wzOVVOZEUzQkJEdTc2JyxcbiAgICAgICAgICBwYXNzd29yZDogJ3Bhc3NwaHJhc2UnLFxuICAgICAgICB9KSxcbiAgICAgICAgY29pblNwZWNpZmljOiB7fSxcbiAgICAgIH0pO1xuICB9KTtcblxuICBjb25zdCBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuXG4gIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgc2FuZGJveC52ZXJpZnlBbmRSZXN0b3JlKCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdzdGFrZScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGNhbGwgZ28tc3Rha2luZy1zZXJ2aWNlIHRvIHN0YWtlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHJldmlldyA9IGZpeHR1cmVzLnByZXZpZXdHb1N0YWtpbmdSZXF1ZXN0KGNvaW4pO1xuICAgICAgY29uc3QgbXNTY29wZTEgPSBub2NrKG1pY3Jvc2VydmljZXNVcmkpXG4gICAgICAgIC5wb3N0KGAvYXBpL2dvLXN0YWtpbmcvdjEvJHtvZmNDb2lufS9hY2NvdW50cy8ke3N0YWtpbmdXYWxsZXQuYWNjb3VudElkfS9yZXF1ZXN0cy9wcmV2aWV3YCwge1xuICAgICAgICAgIGFtb3VudDogJzEnLFxuICAgICAgICAgIGNsaWVudElkOiAnY2xpZW50SWQnLFxuICAgICAgICAgIHR5cGU6ICdTVEFLRScsXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDEsIHByZXZpZXcpO1xuXG4gICAgICBjb25zdCBleHBlY3RlZCA9IGZpeHR1cmVzLmZpbmFsaXplR29TdGFraW5nUmVxdWVzdChjb2luLCAnU1RBS0UnKTtcbiAgICAgIGNvbnN0IG1zU2NvcGUyID0gbm9jayhtaWNyb3NlcnZpY2VzVXJpKVxuICAgICAgICAucG9zdChgL2FwaS9nby1zdGFraW5nL3YxLyR7b2ZjQ29pbn0vYWNjb3VudHMvJHtzdGFraW5nV2FsbGV0LmFjY291bnRJZH0vcmVxdWVzdHMvZmluYWxpemVgLCB7XG4gICAgICAgICAgYW1vdW50OiAnMScsXG4gICAgICAgICAgY2xpZW50SWQ6ICdjbGllbnRJZCcsXG4gICAgICAgICAgZnJvbnRUcmFuc2ZlclNlbmRSZXF1ZXN0OiB7XG4gICAgICAgICAgICBoYWxmU2lnbmVkOiB7XG4gICAgICAgICAgICAgIHBheWxvYWQ6IHByZXZpZXcucGF5bG9hZCxcbiAgICAgICAgICAgICAgc2lnbmF0dXJlOlxuICAgICAgICAgICAgICAgICcxZjRmN2U3ODllZjQ4NTM2M2IzM2RjYTcyNzM3MTdhNGE0NDEzMzMwZjJiYWRiY2FmMzAyNzU4YmM0MDRmZjhlOTMwOTQzZGI4MWFhMmM3NzAwNzczOGFmYTIzMTY2OTM0YzJhMzEzNmJhZTI4MWJlYTAzNzA5NWJlNzE4M2MwNjAyJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0eXBlOiAnU1RBS0UnLFxuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAxLCBleHBlY3RlZCk7XG5cbiAgICAgIGNvbnN0IHN0YWtpbmdSZXF1ZXN0ID0gYXdhaXQgc3Rha2luZ1dhbGxldC5zdGFrZSh7XG4gICAgICAgIGFtb3VudDogJzEnLFxuICAgICAgICBjbGllbnRJZDogJ2NsaWVudElkJyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ3Bhc3NwaHJhc2UnLFxuICAgICAgfSk7XG5cbiAgICAgIHNob3VsZC5leGlzdChzdGFraW5nUmVxdWVzdCk7XG5cbiAgICAgIHN0YWtpbmdSZXF1ZXN0LnNob3VsZC5kZWVwRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgbXNTY29wZTEuaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICAgIG1zU2NvcGUyLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHN0YWtlIHdpdGhvdXQgYSB3YWxsZXQgcGFzc3BocmFzZSBmb3IgYW4gT0ZDIHdhbGxldCB0aGF0IHNpZ25zIHJlbW90ZWx5ICh1c2VyS2V5U2lnbmluZ1JlcXVpcmVkID09PSBmYWxzZSknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBPRkMgd2FsbGV0IHNpZ25zIHJlbW90ZWx5IHZpYSB0aGUgQml0R28ga2V5IGluc3RlYWQgb2YgZGVjcnlwdGluZyB0aGUgdXNlciBrZXkgbG9jYWxseS5cbiAgICAgIGNvbnN0IHJlbW90ZVdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2VDb2luLCB7XG4gICAgICAgIGlkOiAncmVtb3RlV2FsbGV0SWQnLFxuICAgICAgICBjb2luOiBvZmNDb2luLFxuICAgICAgICBlbnRlcnByaXNlOiBlbnRlcnByaXNlLmlkLFxuICAgICAgICBrZXlzOiBbJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NScsICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzQnLCAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTczJ10sXG4gICAgICAgIGNvaW5TcGVjaWZpYzogeyB1c2VyS2V5U2lnbmluZ1JlcXVpcmVkOiBmYWxzZSB9LFxuICAgICAgfSk7XG4gICAgICBjb25zdCByZW1vdGVTdGFraW5nV2FsbGV0ID0gcmVtb3RlV2FsbGV0LnRvR29TdGFraW5nV2FsbGV0KCk7XG5cbiAgICAgIC8vIHByZWJ1aWxkQW5kU2lnblRyYW5zYWN0aW9uIHN0aWxsIGZldGNoZXMgdGhlIHVzZXIga2V5Y2hhaW4gKGluZGV4IDApLCBidXQgd2l0aCBubyBwYXNzcGhyYXNlXG4gICAgICAvLyB0aGUgZGVjcnlwdCBjaGVjayBpcyBza2lwcGVkIGFuZCB0aGUga2V5IGlzIG5ldmVyIHVzZWQgdG8gc2lnbi5cbiAgICAgIG5vY2sobWljcm9zZXJ2aWNlc1VyaSkuZ2V0KGAvYXBpL3YyLyR7b2ZjQ29pbn0va2V5LyR7cmVtb3RlU3Rha2luZ1dhbGxldC53YWxsZXQua2V5SWRzKClbMF19YCkucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiByZW1vdGVTdGFraW5nV2FsbGV0LndhbGxldC5rZXlJZHMoKVswXSxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0ZxNjVkdkdNZUVWYjgxS0tEUlJrV2thd1NWZXNXY3lldkdjNWdyOFYyN0xqTmZra3RhTXVLdE0zNjJqaGdLeTJldTM1UmRBcmNtbUVBb1VMekF2Z0trSnBXUVB2TFhNJyxcbiAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIGNvaW5TcGVjaWZpYzoge30sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcHJldmlldyA9IGZpeHR1cmVzLnByZXZpZXdHb1N0YWtpbmdSZXF1ZXN0KGNvaW4pO1xuICAgICAgY29uc3QgbXNTY29wZTEgPSBub2NrKG1pY3Jvc2VydmljZXNVcmkpXG4gICAgICAgIC5wb3N0KGAvYXBpL2dvLXN0YWtpbmcvdjEvJHtvZmNDb2lufS9hY2NvdW50cy8ke3JlbW90ZVN0YWtpbmdXYWxsZXQuYWNjb3VudElkfS9yZXF1ZXN0cy9wcmV2aWV3YCwge1xuICAgICAgICAgIGFtb3VudDogJzEnLFxuICAgICAgICAgIGNsaWVudElkOiAnY2xpZW50SWQnLFxuICAgICAgICAgIHR5cGU6ICdTVEFLRScsXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDEsIHByZXZpZXcpO1xuXG4gICAgICAvLyByZW1vdGUgc2lnbmluZzogdGhlIEJpdEdvIGtleSBzaWducyB0aGUgcGF5bG9hZCBhbmQgcmV0dXJucyB0aGUgc2lnbmF0dXJlXG4gICAgICBjb25zdCBzaWduYXR1cmUgPVxuICAgICAgICAnMWY0ZjdlNzg5ZWY0ODUzNjNiMzNkY2E3MjczNzE3YTRhNDQxMzMzMGYyYmFkYmNhZjMwMjc1OGJjNDA0ZmY4ZTkzMDk0M2RiODFhYTJjNzcwMDc3MzhhZmEyMzE2NjkzNGMyYTMxMzZiYWUyODFiZWEwMzcwOTViZTcxODNjMDYwMic7XG4gICAgICBjb25zdCBzaWduU2NvcGUgPSBub2NrKG1pY3Jvc2VydmljZXNVcmkpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyL29mYy93YWxsZXQvJHtyZW1vdGVXYWxsZXQuaWQoKX0vdHgvc2lnbmAsIHsgcGF5bG9hZDogcHJldmlldy5wYXlsb2FkIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHsgc2lnbmF0dXJlIH0pO1xuXG4gICAgICBjb25zdCBleHBlY3RlZCA9IGZpeHR1cmVzLmZpbmFsaXplR29TdGFraW5nUmVxdWVzdChjb2luLCAnU1RBS0UnKTtcbiAgICAgIGNvbnN0IG1zU2NvcGUyID0gbm9jayhtaWNyb3NlcnZpY2VzVXJpKVxuICAgICAgICAucG9zdChgL2FwaS9nby1zdGFraW5nL3YxLyR7b2ZjQ29pbn0vYWNjb3VudHMvJHtyZW1vdGVTdGFraW5nV2FsbGV0LmFjY291bnRJZH0vcmVxdWVzdHMvZmluYWxpemVgLCB7XG4gICAgICAgICAgYW1vdW50OiAnMScsXG4gICAgICAgICAgY2xpZW50SWQ6ICdjbGllbnRJZCcsXG4gICAgICAgICAgZnJvbnRUcmFuc2ZlclNlbmRSZXF1ZXN0OiB7XG4gICAgICAgICAgICBoYWxmU2lnbmVkOiB7XG4gICAgICAgICAgICAgIHBheWxvYWQ6IHByZXZpZXcucGF5bG9hZCxcbiAgICAgICAgICAgICAgc2lnbmF0dXJlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHR5cGU6ICdTVEFLRScsXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDEsIGV4cGVjdGVkKTtcblxuICAgICAgY29uc3Qgc3Rha2luZ1JlcXVlc3QgPSBhd2FpdCByZW1vdGVTdGFraW5nV2FsbGV0LnN0YWtlKHtcbiAgICAgICAgYW1vdW50OiAnMScsXG4gICAgICAgIGNsaWVudElkOiAnY2xpZW50SWQnLFxuICAgICAgfSk7XG5cbiAgICAgIHNob3VsZC5leGlzdChzdGFraW5nUmVxdWVzdCk7XG5cbiAgICAgIHN0YWtpbmdSZXF1ZXN0LnNob3VsZC5kZWVwRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgbXNTY29wZTEuaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICAgIHNpZ25TY29wZS5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgICAgbXNTY29wZTIuaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3Vuc3Rha2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBjYWxsIGdvLXN0YWtpbmctc2VydmljZSB0byB1bnN0YWtlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwZWN0ZWQgPSBmaXh0dXJlcy5maW5hbGl6ZUdvU3Rha2luZ1JlcXVlc3QoY29pbiwgJ1VOU1RBS0UnKTtcbiAgICAgIGNvbnN0IG1zU2NvcGUgPSBub2NrKG1pY3Jvc2VydmljZXNVcmkpXG4gICAgICAgIC5wb3N0KGAvYXBpL2dvLXN0YWtpbmcvdjEvJHtvZmNDb2lufS9hY2NvdW50cy8ke3N0YWtpbmdXYWxsZXQuYWNjb3VudElkfS9yZXF1ZXN0cy9maW5hbGl6ZWAsIHtcbiAgICAgICAgICBhbW91bnQ6ICcxJyxcbiAgICAgICAgICBjbGllbnRJZDogJ2NsaWVudElkJyxcbiAgICAgICAgICB0eXBlOiAnVU5TVEFLRScsXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDEsIGV4cGVjdGVkKTtcblxuICAgICAgY29uc3Qgc3Rha2luZ1JlcXVlc3QgPSBhd2FpdCBzdGFraW5nV2FsbGV0LnVuc3Rha2Uoe1xuICAgICAgICBhbW91bnQ6ICcxJyxcbiAgICAgICAgY2xpZW50SWQ6ICdjbGllbnRJZCcsXG4gICAgICB9KTtcblxuICAgICAgc2hvdWxkLmV4aXN0KHN0YWtpbmdSZXF1ZXN0KTtcblxuICAgICAgc3Rha2luZ1JlcXVlc3Quc2hvdWxkLmRlZXBFcXVhbChleHBlY3RlZCk7XG4gICAgICBtc1Njb3BlLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdnZXRHb1N0YWtpbmdSZXF1ZXN0JywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY2FsbCBnby1zdGFraW5nLXNlcnZpY2UgdG8gZ2V0IGdvIHN0YWtpbmcgcmVxdWVzdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHN0YWtpbmdSZXF1ZXN0SWQgPSAnODYzODI4NGEtZGFiMi00NmI5LWIwN2YtMjExMDlhNmU3MjIwJztcbiAgICAgIGNvbnN0IGV4cGVjdGVkID0gZml4dHVyZXMuZmluYWxpemVHb1N0YWtpbmdSZXF1ZXN0KGNvaW4sICdTVEFLRScpO1xuICAgICAgY29uc3QgbXNTY29wZSA9IG5vY2sobWljcm9zZXJ2aWNlc1VyaSlcbiAgICAgICAgLmdldChgL2FwaS9nby1zdGFraW5nL3YxLyR7b2ZjQ29pbn0vYWNjb3VudHMvJHtzdGFraW5nV2FsbGV0LmFjY291bnRJZH0vcmVxdWVzdHMvJHtzdGFraW5nUmVxdWVzdElkfWApXG4gICAgICAgIC5yZXBseSgyMDAsIGV4cGVjdGVkKTtcblxuICAgICAgY29uc3Qgc3Rha2luZ1JlcXVlc3QgPSBhd2FpdCBzdGFraW5nV2FsbGV0LmdldEdvU3Rha2luZ1JlcXVlc3Qoc3Rha2luZ1JlcXVlc3RJZCk7XG5cbiAgICAgIHNob3VsZC5leGlzdChzdGFraW5nUmVxdWVzdCk7XG5cbiAgICAgIHN0YWtpbmdSZXF1ZXN0LnNob3VsZC5kZWVwRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgbXNTY29wZS5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZ2V0R29TdGFraW5nUmVxdWVzdHNCeUNvaW4nLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBjYWxsIGdvLXN0YWtpbmctc2VydmljZSB0byBnZXQgZ28gc3Rha2luZyByZXF1ZXN0cyBieSBjb2luJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwZWN0ZWQgPSBmaXh0dXJlcy5nZXRHb1N0YWtpbmdSZXF1ZXN0c0J5Q29pbihvZmNDb2luKTtcbiAgICAgIGNvbnN0IG1zU2NvcGUgPSBub2NrKG1pY3Jvc2VydmljZXNVcmkpXG4gICAgICAgIC5nZXQoYC9hcGkvZ28tc3Rha2luZy92MS8ke29mY0NvaW59L2FjY291bnRzLyR7c3Rha2luZ1dhbGxldC5hY2NvdW50SWR9L3JlcXVlc3RzYClcbiAgICAgICAgLnJlcGx5KDIwMCwgZXhwZWN0ZWQpO1xuXG4gICAgICBjb25zdCBzdGFraW5nUmVxdWVzdHMgPSBhd2FpdCBzdGFraW5nV2FsbGV0LmdldEdvU3Rha2luZ1JlcXVlc3RzQnlXYWxsZXRDb2luKCk7XG5cbiAgICAgIHNob3VsZC5leGlzdChzdGFraW5nUmVxdWVzdHMpO1xuXG4gICAgICBzdGFraW5nUmVxdWVzdHMuc2hvdWxkLmRlZXBFcXVhbChleHBlY3RlZCk7XG4gICAgICBtc1Njb3BlLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdnZXRHb1N0YWtpbmdSZXF1ZXN0cycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGNhbGwgZ28tc3Rha2luZy1zZXJ2aWNlIHRvIGdldCBnbyBzdGFraW5nIHJlcXVlc3RzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwZWN0ZWQgPSBmaXh0dXJlcy5nZXRHb1N0YWtpbmdSZXF1ZXN0cyhbb2ZjQ29pbl0pO1xuICAgICAgY29uc3QgbXNTY29wZSA9IG5vY2sobWljcm9zZXJ2aWNlc1VyaSlcbiAgICAgICAgLmdldChgL2FwaS9nby1zdGFraW5nL3YxL2FjY291bnRzLyR7c3Rha2luZ1dhbGxldC5hY2NvdW50SWR9L3JlcXVlc3RzYClcbiAgICAgICAgLnJlcGx5KDIwMCwgZXhwZWN0ZWQpO1xuXG4gICAgICBjb25zdCBzdGFraW5nUmVxdWVzdHMgPSBhd2FpdCBzdGFraW5nV2FsbGV0LmdldEdvU3Rha2luZ1JlcXVlc3RzKCk7XG5cbiAgICAgIHNob3VsZC5leGlzdChzdGFraW5nUmVxdWVzdHMpO1xuXG4gICAgICBzdGFraW5nUmVxdWVzdHMuc2hvdWxkLmRlZXBFcXVhbChleHBlY3RlZCk7XG4gICAgICBtc1Njb3BlLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdnZXRHb1N0YWtpbmdXYWxsZXRzJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY2FsbCBnby1zdGFraW5nLXNlcnZpY2UgdG8gZ2V0IGdvIHN0YWtpbmcgd2FsbGV0cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkID0gZml4dHVyZXMuZ2V0R29TdGFraW5nV2FsbGV0cyhbb2ZjQ29pbl0pO1xuICAgICAgY29uc3QgbXNTY29wZSA9IG5vY2sobWljcm9zZXJ2aWNlc1VyaSlcbiAgICAgICAgLmdldChgL2FwaS9nby1zdGFraW5nL3YxL2FjY291bnRzLyR7c3Rha2luZ1dhbGxldC5hY2NvdW50SWR9L2NvaW5zYClcbiAgICAgICAgLnJlcGx5KDIwMCwgZXhwZWN0ZWQpO1xuXG4gICAgICBjb25zdCBnb1N0YWtpbmdXYWxsZXRzID0gYXdhaXQgc3Rha2luZ1dhbGxldC5nZXRHb1N0YWtpbmdXYWxsZXRzKCk7XG5cbiAgICAgIHNob3VsZC5leGlzdChnb1N0YWtpbmdXYWxsZXRzKTtcblxuICAgICAgZ29TdGFraW5nV2FsbGV0cy5zaG91bGQuZGVlcEVxdWFsKGV4cGVjdGVkKTtcbiAgICAgIG1zU2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2dldEdvU3Rha2luZ1dhbGxldCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGNhbGwgZ28tc3Rha2luZy1zZXJ2aWNlIHRvIGdldCBnbyBzdGFraW5nIHdhbGxldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkID0gZml4dHVyZXMuZ2V0R29TdGFraW5nV2FsbGV0KG9mY0NvaW4pO1xuICAgICAgY29uc3QgbXNTY29wZSA9IG5vY2sobWljcm9zZXJ2aWNlc1VyaSlcbiAgICAgICAgLmdldChgL2FwaS9nby1zdGFraW5nL3YxLyR7b2ZjQ29pbn0vYWNjb3VudHMvJHtzdGFraW5nV2FsbGV0LmFjY291bnRJZH0vY29pbnNgKVxuICAgICAgICAucmVwbHkoMjAwLCBleHBlY3RlZCk7XG5cbiAgICAgIGNvbnN0IGdvU3Rha2luZ1dhbGxldCA9IGF3YWl0IHN0YWtpbmdXYWxsZXQuZ2V0R29TdGFraW5nV2FsbGV0KCk7XG5cbiAgICAgIHNob3VsZC5leGlzdChnb1N0YWtpbmdXYWxsZXQpO1xuXG4gICAgICBnb1N0YWtpbmdXYWxsZXQuc2hvdWxkLmRlZXBFcXVhbChleHBlY3RlZCk7XG4gICAgICBtc1Njb3BlLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=