Een dating-app op basis van brieven, niet van gezichten!
Deze repository wordt als momentopname gepubliceerd: een clone bevat de volledige inhoud, maar geen commitgeschiedenis.
/*
* Getallen → Nederlands. Gedeeld door de twee uitvoervormen van `npm run health`: de terminal
* (scripts/health.js) en de pagina (scripts/health-html.js). Ze staan hier zodat "20 u" en
* "18% (702 van 3858)" op beide plekken hetzelfde betekenen én er hetzelfde uitzien; twee kopieën
* van een afrondingsregel is één kopie te veel.
*/
import { GENDER_LABEL } from "../src/constants.js";
export const nl = (x, d = 1) => (x == null ? "—" : x.toFixed(d).replace(".", ","));
/*
* Elk percentage draagt zijn n mee. Er wordt niets verzwegen bij kleine aantallen — 100% over twee
* mensen mag er staan, zolang die twee er ook staat. Zonder noemer een streepje, want 0/0 is geen 0%.
*/
export const pct = (n, of) => (of ? `${Math.round((n / of) * 100)}% (${n} van ${of})` : "— (geen)");
export const pctShort = (n, of) => (of ? `${Math.round((n / of) * 100)}%` : "—");
export const share = (n, of) => (of ? n / of : 0);
export const per100 = (n, of) => (of ? `${nl((n / of) * 100)} per 100` : "—");
/* Seconden → iets wat een mens leest */
export const span = (sec) => {
if (sec == null) return "—";
const h = sec / 3600;
if (h < 1) return `${Math.round(sec / 60)} min`;
if (h < 48) return `${nl(h, 0)} u`;
const d = h / 24;
if (d < 21) return `${nl(d, 0)} d`;
return `${nl(d / 7, 0)} wk`;
};
export const spanH = (h) => span(h == null ? null : h * 3600);
export const genderName = (g) => (g == null ? "iedereen" : GENDER_LABEL[g] ?? g);
export const weekLabel = (d) =>
new Date(d).toLocaleDateString("nl-NL", { day: "numeric", month: "short", year: "2-digit" });
export const dateLabel = (d) =>
new Date(d).toLocaleDateString("nl-NL", { day: "numeric", month: "long", year: "numeric" });
/*
* De wachttijdbakken, afgetopt op de horizon van --settle. Zonder die aftopping staat er "7 tot 30
* dagen" boven een telling die maar 14 dagen ver kijkt, en dat opschrift liegt dan. Bakken waarvan
* de ondergrens al voorbij de horizon ligt vallen helemaal weg: die kunnen per definitie leeg zijn.
*/
export const waitBuckets = (row, settleDays) => {
const horizon = settleDays * 24;
return [[0, 24, row.b1], [24, 72, row.b2], [72, 168, row.b3], [168, 720, row.b4], [720, Infinity, row.b5]]
.filter(([low]) => low < horizon)
.map(([low, high, n]) => {
const hi = Math.min(high, horizon) / 24;
const label = low === 0 ? (hi === 1 ? "binnen een dag" : `binnen ${nl(hi, 0)} dagen`) : `${low / 24} tot ${nl(hi, 0)} dagen`;
return { label, n: n ?? 0 };
});
};
/* De middelste waarde; bij een even aantal de laagste van de twee — geen half proefprofiel */
export const median = (xs) => (xs.length ? [...xs].sort((a, b) => a - b)[Math.floor((xs.length - 1) / 2)] : null);