PHP WebShell

Текущая директория: /opt/BitGoJS/modules/sdk-coin-avaxp/dist/src/lib

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

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DeprecatedTransaction = void 0;
const sdk_core_1 = require("@bitgo/sdk-core");
const iface_1 = require("./iface");
const avalanche_1 = require("avalanche");
const utils_1 = __importDefault(require("./utils"));
function isEmptySignature(s) {
    return !!s && s.startsWith(''.padStart(90, '0'));
}
/**
 * Signatures are prestore as empty buffer for hsm and address of signar for first signature.
 * When sign is required, this method return the function that identify a signature to be replaced.
 * @param signatures any signatures as samples to identify which signature required replace.
 */
function generateSelectorSignature(signatures) {
    if (signatures.length > 1 && signatures.every((sig) => isEmptySignature(sig.bytes))) {
        // Look for address.
        return function (sig, address) {
            try {
                if (!isEmptySignature(sig.bytes)) {
                    return false;
                }
                const pub = sig.bytes.substring(90);
                return pub === address;
            }
            catch (e) {
                return false;
            }
        };
    }
    else {
        // Look for empty string
        return function (sig, address) {
            if (isEmptySignature(sig.bytes))
                return true;
            return false;
        };
    }
}
// end region utils for sign
class DeprecatedTransaction extends sdk_core_1.BaseTransaction {
    constructor(coinConfig) {
        super(coinConfig);
        this._threshold = 2;
        this._locktime = new avalanche_1.BN(0);
        this._fromAddresses = [];
        this._utxos = [];
        this._fee = {};
        this._network = coinConfig.network;
        this._assetId = utils_1.default.cb58Decode(this._network.avaxAssetID);
        this._blockchainID = utils_1.default.cb58Decode(this._network.blockchainID);
        this._networkID = this._network.networkID;
    }
    get avaxPTransaction() {
        return this._avaxTransaction.getUnsignedTx().getTransaction();
    }
    get signature() {
        if (this.credentials.length === 0) {
            return [];
        }
        const obj = this.credentials[0].serialize();
        return obj.sigArray.map((s) => s.bytes).filter((s) => !isEmptySignature(s));
    }
    get credentials() {
        return this._avaxTransaction?.credentials;
    }
    get hasCredentials() {
        return this.credentials !== undefined && this.credentials.length > 0;
    }
    /** @inheritdoc */
    canSign({ key }) {
        // TODO(BG-56700):  Improve canSign by check in addresses in empty credentials match signer
        return true;
    }
    /**
     * Sign a avaxp transaction and update the transaction hex
     * validator, delegator, import, exports extend baseTx
     * unsignedTx: UnsignedTx = new UnsignedTx(baseTx)  (baseTx = addValidatorTx)
     * const tx: Tx = unsignedTx.sign(keychain) (tx is type standard signed tx)
     * get baseTx then create new unsignedTx then sign
     *
     * @param {KeyPair} keyPair
     */
    sign(keyPair) {
        const prv = keyPair.getPrivateKey();
        const addressHex = keyPair.getAddressBuffer().toString('hex');
        if (!prv) {
            throw new sdk_core_1.SigningError('Missing private key');
        }
        if (!this.avaxPTransaction) {
            throw new sdk_core_1.InvalidTransactionError('empty transaction to sign');
        }
        if (!this.hasCredentials) {
            throw new sdk_core_1.InvalidTransactionError('empty credentials to sign');
        }
        const signature = this.createSignature(prv);
        let checkSign = undefined;
        this.credentials.forEach((c, index) => {
            const cs = c.serialize();
            if (checkSign === undefined) {
                checkSign = generateSelectorSignature(cs.sigArray);
            }
            let find = false;
            cs.sigArray.forEach((sig) => {
                if (checkSign && checkSign(sig, addressHex)) {
                    sig.bytes = signature;
                    find = true;
                }
            });
            if (!find)
                throw new sdk_core_1.SigningError('Private key cannot sign the transaction');
            c.deserialize(cs);
        });
    }
    /** @inheritdoc */
    /**
     * should be of signedTx doing this with baseTx
     */
    toBroadcastFormat() {
        if (!this.avaxPTransaction) {
            throw new sdk_core_1.InvalidTransactionError('Empty transaction data');
        }
        return this._avaxTransaction.toStringHex();
    }
    // types - stakingTransaction, import, export
    toJson() {
        if (!this.avaxPTransaction) {
            throw new sdk_core_1.InvalidTransactionError('Empty transaction data');
        }
        return {
            id: this.id,
            inputs: this.inputs,
            fromAddresses: this.fromAddresses,
            threshold: this._threshold,
            locktime: this._locktime.toString(),
            type: this.type,
            signatures: this.signature,
            outputs: this.outputs,
            changeOutputs: this.changeOutputs,
            sourceChain: this.sourceChain,
            destinationChain: this.destinationChain,
        };
    }
    setTransaction(tx) {
        this._avaxTransaction = tx;
    }
    /**
     * Set the transaction type
     *
     * @param {TransactionType} transactionType The transaction type to be set
     */
    setTransactionType(transactionType) {
        this._type = transactionType;
    }
    /**
     * Returns the portion of the transaction that needs to be signed in Buffer format.
     * Only needed for coins that support adding signatures directly (e.g. TSS).
     */
    get signablePayload() {
        return utils_1.default.sha256(this._avaxTransaction.getUnsignedTx().toBuffer());
    }
    get id() {
        return utils_1.default.cb58Encode(avalanche_1.Buffer.from(utils_1.default.sha256(this._avaxTransaction.toBuffer())));
    }
    get fromAddresses() {
        return this._fromAddresses.map((a) => utils_1.default.addressToString(this._network.hrp, this._network.alias, a));
    }
    get rewardAddresses() {
        return this._rewardAddresses.map((a) => utils_1.default.addressToString(this._network.hrp, this._network.alias, a));
    }
    /**
     * Get the list of outputs. Amounts are expressed in absolute value.
     */
    get outputs() {
        switch (this.type) {
            case sdk_core_1.TransactionType.Import:
                return this.avaxPTransaction
                    .getOuts()
                    .map(utils_1.default.deprecatedMapOutputToEntry(this._network));
            case sdk_core_1.TransactionType.Export:
                if (utils_1.default.isTransactionOf(this._avaxTransaction, this._network.cChainBlockchainID)) {
                    return this.avaxPTransaction
                        .getExportedOutputs()
                        .map(utils_1.default.deprecatedMapOutputToEntry(this._network));
                }
                else {
                    return this.avaxPTransaction
                        .getExportOutputs()
                        .map(utils_1.default.deprecatedMapOutputToEntry(this._network));
                }
            case sdk_core_1.TransactionType.AddDelegator:
            case sdk_core_1.TransactionType.AddValidator:
                // Get staked outputs
                const addValidatorTx = this.avaxPTransaction;
                return [
                    {
                        address: addValidatorTx.getNodeIDString(),
                        value: addValidatorTx.getStakeAmount().toString(),
                    },
                ];
            default:
                return [];
        }
    }
    /**
     * Get a Transasction Fee.
     */
    get fee() {
        return { fee: '0', ...this._fee };
    }
    get changeOutputs() {
        // C-chain tx adn Import Txs don't have change outputs
        if (this.type === sdk_core_1.TransactionType.Import ||
            utils_1.default.isTransactionOf(this._avaxTransaction, this._network.cChainBlockchainID)) {
            return [];
        }
        // general support any transaction type, but it's scoped yet
        return this.avaxPTransaction.getOuts().map(utils_1.default.deprecatedMapOutputToEntry(this._network));
    }
    get inputs() {
        let inputs;
        switch (this.type) {
            case sdk_core_1.TransactionType.Import:
                inputs = this.avaxPTransaction.getImportInputs();
                break;
            case sdk_core_1.TransactionType.Export:
                if (utils_1.default.isTransactionOf(this._avaxTransaction, this._network.cChainBlockchainID)) {
                    return this.avaxPTransaction.getInputs().map((evmInput) => ({
                        address: '0x' + evmInput.getAddressString(),
                        value: new avalanche_1.BN(evmInput.amount).toString(),
                        nonce: evmInput.getNonce().toNumber(),
                    }));
                }
                inputs = this.avaxPTransaction.getIns();
                break;
            default:
                inputs = this.avaxPTransaction.getIns();
        }
        return inputs.map((input) => {
            const amountInput = input.getInput();
            return {
                id: utils_1.default.cb58Encode(input.getTxID()) + iface_1.INPUT_SEPARATOR + utils_1.default.outputidxBufferToNumber(input.getOutputIdx()),
                address: this.fromAddresses.sort().join(iface_1.ADDRESS_SEPARATOR),
                value: amountInput.getAmount().toString(),
            };
        });
    }
    /**
     * Avax wrapper to create signature and return it for credentials
     * @param prv
     * @return hexstring
     */
    createSignature(prv) {
        const signval = utils_1.default.createSignatureAvaxBuffer(this._network, avalanche_1.Buffer.from(this.signablePayload), avalanche_1.Buffer.from(prv));
        return signval.toString('hex');
    }
    /** @inheritdoc */
    explainTransaction() {
        const txJson = this.toJson();
        const displayOrder = ['id', 'inputs', 'outputAmount', 'changeAmount', 'outputs', 'changeOutputs', 'fee', 'type'];
        const outputAmount = txJson.outputs.reduce((p, n) => p.add(new avalanche_1.BN(n.value)), new avalanche_1.BN(0)).toString();
        const changeAmount = txJson.changeOutputs.reduce((p, n) => p.add(new avalanche_1.BN(n.value)), new avalanche_1.BN(0)).toString();
        let rewardAddresses;
        if ([sdk_core_1.TransactionType.AddValidator, sdk_core_1.TransactionType.AddDelegator].includes(txJson.type)) {
            rewardAddresses = this.rewardAddresses;
            displayOrder.splice(6, 0, 'rewardAddresses');
        }
        return {
            displayOrder,
            id: txJson.id,
            inputs: txJson.inputs,
            outputs: txJson.outputs.map((o) => ({ address: o.address, amount: o.value })),
            outputAmount,
            changeOutputs: txJson.changeOutputs.map((o) => ({ address: o.address, amount: o.value })),
            changeAmount,
            rewardAddresses,
            fee: this.fee,
            type: txJson.type,
        };
    }
    /**
     * Check if this transaction is a P chain
     */
    get isTransactionForCChain() {
        return utils_1.default.isTransactionOf(this._avaxTransaction, this._network.cChainBlockchainID);
    }
    /**
     * get the source chain id or undefined if it's a cross chain transfer.
     */
    get sourceChain() {
        let blockchainID;
        switch (this.type) {
            case sdk_core_1.TransactionType.Import:
                blockchainID = this.avaxPTransaction.getSourceChain();
                break;
            case sdk_core_1.TransactionType.Export:
                blockchainID = this.avaxPTransaction.getBlockchainID();
                break;
            default:
                return undefined;
        }
        return this.blockchainIDtoAlias(blockchainID);
    }
    /**
     * get the destinationChain or undefined if it's a cross chain transfer.
     */
    get destinationChain() {
        let blockchainID;
        switch (this.type) {
            case sdk_core_1.TransactionType.Import:
                blockchainID = this.avaxPTransaction.getBlockchainID();
                break;
            case sdk_core_1.TransactionType.Export:
                blockchainID = this.avaxPTransaction.getDestinationChain();
                break;
            default:
                return undefined;
        }
        return this.blockchainIDtoAlias(blockchainID);
    }
    /**
     * Convert a blockchainId buffer to string and return P or C alias if match of any of that chains.
     * @param {BufferAvax} blockchainIDBuffer
     * @return {string} blocchainID or alias if exists.
     * @private
     */
    blockchainIDtoAlias(blockchainIDBuffer) {
        const blockchainId = utils_1.default.cb58Encode(blockchainIDBuffer);
        switch (blockchainId) {
            case this._network.cChainBlockchainID:
                return 'C';
            case this._network.blockchainID:
                return 'P';
            default:
                return blockchainId;
        }
    }
}
exports.DeprecatedTransaction = DeprecatedTransaction;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwcmVjYXRlZFRyYW5zYWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9kZXByZWNhdGVkVHJhbnNhY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQ0EsOENBUXlCO0FBRXpCLG1DQVFpQjtBQUdqQix5Q0FBcUQ7QUFDckQsb0RBQTRCO0FBWTVCLFNBQVMsZ0JBQWdCLENBQUMsQ0FBUztJQUNqQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ25ELENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBUyx5QkFBeUIsQ0FBQyxVQUFpQztJQUNsRSxJQUFJLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDcEYsb0JBQW9CO1FBQ3BCLE9BQU8sVUFBVSxHQUFHLEVBQUUsT0FBTztZQUMzQixJQUFJLENBQUM7Z0JBQ0gsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO29CQUNqQyxPQUFPLEtBQUssQ0FBQztnQkFDZixDQUFDO2dCQUNELE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNwQyxPQUFPLEdBQUcsS0FBSyxPQUFPLENBQUM7WUFDekIsQ0FBQztZQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ1gsT0FBTyxLQUFLLENBQUM7WUFDZixDQUFDO1FBQ0gsQ0FBQyxDQUFDO0lBQ0osQ0FBQztTQUFNLENBQUM7UUFDTix3QkFBd0I7UUFDeEIsT0FBTyxVQUFVLEdBQUcsRUFBRSxPQUFPO1lBQzNCLElBQUksZ0JBQWdCLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQztnQkFBRSxPQUFPLElBQUksQ0FBQztZQUM3QyxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUMsQ0FBQztJQUNKLENBQUM7QUFDSCxDQUFDO0FBQ0QsNEJBQTRCO0FBRTVCLE1BQWEscUJBQXNCLFNBQVEsMEJBQWU7SUFleEQsWUFBWSxVQUFnQztRQUMxQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7UUFUYixlQUFVLEdBQUcsQ0FBQyxDQUFDO1FBQ2YsY0FBUyxHQUFPLElBQUksY0FBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzFCLG1CQUFjLEdBQWlCLEVBQUUsQ0FBQztRQUVsQyxXQUFNLEdBQXFCLEVBQUUsQ0FBQztRQUU5QixTQUFJLEdBQTRCLEVBQUUsQ0FBQztRQUl4QyxJQUFJLENBQUMsUUFBUSxHQUFHLFVBQVUsQ0FBQyxPQUEyQixDQUFDO1FBQ3ZELElBQUksQ0FBQyxRQUFRLEdBQUcsZUFBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzVELElBQUksQ0FBQyxhQUFhLEdBQUcsZUFBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ2xFLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUM7SUFDNUMsQ0FBQztJQUVELElBQUksZ0JBQWdCO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLGFBQWEsRUFBRSxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQ2hFLENBQUM7SUFFRCxJQUFJLFNBQVM7UUFDWCxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ2xDLE9BQU8sRUFBRSxDQUFDO1FBQ1osQ0FBQztRQUNELE1BQU0sR0FBRyxHQUFRLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDakQsT0FBTyxHQUFHLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzlFLENBQUM7SUFFRCxJQUFJLFdBQVc7UUFDYixPQUFRLElBQUksQ0FBQyxnQkFBd0IsRUFBRSxXQUFXLENBQUM7SUFDckQsQ0FBQztJQUVELElBQUksY0FBYztRQUNoQixPQUFPLElBQUksQ0FBQyxXQUFXLEtBQUssU0FBUyxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUN2RSxDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLE9BQU8sQ0FBQyxFQUFFLEdBQUcsRUFBVztRQUN0QiwyRkFBMkY7UUFDM0YsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSCxJQUFJLENBQUMsT0FBZ0I7UUFDbkIsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3BDLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5RCxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDVCxNQUFNLElBQUksdUJBQVksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQ2hELENBQUM7UUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDM0IsTUFBTSxJQUFJLGtDQUF1QixDQUFDLDJCQUEyQixDQUFDLENBQUM7UUFDakUsQ0FBQztRQUNELElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDekIsTUFBTSxJQUFJLGtDQUF1QixDQUFDLDJCQUEyQixDQUFDLENBQUM7UUFDakUsQ0FBQztRQUNELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDNUMsSUFBSSxTQUFTLEdBQStCLFNBQVMsQ0FBQztRQUN0RCxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRTtZQUNwQyxNQUFNLEVBQUUsR0FBUSxDQUFDLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDOUIsSUFBSSxTQUFTLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQzVCLFNBQVMsR0FBRyx5QkFBeUIsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDckQsQ0FBQztZQUNELElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQztZQUNqQixFQUFFLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO2dCQUMxQixJQUFJLFNBQVMsSUFBSSxTQUFTLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQyxFQUFFLENBQUM7b0JBQzVDLEdBQUcsQ0FBQyxLQUFLLEdBQUcsU0FBUyxDQUFDO29CQUN0QixJQUFJLEdBQUcsSUFBSSxDQUFDO2dCQUNkLENBQUM7WUFDSCxDQUFDLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxJQUFJO2dCQUFFLE1BQU0sSUFBSSx1QkFBWSxDQUFDLHlDQUF5QyxDQUFDLENBQUM7WUFDN0UsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNwQixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxrQkFBa0I7SUFDbEI7O09BRUc7SUFDSCxpQkFBaUI7UUFDZixJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDM0IsTUFBTSxJQUFJLGtDQUF1QixDQUFDLHdCQUF3QixDQUFDLENBQUM7UUFDOUQsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQzdDLENBQUM7SUFFRCw2Q0FBNkM7SUFDN0MsTUFBTTtRQUNKLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUMzQixNQUFNLElBQUksa0NBQXVCLENBQUMsd0JBQXdCLENBQUMsQ0FBQztRQUM5RCxDQUFDO1FBQ0QsT0FBTztZQUNMLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRTtZQUNYLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTTtZQUNuQixhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWE7WUFDakMsU0FBUyxFQUFFLElBQUksQ0FBQyxVQUFVO1lBQzFCLFFBQVEsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRTtZQUNuQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7WUFDZixVQUFVLEVBQUUsSUFBSSxDQUFDLFNBQVM7WUFDMUIsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO1lBQ3JCLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYTtZQUNqQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVc7WUFDN0IsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLGdCQUFnQjtTQUN4QyxDQUFDO0lBQ0osQ0FBQztJQUVELGNBQWMsQ0FBQyxFQUFnQjtRQUM3QixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsa0JBQWtCLENBQUMsZUFBZ0M7UUFDakQsSUFBSSxDQUFDLEtBQUssR0FBRyxlQUFlLENBQUM7SUFDL0IsQ0FBQztJQUVEOzs7T0FHRztJQUNILElBQUksZUFBZTtRQUNqQixPQUFPLGVBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGFBQWEsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDeEUsQ0FBQztJQUVELElBQUksRUFBRTtRQUNKLE9BQU8sZUFBSyxDQUFDLFVBQVUsQ0FBQyxrQkFBVSxDQUFDLElBQUksQ0FBQyxlQUFLLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMzRixDQUFDO0lBRUQsSUFBSSxhQUFhO1FBQ2YsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsZUFBSyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzFHLENBQUM7SUFFRCxJQUFJLGVBQWU7UUFDakIsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxlQUFLLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDNUcsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSSxPQUFPO1FBQ1QsUUFBUSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDbEIsS0FBSywwQkFBZSxDQUFDLE1BQU07Z0JBQ3pCLE9BQVEsSUFBSSxDQUFDLGdCQUEyQztxQkFDckQsT0FBTyxFQUFFO3FCQUNULEdBQUcsQ0FBQyxlQUFLLENBQUMsMEJBQTBCLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDMUQsS0FBSywwQkFBZSxDQUFDLE1BQU07Z0JBQ3pCLElBQUksZUFBSyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLENBQUM7b0JBQ25GLE9BQVEsSUFBSSxDQUFDLGdCQUFnQzt5QkFDMUMsa0JBQWtCLEVBQUU7eUJBQ3BCLEdBQUcsQ0FBQyxlQUFLLENBQUMsMEJBQTBCLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7Z0JBQzFELENBQUM7cUJBQU0sQ0FBQztvQkFDTixPQUFRLElBQUksQ0FBQyxnQkFBNkI7eUJBQ3ZDLGdCQUFnQixFQUFFO3lCQUNsQixHQUFHLENBQUMsZUFBSyxDQUFDLDBCQUEwQixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO2dCQUMxRCxDQUFDO1lBQ0gsS0FBSywwQkFBZSxDQUFDLFlBQVksQ0FBQztZQUNsQyxLQUFLLDBCQUFlLENBQUMsWUFBWTtnQkFDL0IscUJBQXFCO2dCQUNyQixNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsZ0JBQWtDLENBQUM7Z0JBQy9ELE9BQU87b0JBQ0w7d0JBQ0UsT0FBTyxFQUFFLGNBQWMsQ0FBQyxlQUFlLEVBQUU7d0JBQ3pDLEtBQUssRUFBRSxjQUFjLENBQUMsY0FBYyxFQUFFLENBQUMsUUFBUSxFQUFFO3FCQUNsRDtpQkFDRixDQUFDO1lBQ0o7Z0JBQ0UsT0FBTyxFQUFFLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSSxHQUFHO1FBQ0wsT0FBTyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDcEMsQ0FBQztJQUVELElBQUksYUFBYTtRQUNmLHNEQUFzRDtRQUN0RCxJQUNFLElBQUksQ0FBQyxJQUFJLEtBQUssMEJBQWUsQ0FBQyxNQUFNO1lBQ3BDLGVBQUssQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsa0JBQWtCLENBQUMsRUFDOUUsQ0FBQztZQUNELE9BQU8sRUFBRSxDQUFDO1FBQ1osQ0FBQztRQUNELDREQUE0RDtRQUM1RCxPQUFRLElBQUksQ0FBQyxnQkFBOEIsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsZUFBSyxDQUFDLDBCQUEwQixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQzdHLENBQUM7SUFFRCxJQUFJLE1BQU07UUFDUixJQUFJLE1BQU0sQ0FBQztRQUNYLFFBQVEsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2xCLEtBQUssMEJBQWUsQ0FBQyxNQUFNO2dCQUN6QixNQUFNLEdBQUksSUFBSSxDQUFDLGdCQUEyQyxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUM3RSxNQUFNO1lBQ1IsS0FBSywwQkFBZSxDQUFDLE1BQU07Z0JBQ3pCLElBQUksZUFBSyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLENBQUM7b0JBQ25GLE9BQVEsSUFBSSxDQUFDLGdCQUFnQyxDQUFDLFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQzt3QkFDM0UsT0FBTyxFQUFFLElBQUksR0FBRyxRQUFRLENBQUMsZ0JBQWdCLEVBQUU7d0JBQzNDLEtBQUssRUFBRSxJQUFJLGNBQUUsQ0FBRSxRQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLFFBQVEsRUFBRTt3QkFDbEQsS0FBSyxFQUFFLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxRQUFRLEVBQUU7cUJBQ3RDLENBQUMsQ0FBQyxDQUFDO2dCQUNOLENBQUM7Z0JBQ0QsTUFBTSxHQUFJLElBQUksQ0FBQyxnQkFBOEIsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDdkQsTUFBTTtZQUNSO2dCQUNFLE1BQU0sR0FBSSxJQUFJLENBQUMsZ0JBQThCLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDM0QsQ0FBQztRQUNELE9BQU8sTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQzFCLE1BQU0sV0FBVyxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQXdCLENBQUM7WUFDM0QsT0FBTztnQkFDTCxFQUFFLEVBQUUsZUFBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBRyx1QkFBZSxHQUFHLGVBQUssQ0FBQyx1QkFBdUIsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQzdHLE9BQU8sRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyx5QkFBaUIsQ0FBQztnQkFDMUQsS0FBSyxFQUFFLFdBQVcsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxRQUFRLEVBQUU7YUFDMUMsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxlQUFlLENBQUMsR0FBVztRQUN6QixNQUFNLE9BQU8sR0FBRyxlQUFLLENBQUMseUJBQXlCLENBQzdDLElBQUksQ0FBQyxRQUFRLEVBQ2Isa0JBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxFQUNyQyxrQkFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FDckIsQ0FBQztRQUNGLE9BQU8sT0FBTyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLGtCQUFrQjtRQUNoQixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDN0IsTUFBTSxZQUFZLEdBQUcsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLGNBQWMsRUFBRSxjQUFjLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFakgsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksY0FBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLElBQUksY0FBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDbkcsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksY0FBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLElBQUksY0FBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7UUFFekcsSUFBSSxlQUFlLENBQUM7UUFDcEIsSUFBSSxDQUFDLDBCQUFlLENBQUMsWUFBWSxFQUFFLDBCQUFlLENBQUMsWUFBWSxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ3ZGLGVBQWUsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDO1lBQ3ZDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1FBQy9DLENBQUM7UUFFRCxPQUFPO1lBQ0wsWUFBWTtZQUNaLEVBQUUsRUFBRSxNQUFNLENBQUMsRUFBRTtZQUNiLE1BQU0sRUFBRSxNQUFNLENBQUMsTUFBTTtZQUNyQixPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDN0UsWUFBWTtZQUNaLGFBQWEsRUFBRSxNQUFNLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUN6RixZQUFZO1lBQ1osZUFBZTtZQUNmLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRztZQUNiLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSTtTQUNsQixDQUFDO0lBQ0osQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSSxzQkFBc0I7UUFDeEIsT0FBTyxlQUFLLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFDLENBQUM7SUFDeEYsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSSxXQUFXO1FBQ2IsSUFBSSxZQUFZLENBQUM7UUFDakIsUUFBUSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDbEIsS0FBSywwQkFBZSxDQUFDLE1BQU07Z0JBQ3pCLFlBQVksR0FBSSxJQUFJLENBQUMsZ0JBQTJDLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQ2xGLE1BQU07WUFDUixLQUFLLDBCQUFlLENBQUMsTUFBTTtnQkFDekIsWUFBWSxHQUFJLElBQUksQ0FBQyxnQkFBMkMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztnQkFDbkYsTUFBTTtZQUNSO2dCQUNFLE9BQU8sU0FBUyxDQUFDO1FBQ3JCLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFJLGdCQUFnQjtRQUNsQixJQUFJLFlBQVksQ0FBQztRQUNqQixRQUFRLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNsQixLQUFLLDBCQUFlLENBQUMsTUFBTTtnQkFDekIsWUFBWSxHQUFJLElBQUksQ0FBQyxnQkFBMkMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztnQkFDbkYsTUFBTTtZQUNSLEtBQUssMEJBQWUsQ0FBQyxNQUFNO2dCQUN6QixZQUFZLEdBQUksSUFBSSxDQUFDLGdCQUEyQyxDQUFDLG1CQUFtQixFQUFFLENBQUM7Z0JBQ3ZGLE1BQU07WUFDUjtnQkFDRSxPQUFPLFNBQVMsQ0FBQztRQUNyQixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ssbUJBQW1CLENBQUMsa0JBQThCO1FBQ3hELE1BQU0sWUFBWSxHQUFHLGVBQUssQ0FBQyxVQUFVLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUMxRCxRQUFRLFlBQVksRUFBRSxDQUFDO1lBQ3JCLEtBQUssSUFBSSxDQUFDLFFBQVEsQ0FBQyxrQkFBa0I7Z0JBQ25DLE9BQU8sR0FBRyxDQUFDO1lBQ2IsS0FBSyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVk7Z0JBQzdCLE9BQU8sR0FBRyxDQUFDO1lBQ2I7Z0JBQ0UsT0FBTyxZQUFZLENBQUM7UUFDeEIsQ0FBQztJQUNILENBQUM7Q0FDRjtBQWpWRCxzREFpVkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBdmFsYW5jaGVOZXR3b3JrLCBCYXNlQ29pbiBhcyBDb2luQ29uZmlnIH0gZnJvbSAnQGJpdGdvL3N0YXRpY3MnO1xuaW1wb3J0IHtcbiAgQmFzZUtleSxcbiAgQmFzZVRyYW5zYWN0aW9uLFxuICBFbnRyeSxcbiAgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IsXG4gIFNpZ25pbmdFcnJvcixcbiAgVHJhbnNhY3Rpb25GZWUsXG4gIFRyYW5zYWN0aW9uVHlwZSxcbn0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCB7IEtleVBhaXIgfSBmcm9tICcuL2tleVBhaXInO1xuaW1wb3J0IHtcbiAgRGVwcmVjYXRlZEJhc2VUeCxcbiAgRGVjb2RlZFV0eG9PYmosXG4gIFRyYW5zYWN0aW9uRXhwbGFuYXRpb24sXG4gIERlcHJlY2F0ZWRUeCxcbiAgVHhEYXRhLFxuICBJTlBVVF9TRVBBUkFUT1IsXG4gIEFERFJFU1NfU0VQQVJBVE9SLFxufSBmcm9tICcuL2lmYWNlJztcbmltcG9ydCB7IEFkZERlbGVnYXRvclR4LCBBbW91bnRJbnB1dCwgQmFzZVR4IGFzIFBWTUJhc2VUeCwgRXhwb3J0VHgsIEltcG9ydFR4IH0gZnJvbSAnYXZhbGFuY2hlL2Rpc3QvYXBpcy9wbGF0Zm9ybXZtJztcbmltcG9ydCB7IEV4cG9ydFR4IGFzIEVWTUV4cG9ydFR4LCBJbXBvcnRUeCBhcyBFVk1JbXBvcnRUeCB9IGZyb20gJ2F2YWxhbmNoZS9kaXN0L2FwaXMvZXZtJztcbmltcG9ydCB7IEJOLCBCdWZmZXIgYXMgQnVmZmVyQXZheCB9IGZyb20gJ2F2YWxhbmNoZSc7XG5pbXBvcnQgdXRpbHMgZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgeyBDcmVkZW50aWFsIH0gZnJvbSAnYXZhbGFuY2hlL2Rpc3QvY29tbW9uJztcbmltcG9ydCB7IEJ1ZmZlciB9IGZyb20gJ2J1ZmZlcic7XG5cbi8vIHJlZ2lvbiB1dGlscyB0byBzaWduXG5pbnRlcmZhY2Ugc2lnbmF0dXJlU2VyaWFsaXplZCB7XG4gIGJ5dGVzOiBzdHJpbmc7XG59XG5pbnRlcmZhY2UgQ2hlY2tTaWduYXR1cmUge1xuICAoc2lnYXR1cmU6IHNpZ25hdHVyZVNlcmlhbGl6ZWQsIGFkZHJlc3NIZXg6IHN0cmluZyk6IGJvb2xlYW47XG59XG5cbmZ1bmN0aW9uIGlzRW1wdHlTaWduYXR1cmUoczogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiAhIXMgJiYgcy5zdGFydHNXaXRoKCcnLnBhZFN0YXJ0KDkwLCAnMCcpKTtcbn1cblxuLyoqXG4gKiBTaWduYXR1cmVzIGFyZSBwcmVzdG9yZSBhcyBlbXB0eSBidWZmZXIgZm9yIGhzbSBhbmQgYWRkcmVzcyBvZiBzaWduYXIgZm9yIGZpcnN0IHNpZ25hdHVyZS5cbiAqIFdoZW4gc2lnbiBpcyByZXF1aXJlZCwgdGhpcyBtZXRob2QgcmV0dXJuIHRoZSBmdW5jdGlvbiB0aGF0IGlkZW50aWZ5IGEgc2lnbmF0dXJlIHRvIGJlIHJlcGxhY2VkLlxuICogQHBhcmFtIHNpZ25hdHVyZXMgYW55IHNpZ25hdHVyZXMgYXMgc2FtcGxlcyB0byBpZGVudGlmeSB3aGljaCBzaWduYXR1cmUgcmVxdWlyZWQgcmVwbGFjZS5cbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVTZWxlY3RvclNpZ25hdHVyZShzaWduYXR1cmVzOiBzaWduYXR1cmVTZXJpYWxpemVkW10pOiBDaGVja1NpZ25hdHVyZSB7XG4gIGlmIChzaWduYXR1cmVzLmxlbmd0aCA+IDEgJiYgc2lnbmF0dXJlcy5ldmVyeSgoc2lnKSA9PiBpc0VtcHR5U2lnbmF0dXJlKHNpZy5ieXRlcykpKSB7XG4gICAgLy8gTG9vayBmb3IgYWRkcmVzcy5cbiAgICByZXR1cm4gZnVuY3Rpb24gKHNpZywgYWRkcmVzcyk6IGJvb2xlYW4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKCFpc0VtcHR5U2lnbmF0dXJlKHNpZy5ieXRlcykpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHViID0gc2lnLmJ5dGVzLnN1YnN0cmluZyg5MCk7XG4gICAgICAgIHJldHVybiBwdWIgPT09IGFkZHJlc3M7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIC8vIExvb2sgZm9yIGVtcHR5IHN0cmluZ1xuICAgIHJldHVybiBmdW5jdGlvbiAoc2lnLCBhZGRyZXNzKTogYm9vbGVhbiB7XG4gICAgICBpZiAoaXNFbXB0eVNpZ25hdHVyZShzaWcuYnl0ZXMpKSByZXR1cm4gdHJ1ZTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICB9XG59XG4vLyBlbmQgcmVnaW9uIHV0aWxzIGZvciBzaWduXG5cbmV4cG9ydCBjbGFzcyBEZXByZWNhdGVkVHJhbnNhY3Rpb24gZXh0ZW5kcyBCYXNlVHJhbnNhY3Rpb24ge1xuICBwcm90ZWN0ZWQgX2F2YXhUcmFuc2FjdGlvbjogRGVwcmVjYXRlZFR4O1xuICBwdWJsaWMgX3R5cGU6IFRyYW5zYWN0aW9uVHlwZTtcbiAgcHVibGljIF9uZXR3b3JrOiBBdmFsYW5jaGVOZXR3b3JrO1xuICBwdWJsaWMgX25ldHdvcmtJRDogbnVtYmVyO1xuICBwdWJsaWMgX2Fzc2V0SWQ6IEJ1ZmZlckF2YXg7XG4gIHB1YmxpYyBfYmxvY2tjaGFpbklEOiBCdWZmZXJBdmF4O1xuICBwdWJsaWMgX3RocmVzaG9sZCA9IDI7XG4gIHB1YmxpYyBfbG9ja3RpbWU6IEJOID0gbmV3IEJOKDApO1xuICBwdWJsaWMgX2Zyb21BZGRyZXNzZXM6IEJ1ZmZlckF2YXhbXSA9IFtdO1xuICBwdWJsaWMgX3Jld2FyZEFkZHJlc3NlczogQnVmZmVyQXZheFtdO1xuICBwdWJsaWMgX3V0eG9zOiBEZWNvZGVkVXR4b09ialtdID0gW107XG4gIHB1YmxpYyBfdG86IEJ1ZmZlckF2YXhbXTtcbiAgcHVibGljIF9mZWU6IFBhcnRpYWw8VHJhbnNhY3Rpb25GZWU+ID0ge307XG5cbiAgY29uc3RydWN0b3IoY29pbkNvbmZpZzogUmVhZG9ubHk8Q29pbkNvbmZpZz4pIHtcbiAgICBzdXBlcihjb2luQ29uZmlnKTtcbiAgICB0aGlzLl9uZXR3b3JrID0gY29pbkNvbmZpZy5uZXR3b3JrIGFzIEF2YWxhbmNoZU5ldHdvcms7XG4gICAgdGhpcy5fYXNzZXRJZCA9IHV0aWxzLmNiNThEZWNvZGUodGhpcy5fbmV0d29yay5hdmF4QXNzZXRJRCk7XG4gICAgdGhpcy5fYmxvY2tjaGFpbklEID0gdXRpbHMuY2I1OERlY29kZSh0aGlzLl9uZXR3b3JrLmJsb2NrY2hhaW5JRCk7XG4gICAgdGhpcy5fbmV0d29ya0lEID0gdGhpcy5fbmV0d29yay5uZXR3b3JrSUQ7XG4gIH1cblxuICBnZXQgYXZheFBUcmFuc2FjdGlvbigpOiBEZXByZWNhdGVkQmFzZVR4IHtcbiAgICByZXR1cm4gdGhpcy5fYXZheFRyYW5zYWN0aW9uLmdldFVuc2lnbmVkVHgoKS5nZXRUcmFuc2FjdGlvbigpO1xuICB9XG5cbiAgZ2V0IHNpZ25hdHVyZSgpOiBzdHJpbmdbXSB7XG4gICAgaWYgKHRoaXMuY3JlZGVudGlhbHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGNvbnN0IG9iajogYW55ID0gdGhpcy5jcmVkZW50aWFsc1swXS5zZXJpYWxpemUoKTtcbiAgICByZXR1cm4gb2JqLnNpZ0FycmF5Lm1hcCgocykgPT4gcy5ieXRlcykuZmlsdGVyKChzKSA9PiAhaXNFbXB0eVNpZ25hdHVyZShzKSk7XG4gIH1cblxuICBnZXQgY3JlZGVudGlhbHMoKTogQ3JlZGVudGlhbFtdIHtcbiAgICByZXR1cm4gKHRoaXMuX2F2YXhUcmFuc2FjdGlvbiBhcyBhbnkpPy5jcmVkZW50aWFscztcbiAgfVxuXG4gIGdldCBoYXNDcmVkZW50aWFscygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5jcmVkZW50aWFscyAhPT0gdW5kZWZpbmVkICYmIHRoaXMuY3JlZGVudGlhbHMubGVuZ3RoID4gMDtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICBjYW5TaWduKHsga2V5IH06IEJhc2VLZXkpOiBib29sZWFuIHtcbiAgICAvLyBUT0RPKEJHLTU2NzAwKTogIEltcHJvdmUgY2FuU2lnbiBieSBjaGVjayBpbiBhZGRyZXNzZXMgaW4gZW1wdHkgY3JlZGVudGlhbHMgbWF0Y2ggc2lnbmVyXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogU2lnbiBhIGF2YXhwIHRyYW5zYWN0aW9uIGFuZCB1cGRhdGUgdGhlIHRyYW5zYWN0aW9uIGhleFxuICAgKiB2YWxpZGF0b3IsIGRlbGVnYXRvciwgaW1wb3J0LCBleHBvcnRzIGV4dGVuZCBiYXNlVHhcbiAgICogdW5zaWduZWRUeDogVW5zaWduZWRUeCA9IG5ldyBVbnNpZ25lZFR4KGJhc2VUeCkgIChiYXNlVHggPSBhZGRWYWxpZGF0b3JUeClcbiAgICogY29uc3QgdHg6IFR4ID0gdW5zaWduZWRUeC5zaWduKGtleWNoYWluKSAodHggaXMgdHlwZSBzdGFuZGFyZCBzaWduZWQgdHgpXG4gICAqIGdldCBiYXNlVHggdGhlbiBjcmVhdGUgbmV3IHVuc2lnbmVkVHggdGhlbiBzaWduXG4gICAqXG4gICAqIEBwYXJhbSB7S2V5UGFpcn0ga2V5UGFpclxuICAgKi9cbiAgc2lnbihrZXlQYWlyOiBLZXlQYWlyKTogdm9pZCB7XG4gICAgY29uc3QgcHJ2ID0ga2V5UGFpci5nZXRQcml2YXRlS2V5KCk7XG4gICAgY29uc3QgYWRkcmVzc0hleCA9IGtleVBhaXIuZ2V0QWRkcmVzc0J1ZmZlcigpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICBpZiAoIXBydikge1xuICAgICAgdGhyb3cgbmV3IFNpZ25pbmdFcnJvcignTWlzc2luZyBwcml2YXRlIGtleScpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuYXZheFBUcmFuc2FjdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCdlbXB0eSB0cmFuc2FjdGlvbiB0byBzaWduJyk7XG4gICAgfVxuICAgIGlmICghdGhpcy5oYXNDcmVkZW50aWFscykge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCdlbXB0eSBjcmVkZW50aWFscyB0byBzaWduJyk7XG4gICAgfVxuICAgIGNvbnN0IHNpZ25hdHVyZSA9IHRoaXMuY3JlYXRlU2lnbmF0dXJlKHBydik7XG4gICAgbGV0IGNoZWNrU2lnbjogQ2hlY2tTaWduYXR1cmUgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5jcmVkZW50aWFscy5mb3JFYWNoKChjLCBpbmRleCkgPT4ge1xuICAgICAgY29uc3QgY3M6IGFueSA9IGMuc2VyaWFsaXplKCk7XG4gICAgICBpZiAoY2hlY2tTaWduID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY2hlY2tTaWduID0gZ2VuZXJhdGVTZWxlY3RvclNpZ25hdHVyZShjcy5zaWdBcnJheSk7XG4gICAgICB9XG4gICAgICBsZXQgZmluZCA9IGZhbHNlO1xuICAgICAgY3Muc2lnQXJyYXkuZm9yRWFjaCgoc2lnKSA9PiB7XG4gICAgICAgIGlmIChjaGVja1NpZ24gJiYgY2hlY2tTaWduKHNpZywgYWRkcmVzc0hleCkpIHtcbiAgICAgICAgICBzaWcuYnl0ZXMgPSBzaWduYXR1cmU7XG4gICAgICAgICAgZmluZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaWYgKCFmaW5kKSB0aHJvdyBuZXcgU2lnbmluZ0Vycm9yKCdQcml2YXRlIGtleSBjYW5ub3Qgc2lnbiB0aGUgdHJhbnNhY3Rpb24nKTtcbiAgICAgIGMuZGVzZXJpYWxpemUoY3MpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIC8qKlxuICAgKiBzaG91bGQgYmUgb2Ygc2lnbmVkVHggZG9pbmcgdGhpcyB3aXRoIGJhc2VUeFxuICAgKi9cbiAgdG9Ccm9hZGNhc3RGb3JtYXQoKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMuYXZheFBUcmFuc2FjdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCdFbXB0eSB0cmFuc2FjdGlvbiBkYXRhJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9hdmF4VHJhbnNhY3Rpb24udG9TdHJpbmdIZXgoKTtcbiAgfVxuXG4gIC8vIHR5cGVzIC0gc3Rha2luZ1RyYW5zYWN0aW9uLCBpbXBvcnQsIGV4cG9ydFxuICB0b0pzb24oKTogVHhEYXRhIHtcbiAgICBpZiAoIXRoaXMuYXZheFBUcmFuc2FjdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCdFbXB0eSB0cmFuc2FjdGlvbiBkYXRhJyk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBpZDogdGhpcy5pZCxcbiAgICAgIGlucHV0czogdGhpcy5pbnB1dHMsXG4gICAgICBmcm9tQWRkcmVzc2VzOiB0aGlzLmZyb21BZGRyZXNzZXMsXG4gICAgICB0aHJlc2hvbGQ6IHRoaXMuX3RocmVzaG9sZCxcbiAgICAgIGxvY2t0aW1lOiB0aGlzLl9sb2NrdGltZS50b1N0cmluZygpLFxuICAgICAgdHlwZTogdGhpcy50eXBlLFxuICAgICAgc2lnbmF0dXJlczogdGhpcy5zaWduYXR1cmUsXG4gICAgICBvdXRwdXRzOiB0aGlzLm91dHB1dHMsXG4gICAgICBjaGFuZ2VPdXRwdXRzOiB0aGlzLmNoYW5nZU91dHB1dHMsXG4gICAgICBzb3VyY2VDaGFpbjogdGhpcy5zb3VyY2VDaGFpbixcbiAgICAgIGRlc3RpbmF0aW9uQ2hhaW46IHRoaXMuZGVzdGluYXRpb25DaGFpbixcbiAgICB9O1xuICB9XG5cbiAgc2V0VHJhbnNhY3Rpb24odHg6IERlcHJlY2F0ZWRUeCk6IHZvaWQge1xuICAgIHRoaXMuX2F2YXhUcmFuc2FjdGlvbiA9IHR4O1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgdHJhbnNhY3Rpb24gdHlwZVxuICAgKlxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9uVHlwZX0gdHJhbnNhY3Rpb25UeXBlIFRoZSB0cmFuc2FjdGlvbiB0eXBlIHRvIGJlIHNldFxuICAgKi9cbiAgc2V0VHJhbnNhY3Rpb25UeXBlKHRyYW5zYWN0aW9uVHlwZTogVHJhbnNhY3Rpb25UeXBlKTogdm9pZCB7XG4gICAgdGhpcy5fdHlwZSA9IHRyYW5zYWN0aW9uVHlwZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBwb3J0aW9uIG9mIHRoZSB0cmFuc2FjdGlvbiB0aGF0IG5lZWRzIHRvIGJlIHNpZ25lZCBpbiBCdWZmZXIgZm9ybWF0LlxuICAgKiBPbmx5IG5lZWRlZCBmb3IgY29pbnMgdGhhdCBzdXBwb3J0IGFkZGluZyBzaWduYXR1cmVzIGRpcmVjdGx5IChlLmcuIFRTUykuXG4gICAqL1xuICBnZXQgc2lnbmFibGVQYXlsb2FkKCk6IEJ1ZmZlciB7XG4gICAgcmV0dXJuIHV0aWxzLnNoYTI1Nih0aGlzLl9hdmF4VHJhbnNhY3Rpb24uZ2V0VW5zaWduZWRUeCgpLnRvQnVmZmVyKCkpO1xuICB9XG5cbiAgZ2V0IGlkKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHV0aWxzLmNiNThFbmNvZGUoQnVmZmVyQXZheC5mcm9tKHV0aWxzLnNoYTI1Nih0aGlzLl9hdmF4VHJhbnNhY3Rpb24udG9CdWZmZXIoKSkpKTtcbiAgfVxuXG4gIGdldCBmcm9tQWRkcmVzc2VzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5fZnJvbUFkZHJlc3Nlcy5tYXAoKGEpID0+IHV0aWxzLmFkZHJlc3NUb1N0cmluZyh0aGlzLl9uZXR3b3JrLmhycCwgdGhpcy5fbmV0d29yay5hbGlhcywgYSkpO1xuICB9XG5cbiAgZ2V0IHJld2FyZEFkZHJlc3NlcygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuX3Jld2FyZEFkZHJlc3Nlcy5tYXAoKGEpID0+IHV0aWxzLmFkZHJlc3NUb1N0cmluZyh0aGlzLl9uZXR3b3JrLmhycCwgdGhpcy5fbmV0d29yay5hbGlhcywgYSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgbGlzdCBvZiBvdXRwdXRzLiBBbW91bnRzIGFyZSBleHByZXNzZWQgaW4gYWJzb2x1dGUgdmFsdWUuXG4gICAqL1xuICBnZXQgb3V0cHV0cygpOiBFbnRyeVtdIHtcbiAgICBzd2l0Y2ggKHRoaXMudHlwZSkge1xuICAgICAgY2FzZSBUcmFuc2FjdGlvblR5cGUuSW1wb3J0OlxuICAgICAgICByZXR1cm4gKHRoaXMuYXZheFBUcmFuc2FjdGlvbiBhcyBJbXBvcnRUeCB8IEVWTUltcG9ydFR4KVxuICAgICAgICAgIC5nZXRPdXRzKClcbiAgICAgICAgICAubWFwKHV0aWxzLmRlcHJlY2F0ZWRNYXBPdXRwdXRUb0VudHJ5KHRoaXMuX25ldHdvcmspKTtcbiAgICAgIGNhc2UgVHJhbnNhY3Rpb25UeXBlLkV4cG9ydDpcbiAgICAgICAgaWYgKHV0aWxzLmlzVHJhbnNhY3Rpb25PZih0aGlzLl9hdmF4VHJhbnNhY3Rpb24sIHRoaXMuX25ldHdvcmsuY0NoYWluQmxvY2tjaGFpbklEKSkge1xuICAgICAgICAgIHJldHVybiAodGhpcy5hdmF4UFRyYW5zYWN0aW9uIGFzIEVWTUV4cG9ydFR4KVxuICAgICAgICAgICAgLmdldEV4cG9ydGVkT3V0cHV0cygpXG4gICAgICAgICAgICAubWFwKHV0aWxzLmRlcHJlY2F0ZWRNYXBPdXRwdXRUb0VudHJ5KHRoaXMuX25ldHdvcmspKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gKHRoaXMuYXZheFBUcmFuc2FjdGlvbiBhcyBFeHBvcnRUeClcbiAgICAgICAgICAgIC5nZXRFeHBvcnRPdXRwdXRzKClcbiAgICAgICAgICAgIC5tYXAodXRpbHMuZGVwcmVjYXRlZE1hcE91dHB1dFRvRW50cnkodGhpcy5fbmV0d29yaykpO1xuICAgICAgICB9XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5BZGREZWxlZ2F0b3I6XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5BZGRWYWxpZGF0b3I6XG4gICAgICAgIC8vIEdldCBzdGFrZWQgb3V0cHV0c1xuICAgICAgICBjb25zdCBhZGRWYWxpZGF0b3JUeCA9IHRoaXMuYXZheFBUcmFuc2FjdGlvbiBhcyBBZGREZWxlZ2F0b3JUeDtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiBhZGRWYWxpZGF0b3JUeC5nZXROb2RlSURTdHJpbmcoKSxcbiAgICAgICAgICAgIHZhbHVlOiBhZGRWYWxpZGF0b3JUeC5nZXRTdGFrZUFtb3VudCgpLnRvU3RyaW5nKCksXG4gICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IGEgVHJhbnNhc2N0aW9uIEZlZS5cbiAgICovXG4gIGdldCBmZWUoKTogVHJhbnNhY3Rpb25GZWUge1xuICAgIHJldHVybiB7IGZlZTogJzAnLCAuLi50aGlzLl9mZWUgfTtcbiAgfVxuXG4gIGdldCBjaGFuZ2VPdXRwdXRzKCk6IEVudHJ5W10ge1xuICAgIC8vIEMtY2hhaW4gdHggYWRuIEltcG9ydCBUeHMgZG9uJ3QgaGF2ZSBjaGFuZ2Ugb3V0cHV0c1xuICAgIGlmIChcbiAgICAgIHRoaXMudHlwZSA9PT0gVHJhbnNhY3Rpb25UeXBlLkltcG9ydCB8fFxuICAgICAgdXRpbHMuaXNUcmFuc2FjdGlvbk9mKHRoaXMuX2F2YXhUcmFuc2FjdGlvbiwgdGhpcy5fbmV0d29yay5jQ2hhaW5CbG9ja2NoYWluSUQpXG4gICAgKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIC8vIGdlbmVyYWwgc3VwcG9ydCBhbnkgdHJhbnNhY3Rpb24gdHlwZSwgYnV0IGl0J3Mgc2NvcGVkIHlldFxuICAgIHJldHVybiAodGhpcy5hdmF4UFRyYW5zYWN0aW9uIGFzIFBWTUJhc2VUeCkuZ2V0T3V0cygpLm1hcCh1dGlscy5kZXByZWNhdGVkTWFwT3V0cHV0VG9FbnRyeSh0aGlzLl9uZXR3b3JrKSk7XG4gIH1cblxuICBnZXQgaW5wdXRzKCk6IEVudHJ5W10ge1xuICAgIGxldCBpbnB1dHM7XG4gICAgc3dpdGNoICh0aGlzLnR5cGUpIHtcbiAgICAgIGNhc2UgVHJhbnNhY3Rpb25UeXBlLkltcG9ydDpcbiAgICAgICAgaW5wdXRzID0gKHRoaXMuYXZheFBUcmFuc2FjdGlvbiBhcyBJbXBvcnRUeCB8IEVWTUltcG9ydFR4KS5nZXRJbXBvcnRJbnB1dHMoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5FeHBvcnQ6XG4gICAgICAgIGlmICh1dGlscy5pc1RyYW5zYWN0aW9uT2YodGhpcy5fYXZheFRyYW5zYWN0aW9uLCB0aGlzLl9uZXR3b3JrLmNDaGFpbkJsb2NrY2hhaW5JRCkpIHtcbiAgICAgICAgICByZXR1cm4gKHRoaXMuYXZheFBUcmFuc2FjdGlvbiBhcyBFVk1FeHBvcnRUeCkuZ2V0SW5wdXRzKCkubWFwKChldm1JbnB1dCkgPT4gKHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcweCcgKyBldm1JbnB1dC5nZXRBZGRyZXNzU3RyaW5nKCksXG4gICAgICAgICAgICB2YWx1ZTogbmV3IEJOKChldm1JbnB1dCBhcyBhbnkpLmFtb3VudCkudG9TdHJpbmcoKSxcbiAgICAgICAgICAgIG5vbmNlOiBldm1JbnB1dC5nZXROb25jZSgpLnRvTnVtYmVyKCksXG4gICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICAgIGlucHV0cyA9ICh0aGlzLmF2YXhQVHJhbnNhY3Rpb24gYXMgUFZNQmFzZVR4KS5nZXRJbnMoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpbnB1dHMgPSAodGhpcy5hdmF4UFRyYW5zYWN0aW9uIGFzIFBWTUJhc2VUeCkuZ2V0SW5zKCk7XG4gICAgfVxuICAgIHJldHVybiBpbnB1dHMubWFwKChpbnB1dCkgPT4ge1xuICAgICAgY29uc3QgYW1vdW50SW5wdXQgPSBpbnB1dC5nZXRJbnB1dCgpIGFzIGFueSBhcyBBbW91bnRJbnB1dDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGlkOiB1dGlscy5jYjU4RW5jb2RlKGlucHV0LmdldFR4SUQoKSkgKyBJTlBVVF9TRVBBUkFUT1IgKyB1dGlscy5vdXRwdXRpZHhCdWZmZXJUb051bWJlcihpbnB1dC5nZXRPdXRwdXRJZHgoKSksXG4gICAgICAgIGFkZHJlc3M6IHRoaXMuZnJvbUFkZHJlc3Nlcy5zb3J0KCkuam9pbihBRERSRVNTX1NFUEFSQVRPUiksXG4gICAgICAgIHZhbHVlOiBhbW91bnRJbnB1dC5nZXRBbW91bnQoKS50b1N0cmluZygpLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBdmF4IHdyYXBwZXIgdG8gY3JlYXRlIHNpZ25hdHVyZSBhbmQgcmV0dXJuIGl0IGZvciBjcmVkZW50aWFsc1xuICAgKiBAcGFyYW0gcHJ2XG4gICAqIEByZXR1cm4gaGV4c3RyaW5nXG4gICAqL1xuICBjcmVhdGVTaWduYXR1cmUocHJ2OiBCdWZmZXIpOiBzdHJpbmcge1xuICAgIGNvbnN0IHNpZ252YWwgPSB1dGlscy5jcmVhdGVTaWduYXR1cmVBdmF4QnVmZmVyKFxuICAgICAgdGhpcy5fbmV0d29yayxcbiAgICAgIEJ1ZmZlckF2YXguZnJvbSh0aGlzLnNpZ25hYmxlUGF5bG9hZCksXG4gICAgICBCdWZmZXJBdmF4LmZyb20ocHJ2KVxuICAgICk7XG4gICAgcmV0dXJuIHNpZ252YWwudG9TdHJpbmcoJ2hleCcpO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIGV4cGxhaW5UcmFuc2FjdGlvbigpOiBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uIHtcbiAgICBjb25zdCB0eEpzb24gPSB0aGlzLnRvSnNvbigpO1xuICAgIGNvbnN0IGRpc3BsYXlPcmRlciA9IFsnaWQnLCAnaW5wdXRzJywgJ291dHB1dEFtb3VudCcsICdjaGFuZ2VBbW91bnQnLCAnb3V0cHV0cycsICdjaGFuZ2VPdXRwdXRzJywgJ2ZlZScsICd0eXBlJ107XG5cbiAgICBjb25zdCBvdXRwdXRBbW91bnQgPSB0eEpzb24ub3V0cHV0cy5yZWR1Y2UoKHAsIG4pID0+IHAuYWRkKG5ldyBCTihuLnZhbHVlKSksIG5ldyBCTigwKSkudG9TdHJpbmcoKTtcbiAgICBjb25zdCBjaGFuZ2VBbW91bnQgPSB0eEpzb24uY2hhbmdlT3V0cHV0cy5yZWR1Y2UoKHAsIG4pID0+IHAuYWRkKG5ldyBCTihuLnZhbHVlKSksIG5ldyBCTigwKSkudG9TdHJpbmcoKTtcblxuICAgIGxldCByZXdhcmRBZGRyZXNzZXM7XG4gICAgaWYgKFtUcmFuc2FjdGlvblR5cGUuQWRkVmFsaWRhdG9yLCBUcmFuc2FjdGlvblR5cGUuQWRkRGVsZWdhdG9yXS5pbmNsdWRlcyh0eEpzb24udHlwZSkpIHtcbiAgICAgIHJld2FyZEFkZHJlc3NlcyA9IHRoaXMucmV3YXJkQWRkcmVzc2VzO1xuICAgICAgZGlzcGxheU9yZGVyLnNwbGljZSg2LCAwLCAncmV3YXJkQWRkcmVzc2VzJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRpc3BsYXlPcmRlcixcbiAgICAgIGlkOiB0eEpzb24uaWQsXG4gICAgICBpbnB1dHM6IHR4SnNvbi5pbnB1dHMsXG4gICAgICBvdXRwdXRzOiB0eEpzb24ub3V0cHV0cy5tYXAoKG8pID0+ICh7IGFkZHJlc3M6IG8uYWRkcmVzcywgYW1vdW50OiBvLnZhbHVlIH0pKSxcbiAgICAgIG91dHB1dEFtb3VudCxcbiAgICAgIGNoYW5nZU91dHB1dHM6IHR4SnNvbi5jaGFuZ2VPdXRwdXRzLm1hcCgobykgPT4gKHsgYWRkcmVzczogby5hZGRyZXNzLCBhbW91bnQ6IG8udmFsdWUgfSkpLFxuICAgICAgY2hhbmdlQW1vdW50LFxuICAgICAgcmV3YXJkQWRkcmVzc2VzLFxuICAgICAgZmVlOiB0aGlzLmZlZSxcbiAgICAgIHR5cGU6IHR4SnNvbi50eXBlLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgdGhpcyB0cmFuc2FjdGlvbiBpcyBhIFAgY2hhaW5cbiAgICovXG4gIGdldCBpc1RyYW5zYWN0aW9uRm9yQ0NoYWluKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB1dGlscy5pc1RyYW5zYWN0aW9uT2YodGhpcy5fYXZheFRyYW5zYWN0aW9uLCB0aGlzLl9uZXR3b3JrLmNDaGFpbkJsb2NrY2hhaW5JRCk7XG4gIH1cblxuICAvKipcbiAgICogZ2V0IHRoZSBzb3VyY2UgY2hhaW4gaWQgb3IgdW5kZWZpbmVkIGlmIGl0J3MgYSBjcm9zcyBjaGFpbiB0cmFuc2Zlci5cbiAgICovXG4gIGdldCBzb3VyY2VDaGFpbigpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGxldCBibG9ja2NoYWluSUQ7XG4gICAgc3dpdGNoICh0aGlzLnR5cGUpIHtcbiAgICAgIGNhc2UgVHJhbnNhY3Rpb25UeXBlLkltcG9ydDpcbiAgICAgICAgYmxvY2tjaGFpbklEID0gKHRoaXMuYXZheFBUcmFuc2FjdGlvbiBhcyBJbXBvcnRUeCB8IEVWTUltcG9ydFR4KS5nZXRTb3VyY2VDaGFpbigpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgVHJhbnNhY3Rpb25UeXBlLkV4cG9ydDpcbiAgICAgICAgYmxvY2tjaGFpbklEID0gKHRoaXMuYXZheFBUcmFuc2FjdGlvbiBhcyBFeHBvcnRUeCB8IEVWTUV4cG9ydFR4KS5nZXRCbG9ja2NoYWluSUQoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5ibG9ja2NoYWluSUR0b0FsaWFzKGJsb2NrY2hhaW5JRCk7XG4gIH1cblxuICAvKipcbiAgICogZ2V0IHRoZSBkZXN0aW5hdGlvbkNoYWluIG9yIHVuZGVmaW5lZCBpZiBpdCdzIGEgY3Jvc3MgY2hhaW4gdHJhbnNmZXIuXG4gICAqL1xuICBnZXQgZGVzdGluYXRpb25DaGFpbigpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGxldCBibG9ja2NoYWluSUQ7XG4gICAgc3dpdGNoICh0aGlzLnR5cGUpIHtcbiAgICAgIGNhc2UgVHJhbnNhY3Rpb25UeXBlLkltcG9ydDpcbiAgICAgICAgYmxvY2tjaGFpbklEID0gKHRoaXMuYXZheFBUcmFuc2FjdGlvbiBhcyBJbXBvcnRUeCB8IEVWTUltcG9ydFR4KS5nZXRCbG9ja2NoYWluSUQoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5FeHBvcnQ6XG4gICAgICAgIGJsb2NrY2hhaW5JRCA9ICh0aGlzLmF2YXhQVHJhbnNhY3Rpb24gYXMgRXhwb3J0VHggfCBFVk1FeHBvcnRUeCkuZ2V0RGVzdGluYXRpb25DaGFpbigpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmJsb2NrY2hhaW5JRHRvQWxpYXMoYmxvY2tjaGFpbklEKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGEgYmxvY2tjaGFpbklkIGJ1ZmZlciB0byBzdHJpbmcgYW5kIHJldHVybiBQIG9yIEMgYWxpYXMgaWYgbWF0Y2ggb2YgYW55IG9mIHRoYXQgY2hhaW5zLlxuICAgKiBAcGFyYW0ge0J1ZmZlckF2YXh9IGJsb2NrY2hhaW5JREJ1ZmZlclxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IGJsb2NjaGFpbklEIG9yIGFsaWFzIGlmIGV4aXN0cy5cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgYmxvY2tjaGFpbklEdG9BbGlhcyhibG9ja2NoYWluSURCdWZmZXI6IEJ1ZmZlckF2YXgpOiBzdHJpbmcge1xuICAgIGNvbnN0IGJsb2NrY2hhaW5JZCA9IHV0aWxzLmNiNThFbmNvZGUoYmxvY2tjaGFpbklEQnVmZmVyKTtcbiAgICBzd2l0Y2ggKGJsb2NrY2hhaW5JZCkge1xuICAgICAgY2FzZSB0aGlzLl9uZXR3b3JrLmNDaGFpbkJsb2NrY2hhaW5JRDpcbiAgICAgICAgcmV0dXJuICdDJztcbiAgICAgIGNhc2UgdGhpcy5fbmV0d29yay5ibG9ja2NoYWluSUQ6XG4gICAgICAgIHJldHVybiAnUCc7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gYmxvY2tjaGFpbklkO1xuICAgIH1cbiAgfVxufVxuIl19

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


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