Skip to content

ChristineTham/hellocalc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

117 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hello Calc

An advanced calculator, reimagined as a modern web app — and a homage to the great Hewlett-Packard calculators.

Hellocalc faithfully emulates the keyboard layouts of classic HP models (colors, key placement, prefix behavior) while also working as a genuinely modern app: use a physical keyboard, a mouse, and a large screen instead of hunting and pecking at virtual keys. Every model runs on one shared, advanced calculator engine, and a native mode exposes the full engine through a typed expression evaluator with history, variables, and an expression library.

Docs: Product Requirements (PRD) · Engine Architecture · Responsive layout & machine UI · Implementation plan · Build rules for agents · HP calculator reference


What it does

  • Faithful HP keyboard emulation — swap between models; each faceplate looks and behaves like the original (modern web design, not skeuomorphic). Switching models retains compatible state (stack, memory).
  • One unified engine shared across all models — each model just exposes its own subset of keys and functions.
  • Native mode — no virtual keypad; type algebraic (or RPN) expressions directly, with a history stack, variables, and a saved expression library.
  • Modern, responsive UI — nameplate, LCD and keyboard render as one integrated machine whose keyboard keeps the real model's proportions on every screen; computation history prints to a paper-style tape, the stack and variables read as notebook notes, and equations render in KaTeX — optimized for mobile, tablet, and desktop.
  • Advanced math:
    • Arbitrary-precision (BigNumber / fixed-point) arithmetic, floating point in selectable precisions, and high-precision currency
    • Symbolic computation / Computer Algebra System (differentiation, integration, factoring, equation solving) — potentially Mathematica-compatible
    • Units & dimensional analysis (e.g. 5 cm + 2 inches)
    • Matrices & linear algebra (determinant, inverse, eigen/SVD/QR/LU)
    • Numerical equation solver and integration (HP SOLVE / )
    • Financial math — Time Value of Money, NPV/IRR, bond pricing, Black-Scholes
    • Geometry
    • Statistics & probability
    • 2D / 3D / statistical plotting
    • HP-48-style programmability
  • Interchange & rendering — textbook-quality KaTeX rendering; copy and paste equations in multiple formats; export equations as KaTeX/LaTeX; editor-based block (notebook) evaluations.
  • Persistent state — memory/registers, variables, saved programs, and history retained across sessions and (where compatible) across model switches; named workspaces (save/list/load/delete) live in Settings.
  • Now live — an RPN⇄algebraic toggle on the modern models (HP-35s/Prime/HP-12C), IEEE-754 float evaluation via the RPL EVALF command, complex matrices (CMUL/ CDET/CINV), Black-Scholes option pricing (BS), an n×n systems solver (MSLV), user-defined units (DEFUNIT), Wolfram/Mathematica interchange (→WL/WL→), and an installable, offline-capable PWA (service worker; heavy Pyodide CAS still needs the network).

See the PRD for the full, prioritized requirement set.

Status

ALL 23 PLAN PHASES ARE COMPLETE: every one of the 35 models is fully wired — zero inert keys, each guarded by a per-model coverage oracle — plus the keyboard-first NATIVE MODE at https://christinetham.github.io/hellocalc/. Every keyboard is authored or generated from the verified hp/ reference data and computes on the math.js/BigNumber value tower (0.1 + 0.2 is exactly 0.3). The engine spans the fixed 4-level RPN stack (HP-35 → HP-16C, with keystroke programs, decimal.js finance, complex, matrices, SOLVE/∫, the 16C integer universe) and the dynamic RPL object stack (28C → 50g: objects, directories, units, softkey menus, 2D/wireframe plotting, a light Nerdamer CAS and a lazy Pyodide+SymPy heavy tier), the 42S/35s/Prime menu-driven planes, and a native notebook/library surface. Sessions autosave to localStorage and export as versioned JSON. The design and full rationale live in docs/responsive-layout.md; the highlights:

  • The integrated machine — nameplate, LCD and keyboard are ONE bezel that reflows across five page templates (phone → desktop): classic portrait models stack LCD-over-keys for the classic calculator look; tall models like the HP-48G go LCD-beside-keyboard with a variables bay under the glass and the history tape at full height alongside.
  • Keyboard aspect fidelity — each keyboard's proportions derive from its real key grid (the Voyagers land landscape at 2.89:1, the HP-35 portrait at 0.70:1, the open HP-28 clamshell at 2.04:1) and scale uniformly — no distortion, no clipping; dual-pitch rows (the genuinely wider digit keys) are modeled exactly via lcm sub-column grids, and the two-block machines (28C/28S, 97) merge their halves across a bare-plate hinge gap.
  • Per-family glass — short single-line seven-segment (DSEG7) readouts for Classic/Voyager models, like the real hardware; a fine dot-matrix (DotGothic16) display for RPL and the pioneer 42S/35s, with the primary number as a vertically-stretched hero that auto-fits the glass (never clipped, even on the keyboard-cramped 35s); a 131:64-proportioned multi-line stack display for RPL after the real HP-48 screen; and the HP Prime as a native colour touchscreen — its Home view rendered at browser resolution (real fonts + KaTeX math), not a pixel LCD, laying screen-beside-keyboard on wide slots.
  • Live faceplate switches — the Power / Mode / Trace slide switches on the classic programmables and the HP-97 actually work: Power lights or darkens the LCD (state preserved), Mode toggles PRGM/RUN program entry, and Trace gates the HP-97 printer echo.
  • Paper, not pixels — history prints as a calculator tape; stack and variables are notebook notes; each individually toggleable and placed by the active template (sheets on phones).
  • Type, don't tap — per-model physical-keyboard maps with visible key echo, a ? shortcut cheat-sheet, and a ⌘K model picker.
  • Prefix promotion — arming any shift plane (f/g/h/f⁻¹/left/right/alpha) promotes each key's shifted function into its primary slot, so the keyboard always shows what a press will do; per-model shift palettes (48SX orange/blue, 49G green/red, 50g white/orange, 28 red) re-theme the planes token-deep.
  • Trademark-safe branding — HELLO·CALC nameplates with the pink hc mark and bare model numbers; mode tags (RPN, FINANCIAL, …) as top-bar badges.

All of it is guarded by unit/component suites (geometry, templates, promotion, machine anatomy) and a Playwright device-matrix e2e (keyboard aspect fidelity ±2%, template boundaries, typing, sheet behavior).

Emulated models

35 landmark models across the HP eras, plus native mode — each backed by a verified keyboard layout and function set (see hp/):

Family Models Logic
Voyager HP-12C, HP-12C Platinum, HP-15C, HP-11C, HP-16C 4-level RPN (Platinum adds RPN/ALG)
Classic / Woodstock HP-35, HP-45, HP-65, HP-25 4-level RPN
Programmable / desktop HP-67, HP-97 4-level RPN
HP-41 HP-41C/CV, HP-41CX 4-level RPN (alphanumeric)
Pioneer scientific HP-42S, HP-27S, HP-32S, HP-32SII, HP-20S RPN / algebraic
Pioneer financial HP-17B, HP-17BII, HP-18C, HP-19B, HP-19BII algebraic + RPN, menu-driven
Modern financial HP-10BII, HP-20b, HP-30b algebraic + RPN
RPL clamshell HP-28C, HP-28S RPL (dynamic stack)
RPL graphing HP-48SX, HP-48G, HP-48GX, HP-49G, HP-50g RPL (dynamic stack)
Modern HP-35s, HP Prime RPN / configurable
Native mode RPN or algebraic

Full feature parity with the legendary HP-48 series (matrices, statistics, programmability) is an explicit goal.

All 35 faceplates and native mode are live and fully wired — no inert keys — each backed by its verified hp/ reference data and computing on the shared engine. The app opens on the HP-35s by default; models are chosen from a collapsible sidebar tree or the topbar gallery picker.

A few of the newest additions carry partial fidelity, noted honestly: the HP-32SII's new-function key positions are inferred (its manual ships no keyboard diagram); the menu-driven financials' variable-entry UX and the HP-27S/HP-32S application menus are navigable but some leaf functions are inert pending deeper wiring; the HP-12C Platinum reuses the HP-12C keyboard (its differences — RPN/ALG mode, backspace, faster CPU — are mostly non-keyboard) and the HP-48GX reuses the HP-48G keyboard (the GX adds expansion ports, not keys).

Architecture

A client-side, statically-deployable app — no backend required. The full rationale and library-by-library evaluation is in docs/architecture.md; in short:

  • Pure-TypeScript engine, framework-agnostic (no React), unit-tested in isolation.
  • Unified core (eager): Math.js as the number tower, expression parser, units, matrices, and complex numbers — with decimal.js used directly for fixed-point currency in the finance module. (Math.js BigNumber is decimal.js under the hood.)
  • Tiered CAS behind one CasProvider interface:
    • Light (lazy): Nerdamer (nerdamer-prime fork) / Algebrite for everyday symbolic math.
    • Heavy (lazy, optional): Pyodide + SymPy/mpmath (CPython → WASM) for Mathematica-grade CAS — loaded on demand, never in the initial bundle.
  • Linear algebra: ml-matrix for decompositions.
  • Rendering: KaTeX (react-katex).
  • Plotting (lazy): function-plot (2D) + Plotly.js (3D / statistical).
  • Programmability: HP programs run in a sandboxed interpreter (Web Worker, step/time limits) — never eval.
  • Model-adapter layer drives keystroke dispatch and per-model exposure from the hp/ data assets (below).

UI stack: Next.js (React client components) · shadcn/ui on Base UI · Tailwind CSS v4 (the app's own HP-calculator design tokens in the @theme block of globals.css) · TypeScript · React state (useState/useReducer) for history and the RPN stack.

Heavy dependencies (Plotly, Pyodide, CAS libraries) are code-split and lazy-loaded to keep the initial bundle small.

The hp/ reference

The hp/ directory is a first-class product input, not just documentation — the app consumes it directly:

  • hp/layouts/ — per-model keyboards (key positions, legends, shift colors) → drives faceplate rendering.
  • hp/functions/ — per-model function catalogs → drives per-model feature exposure.
  • hp/mapping/ — a unified key+prefix → function map (CSV + JSON) → drives keystroke dispatch (regenerable via hp/mapping/build_mapping.py).
  • hp/manuals/ — source owner's manuals for behavior verification.

Project structure

src/
  lib/engine/     # pure-TS math engine (value tower, parser, stack machine, feature modules)
  lib/layout/     # layout oracles: keyboard geometry, page templates, shared breakpoints
  lib/models/     # model-adapter layer (keystroke → engine op; per-model config from hp/)
  hooks/          # React hooks bridging engine ↔ UI (calculators, hotkeys, viewport tier)
  components/     # the machine (bezel, keyboards, LCD, paper tape/notes) + chrome (topbar, nav)
  components/ui/  # shadcn primitives (added via CLI)
  app/            # Next.js routes/layout (static export)
  __tests__/      # unit/component tests (Vitest)
e2e/              # end-to-end tests (Playwright)
docs/             # prd.md, architecture.md, responsive-layout.md
plan/             # phased implementation plan (one .md per phase + index)
hp/               # HP calculator reference (layouts, functions, mapping, manuals)

Getting started

This project uses pnpm (see packageManager), Node 24, Next.js, and Tailwind v4.

pnpm install
pnpm dev          # start the dev server → http://localhost:3000

Scripts

pnpm lint         # ESLint
pnpm test         # unit & component tests (Vitest)
pnpm test:e2e     # end-to-end tests (Playwright)
pnpm build        # static export → out/

Before finishing any change, pnpm lint, pnpm test, and pnpm build must pass — see the full build rules in AGENTS.md.

Deployment

Configured via next.config.ts as a static export (output: "export") under the base path /hellocalc, deployed to GitHub Pages automatically on push to main by .github/workflows/deploy.yml — live at https://christinetham.github.io/hellocalc/. CI (lint · test · build · e2e) runs via .github/workflows/ci.yml. The app can also be deployed to Vercel.

Because it's a static export, there is no server runtime: no API routes, Server Actions, or middleware — everything runs in the browser.

Roadmap — the completed build order

Built in iterative, chronological phases, all now delivered. With every faceplate live from the start, each phase took the next HP model (in release order), implemented the engine capability it first required, and wired it through the existing keys — finish line per model: no inert key. Large subsystems (programmability, RPL, units, CAS, plotting, heavy CAS) got their own phase; native mode was last. Full detail — one file per phase with tasks and acceptance tests — is in plan/ (index).

Phase 1 — Engine foundation & HP-35 (1972). The shared pure-TS engine (math.js/BigNumber value tower, 4-level RPN stack + LAST X, memory, scientific functions), the hp/mapping-driven model adapter, and state persistence — making the already-live HP-35 the first fully functional, exact-arithmetic model.

Then, in release order:

Phases Models · era Capability introduced
2–5 HP-45, HP-65, HP-25, HP-67/97 · 1973–76 Statistics; keystroke programmability (sandboxed); continuous memory; indirect addressing
6 HP-41C/CV · 1979–80 Alphanumeric display, ALPHA mode, named programs, USER keys
7–8 HP-12C, HP-11C · 1981 Financial engine (TVM/NPV/IRR/bonds); probability
9–11 HP-15C, HP-16C, HP-41CX · 1982–83 Complex, matrices, SOLVE & ∫; integer/base/bitwise; extended memory
12–16 HP-28C, HP-28S, HP-42S · 1986–88 RPL dynamic stack; units; light symbolic CAS; menu-driven RPN + regression
17–18 HP-48SX, HP-48G · 1990–93 Plotting (2D → 3D/statistical); equation writer, apps
19–20 HP-49G, HP-50g · 1999–2006 Heavy CAS (lazy Pyodide+SymPy); CAS-graphing consolidation
21–22 HP-35s, HP Prime · 2007–13 Modern RPN/algebraic dual entry; touchscreen CAS, Home/CAS + apps
23 Native mode Full-engine expression evaluator: notebook, expression library, copy/paste + KaTeX export

Responsive scaling and the history display are already delivered (see docs/responsive-layout.md) and reused by every faceplate; state persistence is established in Phase 1, and file import/export and named workspaces are finalized in Phase 23 (see architecture §9).

Contributing

Read AGENTS.md before writing code — it defines the hard rules (fully-typed TypeScript, vanilla Tailwind, shadcn-via-CLI, testing, static-export constraints) and which skills to use for each kind of task.

About

Experimental advanced calculator, reimagined as a modern app.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors