PHP WebShell

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

Просмотр файла: assetTransferBuilder.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 statics_1 = require("@bitgo/statics");
const assert_1 = __importDefault(require("assert"));
const should_1 = __importDefault(require("should"));
const mocha_1 = require("mocha");
const lib_1 = require("../../../../src/lib");
const AlgoResources = __importStar(require("../../../fixtures/resources"));
describe('Algo Asset Transfer Transaction Builder', () => {
    let txnBuilder;
    const { accounts: { account1 }, rawTx, } = AlgoResources;
    beforeEach(() => {
        const config = statics_1.coins.get('algo');
        txnBuilder = new lib_1.TransactionBuilderFactory(config).getAssetTransferBuilder();
    });
    describe('setter validation', () => {
        it('should validate asset id is not lte 0', () => {
            assert_1.default.throws(() => txnBuilder.tokenId(-1));
            assert_1.default.throws(() => txnBuilder.tokenId(0));
            should_1.default.doesNotThrow(() => txnBuilder.tokenId(1));
        });
    });
    describe('build asset transfer transaction', () => {
        it('should build a normal asset transfer transaction', async () => {
            const sender = AlgoResources.accounts.account1;
            const receiver = AlgoResources.accounts.account2;
            const amount = 1234;
            const firstRound = 1;
            const lastRound = 10;
            const fee = 1000;
            const tokenId = 1;
            const { networks: { testnet }, } = AlgoResources;
            const { genesisHash, genesisID } = testnet;
            const tx = await txnBuilder
                .fee({ fee: fee.toString() })
                .isFlatFee(true)
                .firstRound(firstRound)
                .lastRound(lastRound)
                .testnet()
                .sender({ address: sender.address })
                .tokenId(tokenId)
                .amount(amount)
                .to({ address: receiver.address })
                .build();
            const txJson = tx.toJson();
            should_1.default.deepEqual(txJson.from, sender.address);
            should_1.default.deepEqual(txJson.to, receiver.address);
            should_1.default.deepEqual(txJson.fee, fee);
            should_1.default.deepEqual(txJson.firstRound, firstRound);
            should_1.default.deepEqual(txJson.lastRound, lastRound);
            should_1.default.deepEqual(txJson.tokenId, tokenId);
            should_1.default.deepEqual(txJson.amount, amount.toString());
            should_1.default.deepEqual(txJson.genesisID, genesisID.toString());
            should_1.default.deepEqual(txJson.genesisHash.toString('base64'), genesisHash);
        });
        it('should build a valid disable token transaction', async function () {
            const firstRound = 167;
            const lastRound = 1167;
            const fee = 1000;
            const tokenId = 1;
            const amount = '0';
            const note = new Uint8Array(Buffer.from('note', 'utf-8'));
            const address = 'RIJVLDYWASZZNGOSQNOK7HN6JNFLMMZ3FFBBFG2NNROM5CE744DAJSPZJ4';
            const closeRemainderTo = 'SP745JJR4KPRQEXJZHVIEN736LYTL2T2DFMG3OIIFJBV66K73PHNMDCZVM';
            const tx = await txnBuilder
                .fee({ fee: fee.toString() })
                .isFlatFee(true)
                .firstRound(firstRound)
                .lastRound(lastRound)
                .testnet()
                .closeRemainderTo({ address: closeRemainderTo })
                .sender({ address: address })
                .tokenId(tokenId)
                .amount(BigInt(amount))
                .to({ address: address })
                .note(note)
                .build();
            const txHex = tx.toBroadcastFormat();
            const txInfo = tx.toJson();
            should_1.default.exists(txHex);
            txInfo.to.should.equal(address);
            txInfo.from.should.equal(address);
            txInfo.closeRemainderTo.should.equal(closeRemainderTo);
            txInfo.amount.should.equal('0');
            txInfo.firstRound.should.equal(167);
            txInfo.tokenId.should.equal(1);
            txInfo.fee.should.equal(1000);
            txInfo.note.should.equal(note);
            txInfo.lastRound.should.equal(1167);
            txInfo.genesisID.should.equal('testnet-v1.0');
            txInfo.genesisHash.should.equal('SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=');
        });
        it('should not build a token transaction with an invalid sender address', async function () {
            const wrongAddress = 'RIJVLDYWASZZNGOSQNOK7HN6JNFLMMZ3FFBBFG2NNROM5CE744DAJSPZJ';
            const tx = await txnBuilder.testnet();
            assert_1.default.throws(() => tx.sender({ address: wrongAddress }), new RegExp("The address '" + wrongAddress + "' is not a well-formed algorand address"));
        });
        it('should not build a token transaction with an invalid closeRemainderTo address', async function () {
            const wrongAddress = 'RIJVLDYWASZZNGOSQNOK7HN6JNFLMMZ3FFBBFG2NNROM5CE744DAJSPZJ';
            const tx = await txnBuilder.testnet();
            assert_1.default.throws(() => tx.closeRemainderTo({ address: wrongAddress }), new RegExp("The address '" + wrongAddress + "' is not a well-formed algorand address"));
        });
        it('should not build a token transaction with an invalid to address', async function () {
            const wrongAddress = 'RIJVLDYWASZZNGOSQNOK7HN6JNFLMMZ3FFBBFG2NNROM5CE744DAJSPZJ';
            const tx = await txnBuilder.testnet();
            assert_1.default.throws(() => tx.to({ address: wrongAddress }), new RegExp("The address '" + wrongAddress + "' is not a well-formed algorand address"));
        });
        it('should build a valid enable token transaction', async function () {
            const firstRound = 167;
            const lastRound = 1167;
            const fee = 1000;
            const tokenId = 1;
            const amount = '0';
            const address = 'RIJVLDYWASZZNGOSQNOK7HN6JNFLMMZ3FFBBFG2NNROM5CE744DAJSPZJ4';
            const tx = await txnBuilder
                .fee({ fee: fee.toString() })
                .isFlatFee(true)
                .firstRound(firstRound)
                .lastRound(lastRound)
                .testnet()
                .sender({ address: address })
                .tokenId(tokenId)
                .amount(BigInt(amount))
                .to({ address: address })
                .build();
            const txHex = tx.toBroadcastFormat();
            const txInfo = tx.toJson();
            should_1.default.exists(txHex);
            txInfo.to.should.equal(address);
            txInfo.from.should.equal(address);
            txInfo.amount.should.equal('0');
            txInfo.firstRound.should.equal(167);
            txInfo.tokenId.should.equal(1);
            txInfo.fee.should.equal(1000);
            txInfo.lastRound.should.equal(1167);
            txInfo.genesisID.should.equal('testnet-v1.0');
            txInfo.genesisHash.should.equal('SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=');
        });
        it('should build a valid enable token transaction and re-calcualte minimum fee', async function () {
            const firstRound = 167;
            const lastRound = 1167;
            const fee = 1000;
            const tokenId = 1;
            const amount = '0';
            const address = 'RIJVLDYWASZZNGOSQNOK7HN6JNFLMMZ3FFBBFG2NNROM5CE744DAJSPZJ4';
            const tx = await txnBuilder
                .fee({ fee: fee.toString() })
                .isFlatFee(true)
                .firstRound(firstRound)
                .lastRound(lastRound)
                .testnet()
                .sender({ address: address })
                .tokenId(tokenId)
                .amount(BigInt(amount))
                .to({ address: address })
                .build();
            const txHex = tx.toBroadcastFormat();
            const txInfo = tx.toJson();
            should_1.default.exists(txHex);
            txInfo.to.should.equal(address);
            txInfo.from.should.equal(address);
            txInfo.amount.should.equal('0');
            txInfo.firstRound.should.equal(167);
            txInfo.tokenId.should.equal(1);
            txInfo.fee.should.equal(1000);
            txInfo.lastRound.should.equal(1167);
            txInfo.genesisID.should.equal('testnet-v1.0');
            txInfo.genesisHash.should.equal('SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=');
        });
        it('should build a valid disable token transaction and re-calcualte minimum fee', async function () {
            const firstRound = 167;
            const lastRound = 1167;
            const fee = 1000;
            const tokenId = 1;
            const closeRemainderTo = 'SP745JJR4KPRQEXJZHVIEN736LYTL2T2DFMG3OIIFJBV66K73PHNMDCZVM';
            const amount = '0';
            const address = 'RIJVLDYWASZZNGOSQNOK7HN6JNFLMMZ3FFBBFG2NNROM5CE744DAJSPZJ4';
            const tx = await txnBuilder
                .fee({ fee: fee.toString() })
                .isFlatFee(true)
                .firstRound(firstRound)
                .lastRound(lastRound)
                .testnet()
                .closeRemainderTo({ address: closeRemainderTo })
                .sender({ address: address })
                .tokenId(tokenId)
                .amount(BigInt(amount))
                .to({ address: address })
                .build();
            const txHex = tx.toBroadcastFormat();
            const txInfo = tx.toJson();
            should_1.default.exists(txHex);
            txInfo.to.should.equal(address);
            txInfo.from.should.equal(address);
            txInfo.amount.should.equal('0');
            txInfo.firstRound.should.equal(167);
            txInfo.tokenId.should.equal(1);
            txInfo.fee.should.equal(1000);
            txInfo.closeRemainderTo.should.equal(closeRemainderTo);
            txInfo.lastRound.should.equal(1167);
            txInfo.genesisID.should.equal('testnet-v1.0');
            txInfo.genesisHash.should.equal('SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=');
        });
        it('should decode an unsigned asset transfer transaction', async () => {
            txnBuilder.from(rawTx.assetTransfer.unsigned);
            const tx = await txnBuilder.build();
            const txJson = tx.toJson();
            const sender = AlgoResources.accounts.account1;
            const receiver = AlgoResources.accounts.account2;
            should_1.default.deepEqual(Buffer.from(tx.toBroadcastFormat()).toString('hex'), AlgoResources.rawTx.assetTransfer.unsigned);
            should_1.default.deepEqual(txJson.from, sender.address);
            should_1.default.deepEqual(txJson.to, receiver.address);
            should_1.default.deepEqual(txJson.amount, '1000');
            should_1.default.deepEqual(txJson.firstRound, 1);
            should_1.default.deepEqual(txJson.lastRound, 10);
            should_1.default.deepEqual(txJson.tokenId, 1);
        });
        it('should decode a signed asset transfer transaction', async () => {
            txnBuilder.from(rawTx.assetTransfer.signed);
            txnBuilder.numberOfSigners(1).sign({ key: account1.prvKey });
            const tx = await txnBuilder.build();
            const txJson = tx.toJson();
            const sender = AlgoResources.accounts.account1;
            const receiver = AlgoResources.accounts.account2;
            should_1.default.deepEqual(Buffer.from(tx.toBroadcastFormat()).toString('hex'), AlgoResources.rawTx.assetTransfer.signed);
            should_1.default.deepEqual(txJson.from, sender.address);
            should_1.default.deepEqual(txJson.to, receiver.address);
            should_1.default.deepEqual(txJson.amount, '10000000000000000000');
            should_1.default.deepEqual(txJson.firstRound, 1);
            should_1.default.deepEqual(txJson.lastRound, 10);
            should_1.default.deepEqual(txJson.tokenId, 1);
        });
        it('should fail to decode other types of transactions', () => {
            assert_1.default.throws(() => txnBuilder.from(rawTx.keyReg.unsigned), /Invalid Transaction Type: keyreg. Expected axfer/);
            assert_1.default.throws(() => txnBuilder.from(rawTx.keyReg.signed), /Invalid Transaction Type: keyreg. Expected axfer/);
            assert_1.default.throws(() => txnBuilder.from(rawTx.transfer.unsigned), /Invalid Transaction Type: pay. Expected axfer/);
            assert_1.default.throws(() => txnBuilder.from(rawTx.transfer.signed), /Invalid Transaction Type: pay. Expected axfer/);
        });
    });
    describe('allowlist asset txn', () => {
        (0, mocha_1.test)('allowlist parameters are set correctly', async () => {
            const tokenId = 123;
            const sender = account1.address;
            const { networks: { testnet }, } = AlgoResources;
            const { genesisHash, genesisID } = testnet;
            txnBuilder
                .allowListAsset(tokenId, { address: sender })
                .firstRound(1)
                .lastRound(10)
                .testnet()
                .numberOfRequiredSigners(1);
            txnBuilder.sign({ key: account1.prvKey });
            const tx = await txnBuilder.build();
            const txJson = tx.toJson();
            should_1.default.equal(txJson.from, account1.address);
            should_1.default.equal(txJson.to, account1.address);
            should_1.default.equal(txJson.tokenId, tokenId);
            should_1.default.equal(txJson.fee, 1000);
            should_1.default.deepEqual(txJson.genesisID, genesisID.toString());
            should_1.default.deepEqual(txJson.genesisHash.toString('base64'), genesisHash);
        });
    });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXRUcmFuc2ZlckJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi90ZXN0L3VuaXQvbGliL3RyYW5zYWN0aW9uQnVpbGRlci9hc3NldFRyYW5zZmVyQnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDRDQUF1QztBQUN2QyxvREFBNEI7QUFDNUIsb0RBQTRCO0FBQzVCLGlDQUE2QjtBQUM3Qiw2Q0FBc0Y7QUFFdEYsMkVBQTZEO0FBRTdELFFBQVEsQ0FBQyx5Q0FBeUMsRUFBRSxHQUFHLEVBQUU7SUFDdkQsSUFBSSxVQUFnQyxDQUFDO0lBRXJDLE1BQU0sRUFDSixRQUFRLEVBQUUsRUFBRSxRQUFRLEVBQUUsRUFDdEIsS0FBSyxHQUNOLEdBQUcsYUFBYSxDQUFDO0lBRWxCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7UUFDZCxNQUFNLE1BQU0sR0FBRyxlQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2pDLFVBQVUsR0FBRyxJQUFJLCtCQUF5QixDQUFDLE1BQU0sQ0FBQyxDQUFDLHVCQUF1QixFQUFFLENBQUM7SUFDL0UsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsbUJBQW1CLEVBQUUsR0FBRyxFQUFFO1FBQ2pDLEVBQUUsQ0FBQyx1Q0FBdUMsRUFBRSxHQUFHLEVBQUU7WUFDL0MsZ0JBQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDNUMsZ0JBQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzNDLGdCQUFNLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFD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QUUsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLENBQUM7aUJBQzVDLFVBQVUsQ0FBQyxDQUFDLENBQUM7aUJBQ2IsU0FBUyxDQUFDLEVBQUUsQ0FBQztpQkFDYixPQUFPLEVBQUU7aUJBQ1QsdUJBQXVCLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFOUIsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUUxQyxNQUFNLEVBQUUsR0FBRyxNQUFNLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNwQyxNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7WUFFM0IsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDNUMsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDMUMsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztZQUN0QyxnQkFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQy9CLGdCQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7WUFDekQsZ0JBQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDdkUsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29pbnMgfSBmcm9tICdAYml0Z28vc3RhdGljcyc7XG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgc2hvdWxkIGZyb20gJ3Nob3VsZCc7XG5pbXBvcnQgeyB0ZXN0IH0gZnJvbSAnbW9jaGEnO1xuaW1wb3J0IHsgQXNzZXRUcmFuc2ZlckJ1aWxkZXIsIFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkgfSBmcm9tICcuLi8uLi8uLi8uLi9zcmMvbGliJztcblxuaW1wb3J0ICogYXMgQWxnb1Jlc291cmNlcyBmcm9tICcuLi8uLi8uLi9maXh0dXJlcy9yZXNvdXJjZXMnO1xuXG5kZXNjcmliZSgnQWxnbyBBc3NldCBUcmFuc2ZlciBUcmFuc2FjdGlvbiBCdWlsZGVyJywgKCkgPT4ge1xuICBsZXQgdHhuQnVpbGRlcjogQXNzZXRUcmFuc2ZlckJ1aWxkZXI7XG5cbiAgY29uc3Qge1xuICAgIGFjY291bnRzOiB7IGFjY291bnQxIH0sXG4gICAgcmF3VHgsXG4gIH0gPSBBbGdvUmVzb3VyY2VzO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IGNvaW5zLmdldCgnYWxnbycpO1xuICAgIHR4bkJ1aWxkZXIgPSBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb25maWcpLmdldEFzc2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdzZXR0ZXIgdmFsaWRhdGlvbicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIGFzc2V0IGlkIGlzIG5vdCBsdGUgMCcsICgpID0+IHtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdHhuQnVpbGRlci50b2tlbklkKC0xKSk7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHR4bkJ1aWxkZXIudG9rZW5JZCgwKSk7XG4gICAgICBzaG91bGQuZG9lc05vdFRocm93KCgpID0+IHR4bkJ1aWxkZXIudG9rZW5JZCgxKSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdidWlsZCBhc3NldCB0cmFuc2ZlciB0cmFuc2FjdGlvbicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGJ1aWxkIGEgbm9ybWFsIGFzc2V0IHRyYW5zZmVyIHRyYW5zYWN0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgc2VuZGVyID0gQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MTtcbiAgICAgIGNvbnN0IHJlY2VpdmVyID0gQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MjtcbiAgICAgIGNvbnN0IGFtb3VudCA9IDEyMzQ7XG4gICAgICBjb25zdCBmaXJzdFJvdW5kID0gMTtcbiAgICAgIGNvbnN0IGxhc3RSb3VuZCA9IDEwO1xuICAgICAgY29uc3QgZmVlID0gMTAwMDtcbiAgICAgIGNvbnN0IHRva2VuSWQgPSAxO1xuICAgICAgY29uc3Qge1xuICAgICAgICBuZXR3b3JrczogeyB0ZXN0bmV0IH0sXG4gICAgICB9ID0gQWxnb1Jlc291cmNlcztcbiAgICAgIGNvbnN0IHsgZ2VuZXNpc0hhc2gsIGdlbmVzaXNJRCB9ID0gdGVzdG5ldDtcblxuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eG5CdWlsZGVyXG4gICAgICAgIC5mZWUoeyBmZWU6IGZlZS50b1N0cmluZygpIH0pXG4gICAgICAgIC5pc0ZsYXRGZWUodHJ1ZSlcbiAgICAgICAgLmZpcnN0Um91bmQoZmlyc3RSb3VuZClcbiAgICAgICAgLmxhc3RSb3VuZChsYXN0Um91bmQpXG4gICAgICAgIC50ZXN0bmV0KClcbiAgICAgICAgLnNlbmRlcih7IGFkZHJlc3M6IHNlbmRlci5hZGRyZXNzIH0pXG4gICAgICAgIC50b2tlbklkKHRva2VuSWQpXG4gICAgICAgIC5hbW91bnQoYW1vdW50KVxuICAgICAgICAudG8oeyBhZGRyZXNzOiByZWNlaXZlci5hZGRyZXNzIH0pXG4gICAgICAgIC5idWlsZCgpO1xuICAgICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG5cbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmZyb20sIHNlbmRlci5hZGRyZXNzKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLnRvLCByZWNlaXZlci5hZGRyZXNzKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmZlZSwgZmVlKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmZpcnN0Um91bmQsIGZpcnN0Um91bmQpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ubGFzdFJvdW5kLCBsYXN0Um91bmQpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24udG9rZW5JZCwgdG9rZW5JZCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5hbW91bnQsIGFtb3VudC50b1N0cmluZygpKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmdlbmVzaXNJRCwgZ2VuZXNpc0lELnRvU3RyaW5nKCkpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uZ2VuZXNpc0hhc2gudG9TdHJpbmcoJ2Jhc2U2NCcpLCBnZW5lc2lzSGFzaCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGJ1aWxkIGEgdmFsaWQgZGlzYWJsZSB0b2tlbiB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGZpcnN0Um91bmQgPSAxNjc7XG4gICAgICBjb25zdCBsYXN0Um91bmQgPSAxMTY3O1xuICAgICAgY29uc3QgZmVlID0gMTAwMDtcbiAgICAgIGNvbnN0IHRva2VuSWQgPSAxO1xuICAgICAgY29uc3QgYW1vdW50ID0gJzAnO1xuICAgICAgY29uc3Qgbm90ZSA9IG5ldyBVaW50OEFycmF5KEJ1ZmZlci5mcm9tKCdub3RlJywgJ3V0Zi04JykpO1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICdSSUpWTERZV0FTWlpOR09TUU5PSzdITjZKTkZMTU1aM0ZGQkJGRzJOTlJPTTVDRTc0NERBSlNQWko0JztcbiAgICAgIGNvbnN0IGNsb3NlUmVtYWluZGVyVG8gPSAnU1A3NDVKSlI0S1BSUUVYSlpIVklFTjczNkxZVEwyVDJERk1HM09JSUZKQlY2Nks3M1BITk1EQ1pWTSc7XG5cbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhuQnVpbGRlclxuICAgICAgICAuZmVlKHsgZmVlOiBmZWUudG9TdHJpbmcoKSB9KVxuICAgICAgICAuaXNGbGF0RmVlKHRydWUpXG4gICAgICAgIC5maXJzdFJvdW5kKGZpcnN0Um91bmQpXG4gICAgICAgIC5sYXN0Um91bmQobGFzdFJvdW5kKVxuICAgICAgICAudGVzdG5ldCgpXG4gICAgICAgIC5jbG9zZVJlbWFpbmRlclRvKHsgYWRkcmVzczogY2xvc2VSZW1haW5kZXJUbyB9KVxuICAgICAgICAuc2VuZGVyKHsgYWRkcmVzczogYWRkcmVzcyB9KVxuICAgICAgICAudG9rZW5JZCh0b2tlbklkKVxuICAgICAgICAuYW1vdW50KEJpZ0ludChhbW91bnQpKVxuICAgICAgICAudG8oeyBhZGRyZXNzOiBhZGRyZXNzIH0pXG4gICAgICAgIC5ub3RlKG5vdGUpXG4gICAgICAgIC5idWlsZCgpO1xuXG4gICAgICBjb25zdCB0eEhleCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICBjb25zdCB0eEluZm8gPSB0eC50b0pzb24oKTtcblxuICAgICAgc2hvdWxkLmV4aXN0cyh0eEhleCk7XG5cbiAgICAgIHR4SW5mby50by5zaG91bGQuZXF1YWwoYWRkcmVzcyk7XG4gICAgICB0eEluZm8uZnJvbS5zaG91bGQuZXF1YWwoYWRkcmVzcyk7XG4gICAgICB0eEluZm8uY2xvc2VSZW1haW5kZXJUby5zaG91bGQuZXF1YWwoY2xvc2VSZW1haW5kZXJUbyk7XG4gICAgICB0eEluZm8uYW1vdW50LnNob3VsZC5lcXVhbCgnMCcpO1xuICAgICAgdHhJbmZvLmZpcnN0Um91bmQuc2hvdWxkLmVxdWFsKDE2Nyk7XG4gICAgICB0eEluZm8udG9rZW5JZC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICB0eEluZm8uZmVlLnNob3VsZC5lcXVhbCgxMDAwKTtcbiAgICAgIHR4SW5mby5ub3RlLnNob3VsZC5lcXVhbChub3RlKTtcbiAgICAgIHR4SW5mby5sYXN0Um91bmQuc2hvdWxkLmVxdWFsKDExNjcpO1xuICAgICAgdHhJbmZvLmdlbmVzaXNJRC5zaG91bGQuZXF1YWwoJ3Rlc3RuZXQtdjEuMCcpO1xuICAgICAgdHhJbmZvLmdlbmVzaXNIYXNoLnNob3VsZC5lcXVhbCgnU0dPMUdLU3p5RTdJRVBJdFR4Q0J5dzl4OEZtbnJDRGV4aTkvY09VSk9pST0nKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IGJ1aWxkIGEgdG9rZW4gdHJhbnNhY3Rpb24gd2l0aCBhbiBpbnZhbGlkIHNlbmRlciBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd3JvbmdBZGRyZXNzID0gJ1JJSlZMRFlXQVNaWk5HT1NRTk9LN0hONkpORkxNTVozRkZCQkZHMk5OUk9NNUNFNzQ0REFKU1BaSic7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4bkJ1aWxkZXIudGVzdG5ldCgpO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4gdHguc2VuZGVyKHsgYWRkcmVzczogd3JvbmdBZGRyZXNzIH0pLFxuICAgICAgICBuZXcgUmVnRXhwKFwiVGhlIGFkZHJlc3MgJ1wiICsgd3JvbmdBZGRyZXNzICsgXCInIGlzIG5vdCBhIHdlbGwtZm9ybWVkIGFsZ29yYW5kIGFkZHJlc3NcIilcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCBidWlsZCBhIHRva2VuIHRyYW5zYWN0aW9uIHdpdGggYW4gaW52YWxpZCBjbG9zZVJlbWFpbmRlclRvIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3cm9uZ0FkZHJlc3MgPSAnUklKVkxEWVdBU1paTkdPU1FOT0s3SE42Sk5GTE1NWjNGRkJCRkcyTk5ST001Q0U3NDREQUpTUFpKJztcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhuQnVpbGRlci50ZXN0bmV0KCk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiB0eC5jbG9zZVJlbWFpbmRlclRvKHsgYWRkcmVzczogd3JvbmdBZGRyZXNzIH0pLFxuICAgICAgICBuZXcgUmVnRXhwKFwiVGhlIGFkZHJlc3MgJ1wiICsgd3JvbmdBZGRyZXNzICsgXCInIGlzIG5vdCBhIHdlbGwtZm9ybWVkIGFsZ29yYW5kIGFkZHJlc3NcIilcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCBidWlsZCBhIHRva2VuIHRyYW5zYWN0aW9uIHdpdGggYW4gaW52YWxpZCB0byBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd3JvbmdBZGRyZXNzID0gJ1JJSlZMRFlXQVNaWk5HT1NRTk9LN0hONkpORkxNTVozRkZCQkZHMk5OUk9NNUNFNzQ0REFKU1BaSic7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4bkJ1aWxkZXIudGVzdG5ldCgpO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4gdHgudG8oeyBhZGRyZXNzOiB3cm9uZ0FkZHJlc3MgfSksXG4gICAgICAgIG5ldyBSZWdFeHAoXCJUaGUgYWRkcmVzcyAnXCIgKyB3cm9uZ0FkZHJlc3MgKyBcIicgaXMgbm90IGEgd2VsbC1mb3JtZWQgYWxnb3JhbmQgYWRkcmVzc1wiKVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYnVpbGQgYSB2YWxpZCBlbmFibGUgdG9rZW4gdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBmaXJzdFJvdW5kID0gMTY3O1xuICAgICAgY29uc3QgbGFzdFJvdW5kID0gMTE2NztcbiAgICAgIGNvbnN0IGZlZSA9IDEwMDA7XG4gICAgICBjb25zdCB0b2tlbklkID0gMTtcbiAgICAgIGNvbnN0IGFtb3VudCA9ICcwJztcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSAnUklKVkxEWVdBU1paTkdPU1FOT0s3SE42Sk5GTE1NWjNGRkJCRkcyTk5ST001Q0U3NDREQUpTUFpKNCc7XG5cbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhuQnVpbGRlclxuICAgICAgICAuZmVlKHsgZmVlOiBmZWUudG9TdHJpbmcoKSB9KVxuICAgICAgICAuaXNGbGF0RmVlKHRydWUpXG4gICAgICAgIC5maXJzdFJvdW5kKGZpcnN0Um91bmQpXG4gICAgICAgIC5sYXN0Um91bmQobGFzdFJvdW5kKVxuICAgICAgICAudGVzdG5ldCgpXG4gICAgICAgIC5zZW5kZXIoeyBhZGRyZXNzOiBhZGRyZXNzIH0pXG4gICAgICAgIC50b2tlbklkKHRva2VuSWQpXG4gICAgICAgIC5hbW91bnQoQmlnSW50KGFtb3VudCkpXG4gICAgICAgIC50byh7IGFkZHJlc3M6IGFkZHJlc3MgfSlcbiAgICAgICAgLmJ1aWxkKCk7XG5cbiAgICAgIGNvbnN0IHR4SGV4ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICAgIGNvbnN0IHR4SW5mbyA9IHR4LnRvSnNvbigpO1xuXG4gICAgICBzaG91bGQuZXhpc3RzKHR4SGV4KTtcblxuICAgICAgdHhJbmZvLnRvLnNob3VsZC5lcXVhbChhZGRyZXNzKTtcbiAgICAgIHR4SW5mby5mcm9tLnNob3VsZC5lcXVhbChhZGRyZXNzKTtcbiAgICAgIHR4SW5mby5hbW91bnQuc2hvdWxkLmVxdWFsKCcwJyk7XG4gICAgICB0eEluZm8uZmlyc3RSb3VuZC5zaG91bGQuZXF1YWwoMTY3KTtcbiAgICAgIHR4SW5mby50b2tlbklkLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIHR4SW5mby5mZWUuc2hvdWxkLmVxdWFsKDEwMDApO1xuICAgICAgdHhJbmZvLmxhc3RSb3VuZC5zaG91bGQuZXF1YWwoMTE2Nyk7XG4gICAgICB0eEluZm8uZ2VuZXNpc0lELnNob3VsZC5lcXVhbCgndGVzdG5ldC12MS4wJyk7XG4gICAgICB0eEluZm8uZ2VuZXNpc0hhc2guc2hvdWxkLmVxdWFsKCdTR08xR0tTenlFN0lFUEl0VHhDQnl3OXg4Rm1uckNEZXhpOS9jT1VKT2lJPScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBidWlsZCBhIHZhbGlkIGVuYWJsZSB0b2tlbiB0cmFuc2FjdGlvbiBhbmQgcmUtY2FsY3VhbHRlIG1pbmltdW0gZmVlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZmlyc3RSb3VuZCA9IDE2NztcbiAgICAgIGNvbnN0IGxhc3RSb3VuZCA9IDExNjc7XG4gICAgICBjb25zdCBmZWUgPSAxMDAwO1xuICAgICAgY29uc3QgdG9rZW5JZCA9IDE7XG4gICAgICBjb25zdCBhbW91bnQgPSAnMCc7XG4gICAgICBjb25zdCBhZGRyZXNzID0gJ1JJSlZMRFlXQVNaWk5HT1NRTk9LN0hONkpORkxNTVozRkZCQkZHMk5OUk9NNUNFNzQ0REFKU1BaSjQnO1xuXG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4bkJ1aWxkZXJcbiAgICAgICAgLmZlZSh7IGZlZTogZmVlLnRvU3RyaW5nKCkgfSlcbiAgICAgICAgLmlzRmxhdEZlZSh0cnVlKVxuICAgICAgICAuZmlyc3RSb3VuZChmaXJzdFJvdW5kKVxuICAgICAgICAubGFzdFJvdW5kKGxhc3RSb3VuZClcbiAgICAgICAgLnRlc3RuZXQoKVxuICAgICAgICAuc2VuZGVyKHsgYWRkcmVzczogYWRkcmVzcyB9KVxuICAgICAgICAudG9rZW5JZCh0b2tlbklkKVxuICAgICAgICAuYW1vdW50KEJpZ0ludChhbW91bnQpKVxuICAgICAgICAudG8oeyBhZGRyZXNzOiBhZGRyZXNzIH0pXG4gICAgICAgIC5idWlsZCgpO1xuXG4gICAgICBjb25zdCB0eEhleCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICBjb25zdCB0eEluZm8gPSB0eC50b0pzb24oKTtcblxuICAgICAgc2hvdWxkLmV4aXN0cyh0eEhleCk7XG5cbiAgICAgIHR4SW5mby50by5zaG91bGQuZXF1YWwoYWRkcmVzcyk7XG4gICAgICB0eEluZm8uZnJvbS5zaG91bGQuZXF1YWwoYWRkcmVzcyk7XG4gICAgICB0eEluZm8uYW1vdW50LnNob3VsZC5lcXVhbCgnMCcpO1xuICAgICAgdHhJbmZvLmZpcnN0Um91bmQuc2hvdWxkLmVxdWFsKDE2Nyk7XG4gICAgICB0eEluZm8udG9rZW5JZC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICB0eEluZm8uZmVlLnNob3VsZC5lcXVhbCgxMDAwKTtcbiAgICAgIHR4SW5mby5sYXN0Um91bmQuc2hvdWxkLmVxdWFsKDExNjcpO1xuICAgICAgdHhJbmZvLmdlbmVzaXNJRC5zaG91bGQuZXF1YWwoJ3Rlc3RuZXQtdjEuMCcpO1xuICAgICAgdHhJbmZvLmdlbmVzaXNIYXNoLnNob3VsZC5lcXVhbCgnU0dPMUdLU3p5RTdJRVBJdFR4Q0J5dzl4OEZtbnJDRGV4aTkvY09VSk9pST0nKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYnVpbGQgYSB2YWxpZCBkaXNhYmxlIHRva2VuIHRyYW5zYWN0aW9uIGFuZCByZS1jYWxjdWFsdGUgbWluaW11bSBmZWUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBmaXJzdFJvdW5kID0gMTY3O1xuICAgICAgY29uc3QgbGFzdFJvdW5kID0gMTE2NztcbiAgICAgIGNvbnN0IGZlZSA9IDEwMDA7XG4gICAgICBjb25zdCB0b2tlbklkID0gMTtcbiAgICAgIGNvbnN0IGNsb3NlUmVtYWluZGVyVG8gPSAnU1A3NDVKSlI0S1BSUUVYSlpIVklFTjczNkxZVEwyVDJERk1HM09JSUZKQlY2Nks3M1BITk1EQ1pWTSc7XG4gICAgICBjb25zdCBhbW91bnQgPSAnMCc7XG4gICAgICBjb25zdCBhZGRyZXNzID0gJ1JJSlZMRFlXQVNaWk5HT1NRTk9LN0hONkpORkxNTVozRkZCQkZHMk5OUk9NNUNFNzQ0REFKU1BaSjQnO1xuXG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4bkJ1aWxkZXJcbiAgICAgICAgLmZlZSh7IGZlZTogZmVlLnRvU3RyaW5nKCkgfSlcbiAgICAgICAgLmlzRmxhdEZlZSh0cnVlKVxuICAgICAgICAuZmlyc3RSb3VuZChmaXJzdFJvdW5kKVxuICAgICAgICAubGFzdFJvdW5kKGxhc3RSb3VuZClcbiAgICAgICAgLnRlc3RuZXQoKVxuICAgICAgICAuY2xvc2VSZW1haW5kZXJUbyh7IGFkZHJlc3M6IGNsb3NlUmVtYWluZGVyVG8gfSlcbiAgICAgICAgLnNlbmRlcih7IGFkZHJlc3M6IGFkZHJlc3MgfSlcbiAgICAgICAgLnRva2VuSWQodG9rZW5JZClcbiAgICAgICAgLmFtb3VudChCaWdJbnQoYW1vdW50KSlcbiAgICAgICAgLnRvKHsgYWRkcmVzczogYWRkcmVzcyB9KVxuICAgICAgICAuYnVpbGQoKTtcblxuICAgICAgY29uc3QgdHhIZXggPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgICAgY29uc3QgdHhJbmZvID0gdHgudG9Kc29uKCk7XG5cbiAgICAgIHNob3VsZC5leGlzdHModHhIZXgpO1xuXG4gICAgICB0eEluZm8udG8uc2hvdWxkLmVxdWFsKGFkZHJlc3MpO1xuICAgICAgdHhJbmZvLmZyb20uc2hvdWxkLmVxdWFsKGFkZHJlc3MpO1xuICAgICAgdHhJbmZvLmFtb3VudC5zaG91bGQuZXF1YWwoJzAnKTtcbiAgICAgIHR4SW5mby5maXJzdFJvdW5kLnNob3VsZC5lcXVhbCgxNjcpO1xuICAgICAgdHhJbmZvLnRva2VuSWQuc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgdHhJbmZvLmZlZS5zaG91bGQuZXF1YWwoMTAwMCk7XG4gICAgICB0eEluZm8uY2xvc2VSZW1haW5kZXJUby5zaG91bGQuZXF1YWwoY2xvc2VSZW1haW5kZXJUbyk7XG4gICAgICB0eEluZm8ubGFzdFJvdW5kLnNob3VsZC5lcXVhbCgxMTY3KTtcbiAgICAgIHR4SW5mby5nZW5lc2lzSUQuc2hvdWxkLmVxdWFsKCd0ZXN0bmV0LXYxLjAnKTtcbiAgICAgIHR4SW5mby5nZW5lc2lzSGFzaC5zaG91bGQuZXF1YWwoJ1NHTzFHS1N6eUU3SUVQSXRUeENCeXc5eDhGbW5yQ0RleGk5L2NPVUpPaUk9Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGRlY29kZSBhbiB1bnNpZ25lZCBhc3NldCB0cmFuc2ZlciB0cmFuc2FjdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgIHR4bkJ1aWxkZXIuZnJvbShyYXdUeC5hc3NldFRyYW5zZmVyLnVuc2lnbmVkKTtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhuQnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG5cbiAgICAgIGNvbnN0IHNlbmRlciA9IEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDE7XG4gICAgICBjb25zdCByZWNlaXZlciA9IEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDI7XG5cbiAgICAgIHNob3VsZC5kZWVwRXF1YWwoQnVmZmVyLmZyb20odHgudG9Ccm9hZGNhc3RGb3JtYXQoKSkudG9TdHJpbmcoJ2hleCcpLCBBbGdvUmVzb3VyY2VzLnJhd1R4LmFzc2V0VHJhbnNmZXIudW5zaWduZWQpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uZnJvbSwgc2VuZGVyLmFkZHJlc3MpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24udG8sIHJlY2VpdmVyLmFkZHJlc3MpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uYW1vdW50LCAnMTAwMCcpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uZmlyc3RSb3VuZCwgMSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5sYXN0Um91bmQsIDEwKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLnRva2VuSWQsIDEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBkZWNvZGUgYSBzaWduZWQgYXNzZXQgdHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICB0eG5CdWlsZGVyLmZyb20ocmF3VHguYXNzZXRUcmFuc2Zlci5zaWduZWQpO1xuXG4gICAgICB0eG5CdWlsZGVyLm51bWJlck9mU2lnbmVycygxKS5zaWduKHsga2V5OiBhY2NvdW50MS5wcnZLZXkgfSk7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4bkJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuXG4gICAgICBjb25zdCBzZW5kZXIgPSBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQxO1xuICAgICAgY29uc3QgcmVjZWl2ZXIgPSBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQyO1xuXG4gICAgICBzaG91bGQuZGVlcEVxdWFsKEJ1ZmZlci5mcm9tKHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCkpLnRvU3RyaW5nKCdoZXgnKSwgQWxnb1Jlc291cmNlcy5yYXdUeC5hc3NldFRyYW5zZmVyLnNpZ25lZCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5mcm9tLCBzZW5kZXIuYWRkcmVzcyk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi50bywgcmVjZWl2ZXIuYWRkcmVzcyk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5hbW91bnQsICcxMDAwMDAwMDAwMDAwMDAwMDAwMCcpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uZmlyc3RSb3VuZCwgMSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5sYXN0Um91bmQsIDEwKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLnRva2VuSWQsIDEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIGRlY29kZSBvdGhlciB0eXBlcyBvZiB0cmFuc2FjdGlvbnMnLCAoKSA9PiB7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHR4bkJ1aWxkZXIuZnJvbShyYXdUeC5rZXlSZWcudW5zaWduZWQpLCAvSW52YWxpZCBUcmFuc2FjdGlvbiBUeXBlOiBrZXlyZWcuIEV4cGVjdGVkIGF4ZmVyLyk7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHR4bkJ1aWxkZXIuZnJvbShyYXdUeC5rZXlSZWcuc2lnbmVkKSwgL0ludmFsaWQgVHJhbnNhY3Rpb24gVHlwZToga2V5cmVnLiBFeHBlY3RlZCBheGZlci8pO1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB0eG5CdWlsZGVyLmZyb20ocmF3VHgudHJhbnNmZXIudW5zaWduZWQpLCAvSW52YWxpZCBUcmFuc2FjdGlvbiBUeXBlOiBwYXkuIEV4cGVjdGVkIGF4ZmVyLyk7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHR4bkJ1aWxkZXIuZnJvbShyYXdUeC50cmFuc2Zlci5zaWduZWQpLCAvSW52YWxpZCBUcmFuc2FjdGlvbiBUeXBlOiBwYXkuIEV4cGVjdGVkIGF4ZmVyLyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdhbGxvd2xpc3QgYXNzZXQgdHhuJywgKCkgPT4ge1xuICAgIHRlc3QoJ2FsbG93bGlzdCBwYXJhbWV0ZXJzIGFyZSBzZXQgY29ycmVjdGx5JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdG9rZW5JZCA9IDEyMztcbiAgICAgIGNvbnN0IHNlbmRlciA9IGFjY291bnQxLmFkZHJlc3M7XG4gICAgICBjb25zdCB7XG4gICAgICAgIG5ldHdvcmtzOiB7IHRlc3RuZXQgfSxcbiAgICAgIH0gPSBBbGdvUmVzb3VyY2VzO1xuICAgICAgY29uc3QgeyBnZW5lc2lzSGFzaCwgZ2VuZXNpc0lEIH0gPSB0ZXN0bmV0O1xuICAgICAgdHhuQnVpbGRlclxuICAgICAgICAuYWxsb3dMaXN0QXNzZXQodG9rZW5JZCwgeyBhZGRyZXNzOiBzZW5kZXIgfSlcbiAgICAgICAgLmZpcnN0Um91bmQoMSlcbiAgICAgICAgLmxhc3RSb3VuZCgxMClcbiAgICAgICAgLnRlc3RuZXQoKVxuICAgICAgICAubnVtYmVyT2ZSZXF1aXJlZFNpZ25lcnMoMSk7XG5cbiAgICAgIHR4bkJ1aWxkZXIuc2lnbih7IGtleTogYWNjb3VudDEucHJ2S2V5IH0pO1xuXG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4bkJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuXG4gICAgICBzaG91bGQuZXF1YWwodHhKc29uLmZyb20sIGFjY291bnQxLmFkZHJlc3MpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4SnNvbi50bywgYWNjb3VudDEuYWRkcmVzcyk7XG4gICAgICBzaG91bGQuZXF1YWwodHhKc29uLnRva2VuSWQsIHRva2VuSWQpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4SnNvbi5mZWUsIDEwMDApO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uZ2VuZXNpc0lELCBnZW5lc2lzSUQudG9TdHJpbmcoKSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5nZW5lc2lzSGFzaC50b1N0cmluZygnYmFzZTY0JyksIGdlbmVzaXNIYXNoKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==

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


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