├── .github └── workflows │ ├── deploy.yml │ └── test-deploy.yml ├── .gitignore ├── LICENSE ├── README.md ├── babel.config.js ├── blog ├── 2019-05-28-first-blog-post.md ├── 2019-05-29-long-blog-post.md ├── 2021-08-01-mdx-blog-post.mdx ├── 2021-08-26-welcome │ ├── docusaurus-plushie-banner.jpeg │ └── index.md └── authors.yml ├── docs ├── 3D.md ├── faq.md ├── firmware │ ├── _category_.json │ ├── img │ │ ├── docsVersionDropdown.png │ │ └── localeDropdown.png │ ├── keyboard.md │ ├── power.md │ └── rgb-led.md ├── getting-started.md ├── hardware │ ├── _category_.json │ ├── img │ │ ├── docsVersionDropdown.png │ │ └── localeDropdown.png │ ├── pinouts.md │ ├── schematic.md │ └── specs.md └── software │ ├── _category_.json │ ├── img │ ├── docsVersionDropdown.png │ └── localeDropdown.png │ ├── linux-drivers.md │ └── os-image.md ├── docusaurus.config.js ├── package-lock.json ├── package.json ├── sidebars.js ├── src ├── components │ ├── HomepageDiagram │ │ ├── index.js │ │ └── styles.module.css │ ├── HomepageFeatures │ │ ├── index.js │ │ └── styles.module.css │ └── HomepageVideos │ │ ├── index.js │ │ └── styles.module.css ├── css │ └── custom.css └── pages │ ├── gallery │ └── index.js │ ├── index.js │ ├── index.module.css │ └── markdown-page.md ├── static ├── .nojekyll ├── CNAME ├── fonts │ ├── NimbusSanL-BolIta.woff │ └── NimbusSanL-BolIta.woff2 └── img │ ├── Raspberry_Pi_Logo.svg │ ├── beepy-diagram-full.png │ ├── beepy-diagram-full.svg │ ├── beepy-edc.jpg │ ├── beepy-fruitforscale-2048x1443.jpg │ ├── beepy-header-breakout.svg │ ├── beepy-header-mount-diagram.jpg │ ├── beepy-header.png │ ├── beepy-social-card.jpg │ ├── beepy-tuir-reddit.jpg │ ├── beepy-v1-3D-render.png │ ├── clear-sandwich-back.jpg │ ├── clear-sandwich-dimensions.jpg │ ├── clear-sandwich-front.jpg │ ├── docusaurus.png │ ├── favicon.ico │ ├── feature-keyboard.svg │ ├── feature-raspberrypizero.svg │ ├── feature-sharpdisplay-400x240.svg │ ├── logo.svg │ ├── sqfmi_logo_32x32.svg │ ├── symbol-keys.png │ ├── undraw_docusaurus_mountain.svg │ ├── undraw_docusaurus_react.svg │ └── undraw_docusaurus_tree.svg └── yarn.lock /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to GitHub Pages 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | # Review gh actions docs if you want to further define triggers, paths, etc 8 | # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on 9 | 10 | permissions: 11 | contents: write 12 | 13 | jobs: 14 | deploy: 15 | name: Deploy to GitHub Pages 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v3 19 | - uses: actions/setup-node@v3 20 | with: 21 | node-version: 18 22 | cache: yarn 23 | 24 | - name: Install dependencies 25 | run: yarn install --frozen-lockfile 26 | - name: Build website 27 | run: yarn build 28 | 29 | # Popular action to deploy to GitHub Pages: 30 | # Docs: https://github.com/peaceiris/actions-gh-pages#%EF%B8%8F-docusaurus 31 | - name: Deploy to GitHub Pages 32 | uses: peaceiris/actions-gh-pages@v3 33 | with: 34 | github_token: ${{ secrets.GITHUB_TOKEN }} 35 | # Build output to publish to the `gh-pages` branch: 36 | publish_dir: ./build 37 | # The following lines assign commit authorship to the official 38 | # GH-Actions bot for deploys to `gh-pages` branch: 39 | # https://github.com/actions/checkout/issues/13#issuecomment-724415212 40 | # The GH actions bot is used by default if you didn't specify the two fields. 41 | # You can swap them out with your own user credentials. 42 | user_name: github-actions[bot] 43 | user_email: 41898282+github-actions[bot]@users.noreply.github.com 44 | -------------------------------------------------------------------------------- /.github/workflows/test-deploy.yml: -------------------------------------------------------------------------------- 1 | name: Test deployment 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | # Review gh actions docs if you want to further define triggers, paths, etc 8 | # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on 9 | 10 | jobs: 11 | test-deploy: 12 | name: Test deployment 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v3 16 | - uses: actions/setup-node@v3 17 | with: 18 | node-version: 18 19 | cache: yarn 20 | 21 | - name: Install dependencies 22 | run: yarn install --frozen-lockfile 23 | - name: Test build website 24 | run: yarn build -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 SQFMI 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Technical documentation for SQFMI Beepy 2 | 3 | Documentation site for the SQFMI Beepy. Beepy is a portable computing device, 4 | with a high contrast, high resolution display, and a tactile keyboard + 5 | touchpad powered by Raspberry Pi Zero W (or any other compatible SBC). 6 | 7 | To see the live version of this documentation visit 8 | [beepy.sqfmi.com/docs/getting-started](https://beepy.sqfmi.com/docs/getting-started). 9 | 10 | This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. 11 | 12 | ### Installation 13 | 14 | ``` 15 | $ yarn 16 | ``` 17 | 18 | ### Local Development 19 | 20 | ``` 21 | $ yarn start 22 | ``` 23 | 24 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 25 | 26 | ### Build 27 | 28 | ``` 29 | $ yarn build 30 | ``` 31 | 32 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 33 | 34 | ### Deployment 35 | 36 | Using SSH: 37 | 38 | ``` 39 | $ USE_SSH=true yarn deploy 40 | ``` 41 | 42 | Not using SSH: 43 | 44 | ``` 45 | $ GIT_USER= yarn deploy 46 | ``` 47 | 48 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. 49 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /blog/2019-05-28-first-blog-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: first-blog-post 3 | title: First Blog Post 4 | authors: 5 | name: Gao Wei 6 | title: Docusaurus Core Team 7 | url: https://github.com/wgao19 8 | image_url: https://github.com/wgao19.png 9 | tags: [hola, docusaurus] 10 | --- 11 | 12 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet 13 | -------------------------------------------------------------------------------- /blog/2019-05-29-long-blog-post.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: long-blog-post 3 | title: Long Blog Post 4 | authors: endi 5 | tags: [hello, docusaurus] 6 | --- 7 | 8 | This is the summary of a very long blog post, 9 | 10 | Use a `` comment to limit blog post size in the list view. 11 | 12 | 13 | 14 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet 15 | 16 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet 17 | 18 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet 19 | 20 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet 21 | 22 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet 23 | 24 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet 25 | 26 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet 27 | 28 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet 29 | 30 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet 31 | 32 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet 33 | 34 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet 35 | 36 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet 37 | 38 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet 39 | 40 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet 41 | 42 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet 43 | 44 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet 45 | -------------------------------------------------------------------------------- /blog/2021-08-01-mdx-blog-post.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | slug: mdx-blog-post 3 | title: MDX Blog Post 4 | authors: [slorber] 5 | tags: [docusaurus] 6 | --- 7 | 8 | Blog posts support [Docusaurus Markdown features](https://docusaurus.io/docs/markdown-features), such as [MDX](https://mdxjs.com/). 9 | 10 | :::tip 11 | 12 | Use the power of React to create interactive blog posts. 13 | 14 | ```js 15 | 16 | ``` 17 | 18 | 19 | 20 | ::: 21 | -------------------------------------------------------------------------------- /blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg -------------------------------------------------------------------------------- /blog/2021-08-26-welcome/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: welcome 3 | title: Welcome 4 | authors: [slorber, yangshun] 5 | tags: [facebook, hello, docusaurus] 6 | --- 7 | 8 | [Docusaurus blogging features](https://docusaurus.io/docs/blog) are powered by the [blog plugin](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-blog). 9 | 10 | Simply add Markdown files (or folders) to the `blog` directory. 11 | 12 | Regular blog authors can be added to `authors.yml`. 13 | 14 | The blog post date can be extracted from filenames, such as: 15 | 16 | - `2019-05-30-welcome.md` 17 | - `2019-05-30-welcome/index.md` 18 | 19 | A blog post folder can be convenient to co-locate blog post images: 20 | 21 | ![Docusaurus Plushie](./docusaurus-plushie-banner.jpeg) 22 | 23 | The blog supports tags as well! 24 | 25 | **And if you don't want a blog**: just delete this directory, and use `blog: false` in your Docusaurus config. 26 | -------------------------------------------------------------------------------- /blog/authors.yml: -------------------------------------------------------------------------------- 1 | endi: 2 | name: Endilie Yacop Sucipto 3 | title: Maintainer of Docusaurus 4 | url: https://github.com/endiliey 5 | image_url: https://github.com/endiliey.png 6 | 7 | yangshun: 8 | name: Yangshun Tay 9 | title: Front End Engineer @ Facebook 10 | url: https://github.com/yangshun 11 | image_url: https://github.com/yangshun.png 12 | 13 | slorber: 14 | name: Sébastien Lorber 15 | title: Docusaurus maintainer 16 | url: https://sebastienlorber.com 17 | image_url: https://github.com/slorber.png 18 | -------------------------------------------------------------------------------- /docs/3D.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | --- 4 | 5 | # Case Designs & 3D Models 6 | 7 | ## Beepy STEP model 8 | 9 | 10 | 11 | 12 | [**beepy-v1.step**](https://github.com/sqfmi/beepy-hardware/blob/main/3D/beepy-device/beepy-v1.step) 13 | 14 | ## Case Designs 15 | 16 | Below are some case designs for the Beepy. If you have any designs you'd like to share with the community, please submit a Pull Request to this repo (include a brief description and some renders/pics): [**https://github.com/sqfmi/beepy-hardware**](https://github.com/sqfmi/beepy-hardware). 17 | 18 | 19 | ### Clear Sandwich 20 | [**Buy Now!**](https://shop.sqfmi.com/products/beepy-enclosure-clear-sandwich) 21 | 22 | 23 | ____ 24 | 25 | 26 | 27 | #### Instructions 28 | 1. Remove the top screws and the SD card from the Raspberry Pi 29 | 2. Align the back plate and tighten the 9mm screws on top. Make sure the battery is sitting securely. You can use the packaging foam for a snug fit. 30 | 3. Align the front plate and tighten the 5mm screws on top and the 12mm screws in the bottom 31 | 32 | ### V1 33 | V1 design of a Beepy case, suitable for 3D printing, requires some tweaking for a proper fit. Screws are M2.5x5mm. 34 | 35 | 36 | [**STLs and STEP model**](https://github.com/sqfmi/beepy-hardware/tree/main/3D/beepy-cases/v1) 37 | 38 | ### Slim Flat 39 | 40 | Slim, flat, minimal case for the Beepy 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | [**STLs and STEP model**](https://github.com/sqfmi/beepy-hardware/tree/main/3D/beepy-cases/slim_flat) 49 | 50 | ### CNC Case 51 | 52 | Coming Soon -------------------------------------------------------------------------------- /docs/faq.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | --- 4 | 5 | # FAQ 6 | 7 | ### What's a Beepy? 8 | 9 | Beepy is a portable computing device, with a beautiful high contrast, high resolution display, and a tactile keyboard + touchpad, it is the ultimate everyday hacking gadget. 10 | 11 | Powered by the Raspberry Pi Zero W (or any other compatible SBCs), you can use it as a chat device (supporting all chat networks on Beeper e.g. iMessage/WhatsApp/Signal/etc. ), or use it as a hackable handheld cyberdeck, running any Linux application that runs on the Pi. 12 | 13 | ### What is Beeper? 14 | 15 | Beeper is a universal chat app. It’s a single app to chat with friends on 15 different chat networks. 16 | 17 | Learn more at https://www.beeper.com 18 | 19 | ### Does it have LTE/4G/5G/LoRA/Zigbee/GPS/etc. connectivity? 20 | 21 | Additional connectivity can be expanded via USB or GPIO ports. 22 | 23 | ### Does Beepy come with a case? 24 | 25 | No, but you can [3D print your own case](/docs/3D). We'll be offering a case soon. Beepy can also be used as is (with the addition of a rubber band). 26 | 27 | ### My Beepy LED is always on 28 | 29 | You may be running an older version of the firmware, follow the firmware flashing instructions to [**update the firmware**](/docs/getting-started#software-setup). 30 | 31 | ### I just opened the box and have no idea what to do 32 | 33 | First you need to follow the instructions to [flash an SD card with the OS](/docs/getting-started), then make sure the battery is charged by plugging in the USB C port and flipping the power switch. 34 | 35 | ### Help, the screen is stuck displaying a very striking static pattern, even after I've flashed the SD card 36 | 37 | Follow the [Getting Started](/docs/getting-started#software-setup) guide and run the install script before the screen can display anything. 38 | 39 | ### I set my WiFi SSID and password in the Pi imager but it can't seem to connect 40 | 41 | The Pi Zero W only supports 2.4GHz WiFi networks. Make sure you're not trying to connect to a 5GHz network. 42 | 43 | ### I prefer a white background with black text 44 | 45 | You can invert the display mode by running `echo 1 | sudo tee /sys/module/sharp_drm/parameters/mono_invert` 46 | 47 | ### My display contrast is too low 48 | 49 | You can modify the display constrast by changing the value in `/sys/module/sharp_drm/parameters/mono_cutoff` - the default is 32. 50 | 51 | If this is your first time booting up and you see a mostly blank screen with a vague raspberry shape in the top left and some scattered patches of black towards the middle then your image is probably set to boot into the desktop environment. You can make the desktop more legible by setting a `mono_cutoff` of `195` or disable it through `raspi-config`. 52 | 53 | ### How can I found the IP address of Beepy on my network? 54 | 55 | You can check your router's config page for the list of connected device and look for the IP address 56 | 57 | -or- 58 | 59 | Run a network scan using the command `sudo arp-scan --localnet`. This will list IP addresses of all devices in your local network -------------------------------------------------------------------------------- /docs/firmware/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Firmware", 3 | "position": 3, 4 | "link": { 5 | "type": "generated-index" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /docs/firmware/img/docsVersionDropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/docs/firmware/img/docsVersionDropdown.png -------------------------------------------------------------------------------- /docs/firmware/img/localeDropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/docs/firmware/img/localeDropdown.png -------------------------------------------------------------------------------- /docs/firmware/keyboard.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Keyboard Firmware 6 | 7 | The keyboard firmware is a fork of [i2c_puppet](https://github.com/solderparty/i2c_puppet) with a few additional features to support the Beepy. 8 | 9 | You can download the latest version of the Beepy firmware here: https://github.com/ardangelo/beepberry-rp2040/releases/latest/download/i2c_puppet.uf2 10 | 11 | ## Basic key mappings 12 | 13 | - Call is mapped to Control 14 | - "Berry" key is mapped to Tmux prefix (customize the prefix in the keymap file) 15 | - Touchpad click enters Meta mode (see the section on Meta mode). Double click enters touchpad scroll mode 16 | - Back is mapped to Escape 17 | - Holding "End Call" safely shuts down the Pi 18 | - Physical Alt is mapped to symbols printed on the keycap 19 | - Symbol is mapped to AltGr (Right Alt), mapped to more symbols via the keymap file 20 | - Physical Alt + Enter is mapped to Tab 21 | 22 | ## Alt and Sym modifiers 23 | 24 | The alternate symbols printed directly on the Beepy keys are triggered by pressing the physical Alt key, then the key on which the symbol is printed. For additional symbols not printed directly on the keys, the Sym key is used. 25 | 26 | ### Symbol key map 27 | 28 | 29 | 30 | ### Sticky modifier keys 31 | 32 | The keyboard driver supports sticky modifier keys. Holding a modifier key (Shift, Alt, Sym) while typing an alpha keys will apply the modifier to all alpha keys until the modifier is released. 33 | 34 | One press and release of the modifier will enter sticky mode, applying the modifier to the next alpha key only. If the same modifier key is pressed and released again in sticky mode, it will be canceled. 35 | 36 | Visual mode indicators are drawn in the top right corner of the display, with indicators for Shift, Physical Alt, Control, Alt, Symbol, and Meta mode. 37 | 38 | ## Meta mode 39 | 40 | Meta mode is a modal layer that assists in rapidly moving the cursor and scrolling with single keypresses. To enter Meta mode, click the touchpad button once. Then, the following keymap is applied, staying in Meta mode until dismissed: 41 | 42 | - E: up, S: down, W: left, D: right 43 | - Why not WASD? This way, you can place your thumb in the middle of all four of these keys, and more fluidly move the cursor without mistyping 44 | - R: Home, F: End, O: PageUp, P: PageDown 45 | - Q: Alt+Left (back one word), A: Alt+Right (forward one word) 46 | - T: Tab (dismisses Meta mode) 47 | - X: Apply Control to next key (dismisses Meta mode) 48 | - C: Apply Alt to next key (dismisses Meta mode) 49 | - 0: Toggle display black/white inversion 50 | - N: Decrease keyboard backlight brightness 51 | - M: Increase keyboard backlight brightness 52 | - $: Toggle keyboard backlight 53 | - Touchpad click (while in Meta mode): Enable touchpad scroll mode (up and down arrrow keys) 54 | - Other Meta mode keys will continue to work as normal 55 | - Exiting meta mode will also exit touchpad scroll mode 56 | - Subsequent clicks of the touchpad will type Enter. 57 | - Esc: ("Back" button): exit meta mode 58 | 59 | Typing any other key while in Meta mode will exit Meta mode and send the key as if it was typed normally. 60 | 61 | ## `sysfs` Interface 62 | 63 | The following sysfs entries are available under `/sys/firmware/beepy`: 64 | 65 | - `led`: 0 to disable LED, 1 to enable. Write-only 66 | - `led_red`, `led_green`, `led_blue`: set LED color intensity from 0 to 255. Write- only 67 | - `keyboard_backlight`: set keyboard brightness from 0 to 255. Write-only 68 | - `battery_raw`: raw numerical battery level as reported by firmware. Read-only 69 | - `battery_volts`: battery voltage estimation. Read-only 70 | - `battery_percent`: battery percentage estimation. Read-only 71 | 72 | ## Module parameters 73 | 74 | Write to `/sys/module/beepy_kbd/parameters/` to set, or unload and reload the module with `beepy-kbd param=val`. 75 | 76 | - `touchpad`: one of `meta` or `keys` 77 | - `meta`: default, will use the touchpad button to enable or disable Meta mode 78 | - `keys`: touchpad always on, swiping sends arrow keys, clicking sends Enter 79 | 80 | ## Custom Keymap 81 | 82 | The Alt and Sym keymaps and the Tmux prefix sent by the "Berry" key can be edited in the file `/usr/share/kbd/keymaps/beepy-kbd.map`. To reapply the keymap without rebooting, run `loadkeys /usr/share/kbd/keymaps/beepy-kbd.map`. 83 | -------------------------------------------------------------------------------- /docs/firmware/power.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Power Management & Battery 6 | 7 | The onboard RP2040 controls the power to the Pi, as well as measuring the battery level with its ADC. The Beepy can be safely shutdown by holding the "End Call" button on the keyboard. 8 | 9 | To battery voltage on the Beepy can read from the register ```0x17``` over I2C. This is a read-only register, it is 2 bytes in size. It returns a 16 bit value from the ADC (VREF = 3.3V). There is a voltage divider so the battery voltage can be calculated as VBAT = 3.3V * (value/4095) * 2. 10 | 11 | ## Examples 12 | 13 | ### Battery Level Reporting 14 | 15 | The following sysfs entries are available under `/sys/firmware/beepy` to read the system battery level: 16 | 17 | - `battery_raw`: raw numerical battery level as reported by firmware. Read-only 18 | - `battery_volts`: battery voltage estimation. Read-only 19 | - `battery_percent`: battery percentage estimation. Read-only 20 | 21 | ## Script 22 | 23 | The following script is an example to calculate a voltage estimation from the raw battery level: 24 | 25 | ``` 26 | #!/bin/sh 27 | 28 | V=$(cat /sys/firmware/beepy/battery_raw) 29 | 30 | V=$(echo "obase=10; ibase=16; $V" | bc) 31 | echo "$V * 3.3 * 2 / 4095" | bc -l | cut -c1-5 32 | ``` 33 | 34 | ### Sleep/Wake 35 | 36 | To Do -------------------------------------------------------------------------------- /docs/firmware/rgb-led.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # RGB LED 6 | 7 | The following sysfs entries are available under `/sys/firmware/beepy`: 8 | 9 | - `led`: 0 to disable LED, 1 to enable. Write-only 10 | - `led_red`, `led_green`, `led_blue`: set LED color intensity from 0 to 255. Write- only 11 | 12 | ## RGB LED over I2C 13 | 14 | The RGB LED is connected to the RP2040. When the keyboard driver is unloaded via `rmmod beepy-kbd`, they can be controlled directly by the Pi via [I²C](https://en.wikipedia.org/wiki/I²C). 15 | 16 | The LED color on the Beepy is exposed on I2C bus 1 at the chip address `0x1F`. 17 | 18 | Controls are available at the following specific data addresses: 19 | 20 | | Function | Read | Write | 21 | |----------|--------|--------| 22 | | Power | `0x20` | `0xA0` | 23 | | Red | `0x21` | `0xA1` | 24 | | Green | `0x22` | `0xA2` | 25 | | Blue | `0x23` | `0xA3` | 26 | 27 | To get/set the LED color on the Beepy, you can read/write to the above registers over I2C. The values are in the range of ```0x00``` - ```0xFF```. 28 | 29 | *Note: write addresses are the read address masked with ```0x80```.* 30 | 31 | A value of 0 in the power register represents the LED's off state, while any other value represents on. 32 | 33 | ## Example 34 | 35 | To set the RGB values to red and turn the LED on from the command line: 36 | 37 | ```bash 38 | # Format: 39 | # i2cset -y [i2cbus] [chip-address] [data-address] value 40 | i2cset -y 1 0x1F 0xA1 0xFF 41 | i2cset -y 1 0x1F 0xA2 0x00 42 | i2cset -y 1 0x1F 0xA3 0x00 43 | i2cset -y 1 0x1F 0xA0 0xFF 44 | ``` 45 | -------------------------------------------------------------------------------- /docs/getting-started.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Getting Started 6 | 7 | Follow these steps to setup your Beepy. Out of the box, the display will only show static. If you see yellow lines on the display, ***that is the screen protector*** and can be removed. 8 | 9 | ## 1. Hardware Setup 10 | 11 | If you are installing your own Raspberry Pi Zero or any other SBC, make sure all the mounting pins are properly aligned to each hole before tightening the screws. **If you cannot see the pin through a header hole, then it is not properly mounted**. You can move the board around until all the pins "click" into place. You can skip this step if the Pi is already pre-installed. 12 | 13 | Beepy Raspberry Pi Zero mounting diagram 14 | 15 | The USB-C port at the bottom powers and charges the Beepy. **Do not power the Raspberry Pi Zero through its Micro-USB port (PWR IN).** 16 | 17 | ## 2. Firmware Update 18 | 19 | Update Beepy's firmware to ensure driver compatibility and the latest device features: 20 | 21 | - Download the [latest firmware image](https://github.com/ardangelo/beepberry-rp2040/releases/latest/download/i2c_puppet.uf2) 22 | - Slide the power switch off (left if facing up) 23 | - Connect the Beepy to your computer via USB-C 24 | - While holding the "End Call" key (top right on the keypad), slide the power switch on 25 | - The Beepy will present itself as a USB mass storage device, drag'n'drop the new firmware (i2c_puppet.uf2) into the drive and it will reboot with the new firmware 26 | - Note: The LED will remain green until the driver packages below are installed and the system has rebooted 27 | 28 | ## 3. Choose an Operating System 29 | 30 | There are two choices of operating systems to run on your Beepy 31 | 32 | - Raspbian: a powerful, customizable distribution with all the bells and whistles 33 | - Buildroot: a slimmed-down, Beepy-centric image with a fast boot 34 | 35 | ### Setting up a Raspbian System 36 | 37 | 1. Use the [Raspberry Pi Imager tool](https://www.raspberrypi.com/software/) to flash an SD card with the Raspberry Pi OS ***Lite*** image 38 | - Choose OS - Raspberry Pi OS (other) - ***Raspberry Pi OS Lite (32-bit) image*** 39 | - Click the gear icon ⚙ (or press ```CTRL + SHIFT + X```) to set the username, password, hostname, WiFi, and enable SSH 40 | - Make sure your computer and the Pi are on the same WiFi network in order to SSH in later 41 | 42 | 2. SSH into your Beepy and install the driver packages 43 | 44 | ```bash 45 | curl -s --compressed "https://ardangelo.github.io/beepy-ppa/KEY.gpg" | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/beepy.gpg >/dev/null \ 46 | && sudo curl -s --compressed -o /etc/apt/sources.list.d/beepy.list "https://ardangelo.github.io/beepy-ppa/beepy.list" \ 47 | && sudo apt update \ 48 | && sudo apt-get -y install beepy-kbd sharp-drm \ 49 | && sudo shutdown -r now 50 | ``` 51 | 52 | 3. Your Beepy with is now ready, enjoy! 53 | 54 | - Review the [default symbol keymap](/docs/firmware/keyboard#symbol-key-map) 55 | 56 | ### Setting up a Buildroot System 57 | 58 | Buildroot is a slimmed-down, Beepy-centric image with a fast boot, compatible with the Raspberry Pi Zero 2 W. It is automatically set up with Beepy device drivers and a set of useful software. Tailored for on-the-go communication, it ships with the following applications: 59 | 60 | * `gomuks` - Beeper command line client 61 | * `mosh` - Mobile remote shell 62 | * `w3m` - Text based browser 63 | * `aerc` - Command line email client 64 | * `nmtui` - Network management 65 | * Python 3 66 | 67 | To use the Beepy Buildroot image, download and flash the latest release here: 68 | 69 | https://github.com/ardangelo/beepberry-buildroot/releases 70 | 71 | The initial boot will take about 30 seconds to resize disk partitions to fill your SD card. Subsequent boots take around 8 seconds from power-on to Tmux. 72 | 73 | * Configure timezone: edit `/boot/timezone.txt` 74 | * Configure Wi-Fi: use `nmtui` or edit `/boot/wlan/.psk` 75 | * Updating Buildroot image: reflash SD card, or run `sudo update_buildroot` 76 | 77 | Review the [default symbol keymap](/docs/firmware/keyboard#symbol-key-map) 78 | 79 | ## Powering on/off your Beepy 80 | 81 | Long holding the "End Call" key (5 seconds) will trigger the key ```KEY_POWER``` and safely shutdown the Pi. The LED will turn red until OS shutdown has completed. 82 | 83 | Please wait another few seconds until the disk activity light has turned off to ensure disks are synced. 84 | 85 | After shutting down using the "End Call" key, holding the key for 1 second will turn the Pi back on. 86 | 87 | ## Changing Font Size 88 | 89 | In ```/boot/cmdline.txt```, edit ```fbcon=font:VGA8x8``` to change the font/size. The next largest size is `VGA8x16`. See [fbcon](https://www.kernel.org/doc/Documentation/fb/fbcon.txt) for more details. 90 | 91 | ## Join the Beepy Discord! 92 | 93 | [**Discord Invite**](https://discord.gg/QERrSferdF) 94 | 95 | ### Matrix Bridge 96 | 97 | [**#beepy-general**](https://matrix.to/#/#beepberry-general:beeper.com) 98 | 99 | [**#beepy-dev**](https://matrix.to/#/#beepberry-dev:beeper.com) 100 | 101 | [**#beepy-apps**](https://matrix.to/#/#beepberry-apps:beeper.com) 102 | 103 | [**#beepy-hw**](https://matrix.to/#/#beepberry-hw:beeper.com) 104 | -------------------------------------------------------------------------------- /docs/hardware/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Hardware", 3 | "position": 3, 4 | "link": { 5 | "type": "generated-index" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /docs/hardware/img/docsVersionDropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/docs/hardware/img/docsVersionDropdown.png -------------------------------------------------------------------------------- /docs/hardware/img/localeDropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/docs/hardware/img/localeDropdown.png -------------------------------------------------------------------------------- /docs/hardware/pinouts.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Pinouts 6 | 7 | ## Raspberry Pi Header Breakout 8 | 9 | 10 | 11 | ## RGB LED 12 | 13 | | RGB LED | RP2040 Pins | 14 | |---------|-------------| 15 | | Red | GPIO 20 | 16 | | Green | GPIO 19 | 17 | | Blue | GPIO 17 | 18 | 19 | ## Programmable Button 20 | 21 | Pi GPIO 17 22 | 23 | ## Display 24 | 25 | | Display | Pi Pins | 26 | |---------|---------| 27 | | SCK | GPIO 11 | 28 | | SDI | GPIO 10 | 29 | | CS | GPIO 8 | 30 | | EXTIN | GPIO 23 | 31 | 32 | ## Keyboard 33 | 34 | | Keyboard | Pi Pins | RP2040 Pins | 35 | |----------|---------|-------------| 36 | | SDA | GPIO 2 | GPIO 28 | 37 | | SCL | GPIO 3 | GPIO 29 | 38 | | INT | GPIO 4 | GPIO 0 | 39 | 40 | ## SWD Header 41 | 42 | ## Power Management 43 | 44 | | Power Management | Pi Pins | RP2040 Pins | 45 | |--------------------|---------|-------------| 46 | | Pi Power Switch | - | GPIO 15 | 47 | | Pi Shutdown Signal | GPIO 26 | GPIO 21 | 48 | | Battery ADC | - | GPIO 26 | 49 | -------------------------------------------------------------------------------- /docs/hardware/schematic.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Schematic 6 | 7 | [beepy-schematic-v1.pdf](https://github.com/sqfmi/beepy-hardware/blob/main/KiCad/beepy-schematic-v1.pdf) 8 | 9 | ## KiCad 10 | 11 | The KiCad files can be found on [GitHub](https://github.com/sqfmi/beepy-hardware). 12 | 13 | ## Keyboard 14 | 15 | The keyboard's schematic is based on the [BBQ20KBD](https://www.tindie.com/products/arturo182/bb-q20-keyboard-with-trackpad-usbi2cpmod/), an open source design by [Solder Party](https://www.solder.party/). The BBQ20KBD is a BB Q20 Keyboard in USB/PMOD/Qwiic format with a injection molded clear plastic case. Learn more about it [here!](https://www.solder.party/docs/bbq20kbd/) 16 | 17 | -------------------------------------------------------------------------------- /docs/hardware/specs.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Tech Specs 6 | 7 | ![Beepy Technical Diagram](/img/beepy-diagram-full.svg) 8 | 9 | - Ultra-low power high contrast Sharp Memory LCD 2.7″ 400 x 240 10 | - Raspberry Pi Zero W (optional) with compatible low profile solderless header 11 | - Tactile keyboard w/ backlight and touchpad 12 | - Programmable RGB LED for notifications 13 | - Programmable side button 14 | - Onboard RP2040 MCU (for keyboard and peripherals control) 15 | - GPIOs breakout 16 | - USB-C programming & charging 17 | - 2000mAh LiPo battery 18 | - 74mm x 104mm x 15mm -------------------------------------------------------------------------------- /docs/software/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Software", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /docs/software/img/docsVersionDropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/docs/software/img/docsVersionDropdown.png -------------------------------------------------------------------------------- /docs/software/img/localeDropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/docs/software/img/localeDropdown.png -------------------------------------------------------------------------------- /docs/software/linux-drivers.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # RGB LED 6 | 7 | The following sysfs entries are available under `/sys/firmware/beepy`: 8 | 9 | - `led`: 0 to disable LED, 1 to enable. Write-only 10 | - `led_red`, `led_green`, `led_blue`: set LED color intensity from 0 to 255. Write- only 11 | 12 | ## RGB LED over I2C 13 | 14 | The RGB LED is connected to the RP2040. When the keyboard driver is unloaded via `rmmod beepy-kbd`, they can be controlled directly by the Pi via [I²C](https://en.wikipedia.org/wiki/I²C). 15 | 16 | The LED color on the Beepy is exposed on I2C bus 1 at the chip address `0x1F`. 17 | 18 | Controls are available at the following specific data addresses: 19 | 20 | | Function | Read | Write | 21 | |----------|--------|--------| 22 | | Power | `0x20` | `0xA0` | 23 | | Red | `0x21` | `0xA1` | 24 | | Green | `0x22` | `0xA2` | 25 | | Blue | `0x23` | `0xA3` | 26 | 27 | 28 | To get/set the LED color on the Beepy, you can read/write to the above registers over I2C. The values are in the range of ```0x00``` - ```0xFF```. 29 | 30 | *Note: write addresses are the read address masked with ```0x80```.* 31 | 32 | A value of 0 in the power register represents the LED's off state, while any other value represents on. 33 | 34 | ## Example 35 | 36 | To set the RGB values to red and turn the LED on from the command line: 37 | 38 | ```bash 39 | # Format: 40 | # i2cset -y [i2cbus] [chip-address] [data-address] value 41 | i2cset -y 1 0x1F 0xA1 0xFF 42 | i2cset -y 1 0x1F 0xA2 0x00 43 | i2cset -y 1 0x1F 0xA3 0x00 44 | i2cset -y 1 0x1F 0xA0 0xFF 45 | ``` 46 | -------------------------------------------------------------------------------- /docs/software/os-image.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # OS Image 6 | 7 | The base OS image is [Raspberry Pi OS Lite 32-bit](https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2023-05-03/2023-05-03-raspios-bullseye-armhf-lite.img.xz) (Debian version 11 bullseye, Kernel 6.1) 8 | 9 | ## Optimizing Boot Speed 10 | 11 | To Do - Optimized boot script to reduce boot up time 12 | 13 | ## Optimizing Battery Life 14 | ### Pi Zero 2W Settings 15 | **Restrict number of cores to limit peak power use** - the Zero 2W can be limited to use two cores and is still much faster than the pi zero, but peak power use is nearly half of what 4 cores will use. 16 | * sudo vi /boot/cmdline.txt 17 | * Add "maxcpus=2" after "console=tty1". 18 | * Reboot 19 | 20 | ## Optimizing Apps for small screens 21 | * By default, the LCD display shows a character screen of 50x15. If you develop text-based apps for Beepy, targeting this format will give you compatibility with the widest userbase. 22 | 23 | **top** - You can reduce the number of columns shown by default so that it shows more useful information on the sharp display. 24 | * ssh to the Beepy (the needed menu doesn't render correctly on the small screen) 25 | * run "top" 26 | * type "f" to enter the columns config screen 27 | * use the up and down keys to move, and space to remove the "\*" from all of the columns except: PID, USER, S, %CPU, %MEM, COMMAND 28 | * type "q" to return to the main screen 29 | * type "W" (capital w) to save the config. 30 | * type "q" to quit. Then go back to the Beepy and top should have a nice setup. 31 | 32 | -------------------------------------------------------------------------------- /docusaurus.config.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Note: type annotations allow type checking and IDEs autocompletion 3 | 4 | const lightCodeTheme = require('prism-react-renderer/themes/github'); 5 | const darkCodeTheme = require('prism-react-renderer/themes/dracula'); 6 | 7 | /** @type {import('@docusaurus/types').Config} */ 8 | const config = { 9 | title: 'Beepy', 10 | tagline: 'the ultimate everyday computing gadget', 11 | favicon: 'img/favicon.ico', 12 | 13 | // Set the production url of your site here 14 | url: 'https://beepy.sqfmi.com', 15 | // Set the // pathname under which your site is served 16 | // For GitHub pages deployment, it is often '//' 17 | baseUrl: '/', 18 | 19 | // GitHub pages deployment config. 20 | // If you aren't using GitHub pages, you don't need these. 21 | organizationName: 'sqfmi', // Usually your GitHub org/user name. 22 | projectName: 'beepy-docs', // Usually your repo name. 23 | trailingSlash: false, 24 | 25 | onBrokenLinks: 'throw', 26 | onBrokenMarkdownLinks: 'warn', 27 | 28 | // Even if you don't use internalization, you can use this field to set useful 29 | // metadata like html lang. For example, if your site is Chinese, you may want 30 | // to replace "en" with "zh-Hans". 31 | i18n: { 32 | defaultLocale: 'en', 33 | locales: ['en'], 34 | }, 35 | 36 | presets: [ 37 | [ 38 | 'classic', 39 | /** @type {import('@docusaurus/preset-classic').Options} */ 40 | ({ 41 | docs: { 42 | sidebarPath: require.resolve('./sidebars.js'), 43 | // Please change this to your repo. 44 | // Remove this to remove the "edit this page" links. 45 | editUrl: 46 | 'https://github.com/sqfmi/beepy-docs/blob/main', 47 | }, 48 | blog: false, 49 | theme: { 50 | customCss: require.resolve('./src/css/custom.css'), 51 | }, 52 | gtag: { 53 | trackingID: 'G-LP16KTWD7P', 54 | anonymizeIP: true, 55 | }, 56 | }), 57 | ], 58 | ], 59 | 60 | themeConfig: 61 | /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ 62 | ({ 63 | // Replace with your project's social card 64 | image: 'img/beepy-social-card.jpg', 65 | navbar: { 66 | title: 'Beepy', 67 | logo: { 68 | alt: 'SQFMI logo', 69 | src: 'img/sqfmi_logo_32x32.svg', 70 | className: 'img-svg', 71 | }, 72 | items: [ 73 | { 74 | type: 'docSidebar', 75 | sidebarId: 'docsSidebar', 76 | position: 'left', 77 | label: 'Docs', 78 | }, 79 | { 80 | to: '/docs/hardware/specs', 81 | label: 'Tech Specs', 82 | position: 'left', 83 | }, 84 | { 85 | to: 'https://forms.gle/Q3NCLSjDZwcURxrs8', 86 | label: 'Buy Beepy!', 87 | position: 'right', 88 | }, 89 | ], 90 | }, 91 | footer: { 92 | style: 'light', 93 | links: [ 94 | { 95 | title: 'Docs', 96 | items: [ 97 | { 98 | label: 'Getting Started', 99 | to: '/docs/getting-started', 100 | }, 101 | { 102 | label: 'FAQ', 103 | to: '/docs/FAQ', 104 | }, 105 | ], 106 | }, 107 | { 108 | title: 'Community', 109 | items: [ 110 | { 111 | label: 'Discord', 112 | href: 'https://discord.gg/QERrSferdF', 113 | }, 114 | { 115 | label: 'Twitter', 116 | href: 'https://twitter.com/sqfmi', 117 | }, 118 | { 119 | label: 'Instagram', 120 | href: 'https://www.instagram.com/sqfmi', 121 | }, 122 | { 123 | label: 'Youtube', 124 | href: 'https://youtube.com/@sqfmi', 125 | }, 126 | ], 127 | }, 128 | { 129 | title: 'More', 130 | items: [ 131 | { 132 | label: 'GitHub', 133 | href: 'https://github.com/beeper/', 134 | }, 135 | { 136 | label: 'Beeper', 137 | href: 'https://www.beeper.com/', 138 | }, 139 | ], 140 | }, 141 | ], 142 | copyright: `Copyright © ${new Date().getFullYear()} Squarofumi. Built with Docusaurus.`, 143 | }, 144 | prism: { 145 | theme: lightCodeTheme, 146 | darkTheme: darkCodeTheme, 147 | }, 148 | }), 149 | }; 150 | 151 | module.exports = config; 152 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "beepy", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "docusaurus": "docusaurus", 7 | "start": "docusaurus start", 8 | "build": "docusaurus build", 9 | "swizzle": "docusaurus swizzle", 10 | "deploy": "docusaurus deploy", 11 | "clear": "docusaurus clear", 12 | "serve": "docusaurus serve", 13 | "write-translations": "docusaurus write-translations", 14 | "write-heading-ids": "docusaurus write-heading-ids" 15 | }, 16 | "dependencies": { 17 | "@docusaurus/core": "2.4.0", 18 | "@docusaurus/preset-classic": "2.4.0", 19 | "@mdx-js/react": "^1.6.22", 20 | "clsx": "^1.2.1", 21 | "prism-react-renderer": "^1.3.5", 22 | "react": "^17.0.2", 23 | "react-dom": "^17.0.2" 24 | }, 25 | "devDependencies": { 26 | "@docusaurus/module-type-aliases": "2.4.0" 27 | }, 28 | "browserslist": { 29 | "production": [ 30 | ">0.5%", 31 | "not dead", 32 | "not op_mini all" 33 | ], 34 | "development": [ 35 | "last 1 chrome version", 36 | "last 1 firefox version", 37 | "last 1 safari version" 38 | ] 39 | }, 40 | "engines": { 41 | "node": ">=16.14" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /sidebars.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Creating a sidebar enables you to: 3 | - create an ordered group of docs 4 | - render a sidebar for each doc of that group 5 | - provide next/previous navigation 6 | 7 | The sidebars can be generated from the filesystem, or explicitly defined here. 8 | 9 | Create as many sidebars as you want. 10 | */ 11 | 12 | // @ts-check 13 | 14 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ 15 | const sidebars = { 16 | // By default, Docusaurus generates a sidebar from the docs folder structure 17 | docsSidebar: [{type: 'autogenerated', dirName: '.'}], 18 | 19 | // But you can create a sidebar manually 20 | /* 21 | tutorialSidebar: [ 22 | 'intro', 23 | 'hello', 24 | { 25 | type: 'category', 26 | label: 'Tutorial', 27 | items: ['tutorial-basics/create-a-document'], 28 | }, 29 | ], 30 | */ 31 | }; 32 | 33 | module.exports = sidebars; 34 | -------------------------------------------------------------------------------- /src/components/HomepageDiagram/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import clsx from 'clsx'; 3 | import styles from './styles.module.css'; 4 | 5 | export default function HomepageDiagram() { 6 | return ( 7 |
8 |
9 |

Technical Diagram

10 |
11 |
12 |
13 |
14 | ); 15 | } -------------------------------------------------------------------------------- /src/components/HomepageDiagram/styles.module.css: -------------------------------------------------------------------------------- 1 | .diagram{ 2 | text-align: center; 3 | padding:1em; 4 | } 5 | 6 | .diagram h1{ 7 | padding-bottom: 1em; 8 | } 9 | 10 | .diagram .front{ 11 | background-image: url("/static/img/beepy-diagram-full.svg"); 12 | background-repeat: no-repeat; 13 | background-size: contain; 14 | width:100%; 15 | height:600px; 16 | } 17 | 18 | @media screen and (max-width: 996px) { 19 | .diagram .front{ 20 | background-repeat: no-repeat; 21 | background-size: 180%; 22 | width: 100%; 23 | height: 300px; 24 | } 25 | .diagram .back{ 26 | background-image: url("/static/img/beepy-diagram-full.svg"); 27 | background-repeat: no-repeat; 28 | background-size: 180%; 29 | background-position: right; 30 | width: 100%; 31 | height: 360px; 32 | } 33 | } -------------------------------------------------------------------------------- /src/components/HomepageFeatures/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import clsx from 'clsx'; 3 | import styles from './styles.module.css'; 4 | 5 | const FeatureList = [ 6 | { 7 | italics: 'Sharp', 8 | title: ' Display', 9 | Svg: require('@site/static/img/feature-sharpdisplay-400x240.svg').default, 10 | description: ( 11 | <> 12 | Ultra-low power, high contrast, high resolution, Sharp Memory LCD display. 13 | 14 | ), 15 | }, 16 | { 17 | title: 'Tactile keyboard & touchpad', 18 | Svg: require('@site/static/img/feature-keyboard.svg').default, 19 | description: ( 20 | <> 21 | Clicky keyboard w/ backlight and touchpad for easy input and navigation. Customizable keymap to suit your needs. 22 | 23 | ), 24 | }, 25 | { 26 | title: 'Powered by Raspberry Pi', 27 | Svg: require('@site/static/img/feature-raspberrypizero.svg').default, 28 | description: ( 29 | <> 30 | Powered by the Pi Zero W (optional) or any other compatible SBCs (e.g. Radxa Zero, MQ-Pro) with the low profile solderless header. 31 | 32 | ), 33 | }, 34 | ]; 35 | 36 | function Feature({Svg, italics, title, description}) { 37 | return ( 38 |
39 |
40 | 41 |
42 |
43 |

{italics}{title}

44 |

{description}

45 |
46 |
47 | ); 48 | } 49 | 50 | export default function HomepageFeatures() { 51 | return ( 52 |
53 |
54 |
55 | {FeatureList.map((props, idx) => ( 56 | 57 | ))} 58 |
59 |
60 |
61 | ); 62 | } 63 | -------------------------------------------------------------------------------- /src/components/HomepageFeatures/styles.module.css: -------------------------------------------------------------------------------- 1 | .features { 2 | display: flex; 3 | align-items: center; 4 | padding: 2rem 0; 5 | width: 100%; 6 | } 7 | 8 | .featureSvg { 9 | height: 200px; 10 | width: 200px; 11 | } 12 | -------------------------------------------------------------------------------- /src/components/HomepageVideos/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import clsx from 'clsx'; 3 | import styles from './styles.module.css'; 4 | import useBaseUrl from '@docusaurus/useBaseUrl'; 5 | 6 | export default function HomepageVideos() { 7 | return ( 8 |
9 |
10 |
11 |

See it in action

12 |
13 |
14 |
15 | 16 |
17 |
18 | 19 |
20 |
21 | 22 |
23 |
24 |
25 |
26 | ); 27 | } 28 | 29 | /** 30 | 31 |
32 |
33 | 34 |
35 |
36 | 37 |
38 |
39 | 40 |
41 |
42 | 43 | **/ 44 | -------------------------------------------------------------------------------- /src/components/HomepageVideos/styles.module.css: -------------------------------------------------------------------------------- 1 | .videos { 2 | display: flex; 3 | align-items: center; 4 | padding: 2rem 0; 5 | width: 100%; 6 | } 7 | 8 | .col { 9 | padding-top: 1rem; 10 | padding-bottom: 1rem; 11 | display: flex; 12 | align-items: center; 13 | } -------------------------------------------------------------------------------- /src/css/custom.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Any CSS included here will be global. The classic template 3 | * bundles Infima by default. Infima is a CSS framework designed to 4 | * work well for content-centric websites. 5 | */ 6 | 7 | /* You can override the default Infima variables here. */ 8 | :root { 9 | --ifm-color-primary: #5d57a8; 10 | --ifm-color-primary-dark: #5f4496; 11 | --ifm-color-primary-darker: #603585; 12 | --ifm-color-primary-darkest: #5e2973; 13 | --ifm-color-primary-light: #6f80b9; 14 | --ifm-color-primary-lighter: #8bafcb; 15 | --ifm-color-primary-lightest: #acd9dc; 16 | --ifm-code-font-size: 95%; 17 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); 18 | } 19 | 20 | /* For readability concerns, you should choose a lighter palette in dark mode. */ 21 | [data-theme='dark'] { 22 | --ifm-color-primary: #7288b9; 23 | --ifm-color-primary-dark: #5e56a8; 24 | --ifm-color-primary-darker: #5f4596; 25 | --ifm-color-primary-darkest: #5c3885; 26 | --ifm-color-primary-light: #93bccb; 27 | --ifm-color-primary-lighter: #b5dcd8; 28 | --ifm-color-primary-lightest: #d7eee4; 29 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); 30 | } 31 | 32 | [data-theme='dark'] .img-svg { 33 | filter: invert(100%); 34 | } 35 | 36 | [data-theme='dark'] img[alt="Beepy Technical Diagram"] { 37 | filter: invert(100%); 38 | } 39 | 40 | @font-face { 41 | font-family: 'Nimbus Sans L'; 42 | src: url('/static/fonts/NimbusSanL-BolIta.woff2') format('woff2'), 43 | url('/static/fonts/NimbusSanL-BolIta.woff') format('woff'); 44 | font-weight: bold; 45 | font-style: normal; 46 | font-display: swap; 47 | } 48 | 49 | .hero h1{ 50 | font-family: 'Nimbus Sans L'; 51 | } -------------------------------------------------------------------------------- /src/pages/gallery/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Layout from '@theme/Layout'; 3 | 4 | export default function Hello() { 5 | return ( 6 | 7 |
8 |
9 | 10 |
11 | 12 | 13 |
14 |
15 |
16 | ); 17 | } -------------------------------------------------------------------------------- /src/pages/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import clsx from 'clsx'; 3 | import Link from '@docusaurus/Link'; 4 | import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; 5 | import Layout from '@theme/Layout'; 6 | import HomepageFeatures from '@site/src/components/HomepageFeatures'; 7 | import HomepageDiagram from '@site/src/components/HomepageDiagram'; 8 | import HomepageVideos from '@site/src/components/HomepageVideos'; 9 | import styles from './index.module.css'; 10 | 11 | function HomepageHeader() { 12 | const {siteConfig} = useDocusaurusContext(); 13 | return ( 14 |
15 |
16 |

{siteConfig.title}

17 | {/*

{siteConfig.tagline}

*/} 18 |
19 | 22 | Order Now 23 | 24 |
25 |
26 |
27 | ); 28 | } 29 | 30 | export default function Home() { 31 | const {siteConfig} = useDocusaurusContext(); 32 | return ( 33 | 36 | 37 |
38 | 39 | 40 | 41 |
42 |
43 | ); 44 | } 45 | -------------------------------------------------------------------------------- /src/pages/index.module.css: -------------------------------------------------------------------------------- 1 | /** 2 | * CSS files with the .module.css suffix will be treated as CSS modules 3 | * and scoped locally. 4 | */ 5 | 6 | .heroBanner { 7 | padding: 4rem 0; 8 | text-align: center; 9 | position: relative; 10 | overflow: hidden; 11 | } 12 | 13 | .heroBanner{ 14 | background-image: url(/img/beepy-header.png); 15 | background-position: 50% 0; 16 | background-size: 700px; 17 | background-repeat: no-repeat; 18 | height: 600px; 19 | } 20 | 21 | @media screen and (max-width: 996px) { 22 | .heroBanner { 23 | padding: 2rem; 24 | } 25 | } 26 | 27 | .buttons { 28 | display: flex; 29 | align-items: center; 30 | justify-content: center; 31 | font-family: system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Noto Sans,Ubuntu,Cantarell,Helvetica Neue,Oxygen,Fira Sans,Droid Sans,sans-serif; 32 | } -------------------------------------------------------------------------------- /src/pages/markdown-page.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Markdown page example 3 | --- 4 | 5 | # Markdown page example 6 | 7 | You don't need React to write simple standalone pages. 8 | -------------------------------------------------------------------------------- /static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/static/.nojekyll -------------------------------------------------------------------------------- /static/CNAME: -------------------------------------------------------------------------------- 1 | beepy.sqfmi.com -------------------------------------------------------------------------------- /static/fonts/NimbusSanL-BolIta.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/static/fonts/NimbusSanL-BolIta.woff -------------------------------------------------------------------------------- /static/fonts/NimbusSanL-BolIta.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/static/fonts/NimbusSanL-BolIta.woff2 -------------------------------------------------------------------------------- /static/img/Raspberry_Pi_Logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /static/img/beepy-diagram-full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/static/img/beepy-diagram-full.png -------------------------------------------------------------------------------- /static/img/beepy-edc.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/static/img/beepy-edc.jpg -------------------------------------------------------------------------------- /static/img/beepy-fruitforscale-2048x1443.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/static/img/beepy-fruitforscale-2048x1443.jpg -------------------------------------------------------------------------------- /static/img/beepy-header-mount-diagram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/static/img/beepy-header-mount-diagram.jpg -------------------------------------------------------------------------------- /static/img/beepy-header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/static/img/beepy-header.png -------------------------------------------------------------------------------- /static/img/beepy-social-card.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/static/img/beepy-social-card.jpg -------------------------------------------------------------------------------- /static/img/beepy-tuir-reddit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/static/img/beepy-tuir-reddit.jpg -------------------------------------------------------------------------------- /static/img/beepy-v1-3D-render.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/static/img/beepy-v1-3D-render.png -------------------------------------------------------------------------------- /static/img/clear-sandwich-back.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/static/img/clear-sandwich-back.jpg -------------------------------------------------------------------------------- /static/img/clear-sandwich-dimensions.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/static/img/clear-sandwich-dimensions.jpg -------------------------------------------------------------------------------- /static/img/clear-sandwich-front.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/static/img/clear-sandwich-front.jpg -------------------------------------------------------------------------------- /static/img/docusaurus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/static/img/docusaurus.png -------------------------------------------------------------------------------- /static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/static/img/favicon.ico -------------------------------------------------------------------------------- /static/img/feature-keyboard.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 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 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 159 | 164 | 166 | 170 | 172 | 176 | 178 | 182 | 184 | 188 | 190 | 194 | 196 | 200 | 202 | 206 | 208 | 212 | 214 | 218 | 220 | 224 | 226 | 230 | 232 | 236 | 238 | 242 | 244 | 248 | 250 | 254 | 256 | 260 | 262 | 266 | 268 | 272 | 274 | 278 | 280 | 284 | 286 | 290 | 292 | 296 | 298 | 302 | 304 | 308 | 310 | 314 | 316 | 320 | 322 | 326 | 328 | 332 | 334 | 338 | 340 | 344 | 346 | 350 | 352 | 356 | 358 | 362 | 364 | 368 | 370 | 374 | 376 | 380 | 382 | 386 | 388 | 392 | 394 | 398 | 400 | 404 | 406 | 410 | 412 | 416 | 418 | 422 | 424 | 428 | 430 | 434 | 436 | 440 | 441 | 442 | -------------------------------------------------------------------------------- /static/img/feature-sharpdisplay-400x240.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | Display 10 | 11 | 12 | 13 | 15 | 16 | 18 | 19 | 26 | 28 | 29 | 30 | 39 | 40 | 42 | 44 | 46 | 50 | 53 | 55 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /static/img/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/img/sqfmi_logo_32x32.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | sqfmi_logo_32x32 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /static/img/symbol-keys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sqfmi/beepy-docs/68019a01875a785e083f966d75f1afc0b73620f0/static/img/symbol-keys.png -------------------------------------------------------------------------------- /static/img/undraw_docusaurus_mountain.svg: -------------------------------------------------------------------------------- 1 | 2 | Easy to Use 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 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 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | -------------------------------------------------------------------------------- /static/img/undraw_docusaurus_react.svg: -------------------------------------------------------------------------------- 1 | 2 | Powered by React 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 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 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /static/img/undraw_docusaurus_tree.svg: -------------------------------------------------------------------------------- 1 | 2 | Focus on What Matters 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | --------------------------------------------------------------------------------