PHP WebShell

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

Просмотр файла: transaction.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 assert_1 = __importDefault(require("assert"));
const should_1 = __importDefault(require("should"));
const statics_1 = require("@bitgo/statics");
const lib_1 = require("../../src/lib");
const testData = __importStar(require("../resources/sol"));
const web3_js_1 = require("@solana/web3.js");
const getBuilderFactory_1 = require("./getBuilderFactory");
describe('Sol Transaction', () => {
    const coin = statics_1.coins.get('tsol');
    describe('toJson should', () => {
        it('throw empty transaction', () => {
            const tx = new lib_1.Transaction(coin);
            assert_1.default.throws(() => tx.toJson(), /Empty transaction/);
            assert_1.default.throws(() => tx.toBroadcastFormat(), /Empty transaction/);
        });
        it('throw for toJson of empty tx', () => {
            const tx = new lib_1.Transaction(coin);
            (0, should_1.default)(() => tx.toJson()).throwError('Empty transaction');
            tx.solTransaction = new web3_js_1.Transaction();
            tx.solTransaction.recentBlockhash = testData.blockHashes.validBlockHashes[0];
            (0, should_1.default)(() => tx.toJson()).throwError('Invalid transaction, transaction type not supported: undefined');
        });
        it('succeed for a unsigned transfer tx', () => {
            const tx = new lib_1.Transaction(coin);
            tx.fromRawTransaction(testData.TRANSFER_UNSIGNED_TX_WITH_MEMO_AND_DURABLE_NONCE);
            tx.signature.should.be.empty();
            const txJson = tx.toJson();
            txJson.should.have.properties(['id', 'feePayer', 'nonce', 'numSignatures', 'instructionsData']);
            txJson.id?.should.equal(undefined);
            txJson.feePayer?.should.equal('5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe');
            txJson.nonce.should.equal('GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi');
            txJson.numSignatures.should.equal(0);
            txJson.instructionsData.length.should.equal(3);
            txJson.lamportsPerSignature?.should.be.undefined();
            txJson.instructionsData.should.deepEqual([
                {
                    type: 'NonceAdvance',
                    params: {
                        walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
                        authWalletAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
                    },
                },
                {
                    type: 'Transfer',
                    params: {
                        fromAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
                        toAddress: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
                        amount: '300000',
                    },
                },
                {
                    type: 'Memo',
                    params: {
                        memo: 'test memo',
                    },
                },
            ]);
        });
        it('succeed for a multi transfer tx', () => {
            const tx = new lib_1.Transaction(coin);
            tx.fromRawTransaction(testData.MULTI_TRANSFER_SIGNED);
            const txJson = tx.toJson();
            txJson.should.have.properties(['id', 'feePayer', 'nonce', 'numSignatures', 'instructionsData']);
            txJson.id?.should.equal('TPVcc18CYxPnM3eRgQhdb6V6ZLa34Dv3dU7MtvKPuy5ZPKLM1uZPFFEmF2m184PTWKRZ1Uq6NKFZWwr2krKk63f');
            tx.signature.should.deepEqual([
                'TPVcc18CYxPnM3eRgQhdb6V6ZLa34Dv3dU7MtvKPuy5ZPKLM1uZPFFEmF2m184PTWKRZ1Uq6NKFZWwr2krKk63f',
            ]);
            txJson.feePayer?.should.equal('5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe');
            txJson.nonce.should.equal('GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi');
            txJson.numSignatures.should.equal(1);
            txJson.lamportsPerSignature?.should.be.undefined();
            txJson.instructionsData.length.should.equal(8);
            txJson.instructionsData.should.deepEqual([
                {
                    type: 'NonceAdvance',
                    params: {
                        walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
                        authWalletAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
                    },
                },
                {
                    type: 'Transfer',
                    params: {
                        fromAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
                        toAddress: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
                        amount: '300000',
                    },
                },
                {
                    type: 'Transfer',
                    params: {
                        fromAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
                        toAddress: '6B55XMiaS6tUZw5Tt3G1RaXAqdrvN38yXVDJmWvKLkiM',
                        amount: '300000',
                    },
                },
                {
                    type: 'Transfer',
                    params: {
                        fromAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
                        toAddress: 'C1UjpxcXNBpp1UyvYsuNBNZ5Da1G1i49g3yTvC23Ny7e',
                        amount: '300000',
                    },
                },
                {
                    type: 'Transfer',
                    params: {
                        fromAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
                        toAddress: 'CpUYXh9xXoWfkBVaBQRZ8nAgDbT16GZeQdqveeBS1hmk',
                        amount: '300000',
                    },
                },
                {
                    type: 'Transfer',
                    params: {
                        fromAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
                        toAddress: '64s6NjmEokdhicHEd432X5Ut2EDfDmVqdvGh4rASn1gd',
                        amount: '300000',
                    },
                },
                {
                    type: 'Transfer',
                    params: {
                        fromAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
                        toAddress: '6nXxL2jMSdkgfHm13Twvn1gzRAPdrWnWLfu89PJL3Aqe',
                        amount: '300000',
                    },
                },
                {
                    type: 'Memo',
                    params: {
                        memo: 'test memo',
                    },
                },
            ]);
        });
    });
    describe('sign should', () => {
        it('fail if the tx doesnt have nonce', async () => {
            const tx = new lib_1.Transaction(coin);
            tx.solTransaction = new web3_js_1.Transaction();
            tx.solTransaction.feePayer = new web3_js_1.PublicKey(testData.authAccount.pub);
            const kp = new lib_1.KeyPair({ prv: testData.prvKeys.prvKey1.base58 });
            await tx.sign(kp).should.be.rejectedWith('Nonce is required before signing');
        });
        it('fail if the tx doesnt have feePayer', async () => {
            const tx = new lib_1.Transaction(coin);
            const kp = new lib_1.KeyPair({ prv: testData.prvKeys.prvKey1.base58 });
            tx.solTransaction = new web3_js_1.Transaction();
            tx.solTransaction.recentBlockhash = testData.blockHashes.validBlockHashes[0];
            await tx.sign(kp).should.be.rejectedWith('feePayer is required before signing');
        });
        it('fail if the KeyPair is not the right one', async () => {
            const tx = new lib_1.Transaction(coin);
            tx.fromRawTransaction(testData.RAW_TX_UNSIGNED);
            const keypair = new lib_1.KeyPair({ prv: testData.prvKeys.prvKey1.base58 });
            await tx.sign(keypair).should.be.rejectedWith('unknown signer: CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S');
        });
        it('fail if the KeyPair doesnt have a prv key', async () => {
            const tx = new lib_1.Transaction(coin);
            tx.fromRawTransaction(testData.RAW_TX_UNSIGNED);
            const keypair = new lib_1.KeyPair({ pub: testData.pubKeys.validPubKeys[0] });
            await tx.sign(keypair).should.be.rejectedWith('Missing private key');
        });
        it('succeed to sign with 1 KeyPair', async () => {
            const tx = new lib_1.Transaction(coin);
            tx.fromRawTransaction(testData.RAW_TX_UNSIGNED);
            const keypair = new lib_1.KeyPair({ prv: testData.accountWithSeed.privateKey.base58 });
            await tx.sign(keypair).should.be.fulfilled();
            should_1.default.equal(tx.toBroadcastFormat(), testData.RAW_TX_SIGNED);
        });
        it('succeed when try to sign with the same keyPair multiple times ', async () => {
            const tx = new lib_1.Transaction(coin);
            tx.fromRawTransaction(testData.RAW_TX_UNSIGNED);
            const keypair = new lib_1.KeyPair({ prv: testData.accountWithSeed.privateKey.base58 });
            await tx.sign([keypair, keypair, keypair, keypair]).should.be.fulfilled();
            should_1.default.equal(tx.toBroadcastFormat(), testData.RAW_TX_SIGNED);
        });
        it('succeed when try to sign with a keyPair that already signed', async () => {
            const tx = new lib_1.Transaction(coin);
            tx.fromRawTransaction(testData.RAW_TX_SIGNED);
            const keypair = new lib_1.KeyPair({ prv: testData.accountWithSeed.privateKey.base58 });
            await tx.sign(keypair).should.be.fulfilled();
            should_1.default.equal(tx.toBroadcastFormat(), testData.RAW_TX_SIGNED);
        });
    });
    describe('transaction parsing', function () {
        it('fromRawTransaction and toBroadcastFormat', async function () {
            const tx = new lib_1.Transaction(coin);
            tx.fromRawTransaction(testData.RAW_TX_UNSIGNED);
            should_1.default.equal(tx.toBroadcastFormat(), testData.RAW_TX_UNSIGNED);
        });
        it('fromRawTransaction, sign and toBroadcastFormat ', async function () {
            const tx = new lib_1.Transaction(coin);
            tx.fromRawTransaction(testData.RAW_TX_UNSIGNED);
            const keypair = new lib_1.KeyPair({ prv: testData.accountWithSeed.privateKey.base58 });
            await tx.sign(keypair);
            should_1.default.equal(tx.toBroadcastFormat(), testData.RAW_TX_SIGNED);
        });
    });
    describe('explain transaction', function () {
        const factory = (0, getBuilderFactory_1.getBuilderFactory)('tsol');
        const blockHash = testData.blockHashes.validBlockHashes[0];
        const sender = testData.authAccount.pub;
        const address = testData.addresses.validAddresses[0];
        const amount = '10000';
        const wallet = new lib_1.KeyPair(testData.authAccount).getKeys();
        const stakeAccount = new lib_1.KeyPair(testData.stakeAccount).getKeys();
        const validator = testData.validator;
        it('should explain single transfer transaction', async function () {
            const tx = await factory
                .getTransferBuilder()
                .nonce(blockHash)
                .sender(sender)
                .send({ address, amount })
                .fee({ amount: 5000 })
                .build();
            const explainedTransaction = tx.explainTransaction();
            explainedTransaction.should.deepEqual({
                displayOrder: [
                    'id',
                    'type',
                    'blockhash',
                    'durableNonce',
                    'outputAmount',
                    'changeAmount',
                    'outputs',
                    'changeOutputs',
                    'fee',
                    'memo',
                ],
                id: 'UNAVAILABLE',
                type: 'Send',
                changeOutputs: [],
                changeAmount: '0',
                outputAmount: '10000',
                outputs: [
                    {
                        address: 'DesU7XscZjng8yj5VX6AZsk3hWSW4sQ3rTG2LuyQ2P4H',
                        amount: '10000',
                    },
                ],
                fee: {
                    fee: '5000',
                    feeRate: 5000,
                },
                memo: undefined,
                blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
                durableNonce: undefined,
            });
        });
        it('should explain single transfer with durable nonce transaction', async function () {
            const tx = await factory
                .getTransferBuilder()
                .nonce(blockHash, { walletNonceAddress: testData.nonceAccount.pub, authWalletAddress: sender })
                .sender(sender)
                .send({ address, amount })
                .build();
            const explainedTransaction = tx.explainTransaction();
            explainedTransaction.should.deepEqual({
                displayOrder: [
                    'id',
                    'type',
                    'blockhash',
                    'durableNonce',
                    'outputAmount',
                    'changeAmount',
                    'outputs',
                    'changeOutputs',
                    'fee',
                    'memo',
                ],
                id: 'UNAVAILABLE',
                type: 'Send',
                changeOutputs: [],
                changeAmount: '0',
                outputAmount: '10000',
                outputs: [
                    {
                        address: 'DesU7XscZjng8yj5VX6AZsk3hWSW4sQ3rTG2LuyQ2P4H',
                        amount: '10000',
                    },
                ],
                fee: {
                    fee: 'UNAVAILABLE',
                    feeRate: undefined,
                },
                memo: undefined,
                blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
                durableNonce: {
                    authWalletAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
                    walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
                },
            });
        });
        it('should explain multi transfer with durable nonce and memo transaction', async function () {
            const tx = await factory
                .getTransferBuilder()
                .nonce(blockHash, { walletNonceAddress: testData.nonceAccount.pub, authWalletAddress: sender })
                .sender(sender)
                .memo('memo text')
                .send({ address, amount })
                .send({ address: testData.addresses.validAddresses[1], amount })
                .send({ address: testData.addresses.validAddresses[2], amount })
                .build();
            const explainedTransaction = tx.explainTransaction();
            explainedTransaction.should.deepEqual({
                displayOrder: [
                    'id',
                    'type',
                    'blockhash',
                    'durableNonce',
                    'outputAmount',
                    'changeAmount',
                    'outputs',
                    'changeOutputs',
                    'fee',
                    'memo',
                ],
                id: 'UNAVAILABLE',
                type: 'Send',
                changeOutputs: [],
                changeAmount: '0',
                outputAmount: '30000',
                outputs: [
                    {
                        address: 'DesU7XscZjng8yj5VX6AZsk3hWSW4sQ3rTG2LuyQ2P4H',
                        amount: '10000',
                    },
                    {
                        address: 'Azz9EmNuhtjoYrhWvidWx1Hfd14SNBsYyzXhA9Tnoca8',
                        amount: '10000',
                    },
                    {
                        address: '2n2xqWM9Z18LqxfJzkNrMMFWiDUFYA2k6WSgSnf6EnJs',
                        amount: '10000',
                    },
                ],
                fee: {
                    fee: 'UNAVAILABLE',
                    feeRate: undefined,
                },
                memo: 'memo text',
                blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
                durableNonce: {
                    authWalletAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
                    walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
                },
            });
        });
        it('should explain signed transfer transaction', async function () {
            const tx = await factory
                .getTransferBuilder()
                .fee({ amount: 5000 })
                .nonce(blockHash)
                .sender(sender)
                .send({ address, amount })
                .build();
            await tx.sign(new lib_1.KeyPair({ prv: testData.authAccount.prv }));
            const explainedTransaction = tx.explainTransaction();
            explainedTransaction.should.deepEqual({
                displayOrder: [
                    'id',
                    'type',
                    'blockhash',
                    'durableNonce',
                    'outputAmount',
                    'changeAmount',
                    'outputs',
                    'changeOutputs',
                    'fee',
                    'memo',
                ],
                id: tx.id,
                type: 'Send',
                changeOutputs: [],
                changeAmount: '0',
                outputAmount: '10000',
                outputs: [
                    {
                        address: 'DesU7XscZjng8yj5VX6AZsk3hWSW4sQ3rTG2LuyQ2P4H',
                        amount: '10000',
                    },
                ],
                fee: {
                    fee: '5000',
                    feeRate: 5000,
                },
                memo: undefined,
                blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
                durableNonce: undefined,
            });
        });
        it('should explain wallet init transaction', async function () {
            const tx = await factory
                .getWalletInitializationBuilder()
                .fee({ amount: 5000 })
                .sender(sender)
                .nonce(blockHash)
                .address(testData.addresses.validAddresses[1])
                .amount(amount)
                .build();
            const explainedTransaction = tx.explainTransaction();
            explainedTransaction.should.deepEqual({
                displayOrder: [
                    'id',
                    'type',
                    'blockhash',
                    'durableNonce',
                    'outputAmount',
                    'changeAmount',
                    'outputs',
                    'changeOutputs',
                    'fee',
                    'memo',
                ],
                id: 'UNAVAILABLE',
                type: 'WalletInitialization',
                changeOutputs: [],
                changeAmount: '0',
                outputAmount: '10000',
                outputs: [
                    {
                        address: 'Azz9EmNuhtjoYrhWvidWx1Hfd14SNBsYyzXhA9Tnoca8',
                        amount: '10000',
                    },
                ],
                fee: {
                    fee: '10000',
                    feeRate: 5000,
                },
                memo: undefined,
                blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
                durableNonce: undefined,
            });
        });
        it('should explain wallet init with durable nonce and memo transaction', async function () {
            const tx = await factory
                .getWalletInitializationBuilder()
                .sender(sender)
                .nonce(blockHash, { walletNonceAddress: testData.nonceAccount.pub, authWalletAddress: sender })
                .memo('memo text')
                .address(testData.addresses.validAddresses[1])
                .amount(amount)
                .build();
            const explainedTransaction = tx.explainTransaction();
            explainedTransaction.should.deepEqual({
                displayOrder: [
                    'id',
                    'type',
                    'blockhash',
                    'durableNonce',
                    'outputAmount',
                    'changeAmount',
                    'outputs',
                    'changeOutputs',
                    'fee',
                    'memo',
                ],
                id: 'UNAVAILABLE',
                type: 'WalletInitialization',
                changeOutputs: [],
                changeAmount: '0',
                outputAmount: '10000',
                outputs: [
                    {
                        address: 'Azz9EmNuhtjoYrhWvidWx1Hfd14SNBsYyzXhA9Tnoca8',
                        amount: '10000',
                    },
                ],
                fee: {
                    fee: 'UNAVAILABLE',
                    feeRate: undefined,
                },
                memo: 'memo text',
                blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
                durableNonce: {
                    authWalletAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
                    walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
                },
            });
        });
        it('should explain signed wallet init transaction', async function () {
            const tx = await factory
                .getWalletInitializationBuilder()
                .fee({ amount: 5000 })
                .sender(sender)
                .nonce(blockHash)
                .address(testData.addresses.validAddresses[1])
                .amount(amount)
                .build();
            await tx.sign(new lib_1.KeyPair({ prv: testData.authAccount.prv }));
            const explainedTransaction = tx.explainTransaction();
            explainedTransaction.should.deepEqual({
                displayOrder: [
                    'id',
                    'type',
                    'blockhash',
                    'durableNonce',
                    'outputAmount',
                    'changeAmount',
                    'outputs',
                    'changeOutputs',
                    'fee',
                    'memo',
                ],
                id: tx.id,
                type: 'WalletInitialization',
                changeOutputs: [],
                changeAmount: '0',
                outputAmount: '10000',
                outputs: [
                    {
                        address: 'Azz9EmNuhtjoYrhWvidWx1Hfd14SNBsYyzXhA9Tnoca8',
                        amount: '10000',
                    },
                ],
                fee: {
                    fee: '10000',
                    feeRate: 5000,
                },
                memo: undefined,
                blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
                durableNonce: undefined,
            });
        });
        it('should explain create ATA transaction', async function () {
            const tx = await factory
                .getAtaInitializationBuilder()
                .fee({ amount: 5000 })
                .sender(sender)
                .nonce(blockHash)
                .mint('tsol:usdc')
                .rentExemptAmount(amount)
                .build();
            const explainedTransaction = tx.explainTransaction();
            explainedTransaction.should.deepEqual({
                displayOrder: [
                    'id',
                    'type',
                    'blockhash',
                    'durableNonce',
                    'outputAmount',
                    'changeAmount',
                    'outputs',
                    'changeOutputs',
                    'fee',
                    'memo',
                ],
                id: 'UNAVAILABLE',
                type: 'AssociatedTokenAccountInitialization',
                changeOutputs: [],
                changeAmount: '0',
                outputAmount: '0',
                outputs: [],
                fee: {
                    fee: '15000',
                    feeRate: 5000,
                },
                memo: undefined,
                blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
                durableNonce: undefined,
            });
        });
        it('should activate builder ', async function () {
            const tx = await factory
                .getStakingActivateBuilder()
                .stakingAddress(stakeAccount.pub)
                .sender(wallet.pub)
                .nonce(blockHash)
                .amount(amount)
                .validator(validator.pub)
                .fee({ amount: 5000 })
                .build();
            const explainedTransaction = tx.explainTransaction();
            explainedTransaction.should.deepEqual({
                displayOrder: [
                    'id',
                    'type',
                    'blockhash',
                    'durableNonce',
                    'outputAmount',
                    'changeAmount',
                    'outputs',
                    'changeOutputs',
                    'fee',
                    'memo',
                ],
                id: 'UNAVAILABLE',
                type: 'StakingActivate',
                changeOutputs: [],
                changeAmount: '0',
                outputAmount: '10000',
                outputs: [
                    {
                        address: '7dRuGFbU2y2kijP6o1LYNzVyz4yf13MooqoionCzv5Za',
                        amount: '10000',
                    },
                ],
                fee: {
                    fee: '10000',
                    feeRate: 5000,
                },
                memo: undefined,
                blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
                durableNonce: undefined,
            });
        });
        it('should deactivate builder ', async function () {
            const recentBlockHash = 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi';
            const tx = await factory
                .getStakingDeactivateBuilder()
                .stakingAddress(stakeAccount.pub)
                .sender(wallet.pub)
                .stakingAddress(stakeAccount.pub)
                .nonce(recentBlockHash)
                .fee({ amount: 5000 })
                .build();
            const explainedTransaction = tx.explainTransaction();
            explainedTransaction.should.deepEqual({
                displayOrder: [
                    'id',
                    'type',
                    'blockhash',
                    'durableNonce',
                    'outputAmount',
                    'changeAmount',
                    'outputs',
                    'changeOutputs',
                    'fee',
                    'memo',
                ],
                id: 'UNAVAILABLE',
                type: 'StakingDeactivate',
                changeOutputs: [],
                changeAmount: '0',
                outputAmount: '0',
                outputs: [],
                fee: {
                    fee: '5000',
                    feeRate: 5000,
                },
                memo: undefined,
                blockhash: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
                durableNonce: undefined,
            });
        });
        it('should explain withdraw transaction ', async function () {
            const recentBlockHash = 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi';
            const tx = await factory
                .getStakingWithdrawBuilder()
                .stakingAddress(stakeAccount.pub)
                .sender(wallet.pub)
                .amount(amount)
                .nonce(recentBlockHash)
                .fee({ amount: 5000 })
                .build();
            const explainedTransaction = tx.explainTransaction();
            explainedTransaction.should.deepEqual({
                displayOrder: [
                    'id',
                    'type',
                    'blockhash',
                    'durableNonce',
                    'outputAmount',
                    'changeAmount',
                    'outputs',
                    'changeOutputs',
                    'fee',
                    'memo',
                ],
                id: 'UNAVAILABLE',
                type: 'StakingWithdraw',
                changeOutputs: [],
                changeAmount: '0',
                outputAmount: '10000',
                outputs: [
                    {
                        address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
                        amount: '10000',
                    },
                ],
                fee: {
                    fee: '5000',
                    feeRate: 5000,
                },
                memo: undefined,
                blockhash: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
                durableNonce: undefined,
            });
        });
        it('should explain withdraw transaction with memo and durable nonce ', async function () {
            const tx = await factory
                .getStakingWithdrawBuilder()
                .stakingAddress(stakeAccount.pub)
                .sender(wallet.pub)
                .amount(amount)
                .nonce(blockHash, { walletNonceAddress: testData.nonceAccount.pub, authWalletAddress: sender })
                .memo('memo text')
                .fee({ amount: 5000 })
                .build();
            tx.signablePayload;
            const explainedTransaction = tx.explainTransaction();
            explainedTransaction.should.deepEqual({
                displayOrder: [
                    'id',
                    'type',
                    'blockhash',
                    'durableNonce',
                    'outputAmount',
                    'changeAmount',
                    'outputs',
                    'changeOutputs',
                    'fee',
                    'memo',
                ],
                id: 'UNAVAILABLE',
                type: 'StakingWithdraw',
                changeOutputs: [],
                changeAmount: '0',
                outputAmount: '10000',
                outputs: [
                    {
                        address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
                        amount: '10000',
                    },
                ],
                fee: {
                    fee: '5000',
                    feeRate: 5000,
                },
                memo: 'memo text',
                blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
                durableNonce: {
                    walletNonceAddress: testData.nonceAccount.pub,
                    authWalletAddress: sender,
                },
            });
        });
        it('should explain single token transfer transaction', async function () {
            const tx = await factory
                .getTokenTransferBuilder()
                .nonce(blockHash)
                .sender(sender)
                .send({ address, amount, tokenName: 'tsol:usdc' })
                .fee({ amount: 5000 })
                .build();
            const explainedTransaction = tx.explainTransaction();
            explainedTransaction.should.deepEqual({
                displayOrder: [
                    'id',
                    'type',
                    'blockhash',
                    'durableNonce',
                    'outputAmount',
                    'changeAmount',
                    'outputs',
                    'changeOutputs',
                    'fee',
                    'memo',
                ],
                id: 'UNAVAILABLE',
                type: 'Send',
                changeOutputs: [],
                changeAmount: '0',
                outputAmount: '0',
                outputs: [
                    {
                        address: 'DesU7XscZjng8yj5VX6AZsk3hWSW4sQ3rTG2LuyQ2P4H',
                        amount: '10000',
                        tokenName: 'tsol:usdc',
                    },
                ],
                fee: {
                    fee: '5000',
                    feeRate: 5000,
                },
                memo: undefined,
                blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
                durableNonce: undefined,
            });
        });
        it('should explain multi token transfer with durable nonce and memo transaction', async function () {
            const tx = await factory
                .getTokenTransferBuilder()
                .nonce(blockHash, { walletNonceAddress: testData.nonceAccount.pub, authWalletAddress: sender })
                .sender(sender)
                .memo('memo text')
                .send({ address, amount, tokenName: 'tsol:usdc' })
                .send({ address: testData.addresses.validAddresses[1], amount, tokenName: 'tsol:usdc' })
                .send({ address: testData.addresses.validAddresses[2], amount, tokenName: 'tsol:usdc' })
                .build();
            const explainedTransaction = tx.explainTransaction();
            explainedTransaction.should.deepEqual({
                displayOrder: [
                    'id',
                    'type',
                    'blockhash',
                    'durableNonce',
                    'outputAmount',
                    'changeAmount',
                    'outputs',
                    'changeOutputs',
                    'fee',
                    'memo',
                ],
                id: 'UNAVAILABLE',
                type: 'Send',
                changeOutputs: [],
                changeAmount: '0',
                outputAmount: '0',
                outputs: [
                    {
                        address: 'DesU7XscZjng8yj5VX6AZsk3hWSW4sQ3rTG2LuyQ2P4H',
                        amount: '10000',
                        tokenName: 'tsol:usdc',
                    },
                    {
                        address: 'Azz9EmNuhtjoYrhWvidWx1Hfd14SNBsYyzXhA9Tnoca8',
                        amount: '10000',
                        tokenName: 'tsol:usdc',
                    },
                    {
                        address: '2n2xqWM9Z18LqxfJzkNrMMFWiDUFYA2k6WSgSnf6EnJs',
                        amount: '10000',
                        tokenName: 'tsol:usdc',
                    },
                ],
                fee: {
                    fee: 'UNAVAILABLE',
                    feeRate: undefined,
                },
                memo: 'memo text',
                blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
                durableNonce: {
                    authWalletAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
                    walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
                },
            });
        });
    });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L3VuaXQvdHJhbnNhY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsb0RBQTRCO0FBQzVCLDRDQUF1QztBQUN2Qyx1Q0FBcUQ7QUFDckQsMkRBQTZDO0FBQzdDLDZDQUEyRTtBQUMzRSwyREFBd0Q7QUFFeEQsUUFBUSxDQUFDLGlCQUFpQixFQUFFLEdBQUcsRUFBRTtJQUMvQixNQUFNLElBQUksR0FBRyxlQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRS9CLFFBQVEsQ0FBQyxlQUFlLEVBQUUsR0FBRyxFQUFFO1FBQzdCLEVBQUUsQ0FBQyx5QkFBeUIsRUFBRSxHQUFHLEVBQUU7WUFDakMsTUFBTSxFQUFFLEdBQUcsSUFBSSxpQkFBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2pDLGdCQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1lBQ3RELGdCQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLG1CQUFtQixDQUFDLENBQUM7UUFDbkUsQ0FBQyxDQUFDLENBQUM7UUFDSCxFQUFFLENBQUMsOEJBQThCLEVBQUUsR0FBRyxFQUFFO1lBQ3RDLE1BQU0sRUFBRSxHQUFHLElBQUksaUJBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNqQyxJQUFBLGdCQUFNLEVBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsVUFBVSxDQUFDLG1CQUFtQixDQUFDLENBQUM7WUFDMUQsRUFBRSxDQUFDLGNBQWMsR0FBRyxJQUFJLHFCQUFjLEVBQUUsQ0FBQztZQUN6QyxF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O1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0IHsgY29pbnMgfSBmcm9tICdAYml0Z28vc3RhdGljcyc7XG5pbXBvcnQgeyBLZXlQYWlyLCBUcmFuc2FjdGlvbiB9IGZyb20gJy4uLy4uL3NyYy9saWInO1xuaW1wb3J0ICogYXMgdGVzdERhdGEgZnJvbSAnLi4vcmVzb3VyY2VzL3NvbCc7XG5pbXBvcnQgeyBQdWJsaWNLZXksIFRyYW5zYWN0aW9uIGFzIFNvbFRyYW5zYWN0aW9uIH0gZnJvbSAnQHNvbGFuYS93ZWIzLmpzJztcbmltcG9ydCB7IGdldEJ1aWxkZXJGYWN0b3J5IH0gZnJvbSAnLi9nZXRCdWlsZGVyRmFjdG9yeSc7XG5cbmRlc2NyaWJlKCdTb2wgVHJhbnNhY3Rpb24nLCAoKSA9PiB7XG4gIGNvbnN0IGNvaW4gPSBjb2lucy5nZXQoJ3Rzb2wnKTtcblxuICBkZXNjcmliZSgndG9Kc29uIHNob3VsZCcsICgpID0+IHtcbiAgICBpdCgndGhyb3cgZW1wdHkgdHJhbnNhY3Rpb24nLCAoKSA9PiB7XG4gICAgICBjb25zdCB0eCA9IG5ldyBUcmFuc2FjdGlvbihjb2luKTtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdHgudG9Kc29uKCksIC9FbXB0eSB0cmFuc2FjdGlvbi8pO1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpLCAvRW1wdHkgdHJhbnNhY3Rpb24vKTtcbiAgICB9KTtcbiAgICBpdCgndGhyb3cgZm9yIHRvSnNvbiBvZiBlbXB0eSB0eCcsICgpID0+IHtcbiAgICAgIGNvbnN0IHR4ID0gbmV3IFRyYW5zYWN0aW9uKGNvaW4pO1xuICAgICAgc2hvdWxkKCgpID0+IHR4LnRvSnNvbigpKS50aHJvd0Vycm9yKCdFbXB0eSB0cmFuc2FjdGlvbicpO1xuICAgICAgdHguc29sVHJhbnNhY3Rpb24gPSBuZXcgU29sVHJhbnNhY3Rpb24oKTtcbiAgICAgIHR4LnNvbFRyYW5zYWN0aW9uLnJlY2VudEJsb2NraGFzaCA9IHRlc3REYXRhLmJsb2NrSGFzaGVzLnZhbGlkQmxvY2tIYXNoZXNbMF07XG4gICAgICBzaG91bGQoKCkgPT4gdHgudG9Kc29uKCkpLnRocm93RXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb24sIHRyYW5zYWN0aW9uIHR5cGUgbm90IHN1cHBvcnRlZDogdW5kZWZpbmVkJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc3VjY2VlZCBmb3IgYSB1bnNpZ25lZCB0cmFuc2ZlciB0eCcsICgpID0+IHtcbiAgICAgIGNvbnN0IHR4ID0gbmV3IFRyYW5zYWN0aW9uKGNvaW4pO1xuICAgICAgdHguZnJvbVJhd1RyYW5zYWN0aW9uKHRlc3REYXRhLlRSQU5TRkVSX1VOU0lHTkVEX1RYX1dJVEhfTUVNT19BTkRfRFVSQUJMRV9OT05DRSk7XG4gICAgICB0eC5zaWduYXR1cmUuc2hvdWxkLmJlLmVtcHR5KCk7XG4gICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgIHR4SnNvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0aWVzKFsnaWQnLCAnZmVlUGF5ZXInLCAnbm9uY2UnLCAnbnVtU2lnbmF0dXJlcycsICdpbnN0cnVjdGlvbnNEYXRhJ10pO1xuICAgICAgdHhKc29uLmlkPy5zaG91bGQuZXF1YWwodW5kZWZpbmVkKTtcbiAgICAgIHR4SnNvbi5mZWVQYXllcj8uc2hvdWxkLmVxdWFsKCc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScpO1xuICAgICAgdHhKc29uLm5vbmNlLnNob3VsZC5lcXVhbCgnR0h0WFFCc29aSFZuTkZhOVlldkF6RnIxN0RKamdIWGszeWNUS0Q1eEQzWmknKTtcbiAgICAgIHR4SnNvbi5udW1TaWduYXR1cmVzLnNob3VsZC5lcXVhbCgwKTtcbiAgICAgIHR4SnNvbi5pbnN0cnVjdGlvbnNEYXRhLmxlbmd0aC5zaG91bGQuZXF1YWwoMyk7XG4gICAgICB0eEpzb24ubGFtcG9ydHNQZXJTaWduYXR1cmU/LnNob3VsZC5iZS51bmRlZmluZWQoKTtcbiAgICAgIHR4SnNvbi5pbnN0cnVjdGlvbnNEYXRhLnNob3VsZC5kZWVwRXF1YWwoW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ05vbmNlQWR2YW5jZScsXG4gICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICB3YWxsZXROb25jZUFkZHJlc3M6ICc4WTdSTTZKZmNYNEFTU05Ca3Jrcm1TYlJ1NDMxWVZpOVkzb0xGbnpDMmRDaCcsXG4gICAgICAgICAgICBhdXRoV2FsbGV0QWRkcmVzczogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ1RyYW5zZmVyJyxcbiAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgIGZyb21BZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICAgICAgdG9BZGRyZXNzOiAnQ1A1RHBhYTQyUnRKbU11S3FDUXNMd21hNVloM2tudXZLc1lERlg4NUY0MVMnLFxuICAgICAgICAgICAgYW1vdW50OiAnMzAwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ01lbW8nLFxuICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgbWVtbzogJ3Rlc3QgbWVtbycsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIF0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3N1Y2NlZWQgZm9yIGEgbXVsdGkgdHJhbnNmZXIgdHgnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0eCA9IG5ldyBUcmFuc2FjdGlvbihjb2luKTtcbiAgICAgIHR4LmZyb21SYXdUcmFuc2FjdGlvbih0ZXN0RGF0YS5NVUxUSV9UUkFOU0ZFUl9TSUdORUQpO1xuICAgICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG4gICAgICB0eEpzb24uc2hvdWxkLmhhdmUucHJvcGVydGllcyhbJ2lkJywgJ2ZlZVBheWVyJywgJ25vbmNlJywgJ251bVNpZ25hdHVyZXMnLCAnaW5zdHJ1Y3Rpb25zRGF0YSddKTtcbiAgICAgIHR4SnNvbi5pZD8uc2hvdWxkLmVxdWFsKFxuICAgICAgICAnVFBWY2MxOENZeFBuTTNlUmdRaGRiNlY2WkxhMzREdjNkVTdNdHZLUHV5NVpQS0xNMXVaUEZGRW1GMm0xODRQVFdLUloxVXE2TktGWld3cjJrcktrNjNmJ1xuICAgICAgKTtcbiAgICAgIHR4LnNpZ25hdHVyZS5zaG91bGQuZGVlcEVxdWFsKFtcbiAgICAgICAgJ1RQVmNjMThDWXhQbk0zZVJnUWhkYjZWNlpMYTM0RHYzZFU3TXR2S1B1eTVaUEtMTTF1WlBGRkVtRjJtMTg0UFRXS1JaMVVxNk5LRlpXd3Iya3JLazYzZicsXG4gICAgICBdKTtcbiAgICAgIHR4SnNvbi5mZWVQYXllcj8uc2hvdWxkLmVxdWFsKCc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScpO1xuICAgICAgdHhKc29uLm5vbmNlLnNob3VsZC5lcXVhbCgnR0h0WFFCc29aSFZuTkZhOVlldkF6RnIxN0RKamdIWGszeWNUS0Q1eEQzWmknKTtcbiAgICAgIHR4SnNvbi5udW1TaWduYXR1cmVzLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIHR4SnNvbi5sYW1wb3J0c1BlclNpZ25hdHVyZT8uc2hvdWxkLmJlLnVuZGVmaW5lZCgpO1xuICAgICAgdHhKc29uLmluc3RydWN0aW9uc0RhdGEubGVuZ3RoLnNob3VsZC5lcXVhbCg4KTtcbiAgICAgIHR4SnNvbi5pbnN0cnVjdGlvbnNEYXRhLnNob3VsZC5kZWVwRXF1YWwoW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ05vbmNlQWR2YW5jZScsXG4gICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICB3YWxsZXROb25jZUFkZHJlc3M6ICc4WTdSTTZKZmNYNEFTU05Ca3Jrcm1TYlJ1NDMxWVZpOVkzb0xGbnpDMmRDaCcsXG4gICAgICAgICAgICBhdXRoV2FsbGV0QWRkcmVzczogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ1RyYW5zZmVyJyxcbiAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgIGZyb21BZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICAgICAgdG9BZGRyZXNzOiAnQ1A1RHBhYTQyUnRKbU11S3FDUXNMd21hNVloM2tudXZLc1lERlg4NUY0MVMnLFxuICAgICAgICAgICAgYW1vdW50OiAnMzAwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ1RyYW5zZmVyJyxcbiAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgIGZyb21BZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICAgICAgdG9BZGRyZXNzOiAnNkI1NVhNaWFTNnRVWnc1VHQzRzFSYVhBcWRydk4zOHlYVkRKbVd2S0xraU0nLFxuICAgICAgICAgICAgYW1vdW50OiAnMzAwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ1RyYW5zZmVyJyxcbiAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgIGZyb21BZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICAgICAgdG9BZGRyZXNzOiAnQzFVanB4Y1hOQnBwMVV5dllzdU5CTlo1RGExRzFpNDlnM3lUdkMyM055N2UnLFxuICAgICAgICAgICAgYW1vdW50OiAnMzAwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ1RyYW5zZmVyJyxcbiAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgIGZyb21BZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICAgICAgdG9BZGRyZXNzOiAnQ3BVWVhoOXhYb1dma0JWYUJRUlo4bkFnRGJUMTZHWmVRZHF2ZWVCUzFobWsnLFxuICAgICAgICAgICAgYW1vdW50OiAnMzAwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ1RyYW5zZmVyJyxcbiAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgIGZyb21BZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICAgICAgdG9BZGRyZXNzOiAnNjRzNk5qbUVva2RoaWNIRWQ0MzJYNVV0MkVEZkRtVnFkdkdoNHJBU24xZ2QnLFxuICAgICAgICAgICAgYW1vdW50OiAnMzAwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ1RyYW5zZmVyJyxcbiAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgIGZyb21BZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICAgICAgdG9BZGRyZXNzOiAnNm5YeEwyak1TZGtnZkhtMTNUd3ZuMWd6UkFQZHJXbldMZnU4OVBKTDNBcWUnLFxuICAgICAgICAgICAgYW1vdW50OiAnMzAwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ01lbW8nLFxuICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgbWVtbzogJ3Rlc3QgbWVtbycsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIF0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnc2lnbiBzaG91bGQnLCAoKSA9PiB7XG4gICAgaXQoJ2ZhaWwgaWYgdGhlIHR4IGRvZXNudCBoYXZlIG5vbmNlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHggPSBuZXcgVHJhbnNhY3Rpb24oY29pbik7XG4gICAgICB0eC5zb2xUcmFuc2FjdGlvbiA9IG5ldyBTb2xUcmFuc2FjdGlvbigpO1xuICAgICAgdHguc29sVHJhbnNhY3Rpb24uZmVlUGF5ZXIgPSBuZXcgUHVibGljS2V5KHRlc3REYXRhLmF1dGhBY2NvdW50LnB1Yik7XG4gICAgICBjb25zdCBrcCA9IG5ldyBLZXlQYWlyKHsgcHJ2OiB0ZXN0RGF0YS5wcnZLZXlzLnBydktleTEuYmFzZTU4IH0pO1xuICAgICAgYXdhaXQgdHguc2lnbihrcCkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnTm9uY2UgaXMgcmVxdWlyZWQgYmVmb3JlIHNpZ25pbmcnKTtcbiAgICB9KTtcblxuICAgIGl0KCdmYWlsIGlmIHRoZSB0eCBkb2VzbnQgaGF2ZSBmZWVQYXllcicsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHR4ID0gbmV3IFRyYW5zYWN0aW9uKGNvaW4pO1xuICAgICAgY29uc3Qga3AgPSBuZXcgS2V5UGFpcih7IHBydjogdGVzdERhdGEucHJ2S2V5cy5wcnZLZXkxLmJhc2U1OCB9KTtcbiAgICAgIHR4LnNvbFRyYW5zYWN0aW9uID0gbmV3IFNvbFRyYW5zYWN0aW9uKCk7XG4gICAgICB0eC5zb2xUcmFuc2FjdGlvbi5yZWNlbnRCbG9ja2hhc2ggPSB0ZXN0RGF0YS5ibG9ja0hhc2hlcy52YWxpZEJsb2NrSGFzaGVzWzBdO1xuICAgICAgYXdhaXQgdHguc2lnbihrcCkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnZmVlUGF5ZXIgaXMgcmVxdWlyZWQgYmVmb3JlIHNpZ25pbmcnKTtcbiAgICB9KTtcblxuICAgIGl0KCdmYWlsIGlmIHRoZSBLZXlQYWlyIGlzIG5vdCB0aGUgcmlnaHQgb25lJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHggPSBuZXcgVHJhbnNhY3Rpb24oY29pbik7XG4gICAgICB0eC5mcm9tUmF3VHJhbnNhY3Rpb24odGVzdERhdGEuUkFXX1RYX1VOU0lHTkVEKTtcbiAgICAgIGNvbnN0IGtleXBhaXIgPSBuZXcgS2V5UGFpcih7IHBydjogdGVzdERhdGEucHJ2S2V5cy5wcnZLZXkxLmJhc2U1OCB9KTtcbiAgICAgIGF3YWl0IHR4LnNpZ24oa2V5cGFpcikuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgndW5rbm93biBzaWduZXI6IENQNURwYWE0MlJ0Sm1NdUtxQ1FzTHdtYTVZaDNrbnV2S3NZREZYODVGNDFTJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnZmFpbCBpZiB0aGUgS2V5UGFpciBkb2VzbnQgaGF2ZSBhIHBydiBrZXknLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0eCA9IG5ldyBUcmFuc2FjdGlvbihjb2luKTtcbiAgICAgIHR4LmZyb21SYXdUcmFuc2FjdGlvbih0ZXN0RGF0YS5SQVdfVFhfVU5TSUdORUQpO1xuICAgICAgY29uc3Qga2V5cGFpciA9IG5ldyBLZXlQYWlyKHsgcHViOiB0ZXN0RGF0YS5wdWJLZXlzLnZhbGlkUHViS2V5c1swXSB9KTtcbiAgICAgIGF3YWl0IHR4LnNpZ24oa2V5cGFpcikuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnTWlzc2luZyBwcml2YXRlIGtleScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3N1Y2NlZWQgdG8gc2lnbiB3aXRoIDEgS2V5UGFpcicsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHR4ID0gbmV3IFRyYW5zYWN0aW9uKGNvaW4pO1xuICAgICAgdHguZnJvbVJhd1RyYW5zYWN0aW9uKHRlc3REYXRhLlJBV19UWF9VTlNJR05FRCk7XG4gICAgICBjb25zdCBrZXlwYWlyID0gbmV3IEtleVBhaXIoeyBwcnY6IHRlc3REYXRhLmFjY291bnRXaXRoU2VlZC5wcml2YXRlS2V5LmJhc2U1OCB9KTtcbiAgICAgIGF3YWl0IHR4LnNpZ24oa2V5cGFpcikuc2hvdWxkLmJlLmZ1bGZpbGxlZCgpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCksIHRlc3REYXRhLlJBV19UWF9TSUdORUQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3N1Y2NlZWQgd2hlbiB0cnkgdG8gc2lnbiB3aXRoIHRoZSBzYW1lIGtleVBhaXIgbXVsdGlwbGUgdGltZXMgJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHggPSBuZXcgVHJhbnNhY3Rpb24oY29pbik7XG4gICAgICB0eC5mcm9tUmF3VHJhbnNhY3Rpb24odGVzdERhdGEuUkFXX1RYX1VOU0lHTkVEKTtcbiAgICAgIGNvbnN0IGtleXBhaXIgPSBuZXcgS2V5UGFpcih7IHBydjogdGVzdERhdGEuYWNjb3VudFdpdGhTZWVkLnByaXZhdGVLZXkuYmFzZTU4IH0pO1xuICAgICAgYXdhaXQgdHguc2lnbihba2V5cGFpciwga2V5cGFpciwga2V5cGFpciwga2V5cGFpcl0pLnNob3VsZC5iZS5mdWxmaWxsZWQoKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eC50b0Jyb2FkY2FzdEZvcm1hdCgpLCB0ZXN0RGF0YS5SQVdfVFhfU0lHTkVEKTtcbiAgICB9KTtcblxuICAgIGl0KCdzdWNjZWVkIHdoZW4gdHJ5IHRvIHNpZ24gd2l0aCBhIGtleVBhaXIgdGhhdCBhbHJlYWR5IHNpZ25lZCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHR4ID0gbmV3IFRyYW5zYWN0aW9uKGNvaW4pO1xuICAgICAgdHguZnJvbVJhd1RyYW5zYWN0aW9uKHRlc3REYXRhLlJBV19UWF9TSUdORUQpO1xuICAgICAgY29uc3Qga2V5cGFpciA9IG5ldyBLZXlQYWlyKHsgcHJ2OiB0ZXN0RGF0YS5hY2NvdW50V2l0aFNlZWQucHJpdmF0ZUtleS5iYXNlNTggfSk7XG4gICAgICBhd2FpdCB0eC5zaWduKGtleXBhaXIpLnNob3VsZC5iZS5mdWxmaWxsZWQoKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eC50b0Jyb2FkY2FzdEZvcm1hdCgpLCB0ZXN0RGF0YS5SQVdfVFhfU0lHTkVEKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3RyYW5zYWN0aW9uIHBhcnNpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ2Zyb21SYXdUcmFuc2FjdGlvbiBhbmQgdG9Ccm9hZGNhc3RGb3JtYXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IG5ldyBUcmFuc2FjdGlvbihjb2luKTtcbiAgICAgIHR4LmZyb21SYXdUcmFuc2FjdGlvbih0ZXN0RGF0YS5SQVdfVFhfVU5TSUdORUQpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCksIHRlc3REYXRhLlJBV19UWF9VTlNJR05FRCk7XG4gICAgfSk7XG5cbiAgICBpdCgnZnJvbVJhd1RyYW5zYWN0aW9uLCBzaWduIGFuZCB0b0Jyb2FkY2FzdEZvcm1hdCAnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IG5ldyBUcmFuc2FjdGlvbihjb2luKTtcbiAgICAgIHR4LmZyb21SYXdUcmFuc2FjdGlvbih0ZXN0RGF0YS5SQVdfVFhfVU5TSUdORUQpO1xuICAgICAgY29uc3Qga2V5cGFpciA9IG5ldyBLZXlQYWlyKHsgcHJ2OiB0ZXN0RGF0YS5hY2NvdW50V2l0aFNlZWQucHJpdmF0ZUtleS5iYXNlNTggfSk7XG4gICAgICBhd2FpdCB0eC5zaWduKGtleXBhaXIpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCksIHRlc3REYXRhLlJBV19UWF9TSUdORUQpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZXhwbGFpbiB0cmFuc2FjdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBmYWN0b3J5ID0gZ2V0QnVpbGRlckZhY3RvcnkoJ3Rzb2wnKTtcbiAgICBjb25zdCBibG9ja0hhc2ggPSB0ZXN0RGF0YS5ibG9ja0hhc2hlcy52YWxpZEJsb2NrSGFzaGVzWzBdO1xuICAgIGNvbnN0IHNlbmRlciA9IHRlc3REYXRhLmF1dGhBY2NvdW50LnB1YjtcbiAgICBjb25zdCBhZGRyZXNzID0gdGVzdERhdGEuYWRkcmVzc2VzLnZhbGlkQWRkcmVzc2VzWzBdO1xuICAgIGNvbnN0IGFtb3VudCA9ICcxMDAwMCc7XG4gICAgY29uc3Qgd2FsbGV0ID0gbmV3IEtleVBhaXIodGVzdERhdGEuYXV0aEFjY291bnQpLmdldEtleXMoKTtcbiAgICBjb25zdCBzdGFrZUFjY291bnQgPSBuZXcgS2V5UGFpcih0ZXN0RGF0YS5zdGFrZUFjY291bnQpLmdldEtleXMoKTtcbiAgICBjb25zdCB2YWxpZGF0b3IgPSB0ZXN0RGF0YS52YWxpZGF0b3I7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gc2luZ2xlIHRyYW5zZmVyIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHggPSBhd2FpdCBmYWN0b3J5XG4gICAgICAgIC5nZXRUcmFuc2ZlckJ1aWxkZXIoKVxuICAgICAgICAubm9uY2UoYmxvY2tIYXNoKVxuICAgICAgICAuc2VuZGVyKHNlbmRlcilcbiAgICAgICAgLnNlbmQoeyBhZGRyZXNzLCBhbW91bnQgfSlcbiAgICAgICAgLmZlZSh7IGFtb3VudDogNTAwMCB9KVxuICAgICAgICAuYnVpbGQoKTtcblxuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSB0eC5leHBsYWluVHJhbnNhY3Rpb24oKTtcbiAgICAgIGV4cGxhaW5lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBkaXNwbGF5T3JkZXI6IFtcbiAgICAgICAgICAnaWQnLFxuICAgICAgICAgICd0eXBlJyxcbiAgICAgICAgICAnYmxvY2toYXNoJyxcbiAgICAgICAgICAnZHVyYWJsZU5vbmNlJyxcbiAgICAgICAgICAnb3V0cHV0QW1vdW50JyxcbiAgICAgICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICAgICAnb3V0cHV0cycsXG4gICAgICAgICAgJ2NoYW5nZU91dHB1dHMnLFxuICAgICAgICAgICdmZWUnLFxuICAgICAgICAgICdtZW1vJyxcbiAgICAgICAgXSxcbiAgICAgICAgaWQ6ICdVTkFWQUlMQUJMRScsXG4gICAgICAgIHR5cGU6ICdTZW5kJyxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRBbW91bnQ6ICcxMDAwMCcsXG4gICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnRGVzVTdYc2Naam5nOHlqNVZYNkFac2szaFdTVzRzUTNyVEcyTHV5UTJQNEgnLFxuICAgICAgICAgICAgYW1vdW50OiAnMTAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGZlZToge1xuICAgICAgICAgIGZlZTogJzUwMDAnLFxuICAgICAgICAgIGZlZVJhdGU6IDUwMDAsXG4gICAgICAgIH0sXG4gICAgICAgIG1lbW86IHVuZGVmaW5lZCxcbiAgICAgICAgYmxvY2toYXNoOiAnNW5lN3BoQTQ4SnJ2cG4zOUF0dXBCOFprQ0NBeThnTFRmcEdpaFpQdURxZW4nLFxuICAgICAgICBkdXJhYmxlTm9uY2U6IHVuZGVmaW5lZCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIHNpbmdsZSB0cmFuc2ZlciB3aXRoIGR1cmFibGUgbm9uY2UgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IGZhY3RvcnlcbiAgICAgICAgLmdldFRyYW5zZmVyQnVpbGRlcigpXG4gICAgICAgIC5ub25jZShibG9ja0hhc2gsIHsgd2FsbGV0Tm9uY2VBZGRyZXNzOiB0ZXN0RGF0YS5ub25jZUFjY291bnQucHViLCBhdXRoV2FsbGV0QWRkcmVzczogc2VuZGVyIH0pXG4gICAgICAgIC5zZW5kZXIoc2VuZGVyKVxuICAgICAgICAuc2VuZCh7IGFkZHJlc3MsIGFtb3VudCB9KVxuICAgICAgICAuYnVpbGQoKTtcblxuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSB0eC5leHBsYWluVHJhbnNhY3Rpb24oKTtcbiAgICAgIGV4cGxhaW5lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBkaXNwbGF5T3JkZXI6IFtcbiAgICAgICAgICAnaWQnLFxuICAgICAgICAgICd0eXBlJyxcbiAgICAgICAgICAnYmxvY2toYXNoJyxcbiAgICAgICAgICAnZHVyYWJsZU5vbmNlJyxcbiAgICAgICAgICAnb3V0cHV0QW1vdW50JyxcbiAgICAgICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICAgICAnb3V0cHV0cycsXG4gICAgICAgICAgJ2NoYW5nZU91dHB1dHMnLFxuICAgICAgICAgICdmZWUnLFxuICAgICAgICAgICdtZW1vJyxcbiAgICAgICAgXSxcbiAgICAgICAgaWQ6ICdVTkFWQUlMQUJMRScsXG4gICAgICAgIHR5cGU6ICdTZW5kJyxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRBbW91bnQ6ICcxMDAwMCcsXG4gICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnRGVzVTdYc2Naam5nOHlqNVZYNkFac2szaFdTVzRzUTNyVEcyTHV5UTJQNEgnLFxuICAgICAgICAgICAgYW1vdW50OiAnMTAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGZlZToge1xuICAgICAgICAgIGZlZTogJ1VOQVZBSUxBQkxFJyxcbiAgICAgICAgICBmZWVSYXRlOiB1bmRlZmluZWQsXG4gICAgICAgIH0sXG4gICAgICAgIG1lbW86IHVuZGVmaW5lZCxcbiAgICAgICAgYmxvY2toYXNoOiAnNW5lN3BoQTQ4SnJ2cG4zOUF0dXBCOFprQ0NBeThnTFRmcEdpaFpQdURxZW4nLFxuICAgICAgICBkdXJhYmxlTm9uY2U6IHtcbiAgICAgICAgICBhdXRoV2FsbGV0QWRkcmVzczogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgICB3YWxsZXROb25jZUFkZHJlc3M6ICc4WTdSTTZKZmNYNEFTU05Ca3Jrcm1TYlJ1NDMxWVZpOVkzb0xGbnpDMmRDaCcsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBtdWx0aSB0cmFuc2ZlciB3aXRoIGR1cmFibGUgbm9uY2UgYW5kIG1lbW8gdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IGZhY3RvcnlcbiAgICAgICAgLmdldFRyYW5zZmVyQnVpbGRlcigpXG4gICAgICAgIC5ub25jZShibG9ja0hhc2gsIHsgd2FsbGV0Tm9uY2VBZGRyZXNzOiB0ZXN0RGF0YS5ub25jZUFjY291bnQucHViLCBhdXRoV2FsbGV0QWRkcmVzczogc2VuZGVyIH0pXG4gICAgICAgIC5zZW5kZXIoc2VuZGVyKVxuICAgICAgICAubWVtbygnbWVtbyB0ZXh0JylcbiAgICAgICAgLnNlbmQoeyBhZGRyZXNzLCBhbW91bnQgfSlcbiAgICAgICAgLnNlbmQoeyBhZGRyZXNzOiB0ZXN0RGF0YS5hZGRyZXNzZXMudmFsaWRBZGRyZXNzZXNbMV0sIGFtb3VudCB9KVxuICAgICAgICAuc2VuZCh7IGFkZHJlc3M6IHRlc3REYXRhLmFkZHJlc3Nlcy52YWxpZEFkZHJlc3Nlc1syXSwgYW1vdW50IH0pXG4gICAgICAgIC5idWlsZCgpO1xuXG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IHR4LmV4cGxhaW5UcmFuc2FjdGlvbigpO1xuICAgICAgZXhwbGFpbmVkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGRpc3BsYXlPcmRlcjogW1xuICAgICAgICAgICdpZCcsXG4gICAgICAgICAgJ3R5cGUnLFxuICAgICAgICAgICdibG9ja2hhc2gnLFxuICAgICAgICAgICdkdXJhYmxlTm9uY2UnLFxuICAgICAgICAgICdvdXRwdXRBbW91bnQnLFxuICAgICAgICAgICdjaGFuZ2VBbW91bnQnLFxuICAgICAgICAgICdvdXRwdXRzJyxcbiAgICAgICAgICAnY2hhbmdlT3V0cHV0cycsXG4gICAgICAgICAgJ2ZlZScsXG4gICAgICAgICAgJ21lbW8nLFxuICAgICAgICBdLFxuICAgICAgICBpZDogJ1VOQVZBSUxBQkxFJyxcbiAgICAgICAgdHlwZTogJ1NlbmQnLFxuICAgICAgICBjaGFuZ2VPdXRwdXRzOiBbXSxcbiAgICAgICAgY2hhbmdlQW1vdW50OiAnMCcsXG4gICAgICAgIG91dHB1dEFtb3VudDogJzMwMDAwJyxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICdEZXNVN1hzY1pqbmc4eWo1Vlg2QVpzazNoV1NXNHNRM3JURzJMdXlRMlA0SCcsXG4gICAgICAgICAgICBhbW91bnQ6ICcxMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnQXp6OUVtTnVodGpvWXJoV3ZpZFd4MUhmZDE0U05Cc1l5elhoQTlUbm9jYTgnLFxuICAgICAgICAgICAgYW1vdW50OiAnMTAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzJuMnhxV005WjE4THF4Zkp6a05yTU1GV2lEVUZZQTJrNldTZ1NuZjZFbkpzJyxcbiAgICAgICAgICAgIGFtb3VudDogJzEwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBmZWU6IHtcbiAgICAgICAgICBmZWU6ICdVTkFWQUlMQUJMRScsXG4gICAgICAgICAgZmVlUmF0ZTogdW5kZWZpbmVkLFxuICAgICAgICB9LFxuICAgICAgICBtZW1vOiAnbWVtbyB0ZXh0JyxcbiAgICAgICAgYmxvY2toYXNoOiAnNW5lN3BoQTQ4SnJ2cG4zOUF0dXBCOFprQ0NBeThnTFRmcEdpaFpQdURxZW4nLFxuICAgICAgICBkdXJhYmxlTm9uY2U6IHtcbiAgICAgICAgICBhdXRoV2FsbGV0QWRkcmVzczogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgICB3YWxsZXROb25jZUFkZHJlc3M6ICc4WTdSTTZKZmNYNEFTU05Ca3Jrcm1TYlJ1NDMxWVZpOVkzb0xGbnpDMmRDaCcsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBzaWduZWQgdHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IGZhY3RvcnlcbiAgICAgICAgLmdldFRyYW5zZmVyQnVpbGRlcigpXG4gICAgICAgIC5mZWUoeyBhbW91bnQ6IDUwMDAgfSlcbiAgICAgICAgLm5vbmNlKGJsb2NrSGFzaClcbiAgICAgICAgLnNlbmRlcihzZW5kZXIpXG4gICAgICAgIC5zZW5kKHsgYWRkcmVzcywgYW1vdW50IH0pXG4gICAgICAgIC5idWlsZCgpO1xuICAgICAgYXdhaXQgKHR4IGFzIFRyYW5zYWN0aW9uKS5zaWduKG5ldyBLZXlQYWlyKHsgcHJ2OiB0ZXN0RGF0YS5hdXRoQWNjb3VudC5wcnYgfSkpO1xuXG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IHR4LmV4cGxhaW5UcmFuc2FjdGlvbigpO1xuICAgICAgZXhwbGFpbmVkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGRpc3BsYXlPcmRlcjogW1xuICAgICAgICAgICdpZCcsXG4gICAgICAgICAgJ3R5cGUnLFxuICAgICAgICAgICdibG9ja2hhc2gnLFxuICAgICAgICAgICdkdXJhYmxlTm9uY2UnLFxuICAgICAgICAgICdvdXRwdXRBbW91bnQnLFxuICAgICAgICAgICdjaGFuZ2VBbW91bnQnLFxuICAgICAgICAgICdvdXRwdXRzJyxcbiAgICAgICAgICAnY2hhbmdlT3V0cHV0cycsXG4gICAgICAgICAgJ2ZlZScsXG4gICAgICAgICAgJ21lbW8nLFxuICAgICAgICBdLFxuICAgICAgICBpZDogdHguaWQsXG4gICAgICAgIHR5cGU6ICdTZW5kJyxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRBbW91bnQ6ICcxMDAwMCcsXG4gICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnRGVzVTdYc2Naam5nOHlqNVZYNkFac2szaFdTVzRzUTNyVEcyTHV5UTJQNEgnLFxuICAgICAgICAgICAgYW1vdW50OiAnMTAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGZlZToge1xuICAgICAgICAgIGZlZTogJzUwMDAnLFxuICAgICAgICAgIGZlZVJhdGU6IDUwMDAsXG4gICAgICAgIH0sXG4gICAgICAgIG1lbW86IHVuZGVmaW5lZCxcbiAgICAgICAgYmxvY2toYXNoOiAnNW5lN3BoQTQ4SnJ2cG4zOUF0dXBCOFprQ0NBeThnTFRmcEdpaFpQdURxZW4nLFxuICAgICAgICBkdXJhYmxlTm9uY2U6IHVuZGVmaW5lZCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIHdhbGxldCBpbml0IHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHggPSBhd2FpdCBmYWN0b3J5XG4gICAgICAgIC5nZXRXYWxsZXRJbml0aWFsaXphdGlvbkJ1aWxkZXIoKVxuICAgICAgICAuZmVlKHsgYW1vdW50OiA1MDAwIH0pXG4gICAgICAgIC5zZW5kZXIoc2VuZGVyKVxuICAgICAgICAubm9uY2UoYmxvY2tIYXNoKVxuICAgICAgICAuYWRkcmVzcyh0ZXN0RGF0YS5hZGRyZXNzZXMudmFsaWRBZGRyZXNzZXNbMV0pXG4gICAgICAgIC5hbW91bnQoYW1vdW50KVxuICAgICAgICAuYnVpbGQoKTtcblxuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSB0eC5leHBsYWluVHJhbnNhY3Rpb24oKTtcbiAgICAgIGV4cGxhaW5lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBkaXNwbGF5T3JkZXI6IFtcbiAgICAgICAgICAnaWQnLFxuICAgICAgICAgICd0eXBlJyxcbiAgICAgICAgICAnYmxvY2toYXNoJyxcbiAgICAgICAgICAnZHVyYWJsZU5vbmNlJyxcbiAgICAgICAgICAnb3V0cHV0QW1vdW50JyxcbiAgICAgICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICAgICAnb3V0cHV0cycsXG4gICAgICAgICAgJ2NoYW5nZU91dHB1dHMnLFxuICAgICAgICAgICdmZWUnLFxuICAgICAgICAgICdtZW1vJyxcbiAgICAgICAgXSxcbiAgICAgICAgaWQ6ICdVTkFWQUlMQUJMRScsXG4gICAgICAgIHR5cGU6ICdXYWxsZXRJbml0aWFsaXphdGlvbicsXG4gICAgICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgICAgICBjaGFuZ2VBbW91bnQ6ICcwJyxcbiAgICAgICAgb3V0cHV0QW1vdW50OiAnMTAwMDAnLFxuICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJ0F6ejlFbU51aHRqb1lyaFd2aWRXeDFIZmQxNFNOQnNZeXpYaEE5VG5vY2E4JyxcbiAgICAgICAgICAgIGFtb3VudDogJzEwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBmZWU6IHtcbiAgICAgICAgICBmZWU6ICcxMDAwMCcsXG4gICAgICAgICAgZmVlUmF0ZTogNTAwMCxcbiAgICAgICAgfSxcbiAgICAgICAgbWVtbzogdW5kZWZpbmVkLFxuICAgICAgICBibG9ja2hhc2g6ICc1bmU3cGhBNDhKcnZwbjM5QXR1cEI4WmtDQ0F5OGdMVGZwR2loWlB1RHFlbicsXG4gICAgICAgIGR1cmFibGVOb25jZTogdW5kZWZpbmVkLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gd2FsbGV0IGluaXQgd2l0aCBkdXJhYmxlIG5vbmNlIGFuZCBtZW1vIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHggPSBhd2FpdCBmYWN0b3J5XG4gICAgICAgIC5nZXRXYWxsZXRJbml0aWFsaXphdGlvbkJ1aWxkZXIoKVxuICAgICAgICAuc2VuZGVyKHNlbmRlcilcbiAgICAgICAgLm5vbmNlKGJsb2NrSGFzaCwgeyB3YWxsZXROb25jZUFkZHJlc3M6IHRlc3REYXRhLm5vbmNlQWNjb3VudC5wdWIsIGF1dGhXYWxsZXRBZGRyZXNzOiBzZW5kZXIgfSlcbiAgICAgICAgLm1lbW8oJ21lbW8gdGV4dCcpXG4gICAgICAgIC5hZGRyZXNzKHRlc3REYXRhLmFkZHJlc3Nlcy52YWxpZEFkZHJlc3Nlc1sxXSlcbiAgICAgICAgLmFtb3VudChhbW91bnQpXG4gICAgICAgIC5idWlsZCgpO1xuXG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IHR4LmV4cGxhaW5UcmFuc2FjdGlvbigpO1xuICAgICAgZXhwbGFpbmVkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGRpc3BsYXlPcmRlcjogW1xuICAgICAgICAgICdpZCcsXG4gICAgICAgICAgJ3R5cGUnLFxuICAgICAgICAgICdibG9ja2hhc2gnLFxuICAgICAgICAgICdkdXJhYmxlTm9uY2UnLFxuICAgICAgICAgICdvdXRwdXRBbW91bnQnLFxuICAgICAgICAgICdjaGFuZ2VBbW91bnQnLFxuICAgICAgICAgICdvdXRwdXRzJyxcbiAgICAgICAgICAnY2hhbmdlT3V0cHV0cycsXG4gICAgICAgICAgJ2ZlZScsXG4gICAgICAgICAgJ21lbW8nLFxuICAgICAgICBdLFxuICAgICAgICBpZDogJ1VOQVZBSUxBQkxFJyxcbiAgICAgICAgdHlwZTogJ1dhbGxldEluaXRpYWxpemF0aW9uJyxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRBbW91bnQ6ICcxMDAwMCcsXG4gICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnQXp6OUVtTnVodGpvWXJoV3ZpZFd4MUhmZDE0U05Cc1l5elhoQTlUbm9jYTgnLFxuICAgICAgICAgICAgYW1vdW50OiAnMTAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGZlZToge1xuICAgICAgICAgIGZlZTogJ1VOQVZBSUxBQkxFJyxcbiAgICAgICAgICBmZWVSYXRlOiB1bmRlZmluZWQsXG4gICAgICAgIH0sXG4gICAgICAgIG1lbW86ICdtZW1vIHRleHQnLFxuICAgICAgICBibG9ja2hhc2g6ICc1bmU3cGhBNDhKcnZwbjM5QXR1cEI4WmtDQ0F5OGdMVGZwR2loWlB1RHFlbicsXG4gICAgICAgIGR1cmFibGVOb25jZToge1xuICAgICAgICAgIGF1dGhXYWxsZXRBZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICAgIHdhbGxldE5vbmNlQWRkcmVzczogJzhZN1JNNkpmY1g0QVNTTkJrcmtybVNiUnU0MzFZVmk5WTNvTEZuekMyZENoJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIHNpZ25lZCB3YWxsZXQgaW5pdCB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgZmFjdG9yeVxuICAgICAgICAuZ2V0V2FsbGV0SW5pdGlhbGl6YXRpb25CdWlsZGVyKClcbiAgICAgICAgLmZlZSh7IGFtb3VudDogNTAwMCB9KVxuICAgICAgICAuc2VuZGVyKHNlbmRlcilcbiAgICAgICAgLm5vbmNlKGJsb2NrSGFzaClcbiAgICAgICAgLmFkZHJlc3ModGVzdERhdGEuYWRkcmVzc2VzLnZhbGlkQWRkcmVzc2VzWzFdKVxuICAgICAgICAuYW1vdW50KGFtb3VudClcbiAgICAgICAgLmJ1aWxkKCk7XG4gICAgICBhd2FpdCAodHggYXMgVHJhbnNhY3Rpb24pLnNpZ24obmV3IEtleVBhaXIoeyBwcnY6IHRlc3REYXRhLmF1dGhBY2NvdW50LnBydiB9KSk7XG5cbiAgICAgIGNvbnN0IGV4cGxhaW5lZFRyYW5zYWN0aW9uID0gdHguZXhwbGFpblRyYW5zYWN0aW9uKCk7XG4gICAgICBleHBsYWluZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbXG4gICAgICAgICAgJ2lkJyxcbiAgICAgICAgICAndHlwZScsXG4gICAgICAgICAgJ2Jsb2NraGFzaCcsXG4gICAgICAgICAgJ2R1cmFibGVOb25jZScsXG4gICAgICAgICAgJ291dHB1dEFtb3VudCcsXG4gICAgICAgICAgJ2NoYW5nZUFtb3VudCcsXG4gICAgICAgICAgJ291dHB1dHMnLFxuICAgICAgICAgICdjaGFuZ2VPdXRwdXRzJyxcbiAgICAgICAgICAnZmVlJyxcbiAgICAgICAgICAnbWVtbycsXG4gICAgICAgIF0sXG4gICAgICAgIGlkOiB0eC5pZCxcbiAgICAgICAgdHlwZTogJ1dhbGxldEluaXRpYWxpemF0aW9uJyxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRBbW91bnQ6ICcxMDAwMCcsXG4gICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnQXp6OUVtTnVodGpvWXJoV3ZpZFd4MUhmZDE0U05Cc1l5elhoQTlUbm9jYTgnLFxuICAgICAgICAgICAgYW1vdW50OiAnMTAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGZlZToge1xuICAgICAgICAgIGZlZTogJzEwMDAwJyxcbiAgICAgICAgICBmZWVSYXRlOiA1MDAwLFxuICAgICAgICB9LFxuICAgICAgICBtZW1vOiB1bmRlZmluZWQsXG4gICAgICAgIGJsb2NraGFzaDogJzVuZTdwaEE0OEpydnBuMzlBdHVwQjhaa0NDQXk4Z0xUZnBHaWhaUHVEcWVuJyxcbiAgICAgICAgZHVyYWJsZU5vbmNlOiB1bmRlZmluZWQsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBjcmVhdGUgQVRBIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHggPSBhd2FpdCBmYWN0b3J5XG4gICAgICAgIC5nZXRBdGFJbml0aWFsaXphdGlvbkJ1aWxkZXIoKVxuICAgICAgICAuZmVlKHsgYW1vdW50OiA1MDAwIH0pXG4gICAgICAgIC5zZW5kZXIoc2VuZGVyKVxuICAgICAgICAubm9uY2UoYmxvY2tIYXNoKVxuICAgICAgICAubWludCgndHNvbDp1c2RjJylcbiAgICAgICAgLnJlbnRFeGVtcHRBbW91bnQoYW1vdW50KVxuICAgICAgICAuYnVpbGQoKTtcblxuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSB0eC5leHBsYWluVHJhbnNhY3Rpb24oKTtcbiAgICAgIGV4cGxhaW5lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBkaXNwbGF5T3JkZXI6IFtcbiAgICAgICAgICAnaWQnLFxuICAgICAgICAgICd0eXBlJyxcbiAgICAgICAgICAnYmxvY2toYXNoJyxcbiAgICAgICAgICAnZHVyYWJsZU5vbmNlJyxcbiAgICAgICAgICAnb3V0cHV0QW1vdW50JyxcbiAgICAgICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICAgICAnb3V0cHV0cycsXG4gICAgICAgICAgJ2NoYW5nZU91dHB1dHMnLFxuICAgICAgICAgICdmZWUnLFxuICAgICAgICAgICdtZW1vJyxcbiAgICAgICAgXSxcbiAgICAgICAgaWQ6ICdVTkFWQUlMQUJMRScsXG4gICAgICAgIHR5cGU6ICdBc3NvY2lhdGVkVG9rZW5BY2NvdW50SW5pdGlhbGl6YXRpb24nLFxuICAgICAgICBjaGFuZ2VPdXRwdXRzOiBbXSxcbiAgICAgICAgY2hhbmdlQW1vdW50OiAnMCcsXG4gICAgICAgIG91dHB1dEFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRzOiBbXSxcbiAgICAgICAgZmVlOiB7XG4gICAgICAgICAgZmVlOiAnMTUwMDAnLFxuICAgICAgICAgIGZlZVJhdGU6IDUwMDAsXG4gICAgICAgIH0sXG4gICAgICAgIG1lbW86IHVuZGVmaW5lZCxcbiAgICAgICAgYmxvY2toYXNoOiAnNW5lN3BoQTQ4SnJ2cG4zOUF0dXBCOFprQ0NBeThnTFRmcEdpaFpQdURxZW4nLFxuICAgICAgICBkdXJhYmxlTm9uY2U6IHVuZGVmaW5lZCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhY3RpdmF0ZSBidWlsZGVyICcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgZmFjdG9yeVxuICAgICAgICAuZ2V0U3Rha2luZ0FjdGl2YXRlQnVpbGRlcigpXG4gICAgICAgIC5zdGFraW5nQWRkcmVzcyhzdGFrZUFjY291bnQucHViKVxuICAgICAgICAuc2VuZGVyKHdhbGxldC5wdWIpXG4gICAgICAgIC5ub25jZShibG9ja0hhc2gpXG4gICAgICAgIC5hbW91bnQoYW1vdW50KVxuICAgICAgICAudmFsaWRhdG9yKHZhbGlkYXRvci5wdWIpXG4gICAgICAgIC5mZWUoeyBhbW91bnQ6IDUwMDAgfSlcbiAgICAgICAgLmJ1aWxkKCk7XG5cbiAgICAgIGNvbnN0IGV4cGxhaW5lZFRyYW5zYWN0aW9uID0gdHguZXhwbGFpblRyYW5zYWN0aW9uKCk7XG4gICAgICBleHBsYWluZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbXG4gICAgICAgICAgJ2lkJyxcbiAgICAgICAgICAndHlwZScsXG4gICAgICAgICAgJ2Jsb2NraGFzaCcsXG4gICAgICAgICAgJ2R1cmFibGVOb25jZScsXG4gICAgICAgICAgJ291dHB1dEFtb3VudCcsXG4gICAgICAgICAgJ2NoYW5nZUFtb3VudCcsXG4gICAgICAgICAgJ291dHB1dHMnLFxuICAgICAgICAgICdjaGFuZ2VPdXRwdXRzJyxcbiAgICAgICAgICAnZmVlJyxcbiAgICAgICAgICAnbWVtbycsXG4gICAgICAgIF0sXG4gICAgICAgIGlkOiAnVU5BVkFJTEFCTEUnLFxuICAgICAgICB0eXBlOiAnU3Rha2luZ0FjdGl2YXRlJyxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRBbW91bnQ6ICcxMDAwMCcsXG4gICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnN2RSdUdGYlUyeTJraWpQNm8xTFlOelZ5ejR5ZjEzTW9vcW9pb25DenY1WmEnLFxuICAgICAgICAgICAgYW1vdW50OiAnMTAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGZlZToge1xuICAgICAgICAgIGZlZTogJzEwMDAwJyxcbiAgICAgICAgICBmZWVSYXRlOiA1MDAwLFxuICAgICAgICB9LFxuICAgICAgICBtZW1vOiB1bmRlZmluZWQsXG4gICAgICAgIGJsb2NraGFzaDogJzVuZTdwaEE0OEpydnBuMzlBdHVwQjhaa0NDQXk4Z0xUZnBHaWhaUHVEcWVuJyxcbiAgICAgICAgZHVyYWJsZU5vbmNlOiB1bmRlZmluZWQsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZGVhY3RpdmF0ZSBidWlsZGVyICcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlY2VudEJsb2NrSGFzaCA9ICdHSHRYUUJzb1pIVm5ORmE5WWV2QXpGcjE3REpqZ0hYazN5Y1RLRDV4RDNaaSc7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IGZhY3RvcnlcbiAgICAgICAgLmdldFN0YWtpbmdEZWFjdGl2YXRlQnVpbGRlcigpXG4gICAgICAgIC5zdGFraW5nQWRkcmVzcyhzdGFrZUFjY291bnQucHViKVxuICAgICAgICAuc2VuZGVyKHdhbGxldC5wdWIpXG4gICAgICAgIC5zdGFraW5nQWRkcmVzcyhzdGFrZUFjY291bnQucHViKVxuICAgICAgICAubm9uY2UocmVjZW50QmxvY2tIYXNoKVxuICAgICAgICAuZmVlKHsgYW1vdW50OiA1MDAwIH0pXG4gICAgICAgIC5idWlsZCgpO1xuXG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IHR4LmV4cGxhaW5UcmFuc2FjdGlvbigpO1xuICAgICAgZXhwbGFpbmVkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGRpc3BsYXlPcmRlcjogW1xuICAgICAgICAgICdpZCcsXG4gICAgICAgICAgJ3R5cGUnLFxuICAgICAgICAgICdibG9ja2hhc2gnLFxuICAgICAgICAgICdkdXJhYmxlTm9uY2UnLFxuICAgICAgICAgICdvdXRwdXRBbW91bnQnLFxuICAgICAgICAgICdjaGFuZ2VBbW91bnQnLFxuICAgICAgICAgICdvdXRwdXRzJyxcbiAgICAgICAgICAnY2hhbmdlT3V0cHV0cycsXG4gICAgICAgICAgJ2ZlZScsXG4gICAgICAgICAgJ21lbW8nLFxuICAgICAgICBdLFxuICAgICAgICBpZDogJ1VOQVZBSUxBQkxFJyxcbiAgICAgICAgdHlwZTogJ1N0YWtpbmdEZWFjdGl2YXRlJyxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRBbW91bnQ6ICcwJyxcbiAgICAgICAgb3V0cHV0czogW10sXG4gICAgICAgIGZlZToge1xuICAgICAgICAgIGZlZTogJzUwMDAnLFxuICAgICAgICAgIGZlZVJhdGU6IDUwMDAsXG4gICAgICAgIH0sXG4gICAgICAgIG1lbW86IHVuZGVmaW5lZCxcbiAgICAgICAgYmxvY2toYXNoOiAnR0h0WFFCc29aSFZuTkZhOVlldkF6RnIxN0RKamdIWGszeWNUS0Q1eEQzWmknLFxuICAgICAgICBkdXJhYmxlTm9uY2U6IHVuZGVmaW5lZCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIHdpdGhkcmF3IHRyYW5zYWN0aW9uICcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlY2VudEJsb2NrSGFzaCA9ICdHSHRYUUJzb1pIVm5ORmE5WWV2QXpGcjE3REpqZ0hYazN5Y1RLRDV4RDNaaSc7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IGZhY3RvcnlcbiAgICAgICAgLmdldFN0YWtpbmdXaXRoZHJhd0J1aWxkZXIoKVxuICAgICAgICAuc3Rha2luZ0FkZHJlc3Moc3Rha2VBY2NvdW50LnB1YilcbiAgICAgICAgLnNlbmRlcih3YWxsZXQucHViKVxuICAgICAgICAuYW1vdW50KGFtb3VudClcbiAgICAgICAgLm5vbmNlKHJlY2VudEJsb2NrSGFzaClcbiAgICAgICAgLmZlZSh7IGFtb3VudDogNTAwMCB9KVxuICAgICAgICAuYnVpbGQoKTtcblxuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSB0eC5leHBsYWluVHJhbnNhY3Rpb24oKTtcbiAgICAgIGV4cGxhaW5lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBkaXNwbGF5T3JkZXI6IFtcbiAgICAgICAgICAnaWQnLFxuICAgICAgICAgICd0eXBlJyxcbiAgICAgICAgICAnYmxvY2toYXNoJyxcbiAgICAgICAgICAnZHVyYWJsZU5vbmNlJyxcbiAgICAgICAgICAnb3V0cHV0QW1vdW50JyxcbiAgICAgICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICAgICAnb3V0cHV0cycsXG4gICAgICAgICAgJ2NoYW5nZU91dHB1dHMnLFxuICAgICAgICAgICdmZWUnLFxuICAgICAgICAgICdtZW1vJyxcbiAgICAgICAgXSxcbiAgICAgICAgaWQ6ICdVTkFWQUlMQUJMRScsXG4gICAgICAgIHR5cGU6ICdTdGFraW5nV2l0aGRyYXcnLFxuICAgICAgICBjaGFuZ2VPdXRwdXRzOiBbXSxcbiAgICAgICAgY2hhbmdlQW1vdW50OiAnMCcsXG4gICAgICAgIG91dHB1dEFtb3VudDogJzEwMDAwJyxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgICAgICBhbW91bnQ6ICcxMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZmVlOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgICAgZmVlUmF0ZTogNTAwMCxcbiAgICAgICAgfSxcbiAgICAgICAgbWVtbzogdW5kZWZpbmVkLFxuICAgICAgICBibG9ja2hhc2g6ICdHSHRYUUJzb1pIVm5ORmE5WWV2QXpGcjE3REpqZ0hYazN5Y1RLRDV4RDNaaScsXG4gICAgICAgIGR1cmFibGVOb25jZTogdW5kZWZpbmVkLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gd2l0aGRyYXcgdHJhbnNhY3Rpb24gd2l0aCBtZW1vIGFuZCBkdXJhYmxlIG5vbmNlICcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgZmFjdG9yeVxuICAgICAgICAuZ2V0U3Rha2luZ1dpdGhkcmF3QnVpbGRlcigpXG4gICAgICAgIC5zdGFraW5nQWRkcmVzcyhzdGFrZUFjY291bnQucHViKVxuICAgICAgICAuc2VuZGVyKHdhbGxldC5wdWIpXG4gICAgICAgIC5hbW91bnQoYW1vdW50KVxuICAgICAgICAubm9uY2UoYmxvY2tIYXNoLCB7IHdhbGxldE5vbmNlQWRkcmVzczogdGVzdERhdGEubm9uY2VBY2NvdW50LnB1YiwgYXV0aFdhbGxldEFkZHJlc3M6IHNlbmRlciB9KVxuICAgICAgICAubWVtbygnbWVtbyB0ZXh0JylcbiAgICAgICAgLmZlZSh7IGFtb3VudDogNTAwMCB9KVxuICAgICAgICAuYnVpbGQoKTtcbiAgICAgIHR4LnNpZ25hYmxlUGF5bG9hZDtcblxuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSB0eC5leHBsYWluVHJhbnNhY3Rpb24oKTtcbiAgICAgIGV4cGxhaW5lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBkaXNwbGF5T3JkZXI6IFtcbiAgICAgICAgICAnaWQnLFxuICAgICAgICAgICd0eXBlJyxcbiAgICAgICAgICAnYmxvY2toYXNoJyxcbiAgICAgICAgICAnZHVyYWJsZU5vbmNlJyxcbiAgICAgICAgICAnb3V0cHV0QW1vdW50JyxcbiAgICAgICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICAgICAnb3V0cHV0cycsXG4gICAgICAgICAgJ2NoYW5nZU91dHB1dHMnLFxuICAgICAgICAgICdmZWUnLFxuICAgICAgICAgICdtZW1vJyxcbiAgICAgICAgXSxcbiAgICAgICAgaWQ6ICdVTkFWQUlMQUJMRScsXG4gICAgICAgIHR5cGU6ICdTdGFraW5nV2l0aGRyYXcnLFxuICAgICAgICBjaGFuZ2VPdXRwdXRzOiBbXSxcbiAgICAgICAgY2hhbmdlQW1vdW50OiAnMCcsXG4gICAgICAgIG91dHB1dEFtb3VudDogJzEwMDAwJyxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgICAgICBhbW91bnQ6ICcxMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZmVlOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgICAgZmVlUmF0ZTogNTAwMCxcbiAgICAgICAgfSxcbiAgICAgICAgbWVtbzogJ21lbW8gdGV4dCcsXG4gICAgICAgIGJsb2NraGFzaDogJzVuZTdwaEE0OEpydnBuMzlBdHVwQjhaa0NDQXk4Z0xUZnBHaWhaUHVEcWVuJyxcbiAgICAgICAgZHVyYWJsZU5vbmNlOiB7XG4gICAgICAgICAgd2FsbGV0Tm9uY2VBZGRyZXNzOiB0ZXN0RGF0YS5ub25jZUFjY291bnQucHViLFxuICAgICAgICAgIGF1dGhXYWxsZXRBZGRyZXNzOiBzZW5kZXIsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBzaW5nbGUgdG9rZW4gdHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IGZhY3RvcnlcbiAgICAgICAgLmdldFRva2VuVHJhbnNmZXJCdWlsZGVyKClcbiAgICAgICAgLm5vbmNlKGJsb2NrSGFzaClcbiAgICAgICAgLnNlbmRlcihzZW5kZXIpXG4gICAgICAgIC5zZW5kKHsgYWRkcmVzcywgYW1vdW50LCB0b2tlbk5hbWU6ICd0c29sOnVzZGMnIH0pXG4gICAgICAgIC5mZWUoeyBhbW91bnQ6IDUwMDAgfSlcbiAgICAgICAgLmJ1aWxkKCk7XG5cbiAgICAgIGNvbnN0IGV4cGxhaW5lZFRyYW5zYWN0aW9uID0gdHguZXhwbGFpblRyYW5zYWN0aW9uKCk7XG4gICAgICBleHBsYWluZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbXG4gICAgICAgICAgJ2lkJyxcbiAgICAgICAgICAndHlwZScsXG4gICAgICAgICAgJ2Jsb2NraGFzaCcsXG4gICAgICAgICAgJ2R1cmFibGVOb25jZScsXG4gICAgICAgICAgJ291dHB1dEFtb3VudCcsXG4gICAgICAgICAgJ2NoYW5nZUFtb3VudCcsXG4gICAgICAgICAgJ291dHB1dHMnLFxuICAgICAgICAgICdjaGFuZ2VPdXRwdXRzJyxcbiAgICAgICAgICAnZmVlJyxcbiAgICAgICAgICAnbWVtbycsXG4gICAgICAgIF0sXG4gICAgICAgIGlkOiAnVU5BVkFJTEFCTEUnLFxuICAgICAgICB0eXBlOiAnU2VuZCcsXG4gICAgICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgICAgICBjaGFuZ2VBbW91bnQ6ICcwJyxcbiAgICAgICAgb3V0cHV0QW1vdW50OiAnMCcsXG4gICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnRGVzVTdYc2Naam5nOHlqNVZYNkFac2szaFdTVzRzUTNyVEcyTHV5UTJQNEgnLFxuICAgICAgICAgICAgYW1vdW50OiAnMTAwMDAnLFxuICAgICAgICAgICAgdG9rZW5OYW1lOiAndHNvbDp1c2RjJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBmZWU6IHtcbiAgICAgICAgICBmZWU6ICc1MDAwJyxcbiAgICAgICAgICBmZWVSYXRlOiA1MDAwLFxuICAgICAgICB9LFxuICAgICAgICBtZW1vOiB1bmRlZmluZWQsXG4gICAgICAgIGJsb2NraGFzaDogJzVuZTdwaEE0OEpydnBuMzlBdHVwQjhaa0NDQXk4Z0xUZnBHaWhaUHVEcWVuJyxcbiAgICAgICAgZHVyYWJsZU5vbmNlOiB1bmRlZmluZWQsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBtdWx0aSB0b2tlbiB0cmFuc2ZlciB3aXRoIGR1cmFibGUgbm9uY2UgYW5kIG1lbW8gdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IGZhY3RvcnlcbiAgICAgICAgLmdldFRva2VuVHJhbnNmZXJCdWlsZGVyKClcbiAgICAgICAgLm5vbmNlKGJsb2NrSGFzaCwgeyB3YWxsZXROb25jZUFkZHJlc3M6IHRlc3REYXRhLm5vbmNlQWNjb3VudC5wdWIsIGF1dGhXYWxsZXRBZGRyZXNzOiBzZW5kZXIgfSlcbiAgICAgICAgLnNlbmRlcihzZW5kZXIpXG4gICAgICAgIC5tZW1vKCdtZW1vIHRleHQnKVxuICAgICAgICAuc2VuZCh7IGFkZHJlc3MsIGFtb3VudCwgdG9rZW5OYW1lOiAndHNvbDp1c2RjJyB9KVxuICAgICAgICAuc2VuZCh7IGFkZHJlc3M6IHRlc3REYXRhLmFkZHJlc3Nlcy52YWxpZEFkZHJlc3Nlc1sxXSwgYW1vdW50LCB0b2tlbk5hbWU6ICd0c29sOnVzZGMnIH0pXG4gICAgICAgIC5zZW5kKHsgYWRkcmVzczogdGVzdERhdGEuYWRkcmVzc2VzLnZhbGlkQWRkcmVzc2VzWzJdLCBhbW91bnQsIHRva2VuTmFtZTogJ3Rzb2w6dXNkYycgfSlcbiAgICAgICAgLmJ1aWxkKCk7XG5cbiAgICAgIGNvbnN0IGV4cGxhaW5lZFRyYW5zYWN0aW9uID0gdHguZXhwbGFpblRyYW5zYWN0aW9uKCk7XG4gICAgICBleHBsYWluZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbXG4gICAgICAgICAgJ2lkJyxcbiAgICAgICAgICAndHlwZScsXG4gICAgICAgICAgJ2Jsb2NraGFzaCcsXG4gICAgICAgICAgJ2R1cmFibGVOb25jZScsXG4gICAgICAgICAgJ291dHB1dEFtb3VudCcsXG4gICAgICAgICAgJ2NoYW5nZUFtb3VudCcsXG4gICAgICAgICAgJ291dHB1dHMnLFxuICAgICAgICAgICdjaGFuZ2VPdXRwdXRzJyxcbiAgICAgICAgICAnZmVlJyxcbiAgICAgICAgICAnbWVtbycsXG4gICAgICAgIF0sXG4gICAgICAgIGlkOiAnVU5BVkFJTEFCTEUnLFxuICAgICAgICB0eXBlOiAnU2VuZCcsXG4gICAgICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgICAgICBjaGFuZ2VBbW91bnQ6ICcwJyxcbiAgICAgICAgb3V0cHV0QW1vdW50OiAnMCcsXG4gICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnRGVzVTdYc2Naam5nOHlqNVZYNkFac2szaFdTVzRzUTNyVEcyTHV5UTJQNEgnLFxuICAgICAgICAgICAgYW1vdW50OiAnMTAwMDAnLFxuICAgICAgICAgICAgdG9rZW5OYW1lOiAndHNvbDp1c2RjJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICdBeno5RW1OdWh0am9ZcmhXdmlkV3gxSGZkMTRTTkJzWXl6WGhBOVRub2NhOCcsXG4gICAgICAgICAgICBhbW91bnQ6ICcxMDAwMCcsXG4gICAgICAgICAgICB0b2tlbk5hbWU6ICd0c29sOnVzZGMnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzJuMnhxV005WjE4THF4Zkp6a05yTU1GV2lEVUZZQTJrNldTZ1NuZjZFbkpzJyxcbiAgICAgICAgICAgIGFtb3VudDogJzEwMDAwJyxcbiAgICAgICAgICAgIHRva2VuTmFtZTogJ3Rzb2w6dXNkYycsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZmVlOiB7XG4gICAgICAgICAgZmVlOiAnVU5BVkFJTEFCTEUnLFxuICAgICAgICAgIGZlZVJhdGU6IHVuZGVmaW5lZCxcbiAgICAgICAgfSxcbiAgICAgICAgbWVtbzogJ21lbW8gdGV4dCcsXG4gICAgICAgIGJsb2NraGFzaDogJzVuZTdwaEE0OEpydnBuMzlBdHVwQjhaa0NDQXk4Z0xUZnBHaWhaUHVEcWVuJyxcbiAgICAgICAgZHVyYWJsZU5vbmNlOiB7XG4gICAgICAgICAgYXV0aFdhbGxldEFkZHJlc3M6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgICAgd2FsbGV0Tm9uY2VBZGRyZXNzOiAnOFk3Uk02SmZjWDRBU1NOQmtya3JtU2JSdTQzMVlWaTlZM29MRm56QzJkQ2gnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=

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


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