oddslib
Version:
Odds conversion and formatting library
270 lines (266 loc) • 7.51 kB
JavaScript
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
});