diff --git a/.continue/rules/project.md b/.continue/rules/project.md
index 746f646..b056b97 100644
--- a/.continue/rules/project.md
+++ b/.continue/rules/project.md
@@ -1,20 +1,24 @@
# Project rules — RPN Virtual Calculator
-- Build a browser-friendly RPN calculator as a JavaScript class, preferably in a single file.
+- Build a browser-friendly RPN calculator as a JavaScript class, currently implemented in `src/rpn-calculator.js`.
- Keep code names, categories, and API identifiers in English.
-- Use only read-only / generic public API methods: `push`, `pop`, `clear`, `swap(index1, index2)`, `remove(index)`, `edit(index)`, `isValidIndex(index)`, `input(command)`, and `command(name, ...args)`.
-- Expose `inputValue` as a string and `isEditing` as a boolean.
-- Constructor options:
+- Keep the public calculator API centered on the generic methods `push`, `pop`, `clear`, `swap(index1, index2)`, `remove(index)`, `edit(index)`, `isValidIndex(index)`, `input(command)`, and `command(name, ...args)`.
+- `inputValue` must remain a string and `isEditing` must remain a boolean.
+- Keep constructor options aligned with the current engine:
- `maxSize` (default `2048`)
- - `base` (default `10`)
- - `angleMode` (`deg` default; also `rad` and `grad`)
+ - `base` (default `10`, accepted range `2..16`)
+ - `angleMode` (`deg` by default; also `rad` and `grad`)
- `enabledCommands`
-- Available constants: `pi`, `e`.
-- Supported operations must be centralized in one dictionary containing at least:
+- Available constants are `pi` and `e`.
+- Supported operations must stay centralized in one dictionary containing at least:
- `argCount`
- `category`
- `aliases`
-- Allowed categories are limited to: `Stack`, `Arithmetic`, and `Trigonometry`.
+ - `execute`
+- Allowed operation categories are limited to `Stack`, `Arithmetic`, and `Trigonometry`.
+- The engine currently exposes static helpers for category discovery: `getOperationCategories()` and `getOperationsByCategory()`.
+- The instance currently exposes `getOperationsByCategory()` and `getConstants()` helpers in addition to the generic API.
+- Preserve browser and CommonJS exports for `RpnCalculator`.
## Supported commands
@@ -22,42 +26,70 @@
- `add`, `sub`, `mul`, `div`, `mod`, `pow`, `sqr`, `neg`, `sqrt`, `recip`,
`sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `log`, `ln`,
`dup`, `drop`, `swap`, `clear`, `enter`
-- Aliases:
+- Current aliases include:
- `+`, `-`, `*`, `/`, `%`, `^`, `y^x`, `1/x`
+- Existing extra alias also present in code:
+ - `sqrt(x)` for `sqrt`
## Behavior rules
-- `mod` is the percentage operator: `a b % => (a * b) / 100`
-- `sqrt`, `asin`, `acos`, `log`, and `ln` must throw clear, explicit domain errors
-- `log` uses `Math.log10`
-- `ln` uses `Math.log`
-- Trigonometric functions must support `deg`, `rad`, and `grad`
-- In the browser demo, degrees are the default angle mode
-- `inputValue` must remain a string to preserve future hexadecimal input support
+- `mod` is the percentage operator: `a b % => (a * b) / 100`.
+- `div` and `recip` must throw `Division by zero` on zero divisors.
+- `sqrt`, `asin`, `acos`, `log`, and `ln` must throw explicit domain errors.
+- `log` uses `Math.log10`.
+- `ln` uses `Math.log`.
+- Trigonometric functions must support `deg`, `rad`, and `grad`.
+- Direct trigonometric functions convert input angles with `toRadians(...)`.
+- Inverse trigonometric functions convert results back using the current angle mode via `toDegrees(...)`.
+- The engine rounds formatted numeric results to 12 decimal places and normalizes `-0` to `0`.
+- `inputValue` must remain a string to preserve future hexadecimal-style input support.
+- `parseInputValue(...)` currently uses `Number(...)` in base 10 and `parseInt(..., base)` for other bases.
+- `input(command)` currently accepts single-character numeric editing input, including `0-9`, `A-F`, `a-f`, `+`, `-`, and `.`.
+- `command(name, ...args)` currently resolves aliases, supports constants, commits pending input before execution, checks `enabledCommands`, and throws clear `Unknown command`, `Command disabled`, `Stack overflow`, `Stack underflow`, `Invalid stack index`, `Invalid number`, and `Invalid input value` errors where appropriate.
## Demo rules
-- The browser demo lives under `samples/dev/`
-- `samples/dev/index.html` is the demo entry page
-- `samples/dev/index.css` contains the calculator visual theme
-- `samples/dev/index.js` contains demo-side presentation helpers and UI logic
-- The demo UI must expose:
- - a stack display
- - a main display
+- The active browser demo lives under `samples/dev/`.
+- `samples/dev/index.html` is the demo entry page.
+- `samples/dev/index.css` contains the calculator visual theme.
+- `samples/dev/index.js` contains demo-side presentation helpers and UI logic.
+- The demo currently exposes:
+ - a stack display with four visible lines
+ - a main display/status area
- a visible angle mode indicator
- an angle mode selector for `deg`, `rad`, and `grad`
-- The demo may present user-facing labels such as `+`, `−`, `×`, `÷`, `y^x`, `1/x`, and `x²` while still using English command identifiers internally
-- The example HTML must group buttons by `Stack`, `Arithmetic`, and `Trigonometry`
-- The example HTML must call `command(...)` for actions
-- Keyboard support in the demo should remain consistent with the displayed help text
+ - status pills showing `inputValue` and `isEditing`
+ - grouped command panels for `Stack`, `Arithmetic`, `Trigonometry`, and `Constants`
+ - an error display area
+- The demo may present user-facing labels such as `+`, `−`, `×`, `÷`, `y^x`, `1/x`, and `x²` while still using English command identifiers internally.
+- The example HTML groups buttons by `Stack`, `Arithmetic`, and `Trigonometry`, plus a dedicated `Constants` section.
+- Demo buttons are wired through demo helpers that eventually call `command(...)` for calculator commands.
+- The demo default angle mode is degrees.
+- Keyboard support in the demo must remain consistent with the displayed help text.
+- The current demo keyboard behavior supports:
+ - digits and decimal point
+ - numpad digits and numpad arithmetic keys
+ - `Enter` to validate input or toggle stack-item move mode
+ - `Backspace` to edit input or drop from the stack
+ - `Delete` to clear
+ - `Escape` to cancel editing, cancel move mode, or clear selection
+ - `ArrowUp` / `ArrowDown` to navigate or move selected stack items
+ - `ArrowRight` for swap
+ - `+`, `-`, `*`, `/`, `%`, `^`
+ - `q`, `n`, `r`, `i`, `g`, `l`, `s`, `c`, `S`, `C`
+ - `x`, `y`, `z`, `t` to select visible stack registers
+- The demo currently implements stack selection and stack-item move mode in its own UI logic using the public stack methods.
+- The demo currently duplicates X on `enter` when not editing, matching classic RPN-style behavior in the UI layer.
## File references
-- `samples/dev/index.html` references `src/rpn-calculator.js` as the calculator engine used by the demo
-- Keep the demo aligned with the public calculator API exposed by `src/rpn-calculator.js`
+- `samples/dev/index.html` references `../../src/rpn-calculator.js` as the calculator engine used by the demo.
+- Keep the demo aligned with the public calculator API exposed by `src/rpn-calculator.js`.
+- `README.md` is currently outdated and duplicated in places; if documentation work is done later, align it with the actual engine and demo behavior.
## Maintenance
+- Re-read `src/rpn-calculator.js` and `samples/dev/` before updating these rules after project changes.
- Keep this file updated after each project change using the provided editing tools.
-- When changing the demo UI or calculator API, update these rules so they continue to match the current project behavior.
+- When changing the demo UI, keyboard help, exported API, command metadata, or calculator behavior, update these rules so they continue to match the current project behavior.
diff --git a/README.md b/README.md
index 5d53e62..253b3c9 100644
--- a/README.md
+++ b/README.md
@@ -2,87 +2,122 @@
A browser-friendly RPN calculator built around a small, generic JavaScript API.
-## Goal
+## Overview
-This project defines a reusable RPN calculator engine with:
+This project provides:
-- a simple stack-based public API
-- configurable numeric and UI behavior
-- centralized command metadata
-- a browser demo that uses the same public API as any consumer code
+- a reusable JavaScript RPN engine in `src/rpn-calculator.js`
+- a browser demo in `samples/dev/`
+- a command system centralized in a single operation dictionary
+- a small public API focused on stack operations and generic command dispatch
-# RPN Virtual Calculator
-
-A browser-friendly RPN calculator built around a small, generic JavaScript API.
-
-## Goal
-
-This project provides a reusable Reverse Polish Notation (RPN) calculator engine with:
-
-- a simple stack-based public API
-- configurable numeric behavior
-- centralized command metadata
-- browser demos that use the same public API as any consumer code
+The main class is `RpnCalculator`.
## Project structure
- `src/rpn-calculator.js`: calculator engine
-- `samples/dev/index.html`: browser demo
-- `samples/calc-01/index.html`: browser demo
-- `samples/calc-XX/index.html`: browser demo
+- `samples/dev/index.html`: active browser demo entry point
+- `samples/dev/index.css`: demo styles
+- `samples/dev/index.js`: demo UI and keyboard logic
+- `samples/calc-01/index.html`: active browser demo entry point
+- `samples/calc-01/index.css`: demo styles
+- `samples/calc-01/index.js`: demo UI and keyboard logic
+- `samples/calc-XX/index.html`: active browser demo entry point
+- `samples/calc-XX/index.css`: demo styles
+- `samples/calc-XX/index.js`: demo UI and keyboard logic
-## Main features
+## Public API
-- Single JavaScript class: `RpnCalculator`
-- Configurable stack size via `maxSize` (default: `2048`)
-- Configurable numeric base via `base` (default: `10`)
-- Configurable angle mode via `angleMode`:
- - `deg` (default)
- - `rad`
- - `grad`
-- Optional command filtering through `enabledCommands`
-- Public API limited to generic methods:
- - `push(value)`
- - `pop()`
- - `clear()`
- - `swap(index1, index2)`
- - `remove(index)`
- - `edit(index)`
- - `isValidIndex(index)`
- - `input(command)`
- - `command(name, ...args)`
-- `inputValue` is always stored as a string
-- `isEditing` is exposed as a boolean
-- Supported operations are centralized in one dictionary with metadata such as:
- - `argCount`
- - `category`
- - `aliases`
-- Supported categories are limited to:
- - `Stack`
- - `Arithmetic`
- - `Trigonometry`
-## Available constants
+The calculator API is centered on these methods:
+
+- `push(value)`
+- `pop()`
+- `clear()`
+- `swap(index1, index2)`
+- `remove(index)`
+- `edit(index)`
+- `isValidIndex(index)`
+- `input(command)`
+- `command(name, ...args)`
+
+Instance helpers also available:
+
+- `getOperationsByCategory()`
+- `getConstants()`
+
+Static helpers also available:
+
+- `RpnCalculator.getOperationCategories()`
+- `RpnCalculator.getOperationsByCategory()`
+
+State exposed on instances:
+
+- `inputValue` as a string
+- `isEditing` as a boolean
+- `stack` as the current internal stack array used by the demo
+- `angleMode`
+- `base`
+- `maxSize`
+
+## Constructor options
+
+```js README.md
+const calc = new RpnCalculator({
+ maxSize: 2048,
+ base: 10,
+ angleMode: 'deg',
+ enabledCommands: ['add', 'sub', 'mul', 'div']
+});
+```
+
+Supported options:
+
+- `maxSize`: maximum stack size, default `2048`
+- `base`: numeric base, default `10`, accepted range `2..16`
+- `angleMode`: `deg`, `rad`, or `grad`, default `deg`
+- `enabledCommands`: optional whitelist of enabled commands and aliases
+
+## Constants
+
+Available constants:
- `pi`
- `e`
+They can be used through `command(...)`:
+
+```js README.md
+calc.command('pi');
+calc.command('e');
+```
+
## Supported commands
+### Stack
+
+- `enter`
+- `dup`
+- `drop`
+- `swap`
+- `clear`
+
### Arithmetic
-- `add` (`+`)
-- `sub` (`-`)
-- `mul` (`*`)
-- `div` (`/`)
-- `mod` (`%`)
-- `pow` (`^`, `y^x`)
+
+- `add` alias: `+`
+- `sub` alias: `-`
+- `mul` alias: `*`
+- `div` alias: `/`
+- `mod` alias: `%`
+- `pow` aliases: `^`, `y^x`
- `sqr`
- `neg`
-- `sqrt`
-- `recip` (`1/x`)
+- `sqrt` alias: `sqrt(x)`
+- `recip` alias: `1/x`
- `log`
- `ln`
### Trigonometry
+
- `sin`
- `cos`
- `tan`
@@ -90,57 +125,146 @@ This project provides a reusable Reverse Polish Notation (RPN) calculator engine
- `acos`
- `atan`
-### Stack
-- `dup`
-- `drop`
-- `swap`
-- `clear`
-- `enter`
-
-## Behavior rules
+## Behavior notes
- `mod` is a percentage operator:
- `a b % => (a * b) / 100`
+- `div` and `recip` throw `Division by zero` when needed
+- `sqrt` throws `Invalid input for sqrt` for negative values
+- `asin` and `acos` throw explicit domain errors outside `[-1, 1]`
+- `log` throws `Invalid input for log` for values `<= 0`
+- `ln` throws `Invalid input for ln` for values `<= 0`
- `log` uses `Math.log10`
- `ln` uses `Math.log`
-- `sqrt`, `asin`, `acos`, `log`, and `ln` throw explicit domain errors on invalid input
-- Trigonometric behavior depends on `angleMode`
-- In degree mode:
- - `sin`, `cos`, `tan` convert degrees to radians internally
- - `asin`, `acos`, `atan` return degrees
-- `inputValue` remains a string to preserve future support for formats such as hexadecimal input
+- direct trigonometric functions convert input using `toRadians(...)`
+- inverse trigonometric functions convert results back using the current angle mode
+- formatted numeric values are rounded to 12 decimal places
+- `-0` is normalized to `0`
+- `inputValue` remains a string to preserve future non-decimal input support
+- base 10 input is parsed with `Number(...)`
+- non-decimal input currently uses `parseInt(..., base)`
+
+## Input handling
+
+`input(command)` supports two modes:
+
+- single-character editing input
+- command dispatch
+
+Accepted single-character editing input currently includes:
+
+- `0-9`
+- `A-F`
+- `a-f`
+- `+`
+- `-`
+- `.`
+
+Everything else is forwarded to `command(...)`.
## Basic usage
-### In a browser
-- `rpn-calculator.js`: calculator engine
-- `rpn-example.html`: example browser interface
+### CommonJS
-## Main features
-- Single JavaScript class
-- Configurable stack size (`maxSize`, default: `2048`)
-- Configurable numeric base (`base`, default: `10`)
-- Configurable angle mode (`angleMode`, default: `deg`)
-- Optional command filtering through `enabledCommands`
-- Generic public API centered on:
- - `push`
- - `pop`
-- `clear`
- - `swap(index1, index2)`
- - `remove(index)`
- - `edit(index)`
- - `isValidIndex(index)`
- - `input(command)`
- - `command(name, ...args)`
-- `inputValue` is kept as a string to preserve future input formats
-- `isEditing` is exposed as a boolean state
-- All supported commands are described in one centralized dictionary
-- Supported categories are limited to:
- - `Stack`
- - `Arithmetic`
- - `Trigonometry`
+```js README.md
+const RpnCalculator = require('./src/rpn-calculator');
-## Basic usage
+const calc = new RpnCalculator();
+calc.push(2);
+calc.push(3);
+calc.command('add');
-### In a browser
+console.log(calc.pop()); // 5
+```
+### Browser
+
+```html README.md
+
+
+```
+
+### Editing values through `input(...)`
+
+```js README.md
+const calc = new RpnCalculator();
+
+calc.input('1');
+calc.input('2');
+calc.input('.');
+calc.input('5');
+calc.command('enter');
+
+console.log(calc.pop()); // 12.5
+```
+
+### Aliases
+
+```js README.md
+const calc = new RpnCalculator();
+calc.push(6);
+calc.push(7);
+calc.command('+');
+console.log(calc.pop()); // 13
+```
+
+### Constants and trigonometry
+
+```js README.md
+const calc = new RpnCalculator({ angleMode: 'deg' });
+calc.command('pi');
+console.log(calc.pop());
+
+calc.push(30);
+calc.command('sin');
+console.log(calc.pop()); // 0.5
+```
+
+## Demo
+
+The active demo lives in `samples/dev/`.
+
+Main UI features:
+
+- four visible stack lines
+- main display/status area
+- visible angle mode indicator
+- angle mode selector for `deg`, `rad`, and `grad`
+- status pills for `inputValue` and `isEditing`
+- grouped panels for `Stack`, `Arithmetic`, `Trigonometry`, and `Constants`
+- error display area
+
+The demo loads the engine from:
+
+```html README.md
+
+```
+
+### Demo keyboard support
+
+The current demo supports:
+
+- digits and decimal point
+- numpad digits and numpad arithmetic keys
+- `Enter`
+- `Backspace`
+- `Delete`
+- `Escape`
+- `ArrowUp`, `ArrowDown`, `ArrowRight`
+- `+`, `-`, `*`, `/`, `%`, `^`
+- `q`, `n`, `r`, `i`, `g`, `l`, `s`, `c`, `S`, `C`
+- `x`, `y`, `z`, `t`
+
+The demo also implements stack selection and stack-item move mode in its UI layer using the public calculator methods.
+
+## Exports
+
+`RpnCalculator` is exposed in both environments:
+
+- browser: `window.RpnCalculator`
+- CommonJS: `module.exports = RpnCalculator`