/* global window */
// ============================================================================
// MELR · Catalogue PEFA — structure officielle des cadres (statique)
// ----------------------------------------------------------------------------
// Source de vérité de la grille de notation PEFA :
//   - PEFA 2016 : 7 piliers, 31 indicateurs (PI), 94 dimensions, méthodes
//     M1 (WL, maillon le plus faible) / M2 (AV, table de conversion).
//     Extrait des cadres officiels FR (réimpression 2020) et EN (2016).
//   - GRPFM 2020 (Genre) : 9 indicateurs, 12 dimensions.
//   - CRPFM (Climat) : 14 indicateurs, 29 dimensions. Libellés extraits de
//     la version pilote FR (août 2020) — à rapprocher de la version finale
//     2024 (pefa.org/climate) lors d'une évaluation réelle.
//
// Statique et bilingue : la grille ne dépend pas du catalogue d'indicateurs
// de chaque organisation (qui peut être incomplet) ; les notes sont stockées
// dans pefa_scores par code (PI-2.1, GRPFM-1.2, CRPFM-5.3, …).
//
// Table M2 : Table 1 « Conversion table for indicator scores using the
// averaging method M2 (AV) » du cadre PEFA 2016. C'est un BARÈME officiel,
// PAS une moyenne arithmétique (ex. D-D-D-B → C alors que D-C → D+).
// ============================================================================

(function () {
  const PILLARS = [
    { num: 1, fr: "Fiabilité du budget",                en: "Budget reliability", es: "Fiabilidad del presupuesto" },
    { num: 2, fr: "Transparence des finances publiques", en: "Transparency of public finances", es: "Transparencia de las finanzas públicas" },
    { num: 3, fr: "Gestion des actifs et des passifs",  en: "Management of assets and liabilities", es: "Gestión de activos y pasivos" },
    { num: 4, fr: "Stratégie budgétaire et budgétisation fondées sur les politiques publiques", en: "Policy-based fiscal strategy and budgeting", es: "Estrategia fiscal y presupuestación basadas en políticas públicas" },
    { num: 5, fr: "Prévisibilité et contrôle de l'exécution du budget", en: "Predictability and control in budget execution", es: "Previsibilidad y control de la ejecución presupuestaria" },
    { num: 6, fr: "Comptabilité et reporting",          en: "Accounting and reporting", es: "Contabilidad y presentación de informes" },
    { num: 7, fr: "Supervision et audit externes",      en: "External scrutiny and audit", es: "Escrutinio y auditoría externos" },
  ];

  // d(suffix, fr, en, es) → dimension d'un indicateur (le code complet est
  // recomposé : <code indicateur>.<suffix>). es optionnel (repli es→en).
  const d = (s, fr, en, es) => ({ s, fr, en, es: es != null ? es : en });

  const PI = [
    { n: 1, pillar: 1, method: null, fr: "Dépenses totales exécutées", en: "Aggregate expenditure outturn", es: "Resultados del gasto agregado", dims: [
      d(1, "Dépenses totales exécutées", "Aggregate expenditure outturn", "Resultados del gasto agregado"),
    ]},
    { n: 2, pillar: 1, method: "M1", fr: "Composition des dépenses exécutées", en: "Expenditure composition outturn", es: "Resultados en la composición del gasto", dims: [
      d(1, "Composition des dépenses exécutées par fonction", "Expenditure composition outturn by function", "Resultados en la composición del gasto por función"),
      d(2, "Composition des dépenses exécutées par catégorie économique", "Expenditure composition outturn by economic type", "Resultados en la composición del gasto por clasificación económica"),
      d(3, "Dépenses imputées sur les réserves pour imprévus", "Expenditure from contingency reserves", "Gasto con cargo a las reservas para imprevistos"),
    ]},
    { n: 3, pillar: 1, method: "M2", fr: "Recettes exécutées", en: "Revenue outturn", es: "Resultados de los ingresos", dims: [
      d(1, "Recettes exécutées totales", "Aggregate revenue outturn", "Resultados de los ingresos agregados"),
      d(2, "Composition des recettes exécutées", "Revenue composition outturn", "Resultados en la composición de los ingresos"),
    ]},
    { n: 4, pillar: 2, method: null, fr: "Classification du budget", en: "Budget classification", es: "Clasificación del presupuesto", dims: [
      d(1, "Classification du budget", "Budget classification", "Clasificación del presupuesto"),
    ]},
    { n: 5, pillar: 2, method: null, fr: "Documentation budgétaire", en: "Budget documentation", es: "Documentación presupuestaria", dims: [
      d(1, "Documentation budgétaire", "Budget documentation", "Documentación presupuestaria"),
    ]},
    { n: 6, pillar: 2, method: "M2", fr: "Opérations de l'administration centrale non comptabilisées dans les états financiers", en: "Central government operations outside financial reports", es: "Operaciones del gobierno central no incluidas en los informes financieros", dims: [
      d(1, "Dépenses non comptabilisées dans les états financiers", "Expenditure outside financial reports", "Gasto no incluido en los informes financieros"),
      d(2, "Recettes non comptabilisées dans les états financiers", "Revenue outside financial reports", "Ingresos no incluidos en los informes financieros"),
      d(3, "États financiers des unités extrabudgétaires", "Financial reports of extrabudgetary units", "Informes financieros de las unidades extrapresupuestarias"),
    ]},
    { n: 7, pillar: 2, method: "M2", fr: "Transferts aux administrations infranationales", en: "Transfers to subnational governments", es: "Transferencias a los gobiernos subnacionales", dims: [
      d(1, "Système d'affectation des transferts", "System for allocating transfers", "Sistema de asignación de las transferencias"),
      d(2, "Communication en temps voulu d'informations sur les transferts", "Timeliness of information on transfers", "Puntualidad de la información sobre las transferencias"),
    ]},
    { n: 8, pillar: 2, method: "M2", fr: "Information sur la performance des services publics", en: "Performance information for service delivery", es: "Información sobre el desempeño en la prestación de servicios", dims: [
      d(1, "Plans de performance pour assurer les prestations de services", "Performance plans for service delivery", "Planes de desempeño para la prestación de servicios"),
      d(2, "Performance des fonctions de prestation de services", "Performance achieved for service delivery", "Desempeño alcanzado en la prestación de servicios"),
      d(3, "Ressources reçues par les unités opérationnelles de prestation de services", "Resources received by service delivery units", "Recursos recibidos por las unidades de prestación de servicios"),
      d(4, "Évaluation de la performance des fonctions de prestation de services", "Performance evaluation for service delivery", "Evaluación del desempeño en la prestación de servicios"),
    ]},
    { n: 9, pillar: 2, method: null, fr: "Accès public aux informations budgétaires", en: "Public access to fiscal information", es: "Acceso público a la información fiscal", dims: [
      d(1, "Accès public aux informations budgétaires", "Public access to fiscal information", "Acceso público a la información fiscal"),
    ]},
    { n: 10, pillar: 3, method: "M2", fr: "Établissement de rapports sur les risques budgétaires", en: "Fiscal risk reporting", es: "Presentación de informes sobre los riesgos fiscales", dims: [
      d(1, "Suivi des entreprises publiques", "Monitoring of public corporations", "Seguimiento de las empresas públicas"),
      d(2, "Suivi des administrations infranationales", "Monitoring of subnational governments", "Seguimiento de los gobiernos subnacionales"),
      d(3, "Passifs éventuels et autres risques budgétaires", "Contingent liabilities and other fiscal risks", "Pasivos contingentes y otros riesgos fiscales"),
    ]},
    { n: 11, pillar: 3, method: "M2", fr: "Gestion des investissements publics", en: "Public investment management", es: "Gestión de la inversión pública", dims: [
      d(1, "Analyse économique des projets d'investissement", "Economic analysis of investment proposals", "Análisis económico de las propuestas de inversión"),
      d(2, "Sélection des projets d'investissement", "Investment project selection", "Selección de los proyectos de inversión"),
      d(3, "Calcul du coût des projets d'investissement", "Investment project costing", "Cálculo de costos de los proyectos de inversión"),
      d(4, "Suivi des projets d'investissement", "Investment project monitoring", "Seguimiento de los proyectos de inversión"),
    ]},
    { n: 12, pillar: 3, method: "M2", fr: "Gestion des actifs publics", en: "Public asset management", es: "Gestión de los activos públicos", dims: [
      d(1, "Suivi des actifs financiers", "Financial asset monitoring", "Seguimiento de los activos financieros"),
      d(2, "Suivi des actifs non financiers", "Nonfinancial asset monitoring", "Seguimiento de los activos no financieros"),
      d(3, "Transparence de la cession des actifs", "Transparency of asset disposal", "Transparencia en la enajenación de activos"),
    ]},
    { n: 13, pillar: 3, method: "M2", fr: "Gestion de la dette", en: "Debt management", es: "Gestión de la deuda", dims: [
      d(1, "Enregistrement et présentation des données sur la dette et les garanties", "Recording and reporting of debt and guarantees", "Registro y presentación de informes sobre la deuda y las garantías"),
      d(2, "Autorisation d'emprunter et d'octroyer des garanties", "Approval of debt and guarantees", "Aprobación de la deuda y las garantías"),
      d(3, "Stratégie de gestion de la dette", "Debt management strategy", "Estrategia de gestión de la deuda"),
    ]},
    { n: 14, pillar: 4, method: "M2", fr: "Prévisions macroéconomiques et budgétaires", en: "Macroeconomic and fiscal forecasting", es: "Previsiones macroeconómicas y fiscales", dims: [
      d(1, "Prévisions macroéconomiques", "Macroeconomic forecasts", "Previsiones macroeconómicas"),
      d(2, "Prévisions budgétaires", "Fiscal forecasts", "Previsiones fiscales"),
      d(3, "Analyse de sensibilité macrobudgétaire", "Macrofiscal sensitivity analysis", "Análisis de sensibilidad macrofiscal"),
    ]},
    { n: 15, pillar: 4, method: "M2", fr: "Stratégie budgétaire", en: "Fiscal strategy", es: "Estrategia fiscal", dims: [
      d(1, "Impact budgétaire des politiques proposées", "Fiscal impact of policy proposals", "Impacto fiscal de las propuestas de política"),
      d(2, "Adoption de la stratégie budgétaire", "Fiscal strategy adoption", "Adopción de la estrategia fiscal"),
      d(3, "Présentation des résultats budgétaires", "Reporting on fiscal outcomes", "Presentación de informes sobre los resultados fiscales"),
    ]},
    { n: 16, pillar: 4, method: "M2", fr: "Perspectives à moyen terme de la budgétisation des dépenses", en: "Medium-term perspective in expenditure budgeting", es: "Perspectiva de mediano plazo en la presupuestación del gasto", dims: [
      d(1, "Prévisions de dépenses à moyen terme", "Medium-term expenditure estimates", "Estimaciones del gasto a mediano plazo"),
      d(2, "Plafonnement des dépenses à moyen terme", "Medium-term expenditure ceilings", "Topes del gasto a mediano plazo"),
      d(3, "Cohérence des plans stratégiques et des budgets à moyen terme", "Alignment of strategic plans and medium-term budgets", "Alineación de los planes estratégicos y los presupuestos de mediano plazo"),
      d(4, "Cohérence des budgets et des estimations de l'exercice précédent", "Consistency of budgets with previous year's estimates", "Coherencia de los presupuestos con las estimaciones del ejercicio anterior"),
    ]},
    { n: 17, pillar: 4, method: "M2", fr: "Processus de préparation du budget", en: "Budget preparation process", es: "Proceso de preparación del presupuesto", dims: [
      d(1, "Calendrier budgétaire", "Budget calendar", "Calendario presupuestario"),
      d(2, "Directives pour l'élaboration du budget", "Guidance on budget preparation", "Directrices para la preparación del presupuesto"),
      d(3, "Présentation du budget au pouvoir législatif", "Budget submission to the legislature", "Presentación del presupuesto al poder legislativo"),
    ]},
    { n: 18, pillar: 4, method: "M1", fr: "Examen des budgets par le pouvoir législatif", en: "Legislative scrutiny of budgets", es: "Escrutinio legislativo de los presupuestos", dims: [
      d(1, "Portée de l'examen des budgets", "Scope of budget scrutiny", "Alcance del escrutinio de los presupuestos"),
      d(2, "Procédures d'examen des budgets par le pouvoir législatif", "Legislative procedures for budget scrutiny", "Procedimientos legislativos para el escrutinio de los presupuestos"),
      d(3, "Calendrier d'approbation des budgets", "Timing of budget approval", "Calendario de aprobación de los presupuestos"),
      d(4, "Règles d'ajustement budgétaire par l'exécutif", "Rules for budget adjustments by the executive", "Reglas para los ajustes presupuestarios por el poder ejecutivo"),
    ]},
    { n: 19, pillar: 5, method: "M2", fr: "Gestion des recettes", en: "Revenue administration", es: "Administración de ingresos", dims: [
      d(1, "Droits et obligations en matière de recettes", "Rights and obligations for revenue measures", "Derechos y obligaciones en materia de ingresos"),
      d(2, "Gestion des risques liés aux recettes", "Revenue risk management", "Gestión de los riesgos relacionados con los ingresos"),
      d(3, "Audits et enquêtes sur les recettes", "Revenue audit and investigation", "Auditorías e investigaciones sobre los ingresos"),
      d(4, "Suivi des arriérés de recettes", "Revenue arrears monitoring", "Seguimiento de los atrasos de ingresos"),
    ]},
    { n: 20, pillar: 5, method: "M1", fr: "Comptabilisation des recettes", en: "Accounting for revenue", es: "Contabilización de los ingresos", dims: [
      d(1, "Informations sur le recouvrement des recettes", "Information on revenue collections", "Información sobre la recaudación de ingresos"),
      d(2, "Transfert des recettes recouvrées", "Transfer of revenue collections", "Transferencia de los ingresos recaudados"),
      d(3, "Rapprochement des comptes de recettes", "Revenue accounts reconciliation", "Conciliación de las cuentas de ingresos"),
    ]},
    { n: 21, pillar: 5, method: "M2", fr: "Prévisibilité de l'affectation des ressources en cours d'exercice", en: "Predictability of in-year resource allocation", es: "Previsibilidad de la asignación de recursos durante el ejercicio", dims: [
      d(1, "Consolidation des soldes de trésorerie", "Consolidation of cash balances", "Consolidación de los saldos de tesorería"),
      d(2, "Prévisions de trésorerie et suivi", "Cash forecasting and monitoring", "Previsión y seguimiento de la tesorería"),
      d(3, "Informations sur les plafonds d'engagement", "Information on commitment ceilings", "Información sobre los topes de los compromisos"),
      d(4, "Ampleur des ajustements budgétaires en cours d'exercice", "Significance of in-year budget adjustments", "Magnitud de los ajustes presupuestarios durante el ejercicio"),
    ]},
    { n: 22, pillar: 5, method: "M1", fr: "Arriérés de dépenses", en: "Expenditure arrears", es: "Atrasos en el pago de gastos", dims: [
      d(1, "Stock d'arriérés de dépenses", "Stock of expenditure arrears", "Volumen de los atrasos en el pago de gastos"),
      d(2, "Suivi des arriérés de dépenses", "Expenditure arrears monitoring", "Seguimiento de los atrasos en el pago de gastos"),
    ]},
    { n: 23, pillar: 5, method: "M1", fr: "Contrôle des états de paie", en: "Payroll controls", es: "Controles de la nómina", dims: [
      d(1, "Intégration des états de paie et des dossiers du personnel", "Integration of payroll and personnel records", "Integración de la nómina y los registros de personal"),
      d(2, "Gestion des modifications apportées aux états de paie", "Management of payroll changes", "Gestión de los cambios en la nómina"),
      d(3, "Contrôle interne des états de paie", "Internal control of payroll", "Control interno de la nómina"),
      d(4, "Audit des états de paie", "Payroll audit", "Auditoría de la nómina"),
    ]},
    { n: 24, pillar: 5, method: "M2", fr: "Passation des marchés publics", en: "Procurement", es: "Contratación pública", dims: [
      d(1, "Suivi de la passation des marchés", "Procurement monitoring", "Seguimiento de la contratación pública"),
      d(2, "Méthodes de passation des marchés", "Procurement methods", "Métodos de contratación pública"),
      d(3, "Accès du public aux informations sur la passation des marchés", "Public access to procurement information", "Acceso público a la información sobre la contratación pública"),
      d(4, "Règlement des litiges en matière de passation des marchés", "Procurement complaints management", "Gestión de las reclamaciones en materia de contratación pública"),
    ]},
    { n: 25, pillar: 5, method: "M2", fr: "Contrôles internes des dépenses non salariales", en: "Internal controls on nonsalary expenditure", es: "Controles internos del gasto no salarial", dims: [
      d(1, "Séparation des fonctions", "Segregation of duties", "Separación de funciones"),
      d(2, "Efficacité du contrôle des engagements de dépenses", "Effectiveness of expenditure commitment controls", "Eficacia de los controles de los compromisos de gasto"),
      d(3, "Respect des règles et procédures de paiement", "Compliance with payment rules and procedures", "Cumplimiento de las normas y los procedimientos de pago"),
    ]},
    { n: 26, pillar: 5, method: "M1", fr: "Audit interne", en: "Internal audit", es: "Auditoría interna", dims: [
      d(1, "Portée de l'audit interne", "Coverage of internal audit", "Alcance de la auditoría interna"),
      d(2, "Nature des audits et normes appliquées", "Nature of audits and standards applied", "Naturaleza de las auditorías y normas aplicadas"),
      d(3, "Conduite d'audits internes et rapports d'audit", "Implementation of internal audits and reporting", "Realización de auditorías internas y presentación de informes"),
      d(4, "Suite donnée aux audits internes", "Response to internal audits", "Respuesta a las auditorías internas"),
    ]},
    { n: 27, pillar: 6, method: "M2", fr: "Intégrité des données financières", en: "Financial data integrity", es: "Integridad de los datos financieros", dims: [
      d(1, "Rapprochement des comptes bancaires", "Bank account reconciliation", "Conciliación de las cuentas bancarias"),
      d(2, "Comptes d'attente", "Suspense accounts", "Cuentas transitorias"),
      d(3, "Comptes d'avances", "Advance accounts", "Cuentas de anticipos"),
      d(4, "Processus en place pour assurer l'intégrité des données financières", "Financial data integrity processes", "Procesos de integridad de los datos financieros"),
    ]},
    { n: 28, pillar: 6, method: "M1", fr: "Rapports budgétaires en cours d'exercice", en: "In-year budget reports", es: "Informes presupuestarios durante el ejercicio", dims: [
      d(1, "Portée et comparabilité des rapports", "Coverage and comparability of reports", "Alcance y comparabilidad de los informes"),
      d(2, "Calendrier de publication des rapports", "Timing of in-year budget reports", "Calendario de presentación de los informes"),
      d(3, "Exactitude des rapports", "Accuracy of in-year budget reports", "Exactitud de los informes"),
    ]},
    { n: 29, pillar: 6, method: "M1", fr: "Rapports financiers annuels", en: "Annual financial reports", es: "Informes financieros anuales", dims: [
      d(1, "Exhaustivité des rapports financiers annuels", "Completeness of annual financial reports", "Exhaustividad de los informes financieros anuales"),
      d(2, "Rapports financiers soumis à des audits externes", "Submission of reports for external audit", "Presentación de los informes para la auditoría externa"),
      d(3, "Normes comptables", "Accounting standards", "Normas contables"),
    ]},
    { n: 30, pillar: 7, method: "M1", fr: "Audit externe", en: "External audit", es: "Auditoría externa", dims: [
      d(1, "Portée de l'audit et normes d'audit", "Audit coverage and standards", "Alcance de la auditoría y normas de auditoría"),
      d(2, "Soumission des rapports d'audit au pouvoir législatif", "Submission of audit reports to the legislature", "Presentación de los informes de auditoría al poder legislativo"),
      d(3, "Suite donnée aux audits externes", "External audit follow-up", "Seguimiento de las auditorías externas"),
      d(4, "Indépendance de l'Institution supérieure de contrôle (ISC)", "Supreme Audit Institution (SAI) independence", "Independencia de la Entidad Fiscalizadora Superior (EFS)"),
    ]},
    { n: 31, pillar: 7, method: "M2", fr: "Examen des rapports d'audit par le pouvoir législatif", en: "Legislative scrutiny of audit reports", es: "Escrutinio legislativo de los informes de auditoría", dims: [
      d(1, "Calendrier d'examen des rapports d'audit", "Timing of audit report scrutiny", "Calendario del escrutinio de los informes de auditoría"),
      d(2, "Auditions sur les conclusions de l'audit", "Hearings on audit findings", "Audiencias sobre las conclusiones de la auditoría"),
      d(3, "Recommandations du pouvoir législatif concernant l'audit", "Recommendations on audit by the legislature", "Recomendaciones del poder legislativo sobre la auditoría"),
      d(4, "Transparence de l'examen des rapports d'audit par le pouvoir législatif", "Transparency of legislative scrutiny of audit reports", "Transparencia del escrutinio legislativo de los informes de auditoría"),
    ]},
  ];

  // ── Module Genre — GRPFM 2020 (9 indicateurs, 12 dimensions) ────────────
  const GRPFM = [
    { n: 1, method: "M2", fr: "Analyse de l'incidence de genre des politiques budgétaires proposées", en: "Gender impact analysis of budget policy proposals", es: "Análisis del impacto de género de las propuestas de política presupuestaria", dims: [
      d(1, "Analyse de l'incidence de genre des politiques de dépenses proposées", "Gender impact analysis of expenditure policy proposals", "Análisis del impacto de género de las propuestas de política de gasto"),
      d(2, "Analyse de l'incidence de genre des politiques de recettes proposées", "Gender impact analysis of revenue policy proposals", "Análisis del impacto de género de las propuestas de política de ingresos"),
    ]},
    { n: 2, method: null, fr: "Gestion des investissements publics sensible au genre", en: "Gender responsive public investment management", es: "Gestión de la inversión pública sensible al género", dims: [
      d(1, "Gestion des investissements publics sensible au genre", "Gender responsive public investment management", "Gestión de la inversión pública sensible al género"),
    ]},
    { n: 3, method: null, fr: "Circulaire budgétaire sensible au genre", en: "Gender responsive budget circular", es: "Circular presupuestaria sensible al género", dims: [
      d(1, "Circulaire budgétaire sensible au genre", "Gender responsive budget circular", "Circular presupuestaria sensible al género"),
    ]},
    { n: 4, method: null, fr: "Documentation sur les propositions budgétaires sensibles au genre", en: "Gender responsive budget proposal documentation", es: "Documentación de las propuestas presupuestarias sensible al género", dims: [
      d(1, "Documentation sur les propositions budgétaires sensibles au genre", "Gender responsive budget proposal documentation", "Documentación de las propuestas presupuestarias sensible al género"),
    ]},
    { n: 5, method: "M2", fr: "Ventilation par genre des informations sur la performance des services publics", en: "Sex-disaggregated performance information for service delivery", es: "Información sobre el desempeño en la prestación de servicios desagregada por sexo", dims: [
      d(1, "Plans de performance des services publics ventilés par sexe", "Sex-disaggregated performance plans for service delivery", "Planes de desempeño para la prestación de servicios desagregados por sexo"),
      d(2, "Performance réalisée des services publics ventilée par sexe", "Sex-disaggregated performance achieved for service delivery", "Desempeño alcanzado en la prestación de servicios desagregado por sexo"),
    ]},
    { n: 6, method: null, fr: "Suivi des dépenses budgétaires en faveur de l'égalité femmes-hommes", en: "Tracking budget expenditure for gender equality", es: "Seguimiento del gasto presupuestario destinado a la igualdad de género", dims: [
      d(1, "Suivi des dépenses budgétaires en faveur de l'égalité femmes-hommes", "Tracking budget expenditure for gender equality", "Seguimiento del gasto presupuestario destinado a la igualdad de género"),
    ]},
    { n: 7, method: null, fr: "Reporting sensible au genre", en: "Gender responsive reporting", es: "Presentación de informes sensible al género", dims: [
      d(1, "Reporting sensible au genre", "Gender responsive reporting", "Presentación de informes sensible al género"),
    ]},
    { n: 8, method: null, fr: "Évaluation de l'impact de genre des services publics", en: "Evaluation of gender impacts of service delivery", es: "Evaluación de los impactos de género de la prestación de servicios", dims: [
      d(1, "Évaluation de l'impact de genre des services publics", "Evaluation of gender impacts of service delivery", "Evaluación de los impactos de género de la prestación de servicios"),
    ]},
    { n: 9, method: "M2", fr: "Examen législatif de l'impact de genre du budget", en: "Legislative scrutiny of gender impacts of the budget", es: "Escrutinio legislativo de los impactos de género del presupuesto", dims: [
      d(1, "Examen des budgets par le pouvoir législatif sensible au genre", "Gender responsive legislative scrutiny of budgets", "Escrutinio legislativo de los presupuestos sensible al género"),
      d(2, "Examen des rapports d'audit par le pouvoir législatif sensible au genre", "Gender responsive legislative scrutiny of audit reports", "Escrutinio legislativo de los informes de auditoría sensible al género"),
    ]},
  ];

  // ── Module Climat — CRPFM (14 indicateurs, 29 dimensions) ───────────────
  // Libellés FR : version pilote (GFPSC, août 2020) ; le cadre final (avril
  // 2024) est la référence — code canonique CRPFM (décision actée).
  const CRPFM = [
    { n: 1, method: null, fr: "Alignement du budget sur les stratégies climat", en: "Budget alignment with climate change strategies", es: "Alineación del presupuesto con las estrategias de cambio climático", dims: [
      d(1, "Alignement du budget sur les stratégies climat", "Budget alignment with climate change strategies", "Alineación del presupuesto con las estrategias de cambio climático"),
    ]},
    { n: 2, method: null, fr: "Suivi des dépenses liées au climat", en: "Tracking climate related expenditure", es: "Seguimiento del gasto relacionado con el clima", dims: [
      d(1, "Suivi des dépenses liées au climat", "Tracking climate related expenditure", "Seguimiento del gasto relacionado con el clima"),
    ]},
    { n: 3, method: null, fr: "Circulaire budgétaire sensible au climat", en: "Climate responsive budget circular", es: "Circular presupuestaria sensible al clima", dims: [
      d(1, "Circulaire budgétaire sensible au climat", "Climate responsive budget circular", "Circular presupuestaria sensible al clima"),
    ]},
    { n: 4, method: "M2", fr: "Examen par le pouvoir législatif", en: "Legislative scrutiny", es: "Escrutinio legislativo", dims: [
      d(1, "Examen des budgets par le pouvoir législatif", "Legislative scrutiny of budgets", "Escrutinio legislativo de los presupuestos"),
      d(2, "Examen des rapports d'audit et d'évaluation par le pouvoir législatif", "Legislative scrutiny of audit and evaluation reports", "Escrutinio legislativo de los informes de auditoría y evaluación"),
    ]},
    { n: 5, method: "M2", fr: "Gestion sensible au climat des investissements publics", en: "Climate responsive public investment management", es: "Gestión de la inversión pública sensible al clima", dims: [
      d(1, "Dispositions relatives au climat du cadre réglementaire des investissements publics", "Climate related provisions in regulatory framework for public investment management", "Disposiciones relacionadas con el clima en el marco regulador de la gestión de la inversión pública"),
      d(2, "Sélection / priorisation des projets fondée sur le climat", "Climate related project selection / prioritization", "Selección / priorización de proyectos en función del clima"),
      d(3, "Modalités d'évaluation des projets fondées sur le climat", "Climate related provisions for project appraisal", "Disposiciones relacionadas con el clima para la evaluación de proyectos"),
      d(4, "Reporting par les entités chargées de la mise en œuvre", "Reporting from entities in charge of implementation", "Presentación de informes por las entidades encargadas de la ejecución"),
    ]},
    { n: 6, method: null, fr: "Gestion sensible au climat des actifs non financiers", en: "Climate responsive non-financial asset management", es: "Gestión de los activos no financieros sensible al clima", dims: [
      d(1, "Gestion sensible au climat des actifs non financiers", "Climate responsive non-financial asset management", "Gestión de los activos no financieros sensible al clima"),
    ]},
    { n: 7, method: "M2", fr: "Passifs liés au climat", en: "Climate related liabilities", es: "Pasivos relacionados con el clima", dims: [
      d(1, "Risques budgétaires liés au climat", "Climate related fiscal risks", "Riesgos fiscales relacionados con el clima"),
      d(2, "Dette et garanties liées au climat", "Climate related debt and guarantees", "Deuda y garantías relacionadas con el clima"),
    ]},
    { n: 8, method: "M2", fr: "Commande publique sensible au climat", en: "Climate responsive public procurement", es: "Contratación pública sensible al clima", dims: [
      d(1, "Cadre de la commande publique sensible au climat", "Climate responsive procurement framework", "Marco de la contratación pública sensible al clima"),
      d(2, "Commandes publiques sensibles au climat", "Climate responsive public procurement operations", "Operaciones de contratación pública sensibles al clima"),
      d(3, "Suivi de la commande publique sensible au climat", "Climate responsive public procurement monitoring", "Seguimiento de la contratación pública sensible al clima"),
      d(4, "Reporting sur la commande publique sensible au climat", "Climate responsive public procurement reporting", "Presentación de informes sobre la contratación pública sensible al clima"),
    ]},
    { n: 9, method: "M2", fr: "Gestion des recettes de la fiscalité climat", en: "Climate related revenue management", es: "Gestión de los ingresos relacionados con el clima", dims: [
      d(1, "Gestion des risques et contrôles en matière de fiscalité climat", "Climate related tax management, audit and investigation", "Gestión, auditoría e investigación de los impuestos relacionados con el clima"),
      d(2, "Arriérés de recettes issues de la fiscalité climat", "Climate related tax arrears", "Atrasos de los impuestos relacionados con el clima"),
    ]},
    { n: 10, method: "M2", fr: "Conformité des dépenses liées au climat", en: "Compliance of climate related expenditure", es: "Cumplimiento del gasto relacionado con el clima", dims: [
      d(1, "Efficacité du système de contrôle des transactions liées au climat", "Effectiveness of the system of controls", "Eficacia del sistema de controles"),
      d(2, "Régularité des transactions liées au climat", "Compliance of transactions", "Regularidad de las transacciones relacionadas con el clima"),
    ]},
    { n: 11, method: "M2", fr: "Cadre de décentralisation budgétaire sensible au climat", en: "Climate responsive fiscal decentralization framework", es: "Marco de descentralización fiscal sensible al clima", dims: [
      d(1, "Mécanismes de décentralisation budgétaire sensibles au climat", "Climate responsive fiscal decentralization arrangements", "Mecanismos de descentralización fiscal sensibles al clima"),
      d(2, "Transferts budgétaires sensibles au climat", "Climate responsive fiscal transfers", "Transferencias fiscales sensibles al clima"),
      d(3, "Dispositifs de GFP sensibles au climat appliqués par les administrations infranationales", "Climate responsive PFM arrangements applied by subnational governments", "Disposiciones de GFP sensibles al clima aplicadas por los gobiernos subnacionales"),
    ]},
    { n: 12, method: "M2", fr: "Information sur la performance liée au climat", en: "Climate related performance information", es: "Información sobre el desempeño relacionada con el clima", dims: [
      d(1, "Information liée au climat dans les plans de performance", "Climate related information in performance plans", "Información relacionada con el clima en los planes de desempeño"),
      d(2, "Information liée au climat dans les rapports de performance", "Climate related information in performance reports", "Información relacionada con el clima en los informes de desempeño"),
    ]},
    { n: 13, method: "M2", fr: "Évaluation liée au climat", en: "Climate related evaluation", es: "Evaluación relacionada con el clima", dims: [
      d(1, "Évaluation des dépenses liée au climat", "Climate related evaluation of expenditure", "Evaluación del gasto relacionada con el clima"),
      d(2, "Évaluation des recettes fiscales liée au climat", "Climate related evaluation of taxes", "Evaluación de los ingresos tributarios relacionada con el clima"),
    ]},
    { n: 14, method: "M2", fr: "Dépenses exécutées pour l'action climatique", en: "Climate related expenditure outturn", es: "Resultados del gasto en acción climática", dims: [
      d(1, "Dépenses totales exécutées liées au climat", "Aggregate climate related expenditure outturn", "Resultados del gasto agregado relacionado con el clima"),
      d(2, "Composition des dépenses exécutées liées au climat", "Climate related expenditure composition outturn", "Resultados en la composición del gasto relacionado con el clima"),
    ]},
  ];

  // Recompose les codes complets (PI-2 → dims PI-2.1…) et fige le tout.
  function build(list, prefix) {
    return list.map((it) => ({
      code: prefix + "-" + it.n,
      n: it.n,
      pillar: it.pillar || null,
      method: it.method,
      fr: it.fr, en: it.en, es: it.es != null ? it.es : it.en,
      dims: it.dims.map((dd) => ({ code: prefix + "-" + it.n + "." + dd.s, fr: dd.fr, en: dd.en, es: dd.es != null ? dd.es : dd.en })),
    }));
  }

  // ── Agrégation officielle ────────────────────────────────────────────────
  // Table 1 du cadre PEFA 2016 (M2/AV). Clé = lettres des dimensions triées
  // par ordre alphabétique (l'ordre des dimensions n'a pas d'importance).
  const M2_TABLE = {
    // 2 dimensions
    DD: "D", CD: "D+", BD: "C", AD: "C+", CC: "C", BC: "C+", AC: "B", BB: "B", AB: "B+", AA: "A",
    // 3 dimensions
    DDD: "D", CDD: "D+", BDD: "D+", ADD: "C", CCD: "D+", BCD: "C", ACD: "C+",
    BBD: "C+", ABD: "B", AAD: "B", CCC: "C", BCC: "C+", ACC: "B", BBC: "B",
    ABC: "B", AAC: "B+", BBB: "B", ABB: "B+", AAB: "A", AAA: "A",
    // 4 dimensions
    DDDD: "D", CDDD: "D", BDDD: "D+", ADDD: "D+", CCDD: "D+", BCDD: "D+",
    ACDD: "C", BBDD: "C", ABDD: "C+", AADD: "C+", CCCD: "D+", BCCD: "C",
    ACCD: "C+", BBCD: "C+", ABCD: "C+", AACD: "B", BBBD: "C+", ABBD: "B",
    AABD: "B", AAAD: "B+", CCCC: "C", BCCC: "C+", ACCC: "C+",
    BBCC: "C+", ABCC: "B", AACC: "B", BBBC: "B", ABBC: "B", AABC: "B+",
    AAAC: "B+", BBBB: "B", ABBB: "B+", AABB: "B+", AAAB: "A", AAAA: "A",
  };

  // pefaAggregate(method, dimScores) → note agrégée proposée ou null.
  //   dimScores : tableau de notes de dimension ("A".."D", "D*", "NA", "" /
  //   null = non notée). Règles :
  //   - "NA" est exclue de l'agrégation (officiel) ; "D*" compte comme "D".
  //   - Toutes les dimensions restantes doivent être notées, sinon null.
  //   - M1 (maillon le plus faible) : note la plus basse, avec « + » si au
  //     moins une autre dimension est mieux notée (jamais sur A).
  //   - M2 : Table 1 officielle ci-dessus.
  //   - 1 seule dimension applicable : sa note, telle quelle.
  function pefaAggregate(method, dimScores) {
    const ORDER = { A: 4, B: 3, C: 2, D: 1 };
    const letters = [];
    for (const raw of dimScores || []) {
      const v = (raw || "").toString().trim().toUpperCase();
      if (v === "NA" || v === "N/A") continue;     // exclue
      const eff = v === "D*" ? "D" : v;
      if (!ORDER[eff]) return null;                // non notée / invalide
      letters.push(eff);
    }
    if (letters.length === 0) return null;
    if (letters.length === 1) return letters[0];
    if (method === "M1") {
      let min = letters[0];
      for (const l of letters) if (ORDER[l] < ORDER[min]) min = l;
      const hasHigher = letters.some((l) => ORDER[l] > ORDER[min]);
      return (hasHigher && min !== "A") ? min + "+" : min;
    }
    // M2 : table officielle (2 à 4 dimensions)
    const key = letters.slice().sort().join("");
    return M2_TABLE[key] || null;
  }

  // ── Feuilles de calcul PI-1 / PI-2 / PI-3 ────────────────────────────────
  // Méthodologie des classeurs officiels (« PI-1 PI-2 Exp calculation »,
  // « PI-3 Rev outturn calculation ») :
  //   - Exécution globale (PI-1.1 / PI-3.1) : total réalisé / total budget.
  //   - Variance de composition (PI-2.1 / PI-2.2 / PI-3.2) : budget ajusté
  //     ligne à ligne au prorata de l'exécution globale, puis
  //     Σ |réalisé_i − ajusté_i| / Σ ajusté_i.
  //   - Réserves pour imprévus (PI-2.3) : moyenne sur 3 exercices de
  //     (dépenses imputées aux imprévus / budget initial total).
  // Barèmes : cadre PEFA 2016 (extraits ci-dessous mot pour mot).
  function yearTotals(rows, y) {
    let tb = 0, ta = 0;
    (rows || []).forEach((r) => { tb += Number(r["b" + y]) || 0; ta += Number(r["a" + y]) || 0; });
    return { tb, ta };
  }
  // Exécution globale (%) par exercice y (1..3) — null si budget vide.
  function outturnPct(rows, y) {
    const { tb, ta } = yearTotals(rows, y);
    if (!tb) return null;
    return 100 * ta / tb;
  }
  // Variance de composition (%) par exercice y — budget ajusté officiel.
  function compositionVariancePct(rows, y) {
    const { tb, ta } = yearTotals(rows, y);
    if (!tb || !ta) return null;
    const ratio = ta / tb;
    let dev = 0;
    (rows || []).forEach((r) => {
      const adj = (Number(r["b" + y]) || 0) * ratio;
      dev += Math.abs((Number(r["a" + y]) || 0) - adj);
    });
    return 100 * dev / ta;   // Σ ajusté = total réalisé par construction
  }
  // ≥ 2 exercices sur 3 dans [lo, hi] ?
  const inRange2of3 = (vals, lo, hi) =>
    (vals || []).filter((v) => v != null && v >= lo && v <= hi).length >= 2;
  const below2of3 = (vals, max) =>
    (vals || []).filter((v) => v != null && v < max).length >= 2;

  const pefaCalc = {
    outturnPct, compositionVariancePct,
    // PI-1.1 : A 95–105 % (≥2/3 ex.) ; B 90–110 ; C 85–115 ; sinon D.
    scorePI11(outturns) {
      if ((outturns || []).filter((v) => v != null).length < 3) return null;
      if (inRange2of3(outturns, 95, 105)) return "A";
      if (inRange2of3(outturns, 90, 110)) return "B";
      if (inRange2of3(outturns, 85, 115)) return "C";
      return "D";
    },
    // PI-2.1 / PI-2.2 / PI-3.2 : variance < 5 % (≥2/3 ex.) → A ; <10 → B ;
    // <15 → C ; sinon D.
    scoreComposition(variances) {
      if ((variances || []).filter((v) => v != null).length < 3) return null;
      if (below2of3(variances, 5))  return "A";
      if (below2of3(variances, 10)) return "B";
      if (below2of3(variances, 15)) return "C";
      return "D";
    },
    // PI-2.3 : moyenne des imprévus < 3 % → A ; 3–6 % inclus → B ;
    // > 6 % et < 10 % → C ; sinon D.
    scoreContingency(avgSharePct) {
      if (avgSharePct == null) return null;
      if (avgSharePct < 3)   return "A";
      if (avgSharePct <= 6)  return "B";
      if (avgSharePct < 10)  return "C";
      return "D";
    },
    // PI-3.1 : A 97–106 % (≥2/3 ex.) ; B 94–112 ; C 92–116 ; sinon D.
    scorePI31(outturns) {
      if ((outturns || []).filter((v) => v != null).length < 3) return null;
      if (inRange2of3(outturns, 97, 106)) return "A";
      if (inRange2of3(outturns, 94, 112)) return "B";
      if (inRange2of3(outturns, 92, 116)) return "C";
      return "D";
    },
    // Part moyenne des imprévus (%) : montants imputés / budget initial total.
    // null / vide = exercice non renseigné (≠ 0) → pas de moyenne proposée.
    contingencyAvgPct(expRows, contingency) {
      const shares = [];
      for (let y = 1; y <= 3; y++) {
        const raw = (contingency || [])[y - 1];
        if (raw == null || raw === "") continue;
        const { tb } = yearTotals(expRows, y);
        const c = Number(raw);
        if (tb && !Number.isNaN(c)) shares.push(100 * c / tb);
      }
      if (shares.length < 3) return null;
      return shares.reduce((s, v) => s + v, 0) / shares.length;
    },
  };

  window.PEFA_CATALOG = {
    pillars: PILLARS,
    indicators: build(PI, "PI"),
    gender: build(GRPFM, "GRPFM"),
    climate: build(CRPFM, "CRPFM"),
  };
  window.pefaAggregate = pefaAggregate;
  window.pefaCalc = pefaCalc;
})();
