diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml deleted file mode 100644 index 054f397..0000000 --- a/.github/workflows/docs.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Deploy Documentation - -on: - push: - branches: [ main ] - paths: [ 'docs/**' ] - pull_request: - branches: [ main ] - paths: [ 'docs/**' ] - -jobs: - deploy: - runs-on: ubuntu-latest - permissions: - contents: read - pages: write - id-token: write - - steps: - - uses: actions/checkout@v4 - - - name: Setup mdBook - uses: peaceiris/actions-mdbook@v1 - with: - mdbook-version: 'latest' - - - name: Build documentation - run: mdbook build docs - - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 - with: - path: ./docs/book - - - name: Deploy to GitHub Pages - if: github.ref == 'refs/heads/main' - id: deployment - uses: actions/deploy-pages@v4 \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 89b8ba9..091ed56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,32 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "ab_glyph" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01c0457472c38ea5bd1c3b5ada5e368271cb550be7a4ca4a0b4634e9913f6cc2" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" + +[[package]] +name = "accesskit" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e25ae84c0260bdf5df07796d7cc4882460de26a2b406ec0e6c42461a723b271b" +dependencies = [ + "enumn", + "serde", +] + [[package]] name = "addr2line" version = "0.24.2" @@ -10,20 +36,43 @@ checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "cpp_demangle", "fallible-iterator", - "gimli", + "gimli 0.31.1", "memmap2", - "object", + "object 0.36.7", "rustc-demangle", "smallvec", "typed-arena", ] +[[package]] +name = "addr2line" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +dependencies = [ + "gimli 0.32.3", +] + [[package]] name = "adler2" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "getrandom 0.3.3", + "once_cell", + "serde", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -39,6 +88,33 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" +[[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.9.1", + "cc", + "cesu8", + "jni", + "jni-sys", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "num_enum", + "thiserror 1.0.69", +] + +[[package]] +name = "android-properties" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" + [[package]] name = "anstream" version = "0.6.19" @@ -95,6 +171,26 @@ version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +[[package]] +name = "arboard" +version = "3.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0348a1c054491f4bfe6ab86a7b6ab1e44e45d899005de92f58b3df180b36ddaf" +dependencies = [ + "clipboard-win", + "image", + "log", + "objc2 0.6.2", + "objc2-app-kit 0.3.1", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation 0.3.1", + "parking_lot", + "percent-encoding", + "windows-sys 0.59.0", + "x11rb", +] + [[package]] name = "argh" version = "0.1.13" @@ -128,474 +224,4109 @@ dependencies = [ ] [[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "bitflags" -version = "2.9.1" +name = "arrayvec" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] -name = "bytemuck" -version = "1.23.1" +name = "as-raw-xcb-connection" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" [[package]] -name = "bytesize" -version = "1.3.3" +name = "ashpd" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e93abca9e28e0a1b9877922aacb20576e05d4679ffa78c3d6dc22a26a216659" +checksum = "6cbdf310d77fd3aaee6ea2093db7011dc2d35d2eb3481e5607f1f8d942ed99df" +dependencies = [ + "enumflags2", + "futures-channel", + "futures-util", + "rand", + "raw-window-handle", + "serde", + "serde_repr", + "tokio", + "url", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "zbus", +] [[package]] -name = "cassowary" -version = "0.3.0" +name = "async-broadcast" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" +dependencies = [ + "event-listener", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] [[package]] -name = "castaway" -version = "0.2.4" +name = "async-recursion" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ - "rustversion", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "cc" -version = "1.2.30" +name = "async-trait" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ - "shlex", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "cfg-if" -version = "1.0.1" +name = "atomic-waker" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] -name = "colorchoice" -version = "1.0.4" +name = "autocfg" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] -name = "compact_str" -version = "0.8.1" +name = "backtrace" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b79c4069c6cad78e2e0cdfcbd26275770669fb39fd308a752dc110e83b9af32" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" dependencies = [ - "castaway", + "addr2line 0.25.1", "cfg-if", - "itoa", - "rustversion", - "ryu", - "static_assertions", + "libc", + "miniz_oxide", + "object 0.37.3", + "rustc-demangle", + "windows-link 0.2.0", ] [[package]] -name = "cpp_demangle" -version = "0.4.5" +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2bb79cb74d735044c972aae58ed0aaa9a837e85b01106a54c39e42e97f62253" -dependencies = [ - "cfg-if", -] +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] -name = "crc32fast" -version = "1.5.0" +name = "bincode" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" dependencies = [ - "cfg-if", + "serde", ] [[package]] -name = "crossbeam-deque" -version = "0.8.6" +name = "bit-set" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", + "bit-vec", ] [[package]] -name = "crossbeam-epoch" -version = "0.9.18" +name = "bit-vec" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] -name = "crossbeam-utils" -version = "0.8.21" +name = "bitflags" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "crossterm" -version = "0.28.1" +name = "bitflags" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" dependencies = [ - "bitflags", - "crossterm_winapi", - "mio", - "parking_lot", - "rustix 0.38.44", - "signal-hook", - "signal-hook-mio", - "winapi", + "serde", ] [[package]] -name = "crossterm_winapi" -version = "0.9.1" +name = "block2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" dependencies = [ - "winapi", + "objc2 0.5.2", ] [[package]] -name = "dang" -version = "0.1.0" +name = "block2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "340d2f0bdb2a43c1d3cd40513185b2bd7def0aa1052f956455114bc98f82dcf2" dependencies = [ - "anyhow", - "argh", - "cc", - "env_logger", - "gdbstub", - "gdbstub_arch", - "glob", - "goblin 0.9.3", - "log", - "num-bigint", - "num_cpus", - "pyo3", - "pywellen", - "serde", - "serde_yaml", - "wellen", + "objc2 0.6.2", ] [[package]] -name = "darling" -version = "0.20.11" +name = "bumpalo" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "bytemuck" +version = "1.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" dependencies = [ - "darling_core", - "darling_macro", + "bytemuck_derive", ] [[package]] -name = "darling_core" -version = "0.20.11" +name = "bytemuck_derive" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +checksum = "4f154e572231cb6ba2bd1176980827e3d5dc04cc183a75dea38109fbdd672d29" dependencies = [ - "fnv", - "ident_case", "proc-macro2", "quote", - "strsim", "syn", ] [[package]] -name = "darling_macro" -version = "0.20.11" +name = "byteorder-lite" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" -dependencies = [ - "darling_core", - "quote", - "syn", -] +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] -name = "either" -version = "1.15.0" +name = "bytes" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] -name = "env_filter" -version = "0.1.3" +name = "bytesize" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" -dependencies = [ - "log", - "regex", -] +checksum = "2e93abca9e28e0a1b9877922aacb20576e05d4679ffa78c3d6dc22a26a216659" [[package]] -name = "env_logger" -version = "0.11.8" +name = "bytesize" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +checksum = "f5c434ae3cf0089ca203e9019ebe529c47ff45cefe8af7c85ecb734ef541822f" + +[[package]] +name = "calloop" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ - "anstream", - "anstyle", - "env_filter", - "jiff", + "bitflags 2.9.1", "log", + "polling", + "rustix 0.38.44", + "slab", + "thiserror 1.0.69", ] [[package]] -name = "equivalent" -version = "1.0.2" +name = "calloop-wayland-source" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" +dependencies = [ + "calloop", + "rustix 0.38.44", + "wayland-backend", + "wayland-client", +] [[package]] -name = "errno" -version = "0.3.13" +name = "camino" +version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "dd0b03af37dad7a14518b7691d81acb0f8222604ad3d1b02f6b4bed5188c0cd5" dependencies = [ - "libc", - "windows-sys 0.60.2", + "serde", ] [[package]] -name = "fallible-iterator" +name = "cassowary" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" +checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" [[package]] -name = "fastrand" -version = "2.3.0" +name = "castaway" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" +dependencies = [ + "rustversion", +] [[package]] -name = "flate2" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" +name = "cc" +version = "1.2.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7" +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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[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 = "chrono" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +dependencies = [ + "num-traits", +] + +[[package]] +name = "clap" +version = "4.5.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" + +[[package]] +name = "clipboard-win" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4" +dependencies = [ + "error-code", +] + +[[package]] +name = "codespan-reporting" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" +dependencies = [ + "serde", + "termcolor", + "unicode-width", +] + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "colored" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" +dependencies = [ + "lazy_static", + "windows-sys 0.59.0", +] + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "compact_str" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b79c4069c6cad78e2e0cdfcbd26275770669fb39fd308a752dc110e83b9af32" +dependencies = [ + "castaway", + "cfg-if", + "itoa", + "rustversion", + "ryu", + "static_assertions", +] + +[[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 = "config" +version = "0.15.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0faa974509d38b33ff89282db9c3295707ccf031727c0de9772038ec526852ba" +dependencies = [ + "pathdiff", + "serde", + "toml", + "winnow", +] + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +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 0.5.0", + "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 = "cpp_demangle" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2bb79cb74d735044c972aae58ed0aaa9a837e85b01106a54c39e42e97f62253" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crossterm" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +dependencies = [ + "bitflags 2.9.1", + "crossterm_winapi", + "mio", + "parking_lot", + "rustix 0.38.44", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "cursor-icon" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" + +[[package]] +name = "dang" +version = "0.1.0" +dependencies = [ + "anyhow", + "argh", + "cc", + "env_logger", + "gdbstub", + "gdbstub_arch", + "glob", + "goblin 0.9.3", + "log", + "num-bigint", + "num_cpus", + "pyo3", + "pywellen", + "serde", + "serde_yaml", + "wellen 0.12.1", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "deranged" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive_builder" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive_builder_macro" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" +dependencies = [ + "derive_builder_core", + "syn", +] + +[[package]] +name = "derive_more" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "directories" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.59.0", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dispatch2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +dependencies = [ + "bitflags 2.9.1", + "block2 0.6.1", + "libc", + "objc2 0.6.2", +] + +[[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.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" + +[[package]] +name = "ecolor" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94bdf37f8d5bd9aa7f753573fdda9cf7343afa73dd28d7bfe9593bd9798fc07e" +dependencies = [ + "bytemuck", + "emath", + "serde", +] + +[[package]] +name = "eframe" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14d1c15e7bd136b309bd3487e6ffe5f668b354cd9768636a836dd738ac90eb0b" +dependencies = [ + "ahash", + "bytemuck", + "document-features", + "egui", + "egui-wgpu", + "egui-winit", + "egui_glow", + "glow", + "glutin", + "glutin-winit", + "image", + "js-sys", + "log", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", + "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.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5d0306cd61ca75e29682926d71f2390160247f135965242e904a636f51c0dc" +dependencies = [ + "accesskit", + "ahash", + "bitflags 2.9.1", + "emath", + "epaint", + "log", + "nohash-hasher", + "profiling", + "serde", + "smallvec", + "unicode-segmentation", +] + +[[package]] +name = "egui-remixicon" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a463c133d92f2ea65465464437aeb3ebd134a5e583379c5f73121727dd0e2d6" + +[[package]] +name = "egui-wgpu" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c12eca13293f8eba27a32aaaa1c765bfbf31acd43e8d30d5881dcbe5e99ca0c7" +dependencies = [ + "ahash", + "bytemuck", + "document-features", + "egui", + "epaint", + "log", + "profiling", + "thiserror 1.0.69", + "type-map", + "web-time", + "wgpu", + "winit", +] + +[[package]] +name = "egui-winit" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f95d0a91f9cb0dc2e732d49c2d521ac8948e1f0b758f306fb7b14d6f5db3927f" +dependencies = [ + "ahash", + "arboard", + "bytemuck", + "egui", + "log", + "profiling", + "raw-window-handle", + "smithay-clipboard", + "web-time", + "webbrowser", + "winit", +] + +[[package]] +name = "egui_extras" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dddbceddf39805fc6c62b1f7f9c05e23590b40844dc9ed89c6dc6dbc886e3e3b" +dependencies = [ + "ahash", + "egui", + "enum-map", + "log", + "profiling", +] + +[[package]] +name = "egui_glow" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7037813341727937f9e22f78d912f3e29bc3c46e2f40a9e82bb51cbf5e4cfb" +dependencies = [ + "ahash", + "bytemuck", + "egui", + "glow", + "log", + "memoffset", + "profiling", + "wasm-bindgen", + "web-sys", + "winit", +] + +[[package]] +name = "egui_plot" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524318041a8ea90c81c738e8985f8ad9e3f9bed636b03c2ff37b218113ed5121" +dependencies = [ + "ahash", + "egui", + "emath", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "emath" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45fd7bc25f769a3c198fe1cf183124bf4de3bd62ef7b4f1eaf6b08711a3af8db" +dependencies = [ + "bytemuck", + "serde", +] + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "endi" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" + +[[package]] +name = "enum-iterator" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4549325971814bda7a44061bf3fe7e487d447cba01e4220a4b454d630d7a016" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685adfa4d6f3d765a26bc5dbc936577de9abf756c1feeb3089b01dd395034842" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "enum-map" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" +dependencies = [ + "enum-map-derive", +] + +[[package]] +name = "enum-map-derive" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "enumflags2" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "enumn" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "env_filter" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "jiff", + "log", +] + +[[package]] +name = "epaint" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63adcea970b7a13094fe97a36ab9307c35a750f9e24bf00bb7ef3de573e0fddb" +dependencies = [ + "ab_glyph", + "ahash", + "bytemuck", + "ecolor", + "emath", + "epaint_default_fonts", + "log", + "nohash-hasher", + "parking_lot", + "profiling", + "serde", +] + +[[package]] +name = "epaint_default_fonts" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1537accc50c9cab5a272c39300bdd0dd5dca210f6e5e8d70be048df9596e7ca2" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "error-code" +version = "3.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" + +[[package]] +name = "event-listener" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener", + "pin-project-lite", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fax" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05de7d48f37cd6730705cbca900770cab77a89f413d23e100ad7fad7795a0ab" +dependencies = [ + "fax_derive", +] + +[[package]] +name = "fax_derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "fern" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4316185f709b23713e41e3195f90edef7fb00c3ed4adc79769cf09cc762a3b29" +dependencies = [ + "colored", + "log", +] + +[[package]] +name = "flate2" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" dependencies = [ - "crc32fast", - "miniz_oxide", + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared 0.1.1", +] + +[[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 0.3.1", +] + +[[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.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fsevent-sys" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +dependencies = [ + "libc", +] + +[[package]] +name = "fst-reader" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3119a583528a16c1b77a2d27aabfe041918b954e6638c5ee2c197c25048a02ee" +dependencies = [ + "flate2", + "lz4_flex", + "num_enum", + "tempfile", + "thiserror 1.0.69", +] + +[[package]] +name = "fst-reader" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c946f675da6bf21c4fbe21b8681deeac0edec787db48d252f9a976c3f35d6616" +dependencies = [ + "lz4_flex", + "miniz_oxide", + "num_enum", + "thiserror 2.0.17", +] + +[[package]] +name = "ftr_parser" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1dfe5ba7233aaa978bbef73999b4c3adf43cd83fbccbbc50904099ce1bb2eb3" +dependencies = [ + "eyre", + "lz4_flex", + "num-bigint", + "serde", +] + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[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.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" +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-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fuzzy-matcher" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94" +dependencies = [ + "thread_local", +] + +[[package]] +name = "gdbstub" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d66e32caf5dd59f561be0143e413e01d651bd8498eb9aa0be8c482c81c8d31" +dependencies = [ + "bitflags 2.9.1", + "cfg-if", + "log", + "managed", + "num-traits", + "paste", +] + +[[package]] +name = "gdbstub_arch" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22dde0e1b68787036ccedd0b1ff6f953527a0e807e571fbe898975203027278f" +dependencies = [ + "gdbstub", + "num-traits", +] + +[[package]] +name = "gethostname" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc257fdb4038301ce4b9cd1b3b51704509692bb3ff716a410cbd07925d9dae55" +dependencies = [ + "rustix 1.0.8", + "windows-targets 0.52.6", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +dependencies = [ + "fallible-iterator", + "indexmap", + "stable_deref_trait", +] + +[[package]] +name = "gimli" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" + +[[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 = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + +[[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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12124de845cacfebedff80e877bb37b5b75c34c5a4c89e47e1cdd67fb6041325" +dependencies = [ + "bitflags 2.9.1", + "cfg_aliases", + "cgl", + "dispatch2", + "glutin_egl_sys", + "glutin_glx_sys", + "glutin_wgl_sys", + "libloading", + "objc2 0.6.2", + "objc2-app-kit 0.3.1", + "objc2-core-foundation", + "objc2-foundation 0.3.1", + "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", + "glutin", + "raw-window-handle", + "winit", +] + +[[package]] +name = "glutin_egl_sys" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c4680ba6195f424febdc3ba46e7a42a0e58743f2edb115297b86d7f8ecc02d2" +dependencies = [ + "gl_generator", + "windows-sys 0.52.0", +] + +[[package]] +name = "glutin_glx_sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7bb2938045a88b612499fbcba375a77198e01306f52272e692f8c1f3751185" +dependencies = [ + "gl_generator", + "x11-dl", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4ee00b289aba7a9e5306d57c2d05499b2e5dc427f84ac708bd2c090212cf3e" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "goblin" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daa0a64d21a7eb230583b4c5f4e23b7e4e57974f96620f42a7e75e08ae66d745" +dependencies = [ + "log", + "plain", + "scroll 0.12.0", +] + +[[package]] +name = "goblin" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e961b33649994dcf69303af6b3a332c1228549e604d455d61ec5d2ab5e68d3a" +dependencies = [ + "log", + "plain", + "scroll 0.13.0", +] + +[[package]] +name = "h2" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "half" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +dependencies = [ + "cfg-if", + "crunchy", + "num-traits", +] + +[[package]] +name = "hashbrown" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[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 = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "system-configuration", + "tokio", + "tower-service", + "tracing", + "windows-registry", +] + +[[package]] +name = "icu_collections" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" + +[[package]] +name = "icu_properties" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "potential_utf", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +dependencies = [ + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "image" +version = "0.25.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "529feb3e6769d234375c4cf1ee2ce713682b8e76538cb13f9fc23e1400a591e7" +dependencies = [ + "bytemuck", + "byteorder-lite", + "moxcms", + "num-traits", + "png", + "tiff", +] + +[[package]] +name = "indenter" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" + +[[package]] +name = "indexmap" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "indoc" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" + +[[package]] +name = "inotify" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" +dependencies = [ + "bitflags 2.9.1", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + +[[package]] +name = "instability" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435d80800b936787d62688c927b6490e887c7ef5ff9ce922c6c6050fca75eb9a" +dependencies = [ + "darling", + "indoc", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "instruction-decoder" +version = "0.1.0" +source = "git+https://gitlab.com/surfer-project/surfer#1d83e7c22dffa8801e3a37966bc70427e92dce4f" +dependencies = [ + "toml", +] + +[[package]] +name = "io-uring" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" +dependencies = [ + "bitflags 2.9.1", + "cfg-if", + "libc", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "jiff" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", +] + +[[package]] +name = "jiff-static" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[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 1.0.69", + "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.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.3", + "libc", +] + +[[package]] +name = "jpdb" +version = "0.1.0" +dependencies = [ + "argh", + "crossterm", + "dang", + "env_logger", + "libsurfer", + "log", + "num", + "ratatui", + "serde_json", + "shucks", +] + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + +[[package]] +name = "kqueue" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +dependencies = [ + "bitflags 1.3.2", + "libc", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "libc" +version = "0.2.174" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" + +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link 0.2.0", +] + +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + +[[package]] +name = "libredox" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" +dependencies = [ + "bitflags 2.9.1", + "libc", + "redox_syscall 0.5.16", +] + +[[package]] +name = "libsurfer" +version = "0.4.0-dev" +source = "git+https://gitlab.com/surfer-project/surfer#1d83e7c22dffa8801e3a37966bc70427e92dce4f" +dependencies = [ + "base64", + "bincode", + "bytes", + "bytesize 2.1.0", + "camino", + "chrono", + "config", + "derive_more", + "directories", + "ecolor", + "eframe", + "egui", + "egui-remixicon", + "egui_extras", + "egui_plot", + "emath", + "enum-iterator", + "epaint", + "eyre", + "fern", + "ftr_parser", + "futures", + "futures-core", + "futures-util", + "fuzzy-matcher", + "half", + "instruction-decoder", + "itertools 0.14.0", + "lazy_static", + "leb128", + "local-impl", + "log", + "lz4_flex", + "notify", + "num", + "numeric-sort", + "pure-rust-locales", + "rayon", + "regex", + "reqwest", + "rfd", + "ron", + "serde", + "serde_json", + "softposit", + "surfer-translation-types", + "surver", + "sys-locale", + "tokio", + "tokio-stream", + "toml", + "vergen-gitcl", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "web-time", + "wellen 0.19.0", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + +[[package]] +name = "litemap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" + +[[package]] +name = "litrs" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" + +[[package]] +name = "local-impl" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e36d656622c9ac5c84be07696931c71e483d27daf86914d7011d0fa6370418b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "lock_api" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown", +] + +[[package]] +name = "lz4_flex" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08ab2867e3eeeca90e844d1940eab391c9dc5228783db2ed999acbc0a9ed375a" +dependencies = [ + "twox-hash 2.1.1", +] + +[[package]] +name = "managed" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "memmap2" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "483758ad303d734cec05e5c12b41d7e93e6a6390c5e9dae6bdeb7c1259012d28" +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 = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "log", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", +] + +[[package]] +name = "moxcms" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd32fa8935aeadb8a8a6b6b351e40225570a37c43de67690383d87ef170cd08" +dependencies = [ + "num-traits", + "pxfm", +] + +[[package]] +name = "naga" +version = "25.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b977c445f26e49757f9aca3631c3b8b836942cb278d69a92e7b80d3b24da632" +dependencies = [ + "arrayvec", + "bit-set", + "bitflags 2.9.1", + "cfg_aliases", + "codespan-reporting", + "half", + "hashbrown", + "hexf-parse", + "indexmap", + "log", + "num-traits", + "once_cell", + "rustc-hash 1.1.0", + "strum", + "thiserror 2.0.17", + "unicode-ident", +] + +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.9.1", + "jni-sys", + "log", + "ndk-sys", + "num_enum", + "raw-window-handle", + "thiserror 1.0.69", +] + +[[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.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "nix" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +dependencies = [ + "bitflags 2.9.1", + "cfg-if", + "cfg_aliases", + "libc", + "memoffset", +] + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[package]] +name = "notify" +version = "8.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" +dependencies = [ + "bitflags 2.9.1", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "log", + "mio", + "notify-types", + "walkdir", + "windows-sys 0.60.2", +] + +[[package]] +name = "notify-types" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d" + +[[package]] +name = "nucleo-matcher" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf33f538733d1a5a3494b836ba913207f14d9d4a1d3cd67030c5061bdd2cac85" +dependencies = [ + "memchr", + "unicode-segmentation", +] + +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", + "serde", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + +[[package]] +name = "numeric-sort" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2dcb6053ab98da45585315f79932c5c9821fab8efa4301c0d7b637c91630eb7" + +[[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" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561f357ba7f3a2a61563a186a163d0a3a5247e1089524a3981d49adb775078bc" +dependencies = [ + "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.9.1", + "block2 0.5.1", + "libc", + "objc2 0.5.2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation 0.2.2", + "objc2-quartz-core", +] + +[[package]] +name = "objc2-app-kit" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc" +dependencies = [ + "bitflags 2.9.1", + "block2 0.6.1", + "objc2 0.6.2", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation 0.3.1", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.9.1", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-core-location", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags 2.9.1", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" +dependencies = [ + "bitflags 2.9.1", + "dispatch2", + "objc2 0.6.2", +] + +[[package]] +name = "objc2-core-graphics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4" +dependencies = [ + "bitflags 2.9.1", + "dispatch2", + "objc2 0.6.2", + "objc2-core-foundation", + "objc2-io-surface", +] + +[[package]] +name = "objc2-core-image" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "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 0.5.1", + "objc2 0.5.2", + "objc2-contacts", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.9.1", + "block2 0.5.1", + "dispatch", + "libc", + "objc2 0.5.2", +] + +[[package]] +name = "objc2-foundation" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" +dependencies = [ + "bitflags 2.9.1", + "objc2 0.6.2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-io-surface" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7282e9ac92529fa3457ce90ebb15f4ecbc383e8338060960760fa2cf75420c3c" +dependencies = [ + "bitflags 2.9.1", + "objc2 0.6.2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.9.1", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.9.1", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "objc2-metal", +] + +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.9.1", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation 0.2.2", + "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 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.9.1", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-core-location", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "flate2", + "memchr", + "ruzstd", +] + +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + +[[package]] +name = "openssl" +version = "0.10.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" +dependencies = [ + "bitflags 2.9.1", + "cfg-if", + "foreign-types 0.3.2", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36820e9051aca1014ddc75770aab4d68bc1e9e632f0f5627c4086bc216fb583b" +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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.5.16", + "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 = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pin-project" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + +[[package]] +name = "png" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0" +dependencies = [ + "bitflags 2.9.1", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix 1.0.8", + "windows-sys 0.61.1", +] + +[[package]] +name = "pollster" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" + +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "potential_utf" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-crate" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "profiling" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" + +[[package]] +name = "pure-rust-locales" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1190fd18ae6ce9e137184f207593877e70f39b015040156b1e05081cdfe3733a" + +[[package]] +name = "pxfm" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83f9b339b02259ada5c0f4a389b7fb472f933aa17ce176fd2ad98f28bb401fde" +dependencies = [ + "num-traits", +] + +[[package]] +name = "pyo3" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e00b96a521718e08e03b1a622f01c8a8deb50719335de3f60b3b3950f069d8" +dependencies = [ + "cfg-if", + "indoc", + "libc", + "memoffset", + "num-bigint", + "parking_lot", + "portable-atomic", + "pyo3-build-config", + "pyo3-ffi", + "pyo3-macros", + "unindent", +] + +[[package]] +name = "pyo3-build-config" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7883df5835fafdad87c0d888b266c8ec0f4c9ca48a5bed6bbb592e8dedee1b50" +dependencies = [ + "once_cell", + "target-lexicon", +] + +[[package]] +name = "pyo3-ffi" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01be5843dc60b916ab4dad1dca6d20b9b4e6ddc8e15f50c47fe6d85f1fb97403" +dependencies = [ + "libc", + "pyo3-build-config", +] + +[[package]] +name = "pyo3-macros" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77b34069fc0682e11b31dbd10321cbf94808394c56fd996796ce45217dfac53c" +dependencies = [ + "proc-macro2", + "pyo3-macros-backend", + "quote", + "syn", +] + +[[package]] +name = "pyo3-macros-backend" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08260721f32db5e1a5beae69a55553f56b99bd0e1c3e6e0a5e8851a9d0f5a85c" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "pyo3-build-config", + "quote", + "syn", +] + +[[package]] +name = "pywellen" +version = "0.12.1" +source = "git+https://github.com/1024bees/wellen.git?branch=signal-builders#36d7247cf1a142e92d6fd3827574cc98592b483a" +dependencies = [ + "bytemuck", + "num-bigint", + "pyo3", + "wellen 0.12.1", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quick-xml" +version = "0.37.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" +dependencies = [ + "memchr", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "raki" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3857a0e1e2be1236e18c3bf84ba90b0d0523fc17b48557c9e3c4ee21a4d04448" + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", +] + +[[package]] +name = "ratatui" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdef7f9be5c0122f890d58bdf4d964349ba6a6161f705907526d891efabba57d" +dependencies = [ + "bitflags 2.9.1", + "cassowary", + "compact_str", + "crossterm", + "instability", + "itertools 0.13.0", + "lru", + "paste", + "strum", + "strum_macros", + "unicode-segmentation", + "unicode-truncate", + "unicode-width", +] + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[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.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7251471db004e509f4e75a62cca9435365b5ec7bcdff530d612ac7c87c44a792" +dependencies = [ + "bitflags 2.9.1", +] + +[[package]] +name = "redox_users" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +dependencies = [ + "getrandom 0.2.16", + "libredox", + "thiserror 2.0.17", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "renderdoc-sys" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" + +[[package]] +name = "reqwest" +version = "0.12.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "js-sys", + "log", + "mime", + "native-tls", + "percent-encoding", + "pin-project-lite", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-native-tls", + "tokio-util", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", +] + +[[package]] +name = "rfd" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2bee61e6cffa4635c72d7d81a84294e28f0930db0ddcb0f66d10244674ebed" +dependencies = [ + "ashpd", + "block2 0.6.1", + "dispatch2", + "js-sys", + "log", + "objc2 0.6.2", + "objc2-app-kit 0.3.1", + "objc2-core-foundation", + "objc2-foundation 0.3.1", + "pollster", + "raw-window-handle", + "urlencoding", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "ron" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f" +dependencies = [ + "base64", + "bitflags 2.9.1", + "serde", + "serde_derive", + "unicode-ident", +] + +[[package]] +name = "rust-fuzzy-search" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a157657054ffe556d8858504af8a672a054a6e0bd9e8ee531059100c0fa11bb2" + +[[package]] +name = "rustc-demangle" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.9.1", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +dependencies = [ + "bitflags 2.9.1", + "errno", + "libc", + "linux-raw-sys 0.9.4", + "windows-sys 0.60.2", +] + +[[package]] +name = "rustls" +version = "0.23.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8572f3c2cb9934231157b45499fc41e1f58c589fdfb81a844ba873265e80f8eb" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + +[[package]] +name = "ruzstd" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fad02996bfc73da3e301efe90b1837be9ed8f4a462b6ed410aa35d00381de89f" +dependencies = [ + "twox-hash 1.6.3", ] [[package]] -name = "fnv" -version = "1.0.7" +name = "ryu" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] -name = "foldhash" -version = "0.1.5" +name = "same-file" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] [[package]] -name = "fst-reader" -version = "0.8.7" +name = "schannel" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3119a583528a16c1b77a2d27aabfe041918b954e6638c5ee2c197c25048a02ee" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "flate2", - "lz4_flex", - "num_enum", - "tempfile", - "thiserror", + "windows-sys 0.61.1", ] [[package]] -name = "gdbstub" -version = "0.7.6" +name = "scoped-tls" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d66e32caf5dd59f561be0143e413e01d651bd8498eb9aa0be8c482c81c8d31" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scroll" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ab8598aa408498679922eff7fa985c25d58a90771bd6be794434c5277eab1a6" dependencies = [ - "bitflags", - "cfg-if", - "log", - "managed", - "num-traits", - "paste", + "scroll_derive 0.12.1", ] [[package]] -name = "gdbstub_arch" -version = "0.3.2" +name = "scroll" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22dde0e1b68787036ccedd0b1ff6f953527a0e807e571fbe898975203027278f" +checksum = "c1257cd4248b4132760d6524d6dda4e053bc648c9070b960929bf50cfb1e7add" dependencies = [ - "gdbstub", - "num-traits", + "scroll_derive 0.13.0", ] [[package]] -name = "getrandom" -version = "0.3.3" +name = "scroll_derive" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "1783eabc414609e28a5ba76aee5ddd52199f7107a0b24c2e9746a1ecc34a683d" dependencies = [ - "cfg-if", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "scroll_derive" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22fc4f90c27b57691bbaf11d8ecc7cfbfe98a4da6dbe60226115d322aa80c06e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.9.1", + "core-foundation 0.9.4", + "core-foundation-sys", "libc", - "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "security-framework-sys", ] [[package]] -name = "gimli" -version = "0.31.1" +name = "security-framework-sys" +version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" dependencies = [ - "fallible-iterator", - "indexmap", - "stable_deref_trait", + "core-foundation-sys", + "libc", ] [[package]] -name = "glob" -version = "0.3.2" +name = "serde" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] [[package]] -name = "goblin" -version = "0.9.3" +name = "serde_derive" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daa0a64d21a7eb230583b4c5f4e23b7e4e57974f96620f42a7e75e08ae66d745" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.143" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_spanned" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "shucks" +version = "0.1.0" dependencies = [ + "addr2line 0.24.2", + "anyhow", + "dang", + "env_logger", + "gdbstub", + "gdbstub_arch", + "gimli 0.31.1", + "goblin 0.10.0", "log", - "plain", - "scroll 0.12.0", + "nucleo-matcher", + "object 0.36.7", + "raki", + "wellen 0.12.1", ] [[package]] -name = "goblin" -version = "0.10.0" +name = "signal-hook" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e961b33649994dcf69303af6b3a332c1228549e604d455d61ec5d2ab5e68d3a" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +dependencies = [ + "libc", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "simple-eyre" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b561532e8ffe7ecf09108c4f662896a9ec3eac4999eba84015ec3dcb8cc630a" +dependencies = [ + "eyre", + "indenter", +] + +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + +[[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.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "smithay-client-toolkit" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" dependencies = [ + "bitflags 2.9.1", + "calloop", + "calloop-wayland-source", + "cursor-icon", + "libc", "log", - "plain", - "scroll 0.13.0", + "memmap2", + "rustix 0.38.44", + "thiserror 1.0.69", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", ] [[package]] -name = "hashbrown" -version = "0.15.4" +name = "smithay-clipboard" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +checksum = "cc8216eec463674a0e90f29e0ae41a4db573ec5b56b1c6c1c71615d249b6d846" dependencies = [ - "allocator-api2", - "equivalent", - "foldhash", + "libc", + "smithay-client-toolkit", + "wayland-backend", ] [[package]] -name = "heck" -version = "0.4.1" +name = "smol_str" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +dependencies = [ + "serde", +] + +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] [[package]] -name = "heck" -version = "0.5.0" +name = "softposit" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +checksum = "8091c9c836e6d8cd1d510e65c4b8e7eb42b9ad876d95723cd35982e5c38f7ee1" +dependencies = [ + "num-traits", +] [[package]] -name = "hermit-abi" -version = "0.5.2" +name = "stable_deref_trait" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] -name = "ident_case" -version = "1.0.1" +name = "static_assertions" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] -name = "indexmap" -version = "2.10.0" +name = "strsim" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" -dependencies = [ - "equivalent", - "hashbrown", -] +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] -name = "indoc" -version = "2.0.6" +name = "strum" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] [[package]] -name = "instability" -version = "0.3.9" +name = "strum_macros" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435d80800b936787d62688c927b6490e887c7ef5ff9ce922c6c6050fca75eb9a" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "darling", - "indoc", + "heck 0.5.0", "proc-macro2", "quote", + "rustversion", "syn", ] [[package]] -name = "is_terminal_polyfill" -version = "1.70.1" +name = "subtle" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +name = "surfer-translation-types" +version = "0.4.0-dev" +source = "git+https://gitlab.com/surfer-project/surfer#1d83e7c22dffa8801e3a37966bc70427e92dce4f" dependencies = [ - "either", + "derive_more", + "ecolor", + "eyre", + "num", + "serde", ] [[package]] -name = "itoa" -version = "1.0.15" +name = "surver" +version = "0.4.0-dev" +source = "git+https://gitlab.com/surfer-project/surfer#1d83e7c22dffa8801e3a37966bc70427e92dce4f" +dependencies = [ + "bincode", + "bytesize 2.1.0", + "clap", + "eyre", + "fastrand", + "fern", + "http-body-util", + "hyper", + "hyper-util", + "lazy_static", + "leb128", + "log", + "lz4_flex", + "serde", + "serde_json", + "simple-eyre", + "tokio", + "web-time", + "wellen 0.19.0", + "whoami", +] + +[[package]] +name = "syn" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] -name = "jiff" -version = "0.2.15" +name = "sync_wrapper" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" dependencies = [ - "jiff-static", - "log", - "portable-atomic", - "portable-atomic-util", - "serde", + "futures-core", ] [[package]] -name = "jiff-static" -version = "0.2.15" +name = "synstructure" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", @@ -603,888 +4334,1069 @@ dependencies = [ ] [[package]] -name = "jpdb" -version = "0.1.0" +name = "sys-locale" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4" dependencies = [ - "crossterm", - "dang", - "env_logger", - "log", - "ratatui", - "shucks", + "libc", ] [[package]] -name = "leb128" -version = "0.2.5" +name = "system-configuration" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.9.1", + "core-foundation 0.9.4", + "system-configuration-sys", +] [[package]] -name = "libc" -version = "0.2.174" +name = "system-configuration-sys" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] [[package]] -name = "linux-raw-sys" -version = "0.4.15" +name = "target-lexicon" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] -name = "linux-raw-sys" -version = "0.9.4" +name = "tempfile" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +dependencies = [ + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix 1.0.8", + "windows-sys 0.59.0", +] [[package]] -name = "lock_api" -version = "0.4.13" +name = "termcolor" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ - "autocfg", - "scopeguard", + "winapi-util", ] [[package]] -name = "log" -version = "0.4.27" +name = "thiserror" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] [[package]] -name = "lru" -version = "0.12.5" +name = "thiserror" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "hashbrown", + "thiserror-impl 2.0.17", ] [[package]] -name = "lz4_flex" -version = "0.11.5" +name = "thiserror-impl" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08ab2867e3eeeca90e844d1940eab391c9dc5228783db2ed999acbc0a9ed375a" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ - "twox-hash 2.1.1", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "managed" -version = "0.8.0" +name = "thiserror-impl" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "memchr" -version = "2.7.5" +name = "thread_local" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] [[package]] -name = "memmap2" -version = "0.9.7" +name = "tiff" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "483758ad303d734cec05e5c12b41d7e93e6a6390c5e9dae6bdeb7c1259012d28" +checksum = "af9605de7fee8d9551863fd692cce7637f548dbd9db9180fcc07ccc6d26c336f" +dependencies = [ + "fax", + "flate2", + "half", + "quick-error", + "weezl", + "zune-jpeg", +] + +[[package]] +name = "time" +version = "0.3.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ + "deranged", + "itoa", "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde", + "time-core", + "time-macros", ] [[package]] -name = "memoffset" -version = "0.9.1" +name = "time-core" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" + +[[package]] +name = "time-macros" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" dependencies = [ - "autocfg", + "num-conv", + "time-core", ] [[package]] -name = "miniz_oxide" -version = "0.8.9" +name = "tinystr" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" dependencies = [ - "adler2", + "displaydoc", + "zerovec", ] [[package]] -name = "mio" -version = "1.0.4" +name = "tokio" +version = "1.47.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" dependencies = [ + "backtrace", + "bytes", + "io-uring", "libc", - "log", - "wasi 0.11.1+wasi-snapshot-preview1", + "mio", + "pin-project-lite", + "signal-hook-registry", + "slab", + "socket2", + "tokio-macros", + "tracing", "windows-sys 0.59.0", ] [[package]] -name = "nucleo-matcher" -version = "0.3.1" +name = "tokio-macros" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf33f538733d1a5a3494b836ba913207f14d9d4a1d3cd67030c5061bdd2cac85" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ - "memchr", - "unicode-segmentation", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "num-bigint" -version = "0.4.6" +name = "tokio-native-tls" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ - "num-integer", - "num-traits", + "native-tls", + "tokio", ] [[package]] -name = "num-integer" -version = "0.1.46" +name = "tokio-rustls" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "num-traits", + "rustls", + "tokio", ] [[package]] -name = "num-traits" -version = "0.2.19" +name = "tokio-stream" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" dependencies = [ - "autocfg", + "futures-core", + "pin-project-lite", + "tokio", ] [[package]] -name = "num_cpus" -version = "1.17.0" +name = "tokio-util" +version = "0.7.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" dependencies = [ - "hermit-abi", - "libc", + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", ] [[package]] -name = "num_enum" -version = "0.7.4" +name = "toml" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" +checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8" dependencies = [ - "num_enum_derive", - "rustversion", + "indexmap", + "serde", + "serde_spanned", + "toml_datetime 0.7.0", + "toml_parser", + "toml_writer", + "winnow", ] [[package]] -name = "num_enum_derive" -version = "0.7.4" +name = "toml_datetime" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" + +[[package]] +name = "toml_datetime" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3" dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", + "serde", ] [[package]] -name = "object" -version = "0.36.7" +name = "toml_edit" +version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "flate2", - "memchr", - "ruzstd", + "indexmap", + "toml_datetime 0.6.11", + "winnow", ] [[package]] -name = "once_cell" -version = "1.21.3" +name = "toml_parser" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10" +dependencies = [ + "winnow", +] [[package]] -name = "once_cell_polyfill" -version = "1.70.1" +name = "toml_writer" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" +checksum = "d163a63c116ce562a22cda521fcc4d79152e7aba014456fb5eb442f6d6a10109" [[package]] -name = "parking_lot" -version = "0.12.4" +name = "tower" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ - "lock_api", - "parking_lot_core", + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", ] [[package]] -name = "parking_lot_core" -version = "0.9.11" +name = "tower-http" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.52.6", + "bitflags 2.9.1", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", ] [[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "plain" -version = "0.2.3" +name = "tower-layer" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] -name = "portable-atomic" -version = "1.11.1" +name = "tower-service" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] -name = "portable-atomic-util" -version = "0.2.4" +name = "tracing" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ - "portable-atomic", + "pin-project-lite", + "tracing-attributes", + "tracing-core", ] [[package]] -name = "proc-macro-crate" -version = "3.3.0" +name = "tracing-attributes" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ - "toml_edit", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "proc-macro2" -version = "1.0.95" +name = "tracing-core" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ - "unicode-ident", + "once_cell", ] [[package]] -name = "pyo3" -version = "0.21.2" +name = "try-lock" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e00b96a521718e08e03b1a622f01c8a8deb50719335de3f60b3b3950f069d8" -dependencies = [ - "cfg-if", - "indoc", - "libc", - "memoffset", - "num-bigint", - "parking_lot", - "portable-atomic", - "pyo3-build-config", - "pyo3-ffi", - "pyo3-macros", - "unindent", -] +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] -name = "pyo3-build-config" -version = "0.21.2" +name = "ttf-parser" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7883df5835fafdad87c0d888b266c8ec0f4c9ca48a5bed6bbb592e8dedee1b50" -dependencies = [ - "once_cell", - "target-lexicon", -] +checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" [[package]] -name = "pyo3-ffi" -version = "0.21.2" +name = "twox-hash" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01be5843dc60b916ab4dad1dca6d20b9b4e6ddc8e15f50c47fe6d85f1fb97403" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ - "libc", - "pyo3-build-config", + "cfg-if", + "static_assertions", ] [[package]] -name = "pyo3-macros" -version = "0.21.2" +name = "twox-hash" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77b34069fc0682e11b31dbd10321cbf94808394c56fd996796ce45217dfac53c" -dependencies = [ - "proc-macro2", - "pyo3-macros-backend", - "quote", - "syn", -] +checksum = "8b907da542cbced5261bd3256de1b3a1bf340a3d37f93425a07362a1d687de56" [[package]] -name = "pyo3-macros-backend" -version = "0.21.2" +name = "type-map" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08260721f32db5e1a5beae69a55553f56b99bd0e1c3e6e0a5e8851a9d0f5a85c" +checksum = "cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90" dependencies = [ - "heck 0.4.1", - "proc-macro2", - "pyo3-build-config", - "quote", - "syn", + "rustc-hash 2.1.1", ] [[package]] -name = "pywellen" -version = "0.12.1" -source = "git+https://github.com/1024bees/wellen.git?branch=signal-builders#36d7247cf1a142e92d6fd3827574cc98592b483a" -dependencies = [ - "bytemuck", - "num-bigint", - "pyo3", - "wellen", -] +name = "typed-arena" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" [[package]] -name = "quote" -version = "1.0.40" +name = "uds_windows" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" dependencies = [ - "proc-macro2", + "memoffset", + "tempfile", + "winapi", ] [[package]] -name = "r-efi" -version = "5.3.0" +name = "unicode-ident" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] -name = "raki" -version = "1.3.2" +name = "unicode-segmentation" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3857a0e1e2be1236e18c3bf84ba90b0d0523fc17b48557c9e3c4ee21a4d04448" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] -name = "ratatui" -version = "0.28.1" +name = "unicode-truncate" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdef7f9be5c0122f890d58bdf4d964349ba6a6161f705907526d891efabba57d" +checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf" dependencies = [ - "bitflags", - "cassowary", - "compact_str", - "crossterm", - "instability", - "itertools", - "lru", - "paste", - "strum", - "strum_macros", + "itertools 0.13.0", "unicode-segmentation", - "unicode-truncate", "unicode-width", ] [[package]] -name = "rayon" -version = "1.10.0" +name = "unicode-width" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" -dependencies = [ - "either", - "rayon-core", -] +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] -name = "rayon-core" -version = "1.12.1" +name = "unicode-xid" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] -name = "redox_syscall" -version = "0.5.16" +name = "unindent" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7251471db004e509f4e75a62cca9435365b5ec7bcdff530d612ac7c87c44a792" -dependencies = [ - "bitflags", -] +checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3" [[package]] -name = "regex" -version = "1.11.1" +name = "unsafe-libyaml" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] -name = "regex-automata" -version = "0.4.9" +name = "untrusted" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", + "form_urlencoded", + "idna", + "percent-encoding", + "serde", ] [[package]] -name = "regex-syntax" -version = "0.8.5" +name = "urlencoding" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" [[package]] -name = "rust-fuzzy-search" -version = "0.1.1" +name = "utf8_iter" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a157657054ffe556d8858504af8a672a054a6e0bd9e8ee531059100c0fa11bb2" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] -name = "rustc-demangle" -version = "0.1.26" +name = "utf8parse" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] -name = "rustix" -version = "0.38.44" +name = "vcpkg" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "vergen" +version = "9.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b2bf58be11fc9414104c6d3a2e464163db5ef74b12296bda593cac37b6e4777" dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", + "anyhow", + "derive_builder", + "rustversion", + "time", + "vergen-lib", ] [[package]] -name = "rustix" +name = "vergen-gitcl" version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +checksum = "b9dfc1de6eb2e08a4ddf152f1b179529638bedc0ea95e6d667c014506377aefe" dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys 0.9.4", - "windows-sys 0.60.2", + "anyhow", + "derive_builder", + "rustversion", + "time", + "vergen", + "vergen-lib", ] [[package]] -name = "rustversion" -version = "1.0.21" +name = "vergen-lib" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" +checksum = "9b07e6010c0f3e59fcb164e0163834597da68d1f864e2b8ca49f74de01e9c166" +dependencies = [ + "anyhow", + "derive_builder", + "rustversion", +] [[package]] -name = "ruzstd" -version = "0.7.3" +name = "version_check" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad02996bfc73da3e301efe90b1837be9ed8f4a462b6ed410aa35d00381de89f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ - "twox-hash 1.6.3", + "same-file", + "winapi-util", ] [[package]] -name = "ryu" -version = "1.0.20" +name = "want" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] [[package]] -name = "scopeguard" -version = "1.2.0" +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "scroll" -version = "0.12.0" +name = "wasi" +version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ab8598aa408498679922eff7fa985c25d58a90771bd6be794434c5277eab1a6" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" dependencies = [ - "scroll_derive 0.12.1", + "wit-bindgen-rt", ] [[package]] -name = "scroll" -version = "0.13.0" +name = "wasite" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1257cd4248b4132760d6524d6dda4e053bc648c9070b960929bf50cfb1e7add" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ - "scroll_derive 0.13.0", + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", ] [[package]] -name = "scroll_derive" -version = "0.12.1" +name = "wasm-bindgen-backend" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1783eabc414609e28a5ba76aee5ddd52199f7107a0b24c2e9746a1ecc34a683d" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ + "bumpalo", + "log", "proc-macro2", "quote", "syn", + "wasm-bindgen-shared", ] [[package]] -name = "scroll_derive" -version = "0.13.0" +name = "wasm-bindgen-futures" +version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22fc4f90c27b57691bbaf11d8ecc7cfbfe98a4da6dbe60226115d322aa80c06e" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ - "proc-macro2", - "quote", - "syn", + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", ] [[package]] -name = "serde" -version = "1.0.219" +name = "wasm-bindgen-macro" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ - "serde_derive", + "quote", + "wasm-bindgen-macro-support", ] [[package]] -name = "serde_derive" -version = "1.0.219" +name = "wasm-bindgen-macro-support" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", ] [[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" +name = "wasm-bindgen-shared" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" dependencies = [ - "indexmap", - "itoa", - "ryu", - "serde", - "unsafe-libyaml", + "unicode-ident", ] [[package]] -name = "shlex" -version = "1.3.0" +name = "wasm-streams" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "shucks" -version = "0.1.0" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" dependencies = [ - "addr2line", - "anyhow", - "dang", - "env_logger", - "gdbstub", - "gdbstub_arch", - "gimli", - "goblin 0.10.0", - "log", - "nucleo-matcher", - "object", - "raki", - "wellen", + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", ] [[package]] -name = "signal-hook" -version = "0.3.18" +name = "wayland-backend" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35" dependencies = [ - "libc", - "signal-hook-registry", + "cc", + "downcast-rs", + "rustix 1.0.8", + "scoped-tls", + "smallvec", + "wayland-sys", ] [[package]] -name = "signal-hook-mio" -version = "0.2.4" +name = "wayland-client" +version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" +checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d" dependencies = [ - "libc", - "mio", - "signal-hook", + "bitflags 2.9.1", + "rustix 1.0.8", + "wayland-backend", + "wayland-scanner", ] [[package]] -name = "signal-hook-registry" -version = "1.4.6" +name = "wayland-csd-frame" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "libc", + "bitflags 2.9.1", + "cursor-icon", + "wayland-backend", ] [[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" +name = "wayland-cursor" +version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "447ccc440a881271b19e9989f75726d60faa09b95b0200a9b7eb5cc47c3eeb29" +dependencies = [ + "rustix 1.0.8", + "wayland-client", + "xcursor", +] [[package]] -name = "static_assertions" -version = "1.1.0" +name = "wayland-protocols" +version = "0.32.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901" +dependencies = [ + "bitflags 2.9.1", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] [[package]] -name = "strsim" -version = "0.11.1" +name = "wayland-protocols-plasma" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +checksum = "a07a14257c077ab3279987c4f8bb987851bf57081b93710381daea94f2c2c032" +dependencies = [ + "bitflags 2.9.1", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] [[package]] -name = "strum" -version = "0.26.3" +name = "wayland-protocols-wlr" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +checksum = "efd94963ed43cf9938a090ca4f7da58eb55325ec8200c3848963e98dc25b78ec" dependencies = [ - "strum_macros", + "bitflags 2.9.1", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", ] [[package]] -name = "strum_macros" -version = "0.26.4" +name = "wayland-scanner" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +checksum = "54cb1e9dc49da91950bdfd8b848c49330536d9d1fb03d4bfec8cae50caa50ae3" dependencies = [ - "heck 0.5.0", "proc-macro2", + "quick-xml", "quote", - "rustversion", - "syn", ] [[package]] -name = "syn" -version = "2.0.104" +name = "wayland-sys" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "34949b42822155826b41db8e5d0c1be3a2bd296c747577a43a3e6daefc296142" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "dlib", + "log", + "once_cell", + "pkg-config", ] [[package]] -name = "target-lexicon" -version = "0.12.16" +name = "web-sys" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] [[package]] -name = "tempfile" -version = "3.20.0" +name = "web-time" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ - "fastrand", - "getrandom", - "once_cell", - "rustix 1.0.8", - "windows-sys 0.59.0", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "thiserror" -version = "1.0.69" +name = "webbrowser" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +checksum = "aaf4f3c0ba838e82b4e5ccc4157003fb8c324ee24c058470ffb82820becbde98" dependencies = [ - "thiserror-impl", + "core-foundation 0.10.1", + "jni", + "log", + "ndk-context", + "objc2 0.6.2", + "objc2-foundation 0.3.1", + "url", + "web-sys", ] [[package]] -name = "thiserror-impl" -version = "1.0.69" +name = "weezl" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3" + +[[package]] +name = "wellen" +version = "0.12.1" +source = "git+https://github.com/1024bees/wellen.git?branch=signal-builders#36d7247cf1a142e92d6fd3827574cc98592b483a" dependencies = [ - "proc-macro2", - "quote", - "syn", + "bytesize 1.3.3", + "fst-reader 0.8.7", + "leb128", + "lz4_flex", + "memmap2", + "num_enum", + "rayon", + "thiserror 1.0.69", ] [[package]] -name = "toml_datetime" -version = "0.6.11" +name = "wellen" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +checksum = "c1b17b319dff557c420010e79278ae0ab85c2dce8a8f5d2860c87579c6b9e108" +dependencies = [ + "fst-reader 0.14.1", + "indexmap", + "leb128", + "lz4_flex", + "memmap2", + "miniz_oxide", + "num_enum", + "rayon", + "rustc-hash 2.1.1", + "serde", + "thiserror 2.0.17", +] [[package]] -name = "toml_edit" -version = "0.22.27" +name = "wgpu" +version = "25.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +checksum = "ec8fb398f119472be4d80bc3647339f56eb63b2a331f6a3d16e25d8144197dd9" dependencies = [ - "indexmap", - "toml_datetime", - "winnow", + "arrayvec", + "bitflags 2.9.1", + "cfg_aliases", + "document-features", + "hashbrown", + "js-sys", + "log", + "parking_lot", + "portable-atomic", + "profiling", + "raw-window-handle", + "smallvec", + "static_assertions", + "wasm-bindgen", + "web-sys", + "wgpu-core", + "wgpu-hal", + "wgpu-types", ] [[package]] -name = "twox-hash" -version = "1.6.3" +name = "wgpu-core" +version = "25.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +checksum = "f7b882196f8368511d613c6aeec80655160db6646aebddf8328879a88d54e500" dependencies = [ - "cfg-if", - "static_assertions", + "arrayvec", + "bit-set", + "bit-vec", + "bitflags 2.9.1", + "cfg_aliases", + "document-features", + "hashbrown", + "indexmap", + "log", + "naga", + "once_cell", + "parking_lot", + "portable-atomic", + "profiling", + "raw-window-handle", + "rustc-hash 1.1.0", + "smallvec", + "thiserror 2.0.17", + "wgpu-core-deps-windows-linux-android", + "wgpu-hal", + "wgpu-types", ] [[package]] -name = "twox-hash" -version = "2.1.1" +name = "wgpu-core-deps-windows-linux-android" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b907da542cbced5261bd3256de1b3a1bf340a3d37f93425a07362a1d687de56" +checksum = "cba5fb5f7f9c98baa7c889d444f63ace25574833df56f5b817985f641af58e46" +dependencies = [ + "wgpu-hal", +] [[package]] -name = "typed-arena" -version = "2.0.2" +name = "wgpu-hal" +version = "25.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" +checksum = "f968767fe4d3d33747bbd1473ccd55bf0f6451f55d733b5597e67b5deab4ad17" +dependencies = [ + "bitflags 2.9.1", + "cfg_aliases", + "libloading", + "log", + "naga", + "parking_lot", + "portable-atomic", + "raw-window-handle", + "renderdoc-sys", + "thiserror 2.0.17", + "wgpu-types", +] [[package]] -name = "unicode-ident" -version = "1.0.18" +name = "wgpu-types" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "2aa49460c2a8ee8edba3fca54325540d904dd85b2e086ada762767e17d06e8bc" +dependencies = [ + "bitflags 2.9.1", + "bytemuck", + "js-sys", + "log", + "thiserror 2.0.17", + "web-sys", +] [[package]] -name = "unicode-segmentation" -version = "1.12.0" +name = "whoami" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" +dependencies = [ + "libredox", + "wasite", + "web-sys", +] [[package]] -name = "unicode-truncate" -version = "1.1.0" +name = "winapi" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ - "itertools", - "unicode-segmentation", - "unicode-width", + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", ] [[package]] -name = "unicode-width" -version = "0.1.14" +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] -name = "unindent" -version = "0.2.4" +name = "winapi-util" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.59.0", +] [[package]] -name = "unsafe-libyaml" -version = "0.2.11" +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "utf8parse" -version = "0.2.2" +name = "windows-link" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" [[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" +name = "windows-link" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" [[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" +name = "windows-registry" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" dependencies = [ - "wit-bindgen-rt", + "windows-link 0.1.3", + "windows-result", + "windows-strings", ] [[package]] -name = "wellen" -version = "0.12.1" -source = "git+https://github.com/1024bees/wellen.git?branch=signal-builders#36d7247cf1a142e92d6fd3827574cc98592b483a" +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "bytesize", - "fst-reader", - "leb128", - "lz4_flex", - "memmap2", - "num_enum", - "rayon", - "thiserror", + "windows-link 0.1.3", ] [[package]] -name = "winapi" -version = "0.3.9" +name = "windows-strings" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "windows-link 0.1.3", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "windows-sys" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "windows-sys" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] [[package]] name = "windows-sys" @@ -1504,6 +5416,30 @@ dependencies = [ "windows-targets 0.53.2", ] +[[package]] +name = "windows-sys" +version = "0.61.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" +dependencies = [ + "windows-link 0.2.0", +] + +[[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.52.6" @@ -1536,6 +5472,12 @@ dependencies = [ "windows_x86_64_msvc 0.53.0", ] +[[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.52.6" @@ -1548,6 +5490,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +[[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.52.6" @@ -1560,6 +5508,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +[[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.52.6" @@ -1584,6 +5538,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +[[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.52.6" @@ -1596,6 +5556,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +[[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.52.6" @@ -1608,6 +5574,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +[[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.52.6" @@ -1620,6 +5592,12 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +[[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.52.6" @@ -1632,6 +5610,57 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +[[package]] +name = "winit" +version = "0.30.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66d4b9ed69c4009f6321f762d6e61ad8a2389cd431b97cb1e146812e9e6c732" +dependencies = [ + "ahash", + "android-activity", + "atomic-waker", + "bitflags 2.9.1", + "block2 0.5.1", + "bytemuck", + "calloop", + "cfg_aliases", + "concurrent-queue", + "core-foundation 0.9.4", + "core-graphics", + "cursor-icon", + "dpi", + "js-sys", + "libc", + "memmap2", + "ndk", + "objc2 0.5.2", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", + "objc2-ui-kit", + "orbclient", + "percent-encoding", + "pin-project", + "raw-window-handle", + "redox_syscall 0.4.1", + "rustix 0.38.44", + "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.7.12" @@ -1647,5 +5676,289 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "bitflags", + "bitflags 2.9.1", +] + +[[package]] +name = "writeable" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" +dependencies = [ + "as-raw-xcb-connection", + "gethostname", + "libc", + "libloading", + "once_cell", + "rustix 1.0.8", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" + +[[package]] +name = "xcursor" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec9e4a500ca8864c5b47b8b482a73d62e4237670e5b5f1d6b9e3cae50f28f2b" + +[[package]] +name = "xkbcommon-dl" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" +dependencies = [ + "bitflags 2.9.1", + "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.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fd8403733700263c6eb89f192880191f1b83e332f7a20371ddcf421c4a337c7" + +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zbus" +version = "5.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d07e46d035fb8e375b2ce63ba4e4ff90a7f73cf2ffb0138b29e1158d2eaadf7" +dependencies = [ + "async-broadcast", + "async-recursion", + "async-trait", + "enumflags2", + "event-listener", + "futures-core", + "futures-lite", + "hex", + "nix", + "ordered-stream", + "serde", + "serde_repr", + "tokio", + "tracing", + "uds_windows", + "windows-sys 0.60.2", + "winnow", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "5.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e797a9c847ed3ccc5b6254e8bcce056494b375b511b3d6edcec0aeb4defaca" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", + "zbus_names", + "zvariant", + "zvariant_utils", +] + +[[package]] +name = "zbus_names" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97" +dependencies = [ + "serde", + "static_assertions", + "winnow", + "zvariant", +] + +[[package]] +name = "zerocopy" +version = "0.8.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + +[[package]] +name = "zune-jpeg" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ce2c8a9384ad323cf564b67da86e21d3cfdff87908bc1223ed5c99bc792713" +dependencies = [ + "zune-core", +] + +[[package]] +name = "zvariant" +version = "5.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "999dd3be73c52b1fccd109a4a81e4fcd20fab1d3599c8121b38d04e1419498db" +dependencies = [ + "endi", + "enumflags2", + "serde", + "url", + "winnow", + "zvariant_derive", + "zvariant_utils", +] + +[[package]] +name = "zvariant_derive" +version = "5.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6643fd0b26a46d226bd90d3f07c1b5321fe9bb7f04673cb37ac6d6883885b68e" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6949d142f89f6916deca2232cf26a8afacf2b9fdc35ce766105e104478be599" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "syn", + "winnow", ] diff --git a/Cargo.toml b/Cargo.toml index aa18856..03f1d6c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ pywellen = { git = "https://github.com/1024bees/wellen.git", branch = "signal-bu anyhow = "1" object = "0.36" addr2line = "0.24" +argh = "0.1" [profile.release] debug = true diff --git a/README.md b/README.md index 01fe307..cae8d90 100644 --- a/README.md +++ b/README.md @@ -94,3 +94,19 @@ no, but it could integrate with vaporview or surfer fairly easily `wellen` library made this easy, thank you kevin laeufer also tom verbeure did something similar a while back, shoutout + + +### Internals + +JPDB is really a few things glued together + +* dang: a GDB server for pre-sillicon CPUs +* shucks: a GDB client, written for this project specfically, with some extra hooks for interacting with waves via `wellen` +* a tui, showing the state taken out of shucks + +when i was starting this out, the point was to start out with just dang and make people bring their own GDB. but two things quickly became clear: + +1. its kind of annoying to get your own gdb. i develop on a mac, and building gdb from scratch on a mac is non trivial. distributing it broadly for people to actually use also kind of sucks +2. having control over the TUI would be useful for more aggresively integrating with wave specific stuff + +you can use these libaries on their own. they should _just_work_ hopefully diff --git a/dang/src/cli.rs b/dang/src/cli.rs index a489b78..96750d3 100644 --- a/dang/src/cli.rs +++ b/dang/src/cli.rs @@ -154,7 +154,7 @@ pub fn start_with_args_and_port( let _ = env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")) .try_init(); - log::info!("starting logger to stdout"); + log::debug!("starting logger to stdout"); let mut emu = Waver::new(wave_path, mapping_path, elf).expect("Could not create wave runtime"); @@ -166,32 +166,32 @@ pub fn start_with_args_and_port( match gdb.run_blocking::(&mut emu) { Ok(disconnect_reason) => match disconnect_reason { DisconnectReason::Disconnect => { - log::info!("GDB client has disconnected. Running to completion..."); + log::debug!("GDB client has disconnected. Running to completion..."); } DisconnectReason::TargetExited(code) => { - log::info!("Target exited with code {code}!") + log::debug!("Target exited with code {code}!") } DisconnectReason::TargetTerminated(sig) => { - log::info!("Target terminated with signal {sig}!") + log::debug!("Target terminated with signal {sig}!") } - DisconnectReason::Kill => log::info!("GDB sent a kill command!"), + DisconnectReason::Kill => log::debug!("GDB sent a kill command!"), }, Err(e) => { if e.is_target_error() { - log::info!( + log::debug!( "target encountered a fatal error: {}", e.into_target_error().unwrap() ) } else if e.is_connection_error() { let (e, kind) = e.into_connection_error().unwrap(); - log::info!("connection error: {kind:?} - {e}",) + log::debug!("connection error: {kind:?} - {e}",) } else { - log::info!("gdbstub encountered a fatal error: {e}") + log::debug!("gdbstub encountered a fatal error: {e}") } } } - log::info!("Program completed"); + log::debug!("Program completed"); Ok(()) } @@ -204,16 +204,16 @@ pub fn start_with_args_and_listener( ) -> DynResult<()> { let _ = env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("debug")) .try_init(); - log::info!("started"); + log::debug!("started"); let mut emu = Waver::new(wave_path, mapping_path, elf).expect("Could not create wave runtime"); - log::info!("emulator made"); + log::debug!("emulator made"); let connection: Box> = { Box::new(wait_for_tcp_with_listener(listener)?) }; - log::info!("connection made"); + log::debug!("connection made"); let gdb = GdbStub::new(connection); @@ -222,32 +222,32 @@ pub fn start_with_args_and_listener( match gdb.run_blocking::(&mut emu) { Ok(disconnect_reason) => match disconnect_reason { DisconnectReason::Disconnect => { - log::info!("GDB client has disconnected. Running to completion..."); + log::debug!("GDB client has disconnected. Running to completion..."); } DisconnectReason::TargetExited(code) => { - log::info!("Target exited with code {code}!") + log::debug!("Target exited with code {code}!") } DisconnectReason::TargetTerminated(sig) => { - log::info!("Target terminated with signal {sig}!") + log::debug!("Target terminated with signal {sig}!") } - DisconnectReason::Kill => log::info!("GDB sent a kill command!"), + DisconnectReason::Kill => log::debug!("GDB sent a kill command!"), }, Err(e) => { if e.is_target_error() { - log::info!( + log::debug!( "target encountered a fatal error: {}", e.into_target_error().unwrap() ) } else if e.is_connection_error() { let (e, kind) = e.into_connection_error().unwrap(); - log::info!("connection error: {kind:?} - {e}",) + log::debug!("connection error: {kind:?} - {e}",) } else { - log::info!("gdbstub encountered a fatal error: {e}") + log::debug!("gdbstub encountered a fatal error: {e}") } } } - log::info!("Program completed"); + log::debug!("Program completed"); Ok(()) } diff --git a/dang/src/gdb.rs b/dang/src/gdb.rs index 8fd9ebb..32b1bb7 100644 --- a/dang/src/gdb.rs +++ b/dang/src/gdb.rs @@ -74,7 +74,7 @@ impl MonitorCmd for Waver { cmd: &[u8], mut out: ConsoleOutput<'_>, ) -> Result<(), Self::Error> { - log::info!("DANG SERVER: Received monitor command (QRcmd) with raw bytes: {cmd:?}"); + log::debug!("DANG SERVER: Received monitor command (QRcmd) with raw bytes: {cmd:?}"); let cmd = match core::str::from_utf8(cmd) { Ok(cmd) => cmd, Err(_) => { @@ -82,7 +82,7 @@ impl MonitorCmd for Waver { return Ok(()); } }; - log::info!("DANG SERVER: Processing monitor command: '{cmd}'"); + log::debug!("DANG SERVER: Processing monitor command: '{cmd}'"); match cmd { "" => outputln!(out, @@ -90,7 +90,7 @@ impl MonitorCmd for Waver { ), "time_idx" => { let time_idx = self.cursor.time_idx; - log::info!("DANG SERVER: time_idx command returning: {time_idx}"); + log::debug!("DANG SERVER: time_idx command returning: {time_idx}"); outputln!(out, "{}", time_idx) }, _ => outputln!(out, "I don't know how to handle '{}'", cmd), @@ -242,9 +242,9 @@ impl SingleThreadBase for Waver { &mut self, regs: &mut ::Registers, ) -> TargetResult<(), Self> { - log::info!("DANG SERVER: Received read_registers command (LowerG)"); + log::debug!("DANG SERVER: Received read_registers command (LowerG)"); regs.pc = self.get_current_pc(); - log::info!("reading pc; pc is {:x}", regs.pc); + log::debug!("reading pc; pc is {:x}", regs.pc); for i in 0..32 { log::trace!("regs {} is {:x}", i, self.get_current_gpr(i)); regs.x[i] = self.get_current_gpr(i); @@ -267,7 +267,7 @@ impl SingleThreadBase for Waver { } fn read_addrs(&mut self, start_addr: u32, data: &mut [u8]) -> TargetResult { - log::info!("DANG SERVER: Received read_addrs command (LowerM) - reading memory from {:x} to {:x}, {} bytes", + log::debug!("DANG SERVER: Received read_addrs command (LowerM) - reading memory from {:x} to {:x}, {} bytes", start_addr, start_addr + data.len() as u32, data.len() @@ -372,7 +372,7 @@ impl target::ext::base::single_register_access::SingleRegisterAccess<()> for Wav _ => Err(TargetError::NonFatal), }; if let Ok(ref inner) = rv { - log::info!("read reg {reg_id:?}, {inner:?} bytes at idx {idx:?}"); + log::debug!("read reg {reg_id:?}, {inner:?} bytes at idx {idx:?}"); } else { log::error!("failed to read reg {reg_id:?}"); } @@ -392,7 +392,7 @@ impl target::ext::base::single_register_access::SingleRegisterAccess<()> for Wav impl target::ext::base::reverse_exec::ReverseCont<()> for Waver { fn reverse_cont(&mut self) -> Result<(), Self::Error> { // FIXME: actually implement reverse step - log::info!( + log::debug!( "FIXME: Not actually reverse-continuing. Performing forwards continue instead..." ); self.exec_mode = ExecMode::Continue; @@ -404,7 +404,7 @@ impl target::ext::base::reverse_exec::ReverseStep<()> for Waver { fn reverse_step(&mut self, _tid: ()) -> Result<(), Self::Error> { // FIXME: actually implement reverse step - log::info!( + log::debug!( "FIXME: Not actually reverse-stepping. Performing single forwards step instead..." ); self.exec_mode = ExecMode::Step; @@ -421,17 +421,17 @@ impl target::ext::base::singlethread::SingleThreadRangeStepping for Waver { impl target::ext::extended_mode::ExtendedMode for Waver { fn kill(&mut self, pid: Option) -> TargetResult { - log::info!("GDB sent a kill request for pid {pid:?}"); + log::debug!("GDB sent a kill request for pid {pid:?}"); Ok(ShouldTerminate::No) } fn restart(&mut self) -> Result<(), Self::Error> { - log::info!("GDB sent a restart request"); + log::debug!("GDB sent a restart request"); Ok(()) } fn attach(&mut self, pid: Pid) -> TargetResult<(), Self> { - log::info!("GDB attached to a process with PID {pid}"); + log::debug!("GDB attached to a process with PID {pid}"); // stub implementation: just report the same code, but running under a // different pid. @@ -453,7 +453,7 @@ impl target::ext::extended_mode::ExtendedMode for Waver { .map(|raw| core::str::from_utf8(raw).map_err(drop)) .collect::, _>>()?; - log::info!("GDB tried to run a new process with filename {filename:?}, and args {args:?}"); + log::debug!("GDB tried to run a new process with filename {filename:?}, and args {args:?}"); self.reset(); @@ -462,7 +462,7 @@ impl target::ext::extended_mode::ExtendedMode for Waver { } fn query_if_attached(&mut self, pid: Pid) -> TargetResult { - log::info!("GDB queried if it was attached to a process with PID {pid}"); + log::debug!("GDB queried if it was attached to a process with PID {pid}"); Ok(AttachKind::Attach) } @@ -504,7 +504,7 @@ impl target::ext::extended_mode::ExtendedMode for Waver { impl target::ext::extended_mode::ConfigureAslr for Waver { fn cfg_aslr(&mut self, enabled: bool) -> TargetResult<(), Self> { - log::info!("GDB {} ASLR", if enabled { "enabled" } else { "disabled" }); + log::debug!("GDB {} ASLR", if enabled { "enabled" } else { "disabled" }); Ok(()) } } @@ -518,20 +518,20 @@ impl target::ext::extended_mode::ConfigureEnv for Waver { Some(raw) => Some(core::str::from_utf8(raw).map_err(drop)?), }; - log::info!("GDB tried to set a new env var: {key:?}={val:?}"); + log::debug!("GDB tried to set a new env var: {key:?}={val:?}"); Ok(()) } fn remove_env(&mut self, key: &[u8]) -> TargetResult<(), Self> { let key = core::str::from_utf8(key).map_err(drop)?; - log::info!("GDB tried to set remove a env var: {key:?}"); + log::debug!("GDB tried to set remove a env var: {key:?}"); Ok(()) } fn reset_env(&mut self) -> TargetResult<(), Self> { - log::info!("GDB tried to reset env vars"); + log::debug!("GDB tried to reset env vars"); Ok(()) } @@ -539,7 +539,7 @@ impl target::ext::extended_mode::ConfigureEnv for Waver { impl target::ext::extended_mode::ConfigureStartupShell for Waver { fn cfg_startup_with_shell(&mut self, enabled: bool) -> TargetResult<(), Self> { - log::info!( + log::debug!( "GDB {} startup with shell", if enabled { "enabled" } else { "disabled" } ); @@ -555,8 +555,8 @@ impl target::ext::extended_mode::ConfigureWorkingDir for Waver { }; match dir { - None => log::info!("GDB reset the working directory"), - Some(dir) => log::info!("GDB set the working directory to {dir:?}"), + None => log::debug!("GDB reset the working directory"), + Some(dir) => log::debug!("GDB set the working directory to {dir:?}"), } Ok(()) diff --git a/dang/src/runtime.rs b/dang/src/runtime.rs index bb7be72..ca55f03 100644 --- a/dang/src/runtime.rs +++ b/dang/src/runtime.rs @@ -64,7 +64,7 @@ impl DummyMem { impl Waver { pub fn reset(&mut self) { - log::info!("resetting cursor! actually doing nothing"); + log::debug!("resetting cursor! actually doing nothing"); } pub fn new( @@ -116,7 +116,7 @@ impl Waver { } } - log::info!( + log::debug!( "The first PC that should be executed is 0x{:08x} (entry = 0x{:08x}).", first_pc, elf_header.entry @@ -161,8 +161,8 @@ impl Waver { pub fn step(&mut self) -> Option { let next_pc = self.next_pc(); if let Some(pc) = next_pc { - log::info!("pc is {pc:?}"); - log::info!("mem is {:?}", self.mem.r32(pc)); + log::debug!("pc is {pc:?}"); + log::debug!("mem is {:?}", self.mem.r32(pc)); if self.breakpoints.contains(&pc) { return Some(Event::Break); @@ -170,7 +170,7 @@ impl Waver { None } else { let current_pc: u32 = self.get_current_pc(); - log::info!("Could not advance past current pc-- extracted value is {current_pc}"); + log::debug!("Could not advance past current pc-- extracted value is {current_pc}"); Some(Event::Halted) } } @@ -187,7 +187,7 @@ impl Waver { let mut cycles = 0; loop { if cycles % 1024 == 0 { - log::info!("executed {cycles} cycles"); + log::debug!("executed {cycles} cycles"); // poll for incoming data if poll_incoming_data() { break RunEvent::IncomingData; @@ -223,7 +223,7 @@ impl Waver { } } }; - log::info!("run_event is {run_event:?}"); + log::debug!("run_event is {run_event:?}"); run_event } } diff --git a/dang/src/waveloader.rs b/dang/src/waveloader.rs index 6e24f56..4c4a47e 100644 --- a/dang/src/waveloader.rs +++ b/dang/src/waveloader.rs @@ -3,7 +3,6 @@ use crate::runtime::{RequiredWaves, WaveCursor}; use anyhow::Result; use pyo3::prelude::*; -use pyo3::PyResult; use pywellen::{self, pywellen as doggy}; use wellen::{self, LoadOptions, Signal, SignalValue, TimeTableIdx}; @@ -159,7 +158,7 @@ impl Loaded { } let all_changes = merge_changes(all_changes_together); let first_pc_idx = pc.find_idx(first_pc).unwrap(); - log::info!("found first PC index: {first_pc_idx}"); + log::debug!("found first PC index: {first_pc_idx}"); let cursor = WaveCursor { time_idx: first_pc_idx, all_changes, @@ -182,39 +181,23 @@ fn initialize() { } pub enum MappingParsedEvents { - FileStatus { - found: bool, - }, - FunctionStatus { - found: bool, - }, + FileStatus, + FunctionStatus, /// If error message is null, it succeeded - WaveCreationStatus { - error_message: Option, - }, + WaveCreationStatus, /// If error essage is null, it succeeded - GetFnCall { - error_message: Option, - }, - /// If no missing signals, it succeeded - GDBSignalStatus { - missing_signals: Vec, - }, + GetFnCall, } -pub struct WellenPayload {} - pub struct ValidationResult { /// If None, it failed pub signals: Option>, - pub all_events: Vec, } impl ValidationResult { - pub fn from_events(all_events: Vec) -> Self { + pub fn from_events(_all_events: Vec) -> Self { Self { signals: None, - all_events, } } } @@ -225,10 +208,10 @@ pub fn validate_get_signals(script: &Path, fn_name: &str, wave_path: &Path) -> V let script_content = fs::read_to_string(script); if let Err(_) = script_content { - events.push(MappingParsedEvents::FileStatus { found: false }); + events.push(MappingParsedEvents::FileStatus); return ValidationResult::from_events(events); } - events.push(MappingParsedEvents::FileStatus { found: true }); + events.push(MappingParsedEvents::FileStatus); let script_content = script_content.unwrap(); pyo3::prepare_freethreaded_python(); @@ -239,9 +222,7 @@ pub fn validate_get_signals(script: &Path, fn_name: &str, wave_path: &Path) -> V let activators = match activators { Ok(module) => module, Err(e) => { - events.push(MappingParsedEvents::WaveCreationStatus { - error_message: Some(format!("Failed to load Python module: {}", e)), - }); + events.push(MappingParsedEvents::WaveCreationStatus); return Err(e); } }; @@ -250,15 +231,11 @@ pub fn validate_get_signals(script: &Path, fn_name: &str, wave_path: &Path) -> V pywellen::Waveform::new(wave_path.to_string_lossy().to_string(), true, true); let wave = match wave_result { Ok(w) => { - events.push(MappingParsedEvents::WaveCreationStatus { - error_message: None, - }); + events.push(MappingParsedEvents::WaveCreationStatus); w } Err(e) => { - events.push(MappingParsedEvents::WaveCreationStatus { - error_message: Some(e.to_string()), - }); + events.push(MappingParsedEvents::WaveCreationStatus); return Err(pyo3::PyErr::new::( e.to_string(), )); @@ -270,14 +247,12 @@ pub fn validate_get_signals(script: &Path, fn_name: &str, wave_path: &Path) -> V let function_result = activators.getattr(fn_name); let function = match function_result { Ok(f) => { - events.push(MappingParsedEvents::FunctionStatus { found: true }); + events.push(MappingParsedEvents::FunctionStatus); f } Err(e) => { - events.push(MappingParsedEvents::FunctionStatus { found: false }); - events.push(MappingParsedEvents::GetFnCall { - error_message: Some(format!("Function '{}' not found: {}", fn_name, e)), - }); + events.push(MappingParsedEvents::FunctionStatus); + events.push(MappingParsedEvents::GetFnCall); return Err(e); } }; @@ -285,15 +260,11 @@ pub fn validate_get_signals(script: &Path, fn_name: &str, wave_path: &Path) -> V let call_result = function.call1((wave_bound,)); let all_waves: HashMap = match call_result { Ok(result) => { - events.push(MappingParsedEvents::GetFnCall { - error_message: None, - }); + events.push(MappingParsedEvents::GetFnCall); result.extract()? } Err(e) => { - events.push(MappingParsedEvents::GetFnCall { - error_message: Some(format!("Function call failed: {}", e)), - }); + events.push(MappingParsedEvents::GetFnCall); return Err(e); } }; @@ -329,7 +300,6 @@ pub fn validate_get_signals(script: &Path, fn_name: &str, wave_path: &Path) -> V ValidationResult { signals, - all_events: events, } } diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index 7585238..0000000 --- a/docs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -book diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 299deb7..0000000 --- a/docs/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# DANG Project Overview - -DANG (**D**ebugger **A**nalysis **N**ext **G**eneration) is a debugging tool that brings GDB-style debugging capabilities to pre-silicon CPU development using waveform data from RTL simulations. - -## Project Components - -### DANG Core -The main application that coordinates waveform loading, signal mapping, and GDB server management. It acts as a bridge between RTL simulation waveforms and standard debugging tools. - -### JPDB Module -Additional debugging utilities and extensions that provide: -- Custom debugging commands specific to waveform analysis -- Performance analysis tools for CPU simulation debugging -- Signal analysis and data export functionality -- Debug session management utilities - -### Shucks Module -The GDB Remote Serial Protocol (RSP) implementation that enables standard debugger clients (GDB, LLDB) to communicate with DANG. It handles: -- Packet parsing and validation -- Command interpretation and routing -- Response formatting and transmission -- Protocol state management - -## How It Works - -1. **Waveform Loading**: DANG parses FST waveform files from RTL simulations -2. **Signal Mapping**: Python scripts define how to extract CPU state from simulation signals -3. **GDB Server**: Exposes a standard GDB server interface for familiar debugging workflows -4. **Debugger Connection**: Standard debuggers connect and debug the "execution" as if it were live - -## Quick Start - -```bash -# Start DANG with a waveform file and signal mapping -dang simulation.fst --mapping-path signals.py - -# Connect with your preferred debugger -lldb -connect connect://localhost:9001 -# or -gdb -ex "target remote localhost:9001" -``` - -This allows you to use familiar debugging commands like breakpoints, step execution, memory examination, and register inspection on pre-silicon CPU designs. \ No newline at end of file diff --git a/docs/installation.md b/docs/installation.md deleted file mode 100644 index ff6ad5e..0000000 --- a/docs/installation.md +++ /dev/null @@ -1,101 +0,0 @@ -# Installation - -## Building from Source - -DANG is written in Rust and uses a workspace-based architecture with three main components: DANG core, JPDB utilities, and Shucks GDB protocol implementation. - -### Prerequisites - -- **Rust toolchain**: 1.76.0 or later -- **Git**: For cloning the repository -- **Python 3.x**: For signal mapping scripts -- **PyWellen**: Python library for waveform access - -### Clone the Repository - -```bash -git clone https://github.com/1024bees/dang.git -cd dang -``` - -### Install Python Dependencies - -```bash -pip install pywellen -``` - -### Build the Project - -```bash -# Build in release mode for best performance -cargo build --release - -# Or build in debug mode for development -cargo build -``` - -### Install JPDB and Components - -```bash -# Install the main dang binary (includes jpdb utilities) -cargo install --path dang - -# Optionally install individual components -cargo install --path jpdb -cargo install --path shucks -``` - -This installs the binaries to your Cargo bin directory (typically `~/.cargo/bin/`). - -### Verify Installation - -Test your installation: - -```bash -# Check version -dang --version - -# Show help -dang --help -``` - -## System Requirements - -### Minimum Requirements - -- **OS**: macOS, Linux, or Windows -- **RAM**: 4GB (waveform files can be large) -- **Storage**: 1GB for source code and dependencies - -### Recommended - -- **RAM**: 16GB+ for large waveform files -- **CPU**: Multi-core processor (waveform parsing is CPU-intensive) -- **Storage**: SSD for faster file I/O - -## Troubleshooting - -### Common Issues - -**Rust toolchain too old**: -```bash -rustup update -``` - -**Missing Python dependencies**: -```bash -pip install pywellen numpy pandas -``` - -**Permission errors**: -```bash -# On Unix systems -sudo chown -R $USER ~/.cargo/ -``` - -**PyWellen installation issues**: -```bash -# Make sure you have the correct Python version -python3 --version -pip3 install pywellen -``` \ No newline at end of file diff --git a/docs/signal-mapping.md b/docs/signal-mapping.md deleted file mode 100644 index d174e0e..0000000 --- a/docs/signal-mapping.md +++ /dev/null @@ -1,218 +0,0 @@ -# Signal Mapping File Semantics - -Signal mapping files are Python scripts that define how DANG extracts CPU state from waveform signals. These scripts serve as the bridge between RTL simulation signals and the debugging interface. - -## Purpose - -The mapping file translates hierarchical signal names from your RTL design into the register and memory state that debuggers expect. This allows DANG to present a familiar debugging interface regardless of the underlying CPU design. - -## Required Functions - -Your mapping script must implement specific functions that DANG calls during execution: - -### Core Functions - -```python -def get_gdb_signals(wave: Waveform) -> dict: - """ - Extract the main signals needed for GDB debugging. - Must return a dictionary with 'pc' and register signals. - - Args: - wave: PyWellen Waveform object - - Returns: - Dictionary mapping signal names to Signal objects - """ -``` - -### Optional Functions - -```python -def get_misc_signals(wave: Waveform) -> List[Signal]: - """ - Extract additional signals for analysis. - - Args: - wave: PyWellen Waveform object - - Returns: - List of additional Signal objects - """ -``` - -## Signal Mapping Semantics - -### PyWellen Integration - -DANG uses the PyWellen library to access waveform data. Your mapping script works with PyWellen's Waveform and Signal objects: - -```python -from pywellen import Waveform, Signal -from typing import List, Dict - -def get_gdb_signals(wave: Waveform) -> Dict[str, Signal]: - # Extract program counter - pc = wave.get_signal_from_path( - "TOP.ibex_simple_system.u_top.u_ibex_top.u_ibex_core.wb_stage_i.pc_wb_o" - ) - - # Extract general-purpose registers - gprs = { - f"x{i}": wave.get_signal_from_path( - f"TOP.ibex_simple_system.u_top.u_ibex_top.gen_regfile_ff.register_file_i.rf_reg.[{i}]" - ).sliced(0, 31) # Extract bits 0-31 - for i in range(32) - } - - return {"pc": pc, **gprs} -``` - -### Signal Path Conventions - -Signal paths follow the hierarchical structure of your RTL design: - -- **Full paths**: Start from the top-level module (e.g., `TOP.module.submodule.signal`) -- **Array indexing**: Use bracket notation for arrays (e.g., `rf_reg.[0]`, `rf_reg.[15]`) -- **Bit slicing**: Use `.sliced(start, end)` to extract specific bits - -### Standard Signal Names - -The returned dictionary should use standard register naming conventions: - -```python -# RISC-V register naming -return { - "pc": pc_signal, # Program counter - "x0": zero_reg, # Zero register - "x1": ra_reg, # Return address - "x2": sp_reg, # Stack pointer - # ... up to x31 -} -``` - -## Example: RISC-V Ibex Core - -Here's a complete example for the Ibex RISC-V core: - -```python -from pywellen import Waveform, Signal -from typing import List, Dict - -def get_gdb_signals(wave: Waveform) -> Dict[str, Signal]: - """Extract signals for RISC-V Ibex core debugging.""" - - # Program counter from writeback stage - pc = wave.get_signal_from_path( - "TOP.ibex_simple_system.u_top.u_ibex_top.u_ibex_core.wb_stage_i.pc_wb_o" - ) - - # General-purpose registers (x0-x31) - gprs = {} - for i in range(32): - reg_signal = wave.get_signal_from_path( - f"TOP.ibex_simple_system.u_top.u_ibex_top.gen_regfile_ff.register_file_i.rf_reg.[{i}]" - ) - # Extract 32-bit register value (bits 0-31) - gprs[f"x{i}"] = reg_signal.sliced(0, 31) - - return {"pc": pc, **gprs} - -def get_misc_signals(wave: Waveform) -> List[Signal]: - """Extract additional signals for analysis.""" - return [ - wave.get_signal_from_path( - "TOP.ibex_simple_system.u_top.u_ibex_top.u_ibex_core.wb_stage_i.pc_wb_o" - ) - ] -``` - -## Signal Naming Guidelines - -### Hierarchy Navigation - -- Start from the testbench top module (often `TOP`) -- Follow the instantiation hierarchy downward -- Use the exact module instance names from your RTL - -### Common Signal Locations - -Different CPU designs store key signals in different locations: - -```python -# Examples for different stages -pc_if = "cpu.if_stage.pc" # Instruction fetch -pc_id = "cpu.id_stage.pc" # Instruction decode -pc_ex = "cpu.ex_stage.pc" # Execute -pc_wb = "cpu.wb_stage.pc" # Writeback (most stable) - -# Register file locations -regfile_ff = "cpu.regfile_ff.regs" # Flip-flop based -regfile_latch = "cpu.regfile_latch.regs" # Latch based -``` - -### Signal Stability - -Choose signals from stable pipeline stages: - -- **Writeback stage**: Most stable, reflects committed state -- **Execute stage**: May change due to pipeline flushes -- **Fetch/Decode**: Least stable, speculative execution - -## Bit Manipulation - -### Extracting Bit Ranges - -```python -# Extract specific bit ranges -signal_32bit = wave_signal.sliced(0, 31) # Bits 0-31 (32 bits) -signal_16bit = wave_signal.sliced(0, 15) # Bits 0-15 (16 bits) -signal_8bit = wave_signal.sliced(0, 7) # Bits 0-7 (8 bits) - -# Extract single bit -enable_bit = control_signal.sliced(0, 0) # Bit 0 only -``` - -### Handling Different Data Widths - -```python -# Handle different register widths -if cpu_width == 64: - reg_signal = wave_signal.sliced(0, 63) # 64-bit -elif cpu_width == 32: - reg_signal = wave_signal.sliced(0, 31) # 32-bit -else: - reg_signal = wave_signal.sliced(0, 15) # 16-bit -``` - -## Debugging Mapping Issues - -### Common Problems - -1. **Signal not found**: Check signal path spelling and hierarchy -2. **Wrong bit width**: Verify bit slicing parameters -3. **Timing issues**: Ensure signals are from stable pipeline stages -4. **Array indexing**: Use correct bracket notation for arrays - -### Testing Your Mapping - -```python -# Add debug prints to your mapping function -def get_gdb_signals(wave: Waveform) -> Dict[str, Signal]: - try: - pc = wave.get_signal_from_path("TOP.cpu.pc") - print(f"Found PC signal: {pc}") - except Exception as e: - print(f"PC signal not found: {e}") - - return {"pc": pc, ...} -``` - -## Best Practices - -1. **Use writeback stage signals** for stability -2. **Add error handling** for missing signals -3. **Document your signal paths** with comments -4. **Test with small waveforms** first -5. **Verify register values** match expected behavior -6. **Use meaningful variable names** in your mapping code \ No newline at end of file diff --git a/docs/usage.md b/docs/usage.md deleted file mode 100644 index 02b219e..0000000 --- a/docs/usage.md +++ /dev/null @@ -1,173 +0,0 @@ -# JPDB and DANG Usage Guide - -This guide covers the fundamental usage patterns and command-line options for DANG with JPDB utilities. - -## Command Line Interface - -### Basic Syntax - -```bash -dang [OPTIONS] -``` - -### Required Arguments - -- **``**: Path to the FST waveform file from RTL simulation - -### Common Options - -- **`--mapping-path `**: Path to Python signal mapping script -- **`--port `**: GDB server port (default: 9001) -- **`--log-level `**: Logging verbosity (error, warn, info, debug, trace) -- **`--help`**: Show help information -- **`--version`**: Show version information - -### Examples - -```bash -# Basic usage with JPDB utilities -dang simulation.fst --mapping-path signals.py - -# Custom port -dang simulation.fst --mapping-path signals.py --port 8080 - -# Verbose logging for debugging -dang simulation.fst --mapping-path signals.py --log-level debug -``` - -## Debugging Workflow - -### 1. Start DANG Server - -```bash -dang waveform.fst --mapping-path mapping.py -``` - -Output should show: -``` -[INFO] Loading waveform: waveform.fst -[INFO] Parsing signal mapping: mapping.py -[INFO] GDB server listening on port 9001 -[INFO] Waiting for debugger connection... -``` - -### 2. Connect Debugger - -In a separate terminal: - -```bash -# Using LLDB -lldb -connect connect://localhost:9001 - -# Using GDB -gdb -ex "target remote localhost:9001" -``` - -### 3. Use Standard GDB Commands - -```gdb -# Set breakpoints -(gdb) break *0x1000 -(gdb) break main - -# Control execution -(gdb) continue -(gdb) stepi -(gdb) nexti - -# Examine state -(gdb) info registers -(gdb) x/10i $pc -(gdb) x/16x 0x2000 -(gdb) backtrace -``` - -## JPDB Utilities - -### Performance Analysis - -JPDB provides additional debugging utilities beyond the core DANG functionality: - -- **Signal trace commands**: Analyze signal behavior over time -- **Performance profiling**: Monitor query performance and cache hit rates -- **Memory usage tracking**: Track memory usage during debugging sessions - -### Custom Commands - -Extended GDB commands specific to waveform debugging: - -```gdb -# Time navigation (JPDB-specific) -(jpdb) time-step 1000 # Jump to specific simulation time -(jpdb) time-range # Show current time range -(jpdb) signal-trace pc # Trace PC signal over time -``` - -## Configuration - -### Environment Variables - -- **`RUST_LOG`**: Override log level (e.g., `RUST_LOG=debug`) -- **`DANG_PORT`**: Default server port -- **`DANG_MAPPING_PATH`**: Default signal mapping script - -### Log Levels - -- **`error`**: Only errors and critical issues -- **`warn`**: Warnings and errors -- **`info`**: General information (default) -- **`debug`**: Detailed debugging information -- **`trace`**: Very verbose tracing - -Example with environment variable: -```bash -RUST_LOG=debug dang simulation.fst --mapping-path signals.py -``` - -## Performance Tips - -### Large Waveform Files - -- Use **release builds** for better performance -- Increase system **RAM** for large files (16GB+ recommended) -- Use **SSD storage** for faster file I/O -- Consider **signal caching** in JPDB for frequently accessed signals - -### Signal Mapping Optimization - -- **Cache expensive calculations** in mapping scripts -- **Minimize signal lookups** per time step -- **Use efficient data structures** for signal access -- **Leverage JPDB's caching mechanisms** - -### JPDB-Specific Optimizations - -- **Batch operations**: Group multiple signal queries together -- **Query optimization**: Use JPDB's performance monitoring to identify bottlenecks -- **Cache management**: Configure cache sizes based on available memory - -## Common Debugging Patterns - -### Debugging Boot Sequence - -```gdb -(gdb) break *0x0 # Reset vector -(gdb) continue -(gdb) x/10i $pc # Show boot code -``` - -### Waveform Time Navigation - -```bash -# Use JPDB time navigation features -(jpdb) time-step 5000 # Jump to simulation time 5000 -(jpdb) signal-value pc # Get PC value at current time -``` - -### Performance Analysis - -```bash -# Monitor JPDB performance -(jpdb) cache-stats # Show cache hit/miss statistics -(jpdb) query-time # Show recent query performance -``` \ No newline at end of file diff --git a/jpdb/Cargo.toml b/jpdb/Cargo.toml index 9321fce..be3c4fa 100644 --- a/jpdb/Cargo.toml +++ b/jpdb/Cargo.toml @@ -15,3 +15,7 @@ shucks = { path = "../shucks" } dang = { path = "../dang" } log = { workspace = true } env_logger = { workspace = true } +serde_json = "1.0" +libsurfer = { git = "https://gitlab.com/surfer-project/surfer" } +argh = { workspace = true } +num = { version = "0.4", features = ["serde"] } diff --git a/jpdb/src/cli.rs b/jpdb/src/cli.rs new file mode 100644 index 0000000..5231de5 --- /dev/null +++ b/jpdb/src/cli.rs @@ -0,0 +1,20 @@ +//! Command line interface for jpdb + +use argh::FromArgs; +use std::path::PathBuf; + +#[derive(FromArgs, Debug, Clone)] +/// CLI to jpdb - JTAG Debugger +pub struct JpdbArgs { + #[argh(option)] + /// path to the vcd, fst or ghw file that will be stepped through + pub wave_path: PathBuf, + + #[argh(option)] + /// path to a signal mapping file + pub mapping_path: PathBuf, + + #[argh(option)] + /// path to the ELF binary + pub elf: PathBuf, +} diff --git a/jpdb/src/main.rs b/jpdb/src/main.rs index 69b31e8..99ead9d 100644 --- a/jpdb/src/main.rs +++ b/jpdb/src/main.rs @@ -2,13 +2,22 @@ use std::{ collections::VecDeque, io, net::TcpListener, + path::Path, sync::{Arc, Mutex}, thread, time::Duration, }; +mod cli; +mod model; mod user_commands; +mod view; +mod wcp_client; + +use model::DebuggerModel; use user_commands::CommandRegistry; +use view::ViewState; +use wcp_client::WcpClient; use crossterm::{ event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode}, @@ -20,13 +29,10 @@ use ratatui::{ backend::{Backend, CrosstermBackend}, layout::{Constraint, Direction, Layout, Rect}, style::{Color, Modifier, Style}, - widgets::{Block, Borders, List, ListItem}, + widgets::{Block, Borders, List, ListItem, Scrollbar}, Frame, Terminal, }; -use shucks::{ - commands::{GdbCommand, Resume}, - Client, Packet, Var, -}; +use shucks::{Client, Var}; // Custom logger that captures messages for ratatui display #[derive(Debug, Clone)] @@ -78,14 +84,20 @@ impl log::Log for AppLogger { fn flush(&self) {} } -pub struct AddsigState { +pub struct AddSigState { active: bool, input: String, matches: Vec<(Var, String)>, selected_index: usize, } -impl AddsigState { +impl Default for AddSigState { + fn default() -> Self { + Self::new() + } +} + +impl AddSigState { pub fn new() -> Self { Self { active: false, @@ -124,7 +136,9 @@ impl AddsigState { pub fn set_matches(&mut self, matches: Vec<(Var, String)>) { self.matches = matches.into_iter().take(10).collect(); // Take top 10 - self.selected_index = self.selected_index.min(self.matches.len().saturating_sub(1)); + self.selected_index = self + .selected_index + .min(self.matches.len().saturating_sub(1)); } pub fn get_matches(&self) -> &[(Var, String)] { @@ -156,17 +170,71 @@ impl AddsigState { } } +pub struct HelpModalState { + active: bool, + content: Vec, + scroll_offset: usize, +} + +impl Default for HelpModalState { + fn default() -> Self { + Self::new() + } +} + +impl HelpModalState { + pub fn new() -> Self { + Self { + active: false, + content: Vec::new(), + scroll_offset: 0, + } + } + + pub fn activate(&mut self, content: Vec) { + self.active = true; + self.content = content; + self.scroll_offset = 0; + } + + pub fn deactivate(&mut self) { + self.active = false; + self.content.clear(); + self.scroll_offset = 0; + } + + pub fn is_active(&self) -> bool { + self.active + } + + pub fn scroll_up(&mut self, lines: usize) { + self.scroll_offset = self.scroll_offset.saturating_add(lines); + } + + pub fn scroll_down(&mut self, lines: usize) { + self.scroll_offset = self.scroll_offset.saturating_sub(lines); + } + + pub fn get_content(&self) -> &[String] { + &self.content + } + + pub fn get_scroll_offset(&self) -> usize { + self.scroll_offset + } +} + pub struct App { pub should_quit: bool, - input_buffer: String, pub command_history: Vec, - pub instruction_output: Vec, - pub shucks_client: Client, + model: DebuggerModel, + view_state: ViewState, _dang_thread_handle: thread::JoinHandle<()>, scroll_offset: usize, // Debug panel state show_debug_panel: bool, + debug_scroll_offset: usize, // Add scroll offset for debug panel // Split view state show_split_view: bool, log_buffer: Arc>>, @@ -176,11 +244,18 @@ pub struct App { user_command_history: Vec, history_index: Option, // Addsig floating window state - addsig_state: AddsigState, + addsig_state: AddSigState, + // Help modal state + help_modal_state: HelpModalState, + // WCP client for Surfer integration + wcp_client: Option, + surfer_process: Option, + // CLI arguments for reference + cli_args: cli::JpdbArgs, } -impl Default for App { - fn default() -> App { +impl App { + fn new(cli_args: cli::JpdbArgs) -> App { // Initialize custom logging system let (logger, log_buffer) = AppLogger::new(); log::set_boxed_logger(Box::new(logger)) @@ -194,18 +269,13 @@ impl Default for App { .expect("Failed to get local addr") .port(); + // Clone paths for thread + let wave_path = cli_args.wave_path.clone(); + let mapping_path = cli_args.mapping_path.clone(); + let elf_path = cli_args.elf.clone(); + // Start dang GDB stub in a separate thread let dang_handle = thread::spawn(move || { - let workspace_root = std::env::current_dir() - .expect("Failed to get current dir") - .parent() - .expect("Failed to get parent dir") - .to_path_buf(); - - let wave_path = workspace_root.join("test_data/ibex/sim.fst"); - let mapping_path = workspace_root.join("test_data/ibex/signal_get.py"); - let elf_path = workspace_root.join("test_data/ibex/hello_test.elf"); - dang::start_with_args_and_listener_silent(wave_path, mapping_path, elf_path, listener) .expect("Failed to start dang"); }); @@ -215,53 +285,98 @@ impl Default for App { // Create shucks client connected to dang let mut shucks_client = Client::new_with_port(port); - let workspace_root = std::env::current_dir() - .expect("Failed to get current dir") - .parent() - .expect("Failed to get parent dir") - .to_path_buf(); - let wave_path = workspace_root.join("test_data/ibex/sim.fst"); - shucks_client - .load_waveform(wave_path) - .expect("Failed to load waveform"); shucks_client.initialize_gdb_session().expect(""); let _ = shucks_client.load_elf_info(); - + shucks_client + .load_waveform(cli_args.wave_path.clone()) + .expect("Failed to load waveform"); thread::sleep(Duration::from_millis(300)); - let mut app = App { + let mut model = DebuggerModel::new(shucks_client); + let mut view_state = ViewState::default(); + + // Initialize views + if let Ok(execution) = model.fetch_execution_snapshot() { + view_state.execution_lines = execution.summary_lines; + view_state.instruction_lines = execution.instruction_lines; + } else { + view_state.execution_lines = vec!["Failed to load execution info".to_string()]; + view_state.instruction_lines = vec!["Failed to load execution info".to_string()]; + } + + if let Ok(source) = model.fetch_source_snapshot() { + view_state.source_lines = source.lines; + } else { + view_state.source_lines = vec!["Failed to load source info".to_string()]; + } + + if let Ok(signals) = model.fetch_signal_snapshot() { + view_state.signal_lines = signals.lines; + } else { + view_state.signal_lines = vec!["Failed to load signal info".to_string()]; + } + + App { should_quit: false, input_buffer: String::new(), command_history: Vec::new(), - instruction_output: Vec::new(), - shucks_client, + model, + view_state, _dang_thread_handle: dang_handle, scroll_offset: 0, show_debug_panel: false, - show_split_view: false, + debug_scroll_offset: 0, // Initialize debug scroll offset + show_split_view: true, log_buffer, last_command: None, user_command_history: Vec::new(), history_index: None, - addsig_state: AddsigState::new(), - }; - - // Show initial instructions when first connecting - app.add_execution_info(); - - app + addsig_state: AddSigState::new(), + help_modal_state: HelpModalState::new(), + wcp_client: None, + surfer_process: None, + cli_args, + } } -} -impl App { fn run(&mut self, terminal: &mut Terminal) -> io::Result<()> { loop { terminal.draw(|f| self.ui(f))?; if let Event::Key(key) = event::read()? { - // Check if we're in addsig mode first - if self.addsig_state.is_active() { + // Check if we're in help modal mode first + if self.help_modal_state.is_active() { + match key.code { + KeyCode::Up => { + self.help_modal_state.scroll_up(1); + } + KeyCode::Down => { + self.help_modal_state.scroll_down(1); + } + KeyCode::PageUp => { + self.help_modal_state.scroll_up(5); + } + KeyCode::PageDown => { + self.help_modal_state.scroll_down(5); + } + KeyCode::Home => { + // Scroll to top + let content_len = self.help_modal_state.get_content().len(); + self.help_modal_state.scroll_up(content_len); + } + KeyCode::End => { + // Scroll to bottom + self.help_modal_state.scroll_down(usize::MAX); + } + KeyCode::Esc | KeyCode::Enter | KeyCode::Char('q') => { + // Close help modal + self.help_modal_state.deactivate(); + } + _ => {} // Ignore other keys in help modal mode + } + } else if self.addsig_state.is_active() { + // Check if we're in addsig mode match key.code { KeyCode::Char(c) => { // Add character to search input @@ -269,11 +384,11 @@ impl App { new_input.push(c); self.addsig_state.update_search(new_input); - // Update fuzzy matches - if let Some(ref mut wave_tracker) = self.shucks_client.wave_tracker { - let matches = wave_tracker.fuzzy_match_var(self.addsig_state.get_input()); - self.addsig_state.set_matches(matches); - } + // Update fuzzy matches via model + let matches = self + .model + .fuzzy_match_signals(self.addsig_state.get_input()); + self.addsig_state.set_matches(matches); } KeyCode::Backspace => { // Remove character from search input @@ -281,11 +396,11 @@ impl App { new_input.pop(); self.addsig_state.update_search(new_input); - // Update fuzzy matches - if let Some(ref mut wave_tracker) = self.shucks_client.wave_tracker { - let matches = wave_tracker.fuzzy_match_var(self.addsig_state.get_input()); - self.addsig_state.set_matches(matches); - } + // Update fuzzy matches via model + let matches = self + .model + .fuzzy_match_signals(self.addsig_state.get_input()); + self.addsig_state.set_matches(matches); } KeyCode::Up => { self.addsig_state.select_prev(); @@ -296,9 +411,13 @@ impl App { KeyCode::Enter => { // Select the signal and exit addsig mode if let Some((var, _)) = self.addsig_state.get_selected().cloned() { - if let Some(ref mut wave_tracker) = self.shucks_client.wave_tracker { - wave_tracker.select_signal(var); + self.model.select_signal(var); + if let Some(ref mut wcp) = self.wcp_client { + if let Some(path) = self.model.most_recent_var_path() { + let _ = wcp.add_signal(path.as_str()); + } } + self.refresh_signal_view(); } self.addsig_state.deactivate(); } @@ -311,76 +430,98 @@ impl App { } else { // Normal key handling when not in addsig mode match key.code { - KeyCode::Char('d') if key.modifiers.contains(event::KeyModifiers::CONTROL) => { - // Ctrl+D: Quit the application - self.should_quit = true; - } - KeyCode::Char('l') if key.modifiers.contains(event::KeyModifiers::CONTROL) => { - // Ctrl+L: Clear screen - self.command_history.clear(); - self.scroll_offset = 0; - } - - - - - KeyCode::Char(c) => { - self.input_buffer.push(c); - // Reset history navigation when user types - self.history_index = None; - } - KeyCode::Enter => { - self.process_command(); - self.input_buffer.clear(); - // Auto-scroll to bottom when new command is entered - self.scroll_offset = 0; - } - KeyCode::Backspace => { - self.input_buffer.pop(); - // Reset history navigation when user modifies input - self.history_index = None; - } - KeyCode::Up => { - // Navigate to previous command in history - if !self.user_command_history.is_empty() { - let new_index = match self.history_index { - None => self.user_command_history.len() - 1, - Some(index) => { - if index > 0 { - index - 1 - } else { - // Wrap to newest (end of history) - self.user_command_history.len() - 1 + KeyCode::Char('d') + if key.modifiers.contains(event::KeyModifiers::CONTROL) => + { + // Ctrl+D: Quit the application + self.should_quit = true; + } + KeyCode::Char('l') + if key.modifiers.contains(event::KeyModifiers::CONTROL) => + { + // Ctrl+L: Clear screen + self.command_history.clear(); + self.scroll_offset = 0; + } + + // Debug panel scrolling (only when debug panel is visible) + KeyCode::PageUp if self.show_debug_panel => { + // Scroll up in debug panel + self.debug_scroll_offset = self.debug_scroll_offset.saturating_add(5); + } + KeyCode::PageDown if self.show_debug_panel => { + // Scroll down in debug panel + self.debug_scroll_offset = self.debug_scroll_offset.saturating_sub(5); + } + KeyCode::Home if self.show_debug_panel => { + // Go to top of debug panel + if let Ok(buffer) = self.log_buffer.lock() { + self.debug_scroll_offset = buffer.len().saturating_sub(1); + } + } + KeyCode::End if self.show_debug_panel => { + // Go to bottom of debug panel + self.debug_scroll_offset = 0; + } + + KeyCode::Char(c) => { + self.input_buffer.push(c); + // Reset history navigation when user types + self.history_index = None; + } + KeyCode::Enter => { + self.process_command(); + self.input_buffer.clear(); + // Auto-scroll to bottom when new command is entered + self.scroll_offset = 0; + } + KeyCode::Backspace => { + self.input_buffer.pop(); + // Reset history navigation when user modifies input + self.history_index = None; + } + KeyCode::Up => { + // Navigate to previous command in history + if !self.user_command_history.is_empty() { + let new_index = match self.history_index { + None => self.user_command_history.len() - 1, + Some(index) => { + if index > 0 { + index - 1 + } else { + // Wrap to newest (end of history) + self.user_command_history.len() - 1 + } } - } - }; - self.history_index = Some(new_index); - self.input_buffer = self.user_command_history[new_index].clone(); + }; + self.history_index = Some(new_index); + self.input_buffer = self.user_command_history[new_index].clone(); + } } - } - KeyCode::Down => { - // Navigate to next (more recent) command in history - if !self.user_command_history.is_empty() { - match self.history_index { - None => { - // Do nothing if not currently navigating history - } - Some(index) => { - if index < self.user_command_history.len() - 1 { - let new_index = index + 1; - self.history_index = Some(new_index); - self.input_buffer = - self.user_command_history[new_index].clone(); - } else { - // Wrap to oldest (beginning of history) - self.history_index = Some(0); - self.input_buffer = self.user_command_history[0].clone(); + KeyCode::Down => { + // Navigate to next (more recent) command in history + if !self.user_command_history.is_empty() { + match self.history_index { + None => { + // Do nothing if not currently navigating history + } + Some(index) => { + if index < self.user_command_history.len() - 1 { + let new_index = index + 1; + self.history_index = Some(new_index); + self.input_buffer = + self.user_command_history[new_index].clone(); + } else { + // Wrap to oldest (beginning of history) + self.history_index = Some(0); + self.input_buffer = + self.user_command_history[0].clone(); + } } } } } - } - _ => {} + _ => {} } } } @@ -393,12 +534,16 @@ impl App { } pub fn step_next(&mut self) { - // Send step command to shucks/dang instead of using hardcoded logic - if let Err(e) = self - .shucks_client - .send_command_parsed(Packet::Command(GdbCommand::Resume(Resume::Step))) - { + if let Err(e) = self.model.step() { self.command_history.push(format!("Error stepping: {e}")); + return; + } + + self.refresh_all_views(); + + // Sync waveform position if connected to Surfer + if let Err(e) = self.sync_waveform_position() { + log::warn!("Failed to sync waveform position: {e}"); } } @@ -448,52 +593,125 @@ impl App { } } - pub fn add_execution_info(&mut self) { - log::debug!("Adding execution info"); - self.instruction_output.clear(); // Clear previous instruction output - self.instruction_output - .push("Process 1 stopped".to_string()); - self.instruction_output - .push("* thread #1, stop reason = instruction step over".to_string()); - - // Get current PC from shucks - log::debug!("About to get current PC"); - match self.shucks_client.get_current_pc() { - Ok(current_pc) => { - log::debug!("Successfully got current PC: 0x{current_pc}"); - let frame_info = format!(" frame #0: 0x{current_pc}"); - self.instruction_output.push(frame_info); - - // Try to get current instruction info from shucks - - if let Ok(insts) = self.shucks_client.get_current_and_next_inst() { - // Only show arrow for the first instruction (current PC) - for (i, ainst) in insts.iter().enumerate() { - let inst_pc = ainst.pc().as_u32(); - if i == 0 { - // First instruction gets the arrow - self.instruction_output - .push(format!("-> 0x{inst_pc:x}: {ainst}")); - } else { - // Subsequent instructions without arrow - self.instruction_output - .push(format!(" 0x{inst_pc:x}: {ainst}")); - } - } - } else { - self.instruction_output - .push(format!("-> 0x{current_pc}: ")); - } - } - Err(e) => { - log::error!("Failed to get current PC: {e}"); - self.instruction_output - .push(format!("Error getting PC: {e}")); + fn refresh_all_views(&mut self) { + if let Ok(execution) = self.model.fetch_execution_snapshot() { + self.view_state.execution_lines = execution.summary_lines; + self.view_state.instruction_lines = execution.instruction_lines; + } else { + self.view_state.execution_lines = vec!["Failed to load execution info".to_string()]; + self.view_state.instruction_lines = vec!["Failed to load execution info".to_string()]; + } + + if let Ok(source) = self.model.fetch_source_snapshot() { + self.view_state.source_lines = source.lines; + } else { + self.view_state.source_lines = vec!["Failed to load source info".to_string()]; + } + + if let Ok(signals) = self.model.fetch_signal_snapshot() { + self.view_state.signal_lines = signals.lines; + } else { + self.view_state.signal_lines = vec!["Failed to load signal info".to_string()]; + } + } + + fn refresh_signal_view(&mut self) { + match self.model.fetch_signal_snapshot() { + Ok(snapshot) => self.view_state.signal_lines = snapshot.lines, + Err(err) => { + self.view_state.signal_lines = vec![format!("Error getting signal info: {err}")]; } } + } + + pub fn set_breakpoint(&mut self, address: u32) -> Result<(), String> { + self.model.set_breakpoint(address) + } + + pub fn set_breakpoint_at_line(&mut self, file: &str, line: u64) -> Result, String> { + self.model.set_breakpoint_at_line(file, line) + } + + pub fn continue_execution(&mut self) -> Result<(), String> { + self.model.continue_execution()?; + + // Sync waveform position if connected to Surfer + if let Err(e) = self.sync_waveform_position() { + log::warn!("Failed to sync waveform position: {e}"); + } + + Ok(()) + } + + pub fn invalidate_time_idx_cache(&mut self) { + self.model.invalidate_time_index(); + } + + /// Launch Surfer waveform viewer and connect to it via WCP + pub fn launch_surfer(&mut self, wave_path: &Path) -> Result<(), Box> { + use std::process::{Command, Stdio}; - self.instruction_output - .push("Target 0: (No executable module.) stopped.".to_string()); + //TODO: get a random port, i am lazy + let wcp_port = 54321; + let mut tmp_script = std::env::temp_dir(); + tmp_script.push("surfer_commands.sucl"); + + std::fs::write(tmp_script.as_path(), "wcp_server_start")?; + + let child = Command::new("surfer") + .arg(wave_path.to_str().ok_or("Invalid wave path")?) + .arg("--script") + .arg( + tmp_script + .as_os_str() + .to_str() + .ok_or("Invalid script path")?, + ) + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .spawn()?; + log::info!("Launched Surfer with PID {}", child.id()); + + self.surfer_process = Some(child); + + // Give Surfer time to start + std::thread::sleep(std::time::Duration::from_millis(1000)); + + // Connect to Surfer via WCP + self.connect_to_surfer(&format!("127.0.0.1:{wcp_port}"))?; + + Ok(()) + } + + /// Connect to a running Surfer instance via WCP + pub fn connect_to_surfer(&mut self, addr: &str) -> Result<(), Box> { + let client = WcpClient::connect(addr)?; + self.wcp_client = Some(client); + log::info!("Connected to Surfer via WCP at {addr}"); + + // Sync current waveform state + self.sync_waveform_position()?; + + Ok(()) + } + + /// Sync the waveform viewer to the current simulation time + fn sync_waveform_position(&mut self) -> Result<(), Box> { + if let Some(ref mut wcp) = self.wcp_client { + if let Ok(time_idx) = self.model.get_time_idx() { + let time = self + .model + .client + .wave_tracker + .as_ref() + .unwrap() + .get_current_time(time_idx as shucks::TimeTableIdx); + + wcp.goto_time(time)?; + } + } + Ok(()) } fn ui(&mut self, f: &mut Frame) { @@ -522,6 +740,11 @@ impl App { if self.addsig_state.is_active() { self.render_addsig_popup(f, f.area()); } + + // Render help modal on top if active + if self.help_modal_state.is_active() { + self.render_help_modal(f, f.area()); + } } fn render_combined_output(&mut self, f: &mut Frame, area: ratatui::layout::Rect) { @@ -540,7 +763,8 @@ impl App { fn render_instruction_panel_combined(&self, f: &mut Frame, area: ratatui::layout::Rect) { let items: Vec = self - .instruction_output + .view_state + .execution_lines .iter() .map(|line| { let style = if line.starts_with("->") { @@ -637,20 +861,30 @@ impl App { } fn render_debug_panel(&self, f: &mut Frame, area: ratatui::layout::Rect) { - // Get log messages from buffer - clone them to avoid lifetime issues - let log_messages = if let Ok(buffer) = self.log_buffer.lock() { - buffer - .iter() - .rev() - .take(area.height.saturating_sub(2) as usize) - .rev() - .cloned() - .collect::>() + // Get all log messages from buffer + let all_log_messages = if let Ok(buffer) = self.log_buffer.lock() { + buffer.iter().cloned().collect::>() } else { Vec::new() }; - let items: Vec = log_messages + let available_height = area.height.saturating_sub(2) as usize; // Account for borders + let total_messages = all_log_messages.len(); + + // Calculate which messages to show based on scroll offset + let visible_messages = if total_messages > available_height { + let max_scroll = total_messages.saturating_sub(available_height); + let actual_scroll = self.debug_scroll_offset.min(max_scroll); + let start_idx = total_messages.saturating_sub(available_height + actual_scroll); + let end_idx = start_idx + available_height; + + all_log_messages[start_idx..end_idx.min(total_messages)].to_vec() + } else { + // If all messages fit, show them all + all_log_messages + }; + + let items: Vec = visible_messages .iter() .map(|msg| { let style = match msg.level { @@ -668,10 +902,35 @@ impl App { let debug_panel = List::new(items).block( Block::default() .borders(Borders::ALL) - .title("Debug (d to toggle)"), + .title("Debug (d to toggle, PgUp/PgDn to scroll, Home/End)"), ); f.render_widget(debug_panel, area); + + // Add scrollbar if there are more messages than can fit + if total_messages > available_height { + let scrollbar_area = Rect { + x: area.x + area.width - 1, + y: area.y + 1, + width: 1, + height: area.height - 2, + }; + + let max_scroll = total_messages.saturating_sub(available_height); + let scrollbar = Scrollbar::default() + .orientation(ratatui::widgets::ScrollbarOrientation::VerticalRight) + .begin_symbol(Some("▲")) + .end_symbol(Some("▼")); + + let mut scrollbar_state = ratatui::widgets::ScrollbarState::new(total_messages) + .position( + total_messages.saturating_sub( + available_height + self.debug_scroll_offset.min(max_scroll), + ), + ); + + f.render_stateful_widget(scrollbar, scrollbar_area, &mut scrollbar_state); + } } fn render_split_view(&mut self, f: &mut Frame, area: ratatui::layout::Rect) { @@ -681,40 +940,29 @@ impl App { .constraints([Constraint::Percentage(70), Constraint::Percentage(30)].as_ref()) .split(area); - // Split the top area horizontally: instructions (left) and source code (right) + // Split the top area horizontally: instructions (left), source code (middle), signals (right) let panel_chunks = Layout::default() .direction(Direction::Horizontal) - .constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref()) + .constraints( + [ + Constraint::Percentage(30), + Constraint::Percentage(30), + Constraint::Percentage(40), + ] + .as_ref(), + ) .split(main_chunks[0]); self.render_instruction_pane(f, panel_chunks[0]); self.render_source_pane(f, panel_chunks[1]); + self.render_signal_panel(f, panel_chunks[2]); self.render_command_bar(f, main_chunks[1]); } fn render_instruction_pane(&mut self, f: &mut Frame, area: ratatui::layout::Rect) { - // Get current and next instructions - let mut instruction_lines = Vec::new(); - - match self.shucks_client.get_current_and_next_inst() { - Ok(instructions) => { - for (i, inst) in instructions.iter().enumerate() { - let pc = inst.pc().as_u32(); - if i == 0 { - // Current instruction with arrow - instruction_lines.push(format!("-> 0x{pc:x}: {inst}")); - } else { - // Next instructions - instruction_lines.push(format!(" 0x{pc:x}: {inst}")); - } - } - } - Err(e) => { - instruction_lines.push(format!("Error: {e}")); - } - } - - let items: Vec = instruction_lines + let items: Vec = self + .view_state + .instruction_lines .iter() .map(|line| { let style = if line.starts_with("->") { @@ -740,60 +988,9 @@ impl App { } fn render_source_pane(&mut self, f: &mut Frame, area: ratatui::layout::Rect) { - let mut source_lines = Vec::new(); - - // Get current source line - match self.shucks_client.get_current_source_line() { - Ok(Some(current_line)) => { - source_lines.push(format!( - "{}:{}", - current_line - .path - .file_name() - .and_then(|n| n.to_str()) - .unwrap_or("unknown"), - current_line.line - )); - source_lines.push("".to_string()); - - // Show current line with arrow - if let Some(ref text) = current_line.text { - source_lines.push(format!("-> {}: {}", current_line.line, text)); - } else { - source_lines.push(format!("-> {}: ", current_line.line)); - } - - // Get next 3 consecutive source lines from the same file - match self - .shucks_client - .get_consecutive_source_lines_after_current(3) - { - Ok(next_lines) => { - for line in next_lines { - if let Some(ref text) = line.text { - source_lines.push(format!(" {}: {}", line.line, text)); - } else { - source_lines - .push(format!(" {}: ", line.line)); - } - } - } - Err(e) => { - source_lines.push(format!("Error getting next lines: {e}")); - } - } - } - Ok(None) => { - source_lines.push("Source Code:".to_string()); - source_lines.push("No debug information available".to_string()); - } - Err(e) => { - source_lines.push("Source Code:".to_string()); - source_lines.push(format!("Error: {e}")); - } - } - - let items: Vec = source_lines + let items: Vec = self + .view_state + .source_lines .iter() .map(|line| { let style = if line.starts_with("->") { @@ -818,6 +1015,38 @@ impl App { f.render_widget(source_panel, area); } + fn render_signal_panel(&mut self, f: &mut Frame, area: ratatui::layout::Rect) { + let items: Vec = self + .view_state + .signal_lines + .iter() + .enumerate() + .map(|(i, line)| { + let style = if i == 0 && line.ends_with(" ps") { + // Time header - make it bold and colored + Style::default() + .fg(Color::Cyan) + .add_modifier(Modifier::BOLD) + } else if line.starts_with("Error:") || line.starts_with("Error ") { + Style::default().fg(Color::Red) + } else if line == "no waves found" || line == "No signals selected" { + Style::default().fg(Color::Yellow) + } else { + Style::default().fg(Color::White) + }; + ListItem::new(line.clone()).style(style) + }) + .collect(); + + let signal_panel = List::new(items).block( + Block::default() + .borders(ratatui::widgets::Borders::ALL) + .title("Signals"), + ); + + f.render_widget(signal_panel, area); + } + fn render_command_bar(&self, f: &mut Frame, area: ratatui::layout::Rect) { // Use shared component with compact history (show last 3 commands) self.render_command_input(f, area, false, 3); @@ -890,7 +1119,7 @@ impl App { .highlight_style( Style::default() .bg(Color::Blue) - .add_modifier(Modifier::BOLD) + .add_modifier(Modifier::BOLD), ); f.render_widget(results_list, chunks[1]); @@ -907,16 +1136,135 @@ impl App { .alignment(Alignment::Center); f.render_widget(help_text, help_area); } + + fn render_help_modal(&self, f: &mut Frame, area: ratatui::layout::Rect) { + use ratatui::layout::Alignment; + use ratatui::widgets::{Clear, Paragraph}; + + // Calculate popup size and position (centered, 70% width, 60% height) + let popup_area = Layout::default() + .direction(Direction::Vertical) + .constraints([ + Constraint::Percentage(20), // Top margin + Constraint::Percentage(60), // Popup height + Constraint::Percentage(20), // Bottom margin + ]) + .split(area)[1]; + + let popup_area = Layout::default() + .direction(Direction::Horizontal) + .constraints([ + Constraint::Percentage(15), // Left margin + Constraint::Percentage(70), // Popup width + Constraint::Percentage(15), // Right margin + ]) + .split(popup_area)[1]; + + // Clear the background + f.render_widget(Clear, popup_area); + + // Get content and calculate visible area + let content = self.help_modal_state.get_content(); + let available_height = popup_area.height.saturating_sub(2) as usize; // Account for borders + let total_lines = content.len(); + let scroll_offset = self.help_modal_state.get_scroll_offset(); + + // Calculate which lines to show based on scroll offset + let visible_content = if total_lines > available_height { + let max_scroll = total_lines.saturating_sub(available_height); + let actual_scroll = scroll_offset.min(max_scroll); + let start_idx = total_lines.saturating_sub(available_height + actual_scroll); + let end_idx = start_idx + available_height; + + &content[start_idx..end_idx.min(total_lines)] + } else { + content + }; + + // Render help content + let items: Vec = visible_content + .iter() + .map(|line| { + let style = if line.starts_with("Current command") || line.starts_with("Help for") { + Style::default() + .fg(Color::Cyan) + .add_modifier(Modifier::BOLD) + } else if line.starts_with(" ") && line.contains("--") { + // Command line + Style::default().fg(Color::Yellow) + } else if line.starts_with("Keyboard shortcuts:") + || line.starts_with("Description:") + || line.starts_with("Usage:") + || line.starts_with("Aliases:") + || line.starts_with("Examples:") + { + Style::default() + .fg(Color::Green) + .add_modifier(Modifier::BOLD) + } else { + Style::default().fg(Color::White) + }; + ListItem::new(line.clone()).style(style) + }) + .collect(); + + let help_list = List::new(items).block( + Block::default() + .borders(Borders::ALL) + .title("Help (Press Esc, Enter, or 'q' to close)"), + ); + + f.render_widget(help_list, popup_area); + + // Add scrollbar if there's more content than can fit + if total_lines > available_height { + let scrollbar_area = Rect { + x: popup_area.x + popup_area.width - 1, + y: popup_area.y + 1, + width: 1, + height: popup_area.height - 2, + }; + + let max_scroll = total_lines.saturating_sub(available_height); + let scrollbar = Scrollbar::default() + .orientation(ratatui::widgets::ScrollbarOrientation::VerticalRight) + .begin_symbol(Some("▲")) + .end_symbol(Some("▼")); + + let mut scrollbar_state = ratatui::widgets::ScrollbarState::new(total_lines).position( + total_lines.saturating_sub(available_height + scroll_offset.min(max_scroll)), + ); + + f.render_stateful_widget(scrollbar, scrollbar_area, &mut scrollbar_state); + } + + // Add navigation help text at the bottom + let help_area = Rect { + x: popup_area.x, + y: popup_area.y + popup_area.height, + width: popup_area.width, + height: 1, + }; + let nav_text = Paragraph::new( + "↑↓: Scroll | PgUp/PgDn: Page | Home/End: Top/Bottom | Esc/Enter/q: Close", + ) + .style(Style::default().fg(Color::Gray)) + .alignment(Alignment::Center); + f.render_widget(nav_text, help_area); + } } fn main() -> Result<(), Box> { + // Parse command line arguments + let cli_args: cli::JpdbArgs = argh::from_env(); + enable_raw_mode()?; let mut stdout = io::stdout(); execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?; let backend = CrosstermBackend::new(stdout); let mut terminal = Terminal::new(backend)?; - let mut app = App::default(); + let mut app = App::new(cli_args); let res = app.run(&mut terminal); disable_raw_mode()?; @@ -928,7 +1276,7 @@ fn main() -> Result<(), Box> { terminal.show_cursor()?; if let Err(err) = res { - println!("{err:?}"); + log::error!("{err:?}"); } Ok(()) diff --git a/jpdb/src/model.rs b/jpdb/src/model.rs new file mode 100644 index 0000000..71dd21e --- /dev/null +++ b/jpdb/src/model.rs @@ -0,0 +1,262 @@ +use shucks::{Client, TimeTableIdx, Var}; + +pub struct DebuggerModel { + pub client: Client, + cached_time_idx: Option, + terminated: bool, +} + +pub struct ExecutionSnapshot { + pub summary_lines: Vec, + pub instruction_lines: Vec, +} + +pub struct SourceSnapshot { + pub lines: Vec, +} + +pub struct SignalSnapshot { + pub lines: Vec, +} + +pub type ModelResult = Result; + +impl DebuggerModel { + pub fn new(client: Client) -> Self { + Self { + client, + cached_time_idx: None, + terminated: false, + } + } + + pub fn step(&mut self) -> ModelResult<()> { + if self.terminated { + return Err("Process has terminated".to_string()); + } + + let still_alive = self.client.step().map_err(|e| e.to_string())?; + if !still_alive { + self.terminated = true; + return Err("Process has terminated".to_string()); + } + + self.invalidate_time_index(); + Ok(()) + } + + pub fn continue_execution(&mut self) -> ModelResult<()> { + if self.terminated { + return Err("Process has terminated".to_string()); + } + + let still_alive = self + .client + .continue_execution() + .map_err(|e| e.to_string())?; + if !still_alive { + self.terminated = true; + return Err("Process has terminated".to_string()); + } + + self.invalidate_time_index(); + Ok(()) + } + + pub fn set_breakpoint(&mut self, address: u32) -> ModelResult<()> { + self.client + .set_breakpoint(address) + .map_err(|e| e.to_string()) + } + + pub fn set_breakpoint_at_line(&mut self, file: &str, line: u64) -> ModelResult> { + self.client + .set_breakpoint_at_line(file, line) + .map_err(|e| e.to_string()) + } + + pub fn fetch_execution_snapshot(&mut self) -> ModelResult { + if self.terminated { + return Ok(ExecutionSnapshot { + summary_lines: vec!["Process has terminated".to_string()], + instruction_lines: vec!["Process has terminated".to_string()], + }); + } + + let mut summary_lines = Vec::new(); + summary_lines.push("Process 1 stopped".to_string()); + summary_lines.push("* thread #1, stop reason = instruction step over".to_string()); + + let mut instruction_lines = Vec::new(); + + match self.client.get_current_pc() { + Ok(current_pc) => { + summary_lines.push(format!(" frame #0: 0x{current_pc}")); + + match self.client.get_current_and_next_inst() { + Ok(insts) => { + for (i, inst) in insts.iter().enumerate() { + let inst_pc = inst.pc().as_u32(); + let formatted = if i == 0 { + format!("-> 0x{inst_pc:x}: {inst}") + } else { + format!(" 0x{inst_pc:x}: {inst}") + }; + summary_lines.push(formatted.clone()); + instruction_lines.push(formatted); + } + } + Err(_) => { + summary_lines + .push(format!("-> 0x{current_pc}: ")); + instruction_lines + .push(format!("-> 0x{current_pc}: ")); + } + } + } + Err(e) => { + summary_lines.push(format!("Error getting PC: {e}")); + instruction_lines.push(format!("Error: {e}")); + } + } + + summary_lines.push("Target 0: (No executable module.) stopped.".to_string()); + + Ok(ExecutionSnapshot { + summary_lines, + instruction_lines, + }) + } + + pub fn fetch_source_snapshot(&mut self) -> ModelResult { + if self.terminated { + return Ok(SourceSnapshot { + lines: vec!["Process has terminated".to_string()], + }); + } + + let mut lines = Vec::new(); + + match self.client.get_current_source_line() { + Ok(Some(current_line)) => { + lines.push(format!( + "{}:{}", + current_line + .path + .file_name() + .and_then(|n| n.to_str()) + .unwrap_or("unknown"), + current_line.line + )); + lines.push(String::new()); + + if let Some(ref text) = current_line.text { + lines.push(format!("-> {}: {}", current_line.line, text)); + } else { + lines.push(format!("-> {}: ", current_line.line)); + } + + match self.client.get_consecutive_source_lines_after_current(3) { + Ok(next_lines) => { + for line in next_lines { + if let Some(ref text) = line.text { + lines.push(format!(" {}: {}", line.line, text)); + } else { + lines.push(format!(" {}: ", line.line)); + } + } + } + Err(e) => { + lines.push(format!("Error getting next lines: {e}")); + } + } + } + Ok(None) => { + lines.push("Source Code:".to_string()); + lines.push("No debug information available".to_string()); + } + Err(e) => { + lines.push("Source Code:".to_string()); + lines.push(format!("Error: {e}")); + } + } + + Ok(SourceSnapshot { lines }) + } + + pub fn fetch_signal_snapshot(&mut self) -> ModelResult { + if self.terminated { + return Ok(SignalSnapshot { + lines: vec!["Process has terminated".to_string()], + }); + } + + if self.client.wave_tracker.is_none() { + return Ok(SignalSnapshot { + lines: vec!["no waves found".to_string()], + }); + } + + let time_idx = self.get_time_index()?; + + let mut lines = Vec::new(); + if let Some(ref mut tracker) = self.client.wave_tracker { + let current_time = tracker.get_current_time(time_idx as TimeTableIdx); + lines.push(format!("{current_time} ps")); + lines.push(String::new()); + + let signal_names = tracker.get_signal_names(); + if signal_names.is_empty() { + lines.push("No signals selected".to_string()); + lines.push("Use 'addsig' to add signals".to_string()); + } else { + let signal_values = tracker.get_values(time_idx as TimeTableIdx); + for (name, value) in signal_names.iter().zip(signal_values.iter()) { + lines.push(format!("{name}: {value}")); + } + } + } + + Ok(SignalSnapshot { lines }) + } + + pub fn fuzzy_match_signals(&mut self, query: &str) -> Vec<(Var, String)> { + if let Some(ref mut tracker) = self.client.wave_tracker { + tracker.fuzzy_match_var(query) + } else { + Vec::new() + } + } + + pub fn select_signal(&mut self, var: Var) { + if let Some(ref mut tracker) = self.client.wave_tracker { + tracker.select_signal(var); + } + } + + pub fn most_recent_var_path(&self) -> Option { + if let Some(ref tracker) = self.client.wave_tracker { + tracker.get_signal_names().last().cloned() + } else { + None + } + } + + pub fn invalidate_time_index(&mut self) { + self.cached_time_idx = None; + } + + pub fn get_time_idx(&mut self) -> ModelResult { + self.get_time_index() + } + + fn get_time_index(&mut self) -> ModelResult { + if let Some(idx) = self.cached_time_idx { + return Ok(idx); + } + + let idx = self.client.get_time_idx().map_err(|e| e.to_string())?; + self.cached_time_idx = Some(idx); + Ok(idx) + } +} diff --git a/jpdb/src/user_commands.rs b/jpdb/src/user_commands.rs index c82d707..46a15e0 100644 --- a/jpdb/src/user_commands.rs +++ b/jpdb/src/user_commands.rs @@ -41,7 +41,7 @@ pub fn parse_breakpoint_arg(input: &str) -> Result { match addr { Ok(address) => Ok(BreakpointTarget::Address(address)), - Err(_) => Err(format!("Invalid breakpoint format: {}", input)), + Err(_) => Err(format!("Invalid breakpoint format: {input}")), } } @@ -57,6 +57,9 @@ pub enum UserCommand { Continue, Toggle, Addsig, + Debug, + Surfer, + SurferConnect, } impl UserCommand { @@ -68,58 +71,56 @@ impl UserCommand { Ok(()) } UserCommand::Next => { - app.add_execution_info(); app.step_next(); Ok(()) } UserCommand::Step => { - app.add_execution_info(); app.step_next(); Ok(()) } UserCommand::Help => { let registry = CommandRegistry::new(); + let mut content = Vec::new(); + if args.trim().is_empty() { // Show all commands in LLDB style - app.command_history.push("Current command abbreviations (type 'help command alias' for more info):".to_string()); + content.push( + "Current command abbreviations (type 'help command alias' for more info):" + .to_string(), + ); + content.push("".to_string()); for cmd in UserCommand::all() { let aliases_str = cmd.aliases().join(", "); - app.command_history.push(format!( - " {:<9} -- {}", - aliases_str, - cmd.description() - )); + content.push(format!(" {:<9} -- {}", aliases_str, cmd.description())); } - app.command_history.push("".to_string()); - app.command_history.push("Keyboard shortcuts:".to_string()); - app.command_history.push(" d -- Toggle debug panel".to_string()); - app.command_history.push(" Ctrl+D -- Quit the debugger".to_string()); - app.command_history.push(" Ctrl+L -- Clear screen".to_string()); - app.command_history.push("".to_string()); + content.push("".to_string()); + content.push("Keyboard shortcuts:".to_string()); + content.push(" Ctrl+D -- Quit the debugger".to_string()); + content.push(" Ctrl+L -- Clear screen".to_string()); + content.push("".to_string()); } else { // Show specific command help let command_name = args.trim(); if let Some(command) = registry.get_command(command_name) { - app.command_history - .push(format!("Help for '{}':", command.name())); - app.command_history.push("".to_string()); - app.command_history - .push(format!("Description: {}", command.description())); - app.command_history - .push(format!("Usage: {}", command.usage())); - app.command_history - .push(format!("Aliases: {}", command.aliases().join(", "))); - app.command_history.push("".to_string()); - app.command_history.push("Examples:".to_string()); + content.push(format!("Help for '{}':", command.name())); + content.push("".to_string()); + content.push(format!("Description: {}", command.description())); + content.push(format!("Usage: {}", command.usage())); + content.push(format!("Aliases: {}", command.aliases().join(", "))); + content.push("".to_string()); + content.push("Examples:".to_string()); for example in command.examples() { - app.command_history.push(format!(" {example}")); + content.push(format!(" {example}")); } } else { return Err(format!("Unknown command: {command_name}")); } } + + // Activate the help modal with the content + app.help_modal_state.activate(content); Ok(()) } UserCommand::Clear => { @@ -127,60 +128,61 @@ impl UserCommand { app.scroll_offset = 0; Ok(()) } - UserCommand::Breakpoint => { - match parse_breakpoint_arg(args)? { - BreakpointTarget::Address(address) => { - match app.shucks_client.set_breakpoint(address) { - Ok(()) => { - app.command_history.push(format!("Breakpoint set at address 0x{:x}", address)); - Ok(()) - } - Err(e) => { - Err(format!("Failed to set breakpoint: {}", e)) - } - } + UserCommand::Breakpoint => match parse_breakpoint_arg(args)? { + BreakpointTarget::Address(address) => match app.set_breakpoint(address) { + Ok(()) => { + app.command_history + .push(format!("Breakpoint set at address 0x{address:x}")); + Ok(()) } - BreakpointTarget::FileLine { file, line } => { - let file_str = file.to_string_lossy(); - match app.shucks_client.set_breakpoint_at_line(&file_str, line) { - Ok(addresses) => { - if addresses.len() == 1 { - app.command_history.push(format!( - "Breakpoint set at {}:{} (address 0x{:x})", - file_str, line, addresses[0] - )); - } else { - app.command_history.push(format!( - "Breakpoint set at {}:{} ({} addresses: {})", - file_str, line, addresses.len(), - addresses.iter().map(|a| format!("0x{:x}", a)).collect::>().join(", ") - )); - } - Ok(()) - } - Err(e) => { - Err(format!("Failed to set breakpoint at {}:{}: {}", file_str, line, e)) + Err(e) => Err(format!("Failed to set breakpoint: {e}")), + }, + BreakpointTarget::FileLine { file, line } => { + let file_str = file.to_string_lossy(); + match app.set_breakpoint_at_line(&file_str, line) { + Ok(addresses) => { + if addresses.len() == 1 { + app.command_history.push(format!( + "Breakpoint set at {}:{} (address 0x{:x})", + file_str, line, addresses[0] + )); + } else { + app.command_history.push(format!( + "Breakpoint set at {}:{} ({} addresses: {})", + file_str, + line, + addresses.len(), + addresses + .iter() + .map(|a| format!("0x{a:x}")) + .collect::>() + .join(", ") + )); } + Ok(()) } + Err(e) => Err(format!( + "Failed to set breakpoint at {file_str}:{line}: {e}" + )), } } - } + }, UserCommand::Continue => { app.command_history.push("Continuing...".to_string()); // Send continue command via shucks client - if let Err(e) = app.shucks_client.send_command_parsed( - shucks::Packet::Command(shucks::commands::GdbCommand::Resume( - shucks::commands::Resume::Continue - )) - ) { - return Err(format!("Error continuing execution: {}", e)); + if let Err(e) = app.continue_execution() { + return Err(format!("Error continuing execution: {e}")); } + + app.command_history.push("Hit breakpoint...".to_string()); + app.refresh_all_views(); Ok(()) } UserCommand::Toggle => { app.show_split_view = !app.show_split_view; if app.show_split_view { - app.command_history.push("Split view enabled (instructions | source code)".to_string()); + app.command_history + .push("Split view enabled (instructions | source code)".to_string()); } else { app.command_history.push("Split view disabled".to_string()); } @@ -190,6 +192,36 @@ impl UserCommand { app.addsig_state.activate(); Ok(()) } + UserCommand::Debug => { + app.show_debug_panel = !app.show_debug_panel; + if app.show_debug_panel { + app.command_history.push("Debug panel enabled".to_string()); + } else { + app.command_history.push("Debug panel disabled".to_string()); + } + Ok(()) + } + UserCommand::Surfer => { + let wave_path = app.cli_args.wave_path.clone(); + app.launch_surfer(&wave_path) + .map_err(|e| format!("Failed to launch Surfer: {e}"))?; + app.command_history + .push("Surfer launched successfully".to_string()); + Ok(()) + } + UserCommand::SurferConnect => { + //FIXME: bad constant evil evil evil + let addr = if args.trim().is_empty() { + "127.0.0.1:54321".to_string() + } else { + args.trim().to_string() + }; + app.connect_to_surfer(&addr) + .map_err(|e| format!("Failed to connect to Surfer: {e}"))?; + app.command_history + .push(format!("Connected to Surfer at {addr}")); + Ok(()) + } } } @@ -205,6 +237,9 @@ impl UserCommand { UserCommand::Continue => "continue", UserCommand::Toggle => "toggle", UserCommand::Addsig => "addsig", + UserCommand::Debug => "debug", + UserCommand::Surfer => "surfer", + UserCommand::SurferConnect => "surferconnect", } } @@ -220,6 +255,9 @@ impl UserCommand { UserCommand::Continue => &["continue", "c"], UserCommand::Toggle => &["toggle", "t"], UserCommand::Addsig => &["addsig", "as"], + UserCommand::Debug => &["debug", "d"], + UserCommand::Surfer => &["surfer", "sf"], + UserCommand::SurferConnect => &["surferconnect", "sfc"], } } @@ -234,7 +272,10 @@ impl UserCommand { UserCommand::Breakpoint => "Set a breakpoint at the specified address or file:line", UserCommand::Continue => "Continue execution until breakpoint", UserCommand::Toggle => "Toggle split view (instructions | source code)", - UserCommand::Addsig => "Open floating window to add signal via fuzzy search", + UserCommand::Addsig => "Open floating window to add waveform signals via fuzzy search", + UserCommand::Debug => "Toggle debug panel", + UserCommand::Surfer => "Launch Surfer waveform viewer and connect to it", + UserCommand::SurferConnect => "Connect to a running Surfer instance", } } @@ -250,6 +291,9 @@ impl UserCommand { UserCommand::Continue => "continue", UserCommand::Toggle => "toggle", UserCommand::Addsig => "addsig", + UserCommand::Debug => "debug", + UserCommand::Surfer => "surfer", + UserCommand::SurferConnect => "surferconnect [address:port]", } } @@ -261,10 +305,18 @@ impl UserCommand { UserCommand::Step => &["step", "s"], UserCommand::Help => &["help", "help next", "h quit"], UserCommand::Clear => &["clear", "cl"], - UserCommand::Breakpoint => &["breakpoint 0x1000", "b 1000", "b main.c:42", "b src/lib.rs:123"], + UserCommand::Breakpoint => &[ + "breakpoint 0x1000", + "b 1000", + "b main.c:42", + "b src/lib.rs:123", + ], UserCommand::Continue => &["continue", "c"], UserCommand::Toggle => &["toggle", "t"], UserCommand::Addsig => &["addsig", "as"], + UserCommand::Debug => &["debug", "d"], + UserCommand::Surfer => &["surfer", "sf"], + UserCommand::SurferConnect => &["surferconnect", "sfc", "surferconnect 127.0.0.1:3333"], } } @@ -280,6 +332,9 @@ impl UserCommand { UserCommand::Continue, UserCommand::Toggle, UserCommand::Addsig, + UserCommand::Debug, + UserCommand::Surfer, + UserCommand::SurferConnect, ] } } @@ -368,4 +423,3 @@ mod tests { ); } } - diff --git a/jpdb/src/view.rs b/jpdb/src/view.rs new file mode 100644 index 0000000..c2f81d9 --- /dev/null +++ b/jpdb/src/view.rs @@ -0,0 +1,8 @@ +#[derive(Default)] +pub struct ViewState { + pub execution_lines: Vec, + pub instruction_lines: Vec, + pub source_lines: Vec, + pub signal_lines: Vec, +} + diff --git a/jpdb/src/wcp_client.rs b/jpdb/src/wcp_client.rs new file mode 100644 index 0000000..162615d --- /dev/null +++ b/jpdb/src/wcp_client.rs @@ -0,0 +1,107 @@ +use libsurfer::wcp::proto::{WcpCSMessage, WcpCommand}; +use std::io::{Read, Write}; +use std::net::TcpStream; +use std::time::Duration; + +/// WCP (Waveform Control Protocol) client for controlling Surfer waveform viewer +pub struct WcpClient { + stream: TcpStream, +} + +impl WcpClient { + /// Connect to a WCP server at the given address + pub fn connect(addr: &str) -> Result> { + let stream = TcpStream::connect(addr)?; + stream.set_nodelay(true)?; + + // Set read timeout to 10 seconds + stream.set_read_timeout(Some(Duration::from_secs(10)))?; + + let mut rv = Self { stream }; + rv.greet()?; + Ok(rv) + } + + fn greet(&mut self) -> Result<(), Box> { + let message = WcpCSMessage::greeting { + version: "0".to_string(), + commands: vec!["set_viewport_to".to_string()], + }; + self.send_message(message)?; + log::info!("greeted surfer"); + Ok(()) + } + + fn send_message(&mut self, message: WcpCSMessage) -> Result<(), Box> { + let message_str = serde_json::to_string(&message)?; + + // Debug: log the JSON being sent + log::info!("Sending WCP message: {message_str}"); + + // Write message followed by null terminator (not newline!) + self.stream.write_all(message_str.as_bytes())?; + self.stream.write_all(b"\0")?; + self.stream.flush()?; + + // Read response until null terminator (with timeout) + let mut buffer = Vec::new(); + let mut byte = [0u8; 1]; + + loop { + match self.stream.read_exact(&mut byte) { + Ok(_) => { + if byte[0] == 0 { + break; // Found null terminator + } + buffer.push(byte[0]); + } + Err(e) if e.kind() == std::io::ErrorKind::TimedOut => { + return Err("Timeout waiting for response from WCP server" + .to_string() + .into()); + } + Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => { + return Err(format!( + "Server closed connection unexpectedly. Partial response: {:?}", + String::from_utf8_lossy(&buffer) + ) + .into()); + } + Err(e) => return Err(e.into()), + } + } + + log::info!("got response: {:?}", String::from_utf8_lossy(&buffer)); + Ok(()) + } + + /// Send a WCP command to the server + fn send_command(&mut self, command: WcpCommand) -> Result<(), Box> { + let message = WcpCSMessage::command(command); + self.send_message(message) + } + + /// Navigate to a specific timestamp in the waveform (time in picoseconds) + pub fn goto_time(&mut self, _time_ps: u64) -> Result<(), Box> { + //TODO: this looks to be buggy on the surfer side, from what i can tell. + //let command = WcpCommand::set_viewport_to { + // timestamp: BigInt::from(time_ps), + //}; + //let rv = self.send_command(command); + //log::info!( + // "tried to set viewport to {time_ps}\n\ + // and got response: \n\ + // {rv:?}" + //); + Ok(()) + //rv + } + + /// Add a signal to the waveform viewer + pub fn add_signal(&mut self, signal_path: &str) -> Result<(), Box> { + let command = WcpCommand::add_variables { + variables: vec![signal_path.to_string()], + }; + self.send_command(command) + } +} diff --git a/shucks/src/addr2line_stepper.rs b/shucks/src/addr2line_stepper.rs index 2be9197..c2bb723 100644 --- a/shucks/src/addr2line_stepper.rs +++ b/shucks/src/addr2line_stepper.rs @@ -22,8 +22,7 @@ pub struct Addr2lineStepper { dwarf: gimli::Dwarf>, load_bias: u64, source_cache: Mutex>>>, - path_cache: Mutex>, // Cache for search_for_path results - _section_data: Vec>, // Keep section data alive + _section_data: Vec>, // Keep section data alive } impl Addr2lineStepper { @@ -101,9 +100,7 @@ impl Addr2lineStepper { ctx, dwarf, load_bias, - source_cache: Mutex::new(HashMap::new()), - path_cache: Mutex::new(HashMap::new()), // Initialize the path cache _section_data: section_data, }) } diff --git a/shucks/src/client.rs b/shucks/src/client.rs index fe2b38f..4ae5983 100644 --- a/shucks/src/client.rs +++ b/shucks/src/client.rs @@ -7,14 +7,13 @@ use std::{ use crate::{ addr2line_stepper::Addr2lineStepper, - commands::{Base, GdbCommand}, + commands::{Base, GdbCommand, Resume}, response::{GdbResponse, RawGdbResponse}, wavetracker::WaveformTracker, Packet, }; use goblin::elf::Elf; use raki::{Decode, Isa}; -use wellen::simple::Waveform; pub struct Client { strm: TcpStream, @@ -23,6 +22,13 @@ pub struct Client { elf_info: Option, addr2line_stepper: Option, pub wave_tracker: Option, + cached_state: CachedState, +} + +#[derive(Default, Clone)] +pub struct CachedState { + pc: Option, + time_idx: Option, } #[derive(Copy, Clone)] @@ -138,13 +144,14 @@ impl Client { addr2line_stepper: None, wave_tracker: None, response_buffer: Vec::new(), + cached_state: CachedState::default(), } } /// Drain any remaining data in the response buffer to ensure synchronization fn drain_response_buffer(&mut self) { if !self.response_buffer.is_empty() { - log::info!( + log::warn!( "Draining {} bytes from response buffer to maintain synchronization", self.response_buffer.len() ); @@ -154,12 +161,12 @@ impl Client { pub fn send_command(&mut self, packet: &Packet) -> Result { let pkt = packet.to_finished_packet(self.packet_scratch.as_mut_slice())?; - log::info!("Sending packet: {packet:?}"); + self.strm.write_all(pkt.0)?; // Read response with proper packet handling let response = self.read_gdb_packet()?; - log::info!("Read {} bytes, content is {:?}", response.len(), &response); + log::trace!("Read {} bytes, content is {:?}", response.len(), &response); let _tstr = String::from_utf8_lossy(response.as_slice()); @@ -177,7 +184,7 @@ impl Client { // First, check if we have a complete packet in the buffer from previous reads if let Some((packet, remaining)) = Self::find_first_complete_packet(&self.response_buffer) { self.response_buffer = remaining; - log::info!( + log::debug!( "Returned buffered packet, {} bytes remaining in buffer", self.response_buffer.len() ); @@ -199,11 +206,6 @@ impl Client { Ok(n) => { // Add new data to our response buffer self.response_buffer.extend_from_slice(&temp_buffer[..n]); - log::debug!( - "Read {} bytes, buffer now has {} bytes", - n, - self.response_buffer.len() - ); // Try to extract a complete packet from buffer - only check if we potentially have enough data if self.response_buffer.len() >= 4 { @@ -212,7 +214,7 @@ impl Client { Self::find_first_complete_packet(&self.response_buffer) { self.response_buffer = remaining; - log::info!( + log::trace!( "Extracted packet, {} bytes remaining in buffer", self.response_buffer.len() ); @@ -256,7 +258,7 @@ impl Client { Self::find_first_complete_packet(&self.response_buffer) { self.response_buffer = remaining; - log::info!( + log::trace!( "Extracted packet, {} bytes remaining in buffer", self.response_buffer.len() ); @@ -283,24 +285,72 @@ impl Client { let mdata = RawGdbResponse::find_packet_data(buffer).ok(); if let Some(data) = mdata { let remaining = buffer[data.entire_packet_len()..].to_vec(); - log::debug!( - "input buffer is {}, output is {}. remaining is {}", - String::from_utf8_lossy(buffer), - String::from_utf8_lossy(data.as_slice()), - String::from_utf8_lossy(remaining.as_slice()) - ); return Some((data, remaining)); } None } + pub fn step(&mut self) -> Result> { + let resp = self.send_command_parsed(Packet::Command(GdbCommand::Resume(Resume::Step)))?; + if let crate::response::GdbResponse::StopReply { reason, .. } = &resp { + match reason { + crate::response::StopReason::ProcessExit { code } => { + log::info!("Program exited with code 0x{:02x}", code); + return Ok(false); + } + crate::response::StopReason::SignalTermination(sig) => { + log::info!("Program terminated with signal 0x{:02x}", sig); + return Ok(false); + } + _ => {} + } + } + + self.cached_state.time_idx = None; + self.cached_state.pc = None; + self.cached_state.pc = Some(self.get_current_pc()?); + self.cached_state.time_idx = Some(self.get_time_idx()?); + Ok(true) + } + + //returns false + pub fn continue_execution(&mut self) -> Result> { + let resp = + self.send_command_parsed(Packet::Command(GdbCommand::Resume(Resume::Continue)))?; + self.cached_state.time_idx = None; + self.cached_state.pc = None; + + // Check if the program has terminated + if let crate::response::GdbResponse::StopReply { reason, .. } = &resp { + match reason { + crate::response::StopReason::ProcessExit { code } => { + log::info!("Program exited with code 0x{:02x}", code); + return Ok(false); + } + crate::response::StopReason::SignalTermination(sig) => { + log::info!("Program terminated with signal 0x{:02x}", sig); + return Ok(false); + } + _ => { + log::info!("cont exec reason: {reason:?}"); + } + } + } + + self.cached_state.pc = Some(self.get_current_pc()?); + self.cached_state.time_idx = Some(self.get_time_idx()?); + log::info!("Continue execution response: {resp:?}"); + + Ok(true) + } + pub fn send_command_parsed( &mut self, packet: Packet, ) -> Result> { let raw_response = self.send_command(&packet)?; let parsed_response = GdbResponse::parse_packet(raw_response, &packet)?; - log::info!("Parsed response: {parsed_response} from input {packet:?}"); + log::info!("Sent packet: {packet:?} and got response: {parsed_response:?}"); Ok(parsed_response) } @@ -311,19 +361,17 @@ impl Client { } pub fn initialize_gdb_session(&mut self) -> Result<(), Box> { - log::info!("Starting GDB initialization sequence..."); - // QStartNoAckMode must return OK per RSP match self.send_command_parsed(Packet::Command(GdbCommand::Base(Base::QStartNoAckMode)))? { GdbResponse::Ack => { - log::info!("QStartNoAckMode acknowledged with an ack"); + log::trace!("QStartNoAckMode acknowledged with an ack"); let resp = self.pop_response()?; if resp != GdbResponse::Ok { return Err(format!("Expected Ok for QStartNoAckMode, got: {resp}").into()); } } GdbResponse::Ok => { - log::info!("QStartNoAckMode acknowledged with an ok"); + log::trace!("QStartNoAckMode acknowledged with an ok"); } other => { return Err(format!("Expected Ack for QStartNoAckMode, got: {other}").into()); @@ -339,7 +387,7 @@ impl Client { format!("qSupported missing PacketSize in features: {features:?}").into(), ); } - log::info!("qSupported features: {features:?}"); + log::trace!("qSupported features: {features:?}"); } other => { return Err(format!("Expected qSupported feature list, got: {other}").into()); @@ -347,10 +395,10 @@ impl Client { } // qfThreadInfo must return thread list (may be empty) or 'm...' chunk - log::info!("About to send qfThreadInfo..."); + match self.send_command_parsed(Packet::Command(GdbCommand::Base(Base::QfThreadInfo)))? { GdbResponse::ThreadInfo { threads, .. } => { - log::info!("qfThreadInfo threads: {threads:?}"); + log::trace!("qfThreadInfo threads: {threads:?}"); } other => { return Err(format!("Expected thread info for qfThreadInfo, got: {other}").into()); @@ -358,10 +406,10 @@ impl Client { } // qsThreadInfo should continue list or return end - log::info!("About to send qsThreadInfo..."); + match self.send_command_parsed(Packet::Command(GdbCommand::Base(Base::QsThreadInfo)))? { GdbResponse::ThreadInfo { threads, .. } => { - log::info!("qsThreadInfo threads: {threads:?}"); + log::trace!("qsThreadInfo threads: {threads:?}"); } other => { return Err(format!("Expected thread info for qsThreadInfo, got: {other}").into()); @@ -371,7 +419,7 @@ impl Client { // '?' must return a stop reply (Sxx or Txx) match self.send_command_parsed(Packet::Command(GdbCommand::Base(Base::QuestionMark)))? { GdbResponse::StopReply { signal, .. } => { - log::info!("Got stop reply with signal 0x{signal:02x}"); + log::trace!("Got stop reply with signal 0x{signal:02x}"); } other => { return Err(format!("Expected stop reply for '?', got: {other}").into()); @@ -387,7 +435,7 @@ impl Client { data.len() ).into()); } - log::info!("Register read length OK: {} bytes", data.len()); + log::trace!("Register read length OK: {} bytes", data.len()); } other => { return Err(format!("Expected RegisterData for 'g' (LowerG), got: {other}").into()); @@ -399,9 +447,12 @@ impl Client { } pub fn get_time_idx(&mut self) -> Result> { + if let Some(time_idx) = self.cached_state.time_idx { + return Ok(time_idx); + } + let rv = self .send_monitor_command("time_idx") - .inspect(|val| println!("{val}")) .map(|output| output.trim().parse::().map_err(|e| e.into()))?; rv @@ -422,7 +473,15 @@ impl Client { let response = self.send_command_parsed(monitor_packet)?; match response { - crate::response::GdbResponse::MonitorOutput { output } => Ok(output), + crate::response::GdbResponse::MonitorOutput { output } => { + // Monitor commands send an OK packet after the output + // We need to consume it to keep the response buffer clean + let ok_response = self.pop_response()?; + if ok_response != crate::response::GdbResponse::Ok { + log::warn!("Expected OK after monitor output, got: {ok_response}"); + } + Ok(output) + } other => Err(format!("Expected monitor output, got: {other}").into()), } } @@ -616,6 +675,10 @@ impl Client { /// Get the current program counter (PC) from registers pub fn get_current_pc(&mut self) -> Result> { + if let Some(pc) = self.cached_state.pc { + return Ok(pc); + } + // Add a small delay to avoid rapid command sending that can cause response ordering issues let registers = @@ -623,7 +686,7 @@ impl Client { match registers { crate::response::GdbResponse::RegisterData { data } => { - log::debug!("Got RegisterData with {} bytes", data.len()); + log::trace!("Got RegisterData with {} bytes", data.len()); if data.len() < 132 { return Err(format!( "Register data too short to contain PC (got {} bytes, need 132)", @@ -654,11 +717,11 @@ impl Client { // Get current PC using the dedicated method let pc = self.get_current_pc()?; - log::info!("Program Counter (PC): 0x{pc}"); + log::debug!("Program Counter (PC): 0x{pc}"); // Check if we have symbol information if let Some((symbol, offset)) = self.find_symbol_at_address(pc.as_u64()) { - log::info!("Current function: {} + 0x{:x}", symbol.name, offset); + log::debug!("Current function: {} + 0x{:x}", symbol.name, offset); } // Get instruction bytes directly from ELF binary (16 bytes = 4 instructions) @@ -687,7 +750,7 @@ impl Client { let u16inst = uu16 .decode(Isa::Rv32) .inspect_err(|e| log::error!("u16 err is {e:?}, 0x{uu16:x}")) - .inspect(|arg| log::info!("{arg}")) + .inspect(|arg| log::debug!("{arg}")) .map(|val| Instruction(val, pc.add(start as u32))) .ok(); let u32inst = uu32 @@ -708,7 +771,7 @@ impl Client { if start == 0 { panic!("THERE S A BOMB IN MY CAR"); } - log::info!("Done") + log::debug!("Done") } } } @@ -989,7 +1052,7 @@ mod tests { &packet_type, ); - log::info!( + log::debug!( "Test case {}: data length = {}, result = {:?}", i, register_data.len(), @@ -999,10 +1062,10 @@ mod tests { match response { Ok(GdbResponse::RegisterData { data }) => { assert_eq!(data.len(), register_data.len()); - log::info!("✓ Correctly parsed as RegisterData"); + log::debug!("✓ Correctly parsed as RegisterData"); } Ok(GdbResponse::Empty) if register_data.is_empty() => { - log::info!("✓ Empty register data correctly parsed as Empty"); + log::debug!("✓ Empty register data correctly parsed as Empty"); } Ok(GdbResponse::MemoryData { data: _ }) => { panic!("⚠ Parsed as MemoryData instead of RegisterData (length={}, divisible by 4={})", @@ -1050,4 +1113,117 @@ mod tests { // Kill the handle by not waiting for it to complete drop(handle); } + + #[test] + fn test_time_idx_then_pc() { + crate::init_test_logger(); + let (listener, port) = create_test_listener(); + + // Start dang GDB stub in a separate thread + let handle = start_dang_instance(listener); + + // Give the server time to start + sleep(Duration::from_millis(1000)); + + // Connect with the client to actual dang instance + let mut client = Client::new_with_port(port); + sleep(Duration::from_millis(200)); // Increased delay for stability + + client + .initialize_gdb_session() + .expect("failed to init gdb session for time_idx_then_pc test"); + sleep(Duration::from_millis(100)); // Increased delay for stability + + // Call get_time_idx first + let time_idx = client.get_time_idx().expect("Failed to get time_idx"); + log::info!("Got time_idx: {}", time_idx); + + // Now try to get PC multiple times + for i in 0..3 { + match client.get_current_pc() { + Ok(pc) => { + log::info!("PC attempt {}: 0x{:x}", i + 1, pc.as_u32()); + assert!(pc.nz(), "PC should be non-zero"); + } + Err(e) => { + panic!( + "Failed to get PC on attempt {} after get_time_idx: {:?}", + i + 1, + e + ); + } + } + } + + // Kill the handle by not waiting for it to complete + drop(handle); + } + + #[test] + fn test_continue_past_program_end() { + crate::init_test_logger(); + let (listener, port) = create_test_listener(); + + // Start dang GDB stub in a separate thread + let handle = start_dang_instance(listener); + + // Give the server time to start + sleep(Duration::from_millis(1000)); + + // Connect with the client to actual dang instance + let mut client = Client::new_with_port(port); + sleep(Duration::from_millis(200)); + + client + .initialize_gdb_session() + .expect("failed to init gdb session for continue_past_end test"); + sleep(Duration::from_millis(100)); + + client.load_elf_info().expect("Failed to load elf info"); + + // Continue execution repeatedly until we reach the end + // The test program should eventually finish + let mut last_time_idx = 0; + let mut same_time_count = 0; + + for i in 0..100 { + log::info!("Continue attempt {}", i + 1); + + let result = client.continue_execution(); + + match result { + Ok(false) => { + log::info!("Program has reached the end"); + } + + Ok(true) => { + log::info!("Program is still running"); + } + Err(e) => { + log::info!("Continue failed (expected at program end): {:?}", e); + break; + } + } + } + + // Now try to continue past the end - this is where the bug should occur + log::info!("Attempting to continue past program end..."); + let result = client.continue_execution(); + + match result { + Ok(true) => { + panic!("WTF we didnt terminate?"); + } + Ok(false) => { + log::info!("We terminated"); + } + Err(e) => { + log::info!("Continue past end failed with error: {:?}", e); + // This is expected - the test should document the error behavior + } + } + + // Kill the handle by not waiting for it to complete + drop(handle); + } } diff --git a/shucks/src/lib.rs b/shucks/src/lib.rs index 980f93f..87b526b 100644 --- a/shucks/src/lib.rs +++ b/shucks/src/lib.rs @@ -9,9 +9,9 @@ mod wavetracker; pub use addr2line_stepper::SourceLine; pub use client::Client; -pub use wellen::Var; use commands::{Base, GdbCommand}; use packet::FinishedPacket; +pub use wellen::{TimeTableIdx, Var}; /// Top-Level GDB packet #[derive(Default, Debug)] @@ -123,7 +123,7 @@ mod tests { let response1 = cl .send_command(&Packet::Command(GdbCommand::Resume(Resume::Step))) .expect("Failed to send first step command"); - log::info!( + log::debug!( "First step response: {:?}", String::from_utf8_lossy(response1.as_slice()) ); @@ -132,7 +132,7 @@ mod tests { let response2 = cl .send_command(&Packet::Command(GdbCommand::Resume(Resume::Step))) .expect("Failed to send second step command"); - log::info!( + log::debug!( "Second step response: {:?}", String::from_utf8_lossy(response2.as_slice()) ); diff --git a/shucks/src/response.rs b/shucks/src/response.rs index 01fd57d..cf9b89b 100644 --- a/shucks/src/response.rs +++ b/shucks/src/response.rs @@ -85,6 +85,7 @@ pub enum StopReason { Watchpoint { addr: u32 }, SingleStep, ProcessExit { code: u8 }, + SignalTermination(u8), Unknown, } @@ -146,12 +147,6 @@ impl RawGdbResponse { } pub fn find_packet_data(data: &[u8]) -> Result { - log::info!( - "find_packet_data: examining {} bytes: {:?}", - data.len(), - String::from_utf8_lossy(data) - ); - if data.is_empty() { return Err(ParseError::InvalidFormat("no data")); } @@ -165,7 +160,7 @@ impl RawGdbResponse { } if data.len() < 4 || data[0] != b'$' { - log::info!("find_packet_data: packet too short or missing $ prefix"); + log::warn!("find_packet_data: packet too short or missing $ prefix"); return Err(ParseError::InvalidFormat("missing $ prefix")); } @@ -185,7 +180,6 @@ impl RawGdbResponse { // Extract exactly 2 characters for checksum, ignore anything after let checksum_str = str::from_utf8(&data[hash_pos + 1..hash_pos + 3]) .map_err(|_| ParseError::InvalidFormat("invalid checksum -- its not a string"))?; - log::info!("Checksum string: {checksum_str}"); // Verify checksum let expected_checksum = @@ -194,9 +188,8 @@ impl RawGdbResponse { let actual_checksum = content.iter().fold(0u8, |acc, &b| acc.wrapping_add(b)); if actual_checksum != expected_checksum { - log::info!("Content: {content:?}"); - log::info!( - "Actual checksum: {actual_checksum}, expected checksum: {expected_checksum}" + log::error!( + "checksum mismatch! actual checksum: {actual_checksum}, expected checksum: {expected_checksum}" ); return Err(ParseError::InvalidChecksum); } @@ -217,19 +210,8 @@ impl GdbResponse { fn parse_content(raw_resp: RawGdbResponse, packet: &Packet) -> Result { let content = raw_resp.as_slice(); - log::debug!( - "Parsing content ({} bytes): {:?}", - content.len(), - String::from_utf8_lossy(content) - ); - log::debug!( - "AAAAAAAAAAPacket starts with {:?}, {}", - content.first(), - content.starts_with(b"m") - ); - if content.is_empty() { - log::debug!("Empty content -> GdbResponse::Empty"); + log::trace!("Empty content -> GdbResponse::Empty"); return Ok(GdbResponse::Empty); } @@ -251,26 +233,21 @@ impl GdbResponse { Ok(GdbResponse::Error { code }) } - // Stop reply packet (Sxx or Txx...) - content if content.len() >= 3 && (content[0] == b'S' || content[0] == b'T') => { + // Stop reply packet (Sxx, Txx, Wxx, or Xxx) + content if content.len() >= 3 && (content[0] == b'S' || content[0] == b'T' || content[0] == b'W' || content[0] == b'X') => { Self::parse_stop_reply(content) } // qXfer responses (m or l) content if content.starts_with(b"m") => { - log::info!("DEBUG: Found 'm' prefix, content length: {}", content.len()); let data_part = &content[1..]; let looks_like_thread = Self::looks_like_thread_info(data_part); - log::info!("DEBUG: Data part: {:?}", String::from_utf8_lossy(data_part)); - log::info!("DEBUG: Looks like thread info: {looks_like_thread}"); // This could be either thread info or qXfer data // Try to parse as thread info first, then fall back to qXfer if looks_like_thread { - log::info!("DEBUG: Parsing as thread info"); Self::parse_thread_info(content, false) } else { - log::info!("DEBUG: Parsing as qXfer data"); // Parse as qXfer data Ok(GdbResponse::QXferData { data: content[1..].to_vec(), @@ -317,36 +294,29 @@ impl GdbResponse { // Monitor responses often come in the format "O" // where 'O' indicates console output let output = if content.starts_with(b"O") && content.len() > 1 { - // Strip the 'O' prefix and decode the remaining hex - println!("stripped hex content is {:?}", &content[1..]); + // Strip the 'O' prefix, decode run-length encoding, then decode hex let hex_content = &content[1..]; - if Self::is_hex_data(hex_content) { - println!("hex content is hex data"); - match Self::decode_hex(hex_content) { + + // Decode run-length encoding first (handles '*' markers) + let run_length_decoded = Self::decode_run_length(hex_content); + + if Self::is_hex_data(&run_length_decoded) { + match Self::decode_hex(&run_length_decoded) { Ok(decoded_bytes) => { - println!("decoded bytes are {:?}", &decoded_bytes); String::from_utf8_lossy(&decoded_bytes).to_string() } - Err(e) => { - println!("error is {e:?} when decoding hex data"); - String::from_utf8_lossy(content).to_string() - } + Err(_e) => String::from_utf8_lossy(content).to_string(), } } else { String::from_utf8_lossy(content).to_string() } - } else if Self::is_hex_data(content) { - println!("hex content is hex data"); - println!("unstripped hex content is {:?}", &content[1..]); - - // Try to decode as hex first - match Self::decode_hex(content) { - Ok(decoded_bytes) => { - println!("decoded bytes are {:?}", &decoded_bytes); - String::from_utf8_lossy(&decoded_bytes).to_string() - } + } else if Self::is_hex_data_or_run_length(content) { + // Decode run-length encoding first, then try hex decode + let run_length_decoded = Self::decode_run_length(content); + match Self::decode_hex(&run_length_decoded) { + Ok(decoded_bytes) => String::from_utf8_lossy(&decoded_bytes).to_string(), Err(e) => { - println!("error is {e:?} when decoding hex data"); + log::error!("error is {e:?} when decoding hex data"); String::from_utf8_lossy(content).to_string() } } @@ -362,21 +332,17 @@ impl GdbResponse { let run_length_decoded = Self::decode_run_length(content); let data = Self::decode_hex(&run_length_decoded)?; - log::info!( - "Original content was {:?}", - String::from_utf8_lossy(content) - ); - log::info!("Decoded run-length + hex data: {} bytes", data.len()); + log::trace!("Decoded run-length + hex data: {} bytes", data.len()); // Use packet type to determine response classification if packet.is_register_read() { - log::debug!( + log::trace!( "Classified as RegisterData based on packet type (length={})", data.len() ); Ok(GdbResponse::RegisterData { data }) } else if packet.is_memory_read() { - log::debug!( + log::trace!( "Classified as MemoryData based on packet type (length={})", data.len() ); @@ -384,7 +350,7 @@ impl GdbResponse { } else { // Fallback: use heuristic for unknown packet types if data.len() >= 128 && data.len() % 4 == 0 { - log::debug!( + log::trace!( "Heuristically classified as RegisterData (length={}, divisible by 4)", data.len() ); @@ -401,33 +367,42 @@ impl GdbResponse { // Default: return as raw data _ => { - log::debug!("Classified as Raw data (no specific pattern matched)"); + log::trace!("Classified as Raw data (no specific pattern matched)"); Ok(GdbResponse::Raw { data: content.to_vec(), }) } } .map(|response| { - log::debug!("Final parsed response: {response}"); + log::trace!("Final parsed response: {response}"); response }) } - /// Parse stop reply packets (S or T packets) + /// Parse stop reply packets (S, T, W, or X packets) fn parse_stop_reply(content: &[u8]) -> Result { if content.len() < 3 { return Err(ParseError::InvalidFormat("stop reply packet too short")); } - let signal_str = str::from_utf8(&content[1..3]).map_err(|_| ParseError::InvalidHex)?; - let signal = u8::from_str_radix(signal_str, 16).map_err(|_| ParseError::InvalidHex)?; + let packet_type = content[0]; + let value_str = str::from_utf8(&content[1..3]).map_err(|_| ParseError::InvalidHex)?; + let value = u8::from_str_radix(value_str, 16).map_err(|_| ParseError::InvalidHex)?; + + // Determine the reason based on packet type + let reason = match packet_type { + b'S' | b'T' => StopReason::Signal(value), + b'W' => StopReason::ProcessExit { code: value }, + b'X' => StopReason::SignalTermination(value), + _ => return Err(ParseError::InvalidFormat("unknown stop reply packet type")), + }; - // For now, we'll parse just the basic signal - // TODO: Parse additional stop reply information (thread ID, registers, etc.) + // For now, we'll parse just the basic signal/code + // TODO: Parse additional stop reply information (thread ID, registers, process:pid extensions, etc.) Ok(GdbResponse::StopReply { - signal, + signal: value, thread_id: None, - reason: StopReason::Signal(signal), + reason, }) } @@ -699,7 +674,7 @@ mod tests { crate::init_test_logger(); assert_eq!( test_parse(b"$OK#9a") - .inspect_err(|e| log::info!("Error: {e:?}")) + .inspect_err(|e| log::debug!("Error: {e:?}")) .expect("Failed ok"), GdbResponse::Ok ); @@ -800,4 +775,68 @@ mod tests { let hex_decoded = GdbResponse::decode_hex(&run_length_decoded).unwrap(); assert_eq!(hex_decoded, vec![0x00, 0x00]); } + + #[test] + fn test_parse_w_packet_normal_exit() { + crate::init_test_logger(); + // Test W packet - normal process exit with code 0 + // Checksum: W(87) + 0(48) + 0(48) = 183 = 0xb7 + let packet = b"$W00#b7"; + let response = test_parse(packet).expect("Failed to parse W00 packet"); + + if let GdbResponse::StopReply { signal, reason, .. } = response { + assert_eq!(signal, 0x00); + assert_eq!(reason, StopReason::ProcessExit { code: 0x00 }); + } else { + panic!("Expected StopReply with ProcessExit, got: {:?}", response); + } + } + + #[test] + fn test_parse_x_packet_signal_termination() { + crate::init_test_logger(); + // Test X packet - termination with signal 0x11 (the original issue) + // Checksum: X(88) + 1(49) + 1(49) = 186 = 0xba + let packet = b"$X11#ba"; + let response = test_parse(packet).expect("Failed to parse X11 packet"); + + if let GdbResponse::StopReply { signal, reason, .. } = response { + assert_eq!(signal, 0x11); + assert_eq!(reason, StopReason::SignalTermination(0x11)); + } else { + panic!("Expected StopReply with SignalTermination, got: {:?}", response); + } + } + + #[test] + fn test_parse_w_packet_nonzero_exit() { + crate::init_test_logger(); + // Test W packet with non-zero exit code + // Checksum: W(87) + 0(48) + 1(49) = 184 = 0xb8 + let packet = b"$W01#b8"; + let response = test_parse(packet).expect("Failed to parse W01 packet"); + + if let GdbResponse::StopReply { signal, reason, .. } = response { + assert_eq!(signal, 0x01); + assert_eq!(reason, StopReason::ProcessExit { code: 0x01 }); + } else { + panic!("Expected StopReply with ProcessExit, got: {:?}", response); + } + } + + #[test] + fn test_parse_x_packet_different_signals() { + crate::init_test_logger(); + // Test X packet with SIGSEGV (signal 11 decimal = 0x0b) + // Checksum: X(88) + 0(48) + b(98) = 234 = 0xea + let packet = b"$X0b#ea"; + let response = test_parse(packet).expect("Failed to parse X0b packet"); + + if let GdbResponse::StopReply { signal, reason, .. } = response { + assert_eq!(signal, 0x0b); + assert_eq!(reason, StopReason::SignalTermination(0x0b)); + } else { + panic!("Expected StopReply with SignalTermination, got: {:?}", response); + } + } } diff --git a/shucks/src/wavetracker.rs b/shucks/src/wavetracker.rs index 363959e..3358bfb 100644 --- a/shucks/src/wavetracker.rs +++ b/shucks/src/wavetracker.rs @@ -1,6 +1,9 @@ use std::path::PathBuf; -use nucleo_matcher::{Config, Matcher, Utf32Str}; +use nucleo_matcher::{ + pattern::{AtomKind, CaseMatching, Normalization, Pattern}, + Config, Matcher, Utf32Str, +}; use wellen::{ simple::{read as waveread, Waveform}, Time, TimeTableIdx, Var, WellenError, @@ -8,16 +11,8 @@ use wellen::{ use dang::waveloader::WellenSignalExt; -#[derive(Clone)] -pub enum FormattingType { - Hex, - Decimal, - Binary, -} - pub struct TrackerVar { var: Var, - formatting_type: FormattingType, } pub struct WaveformTracker { @@ -53,17 +48,24 @@ impl WaveformTracker { } pub fn fuzzy_match_var(&mut self, query: &str) -> Vec<(Var, String)> { - let mut query_buf = Vec::new(); - let q = Utf32Str::new(query, &mut query_buf); + // Use the pattern API for proper normalization and matching + let pattern = Pattern::new( + query, + CaseMatching::Ignore, + Normalization::Smart, + AtomKind::Fuzzy, + ); - let mut scored: Vec<(u16, usize)> = self + let mut scored: Vec<(u32, usize)> = self .cached_vars .iter() .enumerate() .filter_map(|(idx, (_, name))| { let mut name_buf = Vec::new(); - let cand = Utf32Str::new(name, &mut name_buf); - self.matcher.fuzzy_match(cand, q).map(|score| (score, idx)) + let haystack = Utf32Str::new(name, &mut name_buf); + pattern + .score(haystack, &mut self.matcher) + .map(|score| (score, idx)) }) .collect(); @@ -83,38 +85,27 @@ impl WaveformTracker { pub fn select_signal(&mut self, var: Var) { self.waveform.load_signals(&[var.signal_ref()]); - self.selected_var_order.push(TrackerVar { - var, - formatting_type: FormattingType::Hex, - }); + self.selected_var_order.push(TrackerVar { var }); } - pub fn get_current_time_idx(&self, timetableidx: TimeTableIdx) -> Option