diff --git a/README.md b/README.md index b753bad..b2ec7f1 100644 --- a/README.md +++ b/README.md @@ -1,447 +1,301 @@

- - InputBridge Logo + InputBridge logo

InputBridge

- Share your keyboard & mouse across multiple PCs — securely, instantly, wirelessly. + One keyboard and mouse. Two computers. One secure bridge.

- Platform - Linux - .NET 8 - AES-256 - MIT License - Status + A lightweight, open-source network KVM for Windows and Linux.

- Features • - Screenshots • - How It Works • - Installation • - Quick Start • - Architecture • - Build • - Contributing + Latest release + CI status + MIT license + GitHub stars

---- - -## 📖 What is InputBridge? - -**InputBridge** is a software-based KVM (Keyboard, Video, Mouse) solution that lets you control multiple Windows PCs using a single keyboard and mouse — no extra hardware, cables, or KVM switches required. Just install it on your computers, connect over your local network, and seamlessly switch input between machines with a keyboard shortcut. - -

- InputBridge — Control multiple PCs with one keyboard and mouse + Features · + Platforms · + Quick start · + How it works · + Security · + Build · + FAQ

-> **Example use case:** You have a work PC and a personal PC on the same desk. Instead of switching between two keyboards, InputBridge lets you press `Ctrl+Win+2` to redirect all your input to the second computer — and `Ctrl+Win+1` to switch back. It's responsive and encrypted on a typical LAN. - ---- - -## 🐧 Linux support - -InputBridge now ships a **Linux edition** (`src/InputBridge.Linux`) — a headless console -app that speaks the **same protocol** as the Windows apps, so Linux and Windows machines -interoperate seamlessly. Mix and match: control a Linux box from Windows, or drive Windows -PCs from Linux. - -It captures/injects input at the kernel layer (**evdev** + **`/dev/uinput`**), so it works -under **both X11 and Wayland**. - -```bash -dotnet publish src/InputBridge.Linux/InputBridge.Linux.csproj -c Release -r linux-x64 --self-contained +

+ + Two computers connected by InputBridge, sharing one keyboard and mouse + +

-INPUTBRIDGE_SECRET='use-a-long-random-secret' ./inputbridge-linux client # be controlled by a Host -INPUTBRIDGE_SECRET='use-a-long-random-secret' ./inputbridge-linux host # control another machine -``` +

+ Download latest release +  ·  + Linux setup guide +  ·  + Report an issue +

-Full guide → **[docs/LINUX.md](docs/LINUX.md)** (hotkeys, udev rule for sudo-less use, interop notes). +> [!NOTE] +> InputBridge is designed for computers on the same trusted local network. A Host captures your physical input; a Client securely replays it on the other machine. ---- + ## ✨ Features -| Feature | Description | +| | | |---|---| -| ⚡ **Sub-millisecond Latency** | Zero-allocation UDP transport designed for imperceptible input lag on LAN. Keyboard events are sent over TCP to guarantee delivery. | -| 🔐 **End-to-End Encryption** | Input data is encrypted and authenticated with **AES-256-GCM**. Use a strong, unique shared secret. | -| 🔍 **Automatic LAN Discovery** | Host broadcasts its presence on the network. The Client discovers it automatically — no need to manually type IP addresses. | -| 🎯 **Precise Input Simulation** | Uses Windows native `SendInput` API with both Virtual Key codes and Hardware Scan Codes for maximum compatibility, even in games. | -| 🎨 **Modern Dark UI** | Sleek WPF interface with dark theme, status indicators, and system tray integration. Runs quietly in the background. | -| ⌨️ **Customizable Hotkeys** | Change the switching hotkeys through the built-in settings panel. Emergency release (`Ctrl+Alt+Escape`) is always available. | -| 🔁 **Auto-Reconnect** | If the network drops, InputBridge automatically detects the disconnection and attempts to reconnect — no manual intervention needed. | -| 🛡️ **Keystroke Safety** | Keystroke values are **never logged** to disk. All keyboard data in logs is masked for security. | +| ⚡ **Low-latency input** | Keyboard events use reliable TCP; mouse movement uses low-overhead UDP. | +| 🔐 **Authenticated encryption** | Input packets are protected with AES-256-GCM after an HMAC-SHA256 challenge-response handshake. | +| 🔎 **LAN discovery** | Clients can find the Host automatically, or connect directly to a known IP address. | +| 🪟 **Native Windows input** | Windows uses low-level hooks for capture and SendInput for replay. | +| 🐧 **X11 + Wayland** | Linux works at the kernel input layer with evdev and /dev/uinput. | +| ⌨️ **Fast switching** | Switch machines with a hotkey and use the emergency release shortcut whenever needed. | +| 🔁 **Connection recovery** | Heartbeats detect dropped sessions and release held input safely. | +| 🕶️ **Privacy-minded logs** | Keystroke values are masked instead of being written to disk. | ---- + -## 📸 Screenshots +## 🖥️ Platforms -> **Note:** Replace the placeholder paths below with your actual screenshot images. +| Platform | Host — controls another PC | Client — is controlled remotely | Interface | +|---|:---:|:---:|---| +| **Windows 10/11 x64** | ✅ | ✅ | WPF desktop app + system tray | +| **Linux x64** | ✅ | ✅ | Headless CLI | +| **Linux display server** | X11 / Wayland | X11 / Wayland | evdev + uinput | +| **macOS** | ❌ | ❌ | Planned | -

- Host Application — Main Window
- Control center where you start connections, configure settings, and switch input modes.

- - InputBridge Host — Main Window -

+Windows and Linux speak the same protocol, so mixed setups work in either direction: -
+- Windows Host → Linux Client +- Linux Host → Windows Client +- Windows Host → Windows Client +- Linux Host → Linux Client -

- Client Application — Waiting for Connection
- Runs on the secondary PC. Once connected, it receives and simulates all input from the Host.

- - InputBridge Client — Main Window -

- -
+For Linux permissions, hotkeys and key-map notes, see the complete **[Linux guide](docs/LINUX.md)**. -

- Connected & Active
- Green status indicator shows an active connection with real-time latency monitoring.

- - InputBridge — Connected State -

- -
- -

- Hotkey Settings
- Customize your switching hotkeys through the intuitive settings dialog.

- - InputBridge — Hotkey Settings -

+ -
+## 🚀 Quick start -

- System Tray
- InputBridge runs in the background via the system tray for easy access.

- - InputBridge — System Tray -

+### 1. Download ---- +Open the **[latest release](https://github.com/onderaktas54/InputBridge/releases/latest)** and choose the package for each computer: -## ⚙️ How It Works +| Package | Put it on | +|---|---| +| InputBridge_Host_*.zip | The Windows PC with the physical keyboard and mouse | +| InputBridge_Client_*.zip | The Windows PC you want to control | +| InputBridge_Linux_x64_*.tar.gz | A Linux PC in either Host or Client mode | -InputBridge operates as a **Host ↔ Client** pair over your local network: +Release archives are self-contained. You do not need to install .NET separately. -``` -┌─────────────────────────────────┐ LAN (Encrypted) ┌─────────────────────────────────┐ -│ HOST COMPUTER │ ◄──────────────────────────────► │ CLIENT COMPUTER │ -│ │ │ │ -│ Physical Keyboard & Mouse │ ┌───────────────────────┐ │ Simulated Keyboard & Mouse │ -│ │ │ │ AES-256-GCM Tunnel │ │ │ │ -│ ▼ │ │ │ │ ▼ │ -│ Low-Level Windows Hooks │ │ Keyboard → TCP │ │ SendInput API │ -│ (SetWindowsHookEx) │───►│ Mouse → UDP │─────►│ (Native Windows Input) │ -│ │ │ Heartbeat → UDP │ │ │ -│ Captures ALL input events │ └───────────────────────┘ │ Replays input as if local │ -└─────────────────────────────────┘ └─────────────────────────────────┘ -``` +### 2. Start both ends -### 🔄 Switching Modes +
+Windows → Windows or Linux +
-| Hotkey | Action | Description | -|---|---|---| -| `Ctrl + Win + 1` | **Switch to Host** | Input goes to your physical (local) PC | -| `Ctrl + Win + 2` | **Switch to Client** | Input is redirected to the remote PC | -| `Ctrl + Alt + Escape` | **Emergency Release** | Immediately releases all hooks and returns control to the local PC. Works under any circumstance. | +1. Run InputBridge.Host.exe on the computer with the keyboard and mouse. +2. Enter a unique shared secret of at least 16 characters and start the Host. +3. Run the Client on the other computer and enter the exact same secret. +4. Let LAN discovery find the Host, then connect. -> 💡 Hotkeys are fully customizable through the **Hotkey Settings** panel. +
-### 🔐 Security Model +
+Linux as the Client +
-1. Both machines share a **Secret Key** (pre-shared passphrase). -2. On connection, a **challenge-response handshake** (HMAC-SHA256) verifies both parties know the key. -3. A unique **AES-256 session key** is derived for each connection. -4. **Every single packet** (keyboard, mouse, heartbeat) is encrypted with AES-256-GCM. -5. GCM mode provides both **confidentiality** and **integrity** — tampered packets are rejected. +~~~bash +INPUTBRIDGE_SECRET='use-a-long-random-secret' ./inputbridge-linux client ---- +# Skip discovery and connect directly: +INPUTBRIDGE_SECRET='use-a-long-random-secret' \ + ./inputbridge-linux client --host 192.168.1.20 +~~~ -## 📥 Installation +
-### Download Pre-built Binaries (Recommended) +
+Linux as the Host +
-1. Go to the [**Releases**](../../releases) page. -2. Download the latest `InputBridge_Release_v*.zip`. -3. Extract the archive — you will find two folders: - - `InputBridge.Host/` — for your **primary** PC (the one with the physical keyboard & mouse) - - `InputBridge.Client/` — for your **secondary** PC (the one you want to control remotely) -4. **No installation required.** Just run the `.exe` files. +~~~bash +INPUTBRIDGE_SECRET='use-a-long-random-secret' ./inputbridge-linux host +~~~ -### System Requirements +Linux needs permission to access kernel input devices. Install the bundled +99-inputbridge.rules udev rule once; the **[Linux guide](docs/LINUX.md#running-without-sudo-udev-rule)** +contains the safe setup steps. -| Requirement | Details | -|---|---| -| **OS** | Windows 10 / 11 (64-bit) | -| **Runtime** | .NET 8.0 Desktop Runtime ([download](https://dotnet.microsoft.com/download/dotnet/8.0)) | -| **Network** | Both PCs must be on the same LAN (Wi-Fi or Ethernet) | -| **Firewall** | Allow TCP/UDP port **7201** (configurable) | +
---- +### 3. Switch control -## 🚀️ Quick Start Guide +| Host | Shortcut | Action | +|---|---|---| +| Windows | Ctrl + Win + 1 | Return input to the local Host | +| Windows | Ctrl + Win + 2 | Forward input to the Client | +| Windows | Ctrl + Alt + Esc | Emergency release | +| Linux | Ctrl + Alt + S | Toggle forwarding | +| Linux | Ctrl + Alt + Esc | Emergency release | -Follow these steps to get InputBridge running in under 2 minutes: +> [!TIP] +> Ethernet gives the most consistent experience, but a healthy local Wi-Fi network also works well. -### Step 1 — Set up the Host (Primary PC) + - -

- Step 1 — Host Setup -

+## 🌉 How it works -1. Run `InputBridge.Host.exe` on the computer that has the physical keyboard and mouse. -2. Enter a strong **Secret Key** of at least 16 characters (preferably randomly generated). -3. Set the **TCP Port** (default `7201` works for most cases). -4. Click **"Start Connection"**. -5. The status will show **"Waiting for Connection..."** until the Client connects. +~~~mermaid +flowchart LR + K["Keyboard + mouse"] --> H["Host capture"] + H -->|"Keyboard · TCP"| E["AES-256-GCM bridge"] + H -->|"Mouse · UDP"| E + E --> C["Client replay"] + C --> O["Remote operating system"] -### Step 2 — Set up the Client (Secondary PC) + classDef edge fill:#071526,stroke:#00b8d9,color:#e6fbff,stroke-width:2px; + classDef secure fill:#1c1233,stroke:#8b5cf6,color:#f3e8ff,stroke-width:2px; + class K,H,C,O edge; + class E secure; +~~~ - -

- Step 2 — Client Setup -

+The shared Core library owns discovery, networking, packet serialization, the handshake and encryption. Each platform only implements native input capture and replay. -1. Run `InputBridge.Client.exe` on the computer you want to control remotely. -2. Enter the **exact same Secret Key** you used on the Host. -3. Click **"Connect"**. -4. The Client will automatically discover the Host on the network and establish a secure connection. +| Channel | Transport | Purpose | +|---|---|---| +| Keyboard | TCP | Preserve every key-down and key-up event | +| Mouse | UDP | Prioritize fresh movement with minimal delay | +| Heartbeat | UDP | Detect a lost peer and release held input | +| Handshake | TCP | Authenticate the shared secret and establish the session | -### Step 3 — Switch & Control + - -

- Step 3 — Switching Between PCs -

+## 🔒 Security -- Press **`Ctrl + Win + 2`** → Your keyboard and mouse now control the **Client PC**. -- Press **`Ctrl + Win + 1`** → Your keyboard and mouse return to controlling the **Host PC**. -- If anything goes wrong, press **`Ctrl + Alt + Escape`** to immediately release all input. - -✅ **You're done!** The connection status will show as green with real-time latency. - ---- - -## 🏗 Architecture - -InputBridge is structured as a clean, modular .NET 8 solution with clear separation of concerns: - -``` -InputBridge.sln -│ -├── src/ -│ ├── InputBridge.Core/ # Shared library — networking, crypto, protocol -│ │ ├── Protocol/ # InputPacket struct (24 bytes), serialization, handshake -│ │ ├── Network/ # UDP & TCP transports, LAN discovery service -│ │ ├── Crypto/ # AES-256-GCM encryption/decryption -│ │ ├── Configuration/ # Settings management (JSON-based) -│ │ └── Logging/ # Serilog-based logger with keystroke masking -│ │ -│ ├── InputBridge.Host/ # WPF app — runs on the primary PC -│ │ ├── Hooks/ # Low-level keyboard & mouse hooks (SetWindowsHookEx) -│ │ ├── Services/ # Connection manager, input router -│ │ └── UI/ # Theme resources, styles -│ │ -│ ├── InputBridge.Client/ # WPF app — runs on the secondary PC -│ │ ├── Simulation/ # Keyboard & mouse simulators (SendInput API) -│ │ └── Services/ # Client-side connection handler -│ │ -│ └── InputBridge.Shared.UI/ # Shared WPF styles and themes -│ -└── tests/ - └── InputBridge.Core.Tests/ # Unit tests for protocol, crypto, network -``` - -### Data Flow Diagram - -``` - ┌──────────────────────────────────────────────────────┐ - │ HOST PC │ - │ │ - │ Keyboard ──► KeyboardHook ──┐ │ - │ ├──► InputRouter │ - │ Mouse ────► MouseHook ──────┘ │ │ - │ │ │ - │ ┌─────────┴──────────┐ │ - │ │ PacketSerializer │ │ - │ │ + │ │ - │ │ AesTransport │ │ - │ │ (Encrypt) │ │ - │ └─────────┬──────────┘ │ - │ │ │ - │ Keyboard:TCP Mouse:UDP │ - └────────────────────────────────────┬─────────────────┘ - │ - ═══════╪═══════ LAN - │ - ┌────────────────────────────────────┬─────────────────┐ - │ │ CLIENT PC │ - │ ┌─────┴──────────┐ │ - │ │ AesTransport │ │ - │ │ (Decrypt) │ │ - │ │ + │ │ - │ │ PacketSerializer│ │ - │ └─────┬──────────┘ │ - │ │ │ - │ ┌──────────┴──────────┐ │ - │ │ │ │ - │ KeyboardSimulator MouseSimulator │ - │ (SendInput) (SendInput) │ - │ │ │ │ - │ ▼ ▼ │ - │ Virtual Keyboard Virtual Mouse │ - └──────────────────────────────────────────────────────┘ -``` - -### Network Protocol - -| Channel | Protocol | Used For | Why | -|---|---|---|---| -| Keyboard Events | **TCP** | Key down/up events | Every keystroke must arrive — TCP guarantees delivery | -| Mouse Events | **UDP** | Movement, clicks, scroll | Speed over reliability — a dropped mouse move is instantly corrected by the next one | -| Heartbeat | **UDP** | Connection health check | Sent every 1 second. 3 missed heartbeats = connection lost | -| Handshake | **TCP** | Initial auth & key exchange | Challenge-response with HMAC-SHA256, then AES session key exchange | - -### Packet Format - -Every input event is serialized into a compact **24-byte** struct: - -``` -┌─────────┬──────────┬───────────┬────────┬────────┬────────────┬────────────────┐ -│ Version │ Type │ Flags │ Data1 │ Data2 │ Timestamp │ SequenceNumber │ -│ 1 byte │ 1 byte │ 2 bytes │ 4 bytes│ 4 bytes│ 8 bytes │ 4 bytes │ -└─────────┴──────────┴───────────┴────────┴────────┴────────────┴────────────────┘ - Total: 24 bytes per packet - After encryption: 52 bytes (24 + 12 IV + 16 auth tag) -``` - ---- - -## 🔧 Building from Source - -### Prerequisites - -- [.NET 8.0 SDK](https://dotnet.microsoft.com/download/dotnet/8.0) or later -- Windows 10/11 (required for WPF) - -### Build - -```bash -# Clone the repository -git clone https://github.com/onderaktas54/InputBridge.git -cd InputBridge - -# Build the entire solution -dotnet build InputBridge.sln -c Release - -# Run tests -dotnet test InputBridge.sln -``` - -### Publish (Create portable executables) - -```bash -# Publish Host -dotnet publish src/InputBridge.Host/InputBridge.Host.csproj -c Release -r win-x64 --self-contained +1. Both machines are configured with the same pre-shared secret. +2. HMAC-SHA256 challenge-response proves both peers know it. +3. Each connection derives fresh session material. +4. AES-256-GCM encrypts and authenticates input packets. +5. Invalid or tampered packets are rejected. -# Publish Client -dotnet publish src/InputBridge.Client/InputBridge.Client.csproj -c Release -r win-x64 --self-contained -``` +> [!IMPORTANT] +> Use a long, random, unique secret and keep InputBridge on a trusted LAN. The project is not designed to expose its ports directly to the public internet. -The output will be in `src/InputBridge.Host/bin/Release/net8.0-windows/win-x64/publish/` and the equivalent Client path. + ---- +## 🧰 Build from source -## 🤝 Contributing +### Linux -Contributions are welcome! Here's how you can help: +Install the .NET 8 SDK or newer, then build only the Linux project: -1. **Fork** the repository -2. **Create** a feature branch: `git checkout -b feature/amazing-feature` -3. **Commit** your changes: `git commit -m 'Add amazing feature'` -4. **Push** to the branch: `git push origin feature/amazing-feature` -5. **Open** a Pull Request +~~~bash +dotnet test tests/InputBridge.Core.Tests/InputBridge.Core.Tests.csproj -c Release +dotnet test tests/InputBridge.Linux.Tests/InputBridge.Linux.Tests.csproj -c Release +dotnet publish src/InputBridge.Linux/InputBridge.Linux.csproj \ + -c Release -r linux-x64 --self-contained +~~~ -### Development Notes +Building the full solution on Linux includes Windows-only WPF projects and therefore requires Windows targeting. -- The project uses **C# 12** with nullable reference types enabled. -- All warnings are treated as errors (`TreatWarningsAsErrors`). -- Run `dotnet test` before submitting any PR. +### Windows ---- +~~~powershell +dotnet test InputBridge.sln -c Release +dotnet publish src/InputBridge.Host/InputBridge.Host.csproj -c Release -r win-x64 --self-contained +dotnet publish src/InputBridge.Client/InputBridge.Client.csproj -c Release -r win-x64 --self-contained +~~~ -## 🗺 Roadmap +
+Repository layout +
+ +~~~text +src/ +├── InputBridge.Core/ Networking, protocol, discovery and crypto +├── InputBridge.Host/ Windows input capture and routing +├── InputBridge.Client/ Windows input replay +├── InputBridge.Linux/ Linux Host and Client CLI +└── InputBridge.Shared.UI/ Shared WPF theme and tray services + +tests/ +├── InputBridge.Core.Tests/ +└── InputBridge.Linux.Tests/ +~~~ -- [ ] Multi-client support (control 3+ PCs) -- [ ] Clipboard sharing between Host and Client -- [x] Cross-platform Client (Linux) -- [ ] Cross-platform Client (macOS) -- [ ] File drag & drop between machines -- [ ] Monitor-edge switching (move mouse to screen edge to switch) +
---- + ## ❓ FAQ
-Is my data safe? Can someone on my network see what I type? -
-Input packets are encrypted with AES-256-GCM and authenticated against tampering. Use a long, unique secret: weak passphrases remain vulnerable to password guessing if an attacker captures the handshake. +Will it work between Windows and Linux? +
+Yes. Both editions share the same wire protocol. Linux can be either the Host or Client and works under X11 and Wayland.
-What happens if the network drops? Will my keyboard get stuck? -
-InputBridge includes automatic disconnection detection via heartbeat monitoring. If the connection drops, the Host immediately releases all hooks and returns control to your local PC. The Client also releases any pressed keys to prevent "stuck key" issues. Reconnection is attempted automatically. +Why does Linux need input-group access? +
+The Client creates a virtual keyboard and mouse through /dev/uinput; the Host reads physical devices through evdev. The bundled udev rule grants those permissions without running the network-facing app as root. Only trusted local users should join the input group.
-Does it work over the internet (WAN)? -
-InputBridge is designed for LAN use only (same local network). While it could theoretically work over the internet with port forwarding, it is not recommended due to latency and security considerations. +What if the network drops or a key gets stuck? +
+Heartbeat monitoring ends the session, releases captured input and clears pressed keys. The emergency release shortcut is also always available.
-What is the latency? -
-Latency depends on the network and both computers. The compact packet format is designed to keep LAN overhead low; measure your own Wi-Fi or Ethernet setup for real-world figures. +Does it work over the internet? +
+InputBridge targets trusted local networks. Do not forward its ports directly to the public internet; use a private VPN if you need to bridge two trusted networks.
-Does it work with games? -
-Yes. InputBridge uses both Virtual Key codes and Hardware Scan Codes via the SendInput API, which provides the highest compatibility with games and applications that use DirectInput or raw input. +Are all Linux keyboard layouts supported? +
+The current Linux-to-Windows key map targets a US layout. Other layouts may need additional mappings; please open an issue with the affected keys.
-
-Can I change the hotkeys? -
-Yes! Click the "Hotkey Settings" button on the Host window to customize the switching shortcuts. The emergency release hotkey (Ctrl+Alt+Escape) is always active and cannot be changed for safety reasons. -
+ + +## 🤝 Contributing ---- +Issues and pull requests are welcome. Before opening a PR: -## 📄 License +~~~bash +dotnet test tests/InputBridge.Core.Tests/InputBridge.Core.Tests.csproj -c Release +dotnet test tests/InputBridge.Linux.Tests/InputBridge.Linux.Tests.csproj -c Release +~~~ -This project is licensed under the [MIT License](LICENSE). +Please keep new warnings at zero; the repository treats warnings as errors. ---- +## 🗺️ Roadmap -

- Made with ❤️ by Önder Aktaş -

+- [ ] Multi-client control +- [ ] Clipboard sharing +- [ ] Monitor-edge switching +- [ ] File transfer +- [ ] macOS support +- [x] Windows ↔ Linux interoperability + +## 📄 License + +InputBridge is available under the **[MIT License](LICENSE)**.

- If you find InputBridge useful, consider giving it a ⭐ on GitHub! + Built with care by Önder Aktaş. + If InputBridge helps your setup, a ⭐ makes the bridge brighter.

diff --git a/docs/images/README_ASSETS.md b/docs/images/README_ASSETS.md new file mode 100644 index 0000000..e5e747c --- /dev/null +++ b/docs/images/README_ASSETS.md @@ -0,0 +1,27 @@ +# README visual assets + +## hero_banner.png + +- Purpose: GitHub repository README hero +- Dimensions: 1942 × 809 pixels +- Generator: OpenAI built-in ImageGen +- Generated: 2026-07-16 +- Source output: retained in the local Codex generated-images directory + +### Production prompt + +Use case: stylized-concept + +Asset type: GitHub repository README hero banner + +Primary request: A premium cinematic technology illustration for an open-source +network KVM app that lets one physical keyboard and mouse control two desktop +computers across a secure local network. + +Scene: A deep navy-to-black desktop environment with two computer setups, one shared +keyboard and mouse, and a luminous encrypted data bridge between the displays. + +Style: Polished high-end 3D editorial technology illustration with cyan light, +restrained violet accents, strong silhouettes and generous safe margins. + +Constraints: No words, typography, watermarks, human figures or extra computers. diff --git a/docs/images/hero_banner.png b/docs/images/hero_banner.png index eca1b6b..632e014 100644 Binary files a/docs/images/hero_banner.png and b/docs/images/hero_banner.png differ