(async () => {
const targetValue = document.getElementById('type_text').value;
const inputArea = document.getElementById('type');
// Reset du champ
inputArea.value = "";
inputArea.focus();
// Calcul du délai pour 75 WPM (160ms en moyenne)
const getHumanDelay = (isSpecial) => {
let base = 160;
let randomVariation = Math.floor(Math.random() * 60) - 30; // +/- 30ms
return isSpecial ? base + randomVariation + 100 : base + randomVariation;
};
console.log("Démarrage... (Mode Événements Seuls - Cible 75 WPM)");
for (let i = 0; i < targetValue.length; i++) {
let char = targetValue[i];
let charCode;
let keyName;
// Gestion du retour chariot (le fameux \n ou ¶)
if (char === '¶') {
charCode = 13;
keyName = 'Enter';
} else if (char === '\\' && targetValue[i + 1] === 'n') {
charCode = 13;
keyName = 'Enter';
i++; // On saute le 'n'
} else {
charCode = char.charCodeAt(0);
keyName = char;
}
const eventParams = {
key: keyName,
keyCode: charCode,
which: charCode,
charCode: charCode,
bubbles: true,
cancelable: true
};
// ON ENVOIE UNIQUEMENT LES ÉVÉNEMENTS
// Le site capte ces événements et écrit lui-même dans le textarea
inputArea.dispatchEvent(new KeyboardEvent('keydown', eventParams));
inputArea.dispatchEvent(new KeyboardEvent('keypress', eventParams));
inputArea.dispatchEvent(new KeyboardEvent('keyup', eventParams));
// On force la notification de modification
inputArea.dispatchEvent(new Event('input', { bubbles: true }));
// Pause pour la vitesse demandée
await new Promise(r => setTimeout(r, getHumanDelay(keyName === 'Enter' || char === ' ')));
}
console.log("Terminé sans doublons !");
})();