chore: initial import

This commit is contained in:
2026-07-24 21:37:03 +02:00
commit 45bc449ea0
53 changed files with 12329 additions and 0 deletions
+82
View File
@@ -0,0 +1,82 @@
# Wandler
Einheiten, Formate, Farben und Zeit — in einer Zeile.
Dieses Werkzeug fällt bewusst aus der Reihe der übrigen Plugins: Es hat keinen
Job-Runner, keine Sicherungen, keine KI und keinen Tandoor-Zugriff. Es verändert
nichts und rechnet **vollständig im Browser**. Dadurch ist das Ergebnis sofort
da und funktioniert auch offline oder wenn Tandoor gerade streikt.
## Die Zeile oben
Einfach tippen, was gemeint ist — die Erkennung läuft deterministisch (keine KI),
also immer gleich und ohne Wartezeit:
```
2 cups Mehl in g → 251 g
180 C in F → 356 °F
5 km in mi → 3,1069 mi
2,5 TB in GiB → 2.328,31 GiB
1 1/2 EL in ml → 22,5 ml
#3b82f6 → rgb(59, 130, 246), hsl(217, 91%, 60%)
1699999999 → Dienstag, 14. November 2023
0 3 * * 1 → montags um 03:00 Uhr
0xff → 255
5 kg → Übersicht aller Gewichtseinheiten
```
Als Trennwort funktionieren `in`, `nach`, `to`, `als`, `zu`, `→` und `>`.
Mit **Eingabetaste** wird eine Umrechnung oben angeheftet; angeheftete und
zuletzt benutzte Umrechnungen bleiben im Browser gespeichert (nur lokal, es
verlässt nichts das Gerät). Ein Klick auf eine Ergebniszeile kopiert sie.
## Zahlen schreiben
* Komma und Punkt werden beide als Dezimaltrennzeichen verstanden: `2,5` = `2.5`.
* Tausendertrennung wird erkannt, wenn beide Zeichen vorkommen (`1.234,56`) oder
mehrere gleiche (`1.234.567`).
* Brüche gehen: `3/4`, `1 1/2`, `1½`.
* **Grenzfall:** `1.234` allein ist zweideutig und wird als 1,234 gelesen. Wer
1234 meint, schreibt es ohne Punkt.
## Reiter
**Küche** — Zutat umrechnen (Volumen ↔ Gewicht mit Dichte je Zutat), Ofen
(°C / °F / Umluft / Gasstufe), Löffel- und Tassenmaße, Portionen hochrechnen.
**Maße** — Länge, Gewicht, Volumen, Fläche, Zeit, Geschwindigkeit, Energie,
Druck, Temperatur.
**Technik** — Datenmengen (MB und MiB sauber getrennt), Zahlensysteme, Farben
mit Farbwähler.
**Formate** — Base64, URL-Kodierung, Slug, Groß-/Kleinschreibung, camelCase,
snake_case, kebab-case, Leerraum säubern, Zeichen zählen, JSON formatieren,
JSON ↔ YAML, JSON ↔ CSV.
**Zeit** — Zeitstempel, Zeitzonen, Datumsdifferenz, Kalenderwoche, Cron im
Klartext.
## Warum die Küchenwerte so aussehen
Volumen und Gewicht lassen sich nur über die **Dichte** ineinander umrechnen,
und die hängt an der Zutat: 1 Cup Mehl wiegt rund 125 g, 1 Cup Zucker rund
201 g. Die hinterlegte Tabelle deckt die üblichen Zutaten ab; ist eine Zutat
unbekannt, wird mit der Dichte von Wasser gerechnet **und das deutlich
angezeigt**. Küchenergebnisse werden bewusst grob gerundet — „250,7835 g Mehl“
wiegt niemand ab.
Ein US-Cup sind 236,6 ml, nicht 250 ml. „Pfund“ wird als 500 g gelesen (deutsche
Bedeutung), `lb` als 453,59 g.
## Bekannte Grenzen
* **YAML → JSON** liest nur den einfachen Teil der Sprache: verschachtelte
Zuordnungen, Listen und Skalare. Keine Anker, keine mehrzeiligen Blöcke, keine
Fluss-Syntax. Die Richtung JSON → YAML ist vollständig.
* **Gasstufen** folgen der britischen Skala (Gas Mark); deutsche Geräte können
abweichen.
* **Währungen** fehlen bewusst — die bräuchten einen Live-Kurs, und ein Wandler,
der still mit vorgestrigen Kursen rechnet, wäre schlimmer als keiner.
* Zeitzonen kommen aus dem Browser (`Intl`), es ist keine eigene Zeitzonen-
Datenbank eingebaut.
+31
View File
@@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
"""
Plugin-Adapter für den „Wandler“.
Bewusst schlank: Dieses Werkzeug rechnet vollständig im Browser. Es gibt keinen
Job-Runner, keine Sicherungen und keine KI — es verändert nichts und braucht
keinen Serverlauf. Das Backend liefert nur die Seite aus.
Vorteil: sofort da, funktioniert auch offline und wenn Tandoor gerade streikt.
"""
from __future__ import annotations
from typing import Any
from fastapi import FastAPI
from fastapi.responses import FileResponse
def create_app(ctx):
app = FastAPI(title=ctx.meta.name, docs_url="/api/docs", redoc_url=None)
@app.get("/", include_in_schema=False)
def index():
return FileResponse(ctx.path("static", "index.html"))
@app.get("/api/state")
def state() -> dict[str, Any]:
# Nur damit die Oberfläche eine Lebenszeichen-Abfrage hat.
return {"ok": True, "version": ctx.meta.version, "offline": True}
return app
+18
View File
@@ -0,0 +1,18 @@
{
"id": "werkzeuge-wandler",
"name": "Wandler",
"summary": "Einheiten, Formate, Farben, Zeit — alles in einer Zeile",
"description": "Ein Eingabefeld für alles: „2 cups Mehl in g“, „180 C in F“, „#3b82f6“, „1699999999“. Dazu Rechner für Küche, Maße, Technik, Formate und Zeit. Rechnet vollständig im Browser — kein Server, keine KI, keine Wartezeit.",
"icon": "🔀",
"category": "Werkzeuge",
"version": "1.0.0",
"entrypoint": "backend:create_app",
"order": 60,
"requires": [],
"features": [
"Eine Zeile für alles — erkennt selbst, was gemeint ist",
"Küchenmaße mit Dichte je Zutat (1 Cup Mehl ≠ 1 Cup Zucker)",
"Läuft ohne Server und ohne Internet"
],
"docs": "TOOL-README.md"
}
File diff suppressed because it is too large Load Diff