// ======================================== // FICHIER: ErrorMoyenne.js // RESPONSABILITÉ: Erreurs MOYENNES (30% articles) // Subtiles mais détectables - erreurs d'inattention // ======================================== const { logSh } = require('../../ErrorReporting'); /** * DÉFINITIONS ERREURS MOYENNES * Probabilité globale: 30% des articles * Maximum: 2 erreurs moyennes par article */ const ERREURS_MOYENNES = { // ======================================== // ACCORD PLURIEL OUBLIÉ // ======================================== accord_pluriel: { name: 'Accord pluriel oublié', probability: 0.25, examples: [ { pattern: 'les plaques résistantes', error: 'les plaques résistant' }, { pattern: 'des matériaux durables', error: 'des matériaux durable' } ], apply: (content) => { let modified = content; let applied = false; // Supprimer 's' final sur adjectif après "les" ou "des" const patterns = [ { from: /\bles plaques résistantes\b/gi, to: 'les plaques résistant' }, { from: /\bdes matériaux durables\b/gi, to: 'des matériaux durable' }, { from: /\bdes solutions efficaces\b/gi, to: 'des solutions efficace' }, { from: /\bdes produits innovants\b/gi, to: 'des produits innovant' } ]; for (const pattern of patterns) { if (applied) break; if (modified.match(pattern.from) && Math.random() < 0.4) { modified = modified.replace(pattern.from, pattern.to); applied = true; logSh(` ⚠️ Erreur moyenne: accord pluriel oublié`, 'DEBUG'); break; } } return { content: modified, applied }; } }, // ======================================== // VIRGULE MANQUANTE // ======================================== virgule_manquante: { name: 'Virgule manquante', probability: 0.30, examples: [ { pattern: 'Ainsi, il est', error: 'Ainsi il est' }, { pattern: 'Par conséquent, nous', error: 'Par conséquent nous' } ], apply: (content) => { let modified = content; let applied = false; // Supprimer virgule après connecteurs const patterns = [ { from: /\bAinsi, /gi, to: 'Ainsi ' }, { from: /\bPar conséquent, /gi, to: 'Par conséquent ' }, { from: /\bToutefois, /gi, to: 'Toutefois ' }, { from: /\bCependant, /gi, to: 'Cependant ' }, { from: /\bEn effet, /gi, to: 'En effet ' } ]; for (const pattern of patterns) { if (applied) break; if (modified.match(pattern.from) && Math.random() < 0.5) { modified = modified.replace(pattern.from, pattern.to); applied = true; logSh(` ⚠️ Erreur moyenne: virgule manquante après connecteur`, 'DEBUG'); break; } } return { content: modified, applied }; } }, // ======================================== // CHANGEMENT REGISTRE INAPPROPRIÉ // ======================================== registre_changement: { name: 'Changement registre inapproprié', probability: 0.20, examples: [ { pattern: 'Par conséquent', error: 'Du coup' }, { pattern: 'toutefois', error: 'mais bon' } ], apply: (content) => { let modified = content; let applied = false; // Remplacer formel par familier const patterns = [ { from: /\bPar conséquent\b/g, to: 'Du coup' }, { from: /\btoutefois\b/gi, to: 'mais bon' }, { from: /\bnéanmoins\b/gi, to: 'quand même' } ]; for (const pattern of patterns) { if (applied) break; if (modified.match(pattern.from) && Math.random() < 0.4) { modified = modified.replace(pattern.from, pattern.to); applied = true; logSh(` ⚠️ Erreur moyenne: registre inapproprié (formel → familier)`, 'DEBUG'); break; } } return { content: modified, applied }; } }, // ======================================== // PRÉPOSITION INCORRECTE // ======================================== preposition_incorrecte: { name: 'Préposition incorrecte', probability: 0.15, examples: [ { pattern: 'résistant aux intempéries', error: 'résistant des intempéries' }, { pattern: 'adapté à vos besoins', error: 'adapté pour vos besoins' } ], apply: (content) => { let modified = content; let applied = false; // Remplacer préposition correcte par incorrecte const patterns = [ { from: /\brésistant aux intempéries\b/gi, to: 'résistant des intempéries' }, { from: /\badapté à vos besoins\b/gi, to: 'adapté pour vos besoins' }, { from: /\bconçu pour résister\b/gi, to: 'conçu à résister' } ]; for (const pattern of patterns) { if (applied) break; if (modified.match(pattern.from) && Math.random() < 0.5) { modified = modified.replace(pattern.from, pattern.to); applied = true; logSh(` ⚠️ Erreur moyenne: préposition incorrecte`, 'DEBUG'); break; } } return { content: modified, applied }; } }, // ======================================== // CONNECTEUR INAPPROPRIÉ // ======================================== connecteur_inapproprie: { name: 'Connecteur logique inapproprié', probability: 0.10, examples: [ { pattern: 'et donc', error: 'et mais' }, { pattern: 'cependant il faut', error: 'donc il faut' } ], apply: (content) => { let modified = content; let applied = false; // Remplacer connecteur par un illogique if (modified.includes('cependant') && Math.random() < 0.5) { modified = modified.replace(/\bcependant\b/i, 'donc'); applied = true; logSh(` ⚠️ Erreur moyenne: connecteur inapproprié "cependant" → "donc"`, 'DEBUG'); } return { content: modified, applied }; } } }; /** * APPLIQUER ERREURS MOYENNES * @param {string} content - Contenu à modifier * @param {number} maxErrors - Maximum erreurs moyennes (défaut: 2) * @param {object} tracker - HumanSimulationTracker instance * @returns {object} - { content, errorsApplied, errorTypes } */ function applyErrorsMoyennes(content, maxErrors = 2, tracker = null) { let modified = content; let errorsApplied = 0; const errorTypes = []; // Vérifier avec tracker combien d'erreurs moyennes déjà appliquées if (tracker && tracker.moyenneErrorsApplied >= maxErrors) { logSh(`🚫 Erreurs moyennes bloquées: déjà ${tracker.moyenneErrorsApplied} erreur(s) dans cet article`, 'DEBUG'); return { content: modified, errorsApplied: 0, errorTypes: [] }; } // Appliquer jusqu'à maxErrors const availableErrors = Object.keys(ERREURS_MOYENNES); while (errorsApplied < maxErrors && availableErrors.length > 0) { // Sélectionner type aléatoire const randomIndex = Math.floor(Math.random() * availableErrors.length); const selectedType = availableErrors[randomIndex]; const errorDefinition = ERREURS_MOYENNES[selectedType]; logSh(`🎲 Tentative erreur moyenne: ${errorDefinition.name}`, 'DEBUG'); // Appliquer const result = errorDefinition.apply(modified); if (result.applied) { modified = result.content; errorsApplied++; errorTypes.push(selectedType); logSh(`✅ Erreur moyenne appliquée: ${errorDefinition.name}`, 'DEBUG'); // Marquer dans tracker if (tracker) { tracker.moyenneErrorsApplied = (tracker.moyenneErrorsApplied || 0) + 1; } } // Retirer de la liste pour éviter doublon availableErrors.splice(randomIndex, 1); } return { content: modified, errorsApplied, errorTypes }; } /** * OBTENIR STATISTIQUES ERREURS MOYENNES */ function getErrorMoyenneStats() { return { totalTypes: Object.keys(ERREURS_MOYENNES).length, types: Object.keys(ERREURS_MOYENNES), globalProbability: '30%', maxPerArticle: 2 }; } // ============= EXPORTS ============= module.exports = { ERREURS_MOYENNES, applyErrorsMoyennes, getErrorMoyenneStats };