From d390f3ce54754f25f0df4e6e92454ad3b061302e Mon Sep 17 00:00:00 2001 From: feie9456 Date: Fri, 27 Jun 2025 09:08:17 +0800 Subject: [PATCH] first commit --- .gitignore | 3 + Cargo.lock | 3939 +++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 11 + readme.txt | 6 + src/assets/icon.bin | Bin 0 -> 65536 bytes src/huffman.rs | 427 +++++ src/lib.rs | 27 + src/lz77.rs | 378 +++++ src/main.rs | 765 +++++++++ 9 files changed, 5556 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 readme.txt create mode 100644 src/assets/icon.bin create mode 100644 src/huffman.rs create mode 100644 src/lib.rs create mode 100644 src/lz77.rs create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bd787a3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target + +.idea \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..859cf99 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,3939 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "ab_glyph" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3672c180e71eeaaac3a541fbbc5f5ad4def8b747c595ad30d674e43049f7b0" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" + +[[package]] +name = "accesskit" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3d3b8f9bae46a948369bc4a03e815d4ed6d616bd00de4051133a5019dc31c5a" + +[[package]] +name = "accesskit_atspi_common" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c5dd55e6e94949498698daf4d48fb5659e824d7abec0d394089656ceaf99d4f" +dependencies = [ + "accesskit", + "accesskit_consumer", + "atspi-common", + "serde", + "thiserror", + "zvariant 4.2.0", +] + +[[package]] +name = "accesskit_consumer" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f47983a1084940ba9a39c077a8c63e55c619388be5476ac04c804cfbd1e63459" +dependencies = [ + "accesskit", + "hashbrown", + "immutable-chunkmap", +] + +[[package]] +name = "accesskit_macos" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7329821f3bd1101e03a7d2e03bd339e3ac0dc64c70b4c9f9ae1949e3ba8dece1" +dependencies = [ + "accesskit", + "accesskit_consumer", + "hashbrown", + "objc2", + "objc2-app-kit", + "objc2-foundation", +] + +[[package]] +name = "accesskit_unix" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcee751cc20d88678c33edaf9c07e8b693cd02819fe89053776f5313492273f5" +dependencies = [ + "accesskit", + "accesskit_atspi_common", + "async-channel", + "async-executor", + "async-task", + "atspi", + "futures-lite", + "futures-util", + "serde", + "zbus 4.4.0", +] + +[[package]] +name = "accesskit_windows" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24fcd5d23d70670992b823e735e859374d694a3d12bfd8dd32bd3bd8bedb5d81" +dependencies = [ + "accesskit", + "accesskit_consumer", + "hashbrown", + "paste", + "static_assertions", + "windows", + "windows-core", +] + +[[package]] +name = "accesskit_winit" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6a48dad5530b6deb9fc7a52cc6c3bf72cdd9eb8157ac9d32d69f2427a5e879" +dependencies = [ + "accesskit", + "accesskit_macos", + "accesskit_unix", + "accesskit_windows", + "raw-window-handle", + "winit", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "android-activity" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" +dependencies = [ + "android-properties", + "bitflags 2.6.0", + "cc", + "cesu8", + "jni", + "jni-sys", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys 0.6.0+11769913", + "num_enum", + "thiserror", +] + +[[package]] +name = "android-properties" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "arboard" +version = "3.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df099ccb16cd014ff054ac1bf392c67feeef57164b05c42f037cd40f5d4357f4" +dependencies = [ + "clipboard-win", + "log", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "parking_lot", + "x11rb", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "as-raw-xcb-connection" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" + +[[package]] +name = "ash" +version = "0.38.0+1.3.281" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" +dependencies = [ + "libloading", +] + +[[package]] +name = "ashpd" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9c39d707614dbcc6bed00015539f488d8e3fe3e66ed60961efc0c90f4b380b3" +dependencies = [ + "async-fs", + "async-net", + "enumflags2", + "futures-channel", + "futures-util", + "rand", + "raw-window-handle", + "serde", + "serde_repr", + "url", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "zbus 5.2.0", +] + +[[package]] +name = "async-broadcast" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" +dependencies = [ + "event-listener", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-fs" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" +dependencies = [ + "async-lock", + "blocking", + "futures-lite", +] + +[[package]] +name = "async-io" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" +dependencies = [ + "async-lock", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-net" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" +dependencies = [ + "async-io", + "blocking", + "futures-lite", +] + +[[package]] +name = "async-process" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" +dependencies = [ + "async-channel", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener", + "futures-lite", + "rustix", + "tracing", +] + +[[package]] +name = "async-recursion" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-signal" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix", + "signal-hook-registry", + "slab", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1244b10dcd56c92219da4e14caa97e312079e185f04ba3eea25061561dc0a0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "atspi" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be534b16650e35237bb1ed189ba2aab86ce65e88cc84c66f4935ba38575cecbf" +dependencies = [ + "atspi-common", + "atspi-connection", + "atspi-proxies", +] + +[[package]] +name = "atspi-common" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1909ed2dc01d0a17505d89311d192518507e8a056a48148e3598fef5e7bb6ba7" +dependencies = [ + "enumflags2", + "serde", + "static_assertions", + "zbus 4.4.0", + "zbus-lockstep", + "zbus-lockstep-macros", + "zbus_names 3.0.0", + "zvariant 4.2.0", +] + +[[package]] +name = "atspi-connection" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "430c5960624a4baaa511c9c0fcc2218e3b58f5dbcc47e6190cafee344b873333" +dependencies = [ + "atspi-common", + "atspi-proxies", + "futures-lite", + "zbus 4.4.0", +] + +[[package]] +name = "atspi-proxies" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e6c5de3e524cf967569722446bcd458d5032348554d9a17d7d72b041ab7496" +dependencies = [ + "atspi-common", + "serde", + "zbus 4.4.0", + "zvariant 4.2.0", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +dependencies = [ + "objc2", +] + +[[package]] +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bytemuck" +version = "1.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "bytes" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" + +[[package]] +name = "calloop" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" +dependencies = [ + "bitflags 2.6.0", + "log", + "polling", + "rustix", + "slab", + "thiserror", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" +dependencies = [ + "calloop", + "rustix", + "wayland-backend", + "wayland-client", +] + +[[package]] +name = "cc" +version = "1.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "cgl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" +dependencies = [ + "libc", +] + +[[package]] +name = "clipboard-win" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892" +dependencies = [ + "error-code", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "compresscsdesign" +version = "0.1.0" +dependencies = [ + "crc32fast", + "eframe", + "egui-notify", + "rfd", + "sha2", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core-graphics" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cursor-icon" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading", +] + +[[package]] +name = "document-features" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" +dependencies = [ + "litrs", +] + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "dpi" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" + +[[package]] +name = "ecolor" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d72e9c39f6e11a2e922d04a34ec5e7ef522ea3f5a1acfca7a19d16ad5fe50f5" +dependencies = [ + "bytemuck", + "emath", +] + +[[package]] +name = "eframe" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2f2d9e7ea2d11ec9e98a8683b6eb99f9d7d0448394ef6e0d6d91bd4eb817220" +dependencies = [ + "ahash", + "bytemuck", + "document-features", + "egui", + "egui-wgpu", + "egui-winit", + "egui_glow", + "glow 0.16.0", + "glutin", + "glutin-winit", + "image", + "js-sys", + "log", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "parking_lot", + "percent-encoding", + "profiling", + "raw-window-handle", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "web-time", + "winapi", + "windows-sys 0.59.0", + "winit", +] + +[[package]] +name = "egui" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "252d52224d35be1535d7fd1d6139ce071fb42c9097773e79f7665604f5596b5e" +dependencies = [ + "accesskit", + "ahash", + "emath", + "epaint", + "log", + "nohash-hasher", + "profiling", +] + +[[package]] +name = "egui-notify" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4bc3995feb2e3f2ab66c9ccbf0e6df8df7c00c612bd8ac5af16b6c8db44146c" +dependencies = [ + "egui", +] + +[[package]] +name = "egui-wgpu" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c1e821d2d8921ef6ce98b258c7e24d9d6aab2ca1f9cdf374eca997e7f67f59" +dependencies = [ + "ahash", + "bytemuck", + "document-features", + "egui", + "epaint", + "log", + "profiling", + "thiserror", + "type-map", + "web-time", + "wgpu", + "winit", +] + +[[package]] +name = "egui-winit" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e84c2919cd9f3a38a91e8f84ac6a245c19251fd95226ed9fae61d5ea564fce3" +dependencies = [ + "accesskit_winit", + "ahash", + "arboard", + "egui", + "log", + "profiling", + "raw-window-handle", + "smithay-clipboard", + "web-time", + "webbrowser", + "winit", +] + +[[package]] +name = "egui_glow" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eaf6264cc7608e3e69a7d57a6175f438275f1b3889c1a551b418277721c95e6" +dependencies = [ + "ahash", + "bytemuck", + "egui", + "glow 0.16.0", + "log", + "memoffset", + "profiling", + "wasm-bindgen", + "web-sys", + "winit", +] + +[[package]] +name = "emath" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4fe73c1207b864ee40aa0b0c038d6092af1030744678c60188a05c28553515d" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "endi" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" + +[[package]] +name = "enumflags2" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "epaint" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5666f8d25236293c966fbb3635eac18b04ad1914e3bab55bc7d44b9980cafcac" +dependencies = [ + "ab_glyph", + "ahash", + "bytemuck", + "ecolor", + "emath", + "epaint_default_fonts", + "log", + "nohash-hasher", + "parking_lot", + "profiling", +] + +[[package]] +name = "epaint_default_fonts" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66f6ddac3e6ac6fd4c3d48bb8b1943472f8da0f43a4303bcd8a18aa594401c80" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "error-code" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f" + +[[package]] +name = "event-listener" +version = "5.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" +dependencies = [ + "event-listener", + "pin-project-lite", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "flate2" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "foldhash" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-lite" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "gethostname" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +dependencies = [ + "libc", + "windows-targets 0.48.5", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + +[[package]] +name = "glow" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51fa363f025f5c111e03f13eda21162faeacb6911fe8caa0c0349f9cf0c4483" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glow" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e5ea60d70410161c8bf5da3fdfeaa1c72ed2c15f8bbb9d19fe3a4fad085f08" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glutin" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec69412a0bf07ea7607e638b415447857a808846c2b685a43c8aa18bc6d5e499" +dependencies = [ + "bitflags 2.6.0", + "cfg_aliases 0.2.1", + "cgl", + "core-foundation 0.9.4", + "dispatch", + "glutin_egl_sys", + "glutin_glx_sys", + "glutin_wgl_sys", + "libloading", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "once_cell", + "raw-window-handle", + "wayland-sys", + "windows-sys 0.52.0", + "x11-dl", +] + +[[package]] +name = "glutin-winit" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85edca7075f8fc728f28cb8fbb111a96c3b89e930574369e3e9c27eb75d3788f" +dependencies = [ + "cfg_aliases 0.2.1", + "glutin", + "raw-window-handle", + "winit", +] + +[[package]] +name = "glutin_egl_sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cae99fff4d2850dbe6fb8c1fa8e4fead5525bab715beaacfccf3fb994e01c827" +dependencies = [ + "gl_generator", + "windows-sys 0.52.0", +] + +[[package]] +name = "glutin_glx_sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c2b2d3918e76e18e08796b55eb64e8fe6ec67d5a6b2e2a7e2edce224ad24c63" +dependencies = [ + "gl_generator", + "x11-dl", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a4e1951bbd9434a81aa496fe59ccc2235af3820d27b85f9314e279609211e2c" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "gpu-alloc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" +dependencies = [ + "bitflags 2.6.0", + "gpu-alloc-types", +] + +[[package]] +name = "gpu-alloc-types" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "gpu-descriptor" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf29e94d6d243368b7a56caa16bc213e4f9f8ed38c4d9557069527b5d5281ca" +dependencies = [ + "bitflags 2.6.0", + "gpu-descriptor-types", + "hashbrown", +] + +[[package]] +name = "gpu-descriptor-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hexf-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" + +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "image" +version = "0.25.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b" +dependencies = [ + "bytemuck", + "byteorder-lite", + "num-traits", + "png", +] + +[[package]] +name = "immutable-chunkmap" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f97096f508d54f8f8ab8957862eee2ccd628847b6217af1a335e1c44dee578" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "indexmap" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "khronos-egl" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" +dependencies = [ + "libc", + "libloading", + "pkg-config", +] + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + +[[package]] +name = "libc" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "libloading" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +dependencies = [ + "cfg-if", + "windows-targets 0.52.6", +] + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", + "redox_syscall 0.5.8", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memmap2" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "metal" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21" +dependencies = [ + "bitflags 2.6.0", + "block", + "core-graphics-types", + "foreign-types", + "log", + "objc", + "paste", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "naga" +version = "23.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "364f94bc34f61332abebe8cad6f6cd82a5b65cff22c828d05d0968911462ca4f" +dependencies = [ + "arrayvec", + "bit-set", + "bitflags 2.6.0", + "cfg_aliases 0.1.1", + "codespan-reporting", + "hexf-parse", + "indexmap", + "log", + "rustc-hash", + "spirv", + "termcolor", + "thiserror", + "unicode-xid", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.6.0", + "jni-sys", + "log", + "ndk-sys 0.6.0+11769913", + "num_enum", + "raw-window-handle", + "thiserror", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.5.0+25.2.9519653" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "cfg_aliases 0.2.1", + "libc", + "memoffset", +] + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[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_enum" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags 2.6.0", + "block2", + "libc", + "objc2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation", + "objc2-quartz-core", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-image" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-core-location" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +dependencies = [ + "block2", + "objc2", + "objc2-contacts", + "objc2-foundation", +] + +[[package]] +name = "objc2-encode" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.6.0", + "block2", + "dispatch", + "libc", + "objc2", +] + +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2", + "objc2", + "objc2-app-kit", + "objc2-foundation", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation", + "objc2-link-presentation", + "objc2-quartz-core", + "objc2-symbols", + "objc2-uniform-type-identifiers", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-uniform-type-identifiers" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "orbclient" +version = "0.3.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba0b26cec2e24f08ed8bb31519a9333140a6599b867dac464bb150bdb796fd43" +dependencies = [ + "libredox", +] + +[[package]] +name = "ordered-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "owned_ttf_parser" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec719bbf3b2a81c109a4e20b1f129b5566b7dce654bc3872f6a05abf82b2c4" +dependencies = [ + "ttf-parser", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.5.8", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "png" +version = "0.17.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "polling" +version = "3.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "pollster" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "profiling" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" + +[[package]] +name = "quick-xml" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "quick-xml" +version = "0.36.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe" +dependencies = [ + "memchr", +] + +[[package]] +name = "quote" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "renderdoc-sys" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" + +[[package]] +name = "rfd" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a24763657bff09769a8ccf12c8b8a50416fb035fe199263b4c5071e4e3f006f" +dependencies = [ + "ashpd", + "block2", + "core-foundation 0.10.0", + "core-foundation-sys", + "js-sys", + "log", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "pollster", + "raw-window-handle", + "urlencoding", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", +] + +[[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 = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sctk-adwaita" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" +dependencies = [ + "ab_glyph", + "log", + "memmap2", + "smithay-client-toolkit", + "tiny-skia", +] + +[[package]] +name = "serde" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "smithay-client-toolkit" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" +dependencies = [ + "bitflags 2.6.0", + "calloop", + "calloop-wayland-source", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix", + "thiserror", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", +] + +[[package]] +name = "smithay-clipboard" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc8216eec463674a0e90f29e0ae41a4db573ec5b56b1c6c1c71615d249b6d846" +dependencies = [ + "libc", + "smithay-client-toolkit", + "wayland-backend", +] + +[[package]] +name = "smol_str" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +dependencies = [ + "serde", +] + +[[package]] +name = "spirv" +version = "0.3.0+sdk-1.3.268.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strict-num" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" + +[[package]] +name = "syn" +version = "2.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tempfile" +version = "3.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" +dependencies = [ + "cfg-if", + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tiny-skia" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" +dependencies = [ + "arrayref", + "arrayvec", + "bytemuck", + "cfg-if", + "log", + "tiny-skia-path", +] + +[[package]] +name = "tiny-skia-path" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" +dependencies = [ + "arrayref", + "bytemuck", + "strict-num", +] + +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", +] + +[[package]] +name = "ttf-parser" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" + +[[package]] +name = "type-map" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deb68604048ff8fa93347f02441e4487594adc20bb8a084f9e564d2b827a0a9f" +dependencies = [ + "rustc-hash", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "uds_windows" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" +dependencies = [ + "memoffset", + "tempfile", + "winapi", +] + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[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 = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" + +[[package]] +name = "wayland-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6" +dependencies = [ + "cc", + "downcast-rs", + "rustix", + "scoped-tls", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-client" +version = "0.31.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66249d3fc69f76fd74c82cc319300faa554e9d865dab1f7cd66cc20db10b280" +dependencies = [ + "bitflags 2.6.0", + "rustix", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-csd-frame" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" +dependencies = [ + "bitflags 2.6.0", + "cursor-icon", + "wayland-backend", +] + +[[package]] +name = "wayland-cursor" +version = "0.31.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b08bc3aafdb0035e7fe0fdf17ba0c09c268732707dca4ae098f60cb28c9e4c" +dependencies = [ + "rustix", + "wayland-client", + "xcursor", +] + +[[package]] +name = "wayland-protocols" +version = "0.32.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd0ade57c4e6e9a8952741325c30bf82f4246885dca8bf561898b86d0c1f58e" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-plasma" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b31cab548ee68c7eb155517f2212049dc151f7cd7910c2b66abfd31c3ee12bd" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "782e12f6cd923c3c316130d56205ebab53f55d6666b7faddfad36cecaeeb4022" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3" +dependencies = [ + "proc-macro2", + "quick-xml 0.36.2", + "quote", +] + +[[package]] +name = "wayland-sys" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efa8ac0d8e8ed3e3b5c9fc92c7881406a268e11555abe36493efabe649a29e09" +dependencies = [ + "dlib", + "log", + "once_cell", + "pkg-config", +] + +[[package]] +name = "web-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +dependencies = [ + "js-sys", + "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 = "webbrowser" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea9fe1ebb156110ff855242c1101df158b822487e4957b0556d9ffce9db0f535" +dependencies = [ + "block2", + "core-foundation 0.10.0", + "home", + "jni", + "log", + "ndk-context", + "objc2", + "objc2-foundation", + "url", + "web-sys", +] + +[[package]] +name = "wgpu" +version = "23.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80f70000db37c469ea9d67defdc13024ddf9a5f1b89cb2941b812ad7cde1735a" +dependencies = [ + "arrayvec", + "cfg_aliases 0.1.1", + "document-features", + "js-sys", + "log", + "parking_lot", + "profiling", + "raw-window-handle", + "smallvec", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-core" +version = "23.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d63c3c478de8e7e01786479919c8769f62a22eec16788d8c2ac77ce2c132778a" +dependencies = [ + "arrayvec", + "bit-vec", + "bitflags 2.6.0", + "cfg_aliases 0.1.1", + "document-features", + "indexmap", + "log", + "naga", + "once_cell", + "parking_lot", + "profiling", + "raw-window-handle", + "rustc-hash", + "smallvec", + "thiserror", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-hal" +version = "23.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89364b8a0b211adc7b16aeaf1bd5ad4a919c1154b44c9ce27838213ba05fd821" +dependencies = [ + "android_system_properties", + "arrayvec", + "ash", + "bitflags 2.6.0", + "bytemuck", + "cfg_aliases 0.1.1", + "core-graphics-types", + "glow 0.14.2", + "glutin_wgl_sys", + "gpu-alloc", + "gpu-descriptor", + "js-sys", + "khronos-egl", + "libc", + "libloading", + "log", + "metal", + "naga", + "ndk-sys 0.5.0+25.2.9519653", + "objc", + "once_cell", + "parking_lot", + "profiling", + "raw-window-handle", + "renderdoc-sys", + "rustc-hash", + "smallvec", + "thiserror", + "wasm-bindgen", + "web-sys", + "wgpu-types", + "windows", +] + +[[package]] +name = "wgpu-types" +version = "23.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "610f6ff27778148c31093f3b03abc4840f9636d58d597ca2f5977433acfe0068" +dependencies = [ + "bitflags 2.6.0", + "js-sys", + "web-sys", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[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.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[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", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winit" +version = "0.30.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d74280aabb958072864bff6cfbcf9025cf8bfacdde5e32b5e12920ef703b0f" +dependencies = [ + "ahash", + "android-activity", + "atomic-waker", + "bitflags 2.6.0", + "block2", + "bytemuck", + "calloop", + "cfg_aliases 0.2.1", + "concurrent-queue", + "core-foundation 0.9.4", + "core-graphics", + "cursor-icon", + "dpi", + "js-sys", + "libc", + "memmap2", + "ndk", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", + "orbclient", + "percent-encoding", + "pin-project", + "raw-window-handle", + "redox_syscall 0.4.1", + "rustix", + "sctk-adwaita", + "smithay-client-toolkit", + "smol_str", + "tracing", + "unicode-segmentation", + "wasm-bindgen", + "wasm-bindgen-futures", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-protocols-plasma", + "web-sys", + "web-time", + "windows-sys 0.52.0", + "x11-dl", + "x11rb", + "xkbcommon-dl", +] + +[[package]] +name = "winnow" +version = "0.6.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39281189af81c07ec09db316b302a3e67bf9bd7cbf6c820b50e35fee9c2fa980" +dependencies = [ + "memchr", +] + +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "x11rb" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" +dependencies = [ + "as-raw-xcb-connection", + "gethostname", + "libc", + "libloading", + "once_cell", + "rustix", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" + +[[package]] +name = "xcursor" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef33da6b1660b4ddbfb3aef0ade110c8b8a781a3b6382fa5f2b5b040fd55f61" + +[[package]] +name = "xdg-home" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "xkbcommon-dl" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" +dependencies = [ + "bitflags 2.6.0", + "dlib", + "log", + "once_cell", + "xkeysym", +] + +[[package]] +name = "xkeysym" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" + +[[package]] +name = "xml-rs" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea8b391c9a790b496184c29f7f93b9ed5b16abb306c05415b68bcc16e4d06432" + +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zbus" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725" +dependencies = [ + "async-broadcast", + "async-executor", + "async-fs", + "async-io", + "async-lock", + "async-process", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "enumflags2", + "event-listener", + "futures-core", + "futures-sink", + "futures-util", + "hex", + "nix", + "ordered-stream", + "rand", + "serde", + "serde_repr", + "sha1", + "static_assertions", + "tracing", + "uds_windows", + "windows-sys 0.52.0", + "xdg-home", + "zbus_macros 4.4.0", + "zbus_names 3.0.0", + "zvariant 4.2.0", +] + +[[package]] +name = "zbus" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb67eadba43784b6fb14857eba0d8fc518686d3ee537066eb6086dc318e2c8a1" +dependencies = [ + "async-broadcast", + "async-executor", + "async-fs", + "async-io", + "async-lock", + "async-process", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "enumflags2", + "event-listener", + "futures-core", + "futures-util", + "hex", + "nix", + "ordered-stream", + "serde", + "serde_repr", + "static_assertions", + "tracing", + "uds_windows", + "windows-sys 0.59.0", + "winnow", + "xdg-home", + "zbus_macros 5.2.0", + "zbus_names 4.1.0", + "zvariant 5.1.0", +] + +[[package]] +name = "zbus-lockstep" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca2c5dceb099bddaade154055c926bb8ae507a18756ba1d8963fd7b51d8ed1d" +dependencies = [ + "zbus_xml", + "zvariant 4.2.0", +] + +[[package]] +name = "zbus-lockstep-macros" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709ab20fc57cb22af85be7b360239563209258430bccf38d8b979c5a2ae3ecce" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "zbus-lockstep", + "zbus_xml", + "zvariant 4.2.0", +] + +[[package]] +name = "zbus_macros" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", + "zvariant_utils 2.1.0", +] + +[[package]] +name = "zbus_macros" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d49ebc960ceb660f2abe40a5904da975de6986f2af0d7884b39eec6528c57" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", + "zbus_names 4.1.0", + "zvariant 5.1.0", + "zvariant_utils 3.0.2", +] + +[[package]] +name = "zbus_names" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" +dependencies = [ + "serde", + "static_assertions", + "zvariant 4.2.0", +] + +[[package]] +name = "zbus_names" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "856b7a38811f71846fd47856ceee8bccaec8399ff53fb370247e66081ace647b" +dependencies = [ + "serde", + "static_assertions", + "winnow", + "zvariant 5.1.0", +] + +[[package]] +name = "zbus_xml" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3f374552b954f6abb4bd6ce979e6c9b38fb9d0cd7cc68a7d796e70c9f3a233" +dependencies = [ + "quick-xml 0.30.0", + "serde", + "static_assertions", + "zbus_names 3.0.0", + "zvariant 4.2.0", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zvariant" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe" +dependencies = [ + "endi", + "enumflags2", + "serde", + "static_assertions", + "zvariant_derive 4.2.0", +] + +[[package]] +name = "zvariant" +version = "5.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1200ee6ac32f1e5a312e455a949a4794855515d34f9909f4a3e082d14e1a56f" +dependencies = [ + "endi", + "enumflags2", + "serde", + "static_assertions", + "url", + "winnow", + "zvariant_derive 5.1.0", + "zvariant_utils 3.0.2", +] + +[[package]] +name = "zvariant_derive" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", + "zvariant_utils 2.1.0", +] + +[[package]] +name = "zvariant_derive" +version = "5.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "687e3b97fae6c9104fbbd36c73d27d149abf04fb874e2efbd84838763daa8916" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", + "zvariant_utils 3.0.2", +] + +[[package]] +name = "zvariant_utils" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zvariant_utils" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20d1d011a38f12360e5fcccceeff5e2c42a8eb7f27f0dcba97a0862ede05c9c6" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "static_assertions", + "syn", + "winnow", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..72ca05a --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "compresscsdesign" +version = "0.1.0" +edition = "2021" + +[dependencies] +eframe = "0.30.0" +rfd = "0.15.2" +egui-notify = "0.18.0" +crc32fast = "1.3" +sha2 = "0.10" diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..7ad124b --- /dev/null +++ b/readme.txt @@ -0,0 +1,6 @@ +构建流程: + +1. 安装 Rust 和 Cargo 环境 +2. 运行 cargo run 进行调试 +3. 运行 cargo build -r 构建可执行文件 +(已构建 Windows 下可执行文件 "鹅鹅文件压缩器.exe" 于当前目录,可直接运行) \ No newline at end of file diff --git a/src/assets/icon.bin b/src/assets/icon.bin new file mode 100644 index 0000000000000000000000000000000000000000..0dfd0a587645ae1fed67ae0758a6398739c94698 GIT binary patch literal 65536 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, + left: Option>, + right: Option>, +} + +// ----------------------------------------------------- +// 实现 Ord/PartialOrd,使得 BinaryHeap 成为最小堆 +// ----------------------------------------------------- +impl PartialOrd for Node { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Node { + fn cmp(&self, other: &Self) -> Ordering { + // BinaryHeap 默认是大顶堆,但我们想要小顶堆效果,所以反转 freq + other.freq.cmp(&self.freq) + } +} + +/// 构建 Huffman 树 +fn build_huffman_tree(freq_map: &HashMap) -> Option> { + if freq_map.is_empty() { + return None; + } + // 按字节升序排序,保证同频时顺序稳定 + let mut keys: Vec = freq_map.keys().cloned().collect(); + keys.sort_unstable(); + + let mut heap = BinaryHeap::new(); + for b in keys { + heap.push(Node { + freq: freq_map[&b], + byte: Some(b), + left: None, + right: None, + }); + } + + while heap.len() > 1 { + let n1 = heap.pop().unwrap(); + let n2 = heap.pop().unwrap(); + let parent = Node { + freq: n1.freq + n2.freq, + byte: None, + left: Some(Box::new(n1)), + right: Some(Box::new(n2)), + }; + heap.push(parent); + } + + let root = heap.pop().map(Box::new); + + root +} + +/// 递归遍历 Huffman 树,构建 (字节 -> 比特序列) 的 map +fn build_code_map(node: &Node, prefix: Vec, code_map: &mut HashMap>) { + if let Some(b) = node.byte { + // 如果树只有一个节点,prefix 会是空,强行给它 [0] + if prefix.is_empty() { + code_map.insert(b, vec![0]); + } else { + code_map.insert(b, prefix); + } + return; + } + // 否则继续往左右子节点 + if let Some(ref left) = node.left { + let mut left_path = prefix.clone(); + left_path.push(0); + build_code_map(left, left_path, code_map); + } + if let Some(ref right) = node.right { + let mut right_path = prefix.clone(); + right_path.push(1); + build_code_map(right, right_path, code_map); + } +} + +// ----------------------------------------------------- +// BitWriter: 将比特流写入内存 buffer +// ----------------------------------------------------- +struct BitWriter { + buffer: Vec, + current_byte: u8, + bit_count: u8, +} + +impl BitWriter { + fn new() -> Self { + Self { + buffer: Vec::new(), + current_byte: 0, + bit_count: 0, + } + } + + fn write_bit(&mut self, bit: u8) { + self.current_byte = (self.current_byte << 1) | (bit & 1); + self.bit_count += 1; + if self.bit_count == 8 { + self.buffer.push(self.current_byte); + self.current_byte = 0; + self.bit_count = 0; + } + } + + fn flush(&mut self) { + if self.bit_count > 0 { + self.current_byte <<= 8 - self.bit_count; + self.buffer.push(self.current_byte); + self.current_byte = 0; + self.bit_count = 0; + } + } + + fn into_inner(mut self) -> Vec { + self.flush(); + self.buffer + } +} + +// ----------------------------------------------------- +// BitReader: 从内存切片逐比特读 +// ----------------------------------------------------- +struct BitReader<'a> { + data: &'a [u8], + byte_pos: usize, + bit_pos: u8, +} + +impl<'a> BitReader<'a> { + fn new(data: &'a [u8]) -> Self { + Self { + data, + byte_pos: 0, + bit_pos: 0, + } + } + + fn read_bit(&mut self) -> Option { + if self.byte_pos >= self.data.len() { + return None; + } + let byte = self.data[self.byte_pos]; + let bit = (byte >> (7 - self.bit_pos)) & 1; + self.bit_pos += 1; + if self.bit_pos == 8 { + self.bit_pos = 0; + self.byte_pos += 1; + } + Some(bit) + } +} + +pub fn encode_stream( + mut input: R, + mut output: W, + onprogress: &mut impl FnMut(usize), + mut debug_out: Option<&mut D>, +) -> io::Result<()> { + // 1) 先把所有输入读到内存 + let mut buf = [0u8; 8192]; + let mut data = Vec::new(); + + let mut total_read = 0usize; + let mut last_reported = 0usize; + const REPORT_THRESHOLD: usize = 16 * 1024; // 16KB + + loop { + let n = input.read(&mut buf)?; + if n == 0 { + break; + } + data.extend_from_slice(&buf[..n]); + total_read += n; + + // 进度回调 + if total_read.saturating_sub(last_reported) >= REPORT_THRESHOLD { + onprogress(total_read); + last_reported = total_read; + } + } + // 结束读输入时再更新一次 + onprogress(total_read); + + // 2) 构建 freq_map + let mut freq_map = HashMap::new(); + for &b in &data { + *freq_map.entry(b).or_insert(0) += 1; + } + + // 3) 构建 Huffman 树 & code_map + let root = build_huffman_tree(&freq_map).unwrap(); + let mut code_map = HashMap::new(); + build_code_map(&root, Vec::new(), &mut code_map); + + // 如果有 debug_out => 输出 frequency table + if let Some(ref mut dbg) = debug_out { + writeln!(dbg, "[Huffman encode] freq_map:")?; + for (&byte, &freq) in &freq_map { + writeln!(dbg, " byte = {:02X}, freq = {}", byte, freq)?; + } + writeln!(dbg, "[Huffman encode] code_map:")?; + for (&byte, code_bits) in &code_map { + // 将 bit 序列拼成字符串 + let bits_str = code_bits + .iter() + .map(|b| if *b == 0 { '0' } else { '1' }) + .collect::(); + writeln!(dbg, " byte = {:02X}, code = {}", byte, bits_str)?; + } + } + + // 4) 写 freq_table (256 个 u32,小端序) + { + let mut freq_array = vec![0u32; 256]; + for (&b, &f) in &freq_map { + freq_array[b as usize] = f; + } + let mut freq_table_bytes = Vec::with_capacity(256 * 4); + for &f in &freq_array { + freq_table_bytes.extend_from_slice(&f.to_le_bytes()); + } + output.write_all(&freq_table_bytes)?; + } + + // 5) 利用 code_map 把 data 编码为 bit_stream + let mut bit_writer = BitWriter::new(); + let mut total_bits: u32 = 0; + for &b in &data { + if let Some(bits) = code_map.get(&b) { + for &bit in bits { + bit_writer.write_bit(bit); + total_bits += 1; + } + } + } + bit_writer.flush(); + let bit_stream = bit_writer.into_inner(); + + // 6) 写 total_bits + output.write_all(&total_bits.to_le_bytes())?; + // 7) 写 bit_stream + output.write_all(&bit_stream)?; + + // 结束时 debug + if let Some(ref mut dbg) = debug_out { + writeln!( + dbg, + "[Huffman encode] data_len = {}, total_bits = {}, bit_stream_len(bytes) = {}", + data.len(), + total_bits, + bit_stream.len() + )?; + } + + Ok(()) +} + +pub fn decode_stream( + mut input: R, + mut output: W, + onprogress: &mut impl FnMut(usize), + mut debug_out: Option<&mut D>, +) -> io::Result<()> { + let mut total_read = 0usize; + let mut last_reported = 0usize; + const REPORT_THRESHOLD: usize = 16 * 1024; // 16KB + + // 帮助函数:读取固定大小到 buffer,并更新进度 + fn read_exact_progress( + reader: &mut R, + buf: &mut [u8], + total_read: &mut usize, + last_reported: &mut usize, + onprogress: &mut impl FnMut(usize), + ) -> io::Result<()> { + let mut offset = 0; + while offset < buf.len() { + let n = reader.read(&mut buf[offset..])?; + if n == 0 { + return Err(io::Error::new( + io::ErrorKind::UnexpectedEof, + "Unexpected EOF while reading Huffman stream", + )); + } + offset += n; + *total_read += n; + + // 回调 + if total_read.saturating_sub(*last_reported) >= REPORT_THRESHOLD { + onprogress(*total_read); + *last_reported = *total_read; + } + } + Ok(()) + } + + // 1) 读取 freq_table + let mut freq_table_bytes = vec![0u8; 256 * 4]; + read_exact_progress( + &mut input, + &mut freq_table_bytes, + &mut total_read, + &mut last_reported, + onprogress, + )?; + + // 2) 构造 freq_map + let mut freq_map = HashMap::new(); + for i in 0..256 { + let freq = u32::from_le_bytes([ + freq_table_bytes[i * 4], + freq_table_bytes[i * 4 + 1], + freq_table_bytes[i * 4 + 2], + freq_table_bytes[i * 4 + 3], + ]); + if freq > 0 { + freq_map.insert(i as u8, freq); + } + } + + // 如果有 debug_out => 输出 frequency table + if let Some(ref mut dbg) = debug_out { + writeln!(dbg, "[Huffman decode] freq_map:")?; + for (&byte, &freq) in &freq_map { + writeln!(dbg, " byte = {:02X}, freq = {}", byte, freq)?; + } + } + + // 3) 重建 Huffman 树 + let root = build_huffman_tree(&freq_map).ok_or_else(|| { + io::Error::new( + io::ErrorKind::InvalidData, + "Invalid Huffman frequency table", + ) + })?; + + // 4) 读取 total_bits + let mut total_bits_buf = [0u8; 4]; + read_exact_progress( + &mut input, + &mut total_bits_buf, + &mut total_read, + &mut last_reported, + onprogress, + )?; + let total_bits = u32::from_le_bytes(total_bits_buf) as usize; + + // 5) 读取 bit_stream + let bit_stream_len = (total_bits + 7) / 8; + let mut bit_stream = vec![0u8; bit_stream_len]; + if bit_stream_len > 0 { + read_exact_progress( + &mut input, + &mut bit_stream, + &mut total_read, + &mut last_reported, + onprogress, + )?; + } + + onprogress(total_read); + + // 6) 解码 + let mut bit_reader = BitReader::new(&bit_stream); + let mut decoded_buffer = Vec::with_capacity(8192); + let mut current_node = &root; + + for _ in 0..total_bits { + let bit = bit_reader + .read_bit() + .ok_or_else(|| io::Error::new(io::ErrorKind::UnexpectedEof, "Bitstream ended early"))?; + if bit == 0 { + if let Some(ref left) = current_node.left { + current_node = left; + } else { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "Invalid Huffman bitstream: 0 leads to no left child", + )); + } + } else { + if let Some(ref right) = current_node.right { + current_node = right; + } else { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "Invalid Huffman bitstream: 1 leads to no right child", + )); + } + } + // 到达叶子节点 => 写入 + if let Some(b) = current_node.byte { + decoded_buffer.push(b); + current_node = &root; + if decoded_buffer.len() >= 8192 { + output.write_all(&decoded_buffer)?; + decoded_buffer.clear(); + } + } + } + + // 写剩余数据 + if !decoded_buffer.is_empty() { + output.write_all(&decoded_buffer)?; + } + + if let Some(ref mut dbg) = debug_out { + writeln!(dbg, "[Huffman decode] Decoding finished. total_bits = {}", total_bits)?; + } + + Ok(()) +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..552b5f7 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,27 @@ +use crc32fast::Hasher as Crc32Hasher; +use sha2::{Digest, Sha256}; +use std::fs::File; +use std::io::Read; +use std::path::Path; + +pub fn compute_crc32_and_sha256(path: &Path) -> (Option, Option) { + let mut file = match File::open(path) { + Ok(f) => f, + Err(_) => return (None, None), + }; + let mut buffer = Vec::new(); + if file.read_to_end(&mut buffer).is_err() { + return (None, None); + } + + let mut crc_hasher = Crc32Hasher::new(); + crc_hasher.update(&buffer); + let crc32 = Some(crc_hasher.finalize()); + + let mut sha_hasher = Sha256::new(); + sha_hasher.update(&buffer); + let result = sha_hasher.finalize(); + let sha256 = Some(format!("{:x}", result)); + + (crc32, sha256) +} diff --git a/src/lz77.rs b/src/lz77.rs new file mode 100644 index 0000000..f96255a --- /dev/null +++ b/src/lz77.rs @@ -0,0 +1,378 @@ +use std::{ + collections::VecDeque, + io::{self, Read, Write}, +}; + +#[derive(Debug, Clone, PartialEq)] +pub struct Token { + pub offset: u16, + pub length: u8, + pub next_char: u8, +} + +pub struct LZ77 { + pub window_size: usize, + pub lookahead_size: usize, +} + +impl LZ77 { + pub fn new(window_size: usize, lookahead_size: usize) -> Self { + Self { + window_size, + lookahead_size, + } + } + + /// 在 window 中寻找与 lookahead 最长的匹配,返回 (offset, length) (usize, usize)。 + fn find_longest_match(&self, window: &[u8], lookahead: &[u8]) -> (usize, usize) { + if lookahead.is_empty() || window.is_empty() { + return (0, 0); + } + + let mut best_len = 0usize; + let mut best_off = 0usize; + + // 从 window 尾部往前搜索 + for start in (0..window.len()).rev() { + let mut length = 0usize; + while length < lookahead.len() + && length < self.lookahead_size + && start + length < window.len() + && window[start + length] == lookahead[length] + { + length += 1; + } + + if length > best_len { + best_len = length; + best_off = window.len() - start; + if best_len == self.lookahead_size { + break; + } + } + } + + (best_off, best_len) + } + + /// 将「匹配 Token」编码成 4 字节 [offset(2bytes,LE), length(1byte), next_char(1byte)] + pub fn encode_token_to_bytes(token: &Token) -> [u8; 4] { + let offset_bytes = token.offset.to_le_bytes(); + [ + offset_bytes[0], + offset_bytes[1], + token.length, + token.next_char, + ] + } + + pub fn compress_stream( + &self, + mut input: R, + mut output: W, + onprogress: &mut impl FnMut(usize), + debug_out: Option<&mut D>, + ) -> io::Result<()> { + let mut window: VecDeque = VecDeque::new(); + let mut lookahead = Vec::new(); + lookahead.reserve(self.lookahead_size); + + let mut buffer = [0u8; 4096]; + + // 节流相关变量 + let mut total_read = 0usize; + let mut last_reported = 0usize; + const REPORT_THRESHOLD: usize = 16 * 1024; // 16KB + + // 用于统计调试信息 + let mut match_count = 0usize; + let mut total_match_length = 0usize; + + // 初次读 + let bytes_read = input.read(&mut buffer)?; + if bytes_read > 0 { + total_read += bytes_read; + onprogress(total_read); + } + lookahead.extend_from_slice(&buffer[..bytes_read]); + + // 用于暂存无法匹配的字面量 + let mut literal_buf: Vec = Vec::new(); + + // 函数内联,用来一次性写出字面量块 + let flush_literal_buf = |out: &mut W, buf: &mut Vec| -> io::Result<()> { + let run_len = buf.len(); + if run_len == 0 { + return Ok(()); + } + if run_len > 255 { + let mut start = 0; + while start < run_len { + let end = (start + 255).min(run_len); + let chunk_size = end - start; + + // 写头 [0,0, chunk_size, 0xFF] + let head = [0u8, 0u8, chunk_size as u8, 0xFF]; + out.write_all(&head)?; + + // 写 chunk_size 个字面量 + out.write_all(&buf[start..end])?; + + start = end; + } + } else { + // 写头 [0,0, run_len, 0xFF] + let head = [0u8, 0u8, run_len as u8, 0xFF]; + out.write_all(&head)?; + out.write_all(buf)?; + } + buf.clear(); + Ok(()) + }; + + while !lookahead.is_empty() { + // 若 lookahead 不足,则再读 + while lookahead.len() < self.lookahead_size { + match input.read(&mut buffer) { + Ok(0) => break, // EOF + Ok(n) => { + total_read += n; + if total_read - last_reported >= REPORT_THRESHOLD { + onprogress(total_read); + last_reported = total_read; + } + lookahead.extend_from_slice(&buffer[..n]); + } + Err(e) => return Err(e), + } + } + + // 在 window 中找最长匹配 + let window_slice: Vec = window.iter().copied().collect(); + let (offset, length) = self.find_longest_match(&window_slice, &lookahead); + + if length > 0 { + // 统计信息 + match_count += 1; + total_match_length += length; + + // 在此处先把字面量缓冲写出(如果有的话) + if !literal_buf.is_empty() { + flush_literal_buf(&mut output, &mut literal_buf)?; + } + + // 有匹配 => 写出一个匹配 Token + if length < lookahead.len() { + let next_char = lookahead[length]; + let token = Token { + offset: offset as u16, + length: length as u8, + next_char, + }; + output.write_all(&Self::encode_token_to_bytes(&token))?; + + // 更新 window + let advance = length + 1; + for _ in 0..advance { + if !lookahead.is_empty() { + window.push_back(lookahead.remove(0)); + if window.len() > self.window_size { + window.pop_front(); + } + } + } + } else { + // length == lookahead.len(),把最后的 next_char 逻辑改成逐字节写字面量 + for _ in 0..length { + if let Some(&byte) = lookahead.get(0) { + literal_buf.push(byte); + lookahead.remove(0); + window.push_back(byte); + if window.len() > self.window_size { + window.pop_front(); + } + } + } + } + } else { + // 无匹配 => 把 lookahead[0] 当字面量放进 literal_buf + let byte = lookahead.remove(0); + literal_buf.push(byte); + window.push_back(byte); + if window.len() > self.window_size { + window.pop_front(); + } + } + } + + // 文件处理结束后,可能还有剩余的字面量要一次性写出 + if !literal_buf.is_empty() { + flush_literal_buf(&mut output, &mut literal_buf)?; + } + + // 最后确保所有读的字节都已报告 + if total_read > last_reported { + onprogress(total_read); + } + + // 如果有 debug_out,就输出一下匹配统计等调试信息 + if let Some(dbg) = debug_out { + let avg_match_len = if match_count > 0 { + total_match_length as f64 / match_count as f64 + } else { + 0.0 + }; + writeln!( + dbg, + "[LZ77 compress] match_count = {}, total_match_length = {}, average_match_len = {:.2}", + match_count, total_match_length, avg_match_len + )?; + } + + Ok(()) + } + + pub fn decompress_stream( + &self, + mut input: R, + mut output: W, + onprogress: &mut impl FnMut(usize), + debug_out: Option<&mut D>, + ) -> io::Result<()> { + let mut ring_buffer = vec![0u8; 65536]; + let mut pos = 0usize; // 已经解出的字节数 + + let mut token_buf = [0u8; 4]; + + // 节流相关变量 + let mut total_read = 0usize; + let mut last_reported = 0usize; + const REPORT_THRESHOLD: usize = 16 * 1024; // 16KB + + // 统计信息 + let mut match_count = 0usize; + let mut total_match_length = 0usize; + let mut literal_count = 0usize; + + loop { + // 读取 4 字节 => 若 EOF 就结束 + let mut read_bytes = 0; + while read_bytes < 4 { + let n = input.read(&mut token_buf[read_bytes..])?; + if n == 0 { + return if read_bytes == 0 { + // 正常EOF + // 在结束时输出一下统计信息 + if let Some(dbg) = debug_out { + if match_count > 0 { + let avg_match_len = total_match_length as f64 / match_count as f64; + writeln!( + dbg, + "[LZ77 decompress] match_count = {}, total_match_length = {}, average_match_len = {:.2}, literal_count = {}", + match_count, total_match_length, avg_match_len, literal_count + )?; + } else { + writeln!( + dbg, + "[LZ77 decompress] No matches, literal_count = {}", + literal_count + )?; + } + } + Ok(()) + } else { + Err(io::Error::new( + io::ErrorKind::UnexpectedEof, + "Unexpected EOF while reading token header", + )) + }; + } + read_bytes += n; + total_read += n; + if total_read - last_reported >= REPORT_THRESHOLD { + onprogress(total_read); + last_reported = total_read; + } + } + + let offset = u16::from_le_bytes([token_buf[0], token_buf[1]]); + let length = token_buf[2]; + let next_char = token_buf[3]; + + // 检测是否是 批量字面量 Token 头 => [0,0, run_len, 0xFF] + if offset == 0 && length > 0 && next_char == 0xFF { + // length 表示 run_len + let run_len = length as usize; + literal_count += run_len; + + // 继续从输入读取 run_len 个字面量 + let mut literal_data = vec![0u8; run_len]; + let mut read_now = 0; + while read_now < run_len { + let n = input.read(&mut literal_data[read_now..])?; + if n == 0 { + return Err(io::Error::new( + io::ErrorKind::UnexpectedEof, + format!("EOF while reading literal run (need {} bytes)", run_len), + )); + } + read_now += n; + total_read += n; + if total_read - last_reported >= REPORT_THRESHOLD { + onprogress(total_read); + last_reported = total_read; + } + } + + // 写出并更新 pos + output.write_all(&literal_data)?; + for &byte in &literal_data { + let buffer_pos = pos % ring_buffer.len(); + ring_buffer[buffer_pos] = byte; + pos += 1; + } + } else { + // 否则 => 这是一个普通 MATCH Token + // (offset, length, next_char) + let offset_usize = offset as usize; + let length_usize = length as usize; + + // 如果有 match,统计 + if offset_usize > 0 && length_usize > 0 { + match_count += 1; + total_match_length += length_usize; + } else { + // 这意味着 offset=0/length=0,算是 1 字节 literal + literal_count += 1; + } + + // 先复制 match + if offset_usize > 0 && length_usize > 0 { + if offset_usize > pos { + // 无效 offset + return Err(io::Error::new( + io::ErrorKind::InvalidData, + format!("Invalid offset: {} > {}", offset_usize, pos), + )); + } + for _ in 0..length_usize { + let buffer_pos = pos % ring_buffer.len(); + let lookup_pos = (pos - offset_usize) % ring_buffer.len(); + let byte = ring_buffer[lookup_pos]; + ring_buffer[buffer_pos] = byte; + output.write_all(&[byte])?; + pos += 1; + } + } + + // next_char 始终写出 + { + let buffer_pos = pos % ring_buffer.len(); + ring_buffer[buffer_pos] = next_char; + output.write_all(&[next_char])?; + pos += 1; + } + } + } + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..c7a8be0 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,765 @@ +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] +use eframe::egui::{Color32, IconData, Shadow}; +use eframe::{ + egui::{self, Align, Layout}, + App, Frame, NativeOptions, +}; +use egui_notify::Toasts; +use rfd::FileDialog; +use std::borrow::Cow; +use std::io::{BufWriter}; +use std::time::{Duration, Instant}; +use std::{fs, fs::File, io::{BufReader, Cursor}, path::PathBuf, sync::mpsc::{self, Receiver, Sender}, thread}; +use std::path::Path; + +mod huffman; +mod lz77; +use compresscsdesign::compute_crc32_and_sha256; + +enum CompressMsg { + FileStart(usize), + FileProgress(usize, usize), // (current_read, total_size) + FileDone(usize), + Error(String), + AllDone, +} + +#[derive(PartialEq)] +enum ProcessType { + Compress, + Decompress, +} + +#[derive(Default)] +struct ChecksumFile { + path: PathBuf, + crc32: Option, + sha256: Option, +} + +#[derive(Default)] +struct ChecksumWindow { + show: bool, + files: Vec, +} + +struct MyApp { + selected_files: Vec, + + enable_lz77: bool, + enable_huffman: bool, + enable_debug: bool, + lz77_window_size: usize, + lz77_lookahead_size: usize, + + output_path: String, + + process_type: ProcessType, + is_compressing: bool, + + compress_index: usize, + compress_progress: usize, + compress_progress_total: usize, + + receiver: Receiver, + sender: Option>, + + // egui_notify + toasts: Toasts, + + checksum_window: ChecksumWindow, + start_time: Instant, +} +fn read_font_file(paths: &[&str]) -> Option> { + for &path in paths { + if let Ok(data) = fs::read(Path::new(path)) { + return Some(data); + } + } + None +} +impl MyApp { + fn new(cc: &eframe::CreationContext<'_>) -> Self { + + let paths = [ + "C:/Users/feie9454/AppData/Local/Microsoft/Windows/Fonts/PingFang Medium.ttf", + "C:/Windows/Fonts/msyh.ttc" + ]; + + match read_font_file(&paths) { + Some(font_data) => { + println!("Font loaded successfully, size: {} bytes", font_data.len()) ; + let mut fonts = egui::FontDefinitions::default(); + fonts.font_data.insert( + "my_font".to_owned(), + egui::FontData::from_owned(font_data).into(), + ); + fonts + .families + .entry(egui::FontFamily::Proportional) + .or_default() + .insert(0, "my_font".to_owned()); + cc.egui_ctx.set_fonts(fonts); + }, + None => eprintln!("Failed to load font from all specified paths."), + } + + let (tx, rx) = mpsc::channel(); + Self { + selected_files: Vec::new(), + enable_lz77: true, + enable_huffman: true, + enable_debug: false, + lz77_window_size: 16384, + lz77_lookahead_size: 127, + output_path: String::new(), + process_type: ProcessType::Compress, + compress_index: 0, + compress_progress: 0, + compress_progress_total: 0, + is_compressing: false, + receiver: rx, + sender: Some(tx), + toasts: Toasts::default().with_shadow(Shadow { + offset: Default::default(), + blur: 10.0, + spread: 5.0, + color: Color32::from_black_alpha(15), + }), + checksum_window: ChecksumWindow { + show: false, + files: vec![], + }, + start_time: Instant::now(), + } + } +} + +impl App for MyApp { + fn update(&mut self, ctx: &egui::Context, _frame: &mut Frame) { + // -- 主窗口:处理文件拖拽事件 -- + ctx.input(|i| { + if !i.raw.dropped_files.is_empty() && !self.checksum_window.show { + // 只有在「校验工具」窗口关闭时才往 selected_files 里加 + // 避免在校验窗口打开时拖拽却误加到压缩列表 + for file in &i.raw.dropped_files { + if let Some(path) = &file.path { + self.selected_files.push(path.clone()); + } + } + } + }); + + // -- 从压缩/解压线程中接收消息 -- + while let Ok(msg) = self.receiver.try_recv() { + match msg { + CompressMsg::FileStart(index) => { + // 切换到正在处理的文件 + println!("开始处理第 {} 个文件", index + 1); + self.compress_index = index; + self.compress_progress = 0; + } + CompressMsg::FileProgress(current_read, total_size) => { + // 更新单个文件的进度百分比 + self.compress_progress = current_read; + self.compress_progress_total = total_size; + } + CompressMsg::FileDone(index) => { + // 某个文件处理结束 + if index + 1 >= self.selected_files.len() { + self.compress_index = self.selected_files.len() - 1; + } else { + self.compress_index = index + 1; + self.compress_progress = 0; + } + } + CompressMsg::AllDone => { + self.is_compressing = false; + self.compress_index = self.selected_files.len() - 1; + self.toasts.success(format!( + "所有文件处理完毕!耗时 {}ms", + (Instant::now() - self.start_time).as_millis() + )); + } + CompressMsg::Error(msg) => { + self.toasts.error(format!("处理时发生错误:{}", msg)); + } + } + } + + // ---- 绘制主界面 ---- + egui::CentralPanel::default().show(ctx, |ui| { + ui.horizontal(|ui| { + ui.heading("鹅鹅文件压缩 / 解压"); + ui.colored_label(Color32::DARK_GRAY, "3230608044 查俊豪"); + }); + ui.separator(); + ui.label("基于 LZ77 和 Huffman 算法实现的压缩工具,支持多文件批量压缩 / 解压。"); + + if !self.selected_files.is_empty() { + ui.label("已选择文件:"); + for path in &self.selected_files { + ui.label(format!("- {}", path.display())); + } + ui.with_layout(Layout::right_to_left(Align::Min), |ui| { + if ui.button("清空").clicked() { + self.selected_files.clear(); + } + }); + } else { + ui.label("请拖拽文件到窗口中以添加文件。"); + } + + ui.separator(); + ui.label("处理类型:"); + ui.radio_value(&mut self.process_type, ProcessType::Compress, "压缩"); + if self.process_type == ProcessType::Compress { + egui::CollapsingHeader::new("压缩设置") + .default_open(true) + .show(ui, |ui| { + ui.add_space(4.0); + ui.horizontal(|ui| { + ui.label("预设:"); + if ui.button("极快").clicked() { + self.enable_lz77 = false; + self.enable_huffman = true; + } + if ui.button("平衡").clicked() { + self.enable_lz77 = true; + self.enable_huffman = true; + self.lz77_window_size = 16384; + self.lz77_lookahead_size = 127; + } + if ui.button("极限压缩").clicked() { + self.enable_lz77 = true; + self.enable_huffman = true; + self.lz77_window_size = 65535; + self.lz77_lookahead_size = 255; + } + }); + ui.add_space(4.0); + ui.horizontal(|ui| { + ui.checkbox(&mut self.enable_lz77, "启用 LZ77"); + }); + + if self.enable_lz77 { + ui.add( + egui::Slider::new(&mut self.lz77_window_size, 128..=65535) + .text("LZ77 Window Size"), + ); + ui.add( + egui::Slider::new(&mut self.lz77_lookahead_size, 32..=255) + .text("LZ77 Lookahead Size"), + ); + } + + ui.horizontal(|ui| { + ui.checkbox(&mut self.enable_huffman, "启用 Huffman"); + }); + ui.add_space(4.0); + }); + } + ui.radio_value(&mut self.process_type, ProcessType::Decompress, "解压"); + + ui.separator(); + + ui.horizontal(|ui| { + ui.label("输出路径: "); + ui.text_edit_singleline(&mut self.output_path); + + if ui.button("选择...").clicked() { + if let Some(folder) = FileDialog::new().pick_folder() { + self.output_path = folder.display().to_string(); + } + } + }); + ui.add_space(4.0); + ui.with_layout(Layout::right_to_left(Align::Min), |ui| { + ui.checkbox(&mut self.enable_debug, "输出调试信息"); + }); + + ui.separator(); + + ui.label(format!( + "正在处理文件: {}/{}", + if self.is_compressing { + self.compress_index + 1 + } else { + 0 + }, + self.selected_files.len() + )); + + let current_file_progress = if self.compress_progress_total == 0 { + 0.0 + } else { + self.compress_progress as f32 / self.compress_progress_total as f32 + }; + + // 总体进度条 + if self.selected_files.is_empty() || !self.is_compressing { + ui.add(egui::ProgressBar::new(0.0).show_percentage()); + } else { + ui.add( + egui::ProgressBar::new( + (self.compress_index as f32 + current_file_progress) + / (self.selected_files.len() as f32), + ) + .show_percentage(), + ); + }; + + // 当前文件进度条 + if self.selected_files.is_empty() || !self.is_compressing { + ui.label("0 KiB / 0 KiB"); + ui.add(egui::ProgressBar::new(0.0).show_percentage()); + } else { + ui.label(format!( + "{}: {} KiB / {} KiB", + if !self.selected_files.is_empty() { + self.selected_files[self.compress_index] + .file_name() + .unwrap_or("".as_ref()) + .to_string_lossy() + } else { + Cow::from("") + }, + self.compress_progress / 1024, + self.compress_progress_total / 1024 + )); + ui.add(egui::ProgressBar::new(current_file_progress).show_percentage()); + } + + ui.separator(); + ui.add_space(ui.available_height() - 24.0); + + ui.horizontal(|ui| { + ui.with_layout(Layout::right_to_left(Align::Min), |ui| { + if ui.button("开始!").clicked() { + if self.selected_files.is_empty() { + self.toasts + .info("请选择要处理的文件") + .duration(Some(Duration::from_secs(3))); + return; + } + if self.output_path.is_empty() { + self.toasts + .info("请指定输出路径") + .duration(Some(Duration::from_secs(3))); + return; + } + if self.is_compressing { + self.toasts + .info("请等待任务处理完成") + .duration(Some(Duration::from_secs(3))); + return; + } + match self.process_type { + ProcessType::Decompress => { + self.start_time = Instant::now(); + self.start_decompress_thread(); + } + ProcessType::Compress => { + self.start_time = Instant::now(); + self.start_compress_thread(); + } + } + } + + if ui.button("校验工具").clicked() { + // 打开校验窗口 + self.checksum_window.show = true; + } + }); + }); + }); + + self.update_checksum_window(ctx); + + self.toasts.show(ctx); + ctx.request_repaint(); + } +} + +impl MyApp { + fn start_compress_thread(&mut self) { + self.is_compressing = true; + self.compress_progress = 0; + self.compress_index = 0; + + let (tx, rx) = mpsc::channel(); + self.sender = Some(tx.clone()); + self.receiver = rx; + + let selected_files = self.selected_files.clone(); + let output_path = self.output_path.clone(); + + // 新增: 这几个为了在子线程里捕获 + let enable_lz77 = self.enable_lz77; + let enable_huffman = self.enable_huffman; + let enable_debug = self.enable_debug; + let lz77_window_size = self.lz77_window_size; + let lz77_lookahead_size = self.lz77_lookahead_size; + + thread::spawn(move || { + // 压缩线程逻辑:依次处理 selected_files + for (i, file_path) in selected_files.iter().enumerate() { + let _ = tx.send(CompressMsg::FileStart(i)); + + let total_size = file_path.metadata().map(|m| m.len()).unwrap_or(0); + + let input_file = match File::open(file_path) { + Ok(f) => f, + Err(e) => { + eprintln!("无法打开输入文件: {}, 错误: {}", file_path.display(), e); + continue; + } + }; + let input_reader = BufReader::new(input_file); + + // ----------------------------- + // 1) 组装输出文件名 + // ----------------------------- + let filename = file_path.file_name().unwrap_or_default().to_string_lossy(); + let mut out_filename = filename.to_string(); + + if enable_lz77 && enable_huffman { + out_filename.push_str(".lz77.huf"); + } else if enable_lz77 { + out_filename.push_str(".lz77"); + } else if enable_huffman { + out_filename.push_str(".huf"); + } else { + let _ = tx.send(CompressMsg::Error("未启用任何压缩算法!".to_string())); + continue; + } + + let output_fullpath = format!("{}/{}", output_path, out_filename); + let output_file = match File::create(&output_fullpath) { + Ok(f) => f, + Err(e) => { + eprintln!("无法创建输出文件: {}, 错误: {}", output_fullpath, e); + continue; + } + }; + let output_writer = BufWriter::new(output_file); + + // ----------------------------- + // 2) 如果 debug,创建同名log文件 + // ----------------------------- + // 用 Option 来存日志句柄 + let mut debug_file: Option = None; + if enable_debug { + let log_filename = format!("{}.log", out_filename); + let log_filepath = format!("{}/{}", output_path, log_filename); + match File::create(&log_filepath) { + Ok(f) => { + debug_file = Some(f); + } + Err(e) => { + eprintln!("无法创建log文件: {}, 错误: {}", log_filepath, e); + // 不要return;只是没有日志而已 + } + } + } + + // ----------------------------- + // 3) 定义进度回调 + // ----------------------------- + let mut bytes_read_so_far = 0usize; + let mut onprogress = |read_bytes: usize| { + bytes_read_so_far = read_bytes; + let _ = tx.send(CompressMsg::FileProgress( + bytes_read_so_far, + total_size as usize, + )); + }; + + // ----------------------------- + // 4) 执行压缩 + // ----------------------------- + let result = if enable_lz77 && enable_huffman { + // 先 LZ77 => temp_buf => 再 Huffman => output + let mut temp_buf = Vec::new(); + let lz77 = lz77::LZ77::new(lz77_window_size, lz77_lookahead_size); + + // 第一次调用: LZ77压缩 => temp_buf + // 注意:把 debug_file.as_mut() 传给 compress_stream + let r1 = { + let debug_out: Option<&mut File> = debug_file.as_mut(); // 取可变引用 + lz77.compress_stream( + input_reader, + &mut temp_buf, + &mut onprogress, + debug_out, + ) + }; + + if r1.is_err() { + r1 + } else { + // 第二次调用: Huffman => output_writer + let temp_reader = BufReader::new(Cursor::new(temp_buf)); + let debug_out: Option<&mut File> = debug_file.as_mut(); + huffman::encode_stream( + temp_reader, + output_writer, + &mut onprogress, + debug_out, + ) + } + } else if enable_lz77 { + // 仅 LZ77 + let lz77 = lz77::LZ77::new(lz77_window_size, lz77_lookahead_size); + let debug_out: Option<&mut File> = debug_file.as_mut(); + lz77.compress_stream(input_reader, output_writer, &mut onprogress, debug_out) + } else { + // 仅 Huffman + let debug_out: Option<&mut File> = debug_file.as_mut(); + huffman::encode_stream(input_reader, output_writer, &mut onprogress, debug_out) + }; + + if let Err(e) = result { + eprintln!("压缩过程出错: {}", e); + let _ = tx.send(CompressMsg::Error(format!("压缩过程出错: {}", e))); + } + + // 单个文件结束 + let _ = tx.send(CompressMsg::FileDone(i)); + } + + // 全部文件处理结束 + let _ = tx.send(CompressMsg::AllDone); + }); + } + + fn start_decompress_thread(&mut self) { + self.is_compressing = true; + self.compress_progress = 0; + self.compress_index = 0; + + let (tx, rx) = mpsc::channel(); + self.sender = Some(tx.clone()); + self.receiver = rx; + + let selected_files = self.selected_files.clone(); + let output_path = self.output_path.clone(); + let enable_debug = self.enable_debug; + + thread::spawn(move || { + for (i, file_path) in selected_files.iter().enumerate() { + let _ = tx.send(CompressMsg::FileStart(i)); + + let total_size = file_path.metadata().map(|m| m.len()).unwrap_or(0); + + let input_file = match File::open(file_path) { + Ok(f) => f, + Err(e) => { + eprintln!("无法打开待解压文件: {}, 错误: {}", file_path.display(), e); + let _ = tx.send(CompressMsg::Error(format!( + "无法打开待解压文件: {}, 错误: {}", + file_path.display(), + e + ))); + continue; + } + }; + let input_reader = BufReader::new(input_file); + + let filename = file_path.file_name().unwrap_or_default().to_string_lossy(); + let mut out_filename = filename.to_string(); + + // ----------------------------- + // 2) 如果 debug,创建同名log文件 + // ----------------------------- + let mut debug_file: Option = None; + if enable_debug { + let log_filename = format!("{}.log", out_filename); + let log_filepath = format!("{}/{}", output_path, log_filename); + match File::create(&log_filepath) { + Ok(f) => { + debug_file = Some(f); + } + Err(e) => { + eprintln!("无法创建log文件: {}, 错误: {}", log_filepath, e); + } + } + } + + let use_lz77 = + out_filename.ends_with(".lz77") || out_filename.ends_with(".lz77.huf"); + let use_huffman = out_filename.ends_with(".huf"); + + // 去掉后缀,以得到解压后的“原始”文件名 + if out_filename.ends_with(".lz77.huf") { + out_filename.truncate(out_filename.len() - ".lz77.huf".len()); + } else if out_filename.ends_with(".lz77") { + out_filename.truncate(out_filename.len() - ".lz77".len()); + } else if out_filename.ends_with(".huf") { + out_filename.truncate(out_filename.len() - ".huf".len()); + } else { + let _ = tx.send(CompressMsg::Error(format!( + "无法识别的压缩格式:{}", + out_filename + ))); + continue; + } + + let output_fullpath = format!("{}/{}", output_path, out_filename); + let output_file = match File::create(&output_fullpath) { + Ok(f) => f, + Err(e) => { + eprintln!("无法创建解压后文件: {}, 错误: {}", output_fullpath, e); + let _ = tx.send(CompressMsg::Error(format!( + "无法创建解压后文件: {}, 错误: {}", + output_fullpath, e + ))); + continue; + } + }; + let output_writer = BufWriter::new(output_file); + + // 定义进度回调 + let mut bytes_read_so_far = 0usize; + let mut onprogress = |read_bytes: usize| { + bytes_read_so_far = read_bytes; + let _ = tx.send(CompressMsg::FileProgress( + bytes_read_so_far, + total_size as usize, + )); + }; + + // ----------------------------- + // 3) 执行解压 + // ----------------------------- + let result = if use_lz77 && use_huffman { + // 后缀是 .lz77.huf => 先 Huffman 解 => temp_buf => 再 LZ77 解 => output + let mut temp_buf = Vec::new(); + // 第一次:Huffman decode => temp_buf + let r1 = { + let debug_out: Option<&mut File> = debug_file.as_mut(); + huffman::decode_stream( + input_reader, + &mut temp_buf, + &mut onprogress, + debug_out, + ) + }; + if r1.is_err() { + r1 + } else { + let temp_reader = BufReader::new(Cursor::new(temp_buf)); + let lz = lz77::LZ77::new(0, 0); + let debug_out: Option<&mut File> = debug_file.as_mut(); + lz.decompress_stream(temp_reader, output_writer, &mut onprogress, debug_out) + } + } else if use_lz77 { + // .lz77 => 直接 LZ77 解 + let lz = lz77::LZ77::new(0, 0); + let debug_out: Option<&mut File> = debug_file.as_mut(); + lz.decompress_stream(input_reader, output_writer, &mut onprogress, debug_out) + } else { + // .huf => 直接 Huffman 解 + let debug_out: Option<&mut File> = debug_file.as_mut(); + huffman::decode_stream(input_reader, output_writer, &mut onprogress, debug_out) + }; + + if let Err(e) = result { + eprintln!("解压过程出错: {}", e); + let _ = tx.send(CompressMsg::Error(format!("解压过程出错: {}", e))); + } + + let _ = tx.send(CompressMsg::FileDone(i)); + } + let _ = tx.send(CompressMsg::AllDone); + }); + } + + fn update_checksum_window(&mut self, ctx: &egui::Context) { + if self.checksum_window.show { + egui::Window::new("校验工具") + .open(&mut self.checksum_window.show) + .collapsible(false) + .resizable(false) + .show(ctx, |ui| { + ui.label("请将文件拖入此窗口,或重复拖拽多个文件。"); + + if ctx.input(|i| !i.raw.dropped_files.is_empty()) { + ctx.input(|i| { + for file in &i.raw.dropped_files { + if let Some(path) = &file.path { + // 如果文件已经存在,就不重复添加 + if !self.checksum_window.files.iter().any(|f| f.path == *path) { + let mut cf = ChecksumFile { + path: path.clone(), + ..Default::default() + }; + let (crc32, sha256) = compute_crc32_and_sha256(&cf.path); + cf.crc32 = crc32; + cf.sha256 = sha256; + self.checksum_window.files.push(cf); + } + } + } + }); + } + + ui.separator(); + + if self.checksum_window.files.is_empty() { + ui.label("尚未添加任何文件。"); + } else { + egui::ScrollArea::vertical() + .max_height(400.0) + .show(ui, |ui| { + for file_info in &self.checksum_window.files { + ui.group(|ui| { + ui.label(format!("文件: {}", file_info.path.display())); + if let Some(crc32) = file_info.crc32 { + ui.label(format!("CRC32: {:08X}", crc32)); + } else { + ui.label("CRC32: 计算失败或文件不可读"); + } + + if let Some(ref sha256) = file_info.sha256 { + ui.label(format!("SHA256: {}", sha256)); + } else { + ui.label("SHA256: 计算失败或文件不可读"); + } + }); + ui.add_space(6.0); + } + }); + ui.with_layout(Layout::right_to_left(Align::Min), |ui| { + if ui.button("清空文件列表").clicked() { + self.checksum_window.files.clear(); + } + }); + } + }); + } + } +} + +fn load_icon() -> IconData { + IconData { + rgba: include_bytes!(".\\assets\\icon.bin").to_vec(), + width: 128, + height: 128, + } +} +fn main() -> eframe::Result<()> { + let options = NativeOptions { + viewport: egui::ViewportBuilder::default() + .with_title("鹅鹅文件压缩器") + .with_icon(load_icon()) + .with_inner_size([500.0, 600.0]), + ..Default::default() + }; + + eframe::run_native( + "鹅鹅文件压缩器", + options, + Box::new(|cc| Ok(Box::new(MyApp::new(cc)))), + ) +}