PHP WebShell

Текущая директория: /opt/BitGoJS/modules/sdk-coin-eos/dist/test/unit

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

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/**
 * @prettier
 */
const sdk_api_1 = require("@bitgo/sdk-api");
const sdk_core_1 = require("@bitgo/sdk-core");
const sdk_test_1 = require("@bitgo/sdk-test");
const secp256k1_1 = require("@bitgo/secp256k1");
const ecc = __importStar(require("eosjs-ecc"));
const _ = __importStar(require("lodash"));
const should_1 = __importDefault(require("should"));
const sinon = __importStar(require("sinon"));
const src_1 = require("../../src");
const fixtures_1 = require("../fixtures");
const assert_1 = __importDefault(require("assert"));
describe('EOS:', function () {
    let bitgo;
    let basecoin;
    before(function () {
        bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
        bitgo.safeRegister('eos', src_1.Eos.createInstance);
        bitgo.safeRegister('teos', src_1.Teos.createInstance);
        bitgo.initializeTestVars();
        basecoin = bitgo.coin('teos');
    });
    it('should get address details', function () {
        let addressDetails = basecoin.getAddressDetails('i1skda3kso43');
        addressDetails.address.should.equal('i1skda3kso43');
        (0, should_1.default)(addressDetails.memoId).be.undefined();
        addressDetails = basecoin.getAddressDetails('ks13k3hdui24?memoId=1');
        addressDetails.address.should.equal('ks13k3hdui24');
        addressDetails.memoId.should.equal('1');
        (() => {
            basecoin.getAddressDetails('ks13k3hdui24?memoId=1&memoId=2');
        }).should.throw();
    });
    it('should get address details with alphanumeric memoid', function () {
        const addressDetails = basecoin.getAddressDetails('i1skda3kso43?memoId=123abc');
        addressDetails.address.should.equal('i1skda3kso43');
        addressDetails.memoId.should.equal('123abc');
    });
    it('should validate address', function () {
        basecoin.isValidAddress('i1skda3kso43').should.equal(true);
        basecoin.isValidAddress('ks13kdh245ls').should.equal(true);
        basecoin.isValidAddress('ks13k3hdui24?memoId=1').should.equal(true);
        basecoin.isValidAddress('ks13k3hdui24?memoId=x').should.equal(true);
    });
    it('verifyAddress should work', async function () {
        await basecoin.verifyAddress({
            address: 'i1skda3kso43',
            rootAddress: 'i1skda3kso43',
        });
        await basecoin.verifyAddress({
            address: 'ks13kdh245ls?memoId=1',
            rootAddress: 'ks13kdh245ls',
        });
        assert_1.default.rejects(basecoin.verifyAddress({ address: 'i1skda3kso43=x', rootAddress: 'i1skda3kso43' }));
        assert_1.default.rejects(basecoin.verifyAddress({ address: 'i1skda3kso43?memoId=243432', rootAddress: 'ks13kdh245ls' }));
        assert_1.default.rejects(basecoin.verifyAddress({ address: 'i1skda3kso43' }));
    });
    it('should generate valid random addresses', () => {
        for (let i = 0; i < 100; i++) {
            const address = basecoin.generateRandomAddress();
            basecoin.isValidAddress(address).should.be.true();
        }
    });
    it('isValidMemo should work', function () {
        basecoin.isValidMemo({ value: '1' }).should.equal(true);
        basecoin.isValidMemo({ value: 'uno' }).should.equal(true);
        basecoin.isValidMemo({ value: fixtures_1.EosInputs.string257CharsLong }).should.equal(false);
    });
    it('isValidMemoId should work', function () {
        basecoin.isValidMemoId('1').should.equal(true);
        basecoin.isValidMemoId('123abc').should.equal(true);
        basecoin.isValidMemoId(fixtures_1.EosInputs.string257CharsLong).should.equal(false);
    });
    it('should validate pub key', () => {
        const { pub } = basecoin.keychains().create();
        basecoin.isValidPub(pub).should.equal(true);
    });
    describe('Keypairs:', () => {
        it('should generate a keypair from random seed', function () {
            const keyPair = basecoin.generateKeyPair();
            keyPair.should.have.property('pub');
            keyPair.should.have.property('prv');
            basecoin.isValidPub(keyPair.pub).should.equal(true);
            basecoin.isValidPrv(keyPair.prv).should.equal(true);
        });
        it('should generate a keypair from seed', function () {
            const seed = Buffer.from('c3b09c24731be2851b641d9d5b3f60fa129695c24071768d15654bea207b7bb6', 'hex');
            const keyPair = basecoin.generateKeyPair(seed);
            keyPair.pub.should.equal('xpub661MyMwAqRbcF2SUqUMiqxWGwaVX6sH4okTtX8jxJ1A14wfL8W7jZEoNE537JqSESXFpTcXCZahPz7RKQLpAEGsVp233dc5CffLSecpU13X');
            keyPair.prv.should.equal('xprv9s21ZrQH143K2YN1jSpiUpZYPYf2hQZDSXYHikLLjfd2C9LBaxoV1SUtNnZGnXeyJ6uFWMbQTfjXqVfgNqRBw5yyaCtBK1AM8PF3XZtKjQp');
        });
    });
    it('should create unsigned recovery transaction without Bitgo', async function () {
        const userKey = 'xpub661MyMwAqRbcH1oUADxatLuKkVjaDB2zTNJoZQsGVQEvoogpbXJw24QMokNwFKj9Qhci6KWaCcQKrzpL4LCQXXX3YpTQxgD9KLBjhDrUWo4';
        const backupKey = 'xpub661MyMwAqRbcH1n6sgY29G7dAxL7twS8rt1jyuuQb1kfnA7s3FJPGoVqb9JenXkeJmC4jZ8iVscn3AH6MkYAVc61FTYCHpxv5cxWar5Jw3C';
        const rootAddress = 'i1skda3kso43';
        const destinationAddress = 'ks13kdh245ls';
        // mock responses to the block chain
        const sandBox = sinon.createSandbox();
        const callBack = sandBox.stub(src_1.Eos.prototype, 'getDataFromNode');
        callBack
            .withArgs({
            endpoint: '/v1/chain/get_account',
            payload: { account_name: rootAddress },
        })
            .resolves(fixtures_1.EosResponses.getAccountResponseSuccess1);
        callBack
            .withArgs({
            endpoint: '/v1/chain/get_account',
            payload: { account_name: destinationAddress },
        })
            .resolves(fixtures_1.EosResponses.getAccountResponseSuccess2);
        callBack
            .withArgs({
            endpoint: '/v1/chain/get_info',
        })
            .resolves(fixtures_1.EosResponses.getInfoResponseSuccess1);
        callBack
            .withArgs({
            endpoint: '/v1/chain/get_block',
            payload: { block_num_or_id: 191839472 },
        })
            .resolves(fixtures_1.EosResponses.getBlockResponseSuccess1);
        // can create unsigned recovery transaction
        const unsignedRecoveryTransaction = await basecoin.recover({
            userKey,
            backupKey,
            bitgoKey: 'key',
            recoveryDestination: destinationAddress,
            rootAddress,
        });
        unsignedRecoveryTransaction.recoveryAmount.should.equal('5.0000');
        unsignedRecoveryTransaction.transaction.signatures.length.should.equal(0);
        // coin and txHex fields are expected during recovery of unsigned transaction using OVC
        unsignedRecoveryTransaction.coin.should.equal('teos');
        unsignedRecoveryTransaction.txHex.should.equal('2a02a0053e5a8cf73a56ba0fda11e4d92e0238a4a2aa74fccf46d5a9107468408cdcdb60f03cf4a9e53c000000000100a6823403ea3055000000572d3ccdcd013008c5709804717000000000a8ed3232213008c57098047170806321a22538028650c300000000000004454f530000000000000000000000000000000000000000000000000000000000000000000000000000');
        // destination address and root address can include memoId
        const unsignedRecoveryTransaction2 = await basecoin.recover({
            userKey,
            backupKey,
            bitgoKey: 'key',
            recoveryDestination: `${destinationAddress}?memoId=0`,
            rootAddress: `${rootAddress}?memoId=0`,
        });
        unsignedRecoveryTransaction2.recoveryAmount.should.equal('5.0000');
        unsignedRecoveryTransaction2.transaction.signatures.length.should.equal(0);
        // coin and txHex fields are expected during recovery of unsigned transaction using OVC
        unsignedRecoveryTransaction.coin.should.equal('teos');
        unsignedRecoveryTransaction.txHex.should.equal('2a02a0053e5a8cf73a56ba0fda11e4d92e0238a4a2aa74fccf46d5a9107468408cdcdb60f03cf4a9e53c000000000100a6823403ea3055000000572d3ccdcd013008c5709804717000000000a8ed3232213008c57098047170806321a22538028650c300000000000004454f530000000000000000000000000000000000000000000000000000000000000000000000000000');
        sandBox.restore();
    });
    describe('Transactions:', function () {
        const testExplainTransaction = (input, expectedOutput) => async function () {
            const explainedTransaction = await basecoin.explainTransaction(input);
            should_1.default.exist(explainedTransaction);
            explainedTransaction.should.deepEqual(expectedOutput);
        };
        it('should generate a valid transaction signature', async function () {
            const signatureData = 'abcd';
            const tx = {
                txHex: signatureData,
                headers: {
                    ref_block_num: 1,
                    ref_block_prefix: 'asd',
                },
                transaction: {
                    signatures: [],
                    packed_trx: signatureData,
                    compression: 'none',
                },
                recipients: [{}],
            };
            const seed = Buffer.from('c3b09c24731be2851b624d9d5b3f60fa129695c24071768d15654bea207b7bb6', 'hex');
            const keyPair = basecoin.generateKeyPair(seed);
            const { halfSigned } = await basecoin.signTransaction({ txPrebuild: tx, prv: keyPair.prv });
            const signature = halfSigned.transaction.signatures[0];
            const hdNode = secp256k1_1.bip32.fromBase58(keyPair.pub);
            const eosPubkey = ecc.PublicKey.fromBuffer(hdNode.publicKey).toString();
            ecc.verify(signature, Buffer.from(signatureData, 'hex'), eosPubkey).should.eql(true);
        });
        it('should explain an EOS transaction', async function () {
            const explainTransactionParams = {
                headers: {
                    ref_block_prefix: 100,
                    ref_block_num: 995,
                    expiration: '2018-04-27T18:40:34.000Z',
                },
                transaction: {
                    packed_trx: 'a26ee35ae30364000000000000000100a6823403ea3055000000572d3ccdcd019013e48c8ce5eed400000000a8ed3232229013e48c8ce5eed4b012362b61b31236640000000000000004454f5300000000013100',
                },
            };
            const explainedTx = await basecoin.explainTransaction(explainTransactionParams);
            explainedTx.outputAmount.should.equal('100');
            explainedTx.outputs.length.should.equal(1);
            explainedTx.outputs[0].amount.should.equal('100');
            explainedTx.outputs[0].address.should.equal('asdfasdfasdf');
            explainedTx.id.should.equal('6132f3bf4a746e6ecad8a31df67d71b4741fc5b7c868ae36dde18309a91df8a6');
            explainedTx.memo.should.equal('1');
        });
        it('explains EOS native transfer transaction', testExplainTransaction(fixtures_1.EosInputs.explainTransactionInputNative, fixtures_1.EosResponses.explainTransactionOutputNative));
        it('explains CHEX token transfer transaction', testExplainTransaction(fixtures_1.EosInputs.explainTransactionInputChex, fixtures_1.EosResponses.explainTransactionOutputChex));
        it('explain EOS Unstake1 transaction', testExplainTransaction(fixtures_1.EosInputs.explainUnstakeInput1, fixtures_1.EosResponses.explainUnstakeOutput1));
        it('explain EOS Unstake2 transaction', testExplainTransaction(fixtures_1.EosInputs.explainUnstakeInput2, fixtures_1.EosResponses.explainUnstakeOutput2));
        it('explain EOS Refund transaction', testExplainTransaction(fixtures_1.EosInputs.explainRefundInput, fixtures_1.EosResponses.explainRefundOutput));
    });
    describe('Transaction Verification', function () {
        let wallet;
        let basecoin;
        let verification;
        let sandBox;
        let newTxPrebuild;
        let newTxParams;
        before(async () => {
            basecoin = bitgo.coin('teos');
            const walletData = {
                id: '5a78dd561c6258a907f1eeaee132f796',
                users: [
                    {
                        user: '543c11ed356d00cb7600000b98794503',
                        permissions: ['admin', 'view', 'spend'],
                    },
                ],
                coin: 'teos',
                label: 'Verification Wallet',
                m: 2,
                n: 3,
                keys: [
                    '5a78dd56bfe424aa07aa068651b194fd',
                    '5a78dd5674a70eb4079f58797dfe2f5e',
                    '5a78dd561c6258a907f1eea9f1d079e2',
                ],
                tags: ['5a78dd561c6258a907f1eeaee132f796'],
                disableTransactionNotifications: false,
                freeze: {},
                deleted: false,
                approvalsRequired: 1,
                isCold: true,
                coinSpecific: {},
                clientFlags: [],
                balance: 650000000,
                confirmedBalance: 650000000,
                spendableBalance: 650000000,
                balanceString: '650000000',
                confirmedBalanceString: '650000000',
                spendableBalanceString: '650000000',
                receiveAddress: {
                    id: '5a78de2bbfe424aa07aa131ec03c8dc1',
                    address: '78xczhaijyhek2',
                    chain: 0,
                    index: 0,
                    coin: 'teos',
                    wallet: '5a78dd561c6258a907f1eeaee132f796',
                    coinSpecific: {},
                },
                pendingApprovals: [],
            };
            wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
            const userKeychain = {
                prv: '5KJq565HTrgEJG9EbvJH5BLYTgioAyY27dT9am1kCtn2YVAJEYK',
                pub: 'EOS6g7AAMQkhXp8j73E8BD4KRwtQevEsFgYx8htaQkRVhhXJMgkMZ',
            };
            const backupKeychain = {
                prv: '5KZ1nXXCi5yXH8AjCJqjnCYHCVnhQa9YWGV2D14i8g221dxNwLW',
                pub: 'EOS7gyDLNk12faVb1aqNxj1L2DpBerFkhAsxBs95yW3yxJpqvg9Mt',
            };
            const txPrebuild = {
                recipients: [
                    {
                        address: 'lionteste212',
                        amount: '1000',
                    },
                ],
                headers: {
                    expiration: '2021-10-28T02:34:05.848',
                    ref_block_num: 42915,
                    ref_block_prefix: 1204086709,
                },
                txHex: '2a02a0053e5a8cf73a56ba0fda11e4d92e0238a4a2aa74fccf46d5a9107468401e0c7a61a3a7b5e7c4470000000100408c7a02ea3055000000000085269d00030233330100a6823403ea3055000000572d3ccdcd0120ceb8437333427c00000000a8ed32322220ceb8437333427c20825019ab3ca98be80300000000000004454f53000000000131000000000000000000000000000000000000000000000000000000000000000000',
                transaction: {
                    compression: 'none',
                    packed_trx: '1e0c7a61a3a7b5e7c4470000000100408c7a02ea3055000000000085269d00030233330100a6823403ea3055000000572d3ccdcd0120ceb8437333427c00000000a8ed32322220ceb8437333427c20825019ab3ca98be80300000000000004454f5300000000013100',
                    signatures: [],
                },
                txid: '586c5b59b10b134d04c16ac1b273fe3c5529f34aef75db4456cd469c5cdac7e2',
                isVotingTransaction: false,
                coin: 'teos',
            };
            verification = {
                disableNetworking: true,
                keychains: {
                    user: { pub: userKeychain.pub },
                    backup: { pub: backupKeychain.pub },
                },
            };
            const seed = Buffer.from('c3b09c24731be2851b624d9d5b3f60fa129695c24071768d15654bea207b7bb6', 'hex');
            const keyPair = basecoin.generateKeyPair(seed);
            const txParams = {
                txPrebuild,
                prv: keyPair.prv,
                recipients: [
                    {
                        address: 'lionteste212?memoId=1',
                        amount: '1000',
                    },
                ],
            };
            newTxPrebuild = () => {
                return _.cloneDeep(txPrebuild);
            };
            newTxParams = () => {
                return _.cloneDeep(txParams);
            };
        });
        beforeEach(async () => {
            // mock responses to the block chain
            sandBox = sinon.createSandbox();
            const callBack = sandBox.stub(src_1.Eos.prototype, 'getDataFromNode');
            callBack
                .withArgs({
                endpoint: '/v1/chain/get_info',
            })
                .resolves(fixtures_1.EosResponses.getInfoResponseSuccess1);
            callBack
                .withArgs({
                endpoint: '/v1/chain/get_block',
                payload: { block_num_or_id: 191839472 },
            })
                .resolves(fixtures_1.EosResponses.getBlockResponseSuccess1);
        });
        afterEach(async () => {
            sandBox.restore();
        });
        it('should verify a transaction', async function () {
            const txParams = newTxParams();
            const txPrebuild = newTxPrebuild();
            const validTransaction = await basecoin.verifyTransaction({ txParams, txPrebuild, wallet, verification });
            validTransaction.should.equal(true);
        });
        it('should verify a transaction without a memoId', async function () {
            const txPrebuild = newTxPrebuild();
            // txParams with different txPrebuild
            const txPrebuild2 = newTxPrebuild();
            txPrebuild2.recipients[0].address = 'lionteste212';
            const txParams = newTxParams();
            txParams.txPrebuild = txPrebuild2;
            const validTransaction = await basecoin.verifyTransaction({ txParams, txPrebuild, wallet, verification });
            validTransaction.should.equal(true);
        });
        it('should throw if different prebuilds are provided in txParams and txPrebuild', async function () {
            const txPrebuild = newTxPrebuild();
            // txParams with different txPrebuild
            const txPrebuild2 = newTxPrebuild();
            txPrebuild2.recipients[0].address = 'sadjghaslsdgo';
            const txParams = newTxParams();
            txParams.txPrebuild = txPrebuild2;
            await basecoin
                .verifyTransaction({ txParams, txPrebuild, wallet, verification })
                .should.be.rejectedWith('inputs txParams.txPrebuild and txPrebuild expected to be equal but were not');
        });
        it('should throw if unpacked txHex is not the same as the unpacked packed_trx', async function () {
            const txPrebuild = newTxPrebuild();
            txPrebuild.txHex =
                'e70aaab8997e1dfce58fbfac80cbbb8fecec7b99cf9111111111111111111111111111111111640000000000000100408c7a02ea3055000000000085269d000201310100a6823403ea3055000000572d3ccdcd01d0f9ce64f437f7cf00000000a8ed323222d0f9ce64f437f7cfb012362b61b31236640000000000000004454f53000000000131000000000000000000000000000000000000000000000000000000000000000000';
            const txParams = newTxParams();
            txParams.txPrebuild = txPrebuild;
            await basecoin
                .verifyTransaction({ txParams, txPrebuild, wallet, verification })
                .should.be.rejectedWith('unpacked packed_trx and unpacked txHex are not equal');
        });
        it('should throw if the expected amount is different than actual amount', async function () {
            const txPrebuild = newTxPrebuild();
            const txParams = newTxParams();
            txParams.recipients[0].amount = 10000;
            await basecoin
                .verifyTransaction({ txParams, txPrebuild, wallet, verification })
                .should.be.rejectedWith('txHex receive amount does not match expected recipient amount');
        });
        it('should throw if the expected recipient is different than actual recipient', async function () {
            const txPrebuild = newTxPrebuild();
            const txParams = newTxParams();
            txParams.recipients[0].address = 'aaaaaaaaaaaa';
            await basecoin
                .verifyTransaction({ txParams, txPrebuild, wallet, verification })
                .should.be.rejectedWith('txHex receive address does not match expected recipient address');
        });
        it('should throw if the expected memo is different than actual memo', async function () {
            const txPrebuild = newTxPrebuild();
            const txParams = newTxParams();
            txParams.recipients[0].address = 'lionteste212?memoId=10';
            await basecoin
                .verifyTransaction({ txParams, txPrebuild, wallet, verification })
                .should.be.rejectedWith('txHex receive memoId does not match expected recipient memoId');
        });
        it('should verify transaction with memo id in params only', async function () {
            const txPrebuild = newTxPrebuild();
            txPrebuild.headers = {
                expiration: '2021-11-08T17:24:47.792',
                ref_block_num: 1,
                ref_block_prefix: 100,
            };
            // has memoid in the txaction with value of '1'
            txPrebuild.txHex =
                'e70aaab8997e1dfce58fbfac80cbbb8fecec7b99cf982a9444273cbc64c41473605d89610100640000000000000100408c7a02ea3055000000000085269d000201300100a6823403ea3055000000572d3ccdcd01001dd9f9a000a53d00000000a8ed323222001dd9f9a000a53d20825019ab3ca98be80300000000000004454f53000000000131000000000000000000000000000000000000000000000000000000000000000000';
            txPrebuild.transaction.packed_trx =
                '605d89610100640000000000000100408c7a02ea3055000000000085269d000201300100a6823403ea3055000000572d3ccdcd01001dd9f9a000a53d00000000a8ed323222001dd9f9a000a53d20825019ab3ca98be80300000000000004454f5300000000013100';
            const txParams = newTxParams();
            txParams.recipients[0].address = 'lionteste212';
            txParams.txPrebuild = txPrebuild;
            const validTransaction = await basecoin.verifyTransaction({ txParams, txPrebuild, wallet, verification });
            validTransaction.should.equal(true);
        });
        it('should verify transaction with alpha numeric memo id params', async function () {
            const txPrebuild = newTxPrebuild();
            txPrebuild.headers = {
                expiration: '2021-11-08T17:55:17.518',
                ref_block_num: 1,
                ref_block_prefix: 100,
            };
            // has memoid in the txaction with value of 'QG73WAXXG'
            txPrebuild.txHex =
                'e70aaab8997e1dfce58fbfac80cbbb8fecec7b99cf982a9444273cbc64c41473866489610100640000000000000100408c7a02ea3055000000000085269d000201300100a6823403ea3055000000572d3ccdcd013085b943b1b54ed700000000a8ed32322a3085b943b1b54ed720825019ab3ca98be80300000000000004454f530000000009514737335741585847000000000000000000000000000000000000000000000000000000000000000000';
            txPrebuild.transaction.packed_trx =
                '866489610100640000000000000100408c7a02ea3055000000000085269d000201300100a6823403ea3055000000572d3ccdcd013085b943b1b54ed700000000a8ed32322a3085b943b1b54ed720825019ab3ca98be80300000000000004454f53000000000951473733574158584700';
            const txParams = newTxParams();
            txParams.recipients[0].address = 'lionteste212';
            txParams.txPrebuild = txPrebuild;
            const validTransaction = await basecoin.verifyTransaction({ txParams, txPrebuild, wallet, verification });
            validTransaction.should.equal(true);
        });
    });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW9zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L2Vvcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBOztHQUVHO0FBQ0gsNENBQTBDO0FBQzFDLDhDQUF5QztBQUN6Qyw4Q0FBMEQ7QUFDMUQsZ0RBQXlDO0FBQ3pDLCtDQUFpQztBQUNqQywwQ0FBNEI7QUFDNUIsb0RBQTRCO0FBQzVCLDZDQUErQjtBQUMvQixtQ0FBc0M7QUFDdEMsMENBQXNEO0FBQ3RELG9EQUE0QjtBQUU1QixRQUFRLENBQUMsTUFBTSxFQUFFO0lBQ2YsSUFBSSxLQUFtQixDQUFDO0lBQ3hCLElBQUksUUFBUSxDQUFDO0lBRWIsTUFBTSxDQUFDO1FBQ0wsS0FBSyxHQUFHLG9CQUFTLENBQUMsUUFBUSxDQUFDLGtCQUFRLEVBQUUsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUN0RCxLQUFLLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxTQUFHLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDOUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsVUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2hELEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQzNCLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ2hDLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDRCQUE0QixFQUFFO1FBQy9CLElBQUksY0FBYyxHQUFHLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUVoRSxjQUFjLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDcEQsSUFBQSxnQkFBTSxFQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsU0FBUyxF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LEVBQUUsQ0FBQztnQkFDaEIsZ0JBQWdCLEVBQUUsR0FBRzthQUN0QixDQUFDO1lBQ0YsdURBQXVEO1lBQ3ZELFVBQVUsQ0FBQyxLQUFLO2dCQUNkLGtXQUFrVyxDQUFDO1lBQ3JXLFVBQVUsQ0FBQyxXQUFXLENBQUMsVUFBVTtnQkFDL0Isa09BQWtPLENBQUM7WUFDck8sTUFBTSxRQUFRLEdBQUcsV0FBVyxFQUFFLENBQUM7WUFDL0IsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEdBQUcsY0FBYyxDQUFDO1lBQ2hELFFBQVEsQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1lBRWpDLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxRQUFRLENBQUMsaUJBQWlCLENBQUMsRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsQ0FBQyxDQUFDO1lBQzFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAcHJldHRpZXJcbiAqL1xuaW1wb3J0IHsgQml0R29BUEkgfSBmcm9tICdAYml0Z28vc2RrLWFwaSc7XG5pbXBvcnQgeyBXYWxsZXQgfSBmcm9tICdAYml0Z28vc2RrLWNvcmUnO1xuaW1wb3J0IHsgVGVzdEJpdEdvLCBUZXN0Qml0R29BUEkgfSBmcm9tICdAYml0Z28vc2RrLXRlc3QnO1xuaW1wb3J0IHsgYmlwMzIgfSBmcm9tICdAYml0Z28vc2VjcDI1NmsxJztcbmltcG9ydCAqIGFzIGVjYyBmcm9tICdlb3Nqcy1lY2MnO1xuaW1wb3J0ICogYXMgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0IHsgRW9zLCBUZW9zIH0gZnJvbSAnLi4vLi4vc3JjJztcbmltcG9ydCB7IEVvc0lucHV0cywgRW9zUmVzcG9uc2VzIH0gZnJvbSAnLi4vZml4dHVyZXMnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuXG5kZXNjcmliZSgnRU9TOicsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IGJpdGdvOiBUZXN0Qml0R29BUEk7XG4gIGxldCBiYXNlY29pbjtcblxuICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7IGVudjogJ3Rlc3QnIH0pO1xuICAgIGJpdGdvLnNhZmVSZWdpc3RlcignZW9zJywgRW9zLmNyZWF0ZUluc3RhbmNlKTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ3Rlb3MnLCBUZW9zLmNyZWF0ZUluc3RhbmNlKTtcbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3Rlb3MnKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBnZXQgYWRkcmVzcyBkZXRhaWxzJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBhZGRyZXNzRGV0YWlscyA9IGJhc2Vjb2luLmdldEFkZHJlc3NEZXRhaWxzKCdpMXNrZGEza3NvNDMnKTtcblxuICAgIGFkZHJlc3NEZXRhaWxzLmFkZHJlc3Muc2hvdWxkLmVxdWFsKCdpMXNrZGEza3NvNDMnKTtcbiAgICBzaG91bGQoYWRkcmVzc0RldGFpbHMubWVtb0lkKS5iZS51bmRlZmluZWQoKTtcblxuICAgIGFkZHJlc3NEZXRhaWxzID0gYmFzZWNvaW4uZ2V0QWRkcmVzc0RldGFpbHMoJ2tzMTNrM2hkdWkyND9tZW1vSWQ9MScpO1xuICAgIGFkZHJlc3NEZXRhaWxzLmFkZHJlc3Muc2hvdWxkLmVxdWFsKCdrczEzazNoZHVpMjQnKTtcbiAgICBhZGRyZXNzRGV0YWlscy5tZW1vSWQuc2hvdWxkLmVxdWFsKCcxJyk7XG5cbiAgICAoKCkgPT4ge1xuICAgICAgYmFzZWNvaW4uZ2V0QWRkcmVzc0RldGFpbHMoJ2tzMTNrM2hkdWkyND9tZW1vSWQ9MSZtZW1vSWQ9MicpO1xuICAgIH0pLnNob3VsZC50aHJvdygpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGdldCBhZGRyZXNzIGRldGFpbHMgd2l0aCBhbHBoYW51bWVyaWMgbWVtb2lkJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGFkZHJlc3NEZXRhaWxzID0gYmFzZWNvaW4uZ2V0QWRkcmVzc0RldGFpbHMoJ2kxc2tkYTNrc280Mz9tZW1vSWQ9MTIzYWJjJyk7XG5cbiAgICBhZGRyZXNzRGV0YWlscy5hZGRyZXNzLnNob3VsZC5lcXVhbCgnaTFza2RhM2tzbzQzJyk7XG4gICAgYWRkcmVzc0RldGFpbHMubWVtb0lkLnNob3VsZC5lcXVhbCgnMTIzYWJjJyk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgdmFsaWRhdGUgYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICBiYXNlY29pbi5pc1ZhbGlkQWRkcmVzcygnaTFza2RhM2tzbzQzJykuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIGJhc2Vjb2luLmlzVmFsaWRBZGRyZXNzKCdrczEza2RoMjQ1bHMnKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgYmFzZWNvaW4uaXNWYWxpZEFkZHJlc3MoJ2tzMTNrM2hkdWkyND9tZW1vSWQ9MScpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICBiYXNlY29pbi5pc1ZhbGlkQWRkcmVzcygna3MxM2szaGR1aTI0P21lbW9JZD14Jykuc2hvdWxkLmVxdWFsKHRydWUpO1xuICB9KTtcblxuICBpdCgndmVyaWZ5QWRkcmVzcyBzaG91bGQgd29yaycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBhd2FpdCBiYXNlY29pbi52ZXJpZnlBZGRyZXNzKHtcbiAgICAgIGFkZHJlc3M6ICdpMXNrZGEza3NvNDMnLFxuICAgICAgcm9vdEFkZHJlc3M6ICdpMXNrZGEza3NvNDMnLFxuICAgIH0pO1xuICAgIGF3YWl0IGJhc2Vjb2luLnZlcmlmeUFkZHJlc3Moe1xuICAgICAgYWRkcmVzczogJ2tzMTNrZGgyNDVscz9tZW1vSWQ9MScsXG4gICAgICByb290QWRkcmVzczogJ2tzMTNrZGgyNDVscycsXG4gICAgfSk7XG5cbiAgICBhc3NlcnQucmVqZWN0cyhiYXNlY29pbi52ZXJpZnlBZGRyZXNzKHsgYWRkcmVzczogJ2kxc2tkYTNrc280Mz14Jywgcm9vdEFkZHJlc3M6ICdpMXNrZGEza3NvNDMnIH0pKTtcbiAgICBhc3NlcnQucmVqZWN0cyhiYXNlY29pbi52ZXJpZnlBZGRyZXNzKHsgYWRkcmVzczogJ2kxc2tkYTNrc280Mz9tZW1vSWQ9MjQzNDMyJywgcm9vdEFkZHJlc3M6ICdrczEza2RoMjQ1bHMnIH0pKTtcbiAgICBhc3NlcnQucmVqZWN0cyhiYXNlY29pbi52ZXJpZnlBZGRyZXNzKHsgYWRkcmVzczogJ2kxc2tkYTNrc280MycgfSkpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGdlbmVyYXRlIHZhbGlkIHJhbmRvbSBhZGRyZXNzZXMnLCAoKSA9PiB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCAxMDA7IGkrKykge1xuICAgICAgY29uc3QgYWRkcmVzcyA9IGJhc2Vjb2luLmdlbmVyYXRlUmFuZG9tQWRkcmVzcygpO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZEFkZHJlc3MoYWRkcmVzcykuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9XG4gIH0pO1xuXG4gIGl0KCdpc1ZhbGlkTWVtbyBzaG91bGQgd29yaycsIGZ1bmN0aW9uICgpIHtcbiAgICBiYXNlY29pbi5pc1ZhbGlkTWVtbyh7IHZhbHVlOiAnMScgfSkuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIGJhc2Vjb2luLmlzVmFsaWRNZW1vKHsgdmFsdWU6ICd1bm8nIH0pLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICBiYXNlY29pbi5pc1ZhbGlkTWVtbyh7IHZhbHVlOiBFb3NJbnB1dHMuc3RyaW5nMjU3Q2hhcnNMb25nIH0pLnNob3VsZC5lcXVhbChmYWxzZSk7XG4gIH0pO1xuXG4gIGl0KCdpc1ZhbGlkTWVtb0lkIHNob3VsZCB3b3JrJywgZnVuY3Rpb24gKCkge1xuICAgIGJhc2Vjb2luLmlzVmFsaWRNZW1vSWQoJzEnKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgYmFzZWNvaW4uaXNWYWxpZE1lbW9JZCgnMTIzYWJjJykuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIGJhc2Vjb2luLmlzVmFsaWRNZW1vSWQoRW9zSW5wdXRzLnN0cmluZzI1N0NoYXJzTG9uZykuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSBwdWIga2V5JywgKCkgPT4ge1xuICAgIGNvbnN0IHsgcHViIH0gPSBiYXNlY29pbi5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICBiYXNlY29pbi5pc1ZhbGlkUHViKHB1Yikuc2hvdWxkLmVxdWFsKHRydWUpO1xuICB9KTtcblxuICBkZXNjcmliZSgnS2V5cGFpcnM6JywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYSBrZXlwYWlyIGZyb20gcmFuZG9tIHNlZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBrZXlQYWlyID0gYmFzZWNvaW4uZ2VuZXJhdGVLZXlQYWlyKCk7XG4gICAgICBrZXlQYWlyLnNob3VsZC5oYXZlLnByb3BlcnR5KCdwdWInKTtcbiAgICAgIGtleVBhaXIuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3BydicpO1xuXG4gICAgICBiYXNlY29pbi5pc1ZhbGlkUHViKGtleVBhaXIucHViKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICBiYXNlY29pbi5pc1ZhbGlkUHJ2KGtleVBhaXIucHJ2KS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGEga2V5cGFpciBmcm9tIHNlZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzZWVkID0gQnVmZmVyLmZyb20oJ2MzYjA5YzI0NzMxYmUyODUxYjY0MWQ5ZDViM2Y2MGZhMTI5Njk1YzI0MDcxNzY4ZDE1NjU0YmVhMjA3YjdiYjYnLCAnaGV4Jyk7XG4gICAgICBjb25zdCBrZXlQYWlyID0gYmFzZWNvaW4uZ2VuZXJhdGVLZXlQYWlyKHNlZWQpO1xuXG4gICAgICBrZXlQYWlyLnB1Yi5zaG91bGQuZXF1YWwoXG4gICAgICAgICd4cHViNjYxTXlNd0FxUmJjRjJTVXFVTWlxeFdHd2FWWDZzSDRva1R0WDhqeEoxQTE0d2ZMOFc3alpFb05FNTM3SnFTRVNYRnBUY1hDWmFoUHo3UktRTHBBRUdzVnAyMzNkYzVDZmZMU2VjcFUxM1gnXG4gICAgICApO1xuICAgICAga2V5UGFpci5wcnYuc2hvdWxkLmVxdWFsKFxuICAgICAgICAneHBydjlzMjFaclFIMTQzSzJZTjFqU3BpVXBaWVBZZjJoUVpEU1hZSGlrTExqZmQyQzlMQmF4b1YxU1V0Tm5aR25YZXlKNnVGV01iUVRmalhxVmZnTnFSQnc1eXlhQ3RCSzFBTThQRjNYWnRLalFwJ1xuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBjcmVhdGUgdW5zaWduZWQgcmVjb3ZlcnkgdHJhbnNhY3Rpb24gd2l0aG91dCBCaXRnbycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCB1c2VyS2V5ID1cbiAgICAgICd4cHViNjYxTXlNd0FxUmJjSDFvVUFEeGF0THVLa1ZqYURCMnpUTkpvWlFzR1ZRRXZvb2dwYlhKdzI0UU1va053RktqOVFoY2k2S1dhQ2NRS3J6cEw0TENRWFhYM1lwVFF4Z0Q5S0xCamhEclVXbzQnO1xuICAgIGNvbnN0IGJhY2t1cEtleSA9XG4gICAgICAneHB1YjY2MU15TXdBcVJiY0gxbjZzZ1kyOUc3ZEF4TDd0d1M4cnQxanl1dVFiMWtmbkE3czNGSlBHb1ZxYjlKZW5Ya2VKbUM0alo4aVZzY24zQUg2TWtZQVZjNjFGVFlDSHB4djVjeFdhcjVKdzNDJztcbiAgICBjb25zdCByb290QWRkcmVzcyA9ICdpMXNrZGEza3NvNDMnO1xuICAgIGNvbnN0IGRlc3RpbmF0aW9uQWRkcmVzcyA9ICdrczEza2RoMjQ1bHMnO1xuXG4gICAgLy8gbW9jayByZXNwb25zZXMgdG8gdGhlIGJsb2NrIGNoYWluXG4gICAgY29uc3Qgc2FuZEJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICBjb25zdCBjYWxsQmFjayA9IHNhbmRCb3guc3R1YihFb3MucHJvdG90eXBlLCA8YW55PidnZXREYXRhRnJvbU5vZGUnKTtcbiAgICBjYWxsQmFja1xuICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgZW5kcG9pbnQ6ICcvdjEvY2hhaW4vZ2V0X2FjY291bnQnLFxuICAgICAgICBwYXlsb2FkOiB7IGFjY291bnRfbmFtZTogcm9vdEFkZHJlc3MgfSxcbiAgICAgIH0pXG4gICAgICAucmVzb2x2ZXMoRW9zUmVzcG9uc2VzLmdldEFjY291bnRSZXNwb25zZVN1Y2Nlc3MxKTtcbiAgICBjYWxsQmFja1xuICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgZW5kcG9pbnQ6ICcvdjEvY2hhaW4vZ2V0X2FjY291bnQnLFxuICAgICAgICBwYXlsb2FkOiB7IGFjY291bnRfbmFtZTogZGVzdGluYXRpb25BZGRyZXNzIH0sXG4gICAgICB9KVxuICAgICAgLnJlc29sdmVzKEVvc1Jlc3BvbnNlcy5nZXRBY2NvdW50UmVzcG9uc2VTdWNjZXNzMik7XG4gICAgY2FsbEJhY2tcbiAgICAgIC53aXRoQXJncyh7XG4gICAgICAgIGVuZHBvaW50OiAnL3YxL2NoYWluL2dldF9pbmZvJyxcbiAgICAgIH0pXG4gICAgICAucmVzb2x2ZXMoRW9zUmVzcG9uc2VzLmdldEluZm9SZXNwb25zZVN1Y2Nlc3MxKTtcbiAgICBjYWxsQmFja1xuICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgZW5kcG9pbnQ6ICcvdjEvY2hhaW4vZ2V0X2Jsb2NrJyxcbiAgICAgICAgcGF5bG9hZDogeyBibG9ja19udW1fb3JfaWQ6IDE5MTgzOTQ3MiB9LFxuICAgICAgfSlcbiAgICAgIC5yZXNvbHZlcyhFb3NSZXNwb25zZXMuZ2V0QmxvY2tSZXNwb25zZVN1Y2Nlc3MxKTtcblxuICAgIC8vIGNhbiBjcmVhdGUgdW5zaWduZWQgcmVjb3ZlcnkgdHJhbnNhY3Rpb25cbiAgICBjb25zdCB1bnNpZ25lZFJlY292ZXJ5VHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgIHVzZXJLZXksXG4gICAgICBiYWNrdXBLZXksXG4gICAgICBiaXRnb0tleTogJ2tleScsXG4gICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBkZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICByb290QWRkcmVzcyxcbiAgICB9KTtcbiAgICB1bnNpZ25lZFJlY292ZXJ5VHJhbnNhY3Rpb24ucmVjb3ZlcnlBbW91bnQuc2hvdWxkLmVxdWFsKCc1LjAwMDAnKTtcbiAgICB1bnNpZ25lZFJlY292ZXJ5VHJhbnNhY3Rpb24udHJhbnNhY3Rpb24uc2lnbmF0dXJlcy5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuXG4gICAgLy8gY29pbiBhbmQgdHhIZXggZmllbGRzIGFyZSBleHBlY3RlZCBkdXJpbmcgcmVjb3Zlcnkgb2YgdW5zaWduZWQgdHJhbnNhY3Rpb24gdXNpbmcgT1ZDXG4gICAgdW5zaWduZWRSZWNvdmVyeVRyYW5zYWN0aW9uLmNvaW4uc2hvdWxkLmVxdWFsKCd0ZW9zJyk7XG4gICAgdW5zaWduZWRSZWNvdmVyeVRyYW5zYWN0aW9uLnR4SGV4LnNob3VsZC5lcXVhbChcbiAgICAgICcyYTAyYTAwNTNlNWE4Y2Y3M2E1NmJhMGZkYTExZTRkOTJlMDIzOGE0YTJhYTc0ZmNjZjQ2ZDVhOTEwNzQ2ODQwOGNkY2RiNjBmMDNjZjRhOWU1M2MwMDAwMDAwMDAxMDBhNjgyMzQwM2VhMzA1NTAwMDAwMDU3MmQzY2NkY2QwMTMwMDhjNTcwOTgwNDcxNzAwMDAwMDAwMGE4ZWQzMjMyMjEzMDA4YzU3MDk4MDQ3MTcwODA2MzIxYTIyNTM4MDI4NjUwYzMwMDAwMDAwMDAwMDAwNDQ1NGY1MzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAnXG4gICAgKTtcblxuICAgIC8vIGRlc3RpbmF0aW9uIGFkZHJlc3MgYW5kIHJvb3QgYWRkcmVzcyBjYW4gaW5jbHVkZSBtZW1vSWRcbiAgICBjb25zdCB1bnNpZ25lZFJlY292ZXJ5VHJhbnNhY3Rpb24yID0gYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICB1c2VyS2V5LFxuICAgICAgYmFja3VwS2V5LFxuICAgICAgYml0Z29LZXk6ICdrZXknLFxuICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogYCR7ZGVzdGluYXRpb25BZGRyZXNzfT9tZW1vSWQ9MGAsXG4gICAgICByb290QWRkcmVzczogYCR7cm9vdEFkZHJlc3N9P21lbW9JZD0wYCxcbiAgICB9KTtcbiAgICB1bnNpZ25lZFJlY292ZXJ5VHJhbnNhY3Rpb24yLnJlY292ZXJ5QW1vdW50LnNob3VsZC5lcXVhbCgnNS4wMDAwJyk7XG4gICAgdW5zaWduZWRSZWNvdmVyeVRyYW5zYWN0aW9uMi50cmFuc2FjdGlvbi5zaWduYXR1cmVzLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG5cbiAgICAvLyBjb2luIGFuZCB0eEhleCBmaWVsZHMgYXJlIGV4cGVjdGVkIGR1cmluZyByZWNvdmVyeSBvZiB1bnNpZ25lZCB0cmFuc2FjdGlvbiB1c2luZyBPVkNcbiAgICB1bnNpZ25lZFJlY292ZXJ5VHJhbnNhY3Rpb24uY29pbi5zaG91bGQuZXF1YWwoJ3Rlb3MnKTtcbiAgICB1bnNpZ25lZFJlY292ZXJ5VHJhbnNhY3Rpb24udHhIZXguc2hvdWxkLmVxdWFsKFxuICAgICAgJzJhMDJhMDA1M2U1YThjZjczYTU2YmEwZmRhMTFlNGQ5MmUwMjM4YTRhMmFhNzRmY2NmNDZkNWE5MTA3NDY4NDA4Y2RjZGI2MGYwM2NmNGE5ZTUzYzAwMDAwMDAwMDEwMGE2ODIzNDAzZWEzMDU1MDAwMDAwNTcyZDNjY2RjZDAxMzAwOGM1NzA5ODA0NzE3MDAwMDAwMDAwYThlZDMyMzIyMTMwMDhjNTcwOTgwNDcxNzA4MDYzMjFhMjI1MzgwMjg2NTBjMzAwMDAwMDAwMDAwMDA0NDU0ZjUzMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCdcbiAgICApO1xuXG4gICAgc2FuZEJveC5yZXN0b3JlKCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdUcmFuc2FjdGlvbnM6JywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHRlc3RFeHBsYWluVHJhbnNhY3Rpb24gPSAoaW5wdXQsIGV4cGVjdGVkT3V0cHV0KSA9PlxuICAgICAgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbihpbnB1dCk7XG4gICAgICAgIHNob3VsZC5leGlzdChleHBsYWluZWRUcmFuc2FjdGlvbik7XG4gICAgICAgIGV4cGxhaW5lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoZXhwZWN0ZWRPdXRwdXQpO1xuICAgICAgfTtcbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGEgdmFsaWQgdHJhbnNhY3Rpb24gc2lnbmF0dXJlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2lnbmF0dXJlRGF0YSA9ICdhYmNkJztcbiAgICAgIGNvbnN0IHR4ID0ge1xuICAgICAgICB0eEhleDogc2lnbmF0dXJlRGF0YSxcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgIHJlZl9ibG9ja19udW06IDEsXG4gICAgICAgICAgcmVmX2Jsb2NrX3ByZWZpeDogJ2FzZCcsXG4gICAgICAgIH0sXG4gICAgICAgIHRyYW5zYWN0aW9uOiB7XG4gICAgICAgICAgc2lnbmF0dXJlczogW10sXG4gICAgICAgICAgcGFja2VkX3RyeDogc2lnbmF0dXJlRGF0YSxcbiAgICAgICAgICBjb21wcmVzc2lvbjogJ25vbmUnLFxuICAgICAgICB9LFxuICAgICAgICByZWNpcGllbnRzOiBbe31dLFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgc2VlZCA9IEJ1ZmZlci5mcm9tKCdjM2IwOWMyNDczMWJlMjg1MWI2MjRkOWQ1YjNmNjBmYTEyOTY5NWMyNDA3MTc2OGQxNTY1NGJlYTIwN2I3YmI2JywgJ2hleCcpO1xuICAgICAgY29uc3Qga2V5UGFpciA9IGJhc2Vjb2luLmdlbmVyYXRlS2V5UGFpcihzZWVkKTtcblxuICAgICAgY29uc3QgeyBoYWxmU2lnbmVkIH0gPSBhd2FpdCBiYXNlY29pbi5zaWduVHJhbnNhY3Rpb24oeyB0eFByZWJ1aWxkOiB0eCwgcHJ2OiBrZXlQYWlyLnBydiB9KTtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IGhhbGZTaWduZWQudHJhbnNhY3Rpb24uc2lnbmF0dXJlc1swXTtcbiAgICAgIGNvbnN0IGhkTm9kZSA9IGJpcDMyLmZyb21CYXNlNTgoa2V5UGFpci5wdWIpO1xuICAgICAgY29uc3QgZW9zUHVia2V5ID0gZWNjLlB1YmxpY0tleS5mcm9tQnVmZmVyKGhkTm9kZS5wdWJsaWNLZXkpLnRvU3RyaW5nKCk7XG4gICAgICBlY2MudmVyaWZ5KHNpZ25hdHVyZSwgQnVmZmVyLmZyb20oc2lnbmF0dXJlRGF0YSwgJ2hleCcpLCBlb3NQdWJrZXkpLnNob3VsZC5lcWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYW4gRU9TIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpblRyYW5zYWN0aW9uUGFyYW1zID0ge1xuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgcmVmX2Jsb2NrX3ByZWZpeDogMTAwLFxuICAgICAgICAgIHJlZl9ibG9ja19udW06IDk5NSxcbiAgICAgICAgICBleHBpcmF0aW9uOiAnMjAxOC0wNC0yN1QxODo0MDozNC4wMDBaJyxcbiAgICAgICAgfSxcbiAgICAgICAgdHJhbnNhY3Rpb246IHtcbiAgICAgICAgICBwYWNrZWRfdHJ4OlxuICAgICAgICAgICAgJ2EyNmVlMzVhZTMwMzY0MDAwMDAwMDAwMDAwMDAwMTAwYTY4MjM0MDNlYTMwNTUwMDAwMDA1NzJkM2NjZGNkMDE5MDEzZTQ4YzhjZTVlZWQ0MDAwMDAwMDBhOGVkMzIzMjIyOTAxM2U0OGM4Y2U1ZWVkNGIwMTIzNjJiNjFiMzEyMzY2NDAwMDAwMDAwMDAwMDAwMDQ0NTRmNTMwMDAwMDAwMDAxMzEwMCcsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBleHBsYWluZWRUeCA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbihleHBsYWluVHJhbnNhY3Rpb25QYXJhbXMpO1xuICAgICAgZXhwbGFpbmVkVHgub3V0cHV0QW1vdW50LnNob3VsZC5lcXVhbCgnMTAwJyk7XG4gICAgICBleHBsYWluZWRUeC5vdXRwdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICBleHBsYWluZWRUeC5vdXRwdXRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWwoJzEwMCcpO1xuICAgICAgZXhwbGFpbmVkVHgub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbCgnYXNkZmFzZGZhc2RmJyk7XG4gICAgICBleHBsYWluZWRUeC5pZC5zaG91bGQuZXF1YWwoJzYxMzJmM2JmNGE3NDZlNmVjYWQ4YTMxZGY2N2Q3MWI0NzQxZmM1YjdjODY4YWUzNmRkZTE4MzA5YTkxZGY4YTYnKTtcbiAgICAgIGV4cGxhaW5lZFR4Lm1lbW8uc2hvdWxkLmVxdWFsKCcxJyk7XG4gICAgfSk7XG4gICAgaXQoXG4gICAgICAnZXhwbGFpbnMgRU9TIG5hdGl2ZSB0cmFuc2ZlciB0cmFuc2FjdGlvbicsXG4gICAgICB0ZXN0RXhwbGFpblRyYW5zYWN0aW9uKEVvc0lucHV0cy5leHBsYWluVHJhbnNhY3Rpb25JbnB1dE5hdGl2ZSwgRW9zUmVzcG9uc2VzLmV4cGxhaW5UcmFuc2FjdGlvbk91dHB1dE5hdGl2ZSlcbiAgICApO1xuICAgIGl0KFxuICAgICAgJ2V4cGxhaW5zIENIRVggdG9rZW4gdHJhbnNmZXIgdHJhbnNhY3Rpb24nLFxuICAgICAgdGVzdEV4cGxhaW5UcmFuc2FjdGlvbihFb3NJbnB1dHMuZXhwbGFpblRyYW5zYWN0aW9uSW5wdXRDaGV4LCBFb3NSZXNwb25zZXMuZXhwbGFpblRyYW5zYWN0aW9uT3V0cHV0Q2hleClcbiAgICApO1xuICAgIGl0KFxuICAgICAgJ2V4cGxhaW4gRU9TIFVuc3Rha2UxIHRyYW5zYWN0aW9uJyxcbiAgICAgIHRlc3RFeHBsYWluVHJhbnNhY3Rpb24oRW9zSW5wdXRzLmV4cGxhaW5VbnN0YWtlSW5wdXQxLCBFb3NSZXNwb25zZXMuZXhwbGFpblVuc3Rha2VPdXRwdXQxKVxuICAgICk7XG4gICAgaXQoXG4gICAgICAnZXhwbGFpbiBFT1MgVW5zdGFrZTIgdHJhbnNhY3Rpb24nLFxuICAgICAgdGVzdEV4cGxhaW5UcmFuc2FjdGlvbihFb3NJbnB1dHMuZXhwbGFpblVuc3Rha2VJbnB1dDIsIEVvc1Jlc3BvbnNlcy5leHBsYWluVW5zdGFrZU91dHB1dDIpXG4gICAgKTtcbiAgICBpdChcbiAgICAgICdleHBsYWluIEVPUyBSZWZ1bmQgdHJhbnNhY3Rpb24nLFxuICAgICAgdGVzdEV4cGxhaW5UcmFuc2FjdGlvbihFb3NJbnB1dHMuZXhwbGFpblJlZnVuZElucHV0LCBFb3NSZXNwb25zZXMuZXhwbGFpblJlZnVuZE91dHB1dClcbiAgICApO1xuICB9KTtcblxuICBkZXNjcmliZSgnVHJhbnNhY3Rpb24gVmVyaWZpY2F0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCB3YWxsZXQ7XG4gICAgbGV0IGJhc2Vjb2luO1xuICAgIGxldCB2ZXJpZmljYXRpb247XG4gICAgbGV0IHNhbmRCb3g7XG4gICAgbGV0IG5ld1R4UHJlYnVpbGQ7XG4gICAgbGV0IG5ld1R4UGFyYW1zO1xuXG4gICAgYmVmb3JlKGFzeW5jICgpID0+IHtcbiAgICAgIGJhc2Vjb2luID0gYml0Z28uY29pbigndGVvcycpO1xuICAgICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgICAgaWQ6ICc1YTc4ZGQ1NjFjNjI1OGE5MDdmMWVlYWVlMTMyZjc5NicsXG4gICAgICAgIHVzZXJzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdXNlcjogJzU0M2MxMWVkMzU2ZDAwY2I3NjAwMDAwYjk4Nzk0NTAzJyxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3ZpZXcnLCAnc3BlbmQnXSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBjb2luOiAndGVvcycsXG4gICAgICAgIGxhYmVsOiAnVmVyaWZpY2F0aW9uIFdhbGxldCcsXG4gICAgICAgIG06IDIsXG4gICAgICAgIG46IDMsXG4gICAgICAgIGtleXM6IFtcbiAgICAgICAgICAnNWE3OGRkNTZiZmU0MjRhYTA3YWEwNjg2NTFiMTk0ZmQnLFxuICAgICAgICAgICc1YTc4ZGQ1Njc0YTcwZWI0MDc5ZjU4Nzk3ZGZlMmY1ZScsXG4gICAgICAgICAgJzVhNzhkZDU2MWM2MjU4YTkwN2YxZWVhOWYxZDA3OWUyJyxcbiAgICAgICAgXSxcbiAgICAgICAgdGFnczogWyc1YTc4ZGQ1NjFjNjI1OGE5MDdmMWVlYWVlMTMyZjc5NiddLFxuICAgICAgICBkaXNhYmxlVHJhbnNhY3Rpb25Ob3RpZmljYXRpb25zOiBmYWxzZSxcbiAgICAgICAgZnJlZXplOiB7fSxcbiAgICAgICAgZGVsZXRlZDogZmFsc2UsXG4gICAgICAgIGFwcHJvdmFsc1JlcXVpcmVkOiAxLFxuICAgICAgICBpc0NvbGQ6IHRydWUsXG4gICAgICAgIGNvaW5TcGVjaWZpYzoge30sXG4gICAgICAgIGNsaWVudEZsYWdzOiBbXSxcbiAgICAgICAgYmFsYW5jZTogNjUwMDAwMDAwLFxuICAgICAgICBjb25maXJtZWRCYWxhbmNlOiA2NTAwMDAwMDAsXG4gICAgICAgIHNwZW5kYWJsZUJhbGFuY2U6IDY1MDAwMDAwMCxcbiAgICAgICAgYmFsYW5jZVN0cmluZzogJzY1MDAwMDAwMCcsXG4gICAgICAgIGNvbmZpcm1lZEJhbGFuY2VTdHJpbmc6ICc2NTAwMDAwMDAnLFxuICAgICAgICBzcGVuZGFibGVCYWxhbmNlU3RyaW5nOiAnNjUwMDAwMDAwJyxcbiAgICAgICAgcmVjZWl2ZUFkZHJlc3M6IHtcbiAgICAgICAgICBpZDogJzVhNzhkZTJiYmZlNDI0YWEwN2FhMTMxZWMwM2M4ZGMxJyxcbiAgICAgICAgICBhZGRyZXNzOiAnNzh4Y3poYWlqeWhlazInLFxuICAgICAgICAgIGNoYWluOiAwLFxuICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgIGNvaW46ICd0ZW9zJyxcbiAgICAgICAgICB3YWxsZXQ6ICc1YTc4ZGQ1NjFjNjI1OGE5MDdmMWVlYWVlMTMyZjc5NicsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAgcGVuZGluZ0FwcHJvdmFsczogW10sXG4gICAgICB9O1xuICAgICAgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHdhbGxldERhdGEpO1xuICAgICAgY29uc3QgdXNlcktleWNoYWluID0ge1xuICAgICAgICBwcnY6ICc1S0pxNTY1SFRyZ0VKRzlFYnZKSDVCTFlUZ2lvQXlZMjdkVDlhbTFrQ3RuMllWQUpFWUsnLFxuICAgICAgICBwdWI6ICdFT1M2ZzdBQU1Ra2hYcDhqNzNFOEJENEtSd3RRZXZFc0ZnWXg4aHRhUWtSVmhoWEpNZ2tNWicsXG4gICAgICB9O1xuICAgICAgY29uc3QgYmFja3VwS2V5Y2hhaW4gPSB7XG4gICAgICAgIHBydjogJzVLWjFuWFhDaTV5WEg4QWpDSnFqbkNZSENWbmhRYTlZV0dWMkQxNGk4ZzIyMWR4TndMVycsXG4gICAgICAgIHB1YjogJ0VPUzdneURMTmsxMmZhVmIxYXFOeGoxTDJEcEJlckZraEFzeEJzOTV5VzN5eEpwcXZnOU10JyxcbiAgICAgIH07XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJ2xpb250ZXN0ZTIxMicsXG4gICAgICAgICAgICBhbW91bnQ6ICcxMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgZXhwaXJhdGlvbjogJzIwMjEtMTAtMjhUMDI6MzQ6MDUuODQ4JyxcbiAgICAgICAgICByZWZfYmxvY2tfbnVtOiA0MjkxNSxcbiAgICAgICAgICByZWZfYmxvY2tfcHJlZml4OiAxMjA0MDg2NzA5LFxuICAgICAgICB9LFxuICAgICAgICB0eEhleDpcbiAgICAgICAgICAnMmEwMmEwMDUzZTVhOGNmNzNhNTZiYTBmZGExMWU0ZDkyZTAyMzhhNGEyYWE3NGZjY2Y0NmQ1YTkxMDc0Njg0MDFlMGM3YTYxYTNhN2I1ZTdjNDQ3MDAwMDAwMDEwMDQwOGM3YTAyZWEzMDU1MDAwMDAwMDAwMDg1MjY5ZDAwMDMwMjMzMzMwMTAwYTY4MjM0MDNlYTMwNTUwMDAwMDA1NzJkM2NjZGNkMDEyMGNlYjg0MzczMzM0MjdjMDAwMDAwMDBhOGVkMzIzMjIyMjBjZWI4NDM3MzMzNDI3YzIwODI1MDE5YWIzY2E5OGJlODAzMDAwMDAwMDAwMDAwMDQ0NTRmNTMwMDAwMDAwMDAxMzEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAnLFxuICAgICAgICB0cmFuc2FjdGlvbjoge1xuICAgICAgICAgIGNvbXByZXNzaW9uOiAnbm9uZScsXG4gICAgICAgICAgcGFja2VkX3RyeDpcbiAgICAgICAgICAgICcxZTBjN2E2MWEzYTdiNWU3YzQ0NzAwMDAwMDAxMDA0MDhjN2EwMmVhMzA1NTAwMDAwMDAwMDA4NTI2OWQwMDAzMDIzMzMzMDEwMGE2ODIzNDAzZWEzMDU1MDAwMDAwNTcyZDNjY2RjZDAxMjBjZWI4NDM3MzMzNDI3YzAwMDAwMDAwYThlZDMyMzIyMjIwY2ViODQzNzMzMzQyN2MyMDgyNTAxOWFiM2NhOThiZTgwMzAwMDAwMDAwMDAwMDA0NDU0ZjUzMDAwMDAwMDAwMTMxMDAnLFxuICAgICAgICAgIHNpZ25hdHVyZXM6IFtdLFxuICAgICAgICB9LFxuICAgICAgICB0eGlkOiAnNTg2YzViNTliMTBiMTM0ZDA0YzE2YWMxYjI3M2ZlM2M1NTI5ZjM0YWVmNzVkYjQ0NTZjZDQ2OWM1Y2RhYzdlMicsXG4gICAgICAgIGlzVm90aW5nVHJhbnNhY3Rpb246IGZhbHNlLFxuICAgICAgICBjb2luOiAndGVvcycsXG4gICAgICB9O1xuICAgICAgdmVyaWZpY2F0aW9uID0ge1xuICAgICAgICBkaXNhYmxlTmV0d29ya2luZzogdHJ1ZSxcbiAgICAgICAga2V5Y2hhaW5zOiB7XG4gICAgICAgICAgdXNlcjogeyBwdWI6IHVzZXJLZXljaGFpbi5wdWIgfSxcbiAgICAgICAgICBiYWNrdXA6IHsgcHViOiBiYWNrdXBLZXljaGFpbi5wdWIgfSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCBzZWVkID0gQnVmZmVyLmZyb20oJ2MzYjA5YzI0NzMxYmUyODUxYjYyNGQ5ZDViM2Y2MGZhMTI5Njk1YzI0MDcxNzY4ZDE1NjU0YmVhMjA3YjdiYjYnLCAnaGV4Jyk7XG4gICAgICBjb25zdCBrZXlQYWlyID0gYmFzZWNvaW4uZ2VuZXJhdGVLZXlQYWlyKHNlZWQpO1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgIHBydjoga2V5UGFpci5wcnYsXG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnbGlvbnRlc3RlMjEyP21lbW9JZD0xJyxcbiAgICAgICAgICAgIGFtb3VudDogJzEwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuXG4gICAgICBuZXdUeFByZWJ1aWxkID0gKCkgPT4ge1xuICAgICAgICByZXR1cm4gXy5jbG9uZURlZXAodHhQcmVidWlsZCk7XG4gICAgICB9O1xuICAgICAgbmV3VHhQYXJhbXMgPSAoKSA9PiB7XG4gICAgICAgIHJldHVybiBfLmNsb25lRGVlcCh0eFBhcmFtcyk7XG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgYmVmb3JlRWFjaChhc3luYyAoKSA9PiB7XG4gICAgICAvLyBtb2NrIHJlc3BvbnNlcyB0byB0aGUgYmxvY2sgY2hhaW5cbiAgICAgIHNhbmRCb3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gICAgICBjb25zdCBjYWxsQmFjayA9IHNhbmRCb3guc3R1YihFb3MucHJvdG90eXBlLCA8YW55PidnZXREYXRhRnJvbU5vZGUnKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgZW5kcG9pbnQ6ICcvdjEvY2hhaW4vZ2V0X2luZm8nLFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXMoRW9zUmVzcG9uc2VzLmdldEluZm9SZXNwb25zZVN1Y2Nlc3MxKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgZW5kcG9pbnQ6ICcvdjEvY2hhaW4vZ2V0X2Jsb2NrJyxcbiAgICAgICAgICBwYXlsb2FkOiB7IGJsb2NrX251bV9vcl9pZDogMTkxODM5NDcyIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyhFb3NSZXNwb25zZXMuZ2V0QmxvY2tSZXNwb25zZVN1Y2Nlc3MxKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChhc3luYyAoKSA9PiB7XG4gICAgICBzYW5kQm94LnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zKCk7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZCgpO1xuICAgICAgY29uc3QgdmFsaWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pO1xuICAgICAgdmFsaWRUcmFuc2FjdGlvbi5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBhIHRyYW5zYWN0aW9uIHdpdGhvdXQgYSBtZW1vSWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZCgpO1xuXG4gICAgICAvLyB0eFBhcmFtcyB3aXRoIGRpZmZlcmVudCB0eFByZWJ1aWxkXG4gICAgICBjb25zdCB0eFByZWJ1aWxkMiA9IG5ld1R4UHJlYnVpbGQoKTtcbiAgICAgIHR4UHJlYnVpbGQyLnJlY2lwaWVudHNbMF0uYWRkcmVzcyA9ICdsaW9udGVzdGUyMTInO1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSBuZXdUeFBhcmFtcygpO1xuICAgICAgdHhQYXJhbXMudHhQcmVidWlsZCA9IHR4UHJlYnVpbGQyO1xuXG4gICAgICBjb25zdCB2YWxpZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSk7XG4gICAgICB2YWxpZFRyYW5zYWN0aW9uLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgaWYgZGlmZmVyZW50IHByZWJ1aWxkcyBhcmUgcHJvdmlkZWQgaW4gdHhQYXJhbXMgYW5kIHR4UHJlYnVpbGQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZCgpO1xuXG4gICAgICAvLyB0eFBhcmFtcyB3aXRoIGRpZmZlcmVudCB0eFByZWJ1aWxkXG4gICAgICBjb25zdCB0eFByZWJ1aWxkMiA9IG5ld1R4UHJlYnVpbGQoKTtcbiAgICAgIHR4UHJlYnVpbGQyLnJlY2lwaWVudHNbMF0uYWRkcmVzcyA9ICdzYWRqZ2hhc2xzZGdvJztcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXMoKTtcbiAgICAgIHR4UGFyYW1zLnR4UHJlYnVpbGQgPSB0eFByZWJ1aWxkMjtcblxuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnB1dHMgdHhQYXJhbXMudHhQcmVidWlsZCBhbmQgdHhQcmVidWlsZCBleHBlY3RlZCB0byBiZSBlcXVhbCBidXQgd2VyZSBub3QnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgaWYgdW5wYWNrZWQgdHhIZXggaXMgbm90IHRoZSBzYW1lIGFzIHRoZSB1bnBhY2tlZCBwYWNrZWRfdHJ4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IG5ld1R4UHJlYnVpbGQoKTtcbiAgICAgIHR4UHJlYnVpbGQudHhIZXggPVxuICAgICAgICAnZTcwYWFhYjg5OTdlMWRmY2U1OGZiZmFjODBjYmJiOGZlY2VjN2I5OWNmOTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTY0MDAwMDAwMDAwMDAwMDEwMDQwOGM3YTAyZWEzMDU1MDAwMDAwMDAwMDg1MjY5ZDAwMDIwMTMxMDEwMGE2ODIzNDAzZWEzMDU1MDAwMDAwNTcyZDNjY2RjZDAxZDBmOWNlNjRmNDM3ZjdjZjAwMDAwMDAwYThlZDMyMzIyMmQwZjljZTY0ZjQzN2Y3Y2ZiMDEyMzYyYjYxYjMxMjM2NjQwMDAwMDAwMDAwMDAwMDA0NDU0ZjUzMDAwMDAwMDAwMTMxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJztcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXMoKTtcbiAgICAgIHR4UGFyYW1zLnR4UHJlYnVpbGQgPSB0eFByZWJ1aWxkO1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCd1bnBhY2tlZCBwYWNrZWRfdHJ4IGFuZCB1bnBhY2tlZCB0eEhleCBhcmUgbm90IGVxdWFsJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGlmIHRoZSBleHBlY3RlZCBhbW91bnQgaXMgZGlmZmVyZW50IHRoYW4gYWN0dWFsIGFtb3VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBuZXdUeFByZWJ1aWxkKCk7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zKCk7XG4gICAgICB0eFBhcmFtcy5yZWNpcGllbnRzWzBdLmFtb3VudCA9IDEwMDAwO1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCd0eEhleCByZWNlaXZlIGFtb3VudCBkb2VzIG5vdCBtYXRjaCBleHBlY3RlZCByZWNpcGllbnQgYW1vdW50Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGlmIHRoZSBleHBlY3RlZCByZWNpcGllbnQgaXMgZGlmZmVyZW50IHRoYW4gYWN0dWFsIHJlY2lwaWVudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBuZXdUeFByZWJ1aWxkKCk7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zKCk7XG4gICAgICB0eFBhcmFtcy5yZWNpcGllbnRzWzBdLmFkZHJlc3MgPSAnYWFhYWFhYWFhYWFhJztcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgndHhIZXggcmVjZWl2ZSBhZGRyZXNzIGRvZXMgbm90IG1hdGNoIGV4cGVjdGVkIHJlY2lwaWVudCBhZGRyZXNzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGlmIHRoZSBleHBlY3RlZCBtZW1vIGlzIGRpZmZlcmVudCB0aGFuIGFjdHVhbCBtZW1vJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IG5ld1R4UHJlYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXMoKTtcbiAgICAgIHR4UGFyYW1zLnJlY2lwaWVudHNbMF0uYWRkcmVzcyA9ICdsaW9udGVzdGUyMTI/bWVtb0lkPTEwJztcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgndHhIZXggcmVjZWl2ZSBtZW1vSWQgZG9lcyBub3QgbWF0Y2ggZXhwZWN0ZWQgcmVjaXBpZW50IG1lbW9JZCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgdHJhbnNhY3Rpb24gd2l0aCBtZW1vIGlkIGluIHBhcmFtcyBvbmx5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IG5ld1R4UHJlYnVpbGQoKTtcblxuICAgICAgdHhQcmVidWlsZC5oZWFkZXJzID0ge1xuICAgICAgICBleHBpcmF0aW9uOiAnMjAyMS0xMS0wOFQxNzoyNDo0Ny43OTInLFxuICAgICAgICByZWZfYmxvY2tfbnVtOiAxLFxuICAgICAgICByZWZfYmxvY2tfcHJlZml4OiAxMDAsXG4gICAgICB9O1xuICAgICAgLy8gaGFzIG1lbW9pZCBpbiB0aGUgdHhhY3Rpb24gd2l0aCB2YWx1ZSBvZiAnMSdcbiAgICAgIHR4UHJlYnVpbGQudHhIZXggPVxuICAgICAgICAnZTcwYWFhYjg5OTdlMWRmY2U1OGZiZmFjODBjYmJiOGZlY2VjN2I5OWNmOTgyYTk0NDQyNzNjYmM2NGM0MTQ3MzYwNWQ4OTYxMDEwMDY0MDAwMDAwMDAwMDAwMDEwMDQwOGM3YTAyZWEzMDU1MDAwMDAwMDAwMDg1MjY5ZDAwMDIwMTMwMDEwMGE2ODIzNDAzZWEzMDU1MDAwMDAwNTcyZDNjY2RjZDAxMDAxZGQ5ZjlhMDAwYTUzZDAwMDAwMDAwYThlZDMyMzIyMjAwMWRkOWY5YTAwMGE1M2QyMDgyNTAxOWFiM2NhOThiZTgwMzAwMDAwMDAwMDAwMDA0NDU0ZjUzMDAwMDAwMDAwMTMxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJztcbiAgICAgIHR4UHJlYnVpbGQudHJhbnNhY3Rpb24ucGFja2VkX3RyeCA9XG4gICAgICAgICc2MDVkODk2MTAxMDA2NDAwMDAwMDAwMDAwMDAxMDA0MDhjN2EwMmVhMzA1NTAwMDAwMDAwMDA4NTI2OWQwMDAyMDEzMDAxMDBhNjgyMzQwM2VhMzA1NTAwMDAwMDU3MmQzY2NkY2QwMTAwMWRkOWY5YTAwMGE1M2QwMDAwMDAwMGE4ZWQzMjMyMjIwMDFkZDlmOWEwMDBhNTNkMjA4MjUwMTlhYjNjYTk4YmU4MDMwMDAwMDAwMDAwMDAwNDQ1NGY1MzAwMDAwMDAwMDEzMTAwJztcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXMoKTtcbiAgICAgIHR4UGFyYW1zLnJlY2lwaWVudHNbMF0uYWRkcmVzcyA9ICdsaW9udGVzdGUyMTInO1xuICAgICAgdHhQYXJhbXMudHhQcmVidWlsZCA9IHR4UHJlYnVpbGQ7XG5cbiAgICAgIGNvbnN0IHZhbGlkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KTtcbiAgICAgIHZhbGlkVHJhbnNhY3Rpb24uc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgdHJhbnNhY3Rpb24gd2l0aCBhbHBoYSBudW1lcmljIG1lbW8gaWQgcGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IG5ld1R4UHJlYnVpbGQoKTtcblxuICAgICAgdHhQcmVidWlsZC5oZWFkZXJzID0ge1xuICAgICAgICBleHBpcmF0aW9uOiAnMjAyMS0xMS0wOFQxNzo1NToxNy41MTgnLFxuICAgICAgICByZWZfYmxvY2tfbnVtOiAxLFxuICAgICAgICByZWZfYmxvY2tfcHJlZml4OiAxMDAsXG4gICAgICB9O1xuICAgICAgLy8gaGFzIG1lbW9pZCBpbiB0aGUgdHhhY3Rpb24gd2l0aCB2YWx1ZSBvZiAnUUc3M1dBWFhHJ1xuICAgICAgdHhQcmVidWlsZC50eEhleCA9XG4gICAgICAgICdlNzBhYWFiODk5N2UxZGZjZTU4ZmJmYWM4MGNiYmI4ZmVjZWM3Yjk5Y2Y5ODJhOTQ0NDI3M2NiYzY0YzQxNDczODY2NDg5NjEwMTAwNjQwMDAwMDAwMDAwMDAwMTAwNDA4YzdhMDJlYTMwNTUwMDAwMDAwMDAwODUyNjlkMDAwMjAxMzAwMTAwYTY4MjM0MDNlYTMwNTUwMDAwMDA1NzJkM2NjZGNkMDEzMDg1Yjk0M2IxYjU0ZWQ3MDAwMDAwMDBhOGVkMzIzMjJhMzA4NWI5NDNiMWI1NGVkNzIwODI1MDE5YWIzY2E5OGJlODAzMDAwMDAwMDAwMDAwMDQ0NTRmNTMwMDAwMDAwMDA5NTE0NzM3MzM1NzQxNTg1ODQ3MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJztcbiAgICAgIHR4UHJlYnVpbGQudHJhbnNhY3Rpb24ucGFja2VkX3RyeCA9XG4gICAgICAgICc4NjY0ODk2MTAxMDA2NDAwMDAwMDAwMDAwMDAxMDA0MDhjN2EwMmVhMzA1NTAwMDAwMDAwMDA4NTI2OWQwMDAyMDEzMDAxMDBhNjgyMzQwM2VhMzA1NTAwMDAwMDU3MmQzY2NkY2QwMTMwODViOTQzYjFiNTRlZDcwMDAwMDAwMGE4ZWQzMjMyMmEzMDg1Yjk0M2IxYjU0ZWQ3MjA4MjUwMTlhYjNjYTk4YmU4MDMwMDAwMDAwMDAwMDAwNDQ1NGY1MzAwMDAwMDAwMDk1MTQ3MzczMzU3NDE1ODU4NDcwMCc7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zKCk7XG4gICAgICB0eFBhcmFtcy5yZWNpcGllbnRzWzBdLmFkZHJlc3MgPSAnbGlvbnRlc3RlMjEyJztcbiAgICAgIHR4UGFyYW1zLnR4UHJlYnVpbGQgPSB0eFByZWJ1aWxkO1xuXG4gICAgICBjb25zdCB2YWxpZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSk7XG4gICAgICB2YWxpZFRyYW5zYWN0aW9uLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==

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


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