├── src ├── .vscode │ └── settings.json ├── assets │ ├── icon.png │ ├── app_image.png │ ├── system-tray-icon.png │ ├── app.css │ ├── editor.css │ ├── milligram.min.css │ └── milligram.min.css.map ├── sounds │ ├── keys │ │ ├── nk-cream │ │ │ ├── [.wav │ │ │ ├── ].wav │ │ │ ├── a.wav │ │ │ ├── b.wav │ │ │ ├── c.wav │ │ │ ├── d.wav │ │ │ ├── e.wav │ │ │ ├── f.wav │ │ │ ├── g.wav │ │ │ ├── h.wav │ │ │ ├── i.wav │ │ │ ├── j.wav │ │ │ ├── k.wav │ │ │ ├── l.wav │ │ │ ├── m.wav │ │ │ ├── n.wav │ │ │ ├── o.wav │ │ │ ├── p.wav │ │ │ ├── q.wav │ │ │ ├── r.wav │ │ │ ├── s.wav │ │ │ ├── t.wav │ │ │ ├── u.wav │ │ │ ├── v.wav │ │ │ ├── w.wav │ │ │ ├── x.wav │ │ │ ├── y.wav │ │ │ ├── z.wav │ │ │ ├── a-up.wav │ │ │ ├── enter.wav │ │ │ ├── shift.wav │ │ │ ├── space.wav │ │ │ ├── tab.wav │ │ │ ├── a-down.wav │ │ │ ├── backspace.wav │ │ │ ├── caps lock.wav │ │ │ └── config.json │ │ ├── eg-oreo │ │ │ ├── oreo.ogg │ │ │ └── config.json │ │ ├── cherrymx-black-abs │ │ │ ├── sound.ogg │ │ │ └── config.json │ │ ├── cherrymx-black-pbt │ │ │ ├── sound.ogg │ │ │ └── config.json │ │ ├── cherrymx-blue-abs │ │ │ ├── sound.ogg │ │ │ └── config.json │ │ ├── cherrymx-blue-pbt │ │ │ ├── sound.ogg │ │ │ └── config.json │ │ ├── cherrymx-brown-abs │ │ │ ├── sound.ogg │ │ │ └── config.json │ │ ├── cherrymx-brown-pbt │ │ │ ├── sound.ogg │ │ │ └── config.json │ │ ├── cherrymx-red-pbt │ │ │ ├── sound.ogg │ │ │ └── config.json │ │ ├── eg-crystal-purple │ │ │ ├── purple.ogg │ │ │ └── config.json │ │ └── topre-purple-hybrid-pbt │ │ │ ├── sound.ogg │ │ │ └── config.json │ └── mouse │ │ ├── logi-g502 │ │ ├── left-up.m4a │ │ ├── right-up.m4a │ │ ├── left-down.m4a │ │ ├── right-down.m4a │ │ ├── scroll-up.m4a │ │ ├── scroll-down.m4a │ │ └── config.json │ │ ├── harpoon-rgb │ │ ├── left-up.m4a │ │ ├── right-up.m4a │ │ ├── left-down.m4a │ │ ├── right-down.m4a │ │ ├── scroll-down.m4a │ │ ├── scroll-up.m4a │ │ └── config.json │ │ ├── mamba-elite │ │ ├── left-up.m4a │ │ ├── right-up.m4a │ │ ├── left-down.m4a │ │ ├── right-down.m4a │ │ ├── scroll-down.m4a │ │ ├── scroll-up.m4a │ │ └── config.json │ │ ├── amazon-gaming │ │ ├── left-down.mp3 │ │ ├── left-up.mp3 │ │ ├── right-up.mp3 │ │ ├── scroll-up.mp3 │ │ ├── right-down.mp3 │ │ ├── scroll-down.mp3 │ │ └── config.json │ │ ├── logi-trackball │ │ ├── left-up.mp3 │ │ ├── right-up.mp3 │ │ ├── left-down.mp3 │ │ ├── right-down.mp3 │ │ ├── scroll-up.mp3 │ │ ├── scroll-down.mp3 │ │ └── config.json │ │ ├── apple-magic-mouse │ │ ├── left-up.mp3 │ │ ├── left-down.mp3 │ │ ├── right-down.mp3 │ │ ├── right-up.mp3 │ │ ├── scroll-up.mp3 │ │ ├── scroll-down.mp3 │ │ └── config.json │ │ └── corsair-m65-elite │ │ ├── left-up.mp3 │ │ ├── left-down.mp3 │ │ ├── right-down.mp3 │ │ ├── right-up.mp3 │ │ ├── scroll-up.mp3 │ │ ├── scroll-down.mp3 │ │ └── config.json ├── utils │ ├── startup_handler.js │ ├── listen_handler.js │ ├── keyup_handler.js │ ├── random_handler.js │ ├── mouse_handler.js │ └── remapper.js ├── libs │ ├── layouts.js │ └── keycodes.js ├── editor.html ├── app.html ├── main.js ├── editor.js └── app.js ├── .DS_Store ├── doc ├── .DS_Store ├── faq.md ├── performance.md ├── bugs │ ├── nosound.md │ └── nopacks.md ├── virus.md └── linux-and-mac.md ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── issues.md ├── LICENSE ├── package.json └── README.md /src/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/.DS_Store -------------------------------------------------------------------------------- /doc/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/doc/.DS_Store -------------------------------------------------------------------------------- /src/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/assets/icon.png -------------------------------------------------------------------------------- /src/assets/app_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/assets/app_image.png -------------------------------------------------------------------------------- /src/assets/system-tray-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/assets/system-tray-icon.png -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/[.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/[.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/].wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/].wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/a.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/a.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/b.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/b.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/c.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/c.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/d.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/d.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/e.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/e.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/f.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/f.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/g.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/g.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/h.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/h.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/i.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/i.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/j.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/j.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/k.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/k.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/l.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/l.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/m.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/m.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/n.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/n.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/o.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/o.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/p.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/p.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/q.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/q.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/r.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/r.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/s.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/s.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/t.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/t.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/u.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/u.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/v.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/v.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/w.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/w.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/x.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/x.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/y.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/y.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/z.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/z.wav -------------------------------------------------------------------------------- /src/sounds/keys/eg-oreo/oreo.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/eg-oreo/oreo.ogg -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/a-up.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/a-up.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/enter.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/enter.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/shift.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/shift.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/space.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/space.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/tab.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/tab.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/a-down.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/a-down.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/backspace.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/backspace.wav -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/caps lock.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/nk-cream/caps lock.wav -------------------------------------------------------------------------------- /src/sounds/mouse/logi-g502/left-up.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/logi-g502/left-up.m4a -------------------------------------------------------------------------------- /src/sounds/mouse/logi-g502/right-up.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/logi-g502/right-up.m4a -------------------------------------------------------------------------------- /src/sounds/mouse/harpoon-rgb/left-up.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/harpoon-rgb/left-up.m4a -------------------------------------------------------------------------------- /src/sounds/mouse/harpoon-rgb/right-up.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/harpoon-rgb/right-up.m4a -------------------------------------------------------------------------------- /src/sounds/mouse/logi-g502/left-down.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/logi-g502/left-down.m4a -------------------------------------------------------------------------------- /src/sounds/mouse/logi-g502/right-down.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/logi-g502/right-down.m4a -------------------------------------------------------------------------------- /src/sounds/mouse/logi-g502/scroll-up.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/logi-g502/scroll-up.m4a -------------------------------------------------------------------------------- /src/sounds/mouse/mamba-elite/left-up.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/mamba-elite/left-up.m4a -------------------------------------------------------------------------------- /src/sounds/mouse/mamba-elite/right-up.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/mamba-elite/right-up.m4a -------------------------------------------------------------------------------- /src/sounds/keys/cherrymx-black-abs/sound.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/cherrymx-black-abs/sound.ogg -------------------------------------------------------------------------------- /src/sounds/keys/cherrymx-black-pbt/sound.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/cherrymx-black-pbt/sound.ogg -------------------------------------------------------------------------------- /src/sounds/keys/cherrymx-blue-abs/sound.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/cherrymx-blue-abs/sound.ogg -------------------------------------------------------------------------------- /src/sounds/keys/cherrymx-blue-pbt/sound.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/cherrymx-blue-pbt/sound.ogg -------------------------------------------------------------------------------- /src/sounds/keys/cherrymx-brown-abs/sound.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/cherrymx-brown-abs/sound.ogg -------------------------------------------------------------------------------- /src/sounds/keys/cherrymx-brown-pbt/sound.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/cherrymx-brown-pbt/sound.ogg -------------------------------------------------------------------------------- /src/sounds/keys/cherrymx-red-pbt/sound.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/cherrymx-red-pbt/sound.ogg -------------------------------------------------------------------------------- /src/sounds/keys/eg-crystal-purple/purple.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/eg-crystal-purple/purple.ogg -------------------------------------------------------------------------------- /src/sounds/mouse/amazon-gaming/left-down.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/amazon-gaming/left-down.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/amazon-gaming/left-up.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/amazon-gaming/left-up.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/amazon-gaming/right-up.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/amazon-gaming/right-up.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/amazon-gaming/scroll-up.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/amazon-gaming/scroll-up.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/harpoon-rgb/left-down.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/harpoon-rgb/left-down.m4a -------------------------------------------------------------------------------- /src/sounds/mouse/harpoon-rgb/right-down.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/harpoon-rgb/right-down.m4a -------------------------------------------------------------------------------- /src/sounds/mouse/harpoon-rgb/scroll-down.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/harpoon-rgb/scroll-down.m4a -------------------------------------------------------------------------------- /src/sounds/mouse/harpoon-rgb/scroll-up.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/harpoon-rgb/scroll-up.m4a -------------------------------------------------------------------------------- /src/sounds/mouse/logi-g502/scroll-down.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/logi-g502/scroll-down.m4a -------------------------------------------------------------------------------- /src/sounds/mouse/logi-trackball/left-up.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/logi-trackball/left-up.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/logi-trackball/right-up.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/logi-trackball/right-up.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/mamba-elite/left-down.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/mamba-elite/left-down.m4a -------------------------------------------------------------------------------- /src/sounds/mouse/mamba-elite/right-down.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/mamba-elite/right-down.m4a -------------------------------------------------------------------------------- /src/sounds/mouse/mamba-elite/scroll-down.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/mamba-elite/scroll-down.m4a -------------------------------------------------------------------------------- /src/sounds/mouse/mamba-elite/scroll-up.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/mamba-elite/scroll-up.m4a -------------------------------------------------------------------------------- /src/sounds/mouse/amazon-gaming/right-down.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/amazon-gaming/right-down.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/amazon-gaming/scroll-down.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/amazon-gaming/scroll-down.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/apple-magic-mouse/left-up.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/apple-magic-mouse/left-up.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/corsair-m65-elite/left-up.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/corsair-m65-elite/left-up.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/logi-trackball/left-down.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/logi-trackball/left-down.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/logi-trackball/right-down.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/logi-trackball/right-down.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/logi-trackball/scroll-up.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/logi-trackball/scroll-up.mp3 -------------------------------------------------------------------------------- /src/sounds/keys/topre-purple-hybrid-pbt/sound.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/keys/topre-purple-hybrid-pbt/sound.ogg -------------------------------------------------------------------------------- /src/sounds/mouse/apple-magic-mouse/left-down.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/apple-magic-mouse/left-down.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/apple-magic-mouse/right-down.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/apple-magic-mouse/right-down.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/apple-magic-mouse/right-up.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/apple-magic-mouse/right-up.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/apple-magic-mouse/scroll-up.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/apple-magic-mouse/scroll-up.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/corsair-m65-elite/left-down.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/corsair-m65-elite/left-down.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/corsair-m65-elite/right-down.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/corsair-m65-elite/right-down.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/corsair-m65-elite/right-up.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/corsair-m65-elite/right-up.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/corsair-m65-elite/scroll-up.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/corsair-m65-elite/scroll-up.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/logi-trackball/scroll-down.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/logi-trackball/scroll-down.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/apple-magic-mouse/scroll-down.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/apple-magic-mouse/scroll-down.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/corsair-m65-elite/scroll-down.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PyroCalzone/MechVibesPlusPlus/HEAD/src/sounds/mouse/corsair-m65-elite/scroll-down.mp3 -------------------------------------------------------------------------------- /src/sounds/mouse/harpoon-rgb/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "custom-sound-pack-90696052", 3 | "name": "Corsair Harpoon RGB", 4 | "key_define_type": "multi", 5 | "sound": "sound.ogg", 6 | "defines": { 7 | "1": "left-down.m4a", 8 | "01": "left-up.m4a", 9 | "2": "right-down.m4a", 10 | "02": "right-up.m4a", 11 | "3": "scroll-down.m4a", 12 | "03": "scroll-up.m4a" 13 | } 14 | } -------------------------------------------------------------------------------- /src/sounds/mouse/mamba-elite/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "custom-sound-pack-90696052", 3 | "name": "Razer Mamba Elite", 4 | "key_define_type": "multi", 5 | "sound": "sound.ogg", 6 | "defines": { 7 | "1": "left-down.m4a", 8 | "01": "left-up.m4a", 9 | "2": "right-down.m4a", 10 | "02": "right-up.m4a", 11 | "3": "scroll-down.m4a", 12 | "03": "scroll-up.m4a" 13 | } 14 | } -------------------------------------------------------------------------------- /src/sounds/mouse/amazon-gaming/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "custom-sound-pack-53799271", 3 | "name": "Amazon Gaming Mouse", 4 | "key_define_type": "multi", 5 | "sound": "sound.ogg", 6 | "defines": { 7 | "1": "left-down.mp3", 8 | "01": "left-up.mp3", 9 | "2": "right-down.mp3", 10 | "02": "right-up.mp3", 11 | "3": "scroll-down.mp3", 12 | "03": "scroll-up.mp3" 13 | } 14 | } -------------------------------------------------------------------------------- /src/sounds/mouse/apple-magic-mouse/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "custom-sound-pack-90696052", 3 | "name": "Apple Magic Mouse", 4 | "key_define_type": "multi", 5 | "sound": "sound.ogg", 6 | "defines": { 7 | "1": "left-down.mp3", 8 | "01": "left-up.mp3", 9 | "2": "right-down.mp3", 10 | "02": "right-up.mp3", 11 | "3": "scroll-down.mp3", 12 | "03": "scroll-up.mp3" 13 | } 14 | } -------------------------------------------------------------------------------- /src/sounds/mouse/corsair-m65-elite/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "custom-sound-pack-43252347", 3 | "name": "Corsair M65 Elite", 4 | "key_define_type": "multi", 5 | "sound": "sound.ogg", 6 | "defines": { 7 | "1": "left-down.mp3", 8 | "01": "left-up.mp3", 9 | "2": "right-down.mp3", 10 | "02": "right-up.mp3", 11 | "3": "scroll-down.mp3", 12 | "03": "scroll-up.mp3" 13 | } 14 | } -------------------------------------------------------------------------------- /src/sounds/mouse/logi-g502/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "custom-sound-pack-90696052", 3 | "name": "Logitech G502 Lightspeed", 4 | "key_define_type": "multi", 5 | "sound": "sound.ogg", 6 | "defines": { 7 | "1": "left-down.m4a", 8 | "01": "left-up.m4a", 9 | "2": "right-down.m4a", 10 | "02": "right-up.m4a", 11 | "3": "scroll-down.m4a", 12 | "03": "scroll-up.m4a" 13 | } 14 | } -------------------------------------------------------------------------------- /src/sounds/mouse/logi-trackball/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "custom-sound-pack-28658750", 3 | "name": "Logitech M570 Trackball", 4 | "key_define_type": "multi", 5 | "sound": "sound.ogg", 6 | "defines": { 7 | "1": "left-down.mp3", 8 | "01": "left-up.mp3", 9 | "2": "right-down.mp3", 10 | "02": "right-up.mp3", 11 | "3": "scroll-down.mp3", 12 | "03": "scroll-up.mp3" 13 | } 14 | } -------------------------------------------------------------------------------- /doc/faq.md: -------------------------------------------------------------------------------- 1 | # Mechvibes++ FAQ 2 | 3 | ## How do I make Mechvibes++ go through my microphone? 4 | 5 | You can use [VoiceMeeter Banana](https://vb-audio.com/Voicemeeter/banana.htm) to do this. Please look up another guide if you can't figure out how to set this up yourself. 6 | 7 | Please also know that VoiceMeeter is not our software and we can't help with issues for it. 8 | 9 | ## How do I get this on Linux/macOS? 10 | 11 | You'll need to compile a version yourself. Please see this [guide](linux-and-mac.md). -------------------------------------------------------------------------------- /src/utils/startup_handler.js: -------------------------------------------------------------------------------- 1 | class startupHandler { 2 | constructor(app) { 3 | this.app = app; 4 | } 5 | 6 | get is_enabled() { 7 | return this.app.getLoginItemSettings().openAtLogin; 8 | } 9 | 10 | enable() { 11 | this.app.setLoginItemSettings({ 12 | openAtLogin: true, 13 | }); 14 | } 15 | 16 | disable() { 17 | this.app.setLoginItemSettings({ 18 | openAtLogin: false, 19 | }); 20 | } 21 | 22 | toggle() { 23 | if (this.isEnabled) { 24 | this.disable(); 25 | } else { 26 | this.enable(); 27 | } 28 | } 29 | } 30 | 31 | module.exports = startupHandler; 32 | -------------------------------------------------------------------------------- /doc/performance.md: -------------------------------------------------------------------------------- 1 | # Mechvibes++ Known Issues 2 | ## High RAM Usage 3 | 4 | This is a known issue with the program and we are trying our best to work on fixing this. 5 | 6 | Here's two temporary fixes that may help: 7 | 8 | - Quit and reopen the app 9 | - Uninstall any custom soundpacks that you don't use 10 | 11 | ## Poor game performance 12 | 13 | - Make sure that normal Mechvibes isn't also open alongside of Mechvibes++ 14 | - You may not have enough system resources (RAM or CPU power) to process both your game and Mechvibes++ at the same time 15 | - Make sure that Mechvibes++ is running as Administrator, they may just be conflicting with one another. -------------------------------------------------------------------------------- /src/utils/listen_handler.js: -------------------------------------------------------------------------------- 1 | const Store = require('electron-store'); 2 | const store = new Store(); 3 | 4 | class startupHandler { 5 | constructor(app) { 6 | this.app = app; 7 | this.MV_MUTED_LSID = 'mechvibes-muted'; 8 | } 9 | 10 | get is_muted() { 11 | return store.get(this.MV_MUTED_LSID); 12 | } 13 | 14 | enable() { 15 | store.set(this.MV_MUTED_LSID, true); 16 | } 17 | 18 | disable() { 19 | store.set(this.MV_MUTED_LSID, false); 20 | } 21 | 22 | toggle() { 23 | if (this.is_muted) { 24 | this.disable(); 25 | } else { 26 | this.enable(); 27 | } 28 | } 29 | } 30 | 31 | module.exports = startupHandler; 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Additional context** 27 | Add any other context about the problem here. 28 | -------------------------------------------------------------------------------- /src/utils/keyup_handler.js: -------------------------------------------------------------------------------- 1 | const Store = require('electron-store'); 2 | const store = new Store(); 3 | 4 | class startupHandler { 5 | constructor(app) { 6 | this.app = app; 7 | this.MV_KEYUP_LSID = 'mechvibes-keyup'; 8 | } 9 | 10 | get is_keyup() { 11 | return store.get(this.MV_KEYUP_LSID); 12 | } 13 | 14 | enable() { 15 | store.set(this.MV_KEYUP_LSID, true); 16 | } 17 | 18 | disable() { 19 | store.set(this.MV_KEYUP_LSID, false); 20 | } 21 | 22 | toggle() { 23 | if (this.is_keyup) { 24 | this.disable(); 25 | } else { 26 | this.enable(); 27 | } 28 | } 29 | } 30 | 31 | module.exports = startupHandler; 32 | -------------------------------------------------------------------------------- /issues.md: -------------------------------------------------------------------------------- 1 | # Mechvibes++ Known Issues 2 | 3 | Please [join our discord](https://discord.gg/CZ8Qgth2SW) if you have any issues that are not listed here. 4 | 5 | ## Software issues 6 | 7 | - No sound on keypress: [guide](doc/bugs/nosound.md) 8 | - No soundpacks showing up/app is loading forever: [guide](doc/bugs/nopacks.md) 9 | 10 | ## System issues 11 | 12 | - Flagged as virus: [guide](doc/virus.md) 13 | - Poor performance in games: [guide](doc/performance.md) 14 | 15 | ## Other issues 16 | 17 | Check out this small [FAQ Page](doc/faq.md) for information on microphone routing and other versions. 18 | 19 | Otherwise, please [join our discord](https://discord.gg/CZ8Qgth2SW) and ask us there! 20 | -------------------------------------------------------------------------------- /src/utils/random_handler.js: -------------------------------------------------------------------------------- 1 | const Store = require('electron-store'); 2 | const store = new Store(); 3 | 4 | class startupHandler { 5 | constructor(app) { 6 | this.app = app; 7 | this.MV_RANDOM_LSID = 'mechvibes-random'; 8 | } 9 | 10 | get is_random() { 11 | return store.get(this.MV_RANDOM_LSID); 12 | } 13 | 14 | enable() { 15 | store.set(this.MV_RANDOM_LSID, true); 16 | } 17 | 18 | disable() { 19 | store.set(this.MV_RANDOM_LSID, false); 20 | } 21 | 22 | toggle() { 23 | if (this.is_random) { 24 | this.disable(); 25 | } else { 26 | this.enable(); 27 | } 28 | } 29 | } 30 | 31 | module.exports = startupHandler; 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /src/utils/mouse_handler.js: -------------------------------------------------------------------------------- 1 | const Store = require('electron-store'); 2 | const store = new Store(); 3 | 4 | class startupHandler { 5 | constructor(app) { 6 | this.app = app; 7 | this.MV_MOUSESOUNDS_LSID = 'mechvibes-mouse'; 8 | } 9 | 10 | get is_mousesounds() { 11 | return store.get(this.MV_MOUSESOUNDS_LSID); 12 | } 13 | 14 | enable() { 15 | store.set(this.MV_MOUSESOUNDS_LSID, true); 16 | } 17 | 18 | disable() { 19 | store.set(this.MV_MOUSESOUNDS_LSID, false); 20 | } 21 | 22 | toggle() { 23 | if (this.is_mousesounds) { 24 | this.disable(); 25 | } else { 26 | this.enable(); 27 | } 28 | } 29 | } 30 | 31 | module.exports = startupHandler; 32 | -------------------------------------------------------------------------------- /doc/bugs/nosound.md: -------------------------------------------------------------------------------- 1 | # Mechvibes++ Known Issues 2 | 3 | ## No Sound on Keypress 4 | 5 | If you are not getting any sound feedback from Mechvibes++, chances are that whatever application you are running is running as Administrator. Therefore, the application is practically blocking Mechvibes from running. 6 | 7 | ### To fix this, you can do two things: 8 | 9 | - Run Mechvibes++ as Administrator 10 | - It should ask for this upon startup. Skipping this prompt will still let the app run but may lead to problems like what you may be having. 11 | 12 | - Quit the application, and run it normally. 13 | 14 | 15 | ### How to quit the app (Windows) 16 | ![](https://media.discordapp.net/attachments/813289308760834058/813289734293291018/T3U83X2.gif?ex=659b9016&is=65891b16&hm=fae197fdcd47a2376548260ce756de03861b2f38cd8d3556463769d9d05df320&=&width=1426&height=398) 17 | 18 | ### How to quit the app (Mac) 19 | Assuming the app is already running, click anywhere on the app to focus it. Then, press [CMD] and [Q] at the same time on your keyboard to quit it. -------------------------------------------------------------------------------- /doc/virus.md: -------------------------------------------------------------------------------- 1 | # Mechvibes++ Known Issues 2 | ## Flagged as Virus 3 | 4 | Windows Defender will probably block the Mechvibes++ installer. 5 | 6 | In simple terms, this is because we have not made Microsoft verify that the software as safe (hence "unknown publisher") 7 | 8 | To stop it from being blocked, click on “more info” and then “Run anyway” 9 | 10 | ## Is Mechvibes++ a virus? 11 | 12 | Short answer: no 13 | 14 | Long answer: 15 | 16 | We understand that there may be a concern of Mechvibes++ being a virus because Windows flags it as one. 17 | 18 | Anti-virus software detects the functions that an application or script has and respond accordingly. Because both keyloggers and Mechvibes++ listen for keypresses, some anti-virus software might see Mechvibes++ as a threat or virus. 19 | 20 | Mechvibes++ will always immediately discard any keypress data once it's done matching it with files in your currently selected soundpack. 21 | 22 | The code for Mechvibes++ is always free for you to look at and scroll through online if you want to investigate. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 PyroCalzone 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /doc/bugs/nopacks.md: -------------------------------------------------------------------------------- 1 | # Mechvibes++ Known Issues 2 | 3 | 4 | ## No soundpacks showing up after fresh install 5 | 6 | ### On Windows 7 | - Download [Visual C++](https://aka.ms/vs/16/release/vc_redist.x64.exe) 8 | - If it says error, _READ THE INFO!_ It may already be installed! 9 | - Restart Mechvibes++ 10 | - Restart your computer. 11 | 12 | ### On macOS 13 | - Go to Privacy in System Settings 14 | - Check for Mechvibes++ in any of the categories and enable any permissions 15 | - Restart Mechvibes++ 16 | 17 | ## No soundpacks showing up after adding a soundpack 18 | 19 | In most cases, this bug happens if you have incorrectly added a soundpack. Below is a list with things that can cause this bug to occur. 20 | 21 | **Known Causes** 22 | 23 | - Adding / leaving an empty folder in mechvibes_custom 24 | - Having a folder inside a folder   25 | - Touching the config.json. 26 | - Having the .zip or .rar files in mechvibes_custom 27 | 28 | **If all else fails** 29 | 30 | Sometimes the custom folder just- breaks. 31 | 32 | How to fix this: 33 | Remove the entire folder and reload. A new one will automatically be created for you once you restart the app. -------------------------------------------------------------------------------- /doc/linux-and-mac.md: -------------------------------------------------------------------------------- 1 | # Mechvibes++ FAQ 2 | ## Linux and macOS 3 | 4 | Linux and macOS are not publicly availible. 5 | 6 | This is because we need to have a machine running one of these operating systems to make a version for it. 7 | 8 | ## Can I make a version myself? 9 | 10 | Yes, you can! 11 | 12 | **What you'll need** 13 | 14 | - [Visual Studio Code](https://code.visualstudio.com/) 15 | - [Node JS] (https://nodejs.org/) 16 | - A machine running your desired OS 17 | - For example, if you're trying to build a Mac version, you'll need a Mac. 18 | - Knowledge in JavaScript 19 | - So you can fix any issues in the code preventing the app from running on your OS 20 | 21 | ## How to do it? 22 | 23 | Follow these steps after installing both NodeJS and Visual Studio Code 24 | 25 | 1. Download the Mechvibes [source code](https://github.com/hainguyents13/mechvibes) 26 | 2. Download the Mechvibes++ [source code](https://github.com/PyroCalzone/MechVibesPlusPlus) 27 | 3. Replace the **src** folder in the Mechvibes source code with the **src** folder from Mechvibes++ 28 | 4. Open the Mechvibes folder in **Visual Studio Code** 29 | 5. At the top, click **Terminal** then **New Terminal** 30 | 6. Run this command in the new terminal: **npm i** 31 | 7. If you're building for **Linux**, run **npm run build:linux** 32 | 8. If you're building for **macOS**, run **npm build:mac** 33 | 9. Wait for the compile to finish, this may take a while. 34 | 10. Run the app and fix any issues using the developer console to check for errors. 35 | 36 | If you can't figure anything out, you can resort to our [Discord](https://discord.gg/CZ8Qgth2SW/) server for help. Remember that we don't own these machines ourselves and may not entirely be available to assist. 37 | -------------------------------------------------------------------------------- /src/libs/layouts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const standard = { 4 | // standard 5 | main: [ 6 | [1, 0, 59, 60, 61, 62, 0, 63, 64, 65, 66, 67, 68, 87, 88], 7 | [41, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], 8 | [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 43], 9 | [58, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 28], 10 | [42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54], 11 | [29, 3675, 56, 57, 3640, 3676, 3677, 3613], 12 | ], 13 | // edit 14 | edit: [ 15 | [3639, 70, 3653], // 16 | [3666, 3655, 3657], // 17 | [3667, 3663, 3665], // 18 | [], 19 | [0, 57416, 0], // 20 | [57419, 57424, 57421], // 21 | ], 22 | // numpad 23 | numpad: [ 24 | [], // 25 | [69, 3637, 55, 74], 26 | [71, 72, 73, 78], 27 | [75, 76, 77], 28 | [79, 80, 81, 3612], 29 | [82, 83], 30 | ], 31 | }; 32 | 33 | function remap(to = 'win32') { 34 | const layout = JSON.parse(JSON.stringify(standard)); 35 | switch (to) { 36 | case 'linux': 37 | break; 38 | 39 | case 'win32': { 40 | layout.edit[1] = [61010, 60999, 61001]; 41 | layout.edit[2] = [61011, 61007, 61009]; 42 | layout.edit[4] = [0, 61000, 0]; 43 | layout.edit[5] = [61003, 61008, 61005]; 44 | break; 45 | } 46 | 47 | case 'darwin': { 48 | layout.main[5][1] = 56; 49 | layout.main[5][2] = 3675; 50 | layout.main[5][4] = 3675; 51 | layout.main[5][5] = 56; 52 | layout.main[5][6] = 29; 53 | 54 | layout.edit[0][0] = [91, 91, 92]; 55 | 56 | layout.numpad[0] = [69, 3597, 3637, 55]; 57 | layout.numpad[1][3] = 74; 58 | layout.numpad[2][3] = 78; 59 | break; 60 | } 61 | } 62 | 63 | return layout; 64 | } 65 | 66 | const sizes = { 67 | 15: 'key-15u', 68 | 58: 'key-175u', 69 | 42: 'key-225u', 70 | 29: 'key-125u', 71 | 3675: 'key-125u', 72 | 56: 'key-125u', 73 | 57: 'key-625u', 74 | 3640: 'key-125u', 75 | 3676: 'key-125u', 76 | 3677: 'key-125u', 77 | 3613: 'key-125u', 78 | 54: 'key-275u', 79 | 28: 'key-225u', 80 | 43: 'key-15u', 81 | 14: 'key-2u', 82 | 83 | 82: 'key-2u', 84 | 78: 'key-height-2u', 85 | 3612: 'key-height-2u', 86 | }; 87 | 88 | module.exports = { win32: remap('win32'), darwin: remap('darwin'), linux: standard, sizes }; 89 | -------------------------------------------------------------------------------- /src/utils/remapper.js: -------------------------------------------------------------------------------- 1 | function remapper(from = 'standard', to = 'darwin', defines = {}) { 2 | if (from == 'standard') { 3 | // from standard linux, darwin, win32 4 | switch (to) { 5 | case 'linux': 6 | break; 7 | case 'darwin': { 8 | defines['91'] = defines['3639']; // mac f13 9 | defines['92'] = defines['70']; // mac f14 10 | defines['93'] = defines['3653']; // mac f15 11 | defines['91'] = defines['57416']; 12 | defines['56'] = defines['3675']; 13 | defines['3675'] = defines['56']; 14 | defines['3675'] = defines['3640']; 15 | defines['56'] = defines['3676']; 16 | defines['29'] = defines['3613']; 17 | 18 | defines['3597'] = defines['69']; // numlock -> clear 19 | break; 20 | } 21 | case 'win32': { 22 | // row 2 23 | defines['61010'] = defines['3666']; 24 | defines['60999'] = defines['3655']; 25 | defines['61001'] = defines['3657']; 26 | // row 3 27 | defines['61011'] = defines['3667']; 28 | defines['61007'] = defines['3663']; 29 | defines['61009'] = defines['3665']; 30 | defines['3677'] = defines['3613']; 31 | // row 4 32 | defines['61000'] = defines['57416']; 33 | // row 5 34 | defines['61003'] = defines['57419']; 35 | defines['61008'] = defines['57424']; 36 | defines['61005'] = defines['57421']; 37 | break; 38 | } 39 | } 40 | } else { 41 | // from linux, darwin, win32 to standard 42 | switch (from) { 43 | case 'darwin': { 44 | defines['3639'] = defines['91']; 45 | defines['70'] = defines['92']; 46 | defines['3653'] = defines['93']; 47 | defines['3675'] = defines['56']; 48 | defines['56'] = defines['3675']; 49 | defines['3640'] = defines['3675']; 50 | defines['3676'] = defines['56']; 51 | defines['3613'] = defines['29']; 52 | break; 53 | } 54 | case 'win32': { 55 | // row 2 56 | defines['3666'] = defines['61010']; 57 | defines['3655'] = defines['60999']; 58 | defines['3657'] = defines['61001']; 59 | // row 3 60 | defines['3667'] = defines['61011']; 61 | defines['3663'] = defines['61007']; 62 | defines['3665'] = defines['61009']; 63 | // row 4 64 | defines['57416'] = defines['61000']; 65 | // row 5 66 | defines['57419'] = defines['61003']; 67 | defines['57424'] = defines['61008']; 68 | defines['57421'] = defines['61005']; 69 | break; 70 | } 71 | } 72 | } 73 | return defines; 74 | } 75 | 76 | module.exports = remapper; 77 | 78 | 79 | // How do I make this compatible with mouse? 80 | -------------------------------------------------------------------------------- /src/assets/app.css: -------------------------------------------------------------------------------- 1 | a, 2 | a:hover { 3 | color: #ff5050; 4 | } 5 | 6 | a:hover { 7 | text-decoration: underline; 8 | } 9 | 10 | #app-logo { 11 | display: flex; 12 | justify-content: center; 13 | margin-bottom: 50px; 14 | } 15 | 16 | #logo { 17 | font-family: sans-serif; 18 | transition: all 0.1s ease; 19 | box-shadow: 0 2px #6b6b6b; 20 | font-size: 3rem; 21 | font-weight: 600; 22 | background: #181818; 23 | text-align: center; 24 | border-radius: 0.5rem; 25 | border: 2px solid #7c7c7c; 26 | padding: 1rem 2rem; 27 | color: #8a8a8a; 28 | } 29 | 30 | #logo.pressed { 31 | box-shadow: 0 0; 32 | margin-bottom: -2px; 33 | margin-top: 2px; 34 | } 35 | 36 | .hidden { 37 | display: none; 38 | } 39 | 40 | .divider { 41 | display: block; 42 | width: 100%; 43 | border-bottom: 1px solid #6b6b6b; 44 | margin-top: 1rem; 45 | margin-bottom: 2rem; 46 | } 47 | 48 | #update-available { 49 | padding: 8px 5px; 50 | border: 1px solid #505050; 51 | background: #161616; 52 | border-radius: 5px; 53 | } 54 | 55 | #soundpack-bug { 56 | padding: 8px 5px; 57 | border: 1px solid #505050; 58 | background: #161616; 59 | border-radius: 5px; 60 | } 61 | 62 | #mouseSounds { 63 | padding: 8px 5px; 64 | border: 1px solid #505050; 65 | background: #161616; 66 | border-radius: 5px; 67 | } 68 | .mb-0 { 69 | margin-bottom: 0; 70 | } 71 | 72 | /* The slider itself */ 73 | .slider { 74 | -webkit-appearance: none; 75 | appearance: none; 76 | width: 100%; 77 | height: 5px; 78 | background: #6b6b6b; 79 | outline: none; 80 | opacity: 0.7; 81 | -webkit-transition: 0.2s; 82 | transition: opacity 0.2s; 83 | border-radius: 5px; 84 | margin-bottom: 12px; 85 | } 86 | 87 | /* Mouse-over effects */ 88 | .slider:hover { 89 | opacity: 1; 90 | /* Fully shown on mouse-over */ 91 | } 92 | 93 | /* The slider handle (use -webkit- (Chrome, Opera, Safari, Edge) and -moz- (Firefox) to override default look) */ 94 | .slider::-webkit-slider-thumb { 95 | -webkit-appearance: none; 96 | /* Override default look */ 97 | appearance: none; 98 | width: 20px; 99 | /* Set a specific slider handle width */ 100 | height: 20px; 101 | /* Slider handle height */ 102 | background: #ff5050; 103 | /* Green background */ 104 | cursor: pointer; 105 | /* Cursor on hover */ 106 | border-radius: 50%; 107 | } 108 | 109 | .slider::-moz-range-thumb { 110 | width: 20px; 111 | /* Set a specific slider handle width */ 112 | height: 20px; 113 | /* Slider handle height */ 114 | background: #ff5050; 115 | /* Green background */ 116 | cursor: pointer; 117 | /* Cursor on hover */ 118 | border-radius: 50%; 119 | } 120 | 121 | table tr td { 122 | border-bottom: 0; 123 | } 124 | 125 | table { 126 | margin-bottom: 0; 127 | } 128 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mechvibesplusplus", 3 | "productName": "MechvibesPlusPlus", 4 | "version": "v2.4.0", 5 | "description": "Play mechanical keyboard sounds as you type.", 6 | "repository": "https://github.com/PyroCalzone/MechVibesPlusPlus", 7 | "main": "src/main.js", 8 | "scripts": { 9 | "start": "electron .", 10 | "build:quick": "electron-builder -- --dir", 11 | "build:win": "electron-builder -w", 12 | "build:mac": "electron-builder -m", 13 | "build:linux": "electron-builder -l" 14 | }, 15 | "keywords": [], 16 | "homepage": "https://mechvibes.com", 17 | "author": { 18 | "name": "Pyro Calzone", 19 | "email": "pyrocalzoneemail+MechVibesPlusPlus@gmail.com" 20 | }, 21 | "license": "MIT", 22 | "iohook": { 23 | "targets": [ 24 | "node-64", 25 | "electron-73" 26 | ], 27 | "platforms": [ 28 | "win32", 29 | "darwin", 30 | "linux" 31 | ], 32 | "arches": [ 33 | "x64" 34 | ] 35 | }, 36 | "build": { 37 | "nsis": { 38 | "oneClick": false, 39 | "allowToChangeInstallationDirectory": true, 40 | "include": "build/installer.nsh" 41 | }, 42 | "win": { 43 | "target": [ 44 | { 45 | "target": "nsis", 46 | "arch": [ 47 | "x64" 48 | ] 49 | } 50 | ], 51 | "requestedExecutionLevel": "requireAdministrator", 52 | "icon": "src/assets/icon.png" 53 | }, 54 | "mac": { 55 | "target": [ 56 | { 57 | "target": "dmg", 58 | "arch": [ 59 | "x64" 60 | ] 61 | } 62 | ], 63 | "icon": "src/assets/icon.png" 64 | }, 65 | "linux": { 66 | "target": [ 67 | { 68 | "target": "deb", 69 | "arch": [ 70 | "x64" 71 | ] 72 | }, 73 | { 74 | "target": "snap", 75 | "arch": [ 76 | "x64" 77 | ] 78 | }, 79 | { 80 | "target": "AppImage", 81 | "arch": [ 82 | "x64" 83 | ] 84 | } 85 | ], 86 | "icon": "src/assets/icon.png" 87 | } 88 | }, 89 | "dependencies": { 90 | "discord.js": "^13.1.0", 91 | "dotenv": "^8.2.0", 92 | "electron-debug": "^3.2.0", 93 | "electron-is-dev": "^1.2.0", 94 | "electron-store": "^6.0.0", 95 | "express": "^4.17.1", 96 | "fs-extra": "^9.0.1", 97 | "glob": "^7.1.6", 98 | "howler": "^2.1.2", 99 | "iohook": "^0.6.2", 100 | "jquery": "^3.6.0", 101 | "node-fetch": "^2.6.1", 102 | "path": "^0.12.7" 103 | }, 104 | "devDependencies": { 105 | "app-builder-lib": "^22.2.0", 106 | "electron": "^6.1.5", 107 | "electron-builder": "^21.2.0", 108 | "electron-compile": "^6.4.4", 109 | "electron-packager": "^14.1.1" 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/libs/keycodes.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const standard = { 3 | 1: 'Esc', 4 | 5 | 59: 'F1', 6 | 60: 'F2', 7 | 61: 'F3', 8 | 62: 'F4', 9 | 63: 'F5', 10 | 64: 'F6', 11 | 65: 'F7', 12 | 66: 'F8', 13 | 67: 'F9', 14 | 68: 'F10', 15 | 87: 'F11', 16 | 88: 'F12', 17 | 18 | 91: 'F13', 19 | 92: 'F14', 20 | 93: 'F15', 21 | 22 | 41: '`', 23 | 24 | 2: '1', 25 | 3: '2', 26 | 4: '3', 27 | 5: '4', 28 | 6: '5', 29 | 7: '6', 30 | 8: '7', 31 | 9: '8', 32 | 10: '9', 33 | 11: '0', 34 | 35 | 12: '-', 36 | 13: '=', 37 | 14: 'Backspace', 38 | 39 | 15: 'Tab', 40 | 58: 'CapsLock', 41 | 42 | 30: 'A', 43 | 48: 'B', 44 | 46: 'C', 45 | 32: 'D', 46 | 18: 'E', 47 | 33: 'F', 48 | 34: 'G', 49 | 35: 'H', 50 | 23: 'I', 51 | 36: 'J', 52 | 37: 'K', 53 | 38: 'L', 54 | 50: 'M', 55 | 49: 'N', 56 | 24: 'O', 57 | 25: 'P', 58 | 16: 'Q', 59 | 19: 'R', 60 | 31: 'S', 61 | 20: 'T', 62 | 22: 'U', 63 | 47: 'V', 64 | 17: 'W', 65 | 45: 'X', 66 | 21: 'Y', 67 | 44: 'Z', 68 | 69 | 26: '[', 70 | 27: ']', 71 | 43: '\\', 72 | 73 | 39: ';', 74 | 40: "'", 75 | 28: 'Enter', 76 | 77 | 51: ',', 78 | 52: '.', 79 | 53: '/', 80 | 81 | 57: 'Space', 82 | 83 | 3639: 'PrtSc', 84 | 70: 'ScrLk', 85 | 3653: 'Pause', 86 | 87 | 3666: 'Ins', 88 | 3667: 'Del', 89 | 3655: 'Home', 90 | 3663: 'End', 91 | 3657: 'PgUp', 92 | 3665: 'PgDn', 93 | 94 | 57416: '↑', 95 | 57419: '←', 96 | 57421: '→', 97 | 57424: '↓', 98 | 99 | 42: 'Shift', 100 | 54: 'Shift', 101 | 29: 'Ctrl', 102 | 3613: 'Ctrl', 103 | 56: 'Alt', 104 | 3640: 'Alt', 105 | 3675: 'Meta', 106 | 3676: 'Meta', 107 | 3677: 'Menu', 108 | 109 | // Numpad 110 | 69: 'Num\nLock', 111 | 3637: '/', // Numpad 112 | 55: '*', // Numpad 113 | 74: '-', // Numpad 114 | 3597: '=', // Numpad 115 | 78: '+', // Numpad 116 | 3612: 'Enter', // Numpad 117 | 83: '.', // Numpad 118 | 119 | 79: '1', // Numpad 120 | 80: '2', // Numpad 121 | 81: '3', // Numpad 122 | 75: '4', // Numpad 123 | 76: '5', // Numpad 124 | 77: '6', // Numpad 125 | 71: '7', // Numpad 126 | 72: '8', // Numpad 127 | 73: '9', // Numpad 128 | 82: '0', // Numpad 129 | }; 130 | 131 | const darwin = JSON.parse(JSON.stringify(standard)); 132 | Object.assign(darwin, { 133 | 28: 'Return', 134 | 56: 'Option', 135 | 69: 'Clear', 136 | 3640: 'Option', 137 | 3666: 'Fn', 138 | 3675: 'Command', 139 | 3676: 'Command', 140 | }); 141 | 142 | const win32 = JSON.parse(JSON.stringify(standard)); 143 | Object.assign(win32, { 144 | 3675: 'Win', 145 | 3676: 'Win', 146 | 61010: 'Ins', 147 | 61011: 'Del', 148 | 60999: 'Home', 149 | 61007: 'End', 150 | 61001: 'PgUp', 151 | 61009: 'PgDn', 152 | 61000: '↑', 153 | 61003: '←', 154 | 61005: '→', 155 | 61008: '↓', 156 | }); 157 | 158 | const linux = JSON.parse(JSON.stringify(standard)); 159 | 160 | module.exports = { darwin, win32, linux }; 161 | -------------------------------------------------------------------------------- /src/sounds/keys/nk-cream/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "custom-sound-pack-1599402588730", 3 | "name": "NK Cream", 4 | "key_define_type": "multi", 5 | "includes_numpad": false, 6 | "sound": "sound.ogg", 7 | "defines": { 8 | "1": "q.wav", 9 | "2": "w.wav", 10 | "3": "e.wav", 11 | "4": "e.wav", 12 | "5": "r.wav", 13 | "6": "t.wav", 14 | "7": "y.wav", 15 | "8": "u.wav", 16 | "9": "i.wav", 17 | "10": "o.wav", 18 | "11": "p.wav", 19 | "12": "[.wav", 20 | "13": "].wav", 21 | "14": "backspace.wav", 22 | "15": "tab.wav", 23 | "16": "q.wav", 24 | "17": "w.wav", 25 | "18": "e.wav", 26 | "19": "r.wav", 27 | "20": "t.wav", 28 | "21": "y.wav", 29 | "22": "u.wav", 30 | "23": "i.wav", 31 | "24": "o.wav", 32 | "25": "p.wav", 33 | "26": "[.wav", 34 | "27": "].wav", 35 | "28": "enter.wav", 36 | "29": "tab.wav", 37 | "30": "a-down.wav", 38 | "31": "s.wav", 39 | "32": "d.wav", 40 | "33": "f.wav", 41 | "34": "g.wav", 42 | "35": "h.wav", 43 | "36": "j.wav", 44 | "37": "k.wav", 45 | "38": "l.wav", 46 | "39": "[.wav", 47 | "40": "].wav", 48 | "41": "q.wav", 49 | "42": "shift.wav", 50 | "43": "backspace.wav", 51 | "44": "z.wav", 52 | "45": "x.wav", 53 | "46": "c.wav", 54 | "47": "v.wav", 55 | "48": "b.wav", 56 | "49": "n.wav", 57 | "50": "m.wav", 58 | "51": "l.wav", 59 | "52": "[.wav", 60 | "53": "].wav", 61 | "54": "shift.wav", 62 | "55": "o.wav", 63 | "56": "e.wav", 64 | "57": "space.wav", 65 | "58": "caps lock.wav", 66 | "59": "w.wav", 67 | "60": "e.wav", 68 | "61": "e.wav", 69 | "62": "r.wav", 70 | "63": "t.wav", 71 | "64": "y.wav", 72 | "65": "u.wav", 73 | "66": "i.wav", 74 | "67": "o.wav", 75 | "68": "p.wav", 76 | "69": "u.wav", 77 | "70": "i.wav", 78 | "71": "y.wav", 79 | "72": "u.wav", 80 | "73": "i.wav", 81 | "74": "p.wav", 82 | "75": "h.wav", 83 | "76": "j.wav", 84 | "77": "k.wav", 85 | "78": "enter.wav", 86 | "79": "b.wav", 87 | "80": "n.wav", 88 | "81": "m.wav", 89 | "82": "shift.wav", 90 | "83": "[.wav", 91 | "87": "].wav", 92 | "88": "].wav", 93 | "91": null, 94 | "92": null, 95 | "93": null, 96 | "3597": null, 97 | "3612": "shift.wav", 98 | "3613": "backspace.wav", 99 | "3637": "i.wav", 100 | "3639": "u.wav", 101 | "3640": "p.wav", 102 | "3653": "o.wav", 103 | "3655": "h.wav", 104 | "3657": "k.wav", 105 | "3663": "n.wav", 106 | "3665": "m.wav", 107 | "3666": "h.wav", 108 | "3667": "b.wav", 109 | "3675": "q.wav", 110 | "3676": "[.wav", 111 | "3677": "].wav", 112 | "57416": "g.wav", 113 | "57419": "c.wav", 114 | "57421": "b.wav", 115 | "57424": "v.wav", 116 | "60999": "h.wav", 117 | "61000": "g.wav", 118 | "61001": "k.wav", 119 | "61003": "c.wav", 120 | "61005": "b.wav", 121 | "61007": "n.wav", 122 | "61008": "v.wav", 123 | "61009": "m.wav", 124 | "61010": "h.wav", 125 | "61011": "b.wav", 126 | "001": "a-up.wav" 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/editor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Editor 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 |
16 |
17 |

Editor

18 |
Create, edit, share your sound pack! How to?
19 |
20 |
21 | 22 | 23 | 24 | 25 |
26 |
27 | 28 |
29 |
30 |
31 | 32 | 33 |
34 |
35 | 36 | 40 |
41 |
42 | 43 | 47 |
48 |
49 | 50 | 51 |
52 |
53 |
54 | 55 |
Loading...
56 | 57 |
58 |
59 |
60 |
61 |
62 |
63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /src/assets/editor.css: -------------------------------------------------------------------------------- 1 | body { 2 | --keybasewidth: 50px; 3 | font-family: arial, sans-serif; 4 | font-size: 13px; 5 | } 6 | 7 | .container { 8 | margin: 0 auto; 9 | width: 1150px; 10 | } 11 | 12 | .header { 13 | border-bottom: 1px solid #ccc; 14 | padding: 20px 0; 15 | margin-bottom: 30px; 16 | } 17 | .header .sub-header { 18 | color: #666; 19 | font-size: 14px; 20 | } 21 | 22 | /* keyboard layout css */ 23 | #kb { 24 | display: flex; 25 | } 26 | 27 | #zone-main { 28 | margin-right: 15px; 29 | } 30 | 31 | #zone-edit { 32 | margin-right: 15px; 33 | } 34 | 35 | #zone-numpad { 36 | } 37 | 38 | .key-row { 39 | width: 100%; 40 | height: var(--keybasewidth); 41 | display: flex; 42 | } 43 | 44 | .key-row-top { 45 | margin-bottom: 15px; 46 | } 47 | 48 | .key { 49 | cursor: pointer; 50 | height: var(--keybasewidth); 51 | font-size: 13px; 52 | outline: 1px solid #333; 53 | width: var(--keybasewidth); 54 | position: relative; 55 | background: #fff; 56 | } 57 | .key .key-rk { 58 | font-size: 10px; 59 | color: #999; 60 | position: absolute; 61 | bottom: 5px; 62 | left: 5px; 63 | } 64 | 65 | .key:hover { 66 | opacity: 1; 67 | background: #ffe0e0; 68 | } 69 | .key-pressed { 70 | color: #000; 71 | background: #f5b6b6 !important; 72 | } 73 | .key-has-sound { 74 | background: #defbde !important; 75 | } 76 | 77 | .popover { 78 | cursor: default; 79 | z-index: 999; 80 | display: none; 81 | position: absolute; 82 | top: var(--keybasewidth); 83 | left: -1px; 84 | background: #fff; 85 | padding: 10px; 86 | border: 1px solid #000; 87 | } 88 | 89 | .popover.up { 90 | bottom: var(--keybasewidth); 91 | top: auto; 92 | } 93 | .popover.left { 94 | right: -1px; 95 | left: auto; 96 | } 97 | 98 | .key-show-popover .popover { 99 | display: inline-block; 100 | } 101 | 102 | .key-hide { 103 | opacity: 0.2; 104 | z-index: auto !important; 105 | } 106 | 107 | .key-blank:hover, 108 | .key-blank { 109 | cursor: default; 110 | opacity: 0; 111 | border-color: transparent; 112 | } 113 | 114 | .key .letter { 115 | position: absolute; 116 | top: 5px; 117 | left: 5px; 118 | } 119 | 120 | .key-125u { 121 | width: calc(var(--keybasewidth) * 1.25) !important; 122 | } 123 | .key-15u { 124 | width: calc(var(--keybasewidth) * 1.5) !important; 125 | } 126 | .key-175u { 127 | width: calc(var(--keybasewidth) * 1.75) !important; 128 | } 129 | 130 | .key-2u { 131 | width: calc(var(--keybasewidth) * 2) !important; 132 | } 133 | 134 | .key-height-2u { 135 | height: calc(var(--keybasewidth) * 2) !important; 136 | z-index: 99; 137 | } 138 | 139 | .key-225u { 140 | width: calc(var(--keybasewidth) * 2.25) !important; 141 | } 142 | 143 | .key-275u { 144 | width: calc(var(--keybasewidth) * 2.75) !important; 145 | } 146 | 147 | .key-625u { 148 | width: calc(var(--keybasewidth) * 6.25) !important; 149 | } 150 | 151 | /* pack info editor */ 152 | #pack-header { 153 | margin-bottom: 30px; 154 | } 155 | 156 | .pack-detail { 157 | margin-top: 30px; 158 | display: flex; 159 | } 160 | .pack-detail .col { 161 | border-right: 1px solid #e4e4e4; 162 | } 163 | .pack-detail .col:last-child { 164 | border-right: 0; 165 | } 166 | 167 | .divider { 168 | display: block; 169 | width: 100%; 170 | border-bottom: 1px solid #e4e4e4; 171 | margin-top: 1rem; 172 | margin-bottom: 1rem; 173 | } 174 | -------------------------------------------------------------------------------- /src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Mechvibes++ 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 |
18 | 19 | 20 | 21 | 24 | 25 | 26 | 34 | 35 | 36 | 37 | 40 | 41 | 42 | 43 | 46 | 47 | 48 |
22 | 23 |
27 | 28 |
29 | 30 | Join our Discord. 31 | 32 |
33 |
Keyboard Volume 38 | 39 |
44 | 45 |
49 |
50 |
51 |

Made with ❤ by Pyro & Saturn

52 |

53 | Support Original Mechvibes 54 |   |   55 | Our GitHub 56 |   |   57 | Buy me a coffee 58 |

59 |

-

60 | 66 | 71 | 74 |
75 | 76 | 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 12 | 13 | 14 | 21 | [![Contributors][contributors-shield]][contributors-url] 22 | [![Forks][forks-shield]][forks-url] 23 | [![Stargazers][stars-shield]][stars-url] 24 | [![Issues][issues-shield]][issues-url] 25 | [![MIT License][license-shield]][license-url] 26 | 27 | 28 | 29 | 30 |
31 |
32 | 34 | 35 |
36 | 37 | 38 | 39 | 40 |
41 | Table of Contents 42 |
    43 |
  1. 44 | About The Project 45 | 48 |
  2. 49 |
  3. 50 | Getting Started 51 | 55 |
  4. 56 |
  5. Issues
  6. 57 |
  7. Contributing
  8. 58 |
  9. License
  10. 59 |
  11. Linux and macOS
  12. 60 |
61 |
62 | 63 | 64 | 65 | 66 | ## About The Project 67 | 68 | [![Product Name Screen Shot][product-screenshot]](src/assets/app_image.png) 69 | 70 | Mechvibes++ brings mouse sounds, key up-and-down sounds, and randomized sounds to Mechvibes. 71 | 72 |

(back to top)

73 | 74 | ### Built With 75 | 76 | * [![Electron][Electron]][Electron-url] 77 | * [![Node.js][Nodejs]][Nodejs-url] 78 | 79 |

(back to top)

80 | 81 | 82 | 83 | ## Getting Started 84 | 85 | ### Prerequisites 86 | 87 | If regular Mechvibes loads normally without any issues, please skip this. 88 | 89 | Download [VC Redist 2015-2019](https://aka.ms/vs/16/release/vc_redist.x64.exe) 90 | 91 | Run the [executable](https://github.com/PyroCalzone/MechVibesPlusPlus/releases) and let it install. Continue with Mechvibes++ installation when it finishes. 92 | 93 | ### Installation Requirements 94 | 95 | - Approximately 200mb of storage available 96 | - Version 2.3.1 comes in around 170mb for us, but this may vary for you. 97 | - Running Windows 8.1 (or later) 98 | - VC Redist (listed above) 99 | - 64-bit (x64) based PC/laptop 100 | - Reccomendation: > 6-8gb of RAM 101 | 102 | 103 | 104 | ## Issues 105 | 106 | Read the [issues list](issues.md) here 107 | 108 | Please [join our discord](https://discord.gg/CZ8Qgth2SW) if you need additional help (read the list first) 109 | 110 | 111 |

(back to top)

112 | 113 | 114 | ## Contributing 115 | 116 | Any contributions you make are **greatly appreciated**. 117 | 118 | If you have a suggestion that would make Mechvibes++ better, please fork the repo and create a pull request. 119 | 120 |

(back to top)

121 | 122 | 123 | ## License 124 | 125 | Distributed under the MIT License. See [the license file](LICENSE) for more information. 126 | 127 |

(back to top)

128 | 129 | ## Linux and macOS 130 | 131 | There is currently **no support** for either operating system since neither of us own a Mac or are able to make time to install Linux and make a version for it. 132 | 133 | If you own a Mac or run Linux, you can create a build yourself. Instructions are posted [here](doc/linux-and-mac.md). 134 | 135 | 136 |

(back to top)

137 | 138 | 139 | 140 | 141 | [contributors-shield]: https://img.shields.io/github/contributors/PyroCalzone/MechVibesPlusPlus.svg?style=for-the-badge 142 | [contributors-url]: https://github.com/PyroCalzone/MechVibesPlusPlus/graphs/contributors 143 | [forks-shield]: https://img.shields.io/github/forks/PyroCalzone/MechVibesPlusPlus.svg?style=for-the-badge 144 | [forks-url]: https://github.com/PyroCalzone/MechVibesPlusPlus/network/members 145 | [stars-shield]: https://img.shields.io/github/stars/PyroCalzone/MechVibesPlusPlus.svg?style=for-the-badge 146 | [stars-url]: https://github.com/PyroCalzone/MechVibesPlusPlus/stargazers 147 | [issues-shield]: https://img.shields.io/github/issues/PyroCalzone/MechVibesPlusPlus.svg?style=for-the-badge 148 | [issues-url]: https://github.com/PyroCalzone/MechVibesPlusPlus/issues 149 | [license-shield]: https://img.shields.io/github/license/PyroCalzone/MechVibesPlusPlus.svg?style=for-the-badge 150 | [license-url]: https://github.com/PyroCalzone/MechVibesPlusPlus/blob/main/LICENSE 151 | [product-screenshot]: src/assets/app_image.png 152 | [Nodejs]: https://img.shields.io/badge/node.js-000000?style=for-the-badge&logo=nodedotjs 153 | [Nodejs-url]: https://nodejs.org/ 154 | [Electron]: https://img.shields.io/badge/Electron-000000?style=for-the-badge&logo=electron 155 | [Electron-url]: https://www.electronjs.org/ 156 | -------------------------------------------------------------------------------- /src/sounds/keys/cherrymx-brown-abs/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "custom-sound-pack-1582656695035", 3 | "name": "CherryMX Brown - ABS keycaps", 4 | "key_define_type": "single", 5 | "includes_numpad": false, 6 | "sound": "sound.ogg", 7 | "defines": { 8 | "1": [ 9 | 1402, 10 | 170 11 | ], 12 | "2": [ 13 | 8760, 14 | 173 15 | ], 16 | "3": [ 17 | 9149, 18 | 167 19 | ], 20 | "4": [ 21 | 9550, 22 | 165 23 | ], 24 | "5": [ 25 | 9942, 26 | 150 27 | ], 28 | "6": [ 29 | 10370, 30 | 145 31 | ], 32 | "7": [ 33 | 10791, 34 | 140 35 | ], 36 | "8": [ 37 | 11205, 38 | 150 39 | ], 40 | "9": [ 41 | 11603, 42 | 136 43 | ], 44 | "10": [ 45 | 12012, 46 | 148 47 | ], 48 | "11": [ 49 | 12440, 50 | 140 51 | ], 52 | "12": [ 53 | 12844, 54 | 131 55 | ], 56 | "13": [ 57 | 13231, 58 | 132 59 | ], 60 | "14": [ 61 | 13667, 62 | 134 63 | ], 64 | "15": [ 65 | 15286, 66 | 161 67 | ], 68 | "16": [ 69 | 15665, 70 | 180 71 | ], 72 | "17": [ 73 | 16052, 74 | 171 75 | ], 76 | "18": [ 77 | 16411, 78 | 174 79 | ], 80 | "19": [ 81 | 16772, 82 | 158 83 | ], 84 | "20": [ 85 | 17124, 86 | 178 87 | ], 88 | "21": [ 89 | 17478, 90 | 142 91 | ], 92 | "22": [ 93 | 17843, 94 | 146 95 | ], 96 | "23": [ 97 | 18212, 98 | 139 99 | ], 100 | "24": [ 101 | 18611, 102 | 148 103 | ], 104 | "25": [ 105 | 19036, 106 | 134 107 | ], 108 | "26": [ 109 | 19440, 110 | 127 111 | ], 112 | "27": [ 113 | 19854, 114 | 192 115 | ], 116 | "28": [ 117 | 26548, 118 | 119 119 | ], 120 | "29": [ 121 | 32761, 122 | 168 123 | ], 124 | "30": [ 125 | 22324, 126 | 167 127 | ], 128 | "31": [ 129 | 22698, 130 | 167 131 | ], 132 | "32": [ 133 | 23072, 134 | 163 135 | ], 136 | "33": [ 137 | 23408, 138 | 178 139 | ], 140 | "34": [ 141 | 23770, 142 | 183 143 | ], 144 | "35": [ 145 | 24140, 146 | 145 147 | ], 148 | "36": [ 149 | 24525, 150 | 154 151 | ], 152 | "37": [ 153 | 24919, 154 | 138 155 | ], 156 | "38": [ 157 | 25314, 158 | 142 159 | ], 160 | "39": [ 161 | 25711, 162 | 129 163 | ], 164 | "40": [ 165 | 26121, 166 | 123 167 | ], 168 | "41": [ 169 | 8365, 170 | 166 171 | ], 172 | "42": [ 173 | 27208, 174 | 158 175 | ], 176 | "43": [ 177 | 20262, 178 | 143 179 | ], 180 | "44": [ 181 | 27589, 182 | 164 183 | ], 184 | "45": [ 185 | 27978, 186 | 160 187 | ], 188 | "46": [ 189 | 28321, 190 | 160 191 | ], 192 | "47": [ 193 | 28694, 194 | 162 195 | ], 196 | "48": [ 197 | 29071, 198 | 152 199 | ], 200 | "49": [ 201 | 29485, 202 | 159 203 | ], 204 | "50": [ 205 | 29873, 206 | 137 207 | ], 208 | "51": [ 209 | 30269, 210 | 139 211 | ], 212 | "52": [ 213 | 30664, 214 | 132 215 | ], 216 | "53": [ 217 | 31026, 218 | 138 219 | ], 220 | "54": [ 221 | 31455, 222 | 139 223 | ], 224 | "55": [ 225 | 7874, 226 | 148 227 | ], 228 | "56": [ 229 | 33530, 230 | 170 231 | ], 232 | "57": [ 233 | 37338, 234 | 200 235 | ], 236 | "58": [ 237 | 21920, 238 | 176 239 | ], 240 | "59": [ 241 | 1852, 242 | 162 243 | ], 244 | "60": [ 245 | 2275, 246 | 155 247 | ], 248 | "61": [ 249 | 2668, 250 | 167 251 | ], 252 | "62": [ 253 | 3054, 254 | 162 255 | ], 256 | "63": [ 257 | 3467, 258 | 161 259 | ], 260 | "64": [ 261 | 3877, 262 | 151 263 | ], 264 | "65": [ 265 | 4501, 266 | 120 267 | ], 268 | "66": [ 269 | 4951, 270 | 141 271 | ], 272 | "67": [ 273 | 5381, 274 | 133 275 | ], 276 | "68": [ 277 | 5779, 278 | 145 279 | ], 280 | "69": [ 281 | 7023, 282 | 161 283 | ], 284 | "70": [ 285 | 7448, 286 | 142 287 | ], 288 | "71": [ 289 | 14084, 290 | 125 291 | ], 292 | "72": [ 293 | 14500, 294 | 142 295 | ], 296 | "73": [ 297 | 14877, 298 | 146 299 | ], 300 | "74": [ 301 | 12844, 302 | 131 303 | ], 304 | "75": [ 305 | 20713, 306 | 139 307 | ], 308 | "76": [ 309 | 21121, 310 | 151 311 | ], 312 | "77": [ 313 | 21527, 314 | 142 315 | ], 316 | "78": [ 317 | 13667, 318 | 134 319 | ], 320 | "79": [ 321 | 35966, 322 | 143 323 | ], 324 | "80": [ 325 | 36356, 326 | 147 327 | ], 328 | "81": [ 329 | 36787, 330 | 170 331 | ], 332 | "82": [ 333 | 31455, 334 | 139 335 | ], 336 | "83": [ 337 | 32054, 338 | 167 339 | ], 340 | "87": [ 341 | 6207, 342 | 139 343 | ], 344 | "88": [ 345 | 6637, 346 | 127 347 | ], 348 | "3612": [ 349 | 26548, 350 | 119 351 | ], 352 | "3613": [ 353 | 35572, 354 | 139 355 | ], 356 | "3637": [ 357 | 7448, 358 | 142 359 | ], 360 | "3639": [ 361 | 7023, 362 | 161 363 | ], 364 | "3640": [ 365 | 34354, 366 | 157 367 | ], 368 | "3653": [ 369 | 7874, 370 | 148 371 | ], 372 | "3655": [ 373 | 14500, 374 | 142 375 | ], 376 | "3657": [ 377 | 14877, 378 | 146 379 | ], 380 | "3663": [ 381 | 21121, 382 | 151 383 | ], 384 | "3665": [ 385 | 21527, 386 | 142 387 | ], 388 | "3666": [ 389 | 14084, 390 | 125 391 | ], 392 | "3667": [ 393 | 20713, 394 | 139 395 | ], 396 | "3675": [ 397 | 33157, 398 | 170 399 | ], 400 | "3676": [ 401 | 34762, 402 | 147 403 | ], 404 | "3677": [ 405 | 35572, 406 | 139 407 | ], 408 | "57416": [ 409 | 32054, 410 | 167 411 | ], 412 | "57419": [ 413 | 35966, 414 | 143 415 | ], 416 | "57421": [ 417 | 36787, 418 | 170 419 | ], 420 | "57424": [ 421 | 36356, 422 | 147 423 | ], 424 | "60999": [ 425 | 14500, 426 | 142 427 | ], 428 | "61000": [ 429 | 32054, 430 | 167 431 | ], 432 | "61001": [ 433 | 14877, 434 | 146 435 | ], 436 | "61003": [ 437 | 35966, 438 | 143 439 | ], 440 | "61005": [ 441 | 36787, 442 | 170 443 | ], 444 | "61007": [ 445 | 21121, 446 | 151 447 | ], 448 | "61008": [ 449 | 36356, 450 | 147 451 | ], 452 | "61009": [ 453 | 21527, 454 | 142 455 | ], 456 | "61010": [ 457 | 14084, 458 | 125 459 | ], 460 | "61011": [ 461 | 20713, 462 | 139 463 | ] 464 | } 465 | } -------------------------------------------------------------------------------- /src/sounds/keys/cherrymx-black-pbt/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "custom-sound-pack-1582654366773", 3 | "name": "CherryMX Black - PBT keycaps", 4 | "key_define_type": "single", 5 | "includes_numpad": false, 6 | "sound": "sound.ogg", 7 | "defines": { 8 | "1": [ 9 | 2078, 10 | 176 11 | ], 12 | "2": [ 13 | 9291, 14 | 164 15 | ], 16 | "3": [ 17 | 9702, 18 | 153 19 | ], 20 | "4": [ 21 | 10097, 22 | 140 23 | ], 24 | "5": [ 25 | 10459, 26 | 165 27 | ], 28 | "6": [ 29 | 10859, 30 | 165 31 | ], 32 | "7": [ 33 | 11250, 34 | 165 35 | ], 36 | "8": [ 37 | 11648, 38 | 159 39 | ], 40 | "9": [ 41 | 12014, 42 | 150 43 | ], 44 | "10": [ 45 | 12414, 46 | 136 47 | ], 48 | "11": [ 49 | 12826, 50 | 137 51 | ], 52 | "12": [ 53 | 13227, 54 | 138 55 | ], 56 | "13": [ 57 | 13625, 58 | 134 59 | ], 60 | "14": [ 61 | 14035, 62 | 137 63 | ], 64 | "15": [ 65 | 15707, 66 | 163 67 | ], 68 | "16": [ 69 | 16114, 70 | 157 71 | ], 72 | "17": [ 73 | 16515, 74 | 150 75 | ], 76 | "18": [ 77 | 16889, 78 | 147 79 | ], 80 | "19": [ 81 | 17253, 82 | 161 83 | ], 84 | "20": [ 85 | 17630, 86 | 156 87 | ], 88 | "21": [ 89 | 18024, 90 | 140 91 | ], 92 | "22": [ 93 | 18416, 94 | 134 95 | ], 96 | "23": [ 97 | 18815, 98 | 140 99 | ], 100 | "24": [ 101 | 19229, 102 | 128 103 | ], 104 | "25": [ 105 | 19632, 106 | 127 107 | ], 108 | "26": [ 109 | 20024, 110 | 131 111 | ], 112 | "27": [ 113 | 20438, 114 | 131 115 | ], 116 | "28": [ 117 | 27154, 118 | 171 119 | ], 120 | "29": [ 121 | 33678, 122 | 163 123 | ], 124 | "30": [ 125 | 22850, 126 | 160 127 | ], 128 | "31": [ 129 | 23243, 130 | 156 131 | ], 132 | "32": [ 133 | 23645, 134 | 155 135 | ], 136 | "33": [ 137 | 24034, 138 | 152 139 | ], 140 | "34": [ 141 | 24445, 142 | 146 143 | ], 144 | "35": [ 145 | 24824, 146 | 148 147 | ], 148 | "36": [ 149 | 25181, 150 | 164 151 | ], 152 | "37": [ 153 | 25593, 154 | 145 155 | ], 156 | "38": [ 157 | 25993, 158 | 139 159 | ], 160 | "39": [ 161 | 26393, 162 | 136 163 | ], 164 | "40": [ 165 | 26801, 166 | 128 167 | ], 168 | "41": [ 169 | 8869, 170 | 181 171 | ], 172 | "42": [ 173 | 28061, 174 | 186 175 | ], 176 | "43": [ 177 | 20858, 178 | 129 179 | ], 180 | "44": [ 181 | 28466, 182 | 161 183 | ], 184 | "45": [ 185 | 28845, 186 | 151 187 | ], 188 | "46": [ 189 | 29208, 190 | 156 191 | ], 192 | "47": [ 193 | 29571, 194 | 144 195 | ], 196 | "48": [ 197 | 29926, 198 | 159 199 | ], 200 | "49": [ 201 | 30248, 202 | 139 203 | ], 204 | "50": [ 205 | 30598, 206 | 140 207 | ], 208 | "51": [ 209 | 30981, 210 | 130 211 | ], 212 | "52": [ 213 | 31353, 214 | 128 215 | ], 216 | "53": [ 217 | 31740, 218 | 126 219 | ], 220 | "54": [ 221 | 32135, 222 | 169 223 | ], 224 | "55": [ 225 | 8372, 226 | 140 227 | ], 228 | "56": [ 229 | 34451, 230 | 164 231 | ], 232 | "57": [ 233 | 34906, 234 | 168 235 | ], 236 | "58": [ 237 | 22462, 238 | 166 239 | ], 240 | "59": [ 241 | 2511, 242 | 186 243 | ], 244 | "60": [ 245 | 2919, 246 | 177 247 | ], 248 | "61": [ 249 | 3307, 250 | 185 251 | ], 252 | "62": [ 253 | 3700, 254 | 176 255 | ], 256 | "63": [ 257 | 4164, 258 | 148 259 | ], 260 | "64": [ 261 | 4613, 262 | 155 263 | ], 264 | "65": [ 265 | 5024, 266 | 150 267 | ], 268 | "66": [ 269 | 5438, 270 | 147 271 | ], 272 | "67": [ 273 | 5862, 274 | 149 275 | ], 276 | "68": [ 277 | 6270, 278 | 138 279 | ], 280 | "69": [ 281 | 7547, 282 | 134 283 | ], 284 | "70": [ 285 | 7957, 286 | 141 287 | ], 288 | "71": [ 289 | 14524, 290 | 141 291 | ], 292 | "72": [ 293 | 14949, 294 | 119 295 | ], 296 | "73": [ 297 | 15311, 298 | 143 299 | ], 300 | "74": [ 301 | 13227, 302 | 138 303 | ], 304 | "75": [ 305 | 21286, 306 | 113 307 | ], 308 | "76": [ 309 | 21671, 310 | 146 311 | ], 312 | "77": [ 313 | 22078, 314 | 134 315 | ], 316 | "78": [ 317 | 14035, 318 | 137 319 | ], 320 | "79": [ 321 | 36831, 322 | 144 323 | ], 324 | "80": [ 325 | 37213, 326 | 144 327 | ], 328 | "81": [ 329 | 37569, 330 | 155 331 | ], 332 | "82": [ 333 | 32135, 334 | 169 335 | ], 336 | "83": [ 337 | 32948, 338 | 138 339 | ], 340 | "87": [ 341 | 6697, 342 | 137 343 | ], 344 | "88": [ 345 | 7122, 346 | 136 347 | ], 348 | "3612": [ 349 | 27154, 350 | 171 351 | ], 352 | "3613": [ 353 | 36449, 354 | 137 355 | ], 356 | "3637": [ 357 | 7957, 358 | 141 359 | ], 360 | "3639": [ 361 | 7547, 362 | 134 363 | ], 364 | "3640": [ 365 | 35316, 366 | 145 367 | ], 368 | "3653": [ 369 | 8372, 370 | 140 371 | ], 372 | "3655": [ 373 | 14949, 374 | 119 375 | ], 376 | "3657": [ 377 | 15311, 378 | 143 379 | ], 380 | "3663": [ 381 | 21671, 382 | 146 383 | ], 384 | "3665": [ 385 | 22078, 386 | 134 387 | ], 388 | "3666": [ 389 | 14524, 390 | 141 391 | ], 392 | "3667": [ 393 | 21286, 394 | 113 395 | ], 396 | "3675": [ 397 | 34093, 398 | 157 399 | ], 400 | "3676": [ 401 | 35716, 402 | 136 403 | ], 404 | "3677": [ 405 | 36449, 406 | 137 407 | ], 408 | "57416": [ 409 | 32948, 410 | 138 411 | ], 412 | "57419": [ 413 | 36831, 414 | 144 415 | ], 416 | "57421": [ 417 | 37569, 418 | 155 419 | ], 420 | "57424": [ 421 | 37213, 422 | 144 423 | ], 424 | "60999": [ 425 | 14949, 426 | 119 427 | ], 428 | "61000": [ 429 | 32948, 430 | 138 431 | ], 432 | "61001": [ 433 | 15311, 434 | 143 435 | ], 436 | "61003": [ 437 | 36831, 438 | 144 439 | ], 440 | "61005": [ 441 | 37569, 442 | 155 443 | ], 444 | "61007": [ 445 | 21671, 446 | 146 447 | ], 448 | "61008": [ 449 | 37213, 450 | 144 451 | ], 452 | "61009": [ 453 | 22078, 454 | 134 455 | ], 456 | "61010": [ 457 | 14524, 458 | 141 459 | ], 460 | "61011": [ 461 | 21286, 462 | 113 463 | ] 464 | } 465 | } -------------------------------------------------------------------------------- /src/sounds/keys/cherrymx-blue-abs/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "custom-sound-pack-1582707445334", 3 | "name": "CherryMX Blue - ABS keycaps", 4 | "key_define_type": "single", 5 | "includes_numpad": false, 6 | "sound": "sound.ogg", 7 | "defines": { 8 | "1": [ 9 | 1754, 10 | 184 11 | ], 12 | "2": [ 13 | 10135, 14 | 199 15 | ], 16 | "3": [ 17 | 10562, 18 | 185 19 | ], 20 | "4": [ 21 | 10966, 22 | 189 23 | ], 24 | "5": [ 25 | 11329, 26 | 199 27 | ], 28 | "6": [ 29 | 11706, 30 | 196 31 | ], 32 | "7": [ 33 | 12094, 34 | 180 35 | ], 36 | "8": [ 37 | 12467, 38 | 184 39 | ], 40 | "9": [ 41 | 12863, 42 | 190 43 | ], 44 | "10": [ 45 | 13248, 46 | 195 47 | ], 48 | "11": [ 49 | 13633, 50 | 170 51 | ], 52 | "12": [ 53 | 13988, 54 | 186 55 | ], 56 | "13": [ 57 | 14372, 58 | 180 59 | ], 60 | "14": [ 61 | 14748, 62 | 212 63 | ], 64 | "15": [ 65 | 16940, 66 | 179 67 | ], 68 | "16": [ 69 | 17316, 70 | 199 71 | ], 72 | "17": [ 73 | 17700, 74 | 172 75 | ], 76 | "18": [ 77 | 18054, 78 | 187 79 | ], 80 | "19": [ 81 | 18400, 82 | 184 83 | ], 84 | "20": [ 85 | 18761, 86 | 176 87 | ], 88 | "21": [ 89 | 19116, 90 | 188 91 | ], 92 | "22": [ 93 | 19495, 94 | 186 95 | ], 96 | "23": [ 97 | 19876, 98 | 174 99 | ], 100 | "24": [ 101 | 20238, 102 | 170 103 | ], 104 | "25": [ 105 | 20605, 106 | 158 107 | ], 108 | "26": [ 109 | 20976, 110 | 164 111 | ], 112 | "27": [ 113 | 21348, 114 | 158 115 | ], 116 | "28": [ 117 | 28558, 118 | 161 119 | ], 120 | "29": [ 121 | 35733, 122 | 190 123 | ], 124 | "30": [ 125 | 24330, 126 | 196 127 | ], 128 | "31": [ 129 | 24700, 130 | 202 131 | ], 132 | "32": [ 133 | 25071, 134 | 194 135 | ], 136 | "33": [ 137 | 25444, 138 | 206 139 | ], 140 | "34": [ 141 | 25803, 142 | 188 143 | ], 144 | "35": [ 145 | 26159, 146 | 185 147 | ], 148 | "36": [ 149 | 26534, 150 | 168 151 | ], 152 | "37": [ 153 | 26928, 154 | 190 155 | ], 156 | "38": [ 157 | 27347, 158 | 180 159 | ], 160 | "39": [ 161 | 27733, 162 | 183 163 | ], 164 | "40": [ 165 | 28157, 166 | 176 167 | ], 168 | "41": [ 169 | 9749, 170 | 195 171 | ], 172 | "42": [ 173 | 29603, 174 | 226 175 | ], 176 | "43": [ 177 | 21707, 178 | 182 179 | ], 180 | "44": [ 181 | 30046, 182 | 175 183 | ], 184 | "45": [ 185 | 30385, 186 | 177 187 | ], 188 | "46": [ 189 | 30761, 190 | 189 191 | ], 192 | "47": [ 193 | 31123, 194 | 191 195 | ], 196 | "48": [ 197 | 31475, 198 | 196 199 | ], 200 | "49": [ 201 | 31891, 202 | 169 203 | ], 204 | "50": [ 205 | 32333, 206 | 175 207 | ], 208 | "51": [ 209 | 33011, 210 | 186 211 | ], 212 | "52": [ 213 | 33438, 214 | 172 215 | ], 216 | "53": [ 217 | 33828, 218 | 178 219 | ], 220 | "54": [ 221 | 34215, 222 | 180 223 | ], 224 | "55": [ 225 | 7583, 226 | 193 227 | ], 228 | "56": [ 229 | 36465, 230 | 214 231 | ], 232 | "57": [ 233 | 36804, 234 | 240 235 | ], 236 | "58": [ 237 | 23925, 238 | 207 239 | ], 240 | "59": [ 241 | 2222, 242 | 186 243 | ], 244 | "60": [ 245 | 2617, 246 | 180 247 | ], 248 | "61": [ 249 | 3028, 250 | 189 251 | ], 252 | "62": [ 253 | 3385, 254 | 223 255 | ], 256 | "63": [ 257 | 3792, 258 | 193 259 | ], 260 | "64": [ 261 | 4136, 262 | 212 263 | ], 264 | "65": [ 265 | 4540, 266 | 188 267 | ], 268 | "66": [ 269 | 4903, 270 | 193 271 | ], 272 | "67": [ 273 | 5296, 274 | 193 275 | ], 276 | "68": [ 277 | 5666, 278 | 183 279 | ], 280 | "69": [ 281 | 6818, 282 | 167 283 | ], 284 | "70": [ 285 | 7187, 286 | 183 287 | ], 288 | "71": [ 289 | 15156, 290 | 180 291 | ], 292 | "72": [ 293 | 15526, 294 | 204 295 | ], 296 | "73": [ 297 | 15893, 298 | 157 299 | ], 300 | "74": [ 301 | 13988, 302 | 186 303 | ], 304 | "75": [ 305 | 22116, 306 | 179 307 | ], 308 | "76": [ 309 | 22513, 310 | 173 311 | ], 312 | "77": [ 313 | 22862, 314 | 158 315 | ], 316 | "78": [ 317 | 14748, 318 | 212 319 | ], 320 | "79": [ 321 | 39220, 322 | 169 323 | ], 324 | "80": [ 325 | 39589, 326 | 179 327 | ], 328 | "81": [ 329 | 39954, 330 | 183 331 | ], 332 | "82": [ 333 | 34215, 334 | 180 335 | ], 336 | "83": [ 337 | 34704, 338 | 159 339 | ], 340 | "87": [ 341 | 6054, 342 | 180 343 | ], 344 | "88": [ 345 | 6425, 346 | 182 347 | ], 348 | "3612": [ 349 | 28558, 350 | 161 351 | ], 352 | "3613": [ 353 | 38821, 354 | 188 355 | ], 356 | "3637": [ 357 | 7187, 358 | 183 359 | ], 360 | "3639": [ 361 | 6818, 362 | 167 363 | ], 364 | "3640": [ 365 | 37730, 366 | 184 367 | ], 368 | "3653": [ 369 | 7583, 370 | 193 371 | ], 372 | "3655": [ 373 | 15526, 374 | 204 375 | ], 376 | "3657": [ 377 | 15893, 378 | 157 379 | ], 380 | "3663": [ 381 | 22513, 382 | 173 383 | ], 384 | "3665": [ 385 | 22862, 386 | 158 387 | ], 388 | "3666": [ 389 | 15156, 390 | 180 391 | ], 392 | "3667": [ 393 | 22116, 394 | 179 395 | ], 396 | "3675": [ 397 | 36115, 398 | 205 399 | ], 400 | "3676": [ 401 | 38116, 402 | 184 403 | ], 404 | "3677": [ 405 | 38821, 406 | 188 407 | ], 408 | "57416": [ 409 | 34704, 410 | 159 411 | ], 412 | "57419": [ 413 | 39220, 414 | 169 415 | ], 416 | "57421": [ 417 | 39954, 418 | 183 419 | ], 420 | "57424": [ 421 | 39589, 422 | 179 423 | ], 424 | "60999": [ 425 | 15526, 426 | 204 427 | ], 428 | "61000": [ 429 | 34704, 430 | 159 431 | ], 432 | "61001": [ 433 | 15893, 434 | 157 435 | ], 436 | "61003": [ 437 | 39220, 438 | 169 439 | ], 440 | "61005": [ 441 | 39954, 442 | 183 443 | ], 444 | "61007": [ 445 | 22513, 446 | 173 447 | ], 448 | "61008": [ 449 | 39589, 450 | 179 451 | ], 452 | "61009": [ 453 | 22862, 454 | 158 455 | ], 456 | "61010": [ 457 | 15156, 458 | 180 459 | ], 460 | "61011": [ 461 | 22116, 462 | 179 463 | ] 464 | } 465 | } -------------------------------------------------------------------------------- /src/sounds/keys/cherrymx-blue-pbt/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "custom-sound-pack-1582707445334", 3 | "name": "CherryMX Blue - PBT keycaps", 4 | "key_define_type": "single", 5 | "includes_numpad": false, 6 | "sound": "sound.ogg", 7 | "defines": { 8 | "1": [ 9 | 1203, 10 | 192 11 | ], 12 | "2": [ 13 | 10794, 14 | 197 15 | ], 16 | "3": [ 17 | 11315, 18 | 196 19 | ], 20 | "4": [ 21 | 11814, 22 | 198 23 | ], 24 | "5": [ 25 | 12334, 26 | 185 27 | ], 28 | "6": [ 29 | 12845, 30 | 196 31 | ], 32 | "7": [ 33 | 13305, 34 | 188 35 | ], 36 | "8": [ 37 | 13846, 38 | 187 39 | ], 40 | "9": [ 41 | 14362, 42 | 197 43 | ], 44 | "10": [ 45 | 14881, 46 | 188 47 | ], 48 | "11": [ 49 | 15408, 50 | 180 51 | ], 52 | "12": [ 53 | 15901, 54 | 200 55 | ], 56 | "13": [ 57 | 16410, 58 | 182 59 | ], 60 | "14": [ 61 | 16906, 62 | 230 63 | ], 64 | "15": [ 65 | 19473, 66 | 191 67 | ], 68 | "16": [ 69 | 19944, 70 | 207 71 | ], 72 | "17": [ 73 | 20490, 74 | 183 75 | ], 76 | "18": [ 77 | 20995, 78 | 192 79 | ], 80 | "19": [ 81 | 21500, 82 | 186 83 | ], 84 | "20": [ 85 | 21993, 86 | 198 87 | ], 88 | "21": [ 89 | 22495, 90 | 185 91 | ], 92 | "22": [ 93 | 22970, 94 | 194 95 | ], 96 | "23": [ 97 | 23492, 98 | 179 99 | ], 100 | "24": [ 101 | 23972, 102 | 212 103 | ], 104 | "25": [ 105 | 24468, 106 | 181 107 | ], 108 | "26": [ 109 | 24955, 110 | 187 111 | ], 112 | "27": [ 113 | 25463, 114 | 172 115 | ], 116 | "28": [ 117 | 34274, 118 | 204 119 | ], 120 | "29": [ 121 | 42603, 122 | 172 123 | ], 124 | "30": [ 125 | 28961, 126 | 164 127 | ], 128 | "31": [ 129 | 29448, 130 | 171 131 | ], 132 | "32": [ 133 | 29968, 134 | 163 135 | ], 136 | "33": [ 137 | 30454, 138 | 208 139 | ], 140 | "34": [ 141 | 30944, 142 | 172 143 | ], 144 | "35": [ 145 | 31395, 146 | 186 147 | ], 148 | "36": [ 149 | 31884, 150 | 174 151 | ], 152 | "37": [ 153 | 32358, 154 | 172 155 | ], 156 | "38": [ 157 | 32358, 158 | 172 159 | ], 160 | "39": [ 161 | 33331, 162 | 191 163 | ], 164 | "40": [ 165 | 33824, 166 | 166 167 | ], 168 | "41": [ 169 | 10318, 170 | 183 171 | ], 172 | "42": [ 173 | 35598, 174 | 197 175 | ], 176 | "43": [ 177 | 25952, 178 | 184 179 | ], 180 | "44": [ 181 | 36143, 182 | 204 183 | ], 184 | "45": [ 185 | 36645, 186 | 165 187 | ], 188 | "46": [ 189 | 37120, 190 | 164 191 | ], 192 | "47": [ 193 | 37606, 194 | 181 195 | ], 196 | "48": [ 197 | 38062, 198 | 179 199 | ], 200 | "49": [ 201 | 38563, 202 | 163 203 | ], 204 | "50": [ 205 | 39025, 206 | 171 207 | ], 208 | "51": [ 209 | 39505, 210 | 172 211 | ], 212 | "52": [ 213 | 39982, 214 | 152 215 | ], 216 | "53": [ 217 | 40437, 218 | 170 219 | ], 220 | "54": [ 221 | 40939, 222 | 176 223 | ], 224 | "55": [ 225 | 9180, 226 | 193 227 | ], 228 | "56": [ 229 | 43991, 230 | 192 231 | ], 232 | "57": [ 233 | 49628, 234 | 230 235 | ], 236 | "58": [ 237 | 28470, 238 | 191 239 | ], 240 | "59": [ 241 | 1783, 242 | 185 243 | ], 244 | "60": [ 245 | 2336, 246 | 204 247 | ], 248 | "61": [ 249 | 2884, 250 | 182 251 | ], 252 | "62": [ 253 | 3404, 254 | 188 255 | ], 256 | "63": [ 257 | 3940, 258 | 168 259 | ], 260 | "64": [ 261 | 4487, 262 | 165 263 | ], 264 | "65": [ 265 | 5013, 266 | 178 267 | ], 268 | "66": [ 269 | 5510, 270 | 187 271 | ], 272 | "67": [ 273 | 6048, 274 | 207 275 | ], 276 | "68": [ 277 | 6609, 278 | 174 279 | ], 280 | "69": [ 281 | 8159, 282 | 221 283 | ], 284 | "70": [ 285 | 8668, 286 | 222 287 | ], 288 | "71": [ 289 | 17483, 290 | 175 291 | ], 292 | "72": [ 293 | 17955, 294 | 189 295 | ], 296 | "73": [ 297 | 18419, 298 | 199 299 | ], 300 | "74": [ 301 | 15901, 302 | 200 303 | ], 304 | "75": [ 305 | 26567, 306 | 177 307 | ], 308 | "76": [ 309 | 27069, 310 | 190 311 | ], 312 | "77": [ 313 | 27541, 314 | 169 315 | ], 316 | "78": [ 317 | 16906, 318 | 230 319 | ], 320 | "79": [ 321 | 47492, 322 | 178 323 | ], 324 | "80": [ 325 | 47981, 326 | 201 327 | ], 328 | "81": [ 329 | 48412, 330 | 201 331 | ], 332 | "82": [ 333 | 40939, 334 | 176 335 | ], 336 | "83": [ 337 | 41501, 338 | 174 339 | ], 340 | "87": [ 341 | 7119, 342 | 175 343 | ], 344 | "88": [ 345 | 7650, 346 | 174 347 | ], 348 | "3612": [ 349 | 34274, 350 | 204 351 | ], 352 | "3613": [ 353 | 47002, 354 | 188 355 | ], 356 | "3637": [ 357 | 8668, 358 | 222 359 | ], 360 | "3639": [ 361 | 8159, 362 | 221 363 | ], 364 | "3640": [ 365 | 46069, 366 | 202 367 | ], 368 | "3653": [ 369 | 9180, 370 | 193 371 | ], 372 | "3655": [ 373 | 17955, 374 | 189 375 | ], 376 | "3657": [ 377 | 18419, 378 | 199 379 | ], 380 | "3663": [ 381 | 27069, 382 | 190 383 | ], 384 | "3665": [ 385 | 27541, 386 | 169 387 | ], 388 | "3666": [ 389 | 17483, 390 | 175 391 | ], 392 | "3667": [ 393 | 26567, 394 | 177 395 | ], 396 | "3675": [ 397 | 43435, 398 | 155 399 | ], 400 | "3676": [ 401 | 46544, 402 | 174 403 | ], 404 | "3677": [ 405 | 47002, 406 | 188 407 | ], 408 | "57416": [ 409 | 41501, 410 | 174 411 | ], 412 | "57419": [ 413 | 47492, 414 | 178 415 | ], 416 | "57421": [ 417 | 48412, 418 | 201 419 | ], 420 | "57424": [ 421 | 47981, 422 | 201 423 | ], 424 | "60999": [ 425 | 17955, 426 | 189 427 | ], 428 | "61000": [ 429 | 41501, 430 | 174 431 | ], 432 | "61001": [ 433 | 18419, 434 | 199 435 | ], 436 | "61003": [ 437 | 47492, 438 | 178 439 | ], 440 | "61005": [ 441 | 48412, 442 | 201 443 | ], 444 | "61007": [ 445 | 27069, 446 | 190 447 | ], 448 | "61008": [ 449 | 47981, 450 | 201 451 | ], 452 | "61009": [ 453 | 27541, 454 | 169 455 | ], 456 | "61010": [ 457 | 17483, 458 | 175 459 | ], 460 | "61011": [ 461 | 26567, 462 | 177 463 | ] 464 | } 465 | } -------------------------------------------------------------------------------- /src/sounds/keys/cherrymx-brown-pbt/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "custom-sound-pack-1582656695035", 3 | "name": "CherryMX Brown - PBT keycaps", 4 | "key_define_type": "single", 5 | "includes_numpad": false, 6 | "sound": "sound.ogg", 7 | "defines": { 8 | "1": [ 9 | 2280, 10 | 199 11 | ], 12 | "2": [ 13 | 9444, 14 | 185 15 | ], 16 | "3": [ 17 | 9833, 18 | 187 19 | ], 20 | "4": [ 21 | 10185, 22 | 194 23 | ], 24 | "5": [ 25 | 10551, 26 | 196 27 | ], 28 | "6": [ 29 | 10899, 30 | 194 31 | ], 32 | "7": [ 33 | 11282, 34 | 180 35 | ], 36 | "8": [ 37 | 11623, 38 | 188 39 | ], 40 | "9": [ 41 | 11976, 42 | 200 43 | ], 44 | "10": [ 45 | 12337, 46 | 197 47 | ], 48 | "11": [ 49 | 12667, 50 | 194 51 | ], 52 | "12": [ 53 | 13058, 54 | 191 55 | ], 56 | "13": [ 57 | 13408, 58 | 187 59 | ], 60 | "14": [ 61 | 13765, 62 | 184 63 | ], 64 | "15": [ 65 | 15916, 66 | 176 67 | ], 68 | "16": [ 69 | 16284, 70 | 150 71 | ], 72 | "17": [ 73 | 16637, 74 | 176 75 | ], 76 | "18": [ 77 | 16964, 78 | 190 79 | ], 80 | "19": [ 81 | 17275, 82 | 185 83 | ], 84 | "20": [ 85 | 17613, 86 | 196 87 | ], 88 | "21": [ 89 | 17957, 90 | 173 91 | ], 92 | "22": [ 93 | 18301, 94 | 190 95 | ], 96 | "23": [ 97 | 18643, 98 | 200 99 | ], 100 | "24": [ 101 | 18994, 102 | 178 103 | ], 104 | "25": [ 105 | 19331, 106 | 197 107 | ], 108 | "26": [ 109 | 19671, 110 | 171 111 | ], 112 | "27": [ 113 | 20020, 114 | 175 115 | ], 116 | "28": [ 117 | 26703, 118 | 181 119 | ], 120 | "29": [ 121 | 33857, 122 | 182 123 | ], 124 | "30": [ 125 | 22869, 126 | 198 127 | ], 128 | "31": [ 129 | 23237, 130 | 178 131 | ], 132 | "32": [ 133 | 23586, 134 | 187 135 | ], 136 | "33": [ 137 | 23898, 138 | 179 139 | ], 140 | "34": [ 141 | 24237, 142 | 185 143 | ], 144 | "35": [ 145 | 24550, 146 | 192 147 | ], 148 | "36": [ 149 | 24917, 150 | 188 151 | ], 152 | "37": [ 153 | 25274, 154 | 185 155 | ], 156 | "38": [ 157 | 25625, 158 | 183 159 | ], 160 | "39": [ 161 | 25989, 162 | 182 163 | ], 164 | "40": [ 165 | 26335, 166 | 180 167 | ], 168 | "41": [ 169 | 9069, 170 | 209 171 | ], 172 | "42": [ 173 | 28109, 174 | 180 175 | ], 176 | "43": [ 177 | 20387, 178 | 176 179 | ], 180 | "44": [ 181 | 28550, 182 | 167 183 | ], 184 | "45": [ 185 | 28855, 186 | 184 187 | ], 188 | "46": [ 189 | 29557, 190 | 204 191 | ], 192 | "47": [ 193 | 29557, 194 | 204 195 | ], 196 | "48": [ 197 | 29909, 198 | 179 199 | ], 200 | "49": [ 201 | 30252, 202 | 203 203 | ], 204 | "50": [ 205 | 30605, 206 | 184 207 | ], 208 | "51": [ 209 | 30965, 210 | 212 211 | ], 212 | "52": [ 213 | 31315, 214 | 176 215 | ], 216 | "53": [ 217 | 31659, 218 | 175 219 | ], 220 | "54": [ 221 | 32015, 222 | 184 223 | ], 224 | "55": [ 225 | 8036, 226 | 168 227 | ], 228 | "56": [ 229 | 34551, 230 | 175 231 | ], 232 | "57": [ 233 | 34910, 234 | 223 235 | ], 236 | "58": [ 237 | 22560, 238 | 181 239 | ], 240 | "59": [ 241 | 2754, 242 | 189 243 | ], 244 | "60": [ 245 | 3155, 246 | 180 247 | ], 248 | "61": [ 249 | 3545, 250 | 187 251 | ], 252 | "62": [ 253 | 3913, 254 | 183 255 | ], 256 | "63": [ 257 | 4305, 258 | 174 259 | ], 260 | "64": [ 261 | 4666, 262 | 187 263 | ], 264 | "65": [ 265 | 5034, 266 | 200 267 | ], 268 | "66": [ 269 | 5433, 270 | 187 271 | ], 272 | "67": [ 273 | 7795, 274 | 198 275 | ], 276 | "68": [ 277 | 6146, 278 | 191 279 | ], 280 | "69": [ 281 | 7322, 282 | 177 283 | ], 284 | "70": [ 285 | 7699, 286 | 178 287 | ], 288 | "71": [ 289 | 14199, 290 | 181 291 | ], 292 | "72": [ 293 | 14522, 294 | 196 295 | ], 296 | "73": [ 297 | 14852, 298 | 169 299 | ], 300 | "74": [ 301 | 13058, 302 | 191 303 | ], 304 | "75": [ 305 | 20766, 306 | 185 307 | ], 308 | "76": [ 309 | 21102, 310 | 187 311 | ], 312 | "77": [ 313 | 21409, 314 | 151 315 | ], 316 | "78": [ 317 | 13765, 318 | 184 319 | ], 320 | "79": [ 321 | 36907, 322 | 163 323 | ], 324 | "80": [ 325 | 37267, 326 | 170 327 | ], 328 | "81": [ 329 | 37586, 330 | 160 331 | ], 332 | "82": [ 333 | 32015, 334 | 184 335 | ], 336 | "83": [ 337 | 32429, 338 | 174 339 | ], 340 | "87": [ 341 | 6560, 342 | 196 343 | ], 344 | "88": [ 345 | 6932, 346 | 193 347 | ], 348 | "3612": [ 349 | 26703, 350 | 181 351 | ], 352 | "3613": [ 353 | 36571, 354 | 182 355 | ], 356 | "3637": [ 357 | 7699, 358 | 178 359 | ], 360 | "3639": [ 361 | 7322, 362 | 177 363 | ], 364 | "3640": [ 365 | 35492, 366 | 157 367 | ], 368 | "3653": [ 369 | 8036, 370 | 168 371 | ], 372 | "3655": [ 373 | 14522, 374 | 196 375 | ], 376 | "3657": [ 377 | 14852, 378 | 169 379 | ], 380 | "3663": [ 381 | 21102, 382 | 187 383 | ], 384 | "3665": [ 385 | 21409, 386 | 151 387 | ], 388 | "3666": [ 389 | 14199, 390 | 181 391 | ], 392 | "3667": [ 393 | 20766, 394 | 185 395 | ], 396 | "3675": [ 397 | 34181, 398 | 177 399 | ], 400 | "3676": [ 401 | 35878, 402 | 164 403 | ], 404 | "3677": [ 405 | 36571, 406 | 182 407 | ], 408 | "57416": [ 409 | 32429, 410 | 174 411 | ], 412 | "57419": [ 413 | 36907, 414 | 163 415 | ], 416 | "57421": [ 417 | 37586, 418 | 160 419 | ], 420 | "57424": [ 421 | 37267, 422 | 170 423 | ], 424 | "60999": [ 425 | 14522, 426 | 196 427 | ], 428 | "61000": [ 429 | 32429, 430 | 174 431 | ], 432 | "61001": [ 433 | 14852, 434 | 169 435 | ], 436 | "61003": [ 437 | 36907, 438 | 163 439 | ], 440 | "61005": [ 441 | 37586, 442 | 160 443 | ], 444 | "61007": [ 445 | 21102, 446 | 187 447 | ], 448 | "61008": [ 449 | 37267, 450 | 170 451 | ], 452 | "61009": [ 453 | 21409, 454 | 151 455 | ], 456 | "61010": [ 457 | 14199, 458 | 181 459 | ], 460 | "61011": [ 461 | 20766, 462 | 185 463 | ] 464 | } 465 | } -------------------------------------------------------------------------------- /src/sounds/keys/cherrymx-red-pbt/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "custom-sound-pack-1582707445334", 3 | "name": "CherryMX Red - PBT keycaps", 4 | "key_define_type": "single", 5 | "includes_numpad": false, 6 | "sound": "sound.ogg", 7 | "defines": { 8 | "1": [ 9 | 3339, 10 | 187 11 | ], 12 | "2": [ 13 | 11673, 14 | 137 15 | ], 16 | "3": [ 17 | 12175, 18 | 143 19 | ], 20 | "4": [ 21 | 12601, 22 | 185 23 | ], 24 | "5": [ 25 | 13056, 26 | 152 27 | ], 28 | "6": [ 29 | 13512, 30 | 150 31 | ], 32 | "7": [ 33 | 13919, 34 | 160 35 | ], 36 | "8": [ 37 | 14411, 38 | 147 39 | ], 40 | "9": [ 41 | 14853, 42 | 182 43 | ], 44 | "10": [ 45 | 15330, 46 | 162 47 | ], 48 | "11": [ 49 | 15771, 50 | 182 51 | ], 52 | "12": [ 53 | 16215, 54 | 158 55 | ], 56 | "13": [ 57 | 16662, 58 | 170 59 | ], 60 | "14": [ 61 | 17067, 62 | 207 63 | ], 64 | "15": [ 65 | 19327, 66 | 196 67 | ], 68 | "16": [ 69 | 19717, 70 | 153 71 | ], 72 | "17": [ 73 | 20144, 74 | 159 75 | ], 76 | "18": [ 77 | 20556, 78 | 150 79 | ], 80 | "19": [ 81 | 20966, 82 | 158 83 | ], 84 | "20": [ 85 | 21371, 86 | 193 87 | ], 88 | "21": [ 89 | 21836, 90 | 186 91 | ], 92 | "22": [ 93 | 22303, 94 | 163 95 | ], 96 | "23": [ 97 | 22724, 98 | 198 99 | ], 100 | "24": [ 101 | 23198, 102 | 170 103 | ], 104 | "25": [ 105 | 23643, 106 | 168 107 | ], 108 | "26": [ 109 | 24072, 110 | 179 111 | ], 112 | "27": [ 113 | 24527, 114 | 175 115 | ], 116 | "28": [ 117 | 32734, 118 | 230 119 | ], 120 | "29": [ 121 | 40191, 122 | 178 123 | ], 124 | "30": [ 125 | 27803, 126 | 158 127 | ], 128 | "31": [ 129 | 28294, 130 | 151 131 | ], 132 | "32": [ 133 | 28716, 134 | 178 135 | ], 136 | "33": [ 137 | 29158, 138 | 182 139 | ], 140 | "34": [ 141 | 29563, 142 | 156 143 | ], 144 | "35": [ 145 | 30053, 146 | 155 147 | ], 148 | "36": [ 149 | 30477, 150 | 148 151 | ], 152 | "37": [ 153 | 30945, 154 | 155 155 | ], 156 | "38": [ 157 | 31372, 158 | 172 159 | ], 160 | "39": [ 161 | 31812, 162 | 188 163 | ], 164 | "40": [ 165 | 32290, 166 | 200 167 | ], 168 | "41": [ 169 | 11265, 170 | 179 171 | ], 172 | "42": [ 173 | 33773, 174 | 225 175 | ], 176 | "43": [ 177 | 24965, 178 | 196 179 | ], 180 | "44": [ 181 | 34211, 182 | 139 183 | ], 184 | "45": [ 185 | 34623, 186 | 154 187 | ], 188 | "46": [ 189 | 34981, 190 | 174 191 | ], 192 | "47": [ 193 | 35448, 194 | 156 195 | ], 196 | "48": [ 197 | 35870, 198 | 188 199 | ], 200 | "49": [ 201 | 36310, 202 | 170 203 | ], 204 | "50": [ 205 | 36715, 206 | 188 207 | ], 208 | "51": [ 209 | 37150, 210 | 165 211 | ], 212 | "52": [ 213 | 37577, 214 | 177 215 | ], 216 | "53": [ 217 | 38025, 218 | 173 219 | ], 220 | "54": [ 221 | 38477, 222 | 180 223 | ], 224 | "55": [ 225 | 10319, 226 | 214 227 | ], 228 | "56": [ 229 | 40985, 230 | 175 231 | ], 232 | "57": [ 233 | 47621, 234 | 300 235 | ], 236 | "58": [ 237 | 27372, 238 | 190 239 | ], 240 | "59": [ 241 | 3878, 242 | 151 243 | ], 244 | "60": [ 245 | 4347, 246 | 169 247 | ], 248 | "61": [ 249 | 4825, 250 | 166 251 | ], 252 | "62": [ 253 | 5272, 254 | 151 255 | ], 256 | "63": [ 257 | 5737, 258 | 157 259 | ], 260 | "64": [ 261 | 6174, 262 | 1194 263 | ], 264 | "65": [ 265 | 6635, 266 | 198 267 | ], 268 | "66": [ 269 | 7088, 270 | 186 271 | ], 272 | "67": [ 273 | 7578, 274 | 195 275 | ], 276 | "68": [ 277 | 7989, 278 | 222 279 | ], 280 | "69": [ 281 | 9455, 282 | 168 283 | ], 284 | "70": [ 285 | 9935, 286 | 145 287 | ], 288 | "71": [ 289 | 17568, 290 | 158 291 | ], 292 | "72": [ 293 | 18000, 294 | 195 295 | ], 296 | "73": [ 297 | 18413, 298 | 166 299 | ], 300 | "74": [ 301 | 16215, 302 | 158 303 | ], 304 | "75": [ 305 | 25461, 306 | 177 307 | ], 308 | "76": [ 309 | 25888, 310 | 193 311 | ], 312 | "77": [ 313 | 26353, 314 | 210 315 | ], 316 | "78": [ 317 | 17067, 318 | 207 319 | ], 320 | "79": [ 321 | 44074, 322 | 175 323 | ], 324 | "80": [ 325 | 44511, 326 | 178 327 | ], 328 | "81": [ 329 | 44989, 330 | 179 331 | ], 332 | "82": [ 333 | 38477, 334 | 180 335 | ], 336 | "83": [ 337 | 39044, 338 | 186 339 | ], 340 | "87": [ 341 | 8467, 342 | 205 343 | ], 344 | "88": [ 345 | 8958, 346 | 190 347 | ], 348 | "3612": [ 349 | 32734, 350 | 230 351 | ], 352 | "3613": [ 353 | 43623, 354 | 175 355 | ], 356 | "3637": [ 357 | 9935, 358 | 145 359 | ], 360 | "3639": [ 361 | 9455, 362 | 168 363 | ], 364 | "3640": [ 365 | 42367, 366 | 194 367 | ], 368 | "3653": [ 369 | 10319, 370 | 214 371 | ], 372 | "3655": [ 373 | 18000, 374 | 195 375 | ], 376 | "3657": [ 377 | 18413, 378 | 166 379 | ], 380 | "3663": [ 381 | 25888, 382 | 193 383 | ], 384 | "3665": [ 385 | 26353, 386 | 210 387 | ], 388 | "3666": [ 389 | 17568, 390 | 158 391 | ], 392 | "3667": [ 393 | 25461, 394 | 177 395 | ], 396 | "3675": [ 397 | 40588, 398 | 184 399 | ], 400 | "3676": [ 401 | 43196, 402 | 203 403 | ], 404 | "3677": [ 405 | 43623, 406 | 175 407 | ], 408 | "57416": [ 409 | 39044, 410 | 186 411 | ], 412 | "57419": [ 413 | 44074, 414 | 175 415 | ], 416 | "57421": [ 417 | 44989, 418 | 179 419 | ], 420 | "57424": [ 421 | 44511, 422 | 178 423 | ], 424 | "60999": [ 425 | 18000, 426 | 195 427 | ], 428 | "61000": [ 429 | 39044, 430 | 186 431 | ], 432 | "61001": [ 433 | 18413, 434 | 166 435 | ], 436 | "61003": [ 437 | 44074, 438 | 175 439 | ], 440 | "61005": [ 441 | 44989, 442 | 179 443 | ], 444 | "61007": [ 445 | 25888, 446 | 193 447 | ], 448 | "61008": [ 449 | 44511, 450 | 178 451 | ], 452 | "61009": [ 453 | 26353, 454 | 210 455 | ], 456 | "61010": [ 457 | 17568, 458 | 158 459 | ], 460 | "61011": [ 461 | 25461, 462 | 177 463 | ] 464 | } 465 | } -------------------------------------------------------------------------------- /src/sounds/keys/cherrymx-black-abs/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "custom-sound-pack-1582654366773", 3 | "name": "CherryMX Black - ABS keycaps", 4 | "key_define_type": "single", 5 | "includes_numpad": false, 6 | "sound": "sound.ogg", 7 | "defines": { 8 | "1": [ 9 | 2894, 10 | 226 11 | ], 12 | "2": [ 13 | 12946, 14 | 191 15 | ], 16 | "3": [ 17 | 13470, 18 | 190 19 | ], 20 | "4": [ 21 | 13963, 22 | 199 23 | ], 24 | "5": [ 25 | 14481, 26 | 204 27 | ], 28 | "6": [ 29 | 14994, 30 | 187 31 | ], 32 | "7": [ 33 | 15505, 34 | 217 35 | ], 36 | "8": [ 37 | 15990, 38 | 193 39 | ], 40 | "9": [ 41 | 16529, 42 | 184 43 | ], 44 | "10": [ 45 | 17012, 46 | 205 47 | ], 48 | "11": [ 49 | 17550, 50 | 174 51 | ], 52 | "12": [ 53 | 18052, 54 | 186 55 | ], 56 | "13": [ 57 | 18553, 58 | 177 59 | ], 60 | "14": [ 61 | 19065, 62 | 220 63 | ], 64 | "15": [ 65 | 21734, 66 | 238 67 | ], 68 | "16": [ 69 | 22245, 70 | 190 71 | ], 72 | "17": [ 73 | 22790, 74 | 177 75 | ], 76 | "18": [ 77 | 23317, 78 | 166 79 | ], 80 | "19": [ 81 | 23817, 82 | 184 83 | ], 84 | "20": [ 85 | 24297, 86 | 183 87 | ], 88 | "21": [ 89 | 24811, 90 | 186 91 | ], 92 | "22": [ 93 | 25313, 94 | 189 95 | ], 96 | "23": [ 97 | 25795, 98 | 182 99 | ], 100 | "24": [ 101 | 26309, 102 | 167 103 | ], 104 | "25": [ 105 | 26804, 106 | 166 107 | ], 108 | "26": [ 109 | 27330, 110 | 169 111 | ], 112 | "27": [ 113 | 27883, 114 | 197 115 | ], 116 | "28": [ 117 | 36902, 118 | 234 119 | ], 120 | "29": [ 121 | 45327, 122 | 165 123 | ], 124 | "30": [ 125 | 31542, 126 | 170 127 | ], 128 | "31": [ 129 | 32031, 130 | 175 131 | ], 132 | "32": [ 133 | 32492, 134 | 169 135 | ], 136 | "33": [ 137 | 32973, 138 | 174 139 | ], 140 | "34": [ 141 | 33453, 142 | 188 143 | ], 144 | "35": [ 145 | 33986, 146 | 185 147 | ], 148 | "36": [ 149 | 34425, 150 | 176 151 | ], 152 | "37": [ 153 | 34932, 154 | 180 155 | ], 156 | "38": [ 157 | 35410, 158 | 190 159 | ], 160 | "39": [ 161 | 35914, 162 | 189 163 | ], 164 | "40": [ 165 | 36428, 166 | 173 167 | ], 168 | "41": [ 169 | 12476, 170 | 200 171 | ], 172 | "42": [ 173 | 38136, 174 | 265 175 | ], 176 | "43": [ 177 | 28393, 178 | 200 179 | ], 180 | "44": [ 181 | 38694, 182 | 160 183 | ], 184 | "45": [ 185 | 39148, 186 | 151 187 | ], 188 | "46": [ 189 | 39632, 190 | 190 191 | ], 192 | "47": [ 193 | 40136, 194 | 188 195 | ], 196 | "48": [ 197 | 40621, 198 | 214 199 | ], 200 | "49": [ 201 | 41103, 202 | 180 203 | ], 204 | "50": [ 205 | 41610, 206 | 186 207 | ], 208 | "51": [ 209 | 42110, 210 | 183 211 | ], 212 | "52": [ 213 | 42594, 214 | 180 215 | ], 216 | "53": [ 217 | 43105, 218 | 190 219 | ], 220 | "54": [ 221 | 43565, 222 | 273 223 | ], 224 | "55": [ 225 | 11270, 226 | 200 227 | ], 228 | "56": [ 229 | 45750, 230 | 164 231 | ], 232 | "57": [ 233 | 51541, 234 | 287 235 | ], 236 | "58": [ 237 | 31011, 238 | 251 239 | ], 240 | "59": [ 241 | 3610, 242 | 195 243 | ], 244 | "60": [ 245 | 4210, 246 | 180 247 | ], 248 | "61": [ 249 | 4758, 250 | 180 251 | ], 252 | "62": [ 253 | 5250, 254 | 199 255 | ], 256 | "63": [ 257 | 5831, 258 | 209 259 | ], 260 | "64": [ 261 | 6396, 262 | 210 263 | ], 264 | "65": [ 265 | 6900, 266 | 210 267 | ], 268 | "66": [ 269 | 7443, 270 | 221 271 | ], 272 | "67": [ 273 | 7955, 274 | 181 275 | ], 276 | "68": [ 277 | 8504, 278 | 209 279 | ], 280 | "69": [ 281 | 10132, 282 | 208 283 | ], 284 | "70": [ 285 | 10763, 286 | 160 287 | ], 288 | "71": [ 289 | 19634, 290 | 171 291 | ], 292 | "72": [ 293 | 20143, 294 | 202 295 | ], 296 | "73": [ 297 | 20647, 298 | 193 299 | ], 300 | "74": [ 301 | 18052, 302 | 186 303 | ], 304 | "75": [ 305 | 28914, 306 | 212 307 | ], 308 | "76": [ 309 | 29427, 310 | 177 311 | ], 312 | "77": [ 313 | 29928, 314 | 190 315 | ], 316 | "78": [ 317 | 19065, 318 | 220 319 | ], 320 | "79": [ 321 | 49837, 322 | 176 323 | ], 324 | "80": [ 325 | 50333, 326 | 179 327 | ], 328 | "81": [ 329 | 50783, 330 | 221 331 | ], 332 | "82": [ 333 | 43565, 334 | 273 335 | ], 336 | "83": [ 337 | 44251, 338 | 220 339 | ], 340 | "87": [ 341 | 9046, 342 | 187 343 | ], 344 | "88": [ 345 | 9582, 346 | 191 347 | ], 348 | "3612": [ 349 | 36902, 350 | 234 351 | ], 352 | "3613": [ 353 | 49329, 354 | 164 355 | ], 356 | "3637": [ 357 | 10763, 358 | 160 359 | ], 360 | "3639": [ 361 | 10132, 362 | 208 363 | ], 364 | "3640": [ 365 | 48381, 366 | 168 367 | ], 368 | "3653": [ 369 | 11270, 370 | 200 371 | ], 372 | "3655": [ 373 | 20143, 374 | 202 375 | ], 376 | "3657": [ 377 | 20647, 378 | 193 379 | ], 380 | "3663": [ 381 | 29427, 382 | 177 383 | ], 384 | "3665": [ 385 | 29928, 386 | 190 387 | ], 388 | "3666": [ 389 | 19634, 390 | 171 391 | ], 392 | "3667": [ 393 | 28914, 394 | 212 395 | ], 396 | "3675": [ 397 | 46199, 398 | 199 399 | ], 400 | "3676": [ 401 | 47929, 402 | 149 403 | ], 404 | "3677": [ 405 | 49329, 406 | 164 407 | ], 408 | "57416": [ 409 | 44251, 410 | 220 411 | ], 412 | "57419": [ 413 | 49837, 414 | 176 415 | ], 416 | "57421": [ 417 | 50783, 418 | 221 419 | ], 420 | "57424": [ 421 | 50333, 422 | 179 423 | ], 424 | "60999": [ 425 | 20143, 426 | 202 427 | ], 428 | "61000": [ 429 | 44251, 430 | 220 431 | ], 432 | "61001": [ 433 | 20647, 434 | 193 435 | ], 436 | "61003": [ 437 | 49837, 438 | 176 439 | ], 440 | "61005": [ 441 | 50783, 442 | 221 443 | ], 444 | "61007": [ 445 | 29427, 446 | 177 447 | ], 448 | "61008": [ 449 | 50333, 450 | 179 451 | ], 452 | "61009": [ 453 | 29928, 454 | 190 455 | ], 456 | "61010": [ 457 | 19634, 458 | 171 459 | ], 460 | "61011": [ 461 | 28914, 462 | 212 463 | ] 464 | } 465 | } -------------------------------------------------------------------------------- /src/sounds/keys/eg-oreo/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "custom-sound-pack-1605532336205", 3 | "name": "EG Oreo", 4 | "key_define_type": "single", 5 | "includes_numpad": false, 6 | "sound": "oreo.ogg", 7 | "defines": { 8 | "1": [ 9 | 971, 10 | 142 11 | ], 12 | "2": [ 13 | 1276, 14 | 115 15 | ], 16 | "3": [ 17 | 1604, 18 | 122 19 | ], 20 | "4": [ 21 | 1929, 22 | 122 23 | ], 24 | "5": [ 25 | 2237, 26 | 134 27 | ], 28 | "6": [ 29 | 2571, 30 | 120 31 | ], 32 | "7": [ 33 | 2869, 34 | 122 35 | ], 36 | "8": [ 37 | 3177, 38 | 130 39 | ], 40 | "9": [ 41 | 3482, 42 | 110 43 | ], 44 | "10": [ 45 | 3782, 46 | 121 47 | ], 48 | "11": [ 49 | 4077, 50 | 128 51 | ], 52 | "12": [ 53 | 4376, 54 | 120 55 | ], 56 | "13": [ 57 | 4673, 58 | 123 59 | ], 60 | "14": [ 61 | 4991, 62 | 131 63 | ], 64 | "15": [ 65 | 5968, 66 | 123 67 | ], 68 | "16": [ 69 | 6221, 70 | 114 71 | ], 72 | "17": [ 73 | 6515, 74 | 120 75 | ], 76 | "18": [ 77 | 6823, 78 | 113 79 | ], 80 | "19": [ 81 | 7112, 82 | 110 83 | ], 84 | "20": [ 85 | 7412, 86 | 107 87 | ], 88 | "21": [ 89 | 7716, 90 | 112 91 | ], 92 | "22": [ 93 | 8012, 94 | 118 95 | ], 96 | "23": [ 97 | 8326, 98 | 112 99 | ], 100 | "24": [ 101 | 8623, 102 | 111 103 | ], 104 | "25": [ 105 | 8932, 106 | 112 107 | ], 108 | "26": [ 109 | 9246, 110 | 117 111 | ], 112 | "27": [ 113 | 9586, 114 | 118 115 | ], 116 | "28": [ 117 | 14603, 118 | 116 119 | ], 120 | "29": [ 121 | 20804, 122 | 118 123 | ], 124 | "30": [ 125 | 11171, 126 | 109 127 | ], 128 | "31": [ 129 | 11462, 130 | 120 131 | ], 132 | "32": [ 133 | 11784, 134 | 106 135 | ], 136 | "33": [ 137 | 12080, 138 | 104 139 | ], 140 | "34": [ 141 | 12400, 142 | 117 143 | ], 144 | "35": [ 145 | 12715, 146 | 110 147 | ], 148 | "36": [ 149 | 13014, 150 | 109 151 | ], 152 | "37": [ 153 | 13333, 154 | 116 155 | ], 156 | "38": [ 157 | 13638, 158 | 113 159 | ], 160 | "39": [ 161 | 13967, 162 | 106 163 | ], 164 | "40": [ 165 | 14280, 166 | 101 167 | ], 168 | "41": [ 169 | 972, 170 | 131 171 | ], 172 | "42": [ 173 | 15759, 174 | 123 175 | ], 176 | "43": [ 177 | 9915, 178 | 121 179 | ], 180 | "44": [ 181 | 16203, 182 | 127 183 | ], 184 | "45": [ 185 | 16533, 186 | 117 187 | ], 188 | "46": [ 189 | 16843, 190 | 111 191 | ], 192 | "47": [ 193 | 17166, 194 | 103 195 | ], 196 | "48": [ 197 | 17455, 198 | 109 199 | ], 200 | "49": [ 201 | 17767, 202 | 108 203 | ], 204 | "50": [ 205 | 18088, 206 | 104 207 | ], 208 | "51": [ 209 | 18402, 210 | 104 211 | ], 212 | "52": [ 213 | 18720, 214 | 110 215 | ], 216 | "53": [ 217 | 19044, 218 | 108 219 | ], 220 | "54": [ 221 | 19375, 222 | 124 223 | ], 224 | "55": [ 225 | 6822, 226 | 116 227 | ], 228 | "56": [ 229 | 21399, 230 | 119 231 | ], 232 | "57": [ 233 | 24626, 234 | 143 235 | ], 236 | "58": [ 237 | 10885, 238 | 126 239 | ], 240 | "59": [ 241 | 1272, 242 | 126 243 | ], 244 | "60": [ 245 | 1603, 246 | 125 247 | ], 248 | "61": [ 249 | 1924, 250 | 128 251 | ], 252 | "62": [ 253 | 2240, 254 | 126 255 | ], 256 | "63": [ 257 | 2566, 258 | 126 259 | ], 260 | "64": [ 261 | 2869, 262 | 122 263 | ], 264 | "65": [ 265 | 3179, 266 | 131 267 | ], 268 | "66": [ 269 | 3480, 270 | 115 271 | ], 272 | "67": [ 273 | 3782, 274 | 124 275 | ], 276 | "68": [ 277 | 4076, 278 | 126 279 | ], 280 | "69": [ 281 | 6216, 282 | 122 283 | ], 284 | "70": [ 285 | 12080, 286 | 103 287 | ], 288 | "71": [ 289 | 8322, 290 | 117 291 | ], 292 | "72": [ 293 | 8620, 294 | 113 295 | ], 296 | "73": [ 297 | 8931, 298 | 114 299 | ], 300 | "74": [ 301 | 7114, 302 | 109 303 | ], 304 | "75": [ 305 | 9242, 306 | 122 307 | ], 308 | "76": [ 309 | 9580, 310 | 131 311 | ], 312 | "77": [ 313 | 9913, 314 | 118 315 | ], 316 | "78": [ 317 | 7409, 318 | 117 319 | ], 320 | "79": [ 321 | 10228, 322 | 118 323 | ], 324 | "80": [ 325 | 11173, 326 | 110 327 | ], 328 | "81": [ 329 | 11463, 330 | 118 331 | ], 332 | "82": [ 333 | 8012, 334 | 115 335 | ], 336 | "83": [ 337 | 12079, 338 | 112 339 | ], 340 | "87": [ 341 | 4377, 342 | 120 343 | ], 344 | "88": [ 345 | 4988, 346 | 135 347 | ], 348 | "91": null, 349 | "92": null, 350 | "93": null, 351 | "3597": null, 352 | "3612": [ 353 | 7715, 354 | 112 355 | ], 356 | "3613": [ 357 | 23519, 358 | 127 359 | ], 360 | "3637": [ 361 | 6511, 362 | 126 363 | ], 364 | "3639": [ 365 | 11782, 366 | 110 367 | ], 368 | "3640": [ 369 | 22658, 370 | 126 371 | ], 372 | "3653": [ 373 | 12715, 374 | 106 375 | ], 376 | "3655": [ 377 | 13328, 378 | 126 379 | ], 380 | "3657": [ 381 | 13641, 382 | 107 383 | ], 384 | "3663": [ 385 | 14278, 386 | 104 387 | ], 388 | "3665": [ 389 | 14602, 390 | 120 391 | ], 392 | "3666": [ 393 | 13016, 394 | 108 395 | ], 396 | "3667": [ 397 | 13964, 398 | 113 399 | ], 400 | "3675": [ 401 | 21097, 402 | 129 403 | ], 404 | "3676": [ 405 | 22917, 406 | 129 407 | ], 408 | "3677": [ 409 | 23232, 410 | 126 411 | ], 412 | "57416": [ 413 | 19720, 414 | 122 415 | ], 416 | "57419": [ 417 | 23797, 418 | 119 419 | ], 420 | "57421": [ 421 | 22657, 422 | 129 423 | ], 424 | "57424": [ 425 | 24087, 426 | 119 427 | ], 428 | "60999": [ 429 | 13328, 430 | 126 431 | ], 432 | "61000": [ 433 | 19720, 434 | 122 435 | ], 436 | "61001": [ 437 | 13641, 438 | 107 439 | ], 440 | "61003": [ 441 | 23797, 442 | 119 443 | ], 444 | "61005": [ 445 | 22657, 446 | 129 447 | ], 448 | "61007": [ 449 | 14278, 450 | 104 451 | ], 452 | "61008": [ 453 | 24087, 454 | 119 455 | ], 456 | "61009": [ 457 | 14602, 458 | 120 459 | ], 460 | "61010": [ 461 | 13016, 462 | 108 463 | ], 464 | "61011": [ 465 | 13964, 466 | 113 467 | ] 468 | } 469 | } -------------------------------------------------------------------------------- /src/sounds/keys/topre-purple-hybrid-pbt/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "custom-sound-pack-1582707445334", 3 | "name": "Topre Purple Hybrid - PBT keycaps", 4 | "key_define_type": "single", 5 | "includes_numpad": false, 6 | "sound": "sound.ogg", 7 | "defines": { 8 | "1": [ 9 | 1813, 10 | 130 11 | ], 12 | "2": [ 13 | 20987, 14 | 180 15 | ], 16 | "3": [ 17 | 22041, 18 | 183 19 | ], 20 | "4": [ 21 | 23126, 22 | 194 23 | ], 24 | "5": [ 25 | 24260, 26 | 191 27 | ], 28 | "6": [ 29 | 25371, 30 | 185 31 | ], 32 | "7": [ 33 | 26392, 34 | 189 35 | ], 36 | "8": [ 37 | 27457, 38 | 180 39 | ], 40 | "9": [ 41 | 28502, 42 | 175 43 | ], 44 | "10": [ 45 | 29566, 46 | 192 47 | ], 48 | "11": [ 49 | 30619, 50 | 200 51 | ], 52 | "12": [ 53 | 31656, 54 | 191 55 | ], 56 | "13": [ 57 | 31712, 58 | 191 59 | ], 60 | "14": [ 61 | 33746, 62 | 190 63 | ], 64 | "15": [ 65 | 37933, 66 | 184 67 | ], 68 | "16": [ 69 | 39000, 70 | 180 71 | ], 72 | "17": [ 73 | 39991, 74 | 188 75 | ], 76 | "18": [ 77 | 40955, 78 | 200 79 | ], 80 | "19": [ 81 | 41924, 82 | 190 83 | ], 84 | "20": [ 85 | 42918, 86 | 192 87 | ], 88 | "21": [ 89 | 43909, 90 | 180 91 | ], 92 | "22": [ 93 | 44822, 94 | 185 95 | ], 96 | "23": [ 97 | 45779, 98 | 194 99 | ], 100 | "24": [ 101 | 46763, 102 | 175 103 | ], 104 | "25": [ 105 | 47787, 106 | 200 107 | ], 108 | "26": [ 109 | 48805, 110 | 208 111 | ], 112 | "27": [ 113 | 49764, 114 | 171 115 | ], 116 | "28": [ 117 | 68501, 118 | 174 119 | ], 120 | "29": [ 121 | 84014, 122 | 174 123 | ], 124 | "30": [ 125 | 56440, 126 | 177 127 | ], 128 | "31": [ 129 | 57571, 130 | 198 131 | ], 132 | "32": [ 133 | 58641, 134 | 182 135 | ], 136 | "33": [ 137 | 59729, 138 | 182 139 | ], 140 | "34": [ 141 | 60765, 142 | 183 143 | ], 144 | "35": [ 145 | 61898, 146 | 171 147 | ], 148 | "36": [ 149 | 63008, 150 | 180 151 | ], 152 | "37": [ 153 | 64156, 154 | 168 155 | ], 156 | "38": [ 157 | 65199, 158 | 171 159 | ], 160 | "39": [ 161 | 66281, 162 | 167 163 | ], 164 | "40": [ 165 | 67418, 166 | 175 167 | ], 168 | "41": [ 169 | 19950, 170 | 190 171 | ], 172 | "42": [ 173 | 69592, 174 | 186 175 | ], 176 | "43": [ 177 | 50707, 178 | 183 179 | ], 180 | "44": [ 181 | 70895, 182 | 174 183 | ], 184 | "45": [ 185 | 72019, 186 | 184 187 | ], 188 | "46": [ 189 | 73119, 190 | 192 191 | ], 192 | "47": [ 193 | 74276, 194 | 198 195 | ], 196 | "48": [ 197 | 75328, 198 | 193 199 | ], 200 | "49": [ 201 | 76458, 202 | 170 203 | ], 204 | "50": [ 205 | 77514, 206 | 190 207 | ], 208 | "51": [ 209 | 78570, 210 | 180 211 | ], 212 | "52": [ 213 | 79601, 214 | 175 215 | ], 216 | "53": [ 217 | 80675, 218 | 160 219 | ], 220 | "54": [ 221 | 81734, 222 | 176 223 | ], 224 | "55": [ 225 | 18833, 226 | 200 227 | ], 228 | "56": [ 229 | 86211, 230 | 187 231 | ], 232 | "57": [ 233 | 87213, 234 | 181 235 | ], 236 | "58": [ 237 | 55235, 238 | 205 239 | ], 240 | "59": [ 241 | 3076, 242 | 149 243 | ], 244 | "60": [ 245 | 4300, 246 | 166 247 | ], 248 | "61": [ 249 | 5415, 250 | 168 251 | ], 252 | "62": [ 253 | 6581, 254 | 162 255 | ], 256 | "63": [ 257 | 7724, 258 | 184 259 | ], 260 | "64": [ 261 | 8860, 262 | 197 263 | ], 264 | "65": [ 265 | 9972, 266 | 195 267 | ], 268 | "66": [ 269 | 1119, 270 | 182 271 | ], 272 | "67": [ 273 | 12242, 274 | 178 275 | ], 276 | "68": [ 277 | 13401, 278 | 194 279 | ], 280 | "69": [ 281 | 16619, 282 | 166 283 | ], 284 | "70": [ 285 | 17743, 286 | 200 287 | ], 288 | "71": [ 289 | 34738, 290 | 166 291 | ], 292 | "72": [ 293 | 35728, 294 | 186 295 | ], 296 | "73": [ 297 | 36825, 298 | 175 299 | ], 300 | "74": [ 301 | 31656, 302 | 191 303 | ], 304 | "75": [ 305 | 51695, 306 | 200 307 | ], 308 | "76": [ 309 | 52666, 310 | 163 311 | ], 312 | "77": [ 313 | 53744, 314 | 192 315 | ], 316 | "78": [ 317 | 33746, 318 | 190 319 | ], 320 | "79": [ 321 | 92565, 322 | 173 323 | ], 324 | "80": [ 325 | 93711, 326 | 174 327 | ], 328 | "81": [ 329 | 93739, 330 | 195 331 | ], 332 | "82": [ 333 | 81734, 334 | 176 335 | ], 336 | "83": [ 337 | 82838, 338 | 211 339 | ], 340 | "87": [ 341 | 14479, 342 | 189 343 | ], 344 | "88": [ 345 | 15559, 346 | 187 347 | ], 348 | "3612": [ 349 | 68501, 350 | 174 351 | ], 352 | "3613": [ 353 | 91445, 354 | 198 355 | ], 356 | "3637": [ 357 | 17743, 358 | 200 359 | ], 360 | "3639": [ 361 | 16619, 362 | 166 363 | ], 364 | "3640": [ 365 | 88293, 366 | 169 367 | ], 368 | "3653": [ 369 | 18833, 370 | 200 371 | ], 372 | "3655": [ 373 | 35728, 374 | 186 375 | ], 376 | "3657": [ 377 | 36825, 378 | 175 379 | ], 380 | "3663": [ 381 | 52666, 382 | 163 383 | ], 384 | "3665": [ 385 | 53744, 386 | 192 387 | ], 388 | "3666": [ 389 | 34738, 390 | 166 391 | ], 392 | "3667": [ 393 | 51695, 394 | 200 395 | ], 396 | "3675": [ 397 | 85179, 398 | 173 399 | ], 400 | "3676": [ 401 | 89346, 402 | 164 403 | ], 404 | "3677": [ 405 | 91445, 406 | 198 407 | ], 408 | "57416": [ 409 | 82838, 410 | 211 411 | ], 412 | "57419": [ 413 | 92565, 414 | 173 415 | ], 416 | "57421": [ 417 | 93739, 418 | 195 419 | ], 420 | "57424": [ 421 | 93711, 422 | 174 423 | ], 424 | "60999": [ 425 | 35728, 426 | 186 427 | ], 428 | "61000": [ 429 | 82838, 430 | 211 431 | ], 432 | "61001": [ 433 | 36825, 434 | 175 435 | ], 436 | "61003": [ 437 | 92565, 438 | 173 439 | ], 440 | "61005": [ 441 | 93739, 442 | 195 443 | ], 444 | "61007": [ 445 | 52666, 446 | 163 447 | ], 448 | "61008": [ 449 | 93711, 450 | 174 451 | ], 452 | "61009": [ 453 | 53744, 454 | 192 455 | ], 456 | "61010": [ 457 | 34738, 458 | 166 459 | ], 460 | "61011": [ 461 | 51695, 462 | 200 463 | ] 464 | } 465 | } -------------------------------------------------------------------------------- /src/sounds/keys/eg-crystal-purple/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "custom-sound-pack-1605530100183", 3 | "name": "EG Crystal Purple", 4 | "key_define_type": "single", 5 | "includes_numpad": false, 6 | "sound": "purple.ogg", 7 | "defines": { 8 | "1": [ 9 | 1088, 10 | 118 11 | ], 12 | "2": [ 13 | 1839, 14 | 140 15 | ], 16 | "3": [ 17 | 2207, 18 | 143 19 | ], 20 | "4": [ 21 | 2507, 22 | 143 23 | ], 24 | "5": [ 25 | 2809, 26 | 148 27 | ], 28 | "6": [ 29 | 3099, 30 | 141 31 | ], 32 | "7": [ 33 | 3408, 34 | 134 35 | ], 36 | "8": [ 37 | 3716, 38 | 147 39 | ], 40 | "9": [ 41 | 4017, 42 | 139 43 | ], 44 | "10": [ 45 | 4352, 46 | 144 47 | ], 48 | "11": [ 49 | 4657, 50 | 126 51 | ], 52 | "12": [ 53 | 4946, 54 | 134 55 | ], 56 | "13": [ 57 | 5250, 58 | 133 59 | ], 60 | "14": [ 61 | 5566, 62 | 143 63 | ], 64 | "15": [ 65 | 6792, 66 | 157 67 | ], 68 | "16": [ 69 | 7080, 70 | 142 71 | ], 72 | "17": [ 73 | 7367, 74 | 134 75 | ], 76 | "18": [ 77 | 7680, 78 | 130 79 | ], 80 | "19": [ 81 | 7973, 82 | 133 83 | ], 84 | "20": [ 85 | 8259, 86 | 134 87 | ], 88 | "21": [ 89 | 8549, 90 | 135 91 | ], 92 | "22": [ 93 | 8838, 94 | 135 95 | ], 96 | "23": [ 97 | 9103, 98 | 150 99 | ], 100 | "24": [ 101 | 9405, 102 | 132 103 | ], 104 | "25": [ 105 | 9703, 106 | 131 107 | ], 108 | "26": [ 109 | 10015, 110 | 144 111 | ], 112 | "27": [ 113 | 10397, 114 | 112 115 | ], 116 | "28": [ 117 | 15361, 118 | 130 119 | ], 120 | "29": [ 121 | 21408, 122 | 128 123 | ], 124 | "30": [ 125 | 12061, 126 | 129 127 | ], 128 | "31": [ 129 | 12339, 130 | 121 131 | ], 132 | "32": [ 133 | 12632, 134 | 127 135 | ], 136 | "33": [ 137 | 12916, 138 | 119 139 | ], 140 | "34": [ 141 | 13227, 142 | 121 143 | ], 144 | "35": [ 145 | 13526, 146 | 124 147 | ], 148 | "36": [ 149 | 13819, 150 | 131 151 | ], 152 | "37": [ 153 | 14115, 154 | 113 155 | ], 156 | "38": [ 157 | 14406, 158 | 123 159 | ], 160 | "39": [ 161 | 14711, 162 | 128 163 | ], 164 | "40": [ 165 | 15022, 166 | 133 167 | ], 168 | "41": [ 169 | 1088, 170 | 118 171 | ], 172 | "42": [ 173 | 16600, 174 | 136 175 | ], 176 | "43": [ 177 | 10718, 178 | 127 179 | ], 180 | "44": [ 181 | 16879, 182 | 128 183 | ], 184 | "45": [ 185 | 17196, 186 | 132 187 | ], 188 | "46": [ 189 | 17503, 190 | 113 191 | ], 192 | "47": [ 193 | 17788, 194 | 115 195 | ], 196 | "48": [ 197 | 18069, 198 | 117 199 | ], 200 | "49": [ 201 | 18349, 202 | 130 203 | ], 204 | "50": [ 205 | 18653, 206 | 123 207 | ], 208 | "51": [ 209 | 18964, 210 | 119 211 | ], 212 | "52": [ 213 | 19282, 214 | 124 215 | ], 216 | "53": [ 217 | 19594, 218 | 120 219 | ], 220 | "54": [ 221 | 19966, 222 | 130 223 | ], 224 | "55": [ 225 | 10398, 226 | 106 227 | ], 228 | "56": [ 229 | 21956, 230 | 134 231 | ], 232 | "57": [ 233 | 22501, 234 | 164 235 | ], 236 | "58": [ 237 | 11797, 238 | 140 239 | ], 240 | "59": [ 241 | 1837, 242 | 150 243 | ], 244 | "60": [ 245 | 2210, 246 | 145 247 | ], 248 | "61": [ 249 | 2503, 250 | 154 251 | ], 252 | "62": [ 253 | 2806, 254 | 149 255 | ], 256 | "63": [ 257 | 3099, 258 | 151 259 | ], 260 | "64": [ 261 | 3405, 262 | 151 263 | ], 264 | "65": [ 265 | 3712, 266 | 150 267 | ], 268 | "66": [ 269 | 4015, 270 | 146 271 | ], 272 | "67": [ 273 | 4354, 274 | 140 275 | ], 276 | "68": [ 277 | 4650, 278 | 143 279 | ], 280 | "69": [ 281 | 9700, 282 | 127 283 | ], 284 | "70": [ 285 | 2205, 286 | 151 287 | ], 288 | "71": [ 289 | 11070, 290 | 112 291 | ], 292 | "72": [ 293 | 12338, 294 | 115 295 | ], 296 | "73": [ 297 | 12634, 298 | 120 299 | ], 300 | "74": [ 301 | 10718, 302 | 123 303 | ], 304 | "75": [ 305 | 12912, 306 | 115 307 | ], 308 | "76": [ 309 | 13226, 310 | 119 311 | ], 312 | "77": [ 313 | 13529, 314 | 117 315 | ], 316 | "78": [ 317 | 5567, 318 | 141 319 | ], 320 | "79": [ 321 | 13814, 322 | 141 323 | ], 324 | "80": [ 325 | 14114, 326 | 117 327 | ], 328 | "81": [ 329 | 14401, 330 | 127 331 | ], 332 | "82": [ 333 | 16592, 334 | 164 335 | ], 336 | "83": [ 337 | 14715, 338 | 123 339 | ], 340 | "87": [ 341 | 4941, 342 | 142 343 | ], 344 | "88": [ 345 | 5249, 346 | 149 347 | ], 348 | "91": null, 349 | "92": null, 350 | "93": null, 351 | "3597": null, 352 | "3612": [ 353 | 11798, 354 | 129 355 | ], 356 | "3613": [ 357 | 23720, 358 | 119 359 | ], 360 | "3637": [ 361 | 10015, 362 | 139 363 | ], 364 | "3639": [ 365 | 1837, 366 | 151 367 | ], 368 | "3640": [ 369 | 23148, 370 | 122 371 | ], 372 | "3653": [ 373 | 2499, 374 | 153 375 | ], 376 | "3655": [ 377 | 7679, 378 | 127 379 | ], 380 | "3657": [ 381 | 7975, 382 | 123 383 | ], 384 | "3663": [ 385 | 9110, 386 | 133 387 | ], 388 | "3665": [ 389 | 9405, 390 | 125 391 | ], 392 | "3666": [ 393 | 7369, 394 | 119 395 | ], 396 | "3667": [ 397 | 8839, 398 | 134 399 | ], 400 | "3675": [ 401 | 21677, 402 | 127 403 | ], 404 | "3676": [ 405 | 23425, 406 | 120 407 | ], 408 | "3677": [ 409 | 23425, 410 | 120 411 | ], 412 | "57416": [ 413 | 20381, 414 | 137 415 | ], 416 | "57419": [ 417 | 23982, 418 | 128 419 | ], 420 | "57421": [ 421 | 24215, 422 | 143 423 | ], 424 | "57424": [ 425 | 24223, 426 | 134 427 | ], 428 | "60999": [ 429 | 7679, 430 | 127 431 | ], 432 | "61000": [ 433 | 20381, 434 | 137 435 | ], 436 | "61001": [ 437 | 7975, 438 | 123 439 | ], 440 | "61003": [ 441 | 23982, 442 | 128 443 | ], 444 | "61005": [ 445 | 24215, 446 | 143 447 | ], 448 | "61007": [ 449 | 9110, 450 | 133 451 | ], 452 | "61008": [ 453 | 24223, 454 | 134 455 | ], 456 | "61009": [ 457 | 9405, 458 | 125 459 | ], 460 | "61010": [ 461 | 7369, 462 | 119 463 | ], 464 | "61011": [ 465 | 8839, 466 | 134 467 | ] 468 | } 469 | } -------------------------------------------------------------------------------- /src/assets/milligram.min.css: -------------------------------------------------------------------------------- 1 | *,*:after,*:before{box-sizing:inherit}html{box-sizing:border-box;font-size:62.5%}body{color:#606c76;font-family:'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;font-size:1.6em;font-weight:300;letter-spacing:.01em;line-height:1.6}blockquote{border-left:0.3rem solid #d1d1d1;margin-left:0;margin-right:0;padding:1rem 1.5rem}blockquote *:last-child{margin-bottom:0}.button,button,input[type='button'],input[type='reset'],input[type='submit']{background-color:#9b4dca;border:0.1rem solid #9b4dca;border-radius:.4rem;color:#fff;cursor:pointer;display:inline-block;font-size:1.1rem;font-weight:700;height:3.8rem;letter-spacing:.1rem;line-height:3.8rem;padding:0 3.0rem;text-align:center;text-decoration:none;text-transform:uppercase;white-space:nowrap}.button:focus,.button:hover,button:focus,button:hover,input[type='button']:focus,input[type='button']:hover,input[type='reset']:focus,input[type='reset']:hover,input[type='submit']:focus,input[type='submit']:hover{background-color:#606c76;border-color:#606c76;color:#fff;outline:0}.button[disabled],button[disabled],input[type='button'][disabled],input[type='reset'][disabled],input[type='submit'][disabled]{cursor:default;opacity:.5}.button[disabled]:focus,.button[disabled]:hover,button[disabled]:focus,button[disabled]:hover,input[type='button'][disabled]:focus,input[type='button'][disabled]:hover,input[type='reset'][disabled]:focus,input[type='reset'][disabled]:hover,input[type='submit'][disabled]:focus,input[type='submit'][disabled]:hover{background-color:#9b4dca;border-color:#9b4dca}.button.button-outline,button.button-outline,input[type='button'].button-outline,input[type='reset'].button-outline,input[type='submit'].button-outline{background-color:transparent;color:#9b4dca}.button.button-outline:focus,.button.button-outline:hover,button.button-outline:focus,button.button-outline:hover,input[type='button'].button-outline:focus,input[type='button'].button-outline:hover,input[type='reset'].button-outline:focus,input[type='reset'].button-outline:hover,input[type='submit'].button-outline:focus,input[type='submit'].button-outline:hover{background-color:transparent;border-color:#606c76;color:#606c76}.button.button-outline[disabled]:focus,.button.button-outline[disabled]:hover,button.button-outline[disabled]:focus,button.button-outline[disabled]:hover,input[type='button'].button-outline[disabled]:focus,input[type='button'].button-outline[disabled]:hover,input[type='reset'].button-outline[disabled]:focus,input[type='reset'].button-outline[disabled]:hover,input[type='submit'].button-outline[disabled]:focus,input[type='submit'].button-outline[disabled]:hover{border-color:inherit;color:#9b4dca}.button.button-clear,button.button-clear,input[type='button'].button-clear,input[type='reset'].button-clear,input[type='submit'].button-clear{background-color:transparent;border-color:transparent;color:#9b4dca}.button.button-clear:focus,.button.button-clear:hover,button.button-clear:focus,button.button-clear:hover,input[type='button'].button-clear:focus,input[type='button'].button-clear:hover,input[type='reset'].button-clear:focus,input[type='reset'].button-clear:hover,input[type='submit'].button-clear:focus,input[type='submit'].button-clear:hover{background-color:transparent;border-color:transparent;color:#606c76}.button.button-clear[disabled]:focus,.button.button-clear[disabled]:hover,button.button-clear[disabled]:focus,button.button-clear[disabled]:hover,input[type='button'].button-clear[disabled]:focus,input[type='button'].button-clear[disabled]:hover,input[type='reset'].button-clear[disabled]:focus,input[type='reset'].button-clear[disabled]:hover,input[type='submit'].button-clear[disabled]:focus,input[type='submit'].button-clear[disabled]:hover{color:#9b4dca}code{background:#f4f5f6;border-radius:.4rem;font-size:86%;margin:0 .2rem;padding:.2rem .5rem;white-space:nowrap}pre{background:#f4f5f6;border-left:0.3rem solid #9b4dca;overflow-y:hidden}pre>code{border-radius:0;display:block;padding:1rem 1.5rem;white-space:pre}hr{border:0;border-top:0.1rem solid #f4f5f6;margin:3.0rem 0}input[type='color'],input[type='date'],input[type='datetime'],input[type='datetime-local'],input[type='email'],input[type='month'],input[type='number'],input[type='password'],input[type='search'],input[type='tel'],input[type='text'],input[type='url'],input[type='week'],input:not([type]),textarea,select{-webkit-appearance:none;background-color:transparent;border:0.1rem solid #d1d1d1;border-radius:.4rem;box-shadow:none;box-sizing:inherit;height:3.8rem;padding:.6rem 1.0rem .7rem;width:100%}input[type='color']:focus,input[type='date']:focus,input[type='datetime']:focus,input[type='datetime-local']:focus,input[type='email']:focus,input[type='month']:focus,input[type='number']:focus,input[type='password']:focus,input[type='search']:focus,input[type='tel']:focus,input[type='text']:focus,input[type='url']:focus,input[type='week']:focus,input:not([type]):focus,textarea:focus,select:focus{border-color:#9b4dca;outline:0}select{background:url('data:image/svg+xml;utf8,') center right no-repeat;padding-right:3.0rem}select:focus{background-image:url('data:image/svg+xml;utf8,')}select[multiple]{background:none;height:auto}textarea{min-height:6.5rem}label,legend{display:block;font-size:1.6rem;font-weight:700;margin-bottom:.5rem}fieldset{border-width:0;padding:0}input[type='checkbox'],input[type='radio']{display:inline}.label-inline{display:inline-block;font-weight:normal;margin-left:.5rem}.container{margin:0 auto;max-width:112.0rem;padding:0 2.0rem;position:relative;width:100%}.row{display:flex;flex-direction:column;padding:0;width:100%}.row.row-no-padding{padding:0}.row.row-no-padding>.column{padding:0}.row.row-wrap{flex-wrap:wrap}.row.row-top{align-items:flex-start}.row.row-bottom{align-items:flex-end}.row.row-center{align-items:center}.row.row-stretch{align-items:stretch}.row.row-baseline{align-items:baseline}.row .column{display:block;flex:1 1 auto;margin-left:0;max-width:100%;width:100%}.row .column.column-offset-10{margin-left:10%}.row .column.column-offset-20{margin-left:20%}.row .column.column-offset-25{margin-left:25%}.row .column.column-offset-33,.row .column.column-offset-34{margin-left:33.3333%}.row .column.column-offset-40{margin-left:40%}.row .column.column-offset-50{margin-left:50%}.row .column.column-offset-60{margin-left:60%}.row .column.column-offset-66,.row .column.column-offset-67{margin-left:66.6666%}.row .column.column-offset-75{margin-left:75%}.row .column.column-offset-80{margin-left:80%}.row .column.column-offset-90{margin-left:90%}.row .column.column-10{flex:0 0 10%;max-width:10%}.row .column.column-20{flex:0 0 20%;max-width:20%}.row .column.column-25{flex:0 0 25%;max-width:25%}.row .column.column-33,.row .column.column-34{flex:0 0 33.3333%;max-width:33.3333%}.row .column.column-40{flex:0 0 40%;max-width:40%}.row .column.column-50{flex:0 0 50%;max-width:50%}.row .column.column-60{flex:0 0 60%;max-width:60%}.row .column.column-66,.row .column.column-67{flex:0 0 66.6666%;max-width:66.6666%}.row .column.column-75{flex:0 0 75%;max-width:75%}.row .column.column-80{flex:0 0 80%;max-width:80%}.row .column.column-90{flex:0 0 90%;max-width:90%}.row .column .column-top{align-self:flex-start}.row .column .column-bottom{align-self:flex-end}.row .column .column-center{align-self:center}@media (min-width: 40rem){.row{flex-direction:row;margin-left:-1.0rem;width:calc(100% + 2.0rem)}.row .column{margin-bottom:inherit;padding:0 1.0rem}}a{color:#9b4dca;text-decoration:none}a:focus,a:hover{color:#606c76}dl,ol,ul{list-style:none;margin-top:0;padding-left:0}dl dl,dl ol,dl ul,ol dl,ol ol,ol ul,ul dl,ul ol,ul ul{font-size:90%;margin:1.5rem 0 1.5rem 3.0rem}ol{list-style:decimal inside}ul{list-style:circle inside}.button,button,dd,dt,li{margin-bottom:1.0rem}fieldset,input,select,textarea{margin-bottom:1.5rem}blockquote,dl,figure,form,ol,p,pre,table,ul{margin-bottom:2.5rem}table{border-spacing:0;display:block;overflow-x:auto;text-align:left;width:100%}td,th{border-bottom:0.1rem solid #e1e1e1;padding:1.2rem 1.5rem}td:first-child,th:first-child{padding-left:0}td:last-child,th:last-child{padding-right:0}@media (min-width: 40rem){table{display:table;overflow-x:initial}}b,strong{font-weight:bold}p{margin-top:0}h1,h2,h3,h4,h5,h6{font-weight:300;letter-spacing:-.1rem;margin-bottom:2.0rem;margin-top:0}h1{font-size:4.6rem;line-height:1.2}h2{font-size:3.6rem;line-height:1.25}h3{font-size:2.8rem;line-height:1.3}h4{font-size:2.2rem;letter-spacing:-.08rem;line-height:1.35}h5{font-size:1.8rem;letter-spacing:-.05rem;line-height:1.5}h6{font-size:1.6rem;letter-spacing:0;line-height:1.4}img{max-width:100%}.clearfix:after{clear:both;content:' ';display:table}.float-left{float:left}.float-right{float:right} 2 | 3 | /*# sourceMappingURL=milligram.min.css.map */ -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | // Modules to control application life and create native browser window 2 | const { app, BrowserWindow, Tray, Menu, shell, ipcMain } = require('electron'); 3 | const path = require('path'); 4 | const fs = require('fs-extra'); 5 | const StartupHandler = require('./utils/startup_handler'); 6 | const ListenHandler = require('./utils/listen_handler'); 7 | const KeyupHandler = require('./utils/keyup_handler'); 8 | const MouseHandler = require('./utils/mouse_handler'); 9 | const RandomHandler = require('./utils/random_handler'); 10 | 11 | const SYSTRAY_ICON = path.join(__dirname, '/assets/system-tray-icon.png'); 12 | const home_dir = app.getPath('home'); 13 | const keyboardcustom_dir = path.join(home_dir, '/mechvibes_custom'); 14 | const mousecustom_dir = path.join(home_dir, '/mousevibes_custom'); 15 | 16 | // Keep a global reference of the window object, if you don't, the window will 17 | // be closed automatically when the JavaScript object is garbage collected. 18 | var win; 19 | var tray = null; 20 | global.app_version = app.getVersion(); 21 | global.keyboardcustom_dir = keyboardcustom_dir; 22 | global.mousecustom_dir = mousecustom_dir; 23 | // create custom sound folder if not exists 24 | fs.ensureDirSync(keyboardcustom_dir); 25 | fs.ensureDirSync(mousecustom_dir); 26 | 27 | function createWindow(show = true) { 28 | // Create the browser window. 29 | win = new BrowserWindow({ 30 | width: 450, 31 | height: 730, 32 | webSecurity: false, 33 | // resizable: false, 34 | // fullscreenable: false, 35 | webPreferences: { 36 | preload: path.join(__dirname, 'app.js'), 37 | contextIsolation: false, 38 | nodeIntegration: true, 39 | }, 40 | show, 41 | }); 42 | 43 | // remove menu bar 44 | win.removeMenu(); 45 | 46 | // and load the index.html of the app. 47 | win.loadFile('./src/app.html'); 48 | 49 | // Open the DevTools. 50 | //win.openDevTools(); 51 | //win.webContents.openDevTools(); 52 | 53 | // Emitted when the window is closed. 54 | win.on('closed', function () { 55 | // Dereference the window object, usually you would store windows 56 | // in an array if your app supports multi windows, this is the time 57 | // when you should delete the corresponding element. 58 | win = null; 59 | }); 60 | 61 | win.on('minimize', function (event) { 62 | if (process.platform === 'darwin') { 63 | app.dock.hide(); 64 | } 65 | event.preventDefault(); 66 | win.hide(); 67 | }); 68 | 69 | win.on('close', function (event) { 70 | if (!app.isQuiting) { 71 | if (process.platform === 'darwin') { 72 | app.dock.hide(); 73 | } 74 | event.preventDefault(); 75 | win.hide(); 76 | } 77 | return false; 78 | }); 79 | 80 | return win; 81 | } 82 | 83 | const gotTheLock = app.requestSingleInstanceLock(); 84 | app.on('second-instance', () => { 85 | // Someone tried to run a second instance, we should focus our window. 86 | if (win) { 87 | win.show(); 88 | win.focus(); 89 | } 90 | }); 91 | 92 | if (!gotTheLock) { 93 | app.quit(); 94 | } else { 95 | app.on('second-instance', () => { 96 | // Someone tried to run a second instance, we should focus our window. 97 | if (win) { 98 | if (win.isMinimized()) { 99 | win.restore(); 100 | } 101 | win.show(); 102 | win.focus(); 103 | } 104 | }); 105 | 106 | // This method will be called when Electron has finished 107 | // initialization and is ready to create browser windows. 108 | // Some APIs can only be used after this event occurs. 109 | // Don't show the window and create a tray instead 110 | // create and get window instance 111 | app.on('ready', () => { 112 | win = createWindow(true); 113 | 114 | // start tray icon 115 | tray = new Tray(SYSTRAY_ICON); 116 | 117 | // tray icon tooltip 118 | tray.setToolTip('MechvibesPlusPlus'); 119 | 120 | const startup_handler = new StartupHandler(app); 121 | const listen_handler = new ListenHandler(app); 122 | const keyup_handler = new KeyupHandler(app); 123 | const mouse_handler = new MouseHandler(app); 124 | const random_handler = new RandomHandler(app); 125 | 126 | // context menu when hover on tray icon 127 | const contextMenu = Menu.buildFromTemplate([ 128 | { 129 | label: 'MechvibesPlusPlus', 130 | click: function () { 131 | // show app on click 132 | win.show(); 133 | }, 134 | }, 135 | { 136 | label: 'Editor', 137 | click: function () { 138 | openEditorWindow(); 139 | }, 140 | }, 141 | { 142 | label: 'Keyboard Sound Custom Folder', 143 | click: function () { 144 | shell.openItem(keyboardcustom_dir); 145 | }, 146 | }, 147 | { 148 | label: 'Mouse Sound Custom Folder', 149 | click: function () { 150 | shell.openItem(mousecustom_dir); 151 | }, 152 | }, 153 | { 154 | label: 'Open Devtools', 155 | click: function () { 156 | win.openDevTools(); 157 | win.webContents.openDevTools(); 158 | }, 159 | }, 160 | { 161 | label: 'Refresh Soundpacks', 162 | click: function () { 163 | win.webContents.send('refresh') 164 | }, 165 | }, 166 | { 167 | label: 'Mute', 168 | type: 'checkbox', 169 | checked: listen_handler.is_muted, 170 | click: function () { 171 | listen_handler.toggle(); 172 | win.webContents.send('muted', listen_handler.is_muted); 173 | }, 174 | }, 175 | { 176 | label: 'Keyup Sounds', 177 | type: 'checkbox', 178 | checked: keyup_handler.is_keyup, 179 | click: function () { 180 | keyup_handler.toggle(); 181 | win.webContents.send('theKeyup', keyup_handler.is_keyup); 182 | }, 183 | }, 184 | { 185 | label: 'Mouse Sounds', 186 | type: 'checkbox', 187 | checked: mouse_handler.is_mousesounds, 188 | click: function () { 189 | mouse_handler.toggle(); 190 | win.webContents.send('MouseSounds', mouse_handler.is_mousesounds); 191 | }, 192 | }, 193 | { 194 | label: 'Random Sounds', 195 | type: 'checkbox', 196 | checked: random_handler.is_random, 197 | click: function () { 198 | random_handler.toggle(); 199 | win.webContents.send('RandomSoundEnable', random_handler.is_random); 200 | }, 201 | }, 202 | { 203 | label: 'Enable at Startup', 204 | type: 'checkbox', 205 | checked: startup_handler.is_enabled, 206 | click: function () { 207 | startup_handler.toggle(); 208 | }, 209 | }, 210 | { 211 | label: 'Quit', 212 | click: function () { 213 | // quit 214 | app.isQuiting = true; 215 | app.quit(); 216 | }, 217 | }, 218 | ]); 219 | 220 | // double click on tray icon, show the app 221 | tray.on('double-click', () => { 222 | win.show(); 223 | }); 224 | 225 | tray.setContextMenu(contextMenu); 226 | 227 | // prevent Electron app from interrupting macOS system shutdown 228 | if (process.platform == 'darwin') { 229 | const { powerMonitor } = require('electron'); 230 | powerMonitor.on('shutdown', () => { 231 | app.quit(); 232 | }); 233 | } 234 | }); 235 | } 236 | 237 | app.commandLine.appendSwitch('autoplay-policy', 'no-user-gesture-required'); 238 | 239 | // Quit when all windows are closed. 240 | app.on('window-all-closed', function () { 241 | // On macOS it is common for applications and their menu bar 242 | // to stay active until the user quits explicitly with Cmd + Q 243 | if (process.platform !== 'darwin') app.quit(); 244 | }); 245 | 246 | app.on('activate', function () { 247 | // On macOS it's common to re-create a window in the app when the 248 | // dock icon is clicked and there are no other windows open. 249 | if (win === null) createWindow(); 250 | }); 251 | 252 | // always be sure that your application handles the 'quit' event in your main process 253 | app.on('quit', () => { 254 | app.quit(); 255 | }); 256 | 257 | var editor_window = null; 258 | 259 | function openEditorWindow() { 260 | if (editor_window) { 261 | editor_window.focus(); 262 | return; 263 | } 264 | 265 | editor_window = new BrowserWindow({ 266 | width: 1200, 267 | height: 600, 268 | // resizable: false, 269 | // minimizable: false, 270 | // fullscreenable: false, 271 | // modal: true, 272 | // parent: win, 273 | webPreferences: { 274 | // preload: path.join(__dirname, 'editor.js'), 275 | nodeIntegration: true, 276 | }, 277 | }); 278 | 279 | // editor_window.openDevTools(); 280 | 281 | editor_window.loadFile('./src/editor.html'); 282 | 283 | editor_window.on('closed', function () { 284 | editor_window = null; 285 | }); 286 | } 287 | -------------------------------------------------------------------------------- /src/assets/milligram.min.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["milligram.min.css"],"names":[],"mappings":"AAAA,mBAAmB,kBAAkB,CAAC,KAAK,qBAAqB,CAAC,eAAe,CAAC,KAAK,aAAa,CAAC,wEAAwE,CAAC,eAAe,CAAC,eAAe,CAAC,oBAAoB,CAAC,eAAe,CAAC,WAAW,gCAAgC,CAAC,aAAa,CAAC,cAAc,CAAC,mBAAmB,CAAC,wBAAwB,eAAe,CAAC,6EAA6E,wBAAwB,CAAC,2BAA2B,CAAC,mBAAmB,CAAC,UAAU,CAAC,cAAc,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,eAAe,CAAC,aAAa,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,oBAAoB,CAAC,wBAAwB,CAAC,kBAAkB,CAAC,sNAAsN,wBAAwB,CAAC,oBAAoB,CAAC,UAAU,CAAC,SAAS,CAAC,+HAA+H,cAAc,CAAC,UAAU,CAAC,0TAA0T,wBAAwB,CAAC,oBAAoB,CAAC,wJAAwJ,4BAA4B,CAAC,aAAa,CAAC,4WAA4W,4BAA4B,CAAC,oBAAoB,CAAC,aAAa,CAAC,gdAAgd,oBAAoB,CAAC,aAAa,CAAC,8IAA8I,4BAA4B,CAAC,wBAAwB,CAAC,aAAa,CAAC,wVAAwV,4BAA4B,CAAC,wBAAwB,CAAC,aAAa,CAAC,4bAA4b,aAAa,CAAC,KAAK,kBAAkB,CAAC,mBAAmB,CAAC,aAAa,CAAC,cAAc,CAAC,mBAAmB,CAAC,kBAAkB,CAAC,IAAI,kBAAkB,CAAC,gCAAgC,CAAC,iBAAiB,CAAC,SAAS,eAAe,CAAC,aAAa,CAAC,mBAAmB,CAAC,eAAe,CAAC,GAAG,QAAQ,CAAC,+BAA+B,CAAC,eAAe,CAAC,gTAAgT,uBAAuB,CAAC,4BAA4B,CAAC,2BAA2B,CAAC,mBAAmB,CAAC,eAAe,CAAC,kBAAkB,CAAC,aAAa,CAAC,0BAA0B,CAAC,UAAU,CAAC,gZAAgZ,oBAAoB,CAAC,SAAS,CAAC,OAAO,sLAAsL,CAAC,oBAAoB,CAAC,aAAa,qKAAqK,CAAC,iBAAiB,eAAe,CAAC,WAAW,CAAC,SAAS,iBAAiB,CAAC,aAAa,aAAa,CAAC,gBAAgB,CAAC,eAAe,CAAC,mBAAmB,CAAC,SAAS,cAAc,CAAC,SAAS,CAAC,2CAA2C,cAAc,CAAC,cAAc,oBAAoB,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,WAAW,aAAa,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,UAAU,CAAC,KAAK,YAAY,CAAC,qBAAqB,CAAC,SAAS,CAAC,UAAU,CAAC,oBAAoB,SAAS,CAAC,4BAA4B,SAAS,CAAC,cAAc,cAAc,CAAC,aAAa,sBAAsB,CAAC,gBAAgB,oBAAoB,CAAC,gBAAgB,kBAAkB,CAAC,iBAAiB,mBAAmB,CAAC,kBAAkB,oBAAoB,CAAC,aAAa,aAAa,CAAC,aAAa,CAAC,aAAa,CAAC,cAAc,CAAC,UAAU,CAAC,8BAA8B,eAAe,CAAC,8BAA8B,eAAe,CAAC,8BAA8B,eAAe,CAAC,4DAA4D,oBAAoB,CAAC,8BAA8B,eAAe,CAAC,8BAA8B,eAAe,CAAC,8BAA8B,eAAe,CAAC,4DAA4D,oBAAoB,CAAC,8BAA8B,eAAe,CAAC,8BAA8B,eAAe,CAAC,8BAA8B,eAAe,CAAC,uBAAuB,YAAY,CAAC,aAAa,CAAC,uBAAuB,YAAY,CAAC,aAAa,CAAC,uBAAuB,YAAY,CAAC,aAAa,CAAC,8CAA8C,iBAAiB,CAAC,kBAAkB,CAAC,uBAAuB,YAAY,CAAC,aAAa,CAAC,uBAAuB,YAAY,CAAC,aAAa,CAAC,uBAAuB,YAAY,CAAC,aAAa,CAAC,8CAA8C,iBAAiB,CAAC,kBAAkB,CAAC,uBAAuB,YAAY,CAAC,aAAa,CAAC,uBAAuB,YAAY,CAAC,aAAa,CAAC,uBAAuB,YAAY,CAAC,aAAa,CAAC,yBAAyB,qBAAqB,CAAC,4BAA4B,mBAAmB,CAAC,4BAA4B,iBAAiB,CAAC,0BAA0B,KAAK,kBAAkB,CAAC,mBAAmB,CAAC,yBAAyB,CAAC,aAAa,qBAAqB,CAAC,gBAAgB,CAAC,CAAC,EAAE,aAAa,CAAC,oBAAoB,CAAC,gBAAgB,aAAa,CAAC,SAAS,eAAe,CAAC,YAAY,CAAC,cAAc,CAAC,sDAAsD,aAAa,CAAC,6BAA6B,CAAC,GAAG,yBAAyB,CAAC,GAAG,wBAAwB,CAAC,wBAAwB,oBAAoB,CAAC,+BAA+B,oBAAoB,CAAC,4CAA4C,oBAAoB,CAAC,MAAM,gBAAgB,CAAC,aAAa,CAAC,eAAe,CAAC,eAAe,CAAC,UAAU,CAAC,MAAM,kCAAkC,CAAC,qBAAqB,CAAC,8BAA8B,cAAc,CAAC,4BAA4B,eAAe,CAAC,0BAA0B,MAAM,aAAa,CAAC,kBAAkB,CAAC,CAAC,SAAS,gBAAgB,CAAC,EAAE,YAAY,CAAC,kBAAkB,eAAe,CAAC,qBAAqB,CAAC,oBAAoB,CAAC,YAAY,CAAC,GAAG,gBAAgB,CAAC,eAAe,CAAC,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAAC,eAAe,CAAC,GAAG,gBAAgB,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAAC,sBAAsB,CAAC,eAAe,CAAC,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,eAAe,CAAC,IAAI,cAAc,CAAC,gBAAgB,UAAU,CAAC,WAAW,CAAC,aAAa,CAAC,YAAY,UAAU,CAAC,aAAa,WAAW","file":"milligram.min.css","sourcesContent":["*,*:after,*:before{box-sizing:inherit}html{box-sizing:border-box;font-size:62.5%}body{color:#606c76;font-family:'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;font-size:1.6em;font-weight:300;letter-spacing:.01em;line-height:1.6}blockquote{border-left:0.3rem solid #d1d1d1;margin-left:0;margin-right:0;padding:1rem 1.5rem}blockquote *:last-child{margin-bottom:0}.button,button,input[type='button'],input[type='reset'],input[type='submit']{background-color:#9b4dca;border:0.1rem solid #9b4dca;border-radius:.4rem;color:#fff;cursor:pointer;display:inline-block;font-size:1.1rem;font-weight:700;height:3.8rem;letter-spacing:.1rem;line-height:3.8rem;padding:0 3.0rem;text-align:center;text-decoration:none;text-transform:uppercase;white-space:nowrap}.button:focus,.button:hover,button:focus,button:hover,input[type='button']:focus,input[type='button']:hover,input[type='reset']:focus,input[type='reset']:hover,input[type='submit']:focus,input[type='submit']:hover{background-color:#606c76;border-color:#606c76;color:#fff;outline:0}.button[disabled],button[disabled],input[type='button'][disabled],input[type='reset'][disabled],input[type='submit'][disabled]{cursor:default;opacity:.5}.button[disabled]:focus,.button[disabled]:hover,button[disabled]:focus,button[disabled]:hover,input[type='button'][disabled]:focus,input[type='button'][disabled]:hover,input[type='reset'][disabled]:focus,input[type='reset'][disabled]:hover,input[type='submit'][disabled]:focus,input[type='submit'][disabled]:hover{background-color:#9b4dca;border-color:#9b4dca}.button.button-outline,button.button-outline,input[type='button'].button-outline,input[type='reset'].button-outline,input[type='submit'].button-outline{background-color:transparent;color:#9b4dca}.button.button-outline:focus,.button.button-outline:hover,button.button-outline:focus,button.button-outline:hover,input[type='button'].button-outline:focus,input[type='button'].button-outline:hover,input[type='reset'].button-outline:focus,input[type='reset'].button-outline:hover,input[type='submit'].button-outline:focus,input[type='submit'].button-outline:hover{background-color:transparent;border-color:#606c76;color:#606c76}.button.button-outline[disabled]:focus,.button.button-outline[disabled]:hover,button.button-outline[disabled]:focus,button.button-outline[disabled]:hover,input[type='button'].button-outline[disabled]:focus,input[type='button'].button-outline[disabled]:hover,input[type='reset'].button-outline[disabled]:focus,input[type='reset'].button-outline[disabled]:hover,input[type='submit'].button-outline[disabled]:focus,input[type='submit'].button-outline[disabled]:hover{border-color:inherit;color:#9b4dca}.button.button-clear,button.button-clear,input[type='button'].button-clear,input[type='reset'].button-clear,input[type='submit'].button-clear{background-color:transparent;border-color:transparent;color:#9b4dca}.button.button-clear:focus,.button.button-clear:hover,button.button-clear:focus,button.button-clear:hover,input[type='button'].button-clear:focus,input[type='button'].button-clear:hover,input[type='reset'].button-clear:focus,input[type='reset'].button-clear:hover,input[type='submit'].button-clear:focus,input[type='submit'].button-clear:hover{background-color:transparent;border-color:transparent;color:#606c76}.button.button-clear[disabled]:focus,.button.button-clear[disabled]:hover,button.button-clear[disabled]:focus,button.button-clear[disabled]:hover,input[type='button'].button-clear[disabled]:focus,input[type='button'].button-clear[disabled]:hover,input[type='reset'].button-clear[disabled]:focus,input[type='reset'].button-clear[disabled]:hover,input[type='submit'].button-clear[disabled]:focus,input[type='submit'].button-clear[disabled]:hover{color:#9b4dca}code{background:#f4f5f6;border-radius:.4rem;font-size:86%;margin:0 .2rem;padding:.2rem .5rem;white-space:nowrap}pre{background:#f4f5f6;border-left:0.3rem solid #9b4dca;overflow-y:hidden}pre>code{border-radius:0;display:block;padding:1rem 1.5rem;white-space:pre}hr{border:0;border-top:0.1rem solid #f4f5f6;margin:3.0rem 0}input[type='color'],input[type='date'],input[type='datetime'],input[type='datetime-local'],input[type='email'],input[type='month'],input[type='number'],input[type='password'],input[type='search'],input[type='tel'],input[type='text'],input[type='url'],input[type='week'],input:not([type]),textarea,select{-webkit-appearance:none;background-color:transparent;border:0.1rem solid #d1d1d1;border-radius:.4rem;box-shadow:none;box-sizing:inherit;height:3.8rem;padding:.6rem 1.0rem .7rem;width:100%}input[type='color']:focus,input[type='date']:focus,input[type='datetime']:focus,input[type='datetime-local']:focus,input[type='email']:focus,input[type='month']:focus,input[type='number']:focus,input[type='password']:focus,input[type='search']:focus,input[type='tel']:focus,input[type='text']:focus,input[type='url']:focus,input[type='week']:focus,input:not([type]):focus,textarea:focus,select:focus{border-color:#9b4dca;outline:0}select{background:url('data:image/svg+xml;utf8,') center right no-repeat;padding-right:3.0rem}select:focus{background-image:url('data:image/svg+xml;utf8,')}select[multiple]{background:none;height:auto}textarea{min-height:6.5rem}label,legend{display:block;font-size:1.6rem;font-weight:700;margin-bottom:.5rem}fieldset{border-width:0;padding:0}input[type='checkbox'],input[type='radio']{display:inline}.label-inline{display:inline-block;font-weight:normal;margin-left:.5rem}.container{margin:0 auto;max-width:112.0rem;padding:0 2.0rem;position:relative;width:100%}.row{display:flex;flex-direction:column;padding:0;width:100%}.row.row-no-padding{padding:0}.row.row-no-padding>.column{padding:0}.row.row-wrap{flex-wrap:wrap}.row.row-top{align-items:flex-start}.row.row-bottom{align-items:flex-end}.row.row-center{align-items:center}.row.row-stretch{align-items:stretch}.row.row-baseline{align-items:baseline}.row .column{display:block;flex:1 1 auto;margin-left:0;max-width:100%;width:100%}.row .column.column-offset-10{margin-left:10%}.row .column.column-offset-20{margin-left:20%}.row .column.column-offset-25{margin-left:25%}.row .column.column-offset-33,.row .column.column-offset-34{margin-left:33.3333%}.row .column.column-offset-40{margin-left:40%}.row .column.column-offset-50{margin-left:50%}.row .column.column-offset-60{margin-left:60%}.row .column.column-offset-66,.row .column.column-offset-67{margin-left:66.6666%}.row .column.column-offset-75{margin-left:75%}.row .column.column-offset-80{margin-left:80%}.row .column.column-offset-90{margin-left:90%}.row .column.column-10{flex:0 0 10%;max-width:10%}.row .column.column-20{flex:0 0 20%;max-width:20%}.row .column.column-25{flex:0 0 25%;max-width:25%}.row .column.column-33,.row .column.column-34{flex:0 0 33.3333%;max-width:33.3333%}.row .column.column-40{flex:0 0 40%;max-width:40%}.row .column.column-50{flex:0 0 50%;max-width:50%}.row .column.column-60{flex:0 0 60%;max-width:60%}.row .column.column-66,.row .column.column-67{flex:0 0 66.6666%;max-width:66.6666%}.row .column.column-75{flex:0 0 75%;max-width:75%}.row .column.column-80{flex:0 0 80%;max-width:80%}.row .column.column-90{flex:0 0 90%;max-width:90%}.row .column .column-top{align-self:flex-start}.row .column .column-bottom{align-self:flex-end}.row .column .column-center{align-self:center}@media (min-width: 40rem){.row{flex-direction:row;margin-left:-1.0rem;width:calc(100% + 2.0rem)}.row .column{margin-bottom:inherit;padding:0 1.0rem}}a{color:#9b4dca;text-decoration:none}a:focus,a:hover{color:#606c76}dl,ol,ul{list-style:none;margin-top:0;padding-left:0}dl dl,dl ol,dl ul,ol dl,ol ol,ol ul,ul dl,ul ol,ul ul{font-size:90%;margin:1.5rem 0 1.5rem 3.0rem}ol{list-style:decimal inside}ul{list-style:circle inside}.button,button,dd,dt,li{margin-bottom:1.0rem}fieldset,input,select,textarea{margin-bottom:1.5rem}blockquote,dl,figure,form,ol,p,pre,table,ul{margin-bottom:2.5rem}table{border-spacing:0;display:block;overflow-x:auto;text-align:left;width:100%}td,th{border-bottom:0.1rem solid #e1e1e1;padding:1.2rem 1.5rem}td:first-child,th:first-child{padding-left:0}td:last-child,th:last-child{padding-right:0}@media (min-width: 40rem){table{display:table;overflow-x:initial}}b,strong{font-weight:bold}p{margin-top:0}h1,h2,h3,h4,h5,h6{font-weight:300;letter-spacing:-.1rem;margin-bottom:2.0rem;margin-top:0}h1{font-size:4.6rem;line-height:1.2}h2{font-size:3.6rem;line-height:1.25}h3{font-size:2.8rem;line-height:1.3}h4{font-size:2.2rem;letter-spacing:-.08rem;line-height:1.35}h5{font-size:1.8rem;letter-spacing:-.05rem;line-height:1.5}h6{font-size:1.6rem;letter-spacing:0;line-height:1.4}img{max-width:100%}.clearfix:after{clear:both;content:' ';display:table}.float-left{float:left}.float-right{float:right}\n"]} -------------------------------------------------------------------------------- /src/editor.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | const { shell } = require('electron'); 6 | 7 | const remapper = require('./utils/remapper'); 8 | const layouts = require('./libs/layouts'); 9 | const keycodes = require('./libs/keycodes'); 10 | const $ = require('./assets/jquery'); 11 | 12 | const layout = layouts[process.platform]; 13 | const { sizes } = layouts; 14 | const os_keycode = keycodes[process.platform]; 15 | const CUSTOM_PACKS_DIR = path.join(__dirname, '../../../custom'); 16 | 17 | let selected_keycode = null; 18 | let current_edit_mode = 'visual'; 19 | let current_key_define_mode = 'single'; 20 | 21 | let pack_data = { 22 | id: `custom-sound-pack-${Date.now()}`, 23 | name: 'Untitled', 24 | key_define_type: 'single', 25 | includes_numpad: false, 26 | sound: 'sound.ogg', 27 | defines: JSON.parse(JSON.stringify(os_keycode)), 28 | }; 29 | Object.keys(pack_data.defines).map(kc => { 30 | pack_data.defines[kc] = null; 31 | }); 32 | 33 | (function(document) { 34 | $(document).ready(() => { 35 | // a little hack for open link in browser 36 | Array.from(document.getElementsByClassName('open-in-browser')).forEach(elem => { 37 | elem.addEventListener('click', e => { 38 | e.preventDefault(); 39 | shell.openExternal(e.target.href); 40 | }); 41 | }); 42 | 43 | // open custom sound pack folder 44 | $('#open-custom-pack-folder').on('click', () => { 45 | shell.showItemInFolder(CUSTOM_PACKS_DIR); 46 | }); 47 | 48 | $('#pack-name').val(pack_data.name); 49 | $('#single-sound-file').val(pack_data.sound); 50 | 51 | const keyboard_holder = $('#kb'); 52 | keyboard_holder.html(''); 53 | for (let zone of ['main', 'edit', 'numpad']) { 54 | const zone_wrapper = $(`
`); 55 | const manual_zone_wrapper = $(`#pack-zone-${zone}`); 56 | const zone_rows = layout[zone]; 57 | let r = 0; 58 | for (let row of zone_rows) { 59 | const _row = $(`
`); 60 | let k = 0; 61 | if (row.length) { 62 | for (let key of row) { 63 | // visual edit 64 | //
${r}-${k++}
65 | const _key = $(` 66 |
67 |
${os_keycode[key] || ''}
68 |
69 | `); 70 | _key.appendTo(_row); 71 | _genPopover(_key, key, r > 3, zone == 'numpad'); 72 | // manual edit 73 | if (key) { 74 | const manual_key = $(` 75 |
76 |
${os_keycode[key]}
77 |
78 |
79 | 80 | 81 |
82 |
83 |
84 | 85 |
86 |
87 | `); 88 | manual_key.appendTo(manual_zone_wrapper); 89 | } 90 | } 91 | } 92 | r++; 93 | _row.appendTo(zone_wrapper); 94 | } 95 | zone_wrapper.appendTo(keyboard_holder); 96 | } 97 | 98 | // ====================== 99 | $('#kb').on('click', '.key', e => { 100 | const target = $(e.currentTarget); 101 | if (target.hasClass('key-blank')) { 102 | e.preventDefault(); 103 | return false; 104 | } 105 | const keycode = target.data('keycode'); 106 | if (!$(e.target).hasClass('close')) { 107 | $('.key') 108 | .removeClass('key-pressed key-show-popover') 109 | .addClass('key-hide'); 110 | target.addClass('key-pressed key-show-popover').removeClass('key-hide'); 111 | } 112 | const letter = target.find('.letter').text(); 113 | selected_keycode = keycode; 114 | }); 115 | 116 | $('#kb').on('click', '.popover .close', e => { 117 | setTimeout(() => { 118 | $('.key').removeClass('key-pressed key-show-popover key-hide'); 119 | }); 120 | }); 121 | 122 | $('#kb').on('click', '.popover .save', e => { 123 | setTimeout(() => { 124 | $('.key').removeClass('key-pressed key-show-popover key-hide'); 125 | const keycode = $(e.currentTarget).data('keycode'); 126 | 127 | if (!current_key_define_mode || current_key_define_mode == 'single') { 128 | const start = $(e.currentTarget).find('.sound-start'); 129 | const length = $(e.currentTarget).find('.sound-length'); 130 | pack_data.defines[keycode] = [Number(start.val()), Number(length.val())]; 131 | } else { 132 | const file_name = $(e.currentTarget).find('.sound-name'); 133 | pack_data.defines[keycode] = file_name.val(); 134 | } 135 | _checkIfHasSound(); 136 | }); 137 | }); 138 | 139 | $('.edit-mode-manual').on('change', '.key-define', e => { 140 | const keycode = $(e.target).data('keycode'); 141 | if (!current_key_define_mode || current_key_define_mode == 'single') { 142 | pack_data.defines[keycode] = pack_data.defines[keycode] || [0, 0]; 143 | if ($(e.target).hasClass('sound-start')) { 144 | pack_data.defines[keycode][0] = Number($(e.target).val()); 145 | } else { 146 | pack_data.defines[keycode][1] = Number($(e.target).val()); 147 | } 148 | } else { 149 | pack_data.defines[keycode] = $(e.target).val(); 150 | } 151 | _checkIfHasSound(); 152 | }); 153 | 154 | $('#single-sound-file').on('change', e => { 155 | pack_data.sound = $(e.target).val() || 'sound.ogg'; 156 | genResults(); 157 | }); 158 | 159 | $('#pack-name').on('change', e => { 160 | pack_data.name = $(e.target).val() || 'Untitled'; 161 | genResults(); 162 | }); 163 | 164 | $('.edit-mode-manual').hide(); 165 | $('#edit-mode').on('change', e => { 166 | current_edit_mode = e.target.value; 167 | $('.edit-mode').hide(); 168 | $(`.edit-mode-${e.target.value}`).show(); 169 | if (e.target.value == 'manual') { 170 | for (let kc in pack_data.defines) { 171 | if (pack_data.defines[kc] && $(`.sound-file[data-keycode="${kc}"]`)) { 172 | if (typeof pack_data.defines[kc] == 'string') { 173 | $(`.sound-file[data-keycode="${kc}"]`).val(pack_data.defines[kc]); 174 | } else { 175 | $(`.sound-start[data-keycode="${kc}"]`).val(pack_data.defines[kc][0]); 176 | $(`.sound-length[data-keycode="${kc}"]`).val(pack_data.defines[kc][1]); 177 | } 178 | } 179 | } 180 | } else { 181 | for (let kc in pack_data.defines) { 182 | if (pack_data.defines[kc] && $(`.sound-file[data-keycode="${kc}"]`)) { 183 | if (typeof pack_data.defines[kc] == 'string') { 184 | $(`.key[data-keycode="${kc}"]`) 185 | .find('.sound-name') 186 | .val(pack_data.defines[kc]); 187 | } else { 188 | $(`.key[data-keycode="${kc}"]`) 189 | .find('.sound-start') 190 | .val(pack_data.defines[kc][0]); 191 | $(`.key[data-keycode="${kc}"]`) 192 | .find('.sound-length') 193 | .val(pack_data.defines[kc][1]); 194 | } 195 | } 196 | } 197 | } 198 | }); 199 | 200 | $('.define-mode-multi').hide(); 201 | $('#key-define-mode').on('change', e => { 202 | pack_data.key_define_type = e.target.value; 203 | current_key_define_mode = e.target.value; 204 | $('.define-mode').hide(); 205 | $(`.define-mode-${e.target.value}`).show(); 206 | $('.key-define').each((index, el) => { 207 | el.value = ''; 208 | }); 209 | Object.keys(pack_data.defines).map(kc => { 210 | pack_data.defines[kc] = null; 211 | }); 212 | _checkIfHasSound(); 213 | }); 214 | }); 215 | 216 | function _checkIfHasSound() { 217 | Object.keys(pack_data.defines).map(kc => { 218 | if (pack_data.defines[kc] != null) { 219 | $(`.key[data-keycode=${kc}]`).addClass('key-has-sound'); 220 | $(`#manual-key-${kc}`).addClass('key-has-sound'); 221 | } else { 222 | $(`.key[data-keycode=${kc}]`).removeClass('key-has-sound'); 223 | $(`#manual-key-${kc}`).removeClass('key-has-sound'); 224 | } 225 | }); 226 | genResults(); 227 | } 228 | 229 | function _genPopover(target, keycode, up, left) { 230 | const popover = $(` 231 |
232 |
233 |
Set start and length (ms)
234 |
235 | 236 | 237 |
238 |
239 | 240 |
241 |
Enter audio file name:
242 | 243 |
244 | 245 |
246 | 247 | 248 |
249 |
250 | `); 251 | popover.appendTo(target); 252 | } 253 | 254 | function genResults() { 255 | const container = $('#result'); 256 | pack_data.defines = remapper(process.platform, 'standard', pack_data.defines); 257 | const result = JSON.stringify(pack_data, null, 2); 258 | container.html(result); 259 | } 260 | 261 | // ====================================== 262 | // new pack 263 | $('#create').on('click', () => { 264 | Object.assign(pack_data, { 265 | id: `custom-sound-pack-${Date.now()}`, 266 | key_define_type: 'single', 267 | name: 'Untitled', 268 | sound: 'sound.ogg', 269 | }); 270 | Object.keys(pack_data.defines).map(kc => { 271 | pack_data.defines[kc] = null; 272 | }); 273 | $('#pack-name').val(pack_data.name); 274 | $('#single-sound-file').val(pack_data.sound); 275 | $('.key-define').val(null); 276 | }); 277 | 278 | function importPack(imported) { 279 | Object.assign(pack_data, imported); 280 | $('#pack-name').val(pack_data.name); 281 | $('#single-sound-file').val(pack_data.sound); 282 | 283 | pack_data.defines = remapper('standard', process.platform, pack_data.defines); 284 | 285 | const key_define_type = imported.key_define_type || 'single'; 286 | $('.define-mode').hide(); 287 | $(`.define-mode-${key_define_type}`).show(); 288 | $('#key-define-mode').val(key_define_type); 289 | $(`#key-define-mode option[value=${key_define_type}]`).attr('selected', 'selected'); 290 | current_key_define_mode = key_define_type; 291 | 292 | console.log(key_define_type); 293 | 294 | for (let kc in pack_data.defines) { 295 | if (pack_data.defines[kc] && $(`.sound-file[data-keycode="${kc}"]`) && pack_data.defines[kc] != '' && pack_data.defines[kc] != [0, 0]) { 296 | if (current_key_define_mode == 'manual') { 297 | if (typeof pack_data.defines[kc] == 'string') { 298 | $(`.sound-file[data-keycode="${kc}"]`).val(pack_data.defines[kc]); 299 | } else { 300 | $(`.sound-start[data-keycode="${kc}"]`).val(pack_data.defines[kc][0]); 301 | $(`.sound-length[data-keycode="${kc}"]`).val(pack_data.defines[kc][1]); 302 | } 303 | } else { 304 | if (typeof pack_data.defines[kc] == 'string') { 305 | $(`.key[data-keycode="${kc}"]`) 306 | .find('.sound-name') 307 | .val(pack_data.defines[kc]); 308 | } else { 309 | $(`.key[data-keycode="${kc}"]`) 310 | .find('.sound-start') 311 | .val(pack_data.defines[kc][0]); 312 | $(`.key[data-keycode="${kc}"]`) 313 | .find('.sound-length') 314 | .val(pack_data.defines[kc][1]); 315 | } 316 | } 317 | } 318 | } 319 | } 320 | 321 | // ====================================== 322 | // inport 323 | $('#import').on('click', e => { 324 | $('#import-input').click(); 325 | }); 326 | $('#import-input').on('change', e => { 327 | const buffer = fs.readFileSync(e.target.files[0].path); 328 | const imported_data = JSON.parse(buffer.toString()); 329 | importPack(imported_data); 330 | _checkIfHasSound(); 331 | genResults(); 332 | }); 333 | 334 | // ====================================== 335 | // export 336 | $('#export').on('click', e => { 337 | var a = document.createElement('a'); 338 | var file = new Blob([JSON.stringify(pack_data, null, 2)], { type: 'text/plain' }); 339 | a.href = URL.createObjectURL(file); 340 | a.download = 'config.json'; 341 | a.click(); 342 | URL.revokeObjectURL(a.href); 343 | }); 344 | })(document); 345 | -------------------------------------------------------------------------------- /src/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // All of the Node.js APIs are available in the preload process. 4 | // It has the same sandbox as a Chrome extension. 5 | // const gkm = require('gkm'); 6 | const Store = require('electron-store'); 7 | const store = new Store(); 8 | const { Howl } = require('howler'); 9 | const { shell, remote, ipcRenderer } = require('electron'); 10 | const glob = require('glob'); 11 | const iohook = require('iohook'); 12 | const path = require('path'); 13 | const { platform } = process; 14 | const remapper = require('./utils/remapper'); 15 | 16 | const MV_KEYBOARD_PACK_LSID = 'mechvibes-pack'; 17 | const MV_MOUSE_PACK_LSID = 'mechvibes-mousepack'; 18 | const MV_KEY_VOL_LSID = 'mechvibes-volume-keyboard'; 19 | const MV_MOUSE_VOL_LSID = 'mechvibes-volume-mouse'; 20 | 21 | const KEYBOARD_CUSTOM_PACKS_DIR = remote.getGlobal('keyboardcustom_dir'); 22 | const KEYBOARD_OFFICIAL_PACKS_DIR = path.join(__dirname, 'sounds/keys'); 23 | const MOUSE_CUSTOM_PACKS_DIR = remote.getGlobal('mousecustom_dir'); 24 | const MOUSE_OFFICIAL_PACKS_DIR = path.join(__dirname, 'sounds/mouse'); 25 | const APP_VERSION = remote.getGlobal('app_version'); 26 | 27 | let current_keyboard_pack = null; 28 | let current_mouse_pack = null; 29 | let current_sound_key = null; 30 | let current_mouse_down = null; 31 | let is_muted = store.get('mechvibes-muted') || false; 32 | let is_keyup = store.get('mechvibes-keyup') || false; 33 | let is_mousesounds = store.get('mechvibes-mouse') || true; 34 | let is_random = store.get('mechvibes-random') || false; 35 | let keyboardpacks = []; 36 | let mousepacks = []; 37 | const all_sound_files = {}; 38 | 39 | // ================================================== 40 | // load all pack 41 | async function loadPacks(status_display_elem, app_body) { 42 | // init 43 | status_display_elem.innerHTML = 'Loading...'; 44 | 45 | // get all audio folders 46 | const official_packs = await glob.sync(KEYBOARD_OFFICIAL_PACKS_DIR + '/*/'); 47 | const custom_packs = await glob.sync(KEYBOARD_CUSTOM_PACKS_DIR + '/*/'); 48 | const mouse_official_packs = await glob.sync(MOUSE_OFFICIAL_PACKS_DIR + '/*/'); 49 | const mouse_custom_packs = await glob.sync(MOUSE_CUSTOM_PACKS_DIR + '/*/'); 50 | const folders = [...official_packs, ...custom_packs]; 51 | const mouse_folders = [...mouse_official_packs, ...mouse_custom_packs]; 52 | 53 | var fucked = false 54 | 55 | // get pack data 56 | folders.map((folder) => { 57 | try{ 58 | // define group by types 59 | const is_custom = folder.indexOf('mechvibes_custom') > -1 ? true : false; 60 | 61 | // get folder name 62 | const splited = folder.split('/'); 63 | const folder_name = splited[splited.length - 2]; 64 | 65 | // define config file path 66 | const config_file = `${folder.replace(/\/$/, '')}/config.json`; 67 | 68 | // get pack info and defines data 69 | const { name, includes_numpad, sound = '', defines, key_define_type = 'single', compatibility = false } = require(config_file); 70 | 71 | // pack sound pack data 72 | const pack_data = { 73 | pack_id: `${is_custom ? 'custom' : 'default'}-${folder_name}`, 74 | group: is_custom ? 'Custom' : 'Default', 75 | abs_path: folder, 76 | key_define_type, 77 | compatibility, 78 | name, 79 | includes_numpad, 80 | }; 81 | 82 | // init sound data 83 | if (key_define_type == 'single') { 84 | // define sound path 85 | const sound_path = `${folder}${sound}`; 86 | const sound_data = new Howl({ src: [sound_path], sprite: keycodesRemap(defines) }); 87 | Object.assign(pack_data, { sound: sound_data }); 88 | all_sound_files[pack_data.pack_id] = false; 89 | // event when sound loaded 90 | sound_data.once('load', function () { 91 | all_sound_files[pack_data.pack_id] = true; 92 | checkIfAllSoundLoaded(status_display_elem, app_body); 93 | }); 94 | } else { 95 | const sound_data = {}; 96 | Object.keys(defines).map((kc) => { 97 | if (defines[kc]) { 98 | // define sound path 99 | const sound_path = `${folder}${defines[kc]}`; 100 | sound_data[kc] = new Howl({ src: [sound_path] }); 101 | all_sound_files[`${pack_data.pack_id}-${kc}`] = false; 102 | // event when sound_data loaded 103 | sound_data[kc].once('load', function () { 104 | all_sound_files[`${pack_data.pack_id}-${kc}`] = true; 105 | checkIfAllSoundLoaded(status_display_elem, app_body); 106 | }); 107 | } 108 | }); 109 | if (Object.keys(sound_data).length) { 110 | Object.assign(pack_data, { sound: keycodesRemap(sound_data) }); 111 | } 112 | } 113 | 114 | // push pack data to pack list 115 | keyboardpacks.push(pack_data); 116 | } catch(err){fucked = true} 117 | }); 118 | 119 | mouse_folders.map((folder) => { 120 | try{ 121 | // define group by types 122 | const is_custom = folder.indexOf('mousevibes_custom') > -1 ? true : false; 123 | 124 | // get folder name 125 | const splited = folder.split('/'); 126 | const folder_name = splited[splited.length - 2]; 127 | 128 | // define config file path 129 | const config_file = `${folder.replace(/\/$/, '')}/config.json`; 130 | 131 | // get pack info and defines data 132 | const { name, sound = '', defines, key_define_type = 'single'} = require(config_file); 133 | 134 | // pack sound pack data 135 | const pack_data = { 136 | pack_id: `${is_custom ? 'custom' : 'default'}-${folder_name}`, 137 | group: is_custom ? 'Custom' : 'Default', 138 | abs_path: folder, 139 | key_define_type, 140 | name, 141 | }; 142 | 143 | // init sound data 144 | if (key_define_type == 'single') { //This wont work, I still don't give a shit. Maybe?? 145 | // define sound path 146 | const sound_path = `${folder}${sound}`; 147 | const sound_data = new Howl({ src: [sound_path], sprite: keycodesRemap(defines) }); 148 | Object.assign(pack_data, { sound: sound_data }); 149 | all_sound_files[pack_data.pack_id] = false; 150 | // event when sound loaded 151 | sound_data.once('load', function () { 152 | all_sound_files[pack_data.pack_id] = true; 153 | checkIfAllSoundLoaded(status_display_elem, app_body); 154 | }); 155 | } else { 156 | const sound_data = {}; 157 | Object.keys(defines).map((kc) => { 158 | if (defines[kc]) { 159 | // define sound path 160 | const sound_path = `${folder}${defines[kc]}`; 161 | sound_data[kc] = new Howl({ src: [sound_path] }); 162 | all_sound_files[`${pack_data.pack_id}-${kc}`] = false; 163 | // event when sound_data loaded 164 | sound_data[kc].once('load', function () { 165 | all_sound_files[`${pack_data.pack_id}-${kc}`] = true; 166 | checkIfAllSoundLoaded(status_display_elem, app_body); 167 | }); 168 | } 169 | }); 170 | if (Object.keys(sound_data).length) { 171 | Object.assign(pack_data, { sound: keycodesRemap(sound_data) }); 172 | } 173 | } 174 | 175 | // push pack data to pack list 176 | mousepacks.push(pack_data); 177 | } catch(err){fucked = true} 178 | }); 179 | 180 | // end load 181 | return fucked; 182 | } 183 | 184 | 185 | // ================================================== 186 | // check if all packs loaded 187 | function checkIfAllSoundLoaded(status_display_elem, app_body) { 188 | Object.keys(all_sound_files).map((key) => { 189 | if (!all_sound_files[key]) { 190 | return false; 191 | } 192 | }); 193 | status_display_elem.innerHTML = 'Mechvibes++'; 194 | app_body.classList.remove('loading'); 195 | return true; 196 | } 197 | 198 | // ================================================== 199 | // remap keycodes from standard to os based keycodes 200 | function keycodesRemap(defines) { 201 | const sprite = remapper('standard', platform, defines); 202 | Object.keys(sprite).map((kc) => { 203 | sprite[`keycode-${kc}`] = sprite[kc]; 204 | delete sprite[kc]; 205 | }); 206 | return sprite; 207 | } 208 | 209 | // ================================================== 210 | // get pack by id, 211 | // if id is null, 212 | // get saved pack 213 | 214 | var packs = null 215 | function getPack(korm, pack_id = null) { 216 | if (!pack_id) { 217 | if (store.get(korm=='keyboard' ? MV_KEYBOARD_PACK_LSID : MV_MOUSE_PACK_LSID)) { 218 | pack_id = store.get(korm=='keyboard' ? MV_KEYBOARD_PACK_LSID : MV_MOUSE_PACK_LSID); 219 | 220 | if(korm=='keyboard'){ 221 | packs = keyboardpacks; 222 | }else{ 223 | packs = mousepacks; 224 | } 225 | 226 | if (!getPack(korm, pack_id)) { 227 | return packs[0]; 228 | } 229 | } else { 230 | return packs[0]; 231 | } 232 | } 233 | store.set(korm=='keyboard' ? MV_KEYBOARD_PACK_LSID : MV_MOUSE_PACK_LSID, pack_id); 234 | return packs.find((pack) => pack.pack_id == pack_id); 235 | } 236 | 237 | // ================================================== 238 | // transform pack to select option list 239 | function packsToOptions(packs, pack_list, korm) { 240 | // get saved pack id 241 | const selected_pack_id = store.get(korm=='keyboard' ? MV_KEYBOARD_PACK_LSID : MV_MOUSE_PACK_LSID); 242 | const groups = []; 243 | packs.map((pack) => { 244 | const exists = groups.find((group) => group.id == pack.group); 245 | if (!exists) { 246 | const group = { 247 | id: pack.group, 248 | name: pack.group || 'Default', 249 | packs: [pack], 250 | }; 251 | groups.push(group); 252 | } else { 253 | exists.packs.push(pack); 254 | } 255 | }); 256 | 257 | for (let group of groups) { 258 | const optgroup = document.createElement('optgroup'); 259 | optgroup.label = group.name; 260 | optgroup.class = group.name; 261 | for (let pack of group.packs) { 262 | // check if selected 263 | const is_selected = selected_pack_id == pack.pack_id; 264 | if (is_selected) { 265 | // pack current pack to saved pack 266 | if(korm=='keyboard'){ 267 | current_keyboard_pack = pack; 268 | } 269 | else{ 270 | current_mouse_pack = pack; 271 | } 272 | } 273 | // add pack to pack list 274 | const opt = document.createElement('option'); 275 | opt.text = pack.name; 276 | opt.value = pack.pack_id; 277 | opt.selected = is_selected ? 'selected' : false; 278 | optgroup.appendChild(opt); 279 | } 280 | pack_list.appendChild(optgroup); 281 | } 282 | 283 | // on select an option 284 | // update saved list id 285 | pack_list.addEventListener('change', (e) => { 286 | const selected_id = e.target.options[e.target.selectedIndex].value; 287 | store.set(korm=='keyboard' ? MV_KEYBOARD_PACK_LSID : MV_MOUSE_PACK_LSID, selected_id); 288 | if(korm=='keyboard'){ 289 | current_keyboard_pack = getPack(korm); 290 | } 291 | else{ 292 | current_mouse_pack = getPack(korm); 293 | } 294 | }); 295 | } 296 | 297 | // ================================================== 298 | // main 299 | (function (window, document) { 300 | window.addEventListener('DOMContentLoaded', async () => { 301 | const version = document.getElementById('app-version'); 302 | const update_available = document.getElementById('update-available'); 303 | const new_version = document.getElementById('new-version'); 304 | const app_logo = document.getElementById('logo'); 305 | const app_body = document.getElementById('app-body'); 306 | const keyboardpack_list = document.getElementById('keyboardpack-list'); 307 | const mousepack_list = document.getElementById('mousepack-list'); 308 | const volume_value = document.getElementById('keyboard-volume-value-display'); 309 | const volume = document.getElementById('keyvolume'); 310 | const mouse_volume_value = document.getElementById('mouse-volume-value-display'); 311 | const mouse_volume = document.getElementById('mousevolume'); 312 | const mouseslider = document.getElementById('MouseVolSlider'); 313 | const soundpackbug = document.getElementById('soundpack-bug'); 314 | const mouseNotification = document.getElementById('mouseSounds'); 315 | const ApplicationBody = document.getElementById('overall-body'); 316 | 317 | // set app version 318 | version.innerHTML = APP_VERSION; 319 | 320 | // load all packs 321 | var fuckcheck = await loadPacks(app_logo, app_body); 322 | 323 | if(fuckcheck){ 324 | soundpackbug.classList.remove('hidden'); 325 | } 326 | 327 | // transform packs to options list 328 | packsToOptions(keyboardpacks, keyboardpack_list, 'keyboard'); 329 | packsToOptions(mousepacks, mousepack_list, 'mouse'); 330 | 331 | if (current_keyboard_pack == null){ 332 | keyboardpack_list.selectedIndex = -1; 333 | } 334 | 335 | if (current_mouse_pack == null){ 336 | mousepack_list.selectedIndex = -1; 337 | } 338 | 339 | // check for new version 340 | fetch('https://api.github.com/repos/PyroCalzone/MechVibesPlusPlus/releases/latest') 341 | .then((res) => res.json()) 342 | .then((json) => { 343 | if (json.tag_name > APP_VERSION) { 344 | new_version.innerHTML = json.tag_name; 345 | update_available.classList.remove('hidden'); 346 | } 347 | }); 348 | 349 | // a little hack for open link in browser 350 | Array.from(document.getElementsByClassName('open-in-browser')).forEach((elem) => { 351 | elem.addEventListener('click', (e) => { 352 | e.preventDefault(); 353 | shell.openExternal(e.target.href); 354 | }); 355 | }); 356 | 357 | // get last selected pack 358 | try { 359 | current_keyboard_pack = getPack('keyboard'); 360 | current_mouse_pack = getPack('mouse'); 361 | } catch { 362 | soundpackbug.classList.remove('hidden'); 363 | }; 364 | 365 | // display volume value 366 | if (store.get(MV_KEY_VOL_LSID)) { 367 | volume.value = store.get(MV_KEY_VOL_LSID); 368 | }; 369 | 370 | volume_value.innerHTML = volume.value; 371 | volume.oninput = function (e) { 372 | volume_value.innerHTML = this.value; 373 | store.set(MV_KEY_VOL_LSID, this.value); 374 | }; 375 | 376 | if (store.get(MV_MOUSE_VOL_LSID)) { 377 | mouse_volume.value = store.get(MV_MOUSE_VOL_LSID); 378 | } 379 | mouse_volume_value.innerHTML = mouse_volume.value; 380 | mouse_volume.oninput = function (e) { 381 | mouse_volume_value.innerHTML = this.value; 382 | store.set(MV_MOUSE_VOL_LSID, this.value); 383 | }; 384 | 385 | function removeOptions(selectElement) { 386 | for(var i = 0; i>=500; i++) { 387 | selectElement.remove(0); 388 | } 389 | } 390 | 391 | ipcRenderer.on("refresh", async () => { 392 | const $ = require('jquery'); 393 | removeOptions(document.getElementById('keyboardpack-list')); 394 | $('#keyboardpack-list').find('optgroup').empty(); 395 | $('#keyboardpack-list').find('optgroup').remove(); 396 | removeOptions(document.getElementById('mousepack-list')); 397 | $('#mousepack-list').find('optgroup').empty(); 398 | $('#mousepack-list').find('optgroup').remove(); 399 | 400 | keyboardpacks = []; 401 | mousepacks = []; 402 | 403 | var fuckcheck2 = await loadPacks(app_logo, app_body) 404 | 405 | 406 | // transform packs to options list 407 | packsToOptions(keyboardpacks, keyboardpack_list, 'keyboard'); 408 | packsToOptions(mousepacks, mousepack_list, 'mouse'); 409 | 410 | app_logo.innerHTML = "Mechvibes++"; 411 | }) 412 | 413 | if (!is_muted) { 414 | iohook.start(); 415 | } 416 | 417 | // listen to key press 418 | ipcRenderer.on('muted', function (_event, _is_muted) { 419 | is_muted = _is_muted; 420 | if (is_muted) { 421 | iohook.stop(); 422 | } else { 423 | iohook.start(); 424 | } 425 | }); 426 | 427 | var playKeyupSound 428 | 429 | if(is_keyup){ 430 | playKeyupSound = true 431 | } 432 | 433 | ipcRenderer.on('theKeyup', function (_event, _is_keyup) { 434 | is_keyup = _is_keyup; 435 | if (is_keyup) { 436 | playKeyupSound = true 437 | } else { 438 | playKeyupSound = false 439 | } 440 | }); 441 | 442 | var playMouseSounds 443 | 444 | if(is_mousesounds){ 445 | playMouseSounds = true 446 | mouse_volume_value.classList.remove('hidden'); 447 | mouse_volume.classList.remove('hidden'); 448 | mousepack_list.classList.remove('hidden'); 449 | mouseslider.classList.remove('hidden'); 450 | mouseNotification.classList.add('hidden'); 451 | } 452 | 453 | ipcRenderer.on('MouseSounds', function (_event, _is_mousesounds) { 454 | is_mousesounds = _is_mousesounds; 455 | if (is_mousesounds) { 456 | playMouseSounds = true 457 | mouse_volume_value.classList.remove('hidden'); 458 | mouse_volume.classList.remove('hidden'); 459 | mousepack_list.classList.remove('hidden'); 460 | mouseslider.classList.remove('hidden'); 461 | mouseNotification.classList.add('hidden'); 462 | } else { 463 | playMouseSounds = false 464 | mouseslider.classList.add('hidden'); 465 | mousepack_list.classList.add('hidden'); 466 | mouse_volume_value.classList.add('hidden'); 467 | mouse_volume.classList.add('hidden'); 468 | mouseNotification.classList.remove('hidden'); 469 | } 470 | }); 471 | 472 | //Random Sounds 473 | var randomSounds 474 | 475 | if(is_random){ 476 | randomSounds = true 477 | } 478 | 479 | ipcRenderer.on('RandomSoundEnable', function (_event, _is_random) { 480 | is_random = _is_random; 481 | if (is_random) { 482 | randomSounds = true 483 | } else { 484 | randomSounds = false 485 | } 486 | }); 487 | 488 | iohook.on('mousedown', ({ button }) => { 489 | if(playMouseSounds){ 490 | if (current_mouse_down != null && current_mouse_down == button) { 491 | return; 492 | } 493 | 494 | current_mouse_down = button; 495 | 496 | const sound_id = `${current_mouse_down}`; 497 | 498 | if (current_mouse_pack) { 499 | playMouseSound(`${sound_id}`, store.get(MV_MOUSE_VOL_LSID), 'down') 500 | } 501 | } 502 | }) 503 | 504 | iohook.on('mouseup', () => { 505 | if(playMouseSounds){ 506 | playMouseSound(`${current_mouse_down}`, store.get(MV_MOUSE_VOL_LSID), 'up') 507 | } 508 | current_mouse_down = null; 509 | }) 510 | 511 | 512 | 513 | var keyPressedList = [] 514 | 515 | 516 | // if key released, clear current key 517 | iohook.on('keyup', ({ keycode }) => { 518 | if(playKeyupSound){ 519 | playSound(`${keycode}`, store.get(MV_KEY_VOL_LSID), playKeyupSound, 'up'); 520 | } 521 | try{ 522 | keyPressedList.splice(keyPressedList.indexOf(keycode), 1); 523 | } 524 | catch{ 525 | console.log("Caught bad keypress") 526 | } 527 | if(keyPressedList.length < 1){ 528 | app_logo.classList.remove('pressed'); 529 | } 530 | }); 531 | 532 | // key pressed, pack current key and play sound 533 | iohook.on('keydown', ({ keycode }) => { 534 | // if hold down a key, not repeat the sound 535 | if (keyPressedList.includes(keycode)) { 536 | return; 537 | } 538 | 539 | // display current pressed key 540 | // app_logo.innerHTML = keycode; 541 | app_logo.classList.add('pressed'); 542 | 543 | const applicablekeys = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83] 544 | const nonapplicablekeys = [57, 29, 3613, 42, 54, 58, 28, 15, 14, 56, 3640] 545 | 546 | keyPressedList.push(keycode); 547 | 548 | // pack current pressed key 549 | if(randomSounds && !nonapplicablekeys.includes(keycode)){ 550 | current_sound_key = applicablekeys[Math.floor(Math.random() * applicablekeys.length)]; 551 | } 552 | else{ 553 | current_sound_key = keycode; 554 | } 555 | 556 | 557 | var sound_id = `${current_sound_key}`; 558 | 559 | // get loaded audio object 560 | // if object valid, pack volume and play sound 561 | if (current_keyboard_pack) { 562 | if(playKeyupSound){ 563 | playSound(`${current_sound_key}`, store.get(MV_KEY_VOL_LSID), playKeyupSound, 'down'); 564 | } 565 | else{ 566 | playSound(sound_id, store.get(MV_KEY_VOL_LSID), playKeyupSound, 'null'); 567 | } 568 | } 569 | }); 570 | }); 571 | })(window, document); 572 | 573 | // ================================================== 574 | // universal play function 575 | function playSound(sound_id, volume, playKeyupSound, downOrUp) { 576 | 577 | var initOne 578 | var initTwo 579 | const pack_compatibility = current_keyboard_pack.compatibility ? current_keyboard_pack.compatibility : false; 580 | var keycode = `keycode-${sound_id}`; 581 | 582 | 583 | //!Setting keycode correct for compat packs! 584 | if(playKeyupSound && downOrUp == 'down' && pack_compatibility){ 585 | keycode = `keycode-0${sound_id}` 586 | } 587 | else if(playKeyupSound && downOrUp == 'up' && pack_compatibility){ 588 | keycode = `keycode-00${sound_id}` 589 | } 590 | 591 | const play_type = current_keyboard_pack.key_define_type ? current_keyboard_pack.key_define_type : 'single'; 592 | const sound = play_type == 'single' ? current_keyboard_pack.sound : current_keyboard_pack.sound[keycode]; 593 | if (!sound) { 594 | return; 595 | } 596 | 597 | //!!Splitting sound up for non compat packs!! -- DOWN SOUND ONLY 598 | var tempHoldings 599 | if(playKeyupSound && !pack_compatibility && downOrUp == 'down'){ 600 | if(play_type == 'single'){ 601 | tempHoldings = sound['_sprite'][keycode] 602 | initOne = sound['_sprite'][keycode][0] //Start Time 603 | initTwo = sound['_sprite'][keycode][1] //Length 604 | sound['_sprite'][keycode][1] = Math.floor(initTwo/2) //Length 605 | } 606 | else{ 607 | tempHoldings = sound['_sprite']['__default'] 608 | initOne = sound['_sprite']['__default'][0] //Start Time 609 | initTwo = sound['_sprite']['__default'][1] //Length 610 | sound['_sprite']['__default'][1] = Math.floor(initTwo/2) //Length 611 | } 612 | } 613 | 614 | else if(playKeyupSound && !pack_compatibility && downOrUp == 'up'){ 615 | if(play_type == 'single'){ 616 | tempHoldings = sound['_sprite'][keycode] 617 | initOne = sound['_sprite'][keycode][0] //Start Time 618 | initTwo = sound['_sprite'][keycode][1] //Length 619 | sound['_sprite'][keycode][0] = initOne+Math.floor((initTwo/2)) //Start Time 620 | sound['_sprite'][keycode][1] = Math.floor(initTwo/2) //Length 621 | } 622 | else{ 623 | tempHoldings = sound['_sprite']['__default'] 624 | initOne = sound['_sprite']['__default'][0] //Start Time 625 | initTwo = sound['_sprite']['__default'][1] //Length 626 | sound['_sprite']['__default'][0] = initOne+Math.floor((initTwo/2)) //Start Time 627 | sound['_sprite']['__default'][1] = Math.floor(initTwo/2) //Length 628 | } 629 | } 630 | 631 | 632 | sound.volume(Number(volume / 100)); 633 | if (play_type == 'single') { 634 | sound.play(keycode); 635 | } else { 636 | sound.play(); 637 | } 638 | 639 | //Resetting values for non compat packs 640 | if(playKeyupSound && !pack_compatibility){ 641 | if(play_type=='single'){ 642 | sound['_sprite'][keycode][0] = initOne 643 | sound['_sprite'][keycode][1] = initTwo 644 | } 645 | else{ 646 | sound['_sprite']['__default'][0] = initOne 647 | sound['_sprite']['__default'][1] = initTwo 648 | } 649 | } 650 | } 651 | 652 | function playMouseSound(mouseCode, volume, downOrUp){ 653 | var keycode = `keycode-${mouseCode}`; 654 | 655 | if(downOrUp == 'down'){ 656 | keycode = `keycode-${mouseCode}`; 657 | } 658 | else if(downOrUp == 'up'){ 659 | keycode = `keycode-0${mouseCode}`; 660 | } 661 | 662 | const play_type = current_mouse_pack.key_define_type ? current_mouse_pack.key_define_type : 'single'; 663 | const sound = play_type == 'single' ? current_mouse_pack.sound : current_mouse_pack.sound[keycode]; 664 | if (!sound) { 665 | return; 666 | } 667 | 668 | sound.volume(Number(volume / 100)); 669 | if (play_type == 'single') { 670 | sound.play(keycode); 671 | } else { 672 | sound.play(); 673 | } 674 | } --------------------------------------------------------------------------------