PHP WebShell

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

Просмотр файла: transactionBuilder.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 should_1 = __importDefault(require("should"));
const bs58 = __importStar(require("bs58"));
const getBuilderFactory_1 = require("../getBuilderFactory");
const src_1 = require("../../../src");
const sdk_core_1 = require("@bitgo/sdk-core");
const testData = __importStar(require("../../resources/sol"));
const bignumber_js_1 = __importDefault(require("bignumber.js"));
const sdk_lib_mpc_1 = require("@bitgo/sdk-lib-mpc");
describe('Sol Transaction Builder', async () => {
    let builders;
    const factory = (0, getBuilderFactory_1.getBuilderFactory)('tsol');
    const authAccount = new src_1.KeyPair(testData.authAccount).getKeys();
    const nonceAccount = new src_1.KeyPair(testData.nonceAccount).getKeys();
    const validBlockhash = 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi';
    beforeEach(function (done) {
        builders = [
            factory.getWalletInitializationBuilder(),
            factory.getTransferBuilder(),
            factory.getStakingActivateBuilder(),
            factory.getStakingWithdrawBuilder(),
        ];
        done();
    });
    it('start and build an empty a transfer tx with fee', async () => {
        const txBuilder = factory.getTransferBuilder();
        txBuilder.sender(authAccount.pub);
        txBuilder.nonce(validBlockhash);
        txBuilder.fee({ amount: 5000 });
        const tx = await txBuilder.build();
        should_1.default.equal(tx.type, sdk_core_1.TransactionType.Send);
        const txJson = tx.toJson();
        txJson.lamportsPerSignature?.should.equal(5000);
    });
    it('should fail to build if missing sender', async () => {
        for (const txBuilder of builders) {
            txBuilder.nonce(validBlockhash);
            await txBuilder.build().should.rejectedWith('Invalid transaction: missing sender');
        }
    });
    it('should fail to build if missing nonce', async () => {
        for (const txBuilder of builders) {
            txBuilder.sender(authAccount.pub);
            await txBuilder.build().should.rejectedWith('Invalid transaction: missing nonce blockhash');
        }
    });
    it('build a wallet init from rawTx', async () => {
        const txBuilder = factory.from(testData.WALLET_INIT_SIGNED_TX);
        const builtTx = await txBuilder.build();
        should_1.default.equal(builtTx.type, sdk_core_1.TransactionType.WalletInitialization);
        should_1.default.equal(builtTx.id, '7TkU8wLgXDeLFbVydtg6mqMsp9GatsetitSngysgjxFhofKSUcLPBoKPHciLeGEfJFMsqezpZmGRSFQTBy7ZDsg');
        builtTx.inputs.length.should.equal(1);
        builtTx.inputs[0].should.deepEqual({
            address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
            value: testData.tokenTransfers.amount.toString(),
            coin: 'tsol',
        });
        builtTx.outputs.length.should.equal(0);
        const jsonTx = builtTx.toJson();
        jsonTx.id.should.equal('7TkU8wLgXDeLFbVydtg6mqMsp9GatsetitSngysgjxFhofKSUcLPBoKPHciLeGEfJFMsqezpZmGRSFQTBy7ZDsg');
        jsonTx.feePayer.should.equal('5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe');
        jsonTx.nonce.should.equal('GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi');
        jsonTx.numSignatures.should.equal(2);
        jsonTx.instructionsData.should.deepEqual([
            {
                type: 'CreateNonceAccount',
                params: {
                    fromAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
                    nonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
                    authAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
                    amount: '300000',
                },
            },
        ]);
        builtTx.toBroadcastFormat().should.equal(testData.WALLET_INIT_SIGNED_TX);
    });
    it('build a staking activate from rawTx', async () => {
        const txBuilder = factory.from(testData.STAKING_ACTIVATE_SIGNED_TX);
        const builtTx = await txBuilder.build();
        should_1.default.equal(builtTx.type, sdk_core_1.TransactionType.StakingActivate);
        should_1.default.equal(builtTx.id, 'DCsSiGuKiWgtFRF2ZCh5x6xukApffYDs5Y9CyvYBEebMVnXH5TydKpT76srTSr1AhvDZqsnS5EVhvkS8Rzh91hH');
        builtTx.inputs.length.should.equal(1);
        builtTx.inputs[0].should.deepEqual({
            address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
            value: testData.tokenTransfers.amount.toString(),
            coin: 'tsol',
        });
        builtTx.outputs.length.should.equal(1);
        const jsonTx = builtTx.toJson();
        jsonTx.id.should.equal('DCsSiGuKiWgtFRF2ZCh5x6xukApffYDs5Y9CyvYBEebMVnXH5TydKpT76srTSr1AhvDZqsnS5EVhvkS8Rzh91hH');
        jsonTx.feePayer.should.equal('5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe');
        jsonTx.nonce.should.equal('GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi');
        jsonTx.numSignatures.should.equal(2);
        jsonTx.instructionsData.should.deepEqual([
            {
                type: 'Activate',
                params: {
                    fromAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
                    stakingAddress: '7dRuGFbU2y2kijP6o1LYNzVyz4yf13MooqoionCzv5Za',
                    amount: '300000',
                    validator: 'CyjoLt3kjqB57K7ewCBHmnHq3UgEj3ak6A7m6EsBsuhA',
                    isMarinade: false,
                },
            },
        ]);
        builtTx.toBroadcastFormat().should.equal(testData.STAKING_ACTIVATE_SIGNED_TX);
    });
    it('build a send from rawTx', async () => {
        const txBuilder = factory.from(testData.TRANSFER_SIGNED_TX_WITH_MEMO_AND_DURABLE_NONCE);
        const builtTx = await txBuilder.build();
        should_1.default.equal(builtTx.type, sdk_core_1.TransactionType.Send);
        should_1.default.equal(builtTx.id, '2XFxGfXddKWnqGaMAsfNL8HgXqDvjBL2Ae28KWrRvg9bQBmCrpHYVDacuZFeAUyYwjXG6ey2jTARX5VQCnj7SF4L');
        builtTx.inputs.length.should.equal(1);
        builtTx.inputs[0].should.deepEqual({
            address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
            value: testData.tokenTransfers.amount.toString(),
            coin: 'tsol',
        });
        builtTx.outputs.length.should.equal(1);
        builtTx.outputs[0].should.deepEqual({
            address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
            value: testData.tokenTransfers.amount.toString(),
            coin: 'tsol',
        });
        const jsonTx = builtTx.toJson();
        jsonTx.id.should.equal('2XFxGfXddKWnqGaMAsfNL8HgXqDvjBL2Ae28KWrRvg9bQBmCrpHYVDacuZFeAUyYwjXG6ey2jTARX5VQCnj7SF4L');
        jsonTx.feePayer.should.equal('5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe');
        jsonTx.nonce.should.equal('GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi');
        jsonTx.numSignatures.should.equal(1);
        jsonTx.durableNonce.should.deepEqual({
            walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
            authWalletAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
        });
        jsonTx.instructionsData.should.deepEqual([
            {
                type: 'Transfer',
                params: {
                    fromAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
                    toAddress: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
                    amount: '300000',
                },
            },
            {
                type: 'Memo',
                params: { memo: 'test memo' },
            },
        ]);
        builtTx.toBroadcastFormat().should.equal(testData.TRANSFER_SIGNED_TX_WITH_MEMO_AND_DURABLE_NONCE);
    });
    it('build a send from raw token transaction', async () => {
        const txBuilder = factory.from(testData.TOKEN_TRANSFER_SIGNED_TX_WITH_MEMO_AND_DURABLE_NONCE);
        const prioFeeMicroLamports = '10000000';
        // We don't have to manually set the priority fee here as the raw txn already has the priority fee instruction;
        // therefore once initBuilder is called (it's called within fromImplementation), it will set the txBuilder's priorityFee field
        // which will then be used in txBuilder.build() by tokenTransferBuilder to add the set compute fee instruction
        const builtTx = await txBuilder.build();
        should_1.default.equal(builtTx.type, sdk_core_1.TransactionType.Send);
        should_1.default.equal(builtTx.id, '2ticU4ZkEqdTHULr6LobTgWBhim6E7wSscDhM4gzyuGUmQyUwLYhoqaifuvwmNzzEf1T5aefVcgMQkSHdJ5nsrfZ');
        builtTx.inputs.length.should.equal(1);
        builtTx.inputs[0].should.deepEqual({
            address: testData.associatedTokenAccounts.accounts[0].pub,
            value: testData.tokenTransfers.amount.toString(),
            coin: 'tsol:usdc',
        });
        builtTx.outputs.length.should.equal(1);
        builtTx.outputs[0].should.deepEqual({
            address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
            value: testData.tokenTransfers.amount.toString(),
            coin: 'tsol:usdc',
        });
        const jsonTx = builtTx.toJson();
        jsonTx.id.should.equal('2ticU4ZkEqdTHULr6LobTgWBhim6E7wSscDhM4gzyuGUmQyUwLYhoqaifuvwmNzzEf1T5aefVcgMQkSHdJ5nsrfZ');
        jsonTx.feePayer.should.equal(testData.associatedTokenAccounts.accounts[0].pub);
        jsonTx.nonce.should.equal('GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi');
        jsonTx.numSignatures.should.equal(1);
        jsonTx.durableNonce.should.deepEqual({
            walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
            authWalletAddress: testData.associatedTokenAccounts.accounts[0].pub,
        });
        const priorityFeeBigInt = BigInt(prioFeeMicroLamports);
        jsonTx.instructionsData.should.deepEqual([
            {
                params: {
                    fee: priorityFeeBigInt,
                },
                type: 'SetPriorityFee',
            },
            {
                type: 'TokenTransfer',
                params: {
                    fromAddress: testData.associatedTokenAccounts.accounts[0].pub,
                    toAddress: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
                    amount: testData.tokenTransfers.amount.toString(),
                    tokenName: testData.tokenTransfers.nameUSDC.toString(),
                    sourceAddress: 'B5rJjuVi7En63iK6o3ijKdJwAoTe2gwCYmJsVdHQ2aKV',
                },
            },
            {
                type: 'Memo',
                params: { memo: 'test memo' },
            },
        ]);
        builtTx.toBroadcastFormat().should.equal(testData.TOKEN_TRANSFER_SIGNED_TX_WITH_MEMO_AND_DURABLE_NONCE);
    });
    describe('Nonce tests', async () => {
        it('should throw for invalid nonce', () => {
            const blockHash = 'randomstring';
            for (const txBuilder of builders) {
                (0, should_1.default)(() => txBuilder.nonce(blockHash)).throw('Invalid or missing blockHash, got: ' + blockHash);
            }
        });
        it('should throw for invalid params using durable nonce', () => {
            const invalidPubKey = 'randomstring';
            for (const txBuilder of builders) {
                (0, should_1.default)(() => txBuilder.nonce(validBlockhash, {
                    walletNonceAddress: invalidPubKey,
                    authWalletAddress: authAccount.pub,
                })).throw('Invalid or missing walletNonceAddress, got: ' + invalidPubKey);
                (0, should_1.default)(() => txBuilder.nonce(validBlockhash, {
                    walletNonceAddress: nonceAccount.pub,
                    authWalletAddress: invalidPubKey,
                })).throw('Invalid or missing authWalletAddress, got: ' + invalidPubKey);
                (0, should_1.default)(() => txBuilder.nonce(validBlockhash, {
                    walletNonceAddress: nonceAccount.pub,
                    authWalletAddress: nonceAccount.pub,
                })).throw('Invalid params: walletNonceAddress cannot be equal to authWalletAddress');
            }
        });
        it('should succeed for valid nonce', () => {
            for (const txBuilder of builders) {
                should_1.default.doesNotThrow(() => txBuilder.nonce(validBlockhash));
            }
        });
        it('should succeed for valid durable nonce', () => {
            for (const txBuilder of builders) {
                should_1.default.doesNotThrow(() => txBuilder.nonce(validBlockhash, { walletNonceAddress: nonceAccount.pub, authWalletAddress: authAccount.pub }));
            }
        });
    });
    describe('sender tests', async () => {
        it('should throw for invalid sender', () => {
            const invalidPublicKey = 'randomstring';
            for (const txBuilder of builders) {
                (0, should_1.default)(() => txBuilder.sender(invalidPublicKey)).throw('Invalid or missing sender, got: ' + invalidPublicKey);
            }
        });
        it('should succeed for valid sender', () => {
            for (const txBuilder of builders) {
                should_1.default.doesNotThrow(() => txBuilder.sender(authAccount.pub));
            }
        });
    });
    it('validateAddress', () => {
        const validAddress = { address: authAccount.pub };
        const invalidAddress = { address: testData.pubKeys.invalidPubKeys[0] };
        for (const builder of builders) {
            should_1.default.doesNotThrow(() => builder.validateAddress(validAddress));
            (0, should_1.default)(() => builder.validateAddress(invalidAddress)).throwError('Invalid address ' + testData.pubKeys.invalidPubKeys[0]);
        }
    });
    it('validateKey', () => {
        const validKey = { key: testData.authAccount.prv };
        const invalidKey = { key: testData.authAccount.pub };
        for (const builder of builders) {
            should_1.default.doesNotThrow(() => builder.validateKey(validKey));
            (0, should_1.default)(() => builder.validateKey(invalidKey)).throwError('Invalid key');
        }
    });
    it('validateRawTransaction', () => {
        const validRawTx = testData.RAW_TX_SIGNED;
        const invalidRawTx = 'AAAAAAAAAAAAAAAAAAA';
        for (const builder of builders) {
            should_1.default.doesNotThrow(() => builder.validateRawTransaction(validRawTx));
            (0, should_1.default)(() => builder.validateRawTransaction(invalidRawTx)).throwError('Invalid raw transaction');
        }
    });
    it('validateValue', () => {
        const validValue = new bignumber_js_1.default('100000');
        const invalidValue = new bignumber_js_1.default('-100000');
        for (const builder of builders) {
            should_1.default.doesNotThrow(() => builder.validateValue(validValue));
            (0, should_1.default)(() => builder.validateValue(invalidValue)).throwError('Value cannot be less than zero');
        }
    });
    it('validateMemo', () => {
        const validMemo = 'test memo';
        const invalidMemo = 'ooawindaonmawñdamwdoianwdonalskdnaiouwbdoinowadn90awndoawndaowdnaioiuwbdioauwndaoudnbawodnba9owudbnaowdnaasdijhaksdkjasdkjhaskdjhkasdasdasdasdasd';
        for (const builder of builders) {
            builder._instructionsData.push({
                type: 'Transfer',
                params: {
                    fromAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
                    toAddress: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
                    amount: '300000',
                },
            });
            builder.validateMemo(validMemo);
            (0, should_1.default)(() => builder.validateMemo(invalidMemo)).throwError('Memo is too long');
            (0, should_1.default)((memo) => builder.validateMemo(memo)).throwError('Invalid memo, got: undefined');
        }
    });
    describe('add signature', () => {
        let MPC;
        it('should add signature to transaction', async () => {
            const transferBuilder = factory
                .getTransferBuilder()
                .sender(authAccount.pub)
                .nonce(validBlockhash)
                .fee({ amount: 5000 })
                .send({ address: nonceAccount.pub, amount: '1000' });
            transferBuilder.sign({ key: authAccount.prv });
            const signedTransaction = await transferBuilder.build();
            // signature is base58 encoded
            const signature = signedTransaction.signature[0];
            // verify rebuilt transaction contains signature
            const rawTransaction = signedTransaction.toBroadcastFormat();
            const rebuiltSignedTransaction = await factory.from(rawTransaction).build();
            rebuiltSignedTransaction.signature.should.deepEqual(signedTransaction.signature);
            const transferBuilder2 = factory
                .getTransferBuilder()
                .sender(authAccount.pub)
                .nonce(validBlockhash)
                .fee({ amount: 5000 })
                .send({ address: nonceAccount.pub, amount: '1000' });
            transferBuilder2.addSignature({ pub: authAccount.pub }, Buffer.from(bs58.decode(signature)));
            const signedTransaction2 = await transferBuilder2.build();
            // verify signatures are correct
            signedTransaction.signature.should.deepEqual(signedTransaction2.signature);
            // verify rebuilt transaction contains signature
            const rawTransaction2 = signedTransaction2.toBroadcastFormat();
            const rebuiltTransaction2 = await factory.from(rawTransaction2).build();
            rebuiltTransaction2.signature.should.deepEqual(signedTransaction2.signature);
        });
        before('initialize mpc module', async () => {
            const hdTree = await sdk_lib_mpc_1.Ed25519Bip32HdTree.initialize();
            MPC = await sdk_core_1.Eddsa.initialize(hdTree);
        });
        it('should add TSS signature', async () => {
            const A = MPC.keyShare(1, 2, 3);
            const B = MPC.keyShare(2, 2, 3);
            const C = MPC.keyShare(3, 2, 3);
            const A_combine = MPC.keyCombine(A.uShare, [B.yShares[1], C.yShares[1]]);
            const B_combine = MPC.keyCombine(B.uShare, [A.yShares[2], C.yShares[2]]);
            const C_combine = MPC.keyCombine(C.uShare, [A.yShares[3], B.yShares[3]]);
            const commonPub = A_combine.pShare.y;
            const solPublicKey = new src_1.KeyPair({ pub: commonPub });
            const sender = solPublicKey.getAddress();
            let transferBuilder = factory
                .getTransferBuilder()
                .sender(sender)
                .nonce(validBlockhash)
                .fee({ amount: 5000 })
                .send({ address: nonceAccount.pub, amount: '1000' });
            const unsignedTransaction = await transferBuilder.build();
            const signablePayload = unsignedTransaction.signablePayload;
            // signing with A and B
            let A_sign_share = MPC.signShare(signablePayload, A_combine.pShare, [A_combine.jShares[2]]);
            let B_sign_share = MPC.signShare(signablePayload, B_combine.pShare, [B_combine.jShares[1]]);
            let A_sign = MPC.sign(signablePayload, A_sign_share.xShare, [B_sign_share.rShares[1]], [C.yShares[1]]);
            let B_sign = MPC.sign(signablePayload, B_sign_share.xShare, [A_sign_share.rShares[2]], [C.yShares[2]]);
            let signature = MPC.signCombine([A_sign, B_sign]);
            let rawSignature = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]);
            transferBuilder = factory
                .getTransferBuilder()
                .sender(sender)
                .nonce(validBlockhash)
                .fee({ amount: 5000 })
                .send({ address: nonceAccount.pub, amount: '1000' });
            transferBuilder.addSignature({ pub: sender }, rawSignature);
            let signedTransaction = await transferBuilder.build();
            signedTransaction.signature.length.should.equal(1);
            signedTransaction.signature[0].should.equal(bs58.encode(rawSignature));
            signedTransaction.id.should.equal(bs58.encode(rawSignature));
            // signing with A and C
            A_sign_share = MPC.signShare(signablePayload, A_combine.pShare, [A_combine.jShares[3]]);
            let C_sign_share = MPC.signShare(signablePayload, C_combine.pShare, [C_combine.jShares[1]]);
            A_sign = MPC.sign(signablePayload, A_sign_share.xShare, [C_sign_share.rShares[1]], [B.yShares[1]]);
            let C_sign = MPC.sign(signablePayload, C_sign_share.xShare, [A_sign_share.rShares[3]], [B.yShares[3]]);
            signature = MPC.signCombine([A_sign, C_sign]);
            rawSignature = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]);
            transferBuilder = factory
                .getTransferBuilder()
                .sender(sender)
                .nonce(validBlockhash)
                .fee({ amount: 5000 })
                .send({ address: nonceAccount.pub, amount: '1000' });
            transferBuilder.addSignature({ pub: sender }, rawSignature);
            signedTransaction = await transferBuilder.build();
            signedTransaction.signature.length.should.equal(1);
            signedTransaction.signature[0].should.equal(bs58.encode(rawSignature));
            signedTransaction.id.should.equal(bs58.encode(rawSignature));
            // signing with B and C
            B_sign_share = MPC.signShare(signablePayload, B_combine.pShare, [B_combine.jShares[3]]);
            C_sign_share = MPC.signShare(signablePayload, C_combine.pShare, [C_combine.jShares[2]]);
            B_sign = MPC.sign(signablePayload, B_sign_share.xShare, [C_sign_share.rShares[2]], [A.yShares[2]]);
            C_sign = MPC.sign(signablePayload, C_sign_share.xShare, [B_sign_share.rShares[3]], [A.yShares[3]]);
            signature = MPC.signCombine([B_sign, C_sign]);
            rawSignature = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]);
            transferBuilder = factory
                .getTransferBuilder()
                .sender(sender)
                .nonce(validBlockhash)
                .fee({ amount: 5000 })
                .send({ address: nonceAccount.pub, amount: '1000' });
            transferBuilder.addSignature({ pub: sender }, rawSignature);
            signedTransaction = await transferBuilder.build();
            signedTransaction.signature.length.should.equal(1);
            signedTransaction.signature[0].should.equal(bs58.encode(rawSignature));
            signedTransaction.id.should.equal(bs58.encode(rawSignature));
            const rawTransaction = signedTransaction.toBroadcastFormat();
            const rebuiltTransaction = await factory.from(rawTransaction).build();
            rebuiltTransaction.id.should.equal(signedTransaction.id);
            rebuiltTransaction.signature.should.deepEqual(signedTransaction.signature);
        });
        it('should add TSS HD signature', async () => {
            const A = MPC.keyShare(1, 2, 3);
            const B = MPC.keyShare(2, 2, 3);
            const C = MPC.keyShare(3, 2, 3);
            const A_combine = MPC.keyCombine(A.uShare, [B.yShares[1], C.yShares[1]]);
            const B_combine = MPC.keyCombine(B.uShare, [A.yShares[2], C.yShares[2]]);
            for (let index = 0; index < 10; index++) {
                const path = `m/${index}`;
                const A_subkey = MPC.keyDerive(A.uShare, [B.yShares[1], C.yShares[1]], path);
                const B_subkey = MPC.keyCombine(B.uShare, [A_subkey.yShares[2], C.yShares[2]]);
                const solPublicKey = new src_1.KeyPair({ pub: A_subkey.pShare.y });
                const sender = solPublicKey.getAddress();
                const transferBuilder = factory
                    .getTransferBuilder()
                    .sender(sender)
                    .nonce(validBlockhash)
                    .fee({ amount: 5000 })
                    .send({ address: nonceAccount.pub, amount: '1000' });
                const unsignedTransaction = await transferBuilder.build();
                const signablePayload = unsignedTransaction.signablePayload;
                const A_sign_share = MPC.signShare(signablePayload, A_subkey.pShare, [A_combine.jShares[2]]);
                const B_sign_share = MPC.signShare(signablePayload, B_subkey.pShare, [B_combine.jShares[1]]);
                const A_sign = MPC.sign(signablePayload, A_sign_share.xShare, [B_sign_share.rShares[1]], [C.yShares[1]]);
                const B_sign = MPC.sign(signablePayload, B_sign_share.xShare, [A_sign_share.rShares[2]], [C.yShares[2]]);
                const signature = MPC.signCombine([A_sign, B_sign]);
                const rawSignature = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]);
                transferBuilder.addSignature({ pub: sender }, rawSignature);
                const signedTransaction = await transferBuilder.build();
                signedTransaction.signature.length.should.equal(1);
                signedTransaction.signature[0].should.equal(bs58.encode(rawSignature));
                signedTransaction.id.should.equal(bs58.encode(rawSignature));
                const rawTransaction = signedTransaction.toBroadcastFormat();
                const rebuiltTransaction = await factory.from(rawTransaction).build();
                rebuiltTransaction.id.should.equal(signedTransaction.id);
                rebuiltTransaction.signature.should.deepEqual(signedTransaction.signature);
            }
        });
    });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb25CdWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC91bml0L3RyYW5zYWN0aW9uQnVpbGRlci90cmFuc2FjdGlvbkJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsMkNBQTZCO0FBRTdCLDREQUF5RDtBQUN6RCxzQ0FBNkQ7QUFDN0QsOENBQXlEO0FBQ3pELDhEQUFnRDtBQUNoRCxnRUFBcUM7QUFDckMsb0RBQXdEO0FBRXhELFFBQVEsQ0FBQyx5QkFBeUIsRUFBRSxLQUFLLElBQUksRUFBRTtJQUM3QyxJQUFJLFFBQVEsQ0FBQztJQUNiLE1BQU0sT0FBTyxHQUFHLElBQUEscUNBQWlCLEVBQUMsTUFBTSxDQUFDLENBQUM7SUFDMUMsTUFBTSxXQUFXLEdBQUcsSUFBSSxhQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2hFLE1BQU0sWUFBWSxHQUFHLElBQUksYUFBTyxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNsRSxNQUFNLGNBQWMsR0FBRyw4Q0FBOEMsQ0FBQztJQUV0RSxVQUFVLENBQUMsVUFBVSxJQUFJO1FBQ3ZCLFFBQVEsR0FBRztZQUNULE9BQU8sQ0FBQyw4QkFBOEIsRUFBRTtZQUN4QyxPQUFPLENBQUMsa0JBQWtCLEVBQUU7WUFDNUIsT0FBTyxDQUFDLHlCQUF5QixFQUFFO1lBQ25DLE9BQU8sQ0FBQyx5QkFBeUIsRUFBRTtTQUNwQyxDQUFDO1FBQ0YsSUFBSSxFQUFFLENBQUM7SUFDVCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxpREFBaUQsRUFBRSxLQUFLLElBQUksRUFBRTtRQUMvRCxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUMvQyxTQUFTLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNsQyxTQUFTLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2hDLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNoQyxNQUFNLEVBQUUsR0FBRyxNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNuQyxnQkFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLDBCQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFNUMsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQzNCLE1BQU0sQ0FBQyxvQkFBb0IsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2xELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHdDQUF3QyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3RELEtBQUssTUFBTSxTQUFTLElBQUksUUFBUSxFQUFFLENBQUM7WUFDakMsU0FBUyxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUNoQyxNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLHFDQUFxQyxDQUFDLENBQUM7UUFDckYsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHVDQUF1QyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3JELEtBQUssTUFBTSxTQUFTLElBQUksUUFBUSxFQUFFLENBQUM7WUFDakMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDbEMsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFDO1FBQzlGLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxnQ0FBZ0MsRUFBRSxLQUFLLElBQUksRUFBRTtRQUM5QyxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQy9ELE1BQU0sT0FBTyxHQUFHLE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3hDLGdCQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsMEJBQWUsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQ2pFLGdCQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUseUZBQXlGLENBQUMsQ0FBQztRQUNwSCxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQztZQUNqQyxPQUFPLEVBQUUsOENBQThDO1lBQ3ZELEtBQUssRUFBRSxRQUFRLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUU7WUFDaEQsSUFBSSxFQUFFLE1BQU07U0FDYixDQUFDLENBQUM7UUFDSCxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNoQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMseUZBQXlGLENBQUMsQ0FBQztRQUNsSCxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsOENBQThDLENBQUMsQ0FBQztRQUM3RSxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsOENBQThDLENBQUMsQ0FBQztRQUMxRSxNQUFNLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUM7WUFDdkM7Z0JBQ0UsSUFBSSxFQUFFLG9CQUFvQjtnQkFDMUIsTUFBTSxFQUFFO29CQUNOLFdBQVcsRUFBRSw4Q0FBOEM7b0JBQzNELFlBQVksRUFBRSw4Q0FBOEM7b0JBQzVELFdBQVcsRUFBRSw4Q0FBOEM7b0JBQzNELE1BQU0sRUFBRSxRQUFRO2lCQUNqQjthQUNGO1NBQ0YsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxDQUFDLGlCQUFpQixFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMscUJBQXFCLENBQUMsQ0FBQztJQUMzRSxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxxQ0FBcUMsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNuRCxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBQ3BFLE1BQU0sT0FBTyxHQUFHLE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3hDLGdCQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsMEJBQWUsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUM1RCxnQkFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLHlGQUF5RixDQUFDLENBQUM7UUFDcEgsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUM7WUFDakMsT0FBTyxFQUFFLDhDQUE4QztZQUN2RCxLQUFLLEVBQUUsUUFBUSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFO1lBQ2hELElBQUksRUFBRSxNQUFNO1NBQ2IsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDaEMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHlGQUF5RixDQUFDLENBQUM7UUFDbEgsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLDhDQUE4QyxDQUFDLENBQUM7UUFDN0UsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLDhDQUE4QyxDQUFDLENBQUM7UUFDMUUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDO1lBQ3ZDO2dCQUNFLElBQUksRUFBRSxVQUFVO2dCQUNoQixNQUFNLEVBQUU7b0JBQ04sV0FBVyxFQUFFLDhDQUE4QztvQkFDM0QsY0FBYyxFQUFFLDhDQUE4QztvQkFDOUQsTUFBTSxFQUFFLFFBQVE7b0JBQ2hCLFNBQVMsRUFBRSw4Q0FBOEM7b0JBQ3pELFVBQVUsRUFBRSxLQUFLO2lCQUNsQjthQUNGO1NBQ0YsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxDQUFDLGlCQUFpQixFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsMEJBQTBCLENBQUMsQ0FBQztJQUNoRixDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyx5QkFBeUIsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN2QyxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFDO1FBQ3hGLE1BQU0sT0FBTyxHQUFHLE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3hDLGdCQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsMEJBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqRCxnQkFBTSxDQUFDLEtBQUssQ0FDVixPQUFPLENBQUMsRUFBRSxFQUNWLDBGQUEwRixDQUMzRixDQUFDO1FBQ0YsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUM7WUFDakMsT0FBTyxFQUFFLDhDQUE4QztZQUN2RCxLQUFLLEVBQUUsUUFBUSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFO1lBQ2hELElBQUksRUFBRSxNQUFNO1NBQ2IsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUM7WUFDbEMsT0FBTyxFQUFFLDhDQUE4QztZQUN2RCxLQUFLLEVBQUUsUUFBUSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFO1lBQ2hELElBQUksRUFBRSxNQUFNO1NBQ2IsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2hDLE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQywwRkFBMEYsQ0FBQyxDQUFDO1FBQ25ILE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFDO1FBQzdFLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFDO1FBQzFFLE1BQU0sQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQyxNQUFNLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUM7WUFDbkMsa0JBQWtCLEVBQUUsOENBQThDO1lBQ2xFLGlCQUFpQixFQUFFLDhDQUE4QztTQUNsRSxDQUFDLENBQUM7UUFDSCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQztZQUN2QztnQkFDRSxJQUFJLEVBQUUsVUFBVTtnQkFDaEIsTUFBTSxFQUFFO29CQUNOLFdBQVcsRUFBRSw4Q0FBOEM7b0JBQzNELFNBQVMsRUFBRSw4Q0FBOEM7b0JBQ3pELE1BQU0sRUFBRSxRQUFRO2lCQUNqQjthQUNGO1lBQ0Q7Z0JBQ0UsSUFBSSxFQUFFLE1BQU07Z0JBQ1osTUFBTSxFQUFFLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRTthQUM5QjtTQUNGLENBQUMsQ0FBQztRQUNILE9BQU8sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLDhDQUE4QyxDQUFDLENBQUM7SUFDcEcsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMseUNBQXlDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDdkQsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FDNUIsUUFBUSxDQUFDLG9EQUFvRCxDQUN0QyxDQUFDO1FBQzFCLE1BQU0sb0JBQW9CLEdBQUcsVUFBVSxDQUFDO1FBQ3hDLCtHQUErRztRQUMvRyw4SEFBOEg7UUFDOUgsOEdBQThHO1FBQzlHLE1BQU0sT0FBTyxHQUFHLE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3hDLGdCQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsMEJBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqRCxnQkFBTSxDQUFDLEtBQUssQ0FDVixPQUFPLENBQUMsRUFBRSxFQUNWLDBGQUEwRixDQUMzRixDQUFDO1FBQ0YsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUM7WUFDakMsT0FBTyxFQUFFLFFBQVEsQ0FBQyx1QkFBdUIsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRztZQUN6RCxLQUFLLEVBQUUsUUFBUSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFO1lBQ2hELElBQUksRUFBRSxXQUFXO1NBQ2xCLENBQUMsQ0FBQztRQUNILE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDO1lBQ2xDLE9BQU8sRUFBRSw4Q0FBOEM7WUFDdkQsS0FBSyxFQUFFLFFBQVEsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRTtZQUNoRCxJQUFJLEVBQUUsV0FBVztTQUNsQixDQUFDLENBQUM7UUFDSCxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDaEMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLDBGQUEwRixDQUFDLENBQUM7UUFDbkgsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyx1QkFBdUIsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDL0UsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLDhDQUE4QyxDQUFDLENBQUM7UUFDMUUsTUFBTSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQztZQUNuQyxrQkFBa0IsRUFBRSw4Q0FBOEM7WUFDbEUsaUJBQWlCLEVBQUUsUUFBUSxDQUFDLHVCQUF1QixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHO1NBQ3BFLENBQUMsQ0FBQztRQUNILE1BQU0saUJBQWlCLEdBQUcsTUFBTSxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFDdkQsTUFBTSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUM7WUFDdkM7Z0JBQ0UsTUFBTSxFQUFFO29CQUNOLEdBQUcsRUFBRSxpQkFBaUI7aUJBQ3ZCO2dCQUNELElBQUksRUFBRSxnQkFBZ0I7YUFDdkI7WUFDRDtnQkFDRSxJQUFJLEVBQUUsZUFBZTtnQkFDckIsTUFBTSxFQUFFO29CQUNOLFdBQVcsRUFBRSxRQUFRLENBQUMsdUJBQXVCLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUc7b0JBQzdELFNBQVMsRUFBRSw4Q0FBOEM7b0JBQ3pELE1BQU0sRUFBRSxRQUFRLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUU7b0JBQ2pELFNBQVMsRUFBRSxRQUFRLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUU7b0JBQ3RELGFBQWEsRUFBRSw4Q0FBOEM7aUJBQzlEO2FBQ0Y7WUFDRDtnQkFDRSxJQUFJLEVBQUUsTUFBTTtnQkFDWixNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFO2FBQzlCO1NBQ0YsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxDQUFDLGlCQUFpQixFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsb0RBQW9ELENBQUMsQ0FBQztJQUMxRyxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxhQUFhLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDakMsRUFBRSxDQUFDLGdDQUFnQyxFQUFFLEdBQUcsRUFBRTtZQUN4QyxNQUFNLFNBQVMsR0FBRyxjQUFjLENBQUM7WUFDakMsS0FBSyxNQUFNLFNBQVMsSUFBSSxRQUFRLEVBQUUsQ0FBQztnQkFDakMsSUFBQSxnQkFBTSxFQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMscUNBQXFDLEdBQUcsU0FBUyxDQUFDLENBQUM7WUFDcEcsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHFEQUFxRCxFQUFFLEdBQUcsRUFBRTtZQUM3RCxNQUFNLGFBQWEsR0FBRyxjQUFjLENBQUM7WUFDckMsS0FBSyxNQUFNLFNBQVMsSUFBSSxRQUFRLEVBQUUsQ0FBQztnQkFDakMsSUFBQSxnQkFBTSxFQUFDLEdBQUcsRUFBRSxDQUNWLFNBQVMsQ0FBQyxLQUFLLENBQUMsY0FBYyxFQUFFO29CQUM5QixrQkFBa0IsRUFBRSxhQUFhO29CQUNqQyxpQkFBaUIsRUFBRSxXQUFXLENBQUMsR0FBRztpQkFDbkMsQ0FBQyxDQUNILENBQUMsS0FBSyxDQUFDLDhDQUE4QyxHQUFHLGFBQWEsQ0FBQyxDQUFDO2dCQUV4RSxJQUFBLGdCQUFNLEVBQUMsR0FBRyxFQUFFLENBQ1YsU0FBUyxDQUFDLEtBQUssQ0FBQyxjQUFjLEVBQUU7b0JBQzlCLGtCQUFrQixFQUFFLFlBQVksQ0FBQyxHQUFHO29CQUNwQyxpQkFBaUIsRUFBRSxhQUFhO2lCQUNqQyxDQUFDLENBQ0gsQ0FBQyxLQUFLLENBQUMsNkNBQTZDLEdBQUcsYUFBYSxDQUFDLENBQUM7Z0JBRXZFLElBQUEsZ0JBQU0sRUFBQyxHQUFHLEVBQUUsQ0FDVixTQUFTLENBQUMsS0FBSyxDQUFDLGNBQWMsRUFBRTtvQkFDOUIsa0JBQWtCLEVBQUUsWUFBWSxDQUFDLEdBQUc7b0JBQ3BDLGlCQUFpQixFQUFFLFlBQVksQ0FBQyxHQUFHO2lCQUNwQyxDQUFDLENBQ0gsQ0FBQyxLQUFLLENBQUMseUVBQXlFLENBQUMsQ0FBQztZQUNyRixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsZ0NBQWdDLEVBQUUsR0FBRyxFQUFFO1lBQ3hDLEtBQUssTUFBTSxTQUFTLElBQUksUUFBUSxFQUFFLENBQUM7Z0JBQ2pDLGdCQUFNLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQztZQUM3RCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsd0NBQXdDLEVBQUUsR0FBRyxFQUFFO1lBQ2hELEtBQUssTUFBTSxTQUFTLElBQUksUUFBUSxFQUFFLENBQUM7Z0JBQ2pDLGdCQUFNLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxDQUN2QixTQUFTLENBQUMsS0FBSyxDQUFDLGNBQWMsRUFBRSxFQUFFLGtCQUFrQixFQUFFLFlBQVksQ0FBQyxHQUFHLEVBQUUsaUJBQWlCLEVBQUUsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQzlHLENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxjQUFjLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDbEMsRUFBRSxDQUFDLGlDQUFpQyxFQUFFLEdBQUcsRUFBRTtZQUN6QyxNQUFNLGdCQUFnQixHQUFHLGNBQWMsQ0FBQztZQUN4QyxLQUFLLE1BQU0sU0FBUyxJQUFJLFFBQVEsRUFBRSxDQUFDO2dCQUNqQyxJQUFBLGdCQUFNLEVBQUMsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLGtDQUFrQyxHQUFHLGdCQUFnQixDQUFDLENBQUM7WUFDaEgsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsRUFBRSxDQUFDLGlDQUFpQyxFQUFFLEdBQUcsRUFBRTtZQUN6QyxLQUFLLE1BQU0sU0FBUyxJQUFJLFFBQVEsRUFBRSxDQUFDO2dCQUNqQyxnQkFBTSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQy9ELENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLGlCQUFpQixFQUFFLEdBQUcsRUFBRTtRQUN6QixNQUFNLFlBQVksR0FBRyxFQUFFLE9BQU8sRUFBRSxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDbEQsTUFBTSxjQUFjLEdBQUcsRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUN2RSxLQUFLLE1BQU0sT0FBTyxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQy9CLGdCQUFNLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQztZQUNqRSxJQUFBLGdCQUFNLEVBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FDOUQsa0JBQWtCLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQ3hELENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsYUFBYSxFQUFFLEdBQUcsRUFBRTtRQUNyQixNQUFNLFFBQVEsR0FBRyxFQUFFLEdBQUcsRUFBRSxRQUFRLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ25ELE1BQU0sVUFBVSxHQUFHLEVBQUUsR0FBRyxFQUFFLFFBQVEsQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDckQsS0FBSyxNQUFNLE9BQU8sSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUMvQixnQkFBTSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDekQsSUFBQSxnQkFBTSxFQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDMUUsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHdCQUF3QixFQUFFLEdBQUcsRUFBRTtRQUNoQyxNQUFNLFVBQVUsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDO1FBQzFDLE1BQU0sWUFBWSxHQUFHLHFCQUFxQixDQUFDO1FBQzNDLEtBQUssTUFBTSxPQUFPLElBQUksUUFBUSxFQUFFLENBQUM7WUFDL0IsZ0JBQU0sQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLHNCQUFzQixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDdEUsSUFBQSxnQkFBTSxFQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1FBQ25HLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxlQUFlLEVBQUUsR0FBRyxFQUFFO1FBQ3ZCLE1BQU0sVUFBVSxHQUFHLElBQUksc0JBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMzQyxNQUFNLFlBQVksR0FBRyxJQUFJLHNCQUFTLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDOUMsS0FBSyxNQUFNLE9BQU8sSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUMvQixnQkFBTSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDN0QsSUFBQSxnQkFBTSxFQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztRQUNqRyxDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsY0FBYyxFQUFFLEdBQUcsRUFBRTtRQUN0QixNQUFNLFNBQVMsR0FBRyxXQUFXLENBQUM7UUFDOUIsTUFBTSxXQUFXLEdBQ2YsbUpBQW1KLENBQUM7UUFDdEosS0FBSyxNQUFNLE9BQU8sSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUMvQixPQUFPLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDO2dCQUM3QixJQUFJLEVBQUUsVUFBVTtnQkFDaEIsTUFBTSxFQUFFO29CQUNOLFdBQVcsRUFBRSw4Q0FBOEM7b0JBQzNELFNBQVMsRUFBRSw4Q0FBOEM7b0JBQ3pELE1BQU0sRUFBRSxRQUFRO2lCQUNqQjthQUNGLENBQUMsQ0FBQztZQUNILE9BQU8sQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDaEMsSUFBQSxnQkFBTSxFQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsa0JBQWtCLENBQUMsQ0FBQztZQUMvRSxJQUFBLGdCQUFNLEVBQUMsQ0FBQyxJQUFZLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsOEJBQThCLENBQUMsQ0FBQztRQUNsRyxDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsZUFBZSxFQUFFLEdBQUcsRUFBRTtRQUM3QixJQUFJLEdBQVUsQ0FBQztRQUVmLEVBQUUsQ0FBQyxxQ0FBcUMsRUFBRSxLQUFLLElBQUksRUFBRTtZQUNuRCxNQUFNLGVBQWUsR0FBRyxPQUFPO2lCQUM1QixrQkFBa0IsRUFBRTtpQkFDcEIsTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUM7aUJBQ3ZCLEtBQUssQ0FBQyxjQUFjLENBQUM7aUJBQ3JCLEdBQUcsQ0FBQyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQztpQkFDckIsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLFlBQVksQ0FBQyxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDdkQsZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztZQUUvQyxNQUFNLGlCQUFpQixHQUFHLE1BQU0sZUFBZSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3hELDhCQUE4QjtZQUM5QixNQUFNLFNBQVMsR0FBRyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFakQsZ0RBQWdEO1lBQ2hELE1BQU0sY0FBYyxHQUFHLGlCQUFpQixDQUFDLGlCQUFpQixFQUFZLENBQUM7WUFDdkUsTUFBTSx3QkFBd0IsR0FBRyxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDNUUsd0JBQXdCLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDLENBQUM7WUFFakYsTUFBTSxnQkFBZ0IsR0FBRyxPQUFPO2lCQUM3QixrQkFBa0IsRUFBRTtpQkFDcEIsTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUM7aUJBQ3ZCLEtBQUssQ0FBQyxjQUFjLENBQUM7aUJBQ3JCLEdBQUcsQ0FBQyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQztpQkFDckIsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLFlBQVksQ0FBQyxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDdkQsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLEVBQUUsR0FBRyxFQUFFLFdBQVcsQ0FBQyxHQUFHLEVBQUUsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzdGLE1BQU0sa0JBQWtCLEdBQUcsTUFBTSxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUUxRCxnQ0FBZ0M7WUFDaEMsaUJBQWlCLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLENBQUM7WUFFM0UsZ0RBQWdEO1lBQ2hELE1BQU0sZUFBZSxHQUFHLGtCQUFrQixDQUFDLGlCQUFpQixFQUFZLENBQUM7WUFDekUsTUFBTSxtQkFBbUIsR0FBRyxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDeEUsbUJBQW1CLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDL0UsQ0FBQyxDQUFDLENBQUM7UUFFSCxNQUFNLENBQUMsdUJBQXVCLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDekMsTUFBTSxNQUFNLEdBQUcsTUFBTSxnQ0FBa0IsQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNyRCxHQUFHLEdBQUcsTUFBTSxnQkFBSyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN2QyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywwQkFBMEIsRUFBRSxLQUFLLElBQUksRUFBRTtZQUN4QyxNQUFNLENBQUMsR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDaEMsTUFBTSxDQUFDLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ2hDLE1BQU0sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUVoQyxNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3pFLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDekUsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUV6RSxNQUFNLFNBQVMsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNyQyxNQUFNLFlBQVksR0FBRyxJQUFJLGFBQU8sQ0FBQyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO1lBQ3JELE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUV6QyxJQUFJLGVBQWUsR0FBRyxPQUFPO2lCQUMxQixrQkFBa0IsRUFBRTtpQkFDcEIsTUFBTSxDQUFDLE1BQU0sQ0FBQztpQkFDZCxLQUFLLENBQUMsY0FBYyxDQUFDO2lCQUNyQixHQUFHLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUM7aUJBQ3JCLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSxZQUFZLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZELE1BQU0sbUJBQW1CLEdBQUcsTUFBTSxlQUFlLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDMUQsTUFBTSxlQUFlLEdBQUcsbUJBQW1CLENBQUMsZUFBZSxDQUFDO1lBRTVELHVCQUF1QjtZQUN2QixJQUFJLFlBQVksR0FBRyxHQUFHLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDNUYsSUFBSSxZQUFZLEdBQUcsR0FBRyxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUUsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzVGLElBQUksTUFBTSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN2RyxJQUFJLE1BQU0sR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDdkcsSUFBSSxTQUFTLEdBQUcsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ2xELElBQUksWUFBWSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUV6RyxlQUFlLEdBQUcsT0FBTztpQkFDdEIsa0JBQWtCLEVBQUU7aUJBQ3BCLE1BQU0sQ0FBQyxNQUFNLENBQUM7aUJBQ2QsS0FBSyxDQUFDLGNBQWMsQ0FBQztpQkFDckIsR0FBRyxDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDO2lCQUNyQixJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsWUFBWSxDQUFDLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUN2RCxlQUFlLENBQUMsWUFBWSxDQUFDLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxFQUFFLFlBQVksQ0FBQyxDQUFDO1lBQzVELElBQUksaUJBQWlCLEdBQUcsTUFBTSxlQUFlLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDdEQsaUJBQWlCLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ25ELGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQztZQUN2RSxpQkFBaUIsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7WUFFN0QsdUJBQXVCO1lBQ3ZCLFlBQVksR0FBRyxHQUFHLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDeEYsSUFBSSxZQUFZLEdBQUcsR0FBRyxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUUsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzVGLE1BQU0sR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbkcsSUFBSSxNQUFNLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsWUFBWSxDQUFDLE1BQU0sRUFBRSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3ZHLFNBQVMsR0FBRyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDOUMsWUFBWSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUVyRyxlQUFlLEdBQUcsT0FBTztpQkFDdEIsa0JBQWtCLEVBQUU7aUJBQ3BCLE1BQU0sQ0FBQyxNQUFNLENBQUM7aUJBQ2QsS0FBSyxDQUFDLGNBQWMsQ0FBQztpQkFDckIsR0FBRyxDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDO2lCQUNyQixJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsWUFBWSxDQUFDLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUN2RCxlQUFlLENBQUMsWUFBWSxDQUFDLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxFQUFFLFlBQVksQ0FBQyxDQUFDO1lBQzVELGlCQUFpQixHQUFHLE1BQU0sZUFBZSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2xELGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNuRCxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7WUFDdkUsaUJBQWlCLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO1lBRTdELHVCQUF1QjtZQUN2QixZQUFZLEdBQUcsR0FBRyxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUUsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3hGLFlBQVksR0FBRyxHQUFHLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDeEYsTUFBTSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNuRyxNQUFNLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsWUFBWSxDQUFDLE1BQU0sRUFBRSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ25HLFNBQVMsR0FBRyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDOUMsWUFBWSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUVyRyxlQUFlLEdBQUcsT0FBTztpQkFDdEIsa0JBQWtCLEVBQUU7aUJBQ3BCLE1BQU0sQ0FBQyxNQUFNLENBQUM7aUJBQ2QsS0FBSyxDQUFDLGNBQWMsQ0FBQztpQkFDckIsR0FBRyxDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDO2lCQUNyQixJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsWUFBWSxDQUFDLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUN2RCxlQUFlLENBQUMsWUFBWSxDQUFDLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxFQUFFLFlBQVksQ0FBQyxDQUFDO1lBQzVELGlCQUFpQixHQUFHLE1BQU0sZUFBZSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2xELGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNuRCxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7WUFDdkUsaUJBQWlCLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO1lBRTdELE1BQU0sY0FBYyxHQUFHLGlCQUFpQixDQUFDLGlCQUFpQixFQUFZLENBQUM7WUFDdkUsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDdEUsa0JBQWtCLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDekQsa0JBQWtCLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDN0UsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsNkJBQTZCLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDM0MsTUFBTSxDQUFDLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ2hDLE1BQU0sQ0FBQyxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUNoQyxNQUFNLENBQUMsR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFFaEMsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN6RSxNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRXpFLEtBQUssSUFBSSxLQUFLLEdBQUcsQ0FBQyxFQUFFLEtBQUssR0FBRyxFQUFFLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQztnQkFDeEMsTUFBTSxJQUFJLEdBQUcsS0FBSyxLQUFLLEVBQUUsQ0FBQztnQkFFMUIsTUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQzdFLE1BQU0sUUFBUSxHQUFHLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBRS9FLE1BQU0sWUFBWSxHQUFHLElBQUksYUFBTyxDQUFDLEVBQUUsR0FBRyxFQUFFLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDN0QsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUV6QyxNQUFNLGVBQWUsR0FBRyxPQUFPO3FCQUM1QixrQkFBa0IsRUFBRTtxQkFDcEIsTUFBTSxDQUFDLE1BQU0sQ0FBQztxQkFDZCxLQUFLLENBQUMsY0FBYyxDQUFDO3FCQUNyQixHQUFHLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUM7cUJBQ3JCLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSxZQUFZLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO2dCQUN2RCxNQUFNLG1CQUFtQixHQUFHLE1BQU0sZUFBZSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUMxRCxNQUFNLGVBQWUsR0FBRyxtQkFBbUIsQ0FBQyxlQUFlLENBQUM7Z0JBRTVELE1BQU0sWUFBWSxHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUMsZUFBZSxFQUFFLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDN0YsTUFBTSxZQUFZLEdBQUcsR0FBRyxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUUsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUM3RixNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3pHLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFFekcsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO2dCQUNwRCxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBRTNHLGVBQWUsQ0FBQyxZQUFZLENBQUMsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLEVBQUUsWUFBWSxDQUFDLENBQUM7Z0JBRTVELE1BQU0saUJBQWlCLEdBQUcsTUFBTSxlQUFlLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ3hELGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDbkQsaUJBQWlCLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO2dCQUN2RSxpQkFBaUIsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7Z0JBRTdELE1BQU0sY0FBYyxHQUFHLGlCQUFpQixDQUFDLGlCQUFpQixFQUFZLENBQUM7Z0JBQ3ZFLE1BQU0sa0JBQWtCLEdBQUcsTUFBTSxPQUFPLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUN0RSxrQkFBa0IsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDekQsa0JBQWtCLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDN0UsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBzaG91bGQgZnJvbSAnc2hvdWxkJztcbmltcG9ydCAqIGFzIGJzNTggZnJvbSAnYnM1OCc7XG5cbmltcG9ydCB7IGdldEJ1aWxkZXJGYWN0b3J5IH0gZnJvbSAnLi4vZ2V0QnVpbGRlckZhY3RvcnknO1xuaW1wb3J0IHsgS2V5UGFpciwgVG9rZW5UcmFuc2ZlckJ1aWxkZXIgfSBmcm9tICcuLi8uLi8uLi9zcmMnO1xuaW1wb3J0IHsgRWRkc2EsIFRyYW5zYWN0aW9uVHlwZSB9IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgKiBhcyB0ZXN0RGF0YSBmcm9tICcuLi8uLi9yZXNvdXJjZXMvc29sJztcbmltcG9ydCBCaWdOdW1iZXIgZnJvbSAnYmlnbnVtYmVyLmpzJztcbmltcG9ydCB7IEVkMjU1MTlCaXAzMkhkVHJlZSB9IGZyb20gJ0BiaXRnby9zZGstbGliLW1wYyc7XG5cbmRlc2NyaWJlKCdTb2wgVHJhbnNhY3Rpb24gQnVpbGRlcicsIGFzeW5jICgpID0+IHtcbiAgbGV0IGJ1aWxkZXJzO1xuICBjb25zdCBmYWN0b3J5ID0gZ2V0QnVpbGRlckZhY3RvcnkoJ3Rzb2wnKTtcbiAgY29uc3QgYXV0aEFjY291bnQgPSBuZXcgS2V5UGFpcih0ZXN0RGF0YS5hdXRoQWNjb3VudCkuZ2V0S2V5cygpO1xuICBjb25zdCBub25jZUFjY291bnQgPSBuZXcgS2V5UGFpcih0ZXN0RGF0YS5ub25jZUFjY291bnQpLmdldEtleXMoKTtcbiAgY29uc3QgdmFsaWRCbG9ja2hhc2ggPSAnR0h0WFFCc29aSFZuTkZhOVlldkF6RnIxN0RKamdIWGszeWNUS0Q1eEQzWmknO1xuXG4gIGJlZm9yZUVhY2goZnVuY3Rpb24gKGRvbmUpIHtcbiAgICBidWlsZGVycyA9IFtcbiAgICAgIGZhY3RvcnkuZ2V0V2FsbGV0SW5pdGlhbGl6YXRpb25CdWlsZGVyKCksXG4gICAgICBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpLFxuICAgICAgZmFjdG9yeS5nZXRTdGFraW5nQWN0aXZhdGVCdWlsZGVyKCksXG4gICAgICBmYWN0b3J5LmdldFN0YWtpbmdXaXRoZHJhd0J1aWxkZXIoKSxcbiAgICBdO1xuICAgIGRvbmUoKTtcbiAgfSk7XG5cbiAgaXQoJ3N0YXJ0IGFuZCBidWlsZCBhbiBlbXB0eSBhIHRyYW5zZmVyIHR4IHdpdGggZmVlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgdHhCdWlsZGVyLnNlbmRlcihhdXRoQWNjb3VudC5wdWIpO1xuICAgIHR4QnVpbGRlci5ub25jZSh2YWxpZEJsb2NraGFzaCk7XG4gICAgdHhCdWlsZGVyLmZlZSh7IGFtb3VudDogNTAwMCB9KTtcbiAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIHNob3VsZC5lcXVhbCh0eC50eXBlLCBUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG5cbiAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICB0eEpzb24ubGFtcG9ydHNQZXJTaWduYXR1cmU/LnNob3VsZC5lcXVhbCg1MDAwKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBmYWlsIHRvIGJ1aWxkIGlmIG1pc3Npbmcgc2VuZGVyJywgYXN5bmMgKCkgPT4ge1xuICAgIGZvciAoY29uc3QgdHhCdWlsZGVyIG9mIGJ1aWxkZXJzKSB7XG4gICAgICB0eEJ1aWxkZXIubm9uY2UodmFsaWRCbG9ja2hhc2gpO1xuICAgICAgYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkuc2hvdWxkLnJlamVjdGVkV2l0aCgnSW52YWxpZCB0cmFuc2FjdGlvbjogbWlzc2luZyBzZW5kZXInKTtcbiAgICB9XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgZmFpbCB0byBidWlsZCBpZiBtaXNzaW5nIG5vbmNlJywgYXN5bmMgKCkgPT4ge1xuICAgIGZvciAoY29uc3QgdHhCdWlsZGVyIG9mIGJ1aWxkZXJzKSB7XG4gICAgICB0eEJ1aWxkZXIuc2VuZGVyKGF1dGhBY2NvdW50LnB1Yik7XG4gICAgICBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKS5zaG91bGQucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIHRyYW5zYWN0aW9uOiBtaXNzaW5nIG5vbmNlIGJsb2NraGFzaCcpO1xuICAgIH1cbiAgfSk7XG5cbiAgaXQoJ2J1aWxkIGEgd2FsbGV0IGluaXQgZnJvbSByYXdUeCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmZyb20odGVzdERhdGEuV0FMTEVUX0lOSVRfU0lHTkVEX1RYKTtcbiAgICBjb25zdCBidWlsdFR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgc2hvdWxkLmVxdWFsKGJ1aWx0VHgudHlwZSwgVHJhbnNhY3Rpb25UeXBlLldhbGxldEluaXRpYWxpemF0aW9uKTtcbiAgICBzaG91bGQuZXF1YWwoYnVpbHRUeC5pZCwgJzdUa1U4d0xnWERlTEZiVnlkdGc2bXFNc3A5R2F0c2V0aXRTbmd5c2dqeEZob2ZLU1VjTFBCb0tQSGNpTGVHRWZKRk1zcWV6cFptR1JTRlFUQnk3WkRzZycpO1xuICAgIGJ1aWx0VHguaW5wdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgYnVpbHRUeC5pbnB1dHNbMF0uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICBhZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgdmFsdWU6IHRlc3REYXRhLnRva2VuVHJhbnNmZXJzLmFtb3VudC50b1N0cmluZygpLFxuICAgICAgY29pbjogJ3Rzb2wnLFxuICAgIH0pO1xuICAgIGJ1aWx0VHgub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgIGNvbnN0IGpzb25UeCA9IGJ1aWx0VHgudG9Kc29uKCk7XG4gICAganNvblR4LmlkLnNob3VsZC5lcXVhbCgnN1RrVTh3TGdYRGVMRmJWeWR0ZzZtcU1zcDlHYXRzZXRpdFNuZ3lzZ2p4RmhvZktTVWNMUEJvS1BIY2lMZUdFZkpGTXNxZXpwWm1HUlNGUVRCeTdaRHNnJyk7XG4gICAganNvblR4LmZlZVBheWVyLnNob3VsZC5lcXVhbCgnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnKTtcbiAgICBqc29uVHgubm9uY2Uuc2hvdWxkLmVxdWFsKCdHSHRYUUJzb1pIVm5ORmE5WWV2QXpGcjE3REpqZ0hYazN5Y1RLRDV4RDNaaScpO1xuICAgIGpzb25UeC5udW1TaWduYXR1cmVzLnNob3VsZC5lcXVhbCgyKTtcbiAgICBqc29uVHguaW5zdHJ1Y3Rpb25zRGF0YS5zaG91bGQuZGVlcEVxdWFsKFtcbiAgICAgIHtcbiAgICAgICAgdHlwZTogJ0NyZWF0ZU5vbmNlQWNjb3VudCcsXG4gICAgICAgIHBhcmFtczoge1xuICAgICAgICAgIGZyb21BZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICAgIG5vbmNlQWRkcmVzczogJzhZN1JNNkpmY1g0QVNTTkJrcmtybVNiUnU0MzFZVmk5WTNvTEZuekMyZENoJyxcbiAgICAgICAgICBhdXRoQWRkcmVzczogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgICBhbW91bnQ6ICczMDAwMDAnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICBdKTtcbiAgICBidWlsdFR4LnRvQnJvYWRjYXN0Rm9ybWF0KCkuc2hvdWxkLmVxdWFsKHRlc3REYXRhLldBTExFVF9JTklUX1NJR05FRF9UWCk7XG4gIH0pO1xuXG4gIGl0KCdidWlsZCBhIHN0YWtpbmcgYWN0aXZhdGUgZnJvbSByYXdUeCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmZyb20odGVzdERhdGEuU1RBS0lOR19BQ1RJVkFURV9TSUdORURfVFgpO1xuICAgIGNvbnN0IGJ1aWx0VHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICBzaG91bGQuZXF1YWwoYnVpbHRUeC50eXBlLCBUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0FjdGl2YXRlKTtcbiAgICBzaG91bGQuZXF1YWwoYnVpbHRUeC5pZCwgJ0RDc1NpR3VLaVdndEZSRjJaQ2g1eDZ4dWtBcGZmWURzNVk5Q3l2WUJFZWJNVm5YSDVUeWRLcFQ3NnNyVFNyMUFodkRacXNuUzVFVmh2a1M4UnpoOTFoSCcpO1xuICAgIGJ1aWx0VHguaW5wdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgYnVpbHRUeC5pbnB1dHNbMF0uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICBhZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgdmFsdWU6IHRlc3REYXRhLnRva2VuVHJhbnNmZXJzLmFtb3VudC50b1N0cmluZygpLFxuICAgICAgY29pbjogJ3Rzb2wnLFxuICAgIH0pO1xuICAgIGJ1aWx0VHgub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgIGNvbnN0IGpzb25UeCA9IGJ1aWx0VHgudG9Kc29uKCk7XG4gICAganNvblR4LmlkLnNob3VsZC5lcXVhbCgnRENzU2lHdUtpV2d0RlJGMlpDaDV4Nnh1a0FwZmZZRHM1WTlDeXZZQkVlYk1WblhINVR5ZEtwVDc2c3JUU3IxQWh2RFpxc25TNUVWaHZrUzhSemg5MWhIJyk7XG4gICAganNvblR4LmZlZVBheWVyLnNob3VsZC5lcXVhbCgnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnKTtcbiAgICBqc29uVHgubm9uY2Uuc2hvdWxkLmVxdWFsKCdHSHRYUUJzb1pIVm5ORmE5WWV2QXpGcjE3REpqZ0hYazN5Y1RLRDV4RDNaaScpO1xuICAgIGpzb25UeC5udW1TaWduYXR1cmVzLnNob3VsZC5lcXVhbCgyKTtcbiAgICBqc29uVHguaW5zdHJ1Y3Rpb25zRGF0YS5zaG91bGQuZGVlcEVxdWFsKFtcbiAgICAgIHtcbiAgICAgICAgdHlwZTogJ0FjdGl2YXRlJyxcbiAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgZnJvbUFkZHJlc3M6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgICAgc3Rha2luZ0FkZHJlc3M6ICc3ZFJ1R0ZiVTJ5MmtpalA2bzFMWU56Vnl6NHlmMTNNb29xb2lvbkN6djVaYScsXG4gICAgICAgICAgYW1vdW50OiAnMzAwMDAwJyxcbiAgICAgICAgICB2YWxpZGF0b3I6ICdDeWpvTHQza2pxQjU3Szdld0NCSG1uSHEzVWdFajNhazZBN202RXNCc3VoQScsXG4gICAgICAgICAgaXNNYXJpbmFkZTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIF0pO1xuICAgIGJ1aWx0VHgudG9Ccm9hZGNhc3RGb3JtYXQoKS5zaG91bGQuZXF1YWwodGVzdERhdGEuU1RBS0lOR19BQ1RJVkFURV9TSUdORURfVFgpO1xuICB9KTtcblxuICBpdCgnYnVpbGQgYSBzZW5kIGZyb20gcmF3VHgnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5mcm9tKHRlc3REYXRhLlRSQU5TRkVSX1NJR05FRF9UWF9XSVRIX01FTU9fQU5EX0RVUkFCTEVfTk9OQ0UpO1xuICAgIGNvbnN0IGJ1aWx0VHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICBzaG91bGQuZXF1YWwoYnVpbHRUeC50eXBlLCBUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgc2hvdWxkLmVxdWFsKFxuICAgICAgYnVpbHRUeC5pZCxcbiAgICAgICcyWEZ4R2ZYZGRLV25xR2FNQXNmTkw4SGdYcUR2akJMMkFlMjhLV3JSdmc5YlFCbUNycEhZVkRhY3VaRmVBVXlZd2pYRzZleTJqVEFSWDVWUUNuajdTRjRMJ1xuICAgICk7XG4gICAgYnVpbHRUeC5pbnB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICBidWlsdFR4LmlucHV0c1swXS5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgIGFkZHJlc3M6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICB2YWx1ZTogdGVzdERhdGEudG9rZW5UcmFuc2ZlcnMuYW1vdW50LnRvU3RyaW5nKCksXG4gICAgICBjb2luOiAndHNvbCcsXG4gICAgfSk7XG4gICAgYnVpbHRUeC5vdXRwdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgYnVpbHRUeC5vdXRwdXRzWzBdLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgYWRkcmVzczogJ0NQNURwYWE0MlJ0Sm1NdUtxQ1FzTHdtYTVZaDNrbnV2S3NZREZYODVGNDFTJyxcbiAgICAgIHZhbHVlOiB0ZXN0RGF0YS50b2tlblRyYW5zZmVycy5hbW91bnQudG9TdHJpbmcoKSxcbiAgICAgIGNvaW46ICd0c29sJyxcbiAgICB9KTtcbiAgICBjb25zdCBqc29uVHggPSBidWlsdFR4LnRvSnNvbigpO1xuICAgIGpzb25UeC5pZC5zaG91bGQuZXF1YWwoJzJYRnhHZlhkZEtXbnFHYU1Bc2ZOTDhIZ1hxRHZqQkwyQWUyOEtXclJ2ZzliUUJtQ3JwSFlWRGFjdVpGZUFVeVl3alhHNmV5MmpUQVJYNVZRQ25qN1NGNEwnKTtcbiAgICBqc29uVHguZmVlUGF5ZXIuc2hvdWxkLmVxdWFsKCc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScpO1xuICAgIGpzb25UeC5ub25jZS5zaG91bGQuZXF1YWwoJ0dIdFhRQnNvWkhWbk5GYTlZZXZBekZyMTdESmpnSFhrM3ljVEtENXhEM1ppJyk7XG4gICAganNvblR4Lm51bVNpZ25hdHVyZXMuc2hvdWxkLmVxdWFsKDEpO1xuICAgIGpzb25UeC5kdXJhYmxlTm9uY2Uuc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICB3YWxsZXROb25jZUFkZHJlc3M6ICc4WTdSTTZKZmNYNEFTU05Ca3Jrcm1TYlJ1NDMxWVZpOVkzb0xGbnpDMmRDaCcsXG4gICAgICBhdXRoV2FsbGV0QWRkcmVzczogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICB9KTtcbiAgICBqc29uVHguaW5zdHJ1Y3Rpb25zRGF0YS5zaG91bGQuZGVlcEVxdWFsKFtcbiAgICAgIHtcbiAgICAgICAgdHlwZTogJ1RyYW5zZmVyJyxcbiAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgZnJvbUFkZHJlc3M6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgICAgdG9BZGRyZXNzOiAnQ1A1RHBhYTQyUnRKbU11S3FDUXNMd21hNVloM2tudXZLc1lERlg4NUY0MVMnLFxuICAgICAgICAgIGFtb3VudDogJzMwMDAwMCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB0eXBlOiAnTWVtbycsXG4gICAgICAgIHBhcmFtczogeyBtZW1vOiAndGVzdCBtZW1vJyB9LFxuICAgICAgfSxcbiAgICBdKTtcbiAgICBidWlsdFR4LnRvQnJvYWRjYXN0Rm9ybWF0KCkuc2hvdWxkLmVxdWFsKHRlc3REYXRhLlRSQU5TRkVSX1NJR05FRF9UWF9XSVRIX01FTU9fQU5EX0RVUkFCTEVfTk9OQ0UpO1xuICB9KTtcblxuICBpdCgnYnVpbGQgYSBzZW5kIGZyb20gcmF3IHRva2VuIHRyYW5zYWN0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZnJvbShcbiAgICAgIHRlc3REYXRhLlRPS0VOX1RSQU5TRkVSX1NJR05FRF9UWF9XSVRIX01FTU9fQU5EX0RVUkFCTEVfTk9OQ0VcbiAgICApIGFzIFRva2VuVHJhbnNmZXJCdWlsZGVyO1xuICAgIGNvbnN0IHByaW9GZWVNaWNyb0xhbXBvcnRzID0gJzEwMDAwMDAwJztcbiAgICAvLyBXZSBkb24ndCBoYXZlIHRvIG1hbnVhbGx5IHNldCB0aGUgcHJpb3JpdHkgZmVlIGhlcmUgYXMgdGhlIHJhdyB0eG4gYWxyZWFkeSBoYXMgdGhlIHByaW9yaXR5IGZlZSBpbnN0cnVjdGlvbjtcbiAgICAvLyB0aGVyZWZvcmUgb25jZSBpbml0QnVpbGRlciBpcyBjYWxsZWQgKGl0J3MgY2FsbGVkIHdpdGhpbiBmcm9tSW1wbGVtZW50YXRpb24pLCBpdCB3aWxsIHNldCB0aGUgdHhCdWlsZGVyJ3MgcHJpb3JpdHlGZWUgZmllbGRcbiAgICAvLyB3aGljaCB3aWxsIHRoZW4gYmUgdXNlZCBpbiB0eEJ1aWxkZXIuYnVpbGQoKSBieSB0b2tlblRyYW5zZmVyQnVpbGRlciB0byBhZGQgdGhlIHNldCBjb21wdXRlIGZlZSBpbnN0cnVjdGlvblxuICAgIGNvbnN0IGJ1aWx0VHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICBzaG91bGQuZXF1YWwoYnVpbHRUeC50eXBlLCBUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgc2hvdWxkLmVxdWFsKFxuICAgICAgYnVpbHRUeC5pZCxcbiAgICAgICcydGljVTRaa0VxZFRIVUxyNkxvYlRnV0JoaW02RTd3U3NjRGhNNGd6eXVHVW1ReVV3TFlob3FhaWZ1dndtTnp6RWYxVDVhZWZWY2dNUWtTSGRKNW5zcmZaJ1xuICAgICk7XG4gICAgYnVpbHRUeC5pbnB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICBidWlsdFR4LmlucHV0c1swXS5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgIGFkZHJlc3M6IHRlc3REYXRhLmFzc29jaWF0ZWRUb2tlbkFjY291bnRzLmFjY291bnRzWzBdLnB1YixcbiAgICAgIHZhbHVlOiB0ZXN0RGF0YS50b2tlblRyYW5zZmVycy5hbW91bnQudG9TdHJpbmcoKSxcbiAgICAgIGNvaW46ICd0c29sOnVzZGMnLFxuICAgIH0pO1xuICAgIGJ1aWx0VHgub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgIGJ1aWx0VHgub3V0cHV0c1swXS5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgIGFkZHJlc3M6ICdDUDVEcGFhNDJSdEptTXVLcUNRc0x3bWE1WWgza251dktzWURGWDg1RjQxUycsXG4gICAgICB2YWx1ZTogdGVzdERhdGEudG9rZW5UcmFuc2ZlcnMuYW1vdW50LnRvU3RyaW5nKCksXG4gICAgICBjb2luOiAndHNvbDp1c2RjJyxcbiAgICB9KTtcbiAgICBjb25zdCBqc29uVHggPSBidWlsdFR4LnRvSnNvbigpO1xuICAgIGpzb25UeC5pZC5zaG91bGQuZXF1YWwoJzJ0aWNVNFprRXFkVEhVTHI2TG9iVGdXQmhpbTZFN3dTc2NEaE00Z3p5dUdVbVF5VXdMWWhvcWFpZnV2d21OenpFZjFUNWFlZlZjZ01Ra1NIZEo1bnNyZlonKTtcbiAgICBqc29uVHguZmVlUGF5ZXIuc2hvdWxkLmVxdWFsKHRlc3REYXRhLmFzc29jaWF0ZWRUb2tlbkFjY291bnRzLmFjY291bnRzWzBdLnB1Yik7XG4gICAganNvblR4Lm5vbmNlLnNob3VsZC5lcXVhbCgnR0h0WFFCc29aSFZuTkZhOVlldkF6RnIxN0RKamdIWGszeWNUS0Q1eEQzWmknKTtcbiAgICBqc29uVHgubnVtU2lnbmF0dXJlcy5zaG91bGQuZXF1YWwoMSk7XG4gICAganNvblR4LmR1cmFibGVOb25jZS5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgIHdhbGxldE5vbmNlQWRkcmVzczogJzhZN1JNNkpmY1g0QVNTTkJrcmtybVNiUnU0MzFZVmk5WTNvTEZuekMyZENoJyxcbiAgICAgIGF1dGhXYWxsZXRBZGRyZXNzOiB0ZXN0RGF0YS5hc3NvY2lhdGVkVG9rZW5BY2NvdW50cy5hY2NvdW50c1swXS5wdWIsXG4gICAgfSk7XG4gICAgY29uc3QgcHJpb3JpdHlGZWVCaWdJbnQgPSBCaWdJbnQocHJpb0ZlZU1pY3JvTGFtcG9ydHMpO1xuICAgIGpzb25UeC5pbnN0cnVjdGlvbnNEYXRhLnNob3VsZC5kZWVwRXF1YWwoW1xuICAgICAge1xuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBmZWU6IHByaW9yaXR5RmVlQmlnSW50LFxuICAgICAgICB9LFxuICAgICAgICB0eXBlOiAnU2V0UHJpb3JpdHlGZWUnLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdHlwZTogJ1Rva2VuVHJhbnNmZXInLFxuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBmcm9tQWRkcmVzczogdGVzdERhdGEuYXNzb2NpYXRlZFRva2VuQWNjb3VudHMuYWNjb3VudHNbMF0ucHViLFxuICAgICAgICAgIHRvQWRkcmVzczogJ0NQNURwYWE0MlJ0Sm1NdUtxQ1FzTHdtYTVZaDNrbnV2S3NZREZYODVGNDFTJyxcbiAgICAgICAgICBhbW91bnQ6IHRlc3REYXRhLnRva2VuVHJhbnNmZXJzLmFtb3VudC50b1N0cmluZygpLFxuICAgICAgICAgIHRva2VuTmFtZTogdGVzdERhdGEudG9rZW5UcmFuc2ZlcnMubmFtZVVTREMudG9TdHJpbmcoKSxcbiAgICAgICAgICBzb3VyY2VBZGRyZXNzOiAnQjVySmp1Vmk3RW42M2lLNm8zaWpLZEp3QW9UZTJnd0NZbUpzVmRIUTJhS1YnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdHlwZTogJ01lbW8nLFxuICAgICAgICBwYXJhbXM6IHsgbWVtbzogJ3Rlc3QgbWVtbycgfSxcbiAgICAgIH0sXG4gICAgXSk7XG4gICAgYnVpbHRUeC50b0Jyb2FkY2FzdEZvcm1hdCgpLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5UT0tFTl9UUkFOU0ZFUl9TSUdORURfVFhfV0lUSF9NRU1PX0FORF9EVVJBQkxFX05PTkNFKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ05vbmNlIHRlc3RzJywgYXN5bmMgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgdGhyb3cgZm9yIGludmFsaWQgbm9uY2UnLCAoKSA9PiB7XG4gICAgICBjb25zdCBibG9ja0hhc2ggPSAncmFuZG9tc3RyaW5nJztcbiAgICAgIGZvciAoY29uc3QgdHhCdWlsZGVyIG9mIGJ1aWxkZXJzKSB7XG4gICAgICAgIHNob3VsZCgoKSA9PiB0eEJ1aWxkZXIubm9uY2UoYmxvY2tIYXNoKSkudGhyb3coJ0ludmFsaWQgb3IgbWlzc2luZyBibG9ja0hhc2gsIGdvdDogJyArIGJsb2NrSGFzaCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGZvciBpbnZhbGlkIHBhcmFtcyB1c2luZyBkdXJhYmxlIG5vbmNlJywgKCkgPT4ge1xuICAgICAgY29uc3QgaW52YWxpZFB1YktleSA9ICdyYW5kb21zdHJpbmcnO1xuICAgICAgZm9yIChjb25zdCB0eEJ1aWxkZXIgb2YgYnVpbGRlcnMpIHtcbiAgICAgICAgc2hvdWxkKCgpID0+XG4gICAgICAgICAgdHhCdWlsZGVyLm5vbmNlKHZhbGlkQmxvY2toYXNoLCB7XG4gICAgICAgICAgICB3YWxsZXROb25jZUFkZHJlc3M6IGludmFsaWRQdWJLZXksXG4gICAgICAgICAgICBhdXRoV2FsbGV0QWRkcmVzczogYXV0aEFjY291bnQucHViLFxuICAgICAgICAgIH0pXG4gICAgICAgICkudGhyb3coJ0ludmFsaWQgb3IgbWlzc2luZyB3YWxsZXROb25jZUFkZHJlc3MsIGdvdDogJyArIGludmFsaWRQdWJLZXkpO1xuXG4gICAgICAgIHNob3VsZCgoKSA9PlxuICAgICAgICAgIHR4QnVpbGRlci5ub25jZSh2YWxpZEJsb2NraGFzaCwge1xuICAgICAgICAgICAgd2FsbGV0Tm9uY2VBZGRyZXNzOiBub25jZUFjY291bnQucHViLFxuICAgICAgICAgICAgYXV0aFdhbGxldEFkZHJlc3M6IGludmFsaWRQdWJLZXksXG4gICAgICAgICAgfSlcbiAgICAgICAgKS50aHJvdygnSW52YWxpZCBvciBtaXNzaW5nIGF1dGhXYWxsZXRBZGRyZXNzLCBnb3Q6ICcgKyBpbnZhbGlkUHViS2V5KTtcblxuICAgICAgICBzaG91bGQoKCkgPT5cbiAgICAgICAgICB0eEJ1aWxkZXIubm9uY2UodmFsaWRCbG9ja2hhc2gsIHtcbiAgICAgICAgICAgIHdhbGxldE5vbmNlQWRkcmVzczogbm9uY2VBY2NvdW50LnB1YixcbiAgICAgICAgICAgIGF1dGhXYWxsZXRBZGRyZXNzOiBub25jZUFjY291bnQucHViLFxuICAgICAgICAgIH0pXG4gICAgICAgICkudGhyb3coJ0ludmFsaWQgcGFyYW1zOiB3YWxsZXROb25jZUFkZHJlc3MgY2Fubm90IGJlIGVxdWFsIHRvIGF1dGhXYWxsZXRBZGRyZXNzJyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHN1Y2NlZWQgZm9yIHZhbGlkIG5vbmNlJywgKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCB0eEJ1aWxkZXIgb2YgYnVpbGRlcnMpIHtcbiAgICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiB0eEJ1aWxkZXIubm9uY2UodmFsaWRCbG9ja2hhc2gpKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc3VjY2VlZCBmb3IgdmFsaWQgZHVyYWJsZSBub25jZScsICgpID0+IHtcbiAgICAgIGZvciAoY29uc3QgdHhCdWlsZGVyIG9mIGJ1aWxkZXJzKSB7XG4gICAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT5cbiAgICAgICAgICB0eEJ1aWxkZXIubm9uY2UodmFsaWRCbG9ja2hhc2gsIHsgd2FsbGV0Tm9uY2VBZGRyZXNzOiBub25jZUFjY291bnQucHViLCBhdXRoV2FsbGV0QWRkcmVzczogYXV0aEFjY291bnQucHViIH0pXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdzZW5kZXIgdGVzdHMnLCBhc3luYyAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBmb3IgaW52YWxpZCBzZW5kZXInLCAoKSA9PiB7XG4gICAgICBjb25zdCBpbnZhbGlkUHVibGljS2V5ID0gJ3JhbmRvbXN0cmluZyc7XG4gICAgICBmb3IgKGNvbnN0IHR4QnVpbGRlciBvZiBidWlsZGVycykge1xuICAgICAgICBzaG91bGQoKCkgPT4gdHhCdWlsZGVyLnNlbmRlcihpbnZhbGlkUHVibGljS2V5KSkudGhyb3coJ0ludmFsaWQgb3IgbWlzc2luZyBzZW5kZXIsIGdvdDogJyArIGludmFsaWRQdWJsaWNLZXkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgc3VjY2VlZCBmb3IgdmFsaWQgc2VuZGVyJywgKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCB0eEJ1aWxkZXIgb2YgYnVpbGRlcnMpIHtcbiAgICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiB0eEJ1aWxkZXIuc2VuZGVyKGF1dGhBY2NvdW50LnB1YikpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBpdCgndmFsaWRhdGVBZGRyZXNzJywgKCkgPT4ge1xuICAgIGNvbnN0IHZhbGlkQWRkcmVzcyA9IHsgYWRkcmVzczogYXV0aEFjY291bnQucHViIH07XG4gICAgY29uc3QgaW52YWxpZEFkZHJlc3MgPSB7IGFkZHJlc3M6IHRlc3REYXRhLnB1YktleXMuaW52YWxpZFB1YktleXNbMF0gfTtcbiAgICBmb3IgKGNvbnN0IGJ1aWxkZXIgb2YgYnVpbGRlcnMpIHtcbiAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT4gYnVpbGRlci52YWxpZGF0ZUFkZHJlc3ModmFsaWRBZGRyZXNzKSk7XG4gICAgICBzaG91bGQoKCkgPT4gYnVpbGRlci52YWxpZGF0ZUFkZHJlc3MoaW52YWxpZEFkZHJlc3MpKS50aHJvd0Vycm9yKFxuICAgICAgICAnSW52YWxpZCBhZGRyZXNzICcgKyB0ZXN0RGF0YS5wdWJLZXlzLmludmFsaWRQdWJLZXlzWzBdXG4gICAgICApO1xuICAgIH1cbiAgfSk7XG5cbiAgaXQoJ3ZhbGlkYXRlS2V5JywgKCkgPT4ge1xuICAgIGNvbnN0IHZhbGlkS2V5ID0geyBrZXk6IHRlc3REYXRhLmF1dGhBY2NvdW50LnBydiB9O1xuICAgIGNvbnN0IGludmFsaWRLZXkgPSB7IGtleTogdGVzdERhdGEuYXV0aEFjY291bnQucHViIH07XG4gICAgZm9yIChjb25zdCBidWlsZGVyIG9mIGJ1aWxkZXJzKSB7XG4gICAgICBzaG91bGQuZG9lc05vdFRocm93KCgpID0+IGJ1aWxkZXIudmFsaWRhdGVLZXkodmFsaWRLZXkpKTtcbiAgICAgIHNob3VsZCgoKSA9PiBidWlsZGVyLnZhbGlkYXRlS2V5KGludmFsaWRLZXkpKS50aHJvd0Vycm9yKCdJbnZhbGlkIGtleScpO1xuICAgIH1cbiAgfSk7XG5cbiAgaXQoJ3ZhbGlkYXRlUmF3VHJhbnNhY3Rpb24nLCAoKSA9PiB7XG4gICAgY29uc3QgdmFsaWRSYXdUeCA9IHRlc3REYXRhLlJBV19UWF9TSUdORUQ7XG4gICAgY29uc3QgaW52YWxpZFJhd1R4ID0gJ0FBQUFBQUFBQUFBQUFBQUFBQUEnO1xuICAgIGZvciAoY29uc3QgYnVpbGRlciBvZiBidWlsZGVycykge1xuICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiBidWlsZGVyLnZhbGlkYXRlUmF3VHJhbnNhY3Rpb24odmFsaWRSYXdUeCkpO1xuICAgICAgc2hvdWxkKCgpID0+IGJ1aWxkZXIudmFsaWRhdGVSYXdUcmFuc2FjdGlvbihpbnZhbGlkUmF3VHgpKS50aHJvd0Vycm9yKCdJbnZhbGlkIHJhdyB0cmFuc2FjdGlvbicpO1xuICAgIH1cbiAgfSk7XG5cbiAgaXQoJ3ZhbGlkYXRlVmFsdWUnLCAoKSA9PiB7XG4gICAgY29uc3QgdmFsaWRWYWx1ZSA9IG5ldyBCaWdOdW1iZXIoJzEwMDAwMCcpO1xuICAgIGNvbnN0IGludmFsaWRWYWx1ZSA9IG5ldyBCaWdOdW1iZXIoJy0xMDAwMDAnKTtcbiAgICBmb3IgKGNvbnN0IGJ1aWxkZXIgb2YgYnVpbGRlcnMpIHtcbiAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT4gYnVpbGRlci52YWxpZGF0ZVZhbHVlKHZhbGlkVmFsdWUpKTtcbiAgICAgIHNob3VsZCgoKSA9PiBidWlsZGVyLnZhbGlkYXRlVmFsdWUoaW52YWxpZFZhbHVlKSkudGhyb3dFcnJvcignVmFsdWUgY2Fubm90IGJlIGxlc3MgdGhhbiB6ZXJvJyk7XG4gICAgfVxuICB9KTtcblxuICBpdCgndmFsaWRhdGVNZW1vJywgKCkgPT4ge1xuICAgIGNvbnN0IHZhbGlkTWVtbyA9ICd0ZXN0IG1lbW8nO1xuICAgIGNvbnN0IGludmFsaWRNZW1vID1cbiAgICAgICdvb2F3aW5kYW9ubWF3w7FkYW13ZG9pYW53ZG9uYWxza2RuYWlvdXdiZG9pbm93YWRuOTBhd25kb2F3bmRhb3dkbmFpb2l1d2JkaW9hdXduZGFvdWRuYmF3b2RuYmE5b3d1ZGJuYW93ZG5hYXNkaWpoYWtzZGtqYXNka2poYXNrZGpoa2FzZGFzZGFzZGFzZGFzZCc7XG4gICAgZm9yIChjb25zdCBidWlsZGVyIG9mIGJ1aWxkZXJzKSB7XG4gICAgICBidWlsZGVyLl9pbnN0cnVjdGlvbnNEYXRhLnB1c2goe1xuICAgICAgICB0eXBlOiAnVHJhbnNmZXInLFxuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBmcm9tQWRkcmVzczogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgICB0b0FkZHJlc3M6ICdDUDVEcGFhNDJSdEptTXVLcUNRc0x3bWE1WWgza251dktzWURGWDg1RjQxUycsXG4gICAgICAgICAgYW1vdW50OiAnMzAwMDAwJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgYnVpbGRlci52YWxpZGF0ZU1lbW8odmFsaWRNZW1vKTtcbiAgICAgIHNob3VsZCgoKSA9PiBidWlsZGVyLnZhbGlkYXRlTWVtbyhpbnZhbGlkTWVtbykpLnRocm93RXJyb3IoJ01lbW8gaXMgdG9vIGxvbmcnKTtcbiAgICAgIHNob3VsZCgobWVtbzogc3RyaW5nKSA9PiBidWlsZGVyLnZhbGlkYXRlTWVtbyhtZW1vKSkudGhyb3dFcnJvcignSW52YWxpZCBtZW1vLCBnb3Q6IHVuZGVmaW5lZCcpO1xuICAgIH1cbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2FkZCBzaWduYXR1cmUnLCAoKSA9PiB7XG4gICAgbGV0IE1QQzogRWRkc2E7XG5cbiAgICBpdCgnc2hvdWxkIGFkZCBzaWduYXR1cmUgdG8gdHJhbnNhY3Rpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0cmFuc2ZlckJ1aWxkZXIgPSBmYWN0b3J5XG4gICAgICAgIC5nZXRUcmFuc2ZlckJ1aWxkZXIoKVxuICAgICAgICAuc2VuZGVyKGF1dGhBY2NvdW50LnB1YilcbiAgICAgICAgLm5vbmNlKHZhbGlkQmxvY2toYXNoKVxuICAgICAgICAuZmVlKHsgYW1vdW50OiA1MDAwIH0pXG4gICAgICAgIC5zZW5kKHsgYWRkcmVzczogbm9uY2VBY2NvdW50LnB1YiwgYW1vdW50OiAnMTAwMCcgfSk7XG4gICAgICB0cmFuc2ZlckJ1aWxkZXIuc2lnbih7IGtleTogYXV0aEFjY291bnQucHJ2IH0pO1xuXG4gICAgICBjb25zdCBzaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IHRyYW5zZmVyQnVpbGRlci5idWlsZCgpO1xuICAgICAgLy8gc2lnbmF0dXJlIGlzIGJhc2U1OCBlbmNvZGVkXG4gICAgICBjb25zdCBzaWduYXR1cmUgPSBzaWduZWRUcmFuc2FjdGlvbi5zaWduYXR1cmVbMF07XG5cbiAgICAgIC8vIHZlcmlmeSByZWJ1aWx0IHRyYW5zYWN0aW9uIGNvbnRhaW5zIHNpZ25hdHVyZVxuICAgICAgY29uc3QgcmF3VHJhbnNhY3Rpb24gPSBzaWduZWRUcmFuc2FjdGlvbi50b0Jyb2FkY2FzdEZvcm1hdCgpIGFzIHN0cmluZztcbiAgICAgIGNvbnN0IHJlYnVpbHRTaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGZhY3RvcnkuZnJvbShyYXdUcmFuc2FjdGlvbikuYnVpbGQoKTtcbiAgICAgIHJlYnVpbHRTaWduZWRUcmFuc2FjdGlvbi5zaWduYXR1cmUuc2hvdWxkLmRlZXBFcXVhbChzaWduZWRUcmFuc2FjdGlvbi5zaWduYXR1cmUpO1xuXG4gICAgICBjb25zdCB0cmFuc2ZlckJ1aWxkZXIyID0gZmFjdG9yeVxuICAgICAgICAuZ2V0VHJhbnNmZXJCdWlsZGVyKClcbiAgICAgICAgLnNlbmRlcihhdXRoQWNjb3VudC5wdWIpXG4gICAgICAgIC5ub25jZSh2YWxpZEJsb2NraGFzaClcbiAgICAgICAgLmZlZSh7IGFtb3VudDogNTAwMCB9KVxuICAgICAgICAuc2VuZCh7IGFkZHJlc3M6IG5vbmNlQWNjb3VudC5wdWIsIGFtb3VudDogJzEwMDAnIH0pO1xuICAgICAgdHJhbnNmZXJCdWlsZGVyMi5hZGRTaWduYXR1cmUoeyBwdWI6IGF1dGhBY2NvdW50LnB1YiB9LCBCdWZmZXIuZnJvbShiczU4LmRlY29kZShzaWduYXR1cmUpKSk7XG4gICAgICBjb25zdCBzaWduZWRUcmFuc2FjdGlvbjIgPSBhd2FpdCB0cmFuc2ZlckJ1aWxkZXIyLmJ1aWxkKCk7XG5cbiAgICAgIC8vIHZlcmlmeSBzaWduYXR1cmVzIGFyZSBjb3JyZWN0XG4gICAgICBzaWduZWRUcmFuc2FjdGlvbi5zaWduYXR1cmUuc2hvdWxkLmRlZXBFcXVhbChzaWduZWRUcmFuc2FjdGlvbjIuc2lnbmF0dXJlKTtcblxuICAgICAgLy8gdmVyaWZ5IHJlYnVpbHQgdHJhbnNhY3Rpb24gY29udGFpbnMgc2lnbmF0dXJlXG4gICAgICBjb25zdCByYXdUcmFuc2FjdGlvbjIgPSBzaWduZWRUcmFuc2FjdGlvbjIudG9Ccm9hZGNhc3RGb3JtYXQoKSBhcyBzdHJpbmc7XG4gICAgICBjb25zdCByZWJ1aWx0VHJhbnNhY3Rpb24yID0gYXdhaXQgZmFjdG9yeS5mcm9tKHJhd1RyYW5zYWN0aW9uMikuYnVpbGQoKTtcbiAgICAgIHJlYnVpbHRUcmFuc2FjdGlvbjIuc2lnbmF0dXJlLnNob3VsZC5kZWVwRXF1YWwoc2lnbmVkVHJhbnNhY3Rpb24yLnNpZ25hdHVyZSk7XG4gICAgfSk7XG5cbiAgICBiZWZvcmUoJ2luaXRpYWxpemUgbXBjIG1vZHVsZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGhkVHJlZSA9IGF3YWl0IEVkMjU1MTlCaXAzMkhkVHJlZS5pbml0aWFsaXplKCk7XG4gICAgICBNUEMgPSBhd2FpdCBFZGRzYS5pbml0aWFsaXplKGhkVHJlZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFkZCBUU1Mgc2lnbmF0dXJlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgQSA9IE1QQy5rZXlTaGFyZSgxLCAyLCAzKTtcbiAgICAgIGNvbnN0IEIgPSBNUEMua2V5U2hhcmUoMiwgMiwgMyk7XG4gICAgICBjb25zdCBDID0gTVBDLmtleVNoYXJlKDMsIDIsIDMpO1xuXG4gICAgICBjb25zdCBBX2NvbWJpbmUgPSBNUEMua2V5Q29tYmluZShBLnVTaGFyZSwgW0IueVNoYXJlc1sxXSwgQy55U2hhcmVzWzFdXSk7XG4gICAgICBjb25zdCBCX2NvbWJpbmUgPSBNUEMua2V5Q29tYmluZShCLnVTaGFyZSwgW0EueVNoYXJlc1syXSwgQy55U2hhcmVzWzJdXSk7XG4gICAgICBjb25zdCBDX2NvbWJpbmUgPSBNUEMua2V5Q29tYmluZShDLnVTaGFyZSwgW0EueVNoYXJlc1szXSwgQi55U2hhcmVzWzNdXSk7XG5cbiAgICAgIGNvbnN0IGNvbW1vblB1YiA9IEFfY29tYmluZS5wU2hhcmUueTtcbiAgICAgIGNvbnN0IHNvbFB1YmxpY0tleSA9IG5ldyBLZXlQYWlyKHsgcHViOiBjb21tb25QdWIgfSk7XG4gICAgICBjb25zdCBzZW5kZXIgPSBzb2xQdWJsaWNLZXkuZ2V0QWRkcmVzcygpO1xuXG4gICAgICBsZXQgdHJhbnNmZXJCdWlsZGVyID0gZmFjdG9yeVxuICAgICAgICAuZ2V0VHJhbnNmZXJCdWlsZGVyKClcbiAgICAgICAgLnNlbmRlcihzZW5kZXIpXG4gICAgICAgIC5ub25jZSh2YWxpZEJsb2NraGFzaClcbiAgICAgICAgLmZlZSh7IGFtb3VudDogNTAwMCB9KVxuICAgICAgICAuc2VuZCh7IGFkZHJlc3M6IG5vbmNlQWNjb3VudC5wdWIsIGFtb3VudDogJzEwMDAnIH0pO1xuICAgICAgY29uc3QgdW5zaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IHRyYW5zZmVyQnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3Qgc2lnbmFibGVQYXlsb2FkID0gdW5zaWduZWRUcmFuc2FjdGlvbi5zaWduYWJsZVBheWxvYWQ7XG5cbiAgICAgIC8vIHNpZ25pbmcgd2l0aCBBIGFuZCBCXG4gICAgICBsZXQgQV9zaWduX3NoYXJlID0gTVBDLnNpZ25TaGFyZShzaWduYWJsZVBheWxvYWQsIEFfY29tYmluZS5wU2hhcmUsIFtBX2NvbWJpbmUualNoYXJlc1syXV0pO1xuICAgICAgbGV0IEJfc2lnbl9zaGFyZSA9IE1QQy5zaWduU2hhcmUoc2lnbmFibGVQYXlsb2FkLCBCX2NvbWJpbmUucFNoYXJlLCBbQl9jb21iaW5lLmpTaGFyZXNbMV1dKTtcbiAgICAgIGxldCBBX3NpZ24gPSBNUEMuc2lnbihzaWduYWJsZVBheWxvYWQsIEFfc2lnbl9zaGFyZS54U2hhcmUsIFtCX3NpZ25fc2hhcmUuclNoYXJlc1sxXV0sIFtDLnlTaGFyZXNbMV1dKTtcbiAgICAgIGxldCBCX3NpZ24gPSBNUEMuc2lnbihzaWduYWJsZVBheWxvYWQsIEJfc2lnbl9zaGFyZS54U2hhcmUsIFtBX3NpZ25fc2hhcmUuclNoYXJlc1syXV0sIFtDLnlTaGFyZXNbMl1dKTtcbiAgICAgIGxldCBzaWduYXR1cmUgPSBNUEMuc2lnbkNvbWJpbmUoW0Ffc2lnbiwgQl9zaWduXSk7XG4gICAgICBsZXQgcmF3U2lnbmF0dXJlID0gQnVmZmVyLmNvbmNhdChbQnVmZmVyLmZyb20oc2lnbmF0dXJlLlIsICdoZXgnKSwgQnVmZmVyLmZyb20oc2lnbmF0dXJlLnNpZ21hLCAnaGV4JyldKTtcblxuICAgICAgdHJhbnNmZXJCdWlsZGVyID0gZmFjdG9yeVxuICAgICAgICAuZ2V0VHJhbnNmZXJCdWlsZGVyKClcbiAgICAgICAgLnNlbmRlcihzZW5kZXIpXG4gICAgICAgIC5ub25jZSh2YWxpZEJsb2NraGFzaClcbiAgICAgICAgLmZlZSh7IGFtb3VudDogNTAwMCB9KVxuICAgICAgICAuc2VuZCh7IGFkZHJlc3M6IG5vbmNlQWNjb3VudC5wdWIsIGFtb3VudDogJzEwMDAnIH0pO1xuICAgICAgdHJhbnNmZXJCdWlsZGVyLmFkZFNpZ25hdHVyZSh7IHB1Yjogc2VuZGVyIH0sIHJhd1NpZ25hdHVyZSk7XG4gICAgICBsZXQgc2lnbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCB0cmFuc2ZlckJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIHNpZ25lZFRyYW5zYWN0aW9uLnNpZ25hdHVyZS5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgc2lnbmVkVHJhbnNhY3Rpb24uc2lnbmF0dXJlWzBdLnNob3VsZC5lcXVhbChiczU4LmVuY29kZShyYXdTaWduYXR1cmUpKTtcbiAgICAgIHNpZ25lZFRyYW5zYWN0aW9uLmlkLnNob3VsZC5lcXVhbChiczU4LmVuY29kZShyYXdTaWduYXR1cmUpKTtcblxuICAgICAgLy8gc2lnbmluZyB3aXRoIEEgYW5kIENcbiAgICAgIEFfc2lnbl9zaGFyZSA9IE1QQy5zaWduU2hhcmUoc2lnbmFibGVQYXlsb2FkLCBBX2NvbWJpbmUucFNoYXJlLCBbQV9jb21iaW5lLmpTaGFyZXNbM11dKTtcbiAgICAgIGxldCBDX3NpZ25fc2hhcmUgPSBNUEMuc2lnblNoYXJlKHNpZ25hYmxlUGF5bG9hZCwgQ19jb21iaW5lLnBTaGFyZSwgW0NfY29tYmluZS5qU2hhcmVzWzFdXSk7XG4gICAgICBBX3NpZ24gPSBNUEMuc2lnbihzaWduYWJsZVBheWxvYWQsIEFfc2lnbl9zaGFyZS54U2hhcmUsIFtDX3NpZ25fc2hhcmUuclNoYXJlc1sxXV0sIFtCLnlTaGFyZXNbMV1dKTtcbiAgICAgIGxldCBDX3NpZ24gPSBNUEMuc2lnbihzaWduYWJsZVBheWxvYWQsIENfc2lnbl9zaGFyZS54U2hhcmUsIFtBX3NpZ25fc2hhcmUuclNoYXJlc1szXV0sIFtCLnlTaGFyZXNbM11dKTtcbiAgICAgIHNpZ25hdHVyZSA9IE1QQy5zaWduQ29tYmluZShbQV9zaWduLCBDX3NpZ25dKTtcbiAgICAgIHJhd1NpZ25hdHVyZSA9IEJ1ZmZlci5jb25jYXQoW0J1ZmZlci5mcm9tKHNpZ25hdHVyZS5SLCAnaGV4JyksIEJ1ZmZlci5mcm9tKHNpZ25hdHVyZS5zaWdtYSwgJ2hleCcpXSk7XG5cbiAgICAgIHRyYW5zZmVyQnVpbGRlciA9IGZhY3RvcnlcbiAgICAgICAgLmdldFRyYW5zZmVyQnVpbGRlcigpXG4gICAgICAgIC5zZW5kZXIoc2VuZGVyKVxuICAgICAgICAubm9uY2UodmFsaWRCbG9ja2hhc2gpXG4gICAgICAgIC5mZWUoeyBhbW91bnQ6IDUwMDAgfSlcbiAgICAgICAgLnNlbmQoeyBhZGRyZXNzOiBub25jZUFjY291bnQucHViLCBhbW91bnQ6ICcxMDAwJyB9KTtcbiAgICAgIHRyYW5zZmVyQnVpbGRlci5hZGRTaWduYXR1cmUoeyBwdWI6IHNlbmRlciB9LCByYXdTaWduYXR1cmUpO1xuICAgICAgc2lnbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCB0cmFuc2ZlckJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIHNpZ25lZFRyYW5zYWN0aW9uLnNpZ25hdHVyZS5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgc2lnbmVkVHJhbnNhY3Rpb24uc2lnbmF0dXJlWzBdLnNob3VsZC5lcXVhbChiczU4LmVuY29kZShyYXdTaWduYXR1cmUpKTtcbiAgICAgIHNpZ25lZFRyYW5zYWN0aW9uLmlkLnNob3VsZC5lcXVhbChiczU4LmVuY29kZShyYXdTaWduYXR1cmUpKTtcblxuICAgICAgLy8gc2lnbmluZyB3aXRoIEIgYW5kIENcbiAgICAgIEJfc2lnbl9zaGFyZSA9IE1QQy5zaWduU2hhcmUoc2lnbmFibGVQYXlsb2FkLCBCX2NvbWJpbmUucFNoYXJlLCBbQl9jb21iaW5lLmpTaGFyZXNbM11dKTtcbiAgICAgIENfc2lnbl9zaGFyZSA9IE1QQy5zaWduU2hhcmUoc2lnbmFibGVQYXlsb2FkLCBDX2NvbWJpbmUucFNoYXJlLCBbQ19jb21iaW5lLmpTaGFyZXNbMl1dKTtcbiAgICAgIEJfc2lnbiA9IE1QQy5zaWduKHNpZ25hYmxlUGF5bG9hZCwgQl9zaWduX3NoYXJlLnhTaGFyZSwgW0Nfc2lnbl9zaGFyZS5yU2hhcmVzWzJdXSwgW0EueVNoYXJlc1syXV0pO1xuICAgICAgQ19zaWduID0gTVBDLnNpZ24oc2lnbmFibGVQYXlsb2FkLCBDX3NpZ25fc2hhcmUueFNoYXJlLCBbQl9zaWduX3NoYXJlLnJTaGFyZXNbM11dLCBbQS55U2hhcmVzWzNdXSk7XG4gICAgICBzaWduYXR1cmUgPSBNUEMuc2lnbkNvbWJpbmUoW0Jfc2lnbiwgQ19zaWduXSk7XG4gICAgICByYXdTaWduYXR1cmUgPSBCdWZmZXIuY29uY2F0KFtCdWZmZXIuZnJvbShzaWduYXR1cmUuUiwgJ2hleCcpLCBCdWZmZXIuZnJvbShzaWduYXR1cmUuc2lnbWEsICdoZXgnKV0pO1xuXG4gICAgICB0cmFuc2ZlckJ1aWxkZXIgPSBmYWN0b3J5XG4gICAgICAgIC5nZXRUcmFuc2ZlckJ1aWxkZXIoKVxuICAgICAgICAuc2VuZGVyKHNlbmRlcilcbiAgICAgICAgLm5vbmNlKHZhbGlkQmxvY2toYXNoKVxuICAgICAgICAuZmVlKHsgYW1vdW50OiA1MDAwIH0pXG4gICAgICAgIC5zZW5kKHsgYWRkcmVzczogbm9uY2VBY2NvdW50LnB1YiwgYW1vdW50OiAnMTAwMCcgfSk7XG4gICAgICB0cmFuc2ZlckJ1aWxkZXIuYWRkU2lnbmF0dXJlKHsgcHViOiBzZW5kZXIgfSwgcmF3U2lnbmF0dXJlKTtcbiAgICAgIHNpZ25lZFRyYW5zYWN0aW9uID0gYXdhaXQgdHJhbnNmZXJCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBzaWduZWRUcmFuc2FjdGlvbi5zaWduYXR1cmUubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIHNpZ25lZFRyYW5zYWN0aW9uLnNpZ25hdHVyZVswXS5zaG91bGQuZXF1YWwoYnM1OC5lbmNvZGUocmF3U2lnbmF0dXJlKSk7XG4gICAgICBzaWduZWRUcmFuc2FjdGlvbi5pZC5zaG91bGQuZXF1YWwoYnM1OC5lbmNvZGUocmF3U2lnbmF0dXJlKSk7XG5cbiAgICAgIGNvbnN0IHJhd1RyYW5zYWN0aW9uID0gc2lnbmVkVHJhbnNhY3Rpb24udG9Ccm9hZGNhc3RGb3JtYXQoKSBhcyBzdHJpbmc7XG4gICAgICBjb25zdCByZWJ1aWx0VHJhbnNhY3Rpb24gPSBhd2FpdCBmYWN0b3J5LmZyb20ocmF3VHJhbnNhY3Rpb24pLmJ1aWxkKCk7XG4gICAgICByZWJ1aWx0VHJhbnNhY3Rpb24uaWQuc2hvdWxkLmVxdWFsKHNpZ25lZFRyYW5zYWN0aW9uLmlkKTtcbiAgICAgIHJlYnVpbHRUcmFuc2FjdGlvbi5zaWduYXR1cmUuc2hvdWxkLmRlZXBFcXVhbChzaWduZWRUcmFuc2FjdGlvbi5zaWduYXR1cmUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhZGQgVFNTIEhEIHNpZ25hdHVyZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IEEgPSBNUEMua2V5U2hhcmUoMSwgMiwgMyk7XG4gICAgICBjb25zdCBCID0gTVBDLmtleVNoYXJlKDIsIDIsIDMpO1xuICAgICAgY29uc3QgQyA9IE1QQy5rZXlTaGFyZSgzLCAyLCAzKTtcblxuICAgICAgY29uc3QgQV9jb21iaW5lID0gTVBDLmtleUNvbWJpbmUoQS51U2hhcmUsIFtCLnlTaGFyZXNbMV0sIEMueVNoYXJlc1sxXV0pO1xuICAgICAgY29uc3QgQl9jb21iaW5lID0gTVBDLmtleUNvbWJpbmUoQi51U2hhcmUsIFtBLnlTaGFyZXNbMl0sIEMueVNoYXJlc1syXV0pO1xuXG4gICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgMTA7IGluZGV4KyspIHtcbiAgICAgICAgY29uc3QgcGF0aCA9IGBtLyR7aW5kZXh9YDtcblxuICAgICAgICBjb25zdCBBX3N1YmtleSA9IE1QQy5rZXlEZXJpdmUoQS51U2hhcmUsIFtCLnlTaGFyZXNbMV0sIEMueVNoYXJlc1sxXV0sIHBhdGgpO1xuICAgICAgICBjb25zdCBCX3N1YmtleSA9IE1QQy5rZXlDb21iaW5lKEIudVNoYXJlLCBbQV9zdWJrZXkueVNoYXJlc1syXSwgQy55U2hhcmVzWzJdXSk7XG5cbiAgICAgICAgY29uc3Qgc29sUHVibGljS2V5ID0gbmV3IEtleVBhaXIoeyBwdWI6IEFfc3Via2V5LnBTaGFyZS55IH0pO1xuICAgICAgICBjb25zdCBzZW5kZXIgPSBzb2xQdWJsaWNLZXkuZ2V0QWRkcmVzcygpO1xuXG4gICAgICAgIGNvbnN0IHRyYW5zZmVyQnVpbGRlciA9IGZhY3RvcnlcbiAgICAgICAgICAuZ2V0VHJhbnNmZXJCdWlsZGVyKClcbiAgICAgICAgICAuc2VuZGVyKHNlbmRlcilcbiAgICAgICAgICAubm9uY2UodmFsaWRCbG9ja2hhc2gpXG4gICAgICAgICAgLmZlZSh7IGFtb3VudDogNTAwMCB9KVxuICAgICAgICAgIC5zZW5kKHsgYWRkcmVzczogbm9uY2VBY2NvdW50LnB1YiwgYW1vdW50OiAnMTAwMCcgfSk7XG4gICAgICAgIGNvbnN0IHVuc2lnbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCB0cmFuc2ZlckJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgICAgY29uc3Qgc2lnbmFibGVQYXlsb2FkID0gdW5zaWduZWRUcmFuc2FjdGlvbi5zaWduYWJsZVBheWxvYWQ7XG5cbiAgICAgICAgY29uc3QgQV9zaWduX3NoYXJlID0gTVBDLnNpZ25TaGFyZShzaWduYWJsZVBheWxvYWQsIEFfc3Via2V5LnBTaGFyZSwgW0FfY29tYmluZS5qU2hhcmVzWzJdXSk7XG4gICAgICAgIGNvbnN0IEJfc2lnbl9zaGFyZSA9IE1QQy5zaWduU2hhcmUoc2lnbmFibGVQYXlsb2FkLCBCX3N1YmtleS5wU2hhcmUsIFtCX2NvbWJpbmUualNoYXJlc1sxXV0pO1xuICAgICAgICBjb25zdCBBX3NpZ24gPSBNUEMuc2lnbihzaWduYWJsZVBheWxvYWQsIEFfc2lnbl9zaGFyZS54U2hhcmUsIFtCX3NpZ25fc2hhcmUuclNoYXJlc1sxXV0sIFtDLnlTaGFyZXNbMV1dKTtcbiAgICAgICAgY29uc3QgQl9zaWduID0gTVBDLnNpZ24oc2lnbmFibGVQYXlsb2FkLCBCX3NpZ25fc2hhcmUueFNoYXJlLCBbQV9zaWduX3NoYXJlLnJTaGFyZXNbMl1dLCBbQy55U2hhcmVzWzJdXSk7XG5cbiAgICAgICAgY29uc3Qgc2lnbmF0dXJlID0gTVBDLnNpZ25Db21iaW5lKFtBX3NpZ24sIEJfc2lnbl0pO1xuICAgICAgICBjb25zdCByYXdTaWduYXR1cmUgPSBCdWZmZXIuY29uY2F0KFtCdWZmZXIuZnJvbShzaWduYXR1cmUuUiwgJ2hleCcpLCBCdWZmZXIuZnJvbShzaWduYXR1cmUuc2lnbWEsICdoZXgnKV0pO1xuXG4gICAgICAgIHRyYW5zZmVyQnVpbGRlci5hZGRTaWduYXR1cmUoeyBwdWI6IHNlbmRlciB9LCByYXdTaWduYXR1cmUpO1xuXG4gICAgICAgIGNvbnN0IHNpZ25lZFRyYW5zYWN0aW9uID0gYXdhaXQgdHJhbnNmZXJCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICAgIHNpZ25lZFRyYW5zYWN0aW9uLnNpZ25hdHVyZS5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICBzaWduZWRUcmFuc2FjdGlvbi5zaWduYXR1cmVbMF0uc2hvdWxkLmVxdWFsKGJzNTguZW5jb2RlKHJhd1NpZ25hdHVyZSkpO1xuICAgICAgICBzaWduZWRUcmFuc2FjdGlvbi5pZC5zaG91bGQuZXF1YWwoYnM1OC5lbmNvZGUocmF3U2lnbmF0dXJlKSk7XG5cbiAgICAgICAgY29uc3QgcmF3VHJhbnNhY3Rpb24gPSBzaWduZWRUcmFuc2FjdGlvbi50b0Jyb2FkY2FzdEZvcm1hdCgpIGFzIHN0cmluZztcbiAgICAgICAgY29uc3QgcmVidWlsdFRyYW5zYWN0aW9uID0gYXdhaXQgZmFjdG9yeS5mcm9tKHJhd1RyYW5zYWN0aW9uKS5idWlsZCgpO1xuICAgICAgICByZWJ1aWx0VHJhbnNhY3Rpb24uaWQuc2hvdWxkLmVxdWFsKHNpZ25lZFRyYW5zYWN0aW9uLmlkKTtcbiAgICAgICAgcmVidWlsdFRyYW5zYWN0aW9uLnNpZ25hdHVyZS5zaG91bGQuZGVlcEVxdWFsKHNpZ25lZFRyYW5zYWN0aW9uLnNpZ25hdHVyZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=

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


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