{"version":3,"file":"useHumanLike-BFxeOC2S.cjs","sources":["../src/constants/index.ts","../src/keyboard/mobile-layouts.ts","../src/keyboard/desktop-layouts.ts","../src/keyboard/timing-profiles.ts","../src/keyboard/KeyboardAnalyzer.ts","../src/utils/TypingEngine.ts","../src/hooks/useHumanLike.ts"],"sourcesContent":["import type { HumanLikeConfig } from '../types';\n\nexport const TIMING_CONSTANTS = {\n  BASE_SPEED: 80,              // Average milliseconds per character\n  SPEED_VARIATION: 40,         // Random timing variation (±40ms)\n  MIN_CHAR_DELAY: 25,          // Minimum delay between characters\n  \n  // Punctuation and Structure\n  SENTENCE_PAUSE: 500,         // Pause after . ! ?\n  COMMA_PAUSE: 200,            // Pause after , ; :\n  WORD_SPACE: 150,             // Pause between words\n  LINE_BREAK: 800,             // Pause for new paragraphs\n  \n  // Mistake Handling\n  REALIZATION_DELAY: 300,      // Time to notice mistake\n  CORRECTION_PAUSE: 250,       // Pause before retyping\n  BACKSPACE_SPEED: 60,         // Speed of corrections\n  \n  // Human Behavior\n  THINKING_PAUSE: 400,         // Pause before complex words\n  FATIGUE_INCREMENT: 0.5,      // Gradual slowdown per 100 chars\n  BURST_SPEED_MULTIPLIER: 0.6, // Speed multiplier during bursts\n  CONCENTRATION_PAUSE: 800,    // Duration of concentration lapses\n  \n  // Enhanced Realism\n  SHIFT_HESITATION: 100,       // Extra delay for shift key characters (increased)\n  CAPS_LOCK_ON_DELAY: 150,     // Delay when turning CAPS LOCK on\n  CAPS_LOCK_OFF_DELAY: 100,    // Delay when turning CAPS LOCK off\n  CAPS_SEQUENCE_THRESHOLD: 3,  // Min consecutive caps to trigger CAPS LOCK mode\n  NUMBER_ROW_PENALTY: 35,      // Extra delay for number characters\n  SYMBOL_BASE_PENALTY: 25,     // Base extra delay for symbols\n  LOOK_AHEAD_CHANCE: 0.08,     // 8% chance of look-ahead typing\n} as const;\n\nexport const BEHAVIOR_RATES = {\n  MISTAKE_FREQUENCY: 0.03,     // 3% base mistake rate\n  CONCENTRATION_LAPSE: 0.03,   // 3% random pause chance\n  BURST_TYPING: 0.15,          // 15% rapid sequence chance\n  FATIGUE_FACTOR: 0.0001,      // Gradual slowdown rate\n  OVERCORRECTION_RATE: 0.2,    // 20% chance of making mistake while correcting\n} as const;\n\n// Desktop QWERTY keyboard layout for adjacent key mistakes\nexport const DESKTOP_ADJACENT: Record<string, string[]> = {\n  'q': ['w', 'a', 's'],\n  'w': ['q', 'e', 'a', 's', 'd'],\n  'e': ['w', 'r', 's', 'd', 'f'],\n  'r': ['e', 't', 'd', 'f', 'g'],\n  't': ['r', 'y', 'f', 'g', 'h'],\n  'y': ['t', 'u', 'g', 'h', 'j'],\n  'u': ['y', 'i', 'h', 'j', 'k'],\n  'i': ['u', 'o', 'j', 'k', 'l'],\n  'o': ['i', 'p', 'k', 'l', ';'],\n  'p': ['o', '[', 'l', ';', \"'\"],\n  '[': ['p', ']', ';', \"'\"],\n  ']': ['[', '\\\\', \"'\"],\n  \n  'a': ['q', 'w', 's', 'z'],\n  's': ['q', 'w', 'e', 'a', 'd', 'z', 'x'],\n  'd': ['w', 'e', 'r', 's', 'f', 'x', 'c'],\n  'f': ['e', 'r', 't', 'd', 'g', 'c', 'v'],\n  'g': ['r', 't', 'y', 'f', 'h', 'v', 'b'],\n  'h': ['t', 'y', 'u', 'g', 'j', 'b', 'n'],\n  'j': ['y', 'u', 'i', 'h', 'k', 'n', 'm'],\n  'k': ['u', 'i', 'o', 'j', 'l', 'm', ','],\n  'l': ['i', 'o', 'p', 'k', ';', ',', '.'],\n  ';': ['o', 'p', '[', 'l', \"'\", '.', '/'],\n  \"'\": ['p', '[', ']', ';', '/', '.'],\n  \n  'z': ['a', 's', 'x'],\n  'x': ['z', 's', 'd', 'c'],\n  'c': ['x', 'd', 'f', 'v', ' '],\n  'v': ['c', 'f', 'g', 'b', ' '],\n  'b': ['v', 'g', 'h', 'n', ' '],\n  'n': ['b', 'h', 'j', 'm', ' '],\n  'm': ['n', 'j', 'k', ',', ' '],\n  ',': ['m', 'k', 'l', '.'],\n  '.': [',', 'l', ';', '/', \"'\"],\n  '/': ['.', ';', \"'\"],\n  \n  ' ': ['c', 'v', 'b', 'n', 'm'], // Space bar adjacent to bottom row\n};\n\n// Mobile keyboard layout for adjacent key mistakes (touch-based errors)\nexport const MOBILE_ADJACENT: Record<string, string[]> = {\n  // Top row - mobile keyboards often have tighter spacing\n  'q': ['w', 'a', 's'], // Less diagonal mistakes on mobile\n  'w': ['q', 'e', 's', 'a'], // More focused on immediate neighbors\n  'e': ['w', 'r', 'd', 's'], \n  'r': ['e', 't', 'f', 'd'],\n  't': ['r', 'y', 'g', 'f'],\n  'y': ['t', 'u', 'h', 'g'],\n  'u': ['y', 'i', 'j', 'h'],\n  'i': ['u', 'o', 'k', 'j'],\n  'o': ['i', 'p', 'l', 'k'],\n  'p': ['o', 'l'],\n\n  // Middle row - more fat finger mistakes due to touch\n  'a': ['q', 'w', 's', 'z'], \n  's': ['a', 'd', 'w', 'e', 'z', 'x'], // High mistake area on mobile\n  'd': ['s', 'f', 'e', 'r', 'x', 'c'],\n  'f': ['d', 'g', 'r', 't', 'c', 'v'],\n  'g': ['f', 'h', 't', 'y', 'v', 'b'],\n  'h': ['g', 'j', 'y', 'u', 'b', 'n'],\n  'j': ['h', 'k', 'u', 'i', 'n', 'm'],\n  'k': ['j', 'l', 'i', 'o', 'm'],\n  'l': ['k', 'o', 'p'],\n\n  // Bottom row - spacebar interference more common on mobile\n  'z': ['a', 's', 'x'], \n  'x': ['z', 'c', 's', 'd'],\n  'c': ['x', 'v', 'd', 'f', ' '], // Space bar mistakes more common\n  'v': ['c', 'b', 'f', 'g', ' '],\n  'b': ['v', 'n', 'g', 'h', ' '],\n  'n': ['b', 'm', 'h', 'j', ' '],\n  'm': ['n', 'j', 'k', ' '],\n\n  // Space bar - different pattern on mobile due to wider space key\n  ' ': ['c', 'v', 'b', 'n', 'm', 'x', 'z'], // Includes more bottom row keys\n  \n  // Numbers often above letters on mobile, but closer spacing\n  '1': ['2', 'q', 'w'],\n  '2': ['1', '3', 'q', 'w', 'e'],\n  '3': ['2', '4', 'w', 'e', 'r'],\n  '4': ['3', '5', 'e', 'r', 't'],\n  '5': ['4', '6', 'r', 't', 'y'],\n  '6': ['5', '7', 't', 'y', 'u'],\n  '7': ['6', '8', 'y', 'u', 'i'],\n  '8': ['7', '9', 'u', 'i', 'o'],\n  '9': ['8', '0', 'i', 'o', 'p'],\n  '0': ['9', 'o', 'p'],\n};\n\n// Legacy export for backward compatibility\nexport const QWERTY_ADJACENT = DESKTOP_ADJACENT;\n\n// Helper function to get appropriate adjacent keys based on keyboard mode\nexport function getAdjacentKeys(keyboardMode: 'mobile' | 'desktop'): Record<string, string[]> {\n  return keyboardMode === 'mobile' ? MOBILE_ADJACENT : DESKTOP_ADJACENT;\n}\n\n// Common words that are typed faster due to muscle memory\nexport const COMMON_WORDS = new Set([\n  'the', 'and', 'for', 'are', 'but', 'not', 'you', 'all', 'can', 'had', 'her', 'was', 'one',\n  'our', 'out', 'day', 'get', 'has', 'him', 'his', 'how', 'man', 'new', 'now', 'old', 'see',\n  'two', 'way', 'who', 'boy', 'did', 'its', 'let', 'put', 'say', 'she', 'too', 'use', 'that',\n  'with', 'have', 'this', 'will', 'your', 'from', 'they', 'know', 'want', 'been', 'good',\n  'much', 'some', 'time', 'very', 'when', 'come', 'here', 'just', 'like', 'long', 'make',\n  'many', 'over', 'such', 'take', 'than', 'them', 'well', 'were'\n]);\n\n// Common typos that humans make\nexport const COMMON_TYPOS: Record<string, string> = {\n  'the': 'teh',\n  'and': 'adn',\n  'for': 'fro',\n  'you': 'yuo',\n  'that': 'taht',\n  'this': 'tihs',\n  'with': 'wiht',\n  'have': 'ahve',\n  'from': 'form',\n  'they': 'thye',\n  'been': 'bene',\n  'than': 'htan',\n  'what': 'waht',\n  'your': 'yuor',\n  'when': 'wehn',\n  'there': 'tehre',\n  'their': 'thier',\n  'would': 'woudl',\n  'could': 'coudl',\n  'should': 'shoudl',\n  'through': 'trhough',\n  'because': 'becasue',\n  'before': 'beofre',\n  'after': 'aftre',\n  'where': 'whree',\n  'which': 'whihc',\n  'between': 'betwene',\n  'different': 'differnet',\n  'important': 'importnat',\n  'example': 'exmaple',\n  'without': 'withuot',\n  'another': 'antoher',\n  'development': 'developement',\n  'environment': 'enviroment',\n  'government': 'goverment',\n  'management': 'managment',\n  'information': 'infromation',\n  'available': 'availabe',\n  'business': 'buisness',\n  'complete': 'compelte',\n  'language': 'langauge',\n  'experience': 'experiance',\n  'position': 'postion',\n  'question': 'quesiton',\n  'remember': 'remeber',\n  'separate': 'seperate',\n  'something': 'somehting',\n  'together': 'togehter',\n  'understand': 'udnerstand'\n};\n\n// Special characters that typically take longer to type\nexport const SPECIAL_CHARS = new Set([\n  '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '_', '+', '=',\n  '[', ']', '{', '}', '\\\\', '|', ';', ':', \"'\", '\"', ',', '.', '<', '>',\n  '/', '?', '`', '~'\n]);\n\n// Characters requiring shift key (capital letters and symbols)\nexport const SHIFT_CHARS = new Set([\n  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',\n  'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',\n  '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '{', '}',\n  '|', ':', '\"', '<', '>', '?', '~'\n]);\n\n// Number row characters (inherently more difficult)\nexport const NUMBER_CHARS = new Set(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']);\n\n// Symbol characters with their complexity levels (1 = simple, 3 = complex)\nexport const SYMBOL_COMPLEXITY: Record<string, number> = {\n  // Simple punctuation\n  '.': 1, ',': 1, '?': 1, '!': 1, ';': 1, ':': 1, \"'\": 1, '\"': 1,\n  \n  // Medium complexity\n  '-': 2, '_': 2, '(': 2, ')': 2, '[': 2, ']': 2, '/': 2,\n  \n  // Complex symbols requiring precise finger movement\n  '@': 3, '#': 3, '$': 3, '%': 3, '^': 3, '&': 3, '*': 3,\n  '+': 3, '=': 3, '{': 3, '}': 3, '\\\\': 3, '|': 3, '`': 3, '~': 3,\n  '<': 3, '>': 3\n};\n\n// Punctuation that affects timing\nexport const SENTENCE_ENDINGS = new Set(['.', '!', '?']);\nexport const CLAUSE_SEPARATORS = new Set([',', ';', ':']);\n\n// Line break characters\nexport const LINE_BREAK_CHARS = new Set(['\\n', '\\r\\n', '\\r']);\n\n// Default configuration\nexport const DEFAULT_CONFIG: HumanLikeConfig = {\n  speed: TIMING_CONSTANTS.BASE_SPEED,\n  speedVariation: TIMING_CONSTANTS.SPEED_VARIATION,\n  mistakeFrequency: BEHAVIOR_RATES.MISTAKE_FREQUENCY,\n  mistakeTypes: {\n    adjacent: true,\n    random: false,\n    doubleChar: true,\n    commonTypos: true,\n  },\n  fatigueEffect: true,\n  concentrationLapses: true,\n  overcorrection: true,\n  debug: false,\n  sentencePause: TIMING_CONSTANTS.SENTENCE_PAUSE,\n  wordPause: TIMING_CONSTANTS.WORD_SPACE,\n  thinkingPause: TIMING_CONSTANTS.THINKING_PAUSE,\n  minCharDelay: TIMING_CONSTANTS.MIN_CHAR_DELAY,\n  backspaceSpeed: TIMING_CONSTANTS.BACKSPACE_SPEED,\n  realizationDelay: TIMING_CONSTANTS.REALIZATION_DELAY,\n  correctionPause: TIMING_CONSTANTS.CORRECTION_PAUSE,\n  // Keyboard simulation defaults\n  keyboardMode: 'mobile'\n};\n\n// Letter frequency in English (affects typing speed)\nexport const LETTER_FREQUENCY: Record<string, number> = {\n  'e': 12.7, 't': 9.1, 'a': 8.2, 'o': 7.5, 'i': 7.0, 'n': 6.7, 's': 6.3, 'h': 6.1,\n  'r': 6.0, 'd': 4.3, 'l': 4.0, 'c': 2.8, 'u': 2.8, 'm': 2.4, 'w': 2.4, 'f': 2.2,\n  'g': 2.0, 'y': 2.0, 'p': 1.9, 'b': 1.3, 'v': 1.0, 'k': 0.8, 'j': 0.15, 'x': 0.15,\n  'q': 0.10, 'z': 0.07\n};\n\n// Vowels are typically typed faster\nexport const VOWELS = new Set(['a', 'e', 'i', 'o', 'u']);\n\n// Hand mapping for alternating hand sequences (affects rhythm)\nexport const LEFT_HAND_KEYS = new Set([\n  'q', 'w', 'e', 'r', 't', 'a', 's', 'd', 'f', 'g', 'z', 'x', 'c', 'v', 'b',\n  '1', '2', '3', '4', '5', '!', '@', '#', '$', '%'\n]);\n\nexport const RIGHT_HAND_KEYS = new Set([\n  'y', 'u', 'i', 'o', 'p', 'h', 'j', 'k', 'l', ';', 'n', 'm', ',', '.', '/',\n  '6', '7', '8', '9', '0', '^', '&', '*', '(', ')', '[', ']', \"'\", '\"'\n]);","import type { KeyboardLayoutDefinition } from './types';\n\n/**\n * Standard mobile keyboard layout (iOS/Android style)\n * Represents the most common mobile keyboard behavior\n */\nexport const MOBILE_LAYOUT: KeyboardLayoutDefinition = {\n  views: {\n    letters: [\n      'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p',\n      'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l',\n      'z', 'x', 'c', 'v', 'b', 'n', 'm'\n    ],\n    numbers: [\n      '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',\n      '-', '/', ':', ';', '(', ')', '$', '&', '@', '\"',\n      '.', ',', '?', '!', \"'\", '[', ']', '{', '}', '#',\n      '%', '^', '*', '+', '=', '_', '\\\\', '|', '~', '<',\n      '>', '€', '£', '¥', '•', '...'\n    ],\n    symbols: [\n      '[', ']', '{', '}', '#', '%', '^', '*', '+', '=',\n      '_', '\\\\', '|', '~', '<', '>', '€', '£', '¥', '•',\n      '.', ',', '?', '!', \"'\", '\"', '/', ':', ';', '(',\n      ')', '$', '&', '@', '`', '§', '¿', '¡', '«', '»',\n      '°', '†', '‡', '…', '‰', '′', '″', '‹', '›'\n    ],\n    emoji: [\n      '😀', '😃', '😄', '😁', '😆', '😅', '🤣', '😂', '🙂', '🙃',\n      '😉', '😊', '😇', '🥰', '😍', '🤩', '😘', '😗', '☺', '😚',\n      '😙', '🥲', '😋', '😛', '😜', '🤪', '😝', '🤑', '🤗', '🤭'\n    ]\n  },\n  \n  viewSwitchers: {\n    toNumbers: '123',\n    toSymbols: '#+=', \n    toLetters: 'ABC',\n    toEmoji: '😀'\n  },\n  \n  modifiers: {\n    shift: '⇧',\n    caps: 'CAPS',\n    space: 'space',\n    enter: 'return',\n    backspace: '⌫'\n  },\n  \n  keyDurations: {\n    letter: 80,       // Fast letter typing\n    number: 90,       // Slightly slower for numbers\n    symbol: 100,      // Slower for symbols\n    modifier: 120,    // Shift/caps key press\n    viewSwitch: 110,  // View switching (123, ABC, etc.)\n    space: 75,        // Space bar\n    enter: 90,        // Return key\n    backspace: 110    // Backspace key\n  }\n};\n\n/**\n * iOS-specific layout variations\n */\nexport const IOS_LAYOUT: KeyboardLayoutDefinition = {\n  ...MOBILE_LAYOUT,\n  \n  viewSwitchers: {\n    toNumbers: '.?123',\n    toSymbols: '#+=',\n    toLetters: 'ABC',\n    toEmoji: '🙂'\n  },\n  \n  modifiers: {\n    shift: '⇧',\n    caps: 'caps lock',\n    space: 'space',\n    enter: 'return',\n    backspace: '⌫'\n  }\n};\n\n/**\n * Android-specific layout variations\n */\nexport const ANDROID_LAYOUT: KeyboardLayoutDefinition = {\n  ...MOBILE_LAYOUT,\n  \n  viewSwitchers: {\n    toNumbers: '?123',\n    toSymbols: '=\\\\<',\n    toLetters: 'ABC',\n    toEmoji: '😀'\n  },\n  \n  modifiers: {\n    shift: '⇧',\n    caps: 'CAPS',\n    space: 'space',\n    enter: 'return',\n    backspace: '⌫'\n  }\n};\n\n/**\n * Map character to the view it belongs to\n */\nexport const MOBILE_CHARACTER_TO_VIEW: Record<string, 'letters' | 'numbers' | 'symbols'> = {\n  // Letters (lowercase and uppercase)\n  ...Object.fromEntries('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('').map(c => [c, 'letters' as const])),\n  \n  // Numbers and basic symbols on number view\n  '1': 'numbers', '2': 'numbers', '3': 'numbers', '4': 'numbers', '5': 'numbers',\n  '6': 'numbers', '7': 'numbers', '8': 'numbers', '9': 'numbers', '0': 'numbers',\n  '-': 'numbers', '/': 'numbers', ':': 'numbers', ';': 'numbers', '(': 'numbers',\n  ')': 'numbers', '$': 'numbers', '&': 'numbers', '@': 'numbers', '\"': 'numbers',\n  '.': 'numbers', ',': 'numbers', '?': 'numbers', '!': 'numbers', \"'\": 'numbers',\n  \n  // Complex symbols on symbol view\n  '[': 'symbols', ']': 'symbols', '{': 'symbols', '}': 'symbols', '#': 'symbols',\n  '%': 'symbols', '^': 'symbols', '*': 'symbols', '+': 'symbols', '=': 'symbols',\n  '_': 'symbols', '\\\\': 'symbols', '|': 'symbols', '~': 'symbols', '<': 'symbols',\n  '>': 'symbols', '€': 'symbols', '£': 'symbols', '¥': 'symbols', '•': 'symbols',\n  '`': 'symbols', '§': 'symbols', '¿': 'symbols', '¡': 'symbols', '«': 'symbols',\n  '»': 'symbols', '°': 'symbols', '†': 'symbols', '‡': 'symbols', '…': 'symbols',\n  '‰': 'symbols', '′': 'symbols', '″': 'symbols', '‹': 'symbols', '›': 'symbols'\n};\n\n/**\n * Special mobile keyboard shortcuts and gestures\n */\nexport const MOBILE_SHORTCUTS = {\n  // Double space = period + space (common mobile behavior)\n  DOUBLE_SPACE_PERIOD: true,\n  \n  // Long press behaviors\n  LONG_PRESS_ACCENTS: {\n    'a': ['à', 'á', 'â', 'ä', 'æ', 'ã', 'å', 'ā'],\n    'e': ['è', 'é', 'ê', 'ë', 'ē', 'ė', 'ę'],\n    'i': ['î', 'ï', 'í', 'ī', 'į', 'ì'],\n    'o': ['ô', 'ö', 'ò', 'ó', 'œ', 'ø', 'ō', 'õ'],\n    'u': ['û', 'ü', 'ù', 'ú', 'ū'],\n    'c': ['ç', 'ć', 'č'],\n    'n': ['ñ', 'ń'],\n    's': ['ś', 'š'],\n    'z': ['ž', 'ź', 'ż']\n  },\n  \n  // Auto-correction common patterns\n  AUTO_CAPITALIZE_AFTER: ['.', '!', '?', '\\n'],\n  AUTO_SPACE_AFTER: ['.', ',', '!', '?', ':', ';']\n};","import type { KeyboardLayoutDefinition } from './types';\n\n/**\n * Standard US QWERTY desktop keyboard layout\n */\nexport const DESKTOP_QWERTY_LAYOUT: KeyboardLayoutDefinition = {\n  views: {\n    letters: [\n      'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p',\n      'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l',\n      'z', 'x', 'c', 'v', 'b', 'n', 'm'\n    ],\n    numbers: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'],\n    symbols: [\n      '`', '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '_', '+', '=',\n      '[', ']', '{', '}', '\\\\', '|', ';', ':', \"'\", '\"', ',', '.', '<', '>', '/', '?'\n    ]\n  },\n  \n  viewSwitchers: {\n    toNumbers: 'numbers',  // No view switching on desktop\n    toSymbols: 'symbols',  // Symbols accessed via shift\n    toLetters: 'letters'\n  },\n  \n  modifiers: {\n    shift: 'shift',\n    caps: 'caps lock',\n    space: 'space',\n    enter: 'enter',\n    backspace: 'backspace'\n  },\n  \n  keyDurations: {\n    letter: 70,       // Fast letter typing on desktop\n    number: 85,       // Numbers require reaching up\n    symbol: 95,       // Symbols often need shift\n    modifier: 90,     // Modifier key press\n    viewSwitch: 0,    // No view switching on desktop\n    space: 60,        // Space bar\n    enter: 80,        // Enter key\n    backspace: 100    // Backspace key\n  }\n};\n\n/**\n * Desktop key mappings - what physical key produces each character\n * Format: [key, requiresShift]\n */\nexport const DESKTOP_KEY_MAPPING: Record<string, [string, boolean]> = {\n  // Letters (lowercase)\n  'a': ['a', false], 'b': ['b', false], 'c': ['c', false], 'd': ['d', false], 'e': ['e', false],\n  'f': ['f', false], 'g': ['g', false], 'h': ['h', false], 'i': ['i', false], 'j': ['j', false],\n  'k': ['k', false], 'l': ['l', false], 'm': ['m', false], 'n': ['n', false], 'o': ['o', false],\n  'p': ['p', false], 'q': ['q', false], 'r': ['r', false], 's': ['s', false], 't': ['t', false],\n  'u': ['u', false], 'v': ['v', false], 'w': ['w', false], 'x': ['x', false], 'y': ['y', false],\n  'z': ['z', false],\n  \n  // Letters (uppercase) - same key + shift\n  'A': ['a', true], 'B': ['b', true], 'C': ['c', true], 'D': ['d', true], 'E': ['e', true],\n  'F': ['f', true], 'G': ['g', true], 'H': ['h', true], 'I': ['i', true], 'J': ['j', true],\n  'K': ['k', true], 'L': ['l', true], 'M': ['m', true], 'N': ['n', true], 'O': ['o', true],\n  'P': ['p', true], 'Q': ['q', true], 'R': ['r', true], 'S': ['s', true], 'T': ['t', true],\n  'U': ['u', true], 'V': ['v', true], 'W': ['w', true], 'X': ['x', true], 'Y': ['y', true],\n  'Z': ['z', true],\n  \n  // Numbers (no shift)\n  '1': ['1', false], '2': ['2', false], '3': ['3', false], '4': ['4', false], '5': ['5', false],\n  '6': ['6', false], '7': ['7', false], '8': ['8', false], '9': ['9', false], '0': ['0', false],\n  \n  // Numbers with shift (top row symbols)\n  '!': ['1', true], '@': ['2', true], '#': ['3', true], '$': ['4', true], '%': ['5', true],\n  '^': ['6', true], '&': ['7', true], '*': ['8', true], '(': ['9', true], ')': ['0', true],\n  \n  // Other keys without shift\n  '`': ['`', false], '-': ['-', false], '=': ['=', false], '[': ['[', false], ']': [']', false],\n  '\\\\': ['\\\\', false], ';': [';', false], \"'\": [\"'\", false], ',': [',', false], '.': ['.', false],\n  '/': ['/', false], ' ': ['space', false], '\\n': ['enter', false], '\\t': ['tab', false],\n  \n  // Other keys with shift\n  '~': ['`', true], '_': ['-', true], '+': ['=', true], '{': ['[', true], '}': [']', true],\n  '|': ['\\\\', true], ':': [';', true], '\"': [\"'\", true], '<': [',', true], '>': ['.', true],\n  '?': ['/', true]\n};\n\n/**\n * Desktop keyboard physical layout for visual representation\n */\nexport const DESKTOP_PHYSICAL_LAYOUT = {\n  rows: [\n    // Number row\n    {\n      keys: [\n        { key: '`', shift: '~' },\n        { key: '1', shift: '!' },\n        { key: '2', shift: '@' },\n        { key: '3', shift: '#' },\n        { key: '4', shift: '$' },\n        { key: '5', shift: '%' },\n        { key: '6', shift: '^' },\n        { key: '7', shift: '&' },\n        { key: '8', shift: '*' },\n        { key: '9', shift: '(' },\n        { key: '0', shift: ')' },\n        { key: '-', shift: '_' },\n        { key: '=', shift: '+' }\n      ]\n    },\n    \n    // QWERTY row\n    {\n      keys: [\n        { key: 'q' }, { key: 'w' }, { key: 'e' }, { key: 'r' }, { key: 't' },\n        { key: 'y' }, { key: 'u' }, { key: 'i' }, { key: 'o' }, { key: 'p' },\n        { key: '[', shift: '{' },\n        { key: ']', shift: '}' },\n        { key: '\\\\', shift: '|' }\n      ]\n    },\n    \n    // ASDF row (home row)\n    {\n      keys: [\n        { key: 'a' }, { key: 's' }, { key: 'd' }, { key: 'f' }, { key: 'g' },\n        { key: 'h' }, { key: 'j' }, { key: 'k' }, { key: 'l' },\n        { key: ';', shift: ':' },\n        { key: \"'\", shift: '\"' }\n      ]\n    },\n    \n    // ZXCV row\n    {\n      keys: [\n        { key: 'z' }, { key: 'x' }, { key: 'c' }, { key: 'v' }, { key: 'b' },\n        { key: 'n' }, { key: 'm' },\n        { key: ',', shift: '<' },\n        { key: '.', shift: '>' },\n        { key: '/', shift: '?' }\n      ]\n    },\n    \n    // Space row\n    {\n      keys: [\n        { key: 'space', width: 'wide' }\n      ]\n    }\n  ],\n  \n  modifiers: {\n    left: ['shift', 'ctrl', 'alt', 'cmd'],\n    right: ['shift', 'ctrl', 'alt', 'cmd']\n  }\n};\n\n/**\n * Common desktop keyboard shortcuts and behaviors\n */\nexport const DESKTOP_SHORTCUTS = {\n  // Copy/paste/cut\n  COPY: ['cmd+c', 'ctrl+c'],\n  PASTE: ['cmd+v', 'ctrl+v'],\n  CUT: ['cmd+x', 'ctrl+x'],\n  \n  // Selection\n  SELECT_ALL: ['cmd+a', 'ctrl+a'],\n  SELECT_WORD: ['shift+alt+arrow', 'shift+ctrl+arrow'],\n  \n  // Navigation\n  HOME: ['cmd+left', 'home'],\n  END: ['cmd+right', 'end'],\n  WORD_LEFT: ['alt+left', 'ctrl+left'],\n  WORD_RIGHT: ['alt+right', 'ctrl+right'],\n  \n  // Deletion\n  DELETE_WORD_LEFT: ['alt+backspace', 'ctrl+backspace'],\n  DELETE_WORD_RIGHT: ['alt+delete', 'ctrl+delete'],\n  DELETE_LINE: ['cmd+backspace', 'ctrl+u'],\n  \n  // Auto-behaviors\n  AUTO_CAPITALIZE_SENTENCES: true,\n  SMART_QUOTES: false, // Usually disabled for coding\n  AUTO_CORRECTION: false // Usually disabled for coding\n};","import type { KeyboardLayoutDefinition } from './types';\n\n/**\n * Platform-specific timing profiles for more realistic keyboard simulation\n */\n\nexport interface TimingProfile {\n  name: string;\n  description: string;\n  baseMultiplier: number;\n  keyDurations: {\n    letter: number;\n    number: number;\n    symbol: number;\n    modifier: number;\n    viewSwitch: number;\n    space: number;\n    enter: number;\n    backspace: number;\n  };\n  // Additional behavioral modifiers\n  viewSwitchDelay: number;    // Extra delay for view switching\n  consecutiveKeyBonus: number; // Speed bonus for typing same-hand sequences\n  complexSymbolPenalty: number; // Extra delay for complex symbols\n  capsLockTransitionDelay: number; // Extra delay for caps lock on/off\n}\n\n/**\n * Mobile device timing profiles\n */\nexport const MOBILE_TIMING_PROFILES: Record<string, TimingProfile> = {\n  // Standard smartphone typing\n  MOBILE_CASUAL: {\n    name: 'Mobile Casual',\n    description: 'Average smartphone user, thumb typing',\n    baseMultiplier: 1.0,\n    keyDurations: {\n      letter: 120,\n      number: 140,\n      symbol: 160,\n      modifier: 180,\n      viewSwitch: 150,\n      space: 100,\n      enter: 130,\n      backspace: 150\n    },\n    viewSwitchDelay: 50,\n    consecutiveKeyBonus: 0.9,\n    complexSymbolPenalty: 40,\n    capsLockTransitionDelay: 60\n  },\n\n  // Fast mobile typist\n  MOBILE_FAST: {\n    name: 'Mobile Fast',\n    description: 'Experienced mobile user, swipe/predictive text habits',\n    baseMultiplier: 0.7,\n    keyDurations: {\n      letter: 80,\n      number: 95,\n      symbol: 110,\n      modifier: 120,\n      viewSwitch: 100,\n      space: 70,\n      enter: 90,\n      backspace: 110\n    },\n    viewSwitchDelay: 30,\n    consecutiveKeyBonus: 0.85,\n    complexSymbolPenalty: 25,\n    capsLockTransitionDelay: 40\n  },\n\n  // Slow/careful mobile typing\n  MOBILE_CAREFUL: {\n    name: 'Mobile Careful',\n    description: 'Deliberate mobile typing, hunt-and-peck style',\n    baseMultiplier: 1.5,\n    keyDurations: {\n      letter: 180,\n      number: 220,\n      symbol: 280,\n      modifier: 250,\n      viewSwitch: 200,\n      space: 150,\n      enter: 180,\n      backspace: 220\n    },\n    viewSwitchDelay: 80,\n    consecutiveKeyBonus: 0.95,\n    complexSymbolPenalty: 60,\n    capsLockTransitionDelay: 100\n  },\n\n  // Tablet typing (larger screen, different hand position)\n  TABLET: {\n    name: 'Tablet',\n    description: 'Tablet device, often landscape mode with more fingers',\n    baseMultiplier: 0.8,\n    keyDurations: {\n      letter: 90,\n      number: 110,\n      symbol: 130,\n      modifier: 140,\n      viewSwitch: 120,\n      space: 80,\n      enter: 100,\n      backspace: 130\n    },\n    viewSwitchDelay: 40,\n    consecutiveKeyBonus: 0.8, // More fingers = better hand alternation\n    complexSymbolPenalty: 30,\n    capsLockTransitionDelay: 50\n  }\n};\n\n/**\n * Desktop timing profiles\n */\nexport const DESKTOP_TIMING_PROFILES: Record<string, TimingProfile> = {\n  // Standard desktop typing\n  DESKTOP_AVERAGE: {\n    name: 'Desktop Average',\n    description: 'Average desktop user, ~40 WPM',\n    baseMultiplier: 1.0,\n    keyDurations: {\n      letter: 80,\n      number: 100,\n      symbol: 120,\n      modifier: 90,\n      viewSwitch: 0, // No view switching on desktop\n      space: 70,\n      enter: 90,\n      backspace: 100\n    },\n    viewSwitchDelay: 0,\n    consecutiveKeyBonus: 0.85, // Good hand alternation on QWERTY\n    complexSymbolPenalty: 30,\n    capsLockTransitionDelay: 50\n  },\n\n  // Fast desktop typist\n  DESKTOP_FAST: {\n    name: 'Desktop Fast',\n    description: 'Experienced typist, ~70+ WPM, touch typing',\n    baseMultiplier: 0.6,\n    keyDurations: {\n      letter: 50,\n      number: 65,\n      symbol: 80,\n      modifier: 60,\n      viewSwitch: 0,\n      space: 45,\n      enter: 60,\n      backspace: 70\n    },\n    viewSwitchDelay: 0,\n    consecutiveKeyBonus: 0.8,\n    complexSymbolPenalty: 15,\n    capsLockTransitionDelay: 25\n  },\n\n  // Programming-focused typing\n  DESKTOP_PROGRAMMER: {\n    name: 'Desktop Programmer',\n    description: 'Developer typing, frequent symbols and modifiers',\n    baseMultiplier: 0.7,\n    keyDurations: {\n      letter: 60,\n      number: 70,\n      symbol: 75, // Programmers are fast with symbols\n      modifier: 65,\n      viewSwitch: 0,\n      space: 50,\n      enter: 70,\n      backspace: 80\n    },\n    viewSwitchDelay: 0,\n    consecutiveKeyBonus: 0.8,\n    complexSymbolPenalty: 10, // Less penalty for complex symbols\n    capsLockTransitionDelay: 30\n  },\n\n  // Hunt-and-peck desktop typing\n  DESKTOP_SLOW: {\n    name: 'Desktop Slow',\n    description: 'Hunt-and-peck typing, looking at keyboard',\n    baseMultiplier: 2.0,\n    keyDurations: {\n      letter: 160,\n      number: 200,\n      symbol: 250,\n      modifier: 180,\n      viewSwitch: 0,\n      space: 140,\n      enter: 160,\n      backspace: 180\n    },\n    viewSwitchDelay: 0,\n    consecutiveKeyBonus: 0.95, // Less benefit from hand alternation\n    complexSymbolPenalty: 80,\n    capsLockTransitionDelay: 120\n  },\n\n  // Gaming keyboard (mechanical, fast response)\n  DESKTOP_GAMING: {\n    name: 'Desktop Gaming',\n    description: 'Mechanical keyboard, gaming-optimized typing',\n    baseMultiplier: 0.5,\n    keyDurations: {\n      letter: 40,\n      number: 50,\n      symbol: 60,\n      modifier: 45,\n      viewSwitch: 0,\n      space: 35,\n      enter: 50,\n      backspace: 60\n    },\n    viewSwitchDelay: 0,\n    consecutiveKeyBonus: 0.75,\n    complexSymbolPenalty: 10,\n    capsLockTransitionDelay: 20\n  }\n};\n\n/**\n * Auto-detect appropriate timing profile based on config\n */\nexport function getDefaultTimingProfile(keyboardMode: 'mobile' | 'desktop', userHint?: string): TimingProfile {\n  if (keyboardMode === 'mobile') {\n    if (userHint === 'fast') return MOBILE_TIMING_PROFILES.MOBILE_FAST;\n    if (userHint === 'slow' || userHint === 'careful') return MOBILE_TIMING_PROFILES.MOBILE_CAREFUL;\n    if (userHint === 'tablet') return MOBILE_TIMING_PROFILES.TABLET;\n    return MOBILE_TIMING_PROFILES.MOBILE_CASUAL; // Default\n  } else {\n    if (userHint === 'fast') return DESKTOP_TIMING_PROFILES.DESKTOP_FAST;\n    if (userHint === 'slow') return DESKTOP_TIMING_PROFILES.DESKTOP_SLOW;\n    if (userHint === 'programmer' || userHint === 'developer') return DESKTOP_TIMING_PROFILES.DESKTOP_PROGRAMMER;\n    if (userHint === 'gaming') return DESKTOP_TIMING_PROFILES.DESKTOP_GAMING;\n    return DESKTOP_TIMING_PROFILES.DESKTOP_AVERAGE; // Default\n  }\n}\n\n/**\n * Apply timing profile to keyboard layout\n */\nexport function applyTimingProfile(layout: KeyboardLayoutDefinition, profile: TimingProfile): KeyboardLayoutDefinition {\n  return {\n    ...layout,\n    keyDurations: {\n      ...profile.keyDurations\n    }\n  };\n}\n\n/**\n * Calculate dynamic timing adjustments based on context\n */\nexport function calculateContextualTiming(\n  baseDelay: number, \n  profile: TimingProfile, \n  context: {\n    isConsecutiveSameHand?: boolean;\n    isComplexSymbol?: boolean;\n    isViewSwitch?: boolean;\n    isCapsLockTransition?: boolean;\n  }\n): number {\n  let adjustedDelay = baseDelay * profile.baseMultiplier;\n\n  // Apply profile-specific adjustments\n  if (context.isConsecutiveSameHand) {\n    adjustedDelay *= profile.consecutiveKeyBonus;\n  }\n\n  if (context.isComplexSymbol) {\n    adjustedDelay += profile.complexSymbolPenalty;\n  }\n\n  if (context.isViewSwitch) {\n    adjustedDelay += profile.viewSwitchDelay;\n  }\n\n  if (context.isCapsLockTransition) {\n    adjustedDelay += profile.capsLockTransitionDelay;\n  }\n\n  return adjustedDelay;\n}","import type { \n  KeyInfo, \n  KeySequence, \n  KeyboardState, \n  KeyboardView,\n  KeyboardAnalyzerConfig,\n  KeyboardLayoutDefinition \n} from './types';\nimport { MOBILE_LAYOUT, MOBILE_CHARACTER_TO_VIEW } from './mobile-layouts';\nimport { DESKTOP_QWERTY_LAYOUT, DESKTOP_KEY_MAPPING } from './desktop-layouts';\nimport { getDefaultTimingProfile, applyTimingProfile, calculateContextualTiming, type TimingProfile } from './timing-profiles';\n\n/**\n * Analyzes characters and converts them to realistic keyboard key sequences\n * Handles both mobile and desktop keyboard behaviors\n */\nexport class KeyboardAnalyzer {\n  private config: KeyboardAnalyzerConfig;\n  private layout: KeyboardLayoutDefinition;\n  private state: KeyboardState;\n  private timingProfile: TimingProfile;\n\n  constructor(config: Partial<KeyboardAnalyzerConfig> = {}) {\n    this.config = {\n      keyboardMode: 'mobile',\n      capsLockThreshold: 3,\n      useNaturalTiming: true,\n      debug: false,\n      ...config\n    };\n\n    // Select appropriate timing profile\n    this.timingProfile = getDefaultTimingProfile(this.config.keyboardMode, this.config.typingSpeed);\n    \n    // Select appropriate layout and apply timing profile\n    const baseLayout = config.customLayout || \n      (this.config.keyboardMode === 'mobile' ? MOBILE_LAYOUT : DESKTOP_QWERTY_LAYOUT);\n    \n    this.layout = applyTimingProfile(baseLayout, this.timingProfile);\n\n    // Initialize keyboard state\n    this.state = {\n      currentView: 'letters',\n      capsLockActive: false,\n      shiftActive: false,\n      recentCharacters: [],\n      mode: this.config.keyboardMode\n    };\n\n    this.debug('KeyboardAnalyzer initialized', { \n      config: this.config, \n      timingProfile: this.timingProfile.name,\n      layout: this.layout.viewSwitchers \n    });\n  }\n\n  /**\n   * Analyzes a character and returns the key sequence needed to type it\n   */\n  public analyzeCharacter(character: string, charIndex: number, fullText: string): KeySequence {\n    this.debug(`Analyzing character: \"${character}\" at index ${charIndex}`);\n    \n    // Update recent characters for caps lock detection\n    this.updateRecentCharacters(character);\n    \n    // Determine if this is part of a caps lock sequence\n    const capsLockInfo = this.analyzeCapsLockSequence(character, charIndex, fullText);\n    \n    let keys: KeyInfo[] = [];\n    \n    if (this.config.keyboardMode === 'mobile') {\n      keys = this.analyzeMobileCharacter(character, capsLockInfo);\n    } else {\n      keys = this.analyzeDesktopCharacter(character, capsLockInfo);\n    }\n    \n    // Calculate total duration\n    const totalDuration = keys.reduce((sum, key) => sum + key.duration, 0);\n    \n    const sequence: KeySequence = {\n      character,\n      keys,\n      totalDuration,\n      usesCapsLock: capsLockInfo.isCapsLockSequence\n    };\n    \n    this.debug(`Generated sequence for \"${character}\":`, sequence);\n    return sequence;\n  }\n\n  /**\n   * Analyzes mobile keyboard character input\n   */\n  private analyzeMobileCharacter(character: string, capsInfo: any): KeyInfo[] {\n    const keys: KeyInfo[] = [];\n    let sequenceIndex = 0;\n    \n    // Handle special characters\n    if (character === ' ') {\n      return [{\n        key: this.layout.modifiers.space,\n        character,\n        type: 'space',\n        keyboardView: this.state.currentView,\n        isCapsLock: false,\n        duration: this.layout.keyDurations.space,\n        sequenceIndex: 0,\n        sequenceLength: 1\n      }];\n    }\n    \n    if (character === '\\n') {\n      return [{\n        key: this.layout.modifiers.enter,\n        character,\n        type: 'enter',\n        keyboardView: this.state.currentView,\n        isCapsLock: false,\n        duration: this.layout.keyDurations.enter,\n        sequenceIndex: 0,\n        sequenceLength: 1\n      }];\n    }\n    \n    // Determine target view for this character\n    const targetView = this.getCharacterView(character);\n    \n    // Add view switching keys if needed\n    if (this.state.currentView !== targetView) {\n      const viewSwitchKeys = this.getViewSwitchSequence(this.state.currentView, targetView);\n      viewSwitchKeys.forEach(viewKey => {\n        keys.push({\n          ...viewKey,\n          sequenceIndex: sequenceIndex++,\n          sequenceLength: 0 // Will be updated after we know total length\n        });\n      });\n      this.state.currentView = targetView;\n    }\n    \n    // Handle caps lock for letters\n    if (character.match(/[A-Z]/)) {\n      if (capsInfo.isCapsLockSequence) {\n        // CAPS LOCK mode - only add caps key for first and last\n        if (capsInfo.isFirst) {\n          keys.push(this.createCapsKey(true, sequenceIndex++));\n          this.state.capsLockActive = true;\n        } else if (capsInfo.isLast) {\n          // Add the letter first, then caps off\n          keys.push(this.createLetterKey(character.toLowerCase(), sequenceIndex++, capsInfo.isCapsLockSequence));\n          keys.push(this.createCapsKey(false, sequenceIndex++));\n          this.state.capsLockActive = false;\n          \n          // Update sequence lengths and return early\n          keys.forEach(key => key.sequenceLength = keys.length);\n          return keys;\n        }\n        // Middle of caps lock sequence - just add the letter (no caps key)\n      } else {\n        // Single capital - use shift\n        keys.push(this.createShiftKey(sequenceIndex++));\n      }\n    }\n    \n    // Add the main character key\n    const mainKey = this.createCharacterKey(character, sequenceIndex++, capsInfo.isCapsLockSequence);\n    keys.push(mainKey);\n    \n    // Update sequence lengths\n    keys.forEach(key => key.sequenceLength = keys.length);\n    \n    return keys;\n  }\n\n  /**\n   * Analyzes desktop keyboard character input\n   */\n  private analyzeDesktopCharacter(character: string, capsInfo: any): KeyInfo[] {\n    const keys: KeyInfo[] = [];\n    let sequenceIndex = 0;\n    \n    // Handle special characters\n    if (character === ' ') {\n      return [{\n        key: 'space',\n        character,\n        type: 'space',\n        keyboardView: 'letters',\n        isCapsLock: false,\n        duration: this.layout.keyDurations.space,\n        sequenceIndex: 0,\n        sequenceLength: 1\n      }];\n    }\n    \n    if (character === '\\n') {\n      return [{\n        key: 'enter',\n        character,\n        type: 'enter',\n        keyboardView: 'letters',\n        isCapsLock: false,\n        duration: this.layout.keyDurations.enter,\n        sequenceIndex: 0,\n        sequenceLength: 1\n      }];\n    }\n    \n    // Get desktop key mapping\n    const mapping = DESKTOP_KEY_MAPPING[character];\n    if (!mapping) {\n      this.debug(`No desktop mapping found for character: \"${character}\"`);\n      // Fallback to basic letter key\n      return [{\n        key: character.toLowerCase(),\n        character,\n        type: 'letter',\n        keyboardView: 'letters',\n        isCapsLock: false,\n        duration: this.layout.keyDurations.letter,\n        sequenceIndex: 0,\n        sequenceLength: 1\n      }];\n    }\n    \n    const [physicalKey, requiresShift] = mapping;\n    \n    // Handle caps lock for letters\n    if (character.match(/[A-Z]/)) {\n      if (capsInfo.isCapsLockSequence) {\n        // CAPS LOCK mode\n        if (capsInfo.isFirst) {\n          keys.push({\n            key: 'caps lock',\n            character,\n            type: 'modifier',\n            keyboardView: 'letters',\n            isCapsLock: true,\n            duration: this.layout.keyDurations.modifier,\n            sequenceIndex: sequenceIndex++,\n            sequenceLength: 0\n          });\n        } else if (capsInfo.isLast) {\n          // Add letter first, then turn off caps lock\n          keys.push({\n            key: physicalKey,\n            character,\n            type: 'letter',\n            keyboardView: 'letters',\n            isCapsLock: true,\n            duration: this.layout.keyDurations.letter,\n            sequenceIndex: sequenceIndex++,\n            sequenceLength: 0\n          });\n          keys.push({\n            key: 'caps lock',\n            character,\n            type: 'modifier',\n            keyboardView: 'letters',\n            isCapsLock: true,\n            duration: this.layout.keyDurations.modifier,\n            sequenceIndex: sequenceIndex++,\n            sequenceLength: 0\n          });\n          \n          // Update sequence lengths and return\n          keys.forEach(key => key.sequenceLength = keys.length);\n          return keys;\n        }\n        // Middle of caps lock - just the letter\n      } else if (requiresShift) {\n        // Single capital with shift\n        keys.push({\n          key: 'shift',\n          character,\n          type: 'modifier',\n          keyboardView: 'letters',\n          isCapsLock: false,\n          duration: this.layout.keyDurations.modifier,\n          sequenceIndex: sequenceIndex++,\n          sequenceLength: 0\n        });\n      }\n    } else if (requiresShift) {\n      // Non-letter that requires shift (symbols)\n      keys.push({\n        key: 'shift',\n        character,\n        type: 'modifier',\n        keyboardView: 'symbols',\n        isCapsLock: false,\n        duration: this.layout.keyDurations.modifier,\n        sequenceIndex: sequenceIndex++,\n        sequenceLength: 0\n      });\n    }\n    \n    // Add the main key\n    const keyType = character.match(/[a-zA-Z]/) ? 'letter' : \n                   character.match(/[0-9]/) ? 'number' : 'symbol';\n    \n    keys.push({\n      key: physicalKey,\n      character,\n      type: keyType,\n      keyboardView: keyType === 'letter' ? 'letters' : keyType === 'number' ? 'numbers' : 'symbols',\n      isCapsLock: capsInfo.isCapsLockSequence,\n      duration: this.layout.keyDurations[keyType],\n      sequenceIndex: sequenceIndex++,\n      sequenceLength: 0\n    });\n    \n    // Update sequence lengths\n    keys.forEach(key => key.sequenceLength = keys.length);\n    \n    return keys;\n  }\n\n  /**\n   * Determines which keyboard view a character belongs to (mobile)\n   */\n  private getCharacterView(character: string): KeyboardView {\n    if (this.config.keyboardMode === 'desktop') {\n      return 'letters'; // Desktop doesn't have view switching\n    }\n    \n    return MOBILE_CHARACTER_TO_VIEW[character] || 'letters';\n  }\n\n  /**\n   * Gets the sequence of view switch keys needed\n   */\n  private getViewSwitchSequence(from: KeyboardView, to: KeyboardView): KeyInfo[] {\n    if (from === to) return [];\n    \n    const keys: KeyInfo[] = [];\n    \n    // Mobile view switching logic\n    switch (to) {\n      case 'numbers':\n        keys.push({\n          key: this.layout.viewSwitchers.toNumbers,\n          character: '',\n          type: 'view-switch',\n          keyboardView: from,\n          isCapsLock: false,\n          duration: this.layout.keyDurations.viewSwitch,\n          sequenceIndex: 0,\n          sequenceLength: 0\n        });\n        break;\n        \n      case 'symbols':\n        // Might need to go through numbers first\n        if (from === 'letters') {\n          keys.push({\n            key: this.layout.viewSwitchers.toNumbers,\n            character: '',\n            type: 'view-switch',\n            keyboardView: from,\n            isCapsLock: false,\n            duration: this.layout.keyDurations.viewSwitch,\n            sequenceIndex: 0,\n            sequenceLength: 0\n          });\n        }\n        keys.push({\n          key: this.layout.viewSwitchers.toSymbols,\n          character: '',\n          type: 'view-switch',\n          keyboardView: 'numbers',\n          isCapsLock: false,\n          duration: this.layout.keyDurations.viewSwitch,\n          sequenceIndex: 0,\n          sequenceLength: 0\n        });\n        break;\n        \n      case 'letters':\n        keys.push({\n          key: this.layout.viewSwitchers.toLetters,\n          character: '',\n          type: 'view-switch',\n          keyboardView: from,\n          isCapsLock: false,\n          duration: this.layout.keyDurations.viewSwitch,\n          sequenceIndex: 0,\n          sequenceLength: 0\n        });\n        break;\n    }\n    \n    return keys;\n  }\n\n  /**\n   * Creates a caps lock key press\n   */\n  private createCapsKey(turningOn: boolean, sequenceIndex: number): KeyInfo {\n    const baseDuration = this.layout.keyDurations.modifier;\n    const contextualDuration = calculateContextualTiming(baseDuration, this.timingProfile, {\n      isCapsLockTransition: true\n    });\n    \n    return {\n      key: this.layout.modifiers.caps,\n      character: '',\n      type: 'modifier',\n      keyboardView: this.state.currentView,\n      isCapsLock: true,\n      duration: turningOn ? contextualDuration + 20 : contextualDuration, // Slightly longer for turning on\n      sequenceIndex,\n      sequenceLength: 0\n    };\n  }\n\n  /**\n   * Creates a shift key press\n   */\n  private createShiftKey(sequenceIndex: number): KeyInfo {\n    return {\n      key: this.layout.modifiers.shift,\n      character: '',\n      type: 'modifier',\n      keyboardView: this.state.currentView,\n      isCapsLock: false,\n      duration: this.layout.keyDurations.modifier,\n      sequenceIndex,\n      sequenceLength: 0\n    };\n  }\n\n  /**\n   * Creates a letter key press\n   */\n  private createLetterKey(letter: string, sequenceIndex: number, isCapsLock: boolean): KeyInfo {\n    return {\n      key: letter,\n      character: letter,\n      type: 'letter',\n      keyboardView: 'letters',\n      isCapsLock,\n      duration: this.layout.keyDurations.letter,\n      sequenceIndex,\n      sequenceLength: 0\n    };\n  }\n\n  /**\n   * Creates a character key press\n   */\n  private createCharacterKey(character: string, sequenceIndex: number, isCapsLock: boolean): KeyInfo {\n    const key = character.toLowerCase();\n    const type = character.match(/[a-zA-Z]/) ? 'letter' : \n                character.match(/[0-9]/) ? 'number' : 'symbol';\n    \n    // Apply contextual timing based on character complexity\n    const baseDuration = this.layout.keyDurations[type];\n    const isComplexSymbol = type === 'symbol' && this.isComplexSymbol(character);\n    const contextualDuration = calculateContextualTiming(baseDuration, this.timingProfile, {\n      isComplexSymbol\n    });\n    \n    return {\n      key,\n      character,\n      type,\n      keyboardView: this.state.currentView,\n      isCapsLock,\n      duration: contextualDuration,\n      sequenceIndex,\n      sequenceLength: 0\n    };\n  }\n\n  /**\n   * Updates recent characters for caps lock detection\n   */\n  private updateRecentCharacters(character: string) {\n    this.state.recentCharacters.push(character);\n    // Keep only last 10 characters for analysis\n    if (this.state.recentCharacters.length > 10) {\n      this.state.recentCharacters.shift();\n    }\n  }\n\n  /**\n   * Analyzes whether character is part of a caps lock sequence\n   * Uses the same logic as the original TypingEngine\n   */\n  private analyzeCapsLockSequence(character: string, charIndex: number, fullText: string) {\n    if (!character.match(/[A-Z]/)) {\n      return { isCapsLockSequence: false, isFirst: false, isLast: false };\n    }\n    \n    // Find the start and end of the caps region\n    let sequenceStart = charIndex;\n    let sequenceEnd = charIndex;\n    \n    // Scan backwards to find start of caps sequence\n    while (sequenceStart > 0) {\n      const prevChar = fullText[sequenceStart - 1];\n      if (prevChar.match(/[A-Z]/) || prevChar === ' ') {\n        sequenceStart--;\n      } else {\n        break;\n      }\n    }\n    \n    // Scan forwards to find end of caps sequence  \n    while (sequenceEnd < fullText.length - 1) {\n      const nextChar = fullText[sequenceEnd + 1];\n      if (nextChar.match(/[A-Z]/) || nextChar === ' ') {\n        sequenceEnd++;\n      } else {\n        break;\n      }\n    }\n    \n    // Count capital letters (excluding spaces)\n    let capitalCount = 0;\n    for (let i = sequenceStart; i <= sequenceEnd; i++) {\n      if (fullText[i].match(/[A-Z]/)) {\n        capitalCount++;\n      }\n    }\n    \n    const isCapsLockSequence = capitalCount >= this.config.capsLockThreshold;\n    \n    // Find first and last capital letters\n    let firstCapitalIndex = sequenceStart;\n    while (firstCapitalIndex <= sequenceEnd && !fullText[firstCapitalIndex].match(/[A-Z]/)) {\n      firstCapitalIndex++;\n    }\n    \n    let lastCapitalIndex = sequenceEnd;\n    while (lastCapitalIndex >= sequenceStart && !fullText[lastCapitalIndex].match(/[A-Z]/)) {\n      lastCapitalIndex--;\n    }\n    \n    return {\n      isCapsLockSequence,\n      isFirst: isCapsLockSequence && charIndex === firstCapitalIndex,\n      isLast: isCapsLockSequence && charIndex === lastCapitalIndex\n    };\n  }\n\n  /**\n   * Check if a symbol is considered complex (requires more precise movement)\n   */\n  private isComplexSymbol(character: string): boolean {\n    const complexSymbols = new Set(['@', '#', '$', '%', '^', '&', '*', '+', '=', '{', '}', '\\\\', '|', '`', '~', '<', '>']);\n    return complexSymbols.has(character);\n  }\n\n  /**\n   * Debug logging\n   */\n  private debug(message: string, data?: any) {\n    if (this.config.debug) {\n      console.log(`[KeyboardAnalyzer] ${message}`, data || '');\n    }\n  }\n\n  /**\n   * Reset keyboard state (useful for testing)\n   */\n  public resetState() {\n    this.state = {\n      currentView: 'letters',\n      capsLockActive: false,\n      shiftActive: false,\n      recentCharacters: [],\n      mode: this.config.keyboardMode\n    };\n  }\n\n  /**\n   * Analyzes a backspace key press and returns the key sequence\n   */\n  public analyzeBackspace(): KeySequence {\n    this.debug('Analyzing backspace key');\n    \n    const backspaceKey: KeyInfo = {\n      key: this.config.keyboardMode === 'mobile' ? this.layout.modifiers.backspace : 'backspace',\n      character: '\\b', // Backspace character\n      type: 'backspace',\n      keyboardView: this.state.currentView,\n      isCapsLock: false,\n      duration: this.layout.keyDurations.backspace || this.layout.keyDurations.modifier || 120,\n      sequenceIndex: 0,\n      sequenceLength: 1\n    };\n    \n    const sequence: KeySequence = {\n      character: '\\b',\n      keys: [backspaceKey],\n      totalDuration: backspaceKey.duration,\n      usesCapsLock: false\n    };\n    \n    this.debug('Generated backspace sequence:', sequence);\n    return sequence;\n  }\n\n  /**\n   * Get current keyboard state (useful for debugging)\n   */\n  public getState(): KeyboardState {\n    return { ...this.state };\n  }\n}","import type {\n  HumanLikeConfig,\n  MistakeInfo,\n  MistakeType,\n  TypingState,\n  TypingEvent,\n  TypingStats,\n  KeyInfo\n} from '../types';\nimport {\n  TIMING_CONSTANTS,\n  BEHAVIOR_RATES,\n  getAdjacentKeys,\n  COMMON_WORDS,\n  COMMON_TYPOS,\n  SPECIAL_CHARS,\n  SHIFT_CHARS,\n  NUMBER_CHARS,\n  SYMBOL_COMPLEXITY,\n  SENTENCE_ENDINGS,\n  CLAUSE_SEPARATORS,\n  LINE_BREAK_CHARS,\n  DEFAULT_CONFIG\n} from '../constants';\nimport { KeyboardAnalyzer } from '../keyboard/KeyboardAnalyzer';\n\nexport class TypingEngine {\n  private config: HumanLikeConfig;\n  private text: string;\n  private currentIndex: number = 0;\n  private displayText: string = '';\n  private state: TypingState = 'idle';\n  private timeoutId: number | null = null;\n  private keyTimeouts: Set<number> = new Set(); // Track all keyboard timing timeouts\n  private stats: TypingStats;\n  private events: TypingEvent[] = [];\n  private mistakes: MistakeInfo[] = [];\n  private correctionQueue: MistakeInfo[] = [];\n  private isCorrectingMistake: boolean = false;\n  private charactersTyped: number = 0;\n  private fatigueLevel: number = 0;\n  private pauseStartTime: number = 0;\n  private totalPausedTime: number = 0;\n  \n  // Keyboard simulation - always enabled now\n  private keyboardAnalyzer: KeyboardAnalyzer;\n  \n  // Event callbacks\n  private onStateChange?: (state: TypingState) => void;\n  private onCharacter?: (char: string, index: number) => void;\n  private onMistake?: (mistake: MistakeInfo) => void;\n  private onBackspace?: () => void;\n  private onComplete?: () => void;\n  private onProgress?: (progress: number) => void;\n  private onKey?: (keyInfo: KeyInfo) => void;\n\n  constructor(text: string, config: Partial<HumanLikeConfig> = {}) {\n    this.text = text ?? ''; // Handle null/undefined text\n    this.config = { ...DEFAULT_CONFIG, ...config };\n    this.stats = this.initializeStats();\n    \n    // Set callback from config if provided\n    if (this.config.onKey) {\n      this.onKey = this.config.onKey;\n    }\n    \n    // Initialize keyboard analyzer - now always enabled\n    this.keyboardAnalyzer = new KeyboardAnalyzer({\n      keyboardMode: this.config.keyboardMode || 'mobile',\n      capsLockThreshold: TIMING_CONSTANTS.CAPS_SEQUENCE_THRESHOLD,\n      useNaturalTiming: true, // Always use natural keyboard timing\n      debug: this.config.debug\n    });\n  }\n\n  private debug(...args: any[]): void {\n    if (this.config.debug) {\n      console.log(...args);\n    }\n  }\n\n  private safeCallback(callback: Function | undefined, ...args: any[]): void {\n    if (callback) {\n      try {\n        callback(...args);\n      } catch (error) {\n        if (this.config.debug) {\n          console.warn('Callback error:', error);\n        }\n        // Continue execution without crashing\n      }\n    }\n  }\n\n  private initializeStats(): TypingStats {\n    return {\n      totalCharacters: this.text.length,\n      charactersTyped: 0,\n      mistakesMade: 0,\n      mistakesCorrected: 0,\n      startTime: 0,\n      currentWPM: 0,\n      averageCharDelay: 0,\n      totalDuration: 0\n    };\n  }\n\n  public start(): void {\n    if (this.state === 'typing' || this.state === 'correcting') return;\n    \n    this.state = 'typing';\n    const now = Date.now();\n    \n    if (this.stats.startTime === 0) {\n      this.stats.startTime = now;\n    }\n    \n    this.safeCallback(this.onStateChange, 'typing');\n    this.scheduleNextCharacter();\n  }\n\n  public stop(): void {\n    if (this.timeoutId) {\n      clearTimeout(this.timeoutId);\n      this.timeoutId = null;\n    }\n    \n    // Clear all keyboard timing timeouts\n    this.keyTimeouts.forEach(timeoutId => clearTimeout(timeoutId));\n    this.keyTimeouts.clear();\n    \n    // Cancel all pending corrections\n    for (const mistake of this.mistakes) {\n      if (!mistake.corrected) {\n        mistake.corrected = true; // Mark as handled to prevent further correction attempts\n      }\n    }\n    this.correctionQueue = [];\n    this.isCorrectingMistake = false;\n    this.state = 'idle';\n    this.safeCallback(this.onStateChange, 'idle');\n  }\n\n  public pause(): void {\n    if (this.state === 'typing' || this.state === 'correcting') {\n      if (this.timeoutId) {\n        clearTimeout(this.timeoutId);\n        this.timeoutId = null;\n      }\n      this.pauseStartTime = Date.now();\n      this.state = 'paused';\n      this.safeCallback(this.onStateChange, 'paused');\n    }\n  }\n\n  public resume(): void {\n    if (this.state === 'paused') {\n      if (this.pauseStartTime > 0) {\n        this.totalPausedTime += Date.now() - this.pauseStartTime;\n        this.pauseStartTime = 0;\n      }\n      this.state = 'typing';\n      this.safeCallback(this.onStateChange, 'typing');\n      this.scheduleNextCharacter();\n    }\n  }\n\n  public skip(): void {\n    this.currentIndex = this.text.length;\n    this.displayText = this.text;\n    this.state = 'completed';\n    this.stats.endTime = Date.now();\n    this.safeCallback(this.onStateChange, 'completed');\n    this.safeCallback(this.onComplete);\n  }\n\n  public reset(): void {\n    this.stop();\n    this.currentIndex = 0;\n    this.displayText = '';\n    this.charactersTyped = 0;\n    this.fatigueLevel = 0;\n    this.mistakes = [];\n    this.correctionQueue = [];\n    this.isCorrectingMistake = false;\n    this.events = [];\n    this.pauseStartTime = 0;\n    this.totalPausedTime = 0;\n    this.stats = this.initializeStats();\n    this.state = 'idle';\n    this.safeCallback(this.onStateChange, 'idle');\n  }\n\n  private scheduleNextCharacter(): void {\n    // Handle empty text case\n    if (this.text.length === 0) {\n      this.completeTyping();\n      return;\n    }\n    \n    if (this.currentIndex >= this.text.length) {\n      // Don't immediately complete if we have pending corrections\n      const hasUncorrectedMistakes = this.mistakes.some(m => !m.corrected);\n      const hasPendingCorrections = this.correctionQueue.length > 0;\n      \n      if (hasUncorrectedMistakes || hasPendingCorrections) {\n        this.debug(`📝 Reached end but have ${this.mistakes.filter(m => !m.corrected).length} uncorrected mistakes and ${this.correctionQueue.length} queued corrections`);\n        // Process corrections first before completing\n        this.processNextCorrection();\n        return;\n      }\n      \n      // Wait for all key timeouts to complete before finishing\n      if (this.keyTimeouts.size > 0) {\n        this.debug(`⏳ Reached end but waiting for ${this.keyTimeouts.size} key timeouts to complete`);\n        this.timeoutId = window.setTimeout(() => {\n          this.scheduleNextCharacter();\n        }, 50);\n        return;\n      }\n      \n      this.completeTyping();\n      return;\n    }\n\n    const char = this.text[this.currentIndex];\n    const delay = this.calculateCharacterDelayWithKeyboard(char);\n    \n    // Skip concentration lapses for the first character to maintain predictable initial state\n    if (this.currentIndex > 0 && this.shouldHaveConcentrationLapse()) {\n      this.state = 'thinking';\n      this.safeCallback(this.onStateChange, 'thinking');\n      this.timeoutId = window.setTimeout(() => {\n        this.state = 'typing';\n        this.safeCallback(this.onStateChange, 'typing');\n        this.scheduleNextCharacter();\n      }, TIMING_CONSTANTS.CONCENTRATION_PAUSE);\n      return;\n    }\n\n    // Check if we should make a mistake\n    const shouldMakeMistake = this.shouldMakeMistake(char);\n    \n    // Use requestAnimationFrame for better performance on fast typing\n    if (delay < 30) {\n      requestAnimationFrame(() => {\n        if (shouldMakeMistake) {\n          this.makeMistake(char);\n        } else {\n          this.typeCharacter(char);\n        }\n      });\n    } else {\n      // Normal delay without state change\n      this.timeoutId = window.setTimeout(() => {\n        if (shouldMakeMistake) {\n          this.makeMistake(char);\n        } else {\n          this.typeCharacter(char);\n        }\n      }, delay);\n    }\n  }\n\n  /**\n   * Calculate character delay using natural keyboard timing\n   * This revolutionary approach replaces artificial delays with realistic key sequences\n   */\n  private calculateCharacterDelayWithKeyboard(char: string): number {\n    \n    // Generate key sequence for this character\n    const keySequence = this.keyboardAnalyzer.analyzeCharacter(char, this.currentIndex, this.text);\n    \n    // Apply user's speed configuration as a multiplier to the natural timing\n    // Default keyboard timing assumes ~80ms base speed, so we scale accordingly\n    const speedMultiplier = this.config.speed / 80.0;\n    \n    // Scale all key durations by the speed multiplier\n    const scaledKeys = keySequence.keys.map(keyInfo => ({\n      ...keyInfo,\n      duration: Math.round(keyInfo.duration * speedMultiplier)\n    }));\n    \n    const scaledTotalDuration = scaledKeys.reduce((sum, key) => sum + key.duration, 0);\n    \n    this.debug(`🎹 Natural timing for \"${char}\": ${scaledKeys.length} keys, ${scaledTotalDuration}ms total (speed: ${this.config.speed}ms, multiplier: ${speedMultiplier.toFixed(2)})`);\n    \n    // Fire onKey callbacks for each key in the sequence with scaled timing\n    let cumulativeDelay = 0;\n    scaledKeys.forEach((keyInfo) => {\n      const keyTimeoutId = window.setTimeout(() => {\n        // Execute onKey callback first\n        this.safeCallback(this.onKey, keyInfo);\n        this.debug(`🔑 Key press: \"${keyInfo.key}\" (${keyInfo.type}) - ${keyInfo.duration}ms`);\n        // Remove completed timeout from tracking AFTER callback execution\n        this.keyTimeouts.delete(keyTimeoutId);\n      }, cumulativeDelay);\n      // Track this timeout so it can be cleared if needed\n      this.keyTimeouts.add(keyTimeoutId);\n      cumulativeDelay += keyInfo.duration;\n    });\n    \n    // Return the total time for all keys in the sequence\n    // This replaces the old artificial CAPS_LOCK_ON_DELAY + SYMBOL_BASE_PENALTY approach\n    let totalDelay = scaledTotalDuration;\n    \n    // Apply speed variation\n    const variation = (Math.random() - 0.5) * 2 * this.config.speedVariation;\n    totalDelay += variation;\n    \n    // Apply fatigue and other human factors\n    if (this.config.fatigueEffect) {\n      totalDelay += this.fatigueLevel;\n      this.fatigueLevel += TIMING_CONSTANTS.FATIGUE_INCREMENT;\n    }\n    \n    // Check for burst typing\n    if (Math.random() < BEHAVIOR_RATES.BURST_TYPING) {\n      totalDelay *= TIMING_CONSTANTS.BURST_SPEED_MULTIPLIER;\n    }\n    \n    // Add pauses for punctuation and structure (these are still relevant)\n    if (SENTENCE_ENDINGS.has(char)) {\n      totalDelay += this.config.sentencePause;\n    } else if (CLAUSE_SEPARATORS.has(char)) {\n      totalDelay += TIMING_CONSTANTS.COMMA_PAUSE;\n    } else if (LINE_BREAK_CHARS.has(char)) {\n      totalDelay += TIMING_CONSTANTS.LINE_BREAK;\n    } else if (char === ' ') {\n      totalDelay += this.config.wordPause;\n      \n      // Check if next word is complex (should add thinking pause)\n      const nextWord = this.getNextWord();\n      if (nextWord && this.isComplexWord(nextWord)) {\n        totalDelay += this.config.thinkingPause;\n      }\n    }\n    \n    return Math.max(this.config.minCharDelay, totalDelay);\n  }\n\n\n  private shouldMakeMistake(char: string): boolean {\n    // Don't make mistakes on spaces, line breaks, or at the beginning\n    if (char === ' ' || LINE_BREAK_CHARS.has(char) || this.currentIndex === 0) return false;\n    \n    let mistakeChance = this.config.mistakeFrequency;\n    \n    // 2. NUMBER ROW DIFFICULTY - Numbers have higher mistake rate\n    if (NUMBER_CHARS.has(char)) {\n      mistakeChance *= 1.5; // 50% higher mistake rate for numbers\n    }\n    \n    // Shift characters are slightly more error-prone\n    if (SHIFT_CHARS.has(char)) {\n      mistakeChance *= 1.2; // 20% higher mistake rate for shift characters\n    }\n    \n    // Complex symbols have higher mistake rates\n    if (SYMBOL_COMPLEXITY[char] && SYMBOL_COMPLEXITY[char] >= 3) {\n      mistakeChance *= 1.3; // 30% higher mistake rate for complex symbols\n    }\n    \n    // Reduce mistake frequency for simple punctuation to avoid too many errors\n    if (SPECIAL_CHARS.has(char) && (!SYMBOL_COMPLEXITY[char] || SYMBOL_COMPLEXITY[char] === 1)) {\n      mistakeChance *= 0.5;\n    }\n    \n    // 6. LOOK-AHEAD TYPING - Sometimes type ahead and make mistakes\n    if (this.shouldMakeLookAheadMistake()) {\n      mistakeChance *= 2; // Double chance when typing ahead\n    }\n    \n    return Math.random() < mistakeChance;\n  }\n\n  private makeMistake(originalChar: string): void {\n    const mistakeType = this.selectMistakeType(originalChar);\n    const mistakeChar = this.generateMistakeChar(originalChar, mistakeType);\n    \n    if (!mistakeChar) {\n      // Fallback to typing correctly if no mistake could be generated\n      this.typeCharacter(originalChar);\n      return;\n    }\n    \n    const mistake: MistakeInfo = {\n      type: mistakeType,\n      originalChar,\n      mistakeChar,\n      position: this.currentIndex,\n      corrected: false,\n      realizationTime: this.config.realizationDelay + (Math.random() * 150)\n    };\n    \n    this.mistakes.push(mistake);\n    this.stats.mistakesMade++;\n    \n    this.debug(`🔴 MISTAKE: \"${originalChar}\" → \"${mistakeChar}\" (${mistakeType}) at pos ${this.currentIndex}`);\n    \n    // Type the mistake\n    this.displayText += mistakeChar;\n    this.currentIndex++;\n    this.charactersTyped++;\n    this.stats.charactersTyped = this.charactersTyped; // Keep stats in sync\n    \n    this.recordEvent({\n      type: 'mistake',\n      position: mistake.position,\n      timestamp: Date.now(),\n      char: mistakeChar,\n      mistake\n    });\n    \n    this.safeCallback(this.onCharacter, mistakeChar, this.currentIndex - mistakeChar.length);\n    this.safeCallback(this.onMistake, mistake);\n    this.updateProgress();\n    \n    // Add to correction queue instead of scheduling immediately\n    const realizationTime = Math.max(mistake.realizationTime, 200);\n    this.debug(`📝 Adding \"${mistakeChar}\" to correction queue (will correct in ${realizationTime}ms)`);\n    \n    this.timeoutId = window.setTimeout(() => {\n      if (!mistake.corrected) {\n        this.correctionQueue.push(mistake);\n        this.processNextCorrection();\n      }\n    }, realizationTime);\n  }\n\n  private processNextCorrection(): void {\n    // If already correcting or no corrections queued, return\n    if (this.isCorrectingMistake || this.correctionQueue.length === 0) {\n      return;\n    }\n\n    // Get the most recent mistake to correct first (LIFO for natural correction behavior)\n    const mistake = this.correctionQueue.pop()!;\n    \n    if (mistake.corrected) {\n      // Already corrected, process next\n      this.processNextCorrection();\n      return;\n    }\n\n    this.debug(`🔧 Processing correction for \"${mistake.mistakeChar}\" → \"${mistake.originalChar}\"`);\n    this.correctMistake(mistake);\n  }\n\n  private correctMistake(mistake: MistakeInfo): void {\n    this.isCorrectingMistake = true;\n    this.state = 'correcting';\n    this.safeCallback(this.onStateChange, 'correcting');\n    \n    this.debug(`🔧 Correcting mistake: \"${mistake.mistakeChar}\" → should be \"${mistake.originalChar}\"`);\n    this.debug(`📍 Current text: \"${this.displayText}\", current position: ${this.currentIndex}, mistake position: ${mistake.position}`);\n    \n    // Calculate exactly where we need to backspace to\n    const targetPosition = mistake.position;\n    const currentTextLength = this.displayText.length;\n    const charsToDelete = currentTextLength - targetPosition;\n    \n    this.debug(`🔄 Need to delete ${charsToDelete} chars to get back to position ${targetPosition}`);\n    \n    if (charsToDelete <= 0) {\n      // Already at or past the correct position, just mark as corrected and continue\n      this.debug(`⚠️ Already at correct position, marking as corrected`);\n      this.finishCorrection(mistake);\n      return;\n    }\n    \n    this.performBackspaceSequence(mistake, charsToDelete, targetPosition);\n  }\n\n  private performBackspaceSequence(mistake: MistakeInfo, charsToDelete: number, targetPosition: number): void {\n    let deletedCount = 0;\n    const backspaceDelay = this.config.backspaceSpeed;\n    \n    const performBackspace = () => {\n      if (deletedCount < charsToDelete && this.displayText.length > targetPosition) {\n        this.displayText = this.displayText.slice(0, -1);\n        deletedCount++;\n        \n        this.recordEvent({\n          type: 'backspace',\n          position: this.displayText.length,\n          timestamp: Date.now()\n        });\n        \n        // Generate keyboard simulation for backspace\n        if (this.keyboardAnalyzer && this.onKey) {\n          const backspaceSequence = this.keyboardAnalyzer.analyzeBackspace();\n          const speedMultiplier = this.config.speed / 80.0;\n          const scaledKeys = backspaceSequence.keys.map(keyInfo => ({\n            ...keyInfo,\n            duration: Math.round(keyInfo.duration * speedMultiplier)\n          }));\n          \n          // Emit all keys in the backspace sequence\n          scaledKeys.forEach(keyInfo => {\n            this.safeCallback(this.onKey, keyInfo);\n          });\n        }\n        \n        this.safeCallback(this.onBackspace);\n        \n        this.debug(`⬅️ Backspace ${deletedCount}/${charsToDelete}: \"${this.displayText}\" (length: ${this.displayText.length})`);\n        \n        if (deletedCount < charsToDelete && this.displayText.length > targetPosition) {\n          this.timeoutId = window.setTimeout(performBackspace, backspaceDelay);\n        } else {\n          // Finished backspacing\n          this.finishCorrection(mistake);\n        }\n      } else {\n        // Force finish correction if we've gone too far\n        this.finishCorrection(mistake);\n      }\n    };\n    \n    this.timeoutId = window.setTimeout(performBackspace, backspaceDelay);\n  }\n\n  private finishCorrection(mistake: MistakeInfo): void {\n    // Ensure we're at exactly the right position\n    this.currentIndex = mistake.position;\n    this.displayText = this.text.slice(0, mistake.position);\n    \n    mistake.corrected = true;\n    this.stats.mistakesCorrected++;\n    this.isCorrectingMistake = false;\n    \n    this.debug(`✅ Correction complete. Position: ${this.currentIndex}, Text: \"${this.displayText}\"`);\n    this.debug(`📝 Ready to type correct character: \"${mistake.originalChar}\"`);\n    \n    this.timeoutId = window.setTimeout(() => {\n      this.state = 'typing';\n      this.safeCallback(this.onStateChange, 'typing');\n      \n      // Type the correct character\n      this.typeCharacter(mistake.originalChar);\n      \n      // Process next correction in queue if any\n      if (this.correctionQueue.length > 0) {\n        this.timeoutId = window.setTimeout(() => {\n          this.processNextCorrection();\n        }, this.config.realizationDelay);\n      } else {\n        // No more corrections queued, check if we should complete\n        if (this.currentIndex >= this.text.length) {\n          this.timeoutId = window.setTimeout(() => {\n            this.completeTyping();\n          }, 100);\n        }\n      }\n    }, this.config.correctionPause);\n  }\n\n  private typeCharacter(char: string): void {\n    this.displayText += char;\n    this.currentIndex++;\n    this.charactersTyped++;\n    this.stats.charactersTyped = this.charactersTyped; // Keep stats in sync\n    \n    const now = Date.now();\n    this.recordEvent({\n      type: 'char',\n      char,\n      position: this.currentIndex - 1,\n      timestamp: now\n    });\n    \n    this.safeCallback(this.onCharacter, char, this.currentIndex - 1);\n    this.updateProgress();\n    this.updateWPM();\n    this.updateTotalDuration();\n    \n    this.scheduleNextCharacter();\n  }\n\n  private selectMistakeType(char: string): MistakeType {\n    const types: MistakeType[] = [];\n    \n    const adjacentKeys = getAdjacentKeys(this.config.keyboardMode || 'desktop');\n    if (this.config.mistakeTypes.adjacent && adjacentKeys[char.toLowerCase()]) {\n      types.push('adjacent');\n    }\n    if (this.config.mistakeTypes.random) {\n      types.push('random');\n    }\n    if (this.config.mistakeTypes.doubleChar) {\n      types.push('doubleChar');\n    }\n    if (this.config.mistakeTypes.commonTypos) {\n      types.push('commonTypo');\n    }\n    \n    // For look-ahead typing, prefer common typo or adjacent key mistakes\n    if (this.shouldMakeLookAheadMistake()) {\n      const lookAheadTypes = types.filter(type => type === 'commonTypo' || type === 'adjacent');\n      if (lookAheadTypes.length > 0) {\n        return lookAheadTypes[Math.floor(Math.random() * lookAheadTypes.length)];\n      }\n    }\n    \n    return types[Math.floor(Math.random() * types.length)] || 'adjacent';\n  }\n\n  private generateMistakeChar(originalChar: string, type: MistakeType): string | null {\n    const isOriginalUppercase = originalChar === originalChar.toUpperCase() && originalChar !== originalChar.toLowerCase();\n    \n    switch (type) {\n      case 'adjacent':\n        const adjacentKeys = getAdjacentKeys(this.config.keyboardMode || 'desktop');\n        const adjacent = adjacentKeys[originalChar.toLowerCase()];\n        if (adjacent && adjacent.length > 0) {\n          let mistakeChar = adjacent[Math.floor(Math.random() * adjacent.length)];\n          // CAPS LOCK LOGIC: Match the case of the original character\n          return isOriginalUppercase ? mistakeChar.toUpperCase() : mistakeChar.toLowerCase();\n        }\n        return null;\n        \n      case 'doubleChar':\n        return originalChar + originalChar;\n        \n      case 'random':\n        const chars = 'abcdefghijklmnopqrstuvwxyz';\n        let randomChar = chars[Math.floor(Math.random() * chars.length)];\n        // CAPS LOCK LOGIC: Match the case of the original character\n        return isOriginalUppercase ? randomChar.toUpperCase() : randomChar.toLowerCase();\n        \n      case 'commonTypo':\n        const currentWord = this.getCurrentWord();\n        if (currentWord && COMMON_TYPOS[currentWord.toLowerCase()]) {\n          const typoWord = COMMON_TYPOS[currentWord.toLowerCase()];\n          const charIndex = this.currentIndex - this.getWordStartIndex(currentWord);\n          if (charIndex < typoWord.length) {\n            let typoChar = typoWord[charIndex];\n            // CAPS LOCK LOGIC: Match the case of the original character\n            return isOriginalUppercase ? typoChar.toUpperCase() : typoChar.toLowerCase();\n          }\n        }\n        // Fallback to adjacent key mistake if no common typo available\n        const fallbackAdjacentKeys = getAdjacentKeys(this.config.keyboardMode || 'desktop');\n        const fallbackKeys = fallbackAdjacentKeys[originalChar.toLowerCase()];\n        if (fallbackKeys && fallbackKeys.length > 0) {\n          let mistakeChar = fallbackKeys[Math.floor(Math.random() * fallbackKeys.length)];\n          // CAPS LOCK LOGIC: Match the case of the original character\n          return isOriginalUppercase ? mistakeChar.toUpperCase() : mistakeChar.toLowerCase();\n        }\n        return null;\n        \n      default:\n        return null;\n    }\n  }\n\n  private shouldHaveConcentrationLapse(): boolean {\n    return this.config.concentrationLapses && Math.random() < BEHAVIOR_RATES.CONCENTRATION_LAPSE;\n  }\n\n\n  private getNextWord(): string | null {\n    const remainingText = this.text.slice(this.currentIndex + 1);\n    const match = remainingText.match(/^\\s*(\\w+)/);\n    return match ? match[1] : null;\n  }\n\n  private getCurrentWord(): string | null {\n    const beforeCursor = this.text.slice(0, this.currentIndex);\n    const afterCursor = this.text.slice(this.currentIndex);\n    \n    const wordBefore = beforeCursor.match(/(\\w+)$/);\n    const wordAfter = afterCursor.match(/^(\\w*)/);\n    \n    const before = wordBefore ? wordBefore[1] : '';\n    const after = wordAfter ? wordAfter[1] : '';\n    \n    return before + after || null;\n  }\n\n  private getWordStartIndex(word: string): number {\n    const beforeCursor = this.text.slice(0, this.currentIndex);\n    const wordStart = beforeCursor.lastIndexOf(word);\n    return wordStart !== -1 ? wordStart : this.currentIndex;\n  }\n\n  private isComplexWord(word: string): boolean {\n    return word.length > 7 || !COMMON_WORDS.has(word.toLowerCase());\n  }\n\n\n  // Helper method for look-ahead typing behavior\n  private shouldMakeLookAheadMistake(): boolean {\n    // Look ahead to see if we're approaching a common word ending\n    const remainingText = this.text.slice(this.currentIndex);\n    const nextFewChars = remainingText.slice(0, 4);\n    \n    // Common word endings that people tend to type ahead\n    const commonEndings = ['ing', 'tion', 'ly', 'ed', 'er', 'est', 'ness'];\n    \n    const hasCommonEnding = commonEndings.some(ending => \n      nextFewChars.includes(ending.slice(0, Math.min(ending.length, nextFewChars.length)))\n    );\n    \n    return hasCommonEnding && Math.random() < TIMING_CONSTANTS.LOOK_AHEAD_CHANCE;\n  }\n\n  private completeTyping(): void {\n    // Before completing, check for any uncorrected mistakes or queued corrections\n    const uncorrectedMistakes = this.mistakes.filter(m => !m.corrected);\n    const hasQueuedCorrections = this.correctionQueue.length > 0;\n    \n    if (uncorrectedMistakes.length > 0 || hasQueuedCorrections || this.isCorrectingMistake) {\n      this.debug(`🔍 Found ${uncorrectedMistakes.length} uncorrected mistakes, ${this.correctionQueue.length} queued corrections, correcting: ${this.isCorrectingMistake}`);\n      \n      // Add any uncorrected mistakes to the correction queue\n      for (const mistake of uncorrectedMistakes) {\n        if (!this.correctionQueue.includes(mistake)) {\n          this.correctionQueue.push(mistake);\n        }\n      }\n      \n      // Process corrections only if not already correcting\n      if (!this.isCorrectingMistake && this.correctionQueue.length > 0) {\n        this.processNextCorrection();\n      }\n      \n      // Check again after a delay, but prevent infinite recursion\n      if (this.state !== 'completed') {\n        this.timeoutId = window.setTimeout(() => {\n          this.completeTyping();\n        }, 500);\n      }\n      return;\n    }\n    \n    // Final check - should not reach here with pending timeouts due to scheduleNextCharacter logic\n    if (this.keyTimeouts.size > 0) {\n      this.debug(`⚠️ Warning: completeTyping called with ${this.keyTimeouts.size} pending key timeouts`);\n      // This is a fallback - the main logic should prevent this\n      this.timeoutId = window.setTimeout(() => {\n        this.completeTyping();\n      }, 100);\n      return;\n    }\n    \n    // Ensure final text matches exactly what was intended\n    this.displayText = this.text;\n    this.currentIndex = this.text.length;\n    \n    // Only set completed state if we're not already completed\n    if (this.state !== 'completed') {\n      this.state = 'completed';\n      const now = Date.now();\n      this.stats.endTime = now;\n      \n      // Final duration update\n      this.updateTotalDuration();\n      \n      this.safeCallback(this.onStateChange, 'completed');\n      this.safeCallback(this.onComplete);\n      \n      this.debug(`🎉 Typing completed! Final text: \"${this.displayText}\"`);\n      this.debug(`⏱️ Total duration: ${this.stats.totalDuration}ms`);\n      \n      // Final progress update to ensure 100%\n      this.safeCallback(this.onProgress, 100);\n    }\n  }\n\n  private updateProgress(): void {\n    // Use the public getProgress method for consistent calculation\n    let actualProgress = this.getProgress();\n    \n    // Don't report 100% progress unless we're actually completed and have no pending corrections\n    const hasUncorrectedMistakes = this.mistakes.some(m => !m.corrected);\n    const hasPendingCorrections = this.correctionQueue.length > 0;\n    \n    if (actualProgress >= 100 && (hasUncorrectedMistakes || hasPendingCorrections || this.isCorrectingMistake)) {\n      // Cap progress at 99% if we still have work to do\n      actualProgress = Math.min(99, actualProgress);\n    }\n    \n    this.safeCallback(this.onProgress, actualProgress);\n  }\n\n  private updateWPM(): void {\n    if (this.stats.startTime === 0) return;\n    \n    const now = Date.now();\n    const minutesElapsed = (now - this.stats.startTime) / 60000;\n    const wordsTyped = this.charactersTyped / 5; // Standard WPM calculation\n    \n    this.stats.currentWPM = Math.round(wordsTyped / minutesElapsed);\n  }\n\n  private updateTotalDuration(): void {\n    if (this.stats.startTime === 0) return;\n    \n    const now = Date.now();\n    // Total duration is the time elapsed minus any paused time\n    this.stats.totalDuration = (now - this.stats.startTime) - this.totalPausedTime;\n  }\n\n\n  private recordEvent(event: TypingEvent): void {\n    this.events.push(event);\n  }\n\n  // Public getters\n  public getText(): string { return this.text; }\n  public getDisplayText(): string { return this.displayText; }\n  public getState(): TypingState { return this.state; }\n  public getProgress(): number { \n    if (this.text.length === 0) return 100;\n    if (this.state === 'completed') return 100;\n    \n    const rawProgress = (this.currentIndex / this.text.length) * 100;\n    if (rawProgress > 100) {\n      this.debug(`⚠️ Progress calculation error: currentIndex=${this.currentIndex}, textLength=${this.text.length}, rawProgress=${rawProgress}%`);\n    }\n    return Math.min(100, rawProgress); \n  }\n  public getStats(): TypingStats { return { ...this.stats }; }\n  public getMistakes(): MistakeInfo[] { return [...this.mistakes]; }\n  public getEvents(): TypingEvent[] { return [...this.events]; }\n  public getCurrentIndex(): number { return this.currentIndex; }\n  public isCompleted(): boolean { return this.state === 'completed'; }\n  public isTyping(): boolean { return this.state === 'typing' || this.state === 'correcting'; }\n  public isPaused(): boolean { return this.state === 'paused'; }\n  public getTotalDuration(): number { \n    this.updateTotalDuration(); \n    return this.stats.totalDuration; \n  }\n\n  // Event listener setters\n  public onStateChangeListener(callback: (state: TypingState) => void): void {\n    this.onStateChange = callback;\n  }\n  \n  public onCharacterListener(callback: (char: string, index: number) => void): void {\n    this.onCharacter = callback;\n  }\n  \n  public onMistakeListener(callback: (mistake: MistakeInfo) => void): void {\n    this.onMistake = callback;\n  }\n  \n  public onBackspaceListener(callback: () => void): void {\n    this.onBackspace = callback;\n  }\n  \n  public onCompleteListener(callback: () => void): void {\n    this.onComplete = callback;\n  }\n  \n  public onProgressListener(callback: (progress: number) => void): void {\n    this.onProgress = callback;\n  }\n  \n  public onKeyListener(callback: (keyInfo: KeyInfo) => void): void {\n    this.onKey = callback;\n  }\n\n  // Configuration updates\n  public updateConfig(newConfig: Partial<HumanLikeConfig>): void {\n    this.config = { ...this.config, ...newConfig };\n  }\n\n  public updateText(newText: string): void {\n    const wasTyping = this.state === 'typing' || this.state === 'correcting' || this.state === 'thinking';\n    this.stop();\n    this.text = newText ?? ''; // Handle null/undefined text\n    this.reset();\n    \n    // Auto-restart if was previously typing\n    if (wasTyping) {\n      this.start();\n    }\n  }\n\n  // Debug method to check mistake correction status\n  public getUncorrectedMistakes(): MistakeInfo[] {\n    return this.mistakes.filter(m => !m.corrected);\n  }\n\n  // Method to get current correction queue\n  public getCorrectionQueue(): MistakeInfo[] {\n    return [...this.correctionQueue];\n  }\n\n  // Method to force correction of all remaining mistakes (for debugging)\n  public forceCorrectAllMistakes(): void {\n    const uncorrected = this.getUncorrectedMistakes();\n    if (uncorrected.length > 0 || this.correctionQueue.length > 0) {\n      this.debug(`🔧 Forcing correction of ${uncorrected.length} uncorrected mistakes and ${this.correctionQueue.length} queued corrections`);\n      \n      // Add uncorrected mistakes to queue\n      for (const mistake of uncorrected) {\n        if (!this.correctionQueue.includes(mistake)) {\n          this.correctionQueue.push(mistake);\n        }\n      }\n      \n      // Process all corrections\n      this.processNextCorrection();\n    }\n  }\n}","import { useState, useEffect, useRef, useCallback } from 'react';\nimport type { \n  HumanLikeConfig, \n  HumanLikeHookReturn, \n  TypingState, \n  MistakeInfo, \n  KeyInfo,\n  StateChangeEvent\n} from '../types';\nimport { TypingEngine } from '../utils/TypingEngine';\n\ninterface UseHumanLikeOptions {\n  text: string;\n  config?: Partial<HumanLikeConfig>;\n  autoStart?: boolean;\n  showCursor?: boolean;\n  cursorChar?: string;\n  cursorBlinkSpeed?: number;\n  id?: string;\n  // Enhanced event system\n  onStart?: (id?: string) => void;\n  onComplete?: (id?: string) => void;\n  onChar?: (char: string, index: number, id?: string) => void;\n  onMistake?: (mistake: MistakeInfo, id?: string) => void;\n  onBackspace?: (id?: string) => void;\n  onPause?: () => void;\n  onResume?: () => void;\n  onStateChange?: (event: StateChangeEvent) => void;\n  onKeyboardReset?: () => void;\n  // Keyboard simulation options\n  keyboardMode?: 'mobile' | 'desktop';\n  onKey?: (keyInfo: KeyInfo) => void;\n}\n\nexport function useHumanLike(options: UseHumanLikeOptions): HumanLikeHookReturn {\n  const {\n    text,\n    config = {},\n    autoStart = false,\n    showCursor: initialShowCursor = true,\n    cursorBlinkSpeed = 530,\n    id,\n    onStart,\n    onComplete,\n    onChar,\n    onMistake,\n    onBackspace,\n    onPause,\n    onResume,\n    onStateChange,\n    onKeyboardReset,\n    keyboardMode,\n    onKey\n  } = options;\n\n  // Core state\n  const [displayText, setDisplayText] = useState('');\n  const [currentState, setCurrentState] = useState<TypingState>('idle');\n  const [progress, setProgress] = useState(0);\n  const [currentWPM, setCurrentWPM] = useState(0);\n  const [mistakeCount, setMistakeCount] = useState(0);\n  const [totalDuration, setTotalDuration] = useState(0);\n  const [showCursor, setShowCursor] = useState(initialShowCursor);\n  const [cursorCharState, setCursorCharState] = useState(options.cursorChar || '|');\n  const [cursorBlinkSpeedState, setCursorBlinkSpeedState] = useState(cursorBlinkSpeed);\n  \n\n  // Refs\n  const engineRef = useRef<TypingEngine | null>(null);\n  const cursorIntervalRef = useRef<number | null>(null);\n  const isInitializedRef = useRef(false);\n  const previousStateRef = useRef<TypingState>('idle');\n\n  // Sync prop changes with internal state\n  useEffect(() => {\n    if (options.cursorChar !== undefined) {\n      setCursorCharState(options.cursorChar || '|');\n    }\n  }, [options.cursorChar]);\n\n  useEffect(() => {\n    if (options.showCursor !== undefined) {\n      setShowCursor(options.showCursor);\n    }\n  }, [options.showCursor]);\n\n  useEffect(() => {\n    if (cursorBlinkSpeed !== undefined) {\n      setCursorBlinkSpeedState(cursorBlinkSpeed);\n    }\n  }, [cursorBlinkSpeed]);\n\n  // Helper function to sync all state with engine\n  const syncStateWithEngine = useCallback((engine: TypingEngine) => {\n    setDisplayText(engine.getDisplayText());\n    setProgress(engine.getProgress());\n    setCurrentWPM(engine.getStats().currentWPM);\n    setMistakeCount(engine.getMistakes().length);\n    setTotalDuration(engine.getTotalDuration());\n    setCurrentState(engine.getState());\n  }, []);\n\n  // Initialize typing engine once\n  useEffect(() => {\n    // Merge keyboard options into config\n    const enhancedConfig = {\n      ...config,\n      ...(keyboardMode && { keyboardMode }),\n      ...(onKey && { onKey: (keyInfo: KeyInfo) => {\n        // Pass the complete KeyInfo object to preserve all key information\n        // (type, duration, sequenceIndex, sequenceLength, etc.)\n        onKey(keyInfo);\n      }})\n    };\n    \n    const typingEngine = new TypingEngine(text, enhancedConfig);\n    engineRef.current = typingEngine;\n    \n    // Initial state sync\n    syncStateWithEngine(typingEngine);\n    \n    // Set up event listeners with optimized rendering\n    typingEngine.onStateChangeListener((state: TypingState) => {\n      const previousState = previousStateRef.current;\n      \n      // Sync all state at once to avoid race conditions\n      setCurrentState(state);\n      setDisplayText(typingEngine.getDisplayText());\n      setProgress(typingEngine.getProgress());\n      setCurrentWPM(typingEngine.getStats().currentWPM);\n      setMistakeCount(typingEngine.getMistakes().length);\n      setTotalDuration(typingEngine.getTotalDuration());\n      \n      onStateChange?.({\n        previousState,\n        currentState: state,\n        timestamp: Date.now()\n      });\n      \n      // Update previous state ref\n      previousStateRef.current = state;\n      \n      // Handle state-specific logic\n      if (state === 'typing' && !isInitializedRef.current) {\n        onStart?.(id);\n        isInitializedRef.current = true;\n      } else if (state === 'completed') {\n        onComplete?.(id);\n      } else if (state === 'paused') {\n        onPause?.();\n      } else if (state === 'typing' && isInitializedRef.current) {\n        onResume?.();\n      }\n    });\n\n    // Optimize character updates to prevent flickering\n    let updateTimeout: number | null = null;\n    typingEngine.onCharacterListener((char, index) => {\n      // Immediate update for better responsiveness\n      setDisplayText(typingEngine.getDisplayText());\n      setProgress(typingEngine.getProgress());\n      \n      // Update WPM more frequently during active typing\n      const stats = typingEngine.getStats();\n      setCurrentWPM(stats.currentWPM);\n      \n      onChar?.(char, index, id);\n      \n      // Clear any pending update to prevent double rendering\n      if (updateTimeout) {\n        clearTimeout(updateTimeout);\n        updateTimeout = null;\n      }\n    });\n\n    typingEngine.onMistakeListener((mistake) => {\n      // Sync mistake count with engine's actual count\n      setMistakeCount(typingEngine.getMistakes().length);\n      onMistake?.(mistake, id);\n    });\n    \n    // Set up keyboard simulation listener if provided (either direct or via config)\n    const keyCallback = onKey || enhancedConfig.onKey;\n    if (keyCallback) {\n      typingEngine.onKeyListener((keyInfo) => {\n        // Pass the complete KeyInfo object to preserve all information\n        keyCallback(keyInfo);\n      });\n    }\n\n    // Optimize backspace updates\n    typingEngine.onBackspaceListener(() => {\n      // Immediate update for consistency with character updates\n      setDisplayText(typingEngine.getDisplayText());\n      setProgress(typingEngine.getProgress());\n      onBackspace?.(id);\n    });\n\n    typingEngine.onProgressListener((progressValue) => {\n      setProgress(progressValue);\n    });\n\n    // Auto-start if requested\n    if (autoStart) {\n      typingEngine.start();\n    }\n\n    // Cleanup on unmount or text/config change\n    return () => {\n      typingEngine.stop();\n      if (updateTimeout) {\n        clearTimeout(updateTimeout);\n      }\n    };\n  }, [text, JSON.stringify(config), autoStart]);\n\n  // Update WPM periodically only when typing\n  useEffect(() => {\n    let wpmInterval: number | null = null;\n    \n    if (currentState === 'typing' || currentState === 'correcting') {\n      wpmInterval = window.setInterval(() => {\n        if (engineRef.current) {\n          const stats = engineRef.current.getStats();\n          setCurrentWPM(stats.currentWPM);\n        }\n      }, 1000);\n    }\n\n    return () => {\n      if (wpmInterval) {\n        clearInterval(wpmInterval);\n      }\n    };\n  }, [currentState]);\n\n  // Cursor blinking effect - optimized to reduce re-renders\n  useEffect(() => {\n    // Clear any existing interval\n    if (cursorIntervalRef.current) {\n      clearInterval(cursorIntervalRef.current);\n      cursorIntervalRef.current = null;\n    }\n\n    // Only manage blinking if cursor should be visible\n    const shouldShowCursor = options.showCursor !== undefined ? options.showCursor : initialShowCursor;\n    \n    if (shouldShowCursor && (currentState === 'idle' || currentState === 'paused' || currentState === 'thinking')) {\n      // Start blinking for idle/paused/thinking states (realistic behavior)\n      setShowCursor(true);\n      cursorIntervalRef.current = window.setInterval(() => {\n        setShowCursor(prev => !prev);\n      }, cursorBlinkSpeedState);\n    } else if (currentState === 'completed') {\n      // Hide cursor when completed\n      setShowCursor(false);\n    } else if (shouldShowCursor && (currentState === 'typing' || currentState === 'correcting')) {\n      // Show solid cursor while actively typing/correcting (realistic behavior)\n      setShowCursor(true);\n    } else {\n      // Default to showing cursor if it should be visible\n      setShowCursor(shouldShowCursor);\n    }\n\n    return () => {\n      if (cursorIntervalRef.current) {\n        clearInterval(cursorIntervalRef.current);\n        cursorIntervalRef.current = null;\n      }\n    };\n  }, [currentState, options.showCursor, initialShowCursor, cursorBlinkSpeedState]);\n\n  // Control methods\n  const start = useCallback(() => {\n    engineRef.current?.start();\n  }, []);\n\n  const stop = useCallback(() => {\n    engineRef.current?.stop();\n    isInitializedRef.current = false;\n  }, []);\n\n  const pause = useCallback(() => {\n    engineRef.current?.pause();\n  }, []);\n\n  const resume = useCallback(() => {\n    engineRef.current?.resume();\n  }, []);\n\n  const skip = useCallback(() => {\n    if (engineRef.current) {\n      engineRef.current.skip();\n      // Let the engine's completion logic handle state updates\n      // The onComplete callback will be triggered automatically\n      setDisplayText(engineRef.current.getDisplayText());\n      setProgress(engineRef.current.getProgress());\n      setCurrentWPM(engineRef.current.getStats().currentWPM);\n    }\n  }, [text]);\n\n  const rewind = useCallback(() => {\n    if (engineRef.current) {\n      engineRef.current.reset();\n      // Sync all state with the reset engine\n      setDisplayText(engineRef.current.getDisplayText());\n      setProgress(engineRef.current.getProgress());\n      setMistakeCount(engineRef.current.getMistakes().length);\n      setCurrentWPM(engineRef.current.getStats().currentWPM);\n      setTotalDuration(engineRef.current.getTotalDuration());\n      isInitializedRef.current = false;\n    }\n  }, []);\n\n  const reset = useCallback(() => {\n    rewind();\n  }, [rewind]);\n\n  const resetKeyboard = useCallback(() => {\n    // Reset keyboard-specific state and emit event\n    if (engineRef.current) {\n      engineRef.current.reset();\n      setDisplayText(engineRef.current.getDisplayText());\n      setProgress(engineRef.current.getProgress());\n      setMistakeCount(engineRef.current.getMistakes().length);\n      setCurrentWPM(engineRef.current.getStats().currentWPM);\n      setTotalDuration(engineRef.current.getTotalDuration());\n      isInitializedRef.current = false;\n    }\n    onKeyboardReset?.();\n  }, [onKeyboardReset]);\n\n  // Cursor control methods\n  const setCursorVisible = useCallback((visible: boolean) => {\n    setShowCursor(visible);\n  }, []);\n\n  const setCursorChar = useCallback((char: string) => {\n    setCursorCharState(char || '|'); // Fallback to default if empty\n  }, []);\n\n  const setCursorBlinkSpeed = useCallback((speed: number) => {\n    setCursorBlinkSpeedState(Math.max(100, speed)); // Minimum 100ms for sanity\n  }, []);\n\n  // Cleanup on unmount\n  useEffect(() => {\n    return () => {\n      engineRef.current?.stop();\n      if (cursorIntervalRef.current) {\n        clearInterval(cursorIntervalRef.current);\n      }\n    };\n  }, []);\n\n  // Computed properties\n  const isTyping = currentState === 'typing' || currentState === 'correcting';\n  const isPaused = currentState === 'paused';\n  const isCompleted = currentState === 'completed';\n  const isActive = currentState !== 'idle' && currentState !== 'completed';\n\n  return {\n    displayText,\n    isTyping,\n    isPaused,\n    isCompleted,\n    isActive,\n    currentState,\n    progress,\n    currentWPM,\n    mistakeCount,\n    totalDuration,\n    showCursor: showCursor && initialShowCursor,\n    cursorChar: cursorCharState,\n    cursorBlinkSpeed: cursorBlinkSpeedState,\n    start,\n    stop,\n    pause,\n    resume,\n    skip,\n    rewind,\n    reset,\n    resetKeyboard,\n    setCursorVisible,\n    setCursorChar,\n    setCursorBlinkSpeed\n  };\n}"],"names":["TIMING_CONSTANTS","BASE_SPEED","SPEED_VARIATION","MIN_CHAR_DELAY","SENTENCE_PAUSE","COMMA_PAUSE","WORD_SPACE","LINE_BREAK","REALIZATION_DELAY","CORRECTION_PAUSE","BACKSPACE_SPEED","THINKING_PAUSE","FATIGUE_INCREMENT","BURST_SPEED_MULTIPLIER","CONCENTRATION_PAUSE","SHIFT_HESITATION","CAPS_LOCK_ON_DELAY","CAPS_LOCK_OFF_DELAY","CAPS_SEQUENCE_THRESHOLD","NUMBER_ROW_PENALTY","SYMBOL_BASE_PENALTY","LOOK_AHEAD_CHANCE","BEHAVIOR_RATES","MISTAKE_FREQUENCY","CONCENTRATION_LAPSE","BURST_TYPING","FATIGUE_FACTOR","OVERCORRECTION_RATE","DESKTOP_ADJACENT","q","w","e","r","t","y","u","i","o","p","a","s","d","f","g","h","j","k","l","z","x","c","v","b","n","m","MOBILE_ADJACENT","QWERTY_ADJACENT","getAdjacentKeys","keyboardMode","COMMON_WORDS","Set","COMMON_TYPOS","the","and","for","you","that","this","with","have","from","they","been","than","what","your","when","there","their","would","could","should","through","because","before","after","where","which","between","different","important","example","without","another","development","environment","government","management","information","available","business","complete","language","experience","position","question","remember","separate","something","together","understand","SPECIAL_CHARS","SHIFT_CHARS","NUMBER_CHARS","SYMBOL_COMPLEXITY","_","$","SENTENCE_ENDINGS","CLAUSE_SEPARATORS","LINE_BREAK_CHARS","DEFAULT_CONFIG","speed","speedVariation","mistakeFrequency","mistakeTypes","adjacent","random","doubleChar","commonTypos","fatigueEffect","concentrationLapses","overcorrection","debug","sentencePause","wordPause","thinkingPause","minCharDelay","backspaceSpeed","realizationDelay","correctionPause","MOBILE_LAYOUT","views","letters","numbers","symbols","emoji","viewSwitchers","toNumbers","toSymbols","toLetters","toEmoji","modifiers","shift","caps","space","enter","backspace","keyDurations","letter","number","symbol","modifier","viewSwitch","MOBILE_CHARACTER_TO_VIEW","Object","fromEntries","split","map","DESKTOP_QWERTY_LAYOUT","DESKTOP_KEY_MAPPING","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","MOBILE_TIMING_PROFILES","MOBILE_CASUAL","name","description","baseMultiplier","viewSwitchDelay","consecutiveKeyBonus","complexSymbolPenalty","capsLockTransitionDelay","MOBILE_FAST","MOBILE_CAREFUL","TABLET","DESKTOP_TIMING_PROFILES","DESKTOP_AVERAGE","DESKTOP_FAST","DESKTOP_PROGRAMMER","DESKTOP_SLOW","DESKTOP_GAMING","getDefaultTimingProfile","userHint","calculateContextualTiming","baseDelay","profile","context","adjustedDelay","isConsecutiveSameHand","isComplexSymbol","isViewSwitch","isCapsLockTransition","KeyboardAnalyzer","constructor","config","__publicField","capsLockThreshold","useNaturalTiming","timingProfile","typingSpeed","baseLayout","customLayout","layout","state","currentView","capsLockActive","shiftActive","recentCharacters","mode","analyzeCharacter","character","charIndex","fullText","updateRecentCharacters","capsLockInfo","analyzeCapsLockSequence","keys","analyzeMobileCharacter","analyzeDesktopCharacter","totalDuration","reduce","sum","key","duration","sequence","usesCapsLock","isCapsLockSequence","capsInfo","sequenceIndex","type","keyboardView","isCapsLock","sequenceLength","targetView","getCharacterView","getViewSwitchSequence","forEach","viewKey","push","match","isFirst","createCapsKey","isLast","createLetterKey","toLowerCase","length","createShiftKey","mainKey","createCharacterKey","mapping","physicalKey","requiresShift","keyType","to","turningOn","contextualDuration","baseDuration","sequenceStart","sequenceEnd","prevChar","nextChar","capitalCount","firstCapitalIndex","lastCapitalIndex","has","message","data","console","log","resetState","analyzeBackspace","backspaceKey","getState","TypingEngine","text","stats","initializeStats","onKey","keyboardAnalyzer","args","safeCallback","callback","error","warn","totalCharacters","charactersTyped","mistakesMade","mistakesCorrected","startTime","currentWPM","averageCharDelay","start","now","Date","onStateChange","scheduleNextCharacter","stop","timeoutId","clearTimeout","keyTimeouts","clear","mistake","mistakes","corrected","correctionQueue","isCorrectingMistake","pause","pauseStartTime","resume","totalPausedTime","skip","currentIndex","displayText","endTime","onComplete","reset","fatigueLevel","events","completeTyping","hasUncorrectedMistakes","some","hasPendingCorrections","filter","processNextCorrection","size","window","setTimeout","char","delay","calculateCharacterDelayWithKeyboard","shouldHaveConcentrationLapse","shouldMakeMistake","requestAnimationFrame","makeMistake","typeCharacter","keySequence","speedMultiplier","scaledKeys","keyInfo","Math","round","scaledTotalDuration","toFixed","cumulativeDelay","keyTimeoutId","delete","add","totalDelay","nextWord","getNextWord","isComplexWord","max","mistakeChance","shouldMakeLookAheadMistake","originalChar","mistakeType","selectMistakeType","mistakeChar","generateMistakeChar","realizationTime","recordEvent","timestamp","onCharacter","onMistake","updateProgress","pop","correctMistake","targetPosition","charsToDelete","finishCorrection","performBackspaceSequence","deletedCount","backspaceDelay","performBackspace","slice","backspaceSequence","onBackspace","updateWPM","updateTotalDuration","types","adjacentKeys","lookAheadTypes","floor","isOriginalUppercase","toUpperCase","chars","randomChar","currentWord","getCurrentWord","typoWord","getWordStartIndex","typoChar","fallbackKeys","beforeCursor","afterCursor","wordBefore","wordAfter","word","wordStart","lastIndexOf","nextFewChars","ending","includes","min","uncorrectedMistakes","hasQueuedCorrections","onProgress","actualProgress","getProgress","minutesElapsed","wordsTyped","event","getText","getDisplayText","rawProgress","getStats","getMistakes","getEvents","getCurrentIndex","isCompleted","isTyping","isPaused","getTotalDuration","onStateChangeListener","onCharacterListener","onMistakeListener","onBackspaceListener","onCompleteListener","onProgressListener","onKeyListener","updateConfig","newConfig","updateText","newText","wasTyping","getUncorrectedMistakes","getCorrectionQueue","forceCorrectAllMistakes","uncorrected","options","autoStart","showCursor","initialShowCursor","cursorBlinkSpeed","id","onStart","onChar","onPause","onResume","onKeyboardReset","setDisplayText","useState","currentState","setCurrentState","progress","setProgress","setCurrentWPM","mistakeCount","setMistakeCount","setTotalDuration","setShowCursor","cursorCharState","setCursorCharState","cursorChar","cursorBlinkSpeedState","setCursorBlinkSpeedState","engineRef","useRef","cursorIntervalRef","isInitializedRef","previousStateRef","useEffect","syncStateWithEngine","useCallback","engine","enhancedConfig","typingEngine","current","previousState","index","keyCallback","progressValue","JSON","stringify","wpmInterval","setInterval","clearInterval","shouldShowCursor","prev","_a","rewind","resetKeyboard","setCursorVisible","visible","setCursorChar","setCursorBlinkSpeed","isActive"],"mappings":"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"}