PHP WebShell

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

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

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const node_test_1 = require("node:test");
const assert_1 = __importDefault(require("assert"));
const sdk_core_1 = require("@bitgo/sdk-core");
const statics_1 = require("@bitgo/statics");
const bignumber_js_1 = __importDefault(require("bignumber.js"));
const builder_1 = require("../../../src/lib/builder");
const resources_1 = require("../../resources");
(0, node_test_1.describe)('Trx Contract call Builder', () => {
    const initTxBuilder = () => {
        const builder = (0, builder_1.getBuilder)('ttrx').getContractCallBuilder();
        builder
            .source({ address: resources_1.PARTICIPANTS.custodian.address })
            .to({ address: resources_1.CONTRACTS.factory })
            .block({ number: resources_1.BLOCK_NUMBER, hash: resources_1.BLOCK_HASH })
            .fee({ feeLimit: resources_1.FEE_LIMIT });
        return builder;
    };
    (0, node_test_1.describe)('Contract Call builder', () => {
        (0, node_test_1.describe)('should build', () => {
            (0, node_test_1.describe)('non serialized transactions', () => {
                (0, node_test_1.it)('a signed contract call transaction', async () => {
                    const txBuilder = initTxBuilder();
                    txBuilder.data(resources_1.MINT_CONFIRM_DATA).sign({ key: resources_1.PARTICIPANTS.custodian.pk });
                    const tx = await txBuilder.build();
                    tx.toJson();
                });
            });
            (0, node_test_1.describe)('serialized transactions', () => {
                (0, node_test_1.it)('a transaction signed multiple times', async () => {
                    const timestamp = Date.now();
                    const txBuilder = initTxBuilder();
                    txBuilder.data(resources_1.MINT_CONFIRM_DATA);
                    txBuilder.timestamp(timestamp);
                    txBuilder.expiration(timestamp + resources_1.EXPIRATION);
                    const tx = await txBuilder.build();
                    let txJson = tx.toJson();
                    let rawData = txJson.raw_data;
                    assert_1.default.deepStrictEqual(rawData.contract, resources_1.TX_CONTRACT);
                    assert_1.default.equal(txJson.signature.length, 0);
                    const txBuilder2 = (0, builder_1.getBuilder)('ttrx').from(tx.toJson());
                    txBuilder2.sign({ key: resources_1.PARTICIPANTS.custodian.pk });
                    const tx2 = await txBuilder2.build();
                    txJson = tx2.toJson();
                    rawData = txJson.raw_data;
                    assert_1.default.deepStrictEqual(rawData.contract, resources_1.TX_CONTRACT);
                    assert_1.default.equal(txJson.signature.length, 1);
                    const txBuilder3 = (0, builder_1.getBuilder)('ttrx').from(tx2.toJson());
                    txBuilder3.sign({ key: resources_1.PARTICIPANTS.from.pk });
                    const tx3 = await txBuilder3.build();
                    txJson = tx3.toJson();
                    rawData = txJson.raw_data;
                    assert_1.default.deepStrictEqual(rawData.contract, resources_1.TX_CONTRACT);
                    assert_1.default.equal(txJson.signature.length, 2);
                    const txBuilder4 = (0, builder_1.getBuilder)('ttrx').from(tx3.toJson());
                    txBuilder4.sign({ key: resources_1.PARTICIPANTS.multisig.pk });
                    const tx4 = await txBuilder4.build();
                    assert_1.default.equal(tx4.inputs.length, 1);
                    assert_1.default.equal(tx4.inputs[0].address, resources_1.PARTICIPANTS.custodian.address);
                    if (tx4.inputs[0].contractAddress) {
                        assert_1.default.equal(tx4.inputs[0].contractAddress, resources_1.CONTRACTS.factory);
                    }
                    if (tx4.inputs[0].data) {
                        assert_1.default.equal(tx4.inputs[0].data, 'K/kLqhJzFAw+G1dWskLMiM18TdimG/hctcHdX1C6YeBmtToV');
                    }
                    assert_1.default.equal(tx4.inputs[0].value, '0');
                    assert_1.default.equal(tx4.outputs[0].value, '0');
                    assert_1.default.equal(tx4.outputs[0].address, resources_1.PARTICIPANTS.custodian.address);
                    txJson = tx4.toJson();
                    rawData = txJson.raw_data;
                    assert_1.default.deepStrictEqual(rawData.contract, resources_1.TX_CONTRACT);
                    assert_1.default.equal(txJson.signature.length, 3);
                    assert_1.default.equal(rawData.fee_limit, resources_1.FEE_LIMIT);
                    assert_1.default.equal(rawData.expiration, timestamp + resources_1.EXPIRATION);
                    assert_1.default.equal(rawData.timestamp, timestamp);
                });
                (0, node_test_1.it)('an unsigned transaction from a string and from a JSON', async () => {
                    const timestamp = Date.now();
                    const txBuilder = initTxBuilder();
                    txBuilder.data(resources_1.MINT_CONFIRM_DATA);
                    txBuilder.timestamp(timestamp);
                    txBuilder.expiration(timestamp + 40000);
                    const tx = await txBuilder.build();
                    const txBuilder2 = (0, builder_1.getBuilder)('ttrx').from(tx.toBroadcastFormat());
                    txBuilder2.sign({ key: resources_1.PARTICIPANTS.custodian.pk });
                    const tx2 = await txBuilder2.build();
                    const txBuilder3 = (0, builder_1.getBuilder)('ttrx').from(tx.toJson());
                    txBuilder3.sign({ key: resources_1.PARTICIPANTS.custodian.pk });
                    const tx3 = await txBuilder3.build();
                    assert_1.default.deepStrictEqual(tx2, tx3);
                });
                (0, node_test_1.it)('an unsigned transaction with extended duration', async () => {
                    const timestamp = Date.now();
                    const expiration = timestamp + resources_1.EXPIRATION;
                    const extension = 60000;
                    const txBuilder = initTxBuilder();
                    txBuilder.data(resources_1.MINT_CONFIRM_DATA);
                    txBuilder.timestamp(timestamp);
                    txBuilder.expiration(expiration);
                    const tx = await txBuilder.build();
                    const txBuilder2 = (0, builder_1.getBuilder)('ttrx').from(tx.toBroadcastFormat());
                    txBuilder2.extendValidTo(extension);
                    txBuilder2.sign({ key: resources_1.PARTICIPANTS.custodian.pk });
                    const tx2 = await txBuilder2.build();
                    assert_1.default.equal(tx2.inputs.length, 1);
                    assert_1.default.equal(tx2.inputs[0].address, resources_1.PARTICIPANTS.custodian.address);
                    if (tx2.inputs[0].contractAddress) {
                        assert_1.default.equal(tx2.inputs[0].contractAddress, resources_1.CONTRACTS.factory);
                    }
                    if (tx2.inputs[0].data) {
                        assert_1.default.equal(tx2.inputs[0].data, 'K/kLqhJzFAw+G1dWskLMiM18TdimG/hctcHdX1C6YeBmtToV');
                    }
                    assert_1.default.equal(tx2.inputs[0].value, '0');
                    assert_1.default.equal(tx2.outputs[0].value, '0');
                    assert_1.default.equal(tx2.outputs[0].address, resources_1.PARTICIPANTS.custodian.address);
                    const txJson = tx2.toJson();
                    assert_1.default.equal(txJson.raw_data.expiration, expiration + extension);
                });
                (0, node_test_1.it)('a transaction with correct inputs', async () => {
                    const timestamp = Date.now();
                    const txBuilder = initTxBuilder();
                    txBuilder.data(resources_1.MINT_CONFIRM_DATA);
                    txBuilder.timestamp(timestamp);
                    txBuilder.expiration(timestamp + 40000);
                    const tx = (await txBuilder.build());
                    assert_1.default.equal(tx.type, sdk_core_1.TransactionType.ContractCall);
                    assert_1.default.equal(tx.inputs.length, 1);
                    assert_1.default.equal(tx.inputs[0].address, resources_1.PARTICIPANTS.custodian.address);
                    if (tx.inputs[0].contractAddress) {
                        assert_1.default.equal(tx.inputs[0].contractAddress, resources_1.CONTRACTS.factory);
                    }
                    if (tx.inputs[0].data) {
                        assert_1.default.equal(tx.inputs[0].data, 'K/kLqhJzFAw+G1dWskLMiM18TdimG/hctcHdX1C6YeBmtToV');
                    }
                    assert_1.default.equal(tx.inputs[0].value, '0');
                    assert_1.default.equal(tx.outputs[0].value, '0');
                    assert_1.default.equal(tx.outputs[0].address, resources_1.PARTICIPANTS.custodian.address);
                });
            });
        });
        (0, node_test_1.describe)('should fail to build', () => {
            (0, node_test_1.it)('a transaction with wrong data', async () => {
                const txBuilder = initTxBuilder();
                assert_1.default.throws(() => {
                    txBuilder.data('addMintRequest()');
                }, (e) => e.message === 'addMintRequest() is not a valid hex string.');
            });
            (0, node_test_1.it)('a transaction with duplicate signatures', async () => {
                const txBuilder = initTxBuilder();
                txBuilder.data(resources_1.MINT_CONFIRM_DATA);
                txBuilder.sign({ key: resources_1.PARTICIPANTS.custodian.pk });
                assert_1.default.throws(() => {
                    txBuilder.sign({ key: resources_1.PARTICIPANTS.custodian.pk });
                }, (e) => e.message === 'Duplicated key');
                const tx = await txBuilder.build();
                const txBuilder2 = (0, builder_1.getBuilder)('ttrx').from(tx.toBroadcastFormat());
                txBuilder2.sign({ key: resources_1.PARTICIPANTS.custodian.pk });
                assert_1.default.rejects(txBuilder2.build(), {
                    message: 'Transaction signing did not return an additional signature.',
                });
            });
            (0, node_test_1.it)('an invalid raw transaction', () => {
                assert_1.default.throws(() => {
                    (0, builder_1.getBuilder)('ttrx').from('an invalid raw transaction');
                }, (e) => e.message === 'There was error in parsing the JSON string');
            });
        });
    });
    (0, node_test_1.describe)('Should validate ', () => {
        (0, node_test_1.it)('a valid expiration', async () => {
            const now = Date.now();
            const expiration = now + resources_1.EXPIRATION;
            const txBuilder = initTxBuilder();
            txBuilder.data(resources_1.MINT_CONFIRM_DATA);
            txBuilder.timestamp(now);
            txBuilder.expiration(expiration + 1000);
            txBuilder.expiration(expiration);
            const tx = await txBuilder.build();
            const txJson = tx.toJson();
            assert_1.default.equal(txJson.raw_data.expiration, expiration);
        });
        (0, node_test_1.it)('an expiration greater than one year', async () => {
            const now = Date.now();
            const txBuilder = initTxBuilder();
            txBuilder.data(resources_1.MINT_CONFIRM_DATA);
            txBuilder.timestamp(now);
            assert_1.default.throws(() => {
                txBuilder.expiration(now + 31536000001);
            }, (e) => e.message === 'Expiration must not be greater than one year');
        });
        (0, node_test_1.it)('an expiration less than the current date', async () => {
            const now = Date.now();
            const txBuilder = initTxBuilder();
            txBuilder.timestamp(now - 2000);
            txBuilder.data(resources_1.MINT_CONFIRM_DATA);
            assert_1.default.throws(() => {
                txBuilder.expiration(now - 1000);
            }, (e) => e.message === 'Expiration must be greater than current time');
        });
        (0, node_test_1.it)('an expiration less than the timestamp', async () => {
            const now = Date.now();
            const txBuilder = initTxBuilder();
            txBuilder.data(resources_1.MINT_CONFIRM_DATA);
            txBuilder.timestamp(now + 2000);
            assert_1.default.throws(() => {
                txBuilder.expiration(now + 1000);
            }, (e) => e.message === 'Expiration must be greater than timestamp');
        });
        (0, node_test_1.it)('an expiration set after build', async () => {
            const now = Date.now();
            const expiration = now + resources_1.EXPIRATION;
            const txBuilder = initTxBuilder();
            txBuilder.data(resources_1.MINT_CONFIRM_DATA);
            await txBuilder.build();
            assert_1.default.throws(() => {
                txBuilder.expiration(expiration);
            }, (e) => e.message === 'Expiration is already set, it can only be extended');
        });
        (0, node_test_1.it)('an expiration set after deserializing', async () => {
            const now = Date.now();
            const expiration = now + resources_1.EXPIRATION;
            const txBuilder = initTxBuilder();
            txBuilder.data(resources_1.MINT_CONFIRM_DATA);
            const tx = await txBuilder.build();
            const txBuilder2 = (0, builder_1.getBuilder)('ttrx').from(tx.toBroadcastFormat());
            assert_1.default.throws(() => {
                txBuilder2.expiration(expiration);
            }, (e) => e.message === 'Expiration is already set, it can only be extended');
        });
        (0, node_test_1.it)('an extension without a set expiration', async () => {
            const txBuilder = initTxBuilder();
            txBuilder.data(resources_1.MINT_CONFIRM_DATA);
            assert_1.default.throws(() => {
                txBuilder.extendValidTo(20000);
            }, (e) => e.message === 'There is not expiration to extend');
        });
        (0, node_test_1.it)('a zero millisecond extension', async () => {
            const txBuilder = initTxBuilder();
            txBuilder.data(resources_1.MINT_CONFIRM_DATA);
            const expiration = Date.now() + resources_1.EXPIRATION;
            txBuilder.expiration(expiration);
            const tx = await txBuilder.build();
            const txBuilder2 = (0, builder_1.getBuilder)('ttrx').from(tx.toBroadcastFormat());
            assert_1.default.throws(() => {
                txBuilder2.extendValidTo(0);
            }, (e) => e.message === 'Value cannot be below zero');
        });
        (0, node_test_1.it)('an extension grater than one year', async () => {
            const txBuilder = initTxBuilder();
            txBuilder.data(resources_1.MINT_CONFIRM_DATA);
            const expiration = Date.now() + resources_1.EXPIRATION;
            txBuilder.expiration(expiration);
            const tx = await txBuilder.build();
            const txBuilder2 = (0, builder_1.getBuilder)('ttrx').from(tx.toBroadcastFormat());
            assert_1.default.throws(() => {
                txBuilder2.extendValidTo(31536000001);
            }, (e) => e.message === 'The expiration cannot be extended more than one year');
        });
        (0, node_test_1.it)('an extension after signing', async () => {
            const txBuilder = initTxBuilder();
            txBuilder.data(resources_1.MINT_CONFIRM_DATA);
            txBuilder.sign({ key: resources_1.PARTICIPANTS.custodian.pk });
            const tx = await txBuilder.build();
            const txBuilder2 = (0, builder_1.getBuilder)('ttrx').from(tx.toBroadcastFormat());
            assert_1.default.throws(() => {
                txBuilder2.extendValidTo(20000);
            }, (e) => e.message === 'Cannot extend a signed transaction');
        });
        (0, node_test_1.it)('fee limit', async () => {
            const txBuilder = initTxBuilder();
            txBuilder.data(resources_1.MINT_CONFIRM_DATA);
            assert_1.default.throws(() => {
                txBuilder.fee({ feeLimit: 'not a number' });
            }, (e) => e.message === 'Invalid fee limit value');
            assert_1.default.throws(() => {
                txBuilder.fee({ feeLimit: '-15000' });
            }, (e) => e.message === 'Invalid fee limit value');
            assert_1.default.throws(() => {
                const tronNetwork = statics_1.coins.get('ttrx').network;
                txBuilder.fee({ feeLimit: new bignumber_js_1.default(tronNetwork.maxFeeLimit).plus(1).toString() });
            }, (e) => e.message === 'Invalid fee limit value');
        });
        (0, node_test_1.it)('transaction mandatory fields', async () => {
            const txBuilder = (0, builder_1.getBuilder)('ttrx').getContractCallBuilder();
            await assert_1.default.rejects(txBuilder.build(), {
                message: 'Missing parameter: data',
            });
            txBuilder.data(resources_1.MINT_CONFIRM_DATA);
            await assert_1.default.rejects(txBuilder.build(), {
                message: 'Missing parameter: source',
            });
            txBuilder.source({ address: resources_1.PARTICIPANTS.custodian.address });
            await assert_1.default.rejects(txBuilder.build(), {
                message: 'Missing parameter: contract address',
            });
            txBuilder.to({ address: resources_1.CONTRACTS.factory });
            await assert_1.default.rejects(txBuilder.build(), {
                message: 'Missing block reference information',
            });
            txBuilder.block({ number: resources_1.BLOCK_NUMBER, hash: resources_1.BLOCK_HASH });
            await assert_1.default.rejects(txBuilder.build(), {
                message: 'Missing fee',
            });
            txBuilder.fee({ feeLimit: resources_1.FEE_LIMIT });
            assert_1.default.doesNotReject(() => {
                return txBuilder.build();
            });
        });
    });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udHJhY3RDYWxsQnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvdW5pdC90cmFuc2FjdGlvbkJ1aWxkZXIvY29udHJhY3RDYWxsQnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHlDQUF5QztBQUN6QyxvREFBNEI7QUFDNUIsOENBQWtEO0FBQ2xELDRDQUFvRDtBQUNwRCxnRUFBcUM7QUFFckMsc0RBQXNEO0FBQ3RELCtDQVN5QjtBQUV6QixJQUFBLG9CQUFRLEVBQUMsMkJBQTJCLEVBQUUsR0FBRyxFQUFFO0lBQ3pDLE1BQU0sYUFBYSxHQUFHLEdBQUcsRUFBRTtRQUN6QixNQUFNLE9BQU8sR0FBSSxJQUFBLG9CQUFVLEVBQUMsTUFBTSxDQUFvQixDQUFDLHNCQUFzQixFQUFFLENBQUM7UUFDaEYsT0FBTzthQUNKLE1BQU0sQ0FBQyxFQUFFLE9BQU8sRUFBRSx3QkFBWSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQzthQUNuRCxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUscUJBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQzthQUNsQyxLQUFLLENBQUMsRUFBRSxNQUFNLEVBQUUsd0JBQVksRUFBRSxJQUFJLEVBQUUsc0JBQVUsRUFBRSxDQUFDO2FBQ2pELEdBQUcsQ0FBQyxFQUFFLFFBQVEsRUFBRSxxQkFBUyxFQUFFLENBQUMsQ0FBQztRQUVoQyxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDLENBQUM7SUFFRixJQUFBLG9CQUFRLEVBQUMsdUJBQXVCLEVBQUUsR0FBRyxFQUFFO1FBQ3JDLElBQUEsb0JBQVEsRUFBQyxjQUFjLEVBQUUsR0FBRyxFQUFFO1lBQzVCLElBQUEsb0JBQVEsRUFBQyw2QkFBNkIsRUFBRSxHQUFHLEVBQUU7Z0JBQzNDLElBQUEsY0FBRSxFQUFDLG9DQUFvQyxFQUFFLEtBQUssSUFBSSxFQUFFO29CQUNsRCxNQUFNLFNBQVMsR0FBRyxhQUFhLEVB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QUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLEVBQUU7Z0JBQ3RDLE9BQU8sRUFBRSxxQ0FBcUM7YUFDL0MsQ0FBQyxDQUFDO1lBRUgsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLE1BQU0sRUFBRSx3QkFBWSxFQUFFLElBQUksRUFBRSxzQkFBVSxFQUFFLENBQUMsQ0FBQztZQUM1RCxNQUFNLGdCQUFNLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtnQkFDdEMsT0FBTyxFQUFFLGFBQWE7YUFDdkIsQ0FBQyxDQUFDO1lBRUgsU0FBUyxDQUFDLEdBQUcsQ0FBQyxFQUFFLFFBQVEsRUFBRSxxQkFBUyxFQUFFLENBQUMsQ0FBQztZQUN2QyxnQkFBTSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUU7Z0JBQ3hCLE9BQU8sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzNCLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZGVzY3JpYmUsIGl0IH0gZnJvbSAnbm9kZTp0ZXN0JztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7IFRyYW5zYWN0aW9uVHlwZSB9IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgeyBjb2lucywgVHJvbk5ldHdvcmsgfSBmcm9tICdAYml0Z28vc3RhdGljcyc7XG5pbXBvcnQgQmlnTnVtYmVyIGZyb20gJ2JpZ251bWJlci5qcyc7XG5pbXBvcnQgeyBUcmFuc2FjdGlvbiwgV3JhcHBlZEJ1aWxkZXIgfSBmcm9tICcuLi8uLi8uLi9zcmMnO1xuaW1wb3J0IHsgZ2V0QnVpbGRlciB9IGZyb20gJy4uLy4uLy4uL3NyYy9saWIvYnVpbGRlcic7XG5pbXBvcnQge1xuICBQQVJUSUNJUEFOVFMsXG4gIENPTlRSQUNUUyxcbiAgTUlOVF9DT05GSVJNX0RBVEEsXG4gIEJMT0NLX0hBU0gsXG4gIEZFRV9MSU1JVCxcbiAgQkxPQ0tfTlVNQkVSLFxuICBFWFBJUkFUSU9OLFxuICBUWF9DT05UUkFDVCxcbn0gZnJvbSAnLi4vLi4vcmVzb3VyY2VzJztcblxuZGVzY3JpYmUoJ1RyeCBDb250cmFjdCBjYWxsIEJ1aWxkZXInLCAoKSA9PiB7XG4gIGNvbnN0IGluaXRUeEJ1aWxkZXIgPSAoKSA9PiB7XG4gICAgY29uc3QgYnVpbGRlciA9IChnZXRCdWlsZGVyKCd0dHJ4JykgYXMgV3JhcHBlZEJ1aWxkZXIpLmdldENvbnRyYWN0Q2FsbEJ1aWxkZXIoKTtcbiAgICBidWlsZGVyXG4gICAgICAuc291cmNlKHsgYWRkcmVzczogUEFSVElDSVBBTlRTLmN1c3RvZGlhbi5hZGRyZXNzIH0pXG4gICAgICAudG8oeyBhZGRyZXNzOiBDT05UUkFDVFMuZmFjdG9yeSB9KVxuICAgICAgLmJsb2NrKHsgbnVtYmVyOiBCTE9DS19OVU1CRVIsIGhhc2g6IEJMT0NLX0hBU0ggfSlcbiAgICAgIC5mZWUoeyBmZWVMaW1pdDogRkVFX0xJTUlUIH0pO1xuXG4gICAgcmV0dXJuIGJ1aWxkZXI7XG4gIH07XG5cbiAgZGVzY3JpYmUoJ0NvbnRyYWN0IENhbGwgYnVpbGRlcicsICgpID0+IHtcbiAgICBkZXNjcmliZSgnc2hvdWxkIGJ1aWxkJywgKCkgPT4ge1xuICAgICAgZGVzY3JpYmUoJ25vbiBzZXJpYWxpemVkIHRyYW5zYWN0aW9ucycsICgpID0+IHtcbiAgICAgICAgaXQoJ2Egc2lnbmVkIGNvbnRyYWN0IGNhbGwgdHJhbnNhY3Rpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gaW5pdFR4QnVpbGRlcigpO1xuICAgICAgICAgIHR4QnVpbGRlci5kYXRhKE1JTlRfQ09ORklSTV9EQVRBKS5zaWduKHsga2V5OiBQQVJUSUNJUEFOVFMuY3VzdG9kaWFuLnBrIH0pO1xuICAgICAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICAgICAgdHgudG9Kc29uKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCdzZXJpYWxpemVkIHRyYW5zYWN0aW9ucycsICgpID0+IHtcbiAgICAgICAgaXQoJ2EgdHJhbnNhY3Rpb24gc2lnbmVkIG11bHRpcGxlIHRpbWVzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IERhdGUubm93KCk7XG4gICAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gaW5pdFR4QnVpbGRlcigpO1xuICAgICAgICAgIHR4QnVpbGRlci5kYXRhKE1JTlRfQ09ORklSTV9EQVRBKTtcbiAgICAgICAgICB0eEJ1aWxkZXIudGltZXN0YW1wKHRpbWVzdGFtcCk7XG4gICAgICAgICAgdHhCdWlsZGVyLmV4cGlyYXRpb24odGltZXN0YW1wICsgRVhQSVJBVElPTik7XG4gICAgICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcblxuICAgICAgICAgIGxldCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgICAgICBsZXQgcmF3RGF0YSA9IHR4SnNvbi5yYXdfZGF0YTtcbiAgICAgICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKHJhd0RhdGEuY29udHJhY3QsIFRYX0NPTlRSQUNUKTtcbiAgICAgICAgICBhc3NlcnQuZXF1YWwodHhKc29uLnNpZ25hdHVyZS5sZW5ndGgsIDApO1xuXG4gICAgICAgICAgY29uc3QgdHhCdWlsZGVyMiA9IGdldEJ1aWxkZXIoJ3R0cngnKS5mcm9tKHR4LnRvSnNvbigpKTtcbiAgICAgICAgICB0eEJ1aWxkZXIyLnNpZ24oeyBrZXk6IFBBUlRJQ0lQQU5UUy5jdXN0b2RpYW4ucGsgfSk7XG4gICAgICAgICAgY29uc3QgdHgyID0gYXdhaXQgdHhCdWlsZGVyMi5idWlsZCgpO1xuXG4gICAgICAgICAgdHhKc29uID0gdHgyLnRvSnNvbigpO1xuICAgICAgICAgIHJhd0RhdGEgPSB0eEpzb24ucmF3X2RhdGE7XG4gICAgICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChyYXdEYXRhLmNvbnRyYWN0LCBUWF9DT05UUkFDVCk7XG4gICAgICAgICAgYXNzZXJ0LmVxdWFsKHR4SnNvbi5zaWduYXR1cmUubGVuZ3RoLCAxKTtcblxuICAgICAgICAgIGNvbnN0IHR4QnVpbGRlcjMgPSBnZXRCdWlsZGVyKCd0dHJ4JykuZnJvbSh0eDIudG9Kc29uKCkpO1xuICAgICAgICAgIHR4QnVpbGRlcjMuc2lnbih7IGtleTogUEFSVElDSVBBTlRTLmZyb20ucGsgfSk7XG4gICAgICAgICAgY29uc3QgdHgzID0gYXdhaXQgdHhCdWlsZGVyMy5idWlsZCgpO1xuXG4gICAgICAgICAgdHhKc29uID0gdHgzLnRvSnNvbigpO1xuICAgICAgICAgIHJhd0RhdGEgPSB0eEpzb24ucmF3X2RhdGE7XG4gICAgICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChyYXdEYXRhLmNvbnRyYWN0LCBUWF9DT05UUkFDVCk7XG4gICAgICAgICAgYXNzZXJ0LmVxdWFsKHR4SnNvbi5zaWduYXR1cmUubGVuZ3RoLCAyKTtcblxuICAgICAgICAgIGNvbnN0IHR4QnVpbGRlcjQgPSBnZXRCdWlsZGVyKCd0dHJ4JykuZnJvbSh0eDMudG9Kc29uKCkpO1xuICAgICAgICAgIHR4QnVpbGRlcjQuc2lnbih7IGtleTogUEFSVElDSVBBTlRTLm11bHRpc2lnLnBrIH0pO1xuICAgICAgICAgIGNvbnN0IHR4NCA9IGF3YWl0IHR4QnVpbGRlcjQuYnVpbGQoKTtcblxuICAgICAgICAgIGFzc2VydC5lcXVhbCh0eDQuaW5wdXRzLmxlbmd0aCwgMSk7XG4gICAgICAgICAgYXNzZXJ0LmVxdWFsKHR4NC5pbnB1dHNbMF0uYWRkcmVzcywgUEFSVElDSVBBTlRTLmN1c3RvZGlhbi5hZGRyZXNzKTtcbiAgICAgICAgICBpZiAodHg0LmlucHV0c1swXS5jb250cmFjdEFkZHJlc3MpIHtcbiAgICAgICAgICAgIGFzc2VydC5lcXVhbCh0eDQuaW5wdXRzWzBdLmNvbnRyYWN0QWRkcmVzcywgQ09OVFJBQ1RTLmZhY3RvcnkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodHg0LmlucHV0c1swXS5kYXRhKSB7XG4gICAgICAgICAgICBhc3NlcnQuZXF1YWwodHg0LmlucHV0c1swXS5kYXRhLCAnSy9rTHFoSnpGQXcrRzFkV3NrTE1pTTE4VGRpbUcvaGN0Y0hkWDFDNlllQm10VG9WJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGFzc2VydC5lcXVhbCh0eDQuaW5wdXRzWzBdLnZhbHVlLCAnMCcpO1xuICAgICAgICAgIGFzc2VydC5lcXVhbCh0eDQub3V0cHV0c1swXS52YWx1ZSwgJzAnKTtcbiAgICAgICAgICBhc3NlcnQuZXF1YWwodHg0Lm91dHB1dHNbMF0uYWRkcmVzcywgUEFSVElDSVBBTlRTLmN1c3RvZGlhbi5hZGRyZXNzKTtcblxuICAgICAgICAgIHR4SnNvbiA9IHR4NC50b0pzb24oKTtcbiAgICAgICAgICByYXdEYXRhID0gdHhKc29uLnJhd19kYXRhO1xuICAgICAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwocmF3RGF0YS5jb250cmFjdCwgVFhfQ09OVFJBQ1QpO1xuICAgICAgICAgIGFzc2VydC5lcXVhbCh0eEpzb24uc2lnbmF0dXJlLmxlbmd0aCwgMyk7XG4gICAgICAgICAgYXNzZXJ0LmVxdWFsKHJhd0RhdGEuZmVlX2xpbWl0LCBGRUVfTElNSVQpO1xuICAgICAgICAgIGFzc2VydC5lcXVhbChyYXdEYXRhLmV4cGlyYXRpb24sIHRpbWVzdGFtcCArIEVYUElSQVRJT04pO1xuICAgICAgICAgIGFzc2VydC5lcXVhbChyYXdEYXRhLnRpbWVzdGFtcCwgdGltZXN0YW1wKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ2FuIHVuc2lnbmVkIHRyYW5zYWN0aW9uIGZyb20gYSBzdHJpbmcgYW5kIGZyb20gYSBKU09OJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IERhdGUubm93KCk7XG4gICAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gaW5pdFR4QnVpbGRlcigpO1xuICAgICAgICAgIHR4QnVpbGRlci5kYXRhKE1JTlRfQ09ORklSTV9EQVRBKTtcbiAgICAgICAgICB0eEJ1aWxkZXIudGltZXN0YW1wKHRpbWVzdGFtcCk7XG4gICAgICAgICAgdHhCdWlsZGVyLmV4cGlyYXRpb24odGltZXN0YW1wICsgNDAwMDApO1xuICAgICAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG5cbiAgICAgICAgICBjb25zdCB0eEJ1aWxkZXIyID0gZ2V0QnVpbGRlcigndHRyeCcpLmZyb20odHgudG9Ccm9hZGNhc3RGb3JtYXQoKSk7XG4gICAgICAgICAgdHhCdWlsZGVyMi5zaWduKHsga2V5OiBQQVJUSUNJUEFOVFMuY3VzdG9kaWFuLnBrIH0pO1xuICAgICAgICAgIGNvbnN0IHR4MiA9IGF3YWl0IHR4QnVpbGRlcjIuYnVpbGQoKTtcblxuICAgICAgICAgIGNvbnN0IHR4QnVpbGRlcjMgPSBnZXRCdWlsZGVyKCd0dHJ4JykuZnJvbSh0eC50b0pzb24oKSk7XG4gICAgICAgICAgdHhCdWlsZGVyMy5zaWduKHsga2V5OiBQQVJUSUNJUEFOVFMuY3VzdG9kaWFuLnBrIH0pO1xuICAgICAgICAgIGNvbnN0IHR4MyA9IGF3YWl0IHR4QnVpbGRlcjMuYnVpbGQoKTtcblxuICAgICAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwodHgyLCB0eDMpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnYW4gdW5zaWduZWQgdHJhbnNhY3Rpb24gd2l0aCBleHRlbmRlZCBkdXJhdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB0aW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuICAgICAgICAgIGNvbnN0IGV4cGlyYXRpb24gPSB0aW1lc3RhbXAgKyBFWFBJUkFUSU9OO1xuICAgICAgICAgIGNvbnN0IGV4dGVuc2lvbiA9IDYwMDAwO1xuICAgICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGluaXRUeEJ1aWxkZXIoKTtcbiAgICAgICAgICB0eEJ1aWxkZXIuZGF0YShNSU5UX0NPTkZJUk1fREFUQSk7XG4gICAgICAgICAgdHhCdWlsZGVyLnRpbWVzdGFtcCh0aW1lc3RhbXApO1xuICAgICAgICAgIHR4QnVpbGRlci5leHBpcmF0aW9uKGV4cGlyYXRpb24pO1xuICAgICAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG5cbiAgICAgICAgICBjb25zdCB0eEJ1aWxkZXIyID0gZ2V0QnVpbGRlcigndHRyeCcpLmZyb20odHgudG9Ccm9hZGNhc3RGb3JtYXQoKSk7XG4gICAgICAgICAgdHhCdWlsZGVyMi5leHRlbmRWYWxpZFRvKGV4dGVuc2lvbik7XG4gICAgICAgICAgdHhCdWlsZGVyMi5zaWduKHsga2V5OiBQQVJUSUNJUEFOVFMuY3VzdG9kaWFuLnBrIH0pO1xuICAgICAgICAgIGNvbnN0IHR4MiA9IGF3YWl0IHR4QnVpbGRlcjIuYnVpbGQoKTtcblxuICAgICAgICAgIGFzc2VydC5lcXVhbCh0eDIuaW5wdXRzLmxlbmd0aCwgMSk7XG4gICAgICAgICAgYXNzZXJ0LmVxdWFsKHR4Mi5pbnB1dHNbMF0uYWRkcmVzcywgUEFSVElDSVBBTlRTLmN1c3RvZGlhbi5hZGRyZXNzKTtcbiAgICAgICAgICBpZiAodHgyLmlucHV0c1swXS5jb250cmFjdEFkZHJlc3MpIHtcbiAgICAgICAgICAgIGFzc2VydC5lcXVhbCh0eDIuaW5wdXRzWzBdLmNvbnRyYWN0QWRkcmVzcywgQ09OVFJBQ1RTLmZhY3RvcnkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodHgyLmlucHV0c1swXS5kYXRhKSB7XG4gICAgICAgICAgICBhc3NlcnQuZXF1YWwodHgyLmlucHV0c1swXS5kYXRhLCAnSy9rTHFoSnpGQXcrRzFkV3NrTE1pTTE4VGRpbUcvaGN0Y0hkWDFDNlllQm10VG9WJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGFzc2VydC5lcXVhbCh0eDIuaW5wdXRzWzBdLnZhbHVlLCAnMCcpO1xuICAgICAgICAgIGFzc2VydC5lcXVhbCh0eDIub3V0cHV0c1swXS52YWx1ZSwgJzAnKTtcbiAgICAgICAgICBhc3NlcnQuZXF1YWwodHgyLm91dHB1dHNbMF0uYWRkcmVzcywgUEFSVElDSVBBTlRTLmN1c3RvZGlhbi5hZGRyZXNzKTtcblxuICAgICAgICAgIGNvbnN0IHR4SnNvbiA9IHR4Mi50b0pzb24oKTtcbiAgICAgICAgICBhc3NlcnQuZXF1YWwodHhKc29uLnJhd19kYXRhLmV4cGlyYXRpb24sIGV4cGlyYXRpb24gKyBleHRlbnNpb24pO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnYSB0cmFuc2FjdGlvbiB3aXRoIGNvcnJlY3QgaW5wdXRzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IERhdGUubm93KCk7XG4gICAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gaW5pdFR4QnVpbGRlcigpO1xuICAgICAgICAgIHR4QnVpbGRlci5kYXRhKE1JTlRfQ09ORklSTV9EQVRBKTtcbiAgICAgICAgICB0eEJ1aWxkZXIudGltZXN0YW1wKHRpbWVzdGFtcCk7XG4gICAgICAgICAgdHhCdWlsZGVyLmV4cGlyYXRpb24odGltZXN0YW1wICsgNDAwMDApO1xuICAgICAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcblxuICAgICAgICAgIGFzc2VydC5lcXVhbCh0eC50eXBlLCBUcmFuc2FjdGlvblR5cGUuQ29udHJhY3RDYWxsKTtcbiAgICAgICAgICBhc3NlcnQuZXF1YWwodHguaW5wdXRzLmxlbmd0aCwgMSk7XG4gICAgICAgICAgYXNzZXJ0LmVxdWFsKHR4LmlucHV0c1swXS5hZGRyZXNzLCBQQVJUSUNJUEFOVFMuY3VzdG9kaWFuLmFkZHJlc3MpO1xuICAgICAgICAgIGlmICh0eC5pbnB1dHNbMF0uY29udHJhY3RBZGRyZXNzKSB7XG4gICAgICAgICAgICBhc3NlcnQuZXF1YWwodHguaW5wdXRzWzBdLmNvbnRyYWN0QWRkcmVzcywgQ09OVFJBQ1RTLmZhY3RvcnkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodHguaW5wdXRzWzBdLmRhdGEpIHtcbiAgICAgICAgICAgIGFzc2VydC5lcXVhbCh0eC5pbnB1dHNbMF0uZGF0YSwgJ0sva0xxaEp6RkF3K0cxZFdza0xNaU0xOFRkaW1HL2hjdGNIZFgxQzZZZUJtdFRvVicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBhc3NlcnQuZXF1YWwodHguaW5wdXRzWzBdLnZhbHVlLCAnMCcpO1xuICAgICAgICAgIGFzc2VydC5lcXVhbCh0eC5vdXRwdXRzWzBdLnZhbHVlLCAnMCcpO1xuICAgICAgICAgIGFzc2VydC5lcXVhbCh0eC5vdXRwdXRzWzBdLmFkZHJlc3MsIFBBUlRJQ0lQQU5UUy5jdXN0b2RpYW4uYWRkcmVzcyk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnc2hvdWxkIGZhaWwgdG8gYnVpbGQnLCAoKSA9PiB7XG4gICAgICBpdCgnYSB0cmFuc2FjdGlvbiB3aXRoIHdyb25nIGRhdGEnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGluaXRUeEJ1aWxkZXIoKTtcbiAgICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICB0eEJ1aWxkZXIuZGF0YSgnYWRkTWludFJlcXVlc3QoKScpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAnYWRkTWludFJlcXVlc3QoKSBpcyBub3QgYSB2YWxpZCBoZXggc3RyaW5nLidcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnYSB0cmFuc2FjdGlvbiB3aXRoIGR1cGxpY2F0ZSBzaWduYXR1cmVzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBpbml0VHhCdWlsZGVyKCk7XG4gICAgICAgIHR4QnVpbGRlci5kYXRhKE1JTlRfQ09ORklSTV9EQVRBKTtcbiAgICAgICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IFBBUlRJQ0lQQU5UUy5jdXN0b2RpYW4ucGsgfSk7XG4gICAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IFBBUlRJQ0lQQU5UUy5jdXN0b2RpYW4ucGsgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09ICdEdXBsaWNhdGVkIGtleSdcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcblxuICAgICAgICBjb25zdCB0eEJ1aWxkZXIyID0gZ2V0QnVpbGRlcigndHRyeCcpLmZyb20odHgudG9Ccm9hZGNhc3RGb3JtYXQoKSk7XG4gICAgICAgIHR4QnVpbGRlcjIuc2lnbih7IGtleTogUEFSVElDSVBBTlRTLmN1c3RvZGlhbi5wayB9KTtcbiAgICAgICAgYXNzZXJ0LnJlamVjdHModHhCdWlsZGVyMi5idWlsZCgpLCB7XG4gICAgICAgICAgbWVzc2FnZTogJ1RyYW5zYWN0aW9uIHNpZ25pbmcgZGlkIG5vdCByZXR1cm4gYW4gYWRkaXRpb25hbCBzaWduYXR1cmUuJyxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ2FuIGludmFsaWQgcmF3IHRyYW5zYWN0aW9uJywgKCkgPT4ge1xuICAgICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIGdldEJ1aWxkZXIoJ3R0cngnKS5mcm9tKCdhbiBpbnZhbGlkIHJhdyB0cmFuc2FjdGlvbicpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAnVGhlcmUgd2FzIGVycm9yIGluIHBhcnNpbmcgdGhlIEpTT04gc3RyaW5nJ1xuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdTaG91bGQgdmFsaWRhdGUgJywgKCkgPT4ge1xuICAgIGl0KCdhIHZhbGlkIGV4cGlyYXRpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgY29uc3QgZXhwaXJhdGlvbiA9IG5vdyArIEVYUElSQVRJT047XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBpbml0VHhCdWlsZGVyKCk7XG4gICAgICB0eEJ1aWxkZXIuZGF0YShNSU5UX0NPTkZJUk1fREFUQSk7XG4gICAgICB0eEJ1aWxkZXIudGltZXN0YW1wKG5vdyk7XG4gICAgICB0eEJ1aWxkZXIuZXhwaXJhdGlvbihleHBpcmF0aW9uICsgMTAwMCk7XG4gICAgICB0eEJ1aWxkZXIuZXhwaXJhdGlvbihleHBpcmF0aW9uKTtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgIGFzc2VydC5lcXVhbCh0eEpzb24ucmF3X2RhdGEuZXhwaXJhdGlvbiwgZXhwaXJhdGlvbik7XG4gICAgfSk7XG5cbiAgICBpdCgnYW4gZXhwaXJhdGlvbiBncmVhdGVyIHRoYW4gb25lIHllYXInLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gaW5pdFR4QnVpbGRlcigpO1xuICAgICAgdHhCdWlsZGVyLmRhdGEoTUlOVF9DT05GSVJNX0RBVEEpO1xuICAgICAgdHhCdWlsZGVyLnRpbWVzdGFtcChub3cpO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHR4QnVpbGRlci5leHBpcmF0aW9uKG5vdyArIDMxNTM2MDAwMDAxKTtcbiAgICAgICAgfSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAnRXhwaXJhdGlvbiBtdXN0IG5vdCBiZSBncmVhdGVyIHRoYW4gb25lIHllYXInXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ2FuIGV4cGlyYXRpb24gbGVzcyB0aGFuIHRoZSBjdXJyZW50IGRhdGUnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gaW5pdFR4QnVpbGRlcigpO1xuICAgICAgdHhCdWlsZGVyLnRpbWVzdGFtcChub3cgLSAyMDAwKTtcbiAgICAgIHR4QnVpbGRlci5kYXRhKE1JTlRfQ09ORklSTV9EQVRBKTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0eEJ1aWxkZXIuZXhwaXJhdGlvbihub3cgLSAxMDAwKTtcbiAgICAgICAgfSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAnRXhwaXJhdGlvbiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBjdXJyZW50IHRpbWUnXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ2FuIGV4cGlyYXRpb24gbGVzcyB0aGFuIHRoZSB0aW1lc3RhbXAnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gaW5pdFR4QnVpbGRlcigpO1xuICAgICAgdHhCdWlsZGVyLmRhdGEoTUlOVF9DT05GSVJNX0RBVEEpO1xuICAgICAgdHhCdWlsZGVyLnRpbWVzdGFtcChub3cgKyAyMDAwKTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0eEJ1aWxkZXIuZXhwaXJhdGlvbihub3cgKyAxMDAwKTtcbiAgICAgICAgfSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAnRXhwaXJhdGlvbiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB0aW1lc3RhbXAnXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ2FuIGV4cGlyYXRpb24gc2V0IGFmdGVyIGJ1aWxkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IGV4cGlyYXRpb24gPSBub3cgKyBFWFBJUkFUSU9OO1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gaW5pdFR4QnVpbGRlcigpO1xuICAgICAgdHhCdWlsZGVyLmRhdGEoTUlOVF9DT05GSVJNX0RBVEEpO1xuICAgICAgYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdHhCdWlsZGVyLmV4cGlyYXRpb24oZXhwaXJhdGlvbik7XG4gICAgICAgIH0sXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gJ0V4cGlyYXRpb24gaXMgYWxyZWFkeSBzZXQsIGl0IGNhbiBvbmx5IGJlIGV4dGVuZGVkJ1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdhbiBleHBpcmF0aW9uIHNldCBhZnRlciBkZXNlcmlhbGl6aW5nJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IGV4cGlyYXRpb24gPSBub3cgKyBFWFBJUkFUSU9OO1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gaW5pdFR4QnVpbGRlcigpO1xuICAgICAgdHhCdWlsZGVyLmRhdGEoTUlOVF9DT05GSVJNX0RBVEEpO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4QnVpbGRlcjIgPSBnZXRCdWlsZGVyKCd0dHJ4JykuZnJvbSh0eC50b0Jyb2FkY2FzdEZvcm1hdCgpKTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0eEJ1aWxkZXIyLmV4cGlyYXRpb24oZXhwaXJhdGlvbik7XG4gICAgICAgIH0sXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gJ0V4cGlyYXRpb24gaXMgYWxyZWFkeSBzZXQsIGl0IGNhbiBvbmx5IGJlIGV4dGVuZGVkJ1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdhbiBleHRlbnNpb24gd2l0aG91dCBhIHNldCBleHBpcmF0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gaW5pdFR4QnVpbGRlcigpO1xuICAgICAgdHhCdWlsZGVyLmRhdGEoTUlOVF9DT05GSVJNX0RBVEEpO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHR4QnVpbGRlci5leHRlbmRWYWxpZFRvKDIwMDAwKTtcbiAgICAgICAgfSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAnVGhlcmUgaXMgbm90IGV4cGlyYXRpb24gdG8gZXh0ZW5kJ1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdhIHplcm8gbWlsbGlzZWNvbmQgZXh0ZW5zaW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gaW5pdFR4QnVpbGRlcigpO1xuICAgICAgdHhCdWlsZGVyLmRhdGEoTUlOVF9DT05GSVJNX0RBVEEpO1xuICAgICAgY29uc3QgZXhwaXJhdGlvbiA9IERhdGUubm93KCkgKyBFWFBJUkFUSU9OO1xuICAgICAgdHhCdWlsZGVyLmV4cGlyYXRpb24oZXhwaXJhdGlvbik7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuXG4gICAgICBjb25zdCB0eEJ1aWxkZXIyID0gZ2V0QnVpbGRlcigndHRyeCcpLmZyb20odHgudG9Ccm9hZGNhc3RGb3JtYXQoKSk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdHhCdWlsZGVyMi5leHRlbmRWYWxpZFRvKDApO1xuICAgICAgICB9LFxuICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09ICdWYWx1ZSBjYW5ub3QgYmUgYmVsb3cgemVybydcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnYW4gZXh0ZW5zaW9uIGdyYXRlciB0aGFuIG9uZSB5ZWFyJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gaW5pdFR4QnVpbGRlcigpO1xuICAgICAgdHhCdWlsZGVyLmRhdGEoTUlOVF9DT05GSVJNX0RBVEEpO1xuICAgICAgY29uc3QgZXhwaXJhdGlvbiA9IERhdGUubm93KCkgKyBFWFBJUkFUSU9OO1xuICAgICAgdHhCdWlsZGVyLmV4cGlyYXRpb24oZXhwaXJhdGlvbik7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuXG4gICAgICBjb25zdCB0eEJ1aWxkZXIyID0gZ2V0QnVpbGRlcigndHRyeCcpLmZyb20odHgudG9Ccm9hZGNhc3RGb3JtYXQoKSk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdHhCdWlsZGVyMi5leHRlbmRWYWxpZFRvKDMxNTM2MDAwMDAxKTtcbiAgICAgICAgfSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAnVGhlIGV4cGlyYXRpb24gY2Fubm90IGJlIGV4dGVuZGVkIG1vcmUgdGhhbiBvbmUgeWVhcidcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnYW4gZXh0ZW5zaW9uIGFmdGVyIHNpZ25pbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBpbml0VHhCdWlsZGVyKCk7XG4gICAgICB0eEJ1aWxkZXIuZGF0YShNSU5UX0NPTkZJUk1fREFUQSk7XG4gICAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogUEFSVElDSVBBTlRTLmN1c3RvZGlhbi5wayB9KTtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG5cbiAgICAgIGNvbnN0IHR4QnVpbGRlcjIgPSBnZXRCdWlsZGVyKCd0dHJ4JykuZnJvbSh0eC50b0Jyb2FkY2FzdEZvcm1hdCgpKTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0eEJ1aWxkZXIyLmV4dGVuZFZhbGlkVG8oMjAwMDApO1xuICAgICAgICB9LFxuICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09ICdDYW5ub3QgZXh0ZW5kIGEgc2lnbmVkIHRyYW5zYWN0aW9uJ1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdmZWUgbGltaXQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBpbml0VHhCdWlsZGVyKCk7XG4gICAgICB0eEJ1aWxkZXIuZGF0YShNSU5UX0NPTkZJUk1fREFUQSk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdHhCdWlsZGVyLmZlZSh7IGZlZUxpbWl0OiAnbm90IGEgbnVtYmVyJyB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAnSW52YWxpZCBmZWUgbGltaXQgdmFsdWUnXG4gICAgICApO1xuXG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdHhCdWlsZGVyLmZlZSh7IGZlZUxpbWl0OiAnLTE1MDAwJyB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAnSW52YWxpZCBmZWUgbGltaXQgdmFsdWUnXG4gICAgICApO1xuXG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgdHJvbk5ldHdvcmsgPSBjb2lucy5nZXQoJ3R0cngnKS5uZXR3b3JrIGFzIFRyb25OZXR3b3JrO1xuICAgICAgICAgIHR4QnVpbGRlci5mZWUoeyBmZWVMaW1pdDogbmV3IEJpZ051bWJlcih0cm9uTmV0d29yay5tYXhGZWVMaW1pdCkucGx1cygxKS50b1N0cmluZygpIH0pO1xuICAgICAgICB9LFxuICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09ICdJbnZhbGlkIGZlZSBsaW1pdCB2YWx1ZSdcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgndHJhbnNhY3Rpb24gbWFuZGF0b3J5IGZpZWxkcycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IChnZXRCdWlsZGVyKCd0dHJ4JykgYXMgV3JhcHBlZEJ1aWxkZXIpLmdldENvbnRyYWN0Q2FsbEJ1aWxkZXIoKTtcbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKHR4QnVpbGRlci5idWlsZCgpLCB7XG4gICAgICAgIG1lc3NhZ2U6ICdNaXNzaW5nIHBhcmFtZXRlcjogZGF0YScsXG4gICAgICB9KTtcblxuICAgICAgdHhCdWlsZGVyLmRhdGEoTUlOVF9DT05GSVJNX0RBVEEpO1xuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHModHhCdWlsZGVyLmJ1aWxkKCksIHtcbiAgICAgICAgbWVzc2FnZTogJ01pc3NpbmcgcGFyYW1ldGVyOiBzb3VyY2UnLFxuICAgICAgfSk7XG5cbiAgICAgIHR4QnVpbGRlci5zb3VyY2UoeyBhZGRyZXNzOiBQQVJUSUNJUEFOVFMuY3VzdG9kaWFuLmFkZHJlc3MgfSk7XG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyh0eEJ1aWxkZXIuYnVpbGQoKSwge1xuICAgICAgICBtZXNzYWdlOiAnTWlzc2luZyBwYXJhbWV0ZXI6IGNvbnRyYWN0IGFkZHJlc3MnLFxuICAgICAgfSk7XG5cbiAgICAgIHR4QnVpbGRlci50byh7IGFkZHJlc3M6IENPTlRSQUNUUy5mYWN0b3J5IH0pO1xuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHModHhCdWlsZGVyLmJ1aWxkKCksIHtcbiAgICAgICAgbWVzc2FnZTogJ01pc3NpbmcgYmxvY2sgcmVmZXJlbmNlIGluZm9ybWF0aW9uJyxcbiAgICAgIH0pO1xuXG4gICAgICB0eEJ1aWxkZXIuYmxvY2soeyBudW1iZXI6IEJMT0NLX05VTUJFUiwgaGFzaDogQkxPQ0tfSEFTSCB9KTtcbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKHR4QnVpbGRlci5idWlsZCgpLCB7XG4gICAgICAgIG1lc3NhZ2U6ICdNaXNzaW5nIGZlZScsXG4gICAgICB9KTtcblxuICAgICAgdHhCdWlsZGVyLmZlZSh7IGZlZUxpbWl0OiBGRUVfTElNSVQgfSk7XG4gICAgICBhc3NlcnQuZG9lc05vdFJlamVjdCgoKSA9PiB7XG4gICAgICAgIHJldHVybiB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19

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


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