ESP32-S3 Bench Guide
ESP32‑S3 N16R8 벤치 가이드: 실시간 핀아웃, 강의, 시뮬레이터 및 벤치 로그
10,000개 이상의 독일어 단어를 소리·뜻·예문과 함께 제공하고, 복습 일정과 영→독 발음 연습 기능을 갖춘 무료 오픈소스 도구
10,000+ German words with sound, meaning and examples, a scheduler that says why each word is back, and a walk mode: hear the English, say the German aloud. Free and open source. No account — your pro
교육TypeScript · CSSGitHub @shamilhzm온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기10,000+ German words with sound, meaning and examples, a scheduler that says why each word is back, and a walk mode: hear the English, say the German aloud. Free and open source. No account — your progress stays on your device.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Scroll German. Save a word. Lexi makes it stick.
A free, open-source German vocabulary app for English speakers: 10,000+ words from
A1 to C2 to learn, and a dictionary of 93,000+ headwords to look things up in. No account,
no ads, nothing to cancel — and your progress stays on your device.
Open Lexi → — it runs in the browser; add it to your
home screen and it works offline.README 전문 보기 ↗Scroll German. Save a word. Lexi makes it stick.
A free, open-source German vocabulary app for English speakers: 10,000+ words from A1 to C2 to learn, and a dictionary of 93,000+ headwords to look things up in. No account, no ads, nothing to cancel — and your progress stays on your device.
Open Lexi → — it runs in the browser; add it to your home screen and it works offline.
English speakers living with German — past the course, somewhere between A2 and B2, who want to read the news and the letter from the Ausländerbehörde without a dictionary open. It works from A1, but Lexi teaches words, not grammar: if you are starting from zero, use it beside a course, not instead of one.
ATTRIBUTIONS.md.Lexi is small on purpose. What the others do better is real, and worth saying:
| If you use… | it is better at… | Lexi is different because… |
|---|---|---|
| Duolingo | a whole course — grammar, listening, speaking — as a daily game | it is only vocabulary, for adults, with no game to win or lose, and it goes deep at B1–C1 |
| Anki with a shared deck | anything, in any language, exactly your way | there is no deck to build or debug, and every gender and plural is checked |
| LingQ, Readlang | reading any text you bring | a word counts as known when the scheduler's evidence says you would recall it, not when you mark it — and it is free |
What Lexi deliberately does not do — teach grammar, mark your speech, run leagues, or say "you can now…" from a word count. Ruled 2026-09-05: a drill earns its place if it tests a property of the word (gender, plural, spelling, the German you have to produce) and goes if it tests a rule of the language. Every gloss is in English; other language pairs are an architectural goal, not a shipped feature.
docs/VISION.mdcarries the whole argument, including what it would take to reverse each refusal.
docs/VISION.md is the anchor — what this is, what it refuses, and
what is still undecided. docs/BACKLOG.md is what's next;
docs/CHANGELOG.md is what shipped and why. Full index at
docs/README.md.
Measured against the shipped corpus on 2026-09-26. The two headline counts are
guarded by src/lib/publicCopy.test.ts, which fails when the corpus outgrows them.
ts-fsrs. Every drill mode is its own track, so recognising
a word and producing it are scheduled separately — that split is what makes the
recall drill honest.Four destinations, and the first one is where the app opens.
browse freely → save what catches you → Üben teaches you what you chose.
Bookmarking is the one thing a feed can honestly record, and it is an instruction to the
scheduler rather than a wishlist: buildBriefing serves saved words ahead of the ones it
would have picked itself.
Walk — On a walk on the saved-words sheet, or ?walk — is the day's queue as audio for
a walk or a run: the English, a cue tone, a pause to say the German aloud, then the
German. Only a deliberate headphone press grades — next track knew it, previous track
didn't — and a word met for the first time is taught before it is tested. See
src/lib/walk.ts.
Each is generated from the lexicon and scheduled on its own FSRS track under
gym:<mode>:<wordId>.
| Asks | Why it is vocabulary and not grammar | |
|---|---|---|
| der / die / das | the article of a noun | a German noun without its gender is a half-learned word |
| Plurals | die Tische, not die Tischen | same |
| Recall | English in, German out — typed, with the article | the productive half of knowing a word, which recognition never proves |
Recall is gated: a word becomes eligible only once its flip card has reached FSRS
Review, because asking someone to produce a word they have only just met is a
retrieval attempt on something not yet encoded.
Vite 6 · React 19 · TypeScript · Tailwind CSS v4 · motion · lucide-react · ts-fsrs.
npm install
npm run dev
Then open http://localhost:5173/lexi/ — the base path is /lexi/ locally and / on
Vercel.
npm run build # production bundle to dist/
npm run typecheck # tsc --noEmit
npm test # vitest — the pure logic, the shipped corpus, and the public copy
npm run lint # eslint, including jsx-a11y
Before pushing anything that touches the corpus:
npm run corpus:validate && npm run corpus:selftest
src/ the app — views/, components/ (+ ui/ primitives), lib/, data/
public/data/ the shipped corpus: cards.json, detail.json, sectors.json, freq.json,
provenance.json, audio.json (vocab.json is canonical, not deployed)
scripts/corpus/ build-time ingestion, audits and one-shot corpus fixes (npm run corpus:*)
scripts/authoring/ the verified card-authoring loop: batch in, machine-gated, audit trail
docs/ VISION (the anchor) · BACKLOG (open) · CHANGELOG (shipped, with reasoning)
design/ logo sources
Nothing under scripts/ ships to the browser: it runs on a maintainer's machine and
writes public/data/*.json, which the app fetches at runtime. Corpus JSON is never
hand-edited — every change goes through a script so it is reviewable and repeatable.
public/data/ is served as static files and fetched at runtime (see
src/data/index.ts → initData) so the corpus isn't parsed inside the JS bundle — the
app shell paints immediately and the service worker caches the data for offline reloads.
To extend coverage, use the reproducible pipeline in
scripts/corpus/: npm run corpus:coverage to see the gap,
corpus:build to grow it from open sources.
vocab.json still carries 110 kind: 'grammar' cards. They are filtered out at load in
src/data/index.ts rather than cut from the corpus, because the corpus is canonical and
reversing the decision should be one line.
Lexi ships a web app manifest and a service worker, so it installs on phone and desktop,
runs full-screen and works offline after the first load. navigator.storage.persist()
runs at boot — without it Safari evicts IndexedDB after about a week of not opening the
app, which for a local-first tool is total data loss.
The code is MIT — see LICENSE.
The corpus (public/data/*.json) is built from Wiktionary/Wiktextract, Tatoeba and
the Leipzig Corpora Collection, and carries CC BY-SA 4.0 with attribution — see
LICENSE-DATA.md. Every source, its licence, and exactly what is
redistributed is recorded in ATTRIBUTIONS.md — if you fork this,
that file travels with it. What the app sends where, the credits and the legal notice
are on one page: public/legal.html.
See CONTRIBUTING.md. The short version: the corpus is never
hand-edited, tests and corpus:validate gate every merge, and
docs/VISION.md lists what the project deliberately refuses to build.
Coverage colour uses FSRS state: a card counts as learned once it leaves New and
consolidated once it reaches Review. New-card introductions are capped per day, at a
pace you can change. Respects prefers-reduced-motion, honours iOS Dynamic Type, and
pairs every colour signal with a shape or a label so nothing rides on hue alone.