[ADD] application: clock, translation, formatting, displayed name
The screens need one clock, one translation mechanism and one way to
format and name, or each component grows its own. horloge.js is the only
code that reads time and arms timers, injected so tests drive it.
traduction.js keys texts by domain, in two families of tables, raises on a
missing key and never shows a raw key; libelles/ splits the label table by
domain. format.js formats numbers and dates in French, and personnes.js
composes the displayed name the frozen labels use. Nothing persists
between sessions.
Checked: 1773 node and 43 browser tests.
--- FR ---
[ADD] application : horloge, traduction, mise en forme, nom affiché
Les écrans exigent une horloge, un mécanisme de traduction et une façon de
mettre en forme et de nommer, sans quoi chaque composant ferait les siens.
horloge.js est le seul code qui lit l'heure et arme des minuteries, injecté
pour que les épreuves le pilotent. traduction.js range les textes par
domaine, en deux familles de tables, lève sur une clé absente et ne montre
jamais une clé brute ; libelles/ découpe la table des libellés par domaine.
format.js met en forme nombres et dates en français, et personnes.js
compose le nom affiché qu'emploient les libellés figés. Rien ne persiste
d'une séance à l'autre.
Vérifié : 1773 node et 43 navigateur.
Assisted-by: Claude Opus 5.5
2026-10-07 02:33:39 -04:00
|
|
|
// © 2026 TechnoLibre (http://www.technolibre.ca)
|
|
|
|
|
// License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
|
|
|
|
|
|
|
|
|
// Les libellés de l'accueil : la liste des événements, les démonstrations, les
|
|
|
|
|
// opérations de fichiers, la corbeille, le dossier de travail et la
|
[ADD] interface: event list, open event, participants, import, plan
The working screens of an evening. The home screen lists the events of
the working folder, asks its question, loads demos, copies, renames,
imports and deletes, and shows what the trash holds. An open event frames
its mode, offers Modifier, Débloquer and a confirmed lock takeover, and
shows its warnings. Participants get a grid, a form and a file; an import
goes through a preview and a report; tables, the default and tours have
their screens; the plan draws tables, chairs, empty seats and names.
Checked: 2342 node, 356 browser, 60 node-long; the Electron start check.
--- FR ---
[ADD] interface : liste, événement, participants, import, tables, plan
Les écrans de travail d'une soirée. L'accueil liste les événements du
dossier de travail, pose sa question, charge les démonstrations, copie,
renomme, importe et supprime, et montre ce que tient la corbeille. Un
événement ouvert encadre son mode, offre Modifier, Débloquer et une
reprise de verrou confirmée, et montre ses avertissements. Les
participants ont une grille, un formulaire et une fiche ; un import passe
par un aperçu et un rapport ; tables, défaut et tours ont leurs écrans ;
le plan dessine tables, chaises, sièges vides et noms.
Vérifié : 2342 node, 356 navigateur, 60 node-long ; démarrage d'Electron.
Assisted-by: Claude Opus 5.5
2026-10-07 08:12:27 -04:00
|
|
|
// récupération (§ 14.6). Chaque clé commence par « accueil. ». Les codes que
|
|
|
|
|
// l'accueil affiche — avis et questions du dossier de travail, refus, état
|
|
|
|
|
// illisible — gardent leur texte dans les tables de l'application.
|
|
|
|
|
|
|
|
|
|
// Une donnée — un chemin, une base — n'entre dans aucun libellé d'écran :
|
|
|
|
|
// le composant la rend dans son propre nœud, à côté du texte traduit
|
|
|
|
|
// (§ 14.6). Un compte s'accorde dans la phrase qui le porte.
|
[ADD] home: retained plan's collisions and redundancy gap per event
The event list showed no outcome, so comparing events meant opening each.
Each line now shows, for the retained plan only, the cumulated collisions
(pair and tour) and the redundancy gap |target - sum of r(p)|, with an
explanation tooltip; an event without a measurable retained plan shows a
dash. The target is set per event in Propositions, 1000 by default: an
optional settings field, absent in every existing file and read as 1000,
written through one undoable command refused in reading mode. Listing
stays read-only. Checked: 2909 node, 604 browser, 62 long tests.
--- FR ---
[ADD] accueil : collisions et Diff de redondance du retenu par événement
La liste des événements ne montrait aucun résultat : comparer obligeait à
ouvrir chacun. Chaque ligne montre, pour le retenu seul, les collisions
cumulées (paire et tour) et la Diff somme d'appartenance, |cible - somme
de r(p)|, avec une infobulle ; sans retenu mesurable, un tiret. La cible
se règle par événement dans Propositions, 1000 par défaut : champ
facultatif des réglages, absent de tout fichier existant et lu 1000, écrit
par une commande qui se défait et se refuse en lecture. La liste reste en
lecture seule. Vérifié : 2909 node, 604 navigateur, 62 longues.
Assisted-by: Claude Opus 5.5
2026-10-08 05:35:48 -04:00
|
|
|
import { CIBLE_REDONDANCE_PAR_DEFAUT } from '../../application/evaluation.js';
|
|
|
|
|
|
[ADD] interface: event list, open event, participants, import, plan
The working screens of an evening. The home screen lists the events of
the working folder, asks its question, loads demos, copies, renames,
imports and deletes, and shows what the trash holds. An open event frames
its mode, offers Modifier, Débloquer and a confirmed lock takeover, and
shows its warnings. Participants get a grid, a form and a file; an import
goes through a preview and a report; tables, the default and tours have
their screens; the plan draws tables, chairs, empty seats and names.
Checked: 2342 node, 356 browser, 60 node-long; the Electron start check.
--- FR ---
[ADD] interface : liste, événement, participants, import, tables, plan
Les écrans de travail d'une soirée. L'accueil liste les événements du
dossier de travail, pose sa question, charge les démonstrations, copie,
renomme, importe et supprime, et montre ce que tient la corbeille. Un
événement ouvert encadre son mode, offre Modifier, Débloquer et une
reprise de verrou confirmée, et montre ses avertissements. Les
participants ont une grille, un formulaire et une fiche ; un import passe
par un aperçu et un rapport ; tables, défaut et tours ont leurs écrans ;
le plan dessine tables, chaises, sièges vides et noms.
Vérifié : 2342 node, 356 navigateur, 60 node-long ; démarrage d'Electron.
Assisted-by: Claude Opus 5.5
2026-10-07 08:12:27 -04:00
|
|
|
const compte = (n, singulier, pluriel) => `${n} ${n <= 1 ? singulier : pluriel}`;
|
|
|
|
|
|
|
|
|
|
export const TABLE = new Map([
|
|
|
|
|
// --- La liste (§ 8.1) ----------------------------------------------------
|
|
|
|
|
// Les intitulés des informations d'une ligne ; le nom est la commande qui
|
|
|
|
|
// ouvre l'événement.
|
|
|
|
|
['accueil.colonne.date', 'Date'],
|
|
|
|
|
['accueil.colonne.etat', 'État'],
|
|
|
|
|
['accueil.colonne.participants', 'Participants'],
|
|
|
|
|
['accueil.colonne.modification', 'Dernière modification'],
|
|
|
|
|
['accueil.colonne.chemin', 'Fichier'],
|
[ADD] home: retained plan's collisions and redundancy gap per event
The event list showed no outcome, so comparing events meant opening each.
Each line now shows, for the retained plan only, the cumulated collisions
(pair and tour) and the redundancy gap |target - sum of r(p)|, with an
explanation tooltip; an event without a measurable retained plan shows a
dash. The target is set per event in Propositions, 1000 by default: an
optional settings field, absent in every existing file and read as 1000,
written through one undoable command refused in reading mode. Listing
stays read-only. Checked: 2909 node, 604 browser, 62 long tests.
--- FR ---
[ADD] accueil : collisions et Diff de redondance du retenu par événement
La liste des événements ne montrait aucun résultat : comparer obligeait à
ouvrir chacun. Chaque ligne montre, pour le retenu seul, les collisions
cumulées (paire et tour) et la Diff somme d'appartenance, |cible - somme
de r(p)|, avec une infobulle ; sans retenu mesurable, un tiret. La cible
se règle par événement dans Propositions, 1000 par défaut : champ
facultatif des réglages, absent de tout fichier existant et lu 1000, écrit
par une commande qui se défait et se refuse en lecture. La liste reste en
lecture seule. Vérifié : 2909 node, 604 navigateur, 62 longues.
Assisted-by: Claude Opus 5.5
2026-10-08 05:35:48 -04:00
|
|
|
// Les deux mesures du placement retenu (§ 5.4, § 8.9), et l'explication
|
|
|
|
|
// que l'infobulle de leur intitulé donne : ce que compte le nombre, d'où
|
|
|
|
|
// il vient, et quand il vaut « — ».
|
|
|
|
|
['accueil.colonne.collisionsCumulees', 'Collisions cumulées (paire et tour)'],
|
|
|
|
|
['accueil.colonne.diffRedondance', "Diff somme d'appartenance"],
|
|
|
|
|
[
|
|
|
|
|
'accueil.explication.collisionsCumulees',
|
|
|
|
|
'Celles du placement retenu : chaque fois que deux personnes de la même appartenance partagent une table, ' +
|
|
|
|
|
'compté une fois par paire et par tour ; deux collègues ensemble aux quatre tours font 4. Le même nombre que la ' +
|
|
|
|
|
"colonne « Collisions cumulées » du tableau des propositions. Plus il est bas, mieux c'est. " +
|
|
|
|
|
"« \u{2014} » quand aucun placement n'est retenu, ou que le retenu ne décrit plus la configuration.",
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'accueil.explication.diffRedondance',
|
|
|
|
|
'|cible \u{2212} Σ r(p)| : la différence, sans signe, entre la cible de la soirée et la somme Σ r(p) du placement ' +
|
|
|
|
|
"retenu, celle de la colonne « Redondance d'appartenance, somme Σ r(p) » du tableau des propositions. r(p) compte " +
|
|
|
|
|
"les personnes que p rencontre et qui ont une appartenance, moins le nombre d'appartenances différentes qu'elles " +
|
|
|
|
|
`portent. La cible vaut ${CIBLE_REDONDANCE_PAR_DEFAUT} tant qu'on ne la change pas, dans la section des ` +
|
|
|
|
|
"propositions. « \u{2014} » quand aucun placement n'est retenu, ou que le retenu ne décrit plus la configuration.",
|
|
|
|
|
],
|
[ADD] interface: event list, open event, participants, import, plan
The working screens of an evening. The home screen lists the events of
the working folder, asks its question, loads demos, copies, renames,
imports and deletes, and shows what the trash holds. An open event frames
its mode, offers Modifier, Débloquer and a confirmed lock takeover, and
shows its warnings. Participants get a grid, a form and a file; an import
goes through a preview and a report; tables, the default and tours have
their screens; the plan draws tables, chairs, empty seats and names.
Checked: 2342 node, 356 browser, 60 node-long; the Electron start check.
--- FR ---
[ADD] interface : liste, événement, participants, import, tables, plan
Les écrans de travail d'une soirée. L'accueil liste les événements du
dossier de travail, pose sa question, charge les démonstrations, copie,
renomme, importe et supprime, et montre ce que tient la corbeille. Un
événement ouvert encadre son mode, offre Modifier, Débloquer et une
reprise de verrou confirmée, et montre ses avertissements. Les
participants ont une grille, un formulaire et une fiche ; un import passe
par un aperçu et un rapport ; tables, défaut et tours ont leurs écrans ;
le plan dessine tables, chaises, sièges vides et noms.
Vérifié : 2342 node, 356 navigateur, 60 node-long ; démarrage d'Electron.
Assisted-by: Claude Opus 5.5
2026-10-07 08:12:27 -04:00
|
|
|
|
|
|
|
|
// Le nom d'un état du plan (§ 9), que rend cleDEtat (modele.js).
|
|
|
|
|
['accueil.etat.brouillon', 'Brouillon'],
|
|
|
|
|
['accueil.etat.propose', 'Proposé'],
|
|
|
|
|
['accueil.etat.retenu', 'Retenu'],
|
|
|
|
|
['accueil.etat.bloque', 'Bloqué'],
|
|
|
|
|
|
|
|
|
|
// autres : le nombre des autres bases qui portent le même identifiant
|
|
|
|
|
// (§ 8.7, § 8.8) ; elles suivent le texte, chacune dans son propre nœud.
|
|
|
|
|
[
|
|
|
|
|
'accueil.signalement.doublon',
|
|
|
|
|
({ autres }) =>
|
|
|
|
|
autres <= 1
|
|
|
|
|
? 'Le même événement se trouve aussi dans le fichier nommé ci-dessous : deux fichiers portent son ' +
|
|
|
|
|
'identifiant, comme après un renommage interrompu. Gardez-en un, et supprimez l\u{2019}autre.'
|
|
|
|
|
: `Le même événement se trouve aussi dans les ${autres} fichiers nommés ci-dessous : chacun porte son ` +
|
|
|
|
|
'identifiant, comme après un renommage interrompu. Gardez-en un, et supprimez les autres.',
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// --- La création (§ 2.1, étape 1) ----------------------------------------
|
|
|
|
|
['accueil.creation.titre', 'Créer un événement'],
|
|
|
|
|
['accueil.creation.nom', 'Nom de l\u{2019}événement'],
|
|
|
|
|
['accueil.creation.date', 'Date, facultative (AAAA-MM-JJ)'],
|
|
|
|
|
['accueil.creation.creer', 'Créer l\u{2019}événement'],
|
|
|
|
|
|
|
|
|
|
// --- Les opérations de fichiers (§ 8.7) ----------------------------------
|
|
|
|
|
['accueil.operation.importer', 'Importer un événement depuis un fichier\u{2026}'],
|
|
|
|
|
['accueil.operation.copier', 'Copier'],
|
|
|
|
|
['accueil.operation.renommer', 'Renommer'],
|
|
|
|
|
['accueil.operation.supprimer', 'Supprimer'],
|
|
|
|
|
['accueil.operation.confirmerSuppression', 'Confirmer : déplacer dans la corbeille'],
|
|
|
|
|
['accueil.operation.nomCopie', 'Nom de la copie'],
|
|
|
|
|
['accueil.operation.nouveauNom', 'Nouveau nom'],
|
|
|
|
|
['accueil.operation.validerCopie', 'Créer la copie'],
|
|
|
|
|
['accueil.operation.validerRenommage', 'Renommer l\u{2019}événement'],
|
|
|
|
|
['accueil.operation.annuler', 'Annuler'],
|
|
|
|
|
|
|
|
|
|
// --- Les démonstrations (§ 15) ---------------------------------------------
|
|
|
|
|
['accueil.demonstrations.titre', 'Démonstrations'],
|
|
|
|
|
[
|
|
|
|
|
'accueil.demonstrations.explication',
|
|
|
|
|
'Chacune se charge comme un nouvel événement, numéroté et ouvert en lecture ; ' +
|
|
|
|
|
'aucun autre événement n\u{2019}est touché.',
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// --- La corbeille (§ 8.7) --------------------------------------------------
|
|
|
|
|
['accueil.corbeille.titre', 'Corbeille'],
|
|
|
|
|
[
|
|
|
|
|
'accueil.corbeille.explication',
|
|
|
|
|
'Un événement supprimé y est déplacé avec tous ses fichiers, dans un dossier daté. ' +
|
|
|
|
|
'Le logiciel ne la vide jamais.',
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// --- Le dossier de travail (§ 8.6) -----------------------------------------
|
|
|
|
|
['accueil.dossier.titre', 'Dossier de travail'],
|
|
|
|
|
['accueil.dossier.explorateur', 'Ouvrir dans l\u{2019}explorateur'],
|
|
|
|
|
['accueil.question.reessayer', 'Réessayer'],
|
|
|
|
|
['accueil.question.documents', 'Travailler dans les Documents, en y copiant ces événements'],
|
|
|
|
|
['accueil.question.continuer', 'Continuer : ouvrir la liste, aucun geste ne s\u{2019}y enregistrera'],
|
|
|
|
|
// evenements : ce que porte l'autre emplacement, dont le chemin suit le
|
|
|
|
|
// texte, dans son propre nœud.
|
|
|
|
|
[
|
|
|
|
|
'accueil.autre.proposition',
|
|
|
|
|
({ evenements }) =>
|
|
|
|
|
`Le dossier de travail est neuf, et cet autre dossier porte ${compte(evenements, 'événement', 'événements')} :`,
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'accueil.autre.originaux',
|
|
|
|
|
'L\u{2019}import les copie : les originaux restent où ils sont, et chaque copie vit ensuite sa propre vie.',
|
|
|
|
|
],
|
|
|
|
|
['accueil.autre.importer', 'Importer ces événements'],
|
|
|
|
|
// importes, refuses : les comptes de l'import de l'autre emplacement.
|
|
|
|
|
[
|
|
|
|
|
'accueil.autre.resultat',
|
|
|
|
|
({ importes, refuses }) =>
|
|
|
|
|
refuses === 0
|
|
|
|
|
? `${compte(importes, 'événement importé', 'événements importés')}.`
|
|
|
|
|
: `${compte(importes, 'événement importé', 'événements importés')} ; ` +
|
|
|
|
|
`${compte(refuses, 'ne s\u{2019}est pas importé', 'ne se sont pas importés')}.`,
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// --- La récupération (§ 8.8) -----------------------------------------------
|
|
|
|
|
['accueil.recuperation.titre', 'Récupération d\u{2019}un événement'],
|
|
|
|
|
['accueil.recuperation.fichier', 'Fichier'],
|
|
|
|
|
[
|
|
|
|
|
'accueil.recuperation.offerte',
|
|
|
|
|
'La version choisie s\u{2019}ouvre en lecture : rien ne s\u{2019}écrit avant un geste en écriture.',
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'accueil.recuperation.aucunSecours',
|
|
|
|
|
'Aucune version de secours ne se lit : l\u{2019}événement ne s\u{2019}ouvre pas, et rien n\u{2019}est créé à sa place.',
|
|
|
|
|
],
|
|
|
|
|
['accueil.recuperation.retour', 'Revenir à la liste'],
|
|
|
|
|
]);
|