BareGUI
Po půldruhém roce se dostávám k pokračování Instalace OpenBSD. Druhá část je tedy na světě.
Po dlouhém období používání cwm(1) jsem dostal chuť se vrátit ke klasičtějšímu desktopovému prostředí. Nainstaloval jsem tedy Xfce, jedno z méně náročných a víceméně kompletních DE (desktop environment), velmi rozšířené v Linuxové komunitě i na BSD. Nastavení Xfce je jednoduché a je dobře popsáno zde. Na mém notebooku mi však Xfce připadalo zpomalené a navíc jsem si neužil takovou legraci s nastavováním.
Vrátil jsem se tedy k desktopu, který jeho autor nazývá BareGui a říká o něm následující:
This grew from a previous SimpleDesktop thread that built a lightweight Desktop Environment (DE) in OpenBSD. The older project relied on manually edited configuration scripts and menus. This iteration produces a fast, lightweight stacking desktop with a resting memory footprint around 170mb. When a user adds an application that has a freedesktop compliant *.desktop entry, it will automatically be added to the menu.
Jeho autorem je jediný člověk, shep, častý přispěvatel na daemonforums.org. Vzhled BareGUI je mírně inspirován MacOS.
Považuju BareGUI za jednoduchý funkční desktop a chci se zde věnovat jeho instalaci, ale nejprve pár slov o DE v unixovském světě obecně.
Desktopová prostředí
Uživatel, který k unixovským systémům přešel z Windows, si většinou není vědom, že to, co zná jako operační systém (OS), je v unixovském světě známé jako desktopové prostředí (DE), oddělené od samotného systému.
Pro mě bylo zpočátku překvapením, když na mě po dokončení instalace Linuxového distra zíral blikající kurzor terminálu. To je ten slavný Linux? Ano, je. Grafické prostředí (GUI) se jmenuje Xorg a instaluje se zvlášť. Teprve pak se na mé obrazovce objevilo něco, co už jsem znal: plochu a otevřené okno (znalci tuší, že se jedná o twm(1), prastarý window manager, nehezký, ale funkční).
Pomalu jsem začal chápat, jak v praxi funguje filozofie programu, co umí pouze 1 věc, ale umí ji dobře. To, čemu se říká DE, je ve skutečnosti souhra mnoha programů, které obstarávají funkce, na něž jsme zvyklí z Windows.
Tento přístup má tu výhodu, že lze ušít své GUI na míru vlastním potřebám a výkonnosti svého stroje. To je zároveň i nevýhoda, neboť je třeba se trochu ponořit do problematiky a strávit nějaký čas učením a experimentováním.
Unixovští uživatelé zpravidla volí jednu ze dvou cest:
Plnohodnotné DE jako Gnome či KDE, zmíněné Xfce nebo MATE, abych jmenoval ty nejznáměnjší. Gnome a KDE představují desktop zcela na úrovni Windows a možná lepší. Jejich vývojáři věnují čas sladění desítek až stovek komponent, aby vytvořili funkční a vzájemně provázaný, spolupracující celek. Mám zkušenost hlavně s KDE a řekl bych, že se jim to daří. Xfce a MATE jsou menší DE, mají méně „fičur“ a komponent, ale stále dobře použitelné a méně náročné na systémové prostředky, takže člověk nemusí každé 2 roky kupovat nový notebook, který utáhne nejnovější verzi Windows.
Zkušenější uživatelé často volí instalaci samotného window manageru a přidávají ekosystém aplikací dle vlastního výběru z nepřeberného výběru samostatných programů či komponent různých DE. A samozřejmě skriptů obstarávajících potřebné funkce. BareGUI je příkladem takového přístupu.
Není třeba stát se programátorem na plný úvazek, aby to člověk zvládl. Větší hlavolam, o tom není sporu, ale konečný výsledek je uspokojivější, lépe šitý na míru, snadněji upravitelný, protože člověk rozumí, jak je celek poskládaný dohromady. V „konfekčním“ DE přeci jen rozhoduje někdo jiný, kde co má být a jak to má fungovat, i přes jinak velmi bohaté možnosti nastavení.
Doufám, že tato delší odbočka dostatečně objasnila problematiku GUI v unixovském prostředí a nyní se můžeme pustit do práce.
BareGUI
Základní instalace OpenBSD již obsahuje Xorg či přesněji Xenocaru, upravený Xorg, aby vyhovoval bezpečnostním požadavkům OpenBSD. Pokud jsme při instalaci nastavili login manager xenodm(1), systém nás automaticky vyzve k přihlášení do GUI, defaultně fvwm(1). Odtud se můžeme vrhnout do instalace a konfigurace BareGUI.
BareGUI je v podstatě složka obsahující návod, 2 seznamy aplikací a konfigurační soubory, které se kopírují do příslušných adresářů dle instrukcí v návodu. Jednoduché, geniální. Filozofií BareGUI je maximálně využít nástrojů, jež jsou k dispozici v základní instalaci OpenBSD.
Instalace
Nejprve je třeba stáhnout zkomprimovanou složku:
$ ftp -o BareGUI.tar.gz http://www.daemonforums.org/attachment.php?attachmentid=958&d=1592676088
$ tar xzfv BareGUI.tar.gz
Nyní je třeba nainstalovat nutné aplikace. Instalátor programů na OpenBSD, pkg_add(1) umí instalovat dle seznamu uloženého v textovém souboru:
# pkg_add -l BareGUI_pkglist.txt
Následují uživatelské a systémové nastavení.
Základní uživatelská nastavení
Začneme kopírováním konfiguračních souborů. Jedná se o konfiguraci spouštění GUI (soubor .xsession), terminálu (soubor .Xdefaults) a instalovaných programů, které patří do adresáře ~/.config. V dobře uklizeném systému obsahuje tento adresář pokud možno všechny konfigurační soubory aplikací. To ovšem není můj případ. LARBS je v tomto ohledu jiná káva, neboť Luke Smith je muž, jenž bere jarní úklid $HOME vážně.
Soubor .xsession se čte při přihlášení do GUI a nastavuje locale, čili jakým jazykem systém komunikuje, layout klávesnice atd. Nastavení částečného českého locale a přepínání amerického a českého qwerty layoutu se nastaví přidáním řádek:
export LC_CTYPE=cs_CZ.UTF-8 setxkbmap -layout "us,cz" -variant ",qwerty" -option "grp:ctrls_toggle,caps:swapescape"
Dále spouští základní programy, především window manager a uživatelské daemony. Window manager je v našem případě openbox(1) a ten dále spouští panel tint2(1). Oba tvoří páteř našeho desktopu. Openbox je velmi oblíbený jednoduchý window manager, tzn. že umožňuje (sofistikovanou) manipulaci s okny a pasivní menu, což je známá nabídka programů. Pasivní v tom smyslu, že se menu automaticky neaktualizuje při instalaci či odinstalaci programů a je třeba ručně upravit konfigurační soubor XML. Shep jej proto nahradil programem jgmenu(1), který je v tomto ohledu vyspělejší a lépe vyhovuje moderním požadavkům na desktop. Openbox, tint2 i jgmenu mají konfigurační soubory uložené v adresáři ~/.config, o kterém byla řeč výše, a k jejich nastavení se ještě dostaneme.
Systémová nastavení
Moderní desktop vyžaduje dbus neboli message bus, daemon pro interní komunikaci mezi aplikacemi.
# rcctl enable messagebus
Je také možné ručně editovat /etc/rc.conf.local, ale nedoporučuje se to.
Dále je potřeba umožnit uživatelům ve skpině wheel vypnutí a restart systému. To je nutné, abychom mohli používat tlačítka Shutdown a Reboot z menu. K tomu slouží soubor doas.conf, který je třeba nakopírovat do adresáře /etc.
Pokud jsme nepovolili xenodm(1) při instalaci:
# rcctl enable xenodm
Přihlašovací obrazovka a wallpaper
Nyní je vhodná chvíle k nastavení přihlašovací obrazovky. Provede se kopírováním souboru Xresources do adresáře /etc/X11/xenodm. Pozor, soubor už tam je, takže je vhodné ho předtím zazálohovat. Viz README.txt, bod 7. Osobně používám jiné nastavení xenodm(1). Tento bod není z hlediska funkčnosti nutný, jde pouze o estetickou volbu.
Shep má také separátní instrukce jak nastavit wallpaper. Sám jsem se těmito instrukcemi neřídil, protože používám interní program na nastavení wallpaperů od vývojářů OpenBSD. K tomu je třeba nainstalovat balíček openbsd-backgrounds, odkomentovat několik řádek v souboru /etc/X11/xenodm/Xsetup_0 a je hotovo.
Doporučené aplikace
A dostáváme se k shepovu druhému seznamu. Zde má uživatel naprostou svobodu vybrat si skutečně ty aplikace, které chce a potřebuje. Přesně to jsem také udělal. Kdo nemá oblíbené programy nebo neví, co si vybrat, může se s klidným srdcem držet shepova seznamu. Chybu neudělá.
# pkg_add -l BareGUI_recommended_apps.txt
Zmíním jenom, že audiopřehrávač Gimmix se už zřejmě nevyvíjí, takže byl vyřazen z packages OpenBSD. Nahradil jsem ho přehrávačem Deadbeef. Narozdíl od shepa nepoužívám mpd, Music Player Daemon, k němuž byl Gimmix frontendem. Mpd běží jako daemon na pozadí a je k němu potřeba frontend, který mpd ovládá. Kdo chce používat mpd, nechť se podívá na seznam frontendů zde.
Soubory *.desktop
Shepem doporučované aplikace se instalují společně s *.desktop souborem, takže se automaticky objeví v (jg)menu. Starší programy nebo CLI aplikace jako xterm *.desktop soubor nemají. Pro ty shep nachystal vlastní v adresáři desktop_files. Kopírují se do adresáře ~/.local/share/applications pro daného uživatele. Systémově se nacházejí v /usr/local/share/applications.
K čemu vlastně slouží?
Soubor *.desktop (např. xterm.desktop) v rámci desktopu identifikuje program. Obsahuje popis, cestu ke spuštění programu, cestu k ikoně programu a to vše umožňuje desktopovým aplikacím, jakou je výše uvedené jgmenu(1) program rozpoznat, zobrazit, zařadit a případně spouštět. Další takový desktopový program je tint2(1), který se stará o launcher a panel a bude o něm řeč za chvíli. Díky souborům *.desktop také tint2(1) dokáže zobrazit požadované aplikace a spustit je na kliknutí uživatele. Soubory *.desktop jsou součástí projektu freedesktop.org.
Chybějící soubory *.desktop se dají najít na internetu nebo ručně upravit. Musel jsem např. upravit vimb.desktop, protože vimb(1) nemá ikonu. Stáhl jsem z netu starou ikonu Netscape Navigatoru a uložil jako ~/.local/share/icons/hicolor/48x48/apps/vimb.png a /usr/local/share/icons/hicolor/48x48/apps/vimb.png. Do desktopového souboru jsem dopsal název ikony. Toto by měl být kanonický adresář dle specifikací freedesktop.org.
UPDATE 9. 7. 2022: Pokud se ikona neobjevuje, nutno vymazat .cache/jgmenu. Pokud problémy přetrvávají, lze uložit ikonu do /usr/local/share/pixmaps/ a ve vimb.desktop nastavit absolutní cestu k této ikoně.
Nyní lze restartovat počítač a po opětovném přihlášení bychom měli vidět toto:
Tint2
Když nyní víme, k čemu slouží *.desktop soubory, můžeme se pustit do nastavení taskbaru a launcheru. Na obrázku výše vidíme, že všechny ikony spouští terminál. To rozhodně není to pravé ořechové. Také informace v systémovém trayi v pravém horním rohu jsou poněkud chudičké. Zvuk, čas a kalendář tvoří jen zlomek toho, co bych tam rád viděl.
Ikony v dolní části plochy se nazývají launcher (v MacOS se jim prý říká dock). Horní lišta je taskbar. Tam najdeme ikony či tlačítka minimalizovaných programů, tedy „shozených“ na lištu. V pravé části panelu je systémový tray čili systray čili notifikační oblast, kde programy běžící na pozadí komunikují s uživatelem, případně je možné kliknutím vyvolat určité akce, např. zobrazit kalendář.
Taskbar i launcher produkuje prográmek zvaný tint2(1). Je velmi lehký, flexibilní a v kombinaci s openbox(1) se používá často. Jeho úkolem je generovat panely. Může jich být více než jeden. V našem případě jde o 2 panely zvané taskbar a launcher a každý z nich má vlastní konfigurační soubor.
Panel se definuje velikostí a obsahem. Velikost je šířka a výška, panel samozřejmě může být široký přes celou obrazovku. Může být umístěný na kterékoliv hraně plochy. Obsah znamená, co na panelu bude. Tint2 rozeznává různé typy úkolů, které má panel provádět a z nichž se má skládat.
- L znamená Launcher
- T znamená Taskbar
- S znamená Systray
- B ukazuje status baterie
- C ukazuje hodiny
- E znamená Exekutor
- P znamená Push button
Pomocí těchto písmen se dá složit obsah panelu.
Tint2 má také mnoho možností, jak upravit vzhled panelu, ale o tom se dlouze a dopodrobna rozepisuje manuálová stránka tint2(1).
Launcher
Konfiguruje se prostřednictvím souboru ~/.config/tint2/launcher.tint2rc.
Obsahuje pouze L, tedy Launcher a šířka panelu se definuje pomocí velikosti ikon (64 x 64 pixelů) a mezer mezi nimi (8 pixelů), 6 ikon tedy zabírá 424 pixelů. Chceme-li přidat další ikony, je nutné vypočítat novou šířku a změnit v konfiguračním souboru.
Dále je nutné upravit část Launcher, kde je třeba uvést cesty k *.desktop souborům programů, které chceme v launcheru mít.
Následuje restart tint2(1):
pkill -USR1 tint2
A nyní můžeme ověřit, zda úpravy zafungovaly.
Existují i jiné aplikace zastávající funkci docku, např. Plank, které se dají upravovat i přes grafické rozhraní, ale shep v nich zřejmě neviděl přidanou hodnotu a tak zůstal u druhé instance tint2(1) pro launcher. Osobně v tom nevidím problém, konfigurace tint2(1) je poměrně jednoduchá a není důvod měnit launcher nějak zvlášť často. Ale je dobré vědět o alternativách, kdyby bylo puzení čtenářova vnitřního geeka příliš silné.
Taskbar a systray
Horní panel se konfiguruje souborem ~/.config/tint2/tint2rc.
Původní obsah tvořily TPSC, tedy Taskbar, Push button, Systray a Clock. Tlačítko (push button) obsahuje klikací ikonu mráčku na spuštění skriptů na předpověď počasí. Systray obsahuje ikonu zvuku. Tu posílá program tray-app/volume na ovládání hlasitosti, který se spouští při přihlášení a běží na pozadí. Na hodiny lze také kliknout a objeví se kalendář.
Kalendář a skripty na počasí využívají služeb jiného programu, zvaného yad(1). Ten umí zobrazit dialogová okna pro nejrůznější skripty. Takže kliknutím na čas se spustí dialogové okno yad(1) s kalendářem. Kliknutím na obláček se spustí dialogové okno s nabídkou tlačítek spouštějící různé skripty, jež stahují předpovědí počasí z netu.
Potřeboval jsem přidat zobrazení aktuálního připojení wifi, ukazatel stavu baterie a ukazatel layoutu klávesnice, neboť často přepínám mezi českou a americkou klávesnicí.
Wifi
Shep napsal skript na zobrazení informací o aktuálním wifi připojení, který jsem si maličko upravil. Stačilo tedy nadefinovat další Push button, který spustí dialogové okno yad(1) s výstupem shepova skriptu.
Opět jsem tedy využil něco, co napsal a zveřejnil někdo jiný a přizpůsobil to svým potřebám. V tom spočívá kouzlo svobodného softwaru.
Baterie
Měl jsem 2 možnosti:
- tint2(1) sám zjišťuje a zobrazuje stav baterie v různých formátech;
- použít externí program tray-app/battery, který už je stejně nainstalovaný, protože je součástí skupiny programů tray-app.
Zvolil jsem obojí. V nastavení baterie v tint2rc jsem nic neměnil, pouze jsem přidal písmeno B do definice panelu. Díky tomu nyní vidím stav baterie jako text v procentech a zbývající čas do úplného vybití. Hned vedle se zobrazuje ikona baterie, která má několik stavů a graficky zobrazuje to, co ukazuje vedlejší text. Až budu mluvit o nastavení openbox(1), vysvětlím, jak se tray-app/battery spouští.
Dunst (UPDATE 9. 7. 2022)
V ráci BareGUI byl nainstalován libnotify, což umožňuje desktopové notifikace, v tomto případě ohledně baterie, což nemusí být zdaleka jediné využití. Podle nastavení tint2(1) příkaz notify-send "zprava" se spustí notifikace. Z nějakého důvodu to nefunguje přímo. Bylo nutné doinstalovat program dunst(1), což je daemon, který zobrazí požadovanou zprávu.
Daemon se spouští v ~/.config/openbox/autostart, tzn. při přihlášení do GUI. Nastavení vzhledu notifikací je možné v konfiguračním souboru. Ten je třeba zkopírovat:
cp /usr/local/share/dunst/dunstrc ~/.config/dunst/
Možné nastavení zprávy v ~/.config/tint2/tint2rc. Druhá zpráva se zobrazí v červeném rámečku:
notify-send "low battery" # běžná zpráva notify-send -u critical "low battery" # kritická zpráva
Pokud stav přetrvává, notifikace se zobrazuje permanentně. Je možné ji zavřít ručně pomocí ovládání daemona (viz manuálová stránka dunstctl):
dunstctl close
Zatím jsem nepřišel na to, jak takovou přetrvávající zprávu vypnout automaticky.
Layout klávesnice
Přidat indikaci layoutu klávesnice představovalo jistý oříšek. Neznám žádný samostatný program, který by indikoval layout. Protože jsem tento problém zkoumal už dříve, našel jsem na internetu řešení zcela v rámci aplikací základní instalace. Napsal jsem krátký skript, jehož výstupem je „EN“ nebo „CZ“. Skript nereaguje na žádný podnět, takže se musí neustále opakovat v krátkém časovém sledu.
Jak ale dostat výstup skriptu do panelu? Push button není vhodný, neboť stav se musí ukazovat automaticky, nikoliv na základě uživatelské akce (kliknutí). Po prostudování manuálové stránky tint2(1) jsem zjistil, že existuje exekutor E, který umí spustit můj skript každou vteřinu a vypsat výstup do notifikační oblasti.
Výsledná definice panelu tedy vypadá takto: TEBSPPC.
Konfigurujeme Openbox
Konfigurační soubory pro openbox(1) se nacházejí v adresáři ~/.config/openbox/ a kopírovali jsme je tam na začátku. Jsou to:
- autostart, čte se při spuštění openbox(1), takže na změny za běhu se nebere zřetel;
- menu.xml, menu nahradilo jgmenu, takže nehraje roli;
- rc.xml, nejdůležitější, řídí chování oken, klávesnice, myši atd.
O souboru autostart už byla řeč. Spouští aplikace, které chceme mít spuštěné, když openbox(1) naběhne, např. zmíněné prográmky v systrayi: sound, battery a nakonec jsem přidal i eject, který zobrazuje připojené disky. Pokud nepoužíváme openbsd-backgrounds, spouští se zde wallpaper pomocí programu feh(1) a dále kompozitor zodpovědný za obrazové efekty desktopu a samozřejmě tint2. Lze zde spouště i mpd a další programy.
Struktura konfiguračního souboru autostart je jednoduchá, jde v podstatě o seznam spouštěných programů, podobně jako v souboru ~/.xsession, který vlastně dělá stejnou práci. Aby se spustily v požadovaném pořadí, je třeba před každý vložit časovou mezeru pomocí příkazu sleep.
Druhý konfigurační soubor, rc.xml už je komplikovanější. Jak název napovídá, jedná se o XML soubor, jenž nepovažuju za obzvlášť čitelný značkovací jazyk. A také je velmi dlouhý, protože možností, jak ovlivnit chování openbox(1) je mnoho: vzhled, chování oken jako fokus, jejich interakce s myší, práce s více monitory, klávesnice a klávesové zkratky a dokonce tiling. Ano, i tak typický stacking window manager jako openbox(1) dokáže jednoduchý tiling pouhou úpravou konfiguračního souboru.
A právě tiling a přidání klávesových zkratek na spouštění některých souborů jsem měl v úmyslu přidat. Nastavení tilingu jsem našel na internetu a zkopíroval ho do sekce pro klávesnici. Ještě jsem zkontroloval, zda se použité klávesové zkratky netlučou s již existujícími. Úprava a přidání klávesových zkratek je ve stejné sekci.
Tento tiling funguje podobně jako u Windows. Pomocí klávesových zkratek lze oknem vyplnit levou nebo pravou polovinu plochy s následně horní či dolní čtvrtinu předešlé poloviny. Není to samozřejmě pravý tiling, ale pro mé účely stačí.
Následující oddíly už nejsou součástí instalace shepova BareGUI.
Terminál a shell
Na začátku tohoto předlouhého textu bylo řečeno, že ~/.Xdefaults má co do činění s terminálem. Přesněji nastavuje vzhled a funkcionalitu xterm(1). Na „trhu“ je spousta fancy terminálů, tak proč používat tento prastarý terminál, který ani neumí průhlednost? Zaprvé, tento terminál je součástí základní instalace a tím pádem má člověk jistotu, že mu byla věnována náležitá pozornost, pokud jde o bezpečnost a správnost zdrojového kódu. A zadruhé, průhlednost sice skutečně nemá, ale jinak jde o poměrně schopný terminál, pokud se mu věnuje náležitá péče.
Terminál je pouhé rozhraní, které posílá uživatelské vstupy do programu zvaného shell (a vrací výstupy shellu). Je mnoho typů shellů, patrně nejznámější je Linuxový bash(1). Na OpenBSD je defaultní kornshell neboli ksh(1).
Zde je několik typů, jak si ulehčit život v terminálu, a zbytek nechám na čtenářově samostudiu.
- V souboru ~/.Xdefaults umožňuje nastavení vkládání textu zkopírovaného v externích aplikacích i interně. Dvojklikem lze označit webový odkaz a následně ho otevřít v externím prohlížeči dle vlastního výběru a hromada dalších věcí, viz Hidden gems of xterm;
- Soubor ~/.kshrc je konfigurační soubor ksh(1). Systémový konfig v /etc lze nakopírovat do $HOME a upravit dle vlastního vkusu. Používám ho k nastavení aliasů, zkratek zastupujících dlouhé, komplexní příkazy. Na internetu jsem našel skript kshbookmark, kde lze definovat často navštěvované složky a následně se do nich přemisťovat pomocí několika málo úderů kláves. Takový inteligentnější alias, hodí se zejména pokud se z aliasů do oblíbených složek stal dlouhý seznam.
- Soubor ~/.ksh_completions. Zmíněný bash(1) automaticky instaluje bash_completions. Dobrá zpráva je, že daleko menší ksh(1) umí totéž. Jen si to musíme nastavit sami, viz Tab completion in OpenBSD’s ksh.
Připojení externích disků a USB klíčenek
Jelikož nepřítel (=Widle) číhá všude, je nutné s ním komunikovat. Proto formátuju většinu svých externích zařízení na NTFS. Je nutné nainstalovat ntfs-3g(8), aby bylo možné NTFS připojit.
Standardní unixovské připojení externích úložišť jako adresáře kdesi ve stromu adresářů pod vrchním adresářem, tzv. rootem pomocí příkazů mount a umount je samozřejmě možné a použitelné.
Nicméně OpenBSD umožňuje i automatickou detekci připojených zařízení a případně i jejich připojení pomocí, jak jinak, skriptu. Detekci zajišťuje daemon hotplud(8), připojení a odpojení skripty attach a detach umístěné v adresáři /etc/hotplug/. Je však třeba tyto skripty nejprve napsat! Naštěstí příklady skriptů uvádějí manuálové stránky. Skript attach se spustí při připojení disku, detach při jeho odpojení.
Připojení mobilního telefonu
Aplikace simple-mtpfs(1) se stará o připojení mobilních telefonů. Jedná se o poměrně dlouhý příkaz, takže:
alias simple_mtpfs='doas /usr/local/bin/simple-mtpfs --device 1 $HOME/android -o uid=1000 -o gid=1000 -o allow_other'
Nesmíme zapomenout povolit na telefonu přenos souborů.
Bohužel toto nefunguje na mém novém Androidu 11. Na starém androidu fungovalo bez problému. Zdá se, že simple-mtpfs(1) potřebuje upgrade. Alespoň na OpenBSD, neboť na Artixu běží bez problému. Snad k němu dojde brzy.
Zatím lze využít sftp(1) a to je na delší povídání.
Konečně závěr
Opět jsem se snažil vysvětlit v rámci možností nejen co kde nastavit, ale i jak daná věc funguje. Doufám, že to bude někomu k užitku.
EOF