/// ## keyboard example
/// ```rust
/// cargo add doe -F kcm
///use doe::keyboard::key_click;
///use doe::keyboard::key_press;
///use doe::keyboard::key_release;
///use doe::keyboard::KeyCode;
///use doe::mouse::mouse_drag;
///use doe::mouse::move_to_paste;
///use doe::mouse::move_to_press_left;
///use doe::*;
///use keyboard::exit_if_click_esc;
///let list = vec!["iphone","ipad","macbook"];
///
///// crete new baogao
///move_to_press_left(857, 588).sleep(1.0); //#000000
///
///// create fengmian
///move_to_paste(1540, 853, "Apple").sleep(1.0); //#000000
///move_to_paste(1360, 882, "ID").sleep(1.0); //#000000
///
///// add shuoming
///move_to_paste(772, 464, "Discription").sleep(1.0); //#ffffff
///mouse_drag((894, 719).into(), (821, 716).into()).sleep(1.0); //#f0f0f0
///key_click("2024-01-23").sleep(1.0);
///move_to_press_left(740, 305).sleep(1.0); //#f0f0f0
///
///for name in list {
///    // add baobao
///    move_to_press_left(476, 253).sleep(1.0); //#ffffff
///
///    // name
///    move_to_press_left(796, 331).sleep(1.0); //#ffffff
///    key_click("end");
///    key_click("shift+home");
///    set_clipboard(name).unwrap().sleep(0.5);
///    key_click("ctrl+v");
///
///    // add fujian
///    move_to_press_left(870, 587).sleep(1.0); //#000000
///    mouse_drag((893, 818).into(), (814, 816).into()).sleep(1.0); //#f0f0f0
///    key_click("2024-01-23").sleep(1.0);
///    move_to_press_left(723, 206).sleep(1.0); //#000000
///}
///
///// set taoshu
///move_to_paste(1341, 910, "New_name").sleep(1.0); //#000000
/// ```
#[allow(warnings)]
#[cfg(feature = "keyboard")]
pub mod keyboard {
    pub mod common {
        #[allow(warnings)]
        /// key_modifiers: 'SHIFT' 'CONTROL' 'ALT' 'SUPER' 'HYPER' 'META' 'NONE'
        /// ```ignore
        /// use doe::keyboard::listen_keyboard_in_terminal;
        /// listen_keyboard_in_terminal(std::sync::Arc::new(|key|{
        ///    if key == "1,0x0,Press"{
        ///        b1::b1();
        ///    }
        /// }));
        /// ```
        pub fn listen_keyboard_in_terminal<F>(press_callback: std::sync::Arc<F>)
        where
            F: Fn(String) + std::marker::Sync + std::marker::Send + 'static,
        {
            use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
            use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
            use std::sync::mpsc;
            use std::thread;
            use std::time::Duration;

            // 启用原始模式，以便可以捕捉按键事件
            enable_raw_mode().expect("Failed to enable raw mode");

            // 创建一个通道，用于从键盘监听线程发送事件到主线程
            let (tx, rx) = mpsc::channel();

            // 复制通道的发送端，用于在键盘监听线程中发送事件
            let tx_clone = tx.clone();

            // 启动键盘监听线程
            thread::spawn(move || {
                // 每隔一段时间检查键盘事件并发送到通道
                loop {
                    if crossterm::event::poll(Duration::from_millis(100)).unwrap() {
                        if let crossterm::event::Event::Key(KeyEvent {
                            code,
                            modifiers,
                            state,
                            kind,
                        }) = crossterm::event::read().unwrap()
                        {
                            // 发送键盘事件到通道
                            tx_clone.send((code, modifiers, state, kind)).unwrap();
                        }
                    }
                }
            });

            // 主线程处理从通道接收到的键盘事件
            loop {
                if let Ok((code, modifiers, state, kind)) = rx.recv() {
                    // 在这里处理接收到的键盘事件
                    // println!(
                    //     "Key event received: {:?} with modifiers {:?}, state: {:?}, kind: {:?}",
                    //     code, modifiers, state,kind
                    // );
                    let code = format!("{:?}", code)
                        .replace("Char", "")
                        .replace(")", "")
                        .replace("'", "")
                        .replace("(", "");
                    let modifiers = format!("{:?}", modifiers)
                        .replace("KeyModifiers(", "")
                        .replace(" | ", ",")
                        .replace(")", "");
                    let _kind = format!("{:?}", kind);
                    press_callback(vec![code, modifiers, _kind].join(",").to_string());
                    // 如果需要退出循环，可以添加一个条件并调用disable_raw_mode来还原终端状态
                    disable_raw_mode().expect("Failed to disable raw mode");
                    // break;
                }
            }
        }
    }

    #[cfg(target_os = "linux")]
    pub mod linux {
        ///
        /// ```rust
        ///fn main(){
        ///     use doe::keyboard::keyboard::key_press;
        ///     key_press("ctrl+v",100);
        /// }
        /// ```
        ///
        ///

        #[cfg(target_os = "linux")]
        pub fn key_press(keys: &str) {
            use xdotool::command::options;
            use xdotool::keyboard::send_key_down;
            use xdotool::keyboard::send_key_up;
            use xdotool::option_vec;
            use xdotool::OptionVec;
            send_key_down(keys, option_vec![options::KeyboardOption::Delay(100)]);
        }
        #[cfg(target_os = "linux")]
        pub fn key_release(keys: &str) {
            use xdotool::command::options;
            use xdotool::keyboard::send_key_down;
            use xdotool::keyboard::send_key_up;
            use xdotool::option_vec;
            use xdotool::OptionVec;
            send_key_up(keys, option_vec![options::KeyboardOption::Delay(100)]);
        }
    }

    #[cfg(target_os = "macos")]
    pub mod macos {
        use core_foundation::base::TCFTypeRef;

        /// ```ignore
        /// "a" => Self::A,
        /// "b" => Self::B,
        /// "c" => Self::C,
        /// "d" => Self::D,
        /// "e" => Self::E,
        /// "f" => Self::F,
        /// "g" => Self::G,
        /// "h" => Self::H,
        /// "i" => Self::I,
        /// "j" => Self::J,
        /// "k" => Self::K,
        /// "l" => Self::L,
        /// "m" => Self::M,
        /// "n" => Self::N,
        /// "o" => Self::O,
        /// "p" => Self::P,
        /// "q" => Self::Q,
        /// "r" => Self::R,
        /// "s" => Self::S,
        /// "t" => Self::T,
        /// "u" => Self::U,
        /// "v" => Self::V,
        /// "w" => Self::W,
        /// "x" => Self::X,
        /// "y" => Self::Y,
        /// "z" => Self::Z,
        /// "0" => Self::NUM_0,
        /// "1" => Self::NUM_1,
        /// "2" => Self::NUM_2,
        /// "3" => Self::NUM_3,
        /// "4" => Self::NUM_4,
        /// "5" => Self::NUM_5,
        /// "6" => Self::NUM_6,
        /// "7" => Self::NUM_7,
        /// "8" => Self::NUM_8,
        /// "9" => Self::NUM_9,
        /// "f1" => Self::F1,
        /// "f2" => Self::F2,
        /// "f3" => Self::F3,
        /// "f4" => Self::F4,
        /// "f5" => Self::F5,
        /// "f6" => Self::F6,
        /// "f7" => Self::F7,
        /// "f8" => Self::F8,
        /// "f9" => Self::F9,
        /// "f10" => Self::F10,
        /// "f11" => Self::F11,
        /// "f12" => Self::F12,
        /// "f13"=>Self::F13,
        /// "f14"=>Self::F14,
        /// "f15"=>Self::F15,
        /// "f16"=>Self::F16,
        /// "f17"=>Self::F17,
        /// "f18"=>Self::F18,
        /// "f19"=>Self::F19,
        /// "20"=>Self::F20,
        /// "help"=>Self::HELP,
        /// "home"=>Self::HOME,
        /// "page_up"=>Self::PAGE_UP,
        /// "forward_delete"=>Self::FORWARD_DELETE,
        /// "end"=>Self::END,
        /// "page_down"=>Self::PAGE_DOWN,
        /// "left_arrow"=>Self::LEFT_ARROW,
        /// "right_arrow"=>Self::RIGHT_ARROW,
        /// "down_arrow"=>Self::DOWN_ARROW,
        /// "up_arrow"=>Self::UP_ARROW,
        /// "*"=>Self::SIGN_MUL,
        /// "+"=>Self::SIGN_ADD,
        /// "-"=>Self::SIGN_SUB,
        /// "."=>Self::SIGN_DOT,
        /// "/"=>Self::SIGN_DIV,
        /// "{"=>Self::LeftBracket,
        /// "}"=>Self::LeftBracket,
        /// "enter"=>Self::RETURN,
        /// "tab"=>Self::TAB,
        /// "space"=>Self::SPACE,
        /// "delete"=>Self::DELETE,
        /// "esc"=>Self::ESC,
        /// "command"=>Self::COMMAND,
        /// "shift"=>Self::SHIFT,
        /// "caps_lock"=>Self::CAPS_LOCK,
        /// "option"=>Self::OPTION,
        /// "ctrl"=>Self::CONTROL,
        /// "right_command"=>Self::RIGHT_COMMAND,
        /// "right_shift"=>Self::RIGHT_SHIFT,
        /// "right_option"=>Self::RIGHT_OPTION,
        /// "right_control"=>Self::RIGHT_CONTROL,
        /// "function"=>Self::FUNCTION,
        /// "volume_up"=>Self::VOLUME_UP,
        /// "volume_down"=>Self::VOLUME_DOWN,
        /// "mute"=>Self::MUTE,
        ///```
        /// # key_click
        /// ```ignore
        /// use doe::keyboard::key_click;
        /// use doe::mouse::move_to_press_left;
        /// use doe::*;
        /// move_to_press_left(726, 348).sleep(0.1);
        /// key_click("command+a");
        /// key_click("command+c");
        /// key_click("2027 command+a");
        /// key_click("command+shift+p");
        /// ```
        pub fn key_click(key: &str) {
            use crate::keyboard::KeyCode;
            use crate::traits::traits::Str;
            let key_vec = key.split_to_vec(" ");
            let keycode = KeyCode::default();
            for key in key_vec.iter() {
                if key == "+" {
                    let keycode = keycode.string_to_keycode(key.to_string());
                    key_press(keycode);
                    key_release(keycode);
                } else if key.contains("+") {
                    for key in key.split_to_vec("+") {
                        let keycode = keycode.string_to_keycode(key.to_string());
                        key_press(keycode);
                    }
                    for key in key.split_to_vec("+") {
                        let keycode = keycode.string_to_keycode(key.to_string());
                        key_release(keycode);
                    }
                } else {
                    for key in key.chars() {
                        let keycode = keycode.string_to_keycode(key.to_string());
                        key_press(keycode);
                        key_release(keycode);
                    }
                }
            }
        }

        /// ## keyboard example
        /// ```rust
        ///    use doe::keyboard::key_press;
        ///    use doe::keyboard::key_release;
        ///    use doe::keyboard::listen_mouse_position;
        ///    use doe::keyboard::get_mouse_position;
        ///
        ///    use doe::keyboard::KeyCode;
        ///    key_press(KeyCode::COMMAND);
        ///    key_press(KeyCode::V);
        ///    key_release(KeyCode::V);
        /// ```
        #[cfg(target_os = "macos")]
        pub fn key_press(keycode: u16) {
            use core_graphics::event::CGKeyCode;
            use core_graphics::event::{CGEvent, CGEventFlags, CGEventTapLocation};
            use core_graphics::event_source::CGEventSource;
            use core_graphics::event_source::CGEventSourceStateID;
            let state_id: CGEventSourceStateID = CGEventSourceStateID::HIDSystemState;
            let source: CGEventSource = CGEventSource::new(state_id).unwrap();
            let new_keycode: CGKeyCode = keycode;
            let event = CGEvent::new_keyboard_event(source, new_keycode, true).unwrap();
            event.set_flags(CGEventFlags::CGEventFlagCommand);
            event.post(CGEventTapLocation::HID);
        }
        /// ## keyboard example
        /// ```rust
        ///fn main(){
        ///    use doe::keyboard::key_press;
        ///    use doe::keyboard::key_release;
        ///    use doe::keyboard::listen_mouse_position;
        ///    use doe::keyboard::get_mouse_position;
        ///
        ///    use doe::keyboard::KeyCode;
        ///    key_press(KeyCode::COMMAND);
        ///    key_press(KeyCode::V);
        ///    key_release(KeyCode::V);
        ///}
        /// ```

        #[cfg(target_os = "macos")]
        pub fn key_release(keycode: u16) {
            use core_graphics::event::CGKeyCode;
            use core_graphics::event::{CGEvent, CGEventFlags, CGEventTapLocation};
            use core_graphics::event_source::CGEventSource;
            use core_graphics::event_source::CGEventSourceStateID;
            let state_id: CGEventSourceStateID = CGEventSourceStateID::HIDSystemState;
            let source: CGEventSource = CGEventSource::new(state_id).unwrap();
            let new_keycode: CGKeyCode = keycode;
            let event = CGEvent::new_keyboard_event(source, new_keycode, false).unwrap();
            event.set_flags(CGEventFlags::CGEventFlagCommand);
            event.post(CGEventTapLocation::HID);
        }
        /// must use cocoa implement
        /// 使用 Cocoa 实现的退出函数
        pub fn exit_if_click_esc() {
            // 导入所需的 Cocoa 模块和类型
            use cocoa::appkit::{NSApp, NSApplication, NSEvent, NSEventType};
            use cocoa::base::id;
        }
    }

    #[cfg(target_os = "windows")]
    pub mod windows {
        use crate::{keyboard::KeyCode, DebugPrint, Print, Sleep, Str};
        use std::sync::{atomic::AtomicU32, Arc, Mutex};

        ///exit_if_click_esc
        /// ```rust
        /// use std::thread;
        /// use doe::keyboard::exit_if_click_esc;
        /// let t1 = std::thread::spawn(move || {
        ///     loop {
        ///         println!("rust");
        ///     }
        /// });
        /// let t2 = std::thread::spawn(move || {
        ///     exit_if_click_esc();
        /// });
        /// t1.join().unwrap();
        /// t2.join().unwrap();
        /// ```

        pub fn exit_if_click_esc() {
            use std::sync::mpsc::channel;
            use std::sync::Arc;
            use std::thread;

            let (tx, rx) = channel();
            let t1 = thread::spawn(move || loop {
                if let Ok(r) = rx.recv() {
                    if r == 1 {
                        let _ = std::fs::remove_file("./.press_release_callback");
                        std::process::exit(0);
                    }
                }
            });

            let t2 = thread::spawn(move || {
                use crate::keyboard::listen_keyboard_callback;
                let _ = std::fs::remove_file("./.press_release_callback");

                listen_keyboard_callback(Arc::new(move |a| {
                    if a == "27,press" {
                        tx.send(1).unwrap();
                    }
                }));
            });

            t1.join().unwrap();
            t2.join().unwrap();
        }

        pub fn exit_if_click_esc_with_callback<F>(callback: std::sync::Arc<F>)
        where
            F: Fn() + std::marker::Sync + std::marker::Send + 'static,
        {
            use std::sync::mpsc::channel;
            use std::sync::Arc;
            use std::thread;

            let (tx, rx) = channel();
            let t1 = thread::spawn(move || loop {
                if let Ok(r) = rx.recv() {
                    if r == 1 {
                        callback();
                        let _ = std::fs::remove_file("./.press_release_callback");
                        std::process::exit(0);
                    }
                }
            });

            let t2 = thread::spawn(move || {
                use crate::keyboard::listen_keyboard_callback;
                listen_keyboard_callback(Arc::new(move |a| {
                    if a == "27,press" {
                        tx.send(1).unwrap();
                    }
                }));
            });

            t1.join().unwrap();
            t2.join().unwrap();
        }

        ///```rust
        ///use doe::keyboard::listen_keyboard_callback;
        ///listen_keyboard_callback(Arc::new( |a|{
        ///    println!("{}",a);
        ///}));
        /// ```

        pub fn listen_keyboard_callback<F>(press_callback: std::sync::Arc<F>)
        where
            F: Fn(String) + std::marker::Sync + std::marker::Send + 'static,
        {
            let t1 = std::thread::spawn(move || {
                use std::ptr;
                use winapi::shared::minwindef::{DWORD, LPARAM, LPVOID, WPARAM};
                use winapi::um::libloaderapi::{
                    FreeLibrary, FreeLibraryAndExitThread, GetModuleHandleW,
                };
                use winapi::um::processthreadsapi::CreateThread;
                use winapi::um::winuser::WM_QUIT;
                use winapi::um::winuser::{
                    CallNextHookEx, DispatchMessageW, GetMessageW, SetWindowsHookExW,
                    TranslateMessage, UnhookWindowsHookEx, KBDLLHOOKSTRUCT, MSG, WH_KEYBOARD_LL,
                };
                let _ = std::fs::remove_file("./.press_release_callback");
                unsafe extern "system" fn keyboard_hook_callback(
                    code: i32,
                    wparam: WPARAM,
                    lparam: LPARAM,
                ) -> LPARAM {
                    if code < 0 {
                        return CallNextHookEx(ptr::null_mut(), code, wparam, lparam);
                    }
                    use std::sync::atomic::Ordering;
                    let kbd_event = *(lparam as *const KBDLLHOOKSTRUCT);
                    let key_code = kbd_event.vkCode;
                    use std::fs::{File, OpenOptions};
                    use std::io::BufWriter;
                    use std::io::Write;
                    let file = OpenOptions::new()
                        .create(true)
                        .append(true)
                        .open("./.press_release_callback")
                        .unwrap();
                    let mut writer = BufWriter::new(file);

                    if wparam == 0x100 || wparam == 0x104 {
                        let new = key_code.to_string().push_back(",press").push_back("\n");
                        writer.write_all(new.as_bytes()).unwrap();
                    } else if wparam == 0x101 || wparam == 0x105 {
                        let new = key_code.to_string().push_back(",release").push_back("\n");
                        writer.write_all(new.as_bytes()).unwrap();
                    }

                    CallNextHookEx(ptr::null_mut(), code, wparam, lparam)
                }

                unsafe extern "system" fn keyboard_hook_thread(_: LPVOID) -> DWORD {
                    let h_instance = GetModuleHandleW(ptr::null_mut());

                    let hook = SetWindowsHookExW(
                        WH_KEYBOARD_LL,
                        Some(keyboard_hook_callback),
                        h_instance,
                        0,
                    );

                    let mut msg: MSG = std::mem::zeroed();
                    loop {
                        let ret = GetMessageW(&mut msg, ptr::null_mut(), 0, 0);
                        if ret == -1 || ret == 0 {
                            break;
                        }
                        if msg.message == WM_QUIT {
                            break;
                        }

                        TranslateMessage(&msg);

                        DispatchMessageW(&msg);
                    }

                    UnhookWindowsHookEx(hook);

                    FreeLibrary(h_instance);

                    0
                }
                unsafe {
                    let h_instance = GetModuleHandleW(ptr::null());
                    let mut thread_id: u32 = 0;
                    let thread_handle = CreateThread(
                        ptr::null_mut(),
                        0,
                        Some(keyboard_hook_thread),
                        h_instance as LPVOID,
                        0,
                        &mut thread_id as *mut _,
                    );

                    if thread_handle.is_null() {
                        panic!("Failed to create thread");
                    }

                    let mut msg = std::mem::zeroed();
                    while GetMessageW(&mut msg, ptr::null_mut(), 0, 0) != 0 {
                        if msg.message == WM_QUIT {
                            break;
                        }
                        TranslateMessage(&msg);

                        DispatchMessageW(&msg);
                    }

                    FreeLibraryAndExitThread(h_instance, 0);
                }
            });

            let t2 = std::thread::spawn(move || -> ! {
                use std::io::BufRead;
                use std::io::BufReader;
                loop {
                    let buf = if let Ok(file) = std::fs::File::open("./.press_release_callback") {
                        let reader = BufReader::new(file);
                        let buf = reader.lines().map(|s| s.unwrap()).collect::<Vec<_>>();
                        buf
                    } else {
                        Vec::new()
                    };
                    ().sleep(0.1);
                    let new_buf = if let Ok(file) = std::fs::File::open("./.press_release_callback")
                    {
                        let reader = BufReader::new(file);
                        let buf = reader.lines().map(|s| s.unwrap()).collect::<Vec<_>>();
                        buf
                    } else {
                        Vec::new()
                    };
                    if new_buf != buf {
                        if let Some(last) = new_buf.last() {
                            press_callback(last.to_string());
                        }
                    }
                }
            });

            t1.join().unwrap();
            t2.join();
        }

        pub fn listen_keybord_append_to_file() {
            use std::ptr;
            use winapi::shared::minwindef::{DWORD, LPARAM, LPVOID, WPARAM};
            use winapi::um::libloaderapi::{
                FreeLibrary, FreeLibraryAndExitThread, GetModuleHandleW,
            };
            use winapi::um::processthreadsapi::CreateThread;
            use winapi::um::winuser::WM_QUIT;
            use winapi::um::winuser::{
                CallNextHookEx, DispatchMessageW, GetMessageW, SetWindowsHookExW, TranslateMessage,
                UnhookWindowsHookEx, KBDLLHOOKSTRUCT, MSG, WH_KEYBOARD_LL,
            };

            unsafe extern "system" fn keyboard_hook_callback(
                code: i32,
                wparam: WPARAM,
                lparam: LPARAM,
            ) -> LPARAM {
                if code < 0 {
                    return CallNextHookEx(ptr::null_mut(), code, wparam, lparam);
                }

                let kbd_event = *(lparam as *const KBDLLHOOKSTRUCT);
                if wparam == 0x100 || wparam == 0x104 {
                    let file_path = "listen_all.bin";
                    if let Ok(_) = crate::append_data_to_file(
                        file_path,
                        format!("key_press({});\n", kbd_event.vkCode),
                    ) {}
                } else if wparam == 0x101 || wparam == 0x105 {
                    let file_path = "listen_all.bin";
                    if let Ok(_) = crate::append_data_to_file(
                        file_path,
                        format!("key_release({});\n", kbd_event.vkCode),
                    ) {}
                }

                CallNextHookEx(ptr::null_mut(), code, wparam, lparam)
            }

            unsafe extern "system" fn keyboard_hook_thread(_: LPVOID) -> DWORD {
                let h_instance = GetModuleHandleW(ptr::null_mut());

                let hook =
                    SetWindowsHookExW(WH_KEYBOARD_LL, Some(keyboard_hook_callback), h_instance, 0);

                let mut msg: MSG = std::mem::zeroed();
                loop {
                    let ret = GetMessageW(&mut msg, ptr::null_mut(), 0, 0);
                    if ret == -1 || ret == 0 {
                        break;
                    }
                    if msg.message == WM_QUIT {
                        break;
                    }
                    TranslateMessage(&msg);
                    DispatchMessageW(&msg);
                }

                UnhookWindowsHookEx(hook);

                FreeLibrary(h_instance);

                0
            }
            unsafe {
                let h_instance = GetModuleHandleW(ptr::null());
                let mut thread_id: u32 = 0;
                let thread_handle = CreateThread(
                    ptr::null_mut(),
                    0,
                    Some(keyboard_hook_thread),
                    h_instance as LPVOID,
                    0,
                    &mut thread_id as *mut _,
                );

                if thread_handle.is_null() {
                    panic!("Failed to create thread");
                }

                let mut msg = std::mem::zeroed();
                while GetMessageW(&mut msg, ptr::null_mut(), 0, 0) != 0 {
                    if msg.message == WM_QUIT {
                        break;
                    }
                    TranslateMessage(&msg);
                    DispatchMessageW(&msg);
                }

                FreeLibraryAndExitThread(h_instance, 0);
            }
        }

        pub fn listen_keybord() {
            let call = || {};
            use std::ptr;
            use winapi::shared::minwindef::{DWORD, LPARAM, LPVOID, WPARAM};
            use winapi::um::libloaderapi::{
                FreeLibrary, FreeLibraryAndExitThread, GetModuleHandleW,
            };
            use winapi::um::processthreadsapi::CreateThread;
            use winapi::um::winuser::WM_QUIT;
            use winapi::um::winuser::{
                CallNextHookEx, DispatchMessageW, GetMessageW, SetWindowsHookExW, TranslateMessage,
                UnhookWindowsHookEx, KBDLLHOOKSTRUCT, MSG, WH_KEYBOARD_LL,
            };

            unsafe extern "system" fn keyboard_hook_callback(
                code: i32,
                wparam: WPARAM,
                lparam: LPARAM,
            ) -> LPARAM {
                if code < 0 {
                    return CallNextHookEx(ptr::null_mut(), code, wparam, lparam);
                }

                let kbd_event = *(lparam as *const KBDLLHOOKSTRUCT);

                if wparam == 0x100 || wparam == 0x104 {
                    println!("key_press({});", kbd_event.vkCode);
                } else if wparam == 0x101 || wparam == 0x105 {
                    println!("key_release({});", kbd_event.vkCode);
                }

                CallNextHookEx(ptr::null_mut(), code, wparam, lparam)
            }

            unsafe extern "system" fn keyboard_hook_thread(_: LPVOID) -> DWORD {
                let h_instance = GetModuleHandleW(ptr::null_mut());

                let hook =
                    SetWindowsHookExW(WH_KEYBOARD_LL, Some(keyboard_hook_callback), h_instance, 0);

                let mut msg: MSG = std::mem::zeroed();
                loop {
                    let ret = GetMessageW(&mut msg, ptr::null_mut(), 0, 0);
                    if ret == -1 || ret == 0 {
                        break;
                    }
                    if msg.message == WM_QUIT {
                        break;
                    }
                    TranslateMessage(&msg);
                    DispatchMessageW(&msg);
                }

                UnhookWindowsHookEx(hook);

                FreeLibrary(h_instance);

                0
            }
            unsafe {
                let h_instance = GetModuleHandleW(ptr::null());
                let mut thread_id: u32 = 0;
                let thread_handle = CreateThread(
                    ptr::null_mut(),
                    0,
                    Some(keyboard_hook_thread),
                    h_instance as LPVOID,
                    0,
                    &mut thread_id as *mut _,
                );

                if thread_handle.is_null() {
                    panic!("Failed to create thread");
                }

                let mut msg = std::mem::zeroed();
                while GetMessageW(&mut msg, ptr::null_mut(), 0, 0) != 0 {
                    if msg.message == WM_QUIT {
                        break;
                    }
                    TranslateMessage(&msg);
                    DispatchMessageW(&msg);
                }

                FreeLibraryAndExitThread(h_instance, 0);
            }
        }

        pub fn key_release_keybd_event(keycode: u16) {
            use winapi::um::winuser::keybd_event;

            unsafe {
                keybd_event(keycode as u8, 0, 0x2, 0);
            }
        }
        pub fn key_press_by_keybd_event(keycode: u16) {
            use winapi::um::winuser::keybd_event;
            use winapi::um::winuser::mouse_event;

            unsafe {
                keybd_event(keycode as u8, 0, 0, 0);
            }
        }
        pub fn key_release(keycode: u16) {
            use winapi::shared::minwindef::DWORD;
            use winapi::um::winuser::keybd_event;
            use winapi::um::winuser::{SendInput, INPUT, INPUT_KEYBOARD};
            pub const KEYEVENTF_KEYUP: DWORD = 0x0002;
            unsafe {
                let mut input = INPUT::default();
                input.type_ = INPUT_KEYBOARD;
                input.u.ki_mut().wVk = keycode as _;
                input.u.ki_mut().dwFlags = KEYEVENTF_KEYUP;
                // Simulate key press
                let usent = SendInput(
                    1,                    // Number of inputs
                    &mut input as *mut _, // Pointer to the input array
                    std::mem::size_of::<INPUT>() as i32,
                );
                if usent != 1 {
                    println!("send error");
                }
            }
        }
        ///```ignore
        /// "/"=>{Self::SIGN_DIV},
        /// "."=>{Self::SIGN_DOT},
        /// "-"=>{Self::SIGN_SUB},
        /// "+"=>{Self::SIGN_ADD},
        /// "*"=>{Self::SIGN_MUL},
        /// "a"=>{Self::A},
        /// "b"=>{Self::B},
        /// "c"=>{Self::C},
        /// "d"=>{Self::D},
        /// "e"=>{Self::E},
        /// "f"=>{Self::F},
        /// "g"=>{Self::G},
        /// "h"=>{Self::H},
        /// "i"=>{Self::I},
        /// "j"=>{Self::J},
        /// "k"=>{Self::K},
        /// "l"=>{Self::L},
        /// "m"=>{Self::M},
        /// "n"=>{Self::N},
        /// "o"=>{Self::O},
        /// "p"=>{Self::P},
        /// "q"=>{Self::Q},
        /// "r"=>{Self::R},
        /// "s"=>{Self::S},
        /// "t"=>{Self::T},
        /// "u"=>{Self::U},
        /// "v"=>{Self::V},
        /// "w"=>{Self::W},
        /// "x"=>{Self::X},
        /// "y"=>{Self::Y},
        /// "z"=>{Self::Z},
        /// "0"=>{Self::NUM_0},
        /// "1"=>{Self::NUM_1},
        /// "2"=>{Self::NUM_2},
        /// "3"=>{Self::NUM_3},
        /// "4"=>{Self::NUM_4},
        /// "5"=>{Self::NUM_5},
        /// "6"=>{Self::NUM_6},
        /// "7"=>{Self::NUM_7},
        /// "8"=>{Self::NUM_8},
        /// "9"=>{Self::NUM_9},
        /// "f1"=>{Self::F1},
        /// "f2"=>{Self::F2},
        /// "f3"=>{Self::F3},
        /// "f4"=>{Self::F4},
        /// "f5"=>{Self::F5},
        /// "f6"=>{Self::F6},
        /// "f7"=>{Self::F7},
        /// "f8"=>{Self::F8},
        /// "f9"=>{Self::F9},
        /// "f10"=>{Self::F10},
        /// "f11"=>{Self::F11},
        /// "f12"=>{Self::F12},
        /// "enter"=>{Self::ENTER},
        /// "end"=>{Self::END},
        /// "home"=>{Self::HOME},
        /// "left_arrow"=>{Self::LEFT_ARROW},
        /// "up_arrow"=>{Self::UP_ARROW},
        /// "right_arrow"=>{Self::RIGHT_ARROW},
        /// "down_arrow"=>{Self::DOWN_ARROW},
        /// "insert"=>{Self::INSERT},
        /// "detele"=>{Self::DELETE},
        /// "help"=>{Self::HELP},
        /// "num_lock"=>{Self::NUM_LOCK},
        /// "backspace"=>{Self::BACKSPACE},
        /// "tab"=>{Self::TAB},
        /// "clear"=>{Self::CLEAR},
        /// "shift"=>{Self::SHIFT},
        /// "ctrl"=>{Self::CONTROL},
        /// "alt"=>{Self::ALT},
        /// "caps_lock"=>{Self::CAPS_LOCK},
        /// "esc"=>{Self::ESC},
        /// "spacebar"=>{Self::SPACEBAR},
        /// "page_up"=>{Self::PAGE_UP},
        /// "page_down"=>{Self::PAGE_DOWN},
        /// "windows"=>Self::WINDOWS,
        ///```
        /// # key_click
        ///```ignore
        /// use doe::keyboard::key_click;
        /// use doe::mouse::move_to_press_left;
        /// use doe::*;
        /// move_to_press_left(726, 348).sleep(0.1);
        /// key_click("ctrl+a");
        /// key_click("ctrl+c");
        /// key_click("2027 ctrl+a");
        /// key_click("ctrl+shift+p");
        /// ```
        pub fn key_click(key: &str) {
            let key_vec = key.split_to_vec(" ");
            let keycode = KeyCode::default();
            for key in key_vec.iter() {
                if key == "+" {
                    let keycode = keycode.string_to_keycode(key.to_string());
                    key_press(keycode);
                    key_release(keycode);
                } else if key.contains("+") {
                    for key in key.split_to_vec("+") {
                        let keycode = keycode.string_to_keycode(key.to_string());
                        key_press(keycode);
                    }
                    for key in key.split_to_vec("+") {
                        let keycode = keycode.string_to_keycode(key.to_string());
                        key_release(keycode);
                    }
                } else {
                    // if key code is 0
                    if keycode.string_to_keycode(key.to_string()) == 0 {
                        for key in key.chars() {
                            let keycode = keycode.string_to_keycode(key.to_string());
                            key_press(keycode);
                            key_release(keycode);
                        }
                    } else {
                        // if key code is not 0
                        let keycode = keycode.string_to_keycode(key.to_string());
                        key_press(keycode);
                        key_release(keycode);
                    }
                }
            }
        }

        pub fn key_press(keycode: u16) {
            use winapi::shared::minwindef::DWORD;
            use winapi::um::winuser::keybd_event;
            use winapi::um::winuser::{SendInput, INPUT, INPUT_KEYBOARD};
            pub const KEYEVENTF_KEYUP: DWORD = 0x0002;
            unsafe {
                let mut input = INPUT::default();
                input.type_ = INPUT_KEYBOARD;
                input.u.ki_mut().wVk = keycode as _;
                input.u.ki_mut().dwFlags = 0; // Press the key

                // Simulate key press
                let usent = SendInput(
                    1,                    // Number of inputs
                    &mut input as *mut _, // Pointer to the input array
                    std::mem::size_of::<INPUT>() as i32,
                );
                if usent != 1 {
                    println!("send error");
                }
            }
        }
    }

    pub use common::*;

    #[cfg(target_os = "linux")]
    pub use linux::*;

    #[cfg(target_os = "macos")]
    pub use macos::*;

    #[cfg(target_os = "windows")]
    pub use windows::*;
}

#[cfg(feature = "keyboard")]
pub use keyboard::*;

///KeyCode struct is struct that contains a set of constants representing keyboard keys on a `Windows` operating system. Each constant is represented by a u16 value, which is the Unicode code point of the key.
#[allow(warnings)]
#[cfg(target_os = "windows")]
#[derive(Debug, Default)]
pub struct KeyCode;
#[cfg(target_os = "windows")]
impl KeyCode {
    /// a
    pub const A: u16 = 65;
    /// b
    pub const B: u16 = 66;
    /// c
    pub const C: u16 = 67;
    /// d
    pub const D: u16 = 68;
    /// e
    pub const E: u16 = 69;
    ///
    pub const F: u16 = 70;
    ///
    pub const G: u16 = 71;
    ///
    pub const H: u16 = 72;
    ///
    pub const I: u16 = 73;
    ///
    pub const J: u16 = 74;
    ///
    pub const K: u16 = 75;
    ///
    pub const L: u16 = 76;
    ///
    pub const M: u16 = 77;
    ///
    pub const N: u16 = 78;
    ///
    pub const O: u16 = 79;
    ///
    pub const P: u16 = 80;
    ///
    pub const Q: u16 = 81;
    ///
    pub const R: u16 = 82;
    ///
    pub const S: u16 = 83;
    ///
    pub const T: u16 = 84;
    ///
    pub const U: u16 = 85;
    ///
    pub const V: u16 = 86;
    ///
    pub const W: u16 = 87;
    ///
    pub const X: u16 = 88;
    ///
    pub const Y: u16 = 89;
    ///
    pub const Z: u16 = 90;
    ///
    pub const NUM_0: u16 = 48;
    ///
    pub const NUM_1: u16 = 49;
    ///
    pub const NUM_2: u16 = 50;
    ///
    pub const NUM_3: u16 = 51;
    ///
    pub const NUM_4: u16 = 52;
    ///
    pub const NUM_5: u16 = 53;
    ///
    pub const NUM_6: u16 = 54;
    ///
    pub const NUM_7: u16 = 55;
    ///
    pub const NUM_8: u16 = 56;
    ///
    pub const NUM_9: u16 = 57;
    ///
    pub const F1: u16 = 112;
    ///
    pub const F2: u16 = 113;
    ///
    pub const F3: u16 = 114;
    ///
    pub const F4: u16 = 115;
    ///
    pub const F5: u16 = 116;
    ///
    pub const F6: u16 = 117;
    ///
    pub const F7: u16 = 118;
    ///
    pub const F8: u16 = 119;
    ///
    pub const F9: u16 = 120;
    ///
    pub const F10: u16 = 121;
    ///
    pub const F11: u16 = 122;
    ///
    pub const F12: u16 = 123;
    ///
    pub const ENTER: u16 = 10;
    ///
    pub const END: u16 = 35;
    ///
    pub const HOME: u16 = 36;
    ///
    pub const LEFT_ARROW: u16 = 37;
    ///
    pub const UP_ARROW: u16 = 38;
    ///
    pub const RIGHT_ARROW: u16 = 39;
    ///
    pub const DOWN_ARROW: u16 = 40;
    ///
    pub const INSERT: u16 = 45;
    ///
    pub const DELETE: u16 = 46;
    ///
    pub const HELP: u16 = 47;
    ///
    pub const NUM_LOCK: u16 = 14;
    ///
    pub const BACKSPACE: u16 = 8;
    ///
    pub const TAB: u16 = 9;
    ///
    pub const CLEAR: u16 = 12;
    ///
    pub const SHIFT: u16 = 16;
    ///
    pub const CONTROL: u16 = 17;
    ///
    pub const ALT: u16 = 18;
    ///
    pub const CAPS_LOCK: u16 = 20;
    ///
    pub const ESC: u16 = 27;
    ///
    pub const SPACEBAR: u16 = 32;
    ///
    pub const PAGE_UP: u16 = 33;
    ///
    pub const PAGE_DOWN: u16 = 3;
    /// *
    pub const SIGN_MUL: u16 = 106; //*
    /// +
    pub const SIGN_ADD: u16 = 107; //+
    /// -
    pub const SIGN_SUB: u16 = 109; //-
    /// .
    pub const SIGN_DOT: u16 = 110; //.
    /// /
    pub const SIGN_DIV: u16 = 111; // \/
    /// WINDOWS
    pub const WINDOWS: u16 = 0x5B;
    #[allow(warnings)]
    fn string_to_keycode(&self, s: String) -> u16 {
        match s.as_str().as_ref() {
            "/" => Self::SIGN_DIV,
            "." => Self::SIGN_DOT,
            "-" => Self::SIGN_SUB,
            "+" => Self::SIGN_ADD,
            "*" => Self::SIGN_MUL,
            "a" => Self::A,
            "b" => Self::B,
            "c" => Self::C,
            "d" => Self::D,
            "e" => Self::E,
            "f" => Self::F,
            "g" => Self::G,
            "h" => Self::H,
            "i" => Self::I,
            "j" => Self::J,
            "k" => Self::K,
            "l" => Self::L,
            "m" => Self::M,
            "n" => Self::N,
            "o" => Self::O,
            "p" => Self::P,
            "q" => Self::Q,
            "r" => Self::R,
            "s" => Self::S,
            "t" => Self::T,
            "u" => Self::U,
            "v" => Self::V,
            "w" => Self::W,
            "x" => Self::X,
            "y" => Self::Y,
            "z" => Self::Z,
            "0" => Self::NUM_0,
            "1" => Self::NUM_1,
            "2" => Self::NUM_2,
            "3" => Self::NUM_3,
            "4" => Self::NUM_4,
            "5" => Self::NUM_5,
            "6" => Self::NUM_6,
            "7" => Self::NUM_7,
            "8" => Self::NUM_8,
            "9" => Self::NUM_9,
            "f1" => Self::F1,
            "f2" => Self::F2,
            "f3" => Self::F3,
            "f4" => Self::F4,
            "f5" => Self::F5,
            "f6" => Self::F6,
            "f7" => Self::F7,
            "f8" => Self::F8,
            "f9" => Self::F9,
            "f10" => Self::F10,
            "f11" => Self::F11,
            "f12" => Self::F12,
            "enter" => Self::ENTER,
            "end" => Self::END,
            "home" => Self::HOME,
            "left_arrow" => Self::LEFT_ARROW,
            "up_arrow" => Self::UP_ARROW,
            "right_arrow" => Self::RIGHT_ARROW,
            "down_arrow" => Self::DOWN_ARROW,
            "insert" => Self::INSERT,
            "detele" => Self::DELETE,
            "help" => Self::HELP,
            "num_lock" => Self::NUM_LOCK,
            "backspace" => Self::BACKSPACE,
            "tab" => Self::TAB,
            "clear" => Self::CLEAR,
            "shift" => Self::SHIFT,
            "ctrl" => Self::CONTROL,
            "alt" => Self::ALT,
            "caps_lock" => Self::CAPS_LOCK,
            "esc" => Self::ESC,
            "spacebar" => Self::SPACEBAR,
            "page_up" => Self::PAGE_UP,
            "page_down" => Self::PAGE_DOWN,
            "windows" => Self::WINDOWS,
            _ => 0,
        }
    }
}

///KeyCode struct is struct that contains a set of constants representing keyboard keys on a `macos` operating system. Each constant is represented by a u16 value, which is the Unicode code point of the key.
#[allow(warnings)]
#[cfg(target_os = "macos")]
#[derive(Debug, Default)]
pub struct KeyCode;
#[allow(warnings)]
#[cfg(target_os = "macos")]
impl KeyCode {
    pub const SIGN_MUL: u16 = 0x6A; //*
    pub const SIGN_ADD: u16 = 0x6B; //+
    pub const SIGN_SUB: u16 = 0x2D; //+
    pub const SIGN_DOT: u16 = 0x2E; //.
    pub const SIGN_DIV: u16 = 0x2F; // \/
    pub const LeftBracket: u16 = 0x2B;
    pub const RightBracket: u16 = 0x30;
    pub const RETURN: u16 = 0x24;
    pub const TAB: u16 = 0x30;
    pub const SPACE: u16 = 0x31;
    pub const DELETE: u16 = 0x33;
    pub const ESC: u16 = 0x35;
    pub const COMMAND: u16 = 0x37;
    pub const SHIFT: u16 = 0x38;
    pub const CAPS_LOCK: u16 = 0x39;
    pub const OPTION: u16 = 0x3A;
    pub const CONTROL: u16 = 0x3B;
    pub const RIGHT_COMMAND: u16 = 0x36;
    pub const RIGHT_SHIFT: u16 = 0x3C;
    pub const RIGHT_OPTION: u16 = 0x3D;
    pub const RIGHT_CONTROL: u16 = 0x3E;
    pub const FUNCTION: u16 = 0x3F;
    pub const VOLUME_UP: u16 = 0x48;
    pub const VOLUME_DOWN: u16 = 0x49;
    pub const MUTE: u16 = 0x4A;
    pub const F1: u16 = 0x7A;
    pub const F2: u16 = 0x78;
    pub const F3: u16 = 0x63;
    pub const F4: u16 = 0x76;
    pub const F5: u16 = 0x60;
    pub const F6: u16 = 0x61;
    pub const F7: u16 = 0x62;
    pub const F8: u16 = 0x64;
    pub const F9: u16 = 0x65;
    pub const F10: u16 = 0x6D;
    pub const F11: u16 = 0x67;
    pub const F12: u16 = 0x6F;
    pub const F13: u16 = 0x69;
    pub const F14: u16 = 0x6B;
    pub const F15: u16 = 0x71;
    pub const F16: u16 = 0x6A;
    pub const F17: u16 = 0x40;
    pub const F18: u16 = 0x4F;
    pub const F19: u16 = 0x50;
    pub const F20: u16 = 0x5A;
    pub const HELP: u16 = 0x72;
    pub const HOME: u16 = 0x73;
    pub const PAGE_UP: u16 = 0x74;
    pub const FORWARD_DELETE: u16 = 0x75;
    pub const END: u16 = 0x77;
    pub const PAGE_DOWN: u16 = 0x79;
    pub const LEFT_ARROW: u16 = 0x7B;
    pub const RIGHT_ARROW: u16 = 0x7C;
    pub const DOWN_ARROW: u16 = 0x7D;
    pub const UP_ARROW: u16 = 0x7E;

    // 字母 A-Z
    pub const A: u16 = 0x00;
    pub const B: u16 = 0x0B;
    pub const C: u16 = 0x08;
    pub const D: u16 = 0x02;
    pub const E: u16 = 0x0E;
    pub const F: u16 = 0x03;
    pub const G: u16 = 0x05;
    pub const H: u16 = 0x04;
    pub const I: u16 = 0x22;
    pub const J: u16 = 0x26;
    pub const K: u16 = 0x28;
    pub const L: u16 = 0x25;
    pub const M: u16 = 0x2E;
    pub const N: u16 = 0x2D;
    pub const O: u16 = 0x1F;
    pub const P: u16 = 0x23;
    pub const Q: u16 = 0x0C;
    pub const R: u16 = 0x0F;
    pub const S: u16 = 0x01;
    pub const T: u16 = 0x11;
    pub const U: u16 = 0x20;
    pub const V: u16 = 0x09;
    pub const W: u16 = 0x0D;
    pub const X: u16 = 0x07;
    pub const Y: u16 = 0x10;
    pub const Z: u16 = 0x06;

    // 数字 0-9
    pub const NUM_0: u16 = 0x1D;
    pub const NUM_1: u16 = 0x12;
    pub const NUM_2: u16 = 0x13;
    pub const NUM_3: u16 = 0x14;
    pub const NUM_4: u16 = 0x15;
    pub const NUM_5: u16 = 0x17;
    pub const NUM_6: u16 = 0x16;
    pub const NUM_7: u16 = 0x1A;
    pub const NUM_8: u16 = 0x1C;
    pub const NUM_9: u16 = 0x19;

    #[allow(warnings)]
    fn string_to_keycode(&self, s: String) -> u16 {
        match s.as_str().as_ref() {
            "a" => Self::A,
            "b" => Self::B,
            "c" => Self::C,
            "d" => Self::D,
            "e" => Self::E,
            "f" => Self::F,
            "g" => Self::G,
            "h" => Self::H,
            "i" => Self::I,
            "j" => Self::J,
            "k" => Self::K,
            "l" => Self::L,
            "m" => Self::M,
            "n" => Self::N,
            "o" => Self::O,
            "p" => Self::P,
            "q" => Self::Q,
            "r" => Self::R,
            "s" => Self::S,
            "t" => Self::T,
            "u" => Self::U,
            "v" => Self::V,
            "w" => Self::W,
            "x" => Self::X,
            "y" => Self::Y,
            "z" => Self::Z,
            "0" => Self::NUM_0,
            "1" => Self::NUM_1,
            "2" => Self::NUM_2,
            "3" => Self::NUM_3,
            "4" => Self::NUM_4,
            "5" => Self::NUM_5,
            "6" => Self::NUM_6,
            "7" => Self::NUM_7,
            "8" => Self::NUM_8,
            "9" => Self::NUM_9,
            "f1" => Self::F1,
            "f2" => Self::F2,
            "f3" => Self::F3,
            "f4" => Self::F4,
            "f5" => Self::F5,
            "f6" => Self::F6,
            "f7" => Self::F7,
            "f8" => Self::F8,
            "f9" => Self::F9,
            "f10" => Self::F10,
            "f11" => Self::F11,
            "f12" => Self::F12,
            "f13" => Self::F13,
            "f14" => Self::F14,
            "f15" => Self::F15,
            "f16" => Self::F16,
            "f17" => Self::F17,
            "f18" => Self::F18,
            "f19" => Self::F19,
            "20" => Self::F20,
            "help" => Self::HELP,
            "home" => Self::HOME,
            "page_up" => Self::PAGE_UP,
            "forward_delete" => Self::FORWARD_DELETE,
            "end" => Self::END,
            "page_down" => Self::PAGE_DOWN,
            "left_arrow" => Self::LEFT_ARROW,
            "right_arrow" => Self::RIGHT_ARROW,
            "down_arrow" => Self::DOWN_ARROW,
            "up_arrow" => Self::UP_ARROW,
            "*" => Self::SIGN_MUL,
            "+" => Self::SIGN_ADD,
            "-" => Self::SIGN_SUB,
            "." => Self::SIGN_DOT,
            "/" => Self::SIGN_DIV,
            "{" => Self::LeftBracket,
            "}" => Self::LeftBracket,
            "enter" => Self::RETURN,
            "tab" => Self::TAB,
            "space" => Self::SPACE,
            "delete" => Self::DELETE,
            "esc" => Self::ESC,
            "command" => Self::COMMAND,
            "shift" => Self::SHIFT,
            "caps_lock" => Self::CAPS_LOCK,
            "option" => Self::OPTION,
            "ctrl" => Self::CONTROL,
            "right_command" => Self::RIGHT_COMMAND,
            "right_shift" => Self::RIGHT_SHIFT,
            "right_option" => Self::RIGHT_OPTION,
            "right_control" => Self::RIGHT_CONTROL,
            "function" => Self::FUNCTION,
            "volume_up" => Self::VOLUME_UP,
            "volume_down" => Self::VOLUME_DOWN,
            "mute" => Self::MUTE,
            _ => 0,
        }
    }
}

///KeyCode struct is struct that contains a set of constants representing keyboard keys on a `linux` operating system. Each constant is represented by a u16 value, which is the Unicode code point of the key.
#[allow(warnings)]
#[cfg(target_os = "linux")]
#[derive(Debug)]
pub struct KeyCode;
#[allow(warnings)]
#[cfg(target_os = "linux")]
impl KeyCode {
    pub const RETURN: u16 = 0x24;
    pub const TAB: u16 = 0x30;
    pub const SPACE: u16 = 0x31;
    pub const DELETE: u16 = 0x33;
    pub const ESCAPE: u16 = 0x35;
    pub const COMMAND: u16 = 0x37;
    pub const SHIFT: u16 = 0x38;
    pub const CAPS_LOCK: u16 = 0x39;
    pub const OPTION: u16 = 0x3A;
    pub const CONTROL: u16 = 0x3B;
    pub const RIGHT_COMMAND: u16 = 0x36;
    pub const RIGHT_SHIFT: u16 = 0x3C;
    pub const RIGHT_OPTION: u16 = 0x3D;
    pub const RIGHT_CONTROL: u16 = 0x3E;
    pub const FUNCTION: u16 = 0x3F;
    pub const VOLUME_UP: u16 = 0x48;
    pub const VOLUME_DOWN: u16 = 0x49;
    pub const MUTE: u16 = 0x4A;
    pub const F1: u16 = 0x7A;
    pub const F2: u16 = 0x78;
    pub const F3: u16 = 0x63;
    pub const F4: u16 = 0x76;
    pub const F5: u16 = 0x60;
    pub const F6: u16 = 0x61;
    pub const F7: u16 = 0x62;
    pub const F8: u16 = 0x64;
    pub const F9: u16 = 0x65;
    pub const F10: u16 = 0x6D;
    pub const F11: u16 = 0x67;
    pub const F12: u16 = 0x6F;
    pub const F13: u16 = 0x69;
    pub const F14: u16 = 0x6B;
    pub const F15: u16 = 0x71;
    pub const F16: u16 = 0x6A;
    pub const F17: u16 = 0x40;
    pub const F18: u16 = 0x4F;
    pub const F19: u16 = 0x50;
    pub const F20: u16 = 0x5A;
    pub const HELP: u16 = 0x72;
    pub const HOME: u16 = 0x73;
    pub const PAGE_UP: u16 = 0x74;
    pub const FORWARD_DELETE: u16 = 0x75;
    pub const END: u16 = 0x77;
    pub const PAGE_DOWN: u16 = 0x79;
    pub const LEFT_ARROW: u16 = 0x7B;
    pub const RIGHT_ARROW: u16 = 0x7C;
    pub const DOWN_ARROW: u16 = 0x7D;
    pub const UP_ARROW: u16 = 0x7E;

    // 字母 A-Z
    pub const A: u16 = 0x00;
    pub const B: u16 = 0x0B;
    pub const C: u16 = 0x08;
    pub const D: u16 = 0x02;
    pub const E: u16 = 0x0E;
    pub const F: u16 = 0x03;
    pub const G: u16 = 0x05;
    pub const H: u16 = 0x04;
    pub const I: u16 = 0x22;
    pub const J: u16 = 0x26;
    pub const K: u16 = 0x28;
    pub const L: u16 = 0x25;
    pub const M: u16 = 0x2E;
    pub const N: u16 = 0x2D;
    pub const O: u16 = 0x1F;
    pub const P: u16 = 0x23;
    pub const Q: u16 = 0x0C;
    pub const R: u16 = 0x0F;
    pub const S: u16 = 0x01;
    pub const T: u16 = 0x11;
    pub const U: u16 = 0x20;
    pub const V: u16 = 0x09;
    pub const W: u16 = 0x0D;
    pub const X: u16 = 0x07;
    pub const Y: u16 = 0x10;
    pub const Z: u16 = 0x06;

    // 数字 0-9
    pub const NUM_0: u16 = 0x1D;
    pub const NUM_1: u16 = 0x12;
    pub const NUM_2: u16 = 0x13;
    pub const NUM_3: u16 = 0x14;
    pub const NUM_4: u16 = 0x15;
    pub const NUM_5: u16 = 0x17;
    pub const NUM_6: u16 = 0x16;
    pub const NUM_7: u16 = 0x1A;
    pub const NUM_8: u16 = 0x1C;
    pub const NUM_9: u16 = 0x19;
}
