| (function () {
|
| console.log("%c Monkeytype Command Typer (execCommand) ", "background: #222; color: #ff0000; font-size: 20px");
|
|
|
| const CONFIG = {
|
| minWPM: 310,
|
| maxWPM: 550,
|
| errorRate: 0.05,
|
| accuracy: 95,
|
| startDelay: 50,
|
| };
|
|
|
| let isArmed = true;
|
|
|
|
|
|
|
|
|
| function typeChar(char) {
|
| const target = document.activeElement || document.body;
|
| const keyConfig = {
|
| key: char,
|
| code: char === ' ' ? 'Space' : `Key${char.toUpperCase()}`,
|
| bubbles: true,
|
| cancelable: true,
|
| view: window
|
| };
|
|
|
|
|
| target.dispatchEvent(new KeyboardEvent('keydown', keyConfig));
|
|
|
|
|
| target.dispatchEvent(new KeyboardEvent('keypress', keyConfig));
|
|
|
|
|
| document.execCommand('insertText', false, char);
|
|
|
|
|
|
|
|
|
|
|
| target.dispatchEvent(new KeyboardEvent('keyup', keyConfig));
|
| }
|
|
|
|
|
| function sleep(ms) {
|
| return new Promise(resolve => setTimeout(resolve, ms));
|
| }
|
|
|
|
|
|
|
|
|
| function getKeystrokeDelay() {
|
|
|
| const currentWPM = Math.floor(Math.random() * (CONFIG.maxWPM - CONFIG.minWPM + 1)) + CONFIG.minWPM;
|
| const baseDelay = 60000 / (currentWPM * 5);
|
|
|
|
|
| const variance = baseDelay * 0.2;
|
| const noise = (Math.random() * variance * 2) - variance;
|
|
|
| return Math.max(10, baseDelay + noise);
|
| }
|
|
|
| async function simulateMistake(correctChar) {
|
| const possibleMistakes = "abcdefghijklmnopqrstuvwxyz";
|
| const distinctMistake = possibleMistakes.charAt(Math.floor(Math.random() * possibleMistakes.length));
|
|
|
|
|
| typeChar(distinctMistake);
|
|
|
|
|
| await sleep(getKeystrokeDelay() * 2.5);
|
|
|
|
|
|
|
|
|
| const target = document.activeElement || document.body;
|
| const bsConfig = { key: 'Backspace', code: 'Backspace', bubbles: true, cancelable: true, view: window };
|
|
|
| target.dispatchEvent(new KeyboardEvent('keydown', bsConfig));
|
| document.execCommand('delete', false, null);
|
| target.dispatchEvent(new KeyboardEvent('keyup', bsConfig));
|
|
|
|
|
| await sleep(getKeystrokeDelay() * 1.5);
|
| }
|
|
|
|
|
| function getCurrentWordText() {
|
| const activeWord = document.querySelector('#words .word.active');
|
| if (!activeWord) return null;
|
|
|
| const letters = activeWord.querySelectorAll('letter');
|
| let text = "";
|
| let foundUntyped = false;
|
|
|
| for (const letter of letters) {
|
|
|
| if (!letter.classList.contains('correct') && !letter.classList.contains('incorrect')) {
|
| foundUntyped = true;
|
| }
|
| if (foundUntyped) {
|
| text += letter.textContent;
|
| }
|
| }
|
|
|
| return text;
|
| }
|
|
|
|
|
| async function autoTypeLoop() {
|
| console.log("Starting continuous auto-type loop...");
|
|
|
| let wordCount = 0;
|
| while (true) {
|
|
|
| const currentWordText = getCurrentWordText();
|
|
|
| if (currentWordText === null) {
|
|
|
| console.log(`Auto-type complete! Typed ${wordCount} words.`);
|
| break;
|
| }
|
|
|
| if (currentWordText.length === 0) {
|
|
|
|
|
| const activeWord = document.querySelector('#words .word.active');
|
| const nextWord = activeWord ? activeWord.nextElementSibling : null;
|
|
|
| if (!nextWord || !nextWord.classList.contains('word')) {
|
|
|
| await sleep(50);
|
| const stillActive = document.querySelector('#words .word.active');
|
| if (!stillActive) {
|
| console.log(`Auto-type complete! Typed ${wordCount} words.`);
|
| break;
|
| }
|
| continue;
|
| }
|
|
|
|
|
| typeChar(' ');
|
| wordCount++;
|
|
|
| let delay = getKeystrokeDelay() * 1.3;
|
| await sleep(delay);
|
| continue;
|
| }
|
|
|
|
|
| const char = currentWordText[0];
|
|
|
|
|
| if (/[a-zA-Z]/.test(char) && Math.random() < CONFIG.errorRate) {
|
| await simulateMistake(char);
|
| }
|
|
|
| typeChar(char);
|
|
|
| let delay = getKeystrokeDelay();
|
| await sleep(delay);
|
| }
|
| }
|
|
|
| const triggerHandler = (e) => {
|
| if (!isArmed) return;
|
|
|
| if (e.key.length === 1 && !e.ctrlKey && !e.altKey && !e.metaKey) {
|
|
|
| const activeWord = document.querySelector('#words .word.active');
|
| if (!activeWord) return;
|
|
|
| const firstLetterElement = activeWord.querySelector('letter');
|
| const firstLetter = firstLetterElement ? firstLetterElement.textContent : null;
|
|
|
| if (firstLetter && e.key === firstLetter) {
|
| isArmed = false;
|
| window.removeEventListener('keydown', triggerHandler);
|
|
|
| console.log("Trigger detected. Starting Command Typer...");
|
| setTimeout(() => {
|
| autoTypeLoop();
|
| }, CONFIG.startDelay);
|
| }
|
| }
|
| };
|
|
|
| window.addEventListener('keydown', triggerHandler);
|
| console.log("READY! Type the first letter to test Command Mode.");
|
| })();
|
|
|