Commit Graph

349 Commits

Author SHA1 Message Date
de77a1aa4e feat(build): Add modular build system and fix package dependencies
Build System:
- Add image/lib/common.sh with shared build functions
- Add profiles for vm-x64, x64-live, rpi400, espressobin-v7
- Add BUILD-SYSTEM.md documentation
- Add splash screens (boot.png, tui-splash.sh, kiosk-loading.sh)
- Add Plymouth theme for boot splash

Package Dependencies:
- Fix python3-uvicorn -> python3-uvicorn | python3-pip
- Fix python3-fastapi -> python3-fastapi | python3-pip
- Fix python3-httpx -> python3-httpx | python3-pip
- Allows packages to install when pip-provided deps are used

Documentation:
- Add Build-System.md wiki page
- Update _Sidebar.md with build system links
- Add VM-Testing.md improvements

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-10 17:31:24 +02:00
f9628d8aef fix(ui): Add sidebar navigation to 11 modules
Fixed UI guideline compliance for modules missing sidebar:
- secubox-cloner, wazuh, ossec, vault, magicmirror
- secubox-mmpm, redroid, rezapp, vm, ndpid, p2p

Changes per module:
- Added <nav class="sidebar" id="sidebar"></nav>
- Added body class="crt-light"
- Added sidebar.js script reference (ndpid)

Also added:
- REPORT-2026-04-10.md: Board/financer status report
- scripts/ui-screenshot-capture.py: Playwright UI capture
- scripts/ui-fix-checker.sh: UI guideline compliance checker

UI checker now passes 120/120 modules.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-10 13:20:24 +02:00
a98323fc34 fix(build): Safer cleanup to prevent /dev corruption
- Add sync and sleep before unmounting /dev
- Check if directory still has mounts before rm -rf
- Use force unmount with fallback to lazy unmount
- Remove duplicate trap and umount function

Prevents host /dev/null and other devices from being corrupted
during build failures or cleanup.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-10 12:59:18 +02:00
712d4b91aa fix(build): Add proper chroot mounts for apt operations
- Mount /dev, /dev/pts, /proc, /sys into chroot before apt-get
- Unmount special filesystems before squashfs creation
- Prevents /dev/null corruption and gpgv errors during build

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-10 12:57:06 +02:00
f7cdbc7c0e fix(network): Improve WAN DHCP compatibility for all devices
- Simplify netplan to match all e* interfaces (eth*, en*, eno*, enp*, etc)
- Enhanced fallback script: retries DHCP, logs actions
- Supports physical interfaces starting with e (ethernet) or w (wifi)
- Skip virtual interfaces (docker, veth, br-, virbr)
- Use networkctl reconfigure for DHCP retry

Ensures network works on Lenovo, Dell, HP, and other hardware
regardless of interface naming scheme.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-10 12:49:36 +02:00
da7d148a66 fix(kiosk): Use localhost URL for network-independent operation
- Change kiosk URL from 192.168.255.1:9443 to https://localhost/
- Kiosk now works without network (localhost always available)
- Remove port 9443 (nginx listens on 443 internally)
- Update URL priority: localhost first, then 127.0.0.1

Fixes kiosk white screen on real hardware (Lenovo) where
dummy0 interface may not be configured.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-10 12:48:05 +02:00
26bd3d970d docs: Add QEMU wiki page and update sidebar to v1.6.0
- New wiki/Live-USB-QEMU.md with run-qemu.sh documentation
- Updated _Sidebar.md version to v1.6.0
- Added links to VM launcher scripts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-10 12:09:14 +02:00
ac7f8a0d7e feat: Add QEMU/VBox launcher scripts + fix kiosk log bug
New scripts:
- scripts/run-qemu.sh: Launch SecuBox in QEMU with port forwarding
- scripts/run-vbox.sh: Create and launch SecuBox VM in VirtualBox

Port forwarding (both scripts):
- SSH:   localhost:2222 → guest:22
- HTTPS: localhost:9443 → guest:443
- HTTP:  localhost:8080 → guest:80

Bug fix:
- secubox-kiosk-launcher: log() now writes to stderr
- Fixes URL corruption when log messages were captured by
  command substitution in determine_url()

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-10 12:02:25 +02:00
e4f65d21b1 docs: Add USB boot scripts documentation for ESPRESSObin
- Updated board/espressobin-v7/README.md with boot scripts section
- Added "U-Boot Boot Scripts" section to wiki/ESPRESSObin.md
- Documented boot-usb.scr, flash-emmc.scr usage

Simplifies ESPRESSObin installation with automated scripts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-10 11:36:54 +02:00
9f4eae6058 feat: Add U-Boot USB boot and flash scripts for ESPRESSObin v7
New scripts for USB boot workflow:
- boot-usb.cmd/scr: Boot live system from USB
- flash-emmc.cmd/scr: Flash compressed image to eMMC

Usage:
1. Copy image.gz + boot.scr to FAT32 USB
2. On U-Boot: usb start && load usb 0:1 $loadaddr boot.scr && source $loadaddr
3. For eMMC flash: load usb 0:1 $loadaddr flash-emmc.scr && source $loadaddr

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-10 11:34:22 +02:00
acde1344aa fix: Remove :9443 from internal kiosk URLs
The kiosk scripts were using port 9443 for internal connections,
but nginx listens on port 443 inside the VM. Port 9443 is only
used for host port forwarding (QEMU/VirtualBox NAT).

URLs changed:
- https://192.168.255.1:9443/https://192.168.255.1/
- https://localhost:9443/https://localhost/
- https://127.0.0.1:9443/https://127.0.0.1/

This fixes the kiosk "connection refused" error in VM environments.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-10 11:30:38 +02:00
d9d2eb4edf docs: Add modules architecture documentation
- modules-architecture.md: 6-domain module organization
- secubox_modules_architecture.svg: Visual diagram
2026-04-10 10:47:35 +02:00
3b1f844bab docs: Add graphic charter with 6-module color system
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-10 10:26:05 +02:00
9690412f29 feat: Add secubox-ui-manager, boot architecture docs, and plymouth theme
New features:
- secubox-ui-manager: Unified UI management with KUI/TUI/Console fallback
  - State machine for mode transitions
  - Hypervisor detection and optimization
  - Modular debug system (levels 0-5)
  - Health monitoring with automatic fallback

- Plymouth secubox-cube theme with CRT effects and module icons

- Boot architecture documentation (ANSSI CSPN reference)
  - Chain de boot diagram (SVG)
  - Execution modes: PROMPT/KIOSK/API

Fixes:
- build-live-usb.sh: Remove Type=idle from getty override
- build-live-usb.sh: Add StandardInput/StandardOutput for proper TTY

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-10 10:23:54 +02:00
c7ec9cc3a3 feat: Add version and build timestamp to boot prompts
- Add SECUBOX_VERSION and BUILD_TIMESTAMP variables
- Include version in GRUB menu entries
- Add version and build timestamp to /etc/issue banner
- Add version and build timestamp to /etc/motd
- Add EFI grub.cfg for VirtualBox/OVMF boot fix

Version: v1.5.10

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-08 19:22:10 +02:00
476dec88bd fix: Add EFI grub.cfg for VirtualBox/OVMF boot compatibility
Create a small grub.cfg in the EFI System Partition that searches
for the root partition by UUID and chains to the main GRUB config.
This fixes boot issues in VirtualBox and other OVMF-based systems.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-08 19:18:11 +02:00
33d287c563 fix: Disable PXE boot on VirtualBox NICs
Add --nicbootprio1 0 and --nicbootprio2 0 to prevent VirtualBox
from attempting network boot when hard disk boot fails.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-08 19:08:56 +02:00
1cddcf6732 chore: Bump version to v1.5.10
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-08 18:31:02 +02:00
34b51bbf8e feat: Implement 6-Module Design System across all UI components
Complete UI design compliance update based on SecuBox Charte Graphique:

Design System:
- Add design-tokens.css with 6-module color system (BOOT/AUTH/ROOT/MIND/MESH/WALL)
- Update crt-light.css, crt-system.css for light/dark theme tokens
- Update sidebar.css, sidebar-light.css with module accent colors
- Refactor crt-components.js web components to use CSS variables

Module CSS Updates (35 files):
- All module CSS files now import design-tokens.css
- Replace hardcoded P31 Phosphor colors with CSS variables
- Add shared symlinks from each package to hub shared assets

UI Components:
- Redesign login.html with 6-module design system
- Update hub index.html dashboard with design tokens
- Remove legacy P31 color variables

System Branding:
- Add /etc/issue, /etc/issue.net, /etc/motd with 6-module branding
- Create Plymouth boot splash theme (secubox + secubox-text)
- Add generate-plymouth-assets.sh for theme image generation

Tools:
- Add update-css-design-tokens.py for batch CSS updates

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-08 18:29:36 +02:00
1189f9b5b8 docs: Apply SecuBox Charte Graphique to wiki pages
- Add DESIGN-CHARTER.md with six-module color system
- Add WIKI-STYLE-GUIDE.md for wiki design conformity
- Add QUICKSHEET-REFERENCE.md with stack architecture details
- Reorganize Home.md and Home-FR.md with 6-stack structure
- Reorganize Modules.md by AUTH/WALL/BOOT/MIND/ROOT/MESH stacks
- Update _Sidebar.md with module category badges
- Update version references to v1.5.9
- Add CyberMind branding footer to all pages

Six-stack architecture:
- AUTH (Orange) - Authentication, ZeroTrust
- WALL (Yellow) - Firewall, CrowdSec, IDS/IPS
- BOOT (Red) - Deployment, provisioning
- MIND (Violet) - AI, behavioral analysis
- ROOT (Green) - System, CLI, hardening
- MESH (Blue) - Network, WireGuard, mesh

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-08 17:15:28 +02:00
17f4886a7f fix: Handle duplicate assets in release workflow retries
- Add step to delete existing assets before upload (handles workflow retries)
- Update to softprops/action-gh-release@v2
- Add fail_on_unmatched_files: false for graceful handling

Fixes 422 error when retrying failed release uploads.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-08 16:11:05 +02:00
aa41893d4b feat: Complete Phase 8, 9, 10 - all modules done
Phase 8 (Applications): 21 modules complete
- jitsi, gotosocial, peertube, hexo, webradio, voip, simplex, torrent, newsbin

Phase 9 (System Tools): 22 modules complete
- Added READMEs for vault, cloner, vm, rtty, reporter, turn, smtp-relay

Phase 10 (Security Extensions): 10 modules complete
- Created secubox-netifyd package (DPI daemon)
- Added README for secubox-wazuh

Infrastructure fixes:
- Fixed uvicorn path in 29 service files (/usr/bin → /usr/local/bin)
- Fixed smtp-relay debian/control (Section: mail, added msmtp alternative)
- Added MODULE-COMPLIANCE.md with formal design rules
- Updated CLAUDE.md to reference compliance requirements

Total: 125 packages, all phases complete

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-08 14:46:58 +02:00
ff4b1f2c5b fix: QEMU ARM64 script use AAVMF firmware and jq for format
- Prefer AAVMF firmware (64MB) over QEMU_EFI (2MB) for UEFI vars
- Use jq instead of grep for reliable format extraction
- Copy AAVMF_VARS.fd template when available

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-08 10:38:17 +02:00
5ebc80fc4b fix: Handle missing GPG_PRIVATE_KEY in CI publish job
Skip signing and deploy steps when secrets are not configured
instead of failing the entire workflow.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-08 10:07:11 +02:00
1ffe7f067b fix: Update VBox audio parameter for newer VirtualBox versions
Use --audio-driver none instead of deprecated --audio none

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-08 08:48:19 +02:00
d7fdc4186e feat: Add QEMU ARM64 VM support and RPi 400 to releases
- Add create-qemu-arm64-vm.sh script for ARM64 emulation on x86 hosts
- Add wiki/QEMU-ARM64.md documentation
- Update CI workflows to include RPi 400 and VM scripts in releases
- Update release notes to document all platforms

Platforms now supported:
- MOCHAbin (Armada 7040)
- ESPRESSObin v7/Ultra (Armada 3720)
- Raspberry Pi 400 / Pi 4
- VirtualBox x64
- QEMU ARM64 emulation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-08 08:13:56 +02:00
16cf0eb529 fix: Add nginx cleanup to all build scripts
- Add nginx config cleanup to build-image.sh and build-rpi-usb.sh
- Moves location-only configs from conf.d/sites-enabled to secubox.d/
- Tests nginx configuration after package install
- Matches existing cleanup in build-live-usb.sh

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-08 08:08:45 +02:00
74ec25436b fix: Add final nginx cleanup after ALL package installs
- Run nginx config cleanup after rootfs cleanup (after all apt-gets)
- Remove any secubox/repo configs from conf.d
- Verify nginx config is valid before creating squashfs
2026-04-08 06:32:12 +02:00
6633ced5b0 fix: Clean bad nginx configs from conf.d (secubox-repo symlink)
- Add cleanup for conf.d directory (not just sites-enabled)
- Move location-only configs from conf.d to secubox.d
- Fixes nginx startup failure caused by secubox-repo.conf symlink
2026-04-07 17:10:34 +02:00
a7f8f959a7 fix: Auto-fix bad nginx configs in sites-enabled
- Move location-only configs from sites-enabled to secubox.d
- Auto-detect and disable problematic nginx config files
- Retry nginx test after auto-fix
2026-04-07 16:10:01 +02:00
c24ddccf9d fix: Ensure nginx config and snippets are installed correctly
- Add explicit nginx snippet installation after package install
- Create secubox-proxy.conf if missing
- Install main secubox nginx site config if missing
- Test nginx config in chroot and show errors
- Regenerate SSL certs if missing
2026-04-07 15:19:43 +02:00
c2f7bc5769 fix: Add complete Python dependencies for SecuBox services
Added missing pip packages required by SecuBox services:
- cryptography (for JWT/TLS operations)
- python-multipart (for FastAPI form handling)
- websockets (for uvicorn websocket support)
- netifaces (for network interface info)
- pydantic, toml, aiofiles (various services)

This fixes the "Failed to start" errors for SecuBox services
that were missing Python dependencies.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-07 14:05:31 +02:00
f1a26d7937 fix: Install kernel BEFORE SecuBox packages to prevent apt breakage
The RPi build was failing because:
1. SecuBox packages installed with dpkg --force-depends
2. apt-get install -f tried to resolve missing deps (python3-fastapi, etc)
3. This broke apt's dependency resolver
4. Kernel install then failed (linux-image-arm64, initramfs-tools)

Fix: Reorganize build steps to install kernel while apt is clean:
- Step 4: Kernel + firmware (before any forced installs)
- Step 5: SecuBox packages (pip provides Python deps)
- Step 6: Bootloader config
- Step 7: Image creation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-07 08:50:46 +02:00
dd46b6e7e7 fix: Generate SSL certs BEFORE SecuBox package install
Package postinst scripts check nginx config which requires SSL certs.
Moving cert generation to before dpkg install prevents postinst failures.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-07 08:09:35 +02:00
5a58dd2bdf fix: Remove head -30 causing SIGPIPE with pipefail in RPi build
The pipeline `dpkg ... | grep | head -30` fails with SIGPIPE when
dpkg continues writing after head exits. With set -o pipefail,
this causes build failure even with || true at end.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-07 07:58:32 +02:00
c292685990 fix: Add chown after sudo build in ISO workflow
Files created by sudo are root-owned, preventing subsequent
steps from accessing them.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-07 07:29:32 +02:00
b047b1e24c fix: Use python3-netifaces from Debian instead of pip
netifaces requires compilation which fails without build-essential.
Use the Debian packaged version instead.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-07 07:03:46 +02:00
6a0b9f45a1 feat: Add secubox CLI tool
Provides common commands:
- secubox status - system and services overview
- secubox services - list all SecuBox services
- secubox logs [svc] - view service logs
- secubox restart/start/stop <svc> - manage services
- secubox info - system information
- secubox network - network configuration
- secubox version - version info

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-07 06:54:25 +02:00
101e3c98e2 fix: Installer parted command parsing negative sizes
Add -- to parted commands to stop option parsing, otherwise -4GiB
is interpreted as -4, -G, -i, -B options instead of a size value.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-07 06:38:23 +02:00
c7bf0b9447 feat: Add Raspberry Pi 400 support with boot menu
- Add rpi400 to default CI builds in build-image.yml
- Create board/rpi400/config.mk with Pi 400 settings
- Add build-image.sh redirect to build-rpi-usb.sh for RPi boards
- Add boot menu system to build-rpi-usb.sh:
  - Normal, Kiosk, Console, Bridge, Minimal modes
  - VT100/DEC PDP-style menu interface
  - Persistent mode selection across reboots
  - systemd integration for early boot
- Fix slipstream in build-rpi-usb.sh:
  - Use dpkg --force-depends (pip provides Python deps)
  - Skip failing apt-get -f install
  - Add more Python dependencies to pip install

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-07 06:32:56 +02:00
9f65ebcd3c fix: Remove failing apt-get -f install from slipstream
apt-get install -f fails because it tries to resolve Debian packages
(python3-jose, python3-httpx, etc.) that don't exist in repos.
These Python dependencies are installed via pip before dpkg, so
apt dependency resolution is unnecessary and causes slipstream
to report failures despite packages being properly installed.

Changes:
- Remove apt-get install -f call from both build scripts
- Keep dpkg --configure -a to complete package configuration
- Pip packages satisfy runtime dependencies without apt

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-07 05:56:24 +02:00
46a957c4bb fix: Pre-install Python deps and systemd dirs before slipstream
- Create /usr/lib/systemd/system and /etc/systemd/system directories
  before dpkg install (fixes "unable to open *.service.dpkg-new" errors)
- Install Python dependencies (fastapi, uvicorn, httpx, etc.) via pip
  BEFORE slipstream (fixes "depends on python3-X but not installed")
- Add --force-depends and --force-overwrite flags for dpkg
- Show proper installed/total package counts
- Move pip install block before slipstream in build-image.sh

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 20:02:55 +02:00
7ead1ff77f fix: Slipstream path + conditional service startup
1. Fix slipstream path: Look for packages in output/ not just output/debs/
   - build-image.sh and build-live-usb.sh now check both locations
   - 73 packages now properly detected and installed

2. Add ConditionPathExists to 22 optional services:
   - Services only start if /etc/secubox/<module>/enabled exists
   - Prevents boot failures when backend apps aren't installed
   - Affected: ollama, jellyfin, zigbee, lyrion, localai, hexo,
     peertube, newsbin, webradio, gotosocial, torrent, domoticz,
     simplex, photoprism, homeassistant, matrix, jitsi, voip,
     magicmirror, mmpm, jabber, redroid

3. Add explicit parted/fdisk install in live USB build
   - Ensures disk tools available for secubox-install

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 19:50:11 +02:00
39667e41bc fix: ESPRESSObin v7 eMMC boot - DTB, root device, mv88e6xxx blacklist
- Use armada-3720-espressobin-v7-emmc.dtb to enable both SDHCI controllers
- Fix root device: /dev/mmcblk1p2 (eMMC is mmc1 with dual controller DTB)
- Add modprobe.blacklist=mv88e6xxx,dsa_core to prevent DSA probe loop
- Add sdhci.debug_quirks2=0x40 to fix xenon-sdhci DDR timing issues
- Add initramfs hooks for sdhci-xenon and mv88e6xxx blacklist
- Add systemd service to load mv88e6xxx after rootfs mount
- Fix fstab tmpfs mount (remove non-existent user reference)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 18:07:30 +02:00
e8d169919c fix: Correct boot.scr paths and make initramfs optional
- build-image.sh: Fix boot.scr to load from boot partition (mmc 1:1)
  with files at root level (Image, not /boot/Image)
- build-rpi-usb.sh: Make initramfs generation failure non-fatal
  (Pi can boot without initramfs, just with reduced functionality)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 10:33:32 +02:00
592ce34202 feat: Add --slipstream option to build-rpi-usb.sh
Consistent with build-image.sh:
- --slipstream installs packages from output/debs/
- Falls back to cache/repo/pool if not using slipstream
- Installs secubox-core first (dependency)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 10:11:14 +02:00
a2eefdb99d docs: Add Configuration and Troubleshooting wiki pages (EN/FR/ZH)
- Configuration.md: TOML config, modules, double-buffer system
- Troubleshooting.md: Common issues, diagnostics, recovery
- All pages translated to French and Chinese
- Sidebar updated to v1.5.3 with new sections

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 10:04:02 +02:00
f281a19aae feat: Add debian packaging for secubox-system-hub
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 10:01:08 +02:00
68d0f11c3b docs: Update WIP.md - Session 43 ARM kernel fix + wiki
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 09:37:31 +02:00
43b62317ec docs: Complete wiki translations (FR/ZH)
- ARM-Installation-FR.md (French translation)
- ARM-Installation-ZH.md (Chinese translation)
- ESPRESSObin-ZH.md (Chinese translation)
- UI-COMPARISON.md (moved from docs/wiki/)
- Updated sidebar with all language links

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-06 09:30:46 +02:00