Mouse #3

Merged
S4NKALP merged 18 commits from mouse into main 2025-10-19 05:19:14 +00:00
197 changed files with 3000 additions and 1580 deletions

No files matched your search

+11 -10
View File
@@ -1,3 +1,4 @@
name: build-and-test
concurrency:
@@ -35,27 +36,27 @@ jobs:
- name: Prepare data dir for runtime
run: |
mkdir -p "$PWD/share/keyvibe"
cp -r audio "$PWD/share/keyvibe/"
mkdir -p "$PWD/share/vbx"
cp -r audio "$PWD/share/vbx/"
- name: List sound packs
run: ./keyvibe --list
run: ./vbx --list
- name: Smoke test help
run: ./keyvibe --help || true
run: ./vbx --help || true
- name: Extra smoke tests (non-fatal)
run: |
./keyvibe --reload || true
./keyvibe --stop || true
./vbx --reload || true
./vbx --stop || true
- name: Upload binaries
uses: actions/upload-artifact@v4
with:
name: keyvibe-binaries
name: vbx-binaries
path: |
keyvibe
keyvibe-audio
keyvibe-input
vbx
vbx-audio
vbx-input
+28 -28
View File
@@ -1,6 +1,6 @@
CC = gcc
CFLAGS = -Wall -Wextra -std=c99 -Iinclude
# Updated include paths for modular headers
CFLAGS = -Wall -Wextra -std=c99 -Iinclude -Iinclude/app -Iinclude/audio -Iinclude/common -Iinclude/sound -Iinclude/config
PREFIX ?= /usr
# Pass PACKAGE_PREFIX macro for config.h
@@ -10,25 +10,25 @@ LDFLAGS_SOUND = -ljson-c -lpulse -lpulse-simple -lsndfile -lpthread
LDFLAGS_KEYBOARD = $(shell pkg-config --libs libevdev libinput libudev) -lpthread
# Targets
KeyVibe_TARGET = keyvibe
SOUND_TARGET = keyvibe-audio
KEYBOARD_TARGET = keyvibe-input
VBX_TARGET = vbx
SOUND_TARGET = audio
KEYBOARD_TARGET = input
# Sources
KeyVibe_SOURCE = src/keyvibe_main.c src/utils.c
SOUND_SOURCE = src/keyvibe_audio.c src/utils.c
KEYBOARD_SOURCE = src/keyvibe_input.c src/utils.c
# Sources (reorganized)
VBX_SOURCE = src/main.c src/common/utils.c src/config.c src/soundpacks.c src/app/process.c src/app/watch.c src/cli.c src/app/reload.c
SOUND_SOURCE = src/audio/main.c src/audio/config.c src/audio/playback.c src/common/utils.c
KEYBOARD_SOURCE = src/input.c src/common/utils.c
# Install paths
BINDIR = $(PREFIX)/bin
SHAREDIR = $(PREFIX)/share/keyvibe
UDEV_RULE = /etc/udev/rules.d/99-keyvibe-allow-keyboard.rules
SHAREDIR = $(PREFIX)/share/vbx
UDEV_RULE = /etc/udev/rules.d/99-vbx-allow-keyboard.rules
all: $(KeyVibe_TARGET) $(SOUND_TARGET) $(KEYBOARD_TARGET)
all: $(VBX_TARGET) $(SOUND_TARGET) $(KEYBOARD_TARGET)
# Build main launcher (needs json-c)
$(KeyVibe_TARGET): $(KeyVibe_SOURCE)
$(VBX_TARGET): $(VBX_SOURCE)
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $^ -ljson-c -lpthread
$(SOUND_TARGET): $(SOUND_SOURCE)
@@ -38,24 +38,24 @@ $(KEYBOARD_TARGET): $(KEYBOARD_SOURCE)
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $^ $(LDFLAGS_KEYBOARD)
clean:
rm -f $(KeyVibe_TARGET) $(SOUND_TARGET) $(KEYBOARD_TARGET)
rm -f $(VBX_TARGET) $(SOUND_TARGET) $(KEYBOARD_TARGET)
test: all
@echo "Testing sound packs:"
./$(KeyVibe_TARGET) --list
./$(VBX_TARGET) --list
@echo ""
@echo "To run KeyVibe:"
@echo " sudo ./$(KeyVibe_TARGET) # Default sound"
@echo " sudo ./$(KeyVibe_TARGET) -s cherrymx-blue-abs # Specific sound"
@echo " sudo ./$(KeyVibe_TARGET) --help # Show help"
@echo "To run VBX:"
@echo " sudo ./$(VBX_TARGET) # Default sound"
@echo " sudo ./$(VBX_TARGET) -s cherrymx-blue-abs # Specific sound"
@echo " sudo ./$(VBX_TARGET) --help # Show help"
install:
@echo "Installing KeyVibe to $(DESTDIR)$(BINDIR) and $(DESTDIR)$(SHAREDIR)..."
install -Dm755 $(KeyVibe_TARGET) $(DESTDIR)$(BINDIR)/$(KeyVibe_TARGET)
install -Dm755 $(SOUND_TARGET) $(DESTDIR)$(BINDIR)/$(SOUND_TARGET)
install -Dm755 $(KEYBOARD_TARGET) $(DESTDIR)$(BINDIR)/$(KEYBOARD_TARGET)
@echo "Installing VBX to $(DESTDIR)$(BINDIR) and $(DESTDIR)$(SHAREDIR)..."
install -Dm755 $(VBX_TARGET) $(DESTDIR)$(BINDIR)/$(VBX_TARGET)
install -Dm755 $(SOUND_TARGET) $(DESTDIR)$(BINDIR)/vbx-audio
install -Dm755 $(KEYBOARD_TARGET) $(DESTDIR)$(BINDIR)/vbx-input
install -d $(DESTDIR)$(SHAREDIR)
cp -r audio $(DESTDIR)$(SHAREDIR)/
cp -r soundpacks $(DESTDIR)$(SHAREDIR)/
@echo "Installing udev rule for non-root keyboard access..."
@echo '# Allow non-root access to input event devices for active seat users and input group' | sudo tee $(UDEV_RULE) >/dev/null
@echo 'SUBSYSTEM=="input", KERNEL=="event*", TAG+="uaccess", GROUP="input", MODE="0660"' | sudo tee -a $(UDEV_RULE) >/dev/null
@@ -70,10 +70,10 @@ install:
@echo "Installation complete."
uninstall:
@echo "Uninstalling KeyVibe from $(DESTDIR)$(BINDIR) and $(DESTDIR)$(SHAREDIR)..."
rm -f $(DESTDIR)$(BINDIR)/$(KeyVibe_TARGET)
rm -f $(DESTDIR)$(BINDIR)/$(SOUND_TARGET)
rm -f $(DESTDIR)$(BINDIR)/$(KEYBOARD_TARGET)
@echo "Uninstalling VBX from $(DESTDIR)$(BINDIR) and $(DESTDIR)$(SHAREDIR)..."
rm -f $(DESTDIR)$(BINDIR)/$(VBX_TARGET)
rm -f $(DESTDIR)$(BINDIR)/vbx-audio
rm -f $(DESTDIR)$(BINDIR)/vbx-input
rm -rf $(DESTDIR)$(SHAREDIR)
@echo "Removing udev rule..."
@sudo rm -f $(UDEV_RULE) || true
+27 -24
View File
@@ -1,22 +1,22 @@
<div align="center">
<img src="assets/logo.png" alt="Project Logo", height="200">
> A CLI tool that brings realistic mechanical keyboard sounds to every keystroke.
# vbx
KeyVibe listens to your keyboard events and plays high‑quality switch sounds with low latency. It ships with multiple sound packs and supports your own custom packs. Run it interactively or as a background daemon with live reload of your preferences.
> A CLI tool that brings realistic mechanical keyboard and mouse sounds to every keystroke.
vbx listens to your keyboard and mouse events and plays high‑quality switch sounds with low latency. It ships with multiple sound packs for both devices and supports your own custom packs. Run it interactively or as a background daemon with live reload of your references.
</div>
<div align="center">
[![Contributors](https://img.shields.io/github/contributors/S4NKALP/KeyVibe?style=for-the-badge&color=6366f1)](https://github.com/S4NKALP/KeyVibe/graphs/contributors)
[![Stars](https://img.shields.io/github/stars/S4NKALP/KeyVibe?style=for-the-badge&color=10b981)](https://github.com/S4NKALP/KeyVibe/stargazers)
[![Forks](https://img.shields.io/github/forks/S4NKALP/KeyVibe?style=for-the-badge&color=06b6d4)](https://github.com/S4NKALP/KeyVibe/network/members)
[![License](https://img.shields.io/github/license/S4NKALP/KeyVibe?style=for-the-badge&color=f59e0b)](LICENSE)
[![Issues](https://img.shields.io/github/issues/S4NKALP/KeyVibe?style=for-the-badge&color=ef4444)](https://github.com/S4NKALP/KeyVibe/issues)
[![Last Commit](https://img.shields.io/github/last-commit/S4NKALP/KeyVibe?style=for-the-badge&color=8b5cf6)](https://github.com/S4NKALP/KeyVibe/pulse)
[![Contributors](https://img.shields.io/github/contributors/S4NKALP/vbx?style=for-the-badge&color=6366f1)](https://github.com/S4NKALP/vbx/graphs/contributors)
[![Stars](https://img.shields.io/github/stars/S4NKALP/vbx?style=for-the-badge&color=10b981)](https://github.com/S4NKALP/vbx/stargazers)
[![Forks](https://img.shields.io/github/forks/S4NKALP/vbx?style=for-the-badge&color=06b6d4)](https://github.com/S4NKALP/vbx/network/members)
[![License](https://img.shields.io/github/license/S4NKALP/vbx?style=for-the-badge&color=f59e0b)](LICENSE)
[![Issues](https://img.shields.io/github/issues/S4NKALP/vbx?style=for-the-badge&color=ef4444)](https://github.com/S4NKALP/vbx/issues)
[![Last Commit](https://img.shields.io/github/last-commit/S4NKALP/vbx?style=for-the-badge&color=8b5cf6)](https://github.com/S4NKALP/vbx/pulse)
[**Report Bug**](https://github.com/S4NKALP/KeyVibe/issues) • [**Request Feature**](https://github.com/S4NKALP/KeyVibe/discussions)
[**Report Bug**](https://github.com/S4NKALP/vbx/issues) • [**Request Feature**](https://github.com/S4NKALP/vbx/discussions)
</div>
@@ -24,11 +24,12 @@ KeyVibe listens to your keyboard events and plays high‑quality switch sounds w
## ✨ Features
- Real-time key press/release sound playback
- Multiple bundled sound packs
- User sound packs under `~/.local/share/keyvibe/audio/`
- Real-time keyboard key press/release sound playback
- Real-time mouse click sound playback
- Multiple bundled sound packs for both keyboard and mouse
- User sound packs under `~/.local/share/vbx/audio/`
- Background daemon mode with PID file and safe shutdown
- Live config reload on `~/.keyvibe.json` changes (daemon mode)
- Live config reload on `~/.vbx.json` changes (daemon mode)
## 📋 Dependencies
@@ -46,21 +47,21 @@ KeyVibe listens to your keyboard events and plays high‑quality switch sounds w
### Arch Linux
```bash
paru -S keyvibe
paru -S vbx-git
```
### 🛠️ Build From Source
```bash
git clone https://github.com/S4NKALP/KeyVibe.git
cd KeyVibe
git clone https://github.com/S4NKALP/vbx.git
cd vbx
make
sudo make install
```
## 💡 Usage
Usage: keyvibe [OPTIONS]
Usage: vbx [OPTIONS]
Options:
-S, --sound SOUND_NAME Select sound pack (default: eg-oreo)
@@ -69,20 +70,21 @@ sudo make install
-s --stop Stop the background daemon
-m --mute Mute sound
-u --unmute Unmute sound
-- enbale/disable DEVICE_NAME Enable/disable a device
-l, --list List available sound packs
-h, --help Show this help message
-v, --verbose Enable verbose output
Notes:
- First run creates `~/.keyvibe.json`. Subsequent runs use it unless `-c` is supplied.
- In daemon mode, editing `~/.keyvibe.json` will automatically reload.
- First run creates `~/.vbx.json`. Subsequent runs use it unless `-c` is supplied.
- In daemon mode, editing `~/.vbx.json` will automatically reload.
## 🎵 Sound Packs
System packs are installed under: `/usr/share/keyvibe/audio/`
System packs are installed under: `/usr/share/vbx/soundpacks/`
User packs go under: `~/.local/share/keyvibe/audio/<pack-name>/`
User packs go under: `~/.local/share/vbx/soundpacks/<device-name>/<pack-name>/`
Required files inside each `<pack-name>/` directory:
@@ -91,7 +93,7 @@ Required files inside each `<pack-name>/` directory:
## 🤝 Contributing
PRs welcome. Please keep code modular and readable, and prefer small, focused changes.
Contributions are welcome! Feel free to open issues or submit pull requests.
## 📄 License
@@ -100,4 +102,5 @@ MIT — see [LICENSE](LICENSE).
## 🙏 Credits
- [MechVibes](https://github.com/hainguyents13/mechvibes) for sound packs
- [mechavibes-dx](https://github.com/hainguyents13/mechvibes-dx) for sound packs
- [showmethekey](https://github.com/AlynxZhou/showmethekey) for code
+25
View File
@@ -0,0 +1,25 @@
#ifndef VBX_CLI_H
#define VBX_CLI_H
typedef struct {
char *sound;
char *mouse_sound;
int volume;
int keyboard_volume;
int mouse_volume;
int daemon_flag;
int stop_flag;
int list_flag;
int verbose;
int keyboard_mute; // -1 unchanged, 0 unmute, 1 mute
int mouse_mute; // -1 unchanged, 0 unmute, 1 mute
int keyboard_enabled; // -1 unchanged, 0 disabled, 1 enabled
int mouse_enabled; // -1 unchanged, 0 disabled, 1 enabled
} CliOptions;
void print_usage(const char *program_name);
int parse_cli(int argc, char **argv, CliOptions *out);
#endif // VBX_CLI_H
+23
View File
@@ -0,0 +1,23 @@
#ifndef VBX_PROCESS_H
#define VBX_PROCESS_H
#include <signal.h>
#include <sys/types.h>
extern pid_t keyboard_pid;
extern pid_t sound_pid;
extern char pidfile_path[];
extern int is_daemon;
extern volatile sig_atomic_t reload_requested;
void cleanup_processes(int sig);
int require_running_pid(pid_t *out_pid);
void daemonize_self(void);
void stop_children(void);
int start_children(const char *sound_dir, const char *config_path, int volume,
int verbose, int mute, const char *mouse_sound_dir,
const char *mouse_config_path, int mouse_volume,
int keyboard_mute, int mouse_mute, int keyboard_enabled, int mouse_enabled);
void handle_sighup(int sig);
#endif // VBX_PROCESS_H
+15
View File
@@ -0,0 +1,15 @@
#ifndef VBX_RELOAD_H
#define VBX_RELOAD_H
int handle_reload(const char *user_cfg_path,
char *current_sound_name, char *current_mouse_sound_name,
int *current_keyboard_volume, int *current_mouse_volume,
char *current_config_path, char *current_sound_dir,
char *current_mouse_config_path, char *current_mouse_sound_dir,
int current_mute, int current_verbose,
int current_mouse_volume_arg, int current_keyboard_mute,
int current_mouse_mute, int *current_keyboard_enabled, int *current_mouse_enabled);
#endif // VBX_RELOAD_H
+6
View File
@@ -0,0 +1,6 @@
#ifndef VBX_WATCH_H
#define VBX_WATCH_H
int start_config_watcher(const char *path);
#endif // VBX_WATCH_H
+10
View File
@@ -0,0 +1,10 @@
#ifndef VBX_AUDIO_PLAYBACK_H
#define VBX_AUDIO_PLAYBACK_H
int init_audio(void);
int parse_keyboard_event(const char *json_line, int *key_code, int *is_pressed);
void play_sound_segment(int key_code, int is_pressed);
#endif // VBX_AUDIO_PLAYBACK_H
+45
View File
@@ -0,0 +1,45 @@
#ifndef VBX_AUDIO_TYPES_H
#define VBX_AUDIO_TYPES_H
#include <sndfile.h>
#define MAX_CONCURRENT_SOUNDS 10
typedef struct {
int start_ms;
int duration_ms;
} SoundMapping;
typedef struct {
char press_file[256];
char release_file[256];
char generic_press_files[5][256];
int num_generic_press_files;
char sound_file[256];
SoundMapping key_mappings[512];
struct {
char *press;
char *release;
} multi_key_mappings[512];
int is_multi;
SF_INFO sf_info;
} SoundPack;
typedef struct {
int key_code;
int thread_id;
int is_pressed;
} PlaybackData;
extern SoundPack g_sound_pack;
extern SoundPack g_mouse_sound_pack;
extern float g_volume;
extern float g_mouse_volume;
extern int g_verbose;
extern int g_mute;
extern int g_keyboard_mute;
extern int g_mouse_mute;
extern int g_keyboard_enabled;
extern int g_mouse_enabled;
#endif // VBX_AUDIO_TYPES_H
+9
View File
@@ -0,0 +1,9 @@
#ifndef VBX_MUTE_H
#define VBX_MUTE_H
int read_runtime_mute_file(void);
void write_runtime_mute_file(int mute);
void write_runtime_keyboard_mute_file(int mute);
void write_runtime_mouse_mute_file(int mute);
#endif // VBX_MUTE_H
+48
View File
@@ -0,0 +1,48 @@
#ifndef VBX_UTILS_H
#define VBX_UTILS_H
#include <stddef.h>
#include <stdio.h>
#include <sys/types.h>
// Returns 1 on success, 0 on truncation/error
int safe_snprintf(char *dst, size_t dst_sz, const char *fmt, ...);
// fprintf to stderr with printf-style formatting. Returns 1 for convenient
// `return errorf(...)` usage.
int errorf(const char *fmt, ...);
// Common runtime helpers
const char *get_runtime_dir(void);
void build_pidfile_path(char *buffer, size_t buflen);
int read_pidfile(const char *path, pid_t *out_pid);
int write_pidfile(const char *path, pid_t pid);
int process_is_running(pid_t pid);
// Runtime mute helpers
int read_runtime_mute_file(void);
void write_runtime_mute_file(int mute);
void write_runtime_keyboard_mute_file(int mute);
void write_runtime_mouse_mute_file(int mute);
// Runtime enabled helpers
int write_runtime_keyboard_enabled_file(int enabled);
int write_runtime_mouse_enabled_file(int enabled);
// Helper functions
void int_to_str(char *buffer, size_t size, int value);
char *xstrdup(const char *s);
int validate_volume(int volume);
const char *get_home_dir(void);
void safe_strncpy(char *dest, const char *src, size_t dest_size);
void print_error_and_close_file(FILE *file, const char *error_msg, const char *filename);
// Safe wrapper functions for clang-tidy compliance
int safe_fscanf(FILE *stream, const char *format, void *ptr);
int safe_fprintf(FILE *stream, const char *format, ...);
int safe_snprintf_wrapper(char *str, size_t size, const char *format, ...);
void *safe_memcpy(void *dest, const void *src, size_t n);
void *safe_memmove(void *dest, const void *src, size_t n);
void *safe_memset(void *s, int c, size_t n);
#endif // VBX_UTILS_H
+5 -5
View File
@@ -1,8 +1,8 @@
#ifndef __CONFIG_H__
#define __CONFIG_H__
#define PROJECT_VERSION "0.1.0"
#define GETTEXT_PACKAGE "keyvibe"
#define PROJECT_VERSION "1.1.0"
#define GETTEXT_PACKAGE "vbx"
#define PKEXEC_PATH "/usr/bin/pkexec"
// Prefix macro should be defined by compiler flags, fallback to /usr
@@ -13,8 +13,8 @@
#define PACKAGE_BINDIR PACKAGE_PREFIX "/bin"
#define PACKAGE_LOCALEDIR PACKAGE_PREFIX "/share/locale"
// KeyVibe specific paths relative to prefix
#define KeyVibe_DATA_DIR PACKAGE_PREFIX "/share/keyvibe"
#define KeyVibe_BIN_DIR PACKAGE_PREFIX "/bin"
// VBX specific paths relative to prefix
#define VBX_DATA_DIR PACKAGE_PREFIX "/share/vbx"
#define VBX_BIN_DIR PACKAGE_PREFIX "/bin"
#endif
+19
View File
@@ -0,0 +1,19 @@
#ifndef VBX_SOUNDPACKS_H
#define VBX_SOUNDPACKS_H
#include <stddef.h>
int resolve_keyboard_sound_base_dir(const char *sound_name, char *out_basedir,
size_t out_sz);
int resolve_mouse_sound_base_dir(const char *sound_name, char *out_basedir,
size_t out_sz);
int build_paths_for_keyboard_sound(const char *sound_name,
char *out_config_path, size_t out_config_sz,
char *out_sound_dir, size_t out_sound_sz);
int build_paths_for_mouse_sound(const char *sound_name, char *out_config_path,
size_t out_config_sz, char *out_sound_dir,
size_t out_sound_sz);
int validate_keyboard_sound_pack(const char *sound_name);
int validate_mouse_sound_pack(const char *sound_name);
int list_sound_packs(void);
#endif // VBX_SOUNDPACKS_H
+18
View File
@@ -0,0 +1,18 @@
#ifndef VBX_CONFIG_IO_H
#define VBX_CONFIG_IO_H
#include <stddef.h>
// Resolve user config path: returns buffer on success, NULL on failure
char *get_user_config_path(char *buffer, size_t buflen);
// Write ~/.vbx.json in new format
int write_user_config(const char *path, const char *keyboard_sound,
const char *mouse_sound, int keyboard_volume,
int mouse_volume, int keyboard_enabled, int mouse_enabled);
// Read ~/.vbx.json supporting new and legacy formats
int read_user_config(const char *path, char **out_keyboard_sound,
char **out_mouse_sound, int *out_keyboard_volume,
int *out_mouse_volume, int *out_keyboard_enabled, int *out_mouse_enabled);
#endif // VBX_CONFIG_IO_H
-22
View File
@@ -1,22 +0,0 @@
#ifndef KEYVIBE_UTILS_H
#define KEYVIBE_UTILS_H
#include <stddef.h>
#include <sys/types.h>
// Returns 1 on success, 0 on truncation/error
int safe_snprintf(char *dst, size_t dst_sz, const char *fmt, ...);
// fprintf to stderr with printf-style formatting. Returns 1 for convenient
// `return errorf(...)` usage.
int errorf(const char *fmt, ...);
// Common runtime helpers
const char *get_runtime_dir(void);
void build_pidfile_path(char *buffer, size_t buflen);
int read_pidfile(const char *path, pid_t *out_pid);
int write_pidfile(const char *path, pid_t pid);
int process_is_running(pid_t pid);
#endif // KEYVIBE_UTILS_H
File renamed without changes.
@@ -464,6 +464,18 @@
"61011": [
13964,
113
],
"272": [
971,
142
],
"273": [
1276,
115
],
"274": [
1604,
122
]
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file not shown.
@@ -0,0 +1,135 @@
{
"id": "custom-sound-pack-1203000000053",
"name": "Kalih Box White",
"key_define_type": "multi",
"includes_numpad": false,
"sound": "sound.ogg",
"defines": {
"1": "kboxwh - 08.mp3",
"2": "kboxwh - 10.mp3",
"3": "kboxwh - 06.mp3",
"4": "kboxwh - 03.mp3",
"5": "kboxwh - 02.mp3",
"6": "kboxwh - 08.mp3",
"7": "kboxwh - 07.mp3",
"8": "kboxwh - 04.mp3",
"9": "kboxwh - 01.mp3",
"10": "kboxwh - 04.mp3",
"11": "kboxwh - 02.mp3",
"12": "Untitled Clip(6).mp3",
"13": "Untitled Clip(5).mp3",
"14": "Untitled Clip(3).mp3",
"15": "Untitled Clip(4).mp3",
"16": "kboxwh - 05.mp3",
"17": "kboxwh - 01.mp3",
"18": "kboxwh - 06.mp3",
"19": "kboxwh - 07.mp3",
"20": "kboxwh - 05.mp3",
"21": "kboxwh - 03.mp3",
"22": "kboxwh - 10.mp3",
"23": "kboxwh - 01.mp3",
"24": "kboxwh - 03.mp3",
"25": "kboxwh - 06.mp3",
"26": "Untitled Clip(5).mp3",
"27": "Untitled Clip(6).mp3",
"28": "enter.mp3",
"29": "Untitled Clip(3).mp3",
"30": "kboxwh - 02.mp3",
"31": "kboxwh - 03.mp3",
"32": "kboxwh - 04.mp3",
"33": "kboxwh - 08.mp3",
"34": "kboxwh - 06.mp3",
"35": "kboxwh - 07.mp3",
"36": "kboxwh - 01.mp3",
"37": "Untitled Clip(3).mp3",
"38": "kboxwh - 06.mp3",
"39": "Untitled Clip(5).mp3",
"40": "Untitled Clip(6).mp3",
"41": "kboxwh - 09.mp3",
"42": "Untitled Clip(5).mp3",
"43": "enter.mp3",
"44": "kboxwh - 06.mp3",
"45": "kboxwh - 04.mp3",
"46": "kboxwh - 09.mp3",
"47": "kboxwh - 10.mp3",
"48": "kboxwh - 02.mp3",
"49": "kboxwh - 09.mp3",
"50": "kboxwh - 08.mp3",
"51": "Untitled Clip(7).mp3",
"52": "Untitled Clip(7).mp3",
"53": "kboxwh - 04.mp3",
"54": "Untitled Clip(5).mp3",
"55": "Untitled Clip(6).mp3",
"56": "alt.mp3",
"57": "Untitled Clip.mp3",
"58": "Untitled Clip(6).mp3",
"59": "kboxwh - 10.mp3",
"60": "kboxwh - 09.mp3",
"61": "kboxwh - 08.mp3",
"62": "kboxwh - 07.mp3",
"63": "kboxwh - 06.mp3",
"64": "kboxwh - 05.mp3",
"65": "kboxwh - 04.mp3",
"66": "kboxwh - 03.mp3",
"67": "kboxwh - 01.mp3",
"68": "kboxwh - 02.mp3",
"69": "Untitled Clip(5).mp3",
"70": null,
"71": "kboxwh - 08.mp3",
"72": "kboxwh - 07.mp3",
"73": "kboxwh - 03.mp3",
"74": "Untitled Clip(6).mp3",
"75": "kboxwh - 09.mp3",
"76": "kboxwh - 01.mp3",
"77": "kboxwh - 09.mp3",
"78": "Untitled Clip(6).mp3",
"79": "kboxwh - 09.mp3",
"80": "kboxwh - 03.mp3",
"81": "kboxwh - 04.mp3",
"82": "kboxwh - 02.mp3",
"83": "Untitled Clip(7).mp3",
"87": "kboxwh - 06.mp3",
"88": "kboxwh - 04.mp3",
"91": null,
"92": null,
"93": null,
"3597": null,
"3612": "enter.mp3",
"3613": "Untitled Clip(3).mp3",
"3637": "Untitled Clip(6).mp3",
"3639": null,
"3640": "alt.mp3",
"3653": null,
"3655": null,
"3657": null,
"3663": null,
"3665": null,
"3666": null,
"3667": null,
"3675": "Untitled Clip(7).mp3",
"3676": "Untitled Clip(7).mp3",
"3677": "Untitled Clip(3).mp3",
"57416": "kboxwh - 01.mp3",
"57419": "kboxwh - 02.mp3",
"57421": "kboxwh - 04.mp3",
"57424": "kboxwh - 03.mp3",
"60999": null,
"61000": "kboxwh - 01.mp3",
"61001": null,
"61003": "kboxwh - 02.mp3",
"61005": "kboxwh - 04.mp3",
"61007": null,
"61008": "kboxwh - 03.mp3",
"61009": null,
"61010": null,
"61011": null
},
"_zip": "kailh-box-white.zip",
"group": "1fMFAp - sOcaAT - MuxCD - GlHmN3",
"description": "Kailh Box White switches with individual sounds per keypress and no background noises.",
"m_author": "edy.",
"tags": [
"keyboard",
"clicky"
]
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loaded 100 of 197 files, more files were not shown because too many files have changed in this diff. Show more