Files
Hellion-NewTab/docs/superpowers/specs/2026-04-16-calculator-upgrade-design.md
T
JonKazama-Hellion cebf277a5d docs(spec): Calculator Upgrade v2.1.0 Design-Spec
6 Modi: Standard, Scientific, Unit-Converter, Satisfactory, Factorio, Stationeers.
Tab-basierte Architektur, Registrierungs-Pattern, erweiteter Shunting-Yard Parser.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 21:22:07 +02:00

16 KiB
Raw Blame History

Hellion NewTab — Calculator Upgrade Design

Datum: 2026-04-16 Autor: Florian Wathling / Claude Code Status: Approved Scope: Calculator erweitern um Scientific, Unit-Converter und Game-Rechner (Satisfactory, Factorio, Stationeers) Ziel-Version: v2.1.0


Kontext

Der Calculator ist aktuell ein reiner Grundrechenarten-Taschenrechner (720 Zeilen, Shunting-Yard Parser, 4x5 Button-Grid, History). Das Upgrade macht ihn zum zentralen Tool-Widget mit 6 Modi:

  1. Standard (bestehend)
  2. Scientific (Wurzel, Potenz, Pi, Formel-Helfer)
  3. Unit-Converter (Länge, Gewicht, Temperatur, Volumen, Geschwindigkeit, Fläche)
  4. Satisfactory (Items/Min, Overclock-Power, Maschinen-Rechner)
  5. Factorio (Assembler-Ratios, Belt-Throughput, Maschinen-Rechner)
  6. Stationeers (Idealgas, Furnace/Verbrennung, Solar/Batterie, Atmosphäre)

Sektion 1: Architektur und Dateistruktur

Datei-Aufteilung

src/js/
├── calculator.js          # Core: Tab-System, Standard-Modus, erweiterter Shunting-Yard Parser
├── calc-scientific.js     # Scientific-Modus
├── calc-converter.js      # Unit-Converter
├── calc-satisfactory.js   # Satisfactory Calculator
├── calc-factorio.js       # Factorio Calculator
└── calc-stationeers.js    # Stationeers Calculator

Load-Order in newtab.html

... → widgets.js → notes.js → calculator.js → calc-scientific.js → calc-converter.js →
calc-satisfactory.js → calc-factorio.js → calc-stationeers.js → timer.js → ...

Alle Mode-Dateien laden nach calculator.js und vor timer.js. Kein zirkulärer Dependency-Konflikt.

Registrierungs-Pattern

Jede Mode-Datei registriert sich beim Calculator-Objekt:

Calculator.registerMode('scientific', {
  label: '\uD83D\uDCD0',        // Icon
  shortName: 'Sci',              // Tab-Label (3 Zeichen)
  titleKey: 'calculator.tab.scientific',  // i18n-Key
  render(bodyEl) { /* UI aufbauen */ },
  destroy() { /* Cleanup, Event-Listener entfernen */ }
});

calculator.js bekommt:

_modes: new Map(),
_activeMode: 'standard',

registerMode(name, config) {
  this._modes.set(name, config);
},

Die Tab-Leiste wird dynamisch aus _modes gebaut. Standard-Modus ist immer registriert (intern, nicht per externer Datei). Die anderen Modi kommen dazu wenn ihre Script-Datei geladen ist.

Tab-Wechsel

switchMode(name) {
  const mode = this._modes.get(name);
  if (!mode) return;
  this._activeMode = name;
  const body = WidgetManager.getBody(this.WIDGET_ID);
  if (!body) return;

  // Alten Modus aufräumen
  const oldMode = this._modes.get(this._previousMode);
  if (oldMode && oldMode.destroy) oldMode.destroy();

  // Neuen Modus rendern
  body.textContent = '';
  mode.render(body);

  // Tab-UI aktualisieren
  this._updateTabBar();

  // State speichern
  this.save();
}

Storage

Jeder Modus speichert seinen State als Sub-Key unter calculator im bestehenden widgetStates:

{
  calculator: {
    x: 400, y: 120, width: 320, height: 480,
    open: true,
    activeMode: 'standard',
    history: [{ expr: '42 × 7', result: '294' }],
    converter: { lastCategory: 'length', fromUnit: 'cm', toUnit: 'in' },
    satisfactory: { lastSubMode: 'itemsPerMin' },
    factorio: { lastSubMode: 'ratio', lastAssembler: 'asm3' },
    stationeers: { lastSubMode: 'gas' }
  }
}

Read-before-write Pattern bleibt: const data = await Store.get(this.STORAGE_KEY) || {};


Sektion 2: Standard-Modus (Änderungen)

Parser-Erweiterung

Der Shunting-Yard Parser wird um zwei Operationen erweitert:

Potenz-Operator ^:

  • Binärer Operator mit höchster Precedence (über * und /)
  • Rechts-assoziativ: 2^3^2 = 2^(3^2) = 512
  • Tokenizer erkennt ^ als { type: 'op', value: '^' }
  • parseFactor() → parsePower() → parseFactor() (neue Precedence-Stufe)

Wurzel-Funktion sqrt:

  • Wird vom Scientific-Modus als sqrt( in die Expression eingefügt
  • Tokenizer erkennt sqrt als { type: 'func', value: 'sqrt' }
  • parseFactor() prüft auf Functions vor Numbers

Die bestehende Operator-Hierarchie wird:

parseExpr:   + -
parseTerm:   * / %
parsePower:  ^           ← NEU
parseFactor: number | (expr) | func(expr)  ← func NEU

Keine Änderungen am Standard-UI

Das 4x5 Button-Grid, History-Panel und Keyboard-Support bleiben identisch. Die Parser-Erweiterung ist rückwärtskompatibel (keine bestehende Expression bricht).


Sektion 3: Scientific-Modus

Zusätzliche Buttons

2 neue Reihen über dem Standard-Grid:

Button Wert Aktion
sqrt( Unäre Funktion, öffnet Klammer
^2 Hängt ^2 an Expression
xⁿ ^ Fügt Potenz-Operator ein
π 3.14159265359 Konstante einfügen
e 2.71828182846 Konstante einfügen
± toggle Vorzeichen des letzten Werts wechseln

Darunter das Standard 4x5-Grid (C, Klammern, %, ÷, 0-9, Operatoren, =). Der Scientific-Modus nutzt den gleichen _handleKey()/_calculate()-Flow.

Formel-Helfer

Ein Dropdown unter dem Button-Grid mit vorgefertigten Formeln:

Formel Eingabefelder Berechnung
Kreis-Fläche Radius (r) π ×
Kreis-Umfang Radius (r) 2 × π × r
°C → °F Temperatur (C × 9/5) + 32
°F → °C Temperatur (F - 32) × 5/9
Pythagoras a, b √(a² + b²)
Prozent-Wert Wert, Prozent Wert × Prozent / 100

Jede Formel öffnet inline Eingabefelder + Live-Ergebnis. Nutzt _formatResult() für einheitliche Zahlenformatierung.

Keyboard

Gleicher Keyboard-Support wie Standard-Modus, plus:

  • p → Pi einfügen
  • e → Euler einfügen (kein Konflikt: e ist im Standard nicht belegt, nur c/C und Escape sind Clear)

Sektion 4: Unit-Converter

UI-Aufbau

┌──────────────────────────┐
│ [Kategorie-Dropdown    ▼]│
│                          │
│ [123.45    ] [cm      ▼] │
│       ⇅ (Swap-Button)    │
│ [48.622    ] [in      ▼] │
│                          │
│ Schnellreferenz:         │
│  1 cm = 0.3937 in       │
│  1 in = 2.54 cm         │
└──────────────────────────┘

Kategorien und Einheiten

Kategorie Einheiten Basis-Einheit
Länge mm, cm, m, km, in, ft, yd, mi m
Gewicht mg, g, kg, t, oz, lb g
Temperatur °C, °F, K (Spezialfunktionen)
Volumen ml, L, m³, gal(US), gal(UK), ft³ ml
Geschwindigkeit m/s, km/h, mph, kn m/s
Fläche mm², cm², m², km², ha, acre, ft², in²

Konvertierungs-Logik

Jede Einheit hat toBase(value) und fromBase(value):

const LENGTH_UNITS = {
  mm:  { toBase: v => v / 1000,     fromBase: v => v * 1000 },
  cm:  { toBase: v => v / 100,      fromBase: v => v * 100 },
  m:   { toBase: v => v,            fromBase: v => v },
  km:  { toBase: v => v * 1000,     fromBase: v => v / 1000 },
  in:  { toBase: v => v * 0.0254,   fromBase: v => v / 0.0254 },
  ft:  { toBase: v => v * 0.3048,   fromBase: v => v / 0.3048 },
  yd:  { toBase: v => v * 0.9144,   fromBase: v => v / 0.9144 },
  mi:  { toBase: v => v * 1609.344, fromBase: v => v / 1609.344 }
};

Temperatur bekommt eigene Funktionen (nicht linear):

const TEMP_CONVERSIONS = {
  'C_F': v => (v * 9/5) + 32,
  'C_K': v => v + 273.15,
  'F_C': v => (v - 32) * 5/9,
  'F_K': v => (v - 32) * 5/9 + 273.15,
  'K_C': v => v - 273.15,
  'K_F': v => (v - 273.15) * 9/5 + 32
};

Verhalten

  • Live-Update bei Eingabe (kein "Berechnen"-Button)
  • Swap-Button (⇅) tauscht Quell- und Ziel-Einheit
  • Schnellreferenz zeigt 1 [from] = x [to] und umgekehrt
  • Kein Keyboard-Override (native <input> Felder)

Storage

converter: { lastCategory: 'length', fromUnit: 'cm', toUnit: 'in' }

Sektion 5: Satisfactory Calculator

Sub-Modi

Drei Buttons oben wählen den aktiven Rechner:

5a: Items/Min

Eingabefelder:

  • Items per Craft (default: 1)
  • Craft Time in Sekunden (default: 4)
  • Clock Speed in % (default: 100)

Formel:

Output = (ItemsPerCraft × 60) / CraftTime × (ClockSpeed / 100)

Ausgabe: X.XX items/min

5b: Overclock Power

Eingabefelder:

  • Base Power in MW (default: 30)
  • Clock Speed in % (default: 100)

Formeln:

PowerUsage = BasePower × (ClockSpeed / 100) ^ 1.321928
EnergyPerItem = (ClockSpeed / 100) ^ 0.321928

Ausgabe:

  • Power Usage: X.X MW
  • Efficiency: ↓ X.X% per item (nur bei ClockSpeed > 100)

5c: Maschinen

Eingabefelder:

  • Target Output/Min (default: 60)
  • Items per Craft (default: 1)
  • Craft Time in Sekunden (default: 4)
  • Clock Speed in % (default: 100)
  • Base Power in MW (default: 30)

Formeln:

ItemsPerMin = (ItemsPerCraft × 60) / CraftTime × (ClockSpeed / 100)
Machines = ceil(TargetOutput / ItemsPerMin)
TotalPower = Machines × BasePower × (ClockSpeed / 100) ^ 1.321928

Ausgabe:

  • Machines needed: X
  • Total Power: X.X MW

Verhalten

Alle Felder berechnen live. <input type="number"> mit step-Attribut für sinnvolle Schrittweiten.


Sektion 6: Factorio Calculator

Sub-Modi

6a: Assembler-Ratio

Eingabefelder:

  • Assembler-Dropdown: Assembler 1 (0.5), Assembler 2 (0.75), Assembler 3 (1.25)
  • Recipe Output Count (default: 1)
  • Recipe Time in Sekunden (default: 1)

Formel:

OutputPerSecond = RecipeOutput × CraftingSpeed / RecipeTime
OutputPerMinute = OutputPerSecond × 60

Ausgabe:

  • X.XX items/s
  • X.XX items/min

6b: Belt-Throughput

Eingabefelder:

  • Belt-Dropdown: Yellow (15/s), Red (30/s), Blue (45/s)
  • Items consumed per second per machine (default: 1)

Feste Werte:

Belt Total (items/s) Per Side (items/s)
Yellow 15 7.5
Red 30 15
Blue 45 22.5

Formel:

MachinesPerBelt = floor(BeltThroughput / ItemsConsumedPerSec)
Utilization = (ItemsConsumedPerSec × MachinesPerBelt) / BeltThroughput × 100

Ausgabe:

  • Machines per belt: X
  • Belt utilization: X%

6c: Maschinen

Eingabefelder:

  • Assembler-Dropdown
  • Target Output/s (default: 10)
  • Recipe Output Count (default: 1)
  • Recipe Time in Sekunden (default: 1)

Formel:

OutputPerMachine = RecipeOutput × CraftingSpeed / RecipeTime
Machines = ceil(TargetOutput / OutputPerMachine)
TotalThroughput = Machines × OutputPerMachine
BeltNeeded = kleinster Belt der TotalThroughput schafft

Ausgabe:

  • Machines needed: X
  • Belt needed: [Color] (X% utilization)

Sektion 7: Stationeers Calculator

Sub-Modi

Vier Buttons oben (statt drei wie bei den anderen Game-Rechnern).

7a: Gas (Idealgas PV=nRT)

Eingabefelder:

  • Dropdown: Gesucht = P, V, n oder T
  • Die drei anderen Variablen als Eingabefelder

Konstante: R = 8314.46261815324 (Stationeers-spezifisch, Einheit: L·Pa / mol·K)

Formeln:

P = nRT / V
V = nRT / P
n = PV / RT
T = PV / nR

Eingabe-Einheiten:

  • P in kPa (wird intern × 1000 zu Pa)
  • V in Litern
  • T in Kelvin (Hilfstext zeigt °C-Äquivalent)
  • n in mol

7b: Furnace / Verbrennung

Eingabefelder:

  • Fuel Ratio (0 bis 1, Anteil Brennstoff am Gesamtgas)
  • Start-Temperatur in Kelvin
  • Start-Druck in kPa

Formeln:

T_nach = (T_vor × specificHeat + fuel × 563452) / (specificHeat + fuel × 172.615)
P_nach = P_vor × T_nach × (1 + 5.7 × fuel) / T_vor

Wobei:

  • fuel = min(ratioO2, ratioVolatile / 2)
  • specificHeat = gewichtete Summe der Gas-Wärmekapazitäten
  • Vereinfachung: Fuel Ratio als einzelner Wert (0-1), specificHeat(before) wird aus reinem Fuel berechnet (61.9 J/mol·K für 1:2 O₂:H₂ Mischung)
  • 563452 = Energie pro Mol bei 95% Effizienz
  • 172.615 = 0.95 × (243.6 - 61.9)

Validierung:

  • Warnung wenn Fuel < 0.05 (unter 5% Minimum)
  • Warnung wenn Start-Druck < 10 kPa

Ausgabe:

  • T after ignition: X K (X °C)
  • P after ignition: X kPa

7c: Solar / Batterie

Eingabefelder:

  • Anzahl Panels (default: 12)
  • Watt pro Panel (default: 500, Mond-Wert)
  • Tag-Länge in Sekunden (default: 600)
  • Nacht-Länge in Sekunden (default: 600)
  • Verbrauch in Watt (default: 2000)

Formeln:

Generation = Panels × WattsPerPanel
Surplus = Generation - Consumption
NightEnergy = Consumption × NightLength    (in Watt-Sekunden)
BatteriesNeeded = ceil(NightEnergy / 50000)  (Station Battery = 50.000 Ws)

Ausgabe:

  • Generation: X W
  • Surplus: X W (rot wenn negativ)
  • Night Energy: X Ws
  • Batteries needed: X

7d: Atmosphäre / Gas-Mischer

Eingabefelder:

  • Target Temperatur in Kelvin
  • Gas 1 Temperatur in Kelvin
  • Gas 2 Temperatur in Kelvin

Formel:

M1 = |T2 - T0| / (|T1 - T0| + |T2 - T0|)
M2 = 1 - M1

Ausgabe:

  • Mixer Input 1: X.X%
  • Mixer Input 2: X.X%

Aufklappbare Wärmekapazität-Referenz:

Gas Cp (J/mol·K)
O₂ 21.1
H₂ 20.4
CO₂ 28.2
N₂ 20.6
H₂O 72.0
N₂O 23.0
Pollutant 24.8

Sektion 8: UI, i18n und Widget-Sizing

Tab-Leiste

Horizontale Leiste direkt unter dem Widget-Header. Immer sichtbar (kein Scrollen).

Tab Icon Label
Standard 🔢 Std
Scientific 📐 Sci
Converter ⚖️ Unit
Satisfactory ⚙️ SAT
Factorio 🏭 FAC
Stationeers 🚀 STA

Aktiver Tab: border-bottom: 2px solid var(--accent), Text in var(--accent). Inaktive Tabs: color: rgba(255,255,255,0.5). CSS-Klasse: .calc-tab-bar und .calc-tab.

Widget-Sizing

  • Standard-Modus Minimum: 280 × 400 px
  • Komplexe Modi (Scientific, Game-Rechner): Auto-Resize auf 320 × 480 px (falls aktuell kleiner)
  • User-Resize überschreibt Auto-Resize
  • Widget-System-Minimum bleibt 200 × 150 px

i18n

Geschätzt ~100 neue Keys in STRINGS.de und STRINGS.en:

  • 6 Tab-Labels
  • 6 Kategorie-Namen (Converter)
  • ~48 Einheiten-Langformen (Converter)
  • ~30 Feld-Labels (Game-Rechner)
  • ~10 Ergebnis-Labels

Einheiten-Abkürzungen (cm, kg, °C, kPa) werden nicht übersetzt.

Keyboard

  • Standard-Modus: Bestehender Keyboard-Support (0-9, +, -, *, /, Enter, Backspace, Escape)
  • Scientific-Modus: Gleicher Support + p (Pi), ^ (Potenz)
  • Converter und Game-Modi: Kein Custom-Keyboard (native <input> Felder)

Betroffene Dateien (Gesamt)

Datei Änderung
src/js/calculator.js Tab-System, registerMode(), switchMode(), Parser-Erweiterung (^, sqrt)
src/js/calc-scientific.js NEU: Scientific-Modus
src/js/calc-converter.js NEU: Unit-Converter
src/js/calc-satisfactory.js NEU: Satisfactory Calculator
src/js/calc-factorio.js NEU: Factorio Calculator
src/js/calc-stationeers.js NEU: Stationeers Calculator
src/css/main.css Tab-Bar Styles, Mode-spezifische Styles
src/js/i18n.js ~100 neue Keys (DE + EN)
newtab.html 5 neue <script> Tags in Load-Order
manifest.json Version → 2.1.0
manifest.firefox.json Version → 2.1.0
manifest.opera.json Version → 2.1.0
CHANGELOG.md v2.1.0 Eintrag

Implementierungsreihenfolge

  1. Calculator Core — Tab-System, registerMode(), switchMode(), Tab-Bar CSS
  2. Parser-Erweiterung^ Operator und sqrt Funktion
  3. Scientific-Modus — Buttons, Formel-Helfer, Registrierung
  4. Unit-Converter — Kategorien, Einheiten, Konvertierungs-Logik, UI
  5. Satisfactory Calculator — 3 Sub-Modi, Formeln, UI
  6. Factorio Calculator — 3 Sub-Modi, Formeln, UI
  7. Stationeers Calculator — 4 Sub-Modi, Formeln, UI
  8. i18n — Alle neuen Keys (DE + EN)
  9. Version Bump — Manifests, CHANGELOG