diff --git a/.claude/settings.local.json b/.claude/settings.local.json index ad1dce8..2fe8bb7 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -2,7 +2,8 @@ "permissions": { "allow": [ "Bash(curl:*)", - "Bash(python -m json.tool:*)" + "Bash(python -m json.tool:*)", + "Bash(python3:*)" ], "deny": [], "ask": [] diff --git a/CLAUDE.md b/CLAUDE.md index 99753bc..645680d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -115,6 +115,29 @@ sili (regard) + -i- (agent) + aska (libre) ### Peuple **Siliaska** = "Les porteurs du regard libre" +## API ConfluentTranslator + +Le serveur de traduction (`ConfluentTranslator/server.js`) expose les endpoints suivants : + +### Gestion des lexiques +- **GET** `/lexique` - Retourne le lexique ancien (legacy) +- **GET** `/api/lexique/:variant` - Retourne le lexique pour `proto` ou `ancien` +- **GET** `/api/stats` - Statistiques des lexiques chargés +- **POST** `/api/reload` - Recharge les lexiques (développement) + +### Recherche et analyse +- **GET** `/api/search?q=&variant=&direction=` - Recherche dans le lexique +- **POST** `/api/analyze/coverage` - Analyse la couverture d'un texte français avant traduction + +### Traduction +- **POST** `/translate` - Traduction FR → Confluent avec système contextuel (retourne layers 1-3) +- **POST** `/api/translate/raw` - Traduction brute sans parsing (debug) +- **POST** `/api/translate/batch` - Traduction par lot de mots +- **POST** `/api/translate/conf2fr` - Traduction Confluent → FR + +### Debug +- **POST** `/api/debug/prompt` - Génère le prompt système sans appeler le LLM + ## Prochaines étapes 1. Enrichir le lexique (verbes, concepts abstraits, émotions...) diff --git a/ConfluentTranslator/confluentToFrench.js b/ConfluentTranslator/confluentToFrench.js index 907e4ad..75d171d 100644 --- a/ConfluentTranslator/confluentToFrench.js +++ b/ConfluentTranslator/confluentToFrench.js @@ -93,7 +93,7 @@ function searchConfluent(word, reverseIndex) { } // 5. NOUVEAU: Décomposition morphologique - const decompositions = decomposeWord(lowerWord); + const decompositions = decomposeWord(lowerWord, reverseIndex); for (const decomp of decompositions) { const part1Match = searchConfluent(decomp.part1, reverseIndex); const part2Match = searchConfluent(decomp.part2, reverseIndex); diff --git a/ConfluentTranslator/contextAnalyzer.js b/ConfluentTranslator/contextAnalyzer.js index c6e804b..a1ae855 100644 --- a/ConfluentTranslator/contextAnalyzer.js +++ b/ConfluentTranslator/contextAnalyzer.js @@ -28,9 +28,11 @@ function tokenizeFrench(text) { ]); // ÉTAPE 1: Normaliser et nettoyer le texte - // ORDRE IMPORTANT: lowercase → accents → contractions + // ORDRE IMPORTANT: lowercase → ligatures → accents → contractions let processedText = text .toLowerCase() + .replace(/œ/g, 'oe') // Ligature œ → oe (cœur → coeur) + .replace(/æ/g, 'ae') // Ligature æ → ae .normalize('NFD') // Décompose les caractères accentués .replace(/[\u0300-\u036f]/g, ''); // Retire les diacritiques (é→e, è→e, ê→e, etc.) @@ -143,7 +145,12 @@ function simpleLemmatize(word) { if (word.endsWith(ending) && word.length > ending.length + 2) { const root = word.slice(0, -ending.length); forms.push(root + replacement); - forms.push(root); // juste la racine aussi + // Ajouter le radical seul UNIQUEMENT s'il fait au moins 5 lettres + // Évite: "dansent" → "dans" (4 lettres, faux positif avec particule "dans") + // Accepte: "écoutent" → "écoute" (6 lettres), "observent" → "observe" (7 lettres) + if (root.length >= 5) { + forms.push(root); + } } } @@ -175,9 +182,10 @@ function simpleLemmatize(word) { * Cherche un mot dans le dictionnaire (correspondance exacte ou synonyme) * @param {string} word - Mot à chercher * @param {Object} dictionnaire - Dictionnaire du lexique + * @param {string} normalizedText - Texte original normalisé (pour vérifier frontières) * @returns {Array} - Entrées trouvées avec score */ -function searchWord(word, dictionnaire) { +function searchWord(word, dictionnaire, normalizedText = '') { const results = []; const lemmas = simpleLemmatize(word); @@ -224,9 +232,10 @@ function searchWord(word, dictionnaire) { * @param {string[]} words - Liste de mots * @param {Object} lexique - Lexique complet * @param {number} maxEntries - Nombre max d'entrées + * @param {string} normalizedText - Texte original normalisé (pour vérifier frontières) * @returns {Object} - Résultat avec entrées trouvées et métadonnées */ -function findRelevantEntries(words, lexique, maxEntries) { +function findRelevantEntries(words, lexique, maxEntries, normalizedText = '') { const foundEntries = new Map(); // key: mot_francais, value: entry const wordsFound = []; // Pour Layer 2 const wordsNotFound = []; @@ -243,7 +252,7 @@ function findRelevantEntries(words, lexique, maxEntries) { // Chercher chaque mot for (const word of words) { - const results = searchWord(word, lexique.dictionnaire); + const results = searchWord(word, lexique.dictionnaire, normalizedText); if (results.length > 0) { // Prendre la meilleure correspondance @@ -380,6 +389,14 @@ function extractRoots(lexique) { function analyzeContext(text, lexique, options = {}) { const expansionLevel = options.expansionLevel || 1; + // 0. Normaliser le texte (pour vérifier frontières de mots plus tard) + const normalizedText = text + .toLowerCase() + .replace(/œ/g, 'oe') + .replace(/æ/g, 'ae') + .normalize('NFD') + .replace(/[\u0300-\u036f]/g, ''); + // 1. Tokenization const words = tokenizeFrench(text); const uniqueWords = [...new Set(words)]; @@ -387,8 +404,8 @@ function analyzeContext(text, lexique, options = {}) { // 2. Calculer limite dynamique const maxEntries = calculateMaxEntries(words.length); - // 3. Trouver entrées pertinentes - const searchResult = findRelevantEntries(uniqueWords, lexique, maxEntries); + // 3. Trouver entrées pertinentes (avec texte normalisé pour vérifier frontières) + const searchResult = findRelevantEntries(uniqueWords, lexique, maxEntries, normalizedText); // 4. Expansion sémantique const expandedEntries = expandContext( diff --git a/ConfluentTranslator/lexiqueLoader.js b/ConfluentTranslator/lexiqueLoader.js index 743fdbb..aa949f3 100644 --- a/ConfluentTranslator/lexiqueLoader.js +++ b/ConfluentTranslator/lexiqueLoader.js @@ -1,6 +1,20 @@ const fs = require('fs'); const path = require('path'); +/** + * Normalise un texte : lowercase + retire accents + ligatures + * @param {string} text - Texte à normaliser + * @returns {string} - Texte normalisé + */ +function normalizeText(text) { + return text + .toLowerCase() + .replace(/œ/g, 'oe') + .replace(/æ/g, 'ae') + .normalize('NFD') + .replace(/[\u0300-\u036f]/g, ''); +} + /** * Charge dynamiquement tous les fichiers de lexique d'un dossier * @param {string} lexiqueDir - Chemin vers le dossier contenant les fichiers JSON @@ -33,7 +47,7 @@ function loadLexiqueFromDir(lexiqueDir) { if (content.dictionnaire) { // Fusionner les entrées for (const [motFr, data] of Object.entries(content.dictionnaire)) { - const key = motFr.toLowerCase(); + const key = normalizeText(motFr); if (!result.dictionnaire[key]) { result.dictionnaire[key] = { @@ -67,7 +81,7 @@ function loadLexiqueFromDir(lexiqueDir) { result.dictionnaire[key].synonymes_fr.push(syn); } // Créer une entrée pour le synonyme qui pointe vers le mot principal - const synKey = syn.toLowerCase(); + const synKey = normalizeText(syn); if (!result.dictionnaire[synKey]) { result.dictionnaire[synKey] = { mot_francais: syn, @@ -119,7 +133,7 @@ function mergeSimpleLexique(baseDir, existingLexique) { for (const [section, entries] of Object.entries(content.dictionnaire)) { if (typeof entries === 'object') { for (const [motFr, traduction] of Object.entries(entries)) { - const key = motFr.toLowerCase(); + const key = normalizeText(motFr); // N'ajouter que si pas déjà présent if (!existingLexique.dictionnaire[key]) { @@ -210,7 +224,7 @@ function buildReverseIndex(lexique) { */ function searchLexique(lexique, query, direction = 'fr2conf') { const results = []; - const queryLower = query.toLowerCase(); + const queryLower = normalizeText(query); if (direction === 'fr2conf') { // Recherche exacte diff --git a/ConfluentTranslator/morphologicalDecomposer.js b/ConfluentTranslator/morphologicalDecomposer.js index dde8785..2ae4144 100644 --- a/ConfluentTranslator/morphologicalDecomposer.js +++ b/ConfluentTranslator/morphologicalDecomposer.js @@ -2,45 +2,128 @@ // Système de décomposition morphologique pour le Confluent // Permet de décomposer les mots composés selon le pattern Racine-Liaison-Racine -// Les 16 liaisons sacrées du Confluent -const SACRED_LIAISONS = { - // Agentivité - 'i': 'agent', - 'ie': 'agent_processus', - 'ii': 'agent_répété', - 'iu': 'agent_possédant', +const lexique = require('../data/lexique.json'); - // Appartenance - 'u': 'appartenance', - 'ui': 'possession_agentive', +// ============================================================================ +// CHARGEMENT DYNAMIQUE DES LIAISONS DEPUIS LE LEXIQUE +// ============================================================================ - // Relation - 'a': 'relation', - 'aa': 'relation_forte', - 'ae': 'relation_dimensionnelle', - 'ao': 'relation_tendue', +/** + * Charge les liaisons sacrées depuis le lexique JSON + * @returns {Object} Dictionnaire des liaisons {liaison: {domaine, concept, description}} + */ +function loadSacredLiaisons() { + const liaisons = {}; - // Tension - 'o': 'tension', - 'oa': 'tension_relationnelle', + if (lexique.liaisons) { + for (const [liaison, data] of Object.entries(lexique.liaisons)) { + liaisons[liaison] = { + domaine: data.domaine, + concept: data.concept, + description: data.description, + base: data.base + }; + } + } - // Dimension - 'e': 'dimension', - 'ei': 'dimension_agentive', - 'ea': 'dimension_relationnelle', - 'eo': 'dimension_tendue' -}; + return liaisons; +} + +// Charger les liaisons depuis le lexique +const SACRED_LIAISONS = loadSacredLiaisons(); + +console.log(`[morphologicalDecomposer] Chargé ${Object.keys(SACRED_LIAISONS).length} liaisons sacrées depuis lexique.json`); + +// ============================================================================ +// VALIDATION DES RACINES +// ============================================================================ + +/** + * Vérifie si une partie ressemble à une racine valide du Confluent + * @param {string} part - Partie à valider + * @param {Object} reverseIndex - Index de recherche (optionnel) + * @returns {{isValid: boolean, found: boolean, confidence: number}} + */ +function validateRoot(part, reverseIndex = null) { + // Critères de base + if (part.length < 2) { + return { isValid: false, found: false, confidence: 0 }; + } + + let confidence = 0.5; // base + let found = false; + + // 1. Vérifier si la partie existe dans l'index de recherche + if (reverseIndex) { + // Recherche exacte + if (reverseIndex.byWord && reverseIndex.byWord[part]) { + found = true; + confidence = 1.0; + return { isValid: true, found: true, confidence }; + } + + // Recherche par forme liée (enlever dernière voyelle) + if (reverseIndex.byFormeLiee) { + const formeLiee = part.endsWith('a') || part.endsWith('e') || + part.endsWith('i') || part.endsWith('o') || + part.endsWith('u') + ? part.slice(0, -1) + : part; + + if (reverseIndex.byFormeLiee[formeLiee]) { + found = true; + confidence = 0.95; + return { isValid: true, found: true, confidence }; + } + } + } + + // 2. Heuristiques morphologiques du Confluent + // Les racines finissent généralement par CV (consonne + voyelle) + const vowels = 'aeiou'; + const lastChar = part[part.length - 1]; + const secondLastChar = part.length > 1 ? part[part.length - 2] : ''; + + // Finit par voyelle = probable racine + if (vowels.includes(lastChar)) { + confidence += 0.2; + + // Pattern CV en fin = très probable + if (secondLastChar && !vowels.includes(secondLastChar)) { + confidence += 0.2; + } + } + + // 3. Longueur typique (3-4 caractères pour racines) + if (part.length >= 3 && part.length <= 5) { + confidence += 0.1; + } + + return { + isValid: confidence >= 0.5, + found: false, + confidence: Math.min(confidence, 1.0) + }; +} + +// ============================================================================ +// DÉCOMPOSITION MORPHOLOGIQUE +// ============================================================================ /** * Décompose un mot composé non trouvé * @param {string} word - Mot composé en confluent - * @returns {Array<{part1: string, liaison: string, liaisonMeaning: string, part2: string, pattern: string, confidence: number}>} + * @param {Object} reverseIndex - Index de recherche (optionnel, pour validation) + * @returns {Array<{part1: string, liaison: string, liaisonMeaning: string, part2: string, pattern: string, confidence: number, part1Valid: boolean, part2Valid: boolean}>} */ -function decomposeWord(word) { +function decomposeWord(word, reverseIndex = null) { const decompositions = []; + // Trier les liaisons par longueur décroissante (essayer 'aa' avant 'a') + const liaisonsSorted = Object.keys(SACRED_LIAISONS).sort((a, b) => b.length - a.length); + // Essayer chaque liaison sacrée - for (const [liaison, meaning] of Object.entries(SACRED_LIAISONS)) { + for (const liaison of liaisonsSorted) { const index = word.indexOf(liaison); // La liaison doit être au milieu du mot, pas au début ni à la fin @@ -48,15 +131,33 @@ function decomposeWord(word) { const part1 = word.substring(0, index); const part2 = word.substring(index + liaison.length); - // Valider que les deux parties ressemblent à des racines (au moins 2 caractères) - if (part1.length >= 2 && part2.length >= 2) { + // Valider les deux parties + const part1Validation = validateRoot(part1, reverseIndex); + const part2Validation = validateRoot(part2, reverseIndex); + + // Les deux parties doivent ressembler à des racines + if (part1Validation.isValid && part2Validation.isValid) { + const liaisonData = SACRED_LIAISONS[liaison]; + decompositions.push({ part1, + part1Found: part1Validation.found, + part1Confidence: part1Validation.confidence, liaison, - liaisonMeaning: meaning, + liaisonDomaine: liaisonData.domaine, + liaisonConcept: liaisonData.concept, + liaisonDescription: liaisonData.description, part2, + part2Found: part2Validation.found, + part2Confidence: part2Validation.confidence, pattern: `${part1}-${liaison}-${part2}`, - confidence: calculateConfidence(part1, liaison, part2) + confidence: calculateConfidence( + part1, + liaison, + part2, + part1Validation, + part2Validation + ) }); } } @@ -71,26 +172,39 @@ function decomposeWord(word) { * @param {string} part1 - Première partie (racine) * @param {string} liaison - Liaison sacrée * @param {string} part2 - Deuxième partie (racine) + * @param {Object} part1Validation - Résultat de validation de part1 + * @param {Object} part2Validation - Résultat de validation de part2 * @returns {number} Score de confiance entre 0 et 1 */ -function calculateConfidence(part1, liaison, part2) { - let score = 0.5; // base +function calculateConfidence(part1, liaison, part2, part1Validation, part2Validation) { + let score = 0.3; // base plus conservative - // Bonus si les parties finissent/commencent par des consonnes (plus typique du Confluent) - if (!'aeiou'.includes(part1[part1.length - 1])) score += 0.1; - if (!'aeiou'.includes(part2[0])) score += 0.1; + // BONUS MAJEUR : Si les deux parties sont trouvées dans le lexique + if (part1Validation.found && part2Validation.found) { + score = 0.95; // Très haute confiance ! + } else if (part1Validation.found || part2Validation.found) { + score = 0.75; // Une partie trouvée = bonne confiance + } else { + // Utiliser la confiance des validations heuristiques + score = (part1Validation.confidence + part2Validation.confidence) / 2; + } // Bonus si liaison courante (i, u, a sont plus fréquentes) - if (['i', 'u', 'a'].includes(liaison)) score += 0.2; + if (['i', 'u', 'a'].includes(liaison)) { + score += 0.05; + } else if (['aa', 'ii'].includes(liaison)) { + score += 0.03; + } // Bonus si longueurs de parties équilibrées const ratio = Math.min(part1.length, part2.length) / Math.max(part1.length, part2.length); - score += ratio * 0.2; + score += ratio * 0.05; return Math.min(score, 1.0); } module.exports = { decomposeWord, - SACRED_LIAISONS + SACRED_LIAISONS, + validateRoot }; diff --git a/ConfluentTranslator/radicalMatcher.js b/ConfluentTranslator/radicalMatcher.js index 990c73e..918757a 100644 --- a/ConfluentTranslator/radicalMatcher.js +++ b/ConfluentTranslator/radicalMatcher.js @@ -2,18 +2,104 @@ // Système de recherche par radicaux pour le traducteur Confluent→Français // Permet de trouver les formes conjuguées et dérivées à partir des racines -// Suffixes verbaux identifiés dans le corpus -const VERBAL_SUFFIXES = [ - 'ak', // forme standard : mirak (voir), pasak (prendre), urak (être) - 'an', // conjugaison : takan (porter), vokan (parler?) - 'un', // conjugaison : kisun (transmettre), pasun (prendre?) - 'is', // conjugaison : vokis (parler?) - 'am', // conjugaison : sukam (forger) - 'im', // conjugaison : verim (vérifier?) - 'ok', // impératif : marqueur temporel - 'ul', // passé? : marqueur temporel - 'iran', // dérivé nominal : kisiran (enseignement/transmission?) -]; +const lexique = require('../data/lexique.json'); + +// ============================================================================ +// CHARGEMENT DYNAMIQUE DES SUFFIXES DEPUIS LE LEXIQUE +// ============================================================================ + +/** + * Extrait tous les conjugateurs depuis le lexique JSON + * @returns {Array} Liste des conjugateurs (u, at, ok, ul, etc.) + */ +function getConjugateurs() { + const conjugateurs = []; + + if (lexique.conjugateurs) { + // Temps : u, at, aan, ait, amat, en + if (lexique.conjugateurs.temps) { + conjugateurs.push(...Object.keys(lexique.conjugateurs.temps)); + } + + // Aspects : il, eol, eon, eom + if (lexique.conjugateurs.aspects) { + conjugateurs.push(...Object.keys(lexique.conjugateurs.aspects)); + } + + // Modes : ok, es, ul + if (lexique.conjugateurs.modes) { + conjugateurs.push(...Object.keys(lexique.conjugateurs.modes)); + } + + // Évidentiel : uv + if (lexique.conjugateurs.evidentiel) { + conjugateurs.push(...Object.keys(lexique.conjugateurs.evidentiel)); + } + } + + return conjugateurs; +} + +/** + * Extrait les suffixes d'infinitif depuis la liste des verbes + * Analyse les patterns : racine "mira" → verbe "mirak" = suffixe "k" + * @returns {Array} Liste des suffixes d'infinitif (k, s, n, m, etc.) + */ +function getInfinitifSuffixes() { + const suffixes = new Set(); + + if (lexique.verbes) { + for (const verbe of lexique.verbes) { + if (verbe.infinitif && verbe.racine) { + // Extraire le suffixe : infinitif - racine + // Ex: "mirak" - "mira" = "k" + if (verbe.infinitif.startsWith(verbe.racine)) { + const suffix = verbe.infinitif.slice(verbe.racine.length); + if (suffix.length > 0) { + suffixes.add(suffix); + } + } + } + } + } + + // Aussi chercher dans les racines avec propriété "verbe" + if (lexique.racines && lexique.racines.standards) { + for (const categorie of Object.values(lexique.racines.standards)) { + if (Array.isArray(categorie)) { + for (const racine of categorie) { + if (racine.verbe && racine.forme_base) { + // Ex: forme_base "mira" → verbe "mirak" = suffixe "k" + if (racine.verbe.startsWith(racine.forme_base)) { + const suffix = racine.verbe.slice(racine.forme_base.length); + if (suffix.length > 0) { + suffixes.add(suffix); + } + } + } + } + } + } + } + + return Array.from(suffixes); +} + +// Charger les suffixes depuis le lexique +const CONJUGATEURS = getConjugateurs(); +const INFINITIF_SUFFIXES = getInfinitifSuffixes(); + +// Tous les suffixes verbaux = conjugateurs + suffixes d'infinitif +const VERBAL_SUFFIXES = [...CONJUGATEURS, ...INFINITIF_SUFFIXES]; + +console.log('[radicalMatcher] Chargé depuis lexique.json:'); +console.log(` - ${CONJUGATEURS.length} conjugateurs:`, CONJUGATEURS.join(', ')); +console.log(` - ${INFINITIF_SUFFIXES.length} suffixes d'infinitif:`, INFINITIF_SUFFIXES.join(', ')); +console.log(` - ${VERBAL_SUFFIXES.length} suffixes verbaux totaux`); + +// ============================================================================ +// EXTRACTION DES RADICAUX +// ============================================================================ /** * Extrait tous les radicaux possibles d'un mot @@ -23,20 +109,25 @@ const VERBAL_SUFFIXES = [ function extractRadicals(word) { const candidates = []; - // Essayer chaque suffixe verbal connu + // 1. Essayer chaque suffixe verbal connu (conjugateurs + infinitifs) for (const suffix of VERBAL_SUFFIXES) { if (word.endsWith(suffix) && word.length > suffix.length + 1) { const radical = word.slice(0, -suffix.length); + + // Différencier conjugateurs et infinitifs pour la confiance + const isConjugateur = CONJUGATEURS.includes(suffix); + const type = isConjugateur ? 'conjugaison' : 'infinitif'; + candidates.push({ radical, suffix, - type: 'verbal', - confidence: 0.9 + type, + confidence: isConjugateur ? 0.95 : 0.9 }); } } - // Essayer sans suffixe (forme racine directe) + // 2. Essayer sans suffixe (forme racine directe) if (word.length >= 3) { candidates.push({ radical: word, @@ -46,8 +137,8 @@ function extractRadicals(word) { }); } - // Essayer d'enlever dernière voyelle (forme liée -> forme pleine) - // mako → mak, voki → vok + // 3. Essayer d'enlever dernière voyelle (forme liée -> forme pleine) + // Ex: mako → mak, voki → vok if (word.length >= 4 && 'aeiou'.includes(word[word.length - 1])) { candidates.push({ radical: word.slice(0, -1), @@ -63,5 +154,7 @@ function extractRadicals(word) { module.exports = { extractRadicals, - VERBAL_SUFFIXES + VERBAL_SUFFIXES, + CONJUGATEURS, + INFINITIF_SUFFIXES }; diff --git a/ancien-confluent/lexique/00-grammaire.json b/ancien-confluent/lexique/00-grammaire.json index 7f5bb13..e817372 100644 --- a/ancien-confluent/lexique/00-grammaire.json +++ b/ancien-confluent/lexique/00-grammaire.json @@ -438,6 +438,101 @@ "synonymes_fr": [ "elles" ] + }, + "nous": { + "traductions": [ + { + "confluent": "tanu", + "type": "pronom", + "categorie": "personnel", + "note": "Pronom 1ère personne pluriel" + } + ] + }, + "sa": { + "traductions": [ + { + "confluent": "na", + "type": "particule", + "categorie": "possession", + "note": "Possessif (réutilise particule génitif na)" + } + ], + "synonymes_fr": [ + "son", + "ses", + "mon", + "ma", + "mes", + "ton", + "ta", + "tes", + "notre", + "nos", + "votre", + "vos", + "leur", + "leurs" + ] + }, + "ce": { + "traductions": [ + { + "confluent": "ko", + "type": "determinant", + "categorie": "demonstratif", + "note": "Démonstratif (radical ko-)" + } + ], + "synonymes_fr": [ + "cet", + "cette", + "ces" + ] + }, + "avant": { + "traductions": [ + { + "confluent": "at", + "type": "particule", + "categorie": "temps", + "note": "Avant/passé (réutilise marqueur passé at)" + } + ], + "synonymes_fr": [ + "hier", + "auparavant" + ] + }, + "apres": { + "traductions": [ + { + "confluent": "ok", + "type": "particule", + "categorie": "temps", + "note": "Après/futur (réutilise marqueur futur ok)" + } + ], + "synonymes_fr": [ + "après", + "demain", + "ensuite" + ] + }, + "autour": { + "traductions": [ + { + "confluent": "no", + "type": "particule", + "categorie": "lieu", + "note": "Autour/spatial (réutilise particule locative no)" + } + ], + "synonymes_fr": [ + "près", + "proche", + "alentour" + ] } } } \ No newline at end of file diff --git a/ancien-confluent/lexique/06-actions.json b/ancien-confluent/lexique/06-actions.json index c293923..7c834a3 100644 --- a/ancien-confluent/lexique/06-actions.json +++ b/ancien-confluent/lexique/06-actions.json @@ -809,6 +809,20 @@ "domaine": "action", "note": "Consommer de la nourriture" } + ], + "synonymes_fr": [ + "mange", + "manges", + "mangeons", + "mangez", + "mangent", + "mangeais", + "mangeait", + "mangions", + "mangiez", + "mangeaient", + "mangeant", + "mangé" ] }, "devorer": { @@ -935,6 +949,109 @@ "rejoignant", "rejoint" ] + }, + "battre": { + "racine_fr": "bat", + "traductions": [ + { + "confluent": "pulum", + "type": "verbe", + "racine": "pulu", + "forme_liee": "pul", + "structure": "CVCVC", + "domaine": "action", + "note": "Battre (cœur), pulser, rythme vital" + } + ], + "synonymes_fr": [ + "bat", + "bats", + "battons", + "battez", + "battent", + "battais", + "battait", + "battions", + "battiez", + "battaient", + "battant", + "battu" + ] + }, + "penser": { + "racine_fr": "pens", + "traductions": [ + { + "confluent": "umis", + "type": "verbe", + "racine": "umi", + "forme_liee": "um", + "structure": "VCVC", + "domaine": "action_cognitive", + "note": "Penser, réfléchir - activité mentale (même racine que méditer)" + } + ], + "synonymes_fr": [ + "réfléchir", + "pense", + "penses", + "pensons", + "pensez", + "pensent", + "pensais", + "pensait", + "pensions", + "pensiez", + "pensaient", + "pensant", + "pensé", + "réfléchis", + "réfléchit", + "réfléchissons", + "réfléchissez", + "réfléchissent", + "réfléchissais", + "réfléchissait", + "réfléchissions", + "réfléchissiez", + "réfléchissaient", + "réfléchissant", + "réfléchi" + ] + }, + "voler": { + "racine_fr": "vol", + "traductions": [ + { + "confluent": "aliuk", + "type": "verbe", + "racine": "aliu", + "forme_liee": "ali", + "structure": "CVCVC", + "domaine": "action", + "note": "Voler, s'envoler, planer dans les airs" + } + ], + "synonymes_fr": [ + "vole", + "voles", + "volons", + "volez", + "volent", + "volais", + "volait", + "volions", + "voliez", + "volaient", + "volant", + "volé", + "s'envoler", + "envole", + "envoles", + "envolons", + "envolez", + "envolent" + ] } } } \ No newline at end of file diff --git a/ancien-confluent/lexique/23-nourriture.json.backup b/ancien-confluent/lexique/23-nourriture.json.backup new file mode 100644 index 0000000..6f803c9 --- /dev/null +++ b/ancien-confluent/lexique/23-nourriture.json.backup @@ -0,0 +1,374 @@ +{ + "_comment": "Vocabulaire alimentaire et culinaire de la Confluence", + "_source": "Basé sur civjdr/Background/2024-10-28-le-village.md", + "dictionnaire": { + "poisson": { + "racine_fr": "poiss", + "traductions": [ + { + "confluent": "pisu", + "type": "racine", + "forme_liee": "pis", + "structure": "CVCV", + "domaine": "nourriture", + "note": "Poisson - source vitale de protéines (même racine que pêcher)" + } + ], + "synonymes_fr": [ + "poissons" + ] + }, + "gibier": { + "racine_fr": "gibier", + "traductions": [ + { + "confluent": "zana", + "type": "racine", + "forme_liee": "zan", + "structure": "CVCV", + "domaine": "nourriture", + "note": "Gibier chassé (lié à zanak-chasser)" + } + ], + "synonymes_fr": [ + "proie" + ] + }, + "baie": { + "racine_fr": "bai", + "traductions": [ + { + "confluent": "beka", + "type": "racine", + "forme_liee": "bek", + "structure": "CVCV", + "domaine": "nourriture", + "note": "Baies - fruits sauvages essentiels" + } + ], + "synonymes_fr": [ + "baies", + "petits fruits" + ] + }, + "tubercule": { + "racine_fr": "tubercul", + "traductions": [ + { + "confluent": "tuba", + "type": "racine", + "forme_liee": "tub", + "structure": "CVCV", + "domaine": "nourriture", + "note": "Tubercules, racines comestibles" + } + ], + "synonymes_fr": [ + "racine", + "tubercules" + ] + }, + "fruit": { + "racine_fr": "fruit", + "traductions": [ + { + "confluent": "veka", + "type": "racine", + "forme_liee": "vek", + "structure": "CVCV", + "domaine": "nourriture", + "note": "Fruits génériques" + } + ], + "synonymes_fr": [ + "fruits" + ] + }, + "mollusque": { + "racine_fr": "mollusqu", + "traductions": [ + { + "confluent": "molu", + "type": "racine", + "forme_liee": "mol", + "structure": "CVCV", + "domaine": "nourriture", + "note": "Mollusques, coquillages" + } + ], + "synonymes_fr": [ + "coquillage", + "mollusques" + ] + }, + "graine": { + "racine_fr": "grain", + "traductions": [ + { + "confluent": "seka", + "type": "racine", + "forme_liee": "sek", + "structure": "CVCV", + "domaine": "nourriture", + "note": "Graines comestibles" + } + ], + "synonymes_fr": [ + "graines", + "semence" + ] + }, + "galette": { + "racine_fr": "galet", + "traductions": [ + { + "confluent": "panu", + "type": "racine", + "forme_liee": "pan", + "structure": "CVCV", + "domaine": "nourriture", + "note": "Galette, pain plat" + } + ], + "synonymes_fr": [ + "pain", + "crêpe", + "galettes" + ] + }, + "herbe": { + "racine_fr": "herb", + "traductions": [ + { + "confluent": "pala", + "type": "racine", + "forme_liee": "pal", + "structure": "CVCV", + "domaine": "nourriture", + "note": "Herbes aromatiques" + } + ], + "synonymes_fr": [ + "herbes", + "aromate", + "aromates" + ] + }, + "morsure-des-ancetres": { + "racine_fr": null, + "traductions": [ + { + "confluent": "aiteopalu", + "type": "composition", + "composition": "ait-eo-palu", + "sens_litteral": "Ancêtre-éternel-qui-brûle", + "racines": ["aita", "palu"], + "liaison": "eo", + "structure": "composition_sacree", + "domaine": "nourriture_sacree", + "note": "Gingembre sauvage très estimé, épice sacrée - utilise liaison sacrée eo (totalité/éternel)" + } + ], + "synonymes_fr": [ + "gingembre sauvage", + "epice sacree" + ] + }, + "larmes-du-ciel": { + "racine_fr": null, + "traductions": [ + { + "confluent": "zeruosi", + "type": "composition", + "composition": "zer-u-osi", + "sens_litteral": "Ciel-de-mort (larmes célestes)", + "racines": ["zeru", "osi"], + "liaison": "u", + "structure": "composition_sacree", + "domaine": "nourriture_sacree", + "note": "Plat cérémoniel traditionnel - poisson fumé, gibier, Morsure-des-Ancêtres, herbes et baies. Utilise liaison u (appartenance)" + } + ], + "synonymes_fr": [ + "plat ceremoniel", + "plat traditionnel" + ] + }, + "fumer": { + "racine_fr": "fum", + "traductions": [ + { + "confluent": "simus", + "type": "verbe", + "racine": "simu", + "forme_liee": "sim", + "structure": "CVCV", + "domaine": "technique_culinaire", + "note": "Fumer (aliment), technique de conservation" + } + ], + "synonymes_fr": [ + "fume", + "fumes", + "fumons", + "fumez", + "fument", + "fumais", + "fumait", + "fumions", + "fumiez", + "fumaient", + "fumant", + "fumé", + "fumée" + ] + }, + "secher": { + "racine_fr": "séch", + "traductions": [ + { + "confluent": "sekus", + "type": "verbe", + "racine": "seku", + "forme_liee": "sek", + "structure": "CVCV", + "domaine": "technique_culinaire", + "note": "Sécher (aliment), conservation" + } + ], + "synonymes_fr": [ + "sécher", + "sèche", + "sèches", + "séchons", + "séchez", + "sèchent", + "séchais", + "séchait", + "séchions", + "séchiez", + "séchaient", + "séchant", + "séché", + "sec", + "sèche" + ] + }, + "griller": { + "racine_fr": "grill", + "traductions": [ + { + "confluent": "palus", + "type": "verbe", + "racine": "palu", + "forme_liee": "pal", + "structure": "CVCV", + "domaine": "technique_culinaire", + "note": "Griller, cuire sur feu" + } + ], + "synonymes_fr": [ + "grille", + "grilles", + "grillons", + "grillez", + "grillent", + "grillais", + "grillait", + "grillions", + "grilliez", + "grillaient", + "grillant", + "grillé", + "cuire", + "rôtir" + ] + }, + "cuisiner": { + "racine_fr": "cuisin", + "traductions": [ + { + "confluent": "nekas", + "type": "verbe", + "racine": "neka", + "forme_liee": "nek", + "structure": "CVCV", + "domaine": "technique_culinaire", + "note": "Cuisiner, préparer (même racine que faire)" + } + ], + "synonymes_fr": [ + "cuisine", + "cuisines", + "cuisinons", + "cuisinez", + "cuisinent", + "cuisinais", + "cuisinait", + "cuisinions", + "cuisiniez", + "cuisinaient", + "cuisinant", + "cuisiné", + "preparer", + "préparer" + ] + }, + "infuser": { + "racine_fr": "infus", + "traductions": [ + { + "confluent": "urapis", + "type": "composition", + "composition": "ura-pis", + "sens_litteral": "Eau-tremper", + "racines": ["ura", "pisu"], + "structure": "composition", + "domaine": "technique_culinaire", + "note": "Infuser, faire tremper dans l'eau" + } + ], + "synonymes_fr": [ + "infuse", + "infusion", + "tremper" + ] + }, + "reserve": { + "racine_fr": "réserv", + "traductions": [ + { + "confluent": "zaku", + "type": "racine", + "forme_liee": "zak", + "structure": "CVCV", + "domaine": "nourriture", + "note": "Réserves alimentaires (lié à garder/protéger)" + } + ], + "synonymes_fr": [ + "réserves", + "provisions", + "stock" + ] + }, + "nourriture": { + "racine_fr": "nourritur", + "traductions": [ + { + "confluent": "muki", + "type": "racine", + "forme_liee": "muk", + "structure": "CVCV", + "domaine": "nourriture", + "note": "Nourriture (racine de manger)" + } + ], + "synonymes_fr": [ + "aliment", + "aliments", + "repas" + ] + } + } +}