UNPKG

oddslib

Version:

Odds conversion and formatting library

270 lines (266 loc) 7.51 kB
var __defProp = Object.defineProperty; var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); var __export = (target, all) => { __markAsModule(target); for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; // oddslib.mjs __export(exports, { Odds: () => Odds, from: () => from }); // approx_fraction.mjs function approximateFraction(d, precision) { var numerators = [0, 1]; var denominators = [1, 0]; var maxNumerator = getMaxNumerator(d); var d2 = d; var calcD, prevCalcD = NaN; var acceptableError = Math.pow(10, -precision) / 2; for (var i = 2; i < 1e3; i++) { var L2 = Math.floor(d2); numerators[i] = L2 * numerators[i - 1] + numerators[i - 2]; if (Math.abs(numerators[i]) > maxNumerator) return; denominators[i] = L2 * denominators[i - 1] + denominators[i - 2]; calcD = numerators[i] / denominators[i]; if (Math.abs(calcD - d) < acceptableError || calcD == prevCalcD) { return numerators[i].toString() + "/" + denominators[i].toString(); } d2 = 1 / (d2 - L2); } } function getMaxNumerator(f) { var f2 = null; var ixe = f.toString().indexOf("E"); if (ixe == -1) ixe = f.toString().indexOf("e"); if (ixe == -1) f2 = f.toString(); else f2 = f.toString().substring(0, ixe); var digits = null; var ix = f2.toString().indexOf("."); if (ix == -1) digits = f2; else if (ix === 0) digits = f2.substring(1, f2.length); else if (ix < f2.length) digits = f2.substring(0, ix) + f2.substring(ix + 1, f2.length); var L = digits; var numDigits = L.toString().length; var L2 = f; var numIntDigits = L2.toString().length; if (L2 === 0) numIntDigits = 0; var numDigitsPastDecimal = numDigits - numIntDigits; var i; for (i = numDigitsPastDecimal; i > 0 && L % 2 === 0; i--) L /= 2; for (i = numDigitsPastDecimal; i > 0 && L % 5 === 0; i--) L /= 5; return L; } // oddslib.mjs if (typeof Object.assign != "function") { Object.assign = function(target, varArgs) { "use strict"; if (target == null) { throw new TypeError("Cannot convert undefined or null to object"); } var to = Object(target); for (var index = 1; index < arguments.length; index++) { var nextSource = arguments[index]; if (nextSource != null) { for (var nextKey in nextSource) { if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { to[nextKey] = nextSource[nextKey]; } } } } return to; }; } var fixFloatError = function(n) { return parseFloat(n.toPrecision(12)); }; function decimalAdjust(type, value, exp) { if (typeof exp === "undefined" || +exp === 0) { return Math[type](value); } value = +value; exp = +exp; if (isNaN(value) || !(typeof exp === "number" && exp % 1 === 0)) { return NaN; } if (value < 0) { return -decimalAdjust(type, -value, exp); } value = value.toString().split("e"); value = Math[type](+(value[0] + "e" + (value[1] ? +value[1] - exp : -exp))); value = value.toString().split("e"); return +(value[0] + "e" + (value[1] ? +value[1] + exp : exp)); } var FORMATS = { decimal: { from: function(decimal) { decimal = parseFloat(decimal); if (decimal <= 1) { throw new Error("Outside valid range."); } return decimal; }, to: function() { return this.decimalValue; } }, moneyline: { from: function(moneyline) { moneyline = parseFloat(moneyline); if (moneyline >= 0) { return moneyline / 100 + 1; } return 100 / -moneyline + 1; }, to: function() { if (this.decimalValue >= 2) { return fixFloatError((this.decimalValue - 1) * 100); } return fixFloatError(-100 / (this.decimalValue - 1)); } }, hongKong: { from: function(hongKong) { hongKong = parseFloat(hongKong); if (hongKong < 0) { throw new Error("Outside valid range."); } return hongKong + 1; }, to: function() { return fixFloatError(this.decimalValue - 1); } }, impliedProbability: { from: function(ip) { if (typeof ip === "string" && ip.slice(-1) == "%") { ip = parseFloat(ip) / 100; } else { ip = parseFloat(ip); } if (ip <= 0 || ip >= 1) { throw new Error("Outside valid range"); } return 1 / ip; }, to: function(options) { if (options.percentage) { var value = fixFloatError(100 / this.decimalValue); if (options.precision !== null) { value = decimalAdjust("round", value, -options.precision); } return value.toString() + "%"; } return fixFloatError(1 / this.decimalValue); } }, fractional: { from: function(n) { var pieces = n.toString().split("/"); n = parseFloat(pieces[0]); var d; if (pieces.length === 2) { d = parseFloat(pieces[1]); } else if (pieces.length === 1) { d = 1; } else { throw new Error("Invalid fraction"); } if (n === 0 || d === 0 || n / d <= 0) { throw new Error("Outside valid range"); } return 1 + n / d; }, to: function(options) { return approximateFraction(this.decimalValue - 1, options.precision || 12); } }, malay: { from: function(malay) { malay = parseFloat(malay); if (malay <= -1 || malay > 1) { throw new Error("Outside valid range."); } if (malay < 0) { malay = -1 / malay; } return malay + 1; }, to: function() { if (this.decimalValue <= 2) { return fixFloatError(this.decimalValue - 1); } return fixFloatError(-1 / (this.decimalValue - 1)); } }, indonesian: { from: function(indonesian) { indonesian = parseFloat(indonesian); if (indonesian === 0) { throw new Error("Outside valid range."); } if (indonesian >= 1) { return indonesian + 1; } return -1 / indonesian + 1; }, to: function() { if (this.decimalValue < 2) { return fixFloatError(-1 / (this.decimalValue - 1)); } return fixFloatError(this.decimalValue - 1); } } }; var Odds = function() { var PublicOdds = function() { throw new Error("This constructor is private, please use the from* functions"); }; var Odds2 = function(decimalValue) { if (typeof decimalValue !== "number" || isNaN(decimalValue)) { throw new Error("Invalid odds"); } this.decimalValue = fixFloatError(decimalValue); }; Odds2.prototype = PublicOdds.prototype; PublicOdds.from = function(format, value) { if (!FORMATS.hasOwnProperty(format)) { throw new Error("Unknown format " + format + "."); } var decimal = FORMATS[format].from(value); return new Odds2(decimal); }; return PublicOdds; }(); Odds.prototype.to = function(format, options) { if (!FORMATS.hasOwnProperty(format)) { throw new Error("Unknown format " + format + "."); } options = Object.assign({ precision: null, percentage: false }, options); var ret = FORMATS[format].to.call(this, options); if (typeof ret === "number" && options.precision !== null) { ret = decimalAdjust("round", ret, -options.precision); } return ret; }; var from = Odds.from; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { Odds, from });