# kbCalc [![Licence: MIT](https://img.shields.io/badge/licence-MIT-2bff77.svg)](LICENSE) [![Poslední vydání](https://img.shields.io/github/v/release/tengolabs/kbcalc)](../../releases) [![Testy](https://github.com/tengolabs/kbcalc/actions/workflows/test.yml/badge.svg)](../../actions) [![Stažení](https://img.shields.io/github/downloads/tengolabs/kbcalc/total)](../../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). ![kbCalc — kalkulačka s rozbaleným přehrávačem](docs/screenshot.png) 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. Mini zápisník pod kalkulačkou s vloženým výsledkem **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í. Přehrávač s otevřeným ekvalizérem - **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á. Dialog O aplikaci > 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