From 2d7ca711848defca7c93b8b42cbb12ee76a16e5b Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Mon, 3 Jun 2024 17:54:11 -0700
Subject: [PATCH 01/32] Yowkees Keyball39 initial bring-up
Imported via ZIP from the designer's GitHub directory.
- https://github.com/Yowkees/keyball/tree/ef172dd614839034429452b0f41a343fe004ad8e/qmk_firmware/keyboards/keyball
- `main` branch at 2024-06-03 17:47 -0700
---
keyboards/yowkees/drivers/pmw3360/pmw3360.c | 176 ++++
keyboards/yowkees/drivers/pmw3360/pmw3360.h | 171 ++++
.../pmw3360/pmw3360_pointing_device_driver.c | 51 ++
keyboards/yowkees/drivers/pmw3360/srom_0x04.c | 263 ++++++
keyboards/yowkees/drivers/pmw3360/srom_0x81.c | 263 ++++++
keyboards/yowkees/keyball39/.noci | 0
keyboards/yowkees/keyball39/config.h | 79 ++
keyboards/yowkees/keyball39/info.json | 63 ++
keyboards/yowkees/keyball39/keyball39.c | 46 ++
keyboards/yowkees/keyball39/keyball39.h | 97 +++
.../keyball39/keymaps/default/config.h | 39 +
.../keyball39/keymaps/default/keymap.c | 71 ++
.../keyball39/keymaps/default/rules.mk | 3 +
.../keyball39/keymaps/develop/config.h | 33 +
.../keyball39/keymaps/develop/keymap.c | 51 ++
.../keyball39/keymaps/develop/rules.mk | 6 +
.../yowkees/keyball39/keymaps/test/config.h | 25 +
.../yowkees/keyball39/keymaps/test/keymap.c | 51 ++
.../yowkees/keyball39/keymaps/test/rules.mk | 6 +
.../yowkees/keyball39/keymaps/via/config.h | 39 +
.../yowkees/keyball39/keymaps/via/keymap.c | 71 ++
.../yowkees/keyball39/keymaps/via/rules.mk | 5 +
keyboards/yowkees/keyball39/readme.md | 21 +
keyboards/yowkees/keyball39/rules.mk | 49 ++
.../yowkees/lib/duplexmatrix/duplexmatrix.c | 177 ++++
.../yowkees/lib/duplexmatrix/duplexmatrix.h | 20 +
keyboards/yowkees/lib/glcdfont.c | 234 ++++++
keyboards/yowkees/lib/keyball/README.md | 128 +++
keyboards/yowkees/lib/keyball/keyball.c | 781 ++++++++++++++++++
keyboards/yowkees/lib/keyball/keyball.h | 272 ++++++
keyboards/yowkees/lib/keyball/keycodes.md | 52 ++
keyboards/yowkees/lib/logofont/font.md | 212 +++++
keyboards/yowkees/lib/logofont/logofont.c | 199 +++++
keyboards/yowkees/lib/oledkit/oledkit.c | 61 ++
keyboards/yowkees/lib/oledkit/oledkit.h | 34 +
35 files changed, 3849 insertions(+)
create mode 100644 keyboards/yowkees/drivers/pmw3360/pmw3360.c
create mode 100644 keyboards/yowkees/drivers/pmw3360/pmw3360.h
create mode 100644 keyboards/yowkees/drivers/pmw3360/pmw3360_pointing_device_driver.c
create mode 100644 keyboards/yowkees/drivers/pmw3360/srom_0x04.c
create mode 100644 keyboards/yowkees/drivers/pmw3360/srom_0x81.c
create mode 100644 keyboards/yowkees/keyball39/.noci
create mode 100644 keyboards/yowkees/keyball39/config.h
create mode 100644 keyboards/yowkees/keyball39/info.json
create mode 100644 keyboards/yowkees/keyball39/keyball39.c
create mode 100644 keyboards/yowkees/keyball39/keyball39.h
create mode 100644 keyboards/yowkees/keyball39/keymaps/default/config.h
create mode 100644 keyboards/yowkees/keyball39/keymaps/default/keymap.c
create mode 100644 keyboards/yowkees/keyball39/keymaps/default/rules.mk
create mode 100644 keyboards/yowkees/keyball39/keymaps/develop/config.h
create mode 100644 keyboards/yowkees/keyball39/keymaps/develop/keymap.c
create mode 100644 keyboards/yowkees/keyball39/keymaps/develop/rules.mk
create mode 100644 keyboards/yowkees/keyball39/keymaps/test/config.h
create mode 100644 keyboards/yowkees/keyball39/keymaps/test/keymap.c
create mode 100644 keyboards/yowkees/keyball39/keymaps/test/rules.mk
create mode 100644 keyboards/yowkees/keyball39/keymaps/via/config.h
create mode 100644 keyboards/yowkees/keyball39/keymaps/via/keymap.c
create mode 100644 keyboards/yowkees/keyball39/keymaps/via/rules.mk
create mode 100644 keyboards/yowkees/keyball39/readme.md
create mode 100644 keyboards/yowkees/keyball39/rules.mk
create mode 100644 keyboards/yowkees/lib/duplexmatrix/duplexmatrix.c
create mode 100644 keyboards/yowkees/lib/duplexmatrix/duplexmatrix.h
create mode 100644 keyboards/yowkees/lib/glcdfont.c
create mode 100644 keyboards/yowkees/lib/keyball/README.md
create mode 100644 keyboards/yowkees/lib/keyball/keyball.c
create mode 100644 keyboards/yowkees/lib/keyball/keyball.h
create mode 100644 keyboards/yowkees/lib/keyball/keycodes.md
create mode 100644 keyboards/yowkees/lib/logofont/font.md
create mode 100644 keyboards/yowkees/lib/logofont/logofont.c
create mode 100644 keyboards/yowkees/lib/oledkit/oledkit.c
create mode 100644 keyboards/yowkees/lib/oledkit/oledkit.h
diff --git a/keyboards/yowkees/drivers/pmw3360/pmw3360.c b/keyboards/yowkees/drivers/pmw3360/pmw3360.c
new file mode 100644
index 00000000000..02a9097614f
--- /dev/null
+++ b/keyboards/yowkees/drivers/pmw3360/pmw3360.c
@@ -0,0 +1,176 @@
+/*
+Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include "quantum.h"
+#include "pmw3360.h"
+
+// Include SROM definitions.
+#include "srom_0x04.c"
+#include "srom_0x81.c"
+
+#define PMW3360_SPI_MODE 3
+#define PMW3360_SPI_DIVISOR (F_CPU / PMW3360_CLOCKS)
+#define PMW3360_CLOCKS 2000000
+
+static bool motion_bursting = false;
+
+bool pmw3360_spi_start(void) {
+ return spi_start(PMW3360_NCS_PIN, false, PMW3360_SPI_MODE, PMW3360_SPI_DIVISOR);
+}
+
+uint8_t pmw3360_reg_read(uint8_t addr) {
+ pmw3360_spi_start();
+ spi_write(addr & 0x7f);
+ wait_us(160);
+ uint8_t data = spi_read();
+ wait_us(1);
+ spi_stop();
+ wait_us(19);
+ // Reset motion_bursting mode if read from a register other than motion
+ // burst register.
+ if (addr != pmw3360_Motion_Burst) {
+ motion_bursting = false;
+ }
+ return data;
+}
+
+void pmw3360_reg_write(uint8_t addr, uint8_t data) {
+ pmw3360_spi_start();
+ spi_write(addr | 0x80);
+ spi_write(data);
+ wait_us(35);
+ spi_stop();
+ wait_us(145);
+}
+
+uint8_t pmw3360_cpi_get(void) {
+ return pmw3360_reg_read(pmw3360_Config1);
+}
+
+void pmw3360_cpi_set(uint8_t cpi) {
+ if (cpi > pmw3360_MAXCPI) {
+ cpi = pmw3360_MAXCPI;
+ }
+ pmw3360_reg_write(pmw3360_Config1, cpi);
+}
+
+static uint32_t pmw3360_timer = 0;
+static uint32_t pmw3360_scan_count = 0;
+static uint32_t pmw3360_last_count = 0;
+
+void pmw3360_scan_perf_task(void) {
+ pmw3360_scan_count++;
+ uint32_t now = timer_read32();
+ if (TIMER_DIFF_32(now, pmw3360_timer) > 1000) {
+#if defined(CONSOLE_ENABLE)
+ dprintf("pmw3360 scan frequency: %lu\n", pmw3360_scan_count);
+#endif
+ pmw3360_last_count = pmw3360_scan_count;
+ pmw3360_scan_count = 0;
+ pmw3360_timer = now;
+ }
+}
+
+uint32_t pmw3360_scan_rate_get(void) {
+ return pmw3360_last_count;
+}
+
+bool pmw3360_motion_read(pmw3360_motion_t *d) {
+#ifdef DEBUG_PMW3360_SCAN_RATE
+ pmw3360_scan_perf_task();
+#endif
+ uint8_t mot = pmw3360_reg_read(pmw3360_Motion);
+ if ((mot & 0x88) != 0x80) {
+ return false;
+ }
+ d->x = pmw3360_reg_read(pmw3360_Delta_X_L);
+ d->x |= pmw3360_reg_read(pmw3360_Delta_X_H) << 8;
+ d->y = pmw3360_reg_read(pmw3360_Delta_Y_L);
+ d->y |= pmw3360_reg_read(pmw3360_Delta_Y_H) << 8;
+ return true;
+}
+
+bool pmw3360_motion_burst(pmw3360_motion_t *d) {
+#ifdef DEBUG_PMW3360_SCAN_RATE
+ pmw3360_scan_perf_task();
+#endif
+ // Start motion burst if motion burst mode is not started.
+ if (!motion_bursting) {
+ pmw3360_reg_write(pmw3360_Motion_Burst, 0);
+ motion_bursting = true;
+ }
+
+ pmw3360_spi_start();
+ spi_write(pmw3360_Motion_Burst);
+ wait_us(35);
+ spi_read(); // skip MOT
+ spi_read(); // skip Observation
+ d->x = spi_read();
+ d->x |= spi_read() << 8;
+ d->y = spi_read();
+ d->y |= spi_read() << 8;
+ spi_stop();
+ // Required NCS in 500ns after motion burst.
+ wait_us(1);
+ return true;
+}
+
+bool pmw3360_init(void) {
+ spi_init();
+ setPinOutput(PMW3360_NCS_PIN);
+ // reboot
+ pmw3360_spi_start();
+ pmw3360_reg_write(pmw3360_Power_Up_Reset, 0x5a);
+ wait_ms(50);
+ // read five registers of motion and discard those values
+ pmw3360_reg_read(pmw3360_Motion);
+ pmw3360_reg_read(pmw3360_Delta_X_L);
+ pmw3360_reg_read(pmw3360_Delta_X_H);
+ pmw3360_reg_read(pmw3360_Delta_Y_L);
+ pmw3360_reg_read(pmw3360_Delta_Y_H);
+ // configuration
+ pmw3360_reg_write(pmw3360_Config2, 0x00);
+ // check product ID and revision ID
+ uint8_t pid = pmw3360_reg_read(pmw3360_Product_ID);
+ uint8_t rev = pmw3360_reg_read(pmw3360_Revision_ID);
+ spi_stop();
+ return pid == 0x42 && rev == 0x01;
+}
+
+uint8_t pmw3360_srom_id = 0;
+
+void pmw3360_srom_upload(pmw3360_srom_t srom) {
+ pmw3360_reg_write(pmw3360_Config2, 0x00);
+ pmw3360_reg_write(pmw3360_SROM_Enable, 0x1d);
+ wait_us(10);
+ pmw3360_reg_write(pmw3360_SROM_Enable, 0x18);
+
+ // SROM upload (download for PMW3360) with burst mode
+ pmw3360_spi_start();
+ spi_write(pmw3360_SROM_Load_Burst | 0x80);
+ wait_us(15);
+ for (size_t i = 0; i < srom.len; i++) {
+ spi_write(pgm_read_byte(srom.data + i));
+ wait_us(15);
+ }
+ spi_stop();
+ wait_us(200);
+
+ pmw3360_srom_id = pmw3360_reg_read(pmw3360_SROM_ID);
+ pmw3360_reg_write(pmw3360_Config2, 0x00);
+ wait_ms(10);
+}
diff --git a/keyboards/yowkees/drivers/pmw3360/pmw3360.h b/keyboards/yowkees/drivers/pmw3360/pmw3360.h
new file mode 100644
index 00000000000..ebac2f69945
--- /dev/null
+++ b/keyboards/yowkees/drivers/pmw3360/pmw3360.h
@@ -0,0 +1,171 @@
+/*
+Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#pragma once
+
+#include
+#include "spi_master.h"
+
+//////////////////////////////////////////////////////////////////////////////
+// Configurations
+
+#ifndef PMW3360_NCS_PIN
+# define PMW3360_NCS_PIN B6
+#endif
+
+/// DEBUG_PMW3360_SCAN_RATE enables scan performance counter.
+/// It records scan count in a last second and enables pmw3360_scan_rate_get().
+/// Additionally, it will be logged automatically when defined CONSOLE_ENABLE
+/// and `debug_enable = true`.
+//#define DEBUG_PMW3360_SCAN_RATE
+
+//////////////////////////////////////////////////////////////////////////////
+// Types
+
+typedef struct {
+ const uint8_t *data;
+ size_t len;
+} pmw3360_srom_t;
+
+typedef struct {
+ int16_t x;
+ int16_t y;
+} pmw3360_motion_t;
+
+typedef enum {
+ pmw3360_Product_ID = 0x00,
+ pmw3360_Revision_ID = 0x01,
+ pmw3360_Motion = 0x02,
+ pmw3360_Delta_X_L = 0x03,
+ pmw3360_Delta_X_H = 0x04,
+ pmw3360_Delta_Y_L = 0x05,
+ pmw3360_Delta_Y_H = 0x06,
+ pmw3360_SQUAL = 0x07,
+ pmw3360_Raw_Data_Sum = 0x08,
+ pmw3360_Maximum_Raw_data = 0x09,
+ pmw3360_Minimum_Raw_data = 0x0A,
+ pmw3360_Shutter_Lower = 0x0B,
+ pmw3360_Shutter_Upper = 0x0C,
+ pmw3360_Control = 0x0D,
+ pmw3360_Config1 = 0x0F,
+ pmw3360_Config2 = 0x10,
+ pmw3360_Angle_Tune = 0x11,
+ pmw3360_Frame_Capture = 0x12,
+ pmw3360_SROM_Enable = 0x13,
+ pmw3360_Run_Downshift = 0x14,
+ pmw3360_Rest1_Rate_Lower = 0x15,
+ pmw3360_Rest1_Rate_Upper = 0x16,
+ pmw3360_Rest1_Downshift = 0x17,
+ pmw3360_Rest2_Rate_Lower = 0x18,
+ pmw3360_Rest2_Rate_Upper = 0x19,
+ pmw3360_Rest2_Downshift = 0x1A,
+ pmw3360_Rest3_Rate_Lower = 0x1B,
+ pmw3360_Rest3_Rate_Upper = 0x1C,
+ pmw3360_Observation = 0x24,
+ pmw3360_Data_Out_Lower = 0x25,
+ pmw3360_Data_Out_Upper = 0x26,
+ pmw3360_Raw_Data_Dump = 0x29,
+ pmw3360_SROM_ID = 0x2A,
+ pmw3360_Min_SQ_Run = 0x2B,
+ pmw3360_Raw_Data_Threshold = 0x2C,
+ pmw3360_Config5 = 0x2F,
+ pmw3360_Power_Up_Reset = 0x3A,
+ pmw3360_Shutdown = 0x3B,
+ pmw3360_Inverse_Product_ID = 0x3F,
+ pmw3360_LiftCutoff_Tune3 = 0x41,
+ pmw3360_Angle_Snap = 0x42,
+ pmw3360_LiftCutoff_Tune1 = 0x4A,
+ pmw3360_Motion_Burst = 0x50,
+ pmw3360_LiftCutoff_Tune_Timeout = 0x58,
+ pmw3360_LiftCutoff_Tune_Min_Length = 0x5A,
+ pmw3360_SROM_Load_Burst = 0x62,
+ pmw3360_Lift_Config = 0x63,
+ pmw3360_Raw_Data_Burst = 0x64,
+ pmw3360_LiftCutoff_Tune2 = 0x65,
+} pmw3360_reg_t;
+
+enum {
+ pmw3360_MAXCPI = 0x77, // = 119: 12000 CPI
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// Exported values (touch carefully)
+
+/// SROM ID, last uploaded. 0 means not uploaded yet.
+extern uint8_t pmw3360_srom_id;
+
+/// SROM 0x04
+extern const pmw3360_srom_t pmw3360_srom_0x04;
+/// SROM 0x81
+extern const pmw3360_srom_t pmw3360_srom_0x81;
+
+//////////////////////////////////////////////////////////////////////////////
+// Top level API
+
+/// pmw3360_init initializes PMW3360DM-T2QU module.
+/// It will return true when succeeded, otherwise false.
+bool pmw3360_init(void);
+
+void pmw3360_srom_upload(pmw3360_srom_t srom);
+
+/// pmw3360_motion_read gets a motion data by Motion register.
+/// This requires to write a dummy data to pmw3360_Motion register
+/// just before.
+bool pmw3360_motion_read(pmw3360_motion_t *d);
+
+/// pmw3360_motion_burst gets a motion data by Motion_Burst command.
+/// This requires to write a dummy data to pmw3360_Motion_Burst register
+/// just before.
+bool pmw3360_motion_burst(pmw3360_motion_t *d);
+
+/// pmw3360_scan_rate_get gets count of scan in a last second.
+/// This works only when DEBUG_PMW3360_SCAN_RATE is defined.
+uint32_t pmw3360_scan_rate_get(void);
+
+// TODO: document
+uint8_t pmw3360_cpi_get(void);
+
+// TODO: document
+void pmw3360_cpi_set(uint8_t cpi);
+
+//////////////////////////////////////////////////////////////////////////////
+// Register operations
+
+/// pmw3360_reg_write writes a value to a register.
+void pmw3360_reg_write(uint8_t addr, uint8_t data);
+
+/// pmw3360_reg_read reads a value from a register.
+uint8_t pmw3360_reg_read(uint8_t addr);
+
+//////////////////////////////////////////////////////////////////////////////
+// SPI operations
+
+bool pmw3360_spi_start(void);
+
+void inline pmw3360_spi_stop(void) {
+ spi_stop();
+}
+
+/// \deprecated use pmw3360_reg_write() instead of this.
+spi_status_t inline pmw3360_spi_write(uint8_t data) {
+ return spi_write(data);
+}
+
+/// \deprecated use pmw3360_reg_read() instead of this.
+spi_status_t inline pmw3360_spi_read(void) {
+ return spi_read();
+}
diff --git a/keyboards/yowkees/drivers/pmw3360/pmw3360_pointing_device_driver.c b/keyboards/yowkees/drivers/pmw3360/pmw3360_pointing_device_driver.c
new file mode 100644
index 00000000000..50c187bdd1e
--- /dev/null
+++ b/keyboards/yowkees/drivers/pmw3360/pmw3360_pointing_device_driver.c
@@ -0,0 +1,51 @@
+/*
+Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include "pointing_device.h"
+#include "pmw3360.h"
+
+bool pmw3360_has = false;
+
+void pointing_device_driver_init(void) {
+ pmw3360_has = pmw3360_init();
+ pmw3360_reg_write(pmw3360_Motion_Burst, 0);
+}
+
+#define constrain_hid(amt) ((amt) < -127 ? -127 : ((amt) > 127 ? 127 : (amt)))
+
+report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report) {
+ pmw3360_motion_t d = {0};
+ if (pmw3360_has && pmw3360_motion_burst(&d)) {
+ mouse_report.x = constrain_hid(d.y);
+ mouse_report.y = constrain_hid(d.x);
+ }
+ return mouse_report;
+}
+
+uint16_t pointing_device_driver_get_cpi(void) {
+ if (!pmw3360_has) {
+ return 0;
+ }
+ return pmw3360_cpi_get();
+}
+
+void pointing_device_driver_set_cpi(uint16_t cpi) {
+ if (!pmw3360_has) {
+ return;
+ }
+ pmw3360_cpi_set(cpi);
+}
diff --git a/keyboards/yowkees/drivers/pmw3360/srom_0x04.c b/keyboards/yowkees/drivers/pmw3360/srom_0x04.c
new file mode 100644
index 00000000000..dd471cab90c
--- /dev/null
+++ b/keyboards/yowkees/drivers/pmw3360/srom_0x04.c
@@ -0,0 +1,263 @@
+static const uint8_t srom_data_0x04[] PROGMEM = {
+ 0x01, 0x04, 0x8E, 0x96, 0x6E, 0x77, 0x3E, 0xFE, 0x7E, 0x5F, 0x1D, 0xB8, 0xF2, 0x66, 0x4E, 0xFF,
+ 0x5D, 0x19, 0xB0, 0xC2, 0x04, 0x69, 0x54, 0x2A, 0xD6, 0x2E, 0xBF, 0xDD, 0x19, 0xB0, 0xC3, 0xE5,
+ 0x29, 0xB1, 0xE0, 0x23, 0xA5, 0xA9, 0xB1, 0xC1, 0x00, 0x82, 0x67, 0x4C, 0x1A, 0x97, 0x8D, 0x79,
+ 0x51, 0x20, 0xC7, 0x06, 0x8E, 0x7C, 0x7C, 0x7A, 0x76, 0x4F, 0xFD, 0x59, 0x30, 0xE2, 0x46, 0x0E,
+ 0x9E, 0xBE, 0xDF, 0x1D, 0x99, 0x91, 0xA0, 0xA5, 0xA1, 0xA9, 0xD0, 0x22, 0xC6, 0xEF, 0x5C, 0x1B,
+ 0x95, 0x89, 0x90, 0xA2, 0xA7, 0xCC, 0xFB, 0x55, 0x28, 0xB3, 0xE4, 0x4A, 0xF7, 0x6C, 0x3B, 0xF4,
+ 0x6A, 0x56, 0x2E, 0xDE, 0x1F, 0x9D, 0xB8, 0xD3, 0x05, 0x88, 0x92, 0xA6, 0xCE, 0x1E, 0xBE, 0xDF,
+ 0x1D, 0x99, 0xB0, 0xE2, 0x46, 0xEF, 0x5C, 0x07, 0x11, 0x5D, 0x98, 0x0B, 0x9D, 0x94, 0x97, 0xEE,
+ 0x4E, 0x45, 0x33, 0x6B, 0x44, 0xC7, 0x29, 0x56, 0x27, 0x30, 0xC6, 0xA7, 0xD5, 0xF2, 0x56, 0xDF,
+ 0xB4, 0x38, 0x62, 0xCB, 0xA0, 0xB6, 0xE3, 0x0F, 0x84, 0x06, 0x24, 0x05, 0x65, 0x6F, 0x76, 0x89,
+ 0xB5, 0x77, 0x41, 0x27, 0x82, 0x66, 0x65, 0x82, 0xCC, 0xD5, 0xE6, 0x20, 0xD5, 0x27, 0x17, 0xC5,
+ 0xF8, 0x03, 0x23, 0x7C, 0x5F, 0x64, 0xA5, 0x1D, 0xC1, 0xD6, 0x36, 0xCB, 0x4C, 0xD4, 0xDB, 0x66,
+ 0xD7, 0x8B, 0xB1, 0x99, 0x7E, 0x6F, 0x4C, 0x36, 0x40, 0x06, 0xD6, 0xEB, 0xD7, 0xA2, 0xE4, 0xF4,
+ 0x95, 0x51, 0x5A, 0x54, 0x96, 0xD5, 0x53, 0x44, 0xD7, 0x8C, 0xE0, 0xB9, 0x40, 0x68, 0xD2, 0x18,
+ 0xE9, 0xDD, 0x9A, 0x23, 0x92, 0x48, 0xEE, 0x7F, 0x43, 0xAF, 0xEA, 0x77, 0x38, 0x84, 0x8C, 0x0A,
+ 0x72, 0xAF, 0x69, 0xF8, 0xDD, 0xF1, 0x24, 0x83, 0xA3, 0xF8, 0x4A, 0xBF, 0xF5, 0x94, 0x13, 0xDB,
+ 0xBB, 0xD8, 0xB4, 0xB3, 0xA0, 0xFB, 0x45, 0x50, 0x60, 0x30, 0x59, 0x12, 0x31, 0x71, 0xA2, 0xD3,
+ 0x13, 0xE7, 0xFA, 0xE7, 0xCE, 0x0F, 0x63, 0x15, 0x0B, 0x6B, 0x94, 0xBB, 0x37, 0x83, 0x26, 0x05,
+ 0x9D, 0xFB, 0x46, 0x92, 0xFC, 0x0A, 0x15, 0xD1, 0x0D, 0x73, 0x92, 0xD6, 0x8C, 0x1B, 0x8C, 0xB8,
+ 0x55, 0x8A, 0xCE, 0xBD, 0xFE, 0x8E, 0xFC, 0xED, 0x09, 0x12, 0x83, 0x91, 0x82, 0x51, 0x31, 0x23,
+ 0xFB, 0xB4, 0x0C, 0x76, 0xAD, 0x7C, 0xD9, 0xB4, 0x4B, 0xB2, 0x67, 0x14, 0x09, 0x9C, 0x7F, 0x0C,
+ 0x18, 0xBA, 0x3B, 0xD6, 0x8E, 0x14, 0x2A, 0xE4, 0x1B, 0x52, 0x9F, 0x2B, 0x7D, 0xE1, 0xFB, 0x6A,
+ 0x33, 0x02, 0xFA, 0xAC, 0x5A, 0xF2, 0x3E, 0x88, 0x7E, 0xAE, 0xD1, 0xF3, 0x78, 0xE8, 0x05, 0xD1,
+ 0xE3, 0xDC, 0x21, 0xF6, 0xE1, 0x9A, 0xBD, 0x17, 0x0E, 0xD9, 0x46, 0x9B, 0x88, 0x03, 0xEA, 0xF6,
+ 0x66, 0xBE, 0x0E, 0x1B, 0x50, 0x49, 0x96, 0x40, 0x97, 0xF1, 0xF1, 0xE4, 0x80, 0xA6, 0x6E, 0xE8,
+ 0x77, 0x34, 0xBF, 0x29, 0x40, 0x44, 0xC2, 0xFF, 0x4E, 0x98, 0xD3, 0x9C, 0xA3, 0x32, 0x2B, 0x76,
+ 0x51, 0x04, 0x09, 0xE7, 0xA9, 0xD1, 0xA6, 0x32, 0xB1, 0x23, 0x53, 0xE2, 0x47, 0xAB, 0xD6, 0xF5,
+ 0x69, 0x5C, 0x3E, 0x5F, 0xFA, 0xAE, 0x45, 0x20, 0xE5, 0xD2, 0x44, 0xFF, 0x39, 0x32, 0x6D, 0xFD,
+ 0x27, 0x57, 0x5C, 0xFD, 0xF0, 0xDE, 0xC1, 0xB5, 0x99, 0xE5, 0xF5, 0x1C, 0x77, 0x01, 0x75, 0xC5,
+ 0x6D, 0x58, 0x92, 0xF2, 0xB2, 0x47, 0x00, 0x01, 0x26, 0x96, 0x7A, 0x30, 0xFF, 0xB7, 0xF0, 0xEF,
+ 0x77, 0xC1, 0x8A, 0x5D, 0xDC, 0xC0, 0xD1, 0x29, 0x30, 0x1E, 0x77, 0x38, 0x7A, 0x94, 0xF1, 0xB8,
+ 0x7A, 0x7E, 0xEF, 0xA4, 0xD1, 0xAC, 0x31, 0x4A, 0xF2, 0x5D, 0x64, 0x3D, 0xB2, 0xE2, 0xF0, 0x08,
+ 0x99, 0xFC, 0x70, 0xEE, 0x24, 0xA7, 0x7E, 0xEE, 0x1E, 0x20, 0x69, 0x7D, 0x44, 0xBF, 0x87, 0x42,
+ 0xDF, 0x88, 0x3B, 0x0C, 0xDA, 0x42, 0xC9, 0x04, 0xF9, 0x45, 0x50, 0xFC, 0x83, 0x8F, 0x11, 0x6A,
+ 0x72, 0xBC, 0x99, 0x95, 0xF0, 0xAC, 0x3D, 0xA7, 0x3B, 0xCD, 0x1C, 0xE2, 0x88, 0x79, 0x37, 0x11,
+ 0x5F, 0x39, 0x89, 0x95, 0x0A, 0x16, 0x84, 0x7A, 0xF6, 0x8A, 0xA4, 0x28, 0xE4, 0xED, 0x83, 0x80,
+ 0x3B, 0xB1, 0x23, 0xA5, 0x03, 0x10, 0xF4, 0x66, 0xEA, 0xBB, 0x0C, 0x0F, 0xC5, 0xEC, 0x6C, 0x69,
+ 0xC5, 0xD3, 0x24, 0xAB, 0xD4, 0x2A, 0xB7, 0x99, 0x88, 0x76, 0x08, 0xA0, 0xA8, 0x95, 0x7C, 0xD8,
+ 0x38, 0x6D, 0xCD, 0x59, 0x02, 0x51, 0x4B, 0xF1, 0xB5, 0x2B, 0x50, 0xE3, 0xB6, 0xBD, 0xD0, 0x72,
+ 0xCF, 0x9E, 0xFD, 0x6E, 0xBB, 0x44, 0xC8, 0x24, 0x8A, 0x77, 0x18, 0x8A, 0x13, 0x06, 0xEF, 0x97,
+ 0x7D, 0xFA, 0x81, 0xF0, 0x31, 0xE6, 0xFA, 0x77, 0xED, 0x31, 0x06, 0x31, 0x5B, 0x54, 0x8A, 0x9F,
+ 0x30, 0x68, 0xDB, 0xE2, 0x40, 0xF8, 0x4E, 0x73, 0xFA, 0xAB, 0x74, 0x8B, 0x10, 0x58, 0x13, 0xDC,
+ 0xD2, 0xE6, 0x78, 0xD1, 0x32, 0x2E, 0x8A, 0x9F, 0x2C, 0x58, 0x06, 0x48, 0x27, 0xC5, 0xA9, 0x5E,
+ 0x81, 0x47, 0x89, 0x46, 0x21, 0x91, 0x03, 0x70, 0xA4, 0x3E, 0x88, 0x9C, 0xDA, 0x33, 0x0A, 0xCE,
+ 0xBC, 0x8B, 0x8E, 0xCF, 0x9F, 0xD3, 0x71, 0x80, 0x43, 0xCF, 0x6B, 0xA9, 0x51, 0x83, 0x76, 0x30,
+ 0x82, 0xC5, 0x6A, 0x85, 0x39, 0x11, 0x50, 0x1A, 0x82, 0xDC, 0x1E, 0x1C, 0xD5, 0x7D, 0xA9, 0x71,
+ 0x99, 0x33, 0x47, 0x19, 0x97, 0xB3, 0x5A, 0xB1, 0xDF, 0xED, 0xA4, 0xF2, 0xE6, 0x26, 0x84, 0xA2,
+ 0x28, 0x9A, 0x9E, 0xDF, 0xA6, 0x6A, 0xF4, 0xD6, 0xFC, 0x2E, 0x5B, 0x9D, 0x1A, 0x2A, 0x27, 0x68,
+ 0xFB, 0xC1, 0x83, 0x21, 0x4B, 0x90, 0xE0, 0x36, 0xDD, 0x5B, 0x31, 0x42, 0x55, 0xA0, 0x13, 0xF7,
+ 0xD0, 0x89, 0x53, 0x71, 0x99, 0x57, 0x09, 0x29, 0xC5, 0xF3, 0x21, 0xF8, 0x37, 0x2F, 0x40, 0xF3,
+ 0xD4, 0xAF, 0x16, 0x08, 0x36, 0x02, 0xFC, 0x77, 0xC5, 0x8B, 0x04, 0x90, 0x56, 0xB9, 0xC9, 0x67,
+ 0x9A, 0x99, 0xE8, 0x00, 0xD3, 0x86, 0xFF, 0x97, 0x2D, 0x08, 0xE9, 0xB7, 0xB3, 0x91, 0xBC, 0xDF,
+ 0x45, 0xC6, 0xED, 0x0F, 0x8C, 0x4C, 0x1E, 0xE6, 0x5B, 0x6E, 0x38, 0x30, 0xE4, 0xAA, 0xE3, 0x95,
+ 0xDE, 0xB9, 0xE4, 0x9A, 0xF5, 0xB2, 0x55, 0x9A, 0x87, 0x9B, 0xF6, 0x6A, 0xB2, 0xF2, 0x77, 0x9A,
+ 0x31, 0xF4, 0x7A, 0x31, 0xD1, 0x1D, 0x04, 0xC0, 0x7C, 0x32, 0xA2, 0x9E, 0x9A, 0xF5, 0x62, 0xF8,
+ 0x27, 0x8D, 0xBF, 0x51, 0xFF, 0xD3, 0xDF, 0x64, 0x37, 0x3F, 0x2A, 0x6F, 0x76, 0x3A, 0x7D, 0x77,
+ 0x06, 0x9E, 0x77, 0x7F, 0x5E, 0xEB, 0x32, 0x51, 0xF9, 0x16, 0x66, 0x9A, 0x09, 0xF3, 0xB0, 0x08,
+ 0xA4, 0x70, 0x96, 0x46, 0x30, 0xFF, 0xDA, 0x4F, 0xE9, 0x1B, 0xED, 0x8D, 0xF8, 0x74, 0x1F, 0x31,
+ 0x92, 0xB3, 0x73, 0x17, 0x36, 0xDB, 0x91, 0x30, 0xD6, 0x88, 0x55, 0x6B, 0x34, 0x77, 0x87, 0x7A,
+ 0xE7, 0xEE, 0x06, 0xC6, 0x1C, 0x8C, 0x19, 0x0C, 0x48, 0x46, 0x23, 0x5E, 0x9C, 0x07, 0x5C, 0xBF,
+ 0xB4, 0x7E, 0xD6, 0x4F, 0x74, 0x9C, 0xE2, 0xC5, 0x50, 0x8B, 0xC5, 0x8B, 0x15, 0x90, 0x60, 0x62,
+ 0x57, 0x29, 0xD0, 0x13, 0x43, 0xA1, 0x80, 0x88, 0x91, 0x00, 0x44, 0xC7, 0x4D, 0x19, 0x86, 0xCC,
+ 0x2F, 0x2A, 0x75, 0x5A, 0xFC, 0xEB, 0x97, 0x2A, 0x70, 0xE3, 0x78, 0xD8, 0x91, 0xB0, 0x4F, 0x99,
+ 0x07, 0xA3, 0x95, 0xEA, 0x24, 0x21, 0xD5, 0xDE, 0x51, 0x20, 0x93, 0x27, 0x0A, 0x30, 0x73, 0xA8,
+ 0xFF, 0x8A, 0x97, 0xE9, 0xA7, 0x6A, 0x8E, 0x0D, 0xE8, 0xF0, 0xDF, 0xEC, 0xEA, 0xB4, 0x6C, 0x1D,
+ 0x39, 0x2A, 0x62, 0x2D, 0x3D, 0x5A, 0x8B, 0x65, 0xF8, 0x90, 0x05, 0x2E, 0x7E, 0x91, 0x2C, 0x78,
+ 0xEF, 0x8E, 0x7A, 0xC1, 0x2F, 0xAC, 0x78, 0xEE, 0xAF, 0x28, 0x45, 0x06, 0x4C, 0x26, 0xAF, 0x3B,
+ 0xA2, 0xDB, 0xA3, 0x93, 0x06, 0xB5, 0x3C, 0xA5, 0xD8, 0xEE, 0x8F, 0xAF, 0x25, 0xCC, 0x3F, 0x85,
+ 0x68, 0x48, 0xA9, 0x62, 0xCC, 0x97, 0x8F, 0x7F, 0x2A, 0xEA, 0xE0, 0x15, 0x0A, 0xAD, 0x62, 0x07,
+ 0xBD, 0x45, 0xF8, 0x41, 0xD8, 0x36, 0xCB, 0x4C, 0xDB, 0x6E, 0xE6, 0x3A, 0xE7, 0xDA, 0x15, 0xE9,
+ 0x29, 0x1E, 0x12, 0x10, 0xA0, 0x14, 0x2C, 0x0E, 0x3D, 0xF4, 0xBF, 0x39, 0x41, 0x92, 0x75, 0x0B,
+ 0x25, 0x7B, 0xA3, 0xCE, 0x39, 0x9C, 0x15, 0x64, 0xC8, 0xFA, 0x3D, 0xEF, 0x73, 0x27, 0xFE, 0x26,
+ 0x2E, 0xCE, 0xDA, 0x6E, 0xFD, 0x71, 0x8E, 0xDD, 0xFE, 0x76, 0xEE, 0xDC, 0x12, 0x5C, 0x02, 0xC5,
+ 0x3A, 0x4E, 0x4E, 0x4F, 0xBF, 0xCA, 0x40, 0x15, 0xC7, 0x6E, 0x8D, 0x41, 0xF1, 0x10, 0xE0, 0x4F,
+ 0x7E, 0x97, 0x7F, 0x1C, 0xAE, 0x47, 0x8E, 0x6B, 0xB1, 0x25, 0x31, 0xB0, 0x73, 0xC7, 0x1B, 0x97,
+ 0x79, 0xF9, 0x80, 0xD3, 0x66, 0x22, 0x30, 0x07, 0x74, 0x1E, 0xE4, 0xD0, 0x80, 0x21, 0xD6, 0xEE,
+ 0x6B, 0x6C, 0x4F, 0xBF, 0xF5, 0xB7, 0xD9, 0x09, 0x87, 0x2F, 0xA9, 0x14, 0xBE, 0x27, 0xD9, 0x72,
+ 0x50, 0x01, 0xD4, 0x13, 0x73, 0xA6, 0xA7, 0x51, 0x02, 0x75, 0x25, 0xE1, 0xB3, 0x45, 0x34, 0x7D,
+ 0xA8, 0x8E, 0xEB, 0xF3, 0x16, 0x49, 0xCB, 0x4F, 0x8C, 0xA1, 0xB9, 0x36, 0x85, 0x39, 0x75, 0x5D,
+ 0x08, 0x00, 0xAE, 0xEB, 0xF6, 0xEA, 0xD7, 0x13, 0x3A, 0x21, 0x5A, 0x5F, 0x30, 0x84, 0x52, 0x26,
+ 0x95, 0xC9, 0x14, 0xF2, 0x57, 0x55, 0x6B, 0xB1, 0x10, 0xC2, 0xE1, 0xBD, 0x3B, 0x51, 0xC0, 0xB7,
+ 0x55, 0x4C, 0x71, 0x12, 0x26, 0xC7, 0x0D, 0xF9, 0x51, 0xA4, 0x38, 0x02, 0x05, 0x7F, 0xB8, 0xF1,
+ 0x72, 0x4B, 0xBF, 0x71, 0x89, 0x14, 0xF3, 0x77, 0x38, 0xD9, 0x71, 0x24, 0xF3, 0x00, 0x11, 0xA1,
+ 0xD8, 0xD4, 0x69, 0x27, 0x08, 0x37, 0x35, 0xC9, 0x11, 0x9D, 0x90, 0x1C, 0x0E, 0xE7, 0x1C, 0xFF,
+ 0x2D, 0x1E, 0xE8, 0x92, 0xE1, 0x18, 0x10, 0x95, 0x7C, 0xE0, 0x80, 0xF4, 0x96, 0x43, 0x21, 0xF9,
+ 0x75, 0x21, 0x64, 0x38, 0xDD, 0x9F, 0x1E, 0x95, 0x16, 0xDA, 0x56, 0x1D, 0x4F, 0x9A, 0x53, 0xB2,
+ 0xE2, 0xE4, 0x18, 0xCB, 0x6B, 0x1A, 0x65, 0xEB, 0x56, 0xC6, 0x3B, 0xE5, 0xFE, 0xD8, 0x26, 0x3F,
+ 0x3A, 0x84, 0x59, 0x72, 0x66, 0xA2, 0xF3, 0x75, 0xFF, 0xFB, 0x60, 0xB3, 0x22, 0xAD, 0x3F, 0x2D,
+ 0x6B, 0xF9, 0xEB, 0xEA, 0x05, 0x7C, 0xD8, 0x8F, 0x6D, 0x2C, 0x98, 0x9E, 0x2B, 0x93, 0xF1, 0x5E,
+ 0x46, 0xF0, 0x87, 0x49, 0x29, 0x73, 0x68, 0xD7, 0x7F, 0xF9, 0xF0, 0xE5, 0x7D, 0xDB, 0x1D, 0x75,
+ 0x19, 0xF3, 0xC4, 0x58, 0x9B, 0x17, 0x88, 0xA8, 0x92, 0xE0, 0xBE, 0xBD, 0x8B, 0x1D, 0x8D, 0x9F,
+ 0x56, 0x76, 0xAD, 0xAF, 0x29, 0xE2, 0xD9, 0xD5, 0x52, 0xF6, 0xB5, 0x56, 0x35, 0x57, 0x3A, 0xC8,
+ 0xE1, 0x56, 0x43, 0x19, 0x94, 0xD3, 0x04, 0x9B, 0x6D, 0x35, 0xD8, 0x0B, 0x5F, 0x4D, 0x19, 0x8E,
+ 0xEC, 0xFA, 0x64, 0x91, 0x0A, 0x72, 0x20, 0x2B, 0xBC, 0x1A, 0x4A, 0xFE, 0x8B, 0xFD, 0xBB, 0xED,
+ 0x1B, 0x23, 0xEA, 0xAD, 0x72, 0x82, 0xA1, 0x29, 0x99, 0x71, 0xBD, 0xF0, 0x95, 0xC1, 0x03, 0xDD,
+ 0x7B, 0xC2, 0xB2, 0x3C, 0x28, 0x54, 0xD3, 0x68, 0xA4, 0x72, 0xC8, 0x66, 0x96, 0xE0, 0xD1, 0xD8,
+ 0x7F, 0xF8, 0xD1, 0x26, 0x2B, 0xF7, 0xAD, 0xBA, 0x55, 0xCA, 0x15, 0xB9, 0x32, 0xC3, 0xE5, 0x88,
+ 0x97, 0x8E, 0x5C, 0xFB, 0x92, 0x25, 0x8B, 0xBF, 0xA2, 0x45, 0x55, 0x7A, 0xA7, 0x6F, 0x8B, 0x57,
+ 0x5B, 0xCF, 0x0E, 0xCB, 0x1D, 0xFB, 0x20, 0x82, 0x77, 0xA8, 0x8C, 0xCC, 0x16, 0xCE, 0x1D, 0xFA,
+ 0xDE, 0xCC, 0x0B, 0x62, 0xFE, 0xCC, 0xE1, 0xB7, 0xF0, 0xC3, 0x81, 0x64, 0x73, 0x40, 0xA0, 0xC2,
+ 0x4D, 0x89, 0x11, 0x75, 0x33, 0x55, 0x33, 0x8D, 0xE8, 0x4A, 0xFD, 0xEA, 0x6E, 0x30, 0x0B, 0xD7,
+ 0x31, 0x2C, 0xDE, 0x47, 0xE3, 0xBF, 0xF8, 0x55, 0x42, 0xE2, 0x7F, 0x59, 0xE5, 0x17, 0xEF, 0x99,
+ 0x34, 0x69, 0x91, 0xB1, 0x23, 0x8E, 0x20, 0x87, 0x2D, 0xA8, 0xFE, 0xD5, 0x8A, 0xF3, 0x84, 0x3A,
+ 0xF0, 0x37, 0xE4, 0x09, 0x00, 0x54, 0xEE, 0x67, 0x49, 0x93, 0xE4, 0x81, 0x70, 0xE3, 0x90, 0x4D,
+ 0xEF, 0xFE, 0x41, 0xB7, 0x99, 0x7B, 0xC1, 0x83, 0xBA, 0x62, 0x12, 0x6F, 0x7D, 0xDE, 0x6B, 0xAF,
+ 0xDA, 0x16, 0xF9, 0x55, 0x51, 0xEE, 0xA6, 0x0C, 0x2B, 0x02, 0xA3, 0xFD, 0x8D, 0xFB, 0x30, 0x17,
+ 0xE4, 0x6F, 0xDF, 0x36, 0x71, 0xC4, 0xCA, 0x87, 0x25, 0x48, 0xB0, 0x47, 0xEC, 0xEA, 0xB4, 0xBF,
+ 0xA5, 0x4D, 0x9B, 0x9F, 0x02, 0x93, 0xC4, 0xE3, 0xE4, 0xE8, 0x42, 0x2D, 0x68, 0x81, 0x15, 0x0A,
+ 0xEB, 0x84, 0x5B, 0xD6, 0xA8, 0x74, 0xFB, 0x7D, 0x1D, 0xCB, 0x2C, 0xDA, 0x46, 0x2A, 0x76, 0x62,
+ 0xCE, 0xBC, 0x5C, 0x9E, 0x8B, 0xE7, 0xCF, 0xBE, 0x78, 0xF5, 0x7C, 0xEB, 0xB3, 0x3A, 0x9C, 0xAA,
+ 0x6F, 0xCC, 0x72, 0xD1, 0x59, 0xF2, 0x11, 0x23, 0xD6, 0x3F, 0x48, 0xD1, 0xB7, 0xCE, 0xB0, 0xBF,
+ 0xCB, 0xEA, 0x80, 0xDE, 0x57, 0xD4, 0x5E, 0x97, 0x2F, 0x75, 0xD1, 0x50, 0x8E, 0x80, 0x2C, 0x66,
+ 0x79, 0xBF, 0x72, 0x4B, 0xBD, 0x8A, 0x81, 0x6C, 0xD3, 0xE1, 0x01, 0xDC, 0xD2, 0x15, 0x26, 0xC5,
+ 0x36, 0xDA, 0x2C, 0x1A, 0xC0, 0x27, 0x94, 0xED, 0xB7, 0x9B, 0x85, 0x0B, 0x5E, 0x80, 0x97, 0xC5,
+ 0xEC, 0x4F, 0xEC, 0x88, 0x5D, 0x50, 0x07, 0x35, 0x47, 0xDC, 0x0B, 0x3B, 0x3D, 0xDD, 0x60, 0xAF,
+ 0xA8, 0x5D, 0x81, 0x38, 0x24, 0x25, 0x5D, 0x5C, 0x15, 0xD1, 0xDE, 0xB3, 0xAB, 0xEC, 0x05, 0x69,
+ 0xEF, 0x83, 0xED, 0x57, 0x54, 0xB8, 0x64, 0x64, 0x11, 0x16, 0x32, 0x69, 0xDA, 0x9F, 0x2D, 0x7F,
+ 0x36, 0xBB, 0x44, 0x5A, 0x34, 0xE8, 0x7F, 0xBF, 0x03, 0xEB, 0x00, 0x7F, 0x59, 0x68, 0x22, 0x79,
+ 0xCF, 0x73, 0x6C, 0x2C, 0x29, 0xA7, 0xA1, 0x5F, 0x38, 0xA1, 0x1D, 0xF0, 0x20, 0x53, 0xE0, 0x1A,
+ 0x63, 0x14, 0x58, 0x71, 0x10, 0xAA, 0x08, 0x0C, 0x3E, 0x16, 0x1A, 0x60, 0x22, 0x82, 0x7F, 0xBA,
+ 0xA4, 0x43, 0xA0, 0xD0, 0xAC, 0x1B, 0xD5, 0x6B, 0x64, 0xB5, 0x14, 0x93, 0x31, 0x9E, 0x53, 0x50,
+ 0xD0, 0x57, 0x66, 0xEE, 0x5A, 0x4F, 0xFB, 0x03, 0x2A, 0x69, 0x58, 0x76, 0xF1, 0x83, 0xF7, 0x4E,
+ 0xBA, 0x8C, 0x42, 0x06, 0x60, 0x5D, 0x6D, 0xCE, 0x60, 0x88, 0xAE, 0xA4, 0xC3, 0xF1, 0x03, 0xA5,
+ 0x4B, 0x98, 0xA1, 0xFF, 0x67, 0xE1, 0xAC, 0xA2, 0xB8, 0x62, 0xD7, 0x6F, 0xA0, 0x31, 0xB4, 0xD2,
+ 0x77, 0xAF, 0x21, 0x10, 0x06, 0xC6, 0x9A, 0xFF, 0x1D, 0x09, 0x17, 0x0E, 0x5F, 0xF1, 0xAA, 0x54,
+ 0x34, 0x4B, 0x45, 0x8A, 0x87, 0x63, 0xA6, 0xDC, 0xF9, 0x24, 0x30, 0x67, 0xC6, 0xB2, 0xD6, 0x61,
+ 0x33, 0x69, 0xEE, 0x50, 0x61, 0x57, 0x28, 0xE7, 0x7E, 0xEE, 0xEC, 0x3A, 0x5A, 0x73, 0x4E, 0xA8,
+ 0x8D, 0xE4, 0x18, 0xEA, 0xEC, 0x41, 0x64, 0xC8, 0xE2, 0xE8, 0x66, 0xB6, 0x2D, 0xB6, 0xFB, 0x6A,
+ 0x6C, 0x16, 0xB3, 0xDD, 0x46, 0x43, 0xB9, 0x73, 0x00, 0x6A, 0x71, 0xED, 0x4E, 0x9D, 0x25, 0x1A,
+ 0xC3, 0x3C, 0x4A, 0x95, 0x15, 0x99, 0x35, 0x81, 0x14, 0x02, 0xD6, 0x98, 0x9B, 0xEC, 0xD8, 0x23,
+ 0x3B, 0x84, 0x29, 0xAF, 0x0C, 0x99, 0x83, 0xA6, 0x9A, 0x34, 0x4F, 0xFA, 0xE8, 0xD0, 0x3C, 0x4B,
+ 0xD0, 0xFB, 0xB6, 0x68, 0xB8, 0x9E, 0x8F, 0xCD, 0xF7, 0x60, 0x2D, 0x7A, 0x22, 0xE5, 0x7D, 0xAB,
+ 0x65, 0x1B, 0x95, 0xA7, 0xA8, 0x7F, 0xB6, 0x77, 0x47, 0x7B, 0x5F, 0x8B, 0x12, 0x72, 0xD0, 0xD4,
+ 0x91, 0xEF, 0xDE, 0x19, 0x50, 0x3C, 0xA7, 0x8B, 0xC4, 0xA9, 0xB3, 0x23, 0xCB, 0x76, 0xE6, 0x81,
+ 0xF0, 0xC1, 0x04, 0x8F, 0xA3, 0xB8, 0x54, 0x5B, 0x97, 0xAC, 0x19, 0xFF, 0x3F, 0x55, 0x27, 0x2F,
+ 0xE0, 0x1D, 0x42, 0x9B, 0x57, 0xFC, 0x4B, 0x4E, 0x0F, 0xCE, 0x98, 0xA9, 0x43, 0x57, 0x03, 0xBD,
+ 0xE7, 0xC8, 0x94, 0xDF, 0x6E, 0x36, 0x73, 0x32, 0xB4, 0xEF, 0x2E, 0x85, 0x7A, 0x6E, 0xFC, 0x6C,
+ 0x18, 0x82, 0x75, 0x35, 0x90, 0x07, 0xF3, 0xE4, 0x9F, 0x3E, 0xDC, 0x68, 0xF3, 0xB5, 0xF3, 0x19,
+ 0x80, 0x92, 0x06, 0x99, 0xA2, 0xE8, 0x6F, 0xFF, 0x2E, 0x7F, 0xAE, 0x42, 0xA4, 0x5F, 0xFB, 0xD4,
+ 0x0E, 0x81, 0x2B, 0xC3, 0x04, 0xFF, 0x2B, 0xB3, 0x74, 0x4E, 0x36, 0x5B, 0x9C, 0x15, 0x00, 0xC6,
+ 0x47, 0x2B, 0xE8, 0x8B, 0x3D, 0xF1, 0x9C, 0x03, 0x9A, 0x58, 0x7F, 0x9B, 0x9C, 0xBF, 0x85, 0x49,
+ 0x79, 0x35, 0x2E, 0x56, 0x7B, 0x41, 0x14, 0x39, 0x47, 0x83, 0x26, 0xAA, 0x07, 0x89, 0x98, 0x11,
+ 0x1B, 0x86, 0xE7, 0x73, 0x7A, 0xD8, 0x7D, 0x78, 0x61, 0x53, 0xE9, 0x79, 0xF5, 0x36, 0x8D, 0x44,
+ 0x92, 0x84, 0xF9, 0x13, 0x50, 0x58, 0x3B, 0xA4, 0x6A, 0x36, 0x65, 0x49, 0x8E, 0x3C, 0x0E, 0xF1,
+ 0x6F, 0xD2, 0x84, 0xC4, 0x7E, 0x8E, 0x3F, 0x39, 0xAE, 0x7C, 0x84, 0xF1, 0x63, 0x37, 0x8E, 0x3C,
+ 0xCC, 0x3E, 0x44, 0x81, 0x45, 0xF1, 0x4B, 0xB9, 0xED, 0x6B, 0x36, 0x5D, 0xBB, 0x20, 0x60, 0x1A,
+ 0x0F, 0xA3, 0xAA, 0x55, 0x77, 0x3A, 0xA9, 0xAE, 0x37, 0x4D, 0xBA, 0xB8, 0x86, 0x6B, 0xBC, 0x08,
+ 0x50, 0xF6, 0xCC, 0xA4, 0xBD, 0x1D, 0x40, 0x72, 0xA5, 0x86, 0xFA, 0xE2, 0x10, 0xAE, 0x3D, 0x58,
+ 0x4B, 0x97, 0xF3, 0x43, 0x74, 0xA9, 0x9E, 0xEB, 0x21, 0xB7, 0x01, 0xA4, 0x86, 0x93, 0x97, 0xEE,
+ 0x2F, 0x4F, 0x3B, 0x86, 0xA1, 0x41, 0x6F, 0x41, 0x26, 0x90, 0x78, 0x5C, 0x7F, 0x30, 0x38, 0x4B,
+ 0x3F, 0xAA, 0xEC, 0xED, 0x5C, 0x6F, 0x0E, 0xAD, 0x43, 0x87, 0xFD, 0x93, 0x35, 0xE6, 0x01, 0xEF,
+ 0x41, 0x26, 0x90, 0x99, 0x9E, 0xFB, 0x19, 0x5B, 0xAD, 0xD2, 0x91, 0x8A, 0xE0, 0x46, 0xAF, 0x65,
+ 0xFA, 0x4F, 0x84, 0xC1, 0xA1, 0x2D, 0xCF, 0x45, 0x8B, 0xD3, 0x85, 0x50, 0x55, 0x7C, 0xF9, 0x67,
+ 0x88, 0xD4, 0x4E, 0xE9, 0xD7, 0x6B, 0x61, 0x54, 0xA1, 0xA4, 0xA6, 0xA2, 0xC2, 0xBF, 0x30, 0x9C,
+ 0x40, 0x9F, 0x5F, 0xD7, 0x69, 0x2B, 0x24, 0x82, 0x5E, 0xD9, 0xD6, 0xA7, 0x12, 0x54, 0x1A, 0xF7,
+ 0x55, 0x9F, 0x76, 0x50, 0xA9, 0x95, 0x84, 0xE6, 0x6B, 0x6D, 0xB5, 0x96, 0x54, 0xD6, 0xCD, 0xB3,
+ 0xA1, 0x9B, 0x46, 0xA7, 0x94, 0x4D, 0xC4, 0x94, 0xB4, 0x98, 0xE3, 0xE1, 0xE2, 0x34, 0xD5, 0x33,
+ 0x16, 0x07, 0x54, 0xCD, 0xB7, 0x77, 0x53, 0xDB, 0x4F, 0x4D, 0x46, 0x9D, 0xE9, 0xD4, 0x9C, 0x8A,
+ 0x36, 0xB6, 0xB8, 0x38, 0x26, 0x6C, 0x0E, 0xFF, 0x9C, 0x1B, 0x43, 0x8B, 0x80, 0xCC, 0xB9, 0x3D,
+ 0xDA, 0xC7, 0xF1, 0x8A, 0xF2, 0x6D, 0xB8, 0xD7, 0x74, 0x2F, 0x7E, 0x1E, 0xB7, 0xD3, 0x4A, 0xB4,
+ 0xAC, 0xFC, 0x79, 0x48, 0x6C, 0xBC, 0x96, 0xB6, 0x94, 0x46, 0x57, 0x2D, 0xB0, 0xA3, 0xFC, 0x1E,
+ 0xB9, 0x52, 0x60, 0x85, 0x2D, 0x41, 0xD0, 0x43, 0x01, 0x1E, 0x1C, 0xD5, 0x7D, 0xFC, 0xF3, 0x96,
+ 0x0D, 0xC7, 0xCB, 0x2A, 0x29, 0x9A, 0x93, 0xDD, 0x88, 0x2D, 0x37, 0x5D, 0xAA, 0xFB, 0x49, 0x68,
+ 0xA0, 0x9C, 0x50, 0x86, 0x7F, 0x68, 0x56, 0x57, 0xF9, 0x79, 0x18, 0x39, 0xD4, 0xE0, 0x01, 0x84,
+ 0x33, 0x61, 0xCA, 0xA5, 0xD2, 0xD6, 0xE4, 0xC9, 0x8A, 0x4A, 0x23, 0x44, 0x4E, 0xBC, 0xF0, 0xDC,
+ 0x24, 0xA1, 0xA0, 0xC4, 0xE2, 0x07, 0x3C, 0x10, 0xC4, 0xB5, 0x25, 0x4B, 0x65, 0x63, 0xF4, 0x80,
+ 0xE7, 0xCF, 0x61, 0xB1, 0x71, 0x82, 0x21, 0x87, 0x2C, 0xF5, 0x91, 0x00, 0x32, 0x0C, 0xEC, 0xA9,
+ 0xB5, 0x9A, 0x74, 0x85, 0xE3, 0x36, 0x8F, 0x76, 0x4F, 0x9C, 0x6D, 0xCE, 0xBC, 0xAD, 0x0A, 0x4B,
+ 0xED, 0x76, 0x04, 0xCB, 0xC3, 0xB9, 0x33, 0x9E, 0x01, 0x93, 0x96, 0x69, 0x7D, 0xC5, 0xA2, 0x45,
+ 0x79, 0x9B, 0x04, 0x5C, 0x84, 0x09, 0xED, 0x88, 0x43, 0xC7, 0xAB, 0x93, 0x14, 0x26, 0xA1, 0x40,
+ 0xB5, 0xCE, 0x4E, 0xBF, 0x2A, 0x42, 0x85, 0x3E, 0x2C, 0x3B, 0x54, 0xE8, 0x12, 0x1F, 0x0E, 0x97,
+ 0x59, 0xB2, 0x27, 0x89, 0xFA, 0xF2, 0xDF, 0x8E, 0x68, 0x59, 0xDC, 0x06, 0xBC, 0xB6, 0x85, 0x0D,
+ 0x06, 0x22, 0xEC, 0xB1, 0xCB, 0xE5, 0x04, 0xE6, 0x3D, 0xB3, 0xB0, 0x41, 0x73, 0x08, 0x3F, 0x3C,
+ 0x58, 0x86, 0x63, 0xEB, 0x50, 0xEE, 0x1D, 0x2C, 0x37, 0x74, 0xA9, 0xD3, 0x18, 0xA3, 0x47, 0x6E,
+ 0x93, 0x54, 0xAD, 0x0A, 0x5D, 0xB8, 0x2A, 0x55, 0x5D, 0x78, 0xF6, 0xEE, 0xBE, 0x8E, 0x3C, 0x76,
+ 0x69, 0xB9, 0x40, 0xC2, 0x34, 0xEC, 0x2A, 0xB9, 0xED, 0x7E, 0x20, 0xE4, 0x8D, 0x00, 0x38, 0xC7,
+ 0xE6, 0x8F, 0x44, 0xA8, 0x86, 0xCE, 0xEB, 0x2A, 0xE9, 0x90, 0xF1, 0x4C, 0xDF, 0x32, 0xFB, 0x73,
+ 0x1B, 0x6D, 0x92, 0x1E, 0x95, 0xFE, 0xB4, 0xDB, 0x65, 0xDF, 0x4D, 0x23, 0x54, 0x89, 0x48, 0xBF,
+ 0x4A, 0x2E, 0x70, 0xD6, 0xD7, 0x62, 0xB4, 0x33, 0x29, 0xB1, 0x3A, 0x33, 0x4C, 0x23, 0x6D, 0xA6,
+ 0x76, 0xA5, 0x21, 0x63, 0x48, 0xE6, 0x90, 0x5D, 0xED, 0x90, 0x95, 0x0B, 0x7A, 0x84, 0xBE, 0xB8,
+ 0x0D, 0x5E, 0x63, 0x0C, 0x62, 0x26, 0x4C, 0x14, 0x5A, 0xB3, 0xAC, 0x23, 0xA4, 0x74, 0xA7, 0x6F,
+ 0x33, 0x30, 0x05, 0x60, 0x01, 0x42, 0xA0, 0x28, 0xB7, 0xEE, 0x19, 0x38, 0xF1, 0x64, 0x80, 0x82,
+ 0x43, 0xE1, 0x41, 0x27, 0x1F, 0x1F, 0x90, 0x54, 0x7A, 0xD5, 0x23, 0x2E, 0xD1, 0x3D, 0xCB, 0x28,
+ 0xBA, 0x58, 0x7F, 0xDC, 0x7C, 0x91, 0x24, 0xE9, 0x28, 0x51, 0x83, 0x6E, 0xC5, 0x56, 0x21, 0x42,
+ 0xED, 0xA0, 0x56, 0x22, 0xA1, 0x40, 0x80, 0x6B, 0xA8, 0xF7, 0x94, 0xCA, 0x13, 0x6B, 0x0C, 0x39,
+ 0xD9, 0xFD, 0xE9, 0xF3, 0x6F, 0xA6, 0x9E, 0xFC, 0x70, 0x8A, 0xB3, 0xBC, 0x59, 0x3C, 0x1E, 0x1D,
+ 0x6C, 0xF9, 0x7C, 0xAF, 0xF9, 0x88, 0x71, 0x95, 0xEB, 0x57, 0x00, 0xBD, 0x9F, 0x8C, 0x4F, 0xE1,
+ 0x24, 0x83, 0xC5, 0x22, 0xEA, 0xFD, 0xD3, 0x0C, 0xE2, 0x17, 0x18, 0x7C, 0x6A, 0x4C, 0xDE, 0x77,
+ 0xB4, 0x53, 0x9B, 0x4C, 0x81, 0xCD, 0x23, 0x60, 0xAA, 0x0E, 0x25, 0x73, 0x9C, 0x02, 0x79, 0x32,
+ 0x30, 0xDF, 0x74, 0xDF, 0x75, 0x19, 0xF4, 0xA5, 0x14, 0x5C, 0xF7, 0x7A, 0xA8, 0xA5, 0x91, 0x84,
+ 0x7C, 0x60, 0x03, 0x06, 0x3B, 0xCD, 0x50, 0xB6, 0x27, 0x9C, 0xFE, 0xB1, 0xDD, 0xCC, 0xD3, 0xB0,
+ 0x59, 0x24, 0xB2, 0xCA, 0xE2, 0x1C, 0x81, 0x22, 0x9D, 0x07, 0x8F, 0x8E, 0xB9, 0xBE, 0x4E, 0xFA,
+ 0xFC, 0x39, 0x65, 0xBA, 0xBF, 0x9D, 0x12, 0x37, 0x5E, 0x97, 0x7E, 0xF3, 0x89, 0xF5, 0x5D, 0xF5,
+ 0xE3, 0x09, 0x8C, 0x62, 0xB5, 0x20, 0x9D, 0x0C, 0x53, 0x8A, 0x68, 0x1B, 0xD2, 0x8F, 0x75, 0x17,
+ 0x5D, 0xD4, 0xE5, 0xDA, 0x75, 0x62, 0x19, 0x14, 0x6A, 0x26, 0x2D, 0xEB, 0xF8, 0xAF, 0x37, 0xF0,
+ 0x6C, 0xA4, 0x55, 0xB1, 0xBC, 0xE2, 0x33, 0xC0, 0x9A, 0xCA, 0xB0, 0x11, 0x49, 0x4F, 0x68, 0x9B,
+ 0x3B, 0x6B, 0x3C, 0xCC, 0x13, 0xF6, 0xC7, 0x85, 0x61, 0x68, 0x42, 0xAE, 0xBB, 0xDD, 0xCD, 0x45,
+ 0x16, 0x29, 0x1D, 0xEA, 0xDB, 0xC8, 0x03, 0x94, 0x3C, 0xEE, 0x4F, 0x82, 0x11, 0xC3, 0xEC, 0x28,
+ 0xBD, 0x97, 0x05, 0x99, 0xDE, 0xD7, 0xBB, 0x5E, 0x22, 0x1F, 0xD4, 0xEB, 0x64, 0xD9, 0x92, 0xD9,
+ 0x85, 0xB7, 0x6A, 0x05, 0x6A, 0xE4, 0x24, 0x41, 0xF1, 0xCD, 0xF0, 0xD8, 0x3F, 0xF8, 0x9E, 0x0E,
+ 0xCD, 0x0B, 0x7A, 0x70, 0x6B, 0x5A, 0x75, 0x0A, 0x6A, 0x33, 0x88, 0xEC, 0x17, 0x75, 0x08, 0x70,
+ 0x10, 0x2F, 0x24, 0xCF, 0xC4, 0xE9, 0x42, 0x00, 0x61, 0x94, 0xCA, 0x1F, 0x3A, 0x76, 0x06, 0xFA,
+ 0xD2, 0x48, 0x81, 0xF0, 0x77, 0x60, 0x03, 0x45, 0xD9, 0x61, 0xF4, 0xA4, 0x6F, 0x3D, 0xD9, 0x30,
+ 0xC3, 0x04, 0x6B, 0x54, 0x2A, 0xB7, 0xEC, 0x3B, 0xF4, 0x4B, 0xF5, 0x68, 0x52, 0x26, 0xCE, 0xFF,
+ 0x5D, 0x19, 0x91, 0xA0, 0xA3, 0xA5, 0xA9, 0xB1, 0xE0, 0x23, 0xC4, 0x0A, 0x77, 0x4D, 0xF9, 0x51,
+ 0x20, 0xA3, 0xA5, 0xA9, 0xB1, 0xC1, 0x00, 0x82, 0x86, 0x8E, 0x7F, 0x5D, 0x19, 0x91, 0xA0, 0xA3,
+ 0xC4, 0xEB, 0x54, 0x0B, 0x75, 0x68, 0x52, 0x07, 0x8C, 0x9A, 0x97, 0x8D, 0x79, 0x70, 0x62, 0x46,
+ 0xEF, 0x5C, 0x1B, 0x95, 0x89, 0x71, 0x41, 0xE1, 0x21, 0xA1, 0xA1, 0xA1, 0xC0, 0x02, 0x67, 0x4C,
+ 0x1A, 0xB6, 0xCF, 0xFD, 0x78, 0x53, 0x24, 0xAB, 0xB5, 0xC9, 0xF1, 0x60, 0x23, 0xA5, 0xC8, 0x12,
+ 0x87, 0x6D, 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x6D, 0x58, 0x32, 0xC7, 0x0C, 0x9A, 0x97, 0xAC,
+ 0xDA, 0x36, 0xEE, 0x5E, 0x3E, 0xDF, 0x1D, 0xB8, 0xF2, 0x66, 0x2F, 0xBD, 0xF8, 0x72, 0x47, 0xED,
+ 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x8C, 0x7B, 0x55, 0x09, 0x90, 0xA2, 0xC6, 0xEF, 0x3D, 0xF8,
+ 0x53, 0x24, 0xAB, 0xD4, 0x2A, 0xB7, 0xEC, 0x5A, 0x36, 0xEE, 0x5E, 0x3E, 0xDF, 0x3C, 0xFA, 0x76,
+ 0x4F, 0xFD, 0x59, 0x30, 0xE2, 0x46, 0xEF, 0x3D, 0xF8, 0x53, 0x05, 0x69, 0x31, 0xC1, 0x00, 0x82,
+ 0x86, 0x8E, 0x7F, 0x5D, 0x19, 0xB0, 0xE2, 0x27, 0xCC, 0xFB, 0x74, 0x4B, 0x14, 0x8B, 0x94, 0x8B,
+ 0x75, 0x68, 0x33, 0xC5, 0x08, 0x92, 0x87, 0x8C, 0x9A, 0xB6, 0xCF, 0x1C, 0xBA, 0xD7, 0x0D, 0x98,
+ 0xB2, 0xE6, 0x2F, 0xDC, 0x1B, 0x95, 0x89, 0x71, 0x60, 0x23, 0xC4, 0x0A, 0x96, 0x8F, 0x9C, 0xBA,
+ 0xF6, 0x6E, 0x3F, 0xFC, 0x5B, 0x15, 0xA8, 0xD2, 0x26, 0xAF, 0xBD, 0xF8, 0x72, 0x66, 0x2F, 0xDC,
+ 0x1B, 0xB4, 0xCB, 0x14, 0x8B, 0x94, 0xAA, 0xB7, 0xCD, 0xF9, 0x51, 0x01, 0x80, 0x82, 0x86, 0x6F,
+ 0x3D, 0xD9, 0x30, 0xE2, 0x27, 0xCC, 0xFB, 0x74, 0x4B, 0x14, 0xAA, 0xB7, 0xCD, 0xF9, 0x70, 0x43,
+ 0x04, 0x6B, 0x35, 0xC9, 0xF1, 0x60, 0x23, 0xA5, 0xC8, 0xF3, 0x45, 0x08, 0x92, 0x87, 0x6D, 0x58,
+ 0x32, 0xE6, 0x2F, 0xBD, 0xF8, 0x72, 0x66, 0x4E, 0x1E, 0xBE, 0xFE, 0x7E, 0x7E, 0x7E, 0x5F, 0x1D,
+ 0x99, 0x91, 0xA0, 0xA3, 0xC4, 0x0A, 0x77, 0x4D, 0x18, 0x93, 0xA4, 0xAB, 0xD4, 0x0B, 0x75, 0x49,
+ 0x10, 0xA2, 0xC6, 0xEF, 0x3D, 0xF8, 0x53, 0x24, 0xAB, 0xB5, 0xE8, 0x33, 0xE4, 0x4A, 0x16, 0xAE,
+ 0xDE, 0x1F, 0xBC, 0xDB, 0x15, 0xA8, 0xB3, 0xC5, 0x08, 0x73, 0x45, 0xE9, 0x31, 0xC1, 0xE1, 0x21,
+ 0xA1, 0xA1, 0xA1, 0xC0, 0x02, 0x86, 0x6F, 0x5C, 0x3A, 0xD7, 0x0D, 0x98, 0x93, 0xA4, 0xCA, 0x16,
+ 0xAE, 0xDE, 0x1F, 0x9D, 0x99, 0xB0, 0xE2, 0x46, 0xEF, 0x3D, 0xF8, 0x72, 0x47, 0x0C, 0x9A, 0xB6,
+ 0xCF, 0xFD, 0x59, 0x11, 0xA0, 0xA3, 0xA5, 0xC8, 0xF3, 0x45, 0x08, 0x92, 0x87, 0x6D, 0x39, 0xF0,
+ 0x43, 0x04, 0x8A, 0x96, 0xAE, 0xDE, 0x3E, 0xDF, 0x1D, 0x99, 0x91, 0xA0, 0xC2, 0x06, 0x6F, 0x3D,
+ 0xF8, 0x72, 0x47, 0x0C, 0x9A, 0x97, 0x8D, 0x98, 0x93, 0x85, 0x88, 0x73, 0x45, 0xE9, 0x31, 0xE0,
+ 0x23, 0xA5, 0xA9, 0xD0, 0x03, 0x84, 0x8A, 0x96, 0xAE, 0xDE, 0x1F, 0xBC, 0xDB, 0x15, 0xA8, 0xD2,
+ 0x26, 0xCE, 0xFF, 0x5D, 0x19, 0x91, 0x81, 0x80, 0x82, 0x67, 0x2D, 0xD8, 0x13, 0xA4, 0xAB, 0xD4,
+ 0x0B, 0x94, 0xAA, 0xB7, 0xCD, 0xF9, 0x51, 0x20, 0xA3, 0xA5, 0xC8, 0xF3, 0x45, 0xE9, 0x50, 0x22,
+ 0xC6, 0xEF, 0x5C, 0x3A, 0xD7, 0x0D, 0x98, 0x93, 0x85, 0x88, 0x73, 0x64, 0x4A, 0xF7, 0x4D, 0xF9,
+ 0x51, 0x20, 0xA3, 0xC4, 0x0A, 0x96, 0xAE, 0xDE, 0x3E, 0xFE, 0x7E, 0x7E, 0x7E, 0x5F, 0x3C, 0xFA,
+ 0x76, 0x4F, 0xFD, 0x78, 0x72, 0x66, 0x2F, 0xBD, 0xD9, 0x30, 0xC3, 0xE5, 0x48, 0x12, 0x87, 0x8C,
+ 0x7B, 0x55, 0x28, 0xD2, 0x07, 0x8C, 0x9A, 0x97, 0xAC, 0xDA, 0x17, 0x8D, 0x79, 0x51, 0x20, 0xA3,
+ 0xC4, 0xEB, 0x54, 0x0B, 0x94, 0x8B, 0x94, 0xAA, 0xD6, 0x2E, 0xBF, 0xFC, 0x5B, 0x15, 0xA8, 0xD2,
+ 0x26, 0xAF, 0xDC, 0x1B, 0xB4, 0xEA, 0x37, 0xEC, 0x3B, 0xF4, 0x6A, 0x37, 0xCD, 0x18, 0x93, 0x85,
+ 0x69, 0x31, 0xC1, 0xE1, 0x40, 0xE3, 0x25, 0xC8, 0x12, 0x87, 0x8C, 0x9A, 0xB6, 0xCF, 0xFD, 0x59,
+ 0x11, 0xA0, 0xC2, 0x06, 0x8E, 0x7F, 0x5D, 0x38, 0xF2, 0x47, 0x0C, 0x7B, 0x74, 0x6A, 0x37, 0xEC,
+ 0x5A, 0x36, 0xEE, 0x3F, 0xFC, 0x7A, 0x76, 0x4F, 0x1C, 0x9B, 0x95, 0x89, 0x71, 0x41, 0x00, 0x63,
+ 0x44, 0xEB, 0x54, 0x2A, 0xD6, 0x0F, 0x9C, 0xBA, 0xD7, 0x0D, 0x98, 0x93, 0x85, 0x69, 0x31, 0xC1,
+ 0x00, 0x82, 0x86, 0x8E, 0x9E, 0xBE, 0xDF, 0x3C, 0xFA, 0x57, 0x2C, 0xDA, 0x36, 0xEE, 0x3F, 0xFC,
+ 0x5B, 0x15, 0x89, 0x71, 0x41, 0x00, 0x82, 0x86, 0x8E, 0x7F, 0x5D, 0x38, 0xF2, 0x47, 0xED, 0x58,
+ 0x13, 0xA4, 0xCA, 0xF7, 0x4D, 0xF9, 0x51, 0x01, 0x80, 0x63, 0x44, 0xEB, 0x54, 0x2A, 0xD6, 0x2E,
+ 0xBF, 0xDD, 0x19, 0x91, 0xA0, 0xA3, 0xA5, 0xA9, 0xB1, 0xE0, 0x42, 0x06, 0x8E, 0x7F, 0x5D, 0x19,
+ 0x91, 0xA0, 0xA3, 0xC4, 0x0A, 0x96, 0x8F, 0x7D, 0x78, 0x72, 0x47, 0x0C, 0x7B, 0x74, 0x6A, 0x56,
+ 0x2E, 0xDE, 0x1F, 0xBC, 0xFA, 0x57, 0x0D, 0x79, 0x51, 0x01, 0x61, 0x21, 0xA1, 0xC0, 0xE3, 0x25,
+ 0xA9, 0xB1, 0xC1, 0xE1, 0x40, 0x02, 0x67, 0x4C, 0x1A, 0x97, 0x8D, 0x98, 0x93, 0xA4, 0xAB, 0xD4,
+ 0x2A, 0xD6, 0x0F, 0x9C, 0x9B, 0xB4, 0xCB, 0x14, 0xAA, 0xB7, 0xCD, 0xF9, 0x51, 0x20, 0xA3, 0xC4,
+ 0xEB, 0x35, 0xC9, 0xF1, 0x60, 0x42, 0x06, 0x8E, 0x7F, 0x7C, 0x7A, 0x76, 0x6E, 0x3F, 0xFC, 0x7A,
+ 0x76, 0x6E, 0x5E, 0x3E, 0xFE, 0x7E, 0x5F, 0x3C, 0xDB, 0x15, 0x89, 0x71, 0x41, 0xE1, 0x21, 0xC0,
+ 0xE3, 0x44, 0xEB, 0x54, 0x2A, 0xB7, 0xCD, 0xF9, 0x70, 0x62, 0x27, 0xAD, 0xD8, 0x32, 0xC7, 0x0C,
+ 0x7B, 0x74, 0x4B, 0x14, 0xAA, 0xB7, 0xEC, 0x3B, 0xD5, 0x28, 0xD2, 0x07, 0x6D, 0x39, 0xD1, 0x20,
+ 0xC2, 0xE7, 0x4C, 0x1A, 0x97, 0x8D, 0x98, 0xB2, 0xC7, 0x0C, 0x59, 0x28, 0xF3, 0x9B
+};
+
+const pmw3360_srom_t pmw3360_srom_0x04 = {
+ .data = srom_data_0x04,
+ .len = sizeof(srom_data_0x04),
+};
diff --git a/keyboards/yowkees/drivers/pmw3360/srom_0x81.c b/keyboards/yowkees/drivers/pmw3360/srom_0x81.c
new file mode 100644
index 00000000000..1a3016fbe83
--- /dev/null
+++ b/keyboards/yowkees/drivers/pmw3360/srom_0x81.c
@@ -0,0 +1,263 @@
+static const uint8_t srom_data_0x81[] PROGMEM = {
+ 0x01, 0x81, 0x01, 0x82, 0x46, 0x27, 0x9E, 0xBE, 0xFE, 0x5F, 0x3C, 0xFA, 0x76, 0x6E, 0x5E, 0x3E,
+ 0xFE, 0x5F, 0x1D, 0x99, 0x91, 0xA0, 0xC2, 0x06, 0x8E, 0x9E, 0x9F, 0xBC, 0xDB, 0x34, 0xEA, 0x56,
+ 0x0F, 0x9C, 0x9B, 0xB4, 0xCB, 0x14, 0x8B, 0x75, 0x68, 0x33, 0xC5, 0x08, 0x73, 0x45, 0xE9, 0x50,
+ 0x22, 0xA7, 0xCC, 0xFB, 0x55, 0x28, 0xB3, 0xC5, 0x08, 0x92, 0xA6, 0xAF, 0xDC, 0x3A, 0xF6, 0x4F,
+ 0x1C, 0x9B, 0xB4, 0xCB, 0x14, 0x8B, 0x94, 0xAF, 0xD6, 0x2E, 0xDE, 0x1F, 0x9D, 0xB8, 0xF2, 0x66,
+ 0x4F, 0xFF, 0x7C, 0x7A, 0x76, 0x6E, 0x5E, 0x3E, 0xDF, 0x1D, 0x99, 0xB0, 0xE2, 0x46, 0x0D, 0x9E,
+ 0x9B, 0xBC, 0xFA, 0x76, 0x6E, 0x5E, 0x1F, 0x9D, 0x99, 0xB6, 0xE2, 0x25, 0xCC, 0x1A, 0x97, 0xAC,
+ 0xBB, 0xF4, 0x6A, 0x37, 0xCD, 0xF9, 0x70, 0xAA, 0xA2, 0x04, 0x6F, 0x9D, 0x8C, 0x1A, 0xBC, 0x44,
+ 0x06, 0xAD, 0xE7, 0x73, 0x58, 0x33, 0x3A, 0x89, 0xAC, 0xAB, 0xE6, 0xF2, 0x59, 0x9C, 0xE4, 0x7F,
+ 0xE2, 0x94, 0x9F, 0x6E, 0x56, 0x0B, 0x78, 0x79, 0xA8, 0x5E, 0xB5, 0x06, 0x63, 0x63, 0x6E, 0xB9,
+ 0xF4, 0xF5, 0x64, 0x6D, 0x16, 0x4E, 0x35, 0xE2, 0x0C, 0x55, 0xE6, 0x20, 0xD5, 0xC6, 0xAB, 0x41,
+ 0xD1, 0x51, 0xE6, 0xF6, 0x4B, 0x4C, 0xF5, 0x7D, 0x01, 0x56, 0x36, 0xCB, 0xAD, 0x16, 0x3E, 0x8D,
+ 0x20, 0x44, 0x0E, 0x27, 0x02, 0x57, 0x5D, 0x75, 0xA7, 0xE9, 0x69, 0x55, 0x8A, 0xD8, 0x10, 0x35,
+ 0x07, 0x8F, 0x07, 0xCA, 0x7C, 0x7A, 0x73, 0xC5, 0x8B, 0xE0, 0x35, 0xE7, 0xD1, 0x41, 0x5E, 0xD5,
+ 0x5E, 0x5F, 0x09, 0xC7, 0x0A, 0x06, 0x6A, 0xFE, 0xEA, 0xDF, 0xB2, 0x4E, 0xBB, 0xBD, 0xFE, 0x82,
+ 0x7E, 0xF6, 0x46, 0x32, 0x3E, 0xE0, 0xAC, 0xB6, 0x09, 0x89, 0x94, 0xD3, 0xE8, 0xFD, 0xF2, 0x4E,
+ 0x3D, 0x9E, 0xC1, 0xBD, 0x86, 0x95, 0x11, 0xD7, 0x85, 0x80, 0xDA, 0x95, 0x86, 0x8D, 0xC9, 0xB3,
+ 0xCB, 0xF4, 0x1A, 0x15, 0x94, 0x6C, 0x0B, 0x37, 0xCB, 0xA6, 0x9F, 0x1F, 0x87, 0xC0, 0xEC, 0xE4,
+ 0x3A, 0x34, 0xF1, 0x4F, 0xDC, 0xD8, 0xCB, 0x6E, 0x5D, 0xB4, 0xB1, 0x9B, 0xD4, 0xA6, 0x28, 0x0E,
+ 0xE1, 0x1F, 0x95, 0x6C, 0x4E, 0x76, 0x00, 0x42, 0x85, 0xDD, 0x0F, 0x7E, 0x9A, 0xC6, 0xAC, 0xED,
+ 0x0C, 0xEA, 0xF4, 0x3D, 0x2A, 0x16, 0x0E, 0xEE, 0xFC, 0x35, 0x2B, 0x11, 0x69, 0x01, 0x03, 0x3F,
+ 0x34, 0x07, 0x97, 0xBD, 0x3B, 0xAC, 0x16, 0x48, 0xFE, 0x0E, 0x1D, 0xC0, 0xCC, 0xF8, 0x96, 0xBF,
+ 0x3F, 0xBD, 0x65, 0x9F, 0x70, 0xFA, 0xE7, 0xCB, 0xED, 0xCF, 0x94, 0x33, 0x7E, 0x60, 0x06, 0x49,
+ 0x4D, 0x23, 0x25, 0xED, 0x00, 0xD5, 0x25, 0x18, 0x9C, 0x69, 0x8C, 0xC0, 0x74, 0x12, 0x65, 0xD0,
+ 0x39, 0x06, 0xE0, 0xF9, 0x1A, 0x78, 0xD0, 0x65, 0x5F, 0xA9, 0xAC, 0x6A, 0x38, 0x52, 0x0F, 0x6C,
+ 0xAA, 0x72, 0xA3, 0x8E, 0x39, 0x1E, 0x4A, 0x6A, 0xC7, 0xA9, 0x1A, 0xB3, 0xA5, 0x7E, 0x5B, 0x6C,
+ 0x4F, 0xE8, 0xC2, 0x40, 0xCA, 0xEF, 0x0F, 0x1A, 0xB6, 0x56, 0x37, 0x3B, 0x39, 0x52, 0x38, 0xB7,
+ 0x4E, 0x88, 0x56, 0xEF, 0x1A, 0x8A, 0xA0, 0x41, 0x76, 0xA8, 0xD3, 0xA2, 0x25, 0x13, 0xA5, 0xC4,
+ 0x0E, 0x1E, 0x59, 0xE8, 0xC9, 0x19, 0xB6, 0xB4, 0x88, 0x86, 0x0B, 0x64, 0x44, 0xAF, 0xE2, 0xBC,
+ 0x8A, 0x91, 0x09, 0xCD, 0xA7, 0x79, 0xE0, 0x57, 0xD1, 0xD4, 0xE7, 0x00, 0x77, 0x20, 0x27, 0xCC,
+ 0xBA, 0x83, 0x90, 0x03, 0x88, 0x30, 0xA5, 0x90, 0x57, 0xEA, 0x2A, 0x3C, 0xE6, 0xE2, 0x8C, 0x56,
+ 0xC5, 0xA2, 0xC3, 0xBE, 0x2D, 0x91, 0x40, 0xFE, 0x37, 0x99, 0xB8, 0x31, 0x9A, 0x8F, 0x35, 0x01,
+ 0x11, 0x98, 0xC8, 0xDE, 0xD5, 0xA3, 0xC1, 0x1A, 0xEA, 0x00, 0xA9, 0xD4, 0x9C, 0xD0, 0x08, 0xFF,
+ 0x76, 0xE2, 0xDD, 0x55, 0xDA, 0x47, 0xAD, 0x67, 0xC6, 0xC2, 0x3A, 0x43, 0xBF, 0x32, 0xFF, 0xE9,
+ 0xF9, 0x88, 0xF3, 0xE2, 0x2D, 0xAD, 0xAB, 0x00, 0xBB, 0x2A, 0x0E, 0x74, 0x27, 0x27, 0xE8, 0x88,
+ 0xB1, 0xA4, 0x92, 0x68, 0x94, 0x14, 0x5D, 0x20, 0xC6, 0xB7, 0x22, 0x0C, 0xFC, 0x66, 0x90, 0xA7,
+ 0x94, 0x8E, 0x1D, 0xF8, 0x58, 0xC2, 0x86, 0x6A, 0x64, 0xA8, 0xC5, 0xAF, 0x26, 0xEB, 0x6D, 0x7C,
+ 0xD8, 0x53, 0x0E, 0x6B, 0x02, 0xAB, 0x51, 0x8D, 0x81, 0x15, 0xF1, 0x84, 0xDD, 0x2A, 0x62, 0xBC,
+ 0xDB, 0x15, 0x89, 0x71, 0x41, 0x75, 0xD0, 0xA7, 0x8B, 0xA6, 0x85, 0xAE, 0xEB, 0xF6, 0x64, 0xF4,
+ 0x3F, 0x7D, 0x6B, 0x03, 0xEF, 0x58, 0x67, 0xEE, 0xBB, 0x14, 0xB9, 0xC2, 0x0F, 0xCC, 0x92, 0x05,
+ 0x2A, 0xA1, 0x25, 0x78, 0x91, 0xB7, 0x6C, 0x37, 0xA1, 0xF7, 0x75, 0xAB, 0xB4, 0x56, 0xD8, 0xFE,
+ 0xEF, 0xDF, 0x45, 0xE5, 0x8F, 0x70, 0xF3, 0xA7, 0xCC, 0x51, 0xF1, 0xE2, 0x71, 0x71, 0x33, 0x03,
+ 0x11, 0xC0, 0xC3, 0x4C, 0x1D, 0x07, 0x56, 0x2F, 0x9D, 0xD0, 0x8F, 0x77, 0xE5, 0xDE, 0x38, 0x29,
+ 0x96, 0x9D, 0xF8, 0xD9, 0x92, 0xC7, 0x26, 0x3E, 0x7F, 0xA0, 0x8B, 0xC4, 0x51, 0x68, 0x03, 0xBD,
+ 0x32, 0x95, 0x90, 0xED, 0x90, 0xE1, 0x7C, 0xB6, 0xAA, 0xEF, 0xB1, 0x8F, 0x37, 0x16, 0x6B, 0x32,
+ 0xD4, 0x4F, 0xE7, 0x88, 0x54, 0x40, 0xE6, 0x16, 0x6B, 0xEF, 0x7E, 0xDC, 0x9E, 0x3A, 0x75, 0x48,
+ 0x43, 0x87, 0xA7, 0x93, 0xD0, 0x42, 0xD5, 0xDD, 0x7B, 0xF0, 0xE1, 0x43, 0x16, 0x85, 0xCE, 0x90,
+ 0xC4, 0xD9, 0x07, 0xF3, 0x2E, 0xFB, 0x2C, 0x8A, 0xCE, 0xBC, 0x7E, 0xCC, 0x5B, 0x07, 0xFC, 0x4A,
+ 0xAA, 0x56, 0x8C, 0xDE, 0xBD, 0x3C, 0x02, 0xE6, 0x49, 0x64, 0x82, 0xE4, 0xDA, 0xC1, 0x04, 0x33,
+ 0xC0, 0xA0, 0xA3, 0x0F, 0x0D, 0x19, 0x64, 0xA5, 0xBF, 0x3F, 0xE2, 0xD0, 0x57, 0xE7, 0xB9, 0x52,
+ 0x39, 0x64, 0xFF, 0x35, 0xA8, 0x34, 0x9E, 0x45, 0x6F, 0x7C, 0xCC, 0x3F, 0x85, 0x67, 0xB4, 0xC9,
+ 0xA1, 0xF7, 0x49, 0xA9, 0xD4, 0xC5, 0x02, 0x24, 0x80, 0x3C, 0x5E, 0xDF, 0x6D, 0x6D, 0xC1, 0xA2,
+ 0x23, 0x24, 0x9B, 0x3B, 0xB9, 0x87, 0x55, 0x8A, 0xF6, 0xD2, 0xB1, 0x2C, 0xAA, 0x74, 0x32, 0x2A,
+ 0x11, 0x4C, 0xD9, 0x29, 0xDB, 0xA7, 0x4F, 0x98, 0x52, 0x38, 0x8D, 0x2E, 0x44, 0x63, 0x48, 0x74,
+ 0x53, 0x24, 0x91, 0xC1, 0x04, 0x33, 0xB4, 0xB2, 0x25, 0x2D, 0x28, 0x93, 0xA2, 0x3B, 0x56, 0xAA,
+ 0x36, 0x1B, 0x6C, 0x7E, 0x34, 0xB9, 0x70, 0x86, 0x87, 0xAC, 0xA4, 0x41, 0x83, 0x73, 0xA0, 0x20,
+ 0xD0, 0x0F, 0xD6, 0xA3, 0x0C, 0x3F, 0xA5, 0x1B, 0xC1, 0x0A, 0x17, 0x89, 0xC8, 0x16, 0xBA, 0xFA,
+ 0x4F, 0x99, 0xF3, 0x53, 0xE0, 0x67, 0xA5, 0xB3, 0x62, 0x75, 0x69, 0x4B, 0x42, 0x22, 0xB6, 0xE8,
+ 0x04, 0x66, 0x91, 0xD9, 0x73, 0x53, 0x11, 0x3A, 0xF4, 0x5C, 0x46, 0xC2, 0x02, 0x3F, 0xB8, 0x81,
+ 0xD0, 0x50, 0x0D, 0xFF, 0xDE, 0x34, 0x75, 0x1C, 0xDA, 0x05, 0x5E, 0x78, 0xB6, 0x59, 0x34, 0xA9,
+ 0xE2, 0xDC, 0x45, 0x64, 0x7E, 0xDD, 0x1B, 0x7D, 0x6C, 0xAA, 0x41, 0xC7, 0x58, 0xA2, 0xA9, 0x90,
+ 0x05, 0xDE, 0xE3, 0xF2, 0x31, 0xC2, 0x1C, 0xEE, 0xE1, 0x4B, 0x3C, 0xCA, 0x25, 0x31, 0xC5, 0x2D,
+ 0x80, 0x62, 0x5C, 0x60, 0xC0, 0x09, 0x52, 0x64, 0x4A, 0xFA, 0x62, 0xB6, 0x79, 0xF7, 0x78, 0x83,
+ 0xEB, 0x16, 0x6C, 0x0C, 0x87, 0x3A, 0xA1, 0x83, 0x9E, 0x04, 0x2B, 0xFE, 0x56, 0xFF, 0x4F, 0xE5,
+ 0x2D, 0xDC, 0x43, 0xE4, 0x71, 0xB9, 0x34, 0xE1, 0x67, 0x5D, 0x8B, 0x58, 0xA9, 0x4F, 0xFA, 0x9C,
+ 0xC3, 0xA6, 0xD8, 0xE6, 0x7C, 0xA5, 0xCC, 0x41, 0x31, 0x5A, 0x75, 0xAA, 0x29, 0xE7, 0x93, 0x57,
+ 0x5B, 0x59, 0x0C, 0x7E, 0x07, 0xBD, 0xE9, 0xB4, 0xAA, 0xA7, 0x0A, 0x33, 0xD5, 0x79, 0x29, 0xDC,
+ 0x6B, 0x6D, 0x13, 0xB4, 0x8A, 0xC9, 0x62, 0x07, 0xDE, 0x84, 0x20, 0x26, 0x69, 0xD8, 0x3B, 0x35,
+ 0x14, 0x42, 0xF3, 0xEC, 0xD9, 0x29, 0x93, 0x33, 0xEB, 0x4E, 0xD5, 0xED, 0xFF, 0x95, 0xA1, 0x20,
+ 0xDF, 0xB4, 0x3C, 0x93, 0x46, 0x57, 0x6F, 0x0B, 0x20, 0xF9, 0xC3, 0xA3, 0x7D, 0xB4, 0x7D, 0xA1,
+ 0x4F, 0x68, 0xEB, 0xDA, 0xA5, 0x70, 0xCE, 0x7B, 0xB6, 0xE8, 0xB7, 0x2E, 0x5F, 0x7F, 0xDF, 0xFF,
+ 0xBF, 0x6D, 0xDA, 0x32, 0x07, 0x4C, 0xFE, 0xDC, 0xB8, 0x12, 0x61, 0xA3, 0xF1, 0xA3, 0x99, 0x03,
+ 0x15, 0x4B, 0xA2, 0x05, 0xDE, 0xC5, 0xFB, 0x61, 0x68, 0xF0, 0x17, 0xEC, 0x2B, 0x71, 0x1F, 0xEA,
+ 0x7B, 0xF5, 0x4A, 0x54, 0x82, 0x74, 0x11, 0x76, 0x72, 0x8B, 0x99, 0x95, 0xF0, 0x26, 0xDA, 0xCA,
+ 0xB5, 0xC7, 0x1D, 0x2C, 0xB2, 0x27, 0x17, 0x0E, 0xA5, 0x7B, 0xC6, 0x8C, 0x97, 0x7E, 0x66, 0x3B,
+ 0x84, 0x29, 0xDC, 0xCB, 0x6C, 0x2D, 0xA8, 0x50, 0x29, 0x4E, 0x06, 0xFB, 0x04, 0x08, 0x79, 0x8D,
+ 0xE0, 0x14, 0x51, 0xF6, 0x53, 0x85, 0x2C, 0xDF, 0x64, 0x5A, 0x81, 0xFE, 0x55, 0x54, 0x50, 0xEB,
+ 0xC0, 0xA1, 0x80, 0x20, 0xAF, 0x0F, 0xC2, 0x3C, 0x76, 0x63, 0x5D, 0xA7, 0x5C, 0x6B, 0xF6, 0xF3,
+ 0xD7, 0x59, 0x08, 0x22, 0x64, 0xB7, 0x5D, 0x9C, 0xD3, 0xB0, 0x4A, 0xB7, 0x6A, 0xFD, 0xDA, 0x96,
+ 0x0C, 0x6F, 0xD6, 0x73, 0x54, 0x65, 0x98, 0xEC, 0x70, 0xC0, 0x95, 0xCD, 0x2D, 0xCB, 0x84, 0xD9,
+ 0x20, 0x3E, 0x3D, 0xBB, 0xF9, 0xB1, 0x66, 0xAF, 0x53, 0x5A, 0x26, 0x44, 0xB3, 0xA4, 0x05, 0xC5,
+ 0xEB, 0x17, 0x88, 0x2B, 0xF0, 0xA1, 0xAE, 0xEA, 0x69, 0x4B, 0xD8, 0x2F, 0xE5, 0x36, 0x57, 0xF9,
+ 0xF3, 0x00, 0x4B, 0x07, 0x48, 0x04, 0x09, 0x0D, 0x4A, 0x42, 0x1F, 0xED, 0xFA, 0xEA, 0xA7, 0x68,
+ 0x1A, 0x03, 0x2C, 0xEB, 0xF6, 0xDB, 0x6A, 0x2D, 0xBF, 0x56, 0x63, 0x54, 0x7B, 0xDA, 0x09, 0x9B,
+ 0xF7, 0x38, 0xF0, 0x57, 0x7F, 0x8D, 0xCB, 0x03, 0x15, 0x0A, 0x15, 0xA5, 0xC9, 0xD6, 0xC8, 0xC2,
+ 0x9F, 0x1D, 0x56, 0x82, 0x44, 0x78, 0x57, 0x74, 0x9D, 0x0F, 0x1A, 0x43, 0x93, 0x52, 0x9D, 0x16,
+ 0xEC, 0x5C, 0xDA, 0x09, 0xEC, 0xFC, 0x2A, 0x75, 0x4B, 0x32, 0xA9, 0xB2, 0x6E, 0x91, 0xB1, 0x22,
+ 0xC2, 0xE2, 0x79, 0xCC, 0xDD, 0x68, 0xD0, 0x22, 0x05, 0x07, 0xCF, 0xB5, 0xC6, 0xED, 0xCD, 0x5D,
+ 0x17, 0xD5, 0xD6, 0xC2, 0x49, 0x28, 0x8D, 0x79, 0xCF, 0xC3, 0x6D, 0xCE, 0x96, 0x3C, 0x8D, 0x6F,
+ 0x16, 0x39, 0x8D, 0x4F, 0xE4, 0x23, 0x7C, 0x4F, 0x56, 0x5A, 0xC0, 0xDC, 0x41, 0x30, 0x2C, 0x24,
+ 0x2E, 0x66, 0xF6, 0x00, 0x6E, 0x03, 0x81, 0x5B, 0x8D, 0xD2, 0x3F, 0x79, 0xFC, 0x43, 0x25, 0xB2,
+ 0x87, 0x88, 0xCA, 0xD8, 0xA9, 0xB5, 0x61, 0x85, 0xAD, 0xE1, 0x64, 0xE8, 0x52, 0x0C, 0x7F, 0xF6,
+ 0x9A, 0xB7, 0xA3, 0x6A, 0x43, 0xCB, 0xBE, 0x33, 0xFA, 0x19, 0xA4, 0xB7, 0xA8, 0xEB, 0x24, 0x94,
+ 0x95, 0xA6, 0xA7, 0xBA, 0xE4, 0x5C, 0x36, 0x31, 0xE4, 0x38, 0xEF, 0x35, 0xAA, 0x66, 0x6B, 0x6D,
+ 0x6C, 0x6A, 0x87, 0x2E, 0xCF, 0x35, 0x48, 0xD7, 0xC4, 0x7E, 0xA8, 0x93, 0xA0, 0xBB, 0x32, 0x95,
+ 0x21, 0xE4, 0x39, 0x9F, 0xBD, 0xB8, 0x50, 0x52, 0xF8, 0x6F, 0x84, 0x3E, 0x61, 0xAD, 0xAC, 0x28,
+ 0xA7, 0xE7, 0xEC, 0x7F, 0x05, 0x4E, 0x08, 0x1D, 0xC7, 0x04, 0x0E, 0x20, 0x00, 0x10, 0x80, 0x26,
+ 0xB4, 0x13, 0xFD, 0x66, 0x40, 0x83, 0x70, 0x47, 0x54, 0xE6, 0x18, 0x5A, 0xCA, 0xB6, 0x2E, 0xCD,
+ 0xD1, 0x99, 0xF2, 0x68, 0xC3, 0xF4, 0xED, 0x20, 0xFC, 0xD9, 0x1E, 0x4C, 0xAA, 0x1D, 0x5C, 0xCC,
+ 0xE0, 0xE1, 0x4F, 0x9B, 0x3C, 0x08, 0xF2, 0x20, 0x7D, 0xBA, 0xD8, 0xE1, 0xA2, 0xB5, 0xA2, 0xF1,
+ 0x9E, 0x10, 0xAF, 0x9E, 0x6B, 0xD6, 0x34, 0x53, 0x1B, 0xBB, 0x36, 0xF6, 0xB2, 0xE5, 0x51, 0x5E,
+ 0x86, 0x2C, 0x79, 0x6B, 0x8E, 0xC0, 0x4D, 0x9A, 0xAF, 0x02, 0xD9, 0x7F, 0xDF, 0x12, 0xE4, 0xCE,
+ 0x81, 0x6C, 0xA2, 0x87, 0x57, 0x2C, 0x10, 0x75, 0x08, 0x46, 0xF4, 0xA8, 0xA8, 0x08, 0xCC, 0x74,
+ 0xA8, 0xCB, 0xCA, 0x74, 0x73, 0x1A, 0x3F, 0x1D, 0xFA, 0x58, 0x75, 0x82, 0x72, 0xE7, 0x0D, 0x29,
+ 0x73, 0x4A, 0xE4, 0x94, 0x51, 0xEA, 0x53, 0xE0, 0xC4, 0x60, 0x29, 0xB5, 0x1D, 0x1A, 0xA0, 0xAB,
+ 0xEE, 0x34, 0x42, 0x41, 0x96, 0xE6, 0x6B, 0x21, 0xA8, 0x85, 0x6F, 0x04, 0x08, 0x9D, 0x7B, 0xE5,
+ 0xEB, 0x3B, 0x25, 0x5C, 0x8B, 0xBA, 0xF8, 0x02, 0x25, 0xA6, 0x3C, 0x54, 0x05, 0x2B, 0xBB, 0x35,
+ 0x2A, 0x97, 0xD5, 0x8B, 0x98, 0x56, 0x0C, 0x4D, 0x49, 0x92, 0xAC, 0x53, 0x06, 0x38, 0x63, 0xC6,
+ 0xE7, 0xC1, 0x62, 0x11, 0xB1, 0x43, 0xF3, 0xB4, 0xA9, 0x66, 0x3E, 0x5D, 0x0D, 0x6D, 0x1B, 0x02,
+ 0xD7, 0x6E, 0x4C, 0x67, 0x5B, 0x3A, 0x86, 0x2D, 0xAA, 0x2D, 0x89, 0x33, 0xD5, 0xF4, 0x1A, 0xF4,
+ 0x5A, 0x09, 0xC1, 0x82, 0x79, 0xD1, 0x50, 0x81, 0x7E, 0xBC, 0x8A, 0x14, 0x97, 0x68, 0x77, 0x15,
+ 0xEA, 0x4B, 0xD2, 0x56, 0x6C, 0x7D, 0xEB, 0x05, 0x0A, 0x6F, 0xB1, 0x71, 0xC3, 0xFC, 0xD5, 0xDC,
+ 0x45, 0x72, 0xB3, 0x4D, 0xA2, 0x8D, 0xD1, 0x65, 0x3B, 0x87, 0x95, 0xC9, 0x79, 0x95, 0xFC, 0x33,
+ 0xB3, 0xB3, 0xAC, 0xDC, 0x09, 0xD9, 0x6E, 0xFE, 0xDD, 0x1E, 0xDB, 0xED, 0x9A, 0x62, 0xE5, 0x54,
+ 0xFE, 0x41, 0x2D, 0xCB, 0x01, 0xF8, 0xF5, 0xD7, 0x6E, 0x22, 0xA5, 0x14, 0x42, 0xB4, 0xBD, 0x5B,
+ 0x2B, 0x06, 0xB1, 0xCD, 0x0B, 0xA0, 0x9B, 0x12, 0x38, 0x30, 0xDE, 0x7C, 0xBF, 0x26, 0xED, 0x2D,
+ 0x5A, 0x09, 0x61, 0x7F, 0xB0, 0xB1, 0xD4, 0x52, 0xA1, 0x5E, 0x9D, 0x84, 0xC8, 0xDC, 0xD7, 0x1D,
+ 0x2B, 0x77, 0x5C, 0xF4, 0x55, 0x64, 0x78, 0x46, 0x76, 0xE9, 0xAF, 0x5E, 0x02, 0xE5, 0xBF, 0x23,
+ 0xE4, 0x9A, 0x15, 0x99, 0x7C, 0x45, 0x25, 0xDB, 0x00, 0xFA, 0xD0, 0x9D, 0x1B, 0xA9, 0x92, 0x37,
+ 0x3D, 0xD6, 0x81, 0x02, 0x74, 0xA0, 0x1C, 0x97, 0x7F, 0x48, 0xBA, 0x55, 0x14, 0x3D, 0x53, 0x44,
+ 0xD2, 0x15, 0xD8, 0x91, 0x87, 0x40, 0x4D, 0x78, 0x79, 0x12, 0x44, 0x0F, 0xCD, 0x9A, 0x85, 0x40,
+ 0x33, 0x47, 0x2B, 0x66, 0x3E, 0x3C, 0xDD, 0x9A, 0x22, 0xDC, 0xDC, 0xB3, 0x29, 0x4B, 0xCA, 0xBE,
+ 0x2B, 0x58, 0xE1, 0xB6, 0x14, 0x7F, 0x75, 0x40, 0x42, 0x61, 0x39, 0x24, 0x97, 0xF8, 0x46, 0xAE,
+ 0xB0, 0x20, 0xE5, 0xEF, 0x48, 0x9C, 0x78, 0x6D, 0x9F, 0xA3, 0x1A, 0xDD, 0xFC, 0x22, 0x97, 0x13,
+ 0x0B, 0x25, 0x7B, 0xB8, 0xEE, 0x47, 0xFE, 0x20, 0x28, 0xB6, 0xFE, 0x4B, 0x31, 0x99, 0x65, 0x20,
+ 0xAA, 0x3C, 0xDE, 0xF4, 0x08, 0xB7, 0xB4, 0xCE, 0x30, 0x61, 0x37, 0x04, 0x76, 0x0D, 0x34, 0x8E,
+ 0x7A, 0x3D, 0xF2, 0x21, 0xDC, 0xD5, 0xEC, 0x63, 0xF3, 0xB0, 0x21, 0xF5, 0x28, 0x32, 0x66, 0xA7,
+ 0x7F, 0x28, 0x9C, 0x59, 0xFE, 0x59, 0xDC, 0x8A, 0xAC, 0x11, 0xE5, 0x62, 0xA6, 0xCA, 0xAF, 0xD9,
+ 0x92, 0xE7, 0x85, 0xD6, 0x40, 0x81, 0x06, 0xA8, 0xD1, 0x18, 0xCC, 0x7D, 0x37, 0xD5, 0x33, 0x08,
+ 0xAA, 0x14, 0x9C, 0xA3, 0x41, 0x66, 0xEC, 0x5C, 0x3D, 0x3C, 0x02, 0x44, 0x5A, 0x7E, 0x1A, 0x70,
+ 0x0B, 0xC1, 0x14, 0x7E, 0x6D, 0xEF, 0xF2, 0xC4, 0x6E, 0x8F, 0x99, 0xF8, 0xF0, 0xF8, 0xA1, 0x88,
+ 0xAD, 0xE7, 0xC3, 0x8B, 0x94, 0x95, 0xC6, 0x8D, 0xC1, 0x7B, 0x77, 0x75, 0x06, 0x2B, 0x4E, 0xBC,
+ 0x94, 0x9D, 0xBB, 0x62, 0xE4, 0x71, 0x5D, 0x2C, 0x59, 0x27, 0x10, 0x2F, 0x86, 0x8B, 0x0F, 0xF6,
+ 0x8A, 0x6F, 0x77, 0xEE, 0x4F, 0x0F, 0xD1, 0x9F, 0x07, 0x0B, 0x17, 0xD5, 0x70, 0x5D, 0x56, 0x6D,
+ 0x66, 0x18, 0xE6, 0x02, 0x80, 0x02, 0x24, 0xE5, 0x3C, 0x7E, 0xF7, 0x9E, 0x1D, 0x6C, 0xF8, 0x0C,
+ 0xCC, 0xDE, 0x97, 0x89, 0x7C, 0x03, 0x07, 0x32, 0xA0, 0xB2, 0x44, 0x44, 0x7E, 0xCB, 0x63, 0x69,
+ 0xB3, 0x11, 0xE2, 0x48, 0x03, 0x5D, 0x08, 0x26, 0x00, 0x56, 0x8D, 0x96, 0x5B, 0x8D, 0x8E, 0x5C,
+ 0xEE, 0xDC, 0x27, 0x3B, 0x4C, 0x4B, 0xC1, 0xCE, 0xCA, 0x94, 0x8D, 0x3A, 0x4E, 0x6E, 0x0B, 0x7B,
+ 0x81, 0x23, 0xBF, 0x24, 0x93, 0xF5, 0xFD, 0xB6, 0x3A, 0x34, 0xD1, 0xFD, 0xC1, 0x37, 0xDF, 0xEF,
+ 0x8D, 0x0B, 0xF6, 0x1C, 0xCA, 0x35, 0xCB, 0xA1, 0x63, 0x5F, 0x07, 0x55, 0x18, 0x06, 0x40, 0xB7,
+ 0x2E, 0xA4, 0x15, 0x11, 0xB6, 0xDD, 0xEB, 0xA4, 0x78, 0xD0, 0x50, 0x52, 0x24, 0x08, 0xC2, 0x7E,
+ 0x14, 0x37, 0x73, 0x33, 0x1F, 0x23, 0x92, 0x78, 0x64, 0xC8, 0xE6, 0x88, 0xA6, 0xFA, 0x98, 0xF0,
+ 0x76, 0xCB, 0x20, 0xF7, 0xA1, 0x67, 0xC6, 0x9B, 0x38, 0x50, 0x81, 0x14, 0x24, 0x8E, 0xE9, 0x0F,
+ 0xC2, 0xA5, 0xBB, 0x5D, 0x07, 0x97, 0x20, 0xCF, 0x05, 0xE6, 0xED, 0xDA, 0x9B, 0xAB, 0xA4, 0x48,
+ 0xD5, 0x88, 0xCE, 0x80, 0x4B, 0x66, 0xCE, 0xAB, 0x9C, 0xDE, 0xB9, 0x78, 0x0B, 0x4E, 0x56, 0x56,
+ 0xD6, 0xDB, 0x85, 0xEA, 0x73, 0x97, 0x64, 0x74, 0xFF, 0xF5, 0xC6, 0xD1, 0x88, 0xB4, 0x67, 0xF3,
+ 0xA6, 0xDD, 0x13, 0x9B, 0xCE, 0xD2, 0x2B, 0xAC, 0xB4, 0x28, 0x31, 0x6C, 0x85, 0x1D, 0x91, 0xC0,
+ 0xCF, 0xB5, 0x91, 0x5B, 0xBC, 0x82, 0x1F, 0x68, 0x82, 0x85, 0xAD, 0x2B, 0x7D, 0x06, 0xFA, 0x9E,
+ 0x31, 0x1E, 0x16, 0xC8, 0x9F, 0xC3, 0xA7, 0xDC, 0x17, 0xB2, 0xFD, 0xF4, 0x46, 0xF6, 0x61, 0xC2,
+ 0x04, 0x27, 0xF2, 0xF7, 0xCF, 0x3A, 0xE3, 0xAE, 0x2A, 0x62, 0x0E, 0x3B, 0x81, 0xC9, 0x49, 0x5B,
+ 0x7C, 0xBC, 0xE8, 0x3A, 0x96, 0x82, 0x32, 0x67, 0xF2, 0xAC, 0xAE, 0x7F, 0xC9, 0x79, 0x35, 0x4E,
+ 0xB7, 0x95, 0x53, 0xAC, 0x43, 0xBC, 0x2E, 0x0E, 0xFC, 0x9F, 0x2E, 0x16, 0xD0, 0x96, 0x46, 0x60,
+ 0xBC, 0xD2, 0x21, 0x4D, 0x46, 0xAD, 0xA8, 0x1C, 0x85, 0x93, 0x28, 0xDF, 0x04, 0xC5, 0xAB, 0x37,
+ 0x60, 0x7C, 0x0E, 0xD6, 0x4E, 0xB2, 0x4F, 0x04, 0x71, 0xC9, 0x68, 0xCB, 0xE1, 0x90, 0xE1, 0x65,
+ 0x9A, 0x7E, 0x00, 0xF6, 0xE7, 0xA2, 0x19, 0xF9, 0x77, 0xE1, 0xFF, 0xBE, 0xE0, 0x92, 0xB8, 0xE9,
+ 0x1C, 0x96, 0xB7, 0x82, 0x04, 0x88, 0x5E, 0x00, 0xD3, 0x66, 0x68, 0x66, 0xA5, 0x5F, 0xA9, 0xB9,
+ 0x15, 0xFC, 0x33, 0xAE, 0x10, 0x8B, 0x12, 0x95, 0xE1, 0xD3, 0xAD, 0xBE, 0xA2, 0x44, 0x2C, 0x7A,
+ 0xD2, 0xCC, 0x8D, 0x07, 0x64, 0x02, 0xC3, 0x62, 0xEF, 0xC4, 0xD0, 0x8B, 0xEC, 0xE2, 0xB3, 0x34,
+ 0x88, 0xB7, 0xFE, 0x97, 0xD2, 0x92, 0xAF, 0x53, 0xDA, 0x9E, 0xD8, 0xBF, 0x83, 0x06, 0x91, 0x72,
+ 0x59, 0x4A, 0xDA, 0x3B, 0xED, 0x36, 0x4D, 0xFB, 0xD9, 0x2F, 0x68, 0x1A, 0xD6, 0xC2, 0x4E, 0x06,
+ 0x54, 0xA2, 0x5F, 0xC4, 0x9E, 0x6E, 0x3C, 0xFE, 0x6C, 0x92, 0xD8, 0x86, 0x66, 0xC1, 0xDF, 0x75,
+ 0x6F, 0xD1, 0x5F, 0x9F, 0xA0, 0x16, 0xB0, 0x18, 0x1F, 0xB1, 0xD8, 0x5C, 0x78, 0x91, 0x2C, 0x05,
+ 0xD9, 0x93, 0xA3, 0xF0, 0x6A, 0xA4, 0x7E, 0x36, 0x2A, 0xA3, 0x8D, 0xAE, 0x89, 0xD8, 0xD5, 0x3A,
+ 0xBF, 0xA2, 0x47, 0xAF, 0xD6, 0xF7, 0x52, 0x79, 0xF7, 0x72, 0xAA, 0xE4, 0x43, 0x0B, 0x4D, 0x31,
+ 0x74, 0xA3, 0x84, 0x08, 0xF7, 0x63, 0xCA, 0xB5, 0xE2, 0xDF, 0x23, 0xBA, 0x71, 0x5F, 0x01, 0xE2,
+ 0x11, 0x61, 0x7B, 0x22, 0x04, 0x0A, 0x6E, 0x23, 0x1D, 0xAE, 0xDB, 0xBF, 0x40, 0x31, 0x47, 0x5D,
+ 0xA6, 0x4C, 0xF7, 0x98, 0xAD, 0xA6, 0x89, 0xCE, 0x33, 0xD6, 0x06, 0x81, 0x59, 0x59, 0x85, 0x20,
+ 0xE3, 0xA7, 0x48, 0xFC, 0xD5, 0x8B, 0x79, 0xA5, 0x17, 0x92, 0x00, 0xDC, 0x07, 0xEE, 0xE8, 0x93,
+ 0xDF, 0x4B, 0xF7, 0x0D, 0x41, 0x9C, 0x23, 0xD2, 0xE3, 0xAE, 0x27, 0xD8, 0x91, 0x6A, 0x5B, 0xF3,
+ 0xE5, 0xC3, 0xF5, 0xCB, 0xEE, 0xA5, 0xF7, 0xE3, 0xC6, 0xF6, 0xB0, 0xE1, 0x59, 0x5E, 0xB1, 0x0F,
+ 0x3F, 0xD4, 0xD4, 0xEE, 0xB4, 0x98, 0xA3, 0x46, 0x06, 0x93, 0x70, 0x48, 0x62, 0x44, 0xCE, 0xB8,
+ 0x87, 0x05, 0xF9, 0xD3, 0x2C, 0x26, 0x9A, 0xA1, 0xDF, 0xA8, 0x4B, 0x96, 0x96, 0x91, 0x64, 0xD3,
+ 0x35, 0x2A, 0xDF, 0xC2, 0x83, 0x4C, 0xEA, 0x07, 0x2F, 0xB5, 0x14, 0x7F, 0xD4, 0x5A, 0x27, 0x6E,
+ 0x75, 0xF7, 0x88, 0x45, 0xB5, 0x1B, 0x55, 0x9E, 0x43, 0xAC, 0xEC, 0xEE, 0xD6, 0xC1, 0x8A, 0x13,
+ 0x5D, 0xB4, 0xE7, 0x23, 0x60, 0x9B, 0x3A, 0xDF, 0x59, 0xD4, 0xDD, 0x89, 0x93, 0xF6, 0xEB, 0x61,
+ 0xA5, 0x6B, 0x22, 0x25, 0xCC, 0x5E, 0x31, 0x90, 0xE0, 0x54, 0xEA, 0xA2, 0x8F, 0x6C, 0x79, 0x74,
+ 0xCC, 0x2F, 0xDD, 0x99, 0xF2, 0x70, 0xA2, 0x73, 0x7F, 0xF9, 0xFA, 0x86, 0xD7, 0x6F, 0xEA, 0x26,
+ 0x6D, 0x40, 0xDE, 0xDB, 0xCC, 0xF9, 0x34, 0xCB, 0x14, 0x8B, 0x94, 0xAA, 0xB7, 0xEC, 0x3B, 0xF4,
+ 0x4B, 0x14, 0xAA, 0xD6, 0x0F, 0x9C, 0x9B, 0x95, 0x89, 0x71, 0x41, 0xE1, 0x40, 0x02, 0x86, 0x8E,
+ 0x9E, 0xBE, 0xFE, 0x5F, 0x3C, 0xDB, 0x15, 0xA8, 0xD2, 0x26, 0xAF, 0xDC, 0x3A, 0xF6, 0x4F, 0xFD,
+ 0x78, 0x53, 0x24, 0xCA, 0x16, 0x8F, 0x7D, 0x59, 0x11, 0xA0, 0xA3, 0xA5, 0xA9, 0xB1, 0xE0, 0x23,
+ 0xC4, 0xEB, 0x35, 0xC9, 0xF1, 0x41, 0x00, 0x63, 0x25, 0xA9, 0xD0, 0x22, 0xA7, 0xCC, 0x1A, 0x97,
+ 0x8D, 0x98, 0xB2, 0xC7, 0x0C, 0x9A, 0x97, 0xAC, 0xBB, 0xF4, 0x6A, 0x37, 0xEC, 0x3B, 0xD5, 0x28,
+ 0xB3, 0xE4, 0x2B, 0xB5, 0xE8, 0x52, 0x26, 0xAF, 0xDC, 0x1B, 0xB4, 0xEA, 0x56, 0x0F, 0x9C, 0xBA,
+ 0xF6, 0x4F, 0xFD, 0x78, 0x53, 0x24, 0xAB, 0xD4, 0x2A, 0xB7, 0xCD, 0xF9, 0x51, 0x20, 0xC2, 0x06,
+ 0x6F, 0x5C, 0x1B, 0xB4, 0xCB, 0xF5, 0x49, 0xF1, 0x41, 0x00, 0x82, 0x67, 0x2D, 0xB9, 0xF0, 0x62,
+ 0x46, 0x0E, 0x9E, 0xBE, 0xDF, 0x3C, 0xFA, 0x76, 0x4F, 0xFD, 0x59, 0x30, 0xC3, 0x04, 0x6B, 0x35,
+ 0xC9, 0x10, 0xA2, 0xC6, 0x0E, 0x7F, 0x5D, 0x19, 0xB0, 0xE2, 0x27, 0xCC, 0xFB, 0x55, 0x09, 0x90,
+ 0x83, 0x84, 0x6B, 0x35, 0xC9, 0x10, 0xA2, 0xA7, 0xAD, 0xB9, 0xF0, 0x43, 0x04, 0x8A, 0x77, 0x4D,
+ 0xF9, 0x51, 0x01, 0x80, 0x82, 0x86, 0x8E, 0x7F, 0x7C, 0x7A, 0x76, 0x4F, 0x1C, 0xBA, 0xD7, 0x2C,
+ 0xDA, 0x36, 0xEE, 0x5E, 0x1F, 0x9D, 0x99, 0xB0, 0xC3, 0x04, 0x6B, 0x35, 0xC9, 0x10, 0x83, 0x84,
+ 0x6B, 0x35, 0xC9, 0xF1, 0x60, 0x23, 0xC4, 0xEB, 0x54, 0x0B, 0x94, 0xAA, 0xB7, 0xEC, 0x3B, 0xF4,
+ 0x4B, 0x14, 0x8B, 0x94, 0x8B, 0x75, 0x68, 0x52, 0x26, 0xCE, 0x1E, 0xBE, 0xDF, 0x1D, 0x99, 0x91,
+ 0x81, 0x61, 0x21, 0xC0, 0x02, 0x86, 0x6F, 0x5C, 0x3A, 0xF6, 0x6E, 0x3F, 0xFC, 0x5B, 0x15, 0x89,
+ 0x71, 0x41, 0xE1, 0x21, 0xC0, 0x02, 0x67, 0x2D, 0xD8, 0x32, 0xC7, 0xED, 0x39, 0xD1, 0x01, 0x80,
+ 0x63, 0x25, 0xC8, 0xF3, 0x64, 0x2B, 0xD4, 0x2A, 0xD6, 0x2E, 0xBF, 0xFC, 0x5B, 0x34, 0xCB, 0x14,
+ 0x8B, 0x75, 0x68, 0x33, 0xE4, 0x4A, 0x16, 0x8F, 0x7D, 0x78, 0x72, 0x66, 0x2F, 0xBD, 0xF8, 0x53,
+ 0x24, 0xCA, 0x16, 0xAE, 0xBF, 0xFC, 0x7A, 0x57, 0x0D, 0x79, 0x70, 0x43, 0xE5, 0x48, 0xF3, 0x45,
+ 0xE9, 0x31, 0xE0, 0x42, 0xE7, 0x4C, 0xFB, 0x55, 0x09, 0x71, 0x41, 0x00, 0x63, 0x25, 0xC8, 0x12,
+ 0x87, 0x6D, 0x39, 0xF0, 0x43, 0x04, 0x6B, 0x35, 0xC9, 0x10, 0x83, 0x84, 0x8A, 0x96, 0x8F, 0x7D,
+ 0x78, 0x53, 0x24, 0xCA, 0x16, 0x8F, 0x9C, 0xBA, 0xF6, 0x6E, 0x3F, 0xDD, 0x19, 0xB0, 0xE2, 0x46,
+ 0x0E, 0x7F, 0x5D, 0x38, 0xD3, 0x05, 0x88, 0x73, 0x64, 0x2B, 0xB5, 0xE8, 0x33, 0xE4, 0x4A, 0x16,
+ 0xAE, 0xBF, 0xFC, 0x7A, 0x57, 0x0D, 0x98, 0x93, 0x85, 0x69, 0x50, 0x03, 0x65, 0x29, 0xD0, 0x22,
+ 0xC6, 0x0E, 0x9E, 0x9F, 0x9D, 0xB8, 0xD3, 0x24, 0xAB, 0xD4, 0x0B, 0x75, 0x49, 0x10, 0x83, 0x65,
+ 0x48, 0xF3, 0x64, 0x2B, 0xB5, 0xE8, 0x52, 0x07, 0x6D, 0x39, 0xD1, 0x01, 0x80, 0x82, 0x67, 0x2D,
+ 0xB9, 0xD1, 0x20, 0xA3, 0xA5, 0xA9, 0xD0, 0x03, 0x84, 0x6B, 0x35, 0xE8, 0x33, 0xC5, 0xE9, 0x50,
+ 0x22, 0xC6, 0xEF, 0x5C, 0x3A, 0xF6, 0x6E, 0x5E, 0x1F, 0x9D, 0xB8, 0xF2, 0x47, 0xED, 0x39, 0xF0,
+ 0x43, 0x04, 0x8A, 0x96, 0x8F, 0x7D, 0x59, 0x11, 0x81, 0x61, 0x21, 0xA1, 0xC0, 0x02, 0x67, 0x2D,
+ 0xB9, 0xF0, 0x43, 0x04, 0x8A, 0x77, 0x4D, 0xF9, 0x70, 0x43, 0x04, 0x8A, 0x96, 0xAE, 0xDE, 0x1F,
+ 0x9D, 0xB8, 0xD3, 0x05, 0x88, 0x92, 0x87, 0x8C, 0x9A, 0xB6, 0xCF, 0xFD, 0x59, 0x30, 0xC3, 0x04,
+ 0x8A, 0x96, 0x8F, 0x7D, 0x78, 0x72, 0x66, 0x4E, 0xFF, 0x7C, 0x5B, 0x15, 0x89, 0x71, 0x41, 0xE1,
+ 0x21, 0xA1, 0xA1, 0xA1, 0xA1, 0xC0, 0xE3, 0x44, 0x0A, 0x96, 0x8F, 0x7D, 0x59, 0x30, 0xE2, 0x27,
+ 0xCC, 0x1A, 0xB6, 0xEE, 0x5E, 0x1F, 0x9D, 0x99, 0x91, 0xA0, 0xA3, 0xC4, 0xEB, 0x35, 0xE8, 0x33,
+ 0xC5, 0x08, 0x73, 0x64, 0x2B, 0xD4, 0x2A, 0xD6, 0x2E, 0xBF, 0xDD, 0x38, 0xF2, 0x47, 0x0C, 0x7B,
+ 0x55, 0x28, 0xB3, 0xC5, 0x08, 0x92, 0xA6, 0xAF, 0xBD, 0xF8, 0x72, 0x47, 0x0C, 0x7B, 0x74, 0x4B,
+ 0xF5, 0x68, 0x33, 0xC5, 0x08, 0x73, 0x64, 0x4A, 0xF7, 0x4D, 0xF9, 0x70, 0x43, 0x04, 0x6B, 0x35,
+ 0xC9, 0xF1, 0x41, 0xE1, 0x21, 0xC0, 0xE3, 0x25, 0xC8, 0x12, 0x87, 0x6D, 0x39, 0xD1, 0x20, 0xA3,
+ 0xA5, 0xA9, 0xB1, 0xE0, 0x23, 0xC4, 0xEB, 0x54, 0x0B, 0x75, 0x49, 0x10, 0x83, 0x65, 0x48, 0xF3,
+ 0x45, 0xE9, 0x31, 0xE0, 0x42, 0xE7, 0x2D, 0xB9, 0xD1, 0x01, 0x61, 0x21, 0xA1, 0xC0, 0x02, 0x67,
+ 0x4C, 0x1A, 0x97, 0x8D, 0x98, 0xB2, 0xC7, 0xED, 0x58, 0x32, 0xE6, 0x2F, 0xDC, 0x3A, 0xD7, 0x2C,
+ 0xDA, 0x17, 0x8D, 0x79, 0x51, 0x01, 0x80, 0x63, 0x44, 0x0A, 0x77, 0x6C, 0x3B, 0xD5, 0x28, 0xD2,
+ 0x26, 0xCE, 0xFF, 0x7C, 0x5B, 0x34, 0xEA, 0x37, 0xEC, 0x3B, 0xF4, 0x4B, 0x14, 0x8B, 0x94, 0xAA,
+ 0xD6, 0x2E, 0xDE, 0x3E, 0xFE, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x5F, 0x3C, 0xDB, 0x15, 0xA8, 0xD2,
+ 0x26, 0xCE, 0xFF, 0x7C, 0x7A, 0x57, 0x0D, 0x98, 0xB2, 0xC7, 0x0C, 0x7B, 0x74, 0x4B, 0x14, 0x8B,
+ 0x94, 0x8B, 0x75, 0x49, 0x10, 0x83, 0x84, 0x8A, 0x77, 0x6C, 0x5A, 0x17, 0xAC, 0xDA, 0x36, 0xCF,
+ 0x1C, 0xBA, 0xF6, 0x6E, 0x3F, 0xFC, 0x5B, 0x34, 0xEA, 0x37, 0xEC, 0x3B, 0xF4, 0x4B, 0xF5, 0x49,
+ 0xF1, 0x41, 0xE1, 0x21, 0xA1, 0xC0, 0x02, 0x86, 0x8E, 0x9E, 0xBE, 0xFE, 0x7E, 0x7E, 0x7E, 0x5F,
+ 0x3C, 0xFA, 0x76, 0x6E, 0x3F, 0xFC, 0x7A, 0x76, 0x4F, 0xFD, 0x59, 0x30, 0xE2, 0x27, 0xAD, 0xD8,
+ 0x13, 0xA4, 0xCA, 0x16, 0xAE, 0xDE, 0x3E, 0xFE, 0x5F, 0x1D, 0xB8, 0xF2, 0x47, 0x0C, 0x7B, 0x74,
+ 0x6A, 0x56, 0x0F, 0x7D, 0x78, 0x72, 0x47, 0x0C, 0x9A, 0xB6, 0xCF, 0xFD, 0x78, 0x72, 0x66, 0x2F,
+ 0xBD, 0xF8, 0x53, 0x24, 0xAB, 0xD4, 0x2A, 0xB7, 0xEC, 0x3B, 0xF4, 0x6A, 0x56, 0x2E, 0xBF, 0xFC,
+ 0x7A, 0x57, 0x0D, 0x79, 0x70, 0x62, 0x46, 0x0E, 0x7F, 0x5D, 0x19, 0x91, 0xA0, 0xC2, 0x06, 0x8E,
+ 0x7F, 0x5D, 0x19, 0xB0, 0xE2, 0x46, 0xEF, 0x5C, 0x3A, 0xD7, 0x2C, 0xBB, 0xF4, 0x6A, 0x37, 0xCD,
+ 0x18, 0xB2, 0xC7, 0x0C, 0x9A, 0x97, 0x8D, 0x98, 0xB2, 0xC7, 0xED, 0x58, 0x13, 0x85, 0x69, 0x50,
+ 0x22, 0xA7, 0xCC, 0xFB, 0x55, 0x09, 0x90, 0xA2, 0xC6, 0x0E, 0x9E, 0x9F, 0xBC, 0xFA, 0x57, 0x2C,
+ 0xDA, 0x36, 0xCF, 0xFD, 0x78, 0x72, 0x47, 0xED, 0x39, 0xD1, 0x20, 0xC2, 0xE7, 0x4C, 0xFB, 0x74,
+ 0x6A, 0x56, 0x2E, 0xBF, 0xFC, 0x7A, 0x57, 0x0D, 0x98, 0xB2, 0xE6, 0x4E, 0x1E, 0x9F, 0x9D, 0xB8,
+ 0xD3, 0x24, 0xCA, 0xF7, 0x6C, 0x5A, 0x17, 0xAC, 0xBB, 0xF4, 0x4B, 0x14, 0x8B, 0x94, 0xAA, 0xB7,
+ 0xCD, 0xF9, 0x70, 0x62, 0x46, 0x0E, 0x9E, 0x9F, 0x9D, 0xB8, 0xF2, 0x47, 0xED, 0x39, 0xD1, 0x01,
+ 0x61, 0x40, 0xE3, 0x44, 0x0A, 0x96, 0x8F, 0x9C, 0xBA, 0xD7, 0x0D, 0x98, 0x93, 0x85, 0x69, 0x50,
+ 0x22, 0xA7, 0xCC, 0x1A, 0xB6, 0xEE, 0x5E, 0x3E, 0xFE, 0x7E, 0x7E, 0x7E, 0x5F, 0x3C, 0xFA, 0x57,
+ 0x0D, 0x79, 0x70, 0x62, 0x27, 0xCC, 0x1A, 0xB6, 0xCF, 0xFD, 0x78, 0x72, 0x66, 0x2F, 0xDC, 0x1B,
+ 0x95, 0xA8, 0xB3, 0xE4, 0x4A, 0xF7, 0x6C, 0x5A, 0x36, 0xEE, 0x3F, 0xFC, 0x7A, 0x57, 0x2C, 0xBB,
+ 0xD5, 0x09, 0x71, 0x41, 0xE1, 0x21, 0xC0, 0xE3, 0x44, 0x0A, 0x77, 0x6C, 0x3B, 0xD5, 0x09, 0x90,
+ 0x83, 0x84, 0x6B, 0x54, 0x0B, 0x94, 0x8B, 0x75, 0x49, 0xF1, 0x60, 0x42, 0xE7, 0x4C, 0x1A, 0xB6,
+ 0xEE, 0x3F, 0xFC, 0x5B, 0x15, 0xA8, 0xB3, 0xC5, 0xE9, 0x50, 0x22, 0xC6, 0x0E, 0x7F, 0x5D, 0x19,
+ 0xB0, 0xE2, 0x27, 0xAD, 0xB9, 0xD1, 0x01, 0x80, 0x63, 0x25, 0xC8, 0xF3, 0x64, 0x4A, 0x16, 0xAE,
+ 0xDE, 0x3E, 0xDF, 0x3C, 0xFA, 0x57, 0x0D, 0x79, 0x70, 0x43, 0x04, 0x6B, 0x54, 0x2A, 0xB7, 0xCD,
+ 0x18, 0x93, 0xA4, 0xAB, 0xD4, 0x2A, 0xD6, 0x0F, 0x7D, 0x78, 0x72, 0x47, 0x0C, 0x7B, 0x74, 0x6A,
+ 0x37, 0xEC, 0x5A, 0x17, 0xAC, 0xBB, 0xF4, 0x6A, 0x56, 0x0F, 0x7D, 0x78, 0x53, 0x05, 0x88, 0x73,
+ 0x64, 0x2B, 0xB5, 0xE8, 0x33, 0xC5, 0x08, 0x92, 0xA6, 0xAF, 0xDC, 0x1B, 0xB4, 0xEA, 0x56, 0x0F,
+ 0x9C, 0x9B, 0xB4, 0xCB, 0xF5, 0x68, 0x33, 0xE4, 0x2B, 0xB5, 0xE8, 0x33, 0xE4, 0x2B, 0xB5, 0xE8,
+ 0x52, 0x26, 0xAF, 0xDC, 0x3A, 0xF6, 0x6E, 0x5E, 0x1F, 0xBC, 0xFA, 0x76, 0x6E, 0x3F, 0xDD, 0x38,
+ 0xF2, 0x47, 0x0C, 0x7B, 0x74, 0x4B, 0x14, 0x8B, 0x94, 0xAA, 0xD6, 0x0F, 0x9C, 0x9B, 0xB4, 0xEA,
+ 0x56, 0x2E, 0xDE, 0x1F, 0x9D, 0x99, 0xB0, 0xE2, 0x27, 0xCC, 0x1A, 0xB6, 0xEE, 0x3F, 0xFC, 0x7A,
+ 0x57, 0x0D, 0x98, 0x93, 0xA4, 0xAB, 0xB5, 0xC9, 0xF1, 0x60, 0x7B, 0x17, 0xC8, 0x4A
+};
+
+const pmw3360_srom_t pmw3360_srom_0x81 = {
+ .data = srom_data_0x81,
+ .len = sizeof(srom_data_0x81),
+};
diff --git a/keyboards/yowkees/keyball39/.noci b/keyboards/yowkees/keyball39/.noci
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/keyboards/yowkees/keyball39/config.h b/keyboards/yowkees/keyball39/config.h
new file mode 100644
index 00000000000..83441bf6060
--- /dev/null
+++ b/keyboards/yowkees/keyball39/config.h
@@ -0,0 +1,79 @@
+/*
+Copyright 2022 @Yowkees
+Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#pragma once
+
+// Key matrix parameters
+#define MATRIX_ROWS (4 * 2) // split keyboard
+#define MATRIX_COLS 6
+#define MATRIX_ROW_PINS { F4, F5, F6, F7 }
+#define MATRIX_COL_PINS { D4, C6, D7, E6, B4, B5 }
+#define MATRIX_MASKED
+#define DEBOUNCE 5
+#define DIODE_DIRECTION COL2ROW
+
+// Split parameters
+#define SOFT_SERIAL_PIN D2
+#define SPLIT_HAND_MATRIX_GRID F6, B5
+#define SPLIT_USB_DETECT
+#ifdef OLED_ENABLE
+# define SPLIT_OLED_ENABLE
+#endif
+
+// If your PC does not recognize Keyball, try setting this macro. This macro
+// increases the firmware size by 200 bytes, so it is disabled by default, but
+// it has been reported to work well in such cases.
+//#define SPLIT_WATCHDOG_ENABLE
+
+#define SPLIT_TRANSACTION_IDS_KB KEYBALL_GET_INFO, KEYBALL_GET_MOTION, KEYBALL_SET_CPI
+
+// RGB LED settings
+#define WS2812_DI_PIN D3
+#ifdef RGBLIGHT_ENABLE
+# define RGBLED_NUM 48
+# define RGBLED_SPLIT { 24, 24 } // (24 + 22)
+# ifndef RGBLIGHT_LIMIT_VAL
+# define RGBLIGHT_LIMIT_VAL 150 // limitated for power consumption
+# endif
+# ifndef RGBLIGHT_VAL_STEP
+# define RGBLIGHT_VAL_STEP 15
+# endif
+# ifndef RGBLIGHT_HUE_STEP
+# define RGBLIGHT_HUE_STEP 17
+# endif
+# ifndef RGBLIGHT_SAT_STEP
+# define RGBLIGHT_SAT_STEP 17
+# endif
+#endif
+#ifdef RGB_MATRIX_ENABLE
+# define RGB_MATRIX_SPLIT { 24, 24 }
+#endif
+
+#ifndef OLED_FONT_H
+# define OLED_FONT_H "keyboards/keyball/lib/logofont/logofont.c"
+# define OLED_FONT_START 32
+# define OLED_FONT_END 195
+#endif
+
+#if !defined(LAYER_STATE_8BIT) && !defined(LAYER_STATE_16BIT) && !defined(LAYER_STATE_32BIT)
+# define LAYER_STATE_8BIT
+#endif
+
+// To squeeze firmware size
+#undef LOCKING_SUPPORT_ENABLE
+#undef LOCKING_RESYNC_ENABLE
diff --git a/keyboards/yowkees/keyball39/info.json b/keyboards/yowkees/keyball39/info.json
new file mode 100644
index 00000000000..163269d8466
--- /dev/null
+++ b/keyboards/yowkees/keyball39/info.json
@@ -0,0 +1,63 @@
+{
+ "usb": {
+ "vid": "0x5957",
+ "pid": "0x0200",
+ "device_version": "1.0.0"
+ },
+ "manufacturer": "Yowkees",
+ "keyboard_name": "Keyball39",
+ "rgblight": {
+ "driver": "ws2812"
+ },
+ "layouts": {
+ "LAYOUT_no_ball": {
+ "layout": [
+ { "label": "L00", "x": 0, "y": 0 },
+ { "label": "L01", "x": 1, "y": 0 },
+ { "label": "L02", "x": 2, "y": 0 },
+ { "label": "L03", "x": 3, "y": 0 },
+ { "label": "L04", "x": 4, "y": 0 },
+ { "label": "R04", "x": 7, "y": 0 },
+ { "label": "R03", "x": 8, "y": 0 },
+ { "label": "R02", "x": 9, "y": 0 },
+ { "label": "R01", "x":10, "y": 0 },
+ { "label": "R00", "x":11, "y": 0 },
+
+ { "label": "L10", "x": 0, "y": 1 },
+ { "label": "L11", "x": 1, "y": 1 },
+ { "label": "L12", "x": 2, "y": 1 },
+ { "label": "L13", "x": 3, "y": 1 },
+ { "label": "L14", "x": 4, "y": 1 },
+ { "label": "R14", "x": 7, "y": 1 },
+ { "label": "R13", "x": 8, "y": 1 },
+ { "label": "R12", "x": 9, "y": 1 },
+ { "label": "R11", "x":10, "y": 1 },
+ { "label": "R10", "x":11, "y": 1 },
+
+ { "label": "L20", "x": 0, "y": 2 },
+ { "label": "L21", "x": 1, "y": 2 },
+ { "label": "L22", "x": 2, "y": 2 },
+ { "label": "L23", "x": 3, "y": 2 },
+ { "label": "L24", "x": 4, "y": 2 },
+ { "label": "R24", "x": 7, "y": 2 },
+ { "label": "R23", "x": 8, "y": 2 },
+ { "label": "R22", "x": 9, "y": 2 },
+ { "label": "R21", "x":10, "y": 2 },
+ { "label": "R20", "x":11, "y": 2 },
+
+ { "label": "L30", "x": 0, "y": 3 },
+ { "label": "L31", "x": 1, "y": 3 },
+ { "label": "L32", "x": 2, "y": 3 },
+ { "label": "L33", "x": 3, "y": 3 },
+ { "label": "L34", "x": 4, "y": 3 },
+ { "label": "L35", "x": 5, "y": 3 },
+ { "label": "R35", "x": 6, "y": 3 },
+ { "label": "R34", "x": 7, "y": 3 },
+ { "label": "R33", "x": 8, "y": 3 },
+ { "label": "R32", "x": 9, "y": 3 },
+ { "label": "R31", "x":10, "y": 3 },
+ { "label": "R30", "x":11, "y": 3 }
+ ]
+ }
+ }
+}
diff --git a/keyboards/yowkees/keyball39/keyball39.c b/keyboards/yowkees/keyball39/keyball39.c
new file mode 100644
index 00000000000..5472a0d48ff
--- /dev/null
+++ b/keyboards/yowkees/keyball39/keyball39.c
@@ -0,0 +1,46 @@
+/*
+Copyright 2021 @Yowkees
+Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include QMK_KEYBOARD_H
+
+#include "lib/keyball/keyball.h"
+
+//////////////////////////////////////////////////////////////////////////////
+
+// clang-format off
+matrix_row_t matrix_mask[MATRIX_ROWS] = {
+ 0b00011111,
+ 0b00011111,
+ 0b00011111,
+ 0b00111111,
+ 0b00011111,
+ 0b00011111,
+ 0b00011111,
+ 0b00111111,
+};
+// clang-format on
+
+void keyball_on_adjust_layout(keyball_adjust_t v) {
+#ifdef RGBLIGHT_ENABLE
+ // adjust RGBLIGHT's clipping and effect ranges
+ uint8_t lednum_this = keyball.this_have_ball ? 22 : 24;
+ uint8_t lednum_that = !keyball.that_enable ? 0 : keyball.that_have_ball ? 22 : 24;
+ rgblight_set_clipping_range(is_keyboard_left() ? 0 : lednum_that, lednum_this);
+ rgblight_set_effect_range(0, lednum_this + lednum_that);
+#endif
+}
diff --git a/keyboards/yowkees/keyball39/keyball39.h b/keyboards/yowkees/keyball39/keyball39.h
new file mode 100644
index 00000000000..a2555e0b502
--- /dev/null
+++ b/keyboards/yowkees/keyball39/keyball39.h
@@ -0,0 +1,97 @@
+/*
+Copyright 2022 @Yowkees
+Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#pragma once
+
+#include "quantum.h"
+#include "lib/keyball/keyball.h"
+
+// clang-format off
+
+#define LAYOUT_right_ball( \
+ L00, L01, L02, L03, L04, R04, R03, R02, R01, R00, \
+ L10, L11, L12, L13, L14, R14, R13, R12, R11, R10, \
+ L20, L21, L22, L23, L24, R24, R23, R22, R21, R20, \
+ L30, L31, L32, L33, L34, L35, R35, R34, R30 \
+ ) \
+ { \
+ { L00, L01, L02, L03, L04, KC_NO }, \
+ { L10, L11, L12, L13, L14, KC_NO }, \
+ { L20, L21, L22, L23, L24, KC_NO }, \
+ { L30, L31, L32, L33, L34, L35 }, \
+ { R00, R01, R02, R03, R04, KC_NO }, \
+ { R10, R11, R12, R13, R14, KC_NO }, \
+ { R20, R21, R22, R23, R24, KC_NO }, \
+ { R30, KC_NO, KC_NO, KC_NO, R34, R35 }, \
+ }
+
+#define LAYOUT_left_ball( \
+ L00, L01, L02, L03, L04, R04, R03, R02, R01, R00, \
+ L10, L11, L12, L13, L14, R14, R13, R12, R11, R10, \
+ L20, L21, L22, L23, L24, R24, R23, R22, R21, R20, \
+ L30, L34, L35, R35, R34, R33, R32, R31, R30 \
+ ) \
+ { \
+ { L00, L01, L02, L03, L04, KC_NO }, \
+ { L10, L11, L12, L13, L14, KC_NO }, \
+ { L20, L21, L22, L23, L24, KC_NO }, \
+ { L30, KC_NO, KC_NO, KC_NO, L34, L35 }, \
+ { R00, R01, R02, R03, R04, KC_NO }, \
+ { R10, R11, R12, R13, R14, KC_NO }, \
+ { R20, R21, R22, R23, R24, KC_NO }, \
+ { R30, R31, R32, R33, R34, R35 }, \
+ }
+
+#define LAYOUT_dual_ball( \
+ L00, L01, L02, L03, L04, R04, R03, R02, R01, R00, \
+ L10, L11, L12, L13, L14, R14, R13, R12, R11, R10, \
+ L20, L21, L22, L23, L24, R24, R23, R22, R21, R20, \
+ L30, L34, L35, R35, R34, R30 \
+ ) \
+ { \
+ { L00, L01, L02, L03, L04, KC_NO }, \
+ { L10, L11, L12, L13, L14, KC_NO }, \
+ { L20, L21, L22, L23, L24, KC_NO }, \
+ { L30, KC_NO, KC_NO, KC_NO, L34, L35 }, \
+ { R00, R01, R02, R03, R04, KC_NO }, \
+ { R10, R11, R12, R13, R14, KC_NO }, \
+ { R20, R21, R22, R23, R24, KC_NO }, \
+ { R30, KC_NO, KC_NO, KC_NO, R34, R35 }, \
+ }
+
+#define LAYOUT_no_ball( \
+ L00, L01, L02, L03, L04, R04, R03, R02, R01, R00, \
+ L10, L11, L12, L13, L14, R14, R13, R12, R11, R10, \
+ L20, L21, L22, L23, L24, R24, R23, R22, R21, R20, \
+ L30, L31, L32, L33, L34, L35, R35, R34, R33, R32, R31, R30 \
+ ) \
+ { \
+ { L00, L01, L02, L03, L04, KC_NO }, \
+ { L10, L11, L12, L13, L14, KC_NO }, \
+ { L20, L21, L22, L23, L24, KC_NO }, \
+ { L30, L31, L32, L33, L34, L35 }, \
+ { R00, R01, R02, R03, R04, KC_NO }, \
+ { R10, R11, R12, R13, R14, KC_NO }, \
+ { R20, R21, R22, R23, R24, KC_NO }, \
+ { R30, R31, R32, R33, R34, R35 }, \
+ }
+
+// clang-format on
+
+#define LAYOUT LAYOUT_right_ball
+#define LAYOUT_universal LAYOUT_no_ball
diff --git a/keyboards/yowkees/keyball39/keymaps/default/config.h b/keyboards/yowkees/keyball39/keymaps/default/config.h
new file mode 100644
index 00000000000..ec062cf45e0
--- /dev/null
+++ b/keyboards/yowkees/keyball39/keymaps/default/config.h
@@ -0,0 +1,39 @@
+/*
+This is the c configuration file for the keymap
+
+Copyright 2022 @Yowkees
+Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#pragma once
+
+#ifdef RGBLIGHT_ENABLE
+# define RGBLIGHT_EFFECT_BREATHING
+# define RGBLIGHT_EFFECT_RAINBOW_MOOD
+# define RGBLIGHT_EFFECT_RAINBOW_SWIRL
+# define RGBLIGHT_EFFECT_SNAKE
+# define RGBLIGHT_EFFECT_KNIGHT
+# define RGBLIGHT_EFFECT_CHRISTMAS
+# define RGBLIGHT_EFFECT_STATIC_GRADIENT
+# define RGBLIGHT_EFFECT_RGB_TEST
+# define RGBLIGHT_EFFECT_ALTERNATING
+# define RGBLIGHT_EFFECT_TWINKLE
+#endif
+
+#define TAP_CODE_DELAY 5
+
+#define POINTING_DEVICE_AUTO_MOUSE_ENABLE
+#define AUTO_MOUSE_DEFAULT_LAYER 1
diff --git a/keyboards/yowkees/keyball39/keymaps/default/keymap.c b/keyboards/yowkees/keyball39/keymaps/default/keymap.c
new file mode 100644
index 00000000000..ebc39675860
--- /dev/null
+++ b/keyboards/yowkees/keyball39/keymaps/default/keymap.c
@@ -0,0 +1,71 @@
+/*
+Copyright 2022 @Yowkees
+Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include QMK_KEYBOARD_H
+
+#include "quantum.h"
+
+// clang-format off
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ // keymap for default
+ [0] = LAYOUT_universal(
+ KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P ,
+ KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_MINS ,
+ KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM , KC_DOT , KC_SLSH ,
+ KC_LCTL , KC_LGUI , KC_LALT ,LSFT_T(KC_LNG2),LT(1,KC_SPC),LT(3,KC_LNG1),KC_BSPC,LT(2,KC_ENT),LSFT_T(KC_LNG2),KC_RALT,KC_RGUI, KC_RSFT
+ ),
+
+ [1] = LAYOUT_universal(
+ KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_RBRC , KC_F6 , KC_F7 , KC_F8 , KC_F9 , KC_F10 ,
+ KC_F5 , KC_EXLM , S(KC_6) ,S(KC_INT3), S(KC_8) , S(KC_INT1), KC_BTN1 , KC_PGUP , KC_BTN2 , KC_SCLN ,
+ S(KC_EQL),S(KC_LBRC),S(KC_7) , S(KC_2) ,S(KC_RBRC), KC_LBRC , KC_DLR , KC_PGDN , KC_BTN3 , KC_F11 ,
+ KC_INT1 , KC_EQL , S(KC_3) , _______ , _______ , _______ , TO(2) , TO(0) , _______ , KC_RALT , KC_RGUI , KC_F12
+ ),
+
+ [2] = LAYOUT_universal(
+ KC_TAB , KC_7 , KC_8 , KC_9 , KC_MINS , KC_NUHS , _______ , KC_BTN3 , _______ , KC_BSPC ,
+ S(KC_QUOT), KC_4 , KC_5 , KC_6 ,S(KC_SCLN), S(KC_9) , KC_BTN1 , KC_UP , KC_BTN2 , KC_QUOT ,
+ KC_SLSH , KC_1 , KC_2 , KC_3 ,S(KC_MINS), S(KC_NUHS), KC_LEFT , KC_DOWN , KC_RGHT , _______ ,
+ KC_ESC , KC_0 , KC_DOT , KC_DEL , KC_ENT , KC_BSPC , _______ , _______ , _______ , _______ , _______ , _______
+ ),
+
+ [3] = LAYOUT_universal(
+ RGB_TOG , AML_TO , AML_I50 , AML_D50 , _______ , _______ , _______ , SSNP_HOR , SSNP_VRT , SSNP_FRE ,
+ RGB_MOD , RGB_HUI , RGB_SAI , RGB_VAI , SCRL_DVI , _______ , _______ , _______ , _______ , _______ ,
+ RGB_RMOD , RGB_HUD , RGB_SAD , RGB_VAD , SCRL_DVD , CPI_D1K , CPI_D100 , CPI_I100 , CPI_I1K , KBC_SAVE ,
+ QK_BOOT , KBC_RST , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , KBC_RST , QK_BOOT
+ ),
+};
+// clang-format on
+
+layer_state_t layer_state_set_user(layer_state_t state) {
+ // Auto enable scroll mode when the highest layer is 3
+ keyball_set_scroll_mode(get_highest_layer(state) == 3);
+ return state;
+}
+
+#ifdef OLED_ENABLE
+
+# include "lib/oledkit/oledkit.h"
+
+void oledkit_render_info_user(void) {
+ keyball_oled_render_keyinfo();
+ keyball_oled_render_ballinfo();
+ keyball_oled_render_layerinfo();
+}
+#endif
diff --git a/keyboards/yowkees/keyball39/keymaps/default/rules.mk b/keyboards/yowkees/keyball39/keymaps/default/rules.mk
new file mode 100644
index 00000000000..5746ccd2854
--- /dev/null
+++ b/keyboards/yowkees/keyball39/keymaps/default/rules.mk
@@ -0,0 +1,3 @@
+RGBLIGHT_ENABLE = yes
+
+OLED_ENABLE = yes
diff --git a/keyboards/yowkees/keyball39/keymaps/develop/config.h b/keyboards/yowkees/keyball39/keymaps/develop/config.h
new file mode 100644
index 00000000000..7c18d0969f7
--- /dev/null
+++ b/keyboards/yowkees/keyball39/keymaps/develop/config.h
@@ -0,0 +1,33 @@
+/*
+This is the c configuration file for the keymap
+
+Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#pragma once
+
+#ifdef RGBLIGHT_ENABLE
+# define RGBLIGHT_EFFECT_BREATHING
+# define RGBLIGHT_EFFECT_RAINBOW_MOOD
+# define RGBLIGHT_EFFECT_RAINBOW_SWIRL
+# define RGBLIGHT_EFFECT_SNAKE
+# define RGBLIGHT_EFFECT_KNIGHT
+# define RGBLIGHT_EFFECT_CHRISTMAS
+# define RGBLIGHT_EFFECT_STATIC_GRADIENT
+# define RGBLIGHT_EFFECT_RGB_TEST
+# define RGBLIGHT_EFFECT_ALTERNATING
+# define RGBLIGHT_EFFECT_TWINKLE
+#endif
diff --git a/keyboards/yowkees/keyball39/keymaps/develop/keymap.c b/keyboards/yowkees/keyball39/keymaps/develop/keymap.c
new file mode 100644
index 00000000000..dca2006c475
--- /dev/null
+++ b/keyboards/yowkees/keyball39/keymaps/develop/keymap.c
@@ -0,0 +1,51 @@
+/*
+Copyright 2022 @Yowkees
+Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include QMK_KEYBOARD_H
+
+#include "quantum.h"
+
+// clang-format off
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ // keymap for development
+ [0] = LAYOUT_universal(
+ KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P ,
+ KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_SCLN ,
+ KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM , KC_DOT , KC_SLSH ,
+ KC_LCTL , KC_LGUI , KC_LALT , SCRL_MO , KC_SPC ,LT(1,KC_TAB),LT(1,KC_BSPC), KC_ENT , SCRL_MO , KC_RALT , KC_RGUI , KC_RSFT
+ ),
+
+ [1] = LAYOUT_universal(
+ RGB_TOG , _______ , _______ , _______ , _______ , RGB_M_P , RGB_M_B , RGB_M_R , RGB_M_SW , RGB_M_SN ,
+ RGB_MOD , RGB_HUI , RGB_SAI , RGB_VAI , SCRL_DVI , RGB_M_K , RGB_M_X , RGB_M_G , RGB_M_T , RGB_M_TW ,
+ RGB_RMOD , RGB_HUD , RGB_SAD , RGB_VAD , SCRL_DVD , CPI_D1K , CPI_D100 , CPI_I100 , CPI_I1K , KBC_SAVE ,
+ QK_BOOT , KBC_RST , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , KBC_RST , QK_BOOT
+ ),
+};
+// clang-format on
+
+#ifdef OLED_ENABLE
+
+# include "lib/oledkit/oledkit.h"
+
+void oledkit_render_info_user(void) {
+ keyball_oled_render_keyinfo();
+ keyball_oled_render_ballinfo();
+ keyball_oled_render_layerinfo();
+}
+#endif
diff --git a/keyboards/yowkees/keyball39/keymaps/develop/rules.mk b/keyboards/yowkees/keyball39/keymaps/develop/rules.mk
new file mode 100644
index 00000000000..98615de5f51
--- /dev/null
+++ b/keyboards/yowkees/keyball39/keymaps/develop/rules.mk
@@ -0,0 +1,6 @@
+RGBLIGHT_ENABLE = yes
+
+OLED_ENABLE = yes
+
+# for debug
+#CONSOLE_ENABLE = yes
diff --git a/keyboards/yowkees/keyball39/keymaps/test/config.h b/keyboards/yowkees/keyball39/keymaps/test/config.h
new file mode 100644
index 00000000000..b8849eed0cc
--- /dev/null
+++ b/keyboards/yowkees/keyball39/keymaps/test/config.h
@@ -0,0 +1,25 @@
+/*
+This is the c configuration file for the keymap
+
+Copyright 2022 @Yowkees
+Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#pragma once
+
+#ifdef RGBLIGHT_ENABLE
+# define RGBLIGHT_EFFECT_RGB_TEST // required for LED test
+#endif
diff --git a/keyboards/yowkees/keyball39/keymaps/test/keymap.c b/keyboards/yowkees/keyball39/keymaps/test/keymap.c
new file mode 100644
index 00000000000..beb81aa4574
--- /dev/null
+++ b/keyboards/yowkees/keyball39/keymaps/test/keymap.c
@@ -0,0 +1,51 @@
+/*
+Copyright 2022 @Yowkees
+Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include QMK_KEYBOARD_H
+
+#include "quantum.h"
+
+// clang-format off
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [0] = LAYOUT_universal(
+ KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P ,
+ KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_SCLN ,
+ KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM , KC_DOT , KC_SLSH ,
+ KC_LCTL , KC_LGUI , KC_LALT , KC_ESC , KC_SPC , KC_TAB , KC_BSPC , KC_ENT , KC_ESC , KC_RALT , KC_RGUI , KC_RSFT
+ ),
+};
+// clang-format on
+
+void keyboard_post_init_user() {
+#ifdef RGBLIGHT_ENABLE
+ // Force RGB lights to show test animation without writing EEPROM.
+ rgblight_enable_noeeprom();
+ rgblight_mode_noeeprom(RGBLIGHT_MODE_RGB_TEST);
+#endif
+}
+
+#ifdef OLED_ENABLE
+
+# include "lib/oledkit/oledkit.h"
+
+void oledkit_render_info_user(void) {
+ keyball_oled_render_keyinfo();
+ keyball_oled_render_ballinfo();
+ keyball_oled_render_layerinfo();
+}
+#endif
diff --git a/keyboards/yowkees/keyball39/keymaps/test/rules.mk b/keyboards/yowkees/keyball39/keymaps/test/rules.mk
new file mode 100644
index 00000000000..98615de5f51
--- /dev/null
+++ b/keyboards/yowkees/keyball39/keymaps/test/rules.mk
@@ -0,0 +1,6 @@
+RGBLIGHT_ENABLE = yes
+
+OLED_ENABLE = yes
+
+# for debug
+#CONSOLE_ENABLE = yes
diff --git a/keyboards/yowkees/keyball39/keymaps/via/config.h b/keyboards/yowkees/keyball39/keymaps/via/config.h
new file mode 100644
index 00000000000..9736eae89c7
--- /dev/null
+++ b/keyboards/yowkees/keyball39/keymaps/via/config.h
@@ -0,0 +1,39 @@
+/*
+This is the c configuration file for the keymap
+
+Copyright 2022 @Yowkees
+Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#pragma once
+
+#ifdef RGBLIGHT_ENABLE
+//# define RGBLIGHT_EFFECT_BREATHING
+//# define RGBLIGHT_EFFECT_RAINBOW_MOOD
+//# define RGBLIGHT_EFFECT_RAINBOW_SWIRL
+//# define RGBLIGHT_EFFECT_SNAKE
+//# define RGBLIGHT_EFFECT_KNIGHT
+//# define RGBLIGHT_EFFECT_CHRISTMAS
+# define RGBLIGHT_EFFECT_STATIC_GRADIENT
+//# define RGBLIGHT_EFFECT_RGB_TEST
+//# define RGBLIGHT_EFFECT_ALTERNATING
+//# define RGBLIGHT_EFFECT_TWINKLE
+#endif
+
+#define TAP_CODE_DELAY 5
+
+#define POINTING_DEVICE_AUTO_MOUSE_ENABLE
+#define AUTO_MOUSE_DEFAULT_LAYER 1
diff --git a/keyboards/yowkees/keyball39/keymaps/via/keymap.c b/keyboards/yowkees/keyball39/keymaps/via/keymap.c
new file mode 100644
index 00000000000..b3addae35a0
--- /dev/null
+++ b/keyboards/yowkees/keyball39/keymaps/via/keymap.c
@@ -0,0 +1,71 @@
+/*
+Copyright 2022 @Yowkees
+Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include QMK_KEYBOARD_H
+
+#include "quantum.h"
+
+// clang-format off
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ // keymap for default (VIA)
+ [0] = LAYOUT_universal(
+ KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P ,
+ KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_MINS ,
+ KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM , KC_DOT , KC_SLSH ,
+ KC_LCTL , KC_LGUI , KC_LALT ,LSFT_T(KC_LNG2),LT(1,KC_SPC),LT(3,KC_LNG1),KC_BSPC,LT(2,KC_ENT),LSFT_T(KC_LNG2),KC_RALT,KC_RGUI, KC_RSFT
+ ),
+
+ [1] = LAYOUT_universal(
+ KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_RBRC , KC_F6 , KC_F7 , KC_F8 , KC_F9 , KC_F10 ,
+ KC_F5 , KC_EXLM , S(KC_6) ,S(KC_INT3), S(KC_8) , S(KC_INT1), KC_BTN1 , KC_PGUP , KC_BTN2 , KC_SCLN ,
+ S(KC_EQL),S(KC_LBRC),S(KC_7) , S(KC_2) ,S(KC_RBRC), KC_LBRC , KC_DLR , KC_PGDN , KC_BTN3 , KC_F11 ,
+ KC_INT1 , KC_EQL , S(KC_3) , _______ , _______ , _______ , TO(2) , TO(0) , _______ , KC_RALT , KC_RGUI , KC_F12
+ ),
+
+ [2] = LAYOUT_universal(
+ KC_TAB , KC_7 , KC_8 , KC_9 , KC_MINS , KC_NUHS , _______ , KC_BTN3 , _______ , KC_BSPC ,
+ S(KC_QUOT), KC_4 , KC_5 , KC_6 ,S(KC_SCLN), S(KC_9) , KC_BTN1 , KC_UP , KC_BTN2 , KC_QUOT ,
+ KC_SLSH , KC_1 , KC_2 , KC_3 ,S(KC_MINS), S(KC_NUHS), KC_LEFT , KC_DOWN , KC_RGHT , _______ ,
+ KC_ESC , KC_0 , KC_DOT , KC_DEL , KC_ENT , KC_BSPC , _______ , _______ , _______ , _______ , _______ , _______
+ ),
+
+ [3] = LAYOUT_universal(
+ RGB_TOG , AML_TO , AML_I50 , AML_D50 , _______ , _______ , _______ , SSNP_HOR , SSNP_VRT , SSNP_FRE ,
+ RGB_MOD , RGB_HUI , RGB_SAI , RGB_VAI , SCRL_DVI , _______ , _______ , _______ , _______ , _______ ,
+ RGB_RMOD , RGB_HUD , RGB_SAD , RGB_VAD , SCRL_DVD , CPI_D1K , CPI_D100 , CPI_I100 , CPI_I1K , KBC_SAVE ,
+ QK_BOOT , KBC_RST , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , KBC_RST , QK_BOOT
+ ),
+};
+// clang-format on
+
+layer_state_t layer_state_set_user(layer_state_t state) {
+ // Auto enable scroll mode when the highest layer is 3
+ keyball_set_scroll_mode(get_highest_layer(state) == 3);
+ return state;
+}
+
+#ifdef OLED_ENABLE
+
+# include "lib/oledkit/oledkit.h"
+
+void oledkit_render_info_user(void) {
+ keyball_oled_render_keyinfo();
+ keyball_oled_render_ballinfo();
+ keyball_oled_render_layerinfo();
+}
+#endif
diff --git a/keyboards/yowkees/keyball39/keymaps/via/rules.mk b/keyboards/yowkees/keyball39/keymaps/via/rules.mk
new file mode 100644
index 00000000000..d80df3fa49a
--- /dev/null
+++ b/keyboards/yowkees/keyball39/keymaps/via/rules.mk
@@ -0,0 +1,5 @@
+RGBLIGHT_ENABLE = yes
+
+OLED_ENABLE = yes
+
+VIA_ENABLE = yes
diff --git a/keyboards/yowkees/keyball39/readme.md b/keyboards/yowkees/keyball39/readme.md
new file mode 100644
index 00000000000..6076b3f2917
--- /dev/null
+++ b/keyboards/yowkees/keyball39/readme.md
@@ -0,0 +1,21 @@
+# Keyball39
+
+![Keyball39](../../../../keyball39/doc/rev1/images/kb39_001.jpg)
+
+A split keyboard with 39 vertically staggered keys and 34mm track ball.
+
+* Keyboard Maintainer: [@Yowkees](https://twitter.com/Yowkees)
+* Hardware Supported: Keyball39 PCB, ProMicro
+* Hardware Availability:
+ *
+ *
+
+Make example for this keyboard (after setting up your build environment):
+
+ make keyball/keyball39:default
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+## Special keycodes
+
+See [Special Keycode](../lib/keyball/keycodes.md) file.
diff --git a/keyboards/yowkees/keyball39/rules.mk b/keyboards/yowkees/keyball39/rules.mk
new file mode 100644
index 00000000000..0dfde5b3dd9
--- /dev/null
+++ b/keyboards/yowkees/keyball39/rules.mk
@@ -0,0 +1,49 @@
+# MCU name
+MCU = atmega32u4
+
+# Bootloader selection
+BOOTLOADER = caterina
+
+# Link Time Optimization required for size.
+LTO_ENABLE = yes
+
+# Build Options
+BOOTMAGIC_ENABLE = no # Enable Bootmagic Lite
+EXTRAKEY_ENABLE = no # Audio control and System control
+CONSOLE_ENABLE = no # Console for debug
+COMMAND_ENABLE = no # Commands for debug and configuration
+NKRO_ENABLE = no # Enable N-Key Rollover
+BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
+AUDIO_ENABLE = no # Audio output
+
+# Keyball39 is split keyboard.
+SPLIT_KEYBOARD = yes
+
+# Optical sensor driver for trackball.
+POINTING_DEVICE_ENABLE = yes
+POINTING_DEVICE_DRIVER = custom
+SRC += drivers/pmw3360/pmw3360.c
+QUANTUM_LIB_SRC += spi_master.c # Optical sensor use SPI to communicate
+
+# This is unnecessary for processing KC_MS_BTN*.
+MOUSEKEY_ENABLE = no
+
+# Enabled only one of RGBLIGHT and RGB_MATRIX if necessary.
+RGBLIGHT_ENABLE = no # Enable RGBLIGHT
+RGB_MATRIX_ENABLE = no # Enable RGB_MATRIX (not work yet)
+RGB_MATRIX_DRIVER = ws2812
+
+# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
+SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
+
+# To support OLED
+OLED_ENABLE = no # Please Enable this in each keymaps.
+SRC += lib/oledkit/oledkit.c # OLED utility for Keyball series.
+
+# Include common library
+SRC += lib/keyball/keyball.c
+
+# Disable other features to squeeze firmware size
+SPACE_CADET_ENABLE = no
+GRAVE_ESC_ENABLE = no
+MAGIC_ENABLE = no
diff --git a/keyboards/yowkees/lib/duplexmatrix/duplexmatrix.c b/keyboards/yowkees/lib/duplexmatrix/duplexmatrix.c
new file mode 100644
index 00000000000..97fa4217532
--- /dev/null
+++ b/keyboards/yowkees/lib/duplexmatrix/duplexmatrix.c
@@ -0,0 +1,177 @@
+/*
+Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include
+#include "quantum.h"
+#include "matrix.h"
+#include "debounce.h"
+
+#ifdef SPLIT_KEYBOARD
+# include "split_common/split_util.h"
+# include "split_common/transactions.h"
+#endif
+
+#ifdef SPLIT_KEYBOARD
+# define PINNUM_ROW (MATRIX_ROWS / 2)
+# define ROWS_PER_HAND (MATRIX_ROWS / 2)
+#else
+# define PINNUM_ROW (MATRIX_ROWS)
+# define ROWS_PER_HAND (MATRIX_ROWS)
+#endif
+#define PINNUM_COL (MATRIX_COLS / 2)
+
+#define MATRIXSIZE_PER_HAND (ROWS_PER_HAND * sizeof(matrix_row_t))
+
+static pin_t row_pins[PINNUM_ROW] = MATRIX_ROW_PINS;
+static pin_t col_pins[PINNUM_COL] = MATRIX_COL_PINS;
+
+static inline void set_pin_input(pin_t pin) {
+ setPinInputHigh(pin);
+}
+
+static void set_pins_input(pin_t* pins, uint8_t n) {
+ for (uint8_t i = 0; i < n; i++) {
+ set_pin_input(pins[i]);
+ }
+}
+
+static inline void set_pin_output(pin_t pin) {
+ setPinOutput(pin);
+ writePinLow(pin);
+}
+
+static inline bool get_pin(pin_t pin) {
+ return readPin(pin);
+}
+
+__attribute__((weak)) void duplex_scan_raw_post_kb(matrix_row_t out_matrix[]) {}
+
+static void duplex_scan_raw(matrix_row_t out_matrix[]) {
+ // scan column to row
+ for (uint8_t row = 0; row < PINNUM_ROW; row++) {
+ set_pin_output(row_pins[row]);
+ matrix_output_select_delay();
+ for (uint8_t col = 0; col < PINNUM_COL; col++) {
+ if (!get_pin(col_pins[col])) {
+ out_matrix[row] |= 1 << col;
+ }
+ }
+ set_pin_input(row_pins[row]);
+ matrix_output_unselect_delay(row, false);
+ }
+
+ // scan row to column.
+ for (uint8_t col = 0; col < PINNUM_COL; col++) {
+ set_pin_output(col_pins[col]);
+ matrix_output_select_delay();
+ matrix_row_t shifter = ((matrix_row_t)1) << (col + PINNUM_COL);
+ for (uint8_t row = 0; row < PINNUM_ROW; row++) {
+ if (!get_pin(row_pins[row])) {
+ out_matrix[row] |= shifter;
+ }
+ }
+ set_pin_input(col_pins[col]);
+ matrix_output_unselect_delay(col, false);
+ }
+
+ duplex_scan_raw_post_kb(out_matrix);
+}
+
+static bool duplex_scan(matrix_row_t current_matrix[]) {
+ bool changed = false;
+ matrix_row_t tmp[MATRIX_ROWS] = {0};
+
+ duplex_scan_raw(tmp);
+ for (uint8_t row = 0; row < PINNUM_ROW; row++) {
+ if (tmp[row] != current_matrix[row]) {
+ changed = true;
+ current_matrix[row] = tmp[row];
+ }
+ }
+ return changed;
+}
+
+#ifdef SPLIT_KEYBOARD
+static uint8_t thisHand, thatHand;
+#else
+# define thisHand 0
+#endif
+
+void matrix_init_custom(void) {
+#ifdef SPLIT_KEYBOARD
+ split_pre_init();
+#endif
+
+ set_pins_input(col_pins, PINNUM_COL);
+ set_pins_input(row_pins, PINNUM_ROW);
+
+#ifdef SPLIT_KEYBOARD
+ thisHand = isLeftHand ? 0 : ROWS_PER_HAND;
+ thatHand = ROWS_PER_HAND - thisHand;
+
+ split_post_init();
+#endif
+}
+
+#ifdef SPLIT_KEYBOARD
+
+// user-defined overridable functions
+__attribute__((weak)) void matrix_slave_scan_kb(void) {
+ matrix_slave_scan_user();
+}
+
+__attribute__((weak)) void matrix_slave_scan_user(void) {}
+
+#endif
+
+// declare matrix buffers which defined in quantum/matrix_common.c
+extern matrix_row_t raw_matrix[MATRIX_ROWS];
+extern matrix_row_t matrix[MATRIX_ROWS];
+
+uint8_t matrix_scan(void) {
+ bool changed = duplex_scan(raw_matrix);
+
+ debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed);
+
+#ifdef SPLIT_KEYBOARD
+ if (!is_keyboard_master()) {
+ // send to primary.
+ transport_slave(matrix + thatHand, matrix + thisHand);
+ matrix_slave_scan_kb();
+ return changed;
+ }
+
+ // receive from secondary.
+ static bool last_connected = false;
+ matrix_row_t* that_raw = raw_matrix + ROWS_PER_HAND;
+ memset(that_raw, 0, MATRIXSIZE_PER_HAND);
+ if (transport_master_if_connected(matrix + thisHand, that_raw)) {
+ last_connected = true;
+ if (memcmp(matrix + thatHand, that_raw, MATRIXSIZE_PER_HAND) != 0) {
+ memcpy(matrix + thatHand, that_raw, MATRIXSIZE_PER_HAND);
+ changed = true;
+ }
+ } else if (last_connected) {
+ last_connected = false;
+ memset(matrix + thatHand, 0, MATRIXSIZE_PER_HAND);
+ changed = true;
+ }
+#endif
+
+ matrix_scan_kb();
+ return changed;
+}
diff --git a/keyboards/yowkees/lib/duplexmatrix/duplexmatrix.h b/keyboards/yowkees/lib/duplexmatrix/duplexmatrix.h
new file mode 100644
index 00000000000..44f57c629aa
--- /dev/null
+++ b/keyboards/yowkees/lib/duplexmatrix/duplexmatrix.h
@@ -0,0 +1,20 @@
+/*
+Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#pragma once
+
+void duplex_scan_raw_post_kb(matrix_row_t out_matrix[]);
diff --git a/keyboards/yowkees/lib/glcdfont.c b/keyboards/yowkees/lib/glcdfont.c
new file mode 100644
index 00000000000..c634898aed1
--- /dev/null
+++ b/keyboards/yowkees/lib/glcdfont.c
@@ -0,0 +1,234 @@
+// This is the 'classic' fixed-space bitmap font for Adafruit_GFX since 1.0.
+// See gfxfont.h for newer custom bitmap font info.
+
+#include "progmem.h"
+
+// Standard ASCII 5x7 font
+// clang-format off
+const unsigned char font[] PROGMEM = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00,
+ 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00,
+ 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00,
+ 0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x00,
+ 0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x00,
+ 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00,
+ 0x00, 0x18, 0x3C, 0x18, 0x00, 0x00,
+ 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00,
+ 0x00, 0x18, 0x24, 0x18, 0x00, 0x00,
+ 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x00,
+ 0x30, 0x48, 0x3A, 0x06, 0x0E, 0x00,
+ 0x26, 0x29, 0x79, 0x29, 0x26, 0x00,
+ 0x40, 0x7F, 0x05, 0x05, 0x07, 0x00,
+ 0x40, 0x7F, 0x05, 0x25, 0x3F, 0x00,
+ 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x00,
+ 0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x00,
+ 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x00,
+ 0x14, 0x22, 0x7F, 0x22, 0x14, 0x00,
+ 0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x00,
+ 0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00,
+ 0x00, 0x66, 0x89, 0x95, 0x6A, 0x00,
+ 0x60, 0x60, 0x60, 0x60, 0x60, 0x00,
+ 0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x00,
+ 0x08, 0x04, 0x7E, 0x04, 0x08, 0x00,
+ 0x10, 0x20, 0x7E, 0x20, 0x10, 0x00,
+ 0x08, 0x08, 0x2A, 0x1C, 0x08, 0x00,
+ 0x08, 0x1C, 0x2A, 0x08, 0x08, 0x00,
+ 0x1E, 0x10, 0x10, 0x10, 0x10, 0x00,
+ 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x00,
+ 0x30, 0x38, 0x3E, 0x38, 0x30, 0x00,
+ 0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00,
+ 0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
+ 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00,
+ 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00,
+ 0x23, 0x13, 0x08, 0x64, 0x62, 0x00,
+ 0x36, 0x49, 0x56, 0x20, 0x50, 0x00,
+ 0x00, 0x08, 0x07, 0x03, 0x00, 0x00,
+ 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00,
+ 0x00, 0x41, 0x22, 0x1C, 0x00, 0x00,
+ 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00,
+ 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00,
+ 0x00, 0x80, 0x70, 0x30, 0x00, 0x00,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
+ 0x00, 0x00, 0x60, 0x60, 0x00, 0x00,
+ 0x20, 0x10, 0x08, 0x04, 0x02, 0x00,
+ 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00,
+ 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00,
+ 0x72, 0x49, 0x49, 0x49, 0x46, 0x00,
+ 0x21, 0x41, 0x49, 0x4D, 0x33, 0x00,
+ 0x18, 0x14, 0x12, 0x7F, 0x10, 0x00,
+ 0x27, 0x45, 0x45, 0x45, 0x39, 0x00,
+ 0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00,
+ 0x41, 0x21, 0x11, 0x09, 0x07, 0x00,
+ 0x36, 0x49, 0x49, 0x49, 0x36, 0x00,
+ 0x46, 0x49, 0x49, 0x29, 0x1E, 0x00,
+ 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x00, 0x40, 0x34, 0x00, 0x00, 0x00,
+ 0x00, 0x08, 0x14, 0x22, 0x41, 0x00,
+ 0x14, 0x14, 0x14, 0x14, 0x14, 0x00,
+ 0x00, 0x41, 0x22, 0x14, 0x08, 0x00,
+ 0x02, 0x01, 0x59, 0x09, 0x06, 0x00,
+ 0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00,
+ 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00,
+ 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00,
+ 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00,
+ 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00,
+ 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00,
+ 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00,
+ 0x3E, 0x41, 0x41, 0x51, 0x73, 0x00,
+ 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00,
+ 0x00, 0x41, 0x7F, 0x41, 0x00, 0x00,
+ 0x20, 0x40, 0x41, 0x3F, 0x01, 0x00,
+ 0x7F, 0x08, 0x14, 0x22, 0x41, 0x00,
+ 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00,
+ 0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00,
+ 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00,
+ 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00,
+ 0x7F, 0x09, 0x09, 0x09, 0x06, 0x00,
+ 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00,
+ 0x7F, 0x09, 0x19, 0x29, 0x46, 0x00,
+ 0x26, 0x49, 0x49, 0x49, 0x32, 0x00,
+ 0x03, 0x01, 0x7F, 0x01, 0x03, 0x00,
+ 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00,
+ 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00,
+ 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00,
+ 0x63, 0x14, 0x08, 0x14, 0x63, 0x00,
+ 0x03, 0x04, 0x78, 0x04, 0x03, 0x00,
+ 0x61, 0x59, 0x49, 0x4D, 0x43, 0x00,
+ 0x00, 0x7F, 0x41, 0x41, 0x41, 0x00,
+ 0x02, 0x04, 0x08, 0x10, 0x20, 0x00,
+ 0x00, 0x41, 0x41, 0x41, 0x7F, 0x00,
+ 0x04, 0x02, 0x01, 0x02, 0x04, 0x00,
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00,
+ 0x00, 0x03, 0x07, 0x08, 0x00, 0x00,
+ 0x20, 0x54, 0x54, 0x78, 0x40, 0x00,
+ 0x7F, 0x28, 0x44, 0x44, 0x38, 0x00,
+ 0x38, 0x44, 0x44, 0x44, 0x28, 0x00,
+ 0x38, 0x44, 0x44, 0x28, 0x7F, 0x00,
+ 0x38, 0x54, 0x54, 0x54, 0x18, 0x00,
+ 0x00, 0x08, 0x7E, 0x09, 0x02, 0x00,
+ 0x18, 0x24, 0x24, 0x1C, 0x78, 0x00,
+ 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00,
+ 0x00, 0x44, 0x7D, 0x40, 0x00, 0x00,
+ 0x20, 0x40, 0x40, 0x3D, 0x00, 0x00,
+ 0x7F, 0x10, 0x28, 0x44, 0x00, 0x00,
+ 0x00, 0x41, 0x7F, 0x40, 0x00, 0x00,
+ 0x7C, 0x04, 0x78, 0x04, 0x78, 0x00,
+ 0x7C, 0x08, 0x04, 0x04, 0x78, 0x00,
+ 0x38, 0x44, 0x44, 0x44, 0x38, 0x00,
+ 0x7C, 0x18, 0x24, 0x24, 0x18, 0x00,
+ 0x18, 0x24, 0x24, 0x18, 0x7C, 0x00,
+ 0x7C, 0x08, 0x04, 0x04, 0x08, 0x00,
+ 0x48, 0x54, 0x54, 0x54, 0x24, 0x00,
+ 0x04, 0x04, 0x3F, 0x44, 0x24, 0x00,
+ 0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00,
+ 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00,
+ 0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00,
+ 0x44, 0x28, 0x10, 0x28, 0x44, 0x00,
+ 0x4C, 0x90, 0x90, 0x90, 0x7C, 0x00,
+ 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00,
+ 0x00, 0x08, 0x36, 0x41, 0x00, 0x00,
+ 0x00, 0x00, 0x77, 0x00, 0x00, 0x00,
+ 0x00, 0x41, 0x36, 0x08, 0x00, 0x00,
+ 0x02, 0x01, 0x02, 0x04, 0x02, 0x00,
+ 0x3C, 0x26, 0x23, 0x26, 0x3C, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC0, 0xF0, 0xF8, 0x8C, 0x86, 0xC6,
+ 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFE, 0xFC, 0xFC, 0xF8, 0xE0,
+ 0x80, 0x00, 0x00, 0x00, 0xF0, 0xF0,
+ 0xF0, 0x00, 0x00, 0xC0, 0xE0, 0xF0,
+ 0x70, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xF8, 0xF8, 0xF8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xF8, 0xF8,
+ 0xF8, 0x00, 0x00, 0xF8, 0xF8, 0xF8,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xE0, 0xF0, 0xF0, 0xF0, 0xE0, 0xEC,
+ 0xEE, 0xF7, 0xF3, 0x70, 0x20, 0x00,
+ 0x7C, 0x7C, 0x7C, 0x7E, 0x00, 0x7E,
+ 0x7E, 0x7E, 0x7F, 0x7F, 0x7F, 0x00,
+ 0x00, 0x80, 0xC0, 0xE0, 0x7E, 0x5B,
+ 0x4F, 0x5B, 0xFE, 0xC0, 0x00, 0x00,
+ 0xC0, 0x00, 0xDC, 0xD7, 0xDE, 0xDE,
+ 0xDE, 0xD7, 0xDC, 0x00, 0xC0, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0xE0, 0x70, 0x78, 0x68, 0x6C, 0x64,
+ 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7,
+ 0xE7, 0x3F, 0x1F, 0x0F, 0x3F, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F,
+ 0x0F, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0x1E, 0x3F, 0xFF, 0xF3, 0xE1,
+ 0x80, 0x00, 0x00, 0xF8, 0xFC, 0xFE,
+ 0x36, 0x36, 0x36, 0x3E, 0xBC, 0xB8,
+ 0x00, 0x0E, 0x3E, 0xFE, 0xF0, 0x80,
+ 0xF0, 0xFE, 0x3E, 0x0E, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x06, 0x06, 0x06,
+ 0xFE, 0xFE, 0xFC, 0x70, 0x00, 0xE6,
+ 0xF6, 0xF6, 0x36, 0x36, 0xFE, 0xFE,
+ 0xFC, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0F, 0x1F, 0x3F, 0x7F, 0x7F, 0x7F,
+ 0x7F, 0x7F, 0x3F, 0x1E, 0x0C, 0x00,
+ 0x1F, 0x1F, 0x1F, 0x3F, 0x00, 0x3F,
+ 0x3F, 0x3F, 0x7F, 0x7F, 0x7F, 0x00,
+ 0x30, 0x7B, 0x7F, 0x78, 0x30, 0x20,
+ 0x20, 0x30, 0x78, 0x7F, 0x3B, 0x00,
+ 0x03, 0x00, 0x0F, 0x7F, 0x0F, 0x0F,
+ 0x0F, 0x7F, 0x0F, 0x00, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x3C, 0x7F,
+ 0x63, 0x60, 0xE0, 0xC0, 0xC0, 0xC0,
+ 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF,
+ 0xFF, 0xC0, 0x60, 0x30, 0x18, 0x0F,
+ 0x03, 0x03, 0x03, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x03,
+ 0x03, 0x03, 0x00, 0x01, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x01,
+ 0x00, 0x70, 0x70, 0x39, 0x3F, 0x1F,
+ 0x07, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x01, 0x00, 0x00, 0x01,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x03,
+ 0x03, 0x00, 0x00, 0x03, 0x03, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+// clang-format on
diff --git a/keyboards/yowkees/lib/keyball/README.md b/keyboards/yowkees/lib/keyball/README.md
new file mode 100644
index 00000000000..0c54427a9b5
--- /dev/null
+++ b/keyboards/yowkees/lib/keyball/README.md
@@ -0,0 +1,128 @@
+# Keyball Core Function Library
+
+## Scroll snap mode
+
+When scrolling with the trackball, the scroll direction is restricted.
+This restriction is called "scroll snap".
+
+The direction of restriction can be changed using special key codes.
+You can also release this restriction.
+It is called as "scroll snap mode"
+The current mode is displayed on the OLED.
+
+There are 3 modes for scroll snap.
+
+1. Vertical (default): key code is `SSNP_VRT`, indicated as `VT`.
+2. Horizontal: key code is `SSNP_HOR`, indicated as `HO`.
+3. Free: key code is `SSNP_FRE`, indicated as `SCR`.
+
+The scroll snap mode at startup is vertical,
+but you can change it by saving the current mode with `KBC_SAVE`
+
+## MEMO
+
+This section contains notes regarding the specifications of this library.
+Since the purpose is to keep a record in whatever form it takes,
+a lot of Japanese is included.
+If you would like to read it in English, please request a translation via issue or discussion.
+Of course you can translate it for us. If you translate it,
+please make pull requests to share it us.
+
+### Scroll Snap Spec
+
+この機能は config.h に `#define KEYBALL_SCROLLSNAP_ENABLE 0` を書き加えることで無効化できる。
+
+トラックボールによるスクロールの方向を制限するのがスクロールスナップ。
+現在のスクロールスナップには3つのモードがある。
+
+* 垂直方向にスナップ (デフォルト)
+* 水平方向にスナップ
+* スナップしない自由スクロール
+
+以上を `SSNP_VRT`, `SSNP_HOR`, `SSNP_FRE` の独自キーコードを用いて手動で切り替える。
+
+#### up to 1.3.2
+
+初期状態でトラックボールによるスクロールを垂直方向に制限(スナップ)している。
+この振る舞いは config.h に `#define KEYBALL_SCROLLSNAP_ENABLE 1` を書き加えることで有効化できる。
+
+この機能はスナップモードとフリーモードから構成される。
+初期状態はスナップモードで、このモードではスクロール方向は垂直に制限される。
+スナップモードで水平の一定方向に一定カウント(デフォルトは12)以上スクロールするとフリーモードに遷移する。
+なおこのカウントはスクロール除数適用後のカウントである。
+フリーモードでは制限が取り払われ、水平と垂直どちらにも自由にスクロールできる。
+フリーモードで一定時間(デフォルトは 100 ミリ秒)、スクロール操作を行わないとスナップモードに遷移する。
+
+フリーモードに遷移するためのカウント数を変更するには `KEYBALL_SCROLLSNAP_TENSION_THRESHOLD` を、
+スナップモードに遷移するためのインターバル(ミリ秒)を変更するには `KEYBALL_SCROLLSNAP_RESET_TIMER` を、それぞれ config.h で設定できる。
+
+以下はカウント数を 5 に、インターバルを 200 ミリ秒に変更する例:
+
+```c
+#define KEYBALL_SCROLLSNAP_TENSION_THRESHOLD 5
+#define KEYBALL_SCROLLSNAP_RESET_TIMER 200
+```
+
+#### History of Scroll Snap
+
+もともとは自由にスクロールできるようにしていた。
+しかし思ったよりもボールの感度が高く一定方向だけに動かすのが難しく、
+誤操作を誘発していた。
+そのためなんらかのスナップ機能が必要だと判断した。
+
+最初のスナップ機能は垂直・水平のどちらかの軸から一定角度以内で収まってるうちはそちらへスナップするとした。
+しかし回転開始初期にはその移動量が極小かつセンサーの感度が高いので、
+垂直に動かしたい時に水平にも極小量の移動が発生しておりスナップ方向が定まらない、
+という問題が発生した。
+人間は自分が思うほどには指を正確に動かせていなかった。
+
+そこで一定方向に一定以上のカウントを検出するまでは一切スクロールしないようにした。
+これは回転開始初期のスクロール量を読み捨てるに等しい。
+
+しかしWebブラウザを思い浮かべてもらえればすぐにわかるように、
+一般のユースケースでは垂直方向のスクロールを頻繁に利用する。
+先の読み捨てにより、垂直方向のスクロールがワンテンポ遅れ、体験を大幅に損なうことが明らかになった。
+この解決のためモード: 初期は垂直のみ、後に自由スクロールする、を導入した。
+
+### Scroll Divider / スクロール除数
+
+Keyballのセンサーは感度がとても高い。
+そのため生の値をスクロール量としてしまうとスクロール操作がとても難しくなった。
+そこで生の値をある数で割ってスクロールに適用する方式を採用した。
+この時の割る数をスクロール除数と言っている。
+
+スクロール除数は、体感として小さく制御する意味がなかったので、
+1, 2, 4, 8, 16, 32, 64 というように2の乗数とした。
+2の乗数であるのならば値の表現として $2 ^ n$ の $n$ で表せる。
+またEEPROMに設定値を保存できるようにするために、
+ビット数を節約する目的で $n$ が取りうる値は 1~7 の範囲とした。
+結果実際の割る数は以下の式で計算できる。
+
+$$ 2 ^ {(n - 1)} $$
+
+$n$ の初期値は 4 で 1/8 になることを意味する。
+この値は config.h で `KEYBALL_SCROLL_DIV_DEFAULT` マクロを定義することで変更できる。
+これを0にすることは考慮していないので設定しないこと。
+
+### Scroll Inhivitor
+
+トラックボールの移動量をポインタに適用するかスクロールに適用するか、
+Keyballは内部にスクロールモードという名のモードで管理している。
+スクロールモードはキーコードやAPI呼び出しの任意のタイミングで切り替えられる。
+デフォルトのキーマップでは特定のレイヤーの状態を
+スクロールモードのオンオフに適用している。
+
+当初はスクロールモードの切り替え直後に、
+トラックボールの移動が意図しない適用先に適用されることが頻発した。
+ポインタをブラウザまで動かした後にスクロールモードに変更すると、
+意図していない方向にスクロールするといった体験になる。
+
+そこでスクロールモード切替直後の一定時間は
+一切のトラックボール操作を読み捨てることにした。
+この読み捨てる時間のことを Scroll Inhivitor と名付けた。
+この Scroll Inhivitor のデフォルト値は 50 ミリ秒である。
+短い時間ではあるが結構効いている。
+
+Scroll Inhivitor は config.h で `KEYBALL_SCROLLBALL_INHIVITOR` マクロを定義することで変更できる。
+無効化したい場合は値として `0` を設定する。
+興味があれば無効にしてみるのも面白いかもしれない。
diff --git a/keyboards/yowkees/lib/keyball/keyball.c b/keyboards/yowkees/lib/keyball/keyball.c
new file mode 100644
index 00000000000..07efac7a7df
--- /dev/null
+++ b/keyboards/yowkees/lib/keyball/keyball.c
@@ -0,0 +1,781 @@
+/*
+Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include "quantum.h"
+#ifdef SPLIT_KEYBOARD
+# include "transactions.h"
+#endif
+
+#include "keyball.h"
+#include "drivers/pmw3360/pmw3360.h"
+
+#include
+
+const uint8_t CPI_DEFAULT = KEYBALL_CPI_DEFAULT / 100;
+const uint8_t CPI_MAX = pmw3360_MAXCPI + 1;
+const uint8_t SCROLL_DIV_MAX = 7;
+
+const uint16_t AML_TIMEOUT_MIN = 100;
+const uint16_t AML_TIMEOUT_MAX = 1000;
+const uint16_t AML_TIMEOUT_QU = 50; // Quantization Unit
+
+static const char BL = '\xB0'; // Blank indicator character
+static const char LFSTR_ON[] PROGMEM = "\xB2\xB3";
+static const char LFSTR_OFF[] PROGMEM = "\xB4\xB5";
+
+keyball_t keyball = {
+ .this_have_ball = false,
+ .that_enable = false,
+ .that_have_ball = false,
+
+ .this_motion = {0},
+ .that_motion = {0},
+
+ .cpi_value = 0,
+ .cpi_changed = false,
+
+ .scroll_mode = false,
+ .scroll_div = 0,
+
+ .pressing_keys = { BL, BL, BL, BL, BL, BL, 0 },
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// Hook points
+
+__attribute__((weak)) void keyball_on_adjust_layout(keyball_adjust_t v) {}
+
+//////////////////////////////////////////////////////////////////////////////
+// Static utilities
+
+// add16 adds two int16_t with clipping.
+static int16_t add16(int16_t a, int16_t b) {
+ int16_t r = a + b;
+ if (a >= 0 && b >= 0 && r < 0) {
+ r = 32767;
+ } else if (a < 0 && b < 0 && r >= 0) {
+ r = -32768;
+ }
+ return r;
+}
+
+// divmod16 divides *v by div, returns the quotient, and assigns the remainder
+// to *v.
+static int16_t divmod16(int16_t *v, int16_t div) {
+ int16_t r = *v / div;
+ *v -= r * div;
+ return r;
+}
+
+// clip2int8 clips an integer fit into int8_t.
+static inline int8_t clip2int8(int16_t v) {
+ return (v) < -127 ? -127 : (v) > 127 ? 127 : (int8_t)v;
+}
+
+#ifdef OLED_ENABLE
+static const char *format_4d(int8_t d) {
+ static char buf[5] = {0}; // max width (4) + NUL (1)
+ char lead = ' ';
+ if (d < 0) {
+ d = -d;
+ lead = '-';
+ }
+ buf[3] = (d % 10) + '0';
+ d /= 10;
+ if (d == 0) {
+ buf[2] = lead;
+ lead = ' ';
+ } else {
+ buf[2] = (d % 10) + '0';
+ d /= 10;
+ }
+ if (d == 0) {
+ buf[1] = lead;
+ lead = ' ';
+ } else {
+ buf[1] = (d % 10) + '0';
+ d /= 10;
+ }
+ buf[0] = lead;
+ return buf;
+}
+
+static char to_1x(uint8_t x) {
+ x &= 0x0f;
+ return x < 10 ? x + '0' : x + 'a' - 10;
+}
+#endif
+
+static void add_cpi(int8_t delta) {
+ int16_t v = keyball_get_cpi() + delta;
+ keyball_set_cpi(v < 1 ? 1 : v);
+}
+
+static void add_scroll_div(int8_t delta) {
+ int8_t v = keyball_get_scroll_div() + delta;
+ keyball_set_scroll_div(v < 1 ? 1 : v);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Pointing device driver
+
+#if KEYBALL_MODEL == 46
+void keyboard_pre_init_kb(void) {
+ keyball.this_have_ball = pmw3360_init();
+ keyboard_pre_init_user();
+}
+#endif
+
+void pointing_device_driver_init(void) {
+#if KEYBALL_MODEL != 46
+ keyball.this_have_ball = pmw3360_init();
+#endif
+ if (keyball.this_have_ball) {
+#if defined(KEYBALL_PMW3360_UPLOAD_SROM_ID)
+# if KEYBALL_PMW3360_UPLOAD_SROM_ID == 0x04
+ pmw3360_srom_upload(pmw3360_srom_0x04);
+# elif KEYBALL_PMW3360_UPLOAD_SROM_ID == 0x81
+ pmw3360_srom_upload(pmw3360_srom_0x81);
+# else
+# error Invalid value for KEYBALL_PMW3360_UPLOAD_SROM_ID. Please choose 0x04 or 0x81 or disable it.
+# endif
+#endif
+ pmw3360_cpi_set(CPI_DEFAULT - 1);
+ }
+}
+
+uint16_t pointing_device_driver_get_cpi(void) {
+ return keyball_get_cpi();
+}
+
+void pointing_device_driver_set_cpi(uint16_t cpi) {
+ keyball_set_cpi(cpi);
+}
+
+__attribute__((weak)) void keyball_on_apply_motion_to_mouse_move(keyball_motion_t *m, report_mouse_t *r, bool is_left) {
+#if KEYBALL_MODEL == 61 || KEYBALL_MODEL == 39 || KEYBALL_MODEL == 147 || KEYBALL_MODEL == 44
+ r->x = clip2int8(m->y);
+ r->y = clip2int8(m->x);
+ if (is_left) {
+ r->x = -r->x;
+ r->y = -r->y;
+ }
+#elif KEYBALL_MODEL == 46
+ r->x = clip2int8(m->x);
+ r->y = -clip2int8(m->y);
+#else
+# error("unknown Keyball model")
+#endif
+ // clear motion
+ m->x = 0;
+ m->y = 0;
+}
+
+__attribute__((weak)) void keyball_on_apply_motion_to_mouse_scroll(keyball_motion_t *m, report_mouse_t *r, bool is_left) {
+ // consume motion of trackball.
+ int16_t div = 1 << (keyball_get_scroll_div() - 1);
+ int16_t x = divmod16(&m->x, div);
+ int16_t y = divmod16(&m->y, div);
+
+ // apply to mouse report.
+#if KEYBALL_MODEL == 61 || KEYBALL_MODEL == 39 || KEYBALL_MODEL == 147 || KEYBALL_MODEL == 44
+ r->h = clip2int8(y);
+ r->v = -clip2int8(x);
+ if (is_left) {
+ r->h = -r->h;
+ r->v = -r->v;
+ }
+#elif KEYBALL_MODEL == 46
+ r->h = clip2int8(x);
+ r->v = clip2int8(y);
+#else
+# error("unknown Keyball model")
+#endif
+
+ // Scroll snapping
+#if KEYBALL_SCROLLSNAP_ENABLE == 1
+ // Old behavior up to 1.3.2)
+ uint32_t now = timer_read32();
+ if (r->h != 0 || r->v != 0) {
+ keyball.scroll_snap_last = now;
+ } else if (TIMER_DIFF_32(now, keyball.scroll_snap_last) >= KEYBALL_SCROLLSNAP_RESET_TIMER) {
+ keyball.scroll_snap_tension_h = 0;
+ }
+ if (abs(keyball.scroll_snap_tension_h) < KEYBALL_SCROLLSNAP_TENSION_THRESHOLD) {
+ keyball.scroll_snap_tension_h += y;
+ r->h = 0;
+ }
+#elif KEYBALL_SCROLLSNAP_ENABLE == 2
+ // New behavior
+ switch (keyball_get_scrollsnap_mode()) {
+ case KEYBALL_SCROLLSNAP_MODE_VERTICAL:
+ r->h = 0;
+ break;
+ case KEYBALL_SCROLLSNAP_MODE_HORIZONTAL:
+ r->v = 0;
+ break;
+ default:
+ // pass by without doing anything
+ break;
+ }
+#endif
+}
+
+static void motion_to_mouse(keyball_motion_t *m, report_mouse_t *r, bool is_left, bool as_scroll) {
+ if (as_scroll) {
+ keyball_on_apply_motion_to_mouse_scroll(m, r, is_left);
+ } else {
+ keyball_on_apply_motion_to_mouse_move(m, r, is_left);
+ }
+}
+
+static inline bool should_report(void) {
+ uint32_t now = timer_read32();
+#if defined(KEYBALL_REPORTMOUSE_INTERVAL) && KEYBALL_REPORTMOUSE_INTERVAL > 0
+ // throttling mouse report rate.
+ static uint32_t last = 0;
+ if (TIMER_DIFF_32(now, last) < KEYBALL_REPORTMOUSE_INTERVAL) {
+ return false;
+ }
+ last = now;
+#endif
+#if defined(KEYBALL_SCROLLBALL_INHIVITOR) && KEYBALL_SCROLLBALL_INHIVITOR > 0
+ if (TIMER_DIFF_32(now, keyball.scroll_mode_changed) < KEYBALL_SCROLLBALL_INHIVITOR) {
+ keyball.this_motion.x = 0;
+ keyball.this_motion.y = 0;
+ keyball.that_motion.x = 0;
+ keyball.that_motion.y = 0;
+ }
+#endif
+ return true;
+}
+
+report_mouse_t pointing_device_driver_get_report(report_mouse_t rep) {
+ // fetch from optical sensor.
+ if (keyball.this_have_ball) {
+ pmw3360_motion_t d = {0};
+ if (pmw3360_motion_burst(&d)) {
+ ATOMIC_BLOCK_FORCEON {
+ keyball.this_motion.x = add16(keyball.this_motion.x, d.x);
+ keyball.this_motion.y = add16(keyball.this_motion.y, d.y);
+ }
+ }
+ }
+ // report mouse event, if keyboard is primary.
+ if (is_keyboard_master() && should_report()) {
+ // modify mouse report by PMW3360 motion.
+ motion_to_mouse(&keyball.this_motion, &rep, is_keyboard_left(), keyball.scroll_mode);
+ motion_to_mouse(&keyball.that_motion, &rep, !is_keyboard_left(), keyball.scroll_mode ^ keyball.this_have_ball);
+ // store mouse report for OLED.
+ keyball.last_mouse = rep;
+ }
+ return rep;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Split RPC
+
+#ifdef SPLIT_KEYBOARD
+
+static void rpc_get_info_handler(uint8_t in_buflen, const void *in_data, uint8_t out_buflen, void *out_data) {
+ keyball_info_t info = {
+ .ballcnt = keyball.this_have_ball ? 1 : 0,
+ };
+ *(keyball_info_t *)out_data = info;
+ keyball_on_adjust_layout(KEYBALL_ADJUST_SECONDARY);
+}
+
+static void rpc_get_info_invoke(void) {
+ static bool negotiated = false;
+ static uint32_t last_sync = 0;
+ static int round = 0;
+ uint32_t now = timer_read32();
+ if (negotiated || TIMER_DIFF_32(now, last_sync) < KEYBALL_TX_GETINFO_INTERVAL) {
+ return;
+ }
+ last_sync = now;
+ round++;
+ keyball_info_t recv = {0};
+ if (!transaction_rpc_exec(KEYBALL_GET_INFO, 0, NULL, sizeof(recv), &recv)) {
+ if (round < KEYBALL_TX_GETINFO_MAXTRY) {
+ dprintf("keyball:rpc_get_info_invoke: missed #%d\n", round);
+ return;
+ }
+ }
+ negotiated = true;
+ keyball.that_enable = true;
+ keyball.that_have_ball = recv.ballcnt > 0;
+ dprintf("keyball:rpc_get_info_invoke: negotiated #%d %d\n", round, keyball.that_have_ball);
+
+ // split keyboard negotiation completed.
+
+# ifdef VIA_ENABLE
+ // adjust VIA layout options according to current combination.
+ uint8_t layouts = (keyball.this_have_ball ? (is_keyboard_left() ? 0x02 : 0x01) : 0x00) | (keyball.that_have_ball ? (is_keyboard_left() ? 0x01 : 0x02) : 0x00);
+ uint32_t curr = via_get_layout_options();
+ uint32_t next = (curr & ~0x3) | layouts;
+ if (next != curr) {
+ via_set_layout_options(next);
+ }
+# endif
+
+ keyball_on_adjust_layout(KEYBALL_ADJUST_PRIMARY);
+}
+
+static void rpc_get_motion_handler(uint8_t in_buflen, const void *in_data, uint8_t out_buflen, void *out_data) {
+ *(keyball_motion_t *)out_data = keyball.this_motion;
+ // clear motion
+ keyball.this_motion.x = 0;
+ keyball.this_motion.y = 0;
+}
+
+static void rpc_get_motion_invoke(void) {
+ static uint32_t last_sync = 0;
+ uint32_t now = timer_read32();
+ if (TIMER_DIFF_32(now, last_sync) < KEYBALL_TX_GETMOTION_INTERVAL) {
+ return;
+ }
+ keyball_motion_t recv = {0};
+ if (transaction_rpc_exec(KEYBALL_GET_MOTION, 0, NULL, sizeof(recv), &recv)) {
+ keyball.that_motion.x = add16(keyball.that_motion.x, recv.x);
+ keyball.that_motion.y = add16(keyball.that_motion.y, recv.y);
+ }
+ last_sync = now;
+ return;
+}
+
+static void rpc_set_cpi_handler(uint8_t in_buflen, const void *in_data, uint8_t out_buflen, void *out_data) {
+ keyball_set_cpi(*(keyball_cpi_t *)in_data);
+}
+
+static void rpc_set_cpi_invoke(void) {
+ if (!keyball.cpi_changed) {
+ return;
+ }
+ keyball_cpi_t req = keyball.cpi_value;
+ if (!transaction_rpc_send(KEYBALL_SET_CPI, sizeof(req), &req)) {
+ return;
+ }
+ keyball.cpi_changed = false;
+}
+
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+// OLED utility
+
+#ifdef OLED_ENABLE
+// clang-format off
+const char PROGMEM code_to_name[] = {
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
+ 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
+ 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4',
+ '5', '6', '7', '8', '9', '0', 'R', 'E', 'B', 'T',
+ '_', '-', '=', '[', ']', '\\', '#', ';', '\'', '`',
+ ',', '.', '/',
+};
+// clang-format on
+#endif
+
+void keyball_oled_render_ballinfo(void) {
+#ifdef OLED_ENABLE
+ // Format: `Ball:{mouse x}{mouse y}{mouse h}{mouse v}`
+ //
+ // Output example:
+ //
+ // Ball: -12 34 0 0
+
+ // 1st line, "Ball" label, mouse x, y, h, and v.
+ oled_write_P(PSTR("Ball\xB1"), false);
+ oled_write(format_4d(keyball.last_mouse.x), false);
+ oled_write(format_4d(keyball.last_mouse.y), false);
+ oled_write(format_4d(keyball.last_mouse.h), false);
+ oled_write(format_4d(keyball.last_mouse.v), false);
+
+ // 2nd line, empty label and CPI
+ oled_write_P(PSTR(" \xB1\xBC\xBD"), false);
+ oled_write(format_4d(keyball_get_cpi()) + 1, false);
+ oled_write_P(PSTR("00 "), false);
+
+ // indicate scroll snap mode: "VT" (vertical), "HN" (horiozntal), and "SCR" (free)
+#if 1 && KEYBALL_SCROLLSNAP_ENABLE == 2
+ switch (keyball_get_scrollsnap_mode()) {
+ case KEYBALL_SCROLLSNAP_MODE_VERTICAL:
+ oled_write_P(PSTR("VT"), false);
+ break;
+ case KEYBALL_SCROLLSNAP_MODE_HORIZONTAL:
+ oled_write_P(PSTR("HO"), false);
+ break;
+ default:
+ oled_write_P(PSTR("\xBE\xBF"), false);
+ break;
+ }
+#else
+ oled_write_P(PSTR("\xBE\xBF"), false);
+#endif
+ // indicate scroll mode: on/off
+ if (keyball.scroll_mode) {
+ oled_write_P(LFSTR_ON, false);
+ } else {
+ oled_write_P(LFSTR_OFF, false);
+ }
+
+ // indicate scroll divider:
+ oled_write_P(PSTR(" \xC0\xC1"), false);
+ oled_write_char('0' + keyball_get_scroll_div(), false);
+#endif
+}
+
+void keyball_oled_render_ballsubinfo(void) {
+#ifdef OLED_ENABLE
+#endif
+}
+
+void keyball_oled_render_keyinfo(void) {
+#ifdef OLED_ENABLE
+ // Format: `Key : R{row} C{col} K{kc} {name}{name}{name}`
+ //
+ // Where `kc` is lower 8 bit of keycode.
+ // Where `name`s are readable labels for pressing keys, valid between 4 and 56.
+ //
+ // `row`, `col`, and `kc` indicates the last processed key,
+ // but `name`s indicate unreleased keys in best effort.
+ //
+ // It is aligned to fit with output of keyball_oled_render_ballinfo().
+ // For example:
+ //
+ // Key : R2 C3 K06 abc
+ // Ball: 0 0 0 0
+
+ // "Key" Label
+ oled_write_P(PSTR("Key \xB1"), false);
+
+ // Row and column
+ oled_write_char('\xB8', false);
+ oled_write_char(to_1x(keyball.last_pos.row), false);
+ oled_write_char('\xB9', false);
+ oled_write_char(to_1x(keyball.last_pos.col), false);
+
+ // Keycode
+ oled_write_P(PSTR("\xBA\xBB"), false);
+ oled_write_char(to_1x(keyball.last_kc >> 4), false);
+ oled_write_char(to_1x(keyball.last_kc), false);
+
+ // Pressing keys
+ oled_write_P(PSTR(" "), false);
+ oled_write(keyball.pressing_keys, false);
+#endif
+}
+
+void keyball_oled_render_layerinfo(void) {
+#ifdef OLED_ENABLE
+ // Format: `Layer:{layer state}`
+ //
+ // Output example:
+ //
+ // Layer:-23------------
+ //
+ oled_write_P(PSTR("L\xB6\xB7r\xB1"), false);
+ for (uint8_t i = 1; i < 8; i++) {
+ oled_write_char((layer_state_is(i) ? to_1x(i) : BL), false);
+ }
+ oled_write_char(' ', false);
+
+# ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE
+ oled_write_P(PSTR("\xC2\xC3"), false);
+ if (get_auto_mouse_enable()) {
+ oled_write_P(LFSTR_ON, false);
+ } else {
+ oled_write_P(LFSTR_OFF, false);
+ }
+
+ oled_write(format_4d(get_auto_mouse_timeout() / 10) + 1, false);
+ oled_write_char('0', false);
+# else
+ oled_write_P(PSTR("\xC2\xC3\xB4\xB5 ---"), false);
+# endif
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Public API functions
+
+bool keyball_get_scroll_mode(void) {
+ return keyball.scroll_mode;
+}
+
+void keyball_set_scroll_mode(bool mode) {
+ if (mode != keyball.scroll_mode) {
+ keyball.scroll_mode_changed = timer_read32();
+ }
+ keyball.scroll_mode = mode;
+}
+
+keyball_scrollsnap_mode_t keyball_get_scrollsnap_mode(void) {
+#if KEYBALL_SCROLLSNAP_ENABLE == 2
+ return keyball.scrollsnap_mode;
+#else
+ return 0;
+#endif
+}
+
+void keyball_set_scrollsnap_mode(keyball_scrollsnap_mode_t mode) {
+#if KEYBALL_SCROLLSNAP_ENABLE == 2
+ keyball.scrollsnap_mode = mode;
+#endif
+}
+
+uint8_t keyball_get_scroll_div(void) {
+ return keyball.scroll_div == 0 ? KEYBALL_SCROLL_DIV_DEFAULT : keyball.scroll_div;
+}
+
+void keyball_set_scroll_div(uint8_t div) {
+ keyball.scroll_div = div > SCROLL_DIV_MAX ? SCROLL_DIV_MAX : div;
+}
+
+uint8_t keyball_get_cpi(void) {
+ return keyball.cpi_value == 0 ? CPI_DEFAULT : keyball.cpi_value;
+}
+
+void keyball_set_cpi(uint8_t cpi) {
+ if (cpi > CPI_MAX) {
+ cpi = CPI_MAX;
+ }
+ keyball.cpi_value = cpi;
+ keyball.cpi_changed = true;
+ if (keyball.this_have_ball) {
+ pmw3360_cpi_set(cpi == 0 ? CPI_DEFAULT - 1 : cpi - 1);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Keyboard hooks
+
+void keyboard_post_init_kb(void) {
+#ifdef SPLIT_KEYBOARD
+ // register transaction handlers on secondary.
+ if (!is_keyboard_master()) {
+ transaction_register_rpc(KEYBALL_GET_INFO, rpc_get_info_handler);
+ transaction_register_rpc(KEYBALL_GET_MOTION, rpc_get_motion_handler);
+ transaction_register_rpc(KEYBALL_SET_CPI, rpc_set_cpi_handler);
+ }
+#endif
+
+ // read keyball configuration from EEPROM
+ if (eeconfig_is_enabled()) {
+ keyball_config_t c = {.raw = eeconfig_read_kb()};
+ keyball_set_cpi(c.cpi);
+ keyball_set_scroll_div(c.sdiv);
+#ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE
+ set_auto_mouse_enable(c.amle);
+ set_auto_mouse_timeout(c.amlto == 0 ? AUTO_MOUSE_TIME : (c.amlto + 1) * AML_TIMEOUT_QU);
+#endif
+#if KEYBALL_SCROLLSNAP_ENABLE == 2
+ keyball_set_scrollsnap_mode(c.ssnap);
+#endif
+ }
+
+ keyball_on_adjust_layout(KEYBALL_ADJUST_PENDING);
+ keyboard_post_init_user();
+}
+
+#if SPLIT_KEYBOARD
+void housekeeping_task_kb(void) {
+ if (is_keyboard_master()) {
+ rpc_get_info_invoke();
+ if (keyball.that_have_ball) {
+ rpc_get_motion_invoke();
+ rpc_set_cpi_invoke();
+ }
+ }
+}
+#endif
+
+static void pressing_keys_update(uint16_t keycode, keyrecord_t *record) {
+ // Process only valid keycodes.
+ if (keycode >= 4 && keycode < 57) {
+ char value = pgm_read_byte(code_to_name + keycode - 4);
+ char where = BL;
+ if (!record->event.pressed) {
+ // Swap `value` and `where` when releasing.
+ where = value;
+ value = BL;
+ }
+ // Rewrite the last `where` of pressing_keys to `value` .
+ for (int i = 0; i < KEYBALL_OLED_MAX_PRESSING_KEYCODES; i++) {
+ if (keyball.pressing_keys[i] == where) {
+ keyball.pressing_keys[i] = value;
+ break;
+ }
+ }
+ }
+}
+
+#ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE
+bool is_mouse_record_kb(uint16_t keycode, keyrecord_t* record) {
+ switch (keycode) {
+ case SCRL_MO:
+ return true;
+ }
+ return is_mouse_record_user(keycode, record);
+}
+#endif
+
+bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
+ // store last keycode, row, and col for OLED
+ keyball.last_kc = keycode;
+ keyball.last_pos = record->event.key;
+
+ pressing_keys_update(keycode, record);
+
+ if (!process_record_user(keycode, record)) {
+ return false;
+ }
+
+ // strip QK_MODS part.
+ if (keycode >= QK_MODS && keycode <= QK_MODS_MAX) {
+ keycode &= 0xff;
+ }
+
+ switch (keycode) {
+#ifndef MOUSEKEY_ENABLE
+ // process KC_MS_BTN1~8 by myself
+ // See process_action() in quantum/action.c for details.
+ case KC_MS_BTN1 ... KC_MS_BTN8: {
+ extern void register_mouse(uint8_t mouse_keycode, bool pressed);
+ register_mouse(keycode, record->event.pressed);
+ // to apply QK_MODS actions, allow to process others.
+ return true;
+ }
+#endif
+
+ case SCRL_MO:
+ keyball_set_scroll_mode(record->event.pressed);
+ // process_auto_mouse may use this in future, if changed order of
+ // processes.
+ return true;
+ }
+
+ // process events which works on pressed only.
+ if (record->event.pressed) {
+ switch (keycode) {
+ case KBC_RST:
+ keyball_set_cpi(0);
+ keyball_set_scroll_div(0);
+#ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE
+ set_auto_mouse_enable(false);
+ set_auto_mouse_timeout(AUTO_MOUSE_TIME);
+#endif
+ break;
+ case KBC_SAVE: {
+ keyball_config_t c = {
+ .cpi = keyball.cpi_value,
+ .sdiv = keyball.scroll_div,
+#ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE
+ .amle = get_auto_mouse_enable(),
+ .amlto = (get_auto_mouse_timeout() / AML_TIMEOUT_QU) - 1,
+#endif
+#if KEYBALL_SCROLLSNAP_ENABLE == 2
+ .ssnap = keyball_get_scrollsnap_mode(),
+#endif
+ };
+ eeconfig_update_kb(c.raw);
+ } break;
+
+ case CPI_I100:
+ add_cpi(1);
+ break;
+ case CPI_D100:
+ add_cpi(-1);
+ break;
+ case CPI_I1K:
+ add_cpi(10);
+ break;
+ case CPI_D1K:
+ add_cpi(-10);
+ break;
+
+ case SCRL_TO:
+ keyball_set_scroll_mode(!keyball.scroll_mode);
+ break;
+ case SCRL_DVI:
+ add_scroll_div(1);
+ break;
+ case SCRL_DVD:
+ add_scroll_div(-1);
+ break;
+
+#if KEYBALL_SCROLLSNAP_ENABLE == 2
+ case SSNP_HOR:
+ keyball_set_scrollsnap_mode(KEYBALL_SCROLLSNAP_MODE_HORIZONTAL);
+ break;
+ case SSNP_VRT:
+ keyball_set_scrollsnap_mode(KEYBALL_SCROLLSNAP_MODE_VERTICAL);
+ break;
+ case SSNP_FRE:
+ keyball_set_scrollsnap_mode(KEYBALL_SCROLLSNAP_MODE_FREE);
+ break;
+#endif
+
+#ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE
+ case AML_TO:
+ set_auto_mouse_enable(!get_auto_mouse_enable());
+ break;
+ case AML_I50:
+ {
+ uint16_t v = get_auto_mouse_timeout() + 50;
+ set_auto_mouse_timeout(MIN(v, AML_TIMEOUT_MAX));
+ }
+ break;
+ case AML_D50:
+ {
+ uint16_t v = get_auto_mouse_timeout() - 50;
+ set_auto_mouse_timeout(MAX(v, AML_TIMEOUT_MIN));
+ }
+ break;
+#endif
+
+ default:
+ return true;
+ }
+ return false;
+ }
+
+ return true;
+}
+
+// Disable functions keycode_config() and mod_config() in keycode_config.c to
+// reduce size. These functions are provided for customizing magic keycode.
+// These two functions are mostly unnecessary if `MAGIC_KEYCODE_ENABLE = no` is
+// set.
+//
+// If `MAGIC_KEYCODE_ENABLE = no` and you want to keep these two functions as
+// they are, define the macro KEYBALL_KEEP_MAGIC_FUNCTIONS.
+//
+// See: https://docs.qmk.fm/#/squeezing_avr?id=magic-functions
+//
+#if !defined(MAGIC_KEYCODE_ENABLE) && !defined(KEYBALL_KEEP_MAGIC_FUNCTIONS)
+
+uint16_t keycode_config(uint16_t keycode) {
+ return keycode;
+}
+
+uint8_t mod_config(uint8_t mod) {
+ return mod;
+}
+
+#endif
diff --git a/keyboards/yowkees/lib/keyball/keyball.h b/keyboards/yowkees/lib/keyball/keyball.h
new file mode 100644
index 00000000000..32003a84632
--- /dev/null
+++ b/keyboards/yowkees/lib/keyball/keyball.h
@@ -0,0 +1,272 @@
+/*
+Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#pragma once
+
+//////////////////////////////////////////////////////////////////////////////
+// Configurations
+
+#ifndef KEYBALL_CPI_DEFAULT
+# define KEYBALL_CPI_DEFAULT 500
+#endif
+
+#ifndef KEYBALL_SCROLL_DIV_DEFAULT
+# define KEYBALL_SCROLL_DIV_DEFAULT 4 // 4: 1/8 (1/2^(n-1))
+#endif
+
+#ifndef KEYBALL_REPORTMOUSE_INTERVAL
+# define KEYBALL_REPORTMOUSE_INTERVAL 8 // mouse report rate: 125Hz
+#endif
+
+#ifndef KEYBALL_SCROLLBALL_INHIVITOR
+# define KEYBALL_SCROLLBALL_INHIVITOR 50
+#endif
+
+/// To disable scroll snap feature, define 0 in your config.h
+#ifndef KEYBALL_SCROLLSNAP_ENABLE
+# define KEYBALL_SCROLLSNAP_ENABLE 2
+#endif
+
+#ifndef KEYBALL_SCROLLSNAP_RESET_TIMER
+# define KEYBALL_SCROLLSNAP_RESET_TIMER 100
+#endif
+
+#ifndef KEYBALL_SCROLLSNAP_TENSION_THRESHOLD
+# define KEYBALL_SCROLLSNAP_TENSION_THRESHOLD 12
+#endif
+
+/// Specify SROM ID to be uploaded PMW3360DW (optical sensor). It will be
+/// enabled high CPI setting or so. Valid valus are 0x04 or 0x81. Define this
+/// in your config.h to be enable. Please note that using this option will
+/// increase the firmware size by more than 4KB.
+//#define KEYBALL_PMW3360_UPLOAD_SROM_ID 0x04
+//#define KEYBALL_PMW3360_UPLOAD_SROM_ID 0x81
+
+/// Defining this macro keeps two functions intact: keycode_config() and
+/// mod_config() in keycode_config.c.
+///
+/// These functions customize the magic key code and are useless if the magic
+/// key code is disabled. Therefore, Keyball automatically disables it.
+/// However, there may be cases where you still need these functions even after
+/// disabling the magic key code. In that case, define this macro.
+//#define KEYBALL_KEEP_MAGIC_FUNCTIONS
+
+//////////////////////////////////////////////////////////////////////////////
+// Constants
+
+#define KEYBALL_TX_GETINFO_INTERVAL 500
+#define KEYBALL_TX_GETINFO_MAXTRY 10
+#define KEYBALL_TX_GETMOTION_INTERVAL 4
+
+#if (PRODUCT_ID & 0xff00) == 0x0000
+# define KEYBALL_MODEL 46
+#elif (PRODUCT_ID & 0xff00) == 0x0100
+# define KEYBALL_MODEL 61
+#elif (PRODUCT_ID & 0xff00) == 0x0200
+# define KEYBALL_MODEL 39
+#elif (PRODUCT_ID & 0xff00) == 0x0300
+# define KEYBALL_MODEL 147
+#elif (PRODUCT_ID & 0xff00) == 0x0400
+# define KEYBALL_MODEL 44
+#endif
+
+#define KEYBALL_OLED_MAX_PRESSING_KEYCODES 6
+
+//////////////////////////////////////////////////////////////////////////////
+// Types
+
+enum keyball_keycodes {
+ KBC_RST = QK_KB_0, // Keyball configuration: reset to default
+ KBC_SAVE = QK_KB_1, // Keyball configuration: save to EEPROM
+
+ CPI_I100 = QK_KB_2, // CPI +100 CPI
+ CPI_D100 = QK_KB_3, // CPI -100 CPI
+ CPI_I1K = QK_KB_4, // CPI +1000 CPI
+ CPI_D1K = QK_KB_5, // CPI -1000 CPI
+
+ // In scroll mode, motion from primary trackball is treated as scroll
+ // wheel.
+ SCRL_TO = QK_KB_6, // Toggle scroll mode
+ SCRL_MO = QK_KB_7, // Momentary scroll mode
+ SCRL_DVI = QK_KB_8, // Increment scroll divider
+ SCRL_DVD = QK_KB_9, // Decrement scroll divider
+
+ SSNP_VRT = QK_KB_13, // Set scroll snap mode as vertical
+ SSNP_HOR = QK_KB_14, // Set scroll snap mode as horizontal
+ SSNP_FRE = QK_KB_15, // Set scroll snap mode as disable (free scroll)
+
+ // Auto mouse layer control keycodes.
+ // Only works when POINTING_DEVICE_AUTO_MOUSE_ENABLE is defined.
+ AML_TO = QK_KB_10, // Toggle automatic mouse layer
+ AML_I50 = QK_KB_11, // Increment automatic mouse layer timeout
+ AML_D50 = QK_KB_12, // Decrement automatic mouse layer timeout
+
+ // User customizable 32 keycodes.
+ KEYBALL_SAFE_RANGE = QK_USER_0,
+};
+
+typedef union {
+ uint32_t raw;
+ struct {
+ uint8_t cpi : 7;
+ uint8_t sdiv : 3; // scroll divider
+#ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE
+ uint8_t amle : 1; // automatic mouse layer enabled
+ uint16_t amlto : 5; // automatic mouse layer timeout
+#endif
+#if KEYBALL_SCROLLSNAP_ENABLE == 2
+ uint8_t ssnap : 2; // scroll snap mode
+#endif
+ };
+} keyball_config_t;
+
+typedef struct {
+ uint8_t ballcnt; // count of balls: support only 0 or 1, for now
+} keyball_info_t;
+
+typedef struct {
+ int16_t x;
+ int16_t y;
+} keyball_motion_t;
+
+typedef uint8_t keyball_cpi_t;
+
+typedef enum {
+ KEYBALL_SCROLLSNAP_MODE_VERTICAL = 0,
+ KEYBALL_SCROLLSNAP_MODE_HORIZONTAL = 1,
+ KEYBALL_SCROLLSNAP_MODE_FREE = 2,
+} keyball_scrollsnap_mode_t;
+
+typedef struct {
+ bool this_have_ball;
+ bool that_enable;
+ bool that_have_ball;
+
+ keyball_motion_t this_motion;
+ keyball_motion_t that_motion;
+
+ uint8_t cpi_value;
+ bool cpi_changed;
+
+ bool scroll_mode;
+ uint32_t scroll_mode_changed;
+ uint8_t scroll_div;
+
+#if KEYBALL_SCROLLSNAP_ENABLE == 1
+ uint32_t scroll_snap_last;
+ int8_t scroll_snap_tension_h;
+#elif KEYBALL_SCROLLSNAP_ENABLE == 2
+ keyball_scrollsnap_mode_t scrollsnap_mode;
+#endif
+
+ uint16_t last_kc;
+ keypos_t last_pos;
+ report_mouse_t last_mouse;
+
+ // Buffer to indicate pressing keys.
+ char pressing_keys[KEYBALL_OLED_MAX_PRESSING_KEYCODES + 1];
+} keyball_t;
+
+typedef enum {
+ KEYBALL_ADJUST_PENDING = 0,
+ KEYBALL_ADJUST_PRIMARY = 1,
+ KEYBALL_ADJUST_SECONDARY = 2,
+} keyball_adjust_t;
+
+//////////////////////////////////////////////////////////////////////////////
+// Exported values (touch carefully)
+
+extern keyball_t keyball;
+
+//////////////////////////////////////////////////////////////////////////////
+// Hook points
+
+/// keyball_on_adjust_layout is called when the keyboard layout adjustted
+void keyball_on_adjust_layout(keyball_adjust_t v);
+
+/// keyball_on_apply_motion_to_mouse_move applies trackball's motion m to r as
+/// mouse movement.
+/// You can change the default algorithm by override this function.
+void keyball_on_apply_motion_to_mouse_move(keyball_motion_t *m, report_mouse_t *r, bool is_left);
+
+/// keyball_on_apply_motion_to_mouse_scroll applies trackball's motion m to r
+/// as mouse scroll.
+/// You can change the default algorithm by override this function.
+void keyball_on_apply_motion_to_mouse_scroll(keyball_motion_t *m, report_mouse_t *r, bool is_left);
+
+//////////////////////////////////////////////////////////////////////////////
+// Public API functions
+
+/// keyball_oled_render_ballinfo renders ball information to OLED.
+/// It uses just 21 columns to show the info.
+void keyball_oled_render_ballinfo(void);
+
+/// keyball_oled_render_keyinfo renders last processed key information to OLED.
+/// It shows column, row, key code, and key name (if available).
+void keyball_oled_render_keyinfo(void);
+
+/// keyball_oled_render_layerinfo renders current layer status information to
+/// OLED. It shows layer mask with number (1~f) for active layers and '_' for
+/// inactive layers.
+void keyball_oled_render_layerinfo(void);
+
+/// keyball_get_scroll_mode gets current scroll mode.
+bool keyball_get_scroll_mode(void);
+
+/// keyball_set_scroll_mode modify scroll mode.
+void keyball_set_scroll_mode(bool mode);
+
+/// keyball_get_scrollsnap_mode gets current scroll snap mode.
+keyball_scrollsnap_mode_t keyball_get_scrollsnap_mode(void);
+
+/// keyball_set_scrollsnap_mode change scroll snap mode.
+void keyball_set_scrollsnap_mode(keyball_scrollsnap_mode_t mode);
+
+/// keyball_get_scroll_div gets current scroll divider.
+/// See also keyball_set_scroll_div for the scroll divider's detail.
+uint8_t keyball_get_scroll_div(void);
+
+/// keyball_set_scroll_div changes scroll divider.
+///
+/// The scroll divider is the number that divides the raw value when applying
+/// trackball motion to scrolling. The CPI value of the trackball is very
+/// high, so if you apply it to scrolling as is, it will scroll too much.
+/// In order to adjust the scroll amount to be appropriate, it is applied after
+/// dividing it by a scroll divider. The actual denominator is determined by
+/// the following formula:
+///
+/// denominator = 2 ^ (div - 1) ^2
+///
+/// Valid values are between 1 and 7, KEYBALL_SCROLL_DIV_DEFAULT is used when 0
+/// is specified.
+void keyball_set_scroll_div(uint8_t div);
+
+/// keyball_get_cpi gets current CPI of trackball.
+/// The actual CPI value is the returned value +1 and multiplied by 100:
+///
+/// CPI = (v + 1) * 100
+uint8_t keyball_get_cpi(void);
+
+/// keyball_set_cpi changes CPI of trackball.
+/// Valid values are between 0 to 119, and the actual CPI value is the set
+/// value +1 and multiplied by 100:
+///
+/// CPI = (v + 1) * 100
+///
+/// In addition, if you do not upload SROM, the maximum value will be limited
+/// to 34 (3500CPI).
+void keyball_set_cpi(uint8_t cpi);
diff --git a/keyboards/yowkees/lib/keyball/keycodes.md b/keyboards/yowkees/lib/keyball/keycodes.md
new file mode 100644
index 00000000000..ed1d15c33d1
--- /dev/null
+++ b/keyboards/yowkees/lib/keyball/keycodes.md
@@ -0,0 +1,52 @@
+# Keyball: Special Keycodes
+
+* [English/英語](#english)
+* [日本語/Japanese](#japanese)
+
+
+## Special Keycodes
+
+| Keycode | Value on Remap | Hex | Description |
+|:-----------|:----------------|:---------|:------------------------------------------------------------------|
+| `KBC_RST` | `Kb 0` | `0x7e00` | Reset Keyball configuration[^1] |
+| `KBC_SAVE` | `Kb 1` | `0x7e01` | Persist Keyball configuration[^1] to EEPROM |
+| `CPI_I100` | `Kb 2` | `0x7e02` | Increase 100 CPI (max 12000) |
+| `CPI_D100` | `Kb 3` | `0x7e03` | Decrease 100 CPI (min 100) |
+| `CPI_I1K` | `Kb 4` | `0x7e04` | Increase 1000 CPI (max 12000) |
+| `CPI_D1K` | `Kb 5` | `0x7e05` | Decrease 1000 CPI (min 100) |
+| `SCRL_TO` | `Kb 6` | `0x7e06` | Toggle scroll mode |
+| `SCRL_MO` | `Kb 7` | `0x7e07` | Enable scroll mode when pressing |
+| `SCRL_DVI` | `Kb 8` | `0x7e08` | Increase scroll divider (max D7 = 1/128) <- Most Scroll slow |
+| `SCRL_DVD` | `Kb 9` | `0x7e09` | Decrease scroll divider (min 0 = 1/1) <- Most Scroll fast |
+| `AML_TO` | `Kb 10` | `0x7e0a` | Toggle automatic mouse layer |
+| `AML_I50` | `Kb 11` | `0x7e0b` | Increase 50ms automatic mouse layer timeout (max 1000ms) |
+| `AML_D50` | `Kb 12` | `0x7e0c` | Decrease 50ms automatic mouse layer timeout (min 100ms) |
+| `SSNP_VRT` | `Kb 13` | `0x7e0d` | Set scroll snap mode as vertical |
+| `SSNP_HOR` | `Kb 14` | `0x7e0e` | Set scroll snap mode as horizontal |
+| `SSNP_FRE` | `Kb 15` | `0x7e0f` | Set scroll snap mode as disable (free scroll) |
+
+[^1]: CPI, scroll divider, automatic mouse layer's enable/disable, and automatic mouse layer's timeout.
+
+
+## 特殊キーコード
+
+| キーコード | Remap上での表記 | 値 | 説明 |
+|:-----------|:----------------|:---------|:------------------------------------------------------------------|
+| `KBC_RST` | `Kb 0` | `0x7e00` | Keyball設定[^2]のリセット |
+| `KBC_SAVE` | `Kb 1` | `0x7e01` | 現在のKeyball設定[^2]をEEPROMに保存します |
+| `CPI_I100` | `Kb 2` | `0x7e02` | CPIを100増加させます(最大:12000) |
+| `CPI_D100` | `Kb 3` | `0x7e03` | CPIを100減少させます(最小:100) |
+| `CPI_I1K` | `Kb 4` | `0x7e04` | CPIを1000増加させます(最大:12000) |
+| `CPI_D1K` | `Kb 5` | `0x7e05` | CPIを1000減少させます(最小:100) |
+| `SCRL_TO` | `Kb 6` | `0x7e06` | タップごとにスクロールモードのON/OFFを切り替えます |
+| `SCRL_MO` | `Kb 7` | `0x7e07` | キーを押している間、スクロールモードになります |
+| `SCRL_DVI` | `Kb 8` | `0x7e08` | スクロール除数を1つ上げます(max D7 = 1/128)←最もスクロール遅い |
+| `SCRL_DVD` | `Kb 9` | `0x7e09` | スクロール除数を1つ下げます(min D0 = 1/1)←最もスクロール速い |
+| `AML_TO` | `Kb 10` | `0x7e0a` | 自動マウスレイヤーをトグルします。 |
+| `AML_I50` | `Kb 11` | `0x7e0b` | 自動マウスレイヤーのタイムアウトを50msec増やします (max 1000ms) |
+| `AML_D50` | `Kb 12` | `0x7e0c` | 自動マウスレイヤーのタイムアウトを50msec減らします (min 100ms) |
+| `SSNP_VRT` | `Kb 13` | `0x7e0d` | スクロールスナップモードを垂直にする |
+| `SSNP_HOR` | `Kb 14` | `0x7e0e` | スクロールスナップモードを水平にする |
+| `SSNP_FRE` | `Kb 15` | `0x7e0f` | スクロールスナップモードを無効にする(自由スクロール) |
+
+[^2]: CPI、スクロール除数、自動マウスレイヤーのON/OFF状態、及び自動マウスレイヤのタイムアウト
diff --git a/keyboards/yowkees/lib/logofont/font.md b/keyboards/yowkees/lib/logofont/font.md
new file mode 100644
index 00000000000..5c963c75ca6
--- /dev/null
+++ b/keyboards/yowkees/lib/logofont/font.md
@@ -0,0 +1,212 @@
+# Special character patterns
+
+## blank
+
+```
+00000000
+00000000
+00000000
+00000000
+00000000
+00000000
+```
+
+## blank indicator
+
+```
+00000000
+00010000
+00010000
+00010000
+00000000
+00000000
+00000000
+```
+
+## vertical label separator
+
+```
+00000000
+00000000
+01010101
+00000000
+00000000
+00000000
+```
+
+## "ON" in 2 chars with light background
+
+```
+00111110
+01100011
+01011101
+01011101
+01100011
+01111111
+01000001
+01111011
+01110111
+01000001
+00111110
+00000000
+```
+
+## "OFF" in 2 chars
+
+```
+00000000
+00011100
+00100010
+00100010
+00011100
+00000000
+00111110
+00001010
+00000000
+00111110
+00001010
+00000000
+```
+
+## "aye" in 2 chars for "Layer"
+
+```
+00110010
+00101010
+00111100
+00000000
+00100110
+00101000
+00011110
+00000000
+00011100
+00101010
+00101100
+00000000
+```
+
+## right half 'R'
+
+```
+00000000
+00000000
+00111111
+00001001
+00110110
+00000000
+```
+
+## right half 'C'
+
+```
+00000000
+00000000
+00011110
+00100001
+00100001
+00000000
+```
+
+## "KC" in 2 chars, indicate "keycode"
+
+```
+00000000
+00000000
+00000000
+00000000
+00111111
+00001000
+00110111
+00000000
+00011110
+00100001
+00100001
+00000000
+```
+
+## "CPI" in 2 chars
+
+```
+00011110
+00100001
+00100001
+00000000
+00111111
+00001001
+00000110
+00000000
+00100001
+00111111
+00100001
+00000000
+```
+
+## "SCR" in 2 chars
+
+```
+00100010
+00100101
+00011001
+00000000
+00011110
+00100001
+00100001
+00000000
+00111111
+00001001
+00110110
+00000000
+```
+
+## "DIV" in 2 chars
+
+```
+00111111
+00100001
+00011110
+00000000
+00100001
+00111111
+00100001
+00000000
+00001111
+00110000
+00001111
+00000000
+```
+
+## "AML" in 2 chars
+
+```
+00111110
+00001001
+00111110
+00000000
+00111111
+00000110
+00111111
+00000000
+00111111
+00100000
+00100000
+00000000
+```
+
+## inactive "ON" in 2 chars
+
+(not use)
+
+```
+00000000
+00011100
+00100010
+00100010
+00011100
+00000000
+00111110
+00000100
+00001000
+00111110
+00000000
+00000000
+```
diff --git a/keyboards/yowkees/lib/logofont/logofont.c b/keyboards/yowkees/lib/logofont/logofont.c
new file mode 100644
index 00000000000..29ce4888891
--- /dev/null
+++ b/keyboards/yowkees/lib/logofont/logofont.c
@@ -0,0 +1,199 @@
+// Copyright 2021 @Yowkees: Keyball logo
+//
+// - Keyball logo (0x80 ~ 0xAF)
+//
+// Copyright 2024 MURAOKA Taro (aka KoRoN, @kaoriya): Other glyphs
+//
+// - ASCII characters (0x20 ~ 0x7E)
+// - Special characters (0xB0 ~ 0xC3)
+
+#include "progmem.h"
+
+// clang-format off
+const unsigned char font[] PROGMEM = {
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Standard ASCII characters, most of which fit within 5x6 area.
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 ' '
+ 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, // 0x21 '!'
+ 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, // 0x22 '"'
+ 0x12, 0x3F, 0x12, 0x3F, 0x12, 0x00, // 0x23 '#'
+ 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00, // 0x24 '$'
+ 0x36, 0x09, 0x1E, 0x24, 0x1B, 0x00, // 0x25 '%'
+ 0x18, 0x26, 0x29, 0x12, 0x28, 0x00, // 0x26 '&'
+ 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, // 0x27 '''
+ 0x00, 0x1E, 0x21, 0x40, 0x00, 0x00, // 0x28 '('
+ 0x00, 0x40, 0x21, 0x1E, 0x00, 0x00, // 0x29 ')'
+ 0x14, 0x08, 0x3E, 0x08, 0x14, 0x00, // 0x2A '*'
+ 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, // 0x2B '+'
+ 0x00, 0x00, 0x30, 0x70, 0x00, 0x00, // 0x2C ','
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, // 0x2D '-'
+ 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, // 0x2E '.'
+ 0x20, 0x10, 0x0C, 0x02, 0x01, 0x00, // 0x2F '/'
+ 0x1E, 0x29, 0x25, 0x23, 0x1E, 0x00, // 0x30 '0'
+ 0x00, 0x22, 0x3F, 0x20, 0x00, 0x00, // 0x31 '1'
+ 0x22, 0x31, 0x29, 0x29, 0x26, 0x00, // 0x32 '2'
+ 0x12, 0x21, 0x25, 0x25, 0x1A, 0x00, // 0x33 '3'
+ 0x18, 0x14, 0x12, 0x3F, 0x10, 0x00, // 0x34 '4'
+ 0x17, 0x25, 0x25, 0x25, 0x18, 0x00, // 0x35 '5'
+ 0x1E, 0x25, 0x25, 0x25, 0x18, 0x00, // 0x36 '6'
+ 0x01, 0x31, 0x09, 0x05, 0x03, 0x00, // 0x37 '7'
+ 0x1A, 0x25, 0x25, 0x25, 0x1A, 0x00, // 0x38 '8'
+ 0x06, 0x29, 0x29, 0x29, 0x1E, 0x00, // 0x39 '9'
+ 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, // 0x3A ':'
+ 0x00, 0x00, 0x33, 0x73, 0x00, 0x00, // 0x3B ';'
+ 0x08, 0x14, 0x14, 0x22, 0x22, 0x00, // 0x3C '<'
+ 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, // 0x3D '='
+ 0x22, 0x22, 0x14, 0x14, 0x08, 0x00, // 0x3E '>'
+ 0x02, 0x01, 0x29, 0x05, 0x02, 0x00, // 0x3F '?'
+ 0x3E, 0x59, 0x55, 0x5D, 0x3E, 0x00, // 0x40 '@'
+ 0x38, 0x16, 0x11, 0x16, 0x38, 0x00, // 0x41 'A'
+ 0x3F, 0x25, 0x25, 0x25, 0x1A, 0x00, // 0x42 'B'
+ 0x1E, 0x21, 0x21, 0x21, 0x12, 0x00, // 0x43 'C'
+ 0x3F, 0x21, 0x21, 0x21, 0x1E, 0x00, // 0x44 'D'
+ 0x3F, 0x25, 0x25, 0x25, 0x21, 0x00, // 0x45 'E'
+ 0x3F, 0x09, 0x09, 0x09, 0x01, 0x00, // 0x46 'F'
+ 0x1E, 0x21, 0x21, 0x29, 0x1A, 0x00, // 0x47 'G'
+ 0x3F, 0x04, 0x04, 0x04, 0x3F, 0x00, // 0x48 'H'
+ 0x00, 0x21, 0x3F, 0x21, 0x00, 0x00, // 0x49 'I'
+ 0x10, 0x20, 0x20, 0x20, 0x1F, 0x00, // 0x4A 'J'
+ 0x3F, 0x04, 0x0C, 0x12, 0x21, 0x00, // 0x4B 'K'
+ 0x3F, 0x20, 0x20, 0x20, 0x20, 0x00, // 0x4C 'L'
+ 0x3F, 0x02, 0x04, 0x02, 0x3F, 0x00, // 0x4D 'M'
+ 0x3F, 0x02, 0x0C, 0x10, 0x3F, 0x00, // 0x4E 'N'
+ 0x1E, 0x21, 0x21, 0x21, 0x1E, 0x00, // 0x4F 'O'
+ 0x3F, 0x09, 0x09, 0x09, 0x06, 0x00, // 0x50 'P'
+ 0x1E, 0x21, 0x29, 0x11, 0x2E, 0x00, // 0x51 'Q'
+ 0x3F, 0x09, 0x09, 0x19, 0x26, 0x00, // 0x52 'R'
+ 0x12, 0x25, 0x25, 0x29, 0x12, 0x00, // 0x53 'S'
+ 0x01, 0x01, 0x3F, 0x01, 0x01, 0x00, // 0x54 'T'
+ 0x1F, 0x20, 0x20, 0x20, 0x1F, 0x00, // 0x55 'U'
+ 0x07, 0x18, 0x20, 0x18, 0x07, 0x00, // 0x56 'V'
+ 0x0F, 0x30, 0x0C, 0x30, 0x0F, 0x00, // 0x57 'W'
+ 0x21, 0x12, 0x0C, 0x12, 0x21, 0x00, // 0x58 'X'
+ 0x03, 0x04, 0x38, 0x04, 0x03, 0x00, // 0x59 'Y'
+ 0x31, 0x29, 0x25, 0x23, 0x21, 0x00, // 0x5A 'Z'
+ 0x00, 0x7F, 0x41, 0x41, 0x00, 0x00, // 0x5B '['
+ 0x01, 0x02, 0x0C, 0x10, 0x20, 0x00, // 0x5C '\'
+ 0x00, 0x41, 0x41, 0x7F, 0x00, 0x00, // 0x5D ']'
+ 0x04, 0x02, 0x01, 0x02, 0x04, 0x00, // 0x5E '^'
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, // 0x5F '_'
+ 0x00, 0x01, 0x03, 0x04, 0x00, 0x00, // 0x60 '`'
+ 0x10, 0x2A, 0x2A, 0x2A, 0x3C, 0x00, // 0x61 'a'
+ 0x3F, 0x24, 0x22, 0x22, 0x1C, 0x00, // 0x62 'b'
+ 0x1C, 0x22, 0x22, 0x22, 0x24, 0x00, // 0x63 'c'
+ 0x1C, 0x22, 0x22, 0x24, 0x3F, 0x00, // 0x64 'd'
+ 0x1C, 0x2A, 0x2A, 0x2A, 0x0C, 0x00, // 0x65 'e'
+ 0x00, 0x04, 0x3E, 0x05, 0x05, 0x00, // 0x66 'f'
+ 0x0C, 0x52, 0x52, 0x54, 0x3E, 0x00, // 0x67 'g'
+ 0x3F, 0x08, 0x04, 0x04, 0x38, 0x00, // 0x68 'h'
+ 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, // 0x69 'i'
+ 0x20, 0x40, 0x40, 0x3D, 0x00, 0x00, // 0x6A 'j'
+ 0x3F, 0x08, 0x08, 0x14, 0x22, 0x00, // 0x6B 'k'
+ 0x00, 0x01, 0x3F, 0x20, 0x00, 0x00, // 0x6C 'l'
+ 0x3E, 0x02, 0x3C, 0x02, 0x3C, 0x00, // 0x6D 'm'
+ 0x3E, 0x04, 0x02, 0x02, 0x3C, 0x00, // 0x6E 'n'
+ 0x1C, 0x22, 0x22, 0x22, 0x1C, 0x00, // 0x6F 'o'
+ 0x7E, 0x14, 0x22, 0x22, 0x1C, 0x00, // 0x70 'p'
+ 0x1C, 0x22, 0x22, 0x14, 0x7E, 0x00, // 0x71 'q'
+ 0x3E, 0x04, 0x02, 0x02, 0x04, 0x00, // 0x72 'r'
+ 0x24, 0x2A, 0x2A, 0x2A, 0x12, 0x00, // 0x73 's'
+ 0x00, 0x02, 0x1F, 0x22, 0x00, 0x00, // 0x74 't'
+ 0x1E, 0x20, 0x20, 0x10, 0x3E, 0x00, // 0x75 'u'
+ 0x06, 0x18, 0x20, 0x18, 0x06, 0x00, // 0x76 'v'
+ 0x0E, 0x30, 0x0C, 0x30, 0x0E, 0x00, // 0x77 'w'
+ 0x22, 0x14, 0x08, 0x14, 0x22, 0x00, // 0x78 'x'
+ 0x0E, 0x50, 0x50, 0x48, 0x3E, 0x00, // 0x79 'y'
+ 0x22, 0x32, 0x2A, 0x26, 0x22, 0x00, // 0x7A 'z'
+ 0x08, 0x08, 0x77, 0x41, 0x41, 0x00, // 0x7B '{'
+ 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, // 0x7C '|'
+ 0x41, 0x41, 0x77, 0x08, 0x08, 0x00, // 0x7D '}'
+ 0x18, 0x04, 0x08, 0x10, 0x0C, 0x00, // 0x7E '~'
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x7F
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Keyball logo
+
+ // Logo 1/3 (0x80 ~ 0x8F)
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC0, 0xF0, 0xF8, 0x8C, 0x86, 0xC6,
+ 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFE, 0xFC, 0xFC, 0xF8, 0xE0,
+ 0x80, 0x00, 0x00, 0x00, 0xF0, 0xF0,
+ 0xF0, 0x00, 0x00, 0xC0, 0xE0, 0xF0,
+ 0x70, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xF8, 0xF8, 0xF8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xF8, 0xF8,
+ 0xF8, 0x00, 0x00, 0xF8, 0xF8, 0xF8,
+
+ // Logo 2/3 (0x90 ~ 0x9F)
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0xE0, 0x70, 0x78, 0x68, 0x6C, 0x64,
+ 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7,
+ 0xE7, 0x3F, 0x1F, 0x0F, 0x3F, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F,
+ 0x0F, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0x1E, 0x3F, 0xFF, 0xF3, 0xE1,
+ 0x80, 0x00, 0x00, 0xF8, 0xFC, 0xFE,
+ 0x36, 0x36, 0x36, 0x3E, 0xBC, 0xB8,
+ 0x00, 0x0E, 0x3E, 0xFE, 0xF0, 0x80,
+ 0xF0, 0xFE, 0x3E, 0x0E, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0x06, 0x06, 0x06,
+ 0xFE, 0xFE, 0xFC, 0x70, 0x00, 0xE6,
+ 0xF6, 0xF6, 0x36, 0x36, 0xFE, 0xFE,
+ 0xFC, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
+
+ // Logo 3/3 (0xA0 ~ 0xAF)
+ 0x00, 0x00, 0x00, 0x00, 0x3C, 0x7F,
+ 0x63, 0x60, 0xE0, 0xC0, 0xC0, 0xC0,
+ 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF,
+ 0xFF, 0xC0, 0x60, 0x30, 0x18, 0x0F,
+ 0x03, 0x03, 0x03, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x03,
+ 0x03, 0x03, 0x00, 0x01, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x01,
+ 0x00, 0x70, 0x70, 0x39, 0x3F, 0x1F,
+ 0x07, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x01, 0x00, 0x00, 0x01,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x03,
+ 0x03, 0x00, 0x00, 0x03, 0x03, 0x03,
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Special characters for Keyball
+
+ // 0xB0
+ 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, // B0: blank indicator (BL)
+ 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, // B1: vertical label separator
+ 0x3E, 0x63, 0x5D, 0x5D, 0x63, 0x7F, // B2, B3:
+ 0x41, 0x7B, 0x77, 0x41, 0x3E, 0x00, // "ON" in 2 chars with light bg.
+ 0x00, 0x1C, 0x22, 0x22, 0x1C, 0x00, // B4, B5:
+ 0x3E, 0x0A, 0x00, 0x3E, 0x0A, 0x00, // "OFF" in 2 chars
+ 0x32, 0x2A, 0x3C, 0x00, 0x26, 0x28, // B6, B7:
+ 0x1E, 0x00, 0x1C, 0x2A, 0x2C, 0x00, // "aye" in 2 chars
+ 0x00, 0x00, 0x3F, 0x09, 0x36, 0x00, // B8: right half "R" indicate "row"
+ 0x00, 0x00, 0x1E, 0x21, 0x21, 0x00, // B9: right halc "C" indicate "column"
+ 0x00, 0x00, 0x00, 0x00, 0x3F, 0x08, // BA, BB:
+ 0x37, 0x00, 0x1E, 0x21, 0x21, 0x00, // "KC" in 2 chars right aligned
+ 0x1E, 0x21, 0x21, 0x00, 0x3F, 0x09, // BC, BD:
+ 0x06, 0x00, 0x21, 0x3F, 0x21, 0x00, // "CPI" in 2 chars
+ 0x22, 0x25, 0x19, 0x00, 0x1E, 0x21, // BE, BF:
+ 0x21, 0x00, 0x3F, 0x09, 0x36, 0x00, // "SCR" in 2 chars indicate "scroll"
+
+ // 0xC0
+ 0x3F, 0x21, 0x1E, 0x00, 0x21, 0x3F, // C0, C1:
+ 0x21, 0x00, 0x0F, 0x30, 0x0F, 0x00, // "DIV" in 2 chars indicate "divider"
+ 0x3E, 0x09, 0x3E, 0x00, 0x3F, 0x06, // C2, C3:
+ 0x3F, 0x00, 0x3F, 0x20, 0x20, 0x00, // "AML" in 2 chars
+};
+// clang-format on
diff --git a/keyboards/yowkees/lib/oledkit/oledkit.c b/keyboards/yowkees/lib/oledkit/oledkit.c
new file mode 100644
index 00000000000..04e67517a9e
--- /dev/null
+++ b/keyboards/yowkees/lib/oledkit/oledkit.c
@@ -0,0 +1,61 @@
+/*
+Copyright 2021 @Yowkees
+Copyright 2021 MURAOKA Taro (aka KoRoN, @kaoriya)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include "quantum.h"
+
+#if defined(OLED_ENABLE) && !defined(OLEDKIT_DISABLE)
+
+__attribute__((weak)) void oledkit_render_logo_user(void) {
+ // Require `OLED_FONT_H "keyboards/keyball/lib/logofont/logofont.c"`
+ char ch = 0x80;
+ for (int y = 0; y < 3; y++) {
+ oled_write_P(PSTR(" "), false);
+ for (int x = 0; x < 16; x++) {
+ oled_write_char(ch++, false);
+ }
+ oled_advance_page(false);
+ }
+}
+
+__attribute__((weak)) void oledkit_render_info_user(void) {
+ oledkit_render_logo_user();
+}
+
+__attribute__((weak)) bool oled_task_user(void) {
+ if (is_keyboard_master()) {
+ oledkit_render_info_user();
+ } else {
+ oledkit_render_logo_user();
+ }
+ return true;
+}
+
+__attribute__((weak)) oled_rotation_t oled_init_user(oled_rotation_t rotation) {
+ // Logo needs to be rotated 180 degrees.
+ //
+ // A typical OLED has a narrow margin on the left side near the origin, and
+ // a wide margin on the right side. The Keyball logo consists of three
+ // lines. If the logo is displayed on an OLED consisting of four lines, the
+ // margin on the right side will be too large and the balance is not good.
+ //
+ // Additionally, by rotating it, the left side of the logo will be above
+ // the OLED screen, giving it a natural look.
+ return !is_keyboard_master() ? OLED_ROTATION_180 : rotation;
+}
+
+#endif // OLED_ENABLE
diff --git a/keyboards/yowkees/lib/oledkit/oledkit.h b/keyboards/yowkees/lib/oledkit/oledkit.h
new file mode 100644
index 00000000000..c8865eb4525
--- /dev/null
+++ b/keyboards/yowkees/lib/oledkit/oledkit.h
@@ -0,0 +1,34 @@
+/*
+Copyright 2021 @Yowkees
+Copyright 2021 MURAOKA Taro (aka KoRoN, @kaoriya)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#pragma once
+
+#if defined(OLED_ENABLE) && !defined(OLEDKIT_DISABLE)
+
+// oledkit_render_info_user renders keyboard's internal state information to
+// primary board. A keymap can override this by defining a function with same
+// signature.
+//
+// It render a logo as default.
+void oledkit_render_info_user(void);
+
+// oledkit_render_logo_user renders a logo of keyboard to secondary board.
+// A keymap can override this by defining a function with same signature.
+void oledkit_render_logo_user(void);
+
+#endif // OLED_ENABLE
From ee7a826d3ac1e8c14ee0dfed737b5bccec747d96 Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Mon, 3 Jun 2024 18:12:28 -0700
Subject: [PATCH 02/32] Update keyball struct
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fixes a complation error in `yowkees/lib/keyball/keyball.c`:
```
Compiling: keyboards/yowkees/lib/keyball/keyball.c keyboards/yowkees/lib/keyball/keyball.c:54:24: error: initializer element is not constant
.pressing_keys = { BL, BL, BL, BL, BL, BL, 0 },
^
keyboards/yowkees/lib/keyball/keyball.c:54:24: note: (near initialization for ‘keyball.pressing_keys[0]’)
keyboards/yowkees/lib/keyball/keyball.c:54:28: error: initializer element is not constant
.pressing_keys = { BL, BL, BL, BL, BL, BL, 0 },
^
keyboards/yowkees/lib/keyball/keyball.c:54:28: note: (near initialization for ‘keyball.pressing_keys[1]’)
keyboards/yowkees/lib/keyball/keyball.c:54:32: error: initializer element is not constant
.pressing_keys = { BL, BL, BL, BL, BL, BL, 0 },
^
keyboards/yowkees/lib/keyball/keyball.c:54:32: note: (near initialization for ‘keyball.pressing_keys[2]’)
keyboards/yowkees/lib/keyball/keyball.c:54:36: error: initializer element is not constant
.pressing_keys = { BL, BL, BL, BL, BL, BL, 0 },
^
keyboards/yowkees/lib/keyball/keyball.c:54:36: note: (near initialization for ‘keyball.pressing_keys[3]’)
keyboards/yowkees/lib/keyball/keyball.c:54:40: error: initializer element is not constant
.pressing_keys = { BL, BL, BL, BL, BL, BL, 0 },
^
keyboards/yowkees/lib/keyball/keyball.c:54:40: note: (near initialization for ‘keyball.pressing_keys[4]’)
keyboards/yowkees/lib/keyball/keyball.c:54:44: error: initializer element is not constant
.pressing_keys = { BL, BL, BL, BL, BL, BL, 0 },
^
keyboards/yowkees/lib/keyball/keyball.c:54:44: note: (near initialization for ‘keyball.pressing_keys[5]’)
[ERRORS]
|
|
|
gmake: *** [builddefs/common_rules.mk:373: .build/obj_yowkees_keyball39_default/lib/keyball/keyball.o] Error 1
gmake: *** Waiting for unfinished jobs....
```
---
keyboards/yowkees/lib/keyball/keyball.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/keyboards/yowkees/lib/keyball/keyball.c b/keyboards/yowkees/lib/keyball/keyball.c
index 07efac7a7df..8faaad1ef45 100644
--- a/keyboards/yowkees/lib/keyball/keyball.c
+++ b/keyboards/yowkees/lib/keyball/keyball.c
@@ -51,7 +51,7 @@ keyball_t keyball = {
.scroll_mode = false,
.scroll_div = 0,
- .pressing_keys = { BL, BL, BL, BL, BL, BL, 0 },
+ .pressing_keys = { '\xB0', '\xB0', '\xB0', '\xB0', '\xB0', '\xB0', 0 },
};
//////////////////////////////////////////////////////////////////////////////
From 1a520b58901579d03e1366c10db32d7d64da5c53 Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Mon, 3 Jun 2024 18:22:57 -0700
Subject: [PATCH 03/32] Update `OLED_FONT_H`
Update to fix a compilation error caused by changing the "vendor"
directory on the initial bring-up. (Source repository uses
`keyboards/keyball/`, but this branch uses `keyboards/yowkees/`.)
```
Compiling: drivers/oled/oled_driver.c drivers/oled/oled_driver.c:27:21: fatal error: keyboards/keyball/lib/logofont/logofont.c: No such file or directory
compilation terminated.
[ERRORS]
|
|
|
gmake: *** [builddefs/common_rules.mk:373: .build/obj_yowkees_keyball39_default/oled_driver.o] Error 1
gmake: *** Waiting for unfinished jobs....
```
---
keyboards/yowkees/keyball39/config.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/keyboards/yowkees/keyball39/config.h b/keyboards/yowkees/keyball39/config.h
index 83441bf6060..00c426a0de9 100644
--- a/keyboards/yowkees/keyball39/config.h
+++ b/keyboards/yowkees/keyball39/config.h
@@ -65,7 +65,7 @@ along with this program. If not, see .
#endif
#ifndef OLED_FONT_H
-# define OLED_FONT_H "keyboards/keyball/lib/logofont/logofont.c"
+# define OLED_FONT_H "../lib/logofont/logofont.c"
# define OLED_FONT_START 32
# define OLED_FONT_END 195
#endif
From e3630cdbb2fd054da1196f42e2cf14d5a17c9539 Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Mon, 3 Jun 2024 18:51:00 -0700
Subject: [PATCH 04/32] Format `info.json`
---
keyboards/yowkees/keyball39/info.json | 95 +++++++++++++--------------
1 file changed, 46 insertions(+), 49 deletions(-)
diff --git a/keyboards/yowkees/keyball39/info.json b/keyboards/yowkees/keyball39/info.json
index 163269d8466..ae6a49ee19f 100644
--- a/keyboards/yowkees/keyball39/info.json
+++ b/keyboards/yowkees/keyball39/info.json
@@ -10,54 +10,51 @@
"driver": "ws2812"
},
"layouts": {
- "LAYOUT_no_ball": {
- "layout": [
- { "label": "L00", "x": 0, "y": 0 },
- { "label": "L01", "x": 1, "y": 0 },
- { "label": "L02", "x": 2, "y": 0 },
- { "label": "L03", "x": 3, "y": 0 },
- { "label": "L04", "x": 4, "y": 0 },
- { "label": "R04", "x": 7, "y": 0 },
- { "label": "R03", "x": 8, "y": 0 },
- { "label": "R02", "x": 9, "y": 0 },
- { "label": "R01", "x":10, "y": 0 },
- { "label": "R00", "x":11, "y": 0 },
-
- { "label": "L10", "x": 0, "y": 1 },
- { "label": "L11", "x": 1, "y": 1 },
- { "label": "L12", "x": 2, "y": 1 },
- { "label": "L13", "x": 3, "y": 1 },
- { "label": "L14", "x": 4, "y": 1 },
- { "label": "R14", "x": 7, "y": 1 },
- { "label": "R13", "x": 8, "y": 1 },
- { "label": "R12", "x": 9, "y": 1 },
- { "label": "R11", "x":10, "y": 1 },
- { "label": "R10", "x":11, "y": 1 },
-
- { "label": "L20", "x": 0, "y": 2 },
- { "label": "L21", "x": 1, "y": 2 },
- { "label": "L22", "x": 2, "y": 2 },
- { "label": "L23", "x": 3, "y": 2 },
- { "label": "L24", "x": 4, "y": 2 },
- { "label": "R24", "x": 7, "y": 2 },
- { "label": "R23", "x": 8, "y": 2 },
- { "label": "R22", "x": 9, "y": 2 },
- { "label": "R21", "x":10, "y": 2 },
- { "label": "R20", "x":11, "y": 2 },
-
- { "label": "L30", "x": 0, "y": 3 },
- { "label": "L31", "x": 1, "y": 3 },
- { "label": "L32", "x": 2, "y": 3 },
- { "label": "L33", "x": 3, "y": 3 },
- { "label": "L34", "x": 4, "y": 3 },
- { "label": "L35", "x": 5, "y": 3 },
- { "label": "R35", "x": 6, "y": 3 },
- { "label": "R34", "x": 7, "y": 3 },
- { "label": "R33", "x": 8, "y": 3 },
- { "label": "R32", "x": 9, "y": 3 },
- { "label": "R31", "x":10, "y": 3 },
- { "label": "R30", "x":11, "y": 3 }
- ]
- }
+ "LAYOUT_no_ball": {
+ "layout": [
+ {"label": "L00", "x": 0, "y": 0},
+ {"label": "L01", "x": 1, "y": 0},
+ {"label": "L02", "x": 2, "y": 0},
+ {"label": "L03", "x": 3, "y": 0},
+ {"label": "L04", "x": 4, "y": 0},
+ {"label": "R04", "x": 7, "y": 0},
+ {"label": "R03", "x": 8, "y": 0},
+ {"label": "R02", "x": 9, "y": 0},
+ {"label": "R01", "x": 10, "y": 0},
+ {"label": "R00", "x": 11, "y": 0},
+ {"label": "L10", "x": 0, "y": 1},
+ {"label": "L11", "x": 1, "y": 1},
+ {"label": "L12", "x": 2, "y": 1},
+ {"label": "L13", "x": 3, "y": 1},
+ {"label": "L14", "x": 4, "y": 1},
+ {"label": "R14", "x": 7, "y": 1},
+ {"label": "R13", "x": 8, "y": 1},
+ {"label": "R12", "x": 9, "y": 1},
+ {"label": "R11", "x": 10, "y": 1},
+ {"label": "R10", "x": 11, "y": 1},
+ {"label": "L20", "x": 0, "y": 2},
+ {"label": "L21", "x": 1, "y": 2},
+ {"label": "L22", "x": 2, "y": 2},
+ {"label": "L23", "x": 3, "y": 2},
+ {"label": "L24", "x": 4, "y": 2},
+ {"label": "R24", "x": 7, "y": 2},
+ {"label": "R23", "x": 8, "y": 2},
+ {"label": "R22", "x": 9, "y": 2},
+ {"label": "R21", "x": 10, "y": 2},
+ {"label": "R20", "x": 11, "y": 2},
+ {"label": "L30", "x": 0, "y": 3},
+ {"label": "L31", "x": 1, "y": 3},
+ {"label": "L32", "x": 2, "y": 3},
+ {"label": "L33", "x": 3, "y": 3},
+ {"label": "L34", "x": 4, "y": 3},
+ {"label": "L35", "x": 5, "y": 3},
+ {"label": "R35", "x": 6, "y": 3},
+ {"label": "R34", "x": 7, "y": 3},
+ {"label": "R33", "x": 8, "y": 3},
+ {"label": "R32", "x": 9, "y": 3},
+ {"label": "R31", "x": 10, "y": 3},
+ {"label": "R30", "x": 11, "y": 3}
+ ]
+ }
}
}
From 09d9486052bed85d4aea26a92aa1d3980af17e52 Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Mon, 3 Jun 2024 18:57:26 -0700
Subject: [PATCH 05/32] Add layout data to `info.json`
---
keyboards/yowkees/keyball39/info.json | 82 +++++++++++++--------------
1 file changed, 41 insertions(+), 41 deletions(-)
diff --git a/keyboards/yowkees/keyball39/info.json b/keyboards/yowkees/keyball39/info.json
index ae6a49ee19f..fdd7f9423b6 100644
--- a/keyboards/yowkees/keyball39/info.json
+++ b/keyboards/yowkees/keyball39/info.json
@@ -12,48 +12,48 @@
"layouts": {
"LAYOUT_no_ball": {
"layout": [
- {"label": "L00", "x": 0, "y": 0},
- {"label": "L01", "x": 1, "y": 0},
+ {"label": "L00", "x": 0, "y": 0.6},
+ {"label": "L01", "x": 1, "y": 0.25},
{"label": "L02", "x": 2, "y": 0},
- {"label": "L03", "x": 3, "y": 0},
- {"label": "L04", "x": 4, "y": 0},
- {"label": "R04", "x": 7, "y": 0},
- {"label": "R03", "x": 8, "y": 0},
- {"label": "R02", "x": 9, "y": 0},
- {"label": "R01", "x": 10, "y": 0},
- {"label": "R00", "x": 11, "y": 0},
- {"label": "L10", "x": 0, "y": 1},
- {"label": "L11", "x": 1, "y": 1},
- {"label": "L12", "x": 2, "y": 1},
- {"label": "L13", "x": 3, "y": 1},
- {"label": "L14", "x": 4, "y": 1},
- {"label": "R14", "x": 7, "y": 1},
- {"label": "R13", "x": 8, "y": 1},
- {"label": "R12", "x": 9, "y": 1},
- {"label": "R11", "x": 10, "y": 1},
- {"label": "R10", "x": 11, "y": 1},
- {"label": "L20", "x": 0, "y": 2},
- {"label": "L21", "x": 1, "y": 2},
- {"label": "L22", "x": 2, "y": 2},
- {"label": "L23", "x": 3, "y": 2},
- {"label": "L24", "x": 4, "y": 2},
- {"label": "R24", "x": 7, "y": 2},
- {"label": "R23", "x": 8, "y": 2},
- {"label": "R22", "x": 9, "y": 2},
- {"label": "R21", "x": 10, "y": 2},
- {"label": "R20", "x": 11, "y": 2},
- {"label": "L30", "x": 0, "y": 3},
- {"label": "L31", "x": 1, "y": 3},
- {"label": "L32", "x": 2, "y": 3},
- {"label": "L33", "x": 3, "y": 3},
- {"label": "L34", "x": 4, "y": 3},
- {"label": "L35", "x": 5, "y": 3},
- {"label": "R35", "x": 6, "y": 3},
- {"label": "R34", "x": 7, "y": 3},
- {"label": "R33", "x": 8, "y": 3},
- {"label": "R32", "x": 9, "y": 3},
- {"label": "R31", "x": 10, "y": 3},
- {"label": "R30", "x": 11, "y": 3}
+ {"label": "L03", "x": 3, "y": 0.125},
+ {"label": "L04", "x": 4, "y": 0.25},
+ {"label": "R04", "x": 9, "y": 0.25},
+ {"label": "R03", "x": 10, "y": 0.125},
+ {"label": "R02", "x": 11, "y": 0},
+ {"label": "R01", "x": 12, "y": 0.25},
+ {"label": "R00", "x": 13, "y": 0.6},
+ {"label": "L10", "x": 0, "y": 1.6},
+ {"label": "L11", "x": 1, "y": 1.25},
+ {"label": "L12", "x": 2, "y": 1.0},
+ {"label": "L13", "x": 3, "y": 1.125},
+ {"label": "L14", "x": 4, "y": 1.25},
+ {"label": "R14", "x": 9, "y": 1.25},
+ {"label": "R13", "x": 10, "y": 1.125},
+ {"label": "R12", "x": 11, "y": 1.0},
+ {"label": "R11", "x": 12, "y": 1.25},
+ {"label": "R10", "x": 13, "y": 1.6},
+ {"label": "L20", "x": 0, "y": 2.6},
+ {"label": "L21", "x": 1, "y": 2.25},
+ {"label": "L22", "x": 2, "y": 2.0},
+ {"label": "L23", "x": 3, "y": 2.125},
+ {"label": "L24", "x": 4, "y": 2.25},
+ {"label": "R24", "x": 9, "y": 2.25},
+ {"label": "R23", "x": 10, "y": 2.125},
+ {"label": "R22", "x": 11, "y": 2.0},
+ {"label": "R21", "x": 12, "y": 2.25},
+ {"label": "R20", "x": 13, "y": 2.6},
+ {"label": "L30", "x": 0, "y": 3.6},
+ {"label": "L31", "x": 1, "y": 3.25},
+ {"label": "L32", "x": 2, "y": 3.0},
+ {"label": "L33", "x": 3.15, "y": 3.5},
+ {"label": "L34", "x": 4.25, "y": 3.61},
+ {"label": "L35", "x": 5.38, "y": 3.86},
+ {"label": "R35", "x": 7.62, "y": 3.86},
+ {"label": "R34", "x": 8.75, "y": 3.61},
+ {"label": "R33", "x": 9.85, "y": 3.5},
+ {"label": "R32", "x": 11, "y": 3.0},
+ {"label": "R31", "x": 12, "y": 3.25},
+ {"label": "R30", "x": 13, "y": 3.6}
]
}
}
From 5122953194231e570aa8cea85275b3b5c50df22e Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Mon, 3 Jun 2024 19:04:38 -0700
Subject: [PATCH 06/32] Convert `LAYOUT_no_ball` to data-driven
---
keyboards/yowkees/keyball39/info.json | 84 ++++++++++++-------------
keyboards/yowkees/keyball39/keyball39.h | 16 -----
2 files changed, 42 insertions(+), 58 deletions(-)
diff --git a/keyboards/yowkees/keyball39/info.json b/keyboards/yowkees/keyball39/info.json
index fdd7f9423b6..2fd406d1341 100644
--- a/keyboards/yowkees/keyball39/info.json
+++ b/keyboards/yowkees/keyball39/info.json
@@ -12,48 +12,48 @@
"layouts": {
"LAYOUT_no_ball": {
"layout": [
- {"label": "L00", "x": 0, "y": 0.6},
- {"label": "L01", "x": 1, "y": 0.25},
- {"label": "L02", "x": 2, "y": 0},
- {"label": "L03", "x": 3, "y": 0.125},
- {"label": "L04", "x": 4, "y": 0.25},
- {"label": "R04", "x": 9, "y": 0.25},
- {"label": "R03", "x": 10, "y": 0.125},
- {"label": "R02", "x": 11, "y": 0},
- {"label": "R01", "x": 12, "y": 0.25},
- {"label": "R00", "x": 13, "y": 0.6},
- {"label": "L10", "x": 0, "y": 1.6},
- {"label": "L11", "x": 1, "y": 1.25},
- {"label": "L12", "x": 2, "y": 1.0},
- {"label": "L13", "x": 3, "y": 1.125},
- {"label": "L14", "x": 4, "y": 1.25},
- {"label": "R14", "x": 9, "y": 1.25},
- {"label": "R13", "x": 10, "y": 1.125},
- {"label": "R12", "x": 11, "y": 1.0},
- {"label": "R11", "x": 12, "y": 1.25},
- {"label": "R10", "x": 13, "y": 1.6},
- {"label": "L20", "x": 0, "y": 2.6},
- {"label": "L21", "x": 1, "y": 2.25},
- {"label": "L22", "x": 2, "y": 2.0},
- {"label": "L23", "x": 3, "y": 2.125},
- {"label": "L24", "x": 4, "y": 2.25},
- {"label": "R24", "x": 9, "y": 2.25},
- {"label": "R23", "x": 10, "y": 2.125},
- {"label": "R22", "x": 11, "y": 2.0},
- {"label": "R21", "x": 12, "y": 2.25},
- {"label": "R20", "x": 13, "y": 2.6},
- {"label": "L30", "x": 0, "y": 3.6},
- {"label": "L31", "x": 1, "y": 3.25},
- {"label": "L32", "x": 2, "y": 3.0},
- {"label": "L33", "x": 3.15, "y": 3.5},
- {"label": "L34", "x": 4.25, "y": 3.61},
- {"label": "L35", "x": 5.38, "y": 3.86},
- {"label": "R35", "x": 7.62, "y": 3.86},
- {"label": "R34", "x": 8.75, "y": 3.61},
- {"label": "R33", "x": 9.85, "y": 3.5},
- {"label": "R32", "x": 11, "y": 3.0},
- {"label": "R31", "x": 12, "y": 3.25},
- {"label": "R30", "x": 13, "y": 3.6}
+ {"matrix": [0, 0], "x": 0, "y": 0.6},
+ {"matrix": [0, 1], "x": 1, "y": 0.25},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0.125},
+ {"matrix": [0, 4], "x": 4, "y": 0.25},
+ {"matrix": [4, 4], "x": 9, "y": 0.25},
+ {"matrix": [4, 3], "x": 10, "y": 0.125},
+ {"matrix": [4, 2], "x": 11, "y": 0},
+ {"matrix": [4, 1], "x": 12, "y": 0.25},
+ {"matrix": [4, 0], "x": 13, "y": 0.6},
+ {"matrix": [1, 0], "x": 0, "y": 1.6},
+ {"matrix": [1, 1], "x": 1, "y": 1.25},
+ {"matrix": [1, 2], "x": 2, "y": 1.0},
+ {"matrix": [1, 3], "x": 3, "y": 1.125},
+ {"matrix": [1, 4], "x": 4, "y": 1.25},
+ {"matrix": [5, 4], "x": 9, "y": 1.25},
+ {"matrix": [5, 3], "x": 10, "y": 1.125},
+ {"matrix": [5, 2], "x": 11, "y": 1.0},
+ {"matrix": [5, 1], "x": 12, "y": 1.25},
+ {"matrix": [5, 0], "x": 13, "y": 1.6},
+ {"matrix": [2, 0], "x": 0, "y": 2.6},
+ {"matrix": [2, 1], "x": 1, "y": 2.25},
+ {"matrix": [2, 2], "x": 2, "y": 2.0},
+ {"matrix": [2, 3], "x": 3, "y": 2.125},
+ {"matrix": [2, 4], "x": 4, "y": 2.25},
+ {"matrix": [6, 4], "x": 9, "y": 2.25},
+ {"matrix": [6, 3], "x": 10, "y": 2.125},
+ {"matrix": [6, 2], "x": 11, "y": 2.0},
+ {"matrix": [6, 1], "x": 12, "y": 2.25},
+ {"matrix": [6, 0], "x": 13, "y": 2.6},
+ {"matrix": [3, 0], "x": 0, "y": 3.6},
+ {"matrix": [3, 1], "x": 1, "y": 3.25},
+ {"matrix": [3, 2], "x": 2, "y": 3.0},
+ {"matrix": [3, 3], "x": 3.15, "y": 3.5},
+ {"matrix": [3, 4], "x": 4.25, "y": 3.61},
+ {"matrix": [3, 5], "x": 5.38, "y": 3.86},
+ {"matrix": [7, 5], "x": 7.62, "y": 3.86},
+ {"matrix": [7, 4], "x": 8.75, "y": 3.61},
+ {"matrix": [7, 3], "x": 9.85, "y": 3.5},
+ {"matrix": [7, 2], "x": 11, "y": 3.0},
+ {"matrix": [7, 1], "x": 12, "y": 3.25},
+ {"matrix": [7, 0], "x": 13, "y": 3.6}
]
}
}
diff --git a/keyboards/yowkees/keyball39/keyball39.h b/keyboards/yowkees/keyball39/keyball39.h
index a2555e0b502..1247e8ddf88 100644
--- a/keyboards/yowkees/keyball39/keyball39.h
+++ b/keyboards/yowkees/keyball39/keyball39.h
@@ -74,22 +74,6 @@ along with this program. If not, see .
{ R30, KC_NO, KC_NO, KC_NO, R34, R35 }, \
}
-#define LAYOUT_no_ball( \
- L00, L01, L02, L03, L04, R04, R03, R02, R01, R00, \
- L10, L11, L12, L13, L14, R14, R13, R12, R11, R10, \
- L20, L21, L22, L23, L24, R24, R23, R22, R21, R20, \
- L30, L31, L32, L33, L34, L35, R35, R34, R33, R32, R31, R30 \
- ) \
- { \
- { L00, L01, L02, L03, L04, KC_NO }, \
- { L10, L11, L12, L13, L14, KC_NO }, \
- { L20, L21, L22, L23, L24, KC_NO }, \
- { L30, L31, L32, L33, L34, L35 }, \
- { R00, R01, R02, R03, R04, KC_NO }, \
- { R10, R11, R12, R13, R14, KC_NO }, \
- { R20, R21, R22, R23, R24, KC_NO }, \
- { R30, R31, R32, R33, R34, R35 }, \
- }
// clang-format on
From 61577fc643bafcfe9a8d61152dbb5b6e5fd09fbb Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Mon, 3 Jun 2024 19:07:18 -0700
Subject: [PATCH 07/32] Convert `LAYOUT_left_ball` to data-driven
---
keyboards/yowkees/keyball39/info.json | 43 +++++++++++++++++++++++++
keyboards/yowkees/keyball39/keyball39.h | 16 ---------
2 files changed, 43 insertions(+), 16 deletions(-)
diff --git a/keyboards/yowkees/keyball39/info.json b/keyboards/yowkees/keyball39/info.json
index 2fd406d1341..233f2b8ea06 100644
--- a/keyboards/yowkees/keyball39/info.json
+++ b/keyboards/yowkees/keyball39/info.json
@@ -55,6 +55,49 @@
{"matrix": [7, 1], "x": 12, "y": 3.25},
{"matrix": [7, 0], "x": 13, "y": 3.6}
]
+ },
+ "LAYOUT_left_ball": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0.6},
+ {"matrix": [0, 1], "x": 1, "y": 0.25},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0.125},
+ {"matrix": [0, 4], "x": 4, "y": 0.25},
+ {"matrix": [4, 4], "x": 9, "y": 0.25},
+ {"matrix": [4, 3], "x": 10, "y": 0.125},
+ {"matrix": [4, 2], "x": 11, "y": 0},
+ {"matrix": [4, 1], "x": 12, "y": 0.25},
+ {"matrix": [4, 0], "x": 13, "y": 0.6},
+ {"matrix": [1, 0], "x": 0, "y": 1.6},
+ {"matrix": [1, 1], "x": 1, "y": 1.25},
+ {"matrix": [1, 2], "x": 2, "y": 1.0},
+ {"matrix": [1, 3], "x": 3, "y": 1.125},
+ {"matrix": [1, 4], "x": 4, "y": 1.25},
+ {"matrix": [5, 4], "x": 9, "y": 1.25},
+ {"matrix": [5, 3], "x": 10, "y": 1.125},
+ {"matrix": [5, 2], "x": 11, "y": 1.0},
+ {"matrix": [5, 1], "x": 12, "y": 1.25},
+ {"matrix": [5, 0], "x": 13, "y": 1.6},
+ {"matrix": [2, 0], "x": 0, "y": 2.6},
+ {"matrix": [2, 1], "x": 1, "y": 2.25},
+ {"matrix": [2, 2], "x": 2, "y": 2.0},
+ {"matrix": [2, 3], "x": 3, "y": 2.125},
+ {"matrix": [2, 4], "x": 4, "y": 2.25},
+ {"matrix": [6, 4], "x": 9, "y": 2.25},
+ {"matrix": [6, 3], "x": 10, "y": 2.125},
+ {"matrix": [6, 2], "x": 11, "y": 2.0},
+ {"matrix": [6, 1], "x": 12, "y": 2.25},
+ {"matrix": [6, 0], "x": 13, "y": 2.6},
+ {"matrix": [3, 0], "x": 0, "y": 3.6},
+ {"matrix": [3, 4], "x": 4.25, "y": 3.61},
+ {"matrix": [3, 5], "x": 5.38, "y": 3.86},
+ {"matrix": [7, 5], "x": 7.62, "y": 3.86},
+ {"matrix": [7, 4], "x": 8.75, "y": 3.61},
+ {"matrix": [7, 3], "x": 9.85, "y": 3.5},
+ {"matrix": [7, 2], "x": 11, "y": 3.0},
+ {"matrix": [7, 1], "x": 12, "y": 3.25},
+ {"matrix": [7, 0], "x": 13, "y": 3.6}
+ ]
}
}
}
diff --git a/keyboards/yowkees/keyball39/keyball39.h b/keyboards/yowkees/keyball39/keyball39.h
index 1247e8ddf88..e3d15baa3cf 100644
--- a/keyboards/yowkees/keyball39/keyball39.h
+++ b/keyboards/yowkees/keyball39/keyball39.h
@@ -40,22 +40,6 @@ along with this program. If not, see .
{ R30, KC_NO, KC_NO, KC_NO, R34, R35 }, \
}
-#define LAYOUT_left_ball( \
- L00, L01, L02, L03, L04, R04, R03, R02, R01, R00, \
- L10, L11, L12, L13, L14, R14, R13, R12, R11, R10, \
- L20, L21, L22, L23, L24, R24, R23, R22, R21, R20, \
- L30, L34, L35, R35, R34, R33, R32, R31, R30 \
- ) \
- { \
- { L00, L01, L02, L03, L04, KC_NO }, \
- { L10, L11, L12, L13, L14, KC_NO }, \
- { L20, L21, L22, L23, L24, KC_NO }, \
- { L30, KC_NO, KC_NO, KC_NO, L34, L35 }, \
- { R00, R01, R02, R03, R04, KC_NO }, \
- { R10, R11, R12, R13, R14, KC_NO }, \
- { R20, R21, R22, R23, R24, KC_NO }, \
- { R30, R31, R32, R33, R34, R35 }, \
- }
#define LAYOUT_dual_ball( \
L00, L01, L02, L03, L04, R04, R03, R02, R01, R00, \
From 3ffd5f9a410b780ac89b5ac9c3212bab0f70880e Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Mon, 3 Jun 2024 19:08:28 -0700
Subject: [PATCH 08/32] Convert `LAYOUT_right_ball` to data-driven
---
keyboards/yowkees/keyball39/info.json | 43 +++++++++++++++++++++++++
keyboards/yowkees/keyball39/keyball39.h | 16 ---------
2 files changed, 43 insertions(+), 16 deletions(-)
diff --git a/keyboards/yowkees/keyball39/info.json b/keyboards/yowkees/keyball39/info.json
index 233f2b8ea06..4c2022aafd8 100644
--- a/keyboards/yowkees/keyball39/info.json
+++ b/keyboards/yowkees/keyball39/info.json
@@ -98,6 +98,49 @@
{"matrix": [7, 1], "x": 12, "y": 3.25},
{"matrix": [7, 0], "x": 13, "y": 3.6}
]
+ },
+ "LAYOUT_right_ball": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0.6},
+ {"matrix": [0, 1], "x": 1, "y": 0.25},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0.125},
+ {"matrix": [0, 4], "x": 4, "y": 0.25},
+ {"matrix": [4, 4], "x": 9, "y": 0.25},
+ {"matrix": [4, 3], "x": 10, "y": 0.125},
+ {"matrix": [4, 2], "x": 11, "y": 0},
+ {"matrix": [4, 1], "x": 12, "y": 0.25},
+ {"matrix": [4, 0], "x": 13, "y": 0.6},
+ {"matrix": [1, 0], "x": 0, "y": 1.6},
+ {"matrix": [1, 1], "x": 1, "y": 1.25},
+ {"matrix": [1, 2], "x": 2, "y": 1.0},
+ {"matrix": [1, 3], "x": 3, "y": 1.125},
+ {"matrix": [1, 4], "x": 4, "y": 1.25},
+ {"matrix": [5, 4], "x": 9, "y": 1.25},
+ {"matrix": [5, 3], "x": 10, "y": 1.125},
+ {"matrix": [5, 2], "x": 11, "y": 1.0},
+ {"matrix": [5, 1], "x": 12, "y": 1.25},
+ {"matrix": [5, 0], "x": 13, "y": 1.6},
+ {"matrix": [2, 0], "x": 0, "y": 2.6},
+ {"matrix": [2, 1], "x": 1, "y": 2.25},
+ {"matrix": [2, 2], "x": 2, "y": 2.0},
+ {"matrix": [2, 3], "x": 3, "y": 2.125},
+ {"matrix": [2, 4], "x": 4, "y": 2.25},
+ {"matrix": [6, 4], "x": 9, "y": 2.25},
+ {"matrix": [6, 3], "x": 10, "y": 2.125},
+ {"matrix": [6, 2], "x": 11, "y": 2.0},
+ {"matrix": [6, 1], "x": 12, "y": 2.25},
+ {"matrix": [6, 0], "x": 13, "y": 2.6},
+ {"matrix": [3, 0], "x": 0, "y": 3.6},
+ {"matrix": [3, 1], "x": 1, "y": 3.25},
+ {"matrix": [3, 2], "x": 2, "y": 3.0},
+ {"matrix": [3, 3], "x": 3.15, "y": 3.5},
+ {"matrix": [3, 4], "x": 4.25, "y": 3.61},
+ {"matrix": [3, 5], "x": 5.38, "y": 3.86},
+ {"matrix": [7, 5], "x": 7.62, "y": 3.86},
+ {"matrix": [7, 4], "x": 8.75, "y": 3.61},
+ {"matrix": [7, 0], "x": 13, "y": 3.6}
+ ]
}
}
}
diff --git a/keyboards/yowkees/keyball39/keyball39.h b/keyboards/yowkees/keyball39/keyball39.h
index e3d15baa3cf..2f322e69b59 100644
--- a/keyboards/yowkees/keyball39/keyball39.h
+++ b/keyboards/yowkees/keyball39/keyball39.h
@@ -23,22 +23,6 @@ along with this program. If not, see .
// clang-format off
-#define LAYOUT_right_ball( \
- L00, L01, L02, L03, L04, R04, R03, R02, R01, R00, \
- L10, L11, L12, L13, L14, R14, R13, R12, R11, R10, \
- L20, L21, L22, L23, L24, R24, R23, R22, R21, R20, \
- L30, L31, L32, L33, L34, L35, R35, R34, R30 \
- ) \
- { \
- { L00, L01, L02, L03, L04, KC_NO }, \
- { L10, L11, L12, L13, L14, KC_NO }, \
- { L20, L21, L22, L23, L24, KC_NO }, \
- { L30, L31, L32, L33, L34, L35 }, \
- { R00, R01, R02, R03, R04, KC_NO }, \
- { R10, R11, R12, R13, R14, KC_NO }, \
- { R20, R21, R22, R23, R24, KC_NO }, \
- { R30, KC_NO, KC_NO, KC_NO, R34, R35 }, \
- }
#define LAYOUT_dual_ball( \
From bbfb5cc2cd8b8a9117f8df020b9300e312bb8c4f Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Mon, 3 Jun 2024 19:09:49 -0700
Subject: [PATCH 09/32] Convert `LAYOUT_dual_ball` to data-driven
---
keyboards/yowkees/keyball39/info.json | 40 +++++++++++++++++++++++++
keyboards/yowkees/keyball39/keyball39.h | 24 ---------------
2 files changed, 40 insertions(+), 24 deletions(-)
diff --git a/keyboards/yowkees/keyball39/info.json b/keyboards/yowkees/keyball39/info.json
index 4c2022aafd8..7b40dcd6be7 100644
--- a/keyboards/yowkees/keyball39/info.json
+++ b/keyboards/yowkees/keyball39/info.json
@@ -141,6 +141,46 @@
{"matrix": [7, 4], "x": 8.75, "y": 3.61},
{"matrix": [7, 0], "x": 13, "y": 3.6}
]
+ },
+ "LAYOUT_dual_ball": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0.6},
+ {"matrix": [0, 1], "x": 1, "y": 0.25},
+ {"matrix": [0, 2], "x": 2, "y": 0},
+ {"matrix": [0, 3], "x": 3, "y": 0.125},
+ {"matrix": [0, 4], "x": 4, "y": 0.25},
+ {"matrix": [4, 4], "x": 9, "y": 0.25},
+ {"matrix": [4, 3], "x": 10, "y": 0.125},
+ {"matrix": [4, 2], "x": 11, "y": 0},
+ {"matrix": [4, 1], "x": 12, "y": 0.25},
+ {"matrix": [4, 0], "x": 13, "y": 0.6},
+ {"matrix": [1, 0], "x": 0, "y": 1.6},
+ {"matrix": [1, 1], "x": 1, "y": 1.25},
+ {"matrix": [1, 2], "x": 2, "y": 1.0},
+ {"matrix": [1, 3], "x": 3, "y": 1.125},
+ {"matrix": [1, 4], "x": 4, "y": 1.25},
+ {"matrix": [5, 4], "x": 9, "y": 1.25},
+ {"matrix": [5, 3], "x": 10, "y": 1.125},
+ {"matrix": [5, 2], "x": 11, "y": 1.0},
+ {"matrix": [5, 1], "x": 12, "y": 1.25},
+ {"matrix": [5, 0], "x": 13, "y": 1.6},
+ {"matrix": [2, 0], "x": 0, "y": 2.6},
+ {"matrix": [2, 1], "x": 1, "y": 2.25},
+ {"matrix": [2, 2], "x": 2, "y": 2.0},
+ {"matrix": [2, 3], "x": 3, "y": 2.125},
+ {"matrix": [2, 4], "x": 4, "y": 2.25},
+ {"matrix": [6, 4], "x": 9, "y": 2.25},
+ {"matrix": [6, 3], "x": 10, "y": 2.125},
+ {"matrix": [6, 2], "x": 11, "y": 2.0},
+ {"matrix": [6, 1], "x": 12, "y": 2.25},
+ {"matrix": [6, 0], "x": 13, "y": 2.6},
+ {"matrix": [3, 0], "x": 0, "y": 3.6},
+ {"matrix": [3, 4], "x": 4.25, "y": 3.61},
+ {"matrix": [3, 5], "x": 5.38, "y": 3.86},
+ {"matrix": [7, 5], "x": 7.62, "y": 3.86},
+ {"matrix": [7, 4], "x": 8.75, "y": 3.61},
+ {"matrix": [7, 0], "x": 13, "y": 3.6}
+ ]
}
}
}
diff --git a/keyboards/yowkees/keyball39/keyball39.h b/keyboards/yowkees/keyball39/keyball39.h
index 2f322e69b59..e7a9b4471be 100644
--- a/keyboards/yowkees/keyball39/keyball39.h
+++ b/keyboards/yowkees/keyball39/keyball39.h
@@ -21,29 +21,5 @@ along with this program. If not, see .
#include "quantum.h"
#include "lib/keyball/keyball.h"
-// clang-format off
-
-
-
-#define LAYOUT_dual_ball( \
- L00, L01, L02, L03, L04, R04, R03, R02, R01, R00, \
- L10, L11, L12, L13, L14, R14, R13, R12, R11, R10, \
- L20, L21, L22, L23, L24, R24, R23, R22, R21, R20, \
- L30, L34, L35, R35, R34, R30 \
- ) \
- { \
- { L00, L01, L02, L03, L04, KC_NO }, \
- { L10, L11, L12, L13, L14, KC_NO }, \
- { L20, L21, L22, L23, L24, KC_NO }, \
- { L30, KC_NO, KC_NO, KC_NO, L34, L35 }, \
- { R00, R01, R02, R03, R04, KC_NO }, \
- { R10, R11, R12, R13, R14, KC_NO }, \
- { R20, R21, R22, R23, R24, KC_NO }, \
- { R30, KC_NO, KC_NO, KC_NO, R34, R35 }, \
- }
-
-
-// clang-format on
-
#define LAYOUT LAYOUT_right_ball
#define LAYOUT_universal LAYOUT_no_ball
From 94f3d2d6d652c36d47bc638502fb813c7c727393 Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Mon, 3 Jun 2024 19:13:08 -0700
Subject: [PATCH 10/32] Convert layout aliases to data-driven
---
keyboards/yowkees/keyball39/info.json | 4 ++++
keyboards/yowkees/keyball39/keyball39.h | 3 ---
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/keyboards/yowkees/keyball39/info.json b/keyboards/yowkees/keyball39/info.json
index 7b40dcd6be7..e86c509e6eb 100644
--- a/keyboards/yowkees/keyball39/info.json
+++ b/keyboards/yowkees/keyball39/info.json
@@ -9,6 +9,10 @@
"rgblight": {
"driver": "ws2812"
},
+ "layout_aliases": {
+ "LAYOUT": "LAYOUT_right_ball",
+ "LAYOUT_universal": "LAYOUT_no_ball"
+ },
"layouts": {
"LAYOUT_no_ball": {
"layout": [
diff --git a/keyboards/yowkees/keyball39/keyball39.h b/keyboards/yowkees/keyball39/keyball39.h
index e7a9b4471be..171f2083ed3 100644
--- a/keyboards/yowkees/keyball39/keyball39.h
+++ b/keyboards/yowkees/keyball39/keyball39.h
@@ -20,6 +20,3 @@ along with this program. If not, see .
#include "quantum.h"
#include "lib/keyball/keyball.h"
-
-#define LAYOUT LAYOUT_right_ball
-#define LAYOUT_universal LAYOUT_no_ball
From 904fecdd04b97f3853cecb54da5a3f2f63e9e4e3 Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Mon, 3 Jun 2024 19:19:22 -0700
Subject: [PATCH 11/32] Re-sort `info.json` keys
---
keyboards/yowkees/keyball39/info.json | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/keyboards/yowkees/keyball39/info.json b/keyboards/yowkees/keyball39/info.json
index e86c509e6eb..81e030ba3d4 100644
--- a/keyboards/yowkees/keyball39/info.json
+++ b/keyboards/yowkees/keyball39/info.json
@@ -1,11 +1,11 @@
{
+ "keyboard_name": "Keyball39",
+ "manufacturer": "Yowkees",
"usb": {
"vid": "0x5957",
"pid": "0x0200",
"device_version": "1.0.0"
},
- "manufacturer": "Yowkees",
- "keyboard_name": "Keyball39",
"rgblight": {
"driver": "ws2812"
},
From 6c3540fb4ec01afd90a507e86acea974a67cbcc6 Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Mon, 3 Jun 2024 21:11:32 -0700
Subject: [PATCH 12/32] Convert `rules.mk` to data-driven
---
keyboards/yowkees/keyball39/info.json | 28 +++++++++++++++++++
keyboards/yowkees/keyball39/rules.mk | 40 ---------------------------
2 files changed, 28 insertions(+), 40 deletions(-)
diff --git a/keyboards/yowkees/keyball39/info.json b/keyboards/yowkees/keyball39/info.json
index 81e030ba3d4..63413db7016 100644
--- a/keyboards/yowkees/keyball39/info.json
+++ b/keyboards/yowkees/keyball39/info.json
@@ -6,9 +6,37 @@
"pid": "0x0200",
"device_version": "1.0.0"
},
+ "development_board": "promicro",
+ "features": {
+ "bootmagic": false,
+ "mousekey": false,
+ "extrakey": false,
+ "console": false,
+ "command": false,
+ "nkro": false,
+ "backlight": false,
+ "rgblight": false,
+ "rgb_matrix": false,
+ "oled": false,
+ "pointing_device": true,
+ "audio": false,
+ "sleep_led": false,
+ "grave_esc": false,
+ "magic": false,
+ "space_cadet": false
+ },
+ "build": {
+ "lto": true
+ },
+ "split": {
+ "enabled": true
+ },
"rgblight": {
"driver": "ws2812"
},
+ "rgb_matrix": {
+ "driver": "ws2812"
+ },
"layout_aliases": {
"LAYOUT": "LAYOUT_right_ball",
"LAYOUT_universal": "LAYOUT_no_ball"
diff --git a/keyboards/yowkees/keyball39/rules.mk b/keyboards/yowkees/keyball39/rules.mk
index 0dfde5b3dd9..ab5a7fab188 100644
--- a/keyboards/yowkees/keyball39/rules.mk
+++ b/keyboards/yowkees/keyball39/rules.mk
@@ -1,49 +1,9 @@
-# MCU name
-MCU = atmega32u4
-
-# Bootloader selection
-BOOTLOADER = caterina
-
-# Link Time Optimization required for size.
-LTO_ENABLE = yes
-
-# Build Options
-BOOTMAGIC_ENABLE = no # Enable Bootmagic Lite
-EXTRAKEY_ENABLE = no # Audio control and System control
-CONSOLE_ENABLE = no # Console for debug
-COMMAND_ENABLE = no # Commands for debug and configuration
-NKRO_ENABLE = no # Enable N-Key Rollover
-BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
-AUDIO_ENABLE = no # Audio output
-
-# Keyball39 is split keyboard.
-SPLIT_KEYBOARD = yes
-
# Optical sensor driver for trackball.
-POINTING_DEVICE_ENABLE = yes
POINTING_DEVICE_DRIVER = custom
SRC += drivers/pmw3360/pmw3360.c
QUANTUM_LIB_SRC += spi_master.c # Optical sensor use SPI to communicate
-# This is unnecessary for processing KC_MS_BTN*.
-MOUSEKEY_ENABLE = no
-
-# Enabled only one of RGBLIGHT and RGB_MATRIX if necessary.
-RGBLIGHT_ENABLE = no # Enable RGBLIGHT
-RGB_MATRIX_ENABLE = no # Enable RGB_MATRIX (not work yet)
-RGB_MATRIX_DRIVER = ws2812
-
-# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
-SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
-
-# To support OLED
-OLED_ENABLE = no # Please Enable this in each keymaps.
SRC += lib/oledkit/oledkit.c # OLED utility for Keyball series.
# Include common library
SRC += lib/keyball/keyball.c
-
-# Disable other features to squeeze firmware size
-SPACE_CADET_ENABLE = no
-GRAVE_ESC_ENABLE = no
-MAGIC_ENABLE = no
From 8e92cd27cf93e4610ff48de893962aec98169583 Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Mon, 3 Jun 2024 23:26:38 -0700
Subject: [PATCH 13/32] Convert `config.h` to data-driven
---
keyboards/yowkees/keyball39/config.h | 10 ----------
keyboards/yowkees/keyball39/info.json | 21 ++++++++++++++++++++-
2 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/keyboards/yowkees/keyball39/config.h b/keyboards/yowkees/keyball39/config.h
index 00c426a0de9..9b7f69b1c21 100644
--- a/keyboards/yowkees/keyball39/config.h
+++ b/keyboards/yowkees/keyball39/config.h
@@ -19,18 +19,9 @@ along with this program. If not, see .
#pragma once
// Key matrix parameters
-#define MATRIX_ROWS (4 * 2) // split keyboard
-#define MATRIX_COLS 6
-#define MATRIX_ROW_PINS { F4, F5, F6, F7 }
-#define MATRIX_COL_PINS { D4, C6, D7, E6, B4, B5 }
#define MATRIX_MASKED
-#define DEBOUNCE 5
-#define DIODE_DIRECTION COL2ROW
// Split parameters
-#define SOFT_SERIAL_PIN D2
-#define SPLIT_HAND_MATRIX_GRID F6, B5
-#define SPLIT_USB_DETECT
#ifdef OLED_ENABLE
# define SPLIT_OLED_ENABLE
#endif
@@ -43,7 +34,6 @@ along with this program. If not, see .
#define SPLIT_TRANSACTION_IDS_KB KEYBALL_GET_INFO, KEYBALL_GET_MOTION, KEYBALL_SET_CPI
// RGB LED settings
-#define WS2812_DI_PIN D3
#ifdef RGBLIGHT_ENABLE
# define RGBLED_NUM 48
# define RGBLED_SPLIT { 24, 24 } // (24 + 22)
diff --git a/keyboards/yowkees/keyball39/info.json b/keyboards/yowkees/keyball39/info.json
index 63413db7016..e5279056088 100644
--- a/keyboards/yowkees/keyball39/info.json
+++ b/keyboards/yowkees/keyball39/info.json
@@ -7,6 +7,12 @@
"device_version": "1.0.0"
},
"development_board": "promicro",
+ "matrix_pins": {
+ "rows": ["F4", "F5", "F6", "F7"],
+ "cols": ["D4", "C6", "D7", "E6", "B4", "B5"]
+ },
+ "diode_direction": "COL2ROW",
+ "debounce": 5,
"features": {
"bootmagic": false,
"mousekey": false,
@@ -29,7 +35,17 @@
"lto": true
},
"split": {
- "enabled": true
+ "enabled": true,
+ "soft_serial_pin": "D2",
+ "transport": {
+ "protocol": "serial"
+ },
+ "usb_detect": {
+ "enabled": true
+ },
+ "handedness": {
+ "matrix_grid": ["F6", "B5"]
+ }
},
"rgblight": {
"driver": "ws2812"
@@ -37,6 +53,9 @@
"rgb_matrix": {
"driver": "ws2812"
},
+ "ws2812": {
+ "pin": "D3"
+ },
"layout_aliases": {
"LAYOUT": "LAYOUT_right_ball",
"LAYOUT_universal": "LAYOUT_no_ball"
From 62711d8858104d4c6a0151c9a2a4e118ad5a4e99 Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Mon, 3 Jun 2024 23:49:19 -0700
Subject: [PATCH 14/32] Add url and maintainer keys to `info.json`
---
keyboards/yowkees/keyball39/info.json | 2 ++
1 file changed, 2 insertions(+)
diff --git a/keyboards/yowkees/keyball39/info.json b/keyboards/yowkees/keyball39/info.json
index e5279056088..3c74abf64be 100644
--- a/keyboards/yowkees/keyball39/info.json
+++ b/keyboards/yowkees/keyball39/info.json
@@ -1,6 +1,8 @@
{
"keyboard_name": "Keyball39",
"manufacturer": "Yowkees",
+ "url": "https://github.com/Yowkees/keyball",
+ "maintainer": "qmk",
"usb": {
"vid": "0x5957",
"pid": "0x0200",
From 9d9f273e7b75e541fbdca517cb3d43d464143c99 Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Tue, 4 Jun 2024 01:49:12 -0700
Subject: [PATCH 15/32] Move RGBLIGHT and OLED rules to keyboard level
---
keyboards/yowkees/keyball39/info.json | 4 ++--
keyboards/yowkees/keyball39/keymaps/default/rules.mk | 3 ---
keyboards/yowkees/keyball39/keymaps/develop/rules.mk | 4 ----
keyboards/yowkees/keyball39/keymaps/test/rules.mk | 4 ----
keyboards/yowkees/keyball39/keymaps/via/rules.mk | 4 ----
5 files changed, 2 insertions(+), 17 deletions(-)
delete mode 100644 keyboards/yowkees/keyball39/keymaps/default/rules.mk
diff --git a/keyboards/yowkees/keyball39/info.json b/keyboards/yowkees/keyball39/info.json
index 3c74abf64be..3aedd9c0c42 100644
--- a/keyboards/yowkees/keyball39/info.json
+++ b/keyboards/yowkees/keyball39/info.json
@@ -23,9 +23,9 @@
"command": false,
"nkro": false,
"backlight": false,
- "rgblight": false,
+ "rgblight": true,
"rgb_matrix": false,
- "oled": false,
+ "oled": true,
"pointing_device": true,
"audio": false,
"sleep_led": false,
diff --git a/keyboards/yowkees/keyball39/keymaps/default/rules.mk b/keyboards/yowkees/keyball39/keymaps/default/rules.mk
deleted file mode 100644
index 5746ccd2854..00000000000
--- a/keyboards/yowkees/keyball39/keymaps/default/rules.mk
+++ /dev/null
@@ -1,3 +0,0 @@
-RGBLIGHT_ENABLE = yes
-
-OLED_ENABLE = yes
diff --git a/keyboards/yowkees/keyball39/keymaps/develop/rules.mk b/keyboards/yowkees/keyball39/keymaps/develop/rules.mk
index 98615de5f51..a84a68c3b78 100644
--- a/keyboards/yowkees/keyball39/keymaps/develop/rules.mk
+++ b/keyboards/yowkees/keyball39/keymaps/develop/rules.mk
@@ -1,6 +1,2 @@
-RGBLIGHT_ENABLE = yes
-
-OLED_ENABLE = yes
-
# for debug
#CONSOLE_ENABLE = yes
diff --git a/keyboards/yowkees/keyball39/keymaps/test/rules.mk b/keyboards/yowkees/keyball39/keymaps/test/rules.mk
index 98615de5f51..a84a68c3b78 100644
--- a/keyboards/yowkees/keyball39/keymaps/test/rules.mk
+++ b/keyboards/yowkees/keyball39/keymaps/test/rules.mk
@@ -1,6 +1,2 @@
-RGBLIGHT_ENABLE = yes
-
-OLED_ENABLE = yes
-
# for debug
#CONSOLE_ENABLE = yes
diff --git a/keyboards/yowkees/keyball39/keymaps/via/rules.mk b/keyboards/yowkees/keyball39/keymaps/via/rules.mk
index d80df3fa49a..1e5b99807cb 100644
--- a/keyboards/yowkees/keyball39/keymaps/via/rules.mk
+++ b/keyboards/yowkees/keyball39/keymaps/via/rules.mk
@@ -1,5 +1 @@
-RGBLIGHT_ENABLE = yes
-
-OLED_ENABLE = yes
-
VIA_ENABLE = yes
From d392a2728aa3bd6d4289bd3c63059871b8f83c2f Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Wed, 5 Jun 2024 11:14:15 -0700
Subject: [PATCH 16/32] Change `SPLIT_HAND_MATRIX_GRID` detection behaviour
The default behaviour of `SPLIT_HAND_MATRIX_GRID` was changed in QMK
Firmware 0.24.0, but the initial code is based on 0.22.x, so this board
needs to have its detection behaviour swapped by defining
`SPLIT_HAND_MATRIX_GRID_LOW_IS_LEFT`.
diff --git a/keyboards/yowkees/keyball39/config.h b/keyboards/yowkees/keyball39/config.h
index 9b7f69b1c2..1a1560e44a 100644
--- a/keyboards/yowkees/keyball39/config.h
+++ b/keyboards/yowkees/keyball39/config.h
@@ -22,6 +22,7 @@ along with this program. If not, see .
#define MATRIX_MASKED
// Split parameters
+#define SPLIT_HAND_MATRIX_GRID_LOW_IS_LEFT
#ifdef OLED_ENABLE
# define SPLIT_OLED_ENABLE
#endif
---
keyboards/yowkees/keyball39/config.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/keyboards/yowkees/keyball39/config.h b/keyboards/yowkees/keyball39/config.h
index 9b7f69b1c21..1a1560e44af 100644
--- a/keyboards/yowkees/keyball39/config.h
+++ b/keyboards/yowkees/keyball39/config.h
@@ -22,6 +22,7 @@ along with this program. If not, see .
#define MATRIX_MASKED
// Split parameters
+#define SPLIT_HAND_MATRIX_GRID_LOW_IS_LEFT
#ifdef OLED_ENABLE
# define SPLIT_OLED_ENABLE
#endif
From f6772f9225be35213f292da94def25249692fe0f Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Thu, 6 Jun 2024 11:07:36 -0700
Subject: [PATCH 17/32] Remove `.noci`
QMK doesn't use this file anymore, so it has been deleted.
---
keyboards/yowkees/keyball39/.noci | 0
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 keyboards/yowkees/keyball39/.noci
diff --git a/keyboards/yowkees/keyball39/.noci b/keyboards/yowkees/keyball39/.noci
deleted file mode 100644
index e69de29bb2d..00000000000
From ec43ced08d142397ce9b1b704cd133195f25911a Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Thu, 6 Jun 2024 11:54:40 -0700
Subject: [PATCH 18/32] Refactor keymaps
- remove redundant `quantum.h` includes
- use `LAYOUT_no_ball` macro directly
- apply four-space indent
- grid-align keycodes
---
.../keyball39/keymaps/default/keymap.c | 52 +++++++++----------
.../keyball39/keymaps/develop/keymap.c | 28 +++++-----
.../yowkees/keyball39/keymaps/test/keymap.c | 14 +++--
.../yowkees/keyball39/keymaps/via/keymap.c | 52 +++++++++----------
4 files changed, 69 insertions(+), 77 deletions(-)
diff --git a/keyboards/yowkees/keyball39/keymaps/default/keymap.c b/keyboards/yowkees/keyball39/keymaps/default/keymap.c
index ebc39675860..4ba6da4d49a 100644
--- a/keyboards/yowkees/keyball39/keymaps/default/keymap.c
+++ b/keyboards/yowkees/keyball39/keymaps/default/keymap.c
@@ -18,38 +18,36 @@ along with this program. If not, see .
#include QMK_KEYBOARD_H
-#include "quantum.h"
-
// clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
- // keymap for default
- [0] = LAYOUT_universal(
- KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P ,
- KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_MINS ,
- KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM , KC_DOT , KC_SLSH ,
- KC_LCTL , KC_LGUI , KC_LALT ,LSFT_T(KC_LNG2),LT(1,KC_SPC),LT(3,KC_LNG1),KC_BSPC,LT(2,KC_ENT),LSFT_T(KC_LNG2),KC_RALT,KC_RGUI, KC_RSFT
- ),
+ // keymap for default
+ [0] = LAYOUT_no_ball(
+ KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P,
+ KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_MINS,
+ KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH,
+ KC_LCTL, KC_LGUI, KC_LALT, LSFT_T(KC_LNG2), LT(1,KC_SPC), LT(3,KC_LNG1), KC_BSPC, LT(2,KC_ENT), LSFT_T(KC_LNG2), KC_RALT, KC_RGUI, KC_RSFT
+ ),
- [1] = LAYOUT_universal(
- KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_RBRC , KC_F6 , KC_F7 , KC_F8 , KC_F9 , KC_F10 ,
- KC_F5 , KC_EXLM , S(KC_6) ,S(KC_INT3), S(KC_8) , S(KC_INT1), KC_BTN1 , KC_PGUP , KC_BTN2 , KC_SCLN ,
- S(KC_EQL),S(KC_LBRC),S(KC_7) , S(KC_2) ,S(KC_RBRC), KC_LBRC , KC_DLR , KC_PGDN , KC_BTN3 , KC_F11 ,
- KC_INT1 , KC_EQL , S(KC_3) , _______ , _______ , _______ , TO(2) , TO(0) , _______ , KC_RALT , KC_RGUI , KC_F12
- ),
+ [1] = LAYOUT_no_ball(
+ KC_F1, KC_F2, KC_F3, KC_F4, KC_RBRC, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10,
+ KC_F5, KC_EXLM, S(KC_6), S(KC_INT3), S(KC_8), S(KC_INT1), KC_BTN1, KC_PGUP, KC_BTN2, KC_SCLN,
+ S(KC_EQL), S(KC_LBRC), S(KC_7), S(KC_2), S(KC_RBRC), KC_LBRC, KC_DLR, KC_PGDN, KC_BTN3, KC_F11,
+ KC_INT1, KC_EQL, S(KC_3), _______, _______, _______, TO(2), TO(0), _______, KC_RALT, KC_RGUI, KC_F12
+ ),
- [2] = LAYOUT_universal(
- KC_TAB , KC_7 , KC_8 , KC_9 , KC_MINS , KC_NUHS , _______ , KC_BTN3 , _______ , KC_BSPC ,
- S(KC_QUOT), KC_4 , KC_5 , KC_6 ,S(KC_SCLN), S(KC_9) , KC_BTN1 , KC_UP , KC_BTN2 , KC_QUOT ,
- KC_SLSH , KC_1 , KC_2 , KC_3 ,S(KC_MINS), S(KC_NUHS), KC_LEFT , KC_DOWN , KC_RGHT , _______ ,
- KC_ESC , KC_0 , KC_DOT , KC_DEL , KC_ENT , KC_BSPC , _______ , _______ , _______ , _______ , _______ , _______
- ),
+ [2] = LAYOUT_no_ball(
+ KC_TAB, KC_7, KC_8, KC_9, KC_MINS, KC_NUHS, _______, KC_BTN3, _______, KC_BSPC,
+ S(KC_QUOT), KC_4, KC_5, KC_6, S(KC_SCLN), S(KC_9), KC_BTN1, KC_UP, KC_BTN2, KC_QUOT,
+ KC_SLSH, KC_1, KC_2, KC_3, S(KC_MINS), S(KC_NUHS), KC_LEFT, KC_DOWN, KC_RGHT, _______,
+ KC_ESC, KC_0, KC_DOT, KC_DEL, KC_ENT, KC_BSPC, _______, _______, _______, _______, _______, _______
+ ),
- [3] = LAYOUT_universal(
- RGB_TOG , AML_TO , AML_I50 , AML_D50 , _______ , _______ , _______ , SSNP_HOR , SSNP_VRT , SSNP_FRE ,
- RGB_MOD , RGB_HUI , RGB_SAI , RGB_VAI , SCRL_DVI , _______ , _______ , _______ , _______ , _______ ,
- RGB_RMOD , RGB_HUD , RGB_SAD , RGB_VAD , SCRL_DVD , CPI_D1K , CPI_D100 , CPI_I100 , CPI_I1K , KBC_SAVE ,
- QK_BOOT , KBC_RST , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , KBC_RST , QK_BOOT
- ),
+ [3] = LAYOUT_no_ball(
+ RGB_TOG, AML_TO, AML_I50, AML_D50, _______, _______, _______, SSNP_HOR, SSNP_VRT, SSNP_FRE,
+ RGB_MOD, RGB_HUI, RGB_SAI, RGB_VAI, SCRL_DVI, _______, _______, _______, _______, _______,
+ RGB_RMOD, RGB_HUD, RGB_SAD, RGB_VAD, SCRL_DVD, CPI_D1K, CPI_D100, CPI_I100, CPI_I1K, KBC_SAVE,
+ QK_BOOT, KBC_RST, _______, _______, _______, _______, _______, _______, _______, _______, KBC_RST, QK_BOOT
+ ),
};
// clang-format on
diff --git a/keyboards/yowkees/keyball39/keymaps/develop/keymap.c b/keyboards/yowkees/keyball39/keymaps/develop/keymap.c
index dca2006c475..680f8cc5bd9 100644
--- a/keyboards/yowkees/keyball39/keymaps/develop/keymap.c
+++ b/keyboards/yowkees/keyball39/keymaps/develop/keymap.c
@@ -18,24 +18,22 @@ along with this program. If not, see .
#include QMK_KEYBOARD_H
-#include "quantum.h"
-
// clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
- // keymap for development
- [0] = LAYOUT_universal(
- KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P ,
- KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_SCLN ,
- KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM , KC_DOT , KC_SLSH ,
- KC_LCTL , KC_LGUI , KC_LALT , SCRL_MO , KC_SPC ,LT(1,KC_TAB),LT(1,KC_BSPC), KC_ENT , SCRL_MO , KC_RALT , KC_RGUI , KC_RSFT
- ),
+ // keymap for development
+ [0] = LAYOUT_no_ball(
+ KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P,
+ KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN,
+ KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH,
+ KC_LCTL, KC_LGUI, KC_LALT, SCRL_MO, KC_SPC, LT(1,KC_TAB), LT(1,KC_BSPC), KC_ENT, SCRL_MO, KC_RALT, KC_RGUI, KC_RSFT
+ ),
- [1] = LAYOUT_universal(
- RGB_TOG , _______ , _______ , _______ , _______ , RGB_M_P , RGB_M_B , RGB_M_R , RGB_M_SW , RGB_M_SN ,
- RGB_MOD , RGB_HUI , RGB_SAI , RGB_VAI , SCRL_DVI , RGB_M_K , RGB_M_X , RGB_M_G , RGB_M_T , RGB_M_TW ,
- RGB_RMOD , RGB_HUD , RGB_SAD , RGB_VAD , SCRL_DVD , CPI_D1K , CPI_D100 , CPI_I100 , CPI_I1K , KBC_SAVE ,
- QK_BOOT , KBC_RST , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , KBC_RST , QK_BOOT
- ),
+ [1] = LAYOUT_no_ball(
+ RGB_TOG, _______, _______, _______, _______, RGB_M_P, RGB_M_B, RGB_M_R, RGB_M_SW, RGB_M_SN,
+ RGB_MOD, RGB_HUI, RGB_SAI, RGB_VAI, SCRL_DVI, RGB_M_K, RGB_M_X, RGB_M_G, RGB_M_T, RGB_M_TW,
+ RGB_RMOD, RGB_HUD, RGB_SAD, RGB_VAD, SCRL_DVD, CPI_D1K, CPI_D100, CPI_I100, CPI_I1K, KBC_SAVE,
+ QK_BOOT, KBC_RST, _______, _______, _______, _______, _______, _______, _______, _______, KBC_RST, QK_BOOT
+ ),
};
// clang-format on
diff --git a/keyboards/yowkees/keyball39/keymaps/test/keymap.c b/keyboards/yowkees/keyball39/keymaps/test/keymap.c
index beb81aa4574..4a7306480e0 100644
--- a/keyboards/yowkees/keyball39/keymaps/test/keymap.c
+++ b/keyboards/yowkees/keyball39/keymaps/test/keymap.c
@@ -18,16 +18,14 @@ along with this program. If not, see .
#include QMK_KEYBOARD_H
-#include "quantum.h"
-
// clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
- [0] = LAYOUT_universal(
- KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P ,
- KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_SCLN ,
- KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM , KC_DOT , KC_SLSH ,
- KC_LCTL , KC_LGUI , KC_LALT , KC_ESC , KC_SPC , KC_TAB , KC_BSPC , KC_ENT , KC_ESC , KC_RALT , KC_RGUI , KC_RSFT
- ),
+ [0] = LAYOUT_no_ball(
+ KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P,
+ KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN,
+ KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_ESC, KC_SPC, KC_TAB, KC_BSPC, KC_ENT, KC_ESC, KC_RALT, KC_RGUI, KC_RSFT
+ ),
};
// clang-format on
diff --git a/keyboards/yowkees/keyball39/keymaps/via/keymap.c b/keyboards/yowkees/keyball39/keymaps/via/keymap.c
index b3addae35a0..0849fe5494a 100644
--- a/keyboards/yowkees/keyball39/keymaps/via/keymap.c
+++ b/keyboards/yowkees/keyball39/keymaps/via/keymap.c
@@ -18,38 +18,36 @@ along with this program. If not, see .
#include QMK_KEYBOARD_H
-#include "quantum.h"
-
// clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
- // keymap for default (VIA)
- [0] = LAYOUT_universal(
- KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P ,
- KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , KC_MINS ,
- KC_Z , KC_X , KC_C , KC_V , KC_B , KC_N , KC_M , KC_COMM , KC_DOT , KC_SLSH ,
- KC_LCTL , KC_LGUI , KC_LALT ,LSFT_T(KC_LNG2),LT(1,KC_SPC),LT(3,KC_LNG1),KC_BSPC,LT(2,KC_ENT),LSFT_T(KC_LNG2),KC_RALT,KC_RGUI, KC_RSFT
- ),
+ // keymap for default (VIA)
+ [0] = LAYOUT_no_ball(
+ KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P,
+ KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_MINS,
+ KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH,
+ KC_LCTL, KC_LGUI, KC_LALT, LSFT_T(KC_LNG2), LT(1,KC_SPC), LT(3,KC_LNG1), KC_BSPC, LT(2,KC_ENT), LSFT_T(KC_LNG2), KC_RALT, KC_RGUI, KC_RSFT
+ ),
- [1] = LAYOUT_universal(
- KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_RBRC , KC_F6 , KC_F7 , KC_F8 , KC_F9 , KC_F10 ,
- KC_F5 , KC_EXLM , S(KC_6) ,S(KC_INT3), S(KC_8) , S(KC_INT1), KC_BTN1 , KC_PGUP , KC_BTN2 , KC_SCLN ,
- S(KC_EQL),S(KC_LBRC),S(KC_7) , S(KC_2) ,S(KC_RBRC), KC_LBRC , KC_DLR , KC_PGDN , KC_BTN3 , KC_F11 ,
- KC_INT1 , KC_EQL , S(KC_3) , _______ , _______ , _______ , TO(2) , TO(0) , _______ , KC_RALT , KC_RGUI , KC_F12
- ),
+ [1] = LAYOUT_no_ball(
+ KC_F1, KC_F2, KC_F3, KC_F4, KC_RBRC, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10,
+ KC_F5, KC_EXLM, S(KC_6), S(KC_INT3), S(KC_8), S(KC_INT1), KC_BTN1, KC_PGUP, KC_BTN2, KC_SCLN,
+ S(KC_EQL), S(KC_LBRC), S(KC_7), S(KC_2), S(KC_RBRC), KC_LBRC, KC_DLR, KC_PGDN, KC_BTN3, KC_F11,
+ KC_INT1, KC_EQL, S(KC_3), _______, _______, _______, TO(2), TO(0), _______, KC_RALT, KC_RGUI, KC_F12
+ ),
- [2] = LAYOUT_universal(
- KC_TAB , KC_7 , KC_8 , KC_9 , KC_MINS , KC_NUHS , _______ , KC_BTN3 , _______ , KC_BSPC ,
- S(KC_QUOT), KC_4 , KC_5 , KC_6 ,S(KC_SCLN), S(KC_9) , KC_BTN1 , KC_UP , KC_BTN2 , KC_QUOT ,
- KC_SLSH , KC_1 , KC_2 , KC_3 ,S(KC_MINS), S(KC_NUHS), KC_LEFT , KC_DOWN , KC_RGHT , _______ ,
- KC_ESC , KC_0 , KC_DOT , KC_DEL , KC_ENT , KC_BSPC , _______ , _______ , _______ , _______ , _______ , _______
- ),
+ [2] = LAYOUT_no_ball(
+ KC_TAB, KC_7, KC_8, KC_9, KC_MINS, KC_NUHS, _______, KC_BTN3, _______, KC_BSPC,
+ S(KC_QUOT), KC_4, KC_5, KC_6, S(KC_SCLN), S(KC_9), KC_BTN1, KC_UP, KC_BTN2, KC_QUOT,
+ KC_SLSH, KC_1, KC_2, KC_3, S(KC_MINS), S(KC_NUHS), KC_LEFT, KC_DOWN, KC_RGHT, _______,
+ KC_ESC, KC_0, KC_DOT, KC_DEL, KC_ENT, KC_BSPC, _______, _______, _______, _______, _______, _______
+ ),
- [3] = LAYOUT_universal(
- RGB_TOG , AML_TO , AML_I50 , AML_D50 , _______ , _______ , _______ , SSNP_HOR , SSNP_VRT , SSNP_FRE ,
- RGB_MOD , RGB_HUI , RGB_SAI , RGB_VAI , SCRL_DVI , _______ , _______ , _______ , _______ , _______ ,
- RGB_RMOD , RGB_HUD , RGB_SAD , RGB_VAD , SCRL_DVD , CPI_D1K , CPI_D100 , CPI_I100 , CPI_I1K , KBC_SAVE ,
- QK_BOOT , KBC_RST , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , KBC_RST , QK_BOOT
- ),
+ [3] = LAYOUT_no_ball(
+ RGB_TOG, AML_TO, AML_I50, AML_D50, _______, _______, _______, SSNP_HOR, SSNP_VRT, SSNP_FRE,
+ RGB_MOD, RGB_HUI, RGB_SAI, RGB_VAI, SCRL_DVI, _______, _______, _______, _______, _______,
+ RGB_RMOD, RGB_HUD, RGB_SAD, RGB_VAD, SCRL_DVD, CPI_D1K, CPI_D100, CPI_I100, CPI_I1K, KBC_SAVE,
+ QK_BOOT, KBC_RST, _______, _______, _______, _______, _______, _______, _______, _______, KBC_RST, QK_BOOT
+ ),
};
// clang-format on
From 9057f11b6237d64f28ba00b08bd8e5b3b4581aa1 Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Fri, 7 Jun 2024 16:57:14 -0700
Subject: [PATCH 19/32] Update readme
Fix image URL and `make` command.
---
keyboards/yowkees/keyball39/readme.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/keyboards/yowkees/keyball39/readme.md b/keyboards/yowkees/keyball39/readme.md
index 6076b3f2917..3d52cc8bc71 100644
--- a/keyboards/yowkees/keyball39/readme.md
+++ b/keyboards/yowkees/keyball39/readme.md
@@ -1,6 +1,6 @@
# Keyball39
-![Keyball39](../../../../keyball39/doc/rev1/images/kb39_001.jpg)
+![Keyball39](https://raw.githubusercontent.com/Yowkees/keyball/main/keyball39/doc/rev1/images/kb39_001.jpg)
A split keyboard with 39 vertically staggered keys and 34mm track ball.
@@ -12,7 +12,7 @@ A split keyboard with 39 vertically staggered keys and 34mm track ball.
Make example for this keyboard (after setting up your build environment):
- make keyball/keyball39:default
+ make yowkees/keyball39:default
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
From 93bf88482912f4ea903f071d92bd4bc970af0032 Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Mon, 10 Jun 2024 01:29:33 -0700
Subject: [PATCH 20/32] Use `SPI_DRIVER_REQUIRED = yes` (per drashna)
---
keyboards/yowkees/keyball39/rules.mk | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/keyboards/yowkees/keyball39/rules.mk b/keyboards/yowkees/keyball39/rules.mk
index ab5a7fab188..bab3a7702d7 100644
--- a/keyboards/yowkees/keyball39/rules.mk
+++ b/keyboards/yowkees/keyball39/rules.mk
@@ -1,7 +1,7 @@
# Optical sensor driver for trackball.
POINTING_DEVICE_DRIVER = custom
SRC += drivers/pmw3360/pmw3360.c
-QUANTUM_LIB_SRC += spi_master.c # Optical sensor use SPI to communicate
+SPI_DRIVER_REQUIRED = yes
SRC += lib/oledkit/oledkit.c # OLED utility for Keyball series.
From b8a1b747e8300ab04400e2cccdb977d05217b2ba Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Thu, 13 Jun 2024 00:01:28 -0700
Subject: [PATCH 21/32] Rename `info.json` to `keyboard.json`
---
keyboards/yowkees/keyball39/{info.json => keyboard.json} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename keyboards/yowkees/keyball39/{info.json => keyboard.json} (100%)
diff --git a/keyboards/yowkees/keyball39/info.json b/keyboards/yowkees/keyball39/keyboard.json
similarity index 100%
rename from keyboards/yowkees/keyball39/info.json
rename to keyboards/yowkees/keyball39/keyboard.json
From 30fbdb7a68317116a2bb91433e2de8cff668983d Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Thu, 13 Jun 2024 03:39:13 -0700
Subject: [PATCH 22/32] Update `rules.mk` to set core PMW3360 driver
---
keyboards/yowkees/keyball39/rules.mk | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/keyboards/yowkees/keyball39/rules.mk b/keyboards/yowkees/keyball39/rules.mk
index bab3a7702d7..906354aea0d 100644
--- a/keyboards/yowkees/keyball39/rules.mk
+++ b/keyboards/yowkees/keyball39/rules.mk
@@ -1,7 +1,5 @@
# Optical sensor driver for trackball.
-POINTING_DEVICE_DRIVER = custom
-SRC += drivers/pmw3360/pmw3360.c
-SPI_DRIVER_REQUIRED = yes
+POINTING_DEVICE_DRIVER = pmw3360
SRC += lib/oledkit/oledkit.c # OLED utility for Keyball series.
From 132d2133c3fc54717ffe6f83be566c9ed31419d4 Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Thu, 13 Jun 2024 03:40:34 -0700
Subject: [PATCH 23/32] Remove custom Yowkees PMW3360 driver
---
keyboards/yowkees/drivers/pmw3360/pmw3360.c | 176 ------------
keyboards/yowkees/drivers/pmw3360/pmw3360.h | 171 ------------
.../pmw3360/pmw3360_pointing_device_driver.c | 51 ----
keyboards/yowkees/drivers/pmw3360/srom_0x04.c | 263 ------------------
keyboards/yowkees/drivers/pmw3360/srom_0x81.c | 263 ------------------
5 files changed, 924 deletions(-)
delete mode 100644 keyboards/yowkees/drivers/pmw3360/pmw3360.c
delete mode 100644 keyboards/yowkees/drivers/pmw3360/pmw3360.h
delete mode 100644 keyboards/yowkees/drivers/pmw3360/pmw3360_pointing_device_driver.c
delete mode 100644 keyboards/yowkees/drivers/pmw3360/srom_0x04.c
delete mode 100644 keyboards/yowkees/drivers/pmw3360/srom_0x81.c
diff --git a/keyboards/yowkees/drivers/pmw3360/pmw3360.c b/keyboards/yowkees/drivers/pmw3360/pmw3360.c
deleted file mode 100644
index 02a9097614f..00000000000
--- a/keyboards/yowkees/drivers/pmw3360/pmw3360.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
-Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-#include "quantum.h"
-#include "pmw3360.h"
-
-// Include SROM definitions.
-#include "srom_0x04.c"
-#include "srom_0x81.c"
-
-#define PMW3360_SPI_MODE 3
-#define PMW3360_SPI_DIVISOR (F_CPU / PMW3360_CLOCKS)
-#define PMW3360_CLOCKS 2000000
-
-static bool motion_bursting = false;
-
-bool pmw3360_spi_start(void) {
- return spi_start(PMW3360_NCS_PIN, false, PMW3360_SPI_MODE, PMW3360_SPI_DIVISOR);
-}
-
-uint8_t pmw3360_reg_read(uint8_t addr) {
- pmw3360_spi_start();
- spi_write(addr & 0x7f);
- wait_us(160);
- uint8_t data = spi_read();
- wait_us(1);
- spi_stop();
- wait_us(19);
- // Reset motion_bursting mode if read from a register other than motion
- // burst register.
- if (addr != pmw3360_Motion_Burst) {
- motion_bursting = false;
- }
- return data;
-}
-
-void pmw3360_reg_write(uint8_t addr, uint8_t data) {
- pmw3360_spi_start();
- spi_write(addr | 0x80);
- spi_write(data);
- wait_us(35);
- spi_stop();
- wait_us(145);
-}
-
-uint8_t pmw3360_cpi_get(void) {
- return pmw3360_reg_read(pmw3360_Config1);
-}
-
-void pmw3360_cpi_set(uint8_t cpi) {
- if (cpi > pmw3360_MAXCPI) {
- cpi = pmw3360_MAXCPI;
- }
- pmw3360_reg_write(pmw3360_Config1, cpi);
-}
-
-static uint32_t pmw3360_timer = 0;
-static uint32_t pmw3360_scan_count = 0;
-static uint32_t pmw3360_last_count = 0;
-
-void pmw3360_scan_perf_task(void) {
- pmw3360_scan_count++;
- uint32_t now = timer_read32();
- if (TIMER_DIFF_32(now, pmw3360_timer) > 1000) {
-#if defined(CONSOLE_ENABLE)
- dprintf("pmw3360 scan frequency: %lu\n", pmw3360_scan_count);
-#endif
- pmw3360_last_count = pmw3360_scan_count;
- pmw3360_scan_count = 0;
- pmw3360_timer = now;
- }
-}
-
-uint32_t pmw3360_scan_rate_get(void) {
- return pmw3360_last_count;
-}
-
-bool pmw3360_motion_read(pmw3360_motion_t *d) {
-#ifdef DEBUG_PMW3360_SCAN_RATE
- pmw3360_scan_perf_task();
-#endif
- uint8_t mot = pmw3360_reg_read(pmw3360_Motion);
- if ((mot & 0x88) != 0x80) {
- return false;
- }
- d->x = pmw3360_reg_read(pmw3360_Delta_X_L);
- d->x |= pmw3360_reg_read(pmw3360_Delta_X_H) << 8;
- d->y = pmw3360_reg_read(pmw3360_Delta_Y_L);
- d->y |= pmw3360_reg_read(pmw3360_Delta_Y_H) << 8;
- return true;
-}
-
-bool pmw3360_motion_burst(pmw3360_motion_t *d) {
-#ifdef DEBUG_PMW3360_SCAN_RATE
- pmw3360_scan_perf_task();
-#endif
- // Start motion burst if motion burst mode is not started.
- if (!motion_bursting) {
- pmw3360_reg_write(pmw3360_Motion_Burst, 0);
- motion_bursting = true;
- }
-
- pmw3360_spi_start();
- spi_write(pmw3360_Motion_Burst);
- wait_us(35);
- spi_read(); // skip MOT
- spi_read(); // skip Observation
- d->x = spi_read();
- d->x |= spi_read() << 8;
- d->y = spi_read();
- d->y |= spi_read() << 8;
- spi_stop();
- // Required NCS in 500ns after motion burst.
- wait_us(1);
- return true;
-}
-
-bool pmw3360_init(void) {
- spi_init();
- setPinOutput(PMW3360_NCS_PIN);
- // reboot
- pmw3360_spi_start();
- pmw3360_reg_write(pmw3360_Power_Up_Reset, 0x5a);
- wait_ms(50);
- // read five registers of motion and discard those values
- pmw3360_reg_read(pmw3360_Motion);
- pmw3360_reg_read(pmw3360_Delta_X_L);
- pmw3360_reg_read(pmw3360_Delta_X_H);
- pmw3360_reg_read(pmw3360_Delta_Y_L);
- pmw3360_reg_read(pmw3360_Delta_Y_H);
- // configuration
- pmw3360_reg_write(pmw3360_Config2, 0x00);
- // check product ID and revision ID
- uint8_t pid = pmw3360_reg_read(pmw3360_Product_ID);
- uint8_t rev = pmw3360_reg_read(pmw3360_Revision_ID);
- spi_stop();
- return pid == 0x42 && rev == 0x01;
-}
-
-uint8_t pmw3360_srom_id = 0;
-
-void pmw3360_srom_upload(pmw3360_srom_t srom) {
- pmw3360_reg_write(pmw3360_Config2, 0x00);
- pmw3360_reg_write(pmw3360_SROM_Enable, 0x1d);
- wait_us(10);
- pmw3360_reg_write(pmw3360_SROM_Enable, 0x18);
-
- // SROM upload (download for PMW3360) with burst mode
- pmw3360_spi_start();
- spi_write(pmw3360_SROM_Load_Burst | 0x80);
- wait_us(15);
- for (size_t i = 0; i < srom.len; i++) {
- spi_write(pgm_read_byte(srom.data + i));
- wait_us(15);
- }
- spi_stop();
- wait_us(200);
-
- pmw3360_srom_id = pmw3360_reg_read(pmw3360_SROM_ID);
- pmw3360_reg_write(pmw3360_Config2, 0x00);
- wait_ms(10);
-}
diff --git a/keyboards/yowkees/drivers/pmw3360/pmw3360.h b/keyboards/yowkees/drivers/pmw3360/pmw3360.h
deleted file mode 100644
index ebac2f69945..00000000000
--- a/keyboards/yowkees/drivers/pmw3360/pmw3360.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
-Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-#pragma once
-
-#include
-#include "spi_master.h"
-
-//////////////////////////////////////////////////////////////////////////////
-// Configurations
-
-#ifndef PMW3360_NCS_PIN
-# define PMW3360_NCS_PIN B6
-#endif
-
-/// DEBUG_PMW3360_SCAN_RATE enables scan performance counter.
-/// It records scan count in a last second and enables pmw3360_scan_rate_get().
-/// Additionally, it will be logged automatically when defined CONSOLE_ENABLE
-/// and `debug_enable = true`.
-//#define DEBUG_PMW3360_SCAN_RATE
-
-//////////////////////////////////////////////////////////////////////////////
-// Types
-
-typedef struct {
- const uint8_t *data;
- size_t len;
-} pmw3360_srom_t;
-
-typedef struct {
- int16_t x;
- int16_t y;
-} pmw3360_motion_t;
-
-typedef enum {
- pmw3360_Product_ID = 0x00,
- pmw3360_Revision_ID = 0x01,
- pmw3360_Motion = 0x02,
- pmw3360_Delta_X_L = 0x03,
- pmw3360_Delta_X_H = 0x04,
- pmw3360_Delta_Y_L = 0x05,
- pmw3360_Delta_Y_H = 0x06,
- pmw3360_SQUAL = 0x07,
- pmw3360_Raw_Data_Sum = 0x08,
- pmw3360_Maximum_Raw_data = 0x09,
- pmw3360_Minimum_Raw_data = 0x0A,
- pmw3360_Shutter_Lower = 0x0B,
- pmw3360_Shutter_Upper = 0x0C,
- pmw3360_Control = 0x0D,
- pmw3360_Config1 = 0x0F,
- pmw3360_Config2 = 0x10,
- pmw3360_Angle_Tune = 0x11,
- pmw3360_Frame_Capture = 0x12,
- pmw3360_SROM_Enable = 0x13,
- pmw3360_Run_Downshift = 0x14,
- pmw3360_Rest1_Rate_Lower = 0x15,
- pmw3360_Rest1_Rate_Upper = 0x16,
- pmw3360_Rest1_Downshift = 0x17,
- pmw3360_Rest2_Rate_Lower = 0x18,
- pmw3360_Rest2_Rate_Upper = 0x19,
- pmw3360_Rest2_Downshift = 0x1A,
- pmw3360_Rest3_Rate_Lower = 0x1B,
- pmw3360_Rest3_Rate_Upper = 0x1C,
- pmw3360_Observation = 0x24,
- pmw3360_Data_Out_Lower = 0x25,
- pmw3360_Data_Out_Upper = 0x26,
- pmw3360_Raw_Data_Dump = 0x29,
- pmw3360_SROM_ID = 0x2A,
- pmw3360_Min_SQ_Run = 0x2B,
- pmw3360_Raw_Data_Threshold = 0x2C,
- pmw3360_Config5 = 0x2F,
- pmw3360_Power_Up_Reset = 0x3A,
- pmw3360_Shutdown = 0x3B,
- pmw3360_Inverse_Product_ID = 0x3F,
- pmw3360_LiftCutoff_Tune3 = 0x41,
- pmw3360_Angle_Snap = 0x42,
- pmw3360_LiftCutoff_Tune1 = 0x4A,
- pmw3360_Motion_Burst = 0x50,
- pmw3360_LiftCutoff_Tune_Timeout = 0x58,
- pmw3360_LiftCutoff_Tune_Min_Length = 0x5A,
- pmw3360_SROM_Load_Burst = 0x62,
- pmw3360_Lift_Config = 0x63,
- pmw3360_Raw_Data_Burst = 0x64,
- pmw3360_LiftCutoff_Tune2 = 0x65,
-} pmw3360_reg_t;
-
-enum {
- pmw3360_MAXCPI = 0x77, // = 119: 12000 CPI
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// Exported values (touch carefully)
-
-/// SROM ID, last uploaded. 0 means not uploaded yet.
-extern uint8_t pmw3360_srom_id;
-
-/// SROM 0x04
-extern const pmw3360_srom_t pmw3360_srom_0x04;
-/// SROM 0x81
-extern const pmw3360_srom_t pmw3360_srom_0x81;
-
-//////////////////////////////////////////////////////////////////////////////
-// Top level API
-
-/// pmw3360_init initializes PMW3360DM-T2QU module.
-/// It will return true when succeeded, otherwise false.
-bool pmw3360_init(void);
-
-void pmw3360_srom_upload(pmw3360_srom_t srom);
-
-/// pmw3360_motion_read gets a motion data by Motion register.
-/// This requires to write a dummy data to pmw3360_Motion register
-/// just before.
-bool pmw3360_motion_read(pmw3360_motion_t *d);
-
-/// pmw3360_motion_burst gets a motion data by Motion_Burst command.
-/// This requires to write a dummy data to pmw3360_Motion_Burst register
-/// just before.
-bool pmw3360_motion_burst(pmw3360_motion_t *d);
-
-/// pmw3360_scan_rate_get gets count of scan in a last second.
-/// This works only when DEBUG_PMW3360_SCAN_RATE is defined.
-uint32_t pmw3360_scan_rate_get(void);
-
-// TODO: document
-uint8_t pmw3360_cpi_get(void);
-
-// TODO: document
-void pmw3360_cpi_set(uint8_t cpi);
-
-//////////////////////////////////////////////////////////////////////////////
-// Register operations
-
-/// pmw3360_reg_write writes a value to a register.
-void pmw3360_reg_write(uint8_t addr, uint8_t data);
-
-/// pmw3360_reg_read reads a value from a register.
-uint8_t pmw3360_reg_read(uint8_t addr);
-
-//////////////////////////////////////////////////////////////////////////////
-// SPI operations
-
-bool pmw3360_spi_start(void);
-
-void inline pmw3360_spi_stop(void) {
- spi_stop();
-}
-
-/// \deprecated use pmw3360_reg_write() instead of this.
-spi_status_t inline pmw3360_spi_write(uint8_t data) {
- return spi_write(data);
-}
-
-/// \deprecated use pmw3360_reg_read() instead of this.
-spi_status_t inline pmw3360_spi_read(void) {
- return spi_read();
-}
diff --git a/keyboards/yowkees/drivers/pmw3360/pmw3360_pointing_device_driver.c b/keyboards/yowkees/drivers/pmw3360/pmw3360_pointing_device_driver.c
deleted file mode 100644
index 50c187bdd1e..00000000000
--- a/keyboards/yowkees/drivers/pmw3360/pmw3360_pointing_device_driver.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-#include "pointing_device.h"
-#include "pmw3360.h"
-
-bool pmw3360_has = false;
-
-void pointing_device_driver_init(void) {
- pmw3360_has = pmw3360_init();
- pmw3360_reg_write(pmw3360_Motion_Burst, 0);
-}
-
-#define constrain_hid(amt) ((amt) < -127 ? -127 : ((amt) > 127 ? 127 : (amt)))
-
-report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report) {
- pmw3360_motion_t d = {0};
- if (pmw3360_has && pmw3360_motion_burst(&d)) {
- mouse_report.x = constrain_hid(d.y);
- mouse_report.y = constrain_hid(d.x);
- }
- return mouse_report;
-}
-
-uint16_t pointing_device_driver_get_cpi(void) {
- if (!pmw3360_has) {
- return 0;
- }
- return pmw3360_cpi_get();
-}
-
-void pointing_device_driver_set_cpi(uint16_t cpi) {
- if (!pmw3360_has) {
- return;
- }
- pmw3360_cpi_set(cpi);
-}
diff --git a/keyboards/yowkees/drivers/pmw3360/srom_0x04.c b/keyboards/yowkees/drivers/pmw3360/srom_0x04.c
deleted file mode 100644
index dd471cab90c..00000000000
--- a/keyboards/yowkees/drivers/pmw3360/srom_0x04.c
+++ /dev/null
@@ -1,263 +0,0 @@
-static const uint8_t srom_data_0x04[] PROGMEM = {
- 0x01, 0x04, 0x8E, 0x96, 0x6E, 0x77, 0x3E, 0xFE, 0x7E, 0x5F, 0x1D, 0xB8, 0xF2, 0x66, 0x4E, 0xFF,
- 0x5D, 0x19, 0xB0, 0xC2, 0x04, 0x69, 0x54, 0x2A, 0xD6, 0x2E, 0xBF, 0xDD, 0x19, 0xB0, 0xC3, 0xE5,
- 0x29, 0xB1, 0xE0, 0x23, 0xA5, 0xA9, 0xB1, 0xC1, 0x00, 0x82, 0x67, 0x4C, 0x1A, 0x97, 0x8D, 0x79,
- 0x51, 0x20, 0xC7, 0x06, 0x8E, 0x7C, 0x7C, 0x7A, 0x76, 0x4F, 0xFD, 0x59, 0x30, 0xE2, 0x46, 0x0E,
- 0x9E, 0xBE, 0xDF, 0x1D, 0x99, 0x91, 0xA0, 0xA5, 0xA1, 0xA9, 0xD0, 0x22, 0xC6, 0xEF, 0x5C, 0x1B,
- 0x95, 0x89, 0x90, 0xA2, 0xA7, 0xCC, 0xFB, 0x55, 0x28, 0xB3, 0xE4, 0x4A, 0xF7, 0x6C, 0x3B, 0xF4,
- 0x6A, 0x56, 0x2E, 0xDE, 0x1F, 0x9D, 0xB8, 0xD3, 0x05, 0x88, 0x92, 0xA6, 0xCE, 0x1E, 0xBE, 0xDF,
- 0x1D, 0x99, 0xB0, 0xE2, 0x46, 0xEF, 0x5C, 0x07, 0x11, 0x5D, 0x98, 0x0B, 0x9D, 0x94, 0x97, 0xEE,
- 0x4E, 0x45, 0x33, 0x6B, 0x44, 0xC7, 0x29, 0x56, 0x27, 0x30, 0xC6, 0xA7, 0xD5, 0xF2, 0x56, 0xDF,
- 0xB4, 0x38, 0x62, 0xCB, 0xA0, 0xB6, 0xE3, 0x0F, 0x84, 0x06, 0x24, 0x05, 0x65, 0x6F, 0x76, 0x89,
- 0xB5, 0x77, 0x41, 0x27, 0x82, 0x66, 0x65, 0x82, 0xCC, 0xD5, 0xE6, 0x20, 0xD5, 0x27, 0x17, 0xC5,
- 0xF8, 0x03, 0x23, 0x7C, 0x5F, 0x64, 0xA5, 0x1D, 0xC1, 0xD6, 0x36, 0xCB, 0x4C, 0xD4, 0xDB, 0x66,
- 0xD7, 0x8B, 0xB1, 0x99, 0x7E, 0x6F, 0x4C, 0x36, 0x40, 0x06, 0xD6, 0xEB, 0xD7, 0xA2, 0xE4, 0xF4,
- 0x95, 0x51, 0x5A, 0x54, 0x96, 0xD5, 0x53, 0x44, 0xD7, 0x8C, 0xE0, 0xB9, 0x40, 0x68, 0xD2, 0x18,
- 0xE9, 0xDD, 0x9A, 0x23, 0x92, 0x48, 0xEE, 0x7F, 0x43, 0xAF, 0xEA, 0x77, 0x38, 0x84, 0x8C, 0x0A,
- 0x72, 0xAF, 0x69, 0xF8, 0xDD, 0xF1, 0x24, 0x83, 0xA3, 0xF8, 0x4A, 0xBF, 0xF5, 0x94, 0x13, 0xDB,
- 0xBB, 0xD8, 0xB4, 0xB3, 0xA0, 0xFB, 0x45, 0x50, 0x60, 0x30, 0x59, 0x12, 0x31, 0x71, 0xA2, 0xD3,
- 0x13, 0xE7, 0xFA, 0xE7, 0xCE, 0x0F, 0x63, 0x15, 0x0B, 0x6B, 0x94, 0xBB, 0x37, 0x83, 0x26, 0x05,
- 0x9D, 0xFB, 0x46, 0x92, 0xFC, 0x0A, 0x15, 0xD1, 0x0D, 0x73, 0x92, 0xD6, 0x8C, 0x1B, 0x8C, 0xB8,
- 0x55, 0x8A, 0xCE, 0xBD, 0xFE, 0x8E, 0xFC, 0xED, 0x09, 0x12, 0x83, 0x91, 0x82, 0x51, 0x31, 0x23,
- 0xFB, 0xB4, 0x0C, 0x76, 0xAD, 0x7C, 0xD9, 0xB4, 0x4B, 0xB2, 0x67, 0x14, 0x09, 0x9C, 0x7F, 0x0C,
- 0x18, 0xBA, 0x3B, 0xD6, 0x8E, 0x14, 0x2A, 0xE4, 0x1B, 0x52, 0x9F, 0x2B, 0x7D, 0xE1, 0xFB, 0x6A,
- 0x33, 0x02, 0xFA, 0xAC, 0x5A, 0xF2, 0x3E, 0x88, 0x7E, 0xAE, 0xD1, 0xF3, 0x78, 0xE8, 0x05, 0xD1,
- 0xE3, 0xDC, 0x21, 0xF6, 0xE1, 0x9A, 0xBD, 0x17, 0x0E, 0xD9, 0x46, 0x9B, 0x88, 0x03, 0xEA, 0xF6,
- 0x66, 0xBE, 0x0E, 0x1B, 0x50, 0x49, 0x96, 0x40, 0x97, 0xF1, 0xF1, 0xE4, 0x80, 0xA6, 0x6E, 0xE8,
- 0x77, 0x34, 0xBF, 0x29, 0x40, 0x44, 0xC2, 0xFF, 0x4E, 0x98, 0xD3, 0x9C, 0xA3, 0x32, 0x2B, 0x76,
- 0x51, 0x04, 0x09, 0xE7, 0xA9, 0xD1, 0xA6, 0x32, 0xB1, 0x23, 0x53, 0xE2, 0x47, 0xAB, 0xD6, 0xF5,
- 0x69, 0x5C, 0x3E, 0x5F, 0xFA, 0xAE, 0x45, 0x20, 0xE5, 0xD2, 0x44, 0xFF, 0x39, 0x32, 0x6D, 0xFD,
- 0x27, 0x57, 0x5C, 0xFD, 0xF0, 0xDE, 0xC1, 0xB5, 0x99, 0xE5, 0xF5, 0x1C, 0x77, 0x01, 0x75, 0xC5,
- 0x6D, 0x58, 0x92, 0xF2, 0xB2, 0x47, 0x00, 0x01, 0x26, 0x96, 0x7A, 0x30, 0xFF, 0xB7, 0xF0, 0xEF,
- 0x77, 0xC1, 0x8A, 0x5D, 0xDC, 0xC0, 0xD1, 0x29, 0x30, 0x1E, 0x77, 0x38, 0x7A, 0x94, 0xF1, 0xB8,
- 0x7A, 0x7E, 0xEF, 0xA4, 0xD1, 0xAC, 0x31, 0x4A, 0xF2, 0x5D, 0x64, 0x3D, 0xB2, 0xE2, 0xF0, 0x08,
- 0x99, 0xFC, 0x70, 0xEE, 0x24, 0xA7, 0x7E, 0xEE, 0x1E, 0x20, 0x69, 0x7D, 0x44, 0xBF, 0x87, 0x42,
- 0xDF, 0x88, 0x3B, 0x0C, 0xDA, 0x42, 0xC9, 0x04, 0xF9, 0x45, 0x50, 0xFC, 0x83, 0x8F, 0x11, 0x6A,
- 0x72, 0xBC, 0x99, 0x95, 0xF0, 0xAC, 0x3D, 0xA7, 0x3B, 0xCD, 0x1C, 0xE2, 0x88, 0x79, 0x37, 0x11,
- 0x5F, 0x39, 0x89, 0x95, 0x0A, 0x16, 0x84, 0x7A, 0xF6, 0x8A, 0xA4, 0x28, 0xE4, 0xED, 0x83, 0x80,
- 0x3B, 0xB1, 0x23, 0xA5, 0x03, 0x10, 0xF4, 0x66, 0xEA, 0xBB, 0x0C, 0x0F, 0xC5, 0xEC, 0x6C, 0x69,
- 0xC5, 0xD3, 0x24, 0xAB, 0xD4, 0x2A, 0xB7, 0x99, 0x88, 0x76, 0x08, 0xA0, 0xA8, 0x95, 0x7C, 0xD8,
- 0x38, 0x6D, 0xCD, 0x59, 0x02, 0x51, 0x4B, 0xF1, 0xB5, 0x2B, 0x50, 0xE3, 0xB6, 0xBD, 0xD0, 0x72,
- 0xCF, 0x9E, 0xFD, 0x6E, 0xBB, 0x44, 0xC8, 0x24, 0x8A, 0x77, 0x18, 0x8A, 0x13, 0x06, 0xEF, 0x97,
- 0x7D, 0xFA, 0x81, 0xF0, 0x31, 0xE6, 0xFA, 0x77, 0xED, 0x31, 0x06, 0x31, 0x5B, 0x54, 0x8A, 0x9F,
- 0x30, 0x68, 0xDB, 0xE2, 0x40, 0xF8, 0x4E, 0x73, 0xFA, 0xAB, 0x74, 0x8B, 0x10, 0x58, 0x13, 0xDC,
- 0xD2, 0xE6, 0x78, 0xD1, 0x32, 0x2E, 0x8A, 0x9F, 0x2C, 0x58, 0x06, 0x48, 0x27, 0xC5, 0xA9, 0x5E,
- 0x81, 0x47, 0x89, 0x46, 0x21, 0x91, 0x03, 0x70, 0xA4, 0x3E, 0x88, 0x9C, 0xDA, 0x33, 0x0A, 0xCE,
- 0xBC, 0x8B, 0x8E, 0xCF, 0x9F, 0xD3, 0x71, 0x80, 0x43, 0xCF, 0x6B, 0xA9, 0x51, 0x83, 0x76, 0x30,
- 0x82, 0xC5, 0x6A, 0x85, 0x39, 0x11, 0x50, 0x1A, 0x82, 0xDC, 0x1E, 0x1C, 0xD5, 0x7D, 0xA9, 0x71,
- 0x99, 0x33, 0x47, 0x19, 0x97, 0xB3, 0x5A, 0xB1, 0xDF, 0xED, 0xA4, 0xF2, 0xE6, 0x26, 0x84, 0xA2,
- 0x28, 0x9A, 0x9E, 0xDF, 0xA6, 0x6A, 0xF4, 0xD6, 0xFC, 0x2E, 0x5B, 0x9D, 0x1A, 0x2A, 0x27, 0x68,
- 0xFB, 0xC1, 0x83, 0x21, 0x4B, 0x90, 0xE0, 0x36, 0xDD, 0x5B, 0x31, 0x42, 0x55, 0xA0, 0x13, 0xF7,
- 0xD0, 0x89, 0x53, 0x71, 0x99, 0x57, 0x09, 0x29, 0xC5, 0xF3, 0x21, 0xF8, 0x37, 0x2F, 0x40, 0xF3,
- 0xD4, 0xAF, 0x16, 0x08, 0x36, 0x02, 0xFC, 0x77, 0xC5, 0x8B, 0x04, 0x90, 0x56, 0xB9, 0xC9, 0x67,
- 0x9A, 0x99, 0xE8, 0x00, 0xD3, 0x86, 0xFF, 0x97, 0x2D, 0x08, 0xE9, 0xB7, 0xB3, 0x91, 0xBC, 0xDF,
- 0x45, 0xC6, 0xED, 0x0F, 0x8C, 0x4C, 0x1E, 0xE6, 0x5B, 0x6E, 0x38, 0x30, 0xE4, 0xAA, 0xE3, 0x95,
- 0xDE, 0xB9, 0xE4, 0x9A, 0xF5, 0xB2, 0x55, 0x9A, 0x87, 0x9B, 0xF6, 0x6A, 0xB2, 0xF2, 0x77, 0x9A,
- 0x31, 0xF4, 0x7A, 0x31, 0xD1, 0x1D, 0x04, 0xC0, 0x7C, 0x32, 0xA2, 0x9E, 0x9A, 0xF5, 0x62, 0xF8,
- 0x27, 0x8D, 0xBF, 0x51, 0xFF, 0xD3, 0xDF, 0x64, 0x37, 0x3F, 0x2A, 0x6F, 0x76, 0x3A, 0x7D, 0x77,
- 0x06, 0x9E, 0x77, 0x7F, 0x5E, 0xEB, 0x32, 0x51, 0xF9, 0x16, 0x66, 0x9A, 0x09, 0xF3, 0xB0, 0x08,
- 0xA4, 0x70, 0x96, 0x46, 0x30, 0xFF, 0xDA, 0x4F, 0xE9, 0x1B, 0xED, 0x8D, 0xF8, 0x74, 0x1F, 0x31,
- 0x92, 0xB3, 0x73, 0x17, 0x36, 0xDB, 0x91, 0x30, 0xD6, 0x88, 0x55, 0x6B, 0x34, 0x77, 0x87, 0x7A,
- 0xE7, 0xEE, 0x06, 0xC6, 0x1C, 0x8C, 0x19, 0x0C, 0x48, 0x46, 0x23, 0x5E, 0x9C, 0x07, 0x5C, 0xBF,
- 0xB4, 0x7E, 0xD6, 0x4F, 0x74, 0x9C, 0xE2, 0xC5, 0x50, 0x8B, 0xC5, 0x8B, 0x15, 0x90, 0x60, 0x62,
- 0x57, 0x29, 0xD0, 0x13, 0x43, 0xA1, 0x80, 0x88, 0x91, 0x00, 0x44, 0xC7, 0x4D, 0x19, 0x86, 0xCC,
- 0x2F, 0x2A, 0x75, 0x5A, 0xFC, 0xEB, 0x97, 0x2A, 0x70, 0xE3, 0x78, 0xD8, 0x91, 0xB0, 0x4F, 0x99,
- 0x07, 0xA3, 0x95, 0xEA, 0x24, 0x21, 0xD5, 0xDE, 0x51, 0x20, 0x93, 0x27, 0x0A, 0x30, 0x73, 0xA8,
- 0xFF, 0x8A, 0x97, 0xE9, 0xA7, 0x6A, 0x8E, 0x0D, 0xE8, 0xF0, 0xDF, 0xEC, 0xEA, 0xB4, 0x6C, 0x1D,
- 0x39, 0x2A, 0x62, 0x2D, 0x3D, 0x5A, 0x8B, 0x65, 0xF8, 0x90, 0x05, 0x2E, 0x7E, 0x91, 0x2C, 0x78,
- 0xEF, 0x8E, 0x7A, 0xC1, 0x2F, 0xAC, 0x78, 0xEE, 0xAF, 0x28, 0x45, 0x06, 0x4C, 0x26, 0xAF, 0x3B,
- 0xA2, 0xDB, 0xA3, 0x93, 0x06, 0xB5, 0x3C, 0xA5, 0xD8, 0xEE, 0x8F, 0xAF, 0x25, 0xCC, 0x3F, 0x85,
- 0x68, 0x48, 0xA9, 0x62, 0xCC, 0x97, 0x8F, 0x7F, 0x2A, 0xEA, 0xE0, 0x15, 0x0A, 0xAD, 0x62, 0x07,
- 0xBD, 0x45, 0xF8, 0x41, 0xD8, 0x36, 0xCB, 0x4C, 0xDB, 0x6E, 0xE6, 0x3A, 0xE7, 0xDA, 0x15, 0xE9,
- 0x29, 0x1E, 0x12, 0x10, 0xA0, 0x14, 0x2C, 0x0E, 0x3D, 0xF4, 0xBF, 0x39, 0x41, 0x92, 0x75, 0x0B,
- 0x25, 0x7B, 0xA3, 0xCE, 0x39, 0x9C, 0x15, 0x64, 0xC8, 0xFA, 0x3D, 0xEF, 0x73, 0x27, 0xFE, 0x26,
- 0x2E, 0xCE, 0xDA, 0x6E, 0xFD, 0x71, 0x8E, 0xDD, 0xFE, 0x76, 0xEE, 0xDC, 0x12, 0x5C, 0x02, 0xC5,
- 0x3A, 0x4E, 0x4E, 0x4F, 0xBF, 0xCA, 0x40, 0x15, 0xC7, 0x6E, 0x8D, 0x41, 0xF1, 0x10, 0xE0, 0x4F,
- 0x7E, 0x97, 0x7F, 0x1C, 0xAE, 0x47, 0x8E, 0x6B, 0xB1, 0x25, 0x31, 0xB0, 0x73, 0xC7, 0x1B, 0x97,
- 0x79, 0xF9, 0x80, 0xD3, 0x66, 0x22, 0x30, 0x07, 0x74, 0x1E, 0xE4, 0xD0, 0x80, 0x21, 0xD6, 0xEE,
- 0x6B, 0x6C, 0x4F, 0xBF, 0xF5, 0xB7, 0xD9, 0x09, 0x87, 0x2F, 0xA9, 0x14, 0xBE, 0x27, 0xD9, 0x72,
- 0x50, 0x01, 0xD4, 0x13, 0x73, 0xA6, 0xA7, 0x51, 0x02, 0x75, 0x25, 0xE1, 0xB3, 0x45, 0x34, 0x7D,
- 0xA8, 0x8E, 0xEB, 0xF3, 0x16, 0x49, 0xCB, 0x4F, 0x8C, 0xA1, 0xB9, 0x36, 0x85, 0x39, 0x75, 0x5D,
- 0x08, 0x00, 0xAE, 0xEB, 0xF6, 0xEA, 0xD7, 0x13, 0x3A, 0x21, 0x5A, 0x5F, 0x30, 0x84, 0x52, 0x26,
- 0x95, 0xC9, 0x14, 0xF2, 0x57, 0x55, 0x6B, 0xB1, 0x10, 0xC2, 0xE1, 0xBD, 0x3B, 0x51, 0xC0, 0xB7,
- 0x55, 0x4C, 0x71, 0x12, 0x26, 0xC7, 0x0D, 0xF9, 0x51, 0xA4, 0x38, 0x02, 0x05, 0x7F, 0xB8, 0xF1,
- 0x72, 0x4B, 0xBF, 0x71, 0x89, 0x14, 0xF3, 0x77, 0x38, 0xD9, 0x71, 0x24, 0xF3, 0x00, 0x11, 0xA1,
- 0xD8, 0xD4, 0x69, 0x27, 0x08, 0x37, 0x35, 0xC9, 0x11, 0x9D, 0x90, 0x1C, 0x0E, 0xE7, 0x1C, 0xFF,
- 0x2D, 0x1E, 0xE8, 0x92, 0xE1, 0x18, 0x10, 0x95, 0x7C, 0xE0, 0x80, 0xF4, 0x96, 0x43, 0x21, 0xF9,
- 0x75, 0x21, 0x64, 0x38, 0xDD, 0x9F, 0x1E, 0x95, 0x16, 0xDA, 0x56, 0x1D, 0x4F, 0x9A, 0x53, 0xB2,
- 0xE2, 0xE4, 0x18, 0xCB, 0x6B, 0x1A, 0x65, 0xEB, 0x56, 0xC6, 0x3B, 0xE5, 0xFE, 0xD8, 0x26, 0x3F,
- 0x3A, 0x84, 0x59, 0x72, 0x66, 0xA2, 0xF3, 0x75, 0xFF, 0xFB, 0x60, 0xB3, 0x22, 0xAD, 0x3F, 0x2D,
- 0x6B, 0xF9, 0xEB, 0xEA, 0x05, 0x7C, 0xD8, 0x8F, 0x6D, 0x2C, 0x98, 0x9E, 0x2B, 0x93, 0xF1, 0x5E,
- 0x46, 0xF0, 0x87, 0x49, 0x29, 0x73, 0x68, 0xD7, 0x7F, 0xF9, 0xF0, 0xE5, 0x7D, 0xDB, 0x1D, 0x75,
- 0x19, 0xF3, 0xC4, 0x58, 0x9B, 0x17, 0x88, 0xA8, 0x92, 0xE0, 0xBE, 0xBD, 0x8B, 0x1D, 0x8D, 0x9F,
- 0x56, 0x76, 0xAD, 0xAF, 0x29, 0xE2, 0xD9, 0xD5, 0x52, 0xF6, 0xB5, 0x56, 0x35, 0x57, 0x3A, 0xC8,
- 0xE1, 0x56, 0x43, 0x19, 0x94, 0xD3, 0x04, 0x9B, 0x6D, 0x35, 0xD8, 0x0B, 0x5F, 0x4D, 0x19, 0x8E,
- 0xEC, 0xFA, 0x64, 0x91, 0x0A, 0x72, 0x20, 0x2B, 0xBC, 0x1A, 0x4A, 0xFE, 0x8B, 0xFD, 0xBB, 0xED,
- 0x1B, 0x23, 0xEA, 0xAD, 0x72, 0x82, 0xA1, 0x29, 0x99, 0x71, 0xBD, 0xF0, 0x95, 0xC1, 0x03, 0xDD,
- 0x7B, 0xC2, 0xB2, 0x3C, 0x28, 0x54, 0xD3, 0x68, 0xA4, 0x72, 0xC8, 0x66, 0x96, 0xE0, 0xD1, 0xD8,
- 0x7F, 0xF8, 0xD1, 0x26, 0x2B, 0xF7, 0xAD, 0xBA, 0x55, 0xCA, 0x15, 0xB9, 0x32, 0xC3, 0xE5, 0x88,
- 0x97, 0x8E, 0x5C, 0xFB, 0x92, 0x25, 0x8B, 0xBF, 0xA2, 0x45, 0x55, 0x7A, 0xA7, 0x6F, 0x8B, 0x57,
- 0x5B, 0xCF, 0x0E, 0xCB, 0x1D, 0xFB, 0x20, 0x82, 0x77, 0xA8, 0x8C, 0xCC, 0x16, 0xCE, 0x1D, 0xFA,
- 0xDE, 0xCC, 0x0B, 0x62, 0xFE, 0xCC, 0xE1, 0xB7, 0xF0, 0xC3, 0x81, 0x64, 0x73, 0x40, 0xA0, 0xC2,
- 0x4D, 0x89, 0x11, 0x75, 0x33, 0x55, 0x33, 0x8D, 0xE8, 0x4A, 0xFD, 0xEA, 0x6E, 0x30, 0x0B, 0xD7,
- 0x31, 0x2C, 0xDE, 0x47, 0xE3, 0xBF, 0xF8, 0x55, 0x42, 0xE2, 0x7F, 0x59, 0xE5, 0x17, 0xEF, 0x99,
- 0x34, 0x69, 0x91, 0xB1, 0x23, 0x8E, 0x20, 0x87, 0x2D, 0xA8, 0xFE, 0xD5, 0x8A, 0xF3, 0x84, 0x3A,
- 0xF0, 0x37, 0xE4, 0x09, 0x00, 0x54, 0xEE, 0x67, 0x49, 0x93, 0xE4, 0x81, 0x70, 0xE3, 0x90, 0x4D,
- 0xEF, 0xFE, 0x41, 0xB7, 0x99, 0x7B, 0xC1, 0x83, 0xBA, 0x62, 0x12, 0x6F, 0x7D, 0xDE, 0x6B, 0xAF,
- 0xDA, 0x16, 0xF9, 0x55, 0x51, 0xEE, 0xA6, 0x0C, 0x2B, 0x02, 0xA3, 0xFD, 0x8D, 0xFB, 0x30, 0x17,
- 0xE4, 0x6F, 0xDF, 0x36, 0x71, 0xC4, 0xCA, 0x87, 0x25, 0x48, 0xB0, 0x47, 0xEC, 0xEA, 0xB4, 0xBF,
- 0xA5, 0x4D, 0x9B, 0x9F, 0x02, 0x93, 0xC4, 0xE3, 0xE4, 0xE8, 0x42, 0x2D, 0x68, 0x81, 0x15, 0x0A,
- 0xEB, 0x84, 0x5B, 0xD6, 0xA8, 0x74, 0xFB, 0x7D, 0x1D, 0xCB, 0x2C, 0xDA, 0x46, 0x2A, 0x76, 0x62,
- 0xCE, 0xBC, 0x5C, 0x9E, 0x8B, 0xE7, 0xCF, 0xBE, 0x78, 0xF5, 0x7C, 0xEB, 0xB3, 0x3A, 0x9C, 0xAA,
- 0x6F, 0xCC, 0x72, 0xD1, 0x59, 0xF2, 0x11, 0x23, 0xD6, 0x3F, 0x48, 0xD1, 0xB7, 0xCE, 0xB0, 0xBF,
- 0xCB, 0xEA, 0x80, 0xDE, 0x57, 0xD4, 0x5E, 0x97, 0x2F, 0x75, 0xD1, 0x50, 0x8E, 0x80, 0x2C, 0x66,
- 0x79, 0xBF, 0x72, 0x4B, 0xBD, 0x8A, 0x81, 0x6C, 0xD3, 0xE1, 0x01, 0xDC, 0xD2, 0x15, 0x26, 0xC5,
- 0x36, 0xDA, 0x2C, 0x1A, 0xC0, 0x27, 0x94, 0xED, 0xB7, 0x9B, 0x85, 0x0B, 0x5E, 0x80, 0x97, 0xC5,
- 0xEC, 0x4F, 0xEC, 0x88, 0x5D, 0x50, 0x07, 0x35, 0x47, 0xDC, 0x0B, 0x3B, 0x3D, 0xDD, 0x60, 0xAF,
- 0xA8, 0x5D, 0x81, 0x38, 0x24, 0x25, 0x5D, 0x5C, 0x15, 0xD1, 0xDE, 0xB3, 0xAB, 0xEC, 0x05, 0x69,
- 0xEF, 0x83, 0xED, 0x57, 0x54, 0xB8, 0x64, 0x64, 0x11, 0x16, 0x32, 0x69, 0xDA, 0x9F, 0x2D, 0x7F,
- 0x36, 0xBB, 0x44, 0x5A, 0x34, 0xE8, 0x7F, 0xBF, 0x03, 0xEB, 0x00, 0x7F, 0x59, 0x68, 0x22, 0x79,
- 0xCF, 0x73, 0x6C, 0x2C, 0x29, 0xA7, 0xA1, 0x5F, 0x38, 0xA1, 0x1D, 0xF0, 0x20, 0x53, 0xE0, 0x1A,
- 0x63, 0x14, 0x58, 0x71, 0x10, 0xAA, 0x08, 0x0C, 0x3E, 0x16, 0x1A, 0x60, 0x22, 0x82, 0x7F, 0xBA,
- 0xA4, 0x43, 0xA0, 0xD0, 0xAC, 0x1B, 0xD5, 0x6B, 0x64, 0xB5, 0x14, 0x93, 0x31, 0x9E, 0x53, 0x50,
- 0xD0, 0x57, 0x66, 0xEE, 0x5A, 0x4F, 0xFB, 0x03, 0x2A, 0x69, 0x58, 0x76, 0xF1, 0x83, 0xF7, 0x4E,
- 0xBA, 0x8C, 0x42, 0x06, 0x60, 0x5D, 0x6D, 0xCE, 0x60, 0x88, 0xAE, 0xA4, 0xC3, 0xF1, 0x03, 0xA5,
- 0x4B, 0x98, 0xA1, 0xFF, 0x67, 0xE1, 0xAC, 0xA2, 0xB8, 0x62, 0xD7, 0x6F, 0xA0, 0x31, 0xB4, 0xD2,
- 0x77, 0xAF, 0x21, 0x10, 0x06, 0xC6, 0x9A, 0xFF, 0x1D, 0x09, 0x17, 0x0E, 0x5F, 0xF1, 0xAA, 0x54,
- 0x34, 0x4B, 0x45, 0x8A, 0x87, 0x63, 0xA6, 0xDC, 0xF9, 0x24, 0x30, 0x67, 0xC6, 0xB2, 0xD6, 0x61,
- 0x33, 0x69, 0xEE, 0x50, 0x61, 0x57, 0x28, 0xE7, 0x7E, 0xEE, 0xEC, 0x3A, 0x5A, 0x73, 0x4E, 0xA8,
- 0x8D, 0xE4, 0x18, 0xEA, 0xEC, 0x41, 0x64, 0xC8, 0xE2, 0xE8, 0x66, 0xB6, 0x2D, 0xB6, 0xFB, 0x6A,
- 0x6C, 0x16, 0xB3, 0xDD, 0x46, 0x43, 0xB9, 0x73, 0x00, 0x6A, 0x71, 0xED, 0x4E, 0x9D, 0x25, 0x1A,
- 0xC3, 0x3C, 0x4A, 0x95, 0x15, 0x99, 0x35, 0x81, 0x14, 0x02, 0xD6, 0x98, 0x9B, 0xEC, 0xD8, 0x23,
- 0x3B, 0x84, 0x29, 0xAF, 0x0C, 0x99, 0x83, 0xA6, 0x9A, 0x34, 0x4F, 0xFA, 0xE8, 0xD0, 0x3C, 0x4B,
- 0xD0, 0xFB, 0xB6, 0x68, 0xB8, 0x9E, 0x8F, 0xCD, 0xF7, 0x60, 0x2D, 0x7A, 0x22, 0xE5, 0x7D, 0xAB,
- 0x65, 0x1B, 0x95, 0xA7, 0xA8, 0x7F, 0xB6, 0x77, 0x47, 0x7B, 0x5F, 0x8B, 0x12, 0x72, 0xD0, 0xD4,
- 0x91, 0xEF, 0xDE, 0x19, 0x50, 0x3C, 0xA7, 0x8B, 0xC4, 0xA9, 0xB3, 0x23, 0xCB, 0x76, 0xE6, 0x81,
- 0xF0, 0xC1, 0x04, 0x8F, 0xA3, 0xB8, 0x54, 0x5B, 0x97, 0xAC, 0x19, 0xFF, 0x3F, 0x55, 0x27, 0x2F,
- 0xE0, 0x1D, 0x42, 0x9B, 0x57, 0xFC, 0x4B, 0x4E, 0x0F, 0xCE, 0x98, 0xA9, 0x43, 0x57, 0x03, 0xBD,
- 0xE7, 0xC8, 0x94, 0xDF, 0x6E, 0x36, 0x73, 0x32, 0xB4, 0xEF, 0x2E, 0x85, 0x7A, 0x6E, 0xFC, 0x6C,
- 0x18, 0x82, 0x75, 0x35, 0x90, 0x07, 0xF3, 0xE4, 0x9F, 0x3E, 0xDC, 0x68, 0xF3, 0xB5, 0xF3, 0x19,
- 0x80, 0x92, 0x06, 0x99, 0xA2, 0xE8, 0x6F, 0xFF, 0x2E, 0x7F, 0xAE, 0x42, 0xA4, 0x5F, 0xFB, 0xD4,
- 0x0E, 0x81, 0x2B, 0xC3, 0x04, 0xFF, 0x2B, 0xB3, 0x74, 0x4E, 0x36, 0x5B, 0x9C, 0x15, 0x00, 0xC6,
- 0x47, 0x2B, 0xE8, 0x8B, 0x3D, 0xF1, 0x9C, 0x03, 0x9A, 0x58, 0x7F, 0x9B, 0x9C, 0xBF, 0x85, 0x49,
- 0x79, 0x35, 0x2E, 0x56, 0x7B, 0x41, 0x14, 0x39, 0x47, 0x83, 0x26, 0xAA, 0x07, 0x89, 0x98, 0x11,
- 0x1B, 0x86, 0xE7, 0x73, 0x7A, 0xD8, 0x7D, 0x78, 0x61, 0x53, 0xE9, 0x79, 0xF5, 0x36, 0x8D, 0x44,
- 0x92, 0x84, 0xF9, 0x13, 0x50, 0x58, 0x3B, 0xA4, 0x6A, 0x36, 0x65, 0x49, 0x8E, 0x3C, 0x0E, 0xF1,
- 0x6F, 0xD2, 0x84, 0xC4, 0x7E, 0x8E, 0x3F, 0x39, 0xAE, 0x7C, 0x84, 0xF1, 0x63, 0x37, 0x8E, 0x3C,
- 0xCC, 0x3E, 0x44, 0x81, 0x45, 0xF1, 0x4B, 0xB9, 0xED, 0x6B, 0x36, 0x5D, 0xBB, 0x20, 0x60, 0x1A,
- 0x0F, 0xA3, 0xAA, 0x55, 0x77, 0x3A, 0xA9, 0xAE, 0x37, 0x4D, 0xBA, 0xB8, 0x86, 0x6B, 0xBC, 0x08,
- 0x50, 0xF6, 0xCC, 0xA4, 0xBD, 0x1D, 0x40, 0x72, 0xA5, 0x86, 0xFA, 0xE2, 0x10, 0xAE, 0x3D, 0x58,
- 0x4B, 0x97, 0xF3, 0x43, 0x74, 0xA9, 0x9E, 0xEB, 0x21, 0xB7, 0x01, 0xA4, 0x86, 0x93, 0x97, 0xEE,
- 0x2F, 0x4F, 0x3B, 0x86, 0xA1, 0x41, 0x6F, 0x41, 0x26, 0x90, 0x78, 0x5C, 0x7F, 0x30, 0x38, 0x4B,
- 0x3F, 0xAA, 0xEC, 0xED, 0x5C, 0x6F, 0x0E, 0xAD, 0x43, 0x87, 0xFD, 0x93, 0x35, 0xE6, 0x01, 0xEF,
- 0x41, 0x26, 0x90, 0x99, 0x9E, 0xFB, 0x19, 0x5B, 0xAD, 0xD2, 0x91, 0x8A, 0xE0, 0x46, 0xAF, 0x65,
- 0xFA, 0x4F, 0x84, 0xC1, 0xA1, 0x2D, 0xCF, 0x45, 0x8B, 0xD3, 0x85, 0x50, 0x55, 0x7C, 0xF9, 0x67,
- 0x88, 0xD4, 0x4E, 0xE9, 0xD7, 0x6B, 0x61, 0x54, 0xA1, 0xA4, 0xA6, 0xA2, 0xC2, 0xBF, 0x30, 0x9C,
- 0x40, 0x9F, 0x5F, 0xD7, 0x69, 0x2B, 0x24, 0x82, 0x5E, 0xD9, 0xD6, 0xA7, 0x12, 0x54, 0x1A, 0xF7,
- 0x55, 0x9F, 0x76, 0x50, 0xA9, 0x95, 0x84, 0xE6, 0x6B, 0x6D, 0xB5, 0x96, 0x54, 0xD6, 0xCD, 0xB3,
- 0xA1, 0x9B, 0x46, 0xA7, 0x94, 0x4D, 0xC4, 0x94, 0xB4, 0x98, 0xE3, 0xE1, 0xE2, 0x34, 0xD5, 0x33,
- 0x16, 0x07, 0x54, 0xCD, 0xB7, 0x77, 0x53, 0xDB, 0x4F, 0x4D, 0x46, 0x9D, 0xE9, 0xD4, 0x9C, 0x8A,
- 0x36, 0xB6, 0xB8, 0x38, 0x26, 0x6C, 0x0E, 0xFF, 0x9C, 0x1B, 0x43, 0x8B, 0x80, 0xCC, 0xB9, 0x3D,
- 0xDA, 0xC7, 0xF1, 0x8A, 0xF2, 0x6D, 0xB8, 0xD7, 0x74, 0x2F, 0x7E, 0x1E, 0xB7, 0xD3, 0x4A, 0xB4,
- 0xAC, 0xFC, 0x79, 0x48, 0x6C, 0xBC, 0x96, 0xB6, 0x94, 0x46, 0x57, 0x2D, 0xB0, 0xA3, 0xFC, 0x1E,
- 0xB9, 0x52, 0x60, 0x85, 0x2D, 0x41, 0xD0, 0x43, 0x01, 0x1E, 0x1C, 0xD5, 0x7D, 0xFC, 0xF3, 0x96,
- 0x0D, 0xC7, 0xCB, 0x2A, 0x29, 0x9A, 0x93, 0xDD, 0x88, 0x2D, 0x37, 0x5D, 0xAA, 0xFB, 0x49, 0x68,
- 0xA0, 0x9C, 0x50, 0x86, 0x7F, 0x68, 0x56, 0x57, 0xF9, 0x79, 0x18, 0x39, 0xD4, 0xE0, 0x01, 0x84,
- 0x33, 0x61, 0xCA, 0xA5, 0xD2, 0xD6, 0xE4, 0xC9, 0x8A, 0x4A, 0x23, 0x44, 0x4E, 0xBC, 0xF0, 0xDC,
- 0x24, 0xA1, 0xA0, 0xC4, 0xE2, 0x07, 0x3C, 0x10, 0xC4, 0xB5, 0x25, 0x4B, 0x65, 0x63, 0xF4, 0x80,
- 0xE7, 0xCF, 0x61, 0xB1, 0x71, 0x82, 0x21, 0x87, 0x2C, 0xF5, 0x91, 0x00, 0x32, 0x0C, 0xEC, 0xA9,
- 0xB5, 0x9A, 0x74, 0x85, 0xE3, 0x36, 0x8F, 0x76, 0x4F, 0x9C, 0x6D, 0xCE, 0xBC, 0xAD, 0x0A, 0x4B,
- 0xED, 0x76, 0x04, 0xCB, 0xC3, 0xB9, 0x33, 0x9E, 0x01, 0x93, 0x96, 0x69, 0x7D, 0xC5, 0xA2, 0x45,
- 0x79, 0x9B, 0x04, 0x5C, 0x84, 0x09, 0xED, 0x88, 0x43, 0xC7, 0xAB, 0x93, 0x14, 0x26, 0xA1, 0x40,
- 0xB5, 0xCE, 0x4E, 0xBF, 0x2A, 0x42, 0x85, 0x3E, 0x2C, 0x3B, 0x54, 0xE8, 0x12, 0x1F, 0x0E, 0x97,
- 0x59, 0xB2, 0x27, 0x89, 0xFA, 0xF2, 0xDF, 0x8E, 0x68, 0x59, 0xDC, 0x06, 0xBC, 0xB6, 0x85, 0x0D,
- 0x06, 0x22, 0xEC, 0xB1, 0xCB, 0xE5, 0x04, 0xE6, 0x3D, 0xB3, 0xB0, 0x41, 0x73, 0x08, 0x3F, 0x3C,
- 0x58, 0x86, 0x63, 0xEB, 0x50, 0xEE, 0x1D, 0x2C, 0x37, 0x74, 0xA9, 0xD3, 0x18, 0xA3, 0x47, 0x6E,
- 0x93, 0x54, 0xAD, 0x0A, 0x5D, 0xB8, 0x2A, 0x55, 0x5D, 0x78, 0xF6, 0xEE, 0xBE, 0x8E, 0x3C, 0x76,
- 0x69, 0xB9, 0x40, 0xC2, 0x34, 0xEC, 0x2A, 0xB9, 0xED, 0x7E, 0x20, 0xE4, 0x8D, 0x00, 0x38, 0xC7,
- 0xE6, 0x8F, 0x44, 0xA8, 0x86, 0xCE, 0xEB, 0x2A, 0xE9, 0x90, 0xF1, 0x4C, 0xDF, 0x32, 0xFB, 0x73,
- 0x1B, 0x6D, 0x92, 0x1E, 0x95, 0xFE, 0xB4, 0xDB, 0x65, 0xDF, 0x4D, 0x23, 0x54, 0x89, 0x48, 0xBF,
- 0x4A, 0x2E, 0x70, 0xD6, 0xD7, 0x62, 0xB4, 0x33, 0x29, 0xB1, 0x3A, 0x33, 0x4C, 0x23, 0x6D, 0xA6,
- 0x76, 0xA5, 0x21, 0x63, 0x48, 0xE6, 0x90, 0x5D, 0xED, 0x90, 0x95, 0x0B, 0x7A, 0x84, 0xBE, 0xB8,
- 0x0D, 0x5E, 0x63, 0x0C, 0x62, 0x26, 0x4C, 0x14, 0x5A, 0xB3, 0xAC, 0x23, 0xA4, 0x74, 0xA7, 0x6F,
- 0x33, 0x30, 0x05, 0x60, 0x01, 0x42, 0xA0, 0x28, 0xB7, 0xEE, 0x19, 0x38, 0xF1, 0x64, 0x80, 0x82,
- 0x43, 0xE1, 0x41, 0x27, 0x1F, 0x1F, 0x90, 0x54, 0x7A, 0xD5, 0x23, 0x2E, 0xD1, 0x3D, 0xCB, 0x28,
- 0xBA, 0x58, 0x7F, 0xDC, 0x7C, 0x91, 0x24, 0xE9, 0x28, 0x51, 0x83, 0x6E, 0xC5, 0x56, 0x21, 0x42,
- 0xED, 0xA0, 0x56, 0x22, 0xA1, 0x40, 0x80, 0x6B, 0xA8, 0xF7, 0x94, 0xCA, 0x13, 0x6B, 0x0C, 0x39,
- 0xD9, 0xFD, 0xE9, 0xF3, 0x6F, 0xA6, 0x9E, 0xFC, 0x70, 0x8A, 0xB3, 0xBC, 0x59, 0x3C, 0x1E, 0x1D,
- 0x6C, 0xF9, 0x7C, 0xAF, 0xF9, 0x88, 0x71, 0x95, 0xEB, 0x57, 0x00, 0xBD, 0x9F, 0x8C, 0x4F, 0xE1,
- 0x24, 0x83, 0xC5, 0x22, 0xEA, 0xFD, 0xD3, 0x0C, 0xE2, 0x17, 0x18, 0x7C, 0x6A, 0x4C, 0xDE, 0x77,
- 0xB4, 0x53, 0x9B, 0x4C, 0x81, 0xCD, 0x23, 0x60, 0xAA, 0x0E, 0x25, 0x73, 0x9C, 0x02, 0x79, 0x32,
- 0x30, 0xDF, 0x74, 0xDF, 0x75, 0x19, 0xF4, 0xA5, 0x14, 0x5C, 0xF7, 0x7A, 0xA8, 0xA5, 0x91, 0x84,
- 0x7C, 0x60, 0x03, 0x06, 0x3B, 0xCD, 0x50, 0xB6, 0x27, 0x9C, 0xFE, 0xB1, 0xDD, 0xCC, 0xD3, 0xB0,
- 0x59, 0x24, 0xB2, 0xCA, 0xE2, 0x1C, 0x81, 0x22, 0x9D, 0x07, 0x8F, 0x8E, 0xB9, 0xBE, 0x4E, 0xFA,
- 0xFC, 0x39, 0x65, 0xBA, 0xBF, 0x9D, 0x12, 0x37, 0x5E, 0x97, 0x7E, 0xF3, 0x89, 0xF5, 0x5D, 0xF5,
- 0xE3, 0x09, 0x8C, 0x62, 0xB5, 0x20, 0x9D, 0x0C, 0x53, 0x8A, 0x68, 0x1B, 0xD2, 0x8F, 0x75, 0x17,
- 0x5D, 0xD4, 0xE5, 0xDA, 0x75, 0x62, 0x19, 0x14, 0x6A, 0x26, 0x2D, 0xEB, 0xF8, 0xAF, 0x37, 0xF0,
- 0x6C, 0xA4, 0x55, 0xB1, 0xBC, 0xE2, 0x33, 0xC0, 0x9A, 0xCA, 0xB0, 0x11, 0x49, 0x4F, 0x68, 0x9B,
- 0x3B, 0x6B, 0x3C, 0xCC, 0x13, 0xF6, 0xC7, 0x85, 0x61, 0x68, 0x42, 0xAE, 0xBB, 0xDD, 0xCD, 0x45,
- 0x16, 0x29, 0x1D, 0xEA, 0xDB, 0xC8, 0x03, 0x94, 0x3C, 0xEE, 0x4F, 0x82, 0x11, 0xC3, 0xEC, 0x28,
- 0xBD, 0x97, 0x05, 0x99, 0xDE, 0xD7, 0xBB, 0x5E, 0x22, 0x1F, 0xD4, 0xEB, 0x64, 0xD9, 0x92, 0xD9,
- 0x85, 0xB7, 0x6A, 0x05, 0x6A, 0xE4, 0x24, 0x41, 0xF1, 0xCD, 0xF0, 0xD8, 0x3F, 0xF8, 0x9E, 0x0E,
- 0xCD, 0x0B, 0x7A, 0x70, 0x6B, 0x5A, 0x75, 0x0A, 0x6A, 0x33, 0x88, 0xEC, 0x17, 0x75, 0x08, 0x70,
- 0x10, 0x2F, 0x24, 0xCF, 0xC4, 0xE9, 0x42, 0x00, 0x61, 0x94, 0xCA, 0x1F, 0x3A, 0x76, 0x06, 0xFA,
- 0xD2, 0x48, 0x81, 0xF0, 0x77, 0x60, 0x03, 0x45, 0xD9, 0x61, 0xF4, 0xA4, 0x6F, 0x3D, 0xD9, 0x30,
- 0xC3, 0x04, 0x6B, 0x54, 0x2A, 0xB7, 0xEC, 0x3B, 0xF4, 0x4B, 0xF5, 0x68, 0x52, 0x26, 0xCE, 0xFF,
- 0x5D, 0x19, 0x91, 0xA0, 0xA3, 0xA5, 0xA9, 0xB1, 0xE0, 0x23, 0xC4, 0x0A, 0x77, 0x4D, 0xF9, 0x51,
- 0x20, 0xA3, 0xA5, 0xA9, 0xB1, 0xC1, 0x00, 0x82, 0x86, 0x8E, 0x7F, 0x5D, 0x19, 0x91, 0xA0, 0xA3,
- 0xC4, 0xEB, 0x54, 0x0B, 0x75, 0x68, 0x52, 0x07, 0x8C, 0x9A, 0x97, 0x8D, 0x79, 0x70, 0x62, 0x46,
- 0xEF, 0x5C, 0x1B, 0x95, 0x89, 0x71, 0x41, 0xE1, 0x21, 0xA1, 0xA1, 0xA1, 0xC0, 0x02, 0x67, 0x4C,
- 0x1A, 0xB6, 0xCF, 0xFD, 0x78, 0x53, 0x24, 0xAB, 0xB5, 0xC9, 0xF1, 0x60, 0x23, 0xA5, 0xC8, 0x12,
- 0x87, 0x6D, 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x6D, 0x58, 0x32, 0xC7, 0x0C, 0x9A, 0x97, 0xAC,
- 0xDA, 0x36, 0xEE, 0x5E, 0x3E, 0xDF, 0x1D, 0xB8, 0xF2, 0x66, 0x2F, 0xBD, 0xF8, 0x72, 0x47, 0xED,
- 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x8C, 0x7B, 0x55, 0x09, 0x90, 0xA2, 0xC6, 0xEF, 0x3D, 0xF8,
- 0x53, 0x24, 0xAB, 0xD4, 0x2A, 0xB7, 0xEC, 0x5A, 0x36, 0xEE, 0x5E, 0x3E, 0xDF, 0x3C, 0xFA, 0x76,
- 0x4F, 0xFD, 0x59, 0x30, 0xE2, 0x46, 0xEF, 0x3D, 0xF8, 0x53, 0x05, 0x69, 0x31, 0xC1, 0x00, 0x82,
- 0x86, 0x8E, 0x7F, 0x5D, 0x19, 0xB0, 0xE2, 0x27, 0xCC, 0xFB, 0x74, 0x4B, 0x14, 0x8B, 0x94, 0x8B,
- 0x75, 0x68, 0x33, 0xC5, 0x08, 0x92, 0x87, 0x8C, 0x9A, 0xB6, 0xCF, 0x1C, 0xBA, 0xD7, 0x0D, 0x98,
- 0xB2, 0xE6, 0x2F, 0xDC, 0x1B, 0x95, 0x89, 0x71, 0x60, 0x23, 0xC4, 0x0A, 0x96, 0x8F, 0x9C, 0xBA,
- 0xF6, 0x6E, 0x3F, 0xFC, 0x5B, 0x15, 0xA8, 0xD2, 0x26, 0xAF, 0xBD, 0xF8, 0x72, 0x66, 0x2F, 0xDC,
- 0x1B, 0xB4, 0xCB, 0x14, 0x8B, 0x94, 0xAA, 0xB7, 0xCD, 0xF9, 0x51, 0x01, 0x80, 0x82, 0x86, 0x6F,
- 0x3D, 0xD9, 0x30, 0xE2, 0x27, 0xCC, 0xFB, 0x74, 0x4B, 0x14, 0xAA, 0xB7, 0xCD, 0xF9, 0x70, 0x43,
- 0x04, 0x6B, 0x35, 0xC9, 0xF1, 0x60, 0x23, 0xA5, 0xC8, 0xF3, 0x45, 0x08, 0x92, 0x87, 0x6D, 0x58,
- 0x32, 0xE6, 0x2F, 0xBD, 0xF8, 0x72, 0x66, 0x4E, 0x1E, 0xBE, 0xFE, 0x7E, 0x7E, 0x7E, 0x5F, 0x1D,
- 0x99, 0x91, 0xA0, 0xA3, 0xC4, 0x0A, 0x77, 0x4D, 0x18, 0x93, 0xA4, 0xAB, 0xD4, 0x0B, 0x75, 0x49,
- 0x10, 0xA2, 0xC6, 0xEF, 0x3D, 0xF8, 0x53, 0x24, 0xAB, 0xB5, 0xE8, 0x33, 0xE4, 0x4A, 0x16, 0xAE,
- 0xDE, 0x1F, 0xBC, 0xDB, 0x15, 0xA8, 0xB3, 0xC5, 0x08, 0x73, 0x45, 0xE9, 0x31, 0xC1, 0xE1, 0x21,
- 0xA1, 0xA1, 0xA1, 0xC0, 0x02, 0x86, 0x6F, 0x5C, 0x3A, 0xD7, 0x0D, 0x98, 0x93, 0xA4, 0xCA, 0x16,
- 0xAE, 0xDE, 0x1F, 0x9D, 0x99, 0xB0, 0xE2, 0x46, 0xEF, 0x3D, 0xF8, 0x72, 0x47, 0x0C, 0x9A, 0xB6,
- 0xCF, 0xFD, 0x59, 0x11, 0xA0, 0xA3, 0xA5, 0xC8, 0xF3, 0x45, 0x08, 0x92, 0x87, 0x6D, 0x39, 0xF0,
- 0x43, 0x04, 0x8A, 0x96, 0xAE, 0xDE, 0x3E, 0xDF, 0x1D, 0x99, 0x91, 0xA0, 0xC2, 0x06, 0x6F, 0x3D,
- 0xF8, 0x72, 0x47, 0x0C, 0x9A, 0x97, 0x8D, 0x98, 0x93, 0x85, 0x88, 0x73, 0x45, 0xE9, 0x31, 0xE0,
- 0x23, 0xA5, 0xA9, 0xD0, 0x03, 0x84, 0x8A, 0x96, 0xAE, 0xDE, 0x1F, 0xBC, 0xDB, 0x15, 0xA8, 0xD2,
- 0x26, 0xCE, 0xFF, 0x5D, 0x19, 0x91, 0x81, 0x80, 0x82, 0x67, 0x2D, 0xD8, 0x13, 0xA4, 0xAB, 0xD4,
- 0x0B, 0x94, 0xAA, 0xB7, 0xCD, 0xF9, 0x51, 0x20, 0xA3, 0xA5, 0xC8, 0xF3, 0x45, 0xE9, 0x50, 0x22,
- 0xC6, 0xEF, 0x5C, 0x3A, 0xD7, 0x0D, 0x98, 0x93, 0x85, 0x88, 0x73, 0x64, 0x4A, 0xF7, 0x4D, 0xF9,
- 0x51, 0x20, 0xA3, 0xC4, 0x0A, 0x96, 0xAE, 0xDE, 0x3E, 0xFE, 0x7E, 0x7E, 0x7E, 0x5F, 0x3C, 0xFA,
- 0x76, 0x4F, 0xFD, 0x78, 0x72, 0x66, 0x2F, 0xBD, 0xD9, 0x30, 0xC3, 0xE5, 0x48, 0x12, 0x87, 0x8C,
- 0x7B, 0x55, 0x28, 0xD2, 0x07, 0x8C, 0x9A, 0x97, 0xAC, 0xDA, 0x17, 0x8D, 0x79, 0x51, 0x20, 0xA3,
- 0xC4, 0xEB, 0x54, 0x0B, 0x94, 0x8B, 0x94, 0xAA, 0xD6, 0x2E, 0xBF, 0xFC, 0x5B, 0x15, 0xA8, 0xD2,
- 0x26, 0xAF, 0xDC, 0x1B, 0xB4, 0xEA, 0x37, 0xEC, 0x3B, 0xF4, 0x6A, 0x37, 0xCD, 0x18, 0x93, 0x85,
- 0x69, 0x31, 0xC1, 0xE1, 0x40, 0xE3, 0x25, 0xC8, 0x12, 0x87, 0x8C, 0x9A, 0xB6, 0xCF, 0xFD, 0x59,
- 0x11, 0xA0, 0xC2, 0x06, 0x8E, 0x7F, 0x5D, 0x38, 0xF2, 0x47, 0x0C, 0x7B, 0x74, 0x6A, 0x37, 0xEC,
- 0x5A, 0x36, 0xEE, 0x3F, 0xFC, 0x7A, 0x76, 0x4F, 0x1C, 0x9B, 0x95, 0x89, 0x71, 0x41, 0x00, 0x63,
- 0x44, 0xEB, 0x54, 0x2A, 0xD6, 0x0F, 0x9C, 0xBA, 0xD7, 0x0D, 0x98, 0x93, 0x85, 0x69, 0x31, 0xC1,
- 0x00, 0x82, 0x86, 0x8E, 0x9E, 0xBE, 0xDF, 0x3C, 0xFA, 0x57, 0x2C, 0xDA, 0x36, 0xEE, 0x3F, 0xFC,
- 0x5B, 0x15, 0x89, 0x71, 0x41, 0x00, 0x82, 0x86, 0x8E, 0x7F, 0x5D, 0x38, 0xF2, 0x47, 0xED, 0x58,
- 0x13, 0xA4, 0xCA, 0xF7, 0x4D, 0xF9, 0x51, 0x01, 0x80, 0x63, 0x44, 0xEB, 0x54, 0x2A, 0xD6, 0x2E,
- 0xBF, 0xDD, 0x19, 0x91, 0xA0, 0xA3, 0xA5, 0xA9, 0xB1, 0xE0, 0x42, 0x06, 0x8E, 0x7F, 0x5D, 0x19,
- 0x91, 0xA0, 0xA3, 0xC4, 0x0A, 0x96, 0x8F, 0x7D, 0x78, 0x72, 0x47, 0x0C, 0x7B, 0x74, 0x6A, 0x56,
- 0x2E, 0xDE, 0x1F, 0xBC, 0xFA, 0x57, 0x0D, 0x79, 0x51, 0x01, 0x61, 0x21, 0xA1, 0xC0, 0xE3, 0x25,
- 0xA9, 0xB1, 0xC1, 0xE1, 0x40, 0x02, 0x67, 0x4C, 0x1A, 0x97, 0x8D, 0x98, 0x93, 0xA4, 0xAB, 0xD4,
- 0x2A, 0xD6, 0x0F, 0x9C, 0x9B, 0xB4, 0xCB, 0x14, 0xAA, 0xB7, 0xCD, 0xF9, 0x51, 0x20, 0xA3, 0xC4,
- 0xEB, 0x35, 0xC9, 0xF1, 0x60, 0x42, 0x06, 0x8E, 0x7F, 0x7C, 0x7A, 0x76, 0x6E, 0x3F, 0xFC, 0x7A,
- 0x76, 0x6E, 0x5E, 0x3E, 0xFE, 0x7E, 0x5F, 0x3C, 0xDB, 0x15, 0x89, 0x71, 0x41, 0xE1, 0x21, 0xC0,
- 0xE3, 0x44, 0xEB, 0x54, 0x2A, 0xB7, 0xCD, 0xF9, 0x70, 0x62, 0x27, 0xAD, 0xD8, 0x32, 0xC7, 0x0C,
- 0x7B, 0x74, 0x4B, 0x14, 0xAA, 0xB7, 0xEC, 0x3B, 0xD5, 0x28, 0xD2, 0x07, 0x6D, 0x39, 0xD1, 0x20,
- 0xC2, 0xE7, 0x4C, 0x1A, 0x97, 0x8D, 0x98, 0xB2, 0xC7, 0x0C, 0x59, 0x28, 0xF3, 0x9B
-};
-
-const pmw3360_srom_t pmw3360_srom_0x04 = {
- .data = srom_data_0x04,
- .len = sizeof(srom_data_0x04),
-};
diff --git a/keyboards/yowkees/drivers/pmw3360/srom_0x81.c b/keyboards/yowkees/drivers/pmw3360/srom_0x81.c
deleted file mode 100644
index 1a3016fbe83..00000000000
--- a/keyboards/yowkees/drivers/pmw3360/srom_0x81.c
+++ /dev/null
@@ -1,263 +0,0 @@
-static const uint8_t srom_data_0x81[] PROGMEM = {
- 0x01, 0x81, 0x01, 0x82, 0x46, 0x27, 0x9E, 0xBE, 0xFE, 0x5F, 0x3C, 0xFA, 0x76, 0x6E, 0x5E, 0x3E,
- 0xFE, 0x5F, 0x1D, 0x99, 0x91, 0xA0, 0xC2, 0x06, 0x8E, 0x9E, 0x9F, 0xBC, 0xDB, 0x34, 0xEA, 0x56,
- 0x0F, 0x9C, 0x9B, 0xB4, 0xCB, 0x14, 0x8B, 0x75, 0x68, 0x33, 0xC5, 0x08, 0x73, 0x45, 0xE9, 0x50,
- 0x22, 0xA7, 0xCC, 0xFB, 0x55, 0x28, 0xB3, 0xC5, 0x08, 0x92, 0xA6, 0xAF, 0xDC, 0x3A, 0xF6, 0x4F,
- 0x1C, 0x9B, 0xB4, 0xCB, 0x14, 0x8B, 0x94, 0xAF, 0xD6, 0x2E, 0xDE, 0x1F, 0x9D, 0xB8, 0xF2, 0x66,
- 0x4F, 0xFF, 0x7C, 0x7A, 0x76, 0x6E, 0x5E, 0x3E, 0xDF, 0x1D, 0x99, 0xB0, 0xE2, 0x46, 0x0D, 0x9E,
- 0x9B, 0xBC, 0xFA, 0x76, 0x6E, 0x5E, 0x1F, 0x9D, 0x99, 0xB6, 0xE2, 0x25, 0xCC, 0x1A, 0x97, 0xAC,
- 0xBB, 0xF4, 0x6A, 0x37, 0xCD, 0xF9, 0x70, 0xAA, 0xA2, 0x04, 0x6F, 0x9D, 0x8C, 0x1A, 0xBC, 0x44,
- 0x06, 0xAD, 0xE7, 0x73, 0x58, 0x33, 0x3A, 0x89, 0xAC, 0xAB, 0xE6, 0xF2, 0x59, 0x9C, 0xE4, 0x7F,
- 0xE2, 0x94, 0x9F, 0x6E, 0x56, 0x0B, 0x78, 0x79, 0xA8, 0x5E, 0xB5, 0x06, 0x63, 0x63, 0x6E, 0xB9,
- 0xF4, 0xF5, 0x64, 0x6D, 0x16, 0x4E, 0x35, 0xE2, 0x0C, 0x55, 0xE6, 0x20, 0xD5, 0xC6, 0xAB, 0x41,
- 0xD1, 0x51, 0xE6, 0xF6, 0x4B, 0x4C, 0xF5, 0x7D, 0x01, 0x56, 0x36, 0xCB, 0xAD, 0x16, 0x3E, 0x8D,
- 0x20, 0x44, 0x0E, 0x27, 0x02, 0x57, 0x5D, 0x75, 0xA7, 0xE9, 0x69, 0x55, 0x8A, 0xD8, 0x10, 0x35,
- 0x07, 0x8F, 0x07, 0xCA, 0x7C, 0x7A, 0x73, 0xC5, 0x8B, 0xE0, 0x35, 0xE7, 0xD1, 0x41, 0x5E, 0xD5,
- 0x5E, 0x5F, 0x09, 0xC7, 0x0A, 0x06, 0x6A, 0xFE, 0xEA, 0xDF, 0xB2, 0x4E, 0xBB, 0xBD, 0xFE, 0x82,
- 0x7E, 0xF6, 0x46, 0x32, 0x3E, 0xE0, 0xAC, 0xB6, 0x09, 0x89, 0x94, 0xD3, 0xE8, 0xFD, 0xF2, 0x4E,
- 0x3D, 0x9E, 0xC1, 0xBD, 0x86, 0x95, 0x11, 0xD7, 0x85, 0x80, 0xDA, 0x95, 0x86, 0x8D, 0xC9, 0xB3,
- 0xCB, 0xF4, 0x1A, 0x15, 0x94, 0x6C, 0x0B, 0x37, 0xCB, 0xA6, 0x9F, 0x1F, 0x87, 0xC0, 0xEC, 0xE4,
- 0x3A, 0x34, 0xF1, 0x4F, 0xDC, 0xD8, 0xCB, 0x6E, 0x5D, 0xB4, 0xB1, 0x9B, 0xD4, 0xA6, 0x28, 0x0E,
- 0xE1, 0x1F, 0x95, 0x6C, 0x4E, 0x76, 0x00, 0x42, 0x85, 0xDD, 0x0F, 0x7E, 0x9A, 0xC6, 0xAC, 0xED,
- 0x0C, 0xEA, 0xF4, 0x3D, 0x2A, 0x16, 0x0E, 0xEE, 0xFC, 0x35, 0x2B, 0x11, 0x69, 0x01, 0x03, 0x3F,
- 0x34, 0x07, 0x97, 0xBD, 0x3B, 0xAC, 0x16, 0x48, 0xFE, 0x0E, 0x1D, 0xC0, 0xCC, 0xF8, 0x96, 0xBF,
- 0x3F, 0xBD, 0x65, 0x9F, 0x70, 0xFA, 0xE7, 0xCB, 0xED, 0xCF, 0x94, 0x33, 0x7E, 0x60, 0x06, 0x49,
- 0x4D, 0x23, 0x25, 0xED, 0x00, 0xD5, 0x25, 0x18, 0x9C, 0x69, 0x8C, 0xC0, 0x74, 0x12, 0x65, 0xD0,
- 0x39, 0x06, 0xE0, 0xF9, 0x1A, 0x78, 0xD0, 0x65, 0x5F, 0xA9, 0xAC, 0x6A, 0x38, 0x52, 0x0F, 0x6C,
- 0xAA, 0x72, 0xA3, 0x8E, 0x39, 0x1E, 0x4A, 0x6A, 0xC7, 0xA9, 0x1A, 0xB3, 0xA5, 0x7E, 0x5B, 0x6C,
- 0x4F, 0xE8, 0xC2, 0x40, 0xCA, 0xEF, 0x0F, 0x1A, 0xB6, 0x56, 0x37, 0x3B, 0x39, 0x52, 0x38, 0xB7,
- 0x4E, 0x88, 0x56, 0xEF, 0x1A, 0x8A, 0xA0, 0x41, 0x76, 0xA8, 0xD3, 0xA2, 0x25, 0x13, 0xA5, 0xC4,
- 0x0E, 0x1E, 0x59, 0xE8, 0xC9, 0x19, 0xB6, 0xB4, 0x88, 0x86, 0x0B, 0x64, 0x44, 0xAF, 0xE2, 0xBC,
- 0x8A, 0x91, 0x09, 0xCD, 0xA7, 0x79, 0xE0, 0x57, 0xD1, 0xD4, 0xE7, 0x00, 0x77, 0x20, 0x27, 0xCC,
- 0xBA, 0x83, 0x90, 0x03, 0x88, 0x30, 0xA5, 0x90, 0x57, 0xEA, 0x2A, 0x3C, 0xE6, 0xE2, 0x8C, 0x56,
- 0xC5, 0xA2, 0xC3, 0xBE, 0x2D, 0x91, 0x40, 0xFE, 0x37, 0x99, 0xB8, 0x31, 0x9A, 0x8F, 0x35, 0x01,
- 0x11, 0x98, 0xC8, 0xDE, 0xD5, 0xA3, 0xC1, 0x1A, 0xEA, 0x00, 0xA9, 0xD4, 0x9C, 0xD0, 0x08, 0xFF,
- 0x76, 0xE2, 0xDD, 0x55, 0xDA, 0x47, 0xAD, 0x67, 0xC6, 0xC2, 0x3A, 0x43, 0xBF, 0x32, 0xFF, 0xE9,
- 0xF9, 0x88, 0xF3, 0xE2, 0x2D, 0xAD, 0xAB, 0x00, 0xBB, 0x2A, 0x0E, 0x74, 0x27, 0x27, 0xE8, 0x88,
- 0xB1, 0xA4, 0x92, 0x68, 0x94, 0x14, 0x5D, 0x20, 0xC6, 0xB7, 0x22, 0x0C, 0xFC, 0x66, 0x90, 0xA7,
- 0x94, 0x8E, 0x1D, 0xF8, 0x58, 0xC2, 0x86, 0x6A, 0x64, 0xA8, 0xC5, 0xAF, 0x26, 0xEB, 0x6D, 0x7C,
- 0xD8, 0x53, 0x0E, 0x6B, 0x02, 0xAB, 0x51, 0x8D, 0x81, 0x15, 0xF1, 0x84, 0xDD, 0x2A, 0x62, 0xBC,
- 0xDB, 0x15, 0x89, 0x71, 0x41, 0x75, 0xD0, 0xA7, 0x8B, 0xA6, 0x85, 0xAE, 0xEB, 0xF6, 0x64, 0xF4,
- 0x3F, 0x7D, 0x6B, 0x03, 0xEF, 0x58, 0x67, 0xEE, 0xBB, 0x14, 0xB9, 0xC2, 0x0F, 0xCC, 0x92, 0x05,
- 0x2A, 0xA1, 0x25, 0x78, 0x91, 0xB7, 0x6C, 0x37, 0xA1, 0xF7, 0x75, 0xAB, 0xB4, 0x56, 0xD8, 0xFE,
- 0xEF, 0xDF, 0x45, 0xE5, 0x8F, 0x70, 0xF3, 0xA7, 0xCC, 0x51, 0xF1, 0xE2, 0x71, 0x71, 0x33, 0x03,
- 0x11, 0xC0, 0xC3, 0x4C, 0x1D, 0x07, 0x56, 0x2F, 0x9D, 0xD0, 0x8F, 0x77, 0xE5, 0xDE, 0x38, 0x29,
- 0x96, 0x9D, 0xF8, 0xD9, 0x92, 0xC7, 0x26, 0x3E, 0x7F, 0xA0, 0x8B, 0xC4, 0x51, 0x68, 0x03, 0xBD,
- 0x32, 0x95, 0x90, 0xED, 0x90, 0xE1, 0x7C, 0xB6, 0xAA, 0xEF, 0xB1, 0x8F, 0x37, 0x16, 0x6B, 0x32,
- 0xD4, 0x4F, 0xE7, 0x88, 0x54, 0x40, 0xE6, 0x16, 0x6B, 0xEF, 0x7E, 0xDC, 0x9E, 0x3A, 0x75, 0x48,
- 0x43, 0x87, 0xA7, 0x93, 0xD0, 0x42, 0xD5, 0xDD, 0x7B, 0xF0, 0xE1, 0x43, 0x16, 0x85, 0xCE, 0x90,
- 0xC4, 0xD9, 0x07, 0xF3, 0x2E, 0xFB, 0x2C, 0x8A, 0xCE, 0xBC, 0x7E, 0xCC, 0x5B, 0x07, 0xFC, 0x4A,
- 0xAA, 0x56, 0x8C, 0xDE, 0xBD, 0x3C, 0x02, 0xE6, 0x49, 0x64, 0x82, 0xE4, 0xDA, 0xC1, 0x04, 0x33,
- 0xC0, 0xA0, 0xA3, 0x0F, 0x0D, 0x19, 0x64, 0xA5, 0xBF, 0x3F, 0xE2, 0xD0, 0x57, 0xE7, 0xB9, 0x52,
- 0x39, 0x64, 0xFF, 0x35, 0xA8, 0x34, 0x9E, 0x45, 0x6F, 0x7C, 0xCC, 0x3F, 0x85, 0x67, 0xB4, 0xC9,
- 0xA1, 0xF7, 0x49, 0xA9, 0xD4, 0xC5, 0x02, 0x24, 0x80, 0x3C, 0x5E, 0xDF, 0x6D, 0x6D, 0xC1, 0xA2,
- 0x23, 0x24, 0x9B, 0x3B, 0xB9, 0x87, 0x55, 0x8A, 0xF6, 0xD2, 0xB1, 0x2C, 0xAA, 0x74, 0x32, 0x2A,
- 0x11, 0x4C, 0xD9, 0x29, 0xDB, 0xA7, 0x4F, 0x98, 0x52, 0x38, 0x8D, 0x2E, 0x44, 0x63, 0x48, 0x74,
- 0x53, 0x24, 0x91, 0xC1, 0x04, 0x33, 0xB4, 0xB2, 0x25, 0x2D, 0x28, 0x93, 0xA2, 0x3B, 0x56, 0xAA,
- 0x36, 0x1B, 0x6C, 0x7E, 0x34, 0xB9, 0x70, 0x86, 0x87, 0xAC, 0xA4, 0x41, 0x83, 0x73, 0xA0, 0x20,
- 0xD0, 0x0F, 0xD6, 0xA3, 0x0C, 0x3F, 0xA5, 0x1B, 0xC1, 0x0A, 0x17, 0x89, 0xC8, 0x16, 0xBA, 0xFA,
- 0x4F, 0x99, 0xF3, 0x53, 0xE0, 0x67, 0xA5, 0xB3, 0x62, 0x75, 0x69, 0x4B, 0x42, 0x22, 0xB6, 0xE8,
- 0x04, 0x66, 0x91, 0xD9, 0x73, 0x53, 0x11, 0x3A, 0xF4, 0x5C, 0x46, 0xC2, 0x02, 0x3F, 0xB8, 0x81,
- 0xD0, 0x50, 0x0D, 0xFF, 0xDE, 0x34, 0x75, 0x1C, 0xDA, 0x05, 0x5E, 0x78, 0xB6, 0x59, 0x34, 0xA9,
- 0xE2, 0xDC, 0x45, 0x64, 0x7E, 0xDD, 0x1B, 0x7D, 0x6C, 0xAA, 0x41, 0xC7, 0x58, 0xA2, 0xA9, 0x90,
- 0x05, 0xDE, 0xE3, 0xF2, 0x31, 0xC2, 0x1C, 0xEE, 0xE1, 0x4B, 0x3C, 0xCA, 0x25, 0x31, 0xC5, 0x2D,
- 0x80, 0x62, 0x5C, 0x60, 0xC0, 0x09, 0x52, 0x64, 0x4A, 0xFA, 0x62, 0xB6, 0x79, 0xF7, 0x78, 0x83,
- 0xEB, 0x16, 0x6C, 0x0C, 0x87, 0x3A, 0xA1, 0x83, 0x9E, 0x04, 0x2B, 0xFE, 0x56, 0xFF, 0x4F, 0xE5,
- 0x2D, 0xDC, 0x43, 0xE4, 0x71, 0xB9, 0x34, 0xE1, 0x67, 0x5D, 0x8B, 0x58, 0xA9, 0x4F, 0xFA, 0x9C,
- 0xC3, 0xA6, 0xD8, 0xE6, 0x7C, 0xA5, 0xCC, 0x41, 0x31, 0x5A, 0x75, 0xAA, 0x29, 0xE7, 0x93, 0x57,
- 0x5B, 0x59, 0x0C, 0x7E, 0x07, 0xBD, 0xE9, 0xB4, 0xAA, 0xA7, 0x0A, 0x33, 0xD5, 0x79, 0x29, 0xDC,
- 0x6B, 0x6D, 0x13, 0xB4, 0x8A, 0xC9, 0x62, 0x07, 0xDE, 0x84, 0x20, 0x26, 0x69, 0xD8, 0x3B, 0x35,
- 0x14, 0x42, 0xF3, 0xEC, 0xD9, 0x29, 0x93, 0x33, 0xEB, 0x4E, 0xD5, 0xED, 0xFF, 0x95, 0xA1, 0x20,
- 0xDF, 0xB4, 0x3C, 0x93, 0x46, 0x57, 0x6F, 0x0B, 0x20, 0xF9, 0xC3, 0xA3, 0x7D, 0xB4, 0x7D, 0xA1,
- 0x4F, 0x68, 0xEB, 0xDA, 0xA5, 0x70, 0xCE, 0x7B, 0xB6, 0xE8, 0xB7, 0x2E, 0x5F, 0x7F, 0xDF, 0xFF,
- 0xBF, 0x6D, 0xDA, 0x32, 0x07, 0x4C, 0xFE, 0xDC, 0xB8, 0x12, 0x61, 0xA3, 0xF1, 0xA3, 0x99, 0x03,
- 0x15, 0x4B, 0xA2, 0x05, 0xDE, 0xC5, 0xFB, 0x61, 0x68, 0xF0, 0x17, 0xEC, 0x2B, 0x71, 0x1F, 0xEA,
- 0x7B, 0xF5, 0x4A, 0x54, 0x82, 0x74, 0x11, 0x76, 0x72, 0x8B, 0x99, 0x95, 0xF0, 0x26, 0xDA, 0xCA,
- 0xB5, 0xC7, 0x1D, 0x2C, 0xB2, 0x27, 0x17, 0x0E, 0xA5, 0x7B, 0xC6, 0x8C, 0x97, 0x7E, 0x66, 0x3B,
- 0x84, 0x29, 0xDC, 0xCB, 0x6C, 0x2D, 0xA8, 0x50, 0x29, 0x4E, 0x06, 0xFB, 0x04, 0x08, 0x79, 0x8D,
- 0xE0, 0x14, 0x51, 0xF6, 0x53, 0x85, 0x2C, 0xDF, 0x64, 0x5A, 0x81, 0xFE, 0x55, 0x54, 0x50, 0xEB,
- 0xC0, 0xA1, 0x80, 0x20, 0xAF, 0x0F, 0xC2, 0x3C, 0x76, 0x63, 0x5D, 0xA7, 0x5C, 0x6B, 0xF6, 0xF3,
- 0xD7, 0x59, 0x08, 0x22, 0x64, 0xB7, 0x5D, 0x9C, 0xD3, 0xB0, 0x4A, 0xB7, 0x6A, 0xFD, 0xDA, 0x96,
- 0x0C, 0x6F, 0xD6, 0x73, 0x54, 0x65, 0x98, 0xEC, 0x70, 0xC0, 0x95, 0xCD, 0x2D, 0xCB, 0x84, 0xD9,
- 0x20, 0x3E, 0x3D, 0xBB, 0xF9, 0xB1, 0x66, 0xAF, 0x53, 0x5A, 0x26, 0x44, 0xB3, 0xA4, 0x05, 0xC5,
- 0xEB, 0x17, 0x88, 0x2B, 0xF0, 0xA1, 0xAE, 0xEA, 0x69, 0x4B, 0xD8, 0x2F, 0xE5, 0x36, 0x57, 0xF9,
- 0xF3, 0x00, 0x4B, 0x07, 0x48, 0x04, 0x09, 0x0D, 0x4A, 0x42, 0x1F, 0xED, 0xFA, 0xEA, 0xA7, 0x68,
- 0x1A, 0x03, 0x2C, 0xEB, 0xF6, 0xDB, 0x6A, 0x2D, 0xBF, 0x56, 0x63, 0x54, 0x7B, 0xDA, 0x09, 0x9B,
- 0xF7, 0x38, 0xF0, 0x57, 0x7F, 0x8D, 0xCB, 0x03, 0x15, 0x0A, 0x15, 0xA5, 0xC9, 0xD6, 0xC8, 0xC2,
- 0x9F, 0x1D, 0x56, 0x82, 0x44, 0x78, 0x57, 0x74, 0x9D, 0x0F, 0x1A, 0x43, 0x93, 0x52, 0x9D, 0x16,
- 0xEC, 0x5C, 0xDA, 0x09, 0xEC, 0xFC, 0x2A, 0x75, 0x4B, 0x32, 0xA9, 0xB2, 0x6E, 0x91, 0xB1, 0x22,
- 0xC2, 0xE2, 0x79, 0xCC, 0xDD, 0x68, 0xD0, 0x22, 0x05, 0x07, 0xCF, 0xB5, 0xC6, 0xED, 0xCD, 0x5D,
- 0x17, 0xD5, 0xD6, 0xC2, 0x49, 0x28, 0x8D, 0x79, 0xCF, 0xC3, 0x6D, 0xCE, 0x96, 0x3C, 0x8D, 0x6F,
- 0x16, 0x39, 0x8D, 0x4F, 0xE4, 0x23, 0x7C, 0x4F, 0x56, 0x5A, 0xC0, 0xDC, 0x41, 0x30, 0x2C, 0x24,
- 0x2E, 0x66, 0xF6, 0x00, 0x6E, 0x03, 0x81, 0x5B, 0x8D, 0xD2, 0x3F, 0x79, 0xFC, 0x43, 0x25, 0xB2,
- 0x87, 0x88, 0xCA, 0xD8, 0xA9, 0xB5, 0x61, 0x85, 0xAD, 0xE1, 0x64, 0xE8, 0x52, 0x0C, 0x7F, 0xF6,
- 0x9A, 0xB7, 0xA3, 0x6A, 0x43, 0xCB, 0xBE, 0x33, 0xFA, 0x19, 0xA4, 0xB7, 0xA8, 0xEB, 0x24, 0x94,
- 0x95, 0xA6, 0xA7, 0xBA, 0xE4, 0x5C, 0x36, 0x31, 0xE4, 0x38, 0xEF, 0x35, 0xAA, 0x66, 0x6B, 0x6D,
- 0x6C, 0x6A, 0x87, 0x2E, 0xCF, 0x35, 0x48, 0xD7, 0xC4, 0x7E, 0xA8, 0x93, 0xA0, 0xBB, 0x32, 0x95,
- 0x21, 0xE4, 0x39, 0x9F, 0xBD, 0xB8, 0x50, 0x52, 0xF8, 0x6F, 0x84, 0x3E, 0x61, 0xAD, 0xAC, 0x28,
- 0xA7, 0xE7, 0xEC, 0x7F, 0x05, 0x4E, 0x08, 0x1D, 0xC7, 0x04, 0x0E, 0x20, 0x00, 0x10, 0x80, 0x26,
- 0xB4, 0x13, 0xFD, 0x66, 0x40, 0x83, 0x70, 0x47, 0x54, 0xE6, 0x18, 0x5A, 0xCA, 0xB6, 0x2E, 0xCD,
- 0xD1, 0x99, 0xF2, 0x68, 0xC3, 0xF4, 0xED, 0x20, 0xFC, 0xD9, 0x1E, 0x4C, 0xAA, 0x1D, 0x5C, 0xCC,
- 0xE0, 0xE1, 0x4F, 0x9B, 0x3C, 0x08, 0xF2, 0x20, 0x7D, 0xBA, 0xD8, 0xE1, 0xA2, 0xB5, 0xA2, 0xF1,
- 0x9E, 0x10, 0xAF, 0x9E, 0x6B, 0xD6, 0x34, 0x53, 0x1B, 0xBB, 0x36, 0xF6, 0xB2, 0xE5, 0x51, 0x5E,
- 0x86, 0x2C, 0x79, 0x6B, 0x8E, 0xC0, 0x4D, 0x9A, 0xAF, 0x02, 0xD9, 0x7F, 0xDF, 0x12, 0xE4, 0xCE,
- 0x81, 0x6C, 0xA2, 0x87, 0x57, 0x2C, 0x10, 0x75, 0x08, 0x46, 0xF4, 0xA8, 0xA8, 0x08, 0xCC, 0x74,
- 0xA8, 0xCB, 0xCA, 0x74, 0x73, 0x1A, 0x3F, 0x1D, 0xFA, 0x58, 0x75, 0x82, 0x72, 0xE7, 0x0D, 0x29,
- 0x73, 0x4A, 0xE4, 0x94, 0x51, 0xEA, 0x53, 0xE0, 0xC4, 0x60, 0x29, 0xB5, 0x1D, 0x1A, 0xA0, 0xAB,
- 0xEE, 0x34, 0x42, 0x41, 0x96, 0xE6, 0x6B, 0x21, 0xA8, 0x85, 0x6F, 0x04, 0x08, 0x9D, 0x7B, 0xE5,
- 0xEB, 0x3B, 0x25, 0x5C, 0x8B, 0xBA, 0xF8, 0x02, 0x25, 0xA6, 0x3C, 0x54, 0x05, 0x2B, 0xBB, 0x35,
- 0x2A, 0x97, 0xD5, 0x8B, 0x98, 0x56, 0x0C, 0x4D, 0x49, 0x92, 0xAC, 0x53, 0x06, 0x38, 0x63, 0xC6,
- 0xE7, 0xC1, 0x62, 0x11, 0xB1, 0x43, 0xF3, 0xB4, 0xA9, 0x66, 0x3E, 0x5D, 0x0D, 0x6D, 0x1B, 0x02,
- 0xD7, 0x6E, 0x4C, 0x67, 0x5B, 0x3A, 0x86, 0x2D, 0xAA, 0x2D, 0x89, 0x33, 0xD5, 0xF4, 0x1A, 0xF4,
- 0x5A, 0x09, 0xC1, 0x82, 0x79, 0xD1, 0x50, 0x81, 0x7E, 0xBC, 0x8A, 0x14, 0x97, 0x68, 0x77, 0x15,
- 0xEA, 0x4B, 0xD2, 0x56, 0x6C, 0x7D, 0xEB, 0x05, 0x0A, 0x6F, 0xB1, 0x71, 0xC3, 0xFC, 0xD5, 0xDC,
- 0x45, 0x72, 0xB3, 0x4D, 0xA2, 0x8D, 0xD1, 0x65, 0x3B, 0x87, 0x95, 0xC9, 0x79, 0x95, 0xFC, 0x33,
- 0xB3, 0xB3, 0xAC, 0xDC, 0x09, 0xD9, 0x6E, 0xFE, 0xDD, 0x1E, 0xDB, 0xED, 0x9A, 0x62, 0xE5, 0x54,
- 0xFE, 0x41, 0x2D, 0xCB, 0x01, 0xF8, 0xF5, 0xD7, 0x6E, 0x22, 0xA5, 0x14, 0x42, 0xB4, 0xBD, 0x5B,
- 0x2B, 0x06, 0xB1, 0xCD, 0x0B, 0xA0, 0x9B, 0x12, 0x38, 0x30, 0xDE, 0x7C, 0xBF, 0x26, 0xED, 0x2D,
- 0x5A, 0x09, 0x61, 0x7F, 0xB0, 0xB1, 0xD4, 0x52, 0xA1, 0x5E, 0x9D, 0x84, 0xC8, 0xDC, 0xD7, 0x1D,
- 0x2B, 0x77, 0x5C, 0xF4, 0x55, 0x64, 0x78, 0x46, 0x76, 0xE9, 0xAF, 0x5E, 0x02, 0xE5, 0xBF, 0x23,
- 0xE4, 0x9A, 0x15, 0x99, 0x7C, 0x45, 0x25, 0xDB, 0x00, 0xFA, 0xD0, 0x9D, 0x1B, 0xA9, 0x92, 0x37,
- 0x3D, 0xD6, 0x81, 0x02, 0x74, 0xA0, 0x1C, 0x97, 0x7F, 0x48, 0xBA, 0x55, 0x14, 0x3D, 0x53, 0x44,
- 0xD2, 0x15, 0xD8, 0x91, 0x87, 0x40, 0x4D, 0x78, 0x79, 0x12, 0x44, 0x0F, 0xCD, 0x9A, 0x85, 0x40,
- 0x33, 0x47, 0x2B, 0x66, 0x3E, 0x3C, 0xDD, 0x9A, 0x22, 0xDC, 0xDC, 0xB3, 0x29, 0x4B, 0xCA, 0xBE,
- 0x2B, 0x58, 0xE1, 0xB6, 0x14, 0x7F, 0x75, 0x40, 0x42, 0x61, 0x39, 0x24, 0x97, 0xF8, 0x46, 0xAE,
- 0xB0, 0x20, 0xE5, 0xEF, 0x48, 0x9C, 0x78, 0x6D, 0x9F, 0xA3, 0x1A, 0xDD, 0xFC, 0x22, 0x97, 0x13,
- 0x0B, 0x25, 0x7B, 0xB8, 0xEE, 0x47, 0xFE, 0x20, 0x28, 0xB6, 0xFE, 0x4B, 0x31, 0x99, 0x65, 0x20,
- 0xAA, 0x3C, 0xDE, 0xF4, 0x08, 0xB7, 0xB4, 0xCE, 0x30, 0x61, 0x37, 0x04, 0x76, 0x0D, 0x34, 0x8E,
- 0x7A, 0x3D, 0xF2, 0x21, 0xDC, 0xD5, 0xEC, 0x63, 0xF3, 0xB0, 0x21, 0xF5, 0x28, 0x32, 0x66, 0xA7,
- 0x7F, 0x28, 0x9C, 0x59, 0xFE, 0x59, 0xDC, 0x8A, 0xAC, 0x11, 0xE5, 0x62, 0xA6, 0xCA, 0xAF, 0xD9,
- 0x92, 0xE7, 0x85, 0xD6, 0x40, 0x81, 0x06, 0xA8, 0xD1, 0x18, 0xCC, 0x7D, 0x37, 0xD5, 0x33, 0x08,
- 0xAA, 0x14, 0x9C, 0xA3, 0x41, 0x66, 0xEC, 0x5C, 0x3D, 0x3C, 0x02, 0x44, 0x5A, 0x7E, 0x1A, 0x70,
- 0x0B, 0xC1, 0x14, 0x7E, 0x6D, 0xEF, 0xF2, 0xC4, 0x6E, 0x8F, 0x99, 0xF8, 0xF0, 0xF8, 0xA1, 0x88,
- 0xAD, 0xE7, 0xC3, 0x8B, 0x94, 0x95, 0xC6, 0x8D, 0xC1, 0x7B, 0x77, 0x75, 0x06, 0x2B, 0x4E, 0xBC,
- 0x94, 0x9D, 0xBB, 0x62, 0xE4, 0x71, 0x5D, 0x2C, 0x59, 0x27, 0x10, 0x2F, 0x86, 0x8B, 0x0F, 0xF6,
- 0x8A, 0x6F, 0x77, 0xEE, 0x4F, 0x0F, 0xD1, 0x9F, 0x07, 0x0B, 0x17, 0xD5, 0x70, 0x5D, 0x56, 0x6D,
- 0x66, 0x18, 0xE6, 0x02, 0x80, 0x02, 0x24, 0xE5, 0x3C, 0x7E, 0xF7, 0x9E, 0x1D, 0x6C, 0xF8, 0x0C,
- 0xCC, 0xDE, 0x97, 0x89, 0x7C, 0x03, 0x07, 0x32, 0xA0, 0xB2, 0x44, 0x44, 0x7E, 0xCB, 0x63, 0x69,
- 0xB3, 0x11, 0xE2, 0x48, 0x03, 0x5D, 0x08, 0x26, 0x00, 0x56, 0x8D, 0x96, 0x5B, 0x8D, 0x8E, 0x5C,
- 0xEE, 0xDC, 0x27, 0x3B, 0x4C, 0x4B, 0xC1, 0xCE, 0xCA, 0x94, 0x8D, 0x3A, 0x4E, 0x6E, 0x0B, 0x7B,
- 0x81, 0x23, 0xBF, 0x24, 0x93, 0xF5, 0xFD, 0xB6, 0x3A, 0x34, 0xD1, 0xFD, 0xC1, 0x37, 0xDF, 0xEF,
- 0x8D, 0x0B, 0xF6, 0x1C, 0xCA, 0x35, 0xCB, 0xA1, 0x63, 0x5F, 0x07, 0x55, 0x18, 0x06, 0x40, 0xB7,
- 0x2E, 0xA4, 0x15, 0x11, 0xB6, 0xDD, 0xEB, 0xA4, 0x78, 0xD0, 0x50, 0x52, 0x24, 0x08, 0xC2, 0x7E,
- 0x14, 0x37, 0x73, 0x33, 0x1F, 0x23, 0x92, 0x78, 0x64, 0xC8, 0xE6, 0x88, 0xA6, 0xFA, 0x98, 0xF0,
- 0x76, 0xCB, 0x20, 0xF7, 0xA1, 0x67, 0xC6, 0x9B, 0x38, 0x50, 0x81, 0x14, 0x24, 0x8E, 0xE9, 0x0F,
- 0xC2, 0xA5, 0xBB, 0x5D, 0x07, 0x97, 0x20, 0xCF, 0x05, 0xE6, 0xED, 0xDA, 0x9B, 0xAB, 0xA4, 0x48,
- 0xD5, 0x88, 0xCE, 0x80, 0x4B, 0x66, 0xCE, 0xAB, 0x9C, 0xDE, 0xB9, 0x78, 0x0B, 0x4E, 0x56, 0x56,
- 0xD6, 0xDB, 0x85, 0xEA, 0x73, 0x97, 0x64, 0x74, 0xFF, 0xF5, 0xC6, 0xD1, 0x88, 0xB4, 0x67, 0xF3,
- 0xA6, 0xDD, 0x13, 0x9B, 0xCE, 0xD2, 0x2B, 0xAC, 0xB4, 0x28, 0x31, 0x6C, 0x85, 0x1D, 0x91, 0xC0,
- 0xCF, 0xB5, 0x91, 0x5B, 0xBC, 0x82, 0x1F, 0x68, 0x82, 0x85, 0xAD, 0x2B, 0x7D, 0x06, 0xFA, 0x9E,
- 0x31, 0x1E, 0x16, 0xC8, 0x9F, 0xC3, 0xA7, 0xDC, 0x17, 0xB2, 0xFD, 0xF4, 0x46, 0xF6, 0x61, 0xC2,
- 0x04, 0x27, 0xF2, 0xF7, 0xCF, 0x3A, 0xE3, 0xAE, 0x2A, 0x62, 0x0E, 0x3B, 0x81, 0xC9, 0x49, 0x5B,
- 0x7C, 0xBC, 0xE8, 0x3A, 0x96, 0x82, 0x32, 0x67, 0xF2, 0xAC, 0xAE, 0x7F, 0xC9, 0x79, 0x35, 0x4E,
- 0xB7, 0x95, 0x53, 0xAC, 0x43, 0xBC, 0x2E, 0x0E, 0xFC, 0x9F, 0x2E, 0x16, 0xD0, 0x96, 0x46, 0x60,
- 0xBC, 0xD2, 0x21, 0x4D, 0x46, 0xAD, 0xA8, 0x1C, 0x85, 0x93, 0x28, 0xDF, 0x04, 0xC5, 0xAB, 0x37,
- 0x60, 0x7C, 0x0E, 0xD6, 0x4E, 0xB2, 0x4F, 0x04, 0x71, 0xC9, 0x68, 0xCB, 0xE1, 0x90, 0xE1, 0x65,
- 0x9A, 0x7E, 0x00, 0xF6, 0xE7, 0xA2, 0x19, 0xF9, 0x77, 0xE1, 0xFF, 0xBE, 0xE0, 0x92, 0xB8, 0xE9,
- 0x1C, 0x96, 0xB7, 0x82, 0x04, 0x88, 0x5E, 0x00, 0xD3, 0x66, 0x68, 0x66, 0xA5, 0x5F, 0xA9, 0xB9,
- 0x15, 0xFC, 0x33, 0xAE, 0x10, 0x8B, 0x12, 0x95, 0xE1, 0xD3, 0xAD, 0xBE, 0xA2, 0x44, 0x2C, 0x7A,
- 0xD2, 0xCC, 0x8D, 0x07, 0x64, 0x02, 0xC3, 0x62, 0xEF, 0xC4, 0xD0, 0x8B, 0xEC, 0xE2, 0xB3, 0x34,
- 0x88, 0xB7, 0xFE, 0x97, 0xD2, 0x92, 0xAF, 0x53, 0xDA, 0x9E, 0xD8, 0xBF, 0x83, 0x06, 0x91, 0x72,
- 0x59, 0x4A, 0xDA, 0x3B, 0xED, 0x36, 0x4D, 0xFB, 0xD9, 0x2F, 0x68, 0x1A, 0xD6, 0xC2, 0x4E, 0x06,
- 0x54, 0xA2, 0x5F, 0xC4, 0x9E, 0x6E, 0x3C, 0xFE, 0x6C, 0x92, 0xD8, 0x86, 0x66, 0xC1, 0xDF, 0x75,
- 0x6F, 0xD1, 0x5F, 0x9F, 0xA0, 0x16, 0xB0, 0x18, 0x1F, 0xB1, 0xD8, 0x5C, 0x78, 0x91, 0x2C, 0x05,
- 0xD9, 0x93, 0xA3, 0xF0, 0x6A, 0xA4, 0x7E, 0x36, 0x2A, 0xA3, 0x8D, 0xAE, 0x89, 0xD8, 0xD5, 0x3A,
- 0xBF, 0xA2, 0x47, 0xAF, 0xD6, 0xF7, 0x52, 0x79, 0xF7, 0x72, 0xAA, 0xE4, 0x43, 0x0B, 0x4D, 0x31,
- 0x74, 0xA3, 0x84, 0x08, 0xF7, 0x63, 0xCA, 0xB5, 0xE2, 0xDF, 0x23, 0xBA, 0x71, 0x5F, 0x01, 0xE2,
- 0x11, 0x61, 0x7B, 0x22, 0x04, 0x0A, 0x6E, 0x23, 0x1D, 0xAE, 0xDB, 0xBF, 0x40, 0x31, 0x47, 0x5D,
- 0xA6, 0x4C, 0xF7, 0x98, 0xAD, 0xA6, 0x89, 0xCE, 0x33, 0xD6, 0x06, 0x81, 0x59, 0x59, 0x85, 0x20,
- 0xE3, 0xA7, 0x48, 0xFC, 0xD5, 0x8B, 0x79, 0xA5, 0x17, 0x92, 0x00, 0xDC, 0x07, 0xEE, 0xE8, 0x93,
- 0xDF, 0x4B, 0xF7, 0x0D, 0x41, 0x9C, 0x23, 0xD2, 0xE3, 0xAE, 0x27, 0xD8, 0x91, 0x6A, 0x5B, 0xF3,
- 0xE5, 0xC3, 0xF5, 0xCB, 0xEE, 0xA5, 0xF7, 0xE3, 0xC6, 0xF6, 0xB0, 0xE1, 0x59, 0x5E, 0xB1, 0x0F,
- 0x3F, 0xD4, 0xD4, 0xEE, 0xB4, 0x98, 0xA3, 0x46, 0x06, 0x93, 0x70, 0x48, 0x62, 0x44, 0xCE, 0xB8,
- 0x87, 0x05, 0xF9, 0xD3, 0x2C, 0x26, 0x9A, 0xA1, 0xDF, 0xA8, 0x4B, 0x96, 0x96, 0x91, 0x64, 0xD3,
- 0x35, 0x2A, 0xDF, 0xC2, 0x83, 0x4C, 0xEA, 0x07, 0x2F, 0xB5, 0x14, 0x7F, 0xD4, 0x5A, 0x27, 0x6E,
- 0x75, 0xF7, 0x88, 0x45, 0xB5, 0x1B, 0x55, 0x9E, 0x43, 0xAC, 0xEC, 0xEE, 0xD6, 0xC1, 0x8A, 0x13,
- 0x5D, 0xB4, 0xE7, 0x23, 0x60, 0x9B, 0x3A, 0xDF, 0x59, 0xD4, 0xDD, 0x89, 0x93, 0xF6, 0xEB, 0x61,
- 0xA5, 0x6B, 0x22, 0x25, 0xCC, 0x5E, 0x31, 0x90, 0xE0, 0x54, 0xEA, 0xA2, 0x8F, 0x6C, 0x79, 0x74,
- 0xCC, 0x2F, 0xDD, 0x99, 0xF2, 0x70, 0xA2, 0x73, 0x7F, 0xF9, 0xFA, 0x86, 0xD7, 0x6F, 0xEA, 0x26,
- 0x6D, 0x40, 0xDE, 0xDB, 0xCC, 0xF9, 0x34, 0xCB, 0x14, 0x8B, 0x94, 0xAA, 0xB7, 0xEC, 0x3B, 0xF4,
- 0x4B, 0x14, 0xAA, 0xD6, 0x0F, 0x9C, 0x9B, 0x95, 0x89, 0x71, 0x41, 0xE1, 0x40, 0x02, 0x86, 0x8E,
- 0x9E, 0xBE, 0xFE, 0x5F, 0x3C, 0xDB, 0x15, 0xA8, 0xD2, 0x26, 0xAF, 0xDC, 0x3A, 0xF6, 0x4F, 0xFD,
- 0x78, 0x53, 0x24, 0xCA, 0x16, 0x8F, 0x7D, 0x59, 0x11, 0xA0, 0xA3, 0xA5, 0xA9, 0xB1, 0xE0, 0x23,
- 0xC4, 0xEB, 0x35, 0xC9, 0xF1, 0x41, 0x00, 0x63, 0x25, 0xA9, 0xD0, 0x22, 0xA7, 0xCC, 0x1A, 0x97,
- 0x8D, 0x98, 0xB2, 0xC7, 0x0C, 0x9A, 0x97, 0xAC, 0xBB, 0xF4, 0x6A, 0x37, 0xEC, 0x3B, 0xD5, 0x28,
- 0xB3, 0xE4, 0x2B, 0xB5, 0xE8, 0x52, 0x26, 0xAF, 0xDC, 0x1B, 0xB4, 0xEA, 0x56, 0x0F, 0x9C, 0xBA,
- 0xF6, 0x4F, 0xFD, 0x78, 0x53, 0x24, 0xAB, 0xD4, 0x2A, 0xB7, 0xCD, 0xF9, 0x51, 0x20, 0xC2, 0x06,
- 0x6F, 0x5C, 0x1B, 0xB4, 0xCB, 0xF5, 0x49, 0xF1, 0x41, 0x00, 0x82, 0x67, 0x2D, 0xB9, 0xF0, 0x62,
- 0x46, 0x0E, 0x9E, 0xBE, 0xDF, 0x3C, 0xFA, 0x76, 0x4F, 0xFD, 0x59, 0x30, 0xC3, 0x04, 0x6B, 0x35,
- 0xC9, 0x10, 0xA2, 0xC6, 0x0E, 0x7F, 0x5D, 0x19, 0xB0, 0xE2, 0x27, 0xCC, 0xFB, 0x55, 0x09, 0x90,
- 0x83, 0x84, 0x6B, 0x35, 0xC9, 0x10, 0xA2, 0xA7, 0xAD, 0xB9, 0xF0, 0x43, 0x04, 0x8A, 0x77, 0x4D,
- 0xF9, 0x51, 0x01, 0x80, 0x82, 0x86, 0x8E, 0x7F, 0x7C, 0x7A, 0x76, 0x4F, 0x1C, 0xBA, 0xD7, 0x2C,
- 0xDA, 0x36, 0xEE, 0x5E, 0x1F, 0x9D, 0x99, 0xB0, 0xC3, 0x04, 0x6B, 0x35, 0xC9, 0x10, 0x83, 0x84,
- 0x6B, 0x35, 0xC9, 0xF1, 0x60, 0x23, 0xC4, 0xEB, 0x54, 0x0B, 0x94, 0xAA, 0xB7, 0xEC, 0x3B, 0xF4,
- 0x4B, 0x14, 0x8B, 0x94, 0x8B, 0x75, 0x68, 0x52, 0x26, 0xCE, 0x1E, 0xBE, 0xDF, 0x1D, 0x99, 0x91,
- 0x81, 0x61, 0x21, 0xC0, 0x02, 0x86, 0x6F, 0x5C, 0x3A, 0xF6, 0x6E, 0x3F, 0xFC, 0x5B, 0x15, 0x89,
- 0x71, 0x41, 0xE1, 0x21, 0xC0, 0x02, 0x67, 0x2D, 0xD8, 0x32, 0xC7, 0xED, 0x39, 0xD1, 0x01, 0x80,
- 0x63, 0x25, 0xC8, 0xF3, 0x64, 0x2B, 0xD4, 0x2A, 0xD6, 0x2E, 0xBF, 0xFC, 0x5B, 0x34, 0xCB, 0x14,
- 0x8B, 0x75, 0x68, 0x33, 0xE4, 0x4A, 0x16, 0x8F, 0x7D, 0x78, 0x72, 0x66, 0x2F, 0xBD, 0xF8, 0x53,
- 0x24, 0xCA, 0x16, 0xAE, 0xBF, 0xFC, 0x7A, 0x57, 0x0D, 0x79, 0x70, 0x43, 0xE5, 0x48, 0xF3, 0x45,
- 0xE9, 0x31, 0xE0, 0x42, 0xE7, 0x4C, 0xFB, 0x55, 0x09, 0x71, 0x41, 0x00, 0x63, 0x25, 0xC8, 0x12,
- 0x87, 0x6D, 0x39, 0xF0, 0x43, 0x04, 0x6B, 0x35, 0xC9, 0x10, 0x83, 0x84, 0x8A, 0x96, 0x8F, 0x7D,
- 0x78, 0x53, 0x24, 0xCA, 0x16, 0x8F, 0x9C, 0xBA, 0xF6, 0x6E, 0x3F, 0xDD, 0x19, 0xB0, 0xE2, 0x46,
- 0x0E, 0x7F, 0x5D, 0x38, 0xD3, 0x05, 0x88, 0x73, 0x64, 0x2B, 0xB5, 0xE8, 0x33, 0xE4, 0x4A, 0x16,
- 0xAE, 0xBF, 0xFC, 0x7A, 0x57, 0x0D, 0x98, 0x93, 0x85, 0x69, 0x50, 0x03, 0x65, 0x29, 0xD0, 0x22,
- 0xC6, 0x0E, 0x9E, 0x9F, 0x9D, 0xB8, 0xD3, 0x24, 0xAB, 0xD4, 0x0B, 0x75, 0x49, 0x10, 0x83, 0x65,
- 0x48, 0xF3, 0x64, 0x2B, 0xB5, 0xE8, 0x52, 0x07, 0x6D, 0x39, 0xD1, 0x01, 0x80, 0x82, 0x67, 0x2D,
- 0xB9, 0xD1, 0x20, 0xA3, 0xA5, 0xA9, 0xD0, 0x03, 0x84, 0x6B, 0x35, 0xE8, 0x33, 0xC5, 0xE9, 0x50,
- 0x22, 0xC6, 0xEF, 0x5C, 0x3A, 0xF6, 0x6E, 0x5E, 0x1F, 0x9D, 0xB8, 0xF2, 0x47, 0xED, 0x39, 0xF0,
- 0x43, 0x04, 0x8A, 0x96, 0x8F, 0x7D, 0x59, 0x11, 0x81, 0x61, 0x21, 0xA1, 0xC0, 0x02, 0x67, 0x2D,
- 0xB9, 0xF0, 0x43, 0x04, 0x8A, 0x77, 0x4D, 0xF9, 0x70, 0x43, 0x04, 0x8A, 0x96, 0xAE, 0xDE, 0x1F,
- 0x9D, 0xB8, 0xD3, 0x05, 0x88, 0x92, 0x87, 0x8C, 0x9A, 0xB6, 0xCF, 0xFD, 0x59, 0x30, 0xC3, 0x04,
- 0x8A, 0x96, 0x8F, 0x7D, 0x78, 0x72, 0x66, 0x4E, 0xFF, 0x7C, 0x5B, 0x15, 0x89, 0x71, 0x41, 0xE1,
- 0x21, 0xA1, 0xA1, 0xA1, 0xA1, 0xC0, 0xE3, 0x44, 0x0A, 0x96, 0x8F, 0x7D, 0x59, 0x30, 0xE2, 0x27,
- 0xCC, 0x1A, 0xB6, 0xEE, 0x5E, 0x1F, 0x9D, 0x99, 0x91, 0xA0, 0xA3, 0xC4, 0xEB, 0x35, 0xE8, 0x33,
- 0xC5, 0x08, 0x73, 0x64, 0x2B, 0xD4, 0x2A, 0xD6, 0x2E, 0xBF, 0xDD, 0x38, 0xF2, 0x47, 0x0C, 0x7B,
- 0x55, 0x28, 0xB3, 0xC5, 0x08, 0x92, 0xA6, 0xAF, 0xBD, 0xF8, 0x72, 0x47, 0x0C, 0x7B, 0x74, 0x4B,
- 0xF5, 0x68, 0x33, 0xC5, 0x08, 0x73, 0x64, 0x4A, 0xF7, 0x4D, 0xF9, 0x70, 0x43, 0x04, 0x6B, 0x35,
- 0xC9, 0xF1, 0x41, 0xE1, 0x21, 0xC0, 0xE3, 0x25, 0xC8, 0x12, 0x87, 0x6D, 0x39, 0xD1, 0x20, 0xA3,
- 0xA5, 0xA9, 0xB1, 0xE0, 0x23, 0xC4, 0xEB, 0x54, 0x0B, 0x75, 0x49, 0x10, 0x83, 0x65, 0x48, 0xF3,
- 0x45, 0xE9, 0x31, 0xE0, 0x42, 0xE7, 0x2D, 0xB9, 0xD1, 0x01, 0x61, 0x21, 0xA1, 0xC0, 0x02, 0x67,
- 0x4C, 0x1A, 0x97, 0x8D, 0x98, 0xB2, 0xC7, 0xED, 0x58, 0x32, 0xE6, 0x2F, 0xDC, 0x3A, 0xD7, 0x2C,
- 0xDA, 0x17, 0x8D, 0x79, 0x51, 0x01, 0x80, 0x63, 0x44, 0x0A, 0x77, 0x6C, 0x3B, 0xD5, 0x28, 0xD2,
- 0x26, 0xCE, 0xFF, 0x7C, 0x5B, 0x34, 0xEA, 0x37, 0xEC, 0x3B, 0xF4, 0x4B, 0x14, 0x8B, 0x94, 0xAA,
- 0xD6, 0x2E, 0xDE, 0x3E, 0xFE, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x5F, 0x3C, 0xDB, 0x15, 0xA8, 0xD2,
- 0x26, 0xCE, 0xFF, 0x7C, 0x7A, 0x57, 0x0D, 0x98, 0xB2, 0xC7, 0x0C, 0x7B, 0x74, 0x4B, 0x14, 0x8B,
- 0x94, 0x8B, 0x75, 0x49, 0x10, 0x83, 0x84, 0x8A, 0x77, 0x6C, 0x5A, 0x17, 0xAC, 0xDA, 0x36, 0xCF,
- 0x1C, 0xBA, 0xF6, 0x6E, 0x3F, 0xFC, 0x5B, 0x34, 0xEA, 0x37, 0xEC, 0x3B, 0xF4, 0x4B, 0xF5, 0x49,
- 0xF1, 0x41, 0xE1, 0x21, 0xA1, 0xC0, 0x02, 0x86, 0x8E, 0x9E, 0xBE, 0xFE, 0x7E, 0x7E, 0x7E, 0x5F,
- 0x3C, 0xFA, 0x76, 0x6E, 0x3F, 0xFC, 0x7A, 0x76, 0x4F, 0xFD, 0x59, 0x30, 0xE2, 0x27, 0xAD, 0xD8,
- 0x13, 0xA4, 0xCA, 0x16, 0xAE, 0xDE, 0x3E, 0xFE, 0x5F, 0x1D, 0xB8, 0xF2, 0x47, 0x0C, 0x7B, 0x74,
- 0x6A, 0x56, 0x0F, 0x7D, 0x78, 0x72, 0x47, 0x0C, 0x9A, 0xB6, 0xCF, 0xFD, 0x78, 0x72, 0x66, 0x2F,
- 0xBD, 0xF8, 0x53, 0x24, 0xAB, 0xD4, 0x2A, 0xB7, 0xEC, 0x3B, 0xF4, 0x6A, 0x56, 0x2E, 0xBF, 0xFC,
- 0x7A, 0x57, 0x0D, 0x79, 0x70, 0x62, 0x46, 0x0E, 0x7F, 0x5D, 0x19, 0x91, 0xA0, 0xC2, 0x06, 0x8E,
- 0x7F, 0x5D, 0x19, 0xB0, 0xE2, 0x46, 0xEF, 0x5C, 0x3A, 0xD7, 0x2C, 0xBB, 0xF4, 0x6A, 0x37, 0xCD,
- 0x18, 0xB2, 0xC7, 0x0C, 0x9A, 0x97, 0x8D, 0x98, 0xB2, 0xC7, 0xED, 0x58, 0x13, 0x85, 0x69, 0x50,
- 0x22, 0xA7, 0xCC, 0xFB, 0x55, 0x09, 0x90, 0xA2, 0xC6, 0x0E, 0x9E, 0x9F, 0xBC, 0xFA, 0x57, 0x2C,
- 0xDA, 0x36, 0xCF, 0xFD, 0x78, 0x72, 0x47, 0xED, 0x39, 0xD1, 0x20, 0xC2, 0xE7, 0x4C, 0xFB, 0x74,
- 0x6A, 0x56, 0x2E, 0xBF, 0xFC, 0x7A, 0x57, 0x0D, 0x98, 0xB2, 0xE6, 0x4E, 0x1E, 0x9F, 0x9D, 0xB8,
- 0xD3, 0x24, 0xCA, 0xF7, 0x6C, 0x5A, 0x17, 0xAC, 0xBB, 0xF4, 0x4B, 0x14, 0x8B, 0x94, 0xAA, 0xB7,
- 0xCD, 0xF9, 0x70, 0x62, 0x46, 0x0E, 0x9E, 0x9F, 0x9D, 0xB8, 0xF2, 0x47, 0xED, 0x39, 0xD1, 0x01,
- 0x61, 0x40, 0xE3, 0x44, 0x0A, 0x96, 0x8F, 0x9C, 0xBA, 0xD7, 0x0D, 0x98, 0x93, 0x85, 0x69, 0x50,
- 0x22, 0xA7, 0xCC, 0x1A, 0xB6, 0xEE, 0x5E, 0x3E, 0xFE, 0x7E, 0x7E, 0x7E, 0x5F, 0x3C, 0xFA, 0x57,
- 0x0D, 0x79, 0x70, 0x62, 0x27, 0xCC, 0x1A, 0xB6, 0xCF, 0xFD, 0x78, 0x72, 0x66, 0x2F, 0xDC, 0x1B,
- 0x95, 0xA8, 0xB3, 0xE4, 0x4A, 0xF7, 0x6C, 0x5A, 0x36, 0xEE, 0x3F, 0xFC, 0x7A, 0x57, 0x2C, 0xBB,
- 0xD5, 0x09, 0x71, 0x41, 0xE1, 0x21, 0xC0, 0xE3, 0x44, 0x0A, 0x77, 0x6C, 0x3B, 0xD5, 0x09, 0x90,
- 0x83, 0x84, 0x6B, 0x54, 0x0B, 0x94, 0x8B, 0x75, 0x49, 0xF1, 0x60, 0x42, 0xE7, 0x4C, 0x1A, 0xB6,
- 0xEE, 0x3F, 0xFC, 0x5B, 0x15, 0xA8, 0xB3, 0xC5, 0xE9, 0x50, 0x22, 0xC6, 0x0E, 0x7F, 0x5D, 0x19,
- 0xB0, 0xE2, 0x27, 0xAD, 0xB9, 0xD1, 0x01, 0x80, 0x63, 0x25, 0xC8, 0xF3, 0x64, 0x4A, 0x16, 0xAE,
- 0xDE, 0x3E, 0xDF, 0x3C, 0xFA, 0x57, 0x0D, 0x79, 0x70, 0x43, 0x04, 0x6B, 0x54, 0x2A, 0xB7, 0xCD,
- 0x18, 0x93, 0xA4, 0xAB, 0xD4, 0x2A, 0xD6, 0x0F, 0x7D, 0x78, 0x72, 0x47, 0x0C, 0x7B, 0x74, 0x6A,
- 0x37, 0xEC, 0x5A, 0x17, 0xAC, 0xBB, 0xF4, 0x6A, 0x56, 0x0F, 0x7D, 0x78, 0x53, 0x05, 0x88, 0x73,
- 0x64, 0x2B, 0xB5, 0xE8, 0x33, 0xC5, 0x08, 0x92, 0xA6, 0xAF, 0xDC, 0x1B, 0xB4, 0xEA, 0x56, 0x0F,
- 0x9C, 0x9B, 0xB4, 0xCB, 0xF5, 0x68, 0x33, 0xE4, 0x2B, 0xB5, 0xE8, 0x33, 0xE4, 0x2B, 0xB5, 0xE8,
- 0x52, 0x26, 0xAF, 0xDC, 0x3A, 0xF6, 0x6E, 0x5E, 0x1F, 0xBC, 0xFA, 0x76, 0x6E, 0x3F, 0xDD, 0x38,
- 0xF2, 0x47, 0x0C, 0x7B, 0x74, 0x4B, 0x14, 0x8B, 0x94, 0xAA, 0xD6, 0x0F, 0x9C, 0x9B, 0xB4, 0xEA,
- 0x56, 0x2E, 0xDE, 0x1F, 0x9D, 0x99, 0xB0, 0xE2, 0x27, 0xCC, 0x1A, 0xB6, 0xEE, 0x3F, 0xFC, 0x7A,
- 0x57, 0x0D, 0x98, 0x93, 0xA4, 0xAB, 0xB5, 0xC9, 0xF1, 0x60, 0x7B, 0x17, 0xC8, 0x4A
-};
-
-const pmw3360_srom_t pmw3360_srom_0x81 = {
- .data = srom_data_0x81,
- .len = sizeof(srom_data_0x81),
-};
From 32d6a621d8dd354825020b81475a17afc175573d Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Thu, 13 Jun 2024 03:42:00 -0700
Subject: [PATCH 24/32] Define `PMW33XX_CS_PIN`
---
keyboards/yowkees/keyball39/config.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/keyboards/yowkees/keyball39/config.h b/keyboards/yowkees/keyball39/config.h
index 1a1560e44af..0c96642e6ae 100644
--- a/keyboards/yowkees/keyball39/config.h
+++ b/keyboards/yowkees/keyball39/config.h
@@ -32,6 +32,9 @@ along with this program. If not, see .
// it has been reported to work well in such cases.
//#define SPLIT_WATCHDOG_ENABLE
+// PMW3360 configuration
+#define PMW33XX_CS_PIN B6
+
#define SPLIT_TRANSACTION_IDS_KB KEYBALL_GET_INFO, KEYBALL_GET_MOTION, KEYBALL_SET_CPI
// RGB LED settings
From 7db0d87ea8ac8242a96b0fba92ba528badc168b4 Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Thu, 13 Jun 2024 03:43:29 -0700
Subject: [PATCH 25/32] Remove custom PMW3360 driver reference from keyball lib
---
keyboards/yowkees/lib/keyball/keyball.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/keyboards/yowkees/lib/keyball/keyball.c b/keyboards/yowkees/lib/keyball/keyball.c
index 8faaad1ef45..04b04f7bcae 100644
--- a/keyboards/yowkees/lib/keyball/keyball.c
+++ b/keyboards/yowkees/lib/keyball/keyball.c
@@ -21,7 +21,6 @@ along with this program. If not, see .
#endif
#include "keyball.h"
-#include "drivers/pmw3360/pmw3360.h"
#include
From 75b745a4cdb029af42be9ffbadc33e9670279c27 Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Thu, 13 Jun 2024 03:45:24 -0700
Subject: [PATCH 26/32] Remove custom `pointing_device_*` functions from
keyball lib
---
keyboards/yowkees/lib/keyball/keyball.c | 48 -------------------------
1 file changed, 48 deletions(-)
diff --git a/keyboards/yowkees/lib/keyball/keyball.c b/keyboards/yowkees/lib/keyball/keyball.c
index 04b04f7bcae..48eaa509b7f 100644
--- a/keyboards/yowkees/lib/keyball/keyball.c
+++ b/keyboards/yowkees/lib/keyball/keyball.c
@@ -139,32 +139,6 @@ void keyboard_pre_init_kb(void) {
}
#endif
-void pointing_device_driver_init(void) {
-#if KEYBALL_MODEL != 46
- keyball.this_have_ball = pmw3360_init();
-#endif
- if (keyball.this_have_ball) {
-#if defined(KEYBALL_PMW3360_UPLOAD_SROM_ID)
-# if KEYBALL_PMW3360_UPLOAD_SROM_ID == 0x04
- pmw3360_srom_upload(pmw3360_srom_0x04);
-# elif KEYBALL_PMW3360_UPLOAD_SROM_ID == 0x81
- pmw3360_srom_upload(pmw3360_srom_0x81);
-# else
-# error Invalid value for KEYBALL_PMW3360_UPLOAD_SROM_ID. Please choose 0x04 or 0x81 or disable it.
-# endif
-#endif
- pmw3360_cpi_set(CPI_DEFAULT - 1);
- }
-}
-
-uint16_t pointing_device_driver_get_cpi(void) {
- return keyball_get_cpi();
-}
-
-void pointing_device_driver_set_cpi(uint16_t cpi) {
- keyball_set_cpi(cpi);
-}
-
__attribute__((weak)) void keyball_on_apply_motion_to_mouse_move(keyball_motion_t *m, report_mouse_t *r, bool is_left) {
#if KEYBALL_MODEL == 61 || KEYBALL_MODEL == 39 || KEYBALL_MODEL == 147 || KEYBALL_MODEL == 44
r->x = clip2int8(m->y);
@@ -263,28 +237,6 @@ static inline bool should_report(void) {
return true;
}
-report_mouse_t pointing_device_driver_get_report(report_mouse_t rep) {
- // fetch from optical sensor.
- if (keyball.this_have_ball) {
- pmw3360_motion_t d = {0};
- if (pmw3360_motion_burst(&d)) {
- ATOMIC_BLOCK_FORCEON {
- keyball.this_motion.x = add16(keyball.this_motion.x, d.x);
- keyball.this_motion.y = add16(keyball.this_motion.y, d.y);
- }
- }
- }
- // report mouse event, if keyboard is primary.
- if (is_keyboard_master() && should_report()) {
- // modify mouse report by PMW3360 motion.
- motion_to_mouse(&keyball.this_motion, &rep, is_keyboard_left(), keyball.scroll_mode);
- motion_to_mouse(&keyball.that_motion, &rep, !is_keyboard_left(), keyball.scroll_mode ^ keyball.this_have_ball);
- // store mouse report for OLED.
- keyball.last_mouse = rep;
- }
- return rep;
-}
-
//////////////////////////////////////////////////////////////////////////////
// Split RPC
From 6451272edb1d96a803d4541cd3c0d77e38f47b89 Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Thu, 13 Jun 2024 03:48:38 -0700
Subject: [PATCH 27/32] Remove `motion_to_mouse()` function from keyball lib
No longer used.
---
keyboards/yowkees/lib/keyball/keyball.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/keyboards/yowkees/lib/keyball/keyball.c b/keyboards/yowkees/lib/keyball/keyball.c
index 48eaa509b7f..c560cab6eaf 100644
--- a/keyboards/yowkees/lib/keyball/keyball.c
+++ b/keyboards/yowkees/lib/keyball/keyball.c
@@ -208,14 +208,6 @@ __attribute__((weak)) void keyball_on_apply_motion_to_mouse_scroll(keyball_motio
#endif
}
-static void motion_to_mouse(keyball_motion_t *m, report_mouse_t *r, bool is_left, bool as_scroll) {
- if (as_scroll) {
- keyball_on_apply_motion_to_mouse_scroll(m, r, is_left);
- } else {
- keyball_on_apply_motion_to_mouse_move(m, r, is_left);
- }
-}
-
static inline bool should_report(void) {
uint32_t now = timer_read32();
#if defined(KEYBALL_REPORTMOUSE_INTERVAL) && KEYBALL_REPORTMOUSE_INTERVAL > 0
From 6d9c10235ffb13fed8ea0810725f60cf90b58cda Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Thu, 13 Jun 2024 03:50:53 -0700
Subject: [PATCH 28/32] Redefine `pmw3360_MAXCPI` (as `KEYBALL_PMW3360_MAXCPI`)
This was previously defined in the custom driver. The
`keyball_set_cpi()` needs it (indirectly), so it has been redefined.
---
keyboards/yowkees/lib/keyball/keyball.c | 6 +++++-
keyboards/yowkees/lib/keyball/keyball.h | 4 ++++
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/keyboards/yowkees/lib/keyball/keyball.c b/keyboards/yowkees/lib/keyball/keyball.c
index c560cab6eaf..abac56b6772 100644
--- a/keyboards/yowkees/lib/keyball/keyball.c
+++ b/keyboards/yowkees/lib/keyball/keyball.c
@@ -25,7 +25,11 @@ along with this program. If not, see .
#include
const uint8_t CPI_DEFAULT = KEYBALL_CPI_DEFAULT / 100;
-const uint8_t CPI_MAX = pmw3360_MAXCPI + 1;
+/**
+ * The Keyball library uses a range of 0 <= cpi <= 119 internally, and the true
+ * CPI value is ( cpi + 1 ) * 100.
+ */
+const uint8_t CPI_MAX = KEYBALL_PMW3360_MAXCPI + 1; // 119 + 1 = 12000 CPI actual
const uint8_t SCROLL_DIV_MAX = 7;
const uint16_t AML_TIMEOUT_MIN = 100;
diff --git a/keyboards/yowkees/lib/keyball/keyball.h b/keyboards/yowkees/lib/keyball/keyball.h
index 32003a84632..cb54241f46c 100644
--- a/keyboards/yowkees/lib/keyball/keyball.h
+++ b/keyboards/yowkees/lib/keyball/keyball.h
@@ -49,6 +49,10 @@ along with this program. If not, see .
# define KEYBALL_SCROLLSNAP_TENSION_THRESHOLD 12
#endif
+#ifndef KEYBALL_PMW3360_MAXCPI
+# define KEYBALL_PMW3360_MAXCPI 119 // 12000 CPI actual
+#endif
+
/// Specify SROM ID to be uploaded PMW3360DW (optical sensor). It will be
/// enabled high CPI setting or so. Valid valus are 0x04 or 0x81. Define this
/// in your config.h to be enable. Please note that using this option will
From 3b2529ccd25781728961d0052fa7a71e1f9ec2cc Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Thu, 13 Jun 2024 03:55:28 -0700
Subject: [PATCH 29/32] Use core `pmw33xx_set_cpi()` function in
`keyball_set_cpi()`
QMK's core PMW3360 driver uses the true CPI value internally, so we have
to translate the Keyball library's value to QMK's expected range.
QMK's core driver also caps the range internally to a valid CPI value,
so we don't need to do it here.
---
keyboards/yowkees/lib/keyball/keyball.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/keyboards/yowkees/lib/keyball/keyball.c b/keyboards/yowkees/lib/keyball/keyball.c
index abac56b6772..2c89e2e4d41 100644
--- a/keyboards/yowkees/lib/keyball/keyball.c
+++ b/keyboards/yowkees/lib/keyball/keyball.c
@@ -505,7 +505,15 @@ void keyball_set_cpi(uint8_t cpi) {
keyball.cpi_value = cpi;
keyball.cpi_changed = true;
if (keyball.this_have_ball) {
- pmw3360_cpi_set(cpi == 0 ? CPI_DEFAULT - 1 : cpi - 1);
+ /**
+ * QMK's core PMW3360 driver uses the true CPI value internally, so we
+ * have to translate the Keyball library's value to QMK's expected
+ * range.
+ *
+ * QMK's core driver also caps the range internally to a valid CPI
+ * value, so we don't need to do it here.
+ */
+ pmw33xx_set_cpi(0, (cpi + 1) * 100);
}
}
From 189bb734788fb155d233df2c7aad412805a8adfd Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Tue, 9 Jul 2024 19:30:58 -0700
Subject: [PATCH 30/32] Disable RGBLIGHT effects for default keymap
---
.../keyball39/keymaps/default/config.h | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/keyboards/yowkees/keyball39/keymaps/default/config.h b/keyboards/yowkees/keyball39/keymaps/default/config.h
index ec062cf45e0..62ea986c7dc 100644
--- a/keyboards/yowkees/keyball39/keymaps/default/config.h
+++ b/keyboards/yowkees/keyball39/keymaps/default/config.h
@@ -21,16 +21,16 @@ along with this program. If not, see .
#pragma once
#ifdef RGBLIGHT_ENABLE
-# define RGBLIGHT_EFFECT_BREATHING
-# define RGBLIGHT_EFFECT_RAINBOW_MOOD
-# define RGBLIGHT_EFFECT_RAINBOW_SWIRL
-# define RGBLIGHT_EFFECT_SNAKE
-# define RGBLIGHT_EFFECT_KNIGHT
-# define RGBLIGHT_EFFECT_CHRISTMAS
-# define RGBLIGHT_EFFECT_STATIC_GRADIENT
-# define RGBLIGHT_EFFECT_RGB_TEST
-# define RGBLIGHT_EFFECT_ALTERNATING
-# define RGBLIGHT_EFFECT_TWINKLE
+//# define RGBLIGHT_EFFECT_BREATHING
+//# define RGBLIGHT_EFFECT_RAINBOW_MOOD
+//# define RGBLIGHT_EFFECT_RAINBOW_SWIRL
+//# define RGBLIGHT_EFFECT_SNAKE
+//# define RGBLIGHT_EFFECT_KNIGHT
+//# define RGBLIGHT_EFFECT_CHRISTMAS
+//# define RGBLIGHT_EFFECT_STATIC_GRADIENT
+//# define RGBLIGHT_EFFECT_RGB_TEST
+//# define RGBLIGHT_EFFECT_ALTERNATING
+//# define RGBLIGHT_EFFECT_TWINKLE
#endif
#define TAP_CODE_DELAY 5
From 41fbc685b3007636a798ceefaa55488f8101ff35 Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Tue, 9 Jul 2024 19:45:18 -0700
Subject: [PATCH 31/32] Enable PMW33XX SROM upload for default keymap
---
keyboards/yowkees/keyball39/keymaps/default/config.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/keyboards/yowkees/keyball39/keymaps/default/config.h b/keyboards/yowkees/keyball39/keymaps/default/config.h
index 62ea986c7dc..2e4971f0f5c 100644
--- a/keyboards/yowkees/keyball39/keymaps/default/config.h
+++ b/keyboards/yowkees/keyball39/keymaps/default/config.h
@@ -20,6 +20,8 @@ along with this program. If not, see .
#pragma once
+#define PMW33XX_UPLOAD_SROM
+
#ifdef RGBLIGHT_ENABLE
//# define RGBLIGHT_EFFECT_BREATHING
//# define RGBLIGHT_EFFECT_RAINBOW_MOOD
From db4d68fcd9f461f392c2dbfbd80cc8d1d5e2febf Mon Sep 17 00:00:00 2001
From: James Young <18669334+noroadsleft@users.noreply.github.com>
Date: Wed, 2 Oct 2024 16:37:16 -0700
Subject: [PATCH 32/32] Remove `via` keymap
---
.../yowkees/keyball39/keymaps/via/config.h | 39 -----------
.../yowkees/keyball39/keymaps/via/keymap.c | 69 -------------------
.../yowkees/keyball39/keymaps/via/rules.mk | 1 -
3 files changed, 109 deletions(-)
delete mode 100644 keyboards/yowkees/keyball39/keymaps/via/config.h
delete mode 100644 keyboards/yowkees/keyball39/keymaps/via/keymap.c
delete mode 100644 keyboards/yowkees/keyball39/keymaps/via/rules.mk
diff --git a/keyboards/yowkees/keyball39/keymaps/via/config.h b/keyboards/yowkees/keyball39/keymaps/via/config.h
deleted file mode 100644
index 9736eae89c7..00000000000
--- a/keyboards/yowkees/keyball39/keymaps/via/config.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-This is the c configuration file for the keymap
-
-Copyright 2022 @Yowkees
-Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-#pragma once
-
-#ifdef RGBLIGHT_ENABLE
-//# define RGBLIGHT_EFFECT_BREATHING
-//# define RGBLIGHT_EFFECT_RAINBOW_MOOD
-//# define RGBLIGHT_EFFECT_RAINBOW_SWIRL
-//# define RGBLIGHT_EFFECT_SNAKE
-//# define RGBLIGHT_EFFECT_KNIGHT
-//# define RGBLIGHT_EFFECT_CHRISTMAS
-# define RGBLIGHT_EFFECT_STATIC_GRADIENT
-//# define RGBLIGHT_EFFECT_RGB_TEST
-//# define RGBLIGHT_EFFECT_ALTERNATING
-//# define RGBLIGHT_EFFECT_TWINKLE
-#endif
-
-#define TAP_CODE_DELAY 5
-
-#define POINTING_DEVICE_AUTO_MOUSE_ENABLE
-#define AUTO_MOUSE_DEFAULT_LAYER 1
diff --git a/keyboards/yowkees/keyball39/keymaps/via/keymap.c b/keyboards/yowkees/keyball39/keymaps/via/keymap.c
deleted file mode 100644
index 0849fe5494a..00000000000
--- a/keyboards/yowkees/keyball39/keymaps/via/keymap.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-Copyright 2022 @Yowkees
-Copyright 2022 MURAOKA Taro (aka KoRoN, @kaoriya)
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-#include QMK_KEYBOARD_H
-
-// clang-format off
-const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
- // keymap for default (VIA)
- [0] = LAYOUT_no_ball(
- KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P,
- KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_MINS,
- KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH,
- KC_LCTL, KC_LGUI, KC_LALT, LSFT_T(KC_LNG2), LT(1,KC_SPC), LT(3,KC_LNG1), KC_BSPC, LT(2,KC_ENT), LSFT_T(KC_LNG2), KC_RALT, KC_RGUI, KC_RSFT
- ),
-
- [1] = LAYOUT_no_ball(
- KC_F1, KC_F2, KC_F3, KC_F4, KC_RBRC, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10,
- KC_F5, KC_EXLM, S(KC_6), S(KC_INT3), S(KC_8), S(KC_INT1), KC_BTN1, KC_PGUP, KC_BTN2, KC_SCLN,
- S(KC_EQL), S(KC_LBRC), S(KC_7), S(KC_2), S(KC_RBRC), KC_LBRC, KC_DLR, KC_PGDN, KC_BTN3, KC_F11,
- KC_INT1, KC_EQL, S(KC_3), _______, _______, _______, TO(2), TO(0), _______, KC_RALT, KC_RGUI, KC_F12
- ),
-
- [2] = LAYOUT_no_ball(
- KC_TAB, KC_7, KC_8, KC_9, KC_MINS, KC_NUHS, _______, KC_BTN3, _______, KC_BSPC,
- S(KC_QUOT), KC_4, KC_5, KC_6, S(KC_SCLN), S(KC_9), KC_BTN1, KC_UP, KC_BTN2, KC_QUOT,
- KC_SLSH, KC_1, KC_2, KC_3, S(KC_MINS), S(KC_NUHS), KC_LEFT, KC_DOWN, KC_RGHT, _______,
- KC_ESC, KC_0, KC_DOT, KC_DEL, KC_ENT, KC_BSPC, _______, _______, _______, _______, _______, _______
- ),
-
- [3] = LAYOUT_no_ball(
- RGB_TOG, AML_TO, AML_I50, AML_D50, _______, _______, _______, SSNP_HOR, SSNP_VRT, SSNP_FRE,
- RGB_MOD, RGB_HUI, RGB_SAI, RGB_VAI, SCRL_DVI, _______, _______, _______, _______, _______,
- RGB_RMOD, RGB_HUD, RGB_SAD, RGB_VAD, SCRL_DVD, CPI_D1K, CPI_D100, CPI_I100, CPI_I1K, KBC_SAVE,
- QK_BOOT, KBC_RST, _______, _______, _______, _______, _______, _______, _______, _______, KBC_RST, QK_BOOT
- ),
-};
-// clang-format on
-
-layer_state_t layer_state_set_user(layer_state_t state) {
- // Auto enable scroll mode when the highest layer is 3
- keyball_set_scroll_mode(get_highest_layer(state) == 3);
- return state;
-}
-
-#ifdef OLED_ENABLE
-
-# include "lib/oledkit/oledkit.h"
-
-void oledkit_render_info_user(void) {
- keyball_oled_render_keyinfo();
- keyball_oled_render_ballinfo();
- keyball_oled_render_layerinfo();
-}
-#endif
diff --git a/keyboards/yowkees/keyball39/keymaps/via/rules.mk b/keyboards/yowkees/keyball39/keymaps/via/rules.mk
deleted file mode 100644
index 1e5b99807cb..00000000000
--- a/keyboards/yowkees/keyball39/keymaps/via/rules.mk
+++ /dev/null
@@ -1 +0,0 @@
-VIA_ENABLE = yes