├── .envrc ├── data ├── v1 │ ├── keyboards │ │ └── niz │ │ │ ├── atom66 │ │ │ ├── readme.md │ │ │ └── info.json │ │ │ └── micro84 │ │ │ ├── readme.md │ │ │ └── info.json │ └── keyboard_list.json └── Dockerfile ├── .gitignore ├── src ├── lib.rs ├── config.rs ├── main.rs ├── keyboard.rs └── consts.rs ├── Cargo.toml ├── README.md ├── flake.nix ├── LICENSE ├── niz-qmk-configurator.nix ├── flake.lock └── Cargo.lock /.envrc: -------------------------------------------------------------------------------- 1 | use flake 2 | -------------------------------------------------------------------------------- /data/v1/keyboards/niz/atom66/readme.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /data/v1/keyboards/niz/micro84/readme.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .direnv 3 | result 4 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod config; 2 | pub mod consts; 3 | pub mod keyboard; 4 | -------------------------------------------------------------------------------- /data/v1/keyboard_list.json: -------------------------------------------------------------------------------- 1 | { 2 | "keyboards": ["niz/atom66", "niz/micro84"] 3 | } 4 | -------------------------------------------------------------------------------- /data/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker.io/qmkfm/qmk_configurator:latest 2 | ENV QMK_API_URL https://example.com 3 | RUN sed -i "s/keyboards\.qmk\.fm/raw\.githubusercontent\.com\/NickCao\/nizctl\/master\/data/g" /qmk_configurator/dist/js/*.js 4 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "nizctl" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [profile.release] 7 | lto = true 8 | strip = true 9 | 10 | [dependencies] 11 | anyhow = "1.0.42" 12 | hidapi = "1.2.6" 13 | packed_struct = { version = "0.6", features = [ "byte_types_64" ] } 14 | serde = { version = "1.0", features = ["derive"] } 15 | serde_json = "1.0" 16 | clap = "=3.0.0-beta.2" 17 | clap_derive = "=3.0.0-beta.2" 18 | lazy_static = "1.4.0" 19 | dialog = "0.3.0" 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nizctl 2 | configure your niz keyboard without resorting to windows VMs 3 | 4 | ## usage 5 | use another keyboard when invoking nizctl to avoid strange behaviors (or just tap enter fast enough) 6 | the generated keymap file is compatible with qmk configurator, and can be used with the container built from `data/Dockerfile` 7 | 8 | ### nizctl pull 9 | dump current keymap to stdout 10 | 11 | ### nizctl push 12 | write new keymap from stdin 13 | 14 | ## supported models 15 | - Atom66 16 | - Micro84 17 | - (should work on other models with minor modification) 18 | 19 | ## TODO 20 | - [x] calibration 21 | - [ ] macro 22 | 23 | ## credits 24 | [niz-tools-ruby](https://github.com/cho45/niz-tools-ruby) 25 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable-small"; 4 | flake-utils.url = "github:numtide/flake-utils"; 5 | }; 6 | outputs = { self, nixpkgs, flake-utils }: 7 | flake-utils.lib.eachDefaultSystem 8 | (system: 9 | let pkgs = import nixpkgs { inherit system; overlays = [ self.overlay ]; }; in 10 | { 11 | packages = { inherit (pkgs) nizctl niz-qmk-configurator; }; 12 | devShell = pkgs.mkShell { inputsFrom = [ pkgs.nizctl ]; }; 13 | defaultPackage = pkgs.nizctl; 14 | } 15 | ) // 16 | { 17 | overlay = final: prev: { 18 | nizctl = final.rustPlatform.buildRustPackage { 19 | name = "nizctl"; 20 | src = final.lib.cleanSource ./.; 21 | nativeBuildInputs = [ final.pkg-config ]; 22 | buildInputs = [ final.hidapi final.libusb ]; 23 | cargoLock = { 24 | lockFile = ./Cargo.lock; 25 | }; 26 | }; 27 | 28 | niz-qmk-configurator = 29 | final.callPackage ./niz-qmk-configurator.nix { }; 30 | }; 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Nick Cao 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /niz-qmk-configurator.nix: -------------------------------------------------------------------------------- 1 | { runCommand 2 | , dockerTools 3 | , makeWrapper 4 | , gnutar 5 | , xdg-utils 6 | }: 7 | 8 | let 9 | qmk-configurator-image = dockerTools.pullImage { 10 | imageName = "docker.io/qmkfm/qmk_configurator"; 11 | imageDigest = "sha256:50e65561cc8b24049f77f4c79fc1e3bb01a7c2410cd351774ba8942c37b6e485"; 12 | sha256 = "0j61sr0l1dpw7r5swbpvssqfl98qpxnfgmiss9icpzh2rr9r3n5c"; 13 | finalImageName = "docker.io/qmkfm/qmk_configurator"; 14 | finalImageTag = "latest"; 15 | }; 16 | 17 | in 18 | runCommand "niz-qmk-configurator" 19 | { 20 | nativeBuildInputs = [ gnutar makeWrapper ]; 21 | buildInputs = [ xdg-utils ]; 22 | } '' 23 | mkdir -p "$out/opt" "$out/bin" 24 | 25 | mkdir image 26 | tar -xf ${qmk-configurator-image} -C image/ 27 | 28 | # Find layer in docker image containing actual configurator code 29 | found_layer= 30 | for layer in image/*.tar; do 31 | if (tar -tf "$layer" 2>/dev/null || true) | grep --silent '^qmk_configurator/dist'; then 32 | found_layer="$layer" 33 | fi 34 | done 35 | 36 | 37 | if [ -z "$found_layer" ]; then 38 | echo No qmk_configurator/dist layer found >&2 39 | exit 1 40 | else 41 | echo "Found qmk_configurator/dist in $layer" 42 | fi 43 | 44 | # Extract that layer to $out/opt 45 | tar -xf "$found_layer" -C $out/opt 46 | 47 | # Replace keyboard info URL references 48 | sed -i "s/keyboards\.qmk\.fm/raw\.githubusercontent\.com\/NickCao\/nizctl\/master\/data/g" "$out"/opt/qmk_configurator/dist/js/*.js 49 | 50 | # Make a convenient runner 51 | cat <"$out/bin/niz-qmk-configurator" 52 | #!/bin/sh 53 | exec xdg-open $out/opt/qmk_configurator/dist/index.html 54 | END 55 | 56 | chmod +x "$out/bin/niz-qmk-configurator" 57 | '' 58 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "inputs": { 5 | "systems": "systems" 6 | }, 7 | "locked": { 8 | "lastModified": 1705309234, 9 | "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", 10 | "owner": "numtide", 11 | "repo": "flake-utils", 12 | "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "numtide", 17 | "repo": "flake-utils", 18 | "type": "github" 19 | } 20 | }, 21 | "nixpkgs": { 22 | "locked": { 23 | "lastModified": 1707594574, 24 | "narHash": "sha256-dsNAxqxAjajzZKJtMDyKCl6R2VOHCG5B5F0kmb08lA4=", 25 | "owner": "NixOS", 26 | "repo": "nixpkgs", 27 | "rev": "4907e7a50c83b6214239d30a833f59493754eb48", 28 | "type": "github" 29 | }, 30 | "original": { 31 | "owner": "NixOS", 32 | "ref": "nixos-unstable-small", 33 | "repo": "nixpkgs", 34 | "type": "github" 35 | } 36 | }, 37 | "root": { 38 | "inputs": { 39 | "flake-utils": "flake-utils", 40 | "nixpkgs": "nixpkgs" 41 | } 42 | }, 43 | "systems": { 44 | "locked": { 45 | "lastModified": 1681028828, 46 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 47 | "owner": "nix-systems", 48 | "repo": "default", 49 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 50 | "type": "github" 51 | }, 52 | "original": { 53 | "owner": "nix-systems", 54 | "repo": "default", 55 | "type": "github" 56 | } 57 | } 58 | }, 59 | "root": "root", 60 | "version": 7 61 | } 62 | -------------------------------------------------------------------------------- /src/config.rs: -------------------------------------------------------------------------------- 1 | use crate::consts; 2 | use serde::{Deserialize, Serialize}; 3 | use std::convert::TryInto; 4 | 5 | #[derive(Serialize, Deserialize, Debug)] 6 | pub struct Keymap { 7 | pub version: u8, 8 | pub keyboard: String, 9 | pub keymap: String, 10 | pub layout: String, 11 | pub layers: Vec>, 12 | } 13 | 14 | impl Keymap { 15 | pub fn new(keyboard: String, keymap: Vec>) -> Self { 16 | Self { 17 | version: 1, 18 | keyboard, 19 | keymap: "default".to_string(), 20 | layout: "LAYOUT".to_string(), 21 | layers: layers_from_keymap(keymap), 22 | } 23 | } 24 | pub fn encode(&self) -> serde_json::Result { 25 | serde_json::to_string(self) 26 | } 27 | pub fn decode(keymap: &str) -> serde_json::Result { 28 | serde_json::from_str(keymap) 29 | } 30 | } 31 | 32 | pub fn layers_from_keymap(keymap: Vec>) -> Vec> { 33 | keymap 34 | .iter() 35 | .map(|layer| { 36 | layer 37 | .iter() 38 | .map(|&keycode| consts::KEY_CODE_NAME[keycode as usize].to_string()) 39 | .collect() 40 | }) 41 | .collect() 42 | } 43 | 44 | pub fn keymap_from_layers(layers: Vec>) -> Vec> { 45 | layers 46 | .iter() 47 | .map(|layer| { 48 | layer 49 | .iter() 50 | .map(|name| { 51 | consts::KEY_CODE_NAME 52 | .iter() 53 | .position(|x| x == name) 54 | .unwrap_or(0) 55 | .try_into() 56 | .unwrap() 57 | }) 58 | .collect() 59 | }) 60 | .collect() 61 | } 62 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::Clap; 2 | use dialog::DialogBox; 3 | use nizctl::{config, keyboard}; 4 | use std::io::Read; 5 | 6 | #[derive(Clap, Debug)] 7 | #[clap(name = "nizctl")] 8 | struct Nizctl { 9 | #[clap(subcommand)] 10 | sub: SubCommand, 11 | } 12 | 13 | #[derive(Clap, Debug)] 14 | enum SubCommand { 15 | Pull(Pull), 16 | Push(Push), 17 | Lock(Lock), 18 | Unlock(Unlock), 19 | Calib(Calib), 20 | } 21 | 22 | #[derive(Clap, Debug)] 23 | struct Pull {} 24 | 25 | #[derive(Clap, Debug)] 26 | struct Push {} 27 | 28 | #[derive(Clap, Debug)] 29 | struct Lock {} 30 | 31 | #[derive(Clap, Debug)] 32 | struct Unlock {} 33 | 34 | #[derive(Clap, Debug)] 35 | struct Calib {} 36 | 37 | fn main() { 38 | let opts: Nizctl = Nizctl::parse(); 39 | match opts.sub { 40 | SubCommand::Pull(_) => { 41 | let kbd = keyboard::Keyboard::open().unwrap(); 42 | println!( 43 | "{}", 44 | config::Keymap::new(format!("niz/{}", kbd.name), kbd.read_keymap().unwrap()) 45 | .encode() 46 | .unwrap() 47 | ); 48 | } 49 | SubCommand::Push(_) => { 50 | let mut buffer = String::new(); 51 | std::io::stdin().read_to_string(&mut buffer).unwrap(); 52 | keyboard::Keyboard::open() 53 | .unwrap() 54 | .write_keymap(config::keymap_from_layers( 55 | config::Keymap::decode(&buffer).unwrap().layers, 56 | )) 57 | .unwrap() 58 | } 59 | SubCommand::Lock(_) => { 60 | if dialog::Question::new("do you really want to lock your keyboard, you will need another keyboard to unlock").title("Warning").show().unwrap() == dialog::Choice::Yes 61 | { 62 | keyboard::Keyboard::open().unwrap().keylock().unwrap(); 63 | } 64 | } 65 | SubCommand::Unlock(_) => { 66 | keyboard::Keyboard::open().unwrap().keyunlock().unwrap(); 67 | } 68 | SubCommand::Calib(_) => { 69 | let ans = dialog::Question::new("Before starting the calibration process, make sure that all the keys are released, if you are seeing this message in your terminal, either install zenity or kdialog, or use another keyboard during the process.").title("Reminder").show().unwrap(); 70 | if ans != dialog::Choice::Yes { 71 | return; 72 | } 73 | let kbd = keyboard::Keyboard::open().unwrap(); 74 | kbd.keylock().unwrap(); 75 | kbd.calib().unwrap(); 76 | while dialog::Question::new("hold the key you want to calibrate firmly, then press Yes, when you are done, press No").title("Calib").show().unwrap() == dialog::Choice::Yes { 77 | kbd.calib_press().unwrap(); 78 | } 79 | kbd.keyunlock().unwrap(); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/keyboard.rs: -------------------------------------------------------------------------------- 1 | use crate::consts::{self, OpCode}; 2 | use anyhow::Result; 3 | use hidapi::{HidApi, HidDevice}; 4 | use packed_struct::prelude::*; 5 | use std::convert::TryInto; 6 | 7 | pub struct Keyboard { 8 | pub name: &'static str, 9 | device: HidDevice, 10 | } 11 | 12 | impl Keyboard { 13 | pub fn open() -> Result { 14 | let hidapi = HidApi::new()?; 15 | for device in hidapi.device_list() { 16 | if device.vendor_id() == consts::VENDOR_ID 17 | && device.interface_number() == consts::INTERFACE_ID 18 | { 19 | if let Some(name) = consts::PRODUCT_ID.get(&device.product_id()) { 20 | let device = device.open_device(&hidapi)?; 21 | return Ok(Keyboard { name, device }); 22 | } 23 | } 24 | } 25 | Err(anyhow::anyhow!("no mactching device found")) 26 | } 27 | 28 | pub fn write_msg>(&self, msg: T) -> Result { 29 | Ok(self.device.write(&msg.pack()?)?) 30 | } 31 | 32 | pub fn read_msg>(&self) -> Result { 33 | let mut buf: [u8; 64] = [0; 64]; 34 | self.device.read_timeout(&mut buf, 100)?; 35 | Ok(T::unpack(&buf)?) 36 | } 37 | 38 | pub fn read_version(&self) -> Result { 39 | self.write_msg(Request::new(OpCode::VersionRead))?; 40 | let record: Version = self.read_msg()?; 41 | Ok(String::from_utf8_lossy(&record.version) 42 | .trim_end_matches('\u{0}') 43 | .to_string()) 44 | } 45 | 46 | pub fn read_counter(&self) -> Result> { 47 | self.write_msg(Request::new(OpCode::CounterRead))?; 48 | let mut counter: Vec = vec![]; 49 | loop { 50 | let record: KeyCounter = self.read_msg()?; 51 | if record._id != 0 { 52 | break; 53 | } 54 | counter.append(&mut record.count[..((record.size / 4) as usize)].to_vec()); 55 | } 56 | Ok(counter) 57 | } 58 | 59 | pub fn read_keymap(&self) -> Result>> { 60 | self.write_msg(Request::new(OpCode::KeymapDataRead))?; 61 | let mut keymap: Vec> = vec![]; 62 | loop { 63 | let record: KeymapResponse = self.read_msg()?; 64 | if record._id != 0 { 65 | break; 66 | } 67 | if record.layer as usize > keymap.len() { 68 | keymap.resize(record.layer as usize, vec![]); 69 | } 70 | let layer = &mut keymap[(record.layer - 1) as usize]; 71 | if record.key as usize > layer.len() { 72 | layer.resize(record.key as usize, 0); 73 | } 74 | layer[(record.key - 1) as usize] = record.keycode; 75 | } 76 | Ok(keymap) 77 | } 78 | 79 | pub fn calib(&self) -> Result<()> { 80 | self.write_msg(Request::new(OpCode::CalibInit))?; 81 | Ok(()) 82 | } 83 | 84 | pub fn calib_press(&self) -> Result<()> { 85 | self.write_msg(Request::new(OpCode::CalibPressed))?; 86 | let _msg: Request = self.read_msg()?; 87 | Ok(()) 88 | } 89 | 90 | pub fn keylock(&self) -> Result<()> { 91 | self.write_msg(Request::new(OpCode::KeyLock))?; 92 | Ok(()) 93 | } 94 | pub fn keyunlock(&self) -> Result<()> { 95 | let mut data = [0; 61]; 96 | data[0] = 1; 97 | self.write_msg(Request::new_with_data(OpCode::KeyLock, data))?; 98 | Ok(()) 99 | } 100 | 101 | pub fn write_keymap(&self, keymap: Vec>) -> Result<()> { 102 | self.write_msg(Request::new(OpCode::KeymapDataStart))?; 103 | for (i, layer) in keymap.iter().enumerate() { 104 | for (key, &keycode) in layer.iter().enumerate() { 105 | self.write_msg(Request::new_with_data( 106 | OpCode::KeymapData, 107 | KeymapData::new((i + 1).try_into()?, (key + 1).try_into()?, keycode).pack()?, 108 | ))?; 109 | } 110 | } 111 | self.write_msg(Request::new_with_data( 112 | OpCode::KeymapDataEnd, 113 | [OpCode::KeymapDataEnd as u8; 61], 114 | ))?; 115 | Ok(()) 116 | } 117 | } 118 | 119 | #[derive(PackedStruct)] 120 | #[packed_struct(endian = "msb")] 121 | pub struct Request { 122 | _id: u8, 123 | op: u16, 124 | data: [u8; 61], 125 | } 126 | 127 | impl Request { 128 | pub fn new(op: consts::OpCode) -> Self { 129 | Self::new_with_data(op, [0; 61]) 130 | } 131 | pub fn new_with_data(op: consts::OpCode, data: [u8; 61]) -> Self { 132 | Self { 133 | _id: 0, 134 | op: op as u16, 135 | data, 136 | } 137 | } 138 | } 139 | 140 | #[derive(PackedStruct)] 141 | #[packed_struct(endian = "msb")] 142 | pub struct Version { 143 | _id: u8, 144 | _type: u8, 145 | version: [u8; 62], 146 | } 147 | 148 | #[derive(PackedStruct)] 149 | #[packed_struct(endian = "msb")] 150 | pub struct KeyCounter { 151 | _id: u8, 152 | _type: u8, 153 | size: u8, 154 | #[packed_field(endian = "lsb")] 155 | count: [u32; 15], 156 | _padding: u8, 157 | } 158 | 159 | #[derive(PackedStruct)] 160 | #[packed_struct(endian = "msb")] 161 | pub struct KeymapResponse { 162 | _id: u8, 163 | _type: u8, 164 | layer: u8, 165 | key: u8, 166 | _zero: u8, 167 | active: u8, 168 | keycode: u8, 169 | _padding: [u8; 57], 170 | } 171 | 172 | #[derive(PackedStruct)] 173 | #[packed_struct(endian = "msb")] 174 | pub struct KeymapData { 175 | layer: u8, 176 | key: u8, 177 | _zero: u8, 178 | active: u8, 179 | keycode: u8, 180 | _padding: [u8; 56], 181 | } 182 | 183 | impl KeymapData { 184 | pub fn new(layer: u8, key: u8, keycode: u8) -> Self { 185 | Self { 186 | layer, 187 | key, 188 | _zero: 0, 189 | active: if keycode == 0 { 0 } else { 1 }, 190 | keycode, 191 | _padding: [0; 56], 192 | } 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/consts.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | 3 | pub const VENDOR_ID: u16 = 0x0483; 4 | pub const INTERFACE_ID: i32 = 1; 5 | lazy_static::lazy_static! { 6 | pub static ref PRODUCT_ID: HashMap = { 7 | let mut map = HashMap::new(); 8 | map.insert(0x512a, "atom66"); 9 | map.insert(0x5129, "micro84"); 10 | map 11 | }; 12 | } 13 | 14 | #[repr(u16)] 15 | pub enum OpCode { 16 | VersionRead = 0xf9, 17 | CounterRead = 0xe3, 18 | KeyLock = 0xd9, 19 | 20 | KeymapDataRead = 0xf2, 21 | KeymapDataStart = 0xf1, 22 | KeymapData = 0xf0, 23 | KeymapDataEnd = 0xf6, 24 | 25 | CalibInit = 0xdb, 26 | CalibPressed = 0xdd, 27 | } 28 | 29 | pub const KEY_CODE_NAME: [&str; 256] = [ 30 | "KC_NO", 31 | "KC_ESC", 32 | "KC_F1", 33 | "KC_F2", 34 | "KC_F3", 35 | "KC_F4", 36 | "KC_F5", 37 | "KC_F6", 38 | "KC_F7", 39 | "KC_F8", 40 | "KC_F9", 41 | "KC_F10", 42 | "KC_F11", 43 | "KC_F12", 44 | "KC_GRV", 45 | "KC_1", 46 | "KC_2", 47 | "KC_3", 48 | "KC_4", 49 | "KC_5", 50 | "KC_6", 51 | "KC_7", 52 | "KC_8", 53 | "KC_9", 54 | "KC_0", 55 | "KC_MINS", 56 | "KC_EQL", 57 | "KC_BSPC", 58 | "KC_TAB", 59 | "KC_Q", 60 | "KC_W", 61 | "KC_E", 62 | "KC_R", 63 | "KC_T", 64 | "KC_Y", 65 | "KC_U", 66 | "KC_I", 67 | "KC_O", 68 | "KC_P", 69 | "KC_LBRC", 70 | "KC_RBRC", 71 | "KC_BSLS", 72 | "KC_CAPS", 73 | "KC_A", 74 | "KC_S", 75 | "KC_D", 76 | "KC_F", 77 | "KC_G", 78 | "KC_H", 79 | "KC_J", 80 | "KC_K", 81 | "KC_L", 82 | "KC_SCLN", 83 | "KC_QUOT", 84 | "KC_ENT", 85 | "KC_LSFT", 86 | "KC_Z", 87 | "KC_X", 88 | "KC_C", 89 | "KC_V", 90 | "KC_B", 91 | "KC_N", 92 | "KC_M", 93 | "KC_COMM", 94 | "KC_DOT", 95 | "KC_SLSH", 96 | "KC_RSFT", 97 | "KC_LCTL", 98 | "KC_LGUI", 99 | "KC_LALT", 100 | "KC_SPC", 101 | "KC_RALT", 102 | "KC_RGUI", 103 | "KC_APPLICATION", 104 | "KC_RCTL", 105 | "KC_SYSTEM_WAKE", 106 | "KC_SYSTEM_SLEEP", 107 | "KC_SYSTEM_POWER", 108 | "KC_PSCR", 109 | "KC_SLCK", 110 | "KC_PAUS", 111 | "KC_INS", 112 | "KC_HOME", 113 | "KC_PGUP", 114 | "KC_DEL", 115 | "KC_END", 116 | "KC_PGDN", 117 | "KC_UP", 118 | "KC_LEFT", 119 | "KC_DOWN", 120 | "KC_RGHT", 121 | "KC_NUMLOCK", 122 | "KC_KP_SLASH", 123 | "KC_KP_ASTERISK", 124 | "KC_KP_7", 125 | "KC_KP_8", 126 | "KC_KP_9", 127 | "KC_KP_4", 128 | "KC_KP_5", 129 | "KC_KP_6", 130 | "KC_KP_1", 131 | "KC_KP_2", 132 | "KC_KP_3", 133 | "KC_KP_0", 134 | "KC_KP_DOT", 135 | "KC_KP_MINUS", 136 | "KC_KP_PLUS", 137 | "KC_KP_ENTER", 138 | "KC_MEDIA_NEXT_TRACK", 139 | "KC_MEDIA_PREV_TRACK", 140 | "KC_MEDIA_STOP", 141 | "KC_MEDIA_PLAY_PAUSE", 142 | "KC_AUDIO_MUTE", 143 | "KC_AUDIO_VOL_UP", 144 | "KC_AUDIO_VOL_DOWN", 145 | "KC_MEDIA_SELECT", 146 | "KC_MAIL", 147 | "KC_CALCULATOR", 148 | "KC_MY_COMPUTER", 149 | "KC_WWW_SEARCH", 150 | "KC_WWW_HOME", 151 | "KC_WWW_BACK", 152 | "KC_WWW_FORWARD", 153 | "KC_WWW_STOP", 154 | "KC_WWW_REFRESH", 155 | "KC_WWW_FAVORITES", 156 | "KC_MS_L", 157 | "KC_MS_R", 158 | "KC_MS_U", 159 | "KC_MS_D", 160 | "KC_BTN1", 161 | "KC_BTN3", 162 | "KC_BTN2", 163 | "KC_MS_WH_UP", 164 | "KC_MS_WH_DOWN", 165 | "BL_TOGG", 166 | "KC_NO", // backlight macro 167 | "RGB_MODE_RGBTEST", // backlight demo 168 | "RGB_MODE_RAINBOW", // backlight star shower 169 | "RGB_MODE_KNIGHT", // backlight riffle 170 | "KC_NO", // backlight demo stop 171 | "BL_BRTG", 172 | "KC_NO", // breathe sequence - 173 | "KC_NO", // breathe sequence + 174 | "BL_DEC", 175 | "BL_INC", 176 | "KC_NO", // sunset or relax/aurora 177 | "KC_NO", // color breathe 178 | "KC_NO", // back color exchange 179 | "ANY(MI_TRNSU)", // adjust trigger point 180 | "ANY(MI_TOG)", // keyboard lock 181 | "RSFT_T(KC_UP)", 182 | "CL_SWAP", 183 | "GUI_OFF", 184 | "KC_NO", // mouse lock 185 | "ANY(UC_MOD)", // exchange win and mac 186 | "MO(1)", 187 | "ANY(MI_VELD)", // mouse unit pixel 188 | "ANY(MI_VELU)", // mouse unit time 189 | "ANY(MI_MOD)", // toggle programmable 190 | "KC_NO", // backlight record 1 191 | "KC_NO", // backlight record 2 192 | "KC_NO", // backlight record 3 193 | "KC_NO", // backlight record 4 194 | "KC_NO", // backlight record 5 195 | "KC_NO", // backlight record 6 196 | "MO(2)", 197 | "ANY(MI_CHU)", // wired/wireless 198 | "ANY(MI_CH1)", // bluetooth device 1 199 | "ANY(MI_CH2)", // bluetooth device 2 200 | "ANY(MI_CH3)", // bluetooth device 3 201 | "ANY(MI_MODSD)", // eco mode 202 | "ANY(MI_MODSU)", // game mode 203 | "KC_NO", // mouse first delay 204 | "ANY(MI_BENDD)", // key repeat rate 205 | "ANY(MI_BENDU)", // key response delay 206 | "KC_NO", // usb report rate 207 | "KC_NO", // key scan period 208 | "KC_NO", 209 | "KC_NO", 210 | "KC_NO", 211 | "KC_NO", 212 | "KC_NO", 213 | "KC_NO", 214 | "KC_NO", 215 | "KC_NO", 216 | "KC_NO", 217 | "KC_NO", 218 | "KC_NO", 219 | "KC_NO", 220 | "KC_NO", 221 | "KC_NO", 222 | "KC_NO", 223 | "KC_NO", 224 | "KC_NO", 225 | "KC_NO", 226 | "KC_NO", 227 | "KC_NO", 228 | "KC_NO", 229 | "KC_NO", 230 | "KC_NO", 231 | "KC_NO", 232 | "KC_NO", 233 | "KC_NO", 234 | "KC_NO", 235 | "KC_NO", 236 | "KC_NO", 237 | "KC_NO", 238 | "KC_NO", 239 | "KC_NO", 240 | "KC_NO", 241 | "KC_NO", 242 | "KC_NO", 243 | "KC_NO", 244 | "KC_NO", 245 | "KC_NO", 246 | "KC_NO", 247 | "KC_NO", 248 | "KC_NO", 249 | "KC_NO", 250 | "KC_NO", 251 | "KC_NO", 252 | "KC_NO", 253 | "KC_NO", 254 | "KC_NO", 255 | "KC_NO", 256 | "KC_NO", 257 | "KC_NO", 258 | "KC_NO", 259 | "KC_NO", 260 | "KC_NO", 261 | "KC_NO", 262 | "KC_NO", 263 | "KC_NO", 264 | "KC_NO", 265 | "KC_NO", 266 | "KC_NO", 267 | "KC_NO", 268 | "KC_NO", 269 | "KC_NO", 270 | "KC_NO", 271 | "KC_NO", 272 | "KC_NO", 273 | "KC_NO", 274 | "KC_NO", 275 | "KC_NO", 276 | "KC_NO", 277 | "KC_NO", 278 | "KC_NO", 279 | "KC_NO", 280 | "KC_NO", 281 | "KC_NO", 282 | "KC_NO", 283 | "KC_NO", 284 | "KC_NO", 285 | "KC_NO", 286 | ]; 287 | -------------------------------------------------------------------------------- /data/v1/keyboards/niz/atom66/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "keyboards": { 3 | "niz/atom66": { 4 | "keymaps": {}, 5 | "layouts": { 6 | "LAYOUT": { 7 | "layout": [ 8 | { 9 | "x": 0, 10 | "y": 0 11 | }, 12 | { 13 | "x": 1, 14 | "y": 0 15 | }, 16 | { 17 | "x": 2, 18 | "y": 0 19 | }, 20 | { 21 | "x": 3, 22 | "y": 0 23 | }, 24 | { 25 | "x": 4, 26 | "y": 0 27 | }, 28 | { 29 | "x": 5, 30 | "y": 0 31 | }, 32 | { 33 | "x": 6, 34 | "y": 0 35 | }, 36 | { 37 | "x": 7, 38 | "y": 0 39 | }, 40 | { 41 | "x": 8, 42 | "y": 0 43 | }, 44 | { 45 | "x": 9, 46 | "y": 0 47 | }, 48 | { 49 | "x": 10, 50 | "y": 0 51 | }, 52 | { 53 | "x": 11, 54 | "y": 0 55 | }, 56 | { 57 | "x": 12, 58 | "y": 0 59 | }, 60 | { 61 | "x": 13, 62 | "y": 0 63 | }, 64 | { 65 | "x": 14, 66 | "y": 0 67 | }, 68 | { 69 | "x": 0, 70 | "y": 1, 71 | "w": 1.5 72 | }, 73 | { 74 | "x": 1.5, 75 | "y": 1 76 | }, 77 | { 78 | "x": 2.5, 79 | "y": 1 80 | }, 81 | { 82 | "x": 3.5, 83 | "y": 1 84 | }, 85 | { 86 | "x": 4.5, 87 | "y": 1 88 | }, 89 | { 90 | "x": 5.5, 91 | "y": 1 92 | }, 93 | { 94 | "x": 6.5, 95 | "y": 1 96 | }, 97 | { 98 | "x": 7.5, 99 | "y": 1 100 | }, 101 | { 102 | "x": 8.5, 103 | "y": 1 104 | }, 105 | { 106 | "x": 9.5, 107 | "y": 1 108 | }, 109 | { 110 | "x": 10.5, 111 | "y": 1 112 | }, 113 | { 114 | "x": 11.5, 115 | "y": 1 116 | }, 117 | { 118 | "x": 12.5, 119 | "y": 1 120 | }, 121 | { 122 | "x": 13.5, 123 | "y": 1, 124 | "w": 1.5 125 | }, 126 | { 127 | "x": 0, 128 | "y": 2, 129 | "w": 1.75 130 | }, 131 | { 132 | "x": 1.75, 133 | "y": 2 134 | }, 135 | { 136 | "x": 2.75, 137 | "y": 2 138 | }, 139 | { 140 | "x": 3.75, 141 | "y": 2 142 | }, 143 | { 144 | "x": 4.75, 145 | "y": 2 146 | }, 147 | { 148 | "x": 5.75, 149 | "y": 2 150 | }, 151 | { 152 | "x": 6.75, 153 | "y": 2 154 | }, 155 | { 156 | "x": 7.75, 157 | "y": 2 158 | }, 159 | { 160 | "x": 8.75, 161 | "y": 2 162 | }, 163 | { 164 | "x": 9.75, 165 | "y": 2 166 | }, 167 | { 168 | "x": 10.75, 169 | "y": 2 170 | }, 171 | { 172 | "x": 11.75, 173 | "y": 2 174 | }, 175 | { 176 | "x": 12.75, 177 | "y": 2, 178 | "w": 2.25 179 | }, 180 | { 181 | "x": 0, 182 | "y": 3, 183 | "w": 2.25 184 | }, 185 | { 186 | "x": 2.25, 187 | "y": 3 188 | }, 189 | { 190 | "x": 3.25, 191 | "y": 3 192 | }, 193 | { 194 | "x": 4.25, 195 | "y": 3 196 | }, 197 | { 198 | "x": 5.25, 199 | "y": 3 200 | }, 201 | { 202 | "x": 6.25, 203 | "y": 3 204 | }, 205 | { 206 | "x": 7.25, 207 | "y": 3 208 | }, 209 | { 210 | "x": 8.25, 211 | "y": 3 212 | }, 213 | { 214 | "x": 9.25, 215 | "y": 3 216 | }, 217 | { 218 | "x": 10.25, 219 | "y": 3 220 | }, 221 | { 222 | "x": 11.25, 223 | "y": 3 224 | }, 225 | { 226 | "x": 12.25, 227 | "y": 3, 228 | "w": 1.75 229 | }, 230 | { 231 | "x": 14, 232 | "y": 3 233 | }, 234 | { 235 | "x": 0, 236 | "y": 4, 237 | "w": 1.25 238 | }, 239 | { 240 | "x": 1.25, 241 | "y": 4 242 | }, 243 | { 244 | "x": 2.25, 245 | "y": 4 246 | }, 247 | { 248 | "x": 3.25, 249 | "y": 4 250 | }, 251 | { 252 | "x": 4.25, 253 | "y": 4, 254 | "w": 4.75 255 | }, 256 | { 257 | "x": 9, 258 | "y": 4 259 | }, 260 | { 261 | "x": 10, 262 | "y": 4 263 | }, 264 | { 265 | "x": 11, 266 | "y": 4 267 | }, 268 | { 269 | "x": 12, 270 | "y": 4 271 | }, 272 | { 273 | "x": 13, 274 | "y": 4 275 | }, 276 | { 277 | "x": 14, 278 | "y": 4 279 | } 280 | ] 281 | } 282 | }, 283 | "width": 15, 284 | "height": 5 285 | } 286 | } 287 | } 288 | -------------------------------------------------------------------------------- /data/v1/keyboards/niz/micro84/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "keyboards": { 3 | "niz/micro84": { 4 | "keymaps": {}, 5 | "layouts": { 6 | "LAYOUT": { 7 | "layout": [ 8 | { 9 | "x": 0, 10 | "y": 0 11 | }, 12 | { 13 | "x": 1.75, 14 | "y": 0 15 | }, 16 | { 17 | "x": 2.75, 18 | "y": 0 19 | }, 20 | { 21 | "x": 3.75, 22 | "y": 0 23 | }, 24 | { 25 | "x": 4.75, 26 | "y": 0 27 | }, 28 | { 29 | "x": 6.25, 30 | "y": 0 31 | }, 32 | { 33 | "x": 7.25, 34 | "y": 0 35 | }, 36 | { 37 | "x": 8.25, 38 | "y": 0 39 | }, 40 | { 41 | "x": 9.25, 42 | "y": 0 43 | }, 44 | { 45 | "x": 10.75, 46 | "y": 0 47 | }, 48 | { 49 | "x": 11.75, 50 | "y": 0 51 | }, 52 | { 53 | "x": 12.75, 54 | "y": 0 55 | }, 56 | { 57 | "x": 13.75, 58 | "y": 0 59 | }, 60 | { 61 | "x": 15, 62 | "y": 0 63 | }, 64 | { 65 | "x": 0, 66 | "y": 1 67 | }, 68 | { 69 | "x": 1, 70 | "y": 1 71 | }, 72 | { 73 | "x": 2, 74 | "y": 1 75 | }, 76 | { 77 | "x": 3, 78 | "y": 1 79 | }, 80 | { 81 | "x": 4, 82 | "y": 1 83 | }, 84 | { 85 | "x": 5, 86 | "y": 1 87 | }, 88 | { 89 | "x": 6, 90 | "y": 1 91 | }, 92 | { 93 | "x": 7, 94 | "y": 1 95 | }, 96 | { 97 | "x": 8, 98 | "y": 1 99 | }, 100 | { 101 | "x": 9, 102 | "y": 1 103 | }, 104 | { 105 | "x": 10, 106 | "y": 1 107 | }, 108 | { 109 | "x": 11, 110 | "y": 1 111 | }, 112 | { 113 | "x": 12, 114 | "y": 1 115 | }, 116 | { 117 | "x": 13, 118 | "y": 1, 119 | "w": 2 120 | }, 121 | { 122 | "x": 15, 123 | "y": 1 124 | }, 125 | { 126 | "x": 0, 127 | "y": 2, 128 | "w": 1.5 129 | }, 130 | { 131 | "x": 1.5, 132 | "y": 2 133 | }, 134 | { 135 | "x": 2.5, 136 | "y": 2 137 | }, 138 | { 139 | "x": 3.5, 140 | "y": 2 141 | }, 142 | { 143 | "x": 4.5, 144 | "y": 2 145 | }, 146 | { 147 | "x": 5.5, 148 | "y": 2 149 | }, 150 | { 151 | "x": 6.5, 152 | "y": 2 153 | }, 154 | { 155 | "x": 7.5, 156 | "y": 2 157 | }, 158 | { 159 | "x": 8.5, 160 | "y": 2 161 | }, 162 | { 163 | "x": 9.5, 164 | "y": 2 165 | }, 166 | { 167 | "x": 10.5, 168 | "y": 2 169 | }, 170 | { 171 | "x": 11.5, 172 | "y": 2 173 | }, 174 | { 175 | "x": 12.5, 176 | "y": 2 177 | }, 178 | { 179 | "x": 13.5, 180 | "y": 2, 181 | "w": 1.5 182 | }, 183 | { 184 | "x": 15, 185 | "y": 2 186 | }, 187 | { 188 | "x": 0, 189 | "y": 3, 190 | "w": 1.75 191 | }, 192 | { 193 | "x": 1.75, 194 | "y": 3 195 | }, 196 | { 197 | "x": 2.75, 198 | "y": 3 199 | }, 200 | { 201 | "x": 3.75, 202 | "y": 3 203 | }, 204 | { 205 | "x": 4.75, 206 | "y": 3 207 | }, 208 | { 209 | "x": 5.75, 210 | "y": 3 211 | }, 212 | { 213 | "x": 6.75, 214 | "y": 3 215 | }, 216 | { 217 | "x": 7.75, 218 | "y": 3 219 | }, 220 | { 221 | "x": 8.75, 222 | "y": 3 223 | }, 224 | { 225 | "x": 9.75, 226 | "y": 3 227 | }, 228 | { 229 | "x": 10.75, 230 | "y": 3 231 | }, 232 | { 233 | "x": 11.75, 234 | "y": 3 235 | }, 236 | { 237 | "x": 12.75, 238 | "y": 3, 239 | "w": 2.25 240 | }, 241 | { 242 | "x": 15, 243 | "y": 3 244 | }, 245 | { 246 | "x": 0, 247 | "y": 4, 248 | "w": 2.25 249 | }, 250 | { 251 | "x": 2.25, 252 | "y": 4 253 | }, 254 | { 255 | "x": 3.25, 256 | "y": 4 257 | }, 258 | { 259 | "x": 4.25, 260 | "y": 4 261 | }, 262 | { 263 | "x": 5.25, 264 | "y": 4 265 | }, 266 | { 267 | "x": 6.25, 268 | "y": 4 269 | }, 270 | { 271 | "x": 7.25, 272 | "y": 4 273 | }, 274 | { 275 | "x": 8.25, 276 | "y": 4 277 | }, 278 | { 279 | "x": 9.25, 280 | "y": 4 281 | }, 282 | { 283 | "x": 10.25, 284 | "y": 4 285 | }, 286 | { 287 | "x": 11.25, 288 | "y": 4 289 | }, 290 | { 291 | "x": 12.25, 292 | "y": 4, 293 | "w": 1.75 294 | }, 295 | { 296 | "x": 14, 297 | "y": 4 298 | }, 299 | { 300 | "x": 15, 301 | "y": 4 302 | }, 303 | { 304 | "x": 0, 305 | "y": 5, 306 | "w": 1.25 307 | }, 308 | { 309 | "x": 1.25, 310 | "y": 5 311 | }, 312 | { 313 | "x": 2.25, 314 | "y": 5 315 | }, 316 | { 317 | "x": 3.25, 318 | "y": 5 319 | }, 320 | { 321 | "x": 4.24, 322 | "y": 5, 323 | "w": 4.75 324 | }, 325 | { 326 | "x": 9, 327 | "y": 5 328 | }, 329 | { 330 | "x": 10, 331 | "y": 5 332 | }, 333 | { 334 | "x": 11, 335 | "y": 5 336 | }, 337 | { 338 | "x": 12, 339 | "y": 5 340 | }, 341 | { 342 | "x": 13, 343 | "y": 5 344 | }, 345 | { 346 | "x": 14, 347 | "y": 5 348 | }, 349 | { 350 | "x": 15, 351 | "y": 5 352 | } 353 | ] 354 | } 355 | }, 356 | "width": 16, 357 | "height": 6 358 | } 359 | } 360 | } 361 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "anyhow" 7 | version = "1.0.79" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" 10 | 11 | [[package]] 12 | name = "atty" 13 | version = "0.2.14" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 16 | dependencies = [ 17 | "hermit-abi", 18 | "libc", 19 | "winapi 0.3.9", 20 | ] 21 | 22 | [[package]] 23 | name = "autocfg" 24 | version = "1.1.0" 25 | source = "registry+https://github.com/rust-lang/crates.io-index" 26 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 27 | 28 | [[package]] 29 | name = "bitflags" 30 | version = "1.3.2" 31 | source = "registry+https://github.com/rust-lang/crates.io-index" 32 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 33 | 34 | [[package]] 35 | name = "bitflags" 36 | version = "2.4.2" 37 | source = "registry+https://github.com/rust-lang/crates.io-index" 38 | checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" 39 | 40 | [[package]] 41 | name = "cc" 42 | version = "1.0.83" 43 | source = "registry+https://github.com/rust-lang/crates.io-index" 44 | checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" 45 | dependencies = [ 46 | "libc", 47 | ] 48 | 49 | [[package]] 50 | name = "cfg-if" 51 | version = "0.1.10" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 54 | 55 | [[package]] 56 | name = "cfg-if" 57 | version = "1.0.0" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 60 | 61 | [[package]] 62 | name = "clap" 63 | version = "3.0.0-beta.2" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | checksum = "4bd1061998a501ee7d4b6d449020df3266ca3124b941ec56cf2005c3779ca142" 66 | dependencies = [ 67 | "atty", 68 | "bitflags 1.3.2", 69 | "clap_derive", 70 | "indexmap", 71 | "lazy_static", 72 | "os_str_bytes", 73 | "strsim", 74 | "termcolor", 75 | "textwrap", 76 | "unicode-width", 77 | "vec_map", 78 | ] 79 | 80 | [[package]] 81 | name = "clap_derive" 82 | version = "3.0.0-beta.2" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | checksum = "370f715b81112975b1b69db93e0b56ea4cd4e5002ac43b2da8474106a54096a1" 85 | dependencies = [ 86 | "heck", 87 | "proc-macro-error", 88 | "proc-macro2", 89 | "quote", 90 | "syn 1.0.109", 91 | ] 92 | 93 | [[package]] 94 | name = "dialog" 95 | version = "0.3.0" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | checksum = "736bab36d647d14c985725a57a4110a1182c6852104536cd42f1c97e96d29bf0" 98 | dependencies = [ 99 | "dirs", 100 | "rpassword", 101 | ] 102 | 103 | [[package]] 104 | name = "dirs" 105 | version = "2.0.2" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" 108 | dependencies = [ 109 | "cfg-if 0.1.10", 110 | "dirs-sys", 111 | ] 112 | 113 | [[package]] 114 | name = "dirs-sys" 115 | version = "0.3.7" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" 118 | dependencies = [ 119 | "libc", 120 | "redox_users", 121 | "winapi 0.3.9", 122 | ] 123 | 124 | [[package]] 125 | name = "getrandom" 126 | version = "0.2.12" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" 129 | dependencies = [ 130 | "cfg-if 1.0.0", 131 | "libc", 132 | "wasi", 133 | ] 134 | 135 | [[package]] 136 | name = "hashbrown" 137 | version = "0.12.3" 138 | source = "registry+https://github.com/rust-lang/crates.io-index" 139 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 140 | 141 | [[package]] 142 | name = "heck" 143 | version = "0.3.3" 144 | source = "registry+https://github.com/rust-lang/crates.io-index" 145 | checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" 146 | dependencies = [ 147 | "unicode-segmentation", 148 | ] 149 | 150 | [[package]] 151 | name = "hermit-abi" 152 | version = "0.1.19" 153 | source = "registry+https://github.com/rust-lang/crates.io-index" 154 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 155 | dependencies = [ 156 | "libc", 157 | ] 158 | 159 | [[package]] 160 | name = "hidapi" 161 | version = "1.5.0" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | checksum = "798154e4b6570af74899d71155fb0072d5b17e6aa12f39c8ef22c60fb8ec99e7" 164 | dependencies = [ 165 | "cc", 166 | "libc", 167 | "pkg-config", 168 | "winapi 0.3.9", 169 | ] 170 | 171 | [[package]] 172 | name = "indexmap" 173 | version = "1.9.3" 174 | source = "registry+https://github.com/rust-lang/crates.io-index" 175 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 176 | dependencies = [ 177 | "autocfg", 178 | "hashbrown", 179 | ] 180 | 181 | [[package]] 182 | name = "itoa" 183 | version = "1.0.10" 184 | source = "registry+https://github.com/rust-lang/crates.io-index" 185 | checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" 186 | 187 | [[package]] 188 | name = "kernel32-sys" 189 | version = "0.2.2" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 192 | dependencies = [ 193 | "winapi 0.2.8", 194 | "winapi-build", 195 | ] 196 | 197 | [[package]] 198 | name = "lazy_static" 199 | version = "1.4.0" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 202 | 203 | [[package]] 204 | name = "libc" 205 | version = "0.2.153" 206 | source = "registry+https://github.com/rust-lang/crates.io-index" 207 | checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" 208 | 209 | [[package]] 210 | name = "libredox" 211 | version = "0.0.1" 212 | source = "registry+https://github.com/rust-lang/crates.io-index" 213 | checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" 214 | dependencies = [ 215 | "bitflags 2.4.2", 216 | "libc", 217 | "redox_syscall", 218 | ] 219 | 220 | [[package]] 221 | name = "nizctl" 222 | version = "0.1.0" 223 | dependencies = [ 224 | "anyhow", 225 | "clap", 226 | "clap_derive", 227 | "dialog", 228 | "hidapi", 229 | "lazy_static", 230 | "packed_struct", 231 | "serde", 232 | "serde_json", 233 | ] 234 | 235 | [[package]] 236 | name = "os_str_bytes" 237 | version = "2.4.0" 238 | source = "registry+https://github.com/rust-lang/crates.io-index" 239 | checksum = "afb2e1c3ee07430c2cf76151675e583e0f19985fa6efae47d6848a3e2c824f85" 240 | 241 | [[package]] 242 | name = "packed_struct" 243 | version = "0.6.1" 244 | source = "registry+https://github.com/rust-lang/crates.io-index" 245 | checksum = "d4e1e99bfad1f9eb1d5d775ce5f73694a93178376b6dc34c30eddce6f1bcf5f2" 246 | dependencies = [ 247 | "packed_struct_codegen", 248 | "serde", 249 | ] 250 | 251 | [[package]] 252 | name = "packed_struct_codegen" 253 | version = "0.6.1" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | checksum = "f8731210ac3e7bff5f86094b9f5b83a84d44965ce3e0b6c3ea827854a28d696c" 256 | dependencies = [ 257 | "proc-macro2", 258 | "quote", 259 | "syn 1.0.109", 260 | ] 261 | 262 | [[package]] 263 | name = "pkg-config" 264 | version = "0.3.29" 265 | source = "registry+https://github.com/rust-lang/crates.io-index" 266 | checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" 267 | 268 | [[package]] 269 | name = "proc-macro-error" 270 | version = "1.0.4" 271 | source = "registry+https://github.com/rust-lang/crates.io-index" 272 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 273 | dependencies = [ 274 | "proc-macro-error-attr", 275 | "proc-macro2", 276 | "quote", 277 | "syn 1.0.109", 278 | "version_check", 279 | ] 280 | 281 | [[package]] 282 | name = "proc-macro-error-attr" 283 | version = "1.0.4" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 286 | dependencies = [ 287 | "proc-macro2", 288 | "quote", 289 | "version_check", 290 | ] 291 | 292 | [[package]] 293 | name = "proc-macro2" 294 | version = "1.0.78" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" 297 | dependencies = [ 298 | "unicode-ident", 299 | ] 300 | 301 | [[package]] 302 | name = "quote" 303 | version = "1.0.35" 304 | source = "registry+https://github.com/rust-lang/crates.io-index" 305 | checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" 306 | dependencies = [ 307 | "proc-macro2", 308 | ] 309 | 310 | [[package]] 311 | name = "redox_syscall" 312 | version = "0.4.1" 313 | source = "registry+https://github.com/rust-lang/crates.io-index" 314 | checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" 315 | dependencies = [ 316 | "bitflags 1.3.2", 317 | ] 318 | 319 | [[package]] 320 | name = "redox_users" 321 | version = "0.4.4" 322 | source = "registry+https://github.com/rust-lang/crates.io-index" 323 | checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" 324 | dependencies = [ 325 | "getrandom", 326 | "libredox", 327 | "thiserror", 328 | ] 329 | 330 | [[package]] 331 | name = "rpassword" 332 | version = "2.1.0" 333 | source = "registry+https://github.com/rust-lang/crates.io-index" 334 | checksum = "d37473170aedbe66ffa3ad3726939ba677d83c646ad4fd99e5b4bc38712f45ec" 335 | dependencies = [ 336 | "kernel32-sys", 337 | "libc", 338 | "winapi 0.2.8", 339 | ] 340 | 341 | [[package]] 342 | name = "ryu" 343 | version = "1.0.16" 344 | source = "registry+https://github.com/rust-lang/crates.io-index" 345 | checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" 346 | 347 | [[package]] 348 | name = "serde" 349 | version = "1.0.196" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" 352 | dependencies = [ 353 | "serde_derive", 354 | ] 355 | 356 | [[package]] 357 | name = "serde_derive" 358 | version = "1.0.196" 359 | source = "registry+https://github.com/rust-lang/crates.io-index" 360 | checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" 361 | dependencies = [ 362 | "proc-macro2", 363 | "quote", 364 | "syn 2.0.48", 365 | ] 366 | 367 | [[package]] 368 | name = "serde_json" 369 | version = "1.0.113" 370 | source = "registry+https://github.com/rust-lang/crates.io-index" 371 | checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" 372 | dependencies = [ 373 | "itoa", 374 | "ryu", 375 | "serde", 376 | ] 377 | 378 | [[package]] 379 | name = "strsim" 380 | version = "0.10.0" 381 | source = "registry+https://github.com/rust-lang/crates.io-index" 382 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 383 | 384 | [[package]] 385 | name = "syn" 386 | version = "1.0.109" 387 | source = "registry+https://github.com/rust-lang/crates.io-index" 388 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 389 | dependencies = [ 390 | "proc-macro2", 391 | "quote", 392 | "unicode-ident", 393 | ] 394 | 395 | [[package]] 396 | name = "syn" 397 | version = "2.0.48" 398 | source = "registry+https://github.com/rust-lang/crates.io-index" 399 | checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" 400 | dependencies = [ 401 | "proc-macro2", 402 | "quote", 403 | "unicode-ident", 404 | ] 405 | 406 | [[package]] 407 | name = "termcolor" 408 | version = "1.4.1" 409 | source = "registry+https://github.com/rust-lang/crates.io-index" 410 | checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" 411 | dependencies = [ 412 | "winapi-util", 413 | ] 414 | 415 | [[package]] 416 | name = "textwrap" 417 | version = "0.12.1" 418 | source = "registry+https://github.com/rust-lang/crates.io-index" 419 | checksum = "203008d98caf094106cfaba70acfed15e18ed3ddb7d94e49baec153a2b462789" 420 | dependencies = [ 421 | "unicode-width", 422 | ] 423 | 424 | [[package]] 425 | name = "thiserror" 426 | version = "1.0.56" 427 | source = "registry+https://github.com/rust-lang/crates.io-index" 428 | checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" 429 | dependencies = [ 430 | "thiserror-impl", 431 | ] 432 | 433 | [[package]] 434 | name = "thiserror-impl" 435 | version = "1.0.56" 436 | source = "registry+https://github.com/rust-lang/crates.io-index" 437 | checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" 438 | dependencies = [ 439 | "proc-macro2", 440 | "quote", 441 | "syn 2.0.48", 442 | ] 443 | 444 | [[package]] 445 | name = "unicode-ident" 446 | version = "1.0.12" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 449 | 450 | [[package]] 451 | name = "unicode-segmentation" 452 | version = "1.11.0" 453 | source = "registry+https://github.com/rust-lang/crates.io-index" 454 | checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" 455 | 456 | [[package]] 457 | name = "unicode-width" 458 | version = "0.1.11" 459 | source = "registry+https://github.com/rust-lang/crates.io-index" 460 | checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" 461 | 462 | [[package]] 463 | name = "vec_map" 464 | version = "0.8.2" 465 | source = "registry+https://github.com/rust-lang/crates.io-index" 466 | checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" 467 | 468 | [[package]] 469 | name = "version_check" 470 | version = "0.9.4" 471 | source = "registry+https://github.com/rust-lang/crates.io-index" 472 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 473 | 474 | [[package]] 475 | name = "wasi" 476 | version = "0.11.0+wasi-snapshot-preview1" 477 | source = "registry+https://github.com/rust-lang/crates.io-index" 478 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 479 | 480 | [[package]] 481 | name = "winapi" 482 | version = "0.2.8" 483 | source = "registry+https://github.com/rust-lang/crates.io-index" 484 | checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 485 | 486 | [[package]] 487 | name = "winapi" 488 | version = "0.3.9" 489 | source = "registry+https://github.com/rust-lang/crates.io-index" 490 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 491 | dependencies = [ 492 | "winapi-i686-pc-windows-gnu", 493 | "winapi-x86_64-pc-windows-gnu", 494 | ] 495 | 496 | [[package]] 497 | name = "winapi-build" 498 | version = "0.1.1" 499 | source = "registry+https://github.com/rust-lang/crates.io-index" 500 | checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 501 | 502 | [[package]] 503 | name = "winapi-i686-pc-windows-gnu" 504 | version = "0.4.0" 505 | source = "registry+https://github.com/rust-lang/crates.io-index" 506 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 507 | 508 | [[package]] 509 | name = "winapi-util" 510 | version = "0.1.6" 511 | source = "registry+https://github.com/rust-lang/crates.io-index" 512 | checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" 513 | dependencies = [ 514 | "winapi 0.3.9", 515 | ] 516 | 517 | [[package]] 518 | name = "winapi-x86_64-pc-windows-gnu" 519 | version = "0.4.0" 520 | source = "registry+https://github.com/rust-lang/crates.io-index" 521 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 522 | --------------------------------------------------------------------------------