PHP WebShell

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

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

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const nock = require("nock");
const should = require("should");
const stakingWallet_1 = require("../../fixtures/staking/stakingWallet");
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");
describe('Staking Wallet Common', function () {
    const microservicesUri = sdk_core_1.Environments['mock'].uri;
    let bitgo;
    let baseCoin;
    let enterprise;
    let stakingWallet;
    before(function () {
        bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock', microservicesUri });
        bitgo.initializeTestVars();
        baseCoin = bitgo.coin('eth');
        baseCoin.keychains();
        enterprise = new sdk_core_1.Enterprise(bitgo, baseCoin, { id: '5cf940949449412d00f53b3d92dbcaa3', name: 'Test Enterprise' });
        const walletData = {
            id: 'walletId',
            coin: 'eth',
            enterprise: enterprise.id,
            keys: ['5b3424f91bf349930e340175'],
        };
        const wallet = new sdk_core_1.Wallet(bitgo, baseCoin, walletData);
        stakingWallet = wallet.toStakingWallet();
    });
    const sandbox = sinon.createSandbox();
    afterEach(function () {
        sandbox.verifyAndRestore();
    });
    describe('stake', function () {
        it('should call staking-service to stake', async function () {
            const expected = stakingWallet_1.default.stakingRequest([stakingWallet_1.default.transaction('NEW')]);
            const msScope = nock(microservicesUri)
                .post(`/api/staking/v1/${stakingWallet.coin}/wallets/${stakingWallet.walletId}/requests`, {
                amount: '1',
                clientId: 'clientId',
                type: 'STAKE',
            })
                .reply(201, expected);
            const stakingRequest = await stakingWallet.stake({
                amount: '1',
                clientId: 'clientId',
            });
            should.exist(stakingRequest);
            stakingRequest.should.deepEqual(expected);
            msScope.isDone().should.be.True();
        });
        it('should call staking-service to stake with optional parameters', async function () {
            const expected = stakingWallet_1.default.stakingRequest([stakingWallet_1.default.transaction('NEW')]);
            const msScope = nock(microservicesUri)
                .post(`/api/staking/v1/${stakingWallet.coin}/wallets/${stakingWallet.walletId}/requests`, {
                amount: '1',
                clientId: 'clientId',
                type: 'STAKE',
                validator: '123',
                durationSeconds: '60',
            })
                .reply(201, expected);
            const options = {
                amount: '1',
                clientId: 'clientId',
                validator: '123',
                durationSeconds: '60',
            };
            const stakingRequest = await stakingWallet.stake(options);
            should.exist(stakingRequest);
            stakingRequest.should.deepEqual(expected);
            msScope.isDone().should.be.True();
        });
        it('should call staking-service to stake with optional stakeMany parameters', async function () {
            const expected = stakingWallet_1.default.stakingRequest([stakingWallet_1.default.transaction('NEW')]);
            const msScope = nock(microservicesUri)
                .post(`/api/staking/v1/${stakingWallet.coin}/wallets/${stakingWallet.walletId}/requests`, {
                clientId: 'clientId',
                type: 'STAKE',
                delegationRequests: [
                    { amount: '1', validator: '123' },
                    { amount: '2', validator: '456' },
                ],
                durationSeconds: '60',
            })
                .reply(201, expected);
            const options = {
                clientId: 'clientId',
                delegationRequests: [
                    { amount: '1', validator: '123' },
                    { amount: '2', validator: '456' },
                ],
                durationSeconds: '60',
            };
            const stakingRequest = await stakingWallet.stake(options);
            should.exist(stakingRequest);
            stakingRequest.should.deepEqual(expected);
            msScope.isDone().should.be.True();
        });
    });
    describe('unstake', function () {
        it('should call staking-service to unstake', async function () {
            const expected = stakingWallet_1.default.stakingRequest([stakingWallet_1.default.transaction('NEW')]);
            const msScope = nock(microservicesUri)
                .post(`/api/staking/v1/${stakingWallet.coin}/wallets/${stakingWallet.walletId}/requests`, {
                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('switch validator', function () {
        it('should call staking-service to switch validator', async function () {
            const expected = stakingWallet_1.default.stakingRequest([stakingWallet_1.default.transaction('NEW')]);
            const msScope = nock(microservicesUri)
                .post(`/api/staking/v1/${stakingWallet.coin}/wallets/${stakingWallet.walletId}/requests`, {
                amount: '1',
                clientId: 'clientId',
                validator: 'validator',
                delegationId: 'delegation',
                type: 'SWITCH_VALIDATOR',
            })
                .reply(201, expected);
            const stakingRequest = await stakingWallet.switchValidator({
                amount: '1',
                clientId: 'clientId',
                validator: 'validator',
                delegationId: 'delegation',
            });
            should.exist(stakingRequest);
            stakingRequest.should.deepEqual(expected);
            msScope.isDone().should.be.True();
        });
    });
    describe('claim rewards', function () {
        it('should call staking-service to claim rewards', async function () {
            const expected = stakingWallet_1.default.stakingRequest([stakingWallet_1.default.transaction('NEW')]);
            const msScope = nock(microservicesUri)
                .post(`/api/staking/v1/${stakingWallet.coin}/wallets/${stakingWallet.walletId}/requests`, {
                amount: '1',
                clientId: 'clientId',
                delegationId: 'delegation',
                type: 'CLAIM_REWARDS',
            })
                .reply(201, expected);
            const stakingRequest = await stakingWallet.claimRewards({
                amount: '1',
                clientId: 'clientId',
                delegationId: 'delegation',
            });
            should.exist(stakingRequest);
            stakingRequest.should.deepEqual(expected);
            msScope.isDone().should.be.True();
        });
    });
    describe('cancelStakingRequest', function () {
        it('should call staking-service to cancel staking request', async function () {
            const stakingRequestId = '8638284a-dab2-46b9-b07f-21109a6e7220';
            const expected = {
                ...stakingWallet_1.default.stakingRequest([stakingWallet_1.default.transaction('REJECTED')]),
                status: 'REJECTED',
            };
            const msScope = nock(microservicesUri)
                .delete(`/api/staking/v1/${stakingWallet.coin}/wallets/${stakingWallet.walletId}/requests/${stakingRequestId}`)
                .reply(200, expected);
            const stakingRequest = await stakingWallet.cancelStakingRequest(stakingRequestId);
            should.exist(stakingRequest);
            stakingRequest.should.deepEqual(expected);
            msScope.isDone().should.be.True();
        });
    });
    describe('getStakingRequest', function () {
        it('should call staking-service to get staking request', async function () {
            const stakingRequestId = '8638284a-dab2-46b9-b07f-21109a6e7220';
            const expected = stakingWallet_1.default.stakingRequest([stakingWallet_1.default.transaction('NEW')]);
            const msScope = nock(microservicesUri)
                .get(`/api/staking/v1/${stakingWallet.coin}/wallets/${stakingWallet.walletId}/requests/${stakingRequestId}`)
                .reply(200, expected);
            const stakingRequest = await stakingWallet.getStakingRequest(stakingRequestId);
            should.exist(stakingRequest);
            stakingRequest.should.deepEqual(expected);
            msScope.isDone().should.be.True();
        });
    });
    describe('getTransactionsReadyToSign', function () {
        function mockGetStakingRequest(stakingRequestId, expected) {
            return nock(microservicesUri)
                .get(`/api/staking/v1/${stakingWallet.coin}/wallets/${stakingWallet.walletId}/requests/${stakingRequestId}`)
                .reply(200, expected);
        }
        it('should return allSigningComplete false when no transactions exist', async function () {
            const stakingRequestId = '8638284a-dab2-46b9-b07f-21109a6e7220';
            const expected = stakingWallet_1.default.stakingRequest([]);
            const msScope = mockGetStakingRequest(stakingRequestId, expected);
            const transactionsReadyToSign = await stakingWallet.getTransactionsReadyToSign(stakingRequestId);
            should.exist(transactionsReadyToSign);
            transactionsReadyToSign.allSigningComplete.should.be.False();
            transactionsReadyToSign.transactions.should.be.empty();
            msScope.isDone().should.be.True();
        });
        it('should return allSigningComplete true and 0 transactions when only a CONFIRMED transaction exists', async function () {
            const stakingRequestId = '8638284a-dab2-46b9-b07f-21109a6e7220';
            const expected = stakingWallet_1.default.stakingRequest([stakingWallet_1.default.transaction('CONFIRMED')]);
            const msScope = mockGetStakingRequest(stakingRequestId, expected);
            const transactionsReadyToSign = await stakingWallet.getTransactionsReadyToSign(stakingRequestId);
            should.exist(transactionsReadyToSign);
            transactionsReadyToSign.allSigningComplete.should.be.True();
            transactionsReadyToSign.transactions.should.be.empty();
            msScope.isDone().should.be.True();
        });
        it('should return allSigningComplete false and 0 transactions when only a NEW transaction exists', async function () {
            const stakingRequestId = '8638284a-dab2-46b9-b07f-21109a6e7220';
            const expectedStakingRequest = stakingWallet_1.default.stakingRequest([stakingWallet_1.default.transaction('NEW')]);
            const msScope = mockGetStakingRequest(stakingRequestId, expectedStakingRequest);
            const transactionsReadyToSign = await stakingWallet.getTransactionsReadyToSign(stakingRequestId);
            should.exist(transactionsReadyToSign);
            transactionsReadyToSign.allSigningComplete.should.be.False();
            transactionsReadyToSign.transactions.should.be.empty();
            msScope.isDone().should.be.True();
        });
        it('should return allSigningComplete false and 1 transactions when only a READY transaction exists', async function () {
            const stakingRequestId = '8638284a-dab2-46b9-b07f-21109a6e7220';
            const expectedTransaction = stakingWallet_1.default.transaction('READY');
            const expectedStakingRequest = stakingWallet_1.default.stakingRequest([expectedTransaction]);
            const msScope = mockGetStakingRequest(stakingRequestId, expectedStakingRequest);
            const transactionsReadyToSign = await stakingWallet.getTransactionsReadyToSign(stakingRequestId);
            should.exist(transactionsReadyToSign);
            transactionsReadyToSign.allSigningComplete.should.be.False();
            transactionsReadyToSign.transactions.should.containEql(expectedTransaction);
            msScope.isDone().should.be.True();
        });
        it('should return allSigningComplete false and 1 transaction when NEW and READY transaction exists', async function () {
            const stakingRequestId = '8638284a-dab2-46b9-b07f-21109a6e7220';
            const expectedTransaction = stakingWallet_1.default.transaction('READY');
            const expectedStakingRequest = stakingWallet_1.default.stakingRequest([expectedTransaction, stakingWallet_1.default.transaction('NEW')]);
            const msScope = mockGetStakingRequest(stakingRequestId, expectedStakingRequest);
            const transactionsReadyToSign = await stakingWallet.getTransactionsReadyToSign(stakingRequestId);
            should.exist(transactionsReadyToSign);
            transactionsReadyToSign.allSigningComplete.should.be.False();
            transactionsReadyToSign.transactions.should.containEql(expectedTransaction);
            msScope.isDone().should.be.True();
        });
    });
    describe('prebuildSelfManagedStakingTransaction', function () {
        it('should prebuild self-managed staking transaction', async function () {
            const transaction = stakingWallet_1.default.transaction('READY', stakingWallet_1.default.buildParams, false);
            nock(microservicesUri)
                .get(`/api/staking/v1/${stakingWallet.coin}/wallets/${stakingWallet.walletId}/requests/${transaction.stakingRequestId}/transactions/${transaction.id}`)
                .query({ expandBuildParams: true })
                .reply(200, transaction);
            const deleteSignatureShares = sandbox.stub(sdk_core_1.TssUtils.prototype, 'deleteSignatureShares');
            const prebuildTransaction = sandbox.stub(sdk_core_1.Wallet.prototype, 'prebuildTransaction');
            const build = sandbox.stub(sdk_core_1.StakingWallet.prototype, 'build');
            const txPrebuild = {
                walletId: stakingWallet.walletId,
                txHex: 'hex',
                buildParams: transaction.buildParams,
            };
            prebuildTransaction.resolves(txPrebuild);
            prebuildTransaction.calledOnceWithExactly(transaction.buildParams);
            const formattedParams = {
                ...stakingWallet_1.default.buildParams,
                coin: stakingWallet.coin,
                walletId: stakingWallet.walletId,
                walletType: stakingWallet.wallet.type(),
                preview: true,
            };
            const stakingTransaction = await stakingWallet.prebuildSelfManagedStakingTransaction(transaction);
            sandbox.assert.calledOnce(prebuildTransaction);
            sandbox.assert.notCalled(build);
            sandbox.assert.notCalled(deleteSignatureShares);
            const expected = await stakingWallet.wallet.prebuildTransaction(formattedParams);
            stakingTransaction.should.deepEqual(expected);
            should.exist(stakingTransaction);
        });
        it('should prebuild self-managed staking transaction - no build params', async function () {
            const transaction = stakingWallet_1.default.transaction('READY', undefined, true);
            nock(microservicesUri)
                .get(`/api/staking/v1/${stakingWallet.coin}/wallets/${stakingWallet.walletId}/requests/${transaction.stakingRequestId}/transactions/${transaction.id}`)
                .query({ expandBuildParams: true })
                .reply(200, transaction);
            const deleteSignatureShares = sandbox.stub(sdk_core_1.TssUtils.prototype, 'deleteSignatureShares');
            const prebuildTransaction = sandbox.stub(sdk_core_1.Wallet.prototype, 'prebuildTransaction');
            const build = sandbox.stub(sdk_core_1.StakingWallet.prototype, 'build');
            const txPrebuild = {
                walletId: stakingWallet.walletId,
                txHex: 'hex',
            };
            prebuildTransaction.resolves(txPrebuild);
            if (transaction.txRequestId) {
                deleteSignatureShares.calledOnceWithExactly(transaction.txRequestId);
            }
            const formattedParams = {
                ...stakingWallet_1.default.buildParams,
                coin: stakingWallet.coin,
                walletId: stakingWallet.walletId,
                walletType: stakingWallet.wallet.type(),
                preview: true,
            };
            const stakingTransaction = await stakingWallet.prebuildSelfManagedStakingTransaction(transaction);
            sandbox.assert.calledOnce(prebuildTransaction);
            sandbox.assert.notCalled(build);
            sandbox.assert.calledOnce(deleteSignatureShares);
            const expected = await stakingWallet.wallet.prebuildTransaction(formattedParams);
            stakingTransaction.should.deepEqual(expected);
            should.exist(stakingTransaction);
        });
    });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Rha2luZ1dhbGxldENvbW1vbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Rlc3QvdjIvdW5pdC9zdGFraW5nL3N0YWtpbmdXYWxsZXRDb21tb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw2QkFBNkI7QUFDN0IsaUNBQWlDO0FBQ2pDLHdFQUE0RDtBQUU1RCw4Q0FBNEc7QUFDNUcsOENBQTRDO0FBQzVDLHlDQUF3QztBQUN4QywrQkFBK0I7QUFFL0IsUUFBUSxDQUFDLHVCQUF1QixFQUFFO0lBQ2hDLE1BQU0sZ0JBQWdCLEdBQUcsdUJBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDbEQsSUFBSSxLQUFLLENBQUM7SUFDVixJQUFJLFFBQVEsQ0FBQztJQUNiLElBQUksVUFBVSxDQUFDO0lBQ2YsSUFBSSxhQUE0QixDQUFDO0lBRWpDLE1BQU0sQ0FBQztRQUNMLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxXQUFLLEVBQUUsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLGdCQUFnQixFQUFTLENBQUMsQ0FBQztRQUM1RSxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUMzQixRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM3QixRQUFRLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDckIsVUFBVSxHQUFHLElBQUkscUJBQVUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxFQUFFLGtDQUFrQyxFQUFFLElBQUksRUFBRSxpQkFBaUIsRUFBRSxDQUFDLENBQUM7UUFDbEgsTUFBTSxVQUFVLEdBQUc7WUFDakIsRUFBRSxFQUFFLFVBQVU7WUFDZCxJQUFJLEVBQUUsS0FBSztZQUNYLFVBQVUsRUFBRSxVQUFVLENBQUMsRUFBRTtZQUN6QixJQUFJLEVBQUUsQ0FBQywwQkFBMEIsQ0FBQztTQUNuQyxDQUFDO1FBQ0YsTUFBTSxN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QUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2hDLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLHFCQUFxQixDQUFDLENBQUM7WUFFakQsTUFBTSxRQUFRLEdBQUcsTUFBTSxhQUFhLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBRWpGLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDOUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ25DLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIG5vY2sgZnJvbSAnbm9jayc7XG5pbXBvcnQgKiBhcyBzaG91bGQgZnJvbSAnc2hvdWxkJztcbmltcG9ydCBmaXh0dXJlcyBmcm9tICcuLi8uLi9maXh0dXJlcy9zdGFraW5nL3N0YWtpbmdXYWxsZXQnO1xuXG5pbXBvcnQgeyBFbnRlcnByaXNlLCBFbnZpcm9ubWVudHMsIFN0YWtpbmdSZXF1ZXN0LCBTdGFraW5nV2FsbGV0LCBUc3NVdGlscywgV2FsbGV0IH0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCB7IFRlc3RCaXRHbyB9IGZyb20gJ0BiaXRnby9zZGstdGVzdCc7XG5pbXBvcnQgeyBCaXRHbyB9IGZyb20gJy4uLy4uLy4uLy4uL3NyYyc7XG5pbXBvcnQgKiBhcyBzaW5vbiBmcm9tICdzaW5vbic7XG5cbmRlc2NyaWJlKCdTdGFraW5nIFdhbGxldCBDb21tb24nLCBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IG1pY3Jvc2VydmljZXNVcmkgPSBFbnZpcm9ubWVudHNbJ21vY2snXS51cmk7XG4gIGxldCBiaXRnbztcbiAgbGV0IGJhc2VDb2luO1xuICBsZXQgZW50ZXJwcmlzZTtcbiAgbGV0IHN0YWtpbmdXYWxsZXQ6IFN0YWtpbmdXYWxsZXQ7XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJywgbWljcm9zZXJ2aWNlc1VyaSB9IGFzIGFueSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgYmFzZUNvaW4gPSBiaXRnby5jb2luKCdldGgnKTtcbiAgICBiYXNlQ29pbi5rZXljaGFpbnMoKTtcbiAgICBlbnRlcnByaXNlID0gbmV3IEVudGVycHJpc2UoYml0Z28sIGJhc2VDb2luLCB7IGlkOiAnNWNmOTQwOTQ5NDQ5NDEyZDAwZjUzYjNkOTJkYmNhYTMnLCBuYW1lOiAnVGVzdCBFbnRlcnByaXNlJyB9KTtcbiAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgaWQ6ICd3YWxsZXRJZCcsXG4gICAgICBjb2luOiAnZXRoJyxcbiAgICAgIGVudGVycHJpc2U6IGVudGVycHJpc2UuaWQsXG4gICAgICBrZXlzOiBbJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NSddLFxuICAgIH07XG4gICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZUNvaW4sIHdhbGxldERhdGEpO1xuICAgIHN0YWtpbmdXYWxsZXQgPSB3YWxsZXQudG9TdGFraW5nV2FsbGV0KCk7XG4gIH0pO1xuXG4gIGNvbnN0IHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG5cbiAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICBzYW5kYm94LnZlcmlmeUFuZFJlc3RvcmUoKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3N0YWtlJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY2FsbCBzdGFraW5nLXNlcnZpY2UgdG8gc3Rha2UnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBlY3RlZCA9IGZpeHR1cmVzLnN0YWtpbmdSZXF1ZXN0KFtmaXh0dXJlcy50cmFuc2FjdGlvbignTkVXJyldKTtcbiAgICAgIGNvbnN0IG1zU2NvcGUgPSBub2NrKG1pY3Jvc2VydmljZXNVcmkpXG4gICAgICAgIC5wb3N0KGAvYXBpL3N0YWtpbmcvdjEvJHtzdGFraW5nV2FsbGV0LmNvaW59L3dhbGxldHMvJHtzdGFraW5nV2FsbGV0LndhbGxldElkfS9yZXF1ZXN0c2AsIHtcbiAgICAgICAgICBhbW91bnQ6ICcxJyxcbiAgICAgICAgICBjbGllbnRJZDogJ2NsaWVudElkJyxcbiAgICAgICAgICB0eXBlOiAnU1RBS0UnLFxuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAxLCBleHBlY3RlZCk7XG5cbiAgICAgIGNvbnN0IHN0YWtpbmdSZXF1ZXN0ID0gYXdhaXQgc3Rha2luZ1dhbGxldC5zdGFrZSh7XG4gICAgICAgIGFtb3VudDogJzEnLFxuICAgICAgICBjbGllbnRJZDogJ2NsaWVudElkJyxcbiAgICAgIH0pO1xuXG4gICAgICBzaG91bGQuZXhpc3Qoc3Rha2luZ1JlcXVlc3QpO1xuXG4gICAgICBzdGFraW5nUmVxdWVzdC5zaG91bGQuZGVlcEVxdWFsKGV4cGVjdGVkKTtcbiAgICAgIG1zU2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY2FsbCBzdGFraW5nLXNlcnZpY2UgdG8gc3Rha2Ugd2l0aCBvcHRpb25hbCBwYXJhbWV0ZXJzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwZWN0ZWQgPSBmaXh0dXJlcy5zdGFraW5nUmVxdWVzdChbZml4dHVyZXMudHJhbnNhY3Rpb24oJ05FVycpXSk7XG4gICAgICBjb25zdCBtc1Njb3BlID0gbm9jayhtaWNyb3NlcnZpY2VzVXJpKVxuICAgICAgICAucG9zdChgL2FwaS9zdGFraW5nL3YxLyR7c3Rha2luZ1dhbGxldC5jb2lufS93YWxsZXRzLyR7c3Rha2luZ1dhbGxldC53YWxsZXRJZH0vcmVxdWVzdHNgLCB7XG4gICAgICAgICAgYW1vdW50OiAnMScsXG4gICAgICAgICAgY2xpZW50SWQ6ICdjbGllbnRJZCcsXG4gICAgICAgICAgdHlwZTogJ1NUQUtFJyxcbiAgICAgICAgICB2YWxpZGF0b3I6ICcxMjMnLFxuICAgICAgICAgIGR1cmF0aW9uU2Vjb25kczogJzYwJyxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMSwgZXhwZWN0ZWQpO1xuXG4gICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICBhbW91bnQ6ICcxJyxcbiAgICAgICAgY2xpZW50SWQ6ICdjbGllbnRJZCcsXG4gICAgICAgIHZhbGlkYXRvcjogJzEyMycsXG4gICAgICAgIGR1cmF0aW9uU2Vjb25kczogJzYwJyxcbiAgICAgIH07XG4gICAgICBjb25zdCBzdGFraW5nUmVxdWVzdCA9IGF3YWl0IHN0YWtpbmdXYWxsZXQuc3Rha2Uob3B0aW9ucyk7XG5cbiAgICAgIHNob3VsZC5leGlzdChzdGFraW5nUmVxdWVzdCk7XG5cbiAgICAgIHN0YWtpbmdSZXF1ZXN0LnNob3VsZC5kZWVwRXF1YWwoZXhwZWN0ZWQpO1xuICAgICAgbXNTY29wZS5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjYWxsIHN0YWtpbmctc2VydmljZSB0byBzdGFrZSB3aXRoIG9wdGlvbmFsIHN0YWtlTWFueSBwYXJhbWV0ZXJzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwZWN0ZWQgPSBmaXh0dXJlcy5zdGFraW5nUmVxdWVzdChbZml4dHVyZXMudHJhbnNhY3Rpb24oJ05FVycpXSk7XG4gICAgICBjb25zdCBtc1Njb3BlID0gbm9jayhtaWNyb3NlcnZpY2VzVXJpKVxuICAgICAgICAucG9zdChgL2FwaS9zdGFraW5nL3YxLyR7c3Rha2luZ1dhbGxldC5jb2lufS93YWxsZXRzLyR7c3Rha2luZ1dhbGxldC53YWxsZXRJZH0vcmVxdWVzdHNgLCB7XG4gICAgICAgICAgY2xpZW50SWQ6ICdjbGllbnRJZCcsXG4gICAgICAgICAgdHlwZTogJ1NUQUtFJyxcbiAgICAgICAgICBkZWxlZ2F0aW9uUmVxdWVzdHM6IFtcbiAgICAgICAgICAgIHsgYW1vdW50OiAnMScsIHZhbGlkYXRvcjogJzEyMycgfSxcbiAgICAgICAgICAgIHsgYW1vdW50OiAnMicsIHZhbGlkYXRvcjogJzQ1NicgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGR1cmF0aW9uU2Vjb25kczogJzYwJyxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMSwgZXhwZWN0ZWQpO1xuXG4gICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICBjbGllbnRJZDogJ2NsaWVudElkJyxcbiAgICAgICAgZGVsZWdhdGlvblJlcXVlc3RzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICcxJywgdmFsaWRhdG9yOiAnMTIzJyB9LFxuICAgICAgICAgIHsgYW1vdW50OiAnMicsIHZhbGlkYXRvcjogJzQ1NicgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZHVyYXRpb25TZWNvbmRzOiAnNjAnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHN0YWtpbmdSZXF1ZXN0ID0gYXdhaXQgc3Rha2luZ1dhbGxldC5zdGFrZShvcHRpb25zKTtcblxuICAgICAgc2hvdWxkLmV4aXN0KHN0YWtpbmdSZXF1ZXN0KTtcblxuICAgICAgc3Rha2luZ1JlcXVlc3Quc2hvdWxkLmRlZXBFcXVhbChleHBlY3RlZCk7XG4gICAgICBtc1Njb3BlLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd1bnN0YWtlJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY2FsbCBzdGFraW5nLXNlcnZpY2UgdG8gdW5zdGFrZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkID0gZml4dHVyZXMuc3Rha2luZ1JlcXVlc3QoW2ZpeHR1cmVzLnRyYW5zYWN0aW9uKCdORVcnKV0pO1xuICAgICAgY29uc3QgbXNTY29wZSA9IG5vY2sobWljcm9zZXJ2aWNlc1VyaSlcbiAgICAgICAgLnBvc3QoYC9hcGkvc3Rha2luZy92MS8ke3N0YWtpbmdXYWxsZXQuY29pbn0vd2FsbGV0cy8ke3N0YWtpbmdXYWxsZXQud2FsbGV0SWR9L3JlcXVlc3RzYCwge1xuICAgICAgICAgIGFtb3VudDogJzEnLFxuICAgICAgICAgIGNsaWVudElkOiAnY2xpZW50SWQnLFxuICAgICAgICAgIHR5cGU6ICdVTlNUQUtFJyxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMSwgZXhwZWN0ZWQpO1xuXG4gICAgICBjb25zdCBzdGFraW5nUmVxdWVzdCA9IGF3YWl0IHN0YWtpbmdXYWxsZXQudW5zdGFrZSh7XG4gICAgICAgIGFtb3VudDogJzEnLFxuICAgICAgICBjbGllbnRJZDogJ2NsaWVudElkJyxcbiAgICAgIH0pO1xuXG4gICAgICBzaG91bGQuZXhpc3Qoc3Rha2luZ1JlcXVlc3QpO1xuXG4gICAgICBzdGFraW5nUmVxdWVzdC5zaG91bGQuZGVlcEVxdWFsKGV4cGVjdGVkKTtcbiAgICAgIG1zU2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3N3aXRjaCB2YWxpZGF0b3InLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBjYWxsIHN0YWtpbmctc2VydmljZSB0byBzd2l0Y2ggdmFsaWRhdG9yJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwZWN0ZWQgPSBmaXh0dXJlcy5zdGFraW5nUmVxdWVzdChbZml4dHVyZXMudHJhbnNhY3Rpb24oJ05FVycpXSk7XG4gICAgICBjb25zdCBtc1Njb3BlID0gbm9jayhtaWNyb3NlcnZpY2VzVXJpKVxuICAgICAgICAucG9zdChgL2FwaS9zdGFraW5nL3YxLyR7c3Rha2luZ1dhbGxldC5jb2lufS93YWxsZXRzLyR7c3Rha2luZ1dhbGxldC53YWxsZXRJZH0vcmVxdWVzdHNgLCB7XG4gICAgICAgICAgYW1vdW50OiAnMScsXG4gICAgICAgICAgY2xpZW50SWQ6ICdjbGllbnRJZCcsXG4gICAgICAgICAgdmFsaWRhdG9yOiAndmFsaWRhdG9yJyxcbiAgICAgICAgICBkZWxlZ2F0aW9uSWQ6ICdkZWxlZ2F0aW9uJyxcbiAgICAgICAgICB0eXBlOiAnU1dJVENIX1ZBTElEQVRPUicsXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDEsIGV4cGVjdGVkKTtcblxuICAgICAgY29uc3Qgc3Rha2luZ1JlcXVlc3QgPSBhd2FpdCBzdGFraW5nV2FsbGV0LnN3aXRjaFZhbGlkYXRvcih7XG4gICAgICAgIGFtb3VudDogJzEnLFxuICAgICAgICBjbGllbnRJZDogJ2NsaWVudElkJyxcbiAgICAgICAgdmFsaWRhdG9yOiAndmFsaWRhdG9yJyxcbiAgICAgICAgZGVsZWdhdGlvbklkOiAnZGVsZWdhdGlvbicsXG4gICAgICB9KTtcblxuICAgICAgc2hvdWxkLmV4aXN0KHN0YWtpbmdSZXF1ZXN0KTtcblxuICAgICAgc3Rha2luZ1JlcXVlc3Quc2hvdWxkLmRlZXBFcXVhbChleHBlY3RlZCk7XG4gICAgICBtc1Njb3BlLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdjbGFpbSByZXdhcmRzJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY2FsbCBzdGFraW5nLXNlcnZpY2UgdG8gY2xhaW0gcmV3YXJkcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkID0gZml4dHVyZXMuc3Rha2luZ1JlcXVlc3QoW2ZpeHR1cmVzLnRyYW5zYWN0aW9uKCdORVcnKV0pO1xuICAgICAgY29uc3QgbXNTY29wZSA9IG5vY2sobWljcm9zZXJ2aWNlc1VyaSlcbiAgICAgICAgLnBvc3QoYC9hcGkvc3Rha2luZy92MS8ke3N0YWtpbmdXYWxsZXQuY29pbn0vd2FsbGV0cy8ke3N0YWtpbmdXYWxsZXQud2FsbGV0SWR9L3JlcXVlc3RzYCwge1xuICAgICAgICAgIGFtb3VudDogJzEnLFxuICAgICAgICAgIGNsaWVudElkOiAnY2xpZW50SWQnLFxuICAgICAgICAgIGRlbGVnYXRpb25JZDogJ2RlbGVnYXRpb24nLFxuICAgICAgICAgIHR5cGU6ICdDTEFJTV9SRVdBUkRTJyxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMSwgZXhwZWN0ZWQpO1xuXG4gICAgICBjb25zdCBzdGFraW5nUmVxdWVzdCA9IGF3YWl0IHN0YWtpbmdXYWxsZXQuY2xhaW1SZXdhcmRzKHtcbiAgICAgICAgYW1vdW50OiAnMScsXG4gICAgICAgIGNsaWVudElkOiAnY2xpZW50SWQnLFxuICAgICAgICBkZWxlZ2F0aW9uSWQ6ICdkZWxlZ2F0aW9uJyxcbiAgICAgIH0pO1xuXG4gICAgICBzaG91bGQuZXhpc3Qoc3Rha2luZ1JlcXVlc3QpO1xuXG4gICAgICBzdGFraW5nUmVxdWVzdC5zaG91bGQuZGVlcEVxdWFsKGV4cGVjdGVkKTtcbiAgICAgIG1zU2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2NhbmNlbFN0YWtpbmdSZXF1ZXN0JywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY2FsbCBzdGFraW5nLXNlcnZpY2UgdG8gY2FuY2VsIHN0YWtpbmcgcmVxdWVzdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHN0YWtpbmdSZXF1ZXN0SWQgPSAnODYzODI4NGEtZGFiMi00NmI5LWIwN2YtMjExMDlhNmU3MjIwJztcbiAgICAgIGNvbnN0IGV4cGVjdGVkID0ge1xuICAgICAgICAuLi5maXh0dXJlcy5zdGFraW5nUmVxdWVzdChbZml4dHVyZXMudHJhbnNhY3Rpb24oJ1JFSkVDVEVEJyldKSxcbiAgICAgICAgc3RhdHVzOiAnUkVKRUNURUQnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IG1zU2NvcGUgPSBub2NrKG1pY3Jvc2VydmljZXNVcmkpXG4gICAgICAgIC5kZWxldGUoYC9hcGkvc3Rha2luZy92MS8ke3N0YWtpbmdXYWxsZXQuY29pbn0vd2FsbGV0cy8ke3N0YWtpbmdXYWxsZXQud2FsbGV0SWR9L3JlcXVlc3RzLyR7c3Rha2luZ1JlcXVlc3RJZH1gKVxuICAgICAgICAucmVwbHkoMjAwLCBleHBlY3RlZCk7XG5cbiAgICAgIGNvbnN0IHN0YWtpbmdSZXF1ZXN0ID0gYXdhaXQgc3Rha2luZ1dhbGxldC5jYW5jZWxTdGFraW5nUmVxdWVzdChzdGFraW5nUmVxdWVzdElkKTtcblxuICAgICAgc2hvdWxkLmV4aXN0KHN0YWtpbmdSZXF1ZXN0KTtcblxuICAgICAgc3Rha2luZ1JlcXVlc3Quc2hvdWxkLmRlZXBFcXVhbChleHBlY3RlZCk7XG4gICAgICBtc1Njb3BlLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdnZXRTdGFraW5nUmVxdWVzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGNhbGwgc3Rha2luZy1zZXJ2aWNlIHRvIGdldCBzdGFraW5nIHJlcXVlc3QnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzdGFraW5nUmVxdWVzdElkID0gJzg2MzgyODRhLWRhYjItNDZiOS1iMDdmLTIxMTA5YTZlNzIyMCc7XG4gICAgICBjb25zdCBleHBlY3RlZCA9IGZpeHR1cmVzLnN0YWtpbmdSZXF1ZXN0KFtmaXh0dXJlcy50cmFuc2FjdGlvbignTkVXJyldKTtcbiAgICAgIGNvbnN0IG1zU2NvcGUgPSBub2NrKG1pY3Jvc2VydmljZXNVcmkpXG4gICAgICAgIC5nZXQoYC9hcGkvc3Rha2luZy92MS8ke3N0YWtpbmdXYWxsZXQuY29pbn0vd2FsbGV0cy8ke3N0YWtpbmdXYWxsZXQud2FsbGV0SWR9L3JlcXVlc3RzLyR7c3Rha2luZ1JlcXVlc3RJZH1gKVxuICAgICAgICAucmVwbHkoMjAwLCBleHBlY3RlZCk7XG5cbiAgICAgIGNvbnN0IHN0YWtpbmdSZXF1ZXN0ID0gYXdhaXQgc3Rha2luZ1dhbGxldC5nZXRTdGFraW5nUmVxdWVzdChzdGFraW5nUmVxdWVzdElkKTtcblxuICAgICAgc2hvdWxkLmV4aXN0KHN0YWtpbmdSZXF1ZXN0KTtcblxuICAgICAgc3Rha2luZ1JlcXVlc3Quc2hvdWxkLmRlZXBFcXVhbChleHBlY3RlZCk7XG4gICAgICBtc1Njb3BlLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdnZXRUcmFuc2FjdGlvbnNSZWFkeVRvU2lnbicsIGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBtb2NrR2V0U3Rha2luZ1JlcXVlc3Qoc3Rha2luZ1JlcXVlc3RJZDogc3RyaW5nLCBleHBlY3RlZDogU3Rha2luZ1JlcXVlc3QpIHtcbiAgICAgIHJldHVybiBub2NrKG1pY3Jvc2VydmljZXNVcmkpXG4gICAgICAgIC5nZXQoYC9hcGkvc3Rha2luZy92MS8ke3N0YWtpbmdXYWxsZXQuY29pbn0vd2FsbGV0cy8ke3N0YWtpbmdXYWxsZXQud2FsbGV0SWR9L3JlcXVlc3RzLyR7c3Rha2luZ1JlcXVlc3RJZH1gKVxuICAgICAgICAucmVwbHkoMjAwLCBleHBlY3RlZCk7XG4gICAgfVxuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYWxsU2lnbmluZ0NvbXBsZXRlIGZhbHNlIHdoZW4gbm8gdHJhbnNhY3Rpb25zIGV4aXN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc3Rha2luZ1JlcXVlc3RJZCA9ICc4NjM4Mjg0YS1kYWIyLTQ2YjktYjA3Zi0yMTEwOWE2ZTcyMjAnO1xuICAgICAgY29uc3QgZXhwZWN0ZWQgPSBmaXh0dXJlcy5zdGFraW5nUmVxdWVzdChbXSk7XG4gICAgICBjb25zdCBtc1Njb3BlID0gbW9ja0dldFN0YWtpbmdSZXF1ZXN0KHN0YWtpbmdSZXF1ZXN0SWQsIGV4cGVjdGVkKTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb25zUmVhZHlUb1NpZ24gPSBhd2FpdCBzdGFraW5nV2FsbGV0LmdldFRyYW5zYWN0aW9uc1JlYWR5VG9TaWduKHN0YWtpbmdSZXF1ZXN0SWQpO1xuXG4gICAgICBzaG91bGQuZXhpc3QodHJhbnNhY3Rpb25zUmVhZHlUb1NpZ24pO1xuICAgICAgdHJhbnNhY3Rpb25zUmVhZHlUb1NpZ24uYWxsU2lnbmluZ0NvbXBsZXRlLnNob3VsZC5iZS5GYWxzZSgpO1xuICAgICAgdHJhbnNhY3Rpb25zUmVhZHlUb1NpZ24udHJhbnNhY3Rpb25zLnNob3VsZC5iZS5lbXB0eSgpO1xuXG4gICAgICBtc1Njb3BlLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBhbGxTaWduaW5nQ29tcGxldGUgdHJ1ZSBhbmQgMCB0cmFuc2FjdGlvbnMgd2hlbiBvbmx5IGEgQ09ORklSTUVEIHRyYW5zYWN0aW9uIGV4aXN0cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHN0YWtpbmdSZXF1ZXN0SWQgPSAnODYzODI4NGEtZGFiMi00NmI5LWIwN2YtMjExMDlhNmU3MjIwJztcbiAgICAgIGNvbnN0IGV4cGVjdGVkID0gZml4dHVyZXMuc3Rha2luZ1JlcXVlc3QoW2ZpeHR1cmVzLnRyYW5zYWN0aW9uKCdDT05GSVJNRUQnKV0pO1xuICAgICAgY29uc3QgbXNTY29wZSA9IG1vY2tHZXRTdGFraW5nUmVxdWVzdChzdGFraW5nUmVxdWVzdElkLCBleHBlY3RlZCk7XG5cbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uc1JlYWR5VG9TaWduID0gYXdhaXQgc3Rha2luZ1dhbGxldC5nZXRUcmFuc2FjdGlvbnNSZWFkeVRvU2lnbihzdGFraW5nUmVxdWVzdElkKTtcblxuICAgICAgc2hvdWxkLmV4aXN0KHRyYW5zYWN0aW9uc1JlYWR5VG9TaWduKTtcbiAgICAgIHRyYW5zYWN0aW9uc1JlYWR5VG9TaWduLmFsbFNpZ25pbmdDb21wbGV0ZS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgICAgdHJhbnNhY3Rpb25zUmVhZHlUb1NpZ24udHJhbnNhY3Rpb25zLnNob3VsZC5iZS5lbXB0eSgpO1xuXG4gICAgICBtc1Njb3BlLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBhbGxTaWduaW5nQ29tcGxldGUgZmFsc2UgYW5kIDAgdHJhbnNhY3Rpb25zIHdoZW4gb25seSBhIE5FVyB0cmFuc2FjdGlvbiBleGlzdHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzdGFraW5nUmVxdWVzdElkID0gJzg2MzgyODRhLWRhYjItNDZiOS1iMDdmLTIxMTA5YTZlNzIyMCc7XG4gICAgICBjb25zdCBleHBlY3RlZFN0YWtpbmdSZXF1ZXN0ID0gZml4dHVyZXMuc3Rha2luZ1JlcXVlc3QoW2ZpeHR1cmVzLnRyYW5zYWN0aW9uKCdORVcnKV0pO1xuICAgICAgY29uc3QgbXNTY29wZSA9IG1vY2tHZXRTdGFraW5nUmVxdWVzdChzdGFraW5nUmVxdWVzdElkLCBleHBlY3RlZFN0YWtpbmdSZXF1ZXN0KTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb25zUmVhZHlUb1NpZ24gPSBhd2FpdCBzdGFraW5nV2FsbGV0LmdldFRyYW5zYWN0aW9uc1JlYWR5VG9TaWduKHN0YWtpbmdSZXF1ZXN0SWQpO1xuXG4gICAgICBzaG91bGQuZXhpc3QodHJhbnNhY3Rpb25zUmVhZHlUb1NpZ24pO1xuICAgICAgdHJhbnNhY3Rpb25zUmVhZHlUb1NpZ24uYWxsU2lnbmluZ0NvbXBsZXRlLnNob3VsZC5iZS5GYWxzZSgpO1xuICAgICAgdHJhbnNhY3Rpb25zUmVhZHlUb1NpZ24udHJhbnNhY3Rpb25zLnNob3VsZC5iZS5lbXB0eSgpO1xuXG4gICAgICBtc1Njb3BlLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBhbGxTaWduaW5nQ29tcGxldGUgZmFsc2UgYW5kIDEgdHJhbnNhY3Rpb25zIHdoZW4gb25seSBhIFJFQURZIHRyYW5zYWN0aW9uIGV4aXN0cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHN0YWtpbmdSZXF1ZXN0SWQgPSAnODYzODI4NGEtZGFiMi00NmI5LWIwN2YtMjExMDlhNmU3MjIwJztcbiAgICAgIGNvbnN0IGV4cGVjdGVkVHJhbnNhY3Rpb24gPSBmaXh0dXJlcy50cmFuc2FjdGlvbignUkVBRFknKTtcbiAgICAgIGNvbnN0IGV4cGVjdGVkU3Rha2luZ1JlcXVlc3QgPSBmaXh0dXJlcy5zdGFraW5nUmVxdWVzdChbZXhwZWN0ZWRUcmFuc2FjdGlvbl0pO1xuICAgICAgY29uc3QgbXNTY29wZSA9IG1vY2tHZXRTdGFraW5nUmVxdWVzdChzdGFraW5nUmVxdWVzdElkLCBleHBlY3RlZFN0YWtpbmdSZXF1ZXN0KTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb25zUmVhZHlUb1NpZ24gPSBhd2FpdCBzdGFraW5nV2FsbGV0LmdldFRyYW5zYWN0aW9uc1JlYWR5VG9TaWduKHN0YWtpbmdSZXF1ZXN0SWQpO1xuXG4gICAgICBzaG91bGQuZXhpc3QodHJhbnNhY3Rpb25zUmVhZHlUb1NpZ24pO1xuICAgICAgdHJhbnNhY3Rpb25zUmVhZHlUb1NpZ24uYWxsU2lnbmluZ0NvbXBsZXRlLnNob3VsZC5iZS5GYWxzZSgpO1xuICAgICAgdHJhbnNhY3Rpb25zUmVhZHlUb1NpZ24udHJhbnNhY3Rpb25zLnNob3VsZC5jb250YWluRXFsKGV4cGVjdGVkVHJhbnNhY3Rpb24pO1xuXG4gICAgICBtc1Njb3BlLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBhbGxTaWduaW5nQ29tcGxldGUgZmFsc2UgYW5kIDEgdHJhbnNhY3Rpb24gd2hlbiBORVcgYW5kIFJFQURZIHRyYW5zYWN0aW9uIGV4aXN0cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHN0YWtpbmdSZXF1ZXN0SWQgPSAnODYzODI4NGEtZGFiMi00NmI5LWIwN2YtMjExMDlhNmU3MjIwJztcbiAgICAgIGNvbnN0IGV4cGVjdGVkVHJhbnNhY3Rpb24gPSBmaXh0dXJlcy50cmFuc2FjdGlvbignUkVBRFknKTtcbiAgICAgIGNvbnN0IGV4cGVjdGVkU3Rha2luZ1JlcXVlc3QgPSBmaXh0dXJlcy5zdGFraW5nUmVxdWVzdChbZXhwZWN0ZWRUcmFuc2FjdGlvbiwgZml4dHVyZXMudHJhbnNhY3Rpb24oJ05FVycpXSk7XG4gICAgICBjb25zdCBtc1Njb3BlID0gbW9ja0dldFN0YWtpbmdSZXF1ZXN0KHN0YWtpbmdSZXF1ZXN0SWQsIGV4cGVjdGVkU3Rha2luZ1JlcXVlc3QpO1xuXG4gICAgICBjb25zdCB0cmFuc2FjdGlvbnNSZWFkeVRvU2lnbiA9IGF3YWl0IHN0YWtpbmdXYWxsZXQuZ2V0VHJhbnNhY3Rpb25zUmVhZHlUb1NpZ24oc3Rha2luZ1JlcXVlc3RJZCk7XG5cbiAgICAgIHNob3VsZC5leGlzdCh0cmFuc2FjdGlvbnNSZWFkeVRvU2lnbik7XG4gICAgICB0cmFuc2FjdGlvbnNSZWFkeVRvU2lnbi5hbGxTaWduaW5nQ29tcGxldGUuc2hvdWxkLmJlLkZhbHNlKCk7XG4gICAgICB0cmFuc2FjdGlvbnNSZWFkeVRvU2lnbi50cmFuc2FjdGlvbnMuc2hvdWxkLmNvbnRhaW5FcWwoZXhwZWN0ZWRUcmFuc2FjdGlvbik7XG5cbiAgICAgIG1zU2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3ByZWJ1aWxkU2VsZk1hbmFnZWRTdGFraW5nVHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBwcmVidWlsZCBzZWxmLW1hbmFnZWQgc3Rha2luZyB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gZml4dHVyZXMudHJhbnNhY3Rpb24oJ1JFQURZJywgZml4dHVyZXMuYnVpbGRQYXJhbXMsIGZhbHNlKTtcbiAgICAgIG5vY2sobWljcm9zZXJ2aWNlc1VyaSlcbiAgICAgICAgLmdldChcbiAgICAgICAgICBgL2FwaS9zdGFraW5nL3YxLyR7c3Rha2luZ1dhbGxldC5jb2lufS93YWxsZXRzLyR7c3Rha2luZ1dhbGxldC53YWxsZXRJZH0vcmVxdWVzdHMvJHt0cmFuc2FjdGlvbi5zdGFraW5nUmVxdWVzdElkfS90cmFuc2FjdGlvbnMvJHt0cmFuc2FjdGlvbi5pZH1gXG4gICAgICAgIClcbiAgICAgICAgLnF1ZXJ5KHsgZXhwYW5kQnVpbGRQYXJhbXM6IHRydWUgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwgdHJhbnNhY3Rpb24pO1xuXG4gICAgICBjb25zdCBkZWxldGVTaWduYXR1cmVTaGFyZXMgPSBzYW5kYm94LnN0dWIoVHNzVXRpbHMucHJvdG90eXBlLCAnZGVsZXRlU2lnbmF0dXJlU2hhcmVzJyk7XG4gICAgICBjb25zdCBwcmVidWlsZFRyYW5zYWN0aW9uID0gc2FuZGJveC5zdHViKFdhbGxldC5wcm90b3R5cGUsICdwcmVidWlsZFRyYW5zYWN0aW9uJyk7XG4gICAgICBjb25zdCBidWlsZCA9IHNhbmRib3guc3R1YihTdGFraW5nV2FsbGV0LnByb3RvdHlwZSwgJ2J1aWxkJyk7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB3YWxsZXRJZDogc3Rha2luZ1dhbGxldC53YWxsZXRJZCxcbiAgICAgICAgdHhIZXg6ICdoZXgnLFxuICAgICAgICBidWlsZFBhcmFtczogdHJhbnNhY3Rpb24uYnVpbGRQYXJhbXMsXG4gICAgICB9O1xuICAgICAgcHJlYnVpbGRUcmFuc2FjdGlvbi5yZXNvbHZlcyh0eFByZWJ1aWxkKTtcbiAgICAgIHByZWJ1aWxkVHJhbnNhY3Rpb24uY2FsbGVkT25jZVdpdGhFeGFjdGx5KHRyYW5zYWN0aW9uLmJ1aWxkUGFyYW1zKTtcbiAgICAgIGNvbnN0IGZvcm1hdHRlZFBhcmFtcyA9IHtcbiAgICAgICAgLi4uZml4dHVyZXMuYnVpbGRQYXJhbXMsXG4gICAgICAgIGNvaW46IHN0YWtpbmdXYWxsZXQuY29pbixcbiAgICAgICAgd2FsbGV0SWQ6IHN0YWtpbmdXYWxsZXQud2FsbGV0SWQsXG4gICAgICAgIHdhbGxldFR5cGU6IHN0YWtpbmdXYWxsZXQud2FsbGV0LnR5cGUoKSxcbiAgICAgICAgcHJldmlldzogdHJ1ZSxcbiAgICAgIH07XG4gICAgICBjb25zdCBzdGFraW5nVHJhbnNhY3Rpb24gPSBhd2FpdCBzdGFraW5nV2FsbGV0LnByZWJ1aWxkU2VsZk1hbmFnZWRTdGFraW5nVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pO1xuICAgICAgc2FuZGJveC5hc3NlcnQuY2FsbGVkT25jZShwcmVidWlsZFRyYW5zYWN0aW9uKTtcbiAgICAgIHNhbmRib3guYXNzZXJ0Lm5vdENhbGxlZChidWlsZCk7XG4gICAgICBzYW5kYm94LmFzc2VydC5ub3RDYWxsZWQoZGVsZXRlU2lnbmF0dXJlU2hhcmVzKTtcblxuICAgICAgY29uc3QgZXhwZWN0ZWQgPSBhd2FpdCBzdGFraW5nV2FsbGV0LndhbGxldC5wcmVidWlsZFRyYW5zYWN0aW9uKGZvcm1hdHRlZFBhcmFtcyk7XG4gICAgICBzdGFraW5nVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbChleHBlY3RlZCk7XG4gICAgICBzaG91bGQuZXhpc3Qoc3Rha2luZ1RyYW5zYWN0aW9uKTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkIHByZWJ1aWxkIHNlbGYtbWFuYWdlZCBzdGFraW5nIHRyYW5zYWN0aW9uIC0gbm8gYnVpbGQgcGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSBmaXh0dXJlcy50cmFuc2FjdGlvbignUkVBRFknLCB1bmRlZmluZWQsIHRydWUpO1xuICAgICAgbm9jayhtaWNyb3NlcnZpY2VzVXJpKVxuICAgICAgICAuZ2V0KFxuICAgICAgICAgIGAvYXBpL3N0YWtpbmcvdjEvJHtzdGFraW5nV2FsbGV0LmNvaW59L3dhbGxldHMvJHtzdGFraW5nV2FsbGV0LndhbGxldElkfS9yZXF1ZXN0cy8ke3RyYW5zYWN0aW9uLnN0YWtpbmdSZXF1ZXN0SWR9L3RyYW5zYWN0aW9ucy8ke3RyYW5zYWN0aW9uLmlkfWBcbiAgICAgICAgKVxuICAgICAgICAucXVlcnkoeyBleHBhbmRCdWlsZFBhcmFtczogdHJ1ZSB9KVxuICAgICAgICAucmVwbHkoMjAwLCB0cmFuc2FjdGlvbik7XG5cbiAgICAgIGNvbnN0IGRlbGV0ZVNpZ25hdHVyZVNoYXJlcyA9IHNhbmRib3guc3R1YihUc3NVdGlscy5wcm90b3R5cGUsICdkZWxldGVTaWduYXR1cmVTaGFyZXMnKTtcbiAgICAgIGNvbnN0IHByZWJ1aWxkVHJhbnNhY3Rpb24gPSBzYW5kYm94LnN0dWIoV2FsbGV0LnByb3RvdHlwZSwgJ3ByZWJ1aWxkVHJhbnNhY3Rpb24nKTtcbiAgICAgIGNvbnN0IGJ1aWxkID0gc2FuZGJveC5zdHViKFN0YWtpbmdXYWxsZXQucHJvdG90eXBlLCAnYnVpbGQnKTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHdhbGxldElkOiBzdGFraW5nV2FsbGV0LndhbGxldElkLFxuICAgICAgICB0eEhleDogJ2hleCcsXG4gICAgICB9O1xuICAgICAgcHJlYnVpbGRUcmFuc2FjdGlvbi5yZXNvbHZlcyh0eFByZWJ1aWxkKTtcbiAgICAgIGlmICh0cmFuc2FjdGlvbi50eFJlcXVlc3RJZCkge1xuICAgICAgICBkZWxldGVTaWduYXR1cmVTaGFyZXMuY2FsbGVkT25jZVdpdGhFeGFjdGx5KHRyYW5zYWN0aW9uLnR4UmVxdWVzdElkKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZvcm1hdHRlZFBhcmFtcyA9IHtcbiAgICAgICAgLi4uZml4dHVyZXMuYnVpbGRQYXJhbXMsXG4gICAgICAgIGNvaW46IHN0YWtpbmdXYWxsZXQuY29pbixcbiAgICAgICAgd2FsbGV0SWQ6IHN0YWtpbmdXYWxsZXQud2FsbGV0SWQsXG4gICAgICAgIHdhbGxldFR5cGU6IHN0YWtpbmdXYWxsZXQud2FsbGV0LnR5cGUoKSxcbiAgICAgICAgcHJldmlldzogdHJ1ZSxcbiAgICAgIH07XG4gICAgICBjb25zdCBzdGFraW5nVHJhbnNhY3Rpb24gPSBhd2FpdCBzdGFraW5nV2FsbGV0LnByZWJ1aWxkU2VsZk1hbmFnZWRTdGFraW5nVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pO1xuICAgICAgc2FuZGJveC5hc3NlcnQuY2FsbGVkT25jZShwcmVidWlsZFRyYW5zYWN0aW9uKTtcbiAgICAgIHNhbmRib3guYXNzZXJ0Lm5vdENhbGxlZChidWlsZCk7XG4gICAgICBzYW5kYm94LmFzc2VydC5jYWxsZWRPbmNlKGRlbGV0ZVNpZ25hdHVyZVNoYXJlcyk7XG5cbiAgICAgIGNvbnN0IGV4cGVjdGVkID0gYXdhaXQgc3Rha2luZ1dhbGxldC53YWxsZXQucHJlYnVpbGRUcmFuc2FjdGlvbihmb3JtYXR0ZWRQYXJhbXMpO1xuXG4gICAgICBzdGFraW5nVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbChleHBlY3RlZCk7XG4gICAgICBzaG91bGQuZXhpc3Qoc3Rha2luZ1RyYW5zYWN0aW9uKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==

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


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