From 72005fd71d78daad0e5598b7afde31baa5165fda Mon Sep 17 00:00:00 2001 From: zanewalker Date: Fri, 29 May 2026 00:41:12 +0000 Subject: [PATCH] (Init): Added shit --- .gitignore | 17 + CONTRIBUTING.md | 54 ++ LICENSE | 21 + README.md | 103 ++ data/nirimod.svg | 26 + flake.lock | 27 + flake.nix | 35 + install.sh | 650 +++++++++++++ media/1.png | Bin 0 -> 309550 bytes media/2.png | Bin 0 -> 296320 bytes media/multiple_configs.png | Bin 0 -> 149550 bytes nirimod/__init__.py | 1 + nirimod/__main__.py | 80 ++ nirimod/app_settings.py | 50 + nirimod/backup.py | 45 + nirimod/kdl_parser.py | 799 ++++++++++++++++ nirimod/niri_ipc.py | 209 ++++ nirimod/pages/__init__.py | 0 nirimod/pages/animations.py | 1222 ++++++++++++++++++++++++ nirimod/pages/appearance.py | 452 +++++++++ nirimod/pages/base.py | 98 ++ nirimod/pages/bindings.py | 776 +++++++++++++++ nirimod/pages/environment.py | 161 ++++ nirimod/pages/gestures.py | 200 ++++ nirimod/pages/input_page.py | 380 ++++++++ nirimod/pages/layout.py | 284 ++++++ nirimod/pages/outputs.py | 746 +++++++++++++++ nirimod/pages/raw_config.py | 322 +++++++ nirimod/pages/startup.py | 171 ++++ nirimod/pages/window_rules.py | 1014 ++++++++++++++++++++ nirimod/pages/workspaces.py | 155 +++ nirimod/profiles.py | 72 ++ nirimod/state.py | 149 +++ nirimod/theme.py | 325 +++++++ nirimod/undo.py | 61 ++ nirimod/updater.py | 135 +++ nirimod/widgets/__init__.py | 5 + nirimod/widgets/keyboard_visualizer.py | 696 ++++++++++++++ nirimod/window.py | 1135 ++++++++++++++++++++++ nirimod/window_effects.py | 299 ++++++ nirimod/xkb_helper.py | 168 ++++ package.nix | 78 ++ pyproject.toml | 34 + tests/__init__.py | 1 + tests/test_features.py | 311 ++++++ tests/test_ipc.py | 192 ++++ tests/test_kdl_parser.py | 202 ++++ tests/test_state.py | 162 ++++ tests/test_updater.py | 116 +++ tests/test_window_effects.py | 384 ++++++++ tests/test_window_rules.py | 173 ++++ uv.lock | 79 ++ 52 files changed, 12875 insertions(+) create mode 100644 .gitignore create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 data/nirimod.svg create mode 100644 flake.lock create mode 100644 flake.nix create mode 100755 install.sh create mode 100644 media/1.png create mode 100644 media/2.png create mode 100644 media/multiple_configs.png create mode 100644 nirimod/__init__.py create mode 100644 nirimod/__main__.py create mode 100644 nirimod/app_settings.py create mode 100644 nirimod/backup.py create mode 100644 nirimod/kdl_parser.py create mode 100644 nirimod/niri_ipc.py create mode 100644 nirimod/pages/__init__.py create mode 100644 nirimod/pages/animations.py create mode 100644 nirimod/pages/appearance.py create mode 100644 nirimod/pages/base.py create mode 100644 nirimod/pages/bindings.py create mode 100644 nirimod/pages/environment.py create mode 100644 nirimod/pages/gestures.py create mode 100644 nirimod/pages/input_page.py create mode 100644 nirimod/pages/layout.py create mode 100644 nirimod/pages/outputs.py create mode 100644 nirimod/pages/raw_config.py create mode 100644 nirimod/pages/startup.py create mode 100644 nirimod/pages/window_rules.py create mode 100644 nirimod/pages/workspaces.py create mode 100644 nirimod/profiles.py create mode 100644 nirimod/state.py create mode 100644 nirimod/theme.py create mode 100644 nirimod/undo.py create mode 100644 nirimod/updater.py create mode 100644 nirimod/widgets/__init__.py create mode 100644 nirimod/widgets/keyboard_visualizer.py create mode 100644 nirimod/window.py create mode 100644 nirimod/window_effects.py create mode 100644 nirimod/xkb_helper.py create mode 100644 package.nix create mode 100644 pyproject.toml create mode 100644 tests/__init__.py create mode 100644 tests/test_features.py create mode 100644 tests/test_ipc.py create mode 100644 tests/test_kdl_parser.py create mode 100644 tests/test_state.py create mode 100644 tests/test_updater.py create mode 100644 tests/test_window_effects.py create mode 100644 tests/test_window_rules.py create mode 100644 uv.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..56b18d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +# Python +__pycache__/ +*.py[cod] + +# Virtual Environment +.venv/ + +# NiriMod Temporary Files +*.kdl.bak +*.kdl.tmp + + +# Scratch / debug scripts +/test_*.py + +# Nix +result \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..5992554 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,54 @@ +# Contributing to NiriMod + +Thanks for your interest in contributing! NiriMod is a growing project and PRs are welcome. + +## Development setup + +System dependencies (Debian/Ubuntu names; adapt for your distro): + +```bash +libcairo2-dev libgirepository-2.0-dev libgtk-4-dev libadwaita-1-dev +``` + +Then: + +```bash +git clone https://github.com/srinivasr/nirimod.git +cd nirimod +uv sync +uv run nirimod +``` + +Requires Python 3.12+ and a running Niri instance for full manual testing. + +## Before submitting a PR + +Run the same checks that CI runs: + +```bash +uv run ruff check --fix . +uv run ruff format . +uv run mypy nirimod +uv run pytest +``` + +All checks must pass before your PR can be merged. + +## Code style + +- Ruff enforces linting and formatting rules. Always run with `--fix` and `format`. +- Mypy must pass clean. Don't use `assert` for type narrowing — restructure the code instead. +- Follow existing patterns for option rows, pages, and GTK widgets rather than inventing new ones. + +## Scope + +- For larger changes, open an issue first so we can discuss the approach. +- System settings that aren't managed by Niri (like Wi-Fi, Bluetooth, general theming outside of compositor scopes) are out of scope. + +## Reporting bugs + +Open a [GitHub issue](https://github.com/srinivasr/nirimod/issues) and include: + +- Niri version (`niri --version`) +- Steps to reproduce +- Relevant log output, if any diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1a84d21 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 srinivasr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..74db78c --- /dev/null +++ b/README.md @@ -0,0 +1,103 @@ +
+

NiriMod

+ + **A GTK4/libadwaita config manager for the [niri](https://github.com/niri-wm/niri) Wayland compositor.** + + [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) + [![Python 3.12+](https://img.shields.io/badge/Python-3.12%2B-blue?logo=python&logoColor=white)](https://python.org) + [![GTK4](https://img.shields.io/badge/GTK-4%20%2B%20libadwaita-4A90D9?logo=gnome&logoColor=white)](https://gtk.org) + [![Wayland](https://img.shields.io/badge/Wayland-native-orange)](https://wayland.freedesktop.org) +
+ +
+ +![NiriMod Interface](media/1.png) + +Editing Niri's configuration file by hand works perfectly fine—until you find yourself tweaking animation curves blindly, guessing the exact names of your monitors, or accidentally overlapping your keybinds. NiriMod steps in to provide a clean, native GUI for the tedious parts of configuration, while staying completely out of the way for everything else. + +--- + +## What It Does + +NiriMod manages your Niri config via a clean interface, allowing you to easily adjust settings while leaving your custom scripts and comments alone. + +- **Display Outputs:** Visually arrange your monitors using drag-and-drop. Easily adjust your resolution, refresh rate, variable refresh rate (VRR), and fractional scaling without diving into the config file. +- **Keybinds:** Manage your shortcuts through an interactive physical keyboard map that lights up bound keys, or use the searchable list view to quickly find and edit specific bindings. +- **Layout & Rules:** Take control of Niri's column layout with a full editor for window rules, column proportions, gaps, struts, and workspaces. +- **System & Input:** Adjust your mouse and touchpad settings, configure swipe gestures, change cursor themes, and manage the environment variables and startup commands Niri uses. +- **Animations:** Stop guessing cubic-bezier values. The visual easing curve editor provides live previews for all of Niri's animation slots (like window open/close or workspace switches). +- **Raw Config Editor:** Sometimes you just want to type. The built-in KDL text editor comes with undo/redo functionality and runs live validation to ensure your manual tweaks are safe. + +![Keybinding Management](media/2.png) + +--- + +## Safe, Non-Destructive Editing + +We built NiriMod to be strictly non-destructive. It is designed to never break your existing configuration: + +- **Strict Validation:** Before anything is written to disk, NiriMod runs `niri validate`. If the validation fails, nothing is saved, keeping your setup safe. +- **Atomic Writes:** Configuration files are saved using temporary files first, which prevents corruption if a save is interrupted. +- **Comment Preservation:** Your custom comments and whitespace formatting are kept completely intact. We don't overwrite your personal notes. +- **Profile Management:** Easily save and switch between full configuration snapshots (like a "work" profile and a "gaming" profile) with a single click. + +### Third-Party Shells & Multi-File Configs + +![Multi-File Configurations](media/multiple_configs.png) + +NiriMod natively supports advanced, multi-file setups. This includes custom visual layers and desktop shells like **Dank Material Shell (DMS)** and **Noctalia**. + +If you like to split your configuration using `include` directives, NiriMod handles that transparently. It can parse included files up to 5 levels deep. When you make a change in the user interface, NiriMod is smart enough to track which file that specific setting came from, and it saves the change back to its exact origin. + +Because NiriMod only touches the standard Niri settings it understands, your custom shell configurations, advanced scripts, and unrecognized blocks are perfectly preserved just the way you left them. + +--- + +## Installation + +### AUR (Arch Linux) + +```bash +yay -S nirimod-git +``` + +### Script (Other Distros) + +```bash +curl -sSL https://raw.githubusercontent.com/srinivasr/nirimod/main/install.sh | bash +``` + +*(You can use `--install` to skip the prompts, `--uninstall` to remove the application, or `--skip-deps` if you prefer to handle dependencies manually).* + +--- + +## Requirements + +NiriMod works out of the box on Arch, Fedora, openSUSE, and Debian/Ubuntu. You will need: +- Python 3.12+ and `uv` (the install script handles `uv` for you) +- GTK4, libadwaita, PyGObject, and Pycairo +- The niri Wayland compositor + +**Gentoo Users** (requires the [GURU overlay](https://wiki.gentoo.org/wiki/Project:GURU) for `niri`): +```bash +emerge dev-vcs/git net-misc/curl dev-lang/python gui-libs/gtk gui-libs/libadwaita dev-python/pygobject dev-python/pycairo x11-libs/libxkbcommon x11-misc/xkeyboard-config +curl -sSL https://raw.githubusercontent.com/srinivasr/nirimod/main/install.sh | bash -s -- --install --skip-deps +``` + +--- + +## Contributing + +Contributions are always welcome. If you would like to help out, please check the [CONTRIBUTING.md](CONTRIBUTING.md) file for setup instructions. If you are planning a major change, please open an issue first so we can discuss it. + + + + + + Star History Chart + + + +--- + +*NiriMod is an independent project and is not affiliated with the official niri team.* diff --git a/data/nirimod.svg b/data/nirimod.svg new file mode 100644 index 0000000..1330bf5 --- /dev/null +++ b/data/nirimod.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..dfdfdf9 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1776548001, + "narHash": "sha256-ZSK0NL4a1BwVbbTBoSnWgbJy9HeZFXLYQizjb2DPF24=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b12141ef619e0a9c1c84dc8c684040326f27cdcc", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..9dfb41b --- /dev/null +++ b/flake.nix @@ -0,0 +1,35 @@ +{ + description = "A polished GTK4/libadwaita GUI configurator for the niri Wayland compositor"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + }; + + outputs = + { self, nixpkgs }: + let + supportedSystems = [ + "x86_64-linux" + "aarch64-linux" + ]; + forAllSystems = nixpkgs.lib.genAttrs supportedSystems; + in + { + packages = forAllSystems (system: let + pkgs = nixpkgs.legacyPackages.${system}; + in { + default = pkgs.callPackage ./package.nix { }; + }); + + overlays.default = final: prev: { + nirimod = final.callPackage ./package.nix { }; + }; + + apps = forAllSystems (system: { + default = { + type = "app"; + program = "${self.packages.${system}.default}/bin/nirimod"; + }; + }); + }; +} diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..666c204 --- /dev/null +++ b/install.sh @@ -0,0 +1,650 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Constants & Paths +INSTALLER_VERSION="1.0.0" +INSTALL_DIR="$HOME/.local/share/nirimod" +BIN_DIR="$HOME/.local/bin" +DESKTOP_FILE_DIR="$HOME/.local/share/applications" +ICON_DIR="$HOME/.local/share/icons/hicolor/scalable/apps" +REPO_URL="https://github.com/srinivasr/nirimod" + +DISTRO="" +DISTRO_PRETTY="" +DISTRO_LIKE="" +PM="" +IMAGE_BUILT_OS=0 + +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +BOLD='\033[1m' +NC='\033[0m' + +# Helpers +info() { echo -e "${BLUE} ➜ ${NC}$*"; } +success() { echo -e "${GREEN} ✓ ${NC}$*"; } +warn() { echo -e "${YELLOW} ⚠ ${NC}$*"; } +error() { echo -e "${RED} ✗ ${NC}$*" >&2; } +step() { echo -e "\n${BOLD}${CYAN}══ $* ══${NC}"; } + +pause() { + echo -e "\n${BLUE}Press any key to continue...${NC}" + read -n 1 -s -r < /dev/tty || true +} + +ask() { + # ask → returns 0 for yes, 1 for no + local prompt="$1" default="${2:-y}" + local yn_hint + [[ "$default" == "y" ]] && yn_hint="[Y/n]" || yn_hint="[y/N]" + read -p "$(echo -e "${YELLOW} ? ${NC}${prompt} ${yn_hint}: ")" reply < /dev/tty || true + reply="${reply:-$default}" + [[ "$reply" =~ ^[Yy]$ ]] +} + +print_banner() { + clear + echo -e "${BLUE}${BOLD}NiriMod Installer v${INSTALLER_VERSION}${NC}" + echo -e "${CYAN}GUI Configuration Manager for the Niri Wayland Compositor${NC}\n" +} + +# OS Detection +detect_distro() { + DISTRO="" + DISTRO_PRETTY="" + DISTRO_LIKE="" + PM="" # detected package manager + IMAGE_BUILT_OS=0 + + if [ -f /etc/os-release ]; then + # shellcheck source=/dev/null + . /etc/os-release + DISTRO="${ID:-}" + DISTRO_PRETTY="${PRETTY_NAME:-$ID}" + DISTRO_LIKE="${ID_LIKE:-}" + fi + + detect_image_built_os + + # Normalize distro id using ID_LIKE fallback + case "$DISTRO" in + arch|manjaro|endeavouros|garuda|artix|parabola) + PM="pacman" ;; + fedora|rhel|centos|rocky|almalinux) + PM="dnf" ;; + opensuse*|sles) + PM="zypper" ;; + ubuntu|debian|linuxmint|pop|elementary|zorin|kali|mx|mxlinux) + PM="apt" ;; + gentoo) + PM="emerge" ;; + *) + # Try ID_LIKE + if [[ "$DISTRO_LIKE" == *"arch"* ]]; then PM="pacman" + elif [[ "$DISTRO_LIKE" == *"fedora"* ]] || [[ "$DISTRO_LIKE" == *"rhel"* ]]; then PM="dnf" + elif [[ "$DISTRO_LIKE" == *"suse"* ]]; then PM="zypper" + elif [[ "$DISTRO_LIKE" == *"debian"* ]] || [[ "$DISTRO_LIKE" == *"ubuntu"* ]]; then PM="apt" + elif [[ "$DISTRO_LIKE" == *"gentoo"* ]]; then PM="emerge" + fi + ;; + esac + + # Verify the detected package manager actually exists. On image-built Fedora, + # keep the Fedora package family even if dnf is absent; dependency checks use rpm + # and missing packages are reported without attempting a dnf install. + if [ -n "$PM" ] && [ "$IMAGE_BUILT_OS" -ne 1 ] && ! command -v "$PM" &>/dev/null; then + PM="" + fi + + # Last resort: probe which package manager is installed + if [ -z "$PM" ]; then + if command -v pacman &>/dev/null; then PM="pacman" + elif command -v dnf &>/dev/null; then PM="dnf" + elif command -v zypper &>/dev/null; then PM="zypper" + elif command -v apt-get &>/dev/null; then PM="apt" + elif command -v emerge &>/dev/null; then PM="emerge" + fi + fi + + if [ -z "$PM" ]; then + error "Could not detect a supported package manager." + error "Supported: pacman (Arch), dnf (Fedora/RHEL), zypper (openSUSE), apt (Debian/Ubuntu), emerge (Gentoo)" + error "If you are on an unsupported distro, re-run with --skip-deps and install dependencies manually." + exit 1 + fi + + info "Detected: ${DISTRO_PRETTY} (package manager: ${PM})" + if [ "$IMAGE_BUILT_OS" -eq 1 ]; then + info "Detected image-built/atomic OS; system dependencies must come from the image." + fi +} + +# Package Installation +install_pkgs() { + local pkgs=("$@") + info "Installing: ${pkgs[*]}" + case "$PM" in + pacman) sudo pacman -S --needed --noconfirm "${pkgs[@]}" ;; + dnf) sudo dnf install -y "${pkgs[@]}" ;; + zypper) sudo zypper install -y "${pkgs[@]}" ;; + apt) sudo apt-get update -qq && sudo apt-get install -y "${pkgs[@]}" ;; + emerge) + echo "" + echo -e " ${YELLOW}⚠ Gentoo:${NC} packages compile from source and may take a few minutes." + echo -e " The cairo USE flag will be set for dev-python/pygobject (needed for the keyboard view)." + echo "" + if ask "Proceed with emerge?" y; then + local use_file="/etc/portage/package.use/nirimod" + if ! grep -q "dev-python/pygobject" "$use_file" 2>/dev/null; then + echo "dev-python/pygobject cairo" | sudo tee -a "$use_file" > /dev/null + fi + sudo emerge --newuse --ask=n "${pkgs[@]}" || { + error "emerge failed. Try running manually:" + for pkg in "${pkgs[@]}"; do + echo -e " ${CYAN}sudo emerge $pkg${NC}" + done + exit 1 + } + else + warn "Install these manually then re-run: bash install.sh --install --skip-deps" + for pkg in "${pkgs[@]}"; do + echo -e " ${CYAN}sudo emerge $pkg${NC}" + done + exit 1 + fi + ;; + esac +} + +pkg_installed() { + # Returns 0 if the package is installed, 1 otherwise + local pkg="$1" + case "$PM" in + pacman) pacman -Qi "$pkg" &>/dev/null ;; + dnf) rpm -q "$pkg" &>/dev/null || rpm -q --whatprovides "$pkg" &>/dev/null ;; + zypper) rpm -q "$pkg" &>/dev/null || rpm -q --whatprovides "$pkg" &>/dev/null ;; + apt) dpkg-query -W -f='${Status}' "$pkg" 2>/dev/null | grep -q "install ok installed" ;; + emerge) + if command -v qlist &>/dev/null; then + qlist -I "$pkg" &>/dev/null + elif command -v equery &>/dev/null; then + equery -q list "$pkg" &>/dev/null + else + return 1 + fi + ;; + esac +} + +cmd_exists() { command -v "$1" &>/dev/null; } + +detect_image_built_os() { + IMAGE_BUILT_OS=0 + if [ -e /run/ostree-booted ]; then + IMAGE_BUILT_OS=1 + fi +} + +needs_uv_preload_cleanup() { + [[ "${LD_PRELOAD:-}" == *"libhardened_malloc.so"* ]] || [[ "${LD_PRELOAD:-}" == *"libno_rlimit_as.so"* ]] +} + +filtered_ld_preload() { + local entry + local kept=() + for entry in ${LD_PRELOAD//:/ }; do + case "$entry" in + *libhardened_malloc.so*|*libno_rlimit_as.so*) ;; + *) kept+=("$entry") ;; + esac + done + printf '%s' "${kept[*]}" +} + +run_with_filtered_preload() { + if needs_uv_preload_cleanup; then + local preload + preload="$(filtered_ld_preload)" + if [ -n "$preload" ]; then + LD_PRELOAD="$preload" "$@" + else + env -u LD_PRELOAD "$@" + fi + return + fi + "$@" +} + +run_uv() { + run_with_filtered_preload uv "$@" +} + +resolve_deps() { + MISSING=() + + # Baseline tools + if ! cmd_exists git; then + case "$PM" in + pacman) MISSING+=("git") ;; + dnf) MISSING+=("git") ;; + zypper) MISSING+=("git") ;; + apt) MISSING+=("git") ;; + emerge) MISSING+=("dev-vcs/git") ;; + esac + fi + + + if ! cmd_exists curl; then + case "$PM" in + pacman) MISSING+=("curl") ;; + dnf) MISSING+=("curl") ;; + zypper) MISSING+=("curl") ;; + apt) MISSING+=("curl") ;; + emerge) MISSING+=("net-misc/curl") ;; + esac + fi + + if ! cmd_exists python3; then + case "$PM" in + pacman) MISSING+=("python") ;; + dnf) MISSING+=("python3") ;; + zypper) MISSING+=("python3") ;; + apt) MISSING+=("python3") ;; + emerge) MISSING+=("dev-lang/python") ;; + esac + fi + + # GTK4 + case "$PM" in + pacman) + pkg_installed gtk4 || MISSING+=("gtk4") ;; + dnf) + pkg_installed gtk4 || MISSING+=("gtk4") ;; + zypper) + pkg_installed libgtk-4-1 || MISSING+=("libgtk-4-1") ;; + apt) + pkg_installed libgtk-4-1 || MISSING+=("libgtk-4-1") ;; + emerge) + pkg_installed gui-libs/gtk || MISSING+=("gui-libs/gtk") ;; + esac + + # libadwaita + case "$PM" in + pacman) + pkg_installed libadwaita || MISSING+=("libadwaita") ;; + dnf) + pkg_installed libadwaita || MISSING+=("libadwaita") ;; + zypper) + pkg_installed libadwaita-1-0 || MISSING+=("libadwaita-1-0") ;; + apt) + pkg_installed libadwaita-1-0 || MISSING+=("libadwaita-1-0") ;; + emerge) + pkg_installed gui-libs/libadwaita || MISSING+=("gui-libs/libadwaita") ;; + esac + + # PyGObject / GObject Introspection + case "$PM" in + pacman) + pkg_installed python-gobject || MISSING+=("python-gobject") ;; + dnf) + pkg_installed python3-gobject || \ + pkg_installed python3-gobject-base || \ + MISSING+=("python3-gobject") ;; + zypper) + pkg_installed python3-gobject || MISSING+=("python3-gobject") ;; + apt) + pkg_installed python3-gi || MISSING+=("python3-gi") + pkg_installed python3-gi-cairo || MISSING+=("python3-gi-cairo") + ;; + emerge) + pkg_installed dev-python/pygobject || MISSING+=("dev-python/pygobject") + pkg_installed dev-python/pycairo || MISSING+=("dev-python/pycairo") + pkg_installed x11-libs/libxkbcommon || MISSING+=("x11-libs/libxkbcommon") + pkg_installed x11-misc/xkeyboard-config || MISSING+=("x11-misc/xkeyboard-config") + ;; + esac + + # GObject typelibs (needed at runtime for gi.require_version) + case "$PM" in + dnf) + pkg_installed gtk4 || MISSING+=("gtk4") + pkg_installed libadwaita || MISSING+=("libadwaita") + ;; + zypper) + pkg_installed typelib-1_0-Gtk-4_0 || MISSING+=("typelib-1_0-Gtk-4_0") + pkg_installed typelib-1_0-Adw-1 || MISSING+=("typelib-1_0-Adw-1") + ;; + apt) + pkg_installed gir1.2-gtk-4.0 || MISSING+=("gir1.2-gtk-4.0") + pkg_installed gir1.2-adw-1 || MISSING+=("gir1.2-adw-1") + ;; + esac + + # Deduplicate + if [ ${#MISSING[@]} -gt 0 ]; then + # Remove duplicate entries + mapfile -t MISSING < <(printf '%s\n' "${MISSING[@]}" | sort -u) + fi +} + +# Full Dependency Check +check_dependencies() { + step "Checking System Dependencies" + detect_image_built_os + + if [ "${SKIP_DEPS:-0}" -eq 1 ]; then + warn "Skipping system package manager checks (--skip-deps)." + warn "Please ensure git, curl, python3, gtk4, libadwaita, and pygobject are installed manually." + else + detect_distro + resolve_deps + + if [ ${#MISSING[@]} -gt 0 ]; then + warn "The following packages are missing:" + for pkg in "${MISSING[@]}"; do + echo -e " ${RED}•${NC} $pkg" + done + echo "" + if [ "${IMAGE_BUILT_OS:-0}" -eq 1 ]; then + error "This looks like an image-built/atomic system, so the installer will not run sudo ${PM} install." + error "Add the missing packages to your image recipe or base image, rebuild, then re-run this installer." + warn "If these dependencies are provided outside the system package database, re-run with --skip-deps." + exit 1 + fi + if ask "Install missing packages via sudo?"; then + install_pkgs "${MISSING[@]}" + success "System packages installed." + else + error "Cannot proceed without required system packages." + exit 1 + fi + else + if [ "${PM:-}" = "emerge" ]; then + success "All system packages are already installed." + echo -e " ${YELLOW}Note:${NC} If the keyboard view is blank, you may need to rebuild pygobject with the cairo USE flag:" + echo -e " ${CYAN}echo 'dev-python/pygobject cairo' | sudo tee -a /etc/portage/package.use/nirimod && sudo emerge --newuse dev-python/pygobject dev-python/pycairo${NC}" + echo "" + else + success "All system packages are already installed." + fi + fi + fi + + # Niri compositor check (optional warning) + if ! cmd_exists niri; then + warn "The 'niri' compositor was not found on PATH." + warn "NiriMod requires niri to be running. Install it separately if needed." + warn " Arch: sudo pacman -S niri" + warn " Fedora: sudo dnf install niri" + warn " Gentoo: sudo emerge gui-wm/niri" + echo "" + fi + + # uv + step "Checking uv (Python Environment Manager)" + if ! cmd_exists uv; then + warn "'uv' is not installed. It is required to manage NiriMod's Python environment." + if ask "Install 'uv' via the official installer (astral.sh)?"; then + info "Downloading and running the uv installer..." + run_with_filtered_preload bash -c 'set -euo pipefail; curl -LsSf https://astral.sh/uv/install.sh | sh' + # Make cargo/uv available in current session + export PATH="$HOME/.local/bin:$HOME/.cargo/bin:$PATH" + if [ -f "$HOME/.cargo/env" ]; then + # shellcheck source=/dev/null + source "$HOME/.cargo/env" + fi + if ! cmd_exists uv; then + error "'uv' was installed but is not on PATH. Please restart your shell and re-run this installer." + error "Or run: export PATH=\"\$HOME/.local/bin:\$HOME/.cargo/bin:\$PATH\"" + exit 1 + fi + success "'uv' installed successfully: $(run_uv --version)" + else + error "Cannot proceed without 'uv'." + exit 1 + fi + else + success "'uv' is available: $(run_uv --version)" + fi +} + +# Download / Update Source +download_source() { + step "Fetching Source Code" + if [ -d "$INSTALL_DIR/.git" ]; then + info "Updating existing installation at $INSTALL_DIR ..." + git -C "$INSTALL_DIR" fetch --quiet origin main && \ + git -C "$INSTALL_DIR" reset --hard origin/main --quiet \ + || warn "Could not fetch latest changes (maybe no network). Continuing with existing source." + else + info "Cloning repository to $INSTALL_DIR ..." + git clone "$REPO_URL" "$INSTALL_DIR" + fi + success "Source code is ready." +} + +# Build & Wire Up +install_app() { + step "Setting Up Python Environment" + cd "$INSTALL_DIR" + + info "Creating virtual environment with system site-packages..." + rm -rf .venv # Ensure clean state + run_uv venv --system-site-packages --python python3 + run_uv sync --no-dev + + # Verification check + if ! run_uv run python -c "import gi" &>/dev/null; then + warn "Virtual environment installed, but 'gi' (PyGObject) is still not found." + warn "This typically happens if the system bindings are missing or Python version mismatch exists." + + # Try to diagnose + local host_python_ver + host_python_ver=$(python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')") + info "Host Python: $host_python_ver" + + if ! python3 -c "import gi" &>/dev/null; then + error "PyGObject is NOT installed on your host system." + error "Please install it via your package manager first (e.g., python3-gi or python-gobject)." + exit 1 + else + warn "PyGObject is available on host but NOT in the venv. This is unexpected." + warn "Attempting a fallback venv creation..." + rm -rf .venv + run_uv venv --system-site-packages + run_uv sync --no-dev + fi + fi + success "Python environment ready and verified." + + # Launcher script + step "Creating Launcher" + mkdir -p "$BIN_DIR" + + # Generate launcher script + cat > "$BIN_DIR/nirimod" << EOF +#!/usr/bin/env bash +# NiriMod launcher — auto-generated by install.sh +INSTALL_DIR="${INSTALL_DIR}" +if [ ! -d "\$INSTALL_DIR" ]; then + echo "NiriMod is not installed at \$INSTALL_DIR. Please re-run the installer." >&2 + exit 1 +fi +export PATH="\$HOME/.local/bin:\$HOME/.cargo/bin:\$PATH" +export PYTHONPATH="\$INSTALL_DIR" +cd "\$INSTALL_DIR" +$(declare -f needs_uv_preload_cleanup) +$(declare -f filtered_ld_preload) +$(declare -f run_with_filtered_preload) +run_with_filtered_preload uv run python3 -m nirimod "\$@" +EOF + chmod +x "$BIN_DIR/nirimod" + success "Launcher created: $BIN_DIR/nirimod" + + # Desktop entry + step "Installing Desktop Entry" + mkdir -p "$DESKTOP_FILE_DIR" + mkdir -p "$ICON_DIR" + + # Copy icon if it exists in the repo + if [ -f "$INSTALL_DIR/data/nirimod.svg" ]; then + cp "$INSTALL_DIR/data/nirimod.svg" "$ICON_DIR/nirimod.svg" + ICON_NAME="nirimod" + elif [ -f "$INSTALL_DIR/data/nirimod.png" ]; then + cp "$INSTALL_DIR/data/nirimod.png" "$HOME/.local/share/icons/hicolor/256x256/apps/nirimod.png" + ICON_NAME="nirimod" + else + ICON_NAME="preferences-system" + fi + + cat > "$DESKTOP_FILE_DIR/io.github.nirimod.desktop" << EOF +[Desktop Entry] +Version=1.0 +Name=NiriMod +GenericName=Compositor Settings +Comment=GUI Configuration Manager for the Niri Wayland Compositor +Exec=${BIN_DIR}/nirimod +Icon=${ICON_NAME} +Terminal=false +Type=Application +Categories=Utility;Settings;DesktopSettings; +Keywords=compositor;windowmanager;wayland;niri;settings;config; +StartupNotify=true +StartupWMClass=nirimod +EOF + + # Refresh desktop database if available + if cmd_exists update-desktop-database; then + update-desktop-database "$DESKTOP_FILE_DIR" 2>/dev/null || true + fi + if cmd_exists gtk-update-icon-cache; then + gtk-update-icon-cache -f -t "$HOME/.local/share/icons/hicolor" 2>/dev/null || true + fi + success "Desktop entry installed." + + if [[ ":$PATH:" != *":$BIN_DIR:"* ]]; then + echo "" + warn "$BIN_DIR isn't in your PATH." + if ask "Add it to your shell profile automatically?"; then + for rc in "$HOME/.bashrc" "$HOME/.zshrc"; do + if [ -f "$rc" ]; then + if ! grep -q 'export PATH=.*\.local/bin' "$rc"; then + echo -e '\n# nirimod' >> "$rc" + echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$rc" + success "Patched $rc" + fi + fi + done + else + warn "You can run it directly: ~/.local/bin/nirimod" + fi + fi + + echo "" + success "${BOLD}NiriMod ${INSTALLER_VERSION} installed successfully!${NC}" + info "Launch from your app menu, or run: ${CYAN}~/.local/bin/nirimod${NC}" +} + +# Uninstall +uninstall() { + step "Uninstalling NiriMod" + warn "This will remove:" + echo " • $INSTALL_DIR" + echo " • $BIN_DIR/nirimod" + echo " • $DESKTOP_FILE_DIR/io.github.nirimod.desktop" + echo "" + + if ! ask "Are you sure you want to uninstall NiriMod?"; then + info "Uninstall cancelled." + return + fi + + rm -rf "$INSTALL_DIR" + rm -f "$BIN_DIR/nirimod" + rm -f "$DESKTOP_FILE_DIR/io.github.nirimod.desktop" + rm -f "$ICON_DIR/nirimod.svg" + + if cmd_exists update-desktop-database; then + update-desktop-database "$DESKTOP_FILE_DIR" 2>/dev/null || true + fi + + success "NiriMod has been uninstalled." + pause + exit 0 +} + +# Menu +main_menu() { + while true; do + print_banner + echo -e " Please select an option:\n" + echo -e " ${GREEN}1${NC}) Install / Update NiriMod" + echo -e " ${GREEN}2${NC}) Uninstall NiriMod" + echo -e " ${GREEN}q${NC}) Quit" + echo "" + read -p "$(echo -e " ${BOLD}Enter your choice:${NC} ")" choice < /dev/tty || true + + case "$choice" in + 1) + print_banner + check_dependencies + download_source + install_app + pause + exit 0 + ;; + 2) + print_banner + uninstall + ;; + q|Q) + echo -e "\n${BLUE} Goodbye!${NC}\n" + exit 0 + ;; + *) + error "Invalid option. Please choose 1, 2, or q." + sleep 1 + ;; + esac + done +} + +# Entry Point +# Flags: +# --install Download from GitHub and install (non-interactive) +# --uninstall Remove NiriMod (non-interactive) +# --skip-deps Skip system package manager checks (useful for Gentoo/unsupported distros) + +MODE="" +SKIP_DEPS=0 + +for arg in "$@"; do + case "$arg" in + --install) MODE="install" ;; + --uninstall) MODE="uninstall" ;; + --skip-deps) SKIP_DEPS=1 ;; + *) + error "Unknown option: $arg" + echo "Usage: $0 [--install | --uninstall] [--skip-deps]" + exit 1 + ;; + esac +done + +if [ "$MODE" = "install" ]; then + print_banner + check_dependencies + download_source + install_app + exit 0 +elif [ "$MODE" = "uninstall" ]; then + print_banner + uninstall + exit 0 +else + main_menu +fi diff --git a/media/1.png b/media/1.png new file mode 100644 index 0000000000000000000000000000000000000000..044f5a3202b95251cf3f68a0823f9b471bbaca11 GIT binary patch literal 309550 zcmcG0bwE^I`|St_q5=vp2CbBUbV&@MA`Gb_ozmSQIUp*a2-1>+bdPj{gmey_gGhHb zGj}7t-~D~}{(CQf$Z%%noPGA$`+3&0)_M$lt|(1(mEtM{0wIFQJbej)oWI1ExPlLU zmE=nz>ZP%R9viPrZ;BA&pu6SR@xIUzKG(mri-q>c{xEoP z3v#=vXs5ees)-p~^MCx%r9Zm-KmG(So2W=3m;UQefFuJ1=f95J@RNby{nrsX{7}f1 z|2iUZ{r;sJ|8>OY&Qlz^|2hKUZe?GawR^-Ml2(_>yniFQXp#i?;uF&k`QJcazEFFZ zHt7FzVTbVIsE?yxW9QeRGk*1{U_u5{qI>%vSA*?9lr`;*r;r z%9NLNby_FuBp08K?+{IN&&qsIX5c;*uzvf+pDBF>?6}JohMBrZM(@qV@S z_gNSa5c>Q*sCmOpfR6Cp#a|K&_x^pvk4)cp4}DT3rH%RfNeOBCf8Uc}lbQW{rb@Pd z7nhHt=57uIg@5PbREt#qSz~5TJa~`)bBDsD|6cot5a+SVzf03e^xqRfo>I5@{T)xs zf3E3MtaJHGkl4lXq$>Ms7q5IW?H*ChI0*z->>YW|?763j^v{Z|FuLv*sVn=7|6OD^ z$SF7-U!2GK)h>hwi&CAz@QWUbEc;c?%jLwQdyaSn>*_>BmbMPbSx~w zX_~%|Ltd$<$T>TgI4OP0*-Oa!=Z*${U3V7O-)HqykqkphI>B^=bROGlG){l_4v%eq zF7o);-Ev#TRRV|ZVhA^wsL$dO6FJ)2SWq;I8RM1k4`9@CQc_Z7nO9`OXf8h0%}8;r zKbXeG^=+|#<1ap3ze$@ia&*qh_D3JZfAnrrorESi7aN;281vl3G}*-& zl5#4v70J++w%dAic~>$+((D`apI(;u`zBFfAYoWcj5RCdnX;y4CHVuVSPP#?X(Maz zi?jQvC$+(0u(lT=Tju;-bPR!TL8qIX&Tsmis_N$>fJmE~Ba%6%p}I$9z}ZT<^ChZ@VL7 zVqRay7jdDo2K$JQ?@elHsp`dGAy3s_zBKS>#Euq|CiN_khh#_!ll{ByCS{PiHM711 zV)VnhB1-Q2tD~#?WXy`KMLlBlO5$e`;0JFq9p*5nsLWKtx0uvzs9^jS}Pr&qeLI3r>3WuR#>U1M0%c#V_A@OVrcEUqj{~_D)bqr z+uoqs92$G}ddY&Xbw^4J@ zU5DMpn=#_>+Bc#!7b~EEU0fXfkxZMp@4NGgs@uV&Yg&={3K~4KCHcNPz1lAw?ynkW zK?3Mfo_!9B)^-00KLY~}K0Vv$;n!L(XrYN->d%PlKpb`A78aJ z#rxs0UeQuq5yNemPX2(3Ek_M$voAbg3qR31+C#!eS20kJ{V(sYiC<}d=erL0})}S1wyP9<5hxM5yGbf`}lIdq>Q(e8PRjdcMi3&igD6H$+qD&G%N}5qG&n zIL1xLZ96qSPov1B;~n8=T>mN09iq_^%M7RVhK72Fy}{wH9h3sO(LX=kCWJJ7wDnpM zpAAQxrefXg?F*`Ry2pq1t^8iSdi8bL&V54Eb)6iQB25y`a9D&m(|#60!zg~Xq}1gJ z6{tO4&Z&~Z(HC7@{gHGQ4<4nx+T|Mwa%_Q9-Y09Am20;ieo=@M0P}LZV*91Ky7}FU z&lzjuW$4O8X0PL2ft}{hl($`Qrr!~gfuK`AQRlib<#4$9%LMr(PrKq}6sO+QD&}~y zZlm@@!T8en{@QqBF!!^^WzmiPB)rjjo?DD7CATi(V}KGNVFH3C!+z}exKc3(M+S#Z zb8isotup1YLA_#RXCK$Wp;I}4M_Ph2&D$f&{>y#4jroimB4{%)GUE{Y;xrC@nympj zjkV1GtXc5_0`YmXH|6JMCEL+}g|#KfBAq!Li5O^{5ht9Q@r9(sp`;gz@F-RH+Kb)rR~k z=IZY34BP1uM>AOE>(z10^2A=}H|bPoVHGwajcst7T3)uelx%#w8&l|Uu>QSPjewZy zi(yM}+*O}gAF6!km7yax2#vUR_0PFyL3eKQT(TSaep9jy{%7AOt*EG~mfr2TIvh$b zomym`$rm4=3?lRrx~?uTfePx*H_IbTSEYmyd#S5CW%7dP^APRSq?WE%ntFhK?rWR@6_SnKG|P8 zhkaLEz!vLJtKGK6th5AE^D;Y$vxhC>n0t#Z3NFV#Ilb>KE#2Lo`Na8woNLg>aDfrBEYYzU zp6{e>Vi;_0bYR)zc+Wj7oXi-++1D!l{nqlC!F1N6<@SCtn%)zdE6xltO%0cD@nv4T zup6woN&g`Z+tIQYbK zEH>>)beM}&i~ag*zDuiNIeX5*Sr;cs+2_{kWL3|pxb2iPkJoXKK=iP2snw`SIxY5) z8FQor-3x-(md2jUal+XxhjPQwXX^)DHne;X>PCMrKY-_XC)t$$`j9k!_3BlH6Z*6~ zKdrFP(ATU})%#uz9N~4CJwmt$I-Sq(-~^5JeW+15aNIbhuSsKxbN@Wd^x=jf z;b(D}mAaG3joHEuj!;g|Uyj?OJz{jX^*q1T$tKbidv1834>-qBn1ssH?T)juvtjsI znNVm>G_IB!W;?o$XQw!<=<3AA%6J)4bhr1(kRxZo{=rbkPEVZ~^&=hfU8+#gI`^YF zcq_P6COk%Dqq<`PQ-}31NnlbG?O6@+-mLd8^ger5q<82qe)__sJDw5Jt5SRTlQU6K zfb8fO3B1?hJl&5S|E9&ZY7d=|P(6Bn1G;aDiu&E6B=h8nUxjB6^q|#LY)1oYeIB?G z*wdTgr^Dq|Z(y;6gukGIH-b^9mpjBYMnlCgmDjXM%7tn8hD`1Ys!n6-2 zX*@UeX2&cS_^WgXb_CK=PHU!`yJ_g31zoRXXJ&306JIstuw0prVqj!!AIMVf@=g>h zQp(f=$)I3%IlyC&F|Z2 zr@1&{VYzae=Z%9+iojp9VpGe%?gr1hdU(3S*|s2dAas|V33V} z|G2@ND7l!v9(&q@#bdlAw%fZPKUar1TQ$YVny{(nM%>nYquY>Hr>xV%9N@*sm{w?u z_I5l<{>1T7cJusK)VC-8>gfJW%Facx#ZdasZC;v3e4DoNSY0cBlH2dA>ufk}YxV>x zrr%zZKUGACFfzjMiK+B|UPpcbo0QM&2;}}Ect&7(Ru;?9P6Y!e=P(1S1>@sCTl)q! zzI*fKZ&o%o`TC$A3_se!Il0~o@U18Lkq&-)B6ZUl=hgm58p!aq-;_E)$ z<;#AvMF=k$5Zv_IM#~RppofR&0 zSyH{OhGQ|eqzT~I6ZC=FE$tGENOQs5Krf1*VX|6^E2oFQBez4~r;QJHkl14t<*esR zt*7GHqmY+6I`oL+fefRehpdetwT(DTxh(W<8i>gMqqxHn3y*K?f;&_(ak3f3m-@&e-Yc2No zf@z?vp~nYs_{b|{Ey&qjdwE)A?O4pl!E94tvxVFkO}|+02>^-K)UE7M^?n3#%Wq?E zWa2*4bzhQNneJwT^lDtaMsN~tuj{$xwskb7Sl-^*Ss3h$)f=hL$xkK}CS!_c?n{C_ z(JHkH?Vfe|fMD1Ih%V+`jX$mTh-aefguOqxZTTposm$}p;V1-qcn}cAU$wjg?Vq{5 z^_XDKd$&)TNh~TM!P>y;I6;*1{rk&>*5fWhE~{V31#_;hh{bM}xo+t8V+2`P>YesS zDjfYQtPeMv@qQE*@)X%pd~C)mp$SNUVXhjMFd~D_+9j zX;c41PCfxuxbjV5adEwi1Tg;cW!RYzpJ`5V@`O|WqCBzmA$KW2dtbjM&EpFt5Z@KF z$z_Rs&Ade|`lhw%(wgs&Ur_i0-k1#J>8F><{l<+S_O_2#cIK9IkfA-E^Ss+*mPk$C zN+?PtQg-(y8-H^kzGBkgRKLEuBQgz;5 zXVC|1GWJgLi9bMj%Y!*@6YHcy66fK0VnzD(Ck``BgvupLi5~04^Zcz~mo~^&U-B_S zMJ<+wh+`h*o36~q3>{Ii29&+_JJYx$UBTpJP9L(k~bXxMi zIVl~k$^S*nu=%>9juxpUPEz92)=n#{@EX&esV}~6)J<^+^hj-aax$uEYc+c)LoxDj z{6+|+;1mO7+0i^wGOk&0?Gn>5Me$41gUrG|Kvd#jsLGYLVm{WAfuh*1v1+51ErA7f zV?19+MB!V&HO}hZCW3#*h+a~oOYjAe;e~;Lq4y%#x%64t**wgKbvp?gv2MDysd|gg zkk#8EG8+asF0oFTzA%2nW_hymc<9M}ERSXZQv@LyD8yE1lM_xeq8=XoxOzwRYlmTT z5P!WJbTm%|Uj^WK@gt=r!kM{_=<~9{O2|>aPt!qb+BzZBZWC!fRACP1W9su#6111yT5wZB2{&2rr*MNoR=d^`d3F^ zAwz;&;Us$pspiRO%-Kn5ZLO|PzJc1^v&}}5yp7}*ynN2;@7(!AQ)h^^ae8EH*2&jc zr#IV11r>?W(Wbg_E;I#eQ#B&9UbqA$X7Rm>80E34^8EZQTlw(pJvUT8uY9DWii!%^ zD;>?>@xlfd>{I-;`=CG26Y5Wkag7o4sx<#i zxs>Uw<>i(4G=Iw(z#hwOTkO7VSbV%yyOm;`z}oJLh(UIT+0U=(#d(2iO@Y%7b z5DZA&d{4{~&ubbSsD+18{Sm8G?6mYUP=2B55JV?+%zjy2TeX{D>sRiSxlekhVXIR$ za>8+?v>1Q_)pq=a44WUqEh~<87Rv7YLo)GZcYTs=QQ)j`wJ*iLBDc-Q*f@iMpT7(4 z(US;`h3alh)d1?3F3Rkaj7L%vk>CWKZSB#sB4ZQ^HM`xhaEt`B$MJ3&?}@r5k?@ys zFBkUyT?p&*7|kKy@QjOYNB6D?*_8o)?l zp*NdJ5D8Nu=Vf_=_RU}PMpz6kDJLJ{*#;c0Xb|Zl{$0zn*!c92a2vqMk&kStu`AbZ zb9_&iN~iwLgk7@z-puQb*+INd7|AHON;l@DXWA5Sa|rX?Hb&TaOrzwI4d>c6xAmA) zcy2TTv4JL;C@?hrbdZ&ox1~oMgl0J#FC??w>&Zz^XUeQWp1IzYIe`D+9wf$DSy_$y z(-lZ_C`0g+01ex99wd0qsV5G0&ASNPWtGoo>sz0eeGvT!LQB( z7J~b2(U>!W^8kC=u|j(s!J_Z$io~t9jCsZ+Z8=t-BhU~PH>qV@=-rpP=3sa zf9dxV9xu25or{~u3wxs}#ToGf_iojs_5;C*O+u_O)ZAmOWao6)b#>%sram?07PwWYneppXjN$gO+K;s$7A_d75sP9(C%ZA}XTz5rCL3WJr z#U;3!-0_M#gY`CQi-yb`_e*OCSTZC%i&@x<>EX0|* z>VZLQz^;n$~#dr3?0X1~E*ji<6ir9SfkW`22T|0~@vvg}qKp8UUtY z?Vklx-D~_n6m91`M5o6Jxo<@&XcLiv@YYMNTOLiK08PY^qt8RW!~_`_)T6@`kqD6OtNy|ZP(Auo*4 z*jvx-@B>+ZBfvgw3IpswN00YDncLwnxZp5A+nj#@HKl+R7XkNeZLXhnwkm3B%xKI$ z{BWbna#)d9i9q-I9j@nzp4%{u@6%p)q3*fb4sDG05K40O<2Kb>OyPK$evekes|6;@ zPz&f{^OQaH=ol~26aI5XXw4fF&iv^t+O#W{eP>?B)&1QN4M-GN-jK8tmoXE^vty#L zxHwDd+|N86D{V6gA|iDteji7z7cWAET-YDnVNla?jy%O2)bX}d{$hRbAOe8R`s;5% zepG5}k7UE^`&K9EYb~vnye7AH$v^h=;A{hn6kk#z%Nua5JJH#Rd*rnEoY22T8QsS2 zW6yDp*h*-Nb(!SvaE^{@pva4_PWxQKJq`2#1pvSmTeqTzul5135-sVs&B)HKl3%s% zZV7j(*(-~-SnJW9)>CAoVkOGon5gJ?;(Y-ISCXqyB)hx<<*}c6svL7cCO3(H?tf24 z(AwF#TXr@$TL<{Eli!Z+iESTuV;)l~W;CL$i`mCsrxrc-d@6h+R1dR#o5yv1g5xfA zE@0dg&H<?Nj6$(t2%Iy-4XIdW^V^t`}3V0JiI9+ayj1CVyy zx=fDGZ02|c*%RHJO6c>e_oLw-Lg8@B@SKx93CCK+;=MWNVjpdZjusetsE251X|YL2 zYu0*ZUBAoIH0JH3z^0vdXjRtpBKF3}t+SJ3P*;ChUA3~*Ln2~umb|T|e?QbJeYL%_ z19+DwFO|a;s+G(m&5347XhhX7Q25I3BhS^50#YIh>7ptL=cx38$|y5IUvMAlU``bV z>(c!k`3b)#&+sn|BjL}vgNELXzhm}^%C;kgIO963 zv*X(QH)O+AgPbq)oK|?pu294FE!X6u3%m%hlm|hI(~8Ofg}V1N)v78!AKOj6A(@i#5CGw`TpTlS{fR!OQS1k1&vytTk3H%;-QohMPIM=SX=Dh z(cC*aT0oo=?Hx&ymxs^}$^Vd33!F5CGb@o^pcnyYbn@VCie%3{XBV6#rtPJQ?9yz= zvX2$@yNOt!lYC{-KCVuXqIY_IoATkJ{X8!F4)s6hU%fJ{tOPX-(;A3W>*ltefIvPM zqcHtS;%vAC#C*ffkUzCB*t#EKVFl(YHEuik(dVQ-Lf>op$EB5H9TSMQE05#+!y{0X zJ?u*&^g$mFHKIm~aV1?`f}NNYG_x}wL>Gn5weIOnX;qgF8uRiNDd`D^w=P_1U%Hks z?P?OUNd}?Zc+x=k=T0PYTYGwkw}uNMj1I-*#;#6 zhCiyNL_JzGoC<~ zAelqFOovXlen(FZ!=YpMxzJB4eUp=)I1KBQb$A_2GLwjIYQW^=cy~&=J}CO~v21d} zkBUx@dO~8N)+a+t3kHYQ3KVm=EkxWh`WdMe5Gz*U*gy9T@iFTYCj$Ad5&+29|1{wEPsyi&yVCL|F8%r z;;$6ryap7vQ|j_EYdGJ9YyhFFS=2B&|=8?VdaO5dyoj~pPtN8 zPJ3b7mlKIijye4+$I|hIWYmA$8GKqJg;d3SGTGKkHM?~E;ydpo$KSmXWefvSX<#7C zL7;jHKPxkH5%q)a;(fdPJ_ZS7+1SSo#*ZD&E?JIZ2({(qE33r7g9aueb0edlyzh)Ze_?AN zt{pykuSxnp((S#xiHvakEBtr4xVa^@^WS~xuqdfJcJEm_8Tcy#`{ZXto;W#xrAd*5 zLBHflB3?Zgm@hTZgh*GC{byh>Z_CABK()VT0dbZ1 zU!C;dLrrx54&vV<|33{R0srwU{JomN7p;G<3z_-SF&Fg?Px1YqBQv+9YyN$Uj)R}? zP1Azqg+pbA{D0pBoeg+ae>NDMt`LCe|MRDb3JA>-*TTX`8HI$-vkC+fz>@LTi}6D! zd6LkFg@xfKB*0cNLs^t2Bli~hNFZy!fFI#sNjgA!O%dW$#X@t1u67A_1<@mI_h+a#l*8y-vm7fZ3_X2eUf)Qu zu}o(r5ma|9Mu&>`A3<&qH68xB=2rfshUeVe91diwb4~F^NQUmkP}Bg$ox%A&dz<;5 z?X_CyX;Y01DefgYO}@U0Z@$ETN`9Zixj*sw&lmpubHnlfmEGt6ep)yF_sm~h@c-xX znT@h(_+=;a`0?9vZ4P_kHaWZ-G>9H%A|fJ_?Kh$qE4xxLm0L`Q1`@FKXA$&z>m))l zC2K(thsnzFMCbkXbo_2R3HbENW@{;f2>; zZ?p7$Iy(;f=0EZ1$LJyo??+S9Q?M2ah?f&)_F@C3muAHsVUQ&2&*NA98`%^yM3@oJ@ZVV6 zla-hghXlm;441QSz427F<9dPW@6Wn$eMk_<$;;C<6VO@wy}cV195Bd0s7F?oIjVPB zg!&G{gDZ6IPJn)_P(=7#JQ3>pwV`%+7Py+z6$8&d$KGYgkwTP}mCxwkUP_{0gb^qR zC@L!6`t#lmud)5If*Axv!XI4e{E)=BF!T}^3kxh>kr{l!=>c;1^)o_CyDtLw{(R%9 zn!$Z;F$i_YoeR#%dL;}`0;kZYUtnP1#oQ)Khm_Rlf&kOqnhTl1&zP#G!ZdR zz$7nzx$$JT2-UW-Co8%%fG1HlZj4#*AW14(+<)d8_2)biPB(tz_KyCUGP)_?OObu{ z?8Du~wVq!WrD5SQN2lrvJ z`}4NmLo%kI=+#v!tS7Qe(q(Oo9SA~S0A(ByqRa62!ey!4wVyaDTR(1nE;8^mReX2o zsS6LXT^lR;yHdG7&x+Hzn2Ah(_<+y*GwiDzBpw(vv|T4l!oGYNSrq`t1QhtZ{qJvg zN1e;1EG#TH|K8eU%kC1d(Nwi%!^bV?R#P}QV-n?E0jqNPL{SYMUf$W+HUkYn*9bW+ zen~QBVaek0*nim8L1~mAv)kI8AYy#9ZTzbGGGvpG3>Jt(=Tbho4u;^Qt~~O@ z?3%m$t{%q@b%YEfGjkj&T^Cv0F{q};7_H+{fpwRXdT%veI!L8&K|4P&q0RE}Ve#8{ zir6)P{xhjWT;w6~Ii5q!qvo3Lq&2xEc&nf^I9%rg_ZbQMKk%mmUY9GL4pA+;kPwWN zEPSr>wTs*VQKD_tayHv6O0K8r5Y$ITpq$QYK0J3akp9N)HeUl2>@{YE^5u1#sx_CT z$ttx^Wwhenj{%>rv1D=i@@0p$l41O=elkO#S2>!91kY0qk^EK=oP2n8yhjv^tn&hz zQYjeD;Si`KK=8TML`(hS>({Sz1SB-1wjN~PdaVZsUb!AEX#O$X7^dS)pA%JWaCfdF zP)c@$G13OKkj2}Nf}#kJC2@Ilzw}{BO3{EB(mThwGS=34bl!|iOfW3wZ1#sQu9dp) z_rp_W3sSO4lZAJ|vgeaA6T_6|CQ1W;n8gk2y0@qec!^rTix|%rHXokbX4sm`nkuQN zdiw65fe<$vvIRsIukBX)kQ={0IW`^I`~F^4#r0R z5WYxApLPh1P*)f>LiMHgcl}G}X2AeM;Tt|+(FrWsD?a?mWN`n|b7_pO>!kC1;qW-! zd6j9@5ygHl8tT5Ac?!7Ua3!y0vAg^h5zfyiv^Z)H4cu1p%2I2bQbd9KV`b}^EK(QR z6;S{2qr+&GE5h@1tHtCWhun%^A1G6k==6Xfgm$Xpw6d_s4x$xTB&HR+f3D(G0%7ad zyuJqd;KytaTmD!2Cm*gy&2^}0N`6Sgq2r^zmuH;L%fpk0?Uy%JRluBYbRWm}s_w|F ztb!S#NZ_=RRd26 z&pSLuGU^>f)WWY+^E4TC+VZ<8);$+DLUJO<0a$6`R-nVV5f|S*GNus{i1&vx3$3-- zn)%7jgdOEG+uiL~Y6GIr22-!oulGfBH3w7Hs_a};m6AiVjez9I^|8yN5`JZb6LC%) z29mXOw1(2p%|+`8NWz}_Gcf`mlFCr7#_+>Oj|`gZ$ndm_Ossnsve@+<9Cv^`x!IwI zvp}kF+R?UTetFnKef%dMZ+3BhzG8d3V$8>DLD}bF(vHKff@&zjjP;x4V-4WCnguHV zOKnf>_Kpr1-l~2$Q^H2bme*!IfohPgWlkUo#fjT|OvcPeAwGZ@&Em#Oq&_ zJVs_C9UwJN2UCj}ZB92NxlwpbR5)hDv(0xWSdzxX9iOWwYh$q{JD)x&X(|W8Jc)~e zFv<2zZciMnS&dxA8<(y;#nB)5Of52WiX>zOR;%kPVxT-L^gQCJm<^KySnwy+9oz9z zh5KnedA{}3A};M(wl&t8KS%huGE-hIbjHxb!B)o8F+JKQH^J$RPy%5#4UY94f<;}= z%FX3s<}GfJ%C)P~86v!AI#JTl8?GeGBTO?a$E?8hnfX|wVsgD)hx3f)cqWsiJh5C! zMkZi<4|Ue}Ms^~2c<&`hkM>o%!afoiZ<5hZ&T?n$YdpnltHO*cdC$&JUXzE~oP-~t zO}LX8!#)}Z8c0@bT13RFwoduzw{P#g)YN?FPeNNW?VSvwfi|Ba$H(7ayZzpo z_VZSrdVx0B2c!m`3lIa(N4L!lic6s+(g?Ads%oOmVCr#&m;0A*%NLY(1g0migE*ni z-9rDich}Vx=yU_zX2j)xy&93=klpw4B0cTSEgh?Ll~* zWPk{WJwv-(CID_KGYodxkFg79a4h+0j``f|?4c6RI1dkx(eeO`s=oafp*ur;vz4bU zv`7n=$1tTN^T@`AhR2SZ`6(eGG*FYbal#a%Lr6V%#o4}=(bf#(xehyN8fIi_+Sb8| zeX_rSwvFo3uLm@I?vFh>vZf&cCW;Xt^Oray<_X2!8&nWl!|bJv4;U zE-t0=aRLf}_L2_^WxBm|lHV4spw#qkCvn1gI004V%ISDiy~FesHvVpr2Qat4;ko`a z?!BkTm3;aDXKItK*n6BcyC1PNy|*5?bDaSbP<^F!`gKZyfnt%tn@yF$!j<`1@$odk ze#8d^L4L$iD80V|YUyx`%xI>`emg@PI*%n@_7L+U!p2&?$LZU?{EN5tf|X zh~vZ$?Hf;#=3LpJ8$Lck7S;AhKe73PIi|H$baafFJ}aAfnr=>qsy>|ed8HD0P4alL z$j~#Efz&)m2{0kFes^fO#SA zhQ$F#!^;WcKajb%B%TzPhlfJT&x|cf1_;T73}b6j_tPZx(E*-LP2wd5l?y;iksD%yg=Y-Gpn zg6{H;;f(-j_TXHgTgi_zeQRjl*4bJ7HnL0$X&O+0ZJ~u*B_6!J#uRh2-?za_X$Xm? zt8!V}M=SZgi4(9cd>i$1zEDBSe{rv{5GA0u0N{W*PVmZ5UKx#L(eCn~R(_p#BKaZp zjpF!H%=tP~xbb5Av)S}ZbWxm5tvCi4;hqere?<+r=bw*%Mj~=d?{MUuVCtT_id}r%gmjuEuS|0jtk#*m81zSf<~7K|v^znK?GT z?yxqt$CTs@fI{qaG=4VUgNfJ*N6zSX@17o=p!K*?+^B85j))?Ng%HjNO)xL+56iO@zdik|rXx+ZJ=?nhOl!H+QtOK2B;l!06abbmyzbHnoG z%jCTS!M;}##om#_)C-oix&7 z^urkTTsMF)U|U*^Q58L2Ovw{VXEGB(6G<#d_Z8HST8`h?0Wc)e5gK96&J4+{` z6wuBuH?S!>(p(zIXA&}dUb{EW-CZphJCGj&jP&>81Z~4~s$7oX!lO{Q zwW@hGSxA*SEh#DgPQxY4d9moT_%RSvdYdRb3G2NtVPRIpw;H}lGQ{D>k3Att0_awV ztSMH=u@bBs1;zMB=ET{hw&;7(Av8pqx_)YBCkI8uPHF^~>jyyIiIw=B`6A`CUXofR zhoD-R=g}ra7T3|)nP#bvK4a7pwO~zgXLV36-0N7gZ0-8h>)C@j!|E$9EG{F8KKBP6JOX8j~( zL$816fn3zXP#_n_N@ObdT?R@O9sv$o+zWx-j&8ZUC@erW_BU}`OXrPurt{sj*;^hY zW${npj`n_;?k%4P1OI?V=_-A= z&uHYXSFD)V2iW4!+AHN)Dr7hlt5Slnf@;1tOOC1+RiEP{Mfed%_2%RLtI#hl^C*~B zqh<13oNet*9`2XsC%d2u?5&P^zS=^;l~iZGSL<;=vlGKlTnwIhUoz~p5}g7&0+fRZ zT_AB&|D%?vnv>M((+DRf>NlZZzZ!7>8U7P%>sl(V2cX*C&YO=&5-gM7M)3Jb?(Te+ zs;I!tGdvcX-=3=RkhiBV)&o$&;)liNbbb2!CZH|m;r6(WRfo_}0U$c5J%l@#eyK>t zjBE2~L63{T$6X>3A>JAk6vwyZ$yT00AZ8nTGc(&3-Rwf+K25r;|5Cbm`ASWCy+lU8 z@%&1C3I1b#^)z}dT&=(nR<=0We@3mJ0^Gv(jgRQf=;O0Xz{>rOpVVW#bZy?N9GG5= zR)(yZ^xc7|1eYV%@<4~10X@l0>#j~qaWQX7%gOGNC1zOPTA3!K1<&x>HG-psC0E(; zuZstgSM0xtKoyIVJWB zdx5p4{YE<*G6MLD3p5%wMp3CH9h`{%?{%2tl`dP@Bfd~At%4QXR?vjOzPIlMiTdEr~s|1{JE^i3?~U1@Fc_@1_`2>EE)8T)O6Fx0CuX_uaPc6FHxhW_t=lVr3;FYQCvVT!7sBZFkitK&UY4|_+9%ObbJ>Z|b zGj6;e0!jg^0c*=*?Hbheb(wcpjrhAQPxRGsUsLcU2w2A+rBDgl1i77!IXsbG7^TlR zj~>W0{mB^TViH9y)^I)Le$U!cYv6-rnJi1rK@Z_dbL z4BUGEEC_j%Tdavxp{YOI`P)dKRqQ+O`pdWZs-P1BKNOY%A1nMQ)mkqt$yHVG0%a3p zY_Z)FeanL=v$RKfQ)8N-tx9i2>bA~9(BAZ_*V8)2qm428L&E888L|{-k#bX|6SAK1 zCu9^QI$q^%aNn!fuE}rDRBe>%Jbhx$Q&vhq?5|2jA?#%K+{46654h^G1H!OYV=kIx zg8YPl#g0$N&9y4pFe1?%FuX%OlG##PiOy(o(0rlJR%*$J0ixF1k<MwHfcTE1@|ixW zS~sNn%;gP%NN8qG4!`7MuiBmNIDOgZl~#3;D;3t`!AZE^(w&;JP=$+t+A4~gG#)dh z68G+;eRbSvDn|dSP%GVRrKdX;_6&gCLIwtg*aHa?oR$z;Q!jkMHemNiCHHv{atK|z zDm#rOf%Ah8cG2q51;}Q`Fk)5Sp4ivg_oS z4Ziayo8(nosP67w3B#EvL*6$!fj)g^=t+@LwO+X*AEacc2g-#)fE%C1&Lhn`*P1D9 z>6(XO0b4hJKUn~UtxPLA>exL*d`opaab@q_yZH=81CBZ$V#} z_lKj{RYun)tDq_#gN^TMVQDAG%`MBPc7LXDj|n=S>KBcTZqj&0&dbX zkOFt!)iKNp;Q|0ZK)7;N@!HsR>~DWJ);?k*WZNHQtNAOee)W6-5Rx^Y9Atqq;Pw8^ zwU0kEx76S}&gd8B&a=tM_xmoX3d2Xfzc#@f@2&XZFMb9kX$3xR8 z;uVH}fvzKg=nyI)R)Fw}_t~3cy`(19rm9?#B_V~4uYL@BO(sG;;to>E%hd&Jr;OIb zRb;BcSW>XtmCpBhP2>d;S*RX$G6=!-J9KKgZtvl4)|b36M+B|P6*-Wk3te6A|3!r zO0D+{xEM)yu*p)N6w=yd5VyI*Aem0ZOMp-7H0w-FHQF)mweUG6$e}OTgQ(*wSKdRt zNC%`T`>-B7L3F3HXkMR(v~sKRWL=~S{}9pp*MBfRwU>nrVuzi)3llig?XC=0cfG~G?j?pSS>H<^%vJ>CR44(> zn;*scbdLhM=Zd_Gi#lCWQs4RfQ8b?VHNOMZkNM98;zY&y`-GcT<|0xGT%Z^|_myYi zmm7DO7jsyit{WFoNYPU}%I-5 zWRE$JdE?13kW5fLns}4!;^_jjp;33dkg63gbhfav#sl~=It65umMtznfquL5k*Rx> z&_@%dRHoNOi|k|&B}lw7Rcs!9-s*=cexAg{w%pb>HYV)&ctVUNpZU8#i7kdg>~!;q za(QwMAE8IXyPd~V=^KrJ>M>{S$Og1-8t2MW)E=t>zWX%4c%;0kC!Myp8H#vjLt<7z7V8{m^Vryvm|h z6+t48QFhNQ0^XDGhZ(qCyLVK`HdtBP8DCb?a-H)8-NZDIq!atQcb}wzW{e?BZ`gMl zxo`|0?73bDJ0oLTEWUb3zaC&hO!xibP>;?DkF%5D%AO2dIwv~>Q~c$1N`BR@M2=6l z*sr=P%>=Hyf=K}_T3t57k~YASOqd;z=l6w=I6OM~c5yBgB7MM%_So>kiXm#zE^)eA znwr^r-Xtaa)C6rS$T}NV#b?_izXE36`W~2&LIxds&U9quIy!GZ6XftZ+2>b&@bf2g z*9SS=M+*q?w$4v{5+l9S+@tLjT(R7SA9B?TCW5Y%EM0+8m!uNFW6g7Sr&kvH4AWJb zfvMY1)@s@Eyv2u0BM+EF`F3_Cv`D@?2x5s-8oVI`Ks8a-7q$#bRSHoWu@?0#8B=c1q%FvE6X`T0NR$=>%;a{8SM zde7pZ8PJbvXliX zb~EDbF%8q^u_&j1bpz$ke$VjdJZ}Mtpkmxi**Z0MpBjUo?cew!z-Y*qASYMmQsIG_YCyL#t6)n0@G<5=qkA7gfo;5C+U0j z@})(>u18ND^{@pGc+y`ikqNgQ+;oO8<0$JRK;oNbw;LH73uvi^$5_XfV@C|(0(pab zMrBMS7CD*<+t!+wpOw{AvZLC0ztJeeX@&im(2R`yN=*YJ8=!GA_NiN3;*H^^R(2WOE2~9jsj_dhnLRc$y+LRf)B$lB1y8pK|bidD#ZPIqY zFbU+UR%u!3CTzRF$!_v-1mRf`~l=-p;apN6Riti(Cmo)T-kOCV}|zfLG|7f6B3x%SFQX~pd+XKp_Z~T8=!}|a4q<1 z0gHEiN5g`@8Sp1@#tmLpQ178j5$^H%xVDjE2vtW>=WM>21*w#;vXBAJW>7krztwh} z*B-KB_>Ov!2pR@KwXoZ<6VoGVrwa1{JwAz`*;7H)&a`kZjf#y~F`kQ(iO9#;)Knv6 zF8sW$h_?47FmRVvgp{%f*-a-AUR`QdB$?W+z?DlyYLzMC6IY{N@eTMS+H4kERhk&A z(CRUO-X!Xs>R}zho~u`>xZsdjA*jBDxN@`O(e@mvf^gVcc20f-Sb6;s9m9V7)Hi`O zMXrP|hdu1zsh<-C9*uz2J9BKZZ;NpUgr@Eaf zID40$Qc(7O{o;51M`rKA9_UypoH1CL+wR~jF@UBh+*hX)Y0emo02;~_uDe3!9mr_j@_UD$&Y~%g->N#0>Ojs6ZMWu0vYLSERGEJn+S@TK`?1(Vm4mXikG>Q+z3MQ- zmTTOR#U-qz>$fdS>=jyz2wWaeH+?&CspPB!yXlI(iIa7cyddO3u#)B>RSbS!fH}bZW+BQ zn^b0{L?fO8XZn;BqG(RNd$jQCc6THtj;_|>Mj-w&=BP()4kQ!-@Q3amw{xvcF@Lz0 z;1Ecb{3}$Sr;|`VXduW{1Fc~2Y9=w?N(#E9Y|4E!*N|@VdCg{noQVd}=2E~DqIq)< z{4QM*DxKVvQa0A?T-y4VaB+_`f;EaCLmTGPm4F3lG2$QyPR1WghHmT;lxJr@K40dL zz7+ewR0feFNw(21cz4(-T-}zlGUOYc=?5ukmGgbx0-f$~Vp$x9=G)M7zVh47Xryc` zs!8L_<4U5M32W{m?0fpItpKp1M2#I;q>Vq<%-$Z-btf%knKW@1-AfOXPKqjZjg`N} zk~fqE|1Bg0RhYY@pxfQrdPO*Na`3TNv#ipGvZrOr-$)^j4(>8qyS!yeC<4?$S$1}_ zu*Ot%jotKtWVni!rXpL%{;E(HTt^9IktU^cds0{6ED;wt4mV-aC_`uHP+!wS>-y}I zSI2Srf!?v3v=(*uBYvDkq{A%Tb$}!h-C^#cHz|HS_kS_>mSIt@-{1GB2%>@t7A*<` zihy*Npybe}hO}p4V293k8 z3l$DWZG1=LTl>5?M zPKQ(O)1i8jTAgIFoy)KpNdGZXJSJZ5Sez>hDUd+-nNBdwvP@g?J}q6y(jaJBxSA!f zl=b2*Ahj4r(E+o}yfj+ME` zBlVDFE?!p6?!X3#&&kdQU1>>%2vXz8-o^sf^J`I6^&kbqgg}@w+1fsO!Z#S4eC-%o zz6?-QnkDdfs`_3!lw?%x_P4sTsFdcG0*m!s<_b!%U{9w*cXK zKfn3Iipz2osBOM`>b}2%2ATWka0I4ejxzj8PHLcchGX%kU`^eRPxQMkNkcm@f43r| z-m@B43|Hk)*a!DBYoEq94k(6? z+P7K(;h-~~xE#C1Kb^a{wKSjydnNOG40sMrP@$yZsrXd&b#10qhE?y$H*NG`NK}sS zjcXLFXTba>&9G}mdknSBcxxwKZlm5T1+0_G4E6JtPX;9IUy|CbNdnoxgV=OX7>U z1*gxHpSgpZjtCKnd+vC@?pVt^%Fr-POGx6548j=vGe}Wh1_n{U8MI#-pZq~}u1jZV z-*9fS2@5Sl%u8(9MScHe*rmb+@&gRm9Znbf+@z|k`uggP1bay)!Ji6YtphL{(^7{Y zZJIqj6eJ=&4G&niZTvQT;vRW0?B%qBjEeo&-LY{_AEE>7%+Le4- z$?B6@;dnp(fsZOCQ{^d?cNk&)$$_51)?LQF>(w*B7ShjIOMuJ=YCoi2M9B@TfZAXJ zi^{C4ib{#HazuP90f9-*_s#ikQK;COFjZ+=ThwK#70vY==0XL^p{>MWj!9`%$H-(( zy>5X`POoE)8FPW#jw0qs)|oxnD!0#Id)FTL@w%6^3BN+?0cj!{eik}wC?cICL67z$ zO`U{8ohu|f_7ReVeVwW!^qFaCG4-;CfnbDqLL?JOXj-}1uZ4>A$UmJuQ6oWBmHp*# zOCpg=dFH!AA5S>qT(QwYj}e$?BuRuk-{Z&4<4SrVo`JS1S2aHjs`Xe-9K5`L2f(>y z6VO*tSEujpP2~JC_wv{GH+Ut{z{?rh9(OC#(9#j-qF>d5JU?tcj`YEkWS&qe|MBa4 zpLmabDoT^k%^8szuG_y2WdC40JIc7`QX~3H6TXd8ps(r@TpB2hCSl8n&+(|Vc@BP< zSQ>`H0Ta)6N{SuIL(q6D5@IRLTb8+|JBHVNNIjOh45SjtNpmTNoJ-KX)`o>4B!TZ) zoNB%^YtlVt=50MfnKn{Z!?!M$V`^RJUqYfDF+DBDX8YuukDu|A*T_rImL0rb_%2sv z`m)a65LP@@JnHUeoFU!G?B%mL?ZD<5NK9ULwWSO%wH!F@syZF&{56B zWj8G3@*$el^hsDgp0>=)I#g_h&hLo^dZjz1%Q>&<( zHR~%KtJ-er`tUU}x8!ym^2q|GPS6uQmzAAOkRuOPKLzk(*d?{eE(1V-P4Xo~*(j{> zZ6F8V=Y^zCTzQscP-t=Kqa995brX+Zk2aHh{8W#9T}sC)Pr*3bOvhtoJhT~6VyRmq z-!tp3&v985mP0+x0;N43pcl&CpMnlc8~FF7ji8ZqMSz*~KiGaEw-KOjQHcZD~9nB(%gL?;u|Wn48Z?D~!6ssObo=N7n7OG-AwBCZ~2vVZym z^|weURilfUR5jC0I^Hup6bw#O#{`;Z!X7^C=rF!;9jkX3t1J;&U*57oE#Mz@SgKt_ z2v_skPiK`}`X~V^B9uxE2v~|HQu9@zud2UdvW%b8G0;Q@7>*Ey)W@;)p3$v$)6@YbtY8h5#nx>|_{+PL@nujbwsj|4U*tZRp&7Dnk3jRO?WgzXD8I#!p%T6<@$sh9 zyoKgxL%&UR(KKL#WTfZ*#*2))9$(LlG8b#?@)&~LTnl22e$MQY$%->ydP<5S=t)e% zn9m3`Vt0G>3IelD&CNWAH94iT6rs?D!XZ%f+xR4xc%QQmQF1;_)w|b2G@tV3!g`8A zCLO~0)xE{PZ_W2u>q>L~=E+UiGm)&ZV=|d;V*;l=9(hdzCCML5mG%66cq8 zY~Sg)mkM}SWI4p@WlF?c3*`q=r6jGW!HC@y)ZTkiW;?wSjZi=is3BN#Ea?GsuwnC6?@8wKd9YX(OE8?pzGbIDM7hFb$ODx)Zd%-l@@8M5F$-mh+)z2A7 z6C6rfj&-aDo&290RY5q%g&q=Q=H)phfBYc-PqHo%V*X+f9gTYe(VvsE^;5g+c_1qA zlJK10o100c7A3hF?CIAuzI|x*l|m>NpCWXI8Zh7$vto>xKh9L039DkHi@;B1%#Y(i(~ z!S(B}3tp@0>QcjQCdAfMYXtTuZ>rm^&jdb>d$P5ddu+)TDm!t!yROHvvV7ZRnQQ#{ zSf!0iZmW@@p@bXQS6V=Ca|>Lq?2Ns`ldJ48rFH9bb;g>%osoyX&G#3f!SCyl1kj%* ztjE}Lj8s>P8+%!-mU^#$$pJYZ#691a+6Z1v1CG=G03^j?DJ|$gC3^AM6wc*4lhh4d zwm*eo2T$k%kD(ha(J*d#`qoFdbgBvp)W8wSgWiu6?j_3Ga3~>D94o9)O>1AN&9okW z^W9RqQnkmW%_94%F;MjF32gl6j@3FOkT?C6Uw@UhWxGyT1UI#`Kxq zP4BT8`^&d*E;}))O*P|Lxm}ivOv0Xe#Jp_r!_r_MWCLFE9gyaO!ype0V5ip8pYHZo z4m(RiDa9UAX74WGD~7rwY&jkIQbw*)NGd2OTzO_y^w;mOb_`*LhqYVmFC~83=g*3W z`b1Es`_Wo2JS4r<%XJ?_X+%UsGP6ZUp?!B=!H4xKcFV)L^Y0BO$O;*#?PC2JKJjFI z*_q`ntl>rx_`z8Zhu5i#_(c94}j)b>I1OCA;ulO@GRlisahb4&~zj zm4ESC|N2!F65#><{{Csz)!GQhOS(3%ps85zZqG!}aB{)_`X+=o;q3Y@NcF>!_zwgG zP=FKt0q!J3Li33S$G@%qEr5h*qdN9SWeD(EzJHL`I zn6fJJBWX^}^Z)mUL?Bq+{P(wlYwbU6M`J#%+2Num@9^9|feQPTPO@Hb*-*8hz*x^n z-2eK&6YleL(|Hud(;8A!4PmCk-F|3>Y! z8D!g*48Sp1?W1zcO+UipqqyA(l3#q9sZ}(SEYoIMDU}C^Yw)6t>~!5tI=rv7Ou3+iuCGlcS0A( zs@}1)vp2msvu{}cwmU2)h8}EHL%idN!Xehe(^pPmXL4)3@O7lb0}EZk}D!r=Fkw z=7(-cf>u-OlE<}@D^iH%zT7f^kZCE!Za&ZjqeV0b-Fq!7+S+7D*iA#=S&sMl8WyGq zK8Qle>*N4=gVtx~eb|J~X}y~Y2Rn#7Tu{U1K|9!#nge1e>;hA{uxtV^EqKT;xLTsF zqSHQIV~C1xl$DYSd-?KoxR`PNdn|mZ#%(*c(NxmYvsO|Nc3iozooQ3PotK*%3cDu> zh3*f=tt&%Cjr`(ZC3oNXMdT1)J6>Jw-rOV+4gB9@URVCaWY7>z85-Ux z;cOkzbbF88|3iDe-5ylEoaomCOYQr>j{ukTYzsg^(?5THIGlnhlHEHZ7j$oOrMi&6 z%`~L!1V_FR-D;#O4u%I>YU*xRMklyO?XaDN?2elRdk1^kQpXcTncw)GVOiakCFlM) zkykcmT$z=%TGdymr^f^7y5!}Hb56tCLSU}I?#DY77^oI2F~cR&Ik~wf*W`ItAHhG@ zr0XnU0>49ChK*eG2F9b3G`UO!cSAZ#u!fkH2#i3;4;XCR=$0Zr1z3*}OCG*Zx$t$Y z9uOWMwq`46<#07?fuAJ=bb+x(0EaLm8h(hSS8U98qetoFL9&kON#Ie!{N~#;C_y60Nhxc65&?cI$K7Pru#O(|c7K zO_+x9MY{2lGaa*rR?AwkXsdJA)2J?5#a+#sAjtQ`N>*U8fkS315!+>Y~x>C`5q0gH=G z87Q(tmCcO`q+Ft9&Xk$r6Y2M|(UP*gK9AEQC&Bu*`F>YX*>R92dZ=}w5^^b={M6FE zzVk0RQEg;Go-a3D-C`PhbG+g{W?Y*yx3G{C5>E#js`v)C^P{i8R65?za2z9~9K{r7 z-C#mJT%PdquFzIfv&dmJf0)oQux-CS8d&K62+pP-^^l;KC*$)>X23#oMb@!lR-X3~!aGBH63wu7nS!H#KB=PyP@N5`7K zbKakn(90a3D2U0Lpxx)oZT5zbiufjaRv7y?_T??B_~3zve=BKPX+Hy*bFZXgim2jlk8BKX-uhkz{^YnsJ-7TssJi4Kah@~3rPQR;+Cd{) zK~sf^6qqr9;6}BoqSlrms9wExZP#XCs~VnEE+r*Oxus@10)j+jzU`)9P$6G=zV#p0 zEi28#2N6C#4I><8@(jeYGcypxQe}MkP!G{LuK@Aod&u1l1b38uDhhyd*TjwLq81n9 zl0nR*8sFl&H8*^v_+HvrWm!fB=X`0#L@In>WFoHKz`l`RYoFZ`)?`&r_8(4lUJ*_I z?=%N9hO|wg20?zx!~NSoue^ItZx+&Q5Ki-T=Bl1(La)j|(_(^kcK$P;%|VFREXOv( z#gguVgnki%=WlHWs;qs)QJBj0n5?=n3eqFZVtss z=$Y8t+lMb@&mO;i9jpc0c*L#ou79`+P@;Zi7C+G~O8n#3dh<^a$(}oO)LHrFsC>Dt z8yrZvT~hwf$K?#mK>O?H&sAeq3Mwovu21UCKm&tLPHomg<}y6d{{H8oCMDNpfF-hG z(GW!MT?mdwtNS62tqa&qrkSk_r;5w1zYkIwB{l2Ox3>=ikb`RBRxkT%Zu%xH{Li}h zbuOXAinLl@r$`!C1}`j_iF9VK1Su(@5B%Q5J&A@L8Pk%%qJ@y-ytia6df>+IsrN25 z?Ro*ojYki)aH)75yR?4;_jZ#%2;a_`VHzeagtuiEj};ucm`NKM)ghx>X9|aJnCnV! zID547LQWwqBJu+Cv^Lgg)g~)if!F)IR(m9-Ygs**k2UW-u>$q~ekKSb209siEAS`n zIgxs_QVD@%_w7^K7~`E2C9`;Sdv3j2uQ!}XpufPpD`&QrP^t@`TdZh=eOG!8h>qgU zEB0|>WpLL3zsYHsRV?`7cU7YpJRRo8jkK`EkS+&}#15eDOX)lAxknTUt1`N9w$i zB>62-e|Ra`{H!XOVq-NtM})#P*3u!_w)O7cw~GGYh>YYHNC;Z1plx6NMm^$1M@+ua`z~ zVx#S4N_Ylub(n@Q)w1LAPFdBk%V#Ma}r(xf1?}MCe*Z4?13uN_~H&FkNszn$Jdb(g_hCE5h_jn zhyBMKU+dU3&vv1IUbA^6XTJ1ZsG#qjOB{QjV%QM$B~Z8HkXdF7TKNSTl18s^XIgEi zh=v3ZnBkH}M!p)4bNj5uDmB*DaIuLj>f47y!Fh)_``qSp9SKMco9U+R&mQ~E>w*IV z197T9LQBv0Pd`T4lk+;pNV@jo$f3S~vE&sTD_yNH5vid-d<`T~)Q}eaQQKu;5_I9k zFO1GM%({jn+HS#ksw-n68(7Hb*Xp^_uSF-yY;`kH;itDTLQlr^P|tgpzz)SaL56)0 zes$lG)+@hoVQ@gAD@s$l*1h7^5$v7%X}HYoKOkkWy}Wa(e@_cI zhp-b1KQ5jT%Q`(UTce7;Y)Xp+vTKj~Dn;dWE5`May4u2w75 zRLuGiRp&+c--4S`v*MQSfOM`xai29q|NOSRQ0{YW=KT7})%pR~1x$3XNnqz@*jt8r z$7hvtg_3%oDs@*iNUj1U+dRMPp^?g~2$jk zNz)1o1XnrbSx!&|Cr<(Pe`8;~k}gI|eTxCD#VsuO-cX|ABA!G;s(z9&JO1CD z*YkfF;PJl>5c=PIL)Ht%4Z#$505uiS9$y91IQTd9hs>r`CID&M_4BpAdN#l`eNB}bD zg0>oWu!sfh9xj@rfy-g`BJq?~x$TG8%ujql_~wCym6dUS!!i(EFRh~yg8+HHfE{xJ zZw$R?4>jKnyu;U*sF+}T41uYMiagKNJWwO+6E^)=Q0$<_eWeN}v@m7=G>}J>mkq54yj88=|rUyM6=~!uSc8bRj#q{Wlo}fndL( zgzpUuqb&$NOmFxea>H4EO-NzR6de`yPam`(m8BL=RNTMcUC~t3%}HBs!|mT=tWUlm z(2J>1ym-=mTz^+fo*+|n$O2va@)QcTaxNEsU&2eg7@UaUV~YhrQ*Hixsvd3pEQ!qlVX zpcVkF&G=nNYyXC2c?T;fD_;e3JJ22($7TQdm2;IbGKk(QbjaO>;uZ-F*~ zQCG4%Y-+1Xtd^a*YAHB4I6gy(=I_c|7t0B`1bYQcn32Q?6*IGJ*z2qBZDW{MNp*zpYOgvcrH z=d;dqZyV8va#u}%_!JjAlJGyz;xU8P6CJj??f3mxU{yFLOyzms0XFo6$rZP(q)62( zegm6OxVDy_^!@%T#K*@6>e=ra@4#I%`KY=eT1rMHaAecm)bxQ8fA`<@ZNa30J*I{M zR}R(fwI2(venZan#9(N@tejU6jf~h_K#Ox)Y1)($?~U}08U4Rkx7TAwzIzFgV$g>Z zLWos(9RF3+29A>#EiK(Q-Tu3Of9k*gx;6U`ob8`~|Nl1E?0+*X{l`Laa=ia@gVz3k z_lBAn5#HsKjtyGYW#13TY?fwh=cnJcZYr*p>dKn9dtN#-&^os+S#8Tb=~gpoHDU+u z)8i={cSX28JS|ttIUR^K@1x;tr~BpBsYw>)w0?@Kiw41ITR?i9L= z(ce3x#gIDsZu&FAtvGpQ>6#YQDC!Nyufczj2S3*-+>u5o=cz6G^?BTN>-wjn;wTOm zM3}tWoElq(lpD2yW6Gk2l(^a5u2T1DDFwD$Q*!=EUV&OQ zass6TT6JG7v`vwvKqQvZXCAdTmV! zLMrv@%YPTofA-B8Y>P{o(U2BK!S5=d)$}Q+-kClln61vmW zR&GV;K6^W|0-x82b2XT0yaQUA68!eOCCZ)$6td=I-jFa-?9Vwj&i(Q_D2SHk4G8w` zlO!f2B{gL`2RQ7erY6?N81J7+k15Z%FpllU9_=ThAOrb^45V+ z@?N!i4^oJ}AP_Lg^NHk=B$GXNtAxYOGhNs72vW9jk<95AFw-fp+&?0GBN@}(vx4yc zv#_N^m#IYj=m*UySAI$&SPJHELF*Al$5mD~6esyBPuUb>HjJ=`he>?46z9b2eW{B{ zlNX1I%C3dl3=YYLdh1ycHR~UHsdOfmoiovPmF-N;UWm(#q&Lu3xgg?vBn-Pt3h4Z2v@65o ztKK@|=e0MI*XJs#PkwU0(7%aY7NyHiEI9LiGp3nRtdCScwzaA0WAKQ5T3VX=Qv%?W zc$ZJv(n|Hu9FG{UC3P-c(d)BYRZW0eP!Qzl@zUDa0`;Ne6P8t4lM*t~ZLLR15w%;% z?C*IUjcZdsy?ku3fnffqiHrDBaDAFPLE@){9gXF~mm``5C-i1m#LlTBeD5qt%SDt>b;{?8VE^ z6zM!3kJdC6KX(&dCCnZ=sP3iGM8Zvb3gO6zI&#?NlOuYgbH{JDNR(+xrXwQoLLFmz zp#Y8Zf>RmahacuQ;_`Z8cEo$mBiQ@O%{F#(_u+W+IS&afw3ebOD+kXzpF(s|EJ)G_ zyqI2nuBjs{$D18>@2}hTTV~%eIbjvY$HG2yZy2_PZP%EYktk}CYN;TwE~ffxCayw~ z6ixSy(3Vu~khdt(H71#GhNm^?qVa!0H9cJPNKIBt;>{d2WoiXYW*@_CZ~b z?b84RqEg64<&*OLolC2IQJhuneFksKS#f>xjt08Ax)w#q00juTYL1_9e+)D8@H8vm zvyq&_6uv7xIZ)Tv;>k+Nm%Ex-$PaUI#e-r`pN7>F1tU)(?7k-`(H9htx6cl&xGF7P zVuaJY{702MGAFX`f{WI-FU={E6JOmKDf3PtzRhiNvd5d0HNsn8nR2F!BbN9uZx<;0 z*W6O!MzoZ7&}v6iCxclaI}|gY`e{x2)UE=8A`(O>8hGdxKKTL&(NME!38R(9L0oow zPjVR7zOEtE(YHi-0}h-$v0uO*Sf`{NyZe=k#)#9x@6m567##8aysb+-EwyRuLkfx| z=SCDg{#ZoA&TLyOv0Y&2m5&a>pkR46{Qby>+$@#c07JOs&|0r zbRfSWJ$c(aJ~s9)5T$*vB9W9|n*(#L1GQT!_ue9e1MM<4EIA8*4L)8~J$XCbG`}ka zF3=c#s}WgG@FVFdcE*j&M%;>vYZPUtp9K!<2vjpp@q+pa^hm45EP`)RSJGnSTe09j z3e(dy=SvvP->3H-KV7On;U3rXW}@|p4%v4LUAp}S`D6nE;@0%`dZJUK4l)aB_ef*8 zY!Zv3gI@#dJ06QF>Cpj*gS6oBE^`a$f6pQy?@j2n)IALCgP^LDm}(KyA=vc#42Zuv2!bHG|TCq~9HRI2~6b*9qq4Vlo zO#<7aj1F_UOaLoa?lOQm9io#OU_8iAUc6zrwR{2IX>8eA48&Zu@)0}PxKqL##VYqv z45t(o2q>r@G;I6HX)~+odHCMft!}E{0gXMfVlk)U=;j32&y1gXp72sWNqI>*O{(K! zAC$`1s+I%XCj36UQ@2k&U}I~=0-*GVYCWo89)TXG^{C<53-4N?$J@3E`%no0^=%&W z4%Hod!+1+sXdBK>Kn*ocT$_Msja8qzxelP&n}M1x##zph!9qX`Yt@kYsGjS%22RLv z$5)h1;CVlv-sC*jrLebY z!PAgAaK^wLTAy?cboD#lgWv5=GCao;wzES9bp#(_S%Mue>L)`8Zr^DRf|p>TnMh-U z(s%RJyJHnB9L@{IYZyVln$@I(oZ&5xYC*-U`CSGE0IU#SgMn7eP1xZNKo5+%di}a) ztB%F6>!{0IzHypE8WuhXRgzL|=OLrnJ)q>1@wjfh#a?3s!bdb0VNR5cULd+P3|1=` z_qShY;noJkKNizilOzwOd0s4OO8CB+CG#VqTi73QR~{^?y=wxG8ce4f#~H>}IF2#Lhw_QfC-DI-p%)50@!cQH zl%c_CsiAed?S)#M+j7U%Fhw%ne!^qBb#p+^L|6J2#n3*C0Y&M$t*9JVgYxZrApKG2 z@jJtp;S0K2(Q% zcaOEhLHvjHJX?-cK7#Qaeqvexr*%JCzjU@ew{RPK`)5C{GDAQ1!-K&I>47&{v|$Qk zwv)AOx)>TBY4a5fZyW(XoIYWGGkzuu{>R}l*P``@eJ@Ou5o&WbzdVbHUjoA?>wuF_ z{vJ%(Y}*8_LZkNaeCnlkC)D|6Q!GpeU^vlw*5uv%PwShETWy9u)6zf4y3VXi175sv z;ETjw>Be3m5RklUc{HyMzt5DTp$w+fK}5QI2NY6RNZ0357q;}`Vr6&+u(pp#nD2oN zHlT(0WM9y2-Vzyk4ThslB|V!8N(v#fE*D8L1854X*Abbq=Eo<13XItCf zd!k$82S4$I*pEjTSxZ)Ik_$anmW)3`$;a6 zjn0J02& zqDu$_jWn0R!Z+YG0aFSCU^4F;$kAx9&Y(IDtgZE$7RbJ>iCTevYB*4k027cN!cKHs zXb!CDGhB7Ms4ia98E&g<`#sV@eNRf_w5_ZXEGKGpGUSqst>%g#H6P4df{}KwbQ{H~ z7$ad?X{(9QzPHyAOg5zjGJQg}=YF=_7{iYrKh`?EaMi*RKvU0xSX^0NYsp$Yv0R*yco3;kJKscg=AJG9C8Xhgri|bo1n}vS zM?Cf69tZN*5-$@>dOPOJ1X6Qer(wp`t5?-AWoTt|ACA1$abA+0^wLBe=+I;4dL+Fp zU{9ZgBkbXh?c-F9F)6XgYsq1tPuVxuzx`urvl$FAPiwzp*I?|BQK#dnqnQNRO#VM# z&h)!g>S3pwu*prl0egl9Mp_8az-)z>@0WxkpyLXQUE+HmeZ>&_iVeBM+X6&y{FI1r zgtwhrisXWO3!)DDpsZ_L;TZM&X7V*Pd~fVvEcj7NLK&D7P0dES1GAyylvPzZw69S3EzAT%g0ylz1DAl*Fl?&SdhGhz7E}**Aw*th$H1?Sz{csF zsduQgc%-7)X+RK{-dF$lrS82oSxHz9GA$cRkWwx~8x}SAW=!9 z!%Cn$J4`cQ12d5o)zxnSqW2TXrNjUP>U5wo_>G|o8NY8HHW)~P zHUeTq|I+hO<>L#=VATd#?gjg)ATIxbB@TQO=g)%>3{XV+Ac^lfWan9f_;ZEs7>JDb z!w0VqdUA6;O9la0Y`uV6t?Dl@at^^7fr~EX;p1zh5!sp#ohl5@#B5@{&P15m&LoVU z8YD2uaQQ z;M4;croCqwh9b)Bx#xq00ZHz;fuAkkNiO07Q_TIcQTrlE%3dctgkzq}vs#(9gS@M0 z9aj*aXwd>qGT+gH)QwA=O_iU8q!m^aMMfr}iZ4EJU;R&QMP6zxh#1VA3q-rm$O_QA zuaq=gQQ|$H$A^oTiHf%-jM_-P(*^S?+pAYb$S%czC8hn?Rd`5QU;o9)qJcns`uXL> z;b&WY1A9D{S~h4l;2@rcBF)V_9W;irKSp%|kdIpQbqozZYEepYXDVIs-tm+xR`sy#L z>wtt|#rFn^&4!xra(8OxZhqIMWdJgH!NSbFjwo-A$}k7dd@WUHNZzbx6zFM&hnQ7n zKA35!L}K^DKk{gX-ER#X^A99rHSIouXbhC*>UCoQhe-j*rUjeN37vvwJuZ{ZbTLtl z0Gw#{h3;w;uzt`7!N)NE%+&5sD+Tk0$-=7x#DYazWXQNq3uyWt%@n)pOG)MMuhtVE zL4fhgQ@I089!(F-8Blx9ddBhZz?_+#@U4=?WL1S;hX^TRmCaAfn9v@NcsERq8gvdB zz)wbm5N;%io@Q^(f)4EYuah-*)Z3zD5>znR};!bNJf`)FOOp3Oy?i8jMi<5BG zbskD*wH%bUI1FpYgqLcUGOR9`8sgZVF>k2UcXgqZX1-;^Mx zyhJ{DL-|m_Ed4tyr4lskBy0i#eaeSQaWo*bc;fXiQ@697;z^DUZmo$cr zYxg*Ff|kwx2&kU7Is%)^#f@j(#k(rYvk>L3oA-*&6s86_`Y0r4;5|Uq9PN=&&pnI2 z!p+OOe6&v$0@jUsaznGpNsvsUq{Cr9;&s@%AcBT@>_$-@F#kE`%LmGHK&Sa|Fhy0^ z1Y=1lHp<@+Qn1c60wT`5X!L_9-b}Z6a||}yg5+|b>*hqV$S$&B`)L2d;d%+hZ@9B2 z7CrocMfLsI1jF<*zI=q+TgXXG(?3dabZl(Q=*u6gi)35Yfh-~o4Y*`v543^RUR9+P zI;oi^F;;^Skc;XnHj9tCKD@U7J3LgIsd?;C-2U9N&NCrSb~ghVzCunxi$AvTZAE#P zbMd@|d3U!0(M6e?$pHh*N?A(PiCnT616v8%0fR;J^~5-f0seF&Mzy}FItp6psANE} zn3hzcI$&eBux6w(BV4d^~GP}hlnN@pIgERAzqByA-^rcVX6V8T;u9w-koxm zgpABAhe7c9A7M6|g&x|Ov={T_xC@RCAXBxlK=3M=%I2M%WR`6-r0$$ zva&KCF_(QI&x08MYYa%ML~wCuyWH=uc2VM?Z5V+Q$SSVi8l~LliE~Q0L%BYO;8DZb z9^WsqIF&PR5kG-kBFkak8{lJCSQ7jCm0Izys>~@nlYpX5^hPEME0iY%ktC+xK8MQ{)PoocZ*EfbW z{^?~PnoQYDj$W_`euG}^H2*s)H_4m9TBU0y4o|gfAlh0xuFs5@Q3Wd? z-NQ}Ouwq%!GP3_IAeG^ZiJ@WEv*ZT?+?EYqeC1>JZR7yMUg^A2sarO~SwntZj=^b0 z%=$+gqc!nVi;p>Z;8dN(>R(=)r!_Cl1c+TKQeZ9Qq zALl2~%|ur+zLAONuy{x-6+v_9(xupjNT&({r^mlO>OtXzX1-~~JBi;VCHrAEp{jkn zxfA_^55+#@z{K#1dfcIm*1r$uR&_YzMonP#L%G|*muVvJoc0zJ6ttfvzT_WyPbIFc z9jz9efYFfS@R6lUMM|*NJoL5aotwKe?$}-kJ$IGG?x{Oc1kCFI37?6G zDcG-bm?PX=8i+o55U_uYb5Tw$jaH=EFNV#s)cWXO41`G`hK#>{>BAXhgpca)lTP%e z8)oo|2L}^E>z6i~XIV8}iuRsn@wu@YH#s({G87j(d&ttn4MHkX5|WT`C8ilnRH4jN zjtziUqVMI|FjRO`zqueFU?cG-=uEg=lHfpY+~mm5dqpfPb`cr z5ywH0c$w*yE>rzW0OP&v*SG^o^J`Dymbc6aL{T_wd#?Z&S&mGuoTR$6p*A9Hh-Kl*!h)ZdMk5@zA3b@)Yat{?y}o_{}#! z(JwN0>?|&>{Nq2{my(HS{TW8mvv3Z2sYM&U7Ljt~NPn?{kQXs@`_7#O5XUMP>Qa3E z_%Y%#)tgIzUQFg^-YSN9o<@o1vRl-1RZ*XdilXIt^$Ijg{BiaZ1yxikYM!r#;ry(8 zhRJzfCj*u)Zt!{? z-G21wkvy3D(p@KDSz#|j&wV0M6P*4DPyvGJCoe!=V4;JB4=?tlUvOIN^()Y;WBSzq zC68va#^3}ZaFuum8t6v^_-i@cM(jM`j=7rt@OsdK-469>D;^~DivHuJA*ZZNV>S5k z#XaRL`h4$zt9H?UM%U-Y9p}6B&8XwMIufeV+s!NNjhcIU{K1B>Fx^b-2v&60B zj_VBwOEfRa;QOV{J}&sPy|F+Hp3kxj#s_$3xNOFy;6r5)(GDv*ItCV(&9yuy-!K>@ zebyf5#45Kk%+WkL`Y;gx)wris>sVNZ`(E#I)Oa4^=4cdUD3eU9eua`= z2CTi(XTc2Kq+W162p=JM-}ippEkxFtfzQDM&y2Ym{o~eOtlH?ckcTz$eYNP%ONT+a z=(bp|%ZO^Xh6ZFyha0<*lRM4_h>om3<&|+;%G-ryzn!7M#eLoKMPaei_fc$tp^kx1 ze{sn735AXDaEQD^5!u&xHU>X%++A)!`ftW$axijo%I?PB6o(|&rYLtfo)hw zXy}#Ln6x8NF0afv>a6;*PNwpFDm99=jp}R1JQ8kOZ{_!V_S5v(%A&$|?YfZMM-VbEiHlhx^4G0JNPI8Z|H2IOTc?i; zv2k%lf9kx!oY=iTjlraDS7#w&9_ds}ia@})^{>0GDG?5jK-jc)b-jfQAR@d4E{dQ@o$jqWM(j3k^Z>8$%|q=yMqqQg9B}J14GQ zxgwIUS(4G!CI2$-PWpg`COlvYZwObiAJf?WcDibw zI+Kdd8v-)fxlS0L2}P>RhrZ|UzAFoaLL|KafK4+;=j2HR-ML}eOYC9Dt(Jpgt2ETd z6lA@yncH0f)~8jc(~xEHSNeYI%l=kDH6f!<{h(*&n4tUQcqo50Vd!$Uc5r6kQ+*5J z{Kx7oE=mq(G+FOUbns2HrAg(tO&_G|gkJqgA-_LhfwuZ(M!zYO2&5f94U(lZCR#H#GhMJ`9FRxFQjVh$tUi1bQZ<&#WNW#l?!sa zMr@y(49IEY_X)UbkwysB?(oGVYbVqkD*Mmp)k zGJj?R{nnT}2_Un!8JK>LQM`Z%dk+GM9x`%(j0EY?N}J<8a&3+i2&SG94}d#O}IrGk+;pCHFDp{V5+gIUM38 zQ*5+TB|5r5@HUe;_uImc8g*7q>U#sdfh}BIw9&U8_dd;{wMvX*Q89E`Hs0L1yw??J z@l$u8kIV_QRCQ|(s7qdHU`q`_VCG!g*hVcI#C`0_7 zf4Qo%0iTkUSZ&2(@Z%MuGg;!-L%s7>F3_bJ&u3o+@e1l0_nR1=V6;i&+ z0WYYOD1UnTXmPmYf(KByU`I+&>9!r5VP*0-Ki;(h_(!NRn~980Au2IIjAZ`#W6SF} z|KJe%S#ewCP~J&<`oq6@mr_75486IO*wdpKJ<}T9>`?-8*ygS26~KZ~;v1G&jmYY1 zRi@23O)YB5mny;5s;QyjwQij!3QUx#j{>e+P{bsaUo+P%^(B3_|4YgqqEpK0v*(-E z>&(!|;cAzn&z^2G9L<>6h_o4wgdWbxnOQ0416O**`h=G+UoN!878OH1Ki}MO(MfJ$ zb80f|jo_i&e@QJ!=~e3|D?(QG{}~qQ=pTRrrI0MyS<@ z{{H>DWvwbKJ^ie&udjvXhjoX&olnumQ9{5=O z)e9O)K05+jUPt^h9yh3$b|6;Mtg~AV-fAC-oVav@>3wu3kw?@WHX%24&2fW2p0=%O z21CM=lh$vIxi$~aTaCt5XfXJdnn-}X78GdeUBPy-gG-UpBkP!;Xdom+Ne6* zh+FHQI>CF^G{eF7Yk`n@>+Ur@Tyz4ud!wBR?{hI*^19Y-vylz?3b|UFk{4b>O?4Kv z7pObG=L|%~rl0CtFq1VRix2bA70ssEIdHz8piUwCj)~4I#H5eVSXr$i!OB{6&4pZC zJo=5rZ>8w|JB-Uu-}n|OlT~V8cUFodG&b_o+1kK6op%%* zpQ?!ESiM2D5o8^ztL(gEU|=F46)U8y*$uXJzN0WxYTUa(#_-wxLE5muebZz2J_EXO zXM7azZ+iWXDTX_y6V+U;ab@LK`Y;9}*4F}?zXg}+kP9f64uyJsTbMaiXD#DQw%O)2 z9UFK@M=>*zoqx#DM@6yz|B&{UaZ#>s7w9M|Vt^9TAqYq#0@5KW-6f4mOP4e#D2gE6 z-7+-NDX4U(bPPj^bl16N@ArS+_y6g9IP+ou+^FNs^W4vUuWMavt&3cxZt9L&-Ul2l zelnG>-W0->x7dPPtUeQ{a4b&ozaZS8Rbalpz-%a0uZW6RBasO%{28J{|H^{5HEb)A zJIrdKm@xpC{aR0N)WF6W&3_e3AwhOJQjFQU5up}?U)k?w92``fi-)YgS{cm2l!Hgp z=gm?fwD;~kdH3k@^*c&g=ea}7-=xDCc2L3L^tDcNKXHK3PKO9E%|f*k-4V zTJ7n%&HJAKtMp#Y7Bd@KjiW$0{R&KKuE4LHF;=_}24!xCg=9xSX*g{Y)tTB}xUF_y z)8%6O+nq)L_c=s}dW)>|reZ;6RPdD>2lu4Sm>=NA*ebpErPU?11Ht?JpFeWoEei2z z2e(q&!1k5Q=+Mx+r)S4Emg_MyL2y1A4Oeg0Qjkp4yrE9ycX+n2+MoGttCl!o*O0<8 zSL<6;>4Xu5h3oE$dPzsmERPo(x6Kr-^iV6HlW=g_Png=zHte)Ub5Nh2?yDG+#|(h( zB68Q`ZjU0gEbm>~0TMpjjrz#)I!^)B2)KYpafKS*zppCs#Fo0QeXxz)zF13)eRFx>sr_N!&%yTkTZa7N)gP%AD+?lvY-kObEvyaZgsXi(r%<2E zZ)|R+LLOO%L#OvZB~jhjxEF)H`ZyTH+V;?{PQs?klLb%$w3{kBpq+-q-n|3FnHm^D zx_;TE0sl&VU{@FwYiy+owI=orHzLLt0u?e0aR?g!tJfoxe|i3iSf$t^4Lf&Ge;(~? z&nm#BuYJ6NPaMDFPH5_hI`25v9wnFh-aEP`FV*`*YYJcCgId~`PnTx-Zbd&w^O_7= z_+>6|Vb8kB6-VvP@%|KurdQZ6^&5EY%#%Hw&YG!S6c?U*n`h~@IGQZJf9^#i;h%7i z=T(lL1UQq$bq+sDo4hTeou8VXw6t*823u4olLV@yx;zHfSCXL^08zEUNoYQ zueFgVc2GRJ;#Vqh!9^aU)>}9??TAW5JVl~tn!&BZy>0g^&8C4;QCwVHC3CqgJew== zhlOgET8Ws%y~xjVmBEG&W4D0N=b#<8Num9?XPpci==`{t3{ zJN<_yogo_^$uvbymb01gedbr5GtF+`U<(~QsA`H4_|ux20u(|2h(T~Va3(5lb|2Ag z1RQbDZPpn2)%pApu7mUHu%0UE>UzU@Dx9s-^ekQ!xP6urmC{WwDLUtl(W|N@Z`Qrg zu4GT4!jQv9%$vg)yg+x)A^>1AUq4iw0>R5O!2cbNBIS~@vd9rjnVr!)fw?ty2kWrz zxL^L1lBee`xZe`_V<$9e#L@mhc>i=?R0=I#2F!PVvUj&q(mIDZcm}n%8TXG4XZ@+~ z4K}~XfV{ugSq?GbEGqB`-)j`=(+%{O)a}+ym)3WyKv&c4km6{qVp-*_HQ>Sd)z$bv zCm2P;{sYYoAc_;^9zJ-GilKQ7^Ps3vD>1^6{}|*O7wGF-z47{EbaL+4=Fx^LE;1)` z@u45fQ?DImye?A_%?G;0FJskY05ml?d1>5hCZgt_Z+RiQdvfCT98#Ku-kA0zg>*WmLpK*mhS6cV*Mv$2V(bzkS?;Vat8Cu)(BbajG}<#}ZtfHg<2f3KneQ z#m+-nZP9J_gdgRk^be=5Z+O`me$K75i>zW7eXjbp|2C#%60RXi$C;*YCOWA^QfY>x zl!$v4wY#5RG_jyK+V(Cua&J_>pdL&_cUMer;pUAr+9A2G=gG)+Z&`orfgc?@%f2mZLHntevQhFfK!{mkufi+=a-r2mH-q{yLwp=nVc>#17tFJHct$l(aX zhy&^GpMJ0auuF%Dfo7NINh*XFQWT+KL*E%nfh&O28SjpLsF>S-S99`s?sMo4%prxi z9)1UnlDA2Lx{s{=Ive|tMzqY_kZ%2Oz$6RMXQJHLvDrQyzCs;I^{lbbm0o4g9SJ6<1bIUl^3IR?p# zJUY&eA z)OVH!+&^oS8EJ-1GT+Q2`|Wk>+|>1bVe5(>ZXspLZ6Kyu<1;F=x4e4j@=Hc4Q0I?V zeQQ+nx^qgfS7{Wp-IY%&LKTWR?_4Rabf`X24=uDspFj2@RvWQkLAaduoi&vz zn?%yfy=3GMZ^lMAP4U`ghz3fUXR{}ojYH?&DJ$bv4s|U`?v$5oksG>xn zDDMO{8>7bdJsmFAk6GNi(HjO9_ys**rX`m5+RUy&8R~ADZa&b1Y*;1`wL|0dLoUg5A18vi-XqOy>= zj{E*(XP^h)Y{uCSg2mHdK%99O94A_bnv@r%?{ji0y}Jo5#|Sa)XDBgj|Mto{%)Az} zCO_)0GLcAo%8CYgDa|qtTyNWsk zw$_OYNjBITYUi?_tgSP+=YAd)r4gYo==>+ddx+@#In?uQ7}~qoxD=*oNb@a2L}2KK z1%@}dG_8`pUOs~$6>X_zj!YDGkLssoD_owxH`2cYJ%p_UVm9q3ud542@UX*U3PuzQ zbicHl%70V~et1$yoK`Wjo~3c!=~8;I+R)YkmwykwfZbeW zseQro;&-|WysH#u3yTrHe!4heb|0feQLwNj`})jnM&hP=ZsG1TWF-ZUTdewG6%-mA z-;3>LDUHvic4IE7W*_)FCo6NL@aVaZ) zkm@m=BMrhy=>=&2)ZbqCE^{q!`Wqk4zTH8vgpWkj?@*_LM?FOTCxaY< zPV_ZRk?QC6e8E-f+=uH&kHiHFC}OA%Wy#F72d0DyC~4$>No&3Ge4?XD?Q~yuT6Y{7c;Fdq^(U9oBGEKJ6&iy5Qh!+g_#NnP}?m;dnK6&hYbY_(Rif znfJNCGtyTjXJ%z3p9RbTP-~kD@FNXk z@xMv7Q&pO24K0;Y^t{vdM&)Dp0E47SGIG;ajYPuh(+!0V^`*5759fHg`1m6FcOsaz zk#<8KKewLg|4&6wkb$GH911JR3y)rMdY{?9)Ja)0NA}=Q z2^bRdyImL5@7%e=o;s4Pm>lwLJ3hd7SuYuKC(OG6Uo%aPt4^b58su5iS+-2F_b+DL z)O>}Kv07R2+H<{`qx(wLg1h(K)}2Rb`l|Wnvou5Q{y+4C*`KQRkuj(hgY~UsXKwleDCwPVHRZuPWD;jLsn_` zi;8tZcLk#8XScM*=+Cu&vH8YErr(W?A(tYm?XQEbiK~BiG~I z5y@wHI?v`tz5^`HL{egZ;v0nFdHk5>o<_&`e5PlOT}>YZY=&fJ(noR_C}@{EFZaKP z@q~=(9WJC?7dgD`*Nr{L_e=&~$8EYRL<0ra)^JoRs?lJ;pWwPNlWMexDzC6OvRvPp zurZml>J%3vjuvX?^2%U+b2&$;<-j3MB3Jiq=*TDE-?~g8cK53x|9NY)vr!D!1v->r z{d8-|cS-$q)>hK28L0^~-0HXH+j8@cS<$XI(a0iLCjFO2tA4pdyNVk~xT6hT2$4d_ zCke$urp_z$u45uD$Oo4r$Lzo6Ze6~Twdd8E(36z6r|&ag74?weAq$rI<&!@P@$2Fj zrtBO&)cs1&t$2T{AV=+70&}sraIe`Tddu>P)qXzYx?BB*{aKUYe$P`?U|Lj8g9}Yp zm>rjIQ|&M$G_UzY+F0(0yl3h_h4h5vQHE(0mCA4iRhZk?7PKgpeK9f0uuKAGXsKO) zaxJv#V!9`l#Fi(SBsqgQ_RLL!%-l+uv;q%q@4CrH9D%s(xZ&44FL#hBhgvYq>;HOk zwkFaRcju<`;kU8`oX1>2Ka07eo9{3+bP|hlU(w;R(cU z$Tc&jPam&FUwbJesu?HKh9TKJH+FV1;1;R^@&eW~NPEQYeL7V0(lv5U>iNA&>QYL2 zXx6*XE6NCFR!6orfF30(MByzREM`q_gCmgNi=hjmEGC9f&(%;L z8{KkOno%%hTP^+pAH1;GMsF;X9P_p~1n-LU6)4*ICC8uQjhO&PT|O z#oKd6V(ECyImbg49x<{C)bD*dAs5?ZX3YZHyE()hr4sKcoChVJ)n$=l_gB*D&0Vvr z?G_5ky_VHHph|QDeJfI=klM52jrRH@I@{HG_$W*rdjS~K=|CkRq0af^_jAGCUsf-{ z{H_R`OLWl)IP8rDu(_))QdM9tSU6Q!Pxg<>Xi=M=-e{9LnVQ`|bwrP?6}%ooGM!J= zd&-`%X%^&Jwp2MR_5){Jw$PP0PA@SGn_W~}DX7Po7td3vy$-}(ZG=+*6e_!Alv4m< z9pzmm?bCi95%LUoChPZD|B@*R@ioa@iS4g*uxawsHMW_t)Y+;}_t@8^Of}z( zj|KcMB{=EP-o{&zs_}VTWmkRtT?J8vhC+AH59L9PQ7?*mOa9KVB$wu}Y1K93!oe}Q zG0t!P(bIm$RoAEsD?ZoknYx|zH%njip_p-W=1CL!6|^+k^&IV$hIX`kddcZrQE{$G|)L^@FfQa7y9K+`D0>~iSiXi4*j+kdkSN_#p4Pas8||*`N0N|W%m?9 zGRc(dJr21C`2AoCyGKJUQJfosjdoGOLQa~Lz-52 zNP<9M^LpWR;%-%FhD9#s6-}*KIOQv9i%M|e`*-3uSRcABjg{rrDkvn2&<$L~QqRwu zoR}!JUSC;}NfdAzjEkDuRra5(%-;ZEertdKI}qSAoM$oQkC#DQ_+Y-yqeESOfQbS7 ziCW3R=AInij~&(wGfq0*mb~crlOfNFUCrk*Jo}o(oVY_@bl7@!^;}3Hs~EYa?oBXs z;rsDoI=!4mab}L%l^b|pvKdEI@IJi1TwCQ`5zwq6AFMO-;ow(a5FPS6sb*L1X(+#z zAX%8~ZMu~QzqHTTrY8a)KP)<;sJQm!s`4Z?_UgeV>)C5x_ZK=Dx;?2?NupY^pN;f2 zaD|7LbKDfCMMxuGcD%AquRVP;ZU(sRnQ!m0W*(gJ`;1?i)ot0 zFIb3(`aTE@Sq_jkAmuf*=+F2xG1cEMqm>kgAAvFs{-RLDHVx_H#-1>ym@c2Hia9Mj zoB(Lmcu-7bWabJ?gxy{}XCGnXpJ)oh@_?pxBzkch-al#;bXan~0*KOKPFWNr{!7As zKQdw6@?~x3bbneFod;v5SM+9?^T(~a;>s}0d8BLfKwo-Gk;0eA_^j>D~HdYOfeEP_3mmoW;o#gMW#mka2!4EZ$;xUglk~ww3HaN!@^b15;f$gIo;F ztSD|Vj4du?D(L7DRg7$zH^hX+EJ3OrAwE8HY93rEsppnk^VB?6(L)Dif-6N%t6U~7XTVyIV=kzy2?QU5QL?{I) zMwp_?>$~3vW&}`HT+z@hLS1uGENGGX7(6LRE^lX-!_l!Si43`0QEPRQ^FD!>Ie4{L zFwFUcN~UTu=zc|f=q2<)#4Z2j#~!;bA>5Vj3~}u|Jds7?Bjan!{oPVyCl2@PDv4!l zOg<>bD@Wlsksnng4zIZgTE&(A-?{^G|Cb90OdXWa_`cLFl zX00AIX4>K97wnACjZtw!IOLj?#e8)c+tws0qkjFg03EcP+qKtUA3c7+<)!c3cD2w@7Bt8d{9Z}mBGa~Ycp|p@j_dyu=|~^1paV1CSv~xQOJxIzhbOYq}U?oUUI+*w^hp0`nI4FYCcwK&h2$l zA^naDQyW36N9yw!_*bMZ=Yt_reZ2@vGwk?eyJvZ#YFlOKvyP)ZJ&XPo$cP1opwi>) z(9qnf%}TY3?IE@yEKSBC;%GLVs1;9JF+ZKp-7wOLdAbaIe8_ye%h_J1N0=sUMCkuK zOfq|5D@y~@oOES~ulNLQB&cfim@_v~c4GHaA+^_{+h#hce8ft-d>n{ovz?{$wrXfr zOCck)w6q4mfSq|w*CI8!bY^5f+Q3VCd!Z|RX^F(RPDf_O8U&^7D7L;;5w0zsE}{-F zOm@pYgUI{4k18IQz84c3;AFHfd4u%AP* zH;8GloZIJW;>It(TI|*j9=w{*<}2w*xK zoWal0XWfYV)OrOCR%hM zjk<9??Ya&fQ@Y*P5D9Mz*7<9$x|<4Xf10lzxj!jVYrei49B#bpiZ9!u;WtpL_|8ah z1vNN!HEvuqq}wXs9yNz?9qkFt8=`AFnMC@iFN;4C#j=Lwf;iHvxtRC23Lqe zvt(oQPoq=O1R;{|278l}pWFLh*J6c*+wyy0VM)||p(wjQ5SjNnus80G{efVBmwgyy zFT`_|(fU)3S!Fj_Tc$k^cGVuJq*U_oXr{8eirBa-`@7_m9XjBrsKpkZF#|)E+XV4> zib+VSXh6Lz)b9NY(5^(D7`BQgm^l4^3mdT!{GUTZi%S|d&d#oER%*PxcsY|R;>hOi zdd)`gdr0iJ_k4z8mVuUj%~ra%xlAtLp8?PdM6fkKy%3Y1&j!iaI**?rL$td!N{pnn z>pe)J-x2_kxldz1z%z*$nD0@>q>U zu6C2$=2sm>kcOUdJkz(b)`d(SP6hg zj>qAaO4l}IYwnB~IGDjt+%)$w-^&LN>wh&pn17a^#6P`KhAbITQq$ThWieJtiZ-gR zujlqWve^;QYw$`0kB~U#4~FcL{%g_2{LlZsj0FFiy#1fwF_QTI^<%LpBP%O;p4Y=P zpv7tr*jnh41pr3pf;Eo$5;K#J|ErQl&|HW6L+!NOA1m^NfI%(=e5ifU_kOk>UaJdzfC{ovtXaUfDJ!UzTWTHs`PKtglE=~o$4V7A2qVhPc5jfmehO}J7k%*GoDZU; z2u=)@#cpa7#Kv%bJUH>6fqEcyUwXvh7BR6TXscSuNuNu!BdbH%j>WpS0xHEoH*V!O_=d?l})=e zMCC^ZB+VnVE3DZlMZE$sqt~p=2`Zk*uWl8AkbeLKpGJZSe0B*K@C$2eKv&eHlcXxK ztc-_)#Pb&^5CM$YPf;%g$xcC$6b;ZRN z?JE2Cc@Az-{AG(i2AUqDzkf@u))O>XV*&($N*NrLdBiqON1s!dgpUNr(ZqSZr@QeK zXoFQiC(1Ljz3M;m8iMWZT>-Y(#~SD?k1{N4wSWey4{)ndJ)nmB>owH#4@UB|*b2A( zT#i8C&>O`TkKXM_riKcZ7JA@d)L2y?Bm&iUM~4*NyNv&?PY_(cplCJ&|2{_X51%)4 z*y$f5%rMww@AL9%Wbv5y`+1$%mFSAt&H0sj<-;tB3CSVk&=O2DPCYnqk>Q}DlQ=rv zC&iZou8>jKJIQ|c7A|*JvZ!K{1MF0pm^$^_w}((qz5}(c*bjd^M#UcT2&$Xpycq`G zr|(ZrPa};-pU%$CmdMwip9yk3c%V_vFL!+X#vok^9&EF@`-A_SxXiCLc1HDx; z=}O7}=NI@=lIE&ypIdIuJyol;eNhcHI2<1FmR43d&T9hPZ~p3%aW6fr_L@{(<&BDp z0>KQ$7VzX?AIX3QP6scORtcfg`q}NvmoulvtRR(ni%c6@c|@#BGO%N2ebURtM9zU*9H*5r%T9XswUo$FP9<4)lYdfekGw0J0>+s&&yG8M`og>Rk`?973|*3@X!tkpom>@Hq1Hw8!c2@W`u2{FGWL2;o{&%qxqPgxOU4Wx z`S)ccPXd#9T1B85R0LN?8a$~CIEXE7SX0i2BaMx3>rb6){e1W;_vYJFW4m9}!R&M; zRC7=cfKv?jC&PhjBJ4UxPjvF~Ocq^ zG1Olz-(T_tE=1b->AH7`WwO^%YzagbRD-+{w4)R`BnLaos$HIHz{@sy!GKwSJ_wq{&mXtbYhH|B4QqdJL5zTafN9p! z&@hE3F?hk{a4U0R>*Vk{=-`lqBqUM`3k&vYx2XA>Br7)*nu=chh)ir521N<@U;gK{ z@pnnE8IG`v`42=2WPBkuz$cH1k5B5cgsxqlSzj7hi-cpX;d~gX1>4j!NVASIXVd16 z?s2r{LE@f2z+I6~Ji0!VuM=JExO}2z7T5pFQBRUX z^jL=FEdEy{ZhBf8&j2kg?NYd+$k6JZ?(7!{6UfLOymnqZlsj^N{M-AI$#|Jx5?)k; zxD`-|po?m)L z_o6CZH_?!cgQMTC(PeU{*mc_^e-Vvo#;!v_Q-*At1dpgzvTY9j0dGfMaD@IN3X%B` zGXEV6-~mQwPHT%<3C4Qyap>^cZ{sErym#YX~ z%imJY`Um$Z^;{PHWPKb)mqA+JA8l}^*dE8Yu(TxB5}cd{l18amoB!M|gv+B!`Ma8y zv(y;`D*hK-18u-d8~30de8c#!Jiwyy6S_qA5UoV#COv1eS$3RVzkkP++jwtl>0_Ga z;0k*v{nuAwnnEoX^cbbbY85vW@I*xo>J~bZMH|%U=Ml-7PGGupft~y{Nvq`=%|&R zo*uEwnOdP`;+e5m%@1=6E+OE&O(#NljIX7xujW8qd_Gx$N5uMEY*hevsW^=Ov#Lq& z8_Gkcj_w5MBdzbVI=CzhKUa@dhFDexvhhGt*v7lCpB)`d3=Y*r0w-T~>@GWCFhf+98f5(9Wp@oCB{HP)MK7X@mX6%bF~x9wHqba^oaK zyJdMf6GsnZLU>X%qj-@M&XJ0`pVl{K>H5PoCkAoo zxALEddgz#vlk2qKI4Vd_OkClKFM6Cx=IwRqvU$Tol{Olr73QrWcVQ?p9nzqoUe5dE zx9pe>BM6cZ{5@qU4Q>6Lk0Oiy${|9wYrj;>FrF~ny2k-7R7y(9$hQshDo7oeCvnIKRFKKs$ zJlmHqUv6)pc#aZNe0fswZe4b=UW1ZBWRY4so0kN3cl$Hz81`M1+Hvm>E;~ z0X?K$T3th&1&mSV^JS&UIbOREIXL~qUkh^$KqKKRpmKa(R73EDNYpt)ah`VQqi=vl zM{b@M7s$DrN#2~_}O+$LLz4dkwEr4c&M#4P)vr?<$&l*299O5D_0HLoeB*a zvVd7`YY-AUUv=-GePJwoep^TCck93e`m@-+%Xo@OD{;lbCjKp>9vUQ;P5 zDq2j{@(+QV8TP%ePKi+1sy#r5XvhUJ6K3P$0A}5 z1d~&pG9Qy_@}oBlw4+;o|Ms)A%)94@MxkUOGa)P-j0%?7;F9P?wX|tk)&V#?%U92h z(qJ(z6L4B-<(jT?@aH18p~H>xguEyGel--b{$%1ZcEhw-EPHHOXHK0p942h%_Oh#i z8SASU4_bd%{32@g8|~RyFBox=+GWT~WCUO!|LQ?3OM&PFN30qddaY~yrU*!VG?*#v zZ{c4M^TGS^>wCkJ)1VX5Ofcq;{51lEkwKr`tRubIgUPE}(jnCqq9;t`FrloUKd}Mf zuzb+jBzOZ%>q^c_9sOWfH#^!f->H|6-AXTc^-w|K{CJuK6zG(vhl@AbBRfKm_Nh~1 zgRw8ibDPTvyLm(yNz#9VUHBcGS27JJT#^6peZX%bnI;GL=ksR<^tXYocVU z{~lR~myT7~BwM!hh#adSNs*h?unjY}ok;lOX2MKp+2d)y05D>E6KFKfuWh2E&(nd8 zfu}-Fe^%0Lyo1WI$p&BeGv8CYP4Lf+`YR6JtR~@$=XI%gdcbj0xntlzGVcjS|6$iG5Q6k}&GI2Y?Gdh; z1ES|A`Ao%y%{^xpZj~!H>(ii0FkdLttNF6U=WBE; z8k+#7)6hs_TaA^5VwNGzYnc;DOt;NG>E|mC_)@7L@n|EV4wifos7T&?02^)yk)7Bg zCfyJ;48Th_-CK9^_V$kBLNnsYJv_ z*w?D$Z6TH_v(6Tv{gM@s7SE}Yb>c?8DoY><1^D@ufnj9g;(7p~%!`yM*?@;hF{yTIba{0(H}<^g{q^?gDBhhG>WBAw;krGHXbFyp z%D#T5GrDIL9vbPQ60<&9Oljr@2j9gP>lZ6x78k8RQ|h=f$dr?$nWOR)Cuws#jwsV9 zHryT8QF_^lfQTsPnzlzkPc_E#u>g)Aro^3Jt!^ zb|O5jVaQ@qfh>U5A3uDdc#B`K3cI7Puiw7vb^(@+nrqTwwPHwbREUrWV6_OtTH3qIkVPDRkgqF%9v(;Pi`+G1MQ-Zv`#<-if8GDa!js8(Ne)Edoa&D1FA zvvHfzb$dbm%4t9!P#Nc$4A#YE+&KUX(jTL7^5e@S7|V65wF<8P$6noUhj zb4gL-)lT2KAJqSx75nf&ByjUZARf)??41M(gwc4#>RBKv1fqKi&47!*ujGCBFuHdg zOpj)er=gu(M=?ky?8Y5L!5_9VoKLszq}a3CZrV?*V$MmovG@Qx*=_$U22*FeV8nd` z^1omVT_~Qp!`=g$g=H{1Sd5qFZ#^m!{?**v2OEHSUmCr(xa3|7wYSXoI)GJM`z8>t z(~lcV-C)pgw$sLlg|22+XYPY56VV{avV_sbOb@(y%Tm7S@Z;?x>x%aL1(1a*z*0{$ z?l?=$yPw~YFyWB$xnM+INr{t^ugF0E5mTA7LLn^Wz4d91Y3TzS$lfBlXVx<<4>={0 zaJ+=>eYeopS6mvmX^6xkge_TiZ_hanVW?d$tquKKx%wW@lg*aF6mhJ>dPj&pMZ33B zgVXC;zN;%~)yf0^W6(407`R(|18GIfreEs^DFZy)_A|x6!nQkjMgR+POVMtg+EY;h z*lVKTz-2w=A6><13m%3Z%{Nkv{eU3o>k&Pd0|X<>^}EHOD42pj?*@e@z2pZVjNUZ| zQzvI+@SqY?fKID(8pmb7?zI+|?a{dQyI2^C+0R=xjQss?AS6^Ecm+2U?$!Ygcs$LYDy$1DbWl^f9rc0Jx%C=|r|9Jqg1< zeafL2{V7Q~I?8`vkX{%V*++sjZIqOq2Vcto3b(pa-9XcM!3_}u(MJlbyS5#mXqd+L z9+9S?=$r?!;@@AdVc9;<{lm%EIx`NMg3`YRBYll0?;G@LcuO8OR|Xyx=(*1y7HAfJ zDN#*lMs;9)z`Aln%{l81rfAL5iU#h58O!e>+M_Am7yS5ik{r;Oc<$^-QsH!XyzXtJ z^Hda#*ONoo95cHhh!DuXgh4hp4<{E$ID$MWP-jI*AzG z4!d@bZ19Gx;4sUjJKY&jlx{vasC5er9v4Nn9Mm5!kav+7G#x%@2Iv{MDgIcOo{M+y z^z`PO9UJbv{Uh4l#b+KK30sfo^+js9z8Sk}{Jcwtt87s1sP*m#0%86uIT27y1~_b_ zd@!?QW~?^OXxA$?d-2aZTyDH=c?z8uXe2Z=1W#=*01NLMs#30}K)Eh632#kR<5d{5ig z*Tau{yi)m`_YQCk(p*8oX_NvxbWAr3gMq0uzjB2XuXEFo91qw2^X=UkLy$(Gr1_!%oAr*-c@K|YZ# zQ${AA(dgw%h8}W=a&8VD_-6V~w1iKdtontEm@I+7@5jFo>sXpnE5D0<^|xRC=a?Q1 zUTL8}nz40P!F_HsSq&gF?3KBBs)yo{A1z(FSz8!=obN>vO||)z?@39I{^?|?L1hsV zOoG}Yw6=cV?^x5@%Ly0=ORv@?luIHXl^M0AC^>ZrJ1U^=g@p zu#RXB<R1tlB~MAT4l0&*KD%-=FTtTA0QNP$eC(^)E()poZvh((#QhJ@u+ed-4BAru*)lH z+selL^zcv%Hn+-m>jc`q)p@eqD!04+1*0MZCB;O&=XH3j^{-GLI0IY=Uwl8_j)68} z!@sZ^Pf(-&8p2oznsmDqf!W~Kh;{s6huwA2kZZ)wvK?JUfi^G|l?3&JB>7770gXFn zh>Xw5H3I%gjLi{1Z>dCs`+h;`;bnvruK&T|v1XaY&{uGHJI*#;#@Q!^7K--C(a}*q z>}3CBePXVtZGT3aTDF27x?|dv=|^k6R^`xTyoA`exK{Mc%q?`s%M7ko0(Ps{2Og=9 zt=oOZRKWWhOQ9D>ic2l>1hWF82%sI328VMZM&|~|BhK~DntHwl*&}P(?D^lLqo8wu zahh7|0sRZ_bm9i{v_2;!CYnQLr@4TNH+aM2_Gl~sn5)-w7b->V;u*V=nNzmqenyT3 zSmTTrf-1gsCX-!U{6fT?BcZIiy7ZF{!3)&~$Bc>fAXr0J;e>_FP6YTVPS_irpLyPfulW_}f?tsbAxoug1y*i%O=qIYpm<1y^Mru}^)NKRH795j6dYGx zd61w6zLQWJ5i`|ZwkL$F1q+ZRoVYJ^nxj1ruH*6{d}uI*uDZ%HG=3g z4{X<`02RX-_L<8U-dOB?<#M!J>|o^FFV8a;3TdT`&cDk3`5eTFciLu2~qJ z>Y>>brkMy8`x0REELejU3ph7!M0mU2dc8F--8MA>ACnuTFk{l-wqh}GakULOH`Xa% znkKu)4_ifaV++vMs&Gc4Kh6h!mwX^7Ah1;1-Pjn)MTU3rp`f5(;t0semlEoYJ52aD z4Otq>Axa_j25m(qNWqk&*%LWAF$_k?)6M4rIUf#P1gp}Y}XprL9tZVDnH666d z|JcNddV9rL!v;9XiP;8y@@ToZ!s2+Xpg1>gd?f@8k`PR9K+I$Y`Nv{Z_)-jn4NZ{I z2?@RHXBHCDJ>%i!P3yFU7^!@^*FXqJLFYAu&Ifd8>4!})NsPdFhBf5m#KRn}we(;A zU}t#`ZdN=GOj&j%-{pHgr0uF)P}W=x+L?JP)GVoE8Ue(CQk~mwYgay}u-lH(YBiMN z%Fo=letrht_bYIkTd1dV=~=KOyyu^W zsg|l^Dbk+ku}=tTLV`Whu|c)(&00k=2ytj^Y;2nX4PDqZ!q&oVfvH8*=`B&w2EyFC z%Ri>3zJRWjO}zy01CAK=2`cXBA>oW?BMEi$fg}8P{>ch;)Ew&2;jTti0)MgrTpoCZ z2vNP_80njE*lqJ)!DX z8xXf>$rPBJ4uiu=7pg&=rwryzv%#+qj7&{A_Cs%9BfKvLOiF0_8Em7{r0=7nv9YTX zJ77^USUq|kO8Yd&X1YG2@8IiWs^2Ipz-q}5R(73x#7;045Vl2E&-f8Aj_oObVeTi2 zD$c6Q3dbdWgItu4?<0c7{ZLFG2jmaWm)peceCT<3zXS#a(L*$c@(T1>G458oB+%ja zLGaiTB(+Hwu;~7lAN3{=om+D~-vBDH^i@l@<9oyBFm5~}U>G#ik*6v2mqPH>cL!s* z%g8Pt^a8F0e%U72+b|&9kh6iIc>LdH_J%e6=_!*t_J!LBj}{LP4@fvEG@EVuwFA&X zs^(Ks5hq+42K55n*k@lTD zxlsPK(U762rK;$ky}w4(_Vecxt>(-2ewNQh>)fMDtl4s0x9^k!jRDQbQnl|h>DK3` zZz6AeF#&Mxl?mMsX`LvzY`t(Fm<;MY)V`Upjg?!GL&%fzLk{ZHE-P`!P|MM+_zVgu zc2SaThY$_}FHojb33($z>VE#ZdlBMb5;H6C$<9AEi$2@Nv(RPwaNhM7JwAI18~Bg~ zPKxZ=iK}^Uiekn!>h=A5gyiJmD{ED5>R=LU9V$yH5#82_o5liPjr!hldk1P`%U=DF z&(8znUxjREc^=~d;RtHxf2svBgOzpfD@=bvHiY;ySN<(C#GG$YQ-}Xqe}-ho9bNTV zrXWDfH^!H?CpRGK@W3*V(r~W-7z^7=M)ZVJnUs}+#ftT4Z%rOt#~FYg+i&N45S|5* zCzV=`ib7w!@!tLq-yI<{K92)i<07kytVwC@4Y5Qryc6szSNcI4YIb_$#1#|W2N6{A zAR@_zP7m|ysDgG{XB>|#Y2bJmldmsmLfU7{HOU^lyaxg5A7!FgpF%T8CF&I+G|$a$ z;+9Z*C&)qZkOph)e#dY5Bwt9j=>>v&e#r#U>ZR0n36|++)%xJNn`hk=$5HziQko&_ z5Sv)Y`z!%^7VL}sY9X+T0ewoLrK8hPic2{*0Q6O6f4H`sT;9SS#TDI#Gx_(7xc;`b zJwrq4?3i=%;yp++m$!@Mn*rDBWeiIO;9CY#EPJoLNzG(I7(IfDHN6xJC$-hsLy>X7K-Ihs79B#Uxaci&(`jqO6Lw{zEV{9q zMKkl}eiswitFchGwfl_Qx&5Oq%r=w(6(U+NHO^N_(I_9H z*YYaV&>u_Ep;MZD<34Umu;^duXm&l?UTVB&Unq}xU`BNe1lY?VK9Q2g8+{I7I%#QZ zZ;zXp{2T_!rdhiR3XSTv2Y4J6Dl$R;1l&o~nA=DPTh%k~kdBh$d$E4Wc zsXg#N0DNqqsfk|ca)`di69WitLf5nabK-bq5gfrXK+r^OV{#Bc;cub04$h9zmV+=| zUETRDm<+tU-VkkGz@b^d3L&*5{5|S%pukLXa-XtEziJCD*;0FSLj=CHX{GI~ zP~wQ)(;T2xZi#7cz7Cbh!P(@yUU6IgW5cWXn3ya#@00quf7A3>Sy|_|8$on-iTg&0 zxWJF@8F`w&p~;c~+hb#6=Wi6;>q<2rE(7TEqR?BZ~Z!czrhksKuMLiI~ja(LN zZi#--y#E4jV@7jp>p|T*3!h+3>mu=bMeXgv!#-&}t#{G?Omc;EqHv_GpG9ELOamfi z?}Cod9_V#sE?n^15ji|woo=L&{38#LMq>1>HO*Zyk<80@A{c(SgwCtcX{k4qN~kjU zZKDxnQ|et&gnVrX=ocQ8TcqZ48Q zU-T9F6;)2FQ41xBiImX(hpf{QI;!*>%^v7eW0>qi-NvD?2V#q#Y_x&@6=Qsd!{;Lv?x85kClUo0ypG?={e0ViLjaza!_sm2t>6Or zIPNUqC;Ky`RqxZ#h^-&j+Rmn(eD64>^$?|)a|a4-eca*d6Sfz}Gf++@fZxZQeI#GU zU*z}?!9_&t7Y2osx6cAey+xKi1n_7@ zan@nZws!Zm#bk9R!%0hH9rUEyLp`ZI2ZMl_5(5MMV6G-!oZy@Ksr|NTem>6Dwa26t zSi_8nR!JgzgdfXoB-rZ{5D1Zb90v6enQ{6-gb=VTY*aKgDBcB+nJfNUuU_JpU*J7h z$7Xc8+AB78aa-hewbs91(}==JUrg{MdM8D7%I5m@>)}|XCE*me5huNnLJj>E zkR(Ed{zS4xNmsWvWA9MX8ANB=2mb6+7f=LZCaCuBm;jq?$j&V_>%*7Noq|KPA0m;T zfk;#>{TUA&h)?6RFTg2be$l7OL2xyprL!||q32xIAvX6m5}S&||7tL$An-6D4$w!l z0$O)e59AMO1%ZKqVLsF3NM;{a5q+YoYU|{7S2@}Ag8%*OV&vF|m1{P08_5<1vhLoW zy&uiAuX%YjMoj*b4Ma^yWvEX5vPyN#=rrA-o>6F+7VB55blH_? zMB#j4j9qW^_5T`$sjouhZ4td=V;?%Zx*R*oVrluz583<1t0eIZs)cv>X1XkZ5 zKOVJ{3*gm!b6x)4j*ic89z&rm9tZu?H<3|4KLt^rQwqC(;BCZQhS8^nh6sNC9NZ_$ z)PFWV%z8&6)Yp6tOHxx;N>&V+hJw|eJ<~0o>%vp#`|$5|6ERxR7DaldyO6ps7Wg22 zb6m#ay9JR9Z>xWJM@8MiC%kcWBmK`+3=cuUkgf4;z_d=O4X=cmop|lfpC>oT2E$c> z=`@GTIX87HkkP7yAq+uTzpMxC%AjF1_)+>{P|+0fvCeXT=Dp`2fv$%;G`hT4G`YRl zhP|wUoQo!@I4S$~ZAjN^cO|m>5GX42Ln4|QC3RXZDJN~Nis4Q?2+_EE9S<-4`*$&Z zLqEJ5^H^8PNKZ6_9ur-hx9}Mom@C6IdwKwW3|=$xSCu?PUi=c>EuBZ6JrI%l{JHMn z=t$}RVeYMivRvEtQBV{?1q&5Pl}<$wkQ7C_OF}R}K?S5iQc+Pv=|&JKkrJe(l`bVE zq(eldq-!6Kto45H_nXhb)Lt0go45@V`&2Ob(nEg`kBW? zAwRJRV-u4LL^>4}&qCmdc&QN$pjwg|^YF9dFwqlpS+!J7dJ_^(*eAQPCju1e?kFkc zzX2Uzw*|*ClW+Az@WJ+Wtw3HwG2r-*GpuIzdYWbP+9+J3?1ZIk%a)Z)bV4-f&$XE3h&!ayku2=;!3&W-}_JGp7h@Jt(!WmV1 zd7z`K%gF38hVeG;{)uU!tOZZ8i6He3I;+QMf{uteGl5L@ke2r6NbCDCY4{SVy_|Kr z*BeJpRjWEs{)qWWIroE0kH{^$HZYqAs14zj4vV?`At!ux=OLcp(qquMZo_E!{i+Hv zIupw$@YuA4Rcf@%Hn^d=zQV}1PRR|+f28V?9cXVa2TH)5XkJ}%t8q+|tmodc52oO&C}o`v4zVLth0T-5mf`ElsC2TxRf&Y< z58j8BG2V z)2mp(bU$nj!9UeVxn$Zf0`_QgddWI`iFL}*83Z<+xe4%x8!8;uTQ2mu$}6Go4j?g%Fzx8 z=-UHnXNK%bKyz&cqNJg+jR^ay0{C}<)R<$$3YEBRoFn7;-T6Lxd4BCu0-!9pNg_rf z39U-vBE^UtncK6VzNnQw*k-hhLG1U|q*H%jLYKN^SaeU3pnP@|*UzYEYBGHL-T=V$ z*sF6gGH*ubRaL(PQs-SuSw0yhI?F=%0M%V!%T!m51!+XTd-qPQl8Gy5&E-_mkE%X) zTkW2%AHNwYmmx`A5!quxso0-{I&;4cB_tV{5>yoza zZD`=GaD-PBu>?i@iSy^rE7tX4UZIkz%g=Ty%WQ>(D9>rZV9CBIst8k_X9pWho8#Dp zem^@&;4f> zj`gxy-@iA4h|x@gR5OVqb+$}<)k5hJE*9?Lu^y|juNgyU)8V;Ej$>T?UVJ>=aJ)SI zzRF~kn8Jq}sB({S-~T#NM<2G2h)eagAc3LQ==t!WjFUoTTLu7%_-*ezJVe`4bUa{k zvMKpM36PPuPds|_7Zd&2bX%4<=KN{x)w%OF2Dzp!XQ6ZFiVu1JK45eed|I{0kn{H5 z5Fgd5Yi|sl2`JE2Nk{<9ndLaU%+#{*vs2p8`J`MUYsz}nFSj=7@~ORi&~+t(ZCY(? zzBPq{h(}-02j!XXuq$Rh>1{KI|M}hj{EzS8k4o%AM1|+|E0npj?E;`7!9;S0kRjS! z0wX%>B;NG$Nu;4aabUf zT3G2Mea@$XVS74U7#n*WAroF)T=o1NO%b{7hyYhFik1%%88!sZzTtEldFU5Zq;E8n z4~EwfDkRXQ1#6r!|BHocym|>pk#ATSHS`nzhr*@MX;Z~w^Z+dpv(q=f<5h5wa+76% zhDXI&#P9z7A2XP|)Kpc4@af`#sHtHOiKK)rHoiC!If)}^pMF+Oj=wqp7SoM&kN*sj zH$T#3)X~2?Q-arv7r~!rxF%rHhFqM7{w47f_nOK!19A z+Q`^g@%L}3n(l7BNflMQt9R~PfQSCRv;P1LaL_+p;xfcGIItH3yq`6t^^a%f`_lQj z|FO^)<>rdKcKte5S8o*7N2br!cz$l!b9Rb1uSfFp@g3X0zeQuxr=(?ekH%p4%|kf2 z1BLC)VWlr;X=z!z{*>7GU(H#(Gttxk8#Db)&DqKMf0}y6Zg@|AaWeSd64QS^a`ofQ z1@Z3{_<#Dc_urWcNGhJy0j!iTC5MSMFPn&nNX;B3L^6EbJUlOen?w+3+RXWRdA{lC zl;8jc@Z7j@qxO2iX9BO_*s%w_!SFA;u@rFK!XiELXLa|=Hmsi?kyVwI;qZJJA8)w{ zOfcD+{`m3ZI`f!;k?+{S_+M|a+V$Ue?S2PGg)=;CuW+cmDs@vI9EbllCgQieo<8+s zN9_kkQ$yB#ZqM%oG$y~kEDz8a&}Fll(o&V*x3R1Un2c^N9Hm*Xq@}kwSz2b;tgmj< zeRst&^S-c)^QtAK*OMo4@$wt8R&=}@iP02ss5fhjDQH2LegFtGHLMCMDUh@z!Ku>V zp{^DIQ4;!)g$OKcP#hd!nUXuS>#??3e=VK74#!$FQ!VVwK)jqHg zmw&63%CY zDsqsWxn}RSm7lzR@eAOY?>^!;{GL8Nxts26C;*^yP?Y^WTmM~HV!QrbK{Obw93E+k zj)rnYijqMr4wW9+7u0!jZ~r8Xz-S$YKsKOYK%9_2N;uFPL~zzY&~vH_BTR^83?4iH zb=_~p+Oj4!EZwxF66AbVO=8C=3`XEr_W{8h1#0I`aFZY8lE5_b7%MBQmzS5^4LYQ) z>|-`5dmx2Rww3J9^fEZ{o(Q73HHz#Ec5n$EqlZ&M50|Mx*k~W`p13`l1er_L5re$D z86>2L^O36yPGuAj5D?m|2>yOLBn^K zeRN+zKalWKteZRViZ1sLsF{*a^=6P->P?UdOq11;;;efPp^pq`7%{kezQy@G^mkSa%T=>FHcg&tz_-5TB2ANNrvv()PbbJz4yCq|bDSMgt891_UP$nZ1OU-L=+ zfl1UQo%?McNq3*R1djFW@PLIgH40u570l)?Yq7c6gzR2 zL&ZVl4$j?Ap2!?Ibt5pVeQs_pXuh2GZG@Q1W0=5|UD&R6pEu^+ySqyrm6f`u%)Wmv z+sD(BWA;J65vIXFa801;vrj5d+&HUKH)Qolf?~ol`3l9hdk*?B(A>)yi(6Y;r;ex$ z$$9=586;wCstVe(f9LMq0agEXiQRt^q6YrHs!tMBVn769LPIZwpS+%+#n~%lJt{vU zYJ1nGdmN#hPw>>qXuj3(=Xij~mgX&?-M<<`rxWX&+U8vs2lT+mKLj%C9kM>lAc-h} zqiLB{=)?J25Kws$MCW*o-GvU*#|Wk|@OB7Gn2KI5-buy5l==i9EK5t?zW%Qn8?l6` z4oDT)fh7~H=RQ8vxG&YLK{vd#uPHXX>4N&me|vmnlKv~@Wb7V#Yj@t$mB-9!;g_%k zqHkr?VtkVOnCBNW4q@N+$52O~f{ZNK4FF_1S-s`qDU_M5nZ`TGX3*qtE>J0GX$9*p zRB+qrKy1^#W=$nYL5x{T`23{!tDc4Ja>!-EG^;u6aEi3xVX8K zP`ETdzy(XG3YsJc5i$$-d9?Q^Jo)HOyRJS&?uvTJv>~=QGOqwjc^9Hr17c#X7I6Nw z+
HsWw!?!A1$H`NPLj!y06dh!HasFS&&k=qcl1_d)Mg-T)0is{#V^N z36Ub2xU2kj*7D8Z_b(psh)!g0gbll4mQju5%iN8Tkm&C{`RZ`ZF$chu zaaK>@M=U{LV)Dfq;Y(RuD?Z{%fm$I?Eq6A6jQe?{Zp$trvaBT#wB9SJERrU{n)cUKqF;~(@x_Vxxg z)QBLFmP+1Ai#dq*~tits6gD!g?OvY4G>H4xN43^mHoYbs8K)F|U z(+&J|{uTml@2X_6=zne{;aN8!Cgj8WUIYY;OaaH`^%VS{LK%wY?%rBwZ;^enRV zxsK>@;8JSSX-HOU_FuqX-)LZ9ry@bj!|`YzUV}mnu~|-;!|3OQ!dFHl=t;|}UaYBY zv0bIsgV=xM{W4{0)#R7hh=&`kW^Va(Qyc37y7_BDrsK)H>#HMGtB~$~N1d$Z_wGi+ zk3T;tYoR3iVk>vvX*d#GXXAj%$WyV|wk3iM!scTe zRrzA=A`dc!qal<&cFvEmahqa{8q9Gi+VyNGIuw)c96HbdSh)rF5|OyuKj)mclmLo- zrpES1POi83EQ|8Gj-;i&qEGia8oB3)P)N0nKrHrWyfr4;P*$I3&SEn+ud1lLyFpLU zhJcI@8h@-_T2u~@w3x9yK7y{^`{ifJRep1)vl#`f zH1uw{td0pm&DXdU(Em`C?$**_O??n|ek_G4zDaeicNm z#w&~k`+0Z&v63nWqY-Yl5%Gili_?Y>*5qrftBcdi_i(6viwd>)NR zJtZXt-emsu^<34Z68!vS)9#yFq3^{XF3DfN3XTXg?f^O%kGiW4M;&EmY&t1QqaV;pTS5Zkp!CPxioPRy@mdRqm<+~CR?peL4lF#g>Ti!;1H9+T= zyk6-XA9nLs*POUZz%fyar8(m$Bc_Lcc=i|^=J4p33ag8CI`x?17yaUar`5l%>rMcFNSMQrAOIyQ)4 z`v<^%U*C1Ae=m{?9}u9YU*^~JGbZ6)*D&(x)s-I|7L3@G0x|GGNB#)AJ}=CR&xboM zN_#*EoVYZ5NCn97c<1{uv<32>l#|-@RnnsaRo9;~v@|N&E}`42_1Sx}c4%9I;J=?S zuD++o|L3n?@wKiOF2rg48T-tzc}t9Tt-G9NVbN0R8L6+Xeu85rsL$BiFDQt4X=&*; zd7RN-8_f`aBZKRp zZbw8!ggRI>vbtNXcie3VpF3?_d!gXo+z~o)SG9?I=A`w~*?=kZ(r#j~!G=!PX00Gm ze{{wB*|QL$0Zc_s=h|9Z$D)pP+%>{ zyz@w$iGU6>Ph$)_;F< z`h(~i=CHA;fmra)$%L8)#B+dLlC2O-Q>`~Z)nQgwKZUI-x_v0ew8g7<#hmsz-O6*? zB0khPMhIcdFNTOX%ed|$Oedmm=t3(OA3qs$UV7L{MP(0Iwz{L5LkBOw?LsTq*yqNP zXfzk}z!yvsK&J~tu%6t%6j{7QoA((R0aFaxYpA%-|2tKp8}f2T*Q&PGR8ynl_2xgf z63%`rL_m_RN3gg6L7Vy2% z6crmbh8hFucZ^B&g4kGFbIfj|gd#&)%bnB}*kCj5W)Sm7NgxSt#h~^w>~eDGa9iua zTDXmmlCE(iQrP|==nMB*lp+=IOO9{8T_Ty8w?ai~_B^m^Q!aupvltn2zo| z1x0?K{PsY)X|;*VuPZj?1gq*`A=D5O&3bNYRR!fNR$sMWcs=~<7x(y|$WLFtJ|WQJ z#q*NH4;?fv@V9-wSGQ$#{(0;ZPfP%bGFi8tqN(k6D{0SqM-#!;em!dbwDFjCx6alR z>sQ-4g>nOb`gnW$awHx-S{A6PuRp`lr~Cv_t_j|7zDbR|qgG^y{mYnoMwVtC=Lu~3 z^JkXbTF&rT^sXA+z8z~zW6ry4#*Nluf+_X1)LdJ>yld3c{G~~N?Yq_dV#io?@^+``UBGB{i3y|7N zVP4H7wMT+i%7qCjU>Y$G=+Jh%BTiM0`Y0kqtlT9pk`g^T$eq+<;q0|gcQqMXh1@F+ zMp!BRqy;y;8Q9NWuNPW$I|e}!KX@=$P3PisQtr*e1GZxQApPznCnICt{FUG{l=eM& zvO`EFdMEjJ^;c}1o6`$?*NQ|;(&wWavc|rHuX%tW{jJy7@UQ|N#sugfYT1+7F-_0( z&S%r+xp{B7m9xU}*#UMIDk4g{F5b3Q!TzsVrkou5UtaI5Ql>Ne7|-7~BB6AMnwtIkZ!N7e2ln{#za{$dp8%EWy?9XI9RCnXf*7)mlMK-v zD0J16yb@8uvT%RJ3X4~}BH>=r?gGO_?4^$Jg9b45aCCBF?LPZrvaW_bch@eGZQK0Q zCnGXf^Q}MlzI-W)EaM3OkD42cXA%-_1Rg=gq7K6xWtFO`YOR@JKzw|*{wT!PPM1P| z*Yc&MnKvI?8mT+9A(}%>#jd8G-=r;@^Y@k-?Sh5G(u>DG+%~VL4h=(IMG3!AF43#M z;55EEOr#$re&$TDTp*k5nKL=M9hZxpRa>@nd^vdtRKP%x)zpAC#>bmyT&sXmr#ekG z;07VS3+2wCAfC%nm~$K(DF2jKa3%JlVvu94%-3{)IvUxxb~nt4q+ZJKXXin(aqjSe z0|zc7t!RI|&&f%!8sSh2;~S~&?9@3W?zsW;NgmBD z)D|9a)KtBD_b*RcV)TSSZd_iTgT_YPC?UFVX~q~4p036W|9l*Y#*f4j=g)677H@oz zx&L24*`4<2*|T0e1|rhNby}|;?~YKpa6z!h_1E#XU$|*J;(1nrY0gV>YI~=aZ8d!x z8&cm{Ma=v`$XU`%hq+#BgO3E@7W>k?_fMR6IromxpdhLsE}h5VSrPIK_M2;vuE6$nqJua7$JOUY zY~w^vL^~{@7frk4;brqHoD`wYUeM76-LXASxMvPdt1fEMlX}jj1nl4)al2USXQ`rcp}$^ zRr3I*j#6lbV&R6{3@>?@PFmR`bZS^cdu!jjtFZ#R@Io)vA?2pwSXaa=1Zq?Zl4U?866e(8gqOV}tX1j5Dgb;Q%Ap1K}_ z%02w-+)a+l1zGJjVmsoIYHBq&)eV-7we#F4pRrsEVkrYO=6F`_wUHs6_O6-Bv4?(mHKcmV<%zM$=3^3A*Yar<8+$2}4qe=v$=cH#fpjVLAv*`+2X zYy?LEs5e(;j?=^8m#@DeqQlsLqBhA=rm15=amNcclVJt}I@(C4`a^sA6His&ymf1) z@0XC^A`9*JUu%()l4=%XD`ys~KVo)R?MSge#jPv3#T{XMR&w8K0$4MD=j2e-{wj=D z8*EAR3F3$O@@AG-Pg2ct{QuG zZE?s4r371TQXcsrG|X{i8`J0bp;H3ds6vQXzq51ws5$&=p@mMgKk|6^mN$gmo9AqG zr$c@8!cgY^|J;7*>X+S*ybkfol2ZI^3vU$95p$Y<2oNfM3q9l;ZIJ>ePB3YANdB3L z&s9h^C}P=0LW1ne6_}WW3s}4yo-QxfI9iSvd)eXDhvz)Rr3UwXI!X)AJp&L0`Fcl=ZJMjraHTB#nQpHwmB3^ODxidgd`sGsEnJ zbe%|LB~0q$ni<8-Wn^}s&W#*xd?}5BN_TdeZ(*{}2UyWX3JQwag*ry8ju#qL@)owm zNJN)?Bw9I8;v@Fs+`zz($zR(E6{#A~U?Ueuc4Yynbo8`?+T67;bI&^Hj@t$iurpf3 z;PN4+GNT@rS%-}yoa6GJfA}DbwkSAC%;hcDY>iR+L{I*+My<-#*nW^Gjk>~4-5iHT zEOGDgVwK|D4!>Ii`Y)Z@Q#uhlZK)hHCg;6-e^`&XYH3&XmrQ8fvu(sztR#sVBN|djkq-H!qdXZPB3hoZ7 zIIWl&|CTJ1QJByWoMEjYg=95(wDA=;AF7QnwF?s3`LqWD?`4}(lw%Nd!TQ9Gp~)i9 zJ6~c|UOax$TVbEv^_(0#XxAl8Me7A+I%3X~k}cuVDyy4?pMRpC?VEfzSx9I^O(~lx zE)Py=BUw+Hy-J#rrKBoUFmM>oJv-#%BwMWvBg;fNU)5A7==aSaRwA}>gbEzCdREqkn%G& zeH`+i@z7&Vx_juz5iaR*hyqk4+<9@%De5j6XQ0W&#>2n)qKdbkEK=!o_<5|CFyd}kE2vuY0lg^mOJ*2QG3ULJ3Xg*0#|;)!2}?0 zYWMQ;hW(61EeD@GToug1=1w;<9j*q}>CD#DR1y*h(b;FMRb%m)tEzt|nv(}fOY-i~&(7TQzhf*;K|CYN zKr5l{xv}^v7~oW`i}h4G5Wg7*#1F;50j%2Lq9kpv(^Nk(_oa8fDJfh81rMLN_6UuL z!ybTi5%s{QI}qO0%?m~@#}}9peL-RnH}`W=jCjzPv~i|{`X(kOYUB*{$0XlA2fD2g z2>P;1>-U0D1ac5xu-&2B(A5=AaQS<cXQHh zE@Ib%tMZ2VfMfARtc77zH=!|JnD`K zmL>;cy5=6BjpIu*3en{kM$Mk(v@ma!UScyYDJKv@6cb)j!Tj*>J_)kSn z3(a8ZC=z5m1%_yBguZ)D_bF5Q)a@(mK?w34>!{#7(Nlldp!20&?9T>Y)`A$rDIDiX zK;|;v*Lt`XwuJ7pC3Ei05Qfv>&-!Uqy~6#qBV+rARE|<^pK+%P@z2f3P_;Wi$Cery z8EHh_Ml5wGq(`^IdIC~3jgfE92v#wUiO)&5FIh5(-n&3pU7~p(4h48AW6rO#T|d^i ze+4`2@VKMY19viPcXG@L!^Iz`i1>5OhbI}6299@Ww!O)kd{&}5w58yQY~1&CmWhx>^YW+7Ct`k4=wR7}=_({5ewe(Z zu8Q(E-z)xmNBchpj_481Qm{{+u%tOl-(ziO$6{eIX*8xisWL;^;cXwf`27^}z!imA zFJns#39`4e^dpuuG!&P6)|0PkHiNw$`~K_|rs!5_;`dGqzvaVLVVA=pT)FTDu_R%Q zTRnb^Y$I~e+dfXsU%&m2PI_d)Z{N93m6dEBl@)>KrgrM~@q%KL?nq~K2_83%`_OSb z(;j`MvfVaUe(J^a!o$Xw;%dd`hy5mrSGRsgwPRZKqG4aAd^OmYwKfOG6yJ6|UwrtAZLpcTd&wbE;>vD8vw08Yq5i#MlG!}%{Uju-J4@|jjnzAp% zwcDb7oL|NI`20m}isACQB%;6;-}F7Jf0~kFWBREje;LT=YSCgY@$tXm|MneSJ%SL& znMm0SK75!cR9+WpQh3_UKHHZj(CbV&Xi1+<7_@%7C_4YzrQ{?b5c11IGI1HH3+9|X zZ#6kb;tHZR)}0r=EnrAax7jUGss~dNy`5HKr=*xEy(~v8!N9;UB0auE12mCN%hBU4 zi`8$ct9>;XK7Rfzv#z)r>vYS3D1wxmI@fJ5_Dh~38N<58Fw9cjZnhz-KF{s?e_Cyv~c^ZUJ4;h2P)2stZ+~r18C5K>GY6B81_g zseS6#V1+fF1lhNGxkr(tr9tg(!F>M{hCy2#4(-~#n=KeZgUft;gDm^H`f{H?S8UGO zh%vt$^6gDK9Ur+{w5HE=`~e~jpL9!2R)*+8g5wwMGjT(Q=su9f&e8(bj)Jo-M~CHM zWx8tlOCw5`pPm*fbW5Z7U^zx?yG^uhL_kwx>lXjtRn{uP<5>c^1I8nDgw$O|dhIPZ z|FZeC?y7dpSjl7n(hf8r*bj;6X;RH#%o($qsIng#jwYA`3#>b1i&(8Lfh!4-s{!Ou0Un*BS-3L5SM9GmoMCzdWdO|^dzU*8D z0Q*hqhI449BGHMny0(8(p32rfbA~L1T4nV3UB{{C%J9hzRGUDF*XBsm)^EV0xU$D> zBP&RL>>z_kKOH@N+AgAtHGUN$g4I4R@80!=mAcB({StRBh9M4#F6sNkL~#t-8vViN zg~&F(-neq*jW*S`AwlP;@(*R)Hix)ErKG$Lz>i8&Bi~B%*5_AGS7q{UHc^mMP^h`? z;*#Xl<_RKa`nfoL{J@bTD93NqX5BSCiWY}CECc{ht>56mgIzHqq@?D1^(Clf`ciiF z>eaDxaL6qY|JjC`O?QiXadG-cAniJFVDdqhPd*jmU5S`zE#vInrgMXT{itnI)XUZn z3q;g^kWCtc-?zW?L%AkDF$~YWoGDU_KEFQoGO8SAP4zax17Azr+=QB<`AI2g6|BU`IDc8Wt6UCC zmwGmed2jNF$c9~Wmg)WmXViZ3R^mP7A?H2x=X{{r*3q5hvt`UMC@R>uejPPyJc3Ja zn@6J^my^9kbswhc>}_ir3nP-^8zPz$v)LwJ1b$h!4LuStcTnrjdHeY)_y}2B+~NJk zV!v=~-z${M_j_2b?i~5#Himj2cItlg4=*pE_3=PZZlxsy`tx6M{P}3>EB($Xa5S<2 zsf0C>2E#*8k%Q6d>Mn{7kZ3li(asK7DJr6DZ|Ip6C?*T>PcLsLb4+|bq@YMcmm;%BbM##*GUhy=2|c`*n*}W;<3fUqfg^{ zszK3_Up+cc7AJx3{EFwld##51=Ag&UuV{YWxNW#*{>045mzs#WF;=6=dg!LizrP@}uPq~AeB9bpsZ zc^{=a?tHmb`qp$KV{}%!wd!`FXcI;C^z$+@GU0jz7rWAx5ljm(yoj%OHg-$1!fB~l zk9wC_%C21tD%p3aM0iWUOAlnyB=R>7o71@X34AgZa+9hxv?*{HuoM zOYcmyKX1;_Zm51zQaQeG{H%Dw%aZM9@?szK!*B=%_P2}D>RmQuEVDD=&HCA2icia^C*FLV%T5HhW<@gvphcGyc&#%9F zrZ*R5ZID+S9Ex`mZ2dS^8eR%3m%9~ihyeviT^ZnTg-uEFd#iECyPr9!8Dhgaf_Sjt%+kk^6?+ z2SIZl7IC9j4n3jT)o*pz0`9P~qtOBuQCy@$O+P_{SA(fIvk4NF1Up$ka#WZu@P@68 z7PM^4nr~Fj>GIEBKS9Bc5z8}}1f}wC0J}1s>~&FV@XKAQ4|6lQ+!V6}PlwHE&*EKb zwS!gC+0*Vc3^5hr!O1?QZIA39U(^teLuRdS@h2v zrL~jv<}CI0h#m7$zV+j{Cn_q&n^Uv1%sj2y@p9Qr9bme0^=Z?K6(+9I$Vzzye%9B1 z_lgr9+?RA0XNatjcryO8vjs$0I_mFZlLwrQT(0$K35tklP^<7JhgHtP-O!(aa4tg% z6U--}FQdNAmm#|QP+yUga78!pdbzN%7mX9(PjY!I(40w8&5^RTvXsrQ_zRpne|7No zDcPD_wbt$dnv-wfX_nls*T9pt?K6Jiti><7RSBDLrDHUAX_Qz6^V zJj?xrtZ>M?6kzc-ybdGpxF2-dO*CT8f@|~LlVAgXHo%|&_3%qR1`A<|?N&0rdK?=- zFjJTEvrpvqj?_BRz8adJ?2#16p5WWEK}RFDx>GmjP8dng(#bskp8|c}+QAE1H;Nw) z%zy*=Ignla3q(~$v`;&HIM4m=%GPUNfe*?i1Dzp_OOM!>bP=vg$JN!N4G(E)zG;CAOPx^&yQ3o(+_iN zzD?nKLidJj%JOiA$rt}DyIzp^%MVHc=lUk%}7m|{Pf2X}=x%;b&DnE)c=Z$uH zMy7#q(0!M-vV%RN^^J`NIwf(b_3$xGan|Nc+@--AJcr(IA5P(5^wS)h7A+E~8cF`O z3&WCpl~vb`L@Mnu*w?691bED%NtEw(z^Cl*LL*sq{8V;IYgY zA4@BwpAkkeQvJRa#1Z*UORrae7wUdFs=V;&8j0aOb&wtU`DW1*gq~Ta=~uTv5W{vu`3XH~X;$MsXSApnUD>(a9nXHS85h~M zeY?u^ATz4{h9HK$P3#`u4xL`eu${OEcEOqa4~Nu?hZaANHcYTt^g1`&h3M^AL6v8} zr!q#=d|N%$5<+RxMT!%9N|vi&O6)Ll;N{O5t0#9qK5kP>O2>ve7f{B%B0FXE)o-hxxw%vj@v`vWh3)GLce{_aJzai! z>dVUTsIxuOK$u2URp zpG0eJvnN*9PX3j!UCz`X`uw#zuwEgh=2Nx*E<)8R`svd}RSkv1QWr?~m%IPxWB9%# zAth~jPLrFJke^R=OkRE`T9_AFrNb3FEgt+#y6|*xUvPnQ=TOmhqW75uT^Tufup6RH zzPr>!bUeZw@f@r%OtulNt*#a5+*P^}TZY(i@TPegWQ`a=jEih++_3yOeofV;AzwzjsKqp5NP zmH5iY%Iwq>BaVCv+meFN@NhK(hmDTlqXP{D1`z4cB)kXL#yZt8e=Z{=BqU4H911e3 zO$pFA$cNN?Zr8y4izV3Nf+85leCHa(Q?D^(Yn~ZNu5M})sF?#Q5Cb<|6CO(Hnfz5u zV6?~rPa>BLP858o?H&-Q4e*-A$mTUypX1A>p>Fe!-lge2(AfDQ5Fqp2J72kABpoC| zW}tTGXT%Se9v*%WA+xTONjknf$f>1a@SfIr#1S}ioNdWdJ-y`acTv!gbr!oK8HU^H z?mJeDR?j*wKA90Ienkj6nja!)b8Y5+@E15tzZPjS)wzLDdc*9;)~0T-M!%zRuE}|5 zyxM~j`#yXC;zi6OHL5;1O#6=tX$_6NG5^+;1qzN8kkg!UD0|^lBuNmDH?)`aEIGx- z6H?p*jdTd3Z?yAjQMs|TV;`x)ZWtM*^!O}iTgdO-yY~;Q=8S2ggUnth^vQCub4a-{57zj|b-TnRxT9)DQarPL7sOXS2voYl-W5zf+!TZd0psBk02W~3Llz;C%KL9H!>zVcRJ@ln z(9Nco!-XzcwLFlveaP$+w-a=pk{A;OMy2o9r^ywJE#R9H&-BxNZFx6x zrZjm%;s_&3C-&6d`BQ{afHAhPgWR3A_2fypl@N9!_rOcx!YVc zjMM%4R&zs6PpdLj3`|x9T7Vx)Zv!Q?;tZI<;Du^7eV0ghn~&7ty-ANf0g7DfU9 zR!jL*saY*}0Yo+hhz2;vnoP27(-1h5>C97W?V#hx>-QYgoW5SJ)cL#n zwtJRIN|u`pRqhV=x=SnavnPK)s#zA`W~sH0KqJWfMnG`GDvt_L5LxX|iY9-ge|ZL8 z;HEir+E0hP?qWamyLFHD$938hKOsNY7#ezaQ#T|mn$y)Ak(qUl6bBRHkeygNpDF<; zHW3tdnK!=EP9A+*_32)CSU%+xvU+C?$M^81e6`Dc#V#ZHgI*p###H(iu3a2d8AVb{ z7Kg*zl z)zb<sL%FQkK-LBF04(y@SJ|R!=KCUgO{BdU`i84(^D?x!8=yJSzVpfRHRwa;9j|vOx zS=n-j4z9)Bq$z$5pZR7ayJU5h%?yd%i@RlCceUWtzQ@yF(H;eLD8y-OX|2NF$$k*P zYv53qvoJT;@^IsljZI*dSWZTUKe@F9l77IsPg$+wwrIO5Ryj%PYIvBMy4pJOE0%8d z=vaG2Pi=6rrqwn@ewV&y)K3k4o_5>!<;9S{6A}`NchFOAikPt&T<}`XTy|X)xYo-< z8!1oAR%kuOBkDBDU8ZpA)GSj6GgObb4HgSHdk7qwkDhNk&fV+d44eDQmGwP1nY!gw zl3&n68(e>nqztM@Qp=kVZs|tnhn+;Mjj6j!CqHTF^nCmFEtUI#35tu)Y9>h^x>I{= zf2}!9{626iONF;f($e1Ev%*+(-EFLnCB^8feW$U&fQw1E5ufZ0mQEw9QRlHeIAtCk zm$j)4onl_)J{kWlHM(S53KKQt3wc@c zfSlr`%cDJSE@fou=3cnGjVBp(S<=|T5Ar~r8kbCeoXodGXLBREODY~PrCPq9(Qd0- z%-`pol^@g;k2CK3obN-0qfaf>?yLH1KDy&3Yv=7F9{TJ3$C6!-RdtHAjN8sK>`(}4 z3coUw`EuBWu?dsnZGr5^-8h+TA`JXanx5t*pE&j4$&)8+yk1F&rfxE^)bywM%KN1Z@%c1k>dIA?LHpj@iWC% z{v2A6CVbW$RZ~-&naeAaY1Z|j|Mn$L_WIX5TGbq~GfjXf`|pw{Th(47BRlgV<%5Pu;3sBNN3K+rilwaiKNcn4+~-ftus)Q{Z0;PsNfYG*3%^(PlLl;t zz1q8#qR#K@SBe&U{`G6*zU4w8g_0AGBxiE#$5_%EP``TgvOIm_pNHq-Y2gXJJN`ZE z+y~?OqdD)#f6TA$yAUl_qyoC@%TU&C1AlG|H}^W+**N2O;hfM2)9r1gk;8VvQqooZ z&GNioe%*_|7R_W5b=Fob+A1Q2R^h74MZ$_4k@90EI&#rZlz;DKrdTM{?v#rQw>Up&QJa?}3%21>A(+ zz*FG)Bpi9)?7Gd)P41_oqp~R|36B)d;4PUYJ>D(ZZph&bx3~+@@>BvzGr@-IX2I$Y z3>6eK5|*s|qs>AM)y@&X+Jc7JKDVY;ZkshtR`3hb`Zy~TukySvJR`)sD0?k|sZ?%T z?W|u!Nrm;P2VBu)kIuavz;1kAdo6&Zbo*{+Gt0GK_aAMDzKo3YLR`<-;w9>C;b?jD zoR&6i%682SJVj~2);nP_k(4OE)5MLxdX>YwX$L<2>q52y5{aA*=GT%p4nLaR8jPj2 z`C`+c6|y?Ko2I=(R^aAs+X+_g>+x-g8VLdI(N+vXI$T=N`{`-t`F{#46f-~3eD4%@ z!+qF68Oa&>2dDU7qDq;&4IeBUHEoO^6UK3XG><_eDVo0I;m1TTJL-4K7$yc+XfOvyFpsw;Rvd$p3O;lEY7JV(R#jU`p%S!}uf zC^!{KB~Q;5e4D5V2meovW9R96O z)nHOs^x%>~PE5zdmob0ZP}{W&?Q@N_hTN)e-xxDdwSqGFc#ti<&UrNZto=$SaMK^N z&>BvZ>@9)O&9`73-TE7fXX{f7SGh-rF;reIgvK%~!T$T_y=U|W+Maa2yXv9jdZ!~T z)z$EZnFnW08lN&QR%>QflTAd*!W&hA!LHlsqGKyx#NEtu0$NP9n)TGs--|V@Y*-et`MEE-bma+TPov^(9}@4c&SihMs>#HQL;) zrkZm{2o;K~cB;RrQIQdNCI{Ku*q2wvbS*|*$! z?ta`2I%&u~SI+_iP1ZgcD}xi@w0$viVV0G7Yc9L<8-&&0yD$uHVKfk(P@H(1FoKDD!1QXcy3C^c# zxTdXCBXN(w1k3KXDL7%)_2*6yanns2ImsBN_?k?aeXWov`i6!&;LezAtgi{${d}kt z37?U|v@O(hbg8`z*_KoN=dvl+v%J@#t{r^ z%M}Hlw|B&6o4-7pZ7Wp(7l^2A$-d6v5sQsh;*lUG+$BPUKtc5T5LQ8EnvG-O=_y(8gKA(8m6JNo)W zj_t&mNU@hsAnE@RM`OA>0w*lkc2{cr;|pvP`ouTtE5VsY%-jCcx7#mhH~7n4!zHcJ zs^R4Ip>fV8%nLG-pYJ1=Jyo~uPWOO5(@7bBzqlFg_ct1v_1GA` z)XmQ}iH|d-Lf1F$^;9jx9F_c~0vppb|EihH-OT5#+f&>=!?CM~)_)JXtl~|*N$)sx zXBKGKk$Y;Ufhk(9-OH2Lx2I^`&QKt#pWv%=azi(Jj|K_R8byh*RtiK1{D)a(6Vx&= z$iKI|W{Yr}luH>ik!0`2{6k7AuHc@WfU=G--~!GfiEH!DX@Lhhca#{&N?iTFxO&UD zso@=f#NBrZDM$7Bjh6KxMsyvmHIz^TzpVMYf0S+>><@u};jv;-hjA}kw zTP{0@^dyQ&dy03=rgXC-y2B*dlZ*tX@30LT{amqH)=nY@msgcSMBwMG2+ITocwDNV z(he#GEBQy+2HC8S%N!+orL|R=G`j_^5|c%xl`UFVg@x*o2dSN3u}`fEryJzuEzWwH zNelWdmpO5peLob0hdL>&RO8p!nl~N1{QY~AR5=3z0y^$IA*40U&$wk#m?qm^ee~R%a{M_Va}aQ5LQ0|PD* zUlGDE2`p$Nm4%&mGz(Vl!u|a}mkpp%OyD8wYP>TtBqBCx`+Iz{$(mo1M{W53u4_JJ zUXf9W1L7m|)`q}FzR9q&Xoi6ba@g`{jQ`Io!GN0zTo=^l1dxCqaEou!)59s_@%L_0 z7vAE${qG}Df2;ng2W+sfuqO|Ul-d3LZJPi2dO~@)_y7Nu`l;pr^Y;Dw@2OX>32?r> zmCw|d{k11cBU{9fq4O)xj-8`Z9ap@a_|NZRM=76A}7K_Shl+|*I z_Pu~VlqYsv7tZktf(wg83n3C7EtRt#c$Jd`|J_5XH90xX+psgilJ;m;ja0&3>9Tx$ zw&+*h>n2)@qb7oSSMt)_gLPE`n&4UN%V3!r`A@`dU?Flm}$cEs>_4svh)#68M+u&TBY;dEFqraDL zZjlUHL`CC+Fr@go>lKw>ETMEN$6J2ClQz2S*&WQ#Z~pIp-a&lecXh{kOF4+FWA#{j z3y9^B6<7hF>c$I&HeS~QnHxK%`$!|cOP~H*+2&_XWoQ+VLn|!dhsz?ziqt~I%+~jq zQ?KDZ=*a4P@zm`4y83zsx5)HMq0l;tjf0Eeeb>yU%{Oyyt&bxf}{@*Q;N$Xa5NfJmR%NDYX5qcj05MO_+a6t+KYg}zEwH$pzH%O}5 z2n4l5;JL1KWoKuP)w>FM950)}V6o6zC|-zexihlGe)MD0=exPQ08Y`CshoDeCLtx| zF=#&gZ_lOn89fmClc={{lKe1((h-MoT&^j%tFL7`#| zlG>_|;zL%y+pLbPIt&$zVNyKL^b`D|wwdz3&s*qvjYiv&tFWCQZ>G>T==|-d4wGuR zc5grq?87|`yJNJJ!9Ll1s)`t1)CUl`w;|nMoU~#=F(}}kyQ16c4`%=}?>hIOcC%vA zdfL9_{(l=NPJQu9eZV=K11km>PTOme} z%OB0XBjR;C;t`|!?|Jn5UehH*3kvnfPgK?#^+}2r^}g%sfyampxYmv%uX~Ix@GH(c zkcleQBEi6GGAH6?Fbj5}WXLy1GuLiEHLm{3@_gHb1`pe#_Y}Go!w&HSEjCInFq_o#SkKPfcLRjF zB=GU~Ozw@Fn;E)6AGZx;ql(POaqFo|@-*~%f^Yt}3EFVj(a6ye>*1|co9}-bj`lO% z>lL(})_S2*PWO4Z3cbt0?S0+z`VE$$>@muH_QQeE6|0MD0WaV4_mCQK`fk*?y-h3o zqFJ`dF7<42Z&zn_pY*Kc3c3zFn`xc3i*l!phcX0*X5Wxc{PBQP2^lcs_8;2J- znIdHS?E9_D`AP3Oiu8wnCrL{AJ|t9lmap#fWhyWFwhTHyoR)Oq9dAXt?))@^qc>h3 zVP#tSfxf4%(V|#$cki^t7`Nw5R)al}j^F4gdd!YO*a;)=?<7xC0~FGx_i*AhvhD4q z%e+q8!`B5Zsdv`j(=mga-S5@O%EE?=i_@*e?fHkXKX2>Q+!05*alqW$2Pk+Lu*xbw z1h4D4-z6lHIJ=1ogiFJ9&bFbSJ|$}rohE5GiPE}r<%i5VuZYD9y+Ln0KVVmR`m`@o zQLk>N({pdOfkW`Wy-p^^j7IML%0z2zH~)`quW*to`jn^P-JIyxc)3it3L0!XhQq%R zLe@433TWCDyRO}{XNU@Cw&<6BcWXVr4h?f-XK>E)Ui#wd{_%n{>080Apxv`N5hCuP z%!B=c_Uxs1I^EOrwO6nucvE1iYGyC{cI&%_AS&GQZR44N=D{8G*s6%!7P773%s8Z zoVSbZA?%gB(rZ5DH@$|{BOil()V4?qq53MLii1&0J*8$f0 z(C*IvO-I@YAdq;c-O-c#5Y`|0<6fa>qR-G5R(uBymA>uI0 z&|7h_EAR{#uNEaV7ZbuO9jOmsJbm*w+gOe>SbcTJ)b^)OqyLq-0@;UBQpXg;#G(25 zHH=8!OFVYY_PM6EE<1H6NgZ*CIp4^eR%}37+#T3_k+!{B(7xO|rG9K6BQM`+;NmR~ z_#O;gP!(IWKCwfGTIS=VW$nWxYC`Oblh;@mr?VPwevR?|m*yz<I78d$`=&&_DK?HQirBB+5W*Z3zH8wnJzs!&U!&& z!A@i6VlMT}J+W9=f3CXzamAY+KZD1*d6TD^;%$$k9uD*6_Z7*~-N_!ITb3Pa($O3;<7_C~r>V@_?KkkqA0^`;EnWoY9O0hO;ECZC}i%;gFX-|LcAfm+i2rBOcusv`GO zfxX|;*wDRcUT6z?*L%47C1k_v3X~zQ^`G0=l!zB<^16N~bl80U9V)I@D7G02<({zy zh~2&w=w;%|%OU=VIf8wd^;}bIOmdIuL)fzhl`92?CBv^C29WRyLCp&?%7G9THlC`g zM$9nZeKpitpd<3X)a?;F2MJpGfOaHbkNv`UQSa7*n{z#F-s~<*Z~Ks1;T)vpMlae0 zdEI;1$L#bUC$H;74XHt`*9Ie;nB2}?owH<$1jy-`2HA~U%c5{=P^l-_Y92*?r zA*z7Jkp}XZnezV4qUWh|og~|pBH_ckrk3>7*#)zMo@~KPzgq=ut(1SP)rPcDr;rkx zOim0=5|N_f`Es;sT&T~rI8KH^JIXOqO3D;M&A8#O7PX&4A~OU0d%y9>uiFk{1-0GS zbI8tFw;@Zy;O)dNB{S6-@Bc!IW^XSRH15ci**eI|<#DNpd0RD5(pABL z&^7e)=Ri5`dVD&!ZI7F86en;Xd~=Q`vfS>VSOo5sNLPtyi0kia7M{NQ6~llb01ZbR z=uQao%t8yP54v^xqDI?b)r*-iYx|>K*qQq^y1tDKiELE&S>2mAOuS~j+UBzjG>`#m z6E$4r8+$+k>v96i((k(@HaMVjk%VN({3la0Sd`cN{#}jwHnr~~^tp90i4BaVpLen5 z-4J0j-S&lx+iN{Sbl3`cU$?rDzFzrB?PQy}_qTo$ElMp|lIeYv@(tU!SF693S&_!_ zGXaqo&gRPQ_ykp(@MQcrgu=Pby|L>d`Y#<(sT}W@h^vW@OH(p`>W(_pxBr zEAg`YShscbDuP{EWYBi&UX8rf?rY)3cS}QGj$ThAKmC;N>l&{)xLZ}e6*6Y;6dK4G zr<`d>5%D4CgNaC^blADj-!rgRk#4#~r=^p0{VIuJpj?7lW5%oljm#(&bYYmV9`%3cbqE1(O zqZ!xgPu4w)-YhHrfpK$~jL?LpZasOU*oQ_lE75i{arSS- zRK2<+t*xTM2NDgo)cs5d!kT7O*oiG8Henj>GYbs#n*24~p=Vl(U_r(b*q40XOIAEA zzQxM5RC~UbiS&iVzYI+baC}_06?-))k))azVO-M@j%3)#jlUyMI6)uATK=;Irb#-O5Ie9}kE1!Y0*SEe(Y&NtNz<+zu-b~JFPS% z-}Y_d**~GqDO}jBEOk^o-tt7|&eD}w!iY15XWlhI=omTzhJf;_I$2Mt`uX|weu?>H zg_^_)cjFm81Do4Ls{~@MK{HqLpA=|0%5$!Co6K)p`%b{y5(otElyl{Co0bP>&V}gS zC`an^PD=W&6th#%Ukow3@jK%Cb3I19Y`5pL@Ic^kM0W)&D3pu=>Q6aSL9DgC9b0Vm zY9|MI>BWPn5u+87;k_HJ4s{ZPWu*LxQWFK^HyKjOXSHK&>i;Yb*_{A;*;nxh zWLf9*R_^!jGVa}=iGP_@mPPSr!|4M}RkUu|iH!q`iz_!YHr~s;4k+!7i*UFmSK;~2 zWc{Boo+6#|l!=LH4TB)=35jxyrleE^UD%5`>oJ4M$;k~)Ppcb z{IA4tnmQ3&rhOR@wqfw~(Zh)i@#CeZ*MWHfdYiq%pkOP_>+mc3Xg#<1CIha?#g;x; zyLocuYFC>^+z99rr2-3wz+F%ZtT2gad1_Ed9&ra_K5VNZ<;4R5%L^$_to;t%ggIF|H0lG60#a-!1S=3D5-~T~$hw%t!`7ej};$(Mo zhf^obWWApVh3<#t1UVx}a4`o`RSB#77F{~D`ZgVI#ry2K1lX3(a1t`o$&ut|AF*p> z2L`&f$?D>0>xOvz>0U1tWnd#2`7ZP8(H{Y$Z+qH3D~cqbFLVvQi6|WTPn5)sJDUkJ zLbI9rMj?xv#Mo3Mj}~A0=knF<##xcSHQA~mJ@&=9#EidxmNjDFt`^#Rtf$6z>d2|` z$k|i#RQ7)?bj{tVt0A*~bI>bd<@Gj-Gwz*#bF83y-zUNI)5w3nC8&@j*$Pcv=&lgX zBc*wgQGGaHy~JW{Yh zGG6-h-%?U|a|`_3nlbi4kl*}L{`ZMq6G%f(9yceftw@%VY6}=Q@9!|Wc4LaC#k@3U zv^%$v#U!HiSp)YnpPn>BD#OnwR$^^AHUDfKioh*F&2N?}Dag1FsK)!X5&TjD_^U=f z>dI2&@T;fT{l8EJis}`{j^{b~Dy#nN&mOpQ=WI!Z<6_)sSds`*xZrQ;_92B2US=1f z$9bD~A^rEG?F?ewcuV&J-=+lr^TFM`%di1cx~}Qa9vhTCYFe`^BDqPdd?{>60#TCD zNAj{XYqV!67wyGS7?LCGd$xBRYHq+L8+P7)U+$l~eRMwu?F8E-UGYAv5vmXE8*(!; zk;7yi9@c~Ca`SrgLAP5aHgEKD37Et2xT57MhhbQK7OEek3UC2QTrnnd^8J(8K`k_@ z1`NrUm-7ri|KxdL^+4)c&Js&tJbr}{%ijWsjiiB5@}9@F6E(D0G#M!=gBBx+NQ>vj zAGvts$(_Wwt`aM+2ILI$Pu@}Ne6th<>&;R*nXZL?I)U!`)lHHiHU8LJ2TOi{dBoUs zLC>F^#>8)4nLDTB6Vh&2q7>nXF@k`lR#kPAki}Ow`ey*lMq);S_K=PgEx@1E+({+a zB+fLDBOnXw@~4txNBF`Q#Su9;TKfv)86W|kgtodOhtVyRzU|pJZZ05{P@t{BflpSV z%N0#UtLRj&5fvCZz$Z*SDo3Kngd-3yb5|Ir+h@@Q=DY!^ZBjngBt`?(p2DS1ZRF+G zMhR}Y3&WV^Qn1WF4Qf~%FA{+9cmX4UyR-#~7J&un4Gwhs5Xr%#-<4maK7*I9F8 z_w*MA@I6RgkgADTFXw;4Bi`nUWdy3#y~C6$Dp zfB(80Gehb^&xX7&zlU1IT1LzctL>Vne$2C@D1TPfh!>7j4Bl$UQkJhC)@1PBu{z3! z=`YwfZwsk*|427<(-mVFd*yVGFUCLXyVGDe+VTB=hF7X(ZjD_J>Pd?fkb^iLCsTRM zF?%L@W>;^WlL%e^2;1tx#7M{e%*mVzaBSUbxu$jl9-JE`Gyj6{%sUbbOF|ddz?1kx zzh_;Fu+^Fw-?`+I<3ag;$iHSMSygW-G<29fy^IFSo4~`$_fJ`OZK0&%65$gzjMaXe zx9Z`H7tZ!ONvfC;bNW8xsfy|?_(28On$~sQtc9-@*{K-L8LGL~oXn7SZV{q&;DFF&|7WpVWyYw9 zvD)2_!ZIW;LW2eAT#qG6o2jcfJLH{CH%Wa7e(l1a65+nKj-b{@Rw+YGMEaT~o*z4QD%e_BVn+`TM$Wn_;oxMA>bBnBWP{y1jFpbtl4{hhDw(k3=zC z_v0UrDqK}m7(7naR+`G7(qG6e{Kmk^Nf50kj@Hr9@y{CI@=3A}wHQZX6=QXihbvsz zR*Amyl`nesq~^S^B{uQE>}Y*|^WoPwRfAUzK4KCp8(6z)uPfc3>Wo#sS3vfuN}tHE2?nL-U<~b!`mx4yGBf`qYvr_ zZwDzwEjRvX*Uid_x!8?%ctW}ec>tRD*>(#$!Vd&!NI?$pJ)j^`SwGT>;ew?SSdD=f zw%^0|3((_wGq(8>^&4P{q4`BWcLHl<=c7K?Gn$O75+05UejRIWj1a2CvO#MWYSs4r z%CB#%38n)6B<~t!k2YP-?aA}h?6@d5*l9NB-(%IUoz8vtE)1V_?rCFs&nP1Fh3ZPkU^Y3o`R<$fW0>G*9j>s51PdaN&wPC)yr*st7)TT!3?+?H#4i zbIVq23uU~}abDI(C1=X>L0SEj$^_ifQk%4_Bp3IyXo=h`UWI0V3fcYsIL#u?D}tbr zUi%_6vTZeSCA%WaSGd$ag$MRS=ahR>uk8L(SN8-uB~ zd0OD>bJ|A0Wr15M!O4CtHIdlfO~B`4R!)8d=t*|Fy9TG?%PDwGYM4rUOj|(5c>8CZ z6{?nqjbaje9Z!_M$(UrK&4_o{Na7=9@x z#BcfRS^8e1xX?QL8)1SM7$N+Q*t+r;#73}JBM^Ztm!+QvTApt7Ct!%x5EQwsd`AE1 z1&!OlB&h%9zEMf9x7LBv?-vmExh}l-3T4&JQg#fDyDQ*a%nR;^@JMYqo|RmO{%i}7 z)q}yM#jw?XgP-YRfXDgC#w1ucyaj*VF96fI&i~VNn(HuFv0s=niPi}OU8}Vq($ZWDIzRk+sVe#isQ%aNp+H2OfTPn0KBlXQrKOP<4dRAs4!P!w5=5bz?65f zQ6nrE1V7N>YTgAWhgTJF^0TFi4ncSeFi_AQDFIPN0G_e zs`1fJjY0W-6XMa$`}XFIR3s~nn2ybtlzwaGJ;t4~3@O+)%d(}sWIjMOs)UTSJAM>0 zNzlSh)i_7GA2z7ah?A#DMocg@L?tTN5NzSH_81VwqS}G z$6&I;VsH>ZooR*wT%u66)yT#tF$N+QVj0U&y!lw#T2Ew`bvuotKJ=SUYR&}Q55~=S zAv`2pIfQX>lKpt1>+gF~($X6~jqr|PXFwxj5o-99SJm$qKo|0+AQmC@+lYv339HPE z0Z&MFP7b${7LAr1CYM?bi%|-ANASY#?Ze1MK?5s-@jH;ya`v4Vu2xP}T1otFM2hdN z4PryzDlRc<(t-=;txcH44LZ8Q=s((tpuP!)4Y(m<2iJieO%=lx@~7`1(L7A!TJgB+ zJ{4}lOjSRj?6{Rwas5@0$ACjMK)B#&efR*q77rDWU+_PQlI&>UUS0Qm^nk8qXZ^Zr zn-IV7NWg;@Spiipllx_4);ZQg{fvSR)Nc%z6YrP@Iv$arFI%n!co7dzd=);r#n|ma zd~n`%f5kLlwnVK`(_v$TZhdM~BszR>`H#+MW!JBKrR!k>!M6t1B_r}xqc{{H!+BFP z@M&EXGdhmxMCX1`d~?~`-Y?~x>Ya)fT#OJ4S_n;o{4;Ygpd_{f9$%UJl|)zFhw2f|xR z0ZNQ9@k92(v{8sy;Qe=4%SYF%rv=P*A*h?yGywZ4VT>jJEkEINT~LA*j~=P^I3E95 zP2b_75^4ocFg6V7V;%&7W^Hu!qu`8`;X;H6&!I zL(7Fsc}VLU6kL+lr*ejJYWB=imI-8uXC&j;6j zxl(xb_8JD4t#QbXyOl^-shqBJ=@9hc*_L6_LQ#eO?)QUW?2LP)29C^MO+We$Q{x16 zWXOFYC0=gbe3KncXAuZ1j&lF}RcU7LMW;F#q%ZwkiOwOBT-oCT%_l2(p47U%v1=Muz!tXWxJx?q#6O z;Q@wlKy43#kW@u`Xhr!mMD7Hj1(N}7B^O8x$r&SI)3%`eKC-RbK_1Hos9go>S@}Y3(%GjKAT0JYp@W=1{omSBGkX5ZfZVx ziHZB#%N@OA5-i$=Jp2=Z;NJb|b+w{}evfqCv?m-h#~X~~TdJpDD0iTxabgvJcJ3h* zVu`ift&(E$Fkxy1QFylE;Ji;nqO-54fiACzW=D46uU~j#HX86Y05TLd8Pn27*y+vr z%Us0$Z3;QronDlvvzCkV4+aMbf8?b`TD@h7Y^)bedN=^hT5Wa)Pj_p;Y-;zoRGY#qTQ^OlSbeG1Baf7UGBpDcLjZu8oz5np?@0P8H8L=c`dHm8y&j0 z`LeIC;gA`<(%?tuCb%6`QhdBIrdnA?wxz3gY3srrSC3nEo9yG$Qyaf=KN2z8mVhLy zCxtvRUp1$0;|Q<)$Pd35s-7IZ82uvh&dClv*<2z-0gVF>vSuZwFRC4nK^*K7vqa(a~4CjKJGY7QL!Wzfhwm>Dyu6mmp1_Yn^gW2i$TSzAidT5A;KBkO-etLq(&Bw?V&eXLRRdw^(n$qJ zEVn$;uP1jbsjcWbHKCec^D=Dl$Lw7M)IwJ|To9xs^i!ye7HGTu8%F?mGpor5 zk?(smg+}d!H8kdr0h}NOyP^o_^VE|_=)t?GEimF(jO6{odAlQWSMc&DY{EUJ^N%;~ z-iQ-4vobpXK-yf*h958-f8S5a%vy4cTloeQiaqC*-UJk&&a}23w8T!z$HBgK=b4P4}3FBrwozvVUkVT`EIN#&{XAR{i1(8& zYywO3hP)U5UE+hKL2EfwsPs*^aW}`TW(G(CZpib)D!|F2YI^Iih_r@9ZA+LFJtI2X z4_~(&_<5HlTF>JiWS3-BT#fv6uD_JU`pm&P%WF+#7+}!x&gO`b@If^V9bcGQn7B*< z$bYf0(R8(4m@50u7*yWVe1e*Aj;()O=w!!E5rTJDQ95>EPB#4c!2cVy6b#*#U$$ z#RR0}m)^G!?^Phrw+I-Se{vSf(QX{hdbR_}=&KLTtP#xcPAb2s+CU=c8hjY;^BvG+ zSHWYX71&+<;Is;d(q)uLatJ>?4~z=2?b`0WY@;G3PSKj76?eP-L+nr#0D!mZkQc5e z_tI+&;qw4-Z$|T4RO_`qJ&r&5euAj|dIa@KXloO&s#BrR16E~x!E+7jC9^m=s#n=g zMiX(kQ56&ZS4| zwpPvtx5wYx{S+4V0kWACL^$&p=y-n?z($=_Da<+ZlG;3!Y)EG{aB0inU7fj!>q|dj zI(Lw0vc0qQ-XMmfCi;=;yROi(B~qsWA?sW0L2agLjaWTwt1G@#VF|afN6?}*8jTw~ z{jh)Kff~~MV-gv8=2=!XJ(6TWjm>+w-XGWwFpXL^@YF}-DqdGHsdfr?)c9`vldQ9| zcxsVI5smJL$!1*OV$9EJZ!lGMbwuyA(=oyQIWH??uj%+vkiV49GW1kb zNck;EeE&mj?{;1joURmuRTQW~i2Cx-~SQTKwA z3Dn4gp0W4}CA1;SzvFqPY6}%a$2V`fvld1&vi^OtJX0jgX(jg|7039}!g+}Ydet)Q zY0xOHoXl68mzsIM^W1mQ1tFQinp1m?SueFxP<|B8z;RCbV9h@7w$vy)8yjfx{GAEz zulNw7e=(Lr4F$if=c3&fEkZ0y9A}EJaHx}ZGxLkC3vLD5V-K!$*XhP;@Sh4NRf`=? zwm8x;?*aaTNv(DIQOq{Sn|zSz-blNJbWHh`DY1kb!<>|T}C0iN^!xVYK&J;*iOu@&qt;~C%`4xpZ&BsP-%I&BuRPn87Xwcu_d4>p z;s&|lYfXl0>|YP%s6kkPOSLXGPnp$@FKcMgt9|)xdnmrf4)2)a?}r}bHut3>;YU+cLzG*#~B!{f)Z&6WJ8Ki^Jn_wDvZ&Lme&TO@BWW^#?do z9)6lZ!|?Mttg{qT^FwzPg?SUP$+ESO_1>!TKaZDpr5>%AMu%n!FWexU&z7f~Jchw= zen-11H2tyay%?HAe#~DnEm0pkHtjZU0tka&p8UFB#FIN~odK4aatWd*B?W1acl>+N zx8`1U)eV`9KFh2vbF#zJFI2#Sryy(u`M%R?%KOlmm@EIR@Jt%RjBoh8wckzyzEqkn zqWy1v9y3)e%b=T>7HgVY*VJuSiPm%`X|bHd8k9f36iwyVF33D4C>8T}bD;is;A?Q* zMYZfh$3dq=NZ=u5!v+@i8Jyn2h$AXNOHlyaxC$jG{PQdStSE?HksEiZnyb_OC1fc5 zUf6fm+i4buVt|@0(S&znB{Jvz@3dRV-SWDX7?%k2A|)vI*u5lf55{f>JT`IvBb1=!5x|~!Y=6rC8z5|GwJ{af zabi+CldaRSBk}b}5)ESJZ0`N(+6k{pk((Dg48BF!J#LNe*Orm^v}Wu^(bhBk&R*lY z=0#ba*13|&PwO=;FPrZFFjXH+XG=ElRZG|dp!vVoHNHCCXxtw)YM+L_JS?}2rqZ?N zbFNpxhoXUt0p=M_(CFteY`wya{QJK729#OwD`kE7Kz5N9lz01ls;O!m+rW`b_kMM; zEumS~g;|rm4MqHW%}YGj!`pxRwx&rcw#yXc*xTVzQBi9(UCZCn5E2HfeXn^u&Yb?Y?VM!B zk3_gIvYS@AT6UR`lzx=br14I#Uy0(j%u0KqR6;Ir4Bm4(5%1)KWfNJh3#J@ z*eAXmG}Q;QEmm9&JuxXds#EA9zM-G;M7nEMSrY>}zn~C!sk#Zm3ov+))@^Hxgx0*E z(ausfz=Nr92YhF^9?=U3sB5&M#z`R38~ura_~*R6$qU58BQn>Tbt8LLPM8Jssm{9p3oQ+P{I5;61F(NZvXi}+(j zetBbGtHR0(&7|!uy2>@iht9MQ+lsYW9O&)C8PWI>$v!+n_XzuCW-Qe4jcPHl0Flw;-sKDP=qUf_)GmpsqEBCTE6XIQLxHMrTnzT31^+!r-i#$g^a z*Dh2dY1n9UZ(V533txE<-MTl$c6}o@k*&eS?u!5n}FM3RR%2mc0<6h`N93je%ef}d4vtk+5k zQyXs#9zGigMIMN zuxFdM_7_}yNsulbvl>E}WlQ`INy4Gu{k2h-#4dW4ab7CyMzwCr!3}qF z1L{3YWo20eq76nzA*lyIM!rv>ur|=JE*0kQywDneKPZPfL%<@36BYVDj#@}BcvmW~ z?~E$N*j3(HV}BjyHLmicS3|j%N9)g?U>vb$38Cc%;6v`3*^(rldax^Gb{gfx#CN3T zBAE(f(N-?f_0jcvIsBwC4W|7pFPnew0Gho=#@;A`<>FY;AP<~Hj`jw*(M8---z@q; zhI)72u}En&^GfZ0SSaqileI=jljKo7(XfbeJw=OaeKUUwhv+E#l(ozVkeiv7o~2^lHrJ8+dw1>w}1wsFu6EOz>1s8hXd4wFJ37}TRQ;cEE5!avyg z7N4IUF1mFr+HXz}z`$TIG7^LoK7ydGX`G_RWxLhB`|ilQ55Q+scMIk{hR`{S{rMV% z=K$)S8J-xgz=A?Qg8mF?lkhX(#fi~Xe`YH2lGnUa#Liykw-~n|gW{$Sc3bifNE%{90Bb63$4tV-<^NJ{LM05dS(UCM6;1OTK>@|9YR^k5Ta7 zc0XAR>8KHNEOO}D(G9bY*yODJ0`jL%yULZUzI^Bscl<57FD$+8o(xnIg{p*mwiyNb zjz5dpa!j^TX>&^&xHcqQ56tVe&7OYhx+y7WoxvZrK2hZ&zFHi4i?A&3(xw>6`9%=J7%#Pkw=J$3FS_GOaAVc>QvS-1R{(rg7 zwa$q$^N(XBylg*L{6k!WGL#aBo z2U*X{ae>xFuk@q}+P%WWuR)mf#I^w%Ny5B6=DphGf|a`_OdUF-I)d^n4hV)AP#S_m zh}UjaNj_dkndLIp(*o^#+OC^Q)L@GZ!LaWTJh3UkujNBwBW(ywyRF3wYSv{@0%*_x zeHvnq3;0WE(1IxGVL_PM#CeJ%!fJn&$k`3d0Vic2S{_4Rm!l7#j*h~nx%WydT4}N& zGtmq*p~q>T9?%(IfNJ6fz{fIRBqI#l&Ko*hbM162m?ZOzZ!C|tH|)^k8LecSqZm0m zcN7zZIiK3-L2G4ig8|`u`}S=Bc_Xm8J{PUBR1#1*0ZL7w+J-4lol4ljyigaJJG6l$05yo*%E2OoQT>(PX_s++^`x#W zh#4r{?o~SO0J~B$9a-7=BAa#n^mlf|v(@w200?b2urNMxH|cfkay>)geV9M?gQ4-h zE>f%T{q%1*t(MC}otNqpqD--&L&hpQzMWg}StE6~p7k1KI9fU$Pwy|SxHRG9&kcsB zFQ+OtF(yX2gDxyOzu4Ams&Xc{(~0u-yj!kS**=_DJhFXRSFmRmW3g_m9-YsVeeQ5t zP%R|3a+evo?A;dob4QJS2MvQT=>KE;Tmx4v47WWSe~~$&eN(SKb*1^MCI0huLtA5#az?QQUi~x?H|!a2ks-N zuMYH1bCP*^NS??KcCZ=a%qtxazb&uRvPQvCH|7-&sR2tqM^bW^kltxAZ#{Q(0r#>iV zxO`TX{xzIS0d7pBF^Xa5jMa#+y|esi6Y=aB7PW1_nP-yTW-?G9$!1LHR1E81lCfQ*Gwm)etrq?fx>Aa)}4=#kOc(H}2dYdCva$TVW?yfd{A zG&F-her!{e_=v|SEgSY+RW(h4BO=iCD?6{Nz2Q%w57NiJy>u=VL~b4I5wT z@XQ%)iC$tR+j<<*Kn&VNy}VzQsKwo+SW-^7=+r06Xn{jRnRSJw>vqSdotmTBLU8ox z!!ej?+E+wIfR&36>UgMkyL7v$rJQD zc?~a5jKkz5ud|VtyS2aMnDtQc%#02wPqm4Cp*cX<;-CNFOXjAKwdgZid5Peq%ry+j zaPDKp-lqa*K1(J^{KwqUcIf)Xb{L|}+*4fdx%OC|Md;dpHRf#zjY7}me1H^UElA7T z>*8)q^(Z6g+;<1Y2*v*5rq=$uO)MJfJ!~wE{O7(fc#w*YMRn!=UbrTJB=CENskGcw z*k(Tbr8s}Rk&}R)6IDsN->cWmHsGx~K`2*V#(y}SGD*53#nzdx z*QiUU$gWfKLE(C?Qc9gT;SEYkuibgMu~O_X<4n2*d)Zp^pS*%o-jgmSb1k*cKJQ>W7Moq|Gy z$)~0J^o3Rm7gJ9Ue2ox{3WIt(6=bf+!EmmPwpc1rGd6UMF$#S2oE>c0G7 zPg(S_abxp0>}fRihK4^6Ki18J={x-tXW2tMzuQ$3&GAg7u<(<6{8X5+CW0#-JajYG z-5LaXv_SKCSALgH=u>t5UI1x>I~}4Re5n?C`Rf*aU@MZRTQ6IQd?G75kcn50|8;5E z-RA5lz!u_?eJoV$%{mhY&#Y;t1IL0L=~LA;t_jiP^6p7Y6OI`VcX;~Edus&tW!oYa zcJ0$J71EvG>`3CO5Yb7gwvjXtl7+=*g=3}Qjdq;vTu)4UD5HD9^vjieeI}uZp{mfBtovE6XKz0KD zQPRdS)3?KKRE7NCq@}K5F)GVo$jOGiRJpCt+IqCo6@Q0u)+#&O?0L;khlaT>l62CU zrE4D;osK7`O%rA^L&^dzk_%awnO6f1f1|G!G2s}i81Urg4H}OxF34tWeVyZ+Jqxgc z+<#Dwkm>fT)joO``KFnASNk2+Z)qYgw>F|DAJFemhbhHGO7ycE?dTLa6kLo-vt9Zr zH6bGRT4S7R=K^?-X$k{for@j1_myTYujDY0*6rvQ9rtQ;>C{|1IoQnAQkM(MR*e(g zz34huh|a6z&>d+NqTgV9C!E%tC_&G)A?z|RYk6TGfl-&_aY6|yRZ6GN&iBMq8kUfdp4!wtyFbKDZyH-3N}vVIsAt#TWb!aJCU4Z zXato7KUd@~cGqpk--L->mb0UlC)b*5fGWslJlqXGI}Rz;Srd?V5=}%-c`4#^6jlf! z#>CuCmECQV(uqIOJys(kdwzuk*1UIt;XX|(<&d>ivq8wAT{Rbf_;RMsmyqz}@;gww zYP}UAn&<8Pal09hd%gcFCK+|az#g1;Y1|+(Koi4nCh*?@=Z_oLHLr62DNb390iV|S zhX+ttO|)88V+FZ!EpXQU0?fLIvz_k4@~{5kapQ$P1>Z(SJ07gR8x zkZ6s1hv^}&FSH)Mn?(=1m{OPY3TPy z@^Ot82g-(RJd#5o@OL*3MQY84x+>>$R06ikv}%F+s8^z?s4{nuYB~qJU9y*<&k9~J z!%%^hhmhE@?!u^G$ndgt`PP>v77M3TyOQ6=;N^l)E2O&hGC@bxLu(2OpWoe|j`k31 zG{}v}XkdY>j5u`nvzi@93sdx{=H}KuOE5?~guFR>_92|ksEVfj2=MA%wf6`FH{&(oZ+kMb@=?uZi;;RP*tVFsM|p9R%)BY%`UvB-f)S@q(@j?Dxpf*APwNXz3!503e1 z48~xtjILm{`qNTl5z;wI$$ko#Ix??E7av1fX;f_;x|Fsvn=KNHUl;C@CBhpmHc1U_ z;Rk(#pacg?a5@*8_u8v)Fgx1xfl~NN2~8UYDB< z-qeAXDE3^>6X*ca)*_SQ_6&L~=tnhv?&oP&DUjW|T38EHq8={C0B`d*AQu}J#@+gzpG&-?o&+=}O?FdE>Q*R$>D9QTCi`jYZb+TLNIVc_ zOWk#`4*mTSJq_nwVpVw>uR*=T)Qk9dtMgTOSz}S zzBN>RM+}Hp@UKaI8rI!gmUiQNv9iUmJZ!RViX4B%Dofioq zBEMF6U;PR+85b^*Cp_c?Cv92Xh=uPAGFm2y#i6l+|5$pPaICgGgUW#i?~~5ziJKa@*F53x>^12 zfu)l4TY^>Fk}?2=mYcExL}cXZyy{pz)&=5sY#_h(x7vj;6~Abfjpe;%J}j`j#XfGN z7LoxLSJ|T-wBoL8i^4JuvBesz;13O^T1!l}nKUsa*!iNm&`jCBiXCGW5+X4|xs8Kc z;<(>!b;`N%Du)%j#i4b6PVGv0wXIMf-F@tkiSStH(iT>-I@lr+E>MU_c000Pb_&@% z*(2U@4Y36?KrJwn?@4Sl9S!TVu$wQGIN)K_NV}oTvVye_8=l^wt*)K620_tC&#L2m z#V*8_mgy!-U$*HKxL*KHI;fv%;J)X4cnes6^0;ArENbldd734fRtpy{Ur#dXT#n+K zU8f@EGK_(C^(xfrH-PYa0qnKFd-U9Q?a_$_x^{MCP_atHD(6$8Y_!$jebtZ@wpNG2 znmMLzV*!9BYECW?*2>oHF>5IQP|6bcm4>e=UFbF^b_2Ny9RUgjtPJR>oN8V@fl@e7 z#RAf-9M(g}*nj_7d>k}n&sZHYV?(vsTx-|uJgOhgNSp>=3q8gA*g9{!e3^rCm@)j^ z;J1hse)i!^t8FVgpA>*~h)c|jd645}R=TMBhVQtic&INOLoPh8*^f!* z7EO0Y?ClX_-3;o9LFYK|AtHdj{)vS1kE!%{ccpe`yV3)zs#OB>pT!T(Ji}C3x8A%2 zspa9Z7Y+?xv3RR&TkzTbtkg-P-BRB?dIT{T6f#v)3%#uOWATG)klD~1BxbjKNfg8l zBQ&FRocviUn=SG6#|HsBb{@e`Cv*X9pqg~MeedL*Zce;QUy3fT?V`X)oO0X(bl*x6 zp4qcdFE!3I%MB6^hC2%}4O7ZP$8DRGZhq6r+@uA__3!RZ-ART_JT%#%D_^1C4%a=V z6D`9)UrG5h;iew75ymt~t(Ie^3yTr29j~x6?KY9?8U=3heS3J#QZ?_HFW~KqO_`@B zM=Nu6V0gXQjp>nkn;s#)y}%;{JvExjPjuq?LIpXnF8+Oi&Ta!KV({GCyJjEZ*M0GS-HspWlf ze|F#+nvw(Ts6=o%e+g(;PfLVB2H1B{Yn7V!u4?hrRo7X55H)NYFyEH7d#3Rb4N9!D zk9>sx{4{<@0y`uN(8m;UvxODI@byq=TNf?3EMB~3z_kR_rhl{m-cjeDfJC5-tsx6x zfd6t&%e7Vevt5ylQ9NDy5ktT#6~uPeorU;Amc1dfB$)=8YIzfKrcF+0f`2p#eM%8H z_y|6Z-p*a^cKk6+S7?N7FFr773p1&#)G4zZAE?~9-x|Wq_xe|k`F88AfaWZn7>*qm zrYIm|46XyEc#@^)F*ah&22k_%1##CCm#3V5$5 zyj$Ckn9A^6(B(Q?oh?GR2Kh1q)6VZ|lr(mW`mMB&YSKq--*rbe_cAVX8urdt%AIuQ z*h^9?q=(@&i7CH0?;yH59yBBAtte@)K3ZlKvs4OZ;R)s=ukNjv8FyQv7z=fKT8Q|! z=3Eg|k2DGQ7JHwr8l+{=J`F&1?E=rIOAv{LV`vLu*JlaO8^1Z<3THBCBNU<-2anN6 z$JLTE{0<%rA>4sh!a}HqSGGZ-pJmZ=Zi#}Z|efCf!Zp1CVUdc=!3aKqzDa`!3el~^;Vty-(RIa>HVNEUawbv5Mf zAvjGe+3ioB>8MEt4#ryZDW#rJ7$nKM>i6`P(0HpNh&{lxNeCtHnFFx^4zW zM!UfIzlGy8?Wk(fMk=q1*_RRQ*7GV}ud_Sx%7$`zv^cNkiwqDlA~niz2p#~2-?~`} z)RrXPa4s!U*jrk_*vERt2TA=M;s|HobL0(RltTD`VO0>7e5hW1FufXsfWXtoM?3vN z8_i_8(`hl5KMaw~))AkuI)M$EBv&5*Tdfp!6HPN$*;tzQo8&<^iT-|OnHyeTAuV&s zGg@L;FU(blgx+ zAs1V3?mMN*l~;CC1@SIxPJ!e$VtIA$SWva${I!WQBw1Utd~NExk-mfF^KXuPHTzi7=qCZxNR;Ebd_>Kdy7b`PY4bf<-hK{vq*W~ z>mEHuKMZ}A=uG{InEA&SHl`b+G2hGp!?Sk*XzqCOp;Pf=doaHt#Jb>{GbzV&q9u_Y zmO@4p94^QP)IU4;abPYzWT&{(#!(dX^B+J8?t@K>XQ`*k$vQ} zP!P`D*8iq^c=OTEA8iZC#Rp-fHN>n64X}K+MgKB;RLUq~Vq#gWkN*NU6jc!xfBVwS z>Sfx#b}Hxb>A_N2Ok;31yo%R9_4U3juO%S(UM79lXJM=j)VnLEdv!zJrAZLVY*=d2 zw|u{C;I`?&o$tr(MUO&h3t&d^RKi^3g632S%z(=ho{B?xs)y&s4ZhJ^xP7T9OvwhV<#gMu^yIkq zt?y=tm|vh|#>&g@jJq5BEUpU}>N9!}n2&@mEF4I@Vb4ImZ#3x$^)*jM3+PE>?(E@|C%5-Y4_p+IaXl~VuH zU}S991?$@a)$J{Q#Tsk9^<+a1;qGWdKO=J99= z*1fzOjEul!h191_2j7QJ^?}FnDr#Xl;p zt94qMq;xkFr6=2}2}P|XUKLu!Bb%jR`nlOmrf+w519XXB!2r^(odBFnFQT`via~(r z9H)IfR`jO8DEloaBe0|~>kfWt-Fx$+ z+_82V+o;4SYQ?&L=;kQ4;b>6LV>`y9Po%0Oq7}Ffbo97L_=)_KF)Z$T>&k!% z$PeYJQUWveM?Ff9>-HtXb{42a&}@lBK%;+&WL&D-OLTG~v(R37xp2|7r?FuD6Jh%ScjGD4<7 z697A?!vGkWWhMOHF%Js2qx{27g8Swx9NB-ltR`c>6)K9}cw9lT^kyx#%f z?1hO3^(>{(D}%KC%m4SrUHgLgsi2;Fl}#xL3&5+ZiJ0d6Teq17uvtg~3)ML*_jPSP zMptilX*ok2bTIz;2sV60!sa*x} zXRlXX;C3DA$7qzWoiN1jW~76koNWA1rtPE_dx}D)Z+@e+N`ltb`6o!$cb0&#_5k1#elZ0w1I~Zh`$BZP zqX;dJL0@=eeyvz#m)62%J=sg=b{$>cxS>2JXGk_&_QuQ3^VL42ak|!@ewO<9rqQum z7cu%C;=(!k*R}YxtQ?t%gg)Gp{NXpXEZ{AXueg zpk??{($Y)yitgWqW%V`yb!sTJ(E6kcrkK489><$5AGg0-5Phctoh%@P3(=M_A`W?Y z&X2x=?R_7{PbicVf#Bp^3&)wEOHRD|=M*g`8GJ$t6V6-_pyT?&yEe0eY{B^zBX&e< zcVec^tb~~iYe(^`E)U=cZvmgmScpx2NE`r4tz`>d^IkBIm!;21-5l!riT8wodB}>F~emsjBnyiO~nmMF| z*$flBo|RjMZ3f3cqw+dH>w5!f&q^kAz@h(ZoLCh^6EH&thPDO%;~u5Pf4FCf?Vckq zdTqoTXMYU#a;oCXv)mlx&SW!|w4pD^L2Gk>E<^Tz*KL>_Y2+w&8QztORP6j|x&7_f zYW6EH?|mLm)Or)esd`O~Xy9Nun+Nb-%v+`dlEq}Zy_bV?i&+NsYRpH2+)}=XA;yh zVHP)-6rHy_lQ*Gm%<|N;x&>zcIDJgzq{PIr=~Ghx*gd_wbpe1*#>Jk*i^Hl)Ar%T7{TqJKoiDgmwqaR*g4};_2(rcpaN57Kcz5ANlRVAx@YEd`EjRk zsJg??D%$4gLDRuizAh5FFuka8%eTdn+@_%Y#fClD4`8ofSu-=>6rbqrK&aml6$1}R z@`}>e!i;XIKdlnxR9{1lLaZ||%-%Lm-@Q|y4(>!_VXJx%GeTuaS(F|BrN&c@;epIy z@AW#gB$0OzyLR&9( z-2ZF!lSQ1BMK{GV?aZB7u$&1=+wLY| zTSg-JJ+;8OfhN_0KYH5MuZwLJ3TSLVTf~j^6q}lxpKnajmoKHo{70)%xHP$8s5_+V zX4%IlA(R+}Bc$uRWC-D=0dRlt%(j%MET3ll#s7UTlG#I}FgVObkbXaCH(WIm;xC5m z&h;=^+>_sMbW8TWZ*ox+v}m8yz&`=|?@HmS(w*Mi#mh*ZuTr=7ts7S&c3Cc58XiE+ zXkq6A*Wfz``dbaiXx(_*m`M0lhVR0ky`F*nS;+B1_BR^w`QZ<`egiwwQV$wU13dfZ zrA$9-mz{;H*83e6L>rZ5lkC-Js~$!R@p*~F?XKa#$Avb%j68hCxi%MYgN20@`i=Xp zuGIwOe#Dtl9MO9U#+x2oTaw;Yf7YmkHMPQA2^^x&tDvF3luk5MSY%nE*=S!g_t0NF zn3e^ob3Q7XXrT@s^R#N}KN1e7np)YjX{p+}fjH}^yhxsNBnk%cI&Izm|LVNxTd#*m z)|}e%8W7;sk{8BRTt{ZR-7OovfsJvMezU&#-Hy=B|C@X9){WbLv7s+EXzalrHPasf z2jich2+_#=RrXCl0*= zv;Whjr!6k3+gT6fK8$EJ41Ml(xSHwic|CtL_Hc~%0P`=$E%ai)COoE4KX2VQyW6n3 zwHS&)QLg`B|57-R4&7dPB8WO65FX`OYEAh!(H@Y2z3}5MpiA}+owRyPH!*~t$}5ol zHnGpZubfBbl;;#Poknx1Mm@UlWp^XX@$VN3L`;0aSswhwYSMgiz6P=T=`$YFDqPX; z*r?!lSY-E7u>k6m7@+i&HM;w18@EsIKiI--?mzYW&pvysVKcxh*6lg^Q~g-TuVF-By!7ow z!D8q&(~bDQY6Lb95GZySDJRrel^4qJ=m#{vAGjs*rEft!H^23_*}=-IifL60Ng+hS zzrhdhB;Q^;cwJE=ywa_BmO`4qgdv;Kt#?R!RjGg(Cv)!aU%{4}G<3up9>5)KOGo8? zxNS6X;CF^x+oMH!uJPx4$no+eLPd3w@)f&eN*KAy|vM&bIam;P3JGb*+t4 zAzcgmSmh$fTwrFaCB^iGo9u;bQ^T}sS!(9pgs}U?yj1_nAg(=88SCaf4nMu*Ha@>A z!*=BfaZdw-=RZG9ioTN}{H*UcK}wpC%2f9y-45Vk}*eunENCiae^ zo}Hw)Z~H$q%_*Di_Wir-B`Kmy0_U2I^6KR*G8TcayfM!OGbu&?`wLf$Y%0Du7b8^; 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%0AEh58aM*CG!a1a+3dGj04cuIbr_ST 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

&Xc459)i|B$0RDgDDq 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�{C$QKx!-%DEvQ(E&s8o*)GhkWZK^h?4pwg$);~YaS{*)?DZ4$Hdww&=bi1&h?Iqxg z?-Brn&)O|M`nTy4Xfjo39J#IW3ju{ZL$ES3VN1LteEA#N>8E0$my05$LJm^2We($M z;!?WfOSKJ*rCor)&g}2ANt|}Z8^oA$7-CBO`H6YcQqA!leVonVT-@`w6IuM-m-EL* z4W`jYgNLr4xO(5LxF|}eA_=6n(!X@g$Q$wAp9Nfc!S>ptVM}hZUT$%Z9r*9cpYvxo zUYLJTbFpV83#nk0GPpeE@3SWCsaiF2j#!3Y`aK zgdw7<$7Y{bA)o|;0NP4iSsHn_VoASPw z-debxKKyH~JJ4X8T(e6c7?*neX)VO=VvJSscrAa2ien{bporGM^X<)N4ax?_l@t=k zHzmHj_Bn4t-kF%&Uf<3Q`>;-N-8hD%l9GcrT3REa)^o+1g17)g6%GGJ^;^J$#)Xcy+9yS{5Rb#7${bTlX7m;t1tF!$-#t@eDnJC>j@s6-BEuVZMx2M zxy&|6|9){@!pJ9}S(^Go5GIyVhmLuu0*IcKUF$m2P1(LZ=VbRD+;yit!#rmeEX3Xpy!Qu-S_j$;Ncs2&Mj&*E;GF?hV1WeqB0G31x*%; zw+iPxlzj$x8$QayQ`v7Z)hp>;XzH%vjCcy?dcW8|h)V<&Jmy<4wTFS6$TwsS!QoVD z-Vi5ZpFb}QVq@MQ@?!zrLXdfIPLTP8VbfcYoYSCh^|=dKo0iCO&sUY)$9_UDhMIn} z%gH;rm&^S=m{S{zu8*mR=dA}hL}mOJ$HKn{TNKe3fF0mPqO5J}x2yA&^MuWD>Uqji z46YW|ps$#P+D7zY7>z(pc?iVD3By->S1K04*s$;kw~hN=Kz?A_&opF?@$|=Xq=&b z$}wuazC^d9*;J~xU)Y;|M++RrO>>Q+0O0I$| z1C|ijAWX2fRA^;;Eri~j*dXF4CzQVc@RVgdiJa%4y+FhTYCw%>YI^c^3d_g4c17kI@z3W^*B!?UgOm{#N~_T2N?2Vk39wtWi6@}q?HrPQaDJPFU~rnc}VN? zG;fU4<(v66j~*!O9eJf3c+_;W?z!;Y?^Sf6%Erd2TBXiN_$EstfRemS#-Ze z{kuW=-)=2N4o=2aU4i2#>lf(mQRR)`}UJ@bUNd}qXT8O=o#%W6@X2F>s?*atV8sMbZ*%0gBC z57I*F`ww)GBxHBYf`ZUANw;Y|N|0gFtn6NN;!mRlX-bKpL^{mVwG$mVUJ3q7KUzSe zVows%xi>x^4m<+sY(|L^tpiBb+mgT~%M4hH2yg;YR=oO(+ye+*;N6WhqbZtUoZaH( z>d17U6)buNjb%3*uS3-)Q&tGMoyZzId$oh@&uye7%<>5(B^r;{E99#tM<1=R&D3*n zk`}k$!&cvcG1xqpXtn#kVX*vZsPQ%Nwb=AYYU}G`f;=CevFP58ROJ}bRnmkI0o++G zWWrkW5(9S-@swT#%jVb`?dtfk&kXM4gLcKy8cmaW>jmIWFWOJPHr2CcqU;QpwhJh_ zl^2=bNIUJ70XtnEMJ<~`tXL1h8`+=!*t+NAY9V$nijHM3og8wZ4*y+2wk^&&YxN44 ze7xxT6epcr5dInxEDU-NMhYuQDZ=HsR(@jE=)#OXwotw%NOTQol0+;tsw1;2-_V4Y zBJxy?wlsBjD(g#N^peb|==w!GDj*XL7?Usi-;9qMvqh2F!isN~Ko8 zA6s^={%tUPW0?ltnTOf-w{Yq2(oIYb5fL9-BdTv>(tV-_MB|8=|`oV zJ*j7+0UI^~Dz$Vg44y&$urIT(yk)nFX6wvEg$+)QCtLh$ZofeO6nR{S zt-Wf@P_TOvrfVY zXq1Va0xJ)@7k;JBO$Eyb+)k1bx6@}qflSLR16sk7Mj4RuVN~Ne#&JQl@o(U_e8E3?qn)D+t2W6+H z!^!VO&(Ai$*5X?lGW`;Wog*4)gJihlr`i+<_&X@JtPWPOg zXwjq;rBQ>2fo1pdHlrS)%TOr{x8J^!d0(dhrLBdB^T6Lk=wKU60|EjN-_P%`i20X| zEaoz!-ghSX{RQ&%O*6DGK@htdKU#f#SC)=u#_fo)v5W~K1}$1`2j*W}vK-(hW-dzR zrE~oiiqMjU>l%=h4zW@=jXXh6T${v-n5*#k`@;|9g6v+EQ$?;^u}(y_iGsvbthn1v zPnZqN^kZtbJttewmV3^!tEhwv2X1vaEVdWESEEJxA>x+v*CR659l^ASr|;De5wq&2J$mz`j_l=u3x!wyRrPem}sZd(-n*8 zNxu0}UPV4dSMf7Jh)GGY9yJJkJev6a-no5pMfOfkA;8;YgEUr=tvPYkny#jO7SokK zoBa1F*tfIs3otU!WxO#x4XL3#|F>LC4}+{9A&2BT;&R%O{}>#B5MeI`Oge6G#>lil zYZw3TcWK$&Uv@e?Bky%tB@x`a#T|>H$5vnsrw>v zsZ$WLSM9iKRJo~B)8r}SlN^sW|Mm}o8?3l5M!#?oYqT3g4g}pvr(H;{F;05sI$0Lk zm&KAzHl3osT9K`Su)bFRGHI9w0enWixWg^j} z0yQ)P*B-C7i*|3kFFdG*&roK_A^`@+>v{_E2XJsqqq+(wbj4{;Zl{tzTVxdXSK*NM zSLA3-Yf;J^+O}2k!zy!6f41?W>S@|}9}D7L9m6pf#}DeDcEKLGSq)l6 zSWuHtFx53rQ@Y0*EO?Jz1W?B1jCy=QlZYf1|@ za&Z(Y(L~0S6?6)o3mTW-FgCtc1N~fY45Aq~uYb*r6|vXx4A77EKwa5Hei>z_%1eI! z7}XvD9JmS)B*E6Vcco@$7km;?baQiq6ZrXB|IQLLo=WpupL^Lnjy*L5%UeqbrKl^r zGU|8py%&4NmFQ5kQ`A?}s%tuU7EJkZxPiuUL$I~kD|E!d{$KE(PF-MP(Dz!Y4j?N4 z+Ny9}85r@NS=~B~+(wX8q!Uv9nh1q4F!7#UYA z8VsmAFkyhHi}TRLIN_fe2^&yuFpV$r2<_yqig;qS=~CF!4}XBi<^XI-I26+$FNRSl ze0P$BhY}dTGmtf4?r^&1QSA@T!j&CPdpqS13}ZJ?bRX0isOdw4kg9?g5_C8}HC5P9 ztE0qu@H`WPI^!7gu7>fyll!xdo`P$l+LMf|__lu(IiTE4fI6o^CLvA~7yxLqn}Rkn zt5$f;XIX6)OWJbY_o2OEl-UnJlG!xG3ZL0Ay+M)IFcq{^`9=0j(sz9x9@xq274hUP z7X4&R`2exVqLoywDw-!0`Y)`2uZW0%)?I&^&ZmQP8Pl85O0;`{M6)I_zyDo9f%-ZO z`yhq$!Kez4X_lgY_E77t)%e?%e0|M-2${iyc%$nA%ZyNJ(o@sZSQPT@&^rvMPNLUy z11)}*Gp1qhP6okFu!s_DbO{U(75LC}5_$5erx1Y2$7ktBYi@xH6S_n*0PVRJR>!w? zP0T>L)NSW+@usrrSBp`Y zGvJ4=yE=(jM+!BHo zlhdHt?3A00RZGNwjs#h$PLb9Nm}Qxt>~;hJeZ9i!7}s_WX8v&qIk65})w*`#qS=D5yn@*fKLy$&1pWyH5^eOLXR<51J zLl$L_D{M9$+j3F7_V&q>Menl9PS>giKp(fkPt`k~(6p{jmL{CN;6VZZ(u=41g>=$c z^VSuwv{V=0+%9J`maCkSqeXDpXh#?=Wk&f>UIAN5G*cUQKNS@%zRNfNM1RFf;}_SW zd&4X0!dP?H+@Cg&^j?*>uQt?DBH~G7#~7(mD$cQNuQRHS*RPwvAV4jZb$&7xB+9Ju z{6%Yx4#AjJ6cc%up6BXhwbJcGai`}`+oRuSV{30DJMj@-wP%u*TH3GJKM&iU{r={J z1pJLEIJCmNlsja;=Pm7>$DmLfW7fBYAf&_Sf;lvM~+$id@ zsb9A2pu`hme_(3Kub&Wjx5Xlw1BS^3%e9#v-pQ;t2iS$e%P*h1&2fU;(B(eor~Y*P zeFdGBmw%OcZxwN**{ABxtS!3n687d7`msS`4iKm1&Z!L#0kqL2odR_%e z>qPD;S`i>aAKE&;ZGUPizP<%Q1aqXDC3;D8a*qDXe zfu4n&0?6|zu9K=4zdsu!OgtBYnXu;R%Vgp~b{arQ&ZE9jm?{=S`F&u|UuK_c@A!zE zyW_{BGl31{AN1>==_=S-;!vIrEyN z!NjrH?u$P8^HCCiWh@pOPy5BlpzE5~$D3kBE>z5zkOD)mgB0vL2);xKOm^6>QC>~_ zwJ~ETrkkHBmx4^Aa*AUmFG^xNNCpyH%m#Oyyj0KZEIXs$lak}OQQS9#xtnor$`0fL zA$&Ps0Pji8K#$y_FP_3_<{Fi2lh-^~a=ULEd*=X&V$#IzUl$C|5Fn-58L zh9_-Uw1>3Icn4dcC>oV|J__~w54HYqc1y|ov>sd#SAJ!Z9Z0mh9n=@3nOrm z6I3Ml4MQ09>+5N=@yD=_D7K)(W1A(^C}XFJfffPs8EXG8A649D$&Bkl4Mu^QWUn2u zK3(8DQ~HaDoo@b=bXkaRwf|zV$@nvVvyCskCEtb@AYV8P<=Bq>CiM}G185Nl&Nu2A zwN791euPoD-WFC$E=#V}blwubsp>DTGl{cxC|XN}x%6U5r#kKequxn!Z+XwK(uTMp9~ib)7qeU{ZCu*kt|VRXf5UUh;TS zy+lu554!F9IKyK5v>1M&WxWXMxwmEuCd*#dkEf}YXe*5eN|D{CWSgn)$8HXfxq2*i zH{y=3dKfD=&r>aiKb2rdyrjsFt~xx;v3z>)&NJcw`V@;AThVB?&^ylQ2SE6ZD2UIzjW2?*sJ4eec>_EnE4zttvdK^Fp8a zt!6p9-Cx^3OWfVe#e_ticRl7_@efkS%g@i(n$AhO*zqAJp9RTZKY5~{n{0%RQdP7Z z35%P~BI=ZoWC}EJ;e~>alG5b;4VYn?6go%404LJvu+Y`r4)vJj$A_gKQU1 zLCxavov5^nl5Z~KK2$Wr{a~XHU$iBtMbg*JX;B-bg;CL!!QbbZL)Gs!X`mU!gmxAa zK~pVVS1(U3t*Y0zF5BD1F)M3WE{C0OXST4t@VnxZR7A$qqzSYN|H;khP$m=zJwZo9 zp+r9SmGa7ws|MDx1;ZEgSuQrJQA|T#+c>tjAvNHJcnPnJIP~3CMIu z3l(RhGF)o9|1}%gi3@n{qoe1?LbniT?aD&t9D_Gs(9#tGtd@o2WxsF7i=WQ8jTR#b z1`|a*sMEccMXhduBJkr&qf@5&#uJ#nqcndOP*)x8eQeH=XkOBqQQnw*kaUG0E8m*F z>_GBWsdK7mvFJ}PN0Ofl2A?eOpI?pciXF{gt+EKN=BN#OdwjTme=`hTwR#pOZD*Pn z64ax6d(U+c(~VXb$*6p3oZm@3j`$P80iBOw#(HKKRo|hoP8v`*9lU%~)m!|ginnO= zlM~o;_-E^Lp(1}daOE8C`a7eElNEZih0DL;QW{+!4Pyd@U8cT!2Q;KX1HRZ<7s6Vp zl!-p!>g=puK2f3tJI$be-aXV#+rjCXi>6}jhOP76)0OEL!s!Ej+Kq)%#^YKt$-MBh z(k#kD)n(!tO>C^rk$&gSHG2!eG-~zvOI6AF_iZfs`lpb01W{_<@LhqAk4Tq(R0RMy#VF`a7UX|x0JwNwAFzitcZpmL79#Y|L);yboJM7|_< z@O<%O6!w&v@+>B6H|-|1-#M=1eEwWNnoi)%byr%~*1}nUJ7NVh;-Bs3j|TKLXTg~N zZY6F{4RS;c`zK!XBueqY`;HocFgn`8smWQ!qf(<$C}+K~pYEexH5YPnmZuvN$-tAD zihM|6fB(X?AkEjrenaR7ZQ@W{4$;{`1#9b@sbJj6kc$|hHDSuReLD{{YnMm$xcVP4 z5nN@W?|+oLNSoRW9NexOd9Xa1C_cVt+_m;UWk-178k+n~>w2Q}-kx2Ut})ILTD%dt z5maE$wVSfBZIhg~qR-@!cwPZe{0f==RX!WVE9x znm+{E^>3nfR`IY)j`9pV@y53E~W1DGFsW`e7$C!pZw0bE;409lnw zL?57@3xhKLzX5VluLsB^OQ2Z*ewauCfI`ULKqWFJAsc`JA_Ryek8l&h#VDy?lM!@Y z5qZ-pd9%R=0YyfHi?XvJ09*C6fp7$Svc}1CCjsf~%EtLi=?VpU&-b#71!M-tpWbN_ zIgg2fDnA6{gJ2CTpd_hT-VJzW2aLv<8G@0FJcr+Gkrzv=-@@m;ka5pmEQk!?hbriw z2&5na$QT7p0?W>Ztq+F^;eiK3r;G||%Hf~aacoe_d_!vG=cA|*=gP$~dhQXR0_6n8 zUY*J1T#LzZnHRxpIwn5pkSp&8Xuw)n^7f3)@_|hd5BcE&cVOM@Y>r63xU{PizD;9r zC#f5RMq!As11R?3@b@z~CcusQaR#i!3~#R!;El`KXw!z3*<15|p_)Pgj|yPaQA_}W zBp1*vz$1A*;2~Hw8s|c9?bqL!hjumGnoyLjd*}kCwZ%S0u0QZD(9U?kbh5&{7@=#j z>0BHI>33g!)B*^SL_p>EC6-Qrg>ZoK2Xz?WgwH@Y?aY9mv-@Z`U^7j z*9t%$Ltw!s58FieJGq$vso(*@tr)=TNJ9=hIX?Urn3ai!9b*G`MF;Jm3;>G_On6Ur=AEk-(-duyl?fDgK& zyxxH~BREg6nr`(i5u^3{;+pO|eRV$8%ehEU1o7$|#>HBLLGkZVg_E>}pSO7ZY8N!-V!S4*M;trXz z%brlYUss0RrM;j0YHFJ&B&NO^c-9Dt~fC?A{$?qh=2@63H`5%gKX6fImu( zng!@?eZ+jl{ETo77ztlbM69oInGB`}K`>k3nRUYyMpuc0-vz~b9k828>(5m`Jzj$G z6%N_^pFfWPjAUIY(mDMqP_$W^zyG)e00kypqs5$!FRW{kw_cya1LMnaXn;g@`{OHX zbaF^zKs;X=Dm<~mIFK2lG#eQ*)Tc*y<>VGBc{Twb1Xp-?xXZVriZ^8j7Zq2 z{TI)6?;8pgEWfIwXTIrKlD_RO6^^Rj7)};yU$6N6N*N61U?^g_09G|HR}8s^T0pq7 zfCSZ+(KP}XJP8ge8HPW21~sjk3C*4FcHCT4d+rrV354E(U!v)dGkW9K(-F8-Bup1P zfiNa*((a=->+3B$v~|O`*JV%1Y)`5Zb{&>F0s;Tf)lRaWL)oYfz|-5W{(3xO(fa;* z!FlP0nr$!v>usQ8;rtCp@lalKQ;ZB0;}`{@xssn#UY0 zwa{4kY(~7s-mlHIfVSp(w0E91-%M^@DERyrM=fw9nfgY&#wLS@`19?46ynN(b;v@d zPq5z=Y!WNgK2KI#@AZM!;MoX?sVx4!b)W;cdhpq;Nt}mcuYV2QUbxEP5SSea0C0|g zSdL&Ix!1n%P*CXCgJOM002-y$ndpq5zpp*=d}?%E`TVF4s7~W0Mujz;Fe`xT@7ZFCRI7OFE|Ifd93-v=#75z=_;Rxz3B_1 z{AxvE;^)NIMI;A3anXXSmr&7rJUoImKIaI-gQWDVH0GIs!ZJt3-ZRh`4GuZdhoxfpY@Wx&_+HvHcEcsyC-*$I=9^7xKp&7m` zeV;vYw7tkb6H+0JCuT1HKMv!E7dyU}+N0aF6k$+L=B`u!J6|g`cbAzkKP~uA+ZlA{ zG|{NK^>a9OIq-jKuK#}rkN2Pd%4^{}+W-C;P005@yg;2o{%`*X<%`H4a*jKmVGujd zjssqFYv=T6I{6^v1T{cLz*|72JYf#SJ1F1X`QZD$(4?%GNZFW)OWwI6;0u0zVH64h zG@!8E4@I9l(tc}3|8ND{FM8~OIqA<;?GhlTz3{ocqXQ2U5!Yeats$xA&CZgha3J{N z1?U7+mJL$Y))6$jhj(v6vn_(aKS@0#c_3s@w*$5j4E>XDk?5`08|PWZ;L0eOSb5|& zQS}jrZazVwW*rNEoI_Gs-V2|5_J0U?GkygMgXngI{}`$fp|91 zZ-q|!{B9|o%)osMBnPDSi`%}R1zwqB^#Wq2Xr*)JU+07pW%;4pp%994!pBHSpdDc% zdTb382*Z&=2o704(5g{PRWlVIhY7KlqNwT2aCN$OxX(S-y* zP-ChEO3jZoZrt8OpP`mV_8ZXYT_sWjg&OR)&671r`aDS+Q9wgdF#<%FO((xXalpV_ z0{E|jWU>U5jPViba6;SU^+-m+(o^LAaw=u-FnG8TfXVYnJ$ZeTd=e?efk{3Dy)`m6 zv%WkQPdx!jgz}S{js5li1n&bEg%3N}2wp!sAnuq88bz__$X5GTflpiK9Ssc~3KZ6` zfy?nZl2S=0uj_+ctED zzz|1Qj~79ViW4x%k>2BpC6?Gm(MU|d?6m&IwBI1v#B%^j@rK{Oz7qk6a;-9FhB?Oq zJWt^?P~2T-*|78T|NepusngV@SdDv=TgzxBvHq2DepC^JZNH^H4HTBdZMm_epOp6f zmJ#p70u_F?{%WvR2;3SIBfc?-d9nen(NS=;!k|1x5EMOnh3^mDT>Q#SF{>WWxNpb+ zx?lq&@VjN}nhd*$q^~lWX%P~ILJH1 zjV>IFQ4#IF3UUSC`I!)TiRfz65qaq+;Ot(2WlhvZ|9pNZG_VjLo8vd?bgSc}*QuMy z&RR{qPo6>+=(HS9^4uWY; zA-e?c;r;333pq2JQQY%;12`u)GtkGu-8Z(y=#j)+^?;*Z9A@(08|yeK#24BHcU-Hi zYm?WZ*kWY+Q9kGk@@q4O~OgAZF-*kdwyuJeq@rjA+Ehy05IJ?gisKfxR*WNu3f^3mM^>}9(OL$TKJDoTVBxVh3^WX}zNqXL9q348htkz|20}|KV z@&Bze0UI5wq&5eogpMp~+hbz56W5;}dJbe5Zvvmrg*W?;UG8qaZC-O1N{ya@z2K7s z1z|&*U+qhaFV85}0(ETRHY~CQJHheD^&5pE3}c@#@ceJHT2@H>2+UOyRxTR<7rW$YJgoPG6f?5!rp$K;A7xvixHcRUaa&uK#fFt^7^``@z5)% zzPkd*kP)|Javy!OiZMNS22j4H;KYOM%jue1KOuk(Waows!PL_26z0MZl(G0T zJI9nHsnWV{XrHPOdTdfdj@J4R*>wiGhGgF2a*LP8tHlv?Kr#qic8 zhfnrVL{11>ct1t%gHrbk_Zyh{>IFfKbWsTc1h|nOAjv{aDflXfjlUr`TV-tAU=B@T#jFOu&!C zH;%)|(cHf30ES8z6VMV@^%hIO#*g_PlsHi1BW*e+5oyu_bvABK!3cO3l$P~n$K;}Q z{adzqk<9u47u;6CwXtlU&Z;vG-K|CSk0UMRbx{)%ESOV9gO@b#*wz2gC~`4#aZysY0UJc9Z)pvoquBS_?pR6qs{?eD z*uj@GDp`|W8QQBKA;3s!CI$OWSlq2S9{#N}d+-;qw(2XhrDwlc=ogj&+VVl~wP>f= z!%wr7GPj}^n-^h{tx)8R-t&ZewIXeE4;26C$k^MnL*P`5RM5GtOJ7$HfByVPeCc6n zJC}Z=OYMjY*CBx?JJ{nMZyRn#NNo2BRvY; zp>cYKy2kSqR4xCOeD?q|<}nW{wcn>S-z6;qtM^+l+7;~zI(o_3pWMQ#7*Mh!zrBQV zk)v*^0v>8g79M^u7gvEE#2H=Gowz{JdWkIsq}gDnSH?kyx|+|NX57}&+5DAd&AjAp zn$36OTMdO0kPnwZT)%q@O$yi7a&z#Y5kD1-aIfC^IG5Pd5V?mB3(0D}DShZ2v3<}- zvmxwhZOja02YhYxPf+y!xf~0-(kDb11p%E11JAlCJvq*hW27Y31#-H=9__&&`OZ3L z;9+^G!RAN#eW}B|$?wcSJV~%?nkIMQgTAPqb+jA* zr7sI5OW*dYeFK;-EKu{^S=Tq4J^((Ty%^DRy^2biHq2QQ-0nYk7fIO6QwaiM_4~f3 z!|*^dFywNH(8!mO}&W=(xW$yDOQ!X@28Kpi!E z+{#d~7U?R_P=|M3iuM}kngOy^oSxHzsh(Zt+vudCqAS)P}E2mJ)AolPL zs)TR@YfTqAjWiG76;HvY7DUfHoWDLoOXypAJKxJKRcvicM7Xh4084b#dh!hAQ!9kg zyAcNu2$#?F3rkxG4kiuB5H3PT1vW~JC&lHS$+9`;yvl`WI+)*x7$6!Ti-*3nA86*5Z^1oD(8pM*tk7kdAVBf$J1t4QQS-4*hd|tiP*vUus%I$z&zIcR!h5H~X4+`6R5mt$NP2Y}q`g*xL<%*SH zI?xR5cRn`So@Exb(c{akqic3t#O@pU*S z`WYS0(L%773tL&a4y?aFe#{ijja^HN+{_!bJAuM1QH zD*qzgQUHozlYskr6V}D73uEz`uA8=;9E&oII9;RnL4_=Ga?9-CM}cF8@&Ie3tWOP>1piVBe4#riWz3 z!~1!S5E9mJqm`eY43Tv3n0&xf7<0lCQyLY38Dn9VFtxjYUX0{MJ22vHngKdtS{^^Sr?LY&e|MGe}EEzb)!xJ+P@O(Jk;K4yfoRo`Ad;Hm~)Yur-h_%(`(2&Zf7cd959& z9hFHprgbD}p+IougnkTMK|V0lA|}WXRGh>IQ8KQA&QAp}B?5Cd3^aNx|ZwgckMmdLFG?DRb71P?vBqn=-DfdTw@ zarqZJYjCvtsuo=>18fFpj(}4a=$Qd1_0;v3>|A7jZU%aWarcz1_$z#2(9U{Bl%N4M zN{=3>j9qnYr3llRSFtIfa%hAd8Z{8s_jZOy_6h;_47s$d+Z)}POl2g1fJxD1S=&xw z_&zK{|46-W{|gFUnteU9200kWYQOzE_$PJ;+wj}nZv&P1x6(hWxD`&>w}$)~%OC3R z!`C9l`Uv@NeUk_mf8bZd@&L05^LrPnQIRm*!f=}B&kotPng(I6^@l`uo{|D4VUL9Q z?<%vf%hlQCF-mh@hCX1|zc^}Ndmp!=ydtn~)cS89!5UqO;(F-Yx>Y zk4UGndAkM^rE@Lp3;HD>f?ZekK3V)1<;>k*QcG1brru|lM>TviI}Lj9b;nQxcg;h2ue znT!kf20Cw5ussOQaBy%!t5E)vXry}7BW|YziKI!c&1*}k6RZYS3AH5LEd@2bgU2Zj2+7RIKJ3L;@R;9q}#P>Uq7&y6jJ4k5D54w^10vrz*^NFW6t1f{4%015WU&MQ5KHlJ8d9jKHC12j{!5JzCT(jpl*n7Y)D z1MR=v<)+=9>h6?g$;aOw#>rbB!>pJ!clVznhL?S}e($s&Wxt)VUUlp6ms&IAnn{cf zyqE*@xPO)_n8nGEfP%zaA}-v$JW(<&9Xc}rcJ_17z!Es)Irm!cjlA;Pw+^|t>H~xl zC`*ZI!G2h3`=)7KNJj}b$doy4>xu{f{`kt*vB9W;c=(W=wPHp5s9Paw&6SNzbB9uS6}=tY#w*kABdZP zrT(`nlO(?yj&jLc^DQU~L%9mhJiXU5f(jp@B7Twg@eN7uLIQIOO-SxfY6 z`O+Ws#m{O(QFV0P^eg4q)ie$H)d|phf zP+VGai{9<78_eq_2b@r^6%kd~PQ$KEC0&55wG@7`SZ=a-@oS;*>Hc)*i9%s!Cy#m$ zZuAFd?4)N42j@f9Oskhp*$)SEgX?lPn+dIFJ|YcMt`Ppk4vWesjhsQf zPXn7dxz7FFkIVESd`n^*gudyJfjyJ4_C3)&E;ya5DW6!X1}y0Vl1Hf4)erA}^;6j5 zAH#y7pJ4DGdhmGpWdA!6L3hfU!=({T^>vb6_eS)&Ex{^cn#{Wjv0d{s`{>!PvE2j% zJeqGU9M4EU3uAZt+;Cx5$9hg`(#<#P1cb?rIJVV4rw=2?wT4|5BC;jT(K9*olTMQ8 zf1KyDqOEfQkz-I=T>qK*|3vR~I5vw!-7QBBP*>VfVO}(vxK1?A2U62|P=9|e-fKQ{ znhtFs$HAr@e{n_bzoGVPo^uM)$S0ULt;O5uiQP#zHs;r_&Kelxqu+vlm)62=qo_}MP zGkr*7TNW(D$acz2u#XezP30dnxkC+8cUtA5ei$iU@_(>ya)c#8Qd;%M{Q42-n6}o| zeQmdHo>=o@2Y&*##_i|Mos)lWb`R2q%0Fo7>ay3>Rix}f3GLcwKa8pwq;t?8&R-8? z1`u&DgX0@n2#wpnzZI7vDjz{I46;TM3ma_W{rT57S}S(%ZIGP+3+W0Zy1`Jy1ZP07 z0OD{6^VC**KT26GM{iZ5%Ya6|nKr&~yDq>V01mGy)*RggC!J|ZVAO$xnrHAFN!q{j zB3$>Jz4bi+2>VbYybq>D3~MI*)kPSp3HcDVp8q1tY#X_{8>RIg(xT*r!h=DsVJlpO z$B2UxRZLTPdqLVZ8g-a{Sy|p@XqLSv0ve>V_&w5KpV`m&B@LTPZJ_UvD@4p!{rxy0 zk>W15Al=}^+7GBRYVs0KKptuZz* zx-S?w_xJR&GHHl5YkCc|3L<5dzyCvfbr}rKU7mFF1GIS)-rv+I1+6tC+X0c3X|Fr# z#$yKmp>>3n@*f^_F&kBSmiqu)9RMhijGd~4y_4;Xc^?dQeVl?+4bN7L8U2~e`yipD|) zl?HW)Wf^9?LjN}XM@rB}Ya{<@y+4JDSReKD57n>obD>-|2F_WHBDEU&V6-&^@tMmQ z`XR^?=U-#V+B{(pkgOq7byQ1%H6#s9U_5U>!XZ<2a z{>MDD2}9qD{7`?i(Pqd$uKYzti*D}<+5IcRU;y*(hfWP<#jT3=qoy0_JR}>w**eMZ z;R0>c9Xnl)BA=^UZJ`gG*x`R|15}d4x;bsDTEt-1^kaQi6EAAtWcJ>QcTHkV=jtWo zyYy{TtM)TagzoCE?}!bFI!g|RP;l6p!yEjs^wX>C$cMHYlRYvYdM`PG#8LNnochTt zLg8=;jMY^a7Z3Itc>dS3uB#vP$wdpgZEQw^1=ZC>@z(d!^5K%m4Nm`)7v8Wh6&P2CU;a@){9 z=V-)w7giJI^q)W$70CO*ywu$OmvKq^)PWz@QK##qw!&_dZOAH*>_|s~QsM2}5d>Tp z?DB6+(`RlOWM9B%8L22je=2KZi@AK+AE1(t_LxDn)h&C7)~aTUHEhpx+l&tYM&~bJ=&#m%XpVw*SpA$GT&r^PIl=2Ka~ z?-N4_!Q>8V$~ziA-*Q8)56LI8#4=}LNe%-EWD@QiZZ3ve315D?2$c&7?%R zO#h;yMBelX-x3D_Ew_ubk@-1Y;>`2&@%TFQY*-}zcx@(HHqQ?%Cm`M+e zgfZ9Mw7rqnm^G!HO1lt5b-I~Ezjylg=s(P)o_!xl4l=^bt|~{Puv^p^Hib)*!I6l7WwJ_#IkuJ zoNQCv!Th>q30+Q`Dh|vsue%(H9X)nXZ1PfM{+$O}A5xS9clD4hySzdkCMY?`==Wr4 z+^Y98t@J@FxJ#-aDi5e_cZ`KMoxb7bDqZ}$OgakH+33*i649DJ&4<@*Sb9R5&d%i_ zvy0k}23sx<^D4#loXllc-KWcuV7fGE8N#hwUD;O{t}9(8Ez(eRHfA?($V;JoUn_s< zxCI;y?V9d0Lx^i`1_+!VN;ct2DT{_8-i!7&HcuuO47m;$SrR%#R*2yV7Hd;ER|l|G zX48E`RI&QkkMP#?0l9og!TG(9BQ;g(!0EqG*JgPBG@(wW@rg-0iJC?<6W+UpI>tIs zJaA-n8iqPU@WrOC!Bipy&aJj7u7_u9iESBm~ zUAacY$OxmdBwAFrF7@fQw`RWR@|Ssa3A?nAIB>T-dv%%^)BlT!#^r2? z8lq`RxbgdBrly93o%S0$7g;iNcC7pEUU7$MzgiPHzf+sNS=f2kk{lhrUbnez#2I12 zxWwnAN_~=MP;!N7YY>O?JMNF0&frSc1}vjgSVG4JN{?H}-~>ucCGdsrZ%p=n;ZAXBwJl;qa-bWoe^;J|xk*3*0Oy~2c{WM0~p-dzF z3MNEu$F;?@ElOKV`;Bq$t5Pmf;mGZon_WT+O{Nen+rMo0dc&5=UVW*DmN^xAgOM@i z9i>$u)LQ7CDYxgyo*HS6*Rw6O=;&b)u0u)C-;F3sKRtwA5mL*VV%pH%=$2zvGxFYe zYg3vo(gVg#*6RCfNlUZo-Nj3*m{d@b_A z-49^9US%~bDKIg3Za`y~S&b{58)I(HTwBcXjCq;kON+CNNf&;x`nYZGb9nG-i)xHm zJFV1}a7aJPzIZAy+s;8I5@-MBl%bUAhg?gWZZTMCg9c>zpMt@)w%BU3>@;@w>e!|FK^1RzC z;UX@d?~M&u@OC-JK}v}=FM8$5kXwH3+lrX#Sm`)dR@WFGl95^Ou2#z?q>1Eqok-0tc2 z*qS5vQROoN_s&LsSyJWl!q<5BzkevmTZdNsSm%2-s@*$hqET8KP?Jzy278xlSSXU8|o5r;pbZKvrojD$BoiQ#@K5c~+$Ge0>s& z;n;%JY%2K@`ppGSx4!F-9njBNPLuDow`eGejuqt|Iy({UTwWljir=08( zuG;KZIEoFYeODtj-XlMavJ9_Nd!65vw_k{+u~hxZo^%me{U~aTZ0?hvo|){2r@`n5 z4G>N9Ia??(9b6C+-`GTzW9rcQi+!u+To_TOntfoBymBi>CWC2JU)jgZ5{jxlM3WWU zrYl@VA5Gj+y>dBaC`TeiM)J!q^8c8AG3m#rdg7R|g#FuScS(xtIF5&MV}E)CpI~|! zIvscs3ObpND`tg?rr48TnWFilNd3mD18WQ`UQLP3$#TMdCFU0Hl31}x)B9s3?GF4^ zEI5-geTl1&7y3+@n9(x?xmE4Y_&Mx6^Q6bqG^5;;QT6gUl#icvMN)NX^?l^C2OI4o z4xOI}?($tK+SPSWhU>+OP1%#mGn$SeU){;+Z%_Z)A9-$#F}XGm|IsA?47IQlg_u*w z!?$OCa3Z-m%Pb}%&9lChUnXr?>e3aiUECZL7W{mnR?Mrpu9&?jT1-;a%cD!9b?xIV zVY1!{pV=2^?escP3NB$Yqi&l1$(RN%!D$t5^)iFy`)NC&`uS^E-%Z;eohRW5rWW;~ zQd?vAqDWnGkL^n{)6z}(&JG8LX2%R1JIh|m6G6o$FDW(DN8t;i4hb;_+9AtYEoV$$ zN|o;!8kZ+wkeJ)Ea<9v7RBebjA?im8;T&q@qRIH7+x&mYSqQ(lVHnM8xX`5}I+>k% z%3wC(;?mFQp~1+8Q5!Aw4{scoV>K;D?pG0IzX|88+^|X4!^$F0o5via)iG?r7v71~^s(`UB^fnSvf_lR@wjcElj_fqW9>gb&o=$M zdp(*PRhyoY!tb4#d8zw3nj-oVB#EoL^9dy~MTE*VMPEvaTXS6hYV-S#{`Rd7c76CC z#W{BiCll+G74x-3mwJ+EJEn}OVB`VFM! zb$_X6&aFCI8-e{o#_wz;y#C`E=vDL|)IQQaYg^oW?WuR?Rt=>34yOIY;04vua4d2P z`j)f>K*87JDJ&W_wkeXM9b*|vB$91O0lQ_PpLT}z&-_3E#M>w@4)I@eah5_AlaKyc zv0{In(ib<}y1*f{GrZ%P+@L}76}L&RnpfJU_~JZE!lAJNJ9h9ljCC^fPZH)9M?A*- z9265-u$F}J<2kmIBJ1Yxr;OCisIz}eAk6bTvlaFn=Q{H-6ESuE8y($&3BD@UE4ON_ zbA-}u^n~WaRYMSOiC^;=XG-^*jOGLj8E_7AkjK%J5phgflj%DjJELlb>_9fm^%=qg zj|4dt>#-Iq0UJ|e-cVV_zU0_S$LOuq-&Y1L+qx5SGJM5pQu@X?`>qb!&Q4&MR5gzU=@j*ioaStWe8Z;+i3$*v@L@&7&Mxsce|F z)G#jleff=T#a@k%8{GZ-SZMksoeX1sf8Fo3Q~vVnPGo60ZpK6SuNVJuTA2SCXI7`k zdD2@qOoi_9>2>_a&7?PDEZdyds=qhmorI-J{|c=jAIbJuY*|Y#$H~r^QqTU!kD`Aq zPyRhO?aSByxWn|_sB{&OoGuEk6u<=jT-boL*FS+1a$Z3l{{7GTZ->AB*NHD}LH+49 z^n)6=?*4x}QCrZUCGAs}Uyw{=+W^u`u;p2ex5wbq>7fR|1?pS^Iem*FaEJag#^}ez zGN-Vx-dR!nn5)*{d2()H{c& z4jtY2h@VO7e?6jhNrpfX4+AG|%kY!(jqgPbyO9&8e%lkbd%lbLMl6v>*X2Yu&IR39 z^y%-H9=oY&cEd?hU-|d)N4IT+Hj?cBA74q^#v6$>7Y`crb2p}&d2k1LQvFydH(W#M zhyp8S{f^4FVt&Z1{~7CW<`>y~3?(~7*=U%S+5o(tjORV@L~9uH}o!myegH!gM!6L%T59Pu`W>L?i#Bbk&j$hthaGU=50 z!dyO>TM%-G%BWoVtJ8FNXXz! zd^x6V0F^yn+GP~UL&j)KyA_T`T`r%K0zr;gD2B8>htw_yrY8${uN`x9cv>6r)4kcF z$TML`M^vW$p7WrR9Jff=jQr`ivQe6bh5}57?qGZOJN$8l}!?JaUS)}pPei+4iL zbBdE^j=8?*hsKQpjP{f>hsIepG-QtDo_r z)gZdT>x4aD$s=u1$$oYI-k0sX)eUI(WVHMFTi>H3Zf80T1P=Xp$QmZcBCeGIdDNYU zaq|r_rjYrut=c^6wW6`#HC@^%z$LaSB!9)*ebOF2V30KKPZy^0uJeB0#eYc=^b;Z zirAzuB>KE5g={)6eP(86Dw0jA26_h#&XCDj14?A{&_<(y)py}xqO8%+w!_Ht(YMec z=y0zPIf8zld1jCSP#a2$3kp(h$+r^|9}M8B2HQp$s!LfNURJwt$rmVd3S(`liID%^ zq@fDwr_WA7%t)ws^nvV5%m*)i$l2OST1FBvMKZnW-GDh)3)M6TGhbPSi_?Ipby*}b z0IGnw-2Wj%0J>-xl1IIIz6QCK#_ou_XapZ#-()L@JsuVZMeQSybFQwzYZL~e=4)u@ zGpG9?G4$~H^KH&F%95gmMcnyx5CJg>lA&IRmM=;wh5R$Ecj#4{NHM1}H;(gU;OmA7 z79KhZ8kAY&mpFD$RRE>S`Mw*1@2jMi zm6-q$=YuyvAiPerN14VYgTDOBbs8t5N@He1L00A%X$6RmuYpM4=7nYUuo@Nh2z45s_HP6!^e3dqzHX4A z8A-3%zoJT8*LTc87IrNp4jlynfSE+iOq9-kL4%{jSB1UDmG<+h7Q#5D6dD$qvHF=P zAet>6&on;B{mQV8Ayk~csxf#smI&!=9@XlqoI!KMQCPCakQoSSnCQ$=4Pvq!VKQ_bo^iy8rFeo;_}tg80a zaiyUgyby%A!SAj6k5Q3i2AEk#=887Gt`9ZYOuTKd4_G;AiJmZk+svt=g-M+$kMKJTG4QRvtJq>80XfTZzk~$vP z=eMcb+`hdnK<3xeV>v{>Ck2q(X?$}}ist!0ZfR}W55wZT2KA{(Yz6e;g`Z<<0 z=6s1jOp&85B+__+x*#(Lvl@|5A32|o4xNVSC?O@~I?Rp+2ceNu7Q%#0g+TdZno!9} z+jDTKQ7(n)t5XedqlDt*Cy#?J2woMZ{CHQ_^+iZ5osbY}!y{u6(_X%xocPzjrkVPC z2*DqNwBi>{ai;#v?V6dDzOcFyfEm*A*%xSL87v17PW}QBgPV^Yv<#M#zdlkQ4K?J& zoq>B%4NU1|Z^!~;g#vw$Zey}kUkI8RFnfB}l2_&lIGV5G6m$fDeascdlFdE?4MLu2 zEm9}bL=X~7Z@G)};z1zl6q35r+Ny$^} zQ9Oejn_Ze7Y%Z}Uuo_O(??ZL|rKPQH?R2kg-4$?9(M`nBJXe3IEtrzx3K|B0~=lpQZ zoAap&>3VtgMc=-W8ArKM$HabVeBTH<#garGuGn9~Am4zk`#%vB`VNffliy?9Z1ax` zrO)Z1V~Av*Yb)aP``qF8sdO_vUxt1(@&luj-c9~hyoH|Y1OJC!?wg8R*J1;c*IAqW z0d?E&Fh2jY9n?VuI(!8)N>9jQfrrm;Wz2Q{WdRLu`5Tz{&skKJ;(gPI&bImFlv0l(zrz+=&fCmHr9*FgX8z zvCDP(HWz1%&ov0HmYHoF=%6{peR%zEOu-2sr-p!e{5O@+Iqr=EV$GAH9+2s!gyE>9 zQ*A#P$b0^eMr+TcBe?Ln{pr!)pk>mbRkrfpg^j0MzXB@O?b`fNQ&Pdezp*aVHedkD z;6bY9WN5rN5t4p*RS$ZxC4ZYlLIP=OXjH767-r-9@P?qL)nwiLIy6~W^-a}fg@Aj# zG{7Saitr)rzkp~H>OED|At6+%`s9#vQa$aRchGBd$kSKwTp{QZ-q=x3*6psB1I-6F zZlThd%QlnOyG-id*R}woi5GO8o*>t;vFxpszsqUd#})fw69e{NFQU~K_XX#g$-;m# zlPd&O1Ns<*gc=RLH@T{*I_a<21j1?_Fz$>O=f7JLW(cz?0r({$eIC3>I)|B@_2NjP z#cF`x@XYv^*S+iI4Zsj!ypKkq&h^1^E0n6688$murIc{HUcz^=>+de00Vfo}*^p_2 zX!vjcQg1?5P)M(f2FuM(#C<|?u2GH^f2PVu@^qkA!enQ*MS^t$_Z*En5Ccr)fofG+ zaj$Dj9oXZB3eCX#&O#rbXi<|n=7f{d!J!wy_6!>z=kR-jkZf_HZXia-`h5)q2IN== z914HF{ApWc!ogn$M$pxzLmrThUlVc0sRp8mr$Fwk0kQC#HRJ<2rJ`_4R&{UAYoy%Y z%v1}s>f^9zm_`pEdHZGa(bM~)7wg2TsyDNeHGv!UNj8}K`WuJ7RyPg2M&?`JpO3v5uBX)5!i^r7;3fl+V9@0BpWdweT9tA(&D_AQO7G@vy0{HulRh zN7wDRvX|%Di0(j;(K#r!%8V7(iqy^ISB=w5lqg#MrL<6XV{L7KhQ22B>Bpwz^z=Yw zLwi3{_b%G4!ok~=75J#kBoRsXq>>>)#2Kpm;(=vz8R@Ijx!YAD<0t;SvdnN+s!0#j5<*979w@U&6w3&1nfp z$yb;-7e|{k5m)kROBpgRKqW~x&n|FphCr#L?NSsNGDf1yL*d{u6xCGPG|w(?q{=zq$el8g0{WP6i02K86C|mox46!oLXK2 z{mKxiB$-P;fyV!`ZvMrDvuX&KDtJ&UJYv@|TyW_Pg#sFqct~Q)A>NDp9)pvml1J=v zZO}HSh(d_S(9l?7OmhpUu9%6FTBnJFqhKetUSFi~q4`aWz`kSD$9kntVV!`G z*d*1EQ1cZgnE1_|pzW801BnJ>aDrvRr+ufr5%;8v#3KkJs0BNaEZcmxfqWlV4+B^x zm&W}(9uN_pV|1JA<9re~2@nOIvG(*-mMmg#k-tz!oB}RPN?K_4;U*9`V(62M8Mo13 z%r4Fl5CtzTjHOyr${0QKd5hojKihe#kvh{8RB;V3gLg}vs-sdz91#``9;vV?WDt)Ox4qB6Csf&fU)vs;YX^VI;uMyKc$v*N9`!8-?dg2Sx z8T1dCY}th3e9O3V|2QsAK5)VGVCtqfKqv6x%3?z_DVWNH4f51s7Pw2{=r8jXYyVmq z=&c4sJZrS<8x3vkgoo9(wzjU*cezQnoiILBnGE^H-BKaDwGH17(ku%Cme`;CC?)LU zws5ygfX-`z+QT$-yO9q3MST4*~?FOFH>fmC(HxI0#-hk_8-1pQ{|Mlh3 z&ZGEK@(xjm&s|cgKtTyN04wTm;2$}|&}EC(A?*R}ET*v^G6}C8xOi=%fqKqF`5|)^ z`%ahfW4_aX2`p?{O?gn5wyWGjcr??GrlL7=i80&rv)?8Jvo z7s0<~k~XbqO~1HlyNqFo8WZ_(qh}6W4%J{yc!$D$XMaMCNu1ltM0zMYC0Yx=`0A(_7yA=c5qADke;Wz zOKPC!B$;|kxKH$eb6zBy-RI8v-kYS!fB`4@>B5CV`>vd8Xq|L}WLk>J%qud~;C|8F z9aJ2i50yeSGd}&g-UWmmcwgLgj=|IT^81@DSLV!Ci^ze2lO(}<3_}q{jKtq{n(d$D zO}MSQ4(PcWOowKF%9Ek-B#xMht90YT}Iq?4m~!lYAAPAl;pwtvgl6RKo&z$|Y|MXz*Q z&4-pFfn1r{$s5}aVK85?{ z->fb*DeNTxhgVkh;;eUZ;b)+FHv3JcHkWt^N3)VRdOz|XzjL}SFTvg}%AEMR=0ey_ z6ZM;(-7FP_b|+3aX`>_OH*tT>OxFP(#o z3X6{}!|ev?wX|K_r3q7Qjl{afv*zEXR;Q7HoUjU7IV4lI+biGCsxeh2cYI0d|J5pR z+g~Ns#3l8?9_-=o8U^_(*=`&Xu1QmD4S9f%4bO{f*1p%{)@pcslmE6lDR!xnGm|)d zt0825IB>gi$;$A4-l5kN@p z1)@a_g`dbb{r3yL0)%AzM_d+&vKgkNq>!f(6w=9;czWf>!|kh~Y0o(_O``3##=A}R zDk2z}9k-U*03_YIW`THV;Jmk~H-*%c1EaPEV2ea=4Na+@{Bvv*37c5Ie)fCrr7{T% z__0B)^7z`4j=dj#k&1^M1lV?cG`Z>X{mj6ksUdL%n7C=)ZSxNVLq1YsXe-I3tK)Xf zh0~SjRp@Lk1IN=tMwSQF8i^w}tbPTYRSnlp)w#N9b5x2RH}H3aU~P6W>ns|fsxMiR zL3VL;+BPalwg?n@nb1y{>xrsv&b@aBwtp{alJ_NmruGXkF^-?^^$yL~ozi}ja_SvO zmEHGEU2Fqvj=gAQ*f9R%iNdrmRH2I|+MnYAHcB;-3E^05)l|a+(io2m&%t3Sy&#HO z?rN*gucsL*7sAiPe^TU7H6RNZ=7+Xtb)PWZF5QkqVCh@zQROI6?Z+&A*Qd(XxIF+~a^!=Rn;seI~(V>ubpJL9szlUU85*cEhxGW;-c4 zI4Fn%bIqzNC!zf!Vj-<+f8*C1>$al}vC;s9wgPy<`Nw@GQDS}x0Z>-%Igosie+<*} zwB=Cs%Q?^o)233FaKxJ_Rp$vG{Dqq51Gv_L$gnE}dbK9_cha5{*;ST5zf|O`O&xQ^ zbOLnb1aPMZ`J6)waMYEBM?OQc3==*yC*8X4O~S*m*3|pjKi=+02{7bs03Yfw06emy ztijfJc`U3;g$qQl%(7K}tP|4n<%7{Gj-P(Ydm@$vQAz;`2_Oa>0qWVmK4amGr6m7o zF?6ClLA#M)J&593deGXM7Xt2q^0YrFU#yKKo2+P|`aoLyZ_wl}@}aKm>$*3H?#l5| zc9#@>fq+J8g@BM@-+^YFQ%(>061J{Yv=jD|X77SaxPl$8dl%g^09xyc&FO|>pd7}V zGw2iwp%f(m`Gn^{kfgdbIc5!y;BCqgGxuW>^VYmc<830IbJkrJ1T#vvb?6czh%Gto zkOTbE8t@>~gDu(whGH)nj*@6#ALmw0a3L!%a|jP=bjHPOqZ|AxA}_O}L@z*dAl5zO z+(VwXe1L5gO!X-0s;ZFYT#qX({SMw(vsWiZyvJ8Iy4df-7}R~W8U z4ESjg~gVBilPWk=0bSJJiffe14j@5cLEMI<|F~jGnE}ImNn1Og`iO`A{t>{jalS6#c+8LtqZ2t9 zRgM6TSznfaIQ$()|%;q!q>b-KOW5E7rV{js#;-4V6oJ5KBq&% zVdTkPfAXTs93?+sd?mP^w%#i-wI4Q7zF;X$YjB&ht#)2A)aAJ6+o_rcUnN2XSjQtj z?ogNd`On^?gNp-xID5&eHY}aS%DJbFCF6Ip5nIFYRaO+{iVO(I#y96ZcH`IOZcR;v z2(0Nrap%_{QvMF{u#^C8%85}J@1RjfWLWW_&5F#CosHlm6m8$YOSPVovC>n^43Gd4 zYck?HTfvTp=obILYWqz9-@R`=IbRFT>JY4UubyywU4!pqu7{LVu=_m`URoS@6OUCobiCCyJ}DS(Q}Jn zPtvXozmkS~^Gw3jjqmYapJFRtt&F+56s#w^zAyH}h1C;>#Ws$>T>tXFQyU=9v8dzz z4AFGs8yfdA*W8LGH&TeS(rh0?Z!Jl4M z@xL$gC#0r+--xzUMxOZ%eQUKtt*?868$DwET#!5!$%1lqEsfc|P!+sE*2FyjabY;v zw`g|b*7DfK1$k6omXZIQ`p=hN5QovN#BWzN-TJdGuYZjIsY8=*@-?7n>zxQ^(``ymJ_oP1`9HpI5{rbO~@=w-Ck}PCJf6hSM zab)A)_rG&d#<)>f55|&=)PF(aPj$Z=(72yd`gyYZ!fQwLiD~TNaa!+@|Jh!#`6)r1 zKd;sPb$R^?D7MGmboL2!0Yi0q93DPUzr}LqpY;RSk_(EjyHB<#73bTHu-ds^J@Gw8 zI5#Z)uQWpmR3m9%5pU=BKL&!CG1TQK0cNZ=aN>?+^hgYTTI{j3D57;bJ#(Ep#5E>b zJLnV`GH-&G%bKzztEDt1Im_)jyneN;`>|2d^gl7AbU=KaLBp&Tfq)S~DQY1Y64&hF zyr}-nRL!>mhw`gVi(93Be&Ec9rezo?_^0@-MjyKJyInYsnsk9l2V2%u@(&!RK)UVWYWq*^i9D-Y zYhK6U={mma5UQCse*E^^H@K&1fbYK4MW4!C!oR9GY9r7 zepSS;&34RVO@=fwmKc2)WHj~4s6NFLbD34o>(?ePZ6*xw4Q`52D_)}wh3e-r5(bA% zR*3lDQ$^l3h4trs5weq7(!@#yJcHeJCT4Z_2)KwtOf-;`RfW_ObBHm&Xirfpao33E z`{$k8bfc=ecF*awMwC^)2467J74zVH=<03$CB@d7#7ZtZfQ`Ym9X`v8VME3-Vk zG7=Ml=&krs0i8Y!X8cp?MF`k90~~};(N5iRJ7xT~*!^)5uJ`@Mb9Cnnbv(SYk)9EI zoXffTJ#}RJ-V>uZB-ku)VmY(l&C0>T;-;*H+>B)V!9SrsQM1n%F7e*HcxhwWuyGsL z8u8P?GH~Dh_7aKx5T`>M=LZxUut!~V_Rsk>V_ET>xg*=!rT#oX9%|G7SJQd;vmLc< zyhCZLt=8T;jH;0u6D1+hs|BKDrI=Xu}v zKlq)`=Q`)yzw3PO`}%J-`IRg5dxeyML)dhKv&&_vfV|wM!KK(<<;gZ*Z`b6h)n~@W za}T)&EtpdXmufj1>IAOh{j-KhQKlI@ms1>4;Qt5l{jX@Q=y3jLZYStc+K>uj8FSk zXS{^^|D(G0zM?%a-@m>s(=k3XYsBfZ)_GqALw}Ed`TvWxd{_F9&wNfiKBi0+U(q|d z^sxml-N(^!(8>85Dd?u{&z1RCt1~@~{@rCJJSc^&jE3FUSnjCfb90cf^EH2tqQX2! znk%jah7g6~()F^o7riFN`Y$Z5d><`-R-F^@+3r6pdx;zETX~{Cs^xFq>K-;=Dy8AS z4?Ro0`dMFJf3%>&prdj{=q+v3owuxZ@#$GNUtb|5d!3IA4?p~G4ca?epz)DxvabCf z$=I9yY02V(wAHaIcz)Ym8y0qN`nz{m)bd>M2!mT%M%$nZ>MnC}LI=`;+LukTLXh^K zi2?<)UUH;2@_dw645a>!wv90cBT87iR~k$*N{~!px364c+|{}Ul?0C6|9tIdr<|gggPl-zyVdDufDCT`jW~ zFevMtB{{Ouc+mf^P`=yLCSLj7v)0ngP->vz`+Dk7mXH66j&p(OiTP-qnfCwPI>X08 z=5pGMHW!G+Yghh$@P3(<{x}P8D7`SxtkUAy&^z688h0-DT#H}sw)A6%cwwG49)1y; z0DQu882@9mNC=S;r}!!@Y0qKH#-#R-C`Ob%+1(SDEC#@6q78)OMk57O@U}7%<>;v5 z{>NkB-<6prTqrh^%39)V(ldY>`jWkwO!9M-kr>U;4#$u%hTs{EzZuPwqiX7TAoQma zUVy(`rsE>gL28OBOSfOYddEY9Jhx{IT}(2ImM-Kc=|?ZMmAR=_8|$$H9qL~fk0sU! zK?@D{w~hXxO8ZREQZQfa7Rl7n_~NdwLhTP;$RJ_;x=Kle=KPEx_y5DA_A`u?S=lYw zK!xrEHEq5KIpe1rQ40;BVa{U(sNiIch%wB1{IUi7sda~%7D@YL}sZ=$S<@}Yo700`f zn=hYmmGf_2KFl!W^mR9|;}w#X-O|+b@6Z3dY@;;|l^?Ax5jLf<`M(qV_c8IZeKOY% zvClaRDuxMm3OwQ1c}>SDEUB!Mo!*N5nhQMJc?EOed{%+}P(V2UB(Hh?m_`XypMNy= zZ2Yxy4d+0^ExGnC3h|Hw1UzVZYCEXFZA4FNvOdm^E`AR%gny`SQ`nhwm5L}cvM z&0_MQpjB*M8HySNv`n2XH3eZ$^c@%4w)jeQyrR=TO=^j`=eBWRlN;C~Z0H;NW;#f0 zvxWF6!|tS1MP$Xig_#f6P*4%Z-X@%>y4b zF09mB?lQdV-bbuAKLGlV{tQ=(Pp&p3IP_t7}duhAOZW80`$x>x z`n~z_W%-c#DcB>%3V$^7X`GY%r&709dV@9v17m;SAgM~@a)(4G=uY^aB=urR0&0)Tb1f$6`3^!8+;WPEJ$vN|JMW7f-+5I!T%NW4 z-JlJZ`XLic>kw9|m=Ewey+G*ZhBxk9{dU^3*>%l&hQDHf3s+d}kopX)T)*+!P=COO zij27H>xu`D2OQi~ObKUBHFt{Cu<1i75@ecwlbS;FgX?%AvwxcBbb}hlDuddXL%(QC zQ+wBf(Zfpnr^vz9lOblzv4EipD{!hMicGolZMC`L znLhBe>JP{OdN*i}N9WxM`svEm*Rjfw4vG7fC?%|>=S$rbfT-qtuF%|P(Q&Z`j?%~YVT%XSjkoU)q6LGYE0C80B4QPyND)Pm3yGT0r9$VKe*@BmOq_2_pGf|D(@ z8p-n}F^yKJoJIv&E>6-#3eb?}=g@83VBLE9rc3|c%RU3jaJkJ}$zdmf~h2L za1%tf+HD_NS5(t1aeXjGXJ%_TaWUci#=*>EHx4wOR=;dn|58|AfPXXi`baxR7G)sc zM=Xxa&S)F>*F+yjy@Bq+^HptF0DqQk?(TO>R*!Wj&M8VO-EN45PCuJEh!GJLe~xLy zoN^{}!R4`<^_;=3Gr8znNx?qGefq~aUSre#?Y;{?VpHELT0axX3qV?aCld?k(x#2R zRzEHBY|^SAb9&6)%m#ps6P;d9iux~jLr3SOdaK#}licos+m_GPwORWOtK`@WKQGA> zMLF-9c)Z3^A;}xcCVJ<`b{RU}9lcq{SbHCuvOGGYitHjE%4YJv7<3nCJ{Z~3hAi$c zS=Qd^@$vFqWK68U=$GX0ym$Gmk^_1}tS|Qu-_d>uIT6tZo4aMw3oFF6jl1q-FA+Vg zD``g8^mdxTxQc>W%P~PQ%-)-+tu432^oBLvYo*}5lBEqcf1QVC9iq8-p)J`o+au*n zs9t|l@J>QP_RAJLR;nFw9ed5s#!?Nf`m7jZou$ycail%&5JaLiWX$v#U#zz-#&iGt zvU&8j%jL$CYP66IsFutQ6}wS%w~%Fq*shk*TbD-uWxOF3aJ06k&b#y_DZO%|`RxtX z<%J^-xwg@X6jS#Khb2|(4{a#9wANC~f!nvsJZsxx|-A8~CGKXn>lgOU$2eY7zl;){xS2KJl zgIcoar=ke0x4<+@AKckBTI|_lwEX$ZR!mBlf+}?E9s@*=07=J)eRZ|_) zY%T2NIv9}_ONgGR52jFeTJZMdN|}QoT&Vdbz-Aw0P>ic!c=5+%Jq|CP z54@OqErBFqHsx!x?Wl=$U3nvQfF~fPke$clcHFkUEM{D|XH)1_I#c&kJ0rrb2+H@P zj^gtux|*_=tkG`<-z~VezA#%l6hE-sU!BsHorYr0M23_Wd^0K|6xm9u$e9y+Vdi#f z^U`Px!}RHK+FVd@fsrX+l{(Z15d)Di4W$|y(nPp3o4fB$jOeL}Y!MAjTj)56#|}nA z7^S2KnM3YtsPc6Ba@eSO>BNSJ3OYailXp@p0OHU!L*oPig2IbZG{nC7ox0aK_7>4I zc+ZJvM9?OaW;%ZebN>^XO}dNS=C9Y8X>dBFhclT5guJp65PhDy*R?|b>}**a6jnNM zO;Bj5H~5=J6Y_l%!6)ghL>So$yT#U=x@@E2V&Jke#mSpar&MF{k)J;_R6ts7`M}6% zRm3QPu0~cQ$u24H-|p;PAMaT()koKbY(w`aKkgT?yAP-G6P(!8iI;a9K_&b9zr}wB1^q@y+9? zhbT6d-WZ^xOF!~^;4~5{K3dHIu$3S1!pO9;E3_>*SnVt>^TBrz{T4460s(6~1(2`Z z+erm5(UiS6kM6?fC=cq61jGRf4g^Qm)xOYRwO6ix5z7%o0D>X`!``J^KvepQKL z)ozz^Sa`58vA2IA+jLCBkSiT0C8cic6rJUu3BFTL!`6rEYz`^Bb?PV^Zn*2))- zfRg@g4pX$d!VM2^nTjB?@uO7`y*&0(a#G)60Gt*IvvX0P5b;*s1e*Q0wLuXbaTs~D z=e_I`&$Z6OY?jySL+DOx7;yn7QP*UBUB+S#rWwQJk@!an+Oc94dy-B;ou{X)rNY%r z<7#9L>jxF@fN$KDMq8aDeJIeM;H%gMcg=MWnL8t1qZ~M5qPfU@{cvRWul1FhLc~ry=#WRYHu$=wvrI zHUAFyL^^=YM<;PC#SzWKYJA>VJ2Yr!?7dA8&c+|r&)`I>dcrk5wyDEbX7ggEAs zTf}=|f~#gXYUktK-=?eQG;a+I(iN#J>T)M1&XswUIo~{_$=t>b4}AyfO#h_+H4*AM z?qa!|SNrURZNBNEYcS+TnsTEAv^5jF4Ez&0c(-o3kMTX>?m@rZ=rFi0e1XLYj?rnQDsHFbCmVS^lvTumdpt} zFT@+b!)I}524t?H_cJmK-@I-u1{m40g+@lQxk2-f)r<-eEjl+h(LCR%dEHL8@tW2e z({~uZS{Oh%vE@T{qW+ol6JvKgQtm^RCI&P2;g=88*&VuyLZB00D_ke?L+Tdct{LEH zEDaK~d`flQKXbxnD&LVv5VacL(E486phU{z?%w|Q1?dTA2pm=iFs&Gjl-b=T2GvGr zOfyD{BV=$5)d$PrTtJ5*v&Mym2e%j?_AL9Zkezg5$p`PD7s@AYCf3j!1K!H}r%mlU zdB)>rw@x=7@@vz=&j^3bf;V#Dfk08c9|EUbRzF}-70w*AcdH^{DyW_DcbN3Pi@=-_ zdkU{tZc)%fOMgE$1{YWc*CMHKLX`Yw$B}Z1!Nk~kvA>!vMP_23;TGt+ByEE&zxZ6_ zLmF7cgjcsR8z??zzn;w zpph#R9Z~|I^wd4q>XY2_x34 zTTp4b%lDPd)LNKacGS4{Gk$PeXxI+80woN_d*Dn4>K^ydWWu@5;!|yFBU$Abp zb7zP9a^cMVXf|+~R8Ll)-MHgTlrzSlgbe}?6+r!7q%JS~5+w0R`j3z=6J;_NCjH*@ zmPbjW+^JaoR?G1GV3Ad1j3CC;eu0~zq2U|-;wXUqX18AsW5%pt0@5`dZO-DwB-#Fx z3!36NCf%N{3#~ek`sI{|j!Ko7?p3Sdh^v1m1?a-;KE5l54(l;_&^Yq&%jr!uqmpIe zmz{3$EcCR7DxN4uPfy{t5pf>ZJc*}Gm3gFCzxdD{_O}Y2vW(l89!O`q-|SrN$()+c z-}-~>4tLj6i*${Wo*+7h$>4hHhSn$<<>sx~?s#W5v|A_7^8~6Ls~=TS18&+-R|01R zfdD^a%WpsR!aX$_bh%)SBICb|>a2M<@*QZv0Hdrhb^5Ge^6Wm%tWI>>znwOogeBdf2O~R$a%AxpWpwq$eH6dXzMku7 zful@TE~1uP1Tr&}G;djHUaH;H5WSU6eVq@VFB?*%rq|YB&O;j?Vsos@*{NXe6u5F| zF_UsRM0s@0Py^7ndTo4b@U?RIdE?`00khgOJx_Z`h2fSjq>Whubz`V6mg-alVhQJ& z{=H@LqjLZmJ2wX7ee{~(qQNR0a2kv)aO!OM*46;`t5R9?kybY5-)mO~wb<>yb-2S& zgLxFd#uMx{a`8@kZ98MQv7H@O;eVL&tfy}6T9MP>(?l>-aN{_LJ+KWcWOV zqs{52xQQ4+ZQJ_+9$Mm|45MPnEYM^GO?0=YZ`vs@Mo*npi2xQy=FzKbeivr&p6wuh zv%=nqwlMrs2r#LXpiDCEZT=$hP6}DjCHQ?f1Z%BG9PD^**b#tl$EV{_&4q5xx%_M+1E{QQqWd}ue3J5qpSxSjmo`G#G-}O}^!z8m>9oQA zgd_3y=L3$hz1K-E<;ReYT@CI}dAU>}yW<=dwwc4C;apF;ai7%YtO=t1s?&|LcS0h5 zg{HIF7BUQ~G(;AZ(vALIsjz8X-imd-#x<}LcnCTEAeRk2DeQaw=t`T@n%(vuc-k!k zX!mm$LI0$(8#{9MPw{?JZHXf90l$FG<5Fg(F}KcG^dG< zZxMFcX(28r#okH?d@C7~M1Pw!!u+(YeM#Od)x#=jgdRzhzN+MqN23lcm9v``g9?fjh#D+K|h+%5Vc5>HS6Ig)?;$WN{g(Mtuse~r2)u)F4kt%NB zxfi33qr98XIX37{H+2h1lGyQ{!iQwPW(c85W-tVBS8Kv5^wQ)AMuQB&-u1zv$>w5H zv;mMc<>*FnBD!O@9j?r;nb9Gooc0?81zn4F^Lo)NeXP@MF2&^S$(Uj=x~>QmS808| zazRmVRW-l->7jlxQ&gf$hX$DbBRtFw|7(oE4IQougIK|ClU4zs@93w?8D;E&oWqoAnnPYlrY=^j z(DJ@aT?_DY{_f&vn6M-w`ggO|Q-H|W>c`B*;xxRh)6V1f7B>#m9tArwok9Oe-WDFK zt0-lYa`=)jbbVp6*~N~%wjHv_eB@@8%r-f0Q(V|=qioTVvda72@Luz0sx~cPz5o2E zCVPz=OLAE~%yWi(HpO58i` z=uZ(j-Fz{OylgeaO^)7<99OE?gS#RYq=zKiQt{pXFKsjwGTQ80$UT25wdNh(?KXtT z0O_|Mw3zTuSKWlgpNe+iC+`-egOJoUjaKriPF=T>43~6jvITMxcd}#@kDlWi1CW_| z%p5f^3^Mn~%+VEIS+Tt;U-OnNyOYd$Q71zy+eWx&f&Cd1wRitP_4LykGD(%?CPU)p zK74V%rU2vxKkDWc;!%W zwRt5Y<;}KKzh+7;hq}~$3qFKM?d#rw>$v;YP6*I*z4PU--)ux>oXp5ZyR__qoIlhJ z!_#!W9VjFSzYztG5*e?XwMkMP65R^_1Ms>e@g$f*pHAMDDkS4W99_PLW8*_8lF48F zD@1Vk1snQ7goxX#uuGkue|sc+1C7AKN*k)t>QhjH_!jC%i!b49f=7O45!H;4(>Z-) z;L0-oTj|!iDK5%G#`K|Ut0k>gyNut=@L$t#FX5TarUvV0$=Uyc>~Q-u^?QM&#jkji zVG|Fw70M?Sk=w)q^M5sk^!sF6&J*V`Q-at|nw9@VY1^{7L)Wd1>$pCVR%rN;Mzw@y zj*vy#vX}UUkn_|(*9D#wa;}w|diBz8&ANeqN7X4lCmp&MH^%s1%(xDai0m6oR_)ef z8HG;0lY`E2pNiWNqX{`WW((pi_3ekdouZEmKmrBE>gRsntV=t~$E0I72nZ>!dofx5 zi~i4PQ*;-%@3Y=dRj!W;WTHD#P*Qw~Ik^K()8Y>o8=@}ZNWE1rkCB#isSy6Npk*)T z!ZrHmwOVJ?-q=y^A=%<@9MBuDX^Mtd>cT{~s|9s9zKIf29vEN&2N{E?z@N~e917g-)vz5L>` zzI1pZqqM^*ue=m9>C}=?C}f#FBp+i)!)pdp8e-AaJ!wzpi~Cfv|I@cMA99~lzii+| z!CU2e!-XbpkOloJ?8KRa>kf+{O^>sn#cQm3biO^;L=ySS{x3RNK=JqAZ>M9XcJ$x3 z0(Tb!-BedjP_1`0G>gERxwMH>oDnU2I{7m?J`cL1olVUc%0fFK<*KYrZLyF(`K~>ku=y2{)>qm8sd9>eyd!CMJSf6F+(9##L1%ur)h% zr##mbh6SXLETp?tr&jYMJ6W=NFK}rMOpwNH(vRSA*rA{Kqm2P^3vX8It(c|>N^#^z zs-V0)2da);zgn^=O`muHr)=1gO+*{7jD^&!` zqpQ6fs$8Frh-AfqKzZ!lW@|4(Th4lh534yBY@eC0(DAfLCiNp`d(1Rcwo~|^ypn=aX}{Cp#LWOQb_cL>zdFb zti| zc<25021=ZDSZ1U@ju0bV1xhH`vTU`UFaM^UuUQaUzMZ+^KnLtFRicyGalrdww0N)ce>!fm9iRD{V`-=)Sc> zE{y2`{aJ%hf&NaC3zDB6@MGO_*i`kd`9HB!wML5L`pm=GNyCL2H5|K`7M;yP68E2i zbHv16DL2Q^>PCdP4Zmku7v*Quq|(4wa2g|4>b>-Me@In)mBqFOgvC~KnfGn{?`lo9 zYy(|m{)|qx2tmQZaviW3W!$ao&3ImSYhLGTXyElXw_B!rAavO5apA_bh-yL8E9Sd| z(sUUrg1^rat3%^rkNo^W(u4G5oyon?TlWAGZN4n~-sR8%;-Tf%0hsJC3H^qHr7;n) zXT>SFIZY9>R%YgtL1abyPaPxWR>tieVw%T^M$18x%W((h_`~ooh%co5VdJImgkd+3 zyhx?_KYv~E|6bnPc|f|`}U?~A=pD={%(q6=;Z7e zw6Ue$fv@BrBWJCi?5Lk!$1lFhR zZA*Z&viD@Uq<(7PNw+U@FM+a*z(^7UIvn% zi(Xb`9yzg#ou|<7sdY42R}qZ=6LkdY)!s#^ZlSa`K{{)P&jg>yYdds7I$f{}TQYo& zYnR)$){OR8DotDyUY~bnuCjfZc3&zbdnQ#Pd-D8p^a#umOL{jU(t{ex&Yn2&r>nF8 zW9t@>WnIfCj6#QK#h@OQ-YVynPKLV1JPr-zG{&4&f~}UAO6-OMsvsVBXW`>@5B}4Y zYh(4lZ{*kUQJ`F&bZrldR)lYI{$x~C2wXv#O(gzm0$2Pbpr+lO@7@o~y4R_qCW1sv z51&GHIcE+-KAwuseA#u;Q|-5z+GYb8Ie2$_mGSU{ELB2-Lzy%>MSW|Z)eQ)fhP)Ig zuM4U0ot?uY4R3~FBa&<&f_p|L0nJ_P0?4I0cAWTr!_CSFk}~OA!;Q{+%bKJ5Xped=|`~ElpqQ90b78bEJ>e6}DffDF@hGQpSq%`0! z-ZcolD@)xlLRQ9C0v5;lnj>>vs{-)^-+w*~S~wh47_pjuiJOU!&^_h2HZH}t?YMZR~zM;)N*!dFtv6#pc2yaAuPi2 zgv(o62AJ)CvR9>gYTO=Hxg2?I-cv5^YcLHFjkYX(Lx#KG zB4j~Mr|qlRO!0cE$l>+KWq|l}Yr|t2p&dxPlQz%3MS3Vftitk4_C5TX=AjusBs~ zR>1C?v;-!{Su5_piG9Q`_R`Ty;)s(MrgUgE5$8S6Y6N&J2?Ss!y&si;#6lMKu7PXe zuSqQOgbp_?=oborYPiHJjt6;B?00@YeRPnt0zX)p9`==~|5yDQ#I3p$%6g(XQ` zxLllMQE~QejXAosei3O5PM3N$A`u^7S@hR#PdVc>J-c}&4J}*g>6UeyaEtgTqphJf zT+=#!zxn<&Q)76KZ0O|DXWDH?&JC^IW1Ng3V^VCzAgr(HaT&tRYTFZVMyOSw9`et{ z(ja|QDqz>K+ZFU^#~Q?6i>EPL5N5u(P`Abl>ts@bfeJTdZjT@1TYJHknj|nrdpP@F PJX=jk>rI8?hrs^MgbA9VWA6Bl%}FGf{KOEAt(lr-a7^MR5J0y>RLLS$&^`NhUAm^{B6yAM)!KKYC@s{mRGs z#W^xMZkJsDwHj@6Z8!1Nyr6ORYFD#~bHWdmt5T|Yhjnpfm#!bY@ZxXP&G*MDz4?O2 zhhI}gX*GP-pZ?)e5L^o~i(DM&s7fkZQWK72CQ&oD!EOJ0S+?r)uK$}$&U)j@?>Clw zn`bwyzpED9`Gb4?P4J1sP5<*HtAC#JuYbbT@O;16?>Em5oYnaKMo{a1!0$J5q5t>X z=$a$xyr-wuc6^QJx%nCq%|LI}V114Z5-j(c+N)$e{slF&fJIl5&{IX-Ls5nn z5yl19^)K}_j7JcN3v2V~nw1kcQS@4vQIQ=Y+qgi=T-9~& z4vJCw(lr)h-(#`(iIM`Fj=E&6M{iS74&j{1JGyT-MofL~?G@tPw(oIt^k;4#q3sFk z{)>-Ss9ia~O?I&BeP-s9iHV8#85zfmS9}g$e-Y{GIQ!$$Ox-TM25is*K{A3$qlM9f zmQ-D(XCIYdv9dTvqCpy=`I@DcmR2?re;|lS72q8mt+!m5=o}6*AlN%O{XSuX4VgJP z(#Ee7E^eWrc;2U{r(f>x?{`(*^}~wPVoffmyv9ENpr}^d4#-z38 zq-X}cis7`Gwe|H6)0B;hyhy4i3*EBHG7jRe_mv8BL8PQBjj{|9wQ9 zqjaQL;QZ$pB}Wr>rTyihtuGwi6b@sid?Q8G-L4Sk=jR((OhyZHx1>R|*z7RDknf0> z_f+30yQpf1^!R-GVnK(7uuVsz^pqRY=eyydh97>C`64d333cDuJ8LlH@+pSbx)-W0 zYEmjwK3J!$pDWw#U%nlzF!R9=i-4K>8>uqf9(tP0<{RR4zt^Wd<#P?Ai6oq(X=#$? zx4F@dr>VNUnWL{Y(a8_^w6g|J1+LEX7yH^73CfyoGHi`GA!pt4>UhXpgsA#yA5DyE z;Hv)mUR9qrFf~=MGi((;&>c_3i~Kozf>wmXH8=;&-6+N1u747v?tj$`TSb)}GMprp zDwLJ+=s18+J+?>MM4x68Rb3TX_JttW+s#;A4fs8gsl#*f3kzFa6^2){G8@p_(v=34 zKHUA9W>oAHC}mb6N2^>KC_&`QTZFE3VUc24hFGEOH^q*`XoAek91olJ1miRZezS}g zWp5g(<^=ep*9IgY zC@8Dn!B9Je2z3VI#LAiJ~FIvO{UEWtA=MKQ8%>=UMk|Ht4pi^M~l$S|s-#&PznU{Ojhi>(bVkE7!+6=9XCPhX>Ec#65 zH9E)VCvpaJ*=&V3oxMnAA%}xlGE{BN)mzVwwzajncBpfsm;DE;St=f5*WkkH*T)Ku zM_qj>*4Sp}su~9ljzv}{#VwmSrI(jW`uY1?RqXsh!MU!^kNYqex_=tA>3H=$ZdcaY z!x%N+8@?5u)M&{FG-ImRsyBZ)51g}6fwg07sNX`TA-E3;3}DtBPEDT2cs|E?)#h3i zP^^br1aypC+7o(z<_^!CzPuZ$Aqy-nEd0zSTpC+GUgzZ(eHNKjP@v!xCH1eTVz0V; z%c~66*&ksnt9{1TWr-v0iR$GZ^=hy&h+=QaNV?zVSy$8M{p7wPd#Ag^-nC7GV3w2` zUNNc2VyAw;`k7b~vxdJ)Ojy}TYAP7EQdC`CUA$rm{2OL^;F{*zcYexDqZnN?*YoqY zZ-0a1dODiuFQc)Lp|@#$ht1kPr)X3B$qXmbRXe-ffgHDm3B{ReZvON3)Q8J6k?4KW z($XOvR}$64tL9T>7syv5iU<6%(0+4P&dyT(-*{@TT)EP=ML@n zNKcGl(8`_bG}v(R@pgt=VS<(p2n0gg-Tf<~ahSfHGi?kbCnslyBF28dCVC)iK5$$Y z`RvlmBbZSOpYIQQ@~jw$?(V+6J%NGUWQ$@nlC5=~j@Jxa{nlJ^Df7P*sByocp}}V) z*17Iqab4XpS=Fm|N@(6equ$yg?0VUt6L98`4N50ZzOoz;V}2G}V1EgOw3my^J0dR5 z{%Ovz*bb+@!VHqLlT(Cj;5Y%y>)+*B4F06x5MwYzI?t*x!rp{jiCU$H#nSLCv-6Th*vuO32`$=V<_7$@&&a3nVb4s6+9XB!Z!hcC{aO7d) zsKye>U0lt3_D8c1z4FRT)1k;$qqAEc=!OLJUR;{&Ef{7!m8}xA@6MGzTLn(NZmy%z zbDT;Q?)vMf*p?Zv9GCPsB}YHC#U85}SFn(!=#49xxe9tqt5ht8eBcLtr$oL9Sy#65 z?{3kda@N#^rL-kJ|wGpmvP_Vun8Fuc%f0?>dSX|tMu4s2%QRdzbv^*zEvXYVWA~sTG^!yKfuN1 z6y`fO!asn`$q9$_FpAN8Us-Z~VSb)ZLlbi4TLd`os&H9w*mo0d&zotN!@weLKc-I= zlOx2KV~>WF6crWg!P4vHX&1pF-v3v9R7=k^>jg=amHWRfS~#b+I%ahpiA0Xj2P(@+ zxZ+}Mc%3|XvJN69<@+PC2(YO7GEb_`me;zT9v<5UI`DNJ(@0ZOQx8v1ju(&%+RC)5 zk~A)LLu{s|^3f|-MudlhhP@~a;lnHYIKG7ZVJc$NSq-PywNw%q{q2!fW9AaIMRs_b zsM_C8-hkpK6oeB#mU~Cv!;2sFT@7TJRKckE|EDKSn~2td~a)VfLSc1 znJpG1dFOp@TH44HtNbVInh;(qHjA0(J2%b7C#}S{ilIc0H<}X`8x&xkVHHLsa5dKv z2oZ3Z(wfsRkLpE$PpY3E|9YDc4aqsmG$K_O(@+)2SVbFkV8j{{6KS&om4ShkGp?`I zd=FktP&wf+u)wNDmT5u&j)42Zk?{WML5{@PBn2u#zW0I?R_>-k?7HVOo{HpWpcq-$ zsvC*r;KvwfY|r0~kz!8;kO3zQa?MUnoJKF#qK`$f@(&_CJ=+G6;`B~K4 zc1t~Z6ej+8xg-=nU)ftqDXxc5K61rH&g6j_U#L!`zJ@>Fy`VwUAU82NZar97+VmTX zb0Q*R*ckK*89W}inpfkqRO&N`E4i03FA*#G=a8v7$a)AWL&F%f!tJ$;o9ROgGP|6! z!A`P5*;!dxPa!Io^vV|>ZfX>9{_^h93CF(qe}hE!4(UP+lekrN{AL>8mU?O9{F5Uc zNrpj2b6D3UTE76~E;1dRU0n^7NX;E|JU*ka?X^bW#g(&!7XKAOh1m!ssA6W_H}%xb zC1xuZx=c^_FHRcagS1v8$!iZSTO6@QdHMQ(wl3m0$*0vek<6J`y~)_La6y^hx=xW~QnY6*kV!$V<~{q;!X<_`ot#6O-FeeWc2N zAHL)Ny~w_M8?LJ@y8Q0`$zlyi!p%NDd3ofDOk*M=X7v5-n){nvC%!fJRIG%s=DIlk z^5=^rbXrx_nebLGYO&0?hidI)Rbfccy&pjGFbGIb?tzaQlv4O_18X{H4@=^mfCu*c0v}*(zvOfNucJEOa#O6$4Xnr+H{+3}GTD zib+!27MQtl zvn)-^ztqvzR%%1T&Gb;i18PBQ=UbET`*RUI!UcAgxE2wKkU#R#ss47WlC7o1K8u%oK3|*EmP9)yjFQ#lBO>2!Vf>gyYr^V3FP@uoxJOnW! z!Sin(VtA#+9g{05HlmcPoh!TKyzJ+P%}B7;)@FP#z}I%0DyUe$r%n}{Z$5%6_I_rh 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�ca@o0j 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

0?%SH*s#uF2zSeVE(-T=WOG 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 literal 0 HcmV?d00001 diff --git a/nirimod/__init__.py b/nirimod/__init__.py new file mode 100644 index 0000000..5885ae1 --- /dev/null +++ b/nirimod/__init__.py @@ -0,0 +1 @@ +# nirimod diff --git a/nirimod/__main__.py b/nirimod/__main__.py new file mode 100644 index 0000000..4cafbed --- /dev/null +++ b/nirimod/__main__.py @@ -0,0 +1,80 @@ +"""NiriMod application entry point.""" + +from __future__ import annotations + +import sys + +try: + import gi +except ModuleNotFoundError: + print( + "\033[31mError: Could not find Python GObject bindings (PyGObject).\033[0m", + file=sys.stderr, + ) + print( + "This application requires system-level libraries to interface with GTK4.", + file=sys.stderr, + ) + print( + "\nPlease install the required packages for your distribution:", file=sys.stderr + ) + print( + " \033[1mArch:\033[0m sudo pacman -S python-gobject gtk4 libadwaita", + file=sys.stderr, + ) + print( + " \033[1mFedora:\033[0m sudo dnf install python3-gobject gtk4 libadwaita", + file=sys.stderr, + ) + print( + " \033[1mUbuntu:\033[0m sudo apt install python3-gi gir1.2-gtk-4.0 gir1.2-adw-1", + file=sys.stderr, + ) + print( + "\nAfter installing, re-run the installer or re-create your virtual environment.", + file=sys.stderr, + ) + sys.exit(1) + +gi.require_version("Gtk", "4.0") +gi.require_version("Adw", "1") + +from gi.repository import Adw, Gio, GLib + +from nirimod.window import NiriModWindow + + +class NiriModApp(Adw.Application): + def __init__(self): + super().__init__( + application_id="io.github.nirimod", + flags=Gio.ApplicationFlags.NON_UNIQUE, + ) + GLib.set_application_name("NiriMod") + GLib.set_prgname("nirimod") + + + # Prefer dark theme globally via libadwaita + style_manager = Adw.StyleManager.get_default() + style_manager.set_color_scheme(Adw.ColorScheme.FORCE_DARK) + + def do_activate(self): + win = self.get_active_window() + if win is None: + from nirimod import app_settings + from nirimod.kdl_parser import set_paths + set_paths( + config_path=app_settings.get("config_path", ""), + backup_path=app_settings.get("backup_path", "") + ) + win = NiriModWindow(application=self) + win.present() + + +def main(): + app = NiriModApp() + return app.run(sys.argv) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/nirimod/app_settings.py b/nirimod/app_settings.py new file mode 100644 index 0000000..674a09c --- /dev/null +++ b/nirimod/app_settings.py @@ -0,0 +1,50 @@ +from __future__ import annotations + +import json +import os +from pathlib import Path + +_SETTINGS_DIR = Path(os.path.expanduser("~/.config/nirimod")) +_SETTINGS_FILE = _SETTINGS_DIR / "settings.json" + +_DEFAULTS: dict = { + "auto_update": True, + "config_path": "", + "backup_path": "", + "auto_backup": True, + "backup_limit": 10, +} + +_cache: dict | None = None + + +def _load() -> dict: + global _cache + if _cache is not None: + return _cache + if _SETTINGS_FILE.exists(): + try: + data = json.loads(_SETTINGS_FILE.read_text()) + _cache = {**_DEFAULTS, **data} + return _cache + except Exception: + pass + _cache = dict(_DEFAULTS) + return _cache + + +def _save(data: dict): + global _cache + _SETTINGS_DIR.mkdir(parents=True, exist_ok=True) + _SETTINGS_FILE.write_text(json.dumps(data, indent=2)) + _cache = data + + +def get(key: str, default=None): + return _load().get(key, default) + + +def set(key: str, value): # noqa: A001 + data = dict(_load()) + data[key] = value + _save(data) diff --git a/nirimod/backup.py b/nirimod/backup.py new file mode 100644 index 0000000..9427154 --- /dev/null +++ b/nirimod/backup.py @@ -0,0 +1,45 @@ +"""Automatic config backup management.""" + +import re +import shutil +from datetime import datetime +from pathlib import Path + +from nirimod import kdl_parser + +def backup_all_sources(source_files: set[Path], limit: int = 10) -> Path | None: + if not source_files: + return None + + kdl_parser.BACKUP_DIR.mkdir(parents=True, exist_ok=True) + + existing_gens = [] + for p in kdl_parser.BACKUP_DIR.iterdir(): + if p.is_dir(): + m = re.match(r"^(?:\(Gen|v|gen)(\d+)", p.name, re.IGNORECASE) + if m: + existing_gens.append(int(m.group(1))) + next_gen = max(existing_gens) + 1 if existing_gens else 1 + + ts = datetime.now().strftime("%Y-%m-%d_%H-%M") + dest_dir = kdl_parser.BACKUP_DIR / f"(Gen{next_gen}){ts}" + dest_dir.mkdir(parents=True, exist_ok=True) + + for src in sorted(source_files): + if not src.exists(): + continue + try: + rel = src.relative_to(kdl_parser.NIRI_CONFIG.parent) + dest = dest_dir / rel + dest.parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(src, dest) + except ValueError: + shutil.copy2(src, dest_dir / src.name) + + if limit > 0: + backups = sorted([p for p in kdl_parser.BACKUP_DIR.iterdir() if p.is_dir()], key=lambda p: p.stat().st_mtime) + while len(backups) > limit: + oldest = backups.pop(0) + shutil.rmtree(oldest) + + return dest_dir diff --git a/nirimod/kdl_parser.py b/nirimod/kdl_parser.py new file mode 100644 index 0000000..7ddfd5d --- /dev/null +++ b/nirimod/kdl_parser.py @@ -0,0 +1,799 @@ +"""Lightweight KDL parser and writer for Niri config.kdl. + +Handles the subset of KDL used by niri's config format. For complex +cases (nested nodes, attributes) we store raw KDL text and do targeted +find/replace rather than a full AST round-trip. +""" + +from __future__ import annotations + +import os +import tempfile +from dataclasses import dataclass, field +from pathlib import Path +from typing import Any + +_config_dir = Path( + os.environ.get("NIRIMOD_CONFIG_DIR", Path.home() / ".config" / "niri") +) +NIRI_CONFIG = _config_dir / "config.kdl" +PROFILES_DIR = _config_dir / "profiles" +BACKUP_DIR = Path.home() / ".config" / "nirimod" / "backups" + +def set_paths(config_path: str | Path | None = None, backup_path: str | Path | None = None) -> None: + """Override the default config and/or backup paths at module level.""" + global NIRI_CONFIG, PROFILES_DIR, BACKUP_DIR, _config_dir + if config_path: + p = Path(config_path).expanduser().resolve() + _config_dir = p.parent + NIRI_CONFIG = p + else: + _config_dir = Path( + os.environ.get("NIRIMOD_CONFIG_DIR", Path.home() / ".config" / "niri") + ) + NIRI_CONFIG = _config_dir / "config.kdl" + PROFILES_DIR = _config_dir / "profiles" + + if backup_path: + BACKUP_DIR = Path(backup_path).expanduser().resolve() + else: + BACKUP_DIR = Path.home() / ".config" / "nirimod" / "backups" + + +class KdlRawString(str): + """Marker class for strings that should be serialized as raw string literals r"...".""" + + pass + + +@dataclass +class KdlNode: + name: str + args: list[Any] = field(default_factory=list) + props: dict[str, Any] = field(default_factory=dict) + children: list["KdlNode"] = field(default_factory=list) + leading_trivia: str = "" + trailing_trivia: str = "" + children_trailing_trivia: str = "" + source_file: Path | None = field(default=None, compare=False, repr=False) + _removed_children: dict[str, tuple[int, "KdlNode"]] = field( + default_factory=dict, compare=False, repr=False + ) + + def get_child(self, name: str) -> "KdlNode | None": + for c in reversed(self.children): + if c.name == name: + return c + return None + + def get_children(self, name: str) -> list["KdlNode"]: + return [c for c in self.children if c.name == name] + + def child_arg(self, name: str, default=None): + c = self.get_child(name) + if c and c.args: + return c.args[0] + return default + + def __repr__(self): + return f"KdlNode({self.name!r}, args={self.args}, props={self.props}, children={len(self.children)})" + + +# Tokenizer + +# Token types +_TOK_NEWLINE = "NL" # statement-terminating newline +_TOK_SEMICOLON = "SC" # ; statement terminator +_TOK_LBRACE = "LB" # { +_TOK_RBRACE = "RB" # } +_TOK_STRING = "STR" # "..." +_TOK_RAW_STRING = "RSTR" # r#"..."# +_TOK_PLAIN = "PL" # identifier / number / keyword +_TOK_SLASHDASH = "SD" # /- (next node/arg suppressed) +_TOK_WS = "WS" # whitespace or comment +_TOK_EOF = "EOF" + + +def _lex(text: str) -> list[tuple[str, str]]: + """Return list of (token_type, token_value) from KDL source.""" + tokens: list[tuple[str, str]] = [] + i = 0 + n = len(text) + in_node = False # True after we've seen a non-WS token on this line + + while i < n: + # whitespace (spaces/tabs only — NOT newlines) + if text[i] in " \t": + j = i + while j < n and text[j] in " \t": + j += 1 + tokens.append((_TOK_WS, text[i:j])) + i = j + continue + + # line comment + if text[i : i + 2] == "//": + j = i + while j < n and text[j] != "\n": + j += 1 + tokens.append((_TOK_WS, text[i:j])) + i = j + continue + + # block comment + if text[i : i + 2] == "/*": + end = text.find("*/", i + 2) + j = end + 2 if end != -1 else n + tokens.append((_TOK_WS, text[i:j])) + i = j + continue + + # backslash line continuation — \ before \n keeps node open + if text[i] == "\\" and i + 1 < n and text[i + 1] in "\r\n": + j = i + 1 + while j < n and text[j] in " \t\r\n": + j += 1 + tokens.append((_TOK_WS, text[i:j])) + i = j + continue + + # newline(s) — act as statement terminator + if text[i] in "\r\n": + j = i + while j < n and text[j] in "\r\n": + j += 1 + nl_str = text[i:j] + if in_node: + tokens.append((_TOK_NEWLINE, nl_str)) + in_node = False + else: + tokens.append((_TOK_WS, nl_str)) + i = j + continue + + # semicolon — explicit terminator + if text[i] == ";": + if in_node: + tokens.append((_TOK_SEMICOLON, ";")) + in_node = False + else: + tokens.append((_TOK_WS, ";")) + i += 1 + continue + + # /- (node/arg comment) + if text[i : i + 2] == "/-": + tokens.append((_TOK_SLASHDASH, "/-")) + i += 2 + in_node = True + continue + + # braces + if text[i] == "{": + tokens.append((_TOK_LBRACE, "{")) + in_node = False # children block resets line context + i += 1 + continue + if text[i] == "}": + tokens.append((_TOK_RBRACE, "}")) + in_node = False + i += 1 + continue + + # raw string r#"..."# (handle r#, r##, etc.) + if text[i] == "r" and i + 1 < n and text[i + 1] in '#"': + j = i + 1 + while j < n and text[j] == "#": + j += 1 + num_hashes = j - i - 1 + if j < n and text[j] == '"': + start = j + 1 + end_delim = '"' + "#" * num_hashes + end = text.find(end_delim, start) + if end == -1: + raw = text[start:] + i = n + else: + raw = text[start:end] + i = end + len(end_delim) + tokens.append((_TOK_RAW_STRING, raw)) + in_node = True + continue + + if text[i] == '"': + j = i + 1 + s = "" + while j < n and text[j] != '"': + if text[j] == "\\" and j + 1 < n: + j += 1 + esc = { + "n": "\n", + "t": "\t", + "r": "\r", + '"': '"', + "\\": "\\", + "b": "\b", + "f": "\f", + }.get(text[j], text[j]) + s += esc + else: + s += text[j] + j += 1 + tokens.append((_TOK_STRING, s)) + in_node = True + i = j + 1 + continue + + j = i + while j < n and text[j] not in ' \t\r\n;{}"\\': + if text[j] == "=" and j + 1 < n and text[j + 1] == "r": + k = j + 2 + while k < n and text[k] == "#": + k += 1 + if k < n and text[k] == '"': + j += 1 + break + if text[j] == "/" and j + 1 < n and text[j + 1] in "-/*": + break + j += 1 + tok = text[i:j] + if tok: + tokens.append((_TOK_PLAIN, tok)) + in_node = True + i = j + + if in_node: + tokens.append((_TOK_EOF, "")) + tokens.append((_TOK_EOF, "")) + return tokens + + +def _parse_value(tok_type: str, tok_val: str) -> Any: + if tok_type == _TOK_STRING: + return tok_val + if tok_type == _TOK_RAW_STRING: + return KdlRawString(tok_val) + v = tok_val + if v == "true": + return True + if v == "false": + return False + if v == "null": + return None + try: + return int(v, 0) + except ValueError: + pass + try: + return float(v) + except ValueError: + pass + return v + + +def _parse_nodes( + tokens: list[tuple[str, str]], pos: int, is_top_level: bool = False +) -> tuple[list[KdlNode], int, str]: + nodes: list[KdlNode] = [] + n = len(tokens) + skip_next = False + + current_trivia = "" + + while pos < n: + tt, tv = tokens[pos] + + if tt in (_TOK_WS, _TOK_NEWLINE, _TOK_SEMICOLON): + current_trivia += tv + pos += 1 + continue + + if tt == _TOK_EOF: + break + + if tt == _TOK_RBRACE: + if is_top_level: + current_trivia += tv + pos += 1 + continue + break + + if tt == _TOK_SLASHDASH: + current_trivia += tv + skip_next = True + pos += 1 + continue + + if tt not in (_TOK_PLAIN, _TOK_STRING): + current_trivia += tv + pos += 1 + continue + + name = tv + pos += 1 + node = KdlNode(name=name) + node.leading_trivia = current_trivia + current_trivia = "" + + accumulated_ws = "" + + while pos < n: + tt2, tv2 = tokens[pos] + + if tt2 in (_TOK_NEWLINE, _TOK_SEMICOLON, _TOK_EOF): + node.trailing_trivia += accumulated_ws + tv2 + pos += 1 + break + + if tt2 == _TOK_WS: + accumulated_ws += tv2 + pos += 1 + continue + + if tt2 == _TOK_RBRACE: + node.trailing_trivia += accumulated_ws + break + + if tt2 == _TOK_LBRACE: + node.trailing_trivia += accumulated_ws + accumulated_ws = "" + pos += 1 + node.children, pos, node.children_trailing_trivia = _parse_nodes( + tokens, pos + ) + if pos < n and tokens[pos][0] == _TOK_RBRACE: + pos += 1 + break + + if tt2 == _TOK_SLASHDASH: + accumulated_ws += tv2 + pos += 1 + while pos < n and tokens[pos][0] == _TOK_WS: + accumulated_ws += tokens[pos][1] + pos += 1 + if pos < n and tokens[pos][0] not in ( + _TOK_NEWLINE, + _TOK_SEMICOLON, + _TOK_EOF, + _TOK_RBRACE, + _TOK_LBRACE, + ): + accumulated_ws += tokens[pos][1] + pos += 1 + continue + + if "/*" in accumulated_ws or "//" in accumulated_ws: + node.trailing_trivia += accumulated_ws + accumulated_ws = "" + + if tt2 == _TOK_PLAIN and "=" in tv2 and not tv2.startswith("-"): + k, _, vraw = tv2.partition("=") + if not vraw: + pos += 1 + while pos < n and tokens[pos][0] == _TOK_WS: + pos += 1 + if pos < n and tokens[pos][0] not in ( + _TOK_NEWLINE, + _TOK_SEMICOLON, + _TOK_EOF, + _TOK_RBRACE, + _TOK_LBRACE, + ): + vtt, vtv = tokens[pos] + node.props[k] = _parse_value(vtt, vtv) + pos += 1 + elif vraw == "r" or ( + vraw.startswith("r") and all(c == "#" for c in vraw[1:]) + ): + num_hashes = len(vraw) - 1 + pos += 1 + while pos < n and tokens[pos][0] == _TOK_WS: + pos += 1 + if pos < n and tokens[pos][0] == _TOK_STRING: + node.props[k] = KdlRawString(tokens[pos][1]) + pos += 1 + while ( + num_hashes > 0 + and pos < n + and tokens[pos] == (_TOK_PLAIN, "#") + ): + pos += 1 + num_hashes -= 1 + else: + node.props[k] = _parse_value(_TOK_PLAIN, vraw) + else: + node.props[k] = _parse_value(_TOK_PLAIN, vraw) + pos += 1 + else: + node.args.append(_parse_value(tt2, tv2)) + pos += 1 + + if skip_next: + current_trivia += _write_node(node) + skip_next = False + else: + nodes.append(node) + + return nodes, pos, current_trivia + + +def parse_kdl(text: str) -> list[KdlNode]: + tokens = _lex(text) + nodes, _, eof_trivia = _parse_nodes(tokens, 0, is_top_level=True) + if nodes and eof_trivia: + setattr(nodes[-1], "eof_trivia", eof_trivia) + return nodes + + +def load_niri_config() -> list[KdlNode]: + if not NIRI_CONFIG.exists(): + return [] + return parse_kdl(NIRI_CONFIG.read_text()) + + +def _resolve_includes( + nodes: list[KdlNode], + base: Path, + depth: int = 0, +) -> tuple[list[KdlNode], list[tuple[KdlNode, Path]]]: + flat: list[KdlNode] = [] + slots: list[tuple[KdlNode, Path]] = [] + + for i, node in enumerate(nodes): + if node.name != "include" or depth > 5: + node.source_file = base + if depth == 0: + node._primary_order = i + flat.append(node) + continue + + optional = node.props.get("optional", False) + if not node.args: + node.source_file = base + if depth == 0: + node._primary_order = i + flat.append(node) + continue + + node.source_file = base + if depth == 0: + node._primary_order = i + target = base.parent / node.args[0] + slots.append((node, target)) + + if not target.exists(): + if not optional: + import warnings + + warnings.warn(f"nirimod: included file not found: {target}") + continue + + included = parse_kdl(target.read_text()) + child_flat, child_slots = _resolve_includes(included, target, depth + 1) + flat.extend(child_flat) + slots.extend(child_slots) + + return flat, slots + + +def load_niri_config_multi() -> tuple[list[KdlNode], list[tuple[KdlNode, Path]]]: + if not NIRI_CONFIG.exists(): + return [], [] + raw = parse_kdl(NIRI_CONFIG.read_text()) + return _resolve_includes(raw, NIRI_CONFIG) + + +def _atomic_write(path: Path, content: str) -> None: + if path.exists() and path.read_text() == content: + return + path.parent.mkdir(parents=True, exist_ok=True) + fd, tmp = tempfile.mkstemp(dir=path.parent, prefix=".nirimod_tmp_") + try: + os.write(fd, content.encode()) + os.close(fd) + fd = -1 + os.replace(tmp, path) + except Exception: + if fd != -1: + os.close(fd) + try: + os.unlink(tmp) + except OSError: + pass + raise + + +def save_niri_config_multi( + nodes: list[KdlNode], + include_slots: list[tuple[KdlNode, Path]], +) -> None: + primary = NIRI_CONFIG + if include_slots and include_slots[0][0].source_file is not None: + primary = include_slots[0][0].source_file + + name_to_file: dict[str, Path] = {} + for node in nodes: + if node.source_file is not None and node.source_file != primary: + name_to_file.setdefault(node.name, node.source_file) + for node in nodes: + if node.source_file is None: + node.source_file = name_to_file.get(node.name) + + by_file: dict[Path, list[KdlNode]] = {} + config_nodes: list[KdlNode] = [] + + for node in nodes: + src = node.source_file + if src is None or src == primary: + config_nodes.append(node) + else: + by_file.setdefault(src, []).append(node) + + for path, file_nodes in by_file.items(): + _atomic_write(path, write_kdl(file_nodes)) + + _LARGE = 10**9 + primary_items: list[tuple[int, KdlNode]] = [] + for inc_node, _ in include_slots: + primary_items.append((getattr(inc_node, "_primary_order", _LARGE), inc_node)) + for node in config_nodes: + primary_items.append((getattr(node, "_primary_order", _LARGE), node)) + primary_items.sort(key=lambda x: x[0]) + + _atomic_write(primary, write_kdl([n for _, n in primary_items])) + + +# Writer + + +def _val_to_kdl(v: Any) -> str: + if isinstance(v, bool): + return "true" if v else "false" + if isinstance(v, KdlRawString): + num_hashes = 0 + delim = "" + while f'"{delim}' in v: + num_hashes += 1 + delim = "#" * num_hashes + return f'r{delim}"{v}"{delim}' + if isinstance(v, str): + escaped = ( + v.replace("\\", "\\\\") + .replace('"', '\\"') + .replace("\n", "\\n") + .replace("\t", "\\t") + ) + return f'"{escaped}"' + if v is None: + return "null" + return str(v) + + +def _is_inline_node(node: KdlNode) -> bool: + if not node.children: + return False + if "\n" in node.trailing_trivia: + return False + for child in node.children: + if "\n" in child.leading_trivia or "\n" in child.trailing_trivia: + return False + if child.children and not _is_inline_node(child): + return False + if "\n" in node.children_trailing_trivia: + return False + return True + + +def _write_node_inline(node: KdlNode) -> str: + # Renders a node as a compact one-liner with no trivia or indentation. + if isinstance(node.name, KdlRawString): + name_str = _val_to_kdl(node.name) + else: + name_str = f'"{node.name}"' if " " in node.name else node.name + + parts = [name_str] + for a in node.args: + parts.append(_val_to_kdl(a)) + for k, v in node.props.items(): + parts.append(f"{k}={_val_to_kdl(v)}") + + res = " ".join(parts) + if node.children: + children_str = " ".join(f"{_write_node_inline(c)};" for c in node.children) + res += f" {{ {children_str} }}" + return res + + +def _write_node(node: KdlNode, indent: int = 0) -> str: + res = node.leading_trivia + + pad = " " * indent + if not node.leading_trivia: + res += pad + elif node.leading_trivia.endswith("\n"): + res += pad + + if isinstance(node.name, KdlRawString): + name_str = _val_to_kdl(node.name) + else: + name_str = f'"{node.name}"' if " " in node.name else node.name + + parts = [name_str] + for a in node.args: + parts.append(_val_to_kdl(a)) + for k, v in node.props.items(): + parts.append(f"{k}={_val_to_kdl(v)}") + + res += " ".join(parts) + + if node.children: + if _is_inline_node(node): + pre_brace = node.trailing_trivia if node.trailing_trivia else " " + if not pre_brace[0].isspace(): + pre_brace = " " + pre_brace + children_str = " ".join(f"{_write_node_inline(c)};" for c in node.children) + res += f"{pre_brace}{{ {children_str} }}" + else: + if not res.endswith(" "): + res += " " + res += "{" + + tt = node.trailing_trivia + if tt and (not tt.isspace() or "\n" in tt): + if not tt[0].isspace() and not tt.startswith("\n"): + res += " " + res += tt + + for child in node.children: + child_str = _write_node(child, indent + 1) + if ( + res + and not res.endswith("\n") + and child_str + and not child_str.startswith("\n") + ): + res += "\n" + res += child_str + + ctt = node.children_trailing_trivia + if ctt and (not ctt.isspace() or "\n" in ctt): + lines = ctt.splitlines(keepends=True) + while lines and lines[-1].strip() == "": + lines.pop() + ctt_trimmed = "".join(lines) + if ctt_trimmed: + res += ctt_trimmed + if not res.endswith("\n"): + res += "\n" + if not res.endswith("\n"): + res += "\n" + res += pad + res += "}" + + return res + + elif node.trailing_trivia: + if not node.trailing_trivia[ + 0 + ].isspace() and not node.trailing_trivia.startswith("\n"): + res += " " + res += node.trailing_trivia + + if not res.endswith("\n"): + res += "\n" + + return res + + +def write_kdl(nodes: list[KdlNode]) -> str: + if not nodes: + return "// NiriMod configuration\n" + + res = "" + for n in nodes: + node_str = _write_node(n) + if getattr(n, "eof_trivia", None): + node_str += getattr(n, "eof_trivia") + + if ( + res + and not res.endswith("\n") + and node_str + and not node_str.startswith("\n") + ): + res += "\n" + res += node_str + + if res and not res.endswith("\n"): + res += "\n" + + return res + + +def save_niri_config(nodes: list[KdlNode], path: Path | None = None) -> None: + target = path or NIRI_CONFIG + _atomic_write(target, write_kdl(nodes)) + + +# Config mutation helpers + + +def find_or_create(nodes: list[KdlNode], *path: str) -> KdlNode: + """Navigate/create nested nodes by path, operating on a list of nodes.""" + current_list = nodes + node: KdlNode | None = None + for name in path: + node = next((n for n in reversed(current_list) if n.name == name), None) + if node is None: + node = KdlNode(name=name) + node.leading_trivia = "\n" + current_list.append(node) + current_list = node.children + return node + + +def set_child_arg(parent: KdlNode, child_name: str, value: Any) -> None: + child = parent.get_child(child_name) + if child is None: + cache = getattr(parent, "_removed_children", {}) + if child_name in cache: + idx, node = cache[child_name] + parent.children.insert(min(idx, len(parent.children)), node) + child = node + else: + child = KdlNode(name=child_name) + child.leading_trivia = "\n" + parent.children.append(child) + child.args = [value] + child.props = {} + + +def remove_child(parent: KdlNode, child_name: str) -> None: + existing = parent.get_child(child_name) + if existing: + if not hasattr(parent, "_removed_children"): + parent._removed_children = {} + parent._removed_children[child_name] = ( + parent.children.index(existing), + existing, + ) + parent.children.remove(existing) + + +def set_node_flag(parent: KdlNode, flag_name: str, enabled: bool) -> None: + existing = parent.get_child(flag_name) + if enabled: + if existing is not None: + existing.args = [] + existing.props = {} + return + cache = getattr(parent, "_removed_children", {}) + if flag_name in cache: + idx, node = cache[flag_name] + node.args = [] + node.props = {} + parent.children.insert(min(idx, len(parent.children)), node) + else: + new_node = KdlNode(name=flag_name) + new_node.leading_trivia = "\n" + parent.children.insert(0, new_node) + elif not enabled and existing is not None: + if not hasattr(parent, "_removed_children"): + parent._removed_children = {} + parent._removed_children[flag_name] = ( + parent.children.index(existing), + existing, + ) + parent.children.remove(existing) + + +def safe_switch_connect(switch_row, initial_value: bool, callback) -> None: + switch_row._last_active = initial_value + + def _guarded(r, _): + new_val = r.get_active() + if new_val != getattr(r, "_last_active", None): + r._last_active = new_val + callback(new_val) + + switch_row.connect("notify::active", _guarded) diff --git a/nirimod/niri_ipc.py b/nirimod/niri_ipc.py new file mode 100644 index 0000000..48c9033 --- /dev/null +++ b/nirimod/niri_ipc.py @@ -0,0 +1,209 @@ +"""Wrappers around `niri msg` C. Low-level IPC operations.""" + +from __future__ import annotations + +import json +from typing import Callable + + + + +# Internal: synchronous helper + + +def _run_sync(args: list[str], timeout: float = 5.0) -> tuple[str, str, int]: + import subprocess + + try: + r = subprocess.run( + args, + capture_output=True, + text=True, + timeout=timeout, + ) + return r.stdout, r.stderr, r.returncode + except FileNotFoundError: + return "", "niri: command not found", 1 + except subprocess.TimeoutExpired: + return "", "niri msg timed out", 1 + + +# Internal: non-blocking async dispatch + + +def _run_async( + args: list[str], + callback: Callable[[str, str, int], None], +) -> None: + import gi + gi.require_version("Gio", "2.0") + gi.require_version("GLib", "2.0") + from gi.repository import Gio, GLib + + try: + proc = Gio.Subprocess.new( + args, + Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_PIPE, + ) + except GLib.Error: + GLib.idle_add(lambda: callback("", "niri: command not found", 1) or False) + return + + def _on_done(source: Gio.Subprocess, result: Gio.AsyncResult) -> None: + try: + ok, stdout_bytes, stderr_bytes = source.communicate_finish(result) + stdout = stdout_bytes.get_data().decode("utf-8", errors="replace") if stdout_bytes else "" + stderr = stderr_bytes.get_data().decode("utf-8", errors="replace") if stderr_bytes else "" + if not ok: + rc = 1 + else: + rc = 0 if source.get_exit_status() == 0 else 1 + except GLib.Error as exc: + stdout, stderr, rc = "", str(exc), 1 + callback(stdout, stderr, rc) + + proc.communicate_async(None, None, _on_done) + + +# IPC Getters + + +def is_niri_running() -> bool: + """Return True if `niri msg version` succeeds. Called once at startup.""" + stdout, _, rc = _run_sync(["niri", "msg", "version"]) + return rc == 0 and bool(stdout.strip()) + + +def get_version() -> str: + stdout, _, rc = _run_sync(["niri", "--version"]) + return stdout.strip() if rc == 0 else "unknown" + + +_touchpad_cache: bool | None = None + + +def has_touchpad() -> bool: + import os + + global _touchpad_cache + if _touchpad_cache is not None: + return _touchpad_cache + + result = False + try: + for dev in os.listdir("/sys/class/input"): + name_file = f"/sys/class/input/{dev}/device/name" + if os.path.exists(name_file): + with open(name_file) as fh: + name = fh.read().lower() + if "touchpad" in name or "trackpad" in name: + result = True + break + except Exception: + pass + + _touchpad_cache = result + return result + + +def validate_config(config_path: str | None = None) -> tuple[bool, str]: + cmd = ["niri", "validate"] + if config_path: + cmd += ["--config", config_path] + stdout, stderr, rc = _run_sync(cmd, timeout=10.0) + if rc == 0: + return True, stdout.strip() or "Config is valid." + return False, stderr.strip() or stdout.strip() or "Unknown validation error." + + +def load_config_file() -> tuple[bool, str]: + stdout, stderr, rc = _run_sync( + ["niri", "msg", "action", "load-config-file"], timeout=10.0 + ) + if rc == 0: + return True, stdout.strip() or "Config applied." + return False, stderr.strip() or stdout.strip() or "Config reload failed." + + +def get_outputs(callback: Callable[[list[dict]], None]) -> None: + def _done(stdout: str, _stderr: str, rc: int) -> None: + if rc != 0: + callback([]) + return + try: + data = json.loads(stdout) + callback(list(data.values()) if isinstance(data, dict) else data) + except json.JSONDecodeError: + callback([]) + + _run_async(["niri", "msg", "--json", "outputs"], _done) + + +def get_workspaces(callback: Callable[[list[dict]], None]) -> None: + def _done(stdout: str, _stderr: str, rc: int) -> None: + if rc != 0: + callback([]) + return + try: + callback(json.loads(stdout)) + except json.JSONDecodeError: + callback([]) + + _run_async(["niri", "msg", "--json", "workspaces"], _done) + + +def get_windows(callback: Callable[[list[dict]], None]) -> None: + def _done(stdout: str, _stderr: str, rc: int) -> None: + if rc != 0: + callback([]) + return + try: + callback(json.loads(stdout)) + except json.JSONDecodeError: + callback([]) + + _run_async(["niri", "msg", "--json", "windows"], _done) + + +def get_focused_window(callback: Callable[[dict | None], None]) -> None: + def _done(stdout: str, _stderr: str, rc: int) -> None: + if rc != 0: + callback(None) + return + try: + callback(json.loads(stdout)) + except json.JSONDecodeError: + callback(None) + + _run_async(["niri", "msg", "--json", "focused-window"], _done) + + +def action(action_name: str, *args: str, callback: Callable[[bool], None] | None = None) -> None: + cmd = ["niri", "msg", "action", action_name] + list(args) + + def _done(_stdout: str, _stderr: str, rc: int) -> None: + if callback is not None: + callback(rc == 0) + + _run_async(cmd, _done) + + +# Legacy thread shims + + +def run_in_thread(fn: Callable, callback: Callable | None = None): + + import threading + + import gi + gi.require_version("GLib", "2.0") + from gi.repository import GLib + + def _worker(): + result = fn() + if callback is not None: + GLib.idle_add(lambda: callback(result) or False) + + t = threading.Thread(target=_worker, daemon=True) + t.start() + return t diff --git a/nirimod/pages/__init__.py b/nirimod/pages/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/nirimod/pages/animations.py b/nirimod/pages/animations.py new file mode 100644 index 0000000..0335dc9 --- /dev/null +++ b/nirimod/pages/animations.py @@ -0,0 +1,1222 @@ +"""Animations page with bezier curve editor and Nirimation preset browser.""" + +from __future__ import annotations + +import json +import math +from pathlib import Path +import threading +import urllib.error +import urllib.request + +import gi + +gi.require_version("Gtk", "4.0") +gi.require_version("Adw", "1") +from gi.repository import Adw, GLib, Gtk + +from nirimod.kdl_parser import KdlNode, find_or_create, parse_kdl, set_child_arg, set_node_flag +from nirimod.pages.base import BasePage + +_NIRIMATION_API = ( + "https://api.github.com/repos/XansiVA/nirimation/contents/animations" +) +_NIRIMATION_RAW = ( + "https://raw.githubusercontent.com/XansiVA/nirimation/main/animations/{name}" +) +_NIRIMATION_HTML = ( + "https://github.com/XansiVA/nirimation/blob/main/animations/{name}" +) + +_JGARZA_API = ( + "https://api.github.com/repos/jgarza9788/niri-animation-collection/contents/animations" +) +_JGARZA_RAW = ( + "https://raw.githubusercontent.com/jgarza9788/niri-animation-collection/main/animations/{name}" +) +_JGARZA_HTML = ( + "https://github.com/jgarza9788/niri-animation-collection/blob/main/animations/{name}" +) + +# In-memory cache: None = not fetched, list = fetched entries, Exception = error +_nirimation_cache: list[dict] | Exception | None = None +_jgarza_cache: list[dict] | Exception | None = None + +# Local presets directory +_LOCAL_PRESETS_DIR = Path("~/.config/nirimod/presets").expanduser() + +# Slug used as subdirectory name for each source +_SOURCE_SLUGS = { + "XansiVA/nirimation": "nirimation", + "jgarza9788/niri-animation-collection": "niri-animation-collection", +} + + + +ANIM_GROUPS = [ + ("Window Management", [ + ("window-open", "Window Open", "window-new-symbolic"), + ("window-close", "Window Close", "window-close-symbolic"), + ("window-movement", "Window Movement", "transform-move-symbolic"), + ("window-resize", "Window Resize", "view-fullscreen-symbolic"), + ]), + ("Workspace", [ + ("workspace-switch", "Workspace Switch", "video-display-symbolic"), + ("horizontal-view-movement", "Horizontal View Movement", "pan-end-symbolic"), + ]), + ("Interface", [ + ("overview-open-close", "Overview Open/Close", "view-app-grid-symbolic"), + ("overview-screenshot", "Overview Screenshot", "camera-photo-symbolic"), + ("screenshot-ui-open", "Screenshot UI Open", "camera-photo-symbolic"), + ("config-notification-open-close", "Config Notification", "preferences-system-symbolic"), + ]) +] + +PRESET_CURVES = { + "ease": (0.25, 0.1, 0.25, 1.0), + "ease-in": (0.42, 0.0, 1.0, 1.0), + "ease-out": (0.0, 0.0, 0.58, 1.0), + "ease-in-out": (0.42, 0.0, 0.58, 1.0), + "linear": (0.0, 0.0, 1.0, 1.0), + "spring": (0.17, 0.67, 0.83, 0.67), +} + + +class BezierEditor(Gtk.DrawingArea): + """Interactive cubic Bézier curve editor with animated preview ball.""" + + def __init__(self, on_changed=None): + super().__init__() + self._cp = [0.25, 0.1, 0.25, 1.0] # x1,y1,x2,y2 + self._on_changed = on_changed + self._dragging: int | None = None # 0=p1, 1=p2 + self._ball_t = 0.0 + self._ball_dir = 1 + self._anim_id: int | None = None + + self.set_content_width(220) + self.set_content_height(180) + self.set_draw_func(self._draw) + + motion = Gtk.EventControllerMotion() + motion.connect("motion", self._on_motion) + self.add_controller(motion) + + click = Gtk.GestureClick() + click.connect("pressed", self._on_press) + click.connect("released", self._on_release) + self.add_controller(click) + + self.add_tick_callback(self._on_tick) + + def set_curve(self, x1, y1, x2, y2): + self._cp = [x1, y1, x2, y2] + self.queue_draw() + + def get_curve(self): + return tuple(self._cp) + + def _on_tick(self, widget, frame_clock): + current_time = frame_clock.get_frame_time() + if not hasattr(self, "_last_time"): + self._last_time = current_time + return True + + dt = (current_time - self._last_time) / 1_000_000.0 + self._last_time = current_time + + # Move at a constant speed of ~0.75 units per second + speed = 0.75 + self._ball_t += (dt * speed) * self._ball_dir + + if self._ball_t >= 1.0: + self._ball_t = 1.0 + self._ball_dir = -1 + elif self._ball_t <= 0.0: + self._ball_t = 0.0 + self._ball_dir = 1 + + self.queue_draw() + return True + + def _bezier_pt(self, t): + x1, y1, x2, y2 = self._cp + # Cubic bezier from (0,0) to (1,1) with controls (x1,y1), (x2,y2) + mt = 1 - t + bx = 3 * mt * mt * t * x1 + 3 * mt * t * t * x2 + t * t * t + by = 3 * mt * mt * t * y1 + 3 * mt * t * t * y2 + t * t * t + return bx, by + + def _canvas_to_cp(self, cx, cy, W, H, pad=20): + """Convert canvas coords to bezier control point (0-1 range).""" + x = (cx - pad) / (W - 2 * pad) + y = 1.0 - (cy - pad) / (H - 2 * pad) + return max(0.0, min(1.0, x)), max(-0.5, min(1.5, y)) + + def _cp_to_canvas(self, x, y, W, H, pad=20): + cx = pad + x * (W - 2 * pad) + cy = pad + (1.0 - y) * (H - 2 * pad) + return cx, cy + + def _draw(self, area, cr, W, H): + pad = 20 + + cr.set_source_rgba(0.08, 0.08, 0.08, 1.0) + cr.rectangle(0, 0, W, H) + cr.fill() + cr.set_source_rgba(0.2, 0.2, 0.22, 0.4) + cr.set_line_width(0.5) + for i in range(5): + gx = pad + i * (W - 2 * pad) / 4 + gy = pad + i * (H - 2 * pad) / 4 + cr.move_to(gx, pad) + cr.line_to(gx, H - pad) + cr.stroke() + cr.move_to(pad, gy) + cr.line_to(W - pad, gy) + cr.stroke() + + x1, y1, x2, y2 = self._cp + px1, py1 = self._cp_to_canvas(x1, y1, W, H, pad) + px2, py2 = self._cp_to_canvas(x2, y2, W, H, pad) + start = self._cp_to_canvas(0, 0, W, H, pad) + end = self._cp_to_canvas(1, 1, W, H, pad) + + cr.set_source_rgba(0.2, 0.2, 0.25, 0.4) + cr.set_line_width(1.0) + cr.move_to(*start) + cr.line_to(px1, py1) + cr.stroke() + cr.move_to(*end) + cr.line_to(px2, py2) + cr.stroke() + + # Bezier path + cr.set_source_rgba(0.3, 0.7, 1.0, 0.9) + cr.set_line_width(2.5) + cr.move_to(*start) + cr.curve_to(px1, py1, px2, py2, *end) + cr.stroke() + + bx_01, by_01 = self._bezier_pt(self._ball_t) + bx_c, by_c = self._cp_to_canvas(bx_01, by_01, W, H, pad) + cr.set_source_rgba(1.0, 0.6, 0.2, 0.95) + cr.arc(bx_c, by_c, 5, 0, 2 * math.pi) + cr.fill() + + for px, py, color in [ + (px1, py1, (0.4, 1.0, 0.5, 1.0)), + (px2, py2, (1.0, 0.4, 0.5, 1.0)), + ]: + cr.set_source_rgba(*color) + cr.arc(px, py, 6, 0, 2 * math.pi) + cr.fill() + cr.set_source_rgba(1, 1, 1, 0.5) + cr.set_line_width(1.5) + cr.arc(px, py, 6, 0, 2 * math.pi) + cr.stroke() + + def _hit_cp(self, cx, cy, W, H, pad=20): + x1, y1, x2, y2 = self._cp + px1, py1 = self._cp_to_canvas(x1, y1, W, H, pad) + px2, py2 = self._cp_to_canvas(x2, y2, W, H, pad) + if math.hypot(cx - px1, cy - py1) < 12: + return 0 + if math.hypot(cx - px2, cy - py2) < 12: + return 1 + return None + + def _on_press(self, gesture, _n, x, y): + W = self.get_width() + H = self.get_height() + self._dragging = self._hit_cp(x, y, W, H) + + def _on_release(self, gesture, _n, x, y): + self._dragging = None + + def _on_motion(self, controller, x, y): + if self._dragging is None: + return + W = self.get_width() + H = self.get_height() + cpx, cpy = self._canvas_to_cp(x, y, W, H) + if self._dragging == 0: + self._cp[0] = cpx + self._cp[1] = cpy + else: + self._cp[2] = cpx + self._cp[3] = cpy + self.queue_draw() + if self._on_changed: + self._on_changed(*self._cp) + + +def _fetch_presets_from_github(api_url, raw_tmpl, html_tmpl, cache_attr, callback): + """Generic preset fetcher for any GitHub contents API endpoint.""" + import sys + mod = sys.modules[__name__] + cached = getattr(mod, cache_attr) + if cached is not None: + GLib.idle_add(callback, cached) + return + + def _worker(): + try: + req = urllib.request.Request( + api_url, + headers={"User-Agent": "nirimod/1.0"}, + ) + with urllib.request.urlopen(req, timeout=10) as resp: + data = json.loads(resp.read().decode()) + + entries = [] + for item in data: + if item.get("type") != "file": + continue + n = item["name"] + if not n.endswith(".kdl"): + continue + stem = n[:-4] # strip .kdl + display = stem.replace("-", " ").replace("_", " ").title() + entries.append( + { + "name": n, + "display_name": display, + "download_url": item.get( + "download_url", + raw_tmpl.format(name=n), + ), + "html_url": item.get( + "html_url", + html_tmpl.format(name=n), + ), + } + ) + entries.sort(key=lambda e: e["display_name"]) + setattr(mod, cache_attr, entries) + GLib.idle_add(callback, entries) + except Exception as exc: + setattr(mod, cache_attr, exc) + GLib.idle_add(callback, exc) + + threading.Thread(target=_worker, daemon=True).start() + + +def _fetch_nirimation_presets(callback): + """Fetch preset list from XansiVA/nirimation in a background thread.""" + _fetch_presets_from_github( + _NIRIMATION_API, _NIRIMATION_RAW, _NIRIMATION_HTML, + "_nirimation_cache", callback, + ) + + +def _fetch_jgarza_presets(callback): + """Fetch preset list from jgarza9788/niri-animation-collection in a background thread.""" + _fetch_presets_from_github( + _JGARZA_API, _JGARZA_RAW, _JGARZA_HTML, + "_jgarza_cache", callback, + ) + + +class AnimationsPage(BasePage): + def __init__(self, window): + super().__init__(window) + self._prev_anim_snapshot = None + self._active_preset_name = None + self._state_file = Path("~/.config/nirimod/animations.json").expanduser() + self._load_state() + + def _load_state(self): + try: + if self._state_file.exists(): + with open(self._state_file, "r", encoding="utf-8") as f: + data = json.load(f) + self._prev_anim_snapshot = data.get("prev_anim_snapshot") + self._active_preset_name = data.get("active_preset_name") + except Exception as e: + print(f"Failed to load animations state: {e}") + + def _save_state(self): + try: + self._state_file.parent.mkdir(parents=True, exist_ok=True) + with open(self._state_file, "w", encoding="utf-8") as f: + json.dump({ + "prev_anim_snapshot": self._prev_anim_snapshot, + "active_preset_name": self._active_preset_name + }, f) + except Exception as e: + print(f"Failed to save animations state: {e}") + + def build(self) -> Gtk.Widget: + tb, header, _, _ = self._make_toolbar_page("") + header.set_title_widget(Gtk.Box()) # hide the default title + + # Custom Header (matches Workspace View / Keybindings aesthetic) + header_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=12) + header_box.set_margin_start(24) + header_box.set_margin_end(24) + header_box.set_margin_top(20) + header_box.set_margin_bottom(12) + + # Title/Subtitle Group + title_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2) + title_vbox.set_hexpand(True) + + self._main_title = Gtk.Label(label="Animations") + self._main_title.set_xalign(0.0) + self._main_title.add_css_class("title-1") + title_vbox.append(self._main_title) + + self._active_preset_lbl = Gtk.Label(label="Using custom animations") + self._active_preset_lbl.set_xalign(0.0) + self._active_preset_lbl.add_css_class("dim-label") + self._active_preset_lbl.add_css_class("caption") + title_vbox.append(self._active_preset_lbl) + header_box.append(title_vbox) + + + # View Switcher (Styled as Custom/Presets buttons) + self._view_stack = Adw.ViewStack() + + switcher_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) + switcher_box.add_css_class("linked") + switcher_box.set_valign(Gtk.Align.START) + + self._btn_custom = Gtk.ToggleButton(label="Custom") + self._btn_presets = Gtk.ToggleButton(label="Presets") + self._btn_presets.set_group(self._btn_custom) + + self._btn_custom.connect("toggled", self._on_view_toggle) + self._btn_presets.connect("toggled", self._on_view_toggle) + + switcher_box.append(self._btn_custom) + switcher_box.append(self._btn_presets) + header_box.append(switcher_box) + + # Custom Header (matches Workspace View / Keybindings aesthetic) + self._view_stack = Adw.ViewStack() + self._view_stack.set_vexpand(True) + + # Tabs + custom_widget = self._build_custom_tab() + self._view_stack.add_named(custom_widget, "custom") + + presets_widget = self._build_presets_tab() + self._view_stack.add_named(presets_widget, "presets") + + # Default to Custom + self._view_stack.set_visible_child_name("custom") + self._btn_custom.set_active(True) + + main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + main_box.append(header_box) + main_box.append(self._view_stack) + + tb.set_content(main_box) + + self._update_header() + return tb + + def _on_view_toggle(self, btn): + if not btn.get_active(): + return + is_custom = btn == self._btn_custom + self._view_stack.set_visible_child_name("custom" if is_custom else "presets") + + def _update_header(self): + if self._active_preset_name: + self._active_preset_lbl.set_label(f"✨ Active preset: {GLib.markup_escape_text(self._active_preset_name)}") + self._active_preset_lbl.set_use_markup(True) + else: + self._active_preset_lbl.set_label("Using custom animations") + self._active_preset_lbl.set_use_markup(False) + + if hasattr(self, "_custom_switch_grp"): + self._custom_switch_grp.set_visible(self._prev_anim_snapshot is not None) + + def _build_custom_tab(self) -> Gtk.Widget: + """Return the custom animations tab (global toggles, bezier editor, and categories).""" + if not hasattr(self, "_custom_scroll"): + self._custom_scroll = Gtk.ScrolledWindow() + self._custom_scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) + self._custom_scroll.set_vexpand(True) + self._custom_content = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=20) + self._custom_content.set_hexpand(True) + self._custom_content.set_margin_start(24) + self._custom_content.set_margin_end(24) + self._custom_content.set_margin_top(24) + self._custom_content.set_margin_bottom(24) + self._custom_scroll.set_child(self._custom_content) + else: + while child := self._custom_content.get_first_child(): + self._custom_content.remove(child) + + content = self._custom_content + anim_node = find_or_create(self._nodes, "animations") + + # ── Switch to Custom Banner ────────────────────────────────────────── + self._custom_switch_grp = Adw.PreferencesGroup() + self._custom_switch_grp.set_hexpand(True) + self._custom_switch_row = Adw.ActionRow( + title="Community Preset Active", + subtitle="You are currently using a preset. Switch back to use your custom animation settings." + ) + self._custom_switch_row.add_css_class("property") + self._custom_switch_row.set_icon_name("emblem-important-symbolic") + switch_btn = Gtk.Button(label="Switch to Custom") + switch_btn.add_css_class("suggested-action") + switch_btn.add_css_class("pill") + switch_btn.set_valign(Gtk.Align.CENTER) + switch_btn.set_margin_top(8) + switch_btn.set_margin_bottom(8) + switch_btn.connect("clicked", self._on_restore_previous) + self._custom_switch_row.add_suffix(switch_btn) + self._custom_switch_grp.add(self._custom_switch_row) + self._custom_switch_grp.set_visible(self._prev_anim_snapshot is not None) + content.append(self._custom_switch_grp) + + # ── Global Settings ────────────────────────────────────────────────── + off_grp = Adw.PreferencesGroup( + title="Global Settings", + description="These apply to all animations universally." + ) + off_grp.set_hexpand(True) + off_row = Adw.SwitchRow(title="Enable Animations", subtitle="Toggle all desktop animations on or off") + off_row.set_icon_name("media-playback-start-symbolic") + off_row.set_active(anim_node.get_child("off") is None) + off_row.connect( + "notify::active", lambda r, _: self._toggle_all(not r.get_active()) + ) + off_grp.add(off_row) + + slowdown_val = float(anim_node.child_arg("slowdown") or 1.0) + slowdown_adj = Gtk.Adjustment( + value=slowdown_val, lower=0.1, upper=10.0, step_increment=0.1 + ) + slowdown_row = Adw.SpinRow( + title="Global Slowdown Factor", + subtitle="Multiply all animation durations by this factor", + adjustment=slowdown_adj, digits=1 + ) + slowdown_row.set_icon_name("preferences-system-time-symbolic") + slowdown_row._last_val = slowdown_val + + def _on_slowdown_changed(r, _): + new_val = float(r.get_value()) + if abs(new_val - getattr(r, "_last_val", 0.0)) > 0.01: + r._last_val = new_val + self._set_anim("slowdown", new_val) + + slowdown_row.connect("notify::value", _on_slowdown_changed) + off_grp.add(slowdown_row) + content.append(off_grp) + + # ── Easing Curve Editor ────────────────────────────────────────────── + bezier_grp = Adw.PreferencesGroup( + title="Easing Curve Editor", + description="Design a custom easing curve to apply to any animation below." + ) + bezier_grp.set_hexpand(True) + + editor_row = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=48) + editor_row.set_margin_start(12) + editor_row.set_margin_end(12) + editor_row.set_margin_top(20) + editor_row.set_margin_bottom(20) + editor_row.set_halign(Gtk.Align.CENTER) + + # Left: bezier canvas + edit_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10) + edit_vbox.set_valign(Gtk.Align.CENTER) + self._bezier_editor = BezierEditor(on_changed=self._on_bezier_changed) + self._bezier_editor.set_halign(Gtk.Align.CENTER) + edit_vbox.append(self._bezier_editor) + + coords_lbl = Gtk.Label(label="0.25, 0.1, 0.25, 1.0") + coords_lbl.add_css_class("monospace") + coords_lbl.add_css_class("dim-label") + coords_lbl.set_selectable(True) + coords_lbl.set_halign(Gtk.Align.CENTER) + self._coords_lbl = coords_lbl + edit_vbox.append(coords_lbl) + editor_row.append(edit_vbox) + + # Right: quick presets + presets_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=16) + presets_vbox.set_valign(Gtk.Align.CENTER) + preset_title = Gtk.Label(label="Quick Presets", xalign=0) + preset_title.add_css_class("heading") + presets_vbox.append(preset_title) + + flow = Gtk.FlowBox() + flow.set_selection_mode(Gtk.SelectionMode.NONE) + flow.set_max_children_per_line(2) + flow.set_min_children_per_line(2) + flow.set_valign(Gtk.Align.START) + flow.set_column_spacing(6) + flow.set_row_spacing(6) + for name, curve in PRESET_CURVES.items(): + btn = Gtk.Button(label=name) + btn.connect("clicked", lambda b, c=curve, n=name: self._apply_preset(c, n)) + flow.append(btn) + presets_vbox.append(flow) + editor_row.append(presets_vbox) + + bezier_grp.add(editor_row) + content.append(bezier_grp) + + # ── Per-animation groups ───────────────────────────────────────────── + for group_title, anims in ANIM_GROUPS: + grp = Adw.PreferencesGroup(title=group_title) + grp.set_hexpand(True) + for anim_key, anim_label, icon_name in anims: + row = self._build_anim_row(anim_key, anim_label, icon_name, anim_node) + grp.add(row) + content.append(grp) + + return self._custom_scroll + + def _build_presets_tab(self) -> Gtk.Widget: + """Return the community presets tab (downloaded + online sources).""" + scroll = Gtk.ScrolledWindow() + scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) + scroll.set_vexpand(True) + + content = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=20) + content.set_hexpand(True) + content.set_margin_start(24) + content.set_margin_end(24) + content.set_margin_top(24) + content.set_margin_bottom(24) + scroll.set_child(content) + + # Downloaded / offline section — always shown first + self._presets_content = content + self._local_presets_grp: Adw.PreferencesGroup | None = None + self._refresh_local_presets_group() + + nim_grp = self._build_nirimation_group() + nim_grp.set_hexpand(True) + content.append(nim_grp) + + jgarza_grp = self._build_jgarza_group() + jgarza_grp.set_hexpand(True) + content.append(jgarza_grp) + + return scroll + + # ------------------------------------------------------------------ local + + def _local_preset_dir(self, source_label: str) -> Path: + slug = _SOURCE_SLUGS.get(source_label, source_label.replace("/", "-")) + return _LOCAL_PRESETS_DIR / slug + + def _list_local_presets(self) -> list[dict]: + """Return all downloaded presets sorted by display name.""" + entries: list[dict] = [] + if not _LOCAL_PRESETS_DIR.exists(): + return entries + for source_dir in sorted(_LOCAL_PRESETS_DIR.iterdir()): + if not source_dir.is_dir(): + continue + # Reverse-map slug → label + slug_to_label = {v: k for k, v in _SOURCE_SLUGS.items()} + source_label = slug_to_label.get(source_dir.name, source_dir.name) + for kdl_file in sorted(source_dir.glob("*.kdl")): + stem = kdl_file.stem + display = stem.replace("-", " ").replace("_", " ").title() + entries.append( + { + "name": kdl_file.name, + "display_name": display, + "source_label": source_label, + "local_path": kdl_file, + } + ) + return entries + + def _refresh_local_presets_group(self): + """Rebuild the Downloaded Presets group from the filesystem.""" + # Remove the old group widget from the content box if present + if self._local_presets_grp is not None and hasattr(self, "_presets_content"): + try: + self._presets_content.remove(self._local_presets_grp) + except Exception: + pass + + entries = self._list_local_presets() + + grp = Adw.PreferencesGroup( + title="Downloaded Presets", + description="Locally saved presets — apply these without an internet connection.", + ) + grp.set_hexpand(True) + grp.set_header_suffix(self._make_open_folder_btn()) + self._local_presets_grp = grp + + if not entries: + empty_row = Adw.ActionRow( + title="No presets downloaded yet", + subtitle="Use the download button (\u2193) next to any online preset below.", + ) + empty_row.add_prefix(Gtk.Image.new_from_icon_name("folder-download-symbolic")) + grp.add(empty_row) + else: + for entry in entries: + row = self._make_local_preset_row(entry) + grp.add(row) + + # Prepend at the top of the presets content box + if hasattr(self, "_presets_content"): + # Insert before the first child (nirimation group) + first = self._presets_content.get_first_child() + if first: + self._presets_content.insert_child_after(grp, None) # prepend + else: + self._presets_content.append(grp) + + + def _make_open_folder_btn(self) -> Gtk.Button: + btn = Gtk.Button(icon_name="folder-open-symbolic") + btn.set_tooltip_text("Open presets folder") + btn.add_css_class("flat") + btn.add_css_class("circular") + btn.connect( + "clicked", + lambda _b: Gtk.show_uri(None, _LOCAL_PRESETS_DIR.as_uri(), 0), + ) + return btn + + def _make_local_preset_row(self, entry: dict) -> Adw.ActionRow: + """Row for a locally-downloaded preset (Apply + Delete).""" + row = Adw.ActionRow( + title=entry["display_name"], + subtitle=f"{entry['source_label']} · {entry['name']}", + ) + row.add_prefix(Gtk.Image.new_from_icon_name("drive-harddisk-symbolic")) + + # Delete button + del_btn = Gtk.Button(icon_name="user-trash-symbolic") + del_btn.set_tooltip_text("Delete local copy") + del_btn.add_css_class("flat") + del_btn.add_css_class("circular") + del_btn.set_valign(Gtk.Align.CENTER) + del_btn.connect( + "clicked", + lambda _b, e=entry: self._delete_local_preset(e), + ) + row.add_suffix(del_btn) + + # Apply button + apply_btn = Gtk.Button(label="Apply") + apply_btn.add_css_class("suggested-action") + apply_btn.add_css_class("pill") + apply_btn.set_valign(Gtk.Align.CENTER) + apply_btn.connect( + "clicked", + lambda _b, e=entry, r=row: self._confirm_apply_local_preset(e, r), + ) + row.add_suffix(apply_btn) + + return row + + def _confirm_apply_local_preset(self, entry: dict, row: Adw.ActionRow): + try: + dialog = Adw.AlertDialog( + heading=f"Apply \"{entry['display_name']}\"?", + body=( + "This will fully replace your current animations block with the locally saved " + f"\"{entry['display_name']}\" preset.\n\n" + "Your existing bezier curves and per-animation settings will be overwritten. " + "You can undo this with Ctrl+Z." + ), + ) + dialog.add_response("cancel", "Cancel") + dialog.add_response("apply", "Apply Preset") + dialog.set_response_appearance("apply", Adw.ResponseAppearance.SUGGESTED) + dialog.set_default_response("cancel") + dialog.set_close_response("cancel") + + def _on_response(d, resp): + if resp == "apply": + self._apply_local_preset(entry, row) + + dialog.connect("response", _on_response) + dialog.present(self._win) + except AttributeError: + self._apply_local_preset(entry, row) + + def _apply_local_preset(self, entry: dict, row: Adw.ActionRow): + """Apply a locally-saved .kdl file (no network required).""" + try: + kdl_text = entry["local_path"].read_text(encoding="utf-8") + self._do_apply_kdl_preset(kdl_text, entry["display_name"], row) + except Exception as exc: + self.show_toast(f"Failed to read local preset: {exc}") + + def _delete_local_preset(self, entry: dict): + try: + entry["local_path"].unlink(missing_ok=True) + # Clean up empty source dir + parent = entry["local_path"].parent + if parent.exists() and not any(parent.iterdir()): + parent.rmdir() + self.show_toast(f"🗑 {entry['display_name']} deleted") + self._refresh_local_presets_group() + except Exception as exc: + self.show_toast(f"Delete failed: {exc}") + + def _on_restore_previous(self, _btn): + """Restore the animations block that was saved before the last preset apply.""" + if self._prev_anim_snapshot is None: + return + try: + snap_nodes = parse_kdl(self._prev_anim_snapshot) + snap_anim = next((n for n in snap_nodes if n.name == "animations"), None) + user_nodes = self._nodes + user_anim = next((n for n in reversed(user_nodes) if n.name == "animations"), None) + if user_anim is None: + user_anim = KdlNode(name="animations") + user_anim.leading_trivia = "\n" + user_nodes.append(user_anim) + if snap_anim is not None: + user_anim.children = list(snap_anim.children) + user_anim.args = list(snap_anim.args) + user_anim.props = dict(snap_anim.props) + else: + user_anim.children = [] + user_anim.args = [] + user_anim.props = {} + self._prev_anim_snapshot = None + self._active_preset_name = None + self._save_state() + self._commit("restore previous animations") + self.show_toast("↩ Previous animations restored") + self._update_header() + self._build_custom_tab() # Refresh UI components + except Exception as exc: + self.show_toast(f"Restore failed: {exc}") + + def _build_preset_group( + self, + title: str, + description: str, + fetch_fn, + bust_cache_attr: str, + rows_attr: str, + source_label: str, + repo_url: str, + ) -> Adw.PreferencesGroup: + """Generic builder for a community-preset PreferencesGroup.""" + import sys + mod = sys.modules[__name__] + + header_btns = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6) + + repo_btn = Gtk.Button(icon_name="web-browser-symbolic") + repo_btn.set_tooltip_text("View repository on GitHub") + repo_btn.add_css_class("flat") + repo_btn.add_css_class("circular") + repo_btn.connect("clicked", lambda _b: Gtk.show_uri(None, repo_url, 0)) + header_btns.append(repo_btn) + + refresh_btn = Gtk.Button(icon_name="view-refresh-symbolic") + refresh_btn.set_tooltip_text("Refresh preset list from GitHub") + refresh_btn.add_css_class("flat") + refresh_btn.add_css_class("circular") + header_btns.append(refresh_btn) + + grp = Adw.PreferencesGroup(title=title, description=description) + grp.set_header_suffix(header_btns) + + spinner = Gtk.Spinner() + spinner.start() + spinner.set_margin_top(8) + spinner.set_margin_bottom(8) + spinner_row = Adw.ActionRow(title="Fetching presets…") + spinner_row.add_prefix(spinner) + grp.add(spinner_row) + + rows: list[Adw.ActionRow] = [] + setattr(self, rows_attr, rows) + + def _on_result(result): + grp.remove(spinner_row) + spinner.stop() + if isinstance(result, Exception): + err_row = Adw.ActionRow( + title="Unable to fetch presets", + subtitle=str(result), + ) + err_row.add_prefix(Gtk.Image.new_from_icon_name("network-error-symbolic")) + grp.add(err_row) + rows.append(err_row) + return + for entry in result: + row = self._make_preset_row(entry, source_label) + grp.add(row) + rows.append(row) + + def _on_refresh_clicked(_btn): + setattr(mod, bust_cache_attr, None) + for row in list(rows): + grp.remove(row) + rows.clear() + sp2 = Gtk.Spinner() + sp2.start() + sp2.set_margin_top(8) + sp2.set_margin_bottom(8) + wait_row = Adw.ActionRow(title="Fetching presets…") + wait_row.add_prefix(sp2) + grp.add(wait_row) + + def _on_result2(result): + grp.remove(wait_row) + sp2.stop() + if isinstance(result, Exception): + err_row = Adw.ActionRow( + title="Unable to fetch presets", + subtitle=str(result), + ) + err_row.add_prefix(Gtk.Image.new_from_icon_name("network-error-symbolic")) + grp.add(err_row) + rows.append(err_row) + return + for entry in result: + row = self._make_preset_row(entry, source_label) + grp.add(row) + rows.append(row) + + fetch_fn(_on_result2) + + refresh_btn.connect("clicked", _on_refresh_clicked) + fetch_fn(_on_result) + return grp + + def _build_nirimation_group(self) -> Adw.PreferencesGroup: + """Build the XansiVA/nirimation presets section.""" + return self._build_preset_group( + title="Nirimation Community Presets", + description="GLSL shader animations from XansiVA/nirimation — replaces your current animations block.", + fetch_fn=_fetch_nirimation_presets, + bust_cache_attr="_nirimation_cache", + rows_attr="_nirimation_rows", + source_label="XansiVA/nirimation", + repo_url="https://github.com/XansiVA/nirimation", + ) + + def _build_jgarza_group(self) -> Adw.PreferencesGroup: + """Build the jgarza9788/niri-animation-collection presets section.""" + return self._build_preset_group( + title="Niri Animation Collection", + description="Community GLSL shader presets from jgarza9788/niri-animation-collection — replaces your current animations block.", + fetch_fn=_fetch_jgarza_presets, + bust_cache_attr="_jgarza_cache", + rows_attr="_jgarza_rows", + source_label="jgarza9788/niri-animation-collection", + repo_url="https://github.com/jgarza9788/niri-animation-collection", + ) + + def _make_preset_row(self, entry: dict, source_label: str) -> Adw.ActionRow: + """Create a single preset row for any community-preset group.""" + row = Adw.ActionRow( + title=entry["display_name"], + subtitle=entry["name"], + ) + + # Download-to-disk button + dl_btn = Gtk.Button(icon_name="folder-download-symbolic") + dl_btn.set_tooltip_text("Download preset for offline use") + dl_btn.add_css_class("flat") + dl_btn.add_css_class("circular") + dl_btn.set_valign(Gtk.Align.CENTER) + dl_btn.connect( + "clicked", + lambda _b, e=entry, r=row, sl=source_label, b=dl_btn: self._download_preset_locally(e, r, sl, b), + ) + row.add_suffix(dl_btn) + + # Apply button + apply_btn = Gtk.Button(label="Apply") + apply_btn.add_css_class("suggested-action") + apply_btn.add_css_class("pill") + apply_btn.set_valign(Gtk.Align.CENTER) + apply_btn.connect( + "clicked", + lambda _b, e=entry, r=row, sl=source_label: self._confirm_apply_preset(e, r, sl), + ) + row.add_suffix(apply_btn) + + return row + + def _download_preset_locally(self, entry, row, source_label, dl_btn): + # download the preset KDL to disk + dest_dir = self._local_preset_dir(source_label) + dest_file = dest_dir / entry["name"] + + dl_btn.set_sensitive(False) + self.show_toast(f"Downloading {entry['display_name']}…", timeout=5) + + def _worker(): + try: + req = urllib.request.Request( + entry["download_url"], + headers={"User-Agent": "nirimod/1.0"}, + ) + with urllib.request.urlopen(req, timeout=10) as resp: + kdl_bytes = resp.read() + GLib.idle_add(_on_done, kdl_bytes, None) + except Exception as exc: + GLib.idle_add(_on_done, None, exc) + + def _on_done(kdl_bytes, error): + dl_btn.set_sensitive(True) + if error: + self.show_toast(f"Download failed: {error}") + return + try: + dest_dir.mkdir(parents=True, exist_ok=True) + dest_file.write_bytes(kdl_bytes) + self.show_toast(f"{entry['display_name']} saved locally") + # Update the download button to show it's already saved + dl_btn.set_icon_name("emblem-ok-symbolic") + dl_btn.set_tooltip_text("Already downloaded") + dl_btn.set_sensitive(False) + self._refresh_local_presets_group() + except Exception as exc: + self.show_toast(f"Save failed: {exc}") + + threading.Thread(target=_worker, daemon=True).start() + + + def _confirm_apply_preset(self, entry, row, source_label="community"): + try: + dialog = Adw.AlertDialog( + heading=f"Apply \"{entry['display_name']}\"?", + body=( + "This will fully replace your current animations block with the " + f"\"{entry['display_name']}\" preset from {source_label}.\n\n" + "Your existing bezier curves and per-animation settings will be overwritten. " + "You can undo this with Ctrl+Z." + ), + ) + dialog.add_response("cancel", "Cancel") + dialog.add_response("apply", "Apply Preset") + dialog.set_response_appearance("apply", Adw.ResponseAppearance.SUGGESTED) + dialog.set_default_response("cancel") + dialog.set_close_response("cancel") + + def _on_response(d, resp): + if resp == "apply": + self._apply_nirimation_preset(entry, row) + + dialog.connect("response", _on_response) + dialog.present(self._win) + except AttributeError: + self._apply_nirimation_preset(entry, row) + + + def _apply_nirimation_preset(self, entry, row): + row.set_sensitive(False) + self.show_toast(f"Downloading {entry['display_name']}...", timeout=5) + + def _worker(): + try: + req = urllib.request.Request( + entry["download_url"], + headers={"User-Agent": "nirimod/1.0"}, + ) + with urllib.request.urlopen(req, timeout=10) as resp: + kdl_text = resp.read().decode() + GLib.idle_add(_on_downloaded, kdl_text, None) + except Exception as exc: + GLib.idle_add(_on_downloaded, None, exc) + + def _on_downloaded(kdl_text, error): + row.set_sensitive(True) + if error: + self.show_toast(f"Failed to download preset: {error}") + return + self._do_apply_kdl_preset(kdl_text, entry["display_name"], row) + + threading.Thread(target=_worker, daemon=True).start() + + def _do_apply_kdl_preset(self, kdl_text, display_name, row): + try: + preset_nodes = parse_kdl(kdl_text) + preset_anim = next( + (n for n in preset_nodes if n.name == "animations"), None + ) + if preset_anim is None: + self.show_toast("Preset has no animations block — nothing applied.") + return + + user_nodes = self._nodes + user_anim = next( + (n for n in reversed(user_nodes) if n.name == "animations"), None + ) + + + if self._prev_anim_snapshot is None: + from nirimod.kdl_parser import write_kdl + if user_anim is not None: + snap_node = KdlNode(name="animations") + snap_node.children = list(user_anim.children) + snap_node.args = list(user_anim.args) + snap_node.props = dict(user_anim.props) + self._prev_anim_snapshot = write_kdl([snap_node]) + else: + self._prev_anim_snapshot = write_kdl([]) + + if user_anim is None: + user_anim = KdlNode(name="animations") + user_anim.leading_trivia = "\n" + user_nodes.append(user_anim) + + user_anim.children = list(preset_anim.children) + user_anim.args = list(preset_anim.args) + user_anim.props = dict(preset_anim.props) + + self._active_preset_name = display_name + self._save_state() + self._commit(f"preset: {display_name}") + self._update_header() + self.show_toast(f"\u2728 {display_name} preset applied!") + except Exception as exc: + self.show_toast(f"Error applying preset: {exc}") + + def _apply_preset(self, curve: tuple, name: str): + self._bezier_editor.set_curve(*curve) + self._update_coords_label() + + def _on_bezier_changed(self, x1, y1, x2, y2): + self._update_coords_label() + + def _update_coords_label(self): + x1, y1, x2, y2 = self._bezier_editor.get_curve() + self._coords_lbl.set_label(f"{x1:.3f}, {y1:.3f}, {x2:.3f}, {y2:.3f}") + + def _build_anim_row( + self, key: str, label: str, icon_name: str, anim_node: KdlNode + ) -> Adw.ExpanderRow: + grp = Adw.ExpanderRow(title=label) + grp.set_icon_name(icon_name) + grp.add_css_class("nm-expander") + an = anim_node.get_child(key) + + enabled_row = Adw.SwitchRow(title="Enabled") + enabled_row.set_active(an is not None and an.get_child("off") is None) + enabled_row.connect( + "notify::active", + lambda r, _, k=key: self._set_anim_enabled(k, r.get_active()), + ) + grp.add_row(enabled_row) + + duration = an.child_arg("duration-ms") if an else 250 + dur_val = int(duration) if duration else 250 + dur_adj = Gtk.Adjustment(value=dur_val, lower=10, upper=2000, step_increment=10) + dur_row = Adw.SpinRow(title="Duration (ms)", adjustment=dur_adj, digits=0) + + dur_row._last_val = dur_val + + def _on_dur_changed(r, _, k=key): + new_val = int(r.get_value()) + if new_val != getattr(r, "_last_val", None): + r._last_val = new_val + self._set_anim_prop(k, "duration-ms", new_val) + + dur_row.connect("notify::value", _on_dur_changed) + grp.add_row(dur_row) + + # Apply bezier button + apply_btn = Gtk.Button(label="Apply Editor Curve") + apply_btn.add_css_class("flat") + apply_btn.set_valign(Gtk.Align.CENTER) + + # Determine current curve for subtitle + + curve_node = an.get_child("curve") if an else None + easing = an.get_child("easing") if an else None + current_curve = "" + if curve_node and len(curve_node.args) >= 5: + vals = " ".join(str(v) for v in curve_node.args[1:]) + current_curve = f"cubic-bezier {vals}" + elif easing and easing.child_arg("bezier"): + current_curve = f"bezier {easing.child_arg('bezier')}" + elif easing and easing.args: + current_curve = str(easing.args[0]) + + apply_row = Adw.ActionRow(title="Easing Curve", subtitle=current_curve if current_curve else "Default") + apply_btn.connect("clicked", lambda *_, k=key, ar=apply_row: self._apply_bezier_to_anim(k, ar)) + apply_row.add_suffix(apply_btn) + grp.add_row(apply_row) + + return grp + + def _toggle_all(self, off: bool): + anim = find_or_create(self._nodes, "animations") + set_node_flag(anim, "off", off) + self._commit("animations off") + + def _set_anim(self, key: str, value): + anim = find_or_create(self._nodes, "animations") + set_child_arg(anim, key, value) + self._commit(f"animations {key}") + + def _set_anim_enabled(self, anim_key: str, enabled: bool): + anim = find_or_create(self._nodes, "animations") + an = anim.get_child(anim_key) + if not enabled: + if an is None: + an = KdlNode(anim_key) + anim.children.append(an) + set_node_flag(an, "off", True) + else: + if an: + from nirimod.kdl_parser import remove_child + + remove_child(an, "off") + self._commit(f"animation {anim_key} enabled") + + def _set_anim_prop(self, anim_key: str, prop: str, value): + anim = find_or_create(self._nodes, "animations") + an = anim.get_child(anim_key) + if an is None: + an = KdlNode(anim_key) + anim.children.append(an) + + if prop == "duration-ms": + from nirimod.kdl_parser import remove_child + remove_child(an, "spring") + + set_child_arg(an, prop, value) + self._commit(f"animation {anim_key} {prop}") + + def _apply_bezier_to_anim(self, anim_key: str, apply_row: Adw.ActionRow = None): + x1, y1, x2, y2 = self._bezier_editor.get_curve() + anim = find_or_create(self._nodes, "animations") + an = anim.get_child(anim_key) + if an is None: + an = KdlNode(anim_key) + anim.children.append(an) + + # Remove legacy easing block if present + old_easing = an.get_child("easing") + if old_easing is not None: + an.children.remove(old_easing) + + from nirimod.kdl_parser import remove_child + remove_child(an, "spring") + + curve_node = an.get_child("curve") + if curve_node is None: + curve_node = KdlNode("curve") + an.children.append(curve_node) + curve_node.args = ["cubic-bezier", round(x1, 3), round(y1, 3), round(x2, 3), round(y2, 3)] + + curve_str = f"{x1:.3f} {y1:.3f} {x2:.3f} {y2:.3f}" + self._commit(f"animation {anim_key} bezier") + self.show_toast(f"Bezier applied to {anim_key}") + + if apply_row: + apply_row.set_subtitle(f"cubic-bezier {curve_str}") diff --git a/nirimod/pages/appearance.py b/nirimod/pages/appearance.py new file mode 100644 index 0000000..12ed4a7 --- /dev/null +++ b/nirimod/pages/appearance.py @@ -0,0 +1,452 @@ +"""Appearance page — borders, focus ring, shadows, corner radius.""" + +from __future__ import annotations + + +import gi + +gi.require_version("Gtk", "4.0") +gi.require_version("Adw", "1") +from gi.repository import Adw, Gdk, Gtk + +from nirimod.kdl_parser import KdlNode, find_or_create, set_child_arg, set_node_flag +from nirimod.pages.base import BasePage +from nirimod.window_effects import ( + blur_effects_enabled, + focused_window_blur_enabled, + get_global_draw_border_with_background, + get_global_corner_radius, + get_global_window_opacity, + global_window_blur_enabled, + global_window_xray_enabled, + set_focused_window_blur, + set_global_draw_border_with_background, + set_global_corner_radius, + set_global_window_blur, + set_global_window_opacity, + set_global_window_xray, + set_blur_effects_enabled, +) + + +def _parse_color(color_str: str) -> Gdk.RGBA: + rgba = Gdk.RGBA() + if color_str and not rgba.parse(color_str): + rgba.parse("#7fc8ff") + return rgba + + +class AppearancePage(BasePage): + def build(self) -> Gtk.Widget: + tb, _, _, content = self._make_toolbar_page("Appearance") + self._content = content + self._build_content() + return tb + + def _build_content(self): + content = self._content + nodes = self._nodes + layout = find_or_create(nodes, "layout") + + fr_node = layout.get_child("focus-ring") or KdlNode("focus-ring") + fr_group = self._build_border_group("Focus Ring", "focus-ring", fr_node, layout) + content.append(fr_group) + + b_node = layout.get_child("border") or KdlNode("border") + b_group = self._build_border_group("Border", "border", b_node, layout) + content.append(b_group) + + shadow_grp = Adw.PreferencesGroup(title="Shadow") + shadow_node = layout.get_child("shadow") or KdlNode("shadow") + + shadow_on_row = Adw.SwitchRow(title="Enable Shadows") + shadow_on_row.set_active(shadow_node.get_child("on") is not None) + shadow_on_row.connect( + "notify::active", lambda r, _: self._set_shadow_flag("on", r.get_active()) + ) + shadow_grp.add(shadow_on_row) + + soft_val = int(shadow_node.child_arg("softness") or 30) + softness_adj = Gtk.Adjustment( + value=soft_val, lower=0, upper=100, step_increment=1 + ) + softness_row = Adw.SpinRow( + title="Softness (blur radius)", adjustment=softness_adj, digits=0 + ) + + softness_row._last_val = soft_val + + def _on_soft_changed(r, _): + new_val = int(r.get_value()) + if new_val != getattr(r, "_last_val", None): + r._last_val = new_val + self._set_shadow("softness", new_val) + + softness_row.connect("notify::value", _on_soft_changed) + shadow_grp.add(softness_row) + + spread_val = int(shadow_node.child_arg("spread") or 5) + spread_adj = Gtk.Adjustment( + value=spread_val, lower=-50, upper=100, step_increment=1 + ) + spread_row = Adw.SpinRow(title="Spread", adjustment=spread_adj, digits=0) + + spread_row._last_val = spread_val + + def _on_spread_changed(r, _): + new_val = int(r.get_value()) + if new_val != getattr(r, "_last_val", None): + r._last_val = new_val + self._set_shadow("spread", new_val) + + spread_row.connect("notify::value", _on_spread_changed) + shadow_grp.add(spread_row) + + color_str = shadow_node.child_arg("color") or "#0007" + color_row = Adw.ActionRow(title="Shadow Color") + color_btn = Gtk.ColorDialogButton( + dialog=Gtk.ColorDialog(title="Shadow Color", with_alpha=True) + ) + color_btn.set_rgba(_parse_color(color_str)) + color_btn.set_valign(Gtk.Align.CENTER) + color_btn.connect( + "notify::rgba", lambda b, _: self._set_shadow_color(b.get_rgba()) + ) + color_row.add_suffix(color_btn) + shadow_grp.add(color_row) + + draw_behind_row = Adw.SwitchRow( + title="Draw Behind Window", + subtitle="Fixes corner artifacts with non-CSD apps", + ) + draw_behind_row.set_active( + shadow_node.get_child("draw-behind-window") is not None + ) + draw_behind_row.connect( + "notify::active", + lambda r, _: self._set_shadow_flag("draw-behind-window", r.get_active()), + ) + shadow_grp.add(draw_behind_row) + content.append(shadow_grp) + + blur_grp = Adw.PreferencesGroup( + title="Blur (Global)", + description=( + "Requires Niri 26.04 or later. Sets blur quality and optional " + "window blur rules." + ), + ) + blur_node = next((n for n in nodes if n.name == "blur"), None) + + blur_effects_row = Adw.SwitchRow( + title="Enable Blur Effects", + subtitle="Controls the compositor-level blur { off } setting", + ) + blur_effects_row.set_active(blur_effects_enabled(nodes)) + blur_effects_row.connect( + "notify::active", + lambda r, _: self._set_blur_effects_enabled(r.get_active()), + ) + blur_grp.add(blur_effects_row) + + blur_enabled_row = Adw.SwitchRow( + title="Force Blur on Windows", + subtitle="Adds background-effect { blur true } to the global window rule", + ) + blur_enabled_row.set_active(global_window_blur_enabled(nodes)) + blur_enabled_row.connect( + "notify::active", + lambda r, _: self._set_window_blur_enabled(r.get_active()), + ) + blur_grp.add(blur_enabled_row) + + focused_blur_row = Adw.SwitchRow( + title="Keep Focused Windows Blurred", + subtitle="Adds a focused-window rule that forces blur on", + ) + focused_blur_row.set_active(focused_window_blur_enabled(nodes)) + focused_blur_row.connect( + "notify::active", + lambda r, _: self._set_focused_window_blur_enabled(r.get_active()), + ) + blur_grp.add(focused_blur_row) + + xray_row = Adw.SwitchRow( + title="Use Xray Wallpaper Blur", + subtitle="Use wallpaper-only blur; disable for regular background blur", + ) + xray_row.set_active(global_window_xray_enabled(nodes)) + xray_row.connect( + "notify::active", + lambda r, _: self._set_window_blur_xray(r.get_active()), + ) + blur_grp.add(xray_row) + + opacity_val = get_global_window_opacity(nodes) + opacity_adj = Gtk.Adjustment( + value=opacity_val, lower=0.1, upper=1.0, step_increment=0.05 + ) + opacity_row = Adw.SpinRow( + title="Window Opacity (1 = unset)", adjustment=opacity_adj, digits=2 + ) + + opacity_row._last_val = opacity_val + + def _on_opacity_changed(r, _): + new_val = round(float(r.get_value()), 2) + if new_val != getattr(r, "_last_val", None): + r._last_val = new_val + self._set_window_opacity(new_val) + + opacity_row.connect("notify::value", _on_opacity_changed) + blur_grp.add(opacity_row) + + border_bg_row = Adw.SwitchRow( + title="Draw Border With Background", + subtitle="Disable to avoid focus colors behind translucent windows", + ) + border_bg_row.set_active(get_global_draw_border_with_background(nodes)) + border_bg_row.connect( + "notify::active", + lambda r, _: self._set_draw_border_with_background(r.get_active()), + ) + blur_grp.add(border_bg_row) + + passes_val = int(blur_node.child_arg("passes", 0) if blur_node else 0) + passes_adj = Gtk.Adjustment( + value=passes_val, lower=0, upper=10, step_increment=1 + ) + passes_row = Adw.SpinRow( + title="Passes", adjustment=passes_adj, digits=0 + ) + + passes_row._last_val = passes_val + + def _on_passes_changed(r, _): + new_val = int(r.get_value()) + if new_val != getattr(r, "_last_val", None): + r._last_val = new_val + self._set_blur("passes", new_val) + + passes_row.connect("notify::value", _on_passes_changed) + blur_grp.add(passes_row) + + offset_val = float(blur_node.child_arg("offset", 2.0) if blur_node else 2.0) + offset_adj = Gtk.Adjustment( + value=offset_val, lower=0.0, upper=20.0, step_increment=0.1 + ) + offset_row = Adw.SpinRow(title="Offset", adjustment=offset_adj, digits=1) + + offset_row._last_val = offset_val + + def _on_offset_changed(r, _): + new_val = float(r.get_value()) + if new_val != getattr(r, "_last_val", None): + r._last_val = new_val + self._set_blur("offset", new_val) + + offset_row.connect("notify::value", _on_offset_changed) + blur_grp.add(offset_row) + + noise_val = float(blur_node.child_arg("noise", 0.0) if blur_node else 0.0) + noise_adj = Gtk.Adjustment( + value=noise_val, lower=0.0, upper=1.0, step_increment=0.01 + ) + noise_row = Adw.SpinRow(title="Noise", adjustment=noise_adj, digits=2) + + noise_row._last_val = noise_val + + def _on_noise_changed(r, _): + new_val = float(r.get_value()) + if new_val != getattr(r, "_last_val", None): + r._last_val = new_val + self._set_blur("noise", new_val) + + noise_row.connect("notify::value", _on_noise_changed) + blur_grp.add(noise_row) + + saturation_val = float(blur_node.child_arg("saturation", 1.0) if blur_node else 1.0) + saturation_adj = Gtk.Adjustment( + value=saturation_val, lower=0.0, upper=5.0, step_increment=0.1 + ) + saturation_row = Adw.SpinRow( + title="Saturation", adjustment=saturation_adj, digits=1 + ) + + saturation_row._last_val = saturation_val + + def _on_saturation_changed(r, _): + new_val = float(r.get_value()) + if new_val != getattr(r, "_last_val", None): + r._last_val = new_val + self._set_blur("saturation", new_val) + + saturation_row.connect("notify::value", _on_saturation_changed) + blur_grp.add(saturation_row) + + content.append(blur_grp) + + misc_grp = Adw.PreferencesGroup(title="Window Geometry") + + cr_val = get_global_corner_radius(nodes) + cr_adj = Gtk.Adjustment(value=cr_val, lower=0, upper=40, step_increment=1) + cr_row = Adw.SpinRow( + title="Corner Radius (px)", + adjustment=cr_adj, + digits=0, + ) + + cr_row._last_val = cr_val + + def _on_cr_changed(r, _): + new_val = int(r.get_value()) + if new_val != getattr(r, "_last_val", None): + r._last_val = new_val + self._set_corner_radius(new_val) + + cr_row.connect("notify::value", _on_cr_changed) + misc_grp.add(cr_row) + content.append(misc_grp) + + def _build_border_group( + self, title: str, key: str, node: KdlNode, layout: KdlNode + ) -> Adw.PreferencesGroup: + grp = Adw.PreferencesGroup(title=title) + + off_row = Adw.SwitchRow(title="Enable") + off_row.set_active(node.get_child("off") is None) + off_row.connect( + "notify::active", + lambda r, _, k=key: self._set_layout_border_flag( + k, "off", not r.get_active() + ), + ) + grp.add(off_row) + + width_val = int(node.child_arg("width") or 4) + width_adj = Gtk.Adjustment(value=width_val, lower=1, upper=20, step_increment=1) + width_row = Adw.SpinRow(title="Width (px)", adjustment=width_adj, digits=0) + + width_row._last_val = width_val + + def _on_width_changed(r, _, k=key): + new_val = int(r.get_value()) + if new_val != getattr(r, "_last_val", None): + r._last_val = new_val + self._set_layout_border(k, "width", new_val) + + width_row.connect("notify::value", _on_width_changed) + grp.add(width_row) + + for color_key, color_label in [ + ("active-color", "Active Color"), + ("inactive-color", "Inactive Color"), + ]: + c_str = node.child_arg(color_key) or ( + "#7fc8ff" if "active" in color_key else "#202020" + ) + c_row = Adw.ActionRow(title=color_label) + c_btn = Gtk.ColorDialogButton( + dialog=Gtk.ColorDialog(title=color_label, with_alpha=True) + ) + c_btn.set_rgba(_parse_color(c_str)) + c_btn.set_valign(Gtk.Align.CENTER) + c_btn.connect( + "notify::rgba", + lambda b, _, k=key, ck=color_key: self._set_layout_border( + k, ck, self._rgba_to_hex(b.get_rgba()) + ), + ) + c_row.add_suffix(c_btn) + grp.add(c_row) + + return grp + + @staticmethod + def _rgba_to_hex(rgba: Gdk.RGBA) -> str: + r = int(rgba.red * 255) + g = int(rgba.green * 255) + b = int(rgba.blue * 255) + a = int(rgba.alpha * 255) + if a == 255: + return f"#{r:02x}{g:02x}{b:02x}" + return f"#{r:02x}{g:02x}{b:02x}{a:02x}" + + def _get_layout(self): + return find_or_create(self._nodes, "layout") + + def _get_border_node(self, key: str) -> KdlNode: + layout = self._get_layout() + node = layout.get_child(key) + if node is None: + node = KdlNode(key) + layout.children.append(node) + return node + + def _set_layout_border(self, bkey: str, prop: str, value): + node = self._get_border_node(bkey) + set_child_arg(node, prop, value) + self._commit(f"{bkey} {prop}") + + def _set_layout_border_flag(self, bkey: str, flag: str, enabled: bool): + node = self._get_border_node(bkey) + set_node_flag(node, flag, enabled) + self._commit(f"{bkey} {flag}") + + def _get_shadow_node(self) -> KdlNode: + layout = self._get_layout() + node = layout.get_child("shadow") + if node is None: + node = KdlNode("shadow") + layout.children.append(node) + return node + + def _set_shadow(self, prop: str, value): + set_child_arg(self._get_shadow_node(), prop, value) + self._commit(f"shadow {prop}") + + def _set_shadow_flag(self, flag: str, enabled: bool): + set_node_flag(self._get_shadow_node(), flag, enabled) + self._commit(f"shadow {flag}") + + def _set_shadow_color(self, rgba: Gdk.RGBA): + set_child_arg(self._get_shadow_node(), "color", self._rgba_to_hex(rgba)) + self._commit("shadow color") + + def _set_blur(self, prop: str, value): + blur_node = find_or_create(self._nodes, "blur") + set_child_arg(blur_node, prop, value) + self._commit(f"blur {prop}") + + def _set_blur_effects_enabled(self, enabled: bool): + set_blur_effects_enabled(self._nodes, enabled) + self._commit("blur effects") + + def _set_window_blur_enabled(self, enabled: bool): + set_global_window_blur(self._nodes, enabled) + self._commit("window blur") + + def _set_focused_window_blur_enabled(self, enabled: bool): + set_focused_window_blur(self._nodes, enabled) + self._commit("focused window blur") + + def _set_window_blur_xray(self, enabled: bool): + set_global_window_xray(self._nodes, enabled) + self._commit("window blur xray") + + def _set_window_opacity(self, opacity: float): + set_global_window_opacity(self._nodes, opacity) + self._commit("window opacity") + + def _set_draw_border_with_background(self, enabled: bool): + set_global_draw_border_with_background(self._nodes, enabled) + self._commit("draw border with background") + + def _set_corner_radius(self, radius: int): + set_global_corner_radius(self._nodes, radius) + self._commit("corner radius") + + def refresh(self): + for child in list(self._content): + self._content.remove(child) + self._build_content() diff --git a/nirimod/pages/base.py b/nirimod/pages/base.py new file mode 100644 index 0000000..4c6f88f --- /dev/null +++ b/nirimod/pages/base.py @@ -0,0 +1,98 @@ + + +from __future__ import annotations + +from typing import TYPE_CHECKING + +import gi + +gi.require_version("Gtk", "4.0") +gi.require_version("Adw", "1") +gi.require_version("Gio", "2.0") + +from gi.repository import Adw, Gtk, Gio + +if TYPE_CHECKING: + from nirimod.window import NiriModWindow + + +def make_toolbar_page( + title: str, + window=None, +) -> tuple[Adw.ToolbarView, Adw.HeaderBar, Gtk.ScrolledWindow, Gtk.Box]: + tb = Adw.ToolbarView() + header = Adw.HeaderBar() + tb.add_top_bar(header) + + # Hamburger menu on the content header (appears next to window close button) + if window is not None: + menu = Gio.Menu() + menu.append("Profiles", "win.open_profiles") + menu.append("Preferences", "win.open_preferences") + menu.append("Restore Backup...", "win.reset_config") + + kofi_section = Gio.Menu() + kofi_section.append("Support on Ko-fi ☕", "win.open_kofi") + menu.append_section(None, kofi_section) + + menu_btn = Gtk.MenuButton(icon_name="open-menu-symbolic") + menu_btn.set_tooltip_text("Menu") + menu_btn.add_css_class("flat") + menu_btn.set_menu_model(menu) + header.pack_end(menu_btn) + + scroll = Gtk.ScrolledWindow() + scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) + scroll.set_vexpand(True) + + content = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=20) + content.set_margin_start(32) + content.set_margin_end(32) + content.set_margin_top(24) + content.set_margin_bottom(32) + scroll.set_child(content) + tb.set_content(scroll) + + return tb, header, scroll, content + + +class BasePage: + def __init__(self, window: "NiriModWindow"): + self._win = window + + def _make_toolbar_page( + self, title: str + ) -> tuple[Adw.ToolbarView, Adw.HeaderBar, Gtk.ScrolledWindow, Gtk.Box]: + return make_toolbar_page(title, window=self._win) + + @property + def _nodes(self): + return self._win.get_nodes() + + def _commit(self, description: str = "change"): + app_state = self._win.app_state + after = app_state.write_current_kdl() + + before = app_state.undo.last_snapshot + if before is None: + before = app_state.saved_kdl + + if before != after: + self._win.push_undo(description, before, after) + + if after == app_state.saved_kdl: + self._win.mark_clean() + else: + self._win.mark_dirty() + + def build(self) -> Gtk.Widget: + raise NotImplementedError + + def refresh(self): + pass + + def on_shown(self): + pass + + def show_toast(self, msg: str, timeout: int = 3): + self._win.show_toast(msg, timeout) diff --git a/nirimod/pages/bindings.py b/nirimod/pages/bindings.py new file mode 100644 index 0000000..4129eac --- /dev/null +++ b/nirimod/pages/bindings.py @@ -0,0 +1,776 @@ +"""Key Bindings page — list editor + keyboard map visualizer. + +Tab 1: "Bindings List" — the original Adw row-based editor (unchanged logic). +Tab 2: "Keyboard Map" — Cairo keyboard visualizer ported from omer-biz/visu. +""" + +from __future__ import annotations + + +import gi + +gi.require_version("Gtk", "4.0") +gi.require_version("Adw", "1") +from gi.repository import Adw, Gio, GLib, Gtk + +from nirimod.kdl_parser import KdlNode +from nirimod.pages.base import BasePage +from nirimod.widgets import KeyboardVisualizer, normalize_key_id + + +MODIFIERS = ["Mod", "Super", "Ctrl", "Alt", "Shift"] + +NIRI_ACTIONS = [ + "close-window", + "focus-column-left", + "focus-column-right", + "focus-column-first", + "focus-column-last", + "focus-window-down", + "focus-window-up", + "move-column-left", + "move-column-right", + "move-column-to-first", + "move-column-to-last", + "move-window-down", + "move-window-up", + "focus-workspace-down", + "focus-workspace-up", + "focus-workspace", + "move-column-to-workspace", + "move-column-to-workspace-down", + "move-column-to-workspace-up", + "move-workspace-down", + "move-workspace-up", + "focus-monitor-left", + "focus-monitor-right", + "focus-monitor-up", + "focus-monitor-down", + "move-column-to-monitor-left", + "move-column-to-monitor-right", + "move-column-to-monitor-down", + "move-column-to-monitor-up", + "maximize-column", + "fullscreen-window", + "maximize-window-to-edges", + "switch-preset-column-width", + "switch-preset-window-height", + "set-column-width", + "set-window-height", + "set-dynamic-cast-window", + "set-dynamic-cast-monitor", + "clear-dynamic-cast-target", + "reset-window-height", + "center-column", + "center-visible-columns", + "screenshot", + "screenshot-screen", + "screenshot-window", + "spawn", + "spawn-sh", + "quit", + "power-off-monitors", + "toggle-window-floating", + "switch-focus-between-floating-and-tiling", + "toggle-column-tabbed-display", + "toggle-overview", + "consume-or-expel-window-left", + "consume-or-expel-window-right", + "consume-window-into-column", + "expel-window-from-column", + "expand-column-to-available-width", + "show-hotkey-overlay", + "toggle-keyboard-shortcuts-inhibit", + "toggle-windowed-fullscreen", +] + + +_KNOWN_BIND_PROPS = {"allow-when-locked", "repeat"} + + +def _make_bind( + keysym: str, + action: str = "", + action_args: list | None = None, + allow_when_locked: bool = False, + repeat: bool = True, + extra_props: dict | None = None, + node: KdlNode | None = None, +) -> dict: + return { + "keysym": keysym, + "action": action, + "action_args": action_args or [], + "allow_when_locked": allow_when_locked, + "repeat": repeat, + "extra_props": extra_props or {}, + "_node": node, + } + + +def _parse_binds_from_nodes(nodes: list[KdlNode]) -> list[dict]: + """Parse all bind nodes from the binds block.""" + binds_node = next((n for n in nodes if n.name == "binds"), None) + if not binds_node: + return [] + result = [] + for child in binds_node.children: + keysym = child.name + action = "" + action_args: list = [] + allow_locked = child.props.get("allow-when-locked", False) + repeat = child.props.get("repeat", True) + extra_props = { + k: v for k, v in child.props.items() if k not in _KNOWN_BIND_PROPS + } + for sub in child.children: + action = sub.name + action_args = list(sub.args) + result.append( + _make_bind( + keysym, + action, + action_args, + allow_locked, + repeat, + extra_props, + node=child, + ) + ) + return result + + +def _write_binds_to_node(binds_list: list[dict], binds_node: KdlNode): + kept_nodes = {id(b.get("_node")) for b in binds_list if b.get("_node") is not None} + salvaged_trivia = "" + for orig_child in binds_node.children: + if id(orig_child) not in kept_nodes: + salvaged_trivia += orig_child.leading_trivia + + new_children = [] + for i, b in enumerate(binds_list): + child = b.get("_node") + if child is None: + child = KdlNode(name=b["keysym"]) + child.leading_trivia = "\n " + else: + child.name = b["keysym"] + + if i == 0 and salvaged_trivia: + child.leading_trivia = salvaged_trivia + child.leading_trivia + salvaged_trivia = "" + + child.props.clear() + if b["allow_when_locked"]: + child.props["allow-when-locked"] = True + if not b["repeat"]: + child.props["repeat"] = False + for k, v in b.get("extra_props", {}).items(): + child.props[k] = v + + if b["action"]: + args = b.get("action_args") or [] + if not args: + legacy = b.get("action_arg", "") + if legacy: + args = [legacy] + + if child.children: + action_node = child.children[0] + action_node.name = b["action"] + action_node.args = list(args) + child.children = [action_node] + else: + action_node = KdlNode(name=b["action"]) + action_node.args = list(args) + action_node.leading_trivia = " " + child.children.append(action_node) + else: + child.children.clear() + + new_children.append(child) + + if salvaged_trivia: + binds_node.children_trailing_trivia = salvaged_trivia + binds_node.children_trailing_trivia + + binds_node.children = new_children + + +def _build_key_bindings_map(binds: list[dict], viz=None) -> dict[str, list[dict]]: + result: dict[str, list[dict]] = {} + for b in binds: + keysym = b.get("keysym", "") + raw_key = keysym.split("+")[-1].lower() + kid = None + if viz and viz._dynamic_keysym_to_kid: + kid = viz._dynamic_keysym_to_kid.get(raw_key) + if not kid: + kid = normalize_key_id(raw_key) + result.setdefault(kid, []).append(b) + return result + + +# BindingsPage + + +class BindingsPage(BasePage): + def __init__(self, window): + super().__init__(window) + self._binds: list[dict] = [] + self._search_query = "" + self._kb_search_query = "" + self._file_monitor: Gio.FileMonitor | None = None + self._viz: KeyboardVisualizer | None = None + + def build(self) -> Gtk.Widget: + tb = Adw.ToolbarView() + + # Custom Header + header_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=12) + header_box.set_margin_start(24) + header_box.set_margin_end(24) + header_box.set_margin_top(20) + header_box.set_margin_bottom(12) + + # Title/Subtitle Group + title_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2) + title_vbox.set_hexpand(True) + + self._main_title = Gtk.Label(label="Keybindings") + self._main_title.set_xalign(0.0) + self._main_title.add_css_class("title-1") + title_vbox.append(self._main_title) + + self._kb_stats_header = Gtk.Label(label="Detecting bindings...") + self._kb_stats_header.set_xalign(0.0) + self._kb_stats_header.add_css_class("dim-label") + self._kb_stats_header.add_css_class("caption") + title_vbox.append(self._kb_stats_header) + header_box.append(title_vbox) + + # Layout Selector (shown only on Keyboard tab) + from nirimod import app_settings + from nirimod.xkb_helper import XkbHelper + + self._layouts = XkbHelper.get_available_layouts() + layout_names = [d for _, d in self._layouts] + self._layout_model = Gtk.StringList.new(layout_names) + self._layout_combo = Gtk.DropDown(model=self._layout_model) + self._layout_combo.set_valign(Gtk.Align.CENTER) + self._layout_combo.set_enable_search(True) + + # Priority: Settings > Niri Config > US + saved_layout = app_settings.get("kb_layout") + if not saved_layout: + saved_layout = self._get_current_niri_layout() or "us" + + selected_idx = 0 + for i, (lid, _) in enumerate(self._layouts): + if lid == saved_layout: + selected_idx = i + break + self._layout_combo.set_selected(selected_idx) + + self._layout_combo.connect("notify::selected", self._on_layout_changed) + header_box.append(self._layout_combo) + + # Add Button (hidden by default, shown on List tab) + self._add_btn = Gtk.Button(icon_name="list-add-symbolic") + self._add_btn.set_tooltip_text("Add binding") + self._add_btn.add_css_class("flat") + self._add_btn.add_css_class("circular") + self._add_btn.set_valign(Gtk.Align.CENTER) + self._add_btn.set_visible(False) + self._add_btn.connect("clicked", self._on_add_clicked) + header_box.append(self._add_btn) + + # View Switcher (Styled as Physical/List View buttons) + self._view_stack = Adw.ViewStack() + + switcher_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0) + switcher_box.add_css_class("linked") + switcher_box.set_valign(Gtk.Align.CENTER) + + self._btn_physical = Gtk.ToggleButton(label="Physical") + self._btn_list = Gtk.ToggleButton(label="List View") + self._btn_list.set_group(self._btn_physical) + + self._btn_physical.connect("toggled", self._on_view_toggle) + self._btn_list.connect("toggled", self._on_view_toggle) + + switcher_box.append(self._btn_physical) + switcher_box.append(self._btn_list) + header_box.append(switcher_box) + + self._view_stack.set_vexpand(True) + list_page_widget = self._build_list_tab() + self._view_stack.add_named(list_page_widget, "list") + + kb_page_widget = self._build_keyboard_tab() + self._view_stack.add_named(kb_page_widget, "keyboard") + + # Default to keyboard (Physical) + self._view_stack.set_visible_child_name("keyboard") + self._btn_physical.set_active(True) + + main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + main_box.append(header_box) + main_box.append(self._view_stack) + + tb.set_content(main_box) + + self.refresh() + self._start_file_monitor() + return tb + + def _get_current_niri_layout(self): + try: + from nirimod import kdl_parser + nodes = kdl_parser.load_niri_config() + for node in nodes: + if node.name == "input": + kb = node.get_child("keyboard") + if kb: + xkb = kb.get_child("xkb") + if xkb: + layout = xkb.child_arg("layout") + v = xkb.child_arg("variant") + if layout: + return f"{layout}:{v}" if v else layout + except Exception: + pass + return None + + def _on_layout_changed(self, dropdown, param): + from nirimod import app_settings + idx = dropdown.get_selected() + if idx < len(self._layouts): + layout_id = self._layouts[idx][0] + app_settings.set("kb_layout", layout_id) + if self._viz: + self._viz.set_layout(layout_id) + + def _on_view_toggle(self, btn): + if not btn.get_active(): + return + is_list = btn == self._btn_list + self._view_stack.set_visible_child_name("list" if is_list else "keyboard") + self._add_btn.set_visible(is_list) + if hasattr(self, "_layout_combo"): + self._layout_combo.set_visible(not is_list) + + def _build_list_tab(self) -> Gtk.Widget: + """Return the scrollable list editor widget (original UI).""" + scroll = Gtk.ScrolledWindow() + scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) + scroll.set_vexpand(True) + + content = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=20) + content.set_margin_start(32) + content.set_margin_end(32) + content.set_margin_top(24) + content.set_margin_bottom(32) + scroll.set_child(content) + + # Search + + # Search + search = Gtk.SearchEntry(placeholder_text="Filter bindings…") + search.set_margin_start(0) + search.set_margin_end(0) + search.connect("search-changed", self._on_filter_changed) + content.append(search) + + # Binds Grid + self._flowbox = Gtk.FlowBox() + self._flowbox.set_valign(Gtk.Align.START) + self._flowbox.set_max_children_per_line(3) + self._flowbox.set_min_children_per_line(1) + self._flowbox.set_selection_mode(Gtk.SelectionMode.NONE) + self._flowbox.set_column_spacing(16) + self._flowbox.set_row_spacing(16) + self._flowbox.set_homogeneous(True) + content.append(self._flowbox) + + + return scroll + + def _build_keyboard_tab(self) -> Gtk.Widget: + scroll = Gtk.ScrolledWindow() + scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) + scroll.set_vexpand(True) + + outer = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=16) + outer.set_margin_start(24) + outer.set_margin_end(24) + outer.set_margin_top(20) + outer.set_margin_bottom(24) + scroll.set_child(outer) + + # Search bar + kb_search = Gtk.SearchEntry( + placeholder_text="Filter by action… (e.g. spawn, focus)" + ) + kb_search.connect("search-changed", self._on_kb_search_changed) + outer.append(kb_search) + + # Search bar + self._kb_stats = Gtk.Label(label="") + self._kb_stats.set_visible(False) + + self._viz = KeyboardVisualizer() + idx = self._layout_combo.get_selected() + if 0 <= idx < len(self._layouts): + self._viz.set_layout(self._layouts[idx][0]) + self._viz.connect("key-selected", self._on_kb_key_selected) + self._viz.connect("edit-binding", self._on_kb_edit_binding) + self._viz.connect("add-binding", self._on_kb_add_binding) + self._viz.connect("delete-binding", self._on_kb_delete_binding) + outer.append(self._viz) + + return scroll + + # Tab switching + + + + # Refresh / sync + + def refresh(self): + self._binds = _parse_binds_from_nodes(self._nodes) + self._rebuild_list() + self._refresh_visualizer() + + def on_shown(self): + self._refresh_visualizer() + + def _refresh_visualizer(self): + if self._viz is None: + return + from nirimod import app_settings + layout_id = app_settings.get("kb_layout") + if not layout_id: + layout_id = self._get_current_niri_layout() or "us" + self._viz.set_layout(layout_id) + + binds_map = _build_key_bindings_map(self._binds, self._viz) + self._viz.set_bindings(binds_map) + self._viz.set_search(self._kb_search_query) + n_total = len(self._binds) + self._kb_stats_header.set_label( + f"{n_total} active bindings detected" + ) + + # List editor helpers (unchanged from original) + + def _rebuild_list(self): + if not hasattr(self, "_flowbox"): + return + + # Clear existing children + while True: + child = self._flowbox.get_first_child() + if child is None: + break + self._flowbox.remove(child) + + q = self._search_query.lower() + visible_count = 0 + for i, b in enumerate(self._binds): + if q and q not in b["keysym"].lower() and q not in b["action"].lower(): + continue + card = self._make_bind_card(b, i) + self._flowbox.append(card) + visible_count += 1 + + def _make_bind_card(self, b: dict, idx: int) -> Gtk.Widget: + keysym = b["keysym"] + action = b["action"] + action_args = b.get("action_args") or [] + action_arg_display = " ".join(str(a) for a in action_args) + + full_action = f"{action} {action_arg_display}".strip() + if not full_action: + full_action = "(unassigned)" + + # Card container + card = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8) + card.set_size_request(240, 140) + card.add_css_class("nm-binding-card") + + # 1. Keycaps Row + keys_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6) + parts = keysym.split("+") + _labels = { + "mod": "Mod", + "super": "Super", + "ctrl": "Ctrl", + "control": "Ctrl", + "shift": "Shift", + "alt": "Alt", + } + + for i, part in enumerate(parts): + label_text = part + is_mod = i < len(parts) - 1 + if is_mod: + label_text = _labels.get(part.lower(), part) + else: + label_text = label_text.upper() if len(label_text) == 1 else label_text + + cap = Gtk.Label(label=label_text) + cap.add_css_class("nm-keycap-purple") + keys_box.append(cap) + + if i < len(parts) - 1: + plus = Gtk.Label(label="+") + plus.add_css_class("dim-label") + keys_box.append(plus) + + card.append(keys_box) + + # 2. "ACTIONS" Label + actions_header = Gtk.Label(label="ACTIONS") + actions_header.set_xalign(0.0) + actions_header.add_css_class("nm-binding-actions-label") + actions_header.set_margin_top(12) + card.append(actions_header) + + # 3. Action Name + action_lbl = Gtk.Label(label=full_action) + action_lbl.set_xalign(0.0) + action_lbl.set_ellipsize(3) + action_lbl.add_css_class("nm-binding-action-name") + card.append(action_lbl) + + # Spacer to push action buttons to the bottom + spacer = Gtk.Box() + spacer.set_vexpand(True) + card.append(spacer) + + bottom_row = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6) + bottom_row.set_halign(Gtk.Align.END) + + if b.get("allow_when_locked"): + lock = Gtk.Label(label="🔒") + lock.set_opacity(0.6) + bottom_row.append(lock) + + edit_btn = Gtk.Button(icon_name="document-edit-symbolic") + edit_btn.add_css_class("flat") + edit_btn.add_css_class("circular") + edit_btn.connect("clicked", lambda *_, i=idx: self._on_edit_clicked(i)) + bottom_row.append(edit_btn) + + del_btn = Gtk.Button(icon_name="user-trash-symbolic") + del_btn.add_css_class("flat") + del_btn.add_css_class("circular") + del_btn.add_css_class("error") + del_btn.connect("clicked", lambda *_, i=idx: self._on_delete_clicked(i)) + bottom_row.append(del_btn) + + card.append(bottom_row) + + return card + + def _on_filter_changed(self, entry): + self._search_query = entry.get_text().strip() + self._rebuild_list() + + def _on_kb_search_changed(self, entry): + self._kb_search_query = entry.get_text().strip() + if self._viz: + self._viz.set_search(self._kb_search_query) + + def _on_kb_key_selected(self, viz, key_id: str): + pass + + def _on_kb_edit_binding(self, viz, bind_dict): + try: + idx = self._binds.index(bind_dict) + self._show_bind_dialog(bind_dict, idx) + except ValueError: + pass + + def _on_kb_delete_binding(self, viz, bind_dict): + try: + idx = self._binds.index(bind_dict) + self._on_delete_clicked(idx) + except ValueError: + pass + + def _on_kb_add_binding(self, viz, key_id: str): + + if len(key_id) == 1: + display_key = key_id.upper() + else: + display_key = key_id.capitalize() + + new_bind = { + "keysym": f"Mod+{display_key}", + "action": "", + "action_args": [], + "allow_when_locked": False, + "repeat": True, + "extra_props": {} + } + self._show_bind_dialog(new_bind, -1) + + def _on_delete_clicked(self, idx: int): + if 0 <= idx < len(self._binds): + del self._binds[idx] + self._save_binds() + self._rebuild_list() + self._refresh_visualizer() + + def _on_add_clicked(self, *_): + self._show_bind_dialog(None, -1) + + def _on_edit_clicked(self, idx: int): + if 0 <= idx < len(self._binds): + self._show_bind_dialog(self._binds[idx], idx) + + def _show_bind_dialog(self, bind: dict | None, idx: int): + dialog = Adw.Dialog(title="Edit Binding" if bind else "Add Binding") + dialog.set_content_width(440) + + box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) + header = Adw.HeaderBar() + header.set_title_widget(Adw.WindowTitle(title=dialog.get_title())) + box.append(header) + + prefs = Adw.PreferencesPage() + prefs.set_vexpand(True) + + # Keysym group + keys_grp = Adw.PreferencesGroup(title="Key Combination") + + mod_row = Adw.ActionRow(title="Modifiers") + mod_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6) + mod_box.set_valign(Gtk.Align.CENTER) + mod_checks: dict[str, Gtk.CheckButton] = {} + cur_keysym = bind["keysym"] if bind else "" + keysym_parts_lower = [p.lower() for p in cur_keysym.split("+")[:-1]] + for mod in MODIFIERS: + cb = Gtk.CheckButton(label=mod) + cb.set_active(mod.lower() in keysym_parts_lower) + mod_box.append(cb) + mod_checks[mod] = cb + mod_row.add_suffix(mod_box) + keys_grp.add(mod_row) + + key_entry = Adw.EntryRow(title="Key (e.g. T, F1, Return)") + bare = cur_keysym.split("+")[-1] if bind else "" + key_entry.set_text(bare) + keys_grp.add(key_entry) + prefs.add(keys_grp) + + # Action group + act_grp = Adw.PreferencesGroup(title="Action") + act_model = Gtk.StringList.new(NIRI_ACTIONS) + act_combo = Adw.ComboRow(title="Action", model=act_model) + cur_action = bind["action"] if bind else "" + if cur_action in NIRI_ACTIONS: + act_combo.set_selected(NIRI_ACTIONS.index(cur_action)) + act_grp.add(act_combo) + + arg_row = Adw.EntryRow(title="Argument (for spawn, focus-workspace, etc.)") + cur_args = (bind.get("action_args") or []) if bind else [] + arg_row.set_text(" ".join(str(a) for a in cur_args) if cur_args else "") + act_grp.add(arg_row) + prefs.add(act_grp) + + # Options + opt_grp = Adw.PreferencesGroup(title="Options") + locked_row = Adw.SwitchRow(title="Allow When Locked") + locked_row.set_active(bind["allow_when_locked"] if bind else False) + opt_grp.add(locked_row) + + repeat_row = Adw.SwitchRow(title="Repeat") + repeat_row.set_active(bind["repeat"] if bind else True) + opt_grp.add(repeat_row) + prefs.add(opt_grp) + + box.append(prefs) + + save_row = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) + save_row.set_halign(Gtk.Align.END) + save_row.set_margin_start(16) + save_row.set_margin_end(16) + save_row.set_margin_top(8) + save_row.set_margin_bottom(16) + save_btn = Gtk.Button(label="Save") + save_btn.add_css_class("suggested-action") + save_btn.add_css_class("pill") + + def _do_save(*_): + mods = [m for m, cb in mod_checks.items() if cb.get_active()] + key = key_entry.get_text().strip() + if not key: + return + keysym = "+".join(mods + [key]) + action_idx = act_combo.get_selected() + action = NIRI_ACTIONS[action_idx] if action_idx < len(NIRI_ACTIONS) else "" + arg_text = arg_row.get_text().strip() + if action == "spawn-sh": + new_args = [arg_text] if arg_text else [] + else: + import shlex + try: + new_args = shlex.split(arg_text) if arg_text else [] + except ValueError: + new_args = arg_text.split() if arg_text else [] + new_bind = _make_bind( + keysym, + action, + new_args, + locked_row.get_active(), + repeat_row.get_active(), + bind.get("extra_props", {}) if bind else {}, + node=bind.get("_node") if bind else None, + ) + if idx >= 0: + self._binds[idx] = new_bind + else: + self._binds.append(new_bind) + self._save_binds() + self._rebuild_list() + self._refresh_visualizer() + dialog.close() + + save_btn.connect("clicked", _do_save) + save_row.append(save_btn) + box.append(save_row) + + dialog.set_child(box) + dialog.present(self._win) + + def _save_binds(self): + nodes = self._nodes + binds_node = next((n for n in nodes if n.name == "binds"), None) + if binds_node is None: + binds_node = KdlNode("binds") + nodes.append(binds_node) + _write_binds_to_node(self._binds, binds_node) + self._commit("keybindings") + + # File monitor (live-sync) + + def _start_file_monitor(self): + try: + from nirimod.kdl_parser import NIRI_CONFIG + + gfile = Gio.File.new_for_path(str(NIRI_CONFIG)) + monitor = gfile.monitor_file(Gio.FileMonitorFlags.NONE, None) + monitor.connect("changed", self._on_config_file_changed) + self._file_monitor = monitor + except Exception: + pass + + def _on_config_file_changed(self, monitor, file, other_file, event_type): + if event_type in (Gio.FileMonitorEvent.CHANGED, Gio.FileMonitorEvent.CREATED): + GLib.timeout_add(400, self._reload_from_disk) + + def _reload_from_disk(self): + self._win.notify_nodes_changed() + return False # don't repeat diff --git a/nirimod/pages/environment.py b/nirimod/pages/environment.py new file mode 100644 index 0000000..d1073c4 --- /dev/null +++ b/nirimod/pages/environment.py @@ -0,0 +1,161 @@ +"""Environment Variables page.""" + +from __future__ import annotations + + +import gi + +gi.require_version("Gtk", "4.0") +gi.require_version("Adw", "1") +from gi.repository import Adw, GLib, Gtk + +from nirimod.kdl_parser import KdlNode, find_or_create +from nirimod.pages.base import BasePage + + +class EnvironmentPage(BasePage): + def build(self) -> Gtk.Widget: + tb, header, _, content = self._make_toolbar_page("Environment") + self._content = content + + # Add button has been moved to the page body for better visibility + self.refresh() + return tb + + def refresh(self): + self._rebuild() + + def _get_env_node(self) -> KdlNode: + return find_or_create(self._nodes, "environment") + + def _rebuild(self): + # Clear existing content + while True: + child = self._content.get_first_child() + if child is None: + break + self._content.remove(child) + + env = self._get_env_node() + entries = list(env.children) + + if not entries: + status = Adw.StatusPage( + title="No Environment Variables", + description="Variables set here will apply to niri and all processes it spawns.", + icon_name="preferences-system-symbolic", + ) + + add_btn = Gtk.Button(label="Add Variable") + add_btn.add_css_class("pill") + add_btn.add_css_class("suggested-action") + add_btn.set_halign(Gtk.Align.CENTER) + add_btn.connect("clicked", self._on_add) + + box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) + box.set_valign(Gtk.Align.CENTER) + box.set_vexpand(True) + box.append(status) + box.append(add_btn) + + self._content.append(box) + else: + grp = Adw.PreferencesGroup( + title="Environment Variables", + description=f"{len(entries)} variable{'s' if len(entries) != 1 else ''} configured", + ) + for i, child in enumerate(entries): + row = self._make_row(child, i) + grp.add(row) + + self._content.append(grp) + + # Convenient button at the bottom + add_btn = Gtk.Button(label="Add Another Variable") + add_btn.add_css_class("pill") + add_btn.set_halign(Gtk.Align.CENTER) + add_btn.set_margin_top(16) + add_btn.connect("clicked", self._on_add) + self._content.append(add_btn) + + def _make_row(self, node: KdlNode, idx: int) -> Adw.ActionRow: + key = node.name + val = node.args[0] if node.args else "" + + # Make key bold and distinct + key_str = GLib.markup_escape_text(key) + val_str = GLib.markup_escape_text(str(val)) + + row = Adw.ActionRow( + title=f"{key_str}", + subtitle=val_str if val_str else "(empty)", + ) + row.set_use_markup(True) + edit_btn = Gtk.Button(icon_name="document-edit-symbolic") + edit_btn.set_valign(Gtk.Align.CENTER) + edit_btn.add_css_class("flat") + edit_btn.connect("clicked", lambda *_, i=idx: self._on_edit(i)) + row.add_suffix(edit_btn) + + del_btn = Gtk.Button(icon_name="user-trash-symbolic") + del_btn.set_valign(Gtk.Align.CENTER) + del_btn.add_css_class("flat") + del_btn.add_css_class("error") + del_btn.connect("clicked", lambda *_, i=idx: self._on_delete(i)) + row.add_suffix(del_btn) + return row + + def _on_add(self, *_): + self._show_dialog(None, -1) + + def _on_edit(self, idx: int): + env = self._get_env_node() + if 0 <= idx < len(env.children): + self._show_dialog(env.children[idx], idx) + + def _on_delete(self, idx: int): + env = self._get_env_node() + if 0 <= idx < len(env.children): + env.children.pop(idx) + self._commit("remove env var") + self._rebuild() + + def _show_dialog(self, node: KdlNode | None, idx: int): + dialog = Adw.AlertDialog( + heading="Environment Variable", body="Set a key=value environment variable." + ) + + key_entry = Adw.EntryRow(title="Variable Name (e.g. QT_QPA_PLATFORM)") + val_entry = Adw.EntryRow(title="Value (e.g. wayland)") + if node: + key_entry.set_text(node.name) + key_entry.set_editable(False) # editing key means replacing the node + val_entry.set_text(str(node.args[0]) if node.args else "") + + grp = Adw.PreferencesGroup() + grp.add(key_entry) + grp.add(val_entry) + dialog.set_extra_child(grp) + + dialog.add_response("cancel", "Cancel") + dialog.add_response("save", "Save") + dialog.set_response_appearance("save", Adw.ResponseAppearance.SUGGESTED) + + def _on_resp(d, r): + if r != "save": + return + key = key_entry.get_text().strip() + val = val_entry.get_text() + if not key: + return + env = self._get_env_node() + new_node = KdlNode(key, args=[val]) + if idx >= 0 and 0 <= idx < len(env.children): + env.children[idx] = new_node + else: + env.children.append(new_node) + self._commit("env var") + self._rebuild() + + dialog.connect("response", _on_resp) + dialog.present(self._win) diff --git a/nirimod/pages/gestures.py b/nirimod/pages/gestures.py new file mode 100644 index 0000000..f57436d --- /dev/null +++ b/nirimod/pages/gestures.py @@ -0,0 +1,200 @@ +"""Gestures & Miscellaneous settings page.""" + +from __future__ import annotations + + +import gi + +gi.require_version("Gtk", "4.0") +gi.require_version("Adw", "1") +from gi.repository import Adw, Gtk + +from nirimod.kdl_parser import ( + KdlNode, + find_or_create, + set_node_flag, + safe_switch_connect, +) +from nirimod.pages.base import BasePage + +_CORNERS = [ + ("top-left", "Top-Left", "Moves cursor to the top-left corner"), + ("top-right", "Top-Right", "Moves cursor to the top-right corner"), + ("bottom-left", "Bottom-Left", "Moves cursor to the bottom-left corner"), + ("bottom-right", "Bottom-Right", "Moves cursor to the bottom-right corner"), +] + + +class GesturesPage(BasePage): + def build(self) -> Gtk.Widget: + tb, _, _, content = self._make_toolbar_page("Gestures & Misc") + self._content = content + self._build_content() + return tb + + def _build_content(self): + content = self._content + nodes = self._nodes + + # ── Hot Corners ─────────────────────────────────────────────────────── + hc_grp = Adw.PreferencesGroup( + title="Hot Corners", + description="Trigger the overview when the cursor touches a screen corner (niri ≥ 25.05)", + ) + gestures_node = next((n for n in nodes if n.name == "gestures"), None) + hc_node = gestures_node.get_child("hot-corners") if gestures_node else None + hc_off = hc_node is not None and hc_node.get_child("off") is not None + hc_enabled = not hc_off + + # Which individual corners are active + active_corners: set[str] = set() + if hc_node and not hc_off: + for corner_key, _, _ in _CORNERS: + if hc_node.get_child(corner_key) is not None: + active_corners.add(corner_key) + + # ExpanderRow = the enable/disable switch + collapsible corner list + hc_expander = Adw.ExpanderRow( + title="Enable Hot Corners", + subtitle="Expand to choose which corners are active (default: top-left)", + ) + hc_expander.set_expanded(hc_enabled) + hc_expander.set_show_enable_switch(True) + hc_expander.set_enable_expansion(hc_enabled) + + # Per-corner rows nested inside the expander + corner_rows: dict[str, Adw.SwitchRow] = {} + for corner_key, corner_label, corner_subtitle in _CORNERS: + sr = Adw.SwitchRow(title=corner_label, subtitle=corner_subtitle) + is_active = corner_key in active_corners + sr.set_active(is_active) + safe_switch_connect( + sr, is_active, + lambda enabled, k=corner_key: self._set_corner(k, enabled), + ) + hc_expander.add_row(sr) + corner_rows[corner_key] = sr + + # Wire the expander's enable-switch to the hot corners on/off mutation + hc_expander._last_enabled = hc_enabled + + def _on_expander_toggled(expander, _param): + val = expander.get_enable_expansion() + if val != getattr(expander, "_last_enabled", None): + expander._last_enabled = val + self._set_hot_corners(val) + + hc_expander.connect("notify::enable-expansion", _on_expander_toggled) + + hc_grp.add(hc_expander) + content.append(hc_grp) + + + # ── Hotkey Overlay ──────────────────────────────────────────────────── + hko_grp = Adw.PreferencesGroup(title="Hotkey Overlay") + hko_node = next((n for n in nodes if n.name == "hotkey-overlay"), None) + + skip_initial = ( + hko_node is not None and hko_node.get_child("skip-at-startup") is not None + ) + skip_row = Adw.SwitchRow( + title="Skip at Startup", + subtitle="Don't show the hotkey overlay when niri starts", + ) + skip_row.set_active(skip_initial) + safe_switch_connect(skip_row, skip_initial, self._set_skip_hotkey_overlay) + hko_grp.add(skip_row) + content.append(hko_grp) + + # ── Screenshots ─────────────────────────────────────────────────────── + ss_grp = Adw.PreferencesGroup( + title="Screenshots", description="Path template for saved screenshots" + ) + cur_path = next( + (n.args[0] for n in nodes if n.name == "screenshot-path" and n.args), + "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png", + ) + path_row = Adw.EntryRow(title="Save Path (strftime format)") + path_row.set_text(str(cur_path)) + path_row.set_show_apply_button(True) + path_row.connect("apply", lambda r: self._set_screenshot_path(r.get_text())) + ss_grp.add(path_row) + content.append(ss_grp) + + # ── Overview ────────────────────────────────────────────────────────── + ov_grp = Adw.PreferencesGroup(title="Overview") + ov_node = next((n for n in nodes if n.name == "overview"), None) + ws_shadow_node = ov_node.get_child("workspace-shadow") if ov_node else None + + ws_shadow_initial = ( + ws_shadow_node is None or ws_shadow_node.get_child("off") is None + ) + ws_shadow_row = Adw.SwitchRow( + title="Workspace Shadow in Overview", + subtitle="Show drop shadows under workspaces in overview mode", + ) + ws_shadow_row.set_active(ws_shadow_initial) + safe_switch_connect( + ws_shadow_row, ws_shadow_initial, self._set_overview_ws_shadow + ) + ov_grp.add(ws_shadow_row) + content.append(ov_grp) + + # ── Mutation methods ────────────────────────────────────────────────────── + + def _get_hot_corners_node(self) -> KdlNode: + gestures = find_or_create(self._nodes, "gestures") + hc = gestures.get_child("hot-corners") + if hc is None: + hc = KdlNode("hot-corners") + hc.leading_trivia = "\n" + gestures.children.append(hc) + return hc + + def _set_hot_corners(self, enabled: bool): + hc = self._get_hot_corners_node() + set_node_flag(hc, "off", not enabled) + self._commit("gestures hot-corners") + + def _set_corner(self, corner_key: str, enabled: bool): + """Enable or disable an individual hot corner (niri ≥ 25.11).""" + hc = self._get_hot_corners_node() + # Remove 'off' if it exists — enabling a corner implicitly enables hot corners + set_node_flag(hc, "off", False) + set_node_flag(hc, corner_key, enabled) + self._commit(f"hot-corner {corner_key}") + + def _set_skip_hotkey_overlay(self, skip: bool): + nodes = self._nodes + hko = next((n for n in nodes if n.name == "hotkey-overlay"), None) + if hko is None: + hko = KdlNode("hotkey-overlay") + nodes.append(hko) + set_node_flag(hko, "skip-at-startup", skip) + self._commit("hotkey-overlay skip-at-startup") + + def _set_screenshot_path(self, path: str): + nodes = self._nodes + existing = next((n for n in nodes if n.name == "screenshot-path"), None) + if path.strip(): + if existing: + existing.args = [path.strip()] + else: + nodes.append(KdlNode("screenshot-path", args=[path.strip()])) + elif existing: + nodes.remove(existing) + self._commit("screenshot-path") + + def _set_overview_ws_shadow(self, enabled: bool): + ov = find_or_create(self._nodes, "overview") + ws_shadow = ov.get_child("workspace-shadow") + if ws_shadow is None: + ws_shadow = KdlNode("workspace-shadow") + ov.children.append(ws_shadow) + set_node_flag(ws_shadow, "off", not enabled) + self._commit("overview workspace-shadow") + + def refresh(self): + for child in list(self._content): + self._content.remove(child) + self._build_content() diff --git a/nirimod/pages/input_page.py b/nirimod/pages/input_page.py new file mode 100644 index 0000000..224101f --- /dev/null +++ b/nirimod/pages/input_page.py @@ -0,0 +1,380 @@ + + +from __future__ import annotations + +import gi + +gi.require_version("Gtk", "4.0") +gi.require_version("Adw", "1") +from gi.repository import Adw, Gtk + +from nirimod import niri_ipc +from nirimod.kdl_parser import ( + KdlNode, + find_or_create, + set_child_arg, + set_node_flag, + safe_switch_connect, +) +from nirimod.pages.base import BasePage + +ACCEL_PROFILES = ["default", "flat", "adaptive"] +SCROLL_METHODS_TP = ["two-finger", "edge", "on-button-down", "no-scroll"] +CLICK_METHODS = ["button-areas", "clickfinger"] + + +class InputPage(BasePage): + def build(self) -> Gtk.Widget: + tb, _, _, content = self._make_toolbar_page("Input") + self._content = content + self._build_content() + return tb + + def _build_content(self): + content = self._content + nodes = self._nodes + + kb_expander = Adw.ExpanderRow(title="Keyboard", subtitle="XKB options & key repeat") + kb_expander.add_css_class("nm-expander") + + kb_node = find_or_create(nodes, "input", "keyboard") + xkb_node = kb_node.get_child("xkb") or KdlNode("xkb") + + fields = [ + ("layout", "Layout", "e.g. us,ru"), + ("variant", "Variant", "e.g. dvorak"), + ("model", "Model", ""), + ("options", "Options", "e.g. grp:win_space_toggle"), + ("rules", "Rules", ""), + ] + self._xkb_entries: dict[str, Adw.EntryRow] = {} + for key, title, ph in fields: + row = Adw.EntryRow(title=title) + row.set_show_apply_button(True) + val = xkb_node.child_arg(key) if xkb_node else None + if val: + row.set_text(str(val)) + row.set_input_purpose(Gtk.InputPurpose.FREE_FORM) + row.connect("apply", lambda r, k=key: self._set_xkb(k, r.get_text())) + kb_expander.add_row(row) + self._xkb_entries[key] = row + + delay_adj = Gtk.Adjustment( + value=kb_node.child_arg("repeat-delay") or 600, + lower=100, upper=3000, step_increment=50, + ) + delay_row = Adw.SpinRow(title="Repeat Delay (ms)", adjustment=delay_adj, digits=0) + delay_row.connect("notify::value", lambda r, _: self._set_kb("repeat-delay", int(r.get_value()))) + kb_expander.add_row(delay_row) + + rate_adj = Gtk.Adjustment( + value=kb_node.child_arg("repeat-rate") or 25, + lower=1, upper=200, step_increment=1, + ) + rate_row = Adw.SpinRow(title="Repeat Rate (keys/sec)", adjustment=rate_adj, digits=0) + rate_row.connect("notify::value", lambda r, _: self._set_kb("repeat-rate", int(r.get_value()))) + kb_expander.add_row(rate_row) + + numlock_row = Adw.SwitchRow(title="Enable Num Lock on Startup") + nl_init = kb_node.get_child("numlock") is not None + numlock_row.set_active(nl_init) + safe_switch_connect(numlock_row, nl_init, self._toggle_numlock) + kb_expander.add_row(numlock_row) + + kb_grp = Adw.PreferencesGroup() + kb_grp.add(kb_expander) + content.append(kb_grp) + + # focus / pointer + focus_grp = Adw.PreferencesGroup(title="Pointer Behavior") + input_node = find_or_create(nodes, "input") + + ffm_row = Adw.SwitchRow(title="Focus Follows Mouse") + ffm_node = input_node.get_child("focus-follows-mouse") + ffm_row._last_active = ffm_node is not None + ffm_row.set_active(ffm_node is not None) + + def _on_ffm_toggled(r, _): + new_val = r.get_active() + if new_val != getattr(r, "_last_active", None): + r._last_active = new_val + self._toggle_ffm(new_val) + + ffm_row.connect("notify::active", _on_ffm_toggled) + focus_grp.add(ffm_row) + + scroll_val = 33 + if ffm_node: + vRaw = ffm_node.props.get("max-scroll-amount") + if vRaw is not None: + try: + scroll_val = int(float(str(vRaw).replace("%", "").strip())) + except ValueError: + pass + self._last_scroll_val = scroll_val + scroll_adj = Gtk.Adjustment(value=scroll_val, lower=0, upper=100, step_increment=1) + scroll_pct_row = Adw.SpinRow( + title="Max Scroll Amount (%)", subtitle="0% = only fully visible windows", + adjustment=scroll_adj, digits=0, + ) + scroll_pct_row.set_sensitive(ffm_node is not None) + self._scroll_pct_row = scroll_pct_row + scroll_pct_row._last_val = scroll_val + + def _on_scroll_pct_changed(r, _): + new_val = int(r.get_value()) + if new_val != getattr(r, "_last_val", None): + r._last_val = new_val + self._set_ffm_scroll(new_val) + + scroll_pct_row.connect("notify::value", _on_scroll_pct_changed) + focus_grp.add(scroll_pct_row) + + warp_init = input_node.get_child("warp-mouse-to-focus") is not None + warp_row = Adw.SwitchRow(title="Warp Mouse to Focus") + warp_row.set_active(warp_init) + safe_switch_connect(warp_row, warp_init, + lambda enabled: self._toggle_input_flag("warp-mouse-to-focus", enabled)) + focus_grp.add(warp_row) + content.append(focus_grp) + + # touchpad + tp_expander = Adw.ExpanderRow(title="Touchpad") + tp_expander.add_css_class("nm-expander") + has_tp = niri_ipc.has_touchpad() + if not has_tp: + tp_expander.set_subtitle("No touchpad detected") + tp_expander.set_sensitive(False) + + tp_node = find_or_create(nodes, "input", "touchpad") + + def tp_switch(key, label, subtitle=""): + r = Adw.SwitchRow(title=label, subtitle=subtitle) + ini = tp_node.get_child(key) is not None + r.set_active(ini) + safe_switch_connect(r, ini, lambda enabled, k=key: self._set_tp_flag(k, enabled)) + return r + + def tp_bool_switch(key, label, default_active=True, subtitle=""): + r = Adw.SwitchRow(title=label, subtitle=subtitle) + node = tp_node.get_child(key) + if node is not None and node.args: + ini = bool(node.args[0]) + else: + ini = default_active + r.set_active(ini) + safe_switch_connect(r, ini, lambda enabled, k=key: self._set_tp(k, enabled)) + return r + + tp_expander.add_row(tp_switch("tap", "Tap to Click")) + tp_expander.add_row(tp_switch("dwt", "Disable While Typing")) + tp_expander.add_row(tp_switch("dwtp", "Disable While Trackpointing")) + tp_expander.add_row(tp_switch("natural-scroll", "Natural Scroll")) + tp_expander.add_row(tp_bool_switch("drag", "Tap Drag")) + tp_expander.add_row(tp_switch("drag-lock", "Tap Drag Lock")) + tp_expander.add_row(tp_switch("disabled-on-external-mouse", "Disable on External Mouse")) + + spd_adj = Gtk.Adjustment(value=float(tp_node.child_arg("accel-speed") or 0.0), + lower=-1.0, upper=1.0, step_increment=0.05) + spd_row = Adw.SpinRow(title="Accel Speed", adjustment=spd_adj, digits=2) + spd_row.connect("notify::value", lambda r, _: self._set_tp("accel-speed", r.get_value())) + tp_expander.add_row(spd_row) + + ap_model = Gtk.StringList.new(ACCEL_PROFILES) + ap_row = Adw.ComboRow(title="Accel Profile", model=ap_model) + cur_ap = tp_node.child_arg("accel-profile") or "default" + if cur_ap in ACCEL_PROFILES: + ap_row.set_selected(ACCEL_PROFILES.index(cur_ap)) + ap_row.connect("notify::selected", + lambda r, _: self._set_tp("accel-profile", ACCEL_PROFILES[r.get_selected()])) + tp_expander.add_row(ap_row) + + sm_model = Gtk.StringList.new(SCROLL_METHODS_TP) + sm_row = Adw.ComboRow(title="Scroll Method", model=sm_model) + cur_sm = tp_node.child_arg("scroll-method") or "two-finger" + if cur_sm in SCROLL_METHODS_TP: + sm_row.set_selected(SCROLL_METHODS_TP.index(cur_sm)) + sm_row.connect("notify::selected", + lambda r, _: self._set_tp("scroll-method", SCROLL_METHODS_TP[r.get_selected()])) + tp_expander.add_row(sm_row) + + cm_model = Gtk.StringList.new(CLICK_METHODS) + cm_row = Adw.ComboRow(title="Click Method", model=cm_model) + cur_cm = tp_node.child_arg("click-method") or "button-areas" + if cur_cm in CLICK_METHODS: + cm_row.set_selected(CLICK_METHODS.index(cur_cm)) + cm_row.connect("notify::selected", + lambda r, _: self._set_tp("click-method", CLICK_METHODS[r.get_selected()])) + tp_expander.add_row(cm_row) + + tp_grp = Adw.PreferencesGroup() + tp_grp.add(tp_expander) + content.append(tp_grp) + + # mouse + m_expander = Adw.ExpanderRow(title="Mouse") + m_expander.add_css_class("nm-expander") + m_node = find_or_create(nodes, "input", "mouse") + + m_nat = Adw.SwitchRow(title="Natural Scroll") + mn_init = m_node.get_child("natural-scroll") is not None + m_nat.set_active(mn_init) + safe_switch_connect(m_nat, mn_init, lambda enabled: self._set_m_flag("natural-scroll", enabled)) + m_expander.add_row(m_nat) + + m_spd_adj = Gtk.Adjustment(value=float(m_node.child_arg("accel-speed") or 0.0), + lower=-1.0, upper=1.0, step_increment=0.05) + m_spd_row = Adw.SpinRow(title="Accel Speed", adjustment=m_spd_adj, digits=2) + m_spd_row.connect("notify::value", lambda r, _: self._set_m("accel-speed", r.get_value())) + m_expander.add_row(m_spd_row) + + m_ap_model = Gtk.StringList.new(ACCEL_PROFILES) + m_ap_row = Adw.ComboRow(title="Accel Profile", model=m_ap_model) + cur_m_ap = m_node.child_arg("accel-profile") or "default" + if cur_m_ap in ACCEL_PROFILES: + m_ap_row.set_selected(ACCEL_PROFILES.index(cur_m_ap)) + m_ap_row.connect("notify::selected", + lambda r, _: self._set_m("accel-profile", ACCEL_PROFILES[r.get_selected()])) + m_expander.add_row(m_ap_row) + + m_grp = Adw.PreferencesGroup() + m_grp.add(m_expander) + content.append(m_grp) + + # cursor + cursor_grp = Adw.PreferencesGroup(title="Cursor") + cursor_node = next((n for n in nodes if n.name == "cursor"), None) + + size_val = int(cursor_node.child_arg("xcursor-size") or 24) if cursor_node else 24 + size_adj = Gtk.Adjustment(value=size_val, lower=8, upper=256, step_increment=2) + size_row = Adw.SpinRow(title="Cursor Size (px)", adjustment=size_adj, digits=0) + size_row.connect("notify::value", + lambda r, _: self._set_cursor("xcursor-size", int(r.get_value()))) + cursor_grp.add(size_row) + + hide_val = int(cursor_node.child_arg("hide-after-inactive-ms") or 0) if cursor_node else 0 + hide_adj = Gtk.Adjustment(value=hide_val, lower=0, upper=60000, step_increment=500) + hide_row = Adw.SpinRow(title="Hide After Inactive (ms)", subtitle="0 = never hide", + adjustment=hide_adj, digits=0) + hide_row.connect("notify::value", + lambda r, _: self._set_cursor("hide-after-inactive-ms", int(r.get_value()))) + cursor_grp.add(hide_row) + + theme_val = str(cursor_node.child_arg("xcursor-theme") or "") if cursor_node else "" + theme_row = Adw.EntryRow(title="Cursor Theme (e.g. Adwaita)") + theme_row.set_text(theme_val) + theme_row.set_show_apply_button(True) + theme_row.connect("apply", lambda r: self._set_cursor_theme(r.get_text())) + cursor_grp.add(theme_row) + content.append(cursor_grp) + + + def _get_kb_node(self): + return find_or_create(self._nodes, "input", "keyboard") + + def _get_xkb_node(self): + kb = self._get_kb_node() + xkb = kb.get_child("xkb") + if xkb is None: + xkb = KdlNode("xkb") + kb.children.insert(0, xkb) + return xkb + + def _set_xkb(self, key: str, value: str): + xkb = self._get_xkb_node() + if value.strip(): + set_child_arg(xkb, key, value.strip()) + else: + from nirimod.kdl_parser import remove_child + remove_child(xkb, key) + self._commit(f"keyboard xkb {key}") + + def _set_kb(self, key: str, value): + set_child_arg(self._get_kb_node(), key, value) + self._commit(f"keyboard {key}") + + def _toggle_numlock(self, enabled: bool): + set_node_flag(self._get_kb_node(), "numlock", enabled) + self._commit("keyboard numlock") + + def _get_input_node(self): + return find_or_create(self._nodes, "input") + + def _toggle_ffm(self, enabled: bool): + inp = self._get_input_node() + existing = inp.get_child("focus-follows-mouse") + if enabled: + if existing is None: + new_ffm = KdlNode(name="focus-follows-mouse") + if hasattr(self, "_last_scroll_val"): + new_ffm.props["max-scroll-amount"] = f"{self._last_scroll_val}%" + inp.children.insert(0, new_ffm) + else: + if existing is not None: + inp.children.remove(existing) + if hasattr(self, "_scroll_pct_row"): + self._scroll_pct_row.set_sensitive(enabled) + self._commit("focus-follows-mouse") + + def _set_ffm_scroll(self, pct: int): + inp = self._get_input_node() + ffm = inp.get_child("focus-follows-mouse") + if ffm is None: + ffm = KdlNode("focus-follows-mouse") + inp.children.append(ffm) + ffm.props["max-scroll-amount"] = f"{pct}%" + self._commit("ffm scroll amount") + + def _toggle_input_flag(self, key: str, enabled: bool): + set_node_flag(self._get_input_node(), key, enabled) + self._commit(f"input {key}") + + def _get_tp_node(self): + return find_or_create(self._nodes, "input", "touchpad") + + def _set_tp_flag(self, key: str, enabled: bool): + set_node_flag(self._get_tp_node(), key, enabled) + self._commit(f"touchpad {key}") + + def _set_tp(self, key: str, value): + set_child_arg(self._get_tp_node(), key, value) + self._commit(f"touchpad {key}") + + def _get_m_node(self): + return find_or_create(self._nodes, "input", "mouse") + + def _set_m_flag(self, key: str, enabled: bool): + set_node_flag(self._get_m_node(), key, enabled) + self._commit(f"mouse {key}") + + def _set_m(self, key: str, value): + set_child_arg(self._get_m_node(), key, value) + self._commit(f"mouse {key}") + + def _get_cursor_node(self): + existing = next((n for n in self._nodes if n.name == "cursor"), None) + if existing is None: + existing = KdlNode("cursor") + self._nodes.append(existing) + return existing + + def _set_cursor(self, key: str, value): + set_child_arg(self._get_cursor_node(), key, value) + self._commit(f"cursor {key}") + + def _set_cursor_theme(self, theme: str): + cur = self._get_cursor_node() + if theme.strip(): + set_child_arg(cur, "xcursor-theme", theme.strip()) + else: + from nirimod.kdl_parser import remove_child + remove_child(cur, "xcursor-theme") + self._commit("cursor xcursor-theme") + + def refresh(self): + child = self._content.get_first_child() + while child: + next_child = child.get_next_sibling() + self._content.remove(child) + child = next_child + self._build_content() diff --git a/nirimod/pages/layout.py b/nirimod/pages/layout.py new file mode 100644 index 0000000..e05b1d6 --- /dev/null +++ b/nirimod/pages/layout.py @@ -0,0 +1,284 @@ +"""Layout settings page.""" + +from __future__ import annotations + + +import gi + +gi.require_version("Gtk", "4.0") +gi.require_version("Adw", "1") +from gi.repository import Adw, Gtk + +from nirimod.kdl_parser import KdlNode, find_or_create, set_child_arg, remove_child +from nirimod.pages.base import BasePage + + +CENTER_OPTIONS = ["never", "always", "on-overflow"] + + +class LayoutPage(BasePage): + def build(self) -> Gtk.Widget: + tb, _, _, content = self._make_toolbar_page("Layout") + self._content = content + self._build_content() + return tb + + def _build_content(self): + content = self._content + nodes = self._nodes + layout = find_or_create(nodes, "layout") + + basic_grp = Adw.PreferencesGroup(title="General") + + gaps_val = int(layout.child_arg("gaps") or 16) + gaps_adj = Gtk.Adjustment(value=gaps_val, lower=0, upper=200, step_increment=2) + gaps_row = Adw.SpinRow(title="Window Gaps (px)", adjustment=gaps_adj, digits=0) + + gaps_row._last_val = gaps_val + + def _on_gaps_changed(r, _): + new_val = int(r.get_value()) + if new_val != getattr(r, "_last_val", None): + r._last_val = new_val + self._set_layout("gaps", new_val) + + gaps_row.connect("notify::value", _on_gaps_changed) + basic_grp.add(gaps_row) + + cfc_model = Gtk.StringList.new(CENTER_OPTIONS) + cfc_row = Adw.ComboRow(title="Center Focused Column", model=cfc_model) + cur_cfc = layout.child_arg("center-focused-column") or "never" + if cur_cfc in CENTER_OPTIONS: + cfc_row.set_selected(CENTER_OPTIONS.index(cur_cfc)) + cfc_row.connect( + "notify::selected", + lambda r, _: self._set_layout( + "center-focused-column", CENTER_OPTIONS[r.get_selected()] + ), + ) + basic_grp.add(cfc_row) + + prefer_csd_row = Adw.SwitchRow( + title="Prefer No CSD", subtitle="Ask apps to omit client-side decorations" + ) + prefer_csd_row.set_active(any(n.name == "prefer-no-csd" for n in nodes)) + prefer_csd_row.connect( + "notify::active", + lambda r, _: self._toggle_top("prefer-no-csd", r.get_active()), + ) + basic_grp.add(prefer_csd_row) + + bg_color_val = str(layout.child_arg("background-color") or "transparent") + bg_row = Adw.EntryRow(title="Background Color (e.g. transparent, #000000)") + bg_row.set_text(bg_color_val) + bg_row.set_show_apply_button(True) + bg_row.connect( + "apply", + lambda r: self._set_layout("background-color", r.get_text().strip()), + ) + basic_grp.add(bg_row) + + content.append(basic_grp) + + dcw_grp = Adw.PreferencesGroup(title="Default Column Width") + dcw_node = layout.get_child("default-column-width") + + prop_val = 0.5 + fixed_val = 800 + use_fixed = False + + if dcw_node: + fc = dcw_node.get_child("fixed") + pc = dcw_node.get_child("proportion") + if fc and fc.args: + fixed_val = int(fc.args[0]) + use_fixed = True + elif pc and pc.args: + prop_val = float(pc.args[0]) + + mode_model = Gtk.StringList.new(["Proportion", "Fixed (px)"]) + mode_row = Adw.ComboRow(title="Mode", model=mode_model) + mode_row.set_selected(1 if use_fixed else 0) + dcw_grp.add(mode_row) + + prop_adj = Gtk.Adjustment(value=prop_val, lower=0.05, upper=1.0, step_increment=0.05) + prop_spin = Gtk.SpinButton(adjustment=prop_adj, digits=2, climb_rate=1) + prop_spin.set_valign(Gtk.Align.CENTER) + prop_spin.connect("value-changed", lambda s: self._set_dcw_proportion(s.get_value())) + prop_row = Adw.ActionRow(title="Proportion") + prop_row.add_suffix(prop_spin) + prop_row.set_visible(not use_fixed) + dcw_grp.add(prop_row) + + fixed_adj = Gtk.Adjustment(value=fixed_val, lower=100, upper=7680, step_increment=10) + fixed_spin = Gtk.SpinButton(adjustment=fixed_adj, digits=0, climb_rate=1) + fixed_spin.set_valign(Gtk.Align.CENTER) + fixed_spin.connect("value-changed", lambda s: self._set_dcw_fixed(int(s.get_value()))) + fixed_row = Adw.ActionRow(title="Fixed Width (px)") + fixed_row.add_suffix(fixed_spin) + fixed_row.set_visible(use_fixed) + dcw_grp.add(fixed_row) + + def _on_mode_changed(r, _): + is_fixed = r.get_selected() == 1 + prop_row.set_visible(not is_fixed) + fixed_row.set_visible(is_fixed) + if is_fixed: + self._set_dcw_fixed(int(fixed_spin.get_value())) + else: + self._set_dcw_proportion(prop_spin.get_value()) + + mode_row.connect("notify::selected", _on_mode_changed) + content.append(dcw_grp) + + pw_grp = Adw.PreferencesGroup(title="Preset Column Widths (proportions)") + pw_grp.set_description("Cycled through by Mod+R") + pcw_node = layout.get_child("preset-column-widths") + presets = [] + if pcw_node: + for c in pcw_node.children: + if c.name == "proportion" and c.args: + presets.append(float(c.args[0])) + self._preset_spins: list[Gtk.SpinButton] = [] + + for val in presets or [0.333, 0.5, 0.667]: + self._add_preset_row(pw_grp, val) + add_preset_btn = Gtk.Button(label="Add Preset") + add_preset_btn.add_css_class("flat") + add_preset_btn.connect("clicked", lambda *_: self._add_preset_row(pw_grp, 0.5)) + pw_grp.set_header_suffix(add_preset_btn) + content.append(pw_grp) + + struts_grp = Adw.PreferencesGroup(title="Struts (outer gaps, px)") + struts_node = layout.get_child("struts") + for side in ["left", "right", "top", "bottom"]: + val = int(struts_node.child_arg(side) or 0) if struts_node else 0 + adj = Gtk.Adjustment(value=val, lower=0, upper=500, step_increment=4) + row = Adw.SpinRow(title=side.capitalize(), adjustment=adj, digits=0) + + row._last_val = val + + def _on_strut_changed(r, _, s=side): + new_val = int(r.get_value()) + if new_val != getattr(r, "_last_val", None): + r._last_val = new_val + self._set_strut(s, new_val) + + row.connect("notify::value", _on_strut_changed) + struts_grp.add(row) + content.append(struts_grp) + + def _add_preset_row(self, grp: Adw.PreferencesGroup, val: float): + spin_adj = Gtk.Adjustment(value=val, lower=0.05, upper=1.0, step_increment=0.05) + spin = Gtk.SpinButton(adjustment=spin_adj, digits=3, climb_rate=1) + spin.set_valign(Gtk.Align.CENTER) + self._preset_spins.append(spin) + + row = Adw.ActionRow(title=f"Proportion {val:.3f}") + spin.connect( + "value-changed", + lambda s, r=row: ( + r.set_title(f"Proportion {s.get_value():.3f}"), + self._save_presets(), + ), + ) + + del_btn = Gtk.Button(icon_name="user-trash-symbolic") + del_btn.set_valign(Gtk.Align.CENTER) + del_btn.add_css_class("flat") + del_btn.add_css_class("error") + + def _on_delete(s=spin): + self._preset_spins.remove(s) + grp.remove(row) + self._save_presets() + + del_btn.connect("clicked", lambda *_: _on_delete()) + row.add_suffix(spin) + row.add_suffix(del_btn) + grp.add(row) + + def _save_presets(self): + layout = find_or_create(self._nodes, "layout") + pcw = layout.get_child("preset-column-widths") + if pcw is None: + pcw = KdlNode("preset-column-widths") + layout.children.append(pcw) + new_children = [] + for i, s in enumerate(self._preset_spins): + if i < len(pcw.children): + child = pcw.children[i] + child.name = "proportion" + child.args = [round(s.get_value(), 5)] + new_children.append(child) + else: + new_children.append(KdlNode("proportion", args=[round(s.get_value(), 5)])) + + salvaged = "" + for i in range(len(self._preset_spins), len(pcw.children)): + salvaged += pcw.children[i].leading_trivia + if salvaged and new_children: + new_children[-1].trailing_trivia += salvaged + + pcw.children = new_children + self._commit("preset column widths") + + def _set_layout(self, key: str, value): + layout = find_or_create(self._nodes, "layout") + set_child_arg(layout, key, value) + self._commit(f"layout {key}") + + def _set_dcw_proportion(self, val: float): + layout = find_or_create(self._nodes, "layout") + dcw = layout.get_child("default-column-width") + if dcw is None: + dcw = KdlNode("default-column-width") + layout.children.append(dcw) + dcw.children = [KdlNode("proportion", args=[round(val, 4)])] + self._commit("default column width proportion") + + def _set_dcw_fixed(self, px: int): + layout = find_or_create(self._nodes, "layout") + dcw = layout.get_child("default-column-width") + if dcw is None: + dcw = KdlNode("default-column-width") + layout.children.append(dcw) + dcw.children = [KdlNode("fixed", args=[px])] + self._commit("default column width fixed") + + def _set_strut(self, side: str, val: int): + layout = find_or_create(self._nodes, "layout") + struts = layout.get_child("struts") + if struts is None: + struts = KdlNode("struts") + layout.children.append(struts) + if val > 0: + set_child_arg(struts, side, val) + else: + remove_child(struts, side) + self._commit(f"strut {side}") + + def _toggle_top(self, key: str, enabled: bool): + nodes = self._nodes + existing = next((n for n in reversed(nodes) if n.name == key), None) + + app_state = self._win.app_state + if enabled and not existing: + cache = getattr(app_state, "_removed_top_nodes", {}) + if key in cache: + idx, node = cache[key] + nodes.insert(min(idx, len(nodes)), node) + else: + nodes.append(KdlNode(key)) + elif not enabled and existing: + if not hasattr(app_state, "_removed_top_nodes"): + app_state._removed_top_nodes = {} + app_state._removed_top_nodes[key] = (nodes.index(existing), existing) + nodes.remove(existing) + + self._commit(f"toggle {key}") + + def refresh(self): + for child in list(self._content): + self._content.remove(child) + self._build_content() diff --git a/nirimod/pages/outputs.py b/nirimod/pages/outputs.py new file mode 100644 index 0000000..5a948d0 --- /dev/null +++ b/nirimod/pages/outputs.py @@ -0,0 +1,746 @@ +"""Outputs / Monitors page with interactive canvas.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +import gi + +gi.require_version("Gtk", "4.0") +gi.require_version("Adw", "1") + + +from gi.repository import Adw, Gtk + +from nirimod import niri_ipc +from nirimod.kdl_parser import KdlNode, set_child_arg, safe_switch_connect +from nirimod.pages.base import BasePage + +if TYPE_CHECKING: + from nirimod.window import NiriModWindow + +TRANSFORMS = [ + "normal", + "90", + "180", + "270", + "flipped", + "flipped-90", + "flipped-180", + "flipped-270", +] + + +class OutputsPage(BasePage): + def __init__(self, window: "NiriModWindow"): + super().__init__(window) + self._outputs: list[dict] = [] + self._current_out: dict | None = None + + self._canvas: Gtk.DrawingArea | None = None + self._drag_output: str | None = None + self._drag_offset: tuple[float, float] = (0, 0) + + def build(self) -> Gtk.Widget: + tb, header, scroll, content = self._make_toolbar_page("Outputs") + + add_fake_btn = Gtk.Button(icon_name="list-add-symbolic") + add_fake_btn.set_tooltip_text("Add fake monitor for testing") + add_fake_btn.add_css_class("flat") + add_fake_btn.connect("clicked", lambda *_: self._add_fake_monitor()) + header.pack_end(add_fake_btn) + + refresh_btn = Gtk.Button(icon_name="view-refresh-symbolic") + refresh_btn.set_tooltip_text("Reload outputs from niri") + refresh_btn.add_css_class("flat") + refresh_btn.connect("clicked", lambda *_: self.refresh()) + header.pack_end(refresh_btn) + + canvas_frame = Gtk.Frame() + canvas_frame.add_css_class("card") + canvas_frame.set_margin_bottom(8) + + self._canvas = Gtk.DrawingArea() + self._canvas.set_content_height(350) + self._canvas.set_draw_func(self._draw_canvas) + canvas_frame.set_child(self._canvas) + content.append(canvas_frame) + + drag = Gtk.GestureDrag() + drag.connect("drag-begin", self._on_drag_begin) + drag.connect("drag-update", self._on_drag_update) + drag.connect("drag-end", self._on_drag_end) + self._canvas.add_controller(drag) + + click = Gtk.GestureClick() + click.connect("pressed", self._on_canvas_click) + self._canvas.add_controller(click) + + self._out_combo = Adw.ComboRow(title="Monitor") + self._out_combo.connect("notify::selected", self._on_output_selected) + sel_group = Adw.PreferencesGroup() + sel_group.add(self._out_combo) + content.append(sel_group) + + self._detail_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12) + content.append(self._detail_box) + + self.refresh() + return tb + + def refresh(self): + def _on_got_outputs(outputs): + self._outputs = outputs + names = [o.get("name", "?") for o in self._outputs] + model = Gtk.StringList.new(names) + self._out_combo.set_model(model) + if self._outputs: + self._load_output_detail(self._outputs[0]) + if self._canvas: + self._canvas.queue_draw() + # Rebuild search index as the detail rows are now populated + if hasattr(self._win, "_build_search_index"): + self._win._build_search_index() + + niri_ipc.get_outputs(_on_got_outputs) + + def _add_fake_monitor(self): + idx = 1 + while any(o.get("name") == f"fake-{idx}" for o in self._outputs): + idx += 1 + name = f"fake-{idx}" + + o = { + "name": name, + "modes": [{"width": 1920, "height": 1080, "refresh_rate": 60000}], + "current_mode": 0, + "logical": { + "x": 0, + "y": 0, + "width": 1920, + "height": 1080, + "scale": 1.0, + "transform": "normal", + }, + } + self._outputs.append(o) + + names = [out.get("name", "?") for out in self._outputs] + model = Gtk.StringList.new(names) + self._out_combo.set_model(model) + self._out_combo.set_selected(len(self._outputs) - 1) + + if self._canvas: + self._canvas.queue_draw() + if hasattr(self._win, "_build_search_index"): + self._win._build_search_index() + + # Canvas drawing + + def _draw_canvas(self, area, cr, width, height): + if not self._outputs: + cr.set_source_rgba(0.05, 0.05, 0.05, 0.4) + cr.rectangle(0, 0, width, height) + cr.fill() + cr.set_source_rgba(0.5, 0.5, 0.5, 0.8) + cr.select_font_face("Sans", 0, 0) + cr.set_font_size(14) + cr.move_to(width / 2 - 80, height / 2) + cr.show_text("No outputs detected") + return + + min_x = min_y = float("inf") + max_x = max_y = float("-inf") + for o in self._outputs: + pos = o.get("logical", {}) + lx = pos.get("x", 0) + ly = pos.get("y", 0) + lw = pos.get("width", 1920) + lh = pos.get("height", 1080) + min_x = min(min_x, lx) + min_y = min(min_y, ly) + max_x = max(max_x, lx + lw) + max_y = max(max_y, ly + lh) + + if min_x == float("inf"): + min_x = min_y = 0 + max_x = 1920 + max_y = 1080 + + total_w = max_x - min_x + total_h = max_y - min_y + + scale = min(width / max(total_w, 1), height / max(total_h, 1)) * 0.9 + off_x = (width - total_w * scale) / 2 - min_x * scale + off_y = (height - total_h * scale) / 2 - min_y * scale + + if self._drag_output and hasattr(self, "_drag_start_scale"): + scale = self._drag_start_scale + off_x, off_y = self._drag_start_offset + + self._canvas_scale = scale + self._canvas_offset = (off_x, off_y) + self._canvas_pixel_w = width + self._canvas_pixel_h = height + + # grid background + cr.set_source_rgba(1, 1, 1, 0.03) + cr.set_line_width(1) + grid_size = 40 + for gx in range(0, int(width), grid_size): + cr.move_to(gx, 0) + cr.line_to(gx, height) + for gy in range(0, int(height), grid_size): + cr.move_to(0, gy) + cr.line_to(width, gy) + cr.stroke() + + for i, o in enumerate(self._outputs): + pos = o.get("logical", {}) + x = off_x + pos.get("x", 0) * scale + y = off_y + pos.get("y", 0) * scale + w = pos.get("width", 1920) * scale + h = pos.get("height", 1080) * scale + + is_sel = o.get("name") == ( + self._current_out.get("name") if self._current_out else None + ) + + if is_sel: + cr.set_source_rgba(155 / 255, 109 / 255, 1.0, 1.0) + else: + cr.set_source_rgba(0.2, 0.2, 0.2, 1.0) + cr.rectangle(x, y, w, h) + cr.fill_preserve() + + # border + cr.set_line_width(1.5) + if is_sel: + cr.set_source_rgba(0.7, 0.7, 0.75, 0.9) + else: + cr.set_source_rgba(0.4, 0.4, 0.45, 0.6) + cr.stroke() + + name = o.get("name", f"Output {i}") + mode_idx = o.get("current_mode") + modes = o.get("modes", []) + mode = ( + modes[mode_idx] + if isinstance(mode_idx, int) and 0 <= mode_idx < len(modes) + else {} + ) + out_scale = o.get("logical", {}).get("scale", 1.0) + res = f"{mode.get('width', '?')}×{mode.get('height', '?')}" + scale_text = f"Scale: {out_scale}x" + + cr.set_source_rgba(1, 1, 1, 0.95 if is_sel else 0.7) + + cr.select_font_face("Sans", 0, 1) + font_size = max(10, min(16, w / 10)) + cr.set_font_size(font_size) + te = cr.text_extents(name) + cr.move_to(x + w / 2 - te.width / 2, y + h / 2 - font_size * 0.3) + cr.show_text(name) + + cr.select_font_face("Sans", 0, 0) + res_size = max(8, min(12, w / 15)) + cr.set_font_size(res_size) + te2 = cr.text_extents(res) + cr.move_to(x + w / 2 - te2.width / 2, y + h / 2 + res_size * 1.2) + cr.show_text(res) + + cr.set_source_rgba(0.6, 0.6, 0.65, 0.9 if is_sel else 0.6) + scale_size = max(7, min(11, w / 18)) + cr.set_font_size(scale_size) + te3 = cr.text_extents(scale_text) + cr.move_to( + x + w / 2 - te3.width / 2, y + h / 2 + res_size * 1.2 + scale_size * 1.4 + ) + cr.show_text(scale_text) + + def _on_drag_begin(self, gesture, sx, sy): + if not hasattr(self, "_canvas_scale"): + return + scale = self._canvas_scale + ox, oy = self._canvas_offset + for o in reversed(self._outputs): + pos = o.get("logical", {}) + x = ox + pos.get("x", 0) * scale + y = oy + pos.get("y", 0) * scale + w = pos.get("width", 1920) * scale + h = pos.get("height", 1080) * scale + if x <= sx <= x + w and y <= sy <= y + h: + self._drag_output = o["name"] + self._last_dx = 0 + self._last_dy = 0 + self._drag_current_lx = pos.get("x", 0) + self._drag_current_ly = pos.get("y", 0) + self._drag_start_scale = scale + self._drag_start_offset = (ox, oy) + return + + def _on_drag_update(self, gesture, dx, dy): + if not self._drag_output or not hasattr(self, "_canvas_scale"): + return + + scale = getattr(self, "_drag_start_scale", self._canvas_scale) + delta_dx = dx - getattr(self, "_last_dx", 0) + delta_dy = dy - getattr(self, "_last_dy", 0) + self._last_dx = dx + self._last_dy = dy + + self._drag_current_lx += delta_dx / scale + self._drag_current_ly += delta_dy / scale + + new_lx = self._drag_current_lx + new_ly = self._drag_current_ly + + drag_o = next( + (o for o in self._outputs if o.get("name") == self._drag_output), None + ) + if not drag_o: + return + + monitor_scale = drag_o.get("logical", {}).get("scale", 1.0) + mode_idx = drag_o.get("current_mode") + modes = drag_o.get("modes", []) + mode = ( + modes[mode_idx] + if isinstance(mode_idx, int) and 0 <= mode_idx < len(modes) + else {} + ) + pixel_w = mode.get("width", 1920) + pixel_h = mode.get("height", 1080) + + transform = str(drag_o.get("logical", {}).get("transform", "normal")).lower().replace("_", "-") + if transform in ["90", "270", "flipped-90", "flipped-270"]: + pixel_w, pixel_h = pixel_h, pixel_w + + logical_w = pixel_w / monitor_scale + logical_h = pixel_h / monitor_scale + + # edge snapping + SNAP_THRESHOLD = 30 + snapped_x = new_lx + snapped_y = new_ly + closest_x = SNAP_THRESHOLD + 1 + closest_y = SNAP_THRESHOLD + 1 + + dragged_left = new_lx + dragged_right = new_lx + logical_w + dragged_top = new_ly + dragged_bottom = new_ly + logical_h + + for other in self._outputs: + if other.get("name") == self._drag_output: + continue + + other_pos = other.get("logical", {}) + other_x = other_pos.get("x", 0) + other_y = other_pos.get("y", 0) + + other_scale = other_pos.get("scale", 1.0) + other_mode_idx = other.get("current_mode") + other_modes = other.get("modes", []) + other_mode = other_modes[other_mode_idx] if isinstance(other_mode_idx, int) and 0 <= other_mode_idx < len(other_modes) else {} + other_pixel_w = other_mode.get("width", 1920) + other_pixel_h = other_mode.get("height", 1080) + + other_transform = str(other_pos.get("transform", "normal")).lower().replace("_", "-") + if other_transform in ["90", "270", "flipped-90", "flipped-270"]: + other_pixel_w, other_pixel_h = other_pixel_h, other_pixel_w + + other_logical_w = other_pixel_w / other_scale + other_logical_h = other_pixel_h / other_scale + + other_left = other_x + other_right = other_x + other_logical_w + other_top = other_y + other_bottom = other_y + other_logical_h + + for dragged_edge, is_left_edge in [(dragged_left, True), (dragged_right, False)]: + for other_edge in [other_left, other_right]: + dist = abs(dragged_edge - other_edge) + if dist < closest_x: + closest_x = dist + snapped_x = other_edge if is_left_edge else other_edge - logical_w + + for dragged_edge, is_top_edge in [(dragged_top, True), (dragged_bottom, False)]: + for other_edge in [other_top, other_bottom]: + dist = abs(dragged_edge - other_edge) + if dist < closest_y: + closest_y = dist + snapped_y = other_edge if is_top_edge else other_edge - logical_h + + if closest_x <= SNAP_THRESHOLD: + new_lx = snapped_x + if closest_y <= SNAP_THRESHOLD: + new_ly = snapped_y + + if "logical" not in drag_o: + drag_o["logical"] = {} + drag_o["logical"]["x"] = new_lx + drag_o["logical"]["y"] = new_ly + + if self._canvas: + self._canvas.queue_draw() + + def _on_drag_end(self, gesture, dx, dy): + if self._drag_output: + if self._canvas: + self._canvas.queue_draw() + + for o in self._outputs: + self._apply_position(o["name"]) + + if self._current_out: + cur_pos = self._current_out.get("logical", {}) + if hasattr(self, "_pos_x_adj"): + self._pos_x_adj.set_value(cur_pos.get("x", 0)) + if hasattr(self, "_pos_y_adj"): + self._pos_y_adj.set_value(cur_pos.get("y", 0)) + + self._drag_output = None + + def _on_canvas_click(self, gesture, n_press, x, y): + if not hasattr(self, "_canvas_scale"): + return + + scale = self._canvas_scale + ox, oy = self._canvas_offset + + for i, o in reversed(list(enumerate(self._outputs))): + pos = o.get("logical", {}) + mx = ox + pos.get("x", 0) * scale + my = oy + pos.get("y", 0) * scale + mw = pos.get("width", 1920) * scale + mh = pos.get("height", 1080) * scale + + if mx <= x <= mx + mw and my <= y <= my + mh: + self._out_combo.set_selected(i) + return + + def _apply_position(self, name: str): + o = next((x for x in self._outputs if x["name"] == name), None) + if not o: + return + pos = o.get("logical", {}) + + nx = pos.get("x", 0) + ny = pos.get("y", 0) + + out_node = self._get_or_create_out_node(name) + pos_node = out_node.get_child("position") + if pos_node is None: + pos_node = KdlNode(name="position") + out_node.children.append(pos_node) + pos_node.props["x"] = int(round(nx)) + pos_node.props["y"] = int(round(ny)) + + if self._current_out and self._current_out.get("name") == name: + if hasattr(self, "_pos_x_adj"): + self._pos_x_adj.set_value(nx) + if hasattr(self, "_pos_y_adj"): + self._pos_y_adj.set_value(ny) + + self._commit("output position") + + def _on_output_selected(self, combo, _): + idx = combo.get_selected() + if 0 <= idx < len(self._outputs): + self._load_output_detail(self._outputs[idx]) + # Rebuild search index as the detail rows have changed + if hasattr(self._win, "_build_search_index"): + self._win._build_search_index() + + def _load_output_detail(self, output: dict): + self._current_out = output + for child in list(self._detail_box): + self._detail_box.remove(child) + + name = output.get("name", "?") + nodes = self._nodes + out_node = next( + (n for n in nodes if n.name == "output" and n.args and n.args[0] == name), + None, + ) + + modes = output.get("modes", []) + mode_strs = [ + f"{m.get('width', 0)}×{m.get('height', 0)}@{m.get('refresh_rate', 0) / 1000:.3f}" + for m in modes + ] + mode_model = Gtk.StringList.new(mode_strs) + mode_row = Adw.ComboRow(title="Resolution & Refresh Rate") + mode_row.set_model(mode_model) + mode_idx = output.get("current_mode") + cur_mode = ( + modes[mode_idx] + if isinstance(mode_idx, int) and 0 <= mode_idx < len(modes) + else {} + ) + cur_str = f"{cur_mode.get('width', 0)}×{cur_mode.get('height', 0)}@{cur_mode.get('refresh_rate', 0) / 1000:.3f}" + if cur_str in mode_strs: + mode_row.set_selected(mode_strs.index(cur_str)) + mode_row.connect( + "notify::selected", + lambda r, _: self._on_mode_changed(name, modes, r.get_selected()), + ) + + scale_val = round(output.get("logical", {}).get("scale", 1.0), 3) + scale_adj = Gtk.Adjustment( + value=scale_val, + lower=0.01, + upper=100.0, + step_increment=0.05, + ) + scale_row = Adw.SpinRow(title="Scale", adjustment=scale_adj, digits=2) + scale_row.connect( + "notify::value", + lambda r, _: self._set_output_prop(name, "scale", r.get_value()), + ) + + t_model = Gtk.StringList.new(TRANSFORMS) + transform_row = Adw.ComboRow(title="Transform", model=t_model) + cur_t = output.get("logical", {}).get("transform", "normal") + cur_t_norm = str(cur_t).lower().replace("_", "-") if cur_t else "normal" + if cur_t_norm in TRANSFORMS: + transform_row.set_selected(TRANSFORMS.index(cur_t_norm)) + transform_row.connect( + "notify::selected", + lambda r, _: self._set_output_prop( + name, "transform", TRANSFORMS[r.get_selected()] + ), + ) + + px = output.get("logical", {}).get("x", 0) + py = output.get("logical", {}).get("y", 0) + px_adj = Gtk.Adjustment(value=px, lower=-1000000, upper=1000000, step_increment=1) + py_adj = Gtk.Adjustment(value=py, lower=-1000000, upper=1000000, step_increment=1) + self._pos_x_adj = px_adj + self._pos_y_adj = py_adj + pos_x_row = Adw.SpinRow(title="Position X", adjustment=px_adj, digits=0) + pos_y_row = Adw.SpinRow(title="Position Y", adjustment=py_adj, digits=0) + pos_x_row.connect( + "notify::value", + lambda r, _: self._set_output_pos( + name, int(r.get_value()), int(py_adj.get_value()) + ), + ) + pos_y_row.connect( + "notify::value", + lambda r, _: self._set_output_pos( + name, int(px_adj.get_value()), int(r.get_value()) + ), + ) + + vrr_row = Adw.SwitchRow(title="Variable Refresh Rate (VRR)") + vrr_val = ( + (out_node.get_child("variable-refresh-rate") is not None) + if out_node + else False + ) + vrr_row.set_active(vrr_val) + safe_switch_connect( + vrr_row, + vrr_val, + lambda enabled: self._set_output_flag( + name, "variable-refresh-rate", enabled + ), + ) + + off_row = Adw.SwitchRow(title="Disable Output") + off_val = (out_node.get_child("off") is not None) if out_node else False + off_row.set_active(off_val) + safe_switch_connect( + off_row, + off_val, + lambda enabled: self._set_output_flag(name, "off", enabled), + ) + + grp = Adw.PreferencesGroup(title=f"Output: {name}") + for r in [ + mode_row, + scale_row, + transform_row, + pos_x_row, + pos_y_row, + vrr_row, + off_row, + ]: + grp.add(r) + self._detail_box.append(grp) + + if self._canvas: + self._canvas.queue_draw() + + def _ensure_output_fields(self, out_node: KdlNode, name: str): + manual_out = None + try: + manual_nodes = self._nodes + if manual_nodes: + manual_out = next( + ( + n + for n in manual_nodes + if n.name == "output" and n.args and n.args[0] == name + ), + None, + ) + except Exception: + pass + + if manual_out: + if out_node.get_child("mode") is None: + m = manual_out.child_arg("mode") + if m: + set_child_arg(out_node, "mode", m) + if out_node.get_child("scale") is None: + s = manual_out.child_arg("scale") + if s is not None: + set_child_arg(out_node, "scale", s) + if out_node.get_child("transform") is None: + t = manual_out.child_arg("transform") + if t: + set_child_arg(out_node, "transform", t) + if out_node.get_child("position") is None: + pos_node = manual_out.get_child("position") + if pos_node: + new_pos = KdlNode(name="position", props=pos_node.props.copy()) + out_node.children.append(new_pos) + + o = next((x for x in self._outputs if x.get("name") == name), None) + if o: + if out_node.get_child("mode") is None: + mode_idx = o.get("current_mode") + modes = o.get("modes", []) + if isinstance(mode_idx, int) and 0 <= mode_idx < len(modes): + m = modes[mode_idx] + mode_str = f"{m.get('width', 0)}x{m.get('height', 0)}@{m.get('refresh_rate', 0) / 1000:.3f}" + set_child_arg(out_node, "mode", mode_str) + if out_node.get_child("scale") is None: + set_child_arg(out_node, "scale", o.get("logical", {}).get("scale", 1.0)) + if out_node.get_child("transform") is None: + t = o.get("logical", {}).get("transform", "normal") + t = str(t).lower().replace("_", "-") if t else "normal" + if t not in TRANSFORMS: + t = "normal" + set_child_arg(out_node, "transform", t) + pos_node = out_node.get_child("position") + if pos_node is None: + pos_node = KdlNode(name="position") + out_node.children.append(pos_node) + pos_node.props["x"] = o.get("logical", {}).get("x", 0) + pos_node.props["y"] = o.get("logical", {}).get("y", 0) + + def _get_or_create_out_node(self, name: str) -> KdlNode: + nodes = self._nodes + out_node = next( + (n for n in nodes if n.name == "output" and n.args and n.args[0] == name), + None, + ) + is_new = out_node is None + if out_node is None: + out_node = KdlNode(name="output", args=[name]) + nodes.append(out_node) + + assert out_node is not None + + if is_new: + self._ensure_output_fields(out_node, name) + + order = {"mode": 0, "scale": 1, "transform": 2, "position": 3} + out_node.children.sort(key=lambda c: order.get(c.name, 999)) + + return out_node + + def _update_logical_dims(self, o: dict): + if "logical" not in o: + o["logical"] = {} + mode_idx = o.get("current_mode") + modes = o.get("modes", []) + m = ( + modes[mode_idx] + if isinstance(mode_idx, int) and 0 <= mode_idx < len(modes) + else {} + ) + pw = m.get("width", 1920) + ph = m.get("height", 1080) + + scale = o["logical"].get("scale", 1.0) + if scale <= 0: + scale = 1.0 + + t = o["logical"].get("transform", "normal") + t_str = str(t).lower().replace("_", "-") + if t_str in ["90", "270", "flipped-90", "flipped-270"]: + pw, ph = ph, pw + + o["logical"]["width"] = round(pw / scale) + o["logical"]["height"] = round(ph / scale) + + def _on_mode_changed(self, name: str, modes: list, idx: int): + if not (0 <= idx < len(modes)): + return + m = modes[idx] + mode_str = f"{m.get('width', 0)}x{m.get('height', 0)}@{m.get('refresh_rate', 0) / 1000:.3f}" + out_node = self._get_or_create_out_node(name) + set_child_arg(out_node, "mode", mode_str) + + o = next((x for x in self._outputs if x.get("name") == name), None) + if o: + o["current_mode"] = idx + self._update_logical_dims(o) + + self._commit("output mode") + if self._canvas: + self._canvas.queue_draw() + + def _set_output_prop(self, name: str, prop: str, value): + if prop == "scale" and isinstance(value, float): + value = round(value, 3) + + out_node = self._get_or_create_out_node(name) + set_child_arg(out_node, prop, value) + + o = next((x for x in self._outputs if x.get("name") == name), None) + if o: + if "logical" not in o: + o["logical"] = {} + if prop == "scale": + o["logical"]["scale"] = value + elif prop == "transform": + o["logical"]["transform"] = value + self._update_logical_dims(o) + + self._commit(f"output {prop}") + if self._canvas: + self._canvas.queue_draw() + + def _set_output_pos(self, name: str, x: int, y: int): + out_node = self._get_or_create_out_node(name) + pos_node = out_node.get_child("position") + if pos_node is None: + pos_node = KdlNode(name="position") + out_node.children.append(pos_node) + + pos_node.props["x"] = int(round(x)) + pos_node.props["y"] = int(round(y)) + + o = next((out for out in self._outputs if out.get("name") == name), None) + if o: + if "logical" not in o: + o["logical"] = {} + o["logical"]["x"] = x + o["logical"]["y"] = y + + self._commit("output position") + if self._canvas: + self._canvas.queue_draw() + + def _set_output_flag(self, name: str, flag: str, enabled: bool): + from nirimod.kdl_parser import set_node_flag + + out_node = self._get_or_create_out_node(name) + set_node_flag(out_node, flag, enabled) + self._commit(f"output {flag}") diff --git a/nirimod/pages/raw_config.py b/nirimod/pages/raw_config.py new file mode 100644 index 0000000..5411a33 --- /dev/null +++ b/nirimod/pages/raw_config.py @@ -0,0 +1,322 @@ +"""Raw Config page — editable view of the full merged config.""" + +from __future__ import annotations + + +import gi + +gi.require_version("Gtk", "4.0") +gi.require_version("Adw", "1") +from gi.repository import Gtk, Pango, GLib + +from pathlib import Path + +from nirimod import niri_ipc +from nirimod.kdl_parser import NIRI_CONFIG +from nirimod.pages.base import BasePage + + +class RawConfigPage(BasePage): + def build(self) -> Gtk.Widget: + tb, header, _, content = self._make_toolbar_page("Raw Config") + self._content = content + + self._scroll_positions: dict[Path, tuple[float, float]] = {} + self._buffer_modified = False + self._original_text = "" + + self._current_files: list[Path] = [] + self._file_dropdown = Gtk.DropDown() + self._file_dropdown.set_valign(Gtk.Align.CENTER) + self._file_dropdown.connect("notify::selected-item", self._on_file_selected) + + title_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=12) + title_box.set_halign(Gtk.Align.CENTER) + title_box.set_valign(Gtk.Align.CENTER) + + title_label = Gtk.Label(label="Config File") + title_label.add_css_class("title") + title_box.append(title_label) + title_box.append(self._file_dropdown) + + header.pack_start(title_box) + title_box.set_margin_start(12) + + # Header actions + validate_btn = Gtk.Button(label="Validate") + validate_btn.add_css_class("suggested-action") + validate_btn.connect("clicked", self._on_validate) + header.pack_end(validate_btn) + + self._save_btn = Gtk.Button(label="Save") + self._save_btn.add_css_class("suggested-action") + self._save_btn.set_tooltip_text("Save this file and reload niri (Ctrl+S)") + self._save_btn.connect("clicked", self._on_save_raw) + self._save_btn.set_sensitive(False) + header.pack_end(self._save_btn) + + self._discard_btn = Gtk.Button(label="Discard") + self._discard_btn.add_css_class("destructive-action") + self._discard_btn.add_css_class("flat") + self._discard_btn.set_tooltip_text("Discard unsaved changes") + self._discard_btn.connect("clicked", self._on_discard_raw) + self._discard_btn.set_sensitive(False) + header.pack_end(self._discard_btn) + + # Editor + self._textview = Gtk.TextView() + self._textview.set_editable(True) + self._textview.set_monospace(True) + self._textview.set_wrap_mode(Gtk.WrapMode.NONE) + self._textview.set_left_margin(16) + self._textview.set_right_margin(16) + self._textview.set_top_margin(16) + self._textview.set_bottom_margin(16) + self._textview.add_css_class("code-editor") + + self._buf = self._textview.get_buffer() + self._buf.connect("changed", self._on_buffer_changed) + + self._scroll = Gtk.ScrolledWindow() + self._scroll.add_css_class("card") + self._scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) + self._scroll.set_vexpand(True) + self._scroll.set_hexpand(True) + self._scroll.set_child(self._textview) + content.append(self._scroll) + + self.refresh() + return tb + + + # Scroll position helpers + + def _save_scroll_position(self): + """Persist the current scroll position for the active file.""" + idx = self._file_dropdown.get_selected() + if idx == Gtk.INVALID_LIST_POSITION or idx >= len(self._current_files): + return + path = self._current_files[idx] + hadj = self._scroll.get_hadjustment() + vadj = self._scroll.get_vadjustment() + self._scroll_positions[path] = (hadj.get_value(), vadj.get_value()) + + def _restore_scroll_position(self, path: Path): + """Restore the saved scroll position for a given file, if any.""" + if path not in self._scroll_positions: + return + hval, vval = self._scroll_positions[path] + + def _apply(): + hadj = self._scroll.get_hadjustment() + vadj = self._scroll.get_vadjustment() + hadj.set_value(hval) + vadj.set_value(vval) + return False # don't repeat + + # Defer one frame so the buffer is fully laid out before scrolling + GLib.idle_add(_apply) + + + # Page lifecycle + + def on_shown(self): + """Called every time the user navigates back to this page.""" + # Restore scroll for whichever file is currently selected + idx = self._file_dropdown.get_selected() + if idx != Gtk.INVALID_LIST_POSITION and idx < len(self._current_files): + self._restore_scroll_position(self._current_files[idx]) + + def refresh(self): + state = self._win.app_state + + if state.is_multi_file: + self._current_files = sorted(list(state.source_files)) + if NIRI_CONFIG in self._current_files: + self._current_files.remove(NIRI_CONFIG) + self._current_files.insert(0, NIRI_CONFIG) + else: + self._current_files = [NIRI_CONFIG] + + strings = [p.name for p in self._current_files] + self._file_dropdown.set_model(Gtk.StringList.new(strings)) + + self._load_selected_file() + + def _reload_from_disk(self): + """Re-read the file from disk, discarding any edits.""" + self._load_selected_file(force=True) + + + # File loading + + def _on_file_selected(self, dropdown, param): + self._save_scroll_position() + self._load_selected_file() + + def _load_selected_file(self, force: bool = False): + idx = self._file_dropdown.get_selected() + if idx == Gtk.INVALID_LIST_POSITION or idx >= len(self._current_files): + return + + if self._buffer_modified and not force: + self._confirm_discard_then(lambda: self._do_load_file(idx)) + return + + self._do_load_file(idx) + + def _do_load_file(self, idx: int): + path = self._current_files[idx] + text = path.read_text() if path.exists() else f"// File not found: {path}" + + self._buf.handler_block_by_func(self._on_buffer_changed) + self._buf.set_text(text) + self._original_text = text + self._apply_syntax_highlighting(self._buf, text) + self._buf.handler_unblock_by_func(self._on_buffer_changed) + + self._set_modified(False) + self._restore_scroll_position(path) + + + # Buffer modification tracking + + def _on_buffer_changed(self, buf): + text = buf.get_text(buf.get_start_iter(), buf.get_end_iter(), False) + is_changed = (text != self._original_text) + if is_changed != self._buffer_modified: + self._set_modified(is_changed) + + def _set_modified(self, modified: bool): + self._buffer_modified = modified + self._save_btn.set_sensitive(modified) + self._discard_btn.set_sensitive(modified) + + + # Save / Discard + + def _on_save_raw(self, *_): + idx = self._file_dropdown.get_selected() + if idx == Gtk.INVALID_LIST_POSITION or idx >= len(self._current_files): + return + + path = self._current_files[idx] + text = self._buf.get_text(self._buf.get_start_iter(), self._buf.get_end_iter(), False) + + from nirimod import app_settings + if app_settings.get("auto_backup", True): + from nirimod.backup import backup_all_sources + limit = app_settings.get("backup_limit", 10) + backup_all_sources(self._win.app_state.source_files, limit=limit) + + tmp = path.with_suffix(path.suffix + ".tmp") + try: + tmp.write_text(text) + except Exception as e: + self.show_toast(f"Write error: {e}", timeout=6) + return + + self.show_toast("Validating…", timeout=2) + + def _on_validated(result): + ok, msg = result + if not ok: + tmp.unlink(missing_ok=True) + self.show_toast(f"Validation error: {msg[:120]}", timeout=8) + return + try: + tmp.replace(path) + except Exception as e: + self.show_toast(f"Save error: {e}", timeout=6) + return + + self._set_modified(False) + self._original_text = text + self._apply_syntax_highlighting(self._buf, text) + niri_ipc.run_in_thread(niri_ipc.load_config_file, self._on_reloaded) + + niri_ipc.run_in_thread( + lambda: niri_ipc.validate_config(str(tmp)), _on_validated + ) + + def _on_reloaded(self, result): + ok, msg = result + if ok: + self.show_toast("Config saved and applied ✓", timeout=3) + else: + self.show_toast(f"Saved, but reload failed: {msg[:80]}", timeout=8) + self._win.app_state.reload_from_disk() + self._win._build_search_index() + + def _on_discard_raw(self, *_): + self._confirm_discard_then(self._reload_from_disk) + + def _confirm_discard_then(self, callback): + import gi + gi.require_version("Adw", "1") + from gi.repository import Adw + + dialog = Adw.AlertDialog( + heading="Discard changes?", + body="Your unsaved edits to this file will be lost.", + ) + dialog.add_response("cancel", "Cancel") + dialog.add_response("discard", "Discard") + dialog.set_response_appearance("discard", Adw.ResponseAppearance.DESTRUCTIVE) + dialog.set_default_response("cancel") + + def _on_response(dlg, response): + if response == "discard": + self._set_modified(False) + callback() + + dialog.connect("response", _on_response) + dialog.present(self._win) + + + # Syntax highlighting + + def _apply_syntax_highlighting(self, buf: Gtk.TextBuffer, text: str): + tag_table = buf.get_tag_table() + + def _get_or_create_tag(name, **props): + t = tag_table.lookup(name) + if t is None: + t = buf.create_tag(name, **props) + return t + + comment_tag = _get_or_create_tag( + "comment", foreground="#6a9955", style=Pango.Style.ITALIC + ) + string_tag = _get_or_create_tag("string", foreground="#ce9178") + node_tag = _get_or_create_tag("node", foreground="#9cdcfe") + keyword_tag = _get_or_create_tag("keyword", foreground="#c586c0") + + import re + + def _apply(pattern, tag, group=0): + for m in re.finditer(pattern, text, re.MULTILINE): + s = buf.get_iter_at_offset(m.start(group)) + e = buf.get_iter_at_offset(m.end(group)) + buf.apply_tag(tag, s, e) + + _apply(r"//[^\n]*", comment_tag) + _apply(r'"[^"\\]*(?:\\.[^"\\]*)*"', string_tag) + _apply(r"\b(true|false|null)\b", keyword_tag) + _apply(r"^(\s*)([a-zA-Z][\w\-]*)", node_tag, group=2) + + + # Copy / Validate + + + + def _on_validate(self, *_): + self.show_toast("Validating...") + + def _on_validated(result): + ok, msg = result + self.show_toast(msg[:120], timeout=5) + + niri_ipc.run_in_thread( + lambda: niri_ipc.validate_config(str(NIRI_CONFIG)), _on_validated + ) diff --git a/nirimod/pages/startup.py b/nirimod/pages/startup.py new file mode 100644 index 0000000..d0f4017 --- /dev/null +++ b/nirimod/pages/startup.py @@ -0,0 +1,171 @@ +"""Startup Programs page.""" + +from __future__ import annotations + + +import shlex +import gi + +gi.require_version("Gtk", "4.0") +gi.require_version("Adw", "1") +from gi.repository import Adw, Gtk, GLib + +from nirimod.kdl_parser import KdlNode +from nirimod.pages.base import BasePage + + +class StartupPage(BasePage): + def build(self) -> Gtk.Widget: + tb, header, _, content = self._make_toolbar_page("Startup Programs") + self._content = content + + + + self.refresh() + return tb + + def refresh(self): + self._rebuild() + + def _get_entries(self) -> list[KdlNode]: + return [ + n + for n in self._nodes + if n.name in ("spawn-at-startup", "spawn-sh-at-startup") + ] + + def _rebuild(self): + # Clear existing content + while True: + child = self._content.get_first_child() + if child is None: + break + self._content.remove(child) + + entries = self._get_entries() + + if not entries: + status = Adw.StatusPage( + title="No Startup Programs", + description="Programs added here will launch automatically when niri starts.", + icon_name="applications-system-symbolic", + ) + + add_btn = Gtk.Button(label="Add Program") + add_btn.add_css_class("pill") + add_btn.add_css_class("suggested-action") + add_btn.set_halign(Gtk.Align.CENTER) + add_btn.connect("clicked", self._on_add) + + box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) + box.set_valign(Gtk.Align.CENTER) + box.set_vexpand(True) + box.append(status) + box.append(add_btn) + + self._content.append(box) + else: + grp = Adw.PreferencesGroup( + title="Startup Programs", + description=f"{len(entries)} program{'s' if len(entries) != 1 else ''} configured to launch", + ) + for i, entry in enumerate(entries): + row = self._make_row(entry, i) + grp.add(row) + + self._content.append(grp) + + # Also add a convenient button at the bottom + add_btn = Gtk.Button(label="Add Another Program") + add_btn.add_css_class("pill") + add_btn.set_halign(Gtk.Align.CENTER) + add_btn.set_margin_top(16) + add_btn.connect("clicked", self._on_add) + self._content.append(add_btn) + + def _make_row(self, node: KdlNode, idx: int) -> Adw.ActionRow: + cmd = " ".join(str(a) for a in node.args) + is_sh = "sh" in node.name + cmd_str = GLib.markup_escape_text(cmd) if cmd else "(empty)" + + row = Adw.ActionRow( + title=cmd_str or "(empty)", + subtitle="Via shell (spawn-sh-at-startup)" if is_sh else "Launched directly", + ) + row.set_activatable(True) + row.connect("activated", lambda *_, i=idx: self._on_edit(i)) + + del_btn = Gtk.Button(icon_name="user-trash-symbolic") + del_btn.set_valign(Gtk.Align.CENTER) + del_btn.add_css_class("flat") + del_btn.add_css_class("error") + del_btn.set_tooltip_text("Remove startup entry") + del_btn.connect("clicked", lambda *_, i=idx: self._on_delete(i)) + row.add_suffix(del_btn) + return row + + def _on_add(self, *_): + self._show_dialog(None, -1) + + def _on_edit(self, idx: int): + entries = self._get_entries() + if 0 <= idx < len(entries): + self._show_dialog(entries[idx], idx) + + def _on_delete(self, idx: int): + entries = self._get_entries() + if 0 <= idx < len(entries): + self._nodes.remove(entries[idx]) + self._commit("remove startup entry") + self._rebuild() + + def _show_dialog(self, node: KdlNode | None, idx: int): + dialog = Adw.AlertDialog( + heading="Startup Program", body="Enter the command to launch at startup." + ) + cmd_entry = Adw.EntryRow(title="Command") + sh_switch = Adw.SwitchRow(title="Use shell (spawn-sh-at-startup)") + if node: + cmd_entry.set_text(" ".join(str(a) for a in node.args)) + sh_switch.set_active("sh" in node.name) + + box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=4) + grp = Adw.PreferencesGroup() + grp.add(cmd_entry) + grp.add(sh_switch) + box.append(grp) + dialog.set_extra_child(box) + + dialog.add_response("cancel", "Cancel") + dialog.add_response("save", "Save") + dialog.set_response_appearance("save", Adw.ResponseAppearance.SUGGESTED) + + def _on_resp(d, r): + if r != "save": + return + cmd = cmd_entry.get_text().strip() + if not cmd: + return + is_sh = sh_switch.get_active() + node_name = "spawn-sh-at-startup" if is_sh else "spawn-at-startup" + if is_sh: + # sh -c expects a single string; store the whole command as one arg + args = [cmd] + else: + try: + args = shlex.split(cmd) + except ValueError: + args = cmd.split() + + new_node = KdlNode(node_name, args=args) + entries = self._get_entries() + if idx >= 0 and 0 <= idx < len(entries): + i = self._nodes.index(entries[idx]) + self._nodes[i] = new_node + else: + self._nodes.append(new_node) + self._commit("startup entry") + self._rebuild() + + dialog.connect("response", _on_resp) + dialog.present(self._win) diff --git a/nirimod/pages/window_rules.py b/nirimod/pages/window_rules.py new file mode 100644 index 0000000..44d8886 --- /dev/null +++ b/nirimod/pages/window_rules.py @@ -0,0 +1,1014 @@ +"""Window Rules page — redesigned for usability.""" + +from __future__ import annotations + +from typing import NamedTuple + +import gi + +gi.require_version("Gtk", "4.0") +gi.require_version("Adw", "1") +from gi.repository import Adw, Gtk, GLib + +from nirimod.kdl_parser import KdlNode, KdlRawString +from nirimod.pages.base import BasePage + + +# ── Human-readable labels ──────────────────────────────────────────────────── + +SCREENCAST_BLOCK_KEY = "block-out-from" + +BOOL_MATCH_LABELS = { + "is-active": "Is Active", + "is-floating": "Is Floating", + "is-focused": "Is Focused", + "at-startup": "At Startup", +} + +BOOL_ACTION_LABELS = { + "open-maximized": "Open Maximized", + "open-fullscreen": "Open Fullscreen", + "open-floating": "Open Floating", + SCREENCAST_BLOCK_KEY: "Block from Screencast", + "draw-border-with-background": "Draw Border with Background", + "clip-to-geometry": "Clip to Geometry", + "prefer-no-csd": "Prefer No CSD", +} + +NUM_ACTION_LABELS = { + "opacity": ("Opacity", 0.0, 1.0, 0.05, 2), + "geometry-corner-radius": ("Corner Radius (px)", 0, 40, 1, 0), + "min-width": ("Min Width (px)", 0, 7680, 1, 0), + "min-height": ("Min Height (px)", 0, 7680, 1, 0), + "max-width": ("Max Width (px)", 0, 7680, 1, 0), + "max-height": ("Max Height (px)", 0, 7680, 1, 0), +} + +STR_ACTION_LABELS = { + "open-on-workspace": "Open on Workspace", + "open-on-output": "Open on Output", +} + +LAYER_BOOL_ACTION_LABELS = { + "place-within-backdrop": "Place Within Backdrop", + SCREENCAST_BLOCK_KEY: "Block from Screencast", +} + +FLOATING_POSITION_PRESETS = [ + ("Top", "top"), + ("Bottom", "bottom"), + ("Left", "left"), + ("Right", "right"), +] +CUSTOM_FLOATING_POSITION_LABEL = "Custom" +FLOATING_POSITION_LOCATION_LABELS = [ + label for label, _ in FLOATING_POSITION_PRESETS +] + [CUSTOM_FLOATING_POSITION_LABEL] +FLOATING_POSITION_CUSTOM_FIELD_LABELS = ["X Offset (px)", "Y Offset (px)"] +CUSTOM_FLOATING_POSITION_INDEX = len(FLOATING_POSITION_PRESETS) +DEFAULT_FLOATING_POSITION_RELATIVE_TO = "top" +CUSTOM_FLOATING_POSITION_RELATIVE_TO = "top-left" + + +class WindowSizeControlConfig(NamedTuple): + title: str + initial_percent: float + fixed: int + + +SIZE_PERCENT_PRESETS = [ + ("25%", 0.25), + ("33%", 0.33333), + ("50%", 0.5), + ("66%", 0.66667), + ("75%", 0.75), + ("100%", 1.0), +] +SIZE_MODE_LABELS = [label for label, _ in SIZE_PERCENT_PRESETS] + [ + "Custom %", + "Fixed (px)", +] +CUSTOM_SIZE_INDEX = len(SIZE_PERCENT_PRESETS) +FIXED_SIZE_INDEX = CUSTOM_SIZE_INDEX + 1 +WINDOW_SIZE_CONTROLS = { + "default-column-width": WindowSizeControlConfig( + title="Default Width", + initial_percent=50.0, + fixed=800, + ), + "default-window-height": WindowSizeControlConfig( + title="Default Height", + initial_percent=100.0, + fixed=600, + ), +} + + +def _bool_action_active(rule: KdlNode | None, key: str) -> bool: + if rule is None: + return False + if key != SCREENCAST_BLOCK_KEY: + return rule.get_child(key) is not None + + legacy = rule.get_child("block-out-from-screencast") + if legacy is not None: + return True + + node = rule.get_child(SCREENCAST_BLOCK_KEY) + return node is not None and bool(node.args) and node.args[0] == "screencast" + + +def _bool_action_node(key: str) -> KdlNode: + if key == SCREENCAST_BLOCK_KEY: + return KdlNode(SCREENCAST_BLOCK_KEY, args=["screencast"]) + return KdlNode(key, args=[True]) + + +def _floating_position_setting(rule: KdlNode | None) -> tuple[bool, int, int, str]: + if rule is None: + return (False, 0, 0, DEFAULT_FLOATING_POSITION_RELATIVE_TO) + + node = rule.get_child("default-floating-position") + if node is None: + return (False, 0, 0, DEFAULT_FLOATING_POSITION_RELATIVE_TO) + + x = int(node.props.get("x", 0)) + y = int(node.props.get("y", 0)) + relative_to = str( + node.props.get("relative-to", DEFAULT_FLOATING_POSITION_RELATIVE_TO) + ) + return (True, x, y, relative_to) + + +def _make_floating_position_node( + enabled: bool, x: int, y: int, relative_to: str +) -> KdlNode | None: + if not enabled: + return None + relative_to = relative_to.strip() + if not relative_to: + relative_to = DEFAULT_FLOATING_POSITION_RELATIVE_TO + return KdlNode( + "default-floating-position", + props={"x": int(x), "y": int(y), "relative-to": relative_to}, + ) + + +def _floating_position_location_index(x: int, y: int, relative_to: str) -> int: + if x != 0 or y != 0: + return CUSTOM_FLOATING_POSITION_INDEX + for index, (_, preset_relative_to) in enumerate(FLOATING_POSITION_PRESETS): + if relative_to == preset_relative_to: + return index + return CUSTOM_FLOATING_POSITION_INDEX + + +def _legacy_size_arg_setting(value) -> tuple[str, float | int | None]: + if isinstance(value, str): + text = value.strip().rstrip(";") + if not text: + return ("default", None) + if text.endswith("%"): + try: + return ("proportion", round(float(text[:-1]) / 100.0, 5)) + except ValueError: + return ("default", None) + + parts = text.split() + if len(parts) == 2 and parts[0] in {"proportion", "fixed"}: + try: + number = float(parts[1]) + except ValueError: + return ("default", None) + if parts[0] == "proportion": + return ("proportion", round(number, 5)) + return ("fixed", int(number)) + + try: + value = float(text) + except ValueError: + return ("default", None) + + if isinstance(value, bool) or value is None: + return ("default", None) + if isinstance(value, float) and 0 < value <= 1: + return ("proportion", round(value, 5)) + if isinstance(value, (int, float)) and value > 0: + return ("fixed", int(value)) + return ("default", None) + + +def _window_size_setting( + rule: KdlNode | None, key: str +) -> tuple[str, float | int | None]: + if rule is None: + return ("default", None) + + node = rule.get_child(key) + if node is None: + return ("default", None) + + proportion = node.get_child("proportion") + if proportion is not None and proportion.args: + return ("proportion", round(float(proportion.args[0]), 5)) + + fixed = node.get_child("fixed") + if fixed is not None and fixed.args: + return ("fixed", int(float(fixed.args[0]))) + + if node.args: + return _legacy_size_arg_setting(node.args[0]) + + return ("default", None) + + +def _make_size_node(key: str, kind: str, value: float | int | None) -> KdlNode | None: + if kind == "default" or value is None: + return None + if kind not in {"proportion", "fixed"}: + raise ValueError(f"Unsupported window size kind: {kind}") + + node = KdlNode(key) + if kind == "proportion": + node.children.append(KdlNode("proportion", args=[round(float(value), 5)])) + else: + node.children.append(KdlNode("fixed", args=[int(value)])) + return node + + +def _rule_summary(rule: KdlNode) -> tuple[str, str]: + """Return (title, subtitle) for a window-rule row.""" + matches = rule.get_children("match") + if not matches: + title = "Global Rule" + else: + parts = [] + for m in matches: + for k, v in m.props.items(): + parts.append(f"{k}: {v}") + for a in m.args: + parts.append(str(a)) + title = " • ".join(parts) if parts else "(any)" + + badges = [] + for c in rule.children: + if c.name == "match": + continue + if c.name == "opacity" and c.args: + badges.append(f"opacity {c.args[0]}") + elif c.name == "background-effect": + badges.append("blur") + elif c.name == "open-floating": + badges.append("floating") + elif c.name == "open-maximized": + badges.append("maximized") + elif c.name == "open-fullscreen": + badges.append("fullscreen") + elif c.name in ("clip-to-geometry", "geometry-corner-radius"): + pass # skip noisy ones + else: + badges.append(c.name.replace("-", " ")) + + subtitle = ", ".join(badges[:5]) if badges else "no actions" + return GLib.markup_escape_text(title), GLib.markup_escape_text(subtitle) + + +def _layer_rule_summary(rule: KdlNode) -> tuple[str, str]: + match_node = rule.get_child("match") + ns = str(match_node.props.get("namespace", "")) if match_node else "" + title = f"namespace: {ns}" if ns else "(any)" + actions = [c.name.replace("-", " ") for c in rule.children if c.name != "match"] + subtitle = ", ".join(actions) if actions else "no actions" + return GLib.markup_escape_text(title), GLib.markup_escape_text(subtitle) + + +# ── Page ───────────────────────────────────────────────────────────────────── + + +class WindowRulesPage(BasePage): + def build(self) -> Gtk.Widget: + tb, header, _, content = self._make_toolbar_page("Window Rules") + self._content = content + + add_win_btn = Gtk.Button(label="Add Window Rule") + add_win_btn.add_css_class("flat") + add_win_btn.set_tooltip_text("Add a new window rule") + add_win_btn.connect("clicked", self._on_add) + header.pack_end(add_win_btn) + + add_layer_btn = Gtk.Button(label="Add Layer Rule") + add_layer_btn.add_css_class("flat") + add_layer_btn.set_tooltip_text("Add a new layer-shell rule") + add_layer_btn.connect("clicked", self._on_add_layer) + header.pack_end(add_layer_btn) + + self._rules_grp = Adw.PreferencesGroup(title="Window Rules") + content.append(self._rules_grp) + + self._layer_rules_grp = Adw.PreferencesGroup( + title="Layer Rules", + description="Rules for layer-shell surfaces (bars, overlays, wallpapers…)", + ) + content.append(self._layer_rules_grp) + + self.refresh() + return tb + + def refresh(self): + self._rebuild() + self._rebuild_layer() + + # ── Window rules ───────────────────────────────────────────────────────── + + def _get_rules(self) -> list[KdlNode]: + return [n for n in self._nodes if n.name == "window-rule"] + + def _rebuild(self): + parent = self._rules_grp.get_parent() + if parent is None: + return + rules = self._get_rules() + new_grp = Adw.PreferencesGroup( + title="Window Rules", + description=f"{len(rules)} rule(s) — click a row to edit", + ) + for i, rule in enumerate(rules): + new_grp.add(self._make_rule_row(rule, i)) + parent.remove(self._rules_grp) + parent.append(new_grp) + self._rules_grp = new_grp + + def _make_rule_row(self, rule: KdlNode, idx: int) -> Adw.ActionRow: + title, subtitle = _rule_summary(rule) + row = Adw.ActionRow(title=title, subtitle=subtitle) + row.set_activatable(True) + row.set_subtitle_lines(1) + row.add_css_class("monospace") + + # visual badge for blur / opacity + has_blur = rule.get_child("background-effect") is not None + op_node = rule.get_child("opacity") + if has_blur: + lbl = Gtk.Label(label="blur") + lbl.add_css_class("tag") + lbl.add_css_class("accent") + lbl.set_valign(Gtk.Align.CENTER) + row.add_suffix(lbl) + if op_node and op_node.args: + lbl2 = Gtk.Label(label=f"α {op_node.args[0]}") + lbl2.add_css_class("tag") + lbl2.set_valign(Gtk.Align.CENTER) + row.add_suffix(lbl2) + + del_btn = Gtk.Button(icon_name="user-trash-symbolic") + del_btn.set_valign(Gtk.Align.CENTER) + del_btn.add_css_class("flat") + del_btn.add_css_class("error") + del_btn.set_tooltip_text("Delete rule") + del_btn.connect("clicked", lambda *_, i=idx: self._on_delete(i)) + row.add_suffix(del_btn) + + row.connect("activated", lambda *_, i=idx: self._on_edit(i)) + return row + + def _on_add(self, *_): + self._show_rule_dialog(None, -1) + + def _on_edit(self, idx: int): + rules = self._get_rules() + if 0 <= idx < len(rules): + self._show_rule_dialog(rules[idx], idx) + + def _on_delete(self, idx: int): + rules = self._get_rules() + if not (0 <= idx < len(rules)): + return + removed = rules[idx] + self._nodes.remove(removed) + self._commit("remove window rule") + self._rebuild() + + # show a quick-undo toast + t = Adw.Toast(title="Window rule deleted", button_label="Undo", timeout=5) + t.connect("button-clicked", lambda *_: self._win._do_undo()) + self._win._toast_overlay.add_toast(t) + + def _add_floating_position_controls( + self, group: Adw.PreferencesGroup, rule: KdlNode | None + ) -> dict[str, Gtk.Widget | str]: + enabled, x, y, relative_to = _floating_position_setting(rule) + + enabled_row = Adw.SwitchRow( + title="Default Floating Position", + subtitle="Set the initial position for matching floating windows", + ) + enabled_row.set_active(enabled) + group.add(enabled_row) + + location_model = Gtk.StringList.new(FLOATING_POSITION_LOCATION_LABELS) + location_row = Adw.ComboRow(title="Location", model=location_model) + location_row.set_selected(_floating_position_location_index(x, y, relative_to)) + group.add(location_row) + + x_adj = Gtk.Adjustment( + value=x, + lower=-7680, + upper=7680, + step_increment=10, + page_increment=100, + ) + x_row = Adw.SpinRow( + title=FLOATING_POSITION_CUSTOM_FIELD_LABELS[0], + adjustment=x_adj, + digits=0, + ) + group.add(x_row) + + y_adj = Gtk.Adjustment( + value=y, + lower=-7680, + upper=7680, + step_increment=10, + page_increment=100, + ) + y_row = Adw.SpinRow( + title=FLOATING_POSITION_CUSTOM_FIELD_LABELS[1], + adjustment=y_adj, + digits=0, + ) + group.add(y_row) + + def _update_visibility(*_): + active = enabled_row.get_active() + custom = location_row.get_selected() == CUSTOM_FLOATING_POSITION_INDEX + location_row.set_visible(active) + x_row.set_visible(active and custom) + y_row.set_visible(active and custom) + + enabled_row.connect("notify::active", _update_visibility) + location_row.connect("notify::selected", _update_visibility) + _update_visibility() + + custom_relative_to = ( + relative_to + if location_row.get_selected() == CUSTOM_FLOATING_POSITION_INDEX + else CUSTOM_FLOATING_POSITION_RELATIVE_TO + ) + return { + "enabled": enabled_row, + "location": location_row, + "x": x_row, + "y": y_row, + "custom_relative_to": custom_relative_to, + } + + def _floating_position_node_from_controls( + self, controls: dict[str, Gtk.Widget | str] + ) -> KdlNode | None: + enabled_row = controls["enabled"] + enabled = ( + enabled_row.get_active() + if isinstance(enabled_row, Adw.SwitchRow) + else False + ) + location_row = controls["location"] + selected = ( + location_row.get_selected() + if isinstance(location_row, Adw.ComboRow) + else CUSTOM_FLOATING_POSITION_INDEX + ) + if selected < CUSTOM_FLOATING_POSITION_INDEX: + _, relative_to = FLOATING_POSITION_PRESETS[selected] + return _make_floating_position_node(enabled, 0, 0, relative_to) + else: + custom_relative_to = controls.get("custom_relative_to") + relative_to = ( + custom_relative_to + if isinstance(custom_relative_to, str) + else CUSTOM_FLOATING_POSITION_RELATIVE_TO + ) + x_row = controls["x"] + y_row = controls["y"] + x = int(x_row.get_value()) if isinstance(x_row, Adw.SpinRow) else 0 + y = int(y_row.get_value()) if isinstance(y_row, Adw.SpinRow) else 0 + return _make_floating_position_node(enabled, x, y, relative_to) + + def _size_mode_index(self, kind: str, value: float | int | None) -> int: + if kind == "fixed": + return FIXED_SIZE_INDEX + if kind == "proportion" and value is not None: + for i, (_, preset) in enumerate(SIZE_PERCENT_PRESETS): + if abs(float(value) - preset) < 0.00001: + return i + return CUSTOM_SIZE_INDEX + return CUSTOM_SIZE_INDEX + + def _add_size_controls( + self, group: Adw.PreferencesGroup, rule: KdlNode | None, key: str + ) -> dict[str, Gtk.Widget]: + cfg = WINDOW_SIZE_CONTROLS[key] + kind, value = _window_size_setting(rule, key) + title = cfg.title + + override_row = Adw.SwitchRow( + title=f"Override {title}", + subtitle="Off writes no explicit size rule", + ) + override_row.set_active(kind != "default") + group.add(override_row) + + mode_model = Gtk.StringList.new(SIZE_MODE_LABELS) + mode_row = Adw.ComboRow(title=title, model=mode_model) + mode_row.set_selected(self._size_mode_index(kind, value)) + group.add(mode_row) + + custom_value = cfg.initial_percent + if kind == "proportion" and value is not None: + custom_value = round(float(value) * 100.0, 2) + custom_adj = Gtk.Adjustment( + value=custom_value, + lower=1.0, + upper=100.0, + step_increment=1.0, + page_increment=5.0, + ) + custom_row = Adw.SpinRow( + title=f"Custom {title} (%)", adjustment=custom_adj, digits=2 + ) + group.add(custom_row) + + fixed_value = cfg.fixed + if kind == "fixed" and value is not None: + fixed_value = int(value) + fixed_adj = Gtk.Adjustment( + value=fixed_value, + lower=1, + upper=7680, + step_increment=10, + page_increment=100, + ) + fixed_row = Adw.SpinRow( + title=f"Fixed {title} (px)", adjustment=fixed_adj, digits=0 + ) + group.add(fixed_row) + + def _update_visibility(*_): + enabled = override_row.get_active() + selected = mode_row.get_selected() + mode_row.set_visible(enabled) + custom_row.set_visible(enabled and selected == CUSTOM_SIZE_INDEX) + fixed_row.set_visible(enabled and selected == FIXED_SIZE_INDEX) + + override_row.connect("notify::active", _update_visibility) + mode_row.connect("notify::selected", _update_visibility) + _update_visibility() + + return { + "override": override_row, + "mode": mode_row, + "custom": custom_row, + "fixed": fixed_row, + } + + def _size_node_from_controls( + self, key: str, controls: dict[str, Gtk.Widget] + ) -> KdlNode | None: + override_row = controls["override"] + if isinstance(override_row, Adw.SwitchRow) and not override_row.get_active(): + return None + + mode_row = controls["mode"] + selected = mode_row.get_selected() if isinstance(mode_row, Adw.ComboRow) else 0 + if selected == FIXED_SIZE_INDEX: + fixed_row = controls["fixed"] + value = fixed_row.get_value() if isinstance(fixed_row, Adw.SpinRow) else 0 + return _make_size_node(key, "fixed", int(value)) + if selected == CUSTOM_SIZE_INDEX: + custom_row = controls["custom"] + value = ( + custom_row.get_value() / 100.0 + if isinstance(custom_row, Adw.SpinRow) + else 0 + ) + return _make_size_node(key, "proportion", value) + + _, value = SIZE_PERCENT_PRESETS[selected] + return _make_size_node(key, "proportion", value) + + def _show_rule_dialog(self, rule: KdlNode | None, rule_idx: int): + dialog = Adw.Dialog(title="Window Rule") + dialog.set_content_width(520) + dialog.set_content_height(680) + + toolbar_view = Adw.ToolbarView() + hdr = Adw.HeaderBar() + title_lbl = "Edit Window Rule" if rule else "New Window Rule" + hdr.set_title_widget(Adw.WindowTitle(title=title_lbl)) + toolbar_view.add_top_bar(hdr) + + scroll = Gtk.ScrolledWindow() + scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) + scroll.set_vexpand(True) + + prefs = Adw.PreferencesPage() + + # ── Match criteria ──────────────────────────────────────────────── + match_grp = Adw.PreferencesGroup( + title="Match Criteria", + description="Leave fields empty to match any window", + ) + match_node = rule.get_child("match") if rule else None + + app_id_row = Adw.EntryRow(title="App ID (regex, e.g. ^kitty$)") + app_id_row.set_text( + str(match_node.props.get("app-id", "")) if match_node else "" + ) + match_grp.add(app_id_row) + + title_row = Adw.EntryRow(title="Window Title (regex)") + title_row.set_text(str(match_node.props.get("title", "")) if match_node else "") + match_grp.add(title_row) + + bool_match_rows: dict[str, Adw.SwitchRow] = {} + for key, label in BOOL_MATCH_LABELS.items(): + sr = Adw.SwitchRow(title=label) + val = match_node.props.get(key, False) if match_node else False + sr.set_active(bool(val)) + match_grp.add(sr) + bool_match_rows[key] = sr + + prefs.add(match_grp) + + # ── Visibility & layout ─────────────────────────────────────────── + layout_grp = Adw.PreferencesGroup( + title="Layout & Visibility", + description="Window-size overrides apply when a matching window opens.", + ) + + size_controls = { + key: self._add_size_controls(layout_grp, rule, key) + for key in WINDOW_SIZE_CONTROLS + } + + bool_rows: dict[str, Adw.SwitchRow] = {} + for key, label in BOOL_ACTION_LABELS.items(): + sr = Adw.SwitchRow(title=label) + sr.set_active(_bool_action_active(rule, key)) + layout_grp.add(sr) + bool_rows[key] = sr + + floating_position_controls = self._add_floating_position_controls( + layout_grp, rule + ) + + prefs.add(layout_grp) + + # ── Visual effects ──────────────────────────────────────────────── + fx_grp = Adw.PreferencesGroup(title="Visual Effects") + + op_val = 0.0 + if rule: + op_node = rule.get_child("opacity") + if op_node and op_node.args: + op_val = float(op_node.args[0]) + op_adj = Gtk.Adjustment(value=op_val, lower=0.0, upper=1.0, step_increment=0.05) + op_row = Adw.SpinRow( + title="Opacity (0 = unset, 1 = fully opaque)", adjustment=op_adj, digits=2 + ) + fx_grp.add(op_row) + + blur_row = Adw.SwitchRow( + title="Background Blur", + subtitle="Adds background-effect { blur true }", + ) + has_blur = False + if rule: + be = rule.get_child("background-effect") + if be is not None: + blur_child = be.get_child("blur") + has_blur = blur_child is not None and ( + not blur_child.args or blur_child.args[0] is True + ) + blur_row.set_active(has_blur) + fx_grp.add(blur_row) + + prefs.add(fx_grp) + + # ── Numeric dimensions ──────────────────────────────────────────── + dim_grp = Adw.PreferencesGroup(title="Dimensions (0 = unset)") + num_rows: dict[str, Adw.SpinRow] = {} + for key, (label, lo, hi, step, digits) in NUM_ACTION_LABELS.items(): + if key == "opacity": + continue # handled above + cur = 0 + if rule: + cn = rule.get_child(key) + cur = cn.args[0] if cn and cn.args else 0 + adj = Gtk.Adjustment( + value=float(cur), lower=lo, upper=hi, step_increment=step + ) + sr = Adw.SpinRow(title=label, adjustment=adj, digits=digits) + dim_grp.add(sr) + num_rows[key] = sr + + prefs.add(dim_grp) + + # ── Workspace / output ──────────────────────────────────────────── + place_grp = Adw.PreferencesGroup(title="Placement") + str_rows: dict[str, Adw.EntryRow] = {} + for key, label in STR_ACTION_LABELS.items(): + e = Adw.EntryRow(title=label) + if rule: + cn = rule.get_child(key) + e.set_text(str(cn.args[0]) if cn and cn.args else "") + place_grp.add(e) + str_rows[key] = e + + prefs.add(place_grp) + + scroll.set_child(prefs) + toolbar_view.set_content(scroll) + + # ── Save button ─────────────────────────────────────────────────── + btn_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8) + btn_box.set_halign(Gtk.Align.END) + btn_box.set_margin_start(16) + btn_box.set_margin_end(16) + btn_box.set_margin_top(8) + btn_box.set_margin_bottom(16) + + cancel_btn = Gtk.Button(label="Cancel") + cancel_btn.add_css_class("pill") + cancel_btn.connect("clicked", lambda *_: dialog.close()) + btn_box.append(cancel_btn) + + save_btn = Gtk.Button(label="Save Rule") + save_btn.add_css_class("suggested-action") + save_btn.add_css_class("pill") + btn_box.append(save_btn) + + toolbar_view.add_bottom_bar(btn_box) + + def _save(*_): + new_rule = KdlNode("window-rule") + new_rule.leading_trivia = "\n" + + # match node + m = KdlNode("match") + has_match = False + app_id_text = app_id_row.get_text().strip() + if app_id_text: + m.props["app-id"] = KdlRawString(app_id_text) + has_match = True + title_text = title_row.get_text().strip() + if title_text: + m.props["title"] = KdlRawString(title_text) + has_match = True + for key, sr in bool_match_rows.items(): + if sr.get_active(): + m.props[key] = True + has_match = True + if has_match: + new_rule.children.append(m) + + # per-rule window sizing + for key, controls in size_controls.items(): + cn = self._size_node_from_controls(key, controls) + if cn is not None: + new_rule.children.append(cn) + + # floating position + position_node = self._floating_position_node_from_controls( + floating_position_controls + ) + if position_node is not None: + new_rule.children.append(position_node) + + # bool actions + for key, sr in bool_rows.items(): + if sr.get_active(): + new_rule.children.append(_bool_action_node(key)) + + # opacity + op = op_row.get_value() + if op > 0.0: + cn = KdlNode("opacity") + cn.args = [round(op, 2)] + new_rule.children.append(cn) + + # blur + if blur_row.get_active(): + be = KdlNode("background-effect") + be.children.append(KdlNode("blur", args=[True])) + new_rule.children.append(be) + + # dimensions + for key, sr in num_rows.items(): + v = sr.get_value() + if v > 0: + cn = KdlNode(key) + cn.args = [int(v)] + new_rule.children.append(cn) + + # placement strings + for key, e in str_rows.items(): + v = e.get_text().strip() + if v: + cn = KdlNode(key) + cn.args = [v] + new_rule.children.append(cn) + + rules = self._get_rules() + if rule_idx >= 0 and 0 <= rule_idx < len(rules): + i = self._nodes.index(rules[rule_idx]) + new_rule.source_file = rules[rule_idx].source_file + new_rule.leading_trivia = rules[rule_idx].leading_trivia + self._nodes[i] = new_rule + else: + if rules: + new_rule.source_file = rules[-1].source_file + self._nodes.append(new_rule) + + self._commit("window rule") + self._rebuild() + dialog.close() + + save_btn.connect("clicked", _save) + dialog.set_child(toolbar_view) + dialog.present(self._win) + + # ── Layer rules ─────────────────────────────────────────────────────────── + + def _get_layer_rules(self) -> list[KdlNode]: + return [n for n in self._nodes if n.name == "layer-rule"] + + def _rebuild_layer(self): + parent = self._layer_rules_grp.get_parent() + if parent is None: + return + rules = self._get_layer_rules() + new_grp = Adw.PreferencesGroup( + title="Layer Rules", + description=f"{len(rules)} rule(s) — bars, overlays, wallpapers", + ) + for i, rule in enumerate(rules): + new_grp.add(self._make_layer_rule_row(rule, i)) + parent.remove(self._layer_rules_grp) + parent.append(new_grp) + self._layer_rules_grp = new_grp + + def _make_layer_rule_row(self, rule: KdlNode, idx: int) -> Adw.ActionRow: + title, subtitle = _layer_rule_summary(rule) + row = Adw.ActionRow(title=title, subtitle=subtitle) + row.set_activatable(True) + row.add_css_class("monospace") + + has_blur = rule.get_child("background-effect") is not None + if has_blur: + lbl = Gtk.Label(label="blur") + lbl.add_css_class("tag") + lbl.add_css_class("accent") + lbl.set_valign(Gtk.Align.CENTER) + row.add_suffix(lbl) + + del_btn = Gtk.Button(icon_name="user-trash-symbolic") + del_btn.set_valign(Gtk.Align.CENTER) + del_btn.add_css_class("flat") + del_btn.add_css_class("error") + del_btn.set_tooltip_text("Delete layer rule") + del_btn.connect("clicked", lambda *_, i=idx: self._on_delete_layer(i)) + row.add_suffix(del_btn) + + row.connect("activated", lambda *_, i=idx: self._on_edit_layer(i)) + return row + + def _on_add_layer(self, *_): + self._show_layer_dialog(None, -1) + + def _on_edit_layer(self, idx: int): + rules = self._get_layer_rules() + if 0 <= idx < len(rules): + self._show_layer_dialog(rules[idx], idx) + + def _on_delete_layer(self, idx: int): + rules = self._get_layer_rules() + if not (0 <= idx < len(rules)): + return + self._nodes.remove(rules[idx]) + self._commit("remove layer rule") + self._rebuild_layer() + + t = Adw.Toast(title="Layer rule deleted", button_label="Undo", timeout=5) + t.connect("button-clicked", lambda *_: self._win._do_undo()) + self._win._toast_overlay.add_toast(t) + + def _show_layer_dialog(self, rule: KdlNode | None, idx: int): + dialog = Adw.Dialog(title="Layer Rule") + dialog.set_content_width(460) + + toolbar_view = Adw.ToolbarView() + hdr = Adw.HeaderBar() + hdr.set_title_widget( + Adw.WindowTitle(title="Edit Layer Rule" if rule else "New Layer Rule") + ) + toolbar_view.add_top_bar(hdr) + + prefs = Adw.PreferencesPage() + + match_grp = Adw.PreferencesGroup(title="Match") + match_node = rule.get_child("match") if rule else None + ns_entry = Adw.EntryRow(title="Namespace (regex, e.g. ^waybar$)") + ns_entry.set_text( + str(match_node.props.get("namespace", "")) if match_node else "" + ) + match_grp.add(ns_entry) + prefs.add(match_grp) + + act_grp = Adw.PreferencesGroup(title="Actions") + bool_rows: dict[str, Adw.SwitchRow] = {} + for key, label in LAYER_BOOL_ACTION_LABELS.items(): + sr = Adw.SwitchRow(title=label) + sr.set_active(_bool_action_active(rule, key)) + act_grp.add(sr) + bool_rows[key] = sr + + blur_row = Adw.SwitchRow(title="Background Blur") + has_blur = False + if rule: + be = rule.get_child("background-effect") + if be: + bc = be.get_child("blur") + has_blur = bc is not None and (not bc.args or bc.args[0] is True) + blur_row.set_active(has_blur) + act_grp.add(blur_row) + + op_adj = Gtk.Adjustment(value=1.0, lower=0.0, upper=1.0, step_increment=0.05) + if rule: + op_node = rule.get_child("opacity") + if op_node and op_node.args: + op_adj.set_value(float(op_node.args[0])) + op_row = Adw.SpinRow(title="Opacity (1 = unset)", adjustment=op_adj, digits=2) + act_grp.add(op_row) + + prefs.add(act_grp) + toolbar_view.set_content(prefs) + + btn_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8) + btn_box.set_halign(Gtk.Align.END) + btn_box.set_margin_start(16) + btn_box.set_margin_end(16) + btn_box.set_margin_top(8) + btn_box.set_margin_bottom(16) + + cancel_btn = Gtk.Button(label="Cancel") + cancel_btn.add_css_class("pill") + cancel_btn.connect("clicked", lambda *_: dialog.close()) + btn_box.append(cancel_btn) + + save_btn = Gtk.Button(label="Save Rule") + save_btn.add_css_class("suggested-action") + save_btn.add_css_class("pill") + btn_box.append(save_btn) + + toolbar_view.add_bottom_bar(btn_box) + + def _save(*_): + new_rule = KdlNode("layer-rule") + new_rule.leading_trivia = "\n" + ns = ns_entry.get_text().strip() + if ns: + m = KdlNode("match") + m.props["namespace"] = KdlRawString(ns) + new_rule.children.append(m) + for key, sr in bool_rows.items(): + if sr.get_active(): + new_rule.children.append(_bool_action_node(key)) + if blur_row.get_active(): + be = KdlNode("background-effect") + be.children.append(KdlNode("blur", args=[True])) + new_rule.children.append(be) + op = op_row.get_value() + if op < 1.0: + op_node = KdlNode("opacity") + op_node.args = [round(op, 2)] + new_rule.children.append(op_node) + + rules = self._get_layer_rules() + if idx >= 0 and 0 <= idx < len(rules): + i = self._nodes.index(rules[idx]) + new_rule.source_file = rules[idx].source_file + new_rule.leading_trivia = rules[idx].leading_trivia + self._nodes[i] = new_rule + else: + if rules: + new_rule.source_file = rules[-1].source_file + elif self._get_rules(): + new_rule.source_file = self._get_rules()[-1].source_file + self._nodes.append(new_rule) + self._commit("layer rule") + self._rebuild_layer() + dialog.close() + + save_btn.connect("clicked", _save) + dialog.set_child(toolbar_view) + dialog.present(self._win) diff --git a/nirimod/pages/workspaces.py b/nirimod/pages/workspaces.py new file mode 100644 index 0000000..0c2f713 --- /dev/null +++ b/nirimod/pages/workspaces.py @@ -0,0 +1,155 @@ +"""Workspaces page.""" + +from __future__ import annotations + + +import gi + +gi.require_version("Gtk", "4.0") +gi.require_version("Adw", "1") +from gi.repository import Adw, Gtk + +from nirimod.kdl_parser import KdlNode, set_child_arg +from nirimod import niri_ipc +from nirimod.pages.base import BasePage + + +class WorkspacesPage(BasePage): + def build(self) -> Gtk.Widget: + tb, header, _, content = self._make_toolbar_page("Workspaces") + self._content = content + + add_btn = Gtk.Button(icon_name="list-add-symbolic") + add_btn.add_css_class("flat") + add_btn.connect("clicked", self._on_add) + header.pack_end(add_btn) + + self._grp = Adw.PreferencesGroup( + title="Named Workspaces", + description="Named workspaces open immediately at niri startup", + ) + content.append(self._grp) + self.refresh() + return tb + + def refresh(self): + self._rebuild() + + def _get_ws_nodes(self) -> list[KdlNode]: + return [n for n in self._nodes if n.name == "workspace"] + + def _rebuild(self): + parent = self._grp.get_parent() + if parent is None: + return + + def _on_outputs(outputs_data): + ws_nodes = self._get_ws_nodes() + outputs = [o.get("name", "") for o in outputs_data] + output_model = Gtk.StringList.new(["(any)"] + outputs) + + new_grp = Adw.PreferencesGroup( + title="Named Workspaces", description=f"{len(ws_nodes)} workspace(s)" + ) + for i, ws in enumerate(ws_nodes): + row = self._make_ws_row(ws, i, outputs, output_model) + new_grp.add(row) + parent.remove(self._grp) + parent.append(new_grp) + self._grp = new_grp + + niri_ipc.get_outputs(_on_outputs) + + def _make_ws_row( + self, ws: KdlNode, idx: int, outputs: list[str], output_model: Gtk.StringList + ) -> Adw.ExpanderRow: + name = ws.args[0] if ws.args else f"workspace-{idx + 1}" + assigned_out = ws.child_arg("open-on-output") or "" + + exp = Adw.ExpanderRow(title=name) + + name_row = Adw.EntryRow(title="Name") + name_row.set_text(str(name)) + name_row.set_show_apply_button(True) + name_row.connect("apply", lambda r, i=idx: self._rename_ws(i, r.get_text())) + exp.add_row(name_row) + + out_row = Adw.ComboRow(title="Open on Output") + out_list = ["(any)"] + outputs + out_row.set_model(Gtk.StringList.new(out_list)) + if assigned_out in outputs: + out_row.set_selected(out_list.index(assigned_out)) + out_row.connect( + "notify::selected", + lambda r, _, i=idx, ol=out_list: self._set_ws_output( + i, ol[r.get_selected()] + ), + ) + exp.add_row(out_row) + + del_btn = Gtk.Button(icon_name="user-trash-symbolic") + del_btn.add_css_class("flat") + del_btn.add_css_class("error") + del_btn.set_valign(Gtk.Align.CENTER) + del_btn.connect("clicked", lambda *_, i=idx: self._on_delete(i)) + exp.add_suffix(del_btn) + + return exp + + def _on_add(self, *_): + dialog = Adw.AlertDialog( + heading="Add Workspace", body="Enter a name for the new workspace." + ) + entry = Adw.EntryRow(title="Workspace Name") + grp = Adw.PreferencesGroup() + grp.add(entry) + dialog.set_extra_child(grp) + dialog.add_response("cancel", "Cancel") + dialog.add_response("add", "Add") + dialog.set_response_appearance("add", Adw.ResponseAppearance.SUGGESTED) + + def _on_resp(d, r): + if r != "add": + return + name = entry.get_text().strip() + if not name: + return + node = KdlNode("workspace", args=[name]) + ws_nodes = self._get_ws_nodes() + if ws_nodes: + last_idx = self._nodes.index(ws_nodes[-1]) + self._nodes.insert(last_idx + 1, node) + else: + # If no workspaces, insert at the top + self._nodes.insert(0, node) + self._commit("add workspace") + self._rebuild() + + dialog.connect("response", _on_resp) + dialog.present(self._win) + + def _on_delete(self, idx: int): + ws_nodes = self._get_ws_nodes() + if 0 <= idx < len(ws_nodes): + self._nodes.remove(ws_nodes[idx]) + self._commit("remove workspace") + self._rebuild() + + def _rename_ws(self, idx: int, name: str): + ws_nodes = self._get_ws_nodes() + if 0 <= idx < len(ws_nodes) and name.strip(): + ws_nodes[idx].args = [name.strip()] + self._commit("rename workspace") + self._rebuild() + + def _set_ws_output(self, idx: int, output: str): + ws_nodes = self._get_ws_nodes() + if 0 <= idx < len(ws_nodes): + ws = ws_nodes[idx] + if output and output != "(any)": + set_child_arg(ws, "open-on-output", output) + else: + from nirimod.kdl_parser import remove_child + + remove_child(ws, "open-on-output") + self._commit("workspace output") diff --git a/nirimod/profiles.py b/nirimod/profiles.py new file mode 100644 index 0000000..d28d011 --- /dev/null +++ b/nirimod/profiles.py @@ -0,0 +1,72 @@ +"""Named config profiles: save/load Niri config snapshots.""" + +from __future__ import annotations + +import shutil +from pathlib import Path + +from nirimod import kdl_parser + + +def list_profiles() -> list[str]: + if not kdl_parser.PROFILES_DIR.exists(): + return [] + names = [p.stem for p in kdl_parser.PROFILES_DIR.glob("*.kdl")] + names += [p.name for p in kdl_parser.PROFILES_DIR.iterdir() if p.is_dir()] + return sorted(names) + + +def save_profile(name: str, source_files: set[Path] | None = None) -> None: + kdl_parser.PROFILES_DIR.mkdir(parents=True, exist_ok=True) + + if source_files and len(source_files) > 1: + dest_dir = kdl_parser.PROFILES_DIR / name + dest_dir.mkdir(exist_ok=True) + for p in source_files: + if p.exists(): + try: + rel = p.relative_to(kdl_parser.NIRI_CONFIG.parent) + dest = dest_dir / rel + dest.parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(p, dest) + except ValueError: + shutil.copy2(p, dest_dir / p.name) + else: + if kdl_parser.NIRI_CONFIG.exists(): + shutil.copy2(kdl_parser.NIRI_CONFIG, kdl_parser.PROFILES_DIR / f"{name}.kdl") + + +def load_profile(name: str) -> bool: + dir_profile = kdl_parser.PROFILES_DIR / name + if dir_profile.is_dir(): + def _restore(src_dir, dest_dir): + for f in src_dir.iterdir(): + if f.is_file(): + rel = f.relative_to(dir_profile) + target = dest_dir / rel + target.parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(f, target) + elif f.is_dir(): + _restore(f, dest_dir) + + _restore(dir_profile, kdl_parser.NIRI_CONFIG.parent) + return True + + src = kdl_parser.PROFILES_DIR / f"{name}.kdl" + if not src.exists(): + return False + kdl_parser.save_niri_config(kdl_parser.parse_kdl(src.read_text())) + return True + + +def delete_profile(name: str) -> bool: + dir_profile = kdl_parser.PROFILES_DIR / name + if dir_profile.is_dir(): + shutil.rmtree(dir_profile) + return True + p = kdl_parser.PROFILES_DIR / f"{name}.kdl" + if p.exists(): + p.unlink() + return True + return False + diff --git a/nirimod/state.py b/nirimod/state.py new file mode 100644 index 0000000..f62484f --- /dev/null +++ b/nirimod/state.py @@ -0,0 +1,149 @@ + + +from __future__ import annotations + +from dataclasses import dataclass +from pathlib import Path +from typing import TYPE_CHECKING + +from nirimod.kdl_parser import ( + NIRI_CONFIG, + KdlNode, + load_niri_config_multi, + parse_kdl, + save_niri_config, + save_niri_config_multi, + write_kdl, +) +from nirimod.undo import UndoEntry, UndoManager + +if TYPE_CHECKING: + pass + + +@dataclass +class RuntimeInfo: + + niri_running: bool = False + has_touchpad: bool = False + + +class AppState: + + def __init__(self) -> None: + self._nodes: list[KdlNode] = [] + self._saved_kdl: str = "" + self._undo: UndoManager = UndoManager() + self._runtime: RuntimeInfo = RuntimeInfo() + self._dirty: bool = False + self._include_slots: list[tuple[KdlNode, Path]] = [] + self._source_files: set[Path] = set() + + def load(self) -> None: + from nirimod import niri_ipc + + self._runtime = RuntimeInfo( + niri_running=niri_ipc.is_niri_running(), + has_touchpad=niri_ipc.has_touchpad(), + ) + self._nodes, self._include_slots = load_niri_config_multi() + self._source_files = {NIRI_CONFIG} + for _, path in self._include_slots: + if path.exists(): + self._source_files.add(path) + self._saved_kdl = write_kdl(self._nodes) if self._nodes else "" + self._dirty = False + + @property + def nodes(self) -> list[KdlNode]: + return self._nodes + + @nodes.setter + def nodes(self, value: list[KdlNode]) -> None: + self._nodes = value + + @property + def saved_kdl(self) -> str: + return self._saved_kdl + + @property + def source_files(self) -> set[Path]: + return self._source_files + + @property + def include_slots(self) -> list[tuple[KdlNode, Path]]: + return self._include_slots + + @property + def is_multi_file(self) -> bool: + return bool(self._include_slots) + + @property + def niri_running(self) -> bool: + return self._runtime.niri_running + + @property + def has_touchpad(self) -> bool: + return self._runtime.has_touchpad + + @property + def is_dirty(self) -> bool: + return self._dirty + + def mark_dirty(self) -> None: + self._dirty = True + + def mark_clean(self) -> None: + self._dirty = False + + @property + def undo(self) -> UndoManager: + return self._undo + + def push_undo(self, description: str, before: str, after: str) -> None: + self._undo.push(UndoEntry(description, before, after)) + + def apply_undo(self) -> UndoEntry | None: + entry = self._undo.pop_undo() + if entry is None: + return None + self._nodes = parse_kdl(entry.snapshot_before) + self._dirty = entry.snapshot_before != self._saved_kdl + return entry + + def apply_redo(self) -> UndoEntry | None: + entry = self._undo.pop_redo() + if entry is None: + return None + self._nodes = parse_kdl(entry.snapshot_after) + self._dirty = entry.snapshot_after != self._saved_kdl + return entry + + def discard(self) -> None: + self._nodes = parse_kdl(self._saved_kdl) if self._saved_kdl else [] + self._undo.clear() + self._dirty = False + + def commit_save(self, new_kdl: str) -> None: + self._saved_kdl = new_kdl + self._undo.clear() + self._dirty = False + + def reload_from_disk(self) -> None: + self._nodes, self._include_slots = load_niri_config_multi() + self._source_files = {NIRI_CONFIG} + for _, path in self._include_slots: + if path.exists(): + self._source_files.add(path) + + def write_current_kdl(self) -> str: + return write_kdl(self._nodes) + + def write_to_path(self, path: Path | None = None) -> None: + if path is not None: + # Explicit path (e.g. validation temp file) — single file write + save_niri_config(self._nodes, path=path) + elif self._include_slots: + save_niri_config_multi(self._nodes, self._include_slots) + else: + save_niri_config(self._nodes) diff --git a/nirimod/theme.py b/nirimod/theme.py new file mode 100644 index 0000000..f5af081 --- /dev/null +++ b/nirimod/theme.py @@ -0,0 +1,325 @@ +"""CSS theme definitions for NiriMod.""" + +CSS = """ +/* --- Nirimod -- Purple Theme --- */ + +/* --- Accent --- */ +@define-color nm_accent #9b6dff; +@define-color nm_accent_mid #7c3aed; +@define-color nm_accent_dim rgba(155, 109, 255, 0.13); +@define-color nm_accent_hover rgba(155, 109, 255, 0.20); +@define-color nm_accent_border rgba(155, 109, 255, 0.28); + +/* --- Surfaces --- */ +@define-color window_bg_color #111114; +@define-color window_fg_color #e8e8ed; +@define-color view_bg_color #18181c; +@define-color view_fg_color #e8e8ed; +@define-color headerbar_bg_color #111114; +@define-color card_bg_color #1e1e24; +@define-color card_fg_color #e8e8ed; +@define-color popover_bg_color #1e1e24; +@define-color popover_fg_color #e8e8ed; +@define-color dialog_bg_color #18181c; +@define-color dialog_fg_color #e8e8ed; + +/* --- Borders --- */ +@define-color nm_border rgba(255, 255, 255, 0.07); +@define-color nm_border_strong rgba(255, 255, 255, 0.12); + +/* --- Window --- */ +window { + background-color: @window_bg_color; + color: @window_fg_color; +} + +/* --- Header Bars --- */ +headerbar, +.nm-sidebar-bg { + background-color: @window_bg_color; + background-image: none; + box-shadow: none; + border-bottom: 1px solid @nm_border; + color: @window_fg_color; +} + +/* --- Sidebar --- */ +.navigation-sidebar { + background-color: transparent; + border-right: 1px solid @nm_border; +} + +.nm-sidebar-listbox { + background: transparent; + border: none; +} + +.nm-sidebar-listbox row { + border-radius: 7px; + margin: 1px 4px; + padding: 5px 8px; + transition: background 130ms ease; + color: @window_fg_color; +} + +.nm-sidebar-listbox row:hover { + background: rgba(255, 255, 255, 0.045); +} + +.nm-sidebar-listbox row:selected { + background: @nm_accent_dim; + color: @nm_accent; +} + +.nm-sidebar-listbox row:selected image, +.nm-sidebar-listbox row:selected label { + color: @nm_accent; +} + +/* --- Section Labels --- */ +.nm-sidebar-section-label { + font-size: 10px; + font-weight: 700; + letter-spacing: 0.08em; + color: rgba(255, 255, 255, 0.30); +} + +/* --- Search --- */ +.nm-search-entry { + color: @window_fg_color; + background-color: @card_bg_color; + border: 1px solid @nm_border; + border-radius: 8px; +} + +.nm-search-entry > box { color: @window_fg_color; } +.nm-search-entry text { color: @window_fg_color; } + +.nm-search-results { + background: transparent; + border: none; +} + +.nm-search-results row { + padding: 8px 12px; + border-radius: 7px; + margin: 2px 4px; + transition: background 110ms ease; +} + +.nm-search-results row:hover { + background: @nm_accent_dim; +} + +/* --- Content Cards --- */ +.nm-card, +preferencesgroup > box { + background-color: @card_bg_color; + border: 1px solid @nm_border; + border-radius: 12px; + padding: 4px; +} + +row { + border-radius: 7px; + transition: background 110ms ease; +} + +row:hover { + background: rgba(255, 255, 255, 0.025); +} + +/* --- Unsaved Changes Bar --- */ +.nm-dirty-bar { + background: rgba(155, 109, 255, 0.07); + border-top: 1px solid rgba(155, 109, 255, 0.18); + padding: 8px 20px; +} + +/* --- Niri Banner --- */ +.nm-niri-banner { + background: rgba(180, 110, 0, 0.10); + color: rgba(240, 180, 50, 0.90); + padding: 6px 16px; + font-size: 13px; + border-bottom: 1px solid rgba(180, 110, 0, 0.18); +} + +/* --- Badges & Status --- */ +.nm-badge { + background: @nm_accent; + color: #111114; + border-radius: 12px; + font-size: 10px; + font-weight: 700; + padding: 1px 7px; + min-width: 16px; +} + +/* --- Inline Tag Chips --- */ +.tag { + background: rgba(255, 255, 255, 0.06); + color: @window_fg_color; + border: 1px solid @nm_border_strong; + border-radius: 5px; + font-size: 11px; + font-weight: 600; + padding: 1px 7px; +} + +.tag.accent { + background: @nm_accent_dim; + color: @nm_accent; + border-color: @nm_accent_border; +} + +/* --- Buttons --- */ +button.suggested-action { + border-radius: 9px; + font-weight: 600; + background: @nm_accent_mid; +} + +/* --- Toasts --- */ +toast { + background-color: @card_bg_color; + color: @card_fg_color; + border: 1px solid @nm_accent_border; + border-radius: 20px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.45); + margin-bottom: 20px; +} + +toast label { font-weight: 500; } + +/* --- Code Editor --- */ +.code-editor { + background-color: #0d0d10; + color: #e8e8ed; + border: 1px solid @nm_border; + border-radius: 10px; +} + +/* --- Keyboard Visualizer --- */ +.nm-kb-action-panel { + background-color: @card_bg_color; + border: 1px solid @nm_border; + border-radius: 12px; + padding: 4px; +} + +.nm-kb-key-id-label { + font-size: 20px; + font-weight: 700; + color: @window_fg_color; +} + +.nm-kb-swatch { + min-width: 12px; + min-height: 12px; + border-radius: 3px; +} + +/* --- Keycaps --- */ +.nm-keycap-main, .nm-keycap-mod { + background-color: @nm_accent_dim; + border: 1px solid @nm_accent_border; + border-radius: 5px; + padding: 2px 8px; + font-size: 12px; + font-weight: 600; + color: @nm_accent; + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.3); +} + +.nm-keycap-main { + background-color: rgba(155, 109, 255, 0.22); + border-color: rgba(155, 109, 255, 0.45); + color: rgba(210, 190, 255, 1.0); + font-weight: 700; +} + +.nm-keycap-mod { opacity: 0.80; } + +.nm-keycap-purple { + background: @nm_accent_dim; + color: @nm_accent; + border: 1px solid @nm_accent_border; + border-radius: 5px; + padding: 2px 8px; + font-weight: 600; + font-size: 12px; +} + +/* --- Pulse Highlight (search) --- */ +@keyframes pulse-highlight { + 0% { background-color: transparent; } + 18% { background-color: rgba(155, 109, 255, 0.28); } + 100% { background-color: transparent; } +} + +.nm-pulse-highlight { + animation-name: pulse-highlight; + animation-duration: 1.4s; + animation-timing-function: ease-out; +} + +/* --- Animations Page --- */ +.nm-anim-banner { + background: @nm_accent_dim; + border: 1px solid @nm_accent_border; + border-radius: 10px; + padding: 10px 16px; + color: @nm_accent; +} + +.nm-anim-banner button { + background: rgba(155, 109, 255, 0.15); + border: 1px solid @nm_accent_border; + color: @nm_accent; + font-weight: 600; + border-radius: 8px; + padding: 4px 14px; +} + +.nm-anim-banner button:hover { + background: @nm_accent_hover; +} + +.nm-preset-icon { + font-size: 18px; + min-width: 28px; +} + +/* --- Bindings Page --- */ +.nm-binding-card { + background: rgba(30, 30, 35, 0.6); + border: 1px solid rgba(255, 255, 255, 0.08); + border-radius: 12px; + padding: 16px; + transition: all 200ms ease; +} +.nm-binding-card:hover { + background: rgba(45, 45, 50, 0.8); + border-color: rgba(147, 51, 234, 0.4); +} +.nm-binding-actions-label { + color: rgba(255, 255, 255, 0.4); + font-weight: 800; + letter-spacing: 0.05em; + font-size: 0.7rem; +} +.nm-binding-action-name { + color: rgba(192, 132, 252, 1.0); + font-weight: 600; + font-size: 1.0rem; +} +.nm-keycap-purple { + background: #581c87; + color: white; + border-radius: 6px; + padding: 2px 8px; + font-weight: bold; + font-size: 0.8rem; +} +""".encode("utf-8") diff --git a/nirimod/undo.py b/nirimod/undo.py new file mode 100644 index 0000000..9541c99 --- /dev/null +++ b/nirimod/undo.py @@ -0,0 +1,61 @@ + + +from __future__ import annotations + +from dataclasses import dataclass + + +@dataclass +class UndoEntry: + description: str + snapshot_before: str + snapshot_after: str + + +class UndoManager: + def __init__(self, max_depth: int = 100): + self._stack: list[UndoEntry] = [] + self._redo_stack: list[UndoEntry] = [] + self._max = max_depth + + def push(self, entry: UndoEntry) -> None: + self._stack.append(entry) + if len(self._stack) > self._max: + self._stack.pop(0) + self._redo_stack.clear() + + @property + def last_snapshot(self) -> str | None: + if self._stack: + return self._stack[-1].snapshot_after + return None + + @property + def last_description(self) -> str | None: + if self._stack: + return self._stack[-1].description + return None + + def pop_undo(self) -> UndoEntry | None: + if not self._stack: + return None + entry = self._stack.pop() + self._redo_stack.append(entry) + return entry + + def pop_redo(self) -> UndoEntry | None: + if not self._redo_stack: + return None + entry = self._redo_stack.pop() + self._stack.append(entry) + return entry + + def can_undo(self) -> bool: + return bool(self._stack) + + def can_redo(self) -> bool: + return bool(self._redo_stack) + + def clear(self) -> None: + self._stack.clear() + self._redo_stack.clear() diff --git a/nirimod/updater.py b/nirimod/updater.py new file mode 100644 index 0000000..edb1827 --- /dev/null +++ b/nirimod/updater.py @@ -0,0 +1,135 @@ +import json +import os +import shlex +import shutil +import subprocess +import tempfile +import threading +import urllib.request +import stat + +API_URL = "https://api.github.com/repos/srinivasr/nirimod/commits/main" +INSTALL_DIR = os.path.expanduser("~/.local/share/nirimod") +FALLBACK_TERMINALS = [ + "xdg-terminal-exec", + "gnome-terminal", + "kgx", # GNOME Console + "kitty", + "ghostty", + "alacritty", + "konsole", + "foot", + "xterm", +] + + +def check_for_updates(callback): + + def _do_check(): + try: + from gi.repository import GLib + + if not os.path.isdir(os.path.join(INSTALL_DIR, ".git")): + GLib.idle_add(callback, None, None) + return + + local_hash = subprocess.check_output( + ["git", "rev-parse", "HEAD"], + cwd=INSTALL_DIR, + text=True, + ).strip() + + req = urllib.request.Request( + API_URL, headers={"User-Agent": "NiriMod-Updater"} + ) + with urllib.request.urlopen(req, timeout=5) as resp: + data = json.loads(resp.read().decode("utf-8")) + remote_hash = data.get("sha") + commit_msg = data.get("commit", {}).get( + "message", "New update available" + ) + + if _update_available(local_hash, remote_hash, INSTALL_DIR): + GLib.idle_add(callback, remote_hash, commit_msg) + else: + GLib.idle_add(callback, None, None) + + except Exception as e: + print(f"Update check failed: {e}") + GLib.idle_add(callback, None, None) + + threading.Thread(target=_do_check, daemon=True).start() + + +def _commit_is_ancestor(commit_hash: str, install_dir: str) -> bool: + result = subprocess.run( + ["git", "merge-base", "--is-ancestor", commit_hash, "HEAD"], + cwd=install_dir, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + check=False, + ) + return result.returncode == 0 + + +def _update_available( + local_hash: str, remote_hash: str | None, install_dir: str = INSTALL_DIR +) -> bool: + if not remote_hash or remote_hash == local_hash: + return False + if _commit_is_ancestor(remote_hash, install_dir): + return False + return True + + +def _terminal_candidates(): + terminal = os.environ.get("TERMINAL", "").strip() + if terminal: + yield terminal + yield from FALLBACK_TERMINALS + + +def _build_terminal_command(terminal: str, script_path: str) -> list[str] | None: + try: + parts = shlex.split(terminal) + except ValueError: + return None + + if not parts: + return None + + if os.path.basename(parts[0]) == "xdg-terminal-exec": + return [*parts, script_path] + + if parts[-1] in {"-e", "--execute", "-x"}: + return [*parts, script_path] + + return [*parts, "-e", script_path] + + +def launch_updater_in_terminal(): + + script_content = """#!/usr/bin/env bash +echo "Starting NiriMod update..." +curl -sSL https://raw.githubusercontent.com/srinivasr/nirimod/main/install.sh | bash -s -- --install +echo "" +echo "Update complete! Press Enter to close this window." +read +""" + script_path = os.path.join(tempfile.gettempdir(), "nirimod_update.sh") + with open(script_path, "w") as f: + f.write(script_content) + os.chmod(script_path, stat.S_IRWXU) + + for term in _terminal_candidates(): + command = _build_terminal_command(term, script_path) + if command is None or shutil.which(command[0]) is None: + continue + + try: + subprocess.Popen(command) + return + except Exception: + continue + + print("Could not find a suitable terminal to launch the update.") diff --git a/nirimod/widgets/__init__.py b/nirimod/widgets/__init__.py new file mode 100644 index 0000000..835d5e7 --- /dev/null +++ b/nirimod/widgets/__init__.py @@ -0,0 +1,5 @@ +"""NiriMod custom widgets.""" + +from nirimod.widgets.keyboard_visualizer import KeyboardVisualizer, normalize_key_id + +__all__ = ["KeyboardVisualizer", "normalize_key_id"] diff --git a/nirimod/widgets/keyboard_visualizer.py b/nirimod/widgets/keyboard_visualizer.py new file mode 100644 index 0000000..a67a78a --- /dev/null +++ b/nirimod/widgets/keyboard_visualizer.py @@ -0,0 +1,696 @@ +"""Keyboard visualizer widget — Cairo DrawingArea keyboard map. + +Inspired from omer-biz/visu (Elm/WASM) into pure Python + Cairo. +""" + +from __future__ import annotations + +import math + +try: + import cairo # noqa: F401 + HAS_CAIRO = True +except ImportError: + HAS_CAIRO = False + +import gi + +gi.require_version("Gtk", "4.0") +gi.require_version("Adw", "1") +from gi.repository import Adw, GLib, GObject, Gtk + +from nirimod.xkb_helper import XkbHelper + +KEYBOARD_GEOMETRIES: dict[str, list[list[tuple[str, int]]]] = { + "ANSI": [ + # Row 0 — function row + [("escape", 4), ("", 2), ("f1", 3), ("f2", 3), ("f3", 3), ("f4", 3), ("", 2), ("f5", 3), ("f6", 3), ("f7", 3), ("f8", 3), ("", 2), ("f9", 3), ("f10", 3), ("f11", 3), ("f12", 3), ("", 2), ("print", 4), ("insert", 4), ("delete", 4)], + # Row 1 — number row + [("grave", 4), ("1", 4), ("2", 4), ("3", 4), ("4", 4), ("5", 4), ("6", 4), ("7", 4), ("8", 4), ("9", 4), ("0", 4), ("minus", 4), ("equal", 4), ("backspace", 8)], + # Row 2 — QWERTY + [("tab", 6), ("q", 4), ("w", 4), ("e", 4), ("r", 4), ("t", 4), ("y", 4), ("u", 4), ("i", 4), ("o", 4), ("p", 4), ("bracketleft", 4), ("bracketright", 4), ("backslash", 6)], + # Row 3 — home row + [("capslock", 7), ("a", 4), ("s", 4), ("d", 4), ("f", 4), ("g", 4), ("h", 4), ("j", 4), ("k", 4), ("l", 4), ("semicolon", 4), ("quote", 4), ("return", 9)], + # Row 4 — shift row + [("shiftleft", 7), ("z", 4), ("x", 4), ("c", 4), ("v", 4), ("b", 4), ("n", 4), ("m", 4), ("comma", 4), ("period", 4), ("slash", 4), ("shiftright", 5), ("up", 4), ("", 4)], + # Row 5 — bottom row + [("ctrlleft", 6), ("superleft", 6), ("altleft", 6), ("space", 24), ("altright", 6), ("left", 4), ("down", 4), ("right", 4)], + ], + "ISO": [ + # Row 0 — function row + [("escape", 4), ("", 2), ("f1", 3), ("f2", 3), ("f3", 3), ("f4", 3), ("", 2), ("f5", 3), ("f6", 3), ("f7", 3), ("f8", 3), ("", 2), ("f9", 3), ("f10", 3), ("f11", 3), ("f12", 3), ("", 2), ("print", 4), ("insert", 4), ("delete", 4)], + # Row 1 — number row + [("grave", 4), ("1", 4), ("2", 4), ("3", 4), ("4", 4), ("5", 4), ("6", 4), ("7", 4), ("8", 4), ("9", 4), ("0", 4), ("minus", 4), ("equal", 4), ("backspace", 8)], + # Row 2 — QWERTY + [("tab", 6), ("q", 4), ("w", 4), ("e", 4), ("r", 4), ("t", 4), ("y", 4), ("u", 4), ("i", 4), ("o", 4), ("p", 4), ("bracketleft", 4), ("bracketright", 4), ("return", 6)], + # Row 3 — home row + [("capslock", 7), ("a", 4), ("s", 4), ("d", 4), ("f", 4), ("g", 4), ("h", 4), ("j", 4), ("k", 4), ("l", 4), ("semicolon", 4), ("quote", 4), ("backslash", 4), ("return", 5)], + # Row 4 — shift row + [("shiftleft", 4), ("less", 4), ("z", 4), ("x", 4), ("c", 4), ("v", 4), ("b", 4), ("n", 4), ("m", 4), ("comma", 4), ("period", 4), ("slash", 4), ("shiftright", 4), ("up", 4), ("", 4)], + # Row 5 — bottom row + [("ctrlleft", 6), ("superleft", 6), ("altleft", 6), ("space", 24), ("altright", 6), ("left", 4), ("down", 4), ("right", 4)], + ] +} + +_KID_TO_KEYCODE = { + # Function row + "escape": 1, "f1": 59, "f2": 60, "f3": 61, "f4": 62, "f5": 63, "f6": 64, "f7": 65, "f8": 66, "f9": 67, "f10": 68, "f11": 87, "f12": 88, "print": 99, "insert": 110, "delete": 111, + # Number row + "grave": 41, "1": 2, "2": 3, "3": 4, "4": 5, "5": 6, "6": 7, "7": 8, "8": 9, "9": 10, "0": 11, "minus": 12, "equal": 13, "backspace": 14, + # Row 2 + "tab": 15, "q": 16, "w": 17, "e": 18, "r": 19, "t": 20, "y": 21, "u": 22, "i": 23, "o": 24, "p": 25, "bracketleft": 26, "bracketright": 27, "backslash": 43, + # Row 3 + "capslock": 58, "a": 30, "s": 31, "d": 32, "f": 33, "g": 34, "h": 35, "j": 36, "k": 37, "l": 38, "semicolon": 39, "quote": 40, "return": 28, + # Row 4 + "shiftleft": 42, "less": 94, "z": 44, "x": 45, "c": 46, "v": 47, "b": 48, "n": 49, "m": 50, "comma": 51, "period": 52, "slash": 53, "shiftright": 54, "up": 103, + # Row 5 + "ctrlleft": 29, "superleft": 125, "altleft": 56, "space": 57, "altright": 100, "left": 105, "down": 108, "right": 106 +} + +_STATIC_LABELS = { + "escape": "Esc", "backspace": "Bksp", "tab": "Tab", "return": "Enter", "capslock": "Caps", + "shiftleft": "Shift", "shiftright": "Shift", "ctrlleft": "Ctrl", "superleft": "Super", + "altleft": "Alt", "altright": "Alt", "up": "↑", "down": "↓", "left": "←", "right": "→", "space": "", + "grave": "`", + "f1": "F1", "f2": "F2", "f3": "F3", "f4": "F4", "f5": "F5", "f6": "F6", + "f7": "F7", "f8": "F8", "f9": "F9", "f10": "F10", "f11": "F11", "f12": "F12", + "print": "PrtSc", "insert": "Ins", "delete": "Del", +} + + +_MODIFIER_KEY_IDS = { + "shiftleft", + "shiftright", + "ctrlleft", + "altleft", + "altright", + "superleft", + "capslock", + "tab", + "backspace", + "space", +} + +_KEYSYM_ALIAS: dict[str, str] = { + "return": "return", + "enter": "return", + "kp_enter": "return", + "escape": "escape", + "esc": "escape", + "backspace": "backspace", + "tab": "tab", + "space": "space", + "bracketleft": "bracketleft", + "bracketright": "bracketright", + "minus": "minus", + "equal": "equal", + "period": "period", + "comma": "comma", + "slash": "slash", + "backslash": "backslash", + "semicolon": "semicolon", + "apostrophe": "quote", + "quote": "quote", + "grave": "grave", + "up": "up", + "down": "down", + "left": "left", + "right": "right", + "page_up": "pageup", + "page_down": "pagedown", + "home": "home", + "end": "end", + "print": "print", + "sysrq": "print", + "delete": "delete", + "del": "delete", + "insert": "insert", + "ins": "insert", + "f1": "f1", "f2": "f2", "f3": "f3", "f4": "f4", + "f5": "f5", "f6": "f6", "f7": "f7", "f8": "f8", + "f9": "f9", "f10": "f10", "f11": "f11", "f12": "f12", +} + +for _c in "abcdefghijklmnopqrstuvwxyz0123456789": + _KEYSYM_ALIAS[_c] = _c + + +def normalize_key_id(raw_key: str) -> str: + """Convert a raw keysym (last part of Mod+Shift+X) to a keyboard layout id.""" + k = raw_key.strip().lower() + return _KEYSYM_ALIAS.get(k, k) + + +def _rgb(r: int, g: int, b: int, a: float = 1.0): + return (r / 255, g / 255, b / 255, a) + + +# Unbound key +_COL_KEY_BG = _rgb(30, 30, 36) # dark charcoal fill +_COL_KEY_BORDER = _rgb(255, 255, 255, 0.07) # barely visible edge +_COL_KEY_FG = _rgb(200, 200, 210) # label colour + +# Bound key +_COL_BOUND_BG = _rgb(45, 30, 80) # muted indigo fill +_COL_BOUND_BORDER = _rgb(100, 60, 160, 1.0) # soft purple border +_COL_BOUND_GLOW = _rgb(100, 60, 160, 0.20) # subtle outer glow +_COL_BOUND_MOD = _rgb(160, 140, 200) # muted MOD label tint + +# Selected key +_COL_SEL_BG = _rgb(70, 40, 120) +_COL_SEL_BORDER = _rgb(140, 80, 200, 1.0) +_COL_SEL_GLOW = _rgb(140, 80, 200, 0.30) + +# Search-match key +_COL_SEARCH_BG = _rgb(100, 50, 130) +_COL_SEARCH_BORDER = _rgb(160, 80, 180, 1.0) +_COL_SEARCH_GLOW = _rgb(160, 80, 180, 0.25) + +# Badge pill +_COL_BADGE_BG = _rgb(80, 40, 140) +_COL_BADGE_FG = _rgb(255, 255, 255) + +# Chassis +_COL_FRAME_BG = _rgb(10, 10, 12) +_COL_FRAME_BORDER = _rgb(255, 255, 255, 0.07) + + +class _AspectDrawingArea(Gtk.DrawingArea): + def __init__(self, ratio=2.43): + super().__init__() + self._ratio = ratio + self.set_hexpand(True) + + def do_get_request_mode(self): + return Gtk.SizeRequestMode.HEIGHT_FOR_WIDTH + + def do_measure(self, orientation, for_size): + if orientation == Gtk.Orientation.HORIZONTAL: + return (400, 560, -1, -1) + else: + if for_size > 0: + h = int(for_size / self._ratio) + return (h, h, -1, -1) + else: + h = int(560 / self._ratio) + return (h, h, -1, -1) + + +class KeyboardVisualizer(Gtk.Box): + """Cairo-rendered ANSI QWERTY keyboard with niri binding overlays.""" + + __gsignals__ = { + "key-selected": (GObject.SignalFlags.RUN_FIRST, None, (str,)), + "edit-binding": (GObject.SignalFlags.RUN_FIRST, None, (object,)), + "add-binding": (GObject.SignalFlags.RUN_FIRST, None, (str,)), + "delete-binding": (GObject.SignalFlags.RUN_FIRST, None, (object,)), + } + + def __init__(self): + super().__init__(orientation=Gtk.Orientation.VERTICAL, spacing=12) + + # State + self._layout_id: str = "us" + self._geometry_id: str = "ANSI" + self._bindings: dict[str, list[dict]] = {} # key_id → [bind_dict, ...] + self._selected_id: str | None = None + self._search_q: str = "" + self._dynamic_keysym_to_kid: dict[str, str] = {} + + self._xkb = XkbHelper() + self._xkb.set_layout(self._layout_id) + + self._key_rects: list[tuple[str, float, float, float, float]] = [] + + if not HAS_CAIRO: + err_lbl = Gtk.Label( + label="Cairo is not installed — the physical keyboard view is unavailable.\nInstall dev-python/pycairo and restart.", + justify=Gtk.Justification.CENTER, + ) + err_lbl.add_css_class("dim-label") + err_lbl.set_vexpand(True) + self.append(err_lbl) + return + + # Drawing area + self._area = _AspectDrawingArea(ratio=2.43) + self._area.set_draw_func(self._draw) + self.append(self._area) + + click = Gtk.GestureClick() + click.connect("released", self._on_click) + self._area.add_controller(click) + + if HAS_CAIRO: + self._panel = _ActionPanel( + on_edit=lambda b: self.emit("edit-binding", b), + on_add=lambda k: self.emit("add-binding", k), + on_delete=lambda b: self.emit("delete-binding", b), + ) + self.append(self._panel) + + # Legend + self.append(self._build_legend()) + + # Public API + + def set_bindings(self, bindings: dict[str, list[dict]]) -> None: + """Accept a key_id → [bind_dict] mapping and refresh.""" + self._bindings = bindings + if hasattr(self, "_area"): + self._area.queue_draw() + if self._selected_id: + self._panel.update( + self._selected_id, self._bindings.get(self._selected_id, []) + ) + + def set_layout(self, layout_id: str) -> None: + """Set the visualizer layout mapping (e.g. 'us', 'it').""" + self._layout_id = layout_id + self._xkb.set_layout(layout_id) + + + base_layout = layout_id.split(":")[0].lower() + iso_layouts = {'it', 'fr', 'de', 'es', 'pt', 'uk', 'ru', 'ch', 'be', 'no', 'se', 'fi', 'dk'} + if base_layout in iso_layouts: + self._geometry_id = "ISO" + else: + self._geometry_id = "ANSI" + + self._dynamic_keysym_to_kid.clear() + for kid, keycode in _KID_TO_KEYCODE.items(): + sym = self._xkb.get_keysym_name(keycode) + if sym: + self._dynamic_keysym_to_kid[sym.lower()] = kid + + if hasattr(self, "_area"): + self._area.queue_draw() + + def set_search(self, query: str) -> None: + self._search_q = query.strip().lower() + if hasattr(self, "_area"): + self._area.queue_draw() + + + # Internal helpers + + def _on_click(self, gesture, n_press, x, y): + for kid, rx, ry, rw, rh in self._key_rects: + if rx <= x <= rx + rw and ry <= y <= ry + rh: + self._selected_id = kid + self._panel.update(kid, self._bindings.get(kid, [])) + self._area.queue_draw() + self.emit("key-selected", kid) + return + + def _matches_search(self, binds: list[dict]) -> bool: + if not self._search_q: + return False + q = self._search_q + for b in binds: + if q in b.get("action", "").lower(): + return True + if q in b.get("keysym", "").lower(): + return True + return False + + def _draw(self, area, cr, width: int, height: int): + if width <= 0 or height <= 0: + return + self._key_rects = [] + + # Internal margins + pad_x, pad_y = 16, 12 + chassis_r = 12.0 + + inner_w = width - 2 * pad_x + inner_h = height - 2 * pad_y + + active_geom = KEYBOARD_GEOMETRIES.get(self._geometry_id) or KEYBOARD_GEOMETRIES["ANSI"] + n_rows = len(active_geom) + + frow_ratio = 0.7 + frow_gap = max(3.0, inner_h * 0.015) + row_h = (inner_h - frow_gap) / (frow_ratio + n_rows - 1) + frow_h = frow_ratio * row_h + + key_gap = max(2.5, row_h * 0.07) + radius = max(4.0, row_h * 0.16) + total_units = max(sum(w for _, w in row) for row in active_geom) + + # Keyboard chassis + self._rounded_rect(cr, 0, 0, width, height, chassis_r) + cr.set_source_rgba(*_COL_FRAME_BG) + cr.fill_preserve() + cr.set_source_rgba(*_COL_FRAME_BORDER) + cr.set_line_width(1.0) + cr.stroke() + + for row_idx, row in enumerate(active_geom): + if row_idx == 0: + y = float(pad_y) + this_row_h = frow_h + else: + y = float(pad_y + frow_h + frow_gap + (row_idx - 1) * row_h) + this_row_h = row_h + x = float(pad_x) + + for kid, units in row: + key_w = (units / total_units) * inner_w + + if not kid: + x += key_w + continue + + label = _STATIC_LABELS.get(kid) + if label is None: + keycode = _KID_TO_KEYCODE.get(kid) + if keycode: + label = self._xkb.get_label(keycode) + if label is None: + label = kid.upper() if len(kid) <= 1 else kid.capitalize() + else: + label = label.upper() if len(label) == 1 else label + + kx = x + key_gap / 2 + ky = y + key_gap / 2 + kw = key_w - key_gap + kh = this_row_h - key_gap + + binds = self._bindings.get(kid, []) + is_bound = bool(binds) + is_sel = self._selected_id == kid + is_search = is_bound and self._matches_search(binds) + + if is_sel: + fill = _COL_SEL_BG + border = _COL_SEL_BORDER + glow = _COL_SEL_GLOW + elif is_search: + fill = _COL_SEARCH_BG + border = _COL_SEARCH_BORDER + glow = _COL_SEARCH_GLOW + elif is_bound: + fill = _COL_BOUND_BG + border = _COL_BOUND_BORDER + glow = _COL_BOUND_GLOW + else: + fill = _COL_KEY_BG + border = _COL_KEY_BORDER + glow = None + + if glow: + for spread, alpha_scale in ((6, 0.15), (3, 0.25), (1, 0.35)): + cr.set_source_rgba(glow[0], glow[1], glow[2], glow[3] * alpha_scale) + self._rounded_rect( + cr, + kx - spread, ky - spread, + kw + spread * 2, kh + spread * 2, + radius + spread, + ) + cr.fill() + + # Key face fill + self._rounded_rect(cr, kx, ky, kw, kh, radius) + cr.set_source_rgba(*fill) + cr.fill_preserve() + + # Key border + lw = 1.2 if (is_bound or is_sel) else 0.8 + cr.set_source_rgba(*border) + cr.set_line_width(lw) + cr.stroke() + + if is_bound: + first_mod = self._first_modifier(binds) + if first_mod: + mod_fs = max(4.5, kh * 0.14) + cr.select_font_face("Sans", 0, 1) + cr.set_font_size(mod_fs) + mx = int(kx + 6) + my = int(ky + mod_fs + 5) + cr.set_source_rgba(*_COL_BOUND_MOD) + cr.move_to(mx, my) + cr.show_text(first_mod[:3].upper()) + + fs = max(7.0, kh * 0.26) + cr.select_font_face("Sans", 0, 1) + cr.set_font_size(fs) + te = cr.text_extents(label) + tx = int(kx + (kw - te.width) / 2 - te.x_bearing) + ty = int(ky + (kh + te.height) / 2 - te.height / 2) + + # Drop shadow + cr.set_source_rgba(0, 0, 0, 0.5) + cr.move_to(tx, ty + 1) + cr.show_text(label) + cr.set_source_rgba(1.0, 1.0, 1.0, 0.9) + cr.move_to(tx, ty) + cr.show_text(label) + + if len(binds) > 1: + badge_txt = str(len(binds)) + bfs = max(5.0, kh * 0.14) + cr.select_font_face("Sans", 0, 1) + cr.set_font_size(bfs) + bte = cr.text_extents(badge_txt) + bpad = 2.0 + bw = bte.width + bpad * 2 + bh_pill = bte.height + bpad * 2 + bx = int(kx + kw - bw - 5) + by = int(ky + kh - bh_pill - 5) + cr.set_source_rgba(*_COL_BADGE_BG) + self._rounded_rect(cr, bx, by, bw, bh_pill, bh_pill / 2) + cr.fill() + cr.set_source_rgba(*_COL_BADGE_FG) + cr.move_to(int(bx + bpad - bte.x_bearing), int(by + bpad - bte.y_bearing)) + cr.show_text(badge_txt) + + self._key_rects.append((kid, kx, ky, kw, kh)) + x += key_w + + @staticmethod + def _rounded_rect(cr, x: float, y: float, w: float, h: float, r: float): + r = min(r, w / 2, h / 2) + cr.new_sub_path() + cr.arc(x + w - r, y + r, r, -math.pi / 2, 0) + cr.arc(x + w - r, y + h - r, r, 0, math.pi / 2) + cr.arc(x + r, y + h - r, r, math.pi / 2, math.pi) + cr.arc(x + r, y + r, r, math.pi, 3 * math.pi / 2) + cr.close_path() + + @staticmethod + def _first_modifier(binds: list[dict]) -> str: + if not binds: + return "" + keysym = binds[0].get("keysym", "") + parts = keysym.split("+") + if len(parts) > 1: + m = parts[0].lower() + _mod_labels = { + "mod": "MOD", + "super": "SUP", + "ctrl": "CTL", + "control": "CTL", + "shift": "SHF", + "alt": "ALT", + "win": "WIN", + } + return _mod_labels.get(m, m[:4].upper()) + return "" + + @staticmethod + def _build_legend() -> Gtk.Box: + box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=20) + box.set_halign(Gtk.Align.CENTER) + box.set_margin_top(2) + box.set_opacity(0.65) + + def _chip(rgba_css: str, text: str) -> Gtk.Box: + hb = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6) + swatch = Gtk.Box() + swatch.set_size_request(12, 12) + swatch.add_css_class("nm-kb-swatch") + + attrs = Gtk.CssProvider() + attrs.load_from_data( + f".nm-kb-swatch {{ background: {rgba_css}; border-radius: 3px; }}".encode() + ) + swatch.get_style_context().add_provider( + attrs, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION + ) + lbl = Gtk.Label(label=text) + lbl.add_css_class("caption") + hb.append(swatch) + hb.append(lbl) + return hb + + box.append(_chip("rgba(147, 51, 234, 0.7)", "Bound")) + box.append(_chip("rgba(192, 97, 203, 1.0)", "Search match")) + box.append(_chip("rgba(168, 85, 247, 1.0)", "Selected")) + box.append(_chip("rgba(24, 24, 27, 1.0)", "Unbound")) + return box + + +# Action overlay panel + + +class _ActionPanel(Gtk.Box): + """Shows the binding details for the currently selected key.""" + + def __init__(self, on_edit=None, on_add=None, on_delete=None): + super().__init__(orientation=Gtk.Orientation.VERTICAL, spacing=0) + self._on_edit = on_edit + self._on_add = on_add + self._on_delete = on_delete + self._current_key_id = None + self.add_css_class("nm-kb-action-panel") + self.set_visible(False) + + # Header row + header = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) + header.set_margin_start(14) + header.set_margin_end(14) + header.set_margin_top(10) + header.set_margin_bottom(6) + + self._key_label = Gtk.Label(label="") + self._key_label.add_css_class("nm-kb-key-id-label") + self._key_label.set_xalign(0.0) + self._key_label.set_hexpand(True) + header.append(self._key_label) + + self._count_label = Gtk.Label(label="") + self._count_label.add_css_class("dim-label") + self._count_label.add_css_class("caption") + header.append(self._count_label) + + self._header_add_btn = Gtk.Button(icon_name="list-add-symbolic") + self._header_add_btn.add_css_class("flat") + self._header_add_btn.add_css_class("circular") + self._header_add_btn.set_tooltip_text("Add another binding for this key") + self._header_add_btn.set_valign(Gtk.Align.CENTER) + self._header_add_btn.set_visible(False) + self._header_add_btn.connect("clicked", self._on_header_add_clicked) + header.append(self._header_add_btn) + + self.append(header) + + self.append(Gtk.Separator()) + + + self._grp_container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) + self._grp_container.set_margin_start(8) + self._grp_container.set_margin_end(8) + self._grp_container.set_margin_top(6) + self._grp_container.set_margin_bottom(8) + self.append(self._grp_container) + + self.set_visible(False) + + def _on_header_add_clicked(self, *_): + if self._on_add and self._current_key_id: + self._on_add(self._current_key_id) + + def update(self, key_id: str, binds: list[dict]): + self._current_key_id = key_id + while True: + c = self._grp_container.get_first_child() + if c is None: + break + self._grp_container.remove(c) + + new_grp = Adw.PreferencesGroup() + + if not binds: + self._key_label.set_label(key_id.upper()) + self._count_label.set_label("No bindings") + self._header_add_btn.set_visible(False) + + add_btn = Gtk.Button(label=f"Create Binding for {key_id.upper()}") + add_btn.add_css_class("suggested-action") + add_btn.add_css_class("pill") + add_btn.set_halign(Gtk.Align.CENTER) + add_btn.set_margin_top(8) + add_btn.set_margin_bottom(8) + if self._on_add: + add_btn.connect("clicked", lambda *_: self._on_add(key_id)) + + new_grp.add(add_btn) + else: + self._key_label.set_label(key_id.upper()) + n = len(binds) + self._count_label.set_label(f"{n} binding" + ("s" if n != 1 else "")) + self._header_add_btn.set_visible(True) + for b in binds: + keysym = b.get("keysym", "?") + action = b.get("action", "") + args = b.get("action_args") or [] + arg_str = " ".join(str(a) for a in args) + full_action = f"{action} {arg_str}".strip() or "(no action)" + + row = Adw.ActionRow(title=GLib.markup_escape_text(full_action)) + + keys_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6) + keys_box.set_valign(Gtk.Align.CENTER) + keys_box.set_margin_start(4) + keys_box.set_margin_end(16) + + parts = keysym.split("+") + _labels = { + "mod": "Mod", + "super": "Super", + "ctrl": "Ctrl", + "control": "Ctrl", + "shift": "Shift", + "alt": "Alt", + "win": "Win", + } + + for i, part in enumerate(parts): + label_text = part + is_mod = i < len(parts) - 1 + if is_mod: + label_text = _labels.get(part.lower(), part) + else: + label_text = ( + label_text.upper() if len(label_text) == 1 else label_text + ) + + cap = Gtk.Label(label=label_text) + if is_mod: + cap.add_css_class("nm-keycap-mod") + else: + cap.add_css_class("nm-keycap-main") + keys_box.append(cap) + + row.add_prefix(keys_box) + + if b.get("allow_when_locked"): + lock = Gtk.Label(label="🔒") + lock.set_tooltip_text("Allowed when screen is locked") + lock.set_valign(Gtk.Align.CENTER) + row.add_suffix(lock) + + edit_btn = Gtk.Button(icon_name="document-edit-symbolic") + edit_btn.add_css_class("flat") + edit_btn.add_css_class("circular") + edit_btn.set_valign(Gtk.Align.CENTER) + if self._on_edit: + edit_btn.connect("clicked", lambda *_, bind_ref=b: self._on_edit(bind_ref)) + row.add_suffix(edit_btn) + + del_btn = Gtk.Button(icon_name="user-trash-symbolic") + del_btn.add_css_class("flat") + del_btn.add_css_class("circular") + del_btn.add_css_class("error") + del_btn.set_valign(Gtk.Align.CENTER) + if self._on_delete: + del_btn.connect("clicked", lambda *_, bind_ref=b: self._on_delete(bind_ref)) + row.add_suffix(del_btn) + + new_grp.add(row) + + self._grp_container.append(new_grp) + self.set_visible(True) + diff --git a/nirimod/window.py b/nirimod/window.py new file mode 100644 index 0000000..4f91b4c --- /dev/null +++ b/nirimod/window.py @@ -0,0 +1,1135 @@ +"""Main application window — sidebar + content NavigationSplitView.""" + +from __future__ import annotations + +import hashlib +import shutil + +import gi + +gi.require_version("Gtk", "4.0") +gi.require_version("Adw", "1") + +from gi.repository import Adw, Gdk, Gio, GLib, Gtk, Pango + +from nirimod import kdl_parser +from nirimod import niri_ipc +from nirimod import profiles as prof_mod +from nirimod.state import AppState +from nirimod.theme import CSS + +# Grouped sidebar structure: (section_title, [(page_id, icon, label), ...]) +SIDEBAR_GROUPS = [ + ("Input", [ + ("input", "input-keyboard-symbolic", "Input"), + ("bindings", "preferences-desktop-keyboard-shortcuts-symbolic", "Key Bindings"), + ]), + ("Display", [ + ("outputs", "video-display-symbolic", "Outputs"), + ("appearance", "preferences-desktop-appearance-symbolic", "Appearance"), + ("animations", "applications-multimedia-symbolic", "Animations"), + ]), + ("Workspace", [ + ("layout", "view-grid-symbolic", "Layout"), + ("workspaces", "view-paged-symbolic", "Workspaces"), + ("window_rules", "preferences-system-symbolic", "Window Rules"), + ]), + ("System", [ + ("startup", "system-run-symbolic", "Startup"), + ("environment", "preferences-other-symbolic", "Environment"), + ("gestures", "input-touchpad-symbolic", "Gestures & Misc"), + ]), + ("Advanced", [ + ("raw_config", "text-x-generic-symbolic", "Raw Config"), + ]), +] + +# Flat list for backward compat (select_page, search index, etc.) +SIDEBAR_PAGES = [entry for _, group in SIDEBAR_GROUPS for entry in group] + + +class NiriModWindow(Adw.ApplicationWindow): + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.set_title("NiriMod") + self.set_default_size(1060, 720) + + self.app_state = AppState() + self.app_state.load() + + self._current_page_id = "" + self._pages: dict[str, Gtk.Widget] = {} + self._sidebar_rows: dict[str, Gtk.ListBoxRow] = {} + self._sidebar_listboxes: dict[str, Gtk.ListBox] = {} + + + self._load_css() + self._build_ui() + self._check_onboarding() + self._check_for_updates() + self._check_kofi() + + def _load_css(self): + provider = Gtk.CssProvider() + provider.load_from_data(CSS) + Gtk.StyleContext.add_provider_for_display( + Gdk.Display.get_default(), + provider, + Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION, + ) + + def _build_ui(self): + self._toast_overlay = Adw.ToastOverlay() + self.set_content(self._toast_overlay) + + root_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + self._toast_overlay.set_child(root_box) + + self._niri_banner = Gtk.Label( + label="⚠ niri is not running — changes will be saved but not applied live", + xalign=0, + ) + self._niri_banner.add_css_class("nm-niri-banner") + self._niri_banner.set_visible(not self.app_state.niri_running) + root_box.append(self._niri_banner) + + self._split_view = Adw.NavigationSplitView() + self._split_view.set_vexpand(True) + root_box.append(self._split_view) + + self._split_view.set_sidebar(self._build_sidebar_nav()) + self._split_view.set_content(self._build_content_nav()) + + self._setup_shortcuts() + + # Navigate to first page + if SIDEBAR_PAGES: + self._select_page(SIDEBAR_PAGES[0][0]) + + def _build_sidebar_nav(self) -> Adw.NavigationPage: + nav = Adw.NavigationPage(title="NiriMod") + + sidebar_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) + sidebar_box.add_css_class("nm-sidebar-bg") + + # Header with app title and a menu button for profiles + header = Adw.HeaderBar() + title_widget = Adw.WindowTitle(title="NiriMod") + header.set_title_widget(title_widget) + + sidebar_box.append(header) + + # Search bar + self._search_entry = Gtk.SearchEntry() + self._search_entry.set_placeholder_text("Search settings\u2026") + self._search_entry.add_css_class("nm-search-entry") + self._search_entry.set_margin_start(10) + self._search_entry.set_margin_end(10) + self._search_entry.set_margin_top(10) + self._search_entry.set_margin_bottom(0) + self._search_entry.connect("search-changed", self._on_search_changed) + self._search_entry.connect("stop-search", self._on_stop_search) + # Enter key navigates to the highlighted result + self._search_entry.connect("activate", self._on_search_activate) + # Up/Down keys move the selection without stealing focus + key_ctrl = Gtk.EventControllerKey() + key_ctrl.connect("key-pressed", self._on_search_key_pressed) + self._search_entry.add_controller(key_ctrl) + sidebar_box.append(self._search_entry) + + + self._search_revealer = Gtk.Revealer() + self._search_revealer.set_transition_type(Gtk.RevealerTransitionType.SLIDE_DOWN) + self._search_revealer.set_transition_duration(120) + self._search_revealer.set_reveal_child(False) + self._search_revealer.set_margin_start(8) + self._search_revealer.set_margin_end(8) + self._search_revealer.set_margin_top(4) + self._search_revealer.set_margin_bottom(4) + results_scroll = Gtk.ScrolledWindow() + results_scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) + results_scroll.set_max_content_height(300) + results_scroll.set_propagate_natural_height(True) + self._search_results_listbox = Gtk.ListBox() + self._search_results_listbox.set_selection_mode(Gtk.SelectionMode.SINGLE) + self._search_results_listbox.add_css_class("nm-search-results") + self._search_results_listbox.connect("row-activated", self._on_search_result_activated) + results_scroll.set_child(self._search_results_listbox) + self._search_revealer.set_child(results_scroll) + sidebar_box.append(self._search_revealer) + + scroll = Gtk.ScrolledWindow() + scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) + scroll.set_vexpand(True) + + nav_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0) + nav_box.set_margin_top(8) + nav_box.set_margin_bottom(16) + + for section_title, pages in SIDEBAR_GROUPS: + # Section header label + section_lbl = Gtk.Label(label=section_title.upper()) + section_lbl.set_xalign(0.0) + section_lbl.set_margin_start(16) + section_lbl.set_margin_end(16) + section_lbl.set_margin_top(16) + section_lbl.set_margin_bottom(4) + section_lbl.add_css_class("nm-sidebar-section-label") + nav_box.append(section_lbl) + + # Page rows for this section + listbox = Gtk.ListBox() + listbox.set_selection_mode(Gtk.SelectionMode.SINGLE) + listbox.add_css_class("navigation-sidebar") + listbox.add_css_class("nm-sidebar-listbox") + listbox.set_margin_start(8) + listbox.set_margin_end(8) + listbox.connect("row-selected", self._on_row_selected) + + for page_id, icon, label in pages: + row = self._make_sidebar_row(page_id, icon, label) + listbox.append(row) + self._sidebar_rows[page_id] = row + self._sidebar_listboxes[page_id] = listbox + + nav_box.append(listbox) + + scroll.set_child(nav_box) + sidebar_box.append(scroll) + + nav.set_child(sidebar_box) + return nav + + def _make_sidebar_row(self, page_id: str, icon: str, label: str) -> Gtk.ListBoxRow: + row = Gtk.ListBoxRow() + row.page_id = page_id # type: ignore[attr-defined] + + box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) + box.set_margin_start(6) + box.set_margin_end(6) + box.set_margin_top(4) + box.set_margin_bottom(4) + + icon_img = Gtk.Image(icon_name=icon) + icon_img.add_css_class("nm-sidebar-icon") + box.append(icon_img) + + text_lbl = Gtk.Label(label=label, xalign=0) + text_lbl.set_hexpand(True) + box.append(text_lbl) + + + + row.set_child(box) + return row + + def _build_content_nav(self) -> Adw.NavigationPage: + self._content_nav = Adw.NavigationPage(title="") + + content_root = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + + self._stack = Gtk.Stack() + self._stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE) + self._stack.set_transition_duration(120) + self._stack.set_vexpand(True) + content_root.append(self._stack) + + + self._build_all_pages() + self._build_search_index() + + self._dirty_bar = self._build_dirty_bar() + content_root.append(self._dirty_bar) + + self._content_nav.set_child(content_root) + return self._content_nav + + def _build_dirty_bar(self) -> Gtk.Box: + bar = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8) + bar.add_css_class("nm-dirty-bar") + bar.set_visible(False) + bar.set_margin_start(12) + bar.set_margin_end(12) + bar.set_margin_top(6) + bar.set_margin_bottom(6) + + self._dirty_label = Gtk.Label(label="Unsaved changes") + self._dirty_label.set_hexpand(True) + self._dirty_label.set_xalign(0.0) + self._dirty_label.set_opacity(0.7) + bar.append(self._dirty_label) + + self._undo_btn = Gtk.Button(label="Undo") + self._undo_btn.add_css_class("flat") + self._undo_btn.set_tooltip_text("Undo last change (Ctrl+Z)") + self._undo_btn.connect("clicked", lambda *_: self._do_undo()) + bar.append(self._undo_btn) + + self._redo_btn = Gtk.Button(label="Redo") + self._redo_btn.add_css_class("flat") + self._redo_btn.set_tooltip_text("Redo (Ctrl+Shift+Z)") + self._redo_btn.set_sensitive(False) + self._redo_btn.connect("clicked", lambda *_: self._do_redo()) + bar.append(self._redo_btn) + + discard_btn = Gtk.Button(label="Discard") + discard_btn.add_css_class("destructive-action") + discard_btn.add_css_class("flat") + discard_btn.set_tooltip_text("Revert all unsaved changes") + discard_btn.connect("clicked", lambda *_: self._on_discard()) + bar.append(discard_btn) + + save_btn = Gtk.Button(label="Save & Apply") + save_btn.add_css_class("suggested-action") + save_btn.set_tooltip_text("Save to config.kdl and reload niri (Ctrl+S)") + save_btn.connect("clicked", lambda *_: self._on_save()) + bar.append(save_btn) + + return bar + + def _build_all_pages(self): + from nirimod.pages import ( + outputs, + input_page, + layout, + appearance, + animations, + bindings, + window_rules, + startup, + workspaces, + environment, + gestures, + raw_config, + ) + + page_builders = { + "outputs": outputs.OutputsPage, + "input": input_page.InputPage, + "layout": layout.LayoutPage, + "appearance": appearance.AppearancePage, + "animations": animations.AnimationsPage, + "bindings": bindings.BindingsPage, + "window_rules": window_rules.WindowRulesPage, + "startup": startup.StartupPage, + "workspaces": workspaces.WorkspacesPage, + "environment": environment.EnvironmentPage, + "gestures": gestures.GesturesPage, + "raw_config": raw_config.RawConfigPage, + } + for page_id, _, title in SIDEBAR_PAGES: + cls = page_builders.get(page_id) + if cls: + page_obj = cls(window=self) + widget = page_obj.build() + self._pages[page_id] = page_obj + self._stack.add_named(widget, page_id) + + def _on_row_selected(self, _lb, row): + if row is None: + return + pid = getattr(row, "page_id", None) + if pid: + + for other_pid, lb in self._sidebar_listboxes.items(): + if lb is not _lb: + lb.unselect_all() + self._select_page(pid) + + def _select_page(self, page_id: str): + self._current_page_id = page_id + self._stack.set_visible_child_name(page_id) + for pid, _, title in SIDEBAR_PAGES: + if pid == page_id: + self._content_nav.set_title(title) + break + # Select the right sidebar row, deselect others + for pid, lb in self._sidebar_listboxes.items(): + row = self._sidebar_rows.get(pid) + if row: + if pid == page_id: + lb.select_row(row) + + + # Notify page of visibility + page = self._pages.get(page_id) + if page and hasattr(page, "on_shown"): + page.on_shown() + + def _build_search_index(self): + self._search_index: list[dict] = [] + + def traverse(widget, pid, p_title): + + if isinstance(widget, Adw.PreferencesRow): + title = widget.get_title() + if title: + subtitle = widget.get_subtitle() if hasattr(widget, "get_subtitle") else "" + self._search_index.append({ + "page_id": pid, + "page_title": p_title, + "title": title, + "subtitle": subtitle, + "widget": widget, + }) + + + if isinstance(widget, Adw.PreferencesGroup): + title = widget.get_title() + if title: + self._search_index.append({ + "page_id": pid, + "page_title": p_title, + "title": title, + "subtitle": "(Group)", + "widget": widget, + }) + + # Recurse into all children to find nested elements + child = widget.get_first_child() + while child: + traverse(child, pid, p_title) + child = child.get_next_sibling() + + for pid, _icon, p_title in SIDEBAR_PAGES: + stack_child = self._stack.get_child_by_name(pid) + if stack_child: + traverse(stack_child, pid, p_title) + + def _on_search_changed(self, entry): + query = entry.get_text().strip().lower() + if not query or len(query) < 2: + self._search_revealer.set_reveal_child(False) + return + + matches = [ + r for r in self._search_index + if query in r["title"].lower() + or query in r["subtitle"].lower() + or query in r["page_title"].lower() + ] + + child = self._search_results_listbox.get_first_child() + while child: + self._search_results_listbox.remove(child) + child = self._search_results_listbox.get_first_child() + + if matches: + for m in matches: + row = Gtk.ListBoxRow() + row.search_match = m + row.set_focusable(False) + box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=1) + box.set_margin_start(8) + box.set_margin_end(8) + box.set_margin_top(6) + box.set_margin_bottom(6) + title_lbl = Gtk.Label(label=m["title"], xalign=0) + title_lbl.add_css_class("heading") + title_lbl.set_focusable(False) + title_lbl.set_ellipsize(Pango.EllipsizeMode.END) + box.append(title_lbl) + sub_text = m["page_title"] + if m["subtitle"]: + sub_text += f" \u2022 {m['subtitle']}" + sub_lbl = Gtk.Label(label=sub_text, xalign=0) + sub_lbl.add_css_class("dim-label") + sub_lbl.set_ellipsize(Pango.EllipsizeMode.END) + sub_lbl.set_focusable(False) + box.append(sub_lbl) + row.set_child(box) + self._search_results_listbox.append(row) + first = self._search_results_listbox.get_row_at_index(0) + if first: + self._search_results_listbox.select_row(first) + self._search_revealer.set_reveal_child(True) + else: + self._search_revealer.set_reveal_child(False) + + def _on_search_key_pressed(self, controller, keyval, keycode, state): + if not self._search_revealer.get_reveal_child(): + return False + lb = self._search_results_listbox + sel = lb.get_selected_row() + if keyval == Gdk.KEY_Down: + idx = (sel.get_index() + 1) if sel else 0 + nxt = lb.get_row_at_index(idx) + if nxt: + lb.select_row(nxt) + return True + if keyval == Gdk.KEY_Up: + if sel and sel.get_index() > 0: + lb.select_row(lb.get_row_at_index(sel.get_index() - 1)) + return True + return False + + def _on_search_activate(self, entry): + if not self._search_revealer.get_reveal_child(): + return + sel = self._search_results_listbox.get_selected_row() + if sel: + self._on_search_result_activated(self._search_results_listbox, sel) + + def _on_stop_search(self, entry): + entry.set_text("") + self._search_revealer.set_reveal_child(False) + + def _on_search_result_activated(self, listbox, row): + if not hasattr(row, "search_match"): + return + + m = row.search_match + self._search_revealer.set_reveal_child(False) + self._search_entry.set_text("") + + # Navigate to the page + self._select_page(m["page_id"]) + + # Highlight the widget + widget = m["widget"] + widget.add_css_class("nm-pulse-highlight") + + def remove_class(): + widget.remove_css_class("nm-pulse-highlight") + return False + + GLib.timeout_add(1500, remove_class) + + # Shortcuts + + def _setup_shortcuts(self): + app = self.get_application() + if not app: + return + shortcuts = [ + ("save", self._on_save, ["s"]), + ("undo", self._do_undo, ["z"]), + ("redo", self._do_redo, ["z"]), + ("search", lambda: self._search_entry.grab_focus(), ["f"]), + ] + for name, fn, accels in shortcuts: + a = Gio.SimpleAction.new(name, None) + a.connect("activate", lambda _a, _p, f=fn: f()) + self.add_action(a) + app.set_accels_for_action(f"win.{name}", accels) + + # Menu actions + open_profiles_action = Gio.SimpleAction.new("open_profiles", None) + open_profiles_action.connect("activate", lambda *_: self._on_profiles_clicked()) + self.add_action(open_profiles_action) + + open_prefs_action = Gio.SimpleAction.new("open_preferences", None) + open_prefs_action.connect("activate", lambda *_: self._open_preferences()) + self.add_action(open_prefs_action) + + reset_config_action = Gio.SimpleAction.new("reset_config", None) + reset_config_action.connect("activate", lambda *_: self._on_reset_config_clicked()) + self.add_action(reset_config_action) + + open_kofi_action = Gio.SimpleAction.new("open_kofi", None) + open_kofi_action.connect("activate", lambda *_: self._show_kofi_dialog()) + self.add_action(open_kofi_action) + + def get_nodes(self): + return self.app_state.nodes + + def mark_dirty(self): + self.app_state.mark_dirty() + self._dirty_bar.set_visible(True) + self._undo_btn.set_sensitive(self.app_state.undo.can_undo()) + self._redo_btn.set_sensitive(self.app_state.undo.can_redo()) + desc = self.app_state.undo.last_description + self._dirty_label.set_label(f"Unsaved: {desc}" if desc else "Unsaved changes") + self._build_search_index() + + def mark_clean(self): + self.app_state.mark_clean() + self._dirty_bar.set_visible(False) + self._dirty_label.set_label("Unsaved changes") + self._redo_btn.set_sensitive(False) + + def push_undo(self, description: str, before: str, after: str): + self.app_state.push_undo(description, before, after) + self._undo_btn.set_sensitive(True) + + def notify_nodes_changed(self): + self.app_state.reload_from_disk() + page = self._pages.get(self._current_page_id) + if page and hasattr(page, "refresh"): + page.refresh() + self._build_search_index() + + def _on_save(self): + from nirimod import app_settings + if app_settings.get("auto_backup", True): + from nirimod.backup import backup_all_sources + limit = app_settings.get("backup_limit", 10) + backup_all_sources(self.app_state.source_files, limit=limit) + + new_kdl = self.app_state.write_current_kdl() + + def _finish_save(reload_result): + reload_ok, reload_msg = reload_result + self.app_state.commit_save(new_kdl) + raw = self._pages.get("raw_config") + if raw and hasattr(raw, "refresh"): + raw.refresh() + self._build_search_index() + self.mark_clean() + if reload_ok: + self.show_toast("Config saved and applied ✓", timeout=3) + else: + self.show_toast( + f"Config saved, but reload failed: {reload_msg}", timeout=8 + ) + + if self.app_state.is_multi_file: + # Snapshot all source files before touching them + snapshots = { + p: p.read_text() for p in self.app_state.source_files if p.exists() + } + self.app_state.write_to_path() + + def _on_validated(result): + ok, msg = result + if not ok: + # Restore all files from snapshots + for p, text in snapshots.items(): + p.write_text(text) + self.show_toast(f"Validation error: {msg}", timeout=8) + return + niri_ipc.run_in_thread(niri_ipc.load_config_file, _finish_save) + + niri_ipc.run_in_thread( + lambda: niri_ipc.validate_config(), _on_validated + ) + else: + tmp_kdl = kdl_parser.NIRI_CONFIG.with_name(".config.kdl.tmp") + self.app_state.write_to_path(tmp_kdl) + + def _on_validated(result): + ok, msg = result + if not ok: + self.show_toast(f"Validation error: {msg}", timeout=8) + tmp_kdl.unlink(missing_ok=True) + return + shutil.move(tmp_kdl, kdl_parser.NIRI_CONFIG) + niri_ipc.run_in_thread(niri_ipc.load_config_file, _finish_save) + + niri_ipc.run_in_thread( + lambda: niri_ipc.validate_config(str(tmp_kdl)), _on_validated + ) + + def _on_discard(self): + self.app_state.discard() + self.mark_clean() + self.notify_nodes_changed() + + def _raw_config_textview_focused(self) -> bool: + """Return True if the raw-config text editor currently has keyboard focus.""" + raw_page = self._pages.get("raw_config") + if raw_page is None: + return False + tv = getattr(raw_page, "_textview", None) + if tv is None: + return False + return tv.has_focus() + + def _do_undo(self): + if self._raw_config_textview_focused(): + raw_page = self._pages.get("raw_config") + buf = raw_page._textview.get_buffer() # type: ignore[union-attr] + if buf.get_can_undo(): + buf.undo() + return + + entry = self.app_state.apply_undo() + if entry is None: + return + + if not self.app_state.undo.can_undo(): + self._undo_btn.set_sensitive(False) + + if self.app_state.is_dirty: + self.mark_dirty() + else: + self.mark_clean() + + self.notify_nodes_changed() + + def _do_redo(self): + if self._raw_config_textview_focused(): + raw_page = self._pages.get("raw_config") + buf = raw_page._textview.get_buffer() + if buf.get_can_redo(): + buf.redo() + return + + entry = self.app_state.apply_redo() + if entry is None: + return + + self._redo_btn.set_sensitive(self.app_state.undo.can_redo()) + self._undo_btn.set_sensitive(True) + self.mark_dirty() + self.notify_nodes_changed() + + def show_toast(self, message: str, timeout: int = 3, copy_text: str | None = None): + toast = Adw.Toast(title=message, timeout=timeout) + if copy_text is not None: + toast.set_button_label("Copy") + toast.connect("button-clicked", lambda *_: self.get_clipboard().set(copy_text)) + elif "error" in message.lower() or "failed" in message.lower(): + toast.set_button_label("Copy") + toast.connect("button-clicked", lambda *_: self.get_clipboard().set(message)) + + self._toast_overlay.add_toast(toast) + + def _get_baseline_dir(self): + from pathlib import Path + path_str = str(kdl_parser.NIRI_CONFIG.resolve()) + path_hash = hashlib.md5(path_str.encode()).hexdigest()[:8] + return Path.home() / ".config" / "nirimod" / "baseline" / f"{kdl_parser.NIRI_CONFIG.name}_{path_hash}" + + def _check_onboarding(self): + baseline_dir = self._get_baseline_dir() + sentinel = baseline_dir / kdl_parser.NIRI_CONFIG.name + if sentinel.exists(): + return + + source_files = sorted(self.app_state.source_files) + filenames = "\n".join(f" • {p.name}" for p in source_files) + body = ( + f"NiriMod will back up your original config files to\n" + f"{baseline_dir}:\n\n" + f"{filenames}\n" + ) + + dialog = Adw.AlertDialog(heading="Welcome to NiriMod", body=body) + dialog.set_body_use_markup(True) + dialog.add_response("cancel", "Not Now") + dialog.add_response("accept", "Create Backup") + dialog.set_response_appearance("accept", Adw.ResponseAppearance.SUGGESTED) + dialog.set_default_response("accept") + dialog.connect("response", self._on_onboarding_response) + dialog.present(self) + + def _check_kofi(self): + from nirimod import app_settings + + if app_settings.get("kofi_v3_dont_show", False): + return + self._show_kofi_dialog() + + def _show_kofi_dialog(self): + from nirimod import app_settings + + dialog = Adw.AlertDialog( + heading="Enjoying NiriMod? ☕", + body=( + "NiriMod is a passion project built entirely in my free time to make customizing Niri easier for everyone.\n\n" + "If it has improved your workflow, please consider supporting its development with a small tip on Ko-fi! " + "Your support directly fuels new features and keeps the project alive." + ), + ) + dialog.add_response("dismiss", "Maybe Later") + dialog.add_response("kofi", "Support on Ko-fi") + dialog.set_response_appearance("kofi", Adw.ResponseAppearance.SUGGESTED) + dialog.set_default_response("kofi") + + dont_show_check = Gtk.CheckButton(label="Don't show this again on startup") + dont_show_check.set_active(app_settings.get("kofi_v3_dont_show", False)) + dont_show_check.set_halign(Gtk.Align.CENTER) + dont_show_check.set_margin_top(4) + dialog.set_extra_child(dont_show_check) + + def _on_kofi_response(dlg, response): + app_settings.set("kofi_v3_dont_show", dont_show_check.get_active()) + if response == "kofi": + Gio.AppInfo.launch_default_for_uri("https://ko-fi.com/srinivasr", None) + + dialog.connect("response", _on_kofi_response) + dialog.present(self) + + def _check_for_updates(self): + from nirimod import app_settings, updater + if app_settings.get("auto_update", True): + updater.check_for_updates(self._on_update_check_result) + + def _on_update_check_result(self, remote_sha: str | None, commit_msg: str | None): + if remote_sha is None: + return + + dialog = Adw.AlertDialog( + heading="Update Available", + body=f"A new version of NiriMod is available on GitHub!\n\nLatest Commit:\n{GLib.markup_escape_text(commit_msg or '')}", + ) + dialog.set_body_use_markup(True) + dialog.add_response("cancel", "Later") + dialog.add_response("update", "Update in Terminal") + dialog.set_response_appearance("update", Adw.ResponseAppearance.SUGGESTED) + + def _on_response(dlg, response): + if response == "update": + from nirimod import updater + updater.launch_updater_in_terminal() + app = self.get_application() + if app: + app.quit() + dialog.connect("response", _on_response) + dialog.present(self) + + def _on_onboarding_response(self, dialog, response): + if response != "accept": + return + baseline_dir = self._get_baseline_dir() + try: + baseline_dir.mkdir(parents=True, exist_ok=True) + for p in self.app_state.source_files: + if p.exists(): + try: + rel = p.relative_to(kdl_parser.NIRI_CONFIG.parent) + dest = baseline_dir / rel + dest.parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(p, dest) + except ValueError: + shutil.copy2(p, baseline_dir / p.name) + self.show_toast("Baseline backup created ✓") + except Exception as e: + self.show_toast(f"Backup failed: {e}", timeout=6) + + def _on_reset_config_clicked(self, _btn=None): + baseline_dir = self._get_baseline_dir() + + backups = [] + if kdl_parser.BACKUP_DIR.exists(): + for p in kdl_parser.BACKUP_DIR.iterdir(): + if p.is_dir(): + backups.append((p.stat().st_mtime, p, p.name)) + + backups.sort(key=lambda x: x[0], reverse=True) + + if baseline_dir.exists(): + backups.append((baseline_dir.stat().st_mtime, baseline_dir, "Original Baseline")) + + if not backups: + self.show_toast("No backups available to restore.") + return + + prefs_win = Adw.PreferencesWindow() + prefs_win.set_title("Restore Backup") + prefs_win.set_modal(True) + prefs_win.set_transient_for(self) + prefs_win.set_default_size(500, 400) + + page = Adw.PreferencesPage() + grp = Adw.PreferencesGroup( + title="Available Backups", + description="Select a backup to restore your configuration from." + ) + + for _, path, name in backups: + row = Adw.ActionRow(title=name) + if name == "Original Baseline": + row.set_subtitle("Taken on first launch") + + restore_btn = Gtk.Button(label="Restore") + restore_btn.set_valign(Gtk.Align.CENTER) + restore_btn.add_css_class("flat") + restore_btn.add_css_class("suggested-action") + restore_btn.connect("clicked", lambda _b, p=path: self._confirm_restore(p, prefs_win)) + row.add_suffix(restore_btn) + grp.add(row) + + page.add(grp) + prefs_win.add(page) + prefs_win.present() + + def _confirm_restore(self, backup_dir, parent_dialog): + parent_dialog.close() + dialog = Adw.AlertDialog( + heading="Confirm Restore", + body="Your current configuration will be replaced by this backup. You may want to manually save your current work first." + ) + dialog.add_response("cancel", "Cancel") + dialog.add_response("restore", "Restore") + dialog.set_response_appearance("restore", Adw.ResponseAppearance.DESTRUCTIVE) + dialog.connect("response", lambda dlg, r: self._perform_restore(backup_dir) if r == "restore" else None) + dialog.present(self) + + def _perform_restore(self, backup_dir): + try: + shutil.copytree(backup_dir, kdl_parser.NIRI_CONFIG.parent, dirs_exist_ok=True) + self.app_state.reload_from_disk() + self.notify_nodes_changed() + self.mark_clean() + self.show_toast("Config restored from backup ✓") + except Exception as e: + self.show_toast(f"Restore failed: {e}", timeout=6) + + def _open_preferences(self): + from nirimod import app_settings + + prefs_win = Adw.PreferencesWindow() + prefs_win.set_title("NiriMod Preferences") + prefs_win.set_modal(True) + prefs_win.set_transient_for(self) + prefs_win.set_default_size(500, 400) + + page = Adw.PreferencesPage( + title="General", icon_name="emblem-system-symbolic" + ) + + updates_grp = Adw.PreferencesGroup( + title="Updates", + description="Control how NiriMod checks for new versions", + ) + + auto_update_row = Adw.SwitchRow( + title="Check for Updates Automatically", + subtitle="Checks the GitHub repository for new commits on launch", + ) + auto_update_row.set_active(app_settings.get("auto_update", True)) + auto_update_row.connect( + "notify::active", + lambda row, _: app_settings.set("auto_update", row.get_active()), + ) + updates_grp.add(auto_update_row) + page.add(updates_grp) + + config_grp = Adw.PreferencesGroup( + title="Configuration File", + description="Manage Niri configuration paths and backups", + ) + + config_path_row = Adw.ActionRow(title="Config Path") + current_path = app_settings.get("config_path", "") + config_path_row.set_subtitle(current_path if current_path else "Default (~/.config/niri/config.kdl)") + + browse_btn = Gtk.Button(label="Browse...") + browse_btn.set_valign(Gtk.Align.CENTER) + browse_btn.connect("clicked", lambda _b: self._on_browse_config(prefs_win, config_path_row)) + config_path_row.add_suffix(browse_btn) + + clear_btn = Gtk.Button(icon_name="edit-clear-symbolic") + clear_btn.set_valign(Gtk.Align.CENTER) + clear_btn.set_tooltip_text("Reset to default") + clear_btn.connect("clicked", lambda _b: self._on_clear_config(config_path_row)) + config_path_row.add_suffix(clear_btn) + + config_grp.add(config_path_row) + + backup_path_row = Adw.ActionRow(title="Backup Directory") + current_backup = app_settings.get("backup_path", "") + backup_path_row.set_subtitle(current_backup if current_backup else "Default (~/.config/nirimod/backups)") + + browse_backup_btn = Gtk.Button(label="Browse...") + browse_backup_btn.set_valign(Gtk.Align.CENTER) + browse_backup_btn.connect("clicked", lambda _b: self._on_browse_backup_dir(prefs_win, backup_path_row)) + backup_path_row.add_suffix(browse_backup_btn) + + clear_backup_btn = Gtk.Button(icon_name="edit-clear-symbolic") + clear_backup_btn.set_valign(Gtk.Align.CENTER) + clear_backup_btn.set_tooltip_text("Reset to default") + clear_backup_btn.connect("clicked", lambda _b: self._on_clear_backup_dir(backup_path_row)) + backup_path_row.add_suffix(clear_backup_btn) + + config_grp.add(backup_path_row) + + auto_backup_row = Adw.SwitchRow( + title="Automatic Backups", + subtitle="Create a timestamped backup before saving", + ) + auto_backup_row.set_active(app_settings.get("auto_backup", True)) + auto_backup_row.connect( + "notify::active", + lambda row, _: app_settings.set("auto_backup", row.get_active()), + ) + config_grp.add(auto_backup_row) + + backup_limit_row = Adw.SpinRow( + title="Backup Limit", + subtitle="Maximum number of backups to keep per file (0 = unlimited)", + digits=0, + ) + backup_limit_row.set_adjustment(Gtk.Adjustment(value=app_settings.get("backup_limit", 10), lower=0, upper=1000, step_increment=1)) + backup_limit_row.connect( + "notify::value", + lambda row, _: app_settings.set("backup_limit", int(row.get_value())), + ) + + def _on_auto_backup_changed(switch_row, _param): + backup_limit_row.set_sensitive(switch_row.get_active()) + + auto_backup_row.connect("notify::active", _on_auto_backup_changed) + backup_limit_row.set_sensitive(auto_backup_row.get_active()) + + config_grp.add(backup_limit_row) + page.add(config_grp) + + prefs_win.add(page) + prefs_win.present() + + def _on_browse_config(self, parent_win, row): + from nirimod import app_settings + dialog = Gtk.FileDialog() + dialog.set_title("Select Niri Config") + f = Gtk.FileFilter() + f.set_name("KDL files") + f.add_pattern("*.kdl") + filters = Gio.ListStore.new(Gtk.FileFilter) + filters.append(f) + dialog.set_filters(filters) + + def _on_response(dialog, result): + try: + f = dialog.open_finish(result) + if f: + path = f.get_path() + app_settings.set("config_path", path) + row.set_subtitle(path) + self.show_toast("Restart NiriMod to use the new config path.", timeout=5) + except GLib.Error: + pass + + dialog.open(parent_win, None, _on_response) + + def _on_browse_backup_dir(self, parent_win, row): + from nirimod import app_settings + dialog = Gtk.FileDialog() + dialog.set_title("Select Backup Directory") + + def _on_response(dialog, result): + try: + f = dialog.select_folder_finish(result) + if f: + path = f.get_path() + app_settings.set("backup_path", path) + row.set_subtitle(path) + kdl_parser.set_paths( + config_path=app_settings.get("config_path", ""), + backup_path=path + ) + self.show_toast("Backup directory updated.", timeout=3) + except GLib.Error: + pass + + dialog.select_folder(parent_win, None, _on_response) + + def _on_clear_backup_dir(self, row): + from nirimod import app_settings + app_settings.set("backup_path", "") + row.set_subtitle("Default (~/.config/nirimod/backups)") + kdl_parser.set_paths( + config_path=app_settings.get("config_path", ""), + backup_path="" + ) + self.show_toast("Backup directory reset to default.", timeout=3) + + def _on_clear_config(self, row): + from nirimod import app_settings + app_settings.set("config_path", "") + row.set_subtitle("Default (~/.config/niri/config.kdl)") + self.show_toast("Restart NiriMod to use the default config path.", timeout=5) + + def _on_profiles_clicked(self, _btn=None): + dialog = Adw.AlertDialog(heading="Profiles") + + box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8) + box.set_margin_start(4) + box.set_margin_end(4) + + names = prof_mod.list_profiles() + if names: + grp = Adw.PreferencesGroup(title="Saved Profiles") + for name in names: + row = Adw.ActionRow(title=name) + load_btn = Gtk.Button(label="Load") + load_btn.set_valign(Gtk.Align.CENTER) + load_btn.add_css_class("flat") + load_btn.connect( + "clicked", lambda _b, n=name: self._load_profile(n, dialog) + ) + del_btn = Gtk.Button(icon_name="user-trash-symbolic") + del_btn.set_valign(Gtk.Align.CENTER) + del_btn.add_css_class("flat") + del_btn.add_css_class("error") + del_btn.connect( + "clicked", lambda _b, n=name: self._delete_profile(n, dialog) + ) + row.add_suffix(load_btn) + row.add_suffix(del_btn) + grp.add(row) + box.append(grp) + + save_row = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8) + save_row.set_margin_top(8) + entry = Gtk.Entry(placeholder_text="New profile name…") + entry.set_hexpand(True) + save_btn = Gtk.Button(label="Save Current") + save_btn.add_css_class("suggested-action") + save_btn.connect( + "clicked", lambda _b: self._save_profile(entry.get_text(), dialog) + ) + save_row.append(entry) + save_row.append(save_btn) + box.append(save_row) + + dialog.set_extra_child(box) + dialog.add_response("close", "Close") + dialog.present(self) + + def _save_profile(self, name: str, dialog): + name = name.strip() + if not name: + return + prof_mod.save_profile(name, source_files=self.app_state.source_files) + self.show_toast(f"Profile '{name}' saved ✓") + + def _load_profile(self, name: str, dialog): + if prof_mod.load_profile(name): + self.notify_nodes_changed() + self.mark_dirty() + self.show_toast(f"Profile '{name}' loaded") + dialog.close() + + def _delete_profile(self, name: str, dialog): + prof_mod.delete_profile(name) + self.show_toast(f"Profile '{name}' deleted") + + extra = dialog.get_extra_child() + if extra: + dialog.set_extra_child(None) + box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8) + box.set_margin_start(4) + box.set_margin_end(4) + names = prof_mod.list_profiles() + if names: + grp = Adw.PreferencesGroup(title="Saved Profiles") + for n in names: + row = Adw.ActionRow(title=n) + load_btn = Gtk.Button(label="Load") + load_btn.set_valign(Gtk.Align.CENTER) + load_btn.add_css_class("flat") + load_btn.connect("clicked", lambda _b, nm=n: self._load_profile(nm, dialog)) + del_btn = Gtk.Button(icon_name="user-trash-symbolic") + del_btn.set_valign(Gtk.Align.CENTER) + del_btn.add_css_class("flat") + del_btn.add_css_class("error") + del_btn.connect("clicked", lambda _b, nm=n: self._delete_profile(nm, dialog)) + row.add_suffix(load_btn) + row.add_suffix(del_btn) + grp.add(row) + box.append(grp) + save_row = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8) + save_row.set_margin_top(8) + entry = Gtk.Entry(placeholder_text="New profile name\u2026") + entry.set_hexpand(True) + save_btn = Gtk.Button(label="Save Current") + save_btn.add_css_class("suggested-action") + save_btn.connect("clicked", lambda _b: self._save_profile(entry.get_text(), dialog)) + save_row.append(entry) + save_row.append(save_btn) + box.append(save_row) + dialog.set_extra_child(box) + diff --git a/nirimod/window_effects.py b/nirimod/window_effects.py new file mode 100644 index 0000000..d45749f --- /dev/null +++ b/nirimod/window_effects.py @@ -0,0 +1,299 @@ +"""Helpers for Niri global window effect rules.""" + +from __future__ import annotations + +from nirimod.kdl_parser import KdlNode, remove_child, set_child_arg, set_node_flag + +_RULE_CHILD_ORDER = [ + "match", + "exclude", + "geometry-corner-radius", + "clip-to-geometry", + "draw-border-with-background", + "opacity", + "background-effect", +] + +_EFFECT_CHILD_ORDER = ["blur", "xray"] +_BLUR_CONFIG_CHILD_ORDER = ["off", "passes", "offset", "noise", "saturation"] + + +def _is_global_window_rule(node: KdlNode) -> bool: + return ( + node.name == "window-rule" + and not node.get_children("match") + and not node.get_children("exclude") + ) + + +def _is_focused_window_rule(node: KdlNode) -> bool: + if node.name != "window-rule" or node.get_children("exclude"): + return False + matches = node.get_children("match") + if len(matches) != 1: + return False + match = matches[0] + return match.args == [] and match.props == {"is-focused": True} + + +def _global_window_rule(nodes: list[KdlNode]) -> KdlNode | None: + return next((n for n in reversed(nodes) if _is_global_window_rule(n)), None) + + +def _focused_window_rule(nodes: list[KdlNode]) -> KdlNode | None: + return next((n for n in reversed(nodes) if _is_focused_window_rule(n)), None) + + +def _blur_config_node(nodes: list[KdlNode]) -> KdlNode | None: + return next((n for n in reversed(nodes) if n.name == "blur"), None) + + +def _ensure_blur_config_node(nodes: list[KdlNode]) -> KdlNode: + blur = _blur_config_node(nodes) + if blur is None: + blur = KdlNode("blur") + blur.leading_trivia = "\n" + nodes.append(blur) + return blur + + +def _ensure_global_window_rule(nodes: list[KdlNode]) -> KdlNode: + rule = _global_window_rule(nodes) + if rule is None: + rule = KdlNode("window-rule") + rule.leading_trivia = "\n" + nodes.append(rule) + return rule + + +def _ensure_focused_window_rule(nodes: list[KdlNode]) -> KdlNode: + rule = _focused_window_rule(nodes) + if rule is None: + rule = KdlNode("window-rule") + rule.leading_trivia = "\n" + rule.children.append(KdlNode("match", props={"is-focused": True})) + nodes.append(rule) + return rule + + +def _background_effect(rule: KdlNode) -> KdlNode | None: + return rule.get_child("background-effect") + + +def _ensure_background_effect(rule: KdlNode) -> KdlNode: + effect = _background_effect(rule) + if effect is None: + effect = KdlNode("background-effect") + effect.leading_trivia = "\n" + rule.children.append(effect) + return effect + + +def _remove_rule_if_empty(nodes: list[KdlNode], rule: KdlNode) -> None: + if not rule.args and not rule.props and not rule.children and rule in nodes: + nodes.remove(rule) + + +def _remove_background_effect_if_empty(rule: KdlNode) -> None: + effect = _background_effect(rule) + if effect and not effect.args and not effect.props and not effect.children: + remove_child(rule, "background-effect") + + +def _compact_generated_spacing(node: KdlNode) -> None: + if not node.trailing_trivia or node.trailing_trivia.isspace(): + node.trailing_trivia = "\n" + for child in node.children: + if not child.leading_trivia or child.leading_trivia.isspace(): + child.leading_trivia = "" + if not child.trailing_trivia or child.trailing_trivia.isspace(): + child.trailing_trivia = "" + if child.name == "background-effect": + _compact_generated_spacing(child) + + +def _sort_children_by_name(node: KdlNode, order: list[str]) -> None: + order_index = {name: index for index, name in enumerate(order)} + indexed_children = list(enumerate(node.children)) + indexed_children.sort( + key=lambda item: (order_index.get(item[1].name, len(order)), item[0]) + ) + node.children = [child for _, child in indexed_children] + + +def _finalize_window_rule(rule: KdlNode) -> None: + effect = _background_effect(rule) + if effect is not None: + _sort_children_by_name(effect, _EFFECT_CHILD_ORDER) + _sort_children_by_name(rule, _RULE_CHILD_ORDER) + _compact_generated_spacing(rule) + + +def _finalize_blur_config(blur: KdlNode) -> None: + _sort_children_by_name(blur, _BLUR_CONFIG_CHILD_ORDER) + _compact_generated_spacing(blur) + + +def _rule_opacity(rule: KdlNode | None) -> float: + if rule is None: + return 1.0 + value = rule.child_arg("opacity", 1.0) + try: + return float(value) + except (TypeError, ValueError): + return 1.0 + + +def get_global_draw_border_with_background(nodes: list[KdlNode]) -> bool: + rule = _global_window_rule(nodes) + if rule is None: + return True + return rule.child_arg("draw-border-with-background", True) is not False + + +def set_global_draw_border_with_background(nodes: list[KdlNode], enabled: bool) -> None: + rule = _ensure_global_window_rule(nodes) + if enabled: + remove_child(rule, "draw-border-with-background") + else: + set_child_arg(rule, "draw-border-with-background", False) + _finalize_window_rule(rule) + _remove_rule_if_empty(nodes, rule) + + +def blur_effects_enabled(nodes: list[KdlNode]) -> bool: + blur = _blur_config_node(nodes) + return blur is None or blur.get_child("off") is None + + +def set_blur_effects_enabled(nodes: list[KdlNode], enabled: bool) -> None: + blur = _ensure_blur_config_node(nodes) + set_node_flag(blur, "off", not enabled) + _finalize_blur_config(blur) + _remove_rule_if_empty(nodes, blur) + if enabled: + rule = _ensure_global_window_rule(nodes) + if _rule_opacity(rule) >= 1.0: + set_child_arg(rule, "opacity", 0.9) + _finalize_window_rule(rule) + else: + set_global_window_blur(nodes, False) + set_focused_window_blur(nodes, False) + + +def global_window_blur_enabled(nodes: list[KdlNode]) -> bool: + rule = _global_window_rule(nodes) + return _rule_blur_enabled(rule) + + +def focused_window_blur_enabled(nodes: list[KdlNode]) -> bool: + rule = _focused_window_rule(nodes) + return _rule_blur_enabled(rule) + + +def _rule_blur_enabled(rule: KdlNode | None) -> bool: + if rule is None: + return False + effect = _background_effect(rule) + if effect is None: + return False + blur = effect.get_child("blur") + return blur is not None and (not blur.args or blur.args[0] is True) + + +def set_global_window_blur(nodes: list[KdlNode], enabled: bool) -> None: + if enabled: + rule = _ensure_global_window_rule(nodes) + if _rule_opacity(rule) >= 1.0: + set_child_arg(rule, "opacity", 0.9) + effect = _ensure_background_effect(rule) + set_child_arg(effect, "blur", True) + _finalize_window_rule(rule) + return + + existing_rule = _global_window_rule(nodes) + if existing_rule is None: + return + existing_effect = _background_effect(existing_rule) + if existing_effect is not None: + remove_child(existing_effect, "blur") + _remove_background_effect_if_empty(existing_rule) + remove_child(existing_rule, "opacity") + _finalize_window_rule(existing_rule) + _remove_rule_if_empty(nodes, existing_rule) + + +def set_focused_window_blur(nodes: list[KdlNode], enabled: bool) -> None: + if enabled: + rule = _ensure_focused_window_rule(nodes) + + effect = _ensure_background_effect(rule) + set_child_arg(effect, "blur", True) + _finalize_window_rule(rule) + return + + existing_rule = _focused_window_rule(nodes) + if existing_rule is None: + return + existing_effect = _background_effect(existing_rule) + if existing_effect is not None: + remove_child(existing_effect, "blur") + _remove_background_effect_if_empty(existing_rule) + _finalize_window_rule(existing_rule) + if len(existing_rule.children) == 1 and existing_rule.get_child("match"): + nodes.remove(existing_rule) + + +def global_window_xray_enabled(nodes: list[KdlNode]) -> bool: + rule = _global_window_rule(nodes) + if rule is None: + return True + effect = _background_effect(rule) + if effect is None: + return True + xray = effect.get_child("xray") + return xray is None or not xray.args or xray.args[0] is True + + +def set_global_window_xray(nodes: list[KdlNode], enabled: bool) -> None: + rule = _ensure_global_window_rule(nodes) + effect = _ensure_background_effect(rule) + set_child_arg(effect, "xray", enabled) + _finalize_window_rule(rule) + + +def get_global_window_opacity(nodes: list[KdlNode]) -> float: + return _rule_opacity(_global_window_rule(nodes)) + + +def set_global_window_opacity(nodes: list[KdlNode], opacity: float) -> None: + rule = _ensure_global_window_rule(nodes) + if opacity < 1.0: + set_child_arg(rule, "opacity", round(opacity, 2)) + else: + remove_child(rule, "opacity") + _finalize_window_rule(rule) + _remove_rule_if_empty(nodes, rule) + + +def get_global_corner_radius(nodes: list[KdlNode]) -> int: + rule = _global_window_rule(nodes) + if rule is None: + return 0 + value = rule.child_arg("geometry-corner-radius", 0) + try: + return int(value) + except (TypeError, ValueError): + return 0 + + +def set_global_corner_radius(nodes: list[KdlNode], radius: int) -> None: + rule = _ensure_global_window_rule(nodes) + if radius > 0: + set_child_arg(rule, "geometry-corner-radius", radius) + set_child_arg(rule, "clip-to-geometry", True) + else: + remove_child(rule, "geometry-corner-radius") + remove_child(rule, "clip-to-geometry") + _finalize_window_rule(rule) + _remove_rule_if_empty(nodes, rule) diff --git a/nirimod/xkb_helper.py b/nirimod/xkb_helper.py new file mode 100644 index 0000000..65224b3 --- /dev/null +++ b/nirimod/xkb_helper.py @@ -0,0 +1,168 @@ +import ctypes +import ctypes.util +import os +import xml.etree.ElementTree as ET + +class XkbHelper: + def __init__(self): + self.lib = None + self.ctx = None + self.keymap = None + self.state = None + + path = ctypes.util.find_library("xkbcommon") + if not path: + + for p in [ + "/usr/lib/libxkbcommon.so.0", + "/usr/lib64/libxkbcommon.so.0", + "/lib/x86_64-linux-gnu/libxkbcommon.so.0", + "/usr/lib/x86_64-linux-gnu/libxkbcommon.so.0", + + "/usr/lib/libxkbcommon.so", + "/usr/lib64/libxkbcommon.so", + + "/lib/libxkbcommon.so.0", + + "/run/current-system/sw/lib/libxkbcommon.so.0", + ]: + if os.path.exists(p): + path = p + break + + if not path: + return + + try: + self.lib = ctypes.CDLL(path) + + # Prototypes + self.lib.xkb_context_new.restype = ctypes.c_void_p + self.lib.xkb_keymap_new_from_names.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int] + self.lib.xkb_keymap_new_from_names.restype = ctypes.c_void_p + self.lib.xkb_state_new.argtypes = [ctypes.c_void_p] + self.lib.xkb_state_new.restype = ctypes.c_void_p + self.lib.xkb_state_key_get_utf8.argtypes = [ctypes.c_void_p, ctypes.c_uint32, ctypes.c_char_p, ctypes.c_size_t] + self.lib.xkb_state_key_get_utf8.restype = ctypes.c_int + + self.lib.xkb_state_key_get_one_sym.argtypes = [ctypes.c_void_p, ctypes.c_uint32] + self.lib.xkb_state_key_get_one_sym.restype = ctypes.c_uint32 + + self.lib.xkb_keysym_get_name.argtypes = [ctypes.c_uint32, ctypes.c_char_p, ctypes.c_size_t] + self.lib.xkb_keysym_get_name.restype = ctypes.c_int + + self.lib.xkb_keymap_unref.argtypes = [ctypes.c_void_p] + self.lib.xkb_keymap_unref.restype = None + self.lib.xkb_state_unref.argtypes = [ctypes.c_void_p] + self.lib.xkb_state_unref.restype = None + + self.ctx = self.lib.xkb_context_new(0) + except Exception: + self.lib = None + + class XkbRuleNames(ctypes.Structure): + _fields_ = [ + ("rules", ctypes.c_char_p), + ("model", ctypes.c_char_p), + ("layout", ctypes.c_char_p), + ("variant", ctypes.c_char_p), + ("options", ctypes.c_char_p), + ] + + def set_layout(self, layout_id: str): + if not self.lib or not self.ctx: + return + + parts = layout_id.split(":", 1) + layout_name = parts[0] + variant_name = parts[1] if len(parts) > 1 else "" + + self._layout_bytes = layout_name.encode() + self._variant_bytes = variant_name.encode() if variant_name else None + names = self.XkbRuleNames(None, None, self._layout_bytes, self._variant_bytes, None) + + if self.state: + self.lib.xkb_state_unref(self.state) + self.state = None + if self.keymap: + self.lib.xkb_keymap_unref(self.keymap) + self.keymap = None + + self.keymap = self.lib.xkb_keymap_new_from_names(self.ctx, ctypes.byref(names), 0) + if self.keymap: + self.state = self.lib.xkb_state_new(self.keymap) + + def get_label(self, keycode: int) -> str | None: + if not self.state: + return None + + + xkb_keycode = keycode + 8 + + buf = ctypes.create_string_buffer(32) + res = self.lib.xkb_state_key_get_utf8(self.state, xkb_keycode, buf, 32) + if res > 0: + return buf.value.decode('utf-8') + return None + + def get_keysym_name(self, keycode: int) -> str | None: + if not self.state: + return None + + xkb_keycode = keycode + 8 + sym = self.lib.xkb_state_key_get_one_sym(self.state, xkb_keycode) + if sym == 0: + return None + + buf = ctypes.create_string_buffer(64) + res = self.lib.xkb_keysym_get_name(sym, buf, 64) + if res >= 0: + return buf.value.decode('utf-8') + return None + + @staticmethod + def get_available_layouts() -> list[tuple[str, str]]: + + paths = [ + "/usr/share/X11/xkb/rules/evdev.xml", + "/usr/share/X11/xkb/rules/base.xml", + + "/usr/share/xkb/rules/evdev.xml", + "/usr/share/xkb/rules/base.xml", + + "/run/current-system/sw/share/X11/xkb/rules/evdev.xml", + ] + layouts = [] + for p in paths: + if os.path.exists(p): + try: + tree = ET.parse(p) + root = tree.getroot() + for layout in root.findall(".//layout"): + config = layout.find("configItem") + if config is not None: + name = config.findtext("name") + desc = config.findtext("description") + if name and desc: + layouts.append((name, desc)) + + + variant_list = layout.find("variantList") + if variant_list is not None: + for variant in variant_list.findall("variant"): + v_config = variant.find("configItem") + if v_config is not None: + v_name = v_config.findtext("name") + v_desc = v_config.findtext("description") + if name and v_name and v_desc: + layouts.append((f"{name}:{v_name}", v_desc)) + + if layouts: + # Sort by description + layouts.sort(key=lambda x: x[1]) + return layouts + except Exception: + continue + + + return [("us", "English (US)"), ("us:dvorak", "English (Dvorak)"), ("it", "Italian"), ("fr", "French"), ("de", "German"), ("es", "Spanish")] diff --git a/package.nix b/package.nix new file mode 100644 index 0000000..b8ec722 --- /dev/null +++ b/package.nix @@ -0,0 +1,78 @@ +{ + lib, + python3Packages, + wrapGAppsHook4, + gtk4, + libadwaita, + gdk-pixbuf, + gobject-introspection, + hicolor-icon-theme, + desktop-file-utils, +}: + +python3Packages.buildPythonApplication (finalAttrs: { + pname = "nirimod"; + version = "0.1.0"; + + pyproject = true; + + src = lib.cleanSource ./.; + # For nixpkgs: replace with fetchFromGitHub pointing to a release tag: + # src = fetchFromGitHub { + # owner = "srinivasr"; + # repo = "nirimod"; + # tag = "v${finalAttrs.version}"; + # hash = "sha256-..."; + # }; + + nativeBuildInputs = [ + wrapGAppsHook4 + gobject-introspection + desktop-file-utils + ]; + + build-system = with python3Packages; [ + hatchling + ]; + + buildInputs = [ + gtk4 + libadwaita + gdk-pixbuf + hicolor-icon-theme + ]; + + dependencies = with python3Packages; [ + pygobject3 + ]; + + postInstall = '' + install -Dm644 data/nirimod.svg $out/share/icons/hicolor/scalable/apps/nirimod.svg + + mkdir -p $out/share/applications + cat > $out/share/applications/io.github.nirimod.desktop << EOF + [Desktop Entry] + Version=1.0 + Name=NiriMod + GenericName=Compositor Settings + Comment=GUI Configuration Manager for the Niri Wayland Compositor + Exec=nirimod + Icon=nirimod + Terminal=false + Type=Application + Categories=Utility;Settings;DesktopSettings; + Keywords=compositor;windowmanager;wayland;niri;settings;config; + StartupNotify=true + StartupWMClass=nirimod + EOF + ''; + + meta = { + description = "A polished GTK4/libadwaita GUI configurator for the niri Wayland compositor"; + homepage = "https://github.com/srinivasr/nirimod"; + license = lib.licenses.mit; + maintainers = [ ]; + mainProgram = "nirimod"; + platforms = lib.platforms.linux; + }; +}) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..06e89f2 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,34 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "nirimod" +version = "0.1.0" +description = "A polished GTK4/libadwaita GUI configurator for the niri Wayland compositor" +readme = "README.md" +license = "MIT" +requires-python = ">=3.12" +dependencies = [ + # PyGObject (gi.repository.Gtk, Adw) must be installed via system package manager: + # Arch: sudo pacman -S python-gobject gtk4 libadwaita + # Fedora: sudo dnf install python3-gobject gtk4 libadwaita + # Ubuntu: sudo apt install python3-gi gir1.2-gtk-4.0 gir1.2-adw-1 +] + +[project.scripts] +nirimod = "nirimod.__main__:main" + +[tool.hatch.build.targets.wheel] +packages = ["nirimod"] + +[tool.ruff] +ignore = ["E402"] + +[tool.uv] +python-preference = "system" + +[dependency-groups] +dev = [ + "pytest>=9.0.3", +] diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..c6ad5a2 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1 @@ +"""NiriMod test suite.""" diff --git a/tests/test_features.py b/tests/test_features.py new file mode 100644 index 0000000..578fc84 --- /dev/null +++ b/tests/test_features.py @@ -0,0 +1,311 @@ +#!/usr/bin/env python3 +"""Headless feature tests for NiriMod — exercises every page's logic.""" + +import sys +import traceback +import os +os.environ.setdefault("DISPLAY", ":0") +os.environ.setdefault("WAYLAND_DISPLAY", "wayland-1") + +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) +PASS = "[PASS]" +WARN = "[WARN]" +FAIL = "[FAIL]" + +results = [] + +def test(name, fn): + try: + msg = fn() + results.append((PASS, name, msg or "")) + except Exception as e: + results.append((FAIL, name, f"{type(e).__name__}: {e}")) + traceback.print_exc() + + +test.__test__ = False + +# KDL Parser +from nirimod.kdl_parser import parse_kdl, write_kdl, KdlNode + +def t_kdl_roundtrip(): + src = 'output "eDP-1" { scale 2.0; }\nbinds { XF86AudioRaise { action "volume-up"; } }' + nodes = parse_kdl(src) + assert nodes, "no nodes parsed" + return f"{len(nodes)} nodes" + +def t_kdl_include(): + src = 'include "~/.config/niri/dms/monitor.kdl"\nspawn-at-startup "waybar"' + nodes = parse_kdl(src) + names = [n.name for n in nodes] + assert "include" in names + assert "spawn-at-startup" in names + return "include + spawn parsed" + +def t_kdl_nested(): + src = 'window-rule { match app-id="firefox"; open-maximized true; }' + nodes = parse_kdl(src) + assert nodes[0].name == "window-rule" + assert nodes[0].children + return "nested nodes OK" + +def t_kdl_write(): + node = KdlNode("spawn-at-startup", args=["waybar", "--config", "/etc/waybar.json"]) + out = write_kdl([node]) + assert "waybar" in out + return out.strip() + +test("KDL: parse + write roundtrip", t_kdl_roundtrip) +test("KDL: include directive parsing", t_kdl_include) +test("KDL: nested children parsing", t_kdl_nested) +test("KDL: write KdlNode with args", t_kdl_write) + +# AppState +from nirimod.state import AppState + +def t_state_load(): + s = AppState() + s.load() + assert isinstance(s.nodes, list) + return f"{len(s.nodes)} top-level nodes loaded" + +def t_state_dirty(): + s = AppState() + s.load() + assert not s.is_dirty + s.mark_dirty() + assert s.is_dirty + s.mark_clean() + assert not s.is_dirty + return "dirty/clean flags OK" + +def t_state_discard(): + s = AppState() + s.load() + original_len = len(s.nodes) + s.nodes.append(KdlNode("test-node")) + s.mark_dirty() + s.discard() + assert len(s.nodes) == original_len + return f"discarded back to {original_len} nodes" + +def t_state_undo(): + s = AppState() + s.load() + before = write_kdl(s.nodes) + s.nodes.append(KdlNode("test-undo-node")) + after = write_kdl(s.nodes) + s.push_undo("add test node", before, after) + assert s.undo.can_undo() + entry = s.apply_undo() + assert entry is not None + assert "test-undo-node" not in write_kdl(s.nodes) + return "undo restored previous state" + +test("AppState: load from disk", t_state_load) +test("AppState: dirty / clean flags", t_state_dirty) +test("AppState: discard reverts nodes", t_state_discard) +test("AppState: undo stack push+pop", t_state_undo) + +# Undo Manager +from nirimod.undo import UndoManager, UndoEntry + +def t_undo_redo(): + m = UndoManager() + m.push(UndoEntry("step1", "before1", "after1")) + m.push(UndoEntry("step2", "before2", "after2")) + assert m.can_undo() + e = m.pop_undo() + assert e.description == "step2" + assert m.can_redo() + e2 = m.pop_redo() + assert e2.description == "step2" + return "undo→redo cycle OK" + +test("UndoManager: push/pop/redo", t_undo_redo) + +# Profiles +from nirimod import profiles as prof_mod + +def t_profiles_list(): + names = prof_mod.list_profiles() + assert isinstance(names, list) + return f"{len(names)} profiles found" + +def t_profiles_save_delete(): + s = AppState() + s.load() + # save_profile takes name + optional set[Path] of source files + prof_mod.save_profile("__test_profile__", s.source_files) + names = prof_mod.list_profiles() + assert "__test_profile__" in names, f"profile not found in {names}" + prof_mod.delete_profile("__test_profile__") + assert "__test_profile__" not in prof_mod.list_profiles() + return "save + delete profile OK" + +test("Profiles: list", t_profiles_list) +test("Profiles: save and delete", t_profiles_save_delete) + +# Pages (import + build check) +# We test imports and logic only — no GTK widget creation without display +page_modules = [ + ("appearance", "nirimod.pages.appearance"), + ("animations", "nirimod.pages.animations"), + ("layout", "nirimod.pages.layout"), + ("startup", "nirimod.pages.startup"), + ("environment","nirimod.pages.environment"), + ("workspaces", "nirimod.pages.workspaces"), + ("window_rules","nirimod.pages.window_rules"), + ("bindings", "nirimod.pages.bindings"), + ("outputs", "nirimod.pages.outputs"), + ("input_page", "nirimod.pages.input_page"), + ("gestures", "nirimod.pages.gestures"), + ("raw_config", "nirimod.pages.raw_config"), +] + +import importlib +for name, module_path in page_modules: + def _test(mp=module_path, n=name): + importlib.import_module(mp) + return "module imported OK" + test(f"Page import: {name}", _test) + +# Startup page logic +import shlex + +def t_startup_spawn_sh(): + cmd = "waybar --config /etc/waybar.json" + node = KdlNode("spawn-sh-at-startup", args=[cmd]) # single string for sh + assert node.args[0] == cmd + return f"spawn-sh-at-startup args = {node.args}" + +def t_startup_spawn_direct(): + cmd = "dunst" + args = shlex.split(cmd) + node = KdlNode("spawn-at-startup", args=args) + assert node.args == ["dunst"] + return "spawn-at-startup args OK" + +test("Startup: spawn-sh-at-startup node", t_startup_spawn_sh) +test("Startup: spawn-at-startup node", t_startup_spawn_direct) + +# Animations curve serialization +def t_anim_curve_format(): + # The correct niri format is: curve "cubic-bezier" 0.25 0.1 0.25 1.0 + kdl = 'animations { workspace-switch { spring damping-ratio=1.0; } }' + nodes = parse_kdl(kdl) + out = write_kdl(nodes) + assert "workspace-switch" in out + return "animation node roundtrip OK" + +test("Animations: curve node roundtrip", t_anim_curve_format) + +# Environment page logic +def t_env_node(): + node = KdlNode("environment", children=[ + KdlNode("WAYLAND_DISPLAY", args=["wayland-1"]) + ]) + out = write_kdl([node]) + assert "WAYLAND_DISPLAY" in out + return out.strip() + +test("Environment: env var node write", t_env_node) + +# Window rules logic +def t_window_rule_node(): + kdl = 'window-rule { match app-id="org.gnome.Calculator"; open-floating true; }' + nodes = parse_kdl(kdl) + assert nodes[0].name == "window-rule" + children_names = [c.name for c in nodes[0].children] + assert "match" in children_names + assert "open-floating" in children_names + return f"children: {children_names}" + +test("Window Rules: parse match+action", t_window_rule_node) + +# Output node +def t_output_node(): + kdl = 'output "eDP-1" { scale 1.5; transform "90"; mode "1920x1080@60"; }' + nodes = parse_kdl(kdl) + assert nodes[0].name == "output" + assert nodes[0].args == ["eDP-1"] + children = {c.name: c for c in nodes[0].children} + assert "scale" in children + assert float(children["scale"].args[0]) == 1.5 + return "output node parsed OK" + +test("Outputs: parse output node", t_output_node) + +# Bindings logic +def t_binds_node(): + kdl = 'binds { Mod+T { action spawn "alacritty"; } Mod+Q { action close-window; } }' + nodes = parse_kdl(kdl) + assert nodes[0].name == "binds" + assert len(nodes[0].children) == 2 + return f"{len(nodes[0].children)} binds found" + +test("Bindings: parse binds block", t_binds_node) + +# Workspaces logic +def t_workspaces_node(): + kdl = 'workspaces { workspace "Browser"; workspace "Terminal"; }' + nodes = parse_kdl(kdl) + assert nodes[0].name == "workspaces" + return f"{len(nodes[0].children)} workspaces" + +test("Workspaces: parse workspace names", t_workspaces_node) + +# NiriIPC +from nirimod import niri_ipc + +def t_ipc_is_running(): + result = niri_ipc.is_niri_running() + assert isinstance(result, bool) + return f"niri running = {result}" + +def t_ipc_has_touchpad(): + result = niri_ipc.has_touchpad() + assert isinstance(result, bool) + return f"has touchpad = {result}" + +test("NiriIPC: is_niri_running()", t_ipc_is_running) +test("NiriIPC: has_touchpad()", t_ipc_has_touchpad) + +# AppSettings +from nirimod import app_settings + +def t_app_settings(): + original = app_settings.get("auto_update", True) + app_settings.set("auto_update", False) + assert not app_settings.get("auto_update") + app_settings.set("auto_update", original) + return "get/set OK" + +test("AppSettings: get/set", t_app_settings) + +def _print_results() -> int: + print("\n" + "="*50) + print(" NIRIMOD FEATURE TEST REPORT") + print("="*50) + + passed = sum(1 for r in results if r[0] == PASS) + failed = sum(1 for r in results if r[0] == FAIL) + warned = sum(1 for r in results if r[0] == WARN) + + for icon, name, detail in results: + status = f"{icon} {name}" + if detail: + print(f"{status}\n → {detail}") + else: + print(status) + + print("="*50) + print( + f" {passed} passed | {warned} warnings | {failed} failed | {len(results)} total" + ) + print("="*50) + return failed + + +if __name__ == "__main__": + sys.exit(1 if _print_results() else 0) diff --git a/tests/test_ipc.py b/tests/test_ipc.py new file mode 100644 index 0000000..a9c59cf --- /dev/null +++ b/tests/test_ipc.py @@ -0,0 +1,192 @@ +"""Unit tests for the niri IPC wrappers. + +Tests the synchronous helpers and validates that the non-blocking async +dispatch functions are wired correctly, using mocks to avoid requiring +a live niri compositor. +""" + +from __future__ import annotations + +import unittest +from unittest.mock import patch + + +class TestRunSync(unittest.TestCase): + """Tests for the internal _run_sync helper.""" + + def test_command_not_found(self): + from nirimod.niri_ipc import _run_sync + + stdout, stderr, rc = _run_sync(["__nonexistent_binary_xyz__"]) + self.assertEqual(rc, 1) + self.assertIn("not found", stderr) + + def test_successful_command(self): + from nirimod.niri_ipc import _run_sync + + stdout, stderr, rc = _run_sync(["echo", "hello"]) + self.assertEqual(rc, 0) + self.assertIn("hello", stdout) + + def test_timeout(self): + from nirimod.niri_ipc import _run_sync + + stdout, stderr, rc = _run_sync(["sleep", "10"], timeout=0.01) + self.assertEqual(rc, 1) + self.assertIn("timed out", stderr) + + +class TestIsNiriRunning(unittest.TestCase): + def test_returns_false_when_niri_absent(self): + from nirimod import niri_ipc + + with patch.object(niri_ipc, "_run_sync", return_value=("", "not found", 1)): + self.assertFalse(niri_ipc.is_niri_running()) + + def test_returns_true_when_niri_present(self): + from nirimod import niri_ipc + + with patch.object(niri_ipc, "_run_sync", return_value=("niri 1.0\n", "", 0)): + self.assertTrue(niri_ipc.is_niri_running()) + + +class TestValidateConfig(unittest.TestCase): + def test_valid_config(self): + from nirimod import niri_ipc + + with patch.object(niri_ipc, "_run_sync", return_value=("Config is valid.\n", "", 0)): + ok, msg = niri_ipc.validate_config() + self.assertTrue(ok) + self.assertIn("valid", msg.lower()) + + def test_invalid_config(self): + from nirimod import niri_ipc + + with patch.object(niri_ipc, "_run_sync", return_value=("", "parse error line 3", 1)): + ok, msg = niri_ipc.validate_config() + self.assertFalse(ok) + self.assertIn("parse error", msg) + + def test_with_config_path(self): + from nirimod import niri_ipc + + captured = {} + + def fake_run(args, timeout=5.0): + captured["args"] = args + return ("ok", "", 0) + + with patch.object(niri_ipc, "_run_sync", side_effect=fake_run): + niri_ipc.validate_config("/tmp/test.kdl") + + self.assertIn("--config", captured["args"]) + self.assertIn("/tmp/test.kdl", captured["args"]) + + +class TestLoadConfigFile(unittest.TestCase): + def test_load_config_file_calls_niri_action(self): + from nirimod import niri_ipc + + captured = {} + + def fake_run(args, timeout=5.0): + captured["args"] = args + captured["timeout"] = timeout + return ("", "", 0) + + with patch.object(niri_ipc, "_run_sync", side_effect=fake_run): + ok, msg = niri_ipc.load_config_file() + + self.assertTrue(ok) + self.assertEqual(captured["args"], ["niri", "msg", "action", "load-config-file"]) + self.assertEqual(captured["timeout"], 10.0) + self.assertIn("applied", msg) + + def test_load_config_file_reports_failure(self): + from nirimod import niri_ipc + + with patch.object(niri_ipc, "_run_sync", return_value=("", "reload failed", 1)): + ok, msg = niri_ipc.load_config_file() + + self.assertFalse(ok) + self.assertIn("reload failed", msg) + + +class TestHasTouchpad(unittest.TestCase): + def test_caching(self): + import nirimod.niri_ipc as ipc_mod + + # Clear any existing cache + ipc_mod._touchpad_cache = None + + call_count = [0] + + original_listdir = __import__("os").listdir + + def fake_listdir(path): + if path == "/sys/class/input": + call_count[0] += 1 + return [] + return original_listdir(path) + + with patch("os.listdir", side_effect=fake_listdir): + ipc_mod.has_touchpad() + ipc_mod.has_touchpad() + + # Second call should use cache, so listdir only called once + self.assertEqual(call_count[0], 1) + + # Clean up for other tests + ipc_mod._touchpad_cache = None + + +class TestGetVersion(unittest.TestCase): + def test_returns_version_string(self): + from nirimod import niri_ipc + + with patch.object(niri_ipc, "_run_sync", return_value=("niri 1.2.3\n", "", 0)): + v = niri_ipc.get_version() + self.assertEqual(v, "niri 1.2.3") + + def test_returns_unknown_on_failure(self): + from nirimod import niri_ipc + + with patch.object(niri_ipc, "_run_sync", return_value=("", "error", 1)): + v = niri_ipc.get_version() + self.assertEqual(v, "unknown") + + +class TestRunInThread(unittest.TestCase): + """Compatibility shim run_in_thread should invoke callback.""" + + def test_shim_calls_callback(self): + from nirimod import niri_ipc + + try: + import gi + gi.require_version("GLib", "2.0") + from gi.repository import GLib + except (ModuleNotFoundError, Exception): + self.skipTest("gi (PyGObject) not available in this test environment") + + results = [] + + original_idle_add = GLib.idle_add + + def sync_idle_add(fn, *args): + fn(*args) + return 0 + + GLib.idle_add = sync_idle_add + try: + t = niri_ipc.run_in_thread(lambda: 42, lambda r: results.append(r)) + t.join(timeout=2.0) + finally: + GLib.idle_add = original_idle_add + + self.assertEqual(results, [42]) + + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_kdl_parser.py b/tests/test_kdl_parser.py new file mode 100644 index 0000000..6a9380a --- /dev/null +++ b/tests/test_kdl_parser.py @@ -0,0 +1,202 @@ +"""Unit tests for the KDL parser and writer. + +Tests the core parse → mutate → write round-trip logic that underpins +all config changes in NiriMod. +""" + +from __future__ import annotations + +import unittest + +from nirimod.kdl_parser import ( + KdlNode, + KdlRawString, + find_or_create, + parse_kdl, + remove_child, + set_child_arg, + set_node_flag, + write_kdl, +) + + +class TestKdlRoundTrip(unittest.TestCase): + """parse_kdl → write_kdl should produce semantically equivalent output.""" + + def _roundtrip(self, text: str) -> list[KdlNode]: + nodes = parse_kdl(text) + out = write_kdl(nodes) + return parse_kdl(out) + + def test_simple_node(self): + nodes = parse_kdl("prefer-no-csd\n") + self.assertEqual(len(nodes), 1) + self.assertEqual(nodes[0].name, "prefer-no-csd") + + def test_node_with_string_arg(self): + nodes = parse_kdl('output "eDP-1" {\n scale 2.0\n}\n') + self.assertEqual(nodes[0].name, "output") + self.assertEqual(nodes[0].args[0], "eDP-1") + scale = nodes[0].get_child("scale") + self.assertIsNotNone(scale) + self.assertAlmostEqual(scale.args[0], 2.0) + + def test_boolean_values(self): + nodes = parse_kdl( + "input {\n keyboard {\n repeat-rate 30\n xkb-numlock true\n }\n}\n" + ) + kb = nodes[0].get_child("keyboard") + self.assertIsNotNone(kb) + numlock = kb.get_child("xkb-numlock") + self.assertIsNotNone(numlock) + self.assertIs(numlock.args[0], True) + + def test_raw_string(self): + text = "spawn-at-startup r#\"bash -c 'echo hi'\"#\n" + nodes = parse_kdl(text) + self.assertIsInstance(nodes[0].args[0], KdlRawString) + + def test_raw_string_property_preserves_backslash(self): + src = 'match app-id="steam" title=r#"^notificationtoasts_\\d+_desktop$"#\n' + nodes = parse_kdl(src) + title = nodes[0].props["title"] + self.assertIsInstance(title, KdlRawString) + self.assertEqual(title, r"^notificationtoasts_\d+_desktop$") + self.assertIn(r'title=r"^notificationtoasts_\d+_desktop$"', write_kdl(nodes)) + + def test_write_preserves_children(self): + src = "layout {\n gaps 16\n border {\n width 2\n }\n}\n" + nodes = self._roundtrip(src) + layout = nodes[0] + self.assertEqual(layout.name, "layout") + border = layout.get_child("border") + self.assertIsNotNone(border) + self.assertEqual(border.get_child("width").args[0], 2) + + def test_null_value(self): + nodes = parse_kdl("cursor-warps null\n") + self.assertIsNone(nodes[0].args[0]) + + def test_props(self): + nodes = parse_kdl("position x=0 y=1080\n") + self.assertEqual(nodes[0].props["x"], 0) + self.assertEqual(nodes[0].props["y"], 1080) + + def test_empty_input(self): + nodes = parse_kdl("") + self.assertEqual(nodes, []) + self.assertIn("NiriMod", write_kdl(nodes)) + + def test_comments_are_preserved_as_trivia(self): + src = "// top-level comment\nprefer-no-csd\n" + out = write_kdl(parse_kdl(src)) + self.assertIn("prefer-no-csd", out) + + +class TestMutationHelpers(unittest.TestCase): + """Tests for find_or_create, set_child_arg, remove_child, set_node_flag.""" + + def setUp(self): + self.nodes = parse_kdl("layout {\n gaps 8\n}\n") + + def test_find_existing(self): + node = find_or_create(self.nodes, "layout") + self.assertEqual(node.name, "layout") + + def test_create_missing(self): + node = find_or_create(self.nodes, "input") + self.assertEqual(node.name, "input") + self.assertIn(node, self.nodes) + + def test_find_or_create_nested(self): + node = find_or_create(self.nodes, "layout", "struts") + self.assertEqual(node.name, "struts") + + def test_set_child_arg_creates(self): + parent = self.nodes[0] + set_child_arg(parent, "border-rule", 4) + child = parent.get_child("border-rule") + self.assertIsNotNone(child) + self.assertEqual(child.args[0], 4) + + def test_set_child_arg_updates(self): + parent = self.nodes[0] + set_child_arg(parent, "gaps", 16) + self.assertEqual(parent.get_child("gaps").args[0], 16) + + def test_remove_child(self): + parent = self.nodes[0] + remove_child(parent, "gaps") + self.assertIsNone(parent.get_child("gaps")) + + def test_remove_nonexistent_is_noop(self): + parent = self.nodes[0] + remove_child(parent, "nonexistent") + self.assertEqual(len(parent.children), 1) + + def test_set_node_flag_add(self): + parent = KdlNode("input") + set_node_flag(parent, "warp-mouse-to-focus", True) + self.assertIsNotNone(parent.get_child("warp-mouse-to-focus")) + self.assertEqual(parent.get_child("warp-mouse-to-focus").args, []) + + def test_set_node_flag_serializes_bare_flag(self): + parent = KdlNode("blur") + + set_node_flag(parent, "off", True) + + self.assertIn("off", write_kdl([parent])) + self.assertNotIn("off true", write_kdl([parent])) + + def test_set_node_flag_remove(self): + parent = KdlNode("input") + parent.children.append(KdlNode("warp-mouse-to-focus")) + set_node_flag(parent, "warp-mouse-to-focus", False) + self.assertIsNone(parent.get_child("warp-mouse-to-focus")) + + def test_set_node_flag_restores_bare_flag(self): + parent = KdlNode("blur") + parent.children.append(KdlNode("off")) + + set_node_flag(parent, "off", False) + set_node_flag(parent, "off", True) + + self.assertIn("off", write_kdl([parent])) + self.assertNotIn("off true", write_kdl([parent])) + + def test_set_node_flag_idempotent_add(self): + parent = KdlNode("input") + set_node_flag(parent, "warp-mouse-to-focus", True) + set_node_flag(parent, "warp-mouse-to-focus", True) + count = sum(1 for c in parent.children if c.name == "warp-mouse-to-focus") + self.assertEqual(count, 1) + + +class TestWriteKdl(unittest.TestCase): + """Tests for the KDL serializer.""" + + def test_write_empty(self): + out = write_kdl([]) + self.assertIn("NiriMod", out) + + def test_write_simple(self): + nodes = [KdlNode("prefer-no-csd")] + out = write_kdl(nodes) + self.assertIn("prefer-no-csd", out) + + def test_write_raw_string(self): + # A value containing a double-quote triggers the hash-delimited r#"..."# form + node = KdlNode("env", args=[KdlRawString('value with "double" quotes')]) + out = write_kdl([node]) + self.assertIn('r#"', out) + + def test_write_nested(self): + parent = KdlNode("layout") + parent.children.append(KdlNode("gaps", args=[16])) + out = write_kdl([parent]) + self.assertIn("gaps", out) + self.assertIn("16", out) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_state.py b/tests/test_state.py new file mode 100644 index 0000000..748eef0 --- /dev/null +++ b/tests/test_state.py @@ -0,0 +1,162 @@ +"""Unit tests for the AppState manager. + +Tests state initialization, dirty tracking, undo/redo integration, +commit_save, discard, and node serialization helpers — without requiring +a live GTK session or filesystem access. +""" + +from __future__ import annotations + +import unittest +from unittest.mock import patch + +from nirimod.kdl_parser import KdlNode, KdlRawString, parse_kdl, write_kdl +from nirimod.state import AppState + + +class TestAppStateInit(unittest.TestCase): + """AppState starts in a clean, non-dirty state.""" + + def test_initial_state(self): + state = AppState() + self.assertEqual(state.nodes, []) + self.assertEqual(state.saved_kdl, "") + self.assertFalse(state.is_dirty) + self.assertFalse(state.niri_running) + self.assertFalse(state.has_touchpad) + + def test_initial_undo_empty(self): + state = AppState() + self.assertFalse(state.undo.can_undo()) + self.assertFalse(state.undo.can_redo()) + + +class TestDirtyTracking(unittest.TestCase): + def test_mark_dirty(self): + state = AppState() + self.assertFalse(state.is_dirty) + state.mark_dirty() + self.assertTrue(state.is_dirty) + + def test_mark_clean(self): + state = AppState() + state.mark_dirty() + state.mark_clean() + self.assertFalse(state.is_dirty) + + +class TestUndoRedo(unittest.TestCase): + def _make_state_with_nodes(self, kdl: str) -> AppState: + state = AppState() + state.nodes = parse_kdl(kdl) + state._saved_kdl = kdl + return state + + def test_push_and_apply_undo(self): + state = self._make_state_with_nodes("gaps 8\n") + before = "gaps 8\n" + after = "gaps 16\n" + state.push_undo("change gaps", before, after) + self.assertTrue(state.undo.can_undo()) + + entry = state.apply_undo() + self.assertIsNotNone(entry) + self.assertEqual(state.nodes[0].get_child("gaps") if state.nodes and state.nodes[0].children else None, None) + # After undo, nodes should be from the 'before' snapshot + kdl_out = write_kdl(state.nodes) + self.assertIn("8", kdl_out) + + def test_apply_undo_empty_returns_none(self): + state = AppState() + result = state.apply_undo() + self.assertIsNone(result) + + def test_apply_redo_empty_returns_none(self): + state = AppState() + result = state.apply_redo() + self.assertIsNone(result) + + def test_undo_sets_dirty(self): + state = self._make_state_with_nodes("gaps 8\n") + state.push_undo("x", "gaps 16\n", "gaps 24\n") + state.apply_undo() + self.assertTrue(state.is_dirty) + + def test_redo_after_undo(self): + state = self._make_state_with_nodes("gaps 8\n") + state.push_undo("x", "gaps 8\n", "gaps 16\n") + state.apply_undo() + self.assertTrue(state.undo.can_redo()) + entry = state.apply_redo() + self.assertIsNotNone(entry) + kdl_out = write_kdl(state.nodes) + self.assertIn("16", kdl_out) + + +class TestCommitSave(unittest.TestCase): + def test_commit_save_clears_undo_and_dirty(self): + state = AppState() + state.push_undo("x", "a", "b") + state.mark_dirty() + state.commit_save("new kdl\n") + self.assertEqual(state.saved_kdl, "new kdl\n") + self.assertFalse(state.is_dirty) + self.assertFalse(state.undo.can_undo()) + + +class TestDiscard(unittest.TestCase): + def test_discard_restores_saved_kdl(self): + state = AppState() + state._saved_kdl = "gaps 8\n" + state.nodes = parse_kdl("gaps 16\n") + state.mark_dirty() + state.push_undo("x", "gaps 8\n", "gaps 16\n") + + state.discard() + + self.assertFalse(state.is_dirty) + self.assertFalse(state.undo.can_undo()) + kdl_out = write_kdl(state.nodes) + self.assertIn("8", kdl_out) + + def test_discard_empty_saved_kdl(self): + state = AppState() + state._saved_kdl = "" + state.discard() + self.assertEqual(state.nodes, []) + + +class TestWriteCurrentKdl(unittest.TestCase): + def test_write_current_kdl(self): + state = AppState() + state.nodes = [KdlNode("prefer-no-csd")] + out = state.write_current_kdl() + self.assertIn("prefer-no-csd", out) + + def test_write_raw_string(self): + # A string containing a double-quote forces the hash-delimited raw form + node = KdlNode("env", args=[KdlRawString('has "double" quotes')]) + out = write_kdl([node]) + self.assertIn('r#"', out) + + +class TestLoad(unittest.TestCase): + def test_load_detects_runtime(self): + state = AppState() + # state.py does: from nirimod import niri_ipc + # We patch at the canonical module location so all references see the mock. + with ( + patch("nirimod.niri_ipc.is_niri_running", return_value=True), + patch("nirimod.niri_ipc.has_touchpad", return_value=True), + patch("nirimod.kdl_parser.NIRI_CONFIG") as mock_cfg, + ): + mock_cfg.exists.return_value = False + state.load() + + self.assertTrue(state.niri_running) + self.assertTrue(state.has_touchpad) + self.assertFalse(state.is_dirty) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_updater.py b/tests/test_updater.py new file mode 100644 index 0000000..c262b36 --- /dev/null +++ b/tests/test_updater.py @@ -0,0 +1,116 @@ +"""Unit tests for updater terminal selection.""" + +from __future__ import annotations + +import os +import subprocess +import tempfile +import pytest + +pytest.importorskip("gi") + +import unittest +from unittest.mock import patch + +from nirimod import updater + + +class TestTerminalCandidates(unittest.TestCase): + def test_terminal_env_is_preferred(self): + with patch.dict(os.environ, {"TERMINAL": "ghostty"}, clear=False): + candidates = list(updater._terminal_candidates()) + + self.assertEqual(candidates[0], "ghostty") + self.assertIn("xdg-terminal-exec", candidates) + + def test_ghostty_is_a_fallback_terminal(self): + self.assertIn("ghostty", updater.FALLBACK_TERMINALS) + + +class TestBuildTerminalCommand(unittest.TestCase): + def test_xdg_terminal_exec_gets_script_directly(self): + command = updater._build_terminal_command("xdg-terminal-exec", "/tmp/update.sh") + + self.assertEqual(command, ["xdg-terminal-exec", "/tmp/update.sh"]) + + def test_regular_terminal_uses_execute_flag(self): + command = updater._build_terminal_command("ghostty", "/tmp/update.sh") + + self.assertEqual(command, ["ghostty", "-e", "/tmp/update.sh"]) + + def test_terminal_command_with_existing_execute_flag(self): + command = updater._build_terminal_command( + "ghostty --gtk-single-instance=false -e", "/tmp/update.sh" + ) + + self.assertEqual( + command, ["ghostty", "--gtk-single-instance=false", "-e", "/tmp/update.sh"] + ) + + def test_invalid_terminal_command_is_ignored(self): + command = updater._build_terminal_command("ghostty '", "/tmp/update.sh") + + self.assertIsNone(command) + + +class TestUpdateAvailability(unittest.TestCase): + def _run_git(self, repo: str, *args: str): + return subprocess.run( + ["git", *args], + cwd=repo, + check=True, + capture_output=True, + text=True, + ) + + def _commit(self, repo: str, message: str) -> str: + self._run_git(repo, "commit", "--allow-empty", "-m", message) + return subprocess.check_output( + ["git", "rev-parse", "HEAD"], cwd=repo, text=True + ).strip() + + def _make_repo(self) -> str: + temp_dir = tempfile.TemporaryDirectory() + self.addCleanup(temp_dir.cleanup) + repo = temp_dir.name + self._run_git(repo, "init") + self._run_git(repo, "config", "user.email", "test@example.com") + self._run_git(repo, "config", "user.name", "Test User") + return repo + + def test_branch_ahead_of_remote_main_is_not_update(self): + repo = self._make_repo() + remote_hash = self._commit(repo, "remote main") + local_hash = self._commit(repo, "local branch") + + self.assertFalse(updater._update_available(local_hash, remote_hash, repo)) + + def test_dirty_worktree_still_gets_remote_update(self): + repo = self._make_repo() + local_hash = self._commit(repo, "installed version") + remote_hash = self._commit(repo, "remote main") + self._run_git(repo, "checkout", "--detach", local_hash) + with open(os.path.join(repo, "local-change.txt"), "w") as fh: + fh.write("local edit\n") + + self.assertTrue(updater._update_available(local_hash, remote_hash, repo)) + + +class TestLaunchUpdaterInTerminal(unittest.TestCase): + def test_launch_uses_terminal_env(self): + with ( + tempfile.TemporaryDirectory() as temp_dir, + patch.dict(os.environ, {"TERMINAL": "ghostty"}, clear=False), + patch.object(updater.tempfile, "gettempdir", return_value=temp_dir), + patch.object(updater.shutil, "which", return_value="/usr/bin/ghostty"), + patch.object(updater.subprocess, "Popen") as popen, + ): + updater.launch_updater_in_terminal() + + popen.assert_called_once_with( + ["ghostty", "-e", os.path.join(temp_dir, "nirimod_update.sh")] + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_window_effects.py b/tests/test_window_effects.py new file mode 100644 index 0000000..bdce241 --- /dev/null +++ b/tests/test_window_effects.py @@ -0,0 +1,384 @@ +"""Tests for global window effect rule helpers.""" + +from __future__ import annotations + +import unittest + +from nirimod.kdl_parser import KdlNode, parse_kdl, write_kdl +from nirimod.window_effects import ( + blur_effects_enabled, + focused_window_blur_enabled, + get_global_draw_border_with_background, + get_global_corner_radius, + get_global_window_opacity, + global_window_blur_enabled, + global_window_xray_enabled, + set_focused_window_blur, + set_global_draw_border_with_background, + set_global_corner_radius, + set_global_window_blur, + set_global_window_opacity, + set_global_window_xray, + set_blur_effects_enabled, +) + + +class TestGlobalWindowEffects(unittest.TestCase): + def test_blur_effects_are_enabled_without_top_level_off(self): + nodes = parse_kdl( + """ +blur { + passes 3 + offset 3 +} +""" + ) + + self.assertTrue(blur_effects_enabled(nodes)) + + def test_disabling_blur_effects_writes_top_level_off(self): + nodes: list[KdlNode] = [] + + set_blur_effects_enabled(nodes, False) + + out = write_kdl(nodes) + self.assertIn("blur", out) + self.assertIn("off", out) + self.assertNotIn("off true", out) + self.assertFalse(blur_effects_enabled(nodes)) + + def test_disabling_blur_effects_preserves_quality_settings(self): + nodes = parse_kdl( + """ +blur { + passes 3 + offset 3 + noise 0.02 + saturation 1.5 +} +""" + ) + + set_blur_effects_enabled(nodes, False) + + out = write_kdl(nodes) + self.assertIn("off", out) + self.assertIn("passes 3", out) + self.assertIn("offset 3", out) + self.assertIn("noise 0.02", out) + self.assertIn("saturation 1.5", out) + self.assertNotIn("off true", out) + + def test_enabling_blur_effects_removes_only_off(self): + nodes = parse_kdl( + """ +blur { + off + passes 3 + offset 3 +} +""" + ) + + set_blur_effects_enabled(nodes, True) + + out = write_kdl(nodes) + blur = parse_kdl(out)[0] + self.assertIsNone(blur.get_child("off")) + self.assertIn("passes 3", out) + self.assertIn("offset 3", out) + self.assertTrue(blur_effects_enabled(nodes)) + + def test_enabling_blur_effects_sets_visible_default_opacity_when_unset(self): + nodes = parse_kdl( + """ +blur { + off + passes 3 +} +""" + ) + + set_blur_effects_enabled(nodes, True) + + out = write_kdl(nodes) + self.assertEqual(get_global_window_opacity(nodes), 0.9) + self.assertIn("opacity 0.9", out) + + def test_enabling_blur_effects_preserves_existing_opacity(self): + nodes = parse_kdl( + """ +blur { + off + passes 3 +} +window-rule { + opacity 0.75 +} +""" + ) + + set_blur_effects_enabled(nodes, True) + + self.assertEqual(get_global_window_opacity(nodes), 0.75) + self.assertIn("opacity 0.75", write_kdl(nodes)) + + def test_enabling_blur_creates_matchless_window_rule(self): + nodes: list[KdlNode] = [] + + set_global_window_blur(nodes, True) + + out = write_kdl(nodes) + self.assertIn("window-rule", out) + self.assertIn("background-effect", out) + self.assertIn("blur true", out) + self.assertNotIn("draw-border-with-background", out) + self.assertTrue(global_window_blur_enabled(nodes)) + + def test_enabling_blur_sets_visible_default_opacity_when_unset(self): + nodes: list[KdlNode] = [] + + set_global_window_blur(nodes, True) + + self.assertEqual(get_global_window_opacity(nodes), 0.9) + self.assertIn("opacity 0.9", write_kdl(nodes)) + + def test_enabling_blur_preserves_existing_opacity(self): + nodes = parse_kdl( + """ +window-rule { + opacity 0.75 +} +""" + ) + + set_global_window_blur(nodes, True) + + self.assertEqual(get_global_window_opacity(nodes), 0.75) + self.assertIn("opacity 0.75", write_kdl(nodes)) + + def test_disabling_blur_preserves_other_window_effect_settings(self): + nodes = parse_kdl( + """ +window-rule { + geometry-corner-radius 16 + draw-border-with-background false + background-effect { + blur true + xray false + } +} +""" + ) + + set_global_window_blur(nodes, False) + + rule = nodes[0] + self.assertEqual(rule.child_arg("geometry-corner-radius"), 16) + self.assertIsNotNone(rule.get_child("draw-border-with-background")) + self.assertIsNotNone(rule.get_child("background-effect")) + self.assertIsNone(rule.get_child("background-effect").get_child("blur")) + self.assertIsNotNone(rule.get_child("background-effect").get_child("xray")) + self.assertFalse(global_window_blur_enabled(nodes)) + + def test_disabling_blur_resets_window_opacity(self): + nodes = parse_kdl( + """ +window-rule { + opacity 0.95 + background-effect { + blur true + xray false + } +} +""" + ) + + set_global_window_blur(nodes, False) + + rule = nodes[0] + self.assertEqual(get_global_window_opacity(nodes), 1.0) + self.assertIsNone(rule.get_child("opacity")) + self.assertIsNone(rule.get_child("background-effect").get_child("blur")) + self.assertIsNotNone(rule.get_child("background-effect").get_child("xray")) + + def test_disabling_blur_effects_clears_forced_blur_and_opacity(self): + nodes = parse_kdl( + """ +blur { + passes 3 +} +window-rule { + opacity 0.9 + background-effect { + blur true + xray false + } +} +window-rule { + match is-focused=true + background-effect { + blur true + } +} +""" + ) + + set_blur_effects_enabled(nodes, False) + + out = write_kdl(nodes) + self.assertIn("off", out) + self.assertFalse(blur_effects_enabled(nodes)) + self.assertFalse(global_window_blur_enabled(nodes)) + self.assertFalse(focused_window_blur_enabled(nodes)) + self.assertEqual(get_global_window_opacity(nodes), 1.0) + self.assertNotIn("blur true", out) + self.assertNotIn("opacity 0.9", out) + + def test_corner_radius_writes_clip_and_can_be_removed(self): + nodes: list[KdlNode] = [] + + set_global_corner_radius(nodes, 16) + + self.assertEqual(get_global_corner_radius(nodes), 16) + out = write_kdl(nodes) + self.assertIn("geometry-corner-radius 16", out) + self.assertIn("clip-to-geometry true", out) + + set_global_corner_radius(nodes, 0) + + self.assertEqual(nodes, []) + + def test_matched_rules_are_not_reused_as_global_effect_rules(self): + nodes = parse_kdl( + """ +window-rule { + match app-id="Alacritty" + background-effect { + blur true + } +} +""" + ) + + set_global_corner_radius(nodes, 12) + + self.assertEqual(len([n for n in nodes if n.name == "window-rule"]), 2) + self.assertIsNone(nodes[0].get_child("geometry-corner-radius")) + self.assertEqual(get_global_corner_radius(nodes), 12) + + def test_global_opacity_is_removed_when_opaque(self): + nodes: list[KdlNode] = [] + + set_global_window_opacity(nodes, 0.9) + + self.assertEqual(get_global_window_opacity(nodes), 0.9) + self.assertIn("opacity 0.9", write_kdl(nodes)) + + set_global_window_opacity(nodes, 1.0) + + self.assertEqual(nodes, []) + + def test_draw_border_with_background_can_be_toggled(self): + nodes: list[KdlNode] = [] + + self.assertTrue(get_global_draw_border_with_background(nodes)) + + set_global_draw_border_with_background(nodes, False) + + self.assertFalse(get_global_draw_border_with_background(nodes)) + self.assertIn("draw-border-with-background false", write_kdl(nodes)) + + set_global_draw_border_with_background(nodes, True) + + self.assertTrue(get_global_draw_border_with_background(nodes)) + self.assertEqual(nodes, []) + + def test_xray_false_is_written_with_blur(self): + nodes: list[KdlNode] = [] + + set_global_window_blur(nodes, True) + set_global_window_xray(nodes, False) + + out = write_kdl(nodes) + self.assertIn("blur true", out) + self.assertIn("xray false", out) + self.assertFalse(global_window_xray_enabled(nodes)) + + def test_xray_toggle_does_not_enable_blur(self): + nodes: list[KdlNode] = [] + + set_global_window_xray(nodes, True) + + out = write_kdl(nodes) + self.assertIn("xray true", out) + self.assertNotIn("blur true", out) + self.assertFalse(global_window_blur_enabled(nodes)) + + def test_generated_global_window_effect_rule_is_compact(self): + nodes: list[KdlNode] = [] + + set_global_corner_radius(nodes, 16) + set_global_draw_border_with_background(nodes, False) + set_global_window_blur(nodes, True) + set_global_window_xray(nodes, False) + set_global_window_opacity(nodes, 0.75) + + self.assertEqual( + write_kdl(nodes).strip(), + """window-rule { + geometry-corner-radius 16 + clip-to-geometry true + draw-border-with-background false + opacity 0.75 + background-effect { + blur true + xray false + } +}""", + ) + + def test_focused_blur_rule_does_not_duplicate_global_effect_settings(self): + nodes: list[KdlNode] = [] + set_global_window_blur(nodes, True) + set_global_window_xray(nodes, False) + set_global_window_opacity(nodes, 0.75) + + set_focused_window_blur(nodes, True) + + out = write_kdl(nodes) + self.assertIn("match is-focused=true", out) + self.assertEqual(out.count("opacity 0.75"), 1) + self.assertEqual(out.count("blur true"), 2) + self.assertEqual(out.count("xray false"), 1) + self.assertTrue(focused_window_blur_enabled(nodes)) + + def test_disabling_focused_blur_preserves_other_focused_rule_settings(self): + nodes = parse_kdl( + """ +window-rule { + match is-focused=true + block-out-from "screen-capture" + draw-border-with-background false + opacity 0.75 + background-effect { + blur true + xray false + } +} +""" + ) + + set_focused_window_blur(nodes, False) + + out = write_kdl(nodes) + self.assertIn('block-out-from "screen-capture"', out) + self.assertIn("draw-border-with-background false", out) + self.assertIn("opacity 0.75", out) + self.assertNotIn("blur true", out) + self.assertIn("xray false", out) + self.assertFalse(focused_window_blur_enabled(nodes)) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_window_rules.py b/tests/test_window_rules.py new file mode 100644 index 0000000..4e96108 --- /dev/null +++ b/tests/test_window_rules.py @@ -0,0 +1,173 @@ +"""Tests for window-rule editor serialization helpers.""" + +from __future__ import annotations + +import unittest +import pytest + +pytest.importorskip("gi") + +from nirimod.kdl_parser import KdlNode, write_kdl +from nirimod.pages.window_rules import ( + CUSTOM_FLOATING_POSITION_INDEX, + DEFAULT_FLOATING_POSITION_RELATIVE_TO, + FLOATING_POSITION_CUSTOM_FIELD_LABELS, + FLOATING_POSITION_LOCATION_LABELS, + SCREENCAST_BLOCK_KEY, + SIZE_PERCENT_PRESETS, + _bool_action_active, + _bool_action_node, + _floating_position_location_index, + _floating_position_setting, + _make_floating_position_node, + _make_size_node, + _window_size_setting, +) + + +class TestWindowRuleActions(unittest.TestCase): + def test_screencast_block_action_writes_valid_niri_syntax(self): + node = _bool_action_node(SCREENCAST_BLOCK_KEY) + out = write_kdl([KdlNode("window-rule", children=[node])]) + + self.assertIn('block-out-from "screencast"', out) + self.assertNotIn("block-out-from-screencast", out) + + def test_screencast_block_action_reads_current_syntax(self): + rule = KdlNode( + "window-rule", children=[KdlNode("block-out-from", args=["screencast"])] + ) + + self.assertTrue(_bool_action_active(rule, SCREENCAST_BLOCK_KEY)) + + def test_screencast_block_action_reads_legacy_syntax(self): + rule = KdlNode( + "window-rule", children=[KdlNode("block-out-from-screencast", args=[True])] + ) + + self.assertTrue(_bool_action_active(rule, SCREENCAST_BLOCK_KEY)) + + def test_window_rule_size_default_writes_no_override(self): + self.assertIsNone(_make_size_node("default-column-width", "default", None)) + self.assertIsNone(_make_size_node("default-window-height", "default", None)) + + def test_window_rule_size_presets_include_full_size(self): + self.assertIn(("100%", 1.0), SIZE_PERCENT_PRESETS) + + def test_window_rule_width_preset_writes_proportion_node(self): + node = _make_size_node("default-column-width", "proportion", 0.25) + out = write_kdl([KdlNode("window-rule", children=[node])]) + + self.assertIn("default-column-width", out) + self.assertIn("proportion 0.25", out) + self.assertNotIn("default-column-width 0.25", out) + + def test_window_rule_height_preset_writes_proportion_node(self): + node = _make_size_node("default-window-height", "proportion", 1.0) + out = write_kdl([KdlNode("window-rule", children=[node])]) + + self.assertIn("default-window-height", out) + self.assertIn("proportion 1.0", out) + self.assertNotIn("default-window-height 1.0", out) + + def test_window_rule_size_reads_nested_fixed_value(self): + rule = KdlNode( + "window-rule", + children=[ + KdlNode( + "default-window-height", + children=[KdlNode("fixed", args=[270])], + ) + ], + ) + + self.assertEqual( + _window_size_setting(rule, "default-window-height"), + ("fixed", 270), + ) + + def test_window_rule_size_reads_legacy_direct_fixed_value(self): + rule = KdlNode( + "window-rule", + children=[KdlNode("default-window-height", args=[270])], + ) + + self.assertEqual( + _window_size_setting(rule, "default-window-height"), + ("fixed", 270), + ) + + def test_floating_position_default_writes_no_override(self): + self.assertIsNone( + _make_floating_position_node( + False, 0, 0, DEFAULT_FLOATING_POSITION_RELATIVE_TO + ) + ) + + def test_floating_position_locations_are_edges_plus_custom(self): + self.assertEqual( + FLOATING_POSITION_LOCATION_LABELS, + ["Top", "Bottom", "Left", "Right", "Custom"], + ) + + def test_floating_position_custom_fields_are_offsets_only(self): + self.assertEqual( + FLOATING_POSITION_CUSTOM_FIELD_LABELS, + ["X Offset (px)", "Y Offset (px)"], + ) + + def test_floating_position_edge_locations_use_zero_offsets(self): + self.assertEqual( + _floating_position_location_index(0, 0, "right"), + FLOATING_POSITION_LOCATION_LABELS.index("Right"), + ) + + def test_floating_position_edge_offsets_are_custom(self): + self.assertEqual( + _floating_position_location_index(20, 0, "right"), + CUSTOM_FLOATING_POSITION_INDEX, + ) + + def test_floating_position_custom_location_is_for_non_edge_anchors(self): + self.assertEqual( + _floating_position_location_index(12, 34, "bottom-right"), + CUSTOM_FLOATING_POSITION_INDEX, + ) + + def test_floating_position_writes_anchor_properties(self): + node = _make_floating_position_node(True, 0, 0, "right") + out = write_kdl([KdlNode("window-rule", children=[node])]) + + self.assertIn( + 'default-floating-position x=0 y=0 relative-to="right"', + out, + ) + + def test_floating_position_writes_custom_offset(self): + node = _make_floating_position_node(True, 12, 34, "right") + out = write_kdl([KdlNode("window-rule", children=[node])]) + + self.assertIn( + 'default-floating-position x=12 y=34 relative-to="right"', + out, + ) + + def test_floating_position_reads_existing_anchor(self): + rule = KdlNode( + "window-rule", + children=[ + KdlNode( + "default-floating-position", + props={"x": 12, "y": 34, "relative-to": "bottom-right"}, + ) + ], + ) + + self.assertEqual( + _floating_position_setting(rule), + (True, 12, 34, "bottom-right"), + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..4aec677 --- /dev/null +++ b/uv.lock @@ -0,0 +1,79 @@ +version = 1 +revision = 3 +requires-python = ">=3.12" + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "nirimod" +version = "0.1.0" +source = { editable = "." } + +[package.dev-dependencies] +dev = [ + { name = "pytest" }, +] + +[package.metadata] + +[package.metadata.requires-dev] +dev = [{ name = "pytest", specifier = ">=9.0.3" }] + +[[package]] +name = "packaging" +version = "26.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/df/de/0d2b39fb4af88a0258f3bac87dfcbb48e73fbdea4a2ed0e2213f9a4c2f9a/packaging-26.1.tar.gz", hash = "sha256:f042152b681c4bfac5cae2742a55e103d27ab2ec0f3d88037136b6bfe7c9c5de", size = 215519, upload-time = "2026-04-14T21:12:49.362Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/c2/920ef838e2f0028c8262f16101ec09ebd5969864e5a64c4c05fad0617c56/packaging-26.1-py3-none-any.whl", hash = "sha256:5d9c0669c6285e491e0ced2eee587eaf67b670d94a19e94e3984a481aba6802f", size = 95831, upload-time = "2026-04-14T21:12:47.56Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pytest" +version = "9.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165, upload-time = "2026-04-07T17:16:18.027Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" }, +]