# kbCalc
[](LICENSE)
[](../../releases)
[](../../actions)
[](../../releases)
*Prefer English? → [README.md](README.md)*
**Svobodný open source software (MIT).** Plovoucí průhledná **kalkulačka**
s vestavěným **MP3 přehrávačem ve stylu Winampu**. Postavené na Electronu,
jedna codebase pro **Linux, Windows i macOS**. Stáhněte, prostudujte,
forkněte, používejte i komerčně — přesně proto existuje: ukázková open source
aplikace od tvůrců [killBottleneck](https://killbottleneck.com).

Okno je frameless a průhledné — na první pohled jen kalkulačka, šipka `▶`
v dolní liště vedle ní vysune plnohodnotný přehrávač s vizualizérem.
## Funkce
**Kalkulačka**
- Myš i klávesnice (číslice, `+ - * /`, `Enter` = `=`, `Backspace`,
`Esc`/`C` = smazat, `.` nebo `,` jako desetinný oddělovač).
- Zelený LCD displej, oddělení tisíců mezerou.
- Záměrně se chová jako windowsovská *Standardní* kalkulačka:
vyhodnocení zleva doprava (`2 + 3 × 4 = 20`) a kontextová procenta
(`200 + 10 % = 220`, `200 × 10 % = 20`).
- Okno se dynamicky mění přesně podle obsahu — sbalené je *jen* kalkulačka
s mini ovládáním přehrávání v dolní liště.
- **Mini zápisník** (`✎`): malý samoukládací blok hned pod kalkulačkou —
chip `⤓` vloží aktuální výsledek na pozici kurzoru.
- **Historie výpočtů** (`≣`): posledních 50 výsledků i s výrazy; kliknutím
na záznam s ním počítáš dál. Persistovaná, jde smazat.
**Přehrávač**
- Transport (předchozí / play–pauza / stop / další / eject = přidat soubory)
+ **náhodné přehrávání** a **opakování** (vypnuto / vše / jedna) — obojí se pamatuje.
- **Hardwarová media tlačítka** fungují, i když je appka na pozadí
(play/pauza, další, předchozí, stop). Zabírají se jen dokud je kbCalc
aktivní přehrávač (od ▶ do Stop) — jinak je dál dostane Spotify či prohlížeč.
- **Ikona v tray**: zobrazit/skrýt okno, ovládání přehrávání, ukončení.
- VOLUME a BALANCE přes Web Audio + **5pásmový ekvalizér**
(60 Hz – 12 kHz, presety Flat/Rock/Pop/Jazz/Bass+/Vocal, pamatuje se).
- **ID3 tagy**: skladby zobrazují „Interpret – Název" z ID3v2/ID3v1
(parser bez závislostí); jinak název souboru.
- **Podcasty** (`📡`): vlož URL RSS kanálu a epizody se stanou novým
playlistem — streamují se na vyžádání (funguje i posun), vizualizér
a ekvalizér běží i u podcastů. Pozice přehrávání se pamatuje.
- **Internetové rádio** (`📻`): vlož URL streamu (Icecast/Shoutcast, např.
kanál SomaFM) a stanice se objeví v playlistu — displej ukazuje `LIVE`,
vizualizér i ekvalizér fungují jako u souborů.
- Vzdálené zdroje (podcasty, rádia) se připojují **až po stisku ▶** — obnova
playlistu po startu sama nikdy neotevře síťové spojení.
- **Víc pojmenovaných playlistů**: nový, inline přejmenování, smazání,
přepínání v hlavičce. Playlisty přežijí restart (ukládají se cesty;
audio se načítá líně — v paměti je max jedna skladba).
- **Drag & drop**: soubory → do aktuálního playlistu; složka → nový playlist
pojmenovaný po ní (rekurzivně, jen audio, seřazeno). Pořadí skladeb jde
měnit přetažením v playlistu.
- Mrtvé/smazané soubory se při přehrávání automaticky přeskočí.
- Formáty: mp3, m4a, ogg/oga, wav, flac, aac, opus, wma.
**Vizualizér**
- 6 stylů — výchozí **KŘIVKA** je hladké vyplněné spektrum s jemným odleskem
(pro fanoušky analyzérů ve stylu AIMP), dál SPEKTRUM, ZRCADLO, BLOKY,
VLNA a NORA. Klik na plochu nebo tlačítko stylu přepíná; volba se pamatuje.
- Fullscreen (`⛶`): klik = změna stylu, `Esc` = zpět.
**Okno**
- Vždy navrchu (`◉`), minimalizace, zavření — vlastní ovládání bez OS lišty.
- Pozice okna se pamatuje mezi spuštěními.
- Dialog O aplikaci (`ⓘ`) s odkazy na projekt a verzí. Jednou denně se appka
anonymně zeptá GitHub Releases, jestli není nová verze, a nabídne odkaz na
poznámky k vydání — žádná telemetrie, nic se nikam neodesílá.
> Rozhraní mluví **česky i anglicky** — řídí se jazykem systému a přepíná se v dialogu O aplikaci.
## Instalace
Instalátory jsou na stránce [Releases](../../releases):
Windows (NSIS + portable exe), Linux (AppImage + deb, x64), macOS (dmg/zip, Apple Silicon).
Buildy zatím **nejsou podepsané** — Windows SmartScreen / macOS Gatekeeper
při prvním spuštění varují (Windows: *Další informace → Přesto spustit*).
## Vývoj
```bash
npm install
npm start
```
## Build instalátorů
```bash
npm run dist # aktuální OS
npm run dist:linux # AppImage + deb
npm run dist:win # NSIS instalátor + portable exe
npm run dist:mac # dmg + zip
```
Instalátory se objeví v `dist/`. CI (`.github/workflows/build.yml`) staví
všechny tři OS na vlastních runnerech; tag `v*` vytvoří Release s balíčky.
## Poznámky k platformám
- Na **Linuxu** se vypíná HW akcelerace (workaround na pád GPU procesu u
průhledného okna); Windows/macOS ji mají zapnutou.
- Zabalené buildy běží s Chromium sandboxem na všech OS. `--no-sandbox`
předává jen vývojářský spouštěč `kbcalc.sh` (electronový `chrome-sandbox`
v `node_modules` nemá na některých distribucích SUID bit); `npm start` ne.
## Bezpečnostní model
- Renderer: `contextIsolation: true`, `nodeIntegration: false`.
- Preload most vystavuje minimum: ovládání okna + dvě souborové funkce pro
playlisty. `fs:read` čte jen skutečné audio soubory (allow-list přípon,
rozřešené symlinky, jen regulérní soubory), `fs:expand` nesleduje symlinky
a má strop hloubky rekurze.
- Restriktivní CSP (`connect-src 'self'`, bez `unsafe-inline`; média jen přes
`blob:` a vlastní schéma `kbaudio:`). Renderer nemá **žádný přímý přístup
k síti** — nemůže otevřít socket ani `fetch()` na cizí host.
- Navigace a `window.open` jsou v main procesu zakázané. Externí odkazy z
dialogu O aplikaci se otevírají v systémovém prohlížeči a jen z pevného
allowlistu podle klíče (renderer předává klíč, ne URL).
- Kontrola verze běží v main procesu, max 1× denně, offline mlčky selže.
- **Podcasty a internetová rádia** jsou jediné místo, kde renderer spustí
síťový požadavek, a to jen přes dva úzké kanály v main procesu: stažení RSS
kanálu, který vložíš, a stream epizody / stanice, kterou přehráváš (přes
vlastní schéma `kbaudio://`). Oba procházejí **ochranou proti SSRF** —
cílový host se resolvuje a privátní / loopback / link-local rozsahy se
odmítnou, redirecty se řeší ručně (`net.request` v manuálním režimu) a každý
hop se prověří, plus limit velikosti a timeout. Podvržený feed tak nedonutí
appku ťukat na `localhost` ani do LAN, a audio graf zůstává bez CORS-taintu,
takže vizualizér i ekvalizér fungují i u podcastů. Vzdálené zdroje se
připojují jen po stisku ▶, nikdy při startu.
- Žádná citlivá oprávnění: appka odmítá všechny žádosti o oprávnění
(mikrofon, kamera, notifikace…) — žádné nepotřebuje.
Našli jste zranitelnost? Viz [SECURITY.md](SECURITY.md).
## Autoři
**Richard Pobrislo** a **Claude Fable 5** (Anthropic) — od tvůrců
[killBottleneck](https://killbottleneck.com). Návody, novinky a AI experimenty
na YouTube: [@ctrlaltaicz](https://www.youtube.com/@ctrlaltaicz).
## Přispívání
Viz [CONTRIBUTING.md](CONTRIBUTING.md) — rozložení kódu, pravidla a spuštění
ze zdrojáků.
## Licence
[MIT](LICENSE) © 2026 Richard Pobrislo