← Source tree
web_demo/inference.js
/* Original BSD-3-Clause evaluator for this project's synthetic trained forest. */
(function (root, factory) {
const api = factory();
if (typeof module === "object" && module.exports) module.exports = api;
else root.ReviewInference = api;
})(globalThis, function () {
"use strict";
function decimal(text) {
if (typeof text !== "string" || !/^[+-]?\d+(?:\.\d+)?$/.test(text.trim()))
throw new Error("Use plain decimal numbers, without commas or exponents.");
const value = Number(text);
if (!Number.isFinite(value) || Math.abs(value) > 1e15)
throw new Error("Number is outside the supported range.");
return value;
}
function score(model, amountText, quantityText) {
const amount = decimal(amountText), quantity = decimal(quantityText);
if (!(quantity > 0)) throw new Error("Quantity must be positive.");
const signedLog = n => Math.sign(n) * Math.log1p(Math.abs(n));
const original = [signedLog(amount), Math.log1p(quantity), signedLog(amount / quantity)];
if (original.some(v => !Number.isFinite(v))) throw new Error("Derived value is outside the supported range.");
// sklearn's tree traversal accepts float32 features; bounds use unrounded features.
const x = original.map(Math.fround);
let total = 0;
for (const tree of model.trees) {
let node = 0;
while (tree.left[node] !== -1) {
node = x[tree.feature[node]] <= tree.threshold[node] ? tree.left[node] : tree.right[node];
}
total += tree.leaf_depth[node];
}
const decisionScore = .5 - 2 ** (-total / (model.trees.length * model.normalizer));
const outside = original.some((v, i) => v < model.bounds[i][0] || v > model.bounds[i][1]);
return { decision_score: decisionScore, model_candidate: decisionScore < 0,
outside_reference_support: outside,
needs_review: decisionScore < 0 && outside,
notice: "Synthetic USD reference only. Score is not an error probability." };
}
return { score };
});