UNPKG

@coolwallet/btc

Version:
293 lines (248 loc) 42.5 kB
"use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } Object.defineProperty(exports, "__esModule", { value: true }); exports.toReverseUintBuffer = toReverseUintBuffer; exports.addressToOutScript = addressToOutScript; exports.pubkeyToAddressAndOutScript = pubkeyToAddressAndOutScript; exports.createUnsignedTransactions = createUnsignedTransactions; exports.composeFinalTransaction = composeFinalTransaction; var _bn = _interopRequireDefault(require("bn.js")); var ecc = _interopRequireWildcard(require("@bitcoin-js/tiny-secp256k1-asmjs")); var _core = require("@coolwallet/core"); var bitcoin = _interopRequireWildcard(require("bitcoinjs-lib")); var varuint = _interopRequireWildcard(require("./varuintUtil")); var cryptoUtil = _interopRequireWildcard(require("./cryptoUtil")); var _types = require("../config/types"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } bitcoin.initEccLib(ecc); function toReverseUintBuffer(numberOrString, byteSize) { var bn = new _bn["default"](numberOrString); var buf = Buffer.from(bn.toArray()).reverse(); return Buffer.alloc(byteSize).fill(buf, 0, buf.length); } function toXOnly(pubKey) { return pubKey.length === 32 ? pubKey : pubKey.slice(1, 33); } function addressToOutScript(address) { var scriptType; var payment; var scriptPubKey; if (address.startsWith('1')) { scriptType = _types.ScriptType.P2PKH; payment = bitcoin.payments.p2pkh({ address: address }); scriptPubKey = payment.hash; } else if (address.startsWith('3')) { scriptType = _types.ScriptType.P2SH_P2WPKH; payment = bitcoin.payments.p2sh({ address: address }); scriptPubKey = payment.hash; } else if (address.startsWith('bc1q') && address.length === 42) { scriptType = _types.ScriptType.P2WPKH; payment = bitcoin.payments.p2wpkh({ address: address }); scriptPubKey = payment.hash; } else if (address.startsWith('bc1q') && address.length === 62) { scriptType = _types.ScriptType.P2WSH; payment = bitcoin.payments.p2wsh({ address: address }); scriptPubKey = payment.hash; } else if (address.startsWith('bc1p')) { scriptType = _types.ScriptType.P2TR; payment = bitcoin.payments.p2tr({ address: address }); scriptPubKey = payment.pubkey; } else { throw new _core.error.SDKError(addressToOutScript.name, "Unsupport Address : ".concat(address)); } if (!payment.output) throw new _core.error.SDKError(addressToOutScript.name, "No OutScript for Address : ".concat(address)); var outScript = payment.output; var outHash = payment.hash; return { scriptType: scriptType, outScript: outScript, outHash: outHash, scriptPubKey: scriptPubKey }; } function pubkeyToAddressAndOutScript(pubkey, scriptType) { var payment; switch (scriptType) { case _types.ScriptType.P2PKH: payment = bitcoin.payments.p2pkh({ pubkey: pubkey }); break; case _types.ScriptType.P2SH_P2WPKH: payment = bitcoin.payments.p2sh({ redeem: bitcoin.payments.p2wpkh({ pubkey: pubkey }) }); break; case _types.ScriptType.P2WPKH: payment = bitcoin.payments.p2wpkh({ pubkey: pubkey }); break; case _types.ScriptType.P2TR: payment = bitcoin.payments.p2tr({ pubkey: toXOnly(pubkey) }); break; default: throw new _core.error.SDKError(pubkeyToAddressAndOutScript.name, "Unsupport ScriptType '".concat(scriptType, "'")); } if (!payment.address) throw new _core.error.SDKError(pubkeyToAddressAndOutScript.name, "No Address for ScriptType '".concat(scriptType, "'")); if (!payment.output) throw new _core.error.SDKError(pubkeyToAddressAndOutScript.name, "No OutScript for ScriptType '".concat(scriptType, "'")); return { address: payment.address, outScript: payment.output }; } function createUnsignedTransactions(redeemScriptType, inputs, output, change) { var version = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1; var lockTime = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; var versionBuf = toReverseUintBuffer(version, 4); var lockTimeBuf = toReverseUintBuffer(lockTime, 4); var inputsCount = varuint.encode(inputs.length); var preparedInputs = inputs.map(function (_ref) { var preTxHash = _ref.preTxHash, preIndex = _ref.preIndex, preValue = _ref.preValue, sequence = _ref.sequence, addressIndex = _ref.addressIndex, pubkeyBuf = _ref.pubkeyBuf, purposeIndex = _ref.purposeIndex; if (!pubkeyBuf) { throw new _core.error.SDKError(createUnsignedTransactions.name, 'Public Key not exists !!'); } var preOutPointBuf = Buffer.concat([Buffer.from(preTxHash, 'hex').reverse(), toReverseUintBuffer(preIndex, 4)]); var preValueBuf = toReverseUintBuffer(preValue, 8); var sequenceBuf = sequence ? toReverseUintBuffer(sequence, 4) : Buffer.from('ffffffff', 'hex'); return { addressIndex: addressIndex, pubkeyBuf: pubkeyBuf, preOutPointBuf: preOutPointBuf, preValueBuf: preValueBuf, sequenceBuf: sequenceBuf, purposeIndex: purposeIndex }; }); var _addressToOutScript = addressToOutScript(output.address), outputType = _addressToOutScript.scriptType, outputScript = _addressToOutScript.outScript; var outputScriptLen = varuint.encode(outputScript.length); var outputArray = [Buffer.concat([toReverseUintBuffer(output.value, 8), outputScriptLen, outputScript])]; if (change) { if (!change.pubkeyBuf) throw new _core.error.SDKError(createUnsignedTransactions.name, 'Public Key not exists !!'); var changeValue = toReverseUintBuffer(change.value, 8); var _pubkeyToAddressAndOu = pubkeyToAddressAndOutScript(change.pubkeyBuf, redeemScriptType), outScript = _pubkeyToAddressAndOu.outScript; var outScriptLen = varuint.encode(outScript.length); outputArray.push(Buffer.concat([changeValue, outScriptLen, outScript])); } var outputsCountNum = 1; outputsCountNum = change ? outputsCountNum + 1 : outputsCountNum; var outputsCount = varuint.encode(outputsCountNum); var outputsBuf = Buffer.concat(outputArray); var hashPrevouts = cryptoUtil.doubleSha256(Buffer.concat(preparedInputs.map(function (input) { return input.preOutPointBuf; }))); var hashSequence = cryptoUtil.doubleSha256(Buffer.concat(preparedInputs.map(function (input) { return input.sequenceBuf; }))); var hashOutputs = cryptoUtil.doubleSha256(outputsBuf); var unsignedTransactions = preparedInputs.map(function (_ref2) { var pubkeyBuf = _ref2.pubkeyBuf, preOutPointBuf = _ref2.preOutPointBuf, preValueBuf = _ref2.preValueBuf, sequenceBuf = _ref2.sequenceBuf; if (redeemScriptType === _types.ScriptType.P2PKH) { var _pubkeyToAddressAndOu2 = pubkeyToAddressAndOutScript(pubkeyBuf, redeemScriptType), _outScript = _pubkeyToAddressAndOu2.outScript; var _outScriptLen = varuint.encode(_outScript.length); return Buffer.concat([versionBuf, varuint.encode(1), preOutPointBuf, _outScriptLen, // preOutScriptBuf _outScript, // preOutScriptBuf sequenceBuf, outputsCount, outputsBuf, lockTimeBuf, Buffer.from('81000000', 'hex')]); } else { return Buffer.concat([versionBuf, hashPrevouts, hashSequence, preOutPointBuf, Buffer.from("1976a914".concat(cryptoUtil.hash160(pubkeyBuf).toString('hex'), "88ac"), 'hex'), // ScriptCode preValueBuf, sequenceBuf, hashOutputs, lockTimeBuf, Buffer.from('01000000', 'hex')]); } }); return { preparedData: { versionBuf: versionBuf, inputsCount: inputsCount, preparedInputs: preparedInputs, outputType: outputType, outputsCount: outputsCount, outputsBuf: outputsBuf, lockTimeBuf: lockTimeBuf }, unsignedTransactions: unsignedTransactions }; } function composeFinalTransaction(redeemScriptType, preparedData, signatures) { var versionBuf = preparedData.versionBuf, inputsCount = preparedData.inputsCount, preparedInputs = preparedData.preparedInputs, outputsCount = preparedData.outputsCount, outputsBuf = preparedData.outputsBuf, lockTimeBuf = preparedData.lockTimeBuf; if (redeemScriptType !== _types.ScriptType.P2PKH && redeemScriptType !== _types.ScriptType.P2WPKH && redeemScriptType !== _types.ScriptType.P2SH_P2WPKH && redeemScriptType !== _types.ScriptType.P2TR) { throw new _core.error.SDKError(composeFinalTransaction.name, "Unsupport ScriptType '".concat(redeemScriptType, "'")); } if (redeemScriptType === _types.ScriptType.P2PKH) { var inputsBuf = Buffer.concat(preparedInputs.map(function (data, i) { var pubkeyBuf = data.pubkeyBuf, preOutPointBuf = data.preOutPointBuf, sequenceBuf = data.sequenceBuf; var signature = signatures[i]; var inScript = Buffer.concat([Buffer.from((signature.length + 1).toString(16), 'hex'), signature, Buffer.from('81', 'hex'), Buffer.from(pubkeyBuf.length.toString(16), 'hex'), pubkeyBuf]); return Buffer.concat([preOutPointBuf, varuint.encode(inScript.length), inScript, sequenceBuf]); })); return Buffer.concat([versionBuf, inputsCount, inputsBuf, outputsCount, outputsBuf, lockTimeBuf]); } else { var flagBuf = Buffer.from('0001', 'hex'); var segwitBuf; if (redeemScriptType === _types.ScriptType.P2TR) { segwitBuf = Buffer.concat(preparedInputs.map(function (_, i) { var signature = signatures[i]; var segwitScript = Buffer.concat([Buffer.from(signature.length.toString(16), 'hex'), signature]); return Buffer.concat([Buffer.from('01', 'hex'), segwitScript]); })); } else { segwitBuf = Buffer.concat(preparedInputs.map(function (_ref3, i) { var pubkeyBuf = _ref3.pubkeyBuf; var signature = signatures[i]; var segwitScript = Buffer.concat([Buffer.from((signature.length + 1).toString(16), 'hex'), signature, Buffer.from('01', 'hex'), Buffer.from(pubkeyBuf.length.toString(16), 'hex'), pubkeyBuf]); return Buffer.concat([Buffer.from('02', 'hex'), segwitScript]); })); } var _inputsBuf = Buffer.concat(preparedInputs.map(function (_ref4) { var pubkeyBuf = _ref4.pubkeyBuf, preOutPointBuf = _ref4.preOutPointBuf, sequenceBuf = _ref4.sequenceBuf; if (redeemScriptType === _types.ScriptType.P2SH_P2WPKH) { var _pubkeyToAddressAndOu3 = pubkeyToAddressAndOutScript(pubkeyBuf, _types.ScriptType.P2WPKH), outScript = _pubkeyToAddressAndOu3.outScript; var inScript = Buffer.concat([Buffer.from(outScript.length.toString(16), 'hex'), outScript]); return Buffer.concat([preOutPointBuf, varuint.encode(inScript.length), inScript, sequenceBuf]); } else { return Buffer.concat([preOutPointBuf, Buffer.from('00', 'hex'), sequenceBuf]); } })); return Buffer.concat([versionBuf, flagBuf, inputsCount, _inputsBuf, outputsCount, outputsBuf, segwitBuf, lockTimeBuf]); } } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy90cmFuc2FjdGlvblV0aWwudHMiXSwibmFtZXMiOlsiYml0Y29pbiIsImluaXRFY2NMaWIiLCJlY2MiLCJ0b1JldmVyc2VVaW50QnVmZmVyIiwibnVtYmVyT3JTdHJpbmciLCJieXRlU2l6ZSIsImJuIiwiQk4iLCJidWYiLCJCdWZmZXIiLCJmcm9tIiwidG9BcnJheSIsInJldmVyc2UiLCJhbGxvYyIsImZpbGwiLCJsZW5ndGgiLCJ0b1hPbmx5IiwicHViS2V5Iiwic2xpY2UiLCJhZGRyZXNzVG9PdXRTY3JpcHQiLCJhZGRyZXNzIiwic2NyaXB0VHlwZSIsInBheW1lbnQiLCJzY3JpcHRQdWJLZXkiLCJzdGFydHNXaXRoIiwiU2NyaXB0VHlwZSIsIlAyUEtIIiwicGF5bWVudHMiLCJwMnBraCIsImhhc2giLCJQMlNIX1AyV1BLSCIsInAyc2giLCJQMldQS0giLCJwMndwa2giLCJQMldTSCIsInAyd3NoIiwiUDJUUiIsInAydHIiLCJwdWJrZXkiLCJlcnJvciIsIlNES0Vycm9yIiwibmFtZSIsIm91dHB1dCIsIm91dFNjcmlwdCIsIm91dEhhc2giLCJwdWJrZXlUb0FkZHJlc3NBbmRPdXRTY3JpcHQiLCJyZWRlZW0iLCJjcmVhdGVVbnNpZ25lZFRyYW5zYWN0aW9ucyIsInJlZGVlbVNjcmlwdFR5cGUiLCJpbnB1dHMiLCJjaGFuZ2UiLCJ2ZXJzaW9uIiwibG9ja1RpbWUiLCJ2ZXJzaW9uQnVmIiwibG9ja1RpbWVCdWYiLCJpbnB1dHNDb3VudCIsInZhcnVpbnQiLCJlbmNvZGUiLCJwcmVwYXJlZElucHV0cyIsIm1hcCIsInByZVR4SGFzaCIsInByZUluZGV4IiwicHJlVmFsdWUiLCJzZXF1ZW5jZSIsImFkZHJlc3NJbmRleCIsInB1YmtleUJ1ZiIsInB1cnBvc2VJbmRleCIsInByZU91dFBvaW50QnVmIiwiY29uY2F0IiwicHJlVmFsdWVCdWYiLCJzZXF1ZW5jZUJ1ZiIsIm91dHB1dFR5cGUiLCJvdXRwdXRTY3JpcHQiLCJvdXRwdXRTY3JpcHRMZW4iLCJvdXRwdXRBcnJheSIsInZhbHVlIiwiY2hhbmdlVmFsdWUiLCJvdXRTY3JpcHRMZW4iLCJwdXNoIiwib3V0cHV0c0NvdW50TnVtIiwib3V0cHV0c0NvdW50Iiwib3V0cHV0c0J1ZiIsImhhc2hQcmV2b3V0cyIsImNyeXB0b1V0aWwiLCJkb3VibGVTaGEyNTYiLCJpbnB1dCIsImhhc2hTZXF1ZW5jZSIsImhhc2hPdXRwdXRzIiwidW5zaWduZWRUcmFuc2FjdGlvbnMiLCJoYXNoMTYwIiwidG9TdHJpbmciLCJwcmVwYXJlZERhdGEiLCJjb21wb3NlRmluYWxUcmFuc2FjdGlvbiIsInNpZ25hdHVyZXMiLCJpbnB1dHNCdWYiLCJkYXRhIiwiaSIsInNpZ25hdHVyZSIsImluU2NyaXB0IiwiZmxhZ0J1ZiIsInNlZ3dpdEJ1ZiIsIl8iLCJzZWd3aXRTY3JpcHQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFQUEsT0FBTyxDQUFDQyxVQUFSLENBQW1CQyxHQUFuQjs7QUFFTyxTQUFTQyxtQkFBVCxDQUE2QkMsY0FBN0IsRUFBOERDLFFBQTlELEVBQXdGO0FBQzdGLE1BQU1DLEVBQUUsR0FBRyxJQUFJQyxjQUFKLENBQU9ILGNBQVAsQ0FBWDtBQUNBLE1BQU1JLEdBQUcsR0FBR0MsTUFBTSxDQUFDQyxJQUFQLENBQVlKLEVBQUUsQ0FBQ0ssT0FBSCxFQUFaLEVBQTBCQyxPQUExQixFQUFaO0FBQ0EsU0FBT0gsTUFBTSxDQUFDSSxLQUFQLENBQWFSLFFBQWIsRUFBdUJTLElBQXZCLENBQTRCTixHQUE1QixFQUFpQyxDQUFqQyxFQUFvQ0EsR0FBRyxDQUFDTyxNQUF4QyxDQUFQO0FBQ0Q7O0FBRUQsU0FBU0MsT0FBVCxDQUFpQkMsTUFBakIsRUFBeUM7QUFDdkMsU0FBT0EsTUFBTSxDQUFDRixNQUFQLEtBQWtCLEVBQWxCLEdBQXVCRSxNQUF2QixHQUFnQ0EsTUFBTSxDQUFDQyxLQUFQLENBQWEs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QVlpQyxTQUFTLENBQUM1QixNQUFWLENBQWlCMkUsUUFBakIsQ0FBMEIsRUFBMUIsQ0FBWixFQUEyQyxLQUEzQyxDQUFELEVBQW9EL0MsU0FBcEQsQ0FBZCxDQUFqQjtBQUNBLGVBQU9sQyxNQUFNLENBQUMyRCxNQUFQLENBQWMsQ0FBQ0QsY0FBRCxFQUFpQlgsT0FBTyxDQUFDQyxNQUFSLENBQWV5QyxRQUFRLENBQUNuRixNQUF4QixDQUFqQixFQUFrRG1GLFFBQWxELEVBQTRENUIsV0FBNUQsQ0FBZCxDQUFQO0FBQ0QsT0FKRCxNQUlPO0FBQ0wsZUFBTzdELE1BQU0sQ0FBQzJELE1BQVAsQ0FBYyxDQUFDRCxjQUFELEVBQWlCMUQsTUFBTSxDQUFDQyxJQUFQLENBQVksSUFBWixFQUFrQixLQUFsQixDQUFqQixFQUEyQzRELFdBQTNDLENBQWQsQ0FBUDtBQUNEO0FBQ0YsS0FSRCxDQURnQixDQUFsQjs7QUFZQSxXQUFPN0QsTUFBTSxDQUFDMkQsTUFBUCxDQUFjLENBQ25CZixVQURtQixFQUVuQjhDLE9BRm1CLEVBR25CNUMsV0FIbUIsRUFJbkJ1QyxVQUptQixFQUtuQmQsWUFMbUIsRUFNbkJDLFVBTm1CLEVBT25CbUIsU0FQbUIsRUFRbkI5QyxXQVJtQixDQUFkLENBQVA7QUFVRDtBQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEJOIGZyb20gJ2JuLmpzJztcbmltcG9ydCAqIGFzIGVjYyBmcm9tICdAYml0Y29pbi1qcy90aW55LXNlY3AyNTZrMS1hc21qcyc7XG5pbXBvcnQgeyBlcnJvciB9IGZyb20gJ0Bjb29sd2FsbGV0L2NvcmUnO1xuaW1wb3J0ICogYXMgYml0Y29pbiBmcm9tICdiaXRjb2luanMtbGliJztcbmltcG9ydCAqIGFzIHZhcnVpbnQgZnJvbSAnLi92YXJ1aW50VXRpbCc7XG5pbXBvcnQgKiBhcyBjcnlwdG9VdGlsIGZyb20gJy4vY3J5cHRvVXRpbCc7XG5pbXBvcnQgeyBTY3JpcHRUeXBlLCBJbnB1dCwgT3V0cHV0LCBDaGFuZ2UsIFByZXBhcmVkRGF0YSB9IGZyb20gJy4uL2NvbmZpZy90eXBlcyc7XG5cbmJpdGNvaW4uaW5pdEVjY0xpYihlY2MpO1xuXG5leHBvcnQgZnVuY3Rpb24gdG9SZXZlcnNlVWludEJ1ZmZlcihudW1iZXJPclN0cmluZzogbnVtYmVyIHwgc3RyaW5nLCBieXRlU2l6ZTogbnVtYmVyKTogQnVmZmVyIHtcbiAgY29uc3QgYm4gPSBuZXcgQk4obnVtYmVyT3JTdHJpbmcpO1xuICBjb25zdCBidWYgPSBCdWZmZXIuZnJvbShibi50b0FycmF5KCkpLnJldmVyc2UoKTtcbiAgcmV0dXJuIEJ1ZmZlci5hbGxvYyhieXRlU2l6ZSkuZmlsbChidWYsIDAsIGJ1Zi5sZW5ndGgpO1xufVxuXG5mdW5jdGlvbiB0b1hPbmx5KHB1YktleTogQnVmZmVyKTogQnVmZmVyIHtcbiAgcmV0dXJuIHB1YktleS5sZW5ndGggPT09IDMyID8gcHViS2V5IDogcHViS2V5LnNsaWNlKDEsIDMzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZHJlc3NUb091dFNjcmlwdChhZGRyZXNzOiBzdHJpbmcpOiB7XG4gIHNjcmlwdFR5cGU6IFNjcmlwdFR5cGU7XG4gIG91dFNjcmlwdDogQnVmZmVyO1xuICBvdXRIYXNoPzogQnVmZmVyO1xuICBzY3JpcHRQdWJLZXk/OiBCdWZmZXI7XG59IHtcbiAgbGV0IHNjcmlwdFR5cGU7XG4gIGxldCBwYXltZW50O1xuICBsZXQgc2NyaXB0UHViS2V5O1xuICBpZiAoYWRkcmVzcy5zdGFydHNXaXRoKCcxJykpIHtcbiAgICBzY3JpcHRUeXBlID0gU2NyaXB0VHlwZS5QMlBLSDtcbiAgICBwYXltZW50ID0gYml0Y29pbi5wYXltZW50cy5wMnBraCh7IGFkZHJlc3MgfSk7XG4gICAgc2NyaXB0UHViS2V5ID0gcGF5bWVudC5oYXNoO1xuICB9IGVsc2UgaWYgKGFkZHJlc3Muc3RhcnRzV2l0aCgnMycpKSB7XG4gICAgc2NyaXB0VHlwZSA9IFNjcmlwdFR5cGUuUDJTSF9QMldQS0g7XG4gICAgcGF5bWVudCA9IGJpdGNvaW4ucGF5bWVudHMucDJzaCh7IGFkZHJlc3MgfSk7XG4gICAgc2NyaXB0UHViS2V5ID0gcGF5bWVudC5oYXNoO1xuICB9IGVsc2UgaWYgKGFkZHJlc3Muc3RhcnRzV2l0aCgnYmMxcScpICYmIGFkZHJlc3MubGVuZ3RoID09PSA0Mikge1xuICAgIHNjcmlwdFR5cGUgPSBTY3JpcHRUeXBlLlAyV1BLSDtcbiAgICBwYXltZW50ID0gYml0Y29pbi5wYXltZW50cy5wMndwa2goeyBhZGRyZXNzIH0pO1xuICAgIHNjcmlwdFB1YktleSA9IHBheW1lbnQuaGFzaDtcbiAgfSBlbHNlIGlmIChhZGRyZXNzLnN0YXJ0c1dpdGgoJ2JjMXEnKSAmJiBhZGRyZXNzLmxlbmd0aCA9PT0gNjIpIHtcbiAgICBzY3JpcHRUeXBlID0gU2NyaXB0VHlwZS5QMldTSDtcbiAgICBwYXltZW50ID0gYml0Y29pbi5wYXltZW50cy5wMndzaCh7IGFkZHJlc3MgfSk7XG4gICAgc2NyaXB0UHViS2V5ID0gcGF5bWVudC5oYXNoO1xuICB9IGVsc2UgaWYgKGFkZHJlc3Muc3RhcnRzV2l0aCgnYmMxcCcpKSB7XG4gICAgc2NyaXB0VHlwZSA9IFNjcmlwdFR5cGUuUDJUUjtcbiAgICBwYXltZW50ID0gYml0Y29pbi5wYXltZW50cy5wMnRyKHsgYWRkcmVzcyB9KTtcbiAgICBzY3JpcHRQdWJLZXkgPSBwYXltZW50LnB1YmtleTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgZXJyb3IuU0RLRXJyb3IoYWRkcmVzc1RvT3V0U2NyaXB0Lm5hbWUsIGBVbnN1cHBvcnQgQWRkcmVzcyA6ICR7YWRkcmVzc31gKTtcbiAgfVxuICBpZiAoIXBheW1lbnQub3V0cHV0KSB0aHJvdyBuZXcgZXJyb3IuU0RLRXJyb3IoYWRkcmVzc1RvT3V0U2NyaXB0Lm5hbWUsIGBObyBPdXRTY3JpcHQgZm9yIEFkZHJlc3MgOiAke2FkZHJlc3N9YCk7XG4gIGNvbnN0IG91dFNjcmlwdCA9IHBheW1lbnQub3V0cHV0O1xuICBjb25zdCBvdXRIYXNoID0gcGF5bWVudC5oYXNoO1xuICByZXR1cm4geyBzY3JpcHRUeXBlLCBvdXRTY3JpcHQsIG91dEhhc2gsIHNjcmlwdFB1YktleSB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHVia2V5VG9BZGRyZXNzQW5kT3V0U2NyaXB0KFxuICBwdWJrZXk6IEJ1ZmZlcixcbiAgc2NyaXB0VHlwZTogU2NyaXB0VHlwZVxuKTogeyBhZGRyZXNzOiBzdHJpbmc7IG91dFNjcmlwdDogQnVmZmVyIH0ge1xuICBsZXQgcGF5bWVudDtcbiAgc3dpdGNoIChzY3JpcHRUeXBlKSB7XG4gICAgY2FzZSBTY3JpcHRUeXBlLlAyUEtIOlxuICAgICAgcGF5bWVudCA9IGJpdGNvaW4ucGF5bWVudHMucDJwa2goeyBwdWJrZXkgfSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIFNjcmlwdFR5cGUuUDJTSF9QMldQS0g6XG4gICAgICBwYXltZW50ID0gYml0Y29pbi5wYXltZW50cy5wMnNoKHtcbiAgICAgICAgcmVkZWVtOiBiaXRjb2luLnBheW1lbnRzLnAyd3BraCh7IHB1YmtleSB9KSxcbiAgICAgIH0pO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBTY3JpcHRUeXBlLlAyV1BLSDpcbiAgICAgIHBheW1lbnQgPSBiaXRjb2luLnBheW1lbnRzLnAyd3BraCh7IHB1YmtleSB9KTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgU2NyaXB0VHlwZS5QMlRSOlxuICAgICAgcGF5bWVudCA9IGJpdGNvaW4ucGF5bWVudHMucDJ0cih7IHB1YmtleTogdG9YT25seShwdWJrZXkpIH0pO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBlcnJvci5TREtFcnJvcihwdWJrZXlUb0FkZHJlc3NBbmRPdXRTY3JpcHQubmFtZSwgYFVuc3VwcG9ydCBTY3JpcHRUeXBlICcke3NjcmlwdFR5cGV9J2ApO1xuICB9XG4gIGlmICghcGF5bWVudC5hZGRyZXNzKVxuICAgIHRocm93IG5ldyBlcnJvci5TREtFcnJvcihwdWJrZXlUb0FkZHJlc3NBbmRPdXRTY3JpcHQubmFtZSwgYE5vIEFkZHJlc3MgZm9yIFNjcmlwdFR5cGUgJyR7c2NyaXB0VHlwZX0nYCk7XG4gIGlmICghcGF5bWVudC5vdXRwdXQpXG4gICAgdGhyb3cgbmV3IGVycm9yLlNES0Vycm9yKHB1YmtleVRvQWRkcmVzc0FuZE91dFNjcmlwdC5uYW1lLCBgTm8gT3V0U2NyaXB0IGZvciBTY3JpcHRUeXBlICcke3NjcmlwdFR5cGV9J2ApO1xuICByZXR1cm4geyBhZGRyZXNzOiBwYXltZW50LmFkZHJlc3MsIG91dFNjcmlwdDogcGF5bWVudC5vdXRwdXQgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVVuc2lnbmVkVHJhbnNhY3Rpb25zKFxuICByZWRlZW1TY3JpcHRUeXBlOiBTY3JpcHRUeXBlLFxuICBpbnB1dHM6IEFycmF5PElucHV0PixcbiAgb3V0cHV0OiBPdXRwdXQsXG4gIGNoYW5nZT86IENoYW5nZSB8IG51bGwsXG4gIHZlcnNpb24gPSAxLFxuICBsb2NrVGltZSA9IDBcbik6IHtcbiAgcHJlcGFyZWREYXRhOiBQcmVwYXJlZERhdGE7XG4gIHVuc2lnbmVkVHJhbnNhY3Rpb25zOiBBcnJheTxCdWZmZXI+O1xufSB7XG4gIGNvbnN0IHZlcnNpb25CdWYgPSB0b1JldmVyc2VVaW50QnVmZmVyKHZlcnNpb24sIDQpO1xuICBjb25zdCBsb2NrVGltZUJ1ZiA9IHRvUmV2ZXJzZVVpbnRCdWZmZXIobG9ja1RpbWUsIDQpO1xuICBjb25zdCBpbnB1dHNDb3VudCA9IHZhcnVpbnQuZW5jb2RlKGlucHV0cy5sZW5ndGgpO1xuICBjb25zdCBwcmVwYXJlZElucHV0cyA9IGlucHV0cy5tYXAoXG4gICAgKHsgcHJlVHhIYXNoLCBwcmVJbmRleCwgcHJlVmFsdWUsIHNlcXVlbmNlLCBhZGRyZXNzSW5kZXgsIHB1YmtleUJ1ZiwgcHVycG9zZUluZGV4IH0pID0+IHtcbiAgICAgIGlmICghcHVia2V5QnVmKSB7XG4gICAgICAgIHRocm93IG5ldyBlcnJvci5TREtFcnJvcihjcmVhdGVVbnNpZ25lZFRyYW5zYWN0aW9ucy5uYW1lLCAnUHVibGljIEtleSBub3QgZXhpc3RzICEhJyk7XG4gICAgICB9XG4gICAgICBjb25zdCBwcmVPdXRQb2ludEJ1ZiA9IEJ1ZmZlci5jb25jYXQoW0J1ZmZlci5mcm9tKHByZVR4SGFzaCwgJ2hleCcpLnJldmVyc2UoKSwgdG9SZXZlcnNlVWludEJ1ZmZlcihwcmVJbmRleCwgNCldKTtcblxuICAgICAgY29uc3QgcHJlVmFsdWVCdWYgPSB0b1JldmVyc2VVaW50QnVmZmVyKHByZVZhbHVlLCA4KTtcbiAgICAgIGNvbnN0IHNlcXVlbmNlQnVmID0gc2VxdWVuY2UgPyB0b1JldmVyc2VVaW50QnVmZmVyKHNlcXVlbmNlLCA0KSA6IEJ1ZmZlci5mcm9tKCdmZmZmZmZmZicsICdoZXgnKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYWRkcmVzc0luZGV4LFxuICAgICAgICBwdWJrZXlCdWYsXG4gICAgICAgIHByZU91dFBvaW50QnVmLFxuICAgICAgICBwcmVWYWx1ZUJ1ZixcbiAgICAgICAgc2VxdWVuY2VCdWYsXG4gICAgICAgIHB1cnBvc2VJbmRleCxcbiAgICAgIH07XG4gICAgfVxuICApO1xuXG4gIGNvbnN0IHsgc2NyaXB0VHlwZTogb3V0cHV0VHlwZSwgb3V0U2NyaXB0OiBvdXRwdXRTY3JpcHQgfSA9IGFkZHJlc3NUb091dFNjcmlwdChvdXRwdXQuYWRkcmVzcyk7XG4gIGNvbnN0IG91dHB1dFNjcmlwdExlbiA9IHZhcnVpbnQuZW5jb2RlKG91dHB1dFNjcmlwdC5sZW5ndGgpO1xuXG4gIGNvbnN0IG91dHB1dEFycmF5ID0gW0J1ZmZlci5jb25jYXQoW3RvUmV2ZXJzZVVpbnRCdWZmZXIob3V0cHV0LnZhbHVlLCA4KSwgb3V0cHV0U2NyaXB0TGVuLCBvdXRwdXRTY3JpcHRdKV07XG4gIGlmIChjaGFuZ2UpIHtcbiAgICBpZiAoIWNoYW5nZS5wdWJrZXlCdWYpIHRocm93IG5ldyBlcnJvci5TREtFcnJvcihjcmVhdGVVbnNpZ25lZFRyYW5zYWN0aW9ucy5uYW1lLCAnUHVibGljIEtleSBub3QgZXhpc3RzICEhJyk7XG4gICAgY29uc3QgY2hhbmdlVmFsdWUgPSB0b1JldmVyc2VVaW50QnVmZmVyKGNoYW5nZS52YWx1ZSwgOCk7XG4gICAgY29uc3QgeyBvdXRTY3JpcHQgfSA9IHB1YmtleVRvQWRkcmVzc0FuZE91dFNjcmlwdChjaGFuZ2UucHVia2V5QnVmLCByZWRlZW1TY3JpcHRUeXBlKTtcbiAgICBjb25zdCBvdXRTY3JpcHRMZW4gPSB2YXJ1aW50LmVuY29kZShvdXRTY3JpcHQubGVuZ3RoKTtcbiAgICBvdXRwdXRBcnJheS5wdXNoKEJ1ZmZlci5jb25jYXQoW2NoYW5nZVZhbHVlLCBvdXRTY3JpcHRMZW4sIG91dFNjcmlwdF0pKTtcbiAgfVxuXG4gIGxldCBvdXRwdXRzQ291bnROdW0gPSAxO1xuICBvdXRwdXRzQ291bnROdW0gPSBjaGFuZ2UgPyBvdXRwdXRzQ291bnROdW0gKyAxIDogb3V0cHV0c0NvdW50TnVtO1xuICBjb25zdCBvdXRwdXRzQ291bnQgPSB2YXJ1aW50LmVuY29kZShvdXRwdXRzQ291bnROdW0pO1xuICBjb25zdCBvdXRwdXRzQnVmID0gQnVmZmVyLmNvbmNhdChvdXRwdXRBcnJheSk7XG5cbiAgY29uc3QgaGFzaFByZXZvdXRzID0gY3J5cHRvVXRpbC5kb3VibGVTaGEyNTYoQnVmZmVyLmNvbmNhdChwcmVwYXJlZElucHV0cy5tYXAoKGlucHV0KSA9PiBpbnB1dC5wcmVPdXRQb2ludEJ1ZikpKTtcbiAgY29uc3QgaGFzaFNlcXVlbmNlID0gY3J5cHRvVXRpbC5kb3VibGVTaGEyNTYoQnVmZmVyLmNvbmNhdChwcmVwYXJlZElucHV0cy5tYXAoKGlucHV0KSA9PiBpbnB1dC5zZXF1ZW5jZUJ1ZikpKTtcbiAgY29uc3QgaGFzaE91dHB1dHMgPSBjcnlwdG9VdGlsLmRvdWJsZVNoYTI1NihvdXRwdXRzQnVmKTtcblxuICBjb25zdCB1bnNpZ25lZFRyYW5zYWN0aW9ucyA9IHByZXBhcmVkSW5wdXRzLm1hcCgoeyBwdWJrZXlCdWYsIHByZU91dFBvaW50QnVmLCBwcmVWYWx1ZUJ1Ziwgc2VxdWVuY2VCdWYgfSkgPT4ge1xuICAgIGlmIChyZWRlZW1TY3JpcHRUeXBlID09PSBTY3JpcHRUeXBlLlAyUEtIKSB7XG4gICAgICBjb25zdCB7IG91dFNjcmlwdCB9ID0gcHVia2V5VG9BZGRyZXNzQW5kT3V0U2NyaXB0KHB1YmtleUJ1ZiwgcmVkZWVtU2NyaXB0VHlwZSk7XG4gICAgICBjb25zdCBvdXRTY3JpcHRMZW4gPSB2YXJ1aW50LmVuY29kZShvdXRTY3JpcHQubGVuZ3RoKTtcbiAgICAgIHJldHVybiBCdWZmZXIuY29uY2F0KFtcbiAgICAgICAgdmVyc2lvbkJ1ZixcbiAgICAgICAgdmFydWludC5lbmNvZGUoMSksXG4gICAgICAgIHByZU91dFBvaW50QnVmLFxuICAgICAgICBvdXRTY3JpcHRMZW4sIC8vIHByZU91dFNjcmlwdEJ1ZlxuICAgICAgICBvdXRTY3JpcHQsIC8vIHByZU91dFNjcmlwdEJ1ZlxuICAgICAgICBzZXF1ZW5jZUJ1ZixcbiAgICAgICAgb3V0cHV0c0NvdW50LFxuICAgICAgICBvdXRwdXRzQnVmLFxuICAgICAgICBsb2NrVGltZUJ1ZixcbiAgICAgICAgQnVmZmVyLmZyb20oJzgxMDAwMDAwJywgJ2hleCcpLFxuICAgICAgXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBCdWZmZXIuY29uY2F0KFtcbiAgICAgICAgdmVyc2lvbkJ1ZixcbiAgICAgICAgaGFzaFByZXZvdXRzLFxuICAgICAgICBoYXNoU2VxdWVuY2UsXG4gICAgICAgIHByZU91dFBvaW50QnVmLFxuICAgICAgICBCdWZmZXIuZnJvbShgMTk3NmE5MTQke2NyeXB0b1V0aWwuaGFzaDE2MChwdWJrZXlCdWYpLnRvU3RyaW5nKCdoZXgnKX04OGFjYCwgJ2hleCcpLCAvLyBTY3JpcHRDb2RlXG4gICAgICAgIHByZVZhbHVlQnVmLFxuICAgICAgICBzZXF1ZW5jZUJ1ZixcbiAgICAgICAgaGFzaE91dHB1dHMsXG4gICAgICAgIGxvY2tUaW1lQnVmLFxuICAgICAgICBCdWZmZXIuZnJvbSgnMDEwMDAwMDAnLCAnaGV4JyksXG4gICAgICBdKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgcHJlcGFyZWREYXRhOiB7XG4gICAgICB2ZXJzaW9uQnVmLFxuICAgICAgaW5wdXRzQ291bnQsXG4gICAgICBwcmVwYXJlZElucHV0cyxcbiAgICAgIG91dHB1dFR5cGUsXG4gICAgICBvdXRwdXRzQ291bnQsXG4gICAgICBvdXRwdXRzQnVmLFxuICAgICAgbG9ja1RpbWVCdWYsXG4gICAgfSxcbiAgICB1bnNpZ25lZFRyYW5zYWN0aW9ucyxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbXBvc2VGaW5hbFRyYW5zYWN0aW9uKFxuICByZWRlZW1TY3JpcHRUeXBlOiBTY3JpcHRUeXBlLFxuICBwcmVwYXJlZERhdGE6IFByZXBhcmVkRGF0YSxcbiAgc2lnbmF0dXJlczogQXJyYXk8QnVmZmVyPlxuKTogQnVmZmVyIHtcbiAgY29uc3QgeyB2ZXJzaW9uQnVmLCBpbnB1dHNDb3VudCwgcHJlcGFyZWRJbnB1dHMsIG91dHB1dHNDb3VudCwgb3V0cHV0c0J1ZiwgbG9ja1RpbWVCdWYgfSA9IHByZXBhcmVkRGF0YTtcblxuICBpZiAoXG4gICAgcmVkZWVtU2NyaXB0VHlwZSAhPT0gU2NyaXB0VHlwZS5QMlBLSCAmJlxuICAgIHJlZGVlbVNjcmlwdFR5cGUgIT09IFNjcmlwdFR5cGUuUDJXUEtIICYmXG4gICAgcmVkZWVtU2NyaXB0VHlwZSAhPT0gU2NyaXB0VHlwZS5QMlNIX1AyV1BLSCAmJlxuICAgIHJlZGVlbVNjcmlwdFR5cGUgIT09IFNjcmlwdFR5cGUuUDJUUlxuICApIHtcbiAgICB0aHJvdyBuZXcgZXJyb3IuU0RLRXJyb3IoY29tcG9zZUZpbmFsVHJhbnNhY3Rpb24ubmFtZSwgYFVuc3VwcG9ydCBTY3JpcHRUeXBlICcke3JlZGVlbVNjcmlwdFR5cGV9J2ApO1xuICB9XG5cbiAgaWYgKHJlZGVlbVNjcmlwdFR5cGUgPT09IFNjcmlwdFR5cGUuUDJQS0gpIHtcbiAgICBjb25zdCBpbnB1dHNCdWYgPSBCdWZmZXIuY29uY2F0KFxuICAgICAgcHJlcGFyZWRJbnB1dHMubWFwKChkYXRhLCBpKSA9PiB7XG4gICAgICAgIGNvbnN0IHsgcHVia2V5QnVmLCBwcmVPdXRQb2ludEJ1Ziwgc2VxdWVuY2VCdWYgfSA9IGRhdGE7XG4gICAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHNpZ25hdHVyZXNbaV07XG4gICAgICAgIGNvbnN0IGluU2NyaXB0ID0gQnVmZmVyLmNvbmNhdChbXG4gICAgICAgICAgQnVmZmVyLmZyb20oKHNpZ25hdHVyZS5sZW5ndGggKyAxKS50b1N0cmluZygxNiksICdoZXgnKSxcbiAgICAgICAgICBzaWduYXR1cmUsXG4gICAgICAgICAgQnVmZmVyLmZyb20oJzgxJywgJ2hleCcpLFxuICAgICAgICAgIEJ1ZmZlci5mcm9tKHB1YmtleUJ1Zi5sZW5ndGgudG9TdHJpbmcoMTYpLCAnaGV4JyksXG4gICAgICAgICAgcHVia2V5QnVmLFxuICAgICAgICBdKTtcbiAgICAgICAgcmV0dXJuIEJ1ZmZlci5jb25jYXQoW3ByZU91dFBvaW50QnVmLCB2YXJ1aW50LmVuY29kZShpblNjcmlwdC5sZW5ndGgpLCBpblNjcmlwdCwgc2VxdWVuY2VCdWZdKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICByZXR1cm4gQnVmZmVyLmNvbmNhdChbdmVyc2lvbkJ1ZiwgaW5wdXRzQ291bnQsIGlucHV0c0J1Ziwgb3V0cHV0c0NvdW50LCBvdXRwdXRzQnVmLCBsb2NrVGltZUJ1Zl0pO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGZsYWdCdWYgPSBCdWZmZXIuZnJvbSgnMDAwMScsICdoZXgnKTtcbiAgICBsZXQgc2Vnd2l0QnVmO1xuICAgIGlmIChyZWRlZW1TY3JpcHRUeXBlID09PSBTY3JpcHRUeXBlLlAyVFIpIHtcbiAgICAgIHNlZ3dpdEJ1ZiA9IEJ1ZmZlci5jb25jYXQoXG4gICAgICAgIHByZXBhcmVkSW5wdXRzLm1hcCgoXywgaSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHNpZ25hdHVyZXNbaV07XG4gICAgICAgICAgY29uc3Qgc2Vnd2l0U2NyaXB0ID0gQnVmZmVyLmNvbmNhdChbQnVmZmVyLmZyb20oc2lnbmF0dXJlLmxlbmd0aC50b1N0cmluZygxNiksICdoZXgnKSwgc2lnbmF0dXJlXSk7XG4gICAgICAgICAgcmV0dXJuIEJ1ZmZlci5jb25jYXQoW0J1ZmZlci5mcm9tKCcwMScsICdoZXgnKSwgc2Vnd2l0U2NyaXB0XSk7XG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBzZWd3aXRCdWYgPSBCdWZmZXIuY29uY2F0KFxuICAgICAgICBwcmVwYXJlZElucHV0cy5tYXAoKHsgcHVia2V5QnVmIH0sIGkpID0+IHtcbiAgICAgICAgICBjb25zdCBzaWduYXR1cmUgPSBzaWduYXR1cmVzW2ldO1xuICAgICAgICAgIGNvbnN0IHNlZ3dpdFNjcmlwdCA9IEJ1ZmZlci5jb25jYXQoW1xuICAgICAgICAgICAgQnVmZmVyLmZyb20oKHNpZ25hdHVyZS5sZW5ndGggKyAxKS50b1N0cmluZygxNiksICdoZXgnKSxcbiAgICAgICAgICAgIHNpZ25hdHVyZSxcbiAgICAgICAgICAgIEJ1ZmZlci5mcm9tKCcwMScsICdoZXgnKSxcbiAgICAgICAgICAgIEJ1ZmZlci5mcm9tKHB1YmtleUJ1Zi5sZW5ndGgudG9TdHJpbmcoMTYpLCAnaGV4JyksXG4gICAgICAgICAgICBwdWJrZXlCdWYsXG4gICAgICAgICAgXSk7XG4gICAgICAgICAgcmV0dXJuIEJ1ZmZlci5jb25jYXQoW0J1ZmZlci5mcm9tKCcwMicsICdoZXgnKSwgc2Vnd2l0U2NyaXB0XSk7XG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IGlucHV0c0J1ZiA9IEJ1ZmZlci5jb25jYXQoXG4gICAgICBwcmVwYXJlZElucHV0cy5tYXAoKHsgcHVia2V5QnVmLCBwcmVPdXRQb2ludEJ1Ziwgc2VxdWVuY2VCdWYgfSkgPT4ge1xuICAgICAgICBpZiAocmVkZWVtU2NyaXB0VHlwZSA9PT0gU2NyaXB0VHlwZS5QMlNIX1AyV1BLSCkge1xuICAgICAgICAgIGNvbnN0IHsgb3V0U2NyaXB0IH0gPSBwdWJrZXlUb0FkZHJlc3NBbmRPdXRTY3JpcHQocHVia2V5QnVmLCBTY3JpcHRUeXBlLlAyV1BLSCk7XG4gICAgICAgICAgY29uc3QgaW5TY3JpcHQgPSBCdWZmZXIuY29uY2F0KFtCdWZmZXIuZnJvbShvdXRTY3JpcHQubGVuZ3RoLnRvU3RyaW5nKDE2KSwgJ2hleCcpLCBvdXRTY3JpcHRdKTtcbiAgICAgICAgICByZXR1cm4gQnVmZmVyLmNvbmNhdChbcHJlT3V0UG9pbnRCdWYsIHZhcnVpbnQuZW5jb2RlKGluU2NyaXB0Lmxlbmd0aCksIGluU2NyaXB0LCBzZXF1ZW5jZUJ1Zl0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBCdWZmZXIuY29uY2F0KFtwcmVPdXRQb2ludEJ1ZiwgQnVmZmVyLmZyb20oJzAwJywgJ2hleCcpLCBzZXF1ZW5jZUJ1Zl0pO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICk7XG5cbiAgICByZXR1cm4gQnVmZmVyLmNvbmNhdChbXG4gICAgICB2ZXJzaW9uQnVmLFxuICAgICAgZmxhZ0J1ZixcbiAgICAgIGlucHV0c0NvdW50LFxuICAgICAgaW5wdXRzQnVmLFxuICAgICAgb3V0cHV0c0NvdW50LFxuICAgICAgb3V0cHV0c0J1ZixcbiAgICAgIHNlZ3dpdEJ1ZixcbiAgICAgIGxvY2tUaW1lQnVmLFxuICAgIF0pO1xuICB9XG59XG4iXX0=