UNPKG

@coolwallet/xrp

Version:
445 lines (347 loc) 50 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.getIouTransferArgument = exports.getTrustSetArgument = exports.encodeIouAmount = exports.mantissaToBitBytes = exports.MANTISSA_BIT_LENGTH = exports.getMessageArgument = exports.getPaymentArgument = exports.encodeMemoField = exports.toRlpBytes = exports.toHexValue = void 0; var _core = require("@coolwallet/core"); var params = _interopRequireWildcard(require("../config/params")); var stringUtil = _interopRequireWildcard(require("./stringUtil")); var txUtil = _interopRequireWildcard(require("./tracsactionUtil")); var _rlp = _interopRequireDefault(require("rlp")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } 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 _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _iterableToArrayLimit(arr, i) { var _i = arr && (typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]); if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } var toHexValue = function toHexValue(value, byteLength) { var rawHex = typeof value === 'string' ? stringUtil.removeHex0x(value.trim()) : BigInt(value).toString(16); if (rawHex.startsWith('-')) { throw new Error("Negative value is not supported: ".concat(value)); } var normalizedHex = stringUtil.handleHex(rawHex); if (!byteLength) return normalizedHex; var targetLength = byteLength * 2; if (normalizedHex.length > targetLength) { throw new Error("Value exceeds ".concat(byteLength, " bytes: ").concat(value)); } return normalizedHex.padStart(targetLength, '0'); }; exports.toHexValue = toHexValue; var toRlpBytes = function toRlpBytes(value, byteLength) { if (value === undefined) { return Uint8Array.from(Buffer.from('', 'hex')); } return Uint8Array.from(Buffer.from(toHexValue(value, byteLength), 'hex')); }; exports.toRlpBytes = toRlpBytes; var encodeMemoField = function encodeMemoField(value) { if (value === undefined) { return Uint8Array.from(Buffer.from('', 'hex')); } var dataHex = stringUtil.handleHex(stringUtil.removeHex0x(value)); var dataLengthHex = toHexValue(dataHex.length / 2); return Uint8Array.from(Buffer.from(dataLengthHex + dataHex, 'hex')); }; exports.encodeMemoField = encodeMemoField; var getPaymentArgument = /*#__PURE__*/function () { var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(addressIndex, payment, newScript) { var SEPath, argument, transaction, memos, _payment$Memos$, memo; return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.t0 = "15"; _context.next = 3; return _core.utils.getPath(params.COIN_TYPE, addressIndex); case 3: _context.t1 = _context.sent; SEPath = _context.t0.concat.call(_context.t0, _context.t1); if (!(!payment.Account || !payment.SigningPubKey)) { _context.next = 7; break; } throw new Error('Account or SigningPubKey is not set'); case 7: if (newScript) { _context.next = 11; break; } argument = stringUtil.handleHex(txUtil.getAccount(payment.Account)) + stringUtil.handleHex(payment.SigningPubKey) + stringUtil.handleHex(txUtil.getAccount(payment.Destination)) + stringUtil.handleHex(BigInt(payment.Amount).toString(16).padStart(16, '0')) + stringUtil.handleHex(BigInt(payment.Fee).toString(16).padStart(16, '0')) + stringUtil.handleHex(payment.Sequence.toString(16).padStart(8, '0')) + stringUtil.handleHex(payment.LastLedgerSequence.toString(16).padStart(8, '0')) + stringUtil.handleHex(payment.DestinationTag.toString(16).padStart(8, '0')) + stringUtil.handleHex(payment.Flags.toString(16).padStart(8, '0')); _context.next = 29; break; case 11: transaction = []; transaction.push(toRlpBytes(payment.Flags, 4)); transaction.push(toRlpBytes(payment.Sequence, 4)); transaction.push(toRlpBytes(payment.DestinationTag, 4)); transaction.push(toRlpBytes(payment.LastLedgerSequence, 4)); transaction.push(toRlpBytes(parseInt(payment.Amount), 7)); transaction.push(toRlpBytes(parseInt(payment.Fee), 7)); transaction.push(toRlpBytes(payment.SigningPubKey, 33)); transaction.push(toRlpBytes(txUtil.getAccount(payment.Account), 20)); transaction.push(toRlpBytes(txUtil.getAccount(payment.Destination), 20)); memos = []; if (!payment.Memos) { _context.next = 27; break; } if (!(payment.Memos.length > 1)) { _context.next = 25; break; } throw new Error('Only one memo is supported at this time.'); case 25: memo = (_payment$Memos$ = payment.Memos[0]) === null || _payment$Memos$ === void 0 ? void 0 : _payment$Memos$.Memo; if (memo) { memos.push(encodeMemoField(memo.MemoType)); memos.push(encodeMemoField(memo.MemoData)); memos.push(encodeMemoField(memo.MemoFormat)); } case 27: transaction.push(memos); argument = Buffer.from(_rlp["default"].encode(transaction)).toString('hex'); case 29: return _context.abrupt("return", SEPath + argument); case 30: case "end": return _context.stop(); } } }, _callee); })); return function getPaymentArgument(_x, _x2, _x3) { return _ref.apply(this, arguments); }; }(); exports.getPaymentArgument = getPaymentArgument; var getMessageArgument = /*#__PURE__*/function () { var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(addressIndex, message) { var SEPath, argument; return regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: _context2.t0 = "15"; _context2.next = 3; return _core.utils.getPath(params.COIN_TYPE, addressIndex); case 3: _context2.t1 = _context2.sent; SEPath = _context2.t0.concat.call(_context2.t0, _context2.t1); argument = Buffer.from(message, 'utf8').toString('hex'); return _context2.abrupt("return", SEPath + argument); case 7: case "end": return _context2.stop(); } } }, _callee2); })); return function getMessageArgument(_x4, _x5) { return _ref2.apply(this, arguments); }; }(); /** * Convert mantissa (bigint) into a 54-byte buffer where each byte represents * one bit of the 54-bit mantissa value. * * Example flow: * mantissa = 1_000_000_000_000_000n * hex = 0x038D7EA4C68000 * 54-bit binary = 000011100011010111111010100100110001101000000000000000 * each bit -> 1 byte (0 -> 0x00, 1 -> 0x01) * result = "000000000000010100000101000001010001010101000001010100010100..." * (108 hex chars / 54 bytes) */ exports.getMessageArgument = getMessageArgument; var MANTISSA_BIT_LENGTH = 54; exports.MANTISSA_BIT_LENGTH = MANTISSA_BIT_LENGTH; var mantissaToBitBytes = function mantissaToBitBytes(mantissa) { var absMantissa = mantissa < 0n ? -mantissa : mantissa; var binaryStr = absMantissa.toString(2); if (binaryStr.length > MANTISSA_BIT_LENGTH) { throw new Error("Mantissa exceeds ".concat(MANTISSA_BIT_LENGTH, " bits: ").concat(mantissa)); } var paddedBinary = binaryStr.padStart(MANTISSA_BIT_LENGTH, '0'); return paddedBinary.split('').map(function (bit) { return bit === '1' ? '01' : '00'; }).join(''); }; exports.mantissaToBitBytes = mantissaToBitBytes; var encodeIouAmount = function encodeIouAmount(amount) { var isNegative = amount.startsWith('-'); var absStr = isNegative ? amount.slice(1) : amount; var _absStr$split = absStr.split('.'), _absStr$split2 = _slicedToArray(_absStr$split, 2), intStr = _absStr$split2[0], _absStr$split2$ = _absStr$split2[1], fracStr = _absStr$split2$ === void 0 ? '' : _absStr$split2$; var cleanFrac = fracStr.replace(/0+$/, ''); var mantissa = BigInt(intStr + cleanFrac); var exponent = -cleanFrac.length; if (mantissa === 0n) { return { mantissa: 0n, exponent: 0, encoded: '8000000000000000' }; } while (mantissa % 10n === 0n) { mantissa /= 10n; exponent += 1; } var minMantissa = 1000000000000000n; // 10^15 var maxMantissa = 9999999999999999n; // 10^16 - 1 while (mantissa < minMantissa) { mantissa *= 10n; exponent -= 1; } while (mantissa > maxMantissa) { mantissa /= 10n; exponent += 1; } // Bit 63 = IOU marker, Bit 62 = sign, Bits 54-61 = exponent+97, Bits 0-53 = mantissa var encoded = 1n << 63n; if (!isNegative) encoded |= 1n << 62n; encoded |= BigInt(exponent + 97) << 54n; encoded |= mantissa; return { mantissa: isNegative ? -mantissa : mantissa, exponent: exponent, encoded: encoded.toString(16).padStart(16, '0').toUpperCase() }; }; exports.encodeIouAmount = encodeIouAmount; var getTrustSetArgument = /*#__PURE__*/function () { var _ref3 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(addressIndex, payment, isRLUSD) { var SEPath, _encodeIouAmount, encoded, transaction, token, tokenNameLength, tokenNameHex, issuerHex, tokenInfo, argument; return regeneratorRuntime.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: _context3.t0 = "15"; _context3.next = 3; return _core.utils.getPath(params.COIN_TYPE, addressIndex); case 3: _context3.t1 = _context3.sent; SEPath = _context3.t0.concat.call(_context3.t0, _context3.t1); if (!(!payment.Account || !payment.SigningPubKey)) { _context3.next = 7; break; } throw new Error('Account or SigningPubKey is not set'); case 7: _encodeIouAmount = encodeIouAmount(payment.Token.value), encoded = _encodeIouAmount.encoded; transaction = []; transaction.push(toRlpBytes(payment.Flags, 4)); transaction.push(toRlpBytes(payment.Sequence, 4)); transaction.push(toRlpBytes(payment.DestinationTag, 4)); transaction.push(toRlpBytes(payment.LastLedgerSequence, 4)); transaction.push(toRlpBytes(encoded, 8)); transaction.push(toRlpBytes(parseInt(payment.Fee), 7)); transaction.push(toRlpBytes(payment.SigningPubKey, 33)); transaction.push(toRlpBytes(txUtil.getAccount(payment.Account), 20)); if (!isRLUSD) { token = payment.Token; tokenNameLength = toHexValue(token.name.length, 1); tokenNameHex = Buffer.from(token.name, 'ascii').toString('hex').padEnd(14, '0').toUpperCase(); issuerHex = txUtil.getAccount(token.issuer); tokenInfo = tokenNameLength + tokenNameHex + token.code + issuerHex; transaction.push(toRlpBytes(tokenInfo, 48)); } argument = Buffer.from(_rlp["default"].encode(transaction)).toString('hex'); return _context3.abrupt("return", SEPath + argument); case 20: case "end": return _context3.stop(); } } }, _callee3); })); return function getTrustSetArgument(_x6, _x7, _x8) { return _ref3.apply(this, arguments); }; }(); exports.getTrustSetArgument = getTrustSetArgument; var getIouTransferArgument = /*#__PURE__*/function () { var _ref4 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4(addressIndex, payment, isRLUSD) { var SEPath, _encodeIouAmount2, mantissa, exponent, mantissaHex, mantissaBytes, transaction, memos, _payment$Memos$2, memo, token, tokenNameLength, tokenNameHex, issuerHex, tokenInfo, argument; return regeneratorRuntime.wrap(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: _context4.t0 = "15"; _context4.next = 3; return _core.utils.getPath(params.COIN_TYPE, addressIndex); case 3: _context4.t1 = _context4.sent; SEPath = _context4.t0.concat.call(_context4.t0, _context4.t1); if (!(!payment.Account || !payment.SigningPubKey)) { _context4.next = 7; break; } throw new Error('Account or SigningPubKey is not set'); case 7: _encodeIouAmount2 = encodeIouAmount(payment.Token.value), mantissa = _encodeIouAmount2.mantissa, exponent = _encodeIouAmount2.exponent; console.log('mantissa', mantissa); console.log('exponent', exponent); mantissaHex = mantissaToBitBytes(mantissa); mantissaBytes = Uint8Array.from(Buffer.from(mantissaHex, 'hex')); transaction = []; transaction.push(toRlpBytes(payment.Flags, 4)); transaction.push(toRlpBytes(payment.Sequence, 4)); transaction.push(toRlpBytes(payment.DestinationTag, 4)); transaction.push(toRlpBytes(payment.LastLedgerSequence, 4)); transaction.push(mantissaBytes); transaction.push(toRlpBytes(exponent * -1, 1)); transaction.push(toRlpBytes(parseInt(payment.Fee), 7)); transaction.push(toRlpBytes(payment.SigningPubKey, 33)); transaction.push(toRlpBytes(txUtil.getAccount(payment.Account), 20)); transaction.push(toRlpBytes(txUtil.getAccount(payment.Destination), 20)); memos = []; if (!payment.Memos) { _context4.next = 29; break; } if (!(payment.Memos.length > 1)) { _context4.next = 27; break; } throw new Error('Only one memo is supported at this time.'); case 27: memo = (_payment$Memos$2 = payment.Memos[0]) === null || _payment$Memos$2 === void 0 ? void 0 : _payment$Memos$2.Memo; if (memo) { memos.push(encodeMemoField(memo.MemoType)); memos.push(encodeMemoField(memo.MemoData)); memos.push(encodeMemoField(memo.MemoFormat)); } case 29: transaction.push(memos); if (!isRLUSD) { token = payment.Token; tokenNameLength = toHexValue(token.name.length, 1); tokenNameHex = Buffer.from(token.name, 'ascii').toString('hex').padEnd(14, '0').toUpperCase(); issuerHex = txUtil.getAccount(token.issuer); tokenInfo = tokenNameLength + tokenNameHex + token.code + issuerHex; transaction.push(toRlpBytes(tokenInfo, 48)); } argument = Buffer.from(_rlp["default"].encode(transaction)).toString('hex'); return _context4.abrupt("return", SEPath + argument); case 33: case "end": return _context4.stop(); } } }, _callee4); })); return function getIouTransferArgument(_x9, _x10, _x11) { return _ref4.apply(this, arguments); }; }(); exports.getIouTransferArgument = getIouTransferArgument; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9zY3JpcHRVdGlsLnRzIl0sIm5hbWVzIjpbInRvSGV4VmFsdWUiLCJ2YWx1ZSIsImJ5dGVMZW5ndGgiLCJyYXdIZXgiLCJzdHJpbmdVdGlsIiwicmVtb3ZlSGV4MHgiLCJ0cmltIiwiQmlnSW50IiwidG9TdHJpbmciLCJzdGFydHNXaXRoIiwiRXJyb3IiLCJub3JtYWxpemVkSGV4IiwiaGFuZGxlSGV4IiwidGFyZ2V0TGVuZ3RoIiwibGVuZ3RoIiwicGFkU3RhcnQiLCJ0b1JscEJ5dGVzIiwidW5kZWZpbmVkIiwiVWludDhBcnJheSIsImZyb20iLCJCdWZmZXIiLCJlbmNvZGVNZW1vRmllbGQiLCJkYXRhSGV4IiwiZGF0YUxlbmd0aEhleCIsImdldFBheW1lbnRBcmd1bWVudCIsImFkZHJlc3NJbmRleCIsInBheW1lbnQiLCJuZXdTY3JpcHQiLCJ1dGlscyIsImdldFBhdGgiLCJwYXJhbXMiLCJDT0lOX1RZUEUiLCJTRVBhdGgiLCJBY2NvdW50IiwiU2lnbmluZ1B1YktleSIsImFyZ3VtZW50IiwidHhVdGlsIiwiZ2V0QWNjb3VudCIsIkRlc3RpbmF0aW9uIiwiQW1vdW50IiwiRmVlIiwiU2VxdWVuY2UiLCJMYXN0TGVkZ2VyU2VxdWVuY2UiLCJEZXN0aW5hdGlvblRhZyIsIkZsYWdzIiwidHJhbnNhY3Rpb24iLCJwdXNoIiwicGFyc2VJbnQiLCJtZW1vcyIsIk1lbW9zIiwibWVtbyIsIk1lbW8iLCJNZW1vVHlwZSIsIk1lbW9EYXRhIiwiTWVtb0Zvcm1hdCIsInJscCIsImVuY29kZSIsImdldE1lc3NhZ2VBcmd1bWVudCIsIm1lc3NhZ2UiLCJNQU5USVNTQV9CSVRfTEVOR1RIIiwibWFudGlzc2FUb0JpdEJ5dGVzIiwibWFudGlzc2EiLCJhYnNNYW50aXNzYSIsImJpbmFyeVN0ciIsInBhZGRlZEJpbmFyeSIsInNwbGl0IiwibWFwIiwiYml0Iiwiam9pbiIsImVuY29kZUlvdUFtb3VudCIsImFtb3VudCIsImlzTmVnYXRpdmUiLCJhYnNTdHIiLCJzbGljZSIsImludFN0ciIsImZyYWNTdHIiLCJjbGVhbkZyYWMiLCJyZXBsYWNlIiwiZXhwb25lbnQiLCJlbmNvZGVkIiwibWluTWFudGlzc2EiLCJtYXhNYW50aXNzYSIsInRvVXBwZXJDYXNlIiwiZ2V0VHJ1c3RTZXRBcmd1bWVudCIsImlzUkxVU0QiLCJUb2tlbiIsInRva2VuIiwidG9rZW5OYW1lTGVuZ3RoIiwibmFtZSIsInRva2VuTmFtZUhleCIsInBhZEVuZCIsImlzc3VlckhleCIsImlzc3VlciIsInRva2VuSW5mbyIsImNvZGUiLCJnZXRJb3VUcmFuc2ZlckFyZ3VtZW50IiwiY29uc29sZSIsImxvZyIsIm1hbnRpc3NhSGV4IiwibWFudGlzc2FCeXRlcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQUE7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUtPLElBQU1BLFVBQVUsR0FBRyxTQUFiQSxVQUFhLENBQUNDLEtBQUQsRUFBa0JDLFVBQWxCLEVBQWtEO0FBQzFFLE1BQU1DLE1BQU0sR0FBRyxPQUFPRixLQUFQLEtBQWlCLFFBQWpCLEdBQTRCRyxVQUFVLENBQUNDLFdBQVgsQ0FBdUJKLEtBQUssQ0FBQ0ssSUFBTixFQUF2QixDQUE1QixHQUFtRUMsTUFBTSxDQUFDTixLQUFELENBQU4sQ0FBY08sUUFBZCxDQUF1QixFQUF2QixDQUFsRjs7QUFFQSxNQUFJTCxNQUFNLENBQUNNLFVBQVAsQ0FBa0IsR0FBbEIsQ0FBSixFQUE0QjtBQUMxQixVQUFNLElBQUlDLEtBQUosNENBQThDVCxLQUE5QyxFQUFOO0FBQ0Q7O0FBRUQsTUFBTVUsYUFBYSxHQUFHUCxVQUFVLENBQUNRLFNBQVgsQ0FBcUJULE1BQXJCLENBQXRCO0FBQ0EsTUFBSSxDQUFDRCxVQUFMLEVBQWlCLE9BQU9TLGFBQVA7QUFFakIsTUFBTUUsWUFBWSxHQUFHWCxVQUFVLEdBQUcsQ0FBbEM7O0FBQ0EsTUFBSVMsYUFBYSxDQUFDRyxNQUFkLEdBQXVCRCxZQUEzQixF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RCxLQUFLLENBQUNNLE1BQXhCLENBSk47QUFLTkMsY0FBQUEsU0FMTSxHQUtNTixlQUFlLEdBQUdFLFlBQWxCLEdBQWlDSCxLQUFLLENBQUNRLElBQXZDLEdBQThDSCxTQUxwRDtBQU1aOUMsY0FBQUEsV0FBVyxDQUFDQyxJQUFaLENBQWlCOUIsVUFBVSxDQUFDNkUsU0FBRCxFQUFZLEVBQVosQ0FBM0I7QUFDRDs7QUFFSzFELFlBQUFBLFFBbEQ4QixHQWtEbkJmLE1BQU0sQ0FBQ0QsSUFBUCxDQUFZb0MsZ0JBQUlDLE1BQUosQ0FBV1gsV0FBWCxDQUFaLEVBQXFDckMsUUFBckMsQ0FBOEMsS0FBOUMsQ0FsRG1CO0FBQUEsOENBbUQ3QndCLE1BQU0sR0FBR0csUUFuRG9COztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEdBQUg7O0FBQUEsa0JBQXRCNEQsc0JBQXNCO0FBQUE7QUFBQTtBQUFBLEdBQTVCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgdXRpbHMgfSBmcm9tICdAY29vbHdhbGxldC9jb3JlJztcbmltcG9ydCAqIGFzIHR5cGVzIGZyb20gJy4uL2NvbmZpZy90eXBlcyc7XG5pbXBvcnQgKiBhcyBwYXJhbXMgZnJvbSAnLi4vY29uZmlnL3BhcmFtcyc7XG5pbXBvcnQgKiBhcyBzdHJpbmdVdGlsIGZyb20gJy4vc3RyaW5nVXRpbCc7XG5pbXBvcnQgKiBhcyB0eFV0aWwgZnJvbSAnLi90cmFjc2FjdGlvblV0aWwnO1xuaW1wb3J0IHJscCBmcm9tICdybHAnO1xuXG50eXBlIEhleElucHV0ID0gc3RyaW5nIHwgbnVtYmVyO1xudHlwZSBQYXltZW50SW5wdXQgPSBIZXhJbnB1dCB8IHVuZGVmaW5lZDtcblxuZXhwb3J0IGNvbnN0IHRvSGV4VmFsdWUgPSAodmFsdWU6IEhleElucHV0LCBieXRlTGVuZ3RoPzogbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgY29uc3QgcmF3SGV4ID0gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyA/IHN0cmluZ1V0aWwucmVtb3ZlSGV4MHgodmFsdWUudHJpbSgpKSA6IEJpZ0ludCh2YWx1ZSkudG9TdHJpbmcoMTYpO1xuXG4gIGlmIChyYXdIZXguc3RhcnRzV2l0aCgnLScpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBOZWdhdGl2ZSB2YWx1ZSBpcyBub3Qgc3VwcG9ydGVkOiAke3ZhbHVlfWApO1xuICB9XG5cbiAgY29uc3Qgbm9ybWFsaXplZEhleCA9IHN0cmluZ1V0aWwuaGFuZGxlSGV4KHJhd0hleCk7XG4gIGlmICghYnl0ZUxlbmd0aCkgcmV0dXJuIG5vcm1hbGl6ZWRIZXg7XG5cbiAgY29uc3QgdGFyZ2V0TGVuZ3RoID0gYnl0ZUxlbmd0aCAqIDI7XG4gIGlmIChub3JtYWxpemVkSGV4Lmxlbmd0aCA+IHRhcmdldExlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVmFsdWUgZXhjZWVkcyAke2J5dGVMZW5ndGh9IGJ5dGVzOiAke3ZhbHVlfWApO1xuICB9XG5cbiAgcmV0dXJuIG5vcm1hbGl6ZWRIZXgucGFkU3RhcnQodGFyZ2V0TGVuZ3RoLCAnMCcpO1xufTtcblxuZXhwb3J0IGNvbnN0IHRvUmxwQnl0ZXMgPSAodmFsdWU6IFBheW1lbnRJbnB1dCwgYnl0ZUxlbmd0aD86IG51bWJlcik6IFVpbnQ4QXJyYXkgPT4ge1xuICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBVaW50OEFycmF5LmZyb20oQnVmZmVyLmZyb20oJycsICdoZXgnKSk7XG4gIH1cbiAgcmV0dXJuIFVpbnQ4QXJyYXkuZnJvbShCdWZmZXIuZnJvbSh0b0hleFZhbHVlKHZhbHVlLCBieXRlTGVuZ3RoKSwgJ2hleCcpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBlbmNvZGVNZW1vRmllbGQgPSAodmFsdWU/OiBzdHJpbmcpOiBVaW50OEFycmF5ID0+IHtcbiAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gVWludDhBcnJheS5mcm9tKEJ1ZmZlci5mcm9tKCcnLCAnaGV4JykpO1xuICB9XG5cbiAgY29uc3QgZGF0YUhleCA9IHN0cmluZ1V0aWwuaGFuZGxlSGV4KHN0cmluZ1V0aWwucmVtb3ZlSGV4MHgodmFsdWUpKTtcbiAgY29uc3QgZGF0YUxlbmd0aEhleCA9IHRvSGV4VmFsdWUoZGF0YUhleC5sZW5ndGggLyAyKTtcbiAgcmV0dXJuIFVpbnQ4QXJyYXkuZnJvbShCdWZmZXIuZnJvbShkYXRhTGVuZ3RoSGV4ICsgZGF0YUhleCwgJ2hleCcpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRQYXltZW50QXJndW1lbnQgPSBhc3luYyAoXG4gIGFkZHJlc3NJbmRleDogbnVtYmVyLFxuICBwYXltZW50OiB0eXBlcy5QYXltZW50LFxuICBuZXdTY3JpcHQ6IGJvb2xlYW5cbik6IFByb21pc2U8c3RyaW5nPiA9PiB7XG4gIGNvbnN0IFNFUGF0aCA9IGAxNSR7YXdhaXQgdXRpbHMuZ2V0UGF0aChwYXJhbXMuQ09JTl9UWVBFLCBhZGRyZXNzSW5kZXgpfWA7XG4gIGlmICghcGF5bWVudC5BY2NvdW50IHx8ICFwYXltZW50LlNpZ25pbmdQdWJLZXkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0FjY291bnQgb3IgU2lnbmluZ1B1YktleSBpcyBub3Qgc2V0Jyk7XG4gIH1cbiAgbGV0IGFyZ3VtZW50O1xuICBpZiAoIW5ld1NjcmlwdCkge1xuICAgIGFyZ3VtZW50ID1cbiAgICAgIHN0cmluZ1V0aWwuaGFuZGxlSGV4KHR4VXRpbC5nZXRBY2NvdW50KHBheW1lbnQuQWNjb3VudCkpICtcbiAgICAgIHN0cmluZ1V0aWwuaGFuZGxlSGV4KHBheW1lbnQuU2lnbmluZ1B1YktleSkgK1xuICAgICAgc3RyaW5nVXRpbC5oYW5kbGVIZXgodHhVdGlsLmdldEFjY291bnQocGF5bWVudC5EZXN0aW5hdGlvbikpICtcbiAgICAgIHN0cmluZ1V0aWwuaGFuZGxlSGV4KEJpZ0ludChwYXltZW50LkFtb3VudCkudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDE2LCAnMCcpKSArXG4gICAgICBzdHJpbmdVdGlsLmhhbmRsZUhleChCaWdJbnQocGF5bWVudC5GZWUpLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgxNiwgJzAnKSkgK1xuICAgICAgc3RyaW5nVXRpbC5oYW5kbGVIZXgocGF5bWVudC5TZXF1ZW5jZS50b1N0cmluZygxNikucGFkU3RhcnQoOCwgJzAnKSkgK1xuICAgICAgc3RyaW5nVXRpbC5oYW5kbGVIZXgocGF5bWVudC5MYXN0TGVkZ2VyU2VxdWVuY2UudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDgsICcwJykpICtcbiAgICAgIHN0cmluZ1V0aWwuaGFuZGxlSGV4KHBheW1lbnQuRGVzdGluYXRpb25UYWchLnRvU3RyaW5nKDE2KS5wYWRTdGFydCg4LCAnMCcpKSArXG4gICAgICBzdHJpbmdVdGlsLmhhbmRsZUhleChwYXltZW50LkZsYWdzIS50b1N0cmluZygxNikucGFkU3RhcnQoOCwgJzAnKSk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgdHJhbnNhY3Rpb246IEFycmF5PFVpbnQ4QXJyYXkgfCBVaW50OEFycmF5W10+ID0gW107XG4gICAgdHJhbnNhY3Rpb24ucHVzaCh0b1JscEJ5dGVzKHBheW1lbnQuRmxhZ3MsIDQpKTtcbiAgICB0cmFuc2FjdGlvbi5wdXNoKHRvUmxwQnl0ZXMocGF5bWVudC5TZXF1ZW5jZSwgNCkpO1xuICAgIHRyYW5zYWN0aW9uLnB1c2godG9SbHBCeXRlcyhwYXltZW50LkRlc3RpbmF0aW9uVGFnLCA0KSk7XG4gICAgdHJhbnNhY3Rpb24ucHVzaCh0b1JscEJ5dGVzKHBheW1lbnQuTGFzdExlZGdlclNlcXVlbmNlLCA0KSk7XG4gICAgdHJhbnNhY3Rpb24ucHVzaCh0b1JscEJ5dGVzKHBhcnNlSW50KHBheW1lbnQuQW1vdW50KSwgNykpO1xuICAgIHRyYW5zYWN0aW9uLnB1c2godG9SbHBCeXRlcyhwYXJzZUludChwYXltZW50LkZlZSksIDcpKTtcbiAgICB0cmFuc2FjdGlvbi5wdXNoKHRvUmxwQnl0ZXMocGF5bWVudC5TaWduaW5nUHViS2V5LCAzMykpO1xuICAgIHRyYW5zYWN0aW9uLnB1c2godG9SbHBCeXRlcyh0eFV0aWwuZ2V0QWNjb3VudChwYXltZW50LkFjY291bnQpLCAyMCkpO1xuICAgIHRyYW5zYWN0aW9uLnB1c2godG9SbHBCeXRlcyh0eFV0aWwuZ2V0QWNjb3VudChwYXltZW50LkRlc3RpbmF0aW9uKSwgMjApKTtcbiAgICBjb25zdCBtZW1vczogVWludDhBcnJheVtdID0gW107XG4gICAgaWYgKHBheW1lbnQuTWVtb3MpIHtcbiAgICAgIGlmIChwYXltZW50Lk1lbW9zLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdPbmx5IG9uZSBtZW1vIGlzIHN1cHBvcnRlZCBhdCB0aGlzIHRpbWUuJyk7XG4gICAgICB9XG4gICAgICBjb25zdCBtZW1vID0gcGF5bWVudC5NZW1vc1swXT8uTWVtbztcbiAgICAgIGlmIChtZW1vKSB7XG4gICAgICAgIG1lbW9zLnB1c2goZW5jb2RlTWVtb0ZpZWxkKG1lbW8uTWVtb1R5cGUpKTtcbiAgICAgICAgbWVtb3MucHVzaChlbmNvZGVNZW1vRmllbGQobWVtby5NZW1vRGF0YSkpO1xuICAgICAgICBtZW1vcy5wdXNoKGVuY29kZU1lbW9GaWVsZChtZW1vLk1lbW9Gb3JtYXQpKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdHJhbnNhY3Rpb24ucHVzaChtZW1vcyk7XG4gICAgYXJndW1lbnQgPSBCdWZmZXIuZnJvbShybHAuZW5jb2RlKHRyYW5zYWN0aW9uKSkudG9TdHJpbmcoJ2hleCcpO1xuICB9XG4gIHJldHVybiBTRVBhdGggKyBhcmd1bWVudDtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRNZXNzYWdlQXJndW1lbnQgPSBhc3luYyAoYWRkcmVzc0luZGV4OiBudW1iZXIsIG1lc3NhZ2U6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiA9PiB7XG4gIGNvbnN0IFNFUGF0aCA9IGAxNSR7YXdhaXQgdXRpbHMuZ2V0UGF0aChwYXJhbXMuQ09JTl9UWVBFLCBhZGRyZXNzSW5kZXgpfWA7XG4gIGNvbnN0IGFyZ3VtZW50ID0gQnVmZmVyLmZyb20obWVzc2FnZSwgJ3V0ZjgnKS50b1N0cmluZygnaGV4Jyk7XG4gIHJldHVybiBTRVBhdGggKyBhcmd1bWVudDtcbn07XG5cbi8qKlxuICogQ29udmVydCBtYW50aXNzYSAoYmlnaW50KSBpbnRvIGEgNTQtYnl0ZSBidWZmZXIgd2hlcmUgZWFjaCBieXRlIHJlcHJlc2VudHNcbiAqIG9uZSBiaXQgb2YgdGhlIDU0LWJpdCBtYW50aXNzYSB2YWx1ZS5cbiAqXG4gKiBFeGFtcGxlIGZsb3c6XG4gKiAgIG1hbnRpc3NhID0gMV8wMDBfMDAwXzAwMF8wMDBfMDAwblxuICogICBoZXggICAgICA9IDB4MDM4RDdFQTRDNjgwMDBcbiAqICAgNTQtYml0IGJpbmFyeSA9IDAwMDAxMTEwMDAxMTAxMDExMTExMTAxMDEwMDEwMDExMDAwMTEwMTAwMDAwMDAwMDAwMDAwMFxuICogICBlYWNoIGJpdCAtPiAxIGJ5dGUgKDAgLT4gMHgwMCwgMSAtPiAweDAxKVxuICogICByZXN1bHQgICA9IFwiMDAwMDAwMDAwMDAwMDEwMTAwMDAwMTAxMDAwMDAxMDEwMDAxMDEwMTAxMDAwMDAxMDEwMTAwMDEwMTAwLi4uXCJcbiAqICAgICAgICAgICAgICAoMTA4IGhleCBjaGFycyAvIDU0IGJ5dGVzKVxuICovXG5leHBvcnQgY29uc3QgTUFOVElTU0FfQklUX0xFTkdUSCA9IDU0O1xuXG5leHBvcnQgY29uc3QgbWFudGlzc2FUb0JpdEJ5dGVzID0gKG1hbnRpc3NhOiBiaWdpbnQpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBhYnNNYW50aXNzYSA9IG1hbnRpc3NhIDwgMG4gPyAtbWFudGlzc2EgOiBtYW50aXNzYTtcbiAgY29uc3QgYmluYXJ5U3RyID0gYWJzTWFudGlzc2EudG9TdHJpbmcoMik7XG5cbiAgaWYgKGJpbmFyeVN0ci5sZW5ndGggPiBNQU5USVNTQV9CSVRfTEVOR1RIKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBNYW50aXNzYSBleGNlZWRzICR7TUFOVElTU0FfQklUX0xFTkdUSH0gYml0czogJHttYW50aXNzYX1gKTtcbiAgfVxuXG4gIGNvbnN0IHBhZGRlZEJpbmFyeSA9IGJpbmFyeVN0ci5wYWRTdGFydChNQU5USVNTQV9CSVRfTEVOR1RILCAnMCcpO1xuICByZXR1cm4gcGFkZGVkQmluYXJ5XG4gICAgLnNwbGl0KCcnKVxuICAgIC5tYXAoKGJpdCkgPT4gKGJpdCA9PT0gJzEnID8gJzAxJyA6ICcwMCcpKVxuICAgIC5qb2luKCcnKTtcbn07XG5cbmV4cG9ydCBjb25zdCBlbmNvZGVJb3VBbW91bnQgPSAoYW1vdW50OiBzdHJpbmcpOiB7IG1hbnRpc3NhOiBiaWdpbnQ7IGV4cG9uZW50OiBudW1iZXI7IGVuY29kZWQ6IHN0cmluZyB9ID0+IHtcbiAgY29uc3QgaXNOZWdhdGl2ZSA9IGFtb3VudC5zdGFydHNXaXRoKCctJyk7XG4gIGNvbnN0IGFic1N0ciA9IGlzTmVnYXRpdmUgPyBhbW91bnQuc2xpY2UoMSkgOiBhbW91bnQ7XG5cbiAgY29uc3QgW2ludFN0ciwgZnJhY1N0ciA9ICcnXSA9IGFic1N0ci5zcGxpdCgnLicpO1xuICBjb25zdCBjbGVhbkZyYWMgPSBmcmFjU3RyLnJlcGxhY2UoLzArJC8sICcnKTtcblxuICBsZXQgbWFudGlzc2EgPSBCaWdJbnQoaW50U3RyICsgY2xlYW5GcmFjKTtcbiAgbGV0IGV4cG9uZW50ID0gLWNsZWFuRnJhYy5sZW5ndGg7XG5cbiAgaWYgKG1hbnRpc3NhID09PSAwbikge1xuICAgIHJldHVybiB7IG1hbnRpc3NhOiAwbiwgZXhwb25lbnQ6IDAsIGVuY29kZWQ6ICc4MDAwMDAwMDAwMDAwMDAwJyB9O1xuICB9XG5cbiAgd2hpbGUgKG1hbnRpc3NhICUgMTBuID09PSAwbikge1xuICAgIG1hbnRpc3NhIC89IDEwbjtcbiAgICBleHBvbmVudCArPSAxO1xuICB9XG5cbiAgY29uc3QgbWluTWFudGlzc2EgPSAxMDAwMDAwMDAwMDAwMDAwbjsgLy8gMTBeMTVcbiAgY29uc3QgbWF4TWFudGlzc2EgPSA5OTk5OTk5OTk5OTk5OTk5bjsgLy8gMTBeMTYgLSAxXG5cbiAgd2hpbGUgKG1hbnRpc3NhIDwgbWluTWFudGlzc2EpIHtcbiAgICBtYW50aXNzYSAqPSAxMG47XG4gICAgZXhwb25lbnQgLT0gMTtcbiAgfVxuICB3aGlsZSAobWFudGlzc2EgPiBtYXhNYW50aXNzYSkge1xuICAgIG1hbnRpc3NhIC89IDEwbjtcbiAgICBleHBvbmVudCArPSAxO1xuICB9XG5cbiAgLy8gQml0IDYzID0gSU9VIG1hcmtlciwgQml0IDYyID0gc2lnbiwgQml0cyA1NC02MSA9IGV4cG9uZW50Kzk3LCBCaXRzIDAtNTMgPSBtYW50aXNzYVxuICBsZXQgZW5jb2RlZCA9IDFuIDw8IDYzbjtcbiAgaWYgKCFpc05lZ2F0aXZlKSBlbmNvZGVkIHw9IDFuIDw8IDYybjtcbiAgZW5jb2RlZCB8PSBCaWdJbnQoZXhwb25lbnQgKyA5NykgPDwgNTRuO1xuICBlbmNvZGVkIHw9IG1hbnRpc3NhO1xuXG4gIHJldHVybiB7XG4gICAgbWFudGlzc2E6IGlzTmVnYXRpdmUgPyAtbWFudGlzc2EgOiBtYW50aXNzYSxcbiAgICBleHBvbmVudCxcbiAgICBlbmNvZGVkOiBlbmNvZGVkLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgxNiwgJzAnKS50b1VwcGVyQ2FzZSgpLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFRydXN0U2V0QXJndW1lbnQgPSBhc3luYyAoXG4gIGFkZHJlc3NJbmRleDogbnVtYmVyLFxuICBwYXltZW50OiB0eXBlcy5Ub2tlblBheW1lbnQsXG4gIGlzUkxVU0Q6IGJvb2xlYW5cbik6IFByb21pc2U8c3RyaW5nPiA9PiB7XG4gIGNvbnN0IFNFUGF0aCA9IGAxNSR7YXdhaXQgdXRpbHMuZ2V0UGF0aChwYXJhbXMuQ09JTl9UWVBFLCBhZGRyZXNzSW5kZXgpfWA7XG4gIGlmICghcGF5bWVudC5BY2NvdW50IHx8ICFwYXltZW50LlNpZ25pbmdQdWJLZXkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0FjY291bnQgb3IgU2lnbmluZ1B1YktleSBpcyBub3Qgc2V0Jyk7XG4gIH1cbiAgY29uc3QgeyBlbmNvZGVkIH0gPSBlbmNvZGVJb3VBbW91bnQocGF5bWVudC5Ub2tlbi52YWx1ZSk7XG5cbiAgY29uc3QgdHJhbnNhY3Rpb246IEFycmF5PFVpbnQ4QXJyYXkgfCBVaW50OEFycmF5W10+ID0gW107XG4gIHRyYW5zYWN0aW9uLnB1c2godG9SbHBCeXRlcyhwYXltZW50LkZsYWdzLCA0KSk7XG4gIHRyYW5zYWN0aW9uLnB1c2godG9SbHBCeXRlcyhwYXltZW50LlNlcXVlbmNlLCA0KSk7XG4gIHRyYW5zYWN0aW9uLnB1c2godG9SbHBCeXRlcyhwYXltZW50LkRlc3RpbmF0aW9uVGFnLCA0KSk7XG4gIHRyYW5zYWN0aW9uLnB1c2godG9SbHBCeXRlcyhwYXltZW50Lkxhc3RMZWRnZXJTZXF1ZW5jZSwgNCkpO1xuICB0cmFuc2FjdGlvbi5wdXNoKHRvUmxwQnl0ZXMoZW5jb2RlZCwgOCkpO1xuICB0cmFuc2FjdGlvbi5wdXNoKHRvUmxwQnl0ZXMocGFyc2VJbnQocGF5bWVudC5GZWUpLCA3KSk7XG4gIHRyYW5zYWN0aW9uLnB1c2godG9SbHBCeXRlcyhwYXltZW50LlNpZ25pbmdQdWJLZXksIDMzKSk7XG4gIHRyYW5zYWN0aW9uLnB1c2godG9SbHBCeXRlcyh0eFV0aWwuZ2V0QWNjb3VudChwYXltZW50LkFjY291bnQpLCAyMCkpO1xuXG4gIGlmICghaXNSTFVTRCkge1xuICAgIGNvbnN0IHsgVG9rZW46IHRva2VuIH0gPSBwYXltZW50O1xuICAgIGNvbnN0IHRva2VuTmFtZUxlbmd0aCA9IHRvSGV4VmFsdWUodG9rZW4ubmFtZS5sZW5ndGgsIDEpO1xuICAgIGNvbnN0IHRva2VuTmFtZUhleCA9IEJ1ZmZlci5mcm9tKHRva2VuLm5hbWUsICdhc2NpaScpLnRvU3RyaW5nKCdoZXgnKS5wYWRFbmQoMTQsICcwJykudG9VcHBlckNhc2UoKTtcbiAgICBjb25zdCBpc3N1ZXJIZXggPSB0eFV0aWwuZ2V0QWNjb3VudCh0b2tlbi5pc3N1ZXIpO1xuICAgIGNvbnN0IHRva2VuSW5mbyA9IHRva2VuTmFtZUxlbmd0aCArIHRva2VuTmFtZUhleCArIHRva2VuLmNvZGUgKyBpc3N1ZXJIZXg7XG4gICAgdHJhbnNhY3Rpb24ucHVzaCh0b1JscEJ5dGVzKHRva2VuSW5mbywgNDgpKTtcbiAgfVxuICBjb25zdCBhcmd1bWVudCA9IEJ1ZmZlci5mcm9tKHJscC5lbmNvZGUodHJhbnNhY3Rpb24pKS50b1N0cmluZygnaGV4Jyk7XG5cbiAgcmV0dXJuIFNFUGF0aCArIGFyZ3VtZW50O1xufTtcblxuZXhwb3J0IGNvbnN0IGdldElvdVRyYW5zZmVyQXJndW1lbnQgPSBhc3luYyAoXG4gIGFkZHJlc3NJbmRleDogbnVtYmVyLFxuICBwYXltZW50OiB0eXBlcy5Jb3VUcmFuc2ZlclBheW1lbnQsXG4gIGlzUkxVU0Q6IGJvb2xlYW5cbik6IFByb21pc2U8c3RyaW5nPiA9PiB7XG4gIGNvbnN0IFNFUGF0aCA9IGAxNSR7YXdhaXQgdXRpbHMuZ2V0UGF0aChwYXJhbXMuQ09JTl9UWVBFLCBhZGRyZXNzSW5kZXgpfWA7XG4gIGlmICghcGF5bWVudC5BY2NvdW50IHx8ICFwYXltZW50LlNpZ25pbmdQdWJLZXkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0FjY291bnQgb3IgU2lnbmluZ1B1YktleSBpcyBub3Qgc2V0Jyk7XG4gIH1cblxuICBjb25zdCB7IG1hbnRpc3NhLCBleHBvbmVudCB9ID0gZW5jb2RlSW91QW1vdW50KHBheW1lbnQuVG9rZW4udmFsdWUpO1xuICBjb25zb2xlLmxvZygnbWFudGlzc2EnLCBtYW50aXNzYSk7XG4gIGNvbnNvbGUubG9nKCdleHBvbmVudCcsIGV4cG9uZW50KTtcblxuICBjb25zdCBtYW50aXNzYUhleCA9IG1hbnRpc3NhVG9CaXRCeXRlcyhtYW50aXNzYSk7XG4gIGNvbnN0IG1hbnRpc3NhQnl0ZXMgPSBVaW50OEFycmF5LmZyb20oQnVmZmVyLmZyb20obWFudGlzc2FIZXgsICdoZXgnKSk7XG5cbiAgY29uc3QgdHJhbnNhY3Rpb246IEFycmF5PFVpbnQ4QXJyYXkgfCBVaW50OEFycmF5W10+ID0gW107XG4gIHRyYW5zYWN0aW9uLnB1c2godG9SbHBCeXRlcyhwYXltZW50LkZsYWdzLCA0KSk7XG4gIHRyYW5zYWN0aW9uLnB1c2godG9SbHBCeXRlcyhwYXltZW50LlNlcXVlbmNlLCA0KSk7XG4gIHRyYW5zYWN0aW9uLnB1c2godG9SbHBCeXRlcyhwYXltZW50LkRlc3RpbmF0aW9uVGFnLCA0KSk7XG4gIHRyYW5zYWN0aW9uLnB1c2godG9SbHBCeXRlcyhwYXltZW50Lkxhc3RMZWRnZXJTZXF1ZW5jZSwgNCkpO1xuICB0cmFuc2FjdGlvbi5wdXNoKG1hbnRpc3NhQnl0ZXMpO1xuICB0cmFuc2FjdGlvbi5wdXNoKHRvUmxwQnl0ZXMoZXhwb25lbnQgKiAtMSwgMSkpO1xuICB0cmFuc2FjdGlvbi5wdXNoKHRvUmxwQnl0ZXMocGFyc2VJbnQocGF5bWVudC5GZWUpLCA3KSk7XG4gIHRyYW5zYWN0aW9uLnB1c2godG9SbHBCeXRlcyhwYXltZW50LlNpZ25pbmdQdWJLZXksIDMzKSk7XG4gIHRyYW5zYWN0aW9uLnB1c2godG9SbHBCeXRlcyh0eFV0aWwuZ2V0QWNjb3VudChwYXltZW50LkFjY291bnQpLCAyMCkpO1xuICB0cmFuc2FjdGlvbi5wdXNoKHRvUmxwQnl0ZXModHhVdGlsLmdldEFjY291bnQocGF5bWVudC5EZXN0aW5hdGlvbiksIDIwKSk7XG4gIGNvbnN0IG1lbW9zOiBVaW50OEFycmF5W10gPSBbXTtcbiAgaWYgKHBheW1lbnQuTWVtb3MpIHtcbiAgICBpZiAocGF5bWVudC5NZW1vcy5sZW5ndGggPiAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ09ubHkgb25lIG1lbW8gaXMgc3VwcG9ydGVkIGF0IHRoaXMgdGltZS4nKTtcbiAgICB9XG4gICAgY29uc3QgbWVtbyA9IHBheW1lbnQuTWVtb3NbMF0/Lk1lbW87XG4gICAgaWYgKG1lbW8pIHtcbiAgICAgIG1lbW9zLnB1c2goZW5jb2RlTWVtb0ZpZWxkKG1lbW8uTWVtb1R5cGUpKTtcbiAgICAgIG1lbW9zLnB1c2goZW5jb2RlTWVtb0ZpZWxkKG1lbW8uTWVtb0RhdGEpKTtcbiAgICAgIG1lbW9zLnB1c2goZW5jb2RlTWVtb0ZpZWxkKG1lbW8uTWVtb0Zvcm1hdCkpO1xuICAgIH1cbiAgfVxuICB0cmFuc2FjdGlvbi5wdXNoKG1lbW9zKTtcbiAgaWYgKCFpc1JMVVNEKSB7XG4gICAgY29uc3QgeyBUb2tlbjogdG9rZW4gfSA9IHBheW1lbnQ7XG4gICAgY29uc3QgdG9rZW5OYW1lTGVuZ3RoID0gdG9IZXhWYWx1ZSh0b2tlbi5uYW1lLmxlbmd0aCwgMSk7XG4gICAgY29uc3QgdG9rZW5OYW1lSGV4ID0gQnVmZmVyLmZyb20odG9rZW4ubmFtZSwgJ2FzY2lpJykudG9TdHJpbmcoJ2hleCcpLnBhZEVuZCgxNCwgJzAnKS50b1VwcGVyQ2FzZSgpO1xuICAgIGNvbnN0IGlzc3VlckhleCA9IHR4VXRpbC5nZXRBY2NvdW50KHRva2VuLmlzc3Vlcik7XG4gICAgY29uc3QgdG9rZW5JbmZvID0gdG9rZW5OYW1lTGVuZ3RoICsgdG9rZW5OYW1lSGV4ICsgdG9rZW4uY29kZSArIGlzc3VlckhleDtcbiAgICB0cmFuc2FjdGlvbi5wdXNoKHRvUmxwQnl0ZXModG9rZW5JbmZvLCA0OCkpO1xuICB9XG5cbiAgY29uc3QgYXJndW1lbnQgPSBCdWZmZXIuZnJvbShybHAuZW5jb2RlKHRyYW5zYWN0aW9uKSkudG9TdHJpbmcoJ2hleCcpO1xuICByZXR1cm4g