PHP WebShell

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

Просмотр файла: ton.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 });
const sdk_test_1 = require("@bitgo/sdk-test");
const sdk_api_1 = require("@bitgo/sdk-api");
const src_1 = require("../../src");
const sinon = __importStar(require("sinon"));
const assert_1 = __importDefault(require("assert"));
const testData = __importStar(require("../resources/ton"));
const sdk_core_1 = require("@bitgo/sdk-core");
const should_1 = __importDefault(require("should"));
const utils_1 = __importDefault(require("../../src/lib/utils"));
const tonweb_1 = __importDefault(require("tonweb"));
describe('TON:', function () {
    let basecoin;
    const bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
    bitgo.safeRegister('ton', src_1.Ton.createInstance);
    bitgo.safeRegister('tton', src_1.Tton.createInstance);
    bitgo.initializeTestVars();
    const txPrebuildList = [
        {
            txHex: Buffer.from(testData.signedSendTransaction.tx, 'base64').toString('hex'),
            txInfo: {},
        },
        {
            txHex: Buffer.from(testData.signedSingleNominatorWithdrawTransaction.tx, 'base64').toString('hex'),
            txInfo: {},
        },
    ];
    const txPrebuildBounceableList = [
        {
            txHex: Buffer.from(testData.signedSendTransaction.txBounceable, 'base64').toString('hex'),
            txInfo: {},
        },
        {
            txHex: Buffer.from(testData.signedSingleNominatorWithdrawTransaction.txBounceable, 'base64').toString('hex'),
            txInfo: {},
        },
    ];
    const txParamsList = [
        {
            recipients: [testData.signedSendTransaction.recipient],
        },
        {
            recipients: [testData.signedSingleNominatorWithdrawTransaction.recipient],
        },
    ];
    const txParamsBounceableList = [
        {
            recipients: [testData.signedSendTransaction.recipientBounceable],
        },
        {
            recipients: [testData.signedSingleNominatorWithdrawTransaction.recipientBounceable],
        },
    ];
    it('should return the right info', function () {
        const ton = bitgo.coin('ton');
        const tton = bitgo.coin('tton');
        ton.getChain().should.equal('ton');
        ton.getFamily().should.equal('ton');
        ton.getFullName().should.equal('Ton');
        ton.getBaseFactor().should.equal(1e9);
        tton.getChain().should.equal('tton');
        tton.getFamily().should.equal('ton');
        tton.getFullName().should.equal('Testnet Ton');
        tton.getBaseFactor().should.equal(1e9);
    });
    describe('Verify transaction: ', () => {
        basecoin = bitgo.coin('tton');
        txParamsList.forEach((_, index) => {
            const txParams = txParamsList[index];
            const txPrebuild = txPrebuildList[index];
            const txParamsBounceable = txParamsBounceableList[index];
            const txPrebuildBounceable = txPrebuildBounceableList[index];
            it('should succeed to verify transaction', async function () {
                const verification = {};
                const isTransactionVerified = await basecoin.verifyTransaction({
                    txParams,
                    txPrebuild,
                    verification,
                });
                isTransactionVerified.should.equal(true);
                const isBounceableTransactionVerified = await basecoin.verifyTransaction({
                    txParams: txParamsBounceable,
                    txPrebuild: txPrebuildBounceable,
                    verification: {},
                });
                isBounceableTransactionVerified.should.equal(true);
            });
            it('should succeed to verify transaction when recipients amount are numbers', async function () {
                const txParamsWithNumberAmounts = JSON.parse(JSON.stringify(txParams));
                txParamsWithNumberAmounts.recipients[0].amount = 20000000;
                const verification = {};
                await basecoin
                    .verifyTransaction({
                    txParams: txParamsWithNumberAmounts,
                    txPrebuild,
                    verification,
                })
                    .should.rejectedWith('Tx outputs does not match with expected txParams recipients');
            });
            it('should succeed to verify transaction when recipients amount are strings', async function () {
                const txParamsWithNumberAmounts = JSON.parse(JSON.stringify(txParams));
                txParamsWithNumberAmounts.recipients[0].amount = '20000000';
                const verification = {};
                await basecoin
                    .verifyTransaction({
                    txParams: txParamsWithNumberAmounts,
                    txPrebuild,
                    verification,
                })
                    .should.rejectedWith('Tx outputs does not match with expected txParams recipients');
            });
            it('should succeed to verify transaction when recipients amounts are number and amount is same', async function () {
                const verification = {};
                await basecoin
                    .verifyTransaction({
                    txParams,
                    txPrebuild,
                    verification,
                })
                    .should.resolvedWith(true);
            });
            it('should succeed to verify transaction when recipients amounts are string and amount is same', async function () {
                const verification = {};
                await basecoin
                    .verifyTransaction({
                    txParams,
                    txPrebuild,
                    verification,
                })
                    .should.resolvedWith(true);
            });
            it('should succeed to verify transaction when recipient address are non bounceable', async function () {
                const txParamsWithNumberAmounts = JSON.parse(JSON.stringify(txParams));
                txParamsWithNumberAmounts.recipients[0].address = new tonweb_1.default.Address(txParamsWithNumberAmounts.recipients[0].address).toString(true, true, false);
                const verification = {};
                const isVerified = await basecoin.verifyTransaction({
                    txParams: txParamsWithNumberAmounts,
                    txPrebuild,
                    verification,
                });
                isVerified.should.equal(true);
            });
            it('should fail to verify transaction with invalid param', async function () {
                const txPrebuild = {};
                await basecoin
                    .verifyTransaction({
                    txParams,
                    txPrebuild,
                })
                    .should.rejectedWith('missing required tx prebuild property txHex');
            });
        });
    });
    describe('Explain Transaction: ', () => {
        const basecoin = bitgo.coin('tton');
        it('should explain a transfer transaction', async function () {
            const explainedTransaction = (await basecoin.explainTransaction({
                txHex: Buffer.from(testData.signedSendTransaction.tx, 'base64').toString('hex'),
            }));
            explainedTransaction.should.deepEqual({
                displayOrder: ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'withdrawAmount'],
                id: 'tuyOkyFUMv_neV_FeNBH24Nd4cML2jUgDP4zjGkuOFI=',
                outputs: [
                    {
                        address: testData.signedSendTransaction.recipient.address,
                        amount: testData.signedSendTransaction.recipient.amount,
                    },
                ],
                outputAmount: testData.signedSendTransaction.recipient.amount,
                changeOutputs: [],
                changeAmount: '0',
                fee: { fee: 'UNKNOWN' },
                withdrawAmount: undefined,
            });
        });
        it('should explain a non-bounceable transfer transaction', async function () {
            const explainedTransaction = (await basecoin.explainTransaction({
                txHex: Buffer.from(testData.signedSendTransaction.tx, 'base64').toString('hex'),
                toAddressBounceable: false,
                fromAddressBounceable: false,
            }));
            explainedTransaction.should.deepEqual({
                displayOrder: ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'withdrawAmount'],
                id: 'tuyOkyFUMv_neV_FeNBH24Nd4cML2jUgDP4zjGkuOFI=',
                outputs: [
                    {
                        address: testData.signedSendTransaction.recipientBounceable.address,
                        amount: testData.signedSendTransaction.recipientBounceable.amount,
                    },
                ],
                outputAmount: testData.signedSendTransaction.recipientBounceable.amount,
                changeOutputs: [],
                changeAmount: '0',
                fee: { fee: 'UNKNOWN' },
                withdrawAmount: undefined,
            });
        });
        it('should explain a single nominator withdraw transaction', async function () {
            const explainedTransaction = (await basecoin.explainTransaction({
                txHex: Buffer.from(testData.signedSingleNominatorWithdrawTransaction.tx, 'base64').toString('hex'),
            }));
            explainedTransaction.should.deepEqual({
                displayOrder: ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'withdrawAmount'],
                id: testData.signedSingleNominatorWithdrawTransaction.txId,
                outputs: [
                    {
                        address: testData.signedSingleNominatorWithdrawTransaction.recipient.address,
                        amount: testData.signedSingleNominatorWithdrawTransaction.recipient.amount,
                    },
                ],
                outputAmount: testData.signedSingleNominatorWithdrawTransaction.recipient.amount,
                changeOutputs: [],
                changeAmount: '0',
                fee: { fee: 'UNKNOWN' },
                withdrawAmount: '932178112330000',
            });
        });
        it('should explain a non-bounceable single nominator withdraw transaction', async function () {
            const explainedTransaction = (await basecoin.explainTransaction({
                txHex: Buffer.from(testData.signedSingleNominatorWithdrawTransaction.tx, 'base64').toString('hex'),
                toAddressBounceable: false,
                fromAddressBounceable: false,
            }));
            explainedTransaction.should.deepEqual({
                displayOrder: ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'withdrawAmount'],
                id: testData.signedSingleNominatorWithdrawTransaction.txIdBounceable,
                outputs: [
                    {
                        address: testData.signedSingleNominatorWithdrawTransaction.recipientBounceable.address,
                        amount: testData.signedSingleNominatorWithdrawTransaction.recipientBounceable.amount,
                    },
                ],
                outputAmount: testData.signedSingleNominatorWithdrawTransaction.recipientBounceable.amount,
                changeOutputs: [],
                changeAmount: '0',
                fee: { fee: 'UNKNOWN' },
                withdrawAmount: '932178112330000',
            });
        });
        it('should fail to explain transaction with missing params', async function () {
            try {
                await basecoin.explainTransaction({});
            }
            catch (error) {
                should_1.default.equal(error.message, 'Invalid transaction');
            }
        });
        it('should fail to explain transaction with invalid params', async function () {
            try {
                await basecoin.explainTransaction({ txHex: 'randomString' });
            }
            catch (error) {
                should_1.default.equal(error.message, 'Invalid transaction');
            }
        });
    });
    describe('Parse Transactions: ', () => {
        const basecoin = bitgo.coin('tton');
        const transactionsList = [testData.signedSendTransaction.tx, testData.signedSingleNominatorWithdrawTransaction.tx];
        const transactionInputsResponseList = [
            [
                {
                    address: 'EQCSBjR3fUOL98WTw2F_IT4BrcqjZJWVLWUSz5WQDpaL9Jpl',
                    amount: '10000000',
                },
            ],
            [
                {
                    address: 'EQAbJug-k-tufWMjEC1RKSM0iiJTDUcYkC7zWANHrkT55Fol',
                    amount: '123400000',
                },
            ],
        ];
        const transactionInputsResponseBounceableList = [
            [
                {
                    address: 'UQCSBjR3fUOL98WTw2F_IT4BrcqjZJWVLWUSz5WQDpaL9Meg',
                    amount: '10000000',
                },
            ],
            [
                {
                    address: 'UQAbJug-k-tufWMjEC1RKSM0iiJTDUcYkC7zWANHrkT55Afg',
                    amount: '123400000',
                },
            ],
        ];
        const transactionOutputsResponseList = [
            [
                {
                    address: 'EQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBXwtG',
                    amount: '10000000',
                },
            ],
            [
                {
                    address: 'EQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBXwtG',
                    amount: '123400000',
                },
            ],
        ];
        const transactionOutputsResponseBounceableList = [
            [
                {
                    address: 'UQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBX1aD',
                    amount: '10000000',
                },
            ],
            [
                {
                    address: 'UQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBX1aD',
                    amount: '123400000',
                },
            ],
        ];
        transactionsList.forEach((_, index) => {
            const transaction = transactionsList[index];
            const transactionInputsResponse = transactionInputsResponseList[index];
            const transactionInputsResponseBounceable = transactionInputsResponseBounceableList[index];
            const transactionOutputsResponse = transactionOutputsResponseList[index];
            const transactionOutputsResponseBounceable = transactionOutputsResponseBounceableList[index];
            it('should parse a TON transaction', async function () {
                const parsedTransaction = await basecoin.parseTransaction({
                    txHex: Buffer.from(transaction, 'base64').toString('hex'),
                });
                parsedTransaction.should.deepEqual({
                    inputs: transactionInputsResponse,
                    outputs: transactionOutputsResponse,
                });
            });
            it('should parse a non-bounceable TON transaction', async function () {
                const parsedTransaction = await basecoin.parseTransaction({
                    txHex: Buffer.from(transaction, 'base64').toString('hex'),
                    toAddressBounceable: false,
                    fromAddressBounceable: false,
                });
                parsedTransaction.should.deepEqual({
                    inputs: transactionInputsResponseBounceable,
                    outputs: transactionOutputsResponseBounceable,
                });
            });
            it('should fail to parse a TON transaction when explainTransaction response is undefined', async function () {
                const stub = sinon.stub(src_1.Ton.prototype, 'explainTransaction');
                stub.resolves(undefined);
                await basecoin.parseTransaction({ txHex: transaction }).should.be.rejectedWith('invalid raw transaction');
                stub.restore();
            });
        });
    });
    describe('Address Validation', () => {
        const basecoin = bitgo.coin('tton');
        let keychains;
        let commonKeychain;
        before(function () {
            commonKeychain =
                '19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781';
            keychains = [
                {
                    id: '6424c353eaf78d000766e95949868468',
                    source: 'user',
                    type: 'tss',
                    commonKeychain: '19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781',
                    encryptedPrv: '{"iv":"cZd5i7L4RxtwrALW2rK7UA==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"5zgoH1Bd3Fw=","ct":"9vVlnXFRtrM9FVEo+d2chbGHlM9lFZemueBuAs3BIkPo33Fo7jzwwNK/kIWkEyg+NmEBd5IaqAS157nvvvwzzsmMWlQdUz9qbmXNv3pg987cXFR08exS+4uhwP1YNOjJTRvRNcO9ZqHb46d4fmyJ/yC9/susCge7r/EsbaN5C3afv1dzybuq912FwaQElZLYYp5BICudFOMZ9k0UDMfKM/PMDkH7WexoGHr9GKq/bgCH2B39TZZyHKU6Uy47lXep2s6h0DrMwHOrnmiL3DZjOj88Ynvphlzxuo4eOlD2UHia2+nvIaISYs29Pr0DAvREutchvcBpExj1kWWPv7hQYrv8F0NAdatsbWl3w+xKyfiMKo1USlrwyJviypGtQtXOJyw0XPN0rv2+L5lW8BbjpzHfYYN13fJTedlGTFhhkzVtbbPAKE02kx7zCJcjYaiexdSTsrDLScYNT9/Jhdt27KpsooehwVohLfSKz4vbFfRu2MPZw3/+c/hfiJNgtz6esWbnxGrcE8U2IwPYCaK+Ghk4DcqWNIni59RI5B5kAsQOToII40qPN510uTgxBSPO7q7MHgkxdd4CqBq+ojr9j0P7oao8E5Y+CBDJrojDoCh1oCCDW9vo2dXlVcD8SIbw7U/9AfvEbA4xyE/5md1M7CIwLnWs2Ynv0YtaKoqhdS9x6FmHlMDhN/DKHinrwmowtrTT82fOkpO5g9saSmgU7Qy3gLt8t+VwdEyeFeQUKRSyci8qgqXQaZIg4+aXgaSOnlCFMtmB8ekYxEhTY5uzRfrNgS4s1QeqFBpNtUF+Ydi297pbVXnJoXAN+SVWd80GCx+yI2dpVC89k3rOWK9WeyqlnzuLJWp2RIOB9cdW8GFv/fN+QAJpYeVxOE4+nZDsKnsj8nKcg9t4Dlx1G6gLM1/Vq9YxNLbuzuRC0asUYvdMnoMvszmpm++TxndYisgNYscpZSoz7wvcazJNEPfhPVjEkd6tUUuN4GM35H0DmKCUQNT+a6B6hmHlTZvjxiyGAg5bY59hdjvJ+22QduazlEEC6LI3HrA7uK0TpplWzS1tCIFvTMUhj65DEZmNJ2+ZY9bQ4vsMf+DRR3OOG4t+DMlNfjOd3zNv3QoY95BjfWpryFwPzDq7bCP67JDsoj7j2TY5FRSrRkD77H0Ewlux2cWfjRTwcMHcdQxxuV0OP0aNjGDjybFN"}',
                },
                {
                    id: '6424c353eaf78d000766e96137d4404b',
                    source: 'backup',
                    type: 'tss',
                    commonKeychain: '19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781',
                    encryptedPrv: '{"iv":"vi0dPef/Rx7kG/pRySQi6Q==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"9efhQsiEvVs=","ct":"Gw6atvf6gxKzsjtl3xseipO3rAxp1mAz7Yu1ihFsi5/lf2vMZegApgZx+pyILFS9KKLHbNF3U6WgSYdrr2t4vzdLsXkH1WIxfHS+cd2C5N59yADZDnPJBT6pv/IRvaYelP0Ck3nIYQ2hSMm8op+VOWC/SzHeh7slYDqwEHTGan0Wigfvk1yRd7CCJTaEAomnc/4eFi2NY3X3gt/3opy9IAgknnwUFohn96EWpEQ0F6pbzH/Z8VF6gF+DUcrrByAxExUPnHQZiFk3YHU/vVV4FxBU/mVAE8xBsBn5ul5e5SUMPfc7TBuJWv4BByTNg9xDShF/91Yx2nbfUm5d9QmM8lpKgzzQvcK8POAPk87gRCuKnsGh5vNS0UppkHc+ocfzRQlGA6jze7QyyQO0rMj5Ly8kWjwk2vISvKYHYS1NR7VU549UIXo7NXjatunKSc3+IreoRUHIshiaLg6hl+pxCCuc0qQ43V0mdIfCjTN8gkGWLNk8R7tAGPz9jyapQPcPEGHgEz0ATIi6yMNWCsibS2eLiE1uVEJONoM4lk6FPl3Q2CHbW2MeEbqjY8hbaw18mNb2xSBH/Fwpiial+Tvi2imqgnCO4ZpO9bllKftZPcQy0stN+eGBlb5ufyflKkDSiChHYroGjEpmiFicdde48cJszF52uKNnf1q67fA9/S2FAHQab3EXojxH2Gbk+kkV2h/TYKFFZSWC3vi4e8mO+vjMUcR0AdsgPFyEIz0SCGuba3CnTLNdEuZwsauAeHkx2vUTnRgJPVgNeeuXmsVG76Sy2ggJHuals0Hj8U2Xda0qO1RuFfoCWfss9wn6HGRwPPkhSB/8oNguAqmRVGKkd8Zwt3IvrTd9fk0/rFFDJKGz7WyNHkYgUmNiGcItD12v0jx7FZ52EJzl3Av1RyJUQK18+8EYPh3SGiU9dt7VX0aF0uo6JouKhOeldUvMP+AugQz8fUclwTQsbboVg27Yxo0DyATVwThW5a56R6Qf5ZiQJluFuzs5y98rq0S5q046lE6o3vVmJpEdwjeSCJoET5CL4nTgkXyWvhm4eB8u/e66l3o0qbaSx8q9YYmT9EpRcl5TP4ThLBKETYdzVvg4exjQfektMatk5EyUpEIhZPXh5vXpJZesdfO9LJ8zTaHBsBjDPU7cdNgQMbebpataRi8A0el2/IJXl+E+olgAz5zC4i2O1Q=="}',
                },
                {
                    id: '6424c353eaf78d000766e9510b125fba',
                    source: 'bitgo',
                    type: 'tss',
                    commonKeychain: '19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781',
                    verifiedVssProof: true,
                    isBitGo: true,
                },
            ];
        });
        it('should return true when validating a well formatted address', async function () {
            const address = 'UQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFOMi';
            basecoin.isValidAddress(address).should.equal(true);
        });
        it('should return false when validating an incorrectly formatted', async function () {
            const address = 'wrongaddress';
            basecoin.isValidAddress(address).should.equal(false);
        });
        it('should return true when validating a non-bounceable address format', async function () {
            const address = 'UQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBX1aD';
            basecoin.isValidAddress(address).should.equal(true);
        });
        it('should return true when validating addresses with memoIds', async function () {
            const address1 = 'EQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFL7n?memoId=123';
            const address2 = 'UQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFOMi?memoId=123';
            basecoin.isValidAddress(address1).should.equal(true);
            basecoin.isValidAddress(address2).should.equal(true);
        });
        it('should return true for isWalletAddress with valid address for index 4', async function () {
            const newAddress = 'EQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFL7n';
            const index = 4;
            const params = { commonKeychain, address: newAddress, index, keychains };
            (await basecoin.isWalletAddress(params)).should.equal(true);
        });
        it('should return true for isWalletAddress with valid addressand index', async function () {
            const newAddress = 'EQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFL7n?memoId=4';
            const index = 4;
            const params = { commonKeychain, address: newAddress, index, keychains };
            (await basecoin.isWalletAddress(params)).should.equal(true);
        });
        it('should return false for isWalletAddress with valid address for index 5 and address is for a different index', async function () {
            const wrongAddressForIndex5 = 'EQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFL7n';
            const index = 5;
            const params = { commonKeychain, address: wrongAddressForIndex5, index, keychains };
            (await basecoin.isWalletAddress(params)).should.equal(false);
        });
        it('should throw error for isWalletAddress when keychains is missing', async function () {
            const address = 'EQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFL7n';
            const index = 0;
            const params = { commonKeychain, address, index };
            await assert_1.default.rejects(async () => basecoin.isWalletAddress(params));
        });
        it('should throw error for isWalletAddress when new address is invalid', async function () {
            const wrongAddress = 'badAddress';
            const index = 0;
            const params = { commonKeychain, address: wrongAddress, index };
            await assert_1.default.rejects(async () => basecoin.isWalletAddress(params), {
                message: `invalid address: ${wrongAddress}`,
            });
        });
    });
    describe('util class ', () => {
        let commonKeychain;
        let derivedPublicKey;
        before(async function () {
            commonKeychain =
                '19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781';
            const MPC = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
            derivedPublicKey = MPC.deriveUnhardened(commonKeychain, 'm/' + 0).slice(0, 64);
        });
        describe('getAddressFromPublicKey', function () {
            it('should derive bounceable address by default', async function () {
                (await utils_1.default.getAddressFromPublicKey(derivedPublicKey)).should.equal('EQDVeyUJOx3AnZGWLtE0l-Vxv7c7uTnD8OXtCFhaO-nvavQ5');
                (await utils_1.default.getAddressFromPublicKey(derivedPublicKey, true)).should.equal('EQDVeyUJOx3AnZGWLtE0l-Vxv7c7uTnD8OXtCFhaO-nvavQ5');
            });
            it('should derive non-bounceable address when requested', async function () {
                (await utils_1.default.getAddressFromPublicKey(derivedPublicKey, false)).should.equal('UQDVeyUJOx3AnZGWLtE0l-Vxv7c7uTnD8OXtCFhaO-nvaqn8');
            });
            it('should derive raw address when requested', async function () {
                (await utils_1.default.getAddressFromPublicKey(derivedPublicKey, false, false)).should.equal('0:d57b25093b1dc09d91962ed13497e571bfb73bb939c3f0e5ed08585a3be9ef6a');
            });
        });
        describe('getAddress', function () {
            it('should return address as per bounceable flag', function () {
                should_1.default.equal(utils_1.default.getAddress('UQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFOMi', false), 'UQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFOMi');
                should_1.default.equal(utils_1.default.getAddress('UQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFOMi', true), 'EQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFL7n');
                should_1.default.equal(utils_1.default.getAddress('EQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFL7n', true), 'EQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFL7n');
                should_1.default.equal(utils_1.default.getAddress('EQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFL7n', false), 'UQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFOMi');
            });
        });
        it('should validate block hash', async function () {
            should_1.default.equal(utils_1.default.isValidBlockId('MPuOvHdu/z+t2l82YpZtiJQk8+FVKmWuKxd6ubn09fI='), true);
            should_1.default.equal(utils_1.default.isValidBlockId('MPuOvHdu/z+t2l82YpZtiJQk8+FVKmWuKxd'), false);
            should_1.default.equal(utils_1.default.isValidBlockId(''), false);
        });
        it('should validate transaction id', async function () {
            should_1.default.equal(utils_1.default.isValidTransactionId('wlTdDOAXwJp8ESRfQAEJQIn0Tci_S5oLbVKBYxDtvpk='), true);
            should_1.default.equal(utils_1.default.isValidTransactionId('3sykx6Rujy7UtBwHQ/X5kLgvKE0SKLA+ABiCKi7sX8o='), true); // No url friendly txid
            should_1.default.equal(utils_1.default.isValidTransactionId('3sykx6Rujy7UtBwHQ_X5kLgvKE0SKLA-ABiCKi7sX8o='), true); // Url friendly txid
            should_1.default.equal(utils_1.default.isValidTransactionId('wlTdDOAXwJp8ESRfQAEJQIn0Tci_S5oLb='), false);
            should_1.default.equal(utils_1.default.isValidTransactionId('wlTdDOAXwJp8ESRfQAEJQIn0Tci_S5oLbVKBYxDtafdsasdadsfvpk='), false);
            should_1.default.equal(utils_1.default.isValidTransactionId(''), false);
        });
        it('should generate transaction id', async function () {
            const id = await utils_1.default.getMessageHashFromData('te6cckECCgEAAkoAA7V2k4Vw1nhxr7XcCBjWcFFHKqGwCglPSRuYAkWjWiTVAIAAAPbLgva0G7ytKw/xeE9a3FHK2RM8fgOpGvTpQRseeMer3efRKsiQAADxPhnaQFZWYrlQADRqbCUIAQIDAgHgBAUAgnIAZ0UIwmknkMaW7QboTcq48FfZ1NT5oMUj2VPOBr3zPoxriab4SfV65i6Hd1J2sFsuTcIWUobcKXMcIys+JWknAhMMwSvWBhmTzwRACAkB4YgA0nCuGs8ONfa7gQMazgoo5VQ2AUEp6SNzAEi0a0SaoBAHHgnPJBQQJ/meoCwzK5/PajBSxuJK2Gkva7NmlALNDs2IMEWi4ZRfIV4VeJpKBhzhKjNlFjuz60g+aeT5cNi4CU1NGLsrey/4AAAAGAAcBgEB3wcAaGIAK2cYdYCtxtBaWJ9hi7N+HVzeMsPQxLHSqYn7bfpOcRyh3NZQAAAAAAAAAAAAAAAAAAAAsWgA0nCuGs8ONfa7gQMazgoo5VQ2AUEp6SNzAEi0a0SaoBEAFbOMOsBW42gtLE+wxdm/Dq5vGWHoYljpVMT9tv0nOI5Q7msoAAYUWGAAAB7ZcF7WhMrMVypAAJ1BnYMTiAAAAAAAAAAAEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAG/Jh6EgTBRYQAAAAAAAAgAAAAAAA4E52AP/eAYnVhJkoII4YUrhpLfpDFt6mRKiktbFnqs+QFAWDAAacQ0=\\');
            should_1.default.equal(id, 'TsVgNKT05cde4Q54sC+RFC7nToTrHk9ppGgE5M0jXtE=');
        });
        it('should deserialize a cell to get the address', function () {
            const data1 = 'te6cckEBAQEAJAAAQ4AaFUTgUQ/k2i+DdAooib0wNVREZQ2z+8R9WQvvFNpUJBARyAgK';
            const rawAddress1 = '0:d0aa2702887f26d17c1ba051444de981aaa223286d9fde23eac85f78a6d2a120';
            should_1.default.equal(utils_1.default.getRawWalletAddressFromCell(data1), rawAddress1);
            const data2 = 'te6cckEBAQEAJAAAQ5/75w034qP9T0ZXY3muM5ouvFlNoNPky2YUs+Hcxd8otjDkIOPq';
            const rawAddress2 = '-1:df3869bf151fea7a32bb1bcd719cd175e2ca6d069f265b30a59f0ee62ef945b1';
            should_1.default.equal(utils_1.default.getRawWalletAddressFromCell(data2), rawAddress2);
        });
    });
    describe('Ton recover - Non-BitGo and Unsigned Sweep Transactions', function () {
        let sandbox;
        beforeEach(() => {
            sandbox = sinon.createSandbox(); // Create a new sandbox for each test
        });
        afterEach(() => {
            sandbox.restore(); // Restore all stubs after each test
        });
        it('should successfully recover funds for non-BitGo recovery', async function () {
            // Define recovery parameters
            const recoveryParams = {
                bitgoKey: '1baafa0d62174bf0c78f3256318613ffc44b6dd54ab1a63c2185232f92ede9dae1b2818dbeb52a8215fd56f5a5f2a9f94c079ce89e4dc3b1ce6ed6e84ce71857',
                recoveryDestination: 'UQBL2idCXR4ATdQtaNa4VpofcpSxuxIgHH7_slOZfdOXSadJ',
                apiKey: 'db2554641c61e60a979cc6c0053f2ec91da9b13e71d287768c93c2fb556be53b',
                userKey: '1baafa0d62174bf0c78f3256318613ffc44b6dd54ab1a63c2185232f92ede9dae1b2818dbeb52a8215fd56f5a5f2a9f94c079ce89e4dc3b1ce6ed6e84ce71857',
                walletPassphrase: 'dummyPassphrase',
            };
            // Mock the expected result for non-BitGo recovery
            const mockResult = {
                serializedTx: 'te6cckEBAgEAqgAB4YgAl7ROhLo8AJuoWtGtcK00PuUpY3YkQDj9/2SnMvunLpIFbl896wlMv7fsUOc+sMHzEl8q3vX5bm6noHginPJKBRznOrO7veIpHIEpiRLbH7/eNdpSsRhvL260JP/fD0vAIU1NGLtABDqAAAAACAAcAQBoQgB/OeiNdLeaL7+O04XuujuChSGrRd7ZnFl2fCd9FXdzAyDOJYCwAAAAAAAAAAAAAAAAAFwXGt8=',
                scanIndex: 0,
                coin: 'tton',
            };
            // Stub the recover function to return the mocked result
            const sandbox = sinon.createSandbox();
            sandbox.stub(basecoin, 'recover').resolves(mockResult);
            // Call the recover function
            const result = await basecoin.recover(recoveryParams);
            // Validate the result
            result.serializedTx.should.equal('te6cckEBAgEAqgAB4YgAl7ROhLo8AJuoWtGtcK00PuUpY3YkQDj9/2SnMvunLpIFbl896wlMv7fsUOc+sMHzEl8q3vX5bm6noHginPJKBRznOrO7veIpHIEpiRLbH7/eNdpSsRhvL260JP/fD0vAIU1NGLtABDqAAAAACAAcAQBoQgB/OeiNdLeaL7+O04XuujuChSGrRd7ZnFl2fCd9FXdzAyDOJYCwAAAAAAAAAAAAAAAAAFwXGt8=');
            result.scanIndex.should.equal(0);
            result.coin.should.equal('tton');
            sandbox.restore(); // Restore the stubbed method
        });
        it('should return an unsigned sweep transaction if userKey and backupKey are missing', async function () {
            // Define recovery parameters
            const recoveryParams = {
                bitgoKey: '1baafa0d62174bf0c78f3256318613ffc44b6dd54ab1a63c2185232f92ede9dae1b2818dbeb52a8215fd56f5a5f2a9f94c079ce89e4dc3b1ce6ed6e84ce71857',
                recoveryDestination: 'UQBL2idCXR4ATdQtaNa4VpofcpSxuxIgHH7_slOZfdOXSadJ',
                apiKey: 'db2554641c61e60a979cc6c0053f2ec91da9b13e71d287768c93c2fb556be53b',
            };
            // Mock the expected result for unsigned sweep transaction
            const mockUnsignedTx = {
                serializedTx: 'te6cckEBAgEAqgAB4YgAl7ROhLo8AJuoWtGtcK00PuUpY3YkQDj9/2SnMvunLpIFbl896wlMv7fsUOc+sMHzEl8q3vX5bm6noHginPJKBRznOrO7veIpHIEpiRLbH7/eNdpSsRhvL260JP/fD0vAIU1NGLtABDqAAAAACAAcAQBoQgB/OeiNdLeaL7+O04XuujuChSGrRd7ZnFl2fCd9FXdzAyDOJYCwAAAAAAAAAAAAAAAAAFwXGt8=',
                scanIndex: 0,
                coin: 'tton',
                signableHex: 'dd98eb5a3700c0203237095ca1c0d5288bc0d650a9b59f7b81bac552f76137df',
                derivationPath: 'm/0',
                parsedTx: {
                    inputs: [
                        {
                            address: 'UQBL2idCXR4ATdQtaNa4VpofcpSxuxIgHH7_slOZfdOXSadJ',
                            valueString: '1000000000',
                            value: 1000000000,
                        },
                    ],
                    outputs: [
                        {
                            address: 'UQBL2idCXR4ATdQtaNa4VpofcpSxuxIgHH7_slOZfdOXSadJ',
                            valueString: '999000000',
                            coinName: 'tton',
                        },
                    ],
                    spendAmount: 999000000,
                    type: '',
                },
                feeInfo: {
                    fee: 1000000,
                    feeString: '1000000',
                },
                coinSpecific: {
                    commonKeychain: '1baafa0d62174bf0c78f3256318613ffc44b6dd54ab1a63c2185232f92ede9dae1b2818dbeb52a8215fd56f5a5f2a9f94c079ce89e4dc3b1ce6ed6e84ce71857',
                },
            };
            const mockTxRequest = {
                transactions: [
                    {
                        unsignedTx: mockUnsignedTx,
                        signatureShares: [],
                    },
                ],
                walletCoin: 'ton',
            };
            const mockTxRequests = {
                txRequests: [mockTxRequest],
            };
            // Stub the recover function to return the mocked unsigned sweep transaction
            const sandbox = sinon.createSandbox();
            sandbox.stub(basecoin, 'recover').resolves(mockTxRequests);
            // Call the recover function
            const result = await basecoin.recover(recoveryParams);
            // Validate the result
            result.should.have.property('txRequests');
            result.txRequests[0].should.have.property('transactions');
            result.txRequests[0].transactions[0].should.have.property('unsignedTx');
            result.txRequests[0].transactions[0].unsignedTx.should.equal(mockUnsignedTx);
        });
        it('should take OVC output and generate a signed sweep transaction', async function () {
            // Define the parameters (mock OVC response)
            const params = {
                ovcResponse: {
                    serializedTx: 'te6cckEBAgEAqgAB4YgAl7ROhLo8AJuoWtGtcK00PuUpY3YkQDj9/2SnMvunLpIFbl896wlMv7fsUOc+sMHzEl8q3vX5bm6noHginPJKBRznOrO7veIpHIEpiRLbH7/eNdpSsRhvL260JP/fD0vAIU1NGLtABDqAAAAACAAcAQBoQgB/OeiNdLeaL7+O04XuujuChSGrRd7ZnFl2fCd9FXdzAyDOJYCwAAAAAAAAAAAAAAAAAFwXGt8=',
                    scanIndex: 0,
                    lastScanIndex: 0,
                },
            };
            // Mock the expected result for the signed sweep transaction
            const mockSignedSweepTxn = {
                transactions: [
                    {
                        serializedTx: 'te6cckEBAgEAqgAB4YgAl7ROhLo8AJuoWtGtcK00PuUpY3YkQDj9/2SnMvunLpIFbl896wlMv7fsUOc+sMHzEl8q3vX5bm6noHginPJKBRznOrO7veIpHIEpiRLbH7/eNdpSsRhvL260JP/fD0vAIU1NGLtABDqAAAAACAAcAQBoQgB/OeiNdLeaL7+O04XuujuChSGrRd7ZnFl2fCd9FXdzAyDOJYCwAAAAAAAAAAAAAAAAAFwXGt8=',
                        scanIndex: 0,
                    },
                ],
                lastScanIndex: 0,
            };
            // Stub the createBroadcastableSweepTransaction function to return the mocked result
            sandbox.stub(basecoin, 'createBroadcastableSweepTransaction').resolves(mockSignedSweepTxn);
            // Call the createBroadcastableSweepTransaction function
            const recoveryTxn = await basecoin.createBroadcastableSweepTransaction(params);
            // Validate the result
            recoveryTxn.transactions[0].serializedTx.should.equal('te6cckEBAgEAqgAB4YgAl7ROhLo8AJuoWtGtcK00PuUpY3YkQDj9/2SnMvunLpIFbl896wlMv7fsUOc+sMHzEl8q3vX5bm6noHginPJKBRznOrO7veIpHIEpiRLbH7/eNdpSsRhvL260JP/fD0vAIU1NGLtABDqAAAAACAAcAQBoQgB/OeiNdLeaL7+O04XuujuChSGrRd7ZnFl2fCd9FXdzAyDOJYCwAAAAAAAAAAAAAAAAAFwXGt8=');
            recoveryTxn.transactions[0].scanIndex.should.equal(0);
            recoveryTxn.lastScanIndex.should.equal(0);
        });
    });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L3Rvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDhDQUE0QztBQUM1Qyw0Q0FBMEM7QUFDMUMsbUNBQWtFO0FBQ2xFLDZDQUErQjtBQUMvQixvREFBNEI7QUFDNUIsMkRBQTZDO0FBQzdDLDhDQUF1RTtBQUN2RSxvREFBNEI7QUFDNUIsZ0VBQXdDO0FBQ3hDLG9EQUE0QjtBQUU1QixRQUFRLENBQUMsTUFBTSxFQUFFO0lBQ2YsSUFBSSxRQUFRLENBQUM7SUFDYixNQUFNLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxrQkFBUSxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDNUQsS0FBSyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsU0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQzlDLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLFVBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUNoRCxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztJQUMzQixNQUFNLGNBQWMsR0FBRztRQUNyQjtZQUNFLEtBQUssRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxFQUFFLEVBQUUsUUFBUSxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztZQUMvRSxNQUFNLEVBQUUsRUFBRTtTQUNYO1FBQ0Q7WUFDRSxLQUFLLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsd0NBQXdDLENBQUMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7WUFDbEcsTUFBTSxFQUFFLEVBQUU7U0FDWDtLQUNGLENBQUM7SUFDRixNQUFNLHdCQUF3QixHQUFHO1FBQy9CO1lBQ0UsS0FBSyxF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LEVBQUUsQ0FBQztvQkFDWixhQUFhLEVBQUUsQ0FBQztpQkFDakI7YUFDRixDQUFDO1lBRUYsNERBQTREO1lBQzVELE1BQU0sa0JBQWtCLEdBQUc7Z0JBQ3pCLFlBQVksRUFBRTtvQkFDWjt3QkFDRSxZQUFZLEVBQ1YsMFBBQTBQO3dCQUM1UCxTQUFTLEVBQUUsQ0FBQztxQkFDYjtpQkFDRjtnQkFDRCxhQUFhLEVBQUUsQ0FBQzthQUNqQixDQUFDO1lBRUYsb0ZBQW9GO1lBQ3BGLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLHFDQUFxQyxDQUFDLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFFM0Ysd0RBQXdEO1lBQ3hELE1BQU0sV0FBVyxHQUFHLE1BQU0sUUFBUSxDQUFDLG1DQUFtQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBRS9FLHNCQUFzQjtZQUN0QixXQUFXLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUNuRCwwUEFBMFAsQ0FDM1AsQ0FBQztZQUNGLFdBQVcsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDdEQsV0FBVyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFRlc3RCaXRHbyB9IGZyb20gJ0BiaXRnby9zZGstdGVzdCc7XG5pbXBvcnQgeyBCaXRHb0FQSSB9IGZyb20gJ0BiaXRnby9zZGstYXBpJztcbmltcG9ydCB7IFRvbiwgVG9uUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMsIFR0b24gfSBmcm9tICcuLi8uLi9zcmMnO1xuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0ICogYXMgdGVzdERhdGEgZnJvbSAnLi4vcmVzb3VyY2VzL3Rvbic7XG5pbXBvcnQgeyBFRERTQU1ldGhvZHMsIFRyYW5zYWN0aW9uRXhwbGFuYXRpb24gfSBmcm9tICdAYml0Z28vc2RrLWNvcmUnO1xuaW1wb3J0IHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0IHV0aWxzIGZyb20gJy4uLy4uL3NyYy9saWIvdXRpbHMnO1xuaW1wb3J0IFRvbndlYiBmcm9tICd0b253ZWInO1xuXG5kZXNjcmliZSgnVE9OOicsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IGJhc2Vjb2luO1xuICBjb25zdCBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICdtb2NrJyB9KTtcbiAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0b24nLCBUb24uY3JlYXRlSW5zdGFuY2UpO1xuICBiaXRnby5zYWZlUmVnaXN0ZXIoJ3R0b24nLCBUdG9uLmNyZWF0ZUluc3RhbmNlKTtcbiAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gIGNvbnN0IHR4UHJlYnVpbGRMaXN0ID0gW1xuICAgIHtcbiAgICAgIHR4SGV4OiBCdWZmZXIuZnJvbSh0ZXN0RGF0YS5zaWduZWRTZW5kVHJhbnNhY3Rpb24udHgsICdiYXNlNjQnKS50b1N0cmluZygnaGV4JyksXG4gICAgICB0eEluZm86IHt9LFxuICAgIH0sXG4gICAge1xuICAgICAgdHhIZXg6IEJ1ZmZlci5mcm9tKHRlc3REYXRhLnNpZ25lZFNpbmdsZU5vbWluYXRvcldpdGhkcmF3VHJhbnNhY3Rpb24udHgsICdiYXNlNjQnKS50b1N0cmluZygnaGV4JyksXG4gICAgICB0eEluZm86IHt9LFxuICAgIH0sXG4gIF07XG4gIGNvbnN0IHR4UHJlYnVpbGRCb3VuY2VhYmxlTGlzdCA9IFtcbiAgICB7XG4gICAgICB0eEhleDogQnVmZmVyLmZyb20odGVzdERhdGEuc2lnbmVkU2VuZFRyYW5zYWN0aW9uLnR4Qm91bmNlYWJsZSwgJ2Jhc2U2NCcpLnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgIHR4SW5mbzoge30sXG4gICAgfSxcbiAgICB7XG4gICAgICB0eEhleDogQnVmZmVyLmZyb20odGVzdERhdGEuc2lnbmVkU2luZ2xlTm9taW5hdG9yV2l0aGRyYXdUcmFuc2FjdGlvbi50eEJvdW5jZWFibGUsICdiYXNlNjQnKS50b1N0cmluZygnaGV4JyksXG4gICAgICB0eEluZm86IHt9LFxuICAgIH0sXG4gIF07XG5cbiAgY29uc3QgdHhQYXJhbXNMaXN0ID0gW1xuICAgIHtcbiAgICAgIHJlY2lwaWVudHM6IFt0ZXN0RGF0YS5zaWduZWRTZW5kVHJhbnNhY3Rpb24ucmVjaXBpZW50XSxcbiAgICB9LFxuICAgIHtcbiAgICAgIHJlY2lwaWVudHM6IFt0ZXN0RGF0YS5zaWduZWRTaW5nbGVOb21pbmF0b3JXaXRoZHJhd1RyYW5zYWN0aW9uLnJlY2lwaWVudF0sXG4gICAgfSxcbiAgXTtcblxuICBjb25zdCB0eFBhcmFtc0JvdW5jZWFibGVMaXN0ID0gW1xuICAgIHtcbiAgICAgIHJlY2lwaWVudHM6IFt0ZXN0RGF0YS5zaWduZWRTZW5kVHJhbnNhY3Rpb24ucmVjaXBpZW50Qm91bmNlYWJsZV0sXG4gICAgfSxcbiAgICB7XG4gICAgICByZWNpcGllbnRzOiBbdGVzdERhdGEuc2lnbmVkU2luZ2xlTm9taW5hdG9yV2l0aGRyYXdUcmFuc2FjdGlvbi5yZWNpcGllbnRCb3VuY2VhYmxlXSxcbiAgICB9LFxuICBdO1xuXG4gIGl0KCdzaG91bGQgcmV0dXJuIHRoZSByaWdodCBpbmZvJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHRvbiA9IGJpdGdvLmNvaW4oJ3RvbicpO1xuICAgIGNvbnN0IHR0b24gPSBiaXRnby5jb2luKCd0dG9uJyk7XG5cbiAgICB0b24uZ2V0Q2hhaW4oKS5zaG91bGQuZXF1YWwoJ3RvbicpO1xuICAgIHRvbi5nZXRGYW1pbHkoKS5zaG91bGQuZXF1YWwoJ3RvbicpO1xuICAgIHRvbi5nZXRGdWxsTmFtZSgpLnNob3VsZC5lcXVhbCgnVG9uJyk7XG4gICAgdG9uLmdldEJhc2VGYWN0b3IoKS5zaG91bGQuZXF1YWwoMWU5KTtcblxuICAgIHR0b24uZ2V0Q2hhaW4oKS5zaG91bGQuZXF1YWwoJ3R0b24nKTtcbiAgICB0dG9uLmdldEZhbWlseSgpLnNob3VsZC5lcXVhbCgndG9uJyk7XG4gICAgdHRvbi5nZXRGdWxsTmFtZSgpLnNob3VsZC5lcXVhbCgnVGVzdG5ldCBUb24nKTtcbiAgICB0dG9uLmdldEJhc2VGYWN0b3IoKS5zaG91bGQuZXF1YWwoMWU5KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1ZlcmlmeSB0cmFuc2FjdGlvbjogJywgKCkgPT4ge1xuICAgIGJhc2Vjb2luID0gYml0Z28uY29pbigndHRvbicpO1xuICAgIHR4UGFyYW1zTGlzdC5mb3JFYWNoKChfLCBpbmRleCkgPT4ge1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSB0eFBhcmFtc0xpc3RbaW5kZXhdO1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHR4UHJlYnVpbGRMaXN0W2luZGV4XTtcbiAgICAgIGNvbnN0IHR4UGFyYW1zQm91bmNlYWJsZSA9IHR4UGFyYW1zQm91bmNlYWJsZUxpc3RbaW5kZXhdO1xuICAgICAgY29uc3QgdHhQcmVidWlsZEJvdW5jZWFibGUgPSB0eFByZWJ1aWxkQm91bmNlYWJsZUxpc3RbaW5kZXhdO1xuXG4gICAgICBpdCgnc2hvdWxkIHN1Y2NlZWQgdG8gdmVyaWZ5IHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcbiAgICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zLFxuICAgICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgICB9IGFzIGFueSk7XG4gICAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG5cbiAgICAgICAgY29uc3QgaXNCb3VuY2VhYmxlVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtczogdHhQYXJhbXNCb3VuY2VhYmxlLFxuICAgICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGRCb3VuY2VhYmxlLFxuICAgICAgICAgIHZlcmlmaWNhdGlvbjoge30sXG4gICAgICAgIH0gYXMgYW55KTtcbiAgICAgICAgaXNCb3VuY2VhYmxlVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBzdWNjZWVkIHRvIHZlcmlmeSB0cmFuc2FjdGlvbiB3aGVuIHJlY2lwaWVudHMgYW1vdW50IGFyZSBudW1iZXJzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB0eFBhcmFtc1dpdGhOdW1iZXJBbW91bnRzID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0eFBhcmFtcykpO1xuICAgICAgICB0eFBhcmFtc1dpdGhOdW1iZXJBbW91bnRzLnJlY2lwaWVudHNbMF0uYW1vdW50ID0gMjAwMDAwMDA7XG4gICAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuICAgICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICB0eFBhcmFtczogdHhQYXJhbXNXaXRoTnVtYmVyQW1vdW50cyxcbiAgICAgICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgICAgfSBhcyBhbnkpXG4gICAgICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ1R4IG91dHB1dHMgZG9lcyBub3QgbWF0Y2ggd2l0aCBleHBlY3RlZCB0eFBhcmFtcyByZWNpcGllbnRzJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBzdWNjZWVkIHRvIHZlcmlmeSB0cmFuc2FjdGlvbiB3aGVuIHJlY2lwaWVudHMgYW1vdW50IGFyZSBzdHJpbmdzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB0eFBhcmFtc1dpdGhOdW1iZXJBbW91bnRzID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0eFBhcmFtcykpO1xuICAgICAgICB0eFBhcmFtc1dpdGhOdW1iZXJBbW91bnRzLnJlY2lwaWVudHNbMF0uYW1vdW50ID0gJzIwMDAwMDAwJztcbiAgICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG4gICAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICAgIHR4UGFyYW1zOiB0eFBhcmFtc1dpdGhOdW1iZXJBbW91bnRzLFxuICAgICAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgICAgICB9IGFzIGFueSlcbiAgICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnVHggb3V0cHV0cyBkb2VzIG5vdCBtYXRjaCB3aXRoIGV4cGVjdGVkIHR4UGFyYW1zIHJlY2lwaWVudHMnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHN1Y2NlZWQgdG8gdmVyaWZ5IHRyYW5zYWN0aW9uIHdoZW4gcmVjaXBpZW50cyBhbW91bnRzIGFyZSBudW1iZXIgYW5kIGFtb3VudCBpcyBzYW1lJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcbiAgICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgICAgIH0gYXMgYW55KVxuICAgICAgICAgIC5zaG91bGQucmVzb2x2ZWRXaXRoKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgc3VjY2VlZCB0byB2ZXJpZnkgdHJhbnNhY3Rpb24gd2hlbiByZWNpcGllbnRzIGFtb3VudHMgYXJlIHN0cmluZyBhbmQgYW1vdW50IGlzIHNhbWUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuICAgICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgICAgfSBhcyBhbnkpXG4gICAgICAgICAgLnNob3VsZC5yZXNvbHZlZFdpdGgodHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBzdWNjZWVkIHRvIHZlcmlmeSB0cmFuc2FjdGlvbiB3aGVuIHJlY2lwaWVudCBhZGRyZXNzIGFyZSBub24gYm91bmNlYWJsZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdHhQYXJhbXNXaXRoTnVtYmVyQW1vdW50cyA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodHhQYXJhbXMpKTtcbiAgICAgICAgdHhQYXJhbXNXaXRoTnVtYmVyQW1vdW50cy5yZWNpcGllbnRzWzBdLmFkZHJlc3MgPSBuZXcgVG9ud2ViLkFkZHJlc3MoXG4gICAgICAgICAgdHhQYXJhbXNXaXRoTnVtYmVyQW1vdW50cy5yZWNpcGllbnRzWzBdLmFkZHJlc3NcbiAgICAgICAgKS50b1N0cmluZyh0cnVlLCB0cnVlLCBmYWxzZSk7XG4gICAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuICAgICAgICBjb25zdCBpc1ZlcmlmaWVkID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zOiB0eFBhcmFtc1dpdGhOdW1iZXJBbW91bnRzLFxuICAgICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgICB9IGFzIGFueSk7XG4gICAgICAgIGlzVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZmFpbCB0byB2ZXJpZnkgdHJhbnNhY3Rpb24gd2l0aCBpbnZhbGlkIHBhcmFtJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB0eFByZWJ1aWxkID0ge307XG4gICAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICAgIHR4UGFyYW1zLFxuICAgICAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgICB9IGFzIGFueSlcbiAgICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnbWlzc2luZyByZXF1aXJlZCB0eCBwcmVidWlsZCBwcm9wZXJ0eSB0eEhleCcpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdFeHBsYWluIFRyYW5zYWN0aW9uOiAnLCAoKSA9PiB7XG4gICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0dG9uJyk7XG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGEgdHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IChhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQnVmZmVyLmZyb20odGVzdERhdGEuc2lnbmVkU2VuZFRyYW5zYWN0aW9uLnR4LCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgfSkpIGFzIFRyYW5zYWN0aW9uRXhwbGFuYXRpb247XG4gICAgICBleHBsYWluZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbJ2lkJywgJ291dHB1dHMnLCAnb3V0cHV0QW1vdW50JywgJ2NoYW5nZU91dHB1dHMnLCAnY2hhbmdlQW1vdW50JywgJ2ZlZScsICd3aXRoZHJhd0Ftb3VudCddLFxuICAgICAgICBpZDogJ3R1eU9reUZVTXZfbmVWX0ZlTkJIMjROZDRjTUwyalVnRFA0empHa3VPRkk9JyxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6IHRlc3REYXRhLnNpZ25lZFNlbmRUcmFuc2FjdGlvbi5yZWNpcGllbnQuYWRkcmVzcyxcbiAgICAgICAgICAgIGFtb3VudDogdGVzdERhdGEuc2lnbmVkU2VuZFRyYW5zYWN0aW9uLnJlY2lwaWVudC5hbW91bnQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgb3V0cHV0QW1vdW50OiB0ZXN0RGF0YS5zaWduZWRTZW5kVHJhbnNhY3Rpb24ucmVjaXBpZW50LmFtb3VudCxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBmZWU6IHsgZmVlOiAnVU5LTk9XTicgfSxcbiAgICAgICAgd2l0aGRyYXdBbW91bnQ6IHVuZGVmaW5lZCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGEgbm9uLWJvdW5jZWFibGUgdHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IChhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQnVmZmVyLmZyb20odGVzdERhdGEuc2lnbmVkU2VuZFRyYW5zYWN0aW9uLnR4LCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICB0b0FkZHJlc3NCb3VuY2VhYmxlOiBmYWxzZSxcbiAgICAgICAgZnJvbUFkZHJlc3NCb3VuY2VhYmxlOiBmYWxzZSxcbiAgICAgIH0pKSBhcyBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uO1xuICAgICAgZXhwbGFpbmVkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGRpc3BsYXlPcmRlcjogWydpZCcsICdvdXRwdXRzJywgJ291dHB1dEFtb3VudCcsICdjaGFuZ2VPdXRwdXRzJywgJ2NoYW5nZUFtb3VudCcsICdmZWUnLCAnd2l0aGRyYXdBbW91bnQnXSxcbiAgICAgICAgaWQ6ICd0dXlPa3lGVU12X25lVl9GZU5CSDI0TmQ0Y01MMmpVZ0RQNHpqR2t1T0ZJPScsXG4gICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiB0ZXN0RGF0YS5zaWduZWRTZW5kVHJhbnNhY3Rpb24ucmVjaXBpZW50Qm91bmNlYWJsZS5hZGRyZXNzLFxuICAgICAgICAgICAgYW1vdW50OiB0ZXN0RGF0YS5zaWduZWRTZW5kVHJhbnNhY3Rpb24ucmVjaXBpZW50Qm91bmNlYWJsZS5hbW91bnQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgb3V0cHV0QW1vdW50OiB0ZXN0RGF0YS5zaWduZWRTZW5kVHJhbnNhY3Rpb24ucmVjaXBpZW50Qm91bmNlYWJsZS5hbW91bnQsXG4gICAgICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgICAgICBjaGFuZ2VBbW91bnQ6ICcwJyxcbiAgICAgICAgZmVlOiB7IGZlZTogJ1VOS05PV04nIH0sXG4gICAgICAgIHdpdGhkcmF3QW1vdW50OiB1bmRlZmluZWQsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIHNpbmdsZSBub21pbmF0b3Igd2l0aGRyYXcgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IChhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQnVmZmVyLmZyb20odGVzdERhdGEuc2lnbmVkU2luZ2xlTm9taW5hdG9yV2l0aGRyYXdUcmFuc2FjdGlvbi50eCwgJ2Jhc2U2NCcpLnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgIH0pKSBhcyBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uO1xuICAgICAgZXhwbGFpbmVkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGRpc3BsYXlPcmRlcjogWydpZCcsICdvdXRwdXRzJywgJ291dHB1dEFtb3VudCcsICdjaGFuZ2VPdXRwdXRzJywgJ2NoYW5nZUFtb3VudCcsICdmZWUnLCAnd2l0aGRyYXdBbW91bnQnXSxcbiAgICAgICAgaWQ6IHRlc3REYXRhLnNpZ25lZFNpbmdsZU5vbWluYXRvcldpdGhkcmF3VHJhbnNhY3Rpb24udHhJZCxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6IHRlc3REYXRhLnNpZ25lZFNpbmdsZU5vbWluYXRvcldpdGhkcmF3VHJhbnNhY3Rpb24ucmVjaXBpZW50LmFkZHJlc3MsXG4gICAgICAgICAgICBhbW91bnQ6IHRlc3REYXRhLnNpZ25lZFNpbmdsZU5vbWluYXRvcldpdGhkcmF3VHJhbnNhY3Rpb24ucmVjaXBpZW50LmFtb3VudCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBvdXRwdXRBbW91bnQ6IHRlc3REYXRhLnNpZ25lZFNpbmdsZU5vbWluYXRvcldpdGhkcmF3VHJhbnNhY3Rpb24ucmVjaXBpZW50LmFtb3VudCxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBmZWU6IHsgZmVlOiAnVU5LTk9XTicgfSxcbiAgICAgICAgd2l0aGRyYXdBbW91bnQ6ICc5MzIxNzgxMTIzMzAwMDAnLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYSBub24tYm91bmNlYWJsZSBzaW5nbGUgbm9taW5hdG9yIHdpdGhkcmF3IHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSAoYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhIZXg6IEJ1ZmZlci5mcm9tKHRlc3REYXRhLnNpZ25lZFNpbmdsZU5vbWluYXRvcldpdGhkcmF3VHJhbnNhY3Rpb24udHgsICdiYXNlNjQnKS50b1N0cmluZygnaGV4JyksXG4gICAgICAgIHRvQWRkcmVzc0JvdW5jZWFibGU6IGZhbHNlLFxuICAgICAgICBmcm9tQWRkcmVzc0JvdW5jZWFibGU6IGZhbHNlLFxuICAgICAgfSkpIGFzIFRyYW5zYWN0aW9uRXhwbGFuYXRpb247XG4gICAgICBleHBsYWluZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbJ2lkJywgJ291dHB1dHMnLCAnb3V0cHV0QW1vdW50JywgJ2NoYW5nZU91dHB1dHMnLCAnY2hhbmdlQW1vdW50JywgJ2ZlZScsICd3aXRoZHJhd0Ftb3VudCddLFxuICAgICAgICBpZDogdGVzdERhdGEuc2lnbmVkU2luZ2xlTm9taW5hdG9yV2l0aGRyYXdUcmFuc2FjdGlvbi50eElkQm91bmNlYWJsZSxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6IHRlc3REYXRhLnNpZ25lZFNpbmdsZU5vbWluYXRvcldpdGhkcmF3VHJhbnNhY3Rpb24ucmVjaXBpZW50Qm91bmNlYWJsZS5hZGRyZXNzLFxuICAgICAgICAgICAgYW1vdW50OiB0ZXN0RGF0YS5zaWduZWRTaW5nbGVOb21pbmF0b3JXaXRoZHJhd1RyYW5zYWN0aW9uLnJlY2lwaWVudEJvdW5jZWFibGUuYW1vdW50LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIG91dHB1dEFtb3VudDogdGVzdERhdGEuc2lnbmVkU2luZ2xlTm9taW5hdG9yV2l0aGRyYXdUcmFuc2FjdGlvbi5yZWNpcGllbnRCb3VuY2VhYmxlLmFtb3VudCxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBmZWU6IHsgZmVlOiAnVU5LTk9XTicgfSxcbiAgICAgICAgd2l0aGRyYXdBbW91bnQ6ICc5MzIxNzgxMTIzMzAwMDAnLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gZXhwbGFpbiB0cmFuc2FjdGlvbiB3aXRoIG1pc3NpbmcgcGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHt9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHNob3VsZC5lcXVhbChlcnJvci5tZXNzYWdlLCAnSW52YWxpZCB0cmFuc2FjdGlvbicpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIGV4cGxhaW4gdHJhbnNhY3Rpb24gd2l0aCBpbnZhbGlkIHBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7IHR4SGV4OiAncmFuZG9tU3RyaW5nJyB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHNob3VsZC5lcXVhbChlcnJvci5tZXNzYWdlLCAnSW52YWxpZCB0cmFuc2FjdGlvbicpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUGFyc2UgVHJhbnNhY3Rpb25zOiAnLCAoKSA9PiB7XG4gICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0dG9uJyk7XG5cbiAgICBjb25zdCB0cmFuc2FjdGlvbnNMaXN0ID0gW3Rlc3REYXRhLnNpZ25lZFNlbmRUcmFuc2FjdGlvbi50eCwgdGVzdERhdGEuc2lnbmVkU2luZ2xlTm9taW5hdG9yV2l0aGRyYXdUcmFuc2FjdGlvbi50eF07XG5cbiAgICBjb25zdCB0cmFuc2FjdGlvbklucHV0c1Jlc3BvbnNlTGlzdCA9IFtcbiAgICAgIFtcbiAgICAgICAge1xuICAgICAgICAgIGFkZHJlc3M6ICdFUUNTQmpSM2ZVT0w5OFdUdzJGX0lUNEJyY3FqWkpXVkxXVVN6NVdRRHBhTDlKcGwnLFxuICAgICAgICAgIGFtb3VudDogJzEwMDAwMDAwJyxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICBhZGRyZXNzOiAnRVFBYkp1Zy1rLXR1ZldNakVDMVJLU00waWlKVERVY1lrQzd6V0FOSHJrVDU1Rm9sJyxcbiAgICAgICAgICBhbW91bnQ6ICcxMjM0MDAwMDAnLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICBdO1xuXG4gICAgY29uc3QgdHJhbnNhY3Rpb25JbnB1dHNSZXNwb25zZUJvdW5jZWFibGVMaXN0ID0gW1xuICAgICAgW1xuICAgICAgICB7XG4gICAgICAgICAgYWRkcmVzczogJ1VRQ1NCalIzZlVPTDk4V1R3MkZfSVQ0QnJjcWpaSldWTFdVU3o1V1FEcGFMOU1lZycsXG4gICAgICAgICAgYW1vdW50OiAnMTAwMDAwMDAnLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAge1xuICAgICAgICAgIGFkZHJlc3M6ICdVUUFiSnVnLWstdHVmV01qRUMxUktTTTBpaUpURFVjWWtDN3pXQU5IcmtUNTVBZmcnLFxuICAgICAgICAgIGFtb3VudDogJzEyMzQwMDAwMCcsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIF07XG5cbiAgICBjb25zdCB0cmFuc2FjdGlvbk91dHB1dHNSZXNwb25zZUxpc3QgPSBbXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICBhZGRyZXNzOiAnRVFBMGk4LUNkR25GX0RoVUhIZjkyUjFPTkg2c0lBOXZMWl9XTGNDSWhmQkJYd3RHJyxcbiAgICAgICAgICBhbW91bnQ6ICcxMDAwMDAwMCcsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICB7XG4gICAgICAgICAgYWRkcmVzczogJ0VRQTBpOC1DZEduRl9EaFVISGY5MlIxT05INnNJQTl2TFpfV0xjQ0loZkJCWHd0RycsXG4gICAgICAgICAgYW1vdW50OiAnMTIzNDAwMDAwJyxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgXTtcblxuICAgIGNvbnN0IHRyYW5zYWN0aW9uT3V0cHV0c1Jlc3BvbnNlQm91bmNlYWJsZUxpc3QgPSBbXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICBhZGRyZXNzOiAnVVFBMGk4LUNkR25GX0RoVUhIZjkyUjFPTkg2c0lBOXZMWl9XTGNDSWhmQkJYMWFEJyxcbiAgICAgICAgICBhbW91bnQ6ICcxMDAwMDAwMCcsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICB7XG4gICAgICAgICAgYWRkcmVzczogJ1VRQTBpOC1DZEduRl9EaFVISGY5MlIxT05INnNJQTl2TFpfV0xjQ0loZkJCWDFhRCcsXG4gICAgICAgICAgYW1vdW50OiAnMTIzNDAwMDAwJyxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgXTtcblxuICAgIHRyYW5zYWN0aW9uc0xpc3QuZm9yRWFjaCgoXywgaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gdHJhbnNhY3Rpb25zTGlzdFtpbmRleF07XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbklucHV0c1Jlc3BvbnNlID0gdHJhbnNhY3Rpb25JbnB1dHNSZXNwb25zZUxpc3RbaW5kZXhdO1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb25JbnB1dHNSZXNwb25zZUJvdW5jZWFibGUgPSB0cmFuc2FjdGlvbklucHV0c1Jlc3BvbnNlQm91bmNlYWJsZUxpc3RbaW5kZXhdO1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb25PdXRwdXRzUmVzcG9uc2UgPSB0cmFuc2FjdGlvbk91dHB1dHNSZXNwb25zZUxpc3RbaW5kZXhdO1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb25PdXRwdXRzUmVzcG9uc2VCb3VuY2VhYmxlID0gdHJhbnNhY3Rpb25PdXRwdXRzUmVzcG9uc2VCb3VuY2VhYmxlTGlzdFtpbmRleF07XG5cbiAgICAgIGl0KCdzaG91bGQgcGFyc2UgYSBUT04gdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4ucGFyc2VUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhIZXg6IEJ1ZmZlci5mcm9tKHRyYW5zYWN0aW9uLCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICB9KTtcblxuICAgICAgICBwYXJzZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgICBpbnB1dHM6IHRyYW5zYWN0aW9uSW5wdXRzUmVzcG9uc2UsXG4gICAgICAgICAgb3V0cHV0czogdHJhbnNhY3Rpb25PdXRwdXRzUmVzcG9uc2UsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcGFyc2UgYSBub24tYm91bmNlYWJsZSBUT04gdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4ucGFyc2VUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhIZXg6IEJ1ZmZlci5mcm9tKHRyYW5zYWN0aW9uLCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgIHRvQWRkcmVzc0JvdW5jZWFibGU6IGZhbHNlLFxuICAgICAgICAgIGZyb21BZGRyZXNzQm91bmNlYWJsZTogZmFsc2UsXG4gICAgICAgIH0gYXMgVG9uUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMpO1xuXG4gICAgICAgIHBhcnNlZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICAgIGlucHV0czogdHJhbnNhY3Rpb25JbnB1dHNSZXNwb25zZUJvdW5jZWFibGUsXG4gICAgICAgICAgb3V0cHV0czogdHJhbnNhY3Rpb25PdXRwdXRzUmVzcG9uc2VCb3VuY2VhYmxlLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgdG8gcGFyc2UgYSBUT04gdHJhbnNhY3Rpb24gd2hlbiBleHBsYWluVHJhbnNhY3Rpb24gcmVzcG9uc2UgaXMgdW5kZWZpbmVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzdHViID0gc2lub24uc3R1YihUb24ucHJvdG90eXBlLCAnZXhwbGFpblRyYW5zYWN0aW9uJyk7XG4gICAgICAgIHN0dWIucmVzb2x2ZXModW5kZWZpbmVkKTtcbiAgICAgICAgYXdhaXQgYmFzZWNvaW4ucGFyc2VUcmFuc2FjdGlvbih7IHR4SGV4OiB0cmFuc2FjdGlvbiB9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIHJhdyB0cmFuc2FjdGlvbicpO1xuICAgICAgICBzdHViLnJlc3RvcmUoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQWRkcmVzcyBWYWxpZGF0aW9uJywgKCkgPT4ge1xuICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndHRvbicpO1xuICAgIGxldCBrZXljaGFpbnM7XG4gICAgbGV0IGNvbW1vbktleWNoYWluO1xuXG4gICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbW1vbktleWNoYWluID1cbiAgICAgICAgJzE5YmRmZTJhNGI0OThhMDU1MTEzODEyMzVhODg5MmQ1NDI2NzgwN2M0YTNmNjU0ZTMxMGI5MzhiOGI0MjRmZjRhZGVkYmU5MmY0YzE0NmRlNjQxYzY3NTA4YTk2MTMyNGM4NTA0Y2RmOGUwYzBhY2JiNjhkNjEwNGNjY2NkNzgxJztcbiAgICAgIGtleWNoYWlucyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIGlkOiAnNjQyNGMzNTNlYWY3OGQwMDA3NjZlOTU5NDk4Njg0NjgnLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgJzE5YmRmZTJhNGI0OThhMDU1MTEzODEyMzVhODg5MmQ1NDI2NzgwN2M0YTNmNjU0ZTMxMGI5MzhiOGI0MjRmZjRhZGVkYmU5MmY0YzE0NmRlNjQxYzY3NTA4YTk2MTMyNGM4NTA0Y2RmOGUwYzBhY2JiNjhkNjEwNGNjY2NkNzgxJyxcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6XG4gICAgICAgICAgICAne1wiaXZcIjpcImNaZDVpN0w0Unh0d3JBTFcycks3VUE9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCI1emdvSDFCZDNGdz1cIixcImN0XCI6XCI5dlZsblhGUnRyTTlGVkVvK2QyY2hiR0hsTTlsRlplbXVlQnVBczNCSWtQbzMzRm83anp3d05LL2tJV2tFeWcrTm1FQmQ1SWFxQVMxNTdudnZ2d3p6c21NV2xRZFV6OXFibVhOdjNwZzk4N2NYRlIwOGV4Uys0dWh3UDFZTk9qSlRSdlJOY085WnFIYjQ2ZDRmbXlKL3lDOS9zdXNDZ2U3ci9Fc2JhTjVDM2FmdjFkenlidXE5MTJGd2FRRWxaTFlZcDVCSUN1ZEZPTVo5azBVRE1mS00vUE1Ea0g3V2V4b0dIcjlHS3EvYmdDSDJCMzlUWlp5SEtVNlV5NDdsWGVwMnM2aDBEck13SE9ybm1pTDNEWmpPajg4WW52cGhsenh1bzRlT2xEMlVIaWEyK252SWFJU1lzMjlQcjBEQXZSRXV0Y2h2Y0JwRXhqMWtXV1B2N2hRWXJ2OEYwTkFkYXRzYldsM3creEt5ZmlNS28xVVNscnd5SnZpeXBHdFF0WE9KeXcwWFBOMHJ2MitMNWxXOEJianB6SGZZWU4xM2ZKVGVkbEdURmhoa3pWdGJiUEFLRTAya3g3ekNKY2pZYWlleGRTVHNyRExTY1lOVDkvSmhkdDI3S3Bzb29laHdWb2hMZlNLejR2YkZmUnUyTVBadzMvK2MvaGZpSk5ndHo2ZXNXYm54R3JjRThVMkl3UFlDYUsrR2hrNERjcVdOSW5pNTlSSTVCNWtBc1FPVG9JSTQwcVBONTEwdVRneEJTUE83cTdNSGdreGRkNENxQnErb2pyOWowUDdvYW84RTVZK0NCREpyb2pEb0NoMW9DQ0RXOXZvMmRYbFZjRDhTSWJ3N1UvOUFmdkViQTR4eUUvNW1kMU03Q0l3TG5XczJZbnYwWXRhS29xaGRTOXg2Rm1IbE1EaE4vREtIaW5yd21vd3RyVFQ4MmZPa3BPNWc5c2FTbWdVN1F5M2dMdDh0K1Z3ZEV5ZUZlUVVLUlN5Y2k4cWdxWFFhWklnNCthWGdhU09ubENGTXRtQjhla1l4RWhUWTV1elJmck5nUzRzMVFlcUZCcE50VUYrWWRpMjk3cGJWWG5Kb1hBTitTVldkODBHQ3greUkyZHBWQzg5azNyT1dLOVdleXFsbnp1TEpXcDJSSU9COWNkVzhHRnYvZk4rUUFKcFllVnhPRTQrblpEc0tuc2o4bktjZzl0NERseDFHNmdMTTEvVnE5WXhOTGJ1enVSQzBhc1VZdmRNbm9NdnN6bXBtKytUeG5kWWlzZ05Zc2NwWlNvejd3dmNhekpORVBmaFBWakVrZDZ0VVV1TjRHTTM1SDBEbUtDVVFOVCthNkI2aG1IbFRadmp4aXlHQWc1Ylk1OWhkanZKKzIyUWR1YXpsRUVDNkxJM0hyQTd1SzBUcHBsV3pTMXRDSUZ2VE1VaGo2NURFWm1OSjIrWlk5YlE0dnNNZitEUlIzT09HNHQrRE1sTmZqT2Qzek52M1FvWTk1QmpmV3ByeUZ3UHpEcTdiQ1A2N0pEc29qN2oyVFk1RlJTclJrRDc3SDBFd2x1eDJjV2ZqUlR3Y01IY2RReHh1VjBPUDBhTmpHRGp5YkZOXCJ9JyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGlkOiAnNjQyNGMzNTNlYWY3OGQwMDA3NjZlOTYxMzdkNDQwNGInLFxuICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAnMTliZGZlMmE0YjQ5OGEwNTUxMTM4MTIzNWE4ODkyZDU0MjY3ODA3YzRhM2Y2NTRlMzEwYjkzOGI4YjQyNGZmNGFkZWRiZTkyZjRjMTQ2ZGU2NDFjNjc1MDhhOTYxMzI0Yzg1MDRjZGY4ZTBjMGFjYmI2OGQ2MTA0Y2NjY2Q3ODEnLFxuICAgICAgICAgIGVuY3J5cHRlZFBydjpcbiAgICAgICAgICAgICd7XCJpdlwiOlwidmkwZFBlZi9SeDdrRy9wUnlTUWk2UT09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIjllZmhRc2lFdlZzPVwiLFwiY3RcIjpcIkd3NmF0dmY2Z3hLenNqdGwzeHNlaXBPM3JBeHAxbUF6N1l1MWloRnNpNS9sZjJ2TVplZ0FwZ1p4K3B5SUxGUzlLS0xIYk5GM1U2V2dTWWRycjJ0NHZ6ZExzWGtIMVdJeGZIUytjZDJDNU41OXlBRFpEblBKQlQ2cHYvSVJ2YVllbFAwQ2szbklZUTJoU01tOG9wK1ZPV0MvU3pIZWg3c2xZRHF3RUhUR2FuMFdpZ2Z2azF5UmQ3Q0NKVGFFQW9tbmMvNGVGaTJOWTNYM2d0LzNvcHk5SUFna25ud1VGb2huOTZFV3BFUTBGNnBiekgvWjhWRjZnRitEVWNyckJ5QXhFeFVQbkhRWmlGazNZSFUvdlZWNEZ4QlUvbVZBRTh4QnNCbjV1bDVlNVNVTVBmYzdUQnVKV3Y0QkJ5VE5nOXhEU2hGLzkxWXgybmJmVW01ZDlRbU04bHBLZ3p6UXZjSzhQT0FQazg3Z1JDdUtuc0doNXZOUzBVcHBrSGMrb2NmelJRbEdBNmp6ZTdReXlRTzByTWo1THk4a1dqd2sydklTdktZSFlTMU5SN1ZVNTQ5VUlYbzdOWGphdHVuS1NjMytJcmVvUlVISXNoaWFMZzZobCtweENDdWMwcVE0M1YwbWRJZkNqVE44Z2tHV0xOazhSN3RBR1B6OWp5YXBRUGNQRUdIZ0V6MEFUSWk2eU1OV0NzaWJTMmVMaUUxdVZFSk9Ob000bGs2RlBsM1EyQ0hiVzJNZUVicWpZOGhiYXcxOG1OYjJ4U0JIL0Z3cGlpYWwrVHZpMmltcWduQ080WnBPOWJsbEtmdFpQY1F5MHN0TitlR0JsYjV1ZnlmbEtrRFNpQ2hIWXJvR2pFcG1pRmljZGRlNDhjSnN6RjUydUtObmYxcTY3ZkE5L1MyRkFIUWFiM0VYb2p4SDJHYmsra2tWMmgvVFlLRkZaU1dDM3ZpNGU4bU8rdmpNVWNSMEFkc2dQRnlFSXowU0NHdWJhM0NuVExOZEV1WndzYXVBZUhreDJ2VVRuUmdKUFZnTmVldVhtc1ZHNzZTeTJnZ0pIdWFsczBIajhVMlhkYTBxTzFSdUZmb0NXZnNzOXduNkhHUndQUGtoU0IvOG9OZ3VBcW1SVkdLa2Q4Wnd0M0l2clRkOWZrMC9yRkZESktHejdXeU5Ia1lnVW1OaUdjSXREMTJ2MGp4N0ZaNTJFSnpsM0F2MVJ5SlVRSzE4KzhFWVBoM1NHaVU5ZHQ3VlgwYUYwdW82Sm91S2hPZWxkVXZNUCtBdWdRejhmVWNsd1RRc2Jib1ZnMjdZeG8wRHlBVFZ3VGhXNWE1NlI2UWY1WmlRSmx1RnV6czV5OThycTBTNXEwNDZsRTZvM3ZWbUpwRWR3amVTQ0pvRVQ1Q0w0blRna1h5V3ZobTRlQjh1L2U2NmwzbzBxYmFTeDhxOVlZbVQ5RXBSY2w1VFA0VGhMQktFVFlkelZ2ZzRleGpRZmVrdE1hdGs1RXlVcEVJaFpQWGg1dlhwSlplc2RmTzlMSjh6VGFIQnNCakRQVTdjZE5nUU1iZWJwYXRhUmk4QTBlbDIvSUpYbCtFK29sZ0F6NXpDNGkyTzFRPT1cIn0nLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgaWQ6ICc2NDI0YzM1M2VhZjc4ZDAwMDc2NmU5NTEwYjEyNWZiYScsXG4gICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgJzE5YmRmZTJhNGI0OThhMDU1MTEzODEyMzVhODg5MmQ1NDI2NzgwN2M0YTNmNjU0ZTMxMGI5MzhiOGI0MjRmZjRhZGVkYmU5MmY0YzE0NmRlNjQxYzY3NTA4YTk2MTMyNGM4NTA0Y2RmOGUwYzBhY2JiNjhkNjEwNGNjY2NkNzgxJyxcbiAgICAgICAgICB2ZXJpZmllZFZzc1Byb29mOiB0cnVlLFxuICAgICAgICAgIGlzQml0R286IHRydWUsXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIHZhbGlkYXRpbmcgYSB3ZWxsIGZvcm1hdHRlZCBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICdVUUIwSHl0MWJUUmZJMFdLX1VMWnlLdnJ2UDBQUHRwVFFGaV9qS1hWWFg2S0ZPTWknO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZEFkZHJlc3MoYWRkcmVzcykuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2Ugd2hlbiB2YWxpZGF0aW5nIGFuIGluY29ycmVjdGx5IGZvcm1hdHRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSAnd3JvbmdhZGRyZXNzJztcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MpLnNob3VsZC5lcXVhbChmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIHdoZW4gdmFsaWRhdGluZyBhIG5vbi1ib3VuY2VhYmxlIGFkZHJlc3MgZm9ybWF0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICdVUUEwaTgtQ2RHbkZfRGhVSEhmOTJSMU9OSDZzSUE5dkxaX1dMY0NJaGZCQlgxYUQnO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZEFkZHJlc3MoYWRkcmVzcykuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIHZhbGlkYXRpbmcgYWRkcmVzc2VzIHdpdGggbWVtb0lkcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3MxID0gJ0VRQjBIeXQxYlRSZkkwV0tfVUxaeUt2cnZQMFBQdHBUUUZpX2pLWFZYWDZLRkw3bj9tZW1vSWQ9MTIzJztcbiAgICAgIGNvbnN0IGFkZHJlc3MyID0gJ1VRQjBIeXQxYlRSZkkwV0tfVUxaeUt2cnZQMFBQdHBUUUZpX2pLWFZYWDZLRk9NaT9tZW1vSWQ9MTIzJztcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MxKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICBiYXNlY29pbi5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzMikuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgaXNXYWxsZXRBZGRyZXNzIHdpdGggdmFsaWQgYWRkcmVzcyBmb3IgaW5kZXggNCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG5ld0FkZHJlc3MgPSAnRVFCMEh5dDFiVFJmSTBXS19VTFp5S3ZydlAwUFB0cFRRRmlfaktYVlhYNktGTDduJztcbiAgICAgIGNvbnN0IGluZGV4ID0gNDtcblxuICAgICAgY29uc3QgcGFyYW1zID0geyBjb21tb25LZXljaGFpbiwgYWRkcmVzczogbmV3QWRkcmVzcywgaW5kZXgsIGtleWNoYWlucyB9O1xuICAgICAgKGF3YWl0IGJhc2Vjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciBpc1dhbGxldEFkZHJlc3Mgd2l0aCB2YWxpZCBhZGRyZXNzYW5kIGluZGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbmV3QWRkcmVzcyA9ICdFUUIwSHl0MWJUUmZJMFdLX1VMWnlLdnJ2UDBQUHRwVFFGaV9qS1hWWFg2S0ZMN24/bWVtb0lkPTQnO1xuICAgICAgY29uc3QgaW5kZXggPSA0O1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7IGNvbW1vbktleWNoYWluLCBhZGRyZXNzOiBuZXdBZGRyZXNzLCBpbmRleCwga2V5Y2hhaW5zIH07XG4gICAgICAoYXdhaXQgYmFzZWNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcykpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBpc1dhbGxldEFkZHJlc3Mgd2l0aCB2YWxpZCBhZGRyZXNzIGZvciBpbmRleCA1IGFuZCBhZGRyZXNzIGlzIGZvciBhIGRpZmZlcmVudCBpbmRleCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdyb25nQWRkcmVzc0ZvckluZGV4NSA9ICdFUUIwSHl0MWJUUmZJMFdLX1VMWnlLdnJ2UDBQUHRwVFFGaV9qS1hWWFg2S0ZMN24nO1xuICAgICAgY29uc3QgaW5kZXggPSA1O1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7IGNvbW1vbktleWNoYWluLCBhZGRyZXNzOiB3cm9uZ0FkZHJlc3NGb3JJbmRleDUsIGluZGV4LCBrZXljaGFpbnMgfTtcbiAgICAgIChhd2FpdCBiYXNlY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKSkuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIGlzV2FsbGV0QWRkcmVzcyB3aGVuIGtleWNoYWlucyBpcyBtaXNzaW5nJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICdFUUIwSHl0MWJUUmZJMFdLX1VMWnlLdnJ2UDBQUHRwVFFGaV9qS1hWWFg2S0ZMN24nO1xuICAgICAgY29uc3QgaW5kZXggPSAwO1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7IGNvbW1vbktleWNoYWluLCBhZGRyZXNzLCBpbmRleCB9O1xuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gYmFzZWNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3IgaXNXYWxsZXRBZGRyZXNzIHdoZW4gbmV3IGFkZHJlc3MgaXMgaW52YWxpZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdyb25nQWRkcmVzcyA9ICdiYWRBZGRyZXNzJztcbiAgICAgIGNvbnN0IGluZGV4ID0gMDtcblxuICAgICAgY29uc3QgcGFyYW1zID0geyBjb21tb25LZXljaGFpbiwgYWRkcmVzczogd3JvbmdBZGRyZXNzLCBpbmRleCB9O1xuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gYmFzZWNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyksIHtcbiAgICAgICAgbWVzc2FnZTogYGludmFsaWQgYWRkcmVzczogJHt3cm9uZ0FkZHJlc3N9YCxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndXRpbCBjbGFzcyAnLCAoKSA9PiB7XG4gICAgbGV0IGNvbW1vbktleWNoYWluO1xuICAgIGxldCBkZXJpdmVkUHVibGljS2V5O1xuICAgIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb21tb25LZXljaGFpbiA9XG4gICAgICAgICcxOWJkZmUyYTRiNDk4YTA1NTExMzgxMjM1YTg4OTJkNTQyNjc4MDdjNGEzZjY1NGUzMTBiOTM4YjhiNDI0ZmY0YWRlZGJlOTJmNGMxNDZkZTY0MWM2NzUwOGE5NjEzMjRjODUwNGNkZjhlMGMwYWNiYjY4ZDYxMDRjY2NjZDc4MSc7XG4gICAgICBjb25zdCBNUEMgPSBhd2FpdCBFRERTQU1ldGhvZHMuZ2V0SW5pdGlhbGl6ZWRNcGNJbnN0YW5jZSgpO1xuICAgICAgZGVyaXZlZFB1YmxpY0tleSA9IE1QQy5kZXJpdmVVbmhhcmRlbmVkKGNvbW1vbktleWNoYWluLCAnbS8nICsgMCkuc2xpY2UoMCwgNjQpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2dldEFkZHJlc3NGcm9tUHVibGljS2V5JywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCBkZXJpdmUgYm91bmNlYWJsZSBhZGRyZXNzIGJ5IGRlZmF1bHQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIChhd2FpdCB1dGlscy5nZXRBZGRyZXNzRnJvbVB1YmxpY0tleShkZXJpdmVkUHVibGljS2V5KSkuc2hvdWxkLmVxdWFsKFxuICAgICAgICAgICdFUURWZXlVSk94M0FuWkdXTHRFMGwtVnh2N2M3dVRuRDhPWHRDRmhhTy1udmF2UTUnXG4gICAgICAgICk7XG4gICAgICAgIChhd2FpdCB1dGlscy5nZXRBZGRyZXNzRnJvbVB1YmxpY0tleShkZXJpdmVkUHVibGljS2V5LCB0cnVlKSkuc2hvdWxkLmVxdWFsKFxuICAgICAgICAgICdFUURWZXlVSk94M0FuWkdXTHRFMGwtVnh2N2M3dVRuRDhPWHRDRmhhTy1udmF2UTUnXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBkZXJpdmUgbm9uLWJvdW5jZWFibGUgYWRkcmVzcyB3aGVuIHJlcXVlc3RlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgKGF3YWl0IHV0aWxzLmdldEFkZHJlc3NGcm9tUHVibGljS2V5KGRlcml2ZWRQdWJsaWNLZXksIGZhbHNlKSkuc2hvdWxkLmVxdWFsKFxuICAgICAgICAgICdVUURWZXlVSk94M0FuWkdXTHRFMGwtVnh2N2M3dVRuRDhPWHRDRmhhTy1udmFxbjgnXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBkZXJpdmUgcmF3IGFkZHJlc3Mgd2hlbiByZXF1ZXN0ZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIChhd2FpdCB1dGlscy5nZXRBZGRyZXNzRnJvbVB1YmxpY0tleShkZXJpdmVkUHVibGljS2V5LCBmYWxzZSwgZmFsc2UpKS5zaG91bGQuZXF1YWwoXG4gICAgICAgICAgJzA6ZDU3YjI1MDkzYjFkYzA5ZDkxOTYyZWQxMzQ5N2U1NzFiZmI3M2JiOTM5YzNmMGU1ZWQwODU4NWEzYmU5ZWY2YSdcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2dldEFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIHJldHVybiBhZGRyZXNzIGFzIHBlciBib3VuY2VhYmxlIGZsYWcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNob3VsZC5lcXVhbChcbiAgICAgICAgICB1dGlscy5nZXRBZGRyZXNzKCdVUUIwSHl0MWJUUmZJMFdLX1VMWnlLdnJ2UDBQUHRwVFFGaV9qS1hWWFg2S0ZPTWknLCBmYWxzZSksXG4gICAgICAgICAgJ1VRQjBIeXQxYlRSZkkwV0tfVUxaeUt2cnZQMFBQdHBUUUZpX2pLWFZYWDZLRk9NaSdcbiAgICAgICAgKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKFxuICAgICAgICAgIHV0aWxzLmdldEFkZHJlc3MoJ1VRQjBIeXQxYlRSZkkwV0tfVUxaeUt2cnZQMFBQdHBUUUZpX2pLWFZYWDZLRk9NaScsIHRydWUpLFxuICAgICAgICAgICdFUUIwSHl0MWJUUmZJMFdLX1VMWnlLdnJ2UDBQUHRwVFFGaV9qS1hWWFg2S0ZMN24nXG4gICAgICAgICk7XG4gICAgICAgIHNob3VsZC5lcXVhbChcbiAgICAgICAgICB1dGlscy5nZXRBZGRyZXNzKCdFUUIwSHl0MWJUUmZJMFdLX1VMWnlLdnJ2UDBQUHRwVFFGaV9qS1hWWFg2S0ZMN24nLCB0cnVlKSxcbiAgICAgICAgICAnRVFCMEh5dDFiVFJmSTBXS19VTFp5S3ZydlAwUFB0cFRRRmlfaktYVlhYNktGTDduJ1xuICAgICAgICApO1xuICAgICAgICBzaG91bGQuZXF1YWwoXG4gICAgICAgICAgdXRpbHMuZ2V0QWRkcmVzcygnRVFCMEh5dDFiVFJmSTBXS19VTFp5S3ZydlAwUFB0cFRRRmlfaktYVlhYNktGTDduJywgZmFsc2UpLFxuICAgICAgICAgICdVUUIwSHl0MWJUUmZJMFdLX1VMWnlLdnJ2UDBQUHRwVFFGaV9qS1hWWFg2S0ZPTWknXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgYmxvY2sgaGFzaCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkQmxvY2tJZCgnTVB1T3ZIZHUveit0Mmw4MllwWnRpSlFrOCtGVkttV3VLeGQ2dWJuMDlmST0nKSwgdHJ1ZSk7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZEJsb2NrSWQoJ01QdU92SGR1L3ordDJsODJZcFp0aUpRazgrRlZLbVd1S3hkJyksIGZhbHNlKTtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkQmxvY2tJZCgnJyksIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgdHJhbnNhY3Rpb24gaWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZFRyYW5zYWN0aW9uSWQoJ3dsVGRET0FYd0pwOEVTUmZRQUVKUUluMFRjaV9TNW9MYlZLQll4RHR2cGs9JyksIHRydWUpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRUcmFuc2FjdGlvbklkKCczc3lreDZSdWp5N1V0QndIUS9YNWtMZ3ZLRTBTS0xBK0FCaUNLaTdzWDhvPScpLCB0cnVlKTsgLy8gTm8gdXJsIGZyaWVuZGx5IHR4aWRcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkVHJhbnNhY3Rpb25JZCgnM3N5a3g2UnVqeTdVdEJ3SFFfWDVrTGd2S0UwU0tMQS1BQmlDS2k3c1g4bz0nKSwgdHJ1ZSk7IC8vIFVybCBmcmllbmRseSB0eGlkXG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZFRyYW5zYWN0aW9uSWQoJ3dsVGRET0FYd0pwOEVTUmZRQUVKUUluMFRjaV9TNW9MYj0nKSwgZmFsc2UpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRUcmFuc2FjdGlvbklkKCd3bFRkRE9BWHdKcDhFU1JmUUFFSlFJbjBUY2lfUzVvTGJWS0JZeER0YWZkc2FzZGFkc2Z2cGs9JyksIGZhbHNlKTtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkVHJhbnNhY3Rpb25JZCgnJyksIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgdHJhbnNhY3Rpb24gaWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpZCA9IGF3YWl0IHV0aWxzLmdldE1lc3NhZ2VIYXNoRnJvbURhdGEoXG4gICAgICAgICd0ZTZjY2tFQ0NnRUFBa29BQTdWMms0Vncxbmh4cjdYY0NCaldjRkZIS3FHd0NnbFBTUnVZQWtXaldpVFZBSUFBQVBiTGd2YTBHN3l0S3cveGVFOWEzRkhLMlJNOGZnT3BHdlRwUVJzZWVNZXIzZWZSS3NpUUFBRHhQaG5hUUZaV1lybFFBRFJxYkNVSUFRSURBZ0hnQkFVQWduSUFaMFVJd21rbmtNYVc3UWJvVGNxNDhGZloxTlQ1b01VajJWUE9CcjN6UG94cmlhYjRTZlY2NWk2SGQxSjJzRnN1VGNJV1VvYmNLWE1jSXlzK0pXa25BaE1Nd1N2V0JobVR6d1JBQ0FrQjRZZ0EwbkN1R3M4T05mYTdnUU1hemdvbzVWUTJBVUVwNlNOekFFaTBhMFNhb0JBSEhnblBKQlFRSi9tZW9Dd3pLNS9QYWpCU3h1SksyR2t2YTdObWxBTE5EczJJTUVXaTRaUmZJVjRWZUpwS0JoemhLak5sRmp1ejYwZythZVQ1Y05pNENVMU5HTHNyZXkvNEFBQUFHQUFjQmdFQjN3Y0FhR0lBSzJjWWRZQ3R4dEJhV0o5aGk3TitIVnplTXNQUXhMSFNxWW43YmZwT2NSeWgzTlpRQUFBQUFBQUFBQUFBQUFBQUFBQUFzV2dBMG5DdUdzOE9OZmE3Z1FNYXpnb281VlEyQVVFcDZTTnpBRWkwYTBTYW9CRUFGYk9NT3NCVzQyZ3RMRSt3eGRtL0RxNXZHV0hvWWxqcFZNVDl0djBuT0k1UTdtc29BQVlVV0dBQUFCN1pjRjdXaE1yTVZ5cEFBSjFCbllNVGlBQUFBQUFBQUFBQUVRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQWdBRy9KaDZFZ1RCUllRQUFBQUFBQUFnQUFBQUFBQTRFNTJBUC9lQVluVmhKa29JSTRZVXJocExmcERGdDZtUktpa3RiRm5xcytRRkFXREFBYWNRMD1cXFxcJ1xuICAgICAgKTtcbiAgICAgIHNob3VsZC5lcXVhbChpZCwgJ1RzVmdOS1QwNWNkZTRRNTRzQytSRkM3blRvVHJIazlwcEdnRTVNMGpYdEU9Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGRlc2VyaWFsaXplIGEgY2VsbCB0byBnZXQgdGhlIGFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkYXRhMSA9ICd0ZTZjY2tFQkFRRUFKQUFBUTRBYUZVVGdVUS9rMmkrRGRBb29pYjB3TlZSRVpRMnorOFI5V1F2dkZOcFVKQkFSeUFnSyc7XG4gICAgICBjb25zdCByYXdBZGRyZXNzMSA9ICcwOmQwYWEyNzAyODg3ZjI2ZDE3YzFiYTA1MTQ0NGRlOTgxYWFhMjIzMjg2ZDlmZGUyM2VhYzg1Zjc4YTZkMmExMjAnO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmdldFJhd1dhbGxldEFkZHJlc3NGcm9tQ2VsbChkYXRhMSksIHJhd0FkZHJlc3MxKTtcblxuICAgICAgY29uc3QgZGF0YTIgPSAndGU2Y2NrRUJBUUVBSkFBQVE1Lzc1dzAzNHFQOVQwWlhZM211TTVvdXZGbE5vTlBreTJZVXMrSGN4ZDhvdGpEa0lPUHEnO1xuICAgICAgY29uc3QgcmF3QWRkcmVzczIgPSAnLTE6ZGYzODY5YmYxNTFmZWE3YTMyYmIxYmNkNzE5Y2QxNzVlMmNhNmQwNjlmMjY1YjMwYTU5ZjBlZTYyZWY5NDViMSc7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuZ2V0UmF3V2FsbGV0QWRkcmVzc0Zyb21DZWxsKGRhdGEyKSwgcmF3QWRkcmVzczIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnVG9uIHJlY292ZXIgLSBOb24tQml0R28gYW5kIFVuc2lnbmVkIFN3ZWVwIFRyYW5zYWN0aW9ucycsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgc2FuZGJveDogc2lub24uU2lub25TYW5kYm94O1xuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTsgLy8gQ3JlYXRlIGEgbmV3IHNhbmRib3ggZm9yIGVhY2ggdGVzdFxuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgIHNhbmRib3gucmVzdG9yZSgpOyAvLyBSZXN0b3JlIGFsbCBzdHVicyBhZnRlciBlYWNoIHRlc3RcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc3VjY2Vzc2Z1bGx5IHJlY292ZXIgZnVuZHMgZm9yIG5vbi1CaXRHbyByZWNvdmVyeScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIERlZmluZSByZWNvdmVyeSBwYXJhbWV0ZXJzXG4gICAgICBjb25zdCByZWNvdmVyeVBhcmFtcyA9IHtcbiAgICAgICAgYml0Z29LZXk6XG4gICAgICAgICAgJzFiYWFmYTBkNjIxNzRiZjBjNzhmMzI1NjMxODYxM2ZmYzQ0YjZkZDU0YWIxYTYzYzIxODUyMzJmOTJlZGU5ZGFlMWIyODE4ZGJlYjUyYTgyMTVmZDU2ZjVhNWYyYTlmOTRjMDc5Y2U4OWU0ZGMzYjFjZTZlZDZlODRjZTcxODU3JyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogJ1VRQkwyaWRDWFI0QVRkUXRhTmE0VnBvZmNwU3h1eElnSEg3X3NsT1pmZE9YU2FkSicsXG4gICAgICAgIGFwaUtleTogJ2RiMjU1NDY0MWM2MWU2MGE5NzljYzZjMDA1M2YyZWM5MWRhOWIxM2U3MWQyODc3NjhjOTNjMmZiNTU2YmU1M2InLFxuICAgICAgICB1c2VyS2V5OlxuICAgICAgICAgICcxYmFhZmEwZDYyMTc0YmYwYzc4ZjMyNTYzMTg2MTNmZmM0NGI2ZGQ1NGFiMWE2M2MyMTg1MjMyZjkyZWRlOWRhZTFiMjgxOGRiZWI1MmE4MjE1ZmQ1NmY1YTVmMmE5Zjk0YzA3OWNlODllNGRjM2IxY2U2ZWQ2ZTg0Y2U3MTg1NycsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdkdW1teVBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgLy8gTW9jayB0aGUgZXhwZWN0ZWQgcmVzdWx0IGZvciBub24tQml0R28gcmVjb3ZlcnlcbiAgICAgIGNvbnN0IG1vY2tSZXN1bHQgPSB7XG4gICAgICAgIHNlcmlhbGl6ZWRUeDpcbiAgICAgICAgICAndGU2Y2NrRUJBZ0VBcWdBQjRZZ0FsN1JPaExvOEFKdW9XdEd0Y0swMFB1VXBZM1lrUURqOS8yU25NdnVuTHBJRmJsODk2d2xNdjdmc1VPYytzTUh6RWw4cTN2WDVibTZub0hnaW5QSktCUnpuT3JPN3ZlSXBISUVwaVJMYkg3L2VOZHBTc1JodkwyNjBKUC9mRDB2QUlVMU5HTHRBQkRxQUFBQUFDQUFjQVFCb1FnQi9PZWlOZExlYUw3K08wNFh1dWp1Q2hTR3JSZDdabkZsMmZDZDlGWGR6QXlET0pZQ3dBQUFBQUFBQUFBQUFBQUFBQUZ3WEd0OD0nLFxuICAgICAgICBzY2FuSW5kZXg6IDAsXG4gICAgICAgIGNvaW46ICd0dG9uJyxcbiAgICAgIH07XG5cbiAgICAgIC8vIFN0dWIgdGhlIHJlY292ZXIgZnVuY3Rpb24gdG8gcmV0dXJuIHRoZSBtb2NrZWQgcmVzdWx0XG4gICAgICBjb25zdCBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgICAgc2FuZGJveC5zdHViKGJhc2Vjb2luLCAncmVjb3ZlcicpLnJlc29sdmVzKG1vY2tSZXN1bHQpO1xuXG4gICAgICAvLyBDYWxsIHRoZSByZWNvdmVyIGZ1bmN0aW9uXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHJlY292ZXJ5UGFyYW1zKTtcblxuICAgICAgLy8gVmFsaWRhdGUgdGhlIHJlc3VsdFxuICAgICAgcmVzdWx0LnNlcmlhbGl6ZWRUeC5zaG91bGQuZXF1YWwoXG4gICAgICAgICd0ZTZjY2tFQkFnRUFxZ0FCNFlnQWw3Uk9oTG84QUp1b1d0R3RjSzAwUHVVcFkzWWtRRGo5LzJTbk12dW5McElGYmw4OTZ3bE12N2ZzVU9jK3NNSHpFbDhxM3ZYNWJtNm5vSGdpblBKS0JSem5Pck83dmVJcEhJRXBpUkxiSDcvZU5kcFNzUmh2TDI2MEpQL2ZEMHZBSVUxTkdMdEFCRHFBQUFBQUNBQWNBUUJvUWdCL09laU5kTGVhTDcrTzA0WHV1anVDaFNHclJkN1puRmwyZkNkOUZYZHpBeURPSllDd0FBQUFBQUFBQUFBQUFBQUFBRndYR3Q4PSdcbiAgICAgICk7XG4gICAgICByZXN1bHQuc2NhbkluZGV4LnNob3VsZC5lcXVhbCgwKTtcbiAgICAgIHJlc3VsdC5jb2luLnNob3VsZC5lcXVhbCgndHRvbicpO1xuICAgICAgc2FuZGJveC5yZXN0b3JlKCk7IC8vIFJlc3RvcmUgdGhlIHN0dWJiZWQgbWV0aG9kXG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBhbiB1bnNpZ25lZCBzd2VlcCB0cmFuc2FjdGlvbiBpZiB1c2VyS2V5IGFuZCBiYWNrdXBLZXkgYXJlIG1pc3NpbmcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBEZWZpbmUgcmVjb3ZlcnkgcGFyYW1ldGVyc1xuICAgICAgY29uc3QgcmVjb3ZlcnlQYXJhbXMgPSB7XG4gICAgICAgIGJpdGdvS2V5OlxuICAgICAgICAgICcxYmFhZmEwZDYyMTc0YmYwYzc4ZjMyNTYzMTg2MTNmZmM0NGI2ZGQ1NGFiMWE2M2MyMTg1MjMyZjkyZWRlOWRhZTFiMjgxOGRiZWI1MmE4MjE1ZmQ1NmY1YTVmMmE5Zjk0YzA3OWNlODllNGRjM2IxY2U2ZWQ2ZTg0Y2U3MTg1NycsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdVUUJMMmlkQ1hSNEFUZFF0YU5hNFZwb2ZjcFN4dXhJZ0hIN19zbE9aZmRPWFNhZEonLFxuICAgICAgICBhcGlLZXk6ICdkYjI1NTQ2NDFjNjFlNjBhOTc5Y2M2YzAwNTNmMmVjOTFkYTliMTNlNzFkMjg3NzY4YzkzYzJmYjU1NmJlNTNiJyxcbiAgICAgIH07XG5cbiAgICAgIC8vIE1vY2sgdGhlIGV4cGVjdGVkIHJlc3VsdCBmb3IgdW5zaWduZWQgc3dlZXAgdHJhbnNhY3Rpb25cbiAgICAgIGNvbnN0IG1vY2tVbnNpZ25lZFR4ID0ge1xuICAgICAgICBzZXJpYWxpemVkVHg6XG4gICAgICAgICAgJ3RlNmNja0VCQWdFQXFnQUI0WWdBbDdST2hMbzhBSnVvV3RHdGNLMDBQdVVwWTNZa1FEajkvMlNuTXZ1bkxwSUZibDg5NndsTXY3ZnNVT2Mrc01IekVsOHEzdlg1Ym02bm9IZ2luUEpLQlJ6bk9yTzd2ZUlwSElFcGlSTGJINy9lTmRwU3NSaHZMMjYwSlAvZkQwdkFJVTFOR0x0QUJEcUFBQUFBQ0FBY0FRQm9RZ0IvT2VpTmRMZWFMNytPMDRYdXVqdUNoU0dyUmQ3Wm5GbDJmQ2Q5RlhkekF5RE9KWUN3QUFBQUFBQUFBQUFBQUFBQUFGd1hHdDg9JyxcbiAgICAgICAgc2NhbkluZGV4OiAwLFxuICAgICAgICBjb2luOiAndHRvbicsXG4gICAgICAgIHNpZ25hYmxlSGV4OiAnZGQ5OGViNWEzNzAwYzAyMDMyMzcwOTVjYTFjMGQ1Mjg4YmMwZDY1MGE5YjU5ZjdiODFiYWM1NTJmNzYxMzdkZicsXG4gICAgICAgIGRlcml2YXRpb25QYXRoOiAnbS8wJyxcbiAgICAgICAgcGFyc2VkVHg6IHtcbiAgICAgICAgICBpbnB1dHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYWRkcmVzczogJ1VRQkwyaWRDWFI0QVRkUXRhTmE0VnBvZmNwU3h1eElnSEg3X3NsT1pmZE9YU2FkSicsXG4gICAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnMTAwMDAwMDAwMCcsXG4gICAgICAgICAgICAgIHZhbHVlOiAxMDAwMDAwMDAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYWRkcmVzczogJ1VRQkwyaWRDWFI0QVRkUXRhTmE0VnBvZmNwU3h1eElnSEg3X3NsT1pmZE9YU2FkSicsXG4gICAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnOTk5MDAwMDAwJyxcbiAgICAgICAgICAgICAgY29pbk5hbWU6ICd0dG9uJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBzcGVuZEFtb3VudDogOTk5MDAwMDAwLFxuICAgICAgICAgIHR5cGU6ICcnLFxuICAgICAgICB9LFxuICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgZmVlOiAxMDAwMDAwLFxuICAgICAgICAgIGZlZVN0cmluZzogJzEwMDAwMDAnLFxuICAgICAgICB9LFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICcxYmFhZmEwZDYyMTc0YmYwYzc4ZjMyNTYzMTg2MTNmZmM0NGI2ZGQ1NGFiMWE2M2MyMTg1MjMyZjkyZWRlOWRhZTFiMjgxOGRiZWI1MmE4MjE1ZmQ1NmY1YTVmMmE5Zjk0YzA3OWNlODllNGRjM2IxY2U2ZWQ2ZTg0Y2U3MTg1NycsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtb2NrVHhSZXF1ZXN0ID0ge1xuICAgICAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB1bnNpZ25lZFR4OiBtb2NrVW5zaWduZWRUeCxcbiAgICAgICAgICAgIHNpZ25hdHVyZVNoYXJlczogW10sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgd2FsbGV0Q29pbjogJ3RvbicsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtb2NrVHhSZXF1ZXN0cyA9IHtcbiAgICAgICAgdHhSZXF1ZXN0czogW21vY2tUeFJlcXVlc3RdLFxuICAgICAgfTtcblxuICAgICAgLy8gU3R1YiB0aGUgcmVjb3ZlciBmdW5jdGlvbiB0byByZXR1cm4gdGhlIG1vY2tlZCB1bnNpZ25lZCBzd2VlcCB0cmFuc2FjdGlvblxuICAgICAgY29uc3Qgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcblxuICAgICAgc2FuZGJveC5zdHViKGJhc2Vjb2luLCAncmVjb3ZlcicpLnJlc29sdmVzKG1vY2tUeFJlcXVlc3RzKTtcblxuICAgICAgLy8gQ2FsbCB0aGUgcmVjb3ZlciBmdW5jdGlvblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4ucmVjb3ZlcihyZWNvdmVyeVBhcmFtcyk7XG5cbiAgICAgIC8vIFZhbGlkYXRlIHRoZSByZXN1bHRcbiAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhSZXF1ZXN0cycpO1xuICAgICAgcmVzdWx0LnR4UmVxdWVzdHNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3RyYW5zYWN0aW9ucycpO1xuICAgICAgcmVzdWx0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd1bnNpZ25lZFR4Jyk7XG4gICAgICByZXN1bHQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuZXF1YWwobW9ja1Vuc2lnbmVkVHgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0YWtlIE9WQyBvdXRwdXQgYW5kIGdlbmVyYXRlIGEgc2lnbmVkIHN3ZWVwIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gRGVmaW5lIHRoZSBwYXJhbWV0ZXJzIChtb2NrIE9WQyByZXNwb25zZSlcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgb3ZjUmVzcG9uc2U6IHtcbiAgICAgICAgICBzZXJpYWxpemVkVHg6XG4gICAgICAgICAgICAndGU2Y2NrRUJBZ0VBcWdBQjRZZ0FsN1JPaExvOEFKdW9XdEd0Y0swMFB1VXBZM1lrUURqOS8yU25NdnVuTHBJRmJsODk2d2xNdjdmc1VPYytzTUh6RWw4cTN2WDVibTZub0hnaW5QSktCUnpuT3JPN3ZlSXBISUVwaVJMYkg3L2VOZHBTc1JodkwyNjBKUC9mRDB2QUlVMU5HTHRBQkRxQUFBQUFDQUFjQVFCb1FnQi9PZWlOZExlYUw3K08wNFh1dWp1Q2hTR3JSZDdabkZsMmZDZDlGWGR6QXlET0pZQ3dBQUFBQUFBQUFBQUFBQUFBQUZ3WEd0OD0nLFxuICAgICAgICAgIHNjYW5JbmRleDogMCxcbiAgICAgICAgICBsYXN0U2NhbkluZGV4OiAwLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgLy8gTW9jayB0aGUgZXhwZWN0ZWQgcmVzdWx0IGZvciB0aGUgc2lnbmVkIHN3ZWVwIHRyYW5zYWN0aW9uXG4gICAgICBjb25zdCBtb2NrU2lnbmVkU3dlZXBUeG4gPSB7XG4gICAgICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNlcmlhbGl6ZWRUeDpcbiAgICAgICAgICAgICAgJ3RlNmNja0VCQWdFQXFnQUI0WWdBbDdST2hMbzhBSnVvV3RHdGNLMDBQdVVwWTNZa1FEajkvMlNuTXZ1bkxwSUZibDg5NndsTXY3ZnNVT2Mrc01IekVsOHEzdlg1Ym02bm9IZ2luUEpLQlJ6bk9yTzd2ZUlwSElFcGlSTGJINy9lTmRwU3NSaHZMMjYwSlAvZkQwdkFJVTFOR0x0QUJEcUFBQUFBQ0FBY0FRQm9RZ0IvT2VpTmRMZWFMNytPMDRYdXVqdUNoU0dyUmQ3Wm5GbDJmQ2Q5RlhkekF5RE9KWUN3QUFBQUFBQUFBQUFBQUFBQUFGd1hHdDg9JyxcbiAgICAgICAgICAgIHNjYW5JbmRleDogMCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBsYXN0U2NhbkluZGV4OiAwLFxuICAgICAgfTtcblxuICAgICAgLy8gU3R1YiB0aGUgY3JlYXRlQnJvYWRjYXN0YWJsZVN3ZWVwVHJhbnNhY3Rpb24gZnVuY3Rpb24gdG8gcmV0dXJuIHRoZSBtb2NrZWQgcmVzdWx0XG4gICAgICBzYW5kYm94LnN0dWIoYmFzZWNvaW4sICdjcmVhdGVCcm9hZGNhc3RhYmxlU3dlZXBUcmFuc2FjdGlvbicpLnJlc29sdmVzKG1vY2tTaWduZWRTd2VlcFR4bik7XG5cbiAgICAgIC8vIENhbGwgdGhlIGNyZWF0ZUJyb2FkY2FzdGFibGVTd2VlcFRyYW5zYWN0aW9uIGZ1bmN0aW9uXG4gICAgICBjb25zdCByZWNvdmVyeVR4biA9IGF3YWl0IGJhc2Vjb2luLmNyZWF0ZUJyb2FkY2FzdGFibGVTd2VlcFRyYW5zYWN0aW9uKHBhcmFtcyk7XG5cbiAgICAgIC8vIFZhbGlkYXRlIHRoZSByZXN1bHRcbiAgICAgIHJlY292ZXJ5VHhuLnRyYW5zYWN0aW9uc1swXS5zZXJpYWxpemVkVHguc2hvdWxkLmVxdWFsKFxuICAgICAgICAndGU2Y2NrRUJBZ0VBcWdBQjRZZ0FsN1JPaExvOEFKdW9XdEd0Y0swMFB1VXBZM1lrUURqOS8yU25NdnVuTHBJRmJsODk2d2xNdjdmc1VPYytzTUh6RWw4cTN2WDVibTZub0hnaW5QSktCUnpuT3JPN3ZlSXBISUVwaVJMYkg3L2VOZHBTc1JodkwyNjBKUC9mRDB2QUlVMU5HTHRBQkRxQUFBQUFDQUFjQVFCb1FnQi9PZWlOZExlYUw3K08wNFh1dWp1Q2hTR3JSZDdabkZsMmZDZDlGWGR6QXlET0pZQ3dBQUFBQUFBQUFBQUFBQUFBQUZ3WEd0OD0nXG4gICAgICApO1xuICAgICAgcmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzBdLnNjYW5JbmRleC5zaG91bGQuZXF1YWwoMCk7XG4gICAgICByZWNvdmVyeVR4bi5sYXN0U2NhbkluZGV4LnNob3VsZC5lcXVhbCgwKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==

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


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