diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 40cf129d..7aed4880 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM zmkfirmware/zmk-dev-arm:2.5 +FROM docker.io/zmkfirmware/zmk-dev-arm:2.5 COPY .bashrc tmp RUN mv /tmp/.bashrc ~/.bashrc diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..7443c24d --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,11 @@ + +## Board/Shield Check-list + - [ ] This board/shield is tested working on real hardware + - [ ] Definitions follow the general style of other shields/boards upstream ([Reference](https://zmk.dev/docs/development/new-shield)) + - [ ] `.zmk.yml` metadata file added + - [ ] Proper Copyright + License headers added to applicable files (Generally, we stick to "The ZMK Contributors" for copyrights to help avoid churn when files get edited) + - [ ] General consistent formatting of DeviceTree files + - [ ] Keymaps do not use deprecated key defines (Check using the [upgrader tool](https://zmk.dev/docs/codes/keymap-upgrader)) + - [ ] `&pro_micro` used in favor of `&pro_micro_d/a` if applicable + - [ ] If split, no name added for the right/peripheral half + - [ ] `.conf` file has optional extra features commented out diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 36bca31d..b790b665 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,7 +14,7 @@ jobs: build: runs-on: ubuntu-latest container: - image: zmkfirmware/zmk-build-arm:2.5 + image: docker.io/zmkfirmware/zmk-build-arm:2.5 strategy: matrix: board: diff --git a/.github/workflows/clang-format-lint.yml b/.github/workflows/clang-format-lint.yml index e9b3e077..375bcd4e 100644 --- a/.github/workflows/clang-format-lint.yml +++ b/.github/workflows/clang-format-lint.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: DoozyX/clang-format-lint-action@v0.12 + - uses: DoozyX/clang-format-lint-action@v0.13 with: source: "./app" extensions: "h,c" diff --git a/.github/workflows/hardware-metadata-validation.yml b/.github/workflows/hardware-metadata-validation.yml index 1318b4bd..5c2fd375 100644 --- a/.github/workflows/hardware-metadata-validation.yml +++ b/.github/workflows/hardware-metadata-validation.yml @@ -29,7 +29,7 @@ jobs: validate-metadata: runs-on: ubuntu-latest container: - image: zmkfirmware/zmk-dev-arm:2.5 + image: docker.io/zmkfirmware/zmk-dev-arm:2.5 steps: - uses: actions/checkout@v2 - name: Install dependencies diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1f8e443a..e8cdcedf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,7 +16,7 @@ jobs: integration_test: runs-on: ubuntu-latest container: - image: zmkfirmware/zmk-build-arm:2.5 + image: docker.io/zmkfirmware/zmk-build-arm:2.5 steps: - name: Checkout uses: actions/checkout@v2 diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 5092deff..9c7befec 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -57,6 +57,7 @@ if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL) target_sources(app PRIVATE src/behaviors/behavior_sensor_rotate_key_press.c) target_sources_ifdef(CONFIG_ZMK_EXT_POWER app PRIVATE src/behaviors/behavior_ext_power.c) target_sources(app PRIVATE src/combo.c) + target_sources(app PRIVATE src/conditional_layer.c) target_sources(app PRIVATE src/keymap.c) endif() target_sources_ifdef(CONFIG_ZMK_RGB_UNDERGLOW app PRIVATE src/behaviors/behavior_rgb_underglow.c) diff --git a/app/Kconfig b/app/Kconfig index f23930b4..3502c652 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -25,7 +25,57 @@ config USB_DEVICE_PID config USB_DEVICE_MANUFACTURER default "ZMK Project" -menu "HID Output Types" +menu "HID" + +choice ZMK_HID_REPORT_TYPE + prompt "HID Report Type" + +config ZMK_HID_REPORT_TYPE_HKRO + bool "#-Key Roll Over (HKRO) HID Report" + help + Enable # key roll over for HID report. This selection is "boot keyboard" compatible + but limits the total number of possible keys to report as held to #. + +config ZMK_HID_REPORT_TYPE_NKRO + bool "Full N-Key Roll Over (NKRO) HID Report" + help + Enable full N-Key Roll Over for HID output. This selection will prevent the keyboard + from working with some BIOS/UEFI versions that only support "boot keyboard" support. + This option also prevents using some infrequently used higher range HID usages. + +endchoice + +if ZMK_HID_REPORT_TYPE_HKRO + +config ZMK_HID_KEYBOARD_REPORT_SIZE + int "# Keyboard Keys Reportable" + default 6 + +endif + +config ZMK_HID_CONSUMER_REPORT_SIZE + int "# Consumer Keys Reportable" + default 6 + + +choice ZMK_HID_CONSUMER_REPORT_USAGES + prompt "HID Report Type" + +config ZMK_HID_CONSUMER_REPORT_USAGES_FULL + bool "Full Consumer HID Usage Support" + help + Enable full Consumer usage ID values to be sent to hosts. Allows for less + frequently used usages, but has compatibability issues with some host OSes. + +config ZMK_HID_CONSUMER_REPORT_USAGES_BASIC + bool "Basic Consumer HID Usage Support" + help + Enable Consumer usage ID values up to "Playback Speed - Slow" to be sent to + hosts. Allows for broader compatibability with more host OSes. + +endchoice + +menu "Output Types" config ZMK_USB bool "USB" @@ -92,7 +142,10 @@ config ZMK_BLE_PASSKEY_ENTRY #ZMK_BLE endif -#HID Output Types +#Output Types +endmenu + +# HID endmenu menu "Split Support" @@ -114,6 +167,7 @@ menuconfig ZMK_SPLIT_BLE_ROLE_CENTRAL bool "Central" select BT_CENTRAL select BT_GATT_CLIENT + select BT_GATT_AUTO_DISCOVER_CCC if ZMK_SPLIT_BLE_ROLE_CENTRAL @@ -156,7 +210,7 @@ endif endif #ZMK_SPLIT -endif +endif if ZMK_BLE @@ -209,36 +263,54 @@ config ZMK_RGB_UNDERGLOW_EXT_POWER bool "RGB underglow toggling also controls external power" default y +config ZMK_RGB_UNDERGLOW_BRT_MIN + int "RGB underglow minimum brightness in percent" + range 0 100 + default 0 + +config ZMK_RGB_UNDERGLOW_BRT_MAX + int "RGB underglow maximum brightness in percent" + range ZMK_RGB_UNDERGLOW_BRT_MIN 100 + default 100 + config ZMK_RGB_UNDERGLOW_HUE_STEP - int "RGB underglow hue step in degrees of 360" + int "RGB underglow hue step in degrees" + range 0 359 default 10 config ZMK_RGB_UNDERGLOW_SAT_STEP - int "RGB underglow sturation step in percent" + int "RGB underglow saturation step in percent" + range 0 100 default 10 config ZMK_RGB_UNDERGLOW_BRT_STEP int "RGB underglow brightness step in percent" + range 0 100 default 10 config ZMK_RGB_UNDERGLOW_HUE_START - int "RGB underglow start hue value from 0-359" + int "RGB underglow start hue value in degrees" + range 0 359 default 0 config ZMK_RGB_UNDERGLOW_SAT_START - int "RGB underglow start saturations value from 0-100" + int "RGB underglow start saturations value in percent" + range 0 100 default 100 config ZMK_RGB_UNDERGLOW_BRT_START - int "RGB underglow start brightness value from 0-100" - default 100 + int "RGB underglow start brightness value in percent" + range ZMK_RGB_UNDERGLOW_BRT_MIN ZMK_RGB_UNDERGLOW_BRT_MAX + default ZMK_RGB_UNDERGLOW_BRT_MAX config ZMK_RGB_UNDERGLOW_SPD_START - int "RGB underglow start animation speed value from 1-5" + int "RGB underglow start animation speed value" + range 1 5 default 3 config ZMK_RGB_UNDERGLOW_EFF_START int "RGB underglow start effect int value related to the effect enum list" + range 0 3 default 0 config ZMK_RGB_UNDERGLOW_ON_START diff --git a/app/boards/arm/mikoto/CMakeLists.txt b/app/boards/arm/mikoto/CMakeLists.txt new file mode 100644 index 00000000..cd4843af --- /dev/null +++ b/app/boards/arm/mikoto/CMakeLists.txt @@ -0,0 +1,14 @@ +set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/../tools/uf2/utils/uf2conv.py + -c + -b 0x26000 + -f 0xADA52840 + -o ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.uf2 + ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.bin +) + +if(CONFIG_PINMUX) +zephyr_library() +zephyr_library_sources(pinmux.c) +zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) +endif() \ No newline at end of file diff --git a/app/boards/arm/mikoto/Kconfig b/app/boards/arm/mikoto/Kconfig new file mode 100644 index 00000000..646d119c --- /dev/null +++ b/app/boards/arm/mikoto/Kconfig @@ -0,0 +1,29 @@ +config BOARD_ENABLE_DCDC + bool "Enable DCDC mode" + select SOC_DCDC_NRF52X + default y + depends on (BOARD_MIKOTO_520) + +choice BOARD_MIKOTO_CHARGER_CURRENT + prompt "Charge current to supply to attached batteries" + depends on (BOARD_MIKOTO_520) + +config BOARD_MIKOTO_CHARGER_CURRENT_40MA + bool "40mA charge current, for battery capacity 40mAh or higher" + +config BOARD_MIKOTO_CHARGER_CURRENT_100MA + bool "100mA charge current, for battery capacity 100mAh or higher" + +config BOARD_MIKOTO_CHARGER_CURRENT_150MA + bool "150mA charge current, for battery capacity 150mAh or higher" + +config BOARD_MIKOTO_CHARGER_CURRENT_250MA + bool "250mA charge current, for battery capacity 250mAh or higher" + +config BOARD_MIKOTO_CHARGER_CURRENT_350MA + bool "350mA charge current, for battery capacity 350mAh or higher" + +config BOARD_MIKOTO_CHARGER_CURRENT_NONE + bool "Disable charge current" + +endchoice \ No newline at end of file diff --git a/app/boards/arm/mikoto/Kconfig.board b/app/boards/arm/mikoto/Kconfig.board new file mode 100644 index 00000000..067c2fbe --- /dev/null +++ b/app/boards/arm/mikoto/Kconfig.board @@ -0,0 +1,8 @@ +# mikoto board configuration + +# Copyright (c) 2020 The ZMK Contributors +# SPDX-License-Identifier: MIT + +config BOARD_MIKOTO_520 + bool "mikoto_520" + depends on SOC_NRF52840_QIAA diff --git a/app/boards/arm/mikoto/Kconfig.defconfig b/app/boards/arm/mikoto/Kconfig.defconfig new file mode 100644 index 00000000..2ca77b9e --- /dev/null +++ b/app/boards/arm/mikoto/Kconfig.defconfig @@ -0,0 +1,40 @@ +# Electronut Labs Papyr board configuration + +# Copyright (c) 2020 The ZMK Contributors +# SPDX-License-Identifier: MIT + +if BOARD_MIKOTO_520 + +config BOARD + default "mikoto" + +if USB + +config USB_NRFX + default y + +config USB_DEVICE_STACK + default y + +endif # USB + +config BT_CTLR + default BT + +config ZMK_BLE + default y + +config ZMK_USB + default y + +config PINMUX + default y + +choice BOARD_MIKOTO_CHARGER_CURRENT + default BOARD_MIKOTO_CHARGER_CURRENT_100MA +endchoice + +config ZMK_BATTERY_VOLTAGE_DIVIDER + default y + +endif # BOARD_MIKOTO_520 diff --git a/app/boards/arm/mikoto/arduino_pro_micro_pins.dtsi b/app/boards/arm/mikoto/arduino_pro_micro_pins.dtsi new file mode 100644 index 00000000..7c5cd12f --- /dev/null +++ b/app/boards/arm/mikoto/arduino_pro_micro_pins.dtsi @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + + +/ { + pro_micro: connector { + compatible = "arduino-pro-micro"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map + = <0 0 &gpio0 4 0> /* D0 */ + , <1 0 &gpio0 8 0> /* D1 */ + , <2 0 &gpio0 17 0> /* D2 */ + , <3 0 &gpio0 20 0> /* D3 */ + , <4 0 &gpio0 22 0> /* D4/A6 */ + , <5 0 &gpio0 24 0> /* D5 */ + , <6 0 &gpio1 0 0> /* D6/A7 */ + , <7 0 &gpio1 2 0> /* D7 */ + , <8 0 &gpio1 4 0> /* D8/A8 */ + , <9 0 &gpio1 6 0> /* D9/A9 */ + , <10 0 &gpio0 9 0> /* D10/A10 */ + , <16 0 &gpio0 10 0> /* D16 */ + , <14 0 &gpio1 13 0> /* D14 */ + , <15 0 &gpio0 2 0> /* D15 */ + , <18 0 &gpio0 29 0> /* D18/A0 */ + , <19 0 &gpio0 31 0> /* D19/A1 */ + , <20 0 &gpio0 25 0> /* D20/A2 */ + , <21 0 &gpio0 11 0> /* D21/A3 */ + ; + }; + + pro_micro_a: connector_a { + compatible = "arduino-pro-micro"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map + = <0 0 &gpio0 29 0> /* D18/A0 */ + , <1 0 &gpio0 31 0> /* D19/A1 */ + , <2 0 &gpio0 25 0> /* D20/A2 */ + , <3 0 &gpio0 11 0> /* D21/A3 */ + , <6 0 &gpio0 22 0> /* D4/A6 */ + , <7 0 &gpio1 0 0> /* D6/A7 */ + , <8 0 &gpio1 4 0> /* D8/A8 */ + , <9 0 &gpio1 6 0> /* D9/A9 */ + , <10 0 &gpio0 9 0> /* D10/A10 */ + ; + }; +}; + + +pro_micro_d: &pro_micro {}; +pro_micro_i2c: &i2c0 {}; +pro_micro_spi: &spi0 {}; +pro_micro_serial: &uart0 {}; diff --git a/app/boards/arm/mikoto/board.cmake b/app/boards/arm/mikoto/board.cmake new file mode 100644 index 00000000..fa847d50 --- /dev/null +++ b/app/boards/arm/mikoto/board.cmake @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: MIT + +board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") +include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/app/boards/arm/mikoto/mikoto_520.dts b/app/boards/arm/mikoto/mikoto_520.dts new file mode 100644 index 00000000..20703e85 --- /dev/null +++ b/app/boards/arm/mikoto/mikoto_520.dts @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +/dts-v1/; +#include +#include "arduino_pro_micro_pins.dtsi" + +/ { + model = "mikoto"; + compatible = "zhiayang,mikoto"; + + chosen { + zephyr,code-partition = &code_partition; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + blue_led: led_0 { + gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; + label = "Blue LED"; + }; + }; + + ext-power { + compatible = "zmk,ext-power-generic"; + label = "EXT_POWER"; + control-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; + }; + + vbatt { + compatible = "zmk,battery-voltage-divider"; + label = "BATTERY"; + io-channels = <&adc 2>; + output-ohms = <10000000>; + full-ohms = <(10000000 + 4000000)>; + }; +}; + +&adc { + status = "okay"; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&i2c0 { + compatible = "nordic,nrf-twi"; + sda-pin = <17>; + scl-pin = <20>; +}; + +&uart0 { + compatible = "nordic,nrf-uarte"; + tx-pin = <8>; + rx-pin = <4>; +}; + +&usbd { + status = "okay"; +}; + + +&flash0 { + /* + * For more information, see: + * http://docs.zephyrproject.org/latest/devices/dts/flash_partitions.html + */ + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + sd_partition: partition@0 { + label = "softdevice"; + reg = <0x00000000 0x00026000>; + }; + code_partition: partition@26000 { + label = "code_partition"; + reg = <0x00026000 0x000c6000>; + }; + + /* + * The flash starting at 0x000ec000 and ending at + * 0x000f3fff is reserved for use by the application. + */ + + /* + * Storage partition will be used by FCB/LittleFS/NVS + * if enabled. + */ + storage_partition: partition@ec000 { + label = "storage"; + reg = <0x000ec000 0x00008000>; + }; + + boot_partition: partition@f4000 { + label = "adafruit_boot"; + reg = <0x000f4000 0x0000c000>; + }; + }; +}; diff --git a/app/boards/arm/mikoto/mikoto_520.yaml b/app/boards/arm/mikoto/mikoto_520.yaml new file mode 100644 index 00000000..8d9f49ae --- /dev/null +++ b/app/boards/arm/mikoto/mikoto_520.yaml @@ -0,0 +1,15 @@ +identifier: mikoto_520 +name: mikoto_520 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - adc + - usb_device + - ble + - ieee802154 + - pwm + - watchdog diff --git a/app/boards/arm/mikoto/mikoto_520.zmk.yml b/app/boards/arm/mikoto/mikoto_520.zmk.yml new file mode 100644 index 00000000..91dcc9e0 --- /dev/null +++ b/app/boards/arm/mikoto/mikoto_520.zmk.yml @@ -0,0 +1,10 @@ +file_format: "1" +id: mikoto_520 +name: Mikoto 5.20 +type: board +arch: arm +outputs: + - usb + - ble +url: https://github.com/zhiayang/mikoto +exposes: [pro_micro] diff --git a/app/boards/arm/mikoto/mikoto_520_defconfig b/app/boards/arm/mikoto/mikoto_520_defconfig new file mode 100644 index 00000000..925711c0 --- /dev/null +++ b/app/boards/arm/mikoto/mikoto_520_defconfig @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: MIT + +CONFIG_SOC_SERIES_NRF52X=y +CONFIG_SOC_NRF52840_QIAA=y +CONFIG_BOARD_MIKOTO_520=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# enable GPIO +CONFIG_GPIO=y + +CONFIG_USE_DT_CODE_PARTITION=y + +CONFIG_MPU_ALLOW_FLASH_WRITE=y +CONFIG_NVS=y +CONFIG_SETTINGS_NVS=y +CONFIG_FLASH=y +CONFIG_FLASH_PAGE_LAYOUT=y +CONFIG_FLASH_MAP=y diff --git a/app/boards/arm/mikoto/pinmux.c b/app/boards/arm/mikoto/pinmux.c new file mode 100644 index 00000000..59a38fbf --- /dev/null +++ b/app/boards/arm/mikoto/pinmux.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include +#include +#include + +static int pinmux_mikoto_init(const struct device *port) { + ARG_UNUSED(port); + +#if CONFIG_BOARD_MIKOTO_520 + const struct device *p0 = device_get_binding("GPIO_0"); + const struct device *p1 = device_get_binding("GPIO_1"); +#if CONFIG_BOARD_MIKOTO_CHARGER_CURRENT_40MA + gpio_pin_configure(p0, 26, GPIO_INPUT | GPIO_PULL_DOWN); + gpio_pin_configure(p1, 15, GPIO_INPUT); +#elif CONFIG_BOARD_MIKOTO_CHARGER_CURRENT_100MA + gpio_pin_configure(p0, 26, GPIO_OUTPUT); + gpio_pin_set(p0, 26, 0); + gpio_pin_configure(p1, 15, GPIO_INPUT); +#elif CONFIG_BOARD_MIKOTO_CHARGER_CURRENT_150MA + gpio_pin_configure(p0, 26, GPIO_OUTPUT); + gpio_pin_set(p0, 26, 0); + gpio_pin_configure(p1, 15, GPIO_INPUT | GPIO_PULL_DOWN); +#elif CONFIG_BOARD_MIKOTO_CHARGER_CURRENT_250MA + gpio_pin_configure(p0, 26, GPIO_INPUT); + gpio_pin_configure(p1, 15, GPIO_OUTPUT); + gpio_pin_set(p1, 15, 0); +#elif CONFIG_BOARD_MIKOTO_CHARGER_CURRENT_350MA + gpio_pin_configure(p0, 26, GPIO_OUTPUT); + gpio_pin_set(p0, 26, 0); + gpio_pin_configure(p1, 15, GPIO_OUTPUT); + gpio_pin_set(p1, 15, 0); +#elif CONFIG_BOARD_MIKOTO_CHARGER_CURRENT_NONE + gpio_pin_configure(p0, 26, GPIO_INPUT); + gpio_pin_configure(p1, 15, GPIO_INPUT); +#endif +#endif + return 0; +} + +SYS_INIT(pinmux_mikoto_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); diff --git a/app/boards/shields/ergodash/Kconfig.defconfig b/app/boards/shields/ergodash/Kconfig.defconfig new file mode 100644 index 00000000..b908584b --- /dev/null +++ b/app/boards/shields/ergodash/Kconfig.defconfig @@ -0,0 +1,19 @@ +# Copyright (c) 2020 The ZMK Contributors +# SPDX-License-Identifier: MIT + +if SHIELD_ERGODASH_LEFT + +config ZMK_KEYBOARD_NAME + default "Ergodash" + +config ZMK_SPLIT_BLE_ROLE_CENTRAL + default y + +endif + +if SHIELD_ERGODASH_LEFT || SHIELD_ERGODASH_RIGHT + +config ZMK_SPLIT + default y + +endif diff --git a/app/boards/shields/ergodash/Kconfig.shield b/app/boards/shields/ergodash/Kconfig.shield new file mode 100644 index 00000000..b3cca293 --- /dev/null +++ b/app/boards/shields/ergodash/Kconfig.shield @@ -0,0 +1,8 @@ +# Copyright (c) 2020 The ZMK Contributors +# SPDX-License-Identifier: MIT + +config SHIELD_ERGODASH_LEFT + def_bool $(shields_list_contains,ergodash_left) + +config SHIELD_ERGODASH_RIGHT + def_bool $(shields_list_contains,ergodash_right) diff --git a/app/boards/shields/ergodash/ergodash.conf b/app/boards/shields/ergodash/ergodash.conf new file mode 100644 index 00000000..e69de29b diff --git a/app/boards/shields/ergodash/ergodash.dtsi b/app/boards/shields/ergodash/ergodash.dtsi new file mode 100644 index 00000000..a2b76075 --- /dev/null +++ b/app/boards/shields/ergodash/ergodash.dtsi @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include + +/ { + chosen { + zmk,kscan = &kscan0; + zmk,matrix_transform = &default_transform; + }; + + default_transform: keymap_transform_0 { + compatible = "zmk,matrix-transform"; + columns = <14>; + rows = <5>; +// Numbering based on rev 1.2 schema +// * keys that can be in different positions are denoted as MW +// * MW40 can be broken off +// | SW1 | SW5 | SW9 | SW13 | SW17 | SW21 | SW25 | | | | SW25 | SW21 | SW17 | SW13 | SW9 | SW5 | SW1 | +// | SW2 | SW6 | SW10 | SW14 | SW18 | SW22 | SW26 | | | | SW26 | SW22 | SW18 | SW14 | SW10 | SW6 | SW2 | +// | SW3 | SW7 | SW11 | SW15 | SW19 | SW23 | SW27 | | | | SW27 | SW23 | SW19 | SW15 | SW11 | SW7 | SW3 | +// | SW4 | SW8 | SW12 | SW16 | SW20 | SW24 | | MW28 | | MW28 | | SW24 | SW20 | SW16 | SW12 | SW8 | SW4 | +// | SW30 | SW31 | SW32 | MW33 | SW34 | | MW35 | MW40 | | MW40 | MW35 | | SW34 | MW33 | SW32 | SW31 | SW30 | + map = < +RC(0,0) RC(0,1) RC(0,2) RC(0,3) RC(0,4) RC(0,5) RC(0,6) RC(0,13) RC(0,12) RC(0,11) RC(0,10) RC(0,9) RC(0,8) RC(0,7) +RC(1,0) RC(1,1) RC(1,2) RC(1,3) RC(1,4) RC(1,5) RC(1,6) RC(1,13) RC(1,12) RC(1,11) RC(1,10) RC(1,9) RC(1,8) RC(1,7) +RC(2,0) RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) RC(2,6) RC(2,13) RC(2,12) RC(2,11) RC(2,10) RC(2,9) RC(2,8) RC(2,7) +RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(3,6) RC(3,13) RC(3,12) RC(3,11) RC(3,10) RC(3,9) RC(3,8) RC(3,7) +RC(4,0) RC(4,1) RC(4,2) RC(4,3) RC(4,4) RC(4,5) RC(4,6) RC(4,13) RC(4,12) RC(4,11) RC(4,10) RC(4,9) RC(4,8) RC(4,7) + >; + }; + + kscan0: kscan { + compatible = "zmk,kscan-gpio-matrix"; + label = "KSCAN"; + + diode-direction = "col2row"; + + row-gpios + = <&pro_micro 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 7 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 8 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 9 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + ; + + col-gpios + = <&pro_micro 21 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 20 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 19 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 18 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 15 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 14 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 16 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + ; + }; +}; + diff --git a/app/boards/shields/ergodash/ergodash.keymap b/app/boards/shields/ergodash/ergodash.keymap new file mode 100644 index 00000000..65cc1178 --- /dev/null +++ b/app/boards/shields/ergodash/ergodash.keymap @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include + +#define DEFAULT 0 +#define LOWER 1 +#define RAISE 2 + + +/ { + keymap { + compatible = "zmk,keymap"; + + default_layer { +/* QWERTY + * .----------------------------------------------------------------------------------------------------------------------. + * | ` | 1 | 2 | 3 | 4 | 5 | [ | | ] | 6 | 7 | 8 | 9 | 0 | PScr | + * |------+------+------+------+------+------+------+--------------------+------+------+------+------+------+------+------| + * | ESC | Q | W | E | R | T | - | | = | Y | U | I | O | P | \ | + * |------+------+------+------+------+------+------+--------------------+------+------+------+------+------+------+------| + * | Tab | A | S | D | F | G | Del | | Bksp | H | J | K | L | ; | ' | + * |------+------+------+------+------+------+---------------------------+------+------+------+------+------+------+------| + * | Shift| Z | X | C | V | B | End | | Home | N | M | , | . | / | Shift| + * |-------------+------+------+------+------+------+------+------+------+------+------+------+------+------+-------------| + * | Ctrl | | PGDN | Win |||||||| Alt | Space| Lower|||||||| Raise| Enter| RAlt |||||||| | PGUP | Ins | RCtrl| + * .----------------------------------------------------------------------------------------------------------------------. + */ + bindings = < +&kp GRAVE &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp LBKT &kp RBKT &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp PSCRN +&kp ESC &kp Q &kp W &kp E &kp R &kp T &kp MINUS &kp EQUAL &kp Y &kp U &kp I &kp O &kp P &kp BSLH +&kp TAB &kp A &kp S &kp D &kp F &kp G &kp DEL &kp BSPC &kp H &kp J &kp K &kp L &kp SEMI &kp SQT +&kp LSHFT &kp Z &kp X &kp C &kp V &kp B &kp END &kp HOME &kp N &kp M &kp COMMA &kp DOT &kp SLASH &kp RSHFT +&kp LCTRL &none &kp PG_DN &kp LMETA &kp LALT &kp SPACE &mo LOWER &mo RAISE &kp RET &kp RALT &none &kp PG_UP &kp INS &kp RCTRL + >; + }; + lower_layer { +/* .----------------------------------------------------------------------------------------------------------------------. + * | F11 | F1 | F2 | F3 | F4 | F5 | | | | F6 | F7 | F8 | F9 | F10 | F12 | + * |------+------+------+------+------+------+------+--------------------+------+------+------+------+------+------+------| + * | | | | | | | | | | | | | | | | + * |------+------+------+------+------+------+------+--------------------+------+------+------+------+------+------+------| + * | | | | | | | | | | | | | | | | + * |------+------+------+------+------+------+---------------------------+------+------+------+------+------+------+------| + * | Shift| Boot | Reset| | | | | | | | | | | | Shift| + * |-------------+------+------+------+------+------+------+------+------+------+------+------+------+------+-------------| + * | Ctlr | | | Win |||||||| Alt | | Lower|||||||| Raise| | RAlt |||||||| | | | RCtrl| + * .----------------------------------------------------------------------------------------------------------------------. + */ /* FIXME boot and reset are not yet locale aware */ + bindings = < +&kp F11 &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp &none &kp &none &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F12 +&none &none &none &none &none &none &none &none &none &none &none &none &none &none +&none &none &none &none &none &none &none &none &none &none &none &none &none &none +&trans &bootloader &reset &none &none &none &none &none &none &none &none &none &none &trans +&trans &none &none &trans &trans &none &trans &trans &none &trans &none &none &none &trans + >; + }; + raise_layer { +/* .----------------------------------------------------------------------------------------------------------------------. + * | | BT 0 | BT 1 | BT 2 | BT 3 | | BTCL | | | | | | | | | + * |------+------+------+------+------+------+------+--------------------+------+------+------+------+------+------+------| + * | | | | | | | | | | | | | | | | + * |------+------+------+------+------+------+------+--------------------+------+------+------+------+------+------+------| + * | | | | | | | | | | | | | | | | + * |------+------+------+------+------+------+---------------------------+------+------+------+------+------+------+------| + * | Shift| | | | | | | | | | | | Boot | Reset| Shift| + * |-------------+------+------+------+------+------+------+------+------+------+------+------+------+------+-------------| + * | Ctlr | | | Win |||||||| Alt | | Lower|||||||| Raise| | RAlt |||||||| | | | RCtrl| + * .----------------------------------------------------------------------------------------------------------------------. + */ /* FIXME boot and reset are not yet locale aware */ + bindings = < +&none &bt BT_SEL 0 &bt BT_SEL 1 &bt BT_SEL 2 &bt BT_SEL 3 &none &bt BT_CLR &none &none &none &none &none &none &none +&none &none &none &none &none &none &none &none &none &none &none &none &none &none +&none &none &none &none &none &none &none &none &none &none &none &none &none &none +&trans &none &none &none &none &none &none &none &none &none &none &bootloader &reset &trans +&trans &none &none &trans &trans &none &trans &trans &none &trans &none &none &none &trans + >; + }; + }; +}; + diff --git a/app/boards/shields/ergodash/ergodash.zmk.yml b/app/boards/shields/ergodash/ergodash.zmk.yml new file mode 100644 index 00000000..376831a6 --- /dev/null +++ b/app/boards/shields/ergodash/ergodash.zmk.yml @@ -0,0 +1,11 @@ +file_format: "1" +id: ergodash +name: Ergodash +type: shield +url: https://github.com/omkbd/ErgoDash +requires: [pro_micro] +features: + - keys +siblings: + - ergodash_left + - ergodash_right diff --git a/app/boards/shields/ergodash/ergodash_left.overlay b/app/boards/shields/ergodash/ergodash_left.overlay new file mode 100644 index 00000000..40263aa4 --- /dev/null +++ b/app/boards/shields/ergodash/ergodash_left.overlay @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include "ergodash.dtsi" + diff --git a/app/boards/shields/ergodash/ergodash_right.overlay b/app/boards/shields/ergodash/ergodash_right.overlay new file mode 100644 index 00000000..464b3f5d --- /dev/null +++ b/app/boards/shields/ergodash/ergodash_right.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include "ergodash.dtsi" + +&default_transform { + col-offset = <7>; +}; diff --git a/app/boards/shields/naked60/Kconfig.defconfig b/app/boards/shields/naked60/Kconfig.defconfig new file mode 100644 index 00000000..ff5978bc --- /dev/null +++ b/app/boards/shields/naked60/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2020 The ZMK Contributors +# SPDX-License-Identifier: MIT + +if SHIELD_NAKED60 + +config ZMK_KEYBOARD_NAME + default "Naked60BMP" + +endif \ No newline at end of file diff --git a/app/boards/shields/naked60/Kconfig.shield b/app/boards/shields/naked60/Kconfig.shield new file mode 100644 index 00000000..61053686 --- /dev/null +++ b/app/boards/shields/naked60/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2020 The ZMK Contributors +# SPDX-License-Identifier: MIT + +config SHIELD_NAKED60 + def_bool $(shields_list_contains,naked60) diff --git a/app/boards/shields/naked60/naked60.conf b/app/boards/shields/naked60/naked60.conf new file mode 100644 index 00000000..e69de29b diff --git a/app/boards/shields/naked60/naked60.keymap b/app/boards/shields/naked60/naked60.keymap new file mode 100644 index 00000000..d380a599 --- /dev/null +++ b/app/boards/shields/naked60/naked60.keymap @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include + + +/ { + keymap { + compatible = "zmk,keymap"; + + default_layer { + // ---------------------------------------------------------------------------------------------------------- + // | ESC | 1 | 2 | 3 | 4 | 5 |-------|-------| 6 | 7 | 8 | 9 | 0 | BSPC | + // | TAB | Q | W | E | R | T |-------|-------| Y | U | I | O | P | \ | + // | SHIFT | A | S | D | F | G |-------|-------| H | J | K | L | ; | ' | + // | CTRL | Z | X | C | V | B |-------|-------| N | M | , | . | / | ENTER | + // |-------|ADJUST| LCTL | LALT | LGUI | LOWR | SPACE | SPACE | RAIS | LARW | DARW | UARW | RARW |-------| + + + bindings = < + &kp ESC &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp BSPC + &kp TAB &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp BSLH + &kp LSHFT &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SEMI &kp SQT + &kp LCTRL &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp FSLH &kp RET + &mo 3 &kp LCTRL &kp LALT &kp LGUI &mo 1 &kp SPACE &kp SPACE &mo 2 &kp LEFT &kp DOWN &kp UP &kp RIGHT + >; + }; + + lower { + // ---------------------------------------------------------------------------------------------------------- + // | ESC | F2 | F3 | F4 | F5 | F6 |-------|-------| F7 | F8 | F9 | F10 | F11 | F12 | + // | ~ | ! | @ | # | $ | % |-------|-------| ^ | & | * | ( | ) | DEL | + // | | F1 | F2 | F3 | F4 | F5 |-------|-------| F6 | _ | + | { | } | | | + // | | F7 | F8 | F9 | F10 | F11 |-------|-------| F12 | LS(#) |LS(|) | | | | + // |-------| | | | | | | | | NEXT | Vol- | Vol+ | PLAY |-------| + bindings = < + &kp ESC &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 + &kp TILDE &kp EXCL &kp AT &kp HASH &kp DLLR &kp PRCNT &kp CARET &kp AMPS &kp ASTRK &kp LPAR &kp RPAR &kp DEL + &trans &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp UNDER &kp PLUS &kp LBRC &kp RBRC &kp PIPE + &trans &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 &kp LS(NON_US_HASH) &kp LS(NON_US_BSLH) &trans &trans &trans + &trans &trans &trans &trans &trans &trans &trans &mo 3 &kp C_NEXT &kp C_VOL_DN &kp C_VOL_UP &kp C_PLAY_PAUSE + >; + }; + + raise { + // ---------------------------------------------------------------------------------------------------------- + // | ESC | F2 | F3 | F4 | F5 | F6 |-------|-------| F7 | F8 | F9 | F10 | F11 | F12 | + // | ~ | 1 | 2 | 3 | 4 | 5 |-------|-------| 6 | 7 | 8 | 9 | 0 | DEL | + // | DEL | F1 | F2 | F3 | F4 | F5 |-------|-------| F6 | - | = | [ | ] | \ | + // | | F7 | F8 | F9 | F10 | F11 |-------|-------| F12 | # | | | | | | + // |-------| | | | | | | | | | | | |-------| + bindings = < + &kp ESC &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 + &kp TILDE &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp DEL + &kp DEL &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp MINUS &kp EQUAL &kp LBKT &kp RBKT &kp BSLH + &trans &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 &kp NON_US_HASH &kp NON_US_BSLH &trans &trans &trans + &trans &trans &trans &trans &mo 3 &trans &trans &trans &trans &trans &trans &trans + >; + }; + + adjust { + // ---------------------------------------------------------------------------------------------------------- + // |tog(4)| F2 | F3 | F4 | F5 | F6 |------|------| F7 | F8 | F9 | F10 | F11 | F12 | + // | | NA | NA | NA | NA | NA |------|------| NA | NA | NA | NA | NA |LALT(PRTSN)| + // | | NA | NA | NA | NA | NA |------|------| NA | NA | NA | NA | NA | PRTSN | + // | | NA | NA | NA | NA | NA |------|------| NA | NA | NA | NA | NA |LCTRL(DEL) | + // |------| | | | | |BOOTLD|BOOTLD| | | | | |-----------| + bindings = < + &tog 4 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 + &trans &none &none &none &none &none &none &none &none &none &none &kp LA(PSCRN) + &trans &none &none &none &none &none &none &none &none &none &none &kp PSCRN + &trans &none &none &none &none &none &none &none &none &none &none &kp LC(DEL) + &trans &trans &trans &trans &trans &bootloader &bootloader &trans &trans &trans &trans &trans + >; + }; + + flock { + // ---------------------------------------------------------------------------------------------------------- + // |tog(4) | F2 | F3 | F4 | F5 | F6 |-------|-------| F7 | F8 | F9 | F10 | F11 | | + // |out tog|BT_SEL 0|BT_SEL 1|BT_SEL 2|BT_SEL 3|BT_SEL 4|-------|-------|BT_PRV|BT_NXT|BT_CLR| | | | + // | | | | | | |-------|-------| | | | | | | + // | | | | | | |-------|-------| | | | | | | + // |-------| | | | | | | | | | | | |------| + bindings = < + &tog 4 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &trans + &out OUT_TOG &bt BT_SEL 0 &bt BT_SEL 1 &bt BT_SEL 2 &bt BT_SEL 3 &bt BT_SEL 4 &bt BT_PRV &bt BT_NXT &bt BT_CLR &trans &trans &trans + &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans + &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans + &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans + >; + }; + }; +}; \ No newline at end of file diff --git a/app/boards/shields/naked60/naked60.overlay b/app/boards/shields/naked60/naked60.overlay new file mode 100644 index 00000000..2260a4af --- /dev/null +++ b/app/boards/shields/naked60/naked60.overlay @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +/ { + chosen { + zmk,kscan = &kscan0; + }; + + kscan0: kscan_0 { + compatible = "zmk,kscan-gpio-matrix"; + label = "KSCAN"; + diode-direction = "col2row"; + + col-gpios + = <&pro_micro 21 GPIO_ACTIVE_HIGH> // col 0 + , <&pro_micro 20 GPIO_ACTIVE_HIGH> // col 1 + , <&pro_micro 19 GPIO_ACTIVE_HIGH> // col 2 + , <&pro_micro 18 GPIO_ACTIVE_HIGH> // col 3 + , <&pro_micro 15 GPIO_ACTIVE_HIGH> // col 4 + , <&pro_micro 14 GPIO_ACTIVE_HIGH> // col 5 + , <&pro_micro 16 GPIO_ACTIVE_HIGH> // col 6 + , <&pro_micro 6 GPIO_ACTIVE_HIGH> // col 7 + , <&pro_micro 7 GPIO_ACTIVE_HIGH> // col 8 + , <&pro_micro 8 GPIO_ACTIVE_HIGH> // col 9 + , <&pro_micro 9 GPIO_ACTIVE_HIGH> // col 10 + , <&pro_micro 1 GPIO_ACTIVE_HIGH> // col 11 + ; + + row-gpios + = <&pro_micro 10 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> // row 0 + , <&pro_micro 2 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> // row 1 + , <&pro_micro 3 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> // row 2 + , <&pro_micro 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> // row 3 + , <&pro_micro 5 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> // row 4 + ; + }; +}; \ No newline at end of file diff --git a/app/boards/shields/naked60/naked60.zmk.yml b/app/boards/shields/naked60/naked60.zmk.yml new file mode 100644 index 00000000..932c2298 --- /dev/null +++ b/app/boards/shields/naked60/naked60.zmk.yml @@ -0,0 +1,8 @@ +file_format: "1" +id: naked60 +name: Naked60 +type: shield +url: https://salicylic-acid3.hatenablog.com/ +requires: [pro_micro] +features: + - keys diff --git a/app/boards/shields/reviung41/reviung41.keymap b/app/boards/shields/reviung41/reviung41.keymap index 9c189759..f0450b19 100644 --- a/app/boards/shields/reviung41/reviung41.keymap +++ b/app/boards/shields/reviung41/reviung41.keymap @@ -35,8 +35,8 @@ // | | | RET | ADJ | | bindings = < &trans &kp EXCL &kp AT &kp HASH &kp DLLR &kp PRCNT &kp CARET &kp AMPS &kp N8 &kp LPAR &kp RPAR &kp DEL - &trans &kp MINUS &kp KP_PLUS &kp LBRC &kp RBRC &kp PIPE &kp LEFT &kp DOWN &kp UP &kp RIGHT &kp GRAVE &kp GRAVE - &trans &kp ESC &kp LGUI &kp LALT &kp CLCK &kp SQT &kp HOME &kp END &kp PG_UP &kp PG_DN &kp PSCRN &mt RSHFT RET + &trans &kp MINUS &kp KP_PLUS &kp LBRC &kp RBRC &kp PIPE &kp LEFT &kp DOWN &kp UP &kp RIGHT &kp GRAVE &kp TILDE + &trans &kp ESC &kp LGUI &kp LALT &kp CLCK &kp DQT &kp HOME &kp END &kp PG_UP &kp PG_DN &kp PSCRN &mt RSHFT RET &trans &trans &kp RET &mo 3 &trans >; }; @@ -50,7 +50,7 @@ bindings = < &trans &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp DEL &trans &kp MINUS &kp EQUAL &kp LBKT &kp RBKT &kp BSLH &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 - &trans &kp ESC &kp LGUI &kp RALT &kp CLCK &kp SQT &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 + &trans &kp ESC &kp LGUI &kp RALT &kp CLCK &kp DQT &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 &trans &mo 3 &kp BSPC &trans &trans >; }; @@ -58,7 +58,7 @@ adjust_layer { // ----------------------------------------------------------------------------------------- // | RGB BRI+ | RGB SAT+ | RGB HUE+ | RGB ANI+ | | RGB TOG | | BT1 | BT2 | BT3 | BT4 | BT5 | BT CLR | -// | RGB BRI- | RGB SAT- | RGB HUE- | RGB ANI+ | | | | | | | | | | +// | RGB BRI- | RGB SAT- | RGB HUE- | RGB ANI- | | | | | | | | | | // | | | | | | | | RESET | | | | | | // | | | | | | bindings = < diff --git a/app/boards/shields/zodiark/Kconfig.defconfig b/app/boards/shields/zodiark/Kconfig.defconfig new file mode 100644 index 00000000..cdad43f6 --- /dev/null +++ b/app/boards/shields/zodiark/Kconfig.defconfig @@ -0,0 +1,55 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +if SHIELD_ZODIARK_LEFT + +config ZMK_KEYBOARD_NAME + default "Zodiark" + +config ZMK_SPLIT_BLE_ROLE_CENTRAL + default y + +endif + +if SHIELD_ZODIARK_LEFT || SHIELD_ZODIARK_RIGHT + +config ZMK_SPLIT + default y + +if ZMK_DISPLAY + +config I2C + default y + +config SSD1306 + default y + +config SSD1306_REVERSE_MODE + default y + +endif # ZMK_DISPLAY + +if LVGL + +config LVGL_HOR_RES_MAX + default 128 + +config LVGL_VER_RES_MAX + default 64 + +config LVGL_VDB_SIZE + default 64 + +config LVGL_DPI + default 148 + +config LVGL_BITS_PER_PIXEL + default 1 + +choice LVGL_COLOR_DEPTH + default LVGL_COLOR_DEPTH_1 +endchoice + +endif # LVGL + +endif diff --git a/app/boards/shields/zodiark/Kconfig.shield b/app/boards/shields/zodiark/Kconfig.shield new file mode 100644 index 00000000..25e23a14 --- /dev/null +++ b/app/boards/shields/zodiark/Kconfig.shield @@ -0,0 +1,8 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +config SHIELD_ZODIARK_LEFT + def_bool $(shields_list_contains,zodiark_left) + +config SHIELD_ZODIARK_RIGHT + def_bool $(shields_list_contains,zodiark_right) diff --git a/app/boards/shields/zodiark/zodiark.conf b/app/boards/shields/zodiark/zodiark.conf new file mode 100644 index 00000000..64784850 --- /dev/null +++ b/app/boards/shields/zodiark/zodiark.conf @@ -0,0 +1,9 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +# Uncomment the following line to enable the Zodiark OLED Display +# CONFIG_ZMK_DISPLAY=y + +# Uncomment these two lines to add support for encoders +# CONFIG_EC11=y +# CONFIG_EC11_TRIGGER_GLOBAL_THREAD=y diff --git a/app/boards/shields/zodiark/zodiark.dtsi b/app/boards/shields/zodiark/zodiark.dtsi new file mode 100644 index 00000000..0adb7f67 --- /dev/null +++ b/app/boards/shields/zodiark/zodiark.dtsi @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include + +/ { + chosen { + zmk,kscan = &kscan0; + zmk,matrix_transform = &default_transform; + }; + + default_transform: keymap_transform_0 { + compatible = "zmk,matrix-transform"; + columns = <18>; + rows = <4>; +// | SW6 | SW5 | SW4 | SW3 | SW2 | SW1 | | SW1 | SW2 | SW3 | SW4 | SW5 | SW6 | +// | SW13 | SW12 | SW11 | SW10 | SW9 | SW8 | SW7 | | SW7 | SW8 | SW9 | SW10 | SW11 | SW12 | SW13 | +// | SW20 | SW19 | SW18 | SW17 | SW16 | SW15 | SW14 | | SW14 | SW15 | SW16 | SW17 | SW18 | SW19 | SW20 | +// | SW28 | SW27 | SW26 | SW25 | SW24 | SW23 | SW22 | SW21 | | SW21 | SW22 | SW23 | SW24 | SW25 | SW26 | SW27 | SW28 | +// | SW35 | SW34 | SW33 | SW32 | SW31 | SW30 | SW29 | | SW29 | SW30 | SW31 | SW32 | SW33 | SW34 | SW35 | + map = < +RC(0,0) RC(0,1) RC(0,2) RC(0,3) RC(0,4) RC(0,5) RC(0,8) RC(0,9) RC(0,10) RC(0,11) RC(0,12) RC(0,13) +RC(1,0) RC(1,1) RC(1,2) RC(1,3) RC(1,4) RC(1,5) RC(0,6) RC(0,7) RC(1,8) RC(1,9) RC(1,10) RC(1,11) RC(1,12) RC(1,13) +RC(2,0) RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) RC(1,6) RC(1,7) RC(2,8) RC(2,9) RC(2,10) RC(2,11) RC(2,12) RC(2,13) +RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(2,6) RC(3,6) RC(3,7) RC(2,7) RC(3,8) RC(3,9) RC(3,10) RC(3,11) RC(3,12) RC(3,13) +RC(4,0) RC(4,1) RC(4,2) RC(4,3) RC(4,4) RC(4,5) RC(4,6) RC(4,7) RC(4,8) RC(4,9) RC(4,10) RC(4,11) RC(4,12) RC(4,13) + >; + }; + + kscan0: kscan { + compatible = "zmk,kscan-gpio-matrix"; + label = "KSCAN"; + + diode-direction = "col2row"; + row-gpios + = <&pro_micro 5 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 7 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 8 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 3 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + ; + }; + + left_encoder: encoder_left { + compatible = "alps,ec11"; + label = "LEFT_ENCODER"; + a-gpios = <&pro_micro 2 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; + b-gpios = <&pro_micro 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; + resolution = <4>; + status = "disabled"; + }; + + right_encoder: encoder_right { + compatible = "alps,ec11"; + label = "RIGHT_ENCODER"; + a-gpios = <&pro_micro 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; + b-gpios = <&pro_micro 2 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; + resolution = <4>; + status = "disabled"; + }; + + sensors { + compatible = "zmk,keymap-sensors"; + sensors = <&left_encoder &right_encoder>; + }; +}; + +&pro_micro_i2c { + status = "okay"; + + ssd1306@3c { + compatible = "solomon,ssd1306fb"; + reg = <0x3c>; + label = "DISPLAY"; + width = <128>; + height = <64>; + segment-offset = <0>; + page-offset = <0>; + display-offset = <0>; + multiplex-ratio = <31>; + prechargep = <0x22>; + }; +}; diff --git a/app/boards/shields/zodiark/zodiark.keymap b/app/boards/shields/zodiark/zodiark.keymap new file mode 100644 index 00000000..21fdef10 --- /dev/null +++ b/app/boards/shields/zodiark/zodiark.keymap @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include + +/ { + keymap { + compatible = "zmk,keymap"; + + default_layer { +// ------------------------------------------------------------------------------------------------------------ +// | ESC | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | BKSPC | +// | TAB | Q | W | E | R | T | [ | | ] | Y | U | I | O | P | \ | +// | CAPS | A | S | D | F | G | - | | = | H | J | K | L | ; | ' | +// | SHIFT | Z | X | C | V | B | ` | MUTE | | PRNT | DEL | N | M | , | . | / | ENTER | +// | CTRL | ALT | GUI | MENU | LOWER| SPACE | ENTER | | ENTER | SPACE | RAISE| LEFT | DOWN | UP | RIGHT | + bindings = < +&kp ESC &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp BSPC +&kp TAB &kp Q &kp W &kp E &kp R &kp T &kp LBKT &kp RBKT &kp Y &kp U &kp I &kp O &kp P &kp BSLH +&kp TAB &kp A &kp S &kp D &kp F &kp G &kp MINUS &kp EQUAL &kp H &kp J &kp K &kp L &kp SEMI &kp SQT +&kp LSHFT &kp Z &kp X &kp C &kp V &kp B &kp GRAVE &kp C_MUTE &kp PSCRN &kp DEL &kp N &kp M &kp COMMA &kp DOT &kp FSLH &kp RET +&kp LCTRL &kp LALT &kp LGUI &kp K_CMENU &mo 1 &kp SPACE &kp RET &kp RET &kp SPACE &mo 2 &kp LEFT &kp DOWN &kp UP &kp RIGHT + >; + + sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN &inc_dec_kp PG_UP PG_DN>; + }; + + lower_layer { +// ------------------------------------------------------------------------------------------------------------ +// | | F1 | F2 | F3 | F4 | F5 | | F6 | F7 | F8 | F9 | F10 | F11 | +// | N.LC | 7 | 8 | 9 |PRTSC | SCRLK| | | | PAUSE| | 7 | 8 | 9 | F12 | +// | | 4 | 5 | 6 | INS | HOME | | | | PGUP| | 4 | 5 | 6 | | +// | | 1 | 2 | 3 | DEL | END | | | | | | PGDN| | 1 | 2 | 3 | | +// | | 0 | . | Enter| | | | | | | | 0 | . | Enter | | + bindings = < +&trans &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 +&kp KP_NUM &kp KP_N7 &kp KP_N8 &kp KP_N9 &kp PSCRN &kp SLCK &trans &trans &kp PAUSE_BREAK &trans &kp KP_N7 &kp KP_N8 &kp KP_N9 &kp F12 +&trans &kp KP_N4 &kp KP_N5 &kp KP_N6 &kp INS &kp HOME &trans &trans &kp PG_UP &trans &kp KP_N4 &kp KP_N5 &kp KP_N6 &trans +&trans &kp KP_N1 &kp KP_N2 &kp KP_N3 &kp DEL &kp END &trans &trans &trans &trans &kp PG_DN &trans &kp KP_N1 &kp KP_N2 &kp KP_N3 &trans +&trans &kp KP_N0 &kp KP_DOT &kp KP_ENTER &trans &trans &trans &trans &trans &trans &kp KP_N0 &kp KP_DOT &kp KP_ENTER &trans + >; + + sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN &inc_dec_kp PG_UP PG_DN>; + }; + + raise_layer { +// ------------------------------------------------------------------------------------------------------------ +// |BTCLR | BT1 | BT2 | BT3 | BT4 | BT5 | | | | | | | RESET | +// | | | | | | | | | | | | | | |BLOADER| +// | | | | | | | | | | | | | | | | +// | | | | | | | | | | | | | | | | | | +// | | | | | | | | | | | | | | | | + bindings = < +&bt BT_CLR &bt BT_SEL 0 &bt BT_SEL 1 &bt BT_SEL 2 &bt BT_SEL 3 &bt BT_SEL 4 &trans &trans &trans &trans &trans &reset +&trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &bootloader +&trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans +&trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans +&trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans + >; + + sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN &inc_dec_kp PG_UP PG_DN>; + }; + }; +}; diff --git a/app/boards/shields/zodiark/zodiark.zmk.yml b/app/boards/shields/zodiark/zodiark.zmk.yml new file mode 100644 index 00000000..fc685881 --- /dev/null +++ b/app/boards/shields/zodiark/zodiark.zmk.yml @@ -0,0 +1,14 @@ +file_format: "1" +id: zodiark +name: Zodiark +type: shield +url: https://www.splitlogic.xyz/buildguides/zodiark-build-guide +requires: [pro_micro] +exposes: [i2c_oled] +features: + - keys + - display + - encoder +siblings: + - zodiark_left + - zodiark_right diff --git a/app/boards/shields/zodiark/zodiark_left.overlay b/app/boards/shields/zodiark/zodiark_left.overlay new file mode 100644 index 00000000..fe55edc6 --- /dev/null +++ b/app/boards/shields/zodiark/zodiark_left.overlay @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include "zodiark.dtsi" + +&kscan0 { + col-gpios + = <&pro_micro 2 GPIO_ACTIVE_HIGH> + , <&pro_micro 1 GPIO_ACTIVE_HIGH> + , <&pro_micro 0 GPIO_ACTIVE_HIGH> + , <&pro_micro 15 GPIO_ACTIVE_HIGH> + , <&pro_micro 14 GPIO_ACTIVE_HIGH> + , <&pro_micro 16 GPIO_ACTIVE_HIGH> + , <&pro_micro 10 GPIO_ACTIVE_HIGH> + ; +}; + +&left_encoder { + status = "okay"; +}; diff --git a/app/boards/shields/zodiark/zodiark_right.overlay b/app/boards/shields/zodiark/zodiark_right.overlay new file mode 100644 index 00000000..3405f59b --- /dev/null +++ b/app/boards/shields/zodiark/zodiark_right.overlay @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include "zodiark.dtsi" + +&default_transform { + col-offset = <7>; +}; + +&kscan0 { + col-gpios + = <&pro_micro 10 GPIO_ACTIVE_HIGH> + , <&pro_micro 16 GPIO_ACTIVE_HIGH> + , <&pro_micro 14 GPIO_ACTIVE_HIGH> + , <&pro_micro 15 GPIO_ACTIVE_HIGH> + , <&pro_micro 0 GPIO_ACTIVE_HIGH> + , <&pro_micro 1 GPIO_ACTIVE_HIGH> + , <&pro_micro 2 GPIO_ACTIVE_HIGH> + ; +}; + +&right_encoder { + status = "okay"; +}; diff --git a/app/cmake/zmk_config.cmake b/app/cmake/zmk_config.cmake index 145352a3..dec31104 100644 --- a/app/cmake/zmk_config.cmake +++ b/app/cmake/zmk_config.cmake @@ -61,13 +61,16 @@ foreach(root ${BOARD_ROOT}) if (EXISTS "${root}/boards/${BOARD}.overlay") list(APPEND ZMK_DTC_FILES "${root}/boards/${BOARD}.overlay") endif() - find_path(BOARD_DIR - NAMES ${BOARD}_defconfig - PATHS ${root}/boards/*/* - NO_DEFAULT_PATH - ) - if(BOARD_DIR) - list(APPEND KEYMAP_DIRS ${BOARD_DIR}) + if (NOT DEFINED BOARD_DIR_NAME) + find_path(BOARD_DIR + NAMES ${BOARD}_defconfig + PATHS ${root}/boards/*/* + NO_DEFAULT_PATH + ) + if(BOARD_DIR) + get_filename_component(BOARD_DIR_NAME ${BOARD_DIR} NAME) + list(APPEND KEYMAP_DIRS ${BOARD_DIR}) + endif() endif() if(DEFINED SHIELD) @@ -130,7 +133,7 @@ endif() if(NOT KEYMAP_FILE) foreach(keymap_dir ${KEYMAP_DIRS}) - foreach(keymap_prefix ${SHIELD} ${SHIELD_DIR} ${BOARD} ${BOARD_DIR}) + foreach(keymap_prefix ${SHIELD} ${SHIELD_DIR} ${BOARD} ${BOARD_DIR_NAME}) if (EXISTS ${keymap_dir}/${keymap_prefix}.keymap) set(KEYMAP_FILE "${keymap_dir}/${keymap_prefix}.keymap" CACHE STRING "Selected keymap file") message(STATUS "Using keymap file: ${KEYMAP_FILE}") diff --git a/app/drivers/kscan/CMakeLists.txt b/app/drivers/kscan/CMakeLists.txt index b5f86abd..c19fa431 100644 --- a/app/drivers/kscan/CMakeLists.txt +++ b/app/drivers/kscan/CMakeLists.txt @@ -4,6 +4,7 @@ zephyr_library_named(zmk__drivers__kscan) zephyr_library_include_directories(${CMAKE_SOURCE_DIR}/include) +zephyr_library_sources_ifdef(CONFIG_ZMK_KSCAN_GPIO_DRIVER debounce.c) zephyr_library_sources_ifdef(CONFIG_ZMK_KSCAN_GPIO_DRIVER kscan_gpio_matrix.c) zephyr_library_sources_ifdef(CONFIG_ZMK_KSCAN_GPIO_DRIVER kscan_gpio_direct.c) zephyr_library_sources_ifdef(CONFIG_ZMK_KSCAN_GPIO_DRIVER kscan_gpio_demux.c) diff --git a/app/drivers/kscan/Kconfig b/app/drivers/kscan/Kconfig index 555b7b98..3ffec09c 100644 --- a/app/drivers/kscan/Kconfig +++ b/app/drivers/kscan/Kconfig @@ -14,6 +14,24 @@ config ZMK_KSCAN_MATRIX_POLLING config ZMK_KSCAN_DIRECT_POLLING bool "Poll for key event triggers instead of using interrupts on direct wired boards." +config ZMK_KSCAN_DEBOUNCE_PRESS_MS + int "Debounce time for key press in milliseconds." + default -1 + help + Global debounce time for key press in milliseconds. + If this is -1, the debounce time is controlled by the debounce-press-ms + Devicetree property, which defaults to 5 ms. Otherwise this overrides the + debounce time for all key scan drivers to the chosen value. + +config ZMK_KSCAN_DEBOUNCE_RELEASE_MS + int "Debounce time for key release in milliseconds." + default -1 + help + Global debounce time for key release in milliseconds. + If this is -1, the debounce time is controlled by the debounce-release-ms + Devicetree property, which defaults to 5 ms. Otherwise this overrides the + debounce time for all key scan drivers to the chosen value. + endif config ZMK_KSCAN_INIT_PRIORITY diff --git a/app/drivers/kscan/debounce.c b/app/drivers/kscan/debounce.c new file mode 100644 index 00000000..b3878226 --- /dev/null +++ b/app/drivers/kscan/debounce.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include "debounce.h" + +static uint32_t get_threshold(const struct debounce_state *state, + const struct debounce_config *config) { + return state->pressed ? config->debounce_release_ms : config->debounce_press_ms; +} + +static void increment_counter(struct debounce_state *state, const int elapsed_ms) { + if (state->counter + elapsed_ms > DEBOUNCE_COUNTER_MAX) { + state->counter = DEBOUNCE_COUNTER_MAX; + } else { + state->counter += elapsed_ms; + } +} + +static void decrement_counter(struct debounce_state *state, const int elapsed_ms) { + if (state->counter < elapsed_ms) { + state->counter = 0; + } else { + state->counter -= elapsed_ms; + } +} + +void debounce_update(struct debounce_state *state, const bool active, const int elapsed_ms, + const struct debounce_config *config) { + // This uses a variation of the integrator debouncing described at + // https://www.kennethkuhn.com/electronics/debounce.c + // Every update where "active" does not match the current state, we increment + // a counter, otherwise we decrement it. When the counter reaches a + // threshold, the state flips and we reset the counter. + state->changed = false; + + if (active == state->pressed) { + decrement_counter(state, elapsed_ms); + return; + } + + const uint32_t flip_threshold = get_threshold(state, config); + + if (state->counter < flip_threshold) { + increment_counter(state, elapsed_ms); + return; + } + + state->pressed = !state->pressed; + state->counter = 0; + state->changed = true; +} + +bool debounce_is_active(const struct debounce_state *state) { + return state->pressed || state->counter > 0; +} + +bool debounce_is_pressed(const struct debounce_state *state) { return state->pressed; } + +bool debounce_get_changed(const struct debounce_state *state) { return state->changed; } \ No newline at end of file diff --git a/app/drivers/kscan/debounce.h b/app/drivers/kscan/debounce.h new file mode 100644 index 00000000..9fa4531b --- /dev/null +++ b/app/drivers/kscan/debounce.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include +#include +#include + +#define DEBOUNCE_COUNTER_BITS 14 +#define DEBOUNCE_COUNTER_MAX BIT_MASK(DEBOUNCE_COUNTER_BITS) + +struct debounce_state { + bool pressed : 1; + bool changed : 1; + uint16_t counter : DEBOUNCE_COUNTER_BITS; +}; + +struct debounce_config { + /** Duration a switch must be pressed to latch as pressed. */ + uint32_t debounce_press_ms; + /** Duration a switch must be released to latch as released. */ + uint32_t debounce_release_ms; +}; + +/** + * Debounces one switch. + * + * @param state The state for the switch to debounce. + * @param active Is the switch currently pressed? + * @param elapsed_ms Time elapsed since the previous update in milliseconds. + * @param config Debounce settings. + */ +void debounce_update(struct debounce_state *state, const bool active, const int elapsed_ms, + const struct debounce_config *config); + +/** + * @returns whether the switch is either latched as pressed or it is potentially + * pressed but the debouncer has not yet made a decision. If this returns true, + * the kscan driver should continue to poll quickly. + */ +bool debounce_is_active(const struct debounce_state *state); + +/** + * @returns whether the switch is latched as pressed. + */ +bool debounce_is_pressed(const struct debounce_state *state); + +/** + * @returns whether the pressed state of the switch changed in the last call to + * debounce_update. + */ +bool debounce_get_changed(const struct debounce_state *state); diff --git a/app/drivers/kscan/kscan_gpio_matrix.c b/app/drivers/kscan/kscan_gpio_matrix.c index 5465dd30..e5a7e562 100644 --- a/app/drivers/kscan/kscan_gpio_matrix.c +++ b/app/drivers/kscan/kscan_gpio_matrix.c @@ -4,10 +4,13 @@ * SPDX-License-Identifier: MIT */ +#include "debounce.h" + #include #include #include #include +#include #include #include #include @@ -27,6 +30,20 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #define INST_MATRIX_LEN(n) (INST_ROWS_LEN(n) * INST_COLS_LEN(n)) #define INST_INPUTS_LEN(n) COND_DIODE_DIR(n, (INST_COLS_LEN(n)), (INST_ROWS_LEN(n))) +#if CONFIG_ZMK_KSCAN_DEBOUNCE_PRESS_MS >= 0 +#define INST_DEBOUNCE_PRESS_MS(n) CONFIG_ZMK_KSCAN_DEBOUNCE_PRESS_MS +#else +#define INST_DEBOUNCE_PRESS_MS(n) \ + DT_INST_PROP_OR(n, debounce_period, DT_INST_PROP(n, debounce_press_ms)) +#endif + +#if CONFIG_ZMK_KSCAN_DEBOUNCE_RELEASE_MS >= 0 +#define INST_DEBOUNCE_RELEASE_MS(n) CONFIG_ZMK_KSCAN_DEBOUNCE_RELEASE_MS +#else +#define INST_DEBOUNCE_RELEASE_MS(n) \ + DT_INST_PROP_OR(n, debounce_period, DT_INST_PROP(n, debounce_release_ms)) +#endif + #define USE_POLLING IS_ENABLED(CONFIG_ZMK_KSCAN_MATRIX_POLLING) #define USE_INTERRUPTS (!USE_POLLING) @@ -66,26 +83,23 @@ enum kscan_diode_direction { struct kscan_matrix_irq_callback { const struct device *dev; struct gpio_callback callback; - struct k_delayed_work *work; }; struct kscan_matrix_data { const struct device *dev; kscan_callback_t callback; struct k_delayed_work work; -#if USE_POLLING - struct k_timer poll_timer; -#else +#if USE_INTERRUPTS /** Array of length config->inputs.len */ struct kscan_matrix_irq_callback *irqs; #endif + /** Timestamp of the current or scheduled scan. */ + int64_t scan_time; /** * Current state of the matrix as a flattened 2D array of length * (config->rows.len * config->cols.len) */ - bool *current_state; - /** Buffer for reading in the next matrix state. Parallel array to current_state. */ - bool *next_state; + struct debounce_state *matrix_state; }; struct kscan_gpio_list { @@ -102,7 +116,8 @@ struct kscan_matrix_config { struct kscan_gpio_list cols; struct kscan_gpio_list inputs; struct kscan_gpio_list outputs; - int32_t debounce_period_ms; + struct debounce_config debounce_config; + int32_t debounce_scan_period_ms; int32_t poll_period_ms; enum kscan_diode_direction diode_direction; }; @@ -190,19 +205,49 @@ static int kscan_matrix_interrupt_disable(const struct device *dev) { #if USE_INTERRUPTS static void kscan_matrix_irq_callback_handler(const struct device *port, struct gpio_callback *cb, const gpio_port_pins_t pin) { - struct kscan_matrix_irq_callback *data = + struct kscan_matrix_irq_callback *irq_data = CONTAINER_OF(cb, struct kscan_matrix_irq_callback, callback); - const struct kscan_matrix_config *config = data->dev->config; + struct kscan_matrix_data *data = irq_data->dev->data; // Disable our interrupts temporarily to avoid re-entry while we scan. kscan_matrix_interrupt_disable(data->dev); + data->scan_time = k_uptime_get(); + // TODO (Zephyr 2.6): use k_work_reschedule() - k_delayed_work_cancel(data->work); - k_delayed_work_submit(data->work, K_MSEC(config->debounce_period_ms)); + k_delayed_work_cancel(&data->work); + k_delayed_work_submit(&data->work, K_NO_WAIT); } #endif +static void kscan_matrix_read_continue(const struct device *dev) { + const struct kscan_matrix_config *config = dev->config; + struct kscan_matrix_data *data = dev->data; + + data->scan_time += config->debounce_scan_period_ms; + + // TODO (Zephyr 2.6): use k_work_reschedule() + k_delayed_work_cancel(&data->work); + k_delayed_work_submit(&data->work, K_TIMEOUT_ABS_MS(data->scan_time)); +} + +static void kscan_matrix_read_end(const struct device *dev) { +#if USE_INTERRUPTS + // Return to waiting for an interrupt. + kscan_matrix_interrupt_enable(dev); +#else + struct kscan_matrix_data *data = dev->data; + const struct kscan_matrix_config *config = dev->config; + + data->scan_time += config->poll_period_ms; + + // Return to polling slowly. + // TODO (Zephyr 2.6): use k_work_reschedule() + k_delayed_work_cancel(&data->work); + k_delayed_work_submit(&data->work, K_TIMEOUT_ABS_MS(data->scan_time)); +#endif +} + static int kscan_matrix_read(const struct device *dev) { struct kscan_matrix_data *data = dev->data; const struct kscan_matrix_config *config = dev->config; @@ -221,7 +266,10 @@ static int kscan_matrix_read(const struct device *dev) { const struct kscan_gpio_dt_spec *in_gpio = &config->inputs.gpios[i]; const int index = state_index_io(config, i, o); - data->next_state[index] = gpio_pin_get(in_gpio->port, in_gpio->pin); + const bool active = gpio_pin_get(in_gpio->port, in_gpio->pin); + + debounce_update(&data->matrix_state[index], active, config->debounce_scan_period_ms, + &config->debounce_config); } err = gpio_pin_set(out_gpio->port, out_gpio->pin, 0); @@ -232,50 +280,36 @@ static int kscan_matrix_read(const struct device *dev) { } // Process the new state. -#if USE_INTERRUPTS - bool submit_followup_read = false; -#endif + bool continue_scan = false; for (int r = 0; r < config->rows.len; r++) { for (int c = 0; c < config->cols.len; c++) { const int index = state_index_rc(config, r, c); - const bool pressed = data->next_state[index]; + struct debounce_state *state = &data->matrix_state[index]; + + if (debounce_get_changed(state)) { + const bool pressed = debounce_is_pressed(state); - // Follow up reads are needed if any key is pressed because further - // interrupts won't fire on already tripped GPIO pins. -#if USE_INTERRUPTS - submit_followup_read = submit_followup_read || pressed; -#endif - if (pressed != data->current_state[index]) { LOG_DBG("Sending event at %i,%i state %s", r, c, pressed ? "on" : "off"); - data->current_state[index] = pressed; data->callback(dev, r, c, pressed); } + + continue_scan = continue_scan || debounce_is_active(state); } } -#if USE_INTERRUPTS - if (submit_followup_read) { - // At least one key is pressed. Poll until everything is released. - // TODO (Zephyr 2.6): use k_work_reschedule() - k_delayed_work_cancel(&data->work); - k_delayed_work_submit(&data->work, K_MSEC(config->debounce_period_ms)); + if (continue_scan) { + // At least one key is pressed or the debouncer has not yet decided if + // it is pressed. Poll quickly until everything is released. + kscan_matrix_read_continue(dev); } else { - // All keys are released. Return to waiting for an interrupt. - kscan_matrix_interrupt_enable(dev); + // All keys are released. Return to normal. + kscan_matrix_read_end(dev); } -#endif return 0; } -#if USE_POLLING -static void kscan_matrix_timer_handler(struct k_timer *timer) { - struct kscan_matrix_data *data = CONTAINER_OF(timer, struct kscan_matrix_data, poll_timer); - k_delayed_work_submit(&data->work, K_NO_WAIT); -} -#endif - static void kscan_matrix_work_handler(struct k_work *work) { struct k_delayed_work *dwork = CONTAINER_OF(work, struct k_delayed_work, work); struct kscan_matrix_data *data = CONTAINER_OF(dwork, struct kscan_matrix_data, work); @@ -294,27 +328,23 @@ static int kscan_matrix_configure(const struct device *dev, const kscan_callback } static int kscan_matrix_enable(const struct device *dev) { -#if USE_POLLING struct kscan_matrix_data *data = dev->data; - const struct kscan_matrix_config *config = dev->config; - k_timer_start(&data->poll_timer, K_MSEC(config->poll_period_ms), - K_MSEC(config->poll_period_ms)); - return 0; -#else - // Read will automatically enable interrupts once done. + data->scan_time = k_uptime_get(); + + // Read will automatically start interrupts/polling once done. return kscan_matrix_read(dev); -#endif } static int kscan_matrix_disable(const struct device *dev) { -#if USE_POLLING struct kscan_matrix_data *data = dev->data; - k_timer_stop(&data->poll_timer); - return 0; -#else + k_delayed_work_cancel(&data->work); + +#if USE_INTERRUPTS return kscan_matrix_interrupt_disable(dev); +#else + return 0; #endif } @@ -338,7 +368,6 @@ static int kscan_matrix_init_input_inst(const struct device *dev, struct kscan_matrix_irq_callback *irq = &data->irqs[index]; irq->dev = dev; - irq->work = &data->work; gpio_init_callback(&irq->callback, kscan_matrix_irq_callback_handler, BIT(gpio->pin)); err = gpio_add_callback(gpio->port, &irq->callback); if (err) { @@ -407,10 +436,6 @@ static int kscan_matrix_init(const struct device *dev) { k_delayed_work_init(&data->work, kscan_matrix_work_handler); -#if USE_POLLING - k_timer_init(&data->poll_timer, kscan_matrix_timer_handler, NULL); -#endif - return 0; } @@ -421,21 +446,24 @@ static const struct kscan_driver_api kscan_matrix_api = { }; #define KSCAN_MATRIX_INIT(index) \ + BUILD_ASSERT(INST_DEBOUNCE_PRESS_MS(index) <= DEBOUNCE_COUNTER_MAX, \ + "ZMK_KSCAN_DEBOUNCE_PRESS_MS or debounce-press-ms is too large"); \ + BUILD_ASSERT(INST_DEBOUNCE_RELEASE_MS(index) <= DEBOUNCE_COUNTER_MAX, \ + "ZMK_KSCAN_DEBOUNCE_RELEASE_MS or debounce-release-ms is too large"); \ + \ static const struct kscan_gpio_dt_spec kscan_matrix_rows_##index[] = { \ UTIL_LISTIFY(INST_ROWS_LEN(index), KSCAN_GPIO_ROW_CFG_INIT, index)}; \ \ static const struct kscan_gpio_dt_spec kscan_matrix_cols_##index[] = { \ UTIL_LISTIFY(INST_COLS_LEN(index), KSCAN_GPIO_COL_CFG_INIT, index)}; \ \ - static bool kscan_current_state_##index[INST_MATRIX_LEN(index)]; \ - static bool kscan_next_state_##index[INST_MATRIX_LEN(index)]; \ + static struct debounce_state kscan_matrix_state_##index[INST_MATRIX_LEN(index)]; \ \ COND_INTERRUPTS((static struct kscan_matrix_irq_callback \ kscan_matrix_irqs_##index[INST_INPUTS_LEN(index)];)) \ \ static struct kscan_matrix_data kscan_matrix_data_##index = { \ - .current_state = kscan_current_state_##index, \ - .next_state = kscan_next_state_##index, \ + .matrix_state = kscan_matrix_state_##index, \ COND_INTERRUPTS((.irqs = kscan_matrix_irqs_##index, ))}; \ \ static struct kscan_matrix_config kscan_matrix_config_##index = { \ @@ -445,7 +473,12 @@ static const struct kscan_driver_api kscan_matrix_api = { COND_DIODE_DIR(index, (kscan_matrix_cols_##index), (kscan_matrix_rows_##index))), \ .outputs = KSCAN_GPIO_LIST( \ COND_DIODE_DIR(index, (kscan_matrix_rows_##index), (kscan_matrix_cols_##index))), \ - .debounce_period_ms = DT_INST_PROP(index, debounce_period), \ + .debounce_config = \ + { \ + .debounce_press_ms = INST_DEBOUNCE_PRESS_MS(index), \ + .debounce_release_ms = INST_DEBOUNCE_RELEASE_MS(index), \ + }, \ + .debounce_scan_period_ms = DT_INST_PROP(index, debounce_scan_period_ms), \ .poll_period_ms = DT_INST_PROP(index, poll_period_ms), \ .diode_direction = INST_DIODE_DIR(index), \ }; \ diff --git a/app/drivers/zephyr/dts/bindings/kscan/zmk,kscan-gpio-matrix.yaml b/app/drivers/zephyr/dts/bindings/kscan/zmk,kscan-gpio-matrix.yaml index 20ee4ac5..2ec6dc6c 100644 --- a/app/drivers/zephyr/dts/bindings/kscan/zmk,kscan-gpio-matrix.yaml +++ b/app/drivers/zephyr/dts/bindings/kscan/zmk,kscan-gpio-matrix.yaml @@ -15,13 +15,26 @@ properties: type: phandle-array required: true debounce-period: + type: int + required: false + deprecated: true + description: Deprecated. Use debounce-press-ms and debounce-release-ms instead. + debounce-press-ms: type: int default: 5 - description: Debounce time in milliseconds + description: Debounce time for key press in milliseconds. Use 0 for eager debouncing. + debounce-release-ms: + type: int + default: 5 + description: Debounce time for key release in milliseconds. + debounce-scan-period-ms: + type: int + default: 1 + description: Time between reads in milliseconds when any key is pressed. poll-period-ms: type: int default: 10 - description: Time between reads in milliseconds when polling is enabled + description: Time between reads in milliseconds when no key is pressed and ZMK_KSCAN_MATRIX_POLLING is enabled. diode-direction: type: string default: row2col diff --git a/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml b/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml index f46b36a4..09691159 100644 --- a/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml +++ b/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml @@ -28,5 +28,10 @@ properties: - "hold-preferred" - "balanced" - "tap-preferred" + - "tap-unless-interrupted" retro-tap: type: boolean + hold-trigger-key-positions: + type: array + required: false + default: [] diff --git a/app/dts/bindings/zmk,conditional-layers.yaml b/app/dts/bindings/zmk,conditional-layers.yaml new file mode 100644 index 00000000..7e79038e --- /dev/null +++ b/app/dts/bindings/zmk,conditional-layers.yaml @@ -0,0 +1,17 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +description: Conditional layers allow layer combinations to trigger additional layers + +compatible: "zmk,conditional-layers" + +child-binding: + description: "Single conditional layer that activates then-layer when if-layers are active" + + properties: + if-layers: + type: array + required: true + then-layer: + type: int + required: true diff --git a/app/include/zmk/hid.h b/app/include/zmk/hid.h index 5aa004c2..e23caff9 100644 --- a/app/include/zmk/hid.h +++ b/app/include/zmk/hid.h @@ -13,12 +13,10 @@ #include #include +#define ZMK_HID_KEYBOARD_NKRO_MAX_USAGE HID_USAGE_KEY_KEYPAD_EQUAL + #define COLLECTION_REPORT 0x03 -#define ZMK_HID_KEYBOARD_NKRO_SIZE 6 - -#define ZMK_HID_CONSUMER_NKRO_SIZE 6 - static const uint8_t zmk_hid_report_desc[] = { /* USAGE_PAGE (Generic Desktop) */ HID_GI_USAGE_PAGE, @@ -74,6 +72,30 @@ static const uint8_t zmk_hid_report_desc[] = { /* USAGE_PAGE (Keyboard/Keypad) */ HID_GI_USAGE_PAGE, HID_USAGE_KEY, + +#if IS_ENABLED(CONFIG_ZMK_HID_REPORT_TYPE_NKRO) + /* LOGICAL_MINIMUM (0) */ + HID_GI_LOGICAL_MIN(1), + 0x00, + /* LOGICAL_MAXIMUM (1) */ + HID_GI_LOGICAL_MAX(1), + 0x01, + /* USAGE_MINIMUM (Reserved) */ + HID_LI_USAGE_MIN(1), + 0x00, + /* USAGE_MAXIMUM (Keyboard Application) */ + HID_LI_USAGE_MAX(1), + ZMK_HID_KEYBOARD_NKRO_MAX_USAGE, + /* REPORT_SIZE (8) */ + HID_GI_REPORT_SIZE, + 0x01, + /* REPORT_COUNT (6) */ + HID_GI_REPORT_COUNT, + ZMK_HID_KEYBOARD_NKRO_MAX_USAGE + 1, + /* INPUT (Data,Ary,Abs) */ + HID_MI_INPUT, + 0x02, +#elif IS_ENABLED(CONFIG_ZMK_HID_REPORT_TYPE_HKRO) /* LOGICAL_MINIMUM (0) */ HID_GI_LOGICAL_MIN(1), 0x00, @@ -89,12 +111,15 @@ static const uint8_t zmk_hid_report_desc[] = { /* REPORT_SIZE (1) */ HID_GI_REPORT_SIZE, 0x08, - /* REPORT_COUNT (ZMK_HID_KEYBOARD_NKRO_SIZE) */ + /* REPORT_COUNT (CONFIG_ZMK_HID_KEYBOARD_REPORT_SIZE) */ HID_GI_REPORT_COUNT, - ZMK_HID_KEYBOARD_NKRO_SIZE, + CONFIG_ZMK_HID_KEYBOARD_REPORT_SIZE, /* INPUT (Data,Ary,Abs) */ HID_MI_INPUT, 0x00, +#else +#error "A proper HID report type must be selected" +#endif /* END_COLLECTION */ HID_MI_COLLECTION_END, @@ -113,6 +138,26 @@ static const uint8_t zmk_hid_report_desc[] = { /* USAGE_PAGE (Consumer) */ HID_GI_USAGE_PAGE, HID_USAGE_CONSUMER, + +#if IS_ENABLED(CONFIG_ZMK_HID_CONSUMER_REPORT_USAGES_BASIC) + /* LOGICAL_MINIMUM (0) */ + HID_GI_LOGICAL_MIN(1), + 0x00, + /* LOGICAL_MAXIMUM (0x00FF) - little endian, and requires two bytes because logical max is + signed */ + HID_GI_LOGICAL_MAX(2), + 0xFF, + 0x00, + HID_LI_USAGE_MIN(1), + 0x00, + /* USAGE_MAXIMUM (0xFF) */ + HID_LI_USAGE_MAX(1), + 0xFF, + /* INPUT (Data,Ary,Abs) */ + /* REPORT_SIZE (8) */ + HID_GI_REPORT_SIZE, + 0x08, +#elif IS_ENABLED(CONFIG_ZMK_HID_CONSUMER_REPORT_USAGES_FULL) /* LOGICAL_MINIMUM (0) */ HID_GI_LOGICAL_MIN(1), 0x00, @@ -130,9 +175,12 @@ static const uint8_t zmk_hid_report_desc[] = { /* REPORT_SIZE (16) */ HID_GI_REPORT_SIZE, 0x10, - /* REPORT_COUNT (ZMK_HID_CONSUMER_NKRO_SIZE) */ +#else +#error "A proper consumer HID report usage range must be selected" +#endif + /* REPORT_COUNT (CONFIG_ZMK_HID_CONSUMER_REPORT_SIZE) */ HID_GI_REPORT_COUNT, - ZMK_HID_CONSUMER_NKRO_SIZE, + CONFIG_ZMK_HID_CONSUMER_REPORT_SIZE, HID_MI_INPUT, 0x00, /* END COLLECTION */ @@ -149,7 +197,11 @@ static const uint8_t zmk_hid_report_desc[] = { struct zmk_hid_keyboard_report_body { zmk_mod_flags_t modifiers; uint8_t _reserved; - uint8_t keys[ZMK_HID_KEYBOARD_NKRO_SIZE]; +#if IS_ENABLED(CONFIG_ZMK_HID_REPORT_TYPE_NKRO) + uint8_t keys[(ZMK_HID_KEYBOARD_NKRO_MAX_USAGE + 1) / 8]; +#elif IS_ENABLED(CONFIG_ZMK_HID_REPORT_TYPE_HKRO) + uint8_t keys[CONFIG_ZMK_HID_KEYBOARD_REPORT_SIZE]; +#endif } __packed; struct zmk_hid_keyboard_report { @@ -158,7 +210,11 @@ struct zmk_hid_keyboard_report { } __packed; struct zmk_hid_consumer_report_body { - uint16_t keys[ZMK_HID_CONSUMER_NKRO_SIZE]; +#if IS_ENABLED(CONFIG_ZMK_HID_CONSUMER_REPORT_USAGES_BASIC) + uint8_t keys[CONFIG_ZMK_HID_CONSUMER_REPORT_SIZE]; +#elif IS_ENABLED(CONFIG_ZMK_HID_CONSUMER_REPORT_USAGES_FULL) + uint16_t keys[CONFIG_ZMK_HID_CONSUMER_REPORT_SIZE]; +#endif } __packed; struct zmk_hid_consumer_report { diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index 02ca5e3a..548d6ef8 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -34,6 +34,7 @@ enum flavor { FLAVOR_HOLD_PREFERRED, FLAVOR_BALANCED, FLAVOR_TAP_PREFERRED, + FLAVOR_TAP_UNLESS_INTERRUPTED, }; enum status { @@ -58,6 +59,8 @@ struct behavior_hold_tap_config { int quick_tap_ms; enum flavor flavor; bool retro_tap; + int32_t hold_trigger_key_positions_len; + int32_t hold_trigger_key_positions[]; }; // this data is specific for each hold-tap @@ -70,6 +73,9 @@ struct active_hold_tap { const struct behavior_hold_tap_config *config; struct k_delayed_work work; bool work_is_cancelled; + + // initialized to -1, which is to be interpreted as "no other key has been pressed yet" + int32_t position_of_first_other_key_pressed; }; // The undecided hold tap is the hold tap that needs to be decided before @@ -206,6 +212,7 @@ static struct active_hold_tap *store_hold_tap(uint32_t position, uint32_t param_ active_hold_taps[i].param_hold = param_hold; active_hold_taps[i].param_tap = param_tap; active_hold_taps[i].timestamp = timestamp; + active_hold_taps[i].position_of_first_other_key_pressed = -1; return &active_hold_taps[i]; } return NULL; @@ -252,6 +259,26 @@ static void decide_tap_preferred(struct active_hold_tap *hold_tap, enum decision } } +static void decide_tap_unless_interrupted(struct active_hold_tap *hold_tap, + enum decision_moment event) { + switch (event) { + case HT_KEY_UP: + hold_tap->status = STATUS_TAP; + return; + case HT_OTHER_KEY_DOWN: + hold_tap->status = STATUS_HOLD_INTERRUPT; + return; + case HT_TIMER_EVENT: + hold_tap->status = STATUS_TAP; + return; + case HT_QUICK_TAP: + hold_tap->status = STATUS_TAP; + return; + default: + return; + } +} + static void decide_hold_preferred(struct active_hold_tap *hold_tap, enum decision_moment event) { switch (event) { case HT_KEY_UP: @@ -279,6 +306,8 @@ static inline const char *flavor_str(enum flavor flavor) { return "balanced"; case FLAVOR_TAP_PREFERRED: return "tap-preferred"; + case FLAVOR_TAP_UNLESS_INTERRUPTED: + return "tap-unless-interrupted"; default: return "UNKNOWN FLAVOR"; } @@ -359,6 +388,39 @@ static int release_binding(struct active_hold_tap *hold_tap) { return behavior_keymap_binding_released(&binding, event); } +static bool is_first_other_key_pressed_trigger_key(struct active_hold_tap *hold_tap) { + for (int i = 0; i < hold_tap->config->hold_trigger_key_positions_len; i++) { + if (hold_tap->config->hold_trigger_key_positions[i] == + hold_tap->position_of_first_other_key_pressed) { + return true; + } + } + return false; +} + +// Force a tap decision if the positional conditions for a hold decision are not met. +static void decide_positional_hold(struct active_hold_tap *hold_tap) { + // Only force a tap decision if the positional hold/tap feature is enabled. + if (!(hold_tap->config->hold_trigger_key_positions_len > 0)) { + return; + } + + // Only force a tap decision if another key was pressed after + // the hold/tap key. + if (hold_tap->position_of_first_other_key_pressed == -1) { + return; + } + + // Only force a tap decision if the first other key to be pressed + // (after the hold/tap key) is not one of the trigger keys. + if (is_first_other_key_pressed_trigger_key(hold_tap)) { + return; + } + + // Since the positional key conditions have failed, force a TAP decision. + hold_tap->status = STATUS_TAP; +} + static void decide_hold_tap(struct active_hold_tap *hold_tap, enum decision_moment decision_moment) { if (hold_tap->status != STATUS_UNDECIDED) { @@ -370,19 +432,30 @@ static void decide_hold_tap(struct active_hold_tap *hold_tap, return; } + // If the hold-tap behavior is still undecided, attempt to decide it. switch (hold_tap->config->flavor) { case FLAVOR_HOLD_PREFERRED: decide_hold_preferred(hold_tap, decision_moment); + break; case FLAVOR_BALANCED: decide_balanced(hold_tap, decision_moment); + break; case FLAVOR_TAP_PREFERRED: decide_tap_preferred(hold_tap, decision_moment); + break; + case FLAVOR_TAP_UNLESS_INTERRUPTED: + decide_tap_unless_interrupted(hold_tap, decision_moment); + break; } if (hold_tap->status == STATUS_UNDECIDED) { return; } + decide_positional_hold(hold_tap); + + // Since the hold-tap has been decided, clean up undecided_hold_tap and + // execute the decided behavior. LOG_DBG("%d decided %s (%s decision moment %s)", hold_tap->position, status_str(hold_tap->status), flavor_str(hold_tap->config->flavor), decision_moment_str(decision_moment)); @@ -501,6 +574,14 @@ static int position_state_changed_listener(const zmk_event_t *eh) { return ZMK_EV_EVENT_BUBBLE; } + // Store the position of pressed key for positional hold-tap purposes. + if ((ev->state) // i.e. key pressed (not released) + && (undecided_hold_tap->position_of_first_other_key_pressed == + -1) // i.e. no other key has been pressed yet + ) { + undecided_hold_tap->position_of_first_other_key_pressed = ev->position; + } + if (undecided_hold_tap->position == ev->position) { if (ev->state) { // keydown LOG_ERR("hold-tap listener should be called before before most other listeners!"); @@ -604,6 +685,8 @@ static struct behavior_hold_tap_data behavior_hold_tap_data; .quick_tap_ms = DT_INST_PROP(n, quick_tap_ms), \ .flavor = DT_ENUM_IDX(DT_DRV_INST(n), flavor), \ .retro_tap = DT_INST_PROP(n, retro_tap), \ + .hold_trigger_key_positions = DT_INST_PROP(n, hold_trigger_key_positions), \ + .hold_trigger_key_positions_len = DT_INST_PROP_LEN(n, hold_trigger_key_positions), \ }; \ DEVICE_DT_INST_DEFINE(n, behavior_hold_tap_init, device_pm_control_nop, \ &behavior_hold_tap_data, &behavior_hold_tap_config_##n, APPLICATION, \ diff --git a/app/src/combo.c b/app/src/combo.c index 16091cdd..bcdaac01 100644 --- a/app/src/combo.c +++ b/app/src/combo.c @@ -469,22 +469,12 @@ static int position_state_changed_listener(const zmk_event_t *ev) { ZMK_LISTENER(combo, position_state_changed_listener); ZMK_SUBSCRIPTION(combo, zmk_position_state_changed); -// todo: remove this once #506 is merged and #include -#define KEY_BINDING_TO_STRUCT(idx, drv_inst) \ - { \ - .behavior_dev = DT_LABEL(DT_PHANDLE_BY_IDX(drv_inst, bindings, idx)), \ - .param1 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(drv_inst, bindings, idx, param1), (0), \ - (DT_PHA_BY_IDX(drv_inst, bindings, idx, param1))), \ - .param2 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(drv_inst, bindings, idx, param2), (0), \ - (DT_PHA_BY_IDX(drv_inst, bindings, idx, param2))), \ - } - #define COMBO_INST(n) \ static struct combo_cfg combo_config_##n = { \ .timeout_ms = DT_PROP(n, timeout_ms), \ .key_positions = DT_PROP(n, key_positions), \ .key_position_len = DT_PROP_LEN(n, key_positions), \ - .behavior = KEY_BINDING_TO_STRUCT(0, n), \ + .behavior = ZMK_KEYMAP_EXTRACT_BINDING(0, n), \ .virtual_key_position = ZMK_KEYMAP_LEN + __COUNTER__, \ .slow_release = DT_PROP(n, slow_release), \ .layers = DT_PROP(n, layers), \ diff --git a/app/src/conditional_layer.c b/app/src/conditional_layer.c new file mode 100644 index 00000000..4beb87e3 --- /dev/null +++ b/app/src/conditional_layer.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#define DT_DRV_COMPAT zmk_conditional_layers + +#include + +#include +#include + +#include +#include +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) + +// Conditional layer configuration that activates the specified then-layer when all if-layers are +// active. With two if-layers, this is referred to as "tri-layer", and is commonly used to activate +// a third "adjust" layer if and only if the "lower" and "raise" layers are both active. +struct conditional_layer_cfg { + // A bitmask of each layer that must be pressed for this conditional layer config to activate. + zmk_keymap_layers_state_t if_layers_state_mask; + + // The layer number that should be active while all layers in the if-layers mask are active. + int8_t then_layer; +}; + +#define IF_LAYER_BIT(i, n) BIT(DT_PROP_BY_IDX(n, if_layers, i)) | + +// Evaluates to conditional_layer_cfg struct initializer. +#define CONDITIONAL_LAYER_DECL(n) \ + { \ + /* TODO: Replace UTIL_LISTIFY with DT_FOREACH_PROP_ELEM after Zepyhr 2.6.0 upgrade. */ \ + .if_layers_state_mask = UTIL_LISTIFY(DT_PROP_LEN(n, if_layers), IF_LAYER_BIT, n) 0, \ + .then_layer = DT_PROP(n, then_layer), \ + }, + +// All conditional layer configurations in the keymap. +static const struct conditional_layer_cfg CONDITIONAL_LAYER_CFGS[] = { + DT_INST_FOREACH_CHILD(0, CONDITIONAL_LAYER_DECL)}; + +static const int32_t NUM_CONDITIONAL_LAYER_CFGS = + sizeof(CONDITIONAL_LAYER_CFGS) / sizeof(*CONDITIONAL_LAYER_CFGS); + +static void conditional_layer_activate(int8_t layer) { + // This may trigger another event that could, in turn, activate additional then-layers. However, + // the process will eventually terminate (at worst, when every layer is active). + if (!zmk_keymap_layer_active(layer)) { + LOG_DBG("layer %d", layer); + zmk_keymap_layer_activate(layer); + } +} + +static void conditional_layer_deactivate(int8_t layer) { + // This may deactivate a then-layer that's already active via another mechanism (e.g., a + // momentary layer behavior). However, the same problem arises when multiple keys with the same + // &mo binding are held and then one is released, so it's probably not an issue in practice. + if (zmk_keymap_layer_active(layer)) { + LOG_DBG("layer %d", layer); + zmk_keymap_layer_deactivate(layer); + } +} + +// On layer state changes, examines each conditional layer config to determine if then-layer in the +// config should activate based on the currently active set of if-layers. +static int layer_state_changed_listener(const zmk_event_t *ev) { + for (int i = 0; i < NUM_CONDITIONAL_LAYER_CFGS; i++) { + const struct conditional_layer_cfg *cfg = CONDITIONAL_LAYER_CFGS + i; + zmk_keymap_layers_state_t mask = cfg->if_layers_state_mask; + + // Activate then-layer if and only if all if-layers are already active. Note that we + // reevaluate the current layer state for each config since activation of one layer can also + // trigger activation of another. + if ((zmk_keymap_layer_state() & mask) == mask) { + conditional_layer_activate(cfg->then_layer); + } else { + conditional_layer_deactivate(cfg->then_layer); + } + } + return 0; +} + +ZMK_LISTENER(conditional_layer, layer_state_changed_listener); +ZMK_SUBSCRIPTION(conditional_layer, zmk_layer_state_changed); + +#endif diff --git a/app/src/display/widgets/output_status.c b/app/src/display/widgets/output_status.c index 4c32faea..89993c69 100644 --- a/app/src/display/widgets/output_status.c +++ b/app/src/display/widgets/output_status.c @@ -39,7 +39,7 @@ static struct output_status_state get_state(const zmk_event_t *_eh) { } static void set_status_symbol(lv_obj_t *label, struct output_status_state state) { - char text[6] = {}; + char text[9] = {}; switch (state.selected_endpoint) { case ZMK_ENDPOINT_USB: diff --git a/app/src/hid.c b/app/src/hid.c index 7ab080e5..b524b09f 100644 --- a/app/src/hid.c +++ b/app/src/hid.c @@ -69,8 +69,30 @@ int zmk_hid_unregister_mods(zmk_mod_flags_t modifiers) { return 0; } +#if IS_ENABLED(CONFIG_ZMK_HID_REPORT_TYPE_NKRO) + +#define TOGGLE_KEYBOARD(code, val) WRITE_BIT(keyboard_report.body.keys[code / 8], code % 8, val) + +static inline int select_keyboard_usage(zmk_key_t usage) { + if (usage > ZMK_HID_KEYBOARD_NKRO_MAX_USAGE) { + return -EINVAL; + } + TOGGLE_KEYBOARD(usage, 1); + return 0; +} + +static inline int deselect_keyboard_usage(zmk_key_t usage) { + if (usage > ZMK_HID_KEYBOARD_NKRO_MAX_USAGE) { + return -EINVAL; + } + TOGGLE_KEYBOARD(usage, 0); + return 0; +} + +#elif IS_ENABLED(CONFIG_ZMK_HID_REPORT_TYPE_HKRO) + #define TOGGLE_KEYBOARD(match, val) \ - for (int idx = 0; idx < ZMK_HID_KEYBOARD_NKRO_SIZE; idx++) { \ + for (int idx = 0; idx < CONFIG_ZMK_HID_KEYBOARD_REPORT_SIZE; idx++) { \ if (keyboard_report.body.keys[idx] != match) { \ continue; \ } \ @@ -80,8 +102,24 @@ int zmk_hid_unregister_mods(zmk_mod_flags_t modifiers) { } \ } +static inline int select_keyboard_usage(zmk_key_t usage) { + TOGGLE_KEYBOARD(0U, usage); + return 0; +} + +static inline int deselect_keyboard_usage(zmk_key_t usage) { + TOGGLE_KEYBOARD(usage, 0U); + return 0; +} + +#else +#error "A proper HID report type must be selected" +#endif + #define TOGGLE_CONSUMER(match, val) \ - for (int idx = 0; idx < ZMK_HID_CONSUMER_NKRO_SIZE; idx++) { \ + COND_CODE_1(IS_ENABLED(CONFIG_ZMK_HID_CONSUMER_REPORT_USAGES_BASIC), \ + (if (val > 0xFF) { return -ENOTSUP; }), ()) \ + for (int idx = 0; idx < CONFIG_ZMK_HID_CONSUMER_REPORT_SIZE; idx++) { \ if (consumer_report.body.keys[idx] != match) { \ continue; \ } \ @@ -105,7 +143,7 @@ int zmk_hid_keyboard_press(zmk_key_t code) { if (code >= HID_USAGE_KEY_KEYBOARD_LEFTCONTROL && code <= HID_USAGE_KEY_KEYBOARD_RIGHT_GUI) { return zmk_hid_register_mod(code - HID_USAGE_KEY_KEYBOARD_LEFTCONTROL); } - TOGGLE_KEYBOARD(0U, code); + select_keyboard_usage(code); return 0; }; @@ -113,7 +151,7 @@ int zmk_hid_keyboard_release(zmk_key_t code) { if (code >= HID_USAGE_KEY_KEYBOARD_LEFTCONTROL && code <= HID_USAGE_KEY_KEYBOARD_RIGHT_GUI) { return zmk_hid_unregister_mod(code - HID_USAGE_KEY_KEYBOARD_LEFTCONTROL); } - TOGGLE_KEYBOARD(code, 0U); + deselect_keyboard_usage(code); return 0; }; diff --git a/app/src/rgb_underglow.c b/app/src/rgb_underglow.c index 5f38aba7..40d99c7d 100644 --- a/app/src/rgb_underglow.c +++ b/app/src/rgb_underglow.c @@ -28,6 +28,9 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #define SAT_MAX 100 #define BRT_MAX 100 +BUILD_ASSERT(CONFIG_ZMK_RGB_UNDERGLOW_BRT_MIN <= CONFIG_ZMK_RGB_UNDERGLOW_BRT_MAX, + "ERROR: RGB underglow maximum brightness is less than minimum brightness"); + enum rgb_underglow_effect { UNDERGLOW_EFFECT_SOLID, UNDERGLOW_EFFECT_BREATHE, @@ -54,6 +57,17 @@ static struct rgb_underglow_state state; static const struct device *ext_power; #endif +static struct zmk_led_hsb hsb_scale_min_max(struct zmk_led_hsb hsb) { + hsb.b = CONFIG_ZMK_RGB_UNDERGLOW_BRT_MIN + + (CONFIG_ZMK_RGB_UNDERGLOW_BRT_MAX - CONFIG_ZMK_RGB_UNDERGLOW_BRT_MIN) * hsb.b / BRT_MAX; + return hsb; +} + +static struct zmk_led_hsb hsb_scale_zero_max(struct zmk_led_hsb hsb) { + hsb.b = hsb.b * CONFIG_ZMK_RGB_UNDERGLOW_BRT_MAX / BRT_MAX; + return hsb; +} + static struct led_rgb hsb_to_rgb(struct zmk_led_hsb hsb) { double r, g, b; @@ -105,7 +119,7 @@ static struct led_rgb hsb_to_rgb(struct zmk_led_hsb hsb) { static void zmk_rgb_underglow_effect_solid() { for (int i = 0; i < STRIP_NUM_PIXELS; i++) { - pixels[i] = hsb_to_rgb(state.color); + pixels[i] = hsb_to_rgb(hsb_scale_min_max(state.color)); } } @@ -114,7 +128,7 @@ static void zmk_rgb_underglow_effect_breathe() { struct zmk_led_hsb hsb = state.color; hsb.b = abs(state.animation_step - 1200) / 12; - pixels[i] = hsb_to_rgb(hsb); + pixels[i] = hsb_to_rgb(hsb_scale_zero_max(hsb)); } state.animation_step += state.animation_speed * 10; @@ -129,7 +143,7 @@ static void zmk_rgb_underglow_effect_spectrum() { struct zmk_led_hsb hsb = state.color; hsb.h = state.animation_step; - pixels[i] = hsb_to_rgb(hsb); + pixels[i] = hsb_to_rgb(hsb_scale_min_max(hsb)); } state.animation_step += state.animation_speed; @@ -141,7 +155,7 @@ static void zmk_rgb_underglow_effect_swirl() { struct zmk_led_hsb hsb = state.color; hsb.h = (HUE_MAX / STRIP_NUM_PIXELS * i + state.animation_step) % HUE_MAX; - pixels[i] = hsb_to_rgb(hsb); + pixels[i] = hsb_to_rgb(hsb_scale_min_max(hsb)); } state.animation_step += state.animation_speed * 2; @@ -371,12 +385,7 @@ struct zmk_led_hsb zmk_rgb_underglow_calc_brt(int direction) { struct zmk_led_hsb color = state.color; int b = color.b + (direction * CONFIG_ZMK_RGB_UNDERGLOW_BRT_STEP); - if (b < 0) { - b = 0; - } else if (b > BRT_MAX) { - b = BRT_MAX; - } - color.b = b; + color.b = CLAMP(b, 0, BRT_MAX); return color; } diff --git a/app/src/split/bluetooth/central.c b/app/src/split/bluetooth/central.c index a56b0b81..9a7f01b2 100644 --- a/app/src/split/bluetooth/central.c +++ b/app/src/split/bluetooth/central.c @@ -29,9 +29,10 @@ static int start_scan(void); static struct bt_conn *default_conn; -static struct bt_uuid_128 uuid = BT_UUID_INIT_128(ZMK_SPLIT_BT_SERVICE_UUID); +static const struct bt_uuid_128 split_service_uuid = BT_UUID_INIT_128(ZMK_SPLIT_BT_SERVICE_UUID); static struct bt_gatt_discover_params discover_params; static struct bt_gatt_subscribe_params subscribe_params; +static struct bt_gatt_discover_params sub_discover_params; K_MSGQ_DEFINE(peripheral_event_msgq, sizeof(struct zmk_position_state_changed), CONFIG_ZMK_SPLIT_BLE_CENTRAL_POSITION_QUEUE_SIZE, 4); @@ -83,15 +84,12 @@ static uint8_t split_central_notify_func(struct bt_conn *conn, return BT_GATT_ITER_CONTINUE; } -static int split_central_subscribe(struct bt_conn *conn) { +static void split_central_subscribe(struct bt_conn *conn) { int err = bt_gatt_subscribe(conn, &subscribe_params); switch (err) { case -EALREADY: LOG_DBG("[ALREADY SUBSCRIBED]"); break; - // break; - // bt_gatt_unsubscribe(conn, &subscribe_params); - // return split_central_subscribe(conn); case 0: LOG_DBG("[SUBSCRIBED]"); break; @@ -99,14 +97,44 @@ static int split_central_subscribe(struct bt_conn *conn) { LOG_ERR("Subscribe failed (err %d)", err); break; } - - return 0; } -static uint8_t split_central_discovery_func(struct bt_conn *conn, const struct bt_gatt_attr *attr, - struct bt_gatt_discover_params *params) { - int err; +static uint8_t split_central_chrc_discovery_func(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + struct bt_gatt_discover_params *params) { + if (!attr) { + LOG_DBG("Discover complete"); + return BT_GATT_ITER_STOP; + } + if (!attr->user_data) { + LOG_ERR("Required user data not passed to discovery"); + return BT_GATT_ITER_STOP; + } + + LOG_DBG("[ATTRIBUTE] handle %u", attr->handle); + + if (!bt_uuid_cmp(((struct bt_gatt_chrc *)attr->user_data)->uuid, + BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_POSITION_STATE_UUID))) { + LOG_DBG("Found position state characteristic"); + discover_params.uuid = NULL; + discover_params.start_handle = attr->handle + 2; + discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC; + + subscribe_params.disc_params = &sub_discover_params; + subscribe_params.end_handle = discover_params.end_handle; + subscribe_params.value_handle = bt_gatt_attr_value_handle(attr); + subscribe_params.notify = split_central_notify_func; + subscribe_params.value = BT_GATT_CCC_NOTIFY; + split_central_subscribe(conn); + } + + return subscribe_params.value_handle ? BT_GATT_ITER_STOP : BT_GATT_ITER_CONTINUE; +} + +static uint8_t split_central_service_discovery_func(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + struct bt_gatt_discover_params *params) { if (!attr) { LOG_DBG("Discover complete"); (void)memset(params, 0, sizeof(*params)); @@ -115,38 +143,21 @@ static uint8_t split_central_discovery_func(struct bt_conn *conn, const struct b LOG_DBG("[ATTRIBUTE] handle %u", attr->handle); - if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_DECLARE_128(ZMK_SPLIT_BT_SERVICE_UUID))) { - memcpy(&uuid, BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_POSITION_STATE_UUID), sizeof(uuid)); - discover_params.uuid = &uuid.uuid; - discover_params.start_handle = attr->handle + 1; - discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC; - - err = bt_gatt_discover(conn, &discover_params); - if (err) { - LOG_ERR("Discover failed (err %d)", err); - } - } else if (!bt_uuid_cmp(discover_params.uuid, - BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_POSITION_STATE_UUID))) { - memcpy(&uuid, BT_UUID_GATT_CCC, sizeof(uuid)); - discover_params.uuid = &uuid.uuid; - discover_params.start_handle = attr->handle + 2; - discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR; - subscribe_params.value_handle = bt_gatt_attr_value_handle(attr); - - err = bt_gatt_discover(conn, &discover_params); - if (err) { - LOG_ERR("Discover failed (err %d)", err); - } - } else { - subscribe_params.notify = split_central_notify_func; - subscribe_params.value = BT_GATT_CCC_NOTIFY; - subscribe_params.ccc_handle = attr->handle; - - split_central_subscribe(conn); - - return BT_GATT_ITER_STOP; + if (bt_uuid_cmp(discover_params.uuid, BT_UUID_DECLARE_128(ZMK_SPLIT_BT_SERVICE_UUID))) { + LOG_DBG("Found other service"); + return BT_GATT_ITER_CONTINUE; } + LOG_DBG("Found split service"); + discover_params.uuid = NULL; + discover_params.func = split_central_chrc_discovery_func; + discover_params.start_handle = attr->handle + 1; + discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC; + + int err = bt_gatt_discover(conn, &discover_params); + if (err) { + LOG_ERR("Failed to start discovering split service characteristics (err %d)", err); + } return BT_GATT_ITER_STOP; } @@ -161,9 +172,9 @@ static void split_central_process_connection(struct bt_conn *conn) { return; } - if (conn == default_conn && !subscribe_params.value) { - discover_params.uuid = &uuid.uuid; - discover_params.func = split_central_discovery_func; + if (conn == default_conn && !subscribe_params.value_handle) { + discover_params.uuid = &split_service_uuid.uuid; + discover_params.func = split_central_service_discovery_func; discover_params.start_handle = 0x0001; discover_params.end_handle = 0xffff; discover_params.type = BT_GATT_DISCOVER_PRIMARY; @@ -318,6 +329,9 @@ static void split_central_disconnected(struct bt_conn *conn, uint8_t reason) { bt_conn_unref(default_conn); default_conn = NULL; + // Clean up previously discovered handles; + subscribe_params.value_handle = 0; + start_scan(); } diff --git a/app/tests/conditional-layer/chained-activation/events.patterns b/app/tests/conditional-layer/chained-activation/events.patterns new file mode 100644 index 00000000..14ded795 --- /dev/null +++ b/app/tests/conditional-layer/chained-activation/events.patterns @@ -0,0 +1,3 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*conditional_layer/cl/p diff --git a/app/tests/conditional-layer/chained-activation/keycode_events.snapshot b/app/tests/conditional-layer/chained-activation/keycode_events.snapshot new file mode 100644 index 00000000..422b075c --- /dev/null +++ b/app/tests/conditional-layer/chained-activation/keycode_events.snapshot @@ -0,0 +1,10 @@ +mo_pressed: position 2 layer 1 +mo_pressed: position 3 layer 2 +cl_activate: layer 3 +cl_activate: layer 4 +kp_pressed: usage_page 0x07 keycode 0x0c implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x0c implicit_mods 0x00 explicit_mods 0x00 +mo_released: position 3 layer 2 +cl_deactivate: layer 3 +cl_deactivate: layer 4 +mo_released: position 2 layer 1 diff --git a/app/tests/conditional-layer/chained-activation/native_posix.keymap b/app/tests/conditional-layer/chained-activation/native_posix.keymap new file mode 100644 index 00000000..d799cc5e --- /dev/null +++ b/app/tests/conditional-layer/chained-activation/native_posix.keymap @@ -0,0 +1,62 @@ +#include +#include +#include + +/ { + conditional_layers { + compatible = "zmk,conditional-layers"; + conditional_layer_1 { + if-layers = <1 2>; + then-layer = <3>; + }; + conditional_layer_2 { + if-layers = <1 3>; + then-layer = <4>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + default_layer { + bindings = < + &kp A &kp B + &mo 1 &mo 2 + >; + }; + layer_1 { + bindings = < + &kp C &kp D + &trans &trans + >; + }; + layer_2 { + bindings = < + &kp E &kp F + &trans &trans + >; + }; + layer_3 { + bindings = < + &kp G &kp H + &trans &trans + >; + }; + layer_4 { + bindings = < + &kp I &kp J + &trans &trans + >; + }; + }; +}; + +&kscan { + events = < + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(1,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(1,0,10) + >; +}; diff --git a/app/tests/conditional-layer/mo-overlap/events.patterns b/app/tests/conditional-layer/mo-overlap/events.patterns new file mode 100644 index 00000000..14ded795 --- /dev/null +++ b/app/tests/conditional-layer/mo-overlap/events.patterns @@ -0,0 +1,3 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*conditional_layer/cl/p diff --git a/app/tests/conditional-layer/mo-overlap/keycode_events.snapshot b/app/tests/conditional-layer/mo-overlap/keycode_events.snapshot new file mode 100644 index 00000000..0200d8de --- /dev/null +++ b/app/tests/conditional-layer/mo-overlap/keycode_events.snapshot @@ -0,0 +1,17 @@ +mo_pressed: position 1 layer 3 +cl_deactivate: layer 3 +kp_pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +mo_pressed: position 2 layer 1 +mo_pressed: position 3 layer 2 +cl_activate: layer 3 +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +mo_released: position 3 layer 2 +cl_deactivate: layer 3 +mo_released: position 2 layer 1 +kp_pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +mo_released: position 1 layer 3 +kp_pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 diff --git a/app/tests/conditional-layer/mo-overlap/native_posix.keymap b/app/tests/conditional-layer/mo-overlap/native_posix.keymap new file mode 100644 index 00000000..1518fc8a --- /dev/null +++ b/app/tests/conditional-layer/mo-overlap/native_posix.keymap @@ -0,0 +1,60 @@ +#include +#include +#include + +/ { + conditional_layers { + compatible = "zmk,conditional-layers"; + tri_layer { + if-layers = <1 2>; + then-layer = <3>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + default_layer { + bindings = < + &kp A &mo 3 + &mo 1 &mo 2 + >; + }; + layer_1 { + bindings = < + &kp B &trans + &trans &trans + >; + }; + layer_2 { + bindings = < + &kp C &trans + &trans &trans + >; + }; + layer_3 { + bindings = < + &kp D &trans + &trans &trans + >; + }; + }; +}; + +&kscan { + events = < + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(1,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(0,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; diff --git a/app/tests/conditional-layer/multiple-configs/events.patterns b/app/tests/conditional-layer/multiple-configs/events.patterns new file mode 100644 index 00000000..14ded795 --- /dev/null +++ b/app/tests/conditional-layer/multiple-configs/events.patterns @@ -0,0 +1,3 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*conditional_layer/cl/p diff --git a/app/tests/conditional-layer/multiple-configs/keycode_events.snapshot b/app/tests/conditional-layer/multiple-configs/keycode_events.snapshot new file mode 100644 index 00000000..a076a639 --- /dev/null +++ b/app/tests/conditional-layer/multiple-configs/keycode_events.snapshot @@ -0,0 +1,16 @@ +mo_pressed: position 2 layer 1 +mo_pressed: position 3 layer 2 +cl_activate: layer 4 +kp_pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +mo_pressed: position 1 layer 3 +cl_activate: layer 5 +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +mo_released: position 1 layer 3 +cl_deactivate: layer 5 +kp_pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +mo_released: position 3 layer 2 +cl_deactivate: layer 4 +mo_released: position 2 layer 1 diff --git a/app/tests/conditional-layer/multiple-configs/native_posix.keymap b/app/tests/conditional-layer/multiple-configs/native_posix.keymap new file mode 100644 index 00000000..8290649f --- /dev/null +++ b/app/tests/conditional-layer/multiple-configs/native_posix.keymap @@ -0,0 +1,74 @@ +#include +#include +#include + +/ { + conditional_layers { + compatible = "zmk,conditional-layers"; + tri_layer { + if-layers = <1 2>; + then-layer = <4>; + }; + quad_layer { + if-layers = <1 2 3>; + then-layer = <5>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + default_layer { + bindings = < + &kp A &mo 3 + &mo 1 &mo 2 + >; + }; + layer_1 { + bindings = < + &kp B &trans + &trans &trans + >; + }; + layer_2 { + bindings = < + &kp C &trans + &trans &trans + >; + }; + layer_3 { + bindings = < + &kp D &trans + &trans &trans + >; + }; + layer_4 { + bindings = < + &kp E &trans + &trans &trans + >; + }; + layer_5 { + bindings = < + &kp F &trans + &trans &trans + >; + }; + }; +}; + +&kscan { + events = < + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(1,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(0,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(1,0,10) + >; +}; diff --git a/app/tests/conditional-layer/quad-layer/events.patterns b/app/tests/conditional-layer/quad-layer/events.patterns new file mode 100644 index 00000000..14ded795 --- /dev/null +++ b/app/tests/conditional-layer/quad-layer/events.patterns @@ -0,0 +1,3 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*conditional_layer/cl/p diff --git a/app/tests/conditional-layer/quad-layer/keycode_events.snapshot b/app/tests/conditional-layer/quad-layer/keycode_events.snapshot new file mode 100644 index 00000000..fb54a6ca --- /dev/null +++ b/app/tests/conditional-layer/quad-layer/keycode_events.snapshot @@ -0,0 +1,10 @@ +mo_pressed: position 2 layer 1 +mo_pressed: position 3 layer 2 +mo_pressed: position 1 layer 3 +cl_activate: layer 4 +kp_pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +mo_released: position 1 layer 3 +cl_deactivate: layer 4 +mo_released: position 3 layer 2 +mo_released: position 2 layer 1 diff --git a/app/tests/conditional-layer/quad-layer/native_posix.keymap b/app/tests/conditional-layer/quad-layer/native_posix.keymap new file mode 100644 index 00000000..300b1f75 --- /dev/null +++ b/app/tests/conditional-layer/quad-layer/native_posix.keymap @@ -0,0 +1,60 @@ +#include +#include +#include + +/ { + conditional_layers { + compatible = "zmk,conditional-layers"; + quad_layer { + if-layers = <1 2 3>; + then-layer = <4>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + default_layer { + bindings = < + &kp A &mo 3 + &mo 1 &mo 2 + >; + }; + layer_1 { + bindings = < + &kp B &trans + &trans &trans + >; + }; + layer_2 { + bindings = < + &kp C &trans + &trans &trans + >; + }; + layer_3 { + bindings = < + &kp D &trans + &trans &trans + >; + }; + layer_4 { + bindings = < + &kp E &trans + &trans &trans + >; + }; + }; +}; + +&kscan { + events = < + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(1,1,10) + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(0,1,10) + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(1,0,10) + >; +}; diff --git a/app/tests/conditional-layer/tri-layer-alt-order/events.patterns b/app/tests/conditional-layer/tri-layer-alt-order/events.patterns new file mode 100644 index 00000000..14ded795 --- /dev/null +++ b/app/tests/conditional-layer/tri-layer-alt-order/events.patterns @@ -0,0 +1,3 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*conditional_layer/cl/p diff --git a/app/tests/conditional-layer/tri-layer-alt-order/keycode_events.snapshot b/app/tests/conditional-layer/tri-layer-alt-order/keycode_events.snapshot new file mode 100644 index 00000000..05337b29 --- /dev/null +++ b/app/tests/conditional-layer/tri-layer-alt-order/keycode_events.snapshot @@ -0,0 +1,8 @@ +mo_pressed: position 3 layer 2 +mo_pressed: position 2 layer 1 +cl_activate: layer 3 +kp_pressed: usage_page 0x07 keycode 0x0a implicit_mods 0x00 explicit_mods 0x00 +mo_released: position 3 layer 2 +cl_deactivate: layer 3 +mo_released: position 2 layer 1 +kp_released: usage_page 0x07 keycode 0x0a implicit_mods 0x00 explicit_mods 0x00 diff --git a/app/tests/conditional-layer/tri-layer-alt-order/native_posix.keymap b/app/tests/conditional-layer/tri-layer-alt-order/native_posix.keymap new file mode 100644 index 00000000..a3154038 --- /dev/null +++ b/app/tests/conditional-layer/tri-layer-alt-order/native_posix.keymap @@ -0,0 +1,52 @@ +#include +#include +#include + +/ { + conditional_layers { + compatible = "zmk,conditional-layers"; + tri_layer { + if-layers = <1 2>; + then-layer = <3>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + default_layer { + bindings = < + &kp A &kp B + &mo 1 &mo 2 + >; + }; + layer_1 { + bindings = < + &kp C &kp D + &trans &trans + >; + }; + layer_2 { + bindings = < + &kp E &kp F + &trans &trans + >; + }; + layer_3 { + bindings = < + &kp G &kp H + &trans &trans + >; + }; + }; +}; + +&kscan { + events = < + ZMK_MOCK_PRESS(1,1,10) + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; diff --git a/app/tests/conditional-layer/tri-layer/events.patterns b/app/tests/conditional-layer/tri-layer/events.patterns new file mode 100644 index 00000000..14ded795 --- /dev/null +++ b/app/tests/conditional-layer/tri-layer/events.patterns @@ -0,0 +1,3 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*conditional_layer/cl/p diff --git a/app/tests/conditional-layer/tri-layer/keycode_events.snapshot b/app/tests/conditional-layer/tri-layer/keycode_events.snapshot new file mode 100644 index 00000000..b23e61b2 --- /dev/null +++ b/app/tests/conditional-layer/tri-layer/keycode_events.snapshot @@ -0,0 +1,8 @@ +mo_pressed: position 2 layer 1 +mo_pressed: position 3 layer 2 +cl_activate: layer 3 +kp_pressed: usage_page 0x07 keycode 0x0a implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x0a implicit_mods 0x00 explicit_mods 0x00 +mo_released: position 3 layer 2 +cl_deactivate: layer 3 +mo_released: position 2 layer 1 diff --git a/app/tests/conditional-layer/tri-layer/native_posix.keymap b/app/tests/conditional-layer/tri-layer/native_posix.keymap new file mode 100644 index 00000000..150d6dd1 --- /dev/null +++ b/app/tests/conditional-layer/tri-layer/native_posix.keymap @@ -0,0 +1,52 @@ +#include +#include +#include + +/ { + conditional_layers { + compatible = "zmk,conditional-layers"; + tri_layer { + if-layers = <1 2>; + then-layer = <3>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + default_layer { + bindings = < + &kp A &kp B + &mo 1 &mo 2 + >; + }; + layer_1 { + bindings = < + &kp C &kp D + &trans &trans + >; + }; + layer_2 { + bindings = < + &kp E &kp F + &trans &trans + >; + }; + layer_3 { + bindings = < + &kp G &kp H + &trans &trans + >; + }; + }; +}; + +&kscan { + events = < + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(1,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(1,0,10) + >; +}; diff --git a/app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/events.patterns b/app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/keycode_events.snapshot b/app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/keycode_events.snapshot new file mode 100644 index 00000000..926174b4 --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/keycode_events.snapshot @@ -0,0 +1,5 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-timer (balanced decision moment timer) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/native_posix.keymap b/app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/native_posix.keymap new file mode 100644 index 00000000..11d033f4 --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/native_posix.keymap @@ -0,0 +1,11 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,500) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns b/app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot b/app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot new file mode 100644 index 00000000..1b5cc8f2 --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (balanced decision moment timer) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap b/app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap new file mode 100644 index 00000000..d1d2b756 --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,200) + ZMK_MOCK_PRESS(1,1,200) // non trigger key + /* timer fires */ + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns b/app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot b/app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot new file mode 100644 index 00000000..242b31f2 --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-timer (balanced decision moment timer) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap b/app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap new file mode 100644 index 00000000..94d9a923 --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,200) + ZMK_MOCK_PRESS(1,0,200) // trigger key + /* timer fires */ + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/balanced/7-positional/behavior_keymap.dtsi b/app/tests/hold-tap/balanced/7-positional/behavior_keymap.dtsi new file mode 100644 index 00000000..5657644d --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/behavior_keymap.dtsi @@ -0,0 +1,29 @@ +#include +#include +#include + +/ { + behaviors { + ht_bal: behavior_hold_tap_balanced { + compatible = "zmk,behavior-hold-tap"; + label = "HOLD_TAP_BALANCED"; + #binding-cells = <2>; + flavor = "balanced"; + tapping-term-ms = <300>; + quick-tap-ms = <200>; + bindings = <&kp>, <&kp>; + hold-trigger-key-positions = <2>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &ht_bal LEFT_SHIFT F &ht_bal LEFT_CONTROL J + &kp D &kp E>; + }; + }; +}; diff --git a/app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns b/app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot b/app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot new file mode 100644 index 00000000..1e1ea6b9 --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot @@ -0,0 +1,9 @@ +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (balanced decision moment timer) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap b/app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap new file mode 100644 index 00000000..6ddf87f8 --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap @@ -0,0 +1,16 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(1,0,10) // trigger key + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_PRESS(1,1,400) // not trigger key + /* timer fires */ + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/events.patterns b/app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/keycode_events.snapshot new file mode 100644 index 00000000..827ac986 --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/keycode_events.snapshot @@ -0,0 +1,5 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-timer (hold-preferred decision moment timer) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/native_posix.keymap b/app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/native_posix.keymap new file mode 100644 index 00000000..11d033f4 --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/native_posix.keymap @@ -0,0 +1,11 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,500) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot new file mode 100644 index 00000000..964cbafe --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (hold-preferred decision moment other-key-down) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap new file mode 100644 index 00000000..d1d2b756 --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,200) + ZMK_MOCK_PRESS(1,1,200) // non trigger key + /* timer fires */ + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot new file mode 100644 index 00000000..1d2b827e --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-interrupt (hold-preferred decision moment other-key-down) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap new file mode 100644 index 00000000..94d9a923 --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,200) + ZMK_MOCK_PRESS(1,0,200) // trigger key + /* timer fires */ + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/hold-preferred/7-positional/behavior_keymap.dtsi b/app/tests/hold-tap/hold-preferred/7-positional/behavior_keymap.dtsi new file mode 100644 index 00000000..bf681004 --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/behavior_keymap.dtsi @@ -0,0 +1,29 @@ +#include +#include +#include + +/ { + behaviors { + ht_hold: behavior_hold_hold_tap { + compatible = "zmk,behavior-hold-tap"; + label = "hold_hold_tap"; + #binding-cells = <2>; + flavor = "hold-preferred"; + tapping-term-ms = <300>; + quick-tap-ms = <200>; + bindings = <&kp>, <&kp>; + hold-trigger-key-positions = <2>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &ht_hold LEFT_SHIFT F &ht_hold LEFT_CONTROL J + &kp D &kp E>; + }; + }; +}; diff --git a/app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns b/app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot new file mode 100644 index 00000000..2838194d --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot @@ -0,0 +1,9 @@ +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (hold-preferred decision moment other-key-down) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap b/app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap new file mode 100644 index 00000000..6ddf87f8 --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap @@ -0,0 +1,16 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(1,0,10) // trigger key + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_PRESS(1,1,400) // not trigger key + /* timer fires */ + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/events.patterns b/app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/keycode_events.snapshot new file mode 100644 index 00000000..4bf3e7ca --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/keycode_events.snapshot @@ -0,0 +1,5 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-timer (tap-preferred decision moment timer) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/native_posix.keymap b/app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/native_posix.keymap new file mode 100644 index 00000000..11d033f4 --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/native_posix.keymap @@ -0,0 +1,11 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,500) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot new file mode 100644 index 00000000..337af3e9 --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (tap-preferred decision moment timer) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap new file mode 100644 index 00000000..d1d2b756 --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,200) + ZMK_MOCK_PRESS(1,1,200) // non trigger key + /* timer fires */ + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot new file mode 100644 index 00000000..2d985568 --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-timer (tap-preferred decision moment timer) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap new file mode 100644 index 00000000..94d9a923 --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,200) + ZMK_MOCK_PRESS(1,0,200) // trigger key + /* timer fires */ + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-preferred/7-positional/behavior_keymap.dtsi b/app/tests/hold-tap/tap-preferred/7-positional/behavior_keymap.dtsi new file mode 100644 index 00000000..e4be8d15 --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/behavior_keymap.dtsi @@ -0,0 +1,29 @@ +#include +#include +#include + +/ { + behaviors { + tp: behavior_tap_preferred { + compatible = "zmk,behavior-hold-tap"; + label = "MOD_TAP"; + #binding-cells = <2>; + flavor = "tap-preferred"; + tapping-term-ms = <300>; + quick-tap-ms = <200>; + bindings = <&kp>, <&kp>; + hold-trigger-key-positions = <2>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &tp LEFT_SHIFT F &tp LEFT_CONTROL J + &kp D &kp E>; + }; + }; +}; diff --git a/app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns b/app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot new file mode 100644 index 00000000..4ecb1b8e --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot @@ -0,0 +1,9 @@ +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (tap-preferred decision moment timer) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap b/app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap new file mode 100644 index 00000000..6ddf87f8 --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap @@ -0,0 +1,16 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(1,0,10) // trigger key + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_PRESS(1,1,400) // not trigger key + /* timer fires */ + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/1-dn-up/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/1-dn-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/1-dn-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/1-dn-up/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/1-dn-up/keycode_events.snapshot new file mode 100644 index 00000000..1eb2d1e3 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/1-dn-up/keycode_events.snapshot @@ -0,0 +1,5 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (tap-unless-interrupted decision moment key-up) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/1-dn-up/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/1-dn-up/native_posix.keymap new file mode 100644 index 00000000..040cdd3e --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/1-dn-up/native_posix.keymap @@ -0,0 +1,11 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/keycode_events.snapshot new file mode 100644 index 00000000..e036acb9 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/keycode_events.snapshot @@ -0,0 +1,5 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (tap-unless-interrupted decision moment timer) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/native_posix.keymap new file mode 100644 index 00000000..11d033f4 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/native_posix.keymap @@ -0,0 +1,11 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,500) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/keycode_events.snapshot new file mode 100644 index 00000000..a733739d --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +kp_pressed: usage_page 0x07 keycode 0xe4 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (tap-unless-interrupted decision moment key-up) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe4 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/native_posix.keymap new file mode 100644 index 00000000..abb31b4b --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/native_posix.keymap @@ -0,0 +1,13 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(1,1,10) /*ctrl*/ + ZMK_MOCK_PRESS(0,0,100) /*mt f-shift */ + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/keycode_events.snapshot new file mode 100644 index 00000000..d2928131 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +kp_pressed: usage_page 0x07 keycode 0xe4 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (tap-unless-interrupted decision moment timer) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe4 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/native_posix.keymap new file mode 100644 index 00000000..38575e9a --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(1,1,10) /*ctrl*/ + ZMK_MOCK_PRESS(0,0,50) /*mt f-shift */ + ZMK_MOCK_RELEASE(1,1,300) + /*timer*/ + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/keycode_events.snapshot new file mode 100644 index 00000000..3a9b3dcb --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 0 new undecided hold_tap +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +ht_decide: 0 decided tap (tap-unless-interrupted decision moment key-up) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/native_posix.keymap new file mode 100644 index 00000000..21baa447 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/native_posix.keymap @@ -0,0 +1,13 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(1,0,10) /*d*/ + ZMK_MOCK_PRESS(0,0,100) /*mt f-shift */ + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/keycode_events.snapshot new file mode 100644 index 00000000..0a72c83a --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 0 new undecided hold_tap +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +ht_decide: 0 decided tap (tap-unless-interrupted decision moment timer) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/native_posix.keymap new file mode 100644 index 00000000..cd7ff384 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/native_posix.keymap @@ -0,0 +1,13 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(1,0,10) /* d */ + ZMK_MOCK_PRESS(0,0,100) /* mt f-shift */ + ZMK_MOCK_RELEASE(1,0,400) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/keycode_events.snapshot new file mode 100644 index 00000000..b138d6cf --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/keycode_events.snapshot @@ -0,0 +1,10 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-interrupt (tap-unless-interrupted decision moment other-key-down) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 1 new undecided hold_tap +ht_decide: 1 decided tap (tap-unless-interrupted decision moment key-up) +kp_pressed: usage_page 0x07 keycode 0x0d implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x0d implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 1 cleaning up hold-tap +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/native_posix.keymap new file mode 100644 index 00000000..b84aa626 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,200) + ZMK_MOCK_PRESS(0,1,200) + /* timer fires */ + ZMK_MOCK_RELEASE(0,1,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/keycode_events.snapshot new file mode 100644 index 00000000..6fa61725 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-interrupt (tap-unless-interrupted decision moment other-key-down) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/native_posix.keymap new file mode 100644 index 00000000..bdfaf9d3 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,200) + ZMK_MOCK_PRESS(1,0,200) + /* timer fires */ + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/keycode_events.snapshot new file mode 100644 index 00000000..6fa61725 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-interrupt (tap-unless-interrupted decision moment other-key-down) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/native_posix.keymap new file mode 100644 index 00000000..c0fd1bd1 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,100) + ZMK_MOCK_PRESS(1,0,100) + ZMK_MOCK_RELEASE(1,0,200) + /* timer fires */ + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/keycode_events.snapshot new file mode 100644 index 00000000..6fa61725 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-interrupt (tap-unless-interrupted decision moment other-key-down) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/native_posix.keymap new file mode 100644 index 00000000..69c19676 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + /* timer */ + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/keycode_events.snapshot new file mode 100644 index 00000000..fc685a37 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-interrupt (tap-unless-interrupted decision moment other-key-down) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 diff --git a/app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/native_posix.keymap new file mode 100644 index 00000000..301ef0ac --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,100) + ZMK_MOCK_PRESS(1,0,100) + ZMK_MOCK_RELEASE(0,0,200) + /* timer fires */ + ZMK_MOCK_RELEASE(1,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*on_hold_tap_binding/ht_binding/p +s/.*decide_hold_tap/ht_decide/p \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/keycode_events.snapshot new file mode 100644 index 00000000..070b9938 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/keycode_events.snapshot @@ -0,0 +1,10 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (tap-unless-interrupted decision moment key-up) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (tap-unless-interrupted decision moment quick-tap) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/native_posix.keymap new file mode 100644 index 00000000..8f90ffad --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_PRESS(0,0,400) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/behavior_keymap.dtsi b/app/tests/hold-tap/tap-unless-interrupted/behavior_keymap.dtsi new file mode 100644 index 00000000..18f68d63 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/behavior_keymap.dtsi @@ -0,0 +1,30 @@ +#include +#include +#include + + + +/ { + behaviors { + ht_tui: behavior_hold_tap_tap_unless_interrupted { + compatible = "zmk,behavior-hold-tap"; + label = "hold_tap_tap_unless_interrupted"; + #binding-cells = <2>; + flavor = "tap-unless-interrupted"; + tapping-term-ms = <300>; + quick-tap-ms = <200>; + bindings = <&kp>, <&kp>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &ht_tui LEFT_SHIFT F &ht_tui LEFT_CONTROL J + &kp D &kp RIGHT_CONTROL>; + }; + }; +}; diff --git a/docs/docs/behaviors/hold-tap.md b/docs/docs/behaviors/hold-tap.md index 6817c602..972df0be 100644 --- a/docs/docs/behaviors/hold-tap.md +++ b/docs/docs/behaviors/hold-tap.md @@ -26,6 +26,7 @@ We call this the 'hold-preferred' flavor of hold-taps. While this flavor may wor - The 'hold-preferred' flavor triggers the hold behavior when the `tapping-term-ms` has expired or another key is pressed. - The 'balanced' flavor will trigger the hold behavior when the `tapping-term-ms` has expired or another key is pressed and released. - The 'tap-preferred' flavor triggers the hold behavior when the `tapping-term-ms` has expired. It triggers the tap behavior when another key is pressed. +- The 'tap-unless-interrupted' flavor triggers a hold behavior only when another key is pressed before `tapping-term-ms` has expired. It triggers the tap behavior in all other situations. When the hold-tap key is released and the hold behavior has not been triggered, the tap behavior will trigger. @@ -59,9 +60,84 @@ For example, if you press `&mt LEFT_SHIFT A` and then release it without pressin }; ``` +#### Positional hold-tap and `hold-trigger-key-positions` + +- Including `hold-trigger-key-postions` in your hold-tap definition turns on the positional hold-tap feature. +- With positional hold-tap enabled, if you press any key **NOT** listed in `hold-trigger-key-positions` before `tapping-term-ms` expires, it will produce a tap. +- In all other situations, positional hold-tap will not modify the behavior of your hold-tap. +- Positional hold-tap is useful with home-row modifiers. If you have a home-row modifier key in the left hand for example, by including only keys positions from the right hand in `hold-trigger-key-positions`, you will only get hold behaviors during cross-hand key combinations. +- Note that `hold-trigger-key-postions` is an array of key position indexes. Key positions are numbered according to your keymap, starting with 0. So if the first key in your keymap is Q, this key is in position 0. The next key (probably W) will be in position 1, et cetera. +- See the following example, which uses a hold-tap behavior definition, configured with the `hold-preferrred` flavor, and with positional hold-tap enabled: + +``` +#include +#include +/ { + behaviors { + pht: positional_hold_tap { + compatible = "zmk,behavior-hold-tap"; + label = "POSITIONAL_HOLD_TAP"; + #binding-cells = <2>; + flavor = "hold-preferred"; + tapping-term-ms = <400>; + quick-tap-ms = <200>; + bindings = <&kp>, <&kp>; + hold-trigger-key-positions = <1>; // <---[[the W key]] + }; + }; + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + default_layer { + bindings = < + // position 0 position 1 position 2 + &pht LEFT_SHIFT Q &kp W &kp E + >; + }; + }; +}; +``` + +- The sequence `(pht_down, E_down, E_up, pht_up)` produces `qe`. The normal hold behavior (LEFT_SHIFT) **IS** modified into a tap behavior (Q) by positional hold-tap because the first key pressed after the hold-tap key is the `E key`, which is in position 2, which **is NOT** included in `hold-trigger-key-positions`. +- The sequence `(pht_down, W_down, W_up, pht_up)` produces `W`. The normal hold behavior (LEFT_SHIFT) **is NOT** modified into a tap behavior (Q) by positional hold-tap because the first key pressed after the hold-tap key is the `W key`, which is in position 1, which **IS** included in `hold-trigger-key-positions`. +- If the `LEFT_SHIFT / Q key` is held by itself for longer than `tapping-term-ms`, a hold behavior is produced. This is because positional hold-tap only modifies the behavior of a hold-tap if another key is pressed before the `tapping-term-ms` period expires. + #### Home row mods -This example configures a hold-tap that works well for homerow mods: +The following are suggested hold-tap configurations that work well with home row mods: + +##### Option 1: cross-hand only modifiers, using `tap-unless-interrupted` and positional hold-tap (`hold-trigger-key-positions`) + +``` +#include +#include +/ { + behaviors { + lh_pht: left_hand_positional_hold_tap { + compatible = "zmk,behavior-hold-tap"; + label = "POSITIONAL_HOLD_TAP"; + #binding-cells = <2>; + flavor = "tap-unless-interrupted"; + tapping-term-ms = <100>; // <---[[produces tap if held longer than tapping-term-ms]] + quick-tap-ms = <200>; + bindings = <&kp>, <&kp>; + hold-trigger-key-positions = <5 6 7 8 9 10>; // <---[[right-hand keys]] + }; + }; + + keymap { + compatible = "zmk,keymap"; + default_layer { + bindings = < + // position 0 pos 1 pos 2 pos 3 pos 4 pos 5 pos 6 pos 7 pos 8 pos 9 pos 10 + &lh_pht LSFT A &lh_pht LGUI S &lh_pht LALT D &lh_pht LCTL F &kp G &kp H &kp I &kp J &kp K &kp L &kp SCLN + >; + }; + }; +}; +``` + +##### Option 2: `tap-preferred` ``` #include @@ -82,7 +158,6 @@ This example configures a hold-tap that works well for homerow mods: keymap { compatible = "zmk,keymap"; - default_layer { bindings = < &hm LCTRL A &hm LGUI S &hm LALT D &hm LSHIFT F @@ -93,7 +168,36 @@ This example configures a hold-tap that works well for homerow mods: ``` -If this config does not work for you, try the flavor "balanced" with a medium `tapping-term-ms` such as 200ms. +##### Option 3: `balanced` + +``` +#include +#include + +/ { + behaviors { + bhm: balanced_homerow_mods { + compatible = "zmk,behavior-hold-tap"; + label = "HOMEROW_MODS"; + #binding-cells = <2>; + tapping-term-ms = <200>; // <---[[moderate duration]] + quick_tap_ms = <0>; + flavor = "balanced"; + bindings = <&kp>, <&kp>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + default_layer { + bindings = < + &bhm LCTRL A &bhm LGUI S &bhm LALT D &bhm LSHIFT F + >; + }; + }; +}; + +``` #### Comparison to QMK diff --git a/docs/docs/behaviors/layers.md b/docs/docs/behaviors/layers.md index 098952e7..5aa98879 100644 --- a/docs/docs/behaviors/layers.md +++ b/docs/docs/behaviors/layers.md @@ -27,7 +27,7 @@ This allows you to use those defines, e.g. `LOWER` later in your keymap. ## Momentary Layer The "momentary layer" behavior enables a layer while a certain key is pressed. Immediately upon -activation of the key, the layer is enabled, and immediately open release of the key, the layer is disabled +activation of the key, the layer is enabled, and immediately upon release of the key, the layer is disabled again. ### Behavior Binding diff --git a/docs/docs/development/documentation.md b/docs/docs/development/documentation.md index 221bb160..ff45d80a 100644 --- a/docs/docs/development/documentation.md +++ b/docs/docs/development/documentation.md @@ -19,7 +19,7 @@ If you are working with the documentation from within VS Code+Docker please be a ::: :::note -You will need `Node.js` and `npm` installed to update the documentation. If you're using the ZMK dev container (Docker) the necessary dependencies are already installed. +You will need `Node.js` and `npm` installed to update the documentation. If you're using the ZMK dev container (Docker) the necessary dependencies are already installed. Otherwise, you must install these dependencies yourself. Since `Node.js` packages in Linux distributions tend to be outdated, it's recommended to install the current version from a repository like [NodeSource](https://github.com/nodesource/distributions) to avoid build errors. ::: ## Testing Documentation Updates Locally diff --git a/docs/docs/development/tests.md b/docs/docs/development/tests.md index 5ebf14f2..e84acf8d 100644 --- a/docs/docs/development/tests.md +++ b/docs/docs/development/tests.md @@ -3,10 +3,10 @@ title: Tests sidebar_label: Tests --- -Running tests requires [native posix support](posix-board.md). Any folder under `/app/tests` -containing `native_posix.keymap` will be selected when running `west test`. - -Run a single test with `west test `, like `west test tests/toggle-layer/normal`. +- Running tests requires [native posix support](posix-board.md). +- Any folder under `/app/tests` containing `native_posix.keymap` will be selected when running `west test`. +- Run tests from within the `/zmk/app` directory. +- Run a single test with `west test `, like `west test tests/toggle-layer/normal`. ## Creating a New Test Set diff --git a/docs/docs/features/conditional-layers.md b/docs/docs/features/conditional-layers.md new file mode 100644 index 00000000..a685bcab --- /dev/null +++ b/docs/docs/features/conditional-layers.md @@ -0,0 +1,56 @@ +--- +title: Conditional Layers +--- + +Conditional layers support activating a particular layer (called the `then-layer`) when all layers +in a specified set (called the `if-layers`) are active. This feature generalizes what's commonly +known as tri-layer support, allowing activation of two layers (usually called "lower" and "raise") +to trigger a third (usually called "adjust"). + +Another way to think of this feature is as a simple combo system for layers, just like the usual +[combos for behaviors](combos.md). + +## Configuration + +Conditional layers are configured via a `conditional_layers` node in your `.keymap` file as follows: + +``` +/ { + conditional_layers { + compatible = "zmk,conditional-layers"; + tri_layer { + if-layers = <1 2>; + then-layer = <3>; + }; + }; +}; +``` + +Each conditional layer configuration may have whatever name you like, but it's helpful to choose +something self explanatory like `tri_layer`. The following properties are supported: + +- `if-layers` specifies a set of layer numbers, all of which must be active for the conditional + layer to trigger. +- `then-layer` specifies a layer number that should be activated if and only if all the layers + specified in the `if-layers` property are active. + +Therefore, in this example, layer 3 ("adjust") will be activated if and only if both layers 1 +("lower") and 2 ("raise") are active. + +:::tip +Since higher-numbered layers are processed first, a `then-layer` should generally have a higher +number than its associated `if-layers` so the `then-layer` can be accessed when active. +::: + +:::info +Activating a `then-layer` in one conditional layer configuration can trigger the `if-layers` +condition in another configuration, possibly repeatedly. +::: + +:::caution +When configured as a `then-layer`, a layer's activation status is entirely controlled by the +conditional layers feature. Even if the layer is activated for another reason (such as a [momentary +layer](../behaviors/layers.md#momentary-layer) behavior), it will be immediately deactivated if the +associated `then-layers` configuration is not met. As such, we recommend avoiding using regular +layer behaviors for `then-layer` targets. +::: diff --git a/docs/docs/features/debouncing.md b/docs/docs/features/debouncing.md new file mode 100644 index 00000000..f0022a59 --- /dev/null +++ b/docs/docs/features/debouncing.md @@ -0,0 +1,100 @@ +--- +title: Debouncing +sidebar_label: Debouncing +--- + +To prevent contact bounce (also known as chatter) and noise spikes from causing +unwanted key presses, ZMK uses a [cycle-based debounce algorithm](https://www.kennethkuhn.com/electronics/debounce.c), +with each key debounced independently. + +By default the debounce algorithm decides that a key is pressed or released after +the input is stable for 5 milliseconds. You can decrease this to improve latency +or increase it to improve reliability. + +If you are having problems with a single key press registering multiple inputs, +you can try increasing the debounce press and/or release times to compensate. +You should also check for mechanical issues that might be causing the bouncing, +such as hot swap sockets that are making poor contact. You can try replacing the +socket or using some sharp tweezers to bend the contacts back together. + +## Debounce Configuration + +### Global Options + +You can set these options in your `.conf` file to control debouncing globally. +Values must be <= 127. + +- `CONFIG_ZMK_KSCAN_DEBOUNCE_PRESS_MS`: Debounce time for key press in milliseconds. Default = 5. +- `CONFIG_ZMK_KSCAN_DEBOUNCE_RELEASE_MS`: Debounce time for key release in milliseconds. Default = 5. + +For example, this would shorten the debounce time for both press and release: + +```ini +CONFIG_ZMK_KSCAN_DEBOUNCE_PRESS_MS=3 +CONFIG_ZMK_KSCAN_DEBOUNCE_RELEASE_MS=3 +``` + +### Per-driver Options + +You can add these Devicetree properties to a kscan node to control debouncing for +that instance of the driver. Values must be <= 127. + +- `debounce-press-ms`: Debounce time for key press in milliseconds. Default = 5. +- `debounce-release-ms`: Debounce time for key release in milliseconds. Default = 5. +- ~~`debounce-period`~~: Deprecated. Sets both press and release debounce times. +- `debounce-scan-period-ms`: Time between reads in milliseconds when any key is pressed. Default = 1. + +If one of the global options described above is set, it overrides the corresponding +per-driver option. + +For example, if your board/shield has a kscan driver labeled `kscan0` in its +`.overlay`, `.dts`, or `.dtsi` files, + +```devicetree +kscan0: kscan { + compatible = "zmk,kscan-gpio-matrix"; + ... +}; +``` + +then you could add this to your `.keymap`: + +```devicetree +&kscan0 { + debounce-press-ms = <3>; + debounce-release-ms = <3>; +}; +``` + +This must be placed outside of any blocks surrounded by curly braces (`{...}`). + +`debounce-scan-period-ms` determines how often the keyboard scans while debouncing. It defaults to 1 ms, but it can be increased to reduce power use. Note that the debounce press/release timers are rounded up to the next multiple of the scan period. For example, if the scan period is 2 ms and debounce timer is 5 ms, key presses will take 6 ms to register instead of 5. + +## Eager Debouncing + +Eager debouncing means reporting a key change immediately and then ignoring +further changes for the debounce time. This eliminates latency but it is not +noise-resistant. + +ZMK does not currently support true eager debouncing, but you can get something +very close by setting the time to detect a key press to zero and the time to detect +a key release to a larger number. This will detect a key press immediately, then +debounce the key release. + +```ini +CONFIG_ZMK_KSCAN_DEBOUNCE_PRESS_MS=0 +CONFIG_ZMK_KSCAN_DEBOUNCE_RELEASE_MS=5 +``` + +Also consider setting `CONFIG_ZMK_KSCAN_DEBOUNCE_PRESS_MS=1` instead, which adds +one millisecond of latency but protects against short noise spikes. + +## Comparison With QMK + +ZMK's default debouncing is similar to QMK's `sym_defer_pk` algorithm. + +Setting `CONFIG_ZMK_KSCAN_DEBOUNCE_PRESS_MS=0` for eager debouncing would be similar +to QMK's (unimplemented as of this writing) `asym_eager_defer_pk`. + +See [QMK's Debounce API documentation](https://beta.docs.qmk.fm/using-qmk/software-features/feature_debounce_type) +for more information. diff --git a/docs/package-lock.json b/docs/package-lock.json index 127baf68..af50fa60 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -12,8 +12,10 @@ "@docusaurus/preset-classic": "^2.0.0-beta.3", "@fortawesome/fontawesome-svg-core": "^1.2.32", "@fortawesome/free-solid-svg-icons": "^5.15.3", - "@fortawesome/react-fontawesome": "^0.1.14", + "@fortawesome/react-fontawesome": "^0.1.16", + "@mdx-js/react": "^1.6.22", "classnames": "^2.2.6", + "js-yaml": "^4.1.0", "react": "^17.0.2", "react-async": "^10.0.1", "react-copy-to-clipboard": "^5.0.3", @@ -22,7 +24,7 @@ "web-tree-sitter": "^0.19.4" }, "devDependencies": { - "@docusaurus/module-type-aliases": "^2.0.0-alpha.72", + "@docusaurus/module-type-aliases": "^2.0.0-beta.3", "@tsconfig/docusaurus": "^1.0.2", "@types/react": "^17.0.3", "@types/react-helmet": "^6.1.0", @@ -32,11 +34,13 @@ "eslint-plugin-mdx": "^1.13.0", "eslint-plugin-react": "^7.23.2", "json-schema-to-typescript": "^10.1.3", + "mustache": "^4.2.0", "null-loader": "^4.0.0", "prebuild-webpack-plugin": "^1.1.1", "prettier": "2.3.1", "string-replace-loader": "^3.0.3", - "typescript": "^4.2.3" + "typescript": "^4.2.3", + "webpack": "^5.46.0" } }, "node_modules/@algolia/autocomplete-core": { @@ -119,6 +123,28 @@ "js-yaml": "^3.13.1" } }, + "node_modules/@apidevtools/json-schema-ref-parser/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@apidevtools/json-schema-ref-parser/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/@babel/code-frame": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", @@ -5390,17 +5416,6 @@ "node": ">=6.9.0" } }, - "node_modules/@docusaurus/core/node_modules/acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/@docusaurus/core/node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -5857,62 +5872,6 @@ "node": ">=4" } }, - "node_modules/@docusaurus/core/node_modules/tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@docusaurus/core/node_modules/terser-webpack-plugin": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz", - "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==", - "dependencies": { - "jest-worker": "^27.0.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - } - }, - "node_modules/@docusaurus/core/node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.0.tgz", - "integrity": "sha512-tTEaeYkyIhEZ9uWgAjDerWov3T9MgX8dhhy2r0IGeeX4W8ngtGl1++dUve/RUqzuaASSh7shwCDJjEzthxki8w==", - "dependencies": { - "@types/json-schema": "^7.0.7", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/@docusaurus/core/node_modules/terser-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@docusaurus/core/node_modules/update-notifier": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", @@ -5940,68 +5899,6 @@ "url": "https://github.com/yeoman/update-notifier?sponsor=1" } }, - "node_modules/@docusaurus/core/node_modules/webpack": { - "version": "5.45.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.45.1.tgz", - "integrity": "sha512-68VT2ZgG9EHs6h6UxfV2SEYewA9BA3SOLSnC2NEbJJiEwbAiueDL033R1xX0jzjmXvMh0oSeKnKgbO2bDXIEyQ==", - "dependencies": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.7.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.2.0", - "webpack-sources": "^2.3.0" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/@docusaurus/core/node_modules/webpack/node_modules/schema-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.0.tgz", - "integrity": "sha512-tTEaeYkyIhEZ9uWgAjDerWov3T9MgX8dhhy2r0IGeeX4W8ngtGl1++dUve/RUqzuaASSh7shwCDJjEzthxki8w==", - "dependencies": { - "@types/json-schema": "^7.0.7", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/@docusaurus/core/node_modules/webpackbar": { "version": "5.0.0-3", "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-5.0.0-3.tgz", @@ -6075,29 +5972,6 @@ "node": ">=6.0.0" } }, - "node_modules/@docusaurus/mdx-loader/node_modules/@mdx-js/react": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.22.tgz", - "integrity": "sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0" - } - }, - "node_modules/@docusaurus/mdx-loader/node_modules/acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/@docusaurus/mdx-loader/node_modules/fs-extra": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", @@ -6111,94 +5985,10 @@ "node": ">=12" } }, - "node_modules/@docusaurus/mdx-loader/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@docusaurus/mdx-loader/node_modules/tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@docusaurus/mdx-loader/node_modules/terser-webpack-plugin": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz", - "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==", - "dependencies": { - "jest-worker": "^27.0.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - } - }, - "node_modules/@docusaurus/mdx-loader/node_modules/webpack": { - "version": "5.45.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.45.1.tgz", - "integrity": "sha512-68VT2ZgG9EHs6h6UxfV2SEYewA9BA3SOLSnC2NEbJJiEwbAiueDL033R1xX0jzjmXvMh0oSeKnKgbO2bDXIEyQ==", - "dependencies": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.7.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.2.0", - "webpack-sources": "^2.3.0" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, "node_modules/@docusaurus/module-type-aliases": { - "version": "2.0.0-alpha.72", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-2.0.0-alpha.72.tgz", - "integrity": "sha512-z8qGXvvyF8FYgnc0c7v5BqulrUJ0A01jsb2gT4miC6Gc/pKnpahZqBXcm1MrQiiUrlHMEjdOAxlHQVZuOwSSRQ==", + "version": "2.0.0-beta.6", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-2.0.0-beta.6.tgz", + "integrity": "sha512-TrJ0u4F3mZ7uQNga22why3SsoNwlHp6vltDLlWI80jZmZpnk9BJglpcR8MPOTSEjyUgMxJ6B3q0PA/rWzupWZA==", "dev": true }, "node_modules/@docusaurus/plugin-content-blog": { @@ -6231,17 +6021,6 @@ "react-dom": "^16.8.4 || ^17.0.0" } }, - "node_modules/@docusaurus/plugin-content-blog/node_modules/acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/@docusaurus/plugin-content-blog/node_modules/fs-extra": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", @@ -6255,90 +6034,6 @@ "node": ">=12" } }, - "node_modules/@docusaurus/plugin-content-blog/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@docusaurus/plugin-content-blog/node_modules/tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@docusaurus/plugin-content-blog/node_modules/terser-webpack-plugin": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz", - "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==", - "dependencies": { - "jest-worker": "^27.0.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - } - }, - "node_modules/@docusaurus/plugin-content-blog/node_modules/webpack": { - "version": "5.45.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.45.1.tgz", - "integrity": "sha512-68VT2ZgG9EHs6h6UxfV2SEYewA9BA3SOLSnC2NEbJJiEwbAiueDL033R1xX0jzjmXvMh0oSeKnKgbO2bDXIEyQ==", - "dependencies": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.7.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.2.0", - "webpack-sources": "^2.3.0" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, "node_modules/@docusaurus/plugin-content-docs": { "version": "2.0.0-beta.3", "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-2.0.0-beta.3.tgz", @@ -6373,22 +6068,6 @@ "react-dom": "^16.8.4 || ^17.0.0" } }, - "node_modules/@docusaurus/plugin-content-docs/node_modules/acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/@docusaurus/plugin-content-docs/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, "node_modules/@docusaurus/plugin-content-docs/node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -6471,17 +6150,6 @@ "node": ">=8" } }, - "node_modules/@docusaurus/plugin-content-docs/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/@docusaurus/plugin-content-docs/node_modules/json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", @@ -6517,90 +6185,6 @@ "node": ">=8" } }, - "node_modules/@docusaurus/plugin-content-docs/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@docusaurus/plugin-content-docs/node_modules/tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@docusaurus/plugin-content-docs/node_modules/terser-webpack-plugin": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz", - "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==", - "dependencies": { - "jest-worker": "^27.0.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - } - }, - "node_modules/@docusaurus/plugin-content-docs/node_modules/webpack": { - "version": "5.45.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.45.1.tgz", - "integrity": "sha512-68VT2ZgG9EHs6h6UxfV2SEYewA9BA3SOLSnC2NEbJJiEwbAiueDL033R1xX0jzjmXvMh0oSeKnKgbO2bDXIEyQ==", - "dependencies": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.7.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.2.0", - "webpack-sources": "^2.3.0" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, "node_modules/@docusaurus/plugin-content-pages": { "version": "2.0.0-beta.3", "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-2.0.0-beta.3.tgz", @@ -6627,101 +6211,6 @@ "react-dom": "^16.8.4 || ^17.0.0" } }, - "node_modules/@docusaurus/plugin-content-pages/node_modules/acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/@docusaurus/plugin-content-pages/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@docusaurus/plugin-content-pages/node_modules/tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@docusaurus/plugin-content-pages/node_modules/terser-webpack-plugin": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz", - "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==", - "dependencies": { - "jest-worker": "^27.0.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - } - }, - "node_modules/@docusaurus/plugin-content-pages/node_modules/webpack": { - "version": "5.45.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.45.1.tgz", - "integrity": "sha512-68VT2ZgG9EHs6h6UxfV2SEYewA9BA3SOLSnC2NEbJJiEwbAiueDL033R1xX0jzjmXvMh0oSeKnKgbO2bDXIEyQ==", - "dependencies": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.7.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.2.0", - "webpack-sources": "^2.3.0" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, "node_modules/@docusaurus/plugin-debug": { "version": "2.0.0-beta.3", "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-2.0.0-beta.3.tgz", @@ -6880,18 +6369,6 @@ "react-dom": "^16.8.4 || ^17.0.0" } }, - "node_modules/@docusaurus/theme-classic/node_modules/@mdx-js/react": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.22.tgz", - "integrity": "sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.0" - } - }, "node_modules/@docusaurus/theme-classic/node_modules/copy-text-to-clipboard": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.0.1.tgz", @@ -6981,101 +6458,6 @@ "webpack-merge": "^5.8.0" } }, - "node_modules/@docusaurus/types/node_modules/acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/@docusaurus/types/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@docusaurus/types/node_modules/tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@docusaurus/types/node_modules/terser-webpack-plugin": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz", - "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==", - "dependencies": { - "jest-worker": "^27.0.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - } - }, - "node_modules/@docusaurus/types/node_modules/webpack": { - "version": "5.45.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.45.1.tgz", - "integrity": "sha512-68VT2ZgG9EHs6h6UxfV2SEYewA9BA3SOLSnC2NEbJJiEwbAiueDL033R1xX0jzjmXvMh0oSeKnKgbO2bDXIEyQ==", - "dependencies": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.7.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.2.0", - "webpack-sources": "^2.3.0" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, "node_modules/@docusaurus/utils": { "version": "2.0.0-beta.3", "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-2.0.0-beta.3.tgz", @@ -7154,6 +6536,15 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "13.10.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", @@ -7169,6 +6560,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/@fortawesome/fontawesome-common-types": { "version": "0.2.35", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.35.tgz", @@ -7203,14 +6607,14 @@ } }, "node_modules/@fortawesome/react-fontawesome": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.14.tgz", - "integrity": "sha512-4wqNb0gRLVaBm/h+lGe8UfPPivcbuJ6ecI4hIgW0LjI7kzpYB9FkN0L9apbVzg+lsBdcTf0AlBtODjcSX5mmKA==", + "version": "0.1.16", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.16.tgz", + "integrity": "sha512-aLmzDwC9rEOAJv2UJdMns89VZR5Ry4IHu5dQQh24Z/lWKEm44lfQr1UNalZlkUaQN8d155tNh+CS7ntntj1VMA==", "dependencies": { "prop-types": "^15.7.2" }, "peerDependencies": { - "@fortawesome/fontawesome-svg-core": "^1.2.32", + "@fortawesome/fontawesome-svg-core": "~1 || >=1.3.0-beta1", "react": ">=16.x" } }, @@ -7648,6 +7052,18 @@ "node": ">=4" } }, + "node_modules/@mdx-js/react": { + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.22.tgz", + "integrity": "sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -7951,6 +7367,14 @@ "node": ">=4" } }, + "node_modules/@svgr/plugin-svgo/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, "node_modules/@svgr/plugin-svgo/node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -8076,6 +7500,18 @@ "node": ">=4" } }, + "node_modules/@svgr/plugin-svgo/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/@svgr/plugin-svgo/node_modules/mdn-data": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", @@ -8256,9 +7692,9 @@ "integrity": "sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w==" }, "node_modules/@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==" + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==" }, "node_modules/@types/lodash": { "version": "4.14.168", @@ -8890,12 +8326,9 @@ "integrity": "sha512-4P8Zm2H+BRS+c/xX1LrHw0qKpEhdlZjLCgWy+d78T9vqa2Z2SiD2wMrYuWIAFy5IZUD7nnNXroRttz+0RzlrzQ==" }, "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/arr-diff": { "version": "4.0.0", @@ -11323,9 +10756,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", - "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", + "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -11334,14 +10767,6 @@ "node": ">=10.13.0" } }, - "node_modules/enhanced-resolve/node_modules/tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", - "engines": { - "node": ">=6" - } - }, "node_modules/enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -11408,9 +10833,9 @@ } }, "node_modules/es-module-lexer": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz", - "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw==" + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", + "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==" }, "node_modules/es-to-primitive": { "version": "1.2.1", @@ -12127,6 +11552,15 @@ "@babel/highlight": "^7.10.4" } }, + "node_modules/eslint/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, "node_modules/eslint/node_modules/globals": { "version": "13.10.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", @@ -12142,6 +11576,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/espree": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", @@ -12713,23 +12160,6 @@ "webpack": "^4.0.0 || ^5.0.0" } }, - "node_modules/file-loader/node_modules/schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dependencies": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", @@ -13426,6 +12856,26 @@ "node": ">=6.0" } }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/gzip-size": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", @@ -14951,12 +14401,11 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" @@ -15876,6 +15325,15 @@ "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=" }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "dev": true, + "bin": { + "mustache": "bin/mustache" + } + }, "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", @@ -16112,24 +15570,6 @@ "node": ">=8.9.0" } }, - "node_modules/null-loader/node_modules/schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -19599,11 +19039,11 @@ } }, "node_modules/schema-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.0.tgz", - "integrity": "sha512-tTEaeYkyIhEZ9uWgAjDerWov3T9MgX8dhhy2r0IGeeX4W8ngtGl1++dUve/RUqzuaASSh7shwCDJjEzthxki8w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", "dependencies": { - "@types/json-schema": "^7.0.7", + "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" }, @@ -20217,9 +19657,9 @@ } }, "node_modules/source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -20799,14 +20239,22 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "engines": { + "node": ">=6" + } + }, "node_modules/terser": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.1.tgz", - "integrity": "sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.9.0.tgz", + "integrity": "sha512-h5hxa23sCdpzcye/7b8YqbE5OwKca/ni0RQz1uRX3tGh8haaGHqcuSqbGRybuAKNdntZ0mDgFNXPJ48xQ2RXKQ==", "dependencies": { "commander": "^2.20.0", "source-map": "~0.7.2", - "source-map-support": "~0.5.19" + "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" @@ -20815,6 +20263,48 @@ "node": ">=10" } }, + "node_modules/terser-webpack-plugin": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.2.4.tgz", + "integrity": "sha512-E2CkNMN+1cho04YpdANyRrn8CyN4yMy+WdFKZIySFZrGXZxJwJP6PMNGGc/Mcr6qygQHUUqRxnAPmi0M9f00XA==", + "dependencies": { + "jest-worker": "^27.0.6", + "p-limit": "^3.1.0", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1", + "terser": "^5.7.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -21465,23 +20955,6 @@ } } }, - "node_modules/url-loader/node_modules/schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dependencies": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/url-parse": { "version": "1.4.7", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", @@ -21748,6 +21221,52 @@ "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.19.4.tgz", "integrity": "sha512-8G0xBj05hqZybCqBtW7RPZ/hWEtP3DiLTauQzGJZuZYfVRgw7qj7iaZ+8djNqJ4VPrdOO+pS2dR1JsTbsLxdYg==" }, + "node_modules/webpack": { + "version": "5.58.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.58.2.tgz", + "integrity": "sha512-3S6e9Vo1W2ijk4F4PPWRIu6D/uGgqaPmqw+av3W3jLDujuNkdxX5h5c+RQ6GkjVR+WwIPOfgY8av+j5j4tMqJw==", + "dependencies": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.50", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.4.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.8.3", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.4", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.2.0", + "webpack-sources": "^3.2.0" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, "node_modules/webpack-bundle-analyzer": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.4.2.tgz", @@ -22412,23 +21931,30 @@ } }, "node_modules/webpack-sources": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.0.tgz", - "integrity": "sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ==", - "dependencies": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - }, + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.1.tgz", + "integrity": "sha512-t6BMVLQ0AkjBOoRTZgqrWm7xbXMBzD+XDq2EZ96+vMfn3qKgsvdXZhbPZ4ElUOpdv4u+iiGe+w3+J75iy/bYGA==", "engines": { "node": ">=10.13.0" } }, - "node_modules/webpack-sources/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/webpack/node_modules/acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "bin": { + "acorn": "bin/acorn" + }, "engines": { - "node": ">=0.10.0" + "node": ">=0.4.0" + } + }, + "node_modules/webpack/node_modules/acorn-import-assertions": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", + "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "peerDependencies": { + "acorn": "^8" } }, "node_modules/websocket-driver": { @@ -22850,6 +22376,27 @@ "@jsdevtools/ono": "^7.1.3", "call-me-maybe": "^1.0.1", "js-yaml": "^3.13.1" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + } } }, "@babel/code-frame": { @@ -24213,11 +23760,11 @@ } }, "@babel/generator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", - "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.8.tgz", + "integrity": "sha512-cYDUpvIzhBVnMzRoY1fkSEhK/HmwEVwlyULYgn/tMQYd6Obag3ylCjONle3gdErfXBW61SVTlR9QR7uWlgeIkg==", "requires": { - "@babel/types": "^7.14.5", + "@babel/types": "^7.14.8", "jsesc": "^2.5.1", "source-map": "^0.5.0" } @@ -24265,18 +23812,18 @@ } }, "@babel/helper-module-transforms": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz", - "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.8.tgz", + "integrity": "sha512-RyE+NFOjXn5A9YU1dkpeBaduagTlZ0+fccnIcAGbv1KGUlReBj7utF7oEth8IdIBQPcux0DDgW5MFBH2xu9KcA==", "requires": { "@babel/helper-module-imports": "^7.14.5", "@babel/helper-replace-supers": "^7.14.5", - "@babel/helper-simple-access": "^7.14.5", + "@babel/helper-simple-access": "^7.14.8", "@babel/helper-split-export-declaration": "^7.14.5", - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.8", "@babel/template": "^7.14.5", - "@babel/traverse": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/traverse": "^7.14.8", + "@babel/types": "^7.14.8" } }, "@babel/helper-optimise-call-expression": { @@ -24304,11 +23851,11 @@ } }, "@babel/helper-simple-access": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz", - "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz", + "integrity": "sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg==", "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.14.8" } }, "@babel/helper-split-export-declaration": { @@ -24320,15 +23867,9 @@ } }, "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz", - "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==", - "requires": { - "@babel/helper-member-expression-to-functions": "^7.14.5", - "@babel/helper-optimise-call-expression": "^7.14.5", - "@babel/traverse": "^7.14.5", - "@babel/types": "^7.14.5" - } + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.8.tgz", + "integrity": "sha512-ZGy6/XQjllhYQrNw/3zfWRwZCTVSiBLZ9DHVZxn9n2gip/7ab8mv2TWlKPIBk26RwedCBoWdjLmn+t9na2Gcow==" }, "@babel/highlight": { "version": "7.14.5", @@ -24341,9 +23882,9 @@ } }, "@babel/parser": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", - "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==" + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.8.tgz", + "integrity": "sha512-syoCQFOoo/fzkWDeM0dLEZi5xqurb5vuyzwIMNZRNun+N/9A4cUZeQaE7dTrB8jGaKuJRBtEOajtnmw0I5hvvA==" }, "@babel/template": { "version": "7.14.5", @@ -24356,27 +23897,27 @@ } }, "@babel/traverse": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz", - "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.8.tgz", + "integrity": "sha512-kexHhzCljJcFNn1KYAQ6A5wxMRzq9ebYpEDV4+WdNyr3i7O44tanbDOR/xjiG2F3sllan+LgwK+7OMk0EmydHg==", "requires": { "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.14.5", + "@babel/generator": "^7.14.8", "@babel/helper-function-name": "^7.14.5", "@babel/helper-hoist-variables": "^7.14.5", "@babel/helper-split-export-declaration": "^7.14.5", - "@babel/parser": "^7.14.7", - "@babel/types": "^7.14.5", + "@babel/parser": "^7.14.8", + "@babel/types": "^7.14.8", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", - "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.8.tgz", + "integrity": "sha512-iob4soQa7dZw8nodR/KlOQkPh9S4I8RwCxwRIFuiMRYjOzH/KJzdUfDgz6cGi5dDaclXF4P2PAhCdrBJNIg68Q==", "requires": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.8", "to-fast-properties": "^2.0.0" } }, @@ -25156,16 +24697,16 @@ } }, "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==" + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.8.tgz", + "integrity": "sha512-ZGy6/XQjllhYQrNw/3zfWRwZCTVSiBLZ9DHVZxn9n2gip/7ab8mv2TWlKPIBk26RwedCBoWdjLmn+t9na2Gcow==" }, "@babel/types": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", - "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.8.tgz", + "integrity": "sha512-iob4soQa7dZw8nodR/KlOQkPh9S4I8RwCxwRIFuiMRYjOzH/KJzdUfDgz6cGi5dDaclXF4P2PAhCdrBJNIg68Q==", "requires": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.8", "to-fast-properties": "^2.0.0" } } @@ -25235,11 +24776,11 @@ } }, "@babel/generator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", - "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.8.tgz", + "integrity": "sha512-cYDUpvIzhBVnMzRoY1fkSEhK/HmwEVwlyULYgn/tMQYd6Obag3ylCjONle3gdErfXBW61SVTlR9QR7uWlgeIkg==", "requires": { - "@babel/types": "^7.14.5", + "@babel/types": "^7.14.8", "jsesc": "^2.5.1", "source-map": "^0.5.0" } @@ -25253,13 +24794,13 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.14.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.6.tgz", - "integrity": "sha512-Z6gsfGofTxH/+LQXqYEK45kxmcensbzmk/oi8DmaQytlQCgqNZt9XQF8iqlI/SeXWVjaMNxvYvzaYw+kh42mDg==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.8.tgz", + "integrity": "sha512-bpYvH8zJBWzeqi1o+co8qOrw+EXzQ/0c74gVmY205AWXy9nifHrOg77y+1zwxX5lXE7Icq4sPlSQ4O2kWBrteQ==", "requires": { "@babel/helper-annotate-as-pure": "^7.14.5", "@babel/helper-function-name": "^7.14.5", - "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-member-expression-to-functions": "^7.14.7", "@babel/helper-optimise-call-expression": "^7.14.5", "@babel/helper-replace-supers": "^7.14.5", "@babel/helper-split-export-declaration": "^7.14.5" @@ -25332,9 +24873,9 @@ } }, "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==" + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.8.tgz", + "integrity": "sha512-ZGy6/XQjllhYQrNw/3zfWRwZCTVSiBLZ9DHVZxn9n2gip/7ab8mv2TWlKPIBk26RwedCBoWdjLmn+t9na2Gcow==" }, "@babel/highlight": { "version": "7.14.5", @@ -25347,9 +24888,9 @@ } }, "@babel/parser": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", - "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==" + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.8.tgz", + "integrity": "sha512-syoCQFOoo/fzkWDeM0dLEZi5xqurb5vuyzwIMNZRNun+N/9A4cUZeQaE7dTrB8jGaKuJRBtEOajtnmw0I5hvvA==" }, "@babel/plugin-syntax-typescript": { "version": "7.14.5", @@ -25370,27 +24911,27 @@ } }, "@babel/traverse": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz", - "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.8.tgz", + "integrity": "sha512-kexHhzCljJcFNn1KYAQ6A5wxMRzq9ebYpEDV4+WdNyr3i7O44tanbDOR/xjiG2F3sllan+LgwK+7OMk0EmydHg==", "requires": { "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.14.5", + "@babel/generator": "^7.14.8", "@babel/helper-function-name": "^7.14.5", "@babel/helper-hoist-variables": "^7.14.5", "@babel/helper-split-export-declaration": "^7.14.5", - "@babel/parser": "^7.14.7", - "@babel/types": "^7.14.5", + "@babel/parser": "^7.14.8", + "@babel/types": "^7.14.8", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", - "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.8.tgz", + "integrity": "sha512-iob4soQa7dZw8nodR/KlOQkPh9S4I8RwCxwRIFuiMRYjOzH/KJzdUfDgz6cGi5dDaclXF4P2PAhCdrBJNIg68Q==", "requires": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.8", "to-fast-properties": "^2.0.0" } }, @@ -25479,16 +25020,16 @@ "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==" }, "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==" + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.8.tgz", + "integrity": "sha512-ZGy6/XQjllhYQrNw/3zfWRwZCTVSiBLZ9DHVZxn9n2gip/7ab8mv2TWlKPIBk26RwedCBoWdjLmn+t9na2Gcow==" }, "@babel/types": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", - "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.8.tgz", + "integrity": "sha512-iob4soQa7dZw8nodR/KlOQkPh9S4I8RwCxwRIFuiMRYjOzH/KJzdUfDgz6cGi5dDaclXF4P2PAhCdrBJNIg68Q==", "requires": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.8", "to-fast-properties": "^2.0.0" } } @@ -25669,9 +25210,9 @@ } }, "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==" + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.8.tgz", + "integrity": "sha512-ZGy6/XQjllhYQrNw/3zfWRwZCTVSiBLZ9DHVZxn9n2gip/7ab8mv2TWlKPIBk26RwedCBoWdjLmn+t9na2Gcow==" }, "@babel/highlight": { "version": "7.14.5", @@ -25684,9 +25225,9 @@ } }, "@babel/parser": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", - "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==" + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.8.tgz", + "integrity": "sha512-syoCQFOoo/fzkWDeM0dLEZi5xqurb5vuyzwIMNZRNun+N/9A4cUZeQaE7dTrB8jGaKuJRBtEOajtnmw0I5hvvA==" }, "ansi-styles": { "version": "3.2.1", @@ -25750,21 +25291,21 @@ } }, "@babel/generator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", - "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.8.tgz", + "integrity": "sha512-cYDUpvIzhBVnMzRoY1fkSEhK/HmwEVwlyULYgn/tMQYd6Obag3ylCjONle3gdErfXBW61SVTlR9QR7uWlgeIkg==", "requires": { - "@babel/types": "^7.14.5", + "@babel/types": "^7.14.8", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, "dependencies": { "@babel/types": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", - "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.8.tgz", + "integrity": "sha512-iob4soQa7dZw8nodR/KlOQkPh9S4I8RwCxwRIFuiMRYjOzH/KJzdUfDgz6cGi5dDaclXF4P2PAhCdrBJNIg68Q==", "requires": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.8", "to-fast-properties": "^2.0.0" } } @@ -25781,11 +25322,11 @@ }, "dependencies": { "@babel/types": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", - "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.8.tgz", + "integrity": "sha512-iob4soQa7dZw8nodR/KlOQkPh9S4I8RwCxwRIFuiMRYjOzH/KJzdUfDgz6cGi5dDaclXF4P2PAhCdrBJNIg68Q==", "requires": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.8", "to-fast-properties": "^2.0.0" } } @@ -25800,11 +25341,11 @@ }, "dependencies": { "@babel/types": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", - "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.8.tgz", + "integrity": "sha512-iob4soQa7dZw8nodR/KlOQkPh9S4I8RwCxwRIFuiMRYjOzH/KJzdUfDgz6cGi5dDaclXF4P2PAhCdrBJNIg68Q==", "requires": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.8", "to-fast-properties": "^2.0.0" } } @@ -25819,20 +25360,20 @@ }, "dependencies": { "@babel/types": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", - "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.8.tgz", + "integrity": "sha512-iob4soQa7dZw8nodR/KlOQkPh9S4I8RwCxwRIFuiMRYjOzH/KJzdUfDgz6cGi5dDaclXF4P2PAhCdrBJNIg68Q==", "requires": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.8", "to-fast-properties": "^2.0.0" } } } }, "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==" + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.8.tgz", + "integrity": "sha512-ZGy6/XQjllhYQrNw/3zfWRwZCTVSiBLZ9DHVZxn9n2gip/7ab8mv2TWlKPIBk26RwedCBoWdjLmn+t9na2Gcow==" }, "@babel/highlight": { "version": "7.14.5", @@ -25845,9 +25386,9 @@ } }, "@babel/parser": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", - "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==" + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.8.tgz", + "integrity": "sha512-syoCQFOoo/fzkWDeM0dLEZi5xqurb5vuyzwIMNZRNun+N/9A4cUZeQaE7dTrB8jGaKuJRBtEOajtnmw0I5hvvA==" }, "@babel/template": { "version": "7.14.5", @@ -25860,11 +25401,11 @@ }, "dependencies": { "@babel/types": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", - "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.8.tgz", + "integrity": "sha512-iob4soQa7dZw8nodR/KlOQkPh9S4I8RwCxwRIFuiMRYjOzH/KJzdUfDgz6cGi5dDaclXF4P2PAhCdrBJNIg68Q==", "requires": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.8", "to-fast-properties": "^2.0.0" } } @@ -25918,9 +25459,9 @@ }, "dependencies": { "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==" + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.8.tgz", + "integrity": "sha512-ZGy6/XQjllhYQrNw/3zfWRwZCTVSiBLZ9DHVZxn9n2gip/7ab8mv2TWlKPIBk26RwedCBoWdjLmn+t9na2Gcow==" } } }, @@ -26819,11 +26360,6 @@ "to-fast-properties": "^2.0.0" } }, - "acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==" - }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -27120,41 +26656,6 @@ "has-flag": "^3.0.0" } }, - "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" - }, - "terser-webpack-plugin": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz", - "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==", - "requires": { - "jest-worker": "^27.0.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.0" - }, - "dependencies": { - "schema-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.0.tgz", - "integrity": "sha512-tTEaeYkyIhEZ9uWgAjDerWov3T9MgX8dhhy2r0IGeeX4W8ngtGl1++dUve/RUqzuaASSh7shwCDJjEzthxki8w==", - "requires": { - "@types/json-schema": "^7.0.7", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, "update-notifier": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", @@ -27176,48 +26677,6 @@ "xdg-basedir": "^4.0.0" } }, - "webpack": { - "version": "5.45.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.45.1.tgz", - "integrity": "sha512-68VT2ZgG9EHs6h6UxfV2SEYewA9BA3SOLSnC2NEbJJiEwbAiueDL033R1xX0jzjmXvMh0oSeKnKgbO2bDXIEyQ==", - "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.7.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.2.0", - "webpack-sources": "^2.3.0" - }, - "dependencies": { - "schema-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.0.tgz", - "integrity": "sha512-tTEaeYkyIhEZ9uWgAjDerWov3T9MgX8dhhy2r0IGeeX4W8ngtGl1++dUve/RUqzuaASSh7shwCDJjEzthxki8w==", - "requires": { - "@types/json-schema": "^7.0.7", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, "webpackbar": { "version": "5.0.0-3", "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-5.0.0-3.tgz", @@ -27274,17 +26733,6 @@ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==" }, - "@mdx-js/react": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.22.tgz", - "integrity": "sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==", - "requires": {} - }, - "acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==" - }, "fs-extra": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", @@ -27294,66 +26742,13 @@ "jsonfile": "^6.0.1", "universalify": "^2.0.0" } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" - }, - "terser-webpack-plugin": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz", - "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==", - "requires": { - "jest-worker": "^27.0.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.0" - } - }, - "webpack": { - "version": "5.45.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.45.1.tgz", - "integrity": "sha512-68VT2ZgG9EHs6h6UxfV2SEYewA9BA3SOLSnC2NEbJJiEwbAiueDL033R1xX0jzjmXvMh0oSeKnKgbO2bDXIEyQ==", - "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.7.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.2.0", - "webpack-sources": "^2.3.0" - } } } }, "@docusaurus/module-type-aliases": { - "version": "2.0.0-beta.3", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-2.0.0-beta.3.tgz", - "integrity": "sha512-vciejziDBu39cyfmdvbpn865YlvugJMUOeD2m/7Kg4RLUPIZzQTWns0ZGIMc/iToiwebHwkoJtRsHaHzj8FpnA==", + "version": "2.0.0-beta.6", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-2.0.0-beta.6.tgz", + "integrity": "sha512-TrJ0u4F3mZ7uQNga22why3SsoNwlHp6vltDLlWI80jZmZpnk9BJglpcR8MPOTSEjyUgMxJ6B3q0PA/rWzupWZA==", "dev": true }, "@docusaurus/plugin-content-blog": { @@ -27379,11 +26774,6 @@ "webpack": "^5.40.0" }, "dependencies": { - "acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==" - }, "fs-extra": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", @@ -27393,59 +26783,6 @@ "jsonfile": "^6.0.1", "universalify": "^2.0.0" } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" - }, - "terser-webpack-plugin": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz", - "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==", - "requires": { - "jest-worker": "^27.0.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.0" - } - }, - "webpack": { - "version": "5.45.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.45.1.tgz", - "integrity": "sha512-68VT2ZgG9EHs6h6UxfV2SEYewA9BA3SOLSnC2NEbJJiEwbAiueDL033R1xX0jzjmXvMh0oSeKnKgbO2bDXIEyQ==", - "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.7.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.2.0", - "webpack-sources": "^2.3.0" - } } } }, @@ -27476,16 +26813,6 @@ "webpack": "^5.40.0" }, "dependencies": { - "acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==" - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -27541,14 +26868,6 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "requires": { - "argparse": "^2.0.1" - } - }, "json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", @@ -27574,59 +26893,6 @@ "requires": { "path-key": "^3.0.0" } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" - }, - "terser-webpack-plugin": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz", - "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==", - "requires": { - "jest-worker": "^27.0.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.0" - } - }, - "webpack": { - "version": "5.45.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.45.1.tgz", - "integrity": "sha512-68VT2ZgG9EHs6h6UxfV2SEYewA9BA3SOLSnC2NEbJJiEwbAiueDL033R1xX0jzjmXvMh0oSeKnKgbO2bDXIEyQ==", - "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.7.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.2.0", - "webpack-sources": "^2.3.0" - } } } }, @@ -27647,66 +26913,6 @@ "slash": "^3.0.0", "tslib": "^2.1.0", "webpack": "^5.40.0" - }, - "dependencies": { - "acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" - }, - "terser-webpack-plugin": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz", - "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==", - "requires": { - "jest-worker": "^27.0.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.0" - } - }, - "webpack": { - "version": "5.45.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.45.1.tgz", - "integrity": "sha512-68VT2ZgG9EHs6h6UxfV2SEYewA9BA3SOLSnC2NEbJJiEwbAiueDL033R1xX0jzjmXvMh0oSeKnKgbO2bDXIEyQ==", - "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.7.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.2.0", - "webpack-sources": "^2.3.0" - } - } } }, "@docusaurus/plugin-debug": { @@ -27821,12 +27027,6 @@ "rtlcss": "^3.1.2" }, "dependencies": { - "@mdx-js/react": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.22.tgz", - "integrity": "sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==", - "requires": {} - }, "copy-text-to-clipboard": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.0.1.tgz", @@ -27890,66 +27090,6 @@ "querystring": "0.2.0", "webpack": "^5.40.0", "webpack-merge": "^5.8.0" - }, - "dependencies": { - "acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" - }, - "terser-webpack-plugin": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz", - "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==", - "requires": { - "jest-worker": "^27.0.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.0" - } - }, - "webpack": { - "version": "5.45.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.45.1.tgz", - "integrity": "sha512-68VT2ZgG9EHs6h6UxfV2SEYewA9BA3SOLSnC2NEbJJiEwbAiueDL033R1xX0jzjmXvMh0oSeKnKgbO2bDXIEyQ==", - "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.4.1", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.7.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.2.0", - "webpack-sources": "^2.3.0" - } - } } }, "@docusaurus/utils": { @@ -28017,6 +27157,15 @@ "strip-json-comments": "^3.1.1" }, "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, "globals": { "version": "13.10.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", @@ -28025,6 +27174,16 @@ "requires": { "type-fest": "^0.20.2" } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } } } }, @@ -28050,9 +27209,9 @@ } }, "@fortawesome/react-fontawesome": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.14.tgz", - "integrity": "sha512-4wqNb0gRLVaBm/h+lGe8UfPPivcbuJ6ecI4hIgW0LjI7kzpYB9FkN0L9apbVzg+lsBdcTf0AlBtODjcSX5mmKA==", + "version": "0.1.16", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.16.tgz", + "integrity": "sha512-aLmzDwC9rEOAJv2UJdMns89VZR5Ry4IHu5dQQh24Z/lWKEm44lfQr1UNalZlkUaQN8d155tNh+CS7ntntj1VMA==", "requires": { "prop-types": "^15.7.2" } @@ -28406,7 +27565,8 @@ "@mdx-js/react": { "version": "1.6.22", "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.22.tgz", - "integrity": "sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==" + "integrity": "sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==", + "requires": {} }, "@nodelib/fs.scandir": { "version": "2.1.5", @@ -28603,6 +27763,14 @@ "color-convert": "^1.9.0" } }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -28703,6 +27871,15 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, "mdn-data": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", @@ -28855,9 +28032,9 @@ "integrity": "sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w==" }, "@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==" + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==" }, "@types/lodash": { "version": "4.14.168", @@ -29418,12 +28595,9 @@ "integrity": "sha512-4P8Zm2H+BRS+c/xX1LrHw0qKpEhdlZjLCgWy+d78T9vqa2Z2SiD2wMrYuWIAFy5IZUD7nnNXroRttz+0RzlrzQ==" }, "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "arr-diff": { "version": "4.0.0", @@ -30567,9 +29741,9 @@ } }, "electron-to-chromium": { - "version": "1.3.779", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.779.tgz", - "integrity": "sha512-nreave0y/1Qhmo8XtO6C/LpawNyC6U26+q7d814/e+tIqUK073pM+4xW7WUXyqCRa5K4wdxHmNMBAi8ap9nEew==" + "version": "1.3.788", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.788.tgz", + "integrity": "sha512-dbMIpX4E4/Gk4gzOh1GYS7ls1vGsByWKpIqLviJi1mSmSt5BvrWLLtSqpFE5BaC7Ef4NnI0GMaiddNX2Brw6zA==" }, "semver": { "version": "7.0.0", @@ -31256,19 +30430,12 @@ } }, "enhanced-resolve": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", - "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", + "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", "requires": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" - }, - "dependencies": { - "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" - } } }, "enquirer": { @@ -31322,9 +30489,9 @@ } }, "es-module-lexer": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz", - "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw==" + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", + "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==" }, "es-to-primitive": { "version": "1.2.1", @@ -31457,6 +30624,15 @@ "@babel/highlight": "^7.10.4" } }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, "globals": { "version": "13.10.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", @@ -31465,6 +30641,16 @@ "requires": { "type-fest": "^0.20.2" } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } } } }, @@ -32366,18 +31552,6 @@ "requires": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0" - }, - "dependencies": { - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } } }, "file-uri-to-path": { @@ -32909,6 +32083,25 @@ "kind-of": "^6.0.2", "section-matter": "^1.0.0", "strip-bom-string": "^1.0.0" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + } } }, "gzip-size": { @@ -34055,12 +33248,11 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" } }, "jsesc": { @@ -34965,17 +34157,6 @@ "emojis-list": "^3.0.0", "json5": "^2.1.2" } - }, - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } } } }, @@ -35933,9 +35114,9 @@ } }, "electron-to-chromium": { - "version": "1.3.779", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.779.tgz", - "integrity": "sha512-nreave0y/1Qhmo8XtO6C/LpawNyC6U26+q7d814/e+tIqUK073pM+4xW7WUXyqCRa5K4wdxHmNMBAi8ap9nEew==" + "version": "1.3.788", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.788.tgz", + "integrity": "sha512-dbMIpX4E4/Gk4gzOh1GYS7ls1vGsByWKpIqLviJi1mSmSt5BvrWLLtSqpFE5BaC7Ef4NnI0GMaiddNX2Brw6zA==" }, "postcss-value-parser": { "version": "4.1.0", @@ -36006,9 +35187,9 @@ } }, "electron-to-chromium": { - "version": "1.3.779", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.779.tgz", - "integrity": "sha512-nreave0y/1Qhmo8XtO6C/LpawNyC6U26+q7d814/e+tIqUK073pM+4xW7WUXyqCRa5K4wdxHmNMBAi8ap9nEew==" + "version": "1.3.788", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.788.tgz", + "integrity": "sha512-dbMIpX4E4/Gk4gzOh1GYS7ls1vGsByWKpIqLviJi1mSmSt5BvrWLLtSqpFE5BaC7Ef4NnI0GMaiddNX2Brw6zA==" } } }, @@ -37576,11 +36757,11 @@ } }, "schema-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.0.tgz", - "integrity": "sha512-tTEaeYkyIhEZ9uWgAjDerWov3T9MgX8dhhy2r0IGeeX4W8ngtGl1++dUve/RUqzuaASSh7shwCDJjEzthxki8w==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", "requires": { - "@types/json-schema": "^7.0.7", + "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } @@ -38082,9 +37263,9 @@ } }, "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -38406,9 +37587,9 @@ } }, "electron-to-chromium": { - "version": "1.3.779", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.779.tgz", - "integrity": "sha512-nreave0y/1Qhmo8XtO6C/LpawNyC6U26+q7d814/e+tIqUK073pM+4xW7WUXyqCRa5K4wdxHmNMBAi8ap9nEew==" + "version": "1.3.788", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.788.tgz", + "integrity": "sha512-dbMIpX4E4/Gk4gzOh1GYS7ls1vGsByWKpIqLviJi1mSmSt5BvrWLLtSqpFE5BaC7Ef4NnI0GMaiddNX2Brw6zA==" }, "postcss-selector-parser": { "version": "6.0.6", @@ -38532,19 +37713,18 @@ } }, "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", - "dev": true + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "terser": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.1.tgz", - "integrity": "sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.9.0.tgz", + "integrity": "sha512-h5hxa23sCdpzcye/7b8YqbE5OwKca/ni0RQz1uRX3tGh8haaGHqcuSqbGRybuAKNdntZ0mDgFNXPJ48xQ2RXKQ==", "requires": { "commander": "^2.20.0", "source-map": "~0.7.2", - "source-map-support": "~0.5.19" + "source-map-support": "~0.5.20" }, "dependencies": { "commander": { @@ -38560,24 +37740,22 @@ } }, "terser-webpack-plugin": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz", - "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==", - "dev": true, + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.2.4.tgz", + "integrity": "sha512-E2CkNMN+1cho04YpdANyRrn8CyN4yMy+WdFKZIySFZrGXZxJwJP6PMNGGc/Mcr6qygQHUUqRxnAPmi0M9f00XA==", "requires": { - "jest-worker": "^27.0.2", + "jest-worker": "^27.0.6", "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", + "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.0", "source-map": "^0.6.1", - "terser": "^5.7.0" + "terser": "^5.7.2" }, "dependencies": { "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, @@ -39042,18 +38220,6 @@ "loader-utils": "^2.0.0", "mime-types": "^2.1.27", "schema-utils": "^3.0.0" - }, - "dependencies": { - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } } }, "url-parse": { @@ -39249,10 +38415,9 @@ "integrity": "sha512-8G0xBj05hqZybCqBtW7RPZ/hWEtP3DiLTauQzGJZuZYfVRgw7qj7iaZ+8djNqJ4VPrdOO+pS2dR1JsTbsLxdYg==" }, "webpack": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.46.0.tgz", - "integrity": "sha512-qxD0t/KTedJbpcXUmvMxY5PUvXDbF8LsThCzqomeGaDlCA6k998D8yYVwZMvO8sSM3BTEOaD4uzFniwpHaTIJw==", - "dev": true, + "version": "5.58.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.58.2.tgz", + "integrity": "sha512-3S6e9Vo1W2ijk4F4PPWRIu6D/uGgqaPmqw+av3W3jLDujuNkdxX5h5c+RQ6GkjVR+WwIPOfgY8av+j5j4tMqJw==", "requires": { "@types/eslint-scope": "^3.7.0", "@types/estree": "^0.0.50", @@ -39260,10 +38425,11 @@ "@webassemblyjs/wasm-edit": "1.11.1", "@webassemblyjs/wasm-parser": "1.11.1", "acorn": "^8.4.1", + "acorn-import-assertions": "^1.7.6", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.7.1", + "enhanced-resolve": "^5.8.3", + "es-module-lexer": "^0.9.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", @@ -39276,30 +38442,19 @@ "tapable": "^2.1.1", "terser-webpack-plugin": "^5.1.3", "watchpack": "^2.2.0", - "webpack-sources": "^2.3.1" + "webpack-sources": "^3.2.0" }, "dependencies": { "acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", - "dev": true + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==" }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "webpack-sources": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", - "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", - "dev": true, - "requires": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - } + "acorn-import-assertions": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", + "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "requires": {} } } }, @@ -39771,9 +38926,9 @@ } }, "url-parse": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz", - "integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz", + "integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==", "requires": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -39819,20 +38974,9 @@ } }, "webpack-sources": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.0.tgz", - "integrity": "sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ==", - "requires": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.1.tgz", + "integrity": "sha512-t6BMVLQ0AkjBOoRTZgqrWm7xbXMBzD+XDq2EZ96+vMfn3qKgsvdXZhbPZ4ElUOpdv4u+iiGe+w3+J75iy/bYGA==" }, "websocket-driver": { "version": "0.7.4", diff --git a/docs/package.json b/docs/package.json index c7f3bcd2..f8b65cee 100644 --- a/docs/package.json +++ b/docs/package.json @@ -19,15 +19,16 @@ "@docusaurus/preset-classic": "^2.0.0-beta.3", "@fortawesome/fontawesome-svg-core": "^1.2.32", "@fortawesome/free-solid-svg-icons": "^5.15.3", - "@fortawesome/react-fontawesome": "^0.1.14", + "@fortawesome/react-fontawesome": "^0.1.16", + "@mdx-js/react": "^1.6.22", "classnames": "^2.2.6", + "js-yaml": "^4.1.0", "react": "^17.0.2", "react-async": "^10.0.1", "react-copy-to-clipboard": "^5.0.3", "react-dom": "^17.0.2", "react-toastify": "^7.0.4", - "web-tree-sitter": "^0.19.4", - "@mdx-js/react": "^1.6.22" + "web-tree-sitter": "^0.19.4" }, "browserslist": { "production": [ @@ -42,6 +43,11 @@ ] }, "devDependencies": { + "@docusaurus/module-type-aliases": "^2.0.0-beta.3", + "@tsconfig/docusaurus": "^1.0.2", + "@types/react": "^17.0.3", + "@types/react-helmet": "^6.1.0", + "@types/react-router-dom": "^5.1.7", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-mdx": "^1.13.0", @@ -53,11 +59,6 @@ "prettier": "2.3.1", "string-replace-loader": "^3.0.3", "typescript": "^4.2.3", - "webpack": "^5.46.0", - "@docusaurus/module-type-aliases": "^2.0.0-beta.3", - "@tsconfig/docusaurus": "^1.0.2", - "@types/react": "^17.0.3", - "@types/react-helmet": "^6.1.0", - "@types/react-router-dom": "^5.1.7" + "webpack": "^5.46.0" } } diff --git a/docs/sidebars.js b/docs/sidebars.js index 8865b577..04389695 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -11,6 +11,8 @@ module.exports = { Features: [ "features/keymaps", "features/combos", + "features/conditional-layers", + "features/debouncing", "features/displays", "features/encoders", "features/underglow", diff --git a/docs/src/hardware-metadata-collection-plugin/index.js b/docs/src/hardware-metadata-collection-plugin/index.js index 5f5660bb..89f057a8 100644 --- a/docs/src/hardware-metadata-collection-plugin/index.js +++ b/docs/src/hardware-metadata-collection-plugin/index.js @@ -12,7 +12,7 @@ const glob = require("glob"); function generateHardwareMetadataAggregate() { glob("../app/boards/**/*.zmk.yml", (error, files) => { const aggregated = files.flatMap((f) => - yaml.safeLoadAll(fs.readFileSync(f, "utf8")) + yaml.loadAll(fs.readFileSync(f, "utf8")) ); fs.writeFileSync( "src/data/hardware-metadata.json", diff --git a/docs/src/setup-script-generation-plugin/index.js b/docs/src/setup-script-generation-plugin/index.js index e97a4d0f..908ac659 100644 --- a/docs/src/setup-script-generation-plugin/index.js +++ b/docs/src/setup-script-generation-plugin/index.js @@ -5,6 +5,7 @@ */ var PrebuildPlugin = require("prebuild-webpack-plugin"); +const path = require("path"); const fs = require("fs"); const glob = require("glob"); const yaml = require("js-yaml"); @@ -12,9 +13,10 @@ const Mustache = require("mustache"); function generateSetupScripts() { return glob("../app/boards/**/*.zmk.yml", (error, files) => { - const aggregated = files.flatMap((f) => - yaml.safeLoadAll(fs.readFileSync(f, "utf8")) - ); + const aggregated = files.map((f) => ({ + ...yaml.load(fs.readFileSync(f, "utf8")), + __base_dir: path.basename(path.dirname(f)), + })); const data = aggregated.reduce( (agg, item) => { @@ -25,7 +27,9 @@ function generateSetupScripts() { agg.keyboards.push(item); break; case "board": - if (!item.features?.includes("keys")) { + if (item.features?.includes("keys")) { + agg.keyboards.push(item); + } else { agg.boards.push(item); } break; @@ -35,6 +39,9 @@ function generateSetupScripts() { { keyboards: [], boards: [] } ); + data.keyboards.sort((a, b) => a.name.localeCompare(b.name)); + data.boards.sort((a, b) => a.name.localeCompare(b.name)); + for (let script_ext of ["sh", "ps1"]) { const templateBuffer = fs.readFileSync( `src/templates/setup.${script_ext}.mustache`, diff --git a/docs/src/templates/setup.ps1.mustache b/docs/src/templates/setup.ps1.mustache index ade8d134..4af4d79d 100644 --- a/docs/src/templates/setup.ps1.mustache +++ b/docs/src/templates/setup.ps1.mustache @@ -84,36 +84,59 @@ if (Test-CommandExists Get-Acl) { } } -$repo_path = "https://github.com/zmkfirmware/zmk-config-split-template.git" +$repo_path = "https://github.com/zmkfirmware/unified-zmk-config-template.git" $title = "ZMK Config Setup:" -$prompt = "Pick an MCU board" -$options = {{#boards}}"{{{name}}}", {{/boards}} "" | Where-Object { $_ -ne "" } -$boards = {{#boards}}"{{id}}", {{/boards}} "" | Where-Object { $_ -ne "" } - -Write-Host "$title" -Write-Host "" -Write-Host "MCU Board Selection:" - -$choice = Get-Choice-From-Options -Options $options -Prompt $prompt -$board = $($boards[$choice]) - Write-Host "" Write-Host "Keyboard Shield Selection:" $prompt = "Pick a keyboard" +$keyboards = [ordered]@{ + {{#keyboards}} + "{{id}}" = @{ + name = "{{{name}}}"; + type = "{{type}}"; + basedir = "{{__base_dir}}"; + split = "{{split}}"; + arch = "{{arch}}"; + siblings = {{#siblings.0}}@( + {{#siblings}} + "{{.}}" + {{/siblings}} + ){{/siblings.0}}{{^siblings.0}}( "{{id}}" ){{/siblings.0}}; + } + {{/keyboards}} +} # TODO: Add support for "Other" and linking to docs on adding custom shields in user config repos. -$options = {{#keyboards}}"{{name}}", {{/keyboards}} "" | Where-Object { $_ -ne "" } -$names = {{#keyboards}}"{{id}}", {{/keyboards}} "" | Where-Object { $_ -ne "" } -$splits = {{#keyboards}}"{{#split}}y{{/split}}{{^split}}n{{/split}}", {{/keyboards}} "" | Where-Object { $_ -ne "" } -$choice = Get-Choice-From-Options -Options $options -Prompt $prompt -$shield_title = $($options[$choice]) -$shield = $($names[$choice]) -$split = $($splits[$choice]) +$choice = Get-Choice-From-Options -Options ($keyboards.values | % { $_['name'] }) -Prompt $prompt +$keyboard = $($($keyboards.keys)[$choice]) +$keyboard_title = $keyboards[$keyboard].name +$basedir = $keyboards[$keyboard].basedir +$keyboard_split = $keyboards[$keyboard].split +$keyboard_arch = $keyboards[$keyboard].arch +$keyboard_siblings = $keyboards[$keyboard].siblings +$keyboard_type = $keyboards[$keyboard].type -if ($split -eq "n") { - $repo_path = "https://github.com/zmkfirmware/zmk-config-template.git" +if ($keyboard_type -eq "shield") { + $prompt = "Pick an MCU board" + $boards = [ordered]@{ + {{#boards}} + {{id}} = "{{{name}}}"; + {{/boards}} + } + + Write-Host "$title" + Write-Host "" + Write-Host "MCU Board Selection:" + + $choice = Get-Choice-From-Options -Options $boards.values -Prompt $prompt + $shields = $keyboard_siblings + $board = $($($boards.keys)[$choice]) + $boards = ( $board ) +} else { + $boards = ( $keyboard_siblings ) + $shields = @( ) } $copy_keymap = Read-Host "Copy in the stock keymap for customisation? [Yn]" @@ -144,8 +167,12 @@ else { Write-Host "" Write-Host "Preparing a user config for:" -Write-Host "* MCU Board: ${board}" -Write-Host "* Shield: ${shield}" +if ($keyboard_type -eq "shield") { + Write-Host "* MCU Board: ${boards}" + Write-Host "* Shield(s): ${shields}" +} else { + Write-Host "* Board(s): ${boards}" +} if ($copy_keymap -eq "yes") { Write-Host "* Copy Keymap?: Yes" @@ -171,24 +198,43 @@ Set-Location "$repo_name" Push-Location config -Invoke-RestMethod -Uri "https://raw.githubusercontent.com/zmkfirmware/zmk/main/app/boards/shields/${shield}/${shield}.conf" -OutFile "${shield}.conf" +$config_file = "${keyboard}.conf" +$keymap_file = "${keyboard}.keymap" + +if ($keyboard_type -eq "shield") { + $config_url = "https://raw.githubusercontent.com/zmkfirmware/zmk/main/app/boards/shields/${basedir}/${keyboard}.conf" + $keymap_url = "https://raw.githubusercontent.com/zmkfirmware/zmk/main/app/boards/shields/${basedir}/${keyboard}.keymap" +} else { + $config_url = "https://raw.githubusercontent.com/zmkfirmware/zmk/main/app/boards/${keyboard_arch}/${basedir}/${keyboard}.conf" + $keymap_url = "https://raw.githubusercontent.com/zmkfirmware/zmk/main/app/boards/${keyboard_arch}/${basedir}/${keyboard}.keymap" +} + +Write-Host "Downloading config file (${config_url})" +Try { + Invoke-RestMethod -Uri "${config_url}" -OutFile "${config_file}" +} Catch { + Set-Content -Path $config_file "# Place configuration items here" +} if ($copy_keymap -eq "yes") { - Invoke-RestMethod -Uri "https://raw.githubusercontent.com/zmkfirmware/zmk/main/app/boards/shields/${shield}/${shield}.keymap" -OutFile "${shield}.keymap" + Write-Host "Downloading keymap file (${keymap_url})" + Invoke-RestMethod -Uri "${keymap_url}" -OutFile "${keymap_file}" } Pop-Location -$build_file = (Get-Content .github/workflows/build.yml).replace("BOARD_NAME", $board) -$build_file = $build_file.replace("SHIELD_NAME", $shield) -$build_file = $build_file.replace("KEYBOARD_TITLE", $shield_title) - -if ($board -eq "proton_c") { - $build_file = $build_file.replace("uf2", "hex") +Add-Content -Path "build.yaml" -Value "include:" +foreach ($b in ${boards}) { + if ($keyboard_type -eq "shield") { + foreach ($s in ${shields}) { + Add-Content -Path "build.yaml" -Value " - board: $b" + Add-Content -Path "build.yaml" -Value " shield: $s" + } + } else { + Add-Content -Path "build.yaml" -Value " - board: $b" + } } -Set-Content -Path .github/workflows/build.yml -Value $build_file - Remove-Item -Recurse -Force .git git init . git add . diff --git a/docs/src/templates/setup.sh.mustache b/docs/src/templates/setup.sh.mustache index 9dbdcfd6..54405fae 100644 --- a/docs/src/templates/setup.sh.mustache +++ b/docs/src/templates/setup.sh.mustache @@ -51,7 +51,7 @@ if [[ $curl_exists == "true" && $wget_exists == "true" ]]; then if [[ $force_wget == "true" ]]; then download_command="wget " else - download_command="curl -O " + download_command="curl -fsOL " fi elif [[ $curl_exists == "true" ]]; then download_command="curl -O " @@ -62,7 +62,7 @@ else exit 1 fi -repo_path="https://github.com/zmkfirmware/zmk-config-split-template.git" +repo_path="https://github.com/zmkfirmware/unified-zmk-config-template.git" title="ZMK Config Setup:" echo "" @@ -71,8 +71,17 @@ PS3="Pick a keyboard: " options=({{#keyboards}}"{{{name}}}" {{/keyboards}}) keyboards_id=({{#keyboards}}"{{id}}" {{/keyboards}}) keyboards_type=({{#keyboards}}"{{type}}" {{/keyboards}}) +keyboards_arch=({{#keyboards}}"{{arch}}" {{/keyboards}}) +keyboards_basedir=({{#keyboards}}"{{__base_dir}}" {{/keyboards}}) keyboards_split=({{#keyboards}}"{{#split}}y{{/split}}{{^split}}n{{/split}}" {{/keyboards}}) keyboards_shield=({{#keyboards}}"{{#compatible}}y{{/compatible}}{{^compatible}}n{{/compatible}}" {{/keyboards}}) + +{{#keyboards}} +{{#siblings.0}} +{{id}}_siblings=({{#siblings}}"{{.}}" {{/siblings}}) +{{/siblings.0}} +{{/keyboards}} + select opt in "${options[@]}" "Quit"; do case "$REPLY" in ''|*[!0-9]*) echo "Invalid option. Try another one."; continue;; @@ -85,9 +94,17 @@ select opt in "${options[@]}" "Quit"; do fi keyboard_index=$(( $REPLY-1 )) keyboard=${keyboards_id[$keyboard_index]} + keyboard_arch=${keyboards_arch[$keyboard_index]} + keyboard_basedir=${keyboards_basedir[$keyboard_index]} keyboard_title=${options[$keyboard_index]} + keyboard_sibling_var=${keyboard}_siblings[@] + keyboard_sibling_first=${keyboard}_siblings[0] + if [ -n "${!keyboard_sibling_first}" ]; then + keyboard_siblings=${!keyboard_sibling_var} + else + keyboard_siblings=( "${keyboard}" ) + fi split=${keyboards_split[$keyboard_index]} - type=${keyboards_type[$keyboard_index]} keyboard_shield=${keyboards_shield[$keyboard_index]} break ;; @@ -96,6 +113,7 @@ select opt in "${options[@]}" "Quit"; do done if [ "$keyboard_shield" == "y" ]; then + shields=$keyboard_siblings shield=${keyboard} shield_title=${keyboard_title} @@ -119,6 +137,7 @@ if [ "$keyboard_shield" == "y" ]; then board_index=$(( $REPLY-1 )) board=${board_ids[$board_index]} board_title=${options[$board_index]} + boards=( "${board}" ) break ;; @@ -126,12 +145,7 @@ if [ "$keyboard_shield" == "y" ]; then done else board=${keyboard} - echo "Support for onboard microcontroller keyboards is still a work in progress." - exit 1 -fi - -if [ "$split" == "n" ]; then - repo_path="https://github.com/zmkfirmware/zmk-config-template.git" + boards=$keyboard_siblings fi read -r -e -p "Copy in the stock keymap for customization? [Yn]: " copy_keymap @@ -152,8 +166,12 @@ fi echo "" echo "Preparing a user config for:" -echo "* MCU Board: ${board}" -echo "* Shield: ${shield}" +if [ "$keyboard_shield" == "y" ]; then + echo "* MCU Board: ${boards}" + echo "* Shield(s): ${shields}" +else + echo "* Board(s): ${boards}" +fi if [ "$copy_keymap" == "yes" ]; then echo "* Copy Keymap?: ✓" @@ -178,26 +196,37 @@ cd ${repo_name} pushd config -$download_command "https://raw.githubusercontent.com/zmkfirmware/zmk/main/app/boards/shields/${shield}/${shield}.conf" +if [ "$keyboard_shield" == "y" ]; then + config_file="https://raw.githubusercontent.com/zmkfirmware/zmk/main/app/boards/shields/${keyboard_basedir}/${shield}.conf" + + keymap_file="https://raw.githubusercontent.com/zmkfirmware/zmk/main/app/boards/shields/${keyboard_basedir}/${shield}.keymap" +else + config_file="https://raw.githubusercontent.com/zmkfirmware/zmk/main/app/boards/${keyboard_arch}/${keyboard_basedir}/${board}.conf" + keymap_file="https://raw.githubusercontent.com/zmkfirmware/zmk/main/app/boards/${keyboard_arch}/${keyboard_basedir}/${board}.keymap" +fi +echo "Downloading config file (${config_file})" +$download_command "${config_file}" || echo "# Put configuration options here" > "${keyboard}.conf" if [ "$copy_keymap" == "yes" ]; then - $download_command "https://raw.githubusercontent.com/zmkfirmware/zmk/main/app/boards/shields/${shield}/${shield}.keymap" + echo "Downloading keymap file (${keymap_file})" + $download_command "${keymap_file}" fi popd -sed -i'.orig' \ - -e "s/BOARD_NAME/$board/" \ - -e "s/SHIELD_NAME/$shield/" \ - -e "s|KEYBOARD_TITLE|$shield_title|" \ - .github/workflows/build.yml +echo "include:" >> build.yaml -if [ "$board" == "proton_c" ]; then - # Proton-C board still fa - sed -i'.orig' -e "s/uf2/hex/g" .github/workflows/build.yml -fi - -rm .github/workflows/*.yml.orig +for b in ${boards}; do + if [ -n "${shields}" ]; + then + for s in ${shields}; do + echo " - board: ${b}" >> build.yaml + echo " shield: ${s}" >> build.yaml + done + else + echo " - board: ${b}" >> build.yaml + fi +done rm -rf .git git init .