~kris/dots

srice

c8d9c68937f2c331a6bac47481ed40147fe73cba — Kris Yotam 4 months ago ff7367c
shell migration: fish -> mksh, reorganize bin/, wallpaper cleanup

- replace fish config with .profile (POSIX login) and .mkshrc (interactive)
- organize .local/bin into subdirs: academic, cron, dev, dmenu, history,
  media, misc, monitoring, nnn, security, statusbar, system
- all subdirs added to PATH, scripts callable by name from anywhere
- remove fish config, .config/shell/aliasrc, .config/shell/profile
- consolidate sb-* scripts into statusbar/ (updated stale copies)
- convert wallpapers to webp, slug-WxH naming scheme
- regenerate plan9 solid fills at proper monitor dimensions
- fix larbs -> lazykris path refs across scripts
- remove remapd from both xprofile files
- fix bashism shebangs (11 scripts: #!/bin/sh -> #!/bin/bash)
- update bm-dirs/bm-files for current home layout
- update emoji set to Unicode 15.0 (3655 entries)
- merge push + push-smart into single script with --smart flag
- delete one-off scripts, convert trivial wrappers to aliases
227 files changed, 6418 insertions(+), 2251 deletions(-)

D .config/fish/conf.d/history.fish
D .config/fish/conf.d/rustup.fish
D .config/fish/config.fish
D .config/fish/functions/earth.fish
D .config/fish/functions/feedsync.fish
D .config/fish/functions/ff.fish
D .config/fish/functions/fish_mode_prompt.fish
D .config/fish/functions/fish_prompt.fish
D .config/fish/functions/nnncd.fish
D .config/fish/functions/se.fish
D .config/shell/aliasrc
M .config/shell/bm-dirs
M .config/shell/bm-files
D .config/shell/profile
M .config/systemd/user/history-browser-sync.service
M .config/systemd/user/history-clipboard.service
D .config/wallpapers/.gitkeep
M .config/x11/xprofile
R .local/bin/{ => academic}/anki-cli
R .local/bin/{ => academic}/compile-all-masters.py
R .local/bin/{ => academic}/countdown.py
R .local/bin/{ => academic}/courses.py
R .local/bin/{ => academic}/lectures.py
R .local/bin/{ => academic}/math-utils.py
R .local/bin/{ => academic}/questions
R .local/bin/{ => academic}/rofi-courses.py
R .local/bin/{ => academic}/rofi-lectures-view.py
R .local/bin/{ => academic}/rofi-lectures.py
A .local/bin/academic/words-drill
R .local/bin/{ => cron}/README.md -rwxr-xr-x => -rw-r--r--
R .local/bin/{ => cron}/checkup
D .local/bin/cron/checkup.sh
D .local/bin/cron/crongtog.sh
R .local/bin/{ => cron}/crontog
A .local/bin/cron/cve
R .local/bin/{ => cron}/newsup
D .local/bin/cron/newsup.sh
A .local/bin/dev/agenticstats
A .local/bin/dev/deps
A .local/bin/dev/kd
A .local/bin/dev/killnext
A .local/bin/dev/push
R .local/bin/{ => dmenu}/dbrowse
R .local/bin/{ => dmenu}/dcalc
R .local/bin/{ => dmenu}/dclip
R .local/bin/{ => dmenu}/dcreate
R .local/bin/{ => dmenu}/dedit
R .local/bin/{ => dmenu}/dkymap
R .local/bin/{ => dmenu}/dlaunch
R .local/bin/{ => dmenu}/dllm
R .local/bin/{ => dmenu}/dlog
R .local/bin/{ => dmenu}/dmenuhandler
R .local/bin/{ => dmenu}/dmenumountcifs
R .local/bin/{ => dmenu}/dmenupass
R .local/bin/{ => dmenu}/dmenurecord
R .local/bin/{ => dmenu}/dmenuunicode
R .local/bin/{ => dmenu}/dmode
R .local/bin/{ => dmenu}/dnotes
R .local/bin/{ => dmenu}/dread
R .local/bin/{ => dmenu}/dsnip
R .local/bin/{ => dmenu}/dsnip-seed
R .local/bin/{ => dmenu}/dtime
R .local/bin/{ => dmenu}/dwrite
D .local/bin/dwmblocks-start
D .local/bin/essay
D .local/bin/git-setup-mirrors
R .local/bin/{ => history}/history
R .local/bin/{ => history}/history-clipboard-daemon
R .local/bin/{ => history}/history-init
R .local/bin/{ => history}/history-sync-browsers
D .local/bin/init-all-courses.py
R .local/bin/{ => media}/bg-picker
R .local/bin/{ => media}/booksplit
R .local/bin/{ => media}/maimpick
R .local/bin/{ => media}/noisereduce
R .local/bin/{ => media}/opout
R .local/bin/{ => media}/output
R .local/bin/{ => media}/pauseallmpv
R .local/bin/{ => media}/peertubetorrent
R .local/bin/{ => media}/qndl
R .local/bin/{ => media}/record
R .local/bin/{ => media}/rotdir
R .local/bin/{ => media}/screenshot
R .local/bin/{ => media}/setbg
R .local/bin/{ => media}/slider
R .local/bin/{ => media}/transadd
A .local/bin/misc/README.md
R .local/bin/{ => misc}/bm
R .local/bin/{ => misc}/browser
R .local/bin/{ => misc}/cmd-menu
R .local/bin/{ => misc}/commit
R .local/bin/{ => misc}/compiler
R .local/bin/{ => misc}/config.py
R .local/bin/{ => misc}/create
R .local/bin/{ => misc}/edit
R .local/bin/{ => misc}/email
R .local/bin/{ => misc}/getbib
R .local/bin/{ => misc}/getkeys
R .local/bin/{ => misc}/git
R .local/bin/{ => misc}/irc
R .local/bin/{ => misc}/linkhandler
R .local/bin/{ => misc}/pin
R .local/bin/{ => misc}/podentr
R .local/bin/{ => misc}/queueandnotify
R .local/bin/{ => misc}/rofi.py
R .local/bin/{ => misc}/rssadd
R .local/bin/{ => misc}/rssget
R .local/bin/{ => misc}/sort
R .local/bin/{ => misc}/sread
R .local/bin/{ => misc}/sync
R .local/bin/{ => misc}/tag
R .local/bin/{ => misc}/td-toggle
R .local/bin/{ => misc}/todo
A .local/bin/misc/udemy-dl
R .local/bin/{ => misc}/unix
R .local/bin/{ => misc}/vroid
R .local/bin/{ => misc}/weath
R .local/bin/{ => misc}/webdev
R .local/bin/{ => misc}/write
A .local/bin/misc/ybrowser
R .local/bin/{ => misc}/ytcomments
A .local/bin/monitoring/hanta
R .local/bin/{ => monitoring}/kaiju-probability-index
R .local/bin/{ => monitoring}/maritime-charts
R .local/bin/{ => monitoring}/ocean-heat-content-index
R .local/bin/{ => monitoring}/sea-surface-temperature-anomaly
R .local/bin/{ => monitoring}/subsea-seismic-monitor
R .local/bin/{ => monitoring}/supervolcano-monitor
D .local/bin/mouse
D .local/bin/nnn-typora
R .local/bin/{ => nnn}/lfub
R .local/bin/{ => nnn}/nnn-zathura
D .local/bin/papers-setup
D .local/bin/sb-aurora
D .local/bin/sb-battery
D .local/bin/sb-brightness
D .local/bin/sb-clock
D .local/bin/sb-cpu
D .local/bin/sb-cpubars
D .local/bin/sb-dashboard
D .local/bin/sb-disk
D .local/bin/sb-doppler
D .local/bin/sb-forecast
D .local/bin/sb-help-icon
D .local/bin/sb-internet
D .local/bin/sb-iplocate
D .local/bin/sb-kbselect
D .local/bin/sb-mailbox
D .local/bin/sb-memory
D .local/bin/sb-moonphase
D .local/bin/sb-mpdup
D .local/bin/sb-music
D .local/bin/sb-nettraf
D .local/bin/sb-news
D .local/bin/sb-ocean
D .local/bin/sb-pacpackages
D .local/bin/sb-playerctl
D .local/bin/sb-popupgrade
D .local/bin/sb-price
D .local/bin/sb-tasks
D .local/bin/sb-temps
D .local/bin/sb-ticker
D .local/bin/sb-torrent
D .local/bin/sb-volume
R .local/bin/{ => security}/htb
R .local/bin/{ => security}/htbvpn
R .local/bin/{ => security}/otp
R .local/bin/{ => security}/shred
A .local/bin/security/surf
R .local/bin/{ => security}/torwrap
M .local/bin/statusbar/sb-battery
M .local/bin/statusbar/sb-clock
M .local/bin/statusbar/sb-dashboard
M .local/bin/statusbar/sb-disk
M .local/bin/statusbar/sb-doppler
M .local/bin/statusbar/sb-forecast
M .local/bin/statusbar/sb-help-icon
M .local/bin/statusbar/sb-internet
M .local/bin/statusbar/sb-iplocate
M .local/bin/statusbar/sb-mailbox
M .local/bin/statusbar/sb-nettraf
M .local/bin/statusbar/sb-news
M .local/bin/statusbar/sb-pacpackages
R .local/bin/{ => statusbar}/sb-surge
R .local/bin/{ => statusbar}/sb-systemstats
M .local/bin/statusbar/sb-temps
M .local/bin/statusbar/sb-torrent
M .local/bin/statusbar/sb-volume
R .local/bin/{xdg-terminal-exec => system/CAPS}
R .local/bin/{ => system}/appinstall
A .local/bin/system/checkup
R .local/bin/{ => system}/clean
A .local/bin/system/crontog
R .local/bin/{ => system}/displayselect
R .local/bin/{ => system}/getcomproot
R .local/bin/{ => system}/ifinstalled
R .local/bin/{ => system}/laptop
R .local/bin/{ => system}/mounter
A .local/bin/system/newsup
R .local/bin/{ => system}/ram
R .local/bin/{ => system}/sd
R .local/bin/{ => system}/shortcuts
R .local/bin/{ => system}/sortfiles
R .local/bin/{ => system}/sysact
R .local/bin/{ => system}/trash
R .local/bin/{ => system}/unmounter
D .local/bin/tutorialvids
D .local/bin/warp
M .local/share/lazykris/bg
M .local/share/lazykris/chars/emoji
M .local/share/lazykris/emoji
D .local/share/lazykris/lazykris-wallpaper.png
A .local/share/wallpapers/cs-winter-1920x960.webp
D .local/share/wallpapers/d1e2f1-horizontal.png
D .local/share/wallpapers/d1e2f1-vertical.png
R .local/share/wallpapers/{khr1st => image1-1536x1024}.webp
A .local/share/wallpapers/image2-1920x1200.webp
A .local/share/wallpapers/image3-1920x1080.webp
D .local/share/wallpapers/khr1st-pain-wallpaper.png
D .local/share/wallpapers/kris-wallpaper-1.jpg
D .local/share/wallpapers/lazykris-perfect-blue-wallpaper.jpg
A .local/share/wallpapers/p9blue-1080x1920.png
A .local/share/wallpapers/p9blue-2560x1440.png
D .local/share/wallpapers/winter-color-scheme.png
A .mkshrc
A .profile
M .xprofile
D .config/fish/conf.d/history.fish => .config/fish/conf.d/history.fish +0 -40
@@ 1,40 0,0 @@
# history - Terminal history logging for fish shell (encrypted with SQLCipher)

set -g __kh_db "$HOME/.local/share/history/history.db"
set -g __kh_key_file "$HOME/.local/share/history/.key"
set -g __kh_last_command ""

function __kh_preexec --on-event fish_preexec
    set -g __kh_last_command "$argv"
end

function __kh_postexec --on-event fish_postexec
    set -l exit_code $status
    set -l cmd "$__kh_last_command"
    set -l pwd_path (pwd)

    # Skip empty commands
    test -z "$cmd"; and return

    # Skip history command itself to avoid recursion
    string match -qr '^history' "$cmd"; and return

    # Skip if key file or database doesn't exist
    test -f "$__kh_key_file"; or return
    test -f "$__kh_db"; or return

    # Escape single quotes for SQL (use fish's string replace)
    set -l escaped_cmd (string replace -a "'" "''" -- "$cmd")
    set -l escaped_pwd (string replace -a "'" "''" -- "$pwd_path")

    # Log to database (async to not slow down shell)
    fish -c "
        set -l key (cat '$__kh_key_file')
        sqlcipher '$__kh_db' \"PRAGMA key = '\$key'; INSERT INTO terminal_history (command, exit_code, pwd, shell) VALUES ('$escaped_cmd', $exit_code, '$escaped_pwd', 'fish');\"
    " &>/dev/null &
end

# Initialize database if it doesn't exist
if not test -f "$__kh_db"
    history-init 2>/dev/null
end

D .config/fish/conf.d/rustup.fish => .config/fish/conf.d/rustup.fish +0 -1
@@ 1,1 0,0 @@
source "$HOME/.local/share/cargo/env.fish" 2>/dev/null

D .config/fish/config.fish => .config/fish/config.fish +0 -231
@@ 1,231 0,0 @@
# ────────────────────────────────────────
# Fish Shell Configuration
# Author: Kris Yotam <krisyotam@gmail.com>
# ────────────────────────────────────────

# ─── Terminal Size Fix ─────────────────
# Force fish to detect actual terminal dimensions on startup
# Fixes prompt width issues with st + starship
if status is-interactive
    set -g fish_handle_reflow 1
    # Use Ctrl+K as interrupt (kill) since st uses Ctrl+C for copy
    stty intr \ck
end

# ─── PATH ───────────────────────────────
# Add ~/.local/bin and subdirectories to PATH
for dir in ~/.local/bin/**/
    set -gx PATH $PATH $dir
end
set -gx PATH $PATH ~/.local/bin $HOME/bin

# Doom Emacs binary path
fish_add_path $HOME/.config/emacs/bin

# Plan 9 from User Space (appended so plan9 tools don't override GNU coreutils)
set -gx PLAN9 /usr/lib/plan9
# Remove plan9 from anywhere in PATH, then re-add at the end
while set -l idx (contains -i -- $PLAN9/bin $PATH)
    set -e PATH[$idx]
end
set -gx PATH $PATH $PLAN9/bin

# ─── Default Programs ───────────────────
set -gx EDITOR nvim
set -gx VISUAL nvim
set -gx TERMINAL st
set -gx TERMINAL_PROG st
set -gx BROWSER librewolf

# ─── XDG Base Directories ───────────────
set -gx XDG_CONFIG_HOME $HOME/.config
set -gx XDG_DATA_HOME $HOME/.local/share
set -gx XDG_CACHE_HOME $HOME/.cache

# ─── XDG Cleanup ────────────────────────
set -gx XINITRC $XDG_CONFIG_HOME/x11/xinitrc
set -gx NOTMUCH_CONFIG $XDG_CONFIG_HOME/notmuch-config
set -gx GTK2_RC_FILES $XDG_CONFIG_HOME/gtk-2.0/gtkrc-2.0
set -gx WGETRC $XDG_CONFIG_HOME/wget/wgetrc
set -gx WINEPREFIX $XDG_DATA_HOME/wineprefixes/default
set -gx KODI_DATA $XDG_DATA_HOME/kodi
set -gx PASSWORD_STORE_DIR $XDG_DATA_HOME/password-store
set -gx ANDROID_SDK_HOME $XDG_CONFIG_HOME/android
set -gx CARGO_HOME $XDG_DATA_HOME/cargo
set -gx GOPATH $XDG_DATA_HOME/go
set -gx GOMODCACHE $XDG_CACHE_HOME/go/mod
set -gx ANSIBLE_CONFIG $XDG_CONFIG_HOME/ansible/ansible.cfg
set -gx UNISON $XDG_DATA_HOME/unison
set -gx MBSYNCRC $XDG_CONFIG_HOME/mbsync/config
set -gx ELECTRUMDIR $XDG_DATA_HOME/electrum
set -gx PYTHONSTARTUP $XDG_CONFIG_HOME/python/pythonrc
set -gx SQLITE_HISTORY $XDG_DATA_HOME/sqlite_history

# ─── nnn File Manager ──────────────────
set -gx NNN_OPTS "adeHQ"                   # a=auto FIFO, d=detail, e=text in $EDITOR, H=show hidden, Q=quit on cd
set -gx NNN_PLUG "p:preview-tui;f:fzcd;o:fzopen;i:imgview;z:autojump"
set -gx NNN_FIFO "/tmp/nnn.fifo"
set -gx NNN_OPENER "$HOME/.config/nnn/plugins/nuke"
set -gx NNN_BMS "d:~/Documents;D:~/Downloads;c:~/.config;p:~/dev;h:~;w:~/content"
set -gx NNN_TRASH 1                        # use trash-cli
set -gx NNN_PREVIEWIMGPROG "ueberzug"      # image previews via ueberzugpp

# ─── Program Settings ───────────────────
set -gx DICS /usr/share/stardict/dic/
set -gx SUDO_ASKPASS $HOME/.local/bin/dmenupass
set -gx FZF_DEFAULT_OPTS "--layout=reverse --height 40%"
set -gx LESS R
set -gx LESSOPEN "| /usr/bin/highlight -O ansi %s 2>/dev/null"
set -gx QT_QPA_PLATFORMTHEME gtk2
set -gx MOZ_USE_XINPUT2 1
set -gx AWT_TOOLKIT "MToolkit wmname LG3D"
set -gx _JAVA_AWT_WM_NONREPARENTING 1

# ─── Less Colors ────────────────────────
set -gx LESS_TERMCAP_mb (printf '\e[1;31m')
set -gx LESS_TERMCAP_md (printf '\e[1;36m')
set -gx LESS_TERMCAP_me (printf '\e[0m')
set -gx LESS_TERMCAP_so (printf '\e[01;44;33m')
set -gx LESS_TERMCAP_se (printf '\e[0m')
set -gx LESS_TERMCAP_us (printf '\e[1;32m')
set -gx LESS_TERMCAP_ue (printf '\e[0m')

# ─── Disable Greeting ─────────────────
set -g fish_greeting

# ─── Vi Mode ────────────────────────────
fish_vi_key_bindings

# ─── Keybindings ────────────────────────
bind \co 'nnncd; commandline -f repaint'
bind \cf 'cd (dirname (fzf)); commandline -f repaint'
bind \ce edit_command_buffer

# Also bind for insert mode
bind -M insert \co 'nnncd; commandline -f repaint'
bind -M insert \cf 'cd (dirname (fzf)); commandline -f repaint'
bind -M insert \ce edit_command_buffer

# ─── Abbreviations (Aliases) ────────────
# Core utilities
abbr -a vim nvim
abbr -a cp "cp -iv"
abbr -a mv "mv -iv"
abbr -a rm "rm -vI"
abbr -a mkd "mkdir -pv"
abbr -a grep "grep --color=auto"
abbr -a diff "diff --color=auto"

# Modern CLI replacements
abbr -a ls "eza --icons --group-directories-first"
abbr -a ll "eza -la --icons --group-directories-first"
abbr -a la "eza -a --icons --group-directories-first"
abbr -a lt "eza --tree --icons --group-directories-first"
abbr -a cat "bat --paging=never"

# Shortcuts
abbr -a ka killall
abbr -a g git
abbr -a e $EDITOR
abbr -a v $EDITOR
abbr -a p pacman
abbr -a z zathura
abbr -a lf nnncd
abbr -a bin "nnn ~/.local/bin"

# System commands
abbr -a logout "pkill -KILL -u krisyotam"
abbr -a lock slock
abbr -a shutdown "sudo shutdown now"
abbr -a restart "sudo systemctl reboot"

# Audio devices
abbr -a hs65 "pactl set-default-sink alsa_output.usb-Corsair_Corsair_HS65_SURROUND-00.analog-stereo"
abbr -a airpods "pactl set-default-sink bluez_output.20_15_82_D9_F9_CC.1"

# Applications
# irc is now a script wrapping catgirl — see ~/.local/bin/irc
abbr -a browser "$BROWSER &"
abbr -a rss "sfeed_curses ~/.sfeed/feeds/*"
abbr -a hn "hakuneko-desktop &"
abbr -a torrent rtorrent

# Flatpak Applications (long commands need aliases)
abbr -a discord "flatpak run com.discordapp.Discord &"
abbr -a notesnook "flatpak run com.notesnook.Notesnook &"
abbr -a novelwriter "flatpak run io.novelwriter.novelWriter &"
abbr -a symbol-editor "flatpak run org.kde.SymbolEditor &"
abbr -a steam "flatpak run com.valvesoftware.Steam"
abbr -a vscode "flatpak run com.visualstudio.code &"
abbr -a anki "flatpak run net.ankiweb.Anki &"
abbr -a tropy "flatpak run org.tropy.Tropy &"

# AppImage Applications
abbr -a hayase "$HOME/.local/bin/appimages/hayase &"

# Terminal UI tools
abbr -a mutt neomutt
abbr -a lg lazygit
abbr -a ld lazydocker
abbr -a ytdl yt-dlp
abbr -a top btop
abbr -a ff fastfetch
abbr -a htop btop

# Claude Code
abbr -a claude "claude --dangerously-skip-permissions"

# Sophia virtual assistant
alias sophia='cd ~/dev/sophia && ./sophia'

# Application aliases
function zed; command zeditor $argv &; disown; end
function warp; command warp-terminal $argv &; disown; end
function mouse; command mouseless $argv &; disown; end

# Git abbreviations
abbr -a ga "git add"
abbr -a gc "git commit"
abbr -a gp "git push"
abbr -a gl "git pull"
abbr -a gs "git status"
abbr -a gd "git diff"
abbr -a gco "git checkout"
abbr -a gb "git branch"
abbr -a glog "git log --oneline --graph"

# Sudo shortcuts
abbr -a sv "sudo nvim"
abbr -a sp "sudo pacman"

# Edit configuration files
abbr -a fishrc "$EDITOR ~/.config/fish/config.fish"
abbr -a nvimrc "$EDITOR ~/.config/nvim/init.lua"
abbr -a snippets "$EDITOR ~/.local/share/karbs/snippets"

# ─── Maritime Monitoring (Monarch Suite) ────
abbr -a sst sea-surface-temperature-anomaly
abbr -a seismic subsea-seismic-monitor
abbr -a ohc ocean-heat-content-index
abbr -a maritime maritime-charts
abbr -a kpi kaiju-probability-index

# ─── Zoxide (smarter cd) ───────────────
if type -q zoxide
    zoxide init fish | source
end

# ─── Direnv (per-directory env vars) ────
if type -q direnv
    direnv hook fish | source
end

# ─── Prompt ────────────────────────────
# Prompt is defined in ~/.config/fish/functions/fish_prompt.fish
# If you want starship instead, uncomment the line below:
# starship init fish | source

# ─── Start X on tty1 ────────────────────
if test (tty) = /dev/tty1; and not pgrep -x Xorg > /dev/null
    exec startx $XINITRC
end

D .config/fish/functions/earth.fish => .config/fish/functions/earth.fish +0 -4
@@ 1,4 0,0 @@
function earth --description "Launch Google Earth Pro (detached)"
    setsid google-earth-pro &>/dev/null &
    disown
end

D .config/fish/functions/feedsync.fish => .config/fish/functions/feedsync.fish +0 -9
@@ 1,9 0,0 @@
function feedsync -d "Sync kris.opml into sfeedrc"
    set -l opml "$HOME/dev/krisyotam.com/public/kris.opml"
    if not test -f $opml
        echo "feedsync: $opml not found" >&2
        return 1
    end
    sfeed_opml_import <$opml >~/.sfeed/sfeedrc
    echo "sfeedrc updated from kris.opml"
end

D .config/fish/functions/ff.fish => .config/fish/functions/ff.fish +0 -54
@@ 1,54 0,0 @@
# ff - fastfetch with logo flags
# Usage: ff [-logo]
# Examples: ff, ff -apple, ff -arch, ff -linux

function ff
    if test (count $argv) -eq 0
        fastfetch
    else
        # Get the flag without the dash and convert to lowercase
        set -l raw $argv[1]
        set -l flag (string lower -- (string replace -r -- '^-' '' $raw))

        switch $flag
            case apple
                fastfetch --logo Apple
            case arch
                fastfetch --logo Arch
            case linux
                fastfetch --logo Linux
            case debian
                fastfetch --logo Debian
            case ubuntu
                fastfetch --logo Ubuntu
            case fedora
                fastfetch --logo Fedora
            case gentoo
                fastfetch --logo Gentoo
            case nixos
                fastfetch --logo NixOS
            case void
                fastfetch --logo Void
            case manjaro
                fastfetch --logo Manjaro
            case mint
                fastfetch --logo Mint
            case pop
                fastfetch --logo Pop
            case kali
                fastfetch --logo Kali
            case parrot
                fastfetch --logo Parrot
            case glenda
                fastfetch -c ~/.config/fastfetch/glenda.jsonc
            case badapple bad-apple
                fastfetch -c ~/.config/fastfetch/bad-apple.jsonc
            case cirno
                fastfetch -c ~/.config/fastfetch/cirno.jsonc
            case '*'
                # Try to use the argument as a logo name directly (capitalize first letter)
                set -l logo (string sub -l 1 -- $flag | string upper)(string sub -s 2 -- $flag)
                fastfetch --logo $logo
        end
    end
end

D .config/fish/functions/fish_mode_prompt.fish => .config/fish/functions/fish_mode_prompt.fish +0 -3
@@ 1,3 0,0 @@
function fish_mode_prompt --description "Vi mode indicator"
    # Empty - mode is shown in main prompt or disable entirely for cleaner look
end

D .config/fish/functions/fish_prompt.fish => .config/fish/functions/fish_prompt.fish +0 -14
@@ 1,14 0,0 @@
function fish_prompt
    set_color blue
    echo -n (whoami)
    set_color normal
    echo -n "@"
    set_color magenta
    echo -n (hostname -s)
    set_color normal
    echo -n ":"
    set_color cyan
    echo -n (prompt_pwd)
    set_color normal
    echo -n " > "
end

D .config/fish/functions/nnncd.fish => .config/fish/functions/nnncd.fish +0 -25
@@ 1,25 0,0 @@
function nnncd --description "nnn file manager with cd on exit"
    # Block nesting of nnn in subshells
    if test -n "$NNNLVL" -a "$NNNLVL" -ge 1
        echo "nnn is already running"
        return
    end

    # Use -Q to quit on cd
    set -x NNN_TMPFILE "$XDG_CONFIG_HOME/nnn/.lastd"
    if test -z "$NNN_TMPFILE"
        set -x NNN_TMPFILE "$HOME/.config/nnn/.lastd"
    end

    nnn -Q $argv

    if test -e "$NNN_TMPFILE"
        source "$NNN_TMPFILE"
        rm -f "$NNN_TMPFILE"
    end
end

# Alias n to nnncd
function n --description "nnn with cd on exit"
    nnncd $argv
end

D .config/fish/functions/se.fish => .config/fish/functions/se.fish +0 -6
@@ 1,6 0,0 @@
function se --description "Script editor - edit scripts in ~/.local/bin"
    set choice (find ~/.local/bin -mindepth 1 -printf '%P\n' | fzf)
    if test -n "$choice"; and test -f "$HOME/.local/bin/$choice"
        $EDITOR "$HOME/.local/bin/$choice"
    end
end

D .config/shell/aliasrc => .config/shell/aliasrc +0 -60
@@ 1,60 0,0 @@
#!/bin/sh

# Use neovim for vim if present.
[ -x "$(command -v nvim)" ] && alias vim="nvim" vimdiff="nvim -d"

# Use $XINITRC variable if file exists.
[ -f "$XINITRC" ] && alias startx='startx $XINITRC'

[ -f "$MBSYNCRC" ] && alias mbsync='mbsync -c $MBSYNCRC'

# sudo not required for some system commands
for command in mount umount sv pacman updatedb su shutdown poweroff reboot ; do
	alias $command="sudo $command"
done; unset command

se() {
	choice="$(find ~/.local/bin -mindepth 1 -printf '%P\n' | 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 \
	ls="ls -hN --color=auto --group-directories-first" \
	grep="grep --color=auto" \
	diff="diff --color=auto" \
	ccat="highlight --out-format=ansi" \
	ip="ip -color=auto"

# These common commands are just too long! Abbreviate them.
alias \
	ka="killall" \
	g="git" \
	trem="transmission-remote" \
	YT="youtube-viewer" \
	sdn="shutdown -h now" \
	e='$EDITOR' \
	v='$EDITOR' \
	p="pacman" \
	xi="sudo xbps-install" \
	xr="sudo xbps-remove -R" \
	xq="xbps-query" \
	z="zathura"

alias \
	lf="lfub" \
	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'
\ No newline at end of file

M .config/shell/bm-dirs => .config/shell/bm-dirs +8 -7
@@ 1,14 1,15 @@
# You can add comments to these files with #
# Directory bookmarks for shell shortcuts
cac ${XDG_CACHE_HOME:-$HOME/.cache}
cf  ${XDG_CONFIG_HOME:-$HOME/.config}
D   ${XDG_DOWNLOAD_DIR:-$HOME/Downloads}
d   ${XDG_DOCUMENTS_DIR:-$HOME/Documents}
dl  $HOME/downloads
dt  ${XDG_DATA_HOME:-$HOME/.local/share}
rr  $HOME/.local/src
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}
\ No newline at end of file
src $HOME/src
dev $HOME/dev
sb  $HOME/slipbox
px  $HOME/pix
vd  $HOME/vids
ml  $HOME/mail

M .config/shell/bm-files => .config/shell/bm-files +15 -22
@@ 1,23 1,16 @@
# These files automatically update when edited/saved in vim:
# Bookmarked files for shell shortcuts

# 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
cfx	${XDG_CONFIG_HOME:-$HOME/.config}/x11/xresources	# Colors, themes and variables for X11
cfb	~/.local/src/dwmblocks/config.h				# dwmblocks: the status bar for dwm


# 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
cfmb	${XDG_CONFIG_HOME:-$HOME/.config}/ncmpcpp/bindings	# ncmpcpp (music player) keybinds file
cfmc	${XDG_CONFIG_HOME:-$HOME/.config}/ncmpcpp/config	# ncmpcpp (music player) config
cfl	${XDG_CONFIG_HOME:-$HOME/.config}/lf/lfrc		# lf (file browser) config
cfL	${XDG_CONFIG_HOME:-$HOME/.config}/lf/scope		# lf's scope/preview file
cfX	${XDG_CONFIG_HOME:-$HOME/.config}/nsxiv/exec/key-handler	# nsxiv (image viewer) key/script handler
\ No newline at end of file
# keys	filename						description
bf	${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-files		# this file
bd	${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-dirs		# bookmarked directories
cfx	${XDG_CONFIG_HOME:-$HOME/.config}/x11/xresources	# X11 colors/themes
cfb	~/.local/src/dwmblocks/config.h				# dwmblocks config
cfv	${XDG_CONFIG_HOME:-$HOME/.config}/nvim/init.lua		# neovim config
cfk	$HOME/.mkshrc						# mksh config
cfp	$HOME/.profile						# login profile
cfm	${XDG_CONFIG_HOME:-$HOME/.config}/mutt/muttrc		# mutt config
cfn	${XDG_CONFIG_HOME:-$HOME/.config}/newsboat/config	# newsboat config
cfu	${XDG_CONFIG_HOME:-$HOME/.config}/newsboat/urls		# newsboat urls
cfmb	${XDG_CONFIG_HOME:-$HOME/.config}/ncmpcpp/bindings	# ncmpcpp keybinds
cfmc	${XDG_CONFIG_HOME:-$HOME/.config}/ncmpcpp/config	# ncmpcpp config
cfX	${XDG_CONFIG_HOME:-$HOME/.config}/nsxiv/exec/key-handler	# nsxiv key handler

D .config/shell/profile => .config/shell/profile +0 -80
@@ 1,80 0,0 @@
#!/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 TERMINAL="st"
export TERMINAL_PROG="st"
export BROWSER="librewolf"

# 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 XINITRC="$XDG_CONFIG_HOME/x11/xinitrc"
#export XAUTHORITY="$XDG_RUNTIME_DIR/Xauthority" # This line will break some DMs.
export NOTMUCH_CONFIG="$XDG_CONFIG_HOME/notmuch-config"
export GTK2_RC_FILES="$XDG_CONFIG_HOME/gtk-2.0/gtkrc-2.0"
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"

# Other program settings:
export DICS="/usr/share/stardict/dic/"
export SUDO_ASKPASS="$HOME/.local/bin/dmenupass"
export FZF_DEFAULT_OPTS="--layout=reverse --height 40%"
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="gtk2"        # Have QT use gtk2 theme.

# nnn file manager settings
export NNN_FIFO=/tmp/nnn.fifo
export NNN_PLUG='p:preview-tui;o:fzopen;d:diffs;v:imgview'
export NNN_TERMINAL="st"
export NNN_PREVIEWIMGPROG="ueberzug"
export NNN_PREVIEWDIR="$XDG_CACHE_HOME/nnn/previews"
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

[ ! -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 Xorg >/dev/null 2>&1 && exec startx "$XINITRC"

# Switch escape and caps if tty and no passwd required:
sudo -n loadkeys "$XDG_DATA_HOME/larbs/ttymaps.kmap" 2>/dev/null
\ No newline at end of file

M .config/systemd/user/history-browser-sync.service => .config/systemd/user/history-browser-sync.service +1 -1
@@ 3,4 3,4 @@ Description=Browser search history sync

[Service]
Type=oneshot
ExecStart=%h/.local/bin/history-sync-browsers
ExecStart=%h/.local/bin/history/history-sync-browsers

M .config/systemd/user/history-clipboard.service => .config/systemd/user/history-clipboard.service +1 -1
@@ 4,7 4,7 @@ After=graphical-session.target

[Service]
Type=simple
ExecStart=%h/.local/bin/history-clipboard-daemon
ExecStart=%h/.local/bin/history/history-clipboard-daemon
Restart=always
RestartSec=3


D .config/wallpapers/.gitkeep => .config/wallpapers/.gitkeep +0 -0
M .config/x11/xprofile => .config/x11/xprofile +4 -4
@@ 3,8 3,8 @@
# This file runs when a DM logs you into a graphical session.
# If you use startx/xinit like a Chad, this file will also be sourced.

# Add local bin to PATH for scripts
export PATH="$HOME/.local/bin:$HOME/.local/bin/statusbar:$PATH"
# Load environment variables from login profile
. "$HOME/.profile"

# Auto-detect device type and set DPI accordingly
DEVICE_TYPE_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/lazykris/device-type"


@@ 15,13 15,13 @@ else
fi
~/.screenlayout/main.sh	# Set up monitor layout
xrdb -merge ${XDG_CONFIG_HOME:-$HOME/.config}/x11/xresources	# Load base Xresources
setbg -s -c "$HOME/.local/share/wallpapers/winter-color-scheme.png" "$HOME/.local/share/wallpapers/d1e2f1-horizontal.png"	# solid bg + winter colorscheme
setbg -s -c "$HOME/.local/share/wallpapers/cs-winter-1920x960.webp" "$HOME/.local/share/wallpapers/p9blue-2560x1440.png"	# solid bg + plan9 colorscheme

# Start gnome-keyring-daemon and export its environment variables
eval $(gnome-keyring-daemon --start --components=pkcs11,secrets,ssh)
export SSH_AUTH_SOCK

autostart="mpd picom dunst unclutter pipewire wireplumber remapd conky"
autostart="mpd picom dunst unclutter pipewire wireplumber conky"

for program in $autostart; do
	pgrep -x "$program" >/dev/null 2>&1 || "$program" &

R .local/bin/anki-cli => .local/bin/academic/anki-cli +0 -0
R .local/bin/compile-all-masters.py => .local/bin/academic/compile-all-masters.py +0 -0
R .local/bin/countdown.py => .local/bin/academic/countdown.py +0 -0
R .local/bin/courses.py => .local/bin/academic/courses.py +0 -0
R .local/bin/lectures.py => .local/bin/academic/lectures.py +0 -0
R .local/bin/math-utils.py => .local/bin/academic/math-utils.py +0 -0
R .local/bin/questions => .local/bin/academic/questions +0 -0
R .local/bin/rofi-courses.py => .local/bin/academic/rofi-courses.py +0 -0
R .local/bin/rofi-lectures-view.py => .local/bin/academic/rofi-lectures-view.py +0 -0
R .local/bin/rofi-lectures.py => .local/bin/academic/rofi-lectures.py +0 -0
A .local/bin/academic/words-drill => .local/bin/academic/words-drill +264 -0
@@ 0,0 1,264 @@
#!/usr/bin/env python3
"""
words-drill -- generate a personalized typing drill HTML page from weak bigrams/trigrams.

Usage:
  words-drill [--name NAME] [--corpus PATH] [--count N] [--out PATH] BIGRAM [BIGRAM ...]
  words-drill --stdin [other flags]   # read bigrams one per line from stdin

Bigrams are 2- or 3-character sequences (e.g. th, qu, tio). For symbol
bigrams (=>, ;;) pass --corpus pointing at a code wordlist.
"""

import argparse
import os
import random
import re
import sys
from datetime import date
from pathlib import Path

# ---------------------------------------------------------------------------
# Paths
# ---------------------------------------------------------------------------

WORDS_ROOT = Path("/home/krisyotam/dev/words")
DEFAULT_CORPUS = WORDS_ROOT / "sources/google-10000-english/google-10000-english-usa-no-swears.txt"
DRILLS_DIR = WORDS_ROOT / "drills"

# ---------------------------------------------------------------------------
# HTML helpers (match build.py style exactly)
# ---------------------------------------------------------------------------

HEAD_TEMPLATE = """\
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="author" content="Kris Yotam">
  <link rel="stylesheet" href="/words/style.css">
  <title>{title} -- Kris Yotam's Word Lists</title>
</head>
<body>
"""

FOOT = """\
</body>
</html>
"""


def render_drill_page(name: str, words: list, bigrams: list) -> str:
    bigram_list = ", ".join(bigrams)
    word_count = len(words)
    body = "\n".join(words)
    return (
        HEAD_TEMPLATE.format(title=name)
        + '<div class="text"><div class="left">\n'
        + '<a class="back-link" href="/words/drills/">&larr; back to drills</a>\n'
        + f"<h1>{name}</h1>\n"
        + f'<p class="wordlist-meta">{word_count:,} words &mdash; bigrams: {bigram_list}</p>\n'
        + f'<pre class="wordlist">{body}</pre>\n'
        + "</div></div>\n"
        + FOOT
    )


def render_drills_index(drill_files: list) -> str:
    """Render drills/index.html from a list of (stem, mtime) pairs, sorted by mtime desc."""
    listing_items = ""
    for stem, _mtime in drill_files:
        title = stem.replace("-", " ").title()
        listing_items += (
            '<div class="listing"><div class="left"><dl>'
            f'<dt><a href="{stem}.html">{title}</a></dt>'
            "</dl></div></div>\n"
        )

    return (
        HEAD_TEMPLATE.format(title="Drills")
        + '<div class="text"><div class="left">\n'
        + '<a class="back-link" href="/words/">&larr; back to word lists</a>\n'
        + "<h1>Drills</h1>\n"
        + "</div></div>\n"
        + listing_items
        + FOOT
    )


def render_drills_placeholder() -> str:
    return (
        HEAD_TEMPLATE.format(title="Drills")
        + '<div class="text"><div class="left">\n'
        + '<a class="back-link" href="/words/">&larr; back to word lists</a>\n'
        + "<h1>Drills</h1>\n"
        + '<p class="coming-soon">Coming soon -- LLM-generated symbol drills.</p>\n'
        + "</div></div>\n"
        + FOOT
    )


# ---------------------------------------------------------------------------
# Core logic
# ---------------------------------------------------------------------------

def load_corpus(path: Path) -> list:
    if not path.exists():
        print(f"error: corpus file not found: {path}", file=sys.stderr)
        sys.exit(1)
    lines = path.read_text(encoding="utf-8").splitlines()
    return [l.strip() for l in lines if l.strip()]


def find_words_for_bigram(corpus: list, bigram: str) -> list:
    """Return all corpus words that contain the given bigram."""
    return [w for w in corpus if bigram in w]


def build_drill_wordlist(corpus: list, bigrams: list, count: int, seed: int) -> tuple:
    """
    Distribute `count` words across bigrams proportionally.
    Returns (final_word_list, counts_dict).
    counts_dict maps each bigram to how many words were found/used.
    """
    per_bigram = count // len(bigrams) if bigrams else 0
    remainder = count - per_bigram * len(bigrams)

    rng = random.Random(seed)

    all_words = []
    counts = {}

    for i, bigram in enumerate(bigrams):
        matches = find_words_for_bigram(corpus, bigram)
        quota = per_bigram + (1 if i < remainder else 0)
        if not matches:
            counts[bigram] = 0
            continue
        rng.shuffle(matches)
        selected = matches[:quota]
        counts[bigram] = len(selected)
        all_words.extend(selected)

    # Shuffle final combined list with same rng for reproducibility
    rng.shuffle(all_words)
    return all_words, counts


def rebuild_drills_index() -> None:
    """Scan drills/*.html (skip index.html), sort by mtime desc, write index."""
    html_files = [
        p for p in DRILLS_DIR.glob("*.html")
        if p.name != "index.html"
    ]
    if not html_files:
        DRILLS_DIR.joinpath("index.html").write_text(render_drills_placeholder(), encoding="utf-8")
        return

    drill_files = sorted(
        [(p.stem, p.stat().st_mtime) for p in html_files],
        key=lambda x: x[1],
        reverse=True,
    )
    DRILLS_DIR.joinpath("index.html").write_text(
        render_drills_index(drill_files), encoding="utf-8"
    )


# ---------------------------------------------------------------------------
# CLI
# ---------------------------------------------------------------------------

def main():
    parser = argparse.ArgumentParser(
        description="Generate a personalized typing drill HTML page from weak bigrams.",
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    parser.add_argument(
        "bigrams",
        nargs="*",
        metavar="BIGRAM",
        help="2- or 3-character sequences to drill (e.g. th qu tio)",
    )
    parser.add_argument(
        "--stdin",
        action="store_true",
        help="Read bigrams one per line from stdin instead of positional args",
    )
    parser.add_argument(
        "--name",
        default=None,
        help="Name for the drill (default: weakness-YYYY-MM-DD)",
    )
    parser.add_argument(
        "--corpus",
        default=str(DEFAULT_CORPUS),
        help="Path to corpus wordlist file (default: google-10000-english-usa-no-swears.txt)",
    )
    parser.add_argument(
        "--count",
        type=int,
        default=200,
        help="Total words in output drill (default: 200)",
    )
    parser.add_argument(
        "--out",
        default=None,
        help="Output HTML file path (default: drills/<name>.html)",
    )

    args = parser.parse_args()

    # Collect bigrams
    if args.stdin:
        bigrams = [line.strip() for line in sys.stdin if line.strip()]
    else:
        bigrams = args.bigrams

    if not bigrams:
        print(
            "usage: words-drill [--name NAME] [--corpus PATH] [--count N] [--out PATH] BIGRAM [BIGRAM ...]\n"
            "       words-drill --stdin [other flags]\n"
            "error: no bigrams specified",
            file=sys.stderr,
        )
        sys.exit(2)

    # Resolve name
    today = date.today().isoformat()
    name = args.name if args.name else f"weakness-{today}"

    # Resolve output path
    DRILLS_DIR.mkdir(parents=True, exist_ok=True)
    out_path = Path(args.out) if args.out else DRILLS_DIR / f"{name}.html"

    # Load corpus
    corpus_path = Path(args.corpus)
    corpus = load_corpus(corpus_path)

    # Derive seed from bigrams + name for reproducibility
    seed_str = name + "".join(sorted(bigrams))
    seed = int.from_bytes(seed_str.encode(), "little") % (2**32)

    # Build drill
    words, counts = build_drill_wordlist(corpus, bigrams, args.count, seed)

    # Write HTML
    html = render_drill_page(name, words, bigrams)
    out_path.write_text(html, encoding="utf-8")

    # Rebuild drills index
    rebuild_drills_index()

    # Report
    total_written = len(words)
    detail = ", ".join(f"{b}: {counts.get(b, 0)}" for b in bigrams)
    print(out_path)
    print(
        f"wrote {total_written}/{args.count} words across {len(bigrams)} bigrams ({detail})"
    )


if __name__ == "__main__":
    main()

R .local/bin/README.md => .local/bin/cron/README.md +0 -0
R .local/bin/checkup => .local/bin/cron/checkup +0 -0
D .local/bin/cron/checkup.sh => .local/bin/cron/checkup.sh +0 -0
D .local/bin/cron/crongtog.sh => .local/bin/cron/crongtog.sh +0 -0
R .local/bin/crontog => .local/bin/cron/crontog +0 -1
@@ 4,4 4,3 @@
# 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.")


A .local/bin/cron/cve => .local/bin/cron/cve +537 -0
@@ 0,0 1,537 @@
#!/bin/sh
# cve -- CVE notification daemon for dunst + claude triage + email alerting
# Install: ln -sf ~/dev/omniscient/scripts/cve ~/.local/bin/cve
#
# Two cron modes:
#   0 */1 * * * ~/.local/bin/cve --deep     # hourly: claude triage + email on affected
#   0 */6 * * * ~/.local/bin/cve --scan     # every 6h: dunst notifications only
#
# Manual:
#   cve                    # interactive: dunst + claude triage
#   cve --deep             # hourly mode: claude triage, email if affected, no dunst
#   cve --scan             # 6h mode: dunst notifications only, no claude
#   cve --list             # print recent CVEs to stdout
#   cve --triage           # show all triage results
#   cve --history          # show notification log

# no set -e: jq may exit non-zero on individual CVEs with bad data

# ============================================================================
# CONFIG
# ============================================================================

CVE_DIR="$HOME/.local/share/cve"
CVE_DB="$CVE_DIR/seen.json"
CVE_LOG="$CVE_DIR/cve.log"
CVE_TRIAGE="$CVE_DIR/triage"
PACKAGES_CACHE="$CVE_DIR/packages.txt"
KERNEL_VER="$(uname -r)"
EMAIL_TO="krisyotam@gmail.com"

# how many hours back to check (overridden per mode below)
HOURS_BACK=4

# severity filter: LOW, MEDIUM, HIGH, CRITICAL
MIN_SEVERITY="HIGH"

# NVD API (no key needed for low-rate, but add one for higher limits)
# Get a key at https://nvd.nist.gov/developers/request-an-api-key
NVD_API_KEY=""
NVD_BASE="https://services.nvd.nist.gov/rest/json/cves/2.0"

# CISA KEV (Known Exploited Vulnerabilities) -- actively exploited in the wild
CISA_KEV="https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json"

# ============================================================================
# INIT
# ============================================================================

mkdir -p "$CVE_DIR" "$CVE_TRIAGE"

# initialize seen db if missing
if [ ! -f "$CVE_DB" ]; then
    echo '{"seen":[],"triaged":[]}' > "$CVE_DB"
fi

log() { printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M')" "$1" >> "$CVE_LOG"; }
notify() {
    urgency="${2:-normal}"
    dunstify -u "$urgency" -t 15000 -a "CVE Monitor" "CVE Alert" "$1" 2>/dev/null || true
}

# ============================================================================
# DEPENDENCY INVENTORY
# ============================================================================

DEPS_CACHE="$CVE_DIR/deps.txt"
DEPS_NAMES="$CVE_DIR/deps-names.txt"
DEPS_SCRIPT="$HOME/dev/omniscient/scripts/deps"

# populate deps cache once per run
refresh_deps() {
    if [ -x "$DEPS_SCRIPT" ]; then
        "$DEPS_SCRIPT" > "$DEPS_CACHE" 2>/dev/null
    else
        pacman -Q 2>/dev/null | awk '{printf "%s\t%s\tpacman\n", $1, $2}' > "$DEPS_CACHE"
    fi
    # extract just lowercased names for fast matching
    awk -F'\t' '{print tolower($1)}' "$DEPS_CACHE" | sort -u > "$DEPS_NAMES"
}

# check if a CVE's affected products match any local dep
# sets MATCHED_PKGS with "name version (source)" lines
# returns 0 if match found, 1 otherwise
matches_local() {
    _ml_vuln="$1"
    MATCHED_PKGS=""

    # extract CPE product names from configurations
    _ml_products=$(printf '%s' "$_ml_vuln" | jq -r '
        [.cve.configurations[]?.nodes[]?.cpeMatch[]?.criteria // empty] |
        map(split(":") | if length > 4 then .[3] + "\n" + .[4] else empty end) |
        unique | join("\n")
    ' 2>/dev/null | tr '[:upper:]' '[:lower:]' | grep -v '^$' | sort -u)

    if [ -n "$_ml_products" ]; then
        _ml_matches=""
        echo "$_ml_products" | while IFS= read -r prod; do
            [ -z "$prod" ] && continue
            grep -iF "$prod" "$DEPS_CACHE" 2>/dev/null | awk -F'\t' '{printf "%s %s (%s)\n", $1, $2, $3}'
        done | sort -u > "$CVE_DIR/.matched_tmp" 2>/dev/null

        if [ -s "$CVE_DIR/.matched_tmp" ]; then
            MATCHED_PKGS=$(cat "$CVE_DIR/.matched_tmp")
            rm -f "$CVE_DIR/.matched_tmp"
            return 0
        fi
        rm -f "$CVE_DIR/.matched_tmp"
    fi

    return 1
}

# legacy: still needed for claude triage prompt
refresh_packages() {
    cp "$DEPS_CACHE" "$PACKAGES_CACHE" 2>/dev/null || refresh_deps
}

# ============================================================================
# CVE FETCHING
# ============================================================================

fetch_nvd_to_file() {
    outfile="$1"
    now_utc=$(date -u '+%Y-%m-%dT%H:%M:%S.000')
    past_utc=$(date -u -d "-${HOURS_BACK} hours" '+%Y-%m-%dT%H:%M:%S.000' 2>/dev/null || \
               date -u -v-${HOURS_BACK}H '+%Y-%m-%dT%H:%M:%S.000' 2>/dev/null || \
               echo "")

    [ -z "$past_utc" ] && { log "Cannot compute date offset"; return 1; }

    url="${NVD_BASE}?pubStartDate=${past_utc}&pubEndDate=${now_utc}"

    # fetch to temp, sanitize through python (NVD returns invalid escapes), write to outfile
    fetch_tmp=$(mktemp "$CVE_DIR/fetch.XXXXXX")
    if [ -n "$NVD_API_KEY" ]; then
        curl -sf --max-time 30 -H "apiKey: $NVD_API_KEY" "$url" -o "$fetch_tmp" 2>/dev/null || { log "NVD fetch failed"; rm -f "$fetch_tmp"; return 1; }
    else
        curl -sf --max-time 30 "$url" -o "$fetch_tmp" 2>/dev/null || { log "NVD fetch failed"; rm -f "$fetch_tmp"; return 1; }
    fi

    # sanitize JSON (NVD sometimes has invalid escape sequences)
    python3 -c "import sys,json; json.dump(json.load(open(sys.argv[1])),open(sys.argv[2],'w'))" "$fetch_tmp" "$outfile" 2>/dev/null || {
        # fallback: just copy raw and hope jq handles it
        cp "$fetch_tmp" "$outfile"
    }
    rm -f "$fetch_tmp"
}

fetch_cisa_kev_to_file() {
    outfile="$1"
    fetch_tmp=$(mktemp "$CVE_DIR/kevfetch.XXXXXX")
    curl -sf --max-time 60 "$CISA_KEV" -o "$fetch_tmp" 2>/dev/null || { log "CISA KEV fetch failed"; rm -f "$fetch_tmp"; return 1; }
    python3 -c "
import sys,json
with open(sys.argv[1]) as f:
    raw = f.read()
# strip control chars that break jq
clean = ''.join(c if ord(c) >= 32 or c in '\n\r\t' else ' ' for c in raw)
d = json.loads(clean)
with open(sys.argv[2],'w') as out:
    json.dump(d, out, ensure_ascii=True)
" "$fetch_tmp" "$outfile" 2>/dev/null || cp "$fetch_tmp" "$outfile"
    rm -f "$fetch_tmp"
}

# ============================================================================
# PARSE + FILTER
# ============================================================================

parse_nvd() {
    raw="$1"
    [ -z "$raw" ] && return

    echo "$raw" | jq -r '
        .vulnerabilities[]? |
        {
            id: .cve.id,
            description: (.cve.descriptions[]? | select(.lang == "en") | .value),
            severity: (.cve.metrics.cvssMetricV31[]?.cvssData.baseSeverity // .cve.metrics.cvssMetricV30[]?.cvssData.baseSeverity // "UNKNOWN"),
            score: (.cve.metrics.cvssMetricV31[]?.cvssData.baseScore // .cve.metrics.cvssMetricV30[]?.cvssData.baseScore // 0),
            published: .cve.published,
            references: [.cve.references[]?.url] | join(" ")
        }
    ' 2>/dev/null || true
}

parse_cisa_new() {
    raw="$1"
    today=$(date '+%Y-%m-%d')
    yesterday=$(date -d '-1 day' '+%Y-%m-%d' 2>/dev/null || date -v-1d '+%Y-%m-%d' 2>/dev/null || echo "$today")

    echo "$raw" | jq -r --arg today "$today" --arg yesterday "$yesterday" '
        .vulnerabilities[]? |
        select(.dateAdded >= $yesterday) |
        {
            id: .cveID,
            description: .shortDescription,
            severity: "CRITICAL-KEV",
            score: 10,
            published: .dateAdded,
            references: .notes
        }
    ' 2>/dev/null || true
}

is_seen() {
    _is_id="$1"
    jq -r --arg id "$_is_id" '.seen[] | select(. == $id)' "$CVE_DB" 2>/dev/null | grep -q .
}

mark_seen() {
    _mk_id="$1"
    _mk_tmp=$(mktemp "$CVE_DIR/tmp.XXXXXX")
    jq --arg id "$_mk_id" '.seen += [$id] | .seen |= unique' "$CVE_DB" > "$_mk_tmp" && mv "$_mk_tmp" "$CVE_DB"
}

# ============================================================================
# TRIAGE WITH CLAUDE
# ============================================================================

triage_cve() {
    cveid="$1"
    desc="$2"
    severity="$3"
    score="$4"

    triage_file="$CVE_TRIAGE/${cveid}.json"
    [ -f "$triage_file" ] && return 0

    refresh_packages

    prompt="You are a security triage assistant. Analyze this CVE against the system inventory below.

CVE: $cveid
Severity: $severity (Score: $score)
Description: $desc

SYSTEM INVENTORY:
$(cat "$PACKAGES_CACHE")

TASK:
1. Determine if this CVE affects ANY package, service, kernel version, or language runtime on this system.
2. If YES: respond with EXACTLY this JSON (no markdown, no backticks):
   {\"affected\": true, \"package\": \"<name>\", \"installed_version\": \"<ver>\", \"action\": \"<what to do>\", \"urgency\": \"immediate|soon|monitor\"}
3. If NO: respond with EXACTLY this JSON:
   {\"affected\": false, \"reason\": \"<why not>\"}

Be conservative -- if uncertain, say affected. Better a false positive than a missed vuln."

    result=$(echo "$prompt" | claude -p --model haiku 2>/dev/null) || { log "Claude triage failed for $cveid"; return 1; }

    # extract JSON from response (claude might wrap it)
    json=$(echo "$result" | grep -o '{.*}' | head -1)
    [ -z "$json" ] && { log "No JSON in triage response for $cveid"; return 1; }

    echo "$json" > "$triage_file"

    # check if affected
    affected=$(echo "$json" | jq -r '.affected' 2>/dev/null)
    if [ "$affected" = "true" ]; then
        pkg=$(echo "$json" | jq -r '.package // "unknown"' 2>/dev/null)
        action=$(echo "$json" | jq -r '.action // "investigate"' 2>/dev/null)
        urgency=$(echo "$json" | jq -r '.urgency // "monitor"' 2>/dev/null)

        # notify via dunst with critical urgency
        notify "$cveid AFFECTS $pkg -- $action" "critical"
        log "AFFECTED: $cveid -> $pkg ($urgency)"

        # email alert
        email_body="CVE ALERT: $cveid affects your system

Severity: $severity (Score: $score)
Package: $pkg
Action: $action
Urgency: $urgency

Description: $desc

Triage output:
$json

-- CVE Monitor (omniscient)"

        echo "$email_body" | email -s "CVE ALERT: $cveid affects $pkg [$urgency]" "$EMAIL_TO" 2>/dev/null || log "Email failed for $cveid"

        return 0
    fi

    log "NOT AFFECTED: $cveid"
    return 0
}

# ============================================================================
# MAIN MODES
# ============================================================================

# mode: "deep" = claude triage + email (hourly cron)
#       "scan" = dunst only (6h cron)
#       "interactive" = both dunst + claude (manual run)
do_check() {
    mode="${1:-interactive}"

    # set time window per mode (with overlap buffer)
    case "$mode" in
        deep)        HOURS_BACK=2;  use_dunst=false; use_claude=true ;;
        scan)        HOURS_BACK=8;  use_dunst=true;  use_claude=false ;;
        interactive) HOURS_BACK=4;  use_dunst=true;  use_claude=true ;;
    esac

    log "Starting CVE check (mode=$mode, hours_back=$HOURS_BACK, min_severity=$MIN_SEVERITY)"

    # build local deps inventory for matching
    refresh_deps
    dep_count=$(wc -l < "$DEPS_NAMES" | tr -d ' ')
    log "Loaded $dep_count local deps for matching"

    new_count=0
    notify_count=0
    nvd_tmp=$(mktemp "$CVE_DIR/nvd.XXXXXX")
    nvd_raw_file=$(mktemp "$CVE_DIR/raw.XXXXXX")

    # fetch from NVD directly to file (too large for shell variables)
    fetch_nvd_to_file "$nvd_raw_file"

    if [ -s "$nvd_raw_file" ] && jq -e '.vulnerabilities' "$nvd_raw_file" >/dev/null 2>&1; then
        total=$(jq '.totalResults // 0' "$nvd_raw_file" 2>/dev/null)
        log "NVD returned $total CVEs"

        # pre-filter: only CRITICAL severity from NVD
        jq -c '
            .vulnerabilities[]? |
            . as $v |
            ($v.cve.metrics.cvssMetricV40[0]?.cvssData.baseSeverity //
             $v.cve.metrics.cvssMetricV31[0]?.cvssData.baseSeverity //
             $v.cve.metrics.cvssMetricV30[0]?.cvssData.baseSeverity //
             "UNKNOWN") as $sev |
            if ($sev == "CRITICAL" or $sev == "HIGH") then $v
            else empty end
        ' "$nvd_raw_file" 2>/dev/null > "$nvd_tmp"

        filtered=$(wc -l < "$nvd_tmp" | tr -d ' ')
        log "After severity filter: $filtered CVEs (HIGH+CRITICAL)"

        while IFS= read -r vuln; do
            cveid=$(printf '%s' "$vuln" | jq -r '.cve.id' 2>/dev/null)
            [ -z "$cveid" ] || [ "$cveid" = "null" ] && continue

            if is_seen "$cveid"; then
                continue
            fi

            severity=$(printf '%s' "$vuln" | jq -r '(.cve.metrics.cvssMetricV40[0]?.cvssData.baseSeverity // .cve.metrics.cvssMetricV31[0]?.cvssData.baseSeverity // .cve.metrics.cvssMetricV30[0]?.cvssData.baseSeverity // "UNKNOWN")' 2>/dev/null)
            score=$(printf '%s' "$vuln" | jq -r '(.cve.metrics.cvssMetricV40[0]?.cvssData.baseScore // .cve.metrics.cvssMetricV31[0]?.cvssData.baseScore // .cve.metrics.cvssMetricV30[0]?.cvssData.baseScore // 0)' 2>/dev/null)
            desc=$(printf '%s' "$vuln" | jq -r '[.cve.descriptions[]? | select(.lang == "en") | .value][0] // ""' 2>/dev/null)

            mark_seen "$cveid"
            new_count=$((new_count + 1))

            # check if this CVE affects local system
            is_local=false
            if matches_local "$vuln"; then
                is_local=true
            fi

            short_desc=$(printf '%.120s' "$desc")

            # build affected line from matched packages
            affected_line=""
            if [ "$is_local" = "true" ] && [ -n "$MATCHED_PKGS" ]; then
                affected_line=$(echo "$MATCHED_PKGS" | tr '\n' ', ' | sed 's/, $//')
            fi

            # notify logic: only CRITICAL or locally-matching CVEs
            if [ "$severity" = "CRITICAL" ] && [ "$is_local" = "true" ]; then
                if [ "$use_dunst" = "true" ]; then
                    notify "LOCAL: $cveid ($score) CRITICAL\n$short_desc\naffected: $affected_line" "critical"
                fi
                if [ "$use_claude" = "true" ]; then
                    triage_cve "$cveid" "$desc" "$severity" "$score"
                fi
                notify_count=$((notify_count + 1))
                log "CRITICAL+LOCAL: $cveid ($score) [$affected_line]"
            elif [ "$is_local" = "true" ]; then
                if [ "$use_dunst" = "true" ]; then
                    notify "LOCAL: $cveid ($score) $severity\n$short_desc\naffected: $affected_line" "normal"
                fi
                if [ "$use_claude" = "true" ]; then
                    triage_cve "$cveid" "$desc" "$severity" "$score"
                fi
                notify_count=$((notify_count + 1))
                log "LOCAL MATCH: $cveid ($severity $score) [$affected_line]"
            elif [ "$severity" = "CRITICAL" ]; then
                # critical but not local: dunst only in interactive, skip in scan
                if [ "$mode" = "interactive" ] && [ "$use_dunst" = "true" ]; then
                    notify "$cveid ($score) CRITICAL\n$short_desc" "low"
                    notify_count=$((notify_count + 1))
                fi
                log "CRITICAL (not local): $cveid ($score)"
            else
                # HIGH but not local: silent, just log
                log "SKIPPED (not local): $cveid ($severity $score)"
            fi
        done < "$nvd_tmp"
    fi

    rm -f "$nvd_tmp" "$nvd_raw_file"

    # CISA KEV: actively exploited in the wild, always notify + triage
    kev_raw_file=$(mktemp "$CVE_DIR/kevraw.XXXXXX")
    fetch_cisa_kev_to_file "$kev_raw_file"
    if [ -s "$kev_raw_file" ] && jq -e '.vulnerabilities' "$kev_raw_file" >/dev/null 2>&1; then
        today=$(date '+%Y-%m-%d')
        yesterday=$(date -d '-1 day' '+%Y-%m-%d' 2>/dev/null || echo "$today")

        kev_tmp=$(mktemp "$CVE_DIR/kev.XXXXXX")
        jq -c --arg yd "$yesterday" '.vulnerabilities[]? | select(.dateAdded >= $yd)' "$kev_raw_file" 2>/dev/null > "$kev_tmp"

        while IFS= read -r vuln; do
            cveid=$(printf '%s' "$vuln" | jq -r '.cveID' 2>/dev/null)
            [ -z "$cveid" ] || [ "$cveid" = "null" ] && continue

            if is_seen "KEV-$cveid"; then
                continue
            fi

            desc=$(printf '%s' "$vuln" | jq -r '.shortDescription' 2>/dev/null)
            kev_vendor=$(printf '%s' "$vuln" | jq -r '.vendorProject // ""' 2>/dev/null | tr '[:upper:]' '[:lower:]')
            kev_product=$(printf '%s' "$vuln" | jq -r '.product // ""' 2>/dev/null | tr '[:upper:]' '[:lower:]')
            mark_seen "KEV-$cveid"

            short_desc=$(printf '%.120s' "$desc")

            # match KEV vendor/product against local deps
            kev_affected=""
            for _kp in $kev_vendor $kev_product; do
                [ -z "$_kp" ] && continue
                _kp_hit=$(grep -iF "$_kp" "$DEPS_CACHE" 2>/dev/null | awk -F'\t' '{printf "%s %s (%s)\n", $1, $2, $3}' | sort -u)
                [ -n "$_kp_hit" ] && kev_affected="${kev_affected:+$kev_affected, }$(echo "$_kp_hit" | tr '\n' ', ' | sed 's/, $//')"
            done

            if [ -n "$kev_affected" ]; then
                notify "CISA KEV: $cveid (ACTIVELY EXPLOITED)\n$short_desc\naffected: $kev_affected" "critical"
            else
                notify "CISA KEV: $cveid (ACTIVELY EXPLOITED)\n$short_desc\naffected: none detected" "critical"
            fi
            log "CISA KEV: $cveid [${kev_affected:-no local match}]"
            notify_count=$((notify_count + 1))

            triage_cve "$cveid" "$desc" "CRITICAL-KEV" "10"
        done < "$kev_tmp"
        rm -f "$kev_tmp"
    fi
    rm -f "$kev_raw_file"

    log "Check complete ($mode). Processed: $new_count, Notified: $notify_count"
}

do_list() {
    echo "=== Recent CVEs (last ${HOURS_BACK}h, severity >= $MIN_SEVERITY) ==="
    list_tmp=$(mktemp "$CVE_DIR/list.XXXXXX")
    fetch_nvd_to_file "$list_tmp"
    if [ -s "$list_tmp" ]; then
        jq -r '
            .vulnerabilities[]? |
            (.cve.metrics.cvssMetricV40[0]?.cvssData.baseSeverity // .cve.metrics.cvssMetricV31[0]?.cvssData.baseSeverity // .cve.metrics.cvssMetricV30[0]?.cvssData.baseSeverity // "?") as $sev |
            (.cve.metrics.cvssMetricV40[0]?.cvssData.baseScore // .cve.metrics.cvssMetricV31[0]?.cvssData.baseScore // .cve.metrics.cvssMetricV30[0]?.cvssData.baseScore // "?") as $score |
            "\(.cve.id) [\($sev)] \($score) - \([.cve.descriptions[]? | select(.lang == "en") | .value][0][:100] // "")"
        ' "$list_tmp" 2>/dev/null | sort -t'[' -k2 -r
    fi
    rm -f "$list_tmp"
    echo
    echo "=== Triaged (affects this system) ==="
    for f in "$CVE_TRIAGE"/*.json; do
        [ -f "$f" ] || continue
        affected=$(jq -r '.affected' "$f" 2>/dev/null)
        if [ "$affected" = "true" ]; then
            cveid=$(basename "$f" .json)
            pkg=$(jq -r '.package' "$f" 2>/dev/null)
            urgency=$(jq -r '.urgency' "$f" 2>/dev/null)
            printf '%s -> %s [%s]\n' "$cveid" "$pkg" "$urgency"
        fi
    done
}

do_triage() {
    echo "[*] Running triage on all unseen CVEs..."
    for f in "$CVE_TRIAGE"/*.json; do
        [ -f "$f" ] || continue
        cveid=$(basename "$f" .json)
        echo "  Triaged: $cveid -> $(jq -r 'if .affected then "AFFECTED: \(.package)" else "safe" end' "$f" 2>/dev/null)"
    done
}

do_history() {
    if [ -f "$CVE_LOG" ]; then
        tail -50 "$CVE_LOG"
    else
        echo "No history yet."
    fi
}

show_help() {
    cat << 'HELP'
cve -- CVE notification daemon

Usage:
  cve              Interactive: dunst notifications + claude triage + email
  cve --deep       Hourly mode: claude triage only, email if affected (no dunst)
  cve --scan       6-hour mode: dunst notifications only (no claude, saves tokens)
  cve --list       Print recent CVEs and triage results
  cve --triage     Show all triage results
  cve --history    Show notification log
  cve --help       This help

Cron setup:
  0 */1 * * * ~/.local/bin/cve --deep      # hourly: claude triage + email
  0 */6 * * * ~/.local/bin/cve --scan      # every 6h: dunst notifications

Config: edit variables at top of this script
Data:   ~/.local/share/cve/
HELP
}

# ============================================================================
# DISPATCH
# ============================================================================

case "${1:-}" in
    --deep)    do_check deep ;;
    --scan)    do_check scan ;;
    --list)    do_list ;;
    --triage)  do_triage ;;
    --history) do_history ;;
    --help|-h) show_help ;;
    "")        do_check interactive ;;
    *)         echo "Unknown option: $1"; show_help; exit 1 ;;
esac

R .local/bin/newsup => .local/bin/cron/newsup +0 -0
D .local/bin/cron/newsup.sh => .local/bin/cron/newsup.sh +0 -0
A .local/bin/dev/agenticstats => .local/bin/dev/agenticstats +410 -0
@@ 0,0 1,410 @@
#!/usr/bin/env python3
"""agenticstats — Weekly-style developer activity report."""

import argparse
import json
import re
import subprocess
import sys
from datetime import datetime, timedelta, timezone
from pathlib import Path

DEV_DIR = Path.home() / "dev"
CLAUDE_DIR = Path.home() / ".claude" / "projects" / "-home-krisyotam"
USER = "Kris Yotam"


# ── time ranges ──────────────────────────────────────────────────────

def get_range(mode):
    """Return (start_dt, end_dt, label) for the given mode."""
    now = datetime.now(timezone.utc)
    today = now.replace(hour=0, minute=0, second=0, microsecond=0)

    if mode == "d":
        start = today
        label = now.strftime("%b %d, %Y")
        return start, now, f"Today — {label}"
    elif mode == "w":
        weekday = today.weekday()
        start = today - timedelta(days=weekday)
        end_day = start + timedelta(days=6)
        if start.month == end_day.month:
            label = f"{start.strftime('%b %d')}–{end_day.strftime('%d, %Y')}"
        else:
            label = f"{start.strftime('%b %d')} – {end_day.strftime('%b %d, %Y')}"
        return start, now, f"Week of {start.strftime('%b %d')}"
    elif mode == "m":
        start = today.replace(day=1)
        label = now.strftime("%B %Y")
        return start, now, label
    elif mode == "y":
        start = today.replace(month=1, day=1)
        label = now.strftime("%Y")
        return start, now, label
    elif mode == "a":
        start = datetime(2020, 1, 1, tzinfo=timezone.utc)
        return start, now, "All Time"


# ── git helpers ──────────────────────────────────────────────────────

def ts_fmt(dt):
    return dt.strftime("%Y-%m-%dT%H:%M:%SZ")


def find_repos(dev_dir):
    repos = []
    if not dev_dir.is_dir():
        return repos
    for d in sorted(dev_dir.iterdir()):
        if d.is_dir() and (d / ".git").exists():
            repos.append(d)
    return repos


def git_stats(repo, since, until):
    """Return (commits, insertions, deletions, is_solo) for a repo in range."""
    since_s, until_s = ts_fmt(since), ts_fmt(until)

    try:
        r = subprocess.run(
            ["git", "-C", str(repo), "log",
             f"--since={since_s}", f"--until={until_s}", "--oneline"],
            capture_output=True, text=True, timeout=10)
        commits = len(r.stdout.strip().splitlines()) if r.stdout.strip() else 0
    except Exception:
        return 0, 0, 0, True

    if commits == 0:
        return 0, 0, 0, True

    # LOC via numstat
    insertions = deletions = 0
    try:
        r = subprocess.run(
            ["git", "-C", str(repo), "log",
             f"--since={since_s}", f"--until={until_s}",
             "--pretty=tformat:", "--numstat"],
            capture_output=True, text=True, timeout=30)
        for line in r.stdout.strip().splitlines():
            parts = line.split()
            if len(parts) >= 2:
                try: insertions += int(parts[0])
                except ValueError: pass
                try: deletions += int(parts[1])
                except ValueError: pass
    except Exception:
        pass

    # Solo check
    try:
        r = subprocess.run(
            ["git", "-C", str(repo), "log",
             f"--since={since_s}", f"--until={until_s}", "--format=%aN"],
            capture_output=True, text=True, timeout=10)
        is_solo = len(set(r.stdout.strip().splitlines())) <= 1
    except Exception:
        is_solo = True

    return commits, insertions, deletions, is_solo


# ── AI session stats ─────────────────────────────────────────────────

def count_ai_sessions(claude_dir, since, until):
    cc = gpt = 0
    if not claude_dir.is_dir():
        return cc, gpt

    for f in claude_dir.glob("*.jsonl"):
        try:
            with open(f) as fh:
                first = fh.readline().strip()
                if not first:
                    continue
                data = json.loads(first)
                ts_str = data.get("timestamp")
                if not ts_str:
                    continue
                ts = datetime.fromisoformat(ts_str.replace("Z", "+00:00"))
                if since <= ts <= until:
                    if "[ChatGPT Import]" in data.get("summary", ""):
                        gpt += 1
                    else:
                        cc += 1
        except Exception:
            continue

    return cc, gpt


# ── per-commit stats for ship + top work ─────────────────────────────

def get_commit_stats(repos, since, until):
    """Return list of (insertions+deletions, files, msg, repo_name) per commit."""
    since_s, until_s = ts_fmt(since), ts_fmt(until)
    results = []

    for repo in repos:
        try:
            # Get each commit hash + message
            r = subprocess.run(
                ["git", "-C", str(repo), "log",
                 f"--since={since_s}", f"--until={until_s}",
                 "--format=%H\t%s"],
                capture_output=True, text=True, timeout=15)
            if not r.stdout.strip():
                continue

            for line in r.stdout.strip().splitlines():
                parts = line.split("\t", 1)
                if len(parts) < 2:
                    continue
                sha, msg = parts
                if msg.startswith("Merge"):
                    continue

                # Get numstat for this specific commit
                r2 = subprocess.run(
                    ["git", "-C", str(repo), "diff", "--numstat",
                     f"{sha}~1", sha],
                    capture_output=True, text=True, timeout=10)

                ins = dels = files = 0
                for sl in r2.stdout.strip().splitlines():
                    sp = sl.split()
                    if len(sp) >= 3:
                        files += 1
                        try: ins += int(sp[0])
                        except ValueError: pass
                        try: dels += int(sp[1])
                        except ValueError: pass

                results.append((ins + dels, files, ins, dels, msg, repo.name))
        except Exception:
            continue

    results.sort(key=lambda x: x[0], reverse=True)
    return results


# ── streak calculation ───────────────────────────────────────────────

def get_shipping_streak(repos):
    today = datetime.now(timezone.utc).date()
    day = today
    streak = 0

    while True:
        day_start = datetime(day.year, day.month, day.day, tzinfo=timezone.utc)
        day_end = day_start + timedelta(days=1)
        has_commit = False

        for repo in repos:
            try:
                r = subprocess.run(
                    ["git", "-C", str(repo), "log",
                     f"--since={ts_fmt(day_start)}", f"--until={ts_fmt(day_end)}",
                     "--oneline", "-1"],
                    capture_output=True, text=True, timeout=5)
                if r.stdout.strip():
                    has_commit = True
                    break
            except Exception:
                continue

        if has_commit:
            streak += 1
            day -= timedelta(days=1)
        else:
            break

    return streak


# ── formatting ───────────────────────────────────────────────────────

def fmt_loc(n):
    abs_n = abs(n)
    if abs_n >= 1_000_000:
        s = f"{abs_n/1_000_000:.1f}M"
    elif abs_n >= 1_000:
        s = f"{abs_n/1_000:.1f}k"
    else:
        s = str(abs_n)
    return s


def fmt_net(n):
    sign = "+" if n >= 0 else "-"
    return f"{sign}{fmt_loc(n)}"


GREY = "\033[38;5;240m"
WHITE = "\033[97m"
DIM = "\033[2m"
BOLD = "\033[1m"
RESET = "\033[0m"
FIRE = "\U0001f525"

_ansi_re = re.compile(r'\033\[[0-9;]*m')

def strip_ansi(s):
    return _ansi_re.sub('', s)

def box_line(text, width=78):
    vis_len = len(strip_ansi(text))
    padding = max(0, width - vis_len - 4)
    return f"  {GREY}\u2502{RESET} {text}{' ' * padding} {GREY}\u2502{RESET}"

def box_top(width=78):
    return f"  {GREY}\u250c{'\u2500' * (width - 2)}\u2510{RESET}"

def box_bottom(width=78):
    return f"  {GREY}\u2514{'\u2500' * (width - 2)}\u2518{RESET}"

def box_sep(width=78):
    return f"  {GREY}\u251c{'\u2500' * (width - 2)}\u2524{RESET}"


# ── rendering ────────────────────────────────────────────────────────

def render(mode, since, until, label):
    repos = find_repos(DEV_DIR)

    # Per-repo stats
    project_stats = []
    total_commits = total_ins = total_del = 0

    for repo in repos:
        commits, ins, dels, solo = git_stats(repo, since, until)
        if commits > 0:
            project_stats.append((repo.name, commits, ins, dels, solo))
            total_commits += commits
            total_ins += ins
            total_del += dels

    project_stats.sort(key=lambda x: x[1], reverse=True)
    active = len(project_stats)

    # AI sessions
    cc_sessions, gpt_sessions = count_ai_sessions(CLAUDE_DIR, since, until)
    total_sessions = cc_sessions + gpt_sessions

    # Streak
    streak = get_shipping_streak(repos)

    # Per-commit stats for ship + top work
    commit_stats = get_commit_stats(repos, since, until)

    # ── output ──
    period_map = {"d": "Day", "w": "Week", "m": "Month", "y": "Year", "a": "All Time"}
    ship_map = {"d": "SHIP OF THE DAY", "w": "SHIP OF THE WEEK", "m": "SHIP OF THE MONTH", "y": "SHIP OF THE YEAR", "a": "BIGGEST SHIP"}

    print()
    print(f"  {BOLD}{WHITE}\u2728 Your {period_map[mode]}: {USER} \u2014 {label}{RESET}")
    print()
    print(box_top())
    print(box_line(f"{BOLD}{WHITE}{USER.upper()} \u2014 {label}{RESET}"))
    print(box_sep())
    print(box_line(""))

    net = total_ins - total_del
    print(box_line(f"  {total_commits} commits across {active} projects"))
    print(box_line(f"  +{fmt_loc(total_ins)} LOC added \u00b7 {fmt_loc(total_del)} LOC deleted \u00b7 {fmt_net(net)} net"))

    if total_sessions > 0:
        parts = []
        if cc_sessions > 0:
            parts.append(f"CC: {cc_sessions}")
        if gpt_sessions > 0:
            parts.append(f"GPT: {gpt_sessions}")
        print(box_line(f"  {total_sessions} AI coding sessions ({', '.join(parts)})"))

    if streak > 0:
        print(box_line(f"  {streak}-day shipping streak {FIRE}"))

    print(box_line(""))
    print(box_sep())
    print(box_line(f"  {BOLD}PROJECTS{RESET}"))
    print(box_line(""))

    if project_stats:
        name_w = max(max(len(p[0]) for p in project_stats[:15]), 12)
        for name, commits, ins, dels, solo in project_stats[:15]:
            tag = "solo" if solo else "team"
            net_loc = ins - dels
            line = f"  {name:<{name_w}}  {commits:>4} commits   {fmt_net(net_loc):>9} LOC   {tag}"
            print(box_line(line))
    else:
        print(box_line("  No commits in this period."))

    print(box_line(""))
    print(box_sep())
    print(box_line(f"  {BOLD}{ship_map[mode]}{RESET}"))

    if commit_stats:
        total_loc, files, ins, dels, msg, repo_name = commit_stats[0]
        if len(msg) > 60:
            msg = msg[:57] + "..."
        print(box_line(f"  {msg}"))
        print(box_line(f"  \u2014 {fmt_loc(total_loc)} lines across {files} files ({repo_name})"))
    else:
        print(box_line("  Nothing shipped yet."))

    print(box_line(""))
    print(box_sep())
    print(box_line(f"  {BOLD}TOP WORK{RESET}"))

    if commit_stats:
        seen = set()
        count = 0
        for _, _, _, _, msg, rn in commit_stats:
            if msg in seen:
                continue
            seen.add(msg)
            if len(msg) > 66:
                msg = msg[:63] + "..."
            print(box_line(f"  \u2022 {msg}"))
            count += 1
            if count >= 5:
                break
    else:
        print(box_line("  No notable commits in this period."))

    print(box_line(""))
    print(box_sep())
    print(box_line(f"  {DIM}Powered by agenticstats{RESET}"))
    print(box_bottom())
    print()


# ── CLI ──────────────────────────────────────────────────────────────

def main():
    parser = argparse.ArgumentParser(
        prog="agenticstats",
        description="Developer activity report."
    )
    group = parser.add_mutually_exclusive_group()
    group.add_argument("-d", action="store_true", help="Daily (today)")
    group.add_argument("-w", action="store_true", help="Weekly (default)")
    group.add_argument("-m", action="store_true", help="Monthly")
    group.add_argument("-y", action="store_true", help="Yearly")
    group.add_argument("-a", action="store_true", help="All time")

    args = parser.parse_args()

    if args.d:     mode = "d"
    elif args.m:   mode = "m"
    elif args.y:   mode = "y"
    elif args.a:   mode = "a"
    else:          mode = "w"

    since, until, label = get_range(mode)
    render(mode, since, until, label)


if __name__ == "__main__":
    main()

A .local/bin/dev/deps => .local/bin/dev/deps +55 -0
@@ 0,0 1,55 @@
#!/bin/sh
# deps -- enumerate all installed software on this system
# outputs one line per dep: NAME<tab>VERSION<tab>SOURCE
# used by cve script for local matching

# pacman (system packages + AUR)
pacman -Q 2>/dev/null | while IFS=' ' read -r name ver; do
    printf '%s\t%s\tpacman\n' "$name" "$ver"
done

# python (pip)
pip list --format=freeze 2>/dev/null | while IFS='=' read -r name _ ver; do
    [ -n "$name" ] && printf '%s\t%s\tpip\n' "$name" "$ver"
done

# python (pipx)
pipx list --short 2>/dev/null | while read -r name ver _; do
    [ -n "$name" ] && printf '%s\t%s\tpipx\n' "$name" "$ver"
done

# node (npm global)
npm list -g --depth=0 --parseable --long 2>/dev/null | tail -n +2 | while IFS= read -r line; do
    pkg=$(basename "$line" | sed 's/@[^@]*$//')
    ver=$(basename "$line" | grep -o '@[^@]*$' | tr -d '@')
    [ -n "$pkg" ] && printf '%s\t%s\tnpm\n' "$pkg" "$ver"
done

# rust (cargo)
cargo install --list 2>/dev/null | grep -E '^[a-zA-Z]' | while read -r name ver _; do
    ver=$(echo "$ver" | tr -d 'v:')
    [ -n "$name" ] && printf '%s\t%s\tcargo\n' "$name" "$ver"
done

# flatpak
flatpak list --columns=application,version 2>/dev/null | tail -n +1 | while IFS=$'\t' read -r app ver; do
    [ -n "$app" ] && printf '%s\t%s\tflatpak\n' "$app" "$ver"
done

# kernel
printf 'linux\t%s\tkernel\n' "$(uname -r)"

# running services (no version, but useful for matching product names)
systemctl list-units --type=service --state=running --no-legend 2>/dev/null | awk '{print $1}' | sed 's/\.service$//' | while read -r svc; do
    printf '%s\t-\tservice\n' "$svc"
done

# docker containers
if command -v docker >/dev/null 2>&1; then
    docker ps --format '{{.Image}}' 2>/dev/null | while read -r img; do
        name=$(echo "$img" | sed 's/:.*//; s|.*/||')
        ver=$(echo "$img" | grep -o ':.*' | tr -d ':')
        [ -z "$ver" ] && ver="latest"
        printf '%s\t%s\tdocker\n' "$name" "$ver"
    done
fi

A .local/bin/dev/kd => .local/bin/dev/kd +190 -0
@@ 0,0 1,190 @@
#!/usr/bin/env bash
# ==============================================================
#  kd — Kill Dev
# --------------------------------------------------------------
#  Author   : Kris Yotam (aka. khr1st)
#  Contact  : krisyotam@protonmail.com
#  License  : GNU GPLv3
#  Date     : 2026-03-25
# --------------------------------------------------------------
#  Description:
#    Kill dev servers and clean up stale lock files.
#    Detects Next.js, Vite, Webpack, Hugo, and other common
#    dev servers by process name and listening port.
# ==============================================================

set -eu

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BOLD='\033[1m'
RESET='\033[0m'

DEV_PORTS=(3000 3001 3080 3081 4000 4200 5000 5173 5174 8000 8080 8888)
DEV_PATTERNS=("next-server" "next dev" "vite" "webpack-dev" "hugo server" "gatsby" "nuxt" "remix" "astro" "turbopack")
LOCK_PATTERNS=(".next/dev/lock" ".next/server.lock")

usage() {
  cat <<EOF
${BOLD}kd${RESET} — kill dev servers

${BOLD}Usage:${RESET}
  kd                  Kill port 3000 + clean lock files (default)
  kd --port <port>    Kill a specific port
  kd --all            Find and kill all dev servers
  kd --clean          Remove stale lock files only
  kd --scan           Show running dev servers without killing
  kd --help           Show this help

${BOLD}Examples:${RESET}
  kd                  Quick kill 3000
  kd --port 5173      Kill Vite on 5173
  kd --all            Nuke everything
  kd --scan           See what's running
EOF
}

log() { printf "${GREEN}[kd]${RESET} %s\n" "$1"; }
warn() { printf "${YELLOW}[kd]${RESET} %s\n" "$1"; }
err() { printf "${RED}[kd]${RESET} %s\n" "$1"; }

kill_port() {
  local port="$1"
  local pids
  pids=$(fuser "$port/tcp" 2>/dev/null | tr -s ' ') || true

  if [ -z "$pids" ]; then
    warn "Nothing on port $port"
    return
  fi

  for pid in $pids; do
    local name
    name=$(ps -p "$pid" -o comm= 2>/dev/null || echo "unknown")
    log "Killing $name (PID $pid) on port $port"
    kill -9 "$pid" 2>/dev/null || true
  done
}

clean_locks() {
  local found=0
  # search common dev directories
  for dir in "$HOME"/dev/*/; do
    [ -d "$dir" ] || continue
    for pattern in "${LOCK_PATTERNS[@]}"; do
      local lockfile="$dir$pattern"
      if [ -f "$lockfile" ]; then
        rm -f "$lockfile"
        log "Removed $lockfile"
        found=1
      fi
    done
  done

  if [ "$found" -eq 0 ]; then
    warn "No stale lock files found"
  fi
}

scan_devs() {
  local found=0
  printf "${BOLD}%-8s %-8s %-20s %s${RESET}\n" "PORT" "PID" "PROCESS" "CMD"
  printf "%-8s %-8s %-20s %s\n" "----" "---" "-------" "---"

  for port in "${DEV_PORTS[@]}"; do
    local pids
    pids=$(fuser "$port/tcp" 2>/dev/null | tr -s ' ') || true
    [ -z "$pids" ] && continue

    for pid in $pids; do
      local name cmd
      name=$(ps -p "$pid" -o comm= 2>/dev/null || echo "unknown")
      cmd=$(ps -p "$pid" -o args= 2>/dev/null | head -c 60 || echo "")
      printf "%-8s %-8s %-20s %s\n" "$port" "$pid" "$name" "$cmd"
      found=1
    done
  done

  # also check for dev processes not on standard ports
  for pattern in "${DEV_PATTERNS[@]}"; do
    while IFS= read -r line; do
      local pid name
      pid=$(echo "$line" | awk '{print $1}')
      name=$(echo "$line" | awk '{for(i=2;i<=NF;i++) printf "%s ", $i; print ""}')
      # skip if we already found this pid above
      printf "%-8s %-8s %-20s %s\n" "?" "$pid" "${pattern}" "$name"
      found=1
    done < <(pgrep -af "$pattern" 2>/dev/null | grep -v "grep\|kd" || true)
  done

  if [ "$found" -eq 0 ]; then
    warn "No dev servers detected"
  fi
}

kill_all() {
  log "Scanning for dev servers..."

  # kill by known ports
  for port in "${DEV_PORTS[@]}"; do
    local pids
    pids=$(fuser "$port/tcp" 2>/dev/null | tr -s ' ') || true
    [ -z "$pids" ] && continue
    kill_port "$port"
  done

  # kill by process pattern
  for pattern in "${DEV_PATTERNS[@]}"; do
    local pids
    pids=$(pgrep -f "$pattern" 2>/dev/null | grep -v "$$" || true)
    [ -z "$pids" ] && continue

    for pid in $pids; do
      local name
      name=$(ps -p "$pid" -o comm= 2>/dev/null || echo "unknown")
      log "Killing $name (PID $pid) matching '$pattern'"
      kill -9 "$pid" 2>/dev/null || true
    done
  done

  clean_locks
  log "Done"
}

# --- main ---

case "${1:-}" in
  --port|-p)
    [ -z "${2:-}" ] && { err "Specify a port: kd --port 3000"; exit 1; }
    kill_port "$2"
    clean_locks
    ;;
  --all|-a)
    kill_all
    ;;
  --clean|-c)
    clean_locks
    ;;
  --scan|-s)
    scan_devs
    ;;
  --help|-h)
    usage
    ;;
  "")
    kill_port 3000
    clean_locks
    ;;
  *)
    # if it's a number, treat as port
    if [[ "$1" =~ ^[0-9]+$ ]]; then
      kill_port "$1"
      clean_locks
    else
      err "Unknown option: $1"
      usage
      exit 1
    fi
    ;;
esac

A .local/bin/dev/killnext => .local/bin/dev/killnext +6 -0
@@ 0,0 1,6 @@
#!/bin/sh
# Kill all Next.js dev servers and their parent npm processes
pkill -9 -f 'next-server' 2>/dev/null
pkill -9 -f 'next dev' 2>/dev/null
pkill -9 -f 'npm run dev' 2>/dev/null
echo "All Next.js dev servers killed."

A .local/bin/dev/push => .local/bin/dev/push +44 -0
@@ 0,0 1,44 @@
#!/bin/bash
# push: push all git repos in ~/dev that have your own remotes
# usage: push          -- direct push of committed changes
#        push --smart  -- use claude to commit+push intelligently

LOGFILE="$HOME/.local/share/dev-push.log"
DEVDIR="$HOME/dev"

smart=0
[ "$1" = "--smart" ] && smart=1

if [ "$smart" -eq 1 ]; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') — push --smart: attempting claude" >> "$LOGFILE"
    timeout 120 claude --dangerously-skip-permissions -p \
        "Run push for me. For each git repo in ~/dev that is owned by krisyotam on GitHub, check if there are unpushed commits or uncommitted changes. If there are uncommitted changes, create a sensible commit and push. If already up to date, skip it. Be efficient — only report repos where you took action." \
        --allowedTools "Bash(command:*)" \
        2>> "$LOGFILE"
    if [ $? -eq 0 ]; then
        exit 0
    fi
    echo "$(date '+%Y-%m-%d %H:%M:%S') — claude unavailable, falling back to direct push" >> "$LOGFILE"
fi

echo "$(date '+%Y-%m-%d %H:%M:%S') — push starting" >> "$LOGFILE"

for d in "$DEVDIR"/*/; do
    [ -d "$d/.git" ] || continue
    name="$(basename "$d")"

    remote_url="$(git -C "$d" remote get-url origin 2>/dev/null)"
    [ -z "$remote_url" ] && continue
    echo "$remote_url" | grep -qiE 'krisyotam|krisportfolio' || continue

    local_ref="$(git -C "$d" rev-parse HEAD 2>/dev/null)"
    tracking="$(git -C "$d" rev-parse '@{u}' 2>/dev/null)"
    [ "$local_ref" = "$tracking" ] 2>/dev/null && continue

    echo "$(date '+%Y-%m-%d %H:%M:%S') — pushing $name" >> "$LOGFILE"
    git -C "$d" push 2>> "$LOGFILE" && \
        echo "$(date '+%Y-%m-%d %H:%M:%S') — $name pushed OK" >> "$LOGFILE" || \
        echo "$(date '+%Y-%m-%d %H:%M:%S') — $name FAILED" >> "$LOGFILE"
done

echo "$(date '+%Y-%m-%d %H:%M:%S') — push complete" >> "$LOGFILE"

R .local/bin/dbrowse => .local/bin/dmenu/dbrowse +0 -0
R .local/bin/dcalc => .local/bin/dmenu/dcalc +0 -0
R .local/bin/dclip => .local/bin/dmenu/dclip +0 -0
R .local/bin/dcreate => .local/bin/dmenu/dcreate +0 -0
R .local/bin/dedit => .local/bin/dmenu/dedit +0 -0
R .local/bin/dkymap => .local/bin/dmenu/dkymap +0 -0
R .local/bin/dlaunch => .local/bin/dmenu/dlaunch +0 -0
R .local/bin/dllm => .local/bin/dmenu/dllm +0 -0
R .local/bin/dlog => .local/bin/dmenu/dlog +0 -0
R .local/bin/dmenuhandler => .local/bin/dmenu/dmenuhandler +0 -0
R .local/bin/dmenumountcifs => .local/bin/dmenu/dmenumountcifs +0 -0
R .local/bin/dmenupass => .local/bin/dmenu/dmenupass +0 -0
R .local/bin/dmenurecord => .local/bin/dmenu/dmenurecord +0 -0
R .local/bin/dmenuunicode => .local/bin/dmenu/dmenuunicode +1 -1
@@ 3,7 3,7 @@
# The famous "get a menu of emojis to copy" script.

# Get user selection via dmenu from emoji file.
chosen=$(cut -d ';' -f1 ~/.local/share/larbs/chars/* | dmenu -i -l 30 | sed "s/ .*//")
chosen=$(cut -d ';' -f1 ~/.local/share/lazykris/chars/* | dmenu -i -l 30 | sed "s/ .*//")

# Exit if none chosen.
[ -z "$chosen" ] && exit

R .local/bin/dmode => .local/bin/dmenu/dmode +0 -0
R .local/bin/dnotes => .local/bin/dmenu/dnotes +0 -0
R .local/bin/dread => .local/bin/dmenu/dread +0 -0
R .local/bin/dsnip => .local/bin/dmenu/dsnip +0 -0
R .local/bin/dsnip-seed => .local/bin/dmenu/dsnip-seed +0 -0
R .local/bin/dtime => .local/bin/dmenu/dtime +0 -0
R .local/bin/dwrite => .local/bin/dmenu/dwrite +0 -0
D .local/bin/dwmblocks-start => .local/bin/dwmblocks-start +0 -3
@@ 1,3 0,0 @@
#!/bin/sh
# Simple wrapper - just start dwmblocks
exec dwmblocks

D .local/bin/essay => .local/bin/essay +0 -0
D .local/bin/git-setup-mirrors => .local/bin/git-setup-mirrors +0 -91
@@ 1,91 0,0 @@
#!/bin/sh
# git-setup-mirrors - Set up multiple push URLs for mirroring
#
# Usage: git-setup-mirrors <profile> <repo-name>
#   profile: krisyotam, khr1st, or laelyotam
#   repo-name: name of the repository (without .git)
#
# Example: git-setup-mirrors krisyotam my-project
#
# This adds multiple push URLs to 'origin' so a single 'git push'
# pushes to all configured mirrors.

set -e

PROFILE="$1"
REPO="$2"

usage() {
    echo "Usage: git-setup-mirrors <profile> <repo-name>"
    echo ""
    echo "Profiles:"
    echo "  krisyotam  - Personal (gitea, codeberg, sourcehut, github, gitlab)"
    echo "  khr1st     - Pentesting (github/imkhr1st, gitea)"
    echo "  laelyotam  - Work (github only)"
    echo ""
    echo "Example: git-setup-mirrors krisyotam my-project"
    exit 1
}

[ -z "$PROFILE" ] || [ -z "$REPO" ] && usage

# Verify we're in a git repo
git rev-parse --git-dir > /dev/null 2>&1 || {
    echo "Error: Not in a git repository"
    exit 1
}

echo "Setting up mirrors for '$REPO' with profile '$PROFILE'..."

case "$PROFILE" in
    krisyotam)
        # Primary remote (pull from github)
        git remote set-url origin "git@github.com:krisyotam/${REPO}.git" 2>/dev/null || \
            git remote add origin "git@github.com:krisyotam/${REPO}.git"

        # Clear existing push URLs and add all mirrors
        git remote set-url --push origin "git@git.krisyotam.com:krisyotam/${REPO}.git"
        git remote set-url --add --push origin "git@codeberg.org:krisyotam/${REPO}.git"
        git remote set-url --add --push origin "git@git.sr.ht:~krisyotam/${REPO}"
        git remote set-url --add --push origin "git@github.com:krisyotam/${REPO}.git"
        git remote set-url --add --push origin "git@gitlab.com:krisyotam/${REPO}.git"

        echo "Mirrors configured:"
        echo "  - git.krisyotam.com:krisyotam/${REPO}"
        echo "  - codeberg.org:krisyotam/${REPO}"
        echo "  - git.sr.ht:~krisyotam/${REPO}"
        echo "  - github.com:krisyotam/${REPO}"
        echo "  - gitlab.com:krisyotam/${REPO}"
        ;;

    khr1st)
        # Primary remote (uses github-khr1st alias from ~/.ssh/config)
        git remote set-url origin "git@github-khr1st:imkhr1st/${REPO}.git" 2>/dev/null || \
            git remote add origin "git@github-khr1st:imkhr1st/${REPO}.git"

        # Push mirrors
        git remote set-url --push origin "git@github-khr1st:imkhr1st/${REPO}.git"
        git remote set-url --add --push origin "git@git.krisyotam.com-khr1st:khr1st/${REPO}.git"

        echo "Mirrors configured:"
        echo "  - github.com (imkhr1st) via github-khr1st alias"
        echo "  - git.krisyotam.com (khr1st) via ky-khr1st alias"
        ;;

    laelyotam)
        # Single remote (uses github-work alias from ~/.ssh/config)
        git remote set-url origin "git@github-work:laelyotam/${REPO}.git" 2>/dev/null || \
            git remote add origin "git@github-work:laelyotam/${REPO}.git"

        echo "Remote configured:"
        echo "  - github.com (laelyotam) via github-work alias"
        ;;

    *)
        echo "Error: Unknown profile '$PROFILE'"
        usage
        ;;
esac

echo ""
echo "Verify with: git remote -v"

R .local/bin/history => .local/bin/history/history +1 -1
@@ 1,4 1,4 @@
#!/bin/sh
#!/bin/bash
# history - unified history viewer (encrypted with SQLCipher)
# Usage: history -m <mode> [options]


R .local/bin/history-clipboard-daemon => .local/bin/history/history-clipboard-daemon +0 -0
R .local/bin/history-init => .local/bin/history/history-init +0 -0
R .local/bin/history-sync-browsers => .local/bin/history/history-sync-browsers +0 -0
D .local/bin/init-all-courses.py => .local/bin/init-all-courses.py +0 -69
@@ 1,69 0,0 @@
#!/usr/bin/env python3
"""
===============================================================
 Script: init-all-courses.py
 Author: Kris Yotam (aka. khr1st)
 Date:   2025-09-29
 License: MIT License
 Description:
   Initializes LaTeX note-taking course directories by
   creating `master.tex`, `master.tex.latexmain`, and
   ensuring `figures/` exists for each course.

 Inspiration:
   Adapted and extended from Gilles Castel's lecture note workflow.
===============================================================
"""

from courses import Courses


def build_master_content(course_title: str) -> str:
    """
    Return the LaTeX master.tex skeleton as a single string.
    """
    lines = [
        r'\documentclass[a4paper]{article}',
        r'\input{../preamble.tex}',
        fr'\title{{{course_title}}}',
        r'\begin{document}',
        r'    \maketitle',
        r'    \tableofcontents',
        r'    % start lectures',
        r'    % end lectures',
        r'\end{document}',
    ]
    return '\n'.join(lines)


def init_course(course):
    """
    Initialize one course directory with master.tex,
    .latexmain marker, and figures/ folder.
    """
    lectures = course.lectures
    course_title = lectures.course.info["title"]

    # Write master.tex with minimal skeleton
    lectures.master_file.touch(exist_ok=True)
    lectures.master_file.write_text(build_master_content(course_title))

    # Touch helper file for latexmk integration
    (lectures.root / 'master.tex.latexmain').touch(exist_ok=True)

    # Ensure figures directory exists
    (lectures.root / 'figures').mkdir(exist_ok=True)

    print(f"[ok] Initialized {course_title}")


def main():
    """
    Iterate over all courses and initialize them.
    """
    for course in Courses():
        init_course(course)


if __name__ == "__main__":
    main()

R .local/bin/bg-picker => .local/bin/media/bg-picker +0 -0
R .local/bin/booksplit => .local/bin/media/booksplit +0 -0
R .local/bin/maimpick => .local/bin/media/maimpick +0 -0
R .local/bin/noisereduce => .local/bin/media/noisereduce +0 -0
R .local/bin/opout => .local/bin/media/opout +0 -0
R .local/bin/output => .local/bin/media/output +0 -0
R .local/bin/pauseallmpv => .local/bin/media/pauseallmpv +0 -0
R .local/bin/peertubetorrent => .local/bin/media/peertubetorrent +0 -0
R .local/bin/qndl => .local/bin/media/qndl +0 -0
R .local/bin/record => .local/bin/media/record +0 -0
R .local/bin/rotdir => .local/bin/media/rotdir +0 -0
R .local/bin/screenshot => .local/bin/media/screenshot +0 -0
R .local/bin/setbg => .local/bin/media/setbg +0 -0
R .local/bin/slider => .local/bin/media/slider +0 -0
R .local/bin/transadd => .local/bin/media/transadd +0 -0
A .local/bin/misc/README.md => .local/bin/misc/README.md +11 -0
@@ 0,0 1,11 @@
# 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 DISPLAY=:0; . $HOME/.zprofile;  then_command_goes_here
```

This ensures that notifications will display, xdotool commands will function and environmental variables will work as well.

R .local/bin/bm => .local/bin/misc/bm +0 -0
R .local/bin/browser => .local/bin/misc/browser +0 -0
R .local/bin/cmd-menu => .local/bin/misc/cmd-menu +0 -0
R .local/bin/commit => .local/bin/misc/commit +0 -0
R .local/bin/compiler => .local/bin/misc/compiler +0 -0
R .local/bin/config.py => .local/bin/misc/config.py +0 -0
R .local/bin/create => .local/bin/misc/create +0 -0
R .local/bin/edit => .local/bin/misc/edit +0 -0
R .local/bin/email => .local/bin/misc/email +0 -0
R .local/bin/getbib => .local/bin/misc/getbib +1 -1
@@ 1,4 1,4 @@
#!/bin/sh
#!/bin/bash

BIB_FILE="${HOME}/latex/uni.bib"
[ -f "${BIB_FILE}" ] || BIB_FILE="${2:-$(find "${HOME}" -path "${HOME}/.*" \

R .local/bin/getkeys => .local/bin/misc/getkeys +2 -2
@@ 1,5 1,5 @@
#!/bin/sh

cat "${XDG_DATA_HOME:-$HOME/.local/share}"/larbs/getkeys/"$1" 2>/dev/null && exit
cat "${XDG_DATA_HOME:-$HOME/.local/share}"/lazykris/getkeys/"$1" 2>/dev/null && exit
echo "Run command with one of the following arguments for info about that program:"
ls "${XDG_DATA_HOME:-$HOME/.local/share}"/larbs/getkeys
ls "${XDG_DATA_HOME:-$HOME/.local/share}"/lazykris/getkeys

R .local/bin/git => .local/bin/misc/git +0 -0
R .local/bin/irc => .local/bin/misc/irc +1 -1
@@ 1,4 1,4 @@
#!/bin/sh
#!/bin/bash

# ═══════════════════════════════════════════════════════════════
#  irc — catgirl wrapper for managing IRC network connections

R .local/bin/linkhandler => .local/bin/misc/linkhandler +0 -0
R .local/bin/pin => .local/bin/misc/pin +0 -0
R .local/bin/podentr => .local/bin/misc/podentr +0 -0
R .local/bin/queueandnotify => .local/bin/misc/queueandnotify +1 -1
@@ 1,4 1,4 @@
#!/bin/sh
#!/bin/bash

# Podboat sucks. This script replaces it.
# It reads the newsboat queue, queuing downloads with taskspooler.

R .local/bin/rofi.py => .local/bin/misc/rofi.py +0 -0
R .local/bin/rssadd => .local/bin/misc/rssadd +0 -0
R .local/bin/rssget => .local/bin/misc/rssget +0 -0
R .local/bin/sort => .local/bin/misc/sort +2 -2
@@ 215,8 215,8 @@ main() {
  case "$ans" in
    [yY]|[yY][eE][sS])
      # call clean script if exists else run inline
      if [ -x "$HOME/.local/bin/clean" ]; then
        "$HOME/.local/bin/clean" "$MISC_BASE"
      if [ -x clean ]; then
        clean "$MISC_BASE"
      elif [ -x "/usr/local/bin/clean" ]; then
        "/usr/local/bin/clean" "$MISC_BASE"
      else

R .local/bin/sread => .local/bin/misc/sread +0 -0
R .local/bin/sync => .local/bin/misc/sync +0 -0
R .local/bin/tag => .local/bin/misc/tag +0 -0
R .local/bin/td-toggle => .local/bin/misc/td-toggle +0 -0
R .local/bin/todo => .local/bin/misc/todo +1 -1
@@ 1,4 1,4 @@
#!/bin/sh
#!/bin/bash
# todo - aesthetic terminal todo list backed by SQLite
# Inspired by todo.txt-cli. Data lives in ~/.config/scripts/scripts.db
# Usage: todo [command] [args...]

A .local/bin/misc/udemy-dl => .local/bin/misc/udemy-dl +6 -0
@@ 0,0 1,6 @@
#!/bin/bash
# Wrapper for udemy-downloader (Puyodead1)
# Usage: udemy-dl "https://www.udemy.com/course/COURSE-SLUG/"
cd ~/dev/udemy-downloader
source .venv/bin/activate
python main.py "$@"

R .local/bin/unix => .local/bin/misc/unix +0 -0
R .local/bin/vroid => .local/bin/misc/vroid +0 -0
R .local/bin/weath => .local/bin/misc/weath +1 -1
@@ 1,4 1,4 @@
#!/bin/sh
#!/bin/bash
#
# 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.

R .local/bin/webdev => .local/bin/misc/webdev +0 -0
R .local/bin/write => .local/bin/misc/write +0 -0
A .local/bin/misc/ybrowser => .local/bin/misc/ybrowser +186 -0
@@ 0,0 1,186 @@
#!/bin/sh
dd="${XDG_CACHE_HOME}/ychannels"
yd="${HOME}/ytvideos"
cl="${XDG_DATA_HOME}/categories"
chl="${XDG_DATA_HOME}/channels"
cld="${XDG_DATA_HOME}/clists"
mkdir -p "${dd}" "${yd}" "${cld}"
pr() { printf "%s\n" "${@}"; }
d() {
        i="$(cat)"
        l="$(pr "${i}" | wc -l)"
        [ "${l}" -gt "21" ] && l="21"
        [ "${i}" ] || l="0"
        pr "${i}" | dmenu -i -l "${l}" -p "${1}"
}
n() { notify-send -i "${XDG_CONFIG_HOME}/dunst/yt.png" "${1}"; }
sv() {
        df="${1}"
        so="${2}"
        case "${so}" in
                "@@sv") sort -nr -t"	" -k3 "${df}" ;;
                "@@sd") sort -nr -t"	" -k4 "${df}" ;;
                *) sort -nr -t"	" -k5 "${df}" ;;
        esac | cut -f1
}
gv() {
        cn="${1}"
        so="${2}"
        df="${dd}/${cn}.tsv"
        sv "${df}" "${so}"
}
vu() {
        cn="${1}"
        vt="${2}"
        df="${dd}/${cn}.tsv"
        grep -F "${vt}" "${df}" | cut -f2
}
ma() {
        pr "WATCH" "DOWNLOAD" "SEND TO A LIST" | d "Actions"
}
ca() {
        lsts="$(pr "${cld}"/* | sed 's|.*/||')"
        [ "${lsts}" = "*" ] && lsts=""
        pr "${lsts}" "## CREATE LIST ##" "## DELETE LIST ##" | d "Lists"
}
lva() {
        pr "WATCH" "DOWNLOAD" "DELETE" | d "Actions"
}
atl() {
        vt="${1}"
        cn="${2}"
        ln="${3}"
        pr "${cn}: ${vt}" >> "${cld}/${ln}"
}
clm() {
        while true; do
                lst="$(ca)"
                case "${lst}" in
                        "## CREATE LIST ##")
                                nlst="$(pr | d "Name")"
                                [ "${nlst}" ] && touch "${cld}/${nlst}"
                                ;;
                        "## DELETE LIST ##")
                                dlst="$(find "${cld}" -mindepth "1" -exec basename {} \; | d "Delete List")"
                                [ "${dlst}" ] && rm -f "${cld}/${dlst}"
                                ;;
                        "") return ;;
                        *) cvm "${lst}" ;;
                esac
        done
}
cvm() {
        ln="${1}"
        while true; do
                vi=$(d "Videos" < "${cld}/${ln}")
                [ "${vi}" ] || return
                cn="${vi%%: *}"
                vt="${vi##*: }"
                clvm "${vt}" "${cn}" "${ln}"
        done
}
clvm() {
        vt="${1}"
        cn="${2}"
        ln="${3}"
        ac="$(lva)"
        case "${ac}" in
                "WATCH") vp "${ac}" "${vt}" "${cn}" ;;
                "DOWNLOAD") vp "${ac}" "${vt}" "${cn}" && n "Download finished" ;;
                "DELETE") sed -i "/${vt}/d" "${cld}/${ln}" ;;
                *) return ;;
        esac
}
vp() {
        ac="${1}"
        vt="${2}"
        cn="${3}"
        vu="$(vu "${cn}" "${vt}")"
        case "${ac}" in
                "WATCH") mpv "${vu}" ;;
                "DOWNLOAD")
                        cdd="${yd}/${cn}"
                        mkdir -p "${cdd}"
                        yt-dlp -o "${cdd}/%(title)s.%(ext)s" "${vu}"
                        n "Download finished"
                        ;;
        esac
}
gav() {
        so="${1}"
        avf="${dd}/all_videos.tsv"
        sv "${avf}" "${so}"
}
bac() {
        while vt="$(gav | d "Videos | Sort: @@s{v,d}")"; do
                [ "${vt}" ] || break
                [ "${vt}" = "@@sv" ] || [ "${vt}" = "@@sd" ] && {
                        vt=$(gav "${vt}" | d "Videos")
                        [ "${vt}" ] || continue
                }
                grep -lF "${vt}" "${dd}"/*.tsv | head -n "1" | while read -r "vf"; do
                        vam "${vt}" "$(basename "${vf}" .tsv)"
                        break
                done
        done
}
cm() {
        while true; do
                c="$(cut -d= -f1 "${cl}" | d "Categories")"
                [ "${c}" ] || return
                chm "${c}"
        done
}
chm() {
        c="${1}"
        IFS="|"
        ch="$(sed -n "s/^${c}=\(.*\)$/\1/p" "${cl}")"
        set -- ${ch}
        while true; do
                cn="$(pr "${@}" | d "Channels")"
                [ "${cn}" ] || return
                vm "${cn}"
        done
}
vm() {
        cn="${1}"
        while true; do
                vt=$(gv "${cn}" | d "Videos")
                [ "${vt}" ] || return
                [ "${vt}" = "@@sv" ] || [ "${vt}" = "@@sd" ] && {
                        so="${vt}"
                        vt="$(gv "${cn}" "${so}" | d "Videos")"
                }
                vam "${vt}" "${cn}"
        done
}
vam() {
        vt="${1}"
        cn="${2}"
        while [ "${vt}" ] && [ "${vt}" != "@@sv" ] && [ "${vt}" != "@@sd" ]; do
                ac="$(ma)"
                case "${ac}" in
                        "WATCH") vp "${ac}" "${vt}" "${cn}" ;;
                        "DOWNLOAD") vp "${ac}" "${vt}" "${cn}" && n "Download finished" ;;
                        "SEND TO A LIST")
                                ln="$(find "${cld}" -mindepth "1" -exec basename {} \; | d "Lists")"
                                [ "${ln}" ] && atl "${vt}" "${cn}" "${ln}" && n "${vt} > list: ${ln}"
                                ;;
                        *) return ;;
                esac
        done
}
mm() {
        pr " ## ALL CHANNELS ##" " ## CATEGORIES ##" " ## CUSTOM LISTS ##" \
                "$(cut -d= -f1 "${chl}")" | d "YouTube"
}
while true; do
        mc="$(mm)"
        case "${mc}" in
                " ## ALL CHANNELS ##") bac ;;
                " ## CATEGORIES ##") cm ;;
                " ## CUSTOM LISTS ##") clm ;;
                "") exit ;;
                *) vm "${mc}" ;;
        esac
done

R .local/bin/ytcomments => .local/bin/misc/ytcomments +1 -1
@@ 1,4 1,4 @@
#!/bin/sh
#!/bin/bash

# Scrape YouTube comments into searchable .md and .json files.
# Usage: ytcomments <url> [output_dir]

A .local/bin/monitoring/hanta => .local/bin/monitoring/hanta +107 -0
@@ 0,0 1,107 @@
#!/bin/sh
# hanta — hantavirus outbreak tracker via dunst
# Left click:  Outbreak vessel + case stats
# Right click: CDC snapshot + spread arcs + latest headlines
# No args:     Quick summary line (for statusbar)

DATA_URL="https://hantavirusonline.org/data.json"
CACHE="$HOME/.cache/hanta.json"
CACHE_MAX=300  # 5 minutes

fetch_data() {
    if [ -f "$CACHE" ]; then
        age=$(( $(date +%s) - $(stat -c %Y "$CACHE" 2>/dev/null || echo 0) ))
        [ "$age" -lt "$CACHE_MAX" ] && return 0
    fi
    mkdir -p "$(dirname "$CACHE")"
    curl -sf --max-time 10 "$DATA_URL" -o "$CACHE" 2>/dev/null || return 1
}

fetch_data || {
    notify-send -u critical "HANTA" "Failed to fetch data"
    exit 1
}

# Parse fields once
total=$(jq -r '.vessel.counts.cases_total // "?"' "$CACHE")
confirmed=$(jq -r '.vessel.counts.cases_confirmed // "?"' "$CACHE")
suspected=$(jq -r '.vessel.counts.cases_suspected // "?"' "$CACHE")
deaths=$(jq -r '.vessel.counts.deaths // "?"' "$CACHE")
critical=$(jq -r '.vessel.counts.critical // "?"' "$CACHE")
as_of=$(jq -r '.vessel.counts.as_of // "?"' "$CACHE")
source=$(jq -r '.vessel.counts.source // "?"' "$CACHE")
vessel=$(jq -r '.vessel.name // "?"' "$CACHE")
operator=$(jq -r '.vessel.operator // "?"' "$CACHE")
flag=$(jq -r '.vessel.flag // "?"' "$CACHE")
departed=$(jq -r '.vessel.departed_from // "?"' "$CACHE")
departed_at=$(jq -r '.vessel.departed_at // "?"' "$CACHE")
pos_lat=$(jq -r '.vessel.position.lat // "?"' "$CACHE")
pos_lng=$(jq -r '.vessel.position.lng // "?"' "$CACHE")
pos_hdg=$(jq -r '.vessel.position.heading_deg // "?"' "$CACHE")
pos_time=$(jq -r '.vessel.position.fetched_at // "?"' "$CACHE")
onboard=$(jq -r '.vessel.counts.on_board // "?"' "$CACHE")
passengers=$(jq -r '.vessel.counts.passengers // "?"' "$CACHE")
crew=$(jq -r '.vessel.counts.crew // "?"' "$CACHE")
generated=$(jq -r '.generated_at // "?"' "$CACHE")

case "${BUTTON:-$1}" in
    1|left)
        # LEFT CLICK: Vessel + outbreak detail
        notify-send -u critical -t 20000 \
            "HANTAVIRUS OUTBREAK" \
"<b>CASE COUNT</b>  ($source, $as_of)
  Total cases:    $total
  Lab confirmed:  $confirmed
  Suspected:      $suspected
  Deaths:         $deaths
  Critical:       $critical

<b>OUTBREAK VESSEL</b>
  $vessel  ($operator)
  Flag: $flag
  Departed: $departed ($departed_at)
  On board: $onboard ($passengers pax / $crew crew)

<b>LAST AIS FIX</b>  $(echo "$pos_time" | cut -dT -f1,2 | tr T ' ')
  Position: ${pos_lat}, ${pos_lng}
  Heading:  ${pos_hdg}deg

<b>AFFECTED REGIONS</b>
$(jq -r '.country_index[] | "  \(.country): \(.count) reports"' "$CACHE")

Updated: $(echo "$generated" | cut -dT -f1,2 | tr T ' ')"
        ;;

    3|right)
        # RIGHT CLICK: CDC snapshot + spread + headlines
        cdc_total=$(jq -r '.cdc_snapshot.total_cases // "?"' "$CACHE")
        cdc_hps=$(jq -r '.cdc_snapshot.hps_cases // "?"' "$CACHE")
        cdc_cfr=$(jq -r '.cdc_snapshot.case_fatality_rate_pct // "?"' "$CACHE")
        cdc_west=$(jq -r '.cdc_snapshot.pct_west_of_mississippi // "?"' "$CACHE")
        cdc_age=$(jq -r '.cdc_snapshot.median_age // "?"' "$CACHE")
        cdc_male=$(jq -r '.cdc_snapshot.pct_male // "?"' "$CACHE")
        cdc_since=$(jq -r '.cdc_snapshot.surveillance_start // "?"' "$CACHE")
        cdc_asof=$(jq -r '.cdc_snapshot.as_of // "?"' "$CACHE")

        notify-send -u normal -t 20000 \
            "HANTA  CDC + SPREAD" \
"<b>CDC SURVEILLANCE</b>  ($cdc_since-$cdc_asof)
  Total US cases:     $cdc_total
  HPS cases:          $cdc_hps
  Fatality rate:      ${cdc_cfr}%
  West of Miss.:      ${cdc_west}%
  Median age:         $cdc_age
  Male:               ${cdc_male}%

<b>SPREAD ARCS</b>
$(jq -r '.spread_arcs[] | "  \(.from) -> \(.to): \(.label)"' "$CACHE")

<b>LATEST HEADLINES</b>
$(jq -r '.items[:6][] | "  [\(.published)] \(.title[:70])"' "$CACHE")"
        ;;

    *)
        # No button / statusbar mode: one-line summary
        printf "HANTA %s/%s/%s" "$total" "$deaths" "$critical"
        ;;
esac

R .local/bin/kaiju-probability-index => .local/bin/monitoring/kaiju-probability-index +0 -0
R .local/bin/maritime-charts => .local/bin/monitoring/maritime-charts +0 -0
R .local/bin/ocean-heat-content-index => .local/bin/monitoring/ocean-heat-content-index +0 -0
R .local/bin/sea-surface-temperature-anomaly => .local/bin/monitoring/sea-surface-temperature-anomaly +0 -0
R .local/bin/subsea-seismic-monitor => .local/bin/monitoring/subsea-seismic-monitor +0 -0
R .local/bin/supervolcano-monitor => .local/bin/monitoring/supervolcano-monitor +0 -0
D .local/bin/mouse => .local/bin/mouse +0 -3
@@ 1,3 0,0 @@
#!/bin/sh
mouseless "$@" &>/dev/null &
disown

D .local/bin/nnn-typora => .local/bin/nnn-typora +0 -8
@@ 1,8 0,0 @@
#!/bin/sh
# nnn-typora — open .mdx/.md files in Typora, everything else via xdg-open
# Used by the `write` script to override NNN_OPENER when browsing content

case "$1" in
    *.mdx|*.md) typora "$1" >/dev/null 2>&1 & disown ;;
    *) ${NNN_FALLBACK_OPENER:-xdg-open} "$1" >/dev/null 2>&1 & disown ;;
esac

R .local/bin/lfub => .local/bin/nnn/lfub +0 -0
R .local/bin/nnn-zathura => .local/bin/nnn/nnn-zathura +0 -0
D .local/bin/papers-setup => .local/bin/papers-setup +0 -78
@@ 1,78 0,0 @@
#!/bin/bash
# ==============================================================================
# Papers Library Setup Script
# Sets up symlinks for the bibliography/papers system
#
# Usage:
#   1. Clone the repo: git clone https://github.com/krisyotam/papers ~/dev/papers
#   2. Run this script: ~/dev/papers/setup.sh
#
# This creates:
#   ~/bib-lib -> ~/dev/papers (symlink)
#   ~/notes/references -> ~/dev/papers/roam/references (symlink)
# ==============================================================================

set -e

PAPERS_DIR="$HOME/dev/papers"
BIB_LINK="$HOME/bib-lib"
NOTES_DIR="$HOME/notes"
REFS_LINK="$NOTES_DIR/references"

echo "=== Papers Library Setup ==="
echo ""

# Check if papers repo exists
if [ ! -d "$PAPERS_DIR" ]; then
    echo "ERROR: Papers repo not found at $PAPERS_DIR"
    echo "Clone it first: git clone https://github.com/krisyotam/papers ~/dev/papers"
    exit 1
fi

# Handle ~/bib-lib
if [ -L "$BIB_LINK" ]; then
    echo "~/bib-lib is already a symlink, removing..."
    rm "$BIB_LINK"
elif [ -d "$BIB_LINK" ]; then
    echo "~/bib-lib is a directory, backing up to ~/bib-lib.bak..."
    if [ -d "$BIB_LINK.bak" ]; then
        rm -rf "$BIB_LINK.bak"
    fi
    mv "$BIB_LINK" "$BIB_LINK.bak"
fi

echo "Creating symlink: ~/bib-lib -> ~/dev/papers"
ln -sf "$PAPERS_DIR" "$BIB_LINK"

# Handle ~/notes/references
mkdir -p "$NOTES_DIR"

if [ -L "$REFS_LINK" ]; then
    echo "~/notes/references is already a symlink, removing..."
    rm "$REFS_LINK"
elif [ -d "$REFS_LINK" ]; then
    echo "~/notes/references is a directory, backing up..."
    if [ -d "$REFS_LINK.bak" ]; then
        rm -rf "$REFS_LINK.bak"
    fi
    mv "$REFS_LINK" "$REFS_LINK.bak"
fi

echo "Creating symlink: ~/notes/references -> ~/dev/papers/roam/references"
ln -sf "$PAPERS_DIR/roam/references" "$REFS_LINK"

echo ""
echo "=== Setup Complete ==="
echo ""
echo "Directory structure:"
echo "  ~/bib-lib -> ~/dev/papers"
echo "  ~/bib-lib/library.bib      - Main bibliography"
echo "  ~/bib-lib/temp-lib.bib     - Temporary imports"
echo "  ~/bib-lib/pdfs/            - Main PDF storage"
echo "  ~/bib-lib/temp-pdfs/       - Temporary PDFs"
echo "  ~/notes/references -> ~/dev/papers/roam/references"
echo ""
echo "Emacs config expects ~/bib-lib/ paths - these now point to ~/dev/papers"
echo ""
echo "To commit changes to your papers:"
echo "  cd ~/dev/papers && git add -A && git commit -m 'Update papers' && git push"

D .local/bin/sb-aurora => .local/bin/sb-aurora +0 -93
@@ 1,93 0,0 @@
#!/bin/bash
# explicitly setting display bc cronjob
export DISPLAY=:0

# urls!
forecasturl="https://services.swpc.noaa.gov/text/3-day-geomag-forecast.txt"
viewlineurl="https://services.swpc.noaa.gov/experimental/images/aurora_dashboard/tonights_static_viewline_forecast.png"
latesturl="https://services.swpc.noaa.gov/images/animations/ovation/north/latest.jpg"
kurl="https://services.swpc.noaa.gov/images/station-k-index.png"

# file locations, kill command for statusbar
forecast="$HOME/.cache/aurora.txt"
viewline="$HOME/.cache/aurora.png"
latest="$HOME/.cache/aurora_latest.jpg"
kindex="$HOME/.cache/aurora_kindex.png"
combo="$HOME/.cache/aurora_combo.jpg"
killcmd=$(pkill -RTMIN+7 dwmblocks)

# threshold values
threshold=3.99
critical=6.99

# goal: get the max value for my nighttime:
# 	hours 21-00 from day 1; 00-12 from day 2

# awk '{a[NR]=$3; b=$2} END { print b " " a[NR-7] }' .cache/aurora.txt
#	add the values from line numbers (beginning at end) to an array for column3
#   then print last value of today (b), and first value of tomorrow (bc it's 7 lines back)

# init val to the last # in column 1 to ensure it's included
# 	loop the 4 values we need from column 2 (lines 7 from end to 4 from end)
# 	compare loop value to init'd val --> set val to that loop value if greater
# then print the val

value=$(awk '{a[NR]=$3; b=$2} END {val=b
		for (i=NR-7; i<=NR-4; i++)
		if (a[i]>val) val=a[i]
		print val}' $forecast)

# echo the value i want to bar (removing extra decimals)
# Always show kp value regardless of threshold
tobar () {
		echo "󰩲 ${value:0:1}"
}

# extra command just to see data if needed
data () {
		cat $forecast
}

# bound to a hotkey.. pull up the recently downloaded images w/ mpv
images () {
		# nsxiv -i $viewline $latest $kindex
		setsid -f mpv --title="Aurora" --idle --autofit=50% \
		--background=none --loop-playlist --image-display-duration=10 \
		$viewline $latest $kindex
}

# full update, i run it in a cronjob
update () {
	    curl -so $forecast $forecasturl && \
		curl -so $latest $latesturl && \
		curl -so $viewline $viewlineurl && \
		curl -so $kindex $kurl && \
		$killcmd && \
		magick $latest $viewline -resize x512 +append $combo && \
		notify-send -t 30000 -u low -i $viewline "󰩲Aurora Forecast Updated" "$(tail -n 9 $forecast)"
}

# script usage
case "$1" in
		u*) update ;;
		i*) images ;;
		d*) data ;;
		h*) echo "aurora: update | images | data | tobar --- set urls + files in script" ;;
		*) tobar ;;
esac

# clickable bar commands + notifications
case $BLOCK_BUTTON in
		1) notify-send -t 60000 -u low -i $combo "Aurora Latest Forecast (right-click: kindex)" "$(tail -n 9 $forecast)" ;;
		2) curl -so $forecast $forecasturl && \
			curl -so $latest $latesturl && \
			curl -so $viewline $viewlineurl && \
			curl -so $kindex $kurl && \
			$killcmd && \
			magick $latest $viewline -resize x512 +append $combo && \
			notify-send -i $latest "Aurora forecast updated!" "Left-click, right-click, or scroll" ;;
		3) notify-send -t 60000 -u low -i $kindex "Aurora Kp Index (left-click: latest/viewline)" "$(tail -n 9 $forecast)" ;;
		4) notify-send -t 60000 -u low -i $latest "Latest Aurora Forecast" "$(tail -n 9 $forecast)" ;;
		5) notify-send -t 60000 -u low -i $viewline "Tonight's Aurora Forecast" "$(tail -n 9 $forecast)" ;;
		6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

D .local/bin/sb-battery => .local/bin/sb-battery +0 -55
@@ 1,55 0,0 @@
#!/bin/sh

# Prints all batteries, their percentage remaining and a Nerd Font icon
# corresponding to charge status and level.

case $BLOCK_BUTTON in
	3) notify-send "󰁹 Battery module" "󰁹: full
󰂁: discharging
󰂄: charging
󰂃: not charging
󰂎: empty
󱃍: battery very low!
- Scroll to change adjust xbacklight." ;;
	4) xbacklight -inc 10 ;;
	5) xbacklight -dec 10 ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
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
	capacity="$(cat "$battery/capacity" 2>&1)"
	charging_status="$(cat "$battery/status" 2>&1)"

	case "$charging_status" in
		"Full") status="󰁹" ;;
		"Charging") status="󰂄" ;;
		"Not charging") status="󰂃" ;;
		"Discharging")
			if [ "$capacity" -ge 95 ]; then
				status="󰁹"
			elif [ "$capacity" -ge 65 ]; then
				status="󰂀"
			elif [ "$capacity" -ge 40 ]; then
				status="󰁾"
			elif [ "$capacity" -ge 25 ]; then
				status="󰁼"
			elif [ "$capacity" -ge 10 ]; then
				status="󰁻"
			elif [ "$capacity" -ge 5 ]; then
				status="󰁺"
			else
				status="󰂎"
			fi
			;;
		"Unknown") status="󰂑" ;;
		*) exit 1 ;;
	esac
	# Will make a warn variable if discharging and low
	[ "$charging_status" = "Discharging" ] && [ "$capacity" -le 25 ] && warn="󱃍"
	# Prints the info
	printf "%s%s %d%%" "$status" "$warn" "$capacity"; unset warn
done && printf "\\n"

D .local/bin/sb-brightness => .local/bin/sb-brightness +0 -23
@@ 1,23 0,0 @@
#!/bin/sh

# current brightness
curr_brightness=$(cat /sys/class/backlight/*/brightness)

# max_brightness
max_brightness=$(cat /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 ☀️." 
        ;;
    6) 
        setsid -f "$TERMINAL" -e "$EDITOR" "$0"
        ;;
esac

echo "💡 ${brightness_per}%"

D .local/bin/sb-clock => .local/bin/sb-clock +0 -29
@@ 1,29 0,0 @@
#!/bin/sh

clock=$(date '+%I')

case "$clock" in
	"12") icon="󱑊" ;;
	"01") icon="󱐿" ;;
	"02") icon="󱑀" ;;
	"03") icon="󱑁" ;;
	"04") icon="󱑂" ;;
	"05") icon="󱑃" ;;
	"06") icon="󱑄" ;;
	"07") icon="󱑅" ;;
	"08") icon="󱑆" ;;
	"09") icon="󱑇" ;;
	"10") icon="󱑈" ;;
	"11") icon="󱑉" ;;
	"00") 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 ;;
	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" ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

TZ="America/Chicago" date "+%Y.%m.%d (%a) $icon %I:%M%p"

D .local/bin/sb-cpu => .local/bin/sb-cpu +0 -12
@@ 1,12 0,0 @@
#!/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 ;;
	3) notify-send "🖥 CPU module " "\- Shows CPU temperature.
- Click to show intensive processes.
- Middle click to open btop." ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

sensors | awk '/Core 0/ {print "🌡" $3}'

D .local/bin/sb-cpubars => .local/bin/sb-cpubars +0 -44
@@ 1,44 0,0 @@
#!/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 ;;
	3) notify-send "🪨 CPU load module" "Each bar represents
one CPU core";;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
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=$(cat "$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"

D .local/bin/sb-dashboard => .local/bin/sb-dashboard +0 -30
@@ 1,30 0,0 @@
#!/bin/sh

# Ensure eww daemon is running
pgrep -x eww >/dev/null 2>&1 || eww daemon >/dev/null 2>&1 &

WINDOW="performance_monitor"
OVERLAY="dashboard_overlay"

# Display distro-specific Nerd Font icon in status bar
if [ -f /etc/arch-release ]; then
	printf '󰣇 \n'
elif [ -f /etc/gentoo-release ]; then
	printf ' \n'
else
	printf ' \n'
fi

case $BLOCK_BUTTON in
	1)
		if eww active-windows 2>/dev/null | grep -q "$WINDOW"; then
			eww update performance_monitor_visible=false
			eww close "$WINDOW" "$OVERLAY"
		else
			eww update performance_monitor_visible=true
			eww open "$OVERLAY"
			eww open "$WINDOW"
		fi
		;;
	3) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

D .local/bin/sb-disk => .local/bin/sb-disk +0 -26
@@ 1,26 0,0 @@
#!/bin/sh

# Status bar module for disk space
# Automatically detects /home if separate partition, otherwise uses /
# Can override with $1 argument

# Smart default: use /home if it's a separate partition, else /
if [ -n "$1" ]; then
    location="$1"
elif df /home 2>/dev/null | grep -q "^/dev" && [ "$(df / --output=source | tail -1)" != "$(df /home --output=source | tail -1)" ]; then
    location="/home"
else
    location="/"
fi

[ -d "$location" ] || exit

case $BLOCK_BUTTON in
    1) notify-send "󰋊 Disk space" "$(df -h --output=target,used,size,avail,pcent /home / 2>/dev/null | head -5)" ;;
    3) notify-send "󰋊 Disk module" "Shows disk space for $location
- Left click for full disk info
- Currently monitoring: $location" ;;
    6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

printf "󰋊  %s\n" "$(df -h "$location" | awk '/[0-9]/ {print $3 "/" $2}')"

D .local/bin/sb-doppler => .local/bin/sb-doppler +0 -239
@@ 1,239 0,0 @@
#!/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" | dmenu -r -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" ;;
	esac
}

showdoppler() { setsid -f mpv --no-osc --loop=inf --no-terminal "$doppler" ;}

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."  ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

echo "󰐷 "

D .local/bin/sb-forecast => .local/bin/sb-forecast +0 -82
@@ 1,82 0,0 @@
#!/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() { timeout --signal=1 2s curl -sf "$url/$LOCATION" > "$weatherreport" || exit 1; }

# Check if forecast is fresh (less than 30 minutes old)
checkforecast() {
	[ -s "$weatherreport" ] || return 1
	last_modified=$(stat -c %Y "$weatherreport" 2>/dev/null) || return 1
	now=$(date +%s)
	age=$((now - last_modified))
	[ "$age" -lt 1800 ]  # 1800 seconds = 30 minutes
}

getprecipchance() {
	precipdata=$(echo "$weatherdata" | sed '16q;d' | grep -wo "[0-9]*%" 2>/dev/null)
	if [ -n "$precipdata" ]; then
		echo "$precipdata" | sort -rn 2>/dev/null | head -1
	else
		echo "0%"
	fi
}

getdailyhighlow() {
	tempdata=$(echo "$weatherdata" | sed '13q;d' | grep -o "m\\([-+]\\)*[0-9]\\+" 2>/dev/null | sed 's/[+m]//g')
	if [ -n "$tempdata" ]; then
		echo "$tempdata" | sort -g 2>/dev/null | sed -e 1b -e '$!d'
	else
		echo "??"
		echo "??"
	fi
}

readfile() { weatherdata="$(cat "$weatherreport")" ;}

validateweather() {
	[ -z "$weatherdata" ] && return 1
	# Check if we can extract valid temp data
	tempdata=$(echo "$weatherdata" | sed '13q;d' | grep -o "m\\([-+]\\)*[0-9]\\+" | sed 's/[+m]//g')
	[ -z "$tempdata" ] && return 1
	return 0
}

showweather() {
	readfile

	# If data invalid, try fetching new data
	if ! validateweather; then
		getforecast 2>/dev/null || exit 0
		readfile
		# Still invalid after fetch? Exit silently
		validateweather || exit 0
	fi

	precip=$(getprecipchance)
	highlow=$(getdailyhighlow)
	low=$(echo "$highlow" | head -1)
	high=$(echo "$highlow" | tail -1)

	printf "󰖐 %s 󰜗 %s° 󰖙 %s°\n" "$precip" "$low" "$high"
}

case $BLOCK_BUTTON in
	1) setsid -f "$TERMINAL" -e less -Sf "$weatherreport" ;;
	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" ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

checkforecast || getforecast 2>/dev/null

showweather

D .local/bin/sb-help-icon => .local/bin/sb-help-icon +0 -17
@@ 1,17 0,0 @@
#!/bin/sh

# The clickable help menu. Middle click to restart wm.

# If dwm is running, use dwm's readme and restart.
pidof dwm >/dev/null &&
	READMEFILE=/usr/local/share/dwm/larbs.mom
	restartwm() { pkill -HUP dwm ;} ||
		restartwm() { i3 restart ;}

case $BLOCK_BUTTON in
	1) groff -mom "${READMEFILE:-${XDG_DATA_HOME:-$HOME/.local/share}/larbs/readme.mom}" -Tpdf | zathura - ;;
	2) restartwm ;;
	3) notify-send "❓ Help module" "\- Left click to open LARBS guide.
- Middle click to refresh window manager." ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac; echo "❓"

D .local/bin/sb-internet => .local/bin/sb-internet +0 -33
@@ 1,33 0,0 @@
#!/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) "$TERMINAL" -e nmtui; pkill -RTMIN+4 dwmblocks ;;
	3) notify-send "󰖩 Internet module" "\- Click to connect
󰖪: wifi disabled
󰤭: no wifi connection
󰖩: wifi connection with quality
󰈂: no ethernet
󰈀: ethernet working
󰌆: vpn is active
" ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

# Wifi
if [ "$(cat /sys/class/net/w*/operstate 2>/dev/null)" = 'up' ] ; then
	wifiicon="$(awk '/^\s*w/ { print "󰖩 ", int($3 * 100 / 70) "% " }' /proc/net/wireless)"
elif [ "$(cat /sys/class/net/w*/operstate 2>/dev/null)" = 'down' ] ; then
	[ "$(cat /sys/class/net/w*/flags 2>/dev/null)" = '0x1003' ] && wifiicon="󰤭  " || wifiicon="󰖪  "
fi

# Ethernet
[ "$(cat /sys/class/net/e*/operstate 2>/dev/null)" = 'up' ] && ethericon="󰈀 " || ethericon="󰈂 "

# TUN
[ -n "$(cat /sys/class/net/tun*/operstate 2>/dev/null)" ] && tunicon=" 󰌆"

printf "%s%s%s\n" "$wifiicon" "$ethericon" "$tunicon"

D .local/bin/sb-iplocate => .local/bin/sb-iplocate +0 -15
@@ 1,15 0,0 @@
#!/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="$(grep "flag: $name" "${XDG_DATA_HOME:-$HOME/.local/share}/larbs/emoji")"
flag="${flag%% *}"
printf "%s %s\\n" "$flag" "$name"

D .local/bin/sb-kbselect => .local/bin/sb-kbselect +0 -17
@@ 1,17 0,0 @@
#!/bin/sh
# works on any init system
# requirements: dmenu, xorg-setxkbmap
kb="$(setxkbmap -query | grep -oP 'layout:\s*\K\w+')" || exit 1

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 | dmenu -l 15)"
	[ -z "$kb_choice" ] && exit 0
	kb="$(echo "$kb_choice" | awk '{print $3}')"
	setxkbmap "$kb"
	pkill -RTMIN+30 "${STATUSBAR:-dwmblocks}";;
	3) notify-send "⌨  Keyboard/language module" "$(printf "%s" "\- Current layout: $(setxkbmap -query | grep -oP 'layout:\s*\K\w+')")
- Left click to change keyboard.";;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

echo "$kb"

D .local/bin/sb-mailbox => .local/bin/sb-mailbox +0 -20
@@ 1,20 0,0 @@
#!/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:-dwmblocks}" ;;
	2) setsid -f mw -Y >/dev/null ;;
	3) notify-send "󰇰 Mail module" "\- Shows unread mail
- Shows 󰑓 if syncing mail
- Left click opens neomutt
- Middle click syncs mail" ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

unread="$(find "${XDG_DATA_HOME:-$HOME/.local/share}"/mail/*/[Ii][Nn][Bb][Oo][Xx]/new/* -type f | wc -l 2>/dev/null)"

pidof mbsync >/dev/null 2>&1 && icon="󰑓"

[ "$unread" = "0" ] && [ "$icon" = "" ] || echo "󰇰 $unread$icon"

D .local/bin/sb-memory => .local/bin/sb-memory +0 -12
@@ 1,12 0,0 @@
#!/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 ;;
	3) notify-send "🧠 Memory module" "\- Shows Memory Used/Total.
- Click to show memory hogs.
- Middle click to open btop." ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

free --mebi | sed -n '2{p;q}' | awk '{printf ("🧠%2.2fGiB/%2.2fGiB\n", ( $3 / 1024), ($2 / 1024))}'

D .local/bin/sb-moonphase => .local/bin/sb-moonphase +0 -37
@@ 1,37 0,0 @@
#!/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="$(cat "$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" ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

D .local/bin/sb-mpdup => .local/bin/sb-mpdup +0 -8
@@ 1,8 0,0 @@
#!/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 "${STATUSBAR:-dwmblocks}")" || break
done

D .local/bin/sb-music => .local/bin/sb-music +0 -19
@@ 1,19 0,0 @@
#!/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 ncmpcpp ;;  # 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 ncmpcpp.
- Middle click pauses.
- Scroll changes track.";;  # right click, pause/unpause
	4) mpc prev   | filter ;;  # scroll up, previous
	5) mpc next   | filter ;;  # scroll down, next
	6) mpc status | filter ; setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
	*) mpc status | filter ;;
esac

D .local/bin/sb-nettraf => .local/bin/sb-nettraf +0 -29
@@ 1,29 0,0 @@
#!/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
	1) setsid -f "$TERMINAL" -e bmon ;;
	3) notify-send "󰛴 Network traffic module" "󱚶: Traffic received
󱚺: Traffic transmitted" ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
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)

D .local/bin/sb-news => .local/bin/sb-news +0 -17
@@ 1,17 0,0 @@
#!/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" -e newsboat ;;
	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." ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

 cat /tmp/newsupdate 2>/dev/null || echo "$(newsboat -x print-unread | awk '{ if($1>0) print "󰑬 " $1}')$(cat "${XDG_CONFIG_HOME:-$HOME/.config}"/newsboat/.update 2>/dev/null)"

D .local/bin/sb-ocean => .local/bin/sb-ocean +0 -0
D .local/bin/sb-pacpackages => .local/bin/sb-pacpackages +0 -29
@@ 1,29 0,0 @@
#!/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 i3blocks if using i3.

case $BLOCK_BUTTON in
	1) setsid -f "$TERMINAL" -e sb-popupgrade ;;
	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" ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

pacman -Qu | grep -Fcv "[ignored]" | sed "s/^/󰮯 /;s/^󰮯 0$//g"

D .local/bin/sb-playerctl => .local/bin/sb-playerctl +0 -39
@@ 1,39 0,0 @@
#!/bin/sh

# playerctl loop ensures that when a track is skipped in the music player itself, it still updates on bar
pidof -x playerctl-loop >/dev/null 2>&1 || playerctl-loop >/dev/null 2>&1 &

# format state to alternate between artist - title and album - title
FORMAT_FILE="/tmp/dwmblocks_mus_format"
[ ! -f "$FORMAT_FILE" ] && echo "0" > "$FORMAT_FILE"
read FORMAT < "$FORMAT_FILE"

# priority is: if browser or mpv are playing, they will display. otherwise, mpd displays, playing or paused.
# browser and mpv should never display if paused.
if [ -z "$MUSIC_PLAYING_PLAYERS" ]; then
    # if MUSIC_PLAYING_PLAYERS is not set, use the default players
    MUSIC_PLAYING_PLAYERS="chromium mpd mpv"
fi

[ "$FORMAT" -eq 0 ] && META="{{ trunc(artist,17) }} - {{ trunc(title,17) }}" || META="{{ trunc(album,17) }} - {{ trunc(title,17) }}"

for PLAYER in $MUSIC_PLAYING_PLAYERS; do
# if the player is not playing, continue to the next player, until we find one that is playing
    [ "$(playerctl --player=$PLAYER status 2>/dev/null)" != "Playing" ] && continue
        ICON=" "
        echo "$ICON"$(playerctl metadata --player $PLAYER --format "$META")
done

# just display what's paused in mpd, in case nothing is playing
ICON="❚❚ "
echo "$ICON"$(playerctl metadata --player mpd --format "$META")


case $BLOCK_BUTTON in
        1) echo "$(( ($FORMAT + 1) % 2 ))" > "$FORMAT_FILE" ;;
        2) playerctl --player mpd play-pause; pkill -RTMIN+11 "${STATUSBAR:-dwmblocks}" ;;
        3) setsid -w -f "$TERMINAL" -e pulsemixer; pkill -RTMIN+11 "${STATUSBAR:-dwmblocks}" ;;
        4) amixer -D pulse sset Master 10%+ ;;
        5) amixer -D pulse sset Master 10%- ;;
        6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

D .local/bin/sb-popupgrade => .local/bin/sb-popupgrade +0 -9
@@ 1,9 0,0 @@
#!/bin/sh

printf "Beginning upgrade.\\n"

yay -Syu
pkill -RTMIN+8 "${STATUSBAR:-dwmblocks}"

printf "\\nUpgrade complete.\\nPress <Enter> to exit window.\\n\\n"
read -r _

D .local/bin/sb-price => .local/bin/sb-price +0 -58
@@ 1,58 0,0 @@
#!/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="€" ;;
	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 %x "$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 "$TERMINAL" -e less -Srf "$chartfile" ;;
	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: \$$(cat "$pricefile")</b>
- Left click for chart of changes.
- Middle click to update.
- Shows 🔃 if updating prices.
- <b>Last updated:
	$uptime</b>" ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

[ -n "$updateme" ] &&
	updateprice "$target" &&
	[ -n "$showupdate" ] &&
	notify-send "$icon Update complete." "$name price is now
\$$(cat "$pricefile")"

[ -f "$pricefile" ] && printf "%s%s%0.2f" "$icon" "$symb" "$(cat "$pricefile")"

D .local/bin/sb-tasks => .local/bin/sb-tasks +0 -20
@@ 1,20 0,0 @@
#!/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 ;;
	3) notify-send "Tasks module" "🤖: number of running/queued background tasks
- Left click opens tsp" ;; # Right click
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

[ "$num" != "0(0)" ] &&
	echo "🤖$num"

D .local/bin/sb-temps => .local/bin/sb-temps +0 -78
@@ 1,78 0,0 @@
#!/usr/bin/env bash

# Sensor info
echo "Available sensors:" > /tmp/dwmblocks_debug.log
sensors >> /tmp/dwmblocks_debug.log
echo "---" >> /tmp/dwmblocks_debug.log


CPU_TEMP=$(sensors | awk '
    /^Tdie|^Package id|^Core 0|^CPU|^temp1/ {
        gsub(/[+°C]/, "");
        for (i=1; i<=NF; i++) {
            if ($i ~ /^[0-9]+(\.[0-9]+)?$/) {
        gsub(/\..*/, "", $i);
                print $i;
                exit;
            }
        }
    }')

# Debug CPU temperature detection, if not found, return N/A
if [ -z "$CPU_TEMP" ]; then
    # Try simpler pattern as fallback
    CPU_TEMP=$(sensors | grep -E '^(Core 0|Package id 0|CPU)' | awk '{print $3}' | tr -d '+°C' | head -n1)
fi

[ -z "$CPU_TEMP" ] && CPU_TEMP="N/A"
echo "CPU_TEMP=$CPU_TEMP" >> /tmp/dwmblocks_debug.log


# Try different GPU temperature sensors (AMD and NVIDIA), if not found, return N/A
if command -v nvidia-smi >/dev/null 2>&1; then
    # NVIDIA GPU
    GPU_TEMP=$(nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader)
else
    # AMD GPU
    GPU_TEMP=$(sensors | awk '/^edge|^junction/ {gsub(/\+/,""); gsub(/\..*/,"",$2); print $2}')
fi

[ -z "$GPU_TEMP" ] && GPU_TEMP="N/A"


# Try different fan sensors
FAN_SPEED=$(sensors | awk '/^fan|^cpu_fan/ {print $2" "$3}')
[ -z "$FAN_SPEED" ] && FAN_SPEED="N/A"


# Memory and CPU usage
MEM_USE=$(free -m | awk '/^Mem/ {printf "%.1f", ($3)/1024}')
CPU_USE=$(iostat -c | awk '/avg-cpu:/{getline; print "User CPU: "$1"%\n\nSystem CPU: "$3"%"}')


# Show warning icon if CPU or GPU temp are high
case $CPU_TEMP in
    "N/A") COLOR="#d8dee9" && CPU_ICON="󰍛 ?" ;;
    [7-9][6-9]|[8-9][0-9]|100) COLOR="#bf616a" && CPU_ICON="" ;;  # Greater than 75
    [6][6-9]|7[0-5]) COLOR="#ebcb8b" && CPU_ICON="󰍛" ;;            # Between 66 and 75
    *) COLOR="#a3be8c" && CPU_ICON="󰍛" ;;                          # 65 or below
esac

case $GPU_TEMP in
    "N/A") GPU_ICON="󰢮 ?" ;;
    [7-9][1-9]|[8-9][0-9]|100) GPU_ICON="" ;;  # Greater than 71
    [5][1-9]|70) GPU_ICON="󰢮" ;;                # Between 51 and 70
    *) GPU_ICON="󰢮" ;;                          # 50 or below
esac


# Send to bar
echo " $GPU_ICON $GPU_TEMP°C  $CPU_ICON $CPU_TEMP°C   ${MEM_USE}g"


# Clicking on bar
case $BLOCK_BUTTON in
        1) setsid -w -f "$TERMINAL" -e btop ;;
        3) notify-send -t 10000 -h string:bgcolor:$COLOR Stats "$CPU_USE\n\nGPU: $GPU_TEMP°C\n\nFan Speed: $FAN_SPEED" ;;
        6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

D .local/bin/sb-ticker => .local/bin/sb-ticker +0 -50
@@ 1,50 0,0 @@
#!/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="$(cat "$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" | grep -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" ;;
    2) notify-send -u low "Updating..." "Updating prices" ; updateme="1" ;;
    3) notify-send "Current prices:" "Current stock prices:\n<b>$(getchange)</b>

LEFT MOUSE BUTTON: show price file
MIDDLE MOUSE BUTTON: update stock prices
RIGHT MOUSE BUTTON: Get stock overview" ;;
    6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

[ -n "$updateme" ] && updateprice

[ -f "$pricefile" ] && getchange

checkprice && updateprice

D .local/bin/sb-torrent => .local/bin/sb-torrent +0 -17
@@ 1,17 0,0 @@
#!/bin/sh

# Torrent status module using rtorrent
# Shows rtorrent status if running

case $BLOCK_BUTTON in
	1) setsid -f "$TERMINAL" -e rtorrent ;;
	3) notify-send "󰦗 Torrent module" "\- Left click to open rtorrent.
- Shows 󰦗 if rtorrent is running.
- Shift+click to edit script." ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

# Check if rtorrent is running
if pidof rtorrent >/dev/null 2>&1; then
	echo "󰦗"
fi

D .local/bin/sb-volume => .local/bin/sb-volume +0 -39
@@ 1,39 0,0 @@
#!/bin/sh

# Prints the current volume or 󰝟 if muted.

case $BLOCK_BUTTON in
	1) setsid -w -f "$TERMINAL" -e pulsemixer; pkill -RTMIN+10 "${STATUSBAR:-dwmblocks}" ;;
	2) wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle ;;
	4) wpctl set-volume @DEFAULT_AUDIO_SINK@ 1%+ ;;
	5) wpctl set-volume @DEFAULT_AUDIO_SINK@ 1%- ;;
	3) notify-send "󰕾 Volume module" "\- Shows volume 󰕾, 󰝟 if muted.
- Middle click to mute.
- Scroll to change." ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
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%"

R .local/bin/htb => .local/bin/security/htb +1 -1
@@ 1,4 1,4 @@
#!/bin/sh
#!/bin/bash
# ==============================================================
#  HTB Writeup Scaffolder (htb)
# --------------------------------------------------------------

R .local/bin/htbvpn => .local/bin/security/htbvpn +1 -1
@@ 6,7 6,7 @@
#=============================================================================
# CONFIGURATION - Set these paths
#=============================================================================
DOWNLOADS_DIR="$HOME/Downloads"
DOWNLOADS_DIR="$HOME/downloads"
HTB_VPN_DIR="$HOME/.config/htb"
VPN_FILE="htb.ovpn"


R .local/bin/otp => .local/bin/security/otp +0 -0
R .local/bin/shred => .local/bin/security/shred +0 -0
A .local/bin/security/surf => .local/bin/security/surf +0 -0
R .local/bin/torwrap => .local/bin/security/torwrap +0 -0
M .local/bin/statusbar/sb-battery => .local/bin/statusbar/sb-battery +37 -42
@@ 1,60 1,55 @@
#!/bin/sh

# Prints all batteries, their percentage remaining and an icon corresponding
# to charge level. Uses Nerd Font battery icons.
# Prints all batteries, their percentage remaining and a Nerd Font icon
# corresponding to charge status and level.

case $BLOCK_BUTTON in
	3) notify-send " Battery module" ": discharging
: charging
: charged
- Scroll to adjust xbacklight." ;;
	3) notify-send "󰁹 Battery module" "󰁹: full
󰂁: discharging
󰂄: charging
󰂃: not charging
󰂎: empty
󱃍: battery very low!
- Scroll to change adjust xbacklight." ;;
	4) xbacklight -inc 10 ;;
	5) xbacklight -dec 10 ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

# Get battery level icon based on percentage
# full= (f240), 3/4= (f241), half= (f242), quarter= (f243)
# 20%=󰁻 (f007b), 10%=󰁺 (f007a), empty= (f244)
get_battery_icon() {
	if [ "$1" -ge 95 ]; then
		echo ""
	elif [ "$1" -ge 65 ]; then
		echo ""
	elif [ "$1" -ge 40 ]; then
		echo ""
	elif [ "$1" -ge 25 ]; then
		echo ""
	elif [ "$1" -ge 10 ]; then
		echo "󰁻"
	elif [ "$1" -ge 5 ]; then
		echo "󰁺"
	else
		echo ""
	fi
}

# Exit silently if no battery exists (desktop)
[ ! -d /sys/class/power_supply/BAT0 ] && [ ! -d /sys/class/power_supply/BAT1 ] && exit 0

# 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
	capacity="$(cat "$battery/capacity" 2>&1)"
	status="$(cat "$battery/status" 2>&1)"

	# Get icon based on battery level
	icon=$(get_battery_icon "$capacity")

	# Add charging indicator
	case "$status" in
		"Charging") charge_indicator=" " ;;
		"Full") charge_indicator=" " ;;
		*) charge_indicator="" ;;
	charging_status="$(cat "$battery/status" 2>&1)"

	case "$charging_status" in
		"Full") status="󰁹" ;;
		"Charging") status="󰂄" ;;
		"Not charging") status="󰂃" ;;
		"Discharging")
			if [ "$capacity" -ge 95 ]; then
				status="󰁹"
			elif [ "$capacity" -ge 65 ]; then
				status="󰂀"
			elif [ "$capacity" -ge 40 ]; then
				status="󰁾"
			elif [ "$capacity" -ge 25 ]; then
				status="󰁼"
			elif [ "$capacity" -ge 10 ]; then
				status="󰁻"
			elif [ "$capacity" -ge 5 ]; then
				status="󰁺"
			else
				status="󰂎"
			fi
			;;
		"Unknown") status="󰂑" ;;
		*) exit 1 ;;
	esac

	# Will make a warn variable if discharging and low
	[ "$charging_status" = "Discharging" ] && [ "$capacity" -le 25 ] && warn="󱃍"
	# Prints the info
	printf "%s %d%%%s" "$icon" "$capacity" "$charge_indicator"
	printf "%s%s %d%%" "$status" "$warn" "$capacity"; unset warn
done && printf "\\n"

M .local/bin/statusbar/sb-clock => .local/bin/statusbar/sb-clock +3 -3
@@ 1,6 1,5 @@
#!/bin/sh

# Clock with time-based Nerd Font icons
clock=$(date '+%I')

case "$clock" in


@@ 16,14 15,15 @@ case "$clock" in
	"09") icon="󱑇" ;;
	"10") icon="󱑈" ;;
	"11") icon="󱑉" ;;
	"00") 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 ;;
	3) notify-send "$icon Time/date module" "\- Left click to show upcoming appointments for the next three days via \`calcurse -d3\` and show the month via \`cal\`
	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" ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

date "+%Y %b %d (%a) $icon%I:%M%p"
TZ="America/Chicago" date "+%Y.%m.%d (%a) $icon %I:%M%p"

M .local/bin/statusbar/sb-dashboard => .local/bin/statusbar/sb-dashboard +8 -7
@@ 1,27 1,28 @@
#!/bin/sh

# Ensure eww daemon is running
pgrep -x eww >/dev/null 2>&1 || eww daemon &
pgrep -x eww >/dev/null 2>&1 || eww daemon >/dev/null 2>&1 &

WINDOW="performance_monitor"
OVERLAY="dashboard_overlay"

# Display distro-specific icon in status bar
# Arch: 󰣇 (f08c7), Gentoo:  (e7e6), Other:  (eb51)
# Display distro-specific Nerd Font icon in status bar
if [ -f /etc/arch-release ]; then
    printf '󰣇\n'
	printf '󰣇 \n'
elif [ -f /etc/gentoo-release ]; then
    printf '\n'
	printf ' \n'
else
    printf '\n'
	printf ' \n'
fi

case $BLOCK_BUTTON in
	1)
		if eww active-windows 2>/dev/null | grep -q "$WINDOW"; then
			eww update performance_monitor_visible=false
			eww close "$WINDOW"
			eww close "$WINDOW" "$OVERLAY"
		else
			eww update performance_monitor_visible=true
			eww open "$OVERLAY"
			eww open "$WINDOW"
		fi
		;;

M .local/bin/statusbar/sb-disk => .local/bin/statusbar/sb-disk +18 -27
@@ 1,35 1,26 @@
#!/usr/bin/env bash
#!/bin/sh

# Disk usage with 󰋊 icon (f02ca)
# Status bar module for disk space
# Automatically detects /home if separate partition, otherwise uses /
# Can override with $1 argument

# Array of disks to monitor
DISKS=("/" "/home")
# Smart default: use /home if it's a separate partition, else /
if [ -n "$1" ]; then
    location="$1"
elif df /home 2>/dev/null | grep -q "^/dev" && [ "$(df / --output=source | tail -1)" != "$(df /home --output=source | tail -1)" ]; then
    location="/home"
else
    location="/"
fi

# Define a file to save current disk and format
DISKS_FILE="/tmp/dwmblocks_disk_info"
[ -f "$DISKS_FILE" ] || echo "0 0" > "$DISKS_FILE"
[ -d "$location" ] || exit

# Read INDEX number and FORMAT number from the file
read INDEX FORMAT < "$DISKS_FILE"

# Set the current disk
CURRENT_DISK="${DISKS[$INDEX]}"

# Pull usage % and space remaining
PERCENT=$(df -h "$CURRENT_DISK" | awk 'NR==2 {print $5}')
SPACE=$(df -h "$CURRENT_DISK" | awk 'NR==2 {print $4}')

# If format is 0, display usage %, otherwise, space remaining
[ "$FORMAT" -eq 0 ] && INFO="$PERCENT" || INFO="$SPACE"

# Click handlers
case $BLOCK_BUTTON in
    1) notify-send -t 60000 "$(dysk --color no -c free+mp+use+size)" ;;
    3) echo "$INDEX $(( ($FORMAT + 1) % 2 ))" > "$DISKS_FILE" ;;
    4) echo "$(( ($INDEX + 1) % ${#DISKS[@]} )) $FORMAT" > "$DISKS_FILE" ;;
    5) echo "$(( ($INDEX - 1) % ${#DISKS[@]} )) $FORMAT" > "$DISKS_FILE" ;;
    1) notify-send "󰋊 Disk space" "$(df -h --output=target,used,size,avail,pcent /home / 2>/dev/null | head -5)" ;;
    3) notify-send "󰋊 Disk module" "Shows disk space for $location
- Left click for full disk info
- Currently monitoring: $location" ;;
    6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

# Send to bar with 󰋊 (f02ca) icon
echo "󰋊 $INFO"
printf "󰋊  %s\n" "$(df -h "$location" | awk '/[0-9]/ {print $3 "/" $2}')"

M .local/bin/statusbar/sb-doppler => .local/bin/statusbar/sb-doppler +1 -1
@@ 236,4 236,4 @@ After $secs seconds, new clicks will also automatically update the doppler RADAR
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

echo "󰐷"
echo "󰐷 "

M .local/bin/statusbar/sb-forecast => .local/bin/statusbar/sb-forecast +13 -39
@@ 1,7 1,7 @@
#!/bin/sh

# Weather forecast with Nerd Font icons
# Uses wttr.in weather codes to determine icon
# 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"


@@ 18,32 18,6 @@ checkforecast() {
	[ "$age" -lt 1800 ]  # 1800 seconds = 30 minutes
}

# Get weather icon based on wttr.in output
# Weather conditions from line 3 of the report
getweathericon() {
	condition=$(echo "$weatherdata" | sed '3q;d' | tr '[:upper:]' '[:lower:]')

	case "$condition" in
		*thunder*rain*|*storm*)  echo "󰙾" ;;  # lightning_rainy
		*thunder*|*lightning*)   echo "󰖓" ;;  # lightning
		*snow*rain*|*sleet*)     echo "󰙿" ;;  # snowy_rainy
		*heavy*snow*)            echo "󰼶" ;;  # partly_snowy_heavy
		*snow*)                  echo "󰖘" ;;  # snowy
		*heavy*rain*|*pour*)     echo "󰖖" ;;  # pouring
		*rain*|*drizzle*)        echo "󰖗" ;;  # rainy
		*hail*)                  echo "󰖒" ;;  # hail
		*fog*|*mist*)            echo "󰖑" ;;  # fog
		*haz*)                   echo "󰼰" ;;  # hazy
		*tornado*)               echo "󰼸" ;;  # tornado
		*hurricane*)             echo "󰢘" ;;  # hurricane
		*wind*)                  echo "󰖝" ;;  # windy
		*partly*cloud*|*overcast*) echo "󰖕" ;;  # partly_cloudy
		*cloud*)                 echo "󰖐" ;;  # cloudy
		*sun*|*clear*)           echo "󰖙" ;;  # sunny
		*)                       echo "󰖕" ;;  # default: partly_cloudy
	esac
}

getprecipchance() {
	precipdata=$(echo "$weatherdata" | sed '16q;d' | grep -wo "[0-9]*%" 2>/dev/null)
	if [ -n "$precipdata" ]; then


@@ 67,7 41,8 @@ readfile() { weatherdata="$(cat "$weatherreport")" ;}

validateweather() {
	[ -z "$weatherdata" ] && return 1
	tempdata=$(echo "$weatherdata" | sed '13q;d' | grep -o "m\\([-+]\\)*[0-9]\\+" 2>/dev/null | sed 's/[+m]//g')
	# Check if we can extract valid temp data
	tempdata=$(echo "$weatherdata" | sed '13q;d' | grep -o "m\\([-+]\\)*[0-9]\\+" | sed 's/[+m]//g')
	[ -z "$tempdata" ] && return 1
	return 0
}


@@ 79,27 54,26 @@ showweather() {
	if ! validateweather; then
		getforecast 2>/dev/null || exit 0
		readfile
		# Still invalid after fetch? Exit silently
		validateweather || exit 0
	fi

	icon=$(getweathericon)
	precip=$(getprecipchance)
	temps=$(getdailyhighlow)
	low=$(echo "$temps" | head -1)
	high=$(echo "$temps" | tail -1)

	# Don't show if we got placeholder data
	echo "$temps" | grep -q "??" && exit 0
	highlow=$(getdailyhighlow)
	low=$(echo "$highlow" | head -1)
	high=$(echo "$highlow" | tail -1)

	printf "%s %s° %s°\n" "$icon" "$low" "$high"
	printf "󰖐 %s 󰜗 %s° 󰖙 %s°\n" "$precip" "$low" "$high"
}

case $BLOCK_BUTTON in
	1) setsid -f "$TERMINAL" -e less -Sf "$weatherreport" ;;
	2) getforecast && showweather ;;
	3) notify-send "󰖙 Weather module" "\- Left click for full forecast.
	3) notify-send "󰖐 Weather module" "\- Left click for full forecast.
- Middle click to update forecast.
- Shows current conditions with temp range" ;;
󰖐: Chance of rain/snow
󰜗: Daily low
󰖙: Daily high" ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac


M .local/bin/statusbar/sb-help-icon => .local/bin/statusbar/sb-help-icon +1 -1
@@ 9,7 9,7 @@ pidof dwm >/dev/null &&
		restartwm() { i3 restart ;}

case $BLOCK_BUTTON in
	1) groff -mom "${READMEFILE:-${XDG_DATA_HOME:-$HOME/.local/share}/larbs/readme.mom}" -Tpdf | zathura - ;;
	1) groff -mom "${READMEFILE:-${XDG_DATA_HOME:-$HOME/.local/share}/lazykris/readme.mom}" -Tpdf | zathura - ;;
	2) restartwm ;;
	3) notify-send "❓ Help module" "\- Left click to open LARBS guide.
- Middle click to refresh window manager." ;;

M .local/bin/statusbar/sb-internet => .local/bin/statusbar/sb-internet +23 -11
@@ 1,21 1,33 @@
#!/bin/sh

# Show internet connection status with 󰖩 (f05a9) icon
# 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) "$TERMINAL" -e nmtui; pkill -RTMIN+4 dwmblocks ;;
	3) notify-send "󰖩 Internet module" "\- Click to connect
- Shows connection quality percentage" ;;
󰖪: wifi disabled
󰤭: no wifi connection
󰖩: wifi connection with quality
󰈂: no ethernet
󰈀: ethernet working
󰌆: vpn is active
" ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

# Check wifi
if [ "$(cat /sys/class/net/w*/operstate 2>/dev/null)" = 'up' ]; then
	quality=$(awk '/^\s*w/ { print int($3 * 100 / 70) }' /proc/net/wireless)
	printf "󰖩 %s%%\n" "$quality"
# Check ethernet
elif [ "$(cat /sys/class/net/e*/operstate 2>/dev/null)" = 'up' ]; then
	printf "󰖩\n"
else
	printf "󰖩 --\n"
# Wifi
if [ "$(cat /sys/class/net/w*/operstate 2>/dev/null)" = 'up' ] ; then
	wifiicon="$(awk '/^\s*w/ { print "󰖩 ", int($3 * 100 / 70) "% " }' /proc/net/wireless)"
elif [ "$(cat /sys/class/net/w*/operstate 2>/dev/null)" = 'down' ] ; then
	[ "$(cat /sys/class/net/w*/flags 2>/dev/null)" = '0x1003' ] && wifiicon="󰤭  " || wifiicon="󰖪  "
fi

# Ethernet
[ "$(cat /sys/class/net/e*/operstate 2>/dev/null)" = 'up' ] && ethericon="󰈀 " || ethericon="󰈂 "

# TUN
[ -n "$(cat /sys/class/net/tun*/operstate 2>/dev/null)" ] && tunicon=" 󰌆"

printf "%s%s%s\n" "$wifiicon" "$ethericon" "$tunicon"

M .local/bin/statusbar/sb-iplocate => .local/bin/statusbar/sb-iplocate +1 -1
@@ 10,6 10,6 @@ set -e
ifinstalled "geoip"
addr="$(geoiplookup "$(curl -sfm 1 ifconfig.me 2>/dev/null)")"
name="${addr##*, }"
flag="$(grep "flag: $name" "${XDG_DATA_HOME:-$HOME/.local/share}/larbs/emoji")"
flag="$(grep "flag: $name" "${XDG_DATA_HOME:-$HOME/.local/share}/lazykris/emoji")"
flag="${flag%% *}"
printf "%s %s\\n" "$flag" "$name"

M .local/bin/statusbar/sb-mailbox => .local/bin/statusbar/sb-mailbox +7 -3
@@ 1,11 1,13 @@
#!/bin/sh
#!/bin/bash

# Displays number of unread mail with 󰇰 icon (f01f0)
# 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:-dwmblocks}" ;;
	2) setsid -f mw -Y >/dev/null ;;
	3) notify-send "󰇰 Mail module" "\- Shows unread mail
- Shows 󰑓 if syncing mail
- Left click opens neomutt
- Middle click syncs mail" ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;


@@ 13,4 15,6 @@ esac

unread="$(find "${XDG_DATA_HOME:-$HOME/.local/share}"/mail/*/[Ii][Nn][Bb][Oo][Xx]/new/* -type f | wc -l 2>/dev/null)"

[ "$unread" = "0" ] || echo "󰇰$unread"
pidof mbsync >/dev/null 2>&1 && icon="󰑓"

[ "$unread" = "0" ] && [ "$icon" = "" ] || echo "󰇰 $unread$icon"

M .local/bin/statusbar/sb-nettraf => .local/bin/statusbar/sb-nettraf +2 -3
@@ 3,11 3,10 @@
# 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.
# Icons: 󱚶 down (f16b6), 󱚺 up (f16ba)

case $BLOCK_BUTTON in
	1) setsid -f "$TERMINAL" -e bmon ;;
	3) notify-send "󱚶 Network traffic module" "󱚶: Traffic received
	3) notify-send "󰛴 Network traffic module" "󱚶: Traffic received
󱚺: Traffic transmitted" ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac


@@ 27,4 26,4 @@ update() {
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)
printf "󱚶 %4sB 󱚺 %4sB\\n" $(numfmt --to=iec $rx $tx)

M .local/bin/statusbar/sb-news => .local/bin/statusbar/sb-news +8 -5
@@ 1,14 1,17 @@
#!/bin/sh

# Displays number of unread news items with 󰑬 icon (f046c)
# Displays number of unread news items and an loading icon if updating.
# When clicked, brings up `newsboat`.

case $BLOCK_BUTTON in
	1) setsid "$TERMINAL" -e newsboat ;;
        1) setsid "$TERMINAL" -e newsboat ;;
	2) setsid -f newsup >/dev/null && exit ;;
	3) notify-send "󰑬 News module" "\- Shows unread news items
        3) notify-send "󰑬 News module" "\- Shows unread news items
- Shows 󰑓 if updating with \`newsup\`
- Left click opens newsboat
- Middle click syncs RSS feeds" ;;
- Middle click syncs RSS feeds
<b>Note:</b> Only one instance of newsboat (including updates) may be running at a time." ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

cat /tmp/newsupdate 2>/dev/null || echo "$(newsboat -x print-unread | awk '{ if($1>0) print "󰑬" $1}')"
 cat /tmp/newsupdate 2>/dev/null || echo "$(newsboat -x print-unread | awk '{ if($1>0) print "󰑬 " $1}')$(cat "${XDG_CONFIG_HOME:-$HOME/.config}"/newsboat/.update 2>/dev/null)"

M .local/bin/statusbar/sb-pacpackages => .local/bin/statusbar/sb-pacpackages +17 -2
@@ 1,6 1,21 @@
#!/bin/sh

# Displays number of upgradeable packages with 󰮯 icon (f0baf)
# 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 i3blocks if using i3.

case $BLOCK_BUTTON in
	1) setsid -f "$TERMINAL" -e sb-popupgrade ;;


@@ 11,4 26,4 @@ case $BLOCK_BUTTON in
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

pacman -Qu | grep -Fcv "[ignored]" | sed "s/^/󰮯/;s/^󰮯0$//g"
pacman -Qu | grep -Fcv "[ignored]" | sed "s/^/󰮯 /;s/^󰮯 0$//g"

R .local/bin/sb-surge => .local/bin/statusbar/sb-surge +1 -1
@@ 1,4 1,4 @@
#!/bin/sh
#!/bin/bash

# Status bar module for Surge download manager
# Shows daemon status on stargate (via tailscale) and active download count

R .local/bin/sb-systemstats => .local/bin/statusbar/sb-systemstats +0 -0
M .local/bin/statusbar/sb-temps => .local/bin/statusbar/sb-temps +45 -10
@@ 1,43 1,78 @@
#!/usr/bin/env bash

# Temperature module with  icon (f2c9)
# Sensor info
echo "Available sensors:" > /tmp/dwmblocks_debug.log
sensors >> /tmp/dwmblocks_debug.log
echo "---" >> /tmp/dwmblocks_debug.log


CPU_TEMP=$(sensors | awk '
    /^Tdie|^Package id|^Core 0|^CPU|^temp1/ {
        gsub(/[+°C]/, "");
        for (i=1; i<=NF; i++) {
            if ($i ~ /^[0-9]+(\.[0-9]+)?$/) {
                gsub(/\..*/, "", $i);
        gsub(/\..*/, "", $i);
                print $i;
                exit;
            }
        }
    }')

# Fallback if not found
# Debug CPU temperature detection, if not found, return N/A
if [ -z "$CPU_TEMP" ]; then
    # Try simpler pattern as fallback
    CPU_TEMP=$(sensors | grep -E '^(Core 0|Package id 0|CPU)' | awk '{print $3}' | tr -d '+°C' | head -n1)
fi

[ -z "$CPU_TEMP" ] && CPU_TEMP="N/A"
echo "CPU_TEMP=$CPU_TEMP" >> /tmp/dwmblocks_debug.log


# Try GPU temp (NVIDIA or AMD)
# Try different GPU temperature sensors (AMD and NVIDIA), if not found, return N/A
if command -v nvidia-smi >/dev/null 2>&1; then
    # NVIDIA GPU
    GPU_TEMP=$(nvidia-smi --query-gpu=temperature.gpu --format=csv,noheader)
else
    # AMD GPU
    GPU_TEMP=$(sensors | awk '/^edge|^junction/ {gsub(/\+/,""); gsub(/\..*/,"",$2); print $2}')
fi

[ -z "$GPU_TEMP" ] && GPU_TEMP="N/A"

# Memory usage

# Try different fan sensors
FAN_SPEED=$(sensors | awk '/^fan|^cpu_fan/ {print $2" "$3}')
[ -z "$FAN_SPEED" ] && FAN_SPEED="N/A"


# Memory and CPU usage
MEM_USE=$(free -m | awk '/^Mem/ {printf "%.1f", ($3)/1024}')
CPU_USE=$(iostat -c | awk '/avg-cpu:/{getline; print "User CPU: "$1"%\n\nSystem CPU: "$3"%"}')


# Show warning icon if CPU or GPU temp are high
case $CPU_TEMP in
    "N/A") COLOR="#d8dee9" && CPU_ICON="󰍛 ?" ;;
    [7-9][6-9]|[8-9][0-9]|100) COLOR="#bf616a" && CPU_ICON="" ;;  # Greater than 75
    [6][6-9]|7[0-5]) COLOR="#ebcb8b" && CPU_ICON="󰍛" ;;            # Between 66 and 75
    *) COLOR="#a3be8c" && CPU_ICON="󰍛" ;;                          # 65 or below
esac

case $GPU_TEMP in
    "N/A") GPU_ICON="󰢮 ?" ;;
    [7-9][1-9]|[8-9][0-9]|100) GPU_ICON="" ;;  # Greater than 71
    [5][1-9]|70) GPU_ICON="󰢮" ;;                # Between 51 and 70
    *) GPU_ICON="󰢮" ;;                          # 50 or below
esac


# Send to bar
echo " $GPU_ICON $GPU_TEMP°C  $CPU_ICON $CPU_TEMP°C   ${MEM_USE}g"

# Send to bar using  (f2c9) icon
echo "  ${CPU_TEMP}°C  ${MEM_USE}g"

# Clicking on bar
case $BLOCK_BUTTON in
    1) setsid -w -f "$TERMINAL" -e btop ;;
    3) notify-send " Temperature" "CPU: ${CPU_TEMP}°C\nGPU: ${GPU_TEMP}°C\nMemory: ${MEM_USE}GB" ;;
    6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
        1) setsid -w -f "$TERMINAL" -e btop ;;
        3) notify-send -t 10000 -h string:bgcolor:$COLOR Stats "$CPU_USE\n\nGPU: $GPU_TEMP°C\n\nFan Speed: $FAN_SPEED" ;;
        6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac

M .local/bin/statusbar/sb-torrent => .local/bin/statusbar/sb-torrent +4 -2
@@ 1,11 1,13 @@
#!/bin/sh

# Torrent status module with 󰦗 icon (f0997)
# Torrent status module using rtorrent
# Shows rtorrent status if running

case $BLOCK_BUTTON in
	1) setsid -f "$TERMINAL" -e rtorrent ;;
	3) notify-send "󰦗 Torrent module" "\- Left click to open rtorrent.
- Shows 󰦗 if rtorrent is running." ;;
- Shows 󰦗 if rtorrent is running.
- Shift+click to edit script." ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;
esac


M .local/bin/statusbar/sb-volume => .local/bin/statusbar/sb-volume +14 -15
@@ 1,14 1,13 @@
#!/bin/sh
#!/bin/bash

# Prints the current volume or mute icon.
# Icons: 󰝟 mute (f075f),  off (f026),  low (f027),  high (f028)
# Prints the current volume or 󰝟 if muted.

case $BLOCK_BUTTON in
	1) setsid -w -f "$TERMINAL" -e pulsemixer; pkill -RTMIN+10 "${STATUSBAR:-dwmblocks}" ;;
	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.
	2) wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle ;;
	4) wpctl set-volume @DEFAULT_AUDIO_SINK@ 1%+ ;;
	5) wpctl set-volume @DEFAULT_AUDIO_SINK@ 1%- ;;
	3) notify-send "󰕾 Volume module" "\- Shows volume 󰕾, 󰝟 if muted.
- Middle click to mute.
- Scroll to change." ;;
	6) setsid -f "$TERMINAL" -e "$EDITOR" "$0" ;;


@@ 16,13 15,13 @@ esac

vol="$(wpctl get-volume @DEFAULT_AUDIO_SINK@)"

# If muted, print mute icon and exit.
[ "$vol" != "${vol%\[MUTED\]}" ] && echo "󰝟" && exit
# If muted, print 󰝟 and exit.
[ "$vol" != "${vol%\[MUTED\]}" ] && echo 󰝟 && exit

vol="${vol#Volume: }"

split() {
	# For omitting the . without calling an external program.
	# For ommiting the . without calling and external program.
	IFS=$2
	set -- $1
	printf '%s' "$@"


@@ 31,10 30,10 @@ split() {
vol="$(printf "%.0f" "$(split "$vol" ".")")"

case 1 in
	$((vol >= 50)) ) icon="" ;;
	$((vol >= 25)) ) icon="" ;;
	$((vol >= 1)) ) icon="" ;;
	* ) echo "󰝟" && exit ;;
	$((vol >= 70)) ) icon="󰕾" ;;
	$((vol >= 30)) ) icon="󰖀" ;;
	$((vol >= 1)) ) icon="󰕿" ;;
	* ) echo 󰝟 && exit ;;
esac

echo "$icon$vol%"
echo "$icon $vol%"

R .local/bin/xdg-terminal-exec => .local/bin/system/CAPS +1 -2
@@ 1,3 1,2 @@
#!/bin/sh

"$TERMINAL" -e "$@"
xdotool key Caps_Lock 2>&1

R .local/bin/appinstall => .local/bin/system/appinstall +0 -0
A .local/bin/system/checkup => .local/bin/system/checkup +17 -0
@@ 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..."

sudo 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:-dwmblocks}"

if pacman -Qu | grep -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

R .local/bin/clean => .local/bin/system/clean +0 -0
A .local/bin/system/crontog => .local/bin/system/crontog +7 -0
@@ 0,0 1,7 @@
#!/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.")


R .local/bin/displayselect => .local/bin/system/displayselect +0 -0
R .local/bin/getcomproot => .local/bin/system/getcomproot +0 -0
R .local/bin/ifinstalled => .local/bin/system/ifinstalled +0 -0
R .local/bin/laptop => .local/bin/system/laptop +0 -0
R .local/bin/mounter => .local/bin/system/mounter +0 -0
A .local/bin/system/newsup => .local/bin/system/newsup +15 -0
@@ 0,0 1,15 @@
#!/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.

/usr/bin/notify-send "📰 Updating RSS feeds..."

pgrep -f newsboat$ && /usr/bin/xdotool key --window "$(/usr/bin/xdotool search --name "^newsboat$")" R && exit

echo 🔃 > /tmp/newsupdate
pkill -RTMIN+6 "${STATUSBAR:-dwmblocks}"
/usr/bin/newsboat -x reload
rm -f /tmp/newsupdate
pkill -RTMIN+6 "${STATUSBAR:-dwmblocks}"
/usr/bin/notify-send "📰 RSS feed update complete."

R .local/bin/ram => .local/bin/system/ram +0 -0
R .local/bin/sd => .local/bin/system/sd +0 -0
R .local/bin/shortcuts => .local/bin/system/shortcuts +0 -0
R .local/bin/sortfiles => .local/bin/system/sortfiles +2 -2
@@ 215,8 215,8 @@ main() {
  case "$ans" in
    [yY]|[yY][eE][sS])
      # call clean script if exists else run inline
      if [ -x "$HOME/.local/bin/clean" ]; then
        "$HOME/.local/bin/clean" "$MISC_BASE"
      if [ -x clean ]; then
        clean "$MISC_BASE"
      elif [ -x "/usr/local/bin/clean" ]; then
        "/usr/local/bin/clean" "$MISC_BASE"
      else

R .local/bin/sysact => .local/bin/system/sysact +0 -0
R .local/bin/trash => .local/bin/system/trash +0 -0
R .local/bin/unmounter => .local/bin/system/unmounter +0 -0
D .local/bin/tutorialvids => .local/bin/tutorialvids +0 -26
@@ 1,26 0,0 @@
#!/bin/sh

# This gives the user a list of videos they can select and watch without a
# browser. If you want to check a tutorial video, it makes it easy. I'll
# add/remove videos from this list as I go on.

vidlist="
dwm (window manager)	https://videos.lukesmith.xyz/videos/watch/f6b78db7-b368-4647-bc64-28c08fff1988
dwmblocks (status bar)	https://videos.lukesmith.xyz/w/mmxHMbqZZEr5FManB57Yy1
pacman (installing/managing programs)	https://videos.lukesmith.xyz/videos/watch/8e7cadb9-0fed-47ce-a2a8-6635fa48614b
sxiv/nsxiv (image viewer)	https://videos.lukesmith.xyz/videos/watch/ad4c8d85-90c3-4f3d-a1f3-89129e64a3c2
st (terminal)		https://videos.lukesmith.xyz/videos/watch/efddd39d-bac5-4599-b572-177beb4ce6e8
i3 (old window manager)	https://videos.lukesmith.xyz/videos/watch/b861525c-7ada-40ee-a2bb-b5e1ffe0f48b
neomutt (email)		https://videos.lukesmith.xyz/videos/watch/83122e83-52d9-4278-ae1a-7d1beeb50c8e
ncmpcpp (music player)	https://videos.lukesmith.xyz/videos/watch/b5ac6f0d-a220-4433-88e3-e98fc791dc0a
newsboat (RSS reader)	https://videos.lukesmith.xyz/videos/watch/bd2c3fff-40fa-47ea-aa98-5b1ec0c903b6
lf (file manager)	https://videos.lukesmith.xyz/w/rKeHsF5ZHDNDbR1buUKB1c
zathura (pdf viewer)	https://videos.lukesmith.xyz/videos/watch/c780f75a-11f6-48a9-a191-d079ebc36ea4
gpg keys		https://videos.lukesmith.xyz/videos/watch/040f5530-4830-4583-9ddc-2080b421531b
calcurse (calendar)	https://videos.lukesmith.xyz/videos/watch/4b937e8b-7654-46e3-8d01-79392ec5b3d1
urlview			https://videos.lukesmith.xyz/videos/watch/31a4918f-633b-4bd6-b08e-956ac75d0324
colorschemes with pywal	https://videos.lukesmith.xyz/videos/watch/1b476003-61b2-4609-ac4b-820c3d128643
vi mode in shell	https://videos.lukesmith.xyz/videos/watch/228aa50c-836f-456f-9f0d-a45157fe4313
pass (password manager)	https://videos.lukesmith.xyz/videos/watch/432fc942-5e28-4682-9beb-f5cb237a1dd6
"
echo "$vidlist" | grep -P "^$(echo "$vidlist" | grep "https:" | sed 's/\t.*//g' | dmenu -i -p "Learn about what? (ESC to cancel)" -l 20 | awk '{print $1}')\s" | sed 's/.*\t//' | xargs -r mpv

D .local/bin/warp => .local/bin/warp +0 -3
@@ 1,3 0,0 @@
#!/bin/sh
warp-terminal "$@" &>/dev/null &
disown

M .local/share/lazykris/bg => .local/share/lazykris/bg +1 -1
@@ 1,1 1,1 @@
lazykris-wallpaper.png
image3-1920x1080.webp

M .local/share/lazykris/chars/emoji => .local/share/lazykris/chars/emoji +2034 -9
@@ 40,11 40,14 @@
😑 expressionless face
😶 face without mouth
🫥 dotted line face
😶‍🌫️ face in clouds
😏 smirking face
😒 unamused face
🙄 face with rolling eyes
😬 grimacing face
😮‍💨 face exhaling
🤥 lying face
🫨 shaking face
😌 relieved face
😔 pensive face
😪 sleepy face


@@ 60,6 63,7 @@
🥶 cold face
🥴 woozy face
😵 face with crossed-out eyes
😵‍💫 face with spiral eyes
🤯 exploding head
🤠 cowboy hat face
🥳 partying face


@@ 94,7 98,7 @@
😫 tired face
🥱 yawning face
😤 face with steam from nose
😡 pouting face
😡 enraged face
😠 angry face
🤬 face with symbols on mouth
😈 smiling face with horns


@@ 121,7 125,6 @@
🙈 see-no-evil monkey
🙉 hear-no-evil monkey
🙊 speak-no-evil monkey
💋 kiss mark
💌 love letter
💘 heart with arrow
💝 heart with ribbon


@@ 133,15 136,21 @@
💟 heart decoration
❣️ heart exclamation
💔 broken heart
❤️‍🔥 heart on fire
❤️‍🩹 mending heart
❤️ red heart
🩷 pink heart
🧡 orange heart
💛 yellow heart
💚 green heart
💙 blue heart
🩵 light blue heart
💜 purple heart
🤎 brown heart
🖤 black heart
🩶 grey heart
🤍 white heart
💋 kiss mark
💯 hundred points
💢 anger symbol
💥 collision


@@ 149,61 158,328 @@
💦 sweat droplets
💨 dashing away
🕳️ hole
💣 bomb
💬 speech balloon
👁️‍🗨️ eye in speech bubble
🗨️ left speech bubble
🗯️ right anger bubble
💭 thought balloon
💤 zzz
💤 ZZZ
👋 waving hand
👋🏻 waving hand: light skin tone
👋🏼 waving hand: medium-light skin tone
👋🏽 waving hand: medium skin tone
👋🏾 waving hand: medium-dark skin tone
👋🏿 waving hand: dark skin tone
🤚 raised back of hand
🤚🏻 raised back of hand: light skin tone
🤚🏼 raised back of hand: medium-light skin tone
🤚🏽 raised back of hand: medium skin tone
🤚🏾 raised back of hand: medium-dark skin tone
🤚🏿 raised back of hand: dark skin tone
🖐️ hand with fingers splayed
🖐🏻 hand with fingers splayed: light skin tone
🖐🏼 hand with fingers splayed: medium-light skin tone
🖐🏽 hand with fingers splayed: medium skin tone
🖐🏾 hand with fingers splayed: medium-dark skin tone
🖐🏿 hand with fingers splayed: dark skin tone
✋ raised hand
✋🏻 raised hand: light skin tone
✋🏼 raised hand: medium-light skin tone
✋🏽 raised hand: medium skin tone
✋🏾 raised hand: medium-dark skin tone
✋🏿 raised hand: dark skin tone
🖖 vulcan salute
🖖🏻 vulcan salute: light skin tone
🖖🏼 vulcan salute: medium-light skin tone
🖖🏽 vulcan salute: medium skin tone
🖖🏾 vulcan salute: medium-dark skin tone
🖖🏿 vulcan salute: dark skin tone
🫱 rightwards hand
🫱🏻 rightwards hand: light skin tone
🫱🏼 rightwards hand: medium-light skin tone
🫱🏽 rightwards hand: medium skin tone
🫱🏾 rightwards hand: medium-dark skin tone
🫱🏿 rightwards hand: dark skin tone
🫲 leftwards hand
🫲🏻 leftwards hand: light skin tone
🫲🏼 leftwards hand: medium-light skin tone
🫲🏽 leftwards hand: medium skin tone
🫲🏾 leftwards hand: medium-dark skin tone
🫲🏿 leftwards hand: dark skin tone
🫳 palm down hand
🫳🏻 palm down hand: light skin tone
🫳🏼 palm down hand: medium-light skin tone
🫳🏽 palm down hand: medium skin tone
🫳🏾 palm down hand: medium-dark skin tone
🫳🏿 palm down hand: dark skin tone
🫴 palm up hand
🫴🏻 palm up hand: light skin tone
🫴🏼 palm up hand: medium-light skin tone
🫴🏽 palm up hand: medium skin tone
🫴🏾 palm up hand: medium-dark skin tone
🫴🏿 palm up hand: dark skin tone
🫷 leftwards pushing hand
🫷🏻 leftwards pushing hand: light skin tone
🫷🏼 leftwards pushing hand: medium-light skin tone
🫷🏽 leftwards pushing hand: medium skin tone
🫷🏾 leftwards pushing hand: medium-dark skin tone
🫷🏿 leftwards pushing hand: dark skin tone
🫸 rightwards pushing hand
🫸🏻 rightwards pushing hand: light skin tone
🫸🏼 rightwards pushing hand: medium-light skin tone
🫸🏽 rightwards pushing hand: medium skin tone
🫸🏾 rightwards pushing hand: medium-dark skin tone
🫸🏿 rightwards pushing hand: dark skin tone
👌 OK hand
👌🏻 OK hand: light skin tone
👌🏼 OK hand: medium-light skin tone
👌🏽 OK hand: medium skin tone
👌🏾 OK hand: medium-dark skin tone
👌🏿 OK hand: dark skin tone
🤌 pinched fingers
🤌🏻 pinched fingers: light skin tone
🤌🏼 pinched fingers: medium-light skin tone
🤌🏽 pinched fingers: medium skin tone
🤌🏾 pinched fingers: medium-dark skin tone
🤌🏿 pinched fingers: dark skin tone
🤏 pinching hand
🤏🏻 pinching hand: light skin tone
🤏🏼 pinching hand: medium-light skin tone
🤏🏽 pinching hand: medium skin tone
🤏🏾 pinching hand: medium-dark skin tone
🤏🏿 pinching hand: dark skin tone
✌️ victory hand
✌🏻 victory hand: light skin tone
✌🏼 victory hand: medium-light skin tone
✌🏽 victory hand: medium skin tone
✌🏾 victory hand: medium-dark skin tone
✌🏿 victory hand: dark skin tone
🤞 crossed fingers
🤞🏻 crossed fingers: light skin tone
🤞🏼 crossed fingers: medium-light skin tone
🤞🏽 crossed fingers: medium skin tone
🤞🏾 crossed fingers: medium-dark skin tone
🤞🏿 crossed fingers: dark skin tone
🫰 hand with index finger and thumb crossed
🫰🏻 hand with index finger and thumb crossed: light skin tone
🫰🏼 hand with index finger and thumb crossed: medium-light skin tone
🫰🏽 hand with index finger and thumb crossed: medium skin tone
🫰🏾 hand with index finger and thumb crossed: medium-dark skin tone
🫰🏿 hand with index finger and thumb crossed: dark skin tone
🤟 love-you gesture
🤟🏻 love-you gesture: light skin tone
🤟🏼 love-you gesture: medium-light skin tone
🤟🏽 love-you gesture: medium skin tone
🤟🏾 love-you gesture: medium-dark skin tone
🤟🏿 love-you gesture: dark skin tone
🤘 sign of the horns
🤘🏻 sign of the horns: light skin tone
🤘🏼 sign of the horns: medium-light skin tone
🤘🏽 sign of the horns: medium skin tone
🤘🏾 sign of the horns: medium-dark skin tone
🤘🏿 sign of the horns: dark skin tone
🤙 call me hand
🤙🏻 call me hand: light skin tone
🤙🏼 call me hand: medium-light skin tone
🤙🏽 call me hand: medium skin tone
🤙🏾 call me hand: medium-dark skin tone
🤙🏿 call me hand: dark skin tone
👈 backhand index pointing left
👈🏻 backhand index pointing left: light skin tone
👈🏼 backhand index pointing left: medium-light skin tone
👈🏽 backhand index pointing left: medium skin tone
👈🏾 backhand index pointing left: medium-dark skin tone
👈🏿 backhand index pointing left: dark skin tone
👉 backhand index pointing right
👉🏻 backhand index pointing right: light skin tone
👉🏼 backhand index pointing right: medium-light skin tone
👉🏽 backhand index pointing right: medium skin tone
👉🏾 backhand index pointing right: medium-dark skin tone
👉🏿 backhand index pointing right: dark skin tone
👆 backhand index pointing up
👆🏻 backhand index pointing up: light skin tone
👆🏼 backhand index pointing up: medium-light skin tone
👆🏽 backhand index pointing up: medium skin tone
👆🏾 backhand index pointing up: medium-dark skin tone
👆🏿 backhand index pointing up: dark skin tone
🖕 middle finger
🖕🏻 middle finger: light skin tone
🖕🏼 middle finger: medium-light skin tone
🖕🏽 middle finger: medium skin tone
🖕🏾 middle finger: medium-dark skin tone
🖕🏿 middle finger: dark skin tone
👇 backhand index pointing down
👇🏻 backhand index pointing down: light skin tone
👇🏼 backhand index pointing down: medium-light skin tone
👇🏽 backhand index pointing down: medium skin tone
👇🏾 backhand index pointing down: medium-dark skin tone
👇🏿 backhand index pointing down: dark skin tone
☝️ index pointing up
☝🏻 index pointing up: light skin tone
☝🏼 index pointing up: medium-light skin tone
☝🏽 index pointing up: medium skin tone
☝🏾 index pointing up: medium-dark skin tone
☝🏿 index pointing up: dark skin tone
🫵 index pointing at the viewer
🫵🏻 index pointing at the viewer: light skin tone
🫵🏼 index pointing at the viewer: medium-light skin tone
🫵🏽 index pointing at the viewer: medium skin tone
🫵🏾 index pointing at the viewer: medium-dark skin tone
🫵🏿 index pointing at the viewer: dark skin tone
👍 thumbs up
👍🏻 thumbs up: light skin tone
👍🏼 thumbs up: medium-light skin tone
👍🏽 thumbs up: medium skin tone
👍🏾 thumbs up: medium-dark skin tone
👍🏿 thumbs up: dark skin tone
👎 thumbs down
👎🏻 thumbs down: light skin tone
👎🏼 thumbs down: medium-light skin tone
👎🏽 thumbs down: medium skin tone
👎🏾 thumbs down: medium-dark skin tone
👎🏿 thumbs down: dark skin tone
✊ raised fist
✊🏻 raised fist: light skin tone
✊🏼 raised fist: medium-light skin tone
✊🏽 raised fist: medium skin tone
✊🏾 raised fist: medium-dark skin tone
✊🏿 raised fist: dark skin tone
👊 oncoming fist
👊🏻 oncoming fist: light skin tone
👊🏼 oncoming fist: medium-light skin tone
👊🏽 oncoming fist: medium skin tone
👊🏾 oncoming fist: medium-dark skin tone
👊🏿 oncoming fist: dark skin tone
🤛 left-facing fist
🤛🏻 left-facing fist: light skin tone
🤛🏼 left-facing fist: medium-light skin tone
🤛🏽 left-facing fist: medium skin tone
🤛🏾 left-facing fist: medium-dark skin tone
🤛🏿 left-facing fist: dark skin tone
🤜 right-facing fist
🤜🏻 right-facing fist: light skin tone
🤜🏼 right-facing fist: medium-light skin tone
🤜🏽 right-facing fist: medium skin tone
🤜🏾 right-facing fist: medium-dark skin tone
🤜🏿 right-facing fist: dark skin tone
👏 clapping hands
👏🏻 clapping hands: light skin tone
👏🏼 clapping hands: medium-light skin tone
👏🏽 clapping hands: medium skin tone
👏🏾 clapping hands: medium-dark skin tone
👏🏿 clapping hands: dark skin tone
🙌 raising hands
🙌🏻 raising hands: light skin tone
🙌🏼 raising hands: medium-light skin tone
🙌🏽 raising hands: medium skin tone
🙌🏾 raising hands: medium-dark skin tone
🙌🏿 raising hands: dark skin tone
🫶 heart hands
🫶🏻 heart hands: light skin tone
🫶🏼 heart hands: medium-light skin tone
🫶🏽 heart hands: medium skin tone
🫶🏾 heart hands: medium-dark skin tone
🫶🏿 heart hands: dark skin tone
👐 open hands
👐🏻 open hands: light skin tone
👐🏼 open hands: medium-light skin tone
👐🏽 open hands: medium skin tone
👐🏾 open hands: medium-dark skin tone
👐🏿 open hands: dark skin tone
🤲 palms up together
🤲🏻 palms up together: light skin tone
🤲🏼 palms up together: medium-light skin tone
🤲🏽 palms up together: medium skin tone
🤲🏾 palms up together: medium-dark skin tone
🤲🏿 palms up together: dark skin tone
🤝 handshake
🤝🏻 handshake: light skin tone
🤝🏼 handshake: medium-light skin tone
🤝🏽 handshake: medium skin tone
🤝🏾 handshake: medium-dark skin tone
🤝🏿 handshake: dark skin tone
🫱🏻‍🫲🏼 handshake: light skin tone, medium-light skin tone
🫱🏻‍🫲🏽 handshake: light skin tone, medium skin tone
🫱🏻‍🫲🏾 handshake: light skin tone, medium-dark skin tone
🫱🏻‍🫲🏿 handshake: light skin tone, dark skin tone
🫱🏼‍🫲🏻 handshake: medium-light skin tone, light skin tone
🫱🏼‍🫲🏽 handshake: medium-light skin tone, medium skin tone
🫱🏼‍🫲🏾 handshake: medium-light skin tone, medium-dark skin tone
🫱🏼‍🫲🏿 handshake: medium-light skin tone, dark skin tone
🫱🏽‍🫲🏻 handshake: medium skin tone, light skin tone
🫱🏽‍🫲🏼 handshake: medium skin tone, medium-light skin tone
🫱🏽‍🫲🏾 handshake: medium skin tone, medium-dark skin tone
🫱🏽‍🫲🏿 handshake: medium skin tone, dark skin tone
🫱🏾‍🫲🏻 handshake: medium-dark skin tone, light skin tone
🫱🏾‍🫲🏼 handshake: medium-dark skin tone, medium-light skin tone
🫱🏾‍🫲🏽 handshake: medium-dark skin tone, medium skin tone
🫱🏾‍🫲🏿 handshake: medium-dark skin tone, dark skin tone
🫱🏿‍🫲🏻 handshake: dark skin tone, light skin tone
🫱🏿‍🫲🏼 handshake: dark skin tone, medium-light skin tone
🫱🏿‍🫲🏽 handshake: dark skin tone, medium skin tone
🫱🏿‍🫲🏾 handshake: dark skin tone, medium-dark skin tone
🙏 folded hands
🙏🏻 folded hands: light skin tone
🙏🏼 folded hands: medium-light skin tone
🙏🏽 folded hands: medium skin tone
🙏🏾 folded hands: medium-dark skin tone
🙏🏿 folded hands: dark skin tone
✍️ writing hand
✍🏻 writing hand: light skin tone
✍🏼 writing hand: medium-light skin tone
✍🏽 writing hand: medium skin tone
✍🏾 writing hand: medium-dark skin tone
✍🏿 writing hand: dark skin tone
💅 nail polish
💅🏻 nail polish: light skin tone
💅🏼 nail polish: medium-light skin tone
💅🏽 nail polish: medium skin tone
💅🏾 nail polish: medium-dark skin tone
💅🏿 nail polish: dark skin tone
🤳 selfie
🤳🏻 selfie: light skin tone
🤳🏼 selfie: medium-light skin tone
🤳🏽 selfie: medium skin tone
🤳🏾 selfie: medium-dark skin tone
🤳🏿 selfie: dark skin tone
💪 flexed biceps
💪🏻 flexed biceps: light skin tone
💪🏼 flexed biceps: medium-light skin tone
💪🏽 flexed biceps: medium skin tone
💪🏾 flexed biceps: medium-dark skin tone
💪🏿 flexed biceps: dark skin tone
🦾 mechanical arm
🦿 mechanical leg
🦵 leg
🦵🏻 leg: light skin tone
🦵🏼 leg: medium-light skin tone
🦵🏽 leg: medium skin tone
🦵🏾 leg: medium-dark skin tone
🦵🏿 leg: dark skin tone
🦶 foot
🦶🏻 foot: light skin tone
🦶🏼 foot: medium-light skin tone
🦶🏽 foot: medium skin tone
🦶🏾 foot: medium-dark skin tone
🦶🏿 foot: dark skin tone
👂 ear
👂🏻 ear: light skin tone
👂🏼 ear: medium-light skin tone
👂🏽 ear: medium skin tone
👂🏾 ear: medium-dark skin tone
👂🏿 ear: dark skin tone
🦻 ear with hearing aid
🦻🏻 ear with hearing aid: light skin tone
🦻🏼 ear with hearing aid: medium-light skin tone
🦻🏽 ear with hearing aid: medium skin tone
🦻🏾 ear with hearing aid: medium-dark skin tone
🦻🏿 ear with hearing aid: dark skin tone
👃 nose
👃🏻 nose: light skin tone
👃🏼 nose: medium-light skin tone
👃🏽 nose: medium skin tone
👃🏾 nose: medium-dark skin tone
👃🏿 nose: dark skin tone
🧠 brain
🫀 anatomical heart
🫁 lungs


@@ 215,95 491,1822 @@
👄 mouth
🫦 biting lip
👶 baby
👶🏻 baby: light skin tone
👶🏼 baby: medium-light skin tone
👶🏽 baby: medium skin tone
👶🏾 baby: medium-dark skin tone
👶🏿 baby: dark skin tone
🧒 child
🧒🏻 child: light skin tone
🧒🏼 child: medium-light skin tone
🧒🏽 child: medium skin tone
🧒🏾 child: medium-dark skin tone
🧒🏿 child: dark skin tone
👦 boy
👦🏻 boy: light skin tone
👦🏼 boy: medium-light skin tone
👦🏽 boy: medium skin tone
👦🏾 boy: medium-dark skin tone
👦🏿 boy: dark skin tone
👧 girl
👧🏻 girl: light skin tone
👧🏼 girl: medium-light skin tone
👧🏽 girl: medium skin tone
👧🏾 girl: medium-dark skin tone
👧🏿 girl: dark skin tone
🧑 person
🧑🏻 person: light skin tone
🧑🏼 person: medium-light skin tone
🧑🏽 person: medium skin tone
🧑🏾 person: medium-dark skin tone
🧑🏿 person: dark skin tone
👱 person: blond hair
👱🏻 person: light skin tone, blond hair
👱🏼 person: medium-light skin tone, blond hair
👱🏽 person: medium skin tone, blond hair
👱🏾 person: medium-dark skin tone, blond hair
👱🏿 person: dark skin tone, blond hair
👨 man
👨🏻 man: light skin tone
👨🏼 man: medium-light skin tone
👨🏽 man: medium skin tone
👨🏾 man: medium-dark skin tone
👨🏿 man: dark skin tone
🧔 person: beard
🧔🏻 person: light skin tone, beard
🧔🏼 person: medium-light skin tone, beard
🧔🏽 person: medium skin tone, beard
🧔🏾 person: medium-dark skin tone, beard
🧔🏿 person: dark skin tone, beard
🧔‍♂️ man: beard
🧔🏻‍♂️ man: light skin tone, beard
🧔🏼‍♂️ man: medium-light skin tone, beard
🧔🏽‍♂️ man: medium skin tone, beard
🧔🏾‍♂️ man: medium-dark skin tone, beard
🧔🏿‍♂️ man: dark skin tone, beard
🧔‍♀️ woman: beard
🧔🏻‍♀️ woman: light skin tone, beard
🧔🏼‍♀️ woman: medium-light skin tone, beard
🧔🏽‍♀️ woman: medium skin tone, beard
🧔🏾‍♀️ woman: medium-dark skin tone, beard
🧔🏿‍♀️ woman: dark skin tone, beard
👨‍🦰 man: red hair
👨🏻‍🦰 man: light skin tone, red hair
👨🏼‍🦰 man: medium-light skin tone, red hair
👨🏽‍🦰 man: medium skin tone, red hair
👨🏾‍🦰 man: medium-dark skin tone, red hair
👨🏿‍🦰 man: dark skin tone, red hair
👨‍🦱 man: curly hair
👨🏻‍🦱 man: light skin tone, curly hair
👨🏼‍🦱 man: medium-light skin tone, curly hair
👨🏽‍🦱 man: medium skin tone, curly hair
👨🏾‍🦱 man: medium-dark skin tone, curly hair
👨🏿‍🦱 man: dark skin tone, curly hair
👨‍🦳 man: white hair
👨🏻‍🦳 man: light skin tone, white hair
👨🏼‍🦳 man: medium-light skin tone, white hair
👨🏽‍🦳 man: medium skin tone, white hair
👨🏾‍🦳 man: medium-dark skin tone, white hair
👨🏿‍🦳 man: dark skin tone, white hair
👨‍🦲 man: bald
👨🏻‍🦲 man: light skin tone, bald
👨🏼‍🦲 man: medium-light skin tone, bald
👨🏽‍🦲 man: medium skin tone, bald
👨🏾‍🦲 man: medium-dark skin tone, bald
👨🏿‍🦲 man: dark skin tone, bald
👩 woman
👩🏻 woman: light skin tone
👩🏼 woman: medium-light skin tone
👩🏽 woman: medium skin tone
👩🏾 woman: medium-dark skin tone
👩🏿 woman: dark skin tone
👩‍🦰 woman: red hair
👩🏻‍🦰 woman: light skin tone, red hair
👩🏼‍🦰 woman: medium-light skin tone, red hair
👩🏽‍🦰 woman: medium skin tone, red hair
👩🏾‍🦰 woman: medium-dark skin tone, red hair
👩🏿‍🦰 woman: dark skin tone, red hair
🧑‍🦰 person: red hair
🧑🏻‍🦰 person: light skin tone, red hair
🧑🏼‍🦰 person: medium-light skin tone, red hair
🧑🏽‍🦰 person: medium skin tone, red hair
🧑🏾‍🦰 person: medium-dark skin tone, red hair
🧑🏿‍🦰 person: dark skin tone, red hair
👩‍🦱 woman: curly hair
👩🏻‍🦱 woman: light skin tone, curly hair
👩🏼‍🦱 woman: medium-light skin tone, curly hair
👩🏽‍🦱 woman: medium skin tone, curly hair
👩🏾‍🦱 woman: medium-dark skin tone, curly hair
👩🏿‍🦱 woman: dark skin tone, curly hair
🧑‍🦱 person: curly hair
🧑🏻‍🦱 person: light skin tone, curly hair
🧑🏼‍🦱 person: medium-light skin tone, curly hair
🧑🏽‍🦱 person: medium skin tone, curly hair
🧑🏾‍🦱 person: medium-dark skin tone, curly hair
🧑🏿‍🦱 person: dark skin tone, curly hair
👩‍🦳 woman: white hair
👩🏻‍🦳 woman: light skin tone, white hair
👩🏼‍🦳 woman: medium-light skin tone, white hair
👩🏽‍🦳 woman: medium skin tone, white hair
👩🏾‍🦳 woman: medium-dark skin tone, white hair
👩🏿‍🦳 woman: dark skin tone, white hair
🧑‍🦳 person: white hair
🧑🏻‍🦳 person: light skin tone, white hair
🧑🏼‍🦳 person: medium-light skin tone, white hair
🧑🏽‍🦳 person: medium skin tone, white hair
🧑🏾‍🦳 person: medium-dark skin tone, white hair
🧑🏿‍🦳 person: dark skin tone, white hair
👩‍🦲 woman: bald
👩🏻‍🦲 woman: light skin tone, bald
👩🏼‍🦲 woman: medium-light skin tone, bald
👩🏽‍🦲 woman: medium skin tone, bald
👩🏾‍🦲 woman: medium-dark skin tone, bald
👩🏿‍🦲 woman: dark skin tone, bald
🧑‍🦲 person: bald
🧑🏻‍🦲 person: light skin tone, bald
🧑🏼‍🦲 person: medium-light skin tone, bald
🧑🏽‍🦲 person: medium skin tone, bald
🧑🏾‍🦲 person: medium-dark skin tone, bald
🧑🏿‍🦲 person: dark skin tone, bald
👱‍♀️ woman: blond hair
👱🏻‍♀️ woman: light skin tone, blond hair
👱🏼‍♀️ woman: medium-light skin tone, blond hair
👱🏽‍♀️ woman: medium skin tone, blond hair
👱🏾‍♀️ woman: medium-dark skin tone, blond hair
👱🏿‍♀️ woman: dark skin tone, blond hair
👱‍♂️ man: blond hair
👱🏻‍♂️ man: light skin tone, blond hair
👱🏼‍♂️ man: medium-light skin tone, blond hair
👱🏽‍♂️ man: medium skin tone, blond hair
👱🏾‍♂️ man: medium-dark skin tone, blond hair
👱🏿‍♂️ man: dark skin tone, blond hair
🧓 older person
🧓🏻 older person: light skin tone
🧓🏼 older person: medium-light skin tone
🧓🏽 older person: medium skin tone
🧓🏾 older person: medium-dark skin tone
🧓🏿 older person: dark skin tone
👴 old man
👴🏻 old man: light skin tone
👴🏼 old man: medium-light skin tone
👴🏽 old man: medium skin tone
👴🏾 old man: medium-dark skin tone
👴🏿 old man: dark skin tone
👵 old woman
👵🏻 old woman: light skin tone
👵🏼 old woman: medium-light skin tone
👵🏽 old woman: medium skin tone
👵🏾 old woman: medium-dark skin tone
👵🏿 old woman: dark skin tone
🙍 person frowning
🙍🏻 person frowning: light skin tone
🙍🏼 person frowning: medium-light skin tone
🙍🏽 person frowning: medium skin tone
🙍🏾 person frowning: medium-dark skin tone
🙍🏿 person frowning: dark skin tone
🙍‍♂️ man frowning
🙍🏻‍♂️ man frowning: light skin tone
🙍🏼‍♂️ man frowning: medium-light skin tone
🙍🏽‍♂️ man frowning: medium skin tone
🙍🏾‍♂️ man frowning: medium-dark skin tone
🙍🏿‍♂️ man frowning: dark skin tone
🙍‍♀️ woman frowning
🙍🏻‍♀️ woman frowning: light skin tone
🙍🏼‍♀️ woman frowning: medium-light skin tone
🙍🏽‍♀️ woman frowning: medium skin tone
🙍🏾‍♀️ woman frowning: medium-dark skin tone
🙍🏿‍♀️ woman frowning: dark skin tone
🙎 person pouting
🙎🏻 person pouting: light skin tone
🙎🏼 person pouting: medium-light skin tone
🙎🏽 person pouting: medium skin tone
🙎🏾 person pouting: medium-dark skin tone
🙎🏿 person pouting: dark skin tone
🙎‍♂️ man pouting
🙎🏻‍♂️ man pouting: light skin tone
🙎🏼‍♂️ man pouting: medium-light skin tone
🙎🏽‍♂️ man pouting: medium skin tone
🙎🏾‍♂️ man pouting: medium-dark skin tone
🙎🏿‍♂️ man pouting: dark skin tone
🙎‍♀️ woman pouting
🙎🏻‍♀️ woman pouting: light skin tone
🙎🏼‍♀️ woman pouting: medium-light skin tone
🙎🏽‍♀️ woman pouting: medium skin tone
🙎🏾‍♀️ woman pouting: medium-dark skin tone
🙎🏿‍♀️ woman pouting: dark skin tone
🙅 person gesturing NO
🙅🏻 person gesturing NO: light skin tone
🙅🏼 person gesturing NO: medium-light skin tone
🙅🏽 person gesturing NO: medium skin tone
🙅🏾 person gesturing NO: medium-dark skin tone
🙅🏿 person gesturing NO: dark skin tone
🙅‍♂️ man gesturing NO
🙅🏻‍♂️ man gesturing NO: light skin tone
🙅🏼‍♂️ man gesturing NO: medium-light skin tone
🙅🏽‍♂️ man gesturing NO: medium skin tone
🙅🏾‍♂️ man gesturing NO: medium-dark skin tone
🙅🏿‍♂️ man gesturing NO: dark skin tone
🙅‍♀️ woman gesturing NO
🙅🏻‍♀️ woman gesturing NO: light skin tone
🙅🏼‍♀️ woman gesturing NO: medium-light skin tone
🙅🏽‍♀️ woman gesturing NO: medium skin tone
🙅🏾‍♀️ woman gesturing NO: medium-dark skin tone
🙅🏿‍♀️ woman gesturing NO: dark skin tone
🙆 person gesturing OK
🙆🏻 person gesturing OK: light skin tone
🙆🏼 person gesturing OK: medium-light skin tone
🙆🏽 person gesturing OK: medium skin tone
🙆🏾 person gesturing OK: medium-dark skin tone
🙆🏿 person gesturing OK: dark skin tone
🙆‍♂️ man gesturing OK
🙆🏻‍♂️ man gesturing OK: light skin tone
🙆🏼‍♂️ man gesturing OK: medium-light skin tone
🙆🏽‍♂️ man gesturing OK: medium skin tone
🙆🏾‍♂️ man gesturing OK: medium-dark skin tone
🙆🏿‍♂️ man gesturing OK: dark skin tone
🙆‍♀️ woman gesturing OK
🙆🏻‍♀️ woman gesturing OK: light skin tone
🙆🏼‍♀️ woman gesturing OK: medium-light skin tone
🙆🏽‍♀️ woman gesturing OK: medium skin tone
🙆🏾‍♀️ woman gesturing OK: medium-dark skin tone
🙆🏿‍♀️ woman gesturing OK: dark skin tone
💁 person tipping hand
💁🏻 person tipping hand: light skin tone
💁🏼 person tipping hand: medium-light skin tone
💁🏽 person tipping hand: medium skin tone
💁🏾 person tipping hand: medium-dark skin tone
💁🏿 person tipping hand: dark skin tone
💁‍♂️ man tipping hand
💁🏻‍♂️ man tipping hand: light skin tone
💁🏼‍♂️ man tipping hand: medium-light skin tone
💁🏽‍♂️ man tipping hand: medium skin tone
💁🏾‍♂️ man tipping hand: medium-dark skin tone
💁🏿‍♂️ man tipping hand: dark skin tone
💁‍♀️ woman tipping hand
💁🏻‍♀️ woman tipping hand: light skin tone
💁🏼‍♀️ woman tipping hand: medium-light skin tone
💁🏽‍♀️ woman tipping hand: medium skin tone
💁🏾‍♀️ woman tipping hand: medium-dark skin tone
💁🏿‍♀️ woman tipping hand: dark skin tone
🙋 person raising hand
🙋🏻 person raising hand: light skin tone
🙋🏼 person raising hand: medium-light skin tone
🙋🏽 person raising hand: medium skin tone
🙋🏾 person raising hand: medium-dark skin tone
🙋🏿 person raising hand: dark skin tone
🙋‍♂️ man raising hand
🙋🏻‍♂️ man raising hand: light skin tone
🙋🏼‍♂️ man raising hand: medium-light skin tone
🙋🏽‍♂️ man raising hand: medium skin tone
🙋🏾‍♂️ man raising hand: medium-dark skin tone
🙋🏿‍♂️ man raising hand: dark skin tone
🙋‍♀️ woman raising hand
🙋🏻‍♀️ woman raising hand: light skin tone
🙋🏼‍♀️ woman raising hand: medium-light skin tone
🙋🏽‍♀️ woman raising hand: medium skin tone
🙋🏾‍♀️ woman raising hand: medium-dark skin tone
🙋🏿‍♀️ woman raising hand: dark skin tone
🧏 deaf person
🧏🏻 deaf person: light skin tone
🧏🏼 deaf person: medium-light skin tone
🧏🏽 deaf person: medium skin tone
🧏🏾 deaf person: medium-dark skin tone
🧏🏿 deaf person: dark skin tone
🧏‍♂️ deaf man
🧏🏻‍♂️ deaf man: light skin tone
🧏🏼‍♂️ deaf man: medium-light skin tone
🧏🏽‍♂️ deaf man: medium skin tone
🧏🏾‍♂️ deaf man: medium-dark skin tone
🧏🏿‍♂️ deaf man: dark skin tone
🧏‍♀️ deaf woman
🧏🏻‍♀️ deaf woman: light skin tone
🧏🏼‍♀️ deaf woman: medium-light skin tone
🧏🏽‍♀️ deaf woman: medium skin tone
🧏🏾‍♀️ deaf woman: medium-dark skin tone
🧏🏿‍♀️ deaf woman: dark skin tone
🙇 person bowing
🙇🏻 person bowing: light skin tone
🙇🏼 person bowing: medium-light skin tone
🙇🏽 person bowing: medium skin tone
🙇🏾 person bowing: medium-dark skin tone
🙇🏿 person bowing: dark skin tone
🙇‍♂️ man bowing
🙇🏻‍♂️ man bowing: light skin tone
🙇🏼‍♂️ man bowing: medium-light skin tone
🙇🏽‍♂️ man bowing: medium skin tone
🙇🏾‍♂️ man bowing: medium-dark skin tone
🙇🏿‍♂️ man bowing: dark skin tone
🙇‍♀️ woman bowing
🙇🏻‍♀️ woman bowing: light skin tone
🙇🏼‍♀️ woman bowing: medium-light skin tone
🙇🏽‍♀️ woman bowing: medium skin tone
🙇🏾‍♀️ woman bowing: medium-dark skin tone
🙇🏿‍♀️ woman bowing: dark skin tone
🤦 person facepalming
🤦🏻 person facepalming: light skin tone
🤦🏼 person facepalming: medium-light skin tone
🤦🏽 person facepalming: medium skin tone
🤦🏾 person facepalming: medium-dark skin tone
🤦🏿 person facepalming: dark skin tone
🤦‍♂️ man facepalming
🤦🏻‍♂️ man facepalming: light skin tone
🤦🏼‍♂️ man facepalming: medium-light skin tone
🤦🏽‍♂️ man facepalming: medium skin tone
🤦🏾‍♂️ man facepalming: medium-dark skin tone
🤦🏿‍♂️ man facepalming: dark skin tone
🤦‍♀️ woman facepalming
🤦🏻‍♀️ woman facepalming: light skin tone
🤦🏼‍♀️ woman facepalming: medium-light skin tone
🤦🏽‍♀️ woman facepalming: medium skin tone
🤦🏾‍♀️ woman facepalming: medium-dark skin tone
🤦🏿‍♀️ woman facepalming: dark skin tone
🤷 person shrugging
🤷🏻 person shrugging: light skin tone
🤷🏼 person shrugging: medium-light skin tone
🤷🏽 person shrugging: medium skin tone
🤷🏾 person shrugging: medium-dark skin tone
🤷🏿 person shrugging: dark skin tone
🤷‍♂️ man shrugging
🤷🏻‍♂️ man shrugging: light skin tone
🤷🏼‍♂️ man shrugging: medium-light skin tone
🤷🏽‍♂️ man shrugging: medium skin tone
🤷🏾‍♂️ man shrugging: medium-dark skin tone
🤷🏿‍♂️ man shrugging: dark skin tone
🤷‍♀️ woman shrugging
🤷🏻‍♀️ woman shrugging: light skin tone
🤷🏼‍♀️ woman shrugging: medium-light skin tone
🤷🏽‍♀️ woman shrugging: medium skin tone
🤷🏾‍♀️ woman shrugging: medium-dark skin tone
🤷🏿‍♀️ woman shrugging: dark skin tone
🧑‍⚕️ health worker
🧑🏻‍⚕️ health worker: light skin tone
🧑🏼‍⚕️ health worker: medium-light skin tone
🧑🏽‍⚕️ health worker: medium skin tone
🧑🏾‍⚕️ health worker: medium-dark skin tone
🧑🏿‍⚕️ health worker: dark skin tone
👨‍⚕️ man health worker
👨🏻‍⚕️ man health worker: light skin tone
👨🏼‍⚕️ man health worker: medium-light skin tone
👨🏽‍⚕️ man health worker: medium skin tone
👨🏾‍⚕️ man health worker: medium-dark skin tone
👨🏿‍⚕️ man health worker: dark skin tone
👩‍⚕️ woman health worker
👩🏻‍⚕️ woman health worker: light skin tone
👩🏼‍⚕️ woman health worker: medium-light skin tone
👩🏽‍⚕️ woman health worker: medium skin tone
👩🏾‍⚕️ woman health worker: medium-dark skin tone
👩🏿‍⚕️ woman health worker: dark skin tone
🧑‍🎓 student
🧑🏻‍🎓 student: light skin tone
🧑🏼‍🎓 student: medium-light skin tone
🧑🏽‍🎓 student: medium skin tone
🧑🏾‍🎓 student: medium-dark skin tone
🧑🏿‍🎓 student: dark skin tone
👨‍🎓 man student
👨🏻‍🎓 man student: light skin tone
👨🏼‍🎓 man student: medium-light skin tone
👨🏽‍🎓 man student: medium skin tone
👨🏾‍🎓 man student: medium-dark skin tone
👨🏿‍🎓 man student: dark skin tone
👩‍🎓 woman student
👩🏻‍🎓 woman student: light skin tone
👩🏼‍🎓 woman student: medium-light skin tone
👩🏽‍🎓 woman student: medium skin tone
👩🏾‍🎓 woman student: medium-dark skin tone
👩🏿‍🎓 woman student: dark skin tone
🧑‍🏫 teacher
🧑🏻‍🏫 teacher: light skin tone
🧑🏼‍🏫 teacher: medium-light skin tone
🧑🏽‍🏫 teacher: medium skin tone
🧑🏾‍🏫 teacher: medium-dark skin tone
🧑🏿‍🏫 teacher: dark skin tone
👨‍🏫 man teacher
👨🏻‍🏫 man teacher: light skin tone
👨🏼‍🏫 man teacher: medium-light skin tone
👨🏽‍🏫 man teacher: medium skin tone
👨🏾‍🏫 man teacher: medium-dark skin tone
👨🏿‍🏫 man teacher: dark skin tone
👩‍🏫 woman teacher
👩🏻‍🏫 woman teacher: light skin tone
👩🏼‍🏫 woman teacher: medium-light skin tone
👩🏽‍🏫 woman teacher: medium skin tone
👩🏾‍🏫 woman teacher: medium-dark skin tone
👩🏿‍🏫 woman teacher: dark skin tone
🧑‍⚖️ judge
🧑🏻‍⚖️ judge: light skin tone
🧑🏼‍⚖️ judge: medium-light skin tone
🧑🏽‍⚖️ judge: medium skin tone
🧑🏾‍⚖️ judge: medium-dark skin tone
🧑🏿‍⚖️ judge: dark skin tone
👨‍⚖️ man judge
👨🏻‍⚖️ man judge: light skin tone
👨🏼‍⚖️ man judge: medium-light skin tone
👨🏽‍⚖️ man judge: medium skin tone
👨🏾‍⚖️ man judge: medium-dark skin tone
👨🏿‍⚖️ man judge: dark skin tone
👩‍⚖️ woman judge
👩🏻‍⚖️ woman judge: light skin tone
👩🏼‍⚖️ woman judge: medium-light skin tone
👩🏽‍⚖️ woman judge: medium skin tone
👩🏾‍⚖️ woman judge: medium-dark skin tone
👩🏿‍⚖️ woman judge: dark skin tone
🧑‍🌾 farmer
🧑🏻‍🌾 farmer: light skin tone
🧑🏼‍🌾 farmer: medium-light skin tone
🧑🏽‍🌾 farmer: medium skin tone
🧑🏾‍🌾 farmer: medium-dark skin tone
🧑🏿‍🌾 farmer: dark skin tone
👨‍🌾 man farmer
👨🏻‍🌾 man farmer: light skin tone
👨🏼‍🌾 man farmer: medium-light skin tone
👨🏽‍🌾 man farmer: medium skin tone
👨🏾‍🌾 man farmer: medium-dark skin tone
👨🏿‍🌾 man farmer: dark skin tone
👩‍🌾 woman farmer
👩🏻‍🌾 woman farmer: light skin tone
👩🏼‍🌾 woman farmer: medium-light skin tone
👩🏽‍🌾 woman farmer: medium skin tone
👩🏾‍🌾 woman farmer: medium-dark skin tone
👩🏿‍🌾 woman farmer: dark skin tone
🧑‍🍳 cook
🧑🏻‍🍳 cook: light skin tone
🧑🏼‍🍳 cook: medium-light skin tone
🧑🏽‍🍳 cook: medium skin tone
🧑🏾‍🍳 cook: medium-dark skin tone
🧑🏿‍🍳 cook: dark skin tone
👨‍🍳 man cook
👨🏻‍🍳 man cook: light skin tone
👨🏼‍🍳 man cook: medium-light skin tone
👨🏽‍🍳 man cook: medium skin tone
👨🏾‍🍳 man cook: medium-dark skin tone
👨🏿‍🍳 man cook: dark skin tone
👩‍🍳 woman cook
👩🏻‍🍳 woman cook: light skin tone
👩🏼‍🍳 woman cook: medium-light skin tone
👩🏽‍🍳 woman cook: medium skin tone
👩🏾‍🍳 woman cook: medium-dark skin tone
👩🏿‍🍳 woman cook: dark skin tone
🧑‍🔧 mechanic
🧑🏻‍🔧 mechanic: light skin tone
🧑🏼‍🔧 mechanic: medium-light skin tone
🧑🏽‍🔧 mechanic: medium skin tone
🧑🏾‍🔧 mechanic: medium-dark skin tone
🧑🏿‍🔧 mechanic: dark skin tone
👨‍🔧 man mechanic
👨🏻‍🔧 man mechanic: light skin tone
👨🏼‍🔧 man mechanic: medium-light skin tone
👨🏽‍🔧 man mechanic: medium skin tone
👨🏾‍🔧 man mechanic: medium-dark skin tone
👨🏿‍🔧 man mechanic: dark skin tone
👩‍🔧 woman mechanic
👩🏻‍🔧 woman mechanic: light skin tone
👩🏼‍🔧 woman mechanic: medium-light skin tone
👩🏽‍🔧 woman mechanic: medium skin tone
👩🏾‍🔧 woman mechanic: medium-dark skin tone
👩🏿‍🔧 woman mechanic: dark skin tone
🧑‍🏭 factory worker
🧑🏻‍🏭 factory worker: light skin tone
🧑🏼‍🏭 factory worker: medium-light skin tone
🧑🏽‍🏭 factory worker: medium skin tone
🧑🏾‍🏭 factory worker: medium-dark skin tone
🧑🏿‍🏭 factory worker: dark skin tone
👨‍🏭 man factory worker
👨🏻‍🏭 man factory worker: light skin tone
👨🏼‍🏭 man factory worker: medium-light skin tone
👨🏽‍🏭 man factory worker: medium skin tone
👨🏾‍🏭 man factory worker: medium-dark skin tone
👨🏿‍🏭 man factory worker: dark skin tone
👩‍🏭 woman factory worker
👩🏻‍🏭 woman factory worker: light skin tone
👩🏼‍🏭 woman factory worker: medium-light skin tone
👩🏽‍🏭 woman factory worker: medium skin tone
👩🏾‍🏭 woman factory worker: medium-dark skin tone
👩🏿‍🏭 woman factory worker: dark skin tone
🧑‍💼 office worker
🧑🏻‍💼 office worker: light skin tone
🧑🏼‍💼 office worker: medium-light skin tone
🧑🏽‍💼 office worker: medium skin tone
🧑🏾‍💼 office worker: medium-dark skin tone
🧑🏿‍💼 office worker: dark skin tone
👨‍💼 man office worker
👨🏻‍💼 man office worker: light skin tone
👨🏼‍💼 man office worker: medium-light skin tone
👨🏽‍💼 man office worker: medium skin tone
👨🏾‍💼 man office worker: medium-dark skin tone
👨🏿‍💼 man office worker: dark skin tone
👩‍💼 woman office worker
👩🏻‍💼 woman office worker: light skin tone
👩🏼‍💼 woman office worker: medium-light skin tone
👩🏽‍💼 woman office worker: medium skin tone
👩🏾‍💼 woman office worker: medium-dark skin tone
👩🏿‍💼 woman office worker: dark skin tone
🧑‍🔬 scientist
🧑🏻‍🔬 scientist: light skin tone
🧑🏼‍🔬 scientist: medium-light skin tone
🧑🏽‍🔬 scientist: medium skin tone
🧑🏾‍🔬 scientist: medium-dark skin tone
🧑🏿‍🔬 scientist: dark skin tone
👨‍🔬 man scientist
👨🏻‍🔬 man scientist: light skin tone
👨🏼‍🔬 man scientist: medium-light skin tone
👨🏽‍🔬 man scientist: medium skin tone
👨🏾‍🔬 man scientist: medium-dark skin tone
👨🏿‍🔬 man scientist: dark skin tone
👩‍🔬 woman scientist
👩🏻‍🔬 woman scientist: light skin tone
👩🏼‍🔬 woman scientist: medium-light skin tone
👩🏽‍🔬 woman scientist: medium skin tone
👩🏾‍🔬 woman scientist: medium-dark skin tone
👩🏿‍🔬 woman scientist: dark skin tone
🧑‍💻 technologist
🧑🏻‍💻 technologist: light skin tone
🧑🏼‍💻 technologist: medium-light skin tone
🧑🏽‍💻 technologist: medium skin tone
🧑🏾‍💻 technologist: medium-dark skin tone
🧑🏿‍💻 technologist: dark skin tone
👨‍💻 man technologist
👨🏻‍💻 man technologist: light skin tone
👨🏼‍💻 man technologist: medium-light skin tone
👨🏽‍💻 man technologist: medium skin tone
👨🏾‍💻 man technologist: medium-dark skin tone
👨🏿‍💻 man technologist: dark skin tone
👩‍💻 woman technologist
👩🏻‍💻 woman technologist: light skin tone
👩🏼‍💻 woman technologist: medium-light skin tone
👩🏽‍💻 woman technologist: medium skin tone
👩🏾‍💻 woman technologist: medium-dark skin tone
👩🏿‍💻 woman technologist: dark skin tone
🧑‍🎤 singer
🧑🏻‍🎤 singer: light skin tone
🧑🏼‍🎤 singer: medium-light skin tone
🧑🏽‍🎤 singer: medium skin tone
🧑🏾‍🎤 singer: medium-dark skin tone
🧑🏿‍🎤 singer: dark skin tone
👨‍🎤 man singer
👨🏻‍🎤 man singer: light skin tone
👨🏼‍🎤 man singer: medium-light skin tone
👨🏽‍🎤 man singer: medium skin tone
👨🏾‍🎤 man singer: medium-dark skin tone
👨🏿‍🎤 man singer: dark skin tone
👩‍🎤 woman singer
👩🏻‍🎤 woman singer: light skin tone
👩🏼‍🎤 woman singer: medium-light skin tone
👩🏽‍🎤 woman singer: medium skin tone
👩🏾‍🎤 woman singer: medium-dark skin tone
👩🏿‍🎤 woman singer: dark skin tone
🧑‍🎨 artist
🧑🏻‍🎨 artist: light skin tone
🧑🏼‍🎨 artist: medium-light skin tone
🧑🏽‍🎨 artist: medium skin tone
🧑🏾‍🎨 artist: medium-dark skin tone
🧑🏿‍🎨 artist: dark skin tone
👨‍🎨 man artist
👨🏻‍🎨 man artist: light skin tone
👨🏼‍🎨 man artist: medium-light skin tone
👨🏽‍🎨 man artist: medium skin tone
👨🏾‍🎨 man artist: medium-dark skin tone
👨🏿‍🎨 man artist: dark skin tone
👩‍🎨 woman artist
👩🏻‍🎨 woman artist: light skin tone
👩🏼‍🎨 woman artist: medium-light skin tone
👩🏽‍🎨 woman artist: medium skin tone
👩🏾‍🎨 woman artist: medium-dark skin tone
👩🏿‍🎨 woman artist: dark skin tone
🧑‍✈️ pilot
🧑🏻‍✈️ pilot: light skin tone
🧑🏼‍✈️ pilot: medium-light skin tone
🧑🏽‍✈️ pilot: medium skin tone
🧑🏾‍✈️ pilot: medium-dark skin tone
🧑🏿‍✈️ pilot: dark skin tone
👨‍✈️ man pilot
👨🏻‍✈️ man pilot: light skin tone
👨🏼‍✈️ man pilot: medium-light skin tone
👨🏽‍✈️ man pilot: medium skin tone
👨🏾‍✈️ man pilot: medium-dark skin tone
👨🏿‍✈️ man pilot: dark skin tone
👩‍✈️ woman pilot
👩🏻‍✈️ woman pilot: light skin tone
👩🏼‍✈️ woman pilot: medium-light skin tone
👩🏽‍✈️ woman pilot: medium skin tone
👩🏾‍✈️ woman pilot: medium-dark skin tone
👩🏿‍✈️ woman pilot: dark skin tone
🧑‍🚀 astronaut
🧑🏻‍🚀 astronaut: light skin tone
🧑🏼‍🚀 astronaut: medium-light skin tone
🧑🏽‍🚀 astronaut: medium skin tone
🧑🏾‍🚀 astronaut: medium-dark skin tone
🧑🏿‍🚀 astronaut: dark skin tone
👨‍🚀 man astronaut
👨🏻‍🚀 man astronaut: light skin tone
👨🏼‍🚀 man astronaut: medium-light skin tone
👨🏽‍🚀 man astronaut: medium skin tone
👨🏾‍🚀 man astronaut: medium-dark skin tone
👨🏿‍🚀 man astronaut: dark skin tone
👩‍🚀 woman astronaut
👩🏻‍🚀 woman astronaut: light skin tone
👩🏼‍🚀 woman astronaut: medium-light skin tone
👩🏽‍🚀 woman astronaut: medium skin tone
👩🏾‍🚀 woman astronaut: medium-dark skin tone
👩🏿‍🚀 woman astronaut: dark skin tone
🧑‍🚒 firefighter
🧑🏻‍🚒 firefighter: light skin tone
🧑🏼‍🚒 firefighter: medium-light skin tone
🧑🏽‍🚒 firefighter: medium skin tone
🧑🏾‍🚒 firefighter: medium-dark skin tone
🧑🏿‍🚒 firefighter: dark skin tone
👨‍🚒 man firefighter
👨🏻‍🚒 man firefighter: light skin tone
👨🏼‍🚒 man firefighter: medium-light skin tone
👨🏽‍🚒 man firefighter: medium skin tone
👨🏾‍🚒 man firefighter: medium-dark skin tone
👨🏿‍🚒 man firefighter: dark skin tone
👩‍🚒 woman firefighter
👩🏻‍🚒 woman firefighter: light skin tone
👩🏼‍🚒 woman firefighter: medium-light skin tone
👩🏽‍🚒 woman firefighter: medium skin tone
👩🏾‍🚒 woman firefighter: medium-dark skin tone
👩🏿‍🚒 woman firefighter: dark skin tone
👮 police officer
👮🏻 police officer: light skin tone
👮🏼 police officer: medium-light skin tone
👮🏽 police officer: medium skin tone
👮🏾 police officer: medium-dark skin tone
👮🏿 police officer: dark skin tone
👮‍♂️ man police officer
👮🏻‍♂️ man police officer: light skin tone
👮🏼‍♂️ man police officer: medium-light skin tone
👮🏽‍♂️ man police officer: medium skin tone
👮🏾‍♂️ man police officer: medium-dark skin tone
👮🏿‍♂️ man police officer: dark skin tone
👮‍♀️ woman police officer
👮🏻‍♀️ woman police officer: light skin tone
👮🏼‍♀️ woman police officer: medium-light skin tone
👮🏽‍♀️ woman police officer: medium skin tone
👮🏾‍♀️ woman police officer: medium-dark skin tone
👮🏿‍♀️ woman police officer: dark skin tone
🕵️ detective
🕵🏻 detective: light skin tone
🕵🏼 detective: medium-light skin tone
🕵🏽 detective: medium skin tone
🕵🏾 detective: medium-dark skin tone
🕵🏿 detective: dark skin tone
🕵️‍♂️ man detective
🕵🏻‍♂️ man detective: light skin tone
🕵🏼‍♂️ man detective: medium-light skin tone
🕵🏽‍♂️ man detective: medium skin tone
🕵🏾‍♂️ man detective: medium-dark skin tone
🕵🏿‍♂️ man detective: dark skin tone
🕵️‍♀️ woman detective
🕵🏻‍♀️ woman detective: light skin tone
🕵🏼‍♀️ woman detective: medium-light skin tone
🕵🏽‍♀️ woman detective: medium skin tone
🕵🏾‍♀️ woman detective: medium-dark skin tone
🕵🏿‍♀️ woman detective: dark skin tone
💂 guard
💂🏻 guard: light skin tone
💂🏼 guard: medium-light skin tone
💂🏽 guard: medium skin tone
💂🏾 guard: medium-dark skin tone
💂🏿 guard: dark skin tone
💂‍♂️ man guard
💂🏻‍♂️ man guard: light skin tone
💂🏼‍♂️ man guard: medium-light skin tone
💂🏽‍♂️ man guard: medium skin tone
💂🏾‍♂️ man guard: medium-dark skin tone
💂🏿‍♂️ man guard: dark skin tone
💂‍♀️ woman guard
💂🏻‍♀️ woman guard: light skin tone
💂🏼‍♀️ woman guard: medium-light skin tone
💂🏽‍♀️ woman guard: medium skin tone
💂🏾‍♀️ woman guard: medium-dark skin tone
💂🏿‍♀️ woman guard: dark skin tone
🥷 ninja
🥷🏻 ninja: light skin tone
🥷🏼 ninja: medium-light skin tone
🥷🏽 ninja: medium skin tone
🥷🏾 ninja: medium-dark skin tone
🥷🏿 ninja: dark skin tone
👷 construction worker
👷🏻 construction worker: light skin tone
👷🏼 construction worker: medium-light skin tone
👷🏽 construction worker: medium skin tone
👷🏾 construction worker: medium-dark skin tone
👷🏿 construction worker: dark skin tone
👷‍♂️ man construction worker
👷🏻‍♂️ man construction worker: light skin tone
👷🏼‍♂️ man construction worker: medium-light skin tone
👷🏽‍♂️ man construction worker: medium skin tone
👷🏾‍♂️ man construction worker: medium-dark skin tone
👷🏿‍♂️ man construction worker: dark skin tone
👷‍♀️ woman construction worker
👷🏻‍♀️ woman construction worker: light skin tone
👷🏼‍♀️ woman construction worker: medium-light skin tone
👷🏽‍♀️ woman construction worker: medium skin tone
👷🏾‍♀️ woman construction worker: medium-dark skin tone
👷🏿‍♀️ woman construction worker: dark skin tone
🫅 person with crown
🫅🏻 person with crown: light skin tone
🫅🏼 person with crown: medium-light skin tone
🫅🏽 person with crown: medium skin tone
🫅🏾 person with crown: medium-dark skin tone
🫅🏿 person with crown: dark skin tone
🤴 prince
🤴🏻 prince: light skin tone
🤴🏼 prince: medium-light skin tone
🤴🏽 prince: medium skin tone
🤴🏾 prince: medium-dark skin tone
🤴🏿 prince: dark skin tone
👸 princess
👸🏻 princess: light skin tone
👸🏼 princess: medium-light skin tone
👸🏽 princess: medium skin tone
👸🏾 princess: medium-dark skin tone
👸🏿 princess: dark skin tone
👳 person wearing turban
👳🏻 person wearing turban: light skin tone
👳🏼 person wearing turban: medium-light skin tone
👳🏽 person wearing turban: medium skin tone
👳🏾 person wearing turban: medium-dark skin tone
👳🏿 person wearing turban: dark skin tone
👳‍♂️ man wearing turban
👳🏻‍♂️ man wearing turban: light skin tone
👳🏼‍♂️ man wearing turban: medium-light skin tone
👳🏽‍♂️ man wearing turban: medium skin tone
👳🏾‍♂️ man wearing turban: medium-dark skin tone
👳🏿‍♂️ man wearing turban: dark skin tone
👳‍♀️ woman wearing turban
👳🏻‍♀️ woman wearing turban: light skin tone
👳🏼‍♀️ woman wearing turban: medium-light skin tone
👳🏽‍♀️ woman wearing turban: medium skin tone
👳🏾‍♀️ woman wearing turban: medium-dark skin tone
👳🏿‍♀️ woman wearing turban: dark skin tone
👲 person with skullcap
👲🏻 person with skullcap: light skin tone
👲🏼 person with skullcap: medium-light skin tone
👲🏽 person with skullcap: medium skin tone
👲🏾 person with skullcap: medium-dark skin tone
👲🏿 person with skullcap: dark skin tone
🧕 woman with headscarf
🧕🏻 woman with headscarf: light skin tone
🧕🏼 woman with headscarf: medium-light skin tone
🧕🏽 woman with headscarf: medium skin tone
🧕🏾 woman with headscarf: medium-dark skin tone
🧕🏿 woman with headscarf: dark skin tone
🤵 person in tuxedo
🤵🏻 person in tuxedo: light skin tone
🤵🏼 person in tuxedo: medium-light skin tone
🤵🏽 person in tuxedo: medium skin tone
🤵🏾 person in tuxedo: medium-dark skin tone
🤵🏿 person in tuxedo: dark skin tone
🤵‍♂️ man in tuxedo
🤵🏻‍♂️ man in tuxedo: light skin tone
🤵🏼‍♂️ man in tuxedo: medium-light skin tone
🤵🏽‍♂️ man in tuxedo: medium skin tone
🤵🏾‍♂️ man in tuxedo: medium-dark skin tone
🤵🏿‍♂️ man in tuxedo: dark skin tone
🤵‍♀️ woman in tuxedo
🤵🏻‍♀️ woman in tuxedo: light skin tone
🤵🏼‍♀️ woman in tuxedo: medium-light skin tone
🤵🏽‍♀️ woman in tuxedo: medium skin tone
🤵🏾‍♀️ woman in tuxedo: medium-dark skin tone
🤵🏿‍♀️ woman in tuxedo: dark skin tone
👰 person with veil
👰🏻 person with veil: light skin tone
👰🏼 person with veil: medium-light skin tone
👰🏽 person with veil: medium skin tone
👰🏾 person with veil: medium-dark skin tone
👰🏿 person with veil: dark skin tone
👰‍♂️ man with veil
👰🏻‍♂️ man with veil: light skin tone
👰🏼‍♂️ man with veil: medium-light skin tone
👰🏽‍♂️ man with veil: medium skin tone
👰🏾‍♂️ man with veil: medium-dark skin tone
👰🏿‍♂️ man with veil: dark skin tone
👰‍♀️ woman with veil
👰🏻‍♀️ woman with veil: light skin tone
👰🏼‍♀️ woman with veil: medium-light skin tone
👰🏽‍♀️ woman with veil: medium skin tone
👰🏾‍♀️ woman with veil: medium-dark skin tone
👰🏿‍♀️ woman with veil: dark skin tone
🤰 pregnant woman
🤰🏻 pregnant woman: light skin tone
🤰🏼 pregnant woman: medium-light skin tone
🤰🏽 pregnant woman: medium skin tone
🤰🏾 pregnant woman: medium-dark skin tone
🤰🏿 pregnant woman: dark skin tone
🫃 pregnant man
🫃🏻 pregnant man: light skin tone
🫃🏼 pregnant man: medium-light skin tone
🫃🏽 pregnant man: medium skin tone
🫃🏾 pregnant man: medium-dark skin tone
🫃🏿 pregnant man: dark skin tone
🫄 pregnant person
🫄🏻 pregnant person: light skin tone
🫄🏼 pregnant person: medium-light skin tone
🫄🏽 pregnant person: medium skin tone
🫄🏾 pregnant person: medium-dark skin tone
🫄🏿 pregnant person: dark skin tone
🤱 breast-feeding
🤱🏻 breast-feeding: light skin tone
🤱🏼 breast-feeding: medium-light skin tone
🤱🏽 breast-feeding: medium skin tone
🤱🏾 breast-feeding: medium-dark skin tone
🤱🏿 breast-feeding: dark skin tone
👩‍🍼 woman feeding baby
👩🏻‍🍼 woman feeding baby: light skin tone
👩🏼‍🍼 woman feeding baby: medium-light skin tone
👩🏽‍🍼 woman feeding baby: medium skin tone
👩🏾‍🍼 woman feeding baby: medium-dark skin tone
👩🏿‍🍼 woman feeding baby: dark skin tone
👨‍🍼 man feeding baby
👨🏻‍🍼 man feeding baby: light skin tone
👨🏼‍🍼 man feeding baby: medium-light skin tone
👨🏽‍🍼 man feeding baby: medium skin tone
👨🏾‍🍼 man feeding baby: medium-dark skin tone
👨🏿‍🍼 man feeding baby: dark skin tone
🧑‍🍼 person feeding baby
🧑🏻‍🍼 person feeding baby: light skin tone
🧑🏼‍🍼 person feeding baby: medium-light skin tone
🧑🏽‍🍼 person feeding baby: medium skin tone
🧑🏾‍🍼 person feeding baby: medium-dark skin tone
🧑🏿‍🍼 person feeding baby: dark skin tone
👼 baby angel
👼🏻 baby angel: light skin tone
👼🏼 baby angel: medium-light skin tone
👼🏽 baby angel: medium skin tone
👼🏾 baby angel: medium-dark skin tone
👼🏿 baby angel: dark skin tone
🎅 Santa Claus
🎅🏻 Santa Claus: light skin tone
🎅🏼 Santa Claus: medium-light skin tone
🎅🏽 Santa Claus: medium skin tone
🎅🏾 Santa Claus: medium-dark skin tone
🎅🏿 Santa Claus: dark skin tone
🤶 Mrs. Claus
🤶🏻 Mrs. Claus: light skin tone
🤶🏼 Mrs. Claus: medium-light skin tone
🤶🏽 Mrs. Claus: medium skin tone
🤶🏾 Mrs. Claus: medium-dark skin tone
🤶🏿 Mrs. Claus: dark skin tone
🧑‍🎄 mx claus
🧑🏻‍🎄 mx claus: light skin tone
🧑🏼‍🎄 mx claus: medium-light skin tone
🧑🏽‍🎄 mx claus: medium skin tone
🧑🏾‍🎄 mx claus: medium-dark skin tone
🧑🏿‍🎄 mx claus: dark skin tone
🦸 superhero
🦸🏻 superhero: light skin tone
🦸🏼 superhero: medium-light skin tone
🦸🏽 superhero: medium skin tone
🦸🏾 superhero: medium-dark skin tone
🦸🏿 superhero: dark skin tone
🦸‍♂️ man superhero
🦸🏻‍♂️ man superhero: light skin tone
🦸🏼‍♂️ man superhero: medium-light skin tone
🦸🏽‍♂️ man superhero: medium skin tone
🦸🏾‍♂️ man superhero: medium-dark skin tone
🦸🏿‍♂️ man superhero: dark skin tone
🦸‍♀️ woman superhero
🦸🏻‍♀️ woman superhero: light skin tone
🦸🏼‍♀️ woman superhero: medium-light skin tone
🦸🏽‍♀️ woman superhero: medium skin tone
🦸🏾‍♀️ woman superhero: medium-dark skin tone
🦸🏿‍♀️ woman superhero: dark skin tone
🦹 supervillain
🦹🏻 supervillain: light skin tone
🦹🏼 supervillain: medium-light skin tone
🦹🏽 supervillain: medium skin tone
🦹🏾 supervillain: medium-dark skin tone
🦹🏿 supervillain: dark skin tone
🦹‍♂️ man supervillain
🦹🏻‍♂️ man supervillain: light skin tone
🦹🏼‍♂️ man supervillain: medium-light skin tone
🦹🏽‍♂️ man supervillain: medium skin tone
🦹🏾‍♂️ man supervillain: medium-dark skin tone
🦹🏿‍♂️ man supervillain: dark skin tone
🦹‍♀️ woman supervillain
🦹🏻‍♀️ woman supervillain: light skin tone
🦹🏼‍♀️ woman supervillain: medium-light skin tone
🦹🏽‍♀️ woman supervillain: medium skin tone
🦹🏾‍♀️ woman supervillain: medium-dark skin tone
🦹🏿‍♀️ woman supervillain: dark skin tone
🧙 mage
🧙🏻 mage: light skin tone
🧙🏼 mage: medium-light skin tone
🧙🏽 mage: medium skin tone
🧙🏾 mage: medium-dark skin tone
🧙🏿 mage: dark skin tone
🧙‍♂️ man mage
🧙🏻‍♂️ man mage: light skin tone
🧙🏼‍♂️ man mage: medium-light skin tone
🧙🏽‍♂️ man mage: medium skin tone
🧙🏾‍♂️ man mage: medium-dark skin tone
🧙🏿‍♂️ man mage: dark skin tone
🧙‍♀️ woman mage
🧙🏻‍♀️ woman mage: light skin tone
🧙🏼‍♀️ woman mage: medium-light skin tone
🧙🏽‍♀️ woman mage: medium skin tone
🧙🏾‍♀️ woman mage: medium-dark skin tone
🧙🏿‍♀️ woman mage: dark skin tone
🧚 fairy
🧚🏻 fairy: light skin tone
🧚🏼 fairy: medium-light skin tone
🧚🏽 fairy: medium skin tone
🧚🏾 fairy: medium-dark skin tone
🧚🏿 fairy: dark skin tone
🧚‍♂️ man fairy
🧚🏻‍♂️ man fairy: light skin tone
🧚🏼‍♂️ man fairy: medium-light skin tone
🧚🏽‍♂️ man fairy: medium skin tone
🧚🏾‍♂️ man fairy: medium-dark skin tone
🧚🏿‍♂️ man fairy: dark skin tone
🧚‍♀️ woman fairy
🧚🏻‍♀️ woman fairy: light skin tone
🧚🏼‍♀️ woman fairy: medium-light skin tone
🧚🏽‍♀️ woman fairy: medium skin tone
🧚🏾‍♀️ woman fairy: medium-dark skin tone
🧚🏿‍♀️ woman fairy: dark skin tone
🧛 vampire
🧛🏻 vampire: light skin tone
🧛🏼 vampire: medium-light skin tone
🧛🏽 vampire: medium skin tone
🧛🏾 vampire: medium-dark skin tone
🧛🏿 vampire: dark skin tone
🧛‍♂️ man vampire
🧛🏻‍♂️ man vampire: light skin tone
🧛🏼‍♂️ man vampire: medium-light skin tone
🧛🏽‍♂️ man vampire: medium skin tone
🧛🏾‍♂️ man vampire: medium-dark skin tone
🧛🏿‍♂️ man vampire: dark skin tone
🧛‍♀️ woman vampire
🧛🏻‍♀️ woman vampire: light skin tone
🧛🏼‍♀️ woman vampire: medium-light skin tone
🧛🏽‍♀️ woman vampire: medium skin tone
🧛🏾‍♀️ woman vampire: medium-dark skin tone
🧛🏿‍♀️ woman vampire: dark skin tone
🧜 merperson
🧜🏻 merperson: light skin tone
🧜🏼 merperson: medium-light skin tone
🧜🏽 merperson: medium skin tone
🧜🏾 merperson: medium-dark skin tone
🧜🏿 merperson: dark skin tone
🧜‍♂️ merman
🧜🏻‍♂️ merman: light skin tone
🧜🏼‍♂️ merman: medium-light skin tone
🧜🏽‍♂️ merman: medium skin tone
🧜🏾‍♂️ merman: medium-dark skin tone
🧜🏿‍♂️ merman: dark skin tone
🧜‍♀️ mermaid
🧜🏻‍♀️ mermaid: light skin tone
🧜🏼‍♀️ mermaid: medium-light skin tone
🧜🏽‍♀️ mermaid: medium skin tone
🧜🏾‍♀️ mermaid: medium-dark skin tone
🧜🏿‍♀️ mermaid: dark skin tone
🧝 elf
🧝🏻 elf: light skin tone
🧝🏼 elf: medium-light skin tone
🧝🏽 elf: medium skin tone
🧝🏾 elf: medium-dark skin tone
🧝🏿 elf: dark skin tone
🧝‍♂️ man elf
🧝🏻‍♂️ man elf: light skin tone
🧝🏼‍♂️ man elf: medium-light skin tone
🧝🏽‍♂️ man elf: medium skin tone
🧝🏾‍♂️ man elf: medium-dark skin tone
🧝🏿‍♂️ man elf: dark skin tone
🧝‍♀️ woman elf
🧝🏻‍♀️ woman elf: light skin tone
🧝🏼‍♀️ woman elf: medium-light skin tone
🧝🏽‍♀️ woman elf: medium skin tone
🧝🏾‍♀️ woman elf: medium-dark skin tone
🧝🏿‍♀️ woman elf: dark skin tone
🧞 genie
🧞‍♂️ man genie
🧞‍♀️ woman genie
🧟 zombie
🧟‍♂️ man zombie
🧟‍♀️ woman zombie
🧌 troll
💆 person getting massage
💆🏻 person getting massage: light skin tone
💆🏼 person getting massage: medium-light skin tone
💆🏽 person getting massage: medium skin tone
💆🏾 person getting massage: medium-dark skin tone
💆🏿 person getting massage: dark skin tone
💆‍♂️ man getting massage
💆🏻‍♂️ man getting massage: light skin tone
💆🏼‍♂️ man getting massage: medium-light skin tone
💆🏽‍♂️ man getting massage: medium skin tone
💆🏾‍♂️ man getting massage: medium-dark skin tone
💆🏿‍♂️ man getting massage: dark skin tone
💆‍♀️ woman getting massage
💆🏻‍♀️ woman getting massage: light skin tone
💆🏼‍♀️ woman getting massage: medium-light skin tone
💆🏽‍♀️ woman getting massage: medium skin tone
💆🏾‍♀️ woman getting massage: medium-dark skin tone
💆🏿‍♀️ woman getting massage: dark skin tone
💇 person getting haircut
💇🏻 person getting haircut: light skin tone
💇🏼 person getting haircut: medium-light skin tone
💇🏽 person getting haircut: medium skin tone
💇🏾 person getting haircut: medium-dark skin tone
💇🏿 person getting haircut: dark skin tone
💇‍♂️ man getting haircut
💇🏻‍♂️ man getting haircut: light skin tone
💇🏼‍♂️ man getting haircut: medium-light skin tone
💇🏽‍♂️ man getting haircut: medium skin tone
💇🏾‍♂️ man getting haircut: medium-dark skin tone
💇🏿‍♂️ man getting haircut: dark skin tone
💇‍♀️ woman getting haircut
💇🏻‍♀️ woman getting haircut: light skin tone
💇🏼‍♀️ woman getting haircut: medium-light skin tone
💇🏽‍♀️ woman getting haircut: medium skin tone
💇🏾‍♀️ woman getting haircut: medium-dark skin tone
💇🏿‍♀️ woman getting haircut: dark skin tone
🚶 person walking
🚶🏻 person walking: light skin tone
🚶🏼 person walking: medium-light skin tone
🚶🏽 person walking: medium skin tone
🚶🏾 person walking: medium-dark skin tone
🚶🏿 person walking: dark skin tone
🚶‍♂️ man walking
🚶🏻‍♂️ man walking: light skin tone
🚶🏼‍♂️ man walking: medium-light skin tone
🚶🏽‍♂️ man walking: medium skin tone
🚶🏾‍♂️ man walking: medium-dark skin tone
🚶🏿‍♂️ man walking: dark skin tone
🚶‍♀️ woman walking
🚶🏻‍♀️ woman walking: light skin tone
🚶🏼‍♀️ woman walking: medium-light skin tone
🚶🏽‍♀️ woman walking: medium skin tone
🚶🏾‍♀️ woman walking: medium-dark skin tone
🚶🏿‍♀️ woman walking: dark skin tone
🧍 person standing
🧍🏻 person standing: light skin tone
🧍🏼 person standing: medium-light skin tone
🧍🏽 person standing: medium skin tone
🧍🏾 person standing: medium-dark skin tone
🧍🏿 person standing: dark skin tone
🧍‍♂️ man standing
🧍🏻‍♂️ man standing: light skin tone
🧍🏼‍♂️ man standing: medium-light skin tone
🧍🏽‍♂️ man standing: medium skin tone
🧍🏾‍♂️ man standing: medium-dark skin tone
🧍🏿‍♂️ man standing: dark skin tone
🧍‍♀️ woman standing
🧍🏻‍♀️ woman standing: light skin tone
🧍🏼‍♀️ woman standing: medium-light skin tone
🧍🏽‍♀️ woman standing: medium skin tone
🧍🏾‍♀️ woman standing: medium-dark skin tone
🧍🏿‍♀️ woman standing: dark skin tone
🧎 person kneeling
🧎🏻 person kneeling: light skin tone
🧎🏼 person kneeling: medium-light skin tone
🧎🏽 person kneeling: medium skin tone
🧎🏾 person kneeling: medium-dark skin tone
🧎🏿 person kneeling: dark skin tone
🧎‍♂️ man kneeling
🧎🏻‍♂️ man kneeling: light skin tone
🧎🏼‍♂️ man kneeling: medium-light skin tone
🧎🏽‍♂️ man kneeling: medium skin tone
🧎🏾‍♂️ man kneeling: medium-dark skin tone
🧎🏿‍♂️ man kneeling: dark skin tone
🧎‍♀️ woman kneeling
🧎🏻‍♀️ woman kneeling: light skin tone
🧎🏼‍♀️ woman kneeling: medium-light skin tone
🧎🏽‍♀️ woman kneeling: medium skin tone
🧎🏾‍♀️ woman kneeling: medium-dark skin tone
🧎🏿‍♀️ woman kneeling: dark skin tone
🧑‍🦯 person with white cane
🧑🏻‍🦯 person with white cane: light skin tone
🧑🏼‍🦯 person with white cane: medium-light skin tone
🧑🏽‍🦯 person with white cane: medium skin tone
🧑🏾‍🦯 person with white cane: medium-dark skin tone
🧑🏿‍🦯 person with white cane: dark skin tone
👨‍🦯 man with white cane
👨🏻‍🦯 man with white cane: light skin tone
👨🏼‍🦯 man with white cane: medium-light skin tone
👨🏽‍🦯 man with white cane: medium skin tone
👨🏾‍🦯 man with white cane: medium-dark skin tone
👨🏿‍🦯 man with white cane: dark skin tone
👩‍🦯 woman with white cane
👩🏻‍🦯 woman with white cane: light skin tone
👩🏼‍🦯 woman with white cane: medium-light skin tone
👩🏽‍🦯 woman with white cane: medium skin tone
👩🏾‍🦯 woman with white cane: medium-dark skin tone
👩🏿‍🦯 woman with white cane: dark skin tone
🧑‍🦼 person in motorized wheelchair
🧑🏻‍🦼 person in motorized wheelchair: light skin tone
🧑🏼‍🦼 person in motorized wheelchair: medium-light skin tone
🧑🏽‍🦼 person in motorized wheelchair: medium skin tone
🧑🏾‍🦼 person in motorized wheelchair: medium-dark skin tone
🧑🏿‍🦼 person in motorized wheelchair: dark skin tone
👨‍🦼 man in motorized wheelchair
👨🏻‍🦼 man in motorized wheelchair: light skin tone
👨🏼‍🦼 man in motorized wheelchair: medium-light skin tone
👨🏽‍🦼 man in motorized wheelchair: medium skin tone
👨🏾‍🦼 man in motorized wheelchair: medium-dark skin tone
👨🏿‍🦼 man in motorized wheelchair: dark skin tone
👩‍🦼 woman in motorized wheelchair
👩🏻‍🦼 woman in motorized wheelchair: light skin tone
👩🏼‍🦼 woman in motorized wheelchair: medium-light skin tone
👩🏽‍🦼 woman in motorized wheelchair: medium skin tone
👩🏾‍🦼 woman in motorized wheelchair: medium-dark skin tone
👩🏿‍🦼 woman in motorized wheelchair: dark skin tone
🧑‍🦽 person in manual wheelchair
🧑🏻‍🦽 person in manual wheelchair: light skin tone
🧑🏼‍🦽 person in manual wheelchair: medium-light skin tone
🧑🏽‍🦽 person in manual wheelchair: medium skin tone
🧑🏾‍🦽 person in manual wheelchair: medium-dark skin tone
🧑🏿‍🦽 person in manual wheelchair: dark skin tone
👨‍🦽 man in manual wheelchair
👨🏻‍🦽 man in manual wheelchair: light skin tone
👨🏼‍🦽 man in manual wheelchair: medium-light skin tone
👨🏽‍🦽 man in manual wheelchair: medium skin tone
👨🏾‍🦽 man in manual wheelchair: medium-dark skin tone
👨🏿‍🦽 man in manual wheelchair: dark skin tone
👩‍🦽 woman in manual wheelchair
👩🏻‍🦽 woman in manual wheelchair: light skin tone
👩🏼‍🦽 woman in manual wheelchair: medium-light skin tone
👩🏽‍🦽 woman in manual wheelchair: medium skin tone
👩🏾‍🦽 woman in manual wheelchair: medium-dark skin tone
👩🏿‍🦽 woman in manual wheelchair: dark skin tone
🏃 person running
🏃🏻 person running: light skin tone
🏃🏼 person running: medium-light skin tone
🏃🏽 person running: medium skin tone
🏃🏾 person running: medium-dark skin tone
🏃🏿 person running: dark skin tone
🏃‍♂️ man running
🏃🏻‍♂️ man running: light skin tone
🏃🏼‍♂️ man running: medium-light skin tone
🏃🏽‍♂️ man running: medium skin tone
🏃🏾‍♂️ man running: medium-dark skin tone
🏃🏿‍♂️ man running: dark skin tone
🏃‍♀️ woman running
🏃🏻‍♀️ woman running: light skin tone
🏃🏼‍♀️ woman running: medium-light skin tone
🏃🏽‍♀️ woman running: medium skin tone
🏃🏾‍♀️ woman running: medium-dark skin tone
🏃🏿‍♀️ woman running: dark skin tone
💃 woman dancing
💃🏻 woman dancing: light skin tone
💃🏼 woman dancing: medium-light skin tone
💃🏽 woman dancing: medium skin tone
💃🏾 woman dancing: medium-dark skin tone
💃🏿 woman dancing: dark skin tone
🕺 man dancing
🕺🏻 man dancing: light skin tone
🕺🏼 man dancing: medium-light skin tone
🕺🏽 man dancing: medium skin tone
🕺🏾 man dancing: medium-dark skin tone
🕺🏿 man dancing: dark skin tone
🕴️ person in suit levitating
🕴🏻 person in suit levitating: light skin tone
🕴🏼 person in suit levitating: medium-light skin tone
🕴🏽 person in suit levitating: medium skin tone
🕴🏾 person in suit levitating: medium-dark skin tone
🕴🏿 person in suit levitating: dark skin tone
👯 people with bunny ears
👯‍♂️ men with bunny ears
👯‍♀️ women with bunny ears
🧖 person in steamy room
🧖🏻 person in steamy room: light skin tone
🧖🏼 person in steamy room: medium-light skin tone
🧖🏽 person in steamy room: medium skin tone
🧖🏾 person in steamy room: medium-dark skin tone
🧖🏿 person in steamy room: dark skin tone
🧖‍♂️ man in steamy room
🧖🏻‍♂️ man in steamy room: light skin tone
🧖🏼‍♂️ man in steamy room: medium-light skin tone
🧖🏽‍♂️ man in steamy room: medium skin tone
🧖🏾‍♂️ man in steamy room: medium-dark skin tone
🧖🏿‍♂️ man in steamy room: dark skin tone
🧖‍♀️ woman in steamy room
🧖🏻‍♀️ woman in steamy room: light skin tone
🧖🏼‍♀️ woman in steamy room: medium-light skin tone
🧖🏽‍♀️ woman in steamy room: medium skin tone
🧖🏾‍♀️ woman in steamy room: medium-dark skin tone
🧖🏿‍♀️ woman in steamy room: dark skin tone
🧗 person climbing
🧗🏻 person climbing: light skin tone
🧗🏼 person climbing: medium-light skin tone
🧗🏽 person climbing: medium skin tone
🧗🏾 person climbing: medium-dark skin tone
🧗🏿 person climbing: dark skin tone
🧗‍♂️ man climbing
🧗🏻‍♂️ man climbing: light skin tone
🧗🏼‍♂️ man climbing: medium-light skin tone
🧗🏽‍♂️ man climbing: medium skin tone
🧗🏾‍♂️ man climbing: medium-dark skin tone
🧗🏿‍♂️ man climbing: dark skin tone
🧗‍♀️ woman climbing
🧗🏻‍♀️ woman climbing: light skin tone
🧗🏼‍♀️ woman climbing: medium-light skin tone
🧗🏽‍♀️ woman climbing: medium skin tone
🧗🏾‍♀️ woman climbing: medium-dark skin tone
🧗🏿‍♀️ woman climbing: dark skin tone
🤺 person fencing
🏇 horse racing
🏇🏻 horse racing: light skin tone
🏇🏼 horse racing: medium-light skin tone
🏇🏽 horse racing: medium skin tone
🏇🏾 horse racing: medium-dark skin tone
🏇🏿 horse racing: dark skin tone
⛷️ skier
🏂 snowboarder
🏂🏻 snowboarder: light skin tone
🏂🏼 snowboarder: medium-light skin tone
🏂🏽 snowboarder: medium skin tone
🏂🏾 snowboarder: medium-dark skin tone
🏂🏿 snowboarder: dark skin tone
🏌️ person golfing
🏌🏻 person golfing: light skin tone
🏌🏼 person golfing: medium-light skin tone
🏌🏽 person golfing: medium skin tone
🏌🏾 person golfing: medium-dark skin tone
🏌🏿 person golfing: dark skin tone
🏌️‍♂️ man golfing
🏌🏻‍♂️ man golfing: light skin tone
🏌🏼‍♂️ man golfing: medium-light skin tone
🏌🏽‍♂️ man golfing: medium skin tone
🏌🏾‍♂️ man golfing: medium-dark skin tone
🏌🏿‍♂️ man golfing: dark skin tone
🏌️‍♀️ woman golfing
🏌🏻‍♀️ woman golfing: light skin tone
🏌🏼‍♀️ woman golfing: medium-light skin tone
🏌🏽‍♀️ woman golfing: medium skin tone
🏌🏾‍♀️ woman golfing: medium-dark skin tone
🏌🏿‍♀️ woman golfing: dark skin tone
🏄 person surfing
🏄🏻 person surfing: light skin tone
🏄🏼 person surfing: medium-light skin tone
🏄🏽 person surfing: medium skin tone
🏄🏾 person surfing: medium-dark skin tone
🏄🏿 person surfing: dark skin tone
🏄‍♂️ man surfing
🏄🏻‍♂️ man surfing: light skin tone
🏄🏼‍♂️ man surfing: medium-light skin tone
🏄🏽‍♂️ man surfing: medium skin tone
🏄🏾‍♂️ man surfing: medium-dark skin tone
🏄🏿‍♂️ man surfing: dark skin tone
🏄‍♀️ woman surfing
🏄🏻‍♀️ woman surfing: light skin tone
🏄🏼‍♀️ woman surfing: medium-light skin tone
🏄🏽‍♀️ woman surfing: medium skin tone
🏄🏾‍♀️ woman surfing: medium-dark skin tone
🏄🏿‍♀️ woman surfing: dark skin tone
🚣 person rowing boat
🚣🏻 person rowing boat: light skin tone
🚣🏼 person rowing boat: medium-light skin tone
🚣🏽 person rowing boat: medium skin tone
🚣🏾 person rowing boat: medium-dark skin tone
🚣🏿 person rowing boat: dark skin tone
🚣‍♂️ man rowing boat
🚣🏻‍♂️ man rowing boat: light skin tone
🚣🏼‍♂️ man rowing boat: medium-light skin tone
🚣🏽‍♂️ man rowing boat: medium skin tone
🚣🏾‍♂️ man rowing boat: medium-dark skin tone
🚣🏿‍♂️ man rowing boat: dark skin tone
🚣‍♀️ woman rowing boat
🚣🏻‍♀️ woman rowing boat: light skin tone
🚣🏼‍♀️ woman rowing boat: medium-light skin tone
🚣🏽‍♀️ woman rowing boat: medium skin tone
🚣🏾‍♀️ woman rowing boat: medium-dark skin tone
🚣🏿‍♀️ woman rowing boat: dark skin tone
🏊 person swimming
🏊🏻 person swimming: light skin tone
🏊🏼 person swimming: medium-light skin tone
🏊🏽 person swimming: medium skin tone
🏊🏾 person swimming: medium-dark skin tone
🏊🏿 person swimming: dark skin tone
🏊‍♂️ man swimming
🏊🏻‍♂️ man swimming: light skin tone
🏊🏼‍♂️ man swimming: medium-light skin tone
🏊🏽‍♂️ man swimming: medium skin tone
🏊🏾‍♂️ man swimming: medium-dark skin tone
🏊🏿‍♂️ man swimming: dark skin tone
🏊‍♀️ woman swimming
🏊🏻‍♀️ woman swimming: light skin tone
🏊🏼‍♀️ woman swimming: medium-light skin tone
🏊🏽‍♀️ woman swimming: medium skin tone
🏊🏾‍♀️ woman swimming: medium-dark skin tone
🏊🏿‍♀️ woman swimming: dark skin tone
⛹️ person bouncing ball
⛹🏻 person bouncing ball: light skin tone
⛹🏼 person bouncing ball: medium-light skin tone
⛹🏽 person bouncing ball: medium skin tone
⛹🏾 person bouncing ball: medium-dark skin tone
⛹🏿 person bouncing ball: dark skin tone
⛹️‍♂️ man bouncing ball
⛹🏻‍♂️ man bouncing ball: light skin tone
⛹🏼‍♂️ man bouncing ball: medium-light skin tone
⛹🏽‍♂️ man bouncing ball: medium skin tone
⛹🏾‍♂️ man bouncing ball: medium-dark skin tone
⛹🏿‍♂️ man bouncing ball: dark skin tone
⛹️‍♀️ woman bouncing ball
⛹🏻‍♀️ woman bouncing ball: light skin tone
⛹🏼‍♀️ woman bouncing ball: medium-light skin tone
⛹🏽‍♀️ woman bouncing ball: medium skin tone
⛹🏾‍♀️ woman bouncing ball: medium-dark skin tone
⛹🏿‍♀️ woman bouncing ball: dark skin tone
🏋️ person lifting weights
🏋🏻 person lifting weights: light skin tone
🏋🏼 person lifting weights: medium-light skin tone
🏋🏽 person lifting weights: medium skin tone
🏋🏾 person lifting weights: medium-dark skin tone
🏋🏿 person lifting weights: dark skin tone
🏋️‍♂️ man lifting weights
🏋🏻‍♂️ man lifting weights: light skin tone
🏋🏼‍♂️ man lifting weights: medium-light skin tone
🏋🏽‍♂️ man lifting weights: medium skin tone
🏋🏾‍♂️ man lifting weights: medium-dark skin tone
🏋🏿‍♂️ man lifting weights: dark skin tone
🏋️‍♀️ woman lifting weights
🏋🏻‍♀️ woman lifting weights: light skin tone
🏋🏼‍♀️ woman lifting weights: medium-light skin tone
🏋🏽‍♀️ woman lifting weights: medium skin tone
🏋🏾‍♀️ woman lifting weights: medium-dark skin tone
🏋🏿‍♀️ woman lifting weights: dark skin tone
🚴 person biking
🚴🏻 person biking: light skin tone
🚴🏼 person biking: medium-light skin tone
🚴🏽 person biking: medium skin tone
🚴🏾 person biking: medium-dark skin tone
🚴🏿 person biking: dark skin tone
🚴‍♂️ man biking
🚴🏻‍♂️ man biking: light skin tone
🚴🏼‍♂️ man biking: medium-light skin tone
🚴🏽‍♂️ man biking: medium skin tone
🚴🏾‍♂️ man biking: medium-dark skin tone
🚴🏿‍♂️ man biking: dark skin tone
🚴‍♀️ woman biking
🚴🏻‍♀️ woman biking: light skin tone
🚴🏼‍♀️ woman biking: medium-light skin tone
🚴🏽‍♀️ woman biking: medium skin tone
🚴🏾‍♀️ woman biking: medium-dark skin tone
🚴🏿‍♀️ woman biking: dark skin tone
🚵 person mountain biking
🚵🏻 person mountain biking: light skin tone
🚵🏼 person mountain biking: medium-light skin tone
🚵🏽 person mountain biking: medium skin tone
🚵🏾 person mountain biking: medium-dark skin tone
🚵🏿 person mountain biking: dark skin tone
🚵‍♂️ man mountain biking
🚵🏻‍♂️ man mountain biking: light skin tone
🚵🏼‍♂️ man mountain biking: medium-light skin tone
🚵🏽‍♂️ man mountain biking: medium skin tone
🚵🏾‍♂️ man mountain biking: medium-dark skin tone
🚵🏿‍♂️ man mountain biking: dark skin tone
🚵‍♀️ woman mountain biking
🚵🏻‍♀️ woman mountain biking: light skin tone
🚵🏼‍♀️ woman mountain biking: medium-light skin tone
🚵🏽‍♀️ woman mountain biking: medium skin tone
🚵🏾‍♀️ woman mountain biking: medium-dark skin tone
🚵🏿‍♀️ woman mountain biking: dark skin tone
🤸 person cartwheeling
🤸🏻 person cartwheeling: light skin tone
🤸🏼 person cartwheeling: medium-light skin tone
🤸🏽 person cartwheeling: medium skin tone
🤸🏾 person cartwheeling: medium-dark skin tone
🤸🏿 person cartwheeling: dark skin tone
🤸‍♂️ man cartwheeling
🤸🏻‍♂️ man cartwheeling: light skin tone
🤸🏼‍♂️ man cartwheeling: medium-light skin tone
🤸🏽‍♂️ man cartwheeling: medium skin tone
🤸🏾‍♂️ man cartwheeling: medium-dark skin tone
🤸🏿‍♂️ man cartwheeling: dark skin tone
🤸‍♀️ woman cartwheeling
🤸🏻‍♀️ woman cartwheeling: light skin tone
🤸🏼‍♀️ woman cartwheeling: medium-light skin tone
🤸🏽‍♀️ woman cartwheeling: medium skin tone
🤸🏾‍♀️ woman cartwheeling: medium-dark skin tone
🤸🏿‍♀️ woman cartwheeling: dark skin tone
🤼 people wrestling
🤼‍♂️ men wrestling
🤼‍♀️ women wrestling
🤽 person playing water polo
🤽🏻 person playing water polo: light skin tone
🤽🏼 person playing water polo: medium-light skin tone
🤽🏽 person playing water polo: medium skin tone
🤽🏾 person playing water polo: medium-dark skin tone
🤽🏿 person playing water polo: dark skin tone
🤽‍♂️ man playing water polo
🤽🏻‍♂️ man playing water polo: light skin tone
🤽🏼‍♂️ man playing water polo: medium-light skin tone
🤽🏽‍♂️ man playing water polo: medium skin tone
🤽🏾‍♂️ man playing water polo: medium-dark skin tone
🤽🏿‍♂️ man playing water polo: dark skin tone
🤽‍♀️ woman playing water polo
🤽🏻‍♀️ woman playing water polo: light skin tone
🤽🏼‍♀️ woman playing water polo: medium-light skin tone
🤽🏽‍♀️ woman playing water polo: medium skin tone
🤽🏾‍♀️ woman playing water polo: medium-dark skin tone
🤽🏿‍♀️ woman playing water polo: dark skin tone
🤾 person playing handball
🤾🏻 person playing handball: light skin tone
🤾🏼 person playing handball: medium-light skin tone
🤾🏽 person playing handball: medium skin tone
🤾🏾 person playing handball: medium-dark skin tone
🤾🏿 person playing handball: dark skin tone
🤾‍♂️ man playing handball
🤾🏻‍♂️ man playing handball: light skin tone
🤾🏼‍♂️ man playing handball: medium-light skin tone
🤾🏽‍♂️ man playing handball: medium skin tone
🤾🏾‍♂️ man playing handball: medium-dark skin tone
🤾🏿‍♂️ man playing handball: dark skin tone
🤾‍♀️ woman playing handball
🤾🏻‍♀️ woman playing handball: light skin tone
🤾🏼‍♀️ woman playing handball: medium-light skin tone
🤾🏽‍♀️ woman playing handball: medium skin tone
🤾🏾‍♀️ woman playing handball: medium-dark skin tone
🤾🏿‍♀️ woman playing handball: dark skin tone
🤹 person juggling
🤹🏻 person juggling: light skin tone
🤹🏼 person juggling: medium-light skin tone
🤹🏽 person juggling: medium skin tone
🤹🏾 person juggling: medium-dark skin tone
🤹🏿 person juggling: dark skin tone
🤹‍♂️ man juggling
🤹🏻‍♂️ man juggling: light skin tone
🤹🏼‍♂️ man juggling: medium-light skin tone
🤹🏽‍♂️ man juggling: medium skin tone
🤹🏾‍♂️ man juggling: medium-dark skin tone
🤹🏿‍♂️ man juggling: dark skin tone
🤹‍♀️ woman juggling
🤹🏻‍♀️ woman juggling: light skin tone
🤹🏼‍♀️ woman juggling: medium-light skin tone
🤹🏽‍♀️ woman juggling: medium skin tone
🤹🏾‍♀️ woman juggling: medium-dark skin tone
🤹🏿‍♀️ woman juggling: dark skin tone
🧘 person in lotus position
🧘🏻 person in lotus position: light skin tone
🧘🏼 person in lotus position: medium-light skin tone
🧘🏽 person in lotus position: medium skin tone
🧘🏾 person in lotus position: medium-dark skin tone
🧘🏿 person in lotus position: dark skin tone
🧘‍♂️ man in lotus position
🧘🏻‍♂️ man in lotus position: light skin tone
🧘🏼‍♂️ man in lotus position: medium-light skin tone
🧘🏽‍♂️ man in lotus position: medium skin tone
🧘🏾‍♂️ man in lotus position: medium-dark skin tone
🧘🏿‍♂️ man in lotus position: dark skin tone
🧘‍♀️ woman in lotus position
🧘🏻‍♀️ woman in lotus position: light skin tone
🧘🏼‍♀️ woman in lotus position: medium-light skin tone
🧘🏽‍♀️ woman in lotus position: medium skin tone
🧘🏾‍♀️ woman in lotus position: medium-dark skin tone
🧘🏿‍♀️ woman in lotus position: dark skin tone
🛀 person taking bath
🛀🏻 person taking bath: light skin tone
🛀🏼 person taking bath: medium-light skin tone
🛀🏽 person taking bath: medium skin tone
🛀🏾 person taking bath: medium-dark skin tone
🛀🏿 person taking bath: dark skin tone
🛌 person in bed
🛌🏻 person in bed: light skin tone
🛌🏼 person in bed: medium-light skin tone
🛌🏽 person in bed: medium skin tone
🛌🏾 person in bed: medium-dark skin tone
🛌🏿 person in bed: dark skin tone
🧑‍🤝‍🧑 people holding hands
🧑🏻‍🤝‍🧑🏻 people holding hands: light skin tone
🧑🏻‍🤝‍🧑🏼 people holding hands: light skin tone, medium-light skin tone
🧑🏻‍🤝‍🧑🏽 people holding hands: light skin tone, medium skin tone
🧑🏻‍🤝‍🧑🏾 people holding hands: light skin tone, medium-dark skin tone
🧑🏻‍🤝‍🧑🏿 people holding hands: light skin tone, dark skin tone
🧑🏼‍🤝‍🧑🏻 people holding hands: medium-light skin tone, light skin tone
🧑🏼‍🤝‍🧑🏼 people holding hands: medium-light skin tone
🧑🏼‍🤝‍🧑🏽 people holding hands: medium-light skin tone, medium skin tone
🧑🏼‍🤝‍🧑🏾 people holding hands: medium-light skin tone, medium-dark skin tone
🧑🏼‍🤝‍🧑🏿 people holding hands: medium-light skin tone, dark skin tone
🧑🏽‍🤝‍🧑🏻 people holding hands: medium skin tone, light skin tone
🧑🏽‍🤝‍🧑🏼 people holding hands: medium skin tone, medium-light skin tone
🧑🏽‍🤝‍🧑🏽 people holding hands: medium skin tone
🧑🏽‍🤝‍🧑🏾 people holding hands: medium skin tone, medium-dark skin tone
🧑🏽‍🤝‍🧑🏿 people holding hands: medium skin tone, dark skin tone
🧑🏾‍🤝‍🧑🏻 people holding hands: medium-dark skin tone, light skin tone
🧑🏾‍🤝‍🧑🏼 people holding hands: medium-dark skin tone, medium-light skin tone
🧑🏾‍🤝‍🧑🏽 people holding hands: medium-dark skin tone, medium skin tone
🧑🏾‍🤝‍🧑🏾 people holding hands: medium-dark skin tone
🧑🏾‍🤝‍🧑🏿 people holding hands: medium-dark skin tone, dark skin tone
🧑🏿‍🤝‍🧑🏻 people holding hands: dark skin tone, light skin tone
🧑🏿‍🤝‍🧑🏼 people holding hands: dark skin tone, medium-light skin tone
🧑🏿‍🤝‍🧑🏽 people holding hands: dark skin tone, medium skin tone
🧑🏿‍🤝‍🧑🏾 people holding hands: dark skin tone, medium-dark skin tone
🧑🏿‍🤝‍🧑🏿 people holding hands: dark skin tone
👭 women holding hands
👭🏻 women holding hands: light skin tone
👩🏻‍🤝‍👩🏼 women holding hands: light skin tone, medium-light skin tone
👩🏻‍🤝‍👩🏽 women holding hands: light skin tone, medium skin tone
👩🏻‍🤝‍👩🏾 women holding hands: light skin tone, medium-dark skin tone
👩🏻‍🤝‍👩🏿 women holding hands: light skin tone, dark skin tone
👩🏼‍🤝‍👩🏻 women holding hands: medium-light skin tone, light skin tone
👭🏼 women holding hands: medium-light skin tone
👩🏼‍🤝‍👩🏽 women holding hands: medium-light skin tone, medium skin tone
👩🏼‍🤝‍👩🏾 women holding hands: medium-light skin tone, medium-dark skin tone
👩🏼‍🤝‍👩🏿 women holding hands: medium-light skin tone, dark skin tone
👩🏽‍🤝‍👩🏻 women holding hands: medium skin tone, light skin tone
👩🏽‍🤝‍👩🏼 women holding hands: medium skin tone, medium-light skin tone
👭🏽 women holding hands: medium skin tone
👩🏽‍🤝‍👩🏾 women holding hands: medium skin tone, medium-dark skin tone
👩🏽‍🤝‍👩🏿 women holding hands: medium skin tone, dark skin tone
👩🏾‍🤝‍👩🏻 women holding hands: medium-dark skin tone, light skin tone
👩🏾‍🤝‍👩🏼 women holding hands: medium-dark skin tone, medium-light skin tone
👩🏾‍🤝‍👩🏽 women holding hands: medium-dark skin tone, medium skin tone
👭🏾 women holding hands: medium-dark skin tone
👩🏾‍🤝‍👩🏿 women holding hands: medium-dark skin tone, dark skin tone
👩🏿‍🤝‍👩🏻 women holding hands: dark skin tone, light skin tone
👩🏿‍🤝‍👩🏼 women holding hands: dark skin tone, medium-light skin tone
👩🏿‍🤝‍👩🏽 women holding hands: dark skin tone, medium skin tone
👩🏿‍🤝‍👩🏾 women holding hands: dark skin tone, medium-dark skin tone
👭🏿 women holding hands: dark skin tone
👫 woman and man holding hands
👫🏻 woman and man holding hands: light skin tone
👩🏻‍🤝‍👨🏼 woman and man holding hands: light skin tone, medium-light skin tone
👩🏻‍🤝‍👨🏽 woman and man holding hands: light skin tone, medium skin tone
👩🏻‍🤝‍👨🏾 woman and man holding hands: light skin tone, medium-dark skin tone
👩🏻‍🤝‍👨🏿 woman and man holding hands: light skin tone, dark skin tone
👩🏼‍🤝‍👨🏻 woman and man holding hands: medium-light skin tone, light skin tone
👫🏼 woman and man holding hands: medium-light skin tone
👩🏼‍🤝‍👨🏽 woman and man holding hands: medium-light skin tone, medium skin tone
👩🏼‍🤝‍👨🏾 woman and man holding hands: medium-light skin tone, medium-dark skin tone
👩🏼‍🤝‍👨🏿 woman and man holding hands: medium-light skin tone, dark skin tone
👩🏽‍🤝‍👨🏻 woman and man holding hands: medium skin tone, light skin tone
👩🏽‍🤝‍👨🏼 woman and man holding hands: medium skin tone, medium-light skin tone
👫🏽 woman and man holding hands: medium skin tone
👩🏽‍🤝‍👨🏾 woman and man holding hands: medium skin tone, medium-dark skin tone
👩🏽‍🤝‍👨🏿 woman and man holding hands: medium skin tone, dark skin tone
👩🏾‍🤝‍👨🏻 woman and man holding hands: medium-dark skin tone, light skin tone
👩🏾‍🤝‍👨🏼 woman and man holding hands: medium-dark skin tone, medium-light skin tone
👩🏾‍🤝‍👨🏽 woman and man holding hands: medium-dark skin tone, medium skin tone
👫🏾 woman and man holding hands: medium-dark skin tone
👩🏾‍🤝‍👨🏿 woman and man holding hands: medium-dark skin tone, dark skin tone
👩🏿‍🤝‍👨🏻 woman and man holding hands: dark skin tone, light skin tone
👩🏿‍🤝‍👨🏼 woman and man holding hands: dark skin tone, medium-light skin tone
👩🏿‍🤝‍👨🏽 woman and man holding hands: dark skin tone, medium skin tone
👩🏿‍🤝‍👨🏾 woman and man holding hands: dark skin tone, medium-dark skin tone
👫🏿 woman and man holding hands: dark skin tone
👬 men holding hands
👬🏻 men holding hands: light skin tone
👨🏻‍🤝‍👨🏼 men holding hands: light skin tone, medium-light skin tone
👨🏻‍🤝‍👨🏽 men holding hands: light skin tone, medium skin tone
👨🏻‍🤝‍👨🏾 men holding hands: light skin tone, medium-dark skin tone
👨🏻‍🤝‍👨🏿 men holding hands: light skin tone, dark skin tone
👨🏼‍🤝‍👨🏻 men holding hands: medium-light skin tone, light skin tone
👬🏼 men holding hands: medium-light skin tone
👨🏼‍🤝‍👨🏽 men holding hands: medium-light skin tone, medium skin tone
👨🏼‍🤝‍👨🏾 men holding hands: medium-light skin tone, medium-dark skin tone
👨🏼‍🤝‍👨🏿 men holding hands: medium-light skin tone, dark skin tone
👨🏽‍🤝‍👨🏻 men holding hands: medium skin tone, light skin tone
👨🏽‍🤝‍👨🏼 men holding hands: medium skin tone, medium-light skin tone
👬🏽 men holding hands: medium skin tone
👨🏽‍🤝‍👨🏾 men holding hands: medium skin tone, medium-dark skin tone
👨🏽‍🤝‍👨🏿 men holding hands: medium skin tone, dark skin tone
👨🏾‍🤝‍👨🏻 men holding hands: medium-dark skin tone, light skin tone
👨🏾‍🤝‍👨🏼 men holding hands: medium-dark skin tone, medium-light skin tone
👨🏾‍🤝‍👨🏽 men holding hands: medium-dark skin tone, medium skin tone
👬🏾 men holding hands: medium-dark skin tone
👨🏾‍🤝‍👨🏿 men holding hands: medium-dark skin tone, dark skin tone
👨🏿‍🤝‍👨🏻 men holding hands: dark skin tone, light skin tone
👨🏿‍🤝‍👨🏼 men holding hands: dark skin tone, medium-light skin tone
👨🏿‍🤝‍👨🏽 men holding hands: dark skin tone, medium skin tone
👨🏿‍🤝‍👨🏾 men holding hands: dark skin tone, medium-dark skin tone
👬🏿 men holding hands: dark skin tone
💏 kiss
💏🏻 kiss: light skin tone
💏🏼 kiss: medium-light skin tone
💏🏽 kiss: medium skin tone
💏🏾 kiss: medium-dark skin tone
💏🏿 kiss: dark skin tone
🧑🏻‍❤️‍💋‍🧑🏼 kiss: person, person, light skin tone, medium-light skin tone
🧑🏻‍❤️‍💋‍🧑🏽 kiss: person, person, light skin tone, medium skin tone
🧑🏻‍❤️‍💋‍🧑🏾 kiss: person, person, light skin tone, medium-dark skin tone
🧑🏻‍❤️‍💋‍🧑🏿 kiss: person, person, light skin tone, dark skin tone
🧑🏼‍❤️‍💋‍🧑🏻 kiss: person, person, medium-light skin tone, light skin tone
🧑🏼‍❤️‍💋‍🧑🏽 kiss: person, person, medium-light skin tone, medium skin tone
🧑🏼‍❤️‍💋‍🧑🏾 kiss: person, person, medium-light skin tone, medium-dark skin tone
🧑🏼‍❤️‍💋‍🧑🏿 kiss: person, person, medium-light skin tone, dark skin tone
🧑🏽‍❤️‍💋‍🧑🏻 kiss: person, person, medium skin tone, light skin tone
🧑🏽‍❤️‍💋‍🧑🏼 kiss: person, person, medium skin tone, medium-light skin tone
🧑🏽‍❤️‍💋‍🧑🏾 kiss: person, person, medium skin tone, medium-dark skin tone
🧑🏽‍❤️‍💋‍🧑🏿 kiss: person, person, medium skin tone, dark skin tone
🧑🏾‍❤️‍💋‍🧑🏻 kiss: person, person, medium-dark skin tone, light skin tone
🧑🏾‍❤️‍💋‍🧑🏼 kiss: person, person, medium-dark skin tone, medium-light skin tone
🧑🏾‍❤️‍💋‍🧑🏽 kiss: person, person, medium-dark skin tone, medium skin tone
🧑🏾‍❤️‍💋‍🧑🏿 kiss: person, person, medium-dark skin tone, dark skin tone
🧑🏿‍❤️‍💋‍🧑🏻 kiss: person, person, dark skin tone, light skin tone
🧑🏿‍❤️‍💋‍🧑🏼 kiss: person, person, dark skin tone, medium-light skin tone
🧑🏿‍❤️‍💋‍🧑🏽 kiss: person, person, dark skin tone, medium skin tone
🧑🏿‍❤️‍💋‍🧑🏾 kiss: person, person, dark skin tone, medium-dark skin tone
👩‍❤️‍💋‍👨 kiss: woman, man
👩🏻‍❤️‍💋‍👨🏻 kiss: woman, man, light skin tone
👩🏻‍❤️‍💋‍👨🏼 kiss: woman, man, light skin tone, medium-light skin tone
👩🏻‍❤️‍💋‍👨🏽 kiss: woman, man, light skin tone, medium skin tone
👩🏻‍❤️‍💋‍👨🏾 kiss: woman, man, light skin tone, medium-dark skin tone
👩🏻‍❤️‍💋‍👨🏿 kiss: woman, man, light skin tone, dark skin tone
👩🏼‍❤️‍💋‍👨🏻 kiss: woman, man, medium-light skin tone, light skin tone
👩🏼‍❤️‍💋‍👨🏼 kiss: woman, man, medium-light skin tone
👩🏼‍❤️‍💋‍👨🏽 kiss: woman, man, medium-light skin tone, medium skin tone
👩🏼‍❤️‍💋‍👨🏾 kiss: woman, man, medium-light skin tone, medium-dark skin tone
👩🏼‍❤️‍💋‍👨🏿 kiss: woman, man, medium-light skin tone, dark skin tone
👩🏽‍❤️‍💋‍👨🏻 kiss: woman, man, medium skin tone, light skin tone
👩🏽‍❤️‍💋‍👨🏼 kiss: woman, man, medium skin tone, medium-light skin tone
👩🏽‍❤️‍💋‍👨🏽 kiss: woman, man, medium skin tone
👩🏽‍❤️‍💋‍👨🏾 kiss: woman, man, medium skin tone, medium-dark skin tone
👩🏽‍❤️‍💋‍👨🏿 kiss: woman, man, medium skin tone, dark skin tone
👩🏾‍❤️‍💋‍👨🏻 kiss: woman, man, medium-dark skin tone, light skin tone
👩🏾‍❤️‍💋‍👨🏼 kiss: woman, man, medium-dark skin tone, medium-light skin tone
👩🏾‍❤️‍💋‍👨🏽 kiss: woman, man, medium-dark skin tone, medium skin tone
👩🏾‍❤️‍💋‍👨🏾 kiss: woman, man, medium-dark skin tone
👩🏾‍❤️‍💋‍👨🏿 kiss: woman, man, medium-dark skin tone, dark skin tone
👩🏿‍❤️‍💋‍👨🏻 kiss: woman, man, dark skin tone, light skin tone
👩🏿‍❤️‍💋‍👨🏼 kiss: woman, man, dark skin tone, medium-light skin tone
👩🏿‍❤️‍💋‍👨🏽 kiss: woman, man, dark skin tone, medium skin tone
👩🏿‍❤️‍💋‍👨🏾 kiss: woman, man, dark skin tone, medium-dark skin tone
👩🏿‍❤️‍💋‍👨🏿 kiss: woman, man, dark skin tone
👨‍❤️‍💋‍👨 kiss: man, man
👨🏻‍❤️‍💋‍👨🏻 kiss: man, man, light skin tone
👨🏻‍❤️‍💋‍👨🏼 kiss: man, man, light skin tone, medium-light skin tone
👨🏻‍❤️‍💋‍👨🏽 kiss: man, man, light skin tone, medium skin tone
👨🏻‍❤️‍💋‍👨🏾 kiss: man, man, light skin tone, medium-dark skin tone
👨🏻‍❤️‍💋‍👨🏿 kiss: man, man, light skin tone, dark skin tone
👨🏼‍❤️‍💋‍👨🏻 kiss: man, man, medium-light skin tone, light skin tone
👨🏼‍❤️‍💋‍👨🏼 kiss: man, man, medium-light skin tone
👨🏼‍❤️‍💋‍👨🏽 kiss: man, man, medium-light skin tone, medium skin tone
👨🏼‍❤️‍💋‍👨🏾 kiss: man, man, medium-light skin tone, medium-dark skin tone
👨🏼‍❤️‍💋‍👨🏿 kiss: man, man, medium-light skin tone, dark skin tone
👨🏽‍❤️‍💋‍👨🏻 kiss: man, man, medium skin tone, light skin tone
👨🏽‍❤️‍💋‍👨🏼 kiss: man, man, medium skin tone, medium-light skin tone
👨🏽‍❤️‍💋‍👨🏽 kiss: man, man, medium skin tone
👨🏽‍❤️‍💋‍👨🏾 kiss: man, man, medium skin tone, medium-dark skin tone
👨🏽‍❤️‍💋‍👨🏿 kiss: man, man, medium skin tone, dark skin tone
👨🏾‍❤️‍💋‍👨🏻 kiss: man, man, medium-dark skin tone, light skin tone
👨🏾‍❤️‍💋‍👨🏼 kiss: man, man, medium-dark skin tone, medium-light skin tone
👨🏾‍❤️‍💋‍👨🏽 kiss: man, man, medium-dark skin tone, medium skin tone
👨🏾‍❤️‍💋‍👨🏾 kiss: man, man, medium-dark skin tone
👨🏾‍❤️‍💋‍👨🏿 kiss: man, man, medium-dark skin tone, dark skin tone
👨🏿‍❤️‍💋‍👨🏻 kiss: man, man, dark skin tone, light skin tone
👨🏿‍❤️‍💋‍👨🏼 kiss: man, man, dark skin tone, medium-light skin tone
👨🏿‍❤️‍💋‍👨🏽 kiss: man, man, dark skin tone, medium skin tone
👨🏿‍❤️‍💋‍👨🏾 kiss: man, man, dark skin tone, medium-dark skin tone
👨🏿‍❤️‍💋‍👨🏿 kiss: man, man, dark skin tone
👩‍❤️‍💋‍👩 kiss: woman, woman
👩🏻‍❤️‍💋‍👩🏻 kiss: woman, woman, light skin tone
👩🏻‍❤️‍💋‍👩🏼 kiss: woman, woman, light skin tone, medium-light skin tone
👩🏻‍❤️‍💋‍👩🏽 kiss: woman, woman, light skin tone, medium skin tone
👩🏻‍❤️‍💋‍👩🏾 kiss: woman, woman, light skin tone, medium-dark skin tone
👩🏻‍❤️‍💋‍👩🏿 kiss: woman, woman, light skin tone, dark skin tone
👩🏼‍❤️‍💋‍👩🏻 kiss: woman, woman, medium-light skin tone, light skin tone
👩🏼‍❤️‍💋‍👩🏼 kiss: woman, woman, medium-light skin tone
👩🏼‍❤️‍💋‍👩🏽 kiss: woman, woman, medium-light skin tone, medium skin tone
👩🏼‍❤️‍💋‍👩🏾 kiss: woman, woman, medium-light skin tone, medium-dark skin tone
👩🏼‍❤️‍💋‍👩🏿 kiss: woman, woman, medium-light skin tone, dark skin tone
👩🏽‍❤️‍💋‍👩🏻 kiss: woman, woman, medium skin tone, light skin tone
👩🏽‍❤️‍💋‍👩🏼 kiss: woman, woman, medium skin tone, medium-light skin tone
👩🏽‍❤️‍💋‍👩🏽 kiss: woman, woman, medium skin tone
👩🏽‍❤️‍💋‍👩🏾 kiss: woman, woman, medium skin tone, medium-dark skin tone
👩🏽‍❤️‍💋‍👩🏿 kiss: woman, woman, medium skin tone, dark skin tone
👩🏾‍❤️‍💋‍👩🏻 kiss: woman, woman, medium-dark skin tone, light skin tone
👩🏾‍❤️‍💋‍👩🏼 kiss: woman, woman, medium-dark skin tone, medium-light skin tone
👩🏾‍❤️‍💋‍👩🏽 kiss: woman, woman, medium-dark skin tone, medium skin tone
👩🏾‍❤️‍💋‍👩🏾 kiss: woman, woman, medium-dark skin tone
👩🏾‍❤️‍💋‍👩🏿 kiss: woman, woman, medium-dark skin tone, dark skin tone
👩🏿‍❤️‍💋‍👩🏻 kiss: woman, woman, dark skin tone, light skin tone
👩🏿‍❤️‍💋‍👩🏼 kiss: woman, woman, dark skin tone, medium-light skin tone
👩🏿‍❤️‍💋‍👩🏽 kiss: woman, woman, dark skin tone, medium skin tone
👩🏿‍❤️‍💋‍👩🏾 kiss: woman, woman, dark skin tone, medium-dark skin tone
👩🏿‍❤️‍💋‍👩🏿 kiss: woman, woman, dark skin tone
💑 couple with heart
💑🏻 couple with heart: light skin tone
💑🏼 couple with heart: medium-light skin tone
💑🏽 couple with heart: medium skin tone
💑🏾 couple with heart: medium-dark skin tone
💑🏿 couple with heart: dark skin tone
🧑🏻‍❤️‍🧑🏼 couple with heart: person, person, light skin tone, medium-light skin tone
🧑🏻‍❤️‍🧑🏽 couple with heart: person, person, light skin tone, medium skin tone
🧑🏻‍❤️‍🧑🏾 couple with heart: person, person, light skin tone, medium-dark skin tone
🧑🏻‍❤️‍🧑🏿 couple with heart: person, person, light skin tone, dark skin tone
🧑🏼‍❤️‍🧑🏻 couple with heart: person, person, medium-light skin tone, light skin tone
🧑🏼‍❤️‍🧑🏽 couple with heart: person, person, medium-light skin tone, medium skin tone
🧑🏼‍❤️‍🧑🏾 couple with heart: person, person, medium-light skin tone, medium-dark skin tone
🧑🏼‍❤️‍🧑🏿 couple with heart: person, person, medium-light skin tone, dark skin tone
🧑🏽‍❤️‍🧑🏻 couple with heart: person, person, medium skin tone, light skin tone
🧑🏽‍❤️‍🧑🏼 couple with heart: person, person, medium skin tone, medium-light skin tone
🧑🏽‍❤️‍🧑🏾 couple with heart: person, person, medium skin tone, medium-dark skin tone
🧑🏽‍❤️‍🧑🏿 couple with heart: person, person, medium skin tone, dark skin tone
🧑🏾‍❤️‍🧑🏻 couple with heart: person, person, medium-dark skin tone, light skin tone
🧑🏾‍❤️‍🧑🏼 couple with heart: person, person, medium-dark skin tone, medium-light skin tone
🧑🏾‍❤️‍🧑🏽 couple with heart: person, person, medium-dark skin tone, medium skin tone
🧑🏾‍❤️‍🧑🏿 couple with heart: person, person, medium-dark skin tone, dark skin tone
🧑🏿‍❤️‍🧑🏻 couple with heart: person, person, dark skin tone, light skin tone
🧑🏿‍❤️‍🧑🏼 couple with heart: person, person, dark skin tone, medium-light skin tone
🧑🏿‍❤️‍🧑🏽 couple with heart: person, person, dark skin tone, medium skin tone
🧑🏿‍❤️‍🧑🏾 couple with heart: person, person, dark skin tone, medium-dark skin tone
👩‍❤️‍👨 couple with heart: woman, man
👩🏻‍❤️‍👨🏻 couple with heart: woman, man, light skin tone
👩🏻‍❤️‍👨🏼 couple with heart: woman, man, light skin tone, medium-light skin tone
👩🏻‍❤️‍👨🏽 couple with heart: woman, man, light skin tone, medium skin tone
👩🏻‍❤️‍👨🏾 couple with heart: woman, man, light skin tone, medium-dark skin tone
👩🏻‍❤️‍👨🏿 couple with heart: woman, man, light skin tone, dark skin tone
👩🏼‍❤️‍👨🏻 couple with heart: woman, man, medium-light skin tone, light skin tone
👩🏼‍❤️‍👨🏼 couple with heart: woman, man, medium-light skin tone
👩🏼‍❤️‍👨🏽 couple with heart: woman, man, medium-light skin tone, medium skin tone
👩🏼‍❤️‍👨🏾 couple with heart: woman, man, medium-light skin tone, medium-dark skin tone
👩🏼‍❤️‍👨🏿 couple with heart: woman, man, medium-light skin tone, dark skin tone
👩🏽‍❤️‍👨🏻 couple with heart: woman, man, medium skin tone, light skin tone
👩🏽‍❤️‍👨🏼 couple with heart: woman, man, medium skin tone, medium-light skin tone
👩🏽‍❤️‍👨🏽 couple with heart: woman, man, medium skin tone
👩🏽‍❤️‍👨🏾 couple with heart: woman, man, medium skin tone, medium-dark skin tone
👩🏽‍❤️‍👨🏿 couple with heart: woman, man, medium skin tone, dark skin tone
👩🏾‍❤️‍👨🏻 couple with heart: woman, man, medium-dark skin tone, light skin tone
👩🏾‍❤️‍👨🏼 couple with heart: woman, man, medium-dark skin tone, medium-light skin tone
👩🏾‍❤️‍👨🏽 couple with heart: woman, man, medium-dark skin tone, medium skin tone
👩🏾‍❤️‍👨🏾 couple with heart: woman, man, medium-dark skin tone
👩🏾‍❤️‍👨🏿 couple with heart: woman, man, medium-dark skin tone, dark skin tone
👩🏿‍❤️‍👨🏻 couple with heart: woman, man, dark skin tone, light skin tone
👩🏿‍❤️‍👨🏼 couple with heart: woman, man, dark skin tone, medium-light skin tone
👩🏿‍❤️‍👨🏽 couple with heart: woman, man, dark skin tone, medium skin tone
👩🏿‍❤️‍👨🏾 couple with heart: woman, man, dark skin tone, medium-dark skin tone
👩🏿‍❤️‍👨🏿 couple with heart: woman, man, dark skin tone
👨‍❤️‍👨 couple with heart: man, man
👨🏻‍❤️‍👨🏻 couple with heart: man, man, light skin tone
👨🏻‍❤️‍👨🏼 couple with heart: man, man, light skin tone, medium-light skin tone
👨🏻‍❤️‍👨🏽 couple with heart: man, man, light skin tone, medium skin tone
👨🏻‍❤️‍👨🏾 couple with heart: man, man, light skin tone, medium-dark skin tone
👨🏻‍❤️‍👨🏿 couple with heart: man, man, light skin tone, dark skin tone
👨🏼‍❤️‍👨🏻 couple with heart: man, man, medium-light skin tone, light skin tone
👨🏼‍❤️‍👨🏼 couple with heart: man, man, medium-light skin tone
👨🏼‍❤️‍👨🏽 couple with heart: man, man, medium-light skin tone, medium skin tone
👨🏼‍❤️‍👨🏾 couple with heart: man, man, medium-light skin tone, medium-dark skin tone
👨🏼‍❤️‍👨🏿 couple with heart: man, man, medium-light skin tone, dark skin tone
👨🏽‍❤️‍👨🏻 couple with heart: man, man, medium skin tone, light skin tone
👨🏽‍❤️‍👨🏼 couple with heart: man, man, medium skin tone, medium-light skin tone
👨🏽‍❤️‍👨🏽 couple with heart: man, man, medium skin tone
👨🏽‍❤️‍👨🏾 couple with heart: man, man, medium skin tone, medium-dark skin tone
👨🏽‍❤️‍👨🏿 couple with heart: man, man, medium skin tone, dark skin tone
👨🏾‍❤️‍👨🏻 couple with heart: man, man, medium-dark skin tone, light skin tone
👨🏾‍❤️‍👨🏼 couple with heart: man, man, medium-dark skin tone, medium-light skin tone
👨🏾‍❤️‍👨🏽 couple with heart: man, man, medium-dark skin tone, medium skin tone
👨🏾‍❤️‍👨🏾 couple with heart: man, man, medium-dark skin tone
👨🏾‍❤️‍👨🏿 couple with heart: man, man, medium-dark skin tone, dark skin tone
👨🏿‍❤️‍👨🏻 couple with heart: man, man, dark skin tone, light skin tone
👨🏿‍❤️‍👨🏼 couple with heart: man, man, dark skin tone, medium-light skin tone
👨🏿‍❤️‍👨🏽 couple with heart: man, man, dark skin tone, medium skin tone
👨🏿‍❤️‍👨🏾 couple with heart: man, man, dark skin tone, medium-dark skin tone
👨🏿‍❤️‍👨🏿 couple with heart: man, man, dark skin tone
👩‍❤️‍👩 couple with heart: woman, woman
👩🏻‍❤️‍👩🏻 couple with heart: woman, woman, light skin tone
👩🏻‍❤️‍👩🏼 couple with heart: woman, woman, light skin tone, medium-light skin tone
👩🏻‍❤️‍👩🏽 couple with heart: woman, woman, light skin tone, medium skin tone
👩🏻‍❤️‍👩🏾 couple with heart: woman, woman, light skin tone, medium-dark skin tone
👩🏻‍❤️‍👩🏿 couple with heart: woman, woman, light skin tone, dark skin tone
👩🏼‍❤️‍👩🏻 couple with heart: woman, woman, medium-light skin tone, light skin tone
👩🏼‍❤️‍👩🏼 couple with heart: woman, woman, medium-light skin tone
👩🏼‍❤️‍👩🏽 couple with heart: woman, woman, medium-light skin tone, medium skin tone
👩🏼‍❤️‍👩🏾 couple with heart: woman, woman, medium-light skin tone, medium-dark skin tone
👩🏼‍❤️‍👩🏿 couple with heart: woman, woman, medium-light skin tone, dark skin tone
👩🏽‍❤️‍👩🏻 couple with heart: woman, woman, medium skin tone, light skin tone
👩🏽‍❤️‍👩🏼 couple with heart: woman, woman, medium skin tone, medium-light skin tone
👩🏽‍❤️‍👩🏽 couple with heart: woman, woman, medium skin tone
👩🏽‍❤️‍👩🏾 couple with heart: woman, woman, medium skin tone, medium-dark skin tone
👩🏽‍❤️‍👩🏿 couple with heart: woman, woman, medium skin tone, dark skin tone
👩🏾‍❤️‍👩🏻 couple with heart: woman, woman, medium-dark skin tone, light skin tone
👩🏾‍❤️‍👩🏼 couple with heart: woman, woman, medium-dark skin tone, medium-light skin tone
👩🏾‍❤️‍👩🏽 couple with heart: woman, woman, medium-dark skin tone, medium skin tone
👩🏾‍❤️‍👩🏾 couple with heart: woman, woman, medium-dark skin tone
👩🏾‍❤️‍👩🏿 couple with heart: woman, woman, medium-dark skin tone, dark skin tone
👩🏿‍❤️‍👩🏻 couple with heart: woman, woman, dark skin tone, light skin tone
👩🏿‍❤️‍👩🏼 couple with heart: woman, woman, dark skin tone, medium-light skin tone
👩🏿‍❤️‍👩🏽 couple with heart: woman, woman, dark skin tone, medium skin tone
👩🏿‍❤️‍👩🏾 couple with heart: woman, woman, dark skin tone, medium-dark skin tone
👩🏿‍❤️‍👩🏿 couple with heart: woman, woman, dark skin tone
👪 family
👨‍👩‍👦 family: man, woman, boy
👨‍👩‍👧 family: man, woman, girl
👨‍👩‍👧‍👦 family: man, woman, girl, boy
👨‍👩‍👦‍👦 family: man, woman, boy, boy
👨‍👩‍👧‍👧 family: man, woman, girl, girl
👨‍👨‍👦 family: man, man, boy
👨‍👨‍👧 family: man, man, girl
👨‍👨‍👧‍👦 family: man, man, girl, boy
👨‍👨‍👦‍👦 family: man, man, boy, boy
👨‍👨‍👧‍👧 family: man, man, girl, girl
👩‍👩‍👦 family: woman, woman, boy
👩‍👩‍👧 family: woman, woman, girl
👩‍👩‍👧‍👦 family: woman, woman, girl, boy
👩‍👩‍👦‍👦 family: woman, woman, boy, boy
👩‍👩‍👧‍👧 family: woman, woman, girl, girl
👨‍👦 family: man, boy
👨‍👦‍👦 family: man, boy, boy
👨‍👧 family: man, girl
👨‍👧‍👦 family: man, girl, boy
👨‍👧‍👧 family: man, girl, girl
👩‍👦 family: woman, boy
👩‍👦‍👦 family: woman, boy, boy
👩‍👧 family: woman, girl
👩‍👧‍👦 family: woman, girl, boy
👩‍👧‍👧 family: woman, girl, girl
🗣️ speaking head
👤 bust in silhouette
👥 busts in silhouette


@@ 316,17 2319,21 @@
🐶 dog face
🐕 dog
🦮 guide dog
🐕‍🦺 service dog
🐩 poodle
🐺 wolf
🦊 fox
🦝 raccoon
🐱 cat face
🐈 cat
🐈‍⬛ black cat
🦁 lion
🐯 tiger face
🐅 tiger
🐆 leopard
🐴 horse face
🫎 moose
🫏 donkey
🐎 horse
🦄 unicorn
🦓 zebra


@@ 362,6 2369,7 @@
🦔 hedgehog
🦇 bat
🐻 bear
🐻‍❄️ polar bear
🐨 koala
🐼 panda
🦥 sloth


@@ 388,6 2396,9 @@
🦩 flamingo
🦚 peacock
🦜 parrot
🪽 wing
🐦‍⬛ black bird
🪿 goose
🐸 frog
🐊 crocodile
🐢 turtle


@@ 408,6 2419,7 @@
🐙 octopus
🐚 spiral shell
🪸 coral
🪼 jellyfish
🐌 snail
🦋 butterfly
🐛 bug


@@ 435,6 2447,7 @@
🌻 sunflower
🌼 blossom
🌷 tulip
🪻 hyacinth
🌱 seedling
🪴 potted plant
🌲 evergreen tree


@@ 450,6 2463,7 @@
🍃 leaf fluttering in wind
🪹 empty nest
🪺 nest with eggs
🍄 mushroom
🍇 grapes
🍈 melon
🍉 watermelon


@@ 481,10 2495,11 @@
🥦 broccoli
🧄 garlic
🧅 onion
🍄 mushroom
🥜 peanuts
🫘 beans
🌰 chestnut
🫚 ginger root
🫛 pea pod
🍞 bread
🥐 croissant
🥖 baguette bread


@@ 857,11 2872,10 @@
🎯 bullseye
🪀 yo-yo
🪁 kite
🔫 water pistol
🎱 pool 8 ball
🔮 crystal ball
🪄 magic wand
🧿 nazar amulet
🪬 hamsa
🎮 video game
🕹️ joystick
🎰 slot machine


@@ 906,6 2920,7 @@
🩳 shorts
👙 bikini
👚 woman’s clothes
🪭 folding hand fan
👛 purse
👜 handbag
👝 clutch bag


@@ 920,6 2935,7 @@
👡 woman’s sandal
🩰 ballet shoes
👢 woman’s boot
🪮 hair pick
👑 crown
👒 woman’s hat
🎩 top hat


@@ 958,6 2974,8 @@
🪕 banjo
🥁 drum
🪘 long drum
🪇 maracas
🪈 flute
📱 mobile phone
📲 mobile phone with arrow
☎️ telephone


@@ 1077,7 3095,7 @@
🛠️ hammer and wrench
🗡️ dagger
⚔️ crossed swords
🔫 water pistol
💣 bomb
🪃 boomerang
🏹 bow and arrow
🛡️ shield


@@ 1138,6 3156,8 @@
⚰️ coffin
🪦 headstone
⚱️ funeral urn
🧿 nazar amulet
🪬 hamsa
🗿 moai
🪧 placard
🪪 identification card


@@ 1200,6 3220,7 @@
☮️ peace symbol
🕎 menorah
🔯 dotted six-pointed star
🪯 khanda
♈ Aries
♉ Taurus
♊ Gemini


@@ 1235,6 3256,7 @@
🔅 dim button
🔆 bright button
📶 antenna bars
🛜 wireless
📳 vibration mode
📴 mobile phone off
♀️ female sign


@@ 1367,6 3389,9 @@
🎌 crossed flags
🏴 black flag
🏳️ white flag
🏳️‍🌈 rainbow flag
🏳️‍⚧️ transgender flag
🏴‍☠️ pirate flag
🇦🇨 flag: Ascension Island
🇦🇩 flag: Andorra
🇦🇪 flag: United Arab Emirates


@@ 1627,4 3652,4 @@
🇿🇼 flag: Zimbabwe
🏴󠁧󠁢󠁥󠁮󠁧󠁿 flag: England
🏴󠁧󠁢󠁳󠁣󠁴󠁿 flag: Scotland
🏴󠁧󠁢󠁷󠁬󠁳󠁿 flag: Wales
\ No newline at end of file
🏴󠁧󠁢󠁷󠁬󠁳󠁿 flag: Wales

M .local/share/lazykris/emoji => .local/share/lazykris/emoji +2034 -9
@@ 40,11 40,14 @@
😑 expressionless face
😶 face without mouth
🫥 dotted line face
😶‍🌫️ face in clouds
😏 smirking face
😒 unamused face
🙄 face with rolling eyes
😬 grimacing face
😮‍💨 face exhaling
🤥 lying face
🫨 shaking face
😌 relieved face
😔 pensive face
😪 sleepy face


@@ 60,6 63,7 @@
🥶 cold face
🥴 woozy face
😵 face with crossed-out eyes
😵‍💫 face with spiral eyes
🤯 exploding head
🤠 cowboy hat face
🥳 partying face


@@ 94,7 98,7 @@
😫 tired face
🥱 yawning face
😤 face with steam from nose
😡 pouting face
😡 enraged face
😠 angry face
🤬 face with symbols on mouth
😈 smiling face with horns


@@ 121,7 125,6 @@
🙈 see-no-evil monkey
🙉 hear-no-evil monkey
🙊 speak-no-evil monkey
💋 kiss mark
💌 love letter
💘 heart with arrow
💝 heart with ribbon


@@ 133,15 136,21 @@
💟 heart decoration
❣️ heart exclamation
💔 broken heart
❤️‍🔥 heart on fire
❤️‍🩹 mending heart
❤️ red heart
🩷 pink heart
🧡 orange heart
💛 yellow heart
💚 green heart
💙 blue heart
🩵 light blue heart
💜 purple heart
🤎 brown heart
🖤 black heart
🩶 grey heart
🤍 white heart
💋 kiss mark
💯 hundred points
💢 anger symbol
💥 collision


@@ 149,61 158,328 @@
💦 sweat droplets
💨 dashing away
🕳️ hole
💣 bomb
💬 speech balloon
👁️‍🗨️ eye in speech bubble
🗨️ left speech bubble
🗯️ right anger bubble
💭 thought balloon
💤 zzz
💤 ZZZ
👋 waving hand
👋🏻 waving hand: light skin tone
👋🏼 waving hand: medium-light skin tone
👋🏽 waving hand: medium skin tone
👋🏾 waving hand: medium-dark skin tone
👋🏿 waving hand: dark skin tone
🤚 raised back of hand
🤚🏻 raised back of hand: light skin tone
🤚🏼 raised back of hand: medium-light skin tone
🤚🏽 raised back of hand: medium skin tone
🤚🏾 raised back of hand: medium-dark skin tone
🤚🏿 raised back of hand: dark skin tone
🖐️ hand with fingers splayed
🖐🏻 hand with fingers splayed: light skin tone
🖐🏼 hand with fingers splayed: medium-light skin tone
🖐🏽 hand with fingers splayed: medium skin tone
🖐🏾 hand with fingers splayed: medium-dark skin tone
🖐🏿 hand with fingers splayed: dark skin tone
✋ raised hand
✋🏻 raised hand: light skin tone
✋🏼 raised hand: medium-light skin tone
✋🏽 raised hand: medium skin tone
✋🏾 raised hand: medium-dark skin tone
✋🏿 raised hand: dark skin tone
🖖 vulcan salute
🖖🏻 vulcan salute: light skin tone
🖖🏼 vulcan salute: medium-light skin tone
🖖🏽 vulcan salute: medium skin tone
🖖🏾 vulcan salute: medium-dark skin tone
🖖🏿 vulcan salute: dark skin tone
🫱 rightwards hand
🫱🏻 rightwards hand: light skin tone
🫱🏼 rightwards hand: medium-light skin tone
🫱🏽 rightwards hand: medium skin tone
🫱🏾 rightwards hand: medium-dark skin tone
🫱🏿 rightwards hand: dark skin tone
🫲 leftwards hand
🫲🏻 leftwards hand: light skin tone
🫲🏼 leftwards hand: medium-light skin tone
🫲🏽 leftwards hand: medium skin tone
🫲🏾 leftwards hand: medium-dark skin tone
🫲🏿 leftwards hand: dark skin tone
🫳 palm down hand
🫳🏻 palm down hand: light skin tone
🫳🏼 palm down hand: medium-light skin tone
🫳🏽 palm down hand: medium skin tone
🫳🏾 palm down hand: medium-dark skin tone
🫳🏿 palm down hand: dark skin tone
🫴 palm up hand
🫴🏻 palm up hand: light skin tone
🫴🏼 palm up hand: medium-light skin tone
🫴🏽 palm up hand: medium skin tone
🫴🏾 palm up hand: medium-dark skin tone
🫴🏿 palm up hand: dark skin tone
🫷 leftwards pushing hand
🫷🏻 leftwards pushing hand: light skin tone
🫷🏼 leftwards pushing hand: medium-light skin tone
🫷🏽 leftwards pushing hand: medium skin tone
🫷🏾 leftwards pushing hand: medium-dark skin tone
🫷🏿 leftwards pushing hand: dark skin tone
🫸 rightwards pushing hand
🫸🏻 rightwards pushing hand: light skin tone
🫸🏼 rightwards pushing hand: medium-light skin tone
🫸🏽 rightwards pushing hand: medium skin tone
🫸🏾 rightwards pushing hand: medium-dark skin tone
🫸🏿 rightwards pushing hand: dark skin tone
👌 OK hand
👌🏻 OK hand: light skin tone
👌🏼 OK hand: medium-light skin tone
👌🏽 OK hand: medium skin tone
👌🏾 OK hand: medium-dark skin tone
👌🏿 OK hand: dark skin tone
🤌 pinched fingers
🤌🏻 pinched fingers: light skin tone
🤌🏼 pinched fingers: medium-light skin tone
🤌🏽 pinched fingers: medium skin tone
🤌🏾 pinched fingers: medium-dark skin tone
🤌🏿 pinched fingers: dark skin tone
🤏 pinching hand
🤏🏻 pinching hand: light skin tone
🤏🏼 pinching hand: medium-light skin tone
🤏🏽 pinching hand: medium skin tone
🤏🏾 pinching hand: medium-dark skin tone
🤏🏿 pinching hand: dark skin tone
✌️ victory hand
✌🏻 victory hand: light skin tone
✌🏼 victory hand: medium-light skin tone
✌🏽 victory hand: medium skin tone
✌🏾 victory hand: medium-dark skin tone
✌🏿 victory hand: dark skin tone
🤞 crossed fingers
🤞🏻 crossed fingers: light skin tone
🤞🏼 crossed fingers: medium-light skin tone
🤞🏽 crossed fingers: medium skin tone
🤞🏾 crossed fingers: medium-dark skin tone
🤞🏿 crossed fingers: dark skin tone
🫰 hand with index finger and thumb crossed
🫰🏻 hand with index finger and thumb crossed: light skin tone
🫰🏼 hand with index finger and thumb crossed: medium-light skin tone
🫰🏽 hand with index finger and thumb crossed: medium skin tone
🫰🏾 hand with index finger and thumb crossed: medium-dark skin tone
🫰🏿 hand with index finger and thumb crossed: dark skin tone
🤟 love-you gesture
🤟🏻 love-you gesture: light skin tone
🤟🏼 love-you gesture: medium-light skin tone
🤟🏽 love-you gesture: medium skin tone
🤟🏾 love-you gesture: medium-dark skin tone
🤟🏿 love-you gesture: dark skin tone
🤘 sign of the horns
🤘🏻 sign of the horns: light skin tone
🤘🏼 sign of the horns: medium-light skin tone
🤘🏽 sign of the horns: medium skin tone
🤘🏾 sign of the horns: medium-dark skin tone
🤘🏿 sign of the horns: dark skin tone
🤙 call me hand
🤙🏻 call me hand: light skin tone
🤙🏼 call me hand: medium-light skin tone
🤙🏽 call me hand: medium skin tone
🤙🏾 call me hand: medium-dark skin tone
🤙🏿 call me hand: dark skin tone
👈 backhand index pointing left
👈🏻 backhand index pointing left: light skin tone
👈🏼 backhand index pointing left: medium-light skin tone
👈🏽 backhand index pointing left: medium skin tone
👈🏾 backhand index pointing left: medium-dark skin tone
👈🏿 backhand index pointing left: dark skin tone
👉 backhand index pointing right
👉🏻 backhand index pointing right: light skin tone
👉🏼 backhand index pointing right: medium-light skin tone
👉🏽 backhand index pointing right: medium skin tone
👉🏾 backhand index pointing right: medium-dark skin tone
👉🏿 backhand index pointing right: dark skin tone
👆 backhand index pointing up
👆🏻 backhand index pointing up: light skin tone
👆🏼 backhand index pointing up: medium-light skin tone
👆🏽 backhand index pointing up: medium skin tone
👆🏾 backhand index pointing up: medium-dark skin tone
👆🏿 backhand index pointing up: dark skin tone
🖕 middle finger
🖕🏻 middle finger: light skin tone
🖕🏼 middle finger: medium-light skin tone
🖕🏽 middle finger: medium skin tone
🖕🏾 middle finger: medium-dark skin tone
🖕🏿 middle finger: dark skin tone
👇 backhand index pointing down
👇🏻 backhand index pointing down: light skin tone
👇🏼 backhand index pointing down: medium-light skin tone
👇🏽 backhand index pointing down: medium skin tone
👇🏾 backhand index pointing down: medium-dark skin tone
👇🏿 backhand index pointing down: dark skin tone
☝️ index pointing up
☝🏻 index pointing up: light skin tone
☝🏼 index pointing up: medium-light skin tone
☝🏽 index pointing up: medium skin tone
☝🏾 index pointing up: medium-dark skin tone
☝🏿 index pointing up: dark skin tone
🫵 index pointing at the viewer
🫵🏻 index pointing at the viewer: light skin tone
🫵🏼 index pointing at the viewer: medium-light skin tone
🫵🏽 index pointing at the viewer: medium skin tone
🫵🏾 index pointing at the viewer: medium-dark skin tone
🫵🏿 index pointing at the viewer: dark skin tone
👍 thumbs up
👍🏻 thumbs up: light skin tone
👍🏼 thumbs up: medium-light skin tone
👍🏽 thumbs up: medium skin tone
👍🏾 thumbs up: medium-dark skin tone
👍🏿 thumbs up: dark skin tone
👎 thumbs down
👎🏻 thumbs down: light skin tone
👎🏼 thumbs down: medium-light skin tone
👎🏽 thumbs down: medium skin tone
👎🏾 thumbs down: medium-dark skin tone
👎🏿 thumbs down: dark skin tone
✊ raised fist
✊🏻 raised fist: light skin tone
✊🏼 raised fist: medium-light skin tone
✊🏽 raised fist: medium skin tone
✊🏾 raised fist: medium-dark skin tone
✊🏿 raised fist: dark skin tone
👊 oncoming fist
👊🏻 oncoming fist: light skin tone
👊🏼 oncoming fist: medium-light skin tone
👊🏽 oncoming fist: medium skin tone
👊🏾 oncoming fist: medium-dark skin tone
👊🏿 oncoming fist: dark skin tone
🤛 left-facing fist
🤛🏻 left-facing fist: light skin tone
🤛🏼 left-facing fist: medium-light skin tone
🤛🏽 left-facing fist: medium skin tone
🤛🏾 left-facing fist: medium-dark skin tone
🤛🏿 left-facing fist: dark skin tone
🤜 right-facing fist
🤜🏻 right-facing fist: light skin tone
🤜🏼 right-facing fist: medium-light skin tone
🤜🏽 right-facing fist: medium skin tone
🤜🏾 right-facing fist: medium-dark skin tone
🤜🏿 right-facing fist: dark skin tone
👏 clapping hands
👏🏻 clapping hands: light skin tone
👏🏼 clapping hands: medium-light skin tone
👏🏽 clapping hands: medium skin tone
👏🏾 clapping hands: medium-dark skin tone
👏🏿 clapping hands: dark skin tone
🙌 raising hands
🙌🏻 raising hands: light skin tone
🙌🏼 raising hands: medium-light skin tone
🙌🏽 raising hands: medium skin tone
🙌🏾 raising hands: medium-dark skin tone
🙌🏿 raising hands: dark skin tone
🫶 heart hands
🫶🏻 heart hands: light skin tone
🫶🏼 heart hands: medium-light skin tone
🫶🏽 heart hands: medium skin tone
🫶🏾 heart hands: medium-dark skin tone
🫶🏿 heart hands: dark skin tone
👐 open hands
👐🏻 open hands: light skin tone
👐🏼 open hands: medium-light skin tone
👐🏽 open hands: medium skin tone
👐🏾 open hands: medium-dark skin tone
👐🏿 open hands: dark skin tone
🤲 palms up together
🤲🏻 palms up together: light skin tone
🤲🏼 palms up together: medium-light skin tone
🤲🏽 palms up together: medium skin tone
🤲🏾 palms up together: medium-dark skin tone
🤲🏿 palms up together: dark skin tone
🤝 handshake
🤝🏻 handshake: light skin tone
🤝🏼 handshake: medium-light skin tone
🤝🏽 handshake: medium skin tone
🤝🏾 handshake: medium-dark skin tone
🤝🏿 handshake: dark skin tone
🫱🏻‍🫲🏼 handshake: light skin tone, medium-light skin tone
🫱🏻‍🫲🏽 handshake: light skin tone, medium skin tone
🫱🏻‍🫲🏾 handshake: light skin tone, medium-dark skin tone
🫱🏻‍🫲🏿 handshake: light skin tone, dark skin tone
🫱🏼‍🫲🏻 handshake: medium-light skin tone, light skin tone
🫱🏼‍🫲🏽 handshake: medium-light skin tone, medium skin tone
🫱🏼‍🫲🏾 handshake: medium-light skin tone, medium-dark skin tone
🫱🏼‍🫲🏿 handshake: medium-light skin tone, dark skin tone
🫱🏽‍🫲🏻 handshake: medium skin tone, light skin tone
🫱🏽‍🫲🏼 handshake: medium skin tone, medium-light skin tone
🫱🏽‍🫲🏾 handshake: medium skin tone, medium-dark skin tone
🫱🏽‍🫲🏿 handshake: medium skin tone, dark skin tone
🫱🏾‍🫲🏻 handshake: medium-dark skin tone, light skin tone
🫱🏾‍🫲🏼 handshake: medium-dark skin tone, medium-light skin tone
🫱🏾‍🫲🏽 handshake: medium-dark skin tone, medium skin tone
🫱🏾‍🫲🏿 handshake: medium-dark skin tone, dark skin tone
🫱🏿‍🫲🏻 handshake: dark skin tone, light skin tone
🫱🏿‍🫲🏼 handshake: dark skin tone, medium-light skin tone
🫱🏿‍🫲🏽 handshake: dark skin tone, medium skin tone
🫱🏿‍🫲🏾 handshake: dark skin tone, medium-dark skin tone
🙏 folded hands
🙏🏻 folded hands: light skin tone
🙏🏼 folded hands: medium-light skin tone
🙏🏽 folded hands: medium skin tone
🙏🏾 folded hands: medium-dark skin tone
🙏🏿 folded hands: dark skin tone
✍️ writing hand
✍🏻 writing hand: light skin tone
✍🏼 writing hand: medium-light skin tone
✍🏽 writing hand: medium skin tone
✍🏾 writing hand: medium-dark skin tone
✍🏿 writing hand: dark skin tone
💅 nail polish
💅🏻 nail polish: light skin tone
💅🏼 nail polish: medium-light skin tone
💅🏽 nail polish: medium skin tone
💅🏾 nail polish: medium-dark skin tone
💅🏿 nail polish: dark skin tone
🤳 selfie
🤳🏻 selfie: light skin tone
🤳🏼 selfie: medium-light skin tone
🤳🏽 selfie: medium skin tone
🤳🏾 selfie: medium-dark skin tone
🤳🏿 selfie: dark skin tone
💪 flexed biceps
💪🏻 flexed biceps: light skin tone
💪🏼 flexed biceps: medium-light skin tone
💪🏽 flexed biceps: medium skin tone
💪🏾 flexed biceps: medium-dark skin tone
💪🏿 flexed biceps: dark skin tone
🦾 mechanical arm
🦿 mechanical leg
🦵 leg
🦵🏻 leg: light skin tone
🦵🏼 leg: medium-light skin tone
🦵🏽 leg: medium skin tone
🦵🏾 leg: medium-dark skin tone
🦵🏿 leg: dark skin tone
🦶 foot
🦶🏻 foot: light skin tone
🦶🏼 foot: medium-light skin tone
🦶🏽 foot: medium skin tone
🦶🏾 foot: medium-dark skin tone
🦶🏿 foot: dark skin tone
👂 ear
👂🏻 ear: light skin tone
👂🏼 ear: medium-light skin tone
👂🏽 ear: medium skin tone
👂🏾 ear: medium-dark skin tone
👂🏿 ear: dark skin tone
🦻 ear with hearing aid
🦻🏻 ear with hearing aid: light skin tone
🦻🏼 ear with hearing aid: medium-light skin tone
🦻🏽 ear with hearing aid: medium skin tone
🦻🏾 ear with hearing aid: medium-dark skin tone
🦻🏿 ear with hearing aid: dark skin tone
👃 nose
👃🏻 nose: light skin tone
👃🏼 nose: medium-light skin tone
👃🏽 nose: medium skin tone
👃🏾 nose: medium-dark skin tone
👃🏿 nose: dark skin tone
🧠 brain
🫀 anatomical heart
🫁 lungs


@@ 215,95 491,1822 @@
👄 mouth
🫦 biting lip
👶 baby
👶🏻 baby: light skin tone
👶🏼 baby: medium-light skin tone
👶🏽 baby: medium skin tone
👶🏾 baby: medium-dark skin tone
👶🏿 baby: dark skin tone
🧒 child
🧒🏻 child: light skin tone
🧒🏼 child: medium-light skin tone
🧒🏽 child: medium skin tone
🧒🏾 child: medium-dark skin tone
🧒🏿 child: dark skin tone
👦 boy
👦🏻 boy: light skin tone
👦🏼 boy: medium-light skin tone
👦🏽 boy: medium skin tone
👦🏾 boy: medium-dark skin tone
👦🏿 boy: dark skin tone
👧 girl
👧🏻 girl: light skin tone
👧🏼 girl: medium-light skin tone
👧🏽 girl: medium skin tone
👧🏾 girl: medium-dark skin tone
👧🏿 girl: dark skin tone
🧑 person
🧑🏻 person: light skin tone
🧑🏼 person: medium-light skin tone
🧑🏽 person: medium skin tone
🧑🏾 person: medium-dark skin tone
🧑🏿 person: dark skin tone
👱 person: blond hair
👱🏻 person: light skin tone, blond hair
👱🏼 person: medium-light skin tone, blond hair
👱🏽 person: medium skin tone, blond hair
👱🏾 person: medium-dark skin tone, blond hair
👱🏿 person: dark skin tone, blond hair
👨 man
👨🏻 man: light skin tone
👨🏼 man: medium-light skin tone
👨🏽 man: medium skin tone
👨🏾 man: medium-dark skin tone
👨🏿 man: dark skin tone
🧔 person: beard
🧔🏻 person: light skin tone, beard
🧔🏼 person: medium-light skin tone, beard
🧔🏽 person: medium skin tone, beard
🧔🏾 person: medium-dark skin tone, beard
🧔🏿 person: dark skin tone, beard
🧔‍♂️ man: beard
🧔🏻‍♂️ man: light skin tone, beard
🧔🏼‍♂️ man: medium-light skin tone, beard
🧔🏽‍♂️ man: medium skin tone, beard
🧔🏾‍♂️ man: medium-dark skin tone, beard
🧔🏿‍♂️ man: dark skin tone, beard
🧔‍♀️ woman: beard
🧔🏻‍♀️ woman: light skin tone, beard
🧔🏼‍♀️ woman: medium-light skin tone, beard
🧔🏽‍♀️ woman: medium skin tone, beard
🧔🏾‍♀️ woman: medium-dark skin tone, beard
🧔🏿‍♀️ woman: dark skin tone, beard
👨‍🦰 man: red hair
👨🏻‍🦰 man: light skin tone, red hair
👨🏼‍🦰 man: medium-light skin tone, red hair
👨🏽‍🦰 man: medium skin tone, red hair
👨🏾‍🦰 man: medium-dark skin tone, red hair
👨🏿‍🦰 man: dark skin tone, red hair
👨‍🦱 man: curly hair
👨🏻‍🦱 man: light skin tone, curly hair
👨🏼‍🦱 man: medium-light skin tone, curly hair
👨🏽‍🦱 man: medium skin tone, curly hair
👨🏾‍🦱 man: medium-dark skin tone, curly hair
👨🏿‍🦱 man: dark skin tone, curly hair
👨‍🦳 man: white hair
👨🏻‍🦳 man: light skin tone, white hair
👨🏼‍🦳 man: medium-light skin tone, white hair
👨🏽‍🦳 man: medium skin tone, white hair
👨🏾‍🦳 man: medium-dark skin tone, white hair
👨🏿‍🦳 man: dark skin tone, white hair
👨‍🦲 man: bald
👨🏻‍🦲 man: light skin tone, bald
👨🏼‍🦲 man: medium-light skin tone, bald
👨🏽‍🦲 man: medium skin tone, bald
👨🏾‍🦲 man: medium-dark skin tone, bald
👨🏿‍🦲 man: dark skin tone, bald
👩 woman
👩🏻 woman: light skin tone
👩🏼 woman: medium-light skin tone
👩🏽 woman: medium skin tone
👩🏾 woman: medium-dark skin tone
👩🏿 woman: dark skin tone
👩‍🦰 woman: red hair
👩🏻‍🦰 woman: light skin tone, red hair
👩🏼‍🦰 woman: medium-light skin tone, red hair
👩🏽‍🦰 woman: medium skin tone, red hair
👩🏾‍🦰 woman: medium-dark skin tone, red hair
👩🏿‍🦰 woman: dark skin tone, red hair
🧑‍🦰 person: red hair
🧑🏻‍🦰 person: light skin tone, red hair
🧑🏼‍🦰 person: medium-light skin tone, red hair
🧑🏽‍🦰 person: medium skin tone, red hair
🧑🏾‍🦰 person: medium-dark skin tone, red hair
🧑🏿‍🦰 person: dark skin tone, red hair
👩‍🦱 woman: curly hair
👩🏻‍🦱 woman: light skin tone, curly hair
👩🏼‍🦱 woman: medium-light skin tone, curly hair
👩🏽‍🦱 woman: medium skin tone, curly hair
👩🏾‍🦱 woman: medium-dark skin tone, curly hair
👩🏿‍🦱 woman: dark skin tone, curly hair
🧑‍🦱 person: curly hair
🧑🏻‍🦱 person: light skin tone, curly hair
🧑🏼‍🦱 person: medium-light skin tone, curly hair
🧑🏽‍🦱 person: medium skin tone, curly hair
🧑🏾‍🦱 person: medium-dark skin tone, curly hair
🧑🏿‍🦱 person: dark skin tone, curly hair
👩‍🦳 woman: white hair
👩🏻‍🦳 woman: light skin tone, white hair
👩🏼‍🦳 woman: medium-light skin tone, white hair
👩🏽‍🦳 woman: medium skin tone, white hair
👩🏾‍🦳 woman: medium-dark skin tone, white hair
👩🏿‍🦳 woman: dark skin tone, white hair
🧑‍🦳 person: white hair
🧑🏻‍🦳 person: light skin tone, white hair
🧑🏼‍🦳 person: medium-light skin tone, white hair
🧑🏽‍🦳 person: medium skin tone, white hair
🧑🏾‍🦳 person: medium-dark skin tone, white hair
🧑🏿‍🦳 person: dark skin tone, white hair
👩‍🦲 woman: bald
👩🏻‍🦲 woman: light skin tone, bald
👩🏼‍🦲 woman: medium-light skin tone, bald
👩🏽‍🦲 woman: medium skin tone, bald
👩🏾‍🦲 woman: medium-dark skin tone, bald
👩🏿‍🦲 woman: dark skin tone, bald
🧑‍🦲 person: bald
🧑🏻‍🦲 person: light skin tone, bald
🧑🏼‍🦲 person: medium-light skin tone, bald
🧑🏽‍🦲 person: medium skin tone, bald
🧑🏾‍🦲 person: medium-dark skin tone, bald
🧑🏿‍🦲 person: dark skin tone, bald
👱‍♀️ woman: blond hair
👱🏻‍♀️ woman: light skin tone, blond hair
👱🏼‍♀️ woman: medium-light skin tone, blond hair
👱🏽‍♀️ woman: medium skin tone, blond hair
👱🏾‍♀️ woman: medium-dark skin tone, blond hair
👱🏿‍♀️ woman: dark skin tone, blond hair
👱‍♂️ man: blond hair
👱🏻‍♂️ man: light skin tone, blond hair
👱🏼‍♂️ man: medium-light skin tone, blond hair
👱🏽‍♂️ man: medium skin tone, blond hair
👱🏾‍♂️ man: medium-dark skin tone, blond hair
👱🏿‍♂️ man: dark skin tone, blond hair
🧓 older person
🧓🏻 older person: light skin tone
🧓🏼 older person: medium-light skin tone
🧓🏽 older person: medium skin tone
🧓🏾 older person: medium-dark skin tone
🧓🏿 older person: dark skin tone
👴 old man
👴🏻 old man: light skin tone
👴🏼 old man: medium-light skin tone
👴🏽 old man: medium skin tone
👴🏾 old man: medium-dark skin tone
👴🏿 old man: dark skin tone
👵 old woman
👵🏻 old woman: light skin tone
👵🏼 old woman: medium-light skin tone
👵🏽 old woman: medium skin tone
👵🏾 old woman: medium-dark skin tone
👵🏿 old woman: dark skin tone
🙍 person frowning
🙍🏻 person frowning: light skin tone
🙍🏼 person frowning: medium-light skin tone
🙍🏽 person frowning: medium skin tone
🙍🏾 person frowning: medium-dark skin tone
🙍🏿 person frowning: dark skin tone
🙍‍♂️ man frowning
🙍🏻‍♂️ man frowning: light skin tone
🙍🏼‍♂️ man frowning: medium-light skin tone
🙍🏽‍♂️ man frowning: medium skin tone
🙍🏾‍♂️ man frowning: medium-dark skin tone
🙍🏿‍♂️ man frowning: dark skin tone
🙍‍♀️ woman frowning
🙍🏻‍♀️ woman frowning: light skin tone
🙍🏼‍♀️ woman frowning: medium-light skin tone
🙍🏽‍♀️ woman frowning: medium skin tone
🙍🏾‍♀️ woman frowning: medium-dark skin tone
🙍🏿‍♀️ woman frowning: dark skin tone
🙎 person pouting
🙎🏻 person pouting: light skin tone
🙎🏼 person pouting: medium-light skin tone
🙎🏽 person pouting: medium skin tone
🙎🏾 person pouting: medium-dark skin tone
🙎🏿 person pouting: dark skin tone
🙎‍♂️ man pouting
🙎🏻‍♂️ man pouting: light skin tone
🙎🏼‍♂️ man pouting: medium-light skin tone
🙎🏽‍♂️ man pouting: medium skin tone
🙎🏾‍♂️ man pouting: medium-dark skin tone
🙎🏿‍♂️ man pouting: dark skin tone
🙎‍♀️ woman pouting
🙎🏻‍♀️ woman pouting: light skin tone
🙎🏼‍♀️ woman pouting: medium-light skin tone
🙎🏽‍♀️ woman pouting: medium skin tone
🙎🏾‍♀️ woman pouting: medium-dark skin tone
🙎🏿‍♀️ woman pouting: dark skin tone
🙅 person gesturing NO
🙅🏻 person gesturing NO: light skin tone
🙅🏼 person gesturing NO: medium-light skin tone
🙅🏽 person gesturing NO: medium skin tone
🙅🏾 person gesturing NO: medium-dark skin tone
🙅🏿 person gesturing NO: dark skin tone
🙅‍♂️ man gesturing NO
🙅🏻‍♂️ man gesturing NO: light skin tone
🙅🏼‍♂️ man gesturing NO: medium-light skin tone
🙅🏽‍♂️ man gesturing NO: medium skin tone
🙅🏾‍♂️ man gesturing NO: medium-dark skin tone
🙅🏿‍♂️ man gesturing NO: dark skin tone
🙅‍♀️ woman gesturing NO
🙅🏻‍♀️ woman gesturing NO: light skin tone
🙅🏼‍♀️ woman gesturing NO: medium-light skin tone
🙅🏽‍♀️ woman gesturing NO: medium skin tone
🙅🏾‍♀️ woman gesturing NO: medium-dark skin tone
🙅🏿‍♀️ woman gesturing NO: dark skin tone
🙆 person gesturing OK
🙆🏻 person gesturing OK: light skin tone
🙆🏼 person gesturing OK: medium-light skin tone
🙆🏽 person gesturing OK: medium skin tone
🙆🏾 person gesturing OK: medium-dark skin tone
🙆🏿 person gesturing OK: dark skin tone
🙆‍♂️ man gesturing OK
🙆🏻‍♂️ man gesturing OK: light skin tone
🙆🏼‍♂️ man gesturing OK: medium-light skin tone
🙆🏽‍♂️ man gesturing OK: medium skin tone
🙆🏾‍♂️ man gesturing OK: medium-dark skin tone
🙆🏿‍♂️ man gesturing OK: dark skin tone
🙆‍♀️ woman gesturing OK
🙆🏻‍♀️ woman gesturing OK: light skin tone
🙆🏼‍♀️ woman gesturing OK: medium-light skin tone
🙆🏽‍♀️ woman gesturing OK: medium skin tone
🙆🏾‍♀️ woman gesturing OK: medium-dark skin tone
🙆🏿‍♀️ woman gesturing OK: dark skin tone
💁 person tipping hand
💁🏻 person tipping hand: light skin tone
💁🏼 person tipping hand: medium-light skin tone
💁🏽 person tipping hand: medium skin tone
💁🏾 person tipping hand: medium-dark skin tone
💁🏿 person tipping hand: dark skin tone
💁‍♂️ man tipping hand
💁🏻‍♂️ man tipping hand: light skin tone
💁🏼‍♂️ man tipping hand: medium-light skin tone
💁🏽‍♂️ man tipping hand: medium skin tone
💁🏾‍♂️ man tipping hand: medium-dark skin tone
💁🏿‍♂️ man tipping hand: dark skin tone
💁‍♀️ woman tipping hand
💁🏻‍♀️ woman tipping hand: light skin tone
💁🏼‍♀️ woman tipping hand: medium-light skin tone
💁🏽‍♀️ woman tipping hand: medium skin tone
💁🏾‍♀️ woman tipping hand: medium-dark skin tone
💁🏿‍♀️ woman tipping hand: dark skin tone
🙋 person raising hand
🙋🏻 person raising hand: light skin tone
🙋🏼 person raising hand: medium-light skin tone
🙋🏽 person raising hand: medium skin tone
🙋🏾 person raising hand: medium-dark skin tone
🙋🏿 person raising hand: dark skin tone
🙋‍♂️ man raising hand
🙋🏻‍♂️ man raising hand: light skin tone
🙋🏼‍♂️ man raising hand: medium-light skin tone
🙋🏽‍♂️ man raising hand: medium skin tone
🙋🏾‍♂️ man raising hand: medium-dark skin tone
🙋🏿‍♂️ man raising hand: dark skin tone
🙋‍♀️ woman raising hand
🙋🏻‍♀️ woman raising hand: light skin tone
🙋🏼‍♀️ woman raising hand: medium-light skin tone
🙋🏽‍♀️ woman raising hand: medium skin tone
🙋🏾‍♀️ woman raising hand: medium-dark skin tone
🙋🏿‍♀️ woman raising hand: dark skin tone
🧏 deaf person
🧏🏻 deaf person: light skin tone
🧏🏼 deaf person: medium-light skin tone
🧏🏽 deaf person: medium skin tone
🧏🏾 deaf person: medium-dark skin tone
🧏🏿 deaf person: dark skin tone
🧏‍♂️ deaf man
🧏🏻‍♂️ deaf man: light skin tone
🧏🏼‍♂️ deaf man: medium-light skin tone
🧏🏽‍♂️ deaf man: medium skin tone
🧏🏾‍♂️ deaf man: medium-dark skin tone
🧏🏿‍♂️ deaf man: dark skin tone
🧏‍♀️ deaf woman
🧏🏻‍♀️ deaf woman: light skin tone
🧏🏼‍♀️ deaf woman: medium-light skin tone
🧏🏽‍♀️ deaf woman: medium skin tone
🧏🏾‍♀️ deaf woman: medium-dark skin tone
🧏🏿‍♀️ deaf woman: dark skin tone
🙇 person bowing
🙇🏻 person bowing: light skin tone
🙇🏼 person bowing: medium-light skin tone
🙇🏽 person bowing: medium skin tone
🙇🏾 person bowing: medium-dark skin tone
🙇🏿 person bowing: dark skin tone
🙇‍♂️ man bowing
🙇🏻‍♂️ man bowing: light skin tone
🙇🏼‍♂️ man bowing: medium-light skin tone
🙇🏽‍♂️ man bowing: medium skin tone
🙇🏾‍♂️ man bowing: medium-dark skin tone
🙇🏿‍♂️ man bowing: dark skin tone
🙇‍♀️ woman bowing
🙇🏻‍♀️ woman bowing: light skin tone
🙇🏼‍♀️ woman bowing: medium-light skin tone
🙇🏽‍♀️ woman bowing: medium skin tone
🙇🏾‍♀️ woman bowing: medium-dark skin tone
🙇🏿‍♀️ woman bowing: dark skin tone
🤦 person facepalming
🤦🏻 person facepalming: light skin tone
🤦🏼 person facepalming: medium-light skin tone
🤦🏽 person facepalming: medium skin tone
🤦🏾 person facepalming: medium-dark skin tone
🤦🏿 person facepalming: dark skin tone
🤦‍♂️ man facepalming
🤦🏻‍♂️ man facepalming: light skin tone
🤦🏼‍♂️ man facepalming: medium-light skin tone
🤦🏽‍♂️ man facepalming: medium skin tone
🤦🏾‍♂️ man facepalming: medium-dark skin tone
🤦🏿‍♂️ man facepalming: dark skin tone
🤦‍♀️ woman facepalming
🤦🏻‍♀️ woman facepalming: light skin tone
🤦🏼‍♀️ woman facepalming: medium-light skin tone
🤦🏽‍♀️ woman facepalming: medium skin tone
🤦🏾‍♀️ woman facepalming: medium-dark skin tone
🤦🏿‍♀️ woman facepalming: dark skin tone
🤷 person shrugging
🤷🏻 person shrugging: light skin tone
🤷🏼 person shrugging: medium-light skin tone
🤷🏽 person shrugging: medium skin tone
🤷🏾 person shrugging: medium-dark skin tone
🤷🏿 person shrugging: dark skin tone
🤷‍♂️ man shrugging
🤷🏻‍♂️ man shrugging: light skin tone
🤷🏼‍♂️ man shrugging: medium-light skin tone
🤷🏽‍♂️ man shrugging: medium skin tone
🤷🏾‍♂️ man shrugging: medium-dark skin tone
🤷🏿‍♂️ man shrugging: dark skin tone
🤷‍♀️ woman shrugging
🤷🏻‍♀️ woman shrugging: light skin tone
🤷🏼‍♀️ woman shrugging: medium-light skin tone
🤷🏽‍♀️ woman shrugging: medium skin tone
🤷🏾‍♀️ woman shrugging: medium-dark skin tone
🤷🏿‍♀️ woman shrugging: dark skin tone
🧑‍⚕️ health worker
🧑🏻‍⚕️ health worker: light skin tone
🧑🏼‍⚕️ health worker: medium-light skin tone
🧑🏽‍⚕️ health worker: medium skin tone
🧑🏾‍⚕️ health worker: medium-dark skin tone
🧑🏿‍⚕️ health worker: dark skin tone
👨‍⚕️ man health worker
👨🏻‍⚕️ man health worker: light skin tone
👨🏼‍⚕️ man health worker: medium-light skin tone
👨🏽‍⚕️ man health worker: medium skin tone
👨🏾‍⚕️ man health worker: medium-dark skin tone
👨🏿‍⚕️ man health worker: dark skin tone
👩‍⚕️ woman health worker
👩🏻‍⚕️ woman health worker: light skin tone
👩🏼‍⚕️ woman health worker: medium-light skin tone
👩🏽‍⚕️ woman health worker: medium skin tone
👩🏾‍⚕️ woman health worker: medium-dark skin tone
👩🏿‍⚕️ woman health worker: dark skin tone
🧑‍🎓 student
🧑🏻‍🎓 student: light skin tone
🧑🏼‍🎓 student: medium-light skin tone
🧑🏽‍🎓 student: medium skin tone
🧑🏾‍🎓 student: medium-dark skin tone
🧑🏿‍🎓 student: dark skin tone
👨‍🎓 man student
👨🏻‍🎓 man student: light skin tone
👨🏼‍🎓 man student: medium-light skin tone
👨🏽‍🎓 man student: medium skin tone
👨🏾‍🎓 man student: medium-dark skin tone
👨🏿‍🎓 man student: dark skin tone
👩‍🎓 woman student
👩🏻‍🎓 woman student: light skin tone
👩🏼‍🎓 woman student: medium-light skin tone
👩🏽‍🎓 woman student: medium skin tone
👩🏾‍🎓 woman student: medium-dark skin tone
👩🏿‍🎓 woman student: dark skin tone
🧑‍🏫 teacher
🧑🏻‍🏫 teacher: light skin tone
🧑🏼‍🏫 teacher: medium-light skin tone
🧑🏽‍🏫 teacher: medium skin tone
🧑🏾‍🏫 teacher: medium-dark skin tone
🧑🏿‍🏫 teacher: dark skin tone
👨‍🏫 man teacher
👨🏻‍🏫 man teacher: light skin tone
👨🏼‍🏫 man teacher: medium-light skin tone
👨🏽‍🏫 man teacher: medium skin tone
👨🏾‍🏫 man teacher: medium-dark skin tone
👨🏿‍🏫 man teacher: dark skin tone
👩‍🏫 woman teacher
👩🏻‍🏫 woman teacher: light skin tone
👩🏼‍🏫 woman teacher: medium-light skin tone
👩🏽‍🏫 woman teacher: medium skin tone
👩🏾‍🏫 woman teacher: medium-dark skin tone
👩🏿‍🏫 woman teacher: dark skin tone
🧑‍⚖️ judge
🧑🏻‍⚖️ judge: light skin tone
🧑🏼‍⚖️ judge: medium-light skin tone
🧑🏽‍⚖️ judge: medium skin tone
🧑🏾‍⚖️ judge: medium-dark skin tone
🧑🏿‍⚖️ judge: dark skin tone
👨‍⚖️ man judge
👨🏻‍⚖️ man judge: light skin tone
👨🏼‍⚖️ man judge: medium-light skin tone
👨🏽‍⚖️ man judge: medium skin tone
👨🏾‍⚖️ man judge: medium-dark skin tone
👨🏿‍⚖️ man judge: dark skin tone
👩‍⚖️ woman judge
👩🏻‍⚖️ woman judge: light skin tone
👩🏼‍⚖️ woman judge: medium-light skin tone
👩🏽‍⚖️ woman judge: medium skin tone
👩🏾‍⚖️ woman judge: medium-dark skin tone
👩🏿‍⚖️ woman judge: dark skin tone
🧑‍🌾 farmer
🧑🏻‍🌾 farmer: light skin tone
🧑🏼‍🌾 farmer: medium-light skin tone
🧑🏽‍🌾 farmer: medium skin tone
🧑🏾‍🌾 farmer: medium-dark skin tone
🧑🏿‍🌾 farmer: dark skin tone
👨‍🌾 man farmer
👨🏻‍🌾 man farmer: light skin tone
👨🏼‍🌾 man farmer: medium-light skin tone
👨🏽‍🌾 man farmer: medium skin tone
👨🏾‍🌾 man farmer: medium-dark skin tone
👨🏿‍🌾 man farmer: dark skin tone
👩‍🌾 woman farmer
👩🏻‍🌾 woman farmer: light skin tone
👩🏼‍🌾 woman farmer: medium-light skin tone
👩🏽‍🌾 woman farmer: medium skin tone
👩🏾‍🌾 woman farmer: medium-dark skin tone
👩🏿‍🌾 woman farmer: dark skin tone
🧑‍🍳 cook
🧑🏻‍🍳 cook: light skin tone
🧑🏼‍🍳 cook: medium-light skin tone
🧑🏽‍🍳 cook: medium skin tone
🧑🏾‍🍳 cook: medium-dark skin tone
🧑🏿‍🍳 cook: dark skin tone
👨‍🍳 man cook
👨🏻‍🍳 man cook: light skin tone
👨🏼‍🍳 man cook: medium-light skin tone
👨🏽‍🍳 man cook: medium skin tone
👨🏾‍🍳 man cook: medium-dark skin tone
👨🏿‍🍳 man cook: dark skin tone
👩‍🍳 woman cook
👩🏻‍🍳 woman cook: light skin tone
👩🏼‍🍳 woman cook: medium-light skin tone
👩🏽‍🍳 woman cook: medium skin tone
👩🏾‍🍳 woman cook: medium-dark skin tone
👩🏿‍🍳 woman cook: dark skin tone
🧑‍🔧 mechanic
🧑🏻‍🔧 mechanic: light skin tone
🧑🏼‍🔧 mechanic: medium-light skin tone
🧑🏽‍🔧 mechanic: medium skin tone
🧑🏾‍🔧 mechanic: medium-dark skin tone
🧑🏿‍🔧 mechanic: dark skin tone
👨‍🔧 man mechanic
👨🏻‍🔧 man mechanic: light skin tone
👨🏼‍🔧 man mechanic: medium-light skin tone
👨🏽‍🔧 man mechanic: medium skin tone
👨🏾‍🔧 man mechanic: medium-dark skin tone
👨🏿‍🔧 man mechanic: dark skin tone
👩‍🔧 woman mechanic
👩🏻‍🔧 woman mechanic: light skin tone
👩🏼‍🔧 woman mechanic: medium-light skin tone
👩🏽‍🔧 woman mechanic: medium skin tone
👩🏾‍🔧 woman mechanic: medium-dark skin tone
👩🏿‍🔧 woman mechanic: dark skin tone
🧑‍🏭 factory worker
🧑🏻‍🏭 factory worker: light skin tone
🧑🏼‍🏭 factory worker: medium-light skin tone
🧑🏽‍🏭 factory worker: medium skin tone
🧑🏾‍🏭 factory worker: medium-dark skin tone
🧑🏿‍🏭 factory worker: dark skin tone
👨‍🏭 man factory worker
👨🏻‍🏭 man factory worker: light skin tone
👨🏼‍🏭 man factory worker: medium-light skin tone
👨🏽‍🏭 man factory worker: medium skin tone
👨🏾‍🏭 man factory worker: medium-dark skin tone
👨🏿‍🏭 man factory worker: dark skin tone
👩‍🏭 woman factory worker
👩🏻‍🏭 woman factory worker: light skin tone
👩🏼‍🏭 woman factory worker: medium-light skin tone
👩🏽‍🏭 woman factory worker: medium skin tone
👩🏾‍🏭 woman factory worker: medium-dark skin tone
👩🏿‍🏭 woman factory worker: dark skin tone
🧑‍💼 office worker
🧑🏻‍💼 office worker: light skin tone
🧑🏼‍💼 office worker: medium-light skin tone
🧑🏽‍💼 office worker: medium skin tone
🧑🏾‍💼 office worker: medium-dark skin tone
🧑🏿‍💼 office worker: dark skin tone
👨‍💼 man office worker
👨🏻‍💼 man office worker: light skin tone
👨🏼‍💼 man office worker: medium-light skin tone
👨🏽‍💼 man office worker: medium skin tone
👨🏾‍💼 man office worker: medium-dark skin tone
👨🏿‍💼 man office worker: dark skin tone
👩‍💼 woman office worker
👩🏻‍💼 woman office worker: light skin tone
👩🏼‍💼 woman office worker: medium-light skin tone
👩🏽‍💼 woman office worker: medium skin tone
👩🏾‍💼 woman office worker: medium-dark skin tone
👩🏿‍💼 woman office worker: dark skin tone
🧑‍🔬 scientist
🧑🏻‍🔬 scientist: light skin tone
🧑🏼‍🔬 scientist: medium-light skin tone
🧑🏽‍🔬 scientist: medium skin tone
🧑🏾‍🔬 scientist: medium-dark skin tone
🧑🏿‍🔬 scientist: dark skin tone
👨‍🔬 man scientist
👨🏻‍🔬 man scientist: light skin tone
👨🏼‍🔬 man scientist: medium-light skin tone
👨🏽‍🔬 man scientist: medium skin tone
👨🏾‍🔬 man scientist: medium-dark skin tone
👨🏿‍🔬 man scientist: dark skin tone
👩‍🔬 woman scientist
👩🏻‍🔬 woman scientist: light skin tone
👩🏼‍🔬 woman scientist: medium-light skin tone
👩🏽‍🔬 woman scientist: medium skin tone
👩🏾‍🔬 woman scientist: medium-dark skin tone
👩🏿‍🔬 woman scientist: dark skin tone
🧑‍💻 technologist
🧑🏻‍💻 technologist: light skin tone
🧑🏼‍💻 technologist: medium-light skin tone
🧑🏽‍💻 technologist: medium skin tone
🧑🏾‍💻 technologist: medium-dark skin tone
🧑🏿‍💻 technologist: dark skin tone
👨‍💻 man technologist
👨🏻‍💻 man technologist: light skin tone
👨🏼‍💻 man technologist: medium-light skin tone
👨🏽‍💻 man technologist: medium skin tone
👨🏾‍💻 man technologist: medium-dark skin tone
👨🏿‍💻 man technologist: dark skin tone
👩‍💻 woman technologist
👩🏻‍💻 woman technologist: light skin tone
👩🏼‍💻 woman technologist: medium-light skin tone
👩🏽‍💻 woman technologist: medium skin tone
👩🏾‍💻 woman technologist: medium-dark skin tone
👩🏿‍💻 woman technologist: dark skin tone
🧑‍🎤 singer
🧑🏻‍🎤 singer: light skin tone
🧑🏼‍🎤 singer: medium-light skin tone
🧑🏽‍🎤 singer: medium skin tone
🧑🏾‍🎤 singer: medium-dark skin tone
🧑🏿‍🎤 singer: dark skin tone
👨‍🎤 man singer
👨🏻‍🎤 man singer: light skin tone
👨🏼‍🎤 man singer: medium-light skin tone
👨🏽‍🎤 man singer: medium skin tone
👨🏾‍🎤 man singer: medium-dark skin tone
👨🏿‍🎤 man singer: dark skin tone
👩‍🎤 woman singer
👩🏻‍🎤 woman singer: light skin tone
👩🏼‍🎤 woman singer: medium-light skin tone
👩🏽‍🎤 woman singer: medium skin tone
👩🏾‍🎤 woman singer: medium-dark skin tone
👩🏿‍🎤 woman singer: dark skin tone
🧑‍🎨 artist
🧑🏻‍🎨 artist: light skin tone
🧑🏼‍🎨 artist: medium-light skin tone
🧑🏽‍🎨 artist: medium skin tone
🧑🏾‍🎨 artist: medium-dark skin tone
🧑🏿‍🎨 artist: dark skin tone
👨‍🎨 man artist
👨🏻‍🎨 man artist: light skin tone
👨🏼‍🎨 man artist: medium-light skin tone
👨🏽‍🎨 man artist: medium skin tone
👨🏾‍🎨 man artist: medium-dark skin tone
👨🏿‍🎨 man artist: dark skin tone
👩‍🎨 woman artist
👩🏻‍🎨 woman artist: light skin tone
👩🏼‍🎨 woman artist: medium-light skin tone
👩🏽‍🎨 woman artist: medium skin tone
👩🏾‍🎨 woman artist: medium-dark skin tone
👩🏿‍🎨 woman artist: dark skin tone
🧑‍✈️ pilot
🧑🏻‍✈️ pilot: light skin tone
🧑🏼‍✈️ pilot: medium-light skin tone
🧑🏽‍✈️ pilot: medium skin tone
🧑🏾‍✈️ pilot: medium-dark skin tone
🧑🏿‍✈️ pilot: dark skin tone
👨‍✈️ man pilot
👨🏻‍✈️ man pilot: light skin tone
👨🏼‍✈️ man pilot: medium-light skin tone
👨🏽‍✈️ man pilot: medium skin tone
👨🏾‍✈️ man pilot: medium-dark skin tone
👨🏿‍✈️ man pilot: dark skin tone
👩‍✈️ woman pilot
👩🏻‍✈️ woman pilot: light skin tone
👩🏼‍✈️ woman pilot: medium-light skin tone
👩🏽‍✈️ woman pilot: medium skin tone
👩🏾‍✈️ woman pilot: medium-dark skin tone
👩🏿‍✈️ woman pilot: dark skin tone
🧑‍🚀 astronaut
🧑🏻‍🚀 astronaut: light skin tone
🧑🏼‍🚀 astronaut: medium-light skin tone
🧑🏽‍🚀 astronaut: medium skin tone
🧑🏾‍🚀 astronaut: medium-dark skin tone
🧑🏿‍🚀 astronaut: dark skin tone
👨‍🚀 man astronaut
👨🏻‍🚀 man astronaut: light skin tone
👨🏼‍🚀 man astronaut: medium-light skin tone
👨🏽‍🚀 man astronaut: medium skin tone
👨🏾‍🚀 man astronaut: medium-dark skin tone
👨🏿‍🚀 man astronaut: dark skin tone
👩‍🚀 woman astronaut
👩🏻‍🚀 woman astronaut: light skin tone
👩🏼‍🚀 woman astronaut: medium-light skin tone
👩🏽‍🚀 woman astronaut: medium skin tone
👩🏾‍🚀 woman astronaut: medium-dark skin tone
👩🏿‍🚀 woman astronaut: dark skin tone
🧑‍🚒 firefighter
🧑🏻‍🚒 firefighter: light skin tone
🧑🏼‍🚒 firefighter: medium-light skin tone
🧑🏽‍🚒 firefighter: medium skin tone
🧑🏾‍🚒 firefighter: medium-dark skin tone
🧑🏿‍🚒 firefighter: dark skin tone
👨‍🚒 man firefighter
👨🏻‍🚒 man firefighter: light skin tone
👨🏼‍🚒 man firefighter: medium-light skin tone
👨🏽‍🚒 man firefighter: medium skin tone
👨🏾‍🚒 man firefighter: medium-dark skin tone
👨🏿‍🚒 man firefighter: dark skin tone
👩‍🚒 woman firefighter
👩🏻‍🚒 woman firefighter: light skin tone
👩🏼‍🚒 woman firefighter: medium-light skin tone
👩🏽‍🚒 woman firefighter: medium skin tone
👩🏾‍🚒 woman firefighter: medium-dark skin tone
👩🏿‍🚒 woman firefighter: dark skin tone
👮 police officer
👮🏻 police officer: light skin tone
👮🏼 police officer: medium-light skin tone
👮🏽 police officer: medium skin tone
👮🏾 police officer: medium-dark skin tone
👮🏿 police officer: dark skin tone
👮‍♂️ man police officer
👮🏻‍♂️ man police officer: light skin tone
👮🏼‍♂️ man police officer: medium-light skin tone
👮🏽‍♂️ man police officer: medium skin tone
👮🏾‍♂️ man police officer: medium-dark skin tone
👮🏿‍♂️ man police officer: dark skin tone
👮‍♀️ woman police officer
👮🏻‍♀️ woman police officer: light skin tone
👮🏼‍♀️ woman police officer: medium-light skin tone
👮🏽‍♀️ woman police officer: medium skin tone
👮🏾‍♀️ woman police officer: medium-dark skin tone
👮🏿‍♀️ woman police officer: dark skin tone
🕵️ detective
🕵🏻 detective: light skin tone
🕵🏼 detective: medium-light skin tone
🕵🏽 detective: medium skin tone
🕵🏾 detective: medium-dark skin tone
🕵🏿 detective: dark skin tone
🕵️‍♂️ man detective
🕵🏻‍♂️ man detective: light skin tone
🕵🏼‍♂️ man detective: medium-light skin tone
🕵🏽‍♂️ man detective: medium skin tone
🕵🏾‍♂️ man detective: medium-dark skin tone
🕵🏿‍♂️ man detective: dark skin tone
🕵️‍♀️ woman detective
🕵🏻‍♀️ woman detective: light skin tone
🕵🏼‍♀️ woman detective: medium-light skin tone
🕵🏽‍♀️ woman detective: medium skin tone
🕵🏾‍♀️ woman detective: medium-dark skin tone
🕵🏿‍♀️ woman detective: dark skin tone
💂 guard
💂🏻 guard: light skin tone
💂🏼 guard: medium-light skin tone
💂🏽 guard: medium skin tone
💂🏾 guard: medium-dark skin tone
💂🏿 guard: dark skin tone
💂‍♂️ man guard
💂🏻‍♂️ man guard: light skin tone
💂🏼‍♂️ man guard: medium-light skin tone
💂🏽‍♂️ man guard: medium skin tone
💂🏾‍♂️ man guard: medium-dark skin tone
💂🏿‍♂️ man guard: dark skin tone
💂‍♀️ woman guard
💂🏻‍♀️ woman guard: light skin tone
💂🏼‍♀️ woman guard: medium-light skin tone
💂🏽‍♀️ woman guard: medium skin tone
💂🏾‍♀️ woman guard: medium-dark skin tone
💂🏿‍♀️ woman guard: dark skin tone
🥷 ninja
🥷🏻 ninja: light skin tone
🥷🏼 ninja: medium-light skin tone
🥷🏽 ninja: medium skin tone
🥷🏾 ninja: medium-dark skin tone
🥷🏿 ninja: dark skin tone
👷 construction worker
👷🏻 construction worker: light skin tone
👷🏼 construction worker: medium-light skin tone
👷🏽 construction worker: medium skin tone
👷🏾 construction worker: medium-dark skin tone
👷🏿 construction worker: dark skin tone
👷‍♂️ man construction worker
👷🏻‍♂️ man construction worker: light skin tone
👷🏼‍♂️ man construction worker: medium-light skin tone
👷🏽‍♂️ man construction worker: medium skin tone
👷🏾‍♂️ man construction worker: medium-dark skin tone
👷🏿‍♂️ man construction worker: dark skin tone
👷‍♀️ woman construction worker
👷🏻‍♀️ woman construction worker: light skin tone
👷🏼‍♀️ woman construction worker: medium-light skin tone
👷🏽‍♀️ woman construction worker: medium skin tone
👷🏾‍♀️ woman construction worker: medium-dark skin tone
👷🏿‍♀️ woman construction worker: dark skin tone
🫅 person with crown
🫅🏻 person with crown: light skin tone
🫅🏼 person with crown: medium-light skin tone
🫅🏽 person with crown: medium skin tone
🫅🏾 person with crown: medium-dark skin tone
🫅🏿 person with crown: dark skin tone
🤴 prince
🤴🏻 prince: light skin tone
🤴🏼 prince: medium-light skin tone
🤴🏽 prince: medium skin tone
🤴🏾 prince: medium-dark skin tone
🤴🏿 prince: dark skin tone
👸 princess
👸🏻 princess: light skin tone
👸🏼 princess: medium-light skin tone
👸🏽 princess: medium skin tone
👸🏾 princess: medium-dark skin tone
👸🏿 princess: dark skin tone
👳 person wearing turban
👳🏻 person wearing turban: light skin tone
👳🏼 person wearing turban: medium-light skin tone
👳🏽 person wearing turban: medium skin tone
👳🏾 person wearing turban: medium-dark skin tone
👳🏿 person wearing turban: dark skin tone
👳‍♂️ man wearing turban
👳🏻‍♂️ man wearing turban: light skin tone
👳🏼‍♂️ man wearing turban: medium-light skin tone
👳🏽‍♂️ man wearing turban: medium skin tone
👳🏾‍♂️ man wearing turban: medium-dark skin tone
👳🏿‍♂️ man wearing turban: dark skin tone
👳‍♀️ woman wearing turban
👳🏻‍♀️ woman wearing turban: light skin tone
👳🏼‍♀️ woman wearing turban: medium-light skin tone
👳🏽‍♀️ woman wearing turban: medium skin tone
👳🏾‍♀️ woman wearing turban: medium-dark skin tone
👳🏿‍♀️ woman wearing turban: dark skin tone
👲 person with skullcap
👲🏻 person with skullcap: light skin tone
👲🏼 person with skullcap: medium-light skin tone
👲🏽 person with skullcap: medium skin tone
👲🏾 person with skullcap: medium-dark skin tone
👲🏿 person with skullcap: dark skin tone
🧕 woman with headscarf
🧕🏻 woman with headscarf: light skin tone
🧕🏼 woman with headscarf: medium-light skin tone
🧕🏽 woman with headscarf: medium skin tone
🧕🏾 woman with headscarf: medium-dark skin tone
🧕🏿 woman with headscarf: dark skin tone
🤵 person in tuxedo
🤵🏻 person in tuxedo: light skin tone
🤵🏼 person in tuxedo: medium-light skin tone
🤵🏽 person in tuxedo: medium skin tone
🤵🏾 person in tuxedo: medium-dark skin tone
🤵🏿 person in tuxedo: dark skin tone
🤵‍♂️ man in tuxedo
🤵🏻‍♂️ man in tuxedo: light skin tone
🤵🏼‍♂️ man in tuxedo: medium-light skin tone
🤵🏽‍♂️ man in tuxedo: medium skin tone
🤵🏾‍♂️ man in tuxedo: medium-dark skin tone
🤵🏿‍♂️ man in tuxedo: dark skin tone
🤵‍♀️ woman in tuxedo
🤵🏻‍♀️ woman in tuxedo: light skin tone
🤵🏼‍♀️ woman in tuxedo: medium-light skin tone
🤵🏽‍♀️ woman in tuxedo: medium skin tone
🤵🏾‍♀️ woman in tuxedo: medium-dark skin tone
🤵🏿‍♀️ woman in tuxedo: dark skin tone
👰 person with veil
👰🏻 person with veil: light skin tone
👰🏼 person with veil: medium-light skin tone
👰🏽 person with veil: medium skin tone
👰🏾 person with veil: medium-dark skin tone
👰🏿 person with veil: dark skin tone
👰‍♂️ man with veil
👰🏻‍♂️ man with veil: light skin tone
👰🏼‍♂️ man with veil: medium-light skin tone
👰🏽‍♂️ man with veil: medium skin tone
👰🏾‍♂️ man with veil: medium-dark skin tone
👰🏿‍♂️ man with veil: dark skin tone
👰‍♀️ woman with veil
👰🏻‍♀️ woman with veil: light skin tone
👰🏼‍♀️ woman with veil: medium-light skin tone
👰🏽‍♀️ woman with veil: medium skin tone
👰🏾‍♀️ woman with veil: medium-dark skin tone
👰🏿‍♀️ woman with veil: dark skin tone
🤰 pregnant woman
🤰🏻 pregnant woman: light skin tone
🤰🏼 pregnant woman: medium-light skin tone
🤰🏽 pregnant woman: medium skin tone
🤰🏾 pregnant woman: medium-dark skin tone
🤰🏿 pregnant woman: dark skin tone
🫃 pregnant man
🫃🏻 pregnant man: light skin tone
🫃🏼 pregnant man: medium-light skin tone
🫃🏽 pregnant man: medium skin tone
🫃🏾 pregnant man: medium-dark skin tone
🫃🏿 pregnant man: dark skin tone
🫄 pregnant person
🫄🏻 pregnant person: light skin tone
🫄🏼 pregnant person: medium-light skin tone
🫄🏽 pregnant person: medium skin tone
🫄🏾 pregnant person: medium-dark skin tone
🫄🏿 pregnant person: dark skin tone
🤱 breast-feeding
🤱🏻 breast-feeding: light skin tone
🤱🏼 breast-feeding: medium-light skin tone
🤱🏽 breast-feeding: medium skin tone
🤱🏾 breast-feeding: medium-dark skin tone
🤱🏿 breast-feeding: dark skin tone
👩‍🍼 woman feeding baby
👩🏻‍🍼 woman feeding baby: light skin tone
👩🏼‍🍼 woman feeding baby: medium-light skin tone
👩🏽‍🍼 woman feeding baby: medium skin tone
👩🏾‍🍼 woman feeding baby: medium-dark skin tone
👩🏿‍🍼 woman feeding baby: dark skin tone
👨‍🍼 man feeding baby
👨🏻‍🍼 man feeding baby: light skin tone
👨🏼‍🍼 man feeding baby: medium-light skin tone
👨🏽‍🍼 man feeding baby: medium skin tone
👨🏾‍🍼 man feeding baby: medium-dark skin tone
👨🏿‍🍼 man feeding baby: dark skin tone
🧑‍🍼 person feeding baby
🧑🏻‍🍼 person feeding baby: light skin tone
🧑🏼‍🍼 person feeding baby: medium-light skin tone
🧑🏽‍🍼 person feeding baby: medium skin tone
🧑🏾‍🍼 person feeding baby: medium-dark skin tone
🧑🏿‍🍼 person feeding baby: dark skin tone
👼 baby angel
👼🏻 baby angel: light skin tone
👼🏼 baby angel: medium-light skin tone
👼🏽 baby angel: medium skin tone
👼🏾 baby angel: medium-dark skin tone
👼🏿 baby angel: dark skin tone
🎅 Santa Claus
🎅🏻 Santa Claus: light skin tone
🎅🏼 Santa Claus: medium-light skin tone
🎅🏽 Santa Claus: medium skin tone
🎅🏾 Santa Claus: medium-dark skin tone
🎅🏿 Santa Claus: dark skin tone
🤶 Mrs. Claus
🤶🏻 Mrs. Claus: light skin tone
🤶🏼 Mrs. Claus: medium-light skin tone
🤶🏽 Mrs. Claus: medium skin tone
🤶🏾 Mrs. Claus: medium-dark skin tone
🤶🏿 Mrs. Claus: dark skin tone
🧑‍🎄 mx claus
🧑🏻‍🎄 mx claus: light skin tone
🧑🏼‍🎄 mx claus: medium-light skin tone
🧑🏽‍🎄 mx claus: medium skin tone
🧑🏾‍🎄 mx claus: medium-dark skin tone
🧑🏿‍🎄 mx claus: dark skin tone
🦸 superhero
🦸🏻 superhero: light skin tone
🦸🏼 superhero: medium-light skin tone
🦸🏽 superhero: medium skin tone
🦸🏾 superhero: medium-dark skin tone
🦸🏿 superhero: dark skin tone
🦸‍♂️ man superhero
🦸🏻‍♂️ man superhero: light skin tone
🦸🏼‍♂️ man superhero: medium-light skin tone
🦸🏽‍♂️ man superhero: medium skin tone
🦸🏾‍♂️ man superhero: medium-dark skin tone
🦸🏿‍♂️ man superhero: dark skin tone
🦸‍♀️ woman superhero
🦸🏻‍♀️ woman superhero: light skin tone
🦸🏼‍♀️ woman superhero: medium-light skin tone
🦸🏽‍♀️ woman superhero: medium skin tone
🦸🏾‍♀️ woman superhero: medium-dark skin tone
🦸🏿‍♀️ woman superhero: dark skin tone
🦹 supervillain
🦹🏻 supervillain: light skin tone
🦹🏼 supervillain: medium-light skin tone
🦹🏽 supervillain: medium skin tone
🦹🏾 supervillain: medium-dark skin tone
🦹🏿 supervillain: dark skin tone
🦹‍♂️ man supervillain
🦹🏻‍♂️ man supervillain: light skin tone
🦹🏼‍♂️ man supervillain: medium-light skin tone
🦹🏽‍♂️ man supervillain: medium skin tone
🦹🏾‍♂️ man supervillain: medium-dark skin tone
🦹🏿‍♂️ man supervillain: dark skin tone
🦹‍♀️ woman supervillain
🦹🏻‍♀️ woman supervillain: light skin tone
🦹🏼‍♀️ woman supervillain: medium-light skin tone
🦹🏽‍♀️ woman supervillain: medium skin tone
🦹🏾‍♀️ woman supervillain: medium-dark skin tone
🦹🏿‍♀️ woman supervillain: dark skin tone
🧙 mage
🧙🏻 mage: light skin tone
🧙🏼 mage: medium-light skin tone
🧙🏽 mage: medium skin tone
🧙🏾 mage: medium-dark skin tone
🧙🏿 mage: dark skin tone
🧙‍♂️ man mage
🧙🏻‍♂️ man mage: light skin tone
🧙🏼‍♂️ man mage: medium-light skin tone
🧙🏽‍♂️ man mage: medium skin tone
🧙🏾‍♂️ man mage: medium-dark skin tone
🧙🏿‍♂️ man mage: dark skin tone
🧙‍♀️ woman mage
🧙🏻‍♀️ woman mage: light skin tone
🧙🏼‍♀️ woman mage: medium-light skin tone
🧙🏽‍♀️ woman mage: medium skin tone
🧙🏾‍♀️ woman mage: medium-dark skin tone
🧙🏿‍♀️ woman mage: dark skin tone
🧚 fairy
🧚🏻 fairy: light skin tone
🧚🏼 fairy: medium-light skin tone
🧚🏽 fairy: medium skin tone
🧚🏾 fairy: medium-dark skin tone
🧚🏿 fairy: dark skin tone
🧚‍♂️ man fairy
🧚🏻‍♂️ man fairy: light skin tone
🧚🏼‍♂️ man fairy: medium-light skin tone
🧚🏽‍♂️ man fairy: medium skin tone
🧚🏾‍♂️ man fairy: medium-dark skin tone
🧚🏿‍♂️ man fairy: dark skin tone
🧚‍♀️ woman fairy
🧚🏻‍♀️ woman fairy: light skin tone
🧚🏼‍♀️ woman fairy: medium-light skin tone
🧚🏽‍♀️ woman fairy: medium skin tone
🧚🏾‍♀️ woman fairy: medium-dark skin tone
🧚🏿‍♀️ woman fairy: dark skin tone
🧛 vampire
🧛🏻 vampire: light skin tone
🧛🏼 vampire: medium-light skin tone
🧛🏽 vampire: medium skin tone
🧛🏾 vampire: medium-dark skin tone
🧛🏿 vampire: dark skin tone
🧛‍♂️ man vampire
🧛🏻‍♂️ man vampire: light skin tone
🧛🏼‍♂️ man vampire: medium-light skin tone
🧛🏽‍♂️ man vampire: medium skin tone
🧛🏾‍♂️ man vampire: medium-dark skin tone
🧛🏿‍♂️ man vampire: dark skin tone
🧛‍♀️ woman vampire
🧛🏻‍♀️ woman vampire: light skin tone
🧛🏼‍♀️ woman vampire: medium-light skin tone
🧛🏽‍♀️ woman vampire: medium skin tone
🧛🏾‍♀️ woman vampire: medium-dark skin tone
🧛🏿‍♀️ woman vampire: dark skin tone
🧜 merperson
🧜🏻 merperson: light skin tone
🧜🏼 merperson: medium-light skin tone
🧜🏽 merperson: medium skin tone
🧜🏾 merperson: medium-dark skin tone
🧜🏿 merperson: dark skin tone
🧜‍♂️ merman
🧜🏻‍♂️ merman: light skin tone
🧜🏼‍♂️ merman: medium-light skin tone
🧜🏽‍♂️ merman: medium skin tone
🧜🏾‍♂️ merman: medium-dark skin tone
🧜🏿‍♂️ merman: dark skin tone
🧜‍♀️ mermaid
🧜🏻‍♀️ mermaid: light skin tone
🧜🏼‍♀️ mermaid: medium-light skin tone
🧜🏽‍♀️ mermaid: medium skin tone
🧜🏾‍♀️ mermaid: medium-dark skin tone
🧜🏿‍♀️ mermaid: dark skin tone
🧝 elf
🧝🏻 elf: light skin tone
🧝🏼 elf: medium-light skin tone
🧝🏽 elf: medium skin tone
🧝🏾 elf: medium-dark skin tone
🧝🏿 elf: dark skin tone
🧝‍♂️ man elf
🧝🏻‍♂️ man elf: light skin tone
🧝🏼‍♂️ man elf: medium-light skin tone
🧝🏽‍♂️ man elf: medium skin tone
🧝🏾‍♂️ man elf: medium-dark skin tone
🧝🏿‍♂️ man elf: dark skin tone
🧝‍♀️ woman elf
🧝🏻‍♀️ woman elf: light skin tone
🧝🏼‍♀️ woman elf: medium-light skin tone
🧝🏽‍♀️ woman elf: medium skin tone
🧝🏾‍♀️ woman elf: medium-dark skin tone
🧝🏿‍♀️ woman elf: dark skin tone
🧞 genie
🧞‍♂️ man genie
🧞‍♀️ woman genie
🧟 zombie
🧟‍♂️ man zombie
🧟‍♀️ woman zombie
🧌 troll
💆 person getting massage
💆🏻 person getting massage: light skin tone
💆🏼 person getting massage: medium-light skin tone
💆🏽 person getting massage: medium skin tone
💆🏾 person getting massage: medium-dark skin tone
💆🏿 person getting massage: dark skin tone
💆‍♂️ man getting massage
💆🏻‍♂️ man getting massage: light skin tone
💆🏼‍♂️ man getting massage: medium-light skin tone
💆🏽‍♂️ man getting massage: medium skin tone
💆🏾‍♂️ man getting massage: medium-dark skin tone
💆🏿‍♂️ man getting massage: dark skin tone
💆‍♀️ woman getting massage
💆🏻‍♀️ woman getting massage: light skin tone
💆🏼‍♀️ woman getting massage: medium-light skin tone
💆🏽‍♀️ woman getting massage: medium skin tone
💆🏾‍♀️ woman getting massage: medium-dark skin tone
💆🏿‍♀️ woman getting massage: dark skin tone
💇 person getting haircut
💇🏻 person getting haircut: light skin tone
💇🏼 person getting haircut: medium-light skin tone
💇🏽 person getting haircut: medium skin tone
💇🏾 person getting haircut: medium-dark skin tone
💇🏿 person getting haircut: dark skin tone
💇‍♂️ man getting haircut
💇🏻‍♂️ man getting haircut: light skin tone
💇🏼‍♂️ man getting haircut: medium-light skin tone
💇🏽‍♂️ man getting haircut: medium skin tone
💇🏾‍♂️ man getting haircut: medium-dark skin tone
💇🏿‍♂️ man getting haircut: dark skin tone
💇‍♀️ woman getting haircut
💇🏻‍♀️ woman getting haircut: light skin tone
💇🏼‍♀️ woman getting haircut: medium-light skin tone
💇🏽‍♀️ woman getting haircut: medium skin tone
💇🏾‍♀️ woman getting haircut: medium-dark skin tone
💇🏿‍♀️ woman getting haircut: dark skin tone
🚶 person walking
🚶🏻 person walking: light skin tone
🚶🏼 person walking: medium-light skin tone
🚶🏽 person walking: medium skin tone
🚶🏾 person walking: medium-dark skin tone
🚶🏿 person walking: dark skin tone
🚶‍♂️ man walking
🚶🏻‍♂️ man walking: light skin tone
🚶🏼‍♂️ man walking: medium-light skin tone
🚶🏽‍♂️ man walking: medium skin tone
🚶🏾‍♂️ man walking: medium-dark skin tone
🚶🏿‍♂️ man walking: dark skin tone
🚶‍♀️ woman walking
🚶🏻‍♀️ woman walking: light skin tone
🚶🏼‍♀️ woman walking: medium-light skin tone
🚶🏽‍♀️ woman walking: medium skin tone
🚶🏾‍♀️ woman walking: medium-dark skin tone
🚶🏿‍♀️ woman walking: dark skin tone
🧍 person standing
🧍🏻 person standing: light skin tone
🧍🏼 person standing: medium-light skin tone
🧍🏽 person standing: medium skin tone
🧍🏾 person standing: medium-dark skin tone
🧍🏿 person standing: dark skin tone
🧍‍♂️ man standing
🧍🏻‍♂️ man standing: light skin tone
🧍🏼‍♂️ man standing: medium-light skin tone
🧍🏽‍♂️ man standing: medium skin tone
🧍🏾‍♂️ man standing: medium-dark skin tone
🧍🏿‍♂️ man standing: dark skin tone
🧍‍♀️ woman standing
🧍🏻‍♀️ woman standing: light skin tone
🧍🏼‍♀️ woman standing: medium-light skin tone
🧍🏽‍♀️ woman standing: medium skin tone
🧍🏾‍♀️ woman standing: medium-dark skin tone
🧍🏿‍♀️ woman standing: dark skin tone
🧎 person kneeling
🧎🏻 person kneeling: light skin tone
🧎🏼 person kneeling: medium-light skin tone
🧎🏽 person kneeling: medium skin tone
🧎🏾 person kneeling: medium-dark skin tone
🧎🏿 person kneeling: dark skin tone
🧎‍♂️ man kneeling
🧎🏻‍♂️ man kneeling: light skin tone
🧎🏼‍♂️ man kneeling: medium-light skin tone
🧎🏽‍♂️ man kneeling: medium skin tone
🧎🏾‍♂️ man kneeling: medium-dark skin tone
🧎🏿‍♂️ man kneeling: dark skin tone
🧎‍♀️ woman kneeling
🧎🏻‍♀️ woman kneeling: light skin tone
🧎🏼‍♀️ woman kneeling: medium-light skin tone
🧎🏽‍♀️ woman kneeling: medium skin tone
🧎🏾‍♀️ woman kneeling: medium-dark skin tone
🧎🏿‍♀️ woman kneeling: dark skin tone
🧑‍🦯 person with white cane
🧑🏻‍🦯 person with white cane: light skin tone
🧑🏼‍🦯 person with white cane: medium-light skin tone
🧑🏽‍🦯 person with white cane: medium skin tone
🧑🏾‍🦯 person with white cane: medium-dark skin tone
🧑🏿‍🦯 person with white cane: dark skin tone
👨‍🦯 man with white cane
👨🏻‍🦯 man with white cane: light skin tone
👨🏼‍🦯 man with white cane: medium-light skin tone
👨🏽‍🦯 man with white cane: medium skin tone
👨🏾‍🦯 man with white cane: medium-dark skin tone
👨🏿‍🦯 man with white cane: dark skin tone
👩‍🦯 woman with white cane
👩🏻‍🦯 woman with white cane: light skin tone
👩🏼‍🦯 woman with white cane: medium-light skin tone
👩🏽‍🦯 woman with white cane: medium skin tone
👩🏾‍🦯 woman with white cane: medium-dark skin tone
👩🏿‍🦯 woman with white cane: dark skin tone
🧑‍🦼 person in motorized wheelchair
🧑🏻‍🦼 person in motorized wheelchair: light skin tone
🧑🏼‍🦼 person in motorized wheelchair: medium-light skin tone
🧑🏽‍🦼 person in motorized wheelchair: medium skin tone
🧑🏾‍🦼 person in motorized wheelchair: medium-dark skin tone
🧑🏿‍🦼 person in motorized wheelchair: dark skin tone
👨‍🦼 man in motorized wheelchair
👨🏻‍🦼 man in motorized wheelchair: light skin tone
👨🏼‍🦼 man in motorized wheelchair: medium-light skin tone
👨🏽‍🦼 man in motorized wheelchair: medium skin tone
👨🏾‍🦼 man in motorized wheelchair: medium-dark skin tone
👨🏿‍🦼 man in motorized wheelchair: dark skin tone
👩‍🦼 woman in motorized wheelchair
👩🏻‍🦼 woman in motorized wheelchair: light skin tone
👩🏼‍🦼 woman in motorized wheelchair: medium-light skin tone
👩🏽‍🦼 woman in motorized wheelchair: medium skin tone
👩🏾‍🦼 woman in motorized wheelchair: medium-dark skin tone
👩🏿‍🦼 woman in motorized wheelchair: dark skin tone
🧑‍🦽 person in manual wheelchair
🧑🏻‍🦽 person in manual wheelchair: light skin tone
🧑🏼‍🦽 person in manual wheelchair: medium-light skin tone
🧑🏽‍🦽 person in manual wheelchair: medium skin tone
🧑🏾‍🦽 person in manual wheelchair: medium-dark skin tone
🧑🏿‍🦽 person in manual wheelchair: dark skin tone
👨‍🦽 man in manual wheelchair
👨🏻‍🦽 man in manual wheelchair: light skin tone
👨🏼‍🦽 man in manual wheelchair: medium-light skin tone
👨🏽‍🦽 man in manual wheelchair: medium skin tone
👨🏾‍🦽 man in manual wheelchair: medium-dark skin tone
👨🏿‍🦽 man in manual wheelchair: dark skin tone
👩‍🦽 woman in manual wheelchair
👩🏻‍🦽 woman in manual wheelchair: light skin tone
👩🏼‍🦽 woman in manual wheelchair: medium-light skin tone
👩🏽‍🦽 woman in manual wheelchair: medium skin tone
👩🏾‍🦽 woman in manual wheelchair: medium-dark skin tone
👩🏿‍🦽 woman in manual wheelchair: dark skin tone
🏃 person running
🏃🏻 person running: light skin tone
🏃🏼 person running: medium-light skin tone
🏃🏽 person running: medium skin tone
🏃🏾 person running: medium-dark skin tone
🏃🏿 person running: dark skin tone
🏃‍♂️ man running
🏃🏻‍♂️ man running: light skin tone
🏃🏼‍♂️ man running: medium-light skin tone
🏃🏽‍♂️ man running: medium skin tone
🏃🏾‍♂️ man running: medium-dark skin tone
🏃🏿‍♂️ man running: dark skin tone
🏃‍♀️ woman running
🏃🏻‍♀️ woman running: light skin tone
🏃🏼‍♀️ woman running: medium-light skin tone
🏃🏽‍♀️ woman running: medium skin tone
🏃🏾‍♀️ woman running: medium-dark skin tone
🏃🏿‍♀️ woman running: dark skin tone
💃 woman dancing
💃🏻 woman dancing: light skin tone
💃🏼 woman dancing: medium-light skin tone
💃🏽 woman dancing: medium skin tone
💃🏾 woman dancing: medium-dark skin tone
💃🏿 woman dancing: dark skin tone
🕺 man dancing
🕺🏻 man dancing: light skin tone
🕺🏼 man dancing: medium-light skin tone
🕺🏽 man dancing: medium skin tone
🕺🏾 man dancing: medium-dark skin tone
🕺🏿 man dancing: dark skin tone
🕴️ person in suit levitating
🕴🏻 person in suit levitating: light skin tone
🕴🏼 person in suit levitating: medium-light skin tone
🕴🏽 person in suit levitating: medium skin tone
🕴🏾 person in suit levitating: medium-dark skin tone
🕴🏿 person in suit levitating: dark skin tone
👯 people with bunny ears
👯‍♂️ men with bunny ears
👯‍♀️ women with bunny ears
🧖 person in steamy room
🧖🏻 person in steamy room: light skin tone
🧖🏼 person in steamy room: medium-light skin tone
🧖🏽 person in steamy room: medium skin tone
🧖🏾 person in steamy room: medium-dark skin tone
🧖🏿 person in steamy room: dark skin tone
🧖‍♂️ man in steamy room
🧖🏻‍♂️ man in steamy room: light skin tone
🧖🏼‍♂️ man in steamy room: medium-light skin tone
🧖🏽‍♂️ man in steamy room: medium skin tone
🧖🏾‍♂️ man in steamy room: medium-dark skin tone
🧖🏿‍♂️ man in steamy room: dark skin tone
🧖‍♀️ woman in steamy room
🧖🏻‍♀️ woman in steamy room: light skin tone
🧖🏼‍♀️ woman in steamy room: medium-light skin tone
🧖🏽‍♀️ woman in steamy room: medium skin tone
🧖🏾‍♀️ woman in steamy room: medium-dark skin tone
🧖🏿‍♀️ woman in steamy room: dark skin tone
🧗 person climbing
🧗🏻 person climbing: light skin tone
🧗🏼 person climbing: medium-light skin tone
🧗🏽 person climbing: medium skin tone
🧗🏾 person climbing: medium-dark skin tone
🧗🏿 person climbing: dark skin tone
🧗‍♂️ man climbing
🧗🏻‍♂️ man climbing: light skin tone
🧗🏼‍♂️ man climbing: medium-light skin tone
🧗🏽‍♂️ man climbing: medium skin tone
🧗🏾‍♂️ man climbing: medium-dark skin tone
🧗🏿‍♂️ man climbing: dark skin tone
🧗‍♀️ woman climbing
🧗🏻‍♀️ woman climbing: light skin tone
🧗🏼‍♀️ woman climbing: medium-light skin tone
🧗🏽‍♀️ woman climbing: medium skin tone
🧗🏾‍♀️ woman climbing: medium-dark skin tone
🧗🏿‍♀️ woman climbing: dark skin tone
🤺 person fencing
🏇 horse racing
🏇🏻 horse racing: light skin tone
🏇🏼 horse racing: medium-light skin tone
🏇🏽 horse racing: medium skin tone
🏇🏾 horse racing: medium-dark skin tone
🏇🏿 horse racing: dark skin tone
⛷️ skier
🏂 snowboarder
🏂🏻 snowboarder: light skin tone
🏂🏼 snowboarder: medium-light skin tone
🏂🏽 snowboarder: medium skin tone
🏂🏾 snowboarder: medium-dark skin tone
🏂🏿 snowboarder: dark skin tone
🏌️ person golfing
🏌🏻 person golfing: light skin tone
🏌🏼 person golfing: medium-light skin tone
🏌🏽 person golfing: medium skin tone
🏌🏾 person golfing: medium-dark skin tone
🏌🏿 person golfing: dark skin tone
🏌️‍♂️ man golfing
🏌🏻‍♂️ man golfing: light skin tone
🏌🏼‍♂️ man golfing: medium-light skin tone
🏌🏽‍♂️ man golfing: medium skin tone
🏌🏾‍♂️ man golfing: medium-dark skin tone
🏌🏿‍♂️ man golfing: dark skin tone
🏌️‍♀️ woman golfing
🏌🏻‍♀️ woman golfing: light skin tone
🏌🏼‍♀️ woman golfing: medium-light skin tone
🏌🏽‍♀️ woman golfing: medium skin tone
🏌🏾‍♀️ woman golfing: medium-dark skin tone
🏌🏿‍♀️ woman golfing: dark skin tone
🏄 person surfing
🏄🏻 person surfing: light skin tone
🏄🏼 person surfing: medium-light skin tone
🏄🏽 person surfing: medium skin tone
🏄🏾 person surfing: medium-dark skin tone
🏄🏿 person surfing: dark skin tone
🏄‍♂️ man surfing
🏄🏻‍♂️ man surfing: light skin tone
🏄🏼‍♂️ man surfing: medium-light skin tone
🏄🏽‍♂️ man surfing: medium skin tone
🏄🏾‍♂️ man surfing: medium-dark skin tone
🏄🏿‍♂️ man surfing: dark skin tone
🏄‍♀️ woman surfing
🏄🏻‍♀️ woman surfing: light skin tone
🏄🏼‍♀️ woman surfing: medium-light skin tone
🏄🏽‍♀️ woman surfing: medium skin tone
🏄🏾‍♀️ woman surfing: medium-dark skin tone
🏄🏿‍♀️ woman surfing: dark skin tone
🚣 person rowing boat
🚣🏻 person rowing boat: light skin tone
🚣🏼 person rowing boat: medium-light skin tone
🚣🏽 person rowing boat: medium skin tone
🚣🏾 person rowing boat: medium-dark skin tone
🚣🏿 person rowing boat: dark skin tone
🚣‍♂️ man rowing boat
🚣🏻‍♂️ man rowing boat: light skin tone
🚣🏼‍♂️ man rowing boat: medium-light skin tone
🚣🏽‍♂️ man rowing boat: medium skin tone
🚣🏾‍♂️ man rowing boat: medium-dark skin tone
🚣🏿‍♂️ man rowing boat: dark skin tone
🚣‍♀️ woman rowing boat
🚣🏻‍♀️ woman rowing boat: light skin tone
🚣🏼‍♀️ woman rowing boat: medium-light skin tone
🚣🏽‍♀️ woman rowing boat: medium skin tone
🚣🏾‍♀️ woman rowing boat: medium-dark skin tone
🚣🏿‍♀️ woman rowing boat: dark skin tone
🏊 person swimming
🏊🏻 person swimming: light skin tone
🏊🏼 person swimming: medium-light skin tone
🏊🏽 person swimming: medium skin tone
🏊🏾 person swimming: medium-dark skin tone
🏊🏿 person swimming: dark skin tone
🏊‍♂️ man swimming
🏊🏻‍♂️ man swimming: light skin tone
🏊🏼‍♂️ man swimming: medium-light skin tone
🏊🏽‍♂️ man swimming: medium skin tone
🏊🏾‍♂️ man swimming: medium-dark skin tone
🏊🏿‍♂️ man swimming: dark skin tone
🏊‍♀️ woman swimming
🏊🏻‍♀️ woman swimming: light skin tone
🏊🏼‍♀️ woman swimming: medium-light skin tone
🏊🏽‍♀️ woman swimming: medium skin tone
🏊🏾‍♀️ woman swimming: medium-dark skin tone
🏊🏿‍♀️ woman swimming: dark skin tone
⛹️ person bouncing ball
⛹🏻 person bouncing ball: light skin tone
⛹🏼 person bouncing ball: medium-light skin tone
⛹🏽 person bouncing ball: medium skin tone
⛹🏾 person bouncing ball: medium-dark skin tone
⛹🏿 person bouncing ball: dark skin tone
⛹️‍♂️ man bouncing ball
⛹🏻‍♂️ man bouncing ball: light skin tone
⛹🏼‍♂️ man bouncing ball: medium-light skin tone
⛹🏽‍♂️ man bouncing ball: medium skin tone
⛹🏾‍♂️ man bouncing ball: medium-dark skin tone
⛹🏿‍♂️ man bouncing ball: dark skin tone
⛹️‍♀️ woman bouncing ball
⛹🏻‍♀️ woman bouncing ball: light skin tone
⛹🏼‍♀️ woman bouncing ball: medium-light skin tone
⛹🏽‍♀️ woman bouncing ball: medium skin tone
⛹🏾‍♀️ woman bouncing ball: medium-dark skin tone
⛹🏿‍♀️ woman bouncing ball: dark skin tone
🏋️ person lifting weights
🏋🏻 person lifting weights: light skin tone
🏋🏼 person lifting weights: medium-light skin tone
🏋🏽 person lifting weights: medium skin tone
🏋🏾 person lifting weights: medium-dark skin tone
🏋🏿 person lifting weights: dark skin tone
🏋️‍♂️ man lifting weights
🏋🏻‍♂️ man lifting weights: light skin tone
🏋🏼‍♂️ man lifting weights: medium-light skin tone
🏋🏽‍♂️ man lifting weights: medium skin tone
🏋🏾‍♂️ man lifting weights: medium-dark skin tone
🏋🏿‍♂️ man lifting weights: dark skin tone
🏋️‍♀️ woman lifting weights
🏋🏻‍♀️ woman lifting weights: light skin tone
🏋🏼‍♀️ woman lifting weights: medium-light skin tone
🏋🏽‍♀️ woman lifting weights: medium skin tone
🏋🏾‍♀️ woman lifting weights: medium-dark skin tone
🏋🏿‍♀️ woman lifting weights: dark skin tone
🚴 person biking
🚴🏻 person biking: light skin tone
🚴🏼 person biking: medium-light skin tone
🚴🏽 person biking: medium skin tone
🚴🏾 person biking: medium-dark skin tone
🚴🏿 person biking: dark skin tone
🚴‍♂️ man biking
🚴🏻‍♂️ man biking: light skin tone
🚴🏼‍♂️ man biking: medium-light skin tone
🚴🏽‍♂️ man biking: medium skin tone
🚴🏾‍♂️ man biking: medium-dark skin tone
🚴🏿‍♂️ man biking: dark skin tone
🚴‍♀️ woman biking
🚴🏻‍♀️ woman biking: light skin tone
🚴🏼‍♀️ woman biking: medium-light skin tone
🚴🏽‍♀️ woman biking: medium skin tone
🚴🏾‍♀️ woman biking: medium-dark skin tone
🚴🏿‍♀️ woman biking: dark skin tone
🚵 person mountain biking
🚵🏻 person mountain biking: light skin tone
🚵🏼 person mountain biking: medium-light skin tone
🚵🏽 person mountain biking: medium skin tone
🚵🏾 person mountain biking: medium-dark skin tone
🚵🏿 person mountain biking: dark skin tone
🚵‍♂️ man mountain biking
🚵🏻‍♂️ man mountain biking: light skin tone
🚵🏼‍♂️ man mountain biking: medium-light skin tone
🚵🏽‍♂️ man mountain biking: medium skin tone
🚵🏾‍♂️ man mountain biking: medium-dark skin tone
🚵🏿‍♂️ man mountain biking: dark skin tone
🚵‍♀️ woman mountain biking
🚵🏻‍♀️ woman mountain biking: light skin tone
🚵🏼‍♀️ woman mountain biking: medium-light skin tone
🚵🏽‍♀️ woman mountain biking: medium skin tone
🚵🏾‍♀️ woman mountain biking: medium-dark skin tone
🚵🏿‍♀️ woman mountain biking: dark skin tone
🤸 person cartwheeling
🤸🏻 person cartwheeling: light skin tone
🤸🏼 person cartwheeling: medium-light skin tone
🤸🏽 person cartwheeling: medium skin tone
🤸🏾 person cartwheeling: medium-dark skin tone
🤸🏿 person cartwheeling: dark skin tone
🤸‍♂️ man cartwheeling
🤸🏻‍♂️ man cartwheeling: light skin tone
🤸🏼‍♂️ man cartwheeling: medium-light skin tone
🤸🏽‍♂️ man cartwheeling: medium skin tone
🤸🏾‍♂️ man cartwheeling: medium-dark skin tone
🤸🏿‍♂️ man cartwheeling: dark skin tone
🤸‍♀️ woman cartwheeling
🤸🏻‍♀️ woman cartwheeling: light skin tone
🤸🏼‍♀️ woman cartwheeling: medium-light skin tone
🤸🏽‍♀️ woman cartwheeling: medium skin tone
🤸🏾‍♀️ woman cartwheeling: medium-dark skin tone
🤸🏿‍♀️ woman cartwheeling: dark skin tone
🤼 people wrestling
🤼‍♂️ men wrestling
🤼‍♀️ women wrestling
🤽 person playing water polo
🤽🏻 person playing water polo: light skin tone
🤽🏼 person playing water polo: medium-light skin tone
🤽🏽 person playing water polo: medium skin tone
🤽🏾 person playing water polo: medium-dark skin tone
🤽🏿 person playing water polo: dark skin tone
🤽‍♂️ man playing water polo
🤽🏻‍♂️ man playing water polo: light skin tone
🤽🏼‍♂️ man playing water polo: medium-light skin tone
🤽🏽‍♂️ man playing water polo: medium skin tone
🤽🏾‍♂️ man playing water polo: medium-dark skin tone
🤽🏿‍♂️ man playing water polo: dark skin tone
🤽‍♀️ woman playing water polo
🤽🏻‍♀️ woman playing water polo: light skin tone
🤽🏼‍♀️ woman playing water polo: medium-light skin tone
🤽🏽‍♀️ woman playing water polo: medium skin tone
🤽🏾‍♀️ woman playing water polo: medium-dark skin tone
🤽🏿‍♀️ woman playing water polo: dark skin tone
🤾 person playing handball
🤾🏻 person playing handball: light skin tone
🤾🏼 person playing handball: medium-light skin tone
🤾🏽 person playing handball: medium skin tone
🤾🏾 person playing handball: medium-dark skin tone
🤾🏿 person playing handball: dark skin tone
🤾‍♂️ man playing handball
🤾🏻‍♂️ man playing handball: light skin tone
🤾🏼‍♂️ man playing handball: medium-light skin tone
🤾🏽‍♂️ man playing handball: medium skin tone
🤾🏾‍♂️ man playing handball: medium-dark skin tone
🤾🏿‍♂️ man playing handball: dark skin tone
🤾‍♀️ woman playing handball
🤾🏻‍♀️ woman playing handball: light skin tone
🤾🏼‍♀️ woman playing handball: medium-light skin tone
🤾🏽‍♀️ woman playing handball: medium skin tone
🤾🏾‍♀️ woman playing handball: medium-dark skin tone
🤾🏿‍♀️ woman playing handball: dark skin tone
🤹 person juggling
🤹🏻 person juggling: light skin tone
🤹🏼 person juggling: medium-light skin tone
🤹🏽 person juggling: medium skin tone
🤹🏾 person juggling: medium-dark skin tone
🤹🏿 person juggling: dark skin tone
🤹‍♂️ man juggling
🤹🏻‍♂️ man juggling: light skin tone
🤹🏼‍♂️ man juggling: medium-light skin tone
🤹🏽‍♂️ man juggling: medium skin tone
🤹🏾‍♂️ man juggling: medium-dark skin tone
🤹🏿‍♂️ man juggling: dark skin tone
🤹‍♀️ woman juggling
🤹🏻‍♀️ woman juggling: light skin tone
🤹🏼‍♀️ woman juggling: medium-light skin tone
🤹🏽‍♀️ woman juggling: medium skin tone
🤹🏾‍♀️ woman juggling: medium-dark skin tone
🤹🏿‍♀️ woman juggling: dark skin tone
🧘 person in lotus position
🧘🏻 person in lotus position: light skin tone
🧘🏼 person in lotus position: medium-light skin tone
🧘🏽 person in lotus position: medium skin tone
🧘🏾 person in lotus position: medium-dark skin tone
🧘🏿 person in lotus position: dark skin tone
🧘‍♂️ man in lotus position
🧘🏻‍♂️ man in lotus position: light skin tone
🧘🏼‍♂️ man in lotus position: medium-light skin tone
🧘🏽‍♂️ man in lotus position: medium skin tone
🧘🏾‍♂️ man in lotus position: medium-dark skin tone
🧘🏿‍♂️ man in lotus position: dark skin tone
🧘‍♀️ woman in lotus position
🧘🏻‍♀️ woman in lotus position: light skin tone
🧘🏼‍♀️ woman in lotus position: medium-light skin tone
🧘🏽‍♀️ woman in lotus position: medium skin tone
🧘🏾‍♀️ woman in lotus position: medium-dark skin tone
🧘🏿‍♀️ woman in lotus position: dark skin tone
🛀 person taking bath
🛀🏻 person taking bath: light skin tone
🛀🏼 person taking bath: medium-light skin tone
🛀🏽 person taking bath: medium skin tone
🛀🏾 person taking bath: medium-dark skin tone
🛀🏿 person taking bath: dark skin tone
🛌 person in bed
🛌🏻 person in bed: light skin tone
🛌🏼 person in bed: medium-light skin tone
🛌🏽 person in bed: medium skin tone
🛌🏾 person in bed: medium-dark skin tone
🛌🏿 person in bed: dark skin tone
🧑‍🤝‍🧑 people holding hands
🧑🏻‍🤝‍🧑🏻 people holding hands: light skin tone
🧑🏻‍🤝‍🧑🏼 people holding hands: light skin tone, medium-light skin tone
🧑🏻‍🤝‍🧑🏽 people holding hands: light skin tone, medium skin tone
🧑🏻‍🤝‍🧑🏾 people holding hands: light skin tone, medium-dark skin tone
🧑🏻‍🤝‍🧑🏿 people holding hands: light skin tone, dark skin tone
🧑🏼‍🤝‍🧑🏻 people holding hands: medium-light skin tone, light skin tone
🧑🏼‍🤝‍🧑🏼 people holding hands: medium-light skin tone
🧑🏼‍🤝‍🧑🏽 people holding hands: medium-light skin tone, medium skin tone
🧑🏼‍🤝‍🧑🏾 people holding hands: medium-light skin tone, medium-dark skin tone
🧑🏼‍🤝‍🧑🏿 people holding hands: medium-light skin tone, dark skin tone
🧑🏽‍🤝‍🧑🏻 people holding hands: medium skin tone, light skin tone
🧑🏽‍🤝‍🧑🏼 people holding hands: medium skin tone, medium-light skin tone
🧑🏽‍🤝‍🧑🏽 people holding hands: medium skin tone
🧑🏽‍🤝‍🧑🏾 people holding hands: medium skin tone, medium-dark skin tone
🧑🏽‍🤝‍🧑🏿 people holding hands: medium skin tone, dark skin tone
🧑🏾‍🤝‍🧑🏻 people holding hands: medium-dark skin tone, light skin tone
🧑🏾‍🤝‍🧑🏼 people holding hands: medium-dark skin tone, medium-light skin tone
🧑🏾‍🤝‍🧑🏽 people holding hands: medium-dark skin tone, medium skin tone
🧑🏾‍🤝‍🧑🏾 people holding hands: medium-dark skin tone
🧑🏾‍🤝‍🧑🏿 people holding hands: medium-dark skin tone, dark skin tone
🧑🏿‍🤝‍🧑🏻 people holding hands: dark skin tone, light skin tone
🧑🏿‍🤝‍🧑🏼 people holding hands: dark skin tone, medium-light skin tone
🧑🏿‍🤝‍🧑🏽 people holding hands: dark skin tone, medium skin tone
🧑🏿‍🤝‍🧑🏾 people holding hands: dark skin tone, medium-dark skin tone
🧑🏿‍🤝‍🧑🏿 people holding hands: dark skin tone
👭 women holding hands
👭🏻 women holding hands: light skin tone
👩🏻‍🤝‍👩🏼 women holding hands: light skin tone, medium-light skin tone
👩🏻‍🤝‍👩🏽 women holding hands: light skin tone, medium skin tone
👩🏻‍🤝‍👩🏾 women holding hands: light skin tone, medium-dark skin tone
👩🏻‍🤝‍👩🏿 women holding hands: light skin tone, dark skin tone
👩🏼‍🤝‍👩🏻 women holding hands: medium-light skin tone, light skin tone
👭🏼 women holding hands: medium-light skin tone
👩🏼‍🤝‍👩🏽 women holding hands: medium-light skin tone, medium skin tone
👩🏼‍🤝‍👩🏾 women holding hands: medium-light skin tone, medium-dark skin tone
👩🏼‍🤝‍👩🏿 women holding hands: medium-light skin tone, dark skin tone
👩🏽‍🤝‍👩🏻 women holding hands: medium skin tone, light skin tone
👩🏽‍🤝‍👩🏼 women holding hands: medium skin tone, medium-light skin tone
👭🏽 women holding hands: medium skin tone
👩🏽‍🤝‍👩🏾 women holding hands: medium skin tone, medium-dark skin tone
👩🏽‍🤝‍👩🏿 women holding hands: medium skin tone, dark skin tone
👩🏾‍🤝‍👩🏻 women holding hands: medium-dark skin tone, light skin tone
👩🏾‍🤝‍👩🏼 women holding hands: medium-dark skin tone, medium-light skin tone
👩🏾‍🤝‍👩🏽 women holding hands: medium-dark skin tone, medium skin tone
👭🏾 women holding hands: medium-dark skin tone
👩🏾‍🤝‍👩🏿 women holding hands: medium-dark skin tone, dark skin tone
👩🏿‍🤝‍👩🏻 women holding hands: dark skin tone, light skin tone
👩🏿‍🤝‍👩🏼 women holding hands: dark skin tone, medium-light skin tone
👩🏿‍🤝‍👩🏽 women holding hands: dark skin tone, medium skin tone
👩🏿‍🤝‍👩🏾 women holding hands: dark skin tone, medium-dark skin tone
👭🏿 women holding hands: dark skin tone
👫 woman and man holding hands
👫🏻 woman and man holding hands: light skin tone
👩🏻‍🤝‍👨🏼 woman and man holding hands: light skin tone, medium-light skin tone
👩🏻‍🤝‍👨🏽 woman and man holding hands: light skin tone, medium skin tone
👩🏻‍🤝‍👨🏾 woman and man holding hands: light skin tone, medium-dark skin tone
👩🏻‍🤝‍👨🏿 woman and man holding hands: light skin tone, dark skin tone
👩🏼‍🤝‍👨🏻 woman and man holding hands: medium-light skin tone, light skin tone
👫🏼 woman and man holding hands: medium-light skin tone
👩🏼‍🤝‍👨🏽 woman and man holding hands: medium-light skin tone, medium skin tone
👩🏼‍🤝‍👨🏾 woman and man holding hands: medium-light skin tone, medium-dark skin tone
👩🏼‍🤝‍👨🏿 woman and man holding hands: medium-light skin tone, dark skin tone
👩🏽‍🤝‍👨🏻 woman and man holding hands: medium skin tone, light skin tone
👩🏽‍🤝‍👨🏼 woman and man holding hands: medium skin tone, medium-light skin tone
👫🏽 woman and man holding hands: medium skin tone
👩🏽‍🤝‍👨🏾 woman and man holding hands: medium skin tone, medium-dark skin tone
👩🏽‍🤝‍👨🏿 woman and man holding hands: medium skin tone, dark skin tone
👩🏾‍🤝‍👨🏻 woman and man holding hands: medium-dark skin tone, light skin tone
👩🏾‍🤝‍👨🏼 woman and man holding hands: medium-dark skin tone, medium-light skin tone
👩🏾‍🤝‍👨🏽 woman and man holding hands: medium-dark skin tone, medium skin tone
👫🏾 woman and man holding hands: medium-dark skin tone
👩🏾‍🤝‍👨🏿 woman and man holding hands: medium-dark skin tone, dark skin tone
👩🏿‍🤝‍👨🏻 woman and man holding hands: dark skin tone, light skin tone
👩🏿‍🤝‍👨🏼 woman and man holding hands: dark skin tone, medium-light skin tone
👩🏿‍🤝‍👨🏽 woman and man holding hands: dark skin tone, medium skin tone
👩🏿‍🤝‍👨🏾 woman and man holding hands: dark skin tone, medium-dark skin tone
👫🏿 woman and man holding hands: dark skin tone
👬 men holding hands
👬🏻 men holding hands: light skin tone
👨🏻‍🤝‍👨🏼 men holding hands: light skin tone, medium-light skin tone
👨🏻‍🤝‍👨🏽 men holding hands: light skin tone, medium skin tone
👨🏻‍🤝‍👨🏾 men holding hands: light skin tone, medium-dark skin tone
👨🏻‍🤝‍👨🏿 men holding hands: light skin tone, dark skin tone
👨🏼‍🤝‍👨🏻 men holding hands: medium-light skin tone, light skin tone
👬🏼 men holding hands: medium-light skin tone
👨🏼‍🤝‍👨🏽 men holding hands: medium-light skin tone, medium skin tone
👨🏼‍🤝‍👨🏾 men holding hands: medium-light skin tone, medium-dark skin tone
👨🏼‍🤝‍👨🏿 men holding hands: medium-light skin tone, dark skin tone
👨🏽‍🤝‍👨🏻 men holding hands: medium skin tone, light skin tone
👨🏽‍🤝‍👨🏼 men holding hands: medium skin tone, medium-light skin tone
👬🏽 men holding hands: medium skin tone
👨🏽‍🤝‍👨🏾 men holding hands: medium skin tone, medium-dark skin tone
👨🏽‍🤝‍👨🏿 men holding hands: medium skin tone, dark skin tone
👨🏾‍🤝‍👨🏻 men holding hands: medium-dark skin tone, light skin tone
👨🏾‍🤝‍👨🏼 men holding hands: medium-dark skin tone, medium-light skin tone
👨🏾‍🤝‍👨🏽 men holding hands: medium-dark skin tone, medium skin tone
👬🏾 men holding hands: medium-dark skin tone
👨🏾‍🤝‍👨🏿 men holding hands: medium-dark skin tone, dark skin tone
👨🏿‍🤝‍👨🏻 men holding hands: dark skin tone, light skin tone
👨🏿‍🤝‍👨🏼 men holding hands: dark skin tone, medium-light skin tone
👨🏿‍🤝‍👨🏽 men holding hands: dark skin tone, medium skin tone
👨🏿‍🤝‍👨🏾 men holding hands: dark skin tone, medium-dark skin tone
👬🏿 men holding hands: dark skin tone
💏 kiss
💏🏻 kiss: light skin tone
💏🏼 kiss: medium-light skin tone
💏🏽 kiss: medium skin tone
💏🏾 kiss: medium-dark skin tone
💏🏿 kiss: dark skin tone
🧑🏻‍❤️‍💋‍🧑🏼 kiss: person, person, light skin tone, medium-light skin tone
🧑🏻‍❤️‍💋‍🧑🏽 kiss: person, person, light skin tone, medium skin tone
🧑🏻‍❤️‍💋‍🧑🏾 kiss: person, person, light skin tone, medium-dark skin tone
🧑🏻‍❤️‍💋‍🧑🏿 kiss: person, person, light skin tone, dark skin tone
🧑🏼‍❤️‍💋‍🧑🏻 kiss: person, person, medium-light skin tone, light skin tone
🧑🏼‍❤️‍💋‍🧑🏽 kiss: person, person, medium-light skin tone, medium skin tone
🧑🏼‍❤️‍💋‍🧑🏾 kiss: person, person, medium-light skin tone, medium-dark skin tone
🧑🏼‍❤️‍💋‍🧑🏿 kiss: person, person, medium-light skin tone, dark skin tone
🧑🏽‍❤️‍💋‍🧑🏻 kiss: person, person, medium skin tone, light skin tone
🧑🏽‍❤️‍💋‍🧑🏼 kiss: person, person, medium skin tone, medium-light skin tone
🧑🏽‍❤️‍💋‍🧑🏾 kiss: person, person, medium skin tone, medium-dark skin tone
🧑🏽‍❤️‍💋‍🧑🏿 kiss: person, person, medium skin tone, dark skin tone
🧑🏾‍❤️‍💋‍🧑🏻 kiss: person, person, medium-dark skin tone, light skin tone
🧑🏾‍❤️‍💋‍🧑🏼 kiss: person, person, medium-dark skin tone, medium-light skin tone
🧑🏾‍❤️‍💋‍🧑🏽 kiss: person, person, medium-dark skin tone, medium skin tone
🧑🏾‍❤️‍💋‍🧑🏿 kiss: person, person, medium-dark skin tone, dark skin tone
🧑🏿‍❤️‍💋‍🧑🏻 kiss: person, person, dark skin tone, light skin tone
🧑🏿‍❤️‍💋‍🧑🏼 kiss: person, person, dark skin tone, medium-light skin tone
🧑🏿‍❤️‍💋‍🧑🏽 kiss: person, person, dark skin tone, medium skin tone
🧑🏿‍❤️‍💋‍🧑🏾 kiss: person, person, dark skin tone, medium-dark skin tone
👩‍❤️‍💋‍👨 kiss: woman, man
👩🏻‍❤️‍💋‍👨🏻 kiss: woman, man, light skin tone
👩🏻‍❤️‍💋‍👨🏼 kiss: woman, man, light skin tone, medium-light skin tone
👩🏻‍❤️‍💋‍👨🏽 kiss: woman, man, light skin tone, medium skin tone
👩🏻‍❤️‍💋‍👨🏾 kiss: woman, man, light skin tone, medium-dark skin tone
👩🏻‍❤️‍💋‍👨🏿 kiss: woman, man, light skin tone, dark skin tone
👩🏼‍❤️‍💋‍👨🏻 kiss: woman, man, medium-light skin tone, light skin tone
👩🏼‍❤️‍💋‍👨🏼 kiss: woman, man, medium-light skin tone
👩🏼‍❤️‍💋‍👨🏽 kiss: woman, man, medium-light skin tone, medium skin tone
👩🏼‍❤️‍💋‍👨🏾 kiss: woman, man, medium-light skin tone, medium-dark skin tone
👩🏼‍❤️‍💋‍👨🏿 kiss: woman, man, medium-light skin tone, dark skin tone
👩🏽‍❤️‍💋‍👨🏻 kiss: woman, man, medium skin tone, light skin tone
👩🏽‍❤️‍💋‍👨🏼 kiss: woman, man, medium skin tone, medium-light skin tone
👩🏽‍❤️‍💋‍👨🏽 kiss: woman, man, medium skin tone
👩🏽‍❤️‍💋‍👨🏾 kiss: woman, man, medium skin tone, medium-dark skin tone
👩🏽‍❤️‍💋‍👨🏿 kiss: woman, man, medium skin tone, dark skin tone
👩🏾‍❤️‍💋‍👨🏻 kiss: woman, man, medium-dark skin tone, light skin tone
👩🏾‍❤️‍💋‍👨🏼 kiss: woman, man, medium-dark skin tone, medium-light skin tone
👩🏾‍❤️‍💋‍👨🏽 kiss: woman, man, medium-dark skin tone, medium skin tone
👩🏾‍❤️‍💋‍👨🏾 kiss: woman, man, medium-dark skin tone
👩🏾‍❤️‍💋‍👨🏿 kiss: woman, man, medium-dark skin tone, dark skin tone
👩🏿‍❤️‍💋‍👨🏻 kiss: woman, man, dark skin tone, light skin tone
👩🏿‍❤️‍💋‍👨🏼 kiss: woman, man, dark skin tone, medium-light skin tone
👩🏿‍❤️‍💋‍👨🏽 kiss: woman, man, dark skin tone, medium skin tone
👩🏿‍❤️‍💋‍👨🏾 kiss: woman, man, dark skin tone, medium-dark skin tone
👩🏿‍❤️‍💋‍👨🏿 kiss: woman, man, dark skin tone
👨‍❤️‍💋‍👨 kiss: man, man
👨🏻‍❤️‍💋‍👨🏻 kiss: man, man, light skin tone
👨🏻‍❤️‍💋‍👨🏼 kiss: man, man, light skin tone, medium-light skin tone
👨🏻‍❤️‍💋‍👨🏽 kiss: man, man, light skin tone, medium skin tone
👨🏻‍❤️‍💋‍👨🏾 kiss: man, man, light skin tone, medium-dark skin tone
👨🏻‍❤️‍💋‍👨🏿 kiss: man, man, light skin tone, dark skin tone
👨🏼‍❤️‍💋‍👨🏻 kiss: man, man, medium-light skin tone, light skin tone
👨🏼‍❤️‍💋‍👨🏼 kiss: man, man, medium-light skin tone
👨🏼‍❤️‍💋‍👨🏽 kiss: man, man, medium-light skin tone, medium skin tone
👨🏼‍❤️‍💋‍👨🏾 kiss: man, man, medium-light skin tone, medium-dark skin tone
👨🏼‍❤️‍💋‍👨🏿 kiss: man, man, medium-light skin tone, dark skin tone
👨🏽‍❤️‍💋‍👨🏻 kiss: man, man, medium skin tone, light skin tone
👨🏽‍❤️‍💋‍👨🏼 kiss: man, man, medium skin tone, medium-light skin tone
👨🏽‍❤️‍💋‍👨🏽 kiss: man, man, medium skin tone
👨🏽‍❤️‍💋‍👨🏾 kiss: man, man, medium skin tone, medium-dark skin tone
👨🏽‍❤️‍💋‍👨🏿 kiss: man, man, medium skin tone, dark skin tone
👨🏾‍❤️‍💋‍👨🏻 kiss: man, man, medium-dark skin tone, light skin tone
👨🏾‍❤️‍💋‍👨🏼 kiss: man, man, medium-dark skin tone, medium-light skin tone
👨🏾‍❤️‍💋‍👨🏽 kiss: man, man, medium-dark skin tone, medium skin tone
👨🏾‍❤️‍💋‍👨🏾 kiss: man, man, medium-dark skin tone
👨🏾‍❤️‍💋‍👨🏿 kiss: man, man, medium-dark skin tone, dark skin tone
👨🏿‍❤️‍💋‍👨🏻 kiss: man, man, dark skin tone, light skin tone
👨🏿‍❤️‍💋‍👨🏼 kiss: man, man, dark skin tone, medium-light skin tone
👨🏿‍❤️‍💋‍👨🏽 kiss: man, man, dark skin tone, medium skin tone
👨🏿‍❤️‍💋‍👨🏾 kiss: man, man, dark skin tone, medium-dark skin tone
👨🏿‍❤️‍💋‍👨🏿 kiss: man, man, dark skin tone
👩‍❤️‍💋‍👩 kiss: woman, woman
👩🏻‍❤️‍💋‍👩🏻 kiss: woman, woman, light skin tone
👩🏻‍❤️‍💋‍👩🏼 kiss: woman, woman, light skin tone, medium-light skin tone
👩🏻‍❤️‍💋‍👩🏽 kiss: woman, woman, light skin tone, medium skin tone
👩🏻‍❤️‍💋‍👩🏾 kiss: woman, woman, light skin tone, medium-dark skin tone
👩🏻‍❤️‍💋‍👩🏿 kiss: woman, woman, light skin tone, dark skin tone
👩🏼‍❤️‍💋‍👩🏻 kiss: woman, woman, medium-light skin tone, light skin tone
👩🏼‍❤️‍💋‍👩🏼 kiss: woman, woman, medium-light skin tone
👩🏼‍❤️‍💋‍👩🏽 kiss: woman, woman, medium-light skin tone, medium skin tone
👩🏼‍❤️‍💋‍👩🏾 kiss: woman, woman, medium-light skin tone, medium-dark skin tone
👩🏼‍❤️‍💋‍👩🏿 kiss: woman, woman, medium-light skin tone, dark skin tone
👩🏽‍❤️‍💋‍👩🏻 kiss: woman, woman, medium skin tone, light skin tone
👩🏽‍❤️‍💋‍👩🏼 kiss: woman, woman, medium skin tone, medium-light skin tone
👩🏽‍❤️‍💋‍👩🏽 kiss: woman, woman, medium skin tone
👩🏽‍❤️‍💋‍👩🏾 kiss: woman, woman, medium skin tone, medium-dark skin tone
👩🏽‍❤️‍💋‍👩🏿 kiss: woman, woman, medium skin tone, dark skin tone
👩🏾‍❤️‍💋‍👩🏻 kiss: woman, woman, medium-dark skin tone, light skin tone
👩🏾‍❤️‍💋‍👩🏼 kiss: woman, woman, medium-dark skin tone, medium-light skin tone
👩🏾‍❤️‍💋‍👩🏽 kiss: woman, woman, medium-dark skin tone, medium skin tone
👩🏾‍❤️‍💋‍👩🏾 kiss: woman, woman, medium-dark skin tone
👩🏾‍❤️‍💋‍👩🏿 kiss: woman, woman, medium-dark skin tone, dark skin tone
👩🏿‍❤️‍💋‍👩🏻 kiss: woman, woman, dark skin tone, light skin tone
👩🏿‍❤️‍💋‍👩🏼 kiss: woman, woman, dark skin tone, medium-light skin tone
👩🏿‍❤️‍💋‍👩🏽 kiss: woman, woman, dark skin tone, medium skin tone
👩🏿‍❤️‍💋‍👩🏾 kiss: woman, woman, dark skin tone, medium-dark skin tone
👩🏿‍❤️‍💋‍👩🏿 kiss: woman, woman, dark skin tone
💑 couple with heart
💑🏻 couple with heart: light skin tone
💑🏼 couple with heart: medium-light skin tone
💑🏽 couple with heart: medium skin tone
💑🏾 couple with heart: medium-dark skin tone
💑🏿 couple with heart: dark skin tone
🧑🏻‍❤️‍🧑🏼 couple with heart: person, person, light skin tone, medium-light skin tone
🧑🏻‍❤️‍🧑🏽 couple with heart: person, person, light skin tone, medium skin tone
🧑🏻‍❤️‍🧑🏾 couple with heart: person, person, light skin tone, medium-dark skin tone
🧑🏻‍❤️‍🧑🏿 couple with heart: person, person, light skin tone, dark skin tone
🧑🏼‍❤️‍🧑🏻 couple with heart: person, person, medium-light skin tone, light skin tone
🧑🏼‍❤️‍🧑🏽 couple with heart: person, person, medium-light skin tone, medium skin tone
🧑🏼‍❤️‍🧑🏾 couple with heart: person, person, medium-light skin tone, medium-dark skin tone
🧑🏼‍❤️‍🧑🏿 couple with heart: person, person, medium-light skin tone, dark skin tone
🧑🏽‍❤️‍🧑🏻 couple with heart: person, person, medium skin tone, light skin tone
🧑🏽‍❤️‍🧑🏼 couple with heart: person, person, medium skin tone, medium-light skin tone
🧑🏽‍❤️‍🧑🏾 couple with heart: person, person, medium skin tone, medium-dark skin tone
🧑🏽‍❤️‍🧑🏿 couple with heart: person, person, medium skin tone, dark skin tone
🧑🏾‍❤️‍🧑🏻 couple with heart: person, person, medium-dark skin tone, light skin tone
🧑🏾‍❤️‍🧑🏼 couple with heart: person, person, medium-dark skin tone, medium-light skin tone
🧑🏾‍❤️‍🧑🏽 couple with heart: person, person, medium-dark skin tone, medium skin tone
🧑🏾‍❤️‍🧑🏿 couple with heart: person, person, medium-dark skin tone, dark skin tone
🧑🏿‍❤️‍🧑🏻 couple with heart: person, person, dark skin tone, light skin tone
🧑🏿‍❤️‍🧑🏼 couple with heart: person, person, dark skin tone, medium-light skin tone
🧑🏿‍❤️‍🧑🏽 couple with heart: person, person, dark skin tone, medium skin tone
🧑🏿‍❤️‍🧑🏾 couple with heart: person, person, dark skin tone, medium-dark skin tone
👩‍❤️‍👨 couple with heart: woman, man
👩🏻‍❤️‍👨🏻 couple with heart: woman, man, light skin tone
👩🏻‍❤️‍👨🏼 couple with heart: woman, man, light skin tone, medium-light skin tone
👩🏻‍❤️‍👨🏽 couple with heart: woman, man, light skin tone, medium skin tone
👩🏻‍❤️‍👨🏾 couple with heart: woman, man, light skin tone, medium-dark skin tone
👩🏻‍❤️‍👨🏿 couple with heart: woman, man, light skin tone, dark skin tone
👩🏼‍❤️‍👨🏻 couple with heart: woman, man, medium-light skin tone, light skin tone
👩🏼‍❤️‍👨🏼 couple with heart: woman, man, medium-light skin tone
👩🏼‍❤️‍👨🏽 couple with heart: woman, man, medium-light skin tone, medium skin tone
👩🏼‍❤️‍👨🏾 couple with heart: woman, man, medium-light skin tone, medium-dark skin tone
👩🏼‍❤️‍👨🏿 couple with heart: woman, man, medium-light skin tone, dark skin tone
👩🏽‍❤️‍👨🏻 couple with heart: woman, man, medium skin tone, light skin tone
👩🏽‍❤️‍👨🏼 couple with heart: woman, man, medium skin tone, medium-light skin tone
👩🏽‍❤️‍👨🏽 couple with heart: woman, man, medium skin tone
👩🏽‍❤️‍👨🏾 couple with heart: woman, man, medium skin tone, medium-dark skin tone
👩🏽‍❤️‍👨🏿 couple with heart: woman, man, medium skin tone, dark skin tone
👩🏾‍❤️‍👨🏻 couple with heart: woman, man, medium-dark skin tone, light skin tone
👩🏾‍❤️‍👨🏼 couple with heart: woman, man, medium-dark skin tone, medium-light skin tone
👩🏾‍❤️‍👨🏽 couple with heart: woman, man, medium-dark skin tone, medium skin tone
👩🏾‍❤️‍👨🏾 couple with heart: woman, man, medium-dark skin tone
👩🏾‍❤️‍👨🏿 couple with heart: woman, man, medium-dark skin tone, dark skin tone
👩🏿‍❤️‍👨🏻 couple with heart: woman, man, dark skin tone, light skin tone
👩🏿‍❤️‍👨🏼 couple with heart: woman, man, dark skin tone, medium-light skin tone
👩🏿‍❤️‍👨🏽 couple with heart: woman, man, dark skin tone, medium skin tone
👩🏿‍❤️‍👨🏾 couple with heart: woman, man, dark skin tone, medium-dark skin tone
👩🏿‍❤️‍👨🏿 couple with heart: woman, man, dark skin tone
👨‍❤️‍👨 couple with heart: man, man
👨🏻‍❤️‍👨🏻 couple with heart: man, man, light skin tone
👨🏻‍❤️‍👨🏼 couple with heart: man, man, light skin tone, medium-light skin tone
👨🏻‍❤️‍👨🏽 couple with heart: man, man, light skin tone, medium skin tone
👨🏻‍❤️‍👨🏾 couple with heart: man, man, light skin tone, medium-dark skin tone
👨🏻‍❤️‍👨🏿 couple with heart: man, man, light skin tone, dark skin tone
👨🏼‍❤️‍👨🏻 couple with heart: man, man, medium-light skin tone, light skin tone
👨🏼‍❤️‍👨🏼 couple with heart: man, man, medium-light skin tone
👨🏼‍❤️‍👨🏽 couple with heart: man, man, medium-light skin tone, medium skin tone
👨🏼‍❤️‍👨🏾 couple with heart: man, man, medium-light skin tone, medium-dark skin tone
👨🏼‍❤️‍👨🏿 couple with heart: man, man, medium-light skin tone, dark skin tone
👨🏽‍❤️‍👨🏻 couple with heart: man, man, medium skin tone, light skin tone
👨🏽‍❤️‍👨🏼 couple with heart: man, man, medium skin tone, medium-light skin tone
👨🏽‍❤️‍👨🏽 couple with heart: man, man, medium skin tone
👨🏽‍❤️‍👨🏾 couple with heart: man, man, medium skin tone, medium-dark skin tone
👨🏽‍❤️‍👨🏿 couple with heart: man, man, medium skin tone, dark skin tone
👨🏾‍❤️‍👨🏻 couple with heart: man, man, medium-dark skin tone, light skin tone
👨🏾‍❤️‍👨🏼 couple with heart: man, man, medium-dark skin tone, medium-light skin tone
👨🏾‍❤️‍👨🏽 couple with heart: man, man, medium-dark skin tone, medium skin tone
👨🏾‍❤️‍👨🏾 couple with heart: man, man, medium-dark skin tone
👨🏾‍❤️‍👨🏿 couple with heart: man, man, medium-dark skin tone, dark skin tone
👨🏿‍❤️‍👨🏻 couple with heart: man, man, dark skin tone, light skin tone
👨🏿‍❤️‍👨🏼 couple with heart: man, man, dark skin tone, medium-light skin tone
👨🏿‍❤️‍👨🏽 couple with heart: man, man, dark skin tone, medium skin tone
👨🏿‍❤️‍👨🏾 couple with heart: man, man, dark skin tone, medium-dark skin tone
👨🏿‍❤️‍👨🏿 couple with heart: man, man, dark skin tone
👩‍❤️‍👩 couple with heart: woman, woman
👩🏻‍❤️‍👩🏻 couple with heart: woman, woman, light skin tone
👩🏻‍❤️‍👩🏼 couple with heart: woman, woman, light skin tone, medium-light skin tone
👩🏻‍❤️‍👩🏽 couple with heart: woman, woman, light skin tone, medium skin tone
👩🏻‍❤️‍👩🏾 couple with heart: woman, woman, light skin tone, medium-dark skin tone
👩🏻‍❤️‍👩🏿 couple with heart: woman, woman, light skin tone, dark skin tone
👩🏼‍❤️‍👩🏻 couple with heart: woman, woman, medium-light skin tone, light skin tone
👩🏼‍❤️‍👩🏼 couple with heart: woman, woman, medium-light skin tone
👩🏼‍❤️‍👩🏽 couple with heart: woman, woman, medium-light skin tone, medium skin tone
👩🏼‍❤️‍👩🏾 couple with heart: woman, woman, medium-light skin tone, medium-dark skin tone
👩🏼‍❤️‍👩🏿 couple with heart: woman, woman, medium-light skin tone, dark skin tone
👩🏽‍❤️‍👩🏻 couple with heart: woman, woman, medium skin tone, light skin tone
👩🏽‍❤️‍👩🏼 couple with heart: woman, woman, medium skin tone, medium-light skin tone
👩🏽‍❤️‍👩🏽 couple with heart: woman, woman, medium skin tone
👩🏽‍❤️‍👩🏾 couple with heart: woman, woman, medium skin tone, medium-dark skin tone
👩🏽‍❤️‍👩🏿 couple with heart: woman, woman, medium skin tone, dark skin tone
👩🏾‍❤️‍👩🏻 couple with heart: woman, woman, medium-dark skin tone, light skin tone
👩🏾‍❤️‍👩🏼 couple with heart: woman, woman, medium-dark skin tone, medium-light skin tone
👩🏾‍❤️‍👩🏽 couple with heart: woman, woman, medium-dark skin tone, medium skin tone
👩🏾‍❤️‍👩🏾 couple with heart: woman, woman, medium-dark skin tone
👩🏾‍❤️‍👩🏿 couple with heart: woman, woman, medium-dark skin tone, dark skin tone
👩🏿‍❤️‍👩🏻 couple with heart: woman, woman, dark skin tone, light skin tone
👩🏿‍❤️‍👩🏼 couple with heart: woman, woman, dark skin tone, medium-light skin tone
👩🏿‍❤️‍👩🏽 couple with heart: woman, woman, dark skin tone, medium skin tone
👩🏿‍❤️‍👩🏾 couple with heart: woman, woman, dark skin tone, medium-dark skin tone
👩🏿‍❤️‍👩🏿 couple with heart: woman, woman, dark skin tone
👪 family
👨‍👩‍👦 family: man, woman, boy
👨‍👩‍👧 family: man, woman, girl
👨‍👩‍👧‍👦 family: man, woman, girl, boy
👨‍👩‍👦‍👦 family: man, woman, boy, boy
👨‍👩‍👧‍👧 family: man, woman, girl, girl
👨‍👨‍👦 family: man, man, boy
👨‍👨‍👧 family: man, man, girl
👨‍👨‍👧‍👦 family: man, man, girl, boy
👨‍👨‍👦‍👦 family: man, man, boy, boy
👨‍👨‍👧‍👧 family: man, man, girl, girl
👩‍👩‍👦 family: woman, woman, boy
👩‍👩‍👧 family: woman, woman, girl
👩‍👩‍👧‍👦 family: woman, woman, girl, boy
👩‍👩‍👦‍👦 family: woman, woman, boy, boy
👩‍👩‍👧‍👧 family: woman, woman, girl, girl
👨‍👦 family: man, boy
👨‍👦‍👦 family: man, boy, boy
👨‍👧 family: man, girl
👨‍👧‍👦 family: man, girl, boy
👨‍👧‍👧 family: man, girl, girl
👩‍👦 family: woman, boy
👩‍👦‍👦 family: woman, boy, boy
👩‍👧 family: woman, girl
👩‍👧‍👦 family: woman, girl, boy
👩‍👧‍👧 family: woman, girl, girl
🗣️ speaking head
👤 bust in silhouette
👥 busts in silhouette


@@ 316,17 2319,21 @@
🐶 dog face
🐕 dog
🦮 guide dog
🐕‍🦺 service dog
🐩 poodle
🐺 wolf
🦊 fox
🦝 raccoon
🐱 cat face
🐈 cat
🐈‍⬛ black cat
🦁 lion
🐯 tiger face
🐅 tiger
🐆 leopard
🐴 horse face
🫎 moose
🫏 donkey
🐎 horse
🦄 unicorn
🦓 zebra


@@ 362,6 2369,7 @@
🦔 hedgehog
🦇 bat
🐻 bear
🐻‍❄️ polar bear
🐨 koala
🐼 panda
🦥 sloth


@@ 388,6 2396,9 @@
🦩 flamingo
🦚 peacock
🦜 parrot
🪽 wing
🐦‍⬛ black bird
🪿 goose
🐸 frog
🐊 crocodile
🐢 turtle


@@ 408,6 2419,7 @@
🐙 octopus
🐚 spiral shell
🪸 coral
🪼 jellyfish
🐌 snail
🦋 butterfly
🐛 bug


@@ 435,6 2447,7 @@
🌻 sunflower
🌼 blossom
🌷 tulip
🪻 hyacinth
🌱 seedling
🪴 potted plant
🌲 evergreen tree


@@ 450,6 2463,7 @@
🍃 leaf fluttering in wind
🪹 empty nest
🪺 nest with eggs
🍄 mushroom
🍇 grapes
🍈 melon
🍉 watermelon


@@ 481,10 2495,11 @@
🥦 broccoli
🧄 garlic
🧅 onion
🍄 mushroom
🥜 peanuts
🫘 beans
🌰 chestnut
🫚 ginger root
🫛 pea pod
🍞 bread
🥐 croissant
🥖 baguette bread


@@ 857,11 2872,10 @@
🎯 bullseye
🪀 yo-yo
🪁 kite
🔫 water pistol
🎱 pool 8 ball
🔮 crystal ball
🪄 magic wand
🧿 nazar amulet
🪬 hamsa
🎮 video game
🕹️ joystick
🎰 slot machine


@@ 906,6 2920,7 @@
🩳 shorts
👙 bikini
👚 woman’s clothes
🪭 folding hand fan
👛 purse
👜 handbag
👝 clutch bag


@@ 920,6 2935,7 @@
👡 woman’s sandal
🩰 ballet shoes
👢 woman’s boot
🪮 hair pick
👑 crown
👒 woman’s hat
🎩 top hat


@@ 958,6 2974,8 @@
🪕 banjo
🥁 drum
🪘 long drum
🪇 maracas
🪈 flute
📱 mobile phone
📲 mobile phone with arrow
☎️ telephone


@@ 1077,7 3095,7 @@
🛠️ hammer and wrench
🗡️ dagger
⚔️ crossed swords
🔫 water pistol
💣 bomb
🪃 boomerang
🏹 bow and arrow
🛡️ shield


@@ 1138,6 3156,8 @@
⚰️ coffin
🪦 headstone
⚱️ funeral urn
🧿 nazar amulet
🪬 hamsa
🗿 moai
🪧 placard
🪪 identification card


@@ 1200,6 3220,7 @@
☮️ peace symbol
🕎 menorah
🔯 dotted six-pointed star
🪯 khanda
♈ Aries
♉ Taurus
♊ Gemini


@@ 1235,6 3256,7 @@
🔅 dim button
🔆 bright button
📶 antenna bars
🛜 wireless
📳 vibration mode
📴 mobile phone off
♀️ female sign


@@ 1367,6 3389,9 @@
🎌 crossed flags
🏴 black flag
🏳️ white flag
🏳️‍🌈 rainbow flag
🏳️‍⚧️ transgender flag
🏴‍☠️ pirate flag
🇦🇨 flag: Ascension Island
🇦🇩 flag: Andorra
🇦🇪 flag: United Arab Emirates


@@ 1627,4 3652,4 @@
🇿🇼 flag: Zimbabwe
🏴󠁧󠁢󠁥󠁮󠁧󠁿 flag: England
🏴󠁧󠁢󠁳󠁣󠁴󠁿 flag: Scotland
🏴󠁧󠁢󠁷󠁬󠁳󠁿 flag: Wales
\ No newline at end of file
🏴󠁧󠁢󠁷󠁬󠁳󠁿 flag: Wales

D .local/share/lazykris/lazykris-wallpaper.png => .local/share/lazykris/lazykris-wallpaper.png +0 -0
A .local/share/wallpapers/cs-winter-1920x960.webp => .local/share/wallpapers/cs-winter-1920x960.webp +0 -0
D .local/share/wallpapers/d1e2f1-horizontal.png => .local/share/wallpapers/d1e2f1-horizontal.png +0 -0
D .local/share/wallpapers/d1e2f1-vertical.png => .local/share/wallpapers/d1e2f1-vertical.png +0 -0
R .local/share/wallpapers/khr1st.webp => .local/share/wallpapers/image1-1536x1024.webp +0 -0
A .local/share/wallpapers/image2-1920x1200.webp => .local/share/wallpapers/image2-1920x1200.webp +0 -0
A .local/share/wallpapers/image3-1920x1080.webp => .local/share/wallpapers/image3-1920x1080.webp +0 -0
D .local/share/wallpapers/khr1st-pain-wallpaper.png => .local/share/wallpapers/khr1st-pain-wallpaper.png +0 -0
D .local/share/wallpapers/kris-wallpaper-1.jpg => .local/share/wallpapers/kris-wallpaper-1.jpg +0 -0
D .local/share/wallpapers/lazykris-perfect-blue-wallpaper.jpg => .local/share/wallpapers/lazykris-perfect-blue-wallpaper.jpg +0 -0
A .local/share/wallpapers/p9blue-1080x1920.png => .local/share/wallpapers/p9blue-1080x1920.png +0 -0
A .local/share/wallpapers/p9blue-2560x1440.png => .local/share/wallpapers/p9blue-2560x1440.png +0 -0
D .local/share/wallpapers/winter-color-scheme.png => .local/share/wallpapers/winter-color-scheme.png +0 -0
A .mkshrc => .mkshrc +158 -0
@@ 0,0 1,158 @@
#!/bin/mksh
# Interactive mksh configuration
# Source login profile if not already loaded
[ -z "$EDITOR" ] && . "$HOME/.profile"

# Vi mode
set -o vi

# Prompt: user@host:dir >
PS1='$(print -n "\033[34m")${USER}$(print -n "\033[0m")@$(print -n "\033[35m")$(hostname -s)$(print -n "\033[0m"):$(print -n "\033[36m")${PWD/#$HOME/\~}$(print -n "\033[0m") > '

# History
HISTFILE="$HOME/.mksh_history"
HISTSIZE=10000

# Core utilities
alias cp='cp -iv'
alias mv='mv -iv'
alias rm='rm -vI'
alias mkd='mkdir -pv'
alias grep='grep --color=auto'
alias diff='diff --color=auto'

# Modern CLI replacements
alias ls='eza --icons --group-directories-first'
alias ll='eza -la --icons --group-directories-first'
alias la='eza -a --icons --group-directories-first'
alias lt='eza --tree --icons --group-directories-first'
alias cat='bat --paging=never'

# Shortcuts
alias ka='killall'
alias g='git'
alias e='$EDITOR'
alias v='$EDITOR'
alias p='pacman'
alias z='zathura'
alias bin='nnn ~/.local/bin'

# System
alias logout='pkill -KILL -u krisyotam'
alias lock='slock'
alias shutdown='sudo shutdown now'
alias restart='sudo reboot'

# Terminal UI
alias mutt='neomutt'
alias top='btop'
alias htop='btop'
alias vim='nvim'

# Claude Code
alias claude='claude --dangerously-skip-permissions'

# Git
alias ga='git add'
alias gc='git commit'
alias gp='git push'
alias gl='git pull'
alias gs='git status'
alias gd='git diff'
alias gco='git checkout'
alias gb='git branch'
alias glog='git log --oneline --graph'

# Sudo
alias sv='sudo nvim'
alias sp='sudo pacman'

# Edit configs
alias mkshrc='$EDITOR ~/.mkshrc'
alias nvimrc='$EDITOR ~/.config/nvim/init.lua'

# Applications
alias browser='$BROWSER &'
alias rss='sfeed_curses ~/.sfeed/feeds/*'
alias torrent='rtorrent'

# Maritime Monitoring (Monarch Suite)
alias ssta='sea-surface-temperature-anomaly'
alias ohci='ocean-heat-content-index'
alias ssm='subsea-seismic-monitor'
alias svm='supervolcano-monitor'
alias kpi='kaiju-probability-index'
alias mc='maritime-charts'

# Application launchers (backgrounded)
alias warp='warp-terminal >/dev/null 2>&1 &'
alias mouse='mouseless >/dev/null 2>&1 &'

# Fastfetch
alias ff='fastfetch'

# --- Functions ---

# nnn with cd on exit
n() {
	if [ -n "$NNNLVL" ] && [ "$NNNLVL" -ge 1 ]; then
		echo "nnn is already running"
		return
	fi
	NNN_TMPFILE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.lastd"
	export NNN_TMPFILE
	nnn -Q "$@"
	if [ -f "$NNN_TMPFILE" ]; then
		. "$NNN_TMPFILE"
		rm -f "$NNN_TMPFILE"
	fi
}

# Script editor -- pick and edit scripts in ~/.local/bin
se() {
	choice=$(find ~/.local/bin -mindepth 1 -printf '%P\n' | fzf)
	[ -n "$choice" ] && [ -f "$HOME/.local/bin/$choice" ] && $EDITOR "$HOME/.local/bin/$choice"
}

# feedsync -- sync kris.opml into sfeedrc
feedsync() {
	opml="$HOME/dev/krisyotam.com/public/kris.opml"
	if [ ! -f "$opml" ]; then
		echo "feedsync: $opml not found" >&2
		return 1
	fi
	sfeed_opml_import <"$opml" >"$HOME/.sfeed/sfeedrc"
	echo "sfeedrc updated from kris.opml"
}

# Launch Google Earth Pro (detached)
earth() {
	setsid google-earth-pro >/dev/null 2>&1 &
}

# Zoxide (smarter cd)
command -v zoxide >/dev/null 2>&1 && eval "$(zoxide init posix --hook prompt)"

# Direnv
command -v direnv >/dev/null 2>&1 && eval "$(direnv hook ksh)"

# History logging (encrypted with SQLCipher)
_kh_db="$HOME/.local/share/history/history.db"
_kh_key_file="$HOME/.local/share/history/.key"

_kh_log() {
	typeset cmd="$1" exit_code="$2" pwd_path="$PWD"
	[ -z "$cmd" ] && return
	case "$cmd" in history*) return ;; esac
	[ -f "$_kh_key_file" ] || return
	[ -f "$_kh_db" ] || return
	typeset escaped_cmd=$(print -r -- "$cmd" | sed "s/'/''/g")
	typeset escaped_pwd=$(print -r -- "$pwd_path" | sed "s/'/''/g")
	typeset key=$(cat "$_kh_key_file")
	(sqlcipher "$_kh_db" "PRAGMA key = '$key'; INSERT INTO terminal_history (command, exit_code, pwd, shell) VALUES ('$escaped_cmd', $exit_code, '$escaped_pwd', 'mksh');" &) >/dev/null 2>&1
}

# PS4 trap to capture commands for history logging
_kh_last_cmd=""
trap '_kh_last_cmd=$(fc -ln -1 2>/dev/null | sed "s/^[[:space:]]*//")' DEBUG
PROMPT_COMMAND='_kh_log "$_kh_last_cmd" "$?"'

A .profile => .profile +83 -0
@@ 0,0 1,83 @@
#!/bin/sh
# Login shell profile -- sourced by sh, mksh, and X session.
# Sets environment variables, PATH, and XDG directories.

# Default programs
export EDITOR="nvim"
export VISUAL="nvim"
export TERMINAL="st"
export TERMINAL_PROG="st"
export BROWSER="librewolf"

# XDG base directories
export XDG_CONFIG_HOME="$HOME/.config"
export XDG_DATA_HOME="$HOME/.local/share"
export XDG_CACHE_HOME="$HOME/.cache"

# PATH -- add ~/.local/bin and all subdirectories
for dir in "$HOME"/.local/bin/*/; do
	case "$PATH" in
		*"$dir"*) ;;
		*) export PATH="$PATH:$dir" ;;
	esac
done
export PATH="$HOME/.local/bin:$HOME/bin:$PATH"
export PATH="$HOME/.config/emacs/bin:$PATH"
export PLAN9="/usr/lib/plan9"
export PATH="$PATH:$PLAN9/bin"

# Cargo/Rust
export CARGO_HOME="$XDG_DATA_HOME/cargo"
[ -f "$CARGO_HOME/env" ] && . "$CARGO_HOME/env"

# XDG cleanup (keep $HOME tidy)
export XINITRC="$XDG_CONFIG_HOME/x11/xinitrc"
export NOTMUCH_CONFIG="$XDG_CONFIG_HOME/notmuch-config"
export GTK2_RC_FILES="$XDG_CONFIG_HOME/gtk-2.0/gtkrc-2.0"
export WGETRC="$XDG_CONFIG_HOME/wget/wgetrc"
export WINEPREFIX="$XDG_DATA_HOME/wineprefixes/default"
export KODI_DATA="$XDG_DATA_HOME/kodi"
export PASSWORD_STORE_DIR="$XDG_DATA_HOME/password-store"
export ANDROID_SDK_HOME="$XDG_CONFIG_HOME/android"
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 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"

# nnn file manager
export NNN_OPTS="adeHQ"
export NNN_PLUG="p:preview-tui;f:fzcd;o:fzopen;i:imgview;z:autojump"
export NNN_FIFO="/tmp/nnn.fifo"
export NNN_OPENER="$HOME/.config/nnn/plugins/nuke"
export NNN_BMS="d:~/downloads;c:~/.config;p:~/dev;h:~;w:~/content"
export NNN_TRASH=1
export NNN_PREVIEWIMGPROG="ueberzug"

# Program settings
export DICS="/usr/share/stardict/dic/"
export SUDO_ASKPASS="$(command -v dmenupass)"
export FZF_DEFAULT_OPTS="--layout=reverse --height 40%"
export LESS="R"
export LESSOPEN="| /usr/bin/highlight -O ansi %s 2>/dev/null"
export QT_QPA_PLATFORMTHEME="gtk2"
export MOZ_USE_XINPUT2="1"
export AWT_TOOLKIT="MToolkit wmname LG3D"
export _JAVA_AWT_WM_NONREPARENTING=1

# Less colors (man pages)
export LESS_TERMCAP_mb="$(printf '\033[1;31m')"
export LESS_TERMCAP_md="$(printf '\033[1;36m')"
export LESS_TERMCAP_me="$(printf '\033[0m')"
export LESS_TERMCAP_so="$(printf '\033[01;44;33m')"
export LESS_TERMCAP_se="$(printf '\033[0m')"
export LESS_TERMCAP_us="$(printf '\033[1;32m')"
export LESS_TERMCAP_ue="$(printf '\033[0m')"

# Start X on tty1 (only from a real login shell, not when sourced by xprofile)
if [ -z "$DISPLAY" ] && [ "$(tty)" = "/dev/tty1" ] && ! pgrep -x Xorg >/dev/null 2>&1; then
	exec startx "$XINITRC"
fi

M .xprofile => .xprofile +4 -1
@@ 3,12 3,15 @@
# This file runs when a DM logs you into a graphical session.
# If you use startx/xinit like a Chad, this file will also be sourced.

# Load environment variables from login profile
. "$HOME/.profile"

xrandr --dpi 128	# Set DPI. Scaled up for 1440p to match 1080p UI size.
~/.screenlayout/main.sh	# Set up monitor layout
xrdb -merge ${XDG_CONFIG_HOME:-$HOME/.config}/x11/xresources	# Load base Xresources
setbg -s			# set the background and colorscheme (sync, not background)

autostart="mpd picom dunst unclutter pipewire remapd"
autostart="mpd picom dunst unclutter pipewire"

for program in $autostart; do
	pidof -sx "$program" || "$program" &