qwerty-cli 0.0.1-alpha.6 → 0.0.1-alpha.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/cli.js +1167 -460
  2. package/dist/cli.js.map +1 -1
  3. package/package.json +1 -1
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../package.json","../src/commands/config.ts","../src/infra/config-store.ts","../src/infra/paths.ts","../src/infra/fs-store.ts","../src/commands/dict.ts","../src/domain/dictionary.ts","../src/infra/registry-store.ts","../src/infra/dict-downloader.ts","../src/commands/practice.ts","../src/ui/App.tsx","../src/ui/nav.tsx","../src/ui/Fullscreen.tsx","../src/ui/audio-context.tsx","../src/infra/audio.ts","../src/ui/app-state.tsx","../src/i18n/context.tsx","../src/i18n/strings.ts","../src/i18n/locale.ts","../src/ui/screens/MainMenu.tsx","../src/ui/components/BigWord.tsx","../src/util/text.ts","../src/ui/screens/PracticeScreen.tsx","../src/util/shuffle.ts","../src/domain/chapters.ts","../src/domain/input-buffer.ts","../src/domain/session.ts","../src/domain/mistakes.ts","../src/ui/hooks/useWordLoop.ts","../src/ui/hooks/useAudio.ts","../src/ui/hooks/useSessionPersistence.ts","../src/domain/stats.ts","../src/infra/session-tracker.ts","../src/ui/screens/DictBrowser.tsx","../src/ui/screens/ConfigEditor.tsx","../src/ui/screens/StatsViewer.tsx","../src/ui/screens/WordLookup.tsx","../src/util/report.ts","../src/commands/stats.ts","../src/commands/word.ts","../src/commands/menu.ts"],"sourcesContent":["import { Command } from 'commander';\nimport pkg from '../package.json' with { type: 'json' };\nimport { buildConfigCommand } from './commands/config.js';\nimport { buildDictCommand } from './commands/dict.js';\nimport { buildPracticeCommand } from './commands/practice.js';\nimport { buildStatsCommand } from './commands/stats.js';\nimport { buildWordCommand } from './commands/word.js';\nimport { runMainMenu } from './commands/menu.js';\n\nconst program = new Command();\n\nprogram\n .name('qwerty')\n .description('Terminal clone of qwerty-learner — typing practice for English vocabulary')\n .version(pkg.version);\n\nprogram.addCommand(buildPracticeCommand());\nprogram.addCommand(buildDictCommand());\nprogram.addCommand(buildWordCommand());\nprogram.addCommand(buildStatsCommand());\nprogram.addCommand(buildConfigCommand());\n\nprogram.action(async () => {\n await runMainMenu();\n});\n\nprogram.parseAsync(process.argv).catch((err) => {\n console.error(err instanceof Error ? err.message : err);\n process.exit(1);\n});\n","{\n \"name\": \"qwerty-cli\",\n \"version\": \"0.0.1-alpha.6\",\n \"description\": \"Terminal clone of qwerty-learner: typing practice for English vocabulary, with chapters, dictation, mistake book, and audio.\",\n \"type\": \"module\",\n \"bin\": {\n \"qwerty\": \"bin/qwerty.mjs\"\n },\n \"files\": [\n \"dist\",\n \"bin\",\n \"assets\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"sync-registry\": \"tsx scripts/sync-registry.ts\",\n \"prepublishOnly\": \"pnpm build\"\n },\n \"engines\": {\n \"node\": \">=20\"\n },\n \"keywords\": [\n \"qwerty\",\n \"typing\",\n \"cli\",\n \"vocabulary\",\n \"ink\",\n \"terminal\"\n ],\n \"license\": \"MIT\",\n \"dependencies\": {\n \"chalk\": \"^5.3.0\",\n \"commander\": \"^12.1.0\",\n \"ink\": \"^5.0.1\",\n \"p-queue\": \"^8.0.1\",\n \"react\": \"^18.3.1\",\n \"undici\": \"^6.19.8\",\n \"zod\": \"^3.23.8\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.14.10\",\n \"@types/react\": \"^18.3.3\",\n \"ts-morph\": \"^23.0.0\",\n \"tsup\": \"^8.2.4\",\n \"tsx\": \"^4.19.0\",\n \"typescript\": \"^5.5.4\",\n \"vitest\": \"^2.0.5\"\n },\n \"pnpm\": {\n \"onlyBuiltDependencies\": [\n \"esbuild\"\n ]\n }\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { loadConfig, saveConfig, getByPath, setByPath } from '../infra/config-store.js';\n\nexport function buildConfigCommand(): Command {\n const cmd = new Command('config').description('Manage CLI configuration');\n\n cmd\n .command('list')\n .description('Show the effective merged config')\n .action(async () => {\n const cfg = await loadConfig();\n console.log(JSON.stringify(cfg, null, 2));\n });\n\n cmd\n .command('get <key>')\n .description('Get a config value by dotted path (e.g. sounds.keystroke)')\n .action(async (key: string) => {\n const cfg = await loadConfig();\n const v = getByPath(cfg, key);\n if (v === undefined) {\n console.error(chalk.red(`Key not found: ${key}`));\n process.exitCode = 1;\n return;\n }\n console.log(typeof v === 'string' ? v : JSON.stringify(v));\n });\n\n cmd\n .command('set <key> <value>')\n .description('Set a config value by dotted path')\n .action(async (key: string, value: string) => {\n const cfg = await loadConfig();\n const next = setByPath(cfg, key, value);\n await saveConfig(next);\n console.log(chalk.green(`Set ${key} = ${value}`));\n });\n\n return cmd;\n}\n","import { z } from 'zod';\nimport { paths } from './paths.js';\nimport { readJson, writeJsonAtomic } from './fs-store.js';\n\nexport const ConfigSchema = z.object({\n mirror: z.enum(['jsdelivr', 'github']).default('jsdelivr'),\n accent: z.enum(['us', 'uk']).default('us'),\n chapterSize: z.number().int().positive().max(200).default(20),\n sounds: z\n .object({\n master: z.boolean().default(true),\n keystroke: z.boolean().default(true),\n feedback: z.boolean().default(true),\n keySoundName: z.string().default('default'),\n })\n .default({ master: true, keystroke: true, feedback: true, keySoundName: 'default' }),\n autoplayPronunciation: z.boolean().default(true),\n defaultMode: z.enum(['order', 'dictation', 'review', 'random', 'loop']).default('order'),\n defaultDict: z.string().optional(),\n language: z.enum(['auto', 'zh', 'en']).default('auto'),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n\nconst DEFAULTS: Config = ConfigSchema.parse({});\n\nexport async function loadConfig(): Promise<Config> {\n const raw = await readJson<unknown>(paths.config);\n if (!raw) return DEFAULTS;\n const result = ConfigSchema.safeParse(raw);\n if (!result.success) {\n throw new Error(`Invalid config at ${paths.config}: ${result.error.message}`);\n }\n return result.data;\n}\n\nexport async function saveConfig(cfg: Config): Promise<void> {\n await writeJsonAtomic(paths.config, cfg);\n}\n\nexport function getByPath(cfg: Config, path: string): unknown {\n const parts = path.split('.');\n let cur: unknown = cfg;\n for (const p of parts) {\n if (cur === null || typeof cur !== 'object') return undefined;\n cur = (cur as Record<string, unknown>)[p];\n }\n return cur;\n}\n\nexport function setByPath(cfg: Config, path: string, rawValue: string): Config {\n const parts = path.split('.');\n if (parts.length === 0) throw new Error('Empty config key');\n const clone: Record<string, unknown> = JSON.parse(JSON.stringify(cfg));\n let cur: Record<string, unknown> = clone;\n for (let i = 0; i < parts.length - 1; i++) {\n const k = parts[i]!;\n const next = cur[k];\n if (typeof next !== 'object' || next === null) {\n throw new Error(`Cannot set ${path}: ${parts.slice(0, i + 1).join('.')} is not an object`);\n }\n cur = next as Record<string, unknown>;\n }\n const leaf = parts[parts.length - 1]!;\n cur[leaf] = coerce(rawValue);\n const validated = ConfigSchema.safeParse(clone);\n if (!validated.success) {\n throw new Error(`Invalid value for ${path}: ${validated.error.issues[0]?.message ?? 'unknown'}`);\n }\n return validated.data;\n}\n\nfunction coerce(v: string): unknown {\n if (v === 'true') return true;\n if (v === 'false') return false;\n if (v === 'null') return null;\n if (/^-?\\d+$/.test(v)) return Number(v);\n if (/^-?\\d+\\.\\d+$/.test(v)) return Number(v);\n return v;\n}\n","import { homedir } from 'node:os';\nimport { join, resolve } from 'node:path';\nimport { mkdir } from 'node:fs/promises';\nimport { fileURLToPath } from 'node:url';\n\nconst ROOT = join(homedir(), '.qwerty-cli');\n\nexport const paths = {\n root: ROOT,\n config: join(ROOT, 'config.json'),\n registry: join(ROOT, 'registry.json'),\n dictsDir: join(ROOT, 'dicts'),\n dictFile: (id: string) => join(ROOT, 'dicts', `${id}.json`),\n dictMeta: (id: string) => join(ROOT, 'dicts', `${id}.meta.json`),\n stats: join(ROOT, 'stats.jsonl'),\n mistakes: join(ROOT, 'mistakes.json'),\n audioCacheDir: join(ROOT, 'cache', 'audio'),\n audioCache: (word: string, accent: 'us' | 'uk') =>\n join(ROOT, 'cache', 'audio', `${encodeURIComponent(word.toLowerCase())}-${accent}.mp3`),\n};\n\nexport async function ensureDirs(): Promise<void> {\n await mkdir(paths.dictsDir, { recursive: true });\n await mkdir(paths.audioCacheDir, { recursive: true });\n}\n\nexport function packageAssetsDir(): string {\n // Works for both bundled (dist/cli.js) and source (src/infra/paths.ts) layouts:\n // 2 levels up from this file lands at the package root.\n const here = fileURLToPath(import.meta.url);\n return resolve(here, '..', '..', 'assets');\n}\n","import { mkdir, readFile, rename, writeFile, appendFile, access } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { randomBytes } from 'node:crypto';\n\nexport async function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readJson<T>(path: string): Promise<T | null> {\n try {\n const buf = await readFile(path, 'utf8');\n return JSON.parse(buf) as T;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n throw err;\n }\n}\n\nexport async function writeJsonAtomic(path: string, value: unknown): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n const tmp = `${path}.${process.pid}.${randomBytes(4).toString('hex')}.tmp`;\n await writeFile(tmp, JSON.stringify(value, null, 2), 'utf8');\n await rename(tmp, path);\n}\n\nexport async function appendJsonl(path: string, line: unknown): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await appendFile(path, JSON.stringify(line) + '\\n', 'utf8');\n}\n\nexport async function readJsonl<T>(path: string): Promise<T[]> {\n try {\n const buf = await readFile(path, 'utf8');\n return buf\n .split('\\n')\n .filter((l) => l.trim().length > 0)\n .map((l) => JSON.parse(l) as T);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return [];\n throw err;\n }\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { filterRegistry, type DictionaryEntry } from '../domain/dictionary.js';\nimport { loadRegistry } from '../infra/registry-store.js';\nimport {\n pullDictionary,\n importDictionary,\n isLocallyAvailable,\n removeDictionary,\n} from '../infra/dict-downloader.js';\n\nfunction fmtBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n return `${(n / 1024 / 1024).toFixed(2)} MB`;\n}\n\nasync function renderTable(entries: DictionaryEntry[]): Promise<void> {\n const flagged = await Promise.all(\n entries.map(async (e) => ({ entry: e, local: await isLocallyAvailable(e.id) })),\n );\n const widths = {\n local: 3,\n id: Math.max(2, ...flagged.map((f) => f.entry.id.length)),\n name: Math.max(4, ...flagged.map((f) => f.entry.name.length)),\n category: Math.max(8, ...flagged.map((f) => f.entry.category.length)),\n length: Math.max(5, ...flagged.map((f) => String(f.entry.length).length)),\n };\n const pad = (s: string, n: number) => s + ' '.repeat(Math.max(0, n - visibleWidth(s)));\n const header = [\n pad(' ', widths.local),\n chalk.bold(pad('ID', widths.id)),\n chalk.bold(pad('Name', widths.name)),\n chalk.bold(pad('Category', widths.category)),\n chalk.bold(pad('Words', widths.length)),\n chalk.bold('Description'),\n ].join(' ');\n console.log(header);\n for (const { entry, local } of flagged) {\n const mark = local ? chalk.green(' ✓') : ' ';\n console.log(\n [\n pad(mark, widths.local),\n pad(entry.id, widths.id),\n pad(entry.name, widths.name),\n chalk.dim(pad(entry.category, widths.category)),\n pad(String(entry.length), widths.length),\n chalk.dim(entry.description),\n ].join(' '),\n );\n }\n}\n\n// Naive: count CJK as width-2 for alignment.\nfunction visibleWidth(s: string): number {\n let w = 0;\n // strip ansi\n const plain = s.replace(/\\x1b\\[[0-9;]*m/g, '');\n for (const ch of plain) {\n const code = ch.codePointAt(0)!;\n w += code > 0x2e80 && code < 0xfb00 ? 2 : 1;\n }\n return w;\n}\n\nexport function buildDictCommand(): Command {\n const cmd = new Command('dict').description('Manage dictionaries');\n\n cmd\n .command('list')\n .description('List dictionaries (✓ = locally available)')\n .option('-c, --category <category>', 'filter by category')\n .option('--local-only', 'show only locally downloaded dictionaries')\n .action(async (opts: { category?: string; localOnly?: boolean }) => {\n const reg = await loadRegistry();\n let entries = opts.category\n ? reg.filter((e) => e.category === opts.category)\n : reg;\n if (opts.localOnly) {\n const flags = await Promise.all(entries.map((e) => isLocallyAvailable(e.id)));\n entries = entries.filter((_, i) => flags[i]);\n }\n await renderTable(entries);\n console.log(chalk.dim(`\\n${entries.length} dictionaries`));\n });\n\n cmd\n .command('search <keyword>')\n .description('Search the upstream registry by name/description/category/tags')\n .option('-c, --category <category>', 'restrict to category')\n .option('-l, --language <language>', 'restrict to language')\n .action(async (keyword: string, opts: { category?: string; language?: string }) => {\n const reg = await loadRegistry();\n const matches = filterRegistry(reg, keyword, opts);\n if (matches.length === 0) {\n console.log(chalk.yellow(`No dictionaries matched \"${keyword}\"`));\n return;\n }\n await renderTable(matches);\n console.log(chalk.dim(`\\n${matches.length} matches`));\n });\n\n cmd\n .command('pull <id>')\n .description('Download an upstream dictionary into the local cache')\n .action(async (id: string) => {\n try {\n const { words, size } = await pullDictionary(id);\n console.log(chalk.green(`Saved ${words.length} words (${fmtBytes(size)}) → dict ${chalk.bold(id)}`));\n } catch (err) {\n console.error(chalk.red((err as Error).message));\n process.exitCode = 1;\n }\n });\n\n cmd\n .command('import <file>')\n .description('Import a local qwerty-native JSON dictionary')\n .requiredOption('--id <id>', 'dictionary id (lowercase, digits, dashes)')\n .action(async (file: string, opts: { id: string }) => {\n try {\n const { words, size } = await importDictionary(file, opts.id);\n console.log(chalk.green(`Imported ${words.length} words (${fmtBytes(size)}) as ${chalk.bold(opts.id)}`));\n } catch (err) {\n console.error(chalk.red((err as Error).message));\n process.exitCode = 1;\n }\n });\n\n cmd\n .command('rm <id>')\n .description('Remove a local dictionary')\n .action(async (id: string) => {\n const removed = await removeDictionary(id);\n if (removed) console.log(chalk.green(`Removed ${id}`));\n else console.log(chalk.yellow(`Nothing to remove for ${id}`));\n });\n\n return cmd;\n}\n","import { z } from 'zod';\n\nexport const DictionaryEntrySchema = z.object({\n id: z.string(),\n name: z.string(),\n description: z.string().default(''),\n category: z.string().default(''),\n tags: z.array(z.string()).default([]),\n url: z.string(),\n length: z.number().int().nonnegative().default(0),\n language: z.string().default('en'),\n languageCategory: z.string().default('en'),\n defaultPronIndex: z.number().int().optional(),\n});\n\nexport type DictionaryEntry = z.infer<typeof DictionaryEntrySchema>;\n\nexport const RegistrySchema = z.array(DictionaryEntrySchema);\nexport type Registry = DictionaryEntry[];\n\nexport const WordSchema = z\n .object({\n name: z.string(),\n trans: z.array(z.string()).default([]),\n usphone: z.string().optional(),\n ukphone: z.string().optional(),\n notation: z.string().optional(),\n })\n .passthrough();\n\nexport type Word = z.infer<typeof WordSchema>;\n\nexport const WordArraySchema = z.array(WordSchema);\n\nexport function filterRegistry(\n registry: Registry,\n query: string,\n opts: { category?: string; language?: string } = {},\n): Registry {\n const q = query.trim().toLowerCase();\n return registry.filter((d) => {\n if (opts.category && d.category !== opts.category) return false;\n if (opts.language && d.language !== opts.language) return false;\n if (!q) return true;\n return (\n d.id.toLowerCase().includes(q) ||\n d.name.toLowerCase().includes(q) ||\n d.description.toLowerCase().includes(q) ||\n d.category.toLowerCase().includes(q) ||\n d.tags.some((t) => t.toLowerCase().includes(q))\n );\n });\n}\n","import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { RegistrySchema, type Registry, type DictionaryEntry } from '../domain/dictionary.js';\nimport { paths, packageAssetsDir } from './paths.js';\nimport { readJson } from './fs-store.js';\n\nlet cached: Registry | null = null;\n\nexport async function loadRegistry(): Promise<Registry> {\n if (cached) return cached;\n\n const userOverride = await readJson<unknown>(paths.registry);\n if (userOverride) {\n const parsed = RegistrySchema.safeParse(userOverride);\n if (parsed.success) {\n cached = parsed.data;\n return cached;\n }\n console.warn(`Ignoring corrupt user registry at ${paths.registry}: ${parsed.error.message}`);\n }\n\n const bundled = await readFile(join(packageAssetsDir(), 'registry.snapshot.json'), 'utf8');\n const parsed = RegistrySchema.parse(JSON.parse(bundled));\n cached = parsed;\n return cached;\n}\n\nexport async function findEntry(id: string): Promise<DictionaryEntry | undefined> {\n const reg = await loadRegistry();\n return reg.find((d) => d.id === id);\n}\n","import { createHash } from 'node:crypto';\nimport { stat, copyFile } from 'node:fs/promises';\nimport { request } from 'undici';\nimport { WordArraySchema, type Word, type DictionaryEntry } from '../domain/dictionary.js';\nimport { paths, ensureDirs } from './paths.js';\nimport { exists, readJson, writeJsonAtomic } from './fs-store.js';\nimport { findEntry } from './registry-store.js';\nimport { loadConfig } from './config-store.js';\n\nconst JSDELIVR_BASE = 'https://cdn.jsdelivr.net/gh/RealKai42/qwerty-learner@master';\nconst GITHUB_RAW_BASE = 'https://raw.githubusercontent.com/RealKai42/qwerty-learner/master';\n\ntype Meta = { sha256: string; size: number; fetchedAt: string; id: string };\n\nasync function fetchWithRetry(url: string, retries = 2): Promise<string> {\n let lastErr: unknown;\n for (let i = 0; i <= retries; i++) {\n try {\n const res = await request(url, { headersTimeout: 10000, bodyTimeout: 30000 });\n if (res.statusCode >= 400) throw new Error(`HTTP ${res.statusCode}`);\n return await res.body.text();\n } catch (err) {\n lastErr = err;\n if (i < retries) await new Promise((r) => setTimeout(r, 500 * (i + 1)));\n }\n }\n throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));\n}\n\nfunction buildUrls(mirror: 'jsdelivr' | 'github', relUrl: string): string[] {\n // Registry urls are web-relative (\"/dicts/X.json\"); upstream repo serves them\n // from /public/, so prepend that prefix when hitting source mirrors.\n const path = relUrl.startsWith('/') ? relUrl : `/${relUrl}`;\n const repoPath = `/public${path}`;\n const jsd = `${JSDELIVR_BASE}${repoPath}`;\n const gh = `${GITHUB_RAW_BASE}${repoPath}`;\n return mirror === 'jsdelivr' ? [jsd, gh] : [gh, jsd];\n}\n\nexport async function pullDictionary(id: string): Promise<{ words: Word[]; size: number }> {\n const entry = await findEntry(id);\n if (!entry) throw new Error(`Unknown dictionary id: ${id}`);\n const cfg = await loadConfig();\n await ensureDirs();\n\n const urls = buildUrls(cfg.mirror, entry.url);\n let body: string | null = null;\n let lastErr: unknown;\n for (const u of urls) {\n try {\n body = await fetchWithRetry(u);\n break;\n } catch (err) {\n lastErr = err;\n }\n }\n if (!body) {\n throw new Error(\n `Failed to download dictionary ${id} from any mirror: ${lastErr instanceof Error ? lastErr.message : lastErr}`,\n );\n }\n\n let json: unknown;\n try {\n json = JSON.parse(body);\n } catch (err) {\n throw new Error(`Dictionary ${id} is not valid JSON: ${(err as Error).message}`);\n }\n\n const parsed = WordArraySchema.safeParse(json);\n if (!parsed.success) {\n throw new Error(`Dictionary ${id} failed schema validation: ${parsed.error.issues[0]?.message}`);\n }\n\n const sha = createHash('sha256').update(body).digest('hex');\n await writeJsonAtomic(paths.dictFile(id), parsed.data);\n const meta: Meta = { sha256: sha, size: body.length, fetchedAt: new Date().toISOString(), id };\n await writeJsonAtomic(paths.dictMeta(id), meta);\n return { words: parsed.data, size: body.length };\n}\n\nexport async function importDictionary(file: string, id: string): Promise<{ words: Word[]; size: number }> {\n if (!/^[a-z0-9-]+$/.test(id)) {\n throw new Error(`Invalid id \"${id}\". Must match /^[a-z0-9-]+$/`);\n }\n await ensureDirs();\n if (!(await exists(file))) throw new Error(`File not found: ${file}`);\n\n const raw = await readJson<unknown>(file);\n const parsed = WordArraySchema.safeParse(raw);\n if (!parsed.success) {\n throw new Error(`Import rejected: ${parsed.error.issues[0]?.message}`);\n }\n await copyFile(file, paths.dictFile(id));\n const size = (await stat(paths.dictFile(id))).size;\n const sha = createHash('sha256').update(JSON.stringify(parsed.data)).digest('hex');\n const meta: Meta = { sha256: sha, size, fetchedAt: new Date().toISOString(), id };\n await writeJsonAtomic(paths.dictMeta(id), meta);\n return { words: parsed.data, size };\n}\n\nexport async function loadLocalDictionary(id: string): Promise<Word[] | null> {\n const data = await readJson<unknown>(paths.dictFile(id));\n if (!data) return null;\n const parsed = WordArraySchema.safeParse(data);\n if (!parsed.success) throw new Error(`Local dictionary ${id} corrupt: ${parsed.error.message}`);\n return parsed.data;\n}\n\nexport async function isLocallyAvailable(id: string): Promise<boolean> {\n return exists(paths.dictFile(id));\n}\n\nexport async function ensureDictionary(id: string): Promise<Word[]> {\n const local = await loadLocalDictionary(id);\n if (local) return local;\n const { words } = await pullDictionary(id);\n return words;\n}\n\nexport async function removeDictionary(id: string): Promise<boolean> {\n const { unlink } = await import('node:fs/promises');\n let removed = false;\n for (const p of [paths.dictFile(id), paths.dictMeta(id)]) {\n try {\n await unlink(p);\n removed = true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n }\n return removed;\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { render } from 'ink';\nimport { createElement } from 'react';\nimport { loadConfig } from '../infra/config-store.js';\nimport { App } from '../ui/App.js';\nimport { start as startSession, report as sessionReport } from '../infra/session-tracker.js';\nimport { printSessionReport, ensureMainScreen } from '../util/report.js';\nimport { pickStrings } from '../i18n/context.js';\nimport type { Mode } from '../domain/chapters.js';\n\nconst MODES: Mode[] = ['order', 'dictation', 'review', 'random', 'loop'];\n\nfunction isMode(v: string): v is Mode {\n return (MODES as string[]).includes(v);\n}\n\nexport async function runPractice(\n dictIdArg: string | undefined,\n options: { chapter?: string | number; mode?: string },\n): Promise<void> {\n if (!process.stdout.isTTY) {\n console.error(chalk.red('Practice requires an interactive TTY.'));\n process.exitCode = 1;\n return;\n }\n const cfg = await loadConfig();\n const dictId = dictIdArg ?? cfg.defaultDict;\n if (!dictId) {\n console.error(chalk.red('No dictionary specified. Pass an id or set config.defaultDict.'));\n process.exitCode = 1;\n return;\n }\n const mode = options.mode ?? cfg.defaultMode;\n if (!isMode(mode)) {\n console.error(chalk.red(`Invalid mode \"${mode}\". Valid: ${MODES.join(', ')}`));\n process.exitCode = 1;\n return;\n }\n const chapterIndex = Math.max(0, Number(options.chapter ?? 1) - 1);\n\n startSession();\n const { waitUntilExit } = render(\n createElement(App, {\n initial: { name: 'practice', params: { dictId, chapterIndex, mode } },\n initialCfg: cfg,\n }),\n { patchConsole: false, exitOnCtrlC: false },\n );\n await waitUntilExit();\n ensureMainScreen();\n const { lang, t } = pickStrings(cfg.language);\n printSessionReport(sessionReport(), t, lang);\n}\n\nexport function buildPracticeCommand(): Command {\n return new Command('practice')\n .argument('[dictId]', 'dictionary id; falls back to config.defaultDict')\n .description('Start a typing practice session')\n .option('-c, --chapter <n>', 'chapter number (1-based)', '1')\n .option('-m, --mode <mode>', 'order | dictation | review | random | loop')\n .action(async (dictIdArg: string | undefined, options: { chapter: string; mode?: string }) => {\n await runPractice(dictIdArg, options);\n });\n}\n","import { useRef, type ReactNode } from 'react';\nimport { useApp, useInput } from 'ink';\nimport { NavProvider, useNav, type ScreenFrame } from './nav.js';\nimport { Fullscreen } from './Fullscreen.js';\nimport { AudioStatusProvider } from './audio-context.js';\nimport { AppStateProvider, useAppState } from './app-state.js';\nimport { StringsProvider } from '../i18n/context.js';\nimport { MainMenu } from './screens/MainMenu.js';\nimport { PracticeScreen } from './screens/PracticeScreen.js';\nimport { DictBrowser } from './screens/DictBrowser.js';\nimport { ConfigEditor } from './screens/ConfigEditor.js';\nimport { StatsViewer } from './screens/StatsViewer.js';\nimport { WordLookup } from './screens/WordLookup.js';\nimport type { Config } from '../infra/config-store.js';\n\nexport function App({ initial, initialCfg }: { initial: ScreenFrame; initialCfg: Config }) {\n return (\n <AppStateProvider initialCfg={initialCfg}>\n <LangBridge>\n <AudioStatusProvider disabled={!initialCfg.sounds.master}>\n <NavProvider initial={initial}>\n <Fullscreen>\n <Router />\n </Fullscreen>\n </NavProvider>\n </AudioStatusProvider>\n </LangBridge>\n </AppStateProvider>\n );\n}\n\nfunction LangBridge({ children }: { children: ReactNode }) {\n const { cfg } = useAppState();\n return <StringsProvider pref={cfg.language}>{children}</StringsProvider>;\n}\n\nfunction screenKey(frame: ScreenFrame): string {\n if (frame.name === 'practice') {\n const p = frame.params;\n return `practice:${p.dictId}:${p.chapterIndex}:${p.mode}`;\n }\n return frame.name;\n}\n\nfunction Router() {\n const nav = useNav();\n const { cfg } = useAppState();\n const { exit } = useApp();\n const lastKeyRef = useRef<string | null>(null);\n\n useInput((input, key) => {\n if (key.ctrl && input === 'c') exit();\n });\n\n const frame = nav.current;\n const key = screenKey(frame);\n if (lastKeyRef.current !== key) {\n if (process.stdout.isTTY) process.stdout.write('\\x1b[2J\\x1b[H');\n lastKeyRef.current = key;\n }\n\n switch (frame.name) {\n case 'main':\n return <MainMenu cfg={cfg} />;\n case 'practice':\n return <PracticeScreen params={frame.params} />;\n case 'dict':\n return <DictBrowser params={frame.params} />;\n case 'config':\n return <ConfigEditor />;\n case 'stats':\n return <StatsViewer />;\n case 'word':\n return <WordLookup />;\n }\n}\n","import { createContext, useContext, useState, useCallback, type ReactNode } from 'react';\n\nexport type ScreenName =\n | 'main'\n | 'practice'\n | 'dict'\n | 'config'\n | 'stats'\n | 'word';\n\nexport type PracticeParams = {\n dictId: string;\n chapterIndex: number;\n mode: 'order' | 'dictation' | 'review' | 'random' | 'loop';\n};\n\nexport type DictParams = {\n pickerMode?: 'set-default' | 'choose-then-practice';\n};\n\nexport type ScreenFrame =\n | { name: 'main' }\n | { name: 'practice'; params: PracticeParams }\n | { name: 'dict'; params?: DictParams }\n | { name: 'config' }\n | { name: 'stats' }\n | { name: 'word' };\n\ntype NavContextValue = {\n current: ScreenFrame;\n stack: ScreenFrame[];\n navigate: (frame: ScreenFrame) => void;\n replace: (frame: ScreenFrame) => void;\n back: () => void;\n reset: (frame: ScreenFrame) => void;\n};\n\nconst NavContext = createContext<NavContextValue | null>(null);\n\nexport function NavProvider({ initial, children }: { initial: ScreenFrame; children: ReactNode }) {\n const [stack, setStack] = useState<ScreenFrame[]>([initial]);\n\n const navigate = useCallback((frame: ScreenFrame) => {\n setStack((s) => [...s, frame]);\n }, []);\n const replace = useCallback((frame: ScreenFrame) => {\n setStack((s) => (s.length === 0 ? [frame] : [...s.slice(0, -1), frame]));\n }, []);\n const back = useCallback(() => {\n setStack((s) => (s.length > 1 ? s.slice(0, -1) : s));\n }, []);\n const reset = useCallback((frame: ScreenFrame) => {\n setStack([frame]);\n }, []);\n\n const current = stack[stack.length - 1]!;\n return (\n <NavContext.Provider value={{ current, stack, navigate, replace, back, reset }}>\n {children}\n </NavContext.Provider>\n );\n}\n\nexport function useNav(): NavContextValue {\n const ctx = useContext(NavContext);\n if (!ctx) throw new Error('useNav must be used inside NavProvider');\n return ctx;\n}\n","import { useEffect, useState, type ReactNode } from 'react';\nimport { Box, useStdout } from 'ink';\n\nconst ENTER = '\\x1b[?1049h\\x1b[?25l\\x1b[2J\\x1b[H';\n// LEAVE intentionally does NOT clear (\\x1b[2J\\x1b[H) — DECRSET 1049 already\n// restores the pre-program main screen, and a clear here would wipe the\n// session report that's printed right after waitUntilExit().\nconst LEAVE = '\\x1b[?25h\\x1b[?1049l';\n\nfunction shouldUse(): boolean {\n return Boolean(process.stdout.isTTY) && process.env.QWERTY_NO_ALTSCREEN !== '1';\n}\n\nexport function Fullscreen({ children }: { children: ReactNode }) {\n const { stdout } = useStdout();\n const [size, setSize] = useState(() => ({\n rows: stdout?.rows ?? 24,\n cols: stdout?.columns ?? 80,\n }));\n\n useEffect(() => {\n if (!shouldUse()) return;\n process.stdout.write(ENTER);\n\n const onResize = () => {\n setSize({ rows: process.stdout.rows ?? 24, cols: process.stdout.columns ?? 80 });\n };\n process.stdout.on('resize', onResize);\n\n const leave = () => {\n try {\n process.stdout.write(LEAVE);\n } catch {\n // stream may already be closed\n }\n };\n\n const onSignal = () => {\n leave();\n process.exit(130);\n };\n\n process.once('SIGINT', onSignal);\n process.once('SIGTERM', onSignal);\n process.once('exit', leave);\n\n return () => {\n process.off('SIGINT', onSignal);\n process.off('SIGTERM', onSignal);\n process.off('exit', leave);\n process.stdout.off('resize', onResize);\n leave();\n };\n }, []);\n\n return (\n <Box width={size.cols} height={size.rows} flexDirection=\"column\">\n {children}\n </Box>\n );\n}\n","import { createContext, useContext, useEffect, useState, type ReactNode } from 'react';\nimport { initAudio, audioWarning } from '../infra/audio.js';\n\ntype AudioStatus = { warning: string | null; ready: boolean };\n\nconst AudioStatusContext = createContext<AudioStatus>({ warning: null, ready: false });\n\nexport function AudioStatusProvider({\n disabled,\n children,\n}: {\n disabled: boolean;\n children: ReactNode;\n}) {\n const [status, setStatus] = useState<AudioStatus>({ warning: null, ready: false });\n\n useEffect(() => {\n let cancelled = false;\n initAudio(disabled)\n .then(() => {\n if (cancelled) return;\n setStatus({ warning: audioWarning(), ready: true });\n })\n .catch(() => {\n if (cancelled) return;\n setStatus({ warning: null, ready: true });\n });\n return () => {\n cancelled = true;\n };\n }, [disabled]);\n\n return <AudioStatusContext.Provider value={status}>{children}</AudioStatusContext.Provider>;\n}\n\nexport function useAudioStatus(): AudioStatus {\n return useContext(AudioStatusContext);\n}\n","import { spawn } from 'node:child_process';\nimport { access, mkdir, rename, writeFile } from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { request } from 'undici';\nimport PQueue from 'p-queue';\nimport { paths, packageAssetsDir, ensureDirs } from './paths.js';\nimport { exists } from './fs-store.js';\n\ntype PlayerKind = 'afplay' | 'paplay' | 'aplay' | 'mpg123' | 'ffplay' | 'powershell';\n\ntype Player = {\n kind: PlayerKind;\n cmd: string;\n args: (file: string) => string[];\n supports: 'wav' | 'mp3' | 'both';\n};\n\nconst CANDIDATES: Player[] = [\n { kind: 'afplay', cmd: 'afplay', args: (f) => [f], supports: 'both' },\n { kind: 'ffplay', cmd: 'ffplay', args: (f) => ['-nodisp', '-autoexit', '-loglevel', 'quiet', f], supports: 'both' },\n { kind: 'mpg123', cmd: 'mpg123', args: (f) => ['-q', f], supports: 'mp3' },\n { kind: 'paplay', cmd: 'paplay', args: (f) => [f], supports: 'wav' },\n { kind: 'aplay', cmd: 'aplay', args: (f) => ['-q', f], supports: 'wav' },\n {\n kind: 'powershell',\n cmd: 'powershell',\n args: (f) => ['-NoProfile', '-Command', `(New-Object Media.SoundPlayer '${f}').PlaySync();`],\n supports: 'wav',\n },\n];\n\nconst PRON_API = 'https://dict.youdao.com/dictvoice?audio=';\n\ntype AudioRuntime = {\n disabled: boolean;\n wavPlayer: Player | null;\n mp3Player: Player | null;\n warning: string | null;\n keyQueue: PQueue;\n feedbackQueue: PQueue;\n pronQueue: PQueue;\n};\n\nlet runtime: AudioRuntime | null = null;\n\nasync function isExecutable(cmd: string): Promise<boolean> {\n return new Promise((resolve) => {\n const probe = spawn(cmd, ['--version'], { stdio: 'ignore' });\n probe.on('error', () => resolve(false));\n probe.on('exit', () => resolve(true));\n setTimeout(() => {\n probe.kill();\n resolve(false);\n }, 500);\n });\n}\n\nasync function detect(): Promise<{ wav: Player | null; mp3: Player | null }> {\n let wav: Player | null = null;\n let mp3: Player | null = null;\n for (const p of CANDIDATES) {\n if (!(await isExecutable(p.cmd))) continue;\n if (!wav && (p.supports === 'wav' || p.supports === 'both')) wav = p;\n if (!mp3 && (p.supports === 'mp3' || p.supports === 'both')) mp3 = p;\n if (wav && mp3) break;\n }\n return { wav, mp3 };\n}\n\nexport async function initAudio(disabledByConfig: boolean): Promise<AudioRuntime> {\n if (runtime) return runtime;\n if (disabledByConfig) {\n runtime = {\n disabled: true,\n wavPlayer: null,\n mp3Player: null,\n warning: null,\n keyQueue: new PQueue({ concurrency: 1 }),\n feedbackQueue: new PQueue({ concurrency: 1 }),\n pronQueue: new PQueue({ concurrency: 1 }),\n };\n return runtime;\n }\n const { wav, mp3 } = await detect();\n let warning: string | null = null;\n if (!wav && !mp3) {\n warning = 'No audio player found on PATH (looked for afplay/ffplay/mpg123/paplay/aplay/powershell). Sounds disabled.';\n } else if (!mp3) {\n warning = 'No MP3 player found; word pronunciations will be skipped.';\n }\n runtime = {\n disabled: !wav && !mp3,\n wavPlayer: wav,\n mp3Player: mp3,\n warning,\n keyQueue: new PQueue({ concurrency: 2 }),\n feedbackQueue: new PQueue({ concurrency: 1 }),\n pronQueue: new PQueue({ concurrency: 1 }),\n };\n return runtime;\n}\n\nfunction spawnPlay(player: Player, file: string): void {\n try {\n const child = spawn(player.cmd, player.args(file), {\n detached: true,\n stdio: 'ignore',\n });\n child.on('error', () => {\n // swallow; runtime will be disabled if many failures stack up\n });\n child.unref();\n } catch {\n /* fail-soft */\n }\n}\n\nfunction playFile(file: string, kind: 'wav' | 'mp3'): void {\n if (!runtime || runtime.disabled) return;\n const player = kind === 'wav' ? runtime.wavPlayer : runtime.mp3Player;\n if (!player) return;\n spawnPlay(player, file);\n}\n\nexport function playKeystroke(): void {\n if (!runtime || runtime.disabled) return;\n // Drop if queue is saturated; we never want to delay typing.\n if (runtime.keyQueue.size >= 2) return;\n void runtime.keyQueue.add(async () => {\n playFile(join(packageAssetsDir(), 'sounds', 'key-default.wav'), 'wav');\n await new Promise((r) => setTimeout(r, 30));\n });\n}\n\nexport function playCorrect(): void {\n if (!runtime || runtime.disabled) return;\n void runtime.feedbackQueue.add(async () => {\n playFile(join(packageAssetsDir(), 'sounds', 'correct.wav'), 'wav');\n await new Promise((r) => setTimeout(r, 50));\n });\n}\n\nexport function playWrong(): void {\n if (!runtime || runtime.disabled) return;\n void runtime.feedbackQueue.add(async () => {\n playFile(join(packageAssetsDir(), 'sounds', 'wrong.wav'), 'wav');\n await new Promise((r) => setTimeout(r, 50));\n });\n}\n\nasync function downloadPronunciation(word: string, accent: 'us' | 'uk'): Promise<string | null> {\n const cacheFile = paths.audioCache(word, accent);\n if (await exists(cacheFile)) return cacheFile;\n await mkdir(dirname(cacheFile), { recursive: true });\n const type = accent === 'us' ? 2 : 1;\n const url = `${PRON_API}${encodeURIComponent(word)}&type=${type}`;\n try {\n const res = await request(url, { headersTimeout: 8000, bodyTimeout: 20000 });\n if (res.statusCode >= 400) return null;\n const buf = Buffer.from(await res.body.arrayBuffer());\n if (buf.length < 1024) return null;\n const tmp = `${cacheFile}.tmp`;\n await writeFile(tmp, buf);\n await rename(tmp, cacheFile);\n return cacheFile;\n } catch {\n return null;\n }\n}\n\nexport async function playPronunciation(word: string, accent: 'us' | 'uk'): Promise<void> {\n if (!runtime || runtime.disabled || !runtime.mp3Player) return;\n await ensureDirs();\n await runtime.pronQueue.add(async () => {\n const file = await downloadPronunciation(word, accent);\n if (file) playFile(file, 'mp3');\n });\n}\n\nexport async function prefetchPronunciation(word: string, accent: 'us' | 'uk'): Promise<void> {\n if (!runtime || runtime.disabled || !runtime.mp3Player) return;\n await ensureDirs();\n void runtime.pronQueue.add(async () => {\n await downloadPronunciation(word, accent);\n });\n}\n\nexport function audioWarning(): string | null {\n return runtime?.warning ?? null;\n}\n\nexport function audioDisabled(): boolean {\n return runtime?.disabled ?? true;\n}\n","import { createContext, useCallback, useContext, useState, type ReactNode } from 'react';\nimport { saveConfig as persistConfig, type Config } from '../infra/config-store.js';\n\ntype AppState = {\n cfg: Config;\n setCfg: (next: Config) => Promise<void>;\n};\n\nconst AppStateContext = createContext<AppState | null>(null);\n\nexport function AppStateProvider({\n initialCfg,\n children,\n}: {\n initialCfg: Config;\n children: ReactNode;\n}) {\n const [cfg, setCfgState] = useState<Config>(initialCfg);\n const setCfg = useCallback(async (next: Config) => {\n setCfgState(next);\n await persistConfig(next);\n }, []);\n return <AppStateContext.Provider value={{ cfg, setCfg }}>{children}</AppStateContext.Provider>;\n}\n\nexport function useAppState(): AppState {\n const ctx = useContext(AppStateContext);\n if (!ctx) throw new Error('useAppState must be used inside AppStateProvider');\n return ctx;\n}\n","import { createContext, useContext, useMemo, type ReactNode } from 'react';\nimport { en, zh, type Strings } from './strings.js';\nimport { detectLocale, type Lang, type LangPref } from './locale.js';\n\nconst StringsContext = createContext<{ lang: Lang; t: Strings } | null>(null);\n\nexport function StringsProvider({\n pref,\n children,\n}: {\n pref: LangPref;\n children: ReactNode;\n}) {\n const value = useMemo(() => {\n const lang = detectLocale(pref);\n return { lang, t: lang === 'zh' ? zh : en };\n }, [pref]);\n return <StringsContext.Provider value={value}>{children}</StringsContext.Provider>;\n}\n\nexport function useStrings(): Strings {\n const ctx = useContext(StringsContext);\n if (!ctx) throw new Error('useStrings must be used inside StringsProvider');\n return ctx.t;\n}\n\nexport function useLang(): Lang {\n const ctx = useContext(StringsContext);\n if (!ctx) throw new Error('useLang must be used inside StringsProvider');\n return ctx.lang;\n}\n\nexport function pickStrings(pref: LangPref): { lang: Lang; t: Strings } {\n const lang = detectLocale(pref);\n return { lang, t: lang === 'zh' ? zh : en };\n}\n","// Centralized string table for the qwerty-cli TUI.\n//\n// Print-only subcommands (qwerty config list, qwerty dict list, etc.) keep\n// English output regardless of locale so shell scripts stay predictable.\n// Only the interactive TUI is localized via this table.\n\nexport type Strings = {\n app: {\n title: string;\n subtitle: string;\n };\n common: {\n back: string;\n quit: string;\n on: string;\n off: string;\n };\n mainMenu: {\n items: {\n practiceLabel: string;\n practiceHintWith: (id: string) => string;\n practiceHintNone: string;\n dictLabel: string;\n dictHint: string;\n wordLabel: string;\n wordHint: string;\n statsLabel: string;\n statsHint: string;\n configLabel: string;\n configHint: string;\n quitLabel: string;\n quitHint: string;\n };\n defaultDict: (id: string) => string;\n noDefault: string;\n hint: string;\n };\n dict: {\n title: string;\n loading: string;\n entries: (n: number) => string;\n filterPrompt: (q: string) => string;\n local: string;\n notLocal: string;\n defaultMark: string;\n tagsLabel: (tags: string) => string;\n wordsLabel: (n: number) => string;\n pulling: (id: string) => string;\n removing: (id: string) => string;\n errorOn: (id: string, msg: string) => string;\n footer: string;\n };\n config: {\n title: string;\n fields: {\n defaultDict: string;\n defaultMode: string;\n accent: string;\n mirror: string;\n chapterSize: string;\n autoplayPronunciation: string;\n soundsMaster: string;\n soundsKeystroke: string;\n soundsFeedback: string;\n soundsKeySound: string;\n language: string;\n };\n hints: {\n editing: string;\n bool: string;\n enum: string;\n dictRef: string;\n stringOrInt: string;\n };\n };\n stats: {\n title: string;\n loading: string;\n none: string;\n nonePractice: string;\n lifetime: string;\n sessions: string;\n words: string;\n errors: string;\n wpm: string;\n accuracy: string;\n streak: string;\n last: (n: number) => string;\n cycleWindow: string;\n recent: string;\n topMistakes: string;\n footer: string;\n };\n word: {\n title: string;\n indexing: string;\n none: string;\n pullFirst: string;\n countAcross: (n: number) => string;\n noMatches: (q: string) => string;\n inDict: (id: string) => string;\n mistakes: (n: number, date: string) => string;\n footer: string;\n };\n practice: {\n loading: string;\n paused: string;\n chapterComplete: string;\n chapterLabel: (c: number, t: number) => string;\n reviewLabel: string;\n statusBar: {\n mode: string;\n accent: string;\n };\n modes: {\n order: string;\n dictation: string;\n review: string;\n random: string;\n loop: string;\n };\n accents: {\n us: string;\n uk: string;\n };\n statCards: {\n words: string;\n errors: string;\n wpm: string;\n accuracy: string;\n elapsed: (t: string) => string;\n };\n footers: {\n typing: string;\n paused: string;\n summary: string;\n };\n errors: {\n noMistakes: string;\n dictEmpty: (id: string) => string;\n unknown: string;\n };\n };\n audio: {\n noPlayer: string;\n };\n report: {\n title: string;\n duration: string;\n practiced: string;\n chapters: string;\n words: string;\n accuracy: string;\n wpm: string;\n newMistakes: string;\n farewell: string;\n };\n};\n\nexport const en: Strings = {\n app: {\n title: 'qwerty',\n subtitle: 'typing practice for the terminal',\n },\n common: {\n back: 'back',\n quit: 'quit',\n on: 'on',\n off: 'off',\n },\n mainMenu: {\n items: {\n practiceLabel: 'Practice',\n practiceHintWith: (id) => `start ${id}`,\n practiceHintNone: 'pick a dictionary',\n dictLabel: 'Dictionaries',\n dictHint: 'browse, pull, set default',\n wordLabel: 'Word lookup',\n wordHint: 'search local dicts',\n statsLabel: 'Stats',\n statsHint: 'history & trends',\n configLabel: 'Config',\n configHint: 'edit preferences',\n quitLabel: 'Quit',\n quitHint: 'Ctrl+C also exits',\n },\n defaultDict: (id) => `default dict: ${id}`,\n noDefault: 'default dict: (none — pick one in Dictionaries)',\n hint: '↑/↓ navigate · Enter select · letters jump',\n },\n dict: {\n title: 'Dictionaries',\n loading: 'loading dictionaries…',\n entries: (n) => `${n} entries`,\n filterPrompt: (q) => `/ ${q}`,\n local: 'local ✓',\n notLocal: 'not local',\n defaultMark: 'default ★',\n tagsLabel: (tags) => `tags: ${tags}`,\n wordsLabel: (n) => `${n} words`,\n pulling: (id) => `pulling ${id}…`,\n removing: (id) => `removing ${id}…`,\n errorOn: (id, msg) => `error on ${id}: ${msg}`,\n footer: '↑/↓ select · Enter set default · p practice · u pull · r remove · / filter · Esc back',\n },\n config: {\n title: 'Config',\n fields: {\n defaultDict: 'default dict',\n defaultMode: 'default mode',\n accent: 'accent',\n mirror: 'mirror',\n chapterSize: 'chapter size',\n autoplayPronunciation: 'autoplay pronunciation',\n soundsMaster: 'sounds master',\n soundsKeystroke: 'sounds keystroke',\n soundsFeedback: 'sounds feedback',\n soundsKeySound: 'sounds key sound',\n language: 'language',\n },\n hints: {\n editing: 'type to edit · Enter save · Esc cancel',\n bool: 'space toggle · ↑/↓ move · Esc back',\n enum: '←/→ cycle · ↑/↓ move · Esc back',\n dictRef: 'Enter pick dict · ↑/↓ move · Esc back',\n stringOrInt: 'Enter edit · ↑/↓ move · Esc back',\n },\n },\n stats: {\n title: 'Stats',\n loading: 'loading stats…',\n none: 'No practice history yet.',\n nonePractice: 'Run a practice session first.',\n lifetime: 'lifetime',\n sessions: 'sessions',\n words: 'words',\n errors: 'errors',\n wpm: 'wpm',\n accuracy: 'accuracy',\n streak: 'streak',\n last: (n) => `last ${n} days (n / N to cycle window)`,\n cycleWindow: 'n / N cycle window · q back',\n recent: 'recent sessions',\n topMistakes: 'top mistakes',\n footer: 'n / N cycle window · q back',\n },\n word: {\n title: 'Word lookup',\n indexing: 'indexing local dictionaries…',\n none: 'No local dictionaries.',\n pullFirst: 'Pull one in Dictionaries first.',\n countAcross: (n) => `${n} words across local dicts`,\n noMatches: (q) => `no matches for \"${q}\"`,\n inDict: (id) => `in: ${id}`,\n mistakes: (n, date) => `mistakes: ${n} (last ${date})`,\n footer: 'type to filter · ↑/↓ select · Esc back',\n },\n practice: {\n loading: 'loading…',\n paused: 'PAUSED',\n chapterComplete: 'CHAPTER COMPLETE',\n chapterLabel: (c, t) => `chapter ${c}/${t}`,\n reviewLabel: 'review',\n statusBar: {\n mode: 'mode',\n accent: 'accent',\n },\n modes: {\n order: 'order',\n dictation: 'dictation',\n review: 'review',\n random: 'random',\n loop: 'loop',\n },\n accents: {\n us: 'us',\n uk: 'uk',\n },\n statCards: {\n words: 'words',\n errors: 'errors',\n wpm: 'wpm',\n accuracy: 'accuracy',\n elapsed: (t) => `elapsed ${t}`,\n },\n footers: {\n typing: 'Ctrl+N skip · Esc pause · Tab replay · Ctrl+C quit',\n paused: '[r] resume · [q] quit to menu',\n summary: '[n] next chapter · [m] review mistakes · [q] back to menu',\n },\n errors: {\n noMistakes: 'No mistakes to review yet. Practice some chapters first.',\n dictEmpty: (id) => `Dictionary ${id} is empty.`,\n unknown: 'Unknown error',\n },\n },\n audio: {\n noPlayer: '! No audio player found on PATH (looked for afplay/ffplay/mpg123/paplay/aplay/powershell). Sounds disabled.',\n },\n report: {\n title: 'Session summary',\n duration: 'duration',\n practiced: 'practiced',\n chapters: 'chapters',\n words: 'words',\n accuracy: 'accuracy',\n wpm: 'wpm',\n newMistakes: 'new mistakes',\n farewell: 'see you next time.',\n },\n};\n\nexport const zh: Strings = {\n app: {\n title: 'qwerty',\n subtitle: '终端键盘练习',\n },\n common: {\n back: '返回',\n quit: '退出',\n on: '开',\n off: '关',\n },\n mainMenu: {\n items: {\n practiceLabel: '练习',\n practiceHintWith: (id) => `开始 ${id}`,\n practiceHintNone: '请先选词典',\n dictLabel: '词典',\n dictHint: '浏览、下载、设为默认',\n wordLabel: '查词',\n wordHint: '在本地词典中搜索',\n statsLabel: '统计',\n statsHint: '历史与趋势',\n configLabel: '设置',\n configHint: '修改偏好',\n quitLabel: '退出',\n quitHint: 'Ctrl+C 亦可退出',\n },\n defaultDict: (id) => `默认词典:${id}`,\n noDefault: '默认词典:(未设置 — 在「词典」中选择)',\n hint: '↑/↓ 移动 · Enter 确认 · 字母直达',\n },\n dict: {\n title: '词典',\n loading: '加载词典中…',\n entries: (n) => `${n} 部词典`,\n filterPrompt: (q) => `/ ${q}`,\n local: '已下载 ✓',\n notLocal: '未下载',\n defaultMark: '默认 ★',\n tagsLabel: (tags) => `标签:${tags}`,\n wordsLabel: (n) => `${n} 词`,\n pulling: (id) => `拉取 ${id} 中…`,\n removing: (id) => `删除 ${id} 中…`,\n errorOn: (id, msg) => `${id} 出错:${msg}`,\n footer: '↑/↓ 选择 · Enter 设为默认 · p 开始练习 · u 拉取 · r 删除 · / 过滤 · Esc 返回',\n },\n config: {\n title: '设置',\n fields: {\n defaultDict: '默认词典',\n defaultMode: '默认模式',\n accent: '发音',\n mirror: '镜像源',\n chapterSize: '章节单词数',\n autoplayPronunciation: '自动播放发音',\n soundsMaster: '音效总开关',\n soundsKeystroke: '按键音',\n soundsFeedback: '反馈音',\n soundsKeySound: '按键音色',\n language: '语言',\n },\n hints: {\n editing: '输入修改 · Enter 保存 · Esc 取消',\n bool: '空格切换 · ↑/↓ 移动 · Esc 返回',\n enum: '←/→ 切换 · ↑/↓ 移动 · Esc 返回',\n dictRef: 'Enter 选词典 · ↑/↓ 移动 · Esc 返回',\n stringOrInt: 'Enter 编辑 · ↑/↓ 移动 · Esc 返回',\n },\n },\n stats: {\n title: '统计',\n loading: '加载统计中…',\n none: '还没有练习记录。',\n nonePractice: '先来一次练习吧。',\n lifetime: '累计',\n sessions: '会话',\n words: '词数',\n errors: '错误',\n wpm: '速度',\n accuracy: '准确率',\n streak: '连续天数',\n last: (n) => `最近 ${n} 天 (n / N 切换窗口)`,\n cycleWindow: 'n / N 切换窗口 · q 返回',\n recent: '最近会话',\n topMistakes: '高频错词',\n footer: 'n / N 切换窗口 · q 返回',\n },\n word: {\n title: '查词',\n indexing: '索引本地词典中…',\n none: '没有本地词典。',\n pullFirst: '先在「词典」中拉取一部。',\n countAcross: (n) => `本地词典共 ${n} 词`,\n noMatches: (q) => `没有匹配「${q}」的词`,\n inDict: (id) => `来源:${id}`,\n mistakes: (n, date) => `错过 ${n} 次 (最近 ${date})`,\n footer: '输入过滤 · ↑/↓ 选择 · Esc 返回',\n },\n practice: {\n loading: '加载中…',\n paused: '已暂停',\n chapterComplete: '本章完成',\n chapterLabel: (c, t) => `第 ${c}/${t} 章`,\n reviewLabel: '复习',\n statusBar: {\n mode: '模式',\n accent: '发音',\n },\n modes: {\n order: '顺序',\n dictation: '默写',\n review: '复习',\n random: '乱序',\n loop: '循环',\n },\n accents: {\n us: '美',\n uk: '英',\n },\n statCards: {\n words: '词数',\n errors: '错误',\n wpm: '速度',\n accuracy: '准确率',\n elapsed: (t) => `耗时 ${t}`,\n },\n footers: {\n typing: 'Ctrl+N 跳过 · Esc 暂停 · Tab 重播 · Ctrl+C 退出',\n paused: '[r] 继续 · [q] 返回菜单',\n summary: '[n] 下一章 · [m] 复习错词 · [q] 返回菜单',\n },\n errors: {\n noMistakes: '错词本是空的。先练习几章吧。',\n dictEmpty: (id) => `词典 ${id} 是空的。`,\n unknown: '未知错误',\n },\n },\n audio: {\n noPlayer: '! 未在 PATH 中找到音频播放器(尝试 afplay/ffplay/mpg123/paplay/aplay/powershell)。音效已禁用。',\n },\n report: {\n title: '本次会话',\n duration: '总时长',\n practiced: '练习用时',\n chapters: '完成章节',\n words: '词数',\n accuracy: '准确率',\n wpm: '速度',\n newMistakes: '新错词',\n farewell: '下次见。',\n },\n};\n","export type Lang = 'zh' | 'en';\nexport type LangPref = 'auto' | Lang;\n\nfunction pickFromString(s: string | undefined): Lang | null {\n if (!s) return null;\n const lower = s.toLowerCase();\n if (lower.startsWith('zh')) return 'zh';\n if (lower.startsWith('en')) return 'en';\n return null;\n}\n\nexport function detectLocale(pref: LangPref): Lang {\n if (pref === 'zh' || pref === 'en') return pref;\n const env =\n process.env.LC_ALL ||\n process.env.LC_MESSAGES ||\n process.env.LANG ||\n process.env.LANGUAGE;\n const fromEnv = pickFromString(env);\n if (fromEnv) return fromEnv;\n try {\n const intlLocale = Intl.DateTimeFormat().resolvedOptions().locale;\n const fromIntl = pickFromString(intlLocale);\n if (fromIntl) return fromIntl;\n } catch {\n // ignore\n }\n return 'en';\n}\n","import { useState } from 'react';\nimport { Box, Text, useApp, useInput } from 'ink';\nimport { useNav } from '../nav.js';\nimport { useAudioStatus } from '../audio-context.js';\nimport { useStrings } from '../../i18n/context.js';\nimport { PALETTE } from '../components/BigWord.js';\nimport { visibleWidth } from '../../util/text.js';\nimport type { Config } from '../../infra/config-store.js';\n\ntype Item = { key: string; label: string; hint: string; run: () => void };\n\nexport function MainMenu({ cfg }: { cfg: Config }) {\n const [selected, setSelected] = useState(0);\n const { exit } = useApp();\n const nav = useNav();\n const audio = useAudioStatus();\n const t = useStrings();\n\n const m = t.mainMenu.items;\n const items: Item[] = [\n {\n key: 'p',\n label: m.practiceLabel,\n hint: cfg.defaultDict ? m.practiceHintWith(cfg.defaultDict) : m.practiceHintNone,\n run: () => {\n if (cfg.defaultDict) {\n nav.navigate({\n name: 'practice',\n params: { dictId: cfg.defaultDict, chapterIndex: 0, mode: cfg.defaultMode },\n });\n } else {\n nav.navigate({ name: 'dict', params: { pickerMode: 'choose-then-practice' } });\n }\n },\n },\n { key: 'd', label: m.dictLabel, hint: m.dictHint, run: () => nav.navigate({ name: 'dict' }) },\n { key: 'w', label: m.wordLabel, hint: m.wordHint, run: () => nav.navigate({ name: 'word' }) },\n { key: 's', label: m.statsLabel, hint: m.statsHint, run: () => nav.navigate({ name: 'stats' }) },\n { key: 'c', label: m.configLabel, hint: m.configHint, run: () => nav.navigate({ name: 'config' }) },\n { key: 'q', label: m.quitLabel, hint: m.quitHint, run: () => exit() },\n ];\n\n // Label width that accounts for CJK double-width chars so columns align.\n const labelW = Math.max(...items.map((it) => visibleWidth(it.label))) + 4;\n\n useInput((input, key) => {\n if (key.upArrow) setSelected((i) => (i - 1 + items.length) % items.length);\n if (key.downArrow) setSelected((i) => (i + 1) % items.length);\n if (key.return) {\n items[selected]!.run();\n return;\n }\n for (const it of items) {\n if (input === it.key) {\n it.run();\n return;\n }\n }\n });\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\">\n <Box>\n <Text bold color={PALETTE.accent}>\n {t.app.title}\n </Text>\n <Text color={PALETTE.muted}> · {t.app.subtitle}</Text>\n </Box>\n\n <Box marginTop={2} flexDirection=\"column\">\n {items.map((it, i) => {\n const active = i === selected;\n const pad = ' '.repeat(Math.max(0, labelW - visibleWidth(it.label)));\n return (\n <Box key={it.key}>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>{active ? '▌ ' : ' '}</Text>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>[{it.key}]</Text>\n <Text>{' '}</Text>\n <Text bold={active} color={active ? PALETTE.text : PALETTE.muted}>\n {it.label}\n {pad}\n </Text>\n <Text color={PALETTE.muted}>{it.hint}</Text>\n </Box>\n );\n })}\n </Box>\n\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>\n {cfg.defaultDict ? t.mainMenu.defaultDict(cfg.defaultDict) : t.mainMenu.noDefault}\n </Text>\n </Box>\n\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{t.mainMenu.hint}</Text>\n </Box>\n\n {audio.warning && (\n <Box marginTop={1}>\n <Text color={PALETTE.warning}>{t.audio.noPlayer}</Text>\n </Box>\n )}\n </Box>\n );\n}\n","import { Box, Text, useStdout } from 'ink';\n\nexport const PALETTE = {\n accent: '#5eead4',\n muted: '#6b7280',\n text: '#e5e7eb',\n primary: '#7dcfff',\n success: '#86efac',\n warning: '#fbbf24',\n error: '#f87171',\n} as const;\n\ntype Props = {\n target: string;\n typed: string;\n error?: boolean;\n hideTarget?: boolean;\n};\n\nexport function BigWord({ target, typed, error = false, hideTarget = false }: Props) {\n const { stdout } = useStdout();\n const cols = stdout?.columns ?? 80;\n const chars = [...target];\n const typedChars = [...typed];\n\n // For narrow terminals, render with single space between letters.\n // For wider terminals, use two spaces for more breathing room.\n const sep = cols < 60 ? ' ' : ' ';\n\n return (\n <Box justifyContent=\"center\">\n {chars.map((ch, i) => {\n const isTyped = i < typedChars.length;\n const display = hideTarget && !isTyped ? '_' : isTyped ? typedChars[i]! : ch;\n const color = isTyped\n ? PALETTE.accent\n : error\n ? PALETTE.error\n : PALETTE.muted;\n return (\n <Text key={i} bold color={color} underline={!isTyped && error}>\n {display}\n {i < chars.length - 1 ? sep : ''}\n </Text>\n );\n })}\n </Box>\n );\n}\n\ntype BoldTextProps = {\n text: string;\n color?: string;\n};\n\nexport function BoldSpaced({ text, color = PALETTE.text }: BoldTextProps) {\n const chars = [...text];\n return (\n <Box>\n {chars.map((ch, i) => (\n <Text key={i} bold color={color}>\n {ch}\n {i < chars.length - 1 ? ' ' : ''}\n </Text>\n ))}\n </Box>\n );\n}\n","const ANSI_RE = /\\x1b\\[[0-9;]*m/g;\n\nexport function stripAnsi(s: string): string {\n return s.replace(ANSI_RE, '');\n}\n\nexport function visibleWidth(s: string): number {\n const plain = stripAnsi(s);\n let w = 0;\n for (const ch of plain) {\n const code = ch.codePointAt(0)!;\n w += code > 0x2e80 && code < 0xfb00 ? 2 : 1;\n }\n return w;\n}\n\nexport function pad(s: string, n: number): string {\n return s + ' '.repeat(Math.max(0, n - visibleWidth(s)));\n}\n\nexport function truncate(s: string, max: number): string {\n if (visibleWidth(s) <= max) return s;\n const plain = stripAnsi(s);\n let out = '';\n let w = 0;\n for (const ch of plain) {\n const code = ch.codePointAt(0)!;\n const cw = code > 0x2e80 && code < 0xfb00 ? 2 : 1;\n if (w + cw > max - 1) break;\n out += ch;\n w += cw;\n }\n return out + '…';\n}\n","import { useState, useEffect, useRef } from 'react';\nimport { Box, Text, useApp, useInput } from 'ink';\nimport type { Word } from '../../domain/dictionary.js';\nimport type { Mode } from '../../domain/chapters.js';\nimport { chunkChapters, buildPlaylist } from '../../domain/chapters.js';\nimport { sessionSummary } from '../../domain/session.js';\nimport { loadMistakes } from '../../domain/mistakes.js';\nimport { ensureDictionary } from '../../infra/dict-downloader.js';\nimport { useWordLoop } from '../hooks/useWordLoop.js';\nimport { useAudio } from '../hooks/useAudio.js';\nimport { useSessionPersistence } from '../hooks/useSessionPersistence.js';\nimport { useNav, type PracticeParams } from '../nav.js';\nimport { useAppState } from '../app-state.js';\nimport { useStrings } from '../../i18n/context.js';\nimport { BigWord, BoldSpaced, PALETTE } from '../components/BigWord.js';\n\ntype Phase = 'loading' | 'typing' | 'paused' | 'summary' | 'error';\n\ntype Loaded = {\n playlist: Word[];\n totalChapters: number;\n};\n\nexport function PracticeScreen({ params }: { params: PracticeParams }) {\n const { dictId, chapterIndex, mode } = params;\n const { cfg } = useAppState();\n const t = useStrings();\n\n const [phase, setPhase] = useState<Phase>('loading');\n const [loaded, setLoaded] = useState<Loaded | null>(null);\n const [errorMsg, setErrorMsg] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n setPhase('loading');\n setLoaded(null);\n setErrorMsg(null);\n (async () => {\n try {\n const words = await ensureDictionary(dictId);\n if (cancelled) return;\n if (mode === 'review') {\n const book = await loadMistakes();\n if (cancelled) return;\n const reviewWords = words.filter((w) => book[w.name]?.count).slice(0, cfg.chapterSize);\n if (reviewWords.length === 0) {\n setErrorMsg(t.practice.errors.noMistakes);\n setPhase('error');\n return;\n }\n setLoaded({ playlist: reviewWords, totalChapters: 1 });\n setPhase('typing');\n return;\n }\n const chapters = chunkChapters(words, cfg.chapterSize);\n if (chapters.length === 0) {\n setErrorMsg(t.practice.errors.dictEmpty(dictId));\n setPhase('error');\n return;\n }\n const idx = Math.max(0, Math.min(chapters.length - 1, chapterIndex));\n const playlist = buildPlaylist(chapters[idx]!, mode);\n setLoaded({ playlist, totalChapters: chapters.length });\n setPhase('typing');\n } catch (err) {\n if (cancelled) return;\n setErrorMsg((err as Error).message);\n setPhase('error');\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [dictId, chapterIndex, mode, cfg.chapterSize, t]);\n\n if (phase === 'loading') {\n return <Centered text={t.practice.loading} color={PALETTE.muted} />;\n }\n if (phase === 'error') {\n return <ErrorView msg={errorMsg ?? t.practice.errors.unknown} />;\n }\n if (!loaded) return null;\n\n return (\n <PracticeRunner\n key={`${dictId}-${chapterIndex}-${mode}`}\n params={params}\n loaded={loaded}\n phase={phase}\n setPhase={setPhase}\n />\n );\n}\n\nfunction PracticeRunner({\n params,\n loaded,\n phase,\n setPhase,\n}: {\n params: PracticeParams;\n loaded: Loaded;\n phase: Phase;\n setPhase: (p: Phase) => void;\n}) {\n const { dictId, chapterIndex, mode } = params;\n const { cfg } = useAppState();\n const nav = useNav();\n const { exit } = useApp();\n const goBack = () => (nav.stack.length > 1 ? nav.back() : exit());\n const persist = useSessionPersistence({ dictId, chapterIndex, mode });\n\n const audio = useAudio({\n enabled: cfg.sounds.master,\n accent: cfg.accent,\n autoplayPronunciation: cfg.autoplayPronunciation,\n });\n\n const finishedRef = useRef(false);\n const lastEffectRef = useRef<string | null>(null);\n const lastIndexRef = useRef<number>(-1);\n\n const { session, lastEffect, tick } = useWordLoop({\n playlist: loaded.playlist,\n enabled: phase === 'typing',\n onComplete: (s) => {\n if (finishedRef.current) return;\n finishedRef.current = true;\n setPhase('summary');\n Promise.resolve(persist(sessionSummary(s))).catch((err) => {\n console.error('Failed to persist session:', err);\n });\n },\n onEscape: () => setPhase(phase === 'paused' ? 'typing' : 'paused'),\n onTab: () => {\n const cur = session.current ? loaded.playlist[session.current.wordIndex] : undefined;\n if (cur) void audio.pronounce(cur.name);\n },\n });\n\n useEffect(() => {\n if (lastEffect === null) return;\n if (lastEffect === lastEffectRef.current) return;\n lastEffectRef.current = lastEffect;\n if (lastEffect === 'wrong' && cfg.sounds.feedback) audio.wrong();\n if (lastEffect === 'progress' && cfg.sounds.keystroke) audio.keystroke();\n if (lastEffect === 'correct') {\n if (cfg.sounds.feedback) audio.correct();\n if (cfg.sounds.keystroke) audio.keystroke();\n }\n }, [lastEffect, audio, cfg.sounds.feedback, cfg.sounds.keystroke]);\n\n useEffect(() => {\n const idx = session.current?.wordIndex ?? -1;\n if (idx === -1) return;\n if (idx === lastIndexRef.current) return;\n lastIndexRef.current = idx;\n const cur = loaded.playlist[idx];\n const next = loaded.playlist[idx + 1];\n if (cur && cfg.autoplayPronunciation) audio.pronounce(cur.name);\n if (next) audio.prefetch(next.name);\n }, [session.current?.wordIndex, audio, cfg.autoplayPronunciation, loaded.playlist]);\n\n void tick;\n\n useInput(\n (input) => {\n if (input === 'r') setPhase('typing');\n if (input === 'q') goBack();\n },\n { isActive: phase === 'paused' },\n );\n\n useInput(\n (input) => {\n if (input === 'q') {\n goBack();\n return;\n }\n if (input === 'n') {\n const nextIdx = chapterIndex + 1;\n if (mode === 'loop') {\n nav.replace({ name: 'practice', params: { dictId, chapterIndex, mode } });\n } else if (mode === 'review' || nextIdx >= loaded.totalChapters) {\n goBack();\n } else {\n nav.replace({ name: 'practice', params: { dictId, chapterIndex: nextIdx, mode } });\n }\n return;\n }\n if (input === 'm') {\n nav.replace({ name: 'practice', params: { dictId, chapterIndex: 0, mode: 'review' } });\n return;\n }\n },\n { isActive: phase === 'summary' },\n );\n\n if (phase === 'paused') return <PausedView />;\n if (phase === 'summary') {\n return (\n <SummaryView\n dictId={dictId}\n chapterIndex={chapterIndex}\n totalChapters={loaded.totalChapters}\n mode={mode}\n summary={sessionSummary(session)}\n />\n );\n }\n\n const currentWord = session.current\n ? loaded.playlist[session.current.wordIndex]\n : loaded.playlist[loaded.playlist.length - 1];\n const inputState = session.current?.input ?? { target: '', typed: '', errorsThisWord: 0 };\n const elapsedMs = Date.now() - session.startedAt;\n const completed = session.results.length;\n const errors = session.results.reduce((a, r) => a + r.errors, 0);\n const minutes = elapsedMs / 60000;\n const wpm = minutes > 0 ? Math.round((completed / minutes) * 10) / 10 : 0;\n\n return (\n <TypingLayout\n dictId={dictId}\n chapterIndex={chapterIndex}\n totalChapters={loaded.totalChapters}\n mode={mode}\n accent={cfg.accent}\n completed={completed}\n total={loaded.playlist.length}\n errors={errors}\n wpm={wpm}\n elapsedMs={elapsedMs}\n target={currentWord?.name ?? ''}\n typed={inputState.typed}\n flashError={lastEffect === 'wrong'}\n hideTarget={mode === 'dictation'}\n phonetic={pickPhonetic(currentWord, cfg.accent)}\n translation={currentWord?.trans ?? []}\n />\n );\n}\n\nfunction pickPhonetic(word: Word | undefined, accent: 'us' | 'uk'): string | null {\n if (!word) return null;\n const p = accent === 'us' ? word.usphone : word.ukphone;\n return p ? `/${p}/` : null;\n}\n\nfunction fmtTime(ms: number): string {\n const total = Math.floor(ms / 1000);\n const m = Math.floor(total / 60);\n const s = total % 60;\n return `${m}:${String(s).padStart(2, '0')}`;\n}\n\nfunction TypingLayout(props: {\n dictId: string;\n chapterIndex: number;\n totalChapters: number;\n mode: Mode;\n accent: 'us' | 'uk';\n completed: number;\n total: number;\n errors: number;\n wpm: number;\n elapsedMs: number;\n target: string;\n typed: string;\n flashError: boolean;\n hideTarget: boolean;\n phonetic: string | null;\n translation: string[];\n}) {\n const t = useStrings();\n const progressFrac = props.total === 0 ? 0 : props.completed / props.total;\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <StatusBar\n dictId={props.dictId}\n chapterIndex={props.chapterIndex}\n totalChapters={props.totalChapters}\n mode={props.mode}\n accent={props.accent}\n completed={props.completed}\n total={props.total}\n elapsedMs={props.elapsedMs}\n />\n\n <Box flexGrow={1} flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\">\n <BigWord\n target={props.target}\n typed={props.typed}\n error={props.flashError}\n hideTarget={props.hideTarget}\n />\n\n {props.phonetic && (\n <Box marginTop={1}>\n <Text italic color={PALETTE.muted}>\n {props.phonetic}\n </Text>\n </Box>\n )}\n\n {props.translation.length > 0 && (\n <Box marginTop={1} flexDirection=\"column\" alignItems=\"center\">\n {props.translation.slice(0, 2).map((tr, i) => (\n <Text key={i} color={PALETTE.primary}>\n {tr}\n </Text>\n ))}\n </Box>\n )}\n </Box>\n\n <Box flexDirection=\"column\">\n <ProgressBar frac={progressFrac} />\n <Box justifyContent=\"center\" marginTop={1}>\n <Text color={PALETTE.muted}>\n {props.completed}/{props.total} · {fmtTime(props.elapsedMs)} · {props.wpm} {t.practice.statCards.wpm} · {props.errors} {t.practice.statCards.errors}\n </Text>\n </Box>\n <Box justifyContent=\"center\" marginTop={1}>\n <Text color={PALETTE.muted}>{t.practice.footers.typing}</Text>\n </Box>\n </Box>\n </Box>\n );\n}\n\nfunction StatusBar(props: {\n dictId: string;\n chapterIndex: number;\n totalChapters: number;\n mode: Mode;\n accent: 'us' | 'uk';\n completed: number;\n total: number;\n elapsedMs: number;\n}) {\n const t = useStrings();\n const modeName = t.practice.modes[props.mode];\n const accentName = t.practice.accents[props.accent];\n const left =\n props.mode === 'review'\n ? `${props.dictId} · ${t.practice.reviewLabel} · ${accentName}`\n : `${props.dictId} · ${t.practice.chapterLabel(props.chapterIndex + 1, props.totalChapters)} · ${modeName} · ${accentName}`;\n const right = `${props.completed}/${props.total} · ${fmtTime(props.elapsedMs)}`;\n return (\n <Box>\n <Text color={PALETTE.muted}>{left}</Text>\n <Box flexGrow={1} />\n <Text color={PALETTE.muted}>{right}</Text>\n </Box>\n );\n}\n\nfunction ProgressBar({ frac }: { frac: number }) {\n const cols = process.stdout.columns ?? 80;\n const width = Math.max(20, Math.min(72, cols - 16));\n const filled = Math.round(width * Math.max(0, Math.min(1, frac)));\n const empty = width - filled;\n return (\n <Box justifyContent=\"center\">\n <Text color={PALETTE.accent}>{'━'.repeat(filled)}</Text>\n <Text color={PALETTE.muted}>{'─'.repeat(empty)}</Text>\n </Box>\n );\n}\n\nfunction PausedView() {\n const t = useStrings();\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <BoldSpaced text={t.practice.paused} color={PALETTE.warning} />\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>{t.practice.footers.paused}</Text>\n </Box>\n </Box>\n );\n}\n\nfunction ErrorView({ msg }: { msg: string }) {\n const t = useStrings();\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.error}>{msg}</Text>\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>[q] {t.common.back}</Text>\n </Box>\n <BackKey />\n </Box>\n );\n}\n\nfunction BackKey() {\n const nav = useNav();\n useInput((input, key) => {\n if (input === 'q' || key.escape) nav.back();\n });\n return null;\n}\n\nfunction Centered({ text, color }: { text: string; color: string }) {\n return (\n <Box alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={color}>{text}</Text>\n </Box>\n );\n}\n\nfunction SummaryView(props: {\n dictId: string;\n chapterIndex: number;\n totalChapters: number;\n mode: Mode;\n summary: { wordCount: number; errors: number; durationMs: number; perWordErrors: Record<string, number> };\n}) {\n const { summary } = props;\n const minutes = summary.durationMs / 60000;\n const wpm = minutes > 0 ? Math.round((summary.wordCount / minutes) * 10) / 10 : 0;\n const errorWords = Object.keys(summary.perWordErrors).length;\n const acc = summary.wordCount === 0 ? 1 : Math.max(0, (summary.wordCount - errorWords) / summary.wordCount);\n const accPct = Math.round(acc * 1000) / 10;\n\n const t = useStrings();\n const modeName = t.practice.modes[props.mode];\n const subtitle =\n props.mode === 'review'\n ? `${props.dictId} · ${t.practice.reviewLabel}`\n : `${props.dictId} · ${t.practice.chapterLabel(props.chapterIndex + 1, props.totalChapters)} · ${modeName}`;\n\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" paddingY={1} width=\"100%\" height=\"100%\">\n <BoldSpaced text={t.practice.chapterComplete} color={PALETTE.success} />\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{subtitle}</Text>\n </Box>\n\n <Box marginTop={3} flexDirection=\"row\" justifyContent=\"center\">\n <StatCard label={t.practice.statCards.words} value={String(summary.wordCount)} color={PALETTE.text} />\n <StatCard\n label={t.practice.statCards.errors}\n value={String(summary.errors)}\n color={summary.errors > 0 ? PALETTE.error : PALETTE.muted}\n />\n <StatCard label={t.practice.statCards.wpm} value={String(wpm)} color={PALETTE.accent} />\n <StatCard label={t.practice.statCards.accuracy} value={`${accPct}%`} color={PALETTE.accent} />\n </Box>\n\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>{t.practice.statCards.elapsed(fmtTime(summary.durationMs))}</Text>\n </Box>\n\n <Box flexGrow={1} />\n\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>{t.practice.footers.summary}</Text>\n </Box>\n </Box>\n );\n}\n\nfunction StatCard({ label, value, color }: { label: string; value: string; color: string }) {\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" marginX={3}>\n <Text bold color={color}>{value}</Text>\n <Text color={PALETTE.muted}>{label}</Text>\n </Box>\n );\n}\n","export function shuffle<T>(arr: readonly T[], rng: () => number = Math.random): T[] {\n const out = [...arr];\n for (let i = out.length - 1; i > 0; i--) {\n const j = Math.floor(rng() * (i + 1));\n const tmp = out[i]!;\n out[i] = out[j]!;\n out[j] = tmp;\n }\n return out;\n}\n\nexport function mulberry32(seed: number): () => number {\n let t = seed >>> 0;\n return () => {\n t = (t + 0x6d2b79f5) >>> 0;\n let r = Math.imul(t ^ (t >>> 15), 1 | t);\n r = (r + Math.imul(r ^ (r >>> 7), 61 | r)) ^ r;\n return ((r ^ (r >>> 14)) >>> 0) / 4294967296;\n };\n}\n","import type { Word } from './dictionary.js';\nimport { shuffle, mulberry32 } from '../util/shuffle.js';\n\nexport type Mode = 'order' | 'dictation' | 'review' | 'random' | 'loop';\n\nexport function chunkChapters(words: Word[], chapterSize: number): Word[][] {\n if (chapterSize <= 0) throw new Error('chapterSize must be positive');\n const chunks: Word[][] = [];\n for (let i = 0; i < words.length; i += chapterSize) {\n chunks.push(words.slice(i, i + chapterSize));\n }\n return chunks;\n}\n\nexport function chapterCount(totalWords: number, chapterSize: number): number {\n return Math.ceil(totalWords / chapterSize);\n}\n\n/**\n * Build a play list for a chapter, applying the given mode.\n * - order: return as-is\n * - dictation: same as order (hide-the-word behavior is UI-only)\n * - random: single shuffled pass\n * - loop: return as-is; the practice screen drives the repeat\n * - review: caller passes the mistake-book words, we just chunk those\n */\nexport function buildPlaylist(chapter: Word[], mode: Mode, seed?: number): Word[] {\n if (mode === 'random') {\n const rng = seed === undefined ? Math.random : mulberry32(seed);\n return shuffle(chapter, rng);\n }\n return chapter;\n}\n","export type InputState = {\n target: string;\n typed: string;\n errorsThisWord: number;\n};\n\nexport type InputEvent =\n | { type: 'char'; ch: string }\n | { type: 'backspace' }\n | { type: 'reset' };\n\nexport type InputEffect = 'none' | 'progress' | 'wrong' | 'correct' | 'skipped';\n\nexport function initialState(target: string): InputState {\n return { target, typed: '', errorsThisWord: 0 };\n}\n\nexport function reduce(state: InputState, ev: InputEvent): { state: InputState; effect: InputEffect } {\n switch (ev.type) {\n case 'reset':\n return { state: { ...state, typed: '' }, effect: 'none' };\n case 'backspace': {\n if (state.typed.length === 0) return { state, effect: 'none' };\n return { state: { ...state, typed: state.typed.slice(0, -1) }, effect: 'none' };\n }\n case 'char': {\n const candidate = state.typed + ev.ch;\n // Compare by code-point index, not byte length, to handle unicode safely.\n const targetUpToCandidate = [...state.target].slice(0, [...candidate].length).join('');\n if (candidate === targetUpToCandidate) {\n if (candidate.length === state.target.length) {\n return { state: { ...state, typed: candidate }, effect: 'correct' };\n }\n return { state: { ...state, typed: candidate }, effect: 'progress' };\n }\n return {\n state: { ...state, typed: '', errorsThisWord: state.errorsThisWord + 1 },\n effect: 'wrong',\n };\n }\n }\n}\n","import type { Word } from './dictionary.js';\nimport { initialState, reduce, type InputEvent, type InputState, type InputEffect } from './input-buffer.js';\n\nexport type SessionWordResult = { word: string; errors: number; durationMs: number; skipped?: boolean };\n\nexport type Session = {\n startedAt: number;\n results: SessionWordResult[];\n current: { wordIndex: number; wordStartedAt: number; input: InputState } | null;\n finishedAt: number | null;\n playlist: Word[];\n};\n\nexport function startSession(playlist: Word[], now = Date.now()): Session {\n if (playlist.length === 0) {\n return { startedAt: now, results: [], current: null, finishedAt: now, playlist };\n }\n return {\n startedAt: now,\n results: [],\n current: { wordIndex: 0, wordStartedAt: now, input: initialState(playlist[0]!.name) },\n finishedAt: null,\n playlist,\n };\n}\n\nexport function feedSession(session: Session, ev: InputEvent, now = Date.now()): { session: Session; effect: InputEffect } {\n if (!session.current) return { session, effect: 'none' };\n const { state, effect } = reduce(session.current.input, ev);\n if (effect === 'correct') {\n const finished: SessionWordResult = {\n word: state.target,\n errors: state.errorsThisWord,\n durationMs: now - session.current.wordStartedAt,\n };\n const nextIndex = session.current.wordIndex + 1;\n const results = [...session.results, finished];\n if (nextIndex >= session.playlist.length) {\n return {\n session: { ...session, results, current: null, finishedAt: now },\n effect,\n };\n }\n return {\n session: {\n ...session,\n results,\n current: {\n wordIndex: nextIndex,\n wordStartedAt: now,\n input: initialState(session.playlist[nextIndex]!.name),\n },\n },\n effect,\n };\n }\n return {\n session: {\n ...session,\n current: { ...session.current, input: state },\n },\n effect,\n };\n}\n\nexport function skipSession(session: Session, now = Date.now()): { session: Session; effect: InputEffect } {\n if (!session.current) return { session, effect: 'none' };\n const result: SessionWordResult = {\n word: session.current.input.target,\n errors: 0,\n durationMs: now - session.current.wordStartedAt,\n skipped: true,\n };\n const nextIndex = session.current.wordIndex + 1;\n const results = [...session.results, result];\n if (nextIndex >= session.playlist.length) {\n return {\n session: { ...session, results, current: null, finishedAt: now },\n effect: 'skipped',\n };\n }\n return {\n session: {\n ...session,\n results,\n current: {\n wordIndex: nextIndex,\n wordStartedAt: now,\n input: initialState(session.playlist[nextIndex]!.name),\n },\n },\n effect: 'skipped',\n };\n}\n\nexport function sessionSummary(session: Session): {\n wordCount: number;\n errors: number;\n durationMs: number;\n perWordErrors: Record<string, number>;\n} {\n const errors = session.results.reduce((a, r) => a + r.errors, 0);\n const durationMs =\n (session.finishedAt ?? Date.now()) - session.startedAt;\n const perWordErrors: Record<string, number> = {};\n for (const r of session.results) {\n if (r.errors > 0) perWordErrors[r.word] = (perWordErrors[r.word] ?? 0) + r.errors;\n }\n return { wordCount: session.results.length, errors, durationMs, perWordErrors };\n}\n","import { z } from 'zod';\nimport { paths } from '../infra/paths.js';\nimport { readJson, writeJsonAtomic } from '../infra/fs-store.js';\n\nexport const MistakeBookSchema = z.record(\n z.string(),\n z.object({\n count: z.number().int().nonnegative(),\n lastSeen: z.string(),\n dictIds: z.array(z.string()).default([]),\n }),\n);\n\nexport type MistakeBook = z.infer<typeof MistakeBookSchema>;\n\nexport async function loadMistakes(): Promise<MistakeBook> {\n const raw = await readJson<unknown>(paths.mistakes);\n if (!raw) return {};\n const parsed = MistakeBookSchema.safeParse(raw);\n if (!parsed.success) {\n console.warn('Mistake book is corrupt; starting fresh');\n return {};\n }\n return parsed.data;\n}\n\nexport async function saveMistakes(book: MistakeBook): Promise<void> {\n await writeJsonAtomic(paths.mistakes, book);\n}\n\nexport function bump(book: MistakeBook, word: string, dictId: string, delta = 1): MistakeBook {\n const prev = book[word] ?? { count: 0, lastSeen: new Date(0).toISOString(), dictIds: [] };\n const dictIds = prev.dictIds.includes(dictId) ? prev.dictIds : [...prev.dictIds, dictId];\n return {\n ...book,\n [word]: {\n count: prev.count + delta,\n lastSeen: new Date().toISOString(),\n dictIds,\n },\n };\n}\n\nexport function topN(book: MistakeBook, n: number): Array<[string, MistakeBook[string]]> {\n return Object.entries(book)\n .sort((a, b) => b[1].count - a[1].count)\n .slice(0, n);\n}\n","import { useEffect, useReducer, useRef, useState } from 'react';\nimport { useInput, useApp } from 'ink';\nimport type { Word } from '../../domain/dictionary.js';\nimport { startSession, feedSession, skipSession, type Session } from '../../domain/session.js';\nimport type { InputEffect } from '../../domain/input-buffer.js';\n\ntype Action =\n | { type: 'event'; input: string; key: { backspace?: boolean; delete?: boolean; tab?: boolean; escape?: boolean; return?: boolean; ctrl?: boolean }; now: number }\n | { type: 'start'; playlist: Word[]; now: number }\n | { type: 'skip'; now: number };\n\nfunction reducer(state: { session: Session; lastEffect: InputEffect | null }, action: Action) {\n if (action.type === 'start') {\n return { session: startSession(action.playlist, action.now), lastEffect: null };\n }\n if (action.type === 'skip') {\n const r = skipSession(state.session, action.now);\n return { session: r.session, lastEffect: r.effect };\n }\n if (action.type === 'event') {\n if (action.key.backspace || action.key.delete) {\n const r = feedSession(state.session, { type: 'backspace' }, action.now);\n return { session: r.session, lastEffect: r.effect };\n }\n if (action.input.length === 0) return state;\n let session = state.session;\n let lastEffect: InputEffect | null = state.lastEffect;\n for (const c of action.input) {\n const r = feedSession(session, { type: 'char', ch: c }, action.now);\n session = r.session;\n lastEffect = r.effect;\n if (session.finishedAt !== null) break;\n }\n return { session, lastEffect };\n }\n return state;\n}\n\nexport type UseWordLoopOpts = {\n playlist: Word[];\n onComplete: (session: Session) => void;\n onTab?: () => void;\n onEscape?: () => void;\n onSkip?: () => void;\n enabled?: boolean;\n};\n\nexport function useWordLoop({ playlist, onComplete, onTab, onEscape, onSkip, enabled = true }: UseWordLoopOpts) {\n const [state, dispatch] = useReducer(reducer, undefined, () => ({\n session: startSession(playlist, Date.now()),\n lastEffect: null as InputEffect | null,\n }));\n const completedRef = useRef(false);\n const [tick, setTick] = useState(0);\n const { exit } = useApp();\n\n useInput(\n (input, key) => {\n if (key.ctrl && input === 'c') {\n exit();\n return;\n }\n if (key.ctrl && input === 'n') {\n onSkip?.();\n dispatch({ type: 'skip', now: Date.now() });\n return;\n }\n if (key.escape) {\n onEscape?.();\n return;\n }\n if (key.tab) {\n onTab?.();\n return;\n }\n if (key.upArrow || key.downArrow || key.leftArrow || key.rightArrow || key.return) return;\n if (key.ctrl || key.meta) return;\n const cleaned = [...input].filter((c) => {\n const code = c.codePointAt(0)!;\n return code === 0x20 || (code >= 0x21 && code !== 0x7f);\n }).join('');\n if (cleaned.length === 0) return;\n dispatch({ type: 'event', input: cleaned, key, now: Date.now() });\n },\n { isActive: enabled },\n );\n\n useEffect(() => {\n if (state.session.finishedAt !== null && !completedRef.current) {\n completedRef.current = true;\n onComplete(state.session);\n }\n }, [state.session, onComplete]);\n\n useEffect(() => {\n if (state.session.finishedAt !== null) return;\n const id = setInterval(() => setTick((t) => t + 1), 1000);\n return () => clearInterval(id);\n }, [state.session.finishedAt]);\n\n return { session: state.session, lastEffect: state.lastEffect, tick };\n}\n","import { useEffect, useRef } from 'react';\nimport {\n initAudio,\n playCorrect,\n playWrong,\n playKeystroke,\n playPronunciation,\n prefetchPronunciation,\n} from '../../infra/audio.js';\n\ntype Opts = {\n enabled: boolean;\n accent: 'us' | 'uk';\n autoplayPronunciation: boolean;\n};\n\nexport type AudioControls = {\n keystroke: () => void;\n correct: () => void;\n wrong: () => void;\n pronounce: (word: string) => void;\n prefetch: (word: string) => void;\n};\n\nexport function useAudio(opts: Opts): AudioControls {\n const initedRef = useRef(false);\n useEffect(() => {\n if (initedRef.current) return;\n initedRef.current = true;\n initAudio(!opts.enabled).catch(() => undefined);\n }, [opts.enabled]);\n\n return {\n keystroke: () => opts.enabled && playKeystroke(),\n correct: () => opts.enabled && playCorrect(),\n wrong: () => opts.enabled && playWrong(),\n pronounce: (word) => {\n if (!opts.enabled) return;\n if (opts.autoplayPronunciation) void playPronunciation(word, opts.accent);\n },\n prefetch: (word) => {\n if (!opts.enabled) return;\n void prefetchPronunciation(word, opts.accent);\n },\n };\n}\n","import { useCallback } from 'react';\nimport { appendSession, type SessionRecord } from '../../domain/stats.js';\nimport { loadMistakes, saveMistakes, bump } from '../../domain/mistakes.js';\nimport { addChapter as trackChapter } from '../../infra/session-tracker.js';\nimport type { Mode } from '../../domain/chapters.js';\n\ntype Summary = {\n wordCount: number;\n errors: number;\n durationMs: number;\n perWordErrors: Record<string, number>;\n};\n\nexport function useSessionPersistence(meta: { dictId: string; chapterIndex: number; mode: Mode }) {\n return useCallback(\n async (summary: Summary): Promise<void> => {\n const rec: SessionRecord = {\n ts: new Date().toISOString(),\n dictId: meta.dictId,\n chapter: meta.chapterIndex,\n mode: meta.mode,\n wordCount: summary.wordCount,\n errors: summary.errors,\n durationMs: summary.durationMs,\n perWordErrors: summary.perWordErrors,\n };\n await appendSession(rec);\n trackChapter({\n dictId: meta.dictId,\n chapterIndex: meta.chapterIndex,\n mode: meta.mode,\n wordCount: summary.wordCount,\n errors: summary.errors,\n durationMs: summary.durationMs,\n perWordErrors: summary.perWordErrors,\n });\n const dirty = Object.entries(summary.perWordErrors).filter(([, n]) => n > 0);\n if (dirty.length === 0) return;\n let book = await loadMistakes();\n for (const [word, n] of dirty) book = bump(book, word, meta.dictId, n);\n await saveMistakes(book);\n },\n [meta.dictId, meta.chapterIndex, meta.mode],\n );\n}\n","import { z } from 'zod';\nimport { paths } from '../infra/paths.js';\nimport { appendJsonl, readJsonl } from '../infra/fs-store.js';\n\nexport const SessionRecordSchema = z.object({\n ts: z.string(),\n dictId: z.string(),\n chapter: z.number().int().nonnegative(),\n mode: z.string(),\n wordCount: z.number().int().nonnegative(),\n errors: z.number().int().nonnegative(),\n durationMs: z.number().int().nonnegative(),\n perWordErrors: z.record(z.string(), z.number().int().nonnegative()).default({}),\n});\n\nexport type SessionRecord = z.infer<typeof SessionRecordSchema>;\n\nexport async function appendSession(record: SessionRecord): Promise<void> {\n await appendJsonl(paths.stats, record);\n}\n\nexport async function loadSessions(): Promise<SessionRecord[]> {\n const rows = await readJsonl<unknown>(paths.stats);\n return rows\n .map((r) => SessionRecordSchema.safeParse(r))\n .filter((r): r is { success: true; data: SessionRecord } => r.success)\n .map((r) => r.data);\n}\n\nexport function computeWPM(record: SessionRecord): number {\n if (record.durationMs === 0) return 0;\n const minutes = record.durationMs / 60000;\n return Math.round((record.wordCount / minutes) * 10) / 10;\n}\n\nexport function accuracy(record: SessionRecord): number {\n // Word-level: fraction of words finished without any mistake (first-try rate).\n if (record.wordCount === 0) return 1;\n const wordsWithErrors = Object.keys(record.perWordErrors).length;\n return Math.max(0, Math.min(1, (record.wordCount - wordsWithErrors) / record.wordCount));\n}\n\nexport function dailyStreak(sessions: SessionRecord[], now = new Date()): number {\n if (sessions.length === 0) return 0;\n const days = new Set<string>();\n for (const s of sessions) days.add(s.ts.slice(0, 10));\n let streak = 0;\n const cur = new Date(now);\n while (true) {\n const key = cur.toISOString().slice(0, 10);\n if (!days.has(key)) break;\n streak++;\n cur.setUTCDate(cur.getUTCDate() - 1);\n }\n return streak;\n}\n\nconst SPARK = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];\n\nexport function sparkline(values: number[]): string {\n if (values.length === 0) return '';\n const max = Math.max(...values, 1);\n const min = Math.min(...values, 0);\n const range = Math.max(1, max - min);\n return values\n .map((v) => {\n const idx = Math.floor(((v - min) / range) * (SPARK.length - 1));\n return SPARK[Math.max(0, Math.min(SPARK.length - 1, idx))]!;\n })\n .join('');\n}\n\nexport type DailyBucket = { date: string; wpm: number; accuracy: number; sessions: number };\n\nexport function dailyBuckets(sessions: SessionRecord[], days: number, now = new Date()): DailyBucket[] {\n const out: DailyBucket[] = [];\n const byDay = new Map<string, SessionRecord[]>();\n for (const s of sessions) {\n const key = s.ts.slice(0, 10);\n const arr = byDay.get(key) ?? [];\n arr.push(s);\n byDay.set(key, arr);\n }\n const cur = new Date(now);\n cur.setUTCDate(cur.getUTCDate() - (days - 1));\n for (let i = 0; i < days; i++) {\n const key = cur.toISOString().slice(0, 10);\n const todays = byDay.get(key) ?? [];\n if (todays.length === 0) {\n out.push({ date: key, wpm: 0, accuracy: 0, sessions: 0 });\n } else {\n const wpm = todays.reduce((a, s) => a + computeWPM(s), 0) / todays.length;\n const acc = todays.reduce((a, s) => a + accuracy(s), 0) / todays.length;\n out.push({ date: key, wpm, accuracy: acc, sessions: todays.length });\n }\n cur.setUTCDate(cur.getUTCDate() + 1);\n }\n return out;\n}\n","type ChapterEntry = {\n dictId: string;\n chapterIndex: number;\n mode: string;\n wordCount: number;\n errors: number;\n durationMs: number;\n perWordErrors: Record<string, number>;\n};\n\ntype State = {\n startedAt: number | null;\n chapters: ChapterEntry[];\n};\n\nconst state: State = {\n startedAt: null,\n chapters: [],\n};\n\nexport function start(now = Date.now()): void {\n if (state.startedAt === null) state.startedAt = now;\n}\n\nexport function addChapter(entry: ChapterEntry): void {\n if (state.startedAt === null) state.startedAt = Date.now();\n state.chapters.push(entry);\n}\n\nexport type SessionReport = {\n startedAt: number | null;\n totalDurationMs: number;\n chaptersCompleted: number;\n wordCount: number;\n errors: number;\n wpm: number;\n accuracy: number;\n newMistakeWords: number;\n practiceMs: number;\n};\n\nexport function report(now = Date.now()): SessionReport {\n const chapters = state.chapters;\n const wordCount = chapters.reduce((a, c) => a + c.wordCount, 0);\n const errors = chapters.reduce((a, c) => a + c.errors, 0);\n const practiceMs = chapters.reduce((a, c) => a + c.durationMs, 0);\n const minutes = practiceMs / 60000;\n const wpm = minutes > 0 ? Math.round((wordCount / minutes) * 10) / 10 : 0;\n const errorWordSet = new Set<string>();\n for (const c of chapters) {\n for (const w of Object.keys(c.perWordErrors)) errorWordSet.add(w);\n }\n const accuracy = wordCount === 0 ? 1 : Math.max(0, (wordCount - errorWordSet.size) / wordCount);\n return {\n startedAt: state.startedAt,\n totalDurationMs: state.startedAt === null ? 0 : now - state.startedAt,\n chaptersCompleted: chapters.length,\n wordCount,\n errors,\n wpm,\n accuracy,\n newMistakeWords: errorWordSet.size,\n practiceMs,\n };\n}\n\nexport function reset(): void {\n state.startedAt = null;\n state.chapters = [];\n}\n","import { useEffect, useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { useNav, type DictParams } from '../nav.js';\nimport { useAppState } from '../app-state.js';\nimport { useStrings } from '../../i18n/context.js';\nimport { PALETTE } from '../components/BigWord.js';\nimport { loadRegistry } from '../../infra/registry-store.js';\nimport {\n isLocallyAvailable,\n pullDictionary,\n removeDictionary,\n} from '../../infra/dict-downloader.js';\nimport type { DictionaryEntry } from '../../domain/dictionary.js';\nimport { filterRegistry } from '../../domain/dictionary.js';\n\ntype Row = { entry: DictionaryEntry; local: boolean };\ntype PendingAction =\n | { kind: 'pulling'; id: string }\n | { kind: 'removing'; id: string }\n | { kind: 'error'; id: string; msg: string }\n | null;\n\nexport function DictBrowser({ params }: { params?: DictParams }) {\n const nav = useNav();\n const { cfg, setCfg } = useAppState();\n const t = useStrings();\n const [rows, setRows] = useState<Row[]>([]);\n const [loading, setLoading] = useState(true);\n const [selected, setSelected] = useState(0);\n const [filter, setFilter] = useState('');\n const [filterFocus, setFilterFocus] = useState(false);\n const [pending, setPending] = useState<PendingAction>(null);\n const [tick, setTick] = useState(0);\n\n const refresh = async () => {\n const reg = await loadRegistry();\n const flagged = await Promise.all(\n reg.map(async (e) => ({ entry: e, local: await isLocallyAvailable(e.id) })),\n );\n setRows(flagged);\n setLoading(false);\n };\n\n useEffect(() => {\n void refresh();\n }, [tick]);\n\n const filtered = filter\n ? rows.filter((r) => filterRegistry([r.entry], filter).length > 0)\n : rows;\n const safeSelected = Math.max(0, Math.min(filtered.length - 1, selected));\n const current = filtered[safeSelected];\n\n useInput((input, key) => {\n if (filterFocus) {\n if (key.escape || key.return) {\n setFilterFocus(false);\n return;\n }\n if (key.backspace || key.delete) {\n setFilter((f) => f.slice(0, -1));\n return;\n }\n if (input && !key.ctrl && !key.meta) {\n setFilter((f) => f + input);\n }\n return;\n }\n if (key.upArrow) setSelected((i) => Math.max(0, i - 1));\n if (key.downArrow) setSelected((i) => Math.min(filtered.length - 1, i + 1));\n if (input === '/') {\n setFilterFocus(true);\n return;\n }\n if (key.escape || input === 'b') {\n nav.back();\n return;\n }\n if (!current) return;\n if (key.return) {\n void (async () => {\n await setCfg({ ...cfg, defaultDict: current.entry.id });\n if (params?.pickerMode === 'choose-then-practice') {\n nav.replace({\n name: 'practice',\n params: { dictId: current.entry.id, chapterIndex: 0, mode: cfg.defaultMode },\n });\n } else {\n nav.back();\n }\n })();\n return;\n }\n if (input === 'p') {\n nav.replace({\n name: 'practice',\n params: { dictId: current.entry.id, chapterIndex: 0, mode: cfg.defaultMode },\n });\n return;\n }\n if (input === 'r' && current.local) {\n setPending({ kind: 'removing', id: current.entry.id });\n void (async () => {\n try {\n await removeDictionary(current.entry.id);\n setPending(null);\n setTick((n) => n + 1);\n } catch (err) {\n setPending({ kind: 'error', id: current.entry.id, msg: (err as Error).message });\n }\n })();\n return;\n }\n if (input === 'u') {\n setPending({ kind: 'pulling', id: current.entry.id });\n void (async () => {\n try {\n await pullDictionary(current.entry.id);\n setPending(null);\n setTick((n) => n + 1);\n } catch (err) {\n setPending({ kind: 'error', id: current.entry.id, msg: (err as Error).message });\n }\n })();\n }\n });\n\n if (loading) {\n return (\n <Box alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.muted}>{t.dict.loading}</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <Box>\n <Text bold color={PALETTE.accent}>\n {t.dict.title}\n </Text>\n <Box flexGrow={1} />\n <Text color={PALETTE.muted}>\n {filterFocus ? `/ ${filter}_` : filter ? t.dict.filterPrompt(filter) : t.dict.entries(filtered.length)}\n </Text>\n </Box>\n\n <Box marginTop={1} flexGrow={1}>\n <Box flexDirection=\"column\" width=\"75%\" paddingRight={1}>\n {filtered.slice(Math.max(0, safeSelected - 8), safeSelected + 16).map((row, vi) => {\n const i = Math.max(0, safeSelected - 8) + vi;\n const active = i === safeSelected;\n const isDefault = cfg.defaultDict === row.entry.id;\n return (\n <Box key={row.entry.id}>\n <Box width={2}>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>{active ? '▌ ' : ' '}</Text>\n </Box>\n <Box width={2}>\n <Text color={row.local ? PALETTE.accent : PALETTE.muted}>\n {row.local ? '●' : '○'}\n </Text>\n </Box>\n <Box width={2}>\n <Text color={isDefault ? PALETTE.success : PALETTE.muted}>\n {isDefault ? '★' : ' '}\n </Text>\n </Box>\n <Box flexGrow={1}>\n <Text bold={active} color={active ? PALETTE.text : PALETTE.muted} wrap=\"wrap\">\n {row.entry.name}\n </Text>\n </Box>\n <Box width={6}>\n <Text color={PALETTE.muted}>{String(row.entry.length).padStart(5)}</Text>\n </Box>\n </Box>\n );\n })}\n </Box>\n\n <Box flexDirection=\"column\" width=\"25%\" paddingLeft={1}>\n {current && (\n <>\n <Text bold color={PALETTE.text} wrap=\"wrap\">\n {current.entry.name}\n </Text>\n <Text color={PALETTE.muted}>{current.entry.id}</Text>\n <Box marginTop={1}>\n <Text color={PALETTE.muted} wrap=\"wrap\">\n {current.entry.language} · {current.entry.category}\n </Text>\n </Box>\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{t.dict.wordsLabel(current.entry.length)}</Text>\n </Box>\n {current.entry.description && (\n <Box marginTop={1}>\n <Text color={PALETTE.primary} wrap=\"wrap\">{current.entry.description}</Text>\n </Box>\n )}\n {current.entry.tags.length > 0 && (\n <Box marginTop={1}>\n <Text color={PALETTE.muted} wrap=\"wrap\">{t.dict.tagsLabel(current.entry.tags.join(', '))}</Text>\n </Box>\n )}\n <Box marginTop={1}>\n <Text color={current.local ? PALETTE.accent : PALETTE.muted}>\n {current.local ? t.dict.local : t.dict.notLocal}\n </Text>\n </Box>\n {cfg.defaultDict === current.entry.id && (\n <Box>\n <Text color={PALETTE.success}>{t.dict.defaultMark}</Text>\n </Box>\n )}\n </>\n )}\n </Box>\n </Box>\n\n {pending && (\n <Box marginTop={1}>\n {pending.kind === 'pulling' && (\n <Text color={PALETTE.warning}>{t.dict.pulling(pending.id)}</Text>\n )}\n {pending.kind === 'removing' && (\n <Text color={PALETTE.warning}>{t.dict.removing(pending.id)}</Text>\n )}\n {pending.kind === 'error' && (\n <Text color={PALETTE.error}>{t.dict.errorOn(pending.id, pending.msg)}</Text>\n )}\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{t.dict.footer}</Text>\n </Box>\n </Box>\n );\n}\n","import { useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { useNav } from '../nav.js';\nimport { useAppState } from '../app-state.js';\nimport { useStrings } from '../../i18n/context.js';\nimport { setByPath, type Config } from '../../infra/config-store.js';\nimport { PALETTE } from '../components/BigWord.js';\nimport { visibleWidth } from '../../util/text.js';\nimport type { Strings } from '../../i18n/strings.js';\n\ntype FieldSpec =\n | { kind: 'enum'; path: string; labelKey: keyof Strings['config']['fields']; options: string[] }\n | { kind: 'bool'; path: string; labelKey: keyof Strings['config']['fields'] }\n | { kind: 'int'; path: string; labelKey: keyof Strings['config']['fields']; min: number; max: number }\n | { kind: 'string'; path: string; labelKey: keyof Strings['config']['fields'] }\n | { kind: 'dictRef'; path: 'defaultDict'; labelKey: keyof Strings['config']['fields'] };\n\nconst FIELDS: FieldSpec[] = [\n { kind: 'dictRef', path: 'defaultDict', labelKey: 'defaultDict' },\n { kind: 'enum', path: 'defaultMode', labelKey: 'defaultMode', options: ['order', 'dictation', 'review', 'random', 'loop'] },\n { kind: 'enum', path: 'accent', labelKey: 'accent', options: ['us', 'uk'] },\n { kind: 'enum', path: 'language', labelKey: 'language', options: ['auto', 'zh', 'en'] },\n { kind: 'enum', path: 'mirror', labelKey: 'mirror', options: ['jsdelivr', 'github'] },\n { kind: 'int', path: 'chapterSize', labelKey: 'chapterSize', min: 1, max: 200 },\n { kind: 'bool', path: 'autoplayPronunciation', labelKey: 'autoplayPronunciation' },\n { kind: 'bool', path: 'sounds.master', labelKey: 'soundsMaster' },\n { kind: 'bool', path: 'sounds.keystroke', labelKey: 'soundsKeystroke' },\n { kind: 'bool', path: 'sounds.feedback', labelKey: 'soundsFeedback' },\n { kind: 'string', path: 'sounds.keySoundName', labelKey: 'soundsKeySound' },\n];\n\nfunction getByPath(cfg: Config, path: string): unknown {\n return path.split('.').reduce<unknown>((acc, k) => {\n if (acc && typeof acc === 'object') return (acc as Record<string, unknown>)[k];\n return undefined;\n }, cfg);\n}\n\nexport function ConfigEditor() {\n const nav = useNav();\n const { cfg, setCfg } = useAppState();\n const t = useStrings();\n const [selected, setSelected] = useState(0);\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState('');\n const [error, setError] = useState<string | null>(null);\n\n const field = FIELDS[selected]!;\n const currentValue = getByPath(cfg, field.path);\n\n const commit = async (raw: string) => {\n try {\n const next = setByPath(cfg, field.path, raw);\n await setCfg(next);\n setEditing(false);\n setError(null);\n } catch (err) {\n setError((err as Error).message);\n }\n };\n\n useInput((input, key) => {\n if (editing && field.kind === 'string') {\n if (key.escape) {\n setEditing(false);\n setError(null);\n return;\n }\n if (key.return) {\n void commit(draft);\n return;\n }\n if (key.backspace || key.delete) {\n setDraft((d) => d.slice(0, -1));\n return;\n }\n if (input && !key.ctrl && !key.meta) setDraft((d) => d + input);\n return;\n }\n if (editing && field.kind === 'int') {\n if (key.escape) {\n setEditing(false);\n setError(null);\n return;\n }\n if (key.return) {\n void commit(draft);\n return;\n }\n if (key.backspace || key.delete) {\n setDraft((d) => d.slice(0, -1));\n return;\n }\n if (/^[0-9]$/.test(input)) setDraft((d) => d + input);\n return;\n }\n\n if (key.escape || input === 'b') {\n nav.back();\n return;\n }\n if (key.upArrow) {\n setSelected((i) => (i - 1 + FIELDS.length) % FIELDS.length);\n setError(null);\n return;\n }\n if (key.downArrow) {\n setSelected((i) => (i + 1) % FIELDS.length);\n setError(null);\n return;\n }\n if (field.kind === 'bool' && (input === ' ' || key.return)) {\n void commit(currentValue ? 'false' : 'true');\n return;\n }\n if (field.kind === 'enum' && (key.leftArrow || key.rightArrow)) {\n const idx = field.options.indexOf(String(currentValue));\n const delta = key.rightArrow ? 1 : -1;\n const next = field.options[(idx + delta + field.options.length) % field.options.length]!;\n void commit(next);\n return;\n }\n if (field.kind === 'dictRef' && key.return) {\n nav.navigate({ name: 'dict', params: { pickerMode: 'set-default' } });\n return;\n }\n if ((field.kind === 'string' || field.kind === 'int') && key.return) {\n setDraft(String(currentValue ?? ''));\n setEditing(true);\n setError(null);\n }\n });\n\n const labelW = Math.max(...FIELDS.map((f) => visibleWidth(t.config.fields[f.labelKey]))) + 4;\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <Text bold color={PALETTE.accent}>\n {t.config.title}\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\" flexGrow={1}>\n {FIELDS.map((f, i) => {\n const active = i === selected;\n const value = getByPath(cfg, f.path);\n const display = renderValue(f, value, active && editing ? draft : null, t);\n const label = t.config.fields[f.labelKey];\n const pad = ' '.repeat(Math.max(0, labelW - visibleWidth(label)));\n return (\n <Box key={f.path}>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>{active ? '▌ ' : ' '}</Text>\n <Text bold={active} color={active ? PALETTE.text : PALETTE.muted}>\n {label}\n {pad}\n </Text>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>{display}</Text>\n </Box>\n );\n })}\n </Box>\n\n {error && (\n <Box marginTop={1}>\n <Text color={PALETTE.error}>! {error}</Text>\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{hintFor(field, editing, t)}</Text>\n </Box>\n </Box>\n );\n}\n\nfunction renderValue(field: FieldSpec, value: unknown, draft: string | null, t: Strings): string {\n if (draft !== null) return `${draft}_`;\n if (field.kind === 'bool') return value ? `✓ ${t.common.on}` : `✗ ${t.common.off}`;\n if (field.kind === 'dictRef') return String(value ?? '—');\n if (field.kind === 'enum') return `< ${value} >`;\n return String(value ?? '');\n}\n\nfunction hintFor(field: FieldSpec, editing: boolean, t: Strings): string {\n if (editing) return t.config.hints.editing;\n if (field.kind === 'bool') return t.config.hints.bool;\n if (field.kind === 'enum') return t.config.hints.enum;\n if (field.kind === 'dictRef') return t.config.hints.dictRef;\n return t.config.hints.stringOrInt;\n}\n","import { useEffect, useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { useNav } from '../nav.js';\nimport { useStrings } from '../../i18n/context.js';\nimport { PALETTE } from '../components/BigWord.js';\nimport {\n loadSessions,\n computeWPM,\n accuracy,\n dailyBuckets,\n sparkline,\n dailyStreak,\n type SessionRecord,\n} from '../../domain/stats.js';\nimport { loadMistakes, topN, type MistakeBook } from '../../domain/mistakes.js';\n\nconst DAY_WINDOWS = [7, 14, 30, 90];\n\nexport function StatsViewer() {\n const nav = useNav();\n const t = useStrings();\n const [sessions, setSessions] = useState<SessionRecord[] | null>(null);\n const [book, setBook] = useState<MistakeBook | null>(null);\n const [windowIdx, setWindowIdx] = useState(1);\n\n useEffect(() => {\n void (async () => {\n const [s, b] = await Promise.all([loadSessions(), loadMistakes()]);\n setSessions(s);\n setBook(b);\n })();\n }, []);\n\n useInput((input, key) => {\n if (key.escape || input === 'b' || input === 'q') {\n nav.back();\n return;\n }\n if (input === 'n') setWindowIdx((i) => (i + 1) % DAY_WINDOWS.length);\n if (input === 'N') setWindowIdx((i) => (i - 1 + DAY_WINDOWS.length) % DAY_WINDOWS.length);\n });\n\n if (!sessions || !book) {\n return (\n <Box alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.muted}>{t.stats.loading}</Text>\n </Box>\n );\n }\n\n if (sessions.length === 0) {\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.muted}>{t.stats.none}</Text>\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{t.stats.nonePractice}</Text>\n </Box>\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>[q] {t.common.back}</Text>\n </Box>\n </Box>\n );\n }\n\n const days = DAY_WINDOWS[windowIdx]!;\n const buckets = dailyBuckets(sessions, days);\n const streak = dailyStreak(sessions);\n const totalWords = sessions.reduce((a, s) => a + s.wordCount, 0);\n const totalErrors = sessions.reduce((a, s) => a + s.errors, 0);\n const totalMs = sessions.reduce((a, s) => a + s.durationMs, 0);\n const firstTryWords = sessions.reduce(\n (a, s) => a + (s.wordCount - Object.keys(s.perWordErrors).length),\n 0,\n );\n const overallWpm = totalMs > 0 ? Math.round((totalWords / (totalMs / 60000)) * 10) / 10 : 0;\n const overallAcc = totalWords === 0 ? 1 : firstTryWords / totalWords;\n\n const recent = sessions.slice(-5).reverse();\n const top = topN(book, 8);\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <Text bold color={PALETTE.accent}>\n {t.stats.title}\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text color={PALETTE.muted}>{t.stats.lifetime}</Text>\n <Box marginTop={1}>\n <Stat label={t.stats.sessions} value={String(sessions.length)} />\n <Stat label={t.stats.words} value={String(totalWords)} />\n <Stat label={t.stats.errors} value={String(totalErrors)} />\n <Stat label={t.stats.wpm} value={String(overallWpm)} accent />\n <Stat label={t.stats.accuracy} value={`${Math.round(overallAcc * 1000) / 10}%`} accent />\n <Stat label={t.stats.streak} value={`${streak}d`} accent />\n </Box>\n </Box>\n\n <Box marginTop={2} flexDirection=\"column\">\n <Text color={PALETTE.muted}>{t.stats.last(days)}</Text>\n <Box marginTop={1} flexDirection=\"column\">\n <Box>\n <Text color={PALETTE.muted}>{t.stats.wpm.padEnd(10)}</Text>\n <Text color={PALETTE.accent}>{sparkline(buckets.map((b) => b.wpm))}</Text>\n <Text color={PALETTE.muted}> max {Math.round(Math.max(...buckets.map((b) => b.wpm)))}</Text>\n </Box>\n <Box>\n <Text color={PALETTE.muted}>{t.stats.accuracy.padEnd(10)}</Text>\n <Text color={PALETTE.accent}>{sparkline(buckets.map((b) => b.accuracy * 100))}</Text>\n </Box>\n <Box>\n <Text color={PALETTE.muted}>{t.stats.sessions.padEnd(10)}</Text>\n <Text color={PALETTE.accent}>{sparkline(buckets.map((b) => b.sessions))}</Text>\n </Box>\n </Box>\n </Box>\n\n <Box marginTop={2} flexDirection=\"column\">\n <Text color={PALETTE.muted}>{t.stats.recent}</Text>\n {recent.map((s, i) => (\n <Box key={i}>\n <Text color={PALETTE.muted}> {s.ts.replace('T', ' ').slice(0, 16)} </Text>\n <Text color={PALETTE.text}>{s.dictId.padEnd(14)}</Text>\n <Text color={PALETTE.muted}>\n {' '}ch{String(s.chapter + 1).padStart(3)} {s.mode.padEnd(9)} {String(s.wordCount).padStart(3)}w {s.errors}err {computeWPM(s)}wpm {Math.round(accuracy(s) * 1000) / 10}%\n </Text>\n </Box>\n ))}\n </Box>\n\n {top.length > 0 && (\n <Box marginTop={2} flexDirection=\"column\">\n <Text color={PALETTE.muted}>{t.stats.topMistakes}</Text>\n {top.map(([word, entry]) => (\n <Box key={word}>\n <Text color={PALETTE.error}> {String(entry.count).padStart(3)} </Text>\n <Text color={PALETTE.text}>{word.padEnd(20)}</Text>\n <Text color={PALETTE.muted}>{entry.dictIds.join(', ')}</Text>\n </Box>\n ))}\n </Box>\n )}\n\n <Box flexGrow={1} />\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{t.stats.footer}</Text>\n </Box>\n </Box>\n );\n}\n\nfunction Stat({ label, value, accent = false }: { label: string; value: string; accent?: boolean }) {\n return (\n <Box marginRight={3}>\n <Text color={PALETTE.muted}>{label} </Text>\n <Text bold color={accent ? PALETTE.accent : PALETTE.text}>\n {value}\n </Text>\n </Box>\n );\n}\n","import { useEffect, useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { useNav } from '../nav.js';\nimport { useStrings } from '../../i18n/context.js';\nimport { PALETTE } from '../components/BigWord.js';\nimport { readdir } from 'node:fs/promises';\nimport { paths } from '../../infra/paths.js';\nimport { loadLocalDictionary } from '../../infra/dict-downloader.js';\nimport { loadMistakes, type MistakeBook } from '../../domain/mistakes.js';\nimport type { Word } from '../../domain/dictionary.js';\n\ntype Hit = { dictId: string; word: Word };\n\nasync function listLocalDictIds(): Promise<string[]> {\n try {\n const files = await readdir(paths.dictsDir);\n return files\n .filter((f) => f.endsWith('.json') && !f.endsWith('.meta.json'))\n .map((f) => f.replace(/\\.json$/, ''));\n } catch {\n return [];\n }\n}\n\nexport function WordLookup() {\n const nav = useNav();\n const t = useStrings();\n const [query, setQuery] = useState('');\n const [allWords, setAllWords] = useState<Hit[]>([]);\n const [book, setBook] = useState<MistakeBook>({});\n const [loading, setLoading] = useState(true);\n const [selected, setSelected] = useState(0);\n\n useEffect(() => {\n void (async () => {\n const ids = await listLocalDictIds();\n const collected: Hit[] = [];\n for (const id of ids) {\n const words = await loadLocalDictionary(id);\n if (!words) continue;\n for (const w of words) collected.push({ dictId: id, word: w });\n }\n setAllWords(collected);\n setBook(await loadMistakes());\n setLoading(false);\n })();\n }, []);\n\n const q = query.toLowerCase().trim();\n const filtered = q\n ? allWords.filter((h) => h.word.name.toLowerCase().includes(q)).slice(0, 50)\n : [];\n\n useInput((input, key) => {\n if (key.escape) {\n nav.back();\n return;\n }\n if (key.upArrow) {\n setSelected((i) => Math.max(0, i - 1));\n return;\n }\n if (key.downArrow) {\n setSelected((i) => Math.min(filtered.length - 1, i + 1));\n return;\n }\n if (key.backspace || key.delete) {\n setQuery((s) => s.slice(0, -1));\n setSelected(0);\n return;\n }\n if (input && !key.ctrl && !key.meta && input.trim().length > 0) {\n setQuery((s) => s + input);\n setSelected(0);\n }\n });\n\n if (loading) {\n return (\n <Box alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.muted}>{t.word.indexing}</Text>\n </Box>\n );\n }\n\n if (allWords.length === 0) {\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.muted}>{t.word.none}</Text>\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{t.word.pullFirst}</Text>\n </Box>\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>[Esc] {t.common.back}</Text>\n </Box>\n </Box>\n );\n }\n\n const current = filtered[selected];\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <Box>\n <Text bold color={PALETTE.accent}>{t.word.title}</Text>\n <Box flexGrow={1} />\n <Text color={PALETTE.muted}>{t.word.countAcross(allWords.length)}</Text>\n </Box>\n\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{'> '}</Text>\n <Text color={PALETTE.text}>{query}</Text>\n <Text color={PALETTE.accent}>_</Text>\n </Box>\n\n <Box marginTop={1} flexGrow={1}>\n <Box flexDirection=\"column\" width=\"40%\">\n {filtered.map((h, i) => {\n const active = i === selected;\n return (\n <Box key={`${h.dictId}-${h.word.name}-${i}`}>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>{active ? '▌ ' : ' '}</Text>\n <Text bold={active} color={active ? PALETTE.text : PALETTE.muted}>\n {h.word.name.padEnd(20)}\n </Text>\n <Text color={PALETTE.muted}>{h.dictId}</Text>\n </Box>\n );\n })}\n {filtered.length === 0 && q && (\n <Text color={PALETTE.muted}>{t.word.noMatches(query)}</Text>\n )}\n </Box>\n\n <Box flexDirection=\"column\" width=\"60%\" paddingLeft={2}>\n {current && (\n <>\n <Text bold color={PALETTE.text}>{current.word.name}</Text>\n <Box marginTop={1}>\n {current.word.usphone && (\n <Text color={PALETTE.muted}>US /{current.word.usphone}/ </Text>\n )}\n {current.word.ukphone && (\n <Text color={PALETTE.muted}>UK /{current.word.ukphone}/</Text>\n )}\n </Box>\n <Box marginTop={1} flexDirection=\"column\">\n {(current.word.trans ?? []).map((tr, i) => (\n <Text key={i} color={PALETTE.primary}>· {tr}</Text>\n ))}\n </Box>\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{t.word.inDict(current.dictId)}</Text>\n </Box>\n {book[current.word.name] && (\n <Box marginTop={1}>\n <Text color={PALETTE.error}>\n {t.word.mistakes(book[current.word.name]!.count, book[current.word.name]!.lastSeen.slice(0, 10))}\n </Text>\n </Box>\n )}\n </>\n )}\n </Box>\n </Box>\n\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{t.word.footer}</Text>\n </Box>\n </Box>\n );\n}\n","import chalk from 'chalk';\nimport type { SessionReport } from '../infra/session-tracker.js';\nimport type { Strings } from '../i18n/strings.js';\nimport { visibleWidth } from './text.js';\n\nconst LEAVE_ALTSCREEN = '\\x1b[?25h\\x1b[?1049l';\n\nexport function ensureMainScreen(): void {\n if (process.stdout.isTTY) process.stdout.write(LEAVE_ALTSCREEN);\n}\n\nfunction fmtDuration(ms: number, lang: 'zh' | 'en'): string {\n const total = Math.floor(ms / 1000);\n const m = Math.floor(total / 60);\n const s = total % 60;\n if (lang === 'zh') {\n if (m === 0) return `${s} 秒`;\n return `${m} 分 ${s} 秒`;\n }\n if (m === 0) return `${s}s`;\n return `${m}m ${s}s`;\n}\n\nexport function printSessionReport(r: SessionReport, t: Strings, lang: 'zh' | 'en'): void {\n if (r.chaptersCompleted === 0) return;\n const accPct = Math.round(r.accuracy * 1000) / 10;\n const labels = [\n t.report.duration,\n t.report.practiced,\n t.report.chapters,\n t.report.words,\n t.report.accuracy,\n t.report.wpm,\n ];\n if (r.newMistakeWords > 0) labels.push(t.report.newMistakes);\n const labelW = Math.max(...labels.map(visibleWidth)) + 2;\n const pad = (label: string) =>\n label + ' '.repeat(Math.max(0, labelW - visibleWidth(label)));\n\n console.log();\n console.log(chalk.bold.cyan(t.report.title));\n console.log(` ${chalk.dim(pad(t.report.duration))} ${fmtDuration(r.totalDurationMs, lang)}`);\n console.log(` ${chalk.dim(pad(t.report.practiced))} ${fmtDuration(r.practiceMs, lang)}`);\n console.log(` ${chalk.dim(pad(t.report.chapters))} ${r.chaptersCompleted}`);\n console.log(` ${chalk.dim(pad(t.report.words))} ${r.wordCount}`);\n console.log(` ${chalk.dim(pad(t.report.accuracy))} ${accPct}%`);\n console.log(` ${chalk.dim(pad(t.report.wpm))} ${r.wpm}`);\n if (r.newMistakeWords > 0) {\n console.log(` ${chalk.dim(pad(t.report.newMistakes))} ${r.newMistakeWords}`);\n }\n console.log();\n console.log(chalk.dim(` ${t.report.farewell}`));\n console.log();\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { loadSessions, computeWPM, accuracy, dailyBuckets, sparkline, dailyStreak } from '../domain/stats.js';\nimport { loadMistakes, topN } from '../domain/mistakes.js';\n\nexport function buildStatsCommand(): Command {\n return new Command('stats')\n .description('Show practice history and trends')\n .option('-d, --days <n>', 'window size for trend (default 14)', '14')\n .option('--top <n>', 'how many top mistakes to show (default 10)', '10')\n .action(async (opts: { days: string; top: string }) => {\n const days = Math.max(1, Number(opts.days) || 14);\n const topCount = Math.max(1, Number(opts.top) || 10);\n const sessions = await loadSessions();\n const book = await loadMistakes();\n\n if (sessions.length === 0) {\n console.log(chalk.yellow('No practice history yet. Run `qwerty practice <dict>` to get started.'));\n return;\n }\n\n const buckets = dailyBuckets(sessions, days);\n const streak = dailyStreak(sessions);\n const totalWords = sessions.reduce((a, s) => a + s.wordCount, 0);\n const totalErrors = sessions.reduce((a, s) => a + s.errors, 0);\n const totalMs = sessions.reduce((a, s) => a + s.durationMs, 0);\n const firstTryWords = sessions.reduce(\n (a, s) => a + (s.wordCount - Object.keys(s.perWordErrors).length),\n 0,\n );\n const overallWpm = totalMs > 0 ? Math.round((totalWords / (totalMs / 60000)) * 10) / 10 : 0;\n const overallAcc = totalWords === 0 ? 1 : firstTryWords / totalWords;\n\n console.log(chalk.bold('\\nLifetime'));\n console.log(` ${chalk.dim('sessions')} ${sessions.length} ${chalk.dim('words')} ${totalWords} ${chalk.dim('errors')} ${totalErrors}`);\n console.log(` ${chalk.dim('avg wpm')} ${overallWpm} ${chalk.dim('avg accuracy')} ${Math.round(overallAcc * 1000) / 10}% ${chalk.dim('streak')} ${chalk.bold(streak)}d`);\n\n console.log(chalk.bold(`\\nLast ${days} days`));\n console.log(` ${chalk.dim('wpm ')} ${sparkline(buckets.map((b) => b.wpm))} ${chalk.dim('max')} ${Math.round(Math.max(...buckets.map((b) => b.wpm)))}`);\n console.log(` ${chalk.dim('accuracy')} ${sparkline(buckets.map((b) => b.accuracy * 100))} ${chalk.dim('range')} ${Math.round(Math.min(...buckets.map((b) => b.accuracy * 100)))}-${Math.round(Math.max(...buckets.map((b) => b.accuracy * 100)))}%`);\n console.log(` ${chalk.dim('sessions')} ${sparkline(buckets.map((b) => b.sessions))}`);\n\n const recent = sessions.slice(-5).reverse();\n console.log(chalk.bold('\\nLast 5 sessions'));\n for (const s of recent) {\n const wpm = computeWPM(s);\n const acc = Math.round(accuracy(s) * 1000) / 10;\n console.log(\n ` ${chalk.dim(s.ts.replace('T', ' ').slice(0, 16))} ${chalk.cyan(s.dictId.padEnd(14))} ch${String(s.chapter + 1).padStart(3)} ${s.mode.padEnd(9)} ${String(s.wordCount).padStart(3)}w ${s.errors}err ${wpm}wpm ${acc}%`,\n );\n }\n\n const top = topN(book, topCount);\n if (top.length > 0) {\n console.log(chalk.bold(`\\nTop ${top.length} mistakes`));\n for (const [word, entry] of top) {\n console.log(` ${chalk.red(String(entry.count).padStart(3))} ${chalk.bold(word.padEnd(20))} ${chalk.dim(entry.dictIds.join(', '))}`);\n }\n } else {\n console.log(chalk.bold('\\nTop mistakes'));\n console.log(chalk.dim(' none — keep going'));\n }\n console.log();\n });\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { readdir } from 'node:fs/promises';\nimport { paths } from '../infra/paths.js';\nimport { loadLocalDictionary } from '../infra/dict-downloader.js';\nimport { loadMistakes } from '../domain/mistakes.js';\nimport { findEntry } from '../infra/registry-store.js';\nimport type { Word } from '../domain/dictionary.js';\n\nasync function listLocalDictIds(): Promise<string[]> {\n try {\n const files = await readdir(paths.dictsDir);\n return files\n .filter((f) => f.endsWith('.json') && !f.endsWith('.meta.json'))\n .map((f) => f.replace(/\\.json$/, ''));\n } catch {\n return [];\n }\n}\n\nexport function buildWordCommand(): Command {\n return new Command('word')\n .argument('<keyword>')\n .description('Look up a word across local dictionaries')\n .option('--exact', 'require exact (case-insensitive) match')\n .action(async (keyword: string, opts: { exact?: boolean }) => {\n const q = keyword.toLowerCase();\n const ids = await listLocalDictIds();\n if (ids.length === 0) {\n console.log(chalk.yellow('No local dictionaries. Run `qwerty dict pull <id>` first.'));\n return;\n }\n\n type Hit = { dictId: string; word: Word };\n const hits: Hit[] = [];\n for (const id of ids) {\n const words = await loadLocalDictionary(id);\n if (!words) continue;\n for (const w of words) {\n const wl = w.name.toLowerCase();\n const match = opts.exact ? wl === q : wl.includes(q);\n if (match) hits.push({ dictId: id, word: w });\n }\n }\n\n if (hits.length === 0) {\n console.log(chalk.yellow(`No matches for \"${keyword}\" in ${ids.length} local dictionaries`));\n return;\n }\n\n // Group hits by word name; one block per distinct word.\n const byName = new Map<string, Hit[]>();\n for (const h of hits) {\n const arr = byName.get(h.word.name) ?? [];\n arr.push(h);\n byName.set(h.word.name, arr);\n }\n\n const book = await loadMistakes();\n for (const [name, group] of byName) {\n const first = group[0]!.word;\n console.log();\n console.log(chalk.bold.white(name));\n const us = first.usphone ? `US /${first.usphone}/` : '';\n const uk = first.ukphone ? `UK /${first.ukphone}/` : '';\n if (us || uk) console.log(chalk.dim(` ${[us, uk].filter(Boolean).join(' ')}`));\n for (const t of first.trans ?? []) console.log(chalk.cyan(` · ${t}`));\n const sources = await Promise.all(\n group.map(async (h) => {\n const reg = await findEntry(h.dictId);\n return reg?.name ?? h.dictId;\n }),\n );\n console.log(chalk.dim(` in: ${sources.join(', ')}`));\n const mistake = book[name];\n if (mistake) {\n console.log(chalk.dim(` mistakes: ${mistake.count} (last ${mistake.lastSeen.slice(0, 10)})`));\n }\n }\n console.log();\n });\n}\n","import { render } from 'ink';\nimport { createElement } from 'react';\nimport { loadConfig } from '../infra/config-store.js';\nimport { App } from '../ui/App.js';\nimport { start as startSession, report as sessionReport } from '../infra/session-tracker.js';\nimport { printSessionReport, ensureMainScreen } from '../util/report.js';\nimport { pickStrings } from '../i18n/context.js';\n\nexport async function runMainMenu(): Promise<void> {\n if (!process.stdout.isTTY) {\n console.log('qwerty-cli — run `qwerty --help` for available commands.');\n return;\n }\n const cfg = await loadConfig();\n startSession();\n const { waitUntilExit } = render(\n createElement(App, { initial: { name: 'main' }, initialCfg: cfg }),\n { patchConsole: false, exitOnCtrlC: false },\n );\n await waitUntilExit();\n ensureMainScreen();\n const { lang, t } = pickStrings(cfg.language);\n printSessionReport(sessionReport(), t, lang);\n}\n"],"mappings":"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","names":["Command","mkdir","Command","chalk","z","readFile","join","parsed","readFile","join","chalk","Command","Command","chalk","useRef","useApp","useInput","useState","jsx","createContext","useContext","useEffect","useState","mkdir","rename","writeFile","join","dirname","request","resolve","join","mkdir","dirname","request","writeFile","rename","jsx","createContext","useState","useEffect","useContext","createContext","useCallback","useContext","useState","jsx","createContext","useState","useCallback","useContext","createContext","useContext","jsx","createContext","useContext","useState","Box","Text","Box","useStdout","jsx","visibleWidth","jsx","jsxs","useState","visibleWidth","Box","Text","useState","useEffect","useRef","Box","Text","useApp","useInput","state","state","z","z","useEffect","useState","useInput","useApp","state","useState","useApp","useInput","useEffect","useEffect","useRef","useRef","useEffect","useCallback","z","z","accuracy","useCallback","jsx","jsxs","useState","useEffect","useApp","useRef","useInput","Box","Text","useEffect","useState","Box","Text","useInput","jsx","jsxs","useState","useEffect","useInput","Box","Text","useState","Box","Text","useInput","jsx","jsxs","getByPath","useState","useInput","visibleWidth","Box","Text","useEffect","useState","Box","Text","useInput","jsx","jsxs","useState","useEffect","useInput","Box","Text","useEffect","useState","Box","Text","useInput","Fragment","jsx","jsxs","useState","useEffect","useInput","Box","Text","jsx","useApp","useRef","useInput","key","chalk","visibleWidth","chalk","chalk","Command","Command","chalk","Command","chalk","Command","chalk","readdir","listLocalDictIds","readdir","Command","chalk","render","createElement","render","createElement","Command"]}
1
+ {"version":3,"sources":["../src/cli.ts","../package.json","../src/commands/config.ts","../src/infra/config-store.ts","../src/infra/paths.ts","../src/infra/fs-store.ts","../src/commands/dict.ts","../src/domain/dictionary.ts","../src/infra/registry-store.ts","../src/infra/dict-downloader.ts","../src/commands/practice.ts","../src/ui/App.tsx","../src/ui/nav.tsx","../src/ui/Fullscreen.tsx","../src/ui/audio-context.tsx","../src/infra/audio.ts","../src/ui/app-state.tsx","../src/i18n/context.tsx","../src/i18n/strings.ts","../src/i18n/locale.ts","../src/ui/registry-context.tsx","../src/ui/screens/MainMenu.tsx","../src/ui/components/BigWord.tsx","../src/util/text.ts","../src/util/dict-name.ts","../src/ui/screens/PracticeScreen.tsx","../src/util/shuffle.ts","../src/domain/chapters.ts","../src/domain/input-buffer.ts","../src/domain/session.ts","../src/domain/mistakes.ts","../src/ui/hooks/useWordLoop.ts","../src/ui/hooks/useAudio.ts","../src/ui/hooks/useSessionPersistence.ts","../src/domain/stats.ts","../src/infra/session-tracker.ts","../src/ui/screens/StealthPracticeLayout.tsx","../src/ui/screens/DictBrowser.tsx","../src/ui/components/ActionPanel.tsx","../src/ui/screens/ConfigEditor.tsx","../src/ui/screens/StatsViewer.tsx","../src/ui/screens/WordLookup.tsx","../src/ui/screens/HelpScreen.tsx","../src/util/report.ts","../src/commands/stats.ts","../src/commands/word.ts","../src/commands/stealth.ts","../src/commands/menu.ts"],"sourcesContent":["import { Command } from 'commander';\nimport pkg from '../package.json' with { type: 'json' };\nimport { buildConfigCommand } from './commands/config.js';\nimport { buildDictCommand } from './commands/dict.js';\nimport { buildPracticeCommand } from './commands/practice.js';\nimport { buildStatsCommand } from './commands/stats.js';\nimport { buildWordCommand } from './commands/word.js';\nimport { buildStealthCommand } from './commands/stealth.js';\nimport { runMainMenu } from './commands/menu.js';\n\nconst program = new Command();\n\nprogram\n .name('qwerty')\n .description('Terminal clone of qwerty-learner — typing practice for English vocabulary')\n .version(pkg.version);\n\nprogram.addCommand(buildPracticeCommand());\nprogram.addCommand(buildStealthCommand());\nprogram.addCommand(buildDictCommand());\nprogram.addCommand(buildWordCommand());\nprogram.addCommand(buildStatsCommand());\nprogram.addCommand(buildConfigCommand());\n\nprogram.action(async () => {\n await runMainMenu();\n});\n\nprogram.parseAsync(process.argv).catch((err) => {\n console.error(err instanceof Error ? err.message : err);\n process.exit(1);\n});\n","{\n \"name\": \"qwerty-cli\",\n \"version\": \"0.0.1-alpha.7\",\n \"description\": \"Terminal clone of qwerty-learner: typing practice for English vocabulary, with chapters, dictation, mistake book, and audio.\",\n \"type\": \"module\",\n \"bin\": {\n \"qwerty\": \"bin/qwerty.mjs\"\n },\n \"files\": [\n \"dist\",\n \"bin\",\n \"assets\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"sync-registry\": \"tsx scripts/sync-registry.ts\",\n \"prepublishOnly\": \"pnpm build\"\n },\n \"engines\": {\n \"node\": \">=20\"\n },\n \"keywords\": [\n \"qwerty\",\n \"typing\",\n \"cli\",\n \"vocabulary\",\n \"ink\",\n \"terminal\"\n ],\n \"license\": \"MIT\",\n \"dependencies\": {\n \"chalk\": \"^5.3.0\",\n \"commander\": \"^12.1.0\",\n \"ink\": \"^5.0.1\",\n \"p-queue\": \"^8.0.1\",\n \"react\": \"^18.3.1\",\n \"undici\": \"^6.19.8\",\n \"zod\": \"^3.23.8\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.14.10\",\n \"@types/react\": \"^18.3.3\",\n \"ts-morph\": \"^23.0.0\",\n \"tsup\": \"^8.2.4\",\n \"tsx\": \"^4.19.0\",\n \"typescript\": \"^5.5.4\",\n \"vitest\": \"^2.0.5\"\n },\n \"pnpm\": {\n \"onlyBuiltDependencies\": [\n \"esbuild\"\n ]\n }\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { loadConfig, saveConfig, getByPath, setByPath } from '../infra/config-store.js';\n\nexport function buildConfigCommand(): Command {\n const cmd = new Command('config').description('Manage CLI configuration');\n\n cmd\n .command('list')\n .description('Show the effective merged config')\n .action(async () => {\n const cfg = await loadConfig();\n console.log(JSON.stringify(cfg, null, 2));\n });\n\n cmd\n .command('get <key>')\n .description('Get a config value by dotted path (e.g. sounds.keystroke)')\n .action(async (key: string) => {\n const cfg = await loadConfig();\n const v = getByPath(cfg, key);\n if (v === undefined) {\n console.error(chalk.red(`Key not found: ${key}`));\n process.exitCode = 1;\n return;\n }\n console.log(typeof v === 'string' ? v : JSON.stringify(v));\n });\n\n cmd\n .command('set <key> <value>')\n .description('Set a config value by dotted path')\n .action(async (key: string, value: string) => {\n const cfg = await loadConfig();\n const next = setByPath(cfg, key, value);\n await saveConfig(next);\n console.log(chalk.green(`Set ${key} = ${value}`));\n });\n\n return cmd;\n}\n","import { z } from 'zod';\nimport { paths } from './paths.js';\nimport { readJson, writeJsonAtomic } from './fs-store.js';\n\nexport const ConfigSchema = z.object({\n mirror: z.enum(['jsdelivr', 'github']).default('jsdelivr'),\n accent: z.enum(['us', 'uk']).default('us'),\n chapterSize: z.number().int().positive().max(200).default(20),\n sounds: z\n .object({\n master: z.boolean().default(true),\n keystroke: z.boolean().default(true),\n feedback: z.boolean().default(true),\n keySoundName: z.string().default('default'),\n })\n .default({ master: true, keystroke: true, feedback: true, keySoundName: 'default' }),\n autoplayPronunciation: z.boolean().default(true),\n defaultMode: z.enum(['order', 'dictation', 'review', 'random', 'loop']).default('order'),\n defaultDict: z.string().optional(),\n language: z.enum(['auto', 'zh', 'en']).default('auto'),\n stealth: z.enum(['off', 'menu', 'default']).default('off'),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n\nconst DEFAULTS: Config = ConfigSchema.parse({});\n\nexport async function loadConfig(): Promise<Config> {\n const raw = await readJson<unknown>(paths.config);\n if (!raw) return DEFAULTS;\n const result = ConfigSchema.safeParse(raw);\n if (!result.success) {\n throw new Error(`Invalid config at ${paths.config}: ${result.error.message}`);\n }\n return result.data;\n}\n\nexport async function saveConfig(cfg: Config): Promise<void> {\n await writeJsonAtomic(paths.config, cfg);\n}\n\nexport function getByPath(cfg: Config, path: string): unknown {\n const parts = path.split('.');\n let cur: unknown = cfg;\n for (const p of parts) {\n if (cur === null || typeof cur !== 'object') return undefined;\n cur = (cur as Record<string, unknown>)[p];\n }\n return cur;\n}\n\nexport function setByPath(cfg: Config, path: string, rawValue: string): Config {\n const parts = path.split('.');\n if (parts.length === 0) throw new Error('Empty config key');\n const clone: Record<string, unknown> = JSON.parse(JSON.stringify(cfg));\n let cur: Record<string, unknown> = clone;\n for (let i = 0; i < parts.length - 1; i++) {\n const k = parts[i]!;\n const next = cur[k];\n if (typeof next !== 'object' || next === null) {\n throw new Error(`Cannot set ${path}: ${parts.slice(0, i + 1).join('.')} is not an object`);\n }\n cur = next as Record<string, unknown>;\n }\n const leaf = parts[parts.length - 1]!;\n cur[leaf] = coerce(rawValue);\n const validated = ConfigSchema.safeParse(clone);\n if (!validated.success) {\n throw new Error(`Invalid value for ${path}: ${validated.error.issues[0]?.message ?? 'unknown'}`);\n }\n return validated.data;\n}\n\nfunction coerce(v: string): unknown {\n if (v === 'true') return true;\n if (v === 'false') return false;\n if (v === 'null') return null;\n if (/^-?\\d+$/.test(v)) return Number(v);\n if (/^-?\\d+\\.\\d+$/.test(v)) return Number(v);\n return v;\n}\n","import { homedir } from 'node:os';\nimport { join, resolve } from 'node:path';\nimport { mkdir } from 'node:fs/promises';\nimport { fileURLToPath } from 'node:url';\n\nconst ROOT = join(homedir(), '.qwerty-cli');\n\nexport const paths = {\n root: ROOT,\n config: join(ROOT, 'config.json'),\n registry: join(ROOT, 'registry.json'),\n dictsDir: join(ROOT, 'dicts'),\n dictFile: (id: string) => join(ROOT, 'dicts', `${id}.json`),\n dictMeta: (id: string) => join(ROOT, 'dicts', `${id}.meta.json`),\n stats: join(ROOT, 'stats.jsonl'),\n mistakes: join(ROOT, 'mistakes.json'),\n audioCacheDir: join(ROOT, 'cache', 'audio'),\n audioCache: (word: string, accent: 'us' | 'uk') =>\n join(ROOT, 'cache', 'audio', `${encodeURIComponent(word.toLowerCase())}-${accent}.mp3`),\n};\n\nexport async function ensureDirs(): Promise<void> {\n await mkdir(paths.dictsDir, { recursive: true });\n await mkdir(paths.audioCacheDir, { recursive: true });\n}\n\nexport function packageAssetsDir(): string {\n // Works for both bundled (dist/cli.js) and source (src/infra/paths.ts) layouts:\n // 2 levels up from this file lands at the package root.\n const here = fileURLToPath(import.meta.url);\n return resolve(here, '..', '..', 'assets');\n}\n","import { mkdir, readFile, rename, writeFile, appendFile, access } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { randomBytes } from 'node:crypto';\n\nexport async function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readJson<T>(path: string): Promise<T | null> {\n try {\n const buf = await readFile(path, 'utf8');\n return JSON.parse(buf) as T;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n throw err;\n }\n}\n\nexport async function writeJsonAtomic(path: string, value: unknown): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n const tmp = `${path}.${process.pid}.${randomBytes(4).toString('hex')}.tmp`;\n await writeFile(tmp, JSON.stringify(value, null, 2), 'utf8');\n await rename(tmp, path);\n}\n\nexport async function appendJsonl(path: string, line: unknown): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await appendFile(path, JSON.stringify(line) + '\\n', 'utf8');\n}\n\nexport async function readJsonl<T>(path: string): Promise<T[]> {\n try {\n const buf = await readFile(path, 'utf8');\n return buf\n .split('\\n')\n .filter((l) => l.trim().length > 0)\n .map((l) => JSON.parse(l) as T);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return [];\n throw err;\n }\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { filterRegistry, type DictionaryEntry } from '../domain/dictionary.js';\nimport { loadRegistry } from '../infra/registry-store.js';\nimport {\n pullDictionary,\n importDictionary,\n isLocallyAvailable,\n removeDictionary,\n} from '../infra/dict-downloader.js';\n\nfunction fmtBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n return `${(n / 1024 / 1024).toFixed(2)} MB`;\n}\n\nasync function renderTable(entries: DictionaryEntry[]): Promise<void> {\n const flagged = await Promise.all(\n entries.map(async (e) => ({ entry: e, local: await isLocallyAvailable(e.id) })),\n );\n const widths = {\n local: 3,\n id: Math.max(2, ...flagged.map((f) => f.entry.id.length)),\n name: Math.max(4, ...flagged.map((f) => f.entry.name.length)),\n category: Math.max(8, ...flagged.map((f) => f.entry.category.length)),\n length: Math.max(5, ...flagged.map((f) => String(f.entry.length).length)),\n };\n const pad = (s: string, n: number) => s + ' '.repeat(Math.max(0, n - visibleWidth(s)));\n const header = [\n pad(' ', widths.local),\n chalk.bold(pad('ID', widths.id)),\n chalk.bold(pad('Name', widths.name)),\n chalk.bold(pad('Category', widths.category)),\n chalk.bold(pad('Words', widths.length)),\n chalk.bold('Description'),\n ].join(' ');\n console.log(header);\n for (const { entry, local } of flagged) {\n const mark = local ? chalk.green(' ✓') : ' ';\n console.log(\n [\n pad(mark, widths.local),\n pad(entry.id, widths.id),\n pad(entry.name, widths.name),\n chalk.dim(pad(entry.category, widths.category)),\n pad(String(entry.length), widths.length),\n chalk.dim(entry.description),\n ].join(' '),\n );\n }\n}\n\n// Naive: count CJK as width-2 for alignment.\nfunction visibleWidth(s: string): number {\n let w = 0;\n // strip ansi\n const plain = s.replace(/\\x1b\\[[0-9;]*m/g, '');\n for (const ch of plain) {\n const code = ch.codePointAt(0)!;\n w += code > 0x2e80 && code < 0xfb00 ? 2 : 1;\n }\n return w;\n}\n\nexport function buildDictCommand(): Command {\n const cmd = new Command('dict').description('Manage dictionaries');\n\n cmd\n .command('list')\n .description('List dictionaries (✓ = locally available)')\n .option('-c, --category <category>', 'filter by category')\n .option('--local-only', 'show only locally downloaded dictionaries')\n .action(async (opts: { category?: string; localOnly?: boolean }) => {\n const reg = await loadRegistry();\n let entries = opts.category\n ? reg.filter((e) => e.category === opts.category)\n : reg;\n if (opts.localOnly) {\n const flags = await Promise.all(entries.map((e) => isLocallyAvailable(e.id)));\n entries = entries.filter((_, i) => flags[i]);\n }\n await renderTable(entries);\n console.log(chalk.dim(`\\n${entries.length} dictionaries`));\n });\n\n cmd\n .command('search <keyword>')\n .description('Search the upstream registry by name/description/category/tags')\n .option('-c, --category <category>', 'restrict to category')\n .option('-l, --language <language>', 'restrict to language')\n .action(async (keyword: string, opts: { category?: string; language?: string }) => {\n const reg = await loadRegistry();\n const matches = filterRegistry(reg, keyword, opts);\n if (matches.length === 0) {\n console.log(chalk.yellow(`No dictionaries matched \"${keyword}\"`));\n return;\n }\n await renderTable(matches);\n console.log(chalk.dim(`\\n${matches.length} matches`));\n });\n\n cmd\n .command('pull <id>')\n .description('Download an upstream dictionary into the local cache')\n .action(async (id: string) => {\n try {\n const { words, size } = await pullDictionary(id);\n console.log(chalk.green(`Saved ${words.length} words (${fmtBytes(size)}) → dict ${chalk.bold(id)}`));\n } catch (err) {\n console.error(chalk.red((err as Error).message));\n process.exitCode = 1;\n }\n });\n\n cmd\n .command('import <file>')\n .description('Import a local qwerty-native JSON dictionary')\n .requiredOption('--id <id>', 'dictionary id (lowercase, digits, dashes)')\n .action(async (file: string, opts: { id: string }) => {\n try {\n const { words, size } = await importDictionary(file, opts.id);\n console.log(chalk.green(`Imported ${words.length} words (${fmtBytes(size)}) as ${chalk.bold(opts.id)}`));\n } catch (err) {\n console.error(chalk.red((err as Error).message));\n process.exitCode = 1;\n }\n });\n\n cmd\n .command('rm <id>')\n .description('Remove a local dictionary')\n .action(async (id: string) => {\n const removed = await removeDictionary(id);\n if (removed) console.log(chalk.green(`Removed ${id}`));\n else console.log(chalk.yellow(`Nothing to remove for ${id}`));\n });\n\n return cmd;\n}\n","import { z } from 'zod';\n\nexport const DictionaryEntrySchema = z.object({\n id: z.string(),\n name: z.string(),\n description: z.string().default(''),\n category: z.string().default(''),\n tags: z.array(z.string()).default([]),\n url: z.string(),\n length: z.number().int().nonnegative().default(0),\n language: z.string().default('en'),\n languageCategory: z.string().default('en'),\n defaultPronIndex: z.number().int().optional(),\n});\n\nexport type DictionaryEntry = z.infer<typeof DictionaryEntrySchema>;\n\nexport const RegistrySchema = z.array(DictionaryEntrySchema);\nexport type Registry = DictionaryEntry[];\n\nexport const WordSchema = z\n .object({\n name: z.string(),\n trans: z.array(z.string()).default([]),\n usphone: z.string().optional(),\n ukphone: z.string().optional(),\n notation: z.string().optional(),\n })\n .passthrough();\n\nexport type Word = z.infer<typeof WordSchema>;\n\nexport const WordArraySchema = z.array(WordSchema);\n\nexport function filterRegistry(\n registry: Registry,\n query: string,\n opts: { category?: string; language?: string } = {},\n): Registry {\n const q = query.trim().toLowerCase();\n return registry.filter((d) => {\n if (opts.category && d.category !== opts.category) return false;\n if (opts.language && d.language !== opts.language) return false;\n if (!q) return true;\n return (\n d.id.toLowerCase().includes(q) ||\n d.name.toLowerCase().includes(q) ||\n d.description.toLowerCase().includes(q) ||\n d.category.toLowerCase().includes(q) ||\n d.tags.some((t) => t.toLowerCase().includes(q))\n );\n });\n}\n","import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { RegistrySchema, type Registry, type DictionaryEntry } from '../domain/dictionary.js';\nimport { paths, packageAssetsDir } from './paths.js';\nimport { readJson } from './fs-store.js';\n\nlet cached: Registry | null = null;\n\nexport async function loadRegistry(): Promise<Registry> {\n if (cached) return cached;\n\n const userOverride = await readJson<unknown>(paths.registry);\n if (userOverride) {\n const parsed = RegistrySchema.safeParse(userOverride);\n if (parsed.success) {\n cached = parsed.data;\n return cached;\n }\n console.warn(`Ignoring corrupt user registry at ${paths.registry}: ${parsed.error.message}`);\n }\n\n const bundled = await readFile(join(packageAssetsDir(), 'registry.snapshot.json'), 'utf8');\n const parsed = RegistrySchema.parse(JSON.parse(bundled));\n cached = parsed;\n return cached;\n}\n\nexport async function findEntry(id: string): Promise<DictionaryEntry | undefined> {\n const reg = await loadRegistry();\n return reg.find((d) => d.id === id);\n}\n","import { createHash } from 'node:crypto';\nimport { stat, copyFile } from 'node:fs/promises';\nimport { request } from 'undici';\nimport { WordArraySchema, type Word, type DictionaryEntry } from '../domain/dictionary.js';\nimport { paths, ensureDirs } from './paths.js';\nimport { exists, readJson, writeJsonAtomic } from './fs-store.js';\nimport { findEntry } from './registry-store.js';\nimport { loadConfig } from './config-store.js';\n\nconst JSDELIVR_BASE = 'https://cdn.jsdelivr.net/gh/RealKai42/qwerty-learner@master';\nconst GITHUB_RAW_BASE = 'https://raw.githubusercontent.com/RealKai42/qwerty-learner/master';\n\ntype Meta = { sha256: string; size: number; fetchedAt: string; id: string };\n\nasync function fetchWithRetry(url: string, retries = 2): Promise<string> {\n let lastErr: unknown;\n for (let i = 0; i <= retries; i++) {\n try {\n const res = await request(url, { headersTimeout: 10000, bodyTimeout: 30000 });\n if (res.statusCode >= 400) throw new Error(`HTTP ${res.statusCode}`);\n return await res.body.text();\n } catch (err) {\n lastErr = err;\n if (i < retries) await new Promise((r) => setTimeout(r, 500 * (i + 1)));\n }\n }\n throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));\n}\n\nfunction buildUrls(mirror: 'jsdelivr' | 'github', relUrl: string): string[] {\n // Registry urls are web-relative (\"/dicts/X.json\"); upstream repo serves them\n // from /public/, so prepend that prefix when hitting source mirrors.\n const path = relUrl.startsWith('/') ? relUrl : `/${relUrl}`;\n const repoPath = `/public${path}`;\n const jsd = `${JSDELIVR_BASE}${repoPath}`;\n const gh = `${GITHUB_RAW_BASE}${repoPath}`;\n return mirror === 'jsdelivr' ? [jsd, gh] : [gh, jsd];\n}\n\nexport async function pullDictionary(id: string): Promise<{ words: Word[]; size: number }> {\n const entry = await findEntry(id);\n if (!entry) throw new Error(`Unknown dictionary id: ${id}`);\n const cfg = await loadConfig();\n await ensureDirs();\n\n const urls = buildUrls(cfg.mirror, entry.url);\n let body: string | null = null;\n let lastErr: unknown;\n for (const u of urls) {\n try {\n body = await fetchWithRetry(u);\n break;\n } catch (err) {\n lastErr = err;\n }\n }\n if (!body) {\n throw new Error(\n `Failed to download dictionary ${id} from any mirror: ${lastErr instanceof Error ? lastErr.message : lastErr}`,\n );\n }\n\n let json: unknown;\n try {\n json = JSON.parse(body);\n } catch (err) {\n throw new Error(`Dictionary ${id} is not valid JSON: ${(err as Error).message}`);\n }\n\n const parsed = WordArraySchema.safeParse(json);\n if (!parsed.success) {\n throw new Error(`Dictionary ${id} failed schema validation: ${parsed.error.issues[0]?.message}`);\n }\n\n const sha = createHash('sha256').update(body).digest('hex');\n await writeJsonAtomic(paths.dictFile(id), parsed.data);\n const meta: Meta = { sha256: sha, size: body.length, fetchedAt: new Date().toISOString(), id };\n await writeJsonAtomic(paths.dictMeta(id), meta);\n return { words: parsed.data, size: body.length };\n}\n\nexport async function importDictionary(file: string, id: string): Promise<{ words: Word[]; size: number }> {\n if (!/^[a-z0-9-]+$/.test(id)) {\n throw new Error(`Invalid id \"${id}\". Must match /^[a-z0-9-]+$/`);\n }\n await ensureDirs();\n if (!(await exists(file))) throw new Error(`File not found: ${file}`);\n\n const raw = await readJson<unknown>(file);\n const parsed = WordArraySchema.safeParse(raw);\n if (!parsed.success) {\n throw new Error(`Import rejected: ${parsed.error.issues[0]?.message}`);\n }\n await copyFile(file, paths.dictFile(id));\n const size = (await stat(paths.dictFile(id))).size;\n const sha = createHash('sha256').update(JSON.stringify(parsed.data)).digest('hex');\n const meta: Meta = { sha256: sha, size, fetchedAt: new Date().toISOString(), id };\n await writeJsonAtomic(paths.dictMeta(id), meta);\n return { words: parsed.data, size };\n}\n\nexport async function loadLocalDictionary(id: string): Promise<Word[] | null> {\n const data = await readJson<unknown>(paths.dictFile(id));\n if (!data) return null;\n const parsed = WordArraySchema.safeParse(data);\n if (!parsed.success) throw new Error(`Local dictionary ${id} corrupt: ${parsed.error.message}`);\n return parsed.data;\n}\n\nexport async function isLocallyAvailable(id: string): Promise<boolean> {\n return exists(paths.dictFile(id));\n}\n\nexport async function ensureDictionary(id: string): Promise<Word[]> {\n const local = await loadLocalDictionary(id);\n if (local) return local;\n const { words } = await pullDictionary(id);\n return words;\n}\n\nexport async function removeDictionary(id: string): Promise<boolean> {\n const { unlink } = await import('node:fs/promises');\n let removed = false;\n for (const p of [paths.dictFile(id), paths.dictMeta(id)]) {\n try {\n await unlink(p);\n removed = true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n }\n return removed;\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { render } from 'ink';\nimport { createElement } from 'react';\nimport { loadConfig } from '../infra/config-store.js';\nimport { App } from '../ui/App.js';\nimport { start as startSession, report as sessionReport } from '../infra/session-tracker.js';\nimport { printSessionReport, ensureMainScreen } from '../util/report.js';\nimport { pickStrings } from '../i18n/context.js';\nimport type { Mode } from '../domain/chapters.js';\n\nconst MODES: Mode[] = ['order', 'dictation', 'review', 'random', 'loop'];\n\nfunction isMode(v: string): v is Mode {\n return (MODES as string[]).includes(v);\n}\n\nexport async function runPractice(\n dictIdArg: string | undefined,\n options: { chapter?: string | number; mode?: string; stealth?: boolean },\n): Promise<void> {\n if (!process.stdout.isTTY) {\n console.error(chalk.red('Practice requires an interactive TTY.'));\n process.exitCode = 1;\n return;\n }\n const cfg = await loadConfig();\n const dictId = dictIdArg ?? cfg.defaultDict;\n if (!dictId) {\n console.error(chalk.red('No dictionary specified. Pass an id or set config.defaultDict.'));\n process.exitCode = 1;\n return;\n }\n const mode = options.mode ?? cfg.defaultMode;\n if (!isMode(mode)) {\n console.error(chalk.red(`Invalid mode \"${mode}\". Valid: ${MODES.join(', ')}`));\n process.exitCode = 1;\n return;\n }\n const chapterIndex = Math.max(0, Number(options.chapter ?? 1) - 1);\n const stealth = options.stealth === true || cfg.stealth === 'default';\n\n startSession();\n const { waitUntilExit } = render(\n createElement(App, {\n initial: { name: 'practice', params: { dictId, chapterIndex, mode, stealth } },\n initialCfg: cfg,\n }),\n { patchConsole: false, exitOnCtrlC: false },\n );\n await waitUntilExit();\n ensureMainScreen();\n const { lang, t } = pickStrings(cfg.language);\n printSessionReport(sessionReport(), t, lang);\n}\n\nexport function buildPracticeCommand(): Command {\n return new Command('practice')\n .argument('[dictId]', 'dictionary id; falls back to config.defaultDict')\n .description('Start a typing practice session')\n .option('-c, --chapter <n>', 'chapter number (1-based)', '1')\n .option('-m, --mode <mode>', 'order | dictation | review | random | loop')\n .option('--stealth', 'enter stealth mode (minimal UI, no sound)')\n .action(\n async (\n dictIdArg: string | undefined,\n options: { chapter: string; mode?: string; stealth?: boolean },\n ) => {\n await runPractice(dictIdArg, options);\n },\n );\n}\n","import { useRef, type ReactNode } from 'react';\nimport { useApp, useInput } from 'ink';\nimport { NavProvider, useNav, type ScreenFrame } from './nav.js';\nimport { Fullscreen } from './Fullscreen.js';\nimport { AudioStatusProvider } from './audio-context.js';\nimport { AppStateProvider, useAppState } from './app-state.js';\nimport { StringsProvider } from '../i18n/context.js';\nimport { RegistryProvider } from './registry-context.js';\nimport { MainMenu } from './screens/MainMenu.js';\nimport { PracticeScreen } from './screens/PracticeScreen.js';\nimport { DictBrowser } from './screens/DictBrowser.js';\nimport { ConfigEditor } from './screens/ConfigEditor.js';\nimport { StatsViewer } from './screens/StatsViewer.js';\nimport { WordLookup } from './screens/WordLookup.js';\nimport { HelpScreen } from './screens/HelpScreen.js';\nimport type { Config } from '../infra/config-store.js';\n\nexport function App({ initial, initialCfg }: { initial: ScreenFrame; initialCfg: Config }) {\n return (\n <AppStateProvider initialCfg={initialCfg}>\n <LangBridge>\n <RegistryProvider>\n <AudioStatusProvider disabled={!initialCfg.sounds.master}>\n <NavProvider initial={initial}>\n <Fullscreen>\n <Router />\n </Fullscreen>\n </NavProvider>\n </AudioStatusProvider>\n </RegistryProvider>\n </LangBridge>\n </AppStateProvider>\n );\n}\n\nfunction LangBridge({ children }: { children: ReactNode }) {\n const { cfg } = useAppState();\n return <StringsProvider pref={cfg.language}>{children}</StringsProvider>;\n}\n\nfunction screenKey(frame: ScreenFrame): string {\n if (frame.name === 'practice') {\n const p = frame.params;\n return `practice:${p.dictId}:${p.chapterIndex}:${p.mode}:${p.stealth ? 's' : 'n'}`;\n }\n return frame.name;\n}\n\nfunction Router() {\n const nav = useNav();\n const { cfg } = useAppState();\n const { exit } = useApp();\n const lastKeyRef = useRef<string | null>(null);\n\n useInput((input, key) => {\n if (key.ctrl && input === 'c') exit();\n });\n\n const frame = nav.current;\n const key = screenKey(frame);\n if (lastKeyRef.current !== key) {\n if (process.stdout.isTTY) process.stdout.write('\\x1b[2J\\x1b[H');\n lastKeyRef.current = key;\n }\n\n switch (frame.name) {\n case 'main':\n return <MainMenu cfg={cfg} />;\n case 'practice':\n return <PracticeScreen params={frame.params} />;\n case 'dict':\n return <DictBrowser params={frame.params} />;\n case 'config':\n return <ConfigEditor />;\n case 'stats':\n return <StatsViewer />;\n case 'word':\n return <WordLookup />;\n case 'help':\n return <HelpScreen />;\n }\n}\n","import { createContext, useContext, useState, useCallback, type ReactNode } from 'react';\n\nexport type ScreenName =\n | 'main'\n | 'practice'\n | 'dict'\n | 'config'\n | 'stats'\n | 'word'\n | 'help';\n\nexport type PracticeParams = {\n dictId: string;\n chapterIndex: number;\n mode: 'order' | 'dictation' | 'review' | 'random' | 'loop';\n stealth?: boolean;\n};\n\nexport type DictParams = {\n pickerMode?: 'set-default' | 'choose-then-practice';\n};\n\nexport type ScreenFrame =\n | { name: 'main' }\n | { name: 'practice'; params: PracticeParams }\n | { name: 'dict'; params?: DictParams }\n | { name: 'config' }\n | { name: 'stats' }\n | { name: 'word' }\n | { name: 'help' };\n\ntype NavContextValue = {\n current: ScreenFrame;\n stack: ScreenFrame[];\n navigate: (frame: ScreenFrame) => void;\n replace: (frame: ScreenFrame) => void;\n back: () => void;\n reset: (frame: ScreenFrame) => void;\n};\n\nconst NavContext = createContext<NavContextValue | null>(null);\n\nexport function NavProvider({ initial, children }: { initial: ScreenFrame; children: ReactNode }) {\n const [stack, setStack] = useState<ScreenFrame[]>([initial]);\n\n const navigate = useCallback((frame: ScreenFrame) => {\n setStack((s) => [...s, frame]);\n }, []);\n const replace = useCallback((frame: ScreenFrame) => {\n setStack((s) => (s.length === 0 ? [frame] : [...s.slice(0, -1), frame]));\n }, []);\n const back = useCallback(() => {\n setStack((s) => (s.length > 1 ? s.slice(0, -1) : s));\n }, []);\n const reset = useCallback((frame: ScreenFrame) => {\n setStack([frame]);\n }, []);\n\n const current = stack[stack.length - 1]!;\n return (\n <NavContext.Provider value={{ current, stack, navigate, replace, back, reset }}>\n {children}\n </NavContext.Provider>\n );\n}\n\nexport function useNav(): NavContextValue {\n const ctx = useContext(NavContext);\n if (!ctx) throw new Error('useNav must be used inside NavProvider');\n return ctx;\n}\n","import { useEffect, useState, type ReactNode } from 'react';\nimport { Box, useStdout } from 'ink';\n\nconst ENTER = '\\x1b[?1049h\\x1b[?25l\\x1b[2J\\x1b[H';\n// LEAVE intentionally does NOT clear (\\x1b[2J\\x1b[H) — DECRSET 1049 already\n// restores the pre-program main screen, and a clear here would wipe the\n// session report that's printed right after waitUntilExit().\nconst LEAVE = '\\x1b[?25h\\x1b[?1049l';\n\nfunction shouldUse(): boolean {\n return Boolean(process.stdout.isTTY) && process.env.QWERTY_NO_ALTSCREEN !== '1';\n}\n\nexport function Fullscreen({ children }: { children: ReactNode }) {\n const { stdout } = useStdout();\n const [size, setSize] = useState(() => ({\n rows: stdout?.rows ?? 24,\n cols: stdout?.columns ?? 80,\n }));\n\n useEffect(() => {\n if (!shouldUse()) return;\n process.stdout.write(ENTER);\n\n const onResize = () => {\n setSize({ rows: process.stdout.rows ?? 24, cols: process.stdout.columns ?? 80 });\n };\n process.stdout.on('resize', onResize);\n\n const leave = () => {\n try {\n process.stdout.write(LEAVE);\n } catch {\n // stream may already be closed\n }\n };\n\n const onSignal = () => {\n leave();\n process.exit(130);\n };\n\n process.once('SIGINT', onSignal);\n process.once('SIGTERM', onSignal);\n process.once('exit', leave);\n\n return () => {\n process.off('SIGINT', onSignal);\n process.off('SIGTERM', onSignal);\n process.off('exit', leave);\n process.stdout.off('resize', onResize);\n leave();\n };\n }, []);\n\n return (\n <Box width={size.cols} height={size.rows} flexDirection=\"column\">\n {children}\n </Box>\n );\n}\n","import { createContext, useContext, useEffect, useState, type ReactNode } from 'react';\nimport { initAudio, audioWarning } from '../infra/audio.js';\n\ntype AudioStatus = { warning: string | null; ready: boolean };\n\nconst AudioStatusContext = createContext<AudioStatus>({ warning: null, ready: false });\n\nexport function AudioStatusProvider({\n disabled,\n children,\n}: {\n disabled: boolean;\n children: ReactNode;\n}) {\n const [status, setStatus] = useState<AudioStatus>({ warning: null, ready: false });\n\n useEffect(() => {\n let cancelled = false;\n initAudio(disabled)\n .then(() => {\n if (cancelled) return;\n setStatus({ warning: audioWarning(), ready: true });\n })\n .catch(() => {\n if (cancelled) return;\n setStatus({ warning: null, ready: true });\n });\n return () => {\n cancelled = true;\n };\n }, [disabled]);\n\n return <AudioStatusContext.Provider value={status}>{children}</AudioStatusContext.Provider>;\n}\n\nexport function useAudioStatus(): AudioStatus {\n return useContext(AudioStatusContext);\n}\n","import { spawn } from 'node:child_process';\nimport { access, mkdir, rename, writeFile } from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { request } from 'undici';\nimport PQueue from 'p-queue';\nimport { paths, packageAssetsDir, ensureDirs } from './paths.js';\nimport { exists } from './fs-store.js';\n\ntype PlayerKind = 'afplay' | 'paplay' | 'aplay' | 'mpg123' | 'ffplay' | 'powershell';\n\ntype Player = {\n kind: PlayerKind;\n cmd: string;\n args: (file: string) => string[];\n supports: 'wav' | 'mp3' | 'both';\n};\n\nconst CANDIDATES: Player[] = [\n { kind: 'afplay', cmd: 'afplay', args: (f) => [f], supports: 'both' },\n { kind: 'ffplay', cmd: 'ffplay', args: (f) => ['-nodisp', '-autoexit', '-loglevel', 'quiet', f], supports: 'both' },\n { kind: 'mpg123', cmd: 'mpg123', args: (f) => ['-q', f], supports: 'mp3' },\n { kind: 'paplay', cmd: 'paplay', args: (f) => [f], supports: 'wav' },\n { kind: 'aplay', cmd: 'aplay', args: (f) => ['-q', f], supports: 'wav' },\n {\n kind: 'powershell',\n cmd: 'powershell',\n args: (f) => ['-NoProfile', '-Command', `(New-Object Media.SoundPlayer '${f}').PlaySync();`],\n supports: 'wav',\n },\n];\n\nconst PRON_API = 'https://dict.youdao.com/dictvoice?audio=';\n\ntype AudioRuntime = {\n disabled: boolean;\n wavPlayer: Player | null;\n mp3Player: Player | null;\n warning: string | null;\n keyQueue: PQueue;\n feedbackQueue: PQueue;\n pronQueue: PQueue;\n};\n\nlet runtime: AudioRuntime | null = null;\n\nasync function isExecutable(cmd: string): Promise<boolean> {\n return new Promise((resolve) => {\n const probe = spawn(cmd, ['--version'], { stdio: 'ignore' });\n probe.on('error', () => resolve(false));\n probe.on('exit', () => resolve(true));\n setTimeout(() => {\n probe.kill();\n resolve(false);\n }, 500);\n });\n}\n\nasync function detect(): Promise<{ wav: Player | null; mp3: Player | null }> {\n let wav: Player | null = null;\n let mp3: Player | null = null;\n for (const p of CANDIDATES) {\n if (!(await isExecutable(p.cmd))) continue;\n if (!wav && (p.supports === 'wav' || p.supports === 'both')) wav = p;\n if (!mp3 && (p.supports === 'mp3' || p.supports === 'both')) mp3 = p;\n if (wav && mp3) break;\n }\n return { wav, mp3 };\n}\n\nexport async function initAudio(disabledByConfig: boolean): Promise<AudioRuntime> {\n if (runtime) return runtime;\n if (disabledByConfig) {\n runtime = {\n disabled: true,\n wavPlayer: null,\n mp3Player: null,\n warning: null,\n keyQueue: new PQueue({ concurrency: 1 }),\n feedbackQueue: new PQueue({ concurrency: 1 }),\n pronQueue: new PQueue({ concurrency: 1 }),\n };\n return runtime;\n }\n const { wav, mp3 } = await detect();\n let warning: string | null = null;\n if (!wav && !mp3) {\n warning = 'No audio player found on PATH (looked for afplay/ffplay/mpg123/paplay/aplay/powershell). Sounds disabled.';\n } else if (!mp3) {\n warning = 'No MP3 player found; word pronunciations will be skipped.';\n }\n runtime = {\n disabled: !wav && !mp3,\n wavPlayer: wav,\n mp3Player: mp3,\n warning,\n keyQueue: new PQueue({ concurrency: 2 }),\n feedbackQueue: new PQueue({ concurrency: 1 }),\n pronQueue: new PQueue({ concurrency: 1 }),\n };\n return runtime;\n}\n\nfunction spawnPlay(player: Player, file: string): void {\n try {\n const child = spawn(player.cmd, player.args(file), {\n detached: true,\n stdio: 'ignore',\n });\n child.on('error', () => {\n // swallow; runtime will be disabled if many failures stack up\n });\n child.unref();\n } catch {\n /* fail-soft */\n }\n}\n\nfunction playFile(file: string, kind: 'wav' | 'mp3'): void {\n if (!runtime || runtime.disabled) return;\n const player = kind === 'wav' ? runtime.wavPlayer : runtime.mp3Player;\n if (!player) return;\n spawnPlay(player, file);\n}\n\nexport function playKeystroke(): void {\n if (!runtime || runtime.disabled) return;\n // Drop if queue is saturated; we never want to delay typing.\n if (runtime.keyQueue.size >= 2) return;\n void runtime.keyQueue.add(async () => {\n playFile(join(packageAssetsDir(), 'sounds', 'key-default.wav'), 'wav');\n await new Promise((r) => setTimeout(r, 30));\n });\n}\n\nexport function playCorrect(): void {\n if (!runtime || runtime.disabled) return;\n void runtime.feedbackQueue.add(async () => {\n playFile(join(packageAssetsDir(), 'sounds', 'correct.wav'), 'wav');\n await new Promise((r) => setTimeout(r, 50));\n });\n}\n\nexport function playWrong(): void {\n if (!runtime || runtime.disabled) return;\n void runtime.feedbackQueue.add(async () => {\n playFile(join(packageAssetsDir(), 'sounds', 'wrong.wav'), 'wav');\n await new Promise((r) => setTimeout(r, 50));\n });\n}\n\nasync function downloadPronunciation(word: string, accent: 'us' | 'uk'): Promise<string | null> {\n const cacheFile = paths.audioCache(word, accent);\n if (await exists(cacheFile)) return cacheFile;\n await mkdir(dirname(cacheFile), { recursive: true });\n const type = accent === 'us' ? 2 : 1;\n const url = `${PRON_API}${encodeURIComponent(word)}&type=${type}`;\n try {\n const res = await request(url, { headersTimeout: 8000, bodyTimeout: 20000 });\n if (res.statusCode >= 400) return null;\n const buf = Buffer.from(await res.body.arrayBuffer());\n if (buf.length < 1024) return null;\n const tmp = `${cacheFile}.tmp`;\n await writeFile(tmp, buf);\n await rename(tmp, cacheFile);\n return cacheFile;\n } catch {\n return null;\n }\n}\n\nexport async function playPronunciation(word: string, accent: 'us' | 'uk'): Promise<void> {\n if (!runtime || runtime.disabled || !runtime.mp3Player) return;\n await ensureDirs();\n await runtime.pronQueue.add(async () => {\n const file = await downloadPronunciation(word, accent);\n if (file) playFile(file, 'mp3');\n });\n}\n\nexport async function prefetchPronunciation(word: string, accent: 'us' | 'uk'): Promise<void> {\n if (!runtime || runtime.disabled || !runtime.mp3Player) return;\n await ensureDirs();\n void runtime.pronQueue.add(async () => {\n await downloadPronunciation(word, accent);\n });\n}\n\nexport function audioWarning(): string | null {\n return runtime?.warning ?? null;\n}\n\nexport function audioDisabled(): boolean {\n return runtime?.disabled ?? true;\n}\n","import { createContext, useCallback, useContext, useState, type ReactNode } from 'react';\nimport { saveConfig as persistConfig, type Config } from '../infra/config-store.js';\n\ntype AppState = {\n cfg: Config;\n setCfg: (next: Config) => Promise<void>;\n};\n\nconst AppStateContext = createContext<AppState | null>(null);\n\nexport function AppStateProvider({\n initialCfg,\n children,\n}: {\n initialCfg: Config;\n children: ReactNode;\n}) {\n const [cfg, setCfgState] = useState<Config>(initialCfg);\n const setCfg = useCallback(async (next: Config) => {\n setCfgState(next);\n await persistConfig(next);\n }, []);\n return <AppStateContext.Provider value={{ cfg, setCfg }}>{children}</AppStateContext.Provider>;\n}\n\nexport function useAppState(): AppState {\n const ctx = useContext(AppStateContext);\n if (!ctx) throw new Error('useAppState must be used inside AppStateProvider');\n return ctx;\n}\n","import { createContext, useContext, useMemo, type ReactNode } from 'react';\nimport { en, zh, type Strings } from './strings.js';\nimport { detectLocale, type Lang, type LangPref } from './locale.js';\n\nconst StringsContext = createContext<{ lang: Lang; t: Strings } | null>(null);\n\nexport function StringsProvider({\n pref,\n children,\n}: {\n pref: LangPref;\n children: ReactNode;\n}) {\n const value = useMemo(() => {\n const lang = detectLocale(pref);\n return { lang, t: lang === 'zh' ? zh : en };\n }, [pref]);\n return <StringsContext.Provider value={value}>{children}</StringsContext.Provider>;\n}\n\nexport function useStrings(): Strings {\n const ctx = useContext(StringsContext);\n if (!ctx) throw new Error('useStrings must be used inside StringsProvider');\n return ctx.t;\n}\n\nexport function useLang(): Lang {\n const ctx = useContext(StringsContext);\n if (!ctx) throw new Error('useLang must be used inside StringsProvider');\n return ctx.lang;\n}\n\nexport function pickStrings(pref: LangPref): { lang: Lang; t: Strings } {\n const lang = detectLocale(pref);\n return { lang, t: lang === 'zh' ? zh : en };\n}\n","// Centralized string table for the qwerty-cli TUI.\n//\n// Print-only subcommands (qwerty config list, qwerty dict list, etc.) keep\n// English output regardless of locale so shell scripts stay predictable.\n// Only the interactive TUI is localized via this table.\n\nexport type Strings = {\n app: {\n title: string;\n subtitle: string;\n };\n common: {\n back: string;\n quit: string;\n on: string;\n off: string;\n cancel: string;\n };\n mainMenu: {\n items: {\n practiceLabel: string;\n practiceHintWith: (name: string) => string;\n practiceHintNone: string;\n dictLabel: string;\n dictHint: string;\n wordLabel: string;\n wordHint: string;\n statsLabel: string;\n statsHint: string;\n configLabel: string;\n configHint: string;\n stealthLabel: string;\n stealthHint: string;\n quitLabel: string;\n quitHint: string;\n };\n hint: string;\n helpHint: string;\n };\n dict: {\n title: string;\n loading: string;\n entries: (n: number) => string;\n filterPlaceholder: string;\n local: string;\n notLocal: string;\n defaultMark: string;\n tagsLabel: (tags: string) => string;\n wordsLabel: (n: number) => string;\n pulling: (id: string) => string;\n removing: (id: string) => string;\n errorOn: (id: string, msg: string) => string;\n footer: string;\n action: {\n title: string;\n setDefault: string;\n practice: string;\n delete: string;\n };\n command: {\n title: string;\n pull: string;\n import: string;\n refreshList: string;\n };\n };\n config: {\n title: string;\n fields: {\n defaultDict: string;\n defaultMode: string;\n accent: string;\n mirror: string;\n chapterSize: string;\n autoplayPronunciation: string;\n soundsMaster: string;\n soundsKeystroke: string;\n soundsFeedback: string;\n soundsKeySound: string;\n language: string;\n stealth: string;\n };\n enumValues: {\n stealth: { off: string; menu: string; default: string };\n };\n hints: {\n editing: string;\n bool: string;\n enum: string;\n dictRef: string;\n stringOrInt: string;\n };\n };\n stats: {\n title: string;\n loading: string;\n none: string;\n nonePractice: string;\n lifetime: string;\n sessions: string;\n words: string;\n errors: string;\n wpm: string;\n accuracy: string;\n streak: string;\n last: (n: number) => string;\n cycleWindow: string;\n recent: string;\n topMistakes: string;\n footer: string;\n maxLabel: string;\n recentUnits: { words: string; errors: string; wpm: string };\n multiDictSuffix: (n: number) => string;\n };\n word: {\n title: string;\n indexing: string;\n none: string;\n pullFirst: string;\n countAcross: (n: number) => string;\n noMatches: (q: string) => string;\n inDict: (name: string) => string;\n mistakes: (n: number, date: string) => string;\n footer: string;\n };\n practice: {\n loading: string;\n paused: string;\n chapterComplete: string;\n chapterLabel: (c: number, t: number) => string;\n reviewLabel: string;\n statusBar: {\n mode: string;\n accent: string;\n };\n modes: {\n order: string;\n dictation: string;\n review: string;\n random: string;\n loop: string;\n };\n accents: {\n us: string;\n uk: string;\n };\n statCards: {\n words: string;\n errors: string;\n wpm: string;\n accuracy: string;\n elapsed: (t: string) => string;\n };\n pause: {\n title: string;\n chapter: (c: number, t: number) => string;\n progress: (completed: number, total: number) => string;\n hint: string;\n };\n summary: {\n loopAgain: string;\n nextChapter: string;\n reviewMistakes: string;\n backMenu: string;\n };\n footers: {\n typing: string;\n };\n errors: {\n noMistakes: string;\n dictEmpty: (id: string) => string;\n unknown: string;\n };\n };\n audio: {\n noPlayer: string;\n };\n report: {\n title: string;\n duration: string;\n practiced: string;\n chapters: string;\n words: string;\n accuracy: string;\n wpm: string;\n newMistakes: string;\n farewell: string;\n notPracticed: string;\n };\n help: {\n title: string;\n subtitle: string;\n sections: {\n main: string;\n practice: string;\n dict: string;\n config: string;\n stats: string;\n word: string;\n global: string;\n };\n keys: {\n navigate: string;\n select: string;\n letterJump: string;\n pause: string;\n skip: string;\n replay: string;\n resume: string;\n backMenu: string;\n backScreen: string;\n nextChapter: string;\n reviewMistakes: string;\n filter: string;\n itemActions: string;\n moreActions: string;\n cycleWindow: string;\n stealthToggle: string;\n helpScreen: string;\n quit: string;\n };\n footer: string;\n };\n stealth: {\n paused: string;\n chapterDone: string;\n resumeHint: string;\n nextHint: string;\n infoFmt: (\n dict: string,\n chapter: string,\n completed: number,\n total: number,\n wpm: number,\n accPct: number,\n ) => string;\n };\n};\n\nexport const en: Strings = {\n app: {\n title: 'qwerty',\n subtitle: 'typing practice for the terminal',\n },\n common: {\n back: 'back',\n quit: 'quit',\n on: 'on',\n off: 'off',\n cancel: 'cancel',\n },\n mainMenu: {\n items: {\n practiceLabel: 'Practice',\n practiceHintWith: (name) => `start ${name}`,\n practiceHintNone: 'pick a dictionary',\n dictLabel: 'Dictionaries',\n dictHint: 'browse, pull, set default',\n wordLabel: 'Word lookup',\n wordHint: 'search local dicts',\n statsLabel: 'Stats',\n statsHint: 'history & trends',\n configLabel: 'Config',\n configHint: 'edit preferences',\n stealthLabel: 'Stealth',\n stealthHint: 'quiet practice mode',\n quitLabel: 'Quit',\n quitHint: 'Esc or Ctrl+C also exits',\n },\n hint: '↑/↓ navigate · Enter select · letters jump',\n helpHint: '? help',\n },\n dict: {\n title: 'Dictionaries',\n loading: 'loading dictionaries…',\n entries: (n) => `${n} entries`,\n filterPlaceholder: 'type to filter',\n local: 'local ✓',\n notLocal: 'not local',\n defaultMark: 'default ★',\n tagsLabel: (tags) => `tags: ${tags}`,\n wordsLabel: (n) => `${n} words`,\n pulling: (id) => `pulling ${id}…`,\n removing: (id) => `removing ${id}…`,\n errorOn: (id, msg) => `error on ${id}: ${msg}`,\n footer: '↑/↓ select · Enter actions · Ctrl+K more · Esc back',\n action: {\n title: 'current dictionary',\n setDefault: 'set as default',\n practice: 'practice now',\n delete: 'delete local',\n },\n command: {\n title: 'more actions',\n pull: 'pull selected',\n import: 'import .json',\n refreshList: 'update dictionary list',\n },\n },\n config: {\n title: 'Config',\n fields: {\n defaultDict: 'default dict',\n defaultMode: 'default mode',\n accent: 'accent',\n mirror: 'dict mirror',\n chapterSize: 'chapter size',\n autoplayPronunciation: 'autoplay pronunciation',\n soundsMaster: 'sounds master',\n soundsKeystroke: 'sounds keystroke',\n soundsFeedback: 'sounds feedback',\n soundsKeySound: 'sounds key sound',\n language: 'language',\n stealth: 'stealth mode',\n },\n enumValues: {\n stealth: { off: 'off', menu: 'show in menu', default: 'default practice' },\n },\n hints: {\n editing: 'type to edit · Enter save · Esc cancel',\n bool: 'space toggle · ↑/↓ move · Esc back',\n enum: '←/→ cycle · ↑/↓ move · Esc back',\n dictRef: 'Enter pick dict · ↑/↓ move · Esc back',\n stringOrInt: 'Enter edit · ↑/↓ move · Esc back',\n },\n },\n stats: {\n title: 'Stats · overview',\n loading: 'loading stats…',\n none: 'No practice history yet.',\n nonePractice: 'Run a practice session first.',\n lifetime: 'lifetime',\n sessions: 'sessions',\n words: 'words',\n errors: 'errors',\n wpm: 'wpm',\n accuracy: 'accuracy',\n streak: 'streak',\n last: (n) => `last ${n} days (←/→ cycle window)`,\n cycleWindow: '←/→ cycle window · Esc back',\n recent: 'recent sessions',\n topMistakes: 'top mistakes',\n footer: '←/→ cycle window · Esc back',\n maxLabel: 'max',\n recentUnits: { words: 'w', errors: 'err', wpm: 'wpm' },\n multiDictSuffix: (n) => ` +${n} more`,\n },\n word: {\n title: 'Word lookup',\n indexing: 'indexing local dictionaries…',\n none: 'No local dictionaries.',\n pullFirst: 'Pull one in Dictionaries first.',\n countAcross: (n) => `${n} words across local dicts`,\n noMatches: (q) => `no matches for \"${q}\"`,\n inDict: (name) => `in: ${name}`,\n mistakes: (n, date) => `mistakes: ${n} (last ${date})`,\n footer: 'type to filter · ↑/↓ select · Esc back',\n },\n practice: {\n loading: 'loading…',\n paused: 'PAUSED',\n chapterComplete: 'CHAPTER COMPLETE',\n chapterLabel: (c, t) => `chapter ${c}/${t}`,\n reviewLabel: 'review',\n statusBar: {\n mode: 'mode',\n accent: 'accent',\n },\n modes: {\n order: 'order',\n dictation: 'dictation',\n review: 'review',\n random: 'random',\n loop: 'loop',\n },\n accents: {\n us: 'us',\n uk: 'uk',\n },\n statCards: {\n words: 'words',\n errors: 'errors',\n wpm: 'wpm',\n accuracy: 'accuracy',\n elapsed: (t) => `elapsed ${t}`,\n },\n pause: {\n title: 'PAUSED',\n chapter: (c, t) => `chapter ${c}/${t}`,\n progress: (completed, total) => `${completed}/${total}`,\n hint: 'Enter resume · Esc back to menu',\n },\n summary: {\n loopAgain: 'again',\n nextChapter: 'next chapter',\n reviewMistakes: 'review mistakes',\n backMenu: 'back to menu',\n },\n footers: {\n typing: 'Ctrl+N skip · Esc pause · Tab replay',\n },\n errors: {\n noMistakes: 'No mistakes to review yet. Practice some chapters first.',\n dictEmpty: (id) => `Dictionary ${id} is empty.`,\n unknown: 'Unknown error',\n },\n },\n audio: {\n noPlayer: '! No audio player found on PATH (looked for afplay/ffplay/mpg123/paplay/aplay/powershell). Sounds disabled.',\n },\n report: {\n title: 'Session summary',\n duration: 'duration',\n practiced: 'practiced',\n chapters: 'chapters',\n words: 'words',\n accuracy: 'accuracy',\n wpm: 'wpm',\n newMistakes: 'new mistakes',\n farewell: 'see you next time.',\n notPracticed: 'no practice this run',\n },\n help: {\n title: 'Help',\n subtitle: 'all shortcuts',\n sections: {\n main: 'main menu',\n practice: 'practice',\n dict: 'dictionaries',\n config: 'config',\n stats: 'stats',\n word: 'word lookup',\n global: 'global',\n },\n keys: {\n navigate: '↑/↓ navigate items',\n select: 'Enter confirm / continue',\n letterJump: 'letter jump to menu item',\n pause: 'Esc pause practice',\n skip: 'Ctrl+N skip current word (neutral)',\n replay: 'Tab replay pronunciation',\n resume: 'Enter resume from pause',\n backMenu: 'Esc back to previous screen',\n backScreen: 'Esc close panel or back',\n nextChapter: 'Enter next chapter',\n reviewMistakes: 'm review mistakes',\n filter: 'type to filter list',\n itemActions: 'Enter open actions panel',\n moreActions: 'Ctrl+K more actions panel',\n cycleWindow: '←/→ cycle day window',\n stealthToggle: 'Ctrl+I toggle stealth info row',\n helpScreen: '? open this help screen',\n quit: 'Ctrl+C quit immediately',\n },\n footer: 'Esc back',\n },\n stealth: {\n paused: 'paused',\n chapterDone: 'chapter done',\n resumeHint: 'Enter resume · Esc menu',\n nextHint: 'Enter next · Esc menu',\n infoFmt: (dict, chapter, completed, total, wpm, accPct) =>\n `${dict} · ${chapter} · ${completed}/${total} · ${wpm} wpm · ${accPct}%`,\n },\n};\n\nexport const zh: Strings = {\n app: {\n title: 'qwerty',\n subtitle: '终端键盘练习',\n },\n common: {\n back: '返回',\n quit: '退出',\n on: '开',\n off: '关',\n cancel: '取消',\n },\n mainMenu: {\n items: {\n practiceLabel: '练习',\n practiceHintWith: (name) => `开始 ${name}`,\n practiceHintNone: '请先选词典',\n dictLabel: '词典',\n dictHint: '浏览、下载、设为默认',\n wordLabel: '查词',\n wordHint: '在本地词典中搜索',\n statsLabel: '统计',\n statsHint: '历史与趋势',\n configLabel: '设置',\n configHint: '修改偏好',\n stealthLabel: '摸鱼',\n stealthHint: '安静练习模式',\n quitLabel: '退出',\n quitHint: 'Esc 或 Ctrl+C 退出',\n },\n hint: '↑/↓ 移动 · Enter 确认 · 字母直达',\n helpHint: '? 帮助',\n },\n dict: {\n title: '词典',\n loading: '加载词典中…',\n entries: (n) => `${n} 部词典`,\n filterPlaceholder: '输入过滤',\n local: '已下载 ✓',\n notLocal: '未下载',\n defaultMark: '默认 ★',\n tagsLabel: (tags) => `标签:${tags}`,\n wordsLabel: (n) => `${n} 词`,\n pulling: (id) => `拉取 ${id} 中…`,\n removing: (id) => `删除 ${id} 中…`,\n errorOn: (id, msg) => `${id} 出错:${msg}`,\n footer: '↑/↓ 选择 · Enter 操作 · Ctrl+K 更多 · Esc 返回',\n action: {\n title: '当前词典',\n setDefault: '设为默认',\n practice: '立即练习',\n delete: '删除本地',\n },\n command: {\n title: '更多功能',\n pull: '拉取选中',\n import: '导入 .json',\n refreshList: '更新词典列表',\n },\n },\n config: {\n title: '设置',\n fields: {\n defaultDict: '默认词典',\n defaultMode: '默认模式',\n accent: '发音',\n mirror: '词典镜像源',\n chapterSize: '章节单词数',\n autoplayPronunciation: '自动播放发音',\n soundsMaster: '音效总开关',\n soundsKeystroke: '按键音',\n soundsFeedback: '反馈音',\n soundsKeySound: '按键音色',\n language: '语言',\n stealth: '摸鱼模式',\n },\n enumValues: {\n stealth: { off: '关闭', menu: '主菜单显示', default: '默认练习模式' },\n },\n hints: {\n editing: '输入修改 · Enter 保存 · Esc 取消',\n bool: '空格切换 · ↑/↓ 移动 · Esc 返回',\n enum: '←/→ 切换 · ↑/↓ 移动 · Esc 返回',\n dictRef: 'Enter 选词典 · ↑/↓ 移动 · Esc 返回',\n stringOrInt: 'Enter 编辑 · ↑/↓ 移动 · Esc 返回',\n },\n },\n stats: {\n title: '统计 · 概览',\n loading: '加载统计中…',\n none: '还没有练习记录。',\n nonePractice: '先来一次练习吧。',\n lifetime: '累计',\n sessions: '会话',\n words: '词数',\n errors: '错误',\n wpm: '速度',\n accuracy: '准确率',\n streak: '连续天数',\n last: (n) => `最近 ${n} 天 (←/→ 切换窗口)`,\n cycleWindow: '←/→ 切换窗口 · Esc 返回',\n recent: '最近会话',\n topMistakes: '高频错词',\n footer: '←/→ 切换窗口 · Esc 返回',\n maxLabel: '最大',\n recentUnits: { words: '词', errors: '错', wpm: '速' },\n multiDictSuffix: (n) => ` 等 ${n} 部`,\n },\n word: {\n title: '查词',\n indexing: '索引本地词典中…',\n none: '没有本地词典。',\n pullFirst: '先在「词典」中拉取一部。',\n countAcross: (n) => `本地词典共 ${n} 词`,\n noMatches: (q) => `没有匹配「${q}」的词`,\n inDict: (name) => `来源:${name}`,\n mistakes: (n, date) => `错过 ${n} 次 (最近 ${date})`,\n footer: '输入过滤 · ↑/↓ 选择 · Esc 返回',\n },\n practice: {\n loading: '加载中…',\n paused: '已暂停',\n chapterComplete: '本章完成',\n chapterLabel: (c, t) => `第 ${c}/${t} 章`,\n reviewLabel: '复习',\n statusBar: {\n mode: '模式',\n accent: '发音',\n },\n modes: {\n order: '顺序',\n dictation: '默写',\n review: '复习',\n random: '乱序',\n loop: '循环',\n },\n accents: {\n us: '美',\n uk: '英',\n },\n statCards: {\n words: '词数',\n errors: '错误',\n wpm: '速度',\n accuracy: '准确率',\n elapsed: (t) => `耗时 ${t}`,\n },\n pause: {\n title: '已暂停',\n chapter: (c, t) => `第 ${c}/${t} 章`,\n progress: (completed, total) => `${completed}/${total}`,\n hint: 'Enter 继续 · Esc 返回菜单',\n },\n summary: {\n loopAgain: '再来一遍',\n nextChapter: '下一章',\n reviewMistakes: '复习错词',\n backMenu: '返回菜单',\n },\n footers: {\n typing: 'Ctrl+N 跳过 · Esc 暂停 · Tab 重播',\n },\n errors: {\n noMistakes: '错词本是空的。先练习几章吧。',\n dictEmpty: (id) => `词典 ${id} 是空的。`,\n unknown: '未知错误',\n },\n },\n audio: {\n noPlayer: '! 未在 PATH 中找到音频播放器(尝试 afplay/ffplay/mpg123/paplay/aplay/powershell)。音效已禁用。',\n },\n report: {\n title: '本次会话',\n duration: '总时长',\n practiced: '练习用时',\n chapters: '完成章节',\n words: '词数',\n accuracy: '准确率',\n wpm: '速度',\n newMistakes: '新错词',\n farewell: '下次见。',\n notPracticed: '本次未练习',\n },\n help: {\n title: '帮助',\n subtitle: '全部快捷键',\n sections: {\n main: '主菜单',\n practice: '练习',\n dict: '词典',\n config: '设置',\n stats: '统计',\n word: '查词',\n global: '全局',\n },\n keys: {\n navigate: '↑/↓ 移动选项',\n select: 'Enter 确认 / 继续',\n letterJump: '字母键 直达菜单项',\n pause: 'Esc 暂停练习',\n skip: 'Ctrl+N 跳过当前词(不计错)',\n replay: 'Tab 重播发音',\n resume: 'Enter 继续练习',\n backMenu: 'Esc 返回上一屏',\n backScreen: 'Esc 关闭面板 / 返回',\n nextChapter: 'Enter 下一章',\n reviewMistakes: 'm 复习错词',\n filter: '输入 过滤列表',\n itemActions: 'Enter 弹出动作面板',\n moreActions: 'Ctrl+K 弹出更多功能',\n cycleWindow: '←/→ 切换日窗口',\n stealthToggle: 'Ctrl+I 切换摸鱼信息行',\n helpScreen: '? 打开本帮助页',\n quit: 'Ctrl+C 立即退出',\n },\n footer: 'Esc 返回',\n },\n stealth: {\n paused: 'paused',\n chapterDone: 'chapter done',\n resumeHint: 'Enter resume · Esc menu',\n nextHint: 'Enter next · Esc menu',\n infoFmt: (dict, chapter, completed, total, wpm, accPct) =>\n `${dict} · ${chapter} · ${completed}/${total} · ${wpm} wpm · ${accPct}%`,\n },\n};\n","export type Lang = 'zh' | 'en';\nexport type LangPref = 'auto' | Lang;\n\nfunction pickFromString(s: string | undefined): Lang | null {\n if (!s) return null;\n const lower = s.toLowerCase();\n if (lower.startsWith('zh')) return 'zh';\n if (lower.startsWith('en')) return 'en';\n return null;\n}\n\nexport function detectLocale(pref: LangPref): Lang {\n if (pref === 'zh' || pref === 'en') return pref;\n const env =\n process.env.LC_ALL ||\n process.env.LC_MESSAGES ||\n process.env.LANG ||\n process.env.LANGUAGE;\n const fromEnv = pickFromString(env);\n if (fromEnv) return fromEnv;\n try {\n const intlLocale = Intl.DateTimeFormat().resolvedOptions().locale;\n const fromIntl = pickFromString(intlLocale);\n if (fromIntl) return fromIntl;\n } catch {\n // ignore\n }\n return 'en';\n}\n","import { createContext, useContext, useEffect, useState, type ReactNode } from 'react';\nimport { loadRegistry } from '../infra/registry-store.js';\nimport type { Registry, DictionaryEntry } from '../domain/dictionary.js';\n\ntype RegistryContextValue = {\n registry: Registry | null;\n byId: Map<string, DictionaryEntry>;\n};\n\nconst RegistryContext = createContext<RegistryContextValue | null>(null);\n\nexport function RegistryProvider({ children }: { children: ReactNode }) {\n const [registry, setRegistry] = useState<Registry | null>(null);\n const [byId, setById] = useState<Map<string, DictionaryEntry>>(new Map());\n\n useEffect(() => {\n let cancelled = false;\n (async () => {\n try {\n const reg = await loadRegistry();\n if (cancelled) return;\n const map = new Map<string, DictionaryEntry>();\n for (const e of reg) map.set(e.id, e);\n setRegistry(reg);\n setById(map);\n } catch {\n if (!cancelled) {\n setRegistry([]);\n setById(new Map());\n }\n }\n })();\n return () => {\n cancelled = true;\n };\n }, []);\n\n return (\n <RegistryContext.Provider value={{ registry, byId }}>\n {children}\n </RegistryContext.Provider>\n );\n}\n\nexport function useRegistry(): RegistryContextValue {\n const ctx = useContext(RegistryContext);\n if (!ctx) throw new Error('useRegistry must be used inside RegistryProvider');\n return ctx;\n}\n\nexport function useDictName(id: string | undefined): string {\n const { byId } = useRegistry();\n if (!id) return '';\n const entry = byId.get(id);\n return entry?.name ?? id;\n}\n","import { useState } from 'react';\nimport { Box, Text, useApp, useInput } from 'ink';\nimport { useNav } from '../nav.js';\nimport { useAudioStatus } from '../audio-context.js';\nimport { useStrings } from '../../i18n/context.js';\nimport { useDictName } from '../registry-context.js';\nimport { PALETTE } from '../components/BigWord.js';\nimport { visibleWidth } from '../../util/text.js';\nimport { truncateName } from '../../util/dict-name.js';\nimport type { Config } from '../../infra/config-store.js';\n\ntype Item = { key: string; label: string; hint: string; run: () => void };\n\nexport function MainMenu({ cfg }: { cfg: Config }) {\n const [selected, setSelected] = useState(0);\n const { exit } = useApp();\n const nav = useNav();\n const audio = useAudioStatus();\n const t = useStrings();\n const defaultDictName = useDictName(cfg.defaultDict);\n\n const m = t.mainMenu.items;\n const startPractice = (stealth: boolean) => {\n if (cfg.defaultDict) {\n nav.navigate({\n name: 'practice',\n params: {\n dictId: cfg.defaultDict,\n chapterIndex: 0,\n mode: cfg.defaultMode,\n stealth,\n },\n });\n } else {\n nav.navigate({ name: 'dict', params: { pickerMode: 'choose-then-practice' } });\n }\n };\n\n const items: Item[] = [\n {\n key: 'p',\n label: m.practiceLabel,\n hint: cfg.defaultDict\n ? m.practiceHintWith(truncateName(defaultDictName, 24))\n : m.practiceHintNone,\n run: () => startPractice(cfg.stealth === 'default'),\n },\n ];\n\n if (cfg.stealth === 'menu' || cfg.stealth === 'default') {\n items.push({\n key: 'b',\n label: m.stealthLabel,\n hint: m.stealthHint,\n run: () => startPractice(true),\n });\n }\n\n items.push(\n { key: 'd', label: m.dictLabel, hint: m.dictHint, run: () => nav.navigate({ name: 'dict' }) },\n { key: 'w', label: m.wordLabel, hint: m.wordHint, run: () => nav.navigate({ name: 'word' }) },\n { key: 's', label: m.statsLabel, hint: m.statsHint, run: () => nav.navigate({ name: 'stats' }) },\n { key: 'c', label: m.configLabel, hint: m.configHint, run: () => nav.navigate({ name: 'config' }) },\n { key: 'q', label: m.quitLabel, hint: m.quitHint, run: () => exit() },\n );\n\n const labelW = Math.max(...items.map((it) => visibleWidth(it.label))) + 4;\n\n useInput((input, key) => {\n if (key.escape) {\n exit();\n return;\n }\n if (key.upArrow) setSelected((i) => (i - 1 + items.length) % items.length);\n if (key.downArrow) setSelected((i) => (i + 1) % items.length);\n if (key.return) {\n items[selected]!.run();\n return;\n }\n if (input === '?') {\n nav.navigate({ name: 'help' });\n return;\n }\n for (const it of items) {\n if (input === it.key) {\n it.run();\n return;\n }\n }\n });\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\">\n <Box>\n <Text bold color={PALETTE.accent}>\n {t.app.title}\n </Text>\n <Text color={PALETTE.muted}> · {t.app.subtitle}</Text>\n </Box>\n\n <Box marginTop={2} flexDirection=\"column\">\n {items.map((it, i) => {\n const active = i === selected;\n const pad = ' '.repeat(Math.max(0, labelW - visibleWidth(it.label)));\n return (\n <Box key={it.key}>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>{active ? '▌ ' : ' '}</Text>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>[{it.key}]</Text>\n <Text>{' '}</Text>\n <Text bold={active} color={active ? PALETTE.text : PALETTE.muted}>\n {it.label}\n {pad}\n </Text>\n <Text color={PALETTE.muted}>{it.hint}</Text>\n </Box>\n );\n })}\n </Box>\n\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>\n {t.mainMenu.hint}\n {' · '}\n {t.mainMenu.helpHint}\n </Text>\n </Box>\n\n {audio.warning && (\n <Box marginTop={1}>\n <Text color={PALETTE.warning}>{t.audio.noPlayer}</Text>\n </Box>\n )}\n </Box>\n );\n}\n","import { Box, Text, useStdout } from 'ink';\n\nexport const PALETTE = {\n accent: '#5eead4',\n muted: '#6b7280',\n text: '#e5e7eb',\n primary: '#7dcfff',\n success: '#86efac',\n warning: '#fbbf24',\n error: '#f87171',\n} as const;\n\ntype Props = {\n target: string;\n typed: string;\n error?: boolean;\n hideTarget?: boolean;\n};\n\nexport function BigWord({ target, typed, error = false, hideTarget = false }: Props) {\n const { stdout } = useStdout();\n const cols = stdout?.columns ?? 80;\n const chars = [...target];\n const typedChars = [...typed];\n\n const sep = cols >= 80 ? ' ' : cols >= 60 ? ' ' : ' ';\n\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" paddingY={1}>\n <Box>\n {chars.map((ch, i) => {\n const isTyped = i < typedChars.length;\n const display = hideTarget && !isTyped ? '_' : isTyped ? typedChars[i]! : ch;\n const color = error\n ? PALETTE.error\n : isTyped\n ? PALETTE.accent\n : PALETTE.muted;\n return (\n <Text key={i} bold color={color}>\n {display}\n {i < chars.length - 1 ? sep : ''}\n </Text>\n );\n })}\n </Box>\n <Box>\n {chars.map((ch, i) => {\n const isTyped = i < typedChars.length;\n const trackChar = isTyped ? '━' : '─';\n const color = error\n ? PALETTE.error\n : isTyped\n ? PALETTE.accent\n : PALETTE.muted;\n return (\n <Text key={i} color={color}>\n {trackChar}\n {i < chars.length - 1 ? sep : ''}\n </Text>\n );\n })}\n </Box>\n </Box>\n );\n}\n\ntype BoldTextProps = {\n text: string;\n color?: string;\n};\n\nexport function BoldSpaced({ text, color = PALETTE.text }: BoldTextProps) {\n const chars = [...text];\n return (\n <Box>\n {chars.map((ch, i) => (\n <Text key={i} bold color={color}>\n {ch}\n {i < chars.length - 1 ? ' ' : ''}\n </Text>\n ))}\n </Box>\n );\n}\n","const ANSI_RE = /\\x1b\\[[0-9;]*m/g;\n\nexport function stripAnsi(s: string): string {\n return s.replace(ANSI_RE, '');\n}\n\nexport function visibleWidth(s: string): number {\n const plain = stripAnsi(s);\n let w = 0;\n for (const ch of plain) {\n const code = ch.codePointAt(0)!;\n w += code > 0x2e80 && code < 0xfb00 ? 2 : 1;\n }\n return w;\n}\n\nexport function pad(s: string, n: number): string {\n return s + ' '.repeat(Math.max(0, n - visibleWidth(s)));\n}\n\nexport function truncate(s: string, max: number): string {\n if (visibleWidth(s) <= max) return s;\n const plain = stripAnsi(s);\n let out = '';\n let w = 0;\n for (const ch of plain) {\n const code = ch.codePointAt(0)!;\n const cw = code > 0x2e80 && code < 0xfb00 ? 2 : 1;\n if (w + cw > max - 1) break;\n out += ch;\n w += cw;\n }\n return out + '…';\n}\n","import { visibleWidth } from './text.js';\n\nexport function truncateName(name: string, max: number): string {\n if (visibleWidth(name) <= max) return name;\n let out = '';\n let w = 0;\n for (const ch of name) {\n const code = ch.codePointAt(0)!;\n const cw = code > 0x2e80 && code < 0xfb00 ? 2 : 1;\n if (w + cw > max - 1) break;\n out += ch;\n w += cw;\n }\n return out + '…';\n}\n","import { useState, useEffect, useRef } from 'react';\nimport { Box, Text, useApp, useInput } from 'ink';\nimport type { Word } from '../../domain/dictionary.js';\nimport type { Mode } from '../../domain/chapters.js';\nimport { chunkChapters, buildPlaylist } from '../../domain/chapters.js';\nimport { sessionSummary } from '../../domain/session.js';\nimport { loadMistakes } from '../../domain/mistakes.js';\nimport { ensureDictionary } from '../../infra/dict-downloader.js';\nimport { useWordLoop } from '../hooks/useWordLoop.js';\nimport { useAudio } from '../hooks/useAudio.js';\nimport { useSessionPersistence } from '../hooks/useSessionPersistence.js';\nimport { useNav, type PracticeParams } from '../nav.js';\nimport { useAppState } from '../app-state.js';\nimport { useStrings } from '../../i18n/context.js';\nimport { useDictName } from '../registry-context.js';\nimport { BigWord, PALETTE } from '../components/BigWord.js';\nimport { truncateName } from '../../util/dict-name.js';\nimport { StealthTyping, StealthPaused, StealthSummary } from './StealthPracticeLayout.js';\n\ntype Phase = 'loading' | 'typing' | 'paused' | 'summary' | 'error';\n\ntype Loaded = {\n playlist: Word[];\n totalChapters: number;\n};\n\nexport function PracticeScreen({ params }: { params: PracticeParams }) {\n const { dictId, chapterIndex, mode } = params;\n const { cfg } = useAppState();\n const t = useStrings();\n\n const [phase, setPhase] = useState<Phase>('loading');\n const [loaded, setLoaded] = useState<Loaded | null>(null);\n const [errorMsg, setErrorMsg] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n setPhase('loading');\n setLoaded(null);\n setErrorMsg(null);\n (async () => {\n try {\n const words = await ensureDictionary(dictId);\n if (cancelled) return;\n if (mode === 'review') {\n const book = await loadMistakes();\n if (cancelled) return;\n const reviewWords = words.filter((w) => book[w.name]?.count).slice(0, cfg.chapterSize);\n if (reviewWords.length === 0) {\n setErrorMsg(t.practice.errors.noMistakes);\n setPhase('error');\n return;\n }\n setLoaded({ playlist: reviewWords, totalChapters: 1 });\n setPhase('typing');\n return;\n }\n const chapters = chunkChapters(words, cfg.chapterSize);\n if (chapters.length === 0) {\n setErrorMsg(t.practice.errors.dictEmpty(dictId));\n setPhase('error');\n return;\n }\n const idx = Math.max(0, Math.min(chapters.length - 1, chapterIndex));\n const playlist = buildPlaylist(chapters[idx]!, mode);\n setLoaded({ playlist, totalChapters: chapters.length });\n setPhase('typing');\n } catch (err) {\n if (cancelled) return;\n setErrorMsg((err as Error).message);\n setPhase('error');\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [dictId, chapterIndex, mode, cfg.chapterSize, t]);\n\n if (phase === 'loading') {\n return <Centered text={t.practice.loading} color={PALETTE.muted} />;\n }\n if (phase === 'error') {\n return <ErrorView msg={errorMsg ?? t.practice.errors.unknown} />;\n }\n if (!loaded) return null;\n\n return (\n <PracticeRunner\n key={`${dictId}-${chapterIndex}-${mode}-${params.stealth ? 's' : 'n'}`}\n params={params}\n loaded={loaded}\n phase={phase}\n setPhase={setPhase}\n />\n );\n}\n\nfunction PracticeRunner({\n params,\n loaded,\n phase,\n setPhase,\n}: {\n params: PracticeParams;\n loaded: Loaded;\n phase: Phase;\n setPhase: (p: Phase) => void;\n}) {\n const { dictId, chapterIndex, mode } = params;\n const stealth = params.stealth === true;\n const { cfg } = useAppState();\n const nav = useNav();\n const { exit } = useApp();\n const goBack = () => (nav.stack.length > 1 ? nav.back() : exit());\n const persist = useSessionPersistence({ dictId, chapterIndex, mode });\n const dictName = useDictName(dictId);\n\n const audio = useAudio({\n enabled: !stealth && cfg.sounds.master,\n accent: cfg.accent,\n autoplayPronunciation: !stealth && cfg.autoplayPronunciation,\n });\n\n const finishedRef = useRef(false);\n const lastEffectRef = useRef<string | null>(null);\n const lastIndexRef = useRef<number>(-1);\n const [infoVisible, setInfoVisible] = useState(false);\n\n const { session, lastEffect, tick } = useWordLoop({\n playlist: loaded.playlist,\n enabled: phase === 'typing',\n onComplete: (s) => {\n if (finishedRef.current) return;\n finishedRef.current = true;\n setPhase('summary');\n Promise.resolve(persist(sessionSummary(s))).catch((err) => {\n console.error('Failed to persist session:', err);\n });\n },\n onEscape: () => setPhase(phase === 'paused' ? 'typing' : 'paused'),\n onTab: stealth\n ? undefined\n : () => {\n const cur = session.current ? loaded.playlist[session.current.wordIndex] : undefined;\n if (cur) void audio.pronounce(cur.name);\n },\n });\n\n useEffect(() => {\n if (stealth) return;\n if (lastEffect === null) return;\n if (lastEffect === lastEffectRef.current) return;\n lastEffectRef.current = lastEffect;\n if (lastEffect === 'wrong' && cfg.sounds.feedback) audio.wrong();\n if (lastEffect === 'progress' && cfg.sounds.keystroke) audio.keystroke();\n if (lastEffect === 'correct') {\n if (cfg.sounds.feedback) audio.correct();\n if (cfg.sounds.keystroke) audio.keystroke();\n }\n }, [stealth, lastEffect, audio, cfg.sounds.feedback, cfg.sounds.keystroke]);\n\n useEffect(() => {\n if (stealth) return;\n const idx = session.current?.wordIndex ?? -1;\n if (idx === -1) return;\n if (idx === lastIndexRef.current) return;\n lastIndexRef.current = idx;\n const cur = loaded.playlist[idx];\n const next = loaded.playlist[idx + 1];\n if (cur && cfg.autoplayPronunciation) audio.pronounce(cur.name);\n if (next) audio.prefetch(next.name);\n }, [stealth, session.current?.wordIndex, audio, cfg.autoplayPronunciation, loaded.playlist]);\n\n void tick;\n\n useInput(\n (input, key) => {\n if (key.ctrl && input === 'i') {\n setInfoVisible((v) => !v);\n return;\n }\n },\n { isActive: stealth && phase === 'typing' },\n );\n\n useInput(\n (_input, key) => {\n if (key.return) {\n setPhase('typing');\n return;\n }\n if (key.escape) {\n goBack();\n return;\n }\n },\n { isActive: phase === 'paused' },\n );\n\n useInput(\n (input, key) => {\n if (key.escape) {\n goBack();\n return;\n }\n if (key.return) {\n const nextIdx = chapterIndex + 1;\n if (mode === 'loop') {\n nav.replace({\n name: 'practice',\n params: { dictId, chapterIndex, mode, stealth: params.stealth },\n });\n } else if (mode === 'review' || nextIdx >= loaded.totalChapters) {\n goBack();\n } else {\n nav.replace({\n name: 'practice',\n params: { dictId, chapterIndex: nextIdx, mode, stealth: params.stealth },\n });\n }\n return;\n }\n if (input === 'm') {\n nav.replace({\n name: 'practice',\n params: { dictId, chapterIndex: 0, mode: 'review', stealth: params.stealth },\n });\n return;\n }\n },\n { isActive: phase === 'summary' },\n );\n\n const completed = session.results.length;\n const errors = session.results.reduce((a, r) => a + r.errors, 0);\n const elapsedMs = Date.now() - session.startedAt;\n const minutes = elapsedMs / 60000;\n const wpm = minutes > 0 ? Math.round((completed / minutes) * 10) / 10 : 0;\n\n const summary = phase === 'summary' ? sessionSummary(session) : null;\n\n if (stealth) {\n if (phase === 'paused') return <StealthPaused />;\n if (phase === 'summary' && summary) {\n const sMinutes = summary.durationMs / 60000;\n const sWpm = sMinutes > 0 ? Math.round((summary.wordCount / sMinutes) * 10) / 10 : 0;\n const sErrWords = Object.keys(summary.perWordErrors).length;\n const sAcc =\n summary.wordCount === 0 ? 1 : Math.max(0, (summary.wordCount - sErrWords) / summary.wordCount);\n const sAccPct = Math.round(sAcc * 1000) / 10;\n return (\n <StealthSummary\n wordCount={summary.wordCount}\n errors={summary.errors}\n durationMs={summary.durationMs}\n wpm={sWpm}\n accPct={sAccPct}\n />\n );\n }\n const currentWord = session.current\n ? loaded.playlist[session.current.wordIndex]\n : loaded.playlist[loaded.playlist.length - 1];\n const inputState = session.current?.input ?? { target: '', typed: '', errorsThisWord: 0 };\n const errWords = new Set(\n session.results.filter((r) => r.errors > 0).map((r) => r.word),\n ).size;\n const accFrac =\n completed === 0 ? 1 : Math.max(0, (completed - errWords) / completed);\n const accPct = Math.round(accFrac * 1000) / 10;\n const chapterLabel =\n mode === 'review'\n ? 'review'\n : `ch ${chapterIndex + 1}/${loaded.totalChapters}`;\n return (\n <StealthTyping\n target={currentWord?.name ?? ''}\n typed={inputState.typed}\n hideTarget={mode === 'dictation'}\n phonetic={pickPhonetic(currentWord, cfg.accent)}\n translation={currentWord?.trans ?? []}\n error={lastEffect === 'wrong'}\n info={{\n visible: infoVisible,\n dictName: truncateName(dictName, 24),\n chapterLabel,\n completed,\n total: loaded.playlist.length,\n wpm,\n accPct,\n }}\n />\n );\n }\n\n if (phase === 'paused') {\n return (\n <PausedView\n dictName={dictName}\n chapterIndex={chapterIndex}\n totalChapters={loaded.totalChapters}\n mode={mode}\n completed={completed}\n total={loaded.playlist.length}\n />\n );\n }\n\n if (phase === 'summary' && summary) {\n return (\n <SummaryView\n dictName={dictName}\n chapterIndex={chapterIndex}\n totalChapters={loaded.totalChapters}\n mode={mode}\n summary={summary}\n />\n );\n }\n\n const currentWord = session.current\n ? loaded.playlist[session.current.wordIndex]\n : loaded.playlist[loaded.playlist.length - 1];\n const inputState = session.current?.input ?? { target: '', typed: '', errorsThisWord: 0 };\n\n return (\n <TypingLayout\n dictName={dictName}\n chapterIndex={chapterIndex}\n totalChapters={loaded.totalChapters}\n mode={mode}\n accent={cfg.accent}\n completed={completed}\n total={loaded.playlist.length}\n errors={errors}\n wpm={wpm}\n elapsedMs={elapsedMs}\n target={currentWord?.name ?? ''}\n typed={inputState.typed}\n flashError={lastEffect === 'wrong'}\n hideTarget={mode === 'dictation'}\n phonetic={pickPhonetic(currentWord, cfg.accent)}\n translation={currentWord?.trans ?? []}\n />\n );\n}\n\nfunction pickPhonetic(word: Word | undefined, accent: 'us' | 'uk'): string | null {\n if (!word) return null;\n const p = accent === 'us' ? word.usphone : word.ukphone;\n return p ? `/${p}/` : null;\n}\n\nfunction fmtTime(ms: number): string {\n const total = Math.floor(ms / 1000);\n const m = Math.floor(total / 60);\n const s = total % 60;\n return `${m}:${String(s).padStart(2, '0')}`;\n}\n\nfunction TypingLayout(props: {\n dictName: string;\n chapterIndex: number;\n totalChapters: number;\n mode: Mode;\n accent: 'us' | 'uk';\n completed: number;\n total: number;\n errors: number;\n wpm: number;\n elapsedMs: number;\n target: string;\n typed: string;\n flashError: boolean;\n hideTarget: boolean;\n phonetic: string | null;\n translation: string[];\n}) {\n const t = useStrings();\n const progressFrac = props.total === 0 ? 0 : props.completed / props.total;\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <StatusBar\n dictName={props.dictName}\n chapterIndex={props.chapterIndex}\n totalChapters={props.totalChapters}\n mode={props.mode}\n accent={props.accent}\n completed={props.completed}\n total={props.total}\n elapsedMs={props.elapsedMs}\n />\n\n <Box flexGrow={1} flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\">\n <BigWord\n target={props.target}\n typed={props.typed}\n error={props.flashError}\n hideTarget={props.hideTarget}\n />\n\n {props.phonetic && (\n <Box marginTop={3}>\n <Text italic color={PALETTE.muted}>\n {props.phonetic}\n </Text>\n </Box>\n )}\n\n {props.translation.length > 0 && (\n <Box marginTop={2} flexDirection=\"column\" alignItems=\"center\">\n {props.translation.slice(0, 2).map((tr, i) => (\n <Text key={i} color={PALETTE.primary}>\n {tr}\n </Text>\n ))}\n </Box>\n )}\n </Box>\n\n <Box flexDirection=\"column\">\n <ProgressBar frac={progressFrac} />\n <Box justifyContent=\"center\" marginTop={1}>\n <Text color={PALETTE.muted}>\n {props.completed}/{props.total} · {fmtTime(props.elapsedMs)} · {props.wpm} {t.practice.statCards.wpm} · {props.errors} {t.practice.statCards.errors}\n </Text>\n </Box>\n <Box justifyContent=\"center\" marginTop={1}>\n <Text color={PALETTE.muted}>{t.practice.footers.typing}</Text>\n </Box>\n </Box>\n </Box>\n );\n}\n\nfunction StatusBar(props: {\n dictName: string;\n chapterIndex: number;\n totalChapters: number;\n mode: Mode;\n accent: 'us' | 'uk';\n completed: number;\n total: number;\n elapsedMs: number;\n}) {\n const t = useStrings();\n const modeName = t.practice.modes[props.mode];\n const accentName = t.practice.accents[props.accent];\n const name = truncateName(props.dictName, 20);\n const left =\n props.mode === 'review'\n ? `${name} · ${t.practice.reviewLabel} · ${accentName}`\n : `${name} · ${t.practice.chapterLabel(props.chapterIndex + 1, props.totalChapters)} · ${modeName} · ${accentName}`;\n const right = `${props.completed}/${props.total} · ${fmtTime(props.elapsedMs)}`;\n return (\n <Box>\n <Text color={PALETTE.muted}>{left}</Text>\n <Box flexGrow={1} />\n <Text color={PALETTE.muted}>{right}</Text>\n </Box>\n );\n}\n\nfunction ProgressBar({ frac }: { frac: number }) {\n const cols = process.stdout.columns ?? 80;\n const width = Math.max(20, Math.min(72, cols - 16));\n const filled = Math.round(width * Math.max(0, Math.min(1, frac)));\n const empty = width - filled;\n return (\n <Box justifyContent=\"center\">\n <Text color={PALETTE.accent}>{'━'.repeat(filled)}</Text>\n <Text color={PALETTE.muted}>{'─'.repeat(empty)}</Text>\n </Box>\n );\n}\n\nfunction PausedView(props: {\n dictName: string;\n chapterIndex: number;\n totalChapters: number;\n mode: Mode;\n completed: number;\n total: number;\n}) {\n const t = useStrings();\n const frac = props.total === 0 ? 0 : props.completed / props.total;\n const subtitle =\n props.mode === 'review'\n ? `${truncateName(props.dictName, 20)} · ${t.practice.reviewLabel}`\n : `${truncateName(props.dictName, 20)} · ${t.practice.pause.chapter(props.chapterIndex + 1, props.totalChapters)}`;\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text bold color={PALETTE.warning}>\n {t.practice.pause.title}\n </Text>\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{subtitle}</Text>\n </Box>\n <Box marginTop={2}>\n <ProgressBar frac={frac} />\n </Box>\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{t.practice.pause.progress(props.completed, props.total)}</Text>\n </Box>\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>{t.practice.pause.hint}</Text>\n </Box>\n </Box>\n );\n}\n\nfunction ErrorView({ msg }: { msg: string }) {\n const t = useStrings();\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.error}>{msg}</Text>\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>Esc {t.common.back}</Text>\n </Box>\n <BackKey />\n </Box>\n );\n}\n\nfunction BackKey() {\n const nav = useNav();\n useInput((_input, key) => {\n if (key.escape) nav.back();\n });\n return null;\n}\n\nfunction Centered({ text, color }: { text: string; color: string }) {\n return (\n <Box alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={color}>{text}</Text>\n </Box>\n );\n}\n\nfunction SummaryView(props: {\n dictName: string;\n chapterIndex: number;\n totalChapters: number;\n mode: Mode;\n summary: { wordCount: number; errors: number; durationMs: number; perWordErrors: Record<string, number> };\n}) {\n const { summary } = props;\n const minutes = summary.durationMs / 60000;\n const wpm = minutes > 0 ? Math.round((summary.wordCount / minutes) * 10) / 10 : 0;\n const errorWords = Object.keys(summary.perWordErrors).length;\n const acc = summary.wordCount === 0 ? 1 : Math.max(0, (summary.wordCount - errorWords) / summary.wordCount);\n const accPct = Math.round(acc * 1000) / 10;\n\n const t = useStrings();\n const modeName = t.practice.modes[props.mode];\n const name = truncateName(props.dictName, 20);\n const subtitle =\n props.mode === 'review'\n ? `${name} · ${t.practice.reviewLabel}`\n : `${name} · ${t.practice.chapterLabel(props.chapterIndex + 1, props.totalChapters)} · ${modeName}`;\n\n const nextLabel =\n props.mode === 'loop'\n ? t.practice.summary.loopAgain\n : props.mode === 'review' || props.chapterIndex + 1 >= props.totalChapters\n ? t.practice.summary.backMenu\n : t.practice.summary.nextChapter;\n const footer = `Enter ${nextLabel} · m ${t.practice.summary.reviewMistakes} · Esc ${t.practice.summary.backMenu}`;\n\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" paddingY={1} width=\"100%\" height=\"100%\">\n <Text bold color={PALETTE.success}>\n {t.practice.chapterComplete}\n </Text>\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{subtitle}</Text>\n </Box>\n\n <Box marginTop={3} flexDirection=\"row\" justifyContent=\"center\">\n <StatCard label={t.practice.statCards.words} value={String(summary.wordCount)} color={PALETTE.text} />\n <StatCard\n label={t.practice.statCards.errors}\n value={String(summary.errors)}\n color={summary.errors > 0 ? PALETTE.error : PALETTE.muted}\n />\n <StatCard label={t.practice.statCards.wpm} value={String(wpm)} color={PALETTE.accent} />\n <StatCard label={t.practice.statCards.accuracy} value={`${accPct}%`} color={PALETTE.accent} />\n </Box>\n\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>{t.practice.statCards.elapsed(fmtTime(summary.durationMs))}</Text>\n </Box>\n\n <Box flexGrow={1} />\n\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>{footer}</Text>\n </Box>\n </Box>\n );\n}\n\nfunction StatCard({ label, value, color }: { label: string; value: string; color: string }) {\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" marginX={3}>\n <Text bold color={color}>{value}</Text>\n <Text color={PALETTE.muted}>{label}</Text>\n </Box>\n );\n}\n","export function shuffle<T>(arr: readonly T[], rng: () => number = Math.random): T[] {\n const out = [...arr];\n for (let i = out.length - 1; i > 0; i--) {\n const j = Math.floor(rng() * (i + 1));\n const tmp = out[i]!;\n out[i] = out[j]!;\n out[j] = tmp;\n }\n return out;\n}\n\nexport function mulberry32(seed: number): () => number {\n let t = seed >>> 0;\n return () => {\n t = (t + 0x6d2b79f5) >>> 0;\n let r = Math.imul(t ^ (t >>> 15), 1 | t);\n r = (r + Math.imul(r ^ (r >>> 7), 61 | r)) ^ r;\n return ((r ^ (r >>> 14)) >>> 0) / 4294967296;\n };\n}\n","import type { Word } from './dictionary.js';\nimport { shuffle, mulberry32 } from '../util/shuffle.js';\n\nexport type Mode = 'order' | 'dictation' | 'review' | 'random' | 'loop';\n\nexport function chunkChapters(words: Word[], chapterSize: number): Word[][] {\n if (chapterSize <= 0) throw new Error('chapterSize must be positive');\n const chunks: Word[][] = [];\n for (let i = 0; i < words.length; i += chapterSize) {\n chunks.push(words.slice(i, i + chapterSize));\n }\n return chunks;\n}\n\nexport function chapterCount(totalWords: number, chapterSize: number): number {\n return Math.ceil(totalWords / chapterSize);\n}\n\n/**\n * Build a play list for a chapter, applying the given mode.\n * - order: return as-is\n * - dictation: same as order (hide-the-word behavior is UI-only)\n * - random: single shuffled pass\n * - loop: return as-is; the practice screen drives the repeat\n * - review: caller passes the mistake-book words, we just chunk those\n */\nexport function buildPlaylist(chapter: Word[], mode: Mode, seed?: number): Word[] {\n if (mode === 'random') {\n const rng = seed === undefined ? Math.random : mulberry32(seed);\n return shuffle(chapter, rng);\n }\n return chapter;\n}\n","export type InputState = {\n target: string;\n typed: string;\n errorsThisWord: number;\n};\n\nexport type InputEvent =\n | { type: 'char'; ch: string }\n | { type: 'backspace' }\n | { type: 'reset' };\n\nexport type InputEffect = 'none' | 'progress' | 'wrong' | 'correct' | 'skipped';\n\nexport function initialState(target: string): InputState {\n return { target, typed: '', errorsThisWord: 0 };\n}\n\nexport function reduce(state: InputState, ev: InputEvent): { state: InputState; effect: InputEffect } {\n switch (ev.type) {\n case 'reset':\n return { state: { ...state, typed: '' }, effect: 'none' };\n case 'backspace': {\n if (state.typed.length === 0) return { state, effect: 'none' };\n return { state: { ...state, typed: state.typed.slice(0, -1) }, effect: 'none' };\n }\n case 'char': {\n const candidate = state.typed + ev.ch;\n // Compare by code-point index, not byte length, to handle unicode safely.\n const targetUpToCandidate = [...state.target].slice(0, [...candidate].length).join('');\n if (candidate === targetUpToCandidate) {\n if (candidate.length === state.target.length) {\n return { state: { ...state, typed: candidate }, effect: 'correct' };\n }\n return { state: { ...state, typed: candidate }, effect: 'progress' };\n }\n return {\n state: { ...state, typed: '', errorsThisWord: state.errorsThisWord + 1 },\n effect: 'wrong',\n };\n }\n }\n}\n","import type { Word } from './dictionary.js';\nimport { initialState, reduce, type InputEvent, type InputState, type InputEffect } from './input-buffer.js';\n\nexport type SessionWordResult = { word: string; errors: number; durationMs: number; skipped?: boolean };\n\nexport type Session = {\n startedAt: number;\n results: SessionWordResult[];\n current: { wordIndex: number; wordStartedAt: number; input: InputState } | null;\n finishedAt: number | null;\n playlist: Word[];\n};\n\nexport function startSession(playlist: Word[], now = Date.now()): Session {\n if (playlist.length === 0) {\n return { startedAt: now, results: [], current: null, finishedAt: now, playlist };\n }\n return {\n startedAt: now,\n results: [],\n current: { wordIndex: 0, wordStartedAt: now, input: initialState(playlist[0]!.name) },\n finishedAt: null,\n playlist,\n };\n}\n\nexport function feedSession(session: Session, ev: InputEvent, now = Date.now()): { session: Session; effect: InputEffect } {\n if (!session.current) return { session, effect: 'none' };\n const { state, effect } = reduce(session.current.input, ev);\n if (effect === 'correct') {\n const finished: SessionWordResult = {\n word: state.target,\n errors: state.errorsThisWord,\n durationMs: now - session.current.wordStartedAt,\n };\n const nextIndex = session.current.wordIndex + 1;\n const results = [...session.results, finished];\n if (nextIndex >= session.playlist.length) {\n return {\n session: { ...session, results, current: null, finishedAt: now },\n effect,\n };\n }\n return {\n session: {\n ...session,\n results,\n current: {\n wordIndex: nextIndex,\n wordStartedAt: now,\n input: initialState(session.playlist[nextIndex]!.name),\n },\n },\n effect,\n };\n }\n return {\n session: {\n ...session,\n current: { ...session.current, input: state },\n },\n effect,\n };\n}\n\nexport function skipSession(session: Session, now = Date.now()): { session: Session; effect: InputEffect } {\n if (!session.current) return { session, effect: 'none' };\n const result: SessionWordResult = {\n word: session.current.input.target,\n errors: 0,\n durationMs: now - session.current.wordStartedAt,\n skipped: true,\n };\n const nextIndex = session.current.wordIndex + 1;\n const results = [...session.results, result];\n if (nextIndex >= session.playlist.length) {\n return {\n session: { ...session, results, current: null, finishedAt: now },\n effect: 'skipped',\n };\n }\n return {\n session: {\n ...session,\n results,\n current: {\n wordIndex: nextIndex,\n wordStartedAt: now,\n input: initialState(session.playlist[nextIndex]!.name),\n },\n },\n effect: 'skipped',\n };\n}\n\nexport function sessionSummary(session: Session): {\n wordCount: number;\n errors: number;\n durationMs: number;\n perWordErrors: Record<string, number>;\n} {\n const errors = session.results.reduce((a, r) => a + r.errors, 0);\n const durationMs =\n (session.finishedAt ?? Date.now()) - session.startedAt;\n const perWordErrors: Record<string, number> = {};\n for (const r of session.results) {\n if (r.errors > 0) perWordErrors[r.word] = (perWordErrors[r.word] ?? 0) + r.errors;\n }\n return { wordCount: session.results.length, errors, durationMs, perWordErrors };\n}\n","import { z } from 'zod';\nimport { paths } from '../infra/paths.js';\nimport { readJson, writeJsonAtomic } from '../infra/fs-store.js';\n\nexport const MistakeBookSchema = z.record(\n z.string(),\n z.object({\n count: z.number().int().nonnegative(),\n lastSeen: z.string(),\n dictIds: z.array(z.string()).default([]),\n }),\n);\n\nexport type MistakeBook = z.infer<typeof MistakeBookSchema>;\n\nexport async function loadMistakes(): Promise<MistakeBook> {\n const raw = await readJson<unknown>(paths.mistakes);\n if (!raw) return {};\n const parsed = MistakeBookSchema.safeParse(raw);\n if (!parsed.success) {\n console.warn('Mistake book is corrupt; starting fresh');\n return {};\n }\n return parsed.data;\n}\n\nexport async function saveMistakes(book: MistakeBook): Promise<void> {\n await writeJsonAtomic(paths.mistakes, book);\n}\n\nexport function bump(book: MistakeBook, word: string, dictId: string, delta = 1): MistakeBook {\n const prev = book[word] ?? { count: 0, lastSeen: new Date(0).toISOString(), dictIds: [] };\n const dictIds = prev.dictIds.includes(dictId) ? prev.dictIds : [...prev.dictIds, dictId];\n return {\n ...book,\n [word]: {\n count: prev.count + delta,\n lastSeen: new Date().toISOString(),\n dictIds,\n },\n };\n}\n\nexport function topN(book: MistakeBook, n: number): Array<[string, MistakeBook[string]]> {\n return Object.entries(book)\n .sort((a, b) => b[1].count - a[1].count)\n .slice(0, n);\n}\n","import { useEffect, useReducer, useRef, useState } from 'react';\nimport { useInput, useApp } from 'ink';\nimport type { Word } from '../../domain/dictionary.js';\nimport { startSession, feedSession, skipSession, type Session } from '../../domain/session.js';\nimport type { InputEffect } from '../../domain/input-buffer.js';\n\ntype Action =\n | { type: 'event'; input: string; key: { backspace?: boolean; delete?: boolean; tab?: boolean; escape?: boolean; return?: boolean; ctrl?: boolean }; now: number }\n | { type: 'start'; playlist: Word[]; now: number }\n | { type: 'skip'; now: number };\n\nfunction reducer(state: { session: Session; lastEffect: InputEffect | null }, action: Action) {\n if (action.type === 'start') {\n return { session: startSession(action.playlist, action.now), lastEffect: null };\n }\n if (action.type === 'skip') {\n const r = skipSession(state.session, action.now);\n return { session: r.session, lastEffect: r.effect };\n }\n if (action.type === 'event') {\n if (action.key.backspace || action.key.delete) {\n const r = feedSession(state.session, { type: 'backspace' }, action.now);\n return { session: r.session, lastEffect: r.effect };\n }\n if (action.input.length === 0) return state;\n let session = state.session;\n let lastEffect: InputEffect | null = state.lastEffect;\n for (const c of action.input) {\n const r = feedSession(session, { type: 'char', ch: c }, action.now);\n session = r.session;\n lastEffect = r.effect;\n if (session.finishedAt !== null) break;\n }\n return { session, lastEffect };\n }\n return state;\n}\n\nexport type UseWordLoopOpts = {\n playlist: Word[];\n onComplete: (session: Session) => void;\n onTab?: () => void;\n onEscape?: () => void;\n onSkip?: () => void;\n enabled?: boolean;\n};\n\nexport function useWordLoop({ playlist, onComplete, onTab, onEscape, onSkip, enabled = true }: UseWordLoopOpts) {\n const [state, dispatch] = useReducer(reducer, undefined, () => ({\n session: startSession(playlist, Date.now()),\n lastEffect: null as InputEffect | null,\n }));\n const completedRef = useRef(false);\n const [tick, setTick] = useState(0);\n const { exit } = useApp();\n\n useInput(\n (input, key) => {\n if (key.ctrl && input === 'c') {\n exit();\n return;\n }\n if (key.ctrl && input === 'n') {\n onSkip?.();\n dispatch({ type: 'skip', now: Date.now() });\n return;\n }\n if (key.escape) {\n onEscape?.();\n return;\n }\n if (key.tab) {\n onTab?.();\n return;\n }\n if (key.upArrow || key.downArrow || key.leftArrow || key.rightArrow || key.return) return;\n if (key.ctrl || key.meta) return;\n const cleaned = [...input].filter((c) => {\n const code = c.codePointAt(0)!;\n return code === 0x20 || (code >= 0x21 && code !== 0x7f);\n }).join('');\n if (cleaned.length === 0) return;\n dispatch({ type: 'event', input: cleaned, key, now: Date.now() });\n },\n { isActive: enabled },\n );\n\n useEffect(() => {\n if (state.session.finishedAt !== null && !completedRef.current) {\n completedRef.current = true;\n onComplete(state.session);\n }\n }, [state.session, onComplete]);\n\n useEffect(() => {\n if (state.session.finishedAt !== null) return;\n const id = setInterval(() => setTick((t) => t + 1), 1000);\n return () => clearInterval(id);\n }, [state.session.finishedAt]);\n\n return { session: state.session, lastEffect: state.lastEffect, tick };\n}\n","import { useEffect, useRef } from 'react';\nimport {\n initAudio,\n playCorrect,\n playWrong,\n playKeystroke,\n playPronunciation,\n prefetchPronunciation,\n} from '../../infra/audio.js';\n\ntype Opts = {\n enabled: boolean;\n accent: 'us' | 'uk';\n autoplayPronunciation: boolean;\n};\n\nexport type AudioControls = {\n keystroke: () => void;\n correct: () => void;\n wrong: () => void;\n pronounce: (word: string) => void;\n prefetch: (word: string) => void;\n};\n\nexport function useAudio(opts: Opts): AudioControls {\n const initedRef = useRef(false);\n useEffect(() => {\n if (initedRef.current) return;\n initedRef.current = true;\n initAudio(!opts.enabled).catch(() => undefined);\n }, [opts.enabled]);\n\n return {\n keystroke: () => opts.enabled && playKeystroke(),\n correct: () => opts.enabled && playCorrect(),\n wrong: () => opts.enabled && playWrong(),\n pronounce: (word) => {\n if (!opts.enabled) return;\n if (opts.autoplayPronunciation) void playPronunciation(word, opts.accent);\n },\n prefetch: (word) => {\n if (!opts.enabled) return;\n void prefetchPronunciation(word, opts.accent);\n },\n };\n}\n","import { useCallback } from 'react';\nimport { appendSession, type SessionRecord } from '../../domain/stats.js';\nimport { loadMistakes, saveMistakes, bump } from '../../domain/mistakes.js';\nimport { addChapter as trackChapter } from '../../infra/session-tracker.js';\nimport type { Mode } from '../../domain/chapters.js';\n\ntype Summary = {\n wordCount: number;\n errors: number;\n durationMs: number;\n perWordErrors: Record<string, number>;\n};\n\nexport function useSessionPersistence(meta: { dictId: string; chapterIndex: number; mode: Mode }) {\n return useCallback(\n async (summary: Summary): Promise<void> => {\n const rec: SessionRecord = {\n ts: new Date().toISOString(),\n dictId: meta.dictId,\n chapter: meta.chapterIndex,\n mode: meta.mode,\n wordCount: summary.wordCount,\n errors: summary.errors,\n durationMs: summary.durationMs,\n perWordErrors: summary.perWordErrors,\n };\n await appendSession(rec);\n trackChapter({\n dictId: meta.dictId,\n chapterIndex: meta.chapterIndex,\n mode: meta.mode,\n wordCount: summary.wordCount,\n errors: summary.errors,\n durationMs: summary.durationMs,\n perWordErrors: summary.perWordErrors,\n });\n const dirty = Object.entries(summary.perWordErrors).filter(([, n]) => n > 0);\n if (dirty.length === 0) return;\n let book = await loadMistakes();\n for (const [word, n] of dirty) book = bump(book, word, meta.dictId, n);\n await saveMistakes(book);\n },\n [meta.dictId, meta.chapterIndex, meta.mode],\n );\n}\n","import { z } from 'zod';\nimport { paths } from '../infra/paths.js';\nimport { appendJsonl, readJsonl } from '../infra/fs-store.js';\n\nexport const SessionRecordSchema = z.object({\n ts: z.string(),\n dictId: z.string(),\n chapter: z.number().int().nonnegative(),\n mode: z.string(),\n wordCount: z.number().int().nonnegative(),\n errors: z.number().int().nonnegative(),\n durationMs: z.number().int().nonnegative(),\n perWordErrors: z.record(z.string(), z.number().int().nonnegative()).default({}),\n});\n\nexport type SessionRecord = z.infer<typeof SessionRecordSchema>;\n\nexport async function appendSession(record: SessionRecord): Promise<void> {\n await appendJsonl(paths.stats, record);\n}\n\nexport async function loadSessions(): Promise<SessionRecord[]> {\n const rows = await readJsonl<unknown>(paths.stats);\n return rows\n .map((r) => SessionRecordSchema.safeParse(r))\n .filter((r): r is { success: true; data: SessionRecord } => r.success)\n .map((r) => r.data);\n}\n\nexport function computeWPM(record: SessionRecord): number {\n if (record.durationMs === 0) return 0;\n const minutes = record.durationMs / 60000;\n return Math.round((record.wordCount / minutes) * 10) / 10;\n}\n\nexport function accuracy(record: SessionRecord): number {\n // Word-level: fraction of words finished without any mistake (first-try rate).\n if (record.wordCount === 0) return 1;\n const wordsWithErrors = Object.keys(record.perWordErrors).length;\n return Math.max(0, Math.min(1, (record.wordCount - wordsWithErrors) / record.wordCount));\n}\n\nexport function dailyStreak(sessions: SessionRecord[], now = new Date()): number {\n if (sessions.length === 0) return 0;\n const days = new Set<string>();\n for (const s of sessions) days.add(s.ts.slice(0, 10));\n let streak = 0;\n const cur = new Date(now);\n while (true) {\n const key = cur.toISOString().slice(0, 10);\n if (!days.has(key)) break;\n streak++;\n cur.setUTCDate(cur.getUTCDate() - 1);\n }\n return streak;\n}\n\nconst SPARK = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];\n\nexport function sparkline(values: number[]): string {\n if (values.length === 0) return '';\n const max = Math.max(...values, 1);\n const min = Math.min(...values, 0);\n const range = Math.max(1, max - min);\n return values\n .map((v) => {\n const idx = Math.floor(((v - min) / range) * (SPARK.length - 1));\n return SPARK[Math.max(0, Math.min(SPARK.length - 1, idx))]!;\n })\n .join('');\n}\n\nexport type DailyBucket = { date: string; wpm: number; accuracy: number; sessions: number };\n\nexport function dailyBuckets(sessions: SessionRecord[], days: number, now = new Date()): DailyBucket[] {\n const out: DailyBucket[] = [];\n const byDay = new Map<string, SessionRecord[]>();\n for (const s of sessions) {\n const key = s.ts.slice(0, 10);\n const arr = byDay.get(key) ?? [];\n arr.push(s);\n byDay.set(key, arr);\n }\n const cur = new Date(now);\n cur.setUTCDate(cur.getUTCDate() - (days - 1));\n for (let i = 0; i < days; i++) {\n const key = cur.toISOString().slice(0, 10);\n const todays = byDay.get(key) ?? [];\n if (todays.length === 0) {\n out.push({ date: key, wpm: 0, accuracy: 0, sessions: 0 });\n } else {\n const wpm = todays.reduce((a, s) => a + computeWPM(s), 0) / todays.length;\n const acc = todays.reduce((a, s) => a + accuracy(s), 0) / todays.length;\n out.push({ date: key, wpm, accuracy: acc, sessions: todays.length });\n }\n cur.setUTCDate(cur.getUTCDate() + 1);\n }\n return out;\n}\n","type ChapterEntry = {\n dictId: string;\n chapterIndex: number;\n mode: string;\n wordCount: number;\n errors: number;\n durationMs: number;\n perWordErrors: Record<string, number>;\n};\n\ntype State = {\n startedAt: number | null;\n chapters: ChapterEntry[];\n};\n\nconst state: State = {\n startedAt: null,\n chapters: [],\n};\n\nexport function start(now = Date.now()): void {\n if (state.startedAt === null) state.startedAt = now;\n}\n\nexport function addChapter(entry: ChapterEntry): void {\n if (state.startedAt === null) state.startedAt = Date.now();\n state.chapters.push(entry);\n}\n\nexport type SessionReport = {\n startedAt: number | null;\n totalDurationMs: number;\n chaptersCompleted: number;\n wordCount: number;\n errors: number;\n wpm: number;\n accuracy: number;\n newMistakeWords: number;\n practiceMs: number;\n};\n\nexport function report(now = Date.now()): SessionReport {\n const chapters = state.chapters;\n const wordCount = chapters.reduce((a, c) => a + c.wordCount, 0);\n const errors = chapters.reduce((a, c) => a + c.errors, 0);\n const practiceMs = chapters.reduce((a, c) => a + c.durationMs, 0);\n const minutes = practiceMs / 60000;\n const wpm = minutes > 0 ? Math.round((wordCount / minutes) * 10) / 10 : 0;\n const errorWordSet = new Set<string>();\n for (const c of chapters) {\n for (const w of Object.keys(c.perWordErrors)) errorWordSet.add(w);\n }\n const accuracy = wordCount === 0 ? 1 : Math.max(0, (wordCount - errorWordSet.size) / wordCount);\n return {\n startedAt: state.startedAt,\n totalDurationMs: state.startedAt === null ? 0 : now - state.startedAt,\n chaptersCompleted: chapters.length,\n wordCount,\n errors,\n wpm,\n accuracy,\n newMistakeWords: errorWordSet.size,\n practiceMs,\n };\n}\n\nexport function reset(): void {\n state.startedAt = null;\n state.chapters = [];\n}\n","import { Box, Text } from 'ink';\nimport { useStrings } from '../../i18n/context.js';\n\nconst TYPED = '#d4d4d4';\nconst UNTYPED = '#808080';\nconst DIM = '#6b6b6b';\n\nfunction fmtTime(ms: number): string {\n const total = Math.floor(ms / 1000);\n const m = Math.floor(total / 60);\n const s = total % 60;\n return `${m}:${String(s).padStart(2, '0')}`;\n}\n\nexport function StealthTyping(props: {\n target: string;\n typed: string;\n hideTarget: boolean;\n phonetic: string | null;\n translation: string[];\n error: boolean;\n info: {\n visible: boolean;\n dictName: string;\n chapterLabel: string;\n completed: number;\n total: number;\n wpm: number;\n accPct: number;\n };\n}) {\n const t = useStrings();\n const target = [...props.target];\n const typed = [...props.typed];\n\n return (\n <Box flexDirection=\"column\" width=\"100%\" height=\"100%\" paddingX={4} paddingY={3}>\n <Box flexGrow={1} />\n <Box>\n <Text color={UNTYPED}>[</Text>\n {target.map((ch, i) => {\n const isTyped = i < typed.length;\n const display = props.hideTarget && !isTyped ? '_' : isTyped ? typed[i]! : ch;\n const color = isTyped ? TYPED : UNTYPED;\n return (\n <Text key={i} color={color} inverse={props.error && isTyped && i === typed.length - 1}>\n {display}\n </Text>\n );\n })}\n <Text color={UNTYPED}>]</Text>\n </Box>\n <Box>\n {props.phonetic && <Text color={DIM}>{props.phonetic}</Text>}\n {props.phonetic && props.translation.length > 0 && <Text color={DIM}>{' · '}</Text>}\n {props.translation.length > 0 && (\n <Text color={DIM}>{props.translation.slice(0, 1).join('')}</Text>\n )}\n </Box>\n <Box>\n {props.info.visible ? (\n <Text color={DIM}>\n {t.stealth.infoFmt(\n props.info.dictName,\n props.info.chapterLabel,\n props.info.completed,\n props.info.total,\n props.info.wpm,\n props.info.accPct,\n )}\n </Text>\n ) : (\n <Text> </Text>\n )}\n </Box>\n <Box flexGrow={3} />\n </Box>\n );\n}\n\nexport function StealthPaused() {\n const t = useStrings();\n return (\n <Box flexDirection=\"column\" width=\"100%\" height=\"100%\" paddingX={4} paddingY={3}>\n <Box flexGrow={1} />\n <Box>\n <Text color={UNTYPED}>{t.stealth.paused}</Text>\n </Box>\n <Box>\n <Text color={DIM}>{t.stealth.resumeHint}</Text>\n </Box>\n <Box flexGrow={3} />\n </Box>\n );\n}\n\nexport function StealthSummary(props: {\n wordCount: number;\n errors: number;\n durationMs: number;\n wpm: number;\n accPct: number;\n}) {\n const t = useStrings();\n const line = `${t.stealth.chapterDone} · ${props.wordCount}w · ${props.wpm}wpm · ${props.accPct}% · ${fmtTime(props.durationMs)}`;\n return (\n <Box flexDirection=\"column\" width=\"100%\" height=\"100%\" paddingX={4} paddingY={3}>\n <Box flexGrow={1} />\n <Box>\n <Text color={UNTYPED}>{line}</Text>\n </Box>\n <Box>\n <Text color={DIM}>{t.stealth.nextHint}</Text>\n </Box>\n <Box flexGrow={3} />\n </Box>\n );\n}\n","import { useEffect, useMemo, useState } from 'react';\nimport { Box, Text, useInput, useStdout } from 'ink';\nimport { useNav, type DictParams } from '../nav.js';\nimport { useAppState } from '../app-state.js';\nimport { useStrings } from '../../i18n/context.js';\nimport { PALETTE } from '../components/BigWord.js';\nimport { ActionPanel, type ActionItem } from '../components/ActionPanel.js';\nimport { loadRegistry } from '../../infra/registry-store.js';\nimport {\n isLocallyAvailable,\n pullDictionary,\n removeDictionary,\n} from '../../infra/dict-downloader.js';\nimport type { DictionaryEntry } from '../../domain/dictionary.js';\nimport { filterRegistry } from '../../domain/dictionary.js';\n\ntype Row = { entry: DictionaryEntry; local: boolean };\ntype PendingAction =\n | { kind: 'pulling'; id: string }\n | { kind: 'removing'; id: string }\n | { kind: 'refreshing' }\n | { kind: 'error'; id: string; msg: string }\n | null;\n\ntype Panel = null | 'item' | 'more';\n\nexport function DictBrowser({ params }: { params?: DictParams }) {\n const nav = useNav();\n const { cfg, setCfg } = useAppState();\n const t = useStrings();\n const { stdout } = useStdout();\n const [rows, setRows] = useState<Row[]>([]);\n const [loading, setLoading] = useState(true);\n const [selected, setSelected] = useState(0);\n const [filter, setFilter] = useState('');\n const [pending, setPending] = useState<PendingAction>(null);\n const [tick, setTick] = useState(0);\n const [panel, setPanel] = useState<Panel>(null);\n\n const refresh = async () => {\n const reg = await loadRegistry();\n const flagged = await Promise.all(\n reg.map(async (e) => ({ entry: e, local: await isLocallyAvailable(e.id) })),\n );\n setRows(flagged);\n setLoading(false);\n };\n\n useEffect(() => {\n void refresh();\n }, [tick]);\n\n const filtered = useMemo(\n () => (filter ? rows.filter((r) => filterRegistry([r.entry], filter).length > 0) : rows),\n [filter, rows],\n );\n const safeSelected = Math.max(0, Math.min(filtered.length - 1, selected));\n const current = filtered[safeSelected];\n\n const rowsTotal = stdout?.rows ?? 24;\n const visibleH = Math.max(6, rowsTotal - 8);\n const half = Math.floor(visibleH / 2);\n const start = Math.max(0, Math.min(filtered.length - visibleH, safeSelected - half));\n const end = Math.min(filtered.length, start + visibleH);\n\n const goPractice = (id: string) => {\n nav.replace({\n name: 'practice',\n params: {\n dictId: id,\n chapterIndex: 0,\n mode: cfg.defaultMode,\n stealth: cfg.stealth === 'default',\n },\n });\n };\n\n const doSetDefault = async (id: string, navigate = true) => {\n await setCfg({ ...cfg, defaultDict: id });\n setPanel(null);\n if (navigate) {\n if (params?.pickerMode === 'choose-then-practice') {\n goPractice(id);\n } else {\n nav.back();\n }\n }\n };\n\n const doDelete = (id: string) => {\n setPanel(null);\n setPending({ kind: 'removing', id });\n void (async () => {\n try {\n await removeDictionary(id);\n setPending(null);\n setTick((n) => n + 1);\n } catch (err) {\n setPending({ kind: 'error', id, msg: (err as Error).message });\n }\n })();\n };\n\n const doPull = (id: string) => {\n setPanel(null);\n setPending({ kind: 'pulling', id });\n void (async () => {\n try {\n await pullDictionary(id);\n setPending(null);\n setTick((n) => n + 1);\n } catch (err) {\n setPending({ kind: 'error', id, msg: (err as Error).message });\n }\n })();\n };\n\n const doRefreshList = () => {\n setPanel(null);\n setPending({ kind: 'refreshing' });\n setTick((n) => n + 1);\n setPending(null);\n };\n\n useInput((input, key) => {\n if (panel !== null) return;\n\n if (key.escape) {\n nav.back();\n return;\n }\n if (key.upArrow) {\n setSelected((i) => Math.max(0, i - 1));\n return;\n }\n if (key.downArrow) {\n setSelected((i) => Math.min(filtered.length - 1, i + 1));\n return;\n }\n if (key.ctrl && input === 'k') {\n setPanel('more');\n return;\n }\n if (key.return) {\n if (current) setPanel('item');\n return;\n }\n if (key.backspace || key.delete) {\n setFilter((f) => f.slice(0, -1));\n setSelected(0);\n return;\n }\n if (input && !key.ctrl && !key.meta && input.length === 1) {\n setFilter((f) => f + input);\n setSelected(0);\n }\n });\n\n if (loading) {\n return (\n <Box alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.muted}>{t.dict.loading}</Text>\n </Box>\n );\n }\n\n const itemPanelItems: ActionItem[] = current\n ? [\n {\n label: t.dict.action.setDefault,\n run: () => void doSetDefault(current.entry.id, params?.pickerMode !== undefined),\n },\n {\n label: t.dict.action.practice,\n run: () => goPractice(current.entry.id),\n },\n {\n label: t.dict.action.delete,\n disabled: !current.local,\n run: () => doDelete(current.entry.id),\n },\n { label: t.common.cancel, run: () => setPanel(null) },\n ]\n : [];\n\n const morePanelItems: ActionItem[] = [\n {\n label: t.dict.command.pull,\n disabled: !current,\n run: () => current && doPull(current.entry.id),\n },\n {\n label: t.dict.command.import,\n disabled: true,\n run: () => undefined,\n },\n { label: t.dict.command.refreshList, run: () => doRefreshList() },\n { label: t.common.cancel, run: () => setPanel(null) },\n ];\n\n if (panel === 'item' && current) {\n return (\n <Box alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <ActionPanel\n title={`${t.dict.action.title} · ${current.entry.name}`}\n items={itemPanelItems}\n onClose={() => setPanel(null)}\n />\n </Box>\n );\n }\n if (panel === 'more') {\n return (\n <Box alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <ActionPanel\n title={t.dict.command.title}\n items={morePanelItems}\n onClose={() => setPanel(null)}\n />\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <Box>\n <Text bold color={PALETTE.accent}>\n {t.dict.title}\n </Text>\n <Box flexGrow={1} />\n <Text color={PALETTE.muted}>\n {filter ? `${t.dict.filterPlaceholder}: ${filter}_` : `${t.dict.filterPlaceholder}_`}\n </Text>\n <Text color={PALETTE.muted}>\n {' '}\n {t.dict.entries(filtered.length)}\n </Text>\n </Box>\n\n <Box marginTop={1} flexGrow={1}>\n <Box flexDirection=\"column\" width=\"75%\" paddingRight={1}>\n {filtered.slice(start, end).map((row, vi) => {\n const i = start + vi;\n const active = i === safeSelected;\n const isDefault = cfg.defaultDict === row.entry.id;\n return (\n <Box key={row.entry.id}>\n <Box width={2}>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>{active ? '▌ ' : ' '}</Text>\n </Box>\n <Box width={2}>\n <Text color={row.local ? PALETTE.accent : PALETTE.muted}>\n {row.local ? '●' : '○'}\n </Text>\n </Box>\n <Box width={2}>\n <Text color={isDefault ? PALETTE.success : PALETTE.muted}>\n {isDefault ? '★' : ' '}\n </Text>\n </Box>\n <Box flexGrow={1}>\n <Text bold={active} color={active ? PALETTE.text : PALETTE.muted} wrap=\"truncate\">\n {row.entry.name}\n </Text>\n </Box>\n <Box width={6}>\n <Text color={PALETTE.muted}>{String(row.entry.length).padStart(5)}</Text>\n </Box>\n </Box>\n );\n })}\n </Box>\n\n <Box flexDirection=\"column\" width=\"25%\" paddingLeft={1}>\n {current && (\n <>\n <Text bold color={PALETTE.text} wrap=\"wrap\">\n {current.entry.name}\n </Text>\n <Text color={PALETTE.muted}>{current.entry.id}</Text>\n <Box marginTop={1}>\n <Text color={PALETTE.muted} wrap=\"wrap\">\n {current.entry.language} · {current.entry.category}\n </Text>\n </Box>\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{t.dict.wordsLabel(current.entry.length)}</Text>\n </Box>\n {current.entry.description && (\n <Box marginTop={1}>\n <Text color={PALETTE.primary} wrap=\"wrap\">{current.entry.description}</Text>\n </Box>\n )}\n {current.entry.tags.length > 0 && (\n <Box marginTop={1}>\n <Text color={PALETTE.muted} wrap=\"wrap\">{t.dict.tagsLabel(current.entry.tags.join(', '))}</Text>\n </Box>\n )}\n <Box marginTop={1}>\n <Text color={current.local ? PALETTE.accent : PALETTE.muted}>\n {current.local ? t.dict.local : t.dict.notLocal}\n </Text>\n </Box>\n {cfg.defaultDict === current.entry.id && (\n <Box>\n <Text color={PALETTE.success}>{t.dict.defaultMark}</Text>\n </Box>\n )}\n </>\n )}\n </Box>\n </Box>\n\n {pending && (\n <Box marginTop={1}>\n {pending.kind === 'pulling' && (\n <Text color={PALETTE.warning}>{t.dict.pulling(pending.id)}</Text>\n )}\n {pending.kind === 'removing' && (\n <Text color={PALETTE.warning}>{t.dict.removing(pending.id)}</Text>\n )}\n {pending.kind === 'refreshing' && (\n <Text color={PALETTE.warning}>{t.dict.command.refreshList}…</Text>\n )}\n {pending.kind === 'error' && (\n <Text color={PALETTE.error}>{t.dict.errorOn(pending.id, pending.msg)}</Text>\n )}\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{t.dict.footer}</Text>\n </Box>\n </Box>\n );\n}\n","import { useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { PALETTE } from './BigWord.js';\n\nexport type ActionItem = {\n key?: string;\n label: string;\n disabled?: boolean;\n run: () => void | Promise<void>;\n};\n\ntype Props = {\n title: string;\n items: ActionItem[];\n onClose: () => void;\n};\n\nexport function ActionPanel({ title, items, onClose }: Props) {\n const enabledIndices = items\n .map((it, i) => (it.disabled ? -1 : i))\n .filter((i) => i >= 0);\n const initial = enabledIndices[0] ?? 0;\n const [selected, setSelected] = useState(initial);\n\n useInput((input, key) => {\n if (key.escape) {\n onClose();\n return;\n }\n if (key.upArrow) {\n const cur = enabledIndices.indexOf(selected);\n const next = enabledIndices[(cur - 1 + enabledIndices.length) % enabledIndices.length];\n if (next !== undefined) setSelected(next);\n return;\n }\n if (key.downArrow) {\n const cur = enabledIndices.indexOf(selected);\n const next = enabledIndices[(cur + 1) % enabledIndices.length];\n if (next !== undefined) setSelected(next);\n return;\n }\n if (key.return) {\n const item = items[selected];\n if (item && !item.disabled) {\n void item.run();\n }\n return;\n }\n for (let i = 0; i < items.length; i++) {\n const it = items[i]!;\n if (it.disabled) continue;\n if (it.key && input === it.key) {\n void it.run();\n return;\n }\n }\n });\n\n const maxLabel = Math.max(...items.map((it) => it.label.length));\n const width = Math.max(maxLabel + 8, title.length + 4, 24);\n\n return (\n <Box\n flexDirection=\"column\"\n borderStyle=\"round\"\n borderColor={PALETTE.accent}\n paddingX={2}\n paddingY={1}\n width={width}\n >\n <Box marginBottom={1}>\n <Text bold color={PALETTE.accent}>\n {title}\n </Text>\n </Box>\n {items.map((it, i) => {\n const active = i === selected;\n const color = it.disabled\n ? PALETTE.muted\n : active\n ? PALETTE.text\n : PALETTE.muted;\n return (\n <Box key={i}>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>\n {active ? '▌ ' : ' '}\n </Text>\n <Text bold={active} color={color}>\n {it.label}\n </Text>\n </Box>\n );\n })}\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>↑/↓ · Enter · Esc</Text>\n </Box>\n </Box>\n );\n}\n","import { useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { useNav } from '../nav.js';\nimport { useAppState } from '../app-state.js';\nimport { useStrings } from '../../i18n/context.js';\nimport { useDictName } from '../registry-context.js';\nimport { setByPath, type Config } from '../../infra/config-store.js';\nimport { PALETTE } from '../components/BigWord.js';\nimport { visibleWidth } from '../../util/text.js';\nimport { truncateName } from '../../util/dict-name.js';\nimport type { Strings } from '../../i18n/strings.js';\n\ntype FieldSpec =\n | { kind: 'enum'; path: string; labelKey: keyof Strings['config']['fields']; options: string[] }\n | { kind: 'bool'; path: string; labelKey: keyof Strings['config']['fields'] }\n | { kind: 'int'; path: string; labelKey: keyof Strings['config']['fields']; min: number; max: number }\n | { kind: 'string'; path: string; labelKey: keyof Strings['config']['fields'] }\n | { kind: 'dictRef'; path: 'defaultDict'; labelKey: keyof Strings['config']['fields'] };\n\nconst FIELDS: FieldSpec[] = [\n { kind: 'dictRef', path: 'defaultDict', labelKey: 'defaultDict' },\n { kind: 'enum', path: 'defaultMode', labelKey: 'defaultMode', options: ['order', 'dictation', 'review', 'random', 'loop'] },\n { kind: 'enum', path: 'accent', labelKey: 'accent', options: ['us', 'uk'] },\n { kind: 'enum', path: 'language', labelKey: 'language', options: ['auto', 'zh', 'en'] },\n { kind: 'enum', path: 'mirror', labelKey: 'mirror', options: ['jsdelivr', 'github'] },\n { kind: 'enum', path: 'stealth', labelKey: 'stealth', options: ['off', 'menu', 'default'] },\n { kind: 'int', path: 'chapterSize', labelKey: 'chapterSize', min: 1, max: 200 },\n { kind: 'bool', path: 'autoplayPronunciation', labelKey: 'autoplayPronunciation' },\n { kind: 'bool', path: 'sounds.master', labelKey: 'soundsMaster' },\n { kind: 'bool', path: 'sounds.keystroke', labelKey: 'soundsKeystroke' },\n { kind: 'bool', path: 'sounds.feedback', labelKey: 'soundsFeedback' },\n { kind: 'string', path: 'sounds.keySoundName', labelKey: 'soundsKeySound' },\n];\n\nfunction getByPath(cfg: Config, path: string): unknown {\n return path.split('.').reduce<unknown>((acc, k) => {\n if (acc && typeof acc === 'object') return (acc as Record<string, unknown>)[k];\n return undefined;\n }, cfg);\n}\n\nexport function ConfigEditor() {\n const nav = useNav();\n const { cfg, setCfg } = useAppState();\n const t = useStrings();\n const defaultDictName = useDictName(cfg.defaultDict);\n const [selected, setSelected] = useState(0);\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState('');\n const [error, setError] = useState<string | null>(null);\n\n const field = FIELDS[selected]!;\n const currentValue = getByPath(cfg, field.path);\n\n const commit = async (raw: string) => {\n try {\n const next = setByPath(cfg, field.path, raw);\n await setCfg(next);\n setEditing(false);\n setError(null);\n } catch (err) {\n setError((err as Error).message);\n }\n };\n\n useInput((input, key) => {\n if (editing && field.kind === 'string') {\n if (key.escape) {\n setEditing(false);\n setError(null);\n return;\n }\n if (key.return) {\n void commit(draft);\n return;\n }\n if (key.backspace || key.delete) {\n setDraft((d) => d.slice(0, -1));\n return;\n }\n if (input && !key.ctrl && !key.meta) setDraft((d) => d + input);\n return;\n }\n if (editing && field.kind === 'int') {\n if (key.escape) {\n setEditing(false);\n setError(null);\n return;\n }\n if (key.return) {\n void commit(draft);\n return;\n }\n if (key.backspace || key.delete) {\n setDraft((d) => d.slice(0, -1));\n return;\n }\n if (/^[0-9]$/.test(input)) setDraft((d) => d + input);\n return;\n }\n\n if (key.escape) {\n nav.back();\n return;\n }\n if (key.upArrow) {\n setSelected((i) => (i - 1 + FIELDS.length) % FIELDS.length);\n setError(null);\n return;\n }\n if (key.downArrow) {\n setSelected((i) => (i + 1) % FIELDS.length);\n setError(null);\n return;\n }\n if (field.kind === 'bool' && (input === ' ' || key.return)) {\n void commit(currentValue ? 'false' : 'true');\n return;\n }\n if (field.kind === 'enum' && (key.leftArrow || key.rightArrow)) {\n const idx = field.options.indexOf(String(currentValue));\n const delta = key.rightArrow ? 1 : -1;\n const next = field.options[(idx + delta + field.options.length) % field.options.length]!;\n void commit(next);\n return;\n }\n if (field.kind === 'dictRef' && key.return) {\n nav.navigate({ name: 'dict', params: { pickerMode: 'set-default' } });\n return;\n }\n if ((field.kind === 'string' || field.kind === 'int') && key.return) {\n setDraft(String(currentValue ?? ''));\n setEditing(true);\n setError(null);\n }\n });\n\n const labelW = Math.max(...FIELDS.map((f) => visibleWidth(t.config.fields[f.labelKey]))) + 4;\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <Text bold color={PALETTE.accent}>\n {t.config.title}\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\" flexGrow={1}>\n {FIELDS.map((f, i) => {\n const active = i === selected;\n const value = getByPath(cfg, f.path);\n const display = renderValue(\n f,\n value,\n active && editing ? draft : null,\n t,\n f.path === 'defaultDict' ? defaultDictName : '',\n );\n const label = t.config.fields[f.labelKey];\n const pad = ' '.repeat(Math.max(0, labelW - visibleWidth(label)));\n return (\n <Box key={f.path}>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>{active ? '▌ ' : ' '}</Text>\n <Text bold={active} color={active ? PALETTE.text : PALETTE.muted}>\n {label}\n {pad}\n </Text>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>{display}</Text>\n </Box>\n );\n })}\n </Box>\n\n {error && (\n <Box marginTop={1}>\n <Text color={PALETTE.error}>! {error}</Text>\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{hintFor(field, editing, t)}</Text>\n </Box>\n </Box>\n );\n}\n\nfunction renderValue(\n field: FieldSpec,\n value: unknown,\n draft: string | null,\n t: Strings,\n dictDisplayName: string,\n): string {\n if (draft !== null) return `${draft}_`;\n if (field.kind === 'bool') return value ? `✓ ${t.common.on}` : `✗ ${t.common.off}`;\n if (field.kind === 'dictRef') {\n if (!value) return '—';\n return truncateName(dictDisplayName || String(value), 24);\n }\n if (field.kind === 'enum') {\n if (field.path === 'stealth') {\n const v = String(value) as keyof Strings['config']['enumValues']['stealth'];\n const label = t.config.enumValues.stealth[v] ?? String(value);\n return `< ${label} >`;\n }\n return `< ${value} >`;\n }\n return String(value ?? '');\n}\n\nfunction hintFor(field: FieldSpec, editing: boolean, t: Strings): string {\n if (editing) return t.config.hints.editing;\n if (field.kind === 'bool') return t.config.hints.bool;\n if (field.kind === 'enum') return t.config.hints.enum;\n if (field.kind === 'dictRef') return t.config.hints.dictRef;\n return t.config.hints.stringOrInt;\n}\n","import { useEffect, useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { useNav } from '../nav.js';\nimport { useStrings } from '../../i18n/context.js';\nimport { useDictName } from '../registry-context.js';\nimport { PALETTE } from '../components/BigWord.js';\nimport {\n loadSessions,\n computeWPM,\n accuracy,\n dailyBuckets,\n sparkline,\n dailyStreak,\n type SessionRecord,\n} from '../../domain/stats.js';\nimport { loadMistakes, topN, type MistakeBook } from '../../domain/mistakes.js';\nimport { truncateName } from '../../util/dict-name.js';\n\nconst DAY_WINDOWS = [7, 14, 30, 90];\n\nexport function StatsViewer() {\n const nav = useNav();\n const t = useStrings();\n const [sessions, setSessions] = useState<SessionRecord[] | null>(null);\n const [book, setBook] = useState<MistakeBook | null>(null);\n const [windowIdx, setWindowIdx] = useState(1);\n\n useEffect(() => {\n void (async () => {\n const [s, b] = await Promise.all([loadSessions(), loadMistakes()]);\n setSessions(s);\n setBook(b);\n })();\n }, []);\n\n useInput((_input, key) => {\n if (key.escape) {\n nav.back();\n return;\n }\n if (key.rightArrow) setWindowIdx((i) => (i + 1) % DAY_WINDOWS.length);\n if (key.leftArrow) setWindowIdx((i) => (i - 1 + DAY_WINDOWS.length) % DAY_WINDOWS.length);\n });\n\n if (!sessions || !book) {\n return (\n <Box alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.muted}>{t.stats.loading}</Text>\n </Box>\n );\n }\n\n if (sessions.length === 0) {\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.muted}>{t.stats.none}</Text>\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{t.stats.nonePractice}</Text>\n </Box>\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>Esc {t.common.back}</Text>\n </Box>\n </Box>\n );\n }\n\n const days = DAY_WINDOWS[windowIdx]!;\n const buckets = dailyBuckets(sessions, days);\n const streak = dailyStreak(sessions);\n const totalWords = sessions.reduce((a, s) => a + s.wordCount, 0);\n const totalErrors = sessions.reduce((a, s) => a + s.errors, 0);\n const totalMs = sessions.reduce((a, s) => a + s.durationMs, 0);\n const firstTryWords = sessions.reduce(\n (a, s) => a + (s.wordCount - Object.keys(s.perWordErrors).length),\n 0,\n );\n const overallWpm = totalMs > 0 ? Math.round((totalWords / (totalMs / 60000)) * 10) / 10 : 0;\n const overallAcc = totalWords === 0 ? 1 : firstTryWords / totalWords;\n\n const recent = sessions.slice(-5).reverse();\n const top = topN(book, 8);\n\n const wpms = buckets.map((b) => b.wpm);\n const accs = buckets.map((b) => b.accuracy * 100);\n const ses = buckets.map((b) => b.sessions);\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <Text bold color={PALETTE.accent}>\n {t.stats.title}\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text color={PALETTE.muted}>{t.stats.lifetime}</Text>\n <Box marginTop={1}>\n <Stat label={t.stats.sessions} value={String(sessions.length)} />\n <Stat label={t.stats.words} value={String(totalWords)} />\n <Stat label={t.stats.errors} value={String(totalErrors)} />\n <Stat label={t.stats.wpm} value={String(overallWpm)} accent />\n <Stat label={t.stats.accuracy} value={`${Math.round(overallAcc * 1000) / 10}%`} accent />\n <Stat label={t.stats.streak} value={`${streak}d`} accent />\n </Box>\n </Box>\n\n <Box marginTop={2} flexDirection=\"column\">\n <Text color={PALETTE.muted}>{t.stats.last(days)}</Text>\n <Box marginTop={1} flexDirection=\"column\" borderStyle=\"round\" borderColor={PALETTE.muted} paddingX={1}>\n <SparkRow\n label={t.stats.wpm}\n values={wpms}\n maxLabel={t.stats.maxLabel}\n />\n <SparkRow\n label={t.stats.accuracy}\n values={accs}\n maxLabel={t.stats.maxLabel}\n suffix=\"%\"\n />\n <SparkRow\n label={t.stats.sessions}\n values={ses}\n maxLabel={t.stats.maxLabel}\n />\n </Box>\n </Box>\n\n <Box marginTop={2} flexDirection=\"column\">\n <Text color={PALETTE.muted}>{t.stats.recent}</Text>\n {recent.map((s, i) => (\n <RecentRow key={i} session={s} units={t.stats.recentUnits} />\n ))}\n </Box>\n\n {top.length > 0 && (\n <Box marginTop={2} flexDirection=\"column\">\n <Text color={PALETTE.muted}>{t.stats.topMistakes}</Text>\n {top.map(([word, entry]) => (\n <MistakeRow\n key={word}\n word={word}\n count={entry.count}\n dictIds={entry.dictIds}\n multiSuffix={t.stats.multiDictSuffix}\n />\n ))}\n </Box>\n )}\n\n <Box flexGrow={1} />\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{t.stats.footer}</Text>\n </Box>\n </Box>\n );\n}\n\nfunction SparkRow({\n label,\n values,\n maxLabel,\n suffix = '',\n}: {\n label: string;\n values: number[];\n maxLabel: string;\n suffix?: string;\n}) {\n const max = values.length === 0 ? 0 : Math.max(...values);\n const maxDisplay = `${Math.round(max)}${suffix}`;\n return (\n <Box>\n <Box width={10}>\n <Text color={PALETTE.muted}>{label}</Text>\n </Box>\n <Box flexGrow={1}>\n <Text color={PALETTE.accent}>{sparkline(values)}</Text>\n </Box>\n <Box marginLeft={2}>\n <Text color={PALETTE.muted}>\n {maxLabel} {maxDisplay}\n </Text>\n </Box>\n </Box>\n );\n}\n\nfunction RecentRow({\n session,\n units,\n}: {\n session: SessionRecord;\n units: { words: string; errors: string; wpm: string };\n}) {\n const name = useDictName(session.dictId);\n const display = truncateName(name, 14);\n return (\n <Box>\n <Text color={PALETTE.muted}> {session.ts.replace('T', ' ').slice(0, 16)} </Text>\n <Text color={PALETTE.text}>{display.padEnd(14)}</Text>\n <Text color={PALETTE.muted}>\n {' '}ch{String(session.chapter + 1).padStart(3)} {session.mode.padEnd(9)} {String(session.wordCount).padStart(3)}{units.words} {session.errors}{units.errors} {computeWPM(session)}{units.wpm} {Math.round(accuracy(session) * 1000) / 10}%\n </Text>\n </Box>\n );\n}\n\nfunction MistakeRow({\n word,\n count,\n dictIds,\n multiSuffix,\n}: {\n word: string;\n count: number;\n dictIds: string[];\n multiSuffix: (n: number) => string;\n}) {\n const firstId = dictIds[0] ?? '';\n const firstName = useDictName(firstId);\n const suffix = dictIds.length > 1 ? multiSuffix(dictIds.length - 1) : '';\n return (\n <Box>\n <Text color={PALETTE.error}> {String(count).padStart(3)} </Text>\n <Text color={PALETTE.text}>{word.padEnd(20)}</Text>\n <Text color={PALETTE.muted}>\n {truncateName(firstName, 20)}\n {suffix}\n </Text>\n </Box>\n );\n}\n\nfunction Stat({ label, value, accent = false }: { label: string; value: string; accent?: boolean }) {\n return (\n <Box marginRight={3}>\n <Text color={PALETTE.muted}>{label} </Text>\n <Text bold color={accent ? PALETTE.accent : PALETTE.text}>\n {value}\n </Text>\n </Box>\n );\n}\n","import { useEffect, useState } from 'react';\nimport { Box, Text, useInput } from 'ink';\nimport { useNav } from '../nav.js';\nimport { useStrings } from '../../i18n/context.js';\nimport { useDictName } from '../registry-context.js';\nimport { PALETTE } from '../components/BigWord.js';\nimport { readdir } from 'node:fs/promises';\nimport { paths } from '../../infra/paths.js';\nimport { loadLocalDictionary } from '../../infra/dict-downloader.js';\nimport { loadMistakes, type MistakeBook } from '../../domain/mistakes.js';\nimport type { Word } from '../../domain/dictionary.js';\nimport { truncateName } from '../../util/dict-name.js';\n\ntype Hit = { dictId: string; word: Word };\n\nasync function listLocalDictIds(): Promise<string[]> {\n try {\n const files = await readdir(paths.dictsDir);\n return files\n .filter((f) => f.endsWith('.json') && !f.endsWith('.meta.json'))\n .map((f) => f.replace(/\\.json$/, ''));\n } catch {\n return [];\n }\n}\n\nexport function WordLookup() {\n const nav = useNav();\n const t = useStrings();\n const [query, setQuery] = useState('');\n const [allWords, setAllWords] = useState<Hit[]>([]);\n const [book, setBook] = useState<MistakeBook>({});\n const [loading, setLoading] = useState(true);\n const [selected, setSelected] = useState(0);\n\n useEffect(() => {\n void (async () => {\n const ids = await listLocalDictIds();\n const collected: Hit[] = [];\n for (const id of ids) {\n const words = await loadLocalDictionary(id);\n if (!words) continue;\n for (const w of words) collected.push({ dictId: id, word: w });\n }\n setAllWords(collected);\n setBook(await loadMistakes());\n setLoading(false);\n })();\n }, []);\n\n const q = query.toLowerCase().trim();\n const filtered = q\n ? allWords.filter((h) => h.word.name.toLowerCase().includes(q)).slice(0, 50)\n : [];\n\n useInput((input, key) => {\n if (key.escape) {\n nav.back();\n return;\n }\n if (key.upArrow) {\n setSelected((i) => Math.max(0, i - 1));\n return;\n }\n if (key.downArrow) {\n setSelected((i) => Math.min(filtered.length - 1, i + 1));\n return;\n }\n if (key.backspace || key.delete) {\n setQuery((s) => s.slice(0, -1));\n setSelected(0);\n return;\n }\n if (input && !key.ctrl && !key.meta && input.trim().length > 0) {\n setQuery((s) => s + input);\n setSelected(0);\n }\n });\n\n if (loading) {\n return (\n <Box alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.muted}>{t.word.indexing}</Text>\n </Box>\n );\n }\n\n if (allWords.length === 0) {\n return (\n <Box flexDirection=\"column\" alignItems=\"center\" justifyContent=\"center\" width=\"100%\" height=\"100%\">\n <Text color={PALETTE.muted}>{t.word.none}</Text>\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{t.word.pullFirst}</Text>\n </Box>\n <Box marginTop={2}>\n <Text color={PALETTE.muted}>[Esc] {t.common.back}</Text>\n </Box>\n </Box>\n );\n }\n\n const current = filtered[selected];\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <Box>\n <Text bold color={PALETTE.accent}>{t.word.title}</Text>\n <Box flexGrow={1} />\n <Text color={PALETTE.muted}>{t.word.countAcross(allWords.length)}</Text>\n </Box>\n\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{'> '}</Text>\n <Text color={PALETTE.text}>{query}</Text>\n <Text color={PALETTE.accent}>_</Text>\n </Box>\n\n <Box marginTop={1} flexGrow={1}>\n <Box flexDirection=\"column\" width=\"40%\">\n {filtered.map((h, i) => (\n <HitRow key={`${h.dictId}-${h.word.name}-${i}`} hit={h} active={i === selected} />\n ))}\n {filtered.length === 0 && q && (\n <Text color={PALETTE.muted}>{t.word.noMatches(query)}</Text>\n )}\n </Box>\n\n <Box flexDirection=\"column\" width=\"60%\" paddingLeft={2}>\n {current && <Detail hit={current} book={book} />}\n </Box>\n </Box>\n\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{t.word.footer}</Text>\n </Box>\n </Box>\n );\n}\n\nfunction HitRow({ hit, active }: { hit: Hit; active: boolean }) {\n const name = useDictName(hit.dictId);\n return (\n <Box>\n <Text color={active ? PALETTE.accent : PALETTE.muted}>{active ? '▌ ' : ' '}</Text>\n <Text bold={active} color={active ? PALETTE.text : PALETTE.muted}>\n {hit.word.name.padEnd(20)}\n </Text>\n <Text color={PALETTE.muted}>{truncateName(name, 18)}</Text>\n </Box>\n );\n}\n\nfunction Detail({ hit, book }: { hit: Hit; book: MistakeBook }) {\n const t = useStrings();\n const name = useDictName(hit.dictId);\n return (\n <>\n <Text bold color={PALETTE.text}>{hit.word.name}</Text>\n <Box marginTop={1}>\n {hit.word.usphone && (\n <Text color={PALETTE.muted}>US /{hit.word.usphone}/ </Text>\n )}\n {hit.word.ukphone && (\n <Text color={PALETTE.muted}>UK /{hit.word.ukphone}/</Text>\n )}\n </Box>\n <Box marginTop={1} flexDirection=\"column\">\n {(hit.word.trans ?? []).map((tr, i) => (\n <Text key={i} color={PALETTE.primary}>· {tr}</Text>\n ))}\n </Box>\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{t.word.inDict(truncateName(name, 22))}</Text>\n </Box>\n {book[hit.word.name] && (\n <Box marginTop={1}>\n <Text color={PALETTE.error}>\n {t.word.mistakes(book[hit.word.name]!.count, book[hit.word.name]!.lastSeen.slice(0, 10))}\n </Text>\n </Box>\n )}\n </>\n );\n}\n","import { Box, Text, useInput } from 'ink';\nimport { useNav } from '../nav.js';\nimport { useStrings } from '../../i18n/context.js';\nimport { PALETTE } from '../components/BigWord.js';\n\nexport function HelpScreen() {\n const nav = useNav();\n const t = useStrings();\n\n useInput((_input, key) => {\n if (key.escape) nav.back();\n });\n\n const k = t.help.keys;\n const sections: Array<{ title: string; keys: string[] }> = [\n { title: t.help.sections.global, keys: [k.helpScreen, k.quit] },\n { title: t.help.sections.main, keys: [k.navigate, k.select, k.letterJump, k.helpScreen] },\n {\n title: t.help.sections.practice,\n keys: [k.pause, k.skip, k.replay, k.resume, k.nextChapter, k.reviewMistakes, k.stealthToggle, k.backMenu],\n },\n {\n title: t.help.sections.dict,\n keys: [k.navigate, k.filter, k.itemActions, k.moreActions, k.backScreen],\n },\n { title: t.help.sections.config, keys: [k.navigate, k.select, k.backMenu] },\n { title: t.help.sections.stats, keys: [k.cycleWindow, k.backMenu] },\n { title: t.help.sections.word, keys: [k.filter, k.navigate, k.backMenu] },\n ];\n\n return (\n <Box flexDirection=\"column\" paddingX={2} paddingY={1} width=\"100%\" height=\"100%\">\n <Box>\n <Text bold color={PALETTE.accent}>\n {t.help.title}\n </Text>\n <Text color={PALETTE.muted}>{' · '}</Text>\n <Text color={PALETTE.muted}>{t.help.subtitle}</Text>\n </Box>\n\n <Box marginTop={1} flexDirection=\"column\" flexGrow={1}>\n {sections.map((sec) => (\n <Box key={sec.title} flexDirection=\"column\" marginTop={1}>\n <Text bold color={PALETTE.text}>\n {sec.title}\n </Text>\n {sec.keys.map((line, i) => (\n <Box key={i}>\n <Text color={PALETTE.muted}> · {line}</Text>\n </Box>\n ))}\n </Box>\n ))}\n </Box>\n\n <Box marginTop={1}>\n <Text color={PALETTE.muted}>{t.help.footer}</Text>\n </Box>\n </Box>\n );\n}\n","import chalk from 'chalk';\nimport type { SessionReport } from '../infra/session-tracker.js';\nimport type { Strings } from '../i18n/strings.js';\nimport { visibleWidth } from './text.js';\n\nconst LEAVE_ALTSCREEN = '\\x1b[?25h\\x1b[?1049l';\n\nexport function ensureMainScreen(): void {\n if (process.stdout.isTTY) process.stdout.write(LEAVE_ALTSCREEN);\n}\n\nfunction fmtDuration(ms: number, lang: 'zh' | 'en'): string {\n const total = Math.floor(ms / 1000);\n const m = Math.floor(total / 60);\n const s = total % 60;\n if (lang === 'zh') {\n if (m === 0) return `${s} 秒`;\n return `${m} 分 ${s} 秒`;\n }\n if (m === 0) return `${s}s`;\n return `${m}m ${s}s`;\n}\n\nexport function printSessionReport(r: SessionReport, t: Strings, lang: 'zh' | 'en'): void {\n if (r.startedAt === null && r.chaptersCompleted === 0) return;\n\n if (r.chaptersCompleted === 0) {\n console.log();\n console.log(chalk.bold.cyan(t.report.title));\n const labelW = Math.max(visibleWidth(t.report.duration), visibleWidth(t.report.notPracticed)) + 2;\n const pad = (label: string) => label + ' '.repeat(Math.max(0, labelW - visibleWidth(label)));\n console.log(` ${chalk.dim(pad(t.report.duration))} ${fmtDuration(r.totalDurationMs, lang)}`);\n console.log(` ${chalk.dim(t.report.notPracticed)}`);\n console.log();\n console.log(chalk.dim(` ${t.report.farewell}`));\n console.log();\n return;\n }\n\n const accPct = Math.round(r.accuracy * 1000) / 10;\n const labels = [\n t.report.duration,\n t.report.practiced,\n t.report.chapters,\n t.report.words,\n t.report.accuracy,\n t.report.wpm,\n ];\n if (r.newMistakeWords > 0) labels.push(t.report.newMistakes);\n const labelW = Math.max(...labels.map(visibleWidth)) + 2;\n const pad = (label: string) =>\n label + ' '.repeat(Math.max(0, labelW - visibleWidth(label)));\n\n console.log();\n console.log(chalk.bold.cyan(t.report.title));\n console.log(` ${chalk.dim(pad(t.report.duration))} ${fmtDuration(r.totalDurationMs, lang)}`);\n console.log(` ${chalk.dim(pad(t.report.practiced))} ${fmtDuration(r.practiceMs, lang)}`);\n console.log(` ${chalk.dim(pad(t.report.chapters))} ${r.chaptersCompleted}`);\n console.log(` ${chalk.dim(pad(t.report.words))} ${r.wordCount}`);\n console.log(` ${chalk.dim(pad(t.report.accuracy))} ${accPct}%`);\n console.log(` ${chalk.dim(pad(t.report.wpm))} ${r.wpm}`);\n if (r.newMistakeWords > 0) {\n console.log(` ${chalk.dim(pad(t.report.newMistakes))} ${r.newMistakeWords}`);\n }\n console.log();\n console.log(chalk.dim(` ${t.report.farewell}`));\n console.log();\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { loadSessions, computeWPM, accuracy, dailyBuckets, sparkline, dailyStreak } from '../domain/stats.js';\nimport { loadMistakes, topN } from '../domain/mistakes.js';\n\nexport function buildStatsCommand(): Command {\n return new Command('stats')\n .description('Show practice history and trends')\n .option('-d, --days <n>', 'window size for trend (default 14)', '14')\n .option('--top <n>', 'how many top mistakes to show (default 10)', '10')\n .action(async (opts: { days: string; top: string }) => {\n const days = Math.max(1, Number(opts.days) || 14);\n const topCount = Math.max(1, Number(opts.top) || 10);\n const sessions = await loadSessions();\n const book = await loadMistakes();\n\n if (sessions.length === 0) {\n console.log(chalk.yellow('No practice history yet. Run `qwerty practice <dict>` to get started.'));\n return;\n }\n\n const buckets = dailyBuckets(sessions, days);\n const streak = dailyStreak(sessions);\n const totalWords = sessions.reduce((a, s) => a + s.wordCount, 0);\n const totalErrors = sessions.reduce((a, s) => a + s.errors, 0);\n const totalMs = sessions.reduce((a, s) => a + s.durationMs, 0);\n const firstTryWords = sessions.reduce(\n (a, s) => a + (s.wordCount - Object.keys(s.perWordErrors).length),\n 0,\n );\n const overallWpm = totalMs > 0 ? Math.round((totalWords / (totalMs / 60000)) * 10) / 10 : 0;\n const overallAcc = totalWords === 0 ? 1 : firstTryWords / totalWords;\n\n console.log(chalk.bold('\\nLifetime'));\n console.log(` ${chalk.dim('sessions')} ${sessions.length} ${chalk.dim('words')} ${totalWords} ${chalk.dim('errors')} ${totalErrors}`);\n console.log(` ${chalk.dim('avg wpm')} ${overallWpm} ${chalk.dim('avg accuracy')} ${Math.round(overallAcc * 1000) / 10}% ${chalk.dim('streak')} ${chalk.bold(streak)}d`);\n\n console.log(chalk.bold(`\\nLast ${days} days`));\n console.log(` ${chalk.dim('wpm ')} ${sparkline(buckets.map((b) => b.wpm))} ${chalk.dim('max')} ${Math.round(Math.max(...buckets.map((b) => b.wpm)))}`);\n console.log(` ${chalk.dim('accuracy')} ${sparkline(buckets.map((b) => b.accuracy * 100))} ${chalk.dim('range')} ${Math.round(Math.min(...buckets.map((b) => b.accuracy * 100)))}-${Math.round(Math.max(...buckets.map((b) => b.accuracy * 100)))}%`);\n console.log(` ${chalk.dim('sessions')} ${sparkline(buckets.map((b) => b.sessions))}`);\n\n const recent = sessions.slice(-5).reverse();\n console.log(chalk.bold('\\nLast 5 sessions'));\n for (const s of recent) {\n const wpm = computeWPM(s);\n const acc = Math.round(accuracy(s) * 1000) / 10;\n console.log(\n ` ${chalk.dim(s.ts.replace('T', ' ').slice(0, 16))} ${chalk.cyan(s.dictId.padEnd(14))} ch${String(s.chapter + 1).padStart(3)} ${s.mode.padEnd(9)} ${String(s.wordCount).padStart(3)}w ${s.errors}err ${wpm}wpm ${acc}%`,\n );\n }\n\n const top = topN(book, topCount);\n if (top.length > 0) {\n console.log(chalk.bold(`\\nTop ${top.length} mistakes`));\n for (const [word, entry] of top) {\n console.log(` ${chalk.red(String(entry.count).padStart(3))} ${chalk.bold(word.padEnd(20))} ${chalk.dim(entry.dictIds.join(', '))}`);\n }\n } else {\n console.log(chalk.bold('\\nTop mistakes'));\n console.log(chalk.dim(' none — keep going'));\n }\n console.log();\n });\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { readdir } from 'node:fs/promises';\nimport { paths } from '../infra/paths.js';\nimport { loadLocalDictionary } from '../infra/dict-downloader.js';\nimport { loadMistakes } from '../domain/mistakes.js';\nimport { findEntry } from '../infra/registry-store.js';\nimport type { Word } from '../domain/dictionary.js';\n\nasync function listLocalDictIds(): Promise<string[]> {\n try {\n const files = await readdir(paths.dictsDir);\n return files\n .filter((f) => f.endsWith('.json') && !f.endsWith('.meta.json'))\n .map((f) => f.replace(/\\.json$/, ''));\n } catch {\n return [];\n }\n}\n\nexport function buildWordCommand(): Command {\n return new Command('word')\n .argument('<keyword>')\n .description('Look up a word across local dictionaries')\n .option('--exact', 'require exact (case-insensitive) match')\n .action(async (keyword: string, opts: { exact?: boolean }) => {\n const q = keyword.toLowerCase();\n const ids = await listLocalDictIds();\n if (ids.length === 0) {\n console.log(chalk.yellow('No local dictionaries. Run `qwerty dict pull <id>` first.'));\n return;\n }\n\n type Hit = { dictId: string; word: Word };\n const hits: Hit[] = [];\n for (const id of ids) {\n const words = await loadLocalDictionary(id);\n if (!words) continue;\n for (const w of words) {\n const wl = w.name.toLowerCase();\n const match = opts.exact ? wl === q : wl.includes(q);\n if (match) hits.push({ dictId: id, word: w });\n }\n }\n\n if (hits.length === 0) {\n console.log(chalk.yellow(`No matches for \"${keyword}\" in ${ids.length} local dictionaries`));\n return;\n }\n\n // Group hits by word name; one block per distinct word.\n const byName = new Map<string, Hit[]>();\n for (const h of hits) {\n const arr = byName.get(h.word.name) ?? [];\n arr.push(h);\n byName.set(h.word.name, arr);\n }\n\n const book = await loadMistakes();\n for (const [name, group] of byName) {\n const first = group[0]!.word;\n console.log();\n console.log(chalk.bold.white(name));\n const us = first.usphone ? `US /${first.usphone}/` : '';\n const uk = first.ukphone ? `UK /${first.ukphone}/` : '';\n if (us || uk) console.log(chalk.dim(` ${[us, uk].filter(Boolean).join(' ')}`));\n for (const t of first.trans ?? []) console.log(chalk.cyan(` · ${t}`));\n const sources = await Promise.all(\n group.map(async (h) => {\n const reg = await findEntry(h.dictId);\n return reg?.name ?? h.dictId;\n }),\n );\n console.log(chalk.dim(` in: ${sources.join(', ')}`));\n const mistake = book[name];\n if (mistake) {\n console.log(chalk.dim(` mistakes: ${mistake.count} (last ${mistake.lastSeen.slice(0, 10)})`));\n }\n }\n console.log();\n });\n}\n","import { Command } from 'commander';\nimport { runPractice } from './practice.js';\n\nexport function buildStealthCommand(): Command {\n return new Command('boss')\n .alias('stealth')\n .description('Start practice in stealth mode (minimal UI, looks like plain terminal output)')\n .argument('[dictId]', 'dictionary id; falls back to config.defaultDict')\n .option('-c, --chapter <n>', 'chapter number (1-based)', '1')\n .option('-m, --mode <mode>', 'order | dictation | review | random | loop')\n .action(\n async (\n dictIdArg: string | undefined,\n options: { chapter: string; mode?: string },\n ) => {\n await runPractice(dictIdArg, { ...options, stealth: true });\n },\n );\n}\n","import { render } from 'ink';\nimport { createElement } from 'react';\nimport { loadConfig } from '../infra/config-store.js';\nimport { App } from '../ui/App.js';\nimport { start as startSession, report as sessionReport } from '../infra/session-tracker.js';\nimport { printSessionReport, ensureMainScreen } from '../util/report.js';\nimport { pickStrings } from '../i18n/context.js';\n\nexport async function runMainMenu(): Promise<void> {\n if (!process.stdout.isTTY) {\n console.log('qwerty-cli — run `qwerty --help` for available commands.');\n return;\n }\n const cfg = await loadConfig();\n startSession();\n const { waitUntilExit } = render(\n createElement(App, { initial: { name: 'main' }, initialCfg: cfg }),\n { patchConsole: false, exitOnCtrlC: false },\n );\n await waitUntilExit();\n ensureMainScreen();\n const { lang, t } = pickStrings(cfg.language);\n printSessionReport(sessionReport(), t, lang);\n}\n"],"mappings":"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","names":["Command","mkdir","Command","chalk","z","readFile","join","parsed","readFile","join","chalk","Command","Command","chalk","useRef","useApp","useInput","useState","jsx","createContext","useContext","useEffect","useState","mkdir","rename","writeFile","join","dirname","request","resolve","join","mkdir","dirname","request","writeFile","rename","jsx","createContext","useState","useEffect","useContext","createContext","useCallback","useContext","useState","jsx","createContext","useState","useCallback","useContext","createContext","useContext","jsx","createContext","useContext","createContext","useContext","useEffect","useState","jsx","createContext","useState","useEffect","useContext","useState","Box","Text","Box","useStdout","jsx","visibleWidth","visibleWidth","jsx","jsxs","useState","visibleWidth","Box","Text","useState","useEffect","useRef","Box","Text","useApp","useInput","state","state","z","z","useEffect","useState","useInput","useApp","state","useState","useApp","useInput","useEffect","useEffect","useRef","useRef","useEffect","useCallback","z","z","accuracy","useCallback","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","useState","useEffect","useApp","useRef","useInput","currentWord","inputState","fmtTime","Box","Text","useEffect","useMemo","useState","Box","Text","useInput","useStdout","useState","Box","Text","useInput","jsx","jsxs","useState","useInput","Box","Text","jsx","jsxs","useStdout","useState","useEffect","useMemo","start","useInput","Box","Text","useState","Box","Text","useInput","jsx","jsxs","getByPath","useState","useInput","visibleWidth","Box","Text","useEffect","useState","Box","Text","useInput","jsx","jsxs","useState","useEffect","useInput","Box","Text","useEffect","useState","Box","Text","useInput","Fragment","jsx","jsxs","useState","useEffect","useInput","Box","Text","Box","Text","useInput","jsx","jsxs","useInput","Box","Text","jsx","useApp","useRef","useInput","key","chalk","chalk","labelW","visibleWidth","pad","chalk","Command","Command","chalk","Command","chalk","Command","chalk","readdir","listLocalDictIds","readdir","Command","chalk","Command","Command","render","createElement","render","createElement","Command"]}