@coolwallet/xrp
Version:
Coolwallet Ripple App
445 lines (347 loc) • 50 kB
JavaScript
"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