From f652785acb73cfcd1f07785c081ed8706a2d12ad Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Tue, 18 Aug 2026 01:41:40 +0200 Subject: [PATCH] =?UTF-8?q?v1.0.0=20=E2=80=94=20Hexagonal=20architecture?= =?UTF-8?q?=20rewrite?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Restructure the monolithic 252-line main.rs into a 10-crate workspace with clean hexagonal architecture, swappable adapters, and a production- ready deployment pipeline. Backend architecture: - domain: Canvas, Color/Position/PixelUpdate value objects, port traits (CanvasStore, CanvasPersistence, EventBroadcaster), BroadcastEvent - application: use cases (place_pixel, get_state, save/restore snapshot, connect/disconnect), AppState with Arc snapshot cache - config: AppConfig structs + ConfigSource trait - api-types: shared DTOs, event name constants - adapters: config-env, canvas-file, http-axum (rust-embed), socketio, websocket — all behind port traits, swappable via feature flags - server: composition root with graceful shutdown (SIGTERM/SIGINT) Frontend: - Transport abstraction: Socket.IO and native WebSocket via VITE_TRANSPORT - Canvas zoom/pan with mouse wheel, pinch-to-zoom, and +/- buttons - ImageData rendering (~50x faster than fillRect loop) - Touch support, responsive CSS scaling, mobile-friendly layout - OG/Twitter Card meta tags for rich link previews Production: - Docker: musl static build on scratch — 2.73MB image - CI workflows for Gitea and GitHub Actions (fmt, clippy, test, Docker push) - deploy.sh for private registry - 39 unit tests across domain and application - Zero unwraps, zero unsafe, graceful error handling with tracing - Periodic canvas snapshots with rotation, restored on startup - All config via environment variables with typed defaults --- .dockerignore | 9 + .env.example | 12 +- .gitea/workflows/ci.yml | 40 + .github/workflows/ci.yml | 74 + .gitignore | 4 +- Cargo.lock | 1307 +++++++++------ Cargo.toml | 72 +- Dockerfile | 29 +- LICENSE | 21 + Makefile | 33 + README.md | 122 +- architecture.mmd | 83 + crates/adapters/canvas-file/Cargo.toml | 9 + crates/adapters/canvas-file/src/lib.rs | 158 ++ crates/adapters/config-env/Cargo.toml | 7 + crates/adapters/config-env/src/lib.rs | 70 + crates/adapters/http-axum/Cargo.toml | 12 + crates/adapters/http-axum/src/lib.rs | 3 + crates/adapters/http-axum/src/routes.rs | 80 + crates/adapters/socketio/Cargo.toml | 13 + crates/adapters/socketio/src/handlers.rs | 109 ++ crates/adapters/socketio/src/lib.rs | 12 + crates/adapters/websocket/Cargo.toml | 14 + crates/adapters/websocket/src/handler.rs | 163 ++ crates/adapters/websocket/src/lib.rs | 24 + crates/adapters/websocket/src/messages.rs | 30 + crates/api-types/Cargo.toml | 8 + crates/api-types/src/lib.rs | 27 + crates/application/Cargo.toml | 10 + crates/application/src/canvas/get_state.rs | 9 + crates/application/src/canvas/mod.rs | 4 + crates/application/src/canvas/place_pixel.rs | 29 + .../src/canvas/restore_snapshot.rs | 14 + .../application/src/canvas/save_snapshot.rs | 10 + crates/application/src/errors.rs | 7 + crates/application/src/lib.rs | 8 + crates/application/src/soldiers/connect.rs | 11 + crates/application/src/soldiers/disconnect.rs | 12 + crates/application/src/soldiers/mod.rs | 2 + crates/application/src/state.rs | 199 +++ crates/application/tests/common/mod.rs | 109 ++ crates/application/tests/place_pixel.rs | 91 + crates/application/tests/snapshots.rs | 75 + crates/application/tests/soldiers.rs | 96 ++ crates/config/Cargo.toml | 7 + crates/config/src/lib.rs | 61 + crates/domain/Cargo.toml | 7 + crates/domain/src/canvas.rs | 57 + crates/domain/src/errors.rs | 21 + crates/domain/src/events.rs | 7 + crates/domain/src/lib.rs | 13 + crates/domain/src/ports.rs | 39 + crates/domain/src/value_objects.rs | 76 + crates/domain/tests/canvas.rs | 125 ++ crates/domain/tests/value_objects.rs | 69 + crates/server/Cargo.toml | 26 + crates/server/src/main.rs | 133 ++ deploy.sh | 21 + painter-js/bun.lock | 315 ++++ painter-js/index.html | 146 +- painter-js/package-lock.json | 917 ----------- painter-js/package.json | 8 +- painter-js/pnpm-lock.yaml | 1466 ----------------- painter-js/public/og-image.png | Bin 0 -> 99977 bytes painter-js/src/Astronaut.glb | Bin 733432 -> 0 bytes painter-js/src/canvas.js | 267 --- painter-js/src/challenge.js | 139 -- painter-js/src/constants.js | 12 - painter-js/src/counter.js | 20 - painter-js/src/domain/canvas-state.js | 11 + painter-js/src/{utils.js => domain/color.js} | 11 +- painter-js/src/domain/constants.js | 4 + painter-js/src/domain/cooldown.js | 9 + painter-js/src/domain/coords.js | 19 + painter-js/src/infrastructure/api.js | 5 + .../src/infrastructure/socket-client.js | 72 + painter-js/src/main.js | 120 +- painter-js/src/socket.js | 21 - painter-js/src/style.css | 27 +- painter-js/src/ui/canvas-renderer.js | 39 + painter-js/src/ui/canvas-viewport.js | 78 + painter-js/src/ui/color-palette.js | 53 + painter-js/src/ui/cooldown-display.js | 16 + painter-js/src/ui/pixel-placer.js | 57 + src/main.rs | 251 --- 85 files changed, 4240 insertions(+), 3736 deletions(-) create mode 100644 .dockerignore create mode 100644 .gitea/workflows/ci.yml create mode 100644 .github/workflows/ci.yml create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 architecture.mmd create mode 100644 crates/adapters/canvas-file/Cargo.toml create mode 100644 crates/adapters/canvas-file/src/lib.rs create mode 100644 crates/adapters/config-env/Cargo.toml create mode 100644 crates/adapters/config-env/src/lib.rs create mode 100644 crates/adapters/http-axum/Cargo.toml create mode 100644 crates/adapters/http-axum/src/lib.rs create mode 100644 crates/adapters/http-axum/src/routes.rs create mode 100644 crates/adapters/socketio/Cargo.toml create mode 100644 crates/adapters/socketio/src/handlers.rs create mode 100644 crates/adapters/socketio/src/lib.rs create mode 100644 crates/adapters/websocket/Cargo.toml create mode 100644 crates/adapters/websocket/src/handler.rs create mode 100644 crates/adapters/websocket/src/lib.rs create mode 100644 crates/adapters/websocket/src/messages.rs create mode 100644 crates/api-types/Cargo.toml create mode 100644 crates/api-types/src/lib.rs create mode 100644 crates/application/Cargo.toml create mode 100644 crates/application/src/canvas/get_state.rs create mode 100644 crates/application/src/canvas/mod.rs create mode 100644 crates/application/src/canvas/place_pixel.rs create mode 100644 crates/application/src/canvas/restore_snapshot.rs create mode 100644 crates/application/src/canvas/save_snapshot.rs create mode 100644 crates/application/src/errors.rs create mode 100644 crates/application/src/lib.rs create mode 100644 crates/application/src/soldiers/connect.rs create mode 100644 crates/application/src/soldiers/disconnect.rs create mode 100644 crates/application/src/soldiers/mod.rs create mode 100644 crates/application/src/state.rs create mode 100644 crates/application/tests/common/mod.rs create mode 100644 crates/application/tests/place_pixel.rs create mode 100644 crates/application/tests/snapshots.rs create mode 100644 crates/application/tests/soldiers.rs create mode 100644 crates/config/Cargo.toml create mode 100644 crates/config/src/lib.rs create mode 100644 crates/domain/Cargo.toml create mode 100644 crates/domain/src/canvas.rs create mode 100644 crates/domain/src/errors.rs create mode 100644 crates/domain/src/events.rs create mode 100644 crates/domain/src/lib.rs create mode 100644 crates/domain/src/ports.rs create mode 100644 crates/domain/src/value_objects.rs create mode 100644 crates/domain/tests/canvas.rs create mode 100644 crates/domain/tests/value_objects.rs create mode 100644 crates/server/Cargo.toml create mode 100644 crates/server/src/main.rs create mode 100755 deploy.sh create mode 100644 painter-js/bun.lock delete mode 100644 painter-js/package-lock.json delete mode 100644 painter-js/pnpm-lock.yaml create mode 100644 painter-js/public/og-image.png delete mode 100644 painter-js/src/Astronaut.glb delete mode 100644 painter-js/src/canvas.js delete mode 100644 painter-js/src/challenge.js delete mode 100644 painter-js/src/constants.js delete mode 100644 painter-js/src/counter.js create mode 100644 painter-js/src/domain/canvas-state.js rename painter-js/src/{utils.js => domain/color.js} (66%) create mode 100644 painter-js/src/domain/constants.js create mode 100644 painter-js/src/domain/cooldown.js create mode 100644 painter-js/src/domain/coords.js create mode 100644 painter-js/src/infrastructure/api.js create mode 100644 painter-js/src/infrastructure/socket-client.js delete mode 100644 painter-js/src/socket.js create mode 100644 painter-js/src/ui/canvas-renderer.js create mode 100644 painter-js/src/ui/canvas-viewport.js create mode 100644 painter-js/src/ui/color-palette.js create mode 100644 painter-js/src/ui/cooldown-display.js create mode 100644 painter-js/src/ui/pixel-placer.js delete mode 100644 src/main.rs diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..864b864 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,9 @@ +target/ +painter-js/node_modules/ +painter-js/dist/ +painter-js/.env +snapshots/ +.git/ +.claude/ +.env +*.DS_Store diff --git a/.env.example b/.env.example index ef918a9..7510bde 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,13 @@ ADDRESS=0.0.0.0 PORT=3000 -ENABLE_CORS=true \ No newline at end of file +ENABLE_CORS=true +CANVAS_WIDTH=500 +CANVAS_HEIGHT=500 +COOLDOWN_SECS=10 +RATE_LIMIT_BURST=10 +RATE_LIMIT_PER_SECOND=10 +BROADCAST_CAPACITY=1024 +SNAPSHOT_ENABLED=true +SNAPSHOT_INTERVAL_SECS=300 +SNAPSHOT_MAX=5 +SNAPSHOT_DIR=snapshots/ diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml new file mode 100644 index 0000000..c651be6 --- /dev/null +++ b/.gitea/workflows/ci.yml @@ -0,0 +1,40 @@ +name: CI + +on: + push: + branches: ["*"] + pull_request: + +jobs: + ci: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + + - uses: oven-sh/setup-bun@v2 + + - name: Build frontend + run: cd painter-js && bun install --frozen-lockfile && bun run build + + - name: Check formatting + run: | + cargo fmt --all -- --check + cd painter-js && bun run fmt:check + + - name: Clippy + run: cargo clippy --workspace -- -D warnings + + - name: Tests + run: cargo test --workspace diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..127aca6 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,74 @@ +name: CI + +on: + push: + branches: ["*"] + tags: ["v*"] + pull_request: + +jobs: + ci: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + + - uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + + - uses: oven-sh/setup-bun@v2 + + - name: Build frontend + run: cd painter-js && bun install --frozen-lockfile && bun run build + + - name: Check formatting + run: | + cargo fmt --all -- --check + cd painter-js && bun run fmt:check + + - name: Clippy + run: cargo clippy --workspace -- -D warnings + + - name: Tests + run: cargo test --workspace + + docker: + needs: ci + runs-on: ubuntu-latest + if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v')) + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v4 + + - uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - uses: docker/metadata-action@v5 + id: meta + with: + images: ghcr.io/${{ github.repository }} + tags: | + type=raw,value=latest,enable={{is_default_branch}} + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=sha + + - uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.gitignore b/.gitignore index 0b745e2..bf2d1b4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /target -.env \ No newline at end of file +.env +/snapshots +*.DS_Store \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 9f43e9f..2970fd8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,35 +1,38 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] -name = "addr2line" -version = "0.21.0" +name = "allocator-api2" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "api-types" +version = "1.0.0" dependencies = [ - "gimli", + "domain", + "serde", ] [[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +name = "application" +version = "1.0.0" dependencies = [ - "libc", + "domain", + "thiserror 2.0.20", + "tokio", + "tracing", +] + +[[package]] +name = "arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" +dependencies = [ + "derive_arbitrary", ] [[package]] @@ -40,9 +43,15 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.63", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.3.0" @@ -51,13 +60,14 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "axum" -version = "0.7.5" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" +checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" dependencies = [ - "async-trait", "axum-core", + "base64", "bytes", + "form_urlencoded", "futures-util", "http", "http-body", @@ -65,18 +75,19 @@ dependencies = [ "hyper", "hyper-util", "itoa", - "matchit", + "matchit 0.8.4", "memchr", "mime", "percent-encoding", "pin-project-lite", - "rustversion", - "serde", + "serde_core", "serde_json", "serde_path_to_error", "serde_urlencoded", - "sync_wrapper 1.0.1", + "sha1", + "sync_wrapper", "tokio", + "tokio-tungstenite", "tower", "tower-layer", "tower-service", @@ -85,55 +96,29 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.4.3" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" dependencies = [ - "async-trait", "bytes", - "futures-util", + "futures-core", "http", "http-body", "http-body-util", "mime", "pin-project-lite", - "rustversion", - "sync_wrapper 0.1.2", + "sync_wrapper", "tower-layer", "tower-service", "tracing", ] -[[package]] -name = "backtrace" -version = "0.3.71" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - [[package]] name = "bitflags" version = "2.5.0" @@ -149,32 +134,38 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +dependencies = [ + "hybrid-array", +] + [[package]] name = "bumpalo" version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "bytes" -version = "1.6.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" dependencies = [ "serde", ] [[package]] -name = "cc" -version = "1.0.97" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" +name = "canvas-file" +version = "1.0.0" +dependencies = [ + "config", + "domain", + "tracing", +] [[package]] name = "cfg-if" @@ -183,24 +174,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "chrono" -version = "0.4.38" +name = "chacha20" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "wasm-bindgen", - "windows-targets 0.52.5", + "cfg-if", + "cpufeatures 0.3.0", + "rand_core 0.10.1", ] [[package]] -name = "core-foundation-sys" -version = "0.8.6" +name = "config" +version = "1.0.0" +dependencies = [ + "thiserror 2.0.20", +] + +[[package]] +name = "config-env" +version = "1.0.0" +dependencies = [ + "config", +] + +[[package]] +name = "const-oid" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" [[package]] name = "cpufeatures" @@ -211,6 +213,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "crossbeam-utils" version = "0.8.19" @@ -228,13 +239,23 @@ dependencies = [ ] [[package]] -name = "dashmap" -version = "5.5.3" +name = "crypto-common" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" dependencies = [ "cfg-if", - "hashbrown", + "crossbeam-utils", + "hashbrown 0.14.5", "lock_api", "once_cell", "parking_lot_core", @@ -246,14 +267,64 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" +[[package]] +name = "derive_arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.63", +] + [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", - "crypto-common", + "block-buffer 0.10.4", + "crypto-common 0.1.6", +] + +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.1", + "const-oid", + "crypto-common 0.2.2", +] + +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys", +] + +[[package]] +name = "domain" +version = "1.0.0" +dependencies = [ + "thiserror 2.0.20", ] [[package]] @@ -264,12 +335,12 @@ checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" [[package]] name = "engineioxide" -version = "0.13.1" +version = "0.17.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76e79b0c318bbff227b003843c56d5fc50b43276441d162124166f4cbacc80" +checksum = "1c48884059941b2b6255eabe1e9dca48e1aa01242299a7ef60844ded113b1d50" dependencies = [ - "base64", "bytes", + "engineioxide-core", "futures-core", "futures-util", "http", @@ -278,22 +349,54 @@ dependencies = [ "hyper", "hyper-util", "pin-project-lite", - "rand", "serde", "serde_json", "smallvec", - "thiserror", + "thiserror 2.0.20", "tokio", "tokio-tungstenite", - "tower", + "tokio-util", + "tower-layer", + "tower-service", ] +[[package]] +name = "engineioxide-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06c5f98b2d2338ec0713bc222c753bfd18746bd76cbb115afa18aa07c6096553" +dependencies = [ + "base64", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "pin-project-lite", + "rand 0.10.2", + "serde", + "serde_json", + "smallvec", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -310,14 +413,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8835f84f38484cc86f110a805655697908257fb9a7af005234060891557198e9" dependencies = [ "nonempty", - "thiserror", + "thiserror 1.0.60", ] [[package]] name = "futures" -version = "0.3.30" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" dependencies = [ "futures-channel", "futures-core", @@ -330,9 +433,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", "futures-sink", @@ -340,15 +443,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" dependencies = [ "futures-core", "futures-task", @@ -357,32 +460,32 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-timer" @@ -392,9 +495,9 @@ checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-channel", "futures-core", @@ -404,7 +507,6 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] @@ -420,9 +522,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "libc", @@ -430,29 +532,71 @@ dependencies = [ ] [[package]] -name = "gimli" -version = "0.28.1" +name = "getrandom" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi 5.3.0", + "wasip2", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "rand_core 0.10.1", +] [[package]] name = "governor" -version = "0.6.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b" +checksum = "9efcab3c1958580ff1f25a2a41be1668f7603d849bb63af523b208a3cc1223b8" dependencies = [ "cfg-if", "dashmap", - "futures", + "futures-sink", "futures-timer", - "no-std-compat", + "futures-util", + "getrandom 0.3.4", + "hashbrown 0.16.1", "nonzero_ext", "parking_lot", "portable-atomic", "quanta", - "rand", + "rand 0.9.5", "smallvec", "spinning_top", + "web-time", +] + +[[package]] +name = "h2" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9f37a958b41b3b19ee2707c06439c0e9e547e847223eb791ecb0cb821c65e27" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", ] [[package]] @@ -462,22 +606,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] -name = "hermit-abi" -version = "0.3.9" +name = "hashbrown" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "http" -version = "1.1.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" dependencies = [ "bytes", - "fnv", "itoa", ] +[[package]] +name = "http-axum" +version = "1.0.0" +dependencies = [ + "axum", + "config", + "rust-embed", + "tokio", + "tower-http", + "tower_governor", +] + [[package]] name = "http-body" version = "1.0.0" @@ -501,17 +667,11 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "http-range-header" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ce4ef31cda248bbdb6e6820603b82dfcd9e833db65a43e997a0ccec777d11fe" - [[package]] name = "httparse" -version = "1.8.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "httpdate" @@ -520,14 +680,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] -name = "hyper" -version = "1.3.1" +name = "hybrid-array" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" +checksum = "3944cf8cf766b40e2a1a333ee5e9b563f854d5fa49d6a8ca2764e97c6eddb214" dependencies = [ + "typenum", +] + +[[package]] +name = "hyper" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d22053281f852e11534f5198498373cbb59295120a20771d90f7ed1897490a72" +dependencies = [ + "atomic-waker", "bytes", "futures-channel", - "futures-util", + "futures-core", + "h2", "http", "http-body", "httparse", @@ -536,55 +707,50 @@ dependencies = [ "pin-project-lite", "smallvec", "tokio", + "want", +] + +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", ] [[package]] name = "hyper-util" -version = "0.1.3" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ "bytes", + "futures-channel", "futures-util", "http", "http-body", "hyper", + "libc", "pin-project-lite", "socket2", "tokio", + "tower-service", + "tracing", ] [[package]] -name = "iana-time-zone" -version = "0.1.60" +name = "indexmap" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", + "equivalent", + "hashbrown 0.17.1", ] [[package]] @@ -595,10 +761,12 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" dependencies = [ + "cfg-if", + "futures-util", "wasm-bindgen", ] @@ -610,9 +778,18 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.154" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" + +[[package]] +name = "libredox" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3" +dependencies = [ + "libc", +] [[package]] name = "lock_api" @@ -632,9 +809,15 @@ checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "matchit" -version = "0.7.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + +[[package]] +name = "matchit" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8863b587001c1b9a8a4e36008cebc6b3612cb1226fe2de94858e06092687b608" [[package]] name = "memchr" @@ -642,16 +825,6 @@ version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" -[[package]] -name = "memory-stats" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34f79cf9964c5c9545493acda1263f1912f8d2c56c8a2ffee2606cb960acaacc" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "mime" version = "0.3.17" @@ -660,40 +833,25 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" -version = "2.0.4" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" dependencies = [ "mime", "unicase", ] -[[package]] -name = "miniz_oxide" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" -dependencies = [ - "adler", -] - [[package]] name = "mio" -version = "0.8.11" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" dependencies = [ "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys", ] -[[package]] -name = "no-std-compat" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" - [[package]] name = "nonempty" version = "0.7.0" @@ -716,66 +874,24 @@ dependencies = [ "winapi", ] -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "overload" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" -[[package]] -name = "painter" -version = "0.1.0" -dependencies = [ - "axum", - "bincode", - "bytes", - "chrono", - "dotenv", - "memory-stats", - "serde", - "serde_json", - "socketioxide", - "tokio", - "tower-http", - "tower_governor", - "tracing", - "tracing-subscriber", -] - [[package]] name = "parking_lot" version = "0.12.2" @@ -796,7 +912,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.5", + "windows-targets", ] [[package]] @@ -822,7 +938,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.63", ] [[package]] @@ -831,12 +947,6 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - [[package]] name = "portable-atomic" version = "1.6.0" @@ -851,9 +961,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.82" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] @@ -883,35 +993,63 @@ dependencies = [ ] [[package]] -name = "rand" -version = "0.8.5" +name = "r-efi" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "rand" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" dependencies = [ - "libc", "rand_chacha", - "rand_core", + "rand_core 0.9.5", +] + +[[package]] +name = "rand" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" +dependencies = [ + "chacha20", + "getrandom 0.4.3", + "rand_core 0.10.1", ] [[package]] name = "rand_chacha" -version = "0.3.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.9.5", ] [[package]] name = "rand_core" -version = "0.6.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ - "getrandom", + "getrandom 0.3.4", ] +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + [[package]] name = "raw-cpuid" version = "11.0.2" @@ -931,10 +1069,52 @@ dependencies = [ ] [[package]] -name = "rustc-demangle" -version = "0.1.24" +name = "redox_users" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +dependencies = [ + "getrandom 0.2.17", + "libredox", + "thiserror 2.0.20", +] + +[[package]] +name = "rust-embed" +version = "8.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9e7760e252aaba7b09f4be00e36476cf585bdb68a53552ac954cdf504ab4bc9" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "8.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bcfc4d6f53af43755f7a723e4b6b8794fcce052a178dd8c6c1dadc5f5343097" +dependencies = [ + "mime_guess", + "proc-macro2", + "quote", + "rust-embed-utils", + "shellexpand", + "syn 2.0.63", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "8.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ffa149f6aa81b58a5b3011d01a857c4ed12c7a732d2c51947a4c7c692185f0" +dependencies = [ + "mime_guess", + "sha2", + "walkdir", +] [[package]] name = "rustversion" @@ -948,6 +1128,15 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -956,22 +1145,32 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.201" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.201" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", ] [[package]] @@ -1007,6 +1206,26 @@ dependencies = [ "serde", ] +[[package]] +name = "server" +version = "1.0.0" +dependencies = [ + "application", + "axum", + "canvas-file", + "config", + "config-env", + "domain", + "dotenv", + "http-axum", + "socketio", + "socketioxide", + "tokio", + "tracing", + "tracing-subscriber", + "websocket", +] + [[package]] name = "sha1" version = "0.10.6" @@ -1014,8 +1233,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures", - "digest", + "cpufeatures 0.2.12", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.3", ] [[package]] @@ -1027,6 +1257,15 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shellexpand" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32824fab5e16e6c4d86dc1ba84489390419a39f97699852b66480bb87d297ed8" +dependencies = [ + "dirs", +] + [[package]] name = "signal-hook-registry" version = "1.4.2" @@ -1047,25 +1286,41 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.2" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" +dependencies = [ + "serde", +] [[package]] name = "socket2" -version = "0.5.7" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys", +] + +[[package]] +name = "socketio" +version = "1.0.0" +dependencies = [ + "api-types", + "application", + "domain", + "serde_json", + "socketioxide", + "tokio", + "tracing", ] [[package]] name = "socketioxide" -version = "0.13.1" +version = "0.18.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "178953184593e92c3f58d0d3eda74865c520b6fc05f80dc6c99bb235e39f400a" +checksum = "8b4ccb119c03dd29d44ad7de4dd7049ec0812d1aa05bdca5cc6f1cb5210d4f96" dependencies = [ "bytes", "engineioxide", @@ -1074,13 +1329,43 @@ dependencies = [ "http", "http-body", "hyper", - "itoa", + "matchit 0.9.2", "pin-project-lite", "serde", - "serde_json", - "thiserror", + "socketioxide-core", + "socketioxide-parser-common", + "thiserror 2.0.20", "tokio", - "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "socketioxide-core" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e520fedd1addc257506026a31268d9a6eeee79b158c7fc8b270c4c7a1cfc4f" +dependencies = [ + "arbitrary", + "bytes", + "engineioxide-core", + "futures-core", + "serde", + "smallvec", + "thiserror 2.0.20", +] + +[[package]] +name = "socketioxide-parser-common" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ba9a856b0de7f665fe0d66fb7d60c74ad2e1810552c60a31f72e9aa6372cc02" +dependencies = [ + "bytes", + "itoa", + "serde", + "serde_json", + "socketioxide-core", ] [[package]] @@ -1104,16 +1389,21 @@ dependencies = [ ] [[package]] -name = "sync_wrapper" -version = "0.1.2" +name = "syn" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] name = "sync_wrapper" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" [[package]] name = "thiserror" @@ -1121,7 +1411,16 @@ version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.60", +] + +[[package]] +name = "thiserror" +version = "2.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" +dependencies = [ + "thiserror-impl 2.0.20", ] [[package]] @@ -1132,7 +1431,18 @@ checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.63", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", ] [[package]] @@ -1145,56 +1455,50 @@ dependencies = [ "once_cell", ] -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "tokio" -version = "1.37.0" +version = "1.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" dependencies = [ - "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.3", +] + +[[package]] +name = "tokio-stream" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", ] [[package]] name = "tokio-tungstenite" -version = "0.21.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" +checksum = "8f72a05e828585856dacd553fba484c242c46e391fb0e58917c942ee9202915c" dependencies = [ "futures-util", "log", @@ -1204,51 +1508,59 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52" dependencies = [ "bytes", "futures-core", "futures-sink", + "libc", "pin-project-lite", "tokio", ] [[package]] -name = "tower" -version = "0.4.13" +name = "tonic" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef" dependencies = [ - "futures-core", - "futures-util", + "async-trait", + "axum", + "base64", + "bytes", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-timeout", + "hyper-util", + "percent-encoding", "pin-project", - "pin-project-lite", + "socket2", + "sync_wrapper", "tokio", + "tokio-stream", + "tower", "tower-layer", "tower-service", "tracing", ] [[package]] -name = "tower-http" -version = "0.5.2" +name = "tower" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ - "bitflags", - "bytes", + "futures-core", "futures-util", - "http", - "http-body", - "http-body-util", - "http-range-header", - "httpdate", - "mime", - "mime_guess", - "percent-encoding", + "indexmap", "pin-project-lite", + "slab", + "sync_wrapper", "tokio", "tokio-util", "tower-layer", @@ -1257,29 +1569,45 @@ dependencies = [ ] [[package]] -name = "tower-layer" -version = "0.3.2" +name = "tower-http" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "b11f75e912b0c2be01b63d8cf8057b8c3f97cf34abb3d431a3a4c8675498e233" +dependencies = [ + "bitflags", + "bytes", + "http", + "percent-encoding", + "pin-project-lite", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tower_governor" -version = "0.4.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "313fa625fea5790ed56360a30ea980e41229cf482b4835801a67ef1922bf63b9" +checksum = "44de9b94d849d3c46e06a883d72d408c2de6403367b39df2b1c9d9e7b6736fe6" dependencies = [ "axum", "forwarded-header-value", "governor", "http", "pin-project", - "thiserror", + "thiserror 2.0.20", + "tonic", "tower", "tracing", ] @@ -1304,7 +1632,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.63", ] [[package]] @@ -1343,22 +1671,25 @@ dependencies = [ ] [[package]] -name = "tungstenite" -version = "0.21.0" +name = "try-lock" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tungstenite" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c01152af293afb9c7c2a57e4b559c5620b421f6d133261c60dd2d0cdb38e6b8" dependencies = [ - "byteorder", "bytes", "data-encoding", "http", "httparse", "log", - "rand", + "rand 0.9.5", "sha1", - "thiserror", - "url", - "utf-8", + "thiserror 2.0.20", ] [[package]] @@ -1369,18 +1700,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicase" -version = "2.7.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" [[package]] name = "unicode-ident" @@ -1388,32 +1710,6 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" -[[package]] -name = "unicode-normalization" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "url" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - [[package]] name = "valuable" version = "0.1.0" @@ -1426,6 +1722,25 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -1433,35 +1748,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "wasm-bindgen" -version = "0.2.92" +name = "wasip2" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ - "cfg-if", - "wasm-bindgen-macro", + "wit-bindgen", ] [[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" +name = "wasm-bindgen" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70" dependencies = [ - "bumpalo", - "log", + "cfg-if", "once_cell", - "proc-macro2", - "quote", - "syn", + "rustversion", + "wasm-bindgen-macro", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1469,22 +1781,25 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284" dependencies = [ + "bumpalo", "proc-macro2", "quote", - "syn", - "wasm-bindgen-backend", + "syn 2.0.63", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf" +dependencies = [ + "unicode-ident", +] [[package]] name = "web-sys" @@ -1496,6 +1811,30 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "websocket" +version = "1.0.0" +dependencies = [ + "application", + "axum", + "domain", + "futures", + "serde", + "serde_json", + "tokio", + "tracing", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1512,6 +1851,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -1519,45 +1867,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows-core" -version = "0.52.0" +name = "windows-link" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.5", -] +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-sys" -version = "0.48.0" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.5", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-link", ] [[package]] @@ -1566,46 +1887,28 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.5" @@ -1618,50 +1921,32 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" diff --git a/Cargo.toml b/Cargo.toml index d0f737a..ed17265 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,22 +1,60 @@ -[package] -name = "painter" -version = "0.1.0" -edition = "2021" +[workspace] +members = [ + "crates/config", + "crates/domain", + "crates/application", + "crates/api-types", + "crates/adapters/canvas-file", + "crates/adapters/config-env", + "crates/adapters/http-axum", + "crates/adapters/socketio", + "crates/adapters/websocket", + "crates/server", +] +default-members = [ + "crates/config", + "crates/domain", + "crates/application", + "crates/api-types", + "crates/adapters/canvas-file", + "crates/adapters/config-env", + "crates/adapters/http-axum", + "crates/server", +] +resolver = "2" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[workspace.package] +version = "1.0.0" +edition = "2024" -[dependencies] -axum = "0.7.5" -bincode = "1.3.3" -bytes = "1.6.0" -chrono = "0.4.38" +[workspace.dependencies] +config = { path = "crates/config" } +domain = { path = "crates/domain" } +application = { path = "crates/application" } +api-types = { path = "crates/api-types" } +canvas-file = { path = "crates/adapters/canvas-file" } +config-env = { path = "crates/adapters/config-env" } +http-axum = { path = "crates/adapters/http-axum" } +socketio = { path = "crates/adapters/socketio" } +websocket = { path = "crates/adapters/websocket" } +futures = "0.3" + +axum = "0.8.9" dotenv = "0.15.0" -memory-stats = "1.1.0" -serde = { version = "1.0.201", features = ["derive"] } -serde_json = "1.0.117" -socketioxide = "0.13.1" -tokio = { version = "1.37.0", features = ["full"] } -tower-http = { version = "0.5.2", features = ["cors", "fs"] } -tower_governor = "0.4.2" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +socketioxide = "0.18.6" +thiserror = "2" +tokio = { version = "1.37", features = ["full"] } +rust-embed = { version = "8", features = ["interpolate-folder-path", "mime-guess"] } +tower-http = { version = "0.7.0", features = ["cors"] } +tower_governor = "0.8.0" tracing = "0.1.40" tracing-subscriber = "0.3.18" + +[profile.release] +lto = true +opt-level = "z" +codegen-units = 1 +panic = "abort" +strip = true diff --git a/Dockerfile b/Dockerfile index 779af35..ee97062 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,19 +1,24 @@ -FROM rust:1.76 as builder +FROM oven/bun:1 AS frontend +WORKDIR /app/painter-js +COPY painter-js/package.json painter-js/bun.lock ./ +RUN bun install --frozen-lockfile +COPY painter-js/ . +RUN bun run build + +FROM rust:1-alpine AS builder WORKDIR /app +RUN apk add --no-cache musl-dev COPY Cargo.toml Cargo.lock ./ +COPY crates/ ./crates/ -COPY src ./src +RUN mkdir -p painter-js/dist && echo '' > painter-js/dist/index.html +RUN cargo build --release --bin server 2>&1 || true -RUN cargo build --release - -FROM rust:1.76 -WORKDIR /app - -COPY --from=builder /app/target/release/painter . -COPY painter-js/dist ./dist -COPY .env .env +COPY --from=frontend /app/painter-js/dist ./painter-js/dist +RUN touch crates/adapters/http-axum/src/routes.rs && cargo build --release --bin server +FROM scratch +COPY --from=builder /app/target/release/server /painter EXPOSE 3000 - -CMD ["./painter"] \ No newline at end of file +ENTRYPOINT ["/painter"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..31bafd2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Gabriel Kaszewski + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c84216c --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ +.PHONY: build dev check check-all test fmt run clean fix + +build: + cargo build --release + +dev: + RUST_LOG=debug cargo run + +check: + cargo fmt --all -- --check + cargo clippy -- -D warnings + cargo test + +check-all: + cargo fmt --all -- --check + cargo clippy --workspace -- -D warnings + cargo test --workspace + +test: + cargo test + +fmt: + cargo fmt --all + +run: + cargo run --release + +fix: + cargo fmt --all + cargo clippy --fix --allow-dirty --allow-staged + +clean: + cargo clean diff --git a/README.md b/README.md index 797d3a2..9152de9 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,121 @@ -# painter +# Painter -Web app inspired by r/place +A collaborative pixel canvas inspired by r/place. Users connect in real-time and place colored pixels on a shared 500x500 canvas. + +## Quick Start + +```bash +# Install frontend dependencies and build +cd painter-js && bun install && bun run build && cd .. + +# Run the server (serves embedded frontend) +cargo run --release +``` + +Open `http://localhost:3000` in your browser. + +## Configuration + +All configuration is via environment variables (or `.env` file): + +| Variable | Default | Description | +|---|---|---| +| `ADDRESS` | `0.0.0.0` | Bind address | +| `PORT` | `3000` | Bind port | +| `ENABLE_CORS` | `true` | Enable CORS headers | +| `CANVAS_WIDTH` | `500` | Canvas width in pixels | +| `CANVAS_HEIGHT` | `500` | Canvas height in pixels | +| `COOLDOWN_SECS` | `10` | Seconds between pixel placements per user | +| `RATE_LIMIT_BURST` | `10` | HTTP rate limit burst size | +| `RATE_LIMIT_PER_SECOND` | `10` | HTTP rate limit per second | +| `BROADCAST_CAPACITY` | `1024` | Broadcast channel buffer size | +| `SNAPSHOT_ENABLED` | `true` | Enable periodic canvas snapshots | +| `SNAPSHOT_INTERVAL_SECS` | `300` | Seconds between snapshots | +| `SNAPSHOT_MAX` | `5` | Maximum snapshot files to keep | +| `SNAPSHOT_DIR` | `snapshots/` | Snapshot storage directory | + +## Transport Adapters + +The server supports two real-time transport protocols, selected at compile time: + +```bash +# Socket.IO (default) +cargo run --release + +# Native WebSocket +cargo run --release --no-default-features --features websocket +``` + +The frontend auto-detects via `VITE_TRANSPORT` environment variable (`socketio` or `websocket`). + +## Docker + +```bash +# Build +docker build -t painter . + +# Run +docker run -p 3000:3000 painter + +# With custom config +docker run -p 3000:3000 \ + -e CANVAS_WIDTH=1000 \ + -e CANVAS_HEIGHT=1000 \ + -e COOLDOWN_SECS=30 \ + -v ./snapshots:/app/snapshots \ + painter +``` + +The Docker image is a single statically-linked binary on `scratch` — **~3MB** total, no OS, no runtime dependencies. The frontend is embedded at compile time. + +The server shuts down gracefully on SIGTERM/SIGINT (Ctrl+C) — in-flight connections are drained and a final canvas snapshot is saved before exit. + +## Development + +```bash +# Backend (watches for changes) +RUST_LOG=debug cargo run + +# Frontend (Vite dev server with HMR) +cd painter-js +VITE_IS_DEBUG=true bun run dev + +# Run all checks (fmt + clippy + tests) +make check + +# Format +make fmt +cd painter-js && bun run fmt +``` + +## Architecture + +Hexagonal architecture with clean dependency boundaries. See [architecture.mmd](architecture.mmd) for the full diagram. + +``` +crates/ + config/ Config structs, ConfigSource trait + domain/ Canvas, value objects, port traits, events + application/ Use cases, AppState, InProcessBroadcaster + api-types/ Shared DTOs, event constants + adapters/ + config-env/ Environment variable config loader + canvas-file/ File-based snapshot persistence + http-axum/ HTTP routes, rate limiting, embedded static files + socketio/ Socket.IO transport adapter + websocket/ Native WebSocket transport adapter + server/ Composition root +``` + +All infrastructure is behind port traits: + +| Port | Adapter | Swappable to | +|---|---|---| +| `CanvasStore` | In-memory | Redis, mmap'd file | +| `CanvasPersistence` | File system | S3, SQLite | +| `EventBroadcaster` | tokio broadcast | NATS, Redis pub/sub | +| `ConfigSource` | Env vars | TOML, JSON, remote API | + +## License + +[MIT](LICENSE) diff --git a/architecture.mmd b/architecture.mmd new file mode 100644 index 0000000..9bd5ca5 --- /dev/null +++ b/architecture.mmd @@ -0,0 +1,83 @@ +graph TB + subgraph Binary ["Server (Composition Root)"] + server["server
wires adapters, starts Axum"] + end + + subgraph Application ["Application Layer"] + AppState["AppState"] + PlacePixel["canvas::place_pixel"] + GetState["canvas::get_state"] + SaveSnapshot["canvas::save_snapshot"] + RestoreSnapshot["canvas::restore_snapshot"] + Connect["soldiers::connect"] + Disconnect["soldiers::disconnect"] + InMemoryCanvas["InMemoryCanvasStore"] + InProcessBroadcast["InProcessBroadcaster"] + end + + subgraph Domain ["Domain Layer (0 infra deps)"] + Canvas["Canvas"] + ValueObjects["Color | Position | PixelUpdate"] + BroadcastEvent["BroadcastEvent"] + DomainError["DomainError"] + + subgraph Ports ["Port Traits"] + CanvasStore["CanvasStore"] + CanvasPersistence["CanvasPersistence"] + EventBroadcaster["EventBroadcaster"] + end + end + + subgraph Shared ["Shared Types"] + Config["config
AppConfig, ConfigSource trait"] + ApiTypes["api-types
PixelUpdatePayload, event constants"] + end + + subgraph Adapters ["Adapters"] + subgraph Transport ["Transport (driving)"] + SocketIO["socketio
Socket.IO protocol"] + WebSocket["websocket
native WebSocket + JSON"] + end + + subgraph Infrastructure ["Infrastructure (driven)"] + ConfigEnv["config-env
env var loader"] + CanvasFile["canvas-file
file snapshots"] + HttpAxum["http-axum
HTTP routes, rate limit,
embedded static files
"] + end + end + + server --> Application + server --> Transport + server --> Infrastructure + server --> Config + + PlacePixel --> CanvasStore + PlacePixel --> EventBroadcaster + SaveSnapshot --> CanvasStore + SaveSnapshot --> CanvasPersistence + RestoreSnapshot --> CanvasStore + RestoreSnapshot --> CanvasPersistence + Connect --> EventBroadcaster + Disconnect --> EventBroadcaster + + InMemoryCanvas -.->|implements| CanvasStore + InProcessBroadcast -.->|implements| EventBroadcaster + CanvasFile -.->|implements| CanvasPersistence + ConfigEnv -.->|implements| Config + + SocketIO --> Application + WebSocket --> Application + SocketIO --> ApiTypes + HttpAxum --> Config + + classDef domain fill:#e8f5e9,stroke:#2e7d32 + classDef app fill:#e3f2fd,stroke:#1565c0 + classDef adapter fill:#fff3e0,stroke:#e65100 + classDef shared fill:#f3e5f5,stroke:#6a1b9a + classDef binary fill:#fce4ec,stroke:#c62828 + + class Canvas,ValueObjects,BroadcastEvent,DomainError,CanvasStore,CanvasPersistence,EventBroadcaster domain + class AppState,PlacePixel,GetState,SaveSnapshot,RestoreSnapshot,Connect,Disconnect,InMemoryCanvas,InProcessBroadcast app + class SocketIO,WebSocket,ConfigEnv,CanvasFile,HttpAxum adapter + class Config,ApiTypes shared + class server binary diff --git a/crates/adapters/canvas-file/Cargo.toml b/crates/adapters/canvas-file/Cargo.toml new file mode 100644 index 0000000..bb97dee --- /dev/null +++ b/crates/adapters/canvas-file/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "canvas-file" +version.workspace = true +edition.workspace = true + +[dependencies] +config = { workspace = true } +domain = { workspace = true } +tracing = { workspace = true } diff --git a/crates/adapters/canvas-file/src/lib.rs b/crates/adapters/canvas-file/src/lib.rs new file mode 100644 index 0000000..6091f33 --- /dev/null +++ b/crates/adapters/canvas-file/src/lib.rs @@ -0,0 +1,158 @@ +use std::fs; +use std::io::{BufWriter, Write}; +use std::path::{Path, PathBuf}; + +use config::SnapshotConfig; +use domain::ports::CanvasPersistence; +use domain::{Color, DomainError}; +use tracing::{error, info}; + +pub struct FileCanvasPersistence { + directory: PathBuf, + max_snapshots: usize, +} + +impl FileCanvasPersistence { + pub fn new(config: &SnapshotConfig) -> Result { + let directory = PathBuf::from(&config.directory); + fs::create_dir_all(&directory).map_err(|err| { + DomainError::Persistence(format!( + "Failed to create snapshot directory '{}': {err}", + directory.display() + )) + })?; + + Ok(Self { + directory, + max_snapshots: config.max_snapshots, + }) + } + + fn snapshot_path(&self, index: usize) -> PathBuf { + self.directory.join(format!("canvas_{index}.bin")) + } + + fn latest_index_path(&self) -> PathBuf { + self.directory.join("latest") + } + + fn read_latest_index(&self) -> Option { + let path = self.latest_index_path(); + fs::read_to_string(&path) + .ok() + .and_then(|content| content.trim().parse().ok()) + } + + fn write_latest_index(&self, index: usize) -> Result<(), DomainError> { + let path = self.latest_index_path(); + fs::write(&path, index.to_string()) + .map_err(|err| DomainError::Persistence(format!("Failed to write latest index: {err}"))) + } + + fn rotate_and_cleanup(&self, new_index: usize) { + if self.max_snapshots == 0 { + return; + } + let oldest_to_keep = new_index.saturating_sub(self.max_snapshots - 1); + for stale_index in 0..oldest_to_keep { + let stale_path = self.snapshot_path(stale_index); + if stale_path.exists() + && let Err(err) = fs::remove_file(&stale_path) + { + error!( + "Failed to remove old snapshot '{}': {err}", + stale_path.display() + ); + } + } + } +} + +impl CanvasPersistence for FileCanvasPersistence { + fn save(&self, pixels: &[Color]) -> Result<(), DomainError> { + let next_index = self.read_latest_index().map(|i| i + 1).unwrap_or(0); + let path = self.snapshot_path(next_index); + + write_pixels_to_file(&path, pixels)?; + self.write_latest_index(next_index)?; + self.rotate_and_cleanup(next_index); + + info!( + "Saved canvas snapshot #{next_index} to '{}'", + path.display() + ); + Ok(()) + } + + fn load_latest(&self) -> Result>, DomainError> { + let Some(index) = self.read_latest_index() else { + info!("No canvas snapshots found"); + return Ok(None); + }; + + let path = self.snapshot_path(index); + if !path.exists() { + info!("Snapshot file '{}' not found", path.display()); + return Ok(None); + } + + let pixels = read_pixels_from_file(&path)?; + info!( + "Loaded canvas snapshot #{index} from '{}' ({} pixels)", + path.display(), + pixels.len() + ); + Ok(Some(pixels)) + } +} + +fn write_pixels_to_file(path: &Path, pixels: &[Color]) -> Result<(), DomainError> { + let file = fs::File::create(path).map_err(|err| { + DomainError::Persistence(format!( + "Failed to create snapshot '{}': {err}", + path.display() + )) + })?; + let mut writer = BufWriter::new(file); + for color in pixels { + writer + .write_all(&color.as_u32().to_ne_bytes()) + .map_err(|err| { + DomainError::Persistence(format!( + "Failed to write snapshot '{}': {err}", + path.display() + )) + })?; + } + writer.flush().map_err(|err| { + DomainError::Persistence(format!( + "Failed to flush snapshot '{}': {err}", + path.display() + )) + })?; + Ok(()) +} + +fn read_pixels_from_file(path: &Path) -> Result, DomainError> { + let bytes = fs::read(path).map_err(|err| { + DomainError::Persistence(format!( + "Failed to read snapshot '{}': {err}", + path.display() + )) + })?; + + if bytes.len() % 4 != 0 { + return Err(DomainError::Persistence(format!( + "Snapshot '{}' has invalid size: {} bytes (not a multiple of 4)", + path.display(), + bytes.len() + ))); + } + + let pixels = bytes + .chunks_exact(4) + .map(|chunk| Color::new(u32::from_ne_bytes([chunk[0], chunk[1], chunk[2], chunk[3]]))) + .collect(); + + Ok(pixels) +} diff --git a/crates/adapters/config-env/Cargo.toml b/crates/adapters/config-env/Cargo.toml new file mode 100644 index 0000000..20e4ec2 --- /dev/null +++ b/crates/adapters/config-env/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "config-env" +version.workspace = true +edition.workspace = true + +[dependencies] +config = { workspace = true } diff --git a/crates/adapters/config-env/src/lib.rs b/crates/adapters/config-env/src/lib.rs new file mode 100644 index 0000000..239d67c --- /dev/null +++ b/crates/adapters/config-env/src/lib.rs @@ -0,0 +1,70 @@ +use config::{ + AppConfig, BroadcastConfig, CanvasConfig, ConfigError, ConfigSource, CooldownConfig, + RateLimitConfig, ServerConfig, SnapshotConfig, +}; + +const DEFAULT_ADDRESS: &str = "0.0.0.0"; +const DEFAULT_PORT: u16 = 3000; +const DEFAULT_CANVAS_WIDTH: u32 = 500; +const DEFAULT_CANVAS_HEIGHT: u32 = 500; +const DEFAULT_COOLDOWN_SECS: u64 = 10; +const DEFAULT_RATE_LIMIT_BURST: u32 = 10; +const DEFAULT_RATE_LIMIT_PER_SECOND: u64 = 10; +const DEFAULT_BROADCAST_CAPACITY: usize = 1024; +const DEFAULT_SNAPSHOT_INTERVAL_SECS: u64 = 300; +const DEFAULT_SNAPSHOT_MAX: usize = 5; +const DEFAULT_SNAPSHOT_DIR: &str = "snapshots/"; + +pub struct EnvConfigSource; + +impl ConfigSource for EnvConfigSource { + fn load(&self) -> Result { + Ok(AppConfig { + server: ServerConfig { + address: env_or("ADDRESS", DEFAULT_ADDRESS), + port: parse_env("PORT", DEFAULT_PORT)?, + enable_cors: parse_bool_env("ENABLE_CORS", true), + }, + canvas: CanvasConfig { + width: parse_env("CANVAS_WIDTH", DEFAULT_CANVAS_WIDTH)?, + height: parse_env("CANVAS_HEIGHT", DEFAULT_CANVAS_HEIGHT)?, + }, + cooldown: CooldownConfig { + placement_secs: parse_env("COOLDOWN_SECS", DEFAULT_COOLDOWN_SECS)?, + }, + rate_limit: RateLimitConfig { + burst_size: parse_env("RATE_LIMIT_BURST", DEFAULT_RATE_LIMIT_BURST)?, + per_second: parse_env("RATE_LIMIT_PER_SECOND", DEFAULT_RATE_LIMIT_PER_SECOND)?, + }, + broadcast: BroadcastConfig { + channel_capacity: parse_env("BROADCAST_CAPACITY", DEFAULT_BROADCAST_CAPACITY)?, + }, + snapshot: SnapshotConfig { + enabled: parse_bool_env("SNAPSHOT_ENABLED", true), + interval_secs: parse_env("SNAPSHOT_INTERVAL_SECS", DEFAULT_SNAPSHOT_INTERVAL_SECS)?, + max_snapshots: parse_env("SNAPSHOT_MAX", DEFAULT_SNAPSHOT_MAX)?, + directory: env_or("SNAPSHOT_DIR", DEFAULT_SNAPSHOT_DIR), + }, + }) + } +} + +fn env_or(key: &str, default: &str) -> String { + std::env::var(key).unwrap_or_else(|_| default.to_string()) +} + +fn parse_bool_env(key: &str, default: bool) -> bool { + std::env::var(key) + .map(|value| value == "true") + .unwrap_or(default) +} + +fn parse_env(key: &str, default: T) -> Result { + match std::env::var(key) { + Ok(value) => value.parse().map_err(|_| ConfigError::InvalidValue { + field: key.to_string(), + reason: format!("'{value}' is not a valid {}", std::any::type_name::()), + }), + Err(_) => Ok(default), + } +} diff --git a/crates/adapters/http-axum/Cargo.toml b/crates/adapters/http-axum/Cargo.toml new file mode 100644 index 0000000..314d9d9 --- /dev/null +++ b/crates/adapters/http-axum/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "http-axum" +version.workspace = true +edition.workspace = true + +[dependencies] +config = { workspace = true } +axum = { workspace = true } +rust-embed = { workspace = true } +tokio = { workspace = true } +tower-http = { workspace = true } +tower_governor = { workspace = true } diff --git a/crates/adapters/http-axum/src/lib.rs b/crates/adapters/http-axum/src/lib.rs new file mode 100644 index 0000000..ff03cc3 --- /dev/null +++ b/crates/adapters/http-axum/src/lib.rs @@ -0,0 +1,3 @@ +mod routes; + +pub use routes::build_router; diff --git a/crates/adapters/http-axum/src/routes.rs b/crates/adapters/http-axum/src/routes.rs new file mode 100644 index 0000000..915581d --- /dev/null +++ b/crates/adapters/http-axum/src/routes.rs @@ -0,0 +1,80 @@ +use std::sync::Arc; + +use axum::http::{StatusCode, header}; +use axum::response::{IntoResponse, Response}; +use axum::{Router, routing::get}; +use config::RateLimitConfig; +use rust_embed::Embed; +use tower_governor::{GovernorLayer, governor::GovernorConfigBuilder}; +use tower_http::cors::{Any, CorsLayer}; + +const RATE_LIMIT_CLEANUP_INTERVAL_SECS: u64 = 1; + +#[derive(Embed)] +#[folder = "$CARGO_MANIFEST_DIR/../../../painter-js/dist/"] +struct StaticAssets; + +async fn serve_static(path: axum::extract::Path) -> Response { + let path = path.0; + serve_embedded_file(&path) +} + +async fn serve_index() -> Response { + serve_embedded_file("index.html") +} + +fn serve_embedded_file(path: &str) -> Response { + match StaticAssets::get(path) { + Some(file) => { + let content_type = file.metadata.mimetype(); + ( + StatusCode::OK, + [(header::CONTENT_TYPE, content_type.to_string())], + file.data, + ) + .into_response() + } + None => serve_embedded_file("index.html"), + } +} + +pub fn build_router( + enable_cors: bool, + rate_limit_config: &RateLimitConfig, +) -> Result { + let rate_governor = Arc::new( + GovernorConfigBuilder::default() + .burst_size(rate_limit_config.burst_size) + .per_second(rate_limit_config.per_second) + .finish() + .ok_or("Invalid rate limit configuration")?, + ); + + let governor = rate_governor.limiter().clone(); + tokio::spawn(async move { + loop { + tokio::time::sleep(std::time::Duration::from_secs( + RATE_LIMIT_CLEANUP_INTERVAL_SECS, + )) + .await; + governor.retain_recent(); + } + }); + + let router = Router::new() + .route("/check/", get(|| async { "OK" })) + .route("/{*path}", get(serve_static)) + .fallback(get(serve_index)) + .layer(GovernorLayer::new(rate_governor)); + + Ok(if enable_cors { + router.layer( + CorsLayer::new() + .allow_origin(Any) + .allow_methods(Any) + .allow_headers(Any), + ) + } else { + router + }) +} diff --git a/crates/adapters/socketio/Cargo.toml b/crates/adapters/socketio/Cargo.toml new file mode 100644 index 0000000..411167b --- /dev/null +++ b/crates/adapters/socketio/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "socketio" +version.workspace = true +edition.workspace = true + +[dependencies] +application = { workspace = true } +api-types = { workspace = true } +domain = { workspace = true } +serde_json = { workspace = true } +socketioxide = { workspace = true } +tokio = { workspace = true } +tracing = { workspace = true } diff --git a/crates/adapters/socketio/src/handlers.rs b/crates/adapters/socketio/src/handlers.rs new file mode 100644 index 0000000..8d0515e --- /dev/null +++ b/crates/adapters/socketio/src/handlers.rs @@ -0,0 +1,109 @@ +use std::sync::Arc; + +use api_types::{self, PixelUpdatePayload}; +use application::AppState; +use application::canvas::place_pixel; +use domain::{BroadcastEvent, BroadcastSubscription, Color, Position}; +use socketioxide::extract::{Data, SocketRef}; +use tracing::info; + +pub async fn on_connect(socket: SocketRef, state: Arc) { + info!("Socket connected: {:?} {:?}", socket.ns(), socket.id); + + let subscription = state.broadcaster().subscribe(); + + send_canvas_state(&socket, &state); + register_soldier(&state, &socket); + spawn_broadcast_forwarder(socket.clone(), subscription); + register_place_pixel_handler(&socket, state.clone()); + register_disconnect_handler(&socket, state); +} + +fn send_canvas_state(socket: &SocketRef, state: &AppState) { + let canvas_pixels = application::canvas::get_state::execute(state); + let pixel_values = Color::collect_as_u32(&canvas_pixels); + socket + .emit(api_types::events::CANVAS_STATE, &pixel_values) + .ok(); +} + +fn register_soldier(state: &AppState, socket: &SocketRef) { + let socket_id = socket.id.to_string(); + application::soldiers::connect::execute(state, socket_id); +} + +fn spawn_broadcast_forwarder(socket: SocketRef, mut subscription: BroadcastSubscription) { + tokio::spawn(async move { + while let Some(event) = subscription.recv().await { + if forward_broadcast_event(&socket, &event).is_err() { + break; + } + } + }); +} + +fn forward_broadcast_event(socket: &SocketRef, event: &BroadcastEvent) -> Result<(), ()> { + match event { + BroadcastEvent::PixelUpdated(update) => { + let payload = PixelUpdatePayload::from(*update); + socket + .emit(api_types::events::PIXEL_UPDATED, &payload) + .map_err(|_| ()) + } + BroadcastEvent::SoldierCountChanged(count) => socket + .emit(api_types::events::CURRENT_SOLDIERS, count) + .map_err(|_| ()), + } +} + +fn register_place_pixel_handler(socket: &SocketRef, state: Arc) { + socket.on( + api_types::events::PLACE_PIXEL, + move |socket: SocketRef, Data::(payload)| async move { + handle_place_pixel(&socket, &state, payload); + }, + ); +} + +fn handle_place_pixel(socket: &SocketRef, state: &AppState, payload: PixelUpdatePayload) { + let position = Position::new(payload.x, payload.y); + let color = Color::new(payload.color); + + info!("Received pixel update: {position} color={}", color.as_u32()); + + let socket_id = socket.id.to_string(); + let command = place_pixel::Command { + user_id: &socket_id, + position, + color, + }; + + match place_pixel::execute(state, command) { + Ok(place_pixel::Outcome::Placed(_)) => {} + Ok(place_pixel::Outcome::CooldownActive) => { + emit_error(socket, domain::COOLDOWN_MESSAGE); + } + Err(err) => { + emit_error(socket, &err.to_string()); + } + } +} + +fn register_disconnect_handler(socket: &SocketRef, state: Arc) { + socket.on_disconnect(move |socket: SocketRef| async move { + handle_disconnect(&socket, &state); + }); +} + +fn handle_disconnect(socket: &SocketRef, state: &AppState) { + info!("Socket disconnected: {:?}", socket.id); + let socket_id = socket.id.to_string(); + application::soldiers::disconnect::execute(state, &socket_id); +} + +fn emit_error(socket: &SocketRef, message: &str) { + let _ = socket.emit( + api_types::events::ERROR, + &serde_json::Value::String(message.to_string()), + ); +} diff --git a/crates/adapters/socketio/src/lib.rs b/crates/adapters/socketio/src/lib.rs new file mode 100644 index 0000000..bb9d321 --- /dev/null +++ b/crates/adapters/socketio/src/lib.rs @@ -0,0 +1,12 @@ +mod handlers; + +use std::sync::Arc; + +use application::AppState; +use socketioxide::{SocketIo, extract::SocketRef}; + +pub fn setup_namespaces(io: &SocketIo, state: Arc) { + io.ns("/", move |socket: SocketRef| async move { + handlers::on_connect(socket, state).await; + }); +} diff --git a/crates/adapters/websocket/Cargo.toml b/crates/adapters/websocket/Cargo.toml new file mode 100644 index 0000000..445a798 --- /dev/null +++ b/crates/adapters/websocket/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "websocket" +version.workspace = true +edition.workspace = true + +[dependencies] +application = { workspace = true } +domain = { workspace = true } +axum = { workspace = true, features = ["ws"] } +futures = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +tokio = { workspace = true } +tracing = { workspace = true } diff --git a/crates/adapters/websocket/src/handler.rs b/crates/adapters/websocket/src/handler.rs new file mode 100644 index 0000000..2e247cd --- /dev/null +++ b/crates/adapters/websocket/src/handler.rs @@ -0,0 +1,163 @@ +use std::sync::Arc; +use std::sync::atomic::Ordering; + +use axum::extract::State; +use axum::extract::ws::{Message, WebSocket, WebSocketUpgrade}; +use axum::response::IntoResponse; +use domain::{BroadcastEvent, BroadcastSubscription, Color, Position}; +use futures::{SinkExt, StreamExt, stream::SplitSink}; +use tokio::sync::mpsc; +use tracing::{error, info}; + +use crate::WsState; +use crate::messages::{ClientMessage, ServerMessage}; +use application::AppState; +use application::canvas::place_pixel; + +type WsSender = SplitSink; + +pub async fn ws_upgrade( + ws: WebSocketUpgrade, + State(state): State>, +) -> impl IntoResponse { + ws.on_upgrade(|socket| handle_connection(socket, state)) +} + +async fn handle_connection(socket: WebSocket, state: Arc) { + let (mut sender, mut receiver) = socket.split(); + + let connection_id = state + .connection_counter + .fetch_add(1, Ordering::Relaxed) + .to_string(); + + info!("WebSocket connected: {connection_id}"); + + // Subscribe before snapshotting to avoid missing updates + let subscription = state.app_state.broadcaster().subscribe(); + + if !send_canvas_snapshot(&mut sender, &state.app_state).await { + return; + } + + application::soldiers::connect::execute(&state.app_state, connection_id.clone()); + + let (error_sender, error_receiver) = mpsc::unbounded_channel::(); + + let mut send_task = tokio::spawn(run_send_loop(sender, subscription, error_receiver)); + + let app_state = state.app_state.clone(); + let recv_connection_id = connection_id.clone(); + let mut recv_task = tokio::spawn(async move { + while let Some(Ok(message)) = receiver.next().await { + if let Message::Text(text) = message { + handle_client_message(&app_state, &error_sender, &recv_connection_id, &text); + } else if let Message::Close(_) = message { + break; + } + } + }); + + tokio::select! { + _ = &mut send_task => recv_task.abort(), + _ = &mut recv_task => send_task.abort(), + } + + info!("WebSocket disconnected: {connection_id}"); + application::soldiers::disconnect::execute(&state.app_state, &connection_id); +} + +async fn send_canvas_snapshot(sender: &mut WsSender, state: &AppState) -> bool { + let pixels = application::canvas::get_state::execute(state); + let bytes = Color::collect_as_bytes(&pixels); + sender.send(Message::Binary(bytes.into())).await.is_ok() +} + +async fn run_send_loop( + mut sender: WsSender, + mut subscription: BroadcastSubscription, + mut error_receiver: mpsc::UnboundedReceiver, +) { + loop { + tokio::select! { + Some(event) = subscription.recv() => { + let Some(json) = serialize_broadcast_event(&event) else { continue }; + if sender.send(Message::Text(json.into())).await.is_err() { + break; + } + } + Some(error_json) = error_receiver.recv() => { + if sender.send(Message::Text(error_json.into())).await.is_err() { + break; + } + } + else => break, + } + } +} + +fn serialize_broadcast_event(event: &BroadcastEvent) -> Option { + let message = match event { + BroadcastEvent::PixelUpdated(update) => ServerMessage::from(*update), + BroadcastEvent::SoldierCountChanged(count) => { + ServerMessage::CurrentSoldiers { count: *count } + } + }; + serde_json::to_string(&message) + .inspect_err(|err| error!("Failed to serialize broadcast event: {err}")) + .ok() +} + +fn handle_client_message( + state: &AppState, + error_sender: &mpsc::UnboundedSender, + connection_id: &str, + text: &str, +) { + let Ok(message) = serde_json::from_str::(text) else { + return; + }; + + match message { + ClientMessage::PlacePixel { x, y, color } => { + handle_place_pixel(state, error_sender, connection_id, x, y, color); + } + } +} + +fn handle_place_pixel( + state: &AppState, + error_sender: &mpsc::UnboundedSender, + connection_id: &str, + x: u32, + y: u32, + color: u32, +) { + let command = place_pixel::Command { + user_id: connection_id, + position: Position::new(x, y), + color: Color::new(color), + }; + + match place_pixel::execute(state, command) { + Ok(place_pixel::Outcome::Placed(_)) => {} + Ok(place_pixel::Outcome::CooldownActive) => { + send_error(error_sender, domain::COOLDOWN_MESSAGE); + } + Err(err) => { + send_error(error_sender, &err.to_string()); + } + } +} + +fn send_error(error_sender: &mpsc::UnboundedSender, message: &str) { + let error_message = ServerMessage::Error { + message: message.to_string(), + }; + match serde_json::to_string(&error_message) { + Ok(json) => { + let _ = error_sender.send(json); + } + Err(err) => error!("Failed to serialize error message: {err}"), + } +} diff --git a/crates/adapters/websocket/src/lib.rs b/crates/adapters/websocket/src/lib.rs new file mode 100644 index 0000000..f193514 --- /dev/null +++ b/crates/adapters/websocket/src/lib.rs @@ -0,0 +1,24 @@ +mod handler; +mod messages; + +use std::sync::Arc; +use std::sync::atomic::AtomicU64; + +use application::AppState; +use axum::{Router, routing::get}; + +pub(crate) struct WsState { + app_state: Arc, + connection_counter: AtomicU64, +} + +pub fn build_router(state: Arc) -> Router { + let ws_state = Arc::new(WsState { + app_state: state, + connection_counter: AtomicU64::new(0), + }); + + Router::new() + .route("/ws", get(handler::ws_upgrade)) + .with_state(ws_state) +} diff --git a/crates/adapters/websocket/src/messages.rs b/crates/adapters/websocket/src/messages.rs new file mode 100644 index 0000000..c9aa32b --- /dev/null +++ b/crates/adapters/websocket/src/messages.rs @@ -0,0 +1,30 @@ +use domain::PixelUpdate; +use serde::{Deserialize, Serialize}; + +#[derive(Deserialize)] +#[serde(tag = "type")] +pub enum ClientMessage { + #[serde(rename = "place-pixel")] + PlacePixel { x: u32, y: u32, color: u32 }, +} + +#[derive(Serialize)] +#[serde(tag = "type")] +pub enum ServerMessage { + #[serde(rename = "pixel-updated")] + PixelUpdated { x: u32, y: u32, color: u32 }, + #[serde(rename = "current_soldiers")] + CurrentSoldiers { count: usize }, + #[serde(rename = "error")] + Error { message: String }, +} + +impl From for ServerMessage { + fn from(update: PixelUpdate) -> Self { + Self::PixelUpdated { + x: update.position().x(), + y: update.position().y(), + color: update.color().as_u32(), + } + } +} diff --git a/crates/api-types/Cargo.toml b/crates/api-types/Cargo.toml new file mode 100644 index 0000000..2d80631 --- /dev/null +++ b/crates/api-types/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "api-types" +version.workspace = true +edition.workspace = true + +[dependencies] +domain = { workspace = true } +serde = { workspace = true } diff --git a/crates/api-types/src/lib.rs b/crates/api-types/src/lib.rs new file mode 100644 index 0000000..9474198 --- /dev/null +++ b/crates/api-types/src/lib.rs @@ -0,0 +1,27 @@ +use domain::PixelUpdate; +use serde::{Deserialize, Serialize}; + +pub mod events { + pub const CANVAS_STATE: &str = "canvas_state"; + pub const PIXEL_UPDATED: &str = "pixel-updated"; + pub const PLACE_PIXEL: &str = "place-pixel"; + pub const CURRENT_SOLDIERS: &str = "current_soldiers"; + pub const ERROR: &str = "error"; +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct PixelUpdatePayload { + pub x: u32, + pub y: u32, + pub color: u32, +} + +impl From for PixelUpdatePayload { + fn from(update: PixelUpdate) -> Self { + Self { + x: update.position().x(), + y: update.position().y(), + color: update.color().as_u32(), + } + } +} diff --git a/crates/application/Cargo.toml b/crates/application/Cargo.toml new file mode 100644 index 0000000..7156e61 --- /dev/null +++ b/crates/application/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "application" +version.workspace = true +edition.workspace = true + +[dependencies] +domain = { workspace = true } +thiserror = { workspace = true } +tokio = { workspace = true } +tracing = { workspace = true } diff --git a/crates/application/src/canvas/get_state.rs b/crates/application/src/canvas/get_state.rs new file mode 100644 index 0000000..6d14c08 --- /dev/null +++ b/crates/application/src/canvas/get_state.rs @@ -0,0 +1,9 @@ +use std::sync::Arc; + +use domain::Color; + +use crate::AppState; + +pub fn execute(state: &AppState) -> Arc<[Color]> { + state.canvas().pixels() +} diff --git a/crates/application/src/canvas/mod.rs b/crates/application/src/canvas/mod.rs new file mode 100644 index 0000000..2fe741c --- /dev/null +++ b/crates/application/src/canvas/mod.rs @@ -0,0 +1,4 @@ +pub mod get_state; +pub mod place_pixel; +pub mod restore_snapshot; +pub mod save_snapshot; diff --git a/crates/application/src/canvas/place_pixel.rs b/crates/application/src/canvas/place_pixel.rs new file mode 100644 index 0000000..871ff35 --- /dev/null +++ b/crates/application/src/canvas/place_pixel.rs @@ -0,0 +1,29 @@ +use domain::{BroadcastEvent, Color, PixelUpdate, Position}; + +use crate::{AppState, ApplicationError}; + +pub struct Command<'a> { + pub user_id: &'a str, + pub position: Position, + pub color: Color, +} + +pub enum Outcome { + Placed(PixelUpdate), + CooldownActive, +} + +pub fn execute(state: &AppState, command: Command<'_>) -> Result { + if state.cooldowns().is_on_cooldown(command.user_id) { + return Ok(Outcome::CooldownActive); + } + state + .canvas() + .place_pixel(command.position, command.color)?; + state.cooldowns().record(command.user_id); + let update = PixelUpdate::new(command.position, command.color); + state + .broadcaster() + .publish(BroadcastEvent::PixelUpdated(update)); + Ok(Outcome::Placed(update)) +} diff --git a/crates/application/src/canvas/restore_snapshot.rs b/crates/application/src/canvas/restore_snapshot.rs new file mode 100644 index 0000000..5967867 --- /dev/null +++ b/crates/application/src/canvas/restore_snapshot.rs @@ -0,0 +1,14 @@ +use crate::{AppState, ApplicationError}; + +pub fn execute(state: &AppState) -> Result { + let Some(persistence) = state.persistence() else { + return Ok(false); + }; + match persistence.load_latest()? { + Some(pixels) => { + state.canvas().restore(pixels)?; + Ok(true) + } + None => Ok(false), + } +} diff --git a/crates/application/src/canvas/save_snapshot.rs b/crates/application/src/canvas/save_snapshot.rs new file mode 100644 index 0000000..85b6846 --- /dev/null +++ b/crates/application/src/canvas/save_snapshot.rs @@ -0,0 +1,10 @@ +use crate::{AppState, ApplicationError}; + +pub fn execute(state: &AppState) -> Result<(), ApplicationError> { + let Some(persistence) = state.persistence() else { + return Ok(()); + }; + let pixels = state.canvas().pixels(); + persistence.save(&pixels)?; + Ok(()) +} diff --git a/crates/application/src/errors.rs b/crates/application/src/errors.rs new file mode 100644 index 0000000..235e7ed --- /dev/null +++ b/crates/application/src/errors.rs @@ -0,0 +1,7 @@ +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum ApplicationError { + #[error(transparent)] + Domain(#[from] domain::DomainError), +} diff --git a/crates/application/src/lib.rs b/crates/application/src/lib.rs new file mode 100644 index 0000000..f2b3ff9 --- /dev/null +++ b/crates/application/src/lib.rs @@ -0,0 +1,8 @@ +mod errors; +mod state; + +pub mod canvas; +pub mod soldiers; + +pub use errors::ApplicationError; +pub use state::{AppState, InMemoryCanvasStore, InProcessBroadcaster}; diff --git a/crates/application/src/soldiers/connect.rs b/crates/application/src/soldiers/connect.rs new file mode 100644 index 0000000..6725374 --- /dev/null +++ b/crates/application/src/soldiers/connect.rs @@ -0,0 +1,11 @@ +use domain::BroadcastEvent; + +use crate::AppState; + +pub fn execute(state: &AppState, user_id: String) -> usize { + let count = state.soldiers().add(user_id); + state + .broadcaster() + .publish(BroadcastEvent::SoldierCountChanged(count)); + count +} diff --git a/crates/application/src/soldiers/disconnect.rs b/crates/application/src/soldiers/disconnect.rs new file mode 100644 index 0000000..89b3b8f --- /dev/null +++ b/crates/application/src/soldiers/disconnect.rs @@ -0,0 +1,12 @@ +use domain::BroadcastEvent; + +use crate::AppState; + +pub fn execute(state: &AppState, user_id: &str) -> usize { + state.cooldowns().remove(user_id); + let count = state.soldiers().remove(user_id); + state + .broadcaster() + .publish(BroadcastEvent::SoldierCountChanged(count)); + count +} diff --git a/crates/application/src/soldiers/mod.rs b/crates/application/src/soldiers/mod.rs new file mode 100644 index 0000000..587edf0 --- /dev/null +++ b/crates/application/src/soldiers/mod.rs @@ -0,0 +1,2 @@ +pub mod connect; +pub mod disconnect; diff --git a/crates/application/src/state.rs b/crates/application/src/state.rs new file mode 100644 index 0000000..77fae3c --- /dev/null +++ b/crates/application/src/state.rs @@ -0,0 +1,199 @@ +use std::collections::{HashMap, HashSet}; +use std::future::Future; +use std::pin::Pin; +use std::sync::{Arc, Mutex, MutexGuard}; +use std::time::{Duration, Instant}; + +use domain::ports::{ + BroadcastReceiverInner, BroadcastSubscription, CanvasPersistence, CanvasStore, EventBroadcaster, +}; +use domain::{BroadcastEvent, Canvas, Color, DomainError, Position}; +use tokio::sync::broadcast; +use tracing::warn; + +const INITIAL_CONNECTION_CAPACITY: usize = 128; + +pub struct AppState { + canvas: Box, + broadcaster: Box, + persistence: Option>, + cooldowns: CooldownTracker, + soldiers: SoldierTracker, +} + +impl AppState { + pub fn new( + canvas: Box, + broadcaster: Box, + cooldown: Duration, + ) -> Self { + Self { + canvas, + broadcaster, + persistence: None, + cooldowns: CooldownTracker::new(cooldown), + soldiers: SoldierTracker::new(), + } + } + + pub fn with_persistence(mut self, persistence: Box) -> Self { + self.persistence = Some(persistence); + self + } + + pub fn canvas(&self) -> &dyn CanvasStore { + &*self.canvas + } + + pub fn broadcaster(&self) -> &dyn EventBroadcaster { + &*self.broadcaster + } + + pub fn persistence(&self) -> Option<&dyn CanvasPersistence> { + self.persistence.as_deref() + } + + pub fn cooldowns(&self) -> &CooldownTracker { + &self.cooldowns + } + + pub fn soldiers(&self) -> &SoldierTracker { + &self.soldiers + } +} + +pub struct InProcessBroadcaster { + sender: broadcast::Sender, +} + +impl InProcessBroadcaster { + pub fn new(sender: broadcast::Sender) -> Self { + Self { sender } + } +} + +impl EventBroadcaster for InProcessBroadcaster { + fn publish(&self, event: BroadcastEvent) { + let _ = self.sender.send(event); + } + + fn subscribe(&self) -> BroadcastSubscription { + BroadcastSubscription::new(Box::new(TokioBroadcastReceiver(self.sender.subscribe()))) + } +} + +struct TokioBroadcastReceiver(broadcast::Receiver); + +impl BroadcastReceiverInner for TokioBroadcastReceiver { + fn recv_boxed(&mut self) -> Pin> + Send + '_>> { + Box::pin(async { self.0.recv().await.ok() }) + } +} + +fn acquire_lock(mutex: &Mutex) -> MutexGuard<'_, T> { + mutex.lock().unwrap_or_else(|poisoned| { + warn!("Recovered from poisoned mutex"); + poisoned.into_inner() + }) +} + +struct CanvasState { + canvas: Canvas, + snapshot: Option>, +} + +pub struct InMemoryCanvasStore { + state: Mutex, +} + +impl InMemoryCanvasStore { + pub fn new(width: u32, height: u32) -> Self { + Self { + state: Mutex::new(CanvasState { + canvas: Canvas::new(width, height), + snapshot: None, + }), + } + } +} + +impl CanvasStore for InMemoryCanvasStore { + fn pixels(&self) -> Arc<[Color]> { + let mut state = acquire_lock(&self.state); + if let Some(ref cached) = state.snapshot { + return cached.clone(); + } + let new_snapshot: Arc<[Color]> = Arc::from(state.canvas.pixels()); + state.snapshot = Some(new_snapshot.clone()); + new_snapshot + } + + fn place_pixel(&self, position: Position, color: Color) -> Result<(), DomainError> { + let mut state = acquire_lock(&self.state); + state.canvas.place_pixel(position, color)?; + state.snapshot = None; + Ok(()) + } + + fn restore(&self, pixels: Vec) -> Result<(), DomainError> { + let mut state = acquire_lock(&self.state); + let new_canvas = Canvas::from_pixels(state.canvas.width(), state.canvas.height(), pixels)?; + state.canvas = new_canvas; + state.snapshot = None; + Ok(()) + } +} + +pub struct CooldownTracker { + entries: Mutex>, + cooldown: Duration, +} + +impl CooldownTracker { + pub fn new(cooldown: Duration) -> Self { + Self { + entries: Mutex::new(HashMap::with_capacity(INITIAL_CONNECTION_CAPACITY)), + cooldown, + } + } + + pub fn is_on_cooldown(&self, user_id: &str) -> bool { + let entries = acquire_lock(&self.entries); + entries + .get(user_id) + .map(|last| last.elapsed() < self.cooldown) + .unwrap_or(false) + } + + pub fn record(&self, user_id: &str) { + acquire_lock(&self.entries).insert(user_id.to_string(), Instant::now()); + } + + pub fn remove(&self, user_id: &str) { + acquire_lock(&self.entries).remove(user_id); + } +} + +pub struct SoldierTracker { + connected: Mutex>, +} + +impl SoldierTracker { + pub fn new() -> Self { + Self { + connected: Mutex::new(HashSet::with_capacity(INITIAL_CONNECTION_CAPACITY)), + } + } + + pub fn add(&self, user_id: String) -> usize { + let mut connected = acquire_lock(&self.connected); + connected.insert(user_id); + connected.len() + } + + pub fn remove(&self, user_id: &str) -> usize { + let mut connected = acquire_lock(&self.connected); + connected.remove(user_id); + connected.len() + } +} diff --git a/crates/application/tests/common/mod.rs b/crates/application/tests/common/mod.rs new file mode 100644 index 0000000..8d5c430 --- /dev/null +++ b/crates/application/tests/common/mod.rs @@ -0,0 +1,109 @@ +use std::future::Future; +use std::pin::Pin; +use std::sync::{Arc, Mutex}; +use std::time::Duration; + +use application::{AppState, InMemoryCanvasStore}; +use domain::ports::{ + BroadcastReceiverInner, BroadcastSubscription, CanvasPersistence, EventBroadcaster, +}; +use domain::{BroadcastEvent, Color, DomainError}; + +#[derive(Clone)] +pub struct SpyBroadcaster { + events: Arc>>, +} + +impl SpyBroadcaster { + pub fn new() -> Self { + Self { + events: Arc::new(Mutex::new(Vec::new())), + } + } + + pub fn events(&self) -> Vec { + self.events.lock().unwrap().clone() + } + + pub fn event_count(&self) -> usize { + self.events.lock().unwrap().len() + } +} + +impl EventBroadcaster for SpyBroadcaster { + fn publish(&self, event: BroadcastEvent) { + self.events.lock().unwrap().push(event); + } + + fn subscribe(&self) -> BroadcastSubscription { + BroadcastSubscription::new(Box::new(NoopReceiver)) + } +} + +struct NoopReceiver; + +impl BroadcastReceiverInner for NoopReceiver { + fn recv_boxed(&mut self) -> Pin> + Send + '_>> { + Box::pin(async { None }) + } +} + +pub struct FakePersistence { + saved: Arc>>>, + to_load: Mutex>>, +} + +impl FakePersistence { + pub fn empty() -> Self { + Self { + saved: Arc::new(Mutex::new(Vec::new())), + to_load: Mutex::new(None), + } + } + + pub fn with_snapshot(pixels: Vec) -> Self { + Self { + saved: Arc::new(Mutex::new(Vec::new())), + to_load: Mutex::new(Some(pixels)), + } + } + + pub fn saved_ref(&self) -> Arc>>> { + self.saved.clone() + } +} + +impl CanvasPersistence for FakePersistence { + fn save(&self, pixels: &[Color]) -> Result<(), DomainError> { + self.saved.lock().unwrap().push(pixels.to_vec()); + Ok(()) + } + + fn load_latest(&self) -> Result>, DomainError> { + Ok(self.to_load.lock().unwrap().clone()) + } +} + +pub fn test_state() -> (Arc, SpyBroadcaster) { + test_state_sized(10, 10) +} + +pub fn test_state_sized(width: u32, height: u32) -> (Arc, SpyBroadcaster) { + let spy = SpyBroadcaster::new(); + let state = AppState::new( + Box::new(InMemoryCanvasStore::new(width, height)), + Box::new(spy.clone()), + Duration::from_secs(10), + ); + (Arc::new(state), spy) +} + +pub fn test_state_no_cooldown() -> (Arc, SpyBroadcaster) { + let spy = SpyBroadcaster::new(); + let state = AppState::new( + Box::new(InMemoryCanvasStore::new(10, 10)), + Box::new(spy.clone()), + Duration::ZERO, + ); + (Arc::new(state), spy) +} diff --git a/crates/application/tests/place_pixel.rs b/crates/application/tests/place_pixel.rs new file mode 100644 index 0000000..72b18f0 --- /dev/null +++ b/crates/application/tests/place_pixel.rs @@ -0,0 +1,91 @@ +mod common; + +use application::canvas::place_pixel::{Command, Outcome}; +use domain::{BroadcastEvent, Color, Position}; + +macro_rules! place { + ($state:expr, $user:expr, $x:expr, $y:expr, $color:expr) => { + application::canvas::place_pixel::execute( + &$state, + Command { + user_id: $user, + position: Position::new($x, $y), + color: Color::new($color), + }, + ) + }; +} + +#[test] +fn successful_placement_returns_update() { + let (state, _) = common::test_state(); + let result = place!(state, "user-1", 3, 4, 0xFF0000).unwrap(); + + let Outcome::Placed(update) = result else { + panic!("expected Placed outcome"); + }; + assert_eq!(update.position(), Position::new(3, 4)); + assert_eq!(update.color(), Color::new(0xFF0000)); +} + +#[test] +fn placement_updates_canvas() { + let (state, _) = common::test_state(); + place!(state, "user-1", 5, 5, 0xAA).unwrap(); + + let pixels = application::canvas::get_state::execute(&state); + let idx = 5 * 10 + 5; + assert_eq!(pixels[idx], Color::new(0xAA)); +} + +#[test] +fn placement_publishes_broadcast_event() { + let (state, spy) = common::test_state(); + place!(state, "user-1", 0, 0, 0xFF).unwrap(); + + let events = spy.events(); + assert_eq!(events.len(), 1); + assert!(matches!(events[0], BroadcastEvent::PixelUpdated(_))); +} + +#[test] +fn cooldown_blocks_rapid_placement() { + let (state, _) = common::test_state(); + place!(state, "user-1", 0, 0, 0xFF).unwrap(); + + let result = place!(state, "user-1", 1, 1, 0xAA).unwrap(); + assert!(matches!(result, Outcome::CooldownActive)); +} + +#[test] +fn cooldown_is_per_user() { + let (state, _) = common::test_state(); + place!(state, "user-1", 0, 0, 0xFF).unwrap(); + + let result = place!(state, "user-2", 1, 1, 0xAA).unwrap(); + assert!(matches!(result, Outcome::Placed(_))); +} + +#[test] +fn zero_cooldown_allows_rapid_placement() { + let (state, _) = common::test_state_no_cooldown(); + place!(state, "user-1", 0, 0, 0xFF).unwrap(); + + let result = place!(state, "user-1", 1, 1, 0xAA).unwrap(); + assert!(matches!(result, Outcome::Placed(_))); +} + +#[test] +fn out_of_bounds_returns_error() { + let (state, _) = common::test_state(); + assert!(place!(state, "user-1", 99, 99, 0xFF).is_err()); +} + +#[test] +fn failed_placement_does_not_trigger_cooldown() { + let (state, _) = common::test_state(); + let _ = place!(state, "user-1", 99, 99, 0xFF); + + let result = place!(state, "user-1", 0, 0, 0xFF).unwrap(); + assert!(matches!(result, Outcome::Placed(_))); +} diff --git a/crates/application/tests/snapshots.rs b/crates/application/tests/snapshots.rs new file mode 100644 index 0000000..cacd493 --- /dev/null +++ b/crates/application/tests/snapshots.rs @@ -0,0 +1,75 @@ +mod common; + +use std::sync::Arc; + +use application::AppState; +use domain::Color; + +fn state_with_persistence(persistence: common::FakePersistence) -> Arc { + let spy = common::SpyBroadcaster::new(); + let state = AppState::new( + Box::new(application::InMemoryCanvasStore::new(10, 10)), + Box::new(spy), + std::time::Duration::from_secs(10), + ) + .with_persistence(Box::new(persistence)); + Arc::new(state) +} + +#[test] +fn save_snapshot_persists_current_canvas() { + let persistence = common::FakePersistence::empty(); + let saved_ref = persistence.saved_ref(); + let state = state_with_persistence(persistence); + + application::canvas::place_pixel::execute( + &state, + application::canvas::place_pixel::Command { + user_id: "user", + position: domain::Position::new(0, 0), + color: Color::new(0xFF), + }, + ) + .unwrap(); + + application::canvas::save_snapshot::execute(&state).unwrap(); + + let snapshots = saved_ref.lock().unwrap(); + assert_eq!(snapshots.len(), 1); + assert_eq!(snapshots[0][0], Color::new(0xFF)); + assert_eq!(snapshots[0].len(), 100); +} + +#[test] +fn restore_snapshot_loads_canvas() { + let mut snapshot = vec![Color::white(); 100]; + snapshot[0] = Color::new(0xDEAD); + snapshot[99] = Color::new(0xBEEF); + + let state = state_with_persistence(common::FakePersistence::with_snapshot(snapshot)); + + let restored = application::canvas::restore_snapshot::execute(&state).unwrap(); + assert!(restored); + + let pixels = application::canvas::get_state::execute(&state); + assert_eq!(pixels[0], Color::new(0xDEAD)); + assert_eq!(pixels[99], Color::new(0xBEEF)); +} + +#[test] +fn restore_returns_false_when_no_snapshot() { + let state = state_with_persistence(common::FakePersistence::empty()); + assert!(!application::canvas::restore_snapshot::execute(&state).unwrap()); +} + +#[test] +fn save_without_persistence_is_noop() { + let (state, _) = common::test_state(); + assert!(application::canvas::save_snapshot::execute(&state).is_ok()); +} + +#[test] +fn restore_without_persistence_returns_false() { + let (state, _) = common::test_state(); + assert!(!application::canvas::restore_snapshot::execute(&state).unwrap()); +} diff --git a/crates/application/tests/soldiers.rs b/crates/application/tests/soldiers.rs new file mode 100644 index 0000000..f28e259 --- /dev/null +++ b/crates/application/tests/soldiers.rs @@ -0,0 +1,96 @@ +mod common; + +use domain::BroadcastEvent; + +#[test] +fn connect_increments_count() { + let (state, _) = common::test_state(); + assert_eq!( + application::soldiers::connect::execute(&state, "a".into()), + 1 + ); + assert_eq!( + application::soldiers::connect::execute(&state, "b".into()), + 2 + ); + assert_eq!( + application::soldiers::connect::execute(&state, "c".into()), + 3 + ); +} + +#[test] +fn disconnect_decrements_count() { + let (state, _) = common::test_state(); + application::soldiers::connect::execute(&state, "a".into()); + application::soldiers::connect::execute(&state, "b".into()); + + assert_eq!(application::soldiers::disconnect::execute(&state, "a"), 1); + assert_eq!(application::soldiers::disconnect::execute(&state, "b"), 0); +} + +#[test] +fn disconnect_unknown_user_is_harmless() { + let (state, _) = common::test_state(); + application::soldiers::connect::execute(&state, "a".into()); + assert_eq!( + application::soldiers::disconnect::execute(&state, "unknown"), + 1 + ); +} + +#[test] +fn connect_publishes_soldier_count() { + let (state, spy) = common::test_state(); + application::soldiers::connect::execute(&state, "a".into()); + + let events = spy.events(); + assert_eq!(events.len(), 1); + assert!(matches!(events[0], BroadcastEvent::SoldierCountChanged(1))); +} + +#[test] +fn disconnect_publishes_soldier_count() { + let (state, spy) = common::test_state(); + application::soldiers::connect::execute(&state, "a".into()); + application::soldiers::disconnect::execute(&state, "a"); + + let events = spy.events(); + assert_eq!(events.len(), 2); + assert!(matches!(events[1], BroadcastEvent::SoldierCountChanged(0))); +} + +#[test] +fn disconnect_clears_cooldown() { + let (state, _) = common::test_state(); + application::soldiers::connect::execute(&state, "user-1".into()); + + application::canvas::place_pixel::execute( + &state, + application::canvas::place_pixel::Command { + user_id: "user-1", + position: domain::Position::new(0, 0), + color: domain::Color::new(0xFF), + }, + ) + .unwrap(); + + application::soldiers::disconnect::execute(&state, "user-1"); + + // Reconnect with same ID — cooldown should be gone + application::soldiers::connect::execute(&state, "user-1".into()); + let result = application::canvas::place_pixel::execute( + &state, + application::canvas::place_pixel::Command { + user_id: "user-1", + position: domain::Position::new(1, 1), + color: domain::Color::new(0xAA), + }, + ) + .unwrap(); + + assert!(matches!( + result, + application::canvas::place_pixel::Outcome::Placed(_) + )); +} diff --git a/crates/config/Cargo.toml b/crates/config/Cargo.toml new file mode 100644 index 0000000..66d1f82 --- /dev/null +++ b/crates/config/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "config" +version.workspace = true +edition.workspace = true + +[dependencies] +thiserror = { workspace = true } diff --git a/crates/config/src/lib.rs b/crates/config/src/lib.rs new file mode 100644 index 0000000..79bd31e --- /dev/null +++ b/crates/config/src/lib.rs @@ -0,0 +1,61 @@ +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum ConfigError { + #[error("invalid value for '{field}': {reason}")] + InvalidValue { field: String, reason: String }, + + #[error("failed to load config: {0}")] + LoadFailed(String), +} + +#[derive(Debug, Clone)] +pub struct AppConfig { + pub server: ServerConfig, + pub canvas: CanvasConfig, + pub cooldown: CooldownConfig, + pub rate_limit: RateLimitConfig, + pub broadcast: BroadcastConfig, + pub snapshot: SnapshotConfig, +} + +#[derive(Debug, Clone)] +pub struct ServerConfig { + pub address: String, + pub port: u16, + pub enable_cors: bool, +} + +#[derive(Debug, Clone)] +pub struct CanvasConfig { + pub width: u32, + pub height: u32, +} + +#[derive(Debug, Clone)] +pub struct CooldownConfig { + pub placement_secs: u64, +} + +#[derive(Debug, Clone)] +pub struct RateLimitConfig { + pub burst_size: u32, + pub per_second: u64, +} + +#[derive(Debug, Clone)] +pub struct BroadcastConfig { + pub channel_capacity: usize, +} + +#[derive(Debug, Clone)] +pub struct SnapshotConfig { + pub enabled: bool, + pub interval_secs: u64, + pub max_snapshots: usize, + pub directory: String, +} + +pub trait ConfigSource { + fn load(&self) -> Result; +} diff --git a/crates/domain/Cargo.toml b/crates/domain/Cargo.toml new file mode 100644 index 0000000..94e5d6d --- /dev/null +++ b/crates/domain/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "domain" +version.workspace = true +edition.workspace = true + +[dependencies] +thiserror = { workspace = true } diff --git a/crates/domain/src/canvas.rs b/crates/domain/src/canvas.rs new file mode 100644 index 0000000..5ce9018 --- /dev/null +++ b/crates/domain/src/canvas.rs @@ -0,0 +1,57 @@ +use crate::{Color, DomainError, PixelUpdate, Position}; + +pub struct Canvas { + pixels: Vec, + width: u32, + height: u32, +} + +impl Canvas { + pub fn new(width: u32, height: u32) -> Self { + Self { + pixels: vec![Color::white(); (width * height) as usize], + width, + height, + } + } + + pub fn from_pixels(width: u32, height: u32, pixels: Vec) -> Result { + let expected = (width * height) as usize; + if pixels.len() != expected { + return Err(DomainError::InvalidCanvasData { + expected_width: width, + expected_height: height, + actual: pixels.len(), + }); + } + Ok(Self { + pixels, + width, + height, + }) + } + + pub fn place_pixel( + &mut self, + position: Position, + color: Color, + ) -> Result { + if position.x() >= self.width || position.y() >= self.height { + return Err(DomainError::PixelOutOfBounds(position)); + } + self.pixels[(position.y() * self.width + position.x()) as usize] = color; + Ok(PixelUpdate::new(position, color)) + } + + pub fn pixels(&self) -> &[Color] { + &self.pixels + } + + pub fn width(&self) -> u32 { + self.width + } + + pub fn height(&self) -> u32 { + self.height + } +} diff --git a/crates/domain/src/errors.rs b/crates/domain/src/errors.rs new file mode 100644 index 0000000..ed5dab9 --- /dev/null +++ b/crates/domain/src/errors.rs @@ -0,0 +1,21 @@ +use thiserror::Error; + +use crate::Position; + +#[derive(Debug, Error)] +pub enum DomainError { + #[error("pixel position {0} is out of bounds")] + PixelOutOfBounds(Position), + + #[error( + "invalid canvas dimensions: expected {expected_width}x{expected_height}, got {actual} pixels" + )] + InvalidCanvasData { + expected_width: u32, + expected_height: u32, + actual: usize, + }, + + #[error("persistence error: {0}")] + Persistence(String), +} diff --git a/crates/domain/src/events.rs b/crates/domain/src/events.rs new file mode 100644 index 0000000..1633da9 --- /dev/null +++ b/crates/domain/src/events.rs @@ -0,0 +1,7 @@ +use crate::PixelUpdate; + +#[derive(Debug, Clone, Copy)] +pub enum BroadcastEvent { + PixelUpdated(PixelUpdate), + SoldierCountChanged(usize), +} diff --git a/crates/domain/src/lib.rs b/crates/domain/src/lib.rs new file mode 100644 index 0000000..f4fac02 --- /dev/null +++ b/crates/domain/src/lib.rs @@ -0,0 +1,13 @@ +pub mod canvas; +pub mod errors; +pub mod events; +pub mod ports; +pub mod value_objects; + +pub use canvas::Canvas; +pub use errors::DomainError; +pub use events::BroadcastEvent; +pub use ports::BroadcastSubscription; +pub use value_objects::{Color, PixelUpdate, Position}; + +pub const COOLDOWN_MESSAGE: &str = "You can only place one pixel per minute"; diff --git a/crates/domain/src/ports.rs b/crates/domain/src/ports.rs new file mode 100644 index 0000000..aafa93c --- /dev/null +++ b/crates/domain/src/ports.rs @@ -0,0 +1,39 @@ +use std::future::Future; +use std::pin::Pin; +use std::sync::Arc; + +use crate::{BroadcastEvent, Color, DomainError, Position}; + +pub trait CanvasStore: Send + Sync { + fn pixels(&self) -> Arc<[Color]>; + fn place_pixel(&self, position: Position, color: Color) -> Result<(), DomainError>; + fn restore(&self, pixels: Vec) -> Result<(), DomainError>; +} + +pub trait CanvasPersistence: Send + Sync { + fn save(&self, pixels: &[Color]) -> Result<(), DomainError>; + fn load_latest(&self) -> Result>, DomainError>; +} + +pub trait EventBroadcaster: Send + Sync { + fn publish(&self, event: BroadcastEvent); + fn subscribe(&self) -> BroadcastSubscription; +} + +pub trait BroadcastReceiverInner: Send { + fn recv_boxed(&mut self) -> Pin> + Send + '_>>; +} + +pub struct BroadcastSubscription { + inner: Box, +} + +impl BroadcastSubscription { + pub fn new(inner: Box) -> Self { + Self { inner } + } + + pub async fn recv(&mut self) -> Option { + self.inner.recv_boxed().await + } +} diff --git a/crates/domain/src/value_objects.rs b/crates/domain/src/value_objects.rs new file mode 100644 index 0000000..603c72c --- /dev/null +++ b/crates/domain/src/value_objects.rs @@ -0,0 +1,76 @@ +use std::fmt; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(transparent)] +pub struct Color(u32); + +impl Color { + pub fn new(value: u32) -> Self { + Self(value) + } + + pub fn as_u32(self) -> u32 { + self.0 + } + + pub fn white() -> Self { + Self(0xFFFFFFFF) + } + + pub fn collect_as_u32(colors: &[Color]) -> Vec { + colors.iter().map(|color| color.as_u32()).collect() + } + + pub fn collect_as_bytes(colors: &[Color]) -> Vec { + colors + .iter() + .flat_map(|color| color.as_u32().to_ne_bytes()) + .collect() + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct Position { + x: u32, + y: u32, +} + +impl Position { + pub fn new(x: u32, y: u32) -> Self { + Self { x, y } + } + + pub fn x(self) -> u32 { + self.x + } + + pub fn y(self) -> u32 { + self.y + } +} + +impl fmt::Display for Position { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "({}, {})", self.x, self.y) + } +} + +#[derive(Debug, Clone, Copy)] +pub struct PixelUpdate { + position: Position, + color: Color, +} + +impl PixelUpdate { + pub fn new(position: Position, color: Color) -> Self { + Self { position, color } + } + + pub fn position(self) -> Position { + self.position + } + + pub fn color(self) -> Color { + self.color + } +} diff --git a/crates/domain/tests/canvas.rs b/crates/domain/tests/canvas.rs new file mode 100644 index 0000000..aa0b324 --- /dev/null +++ b/crates/domain/tests/canvas.rs @@ -0,0 +1,125 @@ +use domain::{Canvas, Color, DomainError, Position}; + +macro_rules! pos { + ($x:expr, $y:expr) => { + Position::new($x, $y) + }; +} + +macro_rules! color { + ($v:expr) => { + Color::new($v) + }; +} + +macro_rules! assert_pixel { + ($canvas:expr, $x:expr, $y:expr, $expected:expr) => {{ + let (x, y): (u32, u32) = ($x, $y); + let idx = y as usize * $canvas.width() as usize + x as usize; + let expected = color!($expected); + assert_eq!($canvas.pixels()[idx], expected, "pixel at ({x}, {y})"); + }}; +} + +fn small_canvas() -> Canvas { + Canvas::new(10, 10) +} + +#[test] +fn new_canvas_is_all_white() { + let canvas = small_canvas(); + assert_eq!(canvas.pixels().len(), 100); + assert!(canvas.pixels().iter().all(|&c| c == Color::white())); +} + +#[test] +fn dimensions_match_construction() { + let canvas = Canvas::new(42, 17); + assert_eq!(canvas.width(), 42); + assert_eq!(canvas.height(), 17); + assert_eq!(canvas.pixels().len(), 42 * 17); +} + +#[test] +fn place_pixel_updates_correct_position() { + let mut canvas = small_canvas(); + let update = canvas.place_pixel(pos!(3, 4), color!(0xFF0000)).unwrap(); + + assert_pixel!(canvas, 3, 4, 0xFF0000); + assert_eq!(update.position(), pos!(3, 4)); + assert_eq!(update.color(), color!(0xFF0000)); +} + +#[test] +fn place_pixel_does_not_affect_neighbors() { + let mut canvas = small_canvas(); + canvas.place_pixel(pos!(5, 5), color!(0xFF)).unwrap(); + + for (x, y) in [(4, 5), (6, 5), (5, 4), (5, 6)] { + assert_pixel!(canvas, x, y, 0xFFFFFFFF); + } +} + +#[test] +fn place_pixel_overwrites_previous() { + let mut canvas = small_canvas(); + canvas.place_pixel(pos!(0, 0), color!(0xAA)).unwrap(); + canvas.place_pixel(pos!(0, 0), color!(0xBB)).unwrap(); + assert_pixel!(canvas, 0, 0, 0xBB); +} + +#[test] +fn place_pixel_at_boundary() { + let mut canvas = small_canvas(); + assert!(canvas.place_pixel(pos!(9, 9), color!(0xFF)).is_ok()); + assert!(canvas.place_pixel(pos!(0, 0), color!(0xFF)).is_ok()); + assert!(canvas.place_pixel(pos!(9, 0), color!(0xFF)).is_ok()); + assert!(canvas.place_pixel(pos!(0, 9), color!(0xFF)).is_ok()); +} + +#[test] +fn place_pixel_out_of_bounds() { + let mut canvas = small_canvas(); + + for (x, y) in [(10, 0), (0, 10), (10, 10), (100, 100)] { + let result = canvas.place_pixel(pos!(x, y), color!(0xFF)); + assert!( + matches!(result, Err(DomainError::PixelOutOfBounds(_))), + "({x}, {y}) should be out of bounds" + ); + } +} + +#[test] +fn from_pixels_with_correct_size() { + let pixels = vec![color!(0xAA); 25]; + let canvas = Canvas::from_pixels(5, 5, pixels).unwrap(); + assert_eq!(canvas.width(), 5); + assert_eq!(canvas.height(), 5); + assert!(canvas.pixels().iter().all(|&c| c == color!(0xAA))); +} + +#[test] +fn from_pixels_with_wrong_size() { + let too_few = vec![color!(0); 10]; + let too_many = vec![color!(0); 30]; + + for pixels in [too_few, too_many] { + assert!( + matches!( + Canvas::from_pixels(5, 5, pixels), + Err(DomainError::InvalidCanvasData { .. }) + ), + "should reject pixel vec that doesn't match dimensions" + ); + } +} + +#[test] +fn from_pixels_preserves_content() { + let mut pixels = vec![Color::white(); 9]; + pixels[4] = color!(0xFF0000); // center pixel of 3x3 + let canvas = Canvas::from_pixels(3, 3, pixels).unwrap(); + assert_pixel!(canvas, 1, 1, 0xFF0000); + assert_pixel!(canvas, 0, 0, 0xFFFFFFFF); +} diff --git a/crates/domain/tests/value_objects.rs b/crates/domain/tests/value_objects.rs new file mode 100644 index 0000000..2739050 --- /dev/null +++ b/crates/domain/tests/value_objects.rs @@ -0,0 +1,69 @@ +use domain::{Color, PixelUpdate, Position}; + +#[test] +fn color_roundtrips_through_u32() { + for value in [0, 0xFF, 0xFF0000, 0xFFFFFFFF, 0xDEADBEEF] { + assert_eq!(Color::new(value).as_u32(), value); + } +} + +#[test] +fn color_white_is_full_alpha() { + assert_eq!(Color::white().as_u32(), 0xFFFFFFFF); +} + +#[test] +fn color_equality() { + assert_eq!(Color::new(42), Color::new(42)); + assert_ne!(Color::new(1), Color::new(2)); +} + +#[test] +fn collect_as_u32_preserves_values() { + let colors = [Color::new(1), Color::new(2), Color::new(3)]; + assert_eq!(Color::collect_as_u32(&colors), vec![1, 2, 3]); +} + +#[test] +fn collect_as_bytes_length() { + let colors = vec![Color::white(); 10]; + assert_eq!(Color::collect_as_bytes(&colors).len(), 40); +} + +#[test] +fn collect_as_bytes_roundtrips() { + let original = vec![Color::new(0x01020304), Color::new(0xAABBCCDD)]; + let bytes = Color::collect_as_bytes(&original); + let restored: Vec = bytes + .chunks_exact(4) + .map(|c| Color::new(u32::from_ne_bytes([c[0], c[1], c[2], c[3]]))) + .collect(); + assert_eq!(original, restored); +} + +#[test] +fn position_accessors() { + let pos = Position::new(42, 17); + assert_eq!(pos.x(), 42); + assert_eq!(pos.y(), 17); +} + +#[test] +fn position_display() { + assert_eq!(Position::new(3, 7).to_string(), "(3, 7)"); +} + +#[test] +fn position_equality() { + assert_eq!(Position::new(1, 2), Position::new(1, 2)); + assert_ne!(Position::new(1, 2), Position::new(2, 1)); +} + +#[test] +fn pixel_update_carries_position_and_color() { + let pos = Position::new(5, 10); + let color = Color::new(0xFF00FF); + let update = PixelUpdate::new(pos, color); + assert_eq!(update.position(), pos); + assert_eq!(update.color(), color); +} diff --git a/crates/server/Cargo.toml b/crates/server/Cargo.toml new file mode 100644 index 0000000..d08710e --- /dev/null +++ b/crates/server/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "server" +version.workspace = true +edition.workspace = true + +[features] +default = ["socketio"] +socketio = ["dep:socketio", "dep:socketioxide"] +websocket = ["dep:websocket"] + +[dependencies] +application = { workspace = true } +canvas-file = { workspace = true } +config = { workspace = true } +config-env = { workspace = true } +axum = { workspace = true } +domain = { workspace = true } +http-axum = { workspace = true } +dotenv = { workspace = true } +tokio = { workspace = true } +tracing = { workspace = true } +tracing-subscriber = { workspace = true } + +socketio = { workspace = true, optional = true } +socketioxide = { workspace = true, optional = true } +websocket = { workspace = true, optional = true } diff --git a/crates/server/src/main.rs b/crates/server/src/main.rs new file mode 100644 index 0000000..a45b014 --- /dev/null +++ b/crates/server/src/main.rs @@ -0,0 +1,133 @@ +#[cfg(not(any(feature = "socketio", feature = "websocket")))] +compile_error!("Enable either the `socketio` or `websocket` feature"); + +use std::net::SocketAddr; +use std::sync::Arc; +use std::time::Duration; + +use application::{AppState, InMemoryCanvasStore, InProcessBroadcaster}; +use canvas_file::FileCanvasPersistence; +use config::{AppConfig, ConfigSource}; +use config_env::EnvConfigSource; +use domain::BroadcastEvent; +use tokio::signal; +use tokio::sync::broadcast; +use tracing::{error, info, warn}; +use tracing_subscriber::FmtSubscriber; + +#[tokio::main] +async fn main() -> Result<(), Box> { + dotenv::dotenv().ok(); + tracing::subscriber::set_global_default(FmtSubscriber::new())?; + + let config = EnvConfigSource.load()?; + let state = build_state(&config)?; + + if config.snapshot.enabled { + if let Err(err) = application::canvas::restore_snapshot::execute(&state) { + warn!("Failed to restore canvas snapshot: {err}"); + } + spawn_snapshot_scheduler(state.clone(), config.snapshot.interval_secs); + } + + let app = build_app(state.clone(), &config)?; + + let server_address = format!("{}:{}", config.server.address, config.server.port); + info!("Starting server on {server_address}"); + + let listener = tokio::net::TcpListener::bind(server_address).await?; + axum::serve( + listener, + app.into_make_service_with_connect_info::(), + ) + .with_graceful_shutdown(shutdown_signal()) + .await?; + + info!("Shutting down gracefully..."); + + if config.snapshot.enabled { + info!("Saving final canvas snapshot..."); + if let Err(err) = application::canvas::save_snapshot::execute(&state) { + error!("Failed to save final snapshot: {err}"); + } + } + + info!("Server stopped"); + Ok(()) +} + +async fn shutdown_signal() { + let ctrl_c = async { + signal::ctrl_c() + .await + .expect("Failed to install Ctrl+C handler"); + }; + + #[cfg(unix)] + let terminate = async { + signal::unix::signal(signal::unix::SignalKind::terminate()) + .expect("Failed to install SIGTERM handler") + .recv() + .await; + }; + + #[cfg(not(unix))] + let terminate = std::future::pending::<()>(); + + tokio::select! { + () = ctrl_c => info!("Received Ctrl+C"), + () = terminate => info!("Received SIGTERM"), + } +} + +fn build_state(config: &AppConfig) -> Result, Box> { + let (broadcast_tx, _) = broadcast::channel::(config.broadcast.channel_capacity); + + let canvas_store = InMemoryCanvasStore::new(config.canvas.width, config.canvas.height); + let broadcaster = InProcessBroadcaster::new(broadcast_tx); + let cooldown = Duration::from_secs(config.cooldown.placement_secs); + + let mut state = AppState::new(Box::new(canvas_store), Box::new(broadcaster), cooldown); + + if config.snapshot.enabled { + let persistence = FileCanvasPersistence::new(&config.snapshot)?; + state = state.with_persistence(Box::new(persistence)); + } + + Ok(Arc::new(state)) +} + +fn spawn_snapshot_scheduler(state: Arc, interval_secs: u64) { + let interval = Duration::from_secs(interval_secs); + info!("Snapshot scheduler started (every {interval_secs}s)"); + + tokio::spawn(async move { + loop { + tokio::time::sleep(interval).await; + if let Err(err) = application::canvas::save_snapshot::execute(&state) { + error!("Failed to save canvas snapshot: {err}"); + } + } + }); +} + +#[cfg(feature = "socketio")] +fn build_app( + state: Arc, + config: &AppConfig, +) -> Result> { + let (layer, io) = socketioxide::SocketIo::new_layer(); + socketio::setup_namespaces(&io, state); + let router = http_axum::build_router(config.server.enable_cors, &config.rate_limit)?; + Ok(router.layer(layer)) +} + +#[cfg(feature = "websocket")] +fn build_app( + state: Arc, + config: &AppConfig, +) -> Result> { + let ws_router = websocket::build_router(state); + let http_router = http_axum::build_router(config.server.enable_cors, &config.rate_limit)?; + Ok(ws_router.merge(http_router)) +} diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 0000000..0ba3426 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +set -euo pipefail + +REGISTRY="registry.gabrielkaszewski.dev" +REPO="painter" + +tag="latest" + +while [[ $# -gt 0 ]]; do + case $1 in + --tag) tag="$2"; shift 2 ;; + *) echo "usage: $0 [--tag T]" >&2; exit 1 ;; + esac +done + +image="${REGISTRY}/${REPO}:${tag}" + +echo "building ${image}" +docker buildx build --platform linux/amd64 \ + -t "$image" --push . +echo "pushed $image" diff --git a/painter-js/bun.lock b/painter-js/bun.lock new file mode 100644 index 0000000..cd2c5ff --- /dev/null +++ b/painter-js/bun.lock @@ -0,0 +1,315 @@ +{ + "lockfileVersion": 1, + "configVersion": 1, + "workspaces": { + "": { + "name": "painter-js", + "dependencies": { + "socket.io-client": "^4.7.5", + }, + "devDependencies": { + "autoprefixer": "^10.4.19", + "postcss": "^8.4.38", + "prettier": "^3.9.6", + "tailwindcss": "^3.4.3", + "typescript": "^5.2.2", + "vite": "^5.2.0", + }, + }, + }, + "packages": { + "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], + + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="], + + "@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="], + + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="], + + "@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="], + + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="], + + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="], + + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="], + + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="], + + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="], + + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="], + + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="], + + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="], + + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="], + + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="], + + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="], + + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="], + + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="], + + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="], + + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="], + + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="], + + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="], + + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="], + + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="], + + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], + + "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], + + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + + "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + + "@napi-rs/lzma-linux-x64-gnu": ["@napi-rs/lzma-linux-x64-gnu@1.5.1", "", { "os": "linux", "cpu": "x64" }, "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ=="], + + "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], + + "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], + + "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], + + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.62.4", "", { "os": "android", "cpu": "arm" }, "sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg=="], + + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.62.4", "", { "os": "android", "cpu": "arm64" }, "sha512-JKuJc+pnpks2pjy7L/N3v/cAkZxYlnmuZoD840ldbMI5KDbC4iO9NKwPKYdjYFCMAIIlBzYSFHxIJVYzRo2/8A=="], + + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.62.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-krw5uS2STmvJ02x0uTXHbqQNuz+9eZ1iw+qXk9dmW2gvV4jV7O2hEoOnuhFrpOPiel1mBFtqbxYZZtC46hXLOw=="], + + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.62.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-wsTxtgApb4PrOsNJIm0FZ1h3WvCC+k9uxLJ4ad75hgoS4NiRes2SoJFlDAyMwiUY8IssDqGcHbXuN0sx1tfF1A=="], + + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.62.4", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-GUOnQlyZe3yAXhWOtOMsn5Qkrv5E5mZXa0thbARWi5Ei2szlVXJFQhddZ4HbAzh8q92w5twp+CQvs/eFanz9YQ=="], + + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.62.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-/Y7f3QuxjzPKsjA/rfEDa3+0vXqyjmJ50Ln8dPpCmWkKTrUoWHG1cWhTqaAMLob2m2nESWuC7yGrREz019Ztqg=="], + + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.62.4", "", { "os": "linux", "cpu": "arm" }, "sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA=="], + + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.62.4", "", { "os": "linux", "cpu": "arm" }, "sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ=="], + + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.62.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ=="], + + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.62.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g=="], + + "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.62.4", "", { "os": "linux", "cpu": "none" }, "sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA=="], + + "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.62.4", "", { "os": "linux", "cpu": "none" }, "sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ=="], + + "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.62.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w=="], + + "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.62.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w=="], + + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.62.4", "", { "os": "linux", "cpu": "none" }, "sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ=="], + + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.62.4", "", { "os": "linux", "cpu": "none" }, "sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA=="], + + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.62.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA=="], + + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.62.4", "", { "os": "linux", "cpu": "x64" }, "sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw=="], + + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.62.4", "", { "os": "linux", "cpu": "x64" }, "sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA=="], + + "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.62.4", "", { "os": "openbsd", "cpu": "x64" }, "sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ=="], + + "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.62.4", "", { "os": "none", "cpu": "arm64" }, "sha512-s62SQ/vgsRSvMwDkOEfTqfgASF0f26ZNaQuTA6Aok5lrikf89yI2W0gFHvZb2Jpgc6N8JnOKZgCK2iciO3CsxQ=="], + + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.62.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-J6wGf8TVGbXJq+HH+ttTvrcfNKPbuZecV6KT1B8I18BC5IURUh5kl4Yl5OEP5eFIUoI5BWxCsyYMhFsDx8kekw=="], + + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.62.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-zmfrQd/0wu6oJs8Vq8KwY/YtsKSsLtKe/HwAP4Wqy8LhWjeT55fHRAkOhYQ12wI3ayS4Tt12d5CDRD7N96SAYQ=="], + + "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.62.4", "", { "os": "win32", "cpu": "x64" }, "sha512-qPzHqdj9rfUD+w79dtE07zi/kFwKyCJqplp5K5ygeLTp7jLpAoc16OAH39HSmRC9UpozaecsleI8uAdEj6v2yw=="], + + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.62.4", "", { "os": "win32", "cpu": "x64" }, "sha512-zD6NdeWEByGE9QF9vCrlJ5YQB4oq9q91kPZS37Jwj5hOkvR1lTBSpsKhKDw4IJtbQ35LsTS1HD9DZYGKIshU1Q=="], + + "@socket.io/component-emitter": ["@socket.io/component-emitter@3.1.2", "", {}, "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA=="], + + "@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="], + + "any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="], + + "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], + + "arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="], + + "autoprefixer": ["autoprefixer@10.5.4", "", { "dependencies": { "browserslist": "^4.28.6", "caniuse-lite": "^1.0.30001806", "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-MaU0U/za7N3r6brxD4YB/l4NSrFzLPlANv6wEuQVaIPlD3L4W9rFcQPbL/EilY9BHhHvhfcz3gInDLrEtWT4EA=="], + + "baseline-browser-mapping": ["baseline-browser-mapping@2.11.15", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-FwMjJJ7HnyZpWe+oWxegG0fezZyBZUagI5LZEoO3GCbtbKNwRfMH9Ue5d5v01PNePBy1QSfPSDTTeVL0Hb9EzA=="], + + "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], + + "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], + + "browserslist": ["browserslist@4.28.8", "", { "dependencies": { "baseline-browser-mapping": "^2.11.12", "caniuse-lite": "^1.0.30001809", "electron-to-chromium": "^1.5.402", "node-releases": "^2.0.53", "update-browserslist-db": "^1.3.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA=="], + + "camelcase-css": ["camelcase-css@2.0.1", "", {}, "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="], + + "caniuse-lite": ["caniuse-lite@1.0.30001809", "", {}, "sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ=="], + + "chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], + + "commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], + + "cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], + + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "didyoumean": ["didyoumean@1.2.2", "", {}, "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="], + + "dlv": ["dlv@1.1.3", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="], + + "electron-to-chromium": ["electron-to-chromium@1.5.408", "", {}, "sha512-SLoprcYpJ/OH2v2ps0+N5biv9H4/KBT3+YmmDew64TwK5y9j2wv7pMOFY7IorVkyMtEyLSCRlXKLsNlakeAlPw=="], + + "engine.io-client": ["engine.io-client@6.6.6", "", { "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.4.1", "engine.io-parser": "~5.2.1", "ws": "~8.21.0", "xmlhttprequest-ssl": "~2.1.1" } }, "sha512-iY6QdftLQ9pyiPoX082bpf/u1UewnOaJrtJIF9T0++QB34lZrj0uP+Q/bj8AlUsAxqhnkTV2BS8SBZSxOmoV5Q=="], + + "engine.io-parser": ["engine.io-parser@5.2.3", "", {}, "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q=="], + + "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], + + "esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="], + + "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + + "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], + + "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="], + + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + + "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], + + "fraction.js": ["fraction.js@5.3.4", "", {}, "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ=="], + + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + + "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], + + "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], + + "hasown": ["hasown@2.0.4", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="], + + "is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="], + + "is-core-module": ["is-core-module@2.16.2", "", { "dependencies": { "hasown": "^2.0.3" } }, "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA=="], + + "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], + + "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], + + "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], + + "jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="], + + "lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="], + + "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], + + "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], + + "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="], + + "nanoid": ["nanoid@3.3.18", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w=="], + + "node-releases": ["node-releases@2.0.53", "", {}, "sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ=="], + + "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], + + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], + + "object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="], + + "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], + + "pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="], + + "pirates": ["pirates@4.0.7", "", {}, "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA=="], + + "postcss": ["postcss@8.5.26", "", { "dependencies": { "nanoid": "^3.3.17", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ=="], + + "postcss-import": ["postcss-import@15.1.0", "", { "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", "resolve": "^1.1.7" }, "peerDependencies": { "postcss": "^8.0.0" } }, "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew=="], + + "postcss-js": ["postcss-js@4.1.0", "", { "dependencies": { "camelcase-css": "^2.0.1" }, "peerDependencies": { "postcss": "^8.4.21" } }, "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw=="], + + "postcss-load-config": ["postcss-load-config@6.0.1", "", { "dependencies": { "lilconfig": "^3.1.1" }, "peerDependencies": { "jiti": ">=1.21.0", "postcss": ">=8.0.9", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["jiti", "postcss", "tsx", "yaml"] }, "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g=="], + + "postcss-nested": ["postcss-nested@6.2.0", "", { "dependencies": { "postcss-selector-parser": "^6.1.1" }, "peerDependencies": { "postcss": "^8.2.14" } }, "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ=="], + + "postcss-selector-parser": ["postcss-selector-parser@6.1.4", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ=="], + + "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], + + "prettier": ["prettier@3.9.6", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g=="], + + "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], + + "read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="], + + "readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], + + "resolve": ["resolve@1.22.12", "", { "dependencies": { "es-errors": "^1.3.0", "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA=="], + + "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], + + "rollup": ["rollup@4.62.4", "", { "dependencies": { "@types/estree": "1.0.9" }, "optionalDependencies": { "@napi-rs/lzma-linux-x64-gnu": "1.5.1", "@rollup/rollup-android-arm-eabi": "4.62.4", "@rollup/rollup-android-arm64": "4.62.4", "@rollup/rollup-darwin-arm64": "4.62.4", "@rollup/rollup-darwin-x64": "4.62.4", "@rollup/rollup-freebsd-arm64": "4.62.4", "@rollup/rollup-freebsd-x64": "4.62.4", "@rollup/rollup-linux-arm-gnueabihf": "4.62.4", "@rollup/rollup-linux-arm-musleabihf": "4.62.4", "@rollup/rollup-linux-arm64-gnu": "4.62.4", "@rollup/rollup-linux-arm64-musl": "4.62.4", "@rollup/rollup-linux-loong64-gnu": "4.62.4", "@rollup/rollup-linux-loong64-musl": "4.62.4", "@rollup/rollup-linux-ppc64-gnu": "4.62.4", "@rollup/rollup-linux-ppc64-musl": "4.62.4", "@rollup/rollup-linux-riscv64-gnu": "4.62.4", "@rollup/rollup-linux-riscv64-musl": "4.62.4", "@rollup/rollup-linux-s390x-gnu": "4.62.4", "@rollup/rollup-linux-x64-gnu": "4.62.4", "@rollup/rollup-linux-x64-musl": "4.62.4", "@rollup/rollup-openbsd-x64": "4.62.4", "@rollup/rollup-openharmony-arm64": "4.62.4", "@rollup/rollup-win32-arm64-msvc": "4.62.4", "@rollup/rollup-win32-ia32-msvc": "4.62.4", "@rollup/rollup-win32-x64-gnu": "4.62.4", "@rollup/rollup-win32-x64-msvc": "4.62.4", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-RXOqwaPsBGjMNMa4sQjDjHieHEZDFoj/Rdr46l2MU5DfEs16wHJPC2RPTPHWhNl+M3aI472LLqFkFKut4SblOg=="], + + "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], + + "socket.io-client": ["socket.io-client@4.8.3", "", { "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.4.1", "engine.io-client": "~6.6.1", "socket.io-parser": "~4.2.4" } }, "sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g=="], + + "socket.io-parser": ["socket.io-parser@4.2.7", "", { "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.4.1" } }, "sha512-IH/iSeO9T6gz1KkFleGDWkG9N3dl4jXVYUtMhIqH10Md0ttMer8nUNWiP1DKuNrybD2xBrixLJdCC9J6ECoYkg=="], + + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + + "sucrase": ["sucrase@3.35.1", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "tinyglobby": "^0.2.11", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw=="], + + "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], + + "tailwindcss": ["tailwindcss@3.4.19", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", "chokidar": "^3.6.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "jiti": "^1.21.7", "lilconfig": "^3.1.3", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.1.1", "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", "postcss-nested": "^6.2.0", "postcss-selector-parser": "^6.1.2", "resolve": "^1.22.8", "sucrase": "^3.35.0" }, "bin": { "tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js" } }, "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ=="], + + "thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="], + + "thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="], + + "tinyglobby": ["tinyglobby@0.2.17", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="], + + "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], + + "ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="], + + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + + "update-browserslist-db": ["update-browserslist-db@1.3.1", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ=="], + + "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + + "vite": ["vite@5.4.21", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": { "vite": "bin/vite.js" } }, "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw=="], + + "ws": ["ws@8.21.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw=="], + + "xmlhttprequest-ssl": ["xmlhttprequest-ssl@2.1.2", "", {}, "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ=="], + + "chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + + "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + + "tinyglobby/picomatch": ["picomatch@4.0.5", "", {}, "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A=="], + } +} diff --git a/painter-js/index.html b/painter-js/index.html index ab2608c..c9652f1 100644 --- a/painter-js/index.html +++ b/painter-js/index.html @@ -1,44 +1,126 @@ - + - - Pixel War + + Painter + + + + + + + + + + + + + - -
-
- - - - - - - - - - - - + +
+
+ + + + + + + + + + + +
-

Your selected color COLOR

-
You can place a pixel now
-
- - - +

+ Your selected color + COLOR +

+
You can place a pixel now
+
+ + 1.0x + + +

-
-

+
+
-
- -
-
-

Current soldiers: 0

- +
+

+ Soldiers: 0 +

+
diff --git a/painter-js/package-lock.json b/painter-js/package-lock.json deleted file mode 100644 index 702b221..0000000 --- a/painter-js/package-lock.json +++ /dev/null @@ -1,917 +0,0 @@ -{ - "name": "painter-js", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "painter-js", - "version": "0.0.0", - "dependencies": { - "socket.io-client": "^4.7.5" - }, - "devDependencies": { - "typescript": "^5.2.2", - "vite": "^5.2.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", - "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", - "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", - "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", - "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", - "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", - "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", - "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", - "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", - "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", - "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", - "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", - "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", - "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", - "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", - "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", - "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@socket.io/component-emitter": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", - "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==" - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/engine.io-client": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz", - "integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1", - "engine.io-parser": "~5.2.1", - "ws": "~8.11.0", - "xmlhttprequest-ssl": "~2.0.0" - } - }, - "node_modules/engine.io-parser": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", - "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/rollup": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", - "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", - "dev": true, - "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.17.2", - "@rollup/rollup-android-arm64": "4.17.2", - "@rollup/rollup-darwin-arm64": "4.17.2", - "@rollup/rollup-darwin-x64": "4.17.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", - "@rollup/rollup-linux-arm-musleabihf": "4.17.2", - "@rollup/rollup-linux-arm64-gnu": "4.17.2", - "@rollup/rollup-linux-arm64-musl": "4.17.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", - "@rollup/rollup-linux-riscv64-gnu": "4.17.2", - "@rollup/rollup-linux-s390x-gnu": "4.17.2", - "@rollup/rollup-linux-x64-gnu": "4.17.2", - "@rollup/rollup-linux-x64-musl": "4.17.2", - "@rollup/rollup-win32-arm64-msvc": "4.17.2", - "@rollup/rollup-win32-ia32-msvc": "4.17.2", - "@rollup/rollup-win32-x64-msvc": "4.17.2", - "fsevents": "~2.3.2" - } - }, - "node_modules/socket.io-client": { - "version": "4.7.5", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.5.tgz", - "integrity": "sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.2", - "engine.io-client": "~6.5.2", - "socket.io-parser": "~4.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/socket.io-parser": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", - "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/vite": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", - "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==", - "dev": true, - "dependencies": { - "esbuild": "^0.20.1", - "postcss": "^8.4.38", - "rollup": "^4.13.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xmlhttprequest-ssl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", - "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", - "engines": { - "node": ">=0.4.0" - } - } - } -} diff --git a/painter-js/package.json b/painter-js/package.json index 3688d4a..921d031 100644 --- a/painter-js/package.json +++ b/painter-js/package.json @@ -6,17 +6,19 @@ "scripts": { "dev": "vite", "build": "tsc && vite build", - "preview": "vite preview" + "preview": "vite preview", + "fmt": "prettier --write 'src/**/*.{js,ts,css,html}'", + "fmt:check": "prettier --check 'src/**/*.{js,ts,css,html}'" }, "devDependencies": { "autoprefixer": "^10.4.19", "postcss": "^8.4.38", + "prettier": "^3.9.6", "tailwindcss": "^3.4.3", "typescript": "^5.2.2", "vite": "^5.2.0" }, "dependencies": { - "socket.io-client": "^4.7.5", - "three": "^0.164.1" + "socket.io-client": "^4.7.5" } } diff --git a/painter-js/pnpm-lock.yaml b/painter-js/pnpm-lock.yaml deleted file mode 100644 index 6819446..0000000 --- a/painter-js/pnpm-lock.yaml +++ /dev/null @@ -1,1466 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - socket.io-client: - specifier: ^4.7.5 - version: 4.7.5 - three: - specifier: ^0.164.1 - version: 0.164.1 - devDependencies: - autoprefixer: - specifier: ^10.4.19 - version: 10.4.19(postcss@8.4.38) - postcss: - specifier: ^8.4.38 - version: 8.4.38 - tailwindcss: - specifier: ^3.4.3 - version: 3.4.3 - typescript: - specifier: ^5.2.2 - version: 5.4.5 - vite: - specifier: ^5.2.0 - version: 5.2.11 - -packages: - - '@alloc/quick-lru@5.2.0': - resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} - engines: {node: '>=10'} - - '@esbuild/aix-ppc64@0.20.2': - resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.20.2': - resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.20.2': - resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.20.2': - resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.20.2': - resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.20.2': - resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.20.2': - resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.20.2': - resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.20.2': - resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.20.2': - resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.20.2': - resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.20.2': - resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.20.2': - resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.20.2': - resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.20.2': - resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.20.2': - resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.20.2': - resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-x64@0.20.2': - resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-x64@0.20.2': - resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/sunos-x64@0.20.2': - resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.20.2': - resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.20.2': - resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.20.2': - resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - - '@jridgewell/gen-mapping@0.3.5': - resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} - engines: {node: '>=6.0.0'} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.4.15': - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - - '@rollup/rollup-android-arm-eabi@4.17.2': - resolution: {integrity: sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.17.2': - resolution: {integrity: sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.17.2': - resolution: {integrity: sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.17.2': - resolution: {integrity: sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-linux-arm-gnueabihf@4.17.2': - resolution: {integrity: sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.17.2': - resolution: {integrity: sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.17.2': - resolution: {integrity: sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.17.2': - resolution: {integrity: sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-powerpc64le-gnu@4.17.2': - resolution: {integrity: sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.17.2': - resolution: {integrity: sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.17.2': - resolution: {integrity: sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.17.2': - resolution: {integrity: sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.17.2': - resolution: {integrity: sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-win32-arm64-msvc@4.17.2': - resolution: {integrity: sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.17.2': - resolution: {integrity: sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.17.2': - resolution: {integrity: sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==} - cpu: [x64] - os: [win32] - - '@socket.io/component-emitter@3.1.2': - resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} - - '@types/estree@1.0.5': - resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - - any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - - arg@5.0.2: - resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} - - autoprefixer@10.4.19: - resolution: {integrity: sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==} - engines: {node: ^10 || ^12 || >=14} - hasBin: true - peerDependencies: - postcss: ^8.1.0 - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - - braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} - engines: {node: '>=8'} - - browserslist@4.23.0: - resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - - camelcase-css@2.0.1: - resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} - engines: {node: '>= 6'} - - caniuse-lite@1.0.30001618: - resolution: {integrity: sha512-p407+D1tIkDvsEAPS22lJxLQQaG8OTBEqo0KhzfABGk0TU4juBNDSfH0hyAp/HRyx+M8L17z/ltyhxh27FTfQg==} - - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} - - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - - cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} - hasBin: true - - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - didyoumean@1.2.2: - resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} - - dlv@1.1.3: - resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} - - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - electron-to-chromium@1.4.767: - resolution: {integrity: sha512-nzzHfmQqBss7CE3apQHkHjXW77+8w3ubGCIoEijKCJebPufREaFETgGXWTkh32t259F3Kcq+R8MZdFdOJROgYw==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - engine.io-client@6.5.3: - resolution: {integrity: sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==} - - engine.io-parser@5.2.2: - resolution: {integrity: sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==} - engines: {node: '>=10.0.0'} - - esbuild@0.20.2: - resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} - engines: {node: '>=12'} - hasBin: true - - escalade@3.1.2: - resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} - engines: {node: '>=6'} - - fast-glob@3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} - engines: {node: '>=8.6.0'} - - fastq@1.17.1: - resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} - - fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} - engines: {node: '>=8'} - - foreground-child@3.1.1: - resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} - engines: {node: '>=14'} - - fraction.js@4.3.7: - resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - glob@10.3.15: - resolution: {integrity: sha512-0c6RlJt1TICLyvJYIApxb8GsXoai0KUP7AxKKAtsYXdgJR1mGEUa7DgwShbdk1nly0PYoZj01xd4hzbq3fsjpw==} - engines: {node: '>=16 || 14 >=14.18'} - hasBin: true - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - - is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - jackspeak@2.3.6: - resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} - engines: {node: '>=14'} - - jiti@1.21.0: - resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} - hasBin: true - - lilconfig@2.1.0: - resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} - engines: {node: '>=10'} - - lilconfig@3.1.1: - resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==} - engines: {node: '>=14'} - - lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - - lru-cache@10.2.2: - resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} - engines: {node: 14 || >=16.14} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} - - minimatch@9.0.4: - resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} - engines: {node: '>=16 || 14 >=14.17'} - - minipass@7.1.1: - resolution: {integrity: sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA==} - engines: {node: '>=16 || 14 >=14.17'} - - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - - mz@2.7.0: - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - - nanoid@3.3.7: - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - node-releases@2.0.14: - resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} - - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - - normalize-range@0.1.2: - resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} - engines: {node: '>=0.10.0'} - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - object-hash@3.0.0: - resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} - engines: {node: '>= 6'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - - picocolors@1.0.1: - resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - pify@2.3.0: - resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} - engines: {node: '>=0.10.0'} - - pirates@4.0.6: - resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} - engines: {node: '>= 6'} - - postcss-import@15.1.0: - resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} - engines: {node: '>=14.0.0'} - peerDependencies: - postcss: ^8.0.0 - - postcss-js@4.0.1: - resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} - engines: {node: ^12 || ^14 || >= 16} - peerDependencies: - postcss: ^8.4.21 - - postcss-load-config@4.0.2: - resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} - engines: {node: '>= 14'} - peerDependencies: - postcss: '>=8.0.9' - ts-node: '>=9.0.0' - peerDependenciesMeta: - postcss: - optional: true - ts-node: - optional: true - - postcss-nested@6.0.1: - resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} - engines: {node: '>=12.0'} - peerDependencies: - postcss: ^8.2.14 - - postcss-selector-parser@6.0.16: - resolution: {integrity: sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==} - engines: {node: '>=4'} - - postcss-value-parser@4.2.0: - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - - postcss@8.4.38: - resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} - engines: {node: ^10 || ^12 || >=14} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - read-cache@1.0.0: - resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} - - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - - resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} - hasBin: true - - reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - rollup@4.17.2: - resolution: {integrity: sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - socket.io-client@4.7.5: - resolution: {integrity: sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==} - engines: {node: '>=10.0.0'} - - socket.io-parser@4.2.4: - resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==} - engines: {node: '>=10.0.0'} - - source-map-js@1.2.0: - resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} - engines: {node: '>=0.10.0'} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - - sucrase@3.35.0: - resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - tailwindcss@3.4.3: - resolution: {integrity: sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==} - engines: {node: '>=14.0.0'} - hasBin: true - - thenify-all@1.6.0: - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} - engines: {node: '>=0.8'} - - thenify@3.3.1: - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - - three@0.164.1: - resolution: {integrity: sha512-iC/hUBbl1vzFny7f5GtqzVXYjMJKaTPxiCxXfrvVdBi1Sf+jhd1CAkitiFwC7mIBFCo3MrDLJG97yisoaWig0w==} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - ts-interface-checker@0.1.13: - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - - typescript@5.4.5: - resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} - engines: {node: '>=14.17'} - hasBin: true - - update-browserslist-db@1.0.16: - resolution: {integrity: sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - vite@5.2.11: - resolution: {integrity: sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - - ws@8.11.0: - resolution: {integrity: sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - xmlhttprequest-ssl@2.0.0: - resolution: {integrity: sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==} - engines: {node: '>=0.4.0'} - - yaml@2.4.2: - resolution: {integrity: sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==} - engines: {node: '>= 14'} - hasBin: true - -snapshots: - - '@alloc/quick-lru@5.2.0': {} - - '@esbuild/aix-ppc64@0.20.2': - optional: true - - '@esbuild/android-arm64@0.20.2': - optional: true - - '@esbuild/android-arm@0.20.2': - optional: true - - '@esbuild/android-x64@0.20.2': - optional: true - - '@esbuild/darwin-arm64@0.20.2': - optional: true - - '@esbuild/darwin-x64@0.20.2': - optional: true - - '@esbuild/freebsd-arm64@0.20.2': - optional: true - - '@esbuild/freebsd-x64@0.20.2': - optional: true - - '@esbuild/linux-arm64@0.20.2': - optional: true - - '@esbuild/linux-arm@0.20.2': - optional: true - - '@esbuild/linux-ia32@0.20.2': - optional: true - - '@esbuild/linux-loong64@0.20.2': - optional: true - - '@esbuild/linux-mips64el@0.20.2': - optional: true - - '@esbuild/linux-ppc64@0.20.2': - optional: true - - '@esbuild/linux-riscv64@0.20.2': - optional: true - - '@esbuild/linux-s390x@0.20.2': - optional: true - - '@esbuild/linux-x64@0.20.2': - optional: true - - '@esbuild/netbsd-x64@0.20.2': - optional: true - - '@esbuild/openbsd-x64@0.20.2': - optional: true - - '@esbuild/sunos-x64@0.20.2': - optional: true - - '@esbuild/win32-arm64@0.20.2': - optional: true - - '@esbuild/win32-ia32@0.20.2': - optional: true - - '@esbuild/win32-x64@0.20.2': - optional: true - - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - - '@jridgewell/gen-mapping@0.3.5': - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.25 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/sourcemap-codec@1.4.15': {} - - '@jridgewell/trace-mapping@0.3.25': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.17.1 - - '@pkgjs/parseargs@0.11.0': - optional: true - - '@rollup/rollup-android-arm-eabi@4.17.2': - optional: true - - '@rollup/rollup-android-arm64@4.17.2': - optional: true - - '@rollup/rollup-darwin-arm64@4.17.2': - optional: true - - '@rollup/rollup-darwin-x64@4.17.2': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.17.2': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.17.2': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.17.2': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.17.2': - optional: true - - '@rollup/rollup-linux-powerpc64le-gnu@4.17.2': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.17.2': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.17.2': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.17.2': - optional: true - - '@rollup/rollup-linux-x64-musl@4.17.2': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.17.2': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.17.2': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.17.2': - optional: true - - '@socket.io/component-emitter@3.1.2': {} - - '@types/estree@1.0.5': {} - - ansi-regex@5.0.1: {} - - ansi-regex@6.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@6.2.1: {} - - any-promise@1.3.0: {} - - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - - arg@5.0.2: {} - - autoprefixer@10.4.19(postcss@8.4.38): - dependencies: - browserslist: 4.23.0 - caniuse-lite: 1.0.30001618 - fraction.js: 4.3.7 - normalize-range: 0.1.2 - picocolors: 1.0.1 - postcss: 8.4.38 - postcss-value-parser: 4.2.0 - - balanced-match@1.0.2: {} - - binary-extensions@2.3.0: {} - - brace-expansion@2.0.1: - dependencies: - balanced-match: 1.0.2 - - braces@3.0.2: - dependencies: - fill-range: 7.0.1 - - browserslist@4.23.0: - dependencies: - caniuse-lite: 1.0.30001618 - electron-to-chromium: 1.4.767 - node-releases: 2.0.14 - update-browserslist-db: 1.0.16(browserslist@4.23.0) - - camelcase-css@2.0.1: {} - - caniuse-lite@1.0.30001618: {} - - chokidar@3.6.0: - dependencies: - anymatch: 3.1.3 - braces: 3.0.2 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - commander@4.1.1: {} - - cross-spawn@7.0.3: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - cssesc@3.0.0: {} - - debug@4.3.4: - dependencies: - ms: 2.1.2 - - didyoumean@1.2.2: {} - - dlv@1.1.3: {} - - eastasianwidth@0.2.0: {} - - electron-to-chromium@1.4.767: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - engine.io-client@6.5.3: - dependencies: - '@socket.io/component-emitter': 3.1.2 - debug: 4.3.4 - engine.io-parser: 5.2.2 - ws: 8.11.0 - xmlhttprequest-ssl: 2.0.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - engine.io-parser@5.2.2: {} - - esbuild@0.20.2: - optionalDependencies: - '@esbuild/aix-ppc64': 0.20.2 - '@esbuild/android-arm': 0.20.2 - '@esbuild/android-arm64': 0.20.2 - '@esbuild/android-x64': 0.20.2 - '@esbuild/darwin-arm64': 0.20.2 - '@esbuild/darwin-x64': 0.20.2 - '@esbuild/freebsd-arm64': 0.20.2 - '@esbuild/freebsd-x64': 0.20.2 - '@esbuild/linux-arm': 0.20.2 - '@esbuild/linux-arm64': 0.20.2 - '@esbuild/linux-ia32': 0.20.2 - '@esbuild/linux-loong64': 0.20.2 - '@esbuild/linux-mips64el': 0.20.2 - '@esbuild/linux-ppc64': 0.20.2 - '@esbuild/linux-riscv64': 0.20.2 - '@esbuild/linux-s390x': 0.20.2 - '@esbuild/linux-x64': 0.20.2 - '@esbuild/netbsd-x64': 0.20.2 - '@esbuild/openbsd-x64': 0.20.2 - '@esbuild/sunos-x64': 0.20.2 - '@esbuild/win32-arm64': 0.20.2 - '@esbuild/win32-ia32': 0.20.2 - '@esbuild/win32-x64': 0.20.2 - - escalade@3.1.2: {} - - fast-glob@3.3.2: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - - fastq@1.17.1: - dependencies: - reusify: 1.0.4 - - fill-range@7.0.1: - dependencies: - to-regex-range: 5.0.1 - - foreground-child@3.1.1: - dependencies: - cross-spawn: 7.0.3 - signal-exit: 4.1.0 - - fraction.js@4.3.7: {} - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - glob@10.3.15: - dependencies: - foreground-child: 3.1.1 - jackspeak: 2.3.6 - minimatch: 9.0.4 - minipass: 7.1.1 - path-scurry: 1.11.1 - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - - is-core-module@2.13.1: - dependencies: - hasown: 2.0.2 - - is-extglob@2.1.1: {} - - is-fullwidth-code-point@3.0.0: {} - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-number@7.0.0: {} - - isexe@2.0.0: {} - - jackspeak@2.3.6: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - - jiti@1.21.0: {} - - lilconfig@2.1.0: {} - - lilconfig@3.1.1: {} - - lines-and-columns@1.2.4: {} - - lru-cache@10.2.2: {} - - merge2@1.4.1: {} - - micromatch@4.0.5: - dependencies: - braces: 3.0.2 - picomatch: 2.3.1 - - minimatch@9.0.4: - dependencies: - brace-expansion: 2.0.1 - - minipass@7.1.1: {} - - ms@2.1.2: {} - - mz@2.7.0: - dependencies: - any-promise: 1.3.0 - object-assign: 4.1.1 - thenify-all: 1.6.0 - - nanoid@3.3.7: {} - - node-releases@2.0.14: {} - - normalize-path@3.0.0: {} - - normalize-range@0.1.2: {} - - object-assign@4.1.1: {} - - object-hash@3.0.0: {} - - path-key@3.1.1: {} - - path-parse@1.0.7: {} - - path-scurry@1.11.1: - dependencies: - lru-cache: 10.2.2 - minipass: 7.1.1 - - picocolors@1.0.1: {} - - picomatch@2.3.1: {} - - pify@2.3.0: {} - - pirates@4.0.6: {} - - postcss-import@15.1.0(postcss@8.4.38): - dependencies: - postcss: 8.4.38 - postcss-value-parser: 4.2.0 - read-cache: 1.0.0 - resolve: 1.22.8 - - postcss-js@4.0.1(postcss@8.4.38): - dependencies: - camelcase-css: 2.0.1 - postcss: 8.4.38 - - postcss-load-config@4.0.2(postcss@8.4.38): - dependencies: - lilconfig: 3.1.1 - yaml: 2.4.2 - optionalDependencies: - postcss: 8.4.38 - - postcss-nested@6.0.1(postcss@8.4.38): - dependencies: - postcss: 8.4.38 - postcss-selector-parser: 6.0.16 - - postcss-selector-parser@6.0.16: - dependencies: - cssesc: 3.0.0 - util-deprecate: 1.0.2 - - postcss-value-parser@4.2.0: {} - - postcss@8.4.38: - dependencies: - nanoid: 3.3.7 - picocolors: 1.0.1 - source-map-js: 1.2.0 - - queue-microtask@1.2.3: {} - - read-cache@1.0.0: - dependencies: - pify: 2.3.0 - - readdirp@3.6.0: - dependencies: - picomatch: 2.3.1 - - resolve@1.22.8: - dependencies: - is-core-module: 2.13.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - reusify@1.0.4: {} - - rollup@4.17.2: - dependencies: - '@types/estree': 1.0.5 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.17.2 - '@rollup/rollup-android-arm64': 4.17.2 - '@rollup/rollup-darwin-arm64': 4.17.2 - '@rollup/rollup-darwin-x64': 4.17.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.17.2 - '@rollup/rollup-linux-arm-musleabihf': 4.17.2 - '@rollup/rollup-linux-arm64-gnu': 4.17.2 - '@rollup/rollup-linux-arm64-musl': 4.17.2 - '@rollup/rollup-linux-powerpc64le-gnu': 4.17.2 - '@rollup/rollup-linux-riscv64-gnu': 4.17.2 - '@rollup/rollup-linux-s390x-gnu': 4.17.2 - '@rollup/rollup-linux-x64-gnu': 4.17.2 - '@rollup/rollup-linux-x64-musl': 4.17.2 - '@rollup/rollup-win32-arm64-msvc': 4.17.2 - '@rollup/rollup-win32-ia32-msvc': 4.17.2 - '@rollup/rollup-win32-x64-msvc': 4.17.2 - fsevents: 2.3.3 - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - signal-exit@4.1.0: {} - - socket.io-client@4.7.5: - dependencies: - '@socket.io/component-emitter': 3.1.2 - debug: 4.3.4 - engine.io-client: 6.5.3 - socket.io-parser: 4.2.4 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - socket.io-parser@4.2.4: - dependencies: - '@socket.io/component-emitter': 3.1.2 - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - - source-map-js@1.2.0: {} - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.0.1 - - sucrase@3.35.0: - dependencies: - '@jridgewell/gen-mapping': 0.3.5 - commander: 4.1.1 - glob: 10.3.15 - lines-and-columns: 1.2.4 - mz: 2.7.0 - pirates: 4.0.6 - ts-interface-checker: 0.1.13 - - supports-preserve-symlinks-flag@1.0.0: {} - - tailwindcss@3.4.3: - dependencies: - '@alloc/quick-lru': 5.2.0 - arg: 5.0.2 - chokidar: 3.6.0 - didyoumean: 1.2.2 - dlv: 1.1.3 - fast-glob: 3.3.2 - glob-parent: 6.0.2 - is-glob: 4.0.3 - jiti: 1.21.0 - lilconfig: 2.1.0 - micromatch: 4.0.5 - normalize-path: 3.0.0 - object-hash: 3.0.0 - picocolors: 1.0.1 - postcss: 8.4.38 - postcss-import: 15.1.0(postcss@8.4.38) - postcss-js: 4.0.1(postcss@8.4.38) - postcss-load-config: 4.0.2(postcss@8.4.38) - postcss-nested: 6.0.1(postcss@8.4.38) - postcss-selector-parser: 6.0.16 - resolve: 1.22.8 - sucrase: 3.35.0 - transitivePeerDependencies: - - ts-node - - thenify-all@1.6.0: - dependencies: - thenify: 3.3.1 - - thenify@3.3.1: - dependencies: - any-promise: 1.3.0 - - three@0.164.1: {} - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - ts-interface-checker@0.1.13: {} - - typescript@5.4.5: {} - - update-browserslist-db@1.0.16(browserslist@4.23.0): - dependencies: - browserslist: 4.23.0 - escalade: 3.1.2 - picocolors: 1.0.1 - - util-deprecate@1.0.2: {} - - vite@5.2.11: - dependencies: - esbuild: 0.20.2 - postcss: 8.4.38 - rollup: 4.17.2 - optionalDependencies: - fsevents: 2.3.3 - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - - ws@8.11.0: {} - - xmlhttprequest-ssl@2.0.0: {} - - yaml@2.4.2: {} diff --git a/painter-js/public/og-image.png b/painter-js/public/og-image.png new file mode 100644 index 0000000000000000000000000000000000000000..e2576d165dd26882db32cfb15e9a888776f8fb0a GIT binary patch literal 99977 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 MnqDcneDB%+05@y1ZU6uP literal 0 HcmV?d00001 diff --git a/painter-js/src/Astronaut.glb b/painter-js/src/Astronaut.glb deleted file mode 100644 index b0b85d7fe11c806e922f7e32dd555e317467184e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 733432 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 z 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
  • =w88Z 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%0A`cep2F5)xKHh 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 { - const hexColor = isColorPicker ? color : rgbToHex(color); - currentColor = hexColor; - currentColorSpan.style.backgroundColor = hexColor; - localStorage.setItem("currentColor", hexColor); -}; - -const handleColorPicker = () => { - colorPicker.addEventListener("input", (event) => { - setCurrentColor(event.target.value, true); - }); - - redButton.addEventListener("click", () => { - setCurrentColor(getColorFromElementCSS(redButton)); - }); - - greenButton.addEventListener("click", () => { - setCurrentColor(getColorFromElementCSS(greenButton)); - }); - - blueButton.addEventListener("click", () => { - setCurrentColor(getColorFromElementCSS(blueButton)); - }); - - yellowButton.addEventListener("click", () => { - setCurrentColor(getColorFromElementCSS(yellowButton)); - }); - - purpleButton.addEventListener("click", () => { - setCurrentColor(getColorFromElementCSS(purpleButton)); - }); - - pinkButton.addEventListener("click", () => { - setCurrentColor(getColorFromElementCSS(pinkButton)); - }); - - cyanButton.addEventListener("click", () => { - setCurrentColor(getColorFromElementCSS(cyanButton)); - }); - - whiteButton.addEventListener("click", () => { - setCurrentColor(getColorFromElementCSS(whiteButton)); - }); - - blackButton.addEventListener("click", () => { - setCurrentColor(getColorFromElementCSS(blackButton)); - }); - - orangeButton.addEventListener("click", () => { - setCurrentColor(getColorFromElementCSS(orangeButton)); - }); - - brownButton.addEventListener("click", () => { - setCurrentColor(getColorFromElementCSS(brownButton)); - }); -}; - -const fetchCanvasState = async () => { - fetch(canvasEndpoint) - .then((response) => response.json()) - .then((data) => { - canvasState = data; - drawCanvasState(data); - }) - .catch((error) => { - alert("Error fetching canvas state from server. Please try again later."); - }); -}; - -const drawCanvasState = (canvasState) => { - for (let y = 0; y < HEIGHT; y++) { - for (let x = 0; x < WIDTH; x++) { - const index = y * WIDTH + x; - const color = u32ToHex(canvasState[index]); - ctx.fillStyle = color; - ctx.fillRect(x * pixelSize, y * pixelSize, pixelSize, pixelSize); - } - } -}; - -const checkIfCanPlacePixel = () => { - const now = Date.now(); - return now - lastPixelTime >= pixelCooldown; -}; - -const setLastPixelTime = () => { - lastPixelTime = Date.now(); - localStorage.setItem("lastPixelTime", lastPixelTime.toString()); -}; - -const handlePlacePixel = (pixelData) => { - if (!checkIfCanPlacePixel()) { - alert("You can't place a pixel yet"); - return; - } - - socket.emit("place-pixel", pixelData); - const index = pixelData.y * WIDTH + pixelData.x; - canvasState[index] = pixelData.color; - setLastPixelTime(); - pixelData = null; -}; - -canvas.addEventListener("click", (event) => { - const rect = canvas.getBoundingClientRect(); - const x = Math.floor((event.clientX - rect.left) / pixelSize); - const y = Math.floor((event.clientY - rect.top) / pixelSize); - - const color = hexToU32(currentColor); - const oldPreviewPixel = previewPixel; - - const update = { x, y, color }; - - if (confirmPlacePixel) { - handlePlacePixel(update); - } else { - previewPixel = update; - } - - if (previewPixel) { - if (oldPreviewPixel) { - ctx.clearRect( - oldPreviewPixel.x * pixelSize, - oldPreviewPixel.y * pixelSize, - pixelSize, - pixelSize - ); - } - - ctx.fillStyle = `rgba(${(color >> 16) & 0xff}, ${(color >> 8) & 0xff}, ${ - color & 0xff - }, 0.5)`; - ctx.fillRect(x * pixelSize, y * pixelSize, pixelSize, pixelSize); - } -}); - -const removePreviewPixel = () => { - previewPixel = null; - ctx.clearRect(0, 0, canvas.width, canvas.height); - drawCanvasState(canvasState); -}; - -const drawGrid = () => { - ctx.strokeStyle = "#000"; - for (let x = 0; x < canvas.width; x += pixelSize) { - ctx.beginPath(); - ctx.moveTo(x, 0); - ctx.lineTo(x, canvas.height); - ctx.stroke(); - } - for (let y = 0; y < canvas.height; y += pixelSize) { - ctx.beginPath(); - ctx.moveTo(0, y); - ctx.lineTo(canvas.width, y); - ctx.stroke(); - } -}; - -const handleToggleGrid = () => { - toggleGridToggle.addEventListener("change", (event) => { - showGrid = event.target.checked; - localStorage.setItem("showGrid", showGrid); - if (showGrid) { - drawGrid(); - } else { - ctx.clearRect(0, 0, canvas.width, canvas.height); - drawCanvasState(canvasState); - } - }); -}; - -window.onkeydown = (event) => { - // on enter (keycode 13 is enter) - if (event.keyCode === 13) { - if (previewPixel) { - handlePlacePixel(previewPixel); - removePreviewPixel(); - } - } -}; - -placePixelButton.addEventListener("click", () => { - if (previewPixel) { - handlePlacePixel(previewPixel); - removePreviewPixel(); - } -}); - -saveCanvasButton.addEventListener("click", () => { - const a = document.createElement("a"); - a.href = canvas.toDataURL(); - a.download = "canvas.png"; - a.click(); -}); - -handleColorPicker(); -handleToggleGrid(); - -export const handleSocketEvents = (_socket) => { - socket = _socket; - socket.on("connect", () => { - fetchCanvasState(); - }); - - socket.on("pixel-updated", (update) => { - const color = u32ToHex(update.color); - ctx.fillStyle = color; - ctx.fillRect( - update.x * pixelSize, - update.y * pixelSize, - pixelSize, - pixelSize - ); - - const index = update.y * WIDTH + update.x; - canvasState[index] = update.color; - }); -}; diff --git a/painter-js/src/challenge.js b/painter-js/src/challenge.js deleted file mode 100644 index e6494df..0000000 --- a/painter-js/src/challenge.js +++ /dev/null @@ -1,139 +0,0 @@ -import * as three from 'three'; -import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; -import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; - -let scene, camera, renderer, character, mixer, clock; -let walkAction, idleAction; -let moving = false; -const keys = {} - -let boxes = []; - -const container = document.getElementById('challenge'); - -const onWindowResize = () => { - camera.aspect = container.clientWidth / container.clientHeight; - camera.updateProjectionMatrix(); - renderer.setSize(container.clientWidth, container.clientHeight); -} - -const onKeyDown = (e) => { - keys[e.code] = true; -} - -const onKeyUp = (e) => { - keys[e.code] = false; -} - -const init = () => { - scene = new three.Scene(); - camera = new three.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); - renderer = new three.WebGLRenderer({ antialias: true}); - renderer.setSize(window.innerWidth, window.innerHeight); - container.appendChild(renderer.domElement); - - clock = new three.Clock(); - - // Adjust light positions and intensity - const light = new three.DirectionalLight(0xffffff, 1); - light.position.set(5, 10, 7.5); - light.castShadow = true; - scene.add(light); - - - - for (let i = 0; i < 10; i++) { - const box = new three.Mesh( - new three.BoxGeometry(1, 1, 1), - new three.MeshStandardMaterial({ color: 0x00ff00 }) - ); - box.position.set(Math.random() * 10 - 5, 0.5, Math.random() * 10 - 5); - box.castShadow = true; - scene.add(box); - boxes.push(box); - } - - const loader = new GLTFLoader(); - loader.load('src/Astronaut.glb',(gltf) => { - character = gltf.scene; - scene.add(character); - - mixer = new three.AnimationMixer(character); - gltf.animations.forEach((clip) => { - if (clip.name === 'CharacterArmature|Walk') { - walkAction = mixer.clipAction(clip); - } - if (clip.name === 'CharacterArmature|Idle') { - idleAction = mixer.clipAction(clip); - } - }); - - if (walkAction) walkAction.play(); - if (idleAction) idleAction.play(); - - character.position.set(-10, 0, -60); - character.rotation.y = Math.PI; - }) - - //blue sky - scene.background = new three.Color(0x87ceeb); - - camera.position.set(20, 10, 10) - camera.lookAt(0, 10, 0) - - window.addEventListener('resize', onWindowResize, false); - document.addEventListener('keydown', onKeyDown, false); - document.addEventListener('keyup', onKeyUp, false); -} - -const animate = () => { - requestAnimationFrame(animate); - - const delta = clock.getDelta(); - if (mixer) mixer.update(delta); - - if (character) { - if (keys['KeyW']) { - character.position.z -= 0.1; - character.rotation.y = Math.PI; // North - } - - if (keys['KeyS']) { - character.position.z += 0.1; - character.rotation.y = 0; // South - } - - if (keys['KeyA']) { - character.position.x -= 0.1; - character.rotation.y = Math.PI / 2; // West - } - - if (keys['KeyD']) { - character.position.x += 0.1; - character.rotation.y = -Math.PI / 2; // East - } - - // check if any key is pressed - if (keys['KeyW'] || keys['KeyS'] || keys['KeyA'] || keys['KeyD']) { - moving = true; - } else { - moving = false; - } - - // Play walking animation if moving - if (mixer) { - if (walkAction && idleAction) { - walkAction.enabled = moving; - idleAction.enabled = !moving; - } - } - } - - renderer.render(scene, camera); -} - -const threejs = import.meta.env.VITE_THREE_JS === "true"; -if (threejs) { - init(); - animate(); -} diff --git a/painter-js/src/constants.js b/painter-js/src/constants.js deleted file mode 100644 index 5f5b670..0000000 --- a/painter-js/src/constants.js +++ /dev/null @@ -1,12 +0,0 @@ -const isDebug = import.meta.env.VITE_IS_DEBUG === "true"; - -export const pixelSize = 10; -export const pixelCooldown = 10 * 1000; // 10 seconds -export const canvasEndpoint = isDebug - ? "http://localhost:3000/canvas/" - : "/canvas/"; -export const checkEndpoint = isDebug - ? "http://localhost:3000/check/" - : "/check/"; -export const WIDTH = 500; -export const HEIGHT = 500; diff --git a/painter-js/src/counter.js b/painter-js/src/counter.js deleted file mode 100644 index 16c3674..0000000 --- a/painter-js/src/counter.js +++ /dev/null @@ -1,20 +0,0 @@ -import { pixelCooldown } from "./constants.js"; - -const countdownDiv = document.getElementById("countdown"); - -export const updateCountdown = () => { - setInterval(() => { - const lastPixelTime = parseInt( - localStorage.getItem("lastPixelTime") || "0" - ); - const now = Date.now(); - const timeLeft = Math.max(0, pixelCooldown - (now - lastPixelTime)); - if (timeLeft > 0) { - countdownDiv.textContent = `You can place a pixel in ${Math.ceil( - timeLeft / 1000 - )} seconds`; - } else { - countdownDiv.textContent = "You can place a pixel now"; - } - }, 1000); -}; diff --git a/painter-js/src/domain/canvas-state.js b/painter-js/src/domain/canvas-state.js new file mode 100644 index 0000000..1d40671 --- /dev/null +++ b/painter-js/src/domain/canvas-state.js @@ -0,0 +1,11 @@ +import { WIDTH } from "./constants.js"; + +export const getPixelIndex = (x, y) => y * WIDTH + x; + +export const setPixel = (state, x, y, color) => { + state[getPixelIndex(x, y)] = color; +}; + +export const getPixel = (state, x, y) => { + return state[getPixelIndex(x, y)]; +}; diff --git a/painter-js/src/utils.js b/painter-js/src/domain/color.js similarity index 66% rename from painter-js/src/utils.js rename to painter-js/src/domain/color.js index e7dac6c..6cf79cc 100644 --- a/painter-js/src/utils.js +++ b/painter-js/src/domain/color.js @@ -6,13 +6,16 @@ export const hexToU32 = (color) => { return parseInt(color.slice(1), 16); }; -export const getColorFromElementCSS = (element) => { - return window.getComputedStyle(element).backgroundColor; -}; - export const rgbToHex = (rgbProperty) => { const rgb = rgbProperty.match(/\d+/g); return `#${rgb .map((x) => parseInt(x).toString(16).padStart(2, "0")) .join("")}`; }; + +export const u32ToRGBA = (color, alpha) => { + const r = (color >> 16) & 0xff; + const g = (color >> 8) & 0xff; + const b = color & 0xff; + return `rgba(${r}, ${g}, ${b}, ${alpha})`; +}; diff --git a/painter-js/src/domain/constants.js b/painter-js/src/domain/constants.js new file mode 100644 index 0000000..73c8a20 --- /dev/null +++ b/painter-js/src/domain/constants.js @@ -0,0 +1,4 @@ +export const PIXEL_SIZE = 1; +export const PIXEL_COOLDOWN = 10 * 1000; +export const WIDTH = 500; +export const HEIGHT = 500; diff --git a/painter-js/src/domain/cooldown.js b/painter-js/src/domain/cooldown.js new file mode 100644 index 0000000..a94269b --- /dev/null +++ b/painter-js/src/domain/cooldown.js @@ -0,0 +1,9 @@ +import { PIXEL_COOLDOWN } from "./constants.js"; + +export const canPlacePixel = (lastPlacementTime) => { + return Date.now() - lastPlacementTime >= PIXEL_COOLDOWN; +}; + +export const timeRemaining = (lastPlacementTime) => { + return Math.max(0, PIXEL_COOLDOWN - (Date.now() - lastPlacementTime)); +}; diff --git a/painter-js/src/domain/coords.js b/painter-js/src/domain/coords.js new file mode 100644 index 0000000..cbbee59 --- /dev/null +++ b/painter-js/src/domain/coords.js @@ -0,0 +1,19 @@ +import { WIDTH, HEIGHT } from "./constants.js"; + +export const getCanvasCoords = (event, canvas) => { + const rect = canvas.getBoundingClientRect(); + const clientX = event.touches ? event.touches[0].clientX : event.clientX; + const clientY = event.touches ? event.touches[0].clientY : event.clientY; + const scaleX = canvas.width / rect.width; + const scaleY = canvas.height / rect.height; + return { + x: Math.min( + Math.max(Math.floor((clientX - rect.left) * scaleX), 0), + WIDTH - 1, + ), + y: Math.min( + Math.max(Math.floor((clientY - rect.top) * scaleY), 0), + HEIGHT - 1, + ), + }; +}; diff --git a/painter-js/src/infrastructure/api.js b/painter-js/src/infrastructure/api.js new file mode 100644 index 0000000..0784b7c --- /dev/null +++ b/painter-js/src/infrastructure/api.js @@ -0,0 +1,5 @@ +const isDebug = import.meta.env.VITE_IS_DEBUG === "true"; + +const CHECK_ENDPOINT = isDebug ? "http://localhost:3000/check/" : "/check/"; + +export const checkServer = () => fetch(CHECK_ENDPOINT); diff --git a/painter-js/src/infrastructure/socket-client.js b/painter-js/src/infrastructure/socket-client.js new file mode 100644 index 0000000..08b671a --- /dev/null +++ b/painter-js/src/infrastructure/socket-client.js @@ -0,0 +1,72 @@ +import io from "socket.io-client"; + +const isDebug = import.meta.env.VITE_IS_DEBUG === "true"; +const transport = import.meta.env.VITE_TRANSPORT || "socketio"; + +const createSocketIoTransport = () => { + const url = isDebug ? "ws://localhost:3000" : undefined; + const socket = url ? io(url) : io({ transports: ["websocket"] }); + + return { + on: (event, handler) => socket.on(event, handler), + emit: (event, data) => socket.emit(event, data), + }; +}; + +const createWebSocketTransport = () => { + const handlers = {}; + const wsUrl = isDebug + ? "ws://localhost:3000/ws" + : `${window.location.protocol === "https:" ? "wss:" : "ws:"}//${window.location.host}/ws`; + + const ws = new WebSocket(wsUrl); + ws.binaryType = "arraybuffer"; + + const on = (event, handler) => { + if (!handlers[event]) handlers[event] = []; + handlers[event].push(handler); + }; + + const emit = (event, data) => { + if (ws.readyState !== WebSocket.OPEN) return; + ws.send(JSON.stringify({ type: event, ...data })); + }; + + const dispatch = (event, ...args) => { + (handlers[event] || []).forEach((handler) => handler(...args)); + }; + + ws.addEventListener("open", () => dispatch("connect")); + + ws.addEventListener("message", (event) => { + if (event.data instanceof ArrayBuffer) { + const pixels = new Uint32Array(event.data); + dispatch("canvas_state", Array.from(pixels)); + return; + } + + const message = JSON.parse(event.data); + switch (message.type) { + case "pixel-updated": + dispatch("pixel-updated", message); + break; + case "current_soldiers": + dispatch("current_soldiers", message.count); + break; + case "error": + dispatch("error", message.message); + break; + } + }); + + ws.addEventListener("close", () => dispatch("disconnect")); + + return { on, emit }; +}; + +export const createSocketConnection = () => { + if (transport === "websocket") { + return createWebSocketTransport(); + } + return createSocketIoTransport(); +}; diff --git a/painter-js/src/main.js b/painter-js/src/main.js index 99c1b20..ed544af 100644 --- a/painter-js/src/main.js +++ b/painter-js/src/main.js @@ -1,58 +1,88 @@ -import { connectToWS } from "./socket.js"; -import "./canvas.js"; -import "./counter.js"; -import { updateCountdown } from "./counter.js"; -import { checkEndpoint, pixelSize } from "./constants.js"; -import { handleSocketEvents } from "./canvas.js"; -import "./challenge.js" +import { createSocketConnection } from "./infrastructure/socket-client.js"; +import { checkServer } from "./infrastructure/api.js"; +import { createCanvasRenderer } from "./ui/canvas-renderer.js"; +import { createColorPalette } from "./ui/color-palette.js"; +import { createPixelPlacer } from "./ui/pixel-placer.js"; +import { startCooldownDisplay } from "./ui/cooldown-display.js"; +import { createCanvasViewport } from "./ui/canvas-viewport.js"; +import { setPixel } from "./domain/canvas-state.js"; +import { getCanvasCoords } from "./domain/coords.js"; -const isDebug = import.meta.env.VITE_IS_DEBUG === "true"; - -const currentSoldiersSpan = document.getElementById("current-soldiers"); - -let coords = []; -const canvas = document.getElementById("canvas"); +const canvasEl = document.getElementById("canvas"); const coordsText = document.getElementById("coords"); -const ogCanvasStyle = canvas.style.display; -canvas.style.display = "none"; +const currentSoldiersSpan = document.getElementById("current-soldiers"); +const statusEl = document.getElementById("connection-status"); -fetch(checkEndpoint) +const savedDisplay = canvasEl.style.display; +canvasEl.style.display = "none"; + +let canvasState = []; + +const renderer = createCanvasRenderer(canvasEl); +const palette = createColorPalette(); + +startCooldownDisplay(); +createCanvasViewport(canvasEl); + +canvasEl.addEventListener("mousemove", (event) => { + const { x, y } = getCanvasCoords(event, canvasEl); + coordsText.textContent = `${x}, ${y}`; +}); + +document.getElementById("save-canvas").addEventListener("click", () => { + const a = document.createElement("a"); + a.href = renderer.toDataURL(); + a.download = "canvas.png"; + a.click(); +}); + +const showStatus = (message, isError) => { + if (!statusEl) return; + statusEl.textContent = message; + statusEl.className = isError + ? "text-red-500 text-sm" + : "text-green-500 text-sm"; +}; + +checkServer() .then((response) => { - if (response.ok) { - const socket = connectToWS(); + if (!response.ok) throw new Error("Server unavailable"); - socket.on("connect", () => { - canvas.style.display = ogCanvasStyle; - console.log("connect"); - }); + const socket = createSocketConnection(); - socket.on("error", (message) => { - alert(message); - }); + socket.on("connect", () => { + canvasEl.style.display = savedDisplay; + showStatus("Connected", false); + }); - socket.on("current_soldiers", (currentSoldiers) => { - currentSoldiersSpan.textContent = currentSoldiers; - }); + socket.on("canvas_state", (data) => { + canvasState = data; + renderer.drawState(data); + }); - handleSocketEvents(socket); + socket.on("error", (message) => showStatus(message, true)); - requestAnimationFrame(updateCountdown); + socket.on("current_soldiers", (count) => { + currentSoldiersSpan.textContent = count; + }); - window.addEventListener("mousemove", (event) => { - // get coordinates of the mouse inside the canvas - const rect = canvas.getBoundingClientRect(); - const x = Math.floor((event.clientX - rect.left) / pixelSize); - const y = Math.floor((event.clientY - rect.top) / pixelSize); - coords = [x, y]; + socket.on("pixel-updated", (update) => { + renderer.drawPixel(update.x, update.y, update.color); + setPixel(canvasState, update.x, update.y, update.color); + }); - coordsText.textContent = `${x}, ${y}`; - }); - } else { - throw new Error("Can't connect to the server"); - } + socket.on("disconnect", () => { + showStatus("Disconnected — reconnecting...", true); + }); + + createPixelPlacer({ + canvas: canvasEl, + renderer, + getColor: palette.getColor, + getState: () => canvasState, + socket, + }); }) - .catch((error) => { - alert( - "You have already connected to the server from another tab or window. Please close the other tab or window and refresh this page." - ); + .catch(() => { + showStatus("Cannot connect to server", true); }); diff --git a/painter-js/src/socket.js b/painter-js/src/socket.js deleted file mode 100644 index 5774edb..0000000 --- a/painter-js/src/socket.js +++ /dev/null @@ -1,21 +0,0 @@ -import io from "socket.io-client"; - -const isDebug = import.meta.env.VITE_IS_DEBUG === "true"; -const wsProtocol = window.location.protocol === "https:" ? "wss:" : "ws:"; -const wsHost = window.location.host; - -let socket; - -export const connectToWS = () => { - if (isDebug) { - socket = io("ws://localhost:3000"); - } else { - socket = io(`${wsProtocol}//${wsHost}`, { - transports: ["websocket"], - }); - } - - return socket; -}; - -export default socket; diff --git a/painter-js/src/style.css b/painter-js/src/style.css index 15550e5..abd3730 100644 --- a/painter-js/src/style.css +++ b/painter-js/src/style.css @@ -2,20 +2,17 @@ @tailwind components; @tailwind utilities; -@layer base { - .rainbow-border { - position: relative; - display: inline-block; - background: linear-gradient(to right, red, orange, yellow, green, blue, indigo, violet); +.canvas-viewport { + overflow: auto; + width: min(92vw, 70vh); + height: min(92vw, 70vh); + border: 2px solid #94a3b8; + border-radius: 4px; + cursor: crosshair; } -.rainbow-border::before { - content: ''; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - background: white; - z-index: -1; /* Place behind the content */ + +#canvas { + image-rendering: pixelated; + image-rendering: crisp-edges; + display: block; } -} \ No newline at end of file diff --git a/painter-js/src/ui/canvas-renderer.js b/painter-js/src/ui/canvas-renderer.js new file mode 100644 index 0000000..e8af1a8 --- /dev/null +++ b/painter-js/src/ui/canvas-renderer.js @@ -0,0 +1,39 @@ +import { u32ToHex, u32ToRGBA } from "../domain/color.js"; +import { WIDTH, HEIGHT } from "../domain/constants.js"; + +export const createCanvasRenderer = (canvas) => { + const ctx = canvas.getContext("2d"); + + const drawState = (state) => { + const imageData = ctx.createImageData(WIDTH, HEIGHT); + const data = imageData.data; + for (let i = 0; i < state.length; i++) { + const color = state[i]; + const offset = i * 4; + data[offset] = (color >> 16) & 0xff; + data[offset + 1] = (color >> 8) & 0xff; + data[offset + 2] = color & 0xff; + data[offset + 3] = 255; + } + ctx.putImageData(imageData, 0, 0); + }; + + const drawPixel = (x, y, colorU32) => { + ctx.fillStyle = u32ToHex(colorU32); + ctx.fillRect(x, y, 1, 1); + }; + + const drawPreview = (x, y, colorU32) => { + ctx.fillStyle = u32ToRGBA(colorU32, 0.5); + ctx.fillRect(x, y, 1, 1); + }; + + const restorePixel = (state, x, y) => { + ctx.fillStyle = u32ToHex(state[y * WIDTH + x]); + ctx.fillRect(x, y, 1, 1); + }; + + const toDataURL = () => canvas.toDataURL(); + + return { drawState, drawPixel, drawPreview, restorePixel, toDataURL }; +}; diff --git a/painter-js/src/ui/canvas-viewport.js b/painter-js/src/ui/canvas-viewport.js new file mode 100644 index 0000000..fa8fc18 --- /dev/null +++ b/painter-js/src/ui/canvas-viewport.js @@ -0,0 +1,78 @@ +const MIN_ZOOM = 1; +const MAX_ZOOM = 40; + +export const createCanvasViewport = (canvas) => { + const viewport = canvas.parentElement; + const zoomLabel = document.getElementById("zoom-level"); + let zoom = 1; + let baseSize = viewport.clientWidth; + + const applyZoom = () => { + const size = baseSize * zoom; + canvas.style.width = `${size}px`; + canvas.style.height = `${size}px`; + if (zoomLabel) zoomLabel.textContent = `${zoom.toFixed(1)}x`; + }; + + const setZoom = (newZoom, centerX, centerY) => { + const oldZoom = zoom; + zoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, newZoom)); + if (zoom === oldZoom) return; + + if (centerX !== undefined && centerY !== undefined) { + const ratio = zoom / oldZoom; + viewport.scrollLeft = (viewport.scrollLeft + centerX) * ratio - centerX; + viewport.scrollTop = (viewport.scrollTop + centerY) * ratio - centerY; + } + + applyZoom(); + }; + + viewport.addEventListener("wheel", (event) => { + event.preventDefault(); + const factor = event.deltaY > 0 ? 0.8 : 1.25; + const rect = viewport.getBoundingClientRect(); + setZoom(zoom * factor, event.clientX - rect.left, event.clientY - rect.top); + }); + + let lastPinchDist = 0; + viewport.addEventListener("touchmove", (event) => { + if (event.touches.length !== 2) return; + event.preventDefault(); + const dist = Math.hypot( + event.touches[0].clientX - event.touches[1].clientX, + event.touches[0].clientY - event.touches[1].clientY, + ); + if (lastPinchDist > 0) { + const midX = + (event.touches[0].clientX + event.touches[1].clientX) / 2 - + viewport.getBoundingClientRect().left; + const midY = + (event.touches[0].clientY + event.touches[1].clientY) / 2 - + viewport.getBoundingClientRect().top; + setZoom(zoom * (dist / lastPinchDist), midX, midY); + } + lastPinchDist = dist; + }); + + viewport.addEventListener("touchend", () => { + lastPinchDist = 0; + }); + + document.getElementById("zoom-in")?.addEventListener("click", () => { + setZoom(zoom * 1.5); + applyZoom(); + }); + + document.getElementById("zoom-out")?.addEventListener("click", () => { + setZoom(zoom / 1.5); + applyZoom(); + }); + + window.addEventListener("resize", () => { + baseSize = viewport.clientWidth; + applyZoom(); + }); + + applyZoom(); +}; diff --git a/painter-js/src/ui/color-palette.js b/painter-js/src/ui/color-palette.js new file mode 100644 index 0000000..5234a11 --- /dev/null +++ b/painter-js/src/ui/color-palette.js @@ -0,0 +1,53 @@ +import { rgbToHex } from "../domain/color.js"; + +const PALETTE_IDS = [ + "red", + "green", + "blue", + "yellow", + "purple", + "pink", + "cyan", + "white", + "black", + "orange", + "brown", +]; + +export const createColorPalette = () => { + const colorPicker = document.getElementById("color-picker"); + const currentColorSpan = document.getElementById("current-color-span"); + let activeButton = null; + + let currentColor = localStorage.getItem("currentColor") || "#000000"; + colorPicker.value = currentColor; + currentColorSpan.style.backgroundColor = currentColor; + + const setColor = (hex, button) => { + currentColor = hex; + currentColorSpan.textContent = hex; + currentColorSpan.style.backgroundColor = hex; + localStorage.setItem("currentColor", hex); + + if (activeButton) + activeButton.classList.remove("ring-2", "ring-offset-2", "ring-cyan-400"); + if (button) { + button.classList.add("ring-2", "ring-offset-2", "ring-cyan-400"); + activeButton = button; + } + }; + + colorPicker.addEventListener("input", (e) => setColor(e.target.value, null)); + + for (const id of PALETTE_IDS) { + const button = document.getElementById(id); + button.addEventListener("click", () => { + setColor( + rgbToHex(window.getComputedStyle(button).backgroundColor), + button, + ); + }); + } + + return { getColor: () => currentColor }; +}; diff --git a/painter-js/src/ui/cooldown-display.js b/painter-js/src/ui/cooldown-display.js new file mode 100644 index 0000000..eb99b52 --- /dev/null +++ b/painter-js/src/ui/cooldown-display.js @@ -0,0 +1,16 @@ +import { timeRemaining } from "../domain/cooldown.js"; + +export const startCooldownDisplay = () => { + const countdownDiv = document.getElementById("countdown"); + + setInterval(() => { + const lastPlacementTime = parseInt( + localStorage.getItem("lastPixelTime") || "0", + ); + const remaining = timeRemaining(lastPlacementTime); + countdownDiv.textContent = + remaining > 0 + ? `You can place a pixel in ${Math.ceil(remaining / 1000)} seconds` + : "You can place a pixel now"; + }, 1000); +}; diff --git a/painter-js/src/ui/pixel-placer.js b/painter-js/src/ui/pixel-placer.js new file mode 100644 index 0000000..2127eed --- /dev/null +++ b/painter-js/src/ui/pixel-placer.js @@ -0,0 +1,57 @@ +import { hexToU32 } from "../domain/color.js"; +import { canPlacePixel } from "../domain/cooldown.js"; +import { setPixel } from "../domain/canvas-state.js"; +import { getCanvasCoords } from "../domain/coords.js"; + +export const createPixelPlacer = ({ + canvas, + renderer, + getColor, + getState, + socket, +}) => { + let previewPixel = null; + + const place = (update) => { + const lastPixelTime = parseInt( + localStorage.getItem("lastPixelTime") || "0", + ); + if (!canPlacePixel(lastPixelTime)) return; + + socket.emit("place-pixel", update); + setPixel(getState(), update.x, update.y, update.color); + localStorage.setItem("lastPixelTime", Date.now().toString()); + }; + + const clearPreview = () => { + if (!previewPixel) return; + renderer.restorePixel(getState(), previewPixel.x, previewPixel.y); + previewPixel = null; + }; + + const confirmPlacement = () => { + if (!previewPixel) return; + place(previewPixel); + clearPreview(); + }; + + const selectPixel = (event) => { + const { x, y } = getCanvasCoords(event, canvas); + const color = hexToU32(getColor()); + + clearPreview(); + previewPixel = { x, y, color }; + renderer.drawPreview(x, y, color); + }; + + canvas.addEventListener("click", selectPixel); + + window.addEventListener("keydown", (event) => { + if (event.key === "Enter") confirmPlacement(); + if (event.key === "Escape") clearPreview(); + }); + + document + .getElementById("place-pixel") + .addEventListener("click", confirmPlacement); +}; diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 2da7653..0000000 --- a/src/main.rs +++ /dev/null @@ -1,251 +0,0 @@ -use std::{ - collections::{HashMap, HashSet}, - net::SocketAddr, - sync::{Arc, Mutex}, -}; - -use axum::{routing::get, Extension, Json, Router}; -use chrono::{DateTime, Duration, Utc}; -use memory_stats::memory_stats; -use serde::{Deserialize, Serialize}; -use serde_json::Value; -use socketioxide::{ - extract::{Bin, Data, SocketRef}, - SocketIo, -}; -use tower_governor::{governor::GovernorConfigBuilder, GovernorLayer}; -use tower_http::{ - cors::{Any, CorsLayer}, - services::ServeDir, -}; -use tracing::info; -use tracing_subscriber::FmtSubscriber; - -type Canvas = Arc>>; -type LastUpdate = Arc>>>; -type Soldiers = Arc>>; - -#[derive(Serialize, Deserialize, Debug)] -struct PixelUpdate { - x: u32, - y: u32, - color: u32, -} - -async fn on_connect( - socket: SocketRef, - canvas: Canvas, - last_update: LastUpdate, - soldiers: Soldiers, -) { - info!("Socket connected: {:?} {:?}", socket.ns(), socket.id,); - - let socket_id = socket.id.to_string(); - - { - let mut soldiers = soldiers.lock().unwrap(); - soldiers.insert(socket_id.clone()); - let soldiers_num = soldiers.len(); - - socket.emit("current_soldiers", &soldiers_num).ok(); - socket - .broadcast() - .emit("current_soldiers", &soldiers_num) - .ok(); - } - - info!("Memory usage after connection and before cloning state: "); - print_memory_usage(); - - let canvas_clone = canvas.clone(); - let last_update_clone = last_update.clone(); - - info!("Memory usage after connection and after cloning state: "); - print_memory_usage(); - - socket.on( - "place-pixel", - move |socket: SocketRef, Data::(update), Bin(_bin)| { - let socket_id = socket.id.to_string(); - let last_update = last_update_clone.clone(); - let canvas = canvas_clone.clone(); - - { - let now = Utc::now(); - let mut last_update = last_update.lock().unwrap(); - - if let Some(&last_time) = last_update.get(&socket_id) { - if now < last_time + Duration::seconds(10) { - let _ = socket.emit( - "error", - Value::String("You can only place one pixel per minute".to_string()), - ); - return; - } - } - - last_update.insert(socket_id.clone(), now); - } - - info!("Received pixel update: {:?}", update); - let mut canvas = canvas.lock().unwrap(); - canvas[update.y as usize * 500 + update.x as usize] = update.color; - - info!("Emitting pixel update"); - socket.emit("pixel-updated", &update).ok(); // Send to the user who placed the pixel - socket.broadcast().emit("pixel-updated", &update).ok(); // Send to all other users - - info!("Memory usage after pixel update: "); - print_memory_usage(); - }, - ); - - socket.on_disconnect(move |socket: SocketRef| { - info!("Socket disconnected: {:?}", socket.id); - info!("Memory usage after disconnection: "); - print_memory_usage(); - let socket_id = socket.id.to_string(); - - { - let mut soldiers = soldiers.lock().unwrap(); - soldiers.remove(&socket_id.to_string()); - info!("Soldiers: {:?}", soldiers.len()); - - let soldiers_num = soldiers.len(); - socket - .broadcast() - .emit("current_soldiers", &soldiers_num) - .ok(); - } - - { - let mut last_update = last_update.lock().unwrap(); - last_update.remove(&socket_id); - - info!("Last update: {:?}", last_update.len()); - } - - info!("Memory usage after disconnection and cleanup: "); - print_memory_usage(); - }); -} - -fn print_memory_usage() { - if let Some(usage) = memory_stats() { - info!( - "Current physical memory usage: {} MB", - usage.physical_mem as f64 / 1024.0 / 1024.0 - ); - info!( - "Current virtual memory usage: {} MB", - usage.virtual_mem as f64 / 1024.0 / 1024.0 - ); - } -} - -async fn get_canvas_state(Extension(canvas): Extension) -> Json> { - let canvas = canvas.lock().unwrap(); - Json(canvas.clone()) -} - -#[tokio::main] -async fn main() -> Result<(), Box> { - dotenv::dotenv().ok(); - tracing::subscriber::set_global_default(FmtSubscriber::new())?; - - let rate_governor = Arc::new( - GovernorConfigBuilder::default() - .burst_size(10) - .per_second(10) - .finish() - .unwrap(), - ); - - let governor = rate_governor.limiter().clone(); - let interval = std::time::Duration::from_secs(1); - - tokio::spawn(async move { - loop { - tokio::time::sleep(interval).await; - governor.retain_recent(); - } - }); - - let (layer, io) = SocketIo::new_layer(); - - let canvas = Arc::new(Mutex::new(vec![0xFFFFFFFF; 500 * 500])); - let last_update = Arc::new(Mutex::new(HashMap::new())); - let soldiers = Arc::new(Mutex::new(HashSet::new())); - - let used_memory = std::mem::size_of_val(&*canvas) - + std::mem::size_of_val(&*last_update) - + std::mem::size_of_val(&*soldiers); - info!( - "Used memory of state: {} bytes, {} KB, {} MB", - used_memory, - used_memory / 1024, - used_memory / 1024 / 1024 - ); - - info!("Memory usage after state setup and before socket.io setup: "); - print_memory_usage(); - - let canvas_for_socket = canvas.clone(); - - io.ns("/", move |socket: SocketRef| { - tokio::spawn(on_connect( - socket, - canvas_for_socket.clone(), - last_update.clone(), - soldiers.clone(), - )); - }); - - info!("Memory usage after socket.io setup: "); - print_memory_usage(); - - let address = std::env::var("ADDRESS").unwrap_or_else(|_| "0.0.0.0".to_string()); - let port: u16 = std::env::var("PORT") - .unwrap_or_else(|_| "3000".to_string()) - .parse() - .expect("Invalid port"); - let enable_cors = std::env::var("ENABLE_CORS").unwrap_or_else(|_| "true".to_string()) == "true"; - - let cors = if enable_cors { - Some( - CorsLayer::new() - .allow_origin(Any) - .allow_methods(Any) - .allow_headers(Any), - ) - } else { - None - }; - - let app = Router::new() - .route("/canvas/", get(get_canvas_state)) - .route("/check/", get(|| async { "OK" })) - .fallback_service(ServeDir::new("dist/")) - .layer(GovernorLayer { - config: rate_governor, - }) - .layer(layer) - .layer(Extension(canvas.clone())); - - let app = if let Some(cors) = cors { - app.layer(cors) - } else { - app - }; - - let server_address = format!("{}:{}", address, port); - info!("Starting server on {}", server_address); - let listener = tokio::net::TcpListener::bind(server_address).await?; - axum::serve( - listener, - app.into_make_service_with_connect_info::(), - ) - .await?; - - Ok(()) -}