koopa-admin-log/configs/bank-landing/goa-amount.js
Hernâni Marques fb1a0b0b8e
landing: kGOA units, full money stats, rootless resource display
Public bank/exchange/merchant landing stats and performance UI only.
Secret goa-ui overlay stays on local/merchant-secret-ui (never push).
2026-07-17 18:13:13 +02:00

245 lines
7.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Compact GOA / CUR:amount display using SI-style alt units (kGOA, MGOA, …).
* Large values → "1.23 MGOA" (title = full GOA:n) so landing tiles fit.
*/
(function (global) {
"use strict";
var DEFAULT_ALT = {
"24": "YGOA",
"21": "ZGOA",
"18": "EGOA",
"15": "PGOA",
"12": "TGOA",
"9": "GGOA",
"6": "MGOA",
"3": "kGOA",
"0": "GOA",
"-1": "dGOA",
"-2": "cGOA",
"-3": "mGOA",
"-6": "µGOA",
"-7": "dµGOA",
"-8": "aGOA"
};
var LONG_TO_COMPACT = {
"yotta-goa": "YGOA",
"zetta-goa": "ZGOA",
"exa-goa": "EGOA",
"peta-goa": "PGOA",
"tera-goa": "TGOA",
"giga-goa": "GGOA",
"mega-goa": "MGOA",
"kilo-goa": "kGOA",
"goa": "GOA",
"deci-goa": "dGOA",
"centi-goa": "cGOA",
"milli-goa": "mGOA",
"micro-goa": "µGOA",
"deci-micro-goa": "dµGOA",
"atomic-goa": "aGOA"
};
var THRESHOLD = 1000;
function compactAlt(altMap) {
var out = {};
var src = altMap || DEFAULT_ALT;
Object.keys(DEFAULT_ALT).forEach(function (k) {
out[k] = DEFAULT_ALT[k];
});
Object.keys(src).forEach(function (k) {
var name = String(src[k] || "").trim();
var low = name.toLowerCase().replace(/\s+/g, "");
if (LONG_TO_COMPACT[low]) out[k] = LONG_TO_COMPACT[low];
else if (DEFAULT_ALT[k] && /goa/i.test(name)) out[k] = DEFAULT_ALT[k];
else out[k] = name || DEFAULT_ALT[k] || name;
});
return out;
}
function parseAmount(s) {
if (s == null || s === "") return { cur: "GOA", val: 0 };
if (typeof s === "number") return { cur: "GOA", val: s };
var t = String(s).trim();
var i = t.indexOf(":");
if (i < 0) return { cur: "GOA", val: parseFloat(t) || 0 };
return {
cur: t.slice(0, i) || "GOA",
val: parseFloat(t.slice(i + 1)) || 0
};
}
function fmtCoeff(v) {
if (!isFinite(v)) return "?";
var a = Math.abs(v);
if (Math.abs(a - Math.round(a)) < 1e-9) return String(Math.round(v));
var s = v.toFixed(4).replace(/\.?0+$/, "");
return s;
}
function baseStr(cur, val) {
if (!isFinite(val)) return String(cur) + ":?";
if (Math.abs(val - Math.round(val)) < 1e-9) return cur + ":" + Math.round(val);
return cur + ":" + String(val).replace(/(\.\d*?[1-9])0+$/, "$1").replace(/\.0+$/, "");
}
/**
* @param {string|number|object} amount
* @param {object} [altMap]
* @returns {{ display: string, title: string, raw: string, usedAlt: boolean }}
*/
function format(amount, altMap) {
if (amount == null || amount === "") {
return { display: "—", title: "", raw: "", usedAlt: false };
}
// Prefer re-format from canonical amount (keeps kGOA even if server sent Kilo-GOA)
if (typeof amount === "object" && amount) {
if (amount.amount) {
return format(amount.amount, altMap);
}
amount = amount.amount_full || amount.amount_alt || "";
}
var alt = compactAlt(altMap || global.__GOA_ALT_UNITS || DEFAULT_ALT);
var p = parseAmount(amount);
var raw = baseStr(p.cur, p.val);
var baseName = (alt && alt["0"]) || p.cur;
var curU = String(p.cur || "").toUpperCase();
var baseU = String(baseName || "").toUpperCase();
if (curU && curU !== "GOA" && (baseU === "GOA" || baseU.indexOf("GOA") !== -1)) {
return { display: raw, title: raw, raw: raw, usedAlt: false };
}
if (p.val === 0) {
return { display: raw, title: raw, raw: raw, usedAlt: false };
}
if (Math.abs(p.val) < THRESHOLD) {
return { display: raw, title: raw, raw: raw, usedAlt: false };
}
var scales = [];
Object.keys(alt || {}).forEach(function (k) {
var n = parseInt(k, 10);
if (!isNaN(n)) scales.push({ sc: n, name: String(alt[k]) });
});
scales.sort(function (a, b) {
return b.sc - a.sc;
});
var abs = Math.abs(p.val);
var chosen = null;
for (var i = 0; i < scales.length; i++) {
var unit = Math.pow(10, scales[i].sc);
if (!(unit > 0)) continue;
var coeff = abs / unit;
if (coeff >= 1) {
chosen = {
sc: scales[i].sc,
name: scales[i].name,
coeff: p.val >= 0 ? coeff : -coeff
};
break;
}
}
if (!chosen || chosen.sc === 0) {
return { display: raw, title: raw, raw: raw, usedAlt: false };
}
var short = fmtCoeff(chosen.coeff) + " " + chosen.name;
return {
display: short,
title: short + " (" + raw + ")",
raw: raw,
usedAlt: true
};
}
function setText(el, amount, altMap) {
if (!el) return;
var f = format(amount, altMap);
el.textContent = f.display;
if (f.title && f.title !== f.display) el.setAttribute("title", f.title);
else el.removeAttribute("title");
}
function setById(id, amount, altMap) {
setText(document.getElementById(id), amount, altMap);
}
/** Prefer formatting from amount field; fall back to amount_alt string. */
function pick(rowOrAmount, altMap) {
if (rowOrAmount && typeof rowOrAmount === "object") {
var a =
rowOrAmount.amount ||
rowOrAmount.total_amount ||
rowOrAmount.amount_paid_sum ||
rowOrAmount.amount_sum;
if (a) return format(a, altMap);
if (rowOrAmount.amount_alt) {
return {
display: String(rowOrAmount.amount_alt),
title: String(rowOrAmount.amount_full || rowOrAmount.amount_alt),
raw: String(rowOrAmount.amount_full || rowOrAmount.amount_alt),
usedAlt: true
};
}
return format("", altMap);
}
return format(rowOrAmount, altMap);
}
function rememberAlt(stats) {
if (stats && stats.alt_unit_names && typeof stats.alt_unit_names === "object") {
global.__GOA_ALT_UNITS = compactAlt(stats.alt_unit_names);
}
}
/** Small legend HTML (positive scales). */
function legendHtml(stats) {
var alt = compactAlt((stats && stats.alt_unit_names) || global.__GOA_ALT_UNITS || DEFAULT_ALT);
var rows = [];
Object.keys(alt)
.map(function (k) {
return parseInt(k, 10);
})
.filter(function (n) {
return !isNaN(n) && n > 0;
})
.sort(function (a, b) {
return a - b;
})
.forEach(function (sc) {
rows.push(
"<tr><td>10<sup>" +
sc +
"</sup></td><td><strong>" +
alt[String(sc)] +
"</strong></td></tr>"
);
});
if (!rows.length) return "";
return (
'<table class="unit-legend" aria-label="GOA unit names"><thead><tr><th>×base</th><th>name</th></tr></thead><tbody>' +
rows.join("") +
"</tbody></table>"
);
}
function fillLegend(elOrId, stats) {
var el = typeof elOrId === "string" ? document.getElementById(elOrId) : elOrId;
if (!el) return;
el.innerHTML = legendHtml(stats);
}
global.GoaAmount = {
format: format,
setText: setText,
setById: setById,
pick: pick,
rememberAlt: rememberAlt,
compactAlt: compactAlt,
legendHtml: legendHtml,
fillLegend: fillLegend,
DEFAULT_ALT: DEFAULT_ALT,
THRESHOLD: THRESHOLD
};
})(typeof window !== "undefined" ? window : globalThis);