├── .cargo ├── aarch64-linux-android.config.toml └── config.toml ├── .dockerignore ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── ci.yml │ └── release.yml ├── .gitignore ├── .lavagna.gif ├── CHANGELOG.md ├── Cargo.lock ├── Cargo.toml ├── Cross.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── assets ├── fonts │ └── FiraMono-Medium.ttf └── sprites │ └── pen.png ├── docker └── lavagna-webapp │ ├── .config │ ├── Dockerfile │ └── httpd.conf ├── rust-toolchain.toml ├── src ├── cli.rs ├── collab.rs ├── debug.rs ├── drawing.rs ├── keybinding.rs ├── lib.rs ├── local_chalk.rs ├── main.rs ├── ui.rs └── web.rs ├── tools ├── build-docker-image-server ├── build-docker-image-webapp ├── build-web ├── dev-web └── watch └── www └── index.html.template /.cargo/aarch64-linux-android.config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "aarch64-linux-android" 3 | -------------------------------------------------------------------------------- /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | # Add the contents of this file to `config.toml` to enable "fast build" configuration. Please read the notes below. 2 | 3 | # NOTE: For maximum performance, build using a nightly compiler 4 | # If you are using rust stable, remove the "-Zshare-generics=y" below. 5 | 6 | [target.x86_64-unknown-linux-gnu] 7 | linker = "clang" 8 | rustflags = ["-Clink-arg=-fuse-ld=lld", "-Zshare-generics=y"] 9 | 10 | # NOTE: you must install [Mach-O LLD Port](https://lld.llvm.org/MachO/index.html) on mac. you can easily do this by installing llvm which includes lld with the "brew" package manager: 11 | # `brew install llvm` 12 | [target.x86_64-apple-darwin] 13 | rustflags = [ 14 | "-C", 15 | "link-arg=-fuse-ld=/usr/local/opt/llvm/bin/ld64.lld", 16 | "-Zshare-generics=y", 17 | ] 18 | 19 | [target.aarch64-apple-darwin] 20 | rustflags = [ 21 | "-C", 22 | "link-arg=-fuse-ld=/opt/homebrew/opt/llvm/bin/ld64.lld", 23 | "-Zshare-generics=y", 24 | ] 25 | 26 | [target.x86_64-pc-windows-msvc] 27 | linker = "rust-lld.exe" 28 | rustflags = ["-Zshare-generics=n"] 29 | 30 | # [build] 31 | # target = "wasm32-unknown-unknown" 32 | 33 | # Optional: Uncommenting the following improves compile times, but reduces the amount of debug info to 'line number tables only' 34 | # In most cases the gains are negligible, but if you are on macos and have slow compile times you should see significant gains. 35 | #[profile.dev] 36 | #debug = 1 37 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | /target 2 | /www/lavagna_bg.wasm 3 | /www/lavagna_bg.wasm.d.ts 4 | /www/lavagna.d.ts 5 | /www/lavagna.js 6 | -------------------------------------------------------------------------------- /.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 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | on: 3 | workflow_dispatch: 4 | pull_request: 5 | push: 6 | branches: 7 | - main 8 | schedule: 9 | - cron: '00 01 * * *' 10 | jobs: 11 | rustfmt: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout repository 15 | uses: actions/checkout@v4 16 | - name: Install Rust 17 | uses: dtolnay/rust-toolchain@stable 18 | with: 19 | toolchain: stable 20 | components: rustfmt 21 | - name: Check formatting 22 | run: rm rust-toolchain.toml .cargo/config.toml && cargo fmt --all --check 23 | 24 | test: 25 | name: test 26 | 27 | env: 28 | # Emit backtraces on panics. 29 | RUST_BACKTRACE: 1 30 | CARGO_INCREMENTAL: 0 31 | RUSTFLAGS: "-C debuginfo=0 --deny warnings" 32 | OPTIONS: ${{ matrix.platform.options }} 33 | FEATURES: ${{ format(',{0}', matrix.platform.features ) }} 34 | CMD: ${{ matrix.platform.cmd }} 35 | 36 | runs-on: ${{ matrix.platform.os }} 37 | strategy: 38 | fail-fast: false 39 | matrix: 40 | # We test lavagna on a pinned version of Rust, along with the moving 41 | # targets of 'stable', 'beta', 'nightly'. 42 | rust_version: 43 | - 1.79.0 44 | - stable 45 | - beta 46 | - nightly 47 | platform: 48 | - { target: x86_64-pc-windows-msvc, os: windows-2019 } 49 | - { target: x86_64-pc-windows-gnu, os: windows-2022, host: -x86_64-pc-windows-gnu } 50 | - { target: x86_64-unknown-linux-gnu, os: ubuntu-latest } 51 | - { target: x86_64-apple-darwin, os: macos-latest } 52 | 53 | steps: 54 | - name: Checkout repository 55 | uses: actions/checkout@v2 56 | 57 | # Note: rust-toolchain.toml is needed only during development so they're removed before building. 58 | - name: Remove rust-toolchain.toml 59 | uses: JesseTG/rm@v1.0.0 60 | with: 61 | path: rust-toolchain.toml 62 | 63 | # Note: .cargo dir is needed only during development so they're removed before building. 64 | - name: Remove .cargo 65 | uses: JesseTG/rm@v1.0.0 66 | with: 67 | path: .cargo 68 | 69 | - name: Cache cargo folder 70 | uses: actions/cache@v3 71 | with: 72 | path: ~/.cargo 73 | key: ${{ matrix.platform.target }}-cargo-${{ matrix.rust_version }} 74 | 75 | - name: Install Rust 76 | uses: actions-rs/toolchain@v1 77 | with: 78 | toolchain: ${{ matrix.rust_version }}${{ matrix.platform.host }} 79 | target: ${{ matrix.platform.target }} 80 | profile: minimal 81 | override: true 82 | components: clippy, rustfmt 83 | 84 | - name: Build tests 85 | shell: bash 86 | run: cargo $CMD test --no-run --verbose --target ${{ matrix.platform.target }} $OPTIONS --features $FEATURES 87 | 88 | - name: Run tests 89 | shell: bash 90 | if: ( 91 | !contains(matrix.platform.target, 'ios') && 92 | !contains(matrix.platform.target, 'wasm32')) 93 | run: cargo $CMD test --verbose --target ${{ matrix.platform.target }} $OPTIONS --features $FEATURES 94 | 95 | - name: Lint with clippy 96 | shell: bash 97 | if: (matrix.rust_version == 'stable') && !contains(matrix.platform.options, '--no-default-features') 98 | run: cargo clippy --all-targets --target ${{ matrix.platform.target }} $OPTIONS --features $FEATURES -- -Dwarnings 99 | 100 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # The way this works is the following: 2 | # 3 | # The create-release job runs purely to initialize the GitHub release itself 4 | # and to output upload_url for the following job. 5 | # 6 | # The build-release job runs only once create-release is finished. It gets the 7 | # release upload URL from create-release job outputs, then builds the release 8 | # executables for each supported platform and attaches them as release assets 9 | # to the previously created release. 10 | # 11 | # The key here is that we create the release only once. 12 | # 13 | # Reference: 14 | # https://eugene-babichenko.github.io/blog/2020/05/09/github-actions-cross-platform-auto-releases/ 15 | 16 | name: release 17 | on: 18 | workflow_dispatch: 19 | inputs: 20 | version: 21 | description: "Version" 22 | required: true 23 | default: "TEST-0.0.0" 24 | type: string 25 | push: 26 | tags: 27 | - "v[0-9]+.[0-9]+.[0-9]+" 28 | jobs: 29 | create-release: 30 | name: create-release 31 | runs-on: ubuntu-latest 32 | env: 33 | # Set to force version number, e.g., when no tag exists. 34 | LAVAGNA_VERSION: ${{ inputs.version }} 35 | 36 | outputs: 37 | upload_url: ${{ steps.release.outputs.upload_url }} 38 | lavagna_version: ${{ env.LAVAGNA_VERSION }} 39 | steps: 40 | - name: Get the release version from the tag 41 | shell: bash 42 | if: env.LAVAGNA_VERSION == '' 43 | run: | 44 | # Apparently, this is the right way to get a tag name. Really? 45 | # 46 | # See: https://github.community/t5/GitHub-Actions/How-to-get-just-the-tag-name/m-p/32167/highlight/true#M1027 47 | echo "LAVAGNA_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV 48 | echo "version is: ${{ env.LAVAGNA_VERSION }}" 49 | - name: Create GitHub release 50 | id: release 51 | uses: actions/create-release@v1 52 | env: 53 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 54 | with: 55 | tag_name: ${{ env.LAVAGNA_VERSION }} 56 | release_name: ${{ env.LAVAGNA_VERSION }} 57 | draft: true 58 | 59 | build-release: 60 | name: build-release 61 | needs: ['create-release'] 62 | runs-on: ${{ matrix.os }} 63 | env: 64 | # For some builds, we use cross to test on 32-bit and big-endian 65 | # systems. 66 | CARGO: cargo 67 | # When CARGO is set to CROSS, this is set to `--target matrix.target`. 68 | TARGET_FLAGS: "" 69 | # When CARGO is set to CROSS, TARGET_DIR includes matrix.target. 70 | TARGET_DIR: ./target 71 | # Emit backtraces on panics. 72 | RUST_BACKTRACE: 1 73 | strategy: 74 | matrix: 75 | include: 76 | - build: linux 77 | os: ubuntu-20.04 78 | rust: stable 79 | target: x86_64-unknown-linux-gnu 80 | - build: linux-arm 81 | os: ubuntu-20.04 82 | rust: stable 83 | target: arm-unknown-linux-gnueabihf 84 | - build: macos 85 | os: macos-latest 86 | rust: stable 87 | target: x86_64-apple-darwin 88 | - build: win-msvc 89 | os: windows-2019 90 | rust: stable 91 | target: x86_64-pc-windows-msvc 92 | - build: win-gnu 93 | os: windows-2019 94 | rust: stable-x86_64-gnu 95 | target: x86_64-pc-windows-gnu 96 | - build: win32-msvc 97 | os: windows-2019 98 | rust: stable 99 | target: i686-pc-windows-msvc 100 | 101 | steps: 102 | - name: Checkout repository 103 | uses: actions/checkout@v2 104 | with: 105 | fetch-depth: 1 106 | 107 | # Note: rust-toolchain.toml is needed only during development so it's removed before building. 108 | - name: Remove rust-toolchain.toml 109 | uses: JesseTG/rm@v1.0.0 110 | with: 111 | path: rust-toolchain.toml 112 | 113 | # Note: .cargo dir is needed only during development so it's removed before building. 114 | - name: Remove .cargo 115 | uses: JesseTG/rm@v1.0.0 116 | with: 117 | path: .cargo 118 | 119 | - name: Cache cargo folder 120 | uses: actions/cache@v3 121 | with: 122 | key: ${{ matrix.build }} 123 | path: | 124 | ~/.cargo 125 | ~/.rustup 126 | 127 | - name: Install Rust 128 | uses: actions-rs/toolchain@v1 129 | with: 130 | toolchain: ${{ matrix.rust }} 131 | profile: minimal 132 | override: true 133 | target: ${{ matrix.target }} 134 | 135 | - name: Use Cross 136 | shell: bash 137 | run: | 138 | cargo install cross --vers 0.2.1 139 | echo "CARGO=cross" >> $GITHUB_ENV 140 | echo "TARGET_FLAGS=--target ${{ matrix.target }}" >> $GITHUB_ENV 141 | echo "TARGET_DIR=./target/${{ matrix.target }}" >> $GITHUB_ENV 142 | 143 | - name: Show command used for Cargo 144 | run: | 145 | echo "cargo command is: ${{ env.CARGO }}" 146 | echo "target flag is: ${{ env.TARGET_FLAGS }}" 147 | echo "target dir is: ${{ env.TARGET_DIR }}" 148 | 149 | - name: Build release binary 150 | env: 151 | BEVY_ASSET_PATH: /project/assets 152 | run: ${{ env.CARGO }} build --verbose --release ${{ env.TARGET_FLAGS }} 153 | 154 | - name: Strip release binary (linux and macos) 155 | if: matrix.build == 'linux' || matrix.build == 'macos' 156 | run: strip "target/${{ matrix.target }}/release/lavagna" 157 | 158 | - name: Strip release binary (arm) 159 | if: matrix.build == 'linux-arm' 160 | run: | 161 | docker run --rm -v \ 162 | "$PWD/target:/target:Z" \ 163 | rustembedded/cross:arm-unknown-linux-gnueabihf \ 164 | arm-linux-gnueabihf-strip \ 165 | /target/arm-unknown-linux-gnueabihf/release/lavagna 166 | 167 | - name: Build archive 168 | shell: bash 169 | run: | 170 | staging="lavagna-${{ needs.create-release.outputs.lavagna_version }}-${{ matrix.target }}" 171 | 172 | mkdir -p "$staging" 173 | 174 | cp {README.md,LICENSE-APACHE,LICENSE-MIT} "$staging/" 175 | 176 | if [ "${{ matrix.os }}" = "windows-2019" ]; then 177 | cp "target/${{ matrix.target }}/release/lavagna.exe" "$staging/" 178 | 7z a "$staging.zip" "$staging" 179 | echo "ASSET=$staging.zip" >> $GITHUB_ENV 180 | else 181 | cp "target/${{ matrix.target }}/release/lavagna" "$staging/" 182 | tar czf "$staging.tar.gz" "$staging" 183 | echo "ASSET=$staging.tar.gz" >> $GITHUB_ENV 184 | fi 185 | 186 | - name: Upload release archive 187 | uses: actions/upload-release-asset@v1.0.2 188 | env: 189 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 190 | with: 191 | upload_url: ${{ needs.create-release.outputs.upload_url }} 192 | asset_path: ${{ env.ASSET }} 193 | asset_name: ${{ env.ASSET }} 194 | asset_content_type: application/octet-stream 195 | 196 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /www/lavagna-*.* 3 | /www/index.html 4 | -------------------------------------------------------------------------------- /.lavagna.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alepez/lavagna/447fe9e9e649c3c109da1fc3e8a9e5b64fcfbc36/.lavagna.gif -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [Unreleased] 8 | 9 | ## [2.1.8](https://github.com/alepez/lavagna/compare/v2.1.7...v2.1.8) - 2023-06-28 10 | 11 | ### Added 12 | 13 | - Peers cursors are now visible 14 | 15 | ### Changed 16 | 17 | - Upgrade dependencies 18 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lavagna" 3 | version = "2.1.9" 4 | authors = ["Alessandro Pezzato "] 5 | edition = "2021" 6 | description = "The uncluttered blackboard" 7 | homepage = "https://github.com/alepez/lavagna" 8 | repository = "https://github.com/alepez/lavagna" 9 | readme = "README.md" 10 | license = "MIT OR Apache-2.0" 11 | include = ["src", "assets", "LICENSE*", "README.md"] 12 | rust-version = "1.79" 13 | 14 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 15 | [dependencies.bevy] 16 | version = "0.14" 17 | default-features = false 18 | features = [ 19 | "bevy_asset", 20 | "bevy_core_pipeline", 21 | "bevy_render", 22 | "bevy_sprite", 23 | "bevy_text", 24 | "bevy_ui", 25 | "bevy_winit", 26 | "x11", 27 | "png", 28 | "webgl2", 29 | "multi_threaded", 30 | ] 31 | 32 | [dependencies] 33 | bevy_embedded_assets = "0.11" 34 | bevy_framepace = "0.17" 35 | bevy_pancam = "0.12" 36 | bevy_prototype_lyon = "0.12" 37 | bevy_matchbox = "0.10" 38 | ciborium = "0.2" 39 | rand = "0.8" 40 | serde = { version = "1.0", features = ["derive"] } 41 | 42 | # Statically disable verbosity level for tracing, to avoid bloating the binary 43 | log = { version = "0.4", features = ["max_level_debug", "release_max_level_error"] } 44 | tracing = { version = "0.1", features = ["max_level_debug", "release_max_level_error"] } 45 | 46 | # Enable a small amount of optimization in debug mode 47 | [profile.dev] 48 | opt-level = 1 49 | 50 | # Enable high optimizations for dependencies (incl. Bevy), but not for our code: 51 | [profile.dev.package."*"] 52 | opt-level = 3 53 | 54 | [features] 55 | # Enabling this feature will enable dynamic linking of Bevy, for faster build 56 | quick-build = ["bevy/dynamic_linking"] 57 | 58 | # wasm only dependencies 59 | [target.wasm32-unknown-unknown.dependencies] 60 | tracing-wasm = "0.2" 61 | tracing = "0.1" 62 | web-sys = { version = "0.3", features = ["Window", "Location"] } 63 | 64 | # dependencies for all other targets 65 | [target.'cfg(not(target_arch = "wasm32"))'.dependencies] 66 | clap = { version = "4", features = ["derive"] } 67 | -------------------------------------------------------------------------------- /Cross.toml: -------------------------------------------------------------------------------- 1 | [build.env] 2 | passthrough = [ 3 | "BEVY_ASSET_PATH", 4 | ] 5 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2022 Alessandro Pezzato 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2022 Alessandro Pezzato (https://pezzato.net). 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lavagna 2 | 3 | > It's a blackboard, not a lasagna. 4 | 5 | ![preview](.lavagna.gif) 6 | 7 | *Lavagna* is a collaborative blackboard, perfect for creating simple sketches 8 | during online meetings. It has an (optional) minimal toolbar which can be 9 | hidden to avoid distractions from your drawings. You can control colors and 10 | line width using the keyboard or the toolbar. 11 | 12 | It's just you, your peers, and your creativity. 13 | 14 | ## Keyboard bindings 15 | 16 | | Button | Action | Note | 17 | |--------|---------|----------------------------| 18 | | C | Color | Change the chalk color | 19 | | M | Grow | Grow chalk size 2x | 20 | | N | Shrink | Shrink chalk size 2x | 21 | | X | Clear | Clear the whole blackboard | 22 | | U | Toolbar | Toggle toolbar visibility | 23 | 24 | ## Installation 25 | 26 | [Archives of precompiled binaries for *lavagna* are available for Windows, macOS 27 | and Linux.](https://github.com/alepez/lavagna/releases/latest) 28 | 29 | ### Install from source 30 | 31 | If you're a **Rust programmer**, *lavagna* can be installed with `cargo`. 32 | 33 | - Note that the minimum supported version of Rust for *lavagna* is 1.79, 34 | although *lavagna* may work with older versions. 35 | 36 | To install from sources: 37 | 38 | ```shell 39 | git clone https://github.com/alepez/lavagna.git 40 | cd lavagna 41 | cargo install --path lavagna --locked 42 | ``` 43 | 44 | ### Install from crates.io 45 | 46 | Currently, installing from crates.io is not 47 | available. [See this issue.](https://github.com/alepez/lavagna/issues/21) 48 | 49 | ## Instant collaboration 50 | 51 | *lavagna* uses *WebRtc* for instant collaboration. So you can use it for online 52 | meetings. You don't even need to install anything, because *lavagna* is 53 | available as a web-app too. 54 | 55 | You need a signaling server 56 | like [`matchbox_server`](https://github.com/johanhelsing/matchbox/tree/main/matchbox_server) 57 | installed somewhere. 58 | See [this post by Johan Helsing](https://johanhelsing.studio/posts/deploying-matchbox/) 59 | 60 | Don't worry, for quick testing you can borrow my signaling server: 61 | 62 | ```shell 63 | lavagna --collab-url ws://lavagna.alepez.dev:3536/demo 64 | ``` 65 | 66 | Change `demo` to your preferred name or a unique id. If you do the same on 67 | different device, anything you draw will be visible on the other side (and vice 68 | versa). 69 | 70 | ## Desktop app development 71 | 72 | `lavagna` works on many operating systems: 73 | 74 | - Linux (x86) 75 | - Linux (ARM) 76 | - macOS (x86) 77 | - Windows 78 | 79 | You just need to have a Rust toolchain installed. Run this from the project 80 | directory: 81 | 82 | ```shell 83 | cargo run 84 | ``` 85 | 86 | To print help information, just use: 87 | 88 | ```shell 89 | cargo run -- --help 90 | ``` 91 | 92 | ## Web app development 93 | 94 | This script builds all the assets needed for a web application. You'll find them 95 | on `www` directory, so you can use any http server able to serve static files. 96 | 97 | ```shell 98 | ./tools/build-web 99 | cd www 100 | python -m http.server 8000 101 | ``` 102 | 103 | See also `docker/lavagna-webapp/Dockerfile` as an example of how to publish the 104 | web-app. 105 | -------------------------------------------------------------------------------- /assets/fonts/FiraMono-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alepez/lavagna/447fe9e9e649c3c109da1fc3e8a9e5b64fcfbc36/assets/fonts/FiraMono-Medium.ttf -------------------------------------------------------------------------------- /assets/sprites/pen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alepez/lavagna/447fe9e9e649c3c109da1fc3e8a9e5b64fcfbc36/assets/sprites/pen.png -------------------------------------------------------------------------------- /docker/lavagna-webapp/.config: -------------------------------------------------------------------------------- 1 | # 2 | # Automatically generated make config: don't edit 3 | # Busybox version: 1.36.0.git 4 | # Sun Jul 31 19:35:26 2022 5 | # 6 | CONFIG_HAVE_DOT_CONFIG=y 7 | 8 | # 9 | # Settings 10 | # 11 | # CONFIG_DESKTOP is not set 12 | # CONFIG_EXTRA_COMPAT is not set 13 | # CONFIG_FEDORA_COMPAT is not set 14 | # CONFIG_INCLUDE_SUSv2 is not set 15 | # CONFIG_LONG_OPTS is not set 16 | # CONFIG_SHOW_USAGE is not set 17 | # CONFIG_FEATURE_VERBOSE_USAGE is not set 18 | # CONFIG_FEATURE_COMPRESS_USAGE is not set 19 | # CONFIG_LFS is not set 20 | # CONFIG_PAM is not set 21 | # CONFIG_FEATURE_DEVPTS is not set 22 | # CONFIG_FEATURE_UTMP is not set 23 | # CONFIG_FEATURE_WTMP is not set 24 | # CONFIG_FEATURE_PIDFILE is not set 25 | CONFIG_PID_FILE_PATH="" 26 | # CONFIG_BUSYBOX is not set 27 | # CONFIG_FEATURE_SHOW_SCRIPT is not set 28 | # CONFIG_FEATURE_INSTALLER is not set 29 | CONFIG_INSTALL_NO_USR=y 30 | # CONFIG_FEATURE_SUID is not set 31 | # CONFIG_FEATURE_SUID_CONFIG is not set 32 | # CONFIG_FEATURE_SUID_CONFIG_QUIET is not set 33 | # CONFIG_FEATURE_PREFER_APPLETS is not set 34 | CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" 35 | # CONFIG_SELINUX is not set 36 | # CONFIG_FEATURE_CLEAN_UP is not set 37 | # CONFIG_FEATURE_SYSLOG_INFO is not set 38 | # CONFIG_FEATURE_SYSLOG is not set 39 | 40 | # 41 | # Build Options 42 | # 43 | CONFIG_STATIC=y 44 | # CONFIG_PIE is not set 45 | # CONFIG_NOMMU is not set 46 | # CONFIG_BUILD_LIBBUSYBOX is not set 47 | # CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set 48 | # CONFIG_FEATURE_INDIVIDUAL is not set 49 | # CONFIG_FEATURE_SHARED_BUSYBOX is not set 50 | CONFIG_CROSS_COMPILER_PREFIX="" 51 | CONFIG_SYSROOT="" 52 | CONFIG_EXTRA_CFLAGS="" 53 | CONFIG_EXTRA_LDFLAGS="" 54 | CONFIG_EXTRA_LDLIBS="" 55 | # CONFIG_USE_PORTABLE_CODE is not set 56 | # CONFIG_STACK_OPTIMIZATION_386 is not set 57 | # CONFIG_STATIC_LIBGCC is not set 58 | 59 | # 60 | # Installation Options ("make install" behavior) 61 | # 62 | # CONFIG_INSTALL_APPLET_SYMLINKS is not set 63 | # CONFIG_INSTALL_APPLET_HARDLINKS is not set 64 | # CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set 65 | # CONFIG_INSTALL_APPLET_DONT is not set 66 | # CONFIG_INSTALL_SH_APPLET_SYMLINK is not set 67 | # CONFIG_INSTALL_SH_APPLET_HARDLINK is not set 68 | # CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set 69 | CONFIG_PREFIX="./_install" 70 | 71 | # 72 | # Debugging Options 73 | # 74 | # CONFIG_DEBUG is not set 75 | # CONFIG_DEBUG_PESSIMIZE is not set 76 | # CONFIG_DEBUG_SANITIZE is not set 77 | # CONFIG_UNIT_TEST is not set 78 | # CONFIG_WERROR is not set 79 | # CONFIG_WARN_SIMPLE_MSG is not set 80 | CONFIG_NO_DEBUG_LIB=y 81 | # CONFIG_DMALLOC is not set 82 | # CONFIG_EFENCE is not set 83 | 84 | # 85 | # Library Tuning 86 | # 87 | # CONFIG_FEATURE_USE_BSS_TAIL is not set 88 | # CONFIG_FLOAT_DURATION is not set 89 | # CONFIG_FEATURE_RTMINMAX is not set 90 | # CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set 91 | CONFIG_FEATURE_BUFFERS_USE_MALLOC=y 92 | # CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set 93 | # CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set 94 | CONFIG_PASSWORD_MINLEN=6 95 | CONFIG_MD5_SMALL=1 96 | CONFIG_SHA1_SMALL=3 97 | # CONFIG_SHA1_HWACCEL is not set 98 | # CONFIG_SHA256_HWACCEL is not set 99 | CONFIG_SHA3_SMALL=1 100 | # CONFIG_FEATURE_NON_POSIX_CP is not set 101 | # CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set 102 | # CONFIG_FEATURE_USE_SENDFILE is not set 103 | CONFIG_FEATURE_COPYBUF_KB=4 104 | # CONFIG_MONOTONIC_SYSCALL is not set 105 | # CONFIG_IOCTL_HEX2STR_ERROR is not set 106 | # CONFIG_FEATURE_EDITING is not set 107 | CONFIG_FEATURE_EDITING_MAX_LEN=0 108 | # CONFIG_FEATURE_EDITING_VI is not set 109 | CONFIG_FEATURE_EDITING_HISTORY=0 110 | # CONFIG_FEATURE_EDITING_SAVEHISTORY is not set 111 | # CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set 112 | # CONFIG_FEATURE_REVERSE_SEARCH is not set 113 | # CONFIG_FEATURE_TAB_COMPLETION is not set 114 | # CONFIG_FEATURE_USERNAME_COMPLETION is not set 115 | # CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set 116 | # CONFIG_FEATURE_EDITING_WINCH is not set 117 | # CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set 118 | # CONFIG_LOCALE_SUPPORT is not set 119 | # CONFIG_UNICODE_SUPPORT is not set 120 | # CONFIG_UNICODE_USING_LOCALE is not set 121 | # CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set 122 | CONFIG_SUBST_WCHAR=0 123 | CONFIG_LAST_SUPPORTED_WCHAR=0 124 | # CONFIG_UNICODE_COMBINING_WCHARS is not set 125 | # CONFIG_UNICODE_WIDE_WCHARS is not set 126 | # CONFIG_UNICODE_BIDI_SUPPORT is not set 127 | # CONFIG_UNICODE_NEUTRAL_TABLE is not set 128 | # CONFIG_UNICODE_PRESERVE_BROKEN is not set 129 | 130 | # 131 | # Applets 132 | # 133 | 134 | # 135 | # Archival Utilities 136 | # 137 | # CONFIG_FEATURE_SEAMLESS_XZ is not set 138 | # CONFIG_FEATURE_SEAMLESS_LZMA is not set 139 | # CONFIG_FEATURE_SEAMLESS_BZ2 is not set 140 | # CONFIG_FEATURE_SEAMLESS_GZ is not set 141 | # CONFIG_FEATURE_SEAMLESS_Z is not set 142 | # CONFIG_AR is not set 143 | # CONFIG_FEATURE_AR_LONG_FILENAMES is not set 144 | # CONFIG_FEATURE_AR_CREATE is not set 145 | # CONFIG_UNCOMPRESS is not set 146 | # CONFIG_GUNZIP is not set 147 | # CONFIG_ZCAT is not set 148 | # CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set 149 | # CONFIG_BUNZIP2 is not set 150 | # CONFIG_BZCAT is not set 151 | # CONFIG_UNLZMA is not set 152 | # CONFIG_LZCAT is not set 153 | # CONFIG_LZMA is not set 154 | # CONFIG_UNXZ is not set 155 | # CONFIG_XZCAT is not set 156 | # CONFIG_XZ is not set 157 | # CONFIG_BZIP2 is not set 158 | CONFIG_BZIP2_SMALL=0 159 | # CONFIG_FEATURE_BZIP2_DECOMPRESS is not set 160 | # CONFIG_CPIO is not set 161 | # CONFIG_FEATURE_CPIO_O is not set 162 | # CONFIG_FEATURE_CPIO_P is not set 163 | # CONFIG_FEATURE_CPIO_IGNORE_DEVNO is not set 164 | # CONFIG_FEATURE_CPIO_RENUMBER_INODES is not set 165 | # CONFIG_DPKG is not set 166 | # CONFIG_DPKG_DEB is not set 167 | # CONFIG_GZIP is not set 168 | # CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set 169 | CONFIG_GZIP_FAST=0 170 | # CONFIG_FEATURE_GZIP_LEVELS is not set 171 | # CONFIG_FEATURE_GZIP_DECOMPRESS is not set 172 | # CONFIG_LZOP is not set 173 | # CONFIG_UNLZOP is not set 174 | # CONFIG_LZOPCAT is not set 175 | # CONFIG_LZOP_COMPR_HIGH is not set 176 | # CONFIG_RPM is not set 177 | # CONFIG_RPM2CPIO is not set 178 | # CONFIG_TAR is not set 179 | # CONFIG_FEATURE_TAR_LONG_OPTIONS is not set 180 | # CONFIG_FEATURE_TAR_CREATE is not set 181 | # CONFIG_FEATURE_TAR_AUTODETECT is not set 182 | # CONFIG_FEATURE_TAR_FROM is not set 183 | # CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set 184 | # CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set 185 | # CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set 186 | # CONFIG_FEATURE_TAR_TO_COMMAND is not set 187 | # CONFIG_FEATURE_TAR_UNAME_GNAME is not set 188 | # CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set 189 | # CONFIG_FEATURE_TAR_SELINUX is not set 190 | # CONFIG_UNZIP is not set 191 | # CONFIG_FEATURE_UNZIP_CDF is not set 192 | # CONFIG_FEATURE_UNZIP_BZIP2 is not set 193 | # CONFIG_FEATURE_UNZIP_LZMA is not set 194 | # CONFIG_FEATURE_UNZIP_XZ is not set 195 | # CONFIG_FEATURE_LZMA_FAST is not set 196 | 197 | # 198 | # Coreutils 199 | # 200 | # CONFIG_FEATURE_VERBOSE is not set 201 | 202 | # 203 | # Common options for date and touch 204 | # 205 | # CONFIG_FEATURE_TIMEZONE is not set 206 | # CONFIG_FEATURE_PRESERVE_HARDLINKS is not set 207 | # CONFIG_FEATURE_HUMAN_READABLE is not set 208 | # CONFIG_BASENAME is not set 209 | # CONFIG_CAT is not set 210 | # CONFIG_FEATURE_CATN is not set 211 | # CONFIG_FEATURE_CATV is not set 212 | # CONFIG_CHGRP is not set 213 | # CONFIG_CHMOD is not set 214 | # CONFIG_CHOWN is not set 215 | # CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set 216 | # CONFIG_CHROOT is not set 217 | # CONFIG_CKSUM is not set 218 | # CONFIG_CRC32 is not set 219 | # CONFIG_COMM is not set 220 | # CONFIG_CP is not set 221 | # CONFIG_FEATURE_CP_LONG_OPTIONS is not set 222 | # CONFIG_FEATURE_CP_REFLINK is not set 223 | # CONFIG_CUT is not set 224 | # CONFIG_FEATURE_CUT_REGEX is not set 225 | # CONFIG_DATE is not set 226 | # CONFIG_FEATURE_DATE_ISOFMT is not set 227 | # CONFIG_FEATURE_DATE_NANO is not set 228 | # CONFIG_FEATURE_DATE_COMPAT is not set 229 | # CONFIG_DD is not set 230 | # CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set 231 | # CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set 232 | # CONFIG_FEATURE_DD_IBS_OBS is not set 233 | # CONFIG_FEATURE_DD_STATUS is not set 234 | # CONFIG_DF is not set 235 | # CONFIG_FEATURE_DF_FANCY is not set 236 | # CONFIG_FEATURE_SKIP_ROOTFS is not set 237 | # CONFIG_DIRNAME is not set 238 | # CONFIG_DOS2UNIX is not set 239 | # CONFIG_UNIX2DOS is not set 240 | # CONFIG_DU is not set 241 | # CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set 242 | # CONFIG_ECHO is not set 243 | # CONFIG_FEATURE_FANCY_ECHO is not set 244 | # CONFIG_ENV is not set 245 | # CONFIG_EXPAND is not set 246 | # CONFIG_UNEXPAND is not set 247 | # CONFIG_EXPR is not set 248 | # CONFIG_EXPR_MATH_SUPPORT_64 is not set 249 | # CONFIG_FACTOR is not set 250 | # CONFIG_FALSE is not set 251 | # CONFIG_FOLD is not set 252 | # CONFIG_HEAD is not set 253 | # CONFIG_FEATURE_FANCY_HEAD is not set 254 | # CONFIG_HOSTID is not set 255 | # CONFIG_ID is not set 256 | # CONFIG_GROUPS is not set 257 | # CONFIG_INSTALL is not set 258 | # CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set 259 | # CONFIG_LINK is not set 260 | # CONFIG_LN is not set 261 | # CONFIG_LOGNAME is not set 262 | # CONFIG_LS is not set 263 | # CONFIG_FEATURE_LS_FILETYPES is not set 264 | # CONFIG_FEATURE_LS_FOLLOWLINKS is not set 265 | # CONFIG_FEATURE_LS_RECURSIVE is not set 266 | # CONFIG_FEATURE_LS_WIDTH is not set 267 | # CONFIG_FEATURE_LS_SORTFILES is not set 268 | # CONFIG_FEATURE_LS_TIMESTAMPS is not set 269 | # CONFIG_FEATURE_LS_USERNAME is not set 270 | # CONFIG_FEATURE_LS_COLOR is not set 271 | # CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set 272 | # CONFIG_MD5SUM is not set 273 | # CONFIG_SHA1SUM is not set 274 | # CONFIG_SHA256SUM is not set 275 | # CONFIG_SHA512SUM is not set 276 | # CONFIG_SHA3SUM is not set 277 | # CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set 278 | # CONFIG_MKDIR is not set 279 | # CONFIG_MKFIFO is not set 280 | # CONFIG_MKNOD is not set 281 | # CONFIG_MKTEMP is not set 282 | # CONFIG_MV is not set 283 | # CONFIG_NICE is not set 284 | # CONFIG_NL is not set 285 | # CONFIG_NOHUP is not set 286 | # CONFIG_NPROC is not set 287 | # CONFIG_OD is not set 288 | # CONFIG_PASTE is not set 289 | # CONFIG_PRINTENV is not set 290 | # CONFIG_PRINTF is not set 291 | # CONFIG_PWD is not set 292 | # CONFIG_READLINK is not set 293 | # CONFIG_FEATURE_READLINK_FOLLOW is not set 294 | # CONFIG_REALPATH is not set 295 | # CONFIG_RM is not set 296 | # CONFIG_RMDIR is not set 297 | # CONFIG_SEQ is not set 298 | # CONFIG_SHRED is not set 299 | # CONFIG_SHUF is not set 300 | # CONFIG_SLEEP is not set 301 | # CONFIG_FEATURE_FANCY_SLEEP is not set 302 | # CONFIG_SORT is not set 303 | # CONFIG_FEATURE_SORT_BIG is not set 304 | # CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set 305 | # CONFIG_SPLIT is not set 306 | # CONFIG_FEATURE_SPLIT_FANCY is not set 307 | # CONFIG_STAT is not set 308 | # CONFIG_FEATURE_STAT_FORMAT is not set 309 | # CONFIG_FEATURE_STAT_FILESYSTEM is not set 310 | # CONFIG_STTY is not set 311 | # CONFIG_SUM is not set 312 | # CONFIG_SYNC is not set 313 | # CONFIG_FEATURE_SYNC_FANCY is not set 314 | # CONFIG_FSYNC is not set 315 | # CONFIG_TAC is not set 316 | # CONFIG_TAIL is not set 317 | # CONFIG_FEATURE_FANCY_TAIL is not set 318 | # CONFIG_TEE is not set 319 | # CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set 320 | # CONFIG_TEST is not set 321 | # CONFIG_TEST1 is not set 322 | # CONFIG_TEST2 is not set 323 | # CONFIG_FEATURE_TEST_64 is not set 324 | # CONFIG_TIMEOUT is not set 325 | # CONFIG_TOUCH is not set 326 | # CONFIG_FEATURE_TOUCH_SUSV3 is not set 327 | # CONFIG_TR is not set 328 | # CONFIG_FEATURE_TR_CLASSES is not set 329 | # CONFIG_FEATURE_TR_EQUIV is not set 330 | # CONFIG_TRUE is not set 331 | # CONFIG_TRUNCATE is not set 332 | # CONFIG_TSORT is not set 333 | # CONFIG_TTY is not set 334 | # CONFIG_UNAME is not set 335 | CONFIG_UNAME_OSNAME="" 336 | # CONFIG_BB_ARCH is not set 337 | # CONFIG_UNIQ is not set 338 | # CONFIG_UNLINK is not set 339 | # CONFIG_USLEEP is not set 340 | # CONFIG_UUDECODE is not set 341 | # CONFIG_BASE32 is not set 342 | # CONFIG_BASE64 is not set 343 | # CONFIG_UUENCODE is not set 344 | # CONFIG_WC is not set 345 | # CONFIG_FEATURE_WC_LARGE is not set 346 | # CONFIG_WHO is not set 347 | # CONFIG_W is not set 348 | # CONFIG_USERS is not set 349 | # CONFIG_WHOAMI is not set 350 | # CONFIG_YES is not set 351 | 352 | # 353 | # Console Utilities 354 | # 355 | # CONFIG_CHVT is not set 356 | # CONFIG_CLEAR is not set 357 | # CONFIG_DEALLOCVT is not set 358 | # CONFIG_DUMPKMAP is not set 359 | # CONFIG_FGCONSOLE is not set 360 | # CONFIG_KBD_MODE is not set 361 | # CONFIG_LOADFONT is not set 362 | # CONFIG_SETFONT is not set 363 | # CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set 364 | CONFIG_DEFAULT_SETFONT_DIR="" 365 | # CONFIG_FEATURE_LOADFONT_PSF2 is not set 366 | # CONFIG_FEATURE_LOADFONT_RAW is not set 367 | # CONFIG_LOADKMAP is not set 368 | # CONFIG_OPENVT is not set 369 | # CONFIG_RESET is not set 370 | # CONFIG_RESIZE is not set 371 | # CONFIG_FEATURE_RESIZE_PRINT is not set 372 | # CONFIG_SETCONSOLE is not set 373 | # CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set 374 | # CONFIG_SETKEYCODES is not set 375 | # CONFIG_SETLOGCONS is not set 376 | # CONFIG_SHOWKEY is not set 377 | 378 | # 379 | # Debian Utilities 380 | # 381 | # CONFIG_PIPE_PROGRESS is not set 382 | # CONFIG_RUN_PARTS is not set 383 | # CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set 384 | # CONFIG_FEATURE_RUN_PARTS_FANCY is not set 385 | # CONFIG_START_STOP_DAEMON is not set 386 | # CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set 387 | # CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set 388 | # CONFIG_WHICH is not set 389 | 390 | # 391 | # klibc-utils 392 | # 393 | # CONFIG_MINIPS is not set 394 | # CONFIG_NUKE is not set 395 | # CONFIG_RESUME is not set 396 | # CONFIG_RUN_INIT is not set 397 | 398 | # 399 | # Editors 400 | # 401 | # CONFIG_AWK is not set 402 | # CONFIG_FEATURE_AWK_LIBM is not set 403 | # CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set 404 | # CONFIG_CMP is not set 405 | # CONFIG_DIFF is not set 406 | # CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set 407 | # CONFIG_FEATURE_DIFF_DIR is not set 408 | # CONFIG_ED is not set 409 | # CONFIG_PATCH is not set 410 | # CONFIG_SED is not set 411 | # CONFIG_VI is not set 412 | CONFIG_FEATURE_VI_MAX_LEN=0 413 | # CONFIG_FEATURE_VI_8BIT is not set 414 | # CONFIG_FEATURE_VI_COLON is not set 415 | # CONFIG_FEATURE_VI_COLON_EXPAND is not set 416 | # CONFIG_FEATURE_VI_YANKMARK is not set 417 | # CONFIG_FEATURE_VI_SEARCH is not set 418 | # CONFIG_FEATURE_VI_REGEX_SEARCH is not set 419 | # CONFIG_FEATURE_VI_USE_SIGNALS is not set 420 | # CONFIG_FEATURE_VI_DOT_CMD is not set 421 | # CONFIG_FEATURE_VI_READONLY is not set 422 | # CONFIG_FEATURE_VI_SETOPTS is not set 423 | # CONFIG_FEATURE_VI_SET is not set 424 | # CONFIG_FEATURE_VI_WIN_RESIZE is not set 425 | # CONFIG_FEATURE_VI_ASK_TERMINAL is not set 426 | # CONFIG_FEATURE_VI_UNDO is not set 427 | # CONFIG_FEATURE_VI_UNDO_QUEUE is not set 428 | CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0 429 | # CONFIG_FEATURE_VI_VERBOSE_STATUS is not set 430 | # CONFIG_FEATURE_ALLOW_EXEC is not set 431 | 432 | # 433 | # Finding Utilities 434 | # 435 | # CONFIG_FIND is not set 436 | # CONFIG_FEATURE_FIND_PRINT0 is not set 437 | # CONFIG_FEATURE_FIND_MTIME is not set 438 | # CONFIG_FEATURE_FIND_ATIME is not set 439 | # CONFIG_FEATURE_FIND_CTIME is not set 440 | # CONFIG_FEATURE_FIND_MMIN is not set 441 | # CONFIG_FEATURE_FIND_AMIN is not set 442 | # CONFIG_FEATURE_FIND_CMIN is not set 443 | # CONFIG_FEATURE_FIND_PERM is not set 444 | # CONFIG_FEATURE_FIND_TYPE is not set 445 | # CONFIG_FEATURE_FIND_EXECUTABLE is not set 446 | # CONFIG_FEATURE_FIND_XDEV is not set 447 | # CONFIG_FEATURE_FIND_MAXDEPTH is not set 448 | # CONFIG_FEATURE_FIND_NEWER is not set 449 | # CONFIG_FEATURE_FIND_INUM is not set 450 | # CONFIG_FEATURE_FIND_SAMEFILE is not set 451 | # CONFIG_FEATURE_FIND_EXEC is not set 452 | # CONFIG_FEATURE_FIND_EXEC_PLUS is not set 453 | # CONFIG_FEATURE_FIND_USER is not set 454 | # CONFIG_FEATURE_FIND_GROUP is not set 455 | # CONFIG_FEATURE_FIND_NOT is not set 456 | # CONFIG_FEATURE_FIND_DEPTH is not set 457 | # CONFIG_FEATURE_FIND_PAREN is not set 458 | # CONFIG_FEATURE_FIND_SIZE is not set 459 | # CONFIG_FEATURE_FIND_PRUNE is not set 460 | # CONFIG_FEATURE_FIND_QUIT is not set 461 | # CONFIG_FEATURE_FIND_DELETE is not set 462 | # CONFIG_FEATURE_FIND_EMPTY is not set 463 | # CONFIG_FEATURE_FIND_PATH is not set 464 | # CONFIG_FEATURE_FIND_REGEX is not set 465 | # CONFIG_FEATURE_FIND_CONTEXT is not set 466 | # CONFIG_FEATURE_FIND_LINKS is not set 467 | # CONFIG_GREP is not set 468 | # CONFIG_EGREP is not set 469 | # CONFIG_FGREP is not set 470 | # CONFIG_FEATURE_GREP_CONTEXT is not set 471 | # CONFIG_XARGS is not set 472 | # CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set 473 | # CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set 474 | # CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set 475 | # CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set 476 | # CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set 477 | # CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set 478 | # CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set 479 | 480 | # 481 | # Init Utilities 482 | # 483 | # CONFIG_BOOTCHARTD is not set 484 | # CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set 485 | # CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set 486 | # CONFIG_HALT is not set 487 | # CONFIG_POWEROFF is not set 488 | # CONFIG_REBOOT is not set 489 | # CONFIG_FEATURE_WAIT_FOR_INIT is not set 490 | # CONFIG_FEATURE_CALL_TELINIT is not set 491 | CONFIG_TELINIT_PATH="" 492 | # CONFIG_INIT is not set 493 | # CONFIG_LINUXRC is not set 494 | # CONFIG_FEATURE_USE_INITTAB is not set 495 | # CONFIG_FEATURE_KILL_REMOVED is not set 496 | CONFIG_FEATURE_KILL_DELAY=0 497 | # CONFIG_FEATURE_INIT_SCTTY is not set 498 | # CONFIG_FEATURE_INIT_SYSLOG is not set 499 | # CONFIG_FEATURE_INIT_QUIET is not set 500 | # CONFIG_FEATURE_INIT_COREDUMPS is not set 501 | CONFIG_INIT_TERMINAL_TYPE="" 502 | # CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set 503 | 504 | # 505 | # Login/Password Management Utilities 506 | # 507 | # CONFIG_FEATURE_SHADOWPASSWDS is not set 508 | # CONFIG_USE_BB_PWD_GRP is not set 509 | # CONFIG_USE_BB_SHADOW is not set 510 | # CONFIG_USE_BB_CRYPT is not set 511 | # CONFIG_USE_BB_CRYPT_SHA is not set 512 | # CONFIG_ADD_SHELL is not set 513 | # CONFIG_REMOVE_SHELL is not set 514 | # CONFIG_ADDGROUP is not set 515 | # CONFIG_FEATURE_ADDUSER_TO_GROUP is not set 516 | # CONFIG_ADDUSER is not set 517 | # CONFIG_FEATURE_CHECK_NAMES is not set 518 | CONFIG_LAST_ID=0 519 | CONFIG_FIRST_SYSTEM_ID=0 520 | CONFIG_LAST_SYSTEM_ID=0 521 | # CONFIG_CHPASSWD is not set 522 | CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" 523 | # CONFIG_CRYPTPW is not set 524 | # CONFIG_MKPASSWD is not set 525 | # CONFIG_DELUSER is not set 526 | # CONFIG_DELGROUP is not set 527 | # CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set 528 | # CONFIG_GETTY is not set 529 | # CONFIG_LOGIN is not set 530 | # CONFIG_LOGIN_SESSION_AS_CHILD is not set 531 | # CONFIG_LOGIN_SCRIPTS is not set 532 | # CONFIG_FEATURE_NOLOGIN is not set 533 | # CONFIG_FEATURE_SECURETTY is not set 534 | # CONFIG_PASSWD is not set 535 | # CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set 536 | # CONFIG_SU is not set 537 | # CONFIG_FEATURE_SU_SYSLOG is not set 538 | # CONFIG_FEATURE_SU_CHECKS_SHELLS is not set 539 | # CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set 540 | # CONFIG_SULOGIN is not set 541 | # CONFIG_VLOCK is not set 542 | 543 | # 544 | # Linux Ext2 FS Progs 545 | # 546 | # CONFIG_CHATTR is not set 547 | # CONFIG_FSCK is not set 548 | # CONFIG_LSATTR is not set 549 | # CONFIG_TUNE2FS is not set 550 | 551 | # 552 | # Linux Module Utilities 553 | # 554 | # CONFIG_MODPROBE_SMALL is not set 555 | # CONFIG_DEPMOD is not set 556 | # CONFIG_INSMOD is not set 557 | # CONFIG_LSMOD is not set 558 | # CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set 559 | # CONFIG_MODINFO is not set 560 | # CONFIG_MODPROBE is not set 561 | # CONFIG_FEATURE_MODPROBE_BLACKLIST is not set 562 | # CONFIG_RMMOD is not set 563 | 564 | # 565 | # Options common to multiple modutils 566 | # 567 | # CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set 568 | # CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set 569 | # CONFIG_FEATURE_2_4_MODULES is not set 570 | # CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set 571 | # CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set 572 | # CONFIG_FEATURE_INSMOD_LOADINKMEM is not set 573 | # CONFIG_FEATURE_INSMOD_LOAD_MAP is not set 574 | # CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set 575 | # CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set 576 | # CONFIG_FEATURE_INSMOD_TRY_MMAP is not set 577 | # CONFIG_FEATURE_MODUTILS_ALIAS is not set 578 | # CONFIG_FEATURE_MODUTILS_SYMBOLS is not set 579 | CONFIG_DEFAULT_MODULES_DIR="" 580 | CONFIG_DEFAULT_DEPMOD_FILE="" 581 | 582 | # 583 | # Linux System Utilities 584 | # 585 | # CONFIG_ACPID is not set 586 | # CONFIG_FEATURE_ACPID_COMPAT is not set 587 | # CONFIG_BLKDISCARD is not set 588 | # CONFIG_BLKID is not set 589 | # CONFIG_FEATURE_BLKID_TYPE is not set 590 | # CONFIG_BLOCKDEV is not set 591 | # CONFIG_CAL is not set 592 | # CONFIG_CHRT is not set 593 | # CONFIG_DMESG is not set 594 | # CONFIG_FEATURE_DMESG_PRETTY is not set 595 | # CONFIG_EJECT is not set 596 | # CONFIG_FEATURE_EJECT_SCSI is not set 597 | # CONFIG_FALLOCATE is not set 598 | # CONFIG_FATATTR is not set 599 | # CONFIG_FBSET is not set 600 | # CONFIG_FEATURE_FBSET_FANCY is not set 601 | # CONFIG_FEATURE_FBSET_READMODE is not set 602 | # CONFIG_FDFORMAT is not set 603 | # CONFIG_FDISK is not set 604 | # CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set 605 | # CONFIG_FEATURE_FDISK_WRITABLE is not set 606 | # CONFIG_FEATURE_AIX_LABEL is not set 607 | # CONFIG_FEATURE_SGI_LABEL is not set 608 | # CONFIG_FEATURE_SUN_LABEL is not set 609 | # CONFIG_FEATURE_OSF_LABEL is not set 610 | # CONFIG_FEATURE_GPT_LABEL is not set 611 | # CONFIG_FEATURE_FDISK_ADVANCED is not set 612 | # CONFIG_FINDFS is not set 613 | # CONFIG_FLOCK is not set 614 | # CONFIG_FDFLUSH is not set 615 | # CONFIG_FREERAMDISK is not set 616 | # CONFIG_FSCK_MINIX is not set 617 | # CONFIG_FSFREEZE is not set 618 | # CONFIG_FSTRIM is not set 619 | # CONFIG_GETOPT is not set 620 | # CONFIG_FEATURE_GETOPT_LONG is not set 621 | # CONFIG_HEXDUMP is not set 622 | # CONFIG_HD is not set 623 | # CONFIG_XXD is not set 624 | # CONFIG_HWCLOCK is not set 625 | # CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set 626 | # CONFIG_IONICE is not set 627 | # CONFIG_IPCRM is not set 628 | # CONFIG_IPCS is not set 629 | # CONFIG_LAST is not set 630 | # CONFIG_FEATURE_LAST_FANCY is not set 631 | # CONFIG_LOSETUP is not set 632 | # CONFIG_LSPCI is not set 633 | # CONFIG_LSUSB is not set 634 | # CONFIG_MDEV is not set 635 | # CONFIG_FEATURE_MDEV_CONF is not set 636 | # CONFIG_FEATURE_MDEV_RENAME is not set 637 | # CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set 638 | # CONFIG_FEATURE_MDEV_EXEC is not set 639 | # CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set 640 | # CONFIG_FEATURE_MDEV_DAEMON is not set 641 | # CONFIG_MESG is not set 642 | # CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set 643 | # CONFIG_MKE2FS is not set 644 | # CONFIG_MKFS_EXT2 is not set 645 | # CONFIG_MKFS_MINIX is not set 646 | # CONFIG_FEATURE_MINIX2 is not set 647 | # CONFIG_MKFS_REISER is not set 648 | # CONFIG_MKDOSFS is not set 649 | # CONFIG_MKFS_VFAT is not set 650 | # CONFIG_MKSWAP is not set 651 | # CONFIG_FEATURE_MKSWAP_UUID is not set 652 | # CONFIG_MORE is not set 653 | # CONFIG_MOUNT is not set 654 | # CONFIG_FEATURE_MOUNT_FAKE is not set 655 | # CONFIG_FEATURE_MOUNT_VERBOSE is not set 656 | # CONFIG_FEATURE_MOUNT_HELPERS is not set 657 | # CONFIG_FEATURE_MOUNT_LABEL is not set 658 | # CONFIG_FEATURE_MOUNT_NFS is not set 659 | # CONFIG_FEATURE_MOUNT_CIFS is not set 660 | # CONFIG_FEATURE_MOUNT_FLAGS is not set 661 | # CONFIG_FEATURE_MOUNT_FSTAB is not set 662 | # CONFIG_FEATURE_MOUNT_OTHERTAB is not set 663 | # CONFIG_MOUNTPOINT is not set 664 | # CONFIG_NOLOGIN is not set 665 | # CONFIG_NOLOGIN_DEPENDENCIES is not set 666 | # CONFIG_NSENTER is not set 667 | # CONFIG_PIVOT_ROOT is not set 668 | # CONFIG_RDATE is not set 669 | # CONFIG_RDEV is not set 670 | # CONFIG_READPROFILE is not set 671 | # CONFIG_RENICE is not set 672 | # CONFIG_REV is not set 673 | # CONFIG_RTCWAKE is not set 674 | # CONFIG_SCRIPT is not set 675 | # CONFIG_SCRIPTREPLAY is not set 676 | # CONFIG_SETARCH is not set 677 | # CONFIG_LINUX32 is not set 678 | # CONFIG_LINUX64 is not set 679 | # CONFIG_SETPRIV is not set 680 | # CONFIG_FEATURE_SETPRIV_DUMP is not set 681 | # CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set 682 | # CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set 683 | # CONFIG_SETSID is not set 684 | # CONFIG_SWAPON is not set 685 | # CONFIG_FEATURE_SWAPON_DISCARD is not set 686 | # CONFIG_FEATURE_SWAPON_PRI is not set 687 | # CONFIG_SWAPOFF is not set 688 | # CONFIG_FEATURE_SWAPONOFF_LABEL is not set 689 | # CONFIG_SWITCH_ROOT is not set 690 | # CONFIG_TASKSET is not set 691 | # CONFIG_FEATURE_TASKSET_FANCY is not set 692 | # CONFIG_FEATURE_TASKSET_CPULIST is not set 693 | # CONFIG_UEVENT is not set 694 | # CONFIG_UMOUNT is not set 695 | # CONFIG_FEATURE_UMOUNT_ALL is not set 696 | # CONFIG_UNSHARE is not set 697 | # CONFIG_WALL is not set 698 | # CONFIG_FEATURE_MOUNT_LOOP is not set 699 | # CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set 700 | # CONFIG_FEATURE_MTAB_SUPPORT is not set 701 | # CONFIG_VOLUMEID is not set 702 | # CONFIG_FEATURE_VOLUMEID_BCACHE is not set 703 | # CONFIG_FEATURE_VOLUMEID_BTRFS is not set 704 | # CONFIG_FEATURE_VOLUMEID_CRAMFS is not set 705 | # CONFIG_FEATURE_VOLUMEID_EROFS is not set 706 | # CONFIG_FEATURE_VOLUMEID_EXFAT is not set 707 | # CONFIG_FEATURE_VOLUMEID_EXT is not set 708 | # CONFIG_FEATURE_VOLUMEID_F2FS is not set 709 | # CONFIG_FEATURE_VOLUMEID_FAT is not set 710 | # CONFIG_FEATURE_VOLUMEID_HFS is not set 711 | # CONFIG_FEATURE_VOLUMEID_ISO9660 is not set 712 | # CONFIG_FEATURE_VOLUMEID_JFS is not set 713 | # CONFIG_FEATURE_VOLUMEID_LFS is not set 714 | # CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set 715 | # CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set 716 | # CONFIG_FEATURE_VOLUMEID_LUKS is not set 717 | # CONFIG_FEATURE_VOLUMEID_MINIX is not set 718 | # CONFIG_FEATURE_VOLUMEID_NILFS is not set 719 | # CONFIG_FEATURE_VOLUMEID_NTFS is not set 720 | # CONFIG_FEATURE_VOLUMEID_OCFS2 is not set 721 | # CONFIG_FEATURE_VOLUMEID_REISERFS is not set 722 | # CONFIG_FEATURE_VOLUMEID_ROMFS is not set 723 | # CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set 724 | # CONFIG_FEATURE_VOLUMEID_SYSV is not set 725 | # CONFIG_FEATURE_VOLUMEID_UBIFS is not set 726 | # CONFIG_FEATURE_VOLUMEID_UDF is not set 727 | # CONFIG_FEATURE_VOLUMEID_XFS is not set 728 | 729 | # 730 | # Miscellaneous Utilities 731 | # 732 | # CONFIG_ADJTIMEX is not set 733 | # CONFIG_ASCII is not set 734 | # CONFIG_BBCONFIG is not set 735 | # CONFIG_FEATURE_COMPRESS_BBCONFIG is not set 736 | # CONFIG_BC is not set 737 | # CONFIG_DC is not set 738 | # CONFIG_FEATURE_DC_BIG is not set 739 | # CONFIG_FEATURE_DC_LIBM is not set 740 | # CONFIG_FEATURE_BC_INTERACTIVE is not set 741 | # CONFIG_FEATURE_BC_LONG_OPTIONS is not set 742 | # CONFIG_BEEP is not set 743 | CONFIG_FEATURE_BEEP_FREQ=0 744 | CONFIG_FEATURE_BEEP_LENGTH_MS=0 745 | # CONFIG_CHAT is not set 746 | # CONFIG_FEATURE_CHAT_NOFAIL is not set 747 | # CONFIG_FEATURE_CHAT_TTY_HIFI is not set 748 | # CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set 749 | # CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set 750 | # CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set 751 | # CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set 752 | # CONFIG_FEATURE_CHAT_CLR_ABORT is not set 753 | # CONFIG_CONSPY is not set 754 | # CONFIG_CROND is not set 755 | # CONFIG_FEATURE_CROND_D is not set 756 | # CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set 757 | # CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set 758 | CONFIG_FEATURE_CROND_DIR="" 759 | # CONFIG_CRONTAB is not set 760 | # CONFIG_DEVFSD is not set 761 | # CONFIG_DEVFSD_MODLOAD is not set 762 | # CONFIG_DEVFSD_FG_NP is not set 763 | # CONFIG_DEVFSD_VERBOSE is not set 764 | # CONFIG_FEATURE_DEVFS is not set 765 | # CONFIG_DEVMEM is not set 766 | # CONFIG_FBSPLASH is not set 767 | # CONFIG_FLASH_ERASEALL is not set 768 | # CONFIG_FLASH_LOCK is not set 769 | # CONFIG_FLASH_UNLOCK is not set 770 | # CONFIG_FLASHCP is not set 771 | # CONFIG_HDPARM is not set 772 | # CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set 773 | # CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set 774 | # CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set 775 | # CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set 776 | # CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set 777 | # CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set 778 | # CONFIG_HEXEDIT is not set 779 | # CONFIG_I2CGET is not set 780 | # CONFIG_I2CSET is not set 781 | # CONFIG_I2CDUMP is not set 782 | # CONFIG_I2CDETECT is not set 783 | # CONFIG_I2CTRANSFER is not set 784 | # CONFIG_INOTIFYD is not set 785 | # CONFIG_LESS is not set 786 | CONFIG_FEATURE_LESS_MAXLINES=0 787 | # CONFIG_FEATURE_LESS_BRACKETS is not set 788 | # CONFIG_FEATURE_LESS_FLAGS is not set 789 | # CONFIG_FEATURE_LESS_TRUNCATE is not set 790 | # CONFIG_FEATURE_LESS_MARKS is not set 791 | # CONFIG_FEATURE_LESS_REGEXP is not set 792 | # CONFIG_FEATURE_LESS_WINCH is not set 793 | # CONFIG_FEATURE_LESS_ASK_TERMINAL is not set 794 | # CONFIG_FEATURE_LESS_DASHCMD is not set 795 | # CONFIG_FEATURE_LESS_LINENUMS is not set 796 | # CONFIG_FEATURE_LESS_RAW is not set 797 | # CONFIG_FEATURE_LESS_ENV is not set 798 | # CONFIG_LSSCSI is not set 799 | # CONFIG_MAKEDEVS is not set 800 | # CONFIG_FEATURE_MAKEDEVS_LEAF is not set 801 | # CONFIG_FEATURE_MAKEDEVS_TABLE is not set 802 | # CONFIG_MAN is not set 803 | # CONFIG_MICROCOM is not set 804 | # CONFIG_MIM is not set 805 | # CONFIG_MT is not set 806 | # CONFIG_NANDWRITE is not set 807 | # CONFIG_NANDDUMP is not set 808 | # CONFIG_PARTPROBE is not set 809 | # CONFIG_RAIDAUTORUN is not set 810 | # CONFIG_READAHEAD is not set 811 | # CONFIG_RFKILL is not set 812 | # CONFIG_RUNLEVEL is not set 813 | # CONFIG_RX is not set 814 | # CONFIG_SEEDRNG is not set 815 | # CONFIG_SETFATTR is not set 816 | # CONFIG_SETSERIAL is not set 817 | # CONFIG_STRINGS is not set 818 | # CONFIG_TIME is not set 819 | # CONFIG_TREE is not set 820 | # CONFIG_TS is not set 821 | # CONFIG_TTYSIZE is not set 822 | # CONFIG_UBIATTACH is not set 823 | # CONFIG_UBIDETACH is not set 824 | # CONFIG_UBIMKVOL is not set 825 | # CONFIG_UBIRMVOL is not set 826 | # CONFIG_UBIRSVOL is not set 827 | # CONFIG_UBIUPDATEVOL is not set 828 | # CONFIG_UBIRENAME is not set 829 | # CONFIG_VOLNAME is not set 830 | # CONFIG_WATCHDOG is not set 831 | # CONFIG_FEATURE_WATCHDOG_OPEN_TWICE is not set 832 | 833 | # 834 | # Networking Utilities 835 | # 836 | # CONFIG_FEATURE_IPV6 is not set 837 | # CONFIG_FEATURE_UNIX_LOCAL is not set 838 | # CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set 839 | # CONFIG_VERBOSE_RESOLUTION_ERRORS is not set 840 | # CONFIG_FEATURE_ETC_NETWORKS is not set 841 | # CONFIG_FEATURE_ETC_SERVICES is not set 842 | # CONFIG_FEATURE_HWIB is not set 843 | # CONFIG_FEATURE_TLS_SHA1 is not set 844 | # CONFIG_ARP is not set 845 | # CONFIG_ARPING is not set 846 | # CONFIG_BRCTL is not set 847 | # CONFIG_FEATURE_BRCTL_FANCY is not set 848 | # CONFIG_FEATURE_BRCTL_SHOW is not set 849 | # CONFIG_DNSD is not set 850 | # CONFIG_ETHER_WAKE is not set 851 | # CONFIG_FTPD is not set 852 | # CONFIG_FEATURE_FTPD_WRITE is not set 853 | # CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set 854 | # CONFIG_FEATURE_FTPD_AUTHENTICATION is not set 855 | # CONFIG_FTPGET is not set 856 | # CONFIG_FTPPUT is not set 857 | # CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set 858 | # CONFIG_HOSTNAME is not set 859 | # CONFIG_DNSDOMAINNAME is not set 860 | CONFIG_HTTPD=y 861 | CONFIG_FEATURE_HTTPD_PORT_DEFAULT=80 862 | # CONFIG_FEATURE_HTTPD_RANGES is not set 863 | # CONFIG_FEATURE_HTTPD_SETUID is not set 864 | CONFIG_FEATURE_HTTPD_BASIC_AUTH=y 865 | # CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set 866 | # CONFIG_FEATURE_HTTPD_CGI is not set 867 | # CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set 868 | # CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set 869 | # CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set 870 | CONFIG_FEATURE_HTTPD_ERROR_PAGES=y 871 | CONFIG_FEATURE_HTTPD_PROXY=y 872 | CONFIG_FEATURE_HTTPD_GZIP=y 873 | CONFIG_FEATURE_HTTPD_ETAG=y 874 | CONFIG_FEATURE_HTTPD_LAST_MODIFIED=y 875 | CONFIG_FEATURE_HTTPD_DATE=y 876 | CONFIG_FEATURE_HTTPD_ACL_IP=y 877 | # CONFIG_IFCONFIG is not set 878 | # CONFIG_FEATURE_IFCONFIG_STATUS is not set 879 | # CONFIG_FEATURE_IFCONFIG_SLIP is not set 880 | # CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set 881 | # CONFIG_FEATURE_IFCONFIG_HW is not set 882 | # CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set 883 | # CONFIG_IFENSLAVE is not set 884 | # CONFIG_IFPLUGD is not set 885 | # CONFIG_IFUP is not set 886 | # CONFIG_IFDOWN is not set 887 | CONFIG_IFUPDOWN_IFSTATE_PATH="" 888 | # CONFIG_FEATURE_IFUPDOWN_IP is not set 889 | # CONFIG_FEATURE_IFUPDOWN_IPV4 is not set 890 | # CONFIG_FEATURE_IFUPDOWN_IPV6 is not set 891 | # CONFIG_FEATURE_IFUPDOWN_MAPPING is not set 892 | # CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set 893 | # CONFIG_INETD is not set 894 | # CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set 895 | # CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set 896 | # CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set 897 | # CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set 898 | # CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set 899 | # CONFIG_FEATURE_INETD_RPC is not set 900 | # CONFIG_IP is not set 901 | # CONFIG_IPADDR is not set 902 | # CONFIG_IPLINK is not set 903 | # CONFIG_IPROUTE is not set 904 | # CONFIG_IPTUNNEL is not set 905 | # CONFIG_IPRULE is not set 906 | # CONFIG_IPNEIGH is not set 907 | # CONFIG_FEATURE_IP_ADDRESS is not set 908 | # CONFIG_FEATURE_IP_LINK is not set 909 | # CONFIG_FEATURE_IP_ROUTE is not set 910 | CONFIG_FEATURE_IP_ROUTE_DIR="" 911 | # CONFIG_FEATURE_IP_TUNNEL is not set 912 | # CONFIG_FEATURE_IP_RULE is not set 913 | # CONFIG_FEATURE_IP_NEIGH is not set 914 | # CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set 915 | # CONFIG_IPCALC is not set 916 | # CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set 917 | # CONFIG_FEATURE_IPCALC_FANCY is not set 918 | # CONFIG_FAKEIDENTD is not set 919 | # CONFIG_NAMEIF is not set 920 | # CONFIG_FEATURE_NAMEIF_EXTENDED is not set 921 | # CONFIG_NBDCLIENT is not set 922 | # CONFIG_NC is not set 923 | # CONFIG_NETCAT is not set 924 | # CONFIG_NC_SERVER is not set 925 | # CONFIG_NC_EXTRA is not set 926 | # CONFIG_NC_110_COMPAT is not set 927 | # CONFIG_NETSTAT is not set 928 | # CONFIG_FEATURE_NETSTAT_WIDE is not set 929 | # CONFIG_FEATURE_NETSTAT_PRG is not set 930 | # CONFIG_NSLOOKUP is not set 931 | # CONFIG_FEATURE_NSLOOKUP_BIG is not set 932 | # CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set 933 | # CONFIG_NTPD is not set 934 | # CONFIG_FEATURE_NTPD_SERVER is not set 935 | # CONFIG_FEATURE_NTPD_CONF is not set 936 | # CONFIG_FEATURE_NTP_AUTH is not set 937 | # CONFIG_PING is not set 938 | # CONFIG_PING6 is not set 939 | # CONFIG_FEATURE_FANCY_PING is not set 940 | # CONFIG_PSCAN is not set 941 | # CONFIG_ROUTE is not set 942 | # CONFIG_SLATTACH is not set 943 | # CONFIG_SSL_CLIENT is not set 944 | # CONFIG_TC is not set 945 | # CONFIG_FEATURE_TC_INGRESS is not set 946 | # CONFIG_TCPSVD is not set 947 | # CONFIG_UDPSVD is not set 948 | # CONFIG_TELNET is not set 949 | # CONFIG_FEATURE_TELNET_TTYPE is not set 950 | # CONFIG_FEATURE_TELNET_AUTOLOGIN is not set 951 | # CONFIG_FEATURE_TELNET_WIDTH is not set 952 | # CONFIG_TELNETD is not set 953 | # CONFIG_FEATURE_TELNETD_STANDALONE is not set 954 | CONFIG_FEATURE_TELNETD_PORT_DEFAULT=0 955 | # CONFIG_FEATURE_TELNETD_INETD_WAIT is not set 956 | # CONFIG_TFTP is not set 957 | # CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set 958 | # CONFIG_FEATURE_TFTP_HPA_COMPAT is not set 959 | # CONFIG_TFTPD is not set 960 | # CONFIG_FEATURE_TFTP_GET is not set 961 | # CONFIG_FEATURE_TFTP_PUT is not set 962 | # CONFIG_FEATURE_TFTP_BLOCKSIZE is not set 963 | # CONFIG_TFTP_DEBUG is not set 964 | # CONFIG_TLS is not set 965 | # CONFIG_TRACEROUTE is not set 966 | # CONFIG_TRACEROUTE6 is not set 967 | # CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set 968 | # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set 969 | # CONFIG_TUNCTL is not set 970 | # CONFIG_FEATURE_TUNCTL_UG is not set 971 | # CONFIG_VCONFIG is not set 972 | # CONFIG_WGET is not set 973 | # CONFIG_FEATURE_WGET_LONG_OPTIONS is not set 974 | # CONFIG_FEATURE_WGET_STATUSBAR is not set 975 | # CONFIG_FEATURE_WGET_FTP is not set 976 | # CONFIG_FEATURE_WGET_AUTHENTICATION is not set 977 | # CONFIG_FEATURE_WGET_TIMEOUT is not set 978 | # CONFIG_FEATURE_WGET_HTTPS is not set 979 | # CONFIG_FEATURE_WGET_OPENSSL is not set 980 | # CONFIG_WHOIS is not set 981 | # CONFIG_ZCIP is not set 982 | # CONFIG_UDHCPD is not set 983 | # CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set 984 | # CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set 985 | CONFIG_DHCPD_LEASES_FILE="" 986 | # CONFIG_DUMPLEASES is not set 987 | # CONFIG_DHCPRELAY is not set 988 | # CONFIG_UDHCPC is not set 989 | # CONFIG_FEATURE_UDHCPC_ARPING is not set 990 | # CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set 991 | CONFIG_UDHCPC_DEFAULT_SCRIPT="" 992 | # CONFIG_UDHCPC6 is not set 993 | # CONFIG_FEATURE_UDHCPC6_RFC3646 is not set 994 | # CONFIG_FEATURE_UDHCPC6_RFC4704 is not set 995 | # CONFIG_FEATURE_UDHCPC6_RFC4833 is not set 996 | # CONFIG_FEATURE_UDHCPC6_RFC5970 is not set 997 | CONFIG_UDHCPC_DEFAULT_INTERFACE="" 998 | # CONFIG_FEATURE_UDHCP_PORT is not set 999 | CONFIG_UDHCP_DEBUG=0 1000 | CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 1001 | # CONFIG_FEATURE_UDHCP_RFC3397 is not set 1002 | # CONFIG_FEATURE_UDHCP_8021Q is not set 1003 | CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" 1004 | 1005 | # 1006 | # Print Utilities 1007 | # 1008 | # CONFIG_LPD is not set 1009 | # CONFIG_LPR is not set 1010 | # CONFIG_LPQ is not set 1011 | 1012 | # 1013 | # Mail Utilities 1014 | # 1015 | CONFIG_FEATURE_MIME_CHARSET="" 1016 | # CONFIG_MAKEMIME is not set 1017 | # CONFIG_POPMAILDIR is not set 1018 | # CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set 1019 | # CONFIG_REFORMIME is not set 1020 | # CONFIG_FEATURE_REFORMIME_COMPAT is not set 1021 | # CONFIG_SENDMAIL is not set 1022 | 1023 | # 1024 | # Process Utilities 1025 | # 1026 | # CONFIG_FEATURE_FAST_TOP is not set 1027 | # CONFIG_FEATURE_SHOW_THREADS is not set 1028 | # CONFIG_FREE is not set 1029 | # CONFIG_FUSER is not set 1030 | # CONFIG_IOSTAT is not set 1031 | # CONFIG_KILL is not set 1032 | # CONFIG_KILLALL is not set 1033 | # CONFIG_KILLALL5 is not set 1034 | # CONFIG_LSOF is not set 1035 | # CONFIG_MPSTAT is not set 1036 | # CONFIG_NMETER is not set 1037 | # CONFIG_PGREP is not set 1038 | # CONFIG_PKILL is not set 1039 | # CONFIG_PIDOF is not set 1040 | # CONFIG_FEATURE_PIDOF_SINGLE is not set 1041 | # CONFIG_FEATURE_PIDOF_OMIT is not set 1042 | # CONFIG_PMAP is not set 1043 | # CONFIG_POWERTOP is not set 1044 | # CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set 1045 | # CONFIG_PS is not set 1046 | # CONFIG_FEATURE_PS_WIDE is not set 1047 | # CONFIG_FEATURE_PS_LONG is not set 1048 | # CONFIG_FEATURE_PS_TIME is not set 1049 | # CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set 1050 | # CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set 1051 | # CONFIG_PSTREE is not set 1052 | # CONFIG_PWDX is not set 1053 | # CONFIG_SMEMCAP is not set 1054 | # CONFIG_BB_SYSCTL is not set 1055 | # CONFIG_TOP is not set 1056 | # CONFIG_FEATURE_TOP_INTERACTIVE is not set 1057 | # CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set 1058 | # CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set 1059 | # CONFIG_FEATURE_TOP_SMP_CPU is not set 1060 | # CONFIG_FEATURE_TOP_DECIMALS is not set 1061 | # CONFIG_FEATURE_TOP_SMP_PROCESS is not set 1062 | # CONFIG_FEATURE_TOPMEM is not set 1063 | # CONFIG_UPTIME is not set 1064 | # CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set 1065 | # CONFIG_WATCH is not set 1066 | 1067 | # 1068 | # Runit Utilities 1069 | # 1070 | # CONFIG_CHPST is not set 1071 | # CONFIG_SETUIDGID is not set 1072 | # CONFIG_ENVUIDGID is not set 1073 | # CONFIG_ENVDIR is not set 1074 | # CONFIG_SOFTLIMIT is not set 1075 | # CONFIG_RUNSV is not set 1076 | # CONFIG_RUNSVDIR is not set 1077 | # CONFIG_FEATURE_RUNSVDIR_LOG is not set 1078 | # CONFIG_SV is not set 1079 | CONFIG_SV_DEFAULT_SERVICE_DIR="" 1080 | # CONFIG_SVC is not set 1081 | # CONFIG_SVOK is not set 1082 | # CONFIG_SVLOGD is not set 1083 | # CONFIG_CHCON is not set 1084 | # CONFIG_GETENFORCE is not set 1085 | # CONFIG_GETSEBOOL is not set 1086 | # CONFIG_LOAD_POLICY is not set 1087 | # CONFIG_MATCHPATHCON is not set 1088 | # CONFIG_RUNCON is not set 1089 | # CONFIG_SELINUXENABLED is not set 1090 | # CONFIG_SESTATUS is not set 1091 | # CONFIG_SETENFORCE is not set 1092 | # CONFIG_SETFILES is not set 1093 | # CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set 1094 | # CONFIG_RESTORECON is not set 1095 | # CONFIG_SETSEBOOL is not set 1096 | 1097 | # 1098 | # Shells 1099 | # 1100 | CONFIG_SH_IS_ASH=y 1101 | # CONFIG_SH_IS_HUSH is not set 1102 | # CONFIG_SH_IS_NONE is not set 1103 | # CONFIG_BASH_IS_ASH is not set 1104 | # CONFIG_BASH_IS_HUSH is not set 1105 | CONFIG_BASH_IS_NONE=y 1106 | CONFIG_SHELL_ASH=y 1107 | # CONFIG_ASH is not set 1108 | # CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set 1109 | # CONFIG_ASH_INTERNAL_GLOB is not set 1110 | # CONFIG_ASH_BASH_COMPAT is not set 1111 | # CONFIG_ASH_BASH_SOURCE_CURDIR is not set 1112 | # CONFIG_ASH_BASH_NOT_FOUND_HOOK is not set 1113 | # CONFIG_ASH_JOB_CONTROL is not set 1114 | # CONFIG_ASH_ALIAS is not set 1115 | # CONFIG_ASH_RANDOM_SUPPORT is not set 1116 | # CONFIG_ASH_EXPAND_PRMT is not set 1117 | # CONFIG_ASH_IDLE_TIMEOUT is not set 1118 | # CONFIG_ASH_MAIL is not set 1119 | # CONFIG_ASH_ECHO is not set 1120 | # CONFIG_ASH_PRINTF is not set 1121 | # CONFIG_ASH_TEST is not set 1122 | # CONFIG_ASH_HELP is not set 1123 | # CONFIG_ASH_GETOPTS is not set 1124 | # CONFIG_ASH_CMDCMD is not set 1125 | # CONFIG_CTTYHACK is not set 1126 | # CONFIG_HUSH is not set 1127 | # CONFIG_SHELL_HUSH is not set 1128 | # CONFIG_HUSH_BASH_COMPAT is not set 1129 | # CONFIG_HUSH_BRACE_EXPANSION is not set 1130 | # CONFIG_HUSH_BASH_SOURCE_CURDIR is not set 1131 | # CONFIG_HUSH_LINENO_VAR is not set 1132 | # CONFIG_HUSH_INTERACTIVE is not set 1133 | # CONFIG_HUSH_SAVEHISTORY is not set 1134 | # CONFIG_HUSH_JOB is not set 1135 | # CONFIG_HUSH_TICK is not set 1136 | # CONFIG_HUSH_IF is not set 1137 | # CONFIG_HUSH_LOOPS is not set 1138 | # CONFIG_HUSH_CASE is not set 1139 | # CONFIG_HUSH_FUNCTIONS is not set 1140 | # CONFIG_HUSH_LOCAL is not set 1141 | # CONFIG_HUSH_RANDOM_SUPPORT is not set 1142 | # CONFIG_HUSH_MODE_X is not set 1143 | # CONFIG_HUSH_ECHO is not set 1144 | # CONFIG_HUSH_PRINTF is not set 1145 | # CONFIG_HUSH_TEST is not set 1146 | # CONFIG_HUSH_HELP is not set 1147 | # CONFIG_HUSH_EXPORT is not set 1148 | # CONFIG_HUSH_EXPORT_N is not set 1149 | # CONFIG_HUSH_READONLY is not set 1150 | # CONFIG_HUSH_KILL is not set 1151 | # CONFIG_HUSH_WAIT is not set 1152 | # CONFIG_HUSH_COMMAND is not set 1153 | # CONFIG_HUSH_TRAP is not set 1154 | # CONFIG_HUSH_TYPE is not set 1155 | # CONFIG_HUSH_TIMES is not set 1156 | # CONFIG_HUSH_READ is not set 1157 | # CONFIG_HUSH_SET is not set 1158 | # CONFIG_HUSH_UNSET is not set 1159 | # CONFIG_HUSH_ULIMIT is not set 1160 | # CONFIG_HUSH_UMASK is not set 1161 | # CONFIG_HUSH_GETOPTS is not set 1162 | # CONFIG_HUSH_MEMLEAK is not set 1163 | 1164 | # 1165 | # Options common to all shells 1166 | # 1167 | # CONFIG_FEATURE_SH_MATH is not set 1168 | # CONFIG_FEATURE_SH_MATH_64 is not set 1169 | # CONFIG_FEATURE_SH_MATH_BASE is not set 1170 | # CONFIG_FEATURE_SH_EXTRA_QUIET is not set 1171 | # CONFIG_FEATURE_SH_STANDALONE is not set 1172 | # CONFIG_FEATURE_SH_NOFORK is not set 1173 | # CONFIG_FEATURE_SH_READ_FRAC is not set 1174 | # CONFIG_FEATURE_SH_HISTFILESIZE is not set 1175 | # CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set 1176 | 1177 | # 1178 | # System Logging Utilities 1179 | # 1180 | # CONFIG_KLOGD is not set 1181 | # CONFIG_FEATURE_KLOGD_KLOGCTL is not set 1182 | # CONFIG_LOGGER is not set 1183 | # CONFIG_LOGREAD is not set 1184 | # CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set 1185 | # CONFIG_SYSLOGD is not set 1186 | # CONFIG_FEATURE_ROTATE_LOGFILE is not set 1187 | # CONFIG_FEATURE_REMOTE_LOG is not set 1188 | # CONFIG_FEATURE_SYSLOGD_DUP is not set 1189 | # CONFIG_FEATURE_SYSLOGD_CFG is not set 1190 | # CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set 1191 | CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 1192 | # CONFIG_FEATURE_IPC_SYSLOG is not set 1193 | CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 1194 | # CONFIG_FEATURE_KMSG_SYSLOG is not set 1195 | -------------------------------------------------------------------------------- /docker/lavagna-webapp/Dockerfile: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Build the web app 3 | 4 | FROM rust:1.79 as builder 5 | 6 | RUN rustup target add wasm32-unknown-unknown && \ 7 | cargo install -f wasm-bindgen-cli 8 | 9 | WORKDIR /src 10 | ADD tools tools 11 | ADD assets assets 12 | ADD Cargo.lock Cargo.lock 13 | ADD Cargo.toml Cargo.toml 14 | ADD src src 15 | ADD www www 16 | 17 | RUN ./tools/build-web 18 | 19 | ################################################################################ 20 | # Build a lightweight http server 21 | 22 | FROM alpine:3.13.2 AS server-builder 23 | RUN apk add gcc musl-dev make perl 24 | RUN wget https://busybox.net/downloads/busybox-1.35.0.tar.bz2 \ 25 | && tar xf busybox-1.35.0.tar.bz2 \ 26 | && mv /busybox-1.35.0 /busybox 27 | 28 | WORKDIR /busybox 29 | COPY docker/lavagna-webapp/.config . 30 | RUN make && make install 31 | RUN adduser -D static 32 | 33 | ################################################################################ 34 | # Merge the web app and the http server 35 | 36 | FROM scratch 37 | EXPOSE 3000 38 | COPY --from=server-builder /etc/passwd /etc/passwd 39 | COPY --from=server-builder /busybox/_install/bin/busybox / 40 | USER static 41 | WORKDIR /home/static 42 | COPY docker/lavagna-webapp/httpd.conf . 43 | 44 | # Copy the static website 45 | COPY --from=builder /src/www ./ 46 | 47 | CMD ["/busybox", "httpd", "-f", "-v", "-p", "8000", "-c", "httpd.conf"] 48 | -------------------------------------------------------------------------------- /docker/lavagna-webapp/httpd.conf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alepez/lavagna/447fe9e9e649c3c109da1fc3e8a9e5b64fcfbc36/docker/lavagna-webapp/httpd.conf -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly-2024-07-04" 3 | -------------------------------------------------------------------------------- /src/cli.rs: -------------------------------------------------------------------------------- 1 | use crate::CollabOpt; 2 | use crate::Opt; 3 | use clap::Parser; 4 | 5 | /// The uncluttered blackboard 6 | #[derive(Parser, Debug)] 7 | #[clap(author, version, about, long_about = None)] 8 | struct Args { 9 | #[clap(short = 'u', long)] 10 | collab_url: Option, 11 | #[clap(short = 'i', long)] 12 | collab_id: Option, 13 | #[clap(long)] 14 | show_debug_pane: bool, 15 | #[clap(short = 'v', long)] 16 | verbose: bool, 17 | #[clap(long)] 18 | ui: bool, 19 | #[clap(long)] 20 | width: Option, 21 | #[clap(long)] 22 | height: Option, 23 | } 24 | 25 | /// On native, options are read from command line arguments 26 | pub(crate) fn options_from_args() -> Opt { 27 | let args = Args::parse(); 28 | 29 | // If collab-url is set, then collab-id must be set too. Randomize it if not. 30 | let collab = if let Some(collab_url) = args.collab_url { 31 | let collab_id = args.collab_id.unwrap_or_else(rand::random); 32 | Some(CollabOpt { 33 | url: collab_url, 34 | collab_id, 35 | }) 36 | } else { 37 | None 38 | }; 39 | 40 | Opt { 41 | collab, 42 | show_debug_pane: args.show_debug_pane, 43 | verbose: args.verbose, 44 | ui: args.ui, 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/collab.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::needless_pass_by_value)] 2 | #![allow(clippy::cast_possible_truncation)] 3 | #![allow(clippy::module_name_repetitions)] 4 | 5 | use crate::drawing::{make_chalk, ClearEvent}; 6 | use crate::{Chalk, Stats}; 7 | use bevy::prelude::*; 8 | use bevy::utils::{Duration, HashMap, Instant}; 9 | use bevy_matchbox::prelude::*; 10 | use bevy_prototype_lyon::prelude::{GeometryBuilder, ShapeBundle, Stroke}; 11 | use bevy_prototype_lyon::shapes; 12 | use serde::{Deserialize, Serialize}; 13 | 14 | use crate::local_chalk::LocalChalk; 15 | 16 | pub(crate) struct CollabPlugin { 17 | opt: CollabPluginOpt, 18 | } 19 | 20 | #[derive(Debug, Resource, Clone)] 21 | pub struct CollabPluginOpt { 22 | pub url: String, 23 | pub collab_id: u16, 24 | } 25 | 26 | impl CollabPlugin { 27 | pub fn new(opt: CollabPluginOpt) -> Self { 28 | Self { opt } 29 | } 30 | } 31 | 32 | impl Plugin for CollabPlugin { 33 | fn build(&self, app: &mut bevy::prelude::App) { 34 | let socket = MatchboxSocket::new_reliable(&self.opt.url); 35 | let collab_id = CollabId(self.opt.collab_id); 36 | let room = Room::new(socket, collab_id); 37 | app.insert_resource(room); 38 | 39 | app.add_systems(Update, room_system); 40 | app.add_systems(Update, emit_events); 41 | app.add_systems(Update, receive_events); 42 | app.add_systems(Update, handle_clear_event); 43 | app.add_systems(Update, update_peer_cursor_visibility); 44 | app.add_systems(Update, update_stats); 45 | } 46 | } 47 | 48 | fn emit_events(chalk: ResMut, mut room: ResMut) { 49 | let chalk = chalk.get(); 50 | 51 | if chalk.updated { 52 | room.send(Event::Move(chalk.into())); 53 | } 54 | 55 | if chalk.just_released { 56 | room.send(Event::Release); 57 | } 58 | } 59 | 60 | fn receive_events( 61 | mut commands: Commands, 62 | mut room: ResMut, 63 | mut chalk_q: Query<&mut Chalk>, 64 | mut cursor_q: Query<(&mut Transform, &mut Stroke, &mut PeerCursor), With>, 65 | mut clear_event: EventWriter, 66 | ) { 67 | // This is needed, otherwise it can hangs forever when the connection is not established 68 | if !room.is_ok() { 69 | return; 70 | } 71 | 72 | let my_id = room.collab_id; 73 | 74 | for &AddressedEvent { src, event } in room.receive().iter().filter(|e| e.src != my_id) { 75 | match event { 76 | Event::Move(e) => handle_draw( 77 | &mut commands, 78 | src, 79 | &e, 80 | &mut room, 81 | &mut chalk_q, 82 | &mut cursor_q, 83 | ), 84 | Event::Release => handle_release(src, &room, &mut chalk_q), 85 | Event::Clear => { 86 | clear_event.send(ClearEvent::local_only()); 87 | } 88 | } 89 | } 90 | } 91 | 92 | fn handle_release(src: CollabId, room: &Room, chalk_q: &mut Query<&mut Chalk>) { 93 | if let Some(peer) = room.peers.0.get(&src) { 94 | if let Ok(mut chalk) = chalk_q.get_mut(peer.chalk) { 95 | chalk.pressed = false; 96 | chalk.just_released = true; 97 | } 98 | } 99 | } 100 | 101 | fn handle_draw( 102 | commands: &mut Commands, 103 | src: CollabId, 104 | event: &MoveEvent, 105 | room: &mut Room, 106 | chalk_q: &mut Query<&mut Chalk>, 107 | cursor_q: &mut Query<(&mut Transform, &mut Stroke, &mut PeerCursor), With>, 108 | ) { 109 | let peer: &Peer = room.peers.0.entry(src).or_insert_with(|| { 110 | let peer_cursor = make_peer_cursor(color_from_u32(event.color), src); 111 | let cursor_id = commands.spawn(peer_cursor).id(); 112 | let chalk_id = commands.spawn(make_chalk(event.into())).id(); 113 | 114 | Peer::new(chalk_id, cursor_id) 115 | }); 116 | 117 | if let Ok(mut chalk) = chalk_q.get_mut(peer.chalk) { 118 | *chalk = event.into(); 119 | } 120 | 121 | if let Ok((mut t, mut stroke, mut peer_cursor)) = cursor_q.get_mut(peer.cursor) { 122 | t.translation.x = event.x.into(); 123 | t.translation.y = event.y.into(); 124 | stroke.color = color_from_u32(event.color).into(); 125 | peer_cursor.touch(); 126 | } 127 | } 128 | 129 | fn update_peer_cursor_visibility( 130 | mut cursor_q: Query<(&mut Visibility, &PeerCursor), With>, 131 | ) { 132 | for (mut visibility, peer_cursor) in &mut cursor_q { 133 | *visibility = if peer_cursor.is_active() { 134 | Visibility::Visible 135 | } else { 136 | Visibility::Hidden 137 | }; 138 | } 139 | } 140 | 141 | impl From<&Chalk> for MoveEvent { 142 | fn from(chalk: &Chalk) -> Self { 143 | Self { 144 | color: color_to_u32(chalk.color), 145 | x: chalk.x as i16, 146 | y: chalk.y as i16, 147 | line_width: chalk.line_width as u8, 148 | pressed: chalk.pressed, 149 | } 150 | } 151 | } 152 | 153 | impl From<&MoveEvent> for Chalk { 154 | fn from(event: &MoveEvent) -> Self { 155 | Self { 156 | pressed: event.pressed, 157 | updated: true, 158 | x: event.x.into(), 159 | y: event.y.into(), 160 | color: color_from_u32(event.color), 161 | line_width: event.line_width.into(), 162 | just_released: false, 163 | } 164 | } 165 | } 166 | 167 | #[allow(clippy::many_single_char_names)] 168 | fn color_from_u32(n: u32) -> Srgba { 169 | let r = ((n) & 0xFF) as u8; 170 | let g = ((n >> 8) & 0xFF) as u8; 171 | let b = ((n >> 16) & 0xFF) as u8; 172 | let a = ((n >> 24) & 0xFF) as u8; 173 | Srgba::rgba_u8(r, g, b, a) 174 | } 175 | 176 | #[allow(clippy::cast_sign_loss)] 177 | fn color_to_u32(color: Srgba) -> u32 { 178 | let r = (color.red * 255.0) as u32; 179 | let g = (color.green * 255.0) as u32; 180 | let b = (color.blue * 255.0) as u32; 181 | let a = (color.alpha * 255.0) as u32; 182 | (a << 24) | (b << 16) | (g << 8) | r 183 | } 184 | 185 | #[derive(Default)] 186 | struct Peers(HashMap); 187 | 188 | struct Peer { 189 | chalk: Entity, 190 | cursor: Entity, 191 | } 192 | 193 | impl Peer { 194 | fn new(chalk: Entity, cursor: Entity) -> Self { 195 | Self { chalk, cursor } 196 | } 197 | } 198 | 199 | #[derive(Resource)] 200 | struct Room { 201 | socket: MatchboxSocket, 202 | collab_id: CollabId, 203 | peers: Peers, 204 | } 205 | 206 | impl Room { 207 | fn new(socket: MatchboxSocket, collab_id: CollabId) -> Self { 208 | Self { 209 | socket, 210 | collab_id, 211 | peers: Peers::default(), 212 | } 213 | } 214 | 215 | fn send(&mut self, event: Event) { 216 | let event = AddressedEvent { 217 | src: self.collab_id, 218 | event, 219 | }; 220 | let peers: Vec<_> = self.socket.connected_peers().collect(); 221 | let mut payload = Vec::new(); 222 | ciborium::ser::into_writer(&event, &mut payload).unwrap(); 223 | for peer in peers { 224 | self.socket.send(payload.clone().into(), peer); 225 | } 226 | } 227 | 228 | fn receive(&mut self) -> Vec { 229 | self.socket 230 | .receive() 231 | .iter() 232 | .map(|(_, payload)| payload) 233 | .filter_map(|payload| ciborium::de::from_reader(&payload[..]).ok()) 234 | .collect() 235 | } 236 | 237 | fn is_ok(&self) -> bool { 238 | self.socket.connected_peers().count() > 0 239 | } 240 | } 241 | 242 | #[derive(Debug, Serialize, Deserialize, Copy, Clone)] 243 | enum Event { 244 | Move(MoveEvent), 245 | Release, 246 | Clear, 247 | } 248 | 249 | #[derive(Debug, Serialize, Deserialize, Copy, Clone)] 250 | struct MoveEvent { 251 | color: u32, 252 | line_width: u8, 253 | x: i16, 254 | y: i16, 255 | pressed: bool, 256 | } 257 | 258 | #[derive(Debug, Serialize, Deserialize, Copy, Clone)] 259 | struct AddressedEvent { 260 | src: CollabId, 261 | event: Event, 262 | } 263 | 264 | #[derive(Debug, Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)] 265 | struct CollabId(u16); 266 | 267 | impl From for CollabId { 268 | fn from(value: u16) -> Self { 269 | Self(value) 270 | } 271 | } 272 | 273 | // regularly call update_peers to update the list of connected peers 274 | fn room_system(mut room: ResMut) { 275 | let Ok(peers) = room.socket.try_update_peers() else { 276 | log::error!("failed to update peers"); 277 | return; 278 | }; 279 | for (peer, new_state) in peers { 280 | match new_state { 281 | PeerState::Connected => info!("peer {peer:?} connected"), 282 | PeerState::Disconnected => info!("peer {peer:?} disconnected"), 283 | } 284 | } 285 | } 286 | 287 | fn handle_clear_event(mut events: EventReader, mut room: ResMut) { 288 | let clear = events.read().filter(|e| e.must_be_forwarded()).count() > 0; 289 | 290 | if clear { 291 | room.send(Event::Clear); 292 | } 293 | } 294 | 295 | fn update_stats(room: Res, mut stats: ResMut) { 296 | stats.collab.active = true; 297 | stats.collab.peers = room.socket.connected_peers().count(); 298 | } 299 | 300 | #[derive(Component)] 301 | struct PeerCursor { 302 | #[allow(dead_code)] 303 | id: CollabId, 304 | last_seen: Instant, 305 | } 306 | 307 | impl PeerCursor { 308 | fn new(id: CollabId) -> Self { 309 | log::info!("new peer cursor {:?}", id); 310 | 311 | Self { 312 | id, 313 | last_seen: Instant::now(), 314 | } 315 | } 316 | 317 | fn is_active(&self) -> bool { 318 | self.last_seen.elapsed() < Duration::from_secs(1) 319 | } 320 | 321 | fn touch(&mut self) { 322 | self.last_seen = Instant::now(); 323 | } 324 | } 325 | 326 | fn make_peer_cursor(color: Srgba, id: CollabId) -> (ShapeBundle, Stroke, PeerCursor) { 327 | let shape = shapes::Circle { 328 | radius: 1.0, 329 | center: Vec2::new(0.0, 0.0), 330 | }; 331 | 332 | // z-index at maximum before clipping pane 333 | let transform = Transform { 334 | translation: Vec3::new(0., 0., 999.0), 335 | ..default() 336 | }; 337 | 338 | let shape = ShapeBundle { 339 | path: GeometryBuilder::build_as(&shape), 340 | spatial: transform.into(), 341 | ..default() 342 | }; 343 | 344 | let stroke = Stroke::new(color, 10.0); 345 | let peer_cursor = PeerCursor::new(id); 346 | 347 | (shape, stroke, peer_cursor) 348 | } 349 | -------------------------------------------------------------------------------- /src/debug.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::needless_pass_by_value)] 2 | 3 | use bevy::prelude::*; 4 | 5 | use bevy::diagnostic::{Diagnostic, DiagnosticsStore, FrameTimeDiagnosticsPlugin}; 6 | 7 | use crate::local_chalk::LocalChalk; 8 | use crate::Stats; 9 | 10 | pub(crate) struct DebugPlugin; 11 | 12 | impl Plugin for DebugPlugin { 13 | fn build(&self, app: &mut App) { 14 | app.add_systems(Startup, startup) 15 | .add_systems(Update, update); 16 | } 17 | } 18 | 19 | #[derive(Component)] 20 | struct DebugText; 21 | 22 | fn startup(mut commands: Commands, asset_server: Res) { 23 | commands.spawn(( 24 | TextBundle::from_section( 25 | "--", 26 | TextStyle { 27 | font: asset_server.load("fonts/FiraMono-Medium.ttf"), 28 | font_size: 20.0, 29 | color: Color::WHITE, 30 | }, 31 | ) 32 | .with_style(Style { 33 | position_type: PositionType::Absolute, 34 | top: Val::Px(5.0), 35 | left: Val::Px(15.0), 36 | ..default() 37 | }), 38 | DebugText, 39 | )); 40 | } 41 | 42 | fn update( 43 | diagnostics: Res, 44 | mut text: Query<&mut Text, With>, 45 | chalk: Res, 46 | stats: Res, 47 | ) { 48 | let mut text = text.single_mut(); 49 | let chalk = chalk.get(); 50 | 51 | let fps = diagnostics 52 | .get(&FrameTimeDiagnosticsPlugin::FPS) 53 | .and_then(Diagnostic::smoothed) 54 | .map_or("-- fps".to_owned(), |x| format!("{x:.1} fps")); 55 | 56 | let frame_time = diagnostics 57 | .get(&FrameTimeDiagnosticsPlugin::FRAME_TIME) 58 | .and_then(Diagnostic::smoothed) 59 | .map_or("-- ms/frame".to_owned(), |x| format!("{x:.1} ms/frame")); 60 | 61 | let chalk = { 62 | let x = chalk.x; 63 | let y = chalk.y; 64 | let pressed = chalk.pressed; 65 | format!("{x:+05}:{y:+05} {pressed}") 66 | }; 67 | 68 | let collab = { format!("{:?}", stats.collab) }; 69 | 70 | let text_value = &mut text.sections[0].value; 71 | 72 | *text_value = format!( 73 | r#"{fps} 74 | {frame_time} 75 | {chalk} 76 | {collab} 77 | "# 78 | ); 79 | } 80 | -------------------------------------------------------------------------------- /src/drawing.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::needless_pass_by_value)] 2 | #![allow(clippy::cast_precision_loss)] 3 | 4 | use crate::Chalk; 5 | use bevy::prelude::*; 6 | 7 | use bevy_prototype_lyon::prelude::*; 8 | 9 | const POINTS_CHUNK_THRESHOLD: usize = 100; 10 | 11 | pub(crate) struct DrawingPlugin; 12 | 13 | impl Plugin for DrawingPlugin { 14 | fn build(&self, app: &mut bevy::prelude::App) { 15 | app.add_plugins(ShapePlugin) 16 | .add_event::() 17 | .add_systems(Update, handle_clear_event) 18 | .add_systems(Update, update); 19 | } 20 | } 21 | 22 | fn update( 23 | mut commands: Commands, 24 | mut chalk_q: Query<(&mut Chalk, &mut Path, &mut Stroke, &mut Polyline), With>, 25 | time: Res