Extraction du cœur autonomie de calculs.trans-former.fr (12 modules, sans singleton, couplages sans mutation, console derrière debug), découpage en trois moteurs d'axe + intégrateur (mode global = calculs, mode par_axe = plateforme), moteurs commun.contexte (Corse 2A/2B, DOM 97x corrigés) et commun.geometrie, table des coefficients harmonisés (docs/CONSTANTES.md pour Jules, R-7), validation structurelle des données (schemas/), tests hors ligne : 28 assertions d'origine + épingle générée depuis le code d'astro-pro + écarts d'harmonisation figés + contrat des moteurs. dist/ committé. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019UBHYPdeQYy2m1GVJp6b12
49 lines
2.0 KiB
JavaScript
49 lines
2.0 KiB
JavaScript
// axes-actifs.ts — Toggles d'axes (V3 vague 1, M2)
|
|
// Produit une config dérivée où les axes désactivés ont un poids nul,
|
|
// sans toucher aux modules cœur de l'algo. La désactivation passe
|
|
// uniquement par les inputs/config (poids), conformément à la spec.
|
|
// Origine calculs/src/lib/autonomie/axes-actifs.js, inchangé (typé).
|
|
import { AXES } from './types.js';
|
|
/**
|
|
* Transforme algo-config pour neutraliser les axes désactivés.
|
|
* - poids_axes_base[axe] = 0 pour tout axe inactif
|
|
* - tous les deltas de modulateurs référençant un axe inactif sont retirés
|
|
* - marqueur `_axes_desactives` (lu par reajuste.ts pour ne pas réinjecter
|
|
* des postes optionnels dans un axe éteint lors du CAS B underspend)
|
|
*
|
|
* @param config — algo-config.json parsé (non muté)
|
|
* @returns nouvelle config
|
|
*/
|
|
export function configPourAxes(config, actifs) {
|
|
const desactives = AXES.filter((a) => actifs && actifs[a] === false);
|
|
if (desactives.length === 0)
|
|
return config;
|
|
// Clone profond (config petite, JSON-safe)
|
|
const cfg = JSON.parse(JSON.stringify(config));
|
|
cfg.poids_axes_base = cfg.poids_axes_base || { eau: 40, energie: 40, alim: 20 };
|
|
for (const axe of desactives)
|
|
cfg.poids_axes_base[axe] = 0;
|
|
// Neutraliser les deltas des modulateurs qui re-donneraient du poids
|
|
// à un axe désactivé (ex : zone MED -> eau+10, parcelle grande -> alim+10).
|
|
const mod = cfg.modulateurs || {};
|
|
for (const key of Object.keys(mod)) {
|
|
const val = mod[key];
|
|
if (val && typeof val === 'object' && !Array.isArray(val)) {
|
|
for (const axe of desactives) {
|
|
if (axe in val)
|
|
delete val[axe];
|
|
}
|
|
}
|
|
}
|
|
cfg._axes_desactives = desactives;
|
|
return cfg;
|
|
}
|
|
/**
|
|
* Vrai si au moins un axe est actif (0 axe actif = état vide géré par l'UI,
|
|
* l'algo ne doit pas tourner).
|
|
*/
|
|
export function auMoinsUnAxe(actifs) {
|
|
return AXES.some((a) => !actifs || actifs[a] !== false);
|
|
}
|
|
export { AXES };
|