PHP WebShell
Текущая директория: /opt/BitGoJS/modules/utxo-lib/dist/src
Просмотр файла: transaction_builder.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransactionBuilder = void 0;
const types = require("bitcoinjs-lib/src/types");
const _1 = require("./");
const bufferutils = require("bitcoinjs-lib/src/bufferutils");
const classify = require("./classify");
const _2 = require("./");
const _3 = require("./");
const _4 = require("./");
const _5 = require("./");
const _6 = require("./");
const _7 = require("./");
const _8 = require("./");
const noble_ecc_1 = require("./noble_ecc");
const typeforce = require('typeforce');
const tfFullSigner = (obj) => {
return typeforce.Buffer(obj.publicKey) && typeof obj.sign === 'function' && typeof obj.signSchnorr === 'function';
};
const SCRIPT_TYPES = classify.types;
const PREVOUT_TYPES = new Set([
// Raw
'p2pkh',
'p2pk',
'p2wpkh',
'p2ms',
// P2SH wrapped
'p2sh-p2pkh',
'p2sh-p2pk',
'p2sh-p2wpkh',
'p2sh-p2ms',
// P2WSH wrapped
'p2wsh-p2pkh',
'p2wsh-p2pk',
'p2wsh-p2ms',
// P2SH-P2WSH wrapper
'p2sh-p2wsh-p2pkh',
'p2sh-p2wsh-p2pk',
'p2sh-p2wsh-p2ms',
// P2TR KeyPath
'p2tr',
// P2TR ScriptPath
'p2tr-p2ns',
]);
function tfMessage(type, value, message) {
try {
typeforce(type, value);
}
catch (err) {
throw new Error(message);
}
}
function txIsString(tx) {
return typeof tx === 'string' || tx instanceof String;
}
function txIsTransaction(tx) {
return tx instanceof _8.Transaction;
}
class TransactionBuilder {
static fromTransaction(transaction, network, prevOutputs) {
const txb = new TransactionBuilder(network);
// Copy transaction fields
txb.setVersion(transaction.version);
txb.setLockTime(transaction.locktime);
// Copy outputs (done first to avoid signature invalidation)
transaction.outs.forEach((txOut) => {
txb.addOutput(txOut.script, txOut.value);
});
// Copy inputs
transaction.ins.forEach((txIn) => {
txb.__addInputUnsafe(txIn.hash, txIn.index, {
sequence: txIn.sequence,
script: txIn.script,
witness: txIn.witness,
});
});
// fix some things not possible through the public API
txb.__INPUTS.forEach((input, i) => {
fixMultisigOrder(input, transaction, i, prevOutputs);
});
return txb;
}
// WARNING: maximumFeeRate is __NOT__ to be relied on,
// it's just another potential safety mechanism (safety in-depth)
constructor(network = _3.networks.bitcoin, maximumFeeRate = 2500) {
this.network = network;
this.maximumFeeRate = maximumFeeRate;
this.__PREV_TX_SET = {};
this.__INPUTS = [];
this.__TX = new _8.Transaction();
this.__TX.version = 2;
this.__USE_LOW_R = false;
}
setLowR(setting) {
typeforce(typeforce.maybe(typeforce.Boolean), setting);
if (setting === undefined) {
setting = true;
}
this.__USE_LOW_R = setting;
return setting;
}
setLockTime(locktime) {
typeforce(types.UInt32, locktime);
// if any signatures exist, throw
if (this.__INPUTS.some((input) => {
if (!input.signatures)
return false;
return input.signatures.some((s) => s !== undefined);
})) {
throw new Error('No, this would invalidate signatures');
}
this.__TX.locktime = locktime;
}
setVersion(version) {
typeforce(types.UInt32, version);
// XXX: this might eventually become more complex depending on what the versions represent
this.__TX.version = version;
}
addInput(txHash, vout, sequence, prevOutScript, value) {
if (!this.__canModifyInputs()) {
throw new Error('No, this would invalidate signatures');
}
// is it a hex string?
if (txIsString(txHash)) {
// transaction hashs's are displayed in reverse order, un-reverse it
txHash = bufferutils.reverseBuffer(Buffer.from(txHash, 'hex'));
// is it a Transaction object?
}
else if (txIsTransaction(txHash)) {
const txOut = txHash.outs[vout];
prevOutScript = txOut.script;
value = txOut.value;
txHash = txHash.getHash(false);
}
return this.__addInputUnsafe(txHash, vout, {
sequence,
prevOutScript,
value,
});
}
addOutput(scriptPubKey, value) {
if (!this.__canModifyOutputs()) {
throw new Error('No, this would invalidate signatures');
}
// Attempt to get a script if it's a base58 or bech32 address string
if (typeof scriptPubKey === 'string') {
scriptPubKey = _1.address.toOutputScript(scriptPubKey, this.network);
}
return this.__TX.addOutput(scriptPubKey, value);
}
build() {
return this.__build(false);
}
buildIncomplete() {
return this.__build(true);
}
sign(signParams, keyPair, redeemScript, hashType, witnessValue, witnessScript, controlBlock, annex) {
trySign(getSigningData(this.network, this.__INPUTS, this.__needsOutputs.bind(this), this.__TX, signParams, keyPair, redeemScript, hashType, witnessValue, witnessScript, controlBlock, annex, this.__USE_LOW_R));
}
__addInputUnsafe(txHash, vout, options) {
if (_8.Transaction.isCoinbaseHash(txHash)) {
throw new Error('coinbase inputs not supported');
}
const prevTxOut = txHash.toString('hex') + ':' + vout;
if (this.__PREV_TX_SET[prevTxOut] !== undefined)
throw new Error('Duplicate TxOut: ' + prevTxOut);
let input = {};
// derive what we can from the scriptSig
if (options.script !== undefined || options.witness !== undefined) {
input = expandInput(options.script, options.witness);
}
// if an input value was given, retain it
if (options.value !== undefined) {
input.value = options.value;
}
// derive what we can from the previous transactions output script
if (!input.prevOutScript && options.prevOutScript) {
let prevOutType;
if (!input.pubkeys && !input.signatures) {
const expanded = expandOutput(options.prevOutScript);
if (expanded.pubkeys) {
input.pubkeys = expanded.pubkeys;
input.signatures = expanded.signatures;
}
prevOutType = expanded.type;
}
input.prevOutScript = options.prevOutScript;
input.prevOutType = prevOutType || classify.output(options.prevOutScript);
}
const vin = this.__TX.addInput(txHash, vout, options.sequence, options.scriptSig);
this.__INPUTS[vin] = input;
this.__PREV_TX_SET[prevTxOut] = true;
return vin;
}
__build(allowIncomplete) {
if (!allowIncomplete) {
if (!this.__TX.ins.length)
throw new Error('Transaction has no inputs');
if (!this.__TX.outs.length)
throw new Error('Transaction has no outputs');
}
const tx = this.__TX.clone();
// create script signatures from inputs
this.__INPUTS.forEach((input, i) => {
if (!input.prevOutType && !allowIncomplete)
throw new Error('Transaction is not complete');
const result = build(input.prevOutType, input, allowIncomplete);
if (!result) {
if (!allowIncomplete && input.prevOutType === SCRIPT_TYPES.NONSTANDARD)
throw new Error('Unknown input type');
if (!allowIncomplete)
throw new Error('Not enough information');
return;
}
if (result.input) {
tx.setInputScript(i, result.input);
}
tx.setWitness(i, result.witness);
});
if (!allowIncomplete) {
// do not rely on this, its merely a last resort
if (this.__overMaximumFees(tx.virtualSize())) {
throw new Error('Transaction has absurd fees');
}
}
return tx;
}
__canModifyInputs() {
return this.__INPUTS.every((input) => {
if (!input.signatures)
return true;
return input.signatures.every((signature) => {
if (!signature)
return true;
const hashType = signatureHashType(signature);
// if SIGHASH_ANYONECANPAY is set, signatures would not
// be invalidated by more inputs
return (hashType & _8.Transaction.SIGHASH_ANYONECANPAY) !== 0;
});
});
}
__needsOutputs(signingHashType) {
if (signingHashType === _8.Transaction.SIGHASH_ALL || signingHashType === _8.Transaction.SIGHASH_DEFAULT) {
return this.__TX.outs.length === 0;
}
// if inputs are being signed with SIGHASH_NONE, we don't strictly need outputs
// .build() will fail, but .buildIncomplete() is OK
return (this.__TX.outs.length === 0 &&
this.__INPUTS.some((input) => {
if (!input.signatures)
return false;
return input.signatures.some((signature) => {
if (!signature)
return false; // no signature, no issue
const hashType = signatureHashType(signature);
if (hashType & _8.Transaction.SIGHASH_NONE)
return false; // SIGHASH_NONE doesn't care about outputs
return true; // SIGHASH_* does care
});
}));
}
__canModifyOutputs() {
const nInputs = this.__TX.ins.length;
const nOutputs = this.__TX.outs.length;
return this.__INPUTS.every((input) => {
if (input.signatures === undefined)
return true;
return input.signatures.every((signature) => {
if (!signature)
return true;
const hashType = signatureHashType(signature);
const hashTypeMod = hashType & 0x1f;
if (hashTypeMod === _8.Transaction.SIGHASH_NONE)
return true;
if (hashTypeMod === _8.Transaction.SIGHASH_SINGLE) {
// if SIGHASH_SINGLE is set, and nInputs > nOutputs
// some signatures would be invalidated by the addition
// of more outputs
return nInputs <= nOutputs;
}
return false;
});
});
}
__overMaximumFees(bytes) {
// not all inputs will have .value defined
const incoming = this.__INPUTS.reduce((a, x) => a + (typeof x.value !== 'undefined' ? BigInt(x.value) : BigInt(0)), BigInt(0));
// but all outputs do, and if we have any input value
// we can immediately determine if the outputs are too small
const outgoing = this.__TX.outs.reduce((a, x) => a + BigInt(x.value), BigInt(0));
const fee = incoming - outgoing;
const feeRate = Number(fee) / bytes; // assume fee fits within number
return feeRate > this.maximumFeeRate;
}
}
exports.TransactionBuilder = TransactionBuilder;
function expandInput(scriptSig, witnessStack = [], type, scriptPubKey) {
if (scriptSig && scriptSig.length === 0 && witnessStack.length === 0)
return {};
if (!type) {
let ssType = scriptSig ? classify.input(scriptSig, true) : undefined;
let wsType = classify.witness(witnessStack, true);
if (ssType === SCRIPT_TYPES.NONSTANDARD)
ssType = undefined;
if (wsType === SCRIPT_TYPES.NONSTANDARD)
wsType = undefined;
type = ssType || wsType;
}
switch (type) {
case SCRIPT_TYPES.P2WPKH: {
const { output, pubkey, signature } = _4.payments.p2wpkh({
witness: witnessStack,
});
return {
prevOutScript: output,
prevOutType: SCRIPT_TYPES.P2WPKH,
pubkeys: [pubkey],
signatures: [signature],
};
}
case SCRIPT_TYPES.P2PKH: {
const { output, pubkey, signature } = _4.payments.p2pkh({
input: scriptSig,
});
return {
prevOutScript: output,
prevOutType: SCRIPT_TYPES.P2PKH,
pubkeys: [pubkey],
signatures: [signature],
};
}
case SCRIPT_TYPES.P2PK: {
const { signature } = _4.payments.p2pk({ input: scriptSig });
return {
prevOutType: SCRIPT_TYPES.P2PK,
pubkeys: [undefined],
signatures: [signature],
};
}
case SCRIPT_TYPES.P2MS: {
const { m, pubkeys, signatures } = _4.payments.p2ms({
input: scriptSig,
output: scriptPubKey,
}, { allowIncomplete: true });
return {
prevOutType: SCRIPT_TYPES.P2MS,
pubkeys,
signatures,
maxSignatures: m,
};
}
case SCRIPT_TYPES.P2TR_NS: {
const { n, pubkeys, signatures } = _1.p2trPayments.p2tr_ns({
// Witness signatures are reverse of pubkeys, because it's a stack
signatures: witnessStack.length ? witnessStack.reverse() : undefined,
output: scriptPubKey,
}, { allowIncomplete: true, eccLib: noble_ecc_1.ecc });
return {
prevOutType: SCRIPT_TYPES.P2TR_NS,
pubkeys,
signatures,
maxSignatures: n,
};
}
}
if (type === SCRIPT_TYPES.P2SH) {
const { output, redeem } = _4.payments.p2sh({
input: scriptSig,
witness: witnessStack,
});
const outputType = classify.output(redeem.output);
const expanded = expandInput(redeem.input, redeem.witness, outputType, redeem.output);
if (!expanded.prevOutType)
return {};
return {
prevOutScript: output,
prevOutType: SCRIPT_TYPES.P2SH,
redeemScript: redeem.output,
redeemScriptType: expanded.prevOutType,
witnessScript: expanded.witnessScript,
witnessScriptType: expanded.witnessScriptType,
pubkeys: expanded.pubkeys,
signatures: expanded.signatures,
};
}
if (type === SCRIPT_TYPES.P2WSH) {
const { output, redeem } = _4.payments.p2wsh({
input: scriptSig,
witness: witnessStack,
});
const outputType = classify.output(redeem.output);
let expanded;
if (outputType === SCRIPT_TYPES.P2WPKH) {
expanded = expandInput(redeem.input, redeem.witness, outputType);
}
else {
expanded = expandInput(_5.script.compile(redeem.witness), [], outputType, redeem.output);
}
if (!expanded.prevOutType)
return {};
return {
prevOutScript: output,
prevOutType: SCRIPT_TYPES.P2WSH,
witnessScript: redeem.output,
witnessScriptType: expanded.prevOutType,
pubkeys: expanded.pubkeys,
signatures: expanded.signatures,
};
}
if (type === SCRIPT_TYPES.P2TR) {
const parsedWitness = _7.taproot.parseTaprootWitness(witnessStack);
if (parsedWitness.spendType === 'Key') {
// key path spend, nothing to expand
const { signature, annex } = parsedWitness;
return {
prevOutType: SCRIPT_TYPES.P2TR,
signatures: [signature],
annex,
};
}
else {
// script path spend
const { tapscript, controlBlock, annex } = parsedWitness;
const prevOutScript = _1.p2trPayments.p2tr({
redeems: [{ output: tapscript }],
redeemIndex: 0,
controlBlock,
annex,
}, { eccLib: noble_ecc_1.ecc }).output;
const witnessScriptType = classify.output(tapscript);
const { pubkeys, signatures } = expandInput(undefined, parsedWitness.scriptSig, witnessScriptType, tapscript);
return {
prevOutScript,
prevOutType: SCRIPT_TYPES.P2TR,
witnessScript: tapscript,
witnessScriptType,
controlBlock,
annex,
pubkeys,
signatures,
};
}
}
return {
prevOutType: SCRIPT_TYPES.NONSTANDARD,
prevOutScript: scriptSig,
};
}
// could be done in expandInput, but requires the original Transaction for hashForSignature
function fixMultisigOrder(input, transaction, vin, prevOutputs) {
if (input.redeemScriptType !== SCRIPT_TYPES.P2MS || !input.redeemScript)
return;
if (input.pubkeys.length === input.signatures.length)
return;
const prevOutput = prevOutputs && prevOutputs[vin];
const unmatched = input.signatures.concat();
input.signatures = input.pubkeys.map((pubKey) => {
const keyPair = noble_ecc_1.ECPair.fromPublicKey(pubKey);
let match;
// check for a signature
unmatched.some((signature, i) => {
// skip if undefined || OP_0
if (!signature)
return false;
// TODO: avoid O(n) hashForSignature
const parsed = _5.script.signature.decode(signature);
const hash = transaction.hashForSignature(vin, input.redeemScript, parsed.hashType, prevOutput?.value);
// skip if signature does not match pubKey
if (!keyPair.verify(hash, parsed.signature))
return false;
// remove matched signature from unmatched
unmatched[i] = undefined;
match = signature;
return true;
});
return match;
});
}
function expandOutput(script, ourPubKey, controlBlock) {
typeforce(types.Buffer, script);
const type = classify.output(script);
switch (type) {
case SCRIPT_TYPES.P2PKH: {
if (!ourPubKey)
return { type };
// does our hash160(pubKey) match the output scripts?
const pkh1 = _4.payments.p2pkh({ output: script }).hash;
const pkh2 = _2.crypto.hash160(ourPubKey);
if (!pkh1.equals(pkh2))
return { type };
return {
type,
pubkeys: [ourPubKey],
signatures: [undefined],
};
}
case SCRIPT_TYPES.P2WPKH: {
if (!ourPubKey)
return { type };
// does our hash160(pubKey) match the output scripts?
const wpkh1 = _4.payments.p2wpkh({ output: script }).hash;
const wpkh2 = _2.crypto.hash160(ourPubKey);
if (!wpkh1.equals(wpkh2))
return { type };
return {
type,
pubkeys: [ourPubKey],
signatures: [undefined],
};
}
case SCRIPT_TYPES.P2TR: {
if (!ourPubKey)
return { type };
// HACK ourPubKey to BIP340-style
if (ourPubKey.length === 33)
ourPubKey = ourPubKey.slice(1);
// TODO: support multiple pubkeys
const p2tr = _1.p2trPayments.p2tr({ pubkey: ourPubKey, controlBlock }, { eccLib: noble_ecc_1.ecc });
// Does tweaked output for a single pubkey match?
if (!script.equals(p2tr.output))
return { type };
// P2TR KeyPath, single key
return {
type,
pubkeys: [ourPubKey],
signatures: [undefined],
};
}
case SCRIPT_TYPES.P2TR_NS: {
const p2trNs = _1.p2trPayments.p2tr_ns({ output: script }, { eccLib: noble_ecc_1.ecc });
// P2TR ScriptPath
return {
type,
pubkeys: p2trNs.pubkeys,
signatures: p2trNs.pubkeys.map(() => undefined),
maxSignatures: p2trNs.pubkeys.length,
};
}
case SCRIPT_TYPES.P2PK: {
const p2pk = _4.payments.p2pk({ output: script });
return {
type,
pubkeys: [p2pk.pubkey],
signatures: [undefined],
};
}
case SCRIPT_TYPES.P2MS: {
const p2ms = _4.payments.p2ms({ output: script });
return {
type,
pubkeys: p2ms.pubkeys,
signatures: p2ms.pubkeys.map(() => undefined),
maxSignatures: p2ms.m,
};
}
}
return { type };
}
function prepareInput(input, ourPubKey, redeemScript, witnessScript, controlBlock, annex) {
if (redeemScript && witnessScript) {
const p2wsh = _4.payments.p2wsh({
redeem: { output: witnessScript },
});
const p2wshAlt = _4.payments.p2wsh({ output: redeemScript });
const p2sh = _4.payments.p2sh({ redeem: { output: redeemScript } });
const p2shAlt = _4.payments.p2sh({ redeem: p2wsh });
// enforces P2SH(P2WSH(...))
if (!p2wsh.hash.equals(p2wshAlt.hash))
throw new Error('Witness script inconsistent with prevOutScript');
if (!p2sh.hash.equals(p2shAlt.hash))
throw new Error('Redeem script inconsistent with prevOutScript');
const expanded = expandOutput(p2wsh.redeem.output, ourPubKey);
if (!expanded.pubkeys) {
throw new Error(expanded.type + ' not supported as witnessScript (' + _5.script.toASM(witnessScript) + ')');
}
if (input.signatures && input.signatures.some((x) => x !== undefined)) {
expanded.signatures = input.signatures;
}
const signScript = witnessScript;
if (expanded.type === SCRIPT_TYPES.P2WPKH)
throw new Error('P2SH(P2WSH(P2WPKH)) is a consensus failure');
return {
redeemScript,
redeemScriptType: SCRIPT_TYPES.P2WSH,
witnessScript,
witnessScriptType: expanded.type,
prevOutType: SCRIPT_TYPES.P2SH,
prevOutScript: p2sh.output,
witnessVersion: 0,
signScript,
signType: expanded.type,
pubkeys: expanded.pubkeys,
signatures: expanded.signatures,
maxSignatures: expanded.maxSignatures,
};
}
if (redeemScript) {
const p2sh = _4.payments.p2sh({ redeem: { output: redeemScript } });
if (input.prevOutScript) {
let p2shAlt;
try {
p2shAlt = _4.payments.p2sh({ output: input.prevOutScript });
}
catch (e) {
throw new Error('PrevOutScript must be P2SH');
}
if (!p2sh.hash.equals(p2shAlt.hash))
throw new Error('Redeem script inconsistent with prevOutScript');
}
const expanded = expandOutput(p2sh.redeem.output, ourPubKey);
if (!expanded.pubkeys) {
throw new Error(expanded.type + ' not supported as redeemScript (' + _5.script.toASM(redeemScript) + ')');
}
if (input.signatures && input.signatures.some((x) => x !== undefined)) {
expanded.signatures = input.signatures;
}
let signScript = redeemScript;
if (expanded.type === SCRIPT_TYPES.P2WPKH) {
signScript = _4.payments.p2pkh({ pubkey: expanded.pubkeys[0] }).output;
}
return {
redeemScript,
redeemScriptType: expanded.type,
prevOutType: SCRIPT_TYPES.P2SH,
prevOutScript: p2sh.output,
witnessVersion: expanded.type === SCRIPT_TYPES.P2WPKH ? 0 : undefined,
signScript,
signType: expanded.type,
pubkeys: expanded.pubkeys,
signatures: expanded.signatures,
maxSignatures: expanded.maxSignatures,
};
}
if (witnessScript && controlBlock) {
// P2TR ScriptPath
/* tslint:disable-next-line:no-shadowed-variable */
let prevOutScript = input.prevOutScript;
if (!prevOutScript) {
prevOutScript = _1.p2trPayments.p2tr({
redeems: [{ output: witnessScript }],
redeemIndex: 0,
controlBlock,
annex,
}, { eccLib: noble_ecc_1.ecc }).output;
}
const expanded = expandOutput(witnessScript, ourPubKey);
if (!expanded.pubkeys) {
throw new Error(expanded.type + ' not supported as witnessScript (' + _5.script.toASM(witnessScript) + ')');
}
if (input.signatures && input.signatures.some((x) => x !== undefined)) {
expanded.signatures = input.signatures;
}
return {
witnessScript,
witnessScriptType: expanded.type,
prevOutType: SCRIPT_TYPES.P2TR,
prevOutScript,
witnessVersion: 1,
signScript: witnessScript,
signType: expanded.type,
pubkeys: expanded.pubkeys,
signatures: expanded.signatures,
maxSignatures: expanded.maxSignatures,
controlBlock,
annex,
};
}
if (witnessScript) {
const p2wsh = _4.payments.p2wsh({ redeem: { output: witnessScript } });
if (input.prevOutScript) {
const p2wshAlt = _4.payments.p2wsh({ output: input.prevOutScript });
if (!p2wsh.hash.equals(p2wshAlt.hash))
throw new Error('Witness script inconsistent with prevOutScript');
}
const expanded = expandOutput(p2wsh.redeem.output, ourPubKey);
if (!expanded.pubkeys) {
throw new Error(expanded.type + ' not supported as witnessScript (' + _5.script.toASM(witnessScript) + ')');
}
if (input.signatures && input.signatures.some((x) => x !== undefined)) {
expanded.signatures = input.signatures;
}
const signScript = witnessScript;
if (expanded.type === SCRIPT_TYPES.P2WPKH)
throw new Error('P2WSH(P2WPKH) is a consensus failure');
return {
witnessScript,
witnessScriptType: expanded.type,
prevOutType: SCRIPT_TYPES.P2WSH,
prevOutScript: p2wsh.output,
witnessVersion: 0,
signScript,
signType: expanded.type,
pubkeys: expanded.pubkeys,
signatures: expanded.signatures,
maxSignatures: expanded.maxSignatures,
};
}
if (input.prevOutType && input.prevOutScript) {
// embedded scripts are not possible without extra information
if (input.prevOutType === SCRIPT_TYPES.P2SH) {
throw new Error('PrevOutScript is ' + input.prevOutType + ', requires redeemScript');
}
if (input.prevOutType === SCRIPT_TYPES.P2WSH) {
throw new Error('PrevOutScript is ' + input.prevOutType + ', requires witnessScript');
}
const expanded = expandOutput(input.prevOutScript, ourPubKey);
if (!expanded.pubkeys) {
throw new Error(expanded.type + ' not supported (' + _5.script.toASM(input.prevOutScript) + ')');
}
if (input.signatures && input.signatures.some((x) => x !== undefined)) {
expanded.signatures = input.signatures;
}
let signScript = input.prevOutScript;
if (expanded.type === SCRIPT_TYPES.P2WPKH) {
signScript = _4.payments.p2pkh({ pubkey: expanded.pubkeys[0] }).output;
}
let witnessVersion;
if (expanded.type === SCRIPT_TYPES.P2WPKH) {
witnessVersion = 0;
}
else if (expanded.type === SCRIPT_TYPES.P2TR) {
witnessVersion = 1;
}
return {
prevOutType: expanded.type,
prevOutScript: input.prevOutScript,
witnessVersion,
signScript,
signType: expanded.type,
pubkeys: expanded.pubkeys,
signatures: expanded.signatures,
maxSignatures: expanded.maxSignatures,
};
}
const prevOutScript = _4.payments.p2pkh({ pubkey: ourPubKey }).output;
return {
prevOutType: SCRIPT_TYPES.P2PKH,
prevOutScript,
signScript: prevOutScript,
signType: SCRIPT_TYPES.P2PKH,
pubkeys: [ourPubKey],
signatures: [undefined],
};
}
function build(type, input, allowIncomplete) {
const pubkeys = (input.pubkeys || []);
let signatures = (input.signatures || []);
switch (type) {
case SCRIPT_TYPES.P2PKH: {
if (pubkeys.length === 0)
break;
if (signatures.length === 0)
break;
return _4.payments.p2pkh({ pubkey: pubkeys[0], signature: signatures[0] });
}
case SCRIPT_TYPES.P2WPKH: {
if (pubkeys.length === 0)
break;
if (signatures.length === 0)
break;
return _4.payments.p2wpkh({ pubkey: pubkeys[0], signature: signatures[0] });
}
case SCRIPT_TYPES.P2PK: {
if (pubkeys.length === 0)
break;
if (signatures.length === 0)
break;
return _4.payments.p2pk({ signature: signatures[0] });
}
case SCRIPT_TYPES.P2MS: {
const m = input.maxSignatures;
if (allowIncomplete) {
signatures = signatures.map((x) => x || _6.opcodes.OP_0);
}
else {
signatures = signatures.filter((x) => x);
}
// if the transaction is not not complete (complete), or if signatures.length === m, validate
// otherwise, the number of OP_0's may be >= m, so don't validate (boo)
const validate = !allowIncomplete || m === signatures.length;
return _4.payments.p2ms({ m, pubkeys, signatures }, { allowIncomplete, validate });
}
case SCRIPT_TYPES.P2SH: {
const redeem = build(input.redeemScriptType, input, allowIncomplete);
if (!redeem)
return;
return _4.payments.p2sh({
redeem: {
output: redeem.output || input.redeemScript,
input: redeem.input,
witness: redeem.witness,
},
});
}
case SCRIPT_TYPES.P2WSH: {
const redeem = build(input.witnessScriptType, input, allowIncomplete);
if (!redeem)
return;
return _4.payments.p2wsh({
redeem: {
output: input.witnessScript,
input: redeem.input,
witness: redeem.witness,
},
});
}
case SCRIPT_TYPES.P2TR: {
if (input.witnessScriptType === SCRIPT_TYPES.P2TR_NS) {
// ScriptPath
const redeem = build(input.witnessScriptType, input, allowIncomplete);
return _1.p2trPayments.p2tr({
output: input.prevOutScript,
controlBlock: input.controlBlock,
annex: input.annex,
redeems: [redeem],
redeemIndex: 0,
}, { eccLib: noble_ecc_1.ecc });
}
// KeyPath
if (signatures.length === 0)
break;
return _1.p2trPayments.p2tr({ pubkeys, signature: signatures[0] }, { eccLib: noble_ecc_1.ecc });
}
case SCRIPT_TYPES.P2TR_NS: {
const m = input.maxSignatures;
if (allowIncomplete) {
signatures = signatures.map((x) => x || _6.opcodes.OP_0);
}
else {
signatures = signatures.filter((x) => x);
}
// if the transaction is not not complete (complete), or if signatures.length === m, validate
// otherwise, the number of OP_0's may be >= m, so don't validate (boo)
const validate = !allowIncomplete || m === signatures.length;
return _1.p2trPayments.p2tr_ns({ pubkeys, signatures }, { allowIncomplete, validate, eccLib: noble_ecc_1.ecc });
}
}
}
function canSign(input) {
return (input.signScript !== undefined &&
input.signType !== undefined &&
input.pubkeys !== undefined &&
input.signatures !== undefined &&
input.signatures.length === input.pubkeys.length &&
input.pubkeys.length > 0 &&
(input.witnessVersion === undefined || input.value !== undefined));
}
function signatureHashType(buffer) {
if (_5.script.isCanonicalSchnorrSignature(buffer) && buffer.length === 64) {
return _8.Transaction.SIGHASH_DEFAULT;
}
return buffer.readUInt8(buffer.length - 1);
}
function checkSignArgs(inputs, signParams) {
if (!PREVOUT_TYPES.has(signParams.prevOutScriptType)) {
throw new TypeError(`Unknown prevOutScriptType "${signParams.prevOutScriptType}"`);
}
tfMessage(typeforce.Number, signParams.vin, `sign must include vin parameter as Number (input index)`);
tfMessage(tfFullSigner, signParams.keyPair, `sign must include keyPair parameter as Signer interface`);
tfMessage(typeforce.maybe(typeforce.Number), signParams.hashType, `sign hashType parameter must be a number`);
const prevOutType = (inputs[signParams.vin] || []).prevOutType;
const posType = signParams.prevOutScriptType;
switch (posType) {
case 'p2pkh':
if (prevOutType && prevOutType !== 'pubkeyhash') {
throw new TypeError(`input #${signParams.vin} is not of type p2pkh: ${prevOutType}`);
}
tfMessage(typeforce.value(undefined), signParams.witnessScript, `${posType} requires NO witnessScript`);
tfMessage(typeforce.value(undefined), signParams.redeemScript, `${posType} requires NO redeemScript`);
tfMessage(typeforce.value(undefined), signParams.witnessValue, `${posType} requires NO witnessValue`);
break;
case 'p2pk':
if (prevOutType && prevOutType !== 'pubkey') {
throw new TypeError(`input #${signParams.vin} is not of type p2pk: ${prevOutType}`);
}
tfMessage(typeforce.value(undefined), signParams.witnessScript, `${posType} requires NO witnessScript`);
tfMessage(typeforce.value(undefined), signParams.redeemScript, `${posType} requires NO redeemScript`);
tfMessage(typeforce.value(undefined), signParams.witnessValue, `${posType} requires NO witnessValue`);
break;
case 'p2wpkh':
if (prevOutType && prevOutType !== 'witnesspubkeyhash') {
throw new TypeError(`input #${signParams.vin} is not of type p2wpkh: ${prevOutType}`);
}
tfMessage(typeforce.value(undefined), signParams.witnessScript, `${posType} requires NO witnessScript`);
tfMessage(typeforce.value(undefined), signParams.redeemScript, `${posType} requires NO redeemScript`);
tfMessage(types.Satoshi, signParams.witnessValue, `${posType} requires witnessValue`);
break;
case 'p2ms':
if (prevOutType && prevOutType !== 'multisig') {
throw new TypeError(`input #${signParams.vin} is not of type p2ms: ${prevOutType}`);
}
tfMessage(typeforce.value(undefined), signParams.witnessScript, `${posType} requires NO witnessScript`);
tfMessage(typeforce.value(undefined), signParams.redeemScript, `${posType} requires NO redeemScript`);
tfMessage(typeforce.value(undefined), signParams.witnessValue, `${posType} requires NO witnessValue`);
break;
case 'p2sh-p2wpkh':
if (prevOutType && prevOutType !== 'scripthash') {
throw new TypeError(`input #${signParams.vin} is not of type p2sh-p2wpkh: ${prevOutType}`);
}
tfMessage(typeforce.value(undefined), signParams.witnessScript, `${posType} requires NO witnessScript`);
tfMessage(typeforce.Buffer, signParams.redeemScript, `${posType} requires redeemScript`);
tfMessage(types.Satoshi, signParams.witnessValue, `${posType} requires witnessValue`);
break;
case 'p2sh-p2ms':
case 'p2sh-p2pk':
case 'p2sh-p2pkh':
if (prevOutType && prevOutType !== 'scripthash') {
throw new TypeError(`input #${signParams.vin} is not of type ${posType}: ${prevOutType}`);
}
tfMessage(typeforce.value(undefined), signParams.witnessScript, `${posType} requires NO witnessScript`);
tfMessage(typeforce.Buffer, signParams.redeemScript, `${posType} requires redeemScript`);
tfMessage(typeforce.value(undefined), signParams.witnessValue, `${posType} requires NO witnessValue`);
break;
case 'p2wsh-p2ms':
case 'p2wsh-p2pk':
case 'p2wsh-p2pkh':
if (prevOutType && prevOutType !== 'witnessscripthash') {
throw new TypeError(`input #${signParams.vin} is not of type ${posType}: ${prevOutType}`);
}
tfMessage(typeforce.Buffer, signParams.witnessScript, `${posType} requires witnessScript`);
tfMessage(typeforce.value(undefined), signParams.redeemScript, `${posType} requires NO redeemScript`);
tfMessage(types.Satoshi, signParams.witnessValue, `${posType} requires witnessValue`);
break;
case 'p2sh-p2wsh-p2ms':
case 'p2sh-p2wsh-p2pk':
case 'p2sh-p2wsh-p2pkh':
if (prevOutType && prevOutType !== 'scripthash') {
throw new TypeError(`input #${signParams.vin} is not of type ${posType}: ${prevOutType}`);
}
tfMessage(typeforce.Buffer, signParams.witnessScript, `${posType} requires witnessScript`);
tfMessage(typeforce.Buffer, signParams.redeemScript, `${posType} requires witnessScript`);
tfMessage(types.Satoshi, signParams.witnessValue, `${posType} requires witnessScript`);
break;
case 'p2tr':
if (prevOutType && prevOutType !== 'taproot') {
throw new TypeError(`input #${signParams.vin} is not of type ${posType}: ${prevOutType}`);
}
tfMessage(typeforce.value(undefined), signParams.witnessScript, `${posType} requires NO witnessScript`);
tfMessage(typeforce.value(undefined), signParams.redeemScript, `${posType} requires NO redeemScript`);
tfMessage(typeforce.value(undefined), signParams.witnessValue, `${posType} requires NO witnessValue`);
break;
case 'p2tr-p2ns':
if (prevOutType && prevOutType !== 'taproot') {
throw new TypeError(`input #${signParams.vin} is not of type ${posType}: ${prevOutType}`);
}
inputs[signParams.vin].prevOutType = inputs[signParams.vin].prevOutType || 'taproot';
tfMessage(typeforce.Buffer, signParams.witnessScript, `${posType} requires witnessScript`);
tfMessage(typeforce.Buffer, signParams.controlBlock, `${posType} requires controlBlock`);
tfMessage(typeforce.value(undefined), signParams.redeemScript, `${posType} requires NO redeemScript`);
break;
}
}
function trySign({ input, ourPubKey, keyPair, signatureHash, hashType, useLowR, taptreeRoot, }) {
if (input.witnessVersion === 1 && ourPubKey.length === 33)
ourPubKey = ourPubKey.slice(1);
// enforce in order signing of public keys
let signed = false;
for (const [i, pubKey] of input.pubkeys.entries()) {
if (!ourPubKey.equals(pubKey))
continue;
if (input.signatures[i] && input.signatures[i].length > 0)
throw new Error('Signature already exists');
// TODO: add tests
if (ourPubKey.length !== 33 && input.witnessVersion === 0) {
throw new Error('BIP143 (Witness v0) inputs require compressed pubkeys');
}
else if (ourPubKey.length !== 32 && input.witnessVersion === 1) {
throw new Error('BIP341 (Witness v1) inputs require x-only pubkeys');
}
if (input.witnessVersion === 1) {
if (!input.witnessScript) {
// FIXME: Workaround for not having proper tweaking support for key path
if (!keyPair.privateKey) {
throw new Error(`unexpected keypair`);
}
const privateKey = _7.taproot.tapTweakPrivkey(noble_ecc_1.ecc, ourPubKey, keyPair.privateKey, taptreeRoot);
keyPair = noble_ecc_1.ECPair.fromPrivateKey(Buffer.from(privateKey));
}
// https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#common-signature-message
const signature = keyPair.signSchnorr(signatureHash);
// SIGHASH_DEFAULT is omitted from the signature
if (hashType === _8.Transaction.SIGHASH_DEFAULT) {
input.signatures[i] = Buffer.from(signature);
}
else {
input.signatures[i] = Buffer.concat([signature, Buffer.of(hashType)]);
}
}
else {
const signature = keyPair.sign(signatureHash, useLowR);
input.signatures[i] = _5.script.signature.encode(signature, hashType);
}
signed = true;
}
if (!signed)
throw new Error('Key pair cannot sign for this input');
}
function getSigningData(network, inputs, needsOutputs, tx, signParams, keyPair, redeemScript, hashType, witnessValue, witnessScript, controlBlock, annex, useLowR) {
let vin;
if (typeof signParams === 'number') {
console.warn('DEPRECATED: TransactionBuilder sign method arguments ' + 'will change in v6, please use the TxbSignArg interface');
vin = signParams;
}
else if (typeof signParams === 'object') {
checkSignArgs(inputs, signParams);
({ vin, keyPair, redeemScript, hashType, witnessValue, witnessScript, controlBlock, annex } = signParams);
}
else {
throw new TypeError('TransactionBuilder sign first arg must be TxbSignArg or number');
}
if (keyPair === undefined) {
throw new Error('sign requires keypair');
}
if (!inputs[vin])
throw new Error('No input at index: ' + vin);
const input = inputs[vin];
// if redeemScript was previously provided, enforce consistency
if (input.redeemScript !== undefined && redeemScript && !input.redeemScript.equals(redeemScript)) {
throw new Error('Inconsistent redeemScript');
}
const ourPubKey = keyPair.publicKey || (keyPair.getPublicKey && keyPair.getPublicKey());
if (!canSign(input)) {
if (witnessValue !== undefined) {
if (input.value !== undefined && input.value !== witnessValue) {
throw new Error('Input did not match witnessValue');
}
typeforce(types.Satoshi, witnessValue);
input.value = witnessValue;
}
if (!canSign(input)) {
const prepared = prepareInput(input, ourPubKey, redeemScript, witnessScript, controlBlock, annex);
// updates inline
Object.assign(input, prepared);
}
if (!canSign(input))
throw Error(input.prevOutType + ' not supported');
}
// hashType can be 0 in Taproot, so can't use hashType || SIGHASH_ALL
if (input.witnessVersion === 1) {
hashType = hashType === undefined ? _8.Transaction.SIGHASH_DEFAULT : hashType;
}
else {
hashType = hashType || _8.Transaction.SIGHASH_ALL;
}
if (needsOutputs(hashType))
throw new Error('Transaction needs outputs');
// TODO: This is not the best place to do this, but might stick with it until PSBT
let leafHash;
let taptreeRoot;
if (controlBlock && witnessScript) {
leafHash = _7.taproot.getTapleafHash(noble_ecc_1.ecc, controlBlock, witnessScript);
taptreeRoot = _7.taproot.getTaptreeRoot(noble_ecc_1.ecc, controlBlock, witnessScript, leafHash);
}
// ready to sign
let signatureHash;
switch (input.witnessVersion) {
case undefined:
signatureHash = tx.hashForSignature(vin, input.signScript, hashType, input.value);
break;
case 0:
signatureHash = tx.hashForWitnessV0(vin, input.signScript, input.value, hashType);
break;
case 1:
signatureHash = tx.hashForWitnessV1(vin, inputs.map(({ prevOutScript }) => prevOutScript), inputs.map(({ value }) => value), hashType, leafHash);
break;
default:
throw new TypeError('Unsupported witness version');
}
return {
input,
ourPubKey,
keyPair,
signatureHash,
hashType,
useLowR: !!useLowR,
taptreeRoot,
};
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb25fYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90cmFuc2FjdGlvbl9idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLGlEQUFpRDtBQUNqRCx5QkFBdUQ7QUFDdkQsNkRBQTZEO0FBQzdELHVDQUF1QztBQUN2Qyx5QkFBdUM7QUFDdkMseUJBQThCO0FBRTlCLHlCQUE4QjtBQUU5Qix5QkFBdUM7QUFDdkMseUJBQW9DO0FBQ3BDLHlCQUE2QjtBQUM3Qix5QkFBMkM7QUFDM0MsMkNBQW9EO0FBVXBELE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUV2QyxNQUFNLFlBQVksR0FBRyxDQUFDLEdBQVEsRUFBVyxFQUFFO0lBQ3pDLE9BQU8sU0FBUyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLElBQUksT0FBTyxHQUFHLENBQUMsSUFBSSxLQUFLLFVBQVUsSUFBSSxPQUFPLEdBQUcsQ0FBQyxXQUFXLEtBQUssVUFBVSxDQUFDO0FBQ3BILENBQUMsQ0FBQztBQUVGLE1BQU0sWUFBWSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUM7QUFFcEMsTUFBTSxhQUFhLEdBQWdCLElBQUksR0FBRyxDQUFDO0lBQ3pDLE1BQU07SUFDTixPQUFPO0lBQ1AsTUFBTTtJQUNOLFFBQVE7SUFDUixNQUFNO0lBQ04sZUFBZTtJQUNmLFlBQVk7SUFDWixXQUFXO0lBQ1gsYUFBYTtJQUNiLFdBQVc7SUFDWCxnQkFBZ0I7SUFDaEIsYUFBYTtJQUNiLFlBQVk7SUFDWixZQUFZO0lBQ1oscUJBQXFCO0lBQ3JCLGtCQUFrQjtJQUNsQixpQkFBaUI7SUFDakIsaUJBQWlCO0lBQ2pCLGVBQWU7SUFDZixNQUFNO0lBQ04sa0JBQWtCO0lBQ2xCLFdBQVc7Q0FDWixDQUFDLENBQUM7QUFrREgsU0FBUyxTQUFTLENBQUMsSUFBUyxFQUFFLEtBQVUsRUFBRSxPQUFlO0lBQ3ZE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QyxDQUFDO0lBQ3ZELENBQUM7SUFFRCxPQUFPO1FBQ0wsS0FBSztRQUNMLFNBQVM7UUFDVCxPQUFPO1FBQ1AsYUFBYTtRQUNiLFFBQVE7UUFDUixPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU87UUFDbEIsV0FBVztLQUNaLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgdHlwZXMgZnJvbSAnYml0Y29pbmpzLWxpYi9zcmMvdHlwZXMnO1xuaW1wb3J0IHsgYWRkcmVzcyBhcyBiYWRkcmVzcywgcDJ0clBheW1lbnRzIH0gZnJvbSAnLi8nO1xuaW1wb3J0ICogYXMgYnVmZmVydXRpbHMgZnJvbSAnYml0Y29pbmpzLWxpYi9zcmMvYnVmZmVydXRpbHMnO1xuaW1wb3J0ICogYXMgY2xhc3NpZnkgZnJvbSAnLi9jbGFzc2lmeSc7XG5pbXBvcnQgeyBjcnlwdG8gYXMgYmNyeXB0byB9IGZyb20gJy4vJztcbmltcG9ydCB7IG5ldHdvcmtzIH0gZnJvbSAnLi8nO1xuaW1wb3J0IHsgTmV0d29yayB9IGZyb20gJy4vJztcbmltcG9ydCB7IHBheW1lbnRzIH0gZnJvbSAnLi8nO1xuaW1wb3J0IHsgUGF5bWVudCB9IGZyb20gJy4vJztcbmltcG9ydCB7IHNjcmlwdCBhcyBic2NyaXB0IH0gZnJvbSAnLi8nO1xuaW1wb3J0IHsgb3Bjb2RlcyBhcyBvcHMgfSBmcm9tICcuLyc7XG5pbXBvcnQgeyB0YXByb290IH0gZnJvbSAnLi8nO1xuaW1wb3J0IHsgVHhPdXRwdXQsIFRyYW5zYWN0aW9uIH0gZnJvbSAnLi8nO1xuaW1wb3J0IHsgRUNQYWlyLCBlY2MgYXMgZWNjTGliIH0gZnJvbSAnLi9ub2JsZV9lY2MnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNpZ25lciB7XG4gIHByaXZhdGVLZXk/OiBCdWZmZXI7XG4gIHB1YmxpY0tleTogQnVmZmVyO1xuICBnZXRQdWJsaWNLZXk/KCk6IEJ1ZmZlcjtcbiAgc2lnbihoYXNoOiBCdWZmZXIsIGxvd1I/OiBib29sZWFuKTogQnVmZmVyO1xuICBzaWduU2Nobm9ycihoYXNoOiBCdWZmZXIpOiBCdWZmZXI7XG59XG5cbmNvbnN0IHR5cGVmb3JjZSA9IHJlcXVpcmUoJ3R5cGVmb3JjZScpO1xuXG5jb25zdCB0ZkZ1bGxTaWduZXIgPSAob2JqOiBhbnkpOiBib29sZWFuID0+IHtcbiAgcmV0dXJuIHR5cGVmb3JjZS5CdWZmZXIob2JqLnB1YmxpY0tleSkgJiYgdHlwZW9mIG9iai5zaWduID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBvYmouc2lnblNjaG5vcnIgPT09ICdmdW5jdGlvbic7XG59O1xuXG5jb25zdCBTQ1JJUFRfVFlQRVMgPSBjbGFzc2lmeS50eXBlcztcblxuY29uc3QgUFJFVk9VVF9UWVBFUzogU2V0PHN0cmluZz4gPSBuZXcgU2V0KFtcbiAgLy8gUmF3XG4gICdwMnBraCcsXG4gICdwMnBrJyxcbiAgJ3Ayd3BraCcsXG4gICdwMm1zJyxcbiAgLy8gUDJTSCB3cmFwcGVkXG4gICdwMnNoLXAycGtoJyxcbiAgJ3Ayc2gtcDJwaycsXG4gICdwMnNoLXAyd3BraCcsXG4gICdwMnNoLXAybXMnLFxuICAvLyBQMldTSCB3cmFwcGVkXG4gICdwMndzaC1wMnBraCcsXG4gICdwMndzaC1wMnBrJyxcbiAgJ3Ayd3NoLXAybXMnLFxuICAvLyBQMlNILVAyV1NIIHdyYXBwZXJcbiAgJ3Ayc2gtcDJ3c2gtcDJwa2gnLFxuICAncDJzaC1wMndzaC1wMnBrJyxcbiAgJ3Ayc2gtcDJ3c2gtcDJtcycsXG4gIC8vIFAyVFIgS2V5UGF0aFxuICAncDJ0cicsXG4gIC8vIFAyVFIgU2NyaXB0UGF0aFxuICAncDJ0ci1wMm5zJyxcbl0pO1xuXG50eXBlIE1heWJlQnVmZmVyID0gQnVmZmVyIHwgdW5kZWZpbmVkO1xudHlwZSBUeGJTaWduYXR1cmVzID0gQnVmZmVyW10gfCBNYXliZUJ1ZmZlcltdO1xudHlwZSBUeGJQdWJrZXlzID0gTWF5YmVCdWZmZXJbXTtcbnR5cGUgVHhiV2l0bmVzcyA9IEJ1ZmZlcltdO1xudHlwZSBUeGJTY3JpcHRUeXBlID0gc3RyaW5nO1xudHlwZSBUeGJTY3JpcHQgPSBCdWZmZXI7XG5cbmludGVyZmFjZSBUeGJJbnB1dDxUTnVtYmVyIGV4dGVuZHMgbnVtYmVyIHwgYmlnaW50ID0gbnVtYmVyPiB7XG4gIHZhbHVlPzogVE51bWJlcjtcbiAgd2l0bmVzc1ZlcnNpb24/OiBudW1iZXI7XG4gIHNpZ25TY3JpcHQ/OiBUeGJTY3JpcHQ7XG4gIHNpZ25UeXBlPzogVHhiU2NyaXB0VHlwZTtcbiAgcHJldk91dFNjcmlwdD86IFR4YlNjcmlwdDtcbiAgcmVkZWVtU2NyaXB0PzogVHhiU2NyaXB0O1xuICByZWRlZW1TY3JpcHRUeXBlPzogVHhiU2NyaXB0VHlwZTtcbiAgcHJldk91dFR5cGU/OiBUeGJTY3JpcHRUeXBlO1xuICBwdWJrZXlzPzogVHhiUHVia2V5cztcbiAgc2lnbmF0dXJlcz86IFR4YlNpZ25hdHVyZXM7XG4gIHdpdG5lc3M/OiBUeGJXaXRuZXNzO1xuICB3aXRuZXNzU2NyaXB0PzogVHhiU2NyaXB0O1xuICB3aXRuZXNzU2NyaXB0VHlwZT86IFR4YlNjcmlwdFR5cGU7XG4gIGNvbnRyb2xCbG9jaz86IEJ1ZmZlcjtcbiAgYW5uZXg/OiBCdWZmZXI7XG4gIHNjcmlwdD86IFR4YlNjcmlwdDtcbiAgc2VxdWVuY2U/OiBudW1iZXI7XG4gIHNjcmlwdFNpZz86IFR4YlNjcmlwdDtcbiAgbWF4U2lnbmF0dXJlcz86IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIFR4Yk91dHB1dCB7XG4gIHR5cGU6IHN0cmluZztcbiAgcHVia2V5cz86IFR4YlB1YmtleXM7XG4gIHNpZ25hdHVyZXM/OiBUeGJTaWduYXR1cmVzO1xuICBtYXhTaWduYXR1cmVzPzogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgVHhiU2lnbkFyZzxUTnVtYmVyIGV4dGVuZHMgbnVtYmVyIHwgYmlnaW50ID0gbnVtYmVyPiB7XG4gIHByZXZPdXRTY3JpcHRUeXBlOiBzdHJpbmc7XG4gIHZpbjogbnVtYmVyO1xuICBrZXlQYWlyOiBTaWduZXI7XG4gIHJlZGVlbVNjcmlwdD86IEJ1ZmZlcjtcbiAgaGFzaFR5cGU/OiBudW1iZXI7XG4gIHdpdG5lc3NWYWx1ZT86IFROdW1iZXI7XG4gIHdpdG5lc3NTY3JpcHQ/OiBCdWZmZXI7XG4gIGNvbnRyb2xCbG9jaz86IEJ1ZmZlcjtcbiAgYW5uZXg/OiBCdWZmZXI7XG59XG5cbmZ1bmN0aW9uIHRmTWVzc2FnZSh0eXBlOiBhbnksIHZhbHVlOiBhbnksIG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xuICB0cnkge1xuICAgIHR5cGVmb3JjZSh0eXBlLCB2YWx1ZSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB0eElzU3RyaW5nPFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQgPSBudW1iZXI+KFxuICB0eDogQnVmZmVyIHwgc3RyaW5nIHwgVHJhbnNhY3Rpb248VE51bWJlcj5cbik6IHR4IGlzIHN0cmluZyB7XG4gIHJldHVybiB0eXBlb2YgdHggPT09ICdzdHJpbmcnIHx8IHR4IGluc3RhbmNlb2YgU3RyaW5nO1xufVxuXG5mdW5jdGlvbiB0eElzVHJhbnNhY3Rpb248VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludCA9IG51bWJlcj4oXG4gIHR4OiBCdWZmZXIgfCBzdHJpbmcgfCBUcmFuc2FjdGlvbjxUTnVtYmVyPlxuKTogdHggaXMgVHJhbnNhY3Rpb248VE51bWJlcj4ge1xuICByZXR1cm4gdHggaW5zdGFuY2VvZiBUcmFuc2FjdGlvbjtcbn1cblxuZXhwb3J0IGNsYXNzIFRyYW5zYWN0aW9uQnVpbGRlcjxUTnVtYmVyIGV4dGVuZHMgbnVtYmVyIHwgYmlnaW50ID0gbnVtYmVyPiB7XG4gIHN0YXRpYyBmcm9tVHJhbnNhY3Rpb248VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludCA9IG51bWJlcj4oXG4gICAgdHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uPFROdW1iZXI+LFxuICAgIG5ldHdvcms/OiBOZXR3b3JrLFxuICAgIHByZXZPdXRwdXRzPzogVHhPdXRwdXQ8VE51bWJlcj5bXVxuICApOiBUcmFuc2FjdGlvbkJ1aWxkZXI8VE51bWJlcj4ge1xuICAgIGNvbnN0IHR4YiA9IG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXI8VE51bWJlcj4obmV0d29yayk7XG5cbiAgICAvLyBDb3B5IHRyYW5zYWN0aW9uIGZpZWxkc1xuICAgIHR4Yi5zZXRWZXJzaW9uKHRyYW5zYWN0aW9uLnZlcnNpb24pO1xuICAgIHR4Yi5zZXRMb2NrVGltZSh0cmFuc2FjdGlvbi5sb2NrdGltZSk7XG5cbiAgICAvLyBDb3B5IG91dHB1dHMgKGRvbmUgZmlyc3QgdG8gYXZvaWQgc2lnbmF0dXJlIGludmFsaWRhdGlvbilcbiAgICB0cmFuc2FjdGlvbi5vdXRzLmZvckVhY2goKHR4T3V0KSA9PiB7XG4gICAgICB0eGIuYWRkT3V0cHV0KHR4T3V0LnNjcmlwdCwgKHR4T3V0IGFzIFR4T3V0cHV0PFROdW1iZXI+KS52YWx1ZSk7XG4gICAgfSk7XG5cbiAgICAvLyBDb3B5IGlucHV0c1xuICAgIHRyYW5zYWN0aW9uLmlucy5mb3JFYWNoKCh0eEluKSA9PiB7XG4gICAgICB0eGIuX19hZGRJbnB1dFVuc2FmZSh0eEluLmhhc2gsIHR4SW4uaW5kZXgsIHtcbiAgICAgICAgc2VxdWVuY2U6IHR4SW4uc2VxdWVuY2UsXG4gICAgICAgIHNjcmlwdDogdHhJbi5zY3JpcHQsXG4gICAgICAgIHdpdG5lc3M6IHR4SW4ud2l0bmVzcyxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gZml4IHNvbWUgdGhpbmdzIG5vdCBwb3NzaWJsZSB0aHJvdWdoIHRoZSBwdWJsaWMgQVBJXG4gICAgdHhiLl9fSU5QVVRTLmZvckVhY2goKGlucHV0LCBpKSA9PiB7XG4gICAgICBmaXhNdWx0aXNpZ09yZGVyPFROdW1iZXI+KGlucHV0LCB0cmFuc2FjdGlvbiwgaSwgcHJldk91dHB1dHMpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHR4YjtcbiAgfVxuXG4gIHByaXZhdGUgX19QUkVWX1RYX1NFVDogeyBbaW5kZXg6IHN0cmluZ106IGJvb2xlYW4gfTtcbiAgcHJpdmF0ZSBfX0lOUFVUUzogQXJyYXk8VHhiSW5wdXQ8VE51bWJlcj4+O1xuICBwcml2YXRlIF9fVFg6IFRyYW5zYWN0aW9uPFROdW1iZXI+O1xuICBwcml2YXRlIF9fVVNFX0xPV19SOiBib29sZWFuO1xuXG4gIC8vIFdBUk5JTkc6IG1heGltdW1GZWVSYXRlIGlzIF9fTk9UX18gdG8gYmUgcmVsaWVkIG9uLFxuICAvLyAgICAgICAgICBpdCdzIGp1c3QgYW5vdGhlciBwb3RlbnRpYWwgc2FmZXR5IG1lY2hhbmlzbSAoc2FmZXR5IGluLWRlcHRoKVxuICBjb25zdHJ1Y3RvcihwdWJsaWMgbmV0d29yazogTmV0d29yayA9IG5ldHdvcmtzLmJpdGNvaW4sIHB1YmxpYyBtYXhpbXVtRmVlUmF0ZTogbnVtYmVyID0gMjUwMCkge1xuICAgIHRoaXMuX19QUkVWX1RYX1NFVCA9IHt9O1xuICAgIHRoaXMuX19JTlBVVFMgPSBbXTtcbiAgICB0aGlzLl9fVFggPSBuZXcgVHJhbnNhY3Rpb248VE51bWJlcj4oKTtcbiAgICB0aGlzLl9fVFgudmVyc2lvbiA9IDI7XG4gICAgdGhpcy5fX1VTRV9MT1dfUiA9IGZhbHNlO1xuICB9XG5cbiAgc2V0TG93UihzZXR0aW5nPzogYm9vbGVhbik6IGJvb2xlYW4ge1xuICAgIHR5cGVmb3JjZSh0eXBlZm9yY2UubWF5YmUodHlwZWZvcmNlLkJvb2xlYW4pLCBzZXR0aW5nKTtcbiAgICBpZiAoc2V0dGluZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBzZXR0aW5nID0gdHJ1ZTtcbiAgICB9XG4gICAgdGhpcy5fX1VTRV9MT1dfUiA9IHNldHRpbmc7XG4gICAgcmV0dXJuIHNldHRpbmc7XG4gIH1cblxuICBzZXRMb2NrVGltZShsb2NrdGltZTogbnVtYmVyKTogdm9pZCB7XG4gICAgdHlwZWZvcmNlKHR5cGVzLlVJbnQzMiwgbG9ja3RpbWUpO1xuXG4gICAgLy8gaWYgYW55IHNpZ25hdHVyZXMgZXhpc3QsIHRocm93XG4gICAgaWYgKFxuICAgICAgdGhpcy5fX0lOUFVUUy5zb21lKChpbnB1dCkgPT4ge1xuICAgICAgICBpZiAoIWlucHV0LnNpZ25hdHVyZXMpIHJldHVybiBmYWxzZTtcblxuICAgICAgICByZXR1cm4gaW5wdXQuc2lnbmF0dXJlcy5zb21lKChzKSA9PiBzICE9PSB1bmRlZmluZWQpO1xuICAgICAgfSlcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8sIHRoaXMgd291bGQgaW52YWxpZGF0ZSBzaWduYXR1cmVzJyk7XG4gICAgfVxuXG4gICAgdGhpcy5fX1RYLmxvY2t0aW1lID0gbG9ja3RpbWU7XG4gIH1cblxuICBzZXRWZXJzaW9uKHZlcnNpb246IG51bWJlcik6IHZvaWQge1xuICAgIHR5cGVmb3JjZSh0eXBlcy5VSW50MzIsIHZlcnNpb24pO1xuXG4gICAgLy8gWFhYOiB0aGlzIG1pZ2h0IGV2ZW50dWFsbHkgYmVjb21lIG1vcmUgY29tcGxleCBkZXBlbmRpbmcgb24gd2hhdCB0aGUgdmVyc2lvbnMgcmVwcmVzZW50XG4gICAgdGhpcy5fX1RYLnZlcnNpb24gPSB2ZXJzaW9uO1xuICB9XG5cbiAgYWRkSW5wdXQoXG4gICAgdHhIYXNoOiBCdWZmZXIgfCBzdHJpbmcgfCBUcmFuc2FjdGlvbjxUTnVtYmVyPixcbiAgICB2b3V0OiBudW1iZXIsXG4gICAgc2VxdWVuY2U/OiBudW1iZXIsXG4gICAgcHJldk91dFNjcmlwdD86IEJ1ZmZlcixcbiAgICB2YWx1ZT86IFROdW1iZXJcbiAgKTogbnVtYmVyIHtcbiAgICBpZiAoIXRoaXMuX19jYW5Nb2RpZnlJbnB1dHMoKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObywgdGhpcyB3b3VsZCBpbnZhbGlkYXRlIHNpZ25hdHVyZXMnKTtcbiAgICB9XG5cbiAgICAvLyBpcyBpdCBhIGhleCBzdHJpbmc/XG4gICAgaWYgKHR4SXNTdHJpbmcodHhIYXNoKSkge1xuICAgICAgLy8gdHJhbnNhY3Rpb24gaGFzaHMncyBhcmUgZGlzcGxheWVkIGluIHJldmVyc2Ugb3JkZXIsIHVuLXJldmVyc2UgaXRcbiAgICAgIHR4SGFzaCA9IGJ1ZmZlcnV0aWxzLnJldmVyc2VCdWZmZXIoQnVmZmVyLmZyb20odHhIYXNoLCAnaGV4JykpO1xuXG4gICAgICAvLyBpcyBpdCBhIFRyYW5zYWN0aW9uIG9iamVjdD9cbiAgICB9IGVsc2UgaWYgKHR4SXNUcmFuc2FjdGlvbih0eEhhc2gpKSB7XG4gICAgICBjb25zdCB0eE91dCA9IHR4SGFzaC5vdXRzW3ZvdXRdO1xuICAgICAgcHJldk91dFNjcmlwdCA9IHR4T3V0LnNjcmlwdDtcbiAgICAgIHZhbHVlID0gKHR4T3V0IGFzIFR4T3V0cHV0PFROdW1iZXI+KS52YWx1ZTtcblxuICAgICAgdHhIYXNoID0gdHhIYXNoLmdldEhhc2goZmFsc2UpIGFzIEJ1ZmZlcjtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fX2FkZElucHV0VW5zYWZlKHR4SGFzaCwgdm91dCwge1xuICAgICAgc2VxdWVuY2UsXG4gICAgICBwcmV2T3V0U2NyaXB0LFxuICAgICAgdmFsdWUsXG4gICAgfSk7XG4gIH1cblxuICBhZGRPdXRwdXQoc2NyaXB0UHViS2V5OiBzdHJpbmcgfCBCdWZmZXIsIHZhbHVlOiBUTnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAoIXRoaXMuX19jYW5Nb2RpZnlPdXRwdXRzKCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8sIHRoaXMgd291bGQgaW52YWxpZGF0ZSBzaWduYXR1cmVzJyk7XG4gICAgfVxuXG4gICAgLy8gQXR0ZW1wdCB0byBnZXQgYSBzY3JpcHQgaWYgaXQncyBhIGJhc2U1OCBvciBiZWNoMzIgYWRkcmVzcyBzdHJpbmdcbiAgICBpZiAodHlwZW9mIHNjcmlwdFB1YktleSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHNjcmlwdFB1YktleSA9IGJhZGRyZXNzLnRvT3V0cHV0U2NyaXB0KHNjcmlwdFB1YktleSwgdGhpcy5uZXR3b3JrKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fX1RYLmFkZE91dHB1dChzY3JpcHRQdWJLZXksIHZhbHVlKTtcbiAgfVxuXG4gIGJ1aWxkKCk6IFRyYW5zYWN0aW9uPFROdW1iZXI+IHtcbiAgICByZXR1cm4gdGhpcy5fX2J1aWxkKGZhbHNlKTtcbiAgfVxuXG4gIGJ1aWxkSW5jb21wbGV0ZSgpOiBUcmFuc2FjdGlvbjxUTnVtYmVyPiB7XG4gICAgcmV0dXJuIHRoaXMuX19idWlsZCh0cnVlKTtcbiAgfVxuXG4gIHNpZ24oXG4gICAgc2lnblBhcmFtczogbnVtYmVyIHwgVHhiU2lnbkFyZzxUTnVtYmVyPixcbiAgICBrZXlQYWlyPzogU2lnbmVyLFxuICAgIHJlZGVlbVNjcmlwdD86IEJ1ZmZlcixcbiAgICBoYXNoVHlwZT86IG51bWJlcixcbiAgICB3aXRuZXNzVmFsdWU/OiBUTnVtYmVyLFxuICAgIHdpdG5lc3NTY3JpcHQ/OiBCdWZmZXIsXG4gICAgY29udHJvbEJsb2NrPzogQnVmZmVyLFxuICAgIGFubmV4PzogQnVmZmVyXG4gICk6IHZvaWQge1xuICAgIHRyeVNpZ248VE51bWJlcj4oXG4gICAgICBnZXRTaWduaW5nRGF0YTxUTnVtYmVyPihcbiAgICAgICAgdGhpcy5uZXR3b3JrLFxuICAgICAgICB0aGlzLl9fSU5QVVRTLFxuICAgICAgICB0aGlzLl9fbmVlZHNPdXRwdXRzLmJpbmQodGhpcyksXG4gICAgICAgIHRoaXMuX19UWCxcbiAgICAgICAgc2lnblBhcmFtcyxcbiAgICAgICAga2V5UGFpcixcbiAgICAgICAgcmVkZWVtU2NyaXB0LFxuICAgICAgICBoYXNoVHlwZSxcbiAgICAgICAgd2l0bmVzc1ZhbHVlLFxuICAgICAgICB3aXRuZXNzU2NyaXB0LFxuICAgICAgICBjb250cm9sQmxvY2ssXG4gICAgICAgIGFubmV4LFxuICAgICAgICB0aGlzLl9fVVNFX0xPV19SXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgX19hZGRJbnB1dFVuc2FmZSh0eEhhc2g6IEJ1ZmZlciwgdm91dDogbnVtYmVyLCBvcHRpb25zOiBUeGJJbnB1dDxUTnVtYmVyPik6IG51bWJlciB7XG4gICAgaWYgKFRyYW5zYWN0aW9uLmlzQ29pbmJhc2VIYXNoKHR4SGFzaCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY29pbmJhc2UgaW5wdXRzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG5cbiAgICBjb25zdCBwcmV2VHhPdXQgPSB0eEhhc2gudG9TdHJpbmcoJ2hleCcpICsgJzonICsgdm91dDtcbiAgICBpZiAodGhpcy5fX1BSRVZfVFhfU0VUW3ByZXZUeE91dF0gIT09IHVuZGVmaW5lZCkgdGhyb3cgbmV3IEVycm9yKCdEdXBsaWNhdGUgVHhPdXQ6ICcgKyBwcmV2VHhPdXQpO1xuXG4gICAgbGV0IGlucHV0OiBUeGJJbnB1dDxUTnVtYmVyPiA9IHt9O1xuXG4gICAgLy8gZGVyaXZlIHdoYXQgd2UgY2FuIGZyb20gdGhlIHNjcmlwdFNpZ1xuICAgIGlmIChvcHRpb25zLnNjcmlwdCAhPT0gdW5kZWZpbmVkIHx8IG9wdGlvbnMud2l0bmVzcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpbnB1dCA9IGV4cGFuZElucHV0PFROdW1iZXI+KG9wdGlvbnMuc2NyaXB0LCBvcHRpb25zLndpdG5lc3MpO1xuICAgIH1cblxuICAgIC8vIGlmIGFuIGlucHV0IHZhbHVlIHdhcyBnaXZlbiwgcmV0YWluIGl0XG4gICAgaWYgKG9wdGlvbnMudmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaW5wdXQudmFsdWUgPSBvcHRpb25zLnZhbHVlO1xuICAgIH1cblxuICAgIC8vIGRlcml2ZSB3aGF0IHdlIGNhbiBmcm9tIHRoZSBwcmV2aW91cyB0cmFuc2FjdGlvbnMgb3V0cHV0IHNjcmlwdFxuICAgIGlmICghaW5wdXQucHJldk91dFNjcmlwdCAmJiBvcHRpb25zLnByZXZPdXRTY3JpcHQpIHtcbiAgICAgIGxldCBwcmV2T3V0VHlwZTtcblxuICAgICAgaWYgKCFpbnB1dC5wdWJrZXlzICYmICFpbnB1dC5zaWduYXR1cmVzKSB7XG4gICAgICAgIGNvbnN0IGV4cGFuZGVkID0gZXhwYW5kT3V0cHV0KG9wdGlvbnMucHJldk91dFNjcmlwdCk7XG4gICAgICAgIGlmIChleHBhbmRlZC5wdWJrZXlzKSB7XG4gICAgICAgICAgaW5wdXQucHVia2V5cyA9IGV4cGFuZGVkLnB1YmtleXM7XG4gICAgICAgICAgaW5wdXQuc2lnbmF0dXJlcyA9IGV4cGFuZGVkLnNpZ25hdHVyZXM7XG4gICAgICAgIH1cblxuICAgICAgICBwcmV2T3V0VHlwZSA9IGV4cGFuZGVkLnR5cGU7XG4gICAgICB9XG5cbiAgICAgIGlucHV0LnByZXZPdXRTY3JpcHQgPSBvcHRpb25zLnByZXZPdXRTY3JpcHQ7XG4gICAgICBpbnB1dC5wcmV2T3V0VHlwZSA9IHByZXZPdXRUeXBlIHx8IGNsYXNzaWZ5Lm91dHB1dChvcHRpb25zLnByZXZPdXRTY3JpcHQpO1xuICAgIH1cblxuICAgIGNvbnN0IHZpbiA9IHRoaXMuX19UWC5hZGRJbnB1dCh0eEhhc2gsIHZvdXQsIG9wdGlvbnMuc2VxdWVuY2UsIG9wdGlvbnMuc2NyaXB0U2lnKTtcbiAgICB0aGlzLl9fSU5QVVRTW3Zpbl0gPSBpbnB1dDtcbiAgICB0aGlzLl9fUFJFVl9UWF9TRVRbcHJldlR4T3V0XSA9IHRydWU7XG4gICAgcmV0dXJuIHZpbjtcbiAgfVxuXG4gIHByaXZhdGUgX19idWlsZChhbGxvd0luY29tcGxldGU/OiBib29sZWFuKTogVHJhbnNhY3Rpb248VE51bWJlcj4ge1xuICAgIGlmICghYWxsb3dJbmNvbXBsZXRlKSB7XG4gICAgICBpZiAoIXRoaXMuX19UWC5pbnMubGVuZ3RoKSB0aHJvdyBuZXcgRXJyb3IoJ1RyYW5zYWN0aW9uIGhhcyBubyBpbnB1dHMnKTtcbiAgICAgIGlmICghdGhpcy5fX1RYLm91dHMubGVuZ3RoKSB0aHJvdyBuZXcgRXJyb3IoJ1RyYW5zYWN0aW9uIGhhcyBubyBvdXRwdXRzJyk7XG4gICAgfVxuXG4gICAgY29uc3QgdHggPSB0aGlzLl9fVFguY2xvbmUoKTtcblxuICAgIC8vIGNyZWF0ZSBzY3JpcHQgc2lnbmF0dXJlcyBmcm9tIGlucHV0c1xuICAgIHRoaXMuX19JTlBVVFMuZm9yRWFjaCgoaW5wdXQsIGkpID0+IHtcbiAgICAgIGlmICghaW5wdXQucHJldk91dFR5cGUgJiYgIWFsbG93SW5jb21wbGV0ZSkgdGhyb3cgbmV3IEVycm9yKCdUcmFuc2FjdGlvbiBpcyBub3QgY29tcGxldGUnKTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYnVpbGQ8VE51bWJlcj4oaW5wdXQucHJldk91dFR5cGUhLCBpbnB1dCwgYWxsb3dJbmNvbXBsZXRlKTtcbiAgICAgIGlmICghcmVzdWx0KSB7XG4gICAgICAgIGlmICghYWxsb3dJbmNvbXBsZXRlICYmIGlucHV0LnByZXZPdXRUeXBlID09PSBTQ1JJUFRfVFlQRVMuTk9OU1RBTkRBUkQpIHRocm93IG5ldyBFcnJvcignVW5rbm93biBpbnB1dCB0eXBlJyk7XG4gICAgICAgIGlmICghYWxsb3dJbmNvbXBsZXRlKSB0aHJvdyBuZXcgRXJyb3IoJ05vdCBlbm91Z2ggaW5mb3JtYXRpb24nKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzdWx0LmlucHV0KSB7XG4gICAgICAgIHR4LnNldElucHV0U2NyaXB0KGksIHJlc3VsdC5pbnB1dCk7XG4gICAgICB9XG4gICAgICB0eC5zZXRXaXRuZXNzKGksIHJlc3VsdC53aXRuZXNzISk7XG4gICAgfSk7XG5cbiAgICBpZiAoIWFsbG93SW5jb21wbGV0ZSkge1xuICAgICAgLy8gZG8gbm90IHJlbHkgb24gdGhpcywgaXRzIG1lcmVseSBhIGxhc3QgcmVzb3J0XG4gICAgICBpZiAodGhpcy5fX292ZXJNYXhpbXVtRmVlcyh0eC52aXJ0dWFsU2l6ZSgpKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyYW5zYWN0aW9uIGhhcyBhYnN1cmQgZmVlcycpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0eDtcbiAgfVxuXG4gIHByaXZhdGUgX19jYW5Nb2RpZnlJbnB1dHMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX19JTlBVVFMuZXZlcnkoKGlucHV0KSA9PiB7XG4gICAgICBpZiAoIWlucHV0LnNpZ25hdHVyZXMpIHJldHVybiB0cnVlO1xuXG4gICAgICByZXR1cm4gaW5wdXQuc2lnbmF0dXJlcy5ldmVyeSgoc2lnbmF0dXJlKSA9PiB7XG4gICAgICAgIGlmICghc2lnbmF0dXJlKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgY29uc3QgaGFzaFR5cGUgPSBzaWduYXR1cmVIYXNoVHlwZShzaWduYXR1cmUpO1xuXG4gICAgICAgIC8vIGlmIFNJR0hBU0hfQU5ZT05FQ0FOUEFZIGlzIHNldCwgc2lnbmF0dXJlcyB3b3VsZCBub3RcbiAgICAgICAgLy8gYmUgaW52YWxpZGF0ZWQgYnkgbW9yZSBpbnB1dHNcbiAgICAgICAgcmV0dXJuIChoYXNoVHlwZSAmIFRyYW5zYWN0aW9uLlNJR0hBU0hfQU5ZT05FQ0FOUEFZKSAhPT0gMDtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfX25lZWRzT3V0cHV0cyhzaWduaW5nSGFzaFR5cGU6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGlmIChzaWduaW5nSGFzaFR5cGUgPT09IFRyYW5zYWN0aW9uLlNJR0hBU0hfQUxMIHx8IHNpZ25pbmdIYXNoVHlwZSA9PT0gVHJhbnNhY3Rpb24uU0lHSEFTSF9ERUZBVUxUKSB7XG4gICAgICByZXR1cm4gdGhpcy5fX1RYLm91dHMubGVuZ3RoID09PSAwO1xuICAgIH1cblxuICAgIC8vIGlmIGlucHV0cyBhcmUgYmVpbmcgc2lnbmVkIHdpdGggU0lHSEFTSF9OT05FLCB3ZSBkb24ndCBzdHJpY3RseSBuZWVkIG91dHB1dHNcbiAgICAvLyAuYnVpbGQoKSB3aWxsIGZhaWwsIGJ1dCAuYnVpbGRJbmNvbXBsZXRlKCkgaXMgT0tcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5fX1RYLm91dHMubGVuZ3RoID09PSAwICYmXG4gICAgICB0aGlzLl9fSU5QVVRTLnNvbWUoKGlucHV0KSA9PiB7XG4gICAgICAgIGlmICghaW5wdXQuc2lnbmF0dXJlcykgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIHJldHVybiBpbnB1dC5zaWduYXR1cmVzLnNvbWUoKHNpZ25hdHVyZSkgPT4ge1xuICAgICAgICAgIGlmICghc2lnbmF0dXJlKSByZXR1cm4gZmFsc2U7IC8vIG5vIHNpZ25hdHVyZSwgbm8gaXNzdWVcbiAgICAgICAgICBjb25zdCBoYXNoVHlwZSA9IHNpZ25hdHVyZUhhc2hUeXBlKHNpZ25hdHVyZSk7XG4gICAgICAgICAgaWYgKGhhc2hUeXBlICYgVHJhbnNhY3Rpb24uU0lHSEFTSF9OT05FKSByZXR1cm4gZmFsc2U7IC8vIFNJR0hBU0hfTk9ORSBkb2Vzbid0IGNhcmUgYWJvdXQgb3V0cHV0c1xuICAgICAgICAgIHJldHVybiB0cnVlOyAvLyBTSUdIQVNIXyogZG9lcyBjYXJlXG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBfX2Nhbk1vZGlmeU91dHB1dHMoKTogYm9vbGVhbiB7XG4gICAgY29uc3QgbklucHV0cyA9IHRoaXMuX19UWC5pbnMubGVuZ3RoO1xuICAgIGNvbnN0IG5PdXRwdXRzID0gdGhpcy5fX1RYLm91dHMubGVuZ3RoO1xuXG4gICAgcmV0dXJuIHRoaXMuX19JTlBVVFMuZXZlcnkoKGlucHV0KSA9PiB7XG4gICAgICBpZiAoaW5wdXQuc2lnbmF0dXJlcyA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdHJ1ZTtcblxuICAgICAgcmV0dXJuIGlucHV0LnNpZ25hdHVyZXMuZXZlcnkoKHNpZ25hdHVyZSkgPT4ge1xuICAgICAgICBpZiAoIXNpZ25hdHVyZSkgcmV0dXJuIHRydWU7XG4gICAgICAgIGNvbnN0IGhhc2hUeXBlID0gc2lnbmF0dXJlSGFzaFR5cGUoc2lnbmF0dXJlKTtcblxuICAgICAgICBjb25zdCBoYXNoVHlwZU1vZCA9IGhhc2hUeXBlICYgMHgxZjtcbiAgICAgICAgaWYgKGhhc2hUeXBlTW9kID09PSBUcmFuc2FjdGlvbi5TSUdIQVNIX05PTkUpIHJldHVybiB0cnVlO1xuICAgICAgICBpZiAoaGFzaFR5cGVNb2QgPT09IFRyYW5zYWN0aW9uLlNJR0hBU0hfU0lOR0xFKSB7XG4gICAgICAgICAgLy8gaWYgU0lHSEFTSF9TSU5HTEUgaXMgc2V0LCBhbmQgbklucHV0cyA+IG5PdXRwdXRzXG4gICAgICAgICAgLy8gc29tZSBzaWduYXR1cmVzIHdvdWxkIGJlIGludmFsaWRhdGVkIGJ5IHRoZSBhZGRpdGlvblxuICAgICAgICAgIC8vIG9mIG1vcmUgb3V0cHV0c1xuICAgICAgICAgIHJldHVybiBuSW5wdXRzIDw9IG5PdXRwdXRzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfX292ZXJNYXhpbXVtRmVlcyhieXRlczogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgLy8gbm90IGFsbCBpbnB1dHMgd2lsbCBoYXZlIC52YWx1ZSBkZWZpbmVkXG4gICAgY29uc3QgaW5jb21pbmcgPSB0aGlzLl9fSU5QVVRTLnJlZHVjZShcbiAgICAgIChhLCB4KSA9PiBhICsgKHR5cGVvZiB4LnZhbHVlICE9PSAndW5kZWZpbmVkJyA/IEJpZ0ludCh4LnZhbHVlKSA6IEJpZ0ludCgwKSksXG4gICAgICBCaWdJbnQoMClcbiAgICApO1xuXG4gICAgLy8gYnV0IGFsbCBvdXRwdXRzIGRvLCBhbmQgaWYgd2UgaGF2ZSBhbnkgaW5wdXQgdmFsdWVcbiAgICAvLyB3ZSBjYW4gaW1tZWRpYXRlbHkgZGV0ZXJtaW5lIGlmIHRoZSBvdXRwdXRzIGFyZSB0b28gc21hbGxcbiAgICBjb25zdCBvdXRnb2luZyA9IHRoaXMuX19UWC5vdXRzLnJlZHVjZSgoYSwgeCkgPT4gYSArIEJpZ0ludCgoeCBhcyBUeE91dHB1dDxUTnVtYmVyPikudmFsdWUpLCBCaWdJbnQoMCkpO1xuICAgIGNvbnN0IGZlZSA9IGluY29taW5nIC0gb3V0Z29pbmc7XG4gICAgY29uc3QgZmVlUmF0ZSA9IE51bWJlcihmZWUpIC8gYnl0ZXM7IC8vIGFzc3VtZSBmZWUgZml0cyB3aXRoaW4gbnVtYmVyXG5cbiAgICByZXR1cm4gZmVlUmF0ZSA+IHRoaXMubWF4aW11bUZlZVJhdGU7XG4gIH1cbn1cblxuZnVuY3Rpb24gZXhwYW5kSW5wdXQ8VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludCA9IG51bWJlcj4oXG4gIHNjcmlwdFNpZz86IEJ1ZmZlcixcbiAgd2l0bmVzc1N0YWNrOiBCdWZmZXJbXSA9IFtdLFxuICB0eXBlPzogc3RyaW5nLFxuICBzY3JpcHRQdWJLZXk/OiBCdWZmZXJcbik6IFR4YklucHV0PFROdW1iZXI+IHtcbiAgaWYgKHNjcmlwdFNpZyAmJiBzY3JpcHRTaWcubGVuZ3RoID09PSAwICYmIHdpdG5lc3NTdGFjay5sZW5ndGggPT09IDApIHJldHVybiB7fTtcbiAgaWYgKCF0eXBlKSB7XG4gICAgbGV0IHNzVHlwZTogc3RyaW5nIHwgdW5kZWZpbmVkID0gc2NyaXB0U2lnID8gY2xhc3NpZnkuaW5wdXQoc2NyaXB0U2lnLCB0cnVlKSA6IHVuZGVmaW5lZDtcbiAgICBsZXQgd3NUeXBlOiBzdHJpbmcgfCB1bmRlZmluZWQgPSBjbGFzc2lmeS53aXRuZXNzKHdpdG5lc3NTdGFjaywgdHJ1ZSk7XG4gICAgaWYgKHNzVHlwZSA9PT0gU0NSSVBUX1RZUEVTLk5PTlNUQU5EQVJEKSBzc1R5cGUgPSB1bmRlZmluZWQ7XG4gICAgaWYgKHdzVHlwZSA9PT0gU0NSSVBUX1RZUEVTLk5PTlNUQU5EQVJEKSB3c1R5cGUgPSB1bmRlZmluZWQ7XG4gICAgdHlwZSA9IHNzVHlwZSB8fCB3c1R5cGU7XG4gIH1cblxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIFNDUklQVF9UWVBFUy5QMldQS0g6IHtcbiAgICAgIGNvbnN0IHsgb3V0cHV0LCBwdWJrZXksIHNpZ25hdHVyZSB9ID0gcGF5bWVudHMucDJ3cGtoKHtcbiAgICAgICAgd2l0bmVzczogd2l0bmVzc1N0YWNrLFxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHByZXZPdXRTY3JpcHQ6IG91dHB1dCxcbiAgICAgICAgcHJldk91dFR5cGU6IFNDUklQVF9UWVBFUy5QMldQS0gsXG4gICAgICAgIHB1YmtleXM6IFtwdWJrZXldLFxuICAgICAgICBzaWduYXR1cmVzOiBbc2lnbmF0dXJlXSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY2FzZSBTQ1JJUFRfVFlQRVMuUDJQS0g6IHtcbiAgICAgIGNvbnN0IHsgb3V0cHV0LCBwdWJrZXksIHNpZ25hdHVyZSB9ID0gcGF5bWVudHMucDJwa2goe1xuICAgICAgICBpbnB1dDogc2NyaXB0U2lnLFxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHByZXZPdXRTY3JpcHQ6IG91dHB1dCxcbiAgICAgICAgcHJldk91dFR5cGU6IFNDUklQVF9UWVBFUy5QMlBLSCxcbiAgICAgICAgcHVia2V5czogW3B1YmtleV0sXG4gICAgICAgIHNpZ25hdHVyZXM6IFtzaWduYXR1cmVdLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjYXNlIFNDUklQVF9UWVBFUy5QMlBLOiB7XG4gICAgICBjb25zdCB7IHNpZ25hdHVyZSB9ID0gcGF5bWVudHMucDJwayh7IGlucHV0OiBzY3JpcHRTaWcgfSk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHByZXZPdXRUeXBlOiBTQ1JJUFRfVFlQRVMuUDJQSyxcbiAgICAgICAgcHVia2V5czogW3VuZGVmaW5lZF0sXG4gICAgICAgIHNpZ25hdHVyZXM6IFtzaWduYXR1cmVdLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjYXNlIFNDUklQVF9UWVBFUy5QMk1TOiB7XG4gICAgICBjb25zdCB7IG0sIHB1YmtleXMsIHNpZ25hdHVyZXMgfSA9IHBheW1lbnRzLnAybXMoXG4gICAgICAgIHtcbiAgICAgICAgICBpbnB1dDogc2NyaXB0U2lnLFxuICAgICAgICAgIG91dHB1dDogc2NyaXB0UHViS2V5LFxuICAgICAgICB9LFxuICAgICAgICB7IGFsbG93SW5jb21wbGV0ZTogdHJ1ZSB9XG4gICAgICApO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBwcmV2T3V0VHlwZTogU0NSSVBUX1RZUEVTLlAyTVMsXG4gICAgICAgIHB1YmtleXMsXG4gICAgICAgIHNpZ25hdHVyZXMsXG4gICAgICAgIG1heFNpZ25hdHVyZXM6IG0sXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNhc2UgU0NSSVBUX1RZUEVTLlAyVFJfTlM6IHtcbiAgICAgIGNvbnN0IHsgbiwgcHVia2V5cywgc2lnbmF0dXJlcyB9ID0gcDJ0clBheW1lbnRzLnAydHJfbnMoXG4gICAgICAgIHtcbiAgICAgICAgICAvLyBXaXRuZXNzIHNpZ25hdHVyZXMgYXJlIHJldmVyc2Ugb2YgcHVia2V5cywgYmVjYXVzZSBpdCdzIGEgc3RhY2tcbiAgICAgICAgICBzaWduYXR1cmVzOiB3aXRuZXNzU3RhY2subGVuZ3RoID8gd2l0bmVzc1N0YWNrLnJldmVyc2UoKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICBvdXRwdXQ6IHNjcmlwdFB1YktleSxcbiAgICAgICAgfSxcbiAgICAgICAgeyBhbGxvd0luY29tcGxldGU6IHRydWUsIGVjY0xpYiB9XG4gICAgICApO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBwcmV2T3V0VHlwZTogU0NSSVBUX1RZUEVTLlAyVFJfTlMsXG4gICAgICAgIHB1YmtleXMsXG4gICAgICAgIHNpZ25hdHVyZXMsXG4gICAgICAgIG1heFNpZ25hdHVyZXM6IG4sXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGlmICh0eXBlID09PSBTQ1JJUFRfVFlQRVMuUDJTSCkge1xuICAgIGNvbnN0IHsgb3V0cHV0LCByZWRlZW0gfSA9IHBheW1lbnRzLnAyc2goe1xuICAgICAgaW5wdXQ6IHNjcmlwdFNpZyxcbiAgICAgIHdpdG5lc3M6IHdpdG5lc3NTdGFjayxcbiAgICB9KTtcblxuICAgIGNvbnN0IG91dHB1dFR5cGUgPSBjbGFzc2lmeS5vdXRwdXQocmVkZWVtIS5vdXRwdXQhKTtcbiAgICBjb25zdCBleHBhbmRlZCA9IGV4cGFuZElucHV0PFROdW1iZXI+KHJlZGVlbSEuaW5wdXQhLCByZWRlZW0hLndpdG5lc3MhLCBvdXRwdXRUeXBlLCByZWRlZW0hLm91dHB1dCk7XG4gICAgaWYgKCFleHBhbmRlZC5wcmV2T3V0VHlwZSkgcmV0dXJuIHt9O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHByZXZPdXRTY3JpcHQ6IG91dHB1dCxcbiAgICAgIHByZXZPdXRUeXBlOiBTQ1JJUFRfVFlQRVMuUDJTSCxcbiAgICAgIHJlZGVlbVNjcmlwdDogcmVkZWVtIS5vdXRwdXQsXG4gICAgICByZWRlZW1TY3JpcHRUeXBlOiBleHBhbmRlZC5wcmV2T3V0VHlwZSxcbiAgICAgIHdpdG5lc3NTY3JpcHQ6IGV4cGFuZGVkLndpdG5lc3NTY3JpcHQsXG4gICAgICB3aXRuZXNzU2NyaXB0VHlwZTogZXhwYW5kZWQud2l0bmVzc1NjcmlwdFR5cGUsXG5cbiAgICAgIHB1YmtleXM6IGV4cGFuZGVkLnB1YmtleXMsXG4gICAgICBzaWduYXR1cmVzOiBleHBhbmRlZC5zaWduYXR1cmVzLFxuICAgIH07XG4gIH1cblxuICBpZiAodHlwZSA9PT0gU0NSSVBUX1RZUEVTLlAyV1NIKSB7XG4gICAgY29uc3QgeyBvdXRwdXQsIHJlZGVlbSB9ID0gcGF5bWVudHMucDJ3c2goe1xuICAgICAgaW5wdXQ6IHNjcmlwdFNpZyxcbiAgICAgIHdpdG5lc3M6IHdpdG5lc3NTdGFjayxcbiAgICB9KTtcbiAgICBjb25zdCBvdXRwdXRUeXBlID0gY2xhc3NpZnkub3V0cHV0KHJlZGVlbSEub3V0cHV0ISk7XG4gICAgbGV0IGV4cGFuZGVkO1xuICAgIGlmIChvdXRwdXRUeXBlID09PSBTQ1JJUFRfVFlQRVMuUDJXUEtIKSB7XG4gICAgICBleHBhbmRlZCA9IGV4cGFuZElucHV0PFROdW1iZXI+KHJlZGVlbSEuaW5wdXQhLCByZWRlZW0hLndpdG5lc3MhLCBvdXRwdXRUeXBlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXhwYW5kZWQgPSBleHBhbmRJbnB1dDxUTnVtYmVyPihic2NyaXB0LmNvbXBpbGUocmVkZWVtIS53aXRuZXNzISksIFtdLCBvdXRwdXRUeXBlLCByZWRlZW0hLm91dHB1dCk7XG4gICAgfVxuICAgIGlmICghZXhwYW5kZWQucHJldk91dFR5cGUpIHJldHVybiB7fTtcblxuICAgIHJldHVybiB7XG4gICAgICBwcmV2T3V0U2NyaXB0OiBvdXRwdXQsXG4gICAgICBwcmV2T3V0VHlwZTogU0NSSVBUX1RZUEVTLlAyV1NILFxuICAgICAgd2l0bmVzc1NjcmlwdDogcmVkZWVtIS5vdXRwdXQsXG4gICAgICB3aXRuZXNzU2NyaXB0VHlwZTogZXhwYW5kZWQucHJldk91dFR5cGUsXG5cbiAgICAgIHB1YmtleXM6IGV4cGFuZGVkLnB1YmtleXMsXG4gICAgICBzaWduYXR1cmVzOiBleHBhbmRlZC5zaWduYXR1cmVzLFxuICAgIH07XG4gIH1cblxuICBpZiAodHlwZSA9PT0gU0NSSVBUX1RZUEVTLlAyVFIpIHtcbiAgICBjb25zdCBwYXJzZWRXaXRuZXNzID0gdGFwcm9vdC5wYXJzZVRhcHJvb3RXaXRuZXNzKHdpdG5lc3NTdGFjayk7XG4gICAgaWYgKHBhcnNlZFdpdG5lc3Muc3BlbmRUeXBlID09PSAnS2V5Jykge1xuICAgICAgLy8ga2V5IHBhdGggc3BlbmQsIG5vdGhpbmcgdG8gZXhwYW5kXG4gICAgICBjb25zdCB7IHNpZ25hdHVyZSwgYW5uZXggfSA9IHBhcnNlZFdpdG5lc3M7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwcmV2T3V0VHlwZTogU0NSSVBUX1RZUEVTLlAyVFIsXG4gICAgICAgIHNpZ25hdHVyZXM6IFtzaWduYXR1cmVdLFxuICAgICAgICBhbm5leCxcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHNjcmlwdCBwYXRoIHNwZW5kXG4gICAgICBjb25zdCB7IHRhcHNjcmlwdCwgY29udHJvbEJsb2NrLCBhbm5leCB9ID0gcGFyc2VkV2l0bmVzcztcbiAgICAgIGNvbnN0IHByZXZPdXRTY3JpcHQgPSBwMnRyUGF5bWVudHMucDJ0cihcbiAgICAgICAge1xuICAgICAgICAgIHJlZGVlbXM6IFt7IG91dHB1dDogdGFwc2NyaXB0IH1dLFxuICAgICAgICAgIHJlZGVlbUluZGV4OiAwLFxuICAgICAgICAgIGNvbnRyb2xCbG9jayxcbiAgICAgICAgICBhbm5leCxcbiAgICAgICAgfSxcbiAgICAgICAgeyBlY2NMaWIgfVxuICAgICAgKS5vdXRwdXQ7XG4gICAgICBjb25zdCB3aXRuZXNzU2NyaXB0VHlwZSA9IGNsYXNzaWZ5Lm91dHB1dCh0YXBzY3JpcHQpO1xuICAgICAgY29uc3QgeyBwdWJrZXlzLCBzaWduYXR1cmVzIH0gPSBleHBhbmRJbnB1dDxUTnVtYmVyPihcbiAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICBwYXJzZWRXaXRuZXNzLnNjcmlwdFNpZyxcbiAgICAgICAgd2l0bmVzc1NjcmlwdFR5cGUsXG4gICAgICAgIHRhcHNjcmlwdFxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcHJldk91dFNjcmlwdCxcbiAgICAgICAgcHJldk91dFR5cGU6IFNDUklQVF9UWVBFUy5QMlRSLFxuICAgICAgICB3aXRuZXNzU2NyaXB0OiB0YXBzY3JpcHQsXG4gICAgICAgIHdpdG5lc3NTY3JpcHRUeXBlLFxuXG4gICAgICAgIGNvbnRyb2xCbG9jayxcbiAgICAgICAgYW5uZXgsXG5cbiAgICAgICAgcHVia2V5cyxcbiAgICAgICAgc2lnbmF0dXJlcyxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBwcmV2T3V0VHlwZTogU0NSSVBUX1RZUEVTLk5PTlNUQU5EQVJELFxuICAgIHByZXZPdXRTY3JpcHQ6IHNjcmlwdFNpZyxcbiAgfTtcbn1cblxuLy8gY291bGQgYmUgZG9uZSBpbiBleHBhbmRJbnB1dCwgYnV0IHJlcXVpcmVzIHRoZSBvcmlnaW5hbCBUcmFuc2FjdGlvbiBmb3IgaGFzaEZvclNpZ25hdHVyZVxuZnVuY3Rpb24gZml4TXVsdGlzaWdPcmRlcjxUTnVtYmVyIGV4dGVuZHMgbnVtYmVyIHwgYmlnaW50ID0gbnVtYmVyPihcbiAgaW5wdXQ6IFR4YklucHV0PFROdW1iZXI+LFxuICB0cmFuc2FjdGlvbjogVHJhbnNhY3Rpb248VE51bWJlcj4sXG4gIHZpbjogbnVtYmVyLFxuICBwcmV2T3V0cHV0cz86IFR4T3V0cHV0PFROdW1iZXI+W11cbik6IHZvaWQge1xuICBpZiAoaW5wdXQucmVkZWVtU2NyaXB0VHlwZSAhPT0gU0NSSVBUX1RZUEVTLlAyTVMgfHwgIWlucHV0LnJlZGVlbVNjcmlwdCkgcmV0dXJuO1xuICBpZiAoaW5wdXQucHVia2V5cyEubGVuZ3RoID09PSBpbnB1dC5zaWduYXR1cmVzIS5sZW5ndGgpIHJldHVybjtcbiAgY29uc3QgcHJldk91dHB1dCA9IHByZXZPdXRwdXRzICYmIHByZXZPdXRwdXRzW3Zpbl07XG5cbiAgY29uc3QgdW5tYXRjaGVkID0gaW5wdXQuc2lnbmF0dXJlcyEuY29uY2F0KCk7XG5cbiAgaW5wdXQuc2lnbmF0dXJlcyA9IGlucHV0LnB1YmtleXMhLm1hcCgocHViS2V5KSA9PiB7XG4gICAgY29uc3Qga2V5UGFpciA9IEVDUGFpci5mcm9tUHVibGljS2V5KHB1YktleSEpO1xuICAgIGxldCBtYXRjaDogQnVmZmVyIHwgdW5kZWZpbmVkO1xuXG4gICAgLy8gY2hlY2sgZm9yIGEgc2lnbmF0dXJlXG4gICAgdW5tYXRjaGVkLnNvbWUoKHNpZ25hdHVyZSwgaSkgPT4ge1xuICAgICAgLy8gc2tpcCBpZiB1bmRlZmluZWQgfHwgT1BfMFxuICAgICAgaWYgKCFzaWduYXR1cmUpIHJldHVybiBmYWxzZTtcblxuICAgICAgLy8gVE9ETzogYXZvaWQgTyhuKSBoYXNoRm9yU2lnbmF0dXJlXG4gICAgICBjb25zdCBwYXJzZWQgPSBic2NyaXB0LnNpZ25hdHVyZS5kZWNvZGUoc2lnbmF0dXJlKTtcbiAgICAgIGNvbnN0IGhhc2ggPSB0cmFuc2FjdGlvbi5oYXNoRm9yU2lnbmF0dXJlKHZpbiwgaW5wdXQucmVkZWVtU2NyaXB0ISwgcGFyc2VkLmhhc2hUeXBlLCBwcmV2T3V0cHV0Py52YWx1ZSk7XG5cbiAgICAgIC8vIHNraXAgaWYgc2lnbmF0dXJlIGRvZXMgbm90IG1hdGNoIHB1YktleVxuICAgICAgaWYgKCFrZXlQYWlyLnZlcmlmeShoYXNoLCBwYXJzZWQuc2lnbmF0dXJlKSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAvLyByZW1vdmUgbWF0Y2hlZCBzaWduYXR1cmUgZnJvbSB1bm1hdGNoZWRcbiAgICAgIHVubWF0Y2hlZFtpXSA9IHVuZGVmaW5lZDtcbiAgICAgIG1hdGNoID0gc2lnbmF0dXJlO1xuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9KTtcblxuICAgIHJldHVybiBtYXRjaDtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGV4cGFuZE91dHB1dChzY3JpcHQ6IEJ1ZmZlciwgb3VyUHViS2V5PzogQnVmZmVyLCBjb250cm9sQmxvY2s/OiBCdWZmZXIpOiBUeGJPdXRwdXQge1xuICB0eXBlZm9yY2UodHlwZXMuQnVmZmVyLCBzY3JpcHQpO1xuICBjb25zdCB0eXBlID0gY2xhc3NpZnkub3V0cHV0KHNjcmlwdCk7XG5cbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSBTQ1JJUFRfVFlQRVMuUDJQS0g6IHtcbiAgICAgIGlmICghb3VyUHViS2V5KSByZXR1cm4geyB0eXBlIH07XG5cbiAgICAgIC8vIGRvZXMgb3VyIGhhc2gxNjAocHViS2V5KSBtYXRjaCB0aGUgb3V0cHV0IHNjcmlwdHM/XG4gICAgICBjb25zdCBwa2gxID0gcGF5bWVudHMucDJwa2goeyBvdXRwdXQ6IHNjcmlwdCB9KS5oYXNoO1xuICAgICAgY29uc3QgcGtoMiA9IGJjcnlwdG8uaGFzaDE2MChvdXJQdWJLZXkpO1xuICAgICAgaWYgKCFwa2gxIS5lcXVhbHMocGtoMikpIHJldHVybiB7IHR5cGUgfTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZSxcbiAgICAgICAgcHVia2V5czogW291clB1YktleV0sXG4gICAgICAgIHNpZ25hdHVyZXM6IFt1bmRlZmluZWRdLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjYXNlIFNDUklQVF9UWVBFUy5QMldQS0g6IHtcbiAgICAgIGlmICghb3VyUHViS2V5KSByZXR1cm4geyB0eXBlIH07XG5cbiAgICAgIC8vIGRvZXMgb3VyIGhhc2gxNjAocHViS2V5KSBtYXRjaCB0aGUgb3V0cHV0IHNjcmlwdHM/XG4gICAgICBjb25zdCB3cGtoMSA9IHBheW1lbnRzLnAyd3BraCh7IG91dHB1dDogc2NyaXB0IH0pLmhhc2g7XG4gICAgICBjb25zdCB3cGtoMiA9IGJjcnlwdG8uaGFzaDE2MChvdXJQdWJLZXkpO1xuICAgICAgaWYgKCF3cGtoMSEuZXF1YWxzKHdwa2gyKSkgcmV0dXJuIHsgdHlwZSB9O1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlLFxuICAgICAgICBwdWJrZXlzOiBbb3VyUHViS2V5XSxcbiAgICAgICAgc2lnbmF0dXJlczogW3VuZGVmaW5lZF0sXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNhc2UgU0NSSVBUX1RZUEVTLlAyVFI6IHtcbiAgICAgIGlmICghb3VyUHViS2V5KSByZXR1cm4geyB0eXBlIH07XG4gICAgICAvLyBIQUNLIG91clB1YktleSB0byBCSVAzNDAtc3R5bGVcbiAgICAgIGlmIChvdXJQdWJLZXkubGVuZ3RoID09PSAzMykgb3VyUHViS2V5ID0gb3VyUHViS2V5LnNsaWNlKDEpO1xuICAgICAgLy8gVE9ETzogc3VwcG9ydCBtdWx0aXBsZSBwdWJrZXlzXG4gICAgICBjb25zdCBwMnRyID0gcDJ0clBheW1lbnRzLnAydHIoeyBwdWJrZXk6IG91clB1YktleSwgY29udHJvbEJsb2NrIH0sIHsgZWNjTGliIH0pO1xuXG4gICAgICAvLyBEb2VzIHR3ZWFrZWQgb3V0cHV0IGZvciBhIHNpbmdsZSBwdWJrZXkgbWF0Y2g/XG4gICAgICBpZiAoIXNjcmlwdC5lcXVhbHMocDJ0ci5vdXRwdXQhKSkgcmV0dXJuIHsgdHlwZSB9O1xuXG4gICAgICAvLyBQMlRSIEtleVBhdGgsIHNpbmdsZSBrZXlcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGUsXG4gICAgICAgIHB1YmtleXM6IFtvdXJQdWJLZXldLFxuICAgICAgICBzaWduYXR1cmVzOiBbdW5kZWZpbmVkXSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY2FzZSBTQ1JJUFRfVFlQRVMuUDJUUl9OUzoge1xuICAgICAgY29uc3QgcDJ0ck5zID0gcDJ0clBheW1lbnRzLnAydHJfbnMoeyBvdXRwdXQ6IHNjcmlwdCB9LCB7IGVjY0xpYiB9KTtcbiAgICAgIC8vIFAyVFIgU2NyaXB0UGF0aFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZSxcbiAgICAgICAgcHVia2V5czogcDJ0ck5zLnB1YmtleXMsXG4gICAgICAgIHNpZ25hdHVyZXM6IHAydHJOcy5wdWJrZXlzIS5tYXAoKCk6IHVuZGVmaW5lZCA9PiB1bmRlZmluZWQpLFxuICAgICAgICBtYXhTaWduYXR1cmVzOiBwMnRyTnMucHVia2V5cyEubGVuZ3RoLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjYXNlIFNDUklQVF9UWVBFUy5QMlBLOiB7XG4gICAgICBjb25zdCBwMnBrID0gcGF5bWVudHMucDJwayh7IG91dHB1dDogc2NyaXB0IH0pO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZSxcbiAgICAgICAgcHVia2V5czogW3AycGsucHVia2V5XSxcbiAgICAgICAgc2lnbmF0dXJlczogW3VuZGVmaW5lZF0sXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNhc2UgU0NSSVBUX1RZUEVTLlAyTVM6IHtcbiAgICAgIGNvbnN0IHAybXMgPSBwYXltZW50cy5wMm1zKHsgb3V0cHV0OiBzY3JpcHQgfSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlLFxuICAgICAgICBwdWJrZXlzOiBwMm1zLnB1YmtleXMsXG4gICAgICAgIHNpZ25hdHVyZXM6IHAybXMucHVia2V5cyEubWFwKCgpOiB1bmRlZmluZWQgPT4gdW5kZWZpbmVkKSxcbiAgICAgICAgbWF4U2lnbmF0dXJlczogcDJtcy5tLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4geyB0eXBlIH07XG59XG5cbmZ1bmN0aW9uIHByZXBhcmVJbnB1dDxUTnVtYmVyIGV4dGVuZHMgbnVtYmVyIHwgYmlnaW50ID0gbnVtYmVyPihcbiAgaW5wdXQ6IFR4YklucHV0PFROdW1iZXI+LFxuICBvdXJQdWJLZXk6IEJ1ZmZlcixcbiAgcmVkZWVtU2NyaXB0PzogQnVmZmVyLFxuICB3aXRuZXNzU2NyaXB0PzogQnVmZmVyLFxuICBjb250cm9sQmxvY2s/OiBCdWZmZXIsXG4gIGFubmV4PzogQnVmZmVyXG4pOiBUeGJJbnB1dDxUTnVtYmVyPiB7XG4gIGlmIChyZWRlZW1TY3JpcHQgJiYgd2l0bmVzc1NjcmlwdCkge1xuICAgIGNvbnN0IHAyd3NoID0gcGF5bWVudHMucDJ3c2goe1xuICAgICAgcmVkZWVtOiB7IG91dHB1dDogd2l0bmVzc1NjcmlwdCB9LFxuICAgIH0pIGFzIFBheW1lbnQ7XG4gICAgY29uc3QgcDJ3c2hBbHQgPSBwYXltZW50cy5wMndzaCh7IG91dHB1dDogcmVkZWVtU2NyaXB0IH0pIGFzIFBheW1lbnQ7XG4gICAgY29uc3QgcDJzaCA9IHBheW1lbnRzLnAyc2goeyByZWRlZW06IHsgb3V0cHV0OiByZWRlZW1TY3JpcHQgfSB9KSBhcyBQYXltZW50O1xuICAgIGNvbnN0IHAyc2hBbHQgPSBwYXltZW50cy5wMnNoKHsgcmVkZWVtOiBwMndzaCB9KSBhcyBQYXltZW50O1xuXG4gICAgLy8gZW5mb3JjZXMgUDJTSChQMldTSCguLi4pKVxuICAgIGlmICghcDJ3c2guaGFzaCEuZXF1YWxzKHAyd3NoQWx0Lmhhc2ghKSkgdGhyb3cgbmV3IEVycm9yKCdXaXRuZXNzIHNjcmlwdCBpbmNvbnNpc3RlbnQgd2l0aCBwcmV2T3V0U2NyaXB0Jyk7XG4gICAgaWYgKCFwMnNoLmhhc2ghLmVxdWFscyhwMnNoQWx0Lmhhc2ghKSkgdGhyb3cgbmV3IEVycm9yKCdSZWRlZW0gc2NyaXB0IGluY29uc2lzdGVudCB3aXRoIHByZXZPdXRTY3JpcHQnKTtcblxuICAgIGNvbnN0IGV4cGFuZGVkID0gZXhwYW5kT3V0cHV0KHAyd3NoLnJlZGVlbSEub3V0cHV0ISwgb3VyUHViS2V5KTtcbiAgICBpZiAoIWV4cGFuZGVkLnB1YmtleXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihleHBhbmRlZC50eXBlICsgJyBub3Qgc3VwcG9ydGVkIGFzIHdpdG5lc3NTY3JpcHQgKCcgKyBic2NyaXB0LnRvQVNNKHdpdG5lc3NTY3JpcHQpICsgJyknKTtcbiAgICB9XG4gICAgaWYgKGlucHV0LnNpZ25hdHVyZXMgJiYgaW5wdXQuc2lnbmF0dXJlcy5zb21lKCh4KSA9PiB4ICE9PSB1bmRlZmluZWQpKSB7XG4gICAgICBleHBhbmRlZC5zaWduYXR1cmVzID0gaW5wdXQuc2lnbmF0dXJlcztcbiAgICB9XG5cbiAgICBjb25zdCBzaWduU2NyaXB0ID0gd2l0bmVzc1NjcmlwdDtcbiAgICBpZiAoZXhwYW5kZWQudHlwZSA9PT0gU0NSSVBUX1RZUEVTLlAyV1BLSCkgdGhyb3cgbmV3IEVycm9yKCdQMlNIKFAyV1NIKFAyV1BLSCkpIGlzIGEgY29uc2Vuc3VzIGZhaWx1cmUnKTtcblxuICAgIHJldHVybiB7XG4gICAgICByZWRlZW1TY3JpcHQsXG4gICAgICByZWRlZW1TY3JpcHRUeXBlOiBTQ1JJUFRfVFlQRVMuUDJXU0gsXG5cbiAgICAgIHdpdG5lc3NTY3JpcHQsXG4gICAgICB3aXRuZXNzU2NyaXB0VHlwZTogZXhwYW5kZWQudHlwZSxcblxuICAgICAgcHJldk91dFR5cGU6IFNDUklQVF9UWVBFUy5QMlNILFxuICAgICAgcHJldk91dFNjcmlwdDogcDJzaC5vdXRwdXQsXG5cbiAgICAgIHdpdG5lc3NWZXJzaW9uOiAwLFxuICAgICAgc2lnblNjcmlwdCxcbiAgICAgIHNpZ25UeXBlOiBleHBhbmRlZC50eXBlLFxuXG4gICAgICBwdWJrZXlzOiBleHBhbmRlZC5wdWJrZXlzLFxuICAgICAgc2lnbmF0dXJlczogZXhwYW5kZWQuc2lnbmF0dXJlcyxcbiAgICAgIG1heFNpZ25hdHVyZXM6IGV4cGFuZGVkLm1heFNpZ25hdHVyZXMsXG4gICAgfTtcbiAgfVxuXG4gIGlmIChyZWRlZW1TY3JpcHQpIHtcbiAgICBjb25zdCBwMnNoID0gcGF5bWVudHMucDJzaCh7IHJlZGVlbTogeyBvdXRwdXQ6IHJlZGVlbVNjcmlwdCB9IH0pIGFzIFBheW1lbnQ7XG5cbiAgICBpZiAoaW5wdXQucHJldk91dFNjcmlwdCkge1xuICAgICAgbGV0IHAyc2hBbHQ7XG4gICAgICB0cnkge1xuICAgICAgICBwMnNoQWx0ID0gcGF5bWVudHMucDJzaCh7IG91dHB1dDogaW5wdXQucHJldk91dFNjcmlwdCB9KSBhcyBQYXltZW50O1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1ByZXZPdXRTY3JpcHQgbXVzdCBiZSBQMlNIJyk7XG4gICAgICB9XG4gICAgICBpZiAoIXAyc2guaGFzaCEuZXF1YWxzKHAyc2hBbHQuaGFzaCEpKSB0aHJvdyBuZXcgRXJyb3IoJ1JlZGVlbSBzY3JpcHQgaW5jb25zaXN0ZW50IHdpdGggcHJldk91dFNjcmlwdCcpO1xuICAgIH1cblxuICAgIGNvbnN0IGV4cGFuZGVkID0gZXhwYW5kT3V0cHV0KHAyc2gucmVkZWVtIS5vdXRwdXQhLCBvdXJQdWJLZXkpO1xuICAgIGlmICghZXhwYW5kZWQucHVia2V5cykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGV4cGFuZGVkLnR5cGUgKyAnIG5vdCBzdXBwb3J0ZWQgYXMgcmVkZWVtU2NyaXB0ICgnICsgYnNjcmlwdC50b0FTTShyZWRlZW1TY3JpcHQpICsgJyknKTtcbiAgICB9XG4gICAgaWYgKGlucHV0LnNpZ25hdHVyZXMgJiYgaW5wdXQuc2lnbmF0dXJlcy5zb21lKCh4KSA9PiB4ICE9PSB1bmRlZmluZWQpKSB7XG4gICAgICBleHBhbmRlZC5zaWduYXR1cmVzID0gaW5wdXQuc2lnbmF0dXJlcztcbiAgICB9XG5cbiAgICBsZXQgc2lnblNjcmlwdCA9IHJlZGVlbVNjcmlwdDtcbiAgICBpZiAoZXhwYW5kZWQudHlwZSA9PT0gU0NSSVBUX1RZUEVTLlAyV1BLSCkge1xuICAgICAgc2lnblNjcmlwdCA9IHBheW1lbnRzLnAycGtoKHsgcHVia2V5OiBleHBhbmRlZC5wdWJrZXlzWzBdIH0pLm91dHB1dCE7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHJlZGVlbVNjcmlwdCxcbiAgICAgIHJlZGVlbVNjcmlwdFR5cGU6IGV4cGFuZGVkLnR5cGUsXG5cbiAgICAgIHByZXZPdXRUeXBlOiBTQ1JJUFRfVFlQRVMuUDJTSCxcbiAgICAgIHByZXZPdXRTY3JpcHQ6IHAyc2gub3V0cHV0LFxuXG4gICAgICB3aXRuZXNzVmVyc2lvbjogZXhwYW5kZWQudHlwZSA9PT0gU0NSSVBUX1RZUEVTLlAyV1BLSCA/IDAgOiB1bmRlZmluZWQsXG4gICAgICBzaWduU2NyaXB0LFxuICAgICAgc2lnblR5cGU6IGV4cGFuZGVkLnR5cGUsXG5cbiAgICAgIHB1YmtleXM6IGV4cGFuZGVkLnB1YmtleXMsXG4gICAgICBzaWduYXR1cmVzOiBleHBhbmRlZC5zaWduYXR1cmVzLFxuICAgICAgbWF4U2lnbmF0dXJlczogZXhwYW5kZWQubWF4U2lnbmF0dXJlcyxcbiAgICB9O1xuICB9XG5cbiAgaWYgKHdpdG5lc3NTY3JpcHQgJiYgY29udHJvbEJsb2NrKSB7XG4gICAgLy8gUDJUUiBTY3JpcHRQYXRoXG4gICAgLyogdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXNoYWRvd2VkLXZhcmlhYmxlICovXG4gICAgbGV0IHByZXZPdXRTY3JpcHQgPSBpbnB1dC5wcmV2T3V0U2NyaXB0O1xuICAgIGlmICghcHJldk91dFNjcmlwdCkge1xuICAgICAgcHJldk91dFNjcmlwdCA9IHAydHJQYXltZW50cy5wMnRyKFxuICAgICAgICB7XG4gICAgICAgICAgcmVkZWVtczogW3sgb3V0cHV0OiB3aXRuZXNzU2NyaXB0IH1dLFxuICAgICAgICAgIHJlZGVlbUluZGV4OiAwLFxuICAgICAgICAgIGNvbnRyb2xCbG9jayxcbiAgICAgICAgICBhbm5leCxcbiAgICAgICAgfSxcbiAgICAgICAgeyBlY2NMaWIgfVxuICAgICAgKS5vdXRwdXQ7XG4gICAgfVxuXG4gICAgY29uc3QgZXhwYW5kZWQgPSBleHBhbmRPdXRwdXQod2l0bmVzc1NjcmlwdCwgb3VyUHViS2V5KTtcbiAgICBpZiAoIWV4cGFuZGVkLnB1YmtleXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihleHBhbmRlZC50eXBlICsgJyBub3Qgc3VwcG9ydGVkIGFzIHdpdG5lc3NTY3JpcHQgKCcgKyBic2NyaXB0LnRvQVNNKHdpdG5lc3NTY3JpcHQpICsgJyknKTtcbiAgICB9XG4gICAgaWYgKGlucHV0LnNpZ25hdHVyZXMgJiYgaW5wdXQuc2lnbmF0dXJlcy5zb21lKCh4KSA9PiB4ICE9PSB1bmRlZmluZWQpKSB7XG4gICAgICBleHBhbmRlZC5zaWduYXR1cmVzID0gaW5wdXQuc2lnbmF0dXJlcztcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgd2l0bmVzc1NjcmlwdCxcbiAgICAgIHdpdG5lc3NTY3JpcHRUeXBlOiBleHBhbmRlZC50eXBlLFxuXG4gICAgICBwcmV2T3V0VHlwZTogU0NSSVBUX1RZUEVTLlAyVFIsXG4gICAgICBwcmV2T3V0U2NyaXB0LFxuXG4gICAgICB3aXRuZXNzVmVyc2lvbjogMSxcbiAgICAgIHNpZ25TY3JpcHQ6IHdpdG5lc3NTY3JpcHQsXG4gICAgICBzaWduVHlwZTogZXhwYW5kZWQudHlwZSxcblxuICAgICAgcHVia2V5czogZXhwYW5kZWQucHVia2V5cyxcbiAgICAgIHNpZ25hdHVyZXM6IGV4cGFuZGVkLnNpZ25hdHVyZXMsXG4gICAgICBtYXhTaWduYXR1cmVzOiBleHBhbmRlZC5tYXhTaWduYXR1cmVzLFxuXG4gICAgICBjb250cm9sQmxvY2ssXG4gICAgICBhbm5leCxcbiAgICB9O1xuICB9XG5cbiAgaWYgKHdpdG5lc3NTY3JpcHQpIHtcbiAgICBjb25zdCBwMndzaCA9IHBheW1lbnRzLnAyd3NoKHsgcmVkZWVtOiB7IG91dHB1dDogd2l0bmVzc1NjcmlwdCB9IH0pO1xuXG4gICAgaWYgKGlucHV0LnByZXZPdXRTY3JpcHQpIHtcbiAgICAgIGNvbnN0IHAyd3NoQWx0ID0gcGF5bWVudHMucDJ3c2goeyBvdXRwdXQ6IGlucHV0LnByZXZPdXRTY3JpcHQgfSk7XG4gICAgICBpZiAoIXAyd3NoLmhhc2ghLmVxdWFscyhwMndzaEFsdC5oYXNoISkpIHRocm93IG5ldyBFcnJvcignV2l0bmVzcyBzY3JpcHQgaW5jb25zaXN0ZW50IHdpdGggcHJldk91dFNjcmlwdCcpO1xuICAgIH1cblxuICAgIGNvbnN0IGV4cGFuZGVkID0gZXhwYW5kT3V0cHV0KHAyd3NoLnJlZGVlbSEub3V0cHV0ISwgb3VyUHViS2V5KTtcbiAgICBpZiAoIWV4cGFuZGVkLnB1YmtleXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihleHBhbmRlZC50eXBlICsgJyBub3Qgc3VwcG9ydGVkIGFzIHdpdG5lc3NTY3JpcHQgKCcgKyBic2NyaXB0LnRvQVNNKHdpdG5lc3NTY3JpcHQpICsgJyknKTtcbiAgICB9XG4gICAgaWYgKGlucHV0LnNpZ25hdHVyZXMgJiYgaW5wdXQuc2lnbmF0dXJlcy5zb21lKCh4KSA9PiB4ICE9PSB1bmRlZmluZWQpKSB7XG4gICAgICBleHBhbmRlZC5zaWduYXR1cmVzID0gaW5wdXQuc2lnbmF0dXJlcztcbiAgICB9XG5cbiAgICBjb25zdCBzaWduU2NyaXB0ID0gd2l0bmVzc1NjcmlwdDtcbiAgICBpZiAoZXhwYW5kZWQudHlwZSA9PT0gU0NSSVBUX1RZUEVTLlAyV1BLSCkgdGhyb3cgbmV3IEVycm9yKCdQMldTSChQMldQS0gpIGlzIGEgY29uc2Vuc3VzIGZhaWx1cmUnKTtcblxuICAgIHJldHVybiB7XG4gICAgICB3aXRuZXNzU2NyaXB0LFxuICAgICAgd2l0bmVzc1NjcmlwdFR5cGU6IGV4cGFuZGVkLnR5cGUsXG5cbiAgICAgIHByZXZPdXRUeXBlOiBTQ1JJUFRfVFlQRVMuUDJXU0gsXG4gICAgICBwcmV2T3V0U2NyaXB0OiBwMndzaC5vdXRwdXQsXG5cbiAgICAgIHdpdG5lc3NWZXJzaW9uOiAwLFxuICAgICAgc2lnblNjcmlwdCxcbiAgICAgIHNpZ25UeXBlOiBleHBhbmRlZC50eXBlLFxuXG4gICAgICBwdWJrZXlzOiBleHBhbmRlZC5wdWJrZXlzLFxuICAgICAgc2lnbmF0dXJlczogZXhwYW5kZWQuc2lnbmF0dXJlcyxcbiAgICAgIG1heFNpZ25hdHVyZXM6IGV4cGFuZGVkLm1heFNpZ25hdHVyZXMsXG4gICAgfTtcbiAgfVxuXG4gIGlmIChpbnB1dC5wcmV2T3V0VHlwZSAmJiBpbnB1dC5wcmV2T3V0U2NyaXB0KSB7XG4gICAgLy8gZW1iZWRkZWQgc2NyaXB0cyBhcmUgbm90IHBvc3NpYmxlIHdpdGhvdXQgZXh0cmEgaW5mb3JtYXRpb25cbiAgICBpZiAoaW5wdXQucHJldk91dFR5cGUgPT09IFNDUklQVF9UWVBFUy5QMlNIKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1ByZXZPdXRTY3JpcHQgaXMgJyArIGlucHV0LnByZXZPdXRUeXBlICsgJywgcmVxdWlyZXMgcmVkZWVtU2NyaXB0Jyk7XG4gICAgfVxuICAgIGlmIChpbnB1dC5wcmV2T3V0VHlwZSA9PT0gU0NSSVBUX1RZUEVTLlAyV1NIKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1ByZXZPdXRTY3JpcHQgaXMgJyArIGlucHV0LnByZXZPdXRUeXBlICsgJywgcmVxdWlyZXMgd2l0bmVzc1NjcmlwdCcpO1xuICAgIH1cblxuICAgIGNvbnN0IGV4cGFuZGVkID0gZXhwYW5kT3V0cHV0KGlucHV0LnByZXZPdXRTY3JpcHQsIG91clB1YktleSk7XG4gICAgaWYgKCFleHBhbmRlZC5wdWJrZXlzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoZXhwYW5kZWQudHlwZSArICcgbm90IHN1cHBvcnRlZCAoJyArIGJzY3JpcHQudG9BU00oaW5wdXQucHJldk91dFNjcmlwdCkgKyAnKScpO1xuICAgIH1cbiAgICBpZiAoaW5wdXQuc2lnbmF0dXJlcyAmJiBpbnB1dC5zaWduYXR1cmVzLnNvbWUoKHgpID0+IHggIT09IHVuZGVmaW5lZCkpIHtcbiAgICAgIGV4cGFuZGVkLnNpZ25hdHVyZXMgPSBpbnB1dC5zaWduYXR1cmVzO1xuICAgIH1cblxuICAgIGxldCBzaWduU2NyaXB0ID0gaW5wdXQucHJldk91dFNjcmlwdDtcbiAgICBpZiAoZXhwYW5kZWQudHlwZSA9PT0gU0NSSVBUX1RZUEVTLlAyV1BLSCkge1xuICAgICAgc2lnblNjcmlwdCA9IHBheW1lbnRzLnAycGtoKHsgcHVia2V5OiBleHBhbmRlZC5wdWJrZXlzWzBdIH0pLm91dHB1dCBhcyBCdWZmZXI7XG4gICAgfVxuXG4gICAgbGV0IHdpdG5lc3NWZXJzaW9uO1xuICAgIGlmIChleHBhbmRlZC50eXBlID09PSBTQ1JJUFRfVFlQRVMuUDJXUEtIKSB7XG4gICAgICB3aXRuZXNzVmVyc2lvbiA9IDA7XG4gICAgfSBlbHNlIGlmIChleHBhbmRlZC50eXBlID09PSBTQ1JJUFRfVFlQRVMuUDJUUikge1xuICAgICAgd2l0bmVzc1ZlcnNpb24gPSAxO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBwcmV2T3V0VHlwZTogZXhwYW5kZWQudHlwZSxcbiAgICAgIHByZXZPdXRTY3JpcHQ6IGlucHV0LnByZXZPdXRTY3JpcHQsXG5cbiAgICAgIHdpdG5lc3NWZXJzaW9uLFxuICAgICAgc2lnblNjcmlwdCxcbiAgICAgIHNpZ25UeXBlOiBleHBhbmRlZC50eXBlLFxuXG4gICAgICBwdWJrZXlzOiBleHBhbmRlZC5wdWJrZXlzLFxuICAgICAgc2lnbmF0dXJlczogZXhwYW5kZWQuc2lnbmF0dXJlcyxcbiAgICAgIG1heFNpZ25hdHVyZXM6IGV4cGFuZGVkLm1heFNpZ25hdHVyZXMsXG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0IHByZXZPdXRTY3JpcHQgPSBwYXltZW50cy5wMnBraCh7IHB1YmtleTogb3VyUHViS2V5IH0pLm91dHB1dDtcbiAgcmV0dXJuIHtcbiAgICBwcmV2T3V0VHlwZTogU0NSSVBUX1RZUEVTLlAyUEtILFxuICAgIHByZXZPdXRTY3JpcHQsXG5cbiAgICBzaWduU2NyaXB0OiBwcmV2T3V0U2NyaXB0LFxuICAgIHNpZ25UeXBlOiBTQ1JJUFRfVFlQRVMuUDJQS0gsXG5cbiAgICBwdWJrZXlzOiBbb3VyUHViS2V5XSxcbiAgICBzaWduYXR1cmVzOiBbdW5kZWZpbmVkXSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gYnVpbGQ8VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludCA9IG51bWJlcj4oXG4gIHR5cGU6IHN0cmluZyxcbiAgaW5wdXQ6IFR4YklucHV0PFROdW1iZXI+LFxuICBhbGxvd0luY29tcGxldGU/OiBib29sZWFuXG4pOiBQYXltZW50IHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgcHVia2V5cyA9IChpbnB1dC5wdWJrZXlzIHx8IFtdKSBhcyBCdWZmZXJbXTtcbiAgbGV0IHNpZ25hdHVyZXMgPSAoaW5wdXQuc2lnbmF0dXJlcyB8fCBbXSkgYXMgQnVmZmVyW107XG5cbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSBTQ1JJUFRfVFlQRVMuUDJQS0g6IHtcbiAgICAgIGlmIChwdWJrZXlzLmxlbmd0aCA9PT0gMCkgYnJlYWs7XG4gICAgICBpZiAoc2lnbmF0dXJlcy5sZW5ndGggPT09IDApIGJyZWFrO1xuXG4gICAgICByZXR1cm4gcGF5bWVudHMucDJwa2goeyBwdWJrZXk6IHB1YmtleXNbMF0sIHNpZ25hdHVyZTogc2lnbmF0dXJlc1swXSB9KTtcbiAgICB9XG4gICAgY2FzZSBTQ1JJUFRfVFlQRVMuUDJXUEtIOiB7XG4gICAgICBpZiAocHVia2V5cy5sZW5ndGggPT09IDApIGJyZWFrO1xuICAgICAgaWYgKHNpZ25hdHVyZXMubGVuZ3RoID09PSAwKSBicmVhaztcblxuICAgICAgcmV0dXJuIHBheW1lbnRzLnAyd3BraCh7IHB1YmtleTogcHVia2V5c1swXSwgc2lnbmF0dXJlOiBzaWduYXR1cmVzWzBdIH0pO1xuICAgIH1cbiAgICBjYXNlIFNDUklQVF9UWVBFUy5QMlBLOiB7XG4gICAgICBpZiAocHVia2V5cy5sZW5ndGggPT09IDApIGJyZWFrO1xuICAgICAgaWYgKHNpZ25hdHVyZXMubGVuZ3RoID09PSAwKSBicmVhaztcblxuICAgICAgcmV0dXJuIHBheW1lbnRzLnAycGsoeyBzaWduYXR1cmU6IHNpZ25hdHVyZXNbMF0gfSk7XG4gICAgfVxuICAgIGNhc2UgU0NSSVBUX1RZUEVTLlAyTVM6IHtcbiAgICAgIGNvbnN0IG0gPSBpbnB1dC5tYXhTaWduYXR1cmVzO1xuICAgICAgaWYgKGFsbG93SW5jb21wbGV0ZSkge1xuICAgICAgICBzaWduYXR1cmVzID0gc2lnbmF0dXJlcy5tYXAoKHgpID0+IHggfHwgb3BzLk9QXzApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2lnbmF0dXJlcyA9IHNpZ25hdHVyZXMuZmlsdGVyKCh4KSA9PiB4KTtcbiAgICAgIH1cblxuICAgICAgLy8gaWYgdGhlIHRyYW5zYWN0aW9uIGlzIG5vdCBub3QgY29tcGxldGUgKGNvbXBsZXRlKSwgb3IgaWYgc2lnbmF0dXJlcy5sZW5ndGggPT09IG0sIHZhbGlkYXRlXG4gICAgICAvLyBvdGhlcndpc2UsIHRoZSBudW1iZXIgb2YgT1BfMCdzIG1heSBiZSA+PSBtLCBzbyBkb24ndCB2YWxpZGF0ZSAoYm9vKVxuICAgICAgY29uc3QgdmFsaWRhdGUgPSAhYWxsb3dJbmNvbXBsZXRlIHx8IG0gPT09IHNpZ25hdHVyZXMubGVuZ3RoO1xuICAgICAgcmV0dXJuIHBheW1lbnRzLnAybXMoeyBtLCBwdWJrZXlzLCBzaWduYXR1cmVzIH0sIHsgYWxsb3dJbmNvbXBsZXRlLCB2YWxpZGF0ZSB9KTtcbiAgICB9XG4gICAgY2FzZSBTQ1JJUFRfVFlQRVMuUDJTSDoge1xuICAgICAgY29uc3QgcmVkZWVtID0gYnVpbGQ8VE51bWJlcj4oaW5wdXQucmVkZWVtU2NyaXB0VHlwZSEsIGlucHV0LCBhbGxvd0luY29tcGxldGUpO1xuICAgICAgaWYgKCFyZWRlZW0pIHJldHVybjtcblxuICAgICAgcmV0dXJuIHBheW1lbnRzLnAyc2goe1xuICAgICAgICByZWRlZW06IHtcbiAgICAgICAgICBvdXRwdXQ6IHJlZGVlbS5vdXRwdXQgfHwgaW5wdXQucmVkZWVtU2NyaXB0LFxuICAgICAgICAgIGlucHV0OiByZWRlZW0uaW5wdXQsXG4gICAgICAgICAgd2l0bmVzczogcmVkZWVtLndpdG5lc3MsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG4gICAgY2FzZSBTQ1JJUFRfVFlQRVMuUDJXU0g6IHtcbiAgICAgIGNvbnN0IHJlZGVlbSA9IGJ1aWxkPFROdW1iZXI+KGlucHV0LndpdG5lc3NTY3JpcHRUeXBlISwgaW5wdXQsIGFsbG93SW5jb21wbGV0ZSk7XG4gICAgICBpZiAoIXJlZGVlbSkgcmV0dXJuO1xuXG4gICAgICByZXR1cm4gcGF5bWVudHMucDJ3c2goe1xuICAgICAgICByZWRlZW06IHtcbiAgICAgICAgICBvdXRwdXQ6IGlucHV0LndpdG5lc3NTY3JpcHQsXG4gICAgICAgICAgaW5wdXQ6IHJlZGVlbS5pbnB1dCxcbiAgICAgICAgICB3aXRuZXNzOiByZWRlZW0ud2l0bmVzcyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBjYXNlIFNDUklQVF9UWVBFUy5QMlRSOiB7XG4gICAgICBpZiAoaW5wdXQud2l0bmVzc1NjcmlwdFR5cGUgPT09IFNDUklQVF9UWVBFUy5QMlRSX05TKSB7XG4gICAgICAgIC8vIFNjcmlwdFBhdGhcbiAgICAgICAgY29uc3QgcmVkZWVtID0gYnVpbGQ8VE51bWJlcj4oaW5wdXQud2l0bmVzc1NjcmlwdFR5cGUhLCBpbnB1dCwgYWxsb3dJbmNvbXBsZXRlKTtcbiAgICAgICAgcmV0dXJuIHAydHJQYXltZW50cy5wMnRyKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIG91dHB1dDogaW5wdXQucHJldk91dFNjcmlwdCxcbiAgICAgICAgICAgIGNvbnRyb2xCbG9jazogaW5wdXQuY29udHJvbEJsb2NrLFxuICAgICAgICAgICAgYW5uZXg6IGlucHV0LmFubmV4LFxuICAgICAgICAgICAgcmVkZWVtczogW3JlZGVlbSFdLFxuICAgICAgICAgICAgcmVkZWVtSW5kZXg6IDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7IGVjY0xpYiB9XG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIEtleVBhdGhcbiAgICAgIGlmIChzaWduYXR1cmVzLmxlbmd0aCA9PT0gMCkgYnJlYWs7XG5cbiAgICAgIHJldHVybiBwMnRyUGF5bWVudHMucDJ0cih7IHB1YmtleXMsIHNpZ25hdHVyZTogc2lnbmF0dXJlc1swXSB9LCB7IGVjY0xpYiB9KTtcbiAgICB9XG4gICAgY2FzZSBTQ1JJUFRfVFlQRVMuUDJUUl9OUzoge1xuICAgICAgY29uc3QgbSA9IGlucHV0Lm1heFNpZ25hdHVyZXM7XG4gICAgICBpZiAoYWxsb3dJbmNvbXBsZXRlKSB7XG4gICAgICAgIHNpZ25hdHVyZXMgPSBzaWduYXR1cmVzLm1hcCgoeCkgPT4geCB8fCBvcHMuT1BfMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzaWduYXR1cmVzID0gc2lnbmF0dXJlcy5maWx0ZXIoKHgpID0+IHgpO1xuICAgICAgfVxuXG4gICAgICAvLyBpZiB0aGUgdHJhbnNhY3Rpb24gaXMgbm90IG5vdCBjb21wbGV0ZSAoY29tcGxldGUpLCBvciBpZiBzaWduYXR1cmVzLmxlbmd0aCA9PT0gbSwgdmFsaWRhdGVcbiAgICAgIC8vIG90aGVyd2lzZSwgdGhlIG51bWJlciBvZiBPUF8wJ3MgbWF5IGJlID49IG0sIHNvIGRvbid0IHZhbGlkYXRlIChib28pXG4gICAgICBjb25zdCB2YWxpZGF0ZSA9ICFhbGxvd0luY29tcGxldGUgfHwgbSA9PT0gc2lnbmF0dXJlcy5sZW5ndGg7XG4gICAgICByZXR1cm4gcDJ0clBheW1lbnRzLnAydHJfbnMoeyBwdWJrZXlzLCBzaWduYXR1cmVzIH0sIHsgYWxsb3dJbmNvbXBsZXRlLCB2YWxpZGF0ZSwgZWNjTGliIH0pO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjYW5TaWduPFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQgPSBudW1iZXI+KGlucHV0OiBUeGJJbnB1dDxUTnVtYmVyPik6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIGlucHV0LnNpZ25TY3JpcHQgIT09IHVuZGVmaW5lZCAmJlxuICAgIGlucHV0LnNpZ25UeXBlICE9PSB1bmRlZmluZWQgJiZcbiAgICBpbnB1dC5wdWJrZXlzICE9PSB1bmRlZmluZWQgJiZcbiAgICBpbnB1dC5zaWduYXR1cmVzICE9PSB1bmRlZmluZWQgJiZcbiAgICBpbnB1dC5zaWduYXR1cmVzLmxlbmd0aCA9PT0gaW5wdXQucHVia2V5cy5sZW5ndGggJiZcbiAgICBpbnB1dC5wdWJrZXlzLmxlbmd0aCA+IDAgJiZcbiAgICAoaW5wdXQud2l0bmVzc1ZlcnNpb24gPT09IHVuZGVmaW5lZCB8fCBpbnB1dC52YWx1ZSAhPT0gdW5kZWZpbmVkKVxuICApO1xufVxuXG5mdW5jdGlvbiBzaWduYXR1cmVIYXNoVHlwZShidWZmZXI6IEJ1ZmZlcik6IG51bWJlciB7XG4gIGlmIChic2NyaXB0LmlzQ2Fub25pY2FsU2Nobm9yclNpZ25hdHVyZShidWZmZXIpICYmIGJ1ZmZlci5sZW5ndGggPT09IDY0KSB7XG4gICAgcmV0dXJuIFRyYW5zYWN0aW9uLlNJR0hBU0hfREVGQVVMVDtcbiAgfVxuICByZXR1cm4gYnVmZmVyLnJlYWRVSW50OChidWZmZXIubGVuZ3RoIC0gMSk7XG59XG5cbmZ1bmN0aW9uIGNoZWNrU2lnbkFyZ3M8VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludCA9IG51bWJlcj4oXG4gIGlucHV0czogQXJyYXk8VHhiSW5wdXQ8VE51bWJlcj4+LFxuICBzaWduUGFyYW1zOiBUeGJTaWduQXJnPFROdW1iZXI+XG4pOiB2b2lkIHtcbiAgaWYgKCFQUkVWT1VUX1RZUEVTLmhhcyhzaWduUGFyYW1zLnByZXZPdXRTY3JpcHRUeXBlKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYFVua25vd24gcHJldk91dFNjcmlwdFR5cGUgXCIke3NpZ25QYXJhbXMucHJldk91dFNjcmlwdFR5cGV9XCJgKTtcbiAgfVxuICB0Zk1lc3NhZ2UodHlwZWZvcmNlLk51bWJlciwgc2lnblBhcmFtcy52aW4sIGBzaWduIG11c3QgaW5jbHVkZSB2aW4gcGFyYW1ldGVyIGFzIE51bWJlciAoaW5wdXQgaW5kZXgpYCk7XG4gIHRmTWVzc2FnZSh0ZkZ1bGxTaWduZXIsIHNpZ25QYXJhbXMua2V5UGFpciwgYHNpZ24gbXVzdCBpbmNsdWRlIGtleVBhaXIgcGFyYW1ldGVyIGFzIFNpZ25lciBpbnRlcmZhY2VgKTtcbiAgdGZNZXNzYWdlKHR5cGVmb3JjZS5tYXliZSh0eXBlZm9yY2UuTnVtYmVyKSwgc2lnblBhcmFtcy5oYXNoVHlwZSwgYHNpZ24gaGFzaFR5cGUgcGFyYW1ldGVyIG11c3QgYmUgYSBudW1iZXJgKTtcbiAgY29uc3QgcHJldk91dFR5cGUgPSAoaW5wdXRzW3NpZ25QYXJhbXMudmluXSB8fCBbXSkucHJldk91dFR5cGU7XG4gIGNvbnN0IHBvc1R5cGUgPSBzaWduUGFyYW1zLnByZXZPdXRTY3JpcHRUeXBlO1xuICBzd2l0Y2ggKHBvc1R5cGUpIHtcbiAgICBjYXNlICdwMnBraCc6XG4gICAgICBpZiAocHJldk91dFR5cGUgJiYgcHJldk91dFR5cGUgIT09ICdwdWJrZXloYXNoJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBpbnB1dCAjJHtzaWduUGFyYW1zLnZpbn0gaXMgbm90IG9mIHR5cGUgcDJwa2g6ICR7cHJldk91dFR5cGV9YCk7XG4gICAgICB9XG4gICAgICB0Zk1lc3NhZ2UodHlwZWZvcmNlLnZhbHVlKHVuZGVmaW5lZCksIHNpZ25QYXJhbXMud2l0bmVzc1NjcmlwdCwgYCR7cG9zVHlwZX0gcmVxdWlyZXMgTk8gd2l0bmVzc1NjcmlwdGApO1xuICAgICAgdGZNZXNzYWdlKHR5cGVmb3JjZS52YWx1ZSh1bmRlZmluZWQpLCBzaWduUGFyYW1zLnJlZGVlbVNjcmlwdCwgYCR7cG9zVHlwZX0gcmVxdWlyZXMgTk8gcmVkZWVtU2NyaXB0YCk7XG4gICAgICB0Zk1lc3NhZ2UodHlwZWZvcmNlLnZhbHVlKHVuZGVmaW5lZCksIHNpZ25QYXJhbXMud2l0bmVzc1ZhbHVlLCBgJHtwb3NUeXBlfSByZXF1aXJlcyBOTyB3aXRuZXNzVmFsdWVgKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3AycGsnOlxuICAgICAgaWYgKHByZXZPdXRUeXBlICYmIHByZXZPdXRUeXBlICE9PSAncHVia2V5Jykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBpbnB1dCAjJHtzaWduUGFyYW1zLnZpbn0gaXMgbm90IG9mIHR5cGUgcDJwazogJHtwcmV2T3V0VHlwZX1gKTtcbiAgICAgIH1cbiAgICAgIHRmTWVzc2FnZSh0eXBlZm9yY2UudmFsdWUodW5kZWZpbmVkKSwgc2lnblBhcmFtcy53aXRuZXNzU2NyaXB0LCBgJHtwb3NUeXBlfSByZXF1aXJlcyBOTyB3aXRuZXNzU2NyaXB0YCk7XG4gICAgICB0Zk1lc3NhZ2UodHlwZWZvcmNlLnZhbHVlKHVuZGVmaW5lZCksIHNpZ25QYXJhbXMucmVkZWVtU2NyaXB0LCBgJHtwb3NUeXBlfSByZXF1aXJlcyBOTyByZWRlZW1TY3JpcHRgKTtcbiAgICAgIHRmTWVzc2FnZSh0eXBlZm9yY2UudmFsdWUodW5kZWZpbmVkKSwgc2lnblBhcmFtcy53aXRuZXNzVmFsdWUsIGAke3Bvc1R5cGV9IHJlcXVpcmVzIE5PIHdpdG5lc3NWYWx1ZWApO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAncDJ3cGtoJzpcbiAgICAgIGlmIChwcmV2T3V0VHlwZSAmJiBwcmV2T3V0VHlwZSAhPT0gJ3dpdG5lc3NwdWJrZXloYXNoJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBpbnB1dCAjJHtzaWduUGFyYW1zLnZpbn0gaXMgbm90IG9mIHR5cGUgcDJ3cGtoOiAke3ByZXZPdXRUeXBlfWApO1xuICAgICAgfVxuICAgICAgdGZNZXNzYWdlKHR5cGVmb3JjZS52YWx1ZSh1bmRlZmluZWQpLCBzaWduUGFyYW1zLndpdG5lc3NTY3JpcHQsIGAke3Bvc1R5cGV9IHJlcXVpcmVzIE5PIHdpdG5lc3NTY3JpcHRgKTtcbiAgICAgIHRmTWVzc2FnZSh0eXBlZm9yY2UudmFsdWUodW5kZWZpbmVkKSwgc2lnblBhcmFtcy5yZWRlZW1TY3JpcHQsIGAke3Bvc1R5cGV9IHJlcXVpcmVzIE5PIHJlZGVlbVNjcmlwdGApO1xuICAgICAgdGZNZXNzYWdlKHR5cGVzLlNhdG9zaGksIHNpZ25QYXJhbXMud2l0bmVzc1ZhbHVlLCBgJHtwb3NUeXBlfSByZXF1aXJlcyB3aXRuZXNzVmFsdWVgKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3AybXMnOlxuICAgICAgaWYgKHByZXZPdXRUeXBlICYmIHByZXZPdXRUeXBlICE9PSAnbXVsdGlzaWcnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYGlucHV0ICMke3NpZ25QYXJhbXMudmlufSBpcyBub3Qgb2YgdHlwZSBwMm1zOiAke3ByZXZPdXRUeXBlfWApO1xuICAgICAgfVxuICAgICAgdGZNZXNzYWdlKHR5cGVmb3JjZS52YWx1ZSh1bmRlZmluZWQpLCBzaWduUGFyYW1zLndpdG5lc3NTY3JpcHQsIGAke3Bvc1R5cGV9IHJlcXVpcmVzIE5PIHdpdG5lc3NTY3JpcHRgKTtcbiAgICAgIHRmTWVzc2FnZSh0eXBlZm9yY2UudmFsdWUodW5kZWZpbmVkKSwgc2lnblBhcmFtcy5yZWRlZW1TY3JpcHQsIGAke3Bvc1R5cGV9IHJlcXVpcmVzIE5PIHJlZGVlbVNjcmlwdGApO1xuICAgICAgdGZNZXNzYWdlKHR5cGVmb3JjZS52YWx1ZSh1bmRlZmluZWQpLCBzaWduUGFyYW1zLndpdG5lc3NWYWx1ZSwgYCR7cG9zVHlwZX0gcmVxdWlyZXMgTk8gd2l0bmVzc1ZhbHVlYCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdwMnNoLXAyd3BraCc6XG4gICAgICBpZiAocHJldk91dFR5cGUgJiYgcHJldk91dFR5cGUgIT09ICdzY3JpcHRoYXNoJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBpbnB1dCAjJHtzaWduUGFyYW1zLnZpbn0gaXMgbm90IG9mIHR5cGUgcDJzaC1wMndwa2g6ICR7cHJldk91dFR5cGV9YCk7XG4gICAgICB9XG4gICAgICB0Zk1lc3NhZ2UodHlwZWZvcmNlLnZhbHVlKHVuZGVmaW5lZCksIHNpZ25QYXJhbXMud2l0bmVzc1NjcmlwdCwgYCR7cG9zVHlwZX0gcmVxdWlyZXMgTk8gd2l0bmVzc1NjcmlwdGApO1xuICAgICAgdGZNZXNzYWdlKHR5cGVmb3JjZS5CdWZmZXIsIHNpZ25QYXJhbXMucmVkZWVtU2NyaXB0LCBgJHtwb3NUeXBlfSByZXF1aXJlcyByZWRlZW1TY3JpcHRgKTtcbiAgICAgIHRmTWVzc2FnZSh0eXBlcy5TYXRvc2hpLCBzaWduUGFyYW1zLndpdG5lc3NWYWx1ZSwgYCR7cG9zVHlwZX0gcmVxdWlyZXMgd2l0bmVzc1ZhbHVlYCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdwMnNoLXAybXMnOlxuICAgIGNhc2UgJ3Ayc2gtcDJwayc6XG4gICAgY2FzZSAncDJzaC1wMnBraCc6XG4gICAgICBpZiAocHJldk91dFR5cGUgJiYgcHJldk91dFR5cGUgIT09ICdzY3JpcHRoYXNoJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBpbnB1dCAjJHtzaWduUGFyYW1zLnZpbn0gaXMgbm90IG9mIHR5cGUgJHtwb3NUeXBlfTogJHtwcmV2T3V0VHlwZX1gKTtcbiAgICAgIH1cbiAgICAgIHRmTWVzc2FnZSh0eXBlZm9yY2UudmFsdWUodW5kZWZpbmVkKSwgc2lnblBhcmFtcy53aXRuZXNzU2NyaXB0LCBgJHtwb3NUeXBlfSByZXF1aXJlcyBOTyB3aXRuZXNzU2NyaXB0YCk7XG4gICAgICB0Zk1lc3NhZ2UodHlwZWZvcmNlLkJ1ZmZlciwgc2lnblBhcmFtcy5yZWRlZW1TY3JpcHQsIGAke3Bvc1R5cGV9IHJlcXVpcmVzIHJlZGVlbVNjcmlwdGApO1xuICAgICAgdGZNZXNzYWdlKHR5cGVmb3JjZS52YWx1ZSh1bmRlZmluZWQpLCBzaWduUGFyYW1zLndpdG5lc3NWYWx1ZSwgYCR7cG9zVHlwZX0gcmVxdWlyZXMgTk8gd2l0bmVzc1ZhbHVlYCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdwMndzaC1wMm1zJzpcbiAgICBjYXNlICdwMndzaC1wMnBrJzpcbiAgICBjYXNlICdwMndzaC1wMnBraCc6XG4gICAgICBpZiAocHJldk91dFR5cGUgJiYgcHJldk91dFR5cGUgIT09ICd3aXRuZXNzc2NyaXB0aGFzaCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgaW5wdXQgIyR7c2lnblBhcmFtcy52aW59IGlzIG5vdCBvZiB0eXBlICR7cG9zVHlwZX06ICR7cHJldk91dFR5cGV9YCk7XG4gICAgICB9XG4gICAgICB0Zk1lc3NhZ2UodHlwZWZvcmNlLkJ1ZmZlciwgc2lnblBhcmFtcy53aXRuZXNzU2NyaXB0LCBgJHtwb3NUeXBlfSByZXF1aXJlcyB3aXRuZXNzU2NyaXB0YCk7XG4gICAgICB0Zk1lc3NhZ2UodHlwZWZvcmNlLnZhbHVlKHVuZGVmaW5lZCksIHNpZ25QYXJhbXMucmVkZWVtU2NyaXB0LCBgJHtwb3NUeXBlfSByZXF1aXJlcyBOTyByZWRlZW1TY3JpcHRgKTtcbiAgICAgIHRmTWVzc2FnZSh0eXBlcy5TYXRvc2hpLCBzaWduUGFyYW1zLndpdG5lc3NWYWx1ZSwgYCR7cG9zVHlwZX0gcmVxdWlyZXMgd2l0bmVzc1ZhbHVlYCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdwMnNoLXAyd3NoLXAybXMnOlxuICAgIGNhc2UgJ3Ayc2gtcDJ3c2gtcDJwayc6XG4gICAgY2FzZSAncDJzaC1wMndzaC1wMnBraCc6XG4gICAgICBpZiAocHJldk91dFR5cGUgJiYgcHJldk91dFR5cGUgIT09ICdzY3JpcHRoYXNoJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBpbnB1dCAjJHtzaWduUGFyYW1zLnZpbn0gaXMgbm90IG9mIHR5cGUgJHtwb3NUeXBlfTogJHtwcmV2T3V0VHlwZX1gKTtcbiAgICAgIH1cbiAgICAgIHRmTWVzc2FnZSh0eXBlZm9yY2UuQnVmZmVyLCBzaWduUGFyYW1zLndpdG5lc3NTY3JpcHQsIGAke3Bvc1R5cGV9IHJlcXVpcmVzIHdpdG5lc3NTY3JpcHRgKTtcbiAgICAgIHRmTWVzc2FnZSh0eXBlZm9yY2UuQnVmZmVyLCBzaWduUGFyYW1zLnJlZGVlbVNjcmlwdCwgYCR7cG9zVHlwZX0gcmVxdWlyZXMgd2l0bmVzc1NjcmlwdGApO1xuICAgICAgdGZNZXNzYWdlKHR5cGVzLlNhdG9zaGksIHNpZ25QYXJhbXMud2l0bmVzc1ZhbHVlLCBgJHtwb3NUeXBlfSByZXF1aXJlcyB3aXRuZXNzU2NyaXB0YCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdwMnRyJzpcbiAgICAgIGlmIChwcmV2T3V0VHlwZSAmJiBwcmV2T3V0VHlwZSAhPT0gJ3RhcHJvb3QnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYGlucHV0ICMke3NpZ25QYXJhbXMudmlufSBpcyBub3Qgb2YgdHlwZSAke3Bvc1R5cGV9OiAke3ByZXZPdXRUeXBlfWApO1xuICAgICAgfVxuICAgICAgdGZNZXNzYWdlKHR5cGVmb3JjZS52YWx1ZSh1bmRlZmluZWQpLCBzaWduUGFyYW1zLndpdG5lc3NTY3JpcHQsIGAke3Bvc1R5cGV9IHJlcXVpcmVzIE5PIHdpdG5lc3NTY3JpcHRgKTtcbiAgICAgIHRmTWVzc2FnZSh0eXBlZm9yY2UudmFsdWUodW5kZWZpbmVkKSwgc2lnblBhcmFtcy5yZWRlZW1TY3JpcHQsIGAke3Bvc1R5cGV9IHJlcXVpcmVzIE5PIHJlZGVlbVNjcmlwdGApO1xuICAgICAgdGZNZXNzYWdlKHR5cGVmb3JjZS52YWx1ZSh1bmRlZmluZWQpLCBzaWduUGFyYW1zLndpdG5lc3NWYWx1ZSwgYCR7cG9zVHlwZX0gcmVxdWlyZXMgTk8gd2l0bmVzc1ZhbHVlYCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdwMnRyLXAybnMnOlxuICAgICAgaWYgKHByZXZPdXRUeXBlICYmIHByZXZPdXRUeXBlICE9PSAndGFwcm9vdCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgaW5wdXQgIyR7c2lnblBhcmFtcy52aW59IGlzIG5vdCBvZiB0eXBlICR7cG9zVHlwZX06ICR7cHJldk91dFR5cGV9YCk7XG4gICAgICB9XG4gICAgICBpbnB1dHNbc2lnblBhcmFtcy52aW5dLnByZXZPdXRUeXBlID0gaW5wdXRzW3NpZ25QYXJhbXMudmluXS5wcmV2T3V0VHlwZSB8fCAndGFwcm9vdCc7XG4gICAgICB0Zk1lc3NhZ2UodHlwZWZvcmNlLkJ1ZmZlciwgc2lnblBhcmFtcy53aXRuZXNzU2NyaXB0LCBgJHtwb3NUeXBlfSByZXF1aXJlcyB3aXRuZXNzU2NyaXB0YCk7XG4gICAgICB0Zk1lc3NhZ2UodHlwZWZvcmNlLkJ1ZmZlciwgc2lnblBhcmFtcy5jb250cm9sQmxvY2ssIGAke3Bvc1R5cGV9IHJlcXVpcmVzIGNvbnRyb2xCbG9ja2ApO1xuICAgICAgdGZNZXNzYWdlKHR5cGVmb3JjZS52YWx1ZSh1bmRlZmluZWQpLCBzaWduUGFyYW1zLnJlZGVlbVNjcmlwdCwgYCR7cG9zVHlwZX0gcmVxdWlyZXMgTk8gcmVkZWVtU2NyaXB0YCk7XG4gICAgICBicmVhaztcbiAgfVxufVxuXG5mdW5jdGlvbiB0cnlTaWduPFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQgPSBudW1iZXI+KHtcbiAgaW5wdXQsXG4gIG91clB1YktleSxcbiAga2V5UGFpcixcbiAgc2lnbmF0dXJlSGFzaCxcbiAgaGFzaFR5cGUsXG4gIHVzZUxvd1IsXG4gIHRhcHRyZWVSb290LFxufTogU2lnbmluZ0RhdGE8VE51bWJlcj4pOiB2b2lkIHtcbiAgaWYgKGlucHV0LndpdG5lc3NWZXJzaW9uID09PSAxICYmIG91clB1YktleS5sZW5ndGggPT09IDMzKSBvdXJQdWJLZXkgPSBvdXJQdWJLZXkuc2xpY2UoMSk7XG4gIC8vIGVuZm9yY2UgaW4gb3JkZXIgc2lnbmluZyBvZiBwdWJsaWMga2V5c1xuICBsZXQgc2lnbmVkID0gZmFsc2U7XG4gIGZvciAoY29uc3QgW2ksIHB1YktleV0gb2YgaW5wdXQucHVia2V5cyEuZW50cmllcygpKSB7XG4gICAgaWYgKCFvdXJQdWJLZXkuZXF1YWxzKHB1YktleSEpKSBjb250aW51ZTtcbiAgICBpZiAoaW5wdXQuc2lnbmF0dXJlcyFbaV0gJiYgaW5wdXQuc2lnbmF0dXJlcyFbaV0hLmxlbmd0aCA+IDApIHRocm93IG5ldyBFcnJvcignU2lnbmF0dXJlIGFscmVhZHkgZXhpc3RzJyk7XG5cbiAgICAvLyBUT0RPOiBhZGQgdGVzdHNcbiAgICBpZiAob3VyUHViS2V5Lmxlbmd0aCAhPT0gMzMgJiYgaW5wdXQud2l0bmVzc1ZlcnNpb24gPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQklQMTQzIChXaXRuZXNzIHYwKSBpbnB1dHMgcmVxdWlyZSBjb21wcmVzc2VkIHB1YmtleXMnKTtcbiAgICB9IGVsc2UgaWYgKG91clB1YktleS5sZW5ndGggIT09IDMyICYmIGlucHV0LndpdG5lc3NWZXJzaW9uID09PSAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0JJUDM0MSAoV2l0bmVzcyB2MSkgaW5wdXRzIHJlcXVpcmUgeC1vbmx5IHB1YmtleXMnKTtcbiAgICB9XG5cbiAgICBpZiAoaW5wdXQud2l0bmVzc1ZlcnNpb24gPT09IDEpIHtcbiAgICAgIGlmICghaW5wdXQud2l0bmVzc1NjcmlwdCkge1xuICAgICAgICAvLyBGSVhNRTogV29ya2Fyb3VuZCBmb3Igbm90IGhhdmluZyBwcm9wZXIgdHdlYWtpbmcgc3VwcG9ydCBmb3Iga2V5IHBhdGhcbiAgICAgICAgaWYgKCFrZXlQYWlyLnByaXZhdGVLZXkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuZXhwZWN0ZWQga2V5cGFpcmApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHByaXZhdGVLZXkgPSB0YXByb290LnRhcFR3ZWFrUHJpdmtleShlY2NMaWIsIG91clB1YktleSwga2V5UGFpci5wcml2YXRlS2V5LCB0YXB0cmVlUm9vdCk7XG4gICAgICAgIGtleVBhaXIgPSBFQ1BhaXIuZnJvbVByaXZhdGVLZXkoQnVmZmVyLmZyb20ocHJpdmF0ZUtleSkpO1xuICAgICAgfVxuICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2JpdGNvaW4vYmlwcy9ibG9iL21hc3Rlci9iaXAtMDM0MS5tZWRpYXdpa2kjY29tbW9uLXNpZ25hdHVyZS1tZXNzYWdlXG4gICAgICBjb25zdCBzaWduYXR1cmUgPSBrZXlQYWlyLnNpZ25TY2hub3JyKHNpZ25hdHVyZUhhc2gpO1xuICAgICAgLy8gU0lHSEFTSF9ERUZBVUxUIGlzIG9taXR0ZWQgZnJvbSB0aGUgc2lnbmF0dXJlXG4gICAgICBpZiAoaGFzaFR5cGUgPT09IFRyYW5zYWN0aW9uLlNJR0hBU0hfREVGQVVMVCkge1xuICAgICAgICBpbnB1dC5zaWduYXR1cmVzIVtpXSA9IEJ1ZmZlci5mcm9tKHNpZ25hdHVyZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbnB1dC5zaWduYXR1cmVzIVtpXSA9IEJ1ZmZlci5jb25jYXQoW3NpZ25hdHVyZSwgQnVmZmVyLm9mKGhhc2hUeXBlKV0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBzaWduYXR1cmUgPSBrZXlQYWlyLnNpZ24oc2lnbmF0dXJlSGFzaCwgdXNlTG93Uik7XG4gICAgICBpbnB1dC5zaWduYXR1cmVzIVtpXSA9IGJzY3JpcHQuc2lnbmF0dXJlLmVuY29kZShzaWduYXR1cmUsIGhhc2hUeXBlKTtcbiAgICB9XG4gICAgc2lnbmVkID0gdHJ1ZTtcbiAgfVxuXG4gIGlmICghc2lnbmVkKSB0aHJvdyBuZXcgRXJyb3IoJ0tleSBwYWlyIGNhbm5vdCBzaWduIGZvciB0aGlzIGlucHV0Jyk7XG59XG5cbmludGVyZmFjZSBTaWduaW5nRGF0YTxUTnVtYmVyIGV4dGVuZHMgbnVtYmVyIHwgYmlnaW50ID0gbnVtYmVyPiB7XG4gIGlucHV0OiBUeGJJbnB1dDxUTnVtYmVyPjtcbiAgb3VyUHViS2V5OiBCdWZmZXI7XG4gIGtleVBhaXI6IFNpZ25lcjtcbiAgc2lnbmF0dXJlSGFzaDogQnVmZmVyO1xuICBoYXNoVHlwZTogbnVtYmVyO1xuICB1c2VMb3dSOiBib29sZWFuO1xuICB0YXB0cmVlUm9vdD86IEJ1ZmZlcjtcbn1cblxudHlwZSBIYXNoVHlwZUNoZWNrID0gKGhhc2hUeXBlOiBudW1iZXIpID0+IGJvb2xlYW47XG5cbmZ1bmN0aW9uIGdldFNpZ25pbmdEYXRhPFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQgPSBudW1iZXI+KFxuICBuZXR3b3JrOiBOZXR3b3JrLFxuICBpbnB1dHM6IEFycmF5PFR4YklucHV0PFROdW1iZXI+PixcbiAgbmVlZHNPdXRwdXRzOiBIYXNoVHlwZUNoZWNrLFxuICB0eDogVHJhbnNhY3Rpb248VE51bWJlcj4sXG4gIHNpZ25QYXJhbXM6IG51bWJlciB8IFR4YlNpZ25Bcmc8VE51bWJlcj4sXG4gIGtleVBhaXI/OiBTaWduZXIsXG4gIHJlZGVlbVNjcmlwdD86IEJ1ZmZlcixcbiAgaGFzaFR5cGU/OiBudW1iZXIsXG4gIHdpdG5lc3NWYWx1ZT86IFROdW1iZXIsXG4gIHdpdG5lc3NTY3JpcHQ/OiBCdWZmZXIsXG4gIGNvbnRyb2xCbG9jaz86IEJ1ZmZlcixcbiAgYW5uZXg/OiBCdWZmZXIsXG4gIHVzZUxvd1I/OiBib29sZWFuXG4pOiBTaWduaW5nRGF0YTxUTnVtYmVyPiB7XG4gIGxldCB2aW46IG51bWJlcjtcbiAgaWYgKHR5cGVvZiBzaWduUGFyYW1zID09PSAnbnVtYmVyJykge1xuICAgIGNvbnNvbGUud2FybihcbiAgICAgICdERVBSRUNBVEVEOiBUcmFuc2FjdGlvbkJ1aWxkZXIgc2lnbiBtZXRob2QgYXJndW1lbnRzICcgKyAnd2lsbCBjaGFuZ2UgaW4gdjYsIHBsZWFzZSB1c2UgdGhlIFR4YlNpZ25BcmcgaW50ZXJmYWNlJ1xuICAgICk7XG4gICAgdmluID0gc2lnblBhcmFtcztcbiAgfSBlbHNlIGlmICh0eXBlb2Ygc2lnblBhcmFtcyA9PT0gJ29iamVjdCcpIHtcbiAgICBjaGVja1NpZ25BcmdzPFROdW1iZXI+KGlucHV0cywgc2lnblBhcmFtcyk7XG4gICAgKHsgdmluLCBrZXlQYWlyLCByZWRlZW1TY3JpcHQsIGhhc2hUeXBlLCB3aXRuZXNzVmFsdWUsIHdpdG5lc3NTY3JpcHQsIGNvbnRyb2xCbG9jaywgYW5uZXggfSA9IHNpZ25QYXJhbXMpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RyYW5zYWN0aW9uQnVpbGRlciBzaWduIGZpcnN0IGFyZyBtdXN0IGJlIFR4YlNpZ25Bcmcgb3IgbnVtYmVyJyk7XG4gIH1cbiAgaWYgKGtleVBhaXIgPT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignc2lnbiByZXF1aXJlcyBrZXlwYWlyJyk7XG4gIH1cbiAgaWYgKCFpbnB1dHNbdmluXSkgdGhyb3cgbmV3IEVycm9yKCdObyBpbnB1dCBhdCBpbmRleDogJyArIHZpbik7XG5cbiAgY29uc3QgaW5wdXQgPSBpbnB1dHNbdmluXTtcblxuICAvLyBpZiByZWRlZW1TY3JpcHQgd2FzIHByZXZpb3VzbHkgcHJvdmlkZWQsIGVuZm9yY2UgY29uc2lzdGVuY3lcbiAgaWYgKGlucHV0LnJlZGVlbVNjcmlwdCAhPT0gdW5kZWZpbmVkICYmIHJlZGVlbVNjcmlwdCAmJiAhaW5wdXQucmVkZWVtU2NyaXB0LmVxdWFscyhyZWRlZW1TY3JpcHQpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbmNvbnNpc3RlbnQgcmVkZWVtU2NyaXB0Jyk7XG4gIH1cblxuICBjb25zdCBvdXJQdWJLZXkgPSBrZXlQYWlyLnB1YmxpY0tleSB8fCAoa2V5UGFpci5nZXRQdWJsaWNLZXkgJiYga2V5UGFpci5nZXRQdWJsaWNLZXkoKSk7XG4gIGlmICghY2FuU2lnbjxUTnVtYmVyPihpbnB1dCkpIHtcbiAgICBpZiAod2l0bmVzc1ZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChpbnB1dC52YWx1ZSAhPT0gdW5kZWZpbmVkICYmIGlucHV0LnZhbHVlICE9PSB3aXRuZXNzVmFsdWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBkaWQgbm90IG1hdGNoIHdpdG5lc3NWYWx1ZScpO1xuICAgICAgfVxuICAgICAgdHlwZWZvcmNlKHR5cGVzLlNhdG9zaGksIHdpdG5lc3NWYWx1ZSk7XG4gICAgICBpbnB1dC52YWx1ZSA9IHdpdG5lc3NWYWx1ZTtcbiAgICB9XG5cbiAgICBpZiAoIWNhblNpZ248VE51bWJlcj4oaW5wdXQpKSB7XG4gICAgICBjb25zdCBwcmVwYXJlZCA9IHByZXBhcmVJbnB1dDxUTnVtYmVyPihpbnB1dCwgb3VyUHViS2V5LCByZWRlZW1TY3JpcHQsIHdpdG5lc3NTY3JpcHQsIGNvbnRyb2xCbG9jaywgYW5uZXgpO1xuXG4gICAgICAvLyB1cGRhdGVzIGlubGluZVxuICAgICAgT2JqZWN0LmFzc2lnbihpbnB1dCwgcHJlcGFyZWQpO1xuICAgIH1cblxuICAgIGlmICghY2FuU2lnbjxUTnVtYmVyPihpbnB1dCkpIHRocm93IEVycm9yKGlucHV0LnByZXZPdXRUeXBlICsgJyBub3Qgc3VwcG9ydGVkJyk7XG4gIH1cblxuICAvLyBoYXNoVHlwZSBjYW4gYmUgMCBpbiBUYXByb290LCBzbyBjYW4ndCB1c2UgaGFzaFR5cGUgfHwgU0lHSEFTSF9BTExcbiAgaWYgKGlucHV0LndpdG5lc3NWZXJzaW9uID09PSAxKSB7XG4gICAgaGFzaFR5cGUgPSBoYXNoVHlwZSA9PT0gdW5kZWZpbmVkID8gVHJhbnNhY3Rpb24uU0lHSEFTSF9ERUZBVUxUIDogaGFzaFR5cGU7XG4gIH0gZWxzZSB7XG4gICAgaGFzaFR5cGUgPSBoYXNoVHlwZSB8fCBUcmFuc2FjdGlvbi5TSUdIQVNIX0FMTDtcbiAgfVxuICBpZiAobmVlZHNPdXRwdXRzKGhhc2hUeXBlKSkgdGhyb3cgbmV3IEVycm9yKCdUcmFuc2FjdGlvbiBuZWVkcyBvdXRwdXRzJyk7XG5cbiAgLy8gVE9ETzogVGhpcyBpcyBub3QgdGhlIGJlc3QgcGxhY2UgdG8gZG8gdGhpcywgYnV0IG1pZ2h0IHN0aWNrIHdpdGggaXQgdW50aWwgUFNCVFxuICBsZXQgbGVhZkhhc2g7XG4gIGxldCB0YXB0cmVlUm9vdDtcbiAgaWYgKGNvbnRyb2xCbG9jayAmJiB3aXRuZXNzU2NyaXB0KSB7XG4gICAgbGVhZkhhc2ggPSB0YXByb290LmdldFRhcGxlYWZIYXNoKGVjY0xpYiwgY29udHJvbEJsb2NrLCB3aXRuZXNzU2NyaXB0KTtcbiAgICB0YXB0cmVlUm9vdCA9IHRhcHJvb3QuZ2V0VGFwdHJlZVJvb3QoZWNjTGliLCBjb250cm9sQmxvY2ssIHdpdG5lc3NTY3JpcHQsIGxlYWZIYXNoKTtcbiAgfVxuXG4gIC8vIHJlYWR5IHRvIHNpZ25cbiAgbGV0IHNpZ25hdHVyZUhhc2g6IEJ1ZmZlcjtcbiAgc3dpdGNoIChpbnB1dC53aXRuZXNzVmVyc2lvbikge1xuICAgIGNhc2UgdW5kZWZpbmVkOlxuICAgICAgc2lnbmF0dXJlSGFzaCA9IHR4Lmhhc2hGb3JTaWduYXR1cmUodmluLCBpbnB1dC5zaWduU2NyaXB0IGFzIEJ1ZmZlciwgaGFzaFR5cGUsIGlucHV0LnZhbHVlKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMDpcbiAgICAgIHNpZ25hdHVyZUhhc2ggPSB0eC5oYXNoRm9yV2l0bmVzc1YwKHZpbiwgaW5wdXQuc2lnblNjcmlwdCBhcyBCdWZmZXIsIGlucHV0LnZhbHVlIGFzIFROdW1iZXIsIGhhc2hUeXBlKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMTpcbiAgICAgIHNpZ25hdHVyZUhhc2ggPSB0eC5oYXNoRm9yV2l0bmVzc1YxKFxuICAgICAgICB2aW4sXG4gICAgICAgIGlucHV0cy5tYXAoKHsgcHJldk91dFNjcmlwdCB9KSA9PiBwcmV2T3V0U2NyaXB0IGFzIEJ1ZmZlciksXG4gICAgICAgIGlucHV0cy5tYXAoKHsgdmFsdWUgfSkgPT4gdmFsdWUgYXMgVE51bWJlciksXG4gICAgICAgIGhhc2hUeXBlLFxuICAgICAgICBsZWFmSGFzaFxuICAgICAgKTtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbnN1cHBvcnRlZCB3aXRuZXNzIHZlcnNpb24nKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgaW5wdXQsXG4gICAgb3VyUHViS2V5LFxuICAgIGtleVBhaXIsXG4gICAgc2lnbmF0dXJlSGFzaCxcbiAgICBoYXNoVHlwZSxcbiAgICB1c2VMb3dSOiAhIXVzZUxvd1IsXG4gICAgdGFwdHJlZVJvb3QsXG4gIH07XG59XG4iXX0=Выполнить команду
Для локальной разработки. Не используйте в интернете!