ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗A Next.js 16 (App Router) + TypeScript + Tailwind port of the original single-file
index.html lab-record builder. Behavior, layout, and UX are preserved 1:1; the
codebase has been split into typed components and modules.
npm install
npm run dev # http://localhost:3000
npm run build # production build
npm run start # serve the production build
See docs/deploy.md for the environment variables, Firebase and Google setup, and a post-deploy checklist. The admin area is described in docs/admin.md and mail in docs/admin-mail.md.
app/page.tsx — top-level client component holding all app state (record,
watermark options, mobile panel, AI modal) and wiring the editor, preview,
print, and PDF-save flows together.app/layout.tsx — loads Material Symbols and html2pdf.js (via
next/script, strategy="lazyOnload" — it touches document/canvas and
isn't SSR-safe).components/ — RecordEditorPanel, WatermarkOptionsSection,
AccordionSection, PreviewPanel, A4Page, MobileNav, and
AiAssistantModal (with ai/CopyPromptTab, ai/PasteImportTab,
ai/DirectLlmTab).lib/paginate.ts — the smart pagination engine, ported line-for-line from
the original. It still measures real rendered heights in a hidden offscreen
DOM node (lib/usePaginatedPages.ts wraps it in a debounced
useEffect/useState hook) because text wrapping depends on actual font
rendering and can't be predicted analytically — this keeps it accurate but
means it isn't a pure function in the strict sense; it's as close to
testable/pure as the original algorithm allows.lib/buildPrintHtml.ts / lib/printCss.ts — build the exact print-document
HTML string reused by both the hidden print <iframe> and html2pdf.js.lib/aiAssistant.ts — the AI prompt template, DOMParser-based section
parser with regex extractTag fallback, and validator.lib/puter.ts — client-side AI text generation via Puter.js
(window.puter.ai.chat), no API key required.lib/types.ts — RecordState, OutputImage, WatermarkOptions,
PageObject.The app chrome (editor, preview toolbar, modal, nav) uses a "lab notebook"
visual identity — a warm paper background, a serif/mono title-block treatment
(Source Serif 4 + Inter + JetBrains Mono, loaded via next/font/google),
a copper accent color, and numbered section eyebrows (01 AIM, 02 ALGORITHM, …)
that mirror the record's actual printed order. Icons are from lucide-react.
This only touches the app UI. The generated record itself (.a4-page and
everything inside it, in A4Page.tsx / globals.css / printCss.ts /
buildPrintHtml.ts) intentionally keeps its own hard-coded Arial stack so
preview, print, and PDF stay pixel-identical — never point the chrome's
--font-* variables at those selectors.
lib/paginate.ts output, rendered via
dangerouslySetInnerHTML in A4Page): the pagination engine has to work in
raw HTML strings because it measures and splits content by rendered pixel
height across page boundaries, and re-deriving that from JSX per fragment
isn't safely feasible without changing the algorithm. All user text within
those fragments is still run through escapeHTML before being placed in the
HTML string, matching the original's XSS-safety guarantee.usePaginatedPages so rapid typing doesn't trigger a synchronous
DOM-measurement pass on every keystroke. This is a minor smoothness
improvement over the original (which re-paginated on every input event
synchronously); it does not change output.useState), matching the
original — nothing is written to localStorage/sessionStorage.puter.ai.chat (loaded via the https://js.puter.com/v2/ script tag in
app/layout.tsx) instead of a keyed provider API. lib/puter.ts tries
gpt-4o first and falls back once to claude-3-5-sonnet if the first
model call fails. Errors surface as a toast ("Generation failed, please try
again") rather than an inline API error message.lib/rateLimiter.ts is a small in-memory
sliding-window limiter (5 requests / 60s) used by DirectLlmTab to block
rapid repeat clicks and show a countdown before the next request is
allowed. It's a UX guard, not a security control..a4-page node and measures scrollHeight), so it only produces
accurate output in a browser environment, not during SSR — this matches the
original's DOM-measurement approach.