Spaces:
Runtime error
Runtime error
All-neutral projective pool (multi-model consensus) + per-dimension scoring + reworded notes
4fcf639 verified | /* compute.js — VADUGWI "Read the Room" scoring. | |
| Pure, deterministic, no DOM. Sets window.RTR_COMPUTE in browser; | |
| exports for Node when run under a module loader / test harness. */ | |
| (function (root) { | |
| 'use strict'; | |
| // Maps a raw slider answer (-6..+6) to an internal 0..255 value (128 = neutral). | |
| // Ported from rtr_logic.js: extremes saturate, the center band is compressed so | |
| // a "0" reads as mild-positive-of-neutral (153), matching the original instrument. | |
| var SCALE_MAP = { | |
| '-6': 0, '-5': 0, '-4': 51, '-3': 102, '-2': 128, '-1': 140, | |
| '0': 153, '1': 166, '2': 179, '3': 204, '4': 230, '5': 255, '6': 255 | |
| }; | |
| var CATS = ['V', 'A', 'D', 'U', 'G', 'W', 'I']; | |
| function clamp(v) { | |
| return Math.round(Math.max(0, Math.min(255, v))); | |
| } | |
| function meanOf(arr) { | |
| var s = 0; | |
| for (var i = 0; i < arr.length; i++) s += arr[i]; | |
| return s / arr.length; | |
| } | |
| // All-neutral pool: every probe is a projective scene with an expected-neutral | |
| // center. There are no NEG/POS tiers anymore, so a dimension is simply how the | |
| // user COLORS those neutral scenes — the per-cat mean of their internal values. | |
| // Arousal is the exception: it reads how much neutral scenes MOVE the user | |
| // (reactivity = mean absolute deviation of raw answers from "doesn't affect me"). | |
| function computeProfile(probes, answers) { | |
| var byCat = {}; | |
| var i; | |
| for (i = 0; i < CATS.length; i++) { | |
| byCat[CATS[i]] = { raw: [], internal: [] }; | |
| } | |
| var deviations = []; | |
| for (i = 0; i < probes.length; i++) { | |
| var p = probes[i]; | |
| var raw = answers[i]; | |
| if (raw === null || raw === undefined) continue; // unanswered: skip | |
| if (!byCat[p.cat]) continue; // unknown cat: skip | |
| var internal = SCALE_MAP[String(raw)]; | |
| byCat[p.cat].raw.push(raw); | |
| byCat[p.cat].internal.push(internal); | |
| // Every probe is neutral (expected center), so the deviation IS the rating: | |
| // how strongly / which way the user colored a scene that was meant to be blank. | |
| deviations.push({ | |
| i: i, | |
| id: p.id, | |
| cat: p.cat, | |
| tier: p.tier, | |
| text: p.text, | |
| answer: raw, | |
| internal: internal, | |
| dev: raw // signed projective reaction | |
| }); | |
| } | |
| deviations.sort(function (a, b) { return Math.abs(b.dev) - Math.abs(a.dev); }); | |
| // Per-dimension projective bias: mean of internal values over that cat's | |
| // answered probes. Default 128 (true neutral) when none answered. | |
| function catMean(cat, dflt) { | |
| var bucket = byCat[cat].internal; | |
| if (!bucket.length) return dflt; | |
| return clamp(meanOf(bucket)); | |
| } | |
| var V = catMean('V', 128); | |
| var D = catMean('D', 128); | |
| var G = catMean('G', 128); | |
| var W = catMean('W', 128); | |
| var I = catMean('I', 128); | |
| // U keeps its 0-based axis meaning (Urgency starts at 0/neutral), but is now | |
| // driven purely by the per-cat mean of the answered U probes; 0 when none. | |
| var U = catMean('U', 0); | |
| // A (Arousal) = reactivity = mean ABS deviation of raw answers, mapped 0..255. | |
| // How much do neutral scenes move you, regardless of which way. | |
| var aVals = byCat.A.raw, absSum = 0; | |
| for (i = 0; i < aVals.length; i++) absSum += Math.abs(aVals[i]); | |
| var avgAbs = aVals.length ? absSum / aVals.length : 0; | |
| var A = clamp((avgAbs / 6) * 255); | |
| return { | |
| V: V, A: A, D: D, U: U, G: G, W: W, I: I, | |
| byCat: byCat, | |
| deviations: deviations | |
| }; | |
| } | |
| var api = { SCALE_MAP: SCALE_MAP, computeProfile: computeProfile }; | |
| if (typeof window !== 'undefined') window.RTR_COMPUTE = api; | |
| if (typeof module !== 'undefined' && module.exports) module.exports = api; | |
| if (typeof root !== 'undefined' && root && !root.RTR_COMPUTE) root.RTR_COMPUTE = api; | |
| })(typeof globalThis !== 'undefined' ? globalThis : this); | |