function isContrastTrainingLesson(lessonType, lessonTitle = '') { const normalizedType = String(lessonType || '').toLowerCase(); if (normalizedType !== 'grammar') { return false; } const title = String(lessonTitle || '').toLowerCase(); return [ 'kontrast', 'fehlertraining', ' / ', 'nicht / kein', 'der / die / das', 'wo / wohin', 'du / sie', 'haben / sein', 'ich bin / ich habe', 'ich bin / ich heiße / ich komme' ].some((marker) => title.includes(marker)); } export function getGermanForBisayaLessonPedagogy(lessonNumber, lessonType, lessonTitle = '') { const phaseLabel = lessonNumber <= 60 ? 'quickstart' : lessonNumber <= 120 ? 'daily_life' : 'stabilization'; const blockNumber = Math.ceil(lessonNumber / 10); let didacticMode = 'core_input'; if (lessonType === 'conversation') didacticMode = 'guided_dialogue'; if (lessonType === 'grammar') didacticMode = 'pattern_drill'; if (isContrastTrainingLesson(lessonType, lessonTitle)) didacticMode = 'contrast_training'; if (lessonType === 'review') didacticMode = 'intensive_review'; if (lessonType === 'culture') didacticMode = 'real_life_scenario'; const difficultyWeight = didacticMode === 'contrast_training' ? 3 : lessonType === 'grammar' ? 3 : lessonType === 'review' ? 2 : lessonType === 'conversation' ? 2 : 1; const newUnitTarget = lessonType === 'review' ? 2 : didacticMode === 'contrast_training' ? 3 : lessonType === 'grammar' ? 4 : phaseLabel === 'quickstart' ? 6 : phaseLabel === 'daily_life' ? 5 : 4; const reviewWeight = lessonType === 'review' ? 90 : didacticMode === 'contrast_training' ? 70 : lessonType === 'grammar' ? 60 : lessonType === 'vocab' ? 55 : lessonType === 'culture' ? 20 : 35; return { phaseLabel, blockNumber, didacticMode, difficultyWeight, newUnitTarget, reviewWeight, isIntensiveReview: lessonType === 'review' }; } export function getGermanForBisayaProgressTargets(lessonData, pedagogy) { const baseMinutes = Number(lessonData?.targetMin || 18); const baseScore = Number(lessonData?.targetScore || 80); const lessonNumber = Number(lessonData?.num || 1); const lessonType = String(lessonData?.type || ''); const didacticMode = String(pedagogy?.didacticMode || ''); const isCheckpoint = String(lessonData?.title || '').toLowerCase().includes('checkpoint'); // Spuerbar steilere Progression: spaetere Wochen bekommen mehr Produktionszeit // und hoehere Zielwerte, ohne den Einstieg zu ueberfrachten. let minutesBump = 0; if (lessonNumber >= 61 && lessonNumber <= 90) minutesBump += 2; if (lessonNumber >= 91 && lessonNumber <= 120) minutesBump += 4; if (lessonNumber >= 121) minutesBump += 6; if (lessonType === 'conversation' && lessonNumber >= 91) minutesBump += 2; if (lessonType === 'review') minutesBump += 3; if (isCheckpoint) minutesBump += 2; let scoreBump = 0; if (lessonNumber >= 61 && lessonNumber <= 90) scoreBump += 2; if (lessonNumber >= 91 && lessonNumber <= 120) scoreBump += 4; if (lessonNumber >= 121) scoreBump += 6; if (lessonType === 'grammar') scoreBump += 2; if (lessonType === 'review') scoreBump += 2; if (didacticMode === 'contrast_training') scoreBump += 1; if (isCheckpoint) scoreBump += 3; const targetMinutes = Math.min(45, baseMinutes + minutesBump); const targetScorePercent = lessonType === 'culture' ? 0 : Math.min(96, baseScore + scoreBump); return { targetMinutes, targetScorePercent }; }