# TYPING.COM AUTO-TYPER

Ultra-Fast Automated Typing

Complete Lessons Instantly

150+
WPM Speed
⚡
Auto-Continue
♾️
Infinite Lessons
🤖

### Fully Automated

Set it once and forget it. Automatically types every lesson and clicks continue buttons.

🎯

### Human-Like Typing

Realistic typing patterns with random variations, occasional errors, and natural pauses.

🔄

### Continuous Loop

Keeps running through unlimited lessons. Works even after page refreshes!

## Setup in 3 Simple Steps

1
Install Requirements
Run: pip install pyautogui flask flask-cors
2
Run Python Server
Save the script below and run: python typer.py
3
Paste JavaScript
Copy the browser code shown in terminal, paste in console, press Enter. Done!
Python Server Script - Save as typer.py

                        #!/usr/bin/env python3
    """
    Typing.com Auto-Typer - Server that receives text from browser and types it
    Run this, then run the JavaScript bookmarklet in your browser

    Requirements: pip install pyautogui flask flask-cors
    Usage: python typer.py
    """

    import time
    import random
    import pyautogui
    from flask import Flask, request, jsonify
    from flask_cors import CORS

    app = Flask(__name__)
    CORS(app)  # Allow requests from browser

    # Configuration
    CONFIG = {
        'base_wpm': 150,  # Much faster!
        'wpm_variation': 15,
        'error_rate': 0.01,  # Fewer errors at high speed
        'pause_after_word': 0.02,  # Shorter pauses
    }

    def get_keystroke_delay():
        """Calculate delay between keystrokes based on WPM with variation"""
        wpm = CONFIG['base_wpm'] + (random.random() * CONFIG['wpm_variation'] * 2 - CONFIG['wpm_variation'])
        cpm = wpm * 5
        ms_per_char = 60.0 / cpm
        return ms_per_char + (random.random() * 0.02 - 0.01)

    def type_text_realistic(text):
        """Type text with realistic timing and occasional errors"""
        print(f"\nTyping text ({len(text)} chars): {text[:50]}...")
        print("You have 3 seconds to switch to typing.com window!")
        time.sleep(3)

        print("Typing now...")

        for i, char in enumerate(text):
            # Check for special characters
            if char == '⏎':
                print("  [Enter key]")
                pyautogui.press('enter')
                time.sleep(0.1)
                continue
            elif char == '⇥' or char == '→':  # Tab key (various arrow symbols)
                print("  [Tab key]")
                pyautogui.press('tab')
                time.sleep(0.1)
                continue

            # Simulate occasional typo (skip for spaces and special keys)
            if random.random() < CONFIG['error_rate'] and char != ' ':
                wrong_char = chr(ord(char) + (1 if random.random() > 0.5 else -1))
                pyautogui.write(wrong_char, interval=0)
                time.sleep(0.05)
                pyautogui.press('backspace')
                time.sleep(0.05)

            # Type correct character
            if char == ' ':
                pyautogui.press('space')
                time.sleep(CONFIG['pause_after_word'])
            else:
                pyautogui.write(char, interval=0)
                time.sleep(get_keystroke_delay())

            # Progress indicator every 50 chars
            if (i + 1) % 50 == 0:
                print(f"Progress: {i+1}/{len(text)} chars")

        print("\n✓ Typing complete!")

        # Wait a moment before pressing Enter
        time.sleep(1.0)

        # Press Enter to submit/continue
        print("Pressing Enter to continue...")
        pyautogui.press('enter')
        time.sleep(0.3)

        print("✓ Waiting for next lesson to load...")

    @app.route('/type', methods=['POST'])
    def type_endpoint():
        """Endpoint that receives text from browser and types it"""
        data = request.get_json()
        text = data.get('text', '')

        if not text:
            return jsonify({'error': 'No text provided'}), 400

        print(f"\n{'='*60}")
        print(f"Received text from browser")
        print(f"{'='*60}")

        # Type the text
        type_text_realistic(text)

        return jsonify({'success': True, 'message': 'Typing complete'})

    @app.route('/health', methods=['GET'])
    def health():
        """Health check endpoint"""
        return jsonify({'status': 'running', 'message': 'Typer server is ready'})

    if __name__ == '__main__':
        pyautogui.FAILSAFE = True  # Move mouse to corner to stop

        print("="*60)
        print("Typing.com Auto-Typer Server")
        print("="*60)
        print("\nServer starting on http://localhost:5000")
        print("\nNow run this JavaScript in your browser console:")
        print("\n" + "="*60)
        print("""
    // === PASTE THIS IN BROWSER CONSOLE ===

    (async function() {
        // Extract text from typing.com
        function extractText() {
            const words = [];
            const wordElements = document.querySelectorAll('.screenBasic-word');

            wordElements.forEach(wordEl => {
                let word = '';
                const letters = wordEl.querySelectorAll('.screenBasic-letter');

                letters.forEach(letter => {
                    const text = letter.textContent.trim();
                    if (text && text !== '\\u00A0') {
                        word += text;
                    }
                });

                if (word) {
                    words.push(word);
                }
            });

            return words.join(' ');
        }

        // Wait for continue button and click it
        function waitForContinueButton() {
            return new Promise((resolve) => {
                const checkInterval = setInterval(() => {
                    const continueBtn = document.querySelector('.js-continue-button');
                    if (continueBtn && continueBtn.offsetParent !== null) {
                        console.log('✓ Found continue button, clicking...');
                        clearInterval(checkInterval);
                        continueBtn.click();
                        setTimeout(resolve, 1000);
                    }
                }, 500);
            });
        }

        // Main loop - keeps running lessons
        async function autoTypeLoop() {
            while (true) {
                // Wait a bit for page to load
                await new Promise(r => setTimeout(r, 2000));

                // Check if we're on completion screen
                const continueBtn = document.querySelector('.js-continue-button');
                if (continueBtn && continueBtn.offsetParent !== null) {
                    console.log('On completion screen, clicking continue...');
                    continueBtn.click();
                    await new Promise(r => setTimeout(r, 2000));
                    continue;
                }

                // Extract text from current lesson
                const text = extractText();
                if (!text) {
                    console.log('No text found, waiting...');
                    await new Promise(r => setTimeout(r, 2000));
                    continue;
                }

                console.log('Extracted text:', text);
                console.log('Sending to typer server...');

                try {
                    const response = await fetch('http://localhost:5000/type', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                        },
                        body: JSON.stringify({ text: text })
                    });

                    const result = await response.json();
                    console.log('Server response:', result);

                    if (result.success) {
                        console.log('✓ Typing complete! Waiting for next lesson...');
                        // Wait for completion screen and continue button
                        await waitForContinueButton();
                    }
                } catch (error) {
                    console.error('Error:', error);
                    console.error('Make sure Python server is running: python typer.py');
                    break;
                }
            }
        }

        console.log('🚀 Starting auto-typer loop! It will continue through all lessons.');
        console.log('To stop: Close this console or refresh the page');
        autoTypeLoop();
    })();

    // === END ===
    """)
        print("="*60)
        print("\nInstructions:")
        print("1. Go to typing.com and start any lesson")
        print("2. Open browser console (F12)")
        print("3. Copy and paste the JavaScript code ONCE")
        print("4. Press Enter")
        print("5. DONE! It will now:")
        print("   ✓ Auto-click instruction screens")
        print("   ✓ Type every lesson automatically")
        print("   ✓ Click continue to next lesson")
        print("   ✓ Keep running forever (even after page refreshes)")
        print("   ✓ You NEVER need to paste it again!")
        print("\nTo stop permanently:")
        print("   localStorage.removeItem('autoTyperScript')")
        print("   Then refresh the page")
        print("\nFailsafe: Move mouse to top-left corner")
        print("="*60)

        app.run(host='localhost', port=5000, debug=False)