PHP WebShell

Текущая директория: /opt/BitGoJS/modules/abstract-utxo/dist/src/transaction/fixedScript

Просмотр файла: explainTransaction.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;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.explainPsbt = explainPsbt;
exports.explainLegacyTx = explainLegacyTx;
const utxolib = __importStar(require("@bitgo/utxo-lib"));
const utxo_lib_1 = require("@bitgo/utxo-lib");
const recipient_1 = require("../recipient");
function explainCommon(tx, params, network) {
    const displayOrder = ['id', 'outputAmount', 'changeAmount', 'outputs', 'changeOutputs'];
    let spendAmount = BigInt(0);
    let changeAmount = BigInt(0);
    const changeOutputs = [];
    const outputs = [];
    const { changeInfo } = params;
    const changeAddresses = changeInfo?.map((info) => info.address) ?? [];
    tx.outs.forEach((currentOutput) => {
        // Try to encode the script pubkey with an address. If it fails, try to parse it as an OP_RETURN output with the prefix.
        // If that fails, then it is an unrecognized scriptPubkey and should fail
        const currentAddress = (0, recipient_1.toExtendedAddressFormat)(currentOutput.script, network);
        const currentAmount = BigInt(currentOutput.value);
        if (changeAddresses.includes(currentAddress)) {
            // this is change
            changeAmount += currentAmount;
            const change = changeInfo?.find((change) => change.address === currentAddress);
            if (!change) {
                throw new Error('changeInfo must have change information for all change outputs');
            }
            changeOutputs.push({
                address: currentAddress,
                amount: currentAmount.toString(),
                chain: change.chain,
                index: change.index,
                external: false,
            });
            return;
        }
        spendAmount += currentAmount;
        outputs.push({
            address: currentAddress,
            amount: currentAmount.toString(),
            // If changeInfo has a length greater than or equal to zero, it means that the change information
            // was provided to the function but the output was not identified as change. In this case,
            // the output is external, and we can set it as so. If changeInfo is undefined, it means we were
            // given no information about change outputs, so we can't determine anything about the output,
            // so we leave it undefined.
            external: changeInfo ? true : undefined,
        });
    });
    const outputDetails = {
        outputAmount: spendAmount.toString(),
        changeAmount: changeAmount.toString(),
        outputs,
        changeOutputs,
    };
    let fee;
    let locktime;
    if (params.feeInfo) {
        displayOrder.push('fee');
        fee = params.feeInfo;
    }
    if (Number.isInteger(tx.locktime) && tx.locktime > 0) {
        displayOrder.push('locktime');
        locktime = tx.locktime;
    }
    return { displayOrder, id: tx.getId(), ...outputDetails, fee, locktime };
}
function getRootWalletKeys(params) {
    const keys = params.pubs?.map((xpub) => utxo_lib_1.bip32.fromBase58(xpub));
    return keys && keys.length === 3 ? new utxo_lib_1.bitgo.RootWalletKeys(keys) : undefined;
}
function getPsbtInputSignaturesCount(psbt, params) {
    const rootWalletKeys = getRootWalletKeys(params);
    return rootWalletKeys
        ? utxo_lib_1.bitgo.getSignatureValidationArrayPsbt(psbt, rootWalletKeys).map((sv) => sv[1].filter((v) => v).length)
        : Array(psbt.data.inputs.length).fill(0);
}
function getTxInputSignaturesCount(tx, params, network) {
    const prevOutputs = params.txInfo?.unspents?.map((u) => utxo_lib_1.bitgo.toOutput(u, network));
    const rootWalletKeys = getRootWalletKeys(params);
    const { unspents = [] } = params.txInfo ?? {};
    // get the number of signatures per input
    return tx.ins.map((input, idx) => {
        if (unspents.length !== tx.ins.length) {
            return 0;
        }
        if (!prevOutputs) {
            throw new Error(`invalid state`);
        }
        if (!rootWalletKeys) {
            // no pub keys or incorrect number of pub keys
            return 0;
        }
        try {
            return utxo_lib_1.bitgo.verifySignatureWithUnspent(tx, idx, unspents, rootWalletKeys).filter((v) => v).length;
        }
        catch (e) {
            // some other error occurred and we can't validate the signatures
            return 0;
        }
    });
}
/**
 * Decompose a raw psbt into useful information, such as the total amounts,
 * change amounts, and transaction outputs.
 */
function explainPsbt(psbt, params, network) {
    const txOutputs = psbt.txOutputs;
    function getChainAndIndexFromBip32Derivations(output) {
        const derivations = output.bip32Derivation ?? output.tapBip32Derivation ?? undefined;
        if (!derivations) {
            return undefined;
        }
        const paths = derivations.map((d) => d.path);
        if (!paths || paths.length !== 3) {
            throw new Error('expected 3 paths in bip32Derivation or tapBip32Derivation');
        }
        if (!paths.every((p) => paths[0] === p)) {
            throw new Error('expected all paths to be the same');
        }
        paths.forEach((path) => {
            if (paths[0] !== path) {
                throw new Error('Unable to get a single chain and index on the output because there are different paths for different keys');
            }
        });
        return utxolib.bitgo.getChainAndIndexFromPath(paths[0]);
    }
    function getChangeInfo() {
        try {
            return utxolib.bitgo.findInternalOutputIndices(psbt).map((i) => {
                const derivationInformation = getChainAndIndexFromBip32Derivations(psbt.data.outputs[i]);
                if (!derivationInformation) {
                    throw new Error('could not find derivation information on bip32Derivation or tapBip32Derivation');
                }
                return {
                    address: utxolib.address.fromOutputScript(txOutputs[i].script, network),
                    external: false,
                    ...derivationInformation,
                };
            });
        }
        catch (e) {
            if (e instanceof utxolib.bitgo.ErrorNoMultiSigInputFound) {
                return undefined;
            }
            throw e;
        }
    }
    const changeInfo = getChangeInfo();
    const tx = psbt.getUnsignedTx();
    const common = explainCommon(tx, { ...params, changeInfo }, network);
    const inputSignaturesCount = getPsbtInputSignaturesCount(psbt, params);
    // Set fee from subtracting inputs from outputs
    const outputAmount = txOutputs.reduce((cumulative, curr) => cumulative + BigInt(curr.value), BigInt(0));
    const inputAmount = psbt.txInputs.reduce((cumulative, txInput, i) => {
        const data = psbt.data.inputs[i];
        if (data.witnessUtxo) {
            return cumulative + BigInt(data.witnessUtxo.value);
        }
        else if (data.nonWitnessUtxo) {
            const tx = utxo_lib_1.bitgo.createTransactionFromBuffer(data.nonWitnessUtxo, network, { amountType: 'bigint' });
            return cumulative + BigInt(tx.outs[txInput.index].value);
        }
        else {
            throw new Error('could not find value on input');
        }
    }, BigInt(0));
    return {
        ...common,
        fee: (inputAmount - outputAmount).toString(),
        inputSignatures: inputSignaturesCount,
        signatures: inputSignaturesCount.reduce((prev, curr) => (curr > prev ? curr : prev), 0),
    };
}
function explainLegacyTx(tx, params, network) {
    const common = explainCommon(tx, params, network);
    const inputSignaturesCount = getTxInputSignaturesCount(tx, params, network);
    return {
        ...common,
        inputSignatures: inputSignaturesCount,
        signatures: inputSignaturesCount.reduce((prev, curr) => (curr > prev ? curr : prev), 0),
    };
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwbGFpblRyYW5zYWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3RyYW5zYWN0aW9uL2ZpeGVkU2NyaXB0L2V4cGxhaW5UcmFuc2FjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTRJQSxrQ0E4RUM7QUFFRCwwQ0FnQkM7QUE1T0QseURBQTJDO0FBQzNDLDhDQUErRDtBQUkvRCw0Q0FBdUQ7QUFJdkQsU0FBUyxhQUFhLENBQ3BCLEVBQWtDLEVBQ2xDLE1BR0MsRUFDRCxPQUF3QjtJQUV4QixNQUFNLFlBQVksR0FBRyxDQUFDLElBQUksRUFBRSxjQUFjLEVBQUUsY0FBYyxFQUFFLFNBQVMsRUFBRSxlQUFlLENBQUMsQ0FBQztJQUN4RixJQUFJLFdBQVcsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDNUIsSUFBSSxZQUFZLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzdCLE1BQU0sYUFBYSxHQUE4QixFQUFFLENBQUM7SUFDcEQsTUFBTSxPQUFPLEdBQWEsRUFBRSxDQUFDO0lBRTdCLE1BQU0sRUFBRSxVQUFVLEVBQUUsR0FBRyxNQUFNLENBQUM7SUFDOUIsTUFBTSxlQUFlLEdBQUcsVUFBVSxFQUFFLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUV0RSxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLGFBQWEsRUFBRSxFQUFFO1FBQ2hDLHdIQUF3SDtRQUN4SCx5RUFBeUU7UUFDekUsTUFBTSxjQUFjLEdBQUcsSUFBQSxtQ0FBdUIsRUFBQyxhQUFhLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzlFLE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7UUFF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QUM7SUFDSCxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFZCxPQUFPO1FBQ0wsR0FBRyxNQUFNO1FBQ1QsR0FBRyxFQUFFLENBQUMsV0FBVyxHQUFHLFlBQVksQ0FBQyxDQUFDLFFBQVEsRUFBRTtRQUM1QyxlQUFlLEVBQUUsb0JBQW9CO1FBQ3JDLFVBQVUsRUFBRSxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0tBQzlELENBQUM7QUFDOUIsQ0FBQztBQUVELFNBQWdCLGVBQWUsQ0FDN0IsRUFBa0MsRUFDbEMsTUFJQyxFQUNELE9BQXdCO0lBRXhCLE1BQU0sTUFBTSxHQUFHLGFBQWEsQ0FBQyxFQUFFLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ2xELE1BQU0sb0JBQW9CLEdBQUcseUJBQXlCLENBQUMsRUFBRSxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQztJQUM1RSxPQUFPO1FBQ0wsR0FBRyxNQUFNO1FBQ1QsZUFBZSxFQUFFLG9CQUFvQjtRQUNyQyxVQUFVLEVBQUUsb0JBQW9CLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztLQUM5RCxDQUFDO0FBQzlCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyB1dHhvbGliIGZyb20gJ0BiaXRnby91dHhvLWxpYic7XG5pbXBvcnQgeyBiaXAzMiwgQklQMzJJbnRlcmZhY2UsIGJpdGdvIH0gZnJvbSAnQGJpdGdvL3V0eG8tbGliJztcbmltcG9ydCB7IFRyaXBsZSB9IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5cbmltcG9ydCB7IE91dHB1dCwgVHJhbnNhY3Rpb25FeHBsYW5hdGlvbiwgRml4ZWRTY3JpcHRXYWxsZXRPdXRwdXQgfSBmcm9tICcuLi8uLi9hYnN0cmFjdFV0eG9Db2luJztcbmltcG9ydCB7IHRvRXh0ZW5kZWRBZGRyZXNzRm9ybWF0IH0gZnJvbSAnLi4vcmVjaXBpZW50JztcblxuZXhwb3J0IHR5cGUgQ2hhbmdlQWRkcmVzc0luZm8gPSB7IGFkZHJlc3M6IHN0cmluZzsgY2hhaW46IG51bWJlcjsgaW5kZXg6IG51bWJlciB9O1xuXG5mdW5jdGlvbiBleHBsYWluQ29tbW9uPFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQ+KFxuICB0eDogYml0Z28uVXR4b1RyYW5zYWN0aW9uPFROdW1iZXI+LFxuICBwYXJhbXM6IHtcbiAgICBjaGFuZ2VJbmZvPzogQ2hhbmdlQWRkcmVzc0luZm9bXTtcbiAgICBmZWVJbmZvPzogc3RyaW5nO1xuICB9LFxuICBuZXR3b3JrOiB1dHhvbGliLk5ldHdvcmtcbikge1xuICBjb25zdCBkaXNwbGF5T3JkZXIgPSBbJ2lkJywgJ291dHB1dEFtb3VudCcsICdjaGFuZ2VBbW91bnQnLCAnb3V0cHV0cycsICdjaGFuZ2VPdXRwdXRzJ107XG4gIGxldCBzcGVuZEFtb3VudCA9IEJpZ0ludCgwKTtcbiAgbGV0IGNoYW5nZUFtb3VudCA9IEJpZ0ludCgwKTtcbiAgY29uc3QgY2hhbmdlT3V0cHV0czogRml4ZWRTY3JpcHRXYWxsZXRPdXRwdXRbXSA9IFtdO1xuICBjb25zdCBvdXRwdXRzOiBPdXRwdXRbXSA9IFtdO1xuXG4gIGNvbnN0IHsgY2hhbmdlSW5mbyB9ID0gcGFyYW1zO1xuICBjb25zdCBjaGFuZ2VBZGRyZXNzZXMgPSBjaGFuZ2VJbmZvPy5tYXAoKGluZm8pID0+IGluZm8uYWRkcmVzcykgPz8gW107XG5cbiAgdHgub3V0cy5mb3JFYWNoKChjdXJyZW50T3V0cHV0KSA9PiB7XG4gICAgLy8gVHJ5IHRvIGVuY29kZSB0aGUgc2NyaXB0IHB1YmtleSB3aXRoIGFuIGFkZHJlc3MuIElmIGl0IGZhaWxzLCB0cnkgdG8gcGFyc2UgaXQgYXMgYW4gT1BfUkVUVVJOIG91dHB1dCB3aXRoIHRoZSBwcmVmaXguXG4gICAgLy8gSWYgdGhhdCBmYWlscywgdGhlbiBpdCBpcyBhbiB1bnJlY29nbml6ZWQgc2NyaXB0UHVia2V5IGFuZCBzaG91bGQgZmFpbFxuICAgIGNvbnN0IGN1cnJlbnRBZGRyZXNzID0gdG9FeHRlbmRlZEFkZHJlc3NGb3JtYXQoY3VycmVudE91dHB1dC5zY3JpcHQsIG5ldHdvcmspO1xuICAgIGNvbnN0IGN1cnJlbnRBbW91bnQgPSBCaWdJbnQoY3VycmVudE91dHB1dC52YWx1ZSk7XG5cbiAgICBpZiAoY2hhbmdlQWRkcmVzc2VzLmluY2x1ZGVzKGN1cnJlbnRBZGRyZXNzKSkge1xuICAgICAgLy8gdGhpcyBpcyBjaGFuZ2VcbiAgICAgIGNoYW5nZUFtb3VudCArPSBjdXJyZW50QW1vdW50O1xuICAgICAgY29uc3QgY2hhbmdlID0gY2hhbmdlSW5mbz8uZmluZCgoY2hhbmdlKSA9PiBjaGFuZ2UuYWRkcmVzcyA9PT0gY3VycmVudEFkZHJlc3MpO1xuXG4gICAgICBpZiAoIWNoYW5nZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NoYW5nZUluZm8gbXVzdCBoYXZlIGNoYW5nZSBpbmZvcm1hdGlvbiBmb3IgYWxsIGNoYW5nZSBvdXRwdXRzJyk7XG4gICAgICB9XG4gICAgICBjaGFuZ2VPdXRwdXRzLnB1c2goe1xuICAgICAgICBhZGRyZXNzOiBjdXJyZW50QWRkcmVzcyxcbiAgICAgICAgYW1vdW50OiBjdXJyZW50QW1vdW50LnRvU3RyaW5nKCksXG4gICAgICAgIGNoYWluOiBjaGFuZ2UuY2hhaW4sXG4gICAgICAgIGluZGV4OiBjaGFuZ2UuaW5kZXgsXG4gICAgICAgIGV4dGVybmFsOiBmYWxzZSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHNwZW5kQW1vdW50ICs9IGN1cnJlbnRBbW91bnQ7XG4gICAgb3V0cHV0cy5wdXNoKHtcbiAgICAgIGFkZHJlc3M6IGN1cnJlbnRBZGRyZXNzLFxuICAgICAgYW1vdW50OiBjdXJyZW50QW1vdW50LnRvU3RyaW5nKCksXG4gICAgICAvLyBJZiBjaGFuZ2VJbmZvIGhhcyBhIGxlbmd0aCBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gemVybywgaXQgbWVhbnMgdGhhdCB0aGUgY2hhbmdlIGluZm9ybWF0aW9uXG4gICAgICAvLyB3YXMgcHJvdmlkZWQgdG8gdGhlIGZ1bmN0aW9uIGJ1dCB0aGUgb3V0cHV0IHdhcyBub3QgaWRlbnRpZmllZCBhcyBjaGFuZ2UuIEluIHRoaXMgY2FzZSxcbiAgICAgIC8vIHRoZSBvdXRwdXQgaXMgZXh0ZXJuYWwsIGFuZCB3ZSBjYW4gc2V0IGl0IGFzIHNvLiBJZiBjaGFuZ2VJbmZvIGlzIHVuZGVmaW5lZCwgaXQgbWVhbnMgd2Ugd2VyZVxuICAgICAgLy8gZ2l2ZW4gbm8gaW5mb3JtYXRpb24gYWJvdXQgY2hhbmdlIG91dHB1dHMsIHNvIHdlIGNhbid0IGRldGVybWluZSBhbnl0aGluZyBhYm91dCB0aGUgb3V0cHV0LFxuICAgICAgLy8gc28gd2UgbGVhdmUgaXQgdW5kZWZpbmVkLlxuICAgICAgZXh0ZXJuYWw6IGNoYW5nZUluZm8gPyB0cnVlIDogdW5kZWZpbmVkLFxuICAgIH0pO1xuICB9KTtcblxuICBjb25zdCBvdXRwdXREZXRhaWxzID0ge1xuICAgIG91dHB1dEFtb3VudDogc3BlbmRBbW91bnQudG9TdHJpbmcoKSxcbiAgICBjaGFuZ2VBbW91bnQ6IGNoYW5nZUFtb3VudC50b1N0cmluZygpLFxuICAgIG91dHB1dHMsXG4gICAgY2hhbmdlT3V0cHV0cyxcbiAgfTtcblxuICBsZXQgZmVlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIGxldCBsb2NrdGltZTogbnVtYmVyIHwgdW5kZWZpbmVkO1xuXG4gIGlmIChwYXJhbXMuZmVlSW5mbykge1xuICAgIGRpc3BsYXlPcmRlci5wdXNoKCdmZWUnKTtcbiAgICBmZWUgPSBwYXJhbXMuZmVlSW5mbztcbiAgfVxuXG4gIGlmIChOdW1iZXIuaXNJbnRlZ2VyKHR4LmxvY2t0aW1lKSAmJiB0eC5sb2NrdGltZSA+IDApIHtcbiAgICBkaXNwbGF5T3JkZXIucHVzaCgnbG9ja3RpbWUnKTtcbiAgICBsb2NrdGltZSA9IHR4LmxvY2t0aW1lO1xuICB9XG5cbiAgcmV0dXJuIHsgZGlzcGxheU9yZGVyLCBpZDogdHguZ2V0SWQoKSwgLi4ub3V0cHV0RGV0YWlscywgZmVlLCBsb2NrdGltZSB9O1xufVxuXG5mdW5jdGlvbiBnZXRSb290V2FsbGV0S2V5cyhwYXJhbXM6IHsgcHVicz86IHN0cmluZ1tdIH0pIHtcbiAgY29uc3Qga2V5cyA9IHBhcmFtcy5wdWJzPy5tYXAoKHhwdWIpID0+IGJpcDMyLmZyb21CYXNlNTgoeHB1YikpO1xuICByZXR1cm4ga2V5cyAmJiBrZXlzLmxlbmd0aCA9PT0gMyA/IG5ldyBiaXRnby5Sb290V2FsbGV0S2V5cyhrZXlzIGFzIFRyaXBsZTxCSVAzMkludGVyZmFjZT4pIDogdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBnZXRQc2J0SW5wdXRTaWduYXR1cmVzQ291bnQoXG4gIHBzYnQ6IGJpdGdvLlV0eG9Qc2J0LFxuICBwYXJhbXM6IHtcbiAgICBwdWJzPzogc3RyaW5nW107XG4gIH1cbikge1xuICBjb25zdCByb290V2FsbGV0S2V5cyA9IGdldFJvb3RXYWxsZXRLZXlzKHBhcmFtcyk7XG4gIHJldHVybiByb290V2FsbGV0S2V5c1xuICAgID8gYml0Z28uZ2V0U2lnbmF0dXJlVmFsaWRhdGlvbkFycmF5UHNidChwc2J0LCByb290V2FsbGV0S2V5cykubWFwKChzdikgPT4gc3ZbMV0uZmlsdGVyKCh2KSA9PiB2KS5sZW5ndGgpXG4gICAgOiAoQXJyYXkocHNidC5kYXRhLmlucHV0cy5sZW5ndGgpIGFzIG51bWJlcltdKS5maWxsKDApO1xufVxuXG5mdW5jdGlvbiBnZXRUeElucHV0U2lnbmF0dXJlc0NvdW50PFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQ+KFxuICB0eDogYml0Z28uVXR4b1RyYW5zYWN0aW9uPFROdW1iZXI+LFxuICBwYXJhbXM6IHtcbiAgICB0eEluZm8/OiB7IHVuc3BlbnRzPzogYml0Z28uVW5zcGVudDxUTnVtYmVyPltdIH07XG4gICAgcHVicz86IHN0cmluZ1tdO1xuICB9LFxuICBuZXR3b3JrOiB1dHhvbGliLk5ldHdvcmtcbikge1xuICBjb25zdCBwcmV2T3V0cHV0cyA9IHBhcmFtcy50eEluZm8/LnVuc3BlbnRzPy5tYXAoKHUpID0+IGJpdGdvLnRvT3V0cHV0PFROdW1iZXI+KHUsIG5ldHdvcmspKTtcbiAgY29uc3Qgcm9vdFdhbGxldEtleXMgPSBnZXRSb290V2FsbGV0S2V5cyhwYXJhbXMpO1xuICBjb25zdCB7IHVuc3BlbnRzID0gW10gfSA9IHBhcmFtcy50eEluZm8gPz8ge307XG5cbiAgLy8gZ2V0IHRoZSBudW1iZXIgb2Ygc2lnbmF0dXJlcyBwZXIgaW5wdXRcbiAgcmV0dXJuIHR4Lmlucy5tYXAoKGlucHV0LCBpZHgpOiBudW1iZXIgPT4ge1xuICAgIGlmICh1bnNwZW50cy5sZW5ndGggIT09IHR4Lmlucy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBpZiAoIXByZXZPdXRwdXRzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgc3RhdGVgKTtcbiAgICB9XG4gICAgaWYgKCFyb290V2FsbGV0S2V5cykge1xuICAgICAgLy8gbm8gcHViIGtleXMgb3IgaW5jb3JyZWN0IG51bWJlciBvZiBwdWIga2V5c1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYml0Z28udmVyaWZ5U2lnbmF0dXJlV2l0aFVuc3BlbnQ8VE51bWJlcj4odHgsIGlkeCwgdW5zcGVudHMsIHJvb3RXYWxsZXRLZXlzKS5maWx0ZXIoKHYpID0+IHYpLmxlbmd0aDtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBzb21lIG90aGVyIGVycm9yIG9jY3VycmVkIGFuZCB3ZSBjYW4ndCB2YWxpZGF0ZSB0aGUgc2lnbmF0dXJlc1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICB9KTtcbn1cblxuLyoqXG4gKiBEZWNvbXBvc2UgYSByYXcgcHNidCBpbnRvIHVzZWZ1bCBpbmZvcm1hdGlvbiwgc3VjaCBhcyB0aGUgdG90YWwgYW1vdW50cyxcbiAqIGNoYW5nZSBhbW91bnRzLCBhbmQgdHJhbnNhY3Rpb24gb3V0cHV0cy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV4cGxhaW5Qc2J0PFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQsIFR4IGV4dGVuZHMgYml0Z28uVXR4b1RyYW5zYWN0aW9uPGJpZ2ludD4+KFxuICBwc2J0OiBiaXRnby5VdHhvUHNidDxUeD4sXG4gIHBhcmFtczoge1xuICAgIHB1YnM/OiBzdHJpbmdbXTtcbiAgICB0eEluZm8/OiB7IHVuc3BlbnRzPzogYml0Z28uVW5zcGVudDxUTnVtYmVyPltdIH07XG4gIH0sXG4gIG5ldHdvcms6IHV0eG9saWIuTmV0d29ya1xuKTogVHJhbnNhY3Rpb25FeHBsYW5hdGlvbiB7XG4gIGNvbnN0IHR4T3V0cHV0cyA9IHBzYnQudHhPdXRwdXRzO1xuXG4gIGZ1bmN0aW9uIGdldENoYWluQW5kSW5kZXhGcm9tQmlwMzJEZXJpdmF0aW9ucyhvdXRwdXQ6IGJpdGdvLlBzYnRPdXRwdXQpIHtcbiAgICBjb25zdCBkZXJpdmF0aW9ucyA9IG91dHB1dC5iaXAzMkRlcml2YXRpb24gPz8gb3V0cHV0LnRhcEJpcDMyRGVyaXZhdGlvbiA/PyB1bmRlZmluZWQ7XG4gICAgaWYgKCFkZXJpdmF0aW9ucykge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgY29uc3QgcGF0aHMgPSBkZXJpdmF0aW9ucy5tYXAoKGQpID0+IGQucGF0aCk7XG4gICAgaWYgKCFwYXRocyB8fCBwYXRocy5sZW5ndGggIT09IDMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZXhwZWN0ZWQgMyBwYXRocyBpbiBiaXAzMkRlcml2YXRpb24gb3IgdGFwQmlwMzJEZXJpdmF0aW9uJyk7XG4gICAgfVxuICAgIGlmICghcGF0aHMuZXZlcnkoKHApID0+IHBhdGhzWzBdID09PSBwKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdleHBlY3RlZCBhbGwgcGF0aHMgdG8gYmUgdGhlIHNhbWUnKTtcbiAgICB9XG5cbiAgICBwYXRocy5mb3JFYWNoKChwYXRoKSA9PiB7XG4gICAgICBpZiAocGF0aHNbMF0gIT09IHBhdGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICdVbmFibGUgdG8gZ2V0IGEgc2luZ2xlIGNoYWluIGFuZCBpbmRleCBvbiB0aGUgb3V0cHV0IGJlY2F1c2UgdGhlcmUgYXJlIGRpZmZlcmVudCBwYXRocyBmb3IgZGlmZmVyZW50IGtleXMnXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHV0eG9saWIuYml0Z28uZ2V0Q2hhaW5BbmRJbmRleEZyb21QYXRoKHBhdGhzWzBdKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldENoYW5nZUluZm8oKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB1dHhvbGliLmJpdGdvLmZpbmRJbnRlcm5hbE91dHB1dEluZGljZXMocHNidCkubWFwKChpKSA9PiB7XG4gICAgICAgIGNvbnN0IGRlcml2YXRpb25JbmZvcm1hdGlvbiA9IGdldENoYWluQW5kSW5kZXhGcm9tQmlwMzJEZXJpdmF0aW9ucyhwc2J0LmRhdGEub3V0cHV0c1tpXSk7XG4gICAgICAgIGlmICghZGVyaXZhdGlvbkluZm9ybWF0aW9uKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdjb3VsZCBub3QgZmluZCBkZXJpdmF0aW9uIGluZm9ybWF0aW9uIG9uIGJpcDMyRGVyaXZhdGlvbiBvciB0YXBCaXAzMkRlcml2YXRpb24nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGFkZHJlc3M6IHV0eG9saWIuYWRkcmVzcy5mcm9tT3V0cHV0U2NyaXB0KHR4T3V0cHV0c1tpXS5zY3JpcHQsIG5ldHdvcmspLFxuICAgICAgICAgIGV4dGVybmFsOiBmYWxzZSxcbiAgICAgICAgICAuLi5kZXJpdmF0aW9uSW5mb3JtYXRpb24sXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAoZSBpbnN0YW5jZW9mIHV0eG9saWIuYml0Z28uRXJyb3JOb011bHRpU2lnSW5wdXRGb3VuZCkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gIH1cbiAgY29uc3QgY2hhbmdlSW5mbyA9IGdldENoYW5nZUluZm8oKTtcbiAgY29uc3QgdHggPSBwc2J0LmdldFVuc2lnbmVkVHgoKSBhcyBiaXRnby5VdHhvVHJhbnNhY3Rpb248VE51bWJlcj47XG4gIGNvbnN0IGNvbW1vbiA9IGV4cGxhaW5Db21tb24odHgsIHsgLi4ucGFyYW1zLCBjaGFuZ2VJbmZvIH0sIG5ldHdvcmspO1xuICBjb25zdCBpbnB1dFNpZ25hdHVyZXNDb3VudCA9IGdldFBzYnRJbnB1dFNpZ25hdHVyZXNDb3VudChwc2J0LCBwYXJhbXMpO1xuXG4gIC8vIFNldCBmZWUgZnJvbSBzdWJ0cmFjdGluZyBpbnB1dHMgZnJvbSBvdXRwdXRzXG4gIGNvbnN0IG91dHB1dEFtb3VudCA9IHR4T3V0cHV0cy5yZWR1Y2UoKGN1bXVsYXRpdmUsIGN1cnIpID0+IGN1bXVsYXRpdmUgKyBCaWdJbnQoY3Vyci52YWx1ZSksIEJpZ0ludCgwKSk7XG4gIGNvbnN0IGlucHV0QW1vdW50ID0gcHNidC50eElucHV0cy5yZWR1Y2UoKGN1bXVsYXRpdmUsIHR4SW5wdXQsIGkpID0+IHtcbiAgICBjb25zdCBkYXRhID0gcHNidC5kYXRhLmlucHV0c1tpXTtcbiAgICBpZiAoZGF0YS53aXRuZXNzVXR4bykge1xuICAgICAgcmV0dXJuIGN1bXVsYXRpdmUgKyBCaWdJbnQoZGF0YS53aXRuZXNzVXR4by52YWx1ZSk7XG4gICAgfSBlbHNlIGlmIChkYXRhLm5vbldpdG5lc3NVdHhvKSB7XG4gICAgICBjb25zdCB0eCA9IGJpdGdvLmNyZWF0ZVRyYW5zYWN0aW9uRnJvbUJ1ZmZlcjxiaWdpbnQ+KGRhdGEubm9uV2l0bmVzc1V0eG8sIG5ldHdvcmssIHsgYW1vdW50VHlwZTogJ2JpZ2ludCcgfSk7XG4gICAgICByZXR1cm4gY3VtdWxhdGl2ZSArIEJpZ0ludCh0eC5vdXRzW3R4SW5wdXQuaW5kZXhdLnZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjb3VsZCBub3QgZmluZCB2YWx1ZSBvbiBpbnB1dCcpO1xuICAgIH1cbiAgfSwgQmlnSW50KDApKTtcblxuICByZXR1cm4ge1xuICAgIC4uLmNvbW1vbixcbiAgICBmZWU6IChpbnB1dEFtb3VudCAtIG91dHB1dEFtb3VudCkudG9TdHJpbmcoKSxcbiAgICBpbnB1dFNpZ25hdHVyZXM6IGlucHV0U2lnbmF0dXJlc0NvdW50LFxuICAgIHNpZ25hdHVyZXM6IGlucHV0U2lnbmF0dXJlc0NvdW50LnJlZHVjZSgocHJldiwgY3VycikgPT4gKGN1cnIgPiBwcmV2ID8gY3VyciA6IHByZXYpLCAwKSxcbiAgfSBhcyBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXhwbGFpbkxlZ2FjeVR4PFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQ+KFxuICB0eDogYml0Z28uVXR4b1RyYW5zYWN0aW9uPFROdW1iZXI+LFxuICBwYXJhbXM6IHtcbiAgICBwdWJzPzogc3RyaW5nW107XG4gICAgdHhJbmZvPzogeyB1bnNwZW50cz86IGJpdGdvLlVuc3BlbnQ8VE51bWJlcj5bXSB9O1xuICAgIGNoYW5nZUluZm8/OiB7IGFkZHJlc3M6IHN0cmluZzsgY2hhaW46IG51bWJlcjsgaW5kZXg6IG51bWJlciB9W107XG4gIH0sXG4gIG5ldHdvcms6IHV0eG9saWIuTmV0d29ya1xuKTogVHJhbnNhY3Rpb25FeHBsYW5hdGlvbiB7XG4gIGNvbnN0IGNvbW1vbiA9IGV4cGxhaW5Db21tb24odHgsIHBhcmFtcywgbmV0d29yayk7XG4gIGNvbnN0IGlucHV0U2lnbmF0dXJlc0NvdW50ID0gZ2V0VHhJbnB1dFNpZ25hdHVyZXNDb3VudCh0eCwgcGFyYW1zLCBuZXR3b3JrKTtcbiAgcmV0dXJuIHtcbiAgICAuLi5jb21tb24sXG4gICAgaW5wdXRTaWduYXR1cmVzOiBpbnB1dFNpZ25hdHVyZXNDb3VudCxcbiAgICBzaWduYXR1cmVzOiBpbnB1dFNpZ25hdHVyZXNDb3VudC5yZWR1Y2UoKHByZXYsIGN1cnIpID0+IChjdXJyID4gcHJldiA/IGN1cnIgOiBwcmV2KSwgMCksXG4gIH0gYXMgVHJhbnNhY3Rpb25FeHBsYW5hdGlvbjtcbn1cbiJdfQ==

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


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