aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.config/btop/btop.conf6
-rw-r--r--.config/fontconfig/fonts.conf40
-rw-r--r--.config/foot/foot.ini21
-rw-r--r--.config/hypr/hyprland.conf224
-rw-r--r--.config/lazygit/config.yml11
-rw-r--r--.config/lazygit/themes.gitconfig667
-rw-r--r--.config/mako/config38
-rw-r--r--.config/mimeapps.list20
-rw-r--r--.config/mpd/mpd.conf19
-rw-r--r--.config/mpv/input.conf5
-rw-r--r--.config/mpv/mpv.conf8
-rw-r--r--.config/newsboat/config55
-rw-r--r--.config/nvim/init.lua20
-rw-r--r--.config/nvim/lua/plugins.lua2
-rw-r--r--.config/nvim/lua/plugins/completions.lua42
-rw-r--r--.config/nvim/lua/plugins/gitsigns.lua6
-rw-r--r--.config/nvim/lua/plugins/gruvbox.lua9
-rw-r--r--.config/nvim/lua/plugins/lsp-config.lua67
-rw-r--r--.config/nvim/lua/plugins/lualine.lua8
-rw-r--r--.config/nvim/lua/plugins/neotree.lua15
-rw-r--r--.config/nvim/lua/plugins/telescope.lua25
-rw-r--r--.config/nvim/lua/plugins/treesitter.lua31
-rw-r--r--.config/nvim/lua/plugins/trim.lua6
-rw-r--r--.config/nvim/lua/vim-options.lua10
-rw-r--r--.config/paru/paru.conf2
-rw-r--r--.config/pipewire/pipewire.conf.d/user-session.conf4
-rw-r--r--.config/python/pythonrc2
-rw-r--r--.config/rmpc/config.ron218
-rwxr-xr-x.config/rmpc/scripts/statusbar2
-rw-r--r--.config/rmpc/themes/def.ron238
-rw-r--r--.config/shell/aliasrc75
-rw-r--r--.config/shell/bm-dirs14
-rw-r--r--.config/shell/bm-files16
-rw-r--r--.config/shell/inputrc19
-rw-r--r--.config/shell/profile94
-rw-r--r--.config/swayidle/config3
-rw-r--r--.config/swayimg/config38
-rwxr-xr-x.config/swayimg/key-handler35
-rw-r--r--.config/swaylock/config1
-rw-r--r--.config/user-dirs.dirs1
l---------.config/waybar/config1
-rw-r--r--.config/waybar/config.json223
-rw-r--r--.config/waybar/style.css98
-rw-r--r--.config/wget/wgetrc1
-rw-r--r--.config/yazi/yazi.toml2
-rw-r--r--.config/zathura/zathurarc25
-rw-r--r--.config/zsh/.zshrc87
-rwxr-xr-x.local/bin/bookmarks142
-rwxr-xr-x.local/bin/booksplit43
-rwxr-xr-x.local/bin/cleanup2
-rwxr-xr-x.local/bin/compiler42
-rw-r--r--.local/bin/cron/README.md14
-rwxr-xr-x.local/bin/cron/checkup17
-rwxr-xr-x.local/bin/cron/crontog6
-rwxr-xr-x.local/bin/cron/mailup9
-rwxr-xr-x.local/bin/cron/newsup18
-rwxr-xr-x.local/bin/define37
-rwxr-xr-x.local/bin/displayselect82
-rwxr-xr-x.local/bin/dmenuhandler21
-rwxr-xr-x.local/bin/dmenumountcifs19
-rwxr-xr-x.local/bin/dmenupass6
-rwxr-xr-x.local/bin/dmenurecord113
-rwxr-xr-x.local/bin/dmenuunicode20
-rwxr-xr-x.local/bin/doas_askpass47
-rwxr-xr-x.local/bin/getbib71
-rwxr-xr-x.local/bin/getcomproot9
-rwxr-xr-x.local/bin/ifinstalled12
-rwxr-xr-x.local/bin/linkhandler32
-rwxr-xr-x.local/bin/maimpick37
-rwxr-xr-x.local/bin/mounter114
-rwxr-xr-x.local/bin/noisereduce81
-rwxr-xr-x.local/bin/opout13
-rwxr-xr-x.local/bin/pauseallmpv10
-rwxr-xr-x.local/bin/peertubetorrent9
-rwxr-xr-x.local/bin/podentr7
-rwxr-xr-x.local/bin/portal5
-rwxr-xr-x.local/bin/qndl12
-rwxr-xr-x.local/bin/queueandnotify14
-rwxr-xr-x.local/bin/randombg21
-rwxr-xr-x.local/bin/rssadd18
-rwxr-xr-x.local/bin/rssget115
-rwxr-xr-x.local/bin/sd22
-rwxr-xr-x.local/bin/setbg42
-rwxr-xr-x.local/bin/shortcuts59
-rwxr-xr-x.local/bin/singboxwrap32
-rwxr-xr-x.local/bin/slider126
-rwxr-xr-x.local/bin/start-pipewire5
-rwxr-xr-x.local/bin/statusbar/sb-battery37
-rwxr-xr-x.local/bin/statusbar/sb-brightness23
-rwxr-xr-x.local/bin/statusbar/sb-clock29
-rwxr-xr-x.local/bin/statusbar/sb-cpu12
-rwxr-xr-x.local/bin/statusbar/sb-cpubars44
-rwxr-xr-x.local/bin/statusbar/sb-disk23
-rwxr-xr-x.local/bin/statusbar/sb-doppler241
-rwxr-xr-x.local/bin/statusbar/sb-forecast65
-rwxr-xr-x.local/bin/statusbar/sb-internet35
-rwxr-xr-x.local/bin/statusbar/sb-iplocate15
-rwxr-xr-x.local/bin/statusbar/sb-kbselect26
-rwxr-xr-x.local/bin/statusbar/sb-mailbox24
-rwxr-xr-x.local/bin/statusbar/sb-memory12
-rwxr-xr-x.local/bin/statusbar/sb-microphone39
-rwxr-xr-x.local/bin/statusbar/sb-moonphase37
-rwxr-xr-x.local/bin/statusbar/sb-mpdup8
-rwxr-xr-x.local/bin/statusbar/sb-music19
-rwxr-xr-x.local/bin/statusbar/sb-nettraf28
-rwxr-xr-x.local/bin/statusbar/sb-news17
-rwxr-xr-x.local/bin/statusbar/sb-pacpackages29
-rwxr-xr-x.local/bin/statusbar/sb-popupgrade9
-rwxr-xr-x.local/bin/statusbar/sb-price59
-rwxr-xr-x.local/bin/statusbar/sb-tasks20
-rwxr-xr-x.local/bin/statusbar/sb-ticker49
-rwxr-xr-x.local/bin/statusbar/sb-torrent27
-rwxr-xr-x.local/bin/statusbar/sb-volume39
-rwxr-xr-x.local/bin/sysact36
-rwxr-xr-x.local/bin/tag49
-rwxr-xr-x.local/bin/td-toggle12
-rwxr-xr-x.local/bin/torwrap7
-rwxr-xr-x.local/bin/transadd9
-rwxr-xr-x.local/bin/unix26
-rwxr-xr-x.local/bin/unmounter25
-rwxr-xr-x.local/bin/weath25
-rwxr-xr-x.local/bin/xdg-terminal-exec3
-rw-r--r--.local/share/applications/file.desktop4
-rw-r--r--.local/share/applications/img.desktop4
-rw-r--r--.local/share/applications/mail.desktop4
-rw-r--r--.local/share/applications/pdf.desktop4
-rw-r--r--.local/share/applications/rss.desktop4
-rw-r--r--.local/share/applications/text.desktop4
-rw-r--r--.local/share/applications/torrent.desktop4
-rw-r--r--.local/share/applications/video.desktop4
l---------.local/share/bg1
-rw-r--r--.local/share/larbs/chars/emoji1630
-rw-r--r--.local/share/larbs/chars/font-awesome1456
-rw-r--r--.local/share/larbs/emoji1630
-rw-r--r--.local/share/thiemeyer_road_to_samarkand.jpgbin0 -> 403799 bytes
l---------.zprofile1
-rw-r--r--LICENSE674
-rw-r--r--README.md4
-rw-r--r--aurdeps.txt7
-rw-r--r--dependencies.txt117
-rwxr-xr-xrice.sh197
141 files changed, 10965 insertions, 0 deletions
diff --git a/.config/btop/btop.conf b/.config/btop/btop.conf
new file mode 100644
index 0000000..f54e85d
--- /dev/null
+++ b/.config/btop/btop.conf
@@ -0,0 +1,6 @@
+color_theme = "/usr/share/btop/themes/gruvbox_dark.theme"
+theme_background = False
+vim_keys = True
+rounded_corners = False
+shown_boxes = "cpu net proc mem gpu0"
+proc_sorting = "memory"
diff --git a/.config/fontconfig/fonts.conf b/.config/fontconfig/fonts.conf
new file mode 100644
index 0000000..7eb3159
--- /dev/null
+++ b/.config/fontconfig/fonts.conf
@@ -0,0 +1,40 @@
+<?xml version='1.0'?>
+<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
+<fontconfig>
+ <alias>
+ <family>serif</family>
+ <prefer>
+ <family>LiterationSerif Nerd Font Propo</family>
+ <family>Noto Color Emoji</family>
+ <family>FontAwesome</family>
+ <family>SymbolsNerdFont</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>sans-serif</family>
+ <prefer>
+ <family>LiterationSans Nerd Font Propo</family>
+ <family>Noto Color Emoji</family>
+ <family>FontAwesome</family>
+ <family>SymbolsNerdFont</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>sans</family>
+ <prefer>
+ <family>LiterationSans Nerd Font Propo</family>
+ <family>Noto Color Emoji</family>
+ <family>FontAwesome</family>
+ <family>SymbolsNerdFont</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>monospace</family>
+ <prefer>
+ <family>LiterationMono Nerd Font Propo</family>
+ <family>Noto Color Emoji</family>
+ <family>FontAwesome</family>
+ <family>SymbolsNerdFont</family>
+ </prefer>
+ </alias>
+</fontconfig>
diff --git a/.config/foot/foot.ini b/.config/foot/foot.ini
new file mode 100644
index 0000000..1f17ff0
--- /dev/null
+++ b/.config/foot/foot.ini
@@ -0,0 +1,21 @@
+include=/usr/share/foot/themes/gruvbox-dark
+font=monospace:size=14
+font-size-adjustment=3
+# dpi-aware=true
+
+[cursor]
+# style=beam
+
+[colors]
+alpha = 0.9
+
+[key-bindings]
+clipboard-copy=Mod1+c
+clipboard-paste=Mod1+v
+scrollback-up-line=Mod1+k
+scrollback-down-line=Mod1+j
+font-increase=Mod1+Shift+k
+font-decrease=Mod1+Shift+j
+font-reset=Mod1+0
+show-urls-launch=Mod1+l
+show-urls-copy=Mod1+y
diff --git a/.config/hypr/hyprland.conf b/.config/hypr/hyprland.conf
new file mode 100644
index 0000000..c381f97
--- /dev/null
+++ b/.config/hypr/hyprland.conf
@@ -0,0 +1,224 @@
+monitor = DP-3, 3840x2160@165, 0x0, 1.5, bitdepth, 10
+monitor = DP-2, 2560x1440@165, -2560x0, 1
+
+$terminal = footclient
+$menu = mew-run
+
+exec-once = dbus-update-activation-environment --all
+exec-once = start-pipewire
+exec-once = mpd
+exec-once = waybar
+exec-once = mako
+exec-once = singboxwrap
+exec-once = sleep 0.1 && randombg
+exec-once = gpg-agent --daemon
+exec-once = gnome-keyring-daemon --start --components=secrets
+
+env = XCURSOR_SIZE,24
+env = HYPRCURSOR_SIZE,24
+env = GBM_BACKEND,nvidia-drm
+env = GTK_THEME,Gruvbox-Material-Dark
+
+# ecosystem {
+# enforce_permissions = 1
+# }
+
+# permission = /usr/(bin|local/bin)/grim, screencopy, allow
+# permission = /usr/(lib|libexec|lib64)/xdg-desktop-portal-hyprland, screencopy, allow
+# permission = /usr/(bin|local/bin)/hyprpm, plugin, allow
+
+general {
+ gaps_in = 5, 10, 10, 5
+ gaps_out = 20, 10, 10, 20
+ border_size = 3
+ col.active_border = rgb(005577)
+ col.inactive_border = rgba(595959aa)
+ resize_on_border = false
+ allow_tearing = false
+ layout = dwindle
+}
+
+decoration {
+ rounding = 0
+ rounding_power = 2
+ active_opacity = 1.0
+ inactive_opacity = 1.0
+
+ shadow {
+ enabled = false
+ }
+
+ blur {
+ enabled = false
+ }
+}
+
+animations {
+ enabled = false
+}
+
+dwindle {
+ pseudotile = true
+ preserve_split = true
+}
+
+master {
+ new_status = master
+}
+
+misc {
+ force_default_wallpaper = 0
+ disable_hyprland_logo = true
+ enable_swallow = 1
+ swallow_regex = ^(footclient)$
+}
+
+experimental {
+ xx_color_management_v4 = true
+}
+
+xwayland {
+ enabled = true
+ force_zero_scaling = true
+}
+
+ecosystem {
+ no_update_news = true
+}
+
+cursor {
+ default_monitor = DP-3
+}
+
+input {
+ kb_layout = us,ru
+ kb_variant =
+ kb_model =
+ kb_options = caps:escape #,grp:alt_shift_toggle
+ kb_rules =
+
+ follow_mouse = 1
+
+ sensitivity = 0 # -1.0 - 1.0, 0 means no modification.
+ force_no_accel = 1
+ repeat_rate = 45
+ repeat_delay = 300
+
+ touchpad {
+ natural_scroll = false
+ }
+}
+
+gestures {
+ workspace_swipe = false
+}
+
+$mainMod = SUPER
+bind = $mainMod, Return, exec, $terminal
+bind = $mainMod, Q, killactive,
+bind = $mainMod, W, exec, firefox
+bind = $mainMod, R, exec, $terminal -e yazi
+bind = $mainMod SHIFT, D, exec, tessen
+bind = $mainMod, V, togglefloating,
+bind = $mainMod, D, exec, $menu
+bind = $mainMod, P, exec, mpc toggle
+bind = $mainMod, Grave, exec, bookmarks
+bind = $mainMod SHIFT, J, togglesplit, # dwindle
+bind = $mainMod, F, fullscreen,
+bind = $mainMod SHIFT, Return, swapnext
+bind = , Print, exec, grim pic-full-$(date '+%y%m%d-%H%M-%S').png
+bind = SHIFT, Print, exec, maimpick
+bind = $mainMod, Print, exec, dmenurecord
+bind = $mainMod SHIFT, Print, exec, dmenurecord kill
+bind = $mainMod, E, exec, $terminal neomutt; pkill -RTMIN+12 waybar
+bind = $mainMod SHIFT, N, exec, $terminal newsboat; pkill -RTMIN+6 waybar
+bind = $mainMod SHIFT, R, exec, $terminal -e btop
+bind = $mainMod, M, exec, $terminal -e rmpc
+bind =,XF86AudioPlay, exec, mpc toggle
+bind =,XF86AudioPrev, exec, mpc prev
+bind = $mainMod, comma, exec, mpc prev
+bind = $mainMod, period, exec, mpc next
+bind = $mainMod SHIFT, comma, exec, mpc seek 0%
+bind = $mainMod SHIFT, period, exec, mpc repeat
+bind =,XF86AudioNext, exec, mpc next
+bind = $mainMod, bracketleft, exec, mpc seek -10
+bind = $mainMod SHIFT, bracketleft, exec, mpc seek -60
+bind = $mainMod, bracketright, exec, mpc seek +10
+bind = $mainMod SHIFT, bracketright, exec, mpc seek +60
+bind =,mouse:276, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle && pkill -RTMIN+23 waybar
+bind = $mainMod, minus, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-; pkill -RTMIN+10 waybar
+bind = $mainMod SHIFT, minus, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 15%-; pkill -RTMIN+10 waybar
+bind = $mainMod, equal, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+; pkill -RTMIN+10 waybar
+bind = $mainMod SHIFT, equal, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 15%+; pkill -RTMIN+10 waybar
+bind = $mainMod SHIFT, M, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle; pkill -RTMIN+10 waybar
+
+bind = $mainMod, F1, exec, singboxwrap menu
+bind = $mainMod, F4, exec, $terminal -e pulsemixer; pkill -RTMIN+10 waybar; pkill -RTMIN+23 waybar
+bind = $mainMod, F6, exec, torwrap
+bind = $mainMod, F7, exec, td-toggle
+bind = $mainMod, F8, exec, mailup
+bind = $mainMod, F9, exec, mounter
+bind = $mainMod, F10, exec, unmounter
+
+bind = $mainMod SHIFT, Q, exec, sysact
+
+bind = $mainMod, L, resizeactive, 100 0
+bind = $mainMod, H, resizeactive, -100 0
+
+bind = $mainMod, J, cyclenext, prev
+bind = $mainMod, K, cyclenext
+
+bind = $mainMod, 1, workspace, 1
+bind = $mainMod, 2, workspace, 2
+bind = $mainMod, 3, workspace, 3
+bind = $mainMod, 4, workspace, 4
+bind = $mainMod, 5, workspace, 5
+bind = $mainMod, 6, workspace, 6
+bind = $mainMod, 7, workspace, 7
+bind = $mainMod, 8, workspace, 8
+bind = $mainMod, 9, workspace, 9
+bind = $mainMod, 0, workspace, 10
+
+bind = $mainMod SHIFT, 1, movetoworkspace, 1
+bind = $mainMod SHIFT, 2, movetoworkspace, 2
+bind = $mainMod SHIFT, 3, movetoworkspace, 3
+bind = $mainMod SHIFT, 4, movetoworkspace, 4
+bind = $mainMod SHIFT, 5, movetoworkspace, 5
+bind = $mainMod SHIFT, 6, movetoworkspace, 6
+bind = $mainMod SHIFT, 7, movetoworkspace, 7
+bind = $mainMod SHIFT, 8, movetoworkspace, 8
+bind = $mainMod SHIFT, 9, movetoworkspace, 9
+bind = $mainMod SHIFT, 0, movetoworkspace, 10
+
+bind = $mainMod, mouse_down, workspace, e+1
+bind = $mainMod, mouse_up, workspace, e-1
+
+bindm = $mainMod, mouse:272, movewindow
+bindm = $mainMod, mouse:273, resizewindow
+
+bindel = ,XF86AudioRaiseVolume, exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+
+bindel = ,XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
+bindel = ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
+bindel = ,XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle
+bindel = ,XF86MonBrightnessUp, exec, brightnessctl s 10%+
+bindel = ,XF86MonBrightnessDown, exec, brightnessctl s 10%-
+
+windowrule = suppressevent maximize, class:.*
+windowrule = nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0
+
+workspace = 1, monitor:DP-2
+workspace = 2, monitor:DP-2
+workspace = 3, monitor:DP-3
+workspace = 4, monitor:DP-3
+
+windowrulev2 = float, class:^(steam)$, title:^(Friends List)$
+windowrulev2 = float, class:^(steam)$, title:^(Steam - News)$
+windowrulev2 = float, class:^(steam)$, title:.* - Chat$
+windowrulev2 = float, class:^(steam)$, title:.* Settings$
+windowrulev2 = float, class:^(steam)$, title:.* - event started$
+windowrulev2 = float, class:^(steam)$, title:.* CD key$
+windowrulev2 = float, class:^(steam)$, title:^(Steam - Self Updater)$
+windowrulev2 = float, class:^(steam)$, title:^(Screenshot Uploader)$
+windowrulev2 = float, class:^(steam)$, title:^(Recordings & Screenshots)$
+windowrulev2 = float, class:^(steam)$, title:^(Steam Guard - Computer Authorization Required)$
+windowrulev2 = float, title:^(Steam Keyboard)$
diff --git a/.config/lazygit/config.yml b/.config/lazygit/config.yml
new file mode 100644
index 0000000..380f458
--- /dev/null
+++ b/.config/lazygit/config.yml
@@ -0,0 +1,11 @@
+git:
+ paging:
+ colorArg: always
+ pager: delta --dark --paging=never
+keybinding:
+ universal:
+ nextBlock-alt2: <disabled>
+ nextTab: <tab>
+ prevTab: <disabled>
+gui:
+ border: single
diff --git a/.config/lazygit/themes.gitconfig b/.config/lazygit/themes.gitconfig
new file mode 100644
index 0000000..d1b65e6
--- /dev/null
+++ b/.config/lazygit/themes.gitconfig
@@ -0,0 +1,667 @@
+# To use these themes, first include this file in your own gitconfig file:
+#
+# [include]
+# path = PATH/TO/delta/themes.gitconfig
+#
+# Then, in your own gitconfig file, activate the chosen theme, e.g.
+#
+# [delta]
+# features = kingfisher
+#
+# Please add your own themes to this file, and open a PR.
+#
+# Instructions:
+#
+# 1. The name of the theme must be the name of some sort of wild organism:
+# mammal, bird, plant, mollusk -- whatever. It can be in any language.
+#
+# 2. Use `delta --show-config` to list all the style settings that are active in
+# your current delta environment, but only include settings in your theme
+# that are essential to its appearance.
+#
+# 3. Include either `dark = true` or `light = true` according to whether it is
+# designed for a light or dark terminal background. (This marks a feature as
+# a "theme", causing it to be picked up by `delta --show-themes`).
+#
+# 4. Feel free to include a comment line indicating who is the author of the
+# theme. E.g. a link to your github user page.
+
+[delta "colibri"]
+ # author: https://github.com/pablospe
+ # Based on woolly-mammoth: https://github.com/Kr1ss-XD.
+ commit-decoration-style = 130 box
+ dark = true
+ file-decoration-style = "#606018" overline
+ file-added-label = [●]
+ file-copied-label = [C]
+ file-modified-label = [+]
+ file-removed-label = [⛌]
+ file-renamed-label = [→]
+ file-style = 232 bold 184
+ hunk-header-style = syntax bold italic 237
+ line-numbers = true
+ line-numbers-left-format = "{nm:>1}┊"
+ line-numbers-left-style = red
+ line-numbers-minus-style = red bold
+ line-numbers-plus-style = green bold
+ line-numbers-right-format = " {np:>1}┊"
+ line-numbers-right-style = green
+ line-numbers-zero-style = "#545474" italic
+ minus-emph-style = normal "#80002a"
+ minus-style = normal "#5e0000"
+ plus-emph-style = syntax bold "#007e5e"
+ plus-style = syntax "#003500"
+ syntax-theme = OneHalfDark
+ whitespace-error-style = "#80002a" reverse
+ zero-style = syntax
+ blame-format = "{author:<18} ({commit:>7}) ┊{timestamp:^16}┊ "
+
+[delta "collared-trogon"]
+ # author: https://github.com/clnoll
+ commit-decoration-style = bold box ul
+ dark = true
+ file-decoration-style = none
+ file-style = omit
+ hunk-header-decoration-style = "#022b45" box ul
+ hunk-header-file-style = "#999999"
+ hunk-header-line-number-style = bold "#003300"
+ hunk-header-style = file line-number syntax
+ line-numbers = true
+ line-numbers-left-style = "#022b45"
+ line-numbers-minus-style = "#80002a"
+ line-numbers-plus-style = "#003300"
+ line-numbers-right-style = "#022b45"
+ line-numbers-zero-style = "#999999"
+ minus-emph-style = normal "#80002a"
+ minus-style = normal "#330011"
+ plus-emph-style = syntax "#003300"
+ plus-style = syntax "#001a00"
+ syntax-theme = Nord
+
+[delta "coracias-caudatus"]
+ # author: https://github.com/clnoll
+ commit-decoration-style = ol "#7536ff"
+ commit-style = "#200078"
+ file-decoration-style = none
+ file-style = omit
+ hunk-header-decoration-style = "#cfd6ff" ul
+ hunk-header-file-style = "#858dff"
+ hunk-header-line-number-style = "#7536ff"
+ hunk-header-style = file line-number syntax
+ light = true
+ line-numbers = true
+ line-numbers-left-format = "{nm:>4} ."
+ line-numbers-left-style = "#e3ab02"
+ line-numbers-minus-style = "#ff38b6"
+ line-numbers-plus-style = "#00e0c2"
+ line-numbers-right-format = "{np:>4} "
+ line-numbers-right-style = white
+ line-numbers-zero-style = "#cccccc"
+ minus-emph-style = bold "#ff3838" "#ffe3f7"
+ minus-style = "#ff0080"
+ plus-emph-style = "#008a81" bold "#00ffbf"
+ plus-style = syntax "#cffff3"
+ syntax-theme = GitHub
+
+[delta "hoopoe"]
+ # author: https://github.com/dandavison
+ light = true
+ pink = "#ffe0e0"
+ dark-pink = "#ffc0c0"
+ green = "#d0ffd0"
+ dark-green = "#a0efa0"
+ dark-green-2 = "#067a00"
+ minus-style = normal hoopoe.pink
+ minus-emph-style = normal hoopoe.dark-pink
+ minus-non-emph-style = minus-style
+ plus-style = syntax hoopoe.green
+ plus-emph-style = syntax hoopoe.dark-green
+ plus-non-emph-style = plus-style
+ minus-empty-line-marker-style = minus-style
+ plus-empty-line-marker-style = plus-style
+ commit-decoration-style = blue ol
+ commit-style = raw
+ file-style = omit
+ hunk-header-decoration-style = blue box
+ hunk-header-file-style = red
+ hunk-header-line-number-style = hoopoe.dark-green-2
+ hunk-header-style = file line-number syntax
+ syntax-theme = GitHub
+ zero-style = syntax
+
+[delta "tangara-chilensis"]
+ # author: https://github.com/clnoll
+ commit-decoration-style = bold box ul "#34fd50"
+ dark = true
+ file-decoration-style = none
+ file-style = omit
+ hunk-header-decoration-style = "#00b494" box ul
+ hunk-header-file-style = "#999999"
+ hunk-header-line-number-style = bold "#03a4ff"
+ hunk-header-style = file line-number syntax
+ line-numbers = true
+ line-numbers-left-style = black
+ line-numbers-minus-style = "#B10036"
+ line-numbers-plus-style = "#03a4ff"
+ line-numbers-right-style = black
+ line-numbers-zero-style = "#999999"
+ minus-emph-style = normal "#de004e"
+ minus-style = normal "#990017"
+ plus-emph-style = syntax "#03a4ff"
+ plus-style = syntax "#450eff"
+ side-by-side = true
+ syntax-theme = Vibrant Sunburst
+
+[delta "villsau"]
+ # author: https://github.com/torarnv
+ dark = true
+ file-style = omit
+ hunk-header-decoration-style = omit
+ hunk-header-file-style = magenta
+ hunk-header-line-number-style = dim magenta
+ hunk-header-style = file line-number syntax
+ line-numbers = false
+ minus-emph-style = bold red 52
+ minus-empty-line-marker-style = normal "#3f0001"
+ minus-non-emph-style = dim red
+ minus-style = bold red
+ plus-emph-style = bold green 22
+ plus-empty-line-marker-style = normal "#002800"
+ plus-non-emph-style = dim green
+ plus-style = bold green
+ syntax-theme = OneHalfDark
+ whitespace-error-style = reverse red
+ zero-style = dim syntax
+
+[delta "woolly-mammoth"]
+ # author: https://github.com/Kr1ss-XD
+ commit-decoration-style = 232 130 box
+ commit-style = 232 bold italic 130
+ dark = true
+ file-added-label = [+]
+ file-copied-label = [C]
+ file-decoration-style = "#606018" overline
+ file-modified-label = [M]
+ file-removed-label = [-]
+ file-renamed-label = [R]
+ file-style = 232 bold 184
+ hunk-header-decoration-style = none
+ hunk-header-style = syntax bold italic 237
+ line-numbers = true
+ line-numbers-left-format = "{nm:>1}┊"
+ line-numbers-left-style = red
+ line-numbers-minus-style = red italic black
+ line-numbers-plus-style = green italic black
+ line-numbers-right-format = "{np:>1}┊"
+ line-numbers-right-style = green
+ line-numbers-zero-style = "#545474" italic
+ minus-emph-style = syntax bold "#780000"
+ minus-style = syntax "#400000"
+ plus-emph-style = syntax bold "#007800"
+ plus-style = syntax "#004000"
+ syntax-theme = Vibrant Sunburst
+ whitespace-error-style = "#280050" reverse
+ zero-style = syntax
+ blame-format = "{author:<18} ({commit:>7}) ┊{timestamp:^16}┊ "
+ blame-palette = "#101010 #200020 #002800 #000028 #202000 #280000 #002020 #002800 #202020"
+
+[delta "calochortus-lyallii"]
+ # author: https://github.com/manojkarthick
+ commit-decoration-style = none
+ dark = true
+ file-added-label = [+]
+ file-copied-label = [C]
+ file-decoration-style = none
+ file-modified-label = [M]
+ file-removed-label = [-]
+ file-renamed-label = [R]
+ file-style = 232 bold 184
+ hunk-header-decoration-style = none
+ hunk-header-file-style = "#999999"
+ hunk-header-line-number-style = bold "#03a4ff"
+ hunk-header-style = file line-number syntax
+ line-numbers = true
+ line-numbers-left-style = black
+ line-numbers-minus-style = "#B10036"
+ line-numbers-plus-style = "#03a4ff"
+ line-numbers-right-style = black
+ line-numbers-zero-style = "#999999"
+ minus-emph-style = syntax bold "#780000"
+ minus-style = syntax "#400000"
+ plus-emph-style = syntax bold "#007800"
+ plus-style = syntax "#004000"
+ whitespace-error-style = "#280050" reverse
+ zero-style = syntax
+ syntax-theme = Nord
+
+[delta "mantis-shrimp"]
+ #author: https://github.com/2kabhishek
+ dark = true
+ side-by-side = true
+ keep-plus-minus-markers = true
+ hyperlinks = true
+ file-added-label = [+]
+ file-copied-label = [==]
+ file-modified-label = [*]
+ file-removed-label = [-]
+ file-renamed-label = [->]
+ file-style = omit
+ zero-style = syntax
+ syntax-theme = Monokai Extended
+ commit-decoration-style ="#11ce16" box
+ commit-style = "#ffd21a" bold italic
+ hunk-header-decoration-style = "#1688f0" box ul
+ hunk-header-file-style = "#c63bee" ul bold
+ hunk-header-line-number-style = "#ffd21a" box bold
+ hunk-header-style = file line-number syntax bold italic
+ line-numbers = true
+ line-numbers-left-format = "{nm:>1}|"
+ line-numbers-left-style = "#1688f0"
+ line-numbers-minus-style = "#ff0051" bold
+ line-numbers-plus-style = "#03e57f" bold
+ line-numbers-right-format = "{np:>1}|"
+ line-numbers-right-style = "#1688f0"
+ line-numbers-zero-style = "#aaaaaa" italic
+ minus-emph-style = syntax bold "#b80000"
+ minus-style = syntax "#5d001e"
+ plus-emph-style = syntax bold "#007800"
+ plus-style = syntax "#004433"
+ whitespace-error-style = "#280050"
+
+[delta "mantis-shrimp-lite"]
+ #author: https://github.com/2kabhishek
+ dark = true
+ side-by-side = true
+ keep-plus-minus-markers = true
+ file-added-label = [+]
+ file-copied-label = [==]
+ file-modified-label = [*]
+ file-removed-label = [-]
+ file-renamed-label = [->]
+ file-style = omit
+ zero-style = syntax
+ syntax-theme = Monokai Extended
+ commit-decoration-style = green box
+ commit-style = yellow bold italic
+ hunk-header-decoration-style = blue box ul
+ hunk-header-file-style = purple ul bold
+ hunk-header-line-number-style = yellow box bold
+ hunk-header-style = file line-number syntax bold italic
+ line-numbers = true
+ line-numbers-left-format = "{nm:>1}|"
+ line-numbers-left-style = blue
+ line-numbers-minus-style = red bold
+ line-numbers-plus-style = green bold
+ line-numbers-right-format = "{np:>1}|"
+ line-numbers-right-style = blue
+ line-numbers-zero-style = white italic
+ minus-emph-style = syntax bold red
+ plus-emph-style = syntax bold green
+ whitespace-error-style = purple bold
+
+[delta "zebra-dark"]
+ minus-style = syntax "#330f0f"
+ minus-emph-style = syntax "#4f1917"
+ plus-style = syntax "#0e2f19"
+ plus-emph-style = syntax "#174525"
+ map-styles = \
+ bold purple => syntax "#330f29", \
+ bold blue => syntax "#271344", \
+ bold cyan => syntax "#0d3531", \
+ bold yellow => syntax "#222f14"
+ zero-style = syntax
+ whitespace-error-style = "#aaaaaa"
+
+[delta "zebra-light"]
+ minus-style = syntax "#fbdada"
+ minus-emph-style = syntax "#f6b6b6"
+ plus-style = syntax "#d6ffd6"
+ plus-emph-style = syntax "#adffad"
+ map-styles = \
+ bold purple => syntax "#feecf7", \
+ bold blue => syntax "#e5dff6", \
+ bold cyan => syntax "#d8fdf6", \
+ bold yellow => syntax "#f4ffe0"
+ zero-style = syntax
+ whitespace-error-style = "#aaaaaa"
+
+[delta "chameleon"]
+ #author: https://github.com/AirOnSkin
+ dark = true
+ line-numbers = true
+ side-by-side = true
+ keep-plus-minus-markers = false
+ syntax-theme = Nord
+ file-style = "#434C5E" bold
+ file-decoration-style = "#434C5E" ul
+ file-added-label = [+]
+ file-copied-label = [==]
+ file-modified-label = [*]
+ file-removed-label = [-]
+ file-renamed-label = [->]
+ hunk-header-style = omit
+ line-numbers-left-format = " {nm:>3} │"
+ line-numbers-left-style = red
+ line-numbers-right-format = " {np:>3} │"
+ line-numbers-right-style = green
+ line-numbers-minus-style = red italic black
+ line-numbers-plus-style = green italic black
+ line-numbers-zero-style = "#434C5E" italic
+ minus-style = bold red
+ minus-emph-style = bold "#202020" "#FF5555"
+ minus-non-emph-style = bold
+ plus-style = bold green
+ plus-emph-style = bold "#202020" "#50FA7B"
+ plus-non-emph-style = bold
+ zero-style = syntax
+ blame-code-style = syntax
+ blame-format = "{author:<18} ({commit:>9}) {timestamp:^16}"
+ blame-palette = "#2E3440" "#3B4252" "#434C5E" "#4C566A"
+ merge-conflict-begin-symbol = ~
+ merge-conflict-end-symbol = ~
+ merge-conflict-ours-diff-header-style = "#F1FA8C" bold
+ merge-conflict-ours-diff-header-decoration-style = "#434C5E" box
+ merge-conflict-theirs-diff-header-style = "#F1FA8C" bold
+ merge-conflict-theirs-diff-header-decoration-style = "#434C5E" box
+
+[delta "gruvmax-fang"]
+ # author: https://github.com/maxfangx
+ # General appearance
+ dark = true
+ syntax-theme = gruvbox-dark
+ # File
+ file-style = "#FFFFFF" bold
+ file-added-label = [+]
+ file-copied-label = [==]
+ file-modified-label = [*]
+ file-removed-label = [-]
+ file-renamed-label = [->]
+ file-decoration-style = "#434C5E" ul
+ file-decoration-style = "#84786A" ul
+ # No hunk headers
+ hunk-header-style = omit
+ # Line numbers
+ line-numbers = true
+ line-numbers-left-style = "#84786A"
+ line-numbers-right-style = "#84786A"
+ line-numbers-minus-style = "#A02A11"
+ line-numbers-plus-style = "#479B36"
+ line-numbers-zero-style = "#84786A"
+ line-numbers-left-format = " {nm:>3} │"
+ line-numbers-right-format = " {np:>3} │"
+ # Diff contents
+ inline-hint-style = syntax
+ minus-style = syntax "#330011"
+ minus-emph-style = syntax "#80002a"
+ minus-non-emph-style = syntax auto
+ plus-style = syntax "#001a00"
+ plus-emph-style = syntax "#003300"
+ plus-non-emph-style = syntax auto
+ whitespace-error-style = "#FB4934" reverse
+ # Commit hash
+ commit-decoration-style = normal box
+ commit-style = "#ffffff" bold
+ # Blame
+ blame-code-style = syntax
+ blame-format = "{author:>18} ({commit:>8}) {timestamp:<13} "
+ blame-palette = "#000000" "#1d2021" "#282828" "#3c3836"
+ # Merge conflicts
+ merge-conflict-begin-symbol = ⌃
+ merge-conflict-end-symbol = ⌄
+ merge-conflict-ours-diff-header-style = "#FABD2F" bold
+ merge-conflict-theirs-diff-header-style = "#FABD2F" bold overline
+ merge-conflict-ours-diff-header-decoration-style = ''
+ merge-conflict-theirs-diff-header-decoration-style = ''
+
+[delta "discord"]
+ commit-style = omit
+ file-style = 34 ul
+ file-decoration-style = none
+ hunk-header-style = omit
+ minus-style = 31
+ minus-non-emph-style = 31
+ minus-emph-style = 40
+ minus-empty-line-marker-style = 31
+ zero-style = 30
+ plus-style = 32
+ plus-non-emph-style = 32
+ plus-emph-style = 40
+ grep-file-style = 34
+ grep-line-number-style = 34
+ whitespace-error-style = 41
+ blame-code-style = omit
+ true-color = never
+ file-modified-label = changed:
+ right-arrow = >
+ hyperlinks = false
+ keep-plus-minus-markers = true
+ diff-stat-align-width = 10
+ syntax-theme = none
+ width = variable
+
+[delta "mellow-barbet"]
+ # author: https://github.com/kvrohit
+ # To configure terminal colors see https://github.com/kvrohit/mellow.nvim#terminals
+ dark = true
+ syntax-theme = base16
+ line-numbers = true
+ side-by-side = true
+ file-style = brightwhite
+ file-decoration-style = none
+ file-added-label = [+]
+ file-copied-label = [==]
+ file-modified-label = [*]
+ file-removed-label = [-]
+ file-renamed-label = [->]
+ hunk-header-decoration-style = "#3e3e43" box ul
+ plus-style = brightgreen black
+ plus-emph-style = black green
+ minus-style = brightred black
+ minus-emph-style = black red
+ line-numbers-minus-style = brightred
+ line-numbers-plus-style = brightgreen
+ line-numbers-left-style = "#3e3e43"
+ line-numbers-right-style = "#3e3e43"
+ line-numbers-zero-style = "#57575f"
+ zero-style = syntax
+ whitespace-error-style = black bold
+ blame-code-style = syntax
+ blame-palette = "#161617" "#1b1b1d" "#2a2a2d" "#3e3e43"
+ merge-conflict-begin-symbol = ~
+ merge-conflict-end-symbol = ~
+ merge-conflict-ours-diff-header-style = yellow bold
+ merge-conflict-ours-diff-header-decoration-style = "#3e3e43" box
+ merge-conflict-theirs-diff-header-style = yellow bold
+ merge-conflict-theirs-diff-header-decoration-style = "#3e3e43" box
+
+[delta "arctic-fox"]
+ # author: https://github.com/anthony-halim
+ dark = true
+ syntax-theme = Nord
+ file-added-label = [+]
+ file-copied-label = [==]
+ file-modified-label = [*]
+ file-removed-label = [-]
+ file-renamed-label = [->]
+ file-style = omit
+ hunk-header-decoration-style = "#5E81AC" ul
+ hunk-header-file-style = blue ul bold
+ hunk-header-line-number-style = yellow box bold
+ hunk-header-style = file line-number syntax bold italic
+ plus-style = brightgreen
+ plus-emph-style = black green
+ minus-style = brightred
+ minus-emph-style = black red
+ line-numbers = true
+ line-numbers-minus-style = brightred
+ line-numbers-plus-style = brightgreen
+ line-numbers-left-style = "#5E81AC"
+ line-numbers-right-style = "#5E81AC"
+ line-numbers-zero-style = "#4C566A"
+ zero-style = syntax
+ whitespace-error-style = black bold
+ blame-code-style = syntax
+ blame-format = "{author:<18} {commit:<6} {timestamp:<15}"
+ blame-palette = "#2E3440" "#3B4252" "#434C5E"
+ merge-conflict-begin-symbol = ~
+ merge-conflict-end-symbol = ~
+ merge-conflict-ours-diff-header-style = yellow bold
+ merge-conflict-ours-diff-header-decoration-style = "#5E81AC" box
+ merge-conflict-theirs-diff-header-style = yellow bold
+ merge-conflict-theirs-diff-header-decoration-style = "#5E81AC" box
+
+[delta "corvus"]
+ # author: https://github.com/evilwaveforms
+ dark = true
+ commit-style = "#949494"
+ file-style = omit
+ syntax-theme = none
+ hunk-header-decoration-style = "#949494" ul
+ hunk-header-file-style = "#949494"
+ hunk-header-style = "#949494"
+ line-numbers = true
+ line-numbers-left-style = "#949494"
+ line-numbers-right-style = "#949494"
+ line-numbers-left-format = "{nm:>2}|"
+ line-numbers-right-format = "{np:>3} "
+ line-numbers-plus-style = "#54c047"
+ line-numbers-minus-style = bold "#591102"
+ plus-style = "#54c047"
+ plus-emph-style = bold "#54c047"
+ plus-non-emph-style = dim "#54c047"
+ minus-style = normal "#591102"
+ minus-emph-style = normal "#591102"
+ minus-non-emph-style = bold "#591102"
+ blame-code-style = omit
+ blame-format = "{author:<18} {commit:<6} {timestamp:<15}"
+ blame-palette = "#000000" "#343434"
+ zero-style = dim
+
+[delta "platypus"]
+ # Author: https://github.com/sarpuser
+ dark = true
+ side-by-side = true
+ true-color = always
+ file-added-label = [+]
+ file-copied-label = [==]
+ file-modified-label = [M]
+ file-removed-label = [-]
+ file-renamed-label = [->]
+ file-style = "#ff9b00" ul bold
+ file-decoration-style = "#ea00ff" box ul
+ zero-style = syntax
+ syntax-theme = Solarized (dark)
+ commit-decoration-style ="#ea00ff" ul
+ hunk-header-decoration-style = omit
+ hunk-header-file-style = "#ff9b00" ul bold
+ hunk-header-line-number-style = "#ffd21a" bold
+ hunk-header-style = line-number syntax bold italic
+ line-numbers = true
+ line-numbers-left-format = "{nm:>1}|"
+ line-numbers-left-style = "#ea00ff"
+ line-numbers-minus-style = "#ff0051" bold
+ line-numbers-plus-style = "#1ac71e" bold
+ line-numbers-right-format = "{np:>1}|"
+ line-numbers-right-style = "#ea00ff"
+ line-numbers-zero-style = "#aaaaaa" italic
+ minus-emph-style = syntax bold "#b80000"
+ minus-style = syntax "#5d001e"
+ plus-emph-style = syntax bold "#1a861a"
+ plus-style = syntax "#2a5e37"
+ whitespace-error-style = "#280050"
+ wrap-max-lines = unlimited
+ wrap-right-percent = 1
+
+[delta "weeping-willow"]
+ # See 'mirthful-willow' for light mode version.
+ # Heavily inspired by the themes above. Thank you. <3
+ # author: https://github.com/lvdh
+ # colors: `pastel list`
+ dark = true
+ right-arrow = >
+ syntax-theme = Coldark-Dark
+ # -- git
+ blame-format = " ({commit:>7}) {author:<18} {timestamp:^13} "
+ blame-palette = "normal midnightblue indigo navy darkblue darkslateblue purple rebeccapurple darkviolet"
+ commit-decoration-style = none
+ commit-style = bold black orange
+ # -- grep
+ grep-file-style = olive
+ grep-line-number-style = olive
+ # -- diff
+ keep-plus-minus-markers = true
+ line-numbers = true
+ line-numbers-minus-style = red
+ line-numbers-plus-style = green
+ line-numbers-left-style = gray
+ line-numbers-left-format = "{nm:>1}┊"
+ line-numbers-right-style = gray
+ line-numbers-right-format = "{np:>1}┊"
+ line-numbers-zero-style = gray
+ minus-emph-style = ghostwhite crimson underline
+ minus-empty-line-marker-style = syntax maroon
+ minus-style = syntax darkred
+ plus-emph-style = ghostwhite olivedrab underline
+ plus-empty-line-marker-style = syntax seagreen
+ plus-style = syntax darkgreen
+ whitespace-error-style = black ghostwhite
+ zero-style = syntax
+ # -- decorations
+ file-decoration-style = olive overline
+ file-added-label = [+]
+ file-copied-label = [*]
+ file-modified-label = [~]
+ file-removed-label = [-]
+ file-renamed-label = [>]
+ file-style = orange bold
+ hunk-header-decoration-style = none
+ hunk-header-file-style = olive
+ hunk-header-line-number-style = orange
+ hunk-header-style = file line-number orchid
+
+[delta "mirthful-willow"]
+ # See 'weeping-willow' for dark mode version.
+ # Heavily inspired by the themes above. Thank you. <3
+ # author: https://github.com/lvdh
+ # colors: `pastel list`
+ light = true
+ right-arrow = >
+ syntax-theme = Coldark-Cold
+ # -- git
+ blame-format = " ({commit:>7}) {author:<18} {timestamp:^13} "
+ blame-palette = "powderblue papayawhip thistle skyblue lavender plum paleturquoise lightcyan violet"
+ commit-decoration-style = none
+ commit-style = bold black orange
+ # -- grep
+ grep-file-style = darkgoldenrod
+ grep-line-number-style = darkgoldenrod
+ # -- diff
+ keep-plus-minus-markers = true
+ line-numbers = true
+ line-numbers-minus-style = red
+ line-numbers-plus-style = green
+ line-numbers-left-style = gray
+ line-numbers-left-format = "{nm:>1}┊"
+ line-numbers-right-style = gray
+ line-numbers-right-format = "{np:>1}┊"
+ line-numbers-zero-style = gray
+ minus-emph-style = ghostwhite tomato underline
+ minus-empty-line-marker-style = syntax orangered
+ minus-style = syntax lightpink
+ plus-emph-style = ghostwhite limegreen underline
+ plus-empty-line-marker-style = syntax forestgreen
+ plus-style = syntax lightgreen
+ whitespace-error-style = black ghostwhite
+ zero-style = syntax
+ # -- decorations
+ file-decoration-style = darkgoldenrod overline
+ file-added-label = [+]
+ file-copied-label = [*]
+ file-modified-label = [~]
+ file-removed-label = [-]
+ file-renamed-label = [>]
+ file-style = orange bold
+ hunk-header-decoration-style = none
+ hunk-header-file-style = darkgoldenrod
+ hunk-header-line-number-style = orange
+ hunk-header-style = file line-number darkviolet
diff --git a/.config/mako/config b/.config/mako/config
new file mode 100644
index 0000000..30046c5
--- /dev/null
+++ b/.config/mako/config
@@ -0,0 +1,38 @@
+anchor=top-right
+text-alignment=left
+width=400
+height=400
+max-history=10
+sort=-time
+
+on-button-left=invoke-default-action
+on-button-middle=exec makoctl menu -n $id -- mew -p 'Select action: '
+on-button-right=dismiss
+
+max-visible=10
+font=monospace 14
+max-icon-size=38
+icon-location=left
+margin=6
+padding=3
+format=<b>%s</b>\n%b
+
+background-color=#222222aa
+border-size=3
+border-radius=0
+default-timeout=10000
+
+[urgency=low]
+text-color=#eeeeee
+border-color=#005577
+default-timeout=10000
+
+[urgency=normal]
+text-color=#eeeeee
+border-color=#005577
+default-timeout=10000
+
+[urgency=critical]
+text-color=#eeeeee
+border-color=#005577
+default-timeout=0
diff --git a/.config/mimeapps.list b/.config/mimeapps.list
new file mode 100644
index 0000000..9124fce
--- /dev/null
+++ b/.config/mimeapps.list
@@ -0,0 +1,20 @@
+[Default Applications]
+
+# xdg-open will use these settings to determine how to open filetypes.
+# These .desktop entries can also be seen and changed in ~/.local/share/applications/
+
+text/x-shellscript=text.desktop;
+x-scheme-handler/magnet=torrent.desktop;
+application/x-bittorrent=torrent.desktop;
+x-scheme-handler/mailto=mail.desktop;
+text/plain=text.desktop;
+application/postscript=pdf.desktop;
+application/pdf=pdf.desktop;
+image/png=img.desktop;
+image/jpeg=img.desktop;
+image/gif=img.desktop;
+application/rss+xml=rss.desktop
+video/x-matroska=video.desktop
+video/mp4=video.desktop
+x-scheme-handler/lbry=lbry.desktop
+inode/directory=file.desktop
diff --git a/.config/mpd/mpd.conf b/.config/mpd/mpd.conf
new file mode 100644
index 0000000..5067671
--- /dev/null
+++ b/.config/mpd/mpd.conf
@@ -0,0 +1,19 @@
+music_directory "/mnt/ssd/music"
+playlist_directory "~/.config/mpd/playlists"
+
+auto_update "yes"
+bind_to_address "127.0.0.1"
+restore_paused "yes"
+max_output_buffer_size "16384"
+
+audio_output {
+ type "pipewire"
+ name "PipeWire Sound Server"
+}
+
+audio_output {
+ type "fifo"
+ name "Visualizer feed"
+ path "/tmp/mpd.fifo"
+ format "44100:16:2"
+}
diff --git a/.config/mpv/input.conf b/.config/mpv/input.conf
new file mode 100644
index 0000000..d614b15
--- /dev/null
+++ b/.config/mpv/input.conf
@@ -0,0 +1,5 @@
+l seek 5
+h seek -5
+j seek -60
+k seek 60
+S cycle sub
diff --git a/.config/mpv/mpv.conf b/.config/mpv/mpv.conf
new file mode 100644
index 0000000..1ab6305
--- /dev/null
+++ b/.config/mpv/mpv.conf
@@ -0,0 +1,8 @@
+profile=high-quality
+vo=gpu-next
+gpu-api=vulkan
+gpu-context=waylandvk
+hwdec=auto
+target-colorspace-hint=yes
+alang=eng
+slang=eng
diff --git a/.config/newsboat/config b/.config/newsboat/config
new file mode 100644
index 0000000..3017d96
--- /dev/null
+++ b/.config/newsboat/config
@@ -0,0 +1,55 @@
+#show-read-feeds no
+auto-reload yes
+
+external-url-viewer "urlscan -dc -r 'linkhandler {}'"
+
+bind-key j down
+bind-key k up
+bind-key j next articlelist
+bind-key k prev articlelist
+bind-key J next-feed articlelist
+bind-key K prev-feed articlelist
+bind-key G end
+bind-key g home
+bind-key d pagedown
+bind-key u pageup
+bind-key l open
+bind-key h quit
+bind-key a toggle-article-read
+bind-key n next-unread
+bind-key N prev-unread
+bind-key D pb-download
+bind-key U show-urls
+bind-key x pb-delete
+
+color listnormal cyan default
+color listfocus black yellow standout bold
+color listnormal_unread blue default
+color listfocus_unread yellow default bold
+color info red black bold
+color article white default bold
+
+browser linkhandler
+macro , open-in-browser
+macro t set browser "qndl" ; open-in-browser ; set browser linkhandler
+macro a set browser "tsp yt-dlp --embed-metadata -xic -f bestaudio/best --restrict-filenames" ; open-in-browser ; set browser linkhandler
+macro v set browser "setsid -f mpv" ; open-in-browser ; set browser linkhandler
+macro w set browser "lynx" ; open-in-browser ; set browser linkhandler
+macro d set browser "dmenuhandler" ; open-in-browser ; set browser linkhandler
+macro c set browser "echo %u | wl-copy" ; open-in-browser ; set browser linkhandler
+macro C set browser "youtube-viewer --comments=%u" ; open-in-browser ; set browser linkhandler
+macro p set browser "peertubetorrent %u 480" ; open-in-browser ; set browser linkhandler
+macro P set browser "peertubetorrent %u 1080" ; open-in-browser ; set browser linkhandler
+
+highlight all "---.*---" yellow
+highlight feedlist ".*(0/0))" black
+highlight article "(^Feed:.*|^Title:.*|^Author:.*)" cyan default bold
+highlight article "(^Link:.*|^Date:.*)" default default
+highlight article "https?://[^ ]+" green default
+highlight article "^(Title):.*$" blue default
+highlight article "\\[[0-9][0-9]*\\]" magenta default bold
+highlight article "\\[image\\ [0-9]+\\]" green default bold
+highlight article "\\[embedded flash: [0-9][0-9]*\\]" green default bold
+highlight article ":.*\\(link\\)$" cyan default
+highlight article ":.*\\(image\\)$" blue default
+highlight article ":.*\\(embedded flash\\)$" magenta default
diff --git a/.config/nvim/init.lua b/.config/nvim/init.lua
new file mode 100644
index 0000000..611659e
--- /dev/null
+++ b/.config/nvim/init.lua
@@ -0,0 +1,20 @@
+-- Bootstrap lazy.nvim
+local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
+if not (vim.uv or vim.loop).fs_stat(lazypath) then
+ local lazyrepo = "https://github.com/folke/lazy.nvim.git"
+ local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath })
+ if vim.v.shell_error ~= 0 then
+ vim.api.nvim_echo({
+ { "Failed to clone lazy.nvim:\n", "ErrorMsg" },
+ { out, "WarningMsg" },
+ { "\nPress any key to exit..." },
+ }, true, {})
+ vim.fn.getchar()
+ os.exit(1)
+ end
+end
+vim.opt.rtp:prepend(lazypath)
+
+-- Setup lazy.nvim
+require("vim-options")
+require("lazy").setup("plugins")
diff --git a/.config/nvim/lua/plugins.lua b/.config/nvim/lua/plugins.lua
new file mode 100644
index 0000000..a2b4f84
--- /dev/null
+++ b/.config/nvim/lua/plugins.lua
@@ -0,0 +1,2 @@
+return {}
+
diff --git a/.config/nvim/lua/plugins/completions.lua b/.config/nvim/lua/plugins/completions.lua
new file mode 100644
index 0000000..ff8fd40
--- /dev/null
+++ b/.config/nvim/lua/plugins/completions.lua
@@ -0,0 +1,42 @@
+return {
+ {
+ "hrsh7th/cmp-nvim-lsp"
+ },
+ {
+ "L3MON4D3/LuaSnip",
+ dependencies = {
+ "saadparwaiz1/cmp_luasnip",
+ "rafamadriz/friendly-snippets"
+ }
+ },
+ {
+ "hrsh7th/nvim-cmp",
+ config = function()
+ local cmp = require'cmp'
+ cmp.setup({
+ snippet = {
+ expand = function(args)
+ require('luasnip').lsp_expand(args.body)
+ end,
+ },
+ window = {
+ -- completion = cmp.config.window.bordered(),
+ -- documentation = cmp.config.window.bordered(),
+ },
+ mapping = cmp.mapping.preset.insert({
+ ['<C-b>'] = cmp.mapping.scroll_docs(-4),
+ ['<C-f>'] = cmp.mapping.scroll_docs(4),
+ ['<C-Space>'] = cmp.mapping.complete(),
+ ['<C-e>'] = cmp.mapping.abort(),
+ ['<CR>'] = cmp.mapping.confirm({ select = true }),
+ }),
+ sources = cmp.config.sources({
+ { name = 'nvim_lsp' },
+ { name = 'luasnip' },
+ }, {
+ { name = 'buffer' },
+ })
+ })
+ end
+ }
+}
diff --git a/.config/nvim/lua/plugins/gitsigns.lua b/.config/nvim/lua/plugins/gitsigns.lua
new file mode 100644
index 0000000..8fcc21f
--- /dev/null
+++ b/.config/nvim/lua/plugins/gitsigns.lua
@@ -0,0 +1,6 @@
+return {
+ "lewis6991/gitsigns.nvim",
+ config = function()
+ require("gitsigns").setup()
+ end,
+}
diff --git a/.config/nvim/lua/plugins/gruvbox.lua b/.config/nvim/lua/plugins/gruvbox.lua
new file mode 100644
index 0000000..ecd9b49
--- /dev/null
+++ b/.config/nvim/lua/plugins/gruvbox.lua
@@ -0,0 +1,9 @@
+return {
+ "ellisonleao/gruvbox.nvim",
+ config = function()
+ require("gruvbox").setup({
+ transparent_mode = true,
+ })
+ vim.cmd.colorscheme "gruvbox"
+ end,
+}
diff --git a/.config/nvim/lua/plugins/lsp-config.lua b/.config/nvim/lua/plugins/lsp-config.lua
new file mode 100644
index 0000000..4a55fc8
--- /dev/null
+++ b/.config/nvim/lua/plugins/lsp-config.lua
@@ -0,0 +1,67 @@
+return {
+ {
+ "neovim/nvim-lspconfig",
+ config = function()
+ local capabilities = require('cmp_nvim_lsp').default_capabilities()
+ local lspconfig = require("lspconfig")
+ lspconfig.clangd.setup({
+ capabilities = capabilities,
+ })
+ lspconfig.rust_analyzer.setup({
+ settings = {
+ ["rust-analyzer"] = {
+ cargo = { allFeatures = true },
+ }
+ }
+ })
+ lspconfig.lua_ls.setup({
+ capabilities = capabilities,
+ })
+ lspconfig.html.setup({
+ capabilities = capabilities,
+ })
+ lspconfig.cssls.setup({
+ capabilities = capabilities,
+ })
+ lspconfig.jsonls.setup({
+ capabilities = capabilities,
+ })
+ lspconfig.yamlls.setup({
+ settings = {
+ yaml = {
+ -- schemas = {
+ -- ["https://raw.githubusercontent.com/instrumenta/kubernetes-json-schema/master/v1.17.0-standalone-strict/all.json"] = "/*.k8s.yaml",
+ -- }
+ schemas = {
+ kubernetes = "*.yaml",
+ ["http://json.schemastore.org/github-workflow"] = ".github/workflows/*",
+ ["http://json.schemastore.org/github-action"] = ".github/action.{yml,yaml}",
+ ["http://json.schemastore.org/ansible-stable-2.9"] = "roles/tasks/*.{yml,yaml}",
+ ["http://json.schemastore.org/kustomization"] = "kustomization.{yml,yaml}",
+ ["http://json.schemastore.org/ansible-playbook"] = "*play*.{yml,yaml}",
+ ["http://json.schemastore.org/chart"] = "Chart.{yml,yaml}",
+ -- ["https://json.schemastore.org/gitlab-ci"] = "*gitlab-ci*.{yml,yaml}",
+ ["https://gitlab.com/gitlab-org/gitlab/-/raw/master/app/assets/javascripts/editor/schema/ci.json"] = "*gitlab-ci*.{yml,yaml}",
+ ["https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json"] = "*docker-compose*.{yml,yaml}",
+ ["https://raw.githubusercontent.com/argoproj/argo-workflows/master/api/jsonschema/schema.json"] = "*flow*.{yml,yaml}",
+ },
+ }
+ }
+ })
+ vim.diagnostic.config({
+ virtual_text = {
+ prefix = '',
+ spacing = 4,
+ },
+ signs = true,
+ underline = true,
+ -- update_in_insert = false,
+ severity_sort = true,
+ })
+ vim.keymap.set("n", "K", vim.lsp.buf.hover, {})
+ vim.keymap.set("n", "<leader>gd", vim.lsp.buf.definition, {})
+ vim.keymap.set("n", "<leader>gr", vim.lsp.buf.references, {})
+ vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, {})
+ end
+ }
+}
diff --git a/.config/nvim/lua/plugins/lualine.lua b/.config/nvim/lua/plugins/lualine.lua
new file mode 100644
index 0000000..cebdf54
--- /dev/null
+++ b/.config/nvim/lua/plugins/lualine.lua
@@ -0,0 +1,8 @@
+return {
+ {
+ 'nvim-lualine/lualine.nvim',
+ config = function()
+ require('lualine').setup({})
+ end
+ }
+}
diff --git a/.config/nvim/lua/plugins/neotree.lua b/.config/nvim/lua/plugins/neotree.lua
new file mode 100644
index 0000000..ed60017
--- /dev/null
+++ b/.config/nvim/lua/plugins/neotree.lua
@@ -0,0 +1,15 @@
+return {
+ {
+ "nvim-neo-tree/neo-tree.nvim",
+ branch = "v3.x",
+ dependencies = {
+ "nvim-lua/plenary.nvim",
+ "MunifTanjim/nui.nvim",
+ "nvim-tree/nvim-web-devicons",
+ },
+ lazy = false,
+ config = function()
+ vim.keymap.set('n', '<C-n>', ':Neotree filesystem reveal left<CR>', {})
+ end
+ }
+}
diff --git a/.config/nvim/lua/plugins/telescope.lua b/.config/nvim/lua/plugins/telescope.lua
new file mode 100644
index 0000000..0097f61
--- /dev/null
+++ b/.config/nvim/lua/plugins/telescope.lua
@@ -0,0 +1,25 @@
+return {
+ {
+ 'nvim-telescope/telescope.nvim', tag = '0.1.8',
+ dependencies = { 'nvim-lua/plenary.nvim' },
+ config = function()
+ local builtin = require("telescope.builtin")
+ vim.keymap.set('n', '<C-p>', builtin.find_files, {})
+ vim.keymap.set('n', '<leader>fg', builtin.live_grep, {})
+ end
+ },
+ {
+ 'nvim-telescope/telescope-ui-select.nvim',
+ config = function()
+ require("telescope").setup {
+ extensions = {
+ ["ui-select"] = {
+ require("telescope.themes").get_dropdown {
+ }
+ }
+ }
+ }
+ require("telescope").load_extension("ui-select")
+ end
+ },
+}
diff --git a/.config/nvim/lua/plugins/treesitter.lua b/.config/nvim/lua/plugins/treesitter.lua
new file mode 100644
index 0000000..5b1e85c
--- /dev/null
+++ b/.config/nvim/lua/plugins/treesitter.lua
@@ -0,0 +1,31 @@
+return {
+ {
+ "nvim-treesitter/nvim-treesitter",
+ branch = 'master',
+ lazy = false,
+ build = ":TSUpdate",
+ config = function()
+ local config = require("nvim-treesitter.configs")
+ config.setup({
+ ensure_installed = {
+ "lua",
+ "javascript",
+ "c",
+ "cpp",
+ "go",
+ "markdown",
+ "meson",
+ "make",
+ "cmake",
+ "python",
+ "rust",
+ "yaml",
+ "toml",
+ "ron",
+ },
+ highlight = { enable = true },
+ indent = { enable = true },
+ })
+ end
+ }
+}
diff --git a/.config/nvim/lua/plugins/trim.lua b/.config/nvim/lua/plugins/trim.lua
new file mode 100644
index 0000000..f6fa98f
--- /dev/null
+++ b/.config/nvim/lua/plugins/trim.lua
@@ -0,0 +1,6 @@
+return {
+ "cappyzawa/trim.nvim",
+ config = function()
+ require("trim").setup({})
+ end
+}
diff --git a/.config/nvim/lua/vim-options.lua b/.config/nvim/lua/vim-options.lua
new file mode 100644
index 0000000..3a8b3e1
--- /dev/null
+++ b/.config/nvim/lua/vim-options.lua
@@ -0,0 +1,10 @@
+vim.cmd("set expandtab")
+vim.cmd("set tabstop=2")
+vim.cmd("set softtabstop=2")
+vim.cmd("set shiftwidth=2")
+vim.g.mapleader = " "
+vim.g.maplocalleader = "\\"
+vim.opt.swapfile = false
+vim.wo.number = true
+vim.wo.relativenumber = true
+vim.opt.clipboard = "unnamedplus"
diff --git a/.config/paru/paru.conf b/.config/paru/paru.conf
new file mode 100644
index 0000000..febee6b
--- /dev/null
+++ b/.config/paru/paru.conf
@@ -0,0 +1,2 @@
+[bin]
+Sudo = doas
diff --git a/.config/pipewire/pipewire.conf.d/user-session.conf b/.config/pipewire/pipewire.conf.d/user-session.conf
new file mode 100644
index 0000000..4cbe1d5
--- /dev/null
+++ b/.config/pipewire/pipewire.conf.d/user-session.conf
@@ -0,0 +1,4 @@
+context.exec = [
+ { path = "/usr/bin/wireplumber" args = "" condition = [ { exec.session-manager = null } { exec.session-manager = true } ] }
+ { path = "/usr/bin/pipewire" args = "-c pipewire-pulse.conf" condition = [ { exec.pipewire-pulse = null } { exec.pipewire-pulse = true } ] }
+]
diff --git a/.config/python/pythonrc b/.config/python/pythonrc
new file mode 100644
index 0000000..b32e6b6
--- /dev/null
+++ b/.config/python/pythonrc
@@ -0,0 +1,2 @@
+import readline
+readline.write_history_file = lambda *args: None
diff --git a/.config/rmpc/config.ron b/.config/rmpc/config.ron
new file mode 100644
index 0000000..0818ddb
--- /dev/null
+++ b/.config/rmpc/config.ron
@@ -0,0 +1,218 @@
+#![enable(implicit_some)]
+#![enable(unwrap_newtypes)]
+#![enable(unwrap_variant_newtypes)]
+(
+ address: "127.0.0.1:6600",
+ volume_step: 5,
+ scrolloff: 2,
+ max_fps: 60,
+ wrap_navigation: true,
+ theme: "def",
+ lyrics_dir: "/mnt/ssd/music",
+ on_song_change: ["~/.config/rmpc/scripts/statusbar"],
+ on_resize: None,
+ status_update_interval_ms: 1000,
+ enable_mouse: true,
+ enable_config_hot_reload: true,
+ album_art: (
+ method: Auto,
+ max_size_px: (width: 0, height: 0),
+ vertical_align: Top,
+ horizontal_align: Center,
+ ),
+ keybinds: (
+ global: {
+ ":": CommandMode,
+ ",": VolumeDown,
+ "s": Stop,
+ ".": VolumeUp,
+ "<Tab>": NextTab,
+ "<S-Tab>": PreviousTab,
+ "1": SwitchToTab("Queue"),
+ "2": SwitchToTab("Directories"),
+ "3": SwitchToTab("Artists"),
+ "4": SwitchToTab("Album Artists"),
+ "5": SwitchToTab("Albums"),
+ "6": SwitchToTab("Playlists"),
+ "7": SwitchToTab("Search"),
+ "q": Quit,
+ ">": NextTrack,
+ "p": TogglePause,
+ "<": PreviousTrack,
+ "f": SeekForward,
+ "z": ToggleRepeat,
+ "x": ToggleRandom,
+ "c": ToggleConsume,
+ "v": ToggleSingle,
+ "b": SeekBack,
+ "~": ShowHelp,
+ "I": ShowCurrentSongInfo,
+ "O": ShowOutputs,
+ "P": ShowDecoders,
+ },
+ navigation: {
+ "k": Up,
+ "j": Down,
+ "h": Left,
+ "l": Right,
+ "<Up>": Up,
+ "<Down>": Down,
+ "<Left>": Left,
+ "<Right>": Right,
+ "<C-k>": PaneUp,
+ "<C-j>": PaneDown,
+ "<C-h>": PaneLeft,
+ "<C-l>": PaneRight,
+ "<C-u>": UpHalf,
+ "N": PreviousResult,
+ "a": Add,
+ "A": AddAll,
+ "r": Rename,
+ "n": NextResult,
+ "g": Top,
+ "<Space>": Select,
+ "<C-Space>": InvertSelection,
+ "G": Bottom,
+ "<CR>": Confirm,
+ "i": FocusInput,
+ "J": MoveDown,
+ "<C-d>": DownHalf,
+ "/": EnterSearch,
+ "<C-c>": Close,
+ "<Esc>": Close,
+ "K": MoveUp,
+ "D": Delete,
+ },
+ queue: {
+ "D": DeleteAll,
+ "<CR>": Play,
+ "<C-s>": Save,
+ "a": AddToPlaylist,
+ "d": Delete,
+ "i": ShowInfo,
+ "C": JumpToCurrent,
+ },
+ ),
+ search: (
+ case_sensitive: false,
+ mode: Contains,
+ tags: [
+ (value: "any", label: "Any Tag"),
+ (value: "artist", label: "Artist"),
+ (value: "album", label: "Album"),
+ (value: "albumartist", label: "Album Artist"),
+ (value: "title", label: "Title"),
+ ],
+ ),
+ tabs: [
+ (
+ name: "Queue",
+ border_type: None,
+ pane: Split(
+ direction: Horizontal,
+ panes: [
+ (
+ size: "40%",
+ borders: "RIGHT",
+ pane: Split(
+ direction: Vertical,
+ panes: [
+ (
+ size: "3",
+ pane: Pane(Lyrics),
+ ),
+ (
+ size: "100%",
+ pane: Pane(AlbumArt),
+ )
+ ],
+ ),
+ ),
+ (
+ size: "60%",
+ pane: Pane(Queue),
+ ),
+ ],
+ ),
+ ),
+ (
+ name: "Directories",
+ border_type: None,
+ pane: Pane(Directories),
+ ),
+ (
+ name: "Artists",
+ border_type: None,
+ pane: Pane(Artists),
+ ),
+ (
+ name: "Album Artists",
+ border_type: None,
+ pane: Pane(AlbumArtists),
+ ),
+ (
+ name: "Albums",
+ border_type: None,
+ pane: Pane(Albums),
+ ),
+ (
+ name: "Playlists",
+ border_type: None,
+ pane: Pane(Playlists),
+ ),
+ (
+ name: "Search",
+ border_type: None,
+ pane: Pane(Search),
+ ),
+ (
+ name: "Testing",
+ border_type: Single,
+ pane: Split(
+ direction: Horizontal,
+ panes: [
+ (
+ size: "40%",
+ pane: Pane(Queue),
+ ),
+ (
+ size: "60%",
+ pane: Split(
+ direction: Vertical,
+ panes: [
+ (
+ size: "50%",
+ pane: Pane(Directories),
+ ),
+ (
+ size: "50%",
+ pane: Split(
+ direction: Horizontal,
+ panes: [
+ (
+ size: "60%",
+ pane: Split(
+ direction: Vertical,
+ panes: [
+ (
+ size: "50%",
+ pane: Pane(Albums),
+ ),
+ (
+ size: "50%",
+ pane: Pane(Artists),
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+)
diff --git a/.config/rmpc/scripts/statusbar b/.config/rmpc/scripts/statusbar
new file mode 100755
index 0000000..3508a02
--- /dev/null
+++ b/.config/rmpc/scripts/statusbar
@@ -0,0 +1,2 @@
+#!/bin/sh
+/usr/bin/pkill -RTMIN+11 waybar
diff --git a/.config/rmpc/themes/def.ron b/.config/rmpc/themes/def.ron
new file mode 100644
index 0000000..c4baa27
--- /dev/null
+++ b/.config/rmpc/themes/def.ron
@@ -0,0 +1,238 @@
+#![enable(implicit_some)]
+#![enable(unwrap_newtypes)]
+#![enable(unwrap_variant_newtypes)]
+(
+ draw_borders: false,
+ show_song_table_header: true,
+ background_color: None,
+ default_album_art_path: None,
+ header_background_color: None,
+ modal_background_color: None,
+ modal_backdrop: true,
+ text_color: None,
+ layout: Split(
+ direction: Vertical,
+ panes: [
+ (
+ size: "4",
+ borders: "ALL",
+ pane: Split(
+ direction: Vertical,
+ panes: [
+ (
+ size: "1",
+ direction: Vertical,
+ pane: Split(
+ direction: Horizontal,
+ panes: [
+ (
+ size: "23",
+ pane: Pane(Property(
+ content: [
+ (kind: Text("["), style: (fg: "yellow", modifiers: "Bold")),
+ (kind: Property(Status(StateV2())), style: (fg: "yellow", modifiers: "Bold")),
+ (kind: Text("]"), style: (fg: "yellow", modifiers: "Bold")),
+ ], align: Left,
+ )),
+ ),
+ (
+ size: "100%",
+ borders: "LEFT | RIGHT",
+ pane: Pane(Property(
+ content: [
+ (kind: Property(Song(Filename)), style: (modifiers: "Bold"),
+ default: (kind: Text("No Song"), style: (modifiers: "Bold")))
+ ], align: Center, scroll_speed: 1
+ )),
+ ),
+ (
+ size: "23",
+ pane: Pane(Property(
+ content: [
+ (kind: Property(Widget(Volume)), style: (fg: "blue", modifiers: "Bold"))
+ ], align: Right
+ )),
+ ),
+ ],
+ ),
+ ),
+ (
+ size: "1",
+ direction: Vertical,
+ pane: Split(
+ direction: Horizontal,
+ panes: [
+ (
+ size: "23",
+ pane: Pane(Property(
+ content: [
+ (kind: Property(Status(Elapsed))),
+ (kind: Text(" / ")),
+ (kind: Property(Status(Duration))),
+ (kind: Group([
+ (kind: Text(" (")),
+ (kind: Property(Status(Bitrate))),
+ (kind: Text(" kbps)")),
+ ])),
+ ], align: Left,
+ )),
+ ),
+ (
+ size: "100%",
+ borders: "LEFT | RIGHT",
+ pane: Pane(Property(
+ content: [
+ (kind: Property(Song(Artist)), style: (fg: "yellow", modifiers: "Bold"),
+ default: (kind: Text("Unknown"), style: (fg: "yellow", modifiers: "Bold"))),
+ (kind: Text(" - ")),
+ (kind: Property(Song(Album)), default: (kind: Text("Unknown Album")))
+ ], align: Center, scroll_speed: 2
+ )),
+ ),
+ (
+ size: "23",
+ pane: Pane(Property(content: [
+ (kind: Property(Status(RepeatV2(
+ on_label: " ",
+ off_label: " ",
+ on_style: (fg: "yellow", modifiers: "Bold"),
+ off_style: (fg: "blue", modifiers: "Dim"),
+ )))),
+ (kind: Property(Status(RandomV2(
+ on_label: " ",
+ off_label: " ",
+ on_style: (fg: "yellow", modifiers: "Bold"),
+ off_style: (fg: "blue", modifiers: "Dim"),
+ )))),
+ (kind: Property(Status(SingleV2(
+ on_label: "󰑘 ",
+ off_label: "󰑘 ",
+ oneshot_label: "󰑘 ",
+ on_style: (fg: "yellow", modifiers: "Bold"),
+ off_style: (fg: "blue", modifiers: "Dim"),
+ oneshot_style: (fg: "red", modifiers: "Bold"),
+ )))),
+ (kind: Property(Status(ConsumeV2(
+ on_label: " ",
+ off_label: " ",
+ oneshot_label: "",
+ on_style: (fg: "yellow", modifiers: "Bold"),
+ off_style: (fg: "blue", modifiers: "Dim"),
+ oneshot_style: (fg: "red", modifiers: "Dim"),
+ )))),
+ ], align: Right)),
+ ),
+ ],
+ ),
+ ),
+ ]
+ )
+ ),
+ (
+ size: "3",
+ borders: "ALL",
+ pane: Pane(Tabs),
+ ),
+ (
+ size: "100%",
+ borders: "ALL",
+ background_color: "red",
+ pane: Pane(TabContent),
+ ),
+ (
+ size: "3",
+ borders: "ALL",
+ pane: Split(
+ direction: Horizontal,
+ panes: [
+ (
+ pane: Pane(Property(content: [(kind: Property(Status(StateV2(playing_label: "  ", paused_label: "  ", stopped_label: "  ",
+ playing_style: (fg: "blue"), paused_style: (fg: "green"), stopped_style: (fg: "red")
+ ))))], align: Left)),
+ size: "3",
+ ),
+ (
+ size: "100%",
+ pane: Pane(ProgressBar),
+ ),
+ (
+ size: "13",
+ pane: Pane(Property(
+ content: [
+ (kind: Property(Status(Elapsed))),
+ (kind: Text(" / ")),
+ (kind: Property(Status(Duration))),
+ ], align: Right,
+ )),
+ ),
+ ]
+ ),
+ ),
+ ]
+ ),
+ symbols: (
+ song: "",
+ dir: "",
+ marker: "\u{e0b0}",
+ ellipsis: "…"
+ ),
+ progress_bar: (
+ symbols: ["█", "\u{e0b0}", "█"],
+ track_style: (fg: "#1e2030"),
+ elapsed_style: (fg: "blue"),
+ thumb_style: (fg: "blue", bg: "#1e2030"),
+ ),
+ scrollbar: (
+ symbols: ["│", "█", "▲", "▼"],
+ track_style: (),
+ ends_style: (),
+ thumb_style: (fg: "blue"),
+ ),
+ browser_column_widths: [20, 38, 42],
+ browser_song_format: [
+ (
+ kind: Group([
+ (kind: Property(Track)),
+ (kind: Text(" ")),
+ ])
+ ),
+ (
+ kind: Group([
+ (kind: Property(Artist)),
+ (kind: Text(" - ")),
+ (kind: Property(Title)),
+ ]),
+ default: (kind: Property(Filename))
+ ),
+ ],
+ tab_bar: (
+ active_style: (fg: "black", bg: "blue", modifiers: "Bold"),
+ inactive_style: (),
+ ),
+ highlighted_item_style: (fg: "blue", modifiers: "Bold"),
+ current_item_style: (fg: "black", bg: "blue", modifiers: "Bold"),
+ borders_style: (fg: "blue", modifiers: "Bold"),
+ highlight_border_style: (fg: "red"),
+ song_table_format: [
+ (
+ prop: (kind: Property(Other("albumartist")), default: (kind: Property(Artist), default: (kind: Text("Unknown")))),
+ width: "20%",
+ label: "Artist"
+ ),
+ (
+ prop: (kind: Property(Title), default: (kind: Text("Unknown"))),
+ width: "35%",
+ ),
+ (
+ prop: (kind: Property(Album), default: (kind: Text("Unknown Album"))),
+ width: "45%",
+ ),
+ (
+ prop: (kind: Property(Duration),default: (kind: Text("-"))),
+ width: "5",
+ alignment: Right,
+ label: "Len"
+ ),
+ ],
+ header: (rows: []),
+)
diff --git a/.config/shell/aliasrc b/.config/shell/aliasrc
new file mode 100644
index 0000000..f875a05
--- /dev/null
+++ b/.config/shell/aliasrc
@@ -0,0 +1,75 @@
+#!/bin/sh
+
+# Use neovim for vim if present.
+[ -x "$(command -v nvim)" ] && alias vim="nvim" vimdiff="nvim -d"
+
+[ -f "$MBSYNCRC" ] && alias mbsync="mbsync -c $MBSYNCRC"
+
+# doas not required for some system commands
+for command in mount umount dinitctl pacman updatedb su shutdown poweroff reboot ; do
+ alias $command="doas $command"
+done; unset command
+
+se() {
+ choice="$(fd . --base-directory=$HOME/.local/bin -t f --min-depth=1 | fzf)"
+ [ -f "$HOME/.local/bin/$choice" ] && $EDITOR "$HOME/.local/bin/$choice"
+}
+
+# Verbosity and settings that you pretty much just always are going to want.
+alias \
+ cp="cp -iv" \
+ mv="mv -iv" \
+ rm="rm -vI" \
+ bc="bc -ql" \
+ rsync="rsync -vrPlu" \
+ mkd="mkdir -pv" \
+ yt="yt-dlp --embed-metadata -i" \
+ yta="yt -x -f bestaudio/best" \
+ ytt="yt --skip-download --write-thumbnail" \
+ ffmpeg="ffmpeg -hide_banner"
+
+# Colorize commands when possible.
+alias \
+ ll="eza -lh --group-directories-first --color=auto --color-scale=all --color-scale-mode=fixed --icons --no-quotes --smart-group -s size --total-size --no-user --no-permissions" \
+ ls="eza --group-directories-first --color=auto --icons --no-quotes -s name" \
+ lsf="eza -f --group-directories-first --color=auto --icons --no-quotes -s name" \
+ lsd="eza -D --group-directories-first --color=auto --icons --no-quotes -s name" \
+ lst="eza -lh --group-directories-first --color=auto --color-scale --icons --no-quotes --smart-group -s time --total-size --no-user --no-permissions" \
+ cat="bat -P" \
+ ccat="highlight --out-format=ansi" \
+ ip="ip -color=auto"
+
+# These common commands are just too long! Abbreviate them.
+alias \
+ cl="clear" \
+ ka="killall" \
+ trem="transmission-remote" \
+ YT="youtube-viewer" \
+ sdn="shutdown -h now" \
+ e="$EDITOR" \
+ v="$EDITOR" \
+ p="paru" \
+ z="zathura" \
+ lg="lazygit" \
+ sx="swayimg" \
+ md="monerod --prune-blockchain --fast-block-sync 1 --data-dir /mnt/ssd/monero/bitmonero" \
+ fetch="fastfetch" \
+ de="doasedit"
+
+# Git related
+alias \
+ g="git" \
+ gs="git status --short" \
+ gd="git diff" \
+ ga="git add" \
+ gc="git commit" \
+ gp="git push" \
+ gu="git pull" \
+ gl="git log" \
+ gb="git branch" \
+ gi="git init" \
+ gcl="git clone"
+
+alias \
+ magit="nvim -c MagitOnly" \
+ ref="shortcuts >/dev/null; source ${XDG_CONFIG_HOME:-$HOME/.config}/shell/shortcutrc ; source ${XDG_CONFIG_HOME:-$HOME/.config}/shell/shortcutenvrc ; source ${XDG_CONFIG_HOME:-$HOME/.config}/shell/zshnameddirrc"
diff --git a/.config/shell/bm-dirs b/.config/shell/bm-dirs
new file mode 100644
index 0000000..3ab0b0d
--- /dev/null
+++ b/.config/shell/bm-dirs
@@ -0,0 +1,14 @@
+# You can add comments to these files with #
+cac ${XDG_CACHE_HOME:-$HOME/.cache}
+cf ${XDG_CONFIG_HOME:-$HOME/.config}
+D ${XDG_DOWNLOAD_DIR:-$HOME/Downloads}
+d ${XDG_DOCUMENTS_DIR:-$HOME/Documents}
+dt ${XDG_DATA_HOME:-$HOME/.local/share}
+rr /mnt/ssd/projects
+h $HOME
+m ${XDG_MUSIC_DIR:-$HOME/Music}
+mn /mnt
+pp ${XDG_PICTURES_DIR:-$HOME/Pictures}
+sc $HOME/.local/bin
+src $HOME/.local/src
+vv ${XDG_VIDEOS_DIR:-$HOME/Videos}
diff --git a/.config/shell/bm-files b/.config/shell/bm-files
new file mode 100644
index 0000000..7d7ef0d
--- /dev/null
+++ b/.config/shell/bm-files
@@ -0,0 +1,16 @@
+# These files automatically update when edited/saved in vim:
+
+# keys filename description
+bf ${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-files # This file, a list of bookmarked files
+bd ${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-dirs # A list of bookmarked directories similar to this file
+
+# These do not update automatically, but on the next new instance of a program:
+
+cfv ${XDG_CONFIG_HOME:-$HOME/.config}/nvim/init.vim # vim/neovim config
+cfz $ZDOTDIR/.zshrc # zsh (shell) config
+cfa ${XDG_CONFIG_HOME:-$HOME/.config}/shell/aliasrc # aliases used by zsh (and potentially other shells)
+cfp ${XDG_CONFIG_HOME:-$HOME/.config}/shell/profile # profile file for login settings for zsh
+cfm ${XDG_CONFIG_HOME:-$HOME/.config}/mutt/muttrc # mutt (email client) config
+cfn ${XDG_CONFIG_HOME:-$HOME/.config}/newsboat/config # newsboat (RSS reader)
+cfu ${XDG_CONFIG_HOME:-$HOME/.config}/newsboat/urls # RSS urls for newsboat
+cfmc ${XDG_CONFIG_HOME:-$HOME/.config}/rmpc/config.ron # rmpc (music player) config
diff --git a/.config/shell/inputrc b/.config/shell/inputrc
new file mode 100644
index 0000000..f9b94dd
--- /dev/null
+++ b/.config/shell/inputrc
@@ -0,0 +1,19 @@
+$include /etc/inputrc
+set editing-mode vi
+$if mode=vi
+
+set show-mode-in-prompt on
+set vi-ins-mode-string \1\e[6 q\2
+set vi-cmd-mode-string \1\e[2 q\2
+
+set keymap vi-command
+# these are for vi-command mode
+Control-l: clear-screen
+Control-a: beginning-of-line
+
+set keymap vi-insert
+# these are for vi-insert mode
+Control-l: clear-screen
+Control-a: beginning-of-line
+
+$endif
diff --git a/.config/shell/profile b/.config/shell/profile
new file mode 100644
index 0000000..6234bba
--- /dev/null
+++ b/.config/shell/profile
@@ -0,0 +1,94 @@
+#!/bin/sh
+# shellcheck disable=SC2155
+
+# Profile file, runs on login. Environmental variables are set here.
+
+# Add all directories in `~/.local/bin` to $PATH
+export PATH="$PATH:$(find ~/.local/bin -type d | paste -sd ':' -)"
+
+unsetopt PROMPT_SP 2>/dev/null
+
+# Default programs:
+export EDITOR="nvim"
+export MANPAGER='nvim +Man!'
+export TERMINAL="footclient"
+export TERMINAL_PROG="footclient"
+export BROWSER="firefox"
+
+unset SSH_AGENT_PID
+if [ "${gnupg_SSH_AUTH_SOCK_by:-0}" -ne $$ ]; then
+ export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
+fi
+
+# Change the default crypto/weather monitor sites.
+# export CRYPTOURL="rate.sx"
+# export WTTRURL="wttr.in"
+
+# ~/ Clean-up:
+export XDG_CONFIG_HOME="$HOME/.config"
+export XDG_DATA_HOME="$HOME/.local/share"
+export XDG_CACHE_HOME="$HOME/.cache"
+export XDG_STATE_HOME="$HOME/.local/state"
+export XDG_MUSIC_DIR="/mnt/ssd/music"
+export NOTMUCH_CONFIG="$XDG_CONFIG_HOME/notmuch-config"
+export WGETRC="$XDG_CONFIG_HOME/wget/wgetrc"
+export INPUTRC="$XDG_CONFIG_HOME/shell/inputrc"
+export ZDOTDIR="$XDG_CONFIG_HOME/zsh"
+#export GNUPGHOME="$XDG_DATA_HOME/gnupg"
+export WINEPREFIX="$XDG_DATA_HOME/wineprefixes/default"
+export KODI_DATA="$XDG_DATA_HOME/kodi"
+export PASSWORD_STORE_DIR="$XDG_DATA_HOME/password-store"
+export TMUX_TMPDIR="$XDG_RUNTIME_DIR"
+export ANDROID_SDK_HOME="$XDG_CONFIG_HOME/android"
+export CARGO_HOME="$XDG_DATA_HOME/cargo"
+export GOPATH="$XDG_DATA_HOME/go"
+export GOMODCACHE="$XDG_CACHE_HOME/go/mod"
+export ANSIBLE_CONFIG="$XDG_CONFIG_HOME/ansible/ansible.cfg"
+export UNISON="$XDG_DATA_HOME/unison"
+export HISTFILE="$XDG_DATA_HOME/history"
+export MBSYNCRC="$XDG_CONFIG_HOME/mbsync/config"
+export ELECTRUMDIR="$XDG_DATA_HOME/electrum"
+export PYTHONSTARTUP="$XDG_CONFIG_HOME/python/pythonrc"
+export SQLITE_HISTORY="$XDG_DATA_HOME/sqlite_history"
+export NPM_CONFIG_USERCONFIG="$XDG_CONFIG_HOME/npm/npmrc"
+export CUDA_CACHE_PATH="$XDG_CACHE_HOME/nv"
+export KUBECONFIG="$XDG_CONFIG_HOME/kube/config"
+export KUBECACHEDIR="$XDG_CACHE_HOME/kube"
+export DOCKER_CONFIG="$XDG_CONFIG_HOME/docker"
+export PASSWORD_STORE_CLIP_TIME=5
+
+# Other program settings:
+export DICS="/usr/share/stardict/dic/"
+export DOAS_ASKPASS="$HOME/.local/bin/dmenupass"
+export LESS="R"
+export LESS_TERMCAP_mb="$(printf '%b' '')"
+export LESS_TERMCAP_md="$(printf '%b' '')"
+export LESS_TERMCAP_me="$(printf '%b' '')"
+export LESS_TERMCAP_so="$(printf '%b' '')"
+export LESS_TERMCAP_se="$(printf '%b' '')"
+export LESS_TERMCAP_us="$(printf '%b' '')"
+export LESS_TERMCAP_ue="$(printf '%b' '')"
+export LESSOPEN="| /usr/bin/highlight -O ansi %s 2>/dev/null"
+export QT_QPA_PLATFORMTHEME="gtk3" # Have QT use gtk3 theme.
+export MOZ_USE_XINPUT2=1 # Mozilla smooth scrolling/touchpads.
+export AWT_TOOLKIT="MToolkit wmname LG3D" # May have to install wmname
+export _JAVA_AWT_WM_NONREPARENTING=1 # Fix for Java applications in dwm
+export LIBVA_DRIVER_NAME=nvidia
+export __GLX_VENDOR_LIBRARY_NAME=nvidia
+export MOZ_DISABLE_RDD_SANDBOX=1 # For HW in Firefox on nvidia gpu
+export ELECTRON_OZONE_PLATFORM_HINT=auto # Electron fix
+export QT_WAYLAND_DISABLE_WINDOWDECORATION=1 # Disables decorations for QT applications
+export FZF_DEFAULT_OPTS=\
+"--layout=reverse --height 40% \
+--color=fg:#e5e9f0,bg:-1,hl:#81a1c1 \
+--color=fg+:#e5e9f0,bg+:#3b4252,hl+:#81a1c1 \
+--color=info:#eacb8a,prompt:#bf6069,pointer:#b48dac \
+--color=marker:#a3be8b,spinner:#b48dac,header:#a3be8b"
+export YT_X_FZF_OPTS="$FZF_DEFAULT_OPTS"
+export ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="fg=#767676"
+export BAT_THEME="gruvbox-dark"
+
+[ ! -f "$XDG_CONFIG_HOME/shell/shortcutrc" ] && setsid -f shortcuts >/dev/null 2>&1
+
+# Start graphical server on user's current tty if not already running.
+[ "$(tty)" = "/dev/tty1" ] && ! pidof -s Hyprland >/dev/null 2>&1 && exec dbus-run-session Hyprland
diff --git a/.config/swayidle/config b/.config/swayidle/config
new file mode 100644
index 0000000..3d33378
--- /dev/null
+++ b/.config/swayidle/config
@@ -0,0 +1,3 @@
+timeout 300 'swaylock -f'
+timeout 330 'swaymsg "output * dpms off"' resume 'swaymsg "output * dpms on"'
+before-sleep 'swaylock -f'
diff --git a/.config/swayimg/config b/.config/swayimg/config
new file mode 100644
index 0000000..e2892a3
--- /dev/null
+++ b/.config/swayimg/config
@@ -0,0 +1,38 @@
+[general]
+compositor = no
+[viewer]
+window = #000000
+scale = fit
+[gallery]
+window = #000000
+[list]
+all = yes
+[keys.viewer]
+h = step_left
+j = step_down
+k = step_up
+l = step_right
+n = next_file
+p = prev_file
+w = zoom fit
+g = first_file
+Shift+g = last_file
+Ctrl+x = exec ~/.config/swayimg/key-handler "%"
+r = rotate_right
+Shift+r = rotate_left
+Alt+Shift+k = zoom +20
+Alt+Shift+j = zoom -20
+[keys.gallery]
+h = step_left
+j = step_down
+k = step_up
+l = step_right
+g = first_file
+Shift+g = last_file
+[info]
+info_timeout = 0
+[info.viewer]
+top_left = none
+top_right = none
+bottom_left = +name
+bottom_right = +scale,+frame,+index
diff --git a/.config/swayimg/key-handler b/.config/swayimg/key-handler
new file mode 100755
index 0000000..67943a9
--- /dev/null
+++ b/.config/swayimg/key-handler
@@ -0,0 +1,35 @@
+#!/bin/sh
+file=$1
+ [ -z "$selection" ] && selection=$(printf "w - Set as wallpaper\nc - Copy to dir\nm - Move to dir\nr - Rotate 90°\nR - Rotate -90°\nf - Flip horizontal\ny - Copy filename to clipboard\nY - Copy full path to clipboard\nd - Delete\ng - Open in GIMP\ni - Show media info" |
+ mew -i -l 12 -p "Choose action for selected files:")
+ action=$(printf "%s" "$selection" | cut -d'-' -f1 | tr -d ' ')
+ case "$action" in
+ "w") setbg "$file" & ;;
+ "c")
+ [ -z "$destdir" ] && destdir="$(sed "s/#.*$//;/^\s*$/d" ${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-dirs | awk '{print $2}' | mew -l 20 -i -p "Copy file(s) to where?" | sed "s|~|$HOME|g")"
+ [ ! -d "$destdir" ] && notify-send "$destdir is not a directory, cancelled." && exit
+ cp "$file" "$destdir" && notify-send -i "$(readlink -f "$file")" "$file copied to $destdir." &
+ ;;
+ "m")
+ [ -z "$destdir" ] && destdir="$(sed "s/#.*$//;/^\s*$/d" ${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-dirs | awk '{print $2}' | mew -l 20 -i -p "Move file(s) to where?" | sed "s|~|$HOME|g")"
+ [ ! -d "$destdir" ] && notify-send "$destdir is not a directory, cancelled." && exit
+ mv "$file" "$destdir" && notify-send -i "$(readlink -f "$file")" "$file moved to $destdir." &
+ ;;
+ "r")
+ magick "$file" -rotate 90 "$file" ;;
+ "R")
+ magick "$file" -rotate -90 "$file" ;;
+ "f")
+ magick "$file" -flop "$file" ;;
+ "y")
+ printf "%s" "$file" | tr -d '\n' | wl-copy &&
+ notify-send "$file copied to clipboard" & ;;
+ "Y")
+ readlink -f "$file" | tr -d '\n' | wl-copy &&
+ notify-send "$(readlink -f "$file") copied to clipboard" & ;;
+ "d")
+ [ "$(printf "No\\nYes" | mew -i -p "Really delete $file?")" = "Yes" ] && rm "$file" && notify-send "$file deleted." ;;
+ "g") ifinstalled gimp && setsid -f gimp "$file" ;;
+ "i") notify-send "File information" "$(mediainfo "$file" | sed "s/[ ]\+:/:/g;s/: /: <b>/;s/$/<\/b>/" | rg "<b>")" ;;
+ *) notify-send "No keybind for that key" ;;
+ esac
diff --git a/.config/swaylock/config b/.config/swaylock/config
new file mode 100644
index 0000000..501b8d6
--- /dev/null
+++ b/.config/swaylock/config
@@ -0,0 +1 @@
+image=$(fd . /mnt/ssd/papes -t f | shuf -n1)
diff --git a/.config/user-dirs.dirs b/.config/user-dirs.dirs
new file mode 100644
index 0000000..5a28707
--- /dev/null
+++ b/.config/user-dirs.dirs
@@ -0,0 +1 @@
+XDG_DESKTOP_DIR="$HOME/"
diff --git a/.config/waybar/config b/.config/waybar/config
new file mode 120000
index 0000000..0cffcb3
--- /dev/null
+++ b/.config/waybar/config
@@ -0,0 +1 @@
+config.json \ No newline at end of file
diff --git a/.config/waybar/config.json b/.config/waybar/config.json
new file mode 100644
index 0000000..581d763
--- /dev/null
+++ b/.config/waybar/config.json
@@ -0,0 +1,223 @@
+{
+ "layer": "top",
+ "position": "top",
+ "output": "DP-2",
+ "reload_style_on_change": true,
+ "modules-left": [
+ "hyprland/workspaces",
+ "custom/vanity",
+ "hyprland/window"
+ ],
+ "modules-right": [
+ "custom/recording",
+ "custom/tasks",
+ "custom/music",
+ "custom/packages",
+ "custom/news",
+ "custom/torrent",
+ "custom/memory",
+ "custom/forecast",
+ "custom/mailbox",
+ "custom/nettraf",
+ "custom/microphone",
+ "custom/volume",
+ "custom/clock",
+ "custom/internet",
+ "tray"
+ ],
+
+ "hyprland/workspaces": {
+ "disable-scroll": true,
+ "all-outputs": true,
+ "on-click": "activate",
+ "format": "{icon}"
+ },
+
+ "custom/vanity" : {
+ "tooltip": false,
+ "format": "[]="
+ },
+
+ "custom/recording" : {
+ "tooltip": false,
+ "format": "{}",
+ "signal": 9,
+ "exec" : "cat /tmp/recordingicon 2> /dev/null"
+ },
+
+ "custom/tasks" : {
+ "tooltip": false,
+ "format": "{}",
+ "signal": 26,
+ "interval": 10,
+ "exec" : "sb-tasks",
+ "on-click": "BLOCK_BUTTON=1 sb-tasks",
+ "on-click-right": "BLOCK_BUTTON=3 sb-tasks",
+ "on-click-middle": "BLOCK_BUTTON=3 sb-tasks",
+ "on-click-backward": "BLOCK_BUTTON=3 sb-tasks"
+ },
+
+ "custom/music" : {
+ "tooltip": false,
+ "escape": true,
+ "format": "{}",
+ "signal": 11,
+ "exec" : "sb-music",
+ "on-click": "BLOCK_BUTTON=1 sb-music",
+ "on-click-right": "BLOCK_BUTTON=3 sb-music",
+ "on-click-middle": "BLOCK_BUTTON=2 sb-music",
+ "on-scroll-up": "BLOCK_BUTTON=4 sb-music",
+ "on-scroll-down": "BLOCK_BUTTON=5 sb-music",
+ "on-click-backward": "BLOCK_BUTTON=8 sb-music"
+ },
+
+ "custom/packages" : {
+ "tooltip": false,
+ "format": "{}",
+ "signal": 8,
+ "exec" : "sb-pacpackages",
+ "on-click": "BLOCK_BUTTON=1 sb-pacpackages",
+ "on-click-right": "BLOCK_BUTTON=3 sb-pacpackages",
+ "on-click-middle": "BLOCK_BUTTON=2 sb-pacpackages",
+ "on-click-backward": "BLOCK_BUTTON=8 sb-pacpackages"
+ },
+
+ "custom/news" : {
+ "tooltip": false,
+ "format": "{}",
+ "signal": 6,
+ "exec" : "sb-news",
+ "on-click": "BLOCK_BUTTON=1 sb-news; pkill -RTMIN+6 waybar",
+ "on-click-right": "BLOCK_BUTTON=3 sb-news 3",
+ "on-click-middle": "BLOCK_BUTTON=2 sb-news 2",
+ "on-click-backward": "BLOCK_BUTTON=8 sb-news 8"
+ },
+
+ "custom/torrent" : {
+ "tooltip": false,
+ "format": "{}",
+ "signal": 7,
+ "interval": 20,
+ "exec" : "sb-torrent",
+ "on-click": "BLOCK_BUTTON=1 sb-torrent",
+ "on-click-right": "BLOCK_BUTTON=3 sb-torrent",
+ "on-click-middle": "BLOCK_BUTTON=2 sb-torrent",
+ "on-click-backward": "BLOCK_BUTTON=8 sb-torrent"
+ },
+
+ "custom/memory" : {
+ "tooltip": false,
+ "format": "{}",
+ "signal": 14,
+ "exec" : "sb-memory",
+ "interval": 10,
+ "on-click": "BLOCK_BUTTON=1 sb-memory",
+ "on-click-right": "BLOCK_BUTTON=3 sb-memory",
+ "on-click-middle": "BLOCK_BUTTON=2 sb-memory",
+ "on-click-backward": "BLOCK_BUTTON=8 sb-memory"
+ },
+
+ "custom/doppler" : {
+ "tooltip": false,
+ "format": "{}",
+ "signal": 13,
+ "interval": 650,
+ "exec" : "sb-doppler",
+ "on-click": "BLOCK_BUTTON=1 sb-doppler",
+ "on-click-right": "BLOCK_BUTTON=3 sb-doppler",
+ "on-click-middle": "BLOCK_BUTTON=2 sb-doppler",
+ "on-click-backward": "BLOCK_BUTTON=8 sb-doppler"
+ },
+
+ "custom/forecast" : {
+ "tooltip": false,
+ "format": "{}",
+ "signal": 5,
+ "exec" : "sb-forecast",
+ "interval" : 18000,
+ "on-click": "BLOCK_BUTTON=1 sb-forecast",
+ "on-click-right": "BLOCK_BUTTON=3 sb-forecast",
+ "on-click-middle": "BLOCK_BUTTON=2 sb-forecast",
+ "on-click-backward": "BLOCK_BUTTON=8 sb-forecast"
+ },
+
+ "custom/mailbox" : {
+ "tooltip": false,
+ "format": "{}",
+ "signal": 12,
+ "exec" : "sb-mailbox",
+ "interval" : 180,
+ "on-click": "BLOCK_BUTTON=1 sb-mailbox",
+ "on-click-right": "BLOCK_BUTTON=3 sb-mailbox",
+ "on-click-middle": "BLOCK_BUTTON=2 sb-mailbox",
+ "on-click-backward": "BLOCK_BUTTON=8 sb-mailbox"
+ },
+
+ "custom/nettraf" : {
+ "tooltip": false,
+ "format": "{}",
+ "signal": 16,
+ "exec" : "sb-nettraf",
+ "interval" : 1,
+ "on-click": "BLOCK_BUTTON=1 sb-nettraf",
+ "on-click-right": "BLOCK_BUTTON=3 sb-nettraf",
+ "on-click-backward": "BLOCK_BUTTON=8 sb-nettraf"
+ },
+
+ "custom/microphone" : {
+ "tooltip": false,
+ "format": "{}",
+ "signal": 23,
+ "exec" : "sb-microphone",
+ "interval": 10,
+ "on-click": "BLOCK_BUTTON=1 sb-microphone",
+ "on-click-middle": "BLOCK_BUTTON=2 sb-microphone",
+ "on-scroll-up": "BLOCK_BUTTON=4 sb-microphone",
+ "on-scroll-down": "BLOCK_BUTTON=5 sb-microphone",
+ "on-click-right": "BLOCK_BUTTON=3 sb-microphone",
+ "on-click-backward": "BLOCK_BUTTON=8 sb-microphone"
+ },
+
+ "custom/volume" : {
+ "tooltip": false,
+ "format": "{}",
+ "signal": 10,
+ "exec" : "sb-volume",
+ "interval": 10,
+ "on-click": "BLOCK_BUTTON=1 sb-volume",
+ "on-click-middle": "BLOCK_BUTTON=2 sb-volume",
+ "on-scroll-up": "BLOCK_BUTTON=4 sb-volume",
+ "on-scroll-down": "BLOCK_BUTTON=5 sb-volume",
+ "on-click-right": "BLOCK_BUTTON=3 sb-volume",
+ "on-click-backward": "BLOCK_BUTTON=8 sb-volume"
+ },
+
+ "custom/clock" : {
+ "tooltip": false,
+ "format": "{}",
+ "signal": 1,
+ "exec" : "sb-clock",
+ "interval" : 1,
+ "on-click": "BLOCK_BUTTON=1 sb-clock",
+ "on-click-middle": "BLOCK_BUTTON=2 sb-clock",
+ "on-click-right": "BLOCK_BUTTON=3 sb-clock",
+ "on-click-backward": "BLOCK_BUTTON=8 sb-clock"
+ },
+
+ "custom/internet" : {
+ "tooltip": false,
+ "format": "{}",
+ "signal": 4,
+ "exec" : "sb-internet",
+ "interval": 10,
+ "on-click": "BLOCK_BUTTON=1 sb-internet; pkill -RTMIN+4 waybar",
+ "on-click-right": "BLOCK_BUTTON=3 sb-internet; pkill -RTMIN+4 waybar",
+ "on-click-middle": "pkill -RTMIN+4 waybar",
+ "on-click-backward": "BLOCK_BUTTON=8 sb-internet"
+ },
+
+ "tray" : {
+ "icon-size": 18,
+ "spacing": 10
+ }
+}
diff --git a/.config/waybar/style.css b/.config/waybar/style.css
new file mode 100644
index 0000000..ff119b0
--- /dev/null
+++ b/.config/waybar/style.css
@@ -0,0 +1,98 @@
+* {
+ font-family: "monospace";
+ min-height: 0;
+ font-size: 100%;
+}
+
+window#waybar {
+ background-color: #005577;
+}
+
+#window {
+ background-color: #005577;
+ padding-left: 10px;
+}
+
+#custom-vanity {
+ padding-left: 5px;
+ padding-right: 10px;
+}
+
+#taskbar button,
+#workspaces button {
+ color: #bbb;
+ background-color: #222;
+ border-radius: 0px;
+}
+
+#taskbar button.active,
+#workspaces button.active {
+ color: #eee;
+ background-color: #005577;
+}
+
+#workspaces button.urgent {
+ color: #fb4934;
+}
+
+.modules-left, .modules-right {
+ background: #222;
+ color: #bbb;
+}
+
+.modules-right {
+ padding-left: 10px;
+}
+
+#window {
+ color: #fff;
+}
+
+#custom-music {
+ padding-right: 10px;
+}
+
+#custom-packages {
+ padding-right: 10px;
+}
+
+#custom-news {
+ padding-right: 10px;
+}
+
+#custom-memory {
+ padding-right: 10px;
+}
+
+#custom-forecast {
+ padding-right: 10px;
+}
+
+#custom-mailbox {
+ padding-right: 10px;
+}
+
+#custom-nettraf {
+ min-width: 120px;
+ padding-right: 10px;
+}
+
+#custom-microphone {
+ padding-right: 10px;
+}
+
+#custom-volume {
+ padding-right: 10px;
+}
+
+#custom-clock {
+ padding-right: 10px;
+}
+
+#custom-internet {
+ padding-right: 10px;
+}
+
+#tray {
+ padding-right: 10px;
+}
diff --git a/.config/wget/wgetrc b/.config/wget/wgetrc
new file mode 100644
index 0000000..4fd7999
--- /dev/null
+++ b/.config/wget/wgetrc
@@ -0,0 +1 @@
+hsts-file=~/.cache/wget-hsts
diff --git a/.config/yazi/yazi.toml b/.config/yazi/yazi.toml
new file mode 100644
index 0000000..7f1fde1
--- /dev/null
+++ b/.config/yazi/yazi.toml
@@ -0,0 +1,2 @@
+[mgr]
+show_hidden = true
diff --git a/.config/zathura/zathurarc b/.config/zathura/zathurarc
new file mode 100644
index 0000000..de92e4d
--- /dev/null
+++ b/.config/zathura/zathurarc
@@ -0,0 +1,25 @@
+set sandbox none
+set statusbar-h-padding 0
+set statusbar-v-padding 0
+set page-padding 1
+set selection-clipboard clipboard
+map u scroll half-up
+map d scroll half-down
+map D toggle_page_mode
+map r reload
+map R rotate
+map K zoom in
+map J zoom out
+map i recolor
+map p print
+map g goto top
+map [fullscreen] u scroll half-up
+map [fullscreen] d scroll half-down
+map [fullscreen] D toggle_page_mode
+map [fullscreen] r reload
+map [fullscreen] R rotate
+map [fullscreen] K zoom in
+map [fullscreen] J zoom out
+map [fullscreen] i recolor
+map [fullscreen] p print
+map [fullscreen] g goto top
diff --git a/.config/zsh/.zshrc b/.config/zsh/.zshrc
new file mode 100644
index 0000000..4d482f6
--- /dev/null
+++ b/.config/zsh/.zshrc
@@ -0,0 +1,87 @@
+# Enable colors and change prompt:
+autoload -U colors && colors # Load colors
+PS1='%B%{$fg[red]%}[%{$fg[yellow]%}%n%{$fg[green]%}@%{$fg[blue]%}%M %{$fg[magenta]%}%~%{$fg[red]%}]%{$reset_color%}$%b${vcs_info_msg_0_} '
+setopt autocd # Automatically cd into typed directory.
+stty stop undef # Disable ctrl-s to freeze terminal.
+setopt interactive_comments
+setopt prompt_subst
+# History in cache directory:
+HISTSIZE=10000000
+SAVEHIST=10000000
+HISTFILE="${XDG_CACHE_HOME:-$HOME/.cache}/zsh/history"
+setopt inc_append_history
+
+autoload -Uz vcs_info # enable vcs_info
+precmd () { vcs_info }
+zstyle ':vcs_info:*' formats ' %s(%F{blue}%b%f)' # git(main)
+
+# Load aliases and shortcuts if existent.
+[ -f "${XDG_CONFIG_HOME:-$HOME/.config}/shell/shortcutrc" ] && source "${XDG_CONFIG_HOME:-$HOME/.config}/shell/shortcutrc"
+[ -f "${XDG_CONFIG_HOME:-$HOME/.config}/shell/shortcutenvrc" ] && source "${XDG_CONFIG_HOME:-$HOME/.config}/shell/shortcutenvrc"
+[ -f "${XDG_CONFIG_HOME:-$HOME/.config}/shell/aliasrc" ] && source "${XDG_CONFIG_HOME:-$HOME/.config}/shell/aliasrc"
+[ -f "${XDG_CONFIG_HOME:-$HOME/.config}/shell/zshnameddirrc" ] && source "${XDG_CONFIG_HOME:-$HOME/.config}/shell/zshnameddirrc"
+
+# Basic auto/tab complete:
+autoload -U compinit
+zstyle ':completion:*' menu select
+zmodload zsh/complist
+compinit
+_comp_options+=(globdots) # Include hidden files.
+
+# vi mode
+bindkey -v
+export KEYTIMEOUT=1
+
+# Use vim keys in tab complete menu:
+bindkey -M menuselect 'h' vi-backward-char
+bindkey -M menuselect 'k' vi-up-line-or-history
+bindkey -M menuselect 'l' vi-forward-char
+bindkey -M menuselect 'j' vi-down-line-or-history
+bindkey -v '^?' backward-delete-char
+
+# Change cursor shape for different vi modes.
+function zle-keymap-select () {
+ case $KEYMAP in
+ vicmd) echo -ne '\e[6 q';;
+ viins|main) echo -ne '\033[0 q';;
+ esac
+}
+zle -N zle-keymap-select
+zle-line-init() {
+ zle -K viins # initiate `vi insert` as keymap (can be removed if `bindkey -V` has been set elsewhere)
+ echo -ne '\033[0 q'
+}
+zle -N zle-line-init
+
+function preexec {
+ print -Pn "\e]0;${(q)1}\e\\"
+}
+
+# Use yazi to switch directories and bind it to ctrl-o
+function y() {
+ local tmp="$(mktemp -t "yazi-cwd.XXXXXX")" cwd
+ yazi "$@" --cwd-file="$tmp"
+ if cwd="$(command cat -- "$tmp")" && [ -n "$cwd" ] && [ "$cwd" != "$PWD" ]; then
+ builtin cd -- "$cwd"
+ fi
+ rm -f -- "$tmp" > /dev/null
+}
+
+bindkey -s '^o' '^uy\n'
+
+bindkey -s '^a' '^ubc -lq\n'
+
+bindkey -s '^f' '^ucd "$(dirname "$(fzf)")"\n'
+
+bindkey '^[[P' delete-char
+
+# Edit line in vim with ctrl-e:
+autoload edit-command-line; zle -N edit-command-line
+bindkey '^e' edit-command-line
+bindkey -M vicmd '^[[P' vi-delete-char
+bindkey -M vicmd '^e' edit-command-line
+bindkey -M visual '^[[P' vi-delete
+
+source /usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh
+# Load syntax highlighting; should be last.
+source /usr/share/zsh/plugins/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh 2>/dev/null
diff --git a/.local/bin/bookmarks b/.local/bin/bookmarks
new file mode 100755
index 0000000..a04a403
--- /dev/null
+++ b/.local/bin/bookmarks
@@ -0,0 +1,142 @@
+#!/bin/dash
+
+URLQUERY_FILE="${HOME}/.local/share/urlquery"
+ACTION_MENU="@@"
+
+CLIPBOARD() {
+ wl-paste
+}
+
+DMENU() {
+ mew -i -l "${1}" -p "${2}"
+}
+
+error_notify() {
+ notify-send "${1}"
+ exit "1"
+}
+
+ensure_file_exists() {
+ [ -f "${URLQUERY_FILE}" ] || {
+ notify-send "${URLQUERY_FILE} does not exist. Creating it now."
+ printf "SearXNG=https://searx.tiekoetter.com/search?q=\n" > "${URLQUERY_FILE}"
+ }
+}
+
+get_selection() {
+ cut -d= -f1 "${URLQUERY_FILE}" | DMENU "${LINE_COUNT}" "Bookmarks"
+}
+
+update_file() {
+ pattern="${1}"
+ replacement="${2}"
+
+ sed "/${pattern}/c\\${replacement}" "${URLQUERY_FILE}" > "${URLQUERY_FILE}.tmp" &&
+ mv "${URLQUERY_FILE}.tmp" "${URLQUERY_FILE}" ||
+ error_notify "Failed to update the file."
+}
+
+is_valid_url() {
+ printf "%s\n" "${1}" | rg -q "^https?://[^[:space:]/?#][^[:space:]]+$"
+}
+
+add_bookmark() {
+ URL="$(CLIPBOARD)"
+
+ is_valid_url "${URL}" || error_notify "The clipboard content is not a valid URL."
+
+ rg -q "=${URL}$" "${URLQUERY_FILE}" &&
+ notify-send "The URL is already in the list." && return
+
+ NAME="$(printf "" | DMENU "0" "Name")"
+
+ [ -n "${NAME}" ] && printf "%s\n" "${NAME}=${URL}" >> "${URLQUERY_FILE}" &&
+ notify-send "'${NAME}' is bookmarked."
+}
+
+delete_bookmark() {
+ NAME="$(get_selection)"
+
+ [ -z "${NAME}" ] && error_notify "Failed to delete the bookmark." && return
+
+ sed "/^${NAME}=/d" "${URLQUERY_FILE}" > "${URLQUERY_FILE}.tmp"
+ mv "${URLQUERY_FILE}.tmp" "${URLQUERY_FILE}"
+
+ [ -s "${URLQUERY_FILE}" ] && rg -q "\S" "${URLQUERY_FILE}" || rm "${URLQUERY_FILE}"
+
+ notify-send "'${NAME}' is deleted."
+}
+
+edit_name() {
+ OLD_NAME="${1}"
+ NEW_NAME="$(printf "" | DMENU "0" "New Name")"
+
+ [ -z "${NEW_NAME}" ] && return
+
+ URL="$(rg "^${OLD_NAME}=" "${URLQUERY_FILE}" | cut -d= -f2)"
+
+ update_file "^${OLD_NAME}=" "${NEW_NAME}=${URL}"
+}
+
+edit_url() {
+ NAME="${1}"
+ NEW_URL="$(echo "" | DMENU "0" "New URL")"
+
+ [ -z "${NEW_URL}" ] && return
+
+ update_file "^${NAME}=.*" "${NAME}=${NEW_URL}"
+}
+
+edit_bookmark() {
+ NAME="$(get_selection)"
+
+ [ -z "${NAME}" ] && error_notify "Failed to edit the bookmark." && return
+
+ FIELD="$(printf "Name\nURL\n" | DMENU "2" "Edit")"
+
+ case "${FIELD}" in
+ "Name")edit_name "${NAME}";;
+ "URL")edit_url "${NAME}"
+ esac
+
+ notify-send "'${NAME}' is updated."
+}
+
+open_bookmark() {
+ URL="$(rg "^${SELECTION}=" "${URLQUERY_FILE}" | cut -d= -f2-)"
+
+ [ -z "${URL}" ] && notify-send "Bookmark not found." && exit "1"
+
+ case "${URL}" in
+ *"search"* | *"wiki"* | *"packages"* | *"chatgpt"*) QUERY="$(echo "" | DMENU "0" "Search")"
+ URL="${URL}${QUERY}"
+ ;;
+ esac
+
+ "${BROWSER}" "${URL}" || notify-send "Failed to open the URL."
+}
+
+ensure_file_exists
+
+LINE_COUNT="$(wc -l < "${URLQUERY_FILE}")"
+
+[ "${LINE_COUNT}" -ge "15" ] && LINE_COUNT="15"
+
+SELECTION="$(get_selection)"
+
+[ -z "${SELECTION}" ] && exit
+
+case "${SELECTION}" in
+ "${ACTION_MENU}")
+ ACTION="$(printf "Add\nDelete\nEdit\n" | DMENU "3" "Action")"
+
+ case "${ACTION}" in
+ "Add") add_bookmark ;;
+ "Delete") delete_bookmark ;;
+ "Edit") edit_bookmark ;;
+ esac
+ ;;
+ *)
+ open_bookmark
+ ;;
+esac
diff --git a/.local/bin/booksplit b/.local/bin/booksplit
new file mode 100755
index 0000000..079d85f
--- /dev/null
+++ b/.local/bin/booksplit
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+# Requires ffmpeg
+
+[ ! -f "$2" ] && printf "The first file should be the audio, the second should be the timecodes.\\n" && exit
+
+echo "Enter the album/book title:"; read -r booktitle
+echo "Enter the artist/author:"; read -r author
+echo "Enter the publication year:"; read -r year
+
+inputaudio="$1"
+ext="${1##*.}"
+
+# Get a safe file name from the book.
+escbook="$(echo "$booktitle" | iconv -c -f UTF-8 -t ASCII//TRANSLIT | tr -d '[:punct:]' | tr '[:upper:]' '[:lower:]' | tr ' ' '-' | sed "s/-\+/-/g;s/\(^-\|-\$\)//g")"
+
+! mkdir -p "$escbook" &&
+ echo "Do you have write access in this directory?" &&
+ exit 1
+
+# Get the total number of tracks from the number of lines.
+total="$(wc -l < "$2")"
+
+cmd="ffmpeg -i \"$inputaudio\" -nostdin -y"
+
+while read -r x;
+do
+ end="$(echo "$x" | cut -d' ' -f1)"
+ file="$escbook/$(printf "%.2d" "$track")-$esctitle.$ext"
+ if [ -n "$start" ]; then
+ cmd="$cmd -metadata artist=\"$author\" -metadata title=\"$title\" -metadata album=\"$booktitle\" -metadata year=\"$year\" -metadata track=\"$track\" -metadata total=\"$total\" -ss \"$start\" -to \"$end\" -vn -c:a copy \"$file\" "
+ fi
+ title="$(echo "$x" | cut -d' ' -f2-)"
+ esctitle="$(echo "$title" | iconv -c -f UTF-8 -t ASCII//TRANSLIT | tr -d '[:punct:]' | tr '[:upper:]' '[:lower:]' | tr ' ' '-' | sed "s/-\+/-/g;s/\(^-\|-\$\)//g")"
+ track="$((track+1))"
+ start="$end"
+done < "$2"
+
+# Last track must be added out of the loop.
+file="$escbook/$(printf "%.2d" "$track")-$esctitle.$ext"
+cmd="$cmd -metadata artist=\"$author\" -metadata title=\"$title\" -metadata album=\"$booktitle\" -metadata year=\"$year\" -metadata track=\"$track\" -ss \"$start\" -vn -c copy \"$file\""
+
+eval "$cmd"
diff --git a/.local/bin/cleanup b/.local/bin/cleanup
new file mode 100755
index 0000000..4f0bee1
--- /dev/null
+++ b/.local/bin/cleanup
@@ -0,0 +1,2 @@
+#!/bin/sh
+yes | paru -Scc
diff --git a/.local/bin/compiler b/.local/bin/compiler
new file mode 100755
index 0000000..5c02164
--- /dev/null
+++ b/.local/bin/compiler
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+# This script will compile or run another finishing operation on a document. I
+# have this script run via vim.
+
+# Compiles .tex. groff (.mom, .ms), .rmd, .md, .org. Opens .sent files as sent
+# presentations. Runs scripts based on extension or shebang.
+
+file="${1}"
+ext="${file##*.}"
+dir=${file%/*}
+base="${file%.*}"
+
+cd "${dir}" || exit "1"
+
+case "${ext}" in
+ [0-9]) preconv "${file}" | refer -PS -e | groff -mandoc -T pdf > "${base}.pdf" ;;
+ mom|ms) preconv "${file}" | refer -PS -e | groff -T pdf -m"${ext}" > "${base}.pdf" ;;
+ c) cc "${file}" -o "${base}" && "${base}" ;;
+ cob) cobc -x -o "$base" "$file" && "$base" ;;
+ cpp|cc) g++ "${file}" -o "${base}" && "${base}" ;;
+ cs) mcs "${file}" && mono "${base}.exe" ;;
+ go) go run "${file}" ;;
+ h) doas make install ;;
+ java) javac -d classes "${file}" && java -cp classes "${base}" ;;
+ m) octave "${file}" ;;
+ md) [ -x "$(command -v lowdown)" ] && \
+ lowdown --parse-no-intraemph "${file}" -Tms | groff -mpdfmark -ms -kept -T pdf > "${base}.pdf" || \
+ [ -x "$(command -v groffdown)" ] && \
+ groffdown -i "${file}" | groff -T pdf > "${base}.pdf" || \
+ pandoc -t ms --highlight-style="kate" -s -o "${base}.pdf" "${file}" ;;
+ org) emacs "${file}" --batch -u "${USER}" -f org-latex-export-to-pdf ;;
+ py) python "${file}" ;;
+ rink) rink -f "${file}" ;;
+ [rR]md) Rscript -e "rmarkdown::render('${file}', quiet=TRUE)" ;;
+ rs) cargo build && cargo run --quiet ;;
+ sass) sassc -a "${file}" "${base}.css" ;;
+ scad) openscad -o "${base}.stl" "${file}" ;;
+ sent) setsid -f sent "${file}" 2> "/dev/null" ;;
+ tex) latexmk ;;
+ *) sed -n '/^#!/s/^#!//p; q' "${file}" | xargs -r -I % "${file}" ;;
+esac
diff --git a/.local/bin/cron/README.md b/.local/bin/cron/README.md
new file mode 100644
index 0000000..e314296
--- /dev/null
+++ b/.local/bin/cron/README.md
@@ -0,0 +1,14 @@
+# Important Note
+
+These cronjobs have components that require information about your current display to display notifications correctly.
+
+When you add them as cronjobs, I recommend you precede the command with commands as those below:
+
+```
+export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u $USER)/bus; export WAYLAND_DISPLAY=wayland-1; . $HOME/.zprofile; then_command_goes_here
+```
+
+This ensures that notifications will display, wtype/wlrctl commands will function and environmental variables will work as well.
+
+# Also important
+DBUS_SESSION_BUS_ADDRESS variable will always have a random address in the /tmp directory when you are using dinit as your init system.
diff --git a/.local/bin/cron/checkup b/.local/bin/cron/checkup
new file mode 100755
index 0000000..fbe8e0f
--- /dev/null
+++ b/.local/bin/cron/checkup
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# Syncs repositories and downloads updates, meant to be run as a cronjob.
+
+notify-send "📦 Repository Sync" "Checking for package updates..."
+
+doas pacman -Syyuw --noconfirm || notify-send "Error downloading updates.
+
+Check your internet connection, if pacman is already running, or run update manually to see errors."
+pkill -RTMIN+8 "${STATUSBAR:-waybar}"
+
+if pacman -Qu | rg -v "\[ignored\]"
+then
+ notify-send "🎁 Repository Sync" "Updates available. Click statusbar icon (📦) for update."
+else
+ notify-send "📦 Repository Sync" "Sync complete. No new packages for update."
+fi
diff --git a/.local/bin/cron/crontog b/.local/bin/cron/crontog
new file mode 100755
index 0000000..c9a640f
--- /dev/null
+++ b/.local/bin/cron/crontog
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Toggles all cronjobs off/on.
+# Stores disabled crontabs in ~/.config/cronsaved until restored.
+
+([ -f "${XDG_CONFIG_HOME:-$HOME/.config}"/cronsaved ] && crontab - < "${XDG_CONFIG_HOME:-$HOME/.config}"/cronsaved && rm "${XDG_CONFIG_HOME:-$HOME/.config}"/cronsaved && notify-send "🕓 Cronjobs re-enabled.") || ( crontab -l > "${XDG_CONFIG_HOME:-$HOME/.config}"/cronsaved && crontab -r && notify-send "🕓 Cronjobs saved and disabled.")
diff --git a/.local/bin/cron/mailup b/.local/bin/cron/mailup
new file mode 100755
index 0000000..0b2ab2d
--- /dev/null
+++ b/.local/bin/cron/mailup
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+pgrep -f mailsync && exit
+
+echo 🔃 > /tmp/mailupdate
+pkill -RTMIN+12 "${STATUSBAR:-waybar}"
+/usr/local/bin/mailsync
+rm -f /tmp/mailupdate
+pkill -RTMIN+12 "${STATUSBAR:-waybar}"
diff --git a/.local/bin/cron/newsup b/.local/bin/cron/newsup
new file mode 100755
index 0000000..efdf4ae
--- /dev/null
+++ b/.local/bin/cron/newsup
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+# Set as a cron job to check for new RSS entries for newsboat.
+# If newsboat is open, sends it an "R" key to refresh.
+
+export XDG_RUNTIME_DIR=/run/user/1000
+export WAYLAND_DISPLAY=wayland-1
+
+/usr/bin/notify-send "📰 Updating RSS feeds..."
+
+pgrep -f newsboat$ && /usr/bin/wlrctl window focus title:newsboat && /usr/bin/wlrctl keyboard type R && exit
+
+echo 🔃 > /tmp/newsupdate
+pkill -RTMIN+6 "${STATUSBAR:-waybar}"
+/usr/bin/newsboat -x reload
+rm -f /tmp/newsupdate
+pkill -RTMIN+6 "${STATUSBAR:-waybar}"
+/usr/bin/notify-send "📰 RSS feed update complete."
diff --git a/.local/bin/define b/.local/bin/define
new file mode 100755
index 0000000..8452671
--- /dev/null
+++ b/.local/bin/define
@@ -0,0 +1,37 @@
+#!/usr/bin/env bash
+
+word=${1:-$(xclip -o -selection primary 2>/dev/null || wl-paste 2>/dev/null)}
+
+# Check for empty word or special characters
+[[ -z "$word" || "$word" =~ [\/] ]] && notify-send -h string:bgcolor:#bf616a -t 3000 "Invalid input." && exit 0
+
+query=$(curl -s --connect-timeout 5 --max-time 10 "https://api.dictionaryapi.dev/api/v2/entries/en_US/$word")
+
+# Check for connection error (curl exit status stored in $?)
+[ $? -ne 0 ] && notify-send -h string:bgcolor:#bf616a -t 3000 "Connection error." && exit 1
+
+# Check for invalid word response
+[[ "$query" == *"No Definitions Found"* ]] && notify-send -h string:bgcolor:#bf616a -t 3000 "Invalid word." && exit 0
+
+# Show only first 3 definitions
+def=$(echo "$query" | jq -r '[.[].meanings[] | {pos: .partOfSpeech, def: .definitions[].definition}] | .[:3].[] | "\n\(.pos). \(.def)"')
+
+# Requires a notification daemon to be installed
+notify-send -t 60000 "$word -" "$def"
+
+
+### MORE OPTIONS :)
+
+# Show first definition for each part of speech (thanks @morgengabe1 on youtube)
+# def=$(echo "$query" | jq -r '.[0].meanings[] | "\(.partOfSpeech): \(.definitions[0].definition)\n"')
+
+# Show all definitions
+# def=$(echo "$query" | jq -r '.[].meanings[] | "\n\(.partOfSpeech). \(.definitions[].definition)"')
+
+# Regex + rg for just definition, if anyone prefers that to jq
+# def=$(rg -Po '"definition":"\K(.*?)(?=")' <<< "$query")
+
+# bold=$(tput bold) # Print text bold with echo, for visual clarity
+# normal=$(tput sgr0) # Reset text to normal
+# echo "${bold}Definition of $word"
+# echo "${normal}$def"
diff --git a/.local/bin/displayselect b/.local/bin/displayselect
new file mode 100755
index 0000000..4744dd3
--- /dev/null
+++ b/.local/bin/displayselect
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+# A UI for detecting and selecting all displays. Probes xrandr for connected
+# displays and lets user select one to use. User may also select "manual
+# selection" which opens arandr.
+
+twoscreen() { # If multi-monitor is selected and there are two screens.
+
+ mirror=$(printf "no\\nyes" | dmenu -i -p "Mirror displays?")
+ # Mirror displays using native resolution of external display and a scaled
+ # version for the internal display
+ if [ "$mirror" = "yes" ]; then
+ external=$(echo "$screens" | dmenu -i -p "Optimize resolution for:")
+ internal=$(echo "$screens" | rg -v "$external")
+
+ res_external=$(xrandr --query | sed -n "/^$external/,/\+/p" | \
+ tail -n 1 | awk '{print $1}')
+ res_internal=$(xrandr --query | sed -n "/^$internal/,/\+/p" | \
+ tail -n 1 | awk '{print $1}')
+
+ res_ext_x=$(echo "$res_external" | sed 's/x.*//')
+ res_ext_y=$(echo "$res_external" | sed 's/.*x//')
+ res_int_x=$(echo "$res_internal" | sed 's/x.*//')
+ res_int_y=$(echo "$res_internal" | sed 's/.*x//')
+
+ scale_x=$(echo "$res_ext_x / $res_int_x" | bc -l)
+ scale_y=$(echo "$res_ext_y / $res_int_y" | bc -l)
+
+ xrandr --output "$external" --auto --scale 1.0x1.0 \
+ --output "$internal" --auto --same-as "$external" \
+ --scale "$scale_x"x"$scale_y"
+ else
+
+ primary=$(echo "$screens" | dmenu -i -p "Select primary display:")
+ secondary=$(echo "$screens" | rg -v ^"$primary"$)
+ direction=$(printf "left\\nright" | dmenu -i -p "What side of $primary should $secondary be on?")
+ xrandr --output "$primary" --auto --scale 1.0x1.0 --output "$secondary" --"$direction"-of "$primary" --auto --scale 1.0x1.0
+ fi
+ }
+
+morescreen() { # If multi-monitor is selected and there are more than two screens.
+ primary=$(echo "$screens" | dmenu -i -p "Select primary display:")
+ secondary=$(echo "$screens" | rg -v ^"$primary"$ | dmenu -i -p "Select secondary display:")
+ direction=$(printf "left\\nright" | dmenu -i -p "What side of $primary should $secondary be on?")
+ tertiary=$(echo "$screens" | rg -v ^"$primary"$ | rg -v ^"$secondary"$ | dmenu -i -p "Select third display:")
+ xrandr --output "$primary" --auto --output "$secondary" --"$direction"-of "$primary" --auto --output "$tertiary" --"$(printf "left\\nright" | rg -v "$direction")"-of "$primary" --auto
+ }
+
+multimon() { # Multi-monitor handler.
+ case "$(echo "$screens" | wc -l)" in
+ 2) twoscreen ;;
+ *) morescreen ;;
+ esac ;}
+
+onescreen() { # If only one output available or chosen.
+ xrandr --output "$1" --auto --scale 1.0x1.0 $(echo "$allposs" | rg -v "\b$1" | awk '{print "--output", $1, "--off"}' | paste -sd ' ' -)
+ }
+
+postrun() { # Stuff to run to clean up.
+ setbg # Fix background if screen size/arangement has changed.
+ { killall dunst ; setsid -f dunst ;} >/dev/null 2>&1 # Restart dunst to ensure proper location on screen
+ }
+
+# Get all possible displays
+allposs=$(xrandr -q | rg "connected")
+
+# Get all connected screens.
+screens=$(echo "$allposs" | awk '/ connected/ {print $1}')
+
+# If there's only one screen
+[ "$(echo "$screens" | wc -l)" -lt 2 ] &&
+ { onescreen "$screens"; postrun; notify-send "💻 Only one screen detected." "Using it in its optimal settings..."; exit ;}
+
+# Get user choice including multi-monitor and manual selection:
+chosen=$(printf "%s\\nmulti-monitor\\nmanual selection" "$screens" | dmenu -i -p "Select display arangement:") &&
+case "$chosen" in
+ "manual selection") arandr ; exit ;;
+ "multi-monitor") multimon ;;
+ *) onescreen "$chosen" ;;
+esac
+
+postrun
diff --git a/.local/bin/dmenuhandler b/.local/bin/dmenuhandler
new file mode 100755
index 0000000..875bbc2
--- /dev/null
+++ b/.local/bin/dmenuhandler
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# Feed this script a link and it will give mew
+# some choice programs to use to open it.
+feed="${1:-$(true | mew -p 'Paste URL or file path')}"
+
+case "$(printf "copy url\\nswayimg\\nsetbg\\nPDF\\nbrowser\\nlynx\\nvim\\nmpv\\nmpv loop\\nmpv float\\nqueue download\\nqueue yt-dlp\\nqueue yt-dlp audio" | mew -i -p "Open it with?")" in
+ "copy url") echo "$feed" | wl-copy ;;
+ mpv) setsid -f mpv -quiet "$feed" >/dev/null 2>&1 ;;
+ "mpv loop") setsid -f mpv -quiet --loop "$feed" >/dev/null 2>&1 ;;
+ "mpv float") setsid -f "$TERMINAL" -e mpv --geometry=+0-0 --autofit=30% --title="mpvfloat" "$feed" >/dev/null 2>&1 ;;
+ "queue yt-dlp") qndl "$feed" >/dev/null 2>&1 ;;
+ "queue yt-dlp audio") qndl "$feed" 'yt-dlp -o "%(title)s.%(ext)s" -f bestaudio --embed-metadata --restrict-filenames' ;;
+ "queue download") qndl "$feed" 'curl -LO' >/dev/null 2>&1 ;;
+ PDF) curl -sL "$feed" > "/tmp/$(echo "$feed" | sed "s|.*/||;s/%20/ /g")" && zathura "/tmp/$(echo "$feed" | sed "s|.*/||;s/%20/ /g")" >/dev/null 2>&1 ;;
+ swayimg) curl -sL "$feed" > "/tmp/$(echo "$feed" | sed "s|.*/||;s/%20/ /g")" && swayimg "/tmp/$(echo "$feed" | sed "s|.*/||;s/%20/ /g")" >/dev/null 2>&1 ;;
+ vim) curl -sL "$feed" > "/tmp/$(echo "$feed" | sed "s|.*/||;s/%20/ /g")" && setsid -f "$TERMINAL" -e "$EDITOR" "/tmp/$(echo "$feed" | sed "s|.*/||;s/%20/ /g")" >/dev/null 2>&1 ;;
+ setbg) curl -L "$feed" > $XDG_CACHE_HOME/pic ; swaybg -i $XDG_CACHE_HOME/pic -m fill & >/dev/null 2>&1 ;;
+ browser) setsid -f "$BROWSER" "$feed" >/dev/null 2>&1 ;;
+ lynx) lynx "$feed" >/dev/null 2>&1 ;;
+esac
diff --git a/.local/bin/dmenumountcifs b/.local/bin/dmenumountcifs
new file mode 100755
index 0000000..4832213
--- /dev/null
+++ b/.local/bin/dmenumountcifs
@@ -0,0 +1,19 @@
+#!/bin/sh
+# Gives a mew prompt to mount unmounted local NAS shares for read/write.
+# Requirements - "%wheel ALL=(ALL) NOPASSWD: ALL"
+#
+# Browse for mDNS/DNS-SD services using the Avahi daemon...
+srvname=$(avahi-browse _smb._tcp -t | awk '{print $4}' | mew -i -p "Which NAS?") || exit 1
+notify-send "Searching for network shares..." "Please wait..."
+# Choose share disk...
+share=$(smbclient -L "$srvname" -N | rg Disk | awk '{print $1}' | mew -i -p "Mount which share?") || exit 1
+# Format URL...
+share2mnt=//"$srvname".local/"$share"
+
+sharemount() {
+ mounted=$(mount -v | rg "$share2mnt") || ([ ! -d /mnt/"$share" ] && doas mkdir /mnt/"$share")
+ [ -z "$mounted" ] && doas mount -t cifs "$share2mnt" -o user=nobody,password="",noperm /mnt/"$share" && notify-send "Netshare $share mounted" && exit 0
+ notify-send "Netshare $share already mounted"; exit 1
+}
+
+sharemount
diff --git a/.local/bin/dmenupass b/.local/bin/dmenupass
new file mode 100755
index 0000000..bea2ad9
--- /dev/null
+++ b/.local/bin/dmenupass
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# This script is the SUDO_ASKPASS variable, meaning that it will be used as a
+# password prompt if needed.
+
+mew -P -p "password:" <&-
diff --git a/.local/bin/dmenurecord b/.local/bin/dmenurecord
new file mode 100755
index 0000000..6f51f5f
--- /dev/null
+++ b/.local/bin/dmenurecord
@@ -0,0 +1,113 @@
+#!/bin/sh
+
+# Usage:
+# `$0`: Ask for recording type via mew
+# `$0 screencast`: Record both audio and screen
+# `$0 video`: Record only screen
+# `$0 audio`: Record only audio
+# `$0 kill`: Kill existing recording
+#
+# If there is already a running instance, user will be prompted to end it.
+
+getdim() {
+ screens=$(hyprctl monitors | grep Monitor | cut -d' ' -f2)
+ choice=$(printf "$screens\nExit\n" | mew)
+ [ "${choice}" != "Exit" ] || [ -z "${choice}" ] || exit &&
+ echo $choice
+}
+
+updateicon() { \
+ echo "$1" > /tmp/recordingicon
+ pkill -RTMIN+9 "${STATUSBAR:-waybar}"
+}
+
+killrecording() {
+ recpid="$(bat /tmp/recordingpid)"
+ echo $recpid
+ kill -2 "$recpid"
+ rm -f /tmp/recordingpid
+ updateicon ""
+ pkill -RTMIN+9 "${STATUSBAR:-waybar}"
+}
+
+screencast() { gpu-screen-recorder \
+ -w "$(getdim)" \
+ -f 60 \
+ -a default_output \
+ -a default_input \
+ -o "$HOME/screencast-$(date '+%y%m%d-%H%M-%S').mp4" &
+ echo $! > /tmp/recordingpid
+ updateicon "⏺️🎙️"
+}
+
+video() { gpu-screen-recorder \
+ -w "$(getdim)" \
+ -f 60 \
+ -o "$HOME/video-$(date '+%y%m%d-%H%M-%S').mkv" &
+ echo $! > /tmp/recordingpid
+ updateicon "⏺️"
+}
+
+webcamhidef() { ffmpeg \
+ -f v4l2 \
+ -i /dev/video0 \
+ -video_size 1920x1080 \
+ "$HOME/webcam-$(date '+%y%m%d-%H%M-%S').mkv" &
+ echo $! > /tmp/recordingpid
+ updateicon "🎥"
+}
+
+webcam() { ffmpeg \
+ -f v4l2 \
+ -i /dev/video0 \
+ -video_size 640x480 \
+ "$HOME/webcam-$(date '+%y%m%d-%H%M-%S').mkv" &
+ echo $! > /tmp/recordingpid
+ updateicon "🎥"
+}
+
+
+audio() { \
+ ffmpeg \
+ -f alsa -i default \
+ -c:a flac \
+ "$HOME/audio-$(date '+%y%m%d-%H%M-%S').flac" &
+ echo $! > /tmp/recordingpid
+ updateicon "🎙️"
+}
+
+askrecording() { \
+ choice=$(printf "screencast\\nvideo\\nvideo selected\\naudio\\nwebcam\\nwebcam (hi-def)" | mew -i -p "Select recording style:")
+ case "$choice" in
+ screencast) screencast;;
+ audio) audio;;
+ video) video;;
+ *selected) videoselected;;
+ webcam) webcam;;
+ "webcam (hi-def)") webcamhidef;;
+ esac
+}
+
+asktoend() { \
+ response=$(printf "No\\nYes" | mew -i -p "Recording still active. End recording?") &&
+ [ "$response" = "Yes" ] && killrecording
+}
+
+videoselected()
+{
+ gpu-screen-recorder \
+ -w region -region $(slurp -f "%wx%h+%x+%y") \
+ -f 60 \
+ -o "$HOME/box-$(date '+%y%m%d-%H%M-%S').mkv" &
+ echo $! > /tmp/recordingpid
+ updateicon "⏺️"
+}
+
+case "$1" in
+ screencast) screencast;;
+ audio) audio;;
+ video) video;;
+ *selected) videoselected;;
+ kill) killrecording;;
+ *) ([ -f /tmp/recordingpid ] && asktoend && exit) || askrecording;;
+esac
diff --git a/.local/bin/dmenuunicode b/.local/bin/dmenuunicode
new file mode 100755
index 0000000..2c09c80
--- /dev/null
+++ b/.local/bin/dmenuunicode
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# The famous "get a menu of emojis to copy" script.
+
+# Get user selection via mew from emoji file.
+chosen=$(cut -d ';' -f1 ~/.local/share/larbs/chars/* | mew -i -l 30 | sed "s/ .*//")
+
+# Exit if none chosen.
+[ -z "$chosen" ] && exit
+
+# If you run this command with an argument, it will automatically insert the
+# character. Otherwise, show a message that the emoji has been copied.
+if [ -n "$1" ]; then
+ # currently only ascii supported in wlrctl
+ # wlrctl keyboard type"$chosen"
+ wtype "$chosen"
+else
+ printf "%s" "$chosen" | wl-copy
+ notify-send "'$chosen' copied to clipboard." &
+fi
diff --git a/.local/bin/doas_askpass b/.local/bin/doas_askpass
new file mode 100755
index 0000000..f5d61ef
--- /dev/null
+++ b/.local/bin/doas_askpass
@@ -0,0 +1,47 @@
+#!/usr/bin/expect --
+
+# askpass implementation for doas
+# example usage: DOAS_ASKPASS="mew -P -p password:" doas_askpass echo working
+
+# don't mind the man behind the curtain
+log_user 0
+
+# no command, then nothing to do
+if { $argc == 0 } { exit 0 }
+
+# treat all arguments as command input
+set cmd [lrange $argv 0 end];
+
+# read askpass from env or fallback to dmenu_pass ()
+if {[info exists ::env(DOAS_ASKPASS)]} {
+ set askpass "$::env(DOAS_ASKPASS)"
+} else {
+ set askpass "dmenu_pass password:"
+}
+
+# read password from user
+set pwd [exec {*}$askpass]
+
+# spawn doas operation
+spawn doas {*}$cmd
+
+# send password and execute command
+expect "doas*password:" {
+ send -- "$pwd\r"
+ expect \r
+ log_user 1
+ expect eof
+}
+
+# get the exit status of the spawned doas command
+set status [wait]
+
+# check exit code (4th element of wait result)
+set exit_code [lindex $status 3]
+
+# exit with 1 if doas failed, else 0
+if { $exit_code != 0 } {
+ exit 1
+} else {
+ exit 0
+}
diff --git a/.local/bin/getbib b/.local/bin/getbib
new file mode 100755
index 0000000..2c3f026
--- /dev/null
+++ b/.local/bin/getbib
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+BIB_FILE="${HOME}/latex/uni.bib"
+[ -f "${BIB_FILE}" ] || BIB_FILE="${2:-$(find "${HOME}" -path "${HOME}/.*" \
+ -prune -o -type "f" -name "*.bib" -print -quit)}"
+
+{ [ -f "${BIB_FILE}" ] || [ "${2}" ]; } || {
+ printf "%s\n" "Create a .bib file or provide as \$2." && exit "1"
+}
+
+filter() {
+ sed -n -E 's/.*((DOI|doi)((\.(org))?\/?|:? *))([^: ]+[^ .]).*/\6/p; T; q'
+}
+
+fpdf() {
+ pdf="${1}"
+ doi="$(pdfinfo "${pdf}" 2> "/dev/null" | filter)"
+
+ [ "${doi}" ] || doi="$(pdftotext -q -l "2" "${pdf}" - 2> "/dev/null" | filter)"
+
+ [ "${doi}" ] || printf "%s\n" "No DOI found for PDF: ${pdf}" >&2
+
+ printf "%s\n" "${doi}"
+}
+
+arrange() {
+ sed 's/\}, /\},\n /g
+ s/, /,\n /
+ s/ }/\n}/
+ s/,\s*pages=/,\n\tpages=/' |
+ sed '1s/^ *//
+ 1s/[0-9]*\([0-9]\{2\}\)/\1/
+ 1s/_//
+ 1s/.*/\L&/
+ s/.*=/\L&/
+ s/=/ = /'
+}
+
+doi2bib() {
+ doi="${1#doi:}"
+ url="https://api.crossref.org/works/${doi}/transform/application/x-bibtex"
+ entry="$(curl -kLsS --no-fail "${url}" | arrange)"
+ red='\033[0;31m'
+ reset='\033[0m'
+
+ printf "${red}%s${reset}\n" "${entry}"
+
+ [ "${entry%"${entry#?}"}" != "@" ] && {
+ printf "%s\n" "Failed to fetch bibtex entry for DOI: ${doi}"
+ return "1"
+ }
+
+ rg -iFq "doi = {${doi}}" "${BIB_FILE}" 2> "/dev/null" && {
+ printf "%s\n" "Bibtex entry for DOI: ${doi} already exists in the file."
+ } || {
+ [ -s "${BIB_FILE}" ] && printf "\n" >> "${BIB_FILE}"
+ printf "%s\n" "${entry}" >> "${BIB_FILE}"
+ printf "%s\n" "Added bibtex entry for DOI: ${doi}"
+ }
+}
+
+[ "${1}" ] || {
+ printf "%s\n" "Give either a pdf file or a DOI or a directory path that has PDFs as an argument."
+ exit "1"
+}
+
+[ -f "${1}" ] && doi="$(fpdf "${1}")" && doi2bib "${doi}" && exit "0"
+
+[ -d "${1}" ] && for i in "${1}"/*.pdf; do doi="$(fpdf "${i}")" && doi2bib "${doi}"; done && exit "0"
+
+doi="$(printf "%s\n" "${1}" | filter)" && doi2bib "${doi}"
diff --git a/.local/bin/getcomproot b/.local/bin/getcomproot
new file mode 100755
index 0000000..dbee348
--- /dev/null
+++ b/.local/bin/getcomproot
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+# A helper script for LaTeX/groff files used by `compiler` and `opout`.
+# The user can add the root file of a larger project as a comment as below:
+# % root = mainfile.tex
+# And the compiler script will run on that instead of the opened file.
+
+texroot="$(sed -n 's/^\s*%.*root\s*=\s*\(\S\+\).*/\1/p' "${1}")"
+[ -f "${texroot}" ] && readlink -f "${texroot}" || exit "1"
diff --git a/.local/bin/ifinstalled b/.local/bin/ifinstalled
new file mode 100755
index 0000000..c192eba
--- /dev/null
+++ b/.local/bin/ifinstalled
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Some optional functions in LARBS require programs not installed by default. I
+# use this little script to check to see if a command exists and if it doesn't
+# it informs the user that they need that command to continue. This is used in
+# various other scripts for clarity's sake.
+
+for x in "$@"; do
+ if ! which "$x" >/dev/null 2>&1 && ! pacman -Qq "$x" >/dev/null 2>&1; then
+ notify-send "📦 $x" "must be installed for this function." && exit 1 ;
+ fi
+done
diff --git a/.local/bin/linkhandler b/.local/bin/linkhandler
new file mode 100755
index 0000000..cb12bf9
--- /dev/null
+++ b/.local/bin/linkhandler
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+# Feed script a url or file location.
+# If an image, it will view in swayimg,
+# if a video or gif, it will view in mpv
+# if a music file or pdf, it will download,
+# otherwise it opens link in browser.
+
+if [ -z "$1" ]; then
+ url="$(wl-paste)"
+else
+ url="$1"
+fi
+
+# Check if the URL is from inv.nadeko.net and adjust it for YouTube
+echo "$url" | rg -q 'inv.nadeko.net/watch'
+if [ $? -eq 0 ]; then
+ url="https://www.youtube.com/watch?v=$(echo "$url" | sed 's/.*inv\.nadeko\.net\/watch?v=\([^&]*\)/\1/')"
+fi
+
+case "$url" in
+ *mkv|*webm|*mp4|*youtube.com/watch*|*youtube.com/playlist*|*youtube.com/v/*|*youtube.com/shorts*|*youtu.be*|*hooktube.com*|*bitchute.com*|*videos.lukesmith.xyz*|*odysee.com*)
+ setsid -f mpv -quiet "$url" >/dev/null 2>&1 ;;
+ *png|*jpg|*jpe|*jpeg|*gif|*webp)
+ curl -sL "$url" > "/tmp/$(echo "$url" | sed "s/.*\///;s/%20/ /g")" && swayimg "/tmp/$(echo "$url" | sed "s/.*\///;s/%20/ /g")" >/dev/null 2>&1 & ;;
+ *pdf|*cbz|*cbr)
+ curl -sL "$url" > "/tmp/$(echo "$url" | sed "s/.*\///;s/%20/ /g")" && zathura "/tmp/$(echo "$url" | sed "s/.*\///;s/%20/ /g")" >/dev/null 2>&1 & ;;
+ *mp3|*flac|*opus|*mp3?source*)
+ qndl "$url" 'curl -LO' >/dev/null 2>&1 ;;
+ *)
+ [ -f "$url" ] && setsid -f "$TERMINAL" -e "$EDITOR" "$url" >/dev/null 2>&1 || setsid -f "$BROWSER" "$url" >/dev/null 2>&1
+esac
diff --git a/.local/bin/maimpick b/.local/bin/maimpick
new file mode 100755
index 0000000..29cf327
--- /dev/null
+++ b/.local/bin/maimpick
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+# This is bound to Shift+PrintScreen by default, requires grim (also optionally tesseract and swappy). It lets you
+# choose the kind of screenshot to take, including copying the image or even
+# highlighting an area to copy.
+
+# variables
+output="$(date '+%y%m%d-%H%M-%S').png"
+wclip_cmd="wl-copy -t image/png"
+ocr_cmd="wl-copy"
+
+get_active_window() {
+ hyprctl -j activewindow | jq -r '"\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"'
+}
+
+case "$(printf "a selected area\\ncurrent window\\nfull screen\\na selected area (copy)\\ncurrent window (copy)\\nfull screen (copy)\\na selected area (swappy)\\ncurrent window (swappy)\\nfull screen (swappy)\\ncopy selected image to text" | mew -l 10 -i -p "Screenshot which area?")" in
+ "a selected area") geometry=$(slurp) && sleep 0.2 && grim -g "$geometry" pic-selected-"${output}" && notify-send "📸 maimpick" "Screenshot saved as pic-selected-$output." ;;
+ "current window")
+ geometry=$(get_active_window)
+ sleep 0.2
+ grim -g "$geometry" pic-window-"${output}" && notify-send "📸 maimpick" "Screenshot saved as pic-window-$output." ;;
+ "full screen") geometry=$(slurp -o) && sleep 0.2 && grim -g "$geometry" pic-full-"${output}" && notify-send "📸 maimpick" "Screenshot saved as pic-full-$output." ;;
+ "a selected area (copy)") geometry=$(slurp) && sleep 0.2 && grim -g "$geometry" - | ${wclip_cmd} && notify-send "📸 maimpick" "Selected area screenshot copied to clipboard." ;;
+ "current window (copy)")
+ geometry=$(get_active_window)
+ sleep 0.2
+ grim -g "$geometry" - | ${wclip_cmd} && notify-send "📸 maimpick" "Window screenshot copied to clipboard." ;;
+ "full screen (copy)") geometry=$(slurp -o) && sleep 0.2 && grim -g "$geometry" - | ${wclip_cmd} && notify-send "📸 maimpick" "Full screen screenshot copied to clipboard.";;
+ "a selected area (swappy)") geometry=$(slurp) && sleep 0.2 && grim -g "$geometry" - | swappy -f - ;;
+ "current window (swappy)")
+ geometry=$(get_active_window)
+ sleep 0.2
+ grim -g "$geometry" - | swappy -f - ;;
+ "full screen (swappy)") geometry=$(slurp -o) && sleep 0.2 && grim -g "$geometry" - | swappy -f - ;;
+ "copy selected image to text") tmpfile=$(mktemp /tmp/ocr-XXXXXX.png) && slurp | grim -g - - > "$tmpfile" && tesseract "$tmpfile" - -l eng | ${ocr_cmd} && rm "$tmpfile" && notify-send "📸 maimpick" "Detected text copied to clipboard.\n$(wl-paste)" ;;
+ *) notify-send "📸 maimpick" "Wrong option."
+esac
diff --git a/.local/bin/mounter b/.local/bin/mounter
new file mode 100755
index 0000000..6d65c2c
--- /dev/null
+++ b/.local/bin/mounter
@@ -0,0 +1,114 @@
+#!/bin/bash
+
+IFS='
+'
+# Function for escaping cell-phone names.
+escape(){ echo "$@" | iconv -cf UTF-8 -t ASCII//TRANSLIT | tr -d '[:punct:]' | tr '[:upper:]' '[:lower:]' | tr ' ' '-' | sed "s/-\+/-/g;s/\(^-\|-\$\)//g" ;}
+
+# Check for phones.
+phones="$(simple-mtpfs -l 2>/dev/null | sed "s/^/📱/")"
+mountedphones="$(rg "simple-mtpfs" /etc/mtab)"
+# If there are already mounted phones, remove them from the list of mountables.
+[ -n "$mountedphones" ] && phones="$(for phone in $phones; do
+ for mounted in $mountedphones; do
+ escphone="$(escape "$phone")"
+ [[ "$mounted" =~ "$escphone" ]] && break 1
+ done && continue 1
+ echo "$phone"
+done)"
+
+# Check for drives.
+lsblkoutput="$(doas lsblk -rpo "uuid,name,type,size,label,mountpoint,fstype")"
+# Get all LUKS drives
+allluks="$(echo "$lsblkoutput" | rg crypto_LUKS)"
+# Get a list of the LUKS drive UUIDs already decrypted.
+decrypted="$(find /dev/disk/by-id/dm-uuid-CRYPT-LUKS2-* | sed "s|.*LUKS2-||;s|-.*||")"
+# Functioning for formatting drives correctly for mew:
+filter() { sed "s/ /:/g" | awk -F':' '$7==""{printf "%s%s (%s) %s\n",$1,$3,$5,$6}' ; }
+
+# Get only LUKS drives that are not decrypted.
+unopenedluks="$(for drive in $allluks; do
+ uuid="${drive%% *}"
+ uuid="${uuid//-}" # This is a bashism.
+ [ -n "$decrypted" ] && for open in $decrypted; do
+ [ "$uuid" = "$open" ] && break 1
+ done && continue 1
+ echo "🔒 $drive"
+done | filter)"
+
+# Get all normal, non-encrypted or decrypted partitions that are not mounted.
+normalparts="$(echo "$lsblkoutput"| rg -v crypto_LUKS | rg 'part|rom|crypt' | sed "s/^/💾 /" | filter )"
+
+# Add all to one variable. If no mountable drives found, exit.
+alldrives="$(echo "$phones
+$unopenedluks
+$normalparts" | sed "/^$/d;s/ *$//")"
+
+# Quit the script if a sequential command fails.
+set -e
+
+test -n "$alldrives"
+
+# Feed all found drives to mew and get user choice.
+chosen="$(echo "$alldrives" | mew -p "Mount which drive?" -i)"
+
+# Function for prompting user for a mountpoint.
+getmount(){
+ mp="$(find /mnt /media /mount /home -maxdepth 1 -type d 2>/dev/null | mew -i -p "Mount this drive where?")"
+ test -n "$mp"
+ if [ ! -d "$mp" ]; then
+ mkdiryn=$(printf "No\\nYes" | mew -i -p "$mp does not exist. Create it?")
+ [ "$mkdiryn" = "Yes" ] && (mkdir -p "$mp" || doas_askpass mkdir -p "$mp")
+ fi
+}
+
+attemptmount(){
+ # Attempt to mount without a mountpoint, to see if drive is in fstab.
+ doas mount "$chosen" || return 1
+ notify-send "💾Drive Mounted." "$chosen mounted."
+ exit
+}
+
+case "$chosen" in
+ 💾*)
+ chosen="${chosen%% *}"
+ chosen="${chosen:1}" # This is a bashism.
+ parttype="$(echo "$lsblkoutput" | rg "$chosen" | awk '{print $NF}' | tr -d '[:space:]\r\n')"
+ attemptmount || getmount
+ case "${parttype##* }" in
+ vfat) doas mount -t vfat "$chosen" "$mp" -o rw,umask=0000 ;;
+ btrfs) doas mount "$chosen" "$mp" ;;
+ ntfs) doas mount -t ntfs3 "$chosen" "$mp" ;;
+ *) doas mount "$chosen" "$mp" -o uid="$(id -u)",gid="$(id -g)" ;;
+ esac
+ notify-send "💾Drive Mounted." "$chosen mounted to $mp."
+ ;;
+
+ 🔒*)
+ chosen="${chosen%% *}"
+ chosen="${chosen:1}" # This is a bashism.
+ # Number the drive.
+ while true; do
+ [ -f "/dev/mapper/usb$num" ] || break
+ num="$(printf "%02d" "$((num +1))")"
+ done
+
+ # Decrypt in a terminal window
+ ${TERMINAL:-st} -a termfloat -e doas cryptsetup open "$chosen" "usb$num"
+ # Check if now decrypted.
+ test -b "/dev/mapper/usb$num"
+
+ attemptmount || getmount
+ doas mount "/dev/mapper/usb$num" "$mp"
+ notify-send "🔓Decrypted drive Mounted." "$chosen decrypted and mounted to $mp."
+ ;;
+
+ 📱*)
+ notify-send "❗Note" "Remember to allow file access on your phone now."
+ getmount
+ number="${chosen%%:*}"
+ number="${chosen:1}" # This is a bashism.
+ doas_askpass simple-mtpfs -o allow_other -o fsname="simple-mtpfs-$(escape "$chosen")" --device "$number" "$mp"
+ notify-send "🤖 Android Mounted." "Android device mounted to $mp."
+ ;;
+esac
diff --git a/.local/bin/noisereduce b/.local/bin/noisereduce
new file mode 100755
index 0000000..13f2a0d
--- /dev/null
+++ b/.local/bin/noisereduce
@@ -0,0 +1,81 @@
+#!/usr/bin/sh
+
+usage ()
+{
+ printf "Usage : noisereduce <input video file> <output video file>\n"
+ exit
+}
+
+# Tests for requirements
+ifinstalled ffmpeg || { echo >&2 "We require 'ffmpeg' but it's not installed."; exit 1; }
+ifinstalled sox || { echo >&2 "We require 'ffmpeg' but it's not installed."; exit 1; }
+
+if [ "$#" -ne 2 ]
+then
+ usage
+fi
+
+if [ ! -e "$1" ]
+then
+ printf "File not found: %s\n" "$1"
+ exit
+fi
+
+if [ -e "$2" ]
+then
+ printf "File %s already exists, overwrite? [y/N]\n: " "$2"
+ read -r yn
+ case $yn in
+ [Yy]* ) ;;
+ * ) exit;;
+ esac
+fi
+
+inBasename=$(basename "$1")
+inExt="${inBasename##*.}"
+
+isVideoStr=$(ffprobe -v warning -show_streams "$1" | rg codec_type=video)
+if [ -n "$isVideoStr" ]
+then
+ isVideo=1
+ printf "Detected %s as a video file\n" "$inBasename"
+else
+ isVideo=0
+ printf "Detected %s as an audio file\n" "$inBasename"
+fi
+
+printf "Sample noise start time [00:00:00]: "
+read -r sampleStart
+if [ -z "$sampleStart" ] ; then sampleStart="00:00:00"; fi
+printf "Sample noise end time [00:00:00.900]: "
+read -r sampleEnd
+if [ -z "$sampleEnd" ] ; then sampleEnd="00:00:00.900"; fi
+printf "Noise reduction amount [0.21]: "
+read -r sensitivity
+if [ -z "$sensitivity" ] ; then sensitivity="0.21"; fi
+
+
+tmpVidFile="/tmp/noiseclean_tmpvid.$inExt"
+tmpAudFile="/tmp/noiseclean_tmpaud.wav"
+noiseAudFile="/tmp/noiseclean_noiseaud.wav"
+noiseProfFile="/tmp/noiseclean_noise.prof"
+tmpAudCleanFile="/tmp/noiseclean_tmpaud-clean.wav"
+
+printf "Cleaning noise on %s...\n" "$1"
+
+if [ $isVideo -eq "1" ]; then
+ ffmpeg -v warning -y -i "$1" -qscale:v 0 -vcodec copy -an "$tmpVidFile"
+ ffmpeg -v warning -y -i "$1" -qscale:a 0 "$tmpAudFile"
+else
+ cp "$1" "$tmpAudFile"
+fi
+ffmpeg -v warning -y -i "$1" -vn -ss "$sampleStart" -t "$sampleEnd" "$noiseAudFile"
+sox "$noiseAudFile" -n noiseprof "$noiseProfFile"
+sox "$tmpAudFile" "$tmpAudCleanFile" noisered "$noiseProfFile" "$sensitivity"
+if [ $isVideo -eq "1" ]; then
+ ffmpeg -v warning -y -i "$tmpAudCleanFile" -i "$tmpVidFile" -vcodec copy -qscale:v 0 -qscale:a 0 "$2"
+else
+ cp "$tmpAudCleanFile" "$2"
+fi
+
+printf "Done"
diff --git a/.local/bin/opout b/.local/bin/opout
new file mode 100755
index 0000000..d2b447a
--- /dev/null
+++ b/.local/bin/opout
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+# opout: "open output": A general handler for opening a file's intended output,
+# usually the pdf of a compiled document. I find this useful especially
+# running from vim.
+
+basename="${1%.*}"
+
+case "${*}" in
+ *.tex|*.sil|*.m[dse]|*.[rR]md|*.mom|*.[0-9]) target="$(getcomproot "$1" || echo "$1")" ; setsid -f xdg-open "${target%.*}".pdf >/dev/null 2>&1 ;;
+ *.html) setsid -f "$BROWSER" "$basename".html >/dev/null 2>&1 ;;
+ *.sent) setsid -f sent "$1" >/dev/null 2>&1 ;;
+esac
diff --git a/.local/bin/pauseallmpv b/.local/bin/pauseallmpv
new file mode 100755
index 0000000..d69a414
--- /dev/null
+++ b/.local/bin/pauseallmpv
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# You might notice all mpv commands are aliased to have this input-ipc-server
+# thing. That's just for this particular command, which allows us to pause
+# every single one of them with one command! This is bound to super + shift + p
+# (with other things) by default and is used in some other places.
+
+for i in $(ls /tmp/mpvSockets/*); do
+ echo '{ "command": ["set_property", "pause", true] }' | socat - "$i";
+done
diff --git a/.local/bin/peertubetorrent b/.local/bin/peertubetorrent
new file mode 100755
index 0000000..6821a40
--- /dev/null
+++ b/.local/bin/peertubetorrent
@@ -0,0 +1,9 @@
+#!/bin/sh
+# torrent peertube videos, requires the transadd script
+# first argument is the video link, second is the quality (360, 480 or 1080)
+# 13/07/20 - Arthur Bais
+
+instance=$(echo "$1" | sed "s|/w.\+||")
+vidid=$(echo "$1" | sed "s|.\+/||")
+link=$(curl -s "$instance/api/v1/videos/$vidid" | rg -o "$instance/download/torrents/.\{37\}$2.torrent")
+transadd "$link"
diff --git a/.local/bin/podentr b/.local/bin/podentr
new file mode 100755
index 0000000..9454b07
--- /dev/null
+++ b/.local/bin/podentr
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# entr command to run `queueandnotify` when newsboat queue is changed
+
+[ "$(pgrep -x "$(basename "$0")" | wc -l)" -gt 2 ] && exit
+
+echo "${XDG_DATA_HOME:-$HOME/.local/share}"/newsboat/queue | entr -p queueandnotify 2>/dev/null
diff --git a/.local/bin/portal b/.local/bin/portal
new file mode 100755
index 0000000..b0afa23
--- /dev/null
+++ b/.local/bin/portal
@@ -0,0 +1,5 @@
+#!/bin/sh
+sleep 1
+killall xdg-desktop-portal-wlr
+killall xdg-desktop-portal
+/lib/xdg-desktop-portal-wlr &
diff --git a/.local/bin/qndl b/.local/bin/qndl
new file mode 100755
index 0000000..48bc61e
--- /dev/null
+++ b/.local/bin/qndl
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# $1 is a url; $2 is a command
+[ -z "$1" ] && exit
+base="$(basename "$1")"
+notify-send "⏳ Queuing $base..."
+cmd="$2"
+[ -z "$cmd" ] && cmd="yt-dlp --embed-metadata -ic"
+idnum="$(tsp $cmd "$1")"
+realname="$(echo "$base" | sed "s/?\(source\|dest\).*//;s/%20/ /g")"
+tsp -D "$idnum" mv "$base" "$realname"
+tsp -D "$idnum" notify-send "👍 $realname done."
diff --git a/.local/bin/queueandnotify b/.local/bin/queueandnotify
new file mode 100755
index 0000000..1c3025c
--- /dev/null
+++ b/.local/bin/queueandnotify
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+# Podboat sucks. This script replaces it.
+# It reads the newsboat queue, queuing downloads with taskspooler.
+# It also removes the junk from extensions.
+queuefile="${XDG_DATA_HOME:-$HOME/.local/share}/newsboat/queue"
+
+while read -r line; do
+ [ -z "$line" ] && continue
+ url="${line%%[ ]*}"
+ qndl "$url" "curl -LO"
+done < "$queuefile"
+
+echo > "$queuefile"
diff --git a/.local/bin/randombg b/.local/bin/randombg
new file mode 100755
index 0000000..6e386ef
--- /dev/null
+++ b/.local/bin/randombg
@@ -0,0 +1,21 @@
+#!/bin/sh
+killall swaybg
+PIDFILE="/tmp/randombg.pid"
+# Check if the PID file exists and if the process is running
+if [ -e "$PIDFILE" ] && kill -0 "$(bat "$PIDFILE")"; then
+ echo "Another instance of the script is already running."
+ kill -9 "$(bat $PIDFILE)" # Forcefully kill the old process
+fi
+echo $$ > "$PIDFILE"
+trap 'rm -f "$PIDFILE"; exit' INT TERM EXIT
+
+swaybg -i $(fd . /mnt/ssd/papes -t f | shuf -n1) -m fill &
+OLD_PID=$!
+while true; do
+ sleep 300
+ swaybg -i $(fd . /mnt/ssd/papes -t f | shuf -n1) -m fill &
+ NEXT_PID=$!
+ sleep 5
+ kill $OLD_PID
+ OLD_PID=$NEXT_PID
+done
diff --git a/.local/bin/rssadd b/.local/bin/rssadd
new file mode 100755
index 0000000..13a525f
--- /dev/null
+++ b/.local/bin/rssadd
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+if echo "$1" | rg -q "https*://\S\+\.[A-Za-z]\+\S*" ; then
+ url="$1"
+else
+ url="$(rg -Eom1 '<[^>]+(rel="self"|application/[a-z]+\+xml)[^>]+>' "$1" |
+ rg -o "https?://[^\" ]")"
+
+ echo "$url" | rg -q "https*://\S\+\.[A-Za-z]\+\S*" ||
+ notify-send "That doesn't look like a full URL." && exit 1
+fi
+
+RSSFILE="${XDG_CONFIG_HOME:-$HOME/.config}/newsboat/urls"
+if awk '{print $1}' "$RSSFILE" | rg "^$url$" >/dev/null; then
+ notify-send "You already have this RSS feed."
+else
+ echo "$url" >> "$RSSFILE" && notify-send "RSS feed added."
+fi
diff --git a/.local/bin/rssget b/.local/bin/rssget
new file mode 100755
index 0000000..45064b7
--- /dev/null
+++ b/.local/bin/rssget
@@ -0,0 +1,115 @@
+#!/bin/bash
+
+# Searches the website for RSS feeds and adds them to newsboat url list. Can
+# also find hidden RSS feeds on various websites, namely Youtube, Reddit,
+# Vimeo, Github, Gitlab and Medium. Gets site url as $1 or (if not present)
+# from X clipboard. Gets tags as $2. If it finds more than one feed, calls
+# mew for the user to choose which one to add. I have bound it to a keyboard
+# shortcut so i copy a site link and easily add its feed to the reader.
+
+# Inspired by and based on the logic of this extension:
+# https://github.com/shevabam/get-rss-feed-url-extension
+
+# This script requires rssadd to add feeds to the list.
+
+getlink () {
+ local url="$1"
+ feeds="$(curl -s "$url" | rg -x '.*type=.*(rss|rdf|atom).*' | sed 's/ //g')"
+ url="$(echo $url | sed 's|^\(https://[^/]*/\).*|\1|')"
+
+ for rsspath in $feeds; do
+ rsspath="$(echo $rsspath | sed -n "s|.*href=['\"]\([^'\"]*\)['\"].*|\1|p")"
+ if echo "$rsspath" | rg "http" > /dev/null; then
+ link="$rsspath"
+ elif echo "$rsspath" | rg "^/" > /dev/null; then
+ link="$url$(echo $rsspath | sed 's|^/||')"
+ else
+ link="$url$rsspath"
+ fi
+ echo $link
+ done
+}
+
+getRedditRss() {
+ echo "${1%/}.rss"
+}
+
+getYoutubeRss() {
+ local url="$1"
+ path=$(echo "$url" | sed -e 's|^http[s]*://||')
+ case "$path" in
+ *"/channel/"*) channel_id="$(echo $path | sed -r 's|.*channel/([^/]*).*|\1|')" && feed="https://www.youtube.com/feeds/videos.xml?channel_id=${channel_id}" ;;
+ *"/c/"*|*"/user/"*)
+ feed=$(wget -q "$url" -O tmp_rssget_yt \
+ && sed -n 's|.*\("rssUrl":"[^"]*\).*|\1|; p' tmp_rssget_yt \
+ | rg rssUrl \
+ | sed 's|"rssUrl":"||') ;;
+ esac
+ echo "$feed"
+}
+
+getVimeoRss() {
+ local url="$1"
+ if echo "$url" | rg -q "/videos$"; then
+ feed_url=$(echo "$url" | sed 's/\/videos$//' | sed 's/\/$/\/rss/')
+ else
+ feed_url="${url}/videos/rss"
+ fi
+ echo "$feed_url"
+}
+
+getGithubRss () {
+ local url="${1%/}"
+ if echo $url | rg "github.com/[^/]*/[a-zA-Z0-9].*" >/dev/null ; then
+ echo "${url}/commits.atom"
+ echo "${url}/releases.atom"
+ echo "${url}/tags.atom"
+ elif echo $url | rg "github.com/[^/]*(/)" >/dev/null ; then
+ echo "${url}.atom"
+ fi
+}
+
+getGitlabRss () {
+ local url="${1%/}"
+ echo "${url}.atom"
+}
+
+getMediumRss () {
+ echo $1 | sed 's|/tag/|/feed/|'
+}
+
+
+if [ -n "$1" ] ; then
+ url="$1"
+else
+ url="$(wl-paste)"
+ [ -z "$url" ] && echo "usage: $0 url 'tag1 tag2 tag3'" && exit 1
+fi
+
+declare -a list=()
+
+yt_regex="^(http(s)?://)?((w){3}\.)?(youtube\.com|invidio\.us|invidious\.flokinet\.to|invidious\.materialio\.us|iv\.datura\.network|invidious\.perennialte\.ch|invidious\.fdn\.fr|invidious\.private\.coffee|invidious\.protokolla\.fi|invidious\.privacyredirect\.com|yt\.artemislena\.eu|yt\.drgnz\.club|invidious\.incogniweb\.net|yewtu\.be|inv\.tux\.pizza|invidious\.reallyaweso\.me|iv\.melmac\.space|inv\.us\.projectsegfau\.lt|inv\.nadeko\.net|invidious\.darkness\.services|invidious\.jing\.rocks|invidious\.privacydev\.net|inv\.in\.projectsegfau\.lt|invidious\.drgns\.space)/(channel|user|c).+"
+reddit_regex="^(http(s)?://)?((w){3}\.)?reddit\.com.*"
+vimeo_regex="^(http(s)?://)?((w){3}.)?vimeo\.com.*"
+if echo $url | rg -x "$yt_regex" >/dev/null ; then
+ list="$(getYoutubeRss "$url")"
+elif echo $url | rg -x "$reddit_regex" >/dev/null ; then
+ list="$(getRedditRss "$url")"
+# vimeo actually works with getlink
+elif echo $url | rg "$vimeo_regex" >/dev/null ; then
+ list="$(getVimeoRss "$url")"
+elif echo $url | rg "github.com" >/dev/null ; then
+ list="$(getGithubRss "$url")"
+# gitlab also works with getlink
+elif echo $url | rg "gitlab.com/[a-zA-Z0-9].*" >/dev/null ; then
+ list="$(getGitlabRss "$url")"
+elif echo $url | rg "medium.com/tag" >/dev/null ; then
+ list="$(getMediumRss "$url")"
+else
+ list="$(getlink "$url")"
+fi
+
+[ "$(echo "$list" | wc -l)" -eq 1 ] && chosen_link="$list" || chosen_link=$(printf '%s\n' "${list[@]}" | mew -p "Choose a feed:")
+tags="$2"
+ifinstalled rssadd && rssadd "$chosen_link" "$tags"
+echo "$chosen_link" "$tags"
diff --git a/.local/bin/sd b/.local/bin/sd
new file mode 100755
index 0000000..6ac08a6
--- /dev/null
+++ b/.local/bin/sd
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# Open a terminal window in the same directory as the currently active window.
+
+windowPID=$(hyprctl activewindow | rg -oP '^\s*pid:\s*\K.*\S.*')
+PIDlist=$(pstree -lpATna "$windowPID" | sed -En 's/.*,([0-9]+).*/\1/p' | tac)
+for PID in $PIDlist; do
+ cmdline=$(ps -o args= -p "$PID")
+ process_group_leader=$(ps -o comm= -p "$(ps -o pgid= -p "$PID" | tr -d ' ')")
+ cwd=$(readlink /proc/"$PID"/cwd)
+ # zsh and yazi won't be ignored even if it shows ~ or /
+ case "$cmdline" in
+ 'Yazi') continue ;;
+ "${SHELL##*/}"|'yazi'|'yazi '*) break ;;
+ esac
+ # git (and its sub-processes) will show the root of a repository instead of the actual cwd, so they're ignored
+ [ "$process_group_leader" = 'git' ] || [ ! -d "$cwd" ] && continue
+ # This is to ignore programs that show ~ or / instead of the actual working directory
+ [ "$cwd" != "$HOME" ] && [ "$cwd" != '/' ] && break
+done
+[ "$PWD" != "$cwd" ] && [ -d "$cwd" ] && { cd "$cwd" || exit 1; }
+"$TERMINAL"
diff --git a/.local/bin/setbg b/.local/bin/setbg
new file mode 100755
index 0000000..e6d4d01
--- /dev/null
+++ b/.local/bin/setbg
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+# This script does the following:
+# Run by itself, set the wallpaper (at X start).
+# If given a file, set that as the new wallpaper.
+# If given a directory, choose random file in it.
+# If wal is installed, also generates a colorscheme.
+
+# Location of link to wallpaper link.
+bgloc="${XDG_DATA_HOME:-$HOME/.local/share}/bg"
+
+# Configuration files of applications that have their themes changed by pywal.
+dunstconf="${XDG_CONFIG_HOME:-$HOME/.config}/dunst/dunstrc"
+zathuraconf="${XDG_CONFIG_HOME:-$HOME/.config}/zathura/zathurarc"
+
+# Give -s as parameter to make notifications silent.
+while getopts "s" o; do case "${o}" in
+ s) silent='1' ;;
+esac done
+
+shift $((OPTIND - 1))
+
+trueloc="$(readlink -f "$1")" &&
+case "$(file --mime-type -b "$trueloc")" in
+ image/* ) ln -sf "$trueloc" "$bgloc" && [ -z "$silent" ] && notify-send -i "$bgloc" "Changing wallpaper..." ;;
+ inode/directory ) ln -sf "$(find "$trueloc" -iregex '.*.\(jpg\|jpeg\|png\|gif\)' -type f | shuf -n 1)" "$bgloc" && [ -z "$silent" ] && notify-send -i "$bgloc" "Random Wallpaper chosen." ;;
+ *) [ -z "$silent" ] && notify-send "🖼️ Error" "Not a valid image or directory." ; exit 1;;
+esac
+
+# If pywal is installed, use it.
+if command -v wal >/dev/null 2>&1 ; then
+ wal -n -i "$(readlink -f $bgloc)" -o "${XDG_CONFIG_HOME:-$HOME/.config}/wal/postrun" >/dev/null 2>&1
+# If pywal is removed, return config files to normal.
+else
+ [ -f "$dunstconf.bak" ] && unlink "$dunstconf" && mv "$dunstconf.bak" "$dunstconf"
+ [ -f "$zathuraconf.bak" ] && unlink "$zathuraconf" && mv "$zathuraconf.bak" "$zathuraconf"
+fi
+
+killall swaybg
+swaybg -i "$bgloc" -m fill &
+# If running, dwm hit the key to refresh the color scheme.
+# pidof dwm >/dev/null && xdotool key super+F5
diff --git a/.local/bin/shortcuts b/.local/bin/shortcuts
new file mode 100755
index 0000000..bc2fb9e
--- /dev/null
+++ b/.local/bin/shortcuts
@@ -0,0 +1,59 @@
+#!/bin/sh
+
+bmdirs="${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-dirs"
+bmfiles="${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-files"
+
+# Output locations. Unactivated progs should go to /dev/null.
+shell_shortcuts="${XDG_CONFIG_HOME:-$HOME/.config}/shell/shortcutrc"
+shell_env_shortcuts="${XDG_CONFIG_HOME:-$HOME/.config}/shell/shortcutenvrc"
+zsh_named_dirs="${XDG_CONFIG_HOME:-$HOME/.config}/shell/zshnameddirrc"
+lf_shortcuts="/dev/null"
+vim_shortcuts="/dev/null"
+qute_shortcuts="/dev/null"
+fish_shortcuts="/dev/null"
+vifm_shortcuts="/dev/null"
+yazi_shortcuts="${XDG_CONFIG_HOME:-$HOME/.config}/yazi/keymap.toml"
+
+# Remove, prepare files
+rm -f "$lf_shortcuts" "$qute_shortcuts" "$zsh_named_dirs" "$vim_shortcuts" "$yazi_shortcuts" 2>/dev/null
+printf "# vim: filetype=sh\\n" > "$fish_shortcuts"
+printf "# vim: filetype=sh\\nalias " > "$shell_shortcuts"
+printf "# vim: filetype=sh\\n" > "$shell_env_shortcuts"
+printf "\" vim: filetype=vim\\n" > "$vifm_shortcuts"
+
+# Format the `directories` file in the correct syntax and sent it to all three configs.
+eval "echo \"$(bat "$bmdirs")\"" | \
+awk "!/^\s*#/ && !/^\s*\$/ {gsub(\"\\\s*#.*$\",\"\");
+ printf(\"%s=\42cd %s && ls -A\42 \\\\\n\",\$1,\$2) >> \"$shell_shortcuts\" ;
+ printf(\"[ -n \42%s\42 ] && export %s=\42%s\42 \n\",\$1,\$1,\$2) >> \"$shell_env_shortcuts\" ;
+ printf(\"hash -d %s=%s \n\",\$1,\$2) >> \"$zsh_named_dirs\" ;
+ printf(\"abbr %s \42cd %s; and ls -A\42\n\",\$1,\$2) >> \"$fish_shortcuts\" ;
+ printf(\"map g%s :cd %s<CR>\nmap t%s <tab>:cd %s<CR><tab>\nmap M%s <tab>:cd %s<CR><tab>:mo<CR>\nmap Y%s <tab>:cd %s<CR><tab>:co<CR> \n\",\$1,\$2, \$1, \$2, \$1, \$2, \$1, \$2) >> \"$vifm_shortcuts\" ;
+ printf(\"config.bind(';%s', \42set downloads.location.directory %s ;; hint links download\42) \n\",\$1,\$2) >> \"$qute_shortcuts\" ;
+ printf(\"map C%s cd \42%s\42 \n\",\$1,\$2) >> \"$lf_shortcuts\" ;
+ printf(\"cmap ;%s %s\n\",\$1,\$2) >> \"$vim_shortcuts\" ;
+ split(\$1, a, \"\")
+ chars = \"\"
+ for (i = 1; i <= length(a); i++) {
+ chars = chars sprintf(\"\\\"%s\\\"\", a[i])
+ if (i < length(a)) chars = chars \", \"
+ }
+ printf(\"[[mgr.prepend_keymap]]\\non = [\\\"g\\\", %s]\\nrun = \\\"cd %s\\\"\\n\\n\", chars, \$2) >> \"$yazi_shortcuts\" }"
+
+# Format the `files` file in the correct syntax and sent it to both configs.
+eval "echo \"$(bat "$bmfiles")\"" | \
+awk "!/^\s*#/ && !/^\s*\$/ {gsub(\"\\\s*#.*$\",\"\");
+ printf(\"%s=\42\$EDITOR %s\42 \\\\\n\",\$1,\$2) >> \"$shell_shortcuts\" ;
+ printf(\"[ -n \42%s\42 ] && export %s=\42%s\42 \n\",\$1,\$1,\$2) >> \"$shell_env_shortcuts\" ;
+ printf(\"hash -d %s=%s \n\",\$1,\$2) >> \"$zsh_named_dirs\" ;
+ printf(\"abbr %s \42\$EDITOR %s\42 \n\",\$1,\$2) >> \"$fish_shortcuts\" ;
+ printf(\"map %s :e %s<CR> \n\",\$1,\$2) >> \"$vifm_shortcuts\" ;
+ printf(\"map E%s \$\$EDITOR \42%s\42 \n\",\$1,\$2) >> \"$lf_shortcuts\" ;
+ printf(\"cmap ;%s %s\n\",\$1,\$2) >> \"$vim_shortcuts\" ;
+ split(\$1, a, \"\")
+ chars = \"\"
+ for (i = 1; i <= length(a); i++) {
+ chars = chars sprintf(\"\\\"%s\\\"\", a[i])
+ if (i < length(a)) chars = chars \", \"
+ }
+ printf(\"[[mgr.prepend_keymap]]\\non = [\\\"e\\\", %s]\\nrun = 'shell --block \\\"\$EDITOR %s\\\"'\\n\\n\", chars, \$2) >> \"$yazi_shortcuts\" }"
diff --git a/.local/bin/singboxwrap b/.local/bin/singboxwrap
new file mode 100755
index 0000000..e52db36
--- /dev/null
+++ b/.local/bin/singboxwrap
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+config_dir="/mnt/ssd/settings/sing-box"
+default_path="${XDG_DATA_HOME:-$HOME/.local/share}/singboxcfg"
+
+input=$1
+
+run_singbox () {
+ sing-box check -c "$1" && {
+ pidof sing-box >/dev/null && killall sing-box
+ setsid -f sing-box -c "$1" run
+ if [ "$input" = menu ]; then
+ notify-send "sing-box with $(readlink "$1") is running now"
+ fi
+ } || notify-send "Config check has failed. Check your configuration at $(readlink $1)" & exit 1
+}
+
+choose_menu () {
+ choose="$(fd . $config_dir -d 1 -t f | mew -p "Config to use")"
+ [ -n "$choose" ] || exit 1
+ ln -sf "$choose" "$default_path"
+ echo "$default_path"
+}
+
+if [ ! -f "$default_path" ]; then
+ input="menu"
+fi
+
+case $input in
+ menu) run_singbox $(choose_menu) ;;
+ *) run_singbox $default_path ;;
+esac
diff --git a/.local/bin/slider b/.local/bin/slider
new file mode 100755
index 0000000..a7615f7
--- /dev/null
+++ b/.local/bin/slider
@@ -0,0 +1,126 @@
+#!/bin/sh
+
+# Give a file with images and timecodes and creates a video slideshow of them.
+#
+# Timecodes must be in format 00:00:00.
+#
+# Imagemagick and ffmpeg required.
+
+# Application cache if not stated elsewhere.
+cache="${XDG_CACHE_HOME:-$HOME/.cache}/slider"
+
+while getopts "hvrpi:c:a:o:d:f:t:e:x:s:" o; do case "${o}" in
+ c) bgc="$OPTARG" ;;
+ t) fgc="$OPTARG" ;;
+ f) font="$OPTARG" ;;
+ i) file="$OPTARG" ;;
+ a) audio="$OPTARG" ;;
+ o) outfile="$OPTARG" ;;
+ d) prepdir="$OPTARG" ;;
+ r) redo="$OPTARG" ;;
+ s) ppt="$OPTARG" ;;
+ e) endtime="$OPTARG" ;;
+ x) res="$OPTARG"
+ echo "$res" | rg -qv "^[0-9]\+x[0-9]\+$" &&
+ echo "Resolution must be dimensions separated by a 'x': 1280x720, etc." &&
+ exit 1 ;;
+ p) echo "Purge old build files in $cache? [y/N]"
+ read -r confirm
+ echo "$confirm" | rg -iq "^y$" && rm -rf "$cache" && echo "Done."
+ exit ;;
+ v) verbose=True ;;
+ *) echo "$(basename "$0") usage:
+ -i input timecode list (required)
+ -a audio file
+ -c color of background (use html names, black is default)
+ -t text color for text slides (white is default)
+ -s text font size for text slides (150 is default)
+ -f text font for text slides (sans serif is default)
+ -o output video file
+ -e if no audio given, the time in seconds that the last slide will be shown (5 is default)
+ -x resolution (1920x1080 is default)
+ -d tmp directory
+ -r rerun imagemagick commands even if done previously (in case files or background has changed)
+ -p purge old build files instead of running
+ -v be verbose" && exit 1
+
+esac done
+
+# Check that the input file looks like it should.
+{ head -n 1 "$file" 2>/dev/null | rg -q "^00:00:00 " ;} || {
+ echo "Give an input file with -i." &&
+ echo "The file should look as this example:
+
+00:00:00 first_image.jpg
+00:00:03 otherdirectory/next_image.jpg
+00:00:09 this_image_starts_at_9_seconds.jpg
+etc...
+
+Timecodes and filenames must be separated by Tabs." &&
+ exit 1
+ }
+
+if [ -n "${audio+x}" ]; then
+ # Check that the audio file looks like an actual audio file.
+ case "$(file --dereference --brief --mime-type -- "$audio")" in
+ audio/*) ;;
+ *) echo "That doesn't look like an audio file."; exit 1 ;;
+ esac
+ totseconds="$(date '+%s' -d $(ffmpeg -i "$audio" 2>&1 | awk '/Duration/ {print $2}' | sed s/,//))"
+fi
+
+prepdir="${prepdir:-$cache/$file}"
+outfile="${outfile:-$file.mp4}"
+prepfile="$prepdir/$file.prep"
+
+[ -n "${verbose+x}" ] && echo "Preparing images... May take a while depending on the number of files."
+mkdir -p "$prepdir"
+
+{
+while read -r x;
+do
+ # Get the time from the first column.
+ time="${x%% *}"
+ seconds="$(date '+%s' -d "$time")"
+ # Duration is not used on the first looped item.
+ duration="$((seconds - prevseconds))"
+
+ # Get the filename/text content from the rest.
+ content="${x#* }"
+ base="$(basename "$content")"
+ base="${base%.*}.jpg"
+
+ if [ -f "$content" ]; then
+ # If images have already been made in a previous run, do not recreate
+ # them unless -r was given.
+ { [ ! -f "$prepdir/$base" ] || [ -n "${redo+x}" ] ;} &&
+ magick -size "${res:-1920x1080}" canvas:"${bgc:-black}" -gravity center "$content" -resize 1920x1080 -composite "$prepdir/$base"
+ else
+ { [ ! -f "$prepdir/$base" ] || [ -n "${redo+x}" ] ;} &&
+ magick -size "${res:-1920x1080}" -background "${bgc:-black}" -fill "${fgc:-white}" -font "${font:-Sans}" -pointsize "${ppt:-150}" -gravity center label:"$content" "$prepdir/$base"
+ fi
+
+ # If the first line, do not write yet.
+ [ "$time" = "00:00:00" ] || echo "file '$prevbase'
+duration $duration"
+
+ # Keep the information required for the next file.
+ prevbase="$base"
+ prevtime="$time"
+ prevseconds="$(date '+%s' -d "$prevtime")"
+done < "$file"
+# Do last file which must be given twice as follows
+endtime="$((totseconds-seconds))"
+echo "file '$base'
+duration ${endtime:-5}
+file '$base'"
+} > "$prepfile"
+if [ -n "${audio+x}" ]; then
+ ffmpeg -hide_banner -y -f concat -safe 0 -i "$prepfile" -i "$audio" -c:a aac -vsync vfr -c:v libx264 -pix_fmt yuv420p "$outfile"
+else
+ ffmpeg -hide_banner -y -f concat -safe 0 -i "$prepfile" -vsync vfr -c:v libx264 -pix_fmt yuv420p "$outfile"
+fi
+
+# Might also try:
+# -vf "fps=${fps:-24},format=yuv420p" "$outfile"
+# but has given some problems.
diff --git a/.local/bin/start-pipewire b/.local/bin/start-pipewire
new file mode 100755
index 0000000..63fc043
--- /dev/null
+++ b/.local/bin/start-pipewire
@@ -0,0 +1,5 @@
+#!/bin/sh
+killall pipewire
+killall pipewire-pulse
+killall wireplumber
+setsid -f pipewire
diff --git a/.local/bin/statusbar/sb-battery b/.local/bin/statusbar/sb-battery
new file mode 100755
index 0000000..0e25e72
--- /dev/null
+++ b/.local/bin/statusbar/sb-battery
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+# Prints all batteries, their percentage remaining and an emoji corresponding
+# to charge status (🔌 for plugged up, 🔋 for discharging on battery, etc.).
+
+case $BLOCK_BUTTON in
+ 3) notify-send "🔋 Battery module" "🔋: discharging
+ 🛑: not charging
+ ♻: stagnant charge
+ 🔌: charging
+ ⚡: charged
+ ❗: battery very low!
+ - Scroll to change adjust xbacklight." ;;
+ 4) xbacklight -inc 10 ;;
+ 5) xbacklight -dec 10 ;;
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 ;;
+esac
+
+# Loop through all attached batteries and format the info
+for battery in /sys/class/power_supply/BAT?*; do
+ # If non-first battery, print a space separator.
+ [ -n "${capacity+x}" ] && printf " "
+ # Sets up the status and capacity
+ case "$(bat "$battery/status" 2>&1)" in
+ "Full") status="⚡" ;;
+ "Discharging") status="🔋" ;;
+ "Charging") status="🔌" ;;
+ "Not charging") status="🛑" ;;
+ "Unknown") status="♻️" ;;
+ *) exit 1 ;;
+ esac
+ capacity="$(bat "$battery/capacity" 2>&1)"
+ # Will make a warn variable if discharging and low
+ [ "$status" = "🔋" ] && [ "$capacity" -le 25 ] && warn="❗"
+ # Prints the info
+ printf "%s%s%d%%" "$status" "$warn" "$capacity"; unset warn
+done && printf "\\n"
diff --git a/.local/bin/statusbar/sb-brightness b/.local/bin/statusbar/sb-brightness
new file mode 100755
index 0000000..30fe76b
--- /dev/null
+++ b/.local/bin/statusbar/sb-brightness
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# current brightness
+curr_brightness=$(bat /sys/class/backlight/*/brightness)
+
+# max_brightness
+max_brightness=$(bat /sys/class/backlight/*/max_brightness)
+
+# brightness percentage
+brightness_per=$((100 * curr_brightness / max_brightness))
+
+case $BLOCK_BUTTON in
+ 1)
+ ;;
+ 3)
+ notify-send "💡 Brightness module" "\- Shows current brightness level ☀️."
+ ;;
+ 8)
+ setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1
+ ;;
+esac
+
+echo "💡 ${brightness_per}%"
diff --git a/.local/bin/statusbar/sb-clock b/.local/bin/statusbar/sb-clock
new file mode 100755
index 0000000..d23af8d
--- /dev/null
+++ b/.local/bin/statusbar/sb-clock
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+clock=$(date '+%I')
+
+case "$clock" in
+ "00") icon="🕛" ;;
+ "01") icon="🕐" ;;
+ "02") icon="🕑" ;;
+ "03") icon="🕒" ;;
+ "04") icon="🕓" ;;
+ "05") icon="🕔" ;;
+ "06") icon="🕕" ;;
+ "07") icon="🕖" ;;
+ "08") icon="🕗" ;;
+ "09") icon="🕘" ;;
+ "10") icon="🕙" ;;
+ "11") icon="🕚" ;;
+ "12") icon="🕛" ;;
+esac
+
+case $BLOCK_BUTTON in
+ 1) notify-send "This Month" "$(cal | sed "s/\<$(date +'%e'|tr -d ' ')\>/<b><span color='red'>&<\/span><\/b>/")" && notify-send "Appointments" "$(calcurse -d3)" ;;
+ 2) setsid -f "$TERMINAL" -e calcurse >/dev/null 2>&1 ;;
+ 3) notify-send "📅 Time/date module" "\- Left click to show upcoming appointments for the next three days via \`calcurse -d3\` and show the month via \`cal\`
+- Middle click opens calcurse if installed" ;;
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 ;;
+esac
+
+date "+%Y %b %d (%a) $icon%H:%M"
diff --git a/.local/bin/statusbar/sb-cpu b/.local/bin/statusbar/sb-cpu
new file mode 100755
index 0000000..e9c9cae
--- /dev/null
+++ b/.local/bin/statusbar/sb-cpu
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+case $BLOCK_BUTTON in
+ 1) notify-send "🖥 CPU hogs" "$(ps axch -o cmd,%cpu | awk '{cmd[$1]+=$2} END {for (i in cmd) print i, cmd[i]}' | sort -nrk2 | head)\\n(100% per core)" ;;
+ 2) setsid -f "$TERMINAL" -e btop >/dev/null 2>&1 ;;
+ 3) notify-send "🖥 CPU module " "\- Shows CPU temperature.
+- Click to show intensive processes.
+- Middle click to open btop." ;;
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 ;;
+esac
+
+sensors | awk '/Core 0/ {print "🌡" $3}'
diff --git a/.local/bin/statusbar/sb-cpubars b/.local/bin/statusbar/sb-cpubars
new file mode 100755
index 0000000..a0d5dce
--- /dev/null
+++ b/.local/bin/statusbar/sb-cpubars
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+# Module showing CPU load as a changing bars.
+# Just like in polybar.
+# Each bar represents amount of load on one core since
+# last run.
+
+# Cache in tmpfs to improve speed and reduce SSD load
+cache=/tmp/cpubarscache
+
+case $BLOCK_BUTTON in
+ 2) setsid -f "$TERMINAL" -e btop >/dev/null 2>&1 ;;
+ 3) notify-send "🪨 CPU load module" "Each bar represents
+one CPU core";;
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 ;;
+esac
+
+# id total idle
+stats=$(awk '/cpu[0-9]+/ {printf "%d %d %d\n", substr($1,4), ($2 + $3 + $4 + $5), $5 }' /proc/stat)
+[ ! -f $cache ] && echo "$stats" > "$cache"
+old=$(bat "$cache")
+printf "🪨"
+echo "$stats" | while read -r row; do
+ id=${row%% *}
+ rest=${row#* }
+ total=${rest%% *}
+ idle=${rest##* }
+
+ case "$(echo "$old" | awk '{if ($1 == id)
+ printf "%d\n", (1 - (idle - $3) / (total - $2))*100 /12.5}' \
+ id="$id" total="$total" idle="$idle")" in
+
+ "0") printf "▁";;
+ "1") printf "▂";;
+ "2") printf "▃";;
+ "3") printf "▄";;
+ "4") printf "▅";;
+ "5") printf "▆";;
+ "6") printf "▇";;
+ "7") printf "█";;
+ "8") printf "█";;
+ esac
+done; printf "\\n"
+echo "$stats" > "$cache"
diff --git a/.local/bin/statusbar/sb-disk b/.local/bin/statusbar/sb-disk
new file mode 100755
index 0000000..adfa0e3
--- /dev/null
+++ b/.local/bin/statusbar/sb-disk
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# Status bar module for disk space
+# $1 should be drive mountpoint, otherwise assumed /.
+
+location=${1:-/}
+
+[ -d "$location" ] || exit
+
+case $BLOCK_BUTTON in
+ 1) notify-send "💽 Disk space" "$(df -h --output=target,used,size)" ;;
+ 3) notify-send "💽 Disk module" "\- Shows used hard drive space.
+- Click to show all disk info." ;;
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 ;;
+esac
+
+case "$location" in
+ "/home"* ) icon="🏠" ;;
+ "/mnt"* ) icon="💾" ;;
+ *) icon="🖥";;
+esac
+
+printf "%s: %s\n" "$icon" "$(df -h "$location" | awk ' /[0-9]/ {print $3 "/" $2}')"
diff --git a/.local/bin/statusbar/sb-doppler b/.local/bin/statusbar/sb-doppler
new file mode 100755
index 0000000..1930752
--- /dev/null
+++ b/.local/bin/statusbar/sb-doppler
@@ -0,0 +1,241 @@
+#!/bin/sh
+
+# Show a Doppler RADAR of a user's preferred location.
+
+secs=600 # Download a new doppler radar if one hasn't been downloaded in $secs seconds.
+radarloc="${XDG_CACHE_HOME:-$HOME/.cache}/radar"
+doppler="${XDG_CACHE_HOME:-$HOME/.cache}/doppler.gif"
+
+pickloc() { chosen="$(echo "US: CONUS: Continental United States
+US: Northeast
+US: Southeast
+US: PacNorthWest
+US: PacSouthWest
+US: UpperMissVly
+US: SouthMissVly
+US: SouthPlains
+US: NorthRockies
+US: SouthRockies
+US: Alaska
+US: Carib
+US: Hawaii
+US: CentGrLakes
+US: Conus-Large
+US: KABR: Aberdeen, SD
+US: KBIS: Bismarck, ND
+US: KFTG: Denver/Boulder, CO
+US: KDMX: Des Moines, IA
+US: KDTX: Detroit, MI
+US: KDDC: Dodge City, KS
+US: KDLH: Duluth, MN
+US: KCYS: Cheyenne, WY
+US: KLOT: Chicago, IL
+US: KGLD: Goodland, KS
+US: KUEX: Hastings, NE
+US: KGJX: Grand Junction, CO
+US: KGRR: Grand Rapids, MI
+US: KMVX: Fargo/Grand Forks, ND
+US: KGRB: Green Bay, WI
+US: KIND: Indianapolis, IN
+US: KJKL: Jackson, KY
+US: KARX: La Crosse, WI
+US: KILX: Lincoln/Central Illinois, IL
+US: KLVX: Louisville, KY
+US: KMQT: Marquette
+US: KMKX: Milwaukee, WI
+US: KMPX: Minneapolis, MN
+US: KAPX: Gaylord/Alpena, MI
+US: KLNX: North Platte, NE
+US: KIWX: N. Webster/Northern, IN
+US: KOAX: Omaha, NE
+US: KPAH: Paducah, KY
+US: KEAX: Pleasant Hill, MO
+US: KPUX: Pueblo, CO
+US: KDVN: Quad Cities, IA
+US: KUDX: Rapid City, SD
+US: KRIW: Riverton, WY
+US: KSGF: Springfield, MO
+US: KLSX: St. LOUIS, MO
+US: KFSD: Sioux Falls, SD
+US: KTWX: Topeka, KS
+US: KICT: Wichita, KS
+US: KVWX: Paducah, KY
+US: ICAO: Responsible Wfo
+US: KLTX: WILMINGTON, NC
+US: KCCX: State College/Central, PA
+US: KLWX: Sterling, VA
+US: KFCX: Blacksburg/Roanoke, VA
+US: KRAX: Raleigh/Durham, NC
+US: KGYX: Portland, ME
+US: KDIX: Mt Holly/Philadelphia, PA
+US: KPBZ: Pittsburgh, PA
+US: KAKQ: Wakefield, VA
+US: KMHX: Morehead City, NC
+US: KGSP: Greer/Greenville/Sprtbg, SC
+US: KILN: Wilmington/Cincinnati, OH
+US: KCLE: Cleveland, OH
+US: KCAE: Columbia, SC
+US: KBGM: Binghamton, NY
+US: KENX: Albany, NY
+US: KBUF: Buffalo, NY
+US: KCXX: Burlington, VT
+US: KCBW: Caribou, ME
+US: KBOX: Boston /Taunton, MA
+US: KOKX: New York City, NY
+US: KCLX: Charleston, SC
+US: KRLX: Charleston, WV
+US: ICAO: Responsible WFO
+US: KBRO: Brownsville, TX
+US: KABX: Albuquerque, NM
+US: KAMA: Amarillo, TX
+US: KFFC: Peachtree City/Atlanta, GA
+US: KEWX: Austin/Sanantonio, TX
+US: KBMX: Birmingham, AL
+US: KCRP: Corpus Christi, TX
+US: KFWS: Dallas / Ft. Worth, TX
+US: KEPZ: El Paso, TX
+US: KHGX: Houston/ Galveston, TX
+US: KJAX: Jacksonville, FL
+US: KBYX: Key West, FL
+US: KMRX: Morristown/knoxville, TN
+US: KLBB: Lubbock, TX
+US: KLZK: Little Rock, AR
+US: KLCH: Lake Charles, LA
+US: KOHX: Nashville, TN
+US: KMLB: Melbourne, FL
+US: KNQA: Memphis, TN
+US: KAMX: Miami, FL
+US: KMAF: Midland/odessa, TX
+US: KTLX: Norman, OK
+US: KHTX: Huntsville, AL
+US: KMOB: Mobile, AL
+US: KTLH: Tallahassee, FL
+US: KTBW: Tampa Bay Area, FL
+US: KSJT: San Angelo, TX
+US: KINX: Tulsa, OK
+US: KSRX: Tulsa, OK
+US: KLIX: New Orleans/slidell, LA
+US: KDGX: Jackson, MS
+US: KSHV: Shreveport, LA
+US: ICAO: Responsible WFO
+US: KLGX: Seattle / Tacoma, WA
+US: KOTX: Spokane, WA
+US: KEMX: Tucson, AZ
+US: KYUX: Phoenix, AZ
+US: KNKX: San Diego, CA
+US: KMUX: Monterey/san Francisco, CA
+US: KHNX: San Joaquin/hanford, CA
+US: KSOX: San Diego, CA
+US: KATX: Seattle / Tacoma, WA
+US: KIWA: Phoenix, AZ
+US: KRTX: Portland, OR
+US: KSFX: Pocatello, ID
+US: KRGX: Reno, NV
+US: KDAX: Sacramento, CA
+US: KMTX: Salt Lake City, UT
+US: KPDT: Pendleton, OR
+US: KMSX: Missoula, MT
+US: KESX: Las Vegas, NV
+US: KVTX: Los Angeles, CA
+US: KMAX: Medford, OR
+US: KFSX: Flagstaff, AZ
+US: KGGW: Glasgow, MT
+US: KLRX: Elko, NV
+US: KBHX: Eureka, CA
+US: KTFX: Great Falls, MT
+US: KCBX: Boise, ID
+US: KBLX: Billings, MT
+US: KICX: Salt Lake City, UT
+US: ICAO: Responsible Wfo W/ MSCF
+US: PABC: Anchorage, AK
+US: PAPD: Fairbanks, AK
+US: PHKM: Honolulu, HI
+US: PAHG: Anchorage, AK
+US: PAKC: Anchorage, AK
+US: PAIH: Anchorage, AK
+US: PHMO: Honolulu, HI
+US: PAEC: Fairbanks, AK
+US: TJUA: San Juan, PR
+US: PACG: Juneau, AK
+US: PHKI: Honolulu, HI
+US: PHWA: Honolulu, HI
+US: ICAO: Responsible Wfo W/ MSCF
+US: KFDR: Norman, OK
+US: PGUA: Guam
+US: KBBX: Sacramento, CA
+US: KFDX: Albuquerque, NM
+US: KGWX: Jackson, MS
+US: KDOX: Wakefield, VA
+US: KDYX: San Angelo, TX
+US: KEYX: Las Vegas, NV
+US: KEVX: Mobile, AL
+US: KHPX: Paducah, KY
+US: KTYX: Burlington, VT
+US: KGRK: Dallas / Ft. Worth, TX
+US: KPOE: Lake Charles, LA
+US: KEOX: Tallahassee, FL
+US: KHDX: El Paso, TX
+US: KDFX: San Antonio, TX
+US: KMXX: Birmingham, AL
+US: KMBX: Bismarck, ND
+US: KVAX: Jacksonville, FL
+US: KJGX: Peachtree City/atlanta, GA
+US: KVNX: Norman, OK
+US: KVBX: Vandenberg Afb: Orcutt, CA
+DE: BAW: Baden-Württemberg
+DE: BAY: Bavaria
+DE: BBB: Berlin
+DE: BBB: Brandenburg
+DE: HES: Hesse
+DE: MVP: Mecklenburg-Western Pomerania
+DE: NIB: Lower Saxony
+DE: NIB: Bremen
+DE: NRW: North Rhine-Westphalia
+DE: RPS: Rhineland-Palatinate
+DE: RPS: Saarland
+DE: SAC: Saxony
+DE: SAA: Saxony-Anhalt
+DE: SHH: Schleswig-Holstein
+DE: SHH: Hamburg
+DE: THU: Thuringia
+NL: The Netherlands
+RU: Russian Federation" | mew -i -l 50 -p "Select a radar to use as default:")"
+
+# Ensure user did not escape.
+[ -z "$chosen" ] && exit 1
+
+# Set country code and radar code.
+countrycode=${chosen%%:*}
+radarcode=${chosen#* } radarcode=${radarcode%:*}
+
+# Print codes to $radarloc file.
+ printf "%s,%s\\n" "$countrycode" "$radarcode" > "$radarloc" ;}
+
+getdoppler() {
+ country=$(cut -c -2 "$radarloc")
+ province=$(cut -c 4- "$radarloc")
+ notify-send "🌦️ Doppler RADAR" "Pulling most recent Doppler RADAR for $province."
+ case "$country" in
+ "US") province="$(echo "$province" | tr "[:lower:]" "[:upper:]")"
+ curl -sL "https://radar.weather.gov/ridge/standard/${province}_loop.gif" > "$doppler" ;;
+ "DE") province="$(echo "$province" | tr "[:upper:]" "[:lower:]")"
+ curl -sL "https://www.dwd.de/DWD/wetter/radar/radfilm_${province}_akt.gif" > "$doppler" ;;
+ "NL") curl -sL "https://cdn.knmi.nl/knmi/map/general/weather-map.gif" > "$doppler" ;;
+ "RU") curl -sL "https://meteoinfo.ru/hmc-output/rmap/phenomena.gif" > "$doppler" ;;
+ esac
+}
+
+showdoppler() { setsid -f mpv --no-osc --loop=inf --no-terminal "$doppler" >/dev/null 2>&1 ;}
+
+case $BLOCK_BUTTON in
+ 1) [ ! -f "$radarloc" ] && pickloc && getdoppler
+ [ $(($(date '+%s') - $(stat -c %Y "$doppler"))) -gt "$secs" ] && getdoppler
+ showdoppler ;;
+ 2) pickloc && getdoppler && showdoppler ;;
+ 3) notify-send "🗺️ Doppler RADAR module" "\- Left click for local Doppler RADAR.
+- Middle click to update RADAR location.
+After $secs seconds, new clicks will also automatically update the doppler RADAR." ;;
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 ;;
+esac
+
+echo 🌅
diff --git a/.local/bin/statusbar/sb-forecast b/.local/bin/statusbar/sb-forecast
new file mode 100755
index 0000000..eb07dfe
--- /dev/null
+++ b/.local/bin/statusbar/sb-forecast
@@ -0,0 +1,65 @@
+#!/bin/sh
+
+# Displays today's precipication chance (☔), and daily low (🥶) and high (🌞).
+# Usually intended for the statusbar.
+
+url="${WTTRURL:-wttr.in}"
+weatherreport="${XDG_CACHE_HOME:-$HOME/.cache}/weatherreport"
+
+# Get a weather report from 'wttr.in' and save it locally.
+getforecast() { { rg -q -m1 '^up$' /sys/class/net/w*/operstate || rg -q -m1 '^up$' /sys/class/net/e*/operstate; } &&
+ curl -sf "$url/$LOCATION" --output "$weatherreport" && touch "$weatherreport"
+}
+
+# Forecast should be updated only once a day.
+checkforecast() {
+ [ "$(stat -c %y "$weatherreport" 2>/dev/null |
+ cut -d' ' -f1)" = "$(date '+%Y-%m-%d')" ]
+}
+
+getprecipchance() {
+ echo "$weatherdata" | sed '16q;d' | # Extract line 16 from file
+ rg -wo "[0-9]*%" | # Find a sequence of digits followed by '%'
+ sort -rn | # Sort in descending order
+ head -1q # Extract first line
+}
+
+getdailyhighlow() {
+ echo "$weatherdata" | sed '13q;d' | # Extract line 13 from file
+ rg -o "m[-+]?[0-9]+" | # Find temperatures in the format "m<signed number>"
+ sed 's/[+m]//g' | # Remove '+' and 'm'
+ sort -g | # Sort in ascending order
+ sed -e 1b -e '$!d' # Extract the first and last lines
+}
+
+readfile() { weatherdata="$(bat "$weatherreport")" ;}
+
+showweather() {
+ readfile
+ # shellcheck disable=SC2046,SC2183
+ printf "☔%s ❄️%s° 🌞%s°\n" "$(getprecipchance)" $(getdailyhighlow)
+}
+
+case $BLOCK_BUTTON in
+ 1) setsid -f "$TERMINAL" -e less -Sf "$weatherreport" >/dev/null 2>&1 ;;
+ 2) getforecast && showweather ;;
+ 3) notify-send "🌈 Weather module" "\- Left click for full forecast.
+- Middle click to update forecast.
+☔: Chance of rain/snow
+❄️: Daily low
+🌞: Daily high" ;;
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 ;;
+esac
+
+# shellcheck disable=SC2015
+checkforecast && showweather ||
+ ( flock -n 9 &&
+ ( tries=0; while [ $tries -ne 100 ]; do
+ getforecast && break ||
+ { tries=$((tries+1)); sleep .1; }
+ done
+ ! checkforecast &&
+ until getforecast; do sleep 60; done
+ pkill -RTMIN+5 "${STATUSBAR:-waybar}"
+ ) &
+ echo ) 9>"${XDG_RUNTIME_DIR}/sb-forecast.lock"
diff --git a/.local/bin/statusbar/sb-internet b/.local/bin/statusbar/sb-internet
new file mode 100755
index 0000000..2c7fd96
--- /dev/null
+++ b/.local/bin/statusbar/sb-internet
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+# Show wifi 📶 and percent strength or 📡 if none.
+# Show 🌎 if connected to ethernet or ❎ if none.
+# Show 🔒 if a vpn connection is active
+
+case $BLOCK_BUTTON in
+ 1) setsid -f "$TERMINAL" -e nmtui >/dev/null 2>&1 ; pkill -RTMIN+4 waybar ;;
+ 3) notify-send "🌎 Internet module" "\- Click to connect
+❌: wifi disabled
+📡: no wifi connection
+📶: wifi connection with quality
+❎: no ethernet
+🌎: ethernet working
+🧭: vpn is active (routing)
+🔒: vpn is active
+ " ;;
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 ;;
+esac
+
+# Wifi
+if [ "$(bat /sys/class/net/w*/operstate 2>/dev/null)" = 'up' ] ; then
+ wifiicon="$(awk '/^\s*w/ { print "📶", int($3 * 100 / 70) "% " }' /proc/net/wireless)"
+elif [ "$(bat /sys/class/net/w*/operstate 2>/dev/null)" = 'down' ] ; then
+ [ "$(bat /sys/class/net/w*/flags 2>/dev/null)" = '0x1003' ] && wifiicon="📡 " || wifiicon="❌ "
+fi
+
+# Ethernet
+[ "$(bat /sys/class/net/e*/operstate 2>/dev/null)" = 'up' ] && ethericon="🌎" || ethericon="❎"
+
+# TUN
+[ -n "$(bat /sys/class/net/tun*/operstate 2>/dev/null)" ] && tunicon=" 🔒"
+[ -n "$(bat /sys/class/net/route*/operstate 2>/dev/null)" ] && tunicon=" 🧭"
+
+printf "%s%s%s\n" "$wifiicon" "$ethericon" "$tunicon"
diff --git a/.local/bin/statusbar/sb-iplocate b/.local/bin/statusbar/sb-iplocate
new file mode 100755
index 0000000..83a37e9
--- /dev/null
+++ b/.local/bin/statusbar/sb-iplocate
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# Gets your public ip address checks which country you are in and
+# displays that information in the statusbar
+#
+# https://www.maketecheasier.com/ip-address-geolocation-lookups-linux/
+
+set -e
+
+ifinstalled "geoip"
+addr="$(geoiplookup "$(curl -sfm 1 ifconfig.me 2>/dev/null)")"
+name="${addr##*, }"
+flag="$(rg "flag: $name" "${XDG_DATA_HOME:-$HOME/.local/share}/larbs/emoji")"
+flag="${flag%% *}"
+printf "%s %s\\n" "$flag" "$name"
diff --git a/.local/bin/statusbar/sb-kbselect b/.local/bin/statusbar/sb-kbselect
new file mode 100755
index 0000000..f4d3e9e
--- /dev/null
+++ b/.local/bin/statusbar/sb-kbselect
@@ -0,0 +1,26 @@
+#!/bin/sh
+# works on any init system
+# requirements: mew
+
+kbquery()
+{
+ kblayout=$(swaymsg --raw -t get_inputs | jq -r '.[] | select(.type == "keyboard") | .xkb_active_layout_name' | sort -u) || exit 1
+ kblayout=$(echo "$kblayout" | sed 's/(/\\(/g; s/)/\\)/g') || exit 1
+ kblayout=$(rg -oP "^\s*\K\w+(?=\s+$kblayout)" /usr/share/X11/xkb/rules/base.lst) || exit 1
+ echo $kblayout
+}
+
+kb=$(kbquery)
+
+case $BLOCK_BUTTON in
+ 1) kb_choice="$(awk '/! layout/{flag=1; next} /! variant/{flag=0} flag {print $2, "- " $1}' /usr/share/X11/xkb/rules/base.lst | mew -l 15)"
+ [ -z "$kb_choice" ] && exit 0
+ kb="$(echo "$kb_choice" | awk '{print $3}')"
+ swaymsg input "type:keyboard" xkb_layout "$kb" >/dev/null 2>&1
+ pkill -RTMIN+30 "${STATUSBAR:-waybar}";;
+ 3) notify-send "⌨ Keyboard/language module" "$(printf "%s" "\- Current layout: $(kbquery)")
+- Left click to change keyboard.";;
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 ;;
+esac
+
+echo "$kb"
diff --git a/.local/bin/statusbar/sb-mailbox b/.local/bin/statusbar/sb-mailbox
new file mode 100755
index 0000000..13ded2b
--- /dev/null
+++ b/.local/bin/statusbar/sb-mailbox
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+# Displays number of unread mail and an loading icon if updating.
+# When clicked, brings up `neomutt`.
+
+case $BLOCK_BUTTON in
+ 1) setsid -w -f "$TERMINAL" -e neomutt ; pkill -RTMIN+12 "${STATUSBAR:-waybar}" ;;
+ 2) setsid -f mailup >/dev/null && exit ;;
+ 3) notify-send "📬 Mail module" "\- Shows unread mail
+- Shows 🔃 if syncing mail
+- Left click opens neomutt
+- Middle click syncs mail" ;;
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 ;;
+esac
+
+unread="$(fd . "${XDG_DATA_HOME:-$HOME/.local/share}"/mail/*/[Ii][Nn][Bb][Oo][Xx]/new/ -t f | wc -l 2>/dev/null)"
+
+icon=$(bat /tmp/mailupdate 2>/dev/null)
+
+if [ "$unread" -eq 0 ]; then
+ [ -n "$icon" ] && echo "📬$icon" || exit 0
+else
+ echo "📬$unread$icon"
+fi
diff --git a/.local/bin/statusbar/sb-memory b/.local/bin/statusbar/sb-memory
new file mode 100755
index 0000000..a37f1ca
--- /dev/null
+++ b/.local/bin/statusbar/sb-memory
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+case $BLOCK_BUTTON in
+ 1) notify-send "🧠 Memory hogs" "$(ps axch -o cmd,%mem | awk '{cmd[$1]+=$2} END {for (i in cmd) print i, cmd[i]}' | sort -nrk2 | head)" ;;
+ 2) setsid -f "$TERMINAL" -e btop >/dev/null 2>&1 ;;
+ 3) notify-send "🧠 Memory module" "\- Shows Memory Used/Total.
+- Click to show memory hogs.
+- Middle click to open btop." ;;
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 ;;
+esac
+
+free --mebi | sed -n '2{p;q}' | awk '{printf ("🧠%sMB\n", ($3))}'
diff --git a/.local/bin/statusbar/sb-microphone b/.local/bin/statusbar/sb-microphone
new file mode 100755
index 0000000..fc1c07a
--- /dev/null
+++ b/.local/bin/statusbar/sb-microphone
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+# Prints the current microphone volume or  if muted.
+
+case $BLOCK_BUTTON in
+ 1) setsid -w -f "$TERMINAL" -e pulsemixer; pkill -RTMIN+23 "${STATUSBAR:-waybar}" ;;
+ 2) wpctl set-mute @DEFAULT_SOURCE@ toggle ;;
+ 4) wpctl set-volume @DEFAULT_SOURCE@ 1%+ ;;
+ 5) wpctl set-volume @DEFAULT_SOURCE@ 1%- ;;
+ 3) notify-send "🎤 Microphone volume module" "\- Shows volume 🎙️,  if muted.
+- Middle click to mute.
+- Scroll to change." ;;
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 ;;
+esac
+
+vol="$(wpctl get-volume @DEFAULT_AUDIO_SOURCE@)"
+
+# If muted, print  and exit.
+[ "$vol" != "${vol%\[MUTED\]}" ] && echo  && exit
+
+vol="${vol#Volume: }"
+
+split() {
+ # For ommiting the . without calling and external program.
+ IFS=$2
+ set -- $1
+ printf '%s' "$@"
+}
+
+vol="$(printf "%.0f" "$(split "$vol" ".")")"
+
+case 1 in
+ $((vol >= 70)) ) icon="🎙️" ;;
+ $((vol >= 30)) ) icon="🎙️" ;;
+ $((vol >= 1)) ) icon="🎙️" ;;
+ * ) echo  && exit ;;
+esac
+
+echo "$icon$vol%"
diff --git a/.local/bin/statusbar/sb-moonphase b/.local/bin/statusbar/sb-moonphase
new file mode 100755
index 0000000..f91a751
--- /dev/null
+++ b/.local/bin/statusbar/sb-moonphase
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+# Shows the current moon phase.
+
+moonfile="${XDG_DATA_HOME:-$HOME/.local/share}/moonphase"
+
+[ -s "$moonfile" ] && [ "$(stat -c %y "$moonfile" 2>/dev/null | cut -d' ' -f1)" = "$(date '+%Y-%m-%d')" ] ||
+ { curl -sf "wttr.in/?format=%m" > "$moonfile" || exit 1 ;}
+
+icon="$(bat "$moonfile")"
+
+case "$icon" in
+ 🌑) name="New" ;;
+ 🌒) name="Waxing Crescent" ;;
+ 🌓) name="First Quarter" ;;
+ 🌔) name="Waxing Gibbous" ;;
+ 🌕) name="Full" ;;
+ 🌖) name="Waning Gibbous" ;;
+ 🌗) name="Last Quarter" ;;
+ 🌘) name="Waning Crescent" ;;
+ *) exit 1 ;;
+esac
+
+echo "${icon-?}"
+
+case $BLOCK_BUTTON in
+ 3) notify-send "🌜 Moon phase module" "Displays current moon phase.
+- 🌑: New
+- 🌒: Waxing Crescent
+- 🌓: First Quarter
+- 🌔: Waxing Gibbous
+- 🌕: Full
+- 🌖: Waning Gibbous
+- 🌗: Last Quarter
+- 🌘: Waning Crescent" ;;
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 ;;
+esac
diff --git a/.local/bin/statusbar/sb-mpdup b/.local/bin/statusbar/sb-mpdup
new file mode 100755
index 0000000..42bd737
--- /dev/null
+++ b/.local/bin/statusbar/sb-mpdup
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+# This loop will update the mpd statusbar module whenever a command changes the
+# music player's status. mpd must be running on X's start for this to work.
+
+while : ; do
+ mpc idle >/dev/null && kill -45 "$(pidof "waybar")" || break
+done
diff --git a/.local/bin/statusbar/sb-music b/.local/bin/statusbar/sb-music
new file mode 100755
index 0000000..8b0ae77
--- /dev/null
+++ b/.local/bin/statusbar/sb-music
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+filter() { sed "/^volume:/d;s/\\[paused\\].*/⏸/g;/\\[playing\\].*/d;/^ERROR/Q" | paste -sd ' ' -;}
+
+pidof -x sb-mpdup >/dev/null 2>&1 || sb-mpdup >/dev/null 2>&1 &
+
+case $BLOCK_BUTTON in
+ 1) mpc status | filter ; setsid -f "$TERMINAL" -e rmpc >/dev/null 2>&1 < /dev/null;; # right click, pause/unpause
+ 2) mpc toggle | filter ;; # right click, pause/unpause
+ 3) mpc status | filter ; notify-send "🎵 Music module" "\- Shows mpd song playing.
+- ⏸ when paused.
+- Left click opens rmpc.
+- Middle click pauses.
+- Scroll changes track.";; # right click, pause/unpause
+ 4) mpc prev | filter ;; # scroll up, previous
+ 5) mpc next | filter ;; # scroll down, next
+ 8) mpc status | filter ; setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 < /dev/null ;;
+ *) mpc status | filter ;;
+esac
diff --git a/.local/bin/statusbar/sb-nettraf b/.local/bin/statusbar/sb-nettraf
new file mode 100755
index 0000000..8921123
--- /dev/null
+++ b/.local/bin/statusbar/sb-nettraf
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+# Module showing network traffic. Shows how much data has been received (RX) or
+# transmitted (TX) since the previous time this script ran. So if run every
+# second, gives network traffic per second.
+
+case $BLOCK_BUTTON in
+ 3) notify-send "🌐 Network traffic module" "🔻: Traffic received
+🔺: Traffic transmitted" ;;
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 ;;
+esac
+
+update() {
+ sum=0
+ for arg; do
+ read -r i < "$arg"
+ sum=$(( sum + i ))
+ done
+ cache=/tmp/${1##*/}
+ [ -f "$cache" ] && read -r old < "$cache" || old=0
+ printf %d\\n "$sum" > "$cache"
+ printf %d\\n $(( sum - old ))
+}
+
+rx=$(update /sys/class/net/[ew]*/statistics/rx_bytes)
+tx=$(update /sys/class/net/[ew]*/statistics/tx_bytes)
+
+printf "🔻%4sB 🔺%4sB\\n" $(numfmt --to=iec $rx $tx)
diff --git a/.local/bin/statusbar/sb-news b/.local/bin/statusbar/sb-news
new file mode 100755
index 0000000..440de7c
--- /dev/null
+++ b/.local/bin/statusbar/sb-news
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# Displays number of unread news items and an loading icon if updating.
+# When clicked, brings up `newsboat`.
+
+case $BLOCK_BUTTON in
+ 1) setsid "$TERMINAL" -T newsboat -e newsboat >/dev/null 2>&1 ;;
+ 2) setsid -f newsup >/dev/null && exit ;;
+ 3) notify-send "📰 News module" "\- Shows unread news items
+- Shows 🔃 if updating with \`newsup\`
+- Left click opens newsboat
+- Middle click syncs RSS feeds
+<b>Note:</b> Only one instance of newsboat (including updates) may be running at a time." ;;
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 ;;
+esac
+
+ bat /tmp/newsupdate 2>/dev/null || echo "$(newsboat -x print-unread | awk '{ if($1>0) print "📰" $1}')$(bat "${XDG_CONFIG_HOME:-$HOME/.config}"/newsboat/.update 2>/dev/null)"
diff --git a/.local/bin/statusbar/sb-pacpackages b/.local/bin/statusbar/sb-pacpackages
new file mode 100755
index 0000000..08b4235
--- /dev/null
+++ b/.local/bin/statusbar/sb-pacpackages
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# Displays number of upgradeable packages.
+# For this to work, have a `pacman -Sy` command run in the background as a
+# cronjob every so often as root. This script will then read those packages.
+# When clicked, it will run an upgrade via pacman.
+#
+# Add the following text as a file in /usr/share/libalpm/hooks/statusbar.hook:
+#
+# [Trigger]
+# Operation = Upgrade
+# Type = Package
+# Target = *
+#
+# [Action]
+# Description = Updating statusbar...
+# When = PostTransaction
+# Exec = /usr/bin/pkill -RTMIN+8 dwmblocks # Or waybar if using sway/hyprland.
+
+case $BLOCK_BUTTON in
+ 1) setsid -f "$TERMINAL" -e sb-popupgrade >/dev/null 2>&1 ;;
+ 2) notify-send "$(/usr/bin/pacman -Qu)" ;;
+ 3) notify-send "🎁 Upgrade module" "📦: number of upgradable packages
+- Left click to upgrade packages
+- Middle click to show upgradable packages" ;;
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 ;;
+esac
+
+pacman -Qu | rg -Fcv "[ignored]" | sed "s/^/📦/;s/^📦0$//g"
diff --git a/.local/bin/statusbar/sb-popupgrade b/.local/bin/statusbar/sb-popupgrade
new file mode 100755
index 0000000..94279c8
--- /dev/null
+++ b/.local/bin/statusbar/sb-popupgrade
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+printf "Beginning upgrade.\\n"
+
+paru
+pkill -RTMIN+8 "${STATUSBAR:-waybar}"
+
+printf "\\nUpgrade complete.\\nPress <Enter> to exit window.\\n\\n"
+read -r _
diff --git a/.local/bin/statusbar/sb-price b/.local/bin/statusbar/sb-price
new file mode 100755
index 0000000..d320511
--- /dev/null
+++ b/.local/bin/statusbar/sb-price
@@ -0,0 +1,59 @@
+#!/bin/sh
+
+# Usage:
+# price <currency-base currency> <name of currency> <icon> <signal>
+# price bat-btc "Basic Attention Token" 🦁 24
+# This will give the price of BAT denominated in BTC and will update on
+# signal 24.
+# When the name of the currency is multi-word, put it in quotes.
+
+[ -z "$1" ] && exit 1
+
+url="${CRYPTOURL:-rate.sx}"
+target="${1%%-*}"
+denom="${1##*-}"
+name="${2:-$1}"
+icon="${3:-💰}"
+case "$denom" in
+ "$target"|usd) denom="usd"; symb="$" ;;
+ gbp) symb="£" ;;
+ eur) symb="€" ;;
+ rub) symb="₽" ;;
+ btc) symb="" ;;
+esac
+interval="@14d" # History contained in chart preceded by '@' (7d = 7 days)
+dir="${XDG_CACHE_HOME:-$HOME/.cache}/crypto-prices"
+pricefile="$dir/$target-$denom"
+chartfile="$dir/$target-$denom-chart"
+filestat="$(stat -c %y "$pricefile" 2>/dev/null)"
+
+[ -d "$dir" ] || mkdir -p "$dir"
+
+updateprice() { curl -sf \
+ --fail-early "${denom}.${url}/1${target}" "${denom}.${url}/${target}${interval}" \
+ --output "$pricefile" --output "$chartfile" ||
+ rm -f "$pricefile" "$chartfile" ;}
+
+[ "${filestat%% *}" != "$(date '+%Y-%m-%d')" ] &&
+ updateme="1"
+
+case $BLOCK_BUTTON in
+ 1) setsid -f "$TERMINAL" -e less -Srf "$chartfile" >/dev/null ;;
+ 2) notify-send -u low "$icon Updating..." "Updating $name price..." ; updateme="1" ; showupdate="1" ;;
+ 3) uptime="$(date -d "$filestat" '+%D at %T' | sed "s|$(date '+%D')|Today|")"
+ notify-send "$icon $name module" "\- <b>Exact price: $symb$(bat "$pricefile")</b>
+- Left click for chart of changes.
+- Middle click to update.
+- Shows 🔃 if updating prices.
+- <b>Last updated:
+$uptime</b>" ;;
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null ;;
+esac
+
+[ -n "$updateme" ] &&
+ updateprice "$target" &&
+ [ -n "$showupdate" ] &&
+ notify-send "$icon Update complete." "$name price is now
+$symb$(bat "$pricefile")"
+
+[ -f "$pricefile" ] && printf "%s%s%0.2f\n" "$icon" "$symb" "$(bat "$pricefile")"
diff --git a/.local/bin/statusbar/sb-tasks b/.local/bin/statusbar/sb-tasks
new file mode 100755
index 0000000..14778a2
--- /dev/null
+++ b/.local/bin/statusbar/sb-tasks
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# Originally by Andr3as07 <https://github.com/Andr3as07>
+# Some changes by Luke
+# Rebuild by Tenyun
+
+# This block displays the number running background tasks. Requires tsp.
+
+num=$(tsp -l | awk -v numr=0 -v numq=0 '{if (/running/)numr++; if (/queued/)numq++} END{print numr+numq"("numq")"}')
+
+# Handle mouse clicks
+case $BLOCK_BUTTON in
+ 1) setsid -f "$TERMINAL" -e tsp -l >/dev/null 2>&1 ;;
+ 3) notify-send "Tasks module" "🤖: number of running/queued background tasks
+- Left click opens tsp" ;; # Right click
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 ;;
+esac
+
+[ "$num" != "0(0)" ] &&
+ echo "🤖$num"
diff --git a/.local/bin/statusbar/sb-ticker b/.local/bin/statusbar/sb-ticker
new file mode 100755
index 0000000..5b26160
--- /dev/null
+++ b/.local/bin/statusbar/sb-ticker
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+# Usage
+# sb-ticker
+# Sample output
+# ^DJI: 0.09%
+# CL=F: -1.88%
+# Description
+# displays/retrieves the latest percent-change in stock market quotes listed in $XDG_CONFIG_HOME/tickers.
+# defaults to S&P 500, Dow Jones Industrial, and the Nasdaq
+#
+# intended to be used in the statusbar, which will display the first quote price in the output
+
+url="terminal-stocks.dev"
+pricefile="${XDG_CACHE_HOME:-$HOME/.cache}/stock-prices"
+tickerfile="${XDG_CONFIG_HOME:-$HOME/.config}/tickers"
+
+[ -f "$tickerfile" ] && tickers="$(bat "$tickerfile")" || tickers="^GSPC,^DJI,^IXIC";
+
+checkprice() {
+ [ -s "$pricefile" ] && [ "$(stat -c %y "$pricefile" 2>/dev/null |
+ cut -d':' -f1)" != "$(date '+%Y-%m-%d %H')" ]
+}
+
+getchange() {
+ mapfile -t changes < <(sed -e 's/ / /g' "$pricefile" | rg -oe '[m-]\+[0-9]\+\.[0-9]\+' | sed 's/[m ]/;/g')
+ IFS=',' read -ra TICKER <<< "$tickers"
+ for idx in "${!TICKER[@]}"; do
+ printf "%s: %s%%\n" "${TICKER[$idx]}" "${changes[$idx]//;/}"
+ done
+}
+
+updateprice() { curl -sfm 10 "$url/$tickers" --output "$pricefile" || rm -f "$pricefile" ; }
+
+case $BLOCK_BUTTON in
+ 1) setsid "$TERMINAL" -e less -Srf "$pricefile" >/dev/null 2>&1 ;;
+ 2) notify-send -u low "Updating..." "Updating prices" ; updateme="1" ;;
+ 3) notify-send "Current prices:" "Current stock prices:\n<b>$(getchange)</b>
+- Left click to show price file
+- Middle click to update stock prices
+- Right click to get stock overview" ;;
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 ;;
+esac
+
+[ -n "$updateme" ] && updateprice
+
+[ -f "$pricefile" ] && getchange
+
+checkprice && updateprice
diff --git a/.local/bin/statusbar/sb-torrent b/.local/bin/statusbar/sb-torrent
new file mode 100755
index 0000000..868b3aa
--- /dev/null
+++ b/.local/bin/statusbar/sb-torrent
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+transmission-remote -l | rg % |
+ sed " # The letters are for sorting and will not appear.
+s/.*Stopped.*/A 🛑/;
+s/.*Seeding.*/Z 🌱/;
+s/.*100%.*/N ✅/;
+s/.*Idle.*/B 🕰️/;
+s/.*Uploading.*/L ⬆️/;
+s/.*%.*/M ⬇️/" |
+ sort -h | uniq -c | awk '{print $3 $1}' | paste -sd ' ' -
+
+case $BLOCK_BUTTON in
+ 1) setsid -f "$TERMINAL" -e stig >/dev/null 2>&1 ;;
+ 2) td-toggle ;;
+ 3) notify-send "🌱 Torrent module" "\- Left click to open stig.
+- Middle click to toggle transmission.
+- Shift click to edit script.
+Module shows number of torrents:
+🛑: paused
+🕰: idle (seeds needed)
+🔼: uploading (unfinished)
+🔽: downloading
+✅: done
+🌱: done and seeding" ;;
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 ;;
+esac
diff --git a/.local/bin/statusbar/sb-volume b/.local/bin/statusbar/sb-volume
new file mode 100755
index 0000000..6742bf5
--- /dev/null
+++ b/.local/bin/statusbar/sb-volume
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+# Prints the current volume or 🔇 if muted.
+
+case $BLOCK_BUTTON in
+ 1) setsid -w -f "$TERMINAL" -e pulsemixer; pkill -RTMIN+10 "${STATUSBAR:-waybar}" ;;
+ 2) wpctl set-mute @DEFAULT_SINK@ toggle ;;
+ 4) wpctl set-volume @DEFAULT_SINK@ 1%+ ;;
+ 5) wpctl set-volume @DEFAULT_SINK@ 1%- ;;
+ 3) notify-send "📢 Volume module" "\- Shows volume 🔊, 🔇 if muted.
+- Middle click to mute.
+- Scroll to change." ;;
+ 8) setsid -f "$TERMINAL" -e "$EDITOR" "$0" >/dev/null 2>&1 ;;
+esac
+
+vol="$(wpctl get-volume @DEFAULT_AUDIO_SINK@)"
+
+# If muted, print 🔇 and exit.
+[ "$vol" != "${vol%\[MUTED\]}" ] && echo 🔇 && exit
+
+vol="${vol#Volume: }"
+
+split() {
+ # For ommiting the . without calling and external program.
+ IFS=$2
+ set -- $1
+ printf '%s' "$@"
+}
+
+vol="$(printf "%.0f" "$(split "$vol" ".")")"
+
+case 1 in
+ $((vol >= 70)) ) icon="🔊" ;;
+ $((vol >= 30)) ) icon="🔉" ;;
+ $((vol >= 1)) ) icon="🔈" ;;
+ * ) echo 🔇 && exit ;;
+esac
+
+echo "$icon$vol%"
diff --git a/.local/bin/sysact b/.local/bin/sysact
new file mode 100755
index 0000000..44a3868
--- /dev/null
+++ b/.local/bin/sysact
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+# A mew wrapper script for system functions.
+export WM="Hyprland"
+case "$(readlink -f /sbin/init)" in
+ *systemd*) ctl='systemctl' ;;
+ *) ctl='loginctl' ;;
+esac
+
+wmpid(){ # This function is needed if there are multiple instances of the window manager.
+ tree="$(pstree -ps $$)"
+ tree="${tree#*$WM(}"
+ echo "${tree%%)*}"
+}
+
+lock(){
+ mpc pause
+ pauseallmpv
+ wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
+ kill -44 $(pidof waybar)
+ swaylock
+ wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
+ kill -44 $(pidof waybar)
+}
+
+case "$(printf "🔒 lock\n🚪 leave $WM\n♻️ renew $WM\n🐻 hibernate\n🔃 reboot\n🖥 shutdown\n💤 sleep\n📺 display off" | mew -i -p 'Action: ')" in
+ '🔒 lock') lock ;;
+ "🚪 leave $WM") hyprctl dispatch exit ;;
+ "♻️ renew $WM") hyprctl reload ;;
+ '🐻 hibernate') $ctl hibernate -i ;;
+ '💤 sleep') $ctl suspend -i ;;
+ '🔃 reboot') $ctl reboot -i ;;
+ '🖥️shutdown') $ctl poweroff -i ;;
+ '📺 display off') xset dpms force off ;;
+ *) exit 1 ;;
+esac
diff --git a/.local/bin/tag b/.local/bin/tag
new file mode 100755
index 0000000..92d6323
--- /dev/null
+++ b/.local/bin/tag
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+err() { echo "Usage:
+ tag [OPTIONS] file
+Options:
+ -a: artist/author
+ -t: song/chapter title
+ -A: album/book title
+ -n: track/chapter number
+ -N: total number of tracks/chapters
+ -d: year of publication
+ -g: genre
+ -c: comment
+You will be prompted for title, artist, album and track if not given." && exit 1 ;}
+
+while getopts "a:t:A:n:N:d:g:c:" o; do case "${o}" in
+ a) artist="${OPTARG}" ;;
+ t) title="${OPTARG}" ;;
+ A) album="${OPTARG}" ;;
+ n) track="${OPTARG}" ;;
+ N) total="${OPTARG}" ;;
+ d) date="${OPTARG}" ;;
+ g) genre="${OPTARG}" ;;
+ c) comment="${OPTARG}" ;;
+ *) printf "Invalid option: -%s\\n" "$OPTARG" && err ;;
+esac done
+
+shift $((OPTIND - 1))
+
+file="$1"
+
+temp="$(mktemp -p "$(dirname "$file")")"
+trap 'rm -f $temp' HUP INT QUIT TERM PWR EXIT
+
+[ ! -f "$file" ] && echo 'Provide file to tag.' && err
+
+[ -z "$title" ] && echo 'Enter a title.' && read -r title
+[ -z "$artist" ] && echo 'Enter an artist.' && read -r artist
+[ -z "$album" ] && echo 'Enter an album.' && read -r album
+[ -z "$track" ] && echo 'Enter a track number.' && read -r track
+
+cp -f "$file" "$temp" && ffmpeg -i "$temp" -map 0 -y -codec copy \
+ -metadata title="$title" \
+ -metadata album="$album" \
+ -metadata artist="$artist" \
+ -metadata track="${track}${total:+/"$total"}" \
+ ${date:+-metadata date="$date"} \
+ ${genre:+-metadata genre="$genre"} \
+ ${comment:+-metadata comment="$comment"} "$file"
diff --git a/.local/bin/td-toggle b/.local/bin/td-toggle
new file mode 100755
index 0000000..977cc56
--- /dev/null
+++ b/.local/bin/td-toggle
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# If transmission-daemon is running, will ask to kill, else will ask to start.
+
+if pidof transmission-daemon >/dev/null ;
+then
+ [ "$(printf "No\\nYes" | mew -i -p "Turn off transmission-daemon?")" = "Yes" ] && killall transmission-daemon && notify-send "transmission-daemon disabled."
+else
+ ifinstalled transmission-cli || exit
+ [ "$(printf "No\\nYes" | mew -i -p "Turn on transmission daemon?")" = "Yes" ] && transmission-daemon && notify-send "transmission-daemon enabled."
+fi
+sleep 3 && pkill -RTMIN+7 "${STATUSBAR:-waybar}"
diff --git a/.local/bin/torwrap b/.local/bin/torwrap
new file mode 100755
index 0000000..4bbeb35
--- /dev/null
+++ b/.local/bin/torwrap
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+ifinstalled stig transmission-cli || exit 1
+
+! pidof transmission-daemon >/dev/null && transmission-daemon && notify-send "Starting torrent daemon..."
+
+$TERMINAL -e stig; pkill -RTMIN+7 "${STATUSBAR:-waybar}"
diff --git a/.local/bin/transadd b/.local/bin/transadd
new file mode 100755
index 0000000..ee7e162
--- /dev/null
+++ b/.local/bin/transadd
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+# Mimeapp script for adding torrent to transmission-daemon, but will also start the daemon first if not running.
+
+# transmission-daemon sometimes fails to take remote requests in its first moments, hence the sleep.
+
+pidof transmission-daemon >/dev/null || (transmission-daemon && notify-send "Starting transmission daemon..." && sleep 3 && pkill -RTMIN+7 "${STATUSBAR:-waybar}")
+
+transmission-remote -a "$@" && notify-send "🔽 Torrent added."
diff --git a/.local/bin/unix b/.local/bin/unix
new file mode 100755
index 0000000..fd15826
--- /dev/null
+++ b/.local/bin/unix
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+#original artwork by http://www.sanderfocus.nl/#/portfolio/tech-heroes
+#converted to shell by #nixers @ irc.unix.chat
+
+bat << 'eof'
+ ,_ ,_==▄▂
+ , ▂▃▄▄▅▅▅▂▅¾. / /
+ ▄▆<´ "»▓▓▓%\ / / / /
+ ,▅7" ´>▓▓▓% / / > / >/%
+ ▐¶▓ ,»▓▓¾´ /> %/%// / /
+ ▓▃▅▅▅▃,,▄▅▅▅Æ\// ///>// />/ /
+ V║«¼.;→ ║<«.,`=// />//%/% / /
+ //╠<´ -²,)(▓~"-╝/¾/ %/>/ />
+ / / / ▐% -./▄▃▄▅▐, /7//;//% / /
+ / ////`▌▐ %zWv xX▓▇▌//&;% / /
+ / / / %//%/¾½´▌▃▄▄▄▄▃▃▐¶\/& /
+ </ /</%//`▓!%▓%╣[38;5;255;╣WY<Y)y&/`\
+ / / %/%//</%//\i7; ╠N>)VY>7; \_ UNIX IS VERY SIMPLE IT JUST NEEDS A
+ / /</ //<///<_/%\▓ V%W%£)XY _/%‾\_, GENIUS TO UNDERSTAND ITS SIMPLICITY
+ / / //%/_,=--^/%/%%\¾%¶%%} /%%%%%%;\,
+ %/< /_/ %%%%%;X%%\%%;, _/%%%;, \
+ / / %%%%%%;, \%%l%%;// _/%;, dmr
+ / %%%;, <;\-=-/ /
+ ;, l
+eof
diff --git a/.local/bin/unmounter b/.local/bin/unmounter
new file mode 100755
index 0000000..fe1d01a
--- /dev/null
+++ b/.local/bin/unmounter
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+set -e
+
+mounteddroids="$(rg simple-mtpfs /etc/mtab | awk '{print "📱" $2}')"
+lsblkoutput="$(lsblk -nrpo "name,type,size,mountpoint")"
+mounteddrives="$(echo "$lsblkoutput" | awk '($2=="part"||$2="crypt")&&$4!~/\/boot|\/home$|SWAP/&&length($4)>1{printf "💾%s (%s)\n",$4,$3}')"
+
+allunmountable="$(echo "$mounteddroids
+$mounteddrives" | sed "/^$/d;s/ *$//")"
+test -n "$allunmountable"
+
+chosen="$(echo "$allunmountable" | mew -i -p "Unmount which drive?")"
+chosen="${chosen%% *}"
+test -n "$chosen"
+
+doas umount -l "/${chosen#*/}"
+notify-send "Device unmounted." "$chosen has been unmounted."
+
+# Close the chosen drive if decrypted.
+cryptid="$(echo "$lsblkoutput" | rg "/${chosen#*/}$")"
+cryptid="${cryptid%% *}"
+test -b /dev/mapper/"${cryptid##*/}"
+doas_askpass cryptsetup close "$cryptid"
+notify-send "🔒Device decryption closed." "Drive is now securely locked again."
diff --git a/.local/bin/weath b/.local/bin/weath
new file mode 100755
index 0000000..ed23534
--- /dev/null
+++ b/.local/bin/weath
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+# Get the weather on the terminal. You can pass an alternative location as a parameter,
+# and/or use the 'cp' option to copy the forecast as plaintext to the clipboard.
+
+report="${XDG_CACHE_HOME:-$HOME/.cache}/weatherreport"
+
+if [ "$1" = 'cp' ]; then
+ # shellcheck disable=SC2015
+ [ -z "$2" ] && sed 's/\x1b\[[^m]*m//g' "$report" | wl-copy &&
+ notify-send "Weather forecast for '${LOCATION:-$(head -n 1 "$report" | cut -d' ' -f3-)}' copied to clipboard." ||
+ { data="$(curl -sfm 5 "${WTTRURL:-wttr.in}/$2?T")" &&
+ notify-send "Weather forecast for '$2' copied to clipboard." &&
+ echo "$data" | wl-copy ||
+ notify-send 'Failed to get weather forecast!' 'Check your internet connection and the supplied location.'; }
+else
+ [ -n "$2" ] &&
+ notify-send "Invalid option '$1'! The only valid option is 'cp'." &&
+ exit 1
+
+ # shellcheck disable=SC2015
+ [ -z "$1" ] && less -S "$report" ||
+ data="$(curl -sfm 5 "${WTTRURL:-wttr.in}/$1")" && echo "$data" | less -S ||
+ notify-send 'Failed to get weather forecast!' 'Check your internet connection and the supplied location.'
+fi
diff --git a/.local/bin/xdg-terminal-exec b/.local/bin/xdg-terminal-exec
new file mode 100755
index 0000000..12b18ff
--- /dev/null
+++ b/.local/bin/xdg-terminal-exec
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+"$TERMINAL" -e "$@"
diff --git a/.local/share/applications/file.desktop b/.local/share/applications/file.desktop
new file mode 100644
index 0000000..dcdf465
--- /dev/null
+++ b/.local/share/applications/file.desktop
@@ -0,0 +1,4 @@
+[Desktop Entry]
+Type=Application
+Name=File Manager
+Exec=/usr/bin/footclient -e yazi %u
diff --git a/.local/share/applications/img.desktop b/.local/share/applications/img.desktop
new file mode 100644
index 0000000..a20b4f2
--- /dev/null
+++ b/.local/share/applications/img.desktop
@@ -0,0 +1,4 @@
+[Desktop Entry]
+Type=Application
+Name=Image viewer
+Exec=/usr/bin/swayimg %f
diff --git a/.local/share/applications/mail.desktop b/.local/share/applications/mail.desktop
new file mode 100644
index 0000000..e7e16ae
--- /dev/null
+++ b/.local/share/applications/mail.desktop
@@ -0,0 +1,4 @@
+[Desktop Entry]
+Type=Application
+Name=Mail
+Exec=/usr/bin/footclient -e neomutt %u
diff --git a/.local/share/applications/pdf.desktop b/.local/share/applications/pdf.desktop
new file mode 100644
index 0000000..8c38677
--- /dev/null
+++ b/.local/share/applications/pdf.desktop
@@ -0,0 +1,4 @@
+[Desktop Entry]
+Type=Application
+Name=PDF reader
+Exec=/usr/bin/zathura %u
diff --git a/.local/share/applications/rss.desktop b/.local/share/applications/rss.desktop
new file mode 100644
index 0000000..6fafc4f
--- /dev/null
+++ b/.local/share/applications/rss.desktop
@@ -0,0 +1,4 @@
+[Desktop Entry]
+Type=Application
+Name=RSS feed addition
+Exec=/usr/bin/env rssadd %U
diff --git a/.local/share/applications/text.desktop b/.local/share/applications/text.desktop
new file mode 100644
index 0000000..ac53b06
--- /dev/null
+++ b/.local/share/applications/text.desktop
@@ -0,0 +1,4 @@
+[Desktop Entry]
+Type=Application
+Name=Text editor
+Exec=/usr/bin/footclient -e nvim %u
diff --git a/.local/share/applications/torrent.desktop b/.local/share/applications/torrent.desktop
new file mode 100644
index 0000000..f6d28d9
--- /dev/null
+++ b/.local/share/applications/torrent.desktop
@@ -0,0 +1,4 @@
+[Desktop Entry]
+Type=Application
+Name=Torrent
+Exec=/usr/bin/env transadd %U
diff --git a/.local/share/applications/video.desktop b/.local/share/applications/video.desktop
new file mode 100644
index 0000000..a29a0b1
--- /dev/null
+++ b/.local/share/applications/video.desktop
@@ -0,0 +1,4 @@
+[Desktop Entry]
+Type=Application
+Name=Video viewer
+Exec=/usr/bin/mpv -quiet %f
diff --git a/.local/share/bg b/.local/share/bg
new file mode 120000
index 0000000..b41641d
--- /dev/null
+++ b/.local/share/bg
@@ -0,0 +1 @@
+thiemeyer_road_to_samarkand.jpg \ No newline at end of file
diff --git a/.local/share/larbs/chars/emoji b/.local/share/larbs/chars/emoji
new file mode 100644
index 0000000..6803731
--- /dev/null
+++ b/.local/share/larbs/chars/emoji
@@ -0,0 +1,1630 @@
+😀 grinning face
+😃 grinning face with big eyes
+😄 grinning face with smiling eyes
+😁 beaming face with smiling eyes
+😆 grinning squinting face
+😅 grinning face with sweat
+🤣 rolling on the floor laughing
+😂 face with tears of joy
+🙂 slightly smiling face
+🙃 upside-down face
+🫠 melting face
+😉 winking face
+😊 smiling face with smiling eyes
+😇 smiling face with halo
+🥰 smiling face with hearts
+😍 smiling face with heart-eyes
+🤩 star-struck
+😘 face blowing a kiss
+😗 kissing face
+☺️ smiling face
+😚 kissing face with closed eyes
+😙 kissing face with smiling eyes
+🥲 smiling face with tear
+😋 face savoring food
+😛 face with tongue
+😜 winking face with tongue
+🤪 zany face
+😝 squinting face with tongue
+🤑 money-mouth face
+🤗 smiling face with open hands
+🤭 face with hand over mouth
+🫢 face with open eyes and hand over mouth
+🫣 face with peeking eye
+🤫 shushing face
+🤔 thinking face
+🫡 saluting face
+🤐 zipper-mouth face
+🤨 face with raised eyebrow
+😐 neutral face
+😑 expressionless face
+😶 face without mouth
+🫥 dotted line face
+😏 smirking face
+😒 unamused face
+🙄 face with rolling eyes
+😬 grimacing face
+🤥 lying face
+😌 relieved face
+😔 pensive face
+😪 sleepy face
+🤤 drooling face
+😴 sleeping face
+😷 face with medical mask
+🤒 face with thermometer
+🤕 face with head-bandage
+🤢 nauseated face
+🤮 face vomiting
+🤧 sneezing face
+🥵 hot face
+🥶 cold face
+🥴 woozy face
+😵 face with crossed-out eyes
+🤯 exploding head
+🤠 cowboy hat face
+🥳 partying face
+🥸 disguised face
+😎 smiling face with sunglasses
+🤓 nerd face
+🧐 face with monocle
+😕 confused face
+🫤 face with diagonal mouth
+😟 worried face
+🙁 slightly frowning face
+☹️ frowning face
+😮 face with open mouth
+😯 hushed face
+😲 astonished face
+😳 flushed face
+🥺 pleading face
+🥹 face holding back tears
+😦 frowning face with open mouth
+😧 anguished face
+😨 fearful face
+😰 anxious face with sweat
+😥 sad but relieved face
+😢 crying face
+😭 loudly crying face
+😱 face screaming in fear
+😖 confounded face
+😣 persevering face
+😞 disappointed face
+😓 downcast face with sweat
+😩 weary face
+😫 tired face
+🥱 yawning face
+😤 face with steam from nose
+😡 pouting face
+😠 angry face
+🤬 face with symbols on mouth
+😈 smiling face with horns
+👿 angry face with horns
+💀 skull
+☠️ skull and crossbones
+💩 pile of poo
+🤡 clown face
+👹 ogre
+👺 goblin
+👻 ghost
+👽 alien
+👾 alien monster
+🤖 robot
+😺 grinning cat
+😸 grinning cat with smiling eyes
+😹 cat with tears of joy
+😻 smiling cat with heart-eyes
+😼 cat with wry smile
+😽 kissing cat
+🙀 weary cat
+😿 crying cat
+😾 pouting cat
+🙈 see-no-evil monkey
+🙉 hear-no-evil monkey
+🙊 speak-no-evil monkey
+💋 kiss mark
+💌 love letter
+💘 heart with arrow
+💝 heart with ribbon
+💖 sparkling heart
+💗 growing heart
+💓 beating heart
+💞 revolving hearts
+💕 two hearts
+💟 heart decoration
+❣️ heart exclamation
+💔 broken heart
+❤️ red heart
+🧡 orange heart
+💛 yellow heart
+💚 green heart
+💙 blue heart
+💜 purple heart
+🤎 brown heart
+🖤 black heart
+🤍 white heart
+💯 hundred points
+💢 anger symbol
+💥 collision
+💫 dizzy
+💦 sweat droplets
+💨 dashing away
+🕳️ hole
+💣 bomb
+💬 speech balloon
+🗨️ left speech bubble
+🗯️ right anger bubble
+💭 thought balloon
+💤 zzz
+👋 waving hand
+🤚 raised back of hand
+🖐️ hand with fingers splayed
+✋ raised hand
+🖖 vulcan salute
+🫱 rightwards hand
+🫲 leftwards hand
+🫳 palm down hand
+🫴 palm up hand
+👌 OK hand
+🤌 pinched fingers
+🤏 pinching hand
+✌️ victory hand
+🤞 crossed fingers
+🫰 hand with index finger and thumb crossed
+🤟 love-you gesture
+🤘 sign of the horns
+🤙 call me hand
+👈 backhand index pointing left
+👉 backhand index pointing right
+👆 backhand index pointing up
+🖕 middle finger
+👇 backhand index pointing down
+☝️ index pointing up
+🫵 index pointing at the viewer
+👍 thumbs up
+👎 thumbs down
+✊ raised fist
+👊 oncoming fist
+🤛 left-facing fist
+🤜 right-facing fist
+👏 clapping hands
+🙌 raising hands
+🫶 heart hands
+👐 open hands
+🤲 palms up together
+🤝 handshake
+🙏 folded hands
+✍️ writing hand
+💅 nail polish
+🤳 selfie
+💪 flexed biceps
+🦾 mechanical arm
+🦿 mechanical leg
+🦵 leg
+🦶 foot
+👂 ear
+🦻 ear with hearing aid
+👃 nose
+🧠 brain
+🫀 anatomical heart
+🫁 lungs
+🦷 tooth
+🦴 bone
+👀 eyes
+👁️ eye
+👅 tongue
+👄 mouth
+🫦 biting lip
+👶 baby
+🧒 child
+👦 boy
+👧 girl
+🧑 person
+👱 person: blond hair
+👨 man
+🧔 person: beard
+👩 woman
+🧓 older person
+👴 old man
+👵 old woman
+🙍 person frowning
+🙎 person pouting
+🙅 person gesturing NO
+🙆 person gesturing OK
+💁 person tipping hand
+🙋 person raising hand
+🧏 deaf person
+🙇 person bowing
+🤦 person facepalming
+🤷 person shrugging
+👮 police officer
+🕵️ detective
+💂 guard
+🥷 ninja
+👷 construction worker
+🫅 person with crown
+🤴 prince
+👸 princess
+👳 person wearing turban
+👲 person with skullcap
+🧕 woman with headscarf
+🤵 person in tuxedo
+👰 person with veil
+🤰 pregnant woman
+🫃 pregnant man
+🫄 pregnant person
+🤱 breast-feeding
+👼 baby angel
+🎅 Santa Claus
+🤶 Mrs. Claus
+🦸 superhero
+🦹 supervillain
+🧙 mage
+🧚 fairy
+🧛 vampire
+🧜 merperson
+🧝 elf
+🧞 genie
+🧟 zombie
+🧌 troll
+💆 person getting massage
+💇 person getting haircut
+🚶 person walking
+🧍 person standing
+🧎 person kneeling
+🏃 person running
+💃 woman dancing
+🕺 man dancing
+🕴️ person in suit levitating
+👯 people with bunny ears
+🧖 person in steamy room
+🧗 person climbing
+🤺 person fencing
+🏇 horse racing
+⛷️ skier
+🏂 snowboarder
+🏌️ person golfing
+🏄 person surfing
+🚣 person rowing boat
+🏊 person swimming
+⛹️ person bouncing ball
+🏋️ person lifting weights
+🚴 person biking
+🚵 person mountain biking
+🤸 person cartwheeling
+🤼 people wrestling
+🤽 person playing water polo
+🤾 person playing handball
+🤹 person juggling
+🧘 person in lotus position
+🛀 person taking bath
+🛌 person in bed
+👭 women holding hands
+👫 woman and man holding hands
+👬 men holding hands
+💏 kiss
+💑 couple with heart
+👪 family
+🗣️ speaking head
+👤 bust in silhouette
+👥 busts in silhouette
+🫂 people hugging
+👣 footprints
+🐵 monkey face
+🐒 monkey
+🦍 gorilla
+🦧 orangutan
+🐶 dog face
+🐕 dog
+🦮 guide dog
+🐩 poodle
+🐺 wolf
+🦊 fox
+🦝 raccoon
+🐱 cat face
+🐈 cat
+🦁 lion
+🐯 tiger face
+🐅 tiger
+🐆 leopard
+🐴 horse face
+🐎 horse
+🦄 unicorn
+🦓 zebra
+🦌 deer
+🦬 bison
+🐮 cow face
+🐂 ox
+🐃 water buffalo
+🐄 cow
+🐷 pig face
+🐖 pig
+🐗 boar
+🐽 pig nose
+🐏 ram
+🐑 ewe
+🐐 goat
+🐪 camel
+🐫 two-hump camel
+🦙 llama
+🦒 giraffe
+🐘 elephant
+🦣 mammoth
+🦏 rhinoceros
+🦛 hippopotamus
+🐭 mouse face
+🐁 mouse
+🐀 rat
+🐹 hamster
+🐰 rabbit face
+🐇 rabbit
+🐿️ chipmunk
+🦫 beaver
+🦔 hedgehog
+🦇 bat
+🐻 bear
+🐨 koala
+🐼 panda
+🦥 sloth
+🦦 otter
+🦨 skunk
+🦘 kangaroo
+🦡 badger
+🐾 paw prints
+🦃 turkey
+🐔 chicken
+🐓 rooster
+🐣 hatching chick
+🐤 baby chick
+🐥 front-facing baby chick
+🐦 bird
+🐧 penguin
+🕊️ dove
+🦅 eagle
+🦆 duck
+🦢 swan
+🦉 owl
+🦤 dodo
+🪶 feather
+🦩 flamingo
+🦚 peacock
+🦜 parrot
+🐸 frog
+🐊 crocodile
+🐢 turtle
+🦎 lizard
+🐍 snake
+🐲 dragon face
+🐉 dragon
+🦕 sauropod
+🦖 T-Rex
+🐳 spouting whale
+🐋 whale
+🐬 dolphin
+🦭 seal
+🐟 fish
+🐠 tropical fish
+🐡 blowfish
+🦈 shark
+🐙 octopus
+🐚 spiral shell
+🪸 coral
+🐌 snail
+🦋 butterfly
+🐛 bug
+🐜 ant
+🐝 honeybee
+🪲 beetle
+🐞 lady beetle
+🦗 cricket
+🪳 cockroach
+🕷️ spider
+🕸️ spider web
+🦂 scorpion
+🦟 mosquito
+🪰 fly
+🪱 worm
+🦠 microbe
+💐 bouquet
+🌸 cherry blossom
+💮 white flower
+🪷 lotus
+🏵️ rosette
+🌹 rose
+🥀 wilted flower
+🌺 hibiscus
+🌻 sunflower
+🌼 blossom
+🌷 tulip
+🌱 seedling
+🪴 potted plant
+🌲 evergreen tree
+🌳 deciduous tree
+🌴 palm tree
+🌵 cactus
+🌾 sheaf of rice
+🌿 herb
+☘️ shamrock
+🍀 four leaf clover
+🍁 maple leaf
+🍂 fallen leaf
+🍃 leaf fluttering in wind
+🪹 empty nest
+🪺 nest with eggs
+🍇 grapes
+🍈 melon
+🍉 watermelon
+🍊 tangerine
+🍋 lemon
+🍌 banana
+🍍 pineapple
+🥭 mango
+🍎 red apple
+🍏 green apple
+🍐 pear
+🍑 peach
+🍒 cherries
+🍓 strawberry
+🫐 blueberries
+🥝 kiwi fruit
+🍅 tomato
+🫒 olive
+🥥 coconut
+🥑 avocado
+🍆 eggplant
+🥔 potato
+🥕 carrot
+🌽 ear of corn
+🌶️ hot pepper
+🫑 bell pepper
+🥒 cucumber
+🥬 leafy green
+🥦 broccoli
+🧄 garlic
+🧅 onion
+🍄 mushroom
+🥜 peanuts
+🫘 beans
+🌰 chestnut
+🍞 bread
+🥐 croissant
+🥖 baguette bread
+🫓 flatbread
+🥨 pretzel
+🥯 bagel
+🥞 pancakes
+🧇 waffle
+🧀 cheese wedge
+🍖 meat on bone
+🍗 poultry leg
+🥩 cut of meat
+🥓 bacon
+🍔 hamburger
+🍟 french fries
+🍕 pizza
+🌭 hot dog
+🥪 sandwich
+🌮 taco
+🌯 burrito
+🫔 tamale
+🥙 stuffed flatbread
+🧆 falafel
+🥚 egg
+🍳 cooking
+🥘 shallow pan of food
+🍲 pot of food
+🫕 fondue
+🥣 bowl with spoon
+🥗 green salad
+🍿 popcorn
+🧈 butter
+🧂 salt
+🥫 canned food
+🍱 bento box
+🍘 rice cracker
+🍙 rice ball
+🍚 cooked rice
+🍛 curry rice
+🍜 steaming bowl
+🍝 spaghetti
+🍠 roasted sweet potato
+🍢 oden
+🍣 sushi
+🍤 fried shrimp
+🍥 fish cake with swirl
+🥮 moon cake
+🍡 dango
+🥟 dumpling
+🥠 fortune cookie
+🥡 takeout box
+🦀 crab
+🦞 lobster
+🦐 shrimp
+🦑 squid
+🦪 oyster
+🍦 soft ice cream
+🍧 shaved ice
+🍨 ice cream
+🍩 doughnut
+🍪 cookie
+🎂 birthday cake
+🍰 shortcake
+🧁 cupcake
+🥧 pie
+🍫 chocolate bar
+🍬 candy
+🍭 lollipop
+🍮 custard
+🍯 honey pot
+🍼 baby bottle
+🥛 glass of milk
+☕ hot beverage
+🫖 teapot
+🍵 teacup without handle
+🍶 sake
+🍾 bottle with popping cork
+🍷 wine glass
+🍸 cocktail glass
+🍹 tropical drink
+🍺 beer mug
+🍻 clinking beer mugs
+🥂 clinking glasses
+🥃 tumbler glass
+🫗 pouring liquid
+🥤 cup with straw
+🧋 bubble tea
+🧃 beverage box
+🧉 mate
+🧊 ice
+🥢 chopsticks
+🍽️ fork and knife with plate
+🍴 fork and knife
+🥄 spoon
+🔪 kitchen knife
+🫙 jar
+🏺 amphora
+🌍 globe showing Europe-Africa
+🌎 globe showing Americas
+🌏 globe showing Asia-Australia
+🌐 globe with meridians
+🗺️ world map
+🗾 map of Japan
+🧭 compass
+🏔️ snow-capped mountain
+⛰️ mountain
+🌋 volcano
+🗻 mount fuji
+🏕️ camping
+🏖️ beach with umbrella
+🏜️ desert
+🏝️ desert island
+🏞️ national park
+🏟️ stadium
+🏛️ classical building
+🏗️ building construction
+🧱 brick
+🪨 rock
+🪵 wood
+🛖 hut
+🏘️ houses
+🏚️ derelict house
+🏠 house
+🏡 house with garden
+🏢 office building
+🏣 Japanese post office
+🏤 post office
+🏥 hospital
+🏦 bank
+🏨 hotel
+🏩 love hotel
+🏪 convenience store
+🏫 school
+🏬 department store
+🏭 factory
+🏯 Japanese castle
+🏰 castle
+💒 wedding
+🗼 Tokyo tower
+🗽 Statue of Liberty
+⛪ church
+🕌 mosque
+🛕 hindu temple
+🕍 synagogue
+⛩️ shinto shrine
+🕋 kaaba
+⛲ fountain
+⛺ tent
+🌁 foggy
+🌃 night with stars
+🏙️ cityscape
+🌄 sunrise over mountains
+🌅 sunrise
+🌆 cityscape at dusk
+🌇 sunset
+🌉 bridge at night
+♨️ hot springs
+🎠 carousel horse
+🛝 playground slide
+🎡 ferris wheel
+🎢 roller coaster
+💈 barber pole
+🎪 circus tent
+🚂 locomotive
+🚃 railway car
+🚄 high-speed train
+🚅 bullet train
+🚆 train
+🚇 metro
+🚈 light rail
+🚉 station
+🚊 tram
+🚝 monorail
+🚞 mountain railway
+🚋 tram car
+🚌 bus
+🚍 oncoming bus
+🚎 trolleybus
+🚐 minibus
+🚑 ambulance
+🚒 fire engine
+🚓 police car
+🚔 oncoming police car
+🚕 taxi
+🚖 oncoming taxi
+🚗 automobile
+🚘 oncoming automobile
+🚙 sport utility vehicle
+🛻 pickup truck
+🚚 delivery truck
+🚛 articulated lorry
+🚜 tractor
+🏎️ racing car
+🏍️ motorcycle
+🛵 motor scooter
+🦽 manual wheelchair
+🦼 motorized wheelchair
+🛺 auto rickshaw
+🚲 bicycle
+🛴 kick scooter
+🛹 skateboard
+🛼 roller skate
+🚏 bus stop
+🛣️ motorway
+🛤️ railway track
+🛢️ oil drum
+⛽ fuel pump
+🛞 wheel
+🚨 police car light
+🚥 horizontal traffic light
+🚦 vertical traffic light
+🛑 stop sign
+🚧 construction
+⚓ anchor
+🛟 ring buoy
+⛵ sailboat
+🛶 canoe
+🚤 speedboat
+🛳️ passenger ship
+⛴️ ferry
+🛥️ motor boat
+🚢 ship
+✈️ airplane
+🛩️ small airplane
+🛫 airplane departure
+🛬 airplane arrival
+🪂 parachute
+💺 seat
+🚁 helicopter
+🚟 suspension railway
+🚠 mountain cableway
+🚡 aerial tramway
+🛰️ satellite
+🚀 rocket
+🛸 flying saucer
+🛎️ bellhop bell
+🧳 luggage
+⌛ hourglass done
+⏳ hourglass not done
+⌚ watch
+⏰ alarm clock
+⏱️ stopwatch
+⏲️ timer clock
+🕰️ mantelpiece clock
+🕛 twelve o’clock
+🕧 twelve-thirty
+🕐 one o’clock
+🕜 one-thirty
+🕑 two o’clock
+🕝 two-thirty
+🕒 three o’clock
+🕞 three-thirty
+🕓 four o’clock
+🕟 four-thirty
+🕔 five o’clock
+🕠 five-thirty
+🕕 six o’clock
+🕡 six-thirty
+🕖 seven o’clock
+🕢 seven-thirty
+🕗 eight o’clock
+🕣 eight-thirty
+🕘 nine o’clock
+🕤 nine-thirty
+🕙 ten o’clock
+🕥 ten-thirty
+🕚 eleven o’clock
+🕦 eleven-thirty
+🌑 new moon
+🌒 waxing crescent moon
+🌓 first quarter moon
+🌔 waxing gibbous moon
+🌕 full moon
+🌖 waning gibbous moon
+🌗 last quarter moon
+🌘 waning crescent moon
+🌙 crescent moon
+🌚 new moon face
+🌛 first quarter moon face
+🌜 last quarter moon face
+🌡️ thermometer
+☀️ sun
+🌝 full moon face
+🌞 sun with face
+🪐 ringed planet
+⭐ star
+🌟 glowing star
+🌠 shooting star
+🌌 milky way
+☁️ cloud
+⛅ sun behind cloud
+⛈️ cloud with lightning and rain
+🌤️ sun behind small cloud
+🌥️ sun behind large cloud
+🌦️ sun behind rain cloud
+🌧️ cloud with rain
+🌨️ cloud with snow
+🌩️ cloud with lightning
+🌪️ tornado
+🌫️ fog
+🌬️ wind face
+🌀 cyclone
+🌈 rainbow
+🌂 closed umbrella
+☂️ umbrella
+☔ umbrella with rain drops
+⛱️ umbrella on ground
+⚡ high voltage
+❄️ snowflake
+☃️ snowman
+⛄ snowman without snow
+☄️ comet
+🔥 fire
+💧 droplet
+🌊 water wave
+🎃 jack-o-lantern
+🎄 Christmas tree
+🎆 fireworks
+🎇 sparkler
+🧨 firecracker
+✨ sparkles
+🎈 balloon
+🎉 party popper
+🎊 confetti ball
+🎋 tanabata tree
+🎍 pine decoration
+🎎 Japanese dolls
+🎏 carp streamer
+🎐 wind chime
+🎑 moon viewing ceremony
+🧧 red envelope
+🎀 ribbon
+🎁 wrapped gift
+🎗️ reminder ribbon
+🎟️ admission tickets
+🎫 ticket
+🎖️ military medal
+🏆 trophy
+🏅 sports medal
+🥇 1st place medal
+🥈 2nd place medal
+🥉 3rd place medal
+⚽ soccer ball
+⚾ baseball
+🥎 softball
+🏀 basketball
+🏐 volleyball
+🏈 american football
+🏉 rugby football
+🎾 tennis
+🥏 flying disc
+🎳 bowling
+🏏 cricket game
+🏑 field hockey
+🏒 ice hockey
+🥍 lacrosse
+🏓 ping pong
+🏸 badminton
+🥊 boxing glove
+🥋 martial arts uniform
+🥅 goal net
+⛳ flag in hole
+⛸️ ice skate
+🎣 fishing pole
+🤿 diving mask
+🎽 running shirt
+🎿 skis
+🛷 sled
+🥌 curling stone
+🎯 bullseye
+🪀 yo-yo
+🪁 kite
+🎱 pool 8 ball
+🔮 crystal ball
+🪄 magic wand
+🧿 nazar amulet
+🪬 hamsa
+🎮 video game
+🕹️ joystick
+🎰 slot machine
+🎲 game die
+🧩 puzzle piece
+🧸 teddy bear
+🪅 piñata
+🪩 mirror ball
+🪆 nesting dolls
+♠️ spade suit
+♥️ heart suit
+♦️ diamond suit
+♣️ club suit
+♟️ chess pawn
+🃏 joker
+🀄 mahjong red dragon
+🎴 flower playing cards
+🎭 performing arts
+🖼️ framed picture
+🎨 artist palette
+🧵 thread
+🪡 sewing needle
+🧶 yarn
+🪢 knot
+👓 glasses
+🕶️ sunglasses
+🥽 goggles
+🥼 lab coat
+🦺 safety vest
+👔 necktie
+👕 t-shirt
+👖 jeans
+🧣 scarf
+🧤 gloves
+🧥 coat
+🧦 socks
+👗 dress
+👘 kimono
+🥻 sari
+🩱 one-piece swimsuit
+🩲 briefs
+🩳 shorts
+👙 bikini
+👚 woman’s clothes
+👛 purse
+👜 handbag
+👝 clutch bag
+🛍️ shopping bags
+🎒 backpack
+🩴 thong sandal
+👞 man’s shoe
+👟 running shoe
+🥾 hiking boot
+🥿 flat shoe
+👠 high-heeled shoe
+👡 woman’s sandal
+🩰 ballet shoes
+👢 woman’s boot
+👑 crown
+👒 woman’s hat
+🎩 top hat
+🎓 graduation cap
+🧢 billed cap
+🪖 military helmet
+⛑️ rescue worker’s helmet
+📿 prayer beads
+💄 lipstick
+💍 ring
+💎 gem stone
+🔇 muted speaker
+🔈 speaker low volume
+🔉 speaker medium volume
+🔊 speaker high volume
+📢 loudspeaker
+📣 megaphone
+📯 postal horn
+🔔 bell
+🔕 bell with slash
+🎼 musical score
+🎵 musical note
+🎶 musical notes
+🎙️ studio microphone
+🎚️ level slider
+🎛️ control knobs
+🎤 microphone
+🎧 headphone
+📻 radio
+🎷 saxophone
+🪗 accordion
+🎸 guitar
+🎹 musical keyboard
+🎺 trumpet
+🎻 violin
+🪕 banjo
+🥁 drum
+🪘 long drum
+📱 mobile phone
+📲 mobile phone with arrow
+☎️ telephone
+📞 telephone receiver
+📟 pager
+📠 fax machine
+🔋 battery
+🪫 low battery
+🔌 electric plug
+💻 laptop
+🖥️ desktop computer
+🖨️ printer
+⌨️ keyboard
+🖱️ computer mouse
+🖲️ trackball
+💽 computer disk
+💾 floppy disk
+💿 optical disk
+📀 dvd
+🧮 abacus
+🎥 movie camera
+🎞️ film frames
+📽️ film projector
+🎬 clapper board
+📺 television
+📷 camera
+📸 camera with flash
+📹 video camera
+📼 videocassette
+🔍 magnifying glass tilted left
+🔎 magnifying glass tilted right
+🕯️ candle
+💡 light bulb
+🔦 flashlight
+🏮 red paper lantern
+🪔 diya lamp
+📔 notebook with decorative cover
+📕 closed book
+📖 open book
+📗 green book
+📘 blue book
+📙 orange book
+📚 books
+📓 notebook
+📒 ledger
+📃 page with curl
+📜 scroll
+📄 page facing up
+📰 newspaper
+🗞️ rolled-up newspaper
+📑 bookmark tabs
+🔖 bookmark
+🏷️ label
+💰 money bag
+🪙 coin
+💴 yen banknote
+💵 dollar banknote
+💶 euro banknote
+💷 pound banknote
+💸 money with wings
+💳 credit card
+🧾 receipt
+💹 chart increasing with yen
+✉️ envelope
+📧 e-mail
+📨 incoming envelope
+📩 envelope with arrow
+📤 outbox tray
+📥 inbox tray
+📦 package
+📫 closed mailbox with raised flag
+📪 closed mailbox with lowered flag
+📬 open mailbox with raised flag
+📭 open mailbox with lowered flag
+📮 postbox
+🗳️ ballot box with ballot
+✏️ pencil
+✒️ black nib
+🖋️ fountain pen
+🖊️ pen
+🖌️ paintbrush
+🖍️ crayon
+📝 memo
+💼 briefcase
+📁 file folder
+📂 open file folder
+🗂️ card index dividers
+📅 calendar
+📆 tear-off calendar
+🗒️ spiral notepad
+🗓️ spiral calendar
+📇 card index
+📈 chart increasing
+📉 chart decreasing
+📊 bar chart
+📋 clipboard
+📌 pushpin
+📍 round pushpin
+📎 paperclip
+🖇️ linked paperclips
+📏 straight ruler
+📐 triangular ruler
+✂️ scissors
+🗃️ card file box
+🗄️ file cabinet
+🗑️ wastebasket
+🔒 locked
+🔓 unlocked
+🔏 locked with pen
+🔐 locked with key
+🔑 key
+🗝️ old key
+🔨 hammer
+🪓 axe
+⛏️ pick
+⚒️ hammer and pick
+🛠️ hammer and wrench
+🗡️ dagger
+⚔️ crossed swords
+🔫 water pistol
+🪃 boomerang
+🏹 bow and arrow
+🛡️ shield
+🪚 carpentry saw
+🔧 wrench
+🪛 screwdriver
+🔩 nut and bolt
+⚙️ gear
+🗜️ clamp
+⚖️ balance scale
+🦯 white cane
+🔗 link
+⛓️ chains
+🪝 hook
+🧰 toolbox
+🧲 magnet
+🪜 ladder
+⚗️ alembic
+🧪 test tube
+🧫 petri dish
+🧬 dna
+🔬 microscope
+🔭 telescope
+📡 satellite antenna
+💉 syringe
+🩸 drop of blood
+💊 pill
+🩹 adhesive bandage
+🩼 crutch
+🩺 stethoscope
+🩻 x-ray
+🚪 door
+🛗 elevator
+🪞 mirror
+🪟 window
+🛏️ bed
+🛋️ couch and lamp
+🪑 chair
+🚽 toilet
+🪠 plunger
+🚿 shower
+🛁 bathtub
+🪤 mouse trap
+🪒 razor
+🧴 lotion bottle
+🧷 safety pin
+🧹 broom
+🧺 basket
+🧻 roll of paper
+🪣 bucket
+🧼 soap
+🫧 bubbles
+🪥 toothbrush
+🧽 sponge
+🧯 fire extinguisher
+🛒 shopping cart
+🚬 cigarette
+⚰️ coffin
+🪦 headstone
+⚱️ funeral urn
+🗿 moai
+🪧 placard
+🪪 identification card
+🏧 ATM sign
+🚮 litter in bin sign
+🚰 potable water
+♿ wheelchair symbol
+🚹 men’s room
+🚺 women’s room
+🚻 restroom
+🚼 baby symbol
+🚾 water closet
+🛂 passport control
+🛃 customs
+🛄 baggage claim
+🛅 left luggage
+⚠️ warning
+🚸 children crossing
+⛔ no entry
+🚫 prohibited
+🚳 no bicycles
+🚭 no smoking
+🚯 no littering
+🚱 non-potable water
+🚷 no pedestrians
+📵 no mobile phones
+🔞 no one under eighteen
+☢️ radioactive
+☣️ biohazard
+⬆️ up arrow
+↗️ up-right arrow
+➡️ right arrow
+↘️ down-right arrow
+⬇️ down arrow
+↙️ down-left arrow
+⬅️ left arrow
+↖️ up-left arrow
+↕️ up-down arrow
+↔️ left-right arrow
+↩️ right arrow curving left
+↪️ left arrow curving right
+⤴️ right arrow curving up
+⤵️ right arrow curving down
+🔃 clockwise vertical arrows
+🔄 counterclockwise arrows button
+🔙 BACK arrow
+🔚 END arrow
+🔛 ON! arrow
+🔜 SOON arrow
+🔝 TOP arrow
+🛐 place of worship
+⚛️ atom symbol
+🕉️ om
+✡️ star of David
+☸️ wheel of dharma
+☯️ yin yang
+✝️ latin cross
+☦️ orthodox cross
+☪️ star and crescent
+☮️ peace symbol
+🕎 menorah
+🔯 dotted six-pointed star
+♈ Aries
+♉ Taurus
+♊ Gemini
+♋ Cancer
+♌ Leo
+♍ Virgo
+♎ Libra
+♏ Scorpio
+♐ Sagittarius
+♑ Capricorn
+♒ Aquarius
+♓ Pisces
+⛎ Ophiuchus
+🔀 shuffle tracks button
+🔁 repeat button
+🔂 repeat single button
+▶️ play button
+⏩ fast-forward button
+⏭️ next track button
+⏯️ play or pause button
+◀️ reverse button
+⏪ fast reverse button
+⏮️ last track button
+🔼 upwards button
+⏫ fast up button
+🔽 downwards button
+⏬ fast down button
+⏸️ pause button
+⏹️ stop button
+⏺️ record button
+⏏️ eject button
+🎦 cinema
+🔅 dim button
+🔆 bright button
+📶 antenna bars
+📳 vibration mode
+📴 mobile phone off
+♀️ female sign
+♂️ male sign
+⚧️ transgender symbol
+✖️ multiply
+➕ plus
+➖ minus
+➗ divide
+🟰 heavy equals sign
+♾️ infinity
+‼️ double exclamation mark
+⁉️ exclamation question mark
+❓ red question mark
+❔ white question mark
+❕ white exclamation mark
+❗ red exclamation mark
+〰️ wavy dash
+💱 currency exchange
+💲 heavy dollar sign
+⚕️ medical symbol
+♻️ recycling symbol
+⚜️ fleur-de-lis
+🔱 trident emblem
+📛 name badge
+🔰 Japanese symbol for beginner
+⭕ hollow red circle
+✅ check mark button
+☑️ check box with check
+✔️ check mark
+❌ cross mark
+❎ cross mark button
+➰ curly loop
+➿ double curly loop
+〽️ part alternation mark
+✳️ eight-spoked asterisk
+✴️ eight-pointed star
+❇️ sparkle
+©️ copyright
+®️ registered
+™️ trade mark
+#️⃣ keycap: #
+*️⃣ keycap: *
+0️⃣ keycap: 0
+1️⃣ keycap: 1
+2️⃣ keycap: 2
+3️⃣ keycap: 3
+4️⃣ keycap: 4
+5️⃣ keycap: 5
+6️⃣ keycap: 6
+7️⃣ keycap: 7
+8️⃣ keycap: 8
+9️⃣ keycap: 9
+🔟 keycap: 10
+🔠 input latin uppercase
+🔡 input latin lowercase
+🔢 input numbers
+🔣 input symbols
+🔤 input latin letters
+🅰️ A button (blood type)
+🆎 AB button (blood type)
+🅱️ B button (blood type)
+🆑 CL button
+🆒 COOL button
+🆓 FREE button
+ℹ️ information
+🆔 ID button
+Ⓜ️ circled M
+🆕 NEW button
+🆖 NG button
+🅾️ O button (blood type)
+🆗 OK button
+🅿️ P button
+🆘 SOS button
+🆙 UP! button
+🆚 VS button
+🈁 Japanese “here” button
+🈂️ Japanese “service charge” button
+🈷️ Japanese “monthly amount” button
+🈶 Japanese “not free of charge” button
+🈯 Japanese “reserved” button
+🉐 Japanese “bargain” button
+🈹 Japanese “discount” button
+🈚 Japanese “free of charge” button
+🈲 Japanese “prohibited” button
+🉑 Japanese “acceptable” button
+🈸 Japanese “application” button
+🈴 Japanese “passing grade” button
+🈳 Japanese “vacancy” button
+㊗️ Japanese “congratulations” button
+㊙️ Japanese “secret” button
+🈺 Japanese “open for business” button
+🈵 Japanese “no vacancy” button
+🔴 red circle
+🟠 orange circle
+🟡 yellow circle
+🟢 green circle
+🔵 blue circle
+🟣 purple circle
+🟤 brown circle
+⚫ black circle
+⚪ white circle
+🟥 red square
+🟧 orange square
+🟨 yellow square
+🟩 green square
+🟦 blue square
+🟪 purple square
+🟫 brown square
+⬛ black large square
+⬜ white large square
+◼️ black medium square
+◻️ white medium square
+◾ black medium-small square
+◽ white medium-small square
+▪️ black small square
+▫️ white small square
+🔶 large orange diamond
+🔷 large blue diamond
+🔸 small orange diamond
+🔹 small blue diamond
+🔺 red triangle pointed up
+🔻 red triangle pointed down
+💠 diamond with a dot
+🔘 radio button
+🔳 white square button
+🔲 black square button
+🏁 chequered flag
+🚩 triangular flag
+🎌 crossed flags
+🏴 black flag
+🏳️ white flag
+🇦🇨 flag: Ascension Island
+🇦🇩 flag: Andorra
+🇦🇪 flag: United Arab Emirates
+🇦🇫 flag: Afghanistan
+🇦🇬 flag: Antigua & Barbuda
+🇦🇮 flag: Anguilla
+🇦🇱 flag: Albania
+🇦🇲 flag: Armenia
+🇦🇴 flag: Angola
+🇦🇶 flag: Antarctica
+🇦🇷 flag: Argentina
+🇦🇸 flag: American Samoa
+🇦🇹 flag: Austria
+🇦🇺 flag: Australia
+🇦🇼 flag: Aruba
+🇦🇽 flag: Åland Islands
+🇦🇿 flag: Azerbaijan
+🇧🇦 flag: Bosnia & Herzegovina
+🇧🇧 flag: Barbados
+🇧🇩 flag: Bangladesh
+🇧🇪 flag: Belgium
+🇧🇫 flag: Burkina Faso
+🇧🇬 flag: Bulgaria
+🇧🇭 flag: Bahrain
+🇧🇮 flag: Burundi
+🇧🇯 flag: Benin
+🇧🇱 flag: St. Barthélemy
+🇧🇲 flag: Bermuda
+🇧🇳 flag: Brunei
+🇧🇴 flag: Bolivia
+🇧🇶 flag: Caribbean Netherlands
+🇧🇷 flag: Brazil
+🇧🇸 flag: Bahamas
+🇧🇹 flag: Bhutan
+🇧🇻 flag: Bouvet Island
+🇧🇼 flag: Botswana
+🇧🇾 flag: Belarus
+🇧🇿 flag: Belize
+🇨🇦 flag: Canada
+🇨🇨 flag: Cocos (Keeling) Islands
+🇨🇩 flag: Congo - Kinshasa
+🇨🇫 flag: Central African Republic
+🇨🇬 flag: Congo - Brazzaville
+🇨🇭 flag: Switzerland
+🇨🇮 flag: Côte d’Ivoire
+🇨🇰 flag: Cook Islands
+🇨🇱 flag: Chile
+🇨🇲 flag: Cameroon
+🇨🇳 flag: China
+🇨🇴 flag: Colombia
+🇨🇵 flag: Clipperton Island
+🇨🇷 flag: Costa Rica
+🇨🇺 flag: Cuba
+🇨🇻 flag: Cape Verde
+🇨🇼 flag: Curaçao
+🇨🇽 flag: Christmas Island
+🇨🇾 flag: Cyprus
+🇨🇿 flag: Czechia
+🇩🇪 flag: Germany
+🇩🇬 flag: Diego Garcia
+🇩🇯 flag: Djibouti
+🇩🇰 flag: Denmark
+🇩🇲 flag: Dominica
+🇩🇴 flag: Dominican Republic
+🇩🇿 flag: Algeria
+🇪🇦 flag: Ceuta & Melilla
+🇪🇨 flag: Ecuador
+🇪🇪 flag: Estonia
+🇪🇬 flag: Egypt
+🇪🇭 flag: Western Sahara
+🇪🇷 flag: Eritrea
+🇪🇸 flag: Spain
+🇪🇹 flag: Ethiopia
+🇪🇺 flag: European Union
+🇫🇮 flag: Finland
+🇫🇯 flag: Fiji
+🇫🇰 flag: Falkland Islands
+🇫🇲 flag: Micronesia
+🇫🇴 flag: Faroe Islands
+🇫🇷 flag: France
+🇬🇦 flag: Gabon
+🇬🇧 flag: United Kingdom
+🇬🇩 flag: Grenada
+🇬🇪 flag: Georgia
+🇬🇫 flag: French Guiana
+🇬🇬 flag: Guernsey
+🇬🇭 flag: Ghana
+🇬🇮 flag: Gibraltar
+🇬🇱 flag: Greenland
+🇬🇲 flag: Gambia
+🇬🇳 flag: Guinea
+🇬🇵 flag: Guadeloupe
+🇬🇶 flag: Equatorial Guinea
+🇬🇷 flag: Greece
+🇬🇸 flag: South Georgia & South Sandwich Islands
+🇬🇹 flag: Guatemala
+🇬🇺 flag: Guam
+🇬🇼 flag: Guinea-Bissau
+🇬🇾 flag: Guyana
+🇭🇰 flag: Hong Kong SAR China
+🇭🇲 flag: Heard & McDonald Islands
+🇭🇳 flag: Honduras
+🇭🇷 flag: Croatia
+🇭🇹 flag: Haiti
+🇭🇺 flag: Hungary
+🇮🇨 flag: Canary Islands
+🇮🇩 flag: Indonesia
+🇮🇪 flag: Ireland
+🇮🇱 flag: Israel
+🇮🇲 flag: Isle of Man
+🇮🇳 flag: India
+🇮🇴 flag: British Indian Ocean Territory
+🇮🇶 flag: Iraq
+🇮🇷 flag: Iran
+🇮🇸 flag: Iceland
+🇮🇹 flag: Italy
+🇯🇪 flag: Jersey
+🇯🇲 flag: Jamaica
+🇯🇴 flag: Jordan
+🇯🇵 flag: Japan
+🇰🇪 flag: Kenya
+🇰🇬 flag: Kyrgyzstan
+🇰🇭 flag: Cambodia
+🇰🇮 flag: Kiribati
+🇰🇲 flag: Comoros
+🇰🇳 flag: St. Kitts & Nevis
+🇰🇵 flag: North Korea
+🇰🇷 flag: South Korea
+🇰🇼 flag: Kuwait
+🇰🇾 flag: Cayman Islands
+🇰🇿 flag: Kazakhstan
+🇱🇦 flag: Laos
+🇱🇧 flag: Lebanon
+🇱🇨 flag: St. Lucia
+🇱🇮 flag: Liechtenstein
+🇱🇰 flag: Sri Lanka
+🇱🇷 flag: Liberia
+🇱🇸 flag: Lesotho
+🇱🇹 flag: Lithuania
+🇱🇺 flag: Luxembourg
+🇱🇻 flag: Latvia
+🇱🇾 flag: Libya
+🇲🇦 flag: Morocco
+🇲🇨 flag: Monaco
+🇲🇩 flag: Moldova
+🇲🇪 flag: Montenegro
+🇲🇫 flag: St. Martin
+🇲🇬 flag: Madagascar
+🇲🇭 flag: Marshall Islands
+🇲🇰 flag: North Macedonia
+🇲🇱 flag: Mali
+🇲🇲 flag: Myanmar (Burma)
+🇲🇳 flag: Mongolia
+🇲🇴 flag: Macao SAR China
+🇲🇵 flag: Northern Mariana Islands
+🇲🇶 flag: Martinique
+🇲🇷 flag: Mauritania
+🇲🇸 flag: Montserrat
+🇲🇹 flag: Malta
+🇲🇺 flag: Mauritius
+🇲🇻 flag: Maldives
+🇲🇼 flag: Malawi
+🇲🇽 flag: Mexico
+🇲🇾 flag: Malaysia
+🇲🇿 flag: Mozambique
+🇳🇦 flag: Namibia
+🇳🇨 flag: New Caledonia
+🇳🇪 flag: Niger
+🇳🇫 flag: Norfolk Island
+🇳🇬 flag: Nigeria
+🇳🇮 flag: Nicaragua
+🇳🇱 flag: Netherlands
+🇳🇴 flag: Norway
+🇳🇵 flag: Nepal
+🇳🇷 flag: Nauru
+🇳🇺 flag: Niue
+🇳🇿 flag: New Zealand
+🇴🇲 flag: Oman
+🇵🇦 flag: Panama
+🇵🇪 flag: Peru
+🇵🇫 flag: French Polynesia
+🇵🇬 flag: Papua New Guinea
+🇵🇭 flag: Philippines
+🇵🇰 flag: Pakistan
+🇵🇱 flag: Poland
+🇵🇲 flag: St. Pierre & Miquelon
+🇵🇳 flag: Pitcairn Islands
+🇵🇷 flag: Puerto Rico
+🇵🇸 flag: Palestinian Territories
+🇵🇹 flag: Portugal
+🇵🇼 flag: Palau
+🇵🇾 flag: Paraguay
+🇶🇦 flag: Qatar
+🇷🇪 flag: Réunion
+🇷🇴 flag: Romania
+🇷🇸 flag: Serbia
+🇷🇺 flag: Russia
+🇷🇼 flag: Rwanda
+🇸🇦 flag: Saudi Arabia
+🇸🇧 flag: Solomon Islands
+🇸🇨 flag: Seychelles
+🇸🇩 flag: Sudan
+🇸🇪 flag: Sweden
+🇸🇬 flag: Singapore
+🇸🇭 flag: St. Helena
+🇸🇮 flag: Slovenia
+🇸🇯 flag: Svalbard & Jan Mayen
+🇸🇰 flag: Slovakia
+🇸🇱 flag: Sierra Leone
+🇸🇲 flag: San Marino
+🇸🇳 flag: Senegal
+🇸🇴 flag: Somalia
+🇸🇷 flag: Suriname
+🇸🇸 flag: South Sudan
+🇸🇹 flag: São Tomé & Príncipe
+🇸🇻 flag: El Salvador
+🇸🇽 flag: Sint Maarten
+🇸🇾 flag: Syria
+🇸🇿 flag: Eswatini
+🇹🇦 flag: Tristan da Cunha
+🇹🇨 flag: Turks & Caicos Islands
+🇹🇩 flag: Chad
+🇹🇫 flag: French Southern Territories
+🇹🇬 flag: Togo
+🇹🇭 flag: Thailand
+🇹🇯 flag: Tajikistan
+🇹🇰 flag: Tokelau
+🇹🇱 flag: Timor-Leste
+🇹🇲 flag: Turkmenistan
+🇹🇳 flag: Tunisia
+🇹🇴 flag: Tonga
+🇹🇷 flag: Turkey
+🇹🇹 flag: Trinidad & Tobago
+🇹🇻 flag: Tuvalu
+🇹🇼 flag: Taiwan
+🇹🇿 flag: Tanzania
+🇺🇦 flag: Ukraine
+🇺🇬 flag: Uganda
+🇺🇲 flag: U.S. Outlying Islands
+🇺🇳 flag: United Nations
+🇺🇸 flag: United States
+🇺🇾 flag: Uruguay
+🇺🇿 flag: Uzbekistan
+🇻🇦 flag: Vatican City
+🇻🇨 flag: St. Vincent & Grenadines
+🇻🇪 flag: Venezuela
+🇻🇬 flag: British Virgin Islands
+🇻🇮 flag: U.S. Virgin Islands
+🇻🇳 flag: Vietnam
+🇻🇺 flag: Vanuatu
+🇼🇫 flag: Wallis & Futuna
+🇼🇸 flag: Samoa
+🇽🇰 flag: Kosovo
+🇾🇪 flag: Yemen
+🇾🇹 flag: Mayotte
+🇿🇦 flag: South Africa
+🇿🇲 flag: Zambia
+🇿🇼 flag: Zimbabwe
+🏴󠁧󠁢󠁥󠁮󠁧󠁿 flag: England
+🏴󠁧󠁢󠁳󠁣󠁴󠁿 flag: Scotland
+🏴󠁧󠁢󠁷󠁬󠁳󠁿 flag: Wales
diff --git a/.local/share/larbs/chars/font-awesome b/.local/share/larbs/chars/font-awesome
new file mode 100644
index 0000000..3283be3
--- /dev/null
+++ b/.local/share/larbs/chars/font-awesome
@@ -0,0 +1,1456 @@
+ 500px; f26e
+ accessible-icon; f368
+ accusoft; f369
+ acquisitions-incorporated; f6af
+ ad; f641
+ address-book; f2b9
+ address-card; f2bb
+ adjust; f042
+ adn; f170
+ adversal; f36a
+ affiliatetheme; f36b
+ air-freshener; f5d0
+ airbnb; f834
+ algolia; f36c
+ align-center; f037
+ align-justify; f039
+ align-left; f036
+ align-right; f038
+ alipay; f642
+ allergies; f461
+ amazon; f270
+ amazon-pay; f42c
+ ambulance; f0f9
+ american-sign-language-interpreting; f2a3
+ amilia; f36d
+ anchor; f13d
+ android; f17b
+ angellist; f209
+ angle-double-down; f103
+ angle-double-left; f100
+ angle-double-right; f101
+ angle-double-up; f102
+ angle-down; f107
+ angle-left; f104
+ angle-right; f105
+ angle-up; f106
+ angry; f556
+ angrycreative; f36e
+ angular; f420
+ ankh; f644
+ app-store; f36f
+ app-store-ios; f370
+ apper; f371
+ apple; f179
+ apple-alt; f5d1
+ apple-pay; f415
+ archive; f187
+ archway; f557
+ arrow-alt-circle-down; f358
+ arrow-alt-circle-left; f359
+ arrow-alt-circle-right; f35a
+ arrow-alt-circle-up; f35b
+ arrow-circle-down; f0ab
+ arrow-circle-left; f0a8
+ arrow-circle-right; f0a9
+ arrow-circle-up; f0aa
+ arrow-down; f063
+ arrow-left; f060
+ arrow-right; f061
+ arrow-up; f062
+ arrows-alt; f0b2
+ arrows-alt-h; f337
+ arrows-alt-v; f338
+ artstation; f77a
+ assistive-listening-systems; f2a2
+ asterisk; f069
+ asymmetrik; f372
+ at; f1fa
+ atlas; f558
+ atlassian; f77b
+ atom; f5d2
+ audible; f373
+ audio-description; f29e
+ autoprefixer; f41c
+ avianex; f374
+ aviato; f421
+ award; f559
+ aws; f375
+ baby; f77c
+ baby-carriage; f77d
+ backspace; f55a
+ backward; f04a
+ bacon; f7e5
+ bacteria e059
+ bacterium e05a
+ bahai; f666
+ balance-scale; f24e
+ balance-scale-left; f515
+ balance-scale-right; f516
+ ban; f05e
+ band-aid; f462
+ bandcamp; f2d5
+ barcode; f02a
+ bars; f0c9
+ baseball-ball; f433
+ basketball-ball; f434
+ bath; f2cd
+ battery-empty; f244
+ battery-full; f240
+ battery-half; f242
+ battery-quarter; f243
+ battery-three-quarters; f241
+ battle-net; f835
+ bed; f236
+ beer; f0fc
+ behance; f1b4
+ behance-square; f1b5
+ bell; f0f3
+ bell-slash; f1f6
+ bezier-curve; f55b
+ bible; f647
+ bicycle; f206
+ biking; f84a
+ bimobject; f378
+ binoculars; f1e5
+ biohazard; f780
+ birthday-cake; f1fd
+ bitbucket; f171
+ bitcoin; f379
+ bity; f37a
+ black-tie; f27e
+ blackberry; f37b
+ blender; f517
+ blender-phone; f6b6
+ blind; f29d
+ blog; f781
+ blogger; f37c
+ blogger-b; f37d
+ bluetooth; f293
+ bluetooth-b; f294
+ bold; f032
+ bolt; f0e7
+ bomb; f1e2
+ bone; f5d7
+ bong; f55c
+ book; f02d
+ book-dead; f6b7
+ book-medical; f7e6
+ book-open; f518
+ book-reader; f5da
+ bookmark; f02e
+ bootstrap; f836
+ border-all; f84c
+ border-none; f850
+ border-style; f853
+ bowling-ball; f436
+ box; f466
+ box-open; f49e
+ box-tissue e05b
+ boxes; f468
+ braille; f2a1
+ brain; f5dc
+ bread-slice; f7ec
+ briefcase; f0b1
+ briefcase-medical; f469
+ broadcast-tower; f519
+ broom; f51a
+ brush; f55d
+ btc; f15a
+ buffer; f837
+ bug; f188
+ building; f1ad
+ bullhorn; f0a1
+ bullseye; f140
+ burn; f46a
+ buromobelexperte; f37f
+ bus; f207
+ bus-alt; f55e
+ business-time; f64a
+ buy-n-large; f8a6
+ calculator; f1ec
+ calendar; f133
+ calendar-alt; f073
+ calendar-check; f274
+ calendar-day; f783
+ calendar-minus; f272
+ calendar-plus; f271
+ calendar-times; f273
+ calendar-week; f784
+ camera; f030
+ camera-retro; f083
+ campground; f6bb
+ canadian-maple-leaf; f785
+ candy-cane; f786
+ cannabis; f55f
+ capsules; f46b
+ car; f1b9
+ car-alt; f5de
+ car-battery; f5df
+ car-crash; f5e1
+ car-side; f5e4
+ caravan; f8ff
+ caret-down; f0d7
+ caret-left; f0d9
+ caret-right; f0da
+ caret-square-down; f150
+ caret-square-left; f191
+ caret-square-right; f152
+ caret-square-up; f151
+ caret-up; f0d8
+ carrot; f787
+ cart-arrow-down; f218
+ cart-plus; f217
+ cash-register; f788
+ cat; f6be
+ cc-amazon-pay; f42d
+ cc-amex; f1f3
+ cc-apple-pay; f416
+ cc-diners-club; f24c
+ cc-discover; f1f2
+ cc-jcb; f24b
+ cc-mastercard; f1f1
+ cc-paypal; f1f4
+ cc-stripe; f1f5
+ cc-visa; f1f0
+ centercode; f380
+ centos; f789
+ certificate; f0a3
+ chair; f6c0
+ chalkboard; f51b
+ chalkboard-teacher; f51c
+ charging-station; f5e7
+ chart-area; f1fe
+ chart-bar; f080
+ chart-line; f201
+ chart-pie; f200
+ check; f00c
+ check-circle; f058
+ check-double; f560
+ check-square; f14a
+ cheese; f7ef
+ chess; f439
+ chess-bishop; f43a
+ chess-board; f43c
+ chess-king; f43f
+ chess-knight; f441
+ chess-pawn; f443
+ chess-queen; f445
+ chess-rook; f447
+ chevron-circle-down; f13a
+ chevron-circle-left; f137
+ chevron-circle-right; f138
+ chevron-circle-up; f139
+ chevron-down; f078
+ chevron-left; f053
+ chevron-right; f054
+ chevron-up; f077
+ child; f1ae
+ chrome; f268
+ chromecast; f838
+ church; f51d
+ circle; f111
+ circle-notch; f1ce
+ city; f64f
+ clinic-medical; f7f2
+ clipboard; f328
+ clipboard-check; f46c
+ clipboard-list; f46d
+ clock; f017
+ clone; f24d
+ closed-captioning; f20a
+ cloud; f0c2
+ cloud-download-alt; f381
+ cloud-meatball; f73b
+ cloud-moon; f6c3
+ cloud-moon-rain; f73c
+ cloud-rain; f73d
+ cloud-showers-heavy; f740
+ cloud-sun; f6c4
+ cloud-sun-rain; f743
+ cloud-upload-alt; f382
+ cloudflare e07d
+ cloudscale; f383
+ cloudsmith; f384
+ cloudversify; f385
+ cocktail; f561
+ code; f121
+ code-branch; f126
+ codepen; f1cb
+ codiepie; f284
+ coffee; f0f4
+ cog; f013
+ cogs; f085
+ coins; f51e
+ columns; f0db
+ comment; f075
+ comment-alt; f27a
+ comment-dollar; f651
+ comment-dots; f4ad
+ comment-medical; f7f5
+ comment-slash; f4b3
+ comments; f086
+ comments-dollar; f653
+ compact-disc; f51f
+ compass; f14e
+ compress; f066
+ compress-alt; f422
+ compress-arrows-alt; f78c
+ concierge-bell; f562
+ confluence; f78d
+ connectdevelop; f20e
+ contao; f26d
+ cookie; f563
+ cookie-bite; f564
+ copy; f0c5
+ copyright; f1f9
+ cotton-bureau; f89e
+ couch; f4b8
+ cpanel; f388
+ creative-commons; f25e
+ creative-commons-by; f4e7
+ creative-commons-nc; f4e8
+ creative-commons-nc-eu; f4e9
+ creative-commons-nc-jp; f4ea
+ creative-commons-nd; f4eb
+ creative-commons-pd; f4ec
+ creative-commons-pd-alt; f4ed
+ creative-commons-remix; f4ee
+ creative-commons-sa; f4ef
+ creative-commons-sampling; f4f0
+ creative-commons-sampling-plus; f4f1
+ creative-commons-share; f4f2
+ creative-commons-zero; f4f3
+ credit-card; f09d
+ critical-role; f6c9
+ crop; f125
+ crop-alt; f565
+ cross; f654
+ crosshairs; f05b
+ crow; f520
+ crown; f521
+ crutch; f7f7
+ css3; f13c
+ css3-alt; f38b
+ cube; f1b2
+ cubes; f1b3
+ cut; f0c4
+ cuttlefish; f38c
+ d-and-d; f38d
+ d-and-d-beyond; f6ca
+ dailymotion e052
+ dashcube; f210
+ database; f1c0
+ deaf; f2a4
+ deezer e077
+ delicious; f1a5
+ democrat; f747
+ deploydog; f38e
+ deskpro; f38f
+ desktop; f108
+ dev; f6cc
+ deviantart; f1bd
+ dharmachakra; f655
+ dhl; f790
+ diagnoses; f470
+ diaspora; f791
+ dice; f522
+ dice-d20; f6cf
+ dice-d6; f6d1
+ dice-five; f523
+ dice-four; f524
+ dice-one; f525
+ dice-six; f526
+ dice-three; f527
+ dice-two; f528
+ digg; f1a6
+ digital-ocean; f391
+ digital-tachograph; f566
+ directions; f5eb
+ discord; f392
+ discourse; f393
+ disease; f7fa
+ divide; f529
+ dizzy; f567
+ dna; f471
+ dochub; f394
+ docker; f395
+ dog; f6d3
+ dollar-sign; f155
+ dolly; f472
+ dolly-flatbed; f474
+ donate; f4b9
+ door-closed; f52a
+ door-open; f52b
+ dot-circle; f192
+ dove; f4ba
+ download; f019
+ draft2digital; f396
+ drafting-compass; f568
+ dragon; f6d5
+ draw-polygon; f5ee
+ dribbble; f17d
+ dribbble-square; f397
+ dropbox; f16b
+ drum; f569
+ drum-steelpan; f56a
+ drumstick-bite; f6d7
+ drupal; f1a9
+ dumbbell; f44b
+ dumpster; f793
+ dumpster-fire; f794
+ dungeon; f6d9
+ dyalog; f399
+ earlybirds; f39a
+ ebay; f4f4
+ edge; f282
+ edge-legacy e078
+ edit; f044
+ egg; f7fb
+ eject; f052
+ elementor; f430
+ ellipsis-h; f141
+ ellipsis-v; f142
+ ello; f5f1
+ ember; f423
+ empire; f1d1
+ envelope; f0e0
+ envelope-open; f2b6
+ envelope-open-text; f658
+ envelope-square; f199
+ envira; f299
+ equals; f52c
+ eraser; f12d
+ erlang; f39d
+ ethereum; f42e
+ ethernet; f796
+ etsy; f2d7
+ euro-sign; f153
+ evernote; f839
+ exchange-alt; f362
+ exclamation; f12a
+ exclamation-circle; f06a
+ exclamation-triangle; f071
+ expand; f065
+ expand-alt; f424
+ expand-arrows-alt; f31e
+ expeditedssl; f23e
+ external-link-alt; f35d
+ external-link-square-alt; f360
+ eye; f06e
+ eye-dropper; f1fb
+ eye-slash; f070
+ ; facebook; f09a
+ ; facebook-f; f39e
+ ; facebook-messenger; f39f
+ ; facebook-square; f082
+ ; fan; f863
+ ; fantasy-flight-games; f6dc
+ ; fast-backward; f049
+ ; fast-forward; f050
+ ; faucet e005
+ ; fax; f1ac
+ ; feather; f52d
+ ; feather-alt; f56b
+ ; fedex; f797
+ ; fedora; f798
+ ; female; f182
+ ; fighter-jet; f0fb
+ ; figma; f799
+ ; file; f15b
+ ; file-alt; f15c
+ ; file-archive; f1c6
+ ; file-audio; f1c7
+ ; file-code; f1c9
+ ; file-contract; f56c
+ ; file-csv; f6dd
+ ; file-download; f56d
+ ; file-excel; f1c3
+ ; file-export; f56e
+ ; file-image; f1c5
+ ; file-import; f56f
+ ; file-invoice; f570
+ ; file-invoice-dollar; f571
+ ; file-medical; f477
+ ; file-medical-alt; f478
+ ; file-pdf; f1c1
+ ; file-powerpoint; f1c4
+ ; file-prescription; f572
+ ; file-signature; f573
+ ; file-upload; f574
+ ; file-video; f1c8
+ ; file-word; f1c2
+ ; fill; f575
+ ; fill-drip; f576
+ ; film; f008
+ ; filter; f0b0
+ ; fingerprint; f577
+ ; fire; f06d
+ ; fire-alt; f7e4
+ ; fire-extinguisher; f134
+ ; firefox; f269
+ ; firefox-browser e007
+ ; first-aid; f479
+ ; first-order; f2b0
+ ; first-order-alt; f50a
+ ; firstdraft; f3a1
+ ; fish; f578
+ ; fist-raised; f6de
+ ; flag; f024
+ ; flag-checkered; f11e
+ ; flag-usa; f74d
+ ; flask; f0c3
+ ; flickr; f16e
+ ; flipboard; f44d
+ ; flushed; f579
+ ; fly; f417
+ ; folder; f07b
+ ; folder-minus; f65d
+ ; folder-open; f07c
+ ; folder-plus; f65e
+ ; font; f031
+ ; font-awesome; f2b4
+ ; font-awesome-alt; f35c
+ ; font-awesome-flag; f425
+ ; fonticons; f280
+ ; fonticons-fi; f3a2
+ ; football-ball; f44e
+ ; fort-awesome; f286
+ ; fort-awesome-alt; f3a3
+ ; forumbee; f211
+ ; forward; f04e
+ ; foursquare; f180
+ ; free-code-camp; f2c5
+ ; freebsd; f3a4
+ ; frog; f52e
+ ; frown; f119
+ ; frown-open; f57a
+ ; fulcrum; f50b
+ ; funnel-dollar; f662
+ ; futbol; f1e3
+ galactic-republic; f50c
+ galactic-senate; f50d
+ gamepad; f11b
+ gas-pump; f52f
+ gavel; f0e3
+ gem; f3a5
+ genderless; f22d
+ get-pocket; f265
+ gg; f260
+ gg-circle; f261
+ ghost; f6e2
+ gift; f06b
+ gifts; f79c
+ git; f1d3
+ git-alt; f841
+ git-square; f1d2
+ github; f09b
+ github-alt; f113
+ github-square; f092
+ gitkraken; f3a6
+ gitlab; f296
+ gitter; f426
+ glass-cheers; f79f
+ glass-martini; f000
+ glass-martini-alt; f57b
+ glass-whiskey; f7a0
+ glasses; f530
+ glide; f2a5
+ glide-g; f2a6
+ globe; f0ac
+ globe-africa; f57c
+ globe-americas; f57d
+ globe-asia; f57e
+ globe-europe; f7a2
+ gofore; f3a7
+ golf-ball; f450
+ goodreads; f3a8
+ goodreads-g; f3a9
+ google; f1a0
+ google-drive; f3aa
+ google-pay e079
+ google-play; f3ab
+ google-plus; f2b3
+ google-plus-g; f0d5
+ google-plus-square; f0d4
+ google-wallet; f1ee
+ gopuram; f664
+ graduation-cap; f19d
+ gratipay; f184
+ grav; f2d6
+ greater-than; f531
+ greater-than-equal; f532
+ grimace; f57f
+ grin; f580
+ grin-alt; f581
+ grin-beam; f582
+ grin-beam-sweat; f583
+ grin-hearts; f584
+ grin-squint; f585
+ grin-squint-tears; f586
+ grin-stars; f587
+ grin-tears; f588
+ grin-tongue; f589
+ grin-tongue-squint; f58a
+ grin-tongue-wink; f58b
+ grin-wink; f58c
+ grip-horizontal; f58d
+ grip-lines; f7a4
+ grip-lines-vertical; f7a5
+ grip-vertical; f58e
+ gripfire; f3ac
+ grunt; f3ad
+ guilded e07e
+ guitar; f7a6
+ gulp; f3ae
+ h-square; f0fd
+ hacker-news; f1d4
+ hacker-news-square; f3af
+ hackerrank; f5f7
+ hamburger; f805
+ hammer; f6e3
+ hamsa; f665
+ hand-holding; f4bd
+ hand-holding-heart; f4be
+ hand-holding-medical e05c
+ hand-holding-usd; f4c0
+ hand-holding-water; f4c1
+ hand-lizard; f258
+ hand-middle-finger; f806
+ hand-paper; f256
+ hand-peace; f25b
+ hand-point-down; f0a7
+ hand-point-left; f0a5
+ hand-point-right; f0a4
+ hand-point-up; f0a6
+ hand-pointer; f25a
+ hand-rock; f255
+ hand-scissors; f257
+ hand-sparkles e05d
+ hand-spock; f259
+ hands; f4c2
+ hands-helping; f4c4
+ hands-wash e05e
+ handshake; f2b5
+ handshake-alt-slash e05f
+ handshake-slash e060
+ hanukiah; f6e6
+ hard-hat; f807
+ hashtag; f292
+ hat-cowboy; f8c0
+ hat-cowboy-side; f8c1
+ hat-wizard; f6e8
+ hdd; f0a0
+ head-side-cough e061
+ head-side-cough-slash e062
+ head-side-mask e063
+ head-side-virus e064
+ heading; f1dc
+ headphones; f025
+ headphones-alt; f58f
+ headset; f590
+ heart; f004
+ heart-broken; f7a9
+ heartbeat; f21e
+ helicopter; f533
+ highlighter; f591
+ hiking; f6ec
+ hippo; f6ed
+ hips; f452
+ hire-a-helper; f3b0
+ history; f1da
+ hive e07f
+ hockey-puck; f453
+ holly-berry; f7aa
+ home; f015
+ hooli; f427
+ hornbill; f592
+ horse; f6f0
+ horse-head; f7ab
+ hospital; f0f8
+ hospital-alt; f47d
+ hospital-symbol; f47e
+ hospital-user; f80d
+ hot-tub; f593
+ hotdog; f80f
+ hotel; f594
+ hotjar; f3b1
+ hourglass; f254
+ hourglass-end; f253
+ hourglass-half; f252
+ hourglass-start; f251
+ house-damage; f6f1
+ house-user e065
+ houzz; f27c
+ hryvnia; f6f2
+ html5; f13b
+ hubspot; f3b2
+ i-cursor; f246
+ ice-cream; f810
+ icicles; f7ad
+ icons; f86d
+ id-badge; f2c1
+ id-card; f2c2
+ id-card-alt; f47f
+ ideal e013
+ igloo; f7ae
+ image; f03e
+ images; f302
+ imdb; f2d8
+ inbox; f01c
+ indent; f03c
+ industry; f275
+ infinity; f534
+ info; f129
+ info-circle; f05a
+ innosoft e080
+ instagram; f16d
+ instagram-square e055
+ instalod e081
+ intercom; f7af
+ internet-explorer; f26b
+ invision; f7b0
+ ioxhost; f208
+ italic; f033
+ itch-io; f83a
+ itunes; f3b4
+ itunes-note; f3b5
+ java; f4e4
+ jedi; f669
+ jedi-order; f50e
+ jenkins; f3b6
+ jira; f7b1
+ joget; f3b7
+ joint; f595
+ joomla; f1aa
+ journal-whills; f66a
+ js; f3b8
+ js-square; f3b9
+ jsfiddle; f1cc
+ kaaba; f66b
+ kaggle; f5fa
+ key; f084
+ keybase; f4f5
+ keyboard; f11c
+ keycdn; f3ba
+ khanda; f66d
+ kickstarter; f3bb
+ kickstarter-k; f3bc
+ kiss; f596
+ kiss-beam; f597
+ kiss-wink-heart; f598
+ kiwi-bird; f535
+ korvue; f42f
+ landmark; f66f
+ language; f1ab
+ laptop; f109
+ laptop-code; f5fc
+ laptop-house e066
+ laptop-medical; f812
+ laravel; f3bd
+ lastfm; f202
+ lastfm-square; f203
+ laugh; f599
+ laugh-beam; f59a
+ laugh-squint; f59b
+ laugh-wink; f59c
+ layer-group; f5fd
+ leaf; f06c
+ leanpub; f212
+ lemon; f094
+ less; f41d
+ less-than; f536
+ less-than-equal; f537
+ level-down-alt; f3be
+ level-up-alt; f3bf
+ life-ring; f1cd
+ lightbulb; f0eb
+ line; f3c0
+ link; f0c1
+ linkedin; f08c
+ linkedin-in; f0e1
+ linode; f2b8
+ linux; f17c
+ lira-sign; f195
+ list; f03a
+ list-alt; f022
+ list-ol; f0cb
+ list-ul; f0ca
+ location-arrow; f124
+ lock; f023
+ lock-open; f3c1
+ long-arrow-alt-down; f309
+ long-arrow-alt-left; f30a
+ long-arrow-alt-right; f30b
+ long-arrow-alt-up; f30c
+ low-vision; f2a8
+ luggage-cart; f59d
+ lungs; f604
+ lungs-virus e067
+ lyft; f3c3
+ magento; f3c4
+ magic; f0d0
+ magnet; f076
+ mail-bulk; f674
+ mailchimp; f59e
+ male; f183
+ mandalorian; f50f
+ map; f279
+ map-marked; f59f
+ map-marked-alt; f5a0
+ map-marker; f041
+ map-marker-alt; f3c5
+ map-pin; f276
+ map-signs; f277
+ markdown; f60f
+ marker; f5a1
+ mars; f222
+ mars-double; f227
+ mars-stroke; f229
+ mars-stroke-h; f22b
+ mars-stroke-v; f22a
+ mask; f6fa
+ mastodon; f4f6
+ maxcdn; f136
+ mdb; f8ca
+ medal; f5a2
+ medapps; f3c6
+ medium; f23a
+ medium-m; f3c7
+ medkit; f0fa
+ medrt; f3c8
+ meetup; f2e0
+ megaport; f5a3
+ meh; f11a
+ meh-blank; f5a4
+ meh-rolling-eyes; f5a5
+ memory; f538
+ mendeley; f7b3
+ menorah; f676
+ mercury; f223
+ meteor; f753
+ microblog e01a
+ microchip; f2db
+ microphone; f130
+ microphone-alt; f3c9
+ microphone-alt-slash; f539
+ microphone-slash; f131
+ microscope; f610
+ microsoft; f3ca
+ minus; f068
+ minus-circle; f056
+ minus-square; f146
+ mitten; f7b5
+ mix; f3cb
+ mixcloud; f289
+ mixer e056
+ mizuni; f3cc
+ mobile; f10b
+ mobile-alt; f3cd
+ modx; f285
+ monero; f3d0
+ money-bill; f0d6
+ money-bill-alt; f3d1
+ money-bill-wave; f53a
+ money-bill-wave-alt; f53b
+ money-check; f53c
+ money-check-alt; f53d
+ monument; f5a6
+ moon; f186
+ mortar-pestle; f5a7
+ mosque; f678
+ motorcycle; f21c
+ mountain; f6fc
+ mouse; f8cc
+ mouse-pointer; f245
+ mug-hot; f7b6
+ music; f001
+ napster; f3d2
+ neos; f612
+ network-wired; f6ff
+ neuter; f22c
+ newspaper; f1ea
+ nimblr; f5a8
+ node; f419
+ node-js; f3d3
+ not-equal; f53e
+ notes-medical; f481
+ npm; f3d4
+ ns8; f3d5
+ nutritionix; f3d6
+ object-group; f247
+ object-ungroup; f248
+ octopus-deploy e082
+ odnoklassniki; f263
+ odnoklassniki-square; f264
+ oil-can; f613
+ old-republic; f510
+ om; f679
+ opencart; f23d
+ openid; f19b
+ opera; f26a
+ optin-monster; f23c
+ orcid; f8d2
+ osi; f41a
+ otter; f700
+ outdent; f03b
+ page4; f3d7
+ pagelines; f18c
+ pager; f815
+ paint-brush; f1fc
+ paint-roller; f5aa
+ palette; f53f
+ palfed; f3d8
+ pallet; f482
+ paper-plane; f1d8
+ paperclip; f0c6
+ parachute-box; f4cd
+ paragraph; f1dd
+ parking; f540
+ passport; f5ab
+ pastafarianism; f67b
+ paste; f0ea
+ patreon; f3d9
+ pause; f04c
+ pause-circle; f28b
+ paw; f1b0
+ paypal; f1ed
+ peace; f67c
+ pen; f304
+ pen-alt; f305
+ pen-fancy; f5ac
+ pen-nib; f5ad
+ pen-square; f14b
+ pencil-alt; f303
+ pencil-ruler; f5ae
+ penny-arcade; f704
+ people-arrows e068
+ people-carry; f4ce
+ pepper-hot; f816
+ perbyte e083
+ percent; f295
+ percentage; f541
+ periscope; f3da
+ person-booth; f756
+ phabricator; f3db
+ phoenix-framework; f3dc
+ phoenix-squadron; f511
+ phone; f095
+ phone-alt; f879
+ phone-slash; f3dd
+ phone-square; f098
+ phone-square-alt; f87b
+ phone-volume; f2a0
+ photo-video; f87c
+ php; f457
+ pied-piper; f2ae
+ pied-piper-alt; f1a8
+ pied-piper-hat; f4e5
+ pied-piper-pp; f1a7
+ pied-piper-square e01e
+ piggy-bank; f4d3
+ pills; f484
+ pinterest; f0d2
+ pinterest-p; f231
+ pinterest-square; f0d3
+ pizza-slice; f818
+ place-of-worship; f67f
+ plane; f072
+ plane-arrival; f5af
+ plane-departure; f5b0
+ plane-slash e069
+ play; f04b
+ play-circle; f144
+ playstation; f3df
+ plug; f1e6
+ plus; f067
+ plus-circle; f055
+ plus-square; f0fe
+ podcast; f2ce
+ poll; f681
+ poll-h; f682
+ poo; f2fe
+ poo-storm; f75a
+ poop; f619
+ portrait; f3e0
+ pound-sign; f154
+ power-off; f011
+ pray; f683
+ praying-hands; f684
+ prescription; f5b1
+ prescription-bottle; f485
+ prescription-bottle-alt; f486
+ print; f02f
+ procedures; f487
+ product-hunt; f288
+ project-diagram; f542
+ pump-medical e06a
+ pump-soap e06b
+ pushed; f3e1
+ puzzle-piece; f12e
+ python; f3e2
+ qq; f1d6
+ qrcode; f029
+ question; f128
+ question-circle; f059
+ quidditch; f458
+ quinscape; f459
+ quora; f2c4
+ quote-left; f10d
+ quote-right; f10e
+ quran; f687
+ r-project; f4f7
+ radiation; f7b9
+ radiation-alt; f7ba
+ rainbow; f75b
+ random; f074
+ raspberry-pi; f7bb
+ ravelry; f2d9
+ react; f41b
+ reacteurope; f75d
+ readme; f4d5
+ rebel; f1d0
+ receipt; f543
+ record-vinyl; f8d9
+ recycle; f1b8
+ red-river; f3e3
+ reddit; f1a1
+ reddit-alien; f281
+ reddit-square; f1a2
+ redhat; f7bc
+ redo; f01e
+ redo-alt; f2f9
+ registered; f25d
+ remove-format; f87d
+ renren; f18b
+ reply; f3e5
+ reply-all; f122
+ replyd; f3e6
+ republican; f75e
+ researchgate; f4f8
+ resolving; f3e7
+ restroom; f7bd
+ retweet; f079
+ rev; f5b2
+ ribbon; f4d6
+ ring; f70b
+ road; f018
+ robot; f544
+ rocket; f135
+ rocketchat; f3e8
+ rockrms; f3e9
+ route; f4d7
+ rss; f09e
+ rss-square; f143
+ ruble-sign; f158
+ ruler; f545
+ ruler-combined; f546
+ ruler-horizontal; f547
+ ruler-vertical; f548
+ running; f70c
+ rupee-sign; f156
+ rust e07a
+ sad-cry; f5b3
+ sad-tear; f5b4
+ safari; f267
+ salesforce; f83b
+ sass; f41e
+ satellite; f7bf
+ satellite-dish; f7c0
+ save; f0c7
+ schlix; f3ea
+ school; f549
+ screwdriver; f54a
+ scribd; f28a
+ scroll; f70e
+ sd-card; f7c2
+ search; f002
+ search-dollar; f688
+ search-location; f689
+ search-minus; f010
+ search-plus; f00e
+ searchengin; f3eb
+ seedling; f4d8
+ sellcast; f2da
+ sellsy; f213
+ server; f233
+ servicestack; f3ec
+ shapes; f61f
+ share; f064
+ share-alt; f1e0
+ share-alt-square; f1e1
+ share-square; f14d
+ shekel-sign; f20b
+ shield-alt; f3ed
+ shield-virus e06c
+ ship; f21a
+ shipping-fast; f48b
+ shirtsinbulk; f214
+ shoe-prints; f54b
+ shopify e057
+ shopping-bag; f290
+ shopping-basket; f291
+ shopping-cart; f07a
+ shopware; f5b5
+ shower; f2cc
+ shuttle-van; f5b6
+ sign; f4d9
+ sign-in-alt; f2f6
+ sign-language; f2a7
+ sign-out-alt; f2f5
+ signal; f012
+ signature; f5b7
+ sim-card; f7c4
+ simplybuilt; f215
+ sink e06d
+ sistrix; f3ee
+ sitemap; f0e8
+ sith; f512
+ skating; f7c5
+ sketch; f7c6
+ skiing; f7c9
+ skiing-nordic; f7ca
+ skull; f54c
+ skull-crossbones; f714
+ skyatlas; f216
+ skype; f17e
+ slack; f198
+ slack-hash; f3ef
+ slash; f715
+ sleigh; f7cc
+ sliders-h; f1de
+ slideshare; f1e7
+ smile; f118
+ smile-beam; f5b8
+ smile-wink; f4da
+ smog; f75f
+ smoking; f48d
+ smoking-ban; f54d
+ sms; f7cd
+ snapchat; f2ab
+ snapchat-ghost; f2ac
+ snapchat-square; f2ad
+ snowboarding; f7ce
+ snowflake; f2dc
+ snowman; f7d0
+ snowplow; f7d2
+ soap e06e
+ socks; f696
+ solar-panel; f5ba
+ sort; f0dc
+ sort-alpha-down; f15d
+ sort-alpha-down-alt; f881
+ sort-alpha-up; f15e
+ sort-alpha-up-alt; f882
+ sort-amount-down; f160
+ sort-amount-down-alt; f884
+ sort-amount-up; f161
+ sort-amount-up-alt; f885
+ sort-down; f0dd
+ sort-numeric-down; f162
+ sort-numeric-down-alt; f886
+ sort-numeric-up; f163
+ sort-numeric-up-alt; f887
+ sort-up; f0de
+ soundcloud; f1be
+ sourcetree; f7d3
+ spa; f5bb
+ space-shuttle; f197
+ speakap; f3f3
+ speaker-deck; f83c
+ spell-check; f891
+ spider; f717
+ spinner; f110
+ splotch; f5bc
+ spotify; f1bc
+ spray-can; f5bd
+ square; f0c8
+ square-full; f45c
+ square-root-alt; f698
+ squarespace; f5be
+ stack-exchange; f18d
+ stack-overflow; f16c
+ stackpath; f842
+ stamp; f5bf
+ star; f005
+ star-and-crescent; f699
+ star-half; f089
+ star-half-alt; f5c0
+ star-of-david; f69a
+ star-of-life; f621
+ staylinked; f3f5
+ steam; f1b6
+ steam-square; f1b7
+ steam-symbol; f3f6
+ step-backward; f048
+ step-forward; f051
+ stethoscope; f0f1
+ sticker-mule; f3f7
+ sticky-note; f249
+ stop; f04d
+ stop-circle; f28d
+ stopwatch; f2f2
+ stopwatch-20 e06f
+ store; f54e
+ store-alt; f54f
+ store-alt-slash e070
+ store-slash e071
+ strava; f428
+ stream; f550
+ street-view; f21d
+ strikethrough; f0cc
+ stripe; f429
+ stripe-s; f42a
+ stroopwafel; f551
+ studiovinari; f3f8
+ stumbleupon; f1a4
+ stumbleupon-circle; f1a3
+ subscript; f12c
+ subway; f239
+ suitcase; f0f2
+ suitcase-rolling; f5c1
+ sun; f185
+ superpowers; f2dd
+ superscript; f12b
+ supple; f3f9
+ surprise; f5c2
+ suse; f7d6
+ swatchbook; f5c3
+ swift; f8e1
+ swimmer; f5c4
+ swimming-pool; f5c5
+ symfony; f83d
+ synagogue; f69b
+ sync; f021
+ sync-alt; f2f1
+ syringe; f48e
+ table; f0ce
+ table-tennis; f45d
+ tablet; f10a
+ tablet-alt; f3fa
+ tablets; f490
+ tachometer-alt; f3fd
+ tag; f02b
+ tags; f02c
+ tape; f4db
+ tasks; f0ae
+ taxi; f1ba
+ teamspeak; f4f9
+ teeth; f62e
+ teeth-open; f62f
+ telegram; f2c6
+ telegram-plane; f3fe
+ temperature-high; f769
+ temperature-low; f76b
+ tencent-weibo; f1d5
+ tenge; f7d7
+ terminal; f120
+ text-height; f034
+ text-width; f035
+ th; f00a
+ th-large; f009
+ th-list; f00b
+ the-red-yeti; f69d
+ theater-masks; f630
+ themeco; f5c6
+ themeisle; f2b2
+ thermometer; f491
+ thermometer-empty; f2cb
+ thermometer-full; f2c7
+ thermometer-half; f2c9
+ thermometer-quarter; f2ca
+ thermometer-three-quarters; f2c8
+ think-peaks; f731
+ thumbs-down; f165
+ thumbs-up; f164
+ thumbtack; f08d
+ ticket-alt; f3ff
+ tiktok e07b
+ times; f00d
+ times-circle; f057
+ tint; f043
+ tint-slash; f5c7
+ tired; f5c8
+ toggle-off; f204
+ toggle-on; f205
+ toilet; f7d8
+ toilet-paper; f71e
+ toilet-paper-slash e072
+ toolbox; f552
+ tools; f7d9
+ tooth; f5c9
+ torah; f6a0
+ torii-gate; f6a1
+ tractor; f722
+ trade-federation; f513
+ trademark; f25c
+ traffic-light; f637
+ trailer e041
+ train; f238
+ tram; f7da
+ transgender; f224
+ transgender-alt; f225
+ trash; f1f8
+ trash-alt; f2ed
+ trash-restore; f829
+ trash-restore-alt; f82a
+ tree; f1bb
+ trello; f181
+ trophy; f091
+ truck; f0d1
+ truck-loading; f4de
+ truck-monster; f63b
+ truck-moving; f4df
+ truck-pickup; f63c
+ tshirt; f553
+ tty; f1e4
+ tumblr; f173
+ tumblr-square; f174
+ tv; f26c
+ twitch; f1e8
+ twitter; f099
+ twitter-square; f081
+ typo3; f42b
+ uber; f402
+ ubuntu; f7df
+ uikit; f403
+ umbraco; f8e8
+ umbrella; f0e9
+ umbrella-beach; f5ca
+ uncharted e084
+ underline; f0cd
+ undo; f0e2
+ undo-alt; f2ea
+ uniregistry; f404
+ unity e049
+ universal-access; f29a
+ university; f19c
+ unlink; f127
+ unlock; f09c
+ unlock-alt; f13e
+ unsplash e07c
+ untappd; f405
+ upload; f093
+ ups; f7e0
+ usb; f287
+ user; f007
+ user-alt; f406
+ user-alt-slash; f4fa
+ user-astronaut; f4fb
+ user-check; f4fc
+ user-circle; f2bd
+ user-clock; f4fd
+ user-cog; f4fe
+ user-edit; f4ff
+ user-friends; f500
+ user-graduate; f501
+ user-injured; f728
+ user-lock; f502
+ user-md; f0f0
+ user-minus; f503
+ user-ninja; f504
+ user-nurse; f82f
+ user-plus; f234
+ user-secret; f21b
+ user-shield; f505
+ user-slash; f506
+ user-tag; f507
+ user-tie; f508
+ user-times; f235
+ users; f0c0
+ users-cog; f509
+ users-slash e073
+ usps; f7e1
+ ussunnah; f407
+ utensil-spoon; f2e5
+ utensils; f2e7
+ vaadin; f408
+ vector-square; f5cb
+ venus; f221
+ venus-double; f226
+ venus-mars; f228
+ vest e085
+ vest-patches e086
+ viacoin; f237
+ viadeo; f2a9
+ viadeo-square; f2aa
+ vial; f492
+ vials; f493
+ viber; f409
+ video; f03d
+ video-slash; f4e2
+ vihara; f6a7
+ vimeo; f40a
+ vimeo-square; f194
+ vimeo-v; f27d
+ vine; f1ca
+ virus e074
+ virus-slash e075
+ viruses e076
+ vk; f189
+ vnv; f40b
+ voicemail; f897
+ volleyball-ball; f45f
+ volume-down; f027
+ volume-mute; f6a9
+ volume-off; f026
+ volume-up; f028
+ vote-yea; f772
+ vr-cardboard; f729
+ vuejs; f41f
+ walking; f554
+ wallet; f555
+ warehouse; f494
+ watchman-monitoring e087
+ water; f773
+ wave-square; f83e
+ waze; f83f
+ weebly; f5cc
+ weibo; f18a
+ weight; f496
+ weight-hanging; f5cd
+ weixin; f1d7
+ whatsapp; f232
+ whatsapp-square; f40c
+ wheelchair; f193
+ whmcs; f40d
+ wifi; f1eb
+ wikipedia-w; f266
+ wind; f72e
+ window-close; f410
+ window-maximize; f2d0
+ window-minimize; f2d1
+ window-restore; f2d2
+ windows; f17a
+ wine-bottle; f72f
+ wine-glass; f4e3
+ wine-glass-alt; f5ce
+ wix; f5cf
+ wizards-of-the-coast; f730
+ wodu e088
+ wolf-pack-battalion; f514
+ won-sign; f159
+ wordpress; f19a
+ wordpress-simple; f411
+ wpbeginner; f297
+ wpexplorer; f2de
+ wpforms; f298
+ wpressr; f3e4
+ wrench; f0ad
+ x-ray; f497
+ xbox; f412
+ xing; f168
+ xing-square; f169
+ y-combinator; f23b
+ yahoo; f19e
+ yammer; f840
+ yandex; f413
+ yandex-international; f414
+ yarn; f7e3
+ yelp; f1e9
+ yen-sign; f157
+ yin-yang; f6ad
+ yoast; f2b1
+ youtube; f167
+ youtube-square; f431
+ zhihu; f63f
diff --git a/.local/share/larbs/emoji b/.local/share/larbs/emoji
new file mode 100644
index 0000000..6803731
--- /dev/null
+++ b/.local/share/larbs/emoji
@@ -0,0 +1,1630 @@
+😀 grinning face
+😃 grinning face with big eyes
+😄 grinning face with smiling eyes
+😁 beaming face with smiling eyes
+😆 grinning squinting face
+😅 grinning face with sweat
+🤣 rolling on the floor laughing
+😂 face with tears of joy
+🙂 slightly smiling face
+🙃 upside-down face
+🫠 melting face
+😉 winking face
+😊 smiling face with smiling eyes
+😇 smiling face with halo
+🥰 smiling face with hearts
+😍 smiling face with heart-eyes
+🤩 star-struck
+😘 face blowing a kiss
+😗 kissing face
+☺️ smiling face
+😚 kissing face with closed eyes
+😙 kissing face with smiling eyes
+🥲 smiling face with tear
+😋 face savoring food
+😛 face with tongue
+😜 winking face with tongue
+🤪 zany face
+😝 squinting face with tongue
+🤑 money-mouth face
+🤗 smiling face with open hands
+🤭 face with hand over mouth
+🫢 face with open eyes and hand over mouth
+🫣 face with peeking eye
+🤫 shushing face
+🤔 thinking face
+🫡 saluting face
+🤐 zipper-mouth face
+🤨 face with raised eyebrow
+😐 neutral face
+😑 expressionless face
+😶 face without mouth
+🫥 dotted line face
+😏 smirking face
+😒 unamused face
+🙄 face with rolling eyes
+😬 grimacing face
+🤥 lying face
+😌 relieved face
+😔 pensive face
+😪 sleepy face
+🤤 drooling face
+😴 sleeping face
+😷 face with medical mask
+🤒 face with thermometer
+🤕 face with head-bandage
+🤢 nauseated face
+🤮 face vomiting
+🤧 sneezing face
+🥵 hot face
+🥶 cold face
+🥴 woozy face
+😵 face with crossed-out eyes
+🤯 exploding head
+🤠 cowboy hat face
+🥳 partying face
+🥸 disguised face
+😎 smiling face with sunglasses
+🤓 nerd face
+🧐 face with monocle
+😕 confused face
+🫤 face with diagonal mouth
+😟 worried face
+🙁 slightly frowning face
+☹️ frowning face
+😮 face with open mouth
+😯 hushed face
+😲 astonished face
+😳 flushed face
+🥺 pleading face
+🥹 face holding back tears
+😦 frowning face with open mouth
+😧 anguished face
+😨 fearful face
+😰 anxious face with sweat
+😥 sad but relieved face
+😢 crying face
+😭 loudly crying face
+😱 face screaming in fear
+😖 confounded face
+😣 persevering face
+😞 disappointed face
+😓 downcast face with sweat
+😩 weary face
+😫 tired face
+🥱 yawning face
+😤 face with steam from nose
+😡 pouting face
+😠 angry face
+🤬 face with symbols on mouth
+😈 smiling face with horns
+👿 angry face with horns
+💀 skull
+☠️ skull and crossbones
+💩 pile of poo
+🤡 clown face
+👹 ogre
+👺 goblin
+👻 ghost
+👽 alien
+👾 alien monster
+🤖 robot
+😺 grinning cat
+😸 grinning cat with smiling eyes
+😹 cat with tears of joy
+😻 smiling cat with heart-eyes
+😼 cat with wry smile
+😽 kissing cat
+🙀 weary cat
+😿 crying cat
+😾 pouting cat
+🙈 see-no-evil monkey
+🙉 hear-no-evil monkey
+🙊 speak-no-evil monkey
+💋 kiss mark
+💌 love letter
+💘 heart with arrow
+💝 heart with ribbon
+💖 sparkling heart
+💗 growing heart
+💓 beating heart
+💞 revolving hearts
+💕 two hearts
+💟 heart decoration
+❣️ heart exclamation
+💔 broken heart
+❤️ red heart
+🧡 orange heart
+💛 yellow heart
+💚 green heart
+💙 blue heart
+💜 purple heart
+🤎 brown heart
+🖤 black heart
+🤍 white heart
+💯 hundred points
+💢 anger symbol
+💥 collision
+💫 dizzy
+💦 sweat droplets
+💨 dashing away
+🕳️ hole
+💣 bomb
+💬 speech balloon
+🗨️ left speech bubble
+🗯️ right anger bubble
+💭 thought balloon
+💤 zzz
+👋 waving hand
+🤚 raised back of hand
+🖐️ hand with fingers splayed
+✋ raised hand
+🖖 vulcan salute
+🫱 rightwards hand
+🫲 leftwards hand
+🫳 palm down hand
+🫴 palm up hand
+👌 OK hand
+🤌 pinched fingers
+🤏 pinching hand
+✌️ victory hand
+🤞 crossed fingers
+🫰 hand with index finger and thumb crossed
+🤟 love-you gesture
+🤘 sign of the horns
+🤙 call me hand
+👈 backhand index pointing left
+👉 backhand index pointing right
+👆 backhand index pointing up
+🖕 middle finger
+👇 backhand index pointing down
+☝️ index pointing up
+🫵 index pointing at the viewer
+👍 thumbs up
+👎 thumbs down
+✊ raised fist
+👊 oncoming fist
+🤛 left-facing fist
+🤜 right-facing fist
+👏 clapping hands
+🙌 raising hands
+🫶 heart hands
+👐 open hands
+🤲 palms up together
+🤝 handshake
+🙏 folded hands
+✍️ writing hand
+💅 nail polish
+🤳 selfie
+💪 flexed biceps
+🦾 mechanical arm
+🦿 mechanical leg
+🦵 leg
+🦶 foot
+👂 ear
+🦻 ear with hearing aid
+👃 nose
+🧠 brain
+🫀 anatomical heart
+🫁 lungs
+🦷 tooth
+🦴 bone
+👀 eyes
+👁️ eye
+👅 tongue
+👄 mouth
+🫦 biting lip
+👶 baby
+🧒 child
+👦 boy
+👧 girl
+🧑 person
+👱 person: blond hair
+👨 man
+🧔 person: beard
+👩 woman
+🧓 older person
+👴 old man
+👵 old woman
+🙍 person frowning
+🙎 person pouting
+🙅 person gesturing NO
+🙆 person gesturing OK
+💁 person tipping hand
+🙋 person raising hand
+🧏 deaf person
+🙇 person bowing
+🤦 person facepalming
+🤷 person shrugging
+👮 police officer
+🕵️ detective
+💂 guard
+🥷 ninja
+👷 construction worker
+🫅 person with crown
+🤴 prince
+👸 princess
+👳 person wearing turban
+👲 person with skullcap
+🧕 woman with headscarf
+🤵 person in tuxedo
+👰 person with veil
+🤰 pregnant woman
+🫃 pregnant man
+🫄 pregnant person
+🤱 breast-feeding
+👼 baby angel
+🎅 Santa Claus
+🤶 Mrs. Claus
+🦸 superhero
+🦹 supervillain
+🧙 mage
+🧚 fairy
+🧛 vampire
+🧜 merperson
+🧝 elf
+🧞 genie
+🧟 zombie
+🧌 troll
+💆 person getting massage
+💇 person getting haircut
+🚶 person walking
+🧍 person standing
+🧎 person kneeling
+🏃 person running
+💃 woman dancing
+🕺 man dancing
+🕴️ person in suit levitating
+👯 people with bunny ears
+🧖 person in steamy room
+🧗 person climbing
+🤺 person fencing
+🏇 horse racing
+⛷️ skier
+🏂 snowboarder
+🏌️ person golfing
+🏄 person surfing
+🚣 person rowing boat
+🏊 person swimming
+⛹️ person bouncing ball
+🏋️ person lifting weights
+🚴 person biking
+🚵 person mountain biking
+🤸 person cartwheeling
+🤼 people wrestling
+🤽 person playing water polo
+🤾 person playing handball
+🤹 person juggling
+🧘 person in lotus position
+🛀 person taking bath
+🛌 person in bed
+👭 women holding hands
+👫 woman and man holding hands
+👬 men holding hands
+💏 kiss
+💑 couple with heart
+👪 family
+🗣️ speaking head
+👤 bust in silhouette
+👥 busts in silhouette
+🫂 people hugging
+👣 footprints
+🐵 monkey face
+🐒 monkey
+🦍 gorilla
+🦧 orangutan
+🐶 dog face
+🐕 dog
+🦮 guide dog
+🐩 poodle
+🐺 wolf
+🦊 fox
+🦝 raccoon
+🐱 cat face
+🐈 cat
+🦁 lion
+🐯 tiger face
+🐅 tiger
+🐆 leopard
+🐴 horse face
+🐎 horse
+🦄 unicorn
+🦓 zebra
+🦌 deer
+🦬 bison
+🐮 cow face
+🐂 ox
+🐃 water buffalo
+🐄 cow
+🐷 pig face
+🐖 pig
+🐗 boar
+🐽 pig nose
+🐏 ram
+🐑 ewe
+🐐 goat
+🐪 camel
+🐫 two-hump camel
+🦙 llama
+🦒 giraffe
+🐘 elephant
+🦣 mammoth
+🦏 rhinoceros
+🦛 hippopotamus
+🐭 mouse face
+🐁 mouse
+🐀 rat
+🐹 hamster
+🐰 rabbit face
+🐇 rabbit
+🐿️ chipmunk
+🦫 beaver
+🦔 hedgehog
+🦇 bat
+🐻 bear
+🐨 koala
+🐼 panda
+🦥 sloth
+🦦 otter
+🦨 skunk
+🦘 kangaroo
+🦡 badger
+🐾 paw prints
+🦃 turkey
+🐔 chicken
+🐓 rooster
+🐣 hatching chick
+🐤 baby chick
+🐥 front-facing baby chick
+🐦 bird
+🐧 penguin
+🕊️ dove
+🦅 eagle
+🦆 duck
+🦢 swan
+🦉 owl
+🦤 dodo
+🪶 feather
+🦩 flamingo
+🦚 peacock
+🦜 parrot
+🐸 frog
+🐊 crocodile
+🐢 turtle
+🦎 lizard
+🐍 snake
+🐲 dragon face
+🐉 dragon
+🦕 sauropod
+🦖 T-Rex
+🐳 spouting whale
+🐋 whale
+🐬 dolphin
+🦭 seal
+🐟 fish
+🐠 tropical fish
+🐡 blowfish
+🦈 shark
+🐙 octopus
+🐚 spiral shell
+🪸 coral
+🐌 snail
+🦋 butterfly
+🐛 bug
+🐜 ant
+🐝 honeybee
+🪲 beetle
+🐞 lady beetle
+🦗 cricket
+🪳 cockroach
+🕷️ spider
+🕸️ spider web
+🦂 scorpion
+🦟 mosquito
+🪰 fly
+🪱 worm
+🦠 microbe
+💐 bouquet
+🌸 cherry blossom
+💮 white flower
+🪷 lotus
+🏵️ rosette
+🌹 rose
+🥀 wilted flower
+🌺 hibiscus
+🌻 sunflower
+🌼 blossom
+🌷 tulip
+🌱 seedling
+🪴 potted plant
+🌲 evergreen tree
+🌳 deciduous tree
+🌴 palm tree
+🌵 cactus
+🌾 sheaf of rice
+🌿 herb
+☘️ shamrock
+🍀 four leaf clover
+🍁 maple leaf
+🍂 fallen leaf
+🍃 leaf fluttering in wind
+🪹 empty nest
+🪺 nest with eggs
+🍇 grapes
+🍈 melon
+🍉 watermelon
+🍊 tangerine
+🍋 lemon
+🍌 banana
+🍍 pineapple
+🥭 mango
+🍎 red apple
+🍏 green apple
+🍐 pear
+🍑 peach
+🍒 cherries
+🍓 strawberry
+🫐 blueberries
+🥝 kiwi fruit
+🍅 tomato
+🫒 olive
+🥥 coconut
+🥑 avocado
+🍆 eggplant
+🥔 potato
+🥕 carrot
+🌽 ear of corn
+🌶️ hot pepper
+🫑 bell pepper
+🥒 cucumber
+🥬 leafy green
+🥦 broccoli
+🧄 garlic
+🧅 onion
+🍄 mushroom
+🥜 peanuts
+🫘 beans
+🌰 chestnut
+🍞 bread
+🥐 croissant
+🥖 baguette bread
+🫓 flatbread
+🥨 pretzel
+🥯 bagel
+🥞 pancakes
+🧇 waffle
+🧀 cheese wedge
+🍖 meat on bone
+🍗 poultry leg
+🥩 cut of meat
+🥓 bacon
+🍔 hamburger
+🍟 french fries
+🍕 pizza
+🌭 hot dog
+🥪 sandwich
+🌮 taco
+🌯 burrito
+🫔 tamale
+🥙 stuffed flatbread
+🧆 falafel
+🥚 egg
+🍳 cooking
+🥘 shallow pan of food
+🍲 pot of food
+🫕 fondue
+🥣 bowl with spoon
+🥗 green salad
+🍿 popcorn
+🧈 butter
+🧂 salt
+🥫 canned food
+🍱 bento box
+🍘 rice cracker
+🍙 rice ball
+🍚 cooked rice
+🍛 curry rice
+🍜 steaming bowl
+🍝 spaghetti
+🍠 roasted sweet potato
+🍢 oden
+🍣 sushi
+🍤 fried shrimp
+🍥 fish cake with swirl
+🥮 moon cake
+🍡 dango
+🥟 dumpling
+🥠 fortune cookie
+🥡 takeout box
+🦀 crab
+🦞 lobster
+🦐 shrimp
+🦑 squid
+🦪 oyster
+🍦 soft ice cream
+🍧 shaved ice
+🍨 ice cream
+🍩 doughnut
+🍪 cookie
+🎂 birthday cake
+🍰 shortcake
+🧁 cupcake
+🥧 pie
+🍫 chocolate bar
+🍬 candy
+🍭 lollipop
+🍮 custard
+🍯 honey pot
+🍼 baby bottle
+🥛 glass of milk
+☕ hot beverage
+🫖 teapot
+🍵 teacup without handle
+🍶 sake
+🍾 bottle with popping cork
+🍷 wine glass
+🍸 cocktail glass
+🍹 tropical drink
+🍺 beer mug
+🍻 clinking beer mugs
+🥂 clinking glasses
+🥃 tumbler glass
+🫗 pouring liquid
+🥤 cup with straw
+🧋 bubble tea
+🧃 beverage box
+🧉 mate
+🧊 ice
+🥢 chopsticks
+🍽️ fork and knife with plate
+🍴 fork and knife
+🥄 spoon
+🔪 kitchen knife
+🫙 jar
+🏺 amphora
+🌍 globe showing Europe-Africa
+🌎 globe showing Americas
+🌏 globe showing Asia-Australia
+🌐 globe with meridians
+🗺️ world map
+🗾 map of Japan
+🧭 compass
+🏔️ snow-capped mountain
+⛰️ mountain
+🌋 volcano
+🗻 mount fuji
+🏕️ camping
+🏖️ beach with umbrella
+🏜️ desert
+🏝️ desert island
+🏞️ national park
+🏟️ stadium
+🏛️ classical building
+🏗️ building construction
+🧱 brick
+🪨 rock
+🪵 wood
+🛖 hut
+🏘️ houses
+🏚️ derelict house
+🏠 house
+🏡 house with garden
+🏢 office building
+🏣 Japanese post office
+🏤 post office
+🏥 hospital
+🏦 bank
+🏨 hotel
+🏩 love hotel
+🏪 convenience store
+🏫 school
+🏬 department store
+🏭 factory
+🏯 Japanese castle
+🏰 castle
+💒 wedding
+🗼 Tokyo tower
+🗽 Statue of Liberty
+⛪ church
+🕌 mosque
+🛕 hindu temple
+🕍 synagogue
+⛩️ shinto shrine
+🕋 kaaba
+⛲ fountain
+⛺ tent
+🌁 foggy
+🌃 night with stars
+🏙️ cityscape
+🌄 sunrise over mountains
+🌅 sunrise
+🌆 cityscape at dusk
+🌇 sunset
+🌉 bridge at night
+♨️ hot springs
+🎠 carousel horse
+🛝 playground slide
+🎡 ferris wheel
+🎢 roller coaster
+💈 barber pole
+🎪 circus tent
+🚂 locomotive
+🚃 railway car
+🚄 high-speed train
+🚅 bullet train
+🚆 train
+🚇 metro
+🚈 light rail
+🚉 station
+🚊 tram
+🚝 monorail
+🚞 mountain railway
+🚋 tram car
+🚌 bus
+🚍 oncoming bus
+🚎 trolleybus
+🚐 minibus
+🚑 ambulance
+🚒 fire engine
+🚓 police car
+🚔 oncoming police car
+🚕 taxi
+🚖 oncoming taxi
+🚗 automobile
+🚘 oncoming automobile
+🚙 sport utility vehicle
+🛻 pickup truck
+🚚 delivery truck
+🚛 articulated lorry
+🚜 tractor
+🏎️ racing car
+🏍️ motorcycle
+🛵 motor scooter
+🦽 manual wheelchair
+🦼 motorized wheelchair
+🛺 auto rickshaw
+🚲 bicycle
+🛴 kick scooter
+🛹 skateboard
+🛼 roller skate
+🚏 bus stop
+🛣️ motorway
+🛤️ railway track
+🛢️ oil drum
+⛽ fuel pump
+🛞 wheel
+🚨 police car light
+🚥 horizontal traffic light
+🚦 vertical traffic light
+🛑 stop sign
+🚧 construction
+⚓ anchor
+🛟 ring buoy
+⛵ sailboat
+🛶 canoe
+🚤 speedboat
+🛳️ passenger ship
+⛴️ ferry
+🛥️ motor boat
+🚢 ship
+✈️ airplane
+🛩️ small airplane
+🛫 airplane departure
+🛬 airplane arrival
+🪂 parachute
+💺 seat
+🚁 helicopter
+🚟 suspension railway
+🚠 mountain cableway
+🚡 aerial tramway
+🛰️ satellite
+🚀 rocket
+🛸 flying saucer
+🛎️ bellhop bell
+🧳 luggage
+⌛ hourglass done
+⏳ hourglass not done
+⌚ watch
+⏰ alarm clock
+⏱️ stopwatch
+⏲️ timer clock
+🕰️ mantelpiece clock
+🕛 twelve o’clock
+🕧 twelve-thirty
+🕐 one o’clock
+🕜 one-thirty
+🕑 two o’clock
+🕝 two-thirty
+🕒 three o’clock
+🕞 three-thirty
+🕓 four o’clock
+🕟 four-thirty
+🕔 five o’clock
+🕠 five-thirty
+🕕 six o’clock
+🕡 six-thirty
+🕖 seven o’clock
+🕢 seven-thirty
+🕗 eight o’clock
+🕣 eight-thirty
+🕘 nine o’clock
+🕤 nine-thirty
+🕙 ten o’clock
+🕥 ten-thirty
+🕚 eleven o’clock
+🕦 eleven-thirty
+🌑 new moon
+🌒 waxing crescent moon
+🌓 first quarter moon
+🌔 waxing gibbous moon
+🌕 full moon
+🌖 waning gibbous moon
+🌗 last quarter moon
+🌘 waning crescent moon
+🌙 crescent moon
+🌚 new moon face
+🌛 first quarter moon face
+🌜 last quarter moon face
+🌡️ thermometer
+☀️ sun
+🌝 full moon face
+🌞 sun with face
+🪐 ringed planet
+⭐ star
+🌟 glowing star
+🌠 shooting star
+🌌 milky way
+☁️ cloud
+⛅ sun behind cloud
+⛈️ cloud with lightning and rain
+🌤️ sun behind small cloud
+🌥️ sun behind large cloud
+🌦️ sun behind rain cloud
+🌧️ cloud with rain
+🌨️ cloud with snow
+🌩️ cloud with lightning
+🌪️ tornado
+🌫️ fog
+🌬️ wind face
+🌀 cyclone
+🌈 rainbow
+🌂 closed umbrella
+☂️ umbrella
+☔ umbrella with rain drops
+⛱️ umbrella on ground
+⚡ high voltage
+❄️ snowflake
+☃️ snowman
+⛄ snowman without snow
+☄️ comet
+🔥 fire
+💧 droplet
+🌊 water wave
+🎃 jack-o-lantern
+🎄 Christmas tree
+🎆 fireworks
+🎇 sparkler
+🧨 firecracker
+✨ sparkles
+🎈 balloon
+🎉 party popper
+🎊 confetti ball
+🎋 tanabata tree
+🎍 pine decoration
+🎎 Japanese dolls
+🎏 carp streamer
+🎐 wind chime
+🎑 moon viewing ceremony
+🧧 red envelope
+🎀 ribbon
+🎁 wrapped gift
+🎗️ reminder ribbon
+🎟️ admission tickets
+🎫 ticket
+🎖️ military medal
+🏆 trophy
+🏅 sports medal
+🥇 1st place medal
+🥈 2nd place medal
+🥉 3rd place medal
+⚽ soccer ball
+⚾ baseball
+🥎 softball
+🏀 basketball
+🏐 volleyball
+🏈 american football
+🏉 rugby football
+🎾 tennis
+🥏 flying disc
+🎳 bowling
+🏏 cricket game
+🏑 field hockey
+🏒 ice hockey
+🥍 lacrosse
+🏓 ping pong
+🏸 badminton
+🥊 boxing glove
+🥋 martial arts uniform
+🥅 goal net
+⛳ flag in hole
+⛸️ ice skate
+🎣 fishing pole
+🤿 diving mask
+🎽 running shirt
+🎿 skis
+🛷 sled
+🥌 curling stone
+🎯 bullseye
+🪀 yo-yo
+🪁 kite
+🎱 pool 8 ball
+🔮 crystal ball
+🪄 magic wand
+🧿 nazar amulet
+🪬 hamsa
+🎮 video game
+🕹️ joystick
+🎰 slot machine
+🎲 game die
+🧩 puzzle piece
+🧸 teddy bear
+🪅 piñata
+🪩 mirror ball
+🪆 nesting dolls
+♠️ spade suit
+♥️ heart suit
+♦️ diamond suit
+♣️ club suit
+♟️ chess pawn
+🃏 joker
+🀄 mahjong red dragon
+🎴 flower playing cards
+🎭 performing arts
+🖼️ framed picture
+🎨 artist palette
+🧵 thread
+🪡 sewing needle
+🧶 yarn
+🪢 knot
+👓 glasses
+🕶️ sunglasses
+🥽 goggles
+🥼 lab coat
+🦺 safety vest
+👔 necktie
+👕 t-shirt
+👖 jeans
+🧣 scarf
+🧤 gloves
+🧥 coat
+🧦 socks
+👗 dress
+👘 kimono
+🥻 sari
+🩱 one-piece swimsuit
+🩲 briefs
+🩳 shorts
+👙 bikini
+👚 woman’s clothes
+👛 purse
+👜 handbag
+👝 clutch bag
+🛍️ shopping bags
+🎒 backpack
+🩴 thong sandal
+👞 man’s shoe
+👟 running shoe
+🥾 hiking boot
+🥿 flat shoe
+👠 high-heeled shoe
+👡 woman’s sandal
+🩰 ballet shoes
+👢 woman’s boot
+👑 crown
+👒 woman’s hat
+🎩 top hat
+🎓 graduation cap
+🧢 billed cap
+🪖 military helmet
+⛑️ rescue worker’s helmet
+📿 prayer beads
+💄 lipstick
+💍 ring
+💎 gem stone
+🔇 muted speaker
+🔈 speaker low volume
+🔉 speaker medium volume
+🔊 speaker high volume
+📢 loudspeaker
+📣 megaphone
+📯 postal horn
+🔔 bell
+🔕 bell with slash
+🎼 musical score
+🎵 musical note
+🎶 musical notes
+🎙️ studio microphone
+🎚️ level slider
+🎛️ control knobs
+🎤 microphone
+🎧 headphone
+📻 radio
+🎷 saxophone
+🪗 accordion
+🎸 guitar
+🎹 musical keyboard
+🎺 trumpet
+🎻 violin
+🪕 banjo
+🥁 drum
+🪘 long drum
+📱 mobile phone
+📲 mobile phone with arrow
+☎️ telephone
+📞 telephone receiver
+📟 pager
+📠 fax machine
+🔋 battery
+🪫 low battery
+🔌 electric plug
+💻 laptop
+🖥️ desktop computer
+🖨️ printer
+⌨️ keyboard
+🖱️ computer mouse
+🖲️ trackball
+💽 computer disk
+💾 floppy disk
+💿 optical disk
+📀 dvd
+🧮 abacus
+🎥 movie camera
+🎞️ film frames
+📽️ film projector
+🎬 clapper board
+📺 television
+📷 camera
+📸 camera with flash
+📹 video camera
+📼 videocassette
+🔍 magnifying glass tilted left
+🔎 magnifying glass tilted right
+🕯️ candle
+💡 light bulb
+🔦 flashlight
+🏮 red paper lantern
+🪔 diya lamp
+📔 notebook with decorative cover
+📕 closed book
+📖 open book
+📗 green book
+📘 blue book
+📙 orange book
+📚 books
+📓 notebook
+📒 ledger
+📃 page with curl
+📜 scroll
+📄 page facing up
+📰 newspaper
+🗞️ rolled-up newspaper
+📑 bookmark tabs
+🔖 bookmark
+🏷️ label
+💰 money bag
+🪙 coin
+💴 yen banknote
+💵 dollar banknote
+💶 euro banknote
+💷 pound banknote
+💸 money with wings
+💳 credit card
+🧾 receipt
+💹 chart increasing with yen
+✉️ envelope
+📧 e-mail
+📨 incoming envelope
+📩 envelope with arrow
+📤 outbox tray
+📥 inbox tray
+📦 package
+📫 closed mailbox with raised flag
+📪 closed mailbox with lowered flag
+📬 open mailbox with raised flag
+📭 open mailbox with lowered flag
+📮 postbox
+🗳️ ballot box with ballot
+✏️ pencil
+✒️ black nib
+🖋️ fountain pen
+🖊️ pen
+🖌️ paintbrush
+🖍️ crayon
+📝 memo
+💼 briefcase
+📁 file folder
+📂 open file folder
+🗂️ card index dividers
+📅 calendar
+📆 tear-off calendar
+🗒️ spiral notepad
+🗓️ spiral calendar
+📇 card index
+📈 chart increasing
+📉 chart decreasing
+📊 bar chart
+📋 clipboard
+📌 pushpin
+📍 round pushpin
+📎 paperclip
+🖇️ linked paperclips
+📏 straight ruler
+📐 triangular ruler
+✂️ scissors
+🗃️ card file box
+🗄️ file cabinet
+🗑️ wastebasket
+🔒 locked
+🔓 unlocked
+🔏 locked with pen
+🔐 locked with key
+🔑 key
+🗝️ old key
+🔨 hammer
+🪓 axe
+⛏️ pick
+⚒️ hammer and pick
+🛠️ hammer and wrench
+🗡️ dagger
+⚔️ crossed swords
+🔫 water pistol
+🪃 boomerang
+🏹 bow and arrow
+🛡️ shield
+🪚 carpentry saw
+🔧 wrench
+🪛 screwdriver
+🔩 nut and bolt
+⚙️ gear
+🗜️ clamp
+⚖️ balance scale
+🦯 white cane
+🔗 link
+⛓️ chains
+🪝 hook
+🧰 toolbox
+🧲 magnet
+🪜 ladder
+⚗️ alembic
+🧪 test tube
+🧫 petri dish
+🧬 dna
+🔬 microscope
+🔭 telescope
+📡 satellite antenna
+💉 syringe
+🩸 drop of blood
+💊 pill
+🩹 adhesive bandage
+🩼 crutch
+🩺 stethoscope
+🩻 x-ray
+🚪 door
+🛗 elevator
+🪞 mirror
+🪟 window
+🛏️ bed
+🛋️ couch and lamp
+🪑 chair
+🚽 toilet
+🪠 plunger
+🚿 shower
+🛁 bathtub
+🪤 mouse trap
+🪒 razor
+🧴 lotion bottle
+🧷 safety pin
+🧹 broom
+🧺 basket
+🧻 roll of paper
+🪣 bucket
+🧼 soap
+🫧 bubbles
+🪥 toothbrush
+🧽 sponge
+🧯 fire extinguisher
+🛒 shopping cart
+🚬 cigarette
+⚰️ coffin
+🪦 headstone
+⚱️ funeral urn
+🗿 moai
+🪧 placard
+🪪 identification card
+🏧 ATM sign
+🚮 litter in bin sign
+🚰 potable water
+♿ wheelchair symbol
+🚹 men’s room
+🚺 women’s room
+🚻 restroom
+🚼 baby symbol
+🚾 water closet
+🛂 passport control
+🛃 customs
+🛄 baggage claim
+🛅 left luggage
+⚠️ warning
+🚸 children crossing
+⛔ no entry
+🚫 prohibited
+🚳 no bicycles
+🚭 no smoking
+🚯 no littering
+🚱 non-potable water
+🚷 no pedestrians
+📵 no mobile phones
+🔞 no one under eighteen
+☢️ radioactive
+☣️ biohazard
+⬆️ up arrow
+↗️ up-right arrow
+➡️ right arrow
+↘️ down-right arrow
+⬇️ down arrow
+↙️ down-left arrow
+⬅️ left arrow
+↖️ up-left arrow
+↕️ up-down arrow
+↔️ left-right arrow
+↩️ right arrow curving left
+↪️ left arrow curving right
+⤴️ right arrow curving up
+⤵️ right arrow curving down
+🔃 clockwise vertical arrows
+🔄 counterclockwise arrows button
+🔙 BACK arrow
+🔚 END arrow
+🔛 ON! arrow
+🔜 SOON arrow
+🔝 TOP arrow
+🛐 place of worship
+⚛️ atom symbol
+🕉️ om
+✡️ star of David
+☸️ wheel of dharma
+☯️ yin yang
+✝️ latin cross
+☦️ orthodox cross
+☪️ star and crescent
+☮️ peace symbol
+🕎 menorah
+🔯 dotted six-pointed star
+♈ Aries
+♉ Taurus
+♊ Gemini
+♋ Cancer
+♌ Leo
+♍ Virgo
+♎ Libra
+♏ Scorpio
+♐ Sagittarius
+♑ Capricorn
+♒ Aquarius
+♓ Pisces
+⛎ Ophiuchus
+🔀 shuffle tracks button
+🔁 repeat button
+🔂 repeat single button
+▶️ play button
+⏩ fast-forward button
+⏭️ next track button
+⏯️ play or pause button
+◀️ reverse button
+⏪ fast reverse button
+⏮️ last track button
+🔼 upwards button
+⏫ fast up button
+🔽 downwards button
+⏬ fast down button
+⏸️ pause button
+⏹️ stop button
+⏺️ record button
+⏏️ eject button
+🎦 cinema
+🔅 dim button
+🔆 bright button
+📶 antenna bars
+📳 vibration mode
+📴 mobile phone off
+♀️ female sign
+♂️ male sign
+⚧️ transgender symbol
+✖️ multiply
+➕ plus
+➖ minus
+➗ divide
+🟰 heavy equals sign
+♾️ infinity
+‼️ double exclamation mark
+⁉️ exclamation question mark
+❓ red question mark
+❔ white question mark
+❕ white exclamation mark
+❗ red exclamation mark
+〰️ wavy dash
+💱 currency exchange
+💲 heavy dollar sign
+⚕️ medical symbol
+♻️ recycling symbol
+⚜️ fleur-de-lis
+🔱 trident emblem
+📛 name badge
+🔰 Japanese symbol for beginner
+⭕ hollow red circle
+✅ check mark button
+☑️ check box with check
+✔️ check mark
+❌ cross mark
+❎ cross mark button
+➰ curly loop
+➿ double curly loop
+〽️ part alternation mark
+✳️ eight-spoked asterisk
+✴️ eight-pointed star
+❇️ sparkle
+©️ copyright
+®️ registered
+™️ trade mark
+#️⃣ keycap: #
+*️⃣ keycap: *
+0️⃣ keycap: 0
+1️⃣ keycap: 1
+2️⃣ keycap: 2
+3️⃣ keycap: 3
+4️⃣ keycap: 4
+5️⃣ keycap: 5
+6️⃣ keycap: 6
+7️⃣ keycap: 7
+8️⃣ keycap: 8
+9️⃣ keycap: 9
+🔟 keycap: 10
+🔠 input latin uppercase
+🔡 input latin lowercase
+🔢 input numbers
+🔣 input symbols
+🔤 input latin letters
+🅰️ A button (blood type)
+🆎 AB button (blood type)
+🅱️ B button (blood type)
+🆑 CL button
+🆒 COOL button
+🆓 FREE button
+ℹ️ information
+🆔 ID button
+Ⓜ️ circled M
+🆕 NEW button
+🆖 NG button
+🅾️ O button (blood type)
+🆗 OK button
+🅿️ P button
+🆘 SOS button
+🆙 UP! button
+🆚 VS button
+🈁 Japanese “here” button
+🈂️ Japanese “service charge” button
+🈷️ Japanese “monthly amount” button
+🈶 Japanese “not free of charge” button
+🈯 Japanese “reserved” button
+🉐 Japanese “bargain” button
+🈹 Japanese “discount” button
+🈚 Japanese “free of charge” button
+🈲 Japanese “prohibited” button
+🉑 Japanese “acceptable” button
+🈸 Japanese “application” button
+🈴 Japanese “passing grade” button
+🈳 Japanese “vacancy” button
+㊗️ Japanese “congratulations” button
+㊙️ Japanese “secret” button
+🈺 Japanese “open for business” button
+🈵 Japanese “no vacancy” button
+🔴 red circle
+🟠 orange circle
+🟡 yellow circle
+🟢 green circle
+🔵 blue circle
+🟣 purple circle
+🟤 brown circle
+⚫ black circle
+⚪ white circle
+🟥 red square
+🟧 orange square
+🟨 yellow square
+🟩 green square
+🟦 blue square
+🟪 purple square
+🟫 brown square
+⬛ black large square
+⬜ white large square
+◼️ black medium square
+◻️ white medium square
+◾ black medium-small square
+◽ white medium-small square
+▪️ black small square
+▫️ white small square
+🔶 large orange diamond
+🔷 large blue diamond
+🔸 small orange diamond
+🔹 small blue diamond
+🔺 red triangle pointed up
+🔻 red triangle pointed down
+💠 diamond with a dot
+🔘 radio button
+🔳 white square button
+🔲 black square button
+🏁 chequered flag
+🚩 triangular flag
+🎌 crossed flags
+🏴 black flag
+🏳️ white flag
+🇦🇨 flag: Ascension Island
+🇦🇩 flag: Andorra
+🇦🇪 flag: United Arab Emirates
+🇦🇫 flag: Afghanistan
+🇦🇬 flag: Antigua & Barbuda
+🇦🇮 flag: Anguilla
+🇦🇱 flag: Albania
+🇦🇲 flag: Armenia
+🇦🇴 flag: Angola
+🇦🇶 flag: Antarctica
+🇦🇷 flag: Argentina
+🇦🇸 flag: American Samoa
+🇦🇹 flag: Austria
+🇦🇺 flag: Australia
+🇦🇼 flag: Aruba
+🇦🇽 flag: Åland Islands
+🇦🇿 flag: Azerbaijan
+🇧🇦 flag: Bosnia & Herzegovina
+🇧🇧 flag: Barbados
+🇧🇩 flag: Bangladesh
+🇧🇪 flag: Belgium
+🇧🇫 flag: Burkina Faso
+🇧🇬 flag: Bulgaria
+🇧🇭 flag: Bahrain
+🇧🇮 flag: Burundi
+🇧🇯 flag: Benin
+🇧🇱 flag: St. Barthélemy
+🇧🇲 flag: Bermuda
+🇧🇳 flag: Brunei
+🇧🇴 flag: Bolivia
+🇧🇶 flag: Caribbean Netherlands
+🇧🇷 flag: Brazil
+🇧🇸 flag: Bahamas
+🇧🇹 flag: Bhutan
+🇧🇻 flag: Bouvet Island
+🇧🇼 flag: Botswana
+🇧🇾 flag: Belarus
+🇧🇿 flag: Belize
+🇨🇦 flag: Canada
+🇨🇨 flag: Cocos (Keeling) Islands
+🇨🇩 flag: Congo - Kinshasa
+🇨🇫 flag: Central African Republic
+🇨🇬 flag: Congo - Brazzaville
+🇨🇭 flag: Switzerland
+🇨🇮 flag: Côte d’Ivoire
+🇨🇰 flag: Cook Islands
+🇨🇱 flag: Chile
+🇨🇲 flag: Cameroon
+🇨🇳 flag: China
+🇨🇴 flag: Colombia
+🇨🇵 flag: Clipperton Island
+🇨🇷 flag: Costa Rica
+🇨🇺 flag: Cuba
+🇨🇻 flag: Cape Verde
+🇨🇼 flag: Curaçao
+🇨🇽 flag: Christmas Island
+🇨🇾 flag: Cyprus
+🇨🇿 flag: Czechia
+🇩🇪 flag: Germany
+🇩🇬 flag: Diego Garcia
+🇩🇯 flag: Djibouti
+🇩🇰 flag: Denmark
+🇩🇲 flag: Dominica
+🇩🇴 flag: Dominican Republic
+🇩🇿 flag: Algeria
+🇪🇦 flag: Ceuta & Melilla
+🇪🇨 flag: Ecuador
+🇪🇪 flag: Estonia
+🇪🇬 flag: Egypt
+🇪🇭 flag: Western Sahara
+🇪🇷 flag: Eritrea
+🇪🇸 flag: Spain
+🇪🇹 flag: Ethiopia
+🇪🇺 flag: European Union
+🇫🇮 flag: Finland
+🇫🇯 flag: Fiji
+🇫🇰 flag: Falkland Islands
+🇫🇲 flag: Micronesia
+🇫🇴 flag: Faroe Islands
+🇫🇷 flag: France
+🇬🇦 flag: Gabon
+🇬🇧 flag: United Kingdom
+🇬🇩 flag: Grenada
+🇬🇪 flag: Georgia
+🇬🇫 flag: French Guiana
+🇬🇬 flag: Guernsey
+🇬🇭 flag: Ghana
+🇬🇮 flag: Gibraltar
+🇬🇱 flag: Greenland
+🇬🇲 flag: Gambia
+🇬🇳 flag: Guinea
+🇬🇵 flag: Guadeloupe
+🇬🇶 flag: Equatorial Guinea
+🇬🇷 flag: Greece
+🇬🇸 flag: South Georgia & South Sandwich Islands
+🇬🇹 flag: Guatemala
+🇬🇺 flag: Guam
+🇬🇼 flag: Guinea-Bissau
+🇬🇾 flag: Guyana
+🇭🇰 flag: Hong Kong SAR China
+🇭🇲 flag: Heard & McDonald Islands
+🇭🇳 flag: Honduras
+🇭🇷 flag: Croatia
+🇭🇹 flag: Haiti
+🇭🇺 flag: Hungary
+🇮🇨 flag: Canary Islands
+🇮🇩 flag: Indonesia
+🇮🇪 flag: Ireland
+🇮🇱 flag: Israel
+🇮🇲 flag: Isle of Man
+🇮🇳 flag: India
+🇮🇴 flag: British Indian Ocean Territory
+🇮🇶 flag: Iraq
+🇮🇷 flag: Iran
+🇮🇸 flag: Iceland
+🇮🇹 flag: Italy
+🇯🇪 flag: Jersey
+🇯🇲 flag: Jamaica
+🇯🇴 flag: Jordan
+🇯🇵 flag: Japan
+🇰🇪 flag: Kenya
+🇰🇬 flag: Kyrgyzstan
+🇰🇭 flag: Cambodia
+🇰🇮 flag: Kiribati
+🇰🇲 flag: Comoros
+🇰🇳 flag: St. Kitts & Nevis
+🇰🇵 flag: North Korea
+🇰🇷 flag: South Korea
+🇰🇼 flag: Kuwait
+🇰🇾 flag: Cayman Islands
+🇰🇿 flag: Kazakhstan
+🇱🇦 flag: Laos
+🇱🇧 flag: Lebanon
+🇱🇨 flag: St. Lucia
+🇱🇮 flag: Liechtenstein
+🇱🇰 flag: Sri Lanka
+🇱🇷 flag: Liberia
+🇱🇸 flag: Lesotho
+🇱🇹 flag: Lithuania
+🇱🇺 flag: Luxembourg
+🇱🇻 flag: Latvia
+🇱🇾 flag: Libya
+🇲🇦 flag: Morocco
+🇲🇨 flag: Monaco
+🇲🇩 flag: Moldova
+🇲🇪 flag: Montenegro
+🇲🇫 flag: St. Martin
+🇲🇬 flag: Madagascar
+🇲🇭 flag: Marshall Islands
+🇲🇰 flag: North Macedonia
+🇲🇱 flag: Mali
+🇲🇲 flag: Myanmar (Burma)
+🇲🇳 flag: Mongolia
+🇲🇴 flag: Macao SAR China
+🇲🇵 flag: Northern Mariana Islands
+🇲🇶 flag: Martinique
+🇲🇷 flag: Mauritania
+🇲🇸 flag: Montserrat
+🇲🇹 flag: Malta
+🇲🇺 flag: Mauritius
+🇲🇻 flag: Maldives
+🇲🇼 flag: Malawi
+🇲🇽 flag: Mexico
+🇲🇾 flag: Malaysia
+🇲🇿 flag: Mozambique
+🇳🇦 flag: Namibia
+🇳🇨 flag: New Caledonia
+🇳🇪 flag: Niger
+🇳🇫 flag: Norfolk Island
+🇳🇬 flag: Nigeria
+🇳🇮 flag: Nicaragua
+🇳🇱 flag: Netherlands
+🇳🇴 flag: Norway
+🇳🇵 flag: Nepal
+🇳🇷 flag: Nauru
+🇳🇺 flag: Niue
+🇳🇿 flag: New Zealand
+🇴🇲 flag: Oman
+🇵🇦 flag: Panama
+🇵🇪 flag: Peru
+🇵🇫 flag: French Polynesia
+🇵🇬 flag: Papua New Guinea
+🇵🇭 flag: Philippines
+🇵🇰 flag: Pakistan
+🇵🇱 flag: Poland
+🇵🇲 flag: St. Pierre & Miquelon
+🇵🇳 flag: Pitcairn Islands
+🇵🇷 flag: Puerto Rico
+🇵🇸 flag: Palestinian Territories
+🇵🇹 flag: Portugal
+🇵🇼 flag: Palau
+🇵🇾 flag: Paraguay
+🇶🇦 flag: Qatar
+🇷🇪 flag: Réunion
+🇷🇴 flag: Romania
+🇷🇸 flag: Serbia
+🇷🇺 flag: Russia
+🇷🇼 flag: Rwanda
+🇸🇦 flag: Saudi Arabia
+🇸🇧 flag: Solomon Islands
+🇸🇨 flag: Seychelles
+🇸🇩 flag: Sudan
+🇸🇪 flag: Sweden
+🇸🇬 flag: Singapore
+🇸🇭 flag: St. Helena
+🇸🇮 flag: Slovenia
+🇸🇯 flag: Svalbard & Jan Mayen
+🇸🇰 flag: Slovakia
+🇸🇱 flag: Sierra Leone
+🇸🇲 flag: San Marino
+🇸🇳 flag: Senegal
+🇸🇴 flag: Somalia
+🇸🇷 flag: Suriname
+🇸🇸 flag: South Sudan
+🇸🇹 flag: São Tomé & Príncipe
+🇸🇻 flag: El Salvador
+🇸🇽 flag: Sint Maarten
+🇸🇾 flag: Syria
+🇸🇿 flag: Eswatini
+🇹🇦 flag: Tristan da Cunha
+🇹🇨 flag: Turks & Caicos Islands
+🇹🇩 flag: Chad
+🇹🇫 flag: French Southern Territories
+🇹🇬 flag: Togo
+🇹🇭 flag: Thailand
+🇹🇯 flag: Tajikistan
+🇹🇰 flag: Tokelau
+🇹🇱 flag: Timor-Leste
+🇹🇲 flag: Turkmenistan
+🇹🇳 flag: Tunisia
+🇹🇴 flag: Tonga
+🇹🇷 flag: Turkey
+🇹🇹 flag: Trinidad & Tobago
+🇹🇻 flag: Tuvalu
+🇹🇼 flag: Taiwan
+🇹🇿 flag: Tanzania
+🇺🇦 flag: Ukraine
+🇺🇬 flag: Uganda
+🇺🇲 flag: U.S. Outlying Islands
+🇺🇳 flag: United Nations
+🇺🇸 flag: United States
+🇺🇾 flag: Uruguay
+🇺🇿 flag: Uzbekistan
+🇻🇦 flag: Vatican City
+🇻🇨 flag: St. Vincent & Grenadines
+🇻🇪 flag: Venezuela
+🇻🇬 flag: British Virgin Islands
+🇻🇮 flag: U.S. Virgin Islands
+🇻🇳 flag: Vietnam
+🇻🇺 flag: Vanuatu
+🇼🇫 flag: Wallis & Futuna
+🇼🇸 flag: Samoa
+🇽🇰 flag: Kosovo
+🇾🇪 flag: Yemen
+🇾🇹 flag: Mayotte
+🇿🇦 flag: South Africa
+🇿🇲 flag: Zambia
+🇿🇼 flag: Zimbabwe
+🏴󠁧󠁢󠁥󠁮󠁧󠁿 flag: England
+🏴󠁧󠁢󠁳󠁣󠁴󠁿 flag: Scotland
+🏴󠁧󠁢󠁷󠁬󠁳󠁿 flag: Wales
diff --git a/.local/share/thiemeyer_road_to_samarkand.jpg b/.local/share/thiemeyer_road_to_samarkand.jpg
new file mode 100644
index 0000000..6a30adb
--- /dev/null
+++ b/.local/share/thiemeyer_road_to_samarkand.jpg
Binary files differ
diff --git a/.zprofile b/.zprofile
new file mode 120000
index 0000000..8486fca
--- /dev/null
+++ b/.zprofile
@@ -0,0 +1 @@
+.config/shell/profile \ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..dcd08a4
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 2025 awy
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) 2025 awy
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<https://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..12300e8
--- /dev/null
+++ b/README.md
@@ -0,0 +1,4 @@
+Hyprland Deployment Script
+======================
+Installs all needed dependencies
+and deploys my dotfiles
diff --git a/aurdeps.txt b/aurdeps.txt
new file mode 100644
index 0000000..58ec134
--- /dev/null
+++ b/aurdeps.txt
@@ -0,0 +1,7 @@
+gruvbox-material-gtk-theme-git
+tessen
+sing-box
+#sing-geoip-rule-set
+#sing-geosite-rule-set
+gpu-screen-recorder
+doasedit-alternative
diff --git a/dependencies.txt b/dependencies.txt
new file mode 100644
index 0000000..71c478b
--- /dev/null
+++ b/dependencies.txt
@@ -0,0 +1,117 @@
+# COMPRESSION #
+7zip
+unrar
+
+# HYPRLAND #
+hyprland
+swayidle
+swaylock
+mako
+foot
+xdg-desktop-portal-hyprland
+waybar
+
+# PROGRAMS #
+neovim
+newsboat
+lynx
+
+# SHELL & YAZI #
+jq
+fzf
+zsh
+zsh-completions
+zsh-autosuggestions
+zathura
+zathura-pdf-mupdf
+wl-clipboard
+yazi
+bat
+chafa
+bc
+eza
+ripgrep
+fd
+git-delta
+
+# BROWSER #
+firefox
+
+# SOUND #
+pipewire
+pipewire-pulse
+wireplumber
+pulsemixer
+
+# FONTS #
+ttf-liberation-mono-nerd
+ttf-nerd-fonts-symbols
+noto-fonts-emoji
+fontconfig
+
+# MONITORING #
+btop
+
+# MULTIMEDIA #
+ffmpeg
+mediainfo
+mpv
+imagemagick
+swayimg
+mpc
+mpd
+rmpc
+grim
+swappy
+slurp
+swaybg
+
+# DATA HOARDING #
+yt-dlp
+transmission-cli
+
+# UTILS #
+gnupg
+gnome-keyring
+openssh
+fakeroot
+polkit
+fastfetch
+libnotify
+pkgconf
+exfat-utils
+tesseract-data-eng
+tesseract
+mandoc
+calcurse
+cmake
+wlrctl
+tllist
+
+# TESSEN DEPS #
+gopass
+which
+wtype
+
+# MUTT-WIZARD DEPS #
+neomutt
+isync
+msmtp
+cronie-dinit
+
+# WAYLAND #
+qt6-wayland
+xorg-xrandr
+python-qdarkstyle
+xorg-xwayland
+wayland-protocols
+
+# DOAS ASKPASS #
+expect
+
+# LANGUAGE SERVERS #
+clang
+rust-analyzer
+vscode-css-languageserver
+vscode-json-languageserver
+vscode-html-languageserver
diff --git a/rice.sh b/rice.sh
new file mode 100755
index 0000000..68ca028
--- /dev/null
+++ b/rice.sh
@@ -0,0 +1,197 @@
+#!/bin/sh
+set -e
+WORKDIRECTORY=$PWD
+
+if [ "$(id -u)" -ne 0 ]
+ then printf "The script has to be run as root.\n"
+ exit
+fi
+
+if [ -x "$(command -v doas)" ]; then
+ PERMUSER=$DOAS_USER
+ evalcommand="doas -u $PERMUSER"
+ cp /etc/doas.conf /etc/doas.bak
+ echo "permit nopass :wheel" > /etc/doas.conf
+ echo "permit nopass root" >> /etc/doas.conf
+else
+ PERMUSER=$SUDO_USER
+ evalcommand="sudo -u $PERMUSER"
+ echo "%wheel ALL=(ALL) NOPASSWD: ALL
+ Defaults:%wheel,root runcwd=*" >/etc/sudoers.d/temp
+fi
+
+run_as_user() {
+ $evalcommand "$@"
+}
+
+usermod -aG seat $PERMUSER
+
+DEPLIST="`sed -e 's/#.*$//' -e '/^$/d' dependencies.txt | tr '\n' ' '`"
+pacman -Sy --noconfirm
+pacman -S $DEPLIST --noconfirm --needed
+
+run_as_user cp -r "$WORKDIRECTORY"/.config /home/"$PERMUSER"
+run_as_user cp -r "$WORKDIRECTORY"/.local /home/"$PERMUSER"
+run_as_user cp -a "$WORKDIRECTORY"/.zprofile /home/"$PERMUSER"
+
+run_as_user mkdir -p /home/"$PERMUSER"/.config/git
+run_as_user touch /home/"$PERMUSER"/.config/git/config
+run_as_user mkdir -p /home/"$PERMUSER"/.config/npm
+run_as_user touch /home/"$PERMUSER"/.config/npm/npmrc
+run_as_user mkdir -p /home/"$PERMUSER"/.cache/zsh
+run_as_user mkdir -p /home/"$PERMUSER"/.config/mpd/playlists
+run_as_user mkdir -p /home/"$PERMUSER"/.local/share/themes
+run_as_user mkdir -p /home/"$PERMUSER"/.local/share/icons
+
+cd "$WORKDIRECTORY" || exit
+run_as_user git clone https://github.com/zdharma-continuum/fast-syntax-highlighting
+mkdir -p /usr/share/zsh/plugins
+cp -rf fast-syntax-highlighting /usr/share/zsh/plugins
+cd "$WORKDIRECTORY"
+
+run_as_user mkdir -p /home/"$PERMUSER"/.ssh
+run_as_user mkdir -p /home/"$PERMUSER"/.gnupg
+run_as_user touch /home/"$PERMUSER"/.gnupg/gpg-agent.conf
+
+cat <<EOL >> /home/$PERMUSER/.gnupg/gpg-agent.conf
+enable-ssh-support
+pinentry-program /usr/bin/pinentry-gnome3
+default-cache-ttl 34560000
+max-cache-ttl 34560000
+EOL
+
+cat <<EOL >> /home/$PERMUSER/.config/npm/npmrc
+prefix=\${XDG_DATA_HOME}/npm
+cache=\${XDG_CACHE_HOME}/npm
+init-module=\${XDG_CONFIG_HOME}/npm/config/npm-init.js
+logs-dir=\${XDG_STATE_HOME}/npm/logs
+EOL
+
+run_as_user find /home/"$PERMUSER"/.gnupg -type f -exec chmod 600 {} \;
+run_as_user find /home/"$PERMUSER"/.gnupg -type d -exec chmod 700 {} \;
+run_as_user find /home/"$PERMUSER"/.ssh -type f -exec chmod 600 {} \;
+run_as_user find /home/"$PERMUSER"/.ssh -type d -exec chmod 700 {} \;
+
+chsh -s /bin/zsh "$PERMUSER"
+
+# Make pacman colorful, concurrent downloads and Pacman eye-candy.
+grep -q "ILoveCandy" /etc/pacman.conf || sed -i "/#VerbosePkgLists/a ILoveCandy" /etc/pacman.conf
+sed -Ei "s/^#(ParallelDownloads).*/\1 = 5/;/^#Color$/s/#//" /etc/pacman.conf
+
+# Disable Pacman sandbox since kernel doesn't support landlock (only for custom kernels from my artix script)
+# sed -Ei "s/^#(DisableSandbox).*/\1/" /etc/pacman.conf
+
+# Use all cores for compilation.
+sed -i "s/-j2/-j$(nproc)/;/^#MAKEFLAGS/s/^#//" /etc/makepkg.conf
+
+if [ -x "$(command -v doas)" ]; then
+ # Use doas for Pacman authentification
+ sed -i 's/#PACMAN_AUTH=.*$/PACMAN_AUTH=(doas)/' /etc/makepkg.conf
+fi
+
+cat <<EOL >> /usr/share/libalpm/hooks/statusbar.hook
+[Trigger]
+Operation = Upgrade
+Type = Package
+Target = *
+
+[Action]
+Description = Updating statusbar...
+When = PostTransaction
+Exec = /usr/bin/pkill -RTMIN+8 waybar
+EOL
+
+cat <<EOL >> /etc/pacman.d/hooks/sing-box.hook
+[Trigger]
+Type = Package
+Operation = Install
+Operation = Upgrade
+Target = sing-box
+
+[Action]
+Description = Setting rights for sing-box...
+When = PostTransaction
+Exec = /usr/bin/setcap cap_net_admin=ep /usr/sbin/sing-box
+EOL
+
+run_as_user git clone https://aur.archlinux.org/paru.git
+cd paru
+run_as_user makepkg -csi --noconfirm
+cd "$WORKDIRECTORY"
+DEPLIST="`sed -e 's/#.*$//' -e '/^$/d' aurdeps.txt | tr '\n' ' '`"
+run_as_user paru --sudo doas -S $DEPLIST --noconfirm
+run_as_user dbus-launch gsettings set org.gnome.desktop.wm.preferences button-layout 'appmenu'
+run_as_user dbus-launch gsettings set org.gnome.desktop.interface font-name "Sans 11"
+cd ..
+rm -rf hyprdots
+rm -rf paru
+rm -rf go
+
+dinitctl enable cronie
+echo "*/30 * * * * export DBUS_SESSION_BUS_ADDRESS=\$(rg --null-data \"DBUS_SESSION_BUS_ADDRESS\" \"/proc/\$(pgrep -x waybar)/environ\" | sed 's/DBUS_SESSION_BUS_ADDRESS=//'); /home/$PERMUSER/.local/bin/cron/newsup
+*/30 * * * * export DBUS_SESSION_BUS_ADDRESS=\$(rg --null-data \"DBUS_SESSION_BUS_ADDRESS\" \"/proc/\$(pgrep -x waybar)/environ\" | sed 's/DBUS_SESSION_BUS_ADDRESS=//'); /home/$PERMUSER/.local/bin/cron/checkup
+*/10 * * * * export DBUS_SESSION_BUS_ADDRESS=\$(rg --null-data \"DBUS_SESSION_BUS_ADDRESS\" \"/proc/\$(pgrep -x waybar)/environ\" | sed 's/DBUS_SESSION_BUS_ADDRESS=//'); /home/$PERMUSER/.local/bin/cron/mailup" | run_as_user crontab -
+
+run_as_user git clone https://git.awy.one/mutt-wizard /home/"$PERMUSER"/mutt-wizard
+cd /home/"$PERMUSER"/mutt-wizard
+make install
+
+cd /home/"$PERMUSER"
+run_as_user git clone https://git.awy.one/autofox
+cd autofox
+run_as_user ./configure_firefox.sh
+cd /home/"$PERMUSER"
+
+run_as_user git clone https://git.awy.one/mew
+cd /home/"$PERMUSER"/mew
+run_as_user git checkout default_theme
+make install
+cd /home/"$PERMUSER"
+
+rm -rf autofox
+rm -rf mutt-wizard
+rm -rf mew
+
+# MPV
+thumbfastlua_url=https://raw.githubusercontent.com/po5/thumbfast/refs/heads/master/thumbfast.lua
+thumbfastconf_url=https://raw.githubusercontent.com/po5/thumbfast/refs/heads/master/thumbfast.conf
+sponsorblock_url=https://codeberg.org/jouni/mpv_sponsorblock_minimal/raw/branch/master/sponsorblock_minimal.lua
+config_dir="/home/$PERMUSER/.config/mpv"
+scriptopts_dir="$config_dir/script-opts"
+
+run_as_user mkdir -p "$config_dir/scripts"
+run_as_user mkdir -p $scriptopts_dir || echo "Couldn't create: $scriptopts_dir"
+
+# thumbfast
+run_as_user curl -Ls -o "$config_dir/scripts/thumbfast.lua" $thumbfastlua_url || echo "Couldn't download: $thumbfastlua_url"
+run_as_user curl -Ls -o "$scriptopts_dir/thumbfast.conf" $thumbfastconf_url || echo "Couldn't download: $thumbfastconf_url"
+sed -Ei "s/(network).*/\1=yes/" "$scriptopts_dir/thumbfast.conf"
+
+# sponsorblock
+run_as_user curl -Ls -o "$config_dir/scripts/sponsorblock_minimal.lua" $sponsorblock_url || echo "Couldn't download: $sponsorblock_url"
+
+# necessary symlinks (pass for mutt-wizard and bemenu for tessen)
+ln -s /bin/gopass /bin/pass
+ln -s /usr/local/bin/mew /bin/bemenu
+
+# pam
+sed -i '/auth[[:space:]]*include[[:space:]]*system-local-login/a auth optional pam_gnome_keyring.so' /etc/pam.d/login
+sed -i '/session[[:space:]]*include[[:space:]]*system-local-login/a session optional pam_gnome_keyring.so auto_start' /etc/pam.d/login
+echo "password optional pam_gnome_keyring.so" >> /etc/pam.d/passwd
+
+yes | run_as_user paru --sudo doas -Scc
+rm -rf /home/"$PERMUSER"/.cargo
+
+if [ -x "$(command -v doas)" ]; then
+ rm /etc/doas.conf
+ mv /etc/doas.bak /etc/doas.conf
+else
+ rm /etc/sudoers.d/temp
+fi
+
+chown -R $PERMUSER:wheel /home/$PERMUSER
+
+# cleanup
+rm -rf /home/$PERMUSER/.cache/go-build
+
+echo "Your linux is riced!"