diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml deleted file mode 100644 index 5852c07..0000000 --- a/.github/workflows/rust.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Rust - -on: - push: - branches: [ "main", "vin" ] - pull_request: - branches: [ "main" ] - -env: - CARGO_TERM_COLOR: always - -jobs: - build: - - runs-on: windows-latest - - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - name: Download and move VPIC database - run: | - curl -L -o data/vpic.sqlite "https://www.dropbox.com/scl/fi/qt21pwczi1pyv7syh05cy/vpic.sqlite?rlkey=zk0qh8q1mn6wyrjm8njfn61r0&e=1&st=ef0qnpt8&dl=1" - - name: Build - run: cargo build - - name: Tests - run: cargo test - - name: Generate Docs - run: cargo doc --no-deps - - name: Format - run: cargo fmt - - name: Clippy - run: cargo clippy -- -D warnings diff --git a/.gitignore b/.gitignore index 0f84cc9..d16cbeb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,28 @@ -/target -/.vscode \ No newline at end of file +/backend/target/ +target/ + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/ +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/Cargo.lock b/Cargo.lock index f94ac69..35ee272 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "aho-corasick" version = "1.1.3" @@ -11,6 +26,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -26,12 +56,75 @@ dependencies = [ "libc", ] +[[package]] +name = "anyhow" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" + +[[package]] +name = "atk" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c3d816ce6f0e2909a96830d6911c2aff044370b1ef92d7f267b43bae5addedd" +dependencies = [ + "atk-sys", + "bitflags 1.3.2", + "glib", + "libc", +] + +[[package]] +name = "atk-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58aeb089fb698e06db8089971c7ee317ab9644bade33383f63631437b03aafb6" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 6.2.2", +] + [[package]] name = "autocfg" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "backtrace" +version = "0.3.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bitflags" version = "1.3.2" @@ -40,640 +133,4133 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] -name = "bumpalo" -version = "3.17.0" +name = "block" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" [[package]] -name = "cc" -version = "1.2.20" +name = "block-buffer" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04da6a0d40b948dfc4fa8f5bbf402b0fc1a64a28dbf7d12ffd683550f2c1b63a" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "shlex", + "generic-array", ] [[package]] -name = "cfg-if" -version = "1.0.0" +name = "brotli" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] [[package]] -name = "chrono" -version = "0.4.41" +name = "brotli-decompressor" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "a334ef7c9e23abf0ce748e8cd309037da93e606ad52eb372e4ce327a0dcfbdfd" dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "wasm-bindgen", - "windows-link", + "alloc-no-stdlib", + "alloc-stdlib", ] [[package]] -name = "core-foundation" -version = "0.10.0" +name = "bstr" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" dependencies = [ - "core-foundation-sys", - "libc", + "memchr", + "serde", ] [[package]] -name = "core-foundation-sys" -version = "0.8.7" +name = "bumpalo" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] -name = "equivalent" -version = "1.0.2" +name = "bytemuck" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c" [[package]] -name = "evalexpr" -version = "12.0.2" +name = "byteorder" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02a3229bec56a977f174b32fe7b8d89e8c79ebb4493d10ad763b6676dc2dc0c9" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] -name = "hashbrown" -version = "0.15.3" +name = "bytes" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] -name = "iana-time-zone" -version = "0.1.63" +name = "cairo-rs" +version = "0.15.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +checksum = "c76ee391b03d35510d9fa917357c7f1855bd9a6659c95a1b392e33f49b3369bc" dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core", + "bitflags 1.3.2", + "cairo-sys-rs", + "glib", + "libc", + "thiserror 1.0.69", ] [[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" +name = "cairo-sys-rs" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +checksum = "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8" dependencies = [ - "cc", + "glib-sys", + "libc", + "system-deps 6.2.2", ] [[package]] -name = "indexmap" -version = "2.9.0" +name = "cargo_toml" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +checksum = "599aa35200ffff8f04c1925aa1acc92fa2e08874379ef42e210a80e527e60838" dependencies = [ - "equivalent", - "hashbrown", + "serde", + "toml 0.7.8", ] [[package]] -name = "io-kit-sys" -version = "0.4.1" +name = "cc" +version = "1.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617ee6cf8e3f66f3b4ea67a4058564628cde41901316e19f559e14c7c72c5e7b" +checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766" dependencies = [ - "core-foundation-sys", - "mach2", + "shlex", ] [[package]] -name = "itoa" -version = "1.0.15" +name = "cesu8" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] -name = "js-sys" -version = "0.3.77" +name = "cfb" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" dependencies = [ - "once_cell", - "wasm-bindgen", + "byteorder", + "fnv", + "uuid", ] [[package]] -name = "libc" -version = "0.2.172" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" - -[[package]] -name = "libudev" -version = "0.3.0" +name = "cfg-expr" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b324152da65df7bb95acfcaab55e3097ceaab02fb19b228a9eb74d55f135e0" +checksum = "3431df59f28accaf4cb4eed4a9acc66bea3f3c3753aa6cdc2f024174ef232af7" dependencies = [ - "libc", - "libudev-sys", + "smallvec", ] [[package]] -name = "libudev-sys" -version = "0.1.4" +name = "cfg-expr" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" dependencies = [ - "libc", - "pkg-config", + "smallvec", + "target-lexicon", ] [[package]] -name = "log" -version = "0.4.27" +name = "cfg-if" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "mach2" -version = "0.4.2" +name = "chrono" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" dependencies = [ - "libc", + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link", ] [[package]] -name = "memchr" -version = "2.7.4" +name = "cocoa" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" +dependencies = [ + "bitflags 1.3.2", + "block", + "cocoa-foundation", + "core-foundation 0.9.4", + "core-graphics", + "foreign-types", + "libc", + "objc", +] [[package]] -name = "nix" -version = "0.26.4" +name = "cocoa-foundation" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" dependencies = [ "bitflags 1.3.2", - "cfg-if", + "block", + "core-foundation 0.9.4", + "core-graphics-types", "libc", + "objc", ] [[package]] -name = "num-traits" -version = "0.2.19" +name = "color_quant" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] -name = "num_enum" -version = "0.7.3" +name = "combine" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ - "num_enum_derive", + "bytes", + "memchr", ] [[package]] -name = "num_enum_derive" -version = "0.7.3" +name = "convert_case" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", + "core-foundation-sys", + "libc", ] [[package]] -name = "obdium" -version = "0.1.0" +name = "core-foundation" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" dependencies = [ - "chrono", - "evalexpr", - "num_enum", - "regex", - "serde", - "serde_json", - "serialport", - "sqlite", - "thiserror 2.0.12", + "core-foundation-sys", + "libc", ] [[package]] -name = "once_cell" -version = "1.21.3" +name = "core-foundation-sys" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] -name = "pkg-config" -version = "0.3.32" +name = "core-graphics" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "core-graphics-types", + "foreign-types", + "libc", +] [[package]] -name = "proc-macro-crate" -version = "3.3.0" +name = "core-graphics-types" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ - "toml_edit", + "bitflags 1.3.2", + "core-foundation 0.9.4", + "libc", ] [[package]] -name = "proc-macro2" -version = "1.0.95" +name = "cpufeatures" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ - "unicode-ident", + "libc", ] [[package]] -name = "quote" -version = "1.0.40" +name = "crc32fast" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ - "proc-macro2", + "cfg-if", ] [[package]] -name = "regex" -version = "1.11.1" +name = "crossbeam-channel" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", + "crossbeam-utils", ] [[package]] -name = "regex-automata" -version = "0.4.9" +name = "crossbeam-deque" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", + "crossbeam-epoch", + "crossbeam-utils", ] [[package]] -name = "regex-syntax" -version = "0.8.5" +name = "crossbeam-epoch" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] [[package]] -name = "rustversion" -version = "1.0.20" +name = "crossbeam-utils" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] -name = "ryu" -version = "1.0.20" +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] [[package]] -name = "scopeguard" -version = "1.2.0" +name = "cssparser" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 0.4.8", + "matches", + "phf 0.8.0", + "proc-macro2", + "quote", + "smallvec", + "syn 1.0.109", +] [[package]] -name = "serde" -version = "1.0.219" +name = "cssparser-macros" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ - "serde_derive", + "quote", + "syn 2.0.101", ] [[package]] -name = "serde_derive" -version = "1.0.219" +name = "ctor" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" +dependencies = [ + "quote", + "syn 2.0.101", +] + +[[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", - "syn", + "strsim", + "syn 2.0.101", ] [[package]] -name = "serde_json" -version = "1.0.140" +name = "darling_macro" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", + "darling_core", + "quote", + "syn 2.0.101", ] [[package]] -name = "serialport" -version = "4.7.1" +name = "deranged" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2daa7abb9b965493e3c8f4184c6f46435484ff2538a332b886788cf6768b927b" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ - "bitflags 2.9.0", - "cfg-if", - "core-foundation", - "core-foundation-sys", - "io-kit-sys", - "libudev", - "mach2", - "nix", - "scopeguard", - "unescaper", - "winapi", + "powerfmt", + "serde", ] [[package]] -name = "shlex" -version = "1.3.0" +name = "derive_more" +version = "0.99.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.101", +] [[package]] -name = "sqlite" -version = "0.37.0" +name = "digest" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f66e9c01a11936154f3910dbba732c01f8b591543bc4d6672bddee79fd9c4783" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "sqlite3-sys", + "block-buffer", + "crypto-common", ] [[package]] -name = "sqlite3-src" -version = "0.7.0" +name = "dirs-next" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5b6d3c860886b0a33e69e421796a5f4a27f23597a182c2450f6d7ace5103120" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" dependencies = [ - "cc", - "pkg-config", + "cfg-if", + "dirs-sys-next", ] [[package]] -name = "sqlite3-sys" -version = "0.18.0" +name = "dirs-sys-next" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7781d97adc13a1d5081127a9ee29afad8427f3757bd984daf814d8265267039" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ - "sqlite3-src", + "libc", + "redox_users", + "winapi", ] [[package]] -name = "syn" -version = "2.0.100" +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "displaydoc" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "unicode-ident", + "syn 2.0.101", ] [[package]] -name = "thiserror" -version = "1.0.69" +name = "dtoa" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] +checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04" [[package]] -name = "thiserror" -version = "2.0.12" +name = "dtoa-short" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" dependencies = [ - "thiserror-impl 2.0.12", + "dtoa", ] [[package]] -name = "thiserror-impl" -version = "1.0.69" +name = "dunce" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "embed-resource" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b68b6f9f63a0b6a38bc447d4ce84e2b388f3ec95c99c641c8ff0dd3ef89a6379" dependencies = [ - "proc-macro2", - "quote", - "syn", + "cc", + "memchr", + "rustc_version", + "toml 0.8.22", + "vswhom", + "winreg", ] [[package]] -name = "thiserror-impl" -version = "2.0.12" +name = "embed_plist" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ - "proc-macro2", - "quote", - "syn", + "cfg-if", ] [[package]] -name = "toml_datetime" -version = "0.6.9" +name = "equivalent" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] -name = "toml_edit" -version = "0.22.26" +name = "errno" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" +checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" dependencies = [ - "indexmap", - "toml_datetime", - "winnow", + "libc", + "windows-sys 0.59.0", ] [[package]] -name = "unescaper" -version = "0.1.5" +name = "evalexpr" +version = "12.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02a3229bec56a977f174b32fe7b8d89e8c79ebb4493d10ad763b6676dc2dc0c9" + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fdeflate" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c878a167baa8afd137494101a688ef8c67125089ff2249284bd2b5f9bfedb815" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" dependencies = [ - "thiserror 1.0.69", + "simd-adler32", ] [[package]] -name = "unicode-ident" -version = "1.0.18" +name = "field-offset" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] [[package]] -name = "wasm-bindgen" -version = "0.2.100" +name = "filetime" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", + "libc", + "libredox", + "windows-sys 0.59.0", ] [[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" +name = "flate2" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", + "crc32fast", + "miniz_oxide", ] [[package]] -name = "wasm-bindgen-macro" -version = "0.2.100" +name = "fluent-uri" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "17c704e9dbe1ddd863da1e6ff3567795087b1eb201ce80d8fa81162e1516500d" dependencies = [ - "quote", - "wasm-bindgen-macro-support", + "bitflags 1.3.2", ] [[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.100" +name = "fnv" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", + "foreign-types-shared", ] [[package]] -name = "wasm-bindgen-shared" -version = "0.2.100" +name = "foreign-types-shared" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ - "unicode-ident", + "percent-encoding", ] [[package]] -name = "winapi" -version = "0.3.9" +name = "futf" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "mac", + "new_debug_unreachable", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "futures-channel" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", +] [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "futures-core" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] -name = "windows-core" -version = "0.61.0" +name = "futures-executor" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ - "windows-implement", - "windows-interface", - "windows-link", - "windows-result", - "windows-strings", + "futures-core", + "futures-task", + "futures-util", ] [[package]] -name = "windows-implement" -version = "0.60.0" +name = "futures-io" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[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", + "syn 2.0.101", ] [[package]] -name = "windows-interface" -version = "0.59.1" +name = "futures-task" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ - "proc-macro2", - "quote", - "syn", + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", ] [[package]] -name = "windows-link" -version = "0.1.1" +name = "fxhash" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] [[package]] -name = "windows-result" -version = "0.3.2" +name = "gdk" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +checksum = "a6e05c1f572ab0e1f15be94217f0dc29088c248b14f792a5ff0af0d84bcda9e8" dependencies = [ - "windows-link", + "bitflags 1.3.2", + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", + "libc", + "pango", ] [[package]] -name = "windows-strings" -version = "0.4.0" +name = "gdk-pixbuf" +version = "0.15.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +checksum = "ad38dd9cc8b099cceecdf41375bb6d481b1b5a7cd5cd603e10a69a9383f8619a" dependencies = [ - "windows-link", + "bitflags 1.3.2", + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", ] [[package]] -name = "winnow" -version = "0.7.10" +name = "gdk-pixbuf-sys" +version = "0.15.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" +checksum = "140b2f5378256527150350a8346dbdb08fadc13453a7a2d73aecd5fab3c402a7" dependencies = [ - "memchr", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "gdk-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e7a08c1e8f06f4177fb7e51a777b8c1689f743a7bc11ea91d44d2226073a88" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps 6.2.2", +] + +[[package]] +name = "gdkwayland-sys" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cca49a59ad8cfdf36ef7330fe7bdfbe1d34323220cc16a0de2679ee773aee2c2" +dependencies = [ + "gdk-sys", + "glib-sys", + "gobject-sys", + "libc", + "pkg-config", + "system-deps 6.2.2", +] + +[[package]] +name = "gdkx11-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b7f8c7a84b407aa9b143877e267e848ff34106578b64d1e0a24bf550716178" +dependencies = [ + "gdk-sys", + "glib-sys", + "libc", + "system-deps 6.2.2", + "x11", +] + +[[package]] +name = "generator" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "windows 0.48.0", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[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.0+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" + +[[package]] +name = "gio" +version = "0.15.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68fdbc90312d462781a395f7a16d96a2b379bb6ef8cd6310a2df272771c4283b" +dependencies = [ + "bitflags 1.3.2", + "futures-channel", + "futures-core", + "futures-io", + "gio-sys", + "glib", + "libc", + "once_cell", + "thiserror 1.0.69", +] + +[[package]] +name = "gio-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32157a475271e2c4a023382e9cab31c4584ee30a97da41d3c4e9fdd605abcf8d" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 6.2.2", + "winapi", +] + +[[package]] +name = "glib" +version = "0.15.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edb0306fbad0ab5428b0ca674a23893db909a98582969c9b537be4ced78c505d" +dependencies = [ + "bitflags 1.3.2", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "once_cell", + "smallvec", + "thiserror 1.0.69", +] + +[[package]] +name = "glib-macros" +version = "0.15.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10c6ae9f6fa26f4fb2ac16b528d138d971ead56141de489f8111e259b9df3c4a" +dependencies = [ + "anyhow", + "heck 0.4.1", + "proc-macro-crate 1.3.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "glib-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef4b192f8e65e9cf76cbf4ea71fa8e3be4a0e18ffe3d68b8da6836974cc5bad4" +dependencies = [ + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + +[[package]] +name = "globset" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "gobject-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d57ce44246becd17153bd035ab4d32cfee096a657fc01f2231c9278378d1e0a" +dependencies = [ + "glib-sys", + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "gtk" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e3004a2d5d6d8b5057d2b57b3712c9529b62e82c77f25c1fecde1fd5c23bd0" +dependencies = [ + "atk", + "bitflags 1.3.2", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio", + "glib", + "gtk-sys", + "gtk3-macros", + "libc", + "once_cell", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5bc2f0587cba247f60246a0ca11fe25fb733eabc3de12d1965fc07efab87c84" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "system-deps 6.2.2", +] + +[[package]] +name = "gtk3-macros" +version = "0.15.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "684c0456c086e8e7e9af73ec5b84e35938df394712054550e81558d21c44ab0d" +dependencies = [ + "anyhow", + "proc-macro-crate 1.3.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[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 = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "html5ever" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa 1.0.15", +] + +[[package]] +name = "http-range" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" + +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ico" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc50b891e4acf8fe0e71ef88ec43ad82ee07b3810ad09de10f1d01f072ed4b98" +dependencies = [ + "byteorder", + "png", +] + +[[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.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "ignore" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata 0.4.9", + "same-file", + "walkdir", + "winapi-util", +] + +[[package]] +name = "image" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "num-traits", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +dependencies = [ + "equivalent", + "hashbrown 0.15.3", + "serde", +] + +[[package]] +name = "infer" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f551f8c3a39f68f986517db0d1759de85881894fdc7db798bd2a9df9cb04b7fc" +dependencies = [ + "cfb", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-kit-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617ee6cf8e3f66f3b4ea67a4058564628cde41901316e19f559e14c7c72c5e7b" +dependencies = [ + "core-foundation-sys", + "mach2", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "javascriptcore-rs" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf053e7843f2812ff03ef5afe34bb9c06ffee120385caad4f6b9967fcd37d41c" +dependencies = [ + "bitflags 1.3.2", + "glib", + "javascriptcore-rs-sys", +] + +[[package]] +name = "javascriptcore-rs-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "905fbb87419c5cde6e3269537e4ea7d46431f3008c5d057e915ef3f115e7793c" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 5.0.0", +] + +[[package]] +name = "jni" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "039022cdf4d7b1cf548d31f60ae783138e5fd42013f6271049d7df7afadef96c" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror 1.0.69", + "walkdir", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[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 = "json-patch" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b1fb8864823fad91877e6caea0baca82e49e8db50f8e5c9f9a453e27d3330fc" +dependencies = [ + "jsonptr", + "serde", + "serde_json", + "thiserror 1.0.69", +] + +[[package]] +name = "jsonptr" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c6e529149475ca0b2820835d3dce8fcc41c6b943ca608d32f35b449255e4627" +dependencies = [ + "fluent-uri", + "serde", + "serde_json", +] + +[[package]] +name = "kuchikiki" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e4755b7b995046f510a7520c42b2fed58b77bd94d5a87a8eb43d2fd126da8" +dependencies = [ + "cssparser", + "html5ever", + "indexmap 1.9.3", + "matches", + "selectors", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.172" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.9.1", + "libc", + "redox_syscall", +] + +[[package]] +name = "libudev" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b324152da65df7bb95acfcaab55e3097ceaab02fb19b228a9eb74d55f135e0" +dependencies = [ + "libc", + "libudev-sys", +] + +[[package]] +name = "libudev-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324" +dependencies = [ + "libc", + "pkg-config", +] + +[[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 = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "loom" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "mach2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +dependencies = [ + "libc", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "markup5ever" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" +dependencies = [ + "log", + "phf 0.10.1", + "phf_codegen 0.10.0", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "ndk" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2032c77e030ddee34a6787a64166008da93f6a352b629261d0fee232b8742dd4" +dependencies = [ + "bitflags 1.3.2", + "jni-sys", + "ndk-sys", + "num_enum 0.5.11", + "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.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5a6ae77c8ee183dcbbba6150e2e6b9f3f4196a7666c02a715a95692ec1fa97" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", +] + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive 0.5.11", +] + +[[package]] +name = "num_enum" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +dependencies = [ + "num_enum_derive 0.7.3", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +dependencies = [ + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "obdium" +version = "0.1.0" +dependencies = [ + "chrono", + "evalexpr", + "num_enum 0.7.3", + "regex", + "serde", + "serde_json", + "serialport", + "sqlite", + "tauri", + "tauri-build", + "thiserror 2.0.12", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "open" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2078c0039e6a54a0c42c28faa984e115fb4c2d5bf2208f77d1961002df8576f8" +dependencies = [ + "pathdiff", + "windows-sys 0.42.0", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "pango" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e4045548659aee5313bde6c582b0d83a627b7904dd20dc2d9ef0895d414e4f" +dependencies = [ + "bitflags 1.3.2", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2a00081cde4661982ed91d80ef437c20eacaf6aa1a5962c0279ae194662c3aa" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_macros 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_shared 0.10.0", +] + +[[package]] +name = "phf" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_macros 0.11.3", + "phf_shared 0.11.3", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", +] + +[[package]] +name = "phf_codegen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.5", +] + +[[package]] +name = "phf_generator" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +dependencies = [ + "phf_shared 0.11.3", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "phf_macros" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher 0.3.11", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher 0.3.11", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher 1.0.1", +] + +[[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 = "plist" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac26e981c03a6e53e0aee43c113e3202f5581d5360dae7bd2c70e800dd0451d" +dependencies = [ + "base64 0.22.1", + "indexmap 2.9.0", + "quick-xml", + "serde", + "time", +] + +[[package]] +name = "png" +version = "0.17.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +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 = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +dependencies = [ + "toml_edit 0.22.26", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[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 = "quick-xml" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2" +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.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "raw-window-handle" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" + +[[package]] +name = "redox_syscall" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" +dependencies = [ + "bitflags 2.9.1", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom 0.2.16", + "libredox", + "thiserror 1.0.69", +] + +[[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 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[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 0.8.5", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +dependencies = [ + "bitflags 2.9.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustversion" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "selectors" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" +dependencies = [ + "bitflags 1.3.2", + "cssparser", + "derive_more", + "fxhash", + "log", + "matches", + "phf 0.8.0", + "phf_codegen 0.8.0", + "precomputed-hash", + "servo_arc", + "smallvec", + "thin-slice", +] + +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +dependencies = [ + "serde", +] + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "serde_json" +version = "1.0.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +dependencies = [ + "indexmap 2.9.0", + "itoa 1.0.15", + "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 2.0.101", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_with" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.9.0", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "serialize-to-javascript" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04f3666a07a197cdb77cdf306c32be9b7f598d7060d50cfd4d5aa04bfd92f6c5" +dependencies = [ + "serde", + "serde_json", + "serialize-to-javascript-impl", +] + +[[package]] +name = "serialize-to-javascript-impl" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "772ee033c0916d670af7860b6e1ef7d658a4629a6d0b4c8c3e67f09b3765b75d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "serialport" +version = "4.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb0bc984f6af6ef8bab54e6cf2071579ee75b9286aa9f2319a0d220c28b0a2b" +dependencies = [ + "bitflags 2.9.1", + "cfg-if", + "core-foundation 0.10.0", + "core-foundation-sys", + "io-kit-sys", + "libudev", + "mach2", + "nix", + "scopeguard", + "unescaper", + "winapi", +] + +[[package]] +name = "servo_arc" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" + +[[package]] +name = "soup2" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b4d76501d8ba387cf0fefbe055c3e0a59891d09f0f995ae4e4b16f6b60f3c0" +dependencies = [ + "bitflags 1.3.2", + "gio", + "glib", + "libc", + "once_cell", + "soup2-sys", +] + +[[package]] +name = "soup2-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "009ef427103fcb17f802871647a7fa6c60cbb654b4c4e4c0ac60a31c5f6dc9cf" +dependencies = [ + "bitflags 1.3.2", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps 5.0.0", +] + +[[package]] +name = "sqlite" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f66e9c01a11936154f3910dbba732c01f8b591543bc4d6672bddee79fd9c4783" +dependencies = [ + "sqlite3-sys", +] + +[[package]] +name = "sqlite3-src" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5b6d3c860886b0a33e69e421796a5f4a27f23597a182c2450f6d7ace5103120" +dependencies = [ + "cc", + "pkg-config", +] + +[[package]] +name = "sqlite3-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7781d97adc13a1d5081127a9ee29afad8427f3757bd984daf814d8265267039" +dependencies = [ + "sqlite3-src", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "state" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbe866e1e51e8260c9eed836a042a5e7f6726bb2b411dffeaa712e19c388f23b" +dependencies = [ + "loom", +] + +[[package]] +name = "string_cache" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared 0.11.3", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", + "proc-macro2", + "quote", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "system-deps" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18db855554db7bd0e73e06cf7ba3df39f97812cb11d3f75e71c39bf45171797e" +dependencies = [ + "cfg-expr 0.9.1", + "heck 0.3.3", + "pkg-config", + "toml 0.5.11", + "version-compare 0.0.11", +] + +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr 0.15.8", + "heck 0.5.0", + "pkg-config", + "toml 0.8.22", + "version-compare 0.2.0", +] + +[[package]] +name = "tao" +version = "0.16.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d298c441a1da46e28e8ad8ec205aab7fd8cd71b9d10e05454224eef422e1ae" +dependencies = [ + "bitflags 1.3.2", + "cairo-rs", + "cc", + "cocoa", + "core-foundation 0.9.4", + "core-graphics", + "crossbeam-channel", + "dispatch", + "gdk", + "gdk-pixbuf", + "gdk-sys", + "gdkwayland-sys", + "gdkx11-sys", + "gio", + "glib", + "glib-sys", + "gtk", + "image", + "instant", + "jni", + "lazy_static", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "objc", + "once_cell", + "parking_lot", + "png", + "raw-window-handle", + "scopeguard", + "serde", + "tao-macros", + "unicode-segmentation", + "uuid", + "windows 0.39.0", + "windows-implement 0.39.0", + "x11-dl", +] + +[[package]] +name = "tao-macros" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "tar" +version = "0.4.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + +[[package]] +name = "tauri" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae1f57c291a6ab8e1d2e6b8ad0a35ff769c9925deb8a89de85425ff08762d0c" +dependencies = [ + "anyhow", + "cocoa", + "dirs-next", + "dunce", + "embed_plist", + "encoding_rs", + "flate2", + "futures-util", + "getrandom 0.2.16", + "glib", + "glob", + "gtk", + "heck 0.5.0", + "http", + "ignore", + "log", + "objc", + "once_cell", + "open", + "percent-encoding", + "plist", + "rand 0.8.5", + "raw-window-handle", + "regex", + "semver", + "serde", + "serde_json", + "serde_repr", + "serialize-to-javascript", + "state", + "tar", + "tauri-macros", + "tauri-runtime", + "tauri-runtime-wry", + "tauri-utils", + "tempfile", + "thiserror 1.0.69", + "tokio", + "url", + "uuid", + "webkit2gtk", + "webview2-com", + "windows 0.39.0", +] + +[[package]] +name = "tauri-build" +version = "1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2db08694eec06f53625cfc6fff3a363e084e5e9a238166d2989996413c346453" +dependencies = [ + "anyhow", + "cargo_toml", + "dirs-next", + "heck 0.5.0", + "json-patch", + "semver", + "serde", + "serde_json", + "tauri-utils", + "tauri-winres", + "walkdir", +] + +[[package]] +name = "tauri-codegen" +version = "1.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53438d78c4a037ffe5eafa19e447eea599bedfb10844cb08ec53c2471ac3ac3f" +dependencies = [ + "base64 0.21.7", + "brotli", + "ico", + "json-patch", + "plist", + "png", + "proc-macro2", + "quote", + "regex", + "semver", + "serde", + "serde_json", + "sha2", + "tauri-utils", + "thiserror 1.0.69", + "time", + "uuid", + "walkdir", +] + +[[package]] +name = "tauri-macros" +version = "1.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233988ac08c1ed3fe794cd65528d48d8f7ed4ab3895ca64cdaa6ad4d00c45c0b" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 1.0.109", + "tauri-codegen", + "tauri-utils", +] + +[[package]] +name = "tauri-runtime" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8066855882f00172935e3fa7d945126580c34dcbabab43f5d4f0c2398a67d47b" +dependencies = [ + "gtk", + "http", + "http-range", + "rand 0.8.5", + "raw-window-handle", + "serde", + "serde_json", + "tauri-utils", + "thiserror 1.0.69", + "url", + "uuid", + "webview2-com", + "windows 0.39.0", +] + +[[package]] +name = "tauri-runtime-wry" +version = "0.14.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce361fec1e186705371f1c64ae9dd2a3a6768bc530d0a2d5e75a634bb416ad4d" +dependencies = [ + "cocoa", + "gtk", + "percent-encoding", + "rand 0.8.5", + "raw-window-handle", + "tauri-runtime", + "tauri-utils", + "uuid", + "webkit2gtk", + "webview2-com", + "windows 0.39.0", + "wry", +] + +[[package]] +name = "tauri-utils" +version = "1.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c357952645e679de02cd35007190fcbce869b93ffc61b029f33fe02648453774" +dependencies = [ + "brotli", + "ctor", + "dunce", + "glob", + "heck 0.5.0", + "html5ever", + "infer", + "json-patch", + "kuchikiki", + "log", + "memchr", + "phf 0.11.3", + "proc-macro2", + "quote", + "semver", + "serde", + "serde_json", + "serde_with", + "thiserror 1.0.69", + "url", + "walkdir", + "windows-version", +] + +[[package]] +name = "tauri-winres" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5993dc129e544393574288923d1ec447c857f3f644187f4fbf7d9a875fbfc4fb" +dependencies = [ + "embed-resource", + "toml 0.7.8", +] + +[[package]] +name = "tempfile" +version = "3.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +dependencies = [ + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "tendril" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" +dependencies = [ + "futf", + "mac", + "utf-8", +] + +[[package]] +name = "thin-slice" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +dependencies = [ + "deranged", + "itoa 1.0.15", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" + +[[package]] +name = "time-macros" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165" +dependencies = [ + "backtrace", + "bytes", + "pin-project-lite", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.19.15", +] + +[[package]] +name = "toml" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.22.26", +] + +[[package]] +name = "toml_datetime" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.9.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" +dependencies = [ + "indexmap 2.9.0", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow 0.7.10", +] + +[[package]] +name = "toml_write" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "unescaper" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c01d12e3a56a4432a8b436f293c25f4808bdf9e9f9f98f9260bba1f1bc5a1f26" +dependencies = [ + "thiserror 2.0.12", +] + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "uuid" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" +dependencies = [ + "getrandom 0.3.3", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "version-compare" +version = "0.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b" + +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "vswhom" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b" +dependencies = [ + "libc", + "vswhom-sys", +] + +[[package]] +name = "vswhom-sys" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb067e4cbd1ff067d1df46c9194b5de0e98efd2810bbc95c5d5e5f25a3231150" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.101", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "webkit2gtk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8f859735e4a452aeb28c6c56a852967a8a76c8eb1cc32dbf931ad28a13d6370" +dependencies = [ + "bitflags 1.3.2", + "cairo-rs", + "gdk", + "gdk-sys", + "gio", + "gio-sys", + "glib", + "glib-sys", + "gobject-sys", + "gtk", + "gtk-sys", + "javascriptcore-rs", + "libc", + "once_cell", + "soup2", + "webkit2gtk-sys", +] + +[[package]] +name = "webkit2gtk-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d76ca6ecc47aeba01ec61e480139dda143796abcae6f83bcddf50d6b5b1dcf3" +dependencies = [ + "atk-sys", + "bitflags 1.3.2", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk-sys", + "javascriptcore-rs-sys", + "libc", + "pango-sys", + "pkg-config", + "soup2-sys", + "system-deps 6.2.2", +] + +[[package]] +name = "webview2-com" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4a769c9f1a64a8734bde70caafac2b96cada12cd4aefa49196b3a386b8b4178" +dependencies = [ + "webview2-com-macros", + "webview2-com-sys", + "windows 0.39.0", + "windows-implement 0.39.0", +] + +[[package]] +name = "webview2-com-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaebe196c01691db62e9e4ca52c5ef1e4fd837dcae27dae3ada599b5a8fd05ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "webview2-com-sys" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aac48ef20ddf657755fdcda8dfed2a7b4fc7e4581acce6fe9b88c3d64f29dee7" +dependencies = [ + "regex", + "serde", + "serde_json", + "thiserror 1.0.69", + "windows 0.39.0", + "windows-bindgen", + "windows-metadata", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1c4bd0a50ac6020f65184721f758dba47bb9fbc2133df715ec74a237b26794a" +dependencies = [ + "windows-implement 0.39.0", + "windows_aarch64_msvc 0.39.0", + "windows_i686_gnu 0.39.0", + "windows_i686_msvc 0.39.0", + "windows_x86_64_gnu 0.39.0", + "windows_x86_64_msvc 0.39.0", +] + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-bindgen" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68003dbd0e38abc0fb85b939240f4bce37c43a5981d3df37ccbaaa981b47cb41" +dependencies = [ + "windows-metadata", + "windows-tokens", +] + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement 0.60.0", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba01f98f509cb5dc05f4e5fc95e535f78260f15fea8fe1a8abdd08f774f1cee7" +dependencies = [ + "syn 1.0.109", + "windows-tokens", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "windows-link" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" + +[[package]] +name = "windows-metadata" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ee5e275231f07c6e240d14f34e1b635bf1faa1c76c57cfd59a5cdb9848e4278" + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +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-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-tokens" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f838de2fe15fe6bac988e74b798f26499a8b21a9d97edec321e79b28d1d7f597" + +[[package]] +name = "windows-version" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e04a5c6627e310a23ad2358483286c7df260c964eb2d003d8efd6d0f4e79265c" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec7711666096bd4096ffa835238905bb33fb87267910e154b18b44eaabb340f2" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "763fc57100a5f7042e3057e7e8d9bdd7860d330070251a73d003563a3bb49e1b" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bc7cbfe58828921e10a9f446fcaaf649204dcfe6c1ddd712c5eebae6bda1106" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6868c165637d653ae1e8dc4d82c25d4f97dd6605eaa8d784b5c6e0ab2a252b65" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e4d40883ae9cae962787ca76ba76390ffa29214667a111db9e0a1ad8377e809" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "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 = "wry" +version = "0.24.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c55c80b12287eb1ff7c365fc2f7a5037cb6181bd44c9fce81c8d1cf7605ffad6" +dependencies = [ + "base64 0.13.1", + "block", + "cocoa", + "core-graphics", + "crossbeam-channel", + "dunce", + "gdk", + "gio", + "glib", + "gtk", + "html5ever", + "http", + "kuchikiki", + "libc", + "log", + "objc", + "objc_id", + "once_cell", + "serde", + "serde_json", + "sha2", + "soup2", + "tao", + "thiserror 1.0.69", + "url", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows 0.39.0", + "windows-implement 0.39.0", +] + +[[package]] +name = "x11" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" +dependencies = [ + "libc", + "pkg-config", +] + +[[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 = "xattr" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d65cbf2f12c15564212d48f4e3dfb87923d25d611f2aed18f4cb23f0413d89e" +dependencies = [ + "libc", + "rustix", +] + +[[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 2.0.101", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[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 2.0.101", + "synstructure", +] + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" +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 2.0.101", ] diff --git a/README.md b/README.md index 19869f5..2d9d925 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@
-

OBDium

+

OBDium - GUI Branch

A Rust-based vehicle diagnostics tool designed to connect with ELM327 adapters, offering live OBD-II data, fault code analysis, and offline VIN decoding.

tests @@ -9,31 +9,31 @@ repo-language-count
-![Banner](/docs/banner.jpg) +![AppImage](/docs/app_image.png) ## Table of Contents - [Overview](#overview) - [Implementation](#implementation-and-logic) - [Features](#features) -- [Usage](#example-usage) +- [Usage](#usage) - [License](#license) +- [Contributing](#contributing) - [Project Structure](#project-structure) - [Roadmap](#roadmap) ## Overview -**OBDium** ( pronounced Oh-Bid-ium ), is a fast, extensible Rust-based diagnostic tool for interfacing with OBD-II systems via ELM327 serial adapters. It provides live access to vehicle sensor data, in-depth diagnostics, and accurate VIN decoding without relying on external crates for critical parsing logic. +**OBDium** ( pronounced Oh-Bid-ium ), is a fast, modern and extensible Rust-based diagnostic tool for interfacing with OBD-II systems via ELM327 serial adapters fully offline. It provides live access to vehicle sensor data, in-depth diagnostics, and accurate VIN decoding without relying on external crates for critical parsing logic. Our goal with OBDium is to fill a gap in the ecosystem, providing the best free, open-source, and easy-to-use vehicle diagnostics tool. ## Features - -- **🔌 Serial Communication:** Connects to ELM327 OBD-II adapters via serial port +- **⚠️ View Troube Codes:** Read diagnostic trouble codes, including **Powertrain, Body, Chassis,** and **Network** alongside a description - **🧠 Live Vehicle Metrics:** Reads and decodes various OBD-II PIDs (engine, fuel, air, exhaust, diagnostics, etc.) with plans for manufacturer specific PIDs soon - **🔎 Advanced VIN Decoding:** In-depth VIN decoding using a custom parser and SQLite-backed lookups based off of the NHTSA's VPIC MSSQL database -- **💾 SQLite-Backed Caching & Queries:** Persistent VIN metadata and decoded lookup results are stored locally for fast and offline operation -- **🧪 Unit Tests:** Comprehensive unit tests for VIN decoding and database access ([`tests/vin.rs`](tests/vin.rs)) -- **⚙️ Error Handling and Resilience:** Gracefully handles common ELM327 quirks and serial errors with clear messages and fallbacks +- **🔌 Serial Communication:** Connects to ELM327 OBD-II adapters via serial port +- **📱 Modern GUI:** No more ugly and outdated native applications. Developed with modern web development technologies using Tauri with JS/HTML/CSS +- **🖥️ Cross-platform:** Available on any operating system include both Linux and Windows ## Implementation and Logic This project required extensive research into concepts like ELM327, the OBD-II protocol, and response decoding. Below is a brief explanation of the implementation and logic behind OBDium. @@ -46,75 +46,60 @@ This project required extensive research into concepts like ELM327, the OBD-II p For any questions about the implementation or logic behind OBDium, feel free to create a Discussion or open an Issue! -## Try it yourself! - -Since commit 9a22b44, it is now possible to use previously recorded results for responses to simulate a vehicle responding to commands. **This means you don't even need an EML327 adapter for testing.** - -1. To get started, follow the [installation](#installation) steps. - -2. In [`src/main.rs`](src/main.rs), ensure the line `obd.record_requests(state)` is commented out or set to false, and `obd.replay_requests(state)` is uncommented or set to true (soon to be made more convienant in later version). - -Now, OBDium will use all the responses located in the [`data/requests.json`](data/requests.json) file. - -## Example Usage - -To try it with an ELM327 adapter paired with a real car: - -1. Connect your ELM327 adapter to your computer and note the serial port (e.g., `COM4` on Windows or `/dev/ttyUSB0` on Linux). - -```sh -cargo run --release -``` - -Sample output: -``` -Model year: 2018 -WMI: "KL4" -WMI ID: 2069 -Key: "CJASB|JB660929" - -======================== VEHICLE MODEL INFO ======================== -Manufacturer Country: ... -Manufacturer Name: ... -Manufacturer Region: ... -... +## Installation -======================== DIAGNOSTICS ======================== -Supported pids for ECUs -ECU 7E8: - 01 03 04 05 06 07 0A 0B 0C 0D ... -Check engine light: false -Number of trouble codes: 0 -OBD standard: JOBD and OBD-II -Auxiliary input status: Inactive -... -``` +### Installer +1. Head to the GitHub releases page [here](https://github.com/provrb/obdium/releases) +2. Download the latest release for your operating system +3. Extract and run the installer. -## Installation +### Command-Line 1. **Install Rust** Download and install from [rust-lang.org](https://www.rust-lang.org/tools/install). +2. **Install Tauri** + ```sh + cargo install tauri-cli --version 1.6.5 + ``` + 2. **Clone the repository** ```sh git clone https://github.com/provrb/obdium.git cd obdium ``` - Ensure you correctly install the vpic.sqlite file from `/data/`. - 3. **Build the project** ```sh - cargo build --release + cargo tauri build ``` -4. **(Optional) Run tests** - ```sh - cargo test - ``` +4. **Find the application**: + - The file built will be located in: `backend/target/release` + - MSI and NSIS installers will be located in: `backend/target/release/bundle` 5. **Prepare SQLite databases** - Ensure the required SQLite databases are present in the `data/` directory (see [`src/vin/parser.rs`](src/vin/parser.rs) for expected paths). This will change to be more convenient in the future. + Ensure the required SQLite databases are present in the `data/` directory (see [`src/vin/parser.rs`](backend/src/vin/mod.rs), [`src/lib.rs`](backend/src/lib.rs) for expected paths). This will change to be more convenient in the future. + +## Usage + +### Connecting +1. Run the application +2. Connect your ELM327 adapter to your vehicles OBD-II port and device. +3. Navigate to the **Connection** panel: + - Select the OBD-II protocol, serial port, and baud rate to use. + - If not serial ports appear, you can click the refresh button to reload serial ports. +4. Click 'Connect' + +### Features +- OBD data will be recorded in the **OBD Dashboard** +- View diagnostic trouble codes in the **DTC** panel. +- View graphs for live data in the **Graphs** panel. +- Decode a VIN to receive model-specific information in the **VIN Decoding** panel. +- To stop tracking a metric, click on the card it's being displayed in, in the **OBD Dashboard** + - Resume tracking by clicking on it again at the very bottom of the dashboard. +- Modify preferences like units, privacy, or startup settings in the **Settings** panel. +- View an index of all PIDs in the **PID List** panel. ## Contributing @@ -128,24 +113,23 @@ To contribute: ## Project Structure -- [`src/main.rs`](src/main.rs): Entry point and CLI logic -- [`src/obd.rs`](src/obd.rs): OBD-II communication and protocol handling -- [`src/pid/`](src/pid/mod.rs): PID modules for various OBD-II data groups -- [`src/vin/`](src/vin/mod.rs): VIN decoding and database integration -- [`tests/vin.rs`](tests/vin.rs): Unit tests for VIN decoding and database access +### Backend +- [`backend/`](/backend/): Backend logic include calculations and core functionality of the app +- [`backend/src/vin/`](/backend/src/vin/mod.rs): VIN decoding and database integration +- [`backend/src/obd.rs`](/backend/src/obd.rs): Main OBD interface +- [`backend/src/bridge`](/backend/src/bridge/): Backend interface for the frontend + +### Frontend +- [`frontend/`](/frontend/): Main GUI logic + ## License This code has minimal restrictions, such that any distributions are made free-of-cost. See [`LICENSE`](LICENSE) for details. ## Roadmap -1. Finish VIN parsing functionality. +1. ~~Finish VIN parsing functionality.~~ 2. Fully functional user-interface with live graph view and the ability to send requests manually to the vehicle. -3. DOCUMENT THE CRATE!!!! - ---- +3. Support for Bluetooth and Wi-fi ELM connection -**Note:** -- Ensure your user account has permission to access the serial port. -- The tool expects the SQLite databases to be present in the `data/` directory. -- For more details on extending PID or VIN decoding, see the module files in [`src/pid/`](src/pid/mod.rs) and [`src/vin/`](src/vin/mod.rs). \ No newline at end of file +--- \ No newline at end of file diff --git a/backend/Cargo.lock b/backend/Cargo.lock new file mode 100644 index 0000000..c59a87e --- /dev/null +++ b/backend/Cargo.lock @@ -0,0 +1,4266 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" + +[[package]] +name = "atk" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c3d816ce6f0e2909a96830d6911c2aff044370b1ef92d7f267b43bae5addedd" +dependencies = [ + "atk-sys", + "bitflags 1.3.2", + "glib", + "libc", +] + +[[package]] +name = "atk-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58aeb089fb698e06db8089971c7ee317ab9644bade33383f63631437b03aafb6" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "backtrace" +version = "0.3.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "brotli" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a334ef7c9e23abf0ce748e8cd309037da93e606ad52eb372e4ce327a0dcfbdfd" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bstr" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" + +[[package]] +name = "bytemuck" +version = "1.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "cairo-rs" +version = "0.15.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c76ee391b03d35510d9fa917357c7f1855bd9a6659c95a1b392e33f49b3369bc" +dependencies = [ + "bitflags 1.3.2", + "cairo-sys-rs", + "glib", + "libc", + "thiserror 1.0.69", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8" +dependencies = [ + "glib-sys", + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "cargo_toml" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "599aa35200ffff8f04c1925aa1acc92fa2e08874379ef42e210a80e527e60838" +dependencies = [ + "serde", + "toml 0.7.8", +] + +[[package]] +name = "cc" +version = "1.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766" +dependencies = [ + "shlex", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfb" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" +dependencies = [ + "byteorder", + "fnv", + "uuid", +] + +[[package]] +name = "cfg-expr" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3431df59f28accaf4cb4eed4a9acc66bea3f3c3753aa6cdc2f024174ef232af7" +dependencies = [ + "smallvec", +] + +[[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "cocoa" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" +dependencies = [ + "bitflags 1.3.2", + "block", + "cocoa-foundation", + "core-foundation 0.9.4", + "core-graphics", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" +dependencies = [ + "bitflags 1.3.2", + "block", + "core-foundation 0.9.4", + "core-graphics-types", + "libc", + "objc", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core-graphics" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + +[[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 = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cssparser" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 0.4.8", + "matches", + "phf 0.8.0", + "proc-macro2", + "quote", + "smallvec", + "syn 1.0.109", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +dependencies = [ + "quote", + "syn 2.0.101", +] + +[[package]] +name = "ctor" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" +dependencies = [ + "quote", + "syn 2.0.101", +] + +[[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 2.0.101", +] + +[[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 2.0.101", +] + +[[package]] +name = "deranged" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "derive_more" +version = "0.99.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.101", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "dtoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04" + +[[package]] +name = "dtoa-short" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" +dependencies = [ + "dtoa", +] + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "embed-resource" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b68b6f9f63a0b6a38bc447d4ce84e2b388f3ec95c99c641c8ff0dd3ef89a6379" +dependencies = [ + "cc", + "memchr", + "rustc_version", + "toml 0.8.22", + "vswhom", + "winreg", +] + +[[package]] +name = "embed_plist" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" + +[[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 = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "evalexpr" +version = "12.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02a3229bec56a977f174b32fe7b8d89e8c79ebb4493d10ad763b6676dc2dc0c9" + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "filetime" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" +dependencies = [ + "cfg-if", + "libc", + "libredox", + "windows-sys 0.59.0", +] + +[[package]] +name = "flate2" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fluent-uri" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17c704e9dbe1ddd863da1e6ff3567795087b1eb201ce80d8fa81162e1516500d" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" +dependencies = [ + "mac", + "new_debug_unreachable", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-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-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "gdk" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6e05c1f572ab0e1f15be94217f0dc29088c248b14f792a5ff0af0d84bcda9e8" +dependencies = [ + "bitflags 1.3.2", + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad38dd9cc8b099cceecdf41375bb6d481b1b5a7cd5cd603e10a69a9383f8619a" +dependencies = [ + "bitflags 1.3.2", + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "140b2f5378256527150350a8346dbdb08fadc13453a7a2d73aecd5fab3c402a7" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "gdk-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e7a08c1e8f06f4177fb7e51a777b8c1689f743a7bc11ea91d44d2226073a88" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps 6.2.2", +] + +[[package]] +name = "gdkwayland-sys" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cca49a59ad8cfdf36ef7330fe7bdfbe1d34323220cc16a0de2679ee773aee2c2" +dependencies = [ + "gdk-sys", + "glib-sys", + "gobject-sys", + "libc", + "pkg-config", + "system-deps 6.2.2", +] + +[[package]] +name = "gdkx11-sys" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b7f8c7a84b407aa9b143877e267e848ff34106578b64d1e0a24bf550716178" +dependencies = [ + "gdk-sys", + "glib-sys", + "libc", + "system-deps 6.2.2", + "x11", +] + +[[package]] +name = "generator" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "windows 0.48.0", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[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.0+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" + +[[package]] +name = "gio" +version = "0.15.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68fdbc90312d462781a395f7a16d96a2b379bb6ef8cd6310a2df272771c4283b" +dependencies = [ + "bitflags 1.3.2", + "futures-channel", + "futures-core", + "futures-io", + "gio-sys", + "glib", + "libc", + "once_cell", + "thiserror 1.0.69", +] + +[[package]] +name = "gio-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32157a475271e2c4a023382e9cab31c4584ee30a97da41d3c4e9fdd605abcf8d" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 6.2.2", + "winapi", +] + +[[package]] +name = "glib" +version = "0.15.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edb0306fbad0ab5428b0ca674a23893db909a98582969c9b537be4ced78c505d" +dependencies = [ + "bitflags 1.3.2", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "once_cell", + "smallvec", + "thiserror 1.0.69", +] + +[[package]] +name = "glib-macros" +version = "0.15.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10c6ae9f6fa26f4fb2ac16b528d138d971ead56141de489f8111e259b9df3c4a" +dependencies = [ + "anyhow", + "heck 0.4.1", + "proc-macro-crate 1.3.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "glib-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef4b192f8e65e9cf76cbf4ea71fa8e3be4a0e18ffe3d68b8da6836974cc5bad4" +dependencies = [ + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + +[[package]] +name = "globset" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "gobject-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d57ce44246becd17153bd035ab4d32cfee096a657fc01f2231c9278378d1e0a" +dependencies = [ + "glib-sys", + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "gtk" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e3004a2d5d6d8b5057d2b57b3712c9529b62e82c77f25c1fecde1fd5c23bd0" +dependencies = [ + "atk", + "bitflags 1.3.2", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio", + "glib", + "gtk-sys", + "gtk3-macros", + "libc", + "once_cell", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5bc2f0587cba247f60246a0ca11fe25fb733eabc3de12d1965fc07efab87c84" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "system-deps 6.2.2", +] + +[[package]] +name = "gtk3-macros" +version = "0.15.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "684c0456c086e8e7e9af73ec5b84e35938df394712054550e81558d21c44ab0d" +dependencies = [ + "anyhow", + "proc-macro-crate 1.3.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[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 = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "html5ever" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa 1.0.15", +] + +[[package]] +name = "http-range" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" + +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ico" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc50b891e4acf8fe0e71ef88ec43ad82ee07b3810ad09de10f1d01f072ed4b98" +dependencies = [ + "byteorder", + "png", +] + +[[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.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "ignore" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata 0.4.9", + "same-file", + "walkdir", + "winapi-util", +] + +[[package]] +name = "image" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "num-traits", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +dependencies = [ + "equivalent", + "hashbrown 0.15.3", + "serde", +] + +[[package]] +name = "infer" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f551f8c3a39f68f986517db0d1759de85881894fdc7db798bd2a9df9cb04b7fc" +dependencies = [ + "cfb", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-kit-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617ee6cf8e3f66f3b4ea67a4058564628cde41901316e19f559e14c7c72c5e7b" +dependencies = [ + "core-foundation-sys", + "mach2", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "javascriptcore-rs" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf053e7843f2812ff03ef5afe34bb9c06ffee120385caad4f6b9967fcd37d41c" +dependencies = [ + "bitflags 1.3.2", + "glib", + "javascriptcore-rs-sys", +] + +[[package]] +name = "javascriptcore-rs-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "905fbb87419c5cde6e3269537e4ea7d46431f3008c5d057e915ef3f115e7793c" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 5.0.0", +] + +[[package]] +name = "jni" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "039022cdf4d7b1cf548d31f60ae783138e5fd42013f6271049d7df7afadef96c" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror 1.0.69", + "walkdir", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[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 = "json-patch" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b1fb8864823fad91877e6caea0baca82e49e8db50f8e5c9f9a453e27d3330fc" +dependencies = [ + "jsonptr", + "serde", + "serde_json", + "thiserror 1.0.69", +] + +[[package]] +name = "jsonptr" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c6e529149475ca0b2820835d3dce8fcc41c6b943ca608d32f35b449255e4627" +dependencies = [ + "fluent-uri", + "serde", + "serde_json", +] + +[[package]] +name = "kuchikiki" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e4755b7b995046f510a7520c42b2fed58b77bd94d5a87a8eb43d2fd126da8" +dependencies = [ + "cssparser", + "html5ever", + "indexmap 1.9.3", + "matches", + "selectors", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.172" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.9.1", + "libc", + "redox_syscall", +] + +[[package]] +name = "libudev" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b324152da65df7bb95acfcaab55e3097ceaab02fb19b228a9eb74d55f135e0" +dependencies = [ + "libc", + "libudev-sys", +] + +[[package]] +name = "libudev-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324" +dependencies = [ + "libc", + "pkg-config", +] + +[[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 = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "loom" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "mach2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +dependencies = [ + "libc", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "markup5ever" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" +dependencies = [ + "log", + "phf 0.10.1", + "phf_codegen 0.10.0", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "ndk" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2032c77e030ddee34a6787a64166008da93f6a352b629261d0fee232b8742dd4" +dependencies = [ + "bitflags 1.3.2", + "jni-sys", + "ndk-sys", + "num_enum 0.5.11", + "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.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5a6ae77c8ee183dcbbba6150e2e6b9f3f4196a7666c02a715a95692ec1fa97" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", +] + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive 0.5.11", +] + +[[package]] +name = "num_enum" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +dependencies = [ + "num_enum_derive 0.7.3", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +dependencies = [ + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "obdium" +version = "1.1.0" +dependencies = [ + "chrono", + "evalexpr", + "num_enum 0.7.3", + "regex", + "serde", + "serde_json", + "serialport", + "sqlite", + "tauri", + "tauri-build", + "thiserror 2.0.12", + "tokio", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "open" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2078c0039e6a54a0c42c28faa984e115fb4c2d5bf2208f77d1961002df8576f8" +dependencies = [ + "pathdiff", + "windows-sys 0.42.0", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "pango" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e4045548659aee5313bde6c582b0d83a627b7904dd20dc2d9ef0895d414e4f" +dependencies = [ + "bitflags 1.3.2", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2a00081cde4661982ed91d80ef437c20eacaf6aa1a5962c0279ae194662c3aa" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps 6.2.2", +] + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_macros 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_shared 0.10.0", +] + +[[package]] +name = "phf" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_macros 0.11.3", + "phf_shared 0.11.3", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", +] + +[[package]] +name = "phf_codegen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.5", +] + +[[package]] +name = "phf_generator" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +dependencies = [ + "phf_shared 0.11.3", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "phf_macros" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher 0.3.11", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher 0.3.11", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher 1.0.1", +] + +[[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 = "plist" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac26e981c03a6e53e0aee43c113e3202f5581d5360dae7bd2c70e800dd0451d" +dependencies = [ + "base64 0.22.1", + "indexmap 2.9.0", + "quick-xml", + "serde", + "time", +] + +[[package]] +name = "png" +version = "0.17.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +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 = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +dependencies = [ + "toml_edit 0.22.26", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[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 = "quick-xml" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2" +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.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "raw-window-handle" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" + +[[package]] +name = "redox_syscall" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" +dependencies = [ + "bitflags 2.9.1", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom 0.2.16", + "libredox", + "thiserror 1.0.69", +] + +[[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 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[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 0.8.5", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +dependencies = [ + "bitflags 2.9.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustversion" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "selectors" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" +dependencies = [ + "bitflags 1.3.2", + "cssparser", + "derive_more", + "fxhash", + "log", + "matches", + "phf 0.8.0", + "phf_codegen 0.8.0", + "precomputed-hash", + "servo_arc", + "smallvec", + "thin-slice", +] + +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +dependencies = [ + "serde", +] + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "serde_json" +version = "1.0.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +dependencies = [ + "indexmap 2.9.0", + "itoa 1.0.15", + "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 2.0.101", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_with" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.9.0", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "serialize-to-javascript" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04f3666a07a197cdb77cdf306c32be9b7f598d7060d50cfd4d5aa04bfd92f6c5" +dependencies = [ + "serde", + "serde_json", + "serialize-to-javascript-impl", +] + +[[package]] +name = "serialize-to-javascript-impl" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "772ee033c0916d670af7860b6e1ef7d658a4629a6d0b4c8c3e67f09b3765b75d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "serialport" +version = "4.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb0bc984f6af6ef8bab54e6cf2071579ee75b9286aa9f2319a0d220c28b0a2b" +dependencies = [ + "bitflags 2.9.1", + "cfg-if", + "core-foundation 0.10.0", + "core-foundation-sys", + "io-kit-sys", + "libudev", + "mach2", + "nix", + "scopeguard", + "unescaper", + "winapi", +] + +[[package]] +name = "servo_arc" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" + +[[package]] +name = "soup2" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b4d76501d8ba387cf0fefbe055c3e0a59891d09f0f995ae4e4b16f6b60f3c0" +dependencies = [ + "bitflags 1.3.2", + "gio", + "glib", + "libc", + "once_cell", + "soup2-sys", +] + +[[package]] +name = "soup2-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "009ef427103fcb17f802871647a7fa6c60cbb654b4c4e4c0ac60a31c5f6dc9cf" +dependencies = [ + "bitflags 1.3.2", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps 5.0.0", +] + +[[package]] +name = "sqlite" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f66e9c01a11936154f3910dbba732c01f8b591543bc4d6672bddee79fd9c4783" +dependencies = [ + "sqlite3-sys", +] + +[[package]] +name = "sqlite3-src" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5b6d3c860886b0a33e69e421796a5f4a27f23597a182c2450f6d7ace5103120" +dependencies = [ + "cc", + "pkg-config", +] + +[[package]] +name = "sqlite3-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7781d97adc13a1d5081127a9ee29afad8427f3757bd984daf814d8265267039" +dependencies = [ + "sqlite3-src", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "state" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbe866e1e51e8260c9eed836a042a5e7f6726bb2b411dffeaa712e19c388f23b" +dependencies = [ + "loom", +] + +[[package]] +name = "string_cache" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared 0.11.3", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", + "proc-macro2", + "quote", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "system-deps" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18db855554db7bd0e73e06cf7ba3df39f97812cb11d3f75e71c39bf45171797e" +dependencies = [ + "cfg-expr 0.9.1", + "heck 0.3.3", + "pkg-config", + "toml 0.5.11", + "version-compare 0.0.11", +] + +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr 0.15.8", + "heck 0.5.0", + "pkg-config", + "toml 0.8.22", + "version-compare 0.2.0", +] + +[[package]] +name = "tao" +version = "0.16.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d298c441a1da46e28e8ad8ec205aab7fd8cd71b9d10e05454224eef422e1ae" +dependencies = [ + "bitflags 1.3.2", + "cairo-rs", + "cc", + "cocoa", + "core-foundation 0.9.4", + "core-graphics", + "crossbeam-channel", + "dispatch", + "gdk", + "gdk-pixbuf", + "gdk-sys", + "gdkwayland-sys", + "gdkx11-sys", + "gio", + "glib", + "glib-sys", + "gtk", + "image", + "instant", + "jni", + "lazy_static", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "objc", + "once_cell", + "parking_lot", + "png", + "raw-window-handle", + "scopeguard", + "serde", + "tao-macros", + "unicode-segmentation", + "uuid", + "windows 0.39.0", + "windows-implement 0.39.0", + "x11-dl", +] + +[[package]] +name = "tao-macros" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "tar" +version = "0.4.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + +[[package]] +name = "tauri" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae1f57c291a6ab8e1d2e6b8ad0a35ff769c9925deb8a89de85425ff08762d0c" +dependencies = [ + "anyhow", + "cocoa", + "dirs-next", + "dunce", + "embed_plist", + "encoding_rs", + "flate2", + "futures-util", + "getrandom 0.2.16", + "glib", + "glob", + "gtk", + "heck 0.5.0", + "http", + "ignore", + "log", + "objc", + "once_cell", + "open", + "percent-encoding", + "plist", + "rand 0.8.5", + "raw-window-handle", + "regex", + "semver", + "serde", + "serde_json", + "serde_repr", + "serialize-to-javascript", + "state", + "tar", + "tauri-macros", + "tauri-runtime", + "tauri-runtime-wry", + "tauri-utils", + "tempfile", + "thiserror 1.0.69", + "tokio", + "url", + "uuid", + "webkit2gtk", + "webview2-com", + "windows 0.39.0", +] + +[[package]] +name = "tauri-build" +version = "1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2db08694eec06f53625cfc6fff3a363e084e5e9a238166d2989996413c346453" +dependencies = [ + "anyhow", + "cargo_toml", + "dirs-next", + "heck 0.5.0", + "json-patch", + "semver", + "serde", + "serde_json", + "tauri-utils", + "tauri-winres", + "walkdir", +] + +[[package]] +name = "tauri-codegen" +version = "1.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53438d78c4a037ffe5eafa19e447eea599bedfb10844cb08ec53c2471ac3ac3f" +dependencies = [ + "base64 0.21.7", + "brotli", + "ico", + "json-patch", + "plist", + "png", + "proc-macro2", + "quote", + "regex", + "semver", + "serde", + "serde_json", + "sha2", + "tauri-utils", + "thiserror 1.0.69", + "time", + "uuid", + "walkdir", +] + +[[package]] +name = "tauri-macros" +version = "1.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233988ac08c1ed3fe794cd65528d48d8f7ed4ab3895ca64cdaa6ad4d00c45c0b" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 1.0.109", + "tauri-codegen", + "tauri-utils", +] + +[[package]] +name = "tauri-runtime" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8066855882f00172935e3fa7d945126580c34dcbabab43f5d4f0c2398a67d47b" +dependencies = [ + "gtk", + "http", + "http-range", + "rand 0.8.5", + "raw-window-handle", + "serde", + "serde_json", + "tauri-utils", + "thiserror 1.0.69", + "url", + "uuid", + "webview2-com", + "windows 0.39.0", +] + +[[package]] +name = "tauri-runtime-wry" +version = "0.14.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce361fec1e186705371f1c64ae9dd2a3a6768bc530d0a2d5e75a634bb416ad4d" +dependencies = [ + "cocoa", + "gtk", + "percent-encoding", + "rand 0.8.5", + "raw-window-handle", + "tauri-runtime", + "tauri-utils", + "uuid", + "webkit2gtk", + "webview2-com", + "windows 0.39.0", + "wry", +] + +[[package]] +name = "tauri-utils" +version = "1.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c357952645e679de02cd35007190fcbce869b93ffc61b029f33fe02648453774" +dependencies = [ + "brotli", + "ctor", + "dunce", + "glob", + "heck 0.5.0", + "html5ever", + "infer", + "json-patch", + "kuchikiki", + "log", + "memchr", + "phf 0.11.3", + "proc-macro2", + "quote", + "semver", + "serde", + "serde_json", + "serde_with", + "thiserror 1.0.69", + "url", + "walkdir", + "windows-version", +] + +[[package]] +name = "tauri-winres" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5993dc129e544393574288923d1ec447c857f3f644187f4fbf7d9a875fbfc4fb" +dependencies = [ + "embed-resource", + "toml 0.7.8", +] + +[[package]] +name = "tempfile" +version = "3.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +dependencies = [ + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "tendril" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" +dependencies = [ + "futf", + "mac", + "utf-8", +] + +[[package]] +name = "thin-slice" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +dependencies = [ + "deranged", + "itoa 1.0.15", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" + +[[package]] +name = "time-macros" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165" +dependencies = [ + "backtrace", + "bytes", + "pin-project-lite", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.19.15", +] + +[[package]] +name = "toml" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.22.26", +] + +[[package]] +name = "toml_datetime" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.9.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" +dependencies = [ + "indexmap 2.9.0", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow 0.7.10", +] + +[[package]] +name = "toml_write" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "unescaper" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c01d12e3a56a4432a8b436f293c25f4808bdf9e9f9f98f9260bba1f1bc5a1f26" +dependencies = [ + "thiserror 2.0.12", +] + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "uuid" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" +dependencies = [ + "getrandom 0.3.3", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "version-compare" +version = "0.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b" + +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "vswhom" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b" +dependencies = [ + "libc", + "vswhom-sys", +] + +[[package]] +name = "vswhom-sys" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb067e4cbd1ff067d1df46c9194b5de0e98efd2810bbc95c5d5e5f25a3231150" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.101", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "webkit2gtk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8f859735e4a452aeb28c6c56a852967a8a76c8eb1cc32dbf931ad28a13d6370" +dependencies = [ + "bitflags 1.3.2", + "cairo-rs", + "gdk", + "gdk-sys", + "gio", + "gio-sys", + "glib", + "glib-sys", + "gobject-sys", + "gtk", + "gtk-sys", + "javascriptcore-rs", + "libc", + "once_cell", + "soup2", + "webkit2gtk-sys", +] + +[[package]] +name = "webkit2gtk-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d76ca6ecc47aeba01ec61e480139dda143796abcae6f83bcddf50d6b5b1dcf3" +dependencies = [ + "atk-sys", + "bitflags 1.3.2", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk-sys", + "javascriptcore-rs-sys", + "libc", + "pango-sys", + "pkg-config", + "soup2-sys", + "system-deps 6.2.2", +] + +[[package]] +name = "webview2-com" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4a769c9f1a64a8734bde70caafac2b96cada12cd4aefa49196b3a386b8b4178" +dependencies = [ + "webview2-com-macros", + "webview2-com-sys", + "windows 0.39.0", + "windows-implement 0.39.0", +] + +[[package]] +name = "webview2-com-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaebe196c01691db62e9e4ca52c5ef1e4fd837dcae27dae3ada599b5a8fd05ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "webview2-com-sys" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aac48ef20ddf657755fdcda8dfed2a7b4fc7e4581acce6fe9b88c3d64f29dee7" +dependencies = [ + "regex", + "serde", + "serde_json", + "thiserror 1.0.69", + "windows 0.39.0", + "windows-bindgen", + "windows-metadata", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1c4bd0a50ac6020f65184721f758dba47bb9fbc2133df715ec74a237b26794a" +dependencies = [ + "windows-implement 0.39.0", + "windows_aarch64_msvc 0.39.0", + "windows_i686_gnu 0.39.0", + "windows_i686_msvc 0.39.0", + "windows_x86_64_gnu 0.39.0", + "windows_x86_64_msvc 0.39.0", +] + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-bindgen" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68003dbd0e38abc0fb85b939240f4bce37c43a5981d3df37ccbaaa981b47cb41" +dependencies = [ + "windows-metadata", + "windows-tokens", +] + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement 0.60.0", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba01f98f509cb5dc05f4e5fc95e535f78260f15fea8fe1a8abdd08f774f1cee7" +dependencies = [ + "syn 1.0.109", + "windows-tokens", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "windows-link" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" + +[[package]] +name = "windows-metadata" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ee5e275231f07c6e240d14f34e1b635bf1faa1c76c57cfd59a5cdb9848e4278" + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +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-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-tokens" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f838de2fe15fe6bac988e74b798f26499a8b21a9d97edec321e79b28d1d7f597" + +[[package]] +name = "windows-version" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e04a5c6627e310a23ad2358483286c7df260c964eb2d003d8efd6d0f4e79265c" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec7711666096bd4096ffa835238905bb33fb87267910e154b18b44eaabb340f2" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "763fc57100a5f7042e3057e7e8d9bdd7860d330070251a73d003563a3bb49e1b" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bc7cbfe58828921e10a9f446fcaaf649204dcfe6c1ddd712c5eebae6bda1106" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6868c165637d653ae1e8dc4d82c25d4f97dd6605eaa8d784b5c6e0ab2a252b65" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e4d40883ae9cae962787ca76ba76390ffa29214667a111db9e0a1ad8377e809" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "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 = "wry" +version = "0.24.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c55c80b12287eb1ff7c365fc2f7a5037cb6181bd44c9fce81c8d1cf7605ffad6" +dependencies = [ + "base64 0.13.1", + "block", + "cocoa", + "core-graphics", + "crossbeam-channel", + "dunce", + "gdk", + "gio", + "glib", + "gtk", + "html5ever", + "http", + "kuchikiki", + "libc", + "log", + "objc", + "objc_id", + "once_cell", + "serde", + "serde_json", + "sha2", + "soup2", + "tao", + "thiserror 1.0.69", + "url", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows 0.39.0", + "windows-implement 0.39.0", +] + +[[package]] +name = "x11" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" +dependencies = [ + "libc", + "pkg-config", +] + +[[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 = "xattr" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d65cbf2f12c15564212d48f4e3dfb87923d25d611f2aed18f4cb23f0413d89e" +dependencies = [ + "libc", + "rustix", +] + +[[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 2.0.101", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[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 2.0.101", + "synstructure", +] + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" +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 2.0.101", +] diff --git a/Cargo.toml b/backend/Cargo.toml similarity index 56% rename from Cargo.toml rename to backend/Cargo.toml index d0ed118..abe54ad 100644 --- a/Cargo.toml +++ b/backend/Cargo.toml @@ -1,18 +1,23 @@ [package] name = "obdium" -version = "0.1.0" +version = "1.1.0" edition = "2021" [dependencies] serialport = "4.7.1" sqlite = "0.37.0" chrono = "0.4.41" - num_enum = "0.7.3" thiserror = "2.0.12" - regex = "1.11.1" evalexpr = "12.0.2" - serde_json = "1.0.140" serde = { version = "^1.0.190", features = ["derive"] } +tokio = "1.45.0" +tauri = { version = "1", features = ["shell-open"] } + +[build-dependencies] +tauri-build = { version = "1", features = [] } + +[features] +custom-protocol = ["tauri/custom-protocol"] diff --git a/backend/build.rs b/backend/build.rs new file mode 100644 index 0000000..d860e1e --- /dev/null +++ b/backend/build.rs @@ -0,0 +1,3 @@ +fn main() { + tauri_build::build() +} diff --git a/data/code-descriptions.sqlite b/backend/data/code-descriptions.sqlite similarity index 100% rename from data/code-descriptions.sqlite rename to backend/data/code-descriptions.sqlite diff --git a/data/model-pids.sqlite b/backend/data/model-pids.sqlite similarity index 100% rename from data/model-pids.sqlite rename to backend/data/model-pids.sqlite diff --git a/backend/data/requests.json b/backend/data/requests.json new file mode 100644 index 0000000..61045e2 --- /dev/null +++ b/backend/data/requests.json @@ -0,0 +1,404 @@ +[ + { + "request": "010C", + "request_type": "PIDCommand", + "response": "7E8 04 41 0C 23 82 \n\n", + "played": true + }, + { + "request": "0174", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "010D", + "request_type": "PIDCommand", + "response": "7E8 03 41 0D 72 \n\n", + "played": true + }, + { + "request": "010C", + "request_type": "PIDCommand", + "response": "7E8 04 41 0C 26 25 \n\n", + "played": true + }, + { + "request": "0174", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "010D", + "request_type": "PIDCommand", + "response": "7E8 03 41 0D 48 \n\n", + "played": true + }, + { + "request": "0104", + "request_type": "PIDCommand", + "response": "7E8 03 41 04 56 \n\n", + "played": true + }, + { + "request": "0163", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "010A", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "0122", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "0123", + "request_type": "PIDCommand", + "response": "7E8 04 41 23 1A 0E \n\n", + "played": true + }, + { + "request": "010C", + "request_type": "PIDCommand", + "response": "7E8 04 41 0C 18 9F \n\n", + "played": true + }, + { + "request": "0174", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "010D", + "request_type": "PIDCommand", + "response": "7E8 03 41 0D 20 \n\n", + "played": true + }, + { + "request": "010C", + "request_type": "PIDCommand", + "response": "7E8 04 41 0C 13 FB \n\n", + "played": true + }, + { + "request": "0174", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "010D", + "request_type": "PIDCommand", + "response": "7E8 03 41 0D 29 \n\n", + "played": true + }, + { + "request": "012E", + "request_type": "PIDCommand", + "response": "7E8 03 41 2E 00 \n\n", + "played": true + }, + { + "request": "0132", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "0142", + "request_type": "PIDCommand", + "response": "7E8 04 41 42 39 5F \n\n", + "played": true + }, + { + "request": "0101", + "request_type": "PIDCommand", + "response": "7E8 06 41 01 00 07 A1 00 \n\n", + "played": true + }, + { + "request": "011F", + "request_type": "PIDCommand", + "response": "7E8 04 41 1F 00 00 \n\n", + "played": true + }, + { + "request": "01A2", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "0150", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "010E", + "request_type": "PIDCommand", + "response": "7E8 03 41 0E A6 \n\n", + "played": true + }, + { + "request": "010B", + "request_type": "PIDCommand", + "response": "7E8 03 41 0B 26 \n\n", + "played": true + }, + { + "request": "0133", + "request_type": "PIDCommand", + "response": "7E8 03 41 33 61 \n\n", + "played": true + }, + { + "request": "0118", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "0119", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "011A", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "011B", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "010C", + "request_type": "PIDCommand", + "response": "7E8 04 41 0C 3F 7A \n\n", + "played": true + }, + { + "request": "0174", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "010D", + "request_type": "PIDCommand", + "response": "7E8 03 41 0D 0E \n\n", + "played": true + }, + { + "request": "010C", + "request_type": "PIDCommand", + "response": "7E8 04 41 0C 14 5F \n\n", + "played": true + }, + { + "request": "0174", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "010D", + "request_type": "PIDCommand", + "response": "7E8 03 41 0D 0A \n\n", + "played": true + }, + { + "request": "0111", + "request_type": "PIDCommand", + "response": "7E8 03 41 11 2B \n\n", + "played": true + }, + { + "request": "0145", + "request_type": "PIDCommand", + "response": "7E8 03 41 45 42 \n\n", + "played": true + }, + { + "request": "0147", + "request_type": "PIDCommand", + "response": "7E8 03 41 47 E9 \n\n", + "played": true + }, + { + "request": "0148", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "0149", + "request_type": "PIDCommand", + "response": "7E8 03 41 49 00 \n\n", + "played": true + }, + { + "request": "010C", + "request_type": "PIDCommand", + "response": "7E8 04 41 0C 3B 2E \n\n", + "played": true + }, + { + "request": "0174", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "010D", + "request_type": "PIDCommand", + "response": "7E8 03 41 0D 20 \n\n", + "played": true + }, + { + "request": "0104", + "request_type": "PIDCommand", + "response": "7E8 03 41 04 69 \n\n", + "played": true + }, + { + "request": "0163", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "010A", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "0122", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "0123", + "request_type": "PIDCommand", + "response": "7E8 04 41 23 1A 0E \n\n", + "played": true + }, + { + "request": "010C", + "request_type": "PIDCommand", + "response": "7E8 04 41 0C 15 2A \n\n", + "played": true + }, + { + "request": "0174", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "010D", + "request_type": "PIDCommand", + "response": "7E8 03 41 0D 29 \n\n", + "played": true + }, + { + "request": "010C", + "request_type": "PIDCommand", + "response": "7E8 04 41 0C 3F 7A \n\n", + "played": true + }, + { + "request": "0174", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "010D", + "request_type": "PIDCommand", + "response": "7E8 03 41 0D 00 \n\n", + "played": true + }, + { + "request": "010C", + "request_type": "PIDCommand", + "response": "7E8 04 41 0C 14 5F \n\n", + "played": true + }, + { + "request": "0174", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "010D", + "request_type": "PIDCommand", + "response": "7E8 03 41 0D 44 \n\n", + "played": true + }, + { + "request": "0110", + "request_type": "PIDCommand", + "response": "7E8 04 41 10 18 1F \n\n", + "played": true + }, + { + "request": "019D", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "221470", + "request_type": "Arbitrary", + "response": "NO DATA", + "played": true + }, + { + "request": "0161", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "0162", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "010C", + "request_type": "PIDCommand", + "response": "7E8 04 41 0C 00 00 \n\n", + "played": true + }, + { + "request": "0174", + "request_type": "PIDCommand", + "response": "NO DATA", + "played": true + }, + { + "request": "010D", + "request_type": "PIDCommand", + "response": "7E8 03 41 0D 5C \n\n", + "played": true + } +] \ No newline at end of file diff --git a/data/vpic.sqlite b/backend/data/vpic.sqlite similarity index 100% rename from data/vpic.sqlite rename to backend/data/vpic.sqlite diff --git a/backend/icons/128x128.png b/backend/icons/128x128.png new file mode 100644 index 0000000..6be5e50 Binary files /dev/null and b/backend/icons/128x128.png differ diff --git a/backend/icons/128x128@2x.png b/backend/icons/128x128@2x.png new file mode 100644 index 0000000..e81bece Binary files /dev/null and b/backend/icons/128x128@2x.png differ diff --git a/backend/icons/32x32.png b/backend/icons/32x32.png new file mode 100644 index 0000000..a437dd5 Binary files /dev/null and b/backend/icons/32x32.png differ diff --git a/backend/icons/Square107x107Logo.png b/backend/icons/Square107x107Logo.png new file mode 100644 index 0000000..0ca4f27 Binary files /dev/null and b/backend/icons/Square107x107Logo.png differ diff --git a/backend/icons/Square142x142Logo.png b/backend/icons/Square142x142Logo.png new file mode 100644 index 0000000..b81f820 Binary files /dev/null and b/backend/icons/Square142x142Logo.png differ diff --git a/backend/icons/Square150x150Logo.png b/backend/icons/Square150x150Logo.png new file mode 100644 index 0000000..624c7bf Binary files /dev/null and b/backend/icons/Square150x150Logo.png differ diff --git a/backend/icons/Square284x284Logo.png b/backend/icons/Square284x284Logo.png new file mode 100644 index 0000000..c021d2b Binary files /dev/null and b/backend/icons/Square284x284Logo.png differ diff --git a/backend/icons/Square30x30Logo.png b/backend/icons/Square30x30Logo.png new file mode 100644 index 0000000..6219700 Binary files /dev/null and b/backend/icons/Square30x30Logo.png differ diff --git a/backend/icons/Square310x310Logo.png b/backend/icons/Square310x310Logo.png new file mode 100644 index 0000000..f9bc048 Binary files /dev/null and b/backend/icons/Square310x310Logo.png differ diff --git a/backend/icons/Square44x44Logo.png b/backend/icons/Square44x44Logo.png new file mode 100644 index 0000000..d5fbfb2 Binary files /dev/null and b/backend/icons/Square44x44Logo.png differ diff --git a/backend/icons/Square71x71Logo.png b/backend/icons/Square71x71Logo.png new file mode 100644 index 0000000..63440d7 Binary files /dev/null and b/backend/icons/Square71x71Logo.png differ diff --git a/backend/icons/Square89x89Logo.png b/backend/icons/Square89x89Logo.png new file mode 100644 index 0000000..f3f705a Binary files /dev/null and b/backend/icons/Square89x89Logo.png differ diff --git a/backend/icons/StoreLogo.png b/backend/icons/StoreLogo.png new file mode 100644 index 0000000..4556388 Binary files /dev/null and b/backend/icons/StoreLogo.png differ diff --git a/backend/icons/icon.icns b/backend/icons/icon.icns new file mode 100644 index 0000000..12a5bce Binary files /dev/null and b/backend/icons/icon.icns differ diff --git a/backend/icons/icon.ico b/backend/icons/icon.ico new file mode 100644 index 0000000..4025c3d Binary files /dev/null and b/backend/icons/icon.ico differ diff --git a/backend/icons/icon.png b/backend/icons/icon.png new file mode 100644 index 0000000..e1cd261 Binary files /dev/null and b/backend/icons/icon.png differ diff --git a/backend/src/bridge/events.rs b/backend/src/bridge/events.rs new file mode 100644 index 0000000..1f7ad45 --- /dev/null +++ b/backend/src/bridge/events.rs @@ -0,0 +1,268 @@ +use super::{ConnectPaylod, ConnectionStatus, Setting, VehicleInfo, VehicleInfoExtended}; +/// Events to bridge the frontend with +/// the backend. +/// +/// Includes listening for requests from the frontend +/// to perform actions +use crate::{connect_obd, track_data, OBD}; +use obdium::dicts::PID_INFOS; +use obdium::vin::VIN; +use std::sync::{Arc, Mutex}; +use std::time::Duration; +use tauri::{async_runtime::spawn, Window}; +use tokio::time::sleep; + +// "Listen" events +// +// Where the backend "listens" for events from the frontend +// All listen events are prefixed with 'listen' + +pub fn listen_send_pids(window: &Arc) { + let window_arc = Arc::new(window.clone()); + let window_clone = Arc::clone(&window_arc); + window_clone.listen("get-pids", move |_| { + let _ = window_arc.emit("update-pids", PID_INFOS); + }); +} + +pub fn listen_send_ports(window: &Arc) { + let window_arc = Arc::new(window.clone()); + let window_clone = Arc::clone(&window_arc); + window_clone.listen("get-serial-ports", move |_| { + let _ = window_arc.emit("update-serial-ports", OBD::get_open_serial_port()); + }); +} + +// TODO: This is an eye sore. +pub fn listen_decode_vin(window: &Window) { + let window_arc = Arc::new(window.clone()); + let window_clone = Arc::clone(&window_arc); + window_clone.listen("decode-vin", move |event| { + let vin = match VIN::new(event.payload().unwrap().replace("\"", "")) { + Ok(vin) => vin, + Err(err) => { + // emit error + let v_info = VehicleInfoExtended { + error_msg: format!("{}", err), + ..Default::default() + }; + + let _ = window_arc.emit("decode-vin", v_info); + return; + } + }; + + let v_info = VehicleInfoExtended { + error_msg: "Decoded successfully.".to_string(), + vin: vin.get_vin().to_string(), + make: vin.get_vehicle_make().unwrap_or("N/A".into()), + model: vin.get_vehicle_model().unwrap_or("N/A".into()), + model_year: vin.get_model_year().unwrap_or(-1).to_string(), + engine_model: vin.get_engine_model().unwrap_or("N/A".into()), + cylinder_count: vin.get_cylinder_count().unwrap_or(-1).to_string(), + axel_count: vin.get_axle_count().unwrap_or(-1).to_string(), + traction_control: vin.traction_control().unwrap_or("N/A".into()), + plant_country: vin.get_plant_country().unwrap_or("N/A".into()), + plant_city: vin.get_plant_city().unwrap_or("N/A".into()), + plant_state: vin.get_plant_state().unwrap_or("N/A".into()), + semi_auto_headlamp_beam_switching: vin + .semiauto_headlamp_beam_switching() + .unwrap_or("N/A".into()), + dynamic_brake_support: vin.dynamic_brake_support().unwrap_or("N/A".into()), + airbag_locations_knee: vin.airbag_locations_knee().unwrap_or("N/A".into()), + airbag_locations_side: vin.airbag_locations_side().unwrap_or("N/A".into()), + body_style: vin.get_body_class().unwrap_or("N/A".into()), + fuel_type: vin.get_fuel_type().unwrap_or("N/A".into()), + fuel_delivery_type: vin.get_fuel_delivery_type().unwrap_or("N/A".into()), + engine_manufacturer: vin.get_engine_manufacturer().unwrap_or("N/A".into()), + anti_lock_braking_system: vin.abs_availablility().unwrap_or("N/A".into()), + transmission_style: vin.get_transmission_style().unwrap_or("N/A".into()), + steering_location: vin.get_steering_location().unwrap_or("N/A".into()), + keyless_ignition: vin.keyless_ignition_availability().unwrap_or("N/A".into()), + top_speed: vin.get_vehicle_top_speed().unwrap_or(-1).to_string(), + daytime_running_light: vin.daytime_running_light().unwrap_or("N/A".into()), + window_auto_reverse: vin.windows_auto_reverse().unwrap_or("N/A".into()), + airbag_locations_front: vin.airbag_locations_front().unwrap_or("N/A".into()), + front_wheel_size: vin.get_front_wheel_size().unwrap_or(-1).to_string(), + rear_wheel_size: vin.get_rear_wheel_size().unwrap_or(-1).to_string(), + automatic_crash_notification: vin + .automatic_crash_notification() + .unwrap_or("N/A".into()), + trim: vin.vehicle_trim().unwrap_or("N/A".into()), + transmission_speeds: vin.get_transmission_speeds().unwrap_or(-1).to_string(), + vehicle_base_price: vin.get_vehicle_base_price().unwrap_or(-1.0).to_string(), + number_of_rows: vin.number_of_rows().unwrap_or(-1).to_string(), + number_of_seats: vin.number_of_seats().unwrap_or(-1).to_string(), + brake_system: vin.get_brake_system().unwrap_or("N/A".into()), + engine_displacement: vin.get_engine_displacement().unwrap_or(-1.0).to_string(), + gross_vehicle_weight_rating: vin.get_vehicle_weight_rating().unwrap_or("N/A".into()), + airbag_locations_curtain: vin.airbag_locations_curtain().unwrap_or("N/A".into()), + backup_camera: vin.backup_camera().unwrap_or("N/A".into()), + drive_type: vin.get_drive_type().unwrap_or("N/A".into()), + vehicle_manufacturer: vin.get_vehicle_manufacturer().unwrap_or("N/A".into()), + }; + + let _ = window_arc.emit("decode-vin", v_info); + }); +} + +pub fn listen_connect_elm(window: &Arc) { + let window_arc = Arc::new(window.clone()); + let window_clone = Arc::clone(&window_arc); + window_clone.listen("connect-elm", move |event| { + let payload = event.payload().unwrap_or(""); + let connect_payload: ConnectPaylod = match serde_json::from_str(payload) { + Ok(p) => p, + Err(e) => { + println!("Failed to parse connect payload: {e}"); + return; + } + }; + + let obd = connect_obd( + &window_arc, + connect_payload.serial_port, + connect_payload.baud_rate, + connect_payload.protocol, + ); + + if let Some(obd) = obd { + // Arc's + let obd = Arc::new(Mutex::new(obd)); + + // Usually called once + do_send_vehicle_details(&window_arc, &obd); + + // Live tracking data + track_data(&window_arc, &obd); + + // spawn thread to keep checking if obd disconnects + let window_arc_clone = Arc::clone(&window_arc); + let obd_clone = Arc::clone(&obd); + spawn(async move { + loop { + sleep(Duration::from_secs(1)).await; + let obd = obd_clone.lock().unwrap(); + if !obd.connected() { + do_send_connection_status( + &window_arc_clone, + &obd, + "Connection dropped".to_string(), + false, + ); + break; + } + } + }); + + // Listen for disconnect-elm event outside of async block to avoid lifetime issues + let window_arc_for_listen = Arc::clone(&window_arc); + let obd_for_listen = Arc::clone(&obd); + window_arc_for_listen.listen("disconnect-elm", { + let window_arc_for_listen = Arc::clone(&window_arc_for_listen); + move |_| { + let mut obd = obd_for_listen.lock().unwrap(); + obd.disconnect(); + do_send_connection_status( + &window_arc_for_listen, + &obd, + "Connection dropped".to_string(), + false, + ); + } + }); + + listen_change_obd_settings(&window_arc, &obd); + } + }); +} + +pub fn listen_change_obd_settings(window: &Arc, obd: &Arc>) { + let obd_arc = Arc::clone(obd); + window.listen("settings-changed", move |event| { + let payload = match event.payload() { + Some(payload) => payload, + None => return, + }; + + let setting: Setting = match serde_json::from_str(payload) { + Ok(p) => p, + Err(e) => { + println!("Failed to parse setting payload: {e}"); + return; + } + }; + + let mut obd = obd_arc.lock().unwrap(); + match setting.t_id.as_str() { + "record-responses" => obd.record_requests(setting.checked), + "replay-responses" => obd.replay_requests(setting.checked), + "use-freeze-fram" => obd.query_freeze_frame(setting.checked), + _ => (), + } + }); +} + +// Calls to the frontend from the backend +// where the backend umprompty tells the +// frontend to do something. +// +// In this case, the frontend would be listening for these events. + +pub fn do_send_vehicle_details(window: &Arc, obd: &Arc>) { + let obd = Arc::clone(obd); + let window = Arc::clone(window); + spawn(async move { + let mut obd = obd.lock().unwrap(); + + // send the vin and vehicle details to the frontend + match obd.get_vin() { + Some(vin) => { + let make = match vin.get_vehicle_make() { + Ok(make) => make, + Err(err) => { + println!("failed to resolve vehicle make from vin: {}", vin.get_vin()); + println!("error: {err}"); + "??".to_string() + } + }; + + let model = match vin.get_vehicle_model() { + Ok(model) => model, + Err(err) => { + println!( + "failed to resolve vehicle model from vin: {}", + vin.get_vin() + ); + println!("error: {err}"); + "??".to_string() + } + }; + + let v_info = VehicleInfo { + vin: vin.get_vin().to_string(), + make, + model, + }; + + window.emit("vehicle-details", v_info).unwrap(); + } + None => { + println!("error: getting vin. vin is none."); + } + }; + }); +} + +pub fn do_send_connection_status(window: &Window, obd: &OBD, message: String, connected: bool) { + let port = obd.serial_port_name().unwrap_or_default(); + let baud = obd.serial_port_baud_rate().unwrap_or_default(); + let conn_status = ConnectionStatus { + connected, + message, + serial_port: port, + baud_rate: baud, + }; + + let _ = window.emit("connection-status", conn_status); +} diff --git a/backend/src/bridge/mod.rs b/backend/src/bridge/mod.rs new file mode 100644 index 0000000..c3e9406 --- /dev/null +++ b/backend/src/bridge/mod.rs @@ -0,0 +1,93 @@ +pub mod events; + +/// Structs that are used as payloads +/// between frontend and backend. +use serde::{Deserialize, Serialize}; + +/// Very brief vehicle information +/// No detailed information- use VehicleInfoExtended +/// with the VIN struct for that instead. +#[derive(Serialize, Deserialize, Clone)] +struct VehicleInfo { + vin: String, + make: String, + model: String, +} + +/// All relevant information about a +/// vehicle. +/// +/// Essential when the frontend +/// requests vehicle info about a VIN but +/// can't use the VIN struct and it's methods. +#[derive(Serialize, Deserialize, Clone, Default)] +struct VehicleInfoExtended { + error_msg: String, + vin: String, + make: String, + model: String, + model_year: String, + engine_model: String, + cylinder_count: String, + axel_count: String, + traction_control: String, + plant_country: String, + plant_city: String, + plant_state: String, + semi_auto_headlamp_beam_switching: String, + dynamic_brake_support: String, + airbag_locations_knee: String, + airbag_locations_side: String, + drive_type: String, + fuel_type: String, + fuel_delivery_type: String, + engine_manufacturer: String, + anti_lock_braking_system: String, + transmission_style: String, + steering_location: String, + keyless_ignition: String, + top_speed: String, + daytime_running_light: String, + window_auto_reverse: String, + airbag_locations_front: String, + front_wheel_size: String, + rear_wheel_size: String, + automatic_crash_notification: String, + trim: String, + transmission_speeds: String, + vehicle_base_price: String, + number_of_rows: String, + number_of_seats: String, + brake_system: String, + engine_displacement: String, + gross_vehicle_weight_rating: String, + airbag_locations_curtain: String, + backup_camera: String, + body_style: String, + vehicle_manufacturer: String, +} + +/// Tells the frontend the serial port +/// connection status. +#[derive(Serialize, Deserialize, Clone)] +struct ConnectionStatus { + connected: bool, + message: String, + serial_port: String, + baud_rate: u32, +} + +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +struct ConnectPaylod { + serial_port: String, + baud_rate: u32, + protocol: u8, +} + +#[derive(Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +struct Setting { + t_id: String, + checked: bool, +} diff --git a/src/cmd.rs b/backend/src/cmd.rs similarity index 100% rename from src/cmd.rs rename to backend/src/cmd.rs diff --git a/backend/src/dicts.rs b/backend/src/dicts.rs new file mode 100644 index 0000000..b7ef9db --- /dev/null +++ b/backend/src/dicts.rs @@ -0,0 +1,169 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Deserialize, Serialize, Clone)] +pub struct PidInfo { + pid: &'static str, + mode: &'static str, + unit: &'static str, + pid_name: &'static str, + formula: &'static str, +} + +pub const PID_INFOS: &[PidInfo] = &[ + PidInfo { pid: "01", mode: "01", unit: "", pid_name: "Monitor status since DTCs cleared", formula: "", }, + PidInfo { pid: "02", mode: "01", unit: "", pid_name: "DTC that caused freeze frame to be stored", formula: "", }, + PidInfo { pid: "03", mode: "01", unit: "", pid_name: "Fuel system status", formula: "", }, + PidInfo { pid: "04", mode: "01", unit: "%", pid_name: "Calculated engine load", formula: "100/255 * A", }, + PidInfo { pid: "05", mode: "01", unit: "°C", pid_name: "Engine coolant temperature", formula: "A - 40", }, + PidInfo { pid: "06", mode: "01", unit: "%", pid_name: "Short term fuel trim Bank 1", formula: "(100/128 * A) - 100", }, + PidInfo { pid: "07", mode: "01", unit: "%", pid_name: "Long term fuel trim Bank 1", formula: "(100/128 * A) - 100", }, + PidInfo { pid: "08", mode: "01", unit: "%", pid_name: "Short term fuel trim Bank 2", formula: "(100/128 * A) - 100", }, + PidInfo { pid: "09", mode: "01", unit: "%", pid_name: "Long term fuel trim Bank 2", formula: "(100/128 * A) - 100", }, + PidInfo { pid: "0A", mode: "01", unit: "kPa", pid_name: "Fuel pressure", formula: "3 * A", }, + PidInfo { pid: "0B", mode: "01", unit: "kPa", pid_name: "Intake manifold absolute pressure", formula: "A", }, + PidInfo { pid: "0C", mode: "01", unit: "rpm", pid_name: "Engine speed", formula: "((256 * A)+B) / 4", }, + PidInfo { pid: "0D", mode: "01", unit: "km/h", pid_name: "Vehicle speed", formula: "A", }, + PidInfo { pid: "0E", mode: "01", unit: "", pid_name: "Timing advance", formula: "A/2 - 64", }, + PidInfo { pid: "0F", mode: "01", unit: "°C", pid_name: "Intake air temperature", formula: "A - 40", }, + PidInfo { pid: "10", mode: "01", unit: "g/s", pid_name: "MAF air flow rate", formula: "((256 * A)+B) / 100", }, + PidInfo { pid: "11", mode: "01", unit: "%", pid_name: "Throttle position", formula: "100/255 * A", }, + PidInfo { pid: "12", mode: "01", unit: "", pid_name: "Commanded secondary air status", formula: "", }, + PidInfo { pid: "13", mode: "01", unit: "", pid_name: "Oxygen sensors present (in 2 banks)", formula: "", }, + PidInfo { pid: "14", mode: "01", unit: "(V, %)", pid_name: "Oxygen Sensor 1 (A: Voltage B: STFT)", formula: "V: A / 200 %: 100/128B - 100", }, + PidInfo { pid: "15", mode: "01", unit: "(V, %)", pid_name: "Oxygen Sensor 2 (A: Voltage B: STFT)", formula: "V: A / 200 %: 100/128B - 100", }, + PidInfo { pid: "16", mode: "01", unit: "(V, %)", pid_name: "Oxygen Sensor 3 (A: Voltage B: STFT)", formula: "V: A / 200 %: 100/128B - 100", }, + PidInfo { pid: "17", mode: "01", unit: "(V, %)", pid_name: "Oxygen Sensor 4 (A: Voltage B: STFT)", formula: "V: A / 200 %: 100/128B - 100", }, + PidInfo { pid: "18", mode: "01", unit: "(V, %)", pid_name: "Oxygen Sensor 5 (A: Voltage B: STFT)", formula: "V: A / 200 %: 100/128B - 100", }, + PidInfo { pid: "19", mode: "01", unit: "(V, %)", pid_name: "Oxygen Sensor 6 (A: Voltage B: STFT)", formula: "V: A / 200 %: 100/128B - 100", }, + PidInfo { pid: "1A", mode: "01", unit: "(V, %)", pid_name: "Oxygen Sensor 7 (A: Voltage B: STFT)", formula: "V: A / 200 %: 100/128B - 100", }, + PidInfo { pid: "1B", mode: "01", unit: "(V, %)", pid_name: "Oxygen Sensor 8 (A: Voltage B: STFT)", formula: "V: A / 200 %: 100/128B - 100", }, + PidInfo { pid: "1C", mode: "01", unit: "", pid_name: "OBD standards this vehicle conforms to", formula: "", }, + PidInfo { pid: "1D", mode: "01", unit: "", pid_name: "Oxygen sensors present (in 4 banks)", formula: "", }, + PidInfo { pid: "1E", mode: "01", unit: "", pid_name: "Aux input status", formula: "", }, + PidInfo { pid: "1F", mode: "01", unit: "s", pid_name: "Run time since engine start", formula: "(256 * A) + B", }, + PidInfo { pid: "21", mode: "01", unit: "km", pid_name: "Dist. with (MIL) on", formula: "(256 * A) + B", }, + PidInfo { pid: "22", mode: "01", unit: "kPa", pid_name: "Fuel Rail Pressure", formula: "0.079(256A + B)", }, + PidInfo { pid: "23", mode: "01", unit: "kPa", pid_name: "Fuel Rail Gauge Pressure", formula: "10(256A + B)", }, + PidInfo { pid: "24", mode: "01", unit: "(ratio, V)", pid_name: "Oxygen Sensor 1 (AB: AFR CD: Voltage)", formula: "(ratio: 2/65536(256A+B) V: 8/65536(256C+D)", }, + PidInfo { pid: "25", mode: "01", unit: "(ratio, V)", pid_name: "Oxygen Sensor 2 (AB: AFR CD: Voltage)", formula: "(ratio: 2/65536(256A+B) V: 8/65536(256C+D)", }, + PidInfo { pid: "26", mode: "01", unit: "(ratio, V)", pid_name: "Oxygen Sensor 3 (AB: AFR CD: Voltage)", formula: "(ratio: 2/65536(256A+B) V: 8/65536(256C+D)", }, + PidInfo { pid: "27", mode: "01", unit: "(ratio, V)", pid_name: "Oxygen Sensor 4 (AB: AFR CD: Voltage)", formula: "(ratio: 2/65536(256A+B) V: 8/65536(256C+D)", }, + PidInfo { pid: "28", mode: "01", unit: "(ratio, V)", pid_name: "Oxygen Sensor 5 (AB: AFR CD: Voltage)", formula: "(ratio: 2/65536(256A+B) V: 8/65536(256C+D)", }, + PidInfo { pid: "29", mode: "01", unit: "(ratio, V)", pid_name: "Oxygen Sensor 6 (AB: AFR CD: Voltage)", formula: "(ratio: 2/65536(256A+B) V: 8/65536(256C+D)", }, + PidInfo { pid: "2A", mode: "01", unit: "(ratio, V)", pid_name: "Oxygen Sensor 7 (AB: AFR CD: Voltage)", formula: "(ratio: 2/65536(256A+B) V: 8/65536(256C+D)", }, + PidInfo { pid: "2B", mode: "01", unit: "(ratio, V)", pid_name: "Oxygen Sensor 8 (AB: AFR CD: Voltage)", formula: "(ratio: 2/65536(256A+B) V: 8/65536(256C+D)", }, + PidInfo { pid: "2C", mode: "01", unit: "%", pid_name: "Commanded EGR", formula: "100/255 * A", }, + PidInfo { pid: "2D", mode: "01", unit: "%", pid_name: "EGR Error", formula: "(100/128 * A) - 100", }, + PidInfo { pid: "2E", mode: "01", unit: "%", pid_name: "Commanded evaporative purge", formula: "100/255 * A", }, + PidInfo { pid: "2F", mode: "01", unit: "%", pid_name: "Fuel Tank Level Input", formula: "100/255 * A", }, + PidInfo { pid: "30", mode: "01", unit: "", pid_name: "Warm-ups since codes cleared", formula: "A", }, + PidInfo { pid: "31", mode: "01", unit: "km", pid_name: "Distance traveled since codes cleared", formula: "(256 * A)+B", }, + PidInfo { pid: "32", mode: "01", unit: "Pa", pid_name: "Evap. System Vapor Pressure", formula: "((256 * A)+B) / 4", }, + PidInfo { pid: "33", mode: "01", unit: "kPa", pid_name: "Absolute Barometric Pressure", formula: "A", }, + PidInfo { pid: "34", mode: "01", unit: "(ratio, mA)", pid_name: "Oxygen Sensor 1 (AB: AFR CD: Current)", formula: "(ratio: 2/65536(256A+B) mA: ((256C + D) / 256) - 128", }, + PidInfo { pid: "35", mode: "01", unit: "(ratio, mA)", pid_name: "Oxygen Sensor 2 (AB: AFR CD: Current)", formula: "(ratio: 2/65536(256A+B) mA: ((256C + D) / 256) - 128", }, + PidInfo { pid: "36", mode: "01", unit: "(ratio, mA)", pid_name: "Oxygen Sensor 3 (AB: AFR CD: Current)", formula: "(ratio: 2/65536(256A+B) mA: ((256C + D) / 256) - 128", }, + PidInfo { pid: "37", mode: "01", unit: "(ratio, mA)", pid_name: "Oxygen Sensor 4 (AB: AFR CD: Current)", formula: "(ratio: 2/65536(256A+B) mA: ((256C + D) / 256) - 128", }, + PidInfo { pid: "38", mode: "01", unit: "(ratio, mA)", pid_name: "Oxygen Sensor 5 (AB: AFR CD: Current)", formula: "(ratio: 2/65536(256A+B) mA: ((256C + D) / 256) - 128", }, + PidInfo { pid: "39", mode: "01", unit: "(ratio, mA)", pid_name: "Oxygen Sensor 6 (AB: AFR CD: Current)", formula: "(ratio: 2/65536(256A+B) mA: ((256C + D) / 256) - 128", }, + PidInfo { pid: "3A", mode: "01", unit: "(ratio, mA)", pid_name: "Oxygen Sensor 7 (AB: AFR CD: Current)", formula: "(ratio: 2/65536(256A+B) mA: ((256C + D) / 256) - 128", }, + PidInfo { pid: "3B", mode: "01", unit: "(ratio, mA)", pid_name: "Oxygen Sensor 8 (AB: AFR CD: Current)", formula: "(ratio: 2/65536(256A+B) mA: ((256C + D) / 256) - 128", }, + PidInfo { pid: "3C", mode: "01", unit: "°C", pid_name: "Catalyst Temperature: Bank 1, Sensor 1", formula: "(((256 * A)+B) / 10) - 40", }, + PidInfo { pid: "3D", mode: "01", unit: "°C", pid_name: "Catalyst Temperature: Bank 2, Sensor 1", formula: "(((256 * A)+B) / 10) - 40", }, + PidInfo { pid: "3E", mode: "01", unit: "°C", pid_name: "Catalyst Temperature: Bank 1, Sensor 2", formula: "(((256 * A)+B) / 10) - 40", }, + PidInfo { pid: "3F", mode: "01", unit: "°C", pid_name: "Catalyst Temperature: Bank 2, Sensor 2", formula: "(((256 * A)+B) / 10) - 40", }, + PidInfo { pid: "41", mode: "01", unit: "", pid_name: "Monitor status this drive cycle", formula: "", }, + PidInfo { pid: "42", mode: "01", unit: "V", pid_name: "Control module voltage", formula: "((256 * A)+B) / 1000", }, + PidInfo { pid: "43", mode: "01", unit: "%", pid_name: "Absolute load value", formula: "(100/255) * (256A + B)", }, + PidInfo { pid: "44", mode: "01", unit: "ratio", pid_name: "Commanded Air-Fuel Equivalence Ratio", formula: "(2/65536) * (256A + B)", }, + PidInfo { pid: "45", mode: "01", unit: "%", pid_name: "Relative throttle position", formula: "100/255 * A", }, + PidInfo { pid: "46", mode: "01", unit: "°C", pid_name: "Ambient air temperature", formula: "A - 40", }, + PidInfo { pid: "47", mode: "01", unit: "%", pid_name: "Absolute throttle position B", formula: "100/255 * A", }, + PidInfo { pid: "4D", mode: "01", unit: "min", pid_name: "Time run with MIL on", formula: "256A + B", }, + PidInfo { pid: "4F", mode: "01", unit: "ratio, V, mA, kPa", pid_name: "Maximum value for AFR, oxygen sensor voltage, oxygen sensor current, and intake manifold absolute pressure", formula: "A, B, C, D * 10", }, + PidInfo { pid: "50", mode: "01", unit: "g/s", pid_name: "Maximum air flow rate from MAF sensor", formula: "A * 10", }, + PidInfo { pid: "51", mode: "01", unit: "", pid_name: "Fuel Type", formula: "", }, + PidInfo { pid: "52", mode: "01", unit: "%", pid_name: "Ethanol fuel %", formula: "100/255 * A", }, + PidInfo { pid: "53", mode: "01", unit: "kPa", pid_name: "Absolute Evap system Vapor Pressure", formula: "((256 * A)+B) / 200", }, + PidInfo { pid: "54", mode: "01", unit: "Pa", pid_name: "Evap system vapor pressure", formula: "(256 * A) + B", }, + PidInfo { pid: "55", mode: "01", unit: "%", pid_name: "Short term secondary oxygen sensor trim, A: bank 1, B: bank 3", formula: "", }, + PidInfo { pid: "59", mode: "01", unit: "kPa", pid_name: "Fuel rail absolute pressure", formula: "10(256A + B)", }, + PidInfo { pid: "5A", mode: "01", unit: "%", pid_name: "Relative accelerator pedal position", formula: "100/255 * A", }, + PidInfo { pid: "5B", mode: "01", unit: "%", pid_name: "Hybrid battery pack remaining life", formula: "100/255 * A", }, + PidInfo { pid: "5C", mode: "01", unit: "°C", pid_name: "Engine oil temperature", formula: "A - 40", }, + PidInfo { pid: "5D", mode: "01", unit: "°", pid_name: "Fuel injection timing", formula: "(((256 * A)+B) / 128) - 210", }, + PidInfo { pid: "5E", mode: "01", unit: "L/h", pid_name: "Engine fuel rate", formula: "((256 * A)+B) / 20", }, + PidInfo { pid: "5F", mode: "01", unit: "", pid_name: "Emission requirements to which vehicle is designed", formula: "", }, + PidInfo { pid: "61", mode: "01", unit: "%", pid_name: "Driver's demand engine - percent torque", formula: "A - 125", }, + PidInfo { pid: "62", mode: "01", unit: "%", pid_name: "Actual engine - percent torque", formula: "A - 125", }, + PidInfo { pid: "63", mode: "01", unit: "Nm", pid_name: "Engine reference torque", formula: "256A + B", }, + PidInfo { pid: "64", mode: "01", unit: "%", pid_name: "Engine percent torque data", formula: "Subtract 125 from A - E", }, + PidInfo { pid: "65", mode: "01", unit: "", pid_name: "Auxiliary input / output supported", formula: "", }, + PidInfo { pid: "66", mode: "01", unit: "g/s", pid_name: "Mass air flow sensor", formula: "{A0}== Sensor A Supported", }, + PidInfo { pid: "67", mode: "01", unit: "°C", pid_name: "Engine coolant temperature", formula: "{A0}== Sensor 1 Supported", }, + PidInfo { pid: "68", mode: "01", unit: "°C", pid_name: "Intake air temperature sensor", formula: "{A0}== Sensor 1 Supported", }, + PidInfo { pid: "69", mode: "01", unit: "", pid_name: "Actual EGR, Commanded EGR, and EGR Error", formula: "", }, + PidInfo { pid: "6A", mode: "01", unit: "", pid_name: "Commanded Diesel intake air flow control and relative intake air flow position", formula: "", }, + PidInfo { pid: "6B", mode: "01", unit: "", pid_name: "Exhaust gas recirculation temperature", formula: "", }, + PidInfo { pid: "6C", mode: "01", unit: "", pid_name: "Commanded throttle actuator control and relative throttle position", formula: "", }, + PidInfo { pid: "6D", mode: "01", unit: "", pid_name: "Fuel pressure control system", formula: "", }, + PidInfo { pid: "6E", mode: "01", unit: "", pid_name: "Injection pressure control system", formula: "", }, + PidInfo { pid: "6F", mode: "01", unit: "", pid_name: "Turbocharger compressor inlet pressure", formula: "", }, + PidInfo { pid: "70", mode: "01", unit: "", pid_name: "Boost pressure control", formula: "", }, + PidInfo { pid: "71", mode: "01", unit: "", pid_name: "Variable Geometry turbo (VGT) control", formula: "", }, + PidInfo { pid: "72", mode: "01", unit: "", pid_name: "Wastegate control", formula: "", }, + PidInfo { pid: "73", mode: "01", unit: "", pid_name: "Exhaust pressure", formula: "", }, + PidInfo { pid: "74", mode: "01", unit: "RPM", pid_name: "Turbocharger RPM", formula: "", }, + PidInfo { pid: "75", mode: "01", unit: "°C", pid_name: "Turbocharger temperature", formula: "", }, + PidInfo { pid: "76", mode: "01", unit: "°C", pid_name: "Turbocharger temperature", formula: "", }, + PidInfo { pid: "77", mode: "01", unit: "°C", pid_name: "Charge air cooler temperature (CACT)", formula: "", }, + PidInfo { pid: "78", mode: "01", unit: "°C", pid_name: "Exhaust Gas temperature (EGT) Bank 1", formula: "", }, + PidInfo { pid: "79", mode: "01", unit: "°C", pid_name: "Exhaust Gas temperature (EGT) Bank 2", formula: "", }, + PidInfo { pid: "7A", mode: "01", unit: "", pid_name: "Diesel particulate filter (DPF)", formula: "", }, + PidInfo { pid: "7B", mode: "01", unit: "", pid_name: "Diesel particulate filter (DPF)", formula: "", }, + PidInfo { pid: "7C", mode: "01", unit: "°C", pid_name: "Diesel Particulate filter (DPF) temperature", formula: "(((256 * A)+B) / 10) - 40", }, + PidInfo { pid: "7D", mode: "01", unit: "", pid_name: "NOx NTE", formula: "", }, + PidInfo { pid: "7E", mode: "01", unit: "", pid_name: "PM NTE", formula: "", }, + PidInfo { pid: "7F", mode: "01", unit: "s", pid_name: "Engine run time", formula: "B(2^24) + C(2^16) + D(2^8) + E", }, + PidInfo { pid: "81", mode: "01", unit: "", pid_name: "Engine run time for Auxiliary Emissions Control Device(AECD)", formula: "", }, + PidInfo { pid: "82", mode: "01", unit: "", pid_name: "Engine run time for Auxiliary Emissions Control Device(AECD)", formula: "", }, + PidInfo { pid: "83", mode: "01", unit: "", pid_name: "NOx sensor", formula: "", }, + PidInfo { pid: "84", mode: "01", unit: "", pid_name: "Manifold surface temperature", formula: "", }, + PidInfo { pid: "85", mode: "01", unit: "%", pid_name: "NOx reagent system", formula: "100/255 * F", }, + PidInfo { pid: "86", mode: "01", unit: "", pid_name: "Particulate matter (PM) sensor", formula: "", }, + PidInfo { pid: "87", mode: "01", unit: "kPa", pid_name: "Intake manifold absolute pressure", formula: "", }, + PidInfo { pid: "88", mode: "01", unit: "", pid_name: "SCR Induce System", formula: "", }, + PidInfo { pid: "89", mode: "01", unit: "", pid_name: "Run Time for AECD #11-#15", formula: "", }, + PidInfo { pid: "8A", mode: "01", unit: "", pid_name: "Run Time for AECD #16-#20", formula: "", }, + PidInfo { pid: "8B", mode: "01", unit: "", pid_name: "Diesel Aftertreatment", formula: "", }, + PidInfo { pid: "8C", mode: "01", unit: "", pid_name: "O2 Sensor (Wide Range)", formula: "", }, + PidInfo { pid: "8D", mode: "01", unit: "%", pid_name: "Throttle Position G", formula: "", }, + PidInfo { pid: "8E", mode: "01", unit: "%", pid_name: "Engine Friction - Percent Torque", formula: "A - 125", }, + PidInfo { pid: "8F", mode: "01", unit: "", pid_name: "PM Sensor Bank 1 & 2", formula: "", }, + PidInfo { pid: "90", mode: "01", unit: "h", pid_name: "WWH-OBD Vehicle OBD System Information", formula: "", }, + PidInfo { pid: "91", mode: "01", unit: "h", pid_name: "WWH-OBD Vehicle OBD System Information", formula: "", }, + PidInfo { pid: "92", mode: "01", unit: "", pid_name: "Fuel System Control", formula: "", }, + PidInfo { pid: "93", mode: "01", unit: "h", pid_name: "WWH-OBD Vehicle OBD Counters support", formula: "", }, + PidInfo { pid: "94", mode: "01", unit: "", pid_name: "NOx Warning And Inducement System", formula: "", }, + PidInfo { pid: "98", mode: "01", unit: "°C", pid_name: "Exhaust Gas Temperature Sensor", formula: "", }, + PidInfo { pid: "99", mode: "01", unit: "°C", pid_name: "Exhaust Gas Temperature Sensor", formula: "", }, + PidInfo { pid: "9A", mode: "01", unit: "", pid_name: "Hybrid/EV Vehicle System Data, Battery, Voltage", formula: "", }, + PidInfo { pid: "9B", mode: "01", unit: "%", pid_name: "Diesel Exhaust Fluid Sensor Data", formula: "100/255 * D", }, + PidInfo { pid: "9C", mode: "01", unit: "", pid_name: "O2 Sensor Data", formula: "", }, + PidInfo { pid: "9D", mode: "01", unit: "g/s", pid_name: "Engine Fuel Rate", formula: "", }, + PidInfo { pid: "9E", mode: "01", unit: "kg/h", pid_name: "Engine Exhaust Flow Rate", formula: "", }, + PidInfo { pid: "9F", mode: "01", unit: "", pid_name: "Fuel System Percentage Use", formula: "", }, + PidInfo { pid: "A1", mode: "01", unit: "ppm", pid_name: "NOx Sensor Corrected Data", formula: "", }, + PidInfo { pid: "A2", mode: "01", unit: "mg/stroke", pid_name: "Cylinder Fuel Rate", formula: "((256 * A)+B) / 32", }, + PidInfo { pid: "A3", mode: "01", unit: "Pa", pid_name: "Evap System Vapor Pressure", formula: "", }, + PidInfo { pid: "A4", mode: "01", unit: "ratio", pid_name: "Transmission Actual Gear", formula: "((256 * C) + D) / 1000", }, + PidInfo { pid: "A5", mode: "01", unit: "%", pid_name: "Commanded Diesel Exhaust Fluid Dosing", formula: "B / 2", }, + PidInfo { pid: "A6", mode: "01", unit: "", pid_name: "Odometer", formula: "(A(2^24) + B(2^16) + C(2^8) + D) / 10", }, + PidInfo { pid: "A7", mode: "01", unit: "", pid_name: "NOx Sensor Concentration Sensors 3 and 4", formula: "", }, + PidInfo { pid: "A8", mode: "01", unit: "", pid_name: "NOx Sensor Corrected Concentration Sensors 3 and 4", formula: "", }, + PidInfo { pid: "A9", mode: "01", unit: "", pid_name: "ABS Disable Switch State", formula: "{A0}= 1:Supported; 0:Unsupported", }, + PidInfo { pid: "C3", mode: "01", unit: "%", pid_name: "Fuel Level Input A/B", formula: "", }, + PidInfo { pid: "C4", mode: "01", unit: "seconds / Count", pid_name: "Exhaust Particulate Control System Diagnostic Time/Count", formula: "", }, + PidInfo { pid: "C5", mode: "01", unit: "kPa", pid_name: "Fuel Pressure A and B", formula: "", }, + PidInfo { pid: "C7", mode: "01", unit: "km", pid_name: "Distance Since Reflash or Module Replacement", formula: "", }, +]; diff --git a/src/lib.rs b/backend/src/lib.rs similarity index 74% rename from src/lib.rs rename to backend/src/lib.rs index 83feaf7..140c30b 100644 --- a/src/lib.rs +++ b/backend/src/lib.rs @@ -1,16 +1,17 @@ -pub mod obd; -pub mod vin; mod cmd; +pub mod dicts; +pub mod obd; mod pid; mod replay; mod response; -mod scalar; +pub mod scalar; +pub mod vin; -pub use pid::*; -pub use response::*; pub use cmd::*; pub use obd::*; +pub use pid::*; +pub use response::*; const CODE_DESC_DB_PATH: &str = "./data/code-descriptions.sqlite"; const MODE22_PIDS_DB_PATH: &str = "./data/model-pids.sqlite"; -const RECORDED_REQEUSTS_DIR: &str = "./data/requests.json"; \ No newline at end of file +const RECORDED_REQEUSTS_DIR: &str = "./data/requests.json"; diff --git a/backend/src/main.rs b/backend/src/main.rs new file mode 100644 index 0000000..83c6bca --- /dev/null +++ b/backend/src/main.rs @@ -0,0 +1,97 @@ +// Prevents additional console window on Windows in release, DO NOT REMOVE!! +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] + +mod bridge; +mod stats; + +use bridge::events::{ + do_send_connection_status, listen_connect_elm, listen_decode_vin, listen_send_pids, + listen_send_ports, +}; +use obdium::OBD; +use stats::{ + critical_frequency_calls, frequent_calls, high_frequency_calls, less_frequent_calls, + once_calls, oxygen_sensors, +}; + +use std::{ + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, Mutex, + }, + thread::sleep, + time::Duration, +}; +use tauri::{async_runtime::spawn, Manager, Window}; + +fn track_data(window: &Arc, obd: &Arc>) { + critical_frequency_calls(window, obd); + high_frequency_calls(window, obd); + frequent_calls(window, obd); + less_frequent_calls(window, obd); + oxygen_sensors(window, obd); + once_calls(window, obd); +} + +fn connect_obd(window: &Window, port: String, baud_rate: u32, protocol: u8) -> Option { + // Try to connect obd + let mut obd = OBD::new(); + + match obd.connect(&port, baud_rate, protocol) { + Ok(()) => { + let band = obd.serial_port_baud_rate().unwrap_or_default(); + let port = obd.serial_port_name().unwrap_or_default(); + + do_send_connection_status( + window, + &obd, + format!("Connected to port {port} on {band} band"), + true, + ); + + Some(obd) + } + Err(error) => { + do_send_connection_status( + window, + &obd, + format!("Failed to connect. Error: {error}"), + false, + ); + + None + } + } +} + +fn main() { + tauri::Builder::default() + .setup(|app| { + let window = app.get_window("main").unwrap(); + let frontend_ready = Arc::new(AtomicBool::new(false)); + + spawn(async move { + listen_decode_vin(&window); + + // Detect when the frontend is loaded + let frontend_ready_listener = Arc::clone(&frontend_ready); + window.listen("frontend-loaded", move |_| { + frontend_ready_listener.store(true, Ordering::SeqCst); + }); + + let window_arc = Arc::new(window); + listen_send_pids(&window_arc); + + while !frontend_ready.load(Ordering::SeqCst) { + sleep(Duration::from_millis(100)); + } + + listen_send_ports(&window_arc); + listen_connect_elm(&window_arc); + }); + + Ok(()) + }) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} diff --git a/src/obd.rs b/backend/src/obd.rs similarity index 85% rename from src/obd.rs rename to backend/src/obd.rs index 2dd0d81..0e0b37e 100644 --- a/src/obd.rs +++ b/backend/src/obd.rs @@ -92,7 +92,7 @@ impl OBD { Self::default() } - pub fn connect(&mut self, port: &str, baud_rate: u32) -> Result<(), Error> { + pub fn connect(&mut self, port: &str, baud_rate: u32, protocol: u8) -> Result<(), Error> { if self.replay_requests { // No connection required return Ok(()); @@ -103,11 +103,104 @@ impl OBD { } self.connection = serialport::new(port, baud_rate) - .timeout(Duration::from_secs(10)) + .timeout(Duration::from_secs(3)) .open() .ok(); - self.init() + if self.connected() { + let initialized = self.init(); + let mut command = match protocol { + 0 => Command::new_at(b"ATSP0"), + 1 => Command::new_at(b"ATSP1"), + 2 => Command::new_at(b"ATSP2"), + 3 => Command::new_at(b"ATSP3"), + 4 => Command::new_at(b"ATSP4"), + 5 => Command::new_at(b"ATSP5"), + 6 => Command::new_at(b"ATSP6"), + 7 => Command::new_at(b"ATSP7"), + 8 => Command::new_at(b"ATSP8"), + 9 => Command::new_at(b"ATSP9"), + _ => return Err(Error::InitFailed), + }; + + self.send_command(&mut command)?; + + initialized + } else { + Err(Error::ConnectionFailed) + } + } + + pub fn disconnect(&mut self) { + if let Some(connection) = self.connection.take() { + drop(connection); + self.connection = None; + } + } + + pub fn connected(&self) -> bool { + self.connection.is_some() + } + + pub fn serial_port_name(&self) -> Option { + match &self.connection { + Some(connection) => connection.name(), + None => None, + } + } + + pub fn serial_port_baud_rate(&self) -> Option { + match &self.connection { + Some(connection) => connection.baud_rate().ok(), + None => None, + } + } + + pub fn get_open_serial_port() -> String { + match serialport::available_ports() { + Ok(ports) => { + for port in ports.iter() { + // test each port with a simple AT command + + if let Ok(mut com) = serialport::new(&port.port_name, 38400) + .timeout(Duration::from_millis(300)) + .open() + { + let _ = com.clear(serialport::ClearBuffer::All); + + if com.write_all(b"ATI\r").is_err() { + continue; + } + + let mut buffer = [0u8; 1]; + let mut response = String::new(); + + loop { + match com.read(&mut buffer) { + Ok(1) => { + let byte = buffer[0]; + response.push(byte as char); + } + Ok(0) => std::thread::sleep(std::time::Duration::from_millis(10)), + Ok(_) => break, + Err(_) => break, + } + } + + let as_string = String::from_utf8_lossy(&buffer); + let cleaned = as_string.trim_matches(|c: char| !c.is_ascii_graphic()); + + if cleaned.ends_with('>') { + return port.port_name.clone(); + } + } + } + } + Err(err) => { + println!("error getting available serial ports: {err}"); + } + } + String::new() } pub fn init(&mut self) -> Result<(), Error> { @@ -117,11 +210,10 @@ impl OBD { // and the ECU wont understand what we're asking for. // Furthermore, causes unexpected behaviour when parsing the response. let commands = vec![ - Command::new_at(b"ATZ"), // Reset all - Command::new_at(b"ATE0"), // Echo off - Command::new_at(b"ATL0"), // Linefeeds off - Command::new_at(b"ATH1"), // Headers on - Command::new_at(b"ATSP0"), // Automatic protocol + Command::new_at(b"ATZ"), // Reset all + Command::new_at(b"ATE0"), // Echo off + Command::new_at(b"ATL0"), // Linefeeds off + Command::new_at(b"ATH1"), // Headers on ]; for mut command in commands { @@ -221,9 +313,12 @@ impl OBD { } cmd.push(b'\r'); - stream - .write_all(&cmd) - .map_err(|_| Error::ELM327WriteError)?; + match stream.write_all(&cmd) { + Ok(()) => (), + + // Connection dropped + Err(_) => self.connection = None, + } Ok(()) } @@ -253,10 +348,11 @@ impl OBD { let ecu_names = self.extract_ecu_names(&response); let escaped = response.clone(); - response = response - .replace(" ", "") - .replace("\n", "") - .replace(format!("{:02X}", payload_size).as_str(), ""); + response = response.replace(" ", "").replace("\n", "").replacen( + format!("{:02X}", payload_size).as_str(), + "", + 1, + ); self.strip_ecu_names(&mut response, ecu_names.as_slice()); @@ -543,12 +639,10 @@ impl OBD { ); } - println!("vin: {vin}"); - - match VIN::new(vin) { + match VIN::new(&vin) { Ok(vin) => Some(vin), Err(err) => { - println!("error when getting vin. {err}"); + println!("error when getting vin {vin}. {err}"); None } } @@ -573,7 +667,7 @@ impl OBD { } match self.send_command(&mut request) { - Ok(_) => {} + Ok(_) => (), Err(err) => { println!( "{}\tAT: '{}' - PID: '{}' ", diff --git a/src/pid/air.rs b/backend/src/pid/air.rs similarity index 86% rename from src/pid/air.rs rename to backend/src/pid/air.rs index c87816c..2ee29d1 100644 --- a/src/pid/air.rs +++ b/backend/src/pid/air.rs @@ -1,8 +1,6 @@ use crate::{ - Command, - SensorNumber, - OBD, - scalar::{Scalar, Unit} + scalar::{Scalar, Unit}, + Command, SensorNumber, OBD, }; #[derive(Debug)] @@ -33,6 +31,11 @@ impl OBD { .map_no_data(|r| Scalar::new(r.a_value() - 40.0, Unit::Celsius)) } + pub fn intake_manifold_abs_pressure(&mut self) -> Scalar { + self.query(Command::new_pid(b"010B")) + .map_no_data(|r| Scalar::new(r.a_value(), Unit::KiloPascal)) + } + pub fn maf_air_flow_rate(&mut self) -> Scalar { self.query(Command::new_pid(b"0110")).map_no_data(|r| { Scalar::new( @@ -52,6 +55,9 @@ impl OBD { .map_no_data(|r| Scalar::new(r.a_value() * 10.0, Unit::GramsPerSecond)) } + // Returns 2 values + // Voltage being given to the sensor + // Short term fuel trim pub fn read_oxygen_sensor(&mut self, sensor: &SensorNumber) -> (Scalar, Scalar) { let command = match sensor { SensorNumber::Sensor1 => Command::new_pid(b"0114"), @@ -78,7 +84,16 @@ impl OBD { ) } - pub fn o2_sensor_air_fuel_ratio(&mut self, sensor: &SensorNumber) -> (Scalar, Scalar) { + // Returns 2 values + // ABCD stands for the bytes in the payload and + // what they represent. + // + // AB (AB Bytes) - Air-Fuel equivalance ratio + // CD (CD Bytes) - Voltage + // + // Unlike read_oxygen_sensor, this doesn't return the + // short term fuel trim. + pub fn read_oxygen_sensor_abcd(&mut self, sensor: &SensorNumber) -> (Scalar, Scalar) { let command = match sensor { SensorNumber::Sensor1 => Command::new_pid(b"0124"), SensorNumber::Sensor2 => Command::new_pid(b"0125"), diff --git a/src/pid/diagnostics.rs b/backend/src/pid/diagnostics.rs similarity index 99% rename from src/pid/diagnostics.rs rename to backend/src/pid/diagnostics.rs index 5054b8b..d0c4be2 100644 --- a/src/pid/diagnostics.rs +++ b/backend/src/pid/diagnostics.rs @@ -2,12 +2,9 @@ use sqlite::State; use std::fmt; use crate::{ - Command, - OBD, - Error, - CODE_DESC_DB_PATH, engine::EngineType, scalar::{Scalar, Unit}, + Command, Error, CODE_DESC_DB_PATH, OBD, }; #[derive(Debug)] diff --git a/src/pid/engine.rs b/backend/src/pid/engine.rs similarity index 95% rename from src/pid/engine.rs rename to backend/src/pid/engine.rs index 35128b6..5529195 100644 --- a/src/pid/engine.rs +++ b/backend/src/pid/engine.rs @@ -1,9 +1,8 @@ use std::fmt; use crate::{ - Command, - SensorNumber, Service, OBD, scalar::{Scalar, Unit}, + Command, SensorNumber, Service, OBD, }; #[derive(PartialEq, Eq)] @@ -80,7 +79,7 @@ impl OBD { .map_no_data(|r| Scalar::new((256.0 * r.a_value()) + r.b_value(), Unit::Seconds)) } - pub fn engine_runtime_diesel(&mut self) -> Scalar { + fn engine_runtime_diesel(&mut self) -> Scalar { let response = self.query(Command::new_pid(b"017F")); if *response.get_payload_size() == 0 { return Scalar::no_data(); @@ -171,6 +170,12 @@ impl OBD { .map_no_data(|r| Scalar::new((256.0 * r.a_value()) + r.b_value(), Unit::NewtonMeters)) } + // Returns 5 values. + // idle - torque at idle + // engine_point_1 - torque at engine point 1 + // engine_point_2 - torque at engine point 2 + // engine_point_3 - torque at engine point 3 + // engine_point_4 - torque at engine point 4 pub fn engine_percent_torque_data(&mut self) -> (Scalar, Scalar, Scalar, Scalar, Scalar) { let response = self.query(Command::new_pid(b"0164")); if *response.get_payload_size() == 0 { diff --git a/src/pid/exhaust.rs b/backend/src/pid/exhaust.rs similarity index 66% rename from src/pid/exhaust.rs rename to backend/src/pid/exhaust.rs index 379454b..8952da7 100644 --- a/src/pid/exhaust.rs +++ b/backend/src/pid/exhaust.rs @@ -1,7 +1,6 @@ use crate::{ - Command, - BankNumber, SensorNumber, OBD, scalar::{Scalar, Unit}, + BankNumber, Command, SensorNumber, OBD, }; impl OBD { @@ -37,23 +36,22 @@ impl OBD { }) } - pub fn boost_pressure_control(&self) -> f32 { - todo!() - } - - pub fn turbocharger_rpm(&self) -> f32 { - todo!() - } + pub fn boost_guage_pressure(&mut self) -> Scalar { + let map = self.intake_manifold_abs_pressure(); + let baro = self.abs_barometric_pressure(); - pub fn turbocharger_temp(&self) -> f32 { - todo!() + // result in kPa, gets converted to PSI. if conversion fails, do no data + // conversion never fail. map and baro will always be Unit::Kilopascal + (map - baro).to(Unit::PSI).unwrap_or(Scalar::no_data()) } - pub fn exhaust_pressure(&self) -> f32 { - todo!() + pub fn turbocharger_rpm(&mut self) -> Scalar { + self.query(Command::new_pid(b"0174")) + .map_no_data(|r| Scalar::new((256.0 * r.a_value()) + r.b_value(), Unit::RPM)) } - pub fn exhaust_gas_temp(&self) -> f32 { - todo!() + // TODO! + pub fn exhaust_gas_temp(&self) -> Scalar { + Scalar::no_data() } } diff --git a/src/pid/fuel.rs b/backend/src/pid/fuel.rs similarity index 96% rename from src/pid/fuel.rs rename to backend/src/pid/fuel.rs index e9443a1..48462ce 100644 --- a/src/pid/fuel.rs +++ b/backend/src/pid/fuel.rs @@ -1,9 +1,8 @@ use std::fmt; use crate::{ - Command, - BankNumber, OBD, - scalar::{Scalar, Unit} + scalar::{Scalar, Unit}, + BankNumber, Command, OBD, }; #[derive(Debug)] @@ -71,7 +70,7 @@ impl FuelSystemStatus { } impl OBD { - pub fn short_term_fuel_trim(&mut self, bank: BankNumber) -> Scalar { + pub fn short_term_fuel_trim(&mut self, bank: &BankNumber) -> Scalar { let mut command = Command::default(); match bank { @@ -83,7 +82,7 @@ impl OBD { .map_no_data(|r| Scalar::new((r.a_value() / 1.28) - 100.0, Unit::Percent)) } - pub fn long_term_fuel_trim(&mut self, bank: BankNumber) -> Scalar { + pub fn long_term_fuel_trim(&mut self, bank: &BankNumber) -> Scalar { let command = match bank { BankNumber::Bank1 => Command::new_pid(b"0107"), BankNumber::Bank2 => Command::new_pid(b"0109"), diff --git a/src/pid/mod.rs b/backend/src/pid/mod.rs similarity index 82% rename from src/pid/mod.rs rename to backend/src/pid/mod.rs index 60ddb3d..b8719fe 100644 --- a/src/pid/mod.rs +++ b/backend/src/pid/mod.rs @@ -3,4 +3,4 @@ pub mod diagnostics; pub mod engine; pub mod exhaust; pub mod fuel; -pub mod sensors; \ No newline at end of file +pub mod sensors; diff --git a/src/pid/sensors.rs b/backend/src/pid/sensors.rs similarity index 98% rename from src/pid/sensors.rs rename to backend/src/pid/sensors.rs index 5f447ff..36a3601 100644 --- a/src/pid/sensors.rs +++ b/backend/src/pid/sensors.rs @@ -1,7 +1,6 @@ use crate::{ - Command, - SensorNumber, OBD, - scalar::{Scalar, Unit} + scalar::{Scalar, Unit}, + Command, SensorNumber, OBD, }; impl OBD { diff --git a/src/replay.rs b/backend/src/replay.rs similarity index 85% rename from src/replay.rs rename to backend/src/replay.rs index 659b084..7b89087 100644 --- a/src/replay.rs +++ b/backend/src/replay.rs @@ -10,13 +10,26 @@ use serde_json::{json, Value}; impl OBD { pub fn record_requests(&mut self, state: bool) { - // clear requests file - if fs::File::create(RECORDED_REQEUSTS_DIR).is_ok() && state { - self.record_requests = state; + if state { + match fs::OpenOptions::new() + .write(true) + .create(true) + .append(true) + .open(RECORDED_REQEUSTS_DIR) + { + Ok(_) => { + self.record_requests = true; + } + Err(e) => { + println!("File creation to save requests failed: {e}. Not recording requests."); + self.record_requests = false; + } + } } else { - println!("file creation to save requests failed. not recording requests."); self.record_requests = false; } + + println!("Recording requests: {state:?}"); } pub fn replay_requests(&mut self, state: bool) { @@ -26,7 +39,8 @@ impl OBD { self.record_requests = false; } - self.replay_requests = state + self.replay_requests = state; + println!("Replaying requests: {state:?}"); } pub(crate) fn save_request(&mut self, request: &Command, response: &Response) { diff --git a/src/response.rs b/backend/src/response.rs similarity index 100% rename from src/response.rs rename to backend/src/response.rs diff --git a/src/scalar.rs b/backend/src/scalar.rs similarity index 84% rename from src/scalar.rs rename to backend/src/scalar.rs index 22f2eb9..2e8710f 100644 --- a/src/scalar.rs +++ b/backend/src/scalar.rs @@ -1,6 +1,11 @@ -use std::{fmt, str::FromStr}; - -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] +use serde::{Deserialize, Serialize}; +use std::{ + fmt, + ops::{Add, Sub}, + str::FromStr, +}; + +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Serialize, Deserialize)] pub enum Unit { Percent, Ratio, @@ -100,6 +105,7 @@ impl Unit { Unit::PartsPerMillion => "ppm", Unit::MiligramsPerStroke => "mg/stroke", Unit::PSI => "PSI", + Unit::NoData => "NO DATA", _ => "", } } @@ -121,6 +127,24 @@ impl fmt::Display for Scalar { } } +// Doesn't matter what unit you are using. +impl Sub for Scalar { + type Output = Scalar; + + fn sub(self, other: Self) -> Self::Output { + Scalar::new(self.value - other.value, self.unit) + } +} + +// Doesn't matter what unit you are using. +impl Add for Scalar { + type Output = Scalar; + + fn add(self, other: Self) -> Self::Output { + Scalar::new(self.value + other.value, self.unit) + } +} + impl Scalar { pub fn new(value: f32, unit: Unit) -> Self { Self { value, unit } @@ -175,6 +199,12 @@ impl Scalar { (NewtonMeters, FootPounds) => Some(Scalar::new(self.value * 0.73756, FootPounds)), (FootPounds, NewtonMeters) => Some(Scalar::new(self.value / 0.73756, NewtonMeters)), + // Pressure + (KiloPascal, PSI) => Some(Scalar::new(self.value / 6.895, Unit::PSI)), + (PSI, KiloPascal) => Some(Scalar::new(self.value * 6.895, Unit::KiloPascal)), + (KiloPascal, Pascal) => Some(Scalar::new(self.value * 1000.0, Unit::Pascal)), + (Pascal, KiloPascal) => Some(Scalar::new(self.value / 1000.0, Unit::KiloPascal)), + (_, _) => None, } } diff --git a/backend/src/stats.rs b/backend/src/stats.rs new file mode 100644 index 0000000..00507d6 --- /dev/null +++ b/backend/src/stats.rs @@ -0,0 +1,543 @@ +use obdium::{scalar::Scalar, BankNumber}; +use obdium::{SensorNumber, Service, OBD}; +use serde::{Deserialize, Serialize}; +use std::{ + sync::{Arc, Mutex}, + time::Duration, +}; +use tauri::{async_runtime::spawn, Window}; +use tokio::time; + +macro_rules! update { + ($win:expr, $($name:expr => $val:expr),* $(,)?) => { + $( + update_card($win, $name, $val); + )* + }; +} + +#[derive(Serialize, Deserialize, Clone)] +struct Card { + name: String, + unit: String, + value: f32, +} + +fn update_card(window: &Window, name: T, scalar: Scalar) +where + T: Into + std::fmt::Debug, +{ + let card = Card { + name: name.into(), + unit: scalar.unit.as_str().to_string().to_uppercase(), + value: scalar.value.round(), + }; + + window.emit("update-card", card).unwrap(); +} + +pub fn critical_frequency_calls(window: &Arc, obd: &Arc>) { + let window = Arc::clone(window); + let obd = Arc::clone(obd); + spawn(async move { + let mut interval = time::interval(Duration::from_millis(500)); + loop { + interval.tick().await; + + let mut obd = obd.lock().unwrap(); + if !obd.connected() { + break; + } + + let rpm = obd.rpm(); + let turbocharger_rpm = obd.turbocharger_rpm(); + let vehicle_speed = obd.vehicle_speed(); + + drop(obd); + + update!( + &window, + "Vehicle Speed" => vehicle_speed, + "Engine Speed" => rpm, + "Turbocharger RPM" => turbocharger_rpm, + ); + } + }); +} + +pub fn high_frequency_calls(window: &Arc, obd: &Arc>) { + let window = Arc::clone(window); + let obd = Arc::clone(obd); + + spawn(async move { + let mut interval = time::interval(Duration::from_secs(1)); + let mut cycle = 0; + loop { + interval.tick().await; + cycle = (cycle + 1) % 5; + + match cycle { + 0 => { + // Cycle 1 + let ( + maf_air_flow_rate, + engine_fuel_rate, + engine_oil_pressure, + drivers_demand_engine_torque, + actual_engine_torque, + ) = { + let mut obd = obd.lock().unwrap(); + if !obd.connected() { + break; + } + + ( + obd.maf_air_flow_rate(), + obd.engine_fuel_rate(), + obd.engine_oil_pressure(), + obd.drivers_demand_engine_torque(), + obd.actual_engine_torque(), + ) + }; + + update!( + &window, + "MAF Airflow Rate" => maf_air_flow_rate, + "Engine Fuel Rate" => engine_fuel_rate, + "Engine Oil Pressure" => engine_oil_pressure, + "Drivers Demand Engine Torque" => drivers_demand_engine_torque, + "Actual Engine Torque" => actual_engine_torque, + ); + } + 1 => { + // Cycle 2 + let ( + engine_load, + ref_engine_torque, + fuel_pressure, + fuel_rail_pressure, + fuel_rail_gauge_pressure, + ) = { + let mut obd = obd.lock().unwrap(); + ( + obd.engine_load(), + obd.reference_engine_torque(), + obd.fuel_pressure(), + obd.fuel_rail_pressure(), + obd.fuel_rail_guage_pressure(), + ) + }; + + update!( + &window, + "Engine Load" => engine_load, + "Reference Engine Torque" => ref_engine_torque, + "Fuel Pressure" => fuel_pressure, + "Fuel Rail Pressure" => fuel_rail_pressure, + "Fuel Rail Gauge Pressure" => fuel_rail_gauge_pressure, + ); + } + 2 => { + // Cycle 3 + let ( + cylinder_fuel_rate, + max_air_flow_rate_maf, + timing_advance, + boost_guage_pressure, + ) = { + let mut obd = obd.lock().unwrap(); + ( + obd.cylinder_fuel_rate(), + obd.max_air_flow_rate_from_maf(), + obd.timing_advance(), + obd.boost_guage_pressure(), + ) + }; + + update!( + &window, + "Cylinder Fuel Rate" => cylinder_fuel_rate, + "MAF Maximum Airflow Rate" => max_air_flow_rate_maf, + "Timing Advance" => timing_advance, + "Boost Gauge Pressure" => boost_guage_pressure, + ); + } + 3 => { + // Cycle 4 + let ( + throttle_pos, + rel_throttle_pos, + abs_throttle_b, + abs_throttle_c, + accel_pedal_d, + ) = { + let mut obd = obd.lock().unwrap(); + ( + obd.throttle_position(), + obd.relative_throttle_pos(), + obd.abs_throttle_position_b(), + obd.abs_throttle_position_c(), + obd.acc_pedal_position_d(), + ) + }; + + update!( + &window, + "Throttle Pos." => throttle_pos, + "Relative Throttle Pos." => rel_throttle_pos, + "Abs. Throttle Pos. (D)" => abs_throttle_b, + "Abs. Throttle Pos. (C)" => abs_throttle_c, + "Accelerator Pedal Pos. (D)" => accel_pedal_d, + ); + } + 4 => { + // Cycle 5 + let (acc_pedal_pos_e, acc_pedal_pos_f, engine_torque_data) = { + let mut obd = obd.lock().unwrap(); + ( + obd.acc_pedal_position_e(), + obd.acc_pedal_position_f(), + obd.engine_percent_torque_data(), + ) + }; + + update!( + &window, + "Idle Engine Torque" => engine_torque_data.0, + "Engine Point 1 Torque" => engine_torque_data.1, + "Engine Point 2 Torque" => engine_torque_data.2, + "Engine Point 3 Torque" => engine_torque_data.3, + "Engine Point 4 Torque" => engine_torque_data.4, + "Accelerator Pedal Pos. (E)" => acc_pedal_pos_e, + "Accelerator Pedal Pos. (F)" => acc_pedal_pos_f, + ); + } + _ => unreachable!(), + } + } + }); +} + +pub fn frequent_calls(window: &Arc, obd: &Arc>) { + let window = Arc::clone(window); + let obd = Arc::clone(obd); + spawn(async move { + let mut interval = time::interval(Duration::from_secs(4)); + let mut cycles = 0; + loop { + interval.tick().await; + + cycles = (cycles + 1) % 2; + match cycles { + 0 => { + let stft_bank_1 = { + let mut obd = obd.lock().unwrap(); + if !obd.connected() { + break; + } + obd.short_term_fuel_trim(&BankNumber::Bank1) + }; + + update!(&window, "Short Term Fuel Trim (Bank 1)" => stft_bank_1); + } + 1 => { + let stft_bank_2 = { + let mut obd = obd.lock().unwrap(); + obd.short_term_fuel_trim(&BankNumber::Bank2) + }; + + update!( + &window, + "Short Term Fuel Trim (Bank 2)" => stft_bank_2, + ); + } + _ => unreachable!(), + } + } + }); +} + +pub fn less_frequent_calls(window: &Arc, obd: &Arc>) { + let window = Arc::clone(window); + let obd = Arc::clone(obd); + spawn(async move { + let mut interval = time::interval(Duration::from_secs(3)); + let mut cycles = 0; + loop { + interval.tick().await; + cycles = (cycles + 1) % 4; + + match cycles { + 0 => { + let ( + ltft_bank_1, + ltft_bank_2, + coolant_temp, + coolant_temp_sensors, + engine_oil_temp, + engine_oil_temp_ext, + engine_oil_temp_sensors, + ) = { + let mut obd = obd.lock().unwrap(); + if !obd.connected() { + break; + } + ( + obd.long_term_fuel_trim(&BankNumber::Bank1), + obd.long_term_fuel_trim(&BankNumber::Bank2), + obd.coolant_temp(), + obd.coolant_temp_sensors(), + obd.engine_oil_temp(Service::Mode01), + obd.engine_oil_temp(Service::Mode22), + obd.engine_oil_temp_sensors(), + ) + }; + + update!( + &window, + "Long Term Fuel Trim (Bank 1)" => ltft_bank_1, + "Long Term Fuel Trim (Bank 2)" => ltft_bank_2, + "Coolant Temp." => coolant_temp, + "Engine Oil Temp. (Mode 22)" => engine_oil_temp_ext, + "Engine Oil Temp. (Mode 01)" => engine_oil_temp, + "Coolant Temp. (Sensors: A)" => coolant_temp_sensors.0, + "Coolant Temp. (Sensors: B)" => coolant_temp_sensors.1, + "Engine Oil Temp. (Sensors: A)" => engine_oil_temp_sensors.0, + "Engine Oil Temp. (Sensors: B)" => engine_oil_temp_sensors.1, + ); + } + 1 => { + let ( + commanded_egr, + egr_error, + catalyst_temp_b1_s1, + catalyst_temp_b1_s2, + catalyst_temp_b2_s1, + catalyst_temp_b2_s2, + ) = { + let mut obd = obd.lock().unwrap(); + ( + obd.commanded_egr(), + obd.egr_error(), + obd.catalyst_temp(BankNumber::Bank1, SensorNumber::Sensor1), + obd.catalyst_temp(BankNumber::Bank1, SensorNumber::Sensor2), + obd.catalyst_temp(BankNumber::Bank2, SensorNumber::Sensor1), + obd.catalyst_temp(BankNumber::Bank2, SensorNumber::Sensor2), + ) + }; + + update!( + &window, + "Catalyst Temp. (Bank 1: Sensor 1)" => catalyst_temp_b1_s1, + "Catalyst Temp. (Bank 1: Sensor 2)" => catalyst_temp_b1_s2, + "Catalyst Temp. (Bank 2: Sensor 1)" => catalyst_temp_b2_s1, + "Catalyst Temp. (Bank 2: Sensor 2)" => catalyst_temp_b2_s2, + "Commanded EGR" => commanded_egr, + "EGR Error" => egr_error, + ); + } + 2 => { + let ( + barometric_pressure, + ambient_air_temp, + max_values_for, + fuel_injection_timing, + ) = { + let mut obd = obd.lock().unwrap(); + ( + obd.abs_barometric_pressure(), + obd.ambient_air_temp(), + obd.max_values_for(), + obd.fuel_injection_timing(), + ) + }; + + update!( + &window, + "Absolute Barometric Pressure" => barometric_pressure, + "Ambient Air Temp." => ambient_air_temp, + "Fuel Injection Timing" => fuel_injection_timing, + "Maximum AFR Value" => max_values_for.0, + "Maximum O2 Sensor Voltage" => max_values_for.1, + "Maximum O2 Sensor Current" => max_values_for.2, + "Maximum Intake Abs. Pressure" => max_values_for.3, + ); + } + 3 => { + let ( + commanded_evap_purge, + evap_sys_vapor_pressure, + control_mod_voltage, + engine_runtime, + ) = { + let mut obd = obd.lock().unwrap(); + ( + obd.commanded_evap_purge(), + obd.evap_system_vapor_pressure(), + obd.control_module_voltage(), + obd.engine_runtime(), + ) + }; + + update!( + &window, + "Commanded EVAP Purge" => commanded_evap_purge, + "EVAP System Vapor Pressure" =>evap_sys_vapor_pressure, + "Control Module Voltage" => control_mod_voltage, + "Engine Runtime (Session)" => engine_runtime, + ); + } + _ => unreachable!(), + } + } + }); +} + +pub fn oxygen_sensors(window: &Arc, obd: &Arc>) { + let window = Arc::clone(window); + let obd = Arc::clone(obd); + spawn(async move { + let mut interval = time::interval(Duration::from_secs(6)); + let mut cycles = 0; + loop { + interval.tick().await; + cycles = (cycles + 1) % 4; + + match cycles { + 0 => { + let (o2_sensor_1, o2_sensor_2, o2_sensor_3, o2_sensor_4) = { + let mut obd = obd.lock().unwrap(); + if !obd.connected() { + break; + } + ( + obd.read_oxygen_sensor(&SensorNumber::Sensor1), + obd.read_oxygen_sensor(&SensorNumber::Sensor2), + obd.read_oxygen_sensor(&SensorNumber::Sensor3), + obd.read_oxygen_sensor(&SensorNumber::Sensor4), + ) + }; + + update!( + &window, + "O2 Sensor (1) Voltage (1)" => o2_sensor_1.0, + "O2 Sensor (1) STFT" => o2_sensor_1.1, + "O2 Sensor (2) Voltage (1)" => o2_sensor_2.0, + "O2 Sensor (2) STFT" => o2_sensor_2.1, + "O2 Sensor (3) Voltage (1)" => o2_sensor_3.0, + "O2 Sensor (3) STFT" => o2_sensor_3.1, + "O2 Sensor (4) Voltage (1)" => o2_sensor_4.0, + "O2 Sensor (4) STFT" => o2_sensor_4.1, + ); + } + 1 => { + let ( + o2_sensor_af_ratio_1, + o2_sensor_af_ratio_2, + o2_sensor_af_ratio_3, + o2_sensor_af_ratio_4, + ) = { + let mut obd = obd.lock().unwrap(); + ( + obd.read_oxygen_sensor_abcd(&SensorNumber::Sensor1), + obd.read_oxygen_sensor_abcd(&SensorNumber::Sensor2), + obd.read_oxygen_sensor_abcd(&SensorNumber::Sensor3), + obd.read_oxygen_sensor_abcd(&SensorNumber::Sensor4), + ) + }; + + update!( + &window, + "O2 Sensor (1) AFR" => o2_sensor_af_ratio_1.0, + "O2 Sensor (1) Voltage (2)" => o2_sensor_af_ratio_1.1, + "O2 Sensor (2) AFR" => o2_sensor_af_ratio_2.0, + "O2 Sensor (2) Voltage (2)" => o2_sensor_af_ratio_2.1, + "O2 Sensor (3) AFR" => o2_sensor_af_ratio_3.0, + "O2 Sensor (3) Voltage (2)" => o2_sensor_af_ratio_3.1, + "O2 Sensor (4) AFR" => o2_sensor_af_ratio_4.0, + "O2 Sensor (4) Voltage (2)" => o2_sensor_af_ratio_4.1, + ); + } + 2 => { + let (o2_sensor_5, o2_sensor_6, o2_sensor_7, o2_sensor_8) = { + let mut obd = obd.lock().unwrap(); + ( + obd.read_oxygen_sensor(&SensorNumber::Sensor5), + obd.read_oxygen_sensor(&SensorNumber::Sensor6), + obd.read_oxygen_sensor(&SensorNumber::Sensor7), + obd.read_oxygen_sensor(&SensorNumber::Sensor8), + ) + }; + + update!( + &window, + "O2 Sensor (5) Voltage (1)" => o2_sensor_5.0, + "O2 Sensor (5) STFT" => o2_sensor_5.1, + "O2 Sensor (6) Voltage (1)" => o2_sensor_6.0, + "O2 Sensor (6) STFT" => o2_sensor_6.1, + "O2 Sensor (7) Voltage (1)" => o2_sensor_7.0, + "O2 Sensor (7) STFT" => o2_sensor_7.1, + "O2 Sensor (8) Voltage (1)" => o2_sensor_8.0, + "O2 Sensor (8) STFT" => o2_sensor_8.1, + ); + } + 3 => { + let ( + o2_sensor_af_ratio_5, + o2_sensor_af_ratio_6, + o2_sensor_af_ratio_7, + o2_sensor_af_ratio_8, + ) = { + let mut obd = obd.lock().unwrap(); + ( + obd.read_oxygen_sensor_abcd(&SensorNumber::Sensor5), + obd.read_oxygen_sensor_abcd(&SensorNumber::Sensor6), + obd.read_oxygen_sensor_abcd(&SensorNumber::Sensor7), + obd.read_oxygen_sensor_abcd(&SensorNumber::Sensor8), + ) + }; + + update!( + &window, + "O2 Sensor (5) AFR" => o2_sensor_af_ratio_5.0, + "O2 Sensor (5) Voltage (2)" => o2_sensor_af_ratio_5.1, + "O2 Sensor (6) AFR" => o2_sensor_af_ratio_6.0, + "O2 Sensor (6) Voltage (2)" => o2_sensor_af_ratio_6.1, + "O2 Sensor (7) AFR" => o2_sensor_af_ratio_7.0, + "O2 Sensor (7) Voltage (2)" => o2_sensor_af_ratio_7.1, + "O2 Sensor (8) AFR" => o2_sensor_af_ratio_8.0, + "O2 Sensor (8) Voltage (2)" => o2_sensor_af_ratio_8.1, + ); + } + _ => unreachable!(), + } + } + }); +} + +pub fn once_calls(window: &Arc, obd: &Arc>) { + // Once calls + let window = Arc::clone(window); + let obd = Arc::clone(obd); + spawn(async move { + let mut obd = obd.lock().unwrap(); + let warm_ups = obd.warm_ups_since_codes_cleared(); + let dist_since = obd.distance_traveled_since_codes_cleared(); + let dist_with = obd.distance_traveled_with_mil(); + let time_since = obd.time_since_codes_cleared(); + let time_with = obd.time_run_with_mil(); + let odometer = obd.odometer(); + let ethanol_fuel_percent = obd.ethanol_fuel_percentage(); + + update!( + &window, + "Warm-Ups Since Codes Cleared" => warm_ups, + "Dist. Since Codes Cleared" => dist_since, + "Dist. With Check Engine Light" => dist_with, + "Time Since Codes Cleared" => time_since, + "Time With Check Engine Light" => time_with, + "Odometer" => odometer, + "Ethanol Fuel Percentage" => ethanol_fuel_percent, + ); + }); +} diff --git a/src/vin/attributes.rs b/backend/src/vin/attributes.rs similarity index 92% rename from src/vin/attributes.rs rename to backend/src/vin/attributes.rs index 82b6c60..6632f20 100644 --- a/src/vin/attributes.rs +++ b/backend/src/vin/attributes.rs @@ -1,3 +1,4 @@ +use chrono::Datelike; use sqlite::State; use std::str::FromStr; @@ -11,9 +12,8 @@ impl VIN { where T::Err: std::fmt::Debug, { - let schema_id = self.get_vin_schema_id()?; let key = self.as_key(); - let data = self.query_pattern(schema_id, element_id, key)?; + let data = self.query_pattern(element_id, key)?; data.4.parse::().map_err(|_| Error::ParseError) } @@ -42,7 +42,7 @@ impl VIN { let vin = self.get_vin(); let pos10 = vin.chars().nth(9).unwrap_or('\0'); - let model_year = match pos10 { + let mut model_year = match pos10 { 'A'..='H' => 2010 + (pos10 as i32) - ('A' as i32), 'J'..='N' => 2010 + (pos10 as i32) - ('A' as i32) - 1, 'P' => 2023, @@ -58,29 +58,34 @@ impl VIN { } }; - // let mut car_lt = false; - // let vehicle_type_id = self.get_vehicle_type_id()?; - // let truck_type_id = self.get_truck_type_id()?; + let mut car_lt = false; + let vehicle_type_id = self.get_vehicle_type_id()?; + let truck_type_id = self.get_truck_type_id()?; - // if (2..=7).contains(&vehicle_type_id) || (vehicle_type_id == 3 && truck_type_id == 1) { - // car_lt = true; - // } + if (2..=7).contains(&vehicle_type_id) || (vehicle_type_id == 3 && truck_type_id == 1) { + car_lt = true; + } - // let pos7 = vin.chars().nth(6).unwrap_or('\0'); + let pos7 = vin.chars().nth(6).unwrap_or('\0'); - // if car_lt { - // if let '0'..='9' = pos7 { - // model_year -= 30; - // } - // } + if car_lt { + if let '0'..='9' = pos7 { + model_year -= 30; + } + } - // if model_year > chrono::Utc::now().year() + 1 { - // model_year -= 30; - // } + if model_year > chrono::Utc::now().year() + 1 { + model_year -= 30; + } Ok(model_year) } + pub fn get_vehicle_manufacturer(&self) -> Result { + let manufactur_id = self.get_manufacturer_id()?; + self.lookup_name_from_id("Manufacturer", manufactur_id) + } + pub fn get_engine_model(&self) -> Result { self.get_attribute_id_from_pattern::(ElementId::EngineModel) } diff --git a/src/vin/element_ids.rs b/backend/src/vin/element_ids.rs similarity index 100% rename from src/vin/element_ids.rs rename to backend/src/vin/element_ids.rs diff --git a/src/vin/mod.rs b/backend/src/vin/mod.rs similarity index 100% rename from src/vin/mod.rs rename to backend/src/vin/mod.rs diff --git a/src/vin/parser.rs b/backend/src/vin/parser.rs similarity index 94% rename from src/vin/parser.rs rename to backend/src/vin/parser.rs index dcceef3..6e59d0b 100644 --- a/src/vin/parser.rs +++ b/backend/src/vin/parser.rs @@ -81,7 +81,6 @@ impl VIN { } } - _vin.get_model_year()?; _vin.checksum()?; _vin.get_wmi(); @@ -223,8 +222,16 @@ impl VIN { pub(crate) fn connect_to_vpic_db(&mut self) -> Result<&Connection, Error> { if self.vpic_db_con.is_none() { - let conn = Connection::open(VPIC_DB_PATH).map_err(|_| Error::VPICConnectFailed); - self.vpic_db_con = conn.ok(); + match Connection::open(VPIC_DB_PATH) { + Ok(con) => { + self.vpic_db_con = Some(con); + return self.vpic_connection(); + } + Err(err) => { + println!("error: {err}"); + return Err(Error::VPICConnectFailed); + } + } } self.vpic_connection() diff --git a/src/vin/pattern.rs b/backend/src/vin/pattern.rs similarity index 77% rename from src/vin/pattern.rs rename to backend/src/vin/pattern.rs index a88273f..797fba0 100644 --- a/src/vin/pattern.rs +++ b/backend/src/vin/pattern.rs @@ -89,6 +89,32 @@ impl VIN { key_chars.next().is_none() } + pub fn get_organization_id(&self) -> Result { + let con = self.vpic_connection()?; + let query = "SELECT * FROM Wmi_VinSchema WHERE WmiId = ? and VinSchemaId = ?"; + let wmi_id = self.get_wmi_id()?; + let vin_schema_id = self.get_vin_schema_id()?; + let mut statement = con + .prepare(query) + .map_err(|_| Error::VPICQueryError(query))?; + + statement + .bind((1, wmi_id)) + .map_err(|_| Error::VPICQueryError(query))?; + + statement + .bind((2, vin_schema_id)) + .map_err(|_| Error::VPICQueryError(query))?; + + if let Ok(State::Row) = statement.next() { + statement + .read::("OrgId") + .map_err(|_| Error::VPICQueryError(query)) + } else { + Err(Error::NoResultsFound(query)) + } + } + /// Returns a row from Pattern table /// that matches conditions: /// 1. Schema ID @@ -96,40 +122,54 @@ impl VIN { /// 3. Key matches pattern 'Keys' pub(crate) fn query_pattern( &self, - vin_schema_id: i64, element_id: ElementId, key: &str, ) -> Result<(i64, i64, String, i64, String), Error> { let con = self.vpic_connection()?; - let query = "SELECT * FROM Pattern WHERE VinSchemaId = ? and ElementId = ?"; + let possible_vin_schema_ids = self.get_similiar_vin_schema_ids()?; + let placeholders = possible_vin_schema_ids + .iter() + .map(|_| "?") + .collect::>() + .join(", "); + let query = format!( + "SELECT * FROM Pattern WHERE VinSchemaId IN ({}) AND ElementId = ?", + placeholders + ); let mut statement = con .prepare(query) - .map_err(|_| Error::VPICQueryError(query))?; + .map_err(|_| Error::VPICQueryError("query pattern"))?; - statement - .bind((1, vin_schema_id)) - .map_err(|_| Error::VPICQueryError(query))?; + for (i, id) in possible_vin_schema_ids.iter().enumerate() { + statement + .bind((i + 1, *id)) + .map_err(|_| Error::VPICQueryError("query pattern"))?; + } statement - .bind((2, element_id.as_i64())) - .map_err(|_| Error::VPICQueryError(query))?; + .bind((possible_vin_schema_ids.len() + 1, element_id.as_i64())) + .map_err(|_| Error::VPICQueryError("query pattern"))?; while let Ok(State::Row) = statement.next() { let pattern = statement .read::("Keys") - .map_err(|_| Error::VPICQueryError(query))?; + .map_err(|_| Error::VPICQueryError("query pattern"))?; let pattern_sql_like = pattern.replace("*", "_") + "%"; // simulate MSSQL logic if VIN::match_pattern(key, &pattern_sql_like) { let pattern_id = statement .read::("Id") - .map_err(|_| Error::VPICQueryError(query))?; + .map_err(|_| Error::VPICQueryError("query pattern"))?; let attribute_id = statement .read::("AttributeId") - .map_err(|_| Error::VPICQueryError(query))?; + .map_err(|_| Error::VPICQueryError("query pattern"))?; + + let vin_schema_id = statement + .read::("VinSchemaId") + .map_err(|_| Error::VPICQueryError("query pattern"))?; return Ok(( pattern_id, @@ -141,7 +181,23 @@ impl VIN { } } - Err(Error::NoResultsFound(query)) + // // Do not try any other possible vin_schema_ids + // if !retry { + // return Err(Error::NoResultsFound(query)) + // } + + // // WORST CASE - VIN_SCHEMA_ID PROVIDED WILL YIELD 0 RESULTS + // // WE SHOULD ATLEAST TRY ANY OTHER VIN_SCHEMA_ID THAT HAVE THE + // // SAME ORGID + + // // retry for every possible vin_schema_id + // for possible_vin_schema_id in possible_vin_schema_ids { + // if let Ok(row) = self.query_pattern(possible_vin_schema_id, element_id, key, false) { + // return Ok(row); + // } + // } + + Err(Error::NoResultsFound("query pattern")) } pub(crate) fn query_vspec_pattern( @@ -259,10 +315,6 @@ impl VIN { Ok(id) => id, Err(_) => return -1, }; - let vin_schema_id = match self.get_vin_schema_id() { - Ok(id) => id, - Err(_) => return -1, - }; let con = match self.vpic_connection() { Ok(c) => c, Err(_) => return -1, @@ -278,6 +330,28 @@ impl VIN { return -1; } + // Check if vspec_schema_id yields only one row. + // If so, this is the only option, return it. + let mut rows = 0; + let mut last_pattern_id = 0; + while let Ok(State::Row) = statement.next() { + rows+=1; + if rows > 1 { + break; + } else { + last_pattern_id = match statement.read::("Id") { + Ok(id) => id, + Err(_) => continue, + }; + } + } + + if rows == 1 { + return last_pattern_id; + } else { + statement.reset().ok(); + } + while let Ok(State::Row) = statement.next() { let pattern_id = match statement.read::("Id") { Ok(id) => id, @@ -310,7 +384,7 @@ impl VIN { // query pattern with schema id and key_element_id // compare key_attribute to the attribute from schema_id if let Ok(element_id) = ElementId::try_from(key_element_id as u16) { - if let Ok(data) = self.query_pattern(vin_schema_id, element_id, vin_key) { + if let Ok(data) = self.query_pattern(element_id, vin_key) { if data.4 == key_attribute { return pattern_id; } diff --git a/src/vin/schema.rs b/backend/src/vin/schema.rs similarity index 82% rename from src/vin/schema.rs rename to backend/src/vin/schema.rs index 2a848a5..cef1409 100644 --- a/src/vin/schema.rs +++ b/backend/src/vin/schema.rs @@ -70,6 +70,7 @@ impl VIN { }; if matched_schema_ids.contains(&schema_id) { + println!("contains"); return schema_id; } } @@ -86,12 +87,41 @@ impl VIN { pub fn get_model_id(&self) -> Result { let key = self.as_key(); - let vin_schema_id = self.get_vin_schema_id()?; - let data = self.query_pattern(vin_schema_id, ElementId::VehicleModel, key)?; + let data = self.query_pattern(ElementId::VehicleModel, key)?; data.4.parse().map_err(|_| Error::ParseError) } + /// Similiar means they have the same OrgId as each other + pub fn get_similiar_vin_schema_ids(&self) -> Result, Error> { + let org_id = self.get_organization_id()?; + let wmi_id = self.get_wmi_id()?; + + let con = self.vpic_connection()?; + let query = "SELECT * FROM Wmi_VinSchema WHERE WmiId = ? and OrgId = ?"; + let mut statement = con + .prepare(query) + .map_err(|_| Error::VPICQueryError(query))?; + + statement + .bind((1, wmi_id)) + .map_err(|_| Error::VPICQueryError(query))?; + + statement + .bind((2, org_id)) + .map_err(|_| Error::VPICQueryError(query))?; + + let mut schema_ids = Vec::new(); + while let Ok(State::Row) = statement.next() { + let vin_schema_id = statement + .read::("VinSchemaId") + .map_err(|_| Error::VPICQueryError(query))?; + schema_ids.push(vin_schema_id); + } + + Ok(schema_ids) + } + pub fn get_vspec_schema_id(&self) -> Result { // query VehicleSpecSchema with MakeId // save all rows 'Id' @@ -103,6 +133,7 @@ impl VIN { let con = self.vpic_connection()?; let make_id = self.get_make_id()?; let model_id = self.get_model_id()?; + println!("model id: {}", model_id); let mut matched_spec_schema_ids = Vec::new(); let vspec_schema_id = *self.vspec_schema_id.get_or_init(|| { diff --git a/src/vin/wmi.rs b/backend/src/vin/wmi.rs similarity index 96% rename from src/vin/wmi.rs rename to backend/src/vin/wmi.rs index 6c16c49..3b0f4f7 100644 --- a/src/vin/wmi.rs +++ b/backend/src/vin/wmi.rs @@ -101,15 +101,15 @@ impl VIN { } pub fn get_make_id(&self) -> Result { - let wmi = self.get_wmi(); + let wmi_id = self.get_wmi_id()?; let con = self.vpic_connection()?; - let query = "SELECT MakeId FROM Wmi WHERE Wmi = ?"; + let query = "SELECT MakeId FROM Wmi_Make WHERE WmiId = ?"; let mut statement = con .prepare(query) .map_err(|_| Error::VPICQueryError(query))?; statement - .bind((1, wmi)) + .bind((1, wmi_id)) .map_err(|_| Error::VPICQueryError(query))?; match statement.next() { diff --git a/backend/tauri.conf.json b/backend/tauri.conf.json new file mode 100644 index 0000000..cf00b5c --- /dev/null +++ b/backend/tauri.conf.json @@ -0,0 +1,45 @@ +{ + "$schema": "https://schema.tauri.app/config/1", + "build": { + "devPath": "../frontend", + "distDir": "../frontend", + "withGlobalTauri": true + }, + "package": { + "productName": "obdium", + "version": "0.1.0" + }, + "tauri": { + "allowlist": { + "all": false, + "shell": { + "all": false, + "open": true + } + }, + "windows": [ + { + "title": "OBDium", + "height": 700, + "width": 1200, + "minHeight": 400, + "minWidth": 1025 + } + ], + "security": { + "csp": null + }, + "bundle": { + "active": true, + "targets": "all", + "identifier": "com.obdium.app", + "icon": [ + "icons/32x32.png", + "icons/128x128.png", + "icons/128x128@2x.png", + "icons/icon.icns", + "icons/icon.ico" + ] + } + } +} diff --git a/data/requests.json b/data/requests.json deleted file mode 100644 index d7a7100..0000000 --- a/data/requests.json +++ /dev/null @@ -1,554 +0,0 @@ -[ - { - "played": false, - "request": "ATZ", - "request_type": "ATCommand", - "response": "\r\rELM327 v1.5\r\r" - }, - { - "played": false, - "request": "ATE0", - "request_type": "ATCommand", - "response": "ATE0\rOK\r\r" - }, - { - "played": false, - "request": "ATL0", - "request_type": "ATCommand", - "response": "OK\r\r" - }, - { - "played": false, - "request": "ATH1", - "request_type": "ATCommand", - "response": "OK\r\r" - }, - { - "played": false, - "request": "ATSP0", - "request_type": "ATCommand", - "response": "OK\r\r" - }, - { - "played": true, - "request": "0100", - "request_type": "PIDCommand", - "response": "\n7EA 06 41 00 98 3A 80 13 \n7E8 06 41 00 BE 3F A8 13 \n\n" - }, - { - "played": true, - "request": "0120", - "request_type": "PIDCommand", - "response": "7EA 06 41 20 80 01 A0 01 \n7E8 06 41 20 90 15 B0 15 \n\n" - }, - { - "played": true, - "request": "0140", - "request_type": "PIDCommand", - "response": "7EA 06 41 40 44 CC 00 21 \n7E8 06 41 40 7A 1C 80 00 \n\n" - }, - { - "played": true, - "request": "0160", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0180", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "01A0", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "01C0", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0101", - "request_type": "PIDCommand", - "response": "7E8 06 41 01 00 07 A1 00 \n\n" - }, - { - "played": true, - "request": "0101", - "request_type": "PIDCommand", - "response": "7E8 06 41 01 00 07 A1 00 \n\n" - }, - { - "played": true, - "request": "0101", - "request_type": "PIDCommand", - "response": "7E8 06 41 01 00 07 A1 00 \n\n" - }, - { - "played": true, - "request": "011C", - "request_type": "PIDCommand", - "response": "7E8 03 41 1C 06 \n\n" - }, - { - "played": true, - "request": "011E", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0142", - "request_type": "PIDCommand", - "response": "7E8 04 41 42 39 C1 \n\n" - }, - { - "played": true, - "request": "0121", - "request_type": "PIDCommand", - "response": "7E8 04 41 21 00 00 \n\n" - }, - { - "played": true, - "request": "014D", - "request_type": "PIDCommand", - "response": "7E8 04 41 4D 00 00 \n\n" - }, - { - "played": true, - "request": "014E", - "request_type": "PIDCommand", - "response": "7E8 04 41 4E 00 5C \n\n" - }, - { - "played": true, - "request": "0130", - "request_type": "PIDCommand", - "response": "7E8 03 41 30 04 \n\n" - }, - { - "played": true, - "request": "AT DP", - "request_type": "ATCommand", - "response": "AUTO, ISO 15765-4 (CAN 11/500) \r\r" - }, - { - "played": true, - "request": "0101", - "request_type": "PIDCommand", - "response": "7E8 06 41 01 00 07 A1 00 \n\n" - }, - { - "played": true, - "request": "0101", - "request_type": "PIDCommand", - "response": "7E8 06 41 01 00 07 A1 00 \n\n" - }, - { - "played": true, - "request": "0101", - "request_type": "PIDCommand", - "response": "7E8 06 41 01 00 07 A1 00 \n\n" - }, - { - "played": true, - "request": "0101", - "request_type": "PIDCommand", - "response": "7E8 06 41 01 00 07 A1 00 \n\n" - }, - { - "played": true, - "request": "010C", - "request_type": "PIDCommand", - "response": "7E8 04 41 0C 00 00 \n\n" - }, - { - "played": true, - "request": "0104", - "request_type": "PIDCommand", - "response": "7E8 03 41 04 57 \n\n" - }, - { - "played": true, - "request": "0167", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0105", - "request_type": "PIDCommand", - "response": "7E8 03 41 05 44 \n\n" - }, - { - "played": true, - "request": "019D", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0101", - "request_type": "PIDCommand", - "response": "7E8 06 41 01 00 07 A1 00 \n\n" - }, - { - "played": true, - "request": "011F", - "request_type": "PIDCommand", - "response": "7E8 04 41 1F 00 26 \n\n" - }, - { - "played": true, - "request": "017F", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "01A6", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0167", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "015C", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "221154", - "request_type": "Arbitrary", - "response": "NO DATA" - }, - { - "played": true, - "request": "221470", - "request_type": "Arbitrary", - "response": "NO DATA" - }, - { - "played": true, - "request": "0161", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0162", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0163", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0164", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0106", - "request_type": "PIDCommand", - "response": "7E8 03 41 06 80 \n\n" - }, - { - "played": true, - "request": "0108", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0107", - "request_type": "PIDCommand", - "response": "7E8 03 41 07 79 \n\n" - }, - { - "played": true, - "request": "0109", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0103", - "request_type": "PIDCommand", - "response": "7E8 04 41 03 04 00 \n\n" - }, - { - "played": true, - "request": "010A", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "012F", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0122", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0123", - "request_type": "PIDCommand", - "response": "7E8 04 41 23 1A 0E \n\n" - }, - { - "played": true, - "request": "0151", - "request_type": "PIDCommand", - "response": "7E8 03 41 51 01 \n\n" - }, - { - "played": true, - "request": "0152", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "015D", - "request_type": "PIDCommand", - "response": "7E8 04 41 5D 66 00 \n\n" - }, - { - "played": true, - "request": "012E", - "request_type": "PIDCommand", - "response": "7E8 03 41 2E 00 \n\n" - }, - { - "played": true, - "request": "0132", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "01A2", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "010D", - "request_type": "PIDCommand", - "response": "7E8 03 41 0D 37 \n\n" - }, - { - "played": true, - "request": "010E", - "request_type": "PIDCommand", - "response": "7E8 03 41 0E 75 \n\n" - }, - { - "played": true, - "request": "0111", - "request_type": "PIDCommand", - "response": "7E8 03 41 11 70 \n\n" - }, - { - "played": true, - "request": "0145", - "request_type": "PIDCommand", - "response": "7E8 03 41 45 19 \n\n" - }, - { - "played": true, - "request": "0147", - "request_type": "PIDCommand", - "response": "7E8 03 41 47 92 \n\n" - }, - { - "played": true, - "request": "0148", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0149", - "request_type": "PIDCommand", - "response": "7E8 03 41 49 00 \n\n" - }, - { - "played": true, - "request": "014A", - "request_type": "PIDCommand", - "response": "7E8 03 41 4A 45 \n\n" - }, - { - "played": true, - "request": "014B", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0114", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0124", - "request_type": "PIDCommand", - "response": "7E8 06 41 24 7B A8 65 D9 \n\n" - }, - { - "played": true, - "request": "0115", - "request_type": "PIDCommand", - "response": "7E8 04 41 15 07 FF \n\n" - }, - { - "played": true, - "request": "0125", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0116", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0126", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0117", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0127", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0118", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0128", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0119", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0129", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "011A", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "012A", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "011B", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "012B", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0166", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "014F", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "010F", - "request_type": "PIDCommand", - "response": "7E8 03 41 0F 3C \n\n" - }, - { - "played": true, - "request": "0110", - "request_type": "PIDCommand", - "response": "7E8 04 41 10 01 46 \n\n" - }, - { - "played": true, - "request": "0146", - "request_type": "PIDCommand", - "response": "7E8 03 41 46 43 \n\n" - }, - { - "played": true, - "request": "0150", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0112", - "request_type": "PIDCommand", - "response": "NO DATA" - }, - { - "played": true, - "request": "0133", - "request_type": "PIDCommand", - "response": "7E8 03 41 33 61 \n\n" - } -] \ No newline at end of file diff --git a/docs/app_image.png b/docs/app_image.png new file mode 100644 index 0000000..1cc2027 Binary files /dev/null and b/docs/app_image.png differ diff --git a/examples/vin-decoding.rs b/examples/vin-decoding.rs index 8e32471..b1f1a22 100644 --- a/examples/vin-decoding.rs +++ b/examples/vin-decoding.rs @@ -25,7 +25,7 @@ fn main() { // Used internally as well let vspec_schema_id = vin.get_vspec_schema_id().unwrap(); let vspec_pattern_id = vin.get_vspec_pattern_id().unwrap(); - + println!("Model year: {}", model_year); println!("WMI: {}", wmi); println!("WMI ID: {}", wmi_id); diff --git a/frontend/assets/icons/arrow-icon.png b/frontend/assets/icons/arrow-icon.png new file mode 100644 index 0000000..37ca481 Binary files /dev/null and b/frontend/assets/icons/arrow-icon.png differ diff --git a/frontend/assets/icons/connected.png b/frontend/assets/icons/connected.png new file mode 100644 index 0000000..533f813 Binary files /dev/null and b/frontend/assets/icons/connected.png differ diff --git a/frontend/assets/icons/edit.png b/frontend/assets/icons/edit.png new file mode 100644 index 0000000..1dbd61d Binary files /dev/null and b/frontend/assets/icons/edit.png differ diff --git a/frontend/assets/icons/graphs.png b/frontend/assets/icons/graphs.png new file mode 100644 index 0000000..fb2aad0 Binary files /dev/null and b/frontend/assets/icons/graphs.png differ diff --git a/frontend/assets/icons/not-connected.png b/frontend/assets/icons/not-connected.png new file mode 100644 index 0000000..75c66aa Binary files /dev/null and b/frontend/assets/icons/not-connected.png differ diff --git a/frontend/assets/icons/search.png b/frontend/assets/icons/search.png new file mode 100644 index 0000000..2d6952b Binary files /dev/null and b/frontend/assets/icons/search.png differ diff --git a/frontend/assets/icons/settings.png b/frontend/assets/icons/settings.png new file mode 100644 index 0000000..e55f716 Binary files /dev/null and b/frontend/assets/icons/settings.png differ diff --git a/frontend/assets/icons/start.png b/frontend/assets/icons/start.png new file mode 100644 index 0000000..4de9166 Binary files /dev/null and b/frontend/assets/icons/start.png differ diff --git a/frontend/assets/icons/table.png b/frontend/assets/icons/table.png new file mode 100644 index 0000000..af24a46 Binary files /dev/null and b/frontend/assets/icons/table.png differ diff --git a/frontend/assets/icons/vin-decoding.png b/frontend/assets/icons/vin-decoding.png new file mode 100644 index 0000000..612cc9f Binary files /dev/null and b/frontend/assets/icons/vin-decoding.png differ diff --git a/frontend/assets/images/vehicle.png b/frontend/assets/images/vehicle.png new file mode 100644 index 0000000..7cc8205 Binary files /dev/null and b/frontend/assets/images/vehicle.png differ diff --git a/frontend/components/buttons.css b/frontend/components/buttons.css new file mode 100644 index 0000000..f95f57d --- /dev/null +++ b/frontend/components/buttons.css @@ -0,0 +1,207 @@ +/* Regular button */ + +.button-row { + display: flex; + gap: 8px; +} + +.btn { + display: flex; + align-items: center; + justify-content: center; + border: none; + color: #F7F3FF; + width: 120px; + height: 30px; + margin-top: 10px; + font-size: 15px; + font-weight: 700; + border-radius: 4px; + cursor: pointer; + transition: background 0.2s; + text-transform: uppercase; + vertical-align: middle; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); +} + +.btn.connect { + background-color: #2A2A2A; +} + +.btn.disconnect { + background-color: #202020; + width: 162px; +} + +.btn:hover { + background-color: #1d1d1d; + box-shadow: 0 4px 20px #1d1d1d; +} + +.btn:disabled { + background-color: #252525; + color: #aaa; + cursor: not-allowed; + box-shadow: none; + opacity: 0.6; +} + +/* Custom dropdown */ + +.form-row { + display: flex; + flex-wrap: wrap; +} + +.dropdown { + position: relative; + display: inline-block; + width: 290px; + margin-right: 10px; +} + +.dropdown label { + margin-left: 1.5px; + font-size: 18px; + font-weight: 700; + text-transform: uppercase; + color: #f3f3f2; + margin-bottom: 5px; + display: block; +} + +.dropdown-toggle { + font-family: 'Montserrat', sans-serif; + width: 100%; + padding-top: 10px; + padding-left: 11px; + background-color: #151515; + border: none; + color: #49454F; + font-weight: 600; + font-size: 14px; + cursor: pointer; + text-align: left; + border-radius: 4px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); +} + +.dropdown-toggle::after { + content: url('data:image/svg+xml;utf8,'); + float: right; + font-size: 0.5em; + margin-bottom: 4px; + padding-right: 5px; +} + +.dropdown-menu { + list-style: none; + margin: 5px 0 0 0; + position: absolute; + width: 100%; + background-color: #151515; + border-radius: 0 0 5px 5px; + display: none; + z-index: 100; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); +} + +.dropdown-menu li { + padding: 8px; + padding-left: 11px; + font-weight: 600; + font-size: 14px; + cursor: pointer; + color: #615c68; + border-radius: 0 0 5px 5px; +} + +.dropdown-menu li:hover { + background-color: #0F0F0F; +} + +.arrow-icon { + width: 32px; + height: 32px; + padding: 0; + border: none; + background: none; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: transform 0.3s ease; +} + +.settings-dropdown-column { + display: flex; + flex-direction: column; +} + +/* Switch */ + +.switch { + position: relative; + width: 42px; + height: 20px; + display: flex; + white-space: nowrap; + margin-bottom: 16px; + margin-top: -8px; +} + +.switch input { + opacity: 0; + width: 0; + height: 0; +} + +.settings-label { + color: #49454F; + font-weight: 600; + font-size: 1rem; + display: flex; + align-items: center; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #2b2b2b; + transition: 0.4s; + border-radius: 34px; +} + +.slider::before { + position: absolute; + content: ""; + height: 15px; + width: 15px; + left: 3px; + bottom: 3px; + background-color: #f3f3f2; + transition: 0.4s; + border-radius: 50%; +} + +input:checked + .slider { + background-color: #1a69ae; +} + +input:checked+.slider::before { + transform: translateX(22px); +} + +input:disabled + .slider { + background-color: #2b2b2b; + cursor: not-allowed; + opacity: 0.6; +} + +input:disabled + .slider::before { + background-color: #424242; +} \ No newline at end of file diff --git a/frontend/components/card.css b/frontend/components/card.css new file mode 100644 index 0000000..e6c746f --- /dev/null +++ b/frontend/components/card.css @@ -0,0 +1,48 @@ +/* + "Card" that holds OBD information: + A label, value and unit +*/ + +.card { + background-color: #151515; + border-radius: 12px; + padding: 28px 25px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); + display: flex; + flex-direction: column; + justify-content: center; + gap: 8px; + user-select: none; +} + +.card:hover { + background-color: #1d1d1d; + box-shadow: 0 4px 20px #1d1d1d; +} + +.card h3 { + font-size: 0.97rem; + font-weight: 500; + text-transform: uppercase; + margin: 0; + line-height: 1; + color: #D4DADF; +} + +.card .value { + font-size: 3.4rem; + font-weight: 700; + margin: 0; + line-height: 1; + color: #F7F3FF; +} + +.card .unit { + font-size: 1.3rem; + font-weight: 200; + color: #D4DADF; +} + +.card.dimmed * { + opacity: 0.15 !important; +} \ No newline at end of file diff --git a/frontend/components/forms.css b/frontend/components/forms.css new file mode 100644 index 0000000..87a5020 --- /dev/null +++ b/frontend/components/forms.css @@ -0,0 +1,71 @@ +/* Simple search bars */ + +.search-container { + position: relative; + width: 50%; + display: flex; + align-items: center; + background-color: #151515; + border-radius: 10px; +} + +.search { + position: relative; + font-size: .95rem; + background-color: #151515; + border-radius: 10px; + padding: 6px 20px; + width: 100%; + height: 35px; + border: none; + outline: none; + color: #F7F3FF; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); +} + +.search-icon { + position: absolute; + right: 15px; + width: 16px; + height: 16px; + pointer-events: none; +} + +.search::placeholder { + color: #49454F; + opacity: 1; +} + +.vin-input-container { + position: relative; + width: 58%; + display: flex; + align-items: center; + background-color: #151515; + border-radius: 5px; +} + +.vin-input { + position: relative; + font-size: .95rem; + background-color: #171717; + border-radius: 5px; + margin-top: 2px; + + padding: 6px 20px; + width: 100%; + height: 35px; + border: none; + outline: none; + color: #F7F3FF; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.4); +} + +.vin-input::placeholder { + color: #49454F; + opacity: 1; +} + +input[type="file"] { + display: none; +} \ No newline at end of file diff --git a/frontend/components/pid.css b/frontend/components/pid.css new file mode 100644 index 0000000..3941eb4 --- /dev/null +++ b/frontend/components/pid.css @@ -0,0 +1,128 @@ +/* + A row containing a title and dropdown arrow. + On click, this row expands to show pid details. + "Glows" when hovered. +*/ + +.pid-container:hover .pid-row, +.pid-container:hover .pid-details { + background-color: #1d1d1d; + box-shadow: 0 4px 20px #1d1d1d; +} + +.pid-row { + background-color: #151515; + height: 10px; + padding: 19px 10px; + display: flex; + align-items: center; + cursor: pointer; + margin-bottom: 0px; +} + +.pid-row .name { + font-size: 1.0rem; + font-weight: 550; + padding-left: 10px; + color: #f3f3f2; +} + +.pid-row.expanded { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + box-shadow: none; +} + +.pid-row.expanded .arrow-icon { + transform: rotate(-180deg); +} + +.pid-row.expanded+.pid-details { + opacity: 1; + transform: translateY(0); +} + + +.pid-details { + height: 0; + opacity: 0; + overflow: hidden; + background-color: #151515; + margin-top: 0px; + + transform: translateY(-10px); + font-size: 0.95rem; + position: static; + padding: 0 12px; + transition: height 0.3s ease, opacity 0.3s ease, transform 0.3s ease; +} + +.pid-data-columns { + display: flex; + gap: 40px; +} + +.pid-column { + display: flex; + flex-direction: column; + align-items: flex-start; +} + +.pid-button { + margin-top: 12px; + margin-bottom: 10px; + height: 22px; + width: 85px; + background-color: #303030; + color: #F7F3FF; + font-weight: 700; + font-size: 0.8em; + border: none; + padding-left: 8px; + padding-right: 8px; + border-radius: 5px; + cursor: pointer; +} + +.pid-label { + font-weight: 600; + font-size: 0.9rem; + color: #F7F3FF; + text-transform: uppercase; +} + +.pid-value { + font-weight: 500; + font-size: 0.85rem; + color: #F7F3FF; + white-space: nowrap; +} + + +.pid-row-scroll { + overflow-y: auto; + flex-grow: 1; + padding-right: 10px; + padding-bottom: 50px; + height: 100%; + min-height: 0; +} + +.pid-row-scroll::-webkit-scrollbar { + width: 13px; +} + +.pid-row-scroll::-webkit-scrollbar-track { + background: #0F0F0F; + border-radius: 10px; +} + +.pid-row-scroll::-webkit-scrollbar-thumb { + background-color: #29272c; + border-radius: 10px; + border: 2px solid #0F0F0F; +} + +.pid-row-scroll::-webkit-scrollbar-thumb:hover { + background-color: #49454F; +} \ No newline at end of file diff --git a/frontend/components/sidebar.css b/frontend/components/sidebar.css new file mode 100644 index 0000000..92c2ba9 --- /dev/null +++ b/frontend/components/sidebar.css @@ -0,0 +1,61 @@ +/* VSCode like sidebar */ + +.sidebar-button { + width: 45px; + height: 45px; + background-color: transparent; + border: none; + border-radius: 8px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + position: relative; +} + +.sidebar-button-img { + margin-left: 3px; + color: #49454F; +} + +.sidebar-button::after { + content: attr(data-tooltip); + position: absolute; + left: 50px; + background: #151515; + color: #eee; + font-size: 12px; + padding: 4px 8px; + border-radius: 4px; + white-space: nowrap; + opacity: 0; + pointer-events: none; + transition: opacity 0.2s ease 0s; + top: 50%; + transform: translateY(-50%); + z-index: 1000; +} + +.sidebar-button.active-button::before { + content: ""; + position: absolute; + left: 0; + top: 0; + bottom: 0; + width: 3px; + background-color: #f3f3f2; + font-family: 'Montserrat', sans-serif; +} + +.sidebar-button:hover::after { + opacity: 1; + transition-delay: 0.3s; +} + +.sidebar-button:hover svg { + stroke: #f3f3f2; +} + +.sidebar-button.active-button svg { + stroke: #f3f3f2; +} \ No newline at end of file diff --git a/frontend/components/vin.css b/frontend/components/vin.css new file mode 100644 index 0000000..52f8e10 --- /dev/null +++ b/frontend/components/vin.css @@ -0,0 +1,44 @@ +/* Vin that is apart of the header in all screens */ + +.vin { + font-size: 16px; + color: #BDBDBD; + margin-left: 1px; + font-weight: 500; +} + +/* Components of the vin screen */ + +.car-image { + height: 215px; +} + +.vin-results { + overflow-y: auto; + display: flex; + gap: 70px; + margin-top: 20px; + flex-wrap: wrap; + height: 100%; +} + +.vin-column { + display: flex; + flex-direction: column; + gap: 16px; +} + +.vin-label .label { + font-size: 16px; + color: #D4DADF; + font-weight: 500; + text-transform: uppercase; +} + +.vin-label .value { + font-size: 20px; + font-weight: 700; + color: #F7F3FF; + margin-bottom: -7px; + max-width: 400px; +} \ No newline at end of file diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000..b282b1c --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,645 @@ + + + + + + + OBDII Dashboard + + + + + + + + + + + + + + + + + + +
+
+
+
+ Connectivity + ELM327 NOT CONNECTED +
+
UNAVAILABLE
+
VIN: ?????????????????
+
+
+ + Search +
+
+ +
+
OBD OVERVIEW
+
+
+
+ + + + +
+ + + + + \ No newline at end of file diff --git a/frontend/layout.css b/frontend/layout.css new file mode 100644 index 0000000..2644239 --- /dev/null +++ b/frontend/layout.css @@ -0,0 +1,83 @@ +.main { + flex: 1; + padding: 20px 15px; + display: flex; + flex-direction: column; + overflow: hidden; + min-height: 0; +} + +.header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 20px; +} + +.header .info { + font-size: 1.2rem; +} + +.container { + max-width: 1000px; + margin: auto; + background: none !important; + background-color: transparent !important; +} + +.sidebar { + width: 60px; + background-color: #0F0F0F; + padding: 10px 0; + gap: 5px; + display: flex; + flex-direction: column; + align-items: center; +} + +.grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); + gap: 15px; + overflow-y: auto; + flex: 1; + align-content: start; + min-height: 0; +} + +.screen { + flex: 1; + display: flex; + flex-direction: column; + overflow: hidden; + min-height: 0; +} + +.screen-label { + padding-bottom: 11px; + font-size: 1.5rem; + color: #F7F3FF; + font-weight: 700; + margin-left: 1px; +} + +#connection-icon { + width: 1em; + height: 1em; + object-fit: contain; +} + +#edit { + display: flex; + flex-direction: column; + height: 100%; + max-height: 100vh; + min-height: 0; +} + +#dashboard { + flex: 1; + display: flex; + flex-direction: column; + min-height: 0; +} diff --git a/frontend/scripts/events.js b/frontend/scripts/events.js new file mode 100644 index 0000000..9f1ab42 --- /dev/null +++ b/frontend/scripts/events.js @@ -0,0 +1,209 @@ +const { listen, emit } = window.__TAURI__.event; + +listen('update-card', (event) => { + const cards = document.querySelectorAll('.card'); + const exists = Array.from(cards).some(card => { + return card.textContent.includes(event.payload.name); + }); + + // create card if it doesnt exist + if (!exists) { + const container = document.querySelector('.grid'); + if (!container) + return; + + // create the card + // has a header, value, and then unit + const card = document.createElement('div'); + const h3 = document.createElement('h3'); + const valueDiv = document.createElement('div'); + const unitSpan = document.createElement('span'); + + card.className = 'card'; + valueDiv.className = 'value'; + unitSpan.className = 'unit'; + + h3.textContent = event.payload.name; + + if (event.payload.unit.toLowerCase() !== "no data") + unitSpan.textContent = event.payload.unit; + + // if the unit is no data meaning that scalar has 'no data' + // (see backend docs), then display 'N/A' for value + const valueText = event.payload.unit.toLowerCase() === "no data" ? "N/A" : event.payload.value.toString(); + + // add value and unit to one div to align horizontally + valueDiv.appendChild(document.createTextNode(valueText + " ")); + valueDiv.appendChild(unitSpan); + + // append elements to card + card.appendChild(h3); + card.appendChild(valueDiv); + + container.appendChild(card); + + return; + } + + cards.forEach(card => { + // Don't update card data. + if (card.classList.contains('dimmed')) { + return; + } + + const h3 = card.querySelector('h3'); + if (!h3) return; + + const title = h3.textContent?.toLowerCase(); + if (title == event.payload.name.toLowerCase()) { + const valueElem = card.querySelector('.value'); + const unitElem = card.querySelector('.unit'); + + if (valueElem) { + const textNode = Array.from(valueElem.childNodes).find( + node => node.nodeType === Node.TEXT_NODE + ); + + if (textNode) { + textNode.textContent = event.payload.unit.toLowerCase() === "no data" + ? "N/A " + : event.payload.value.toString() + " "; + } + } + } + }); +}); + +listen('vehicle-details', (event) => { + const vin = document.querySelector(".vin") + const makeModel = document.querySelector(".car-model"); + + if (!hideVin) { + vin.textContent = "VIN: " + event.payload.vin.toUpperCase(); + } else { + vin.textContent = "VIN: " + event.payload.vin.toUpperCase().slice(0, 6) + "*".repeat(12); + } + + makeModel.textContent = (event.payload.make + " " + event.payload.model).toUpperCase(); +}); + +listen('connection-status', (event) => { + const connection_label = document.getElementById("connection-label"); + const connection_icon = document.getElementById("connection-icon"); + + if (event.payload.connected) { + connection_label.textContent = "ELM327 CONNECTED VIA " + event.payload.serial_port.toUpperCase(); + connection_icon.src = "/assets/icons/connected.png"; + window.connected = true; + } else { + connection_label.textContent = "ELM327 NOT CONNECTED"; + connection_icon.src = "/assets/icons/not-connected.png"; + window.connected = false; + } + + + console.log(event.payload.message); +}); + +listen('update-pids', (event) => { + const pids = event.payload; + const pidList = document.getElementById('pid-list'); + + for (const pidInfo of pids) { + const pidGroup = document.createElement('div'); + pidGroup.className = 'pid-group'; + + pidGroup.innerHTML = ` +
+
+ + ${pidInfo.pid_name.toUpperCase()} +
+ +
+ `; + + pidList.appendChild(pidGroup); + + // Increment results counter + const header = document.getElementById('pid-list-header'); + header.textContent = "VIEW PIDS (" + pidList.children.length + ")"; + + // Add expand/collapse event listener + const row = pidGroup.querySelector('.pid-row'); + const details = pidGroup.querySelector('.pid-details'); + + row.addEventListener('click', () => { + const expanded = row.classList.contains('expanded'); + + if (expanded) { + details.style.height = details.scrollHeight + 'px'; + requestAnimationFrame(() => { + details.style.height = '0px'; + }); + row.classList.remove('expanded'); + } else { + details.style.display = 'block'; + const height = details.scrollHeight + 'px'; + details.style.height = '0px'; + requestAnimationFrame(() => { + details.style.height = height; + }); + row.classList.add('expanded'); + } + + details.addEventListener('transitionend', function handler(e) { + if (e.propertyName === 'height') { + if (!row.classList.contains('expanded')) { + details.style.display = 'none'; + } else { + details.style.height = 'auto'; + } + details.removeEventListener('transitionend', handler); + } + }); + }); + } +}); + +const menu = document.getElementById('serial-port-dropdown-menu'); +const serialPortSelected = document.getElementById('serial-port-selected'); + +listen('update-serial-ports', (event) => { + serialPortSelected.textContent = "NO PORTS SELECTED"; + menu.innerHTML = ''; + + if (event.payload === "") { + return; + } + + const portOption = document.createElement('li'); + portOption.textContent = event.payload; + portOption.dataset.value = event.payload; + + menu.appendChild(portOption); +}) \ No newline at end of file diff --git a/frontend/scripts/main.js b/frontend/scripts/main.js new file mode 100644 index 0000000..54a992b --- /dev/null +++ b/frontend/scripts/main.js @@ -0,0 +1,148 @@ +const { listen, emit } = window.__TAURI__.event; +import { saveConnectionConfig } from './settings.js' + +// ELM connection +// Changes when connection-status is fired +let connected = false; +window.connectionConfig = { + serialPort: "0", + baudRate: "0", + protocol: 0, +}; + +// Personal settings +let hideVin = false; +let deleteLogsOnExit = false; + +// When frontend gets loaded +// alert the backend with an event. +window.addEventListener('DOMContentLoaded', () => { + emit('frontend-loaded'); + // Load pid list + emit('get-pids') + + // load serial ports + emit('get-serial-ports'); +}); + +export async function connect_elm(baudRate, serialPort, protocol) { + const status = document.getElementById('connection-details'); + const recordResponses = document.getElementById('record-responses'); + const replayResponses = document.getElementById('replay-responses'); + + let dots = 0; + const interval = setInterval(() => { + if (dots == 4) { + dots = 0; + } + + status.textContent = "CONNECTING" + '.'.repeat(dots); + dots += 1; + }, 500); + + connectButton.disabled = true; + emit('connect-elm', { serialPort: serialPort, baudRate: parseInt(baudRate), protocol: parseInt(protocol) }); + await new Promise(r => setTimeout(r, 1000)); + clearInterval(interval); + + if (window.connected) { + status.textContent = "CONNECTED THROUGH SERIAL PORT " + serialPort.toUpperCase(); + connectButton.disabled = true; + disconnectButton.disabled = false; + + window.connectionConfig = { + serialPort: serialPort, + baudRate: baudRate, + protocol: parseInt(protocol), + }; + + saveConnectionConfig(); + + // enable buttons for logging + recordResponses.disabled = false; + replayResponses.disabled = false; + } else { + status.textContent = "FAILED TO CONNECT THROUGH SERIAL PORT"; + connectButton.disabled = false; + disconnectButton.disabled = true; + } + + document.getElementById('baud-rate-selected').textContent = baudRate; + document.getElementById('serial-port-selected').textContent = serialPort; + document.getElementById('protocol-selected').dataset.value = protocol ; +} + +async function disconnect_elm() { + const recordResponses = document.getElementById('record-responses'); + const replayResponses = document.getElementById('replay-responses'); + const status = document.getElementById('connection-details'); + + let dots = 0; + const interval = setInterval(() => { + if (dots == 4) { + dots = 0; + } + + status.textContent = "DISCONNECTING" + '.'.repeat(dots); + dots += 1; + }, 500); + + connectButton.disabled = true; + emit('disconnect-elm'); + await new Promise(r => setTimeout(r, 1000)); + clearInterval(interval); + + status.textContent = "NO CONNECTION ESTABLISHED"; + connectButton.disabled = false; + disconnectButton.disabled = true; + recordResponses.disabled = true; + replayResponses.disabled = true; +} + +const dropdowns = document.querySelectorAll(".dropdown"); + +dropdowns.forEach(dropdown => { + const toggle = dropdown.querySelector(".dropdown-toggle"); + const menu = dropdown.querySelector(".dropdown-menu"); + + toggle.addEventListener("click", (e) => { + e.stopPropagation(); + if (menu.style.display === "block") { + menu.style.display = "none"; + } else { + document.querySelectorAll(".dropdown-menu").forEach(m => { + m.style.display = "none"; + }); + menu.style.display = "block"; + } + }); + + menu.addEventListener("click", (e) => { + if (e.target.tagName === "LI") { + toggle.textContent = e.target.textContent; + toggle.dataset.value = e.target.dataset.value; + menu.style.display = "none"; + } + }); +}); + +document.addEventListener("click", () => { + document.querySelectorAll(".dropdown-menu").forEach(menu => { + menu.style.display = "none"; + }); +}); + +const connectButton = document.getElementById('btn-connect'); +const disconnectButton = document.getElementById('btn-disconnect'); + +connectButton.addEventListener("click", async () => { + const baudRate = document.getElementById('baud-rate-selected'); + const serialPort = document.getElementById('serial-port-selected'); + const protocol = document.getElementById('protocol-selected'); + + connect_elm(baudRate.textContent, serialPort.textContent, parseInt(protocol.dataset.value)); +}) + +disconnectButton.addEventListener("click", async () => { + disconnect_elm(); +}) \ No newline at end of file diff --git a/frontend/scripts/settings.js b/frontend/scripts/settings.js new file mode 100644 index 0000000..6fe50ca --- /dev/null +++ b/frontend/scripts/settings.js @@ -0,0 +1,136 @@ +import { connect_elm } from './main.js'; + +function importSettings() { + let settings = JSON.parse(localStorage.getItem('userSettings')); + if (!settings) { + return; + } + + console.log("Importing settings:", settings); + + if (!settings.connectionConfig) { + settings.connectionConfig = window.connectionConfig; + } + + // read from connectionConfig + // if empty, we cannot connect + if (settings.autoConnect && !window.connected && settings.connectionConfig) { + console.log("Auto-connect"); + connect_elm(settings.connectionConfig.baudRate, settings.connectionConfig.serialPort, 0); + } + + window.hideVin = settings.showPartialVin; + window.deleteLogsOnExit = settings.deleteLogsOnExit; + + // show buttons depending on which are toggled + document.getElementById('save-dtcs').checked = settings.saveDtcs; + document.getElementById('auto-check-codes').checked = settings.autoCheckCodes; + document.getElementById('auto-connect').checked = settings.autoConnect; + document.getElementById('hide-vin').checked = settings.showPartialVin; + document.getElementById('del-logs').checked = settings.deleteLogsOnExit; + console.log("Imported settings:", settings); +} + +export function saveConnectionConfig() { + console.log("Saving connection config!"); + + let settings = JSON.parse(localStorage.getItem('userSettings')); + if (!settings) { + return; + } + + if (window.connectionConfig) { + console.log("Not null"); + settings.connectionConfig = window.connectionConfig; + localStorage.setItem('userSettings', JSON.stringify(settings)); + console.log("Saved new settings:", settings); + } +} + +function settingChange(event) { + // get existing settings + let settings = JSON.parse(localStorage.getItem('userSettings')); + if (!settings) { + settings = { + saveDtcs: false, + autoCheckCodes: false, + autoConnect: false, + connectionConfig: { + protocol: 0, + baudRate: "0", + serialPort: "0", + }, + showPartialVin: false, + deleteLogsOnExit: false, + }; + } + + // settings to save to localStorage + // save dtcs + // auto check for codes + // auto connect startup + // show partial vin + // delete logs on exit + const tId = event.target.id; + const checked = event.target.checked; + + switch (tId) { + case 'save-dtcs': + settings.saveDtcs = checked; + break; + case 'auto-check-codes': + settings.autoCheckCodes = checked; + break; + case 'auto-connect': + // save connection config + settings.autoConnect = checked; + if (window.connectionConfig) { + settings.connectionConfig = window.connectionConfig; + } + break; + case 'hide-vin': + settings.showPartialVin = checked; + break; + case 'del-logs': + settings.deleteLogsOnExit = checked; + break; + // the rest will have the frontend send an event + // record response + // replay response + // use freeze frame + case 'record-responses': + // uncheck replay requests + document.getElementById('replay-responses').checked = false; + window.__TAURI__.event.emit('settings-changed', {tId: 'replay-responses', checked: false}) + window.__TAURI__.event.emit('settings-changed', { tId, checked }); + break; + case 'replay-responses': + // uncheck record requests + document.getElementById('record-responses').checked = false; + window.__TAURI__.event.emit('settings-changed', {tId: 'record-responses', checked: false}) + window.__TAURI__.event.emit('settings-changed', { tId, checked }); + break; + case 'use-freeze-frame': + window.__TAURI__.event.emit('settings-changed', { tId, checked }); + break; + } + + localStorage.setItem('userSettings', JSON.stringify(settings)); + console.log("Saved settings:", settings); +} + +window.addEventListener('DOMContentLoaded', async () => { + // sleep + await new Promise(r => setTimeout(r, 4000)); + + importSettings(); + + document.getElementById('record-responses').addEventListener('change', settingChange); + document.getElementById('replay-responses').addEventListener('change', settingChange); + document.getElementById('save-dtcs').addEventListener('change', settingChange); + document.getElementById('auto-check-codes').addEventListener('change', settingChange); + document.getElementById('use-freeze-frame').addEventListener('change', settingChange); + document.getElementById('auto-connect').addEventListener('change', settingChange); + document.getElementById('hide-vin').addEventListener('change', settingChange); + document.getElementById('del-logs').addEventListener('change', settingChange); +}); diff --git a/frontend/scrollbar.css b/frontend/scrollbar.css new file mode 100644 index 0000000..47d74b4 --- /dev/null +++ b/frontend/scrollbar.css @@ -0,0 +1,38 @@ +.grid::-webkit-scrollbar { + width: 13px; +} + +.grid::-webkit-scrollbar-track { + background: #0F0F0F; + border-radius: 10px; +} + +.grid::-webkit-scrollbar-thumb { + background-color: #29272c; + border-radius: 10px; + border: 2px solid #0F0F0F; +} + +.grid::-webkit-scrollbar-thumb:hover { + background-color: #49454F; +} + + +.vin-results::-webkit-scrollbar { + width: 13px; +} + +.vin-results::-webkit-scrollbar-track { + background: #0F0F0F; + border-radius: 10px; +} + +.vin-results::-webkit-scrollbar-thumb { + background-color: #29272c; + border-radius: 10px; + border: 2px solid #0F0F0F; +} + +.vin-results::-webkit-scrollbar-thumb:hover { + background-color: #49454F; +} \ No newline at end of file diff --git a/frontend/styles.css b/frontend/styles.css new file mode 100644 index 0000000..408782e --- /dev/null +++ b/frontend/styles.css @@ -0,0 +1,92 @@ +* { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +body { + font-family: 'Montserrat', sans-serif; + background-color: #121212; + color: #f0e9f9; + display: flex; + height: 100vh; + overflow: hidden; +} + +h1 { + font-size: 1.8rem; + margin-bottom: 1.5rem; +} + + +/* Labels */ + +.info { + display: flex; + flex-direction: column; +} + +.connection { + font-size: 16px; + color: #F7F3FF; + font-weight: 500; +} + +.car-model { + font-size: 1.5rem; + color: #F7F3FF; + font-weight: 700; +} + +.connection { + font-size: 0.95rem; + color: #F7F3FF; + font-weight: 500; + display: flex; + align-items: center; + gap: 4px; +} + +.connection-details { + font-size: 0.95rem; + color: #F7F3FF; + font-weight: 500; + display: flex; + align-items: center; + gap: 4px; + margin-top: -12px; + margin-bottom: 12px; +} + +.error-hint { + font-size: 0.7rem; + color: #575757; + font-weight: 500; + display: flex; + align-items: center; + gap: 4px; + margin-top: 5px; + margin-bottom: 12px; +} + +.label-row { + display: flex; + align-items: center; + gap: 5.7rem; +} + +button.refresh { + background: none; + border: none; + cursor: pointer; + padding: 0; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +.spinning { + animation: spin 0.3s linear 1; +} \ No newline at end of file diff --git a/ref/dump.txt b/ref/dump.txt deleted file mode 100644 index c97f9ec..0000000 --- a/ref/dump.txt +++ /dev/null @@ -1,460 +0,0 @@ -======================== SENDING MANUAL COMMANDS ======================== - -> 0101 -< '7E8 06 41 01 03 07 E5 00 \r7EB 06 41 01 00 04 00 00 \r7EA 06 41 01 00 04 00 00 \r\r' - -> 0102 -< 'NO DATA\r\r' - -> 0103 -< '7E8 04 41 03 02 00 \r\r' - -> 0104 -< '7E8 03 41 04 3D \r\r' - -> 0105 -< '7E8 03 41 05 52 \r\r' - -> 0106 -< '7E8 03 41 06 81 \r\r' - -> 0107 -< '7E8 03 41 07 83 \r\r' - -> 0108 -< 'NO DATA\r\r' - -> 0109 -< 'NO DATA\r\r' - -> 010A -< '7EB 03 41 0A 68 \r7E8 03 41 0A 67 \r\r' - -> 010B -< '7E8 03 41 0B 20 \r\r' - -> 010C -< '7E8 04 41 0C 0E 20 \r\r' - -> 010D -< '7E8 03 41 0D 00 \r\r' - -> 010E -< '7E8 03 41 0E 83 \r\r' - -> 010F -< '7E8 03 41 0F 42 \r\r' - -> 0110 -< '7E8 04 41 10 01 22 \r\r' - -> 0111 -< '7E8 03 41 11 3B \r\r' - -> 0112 -< 'NO DATA\r\r' - -> 0113 -< '7E8 03 41 13 03 \r\r' - -> 0114 -< '7E8 04 41 14 90 7C \r\r' - -> 0115 -< '7E8 04 41 15 FF FF \r\r' - -> 0116 -< 'NO DATA\r\r' - -> 0117 -< 'NO DATA\r\r' - -> 0118 -< 'NO DATA\r\r' - -> 0119 -< 'NO DATA\r\r' - -> 01A0 -< 'NO DATA\r\r' - -> 01A1 -< 'NO DATA\r\r' - -> 0120 -< '7E8 06 41 20 80 07 E0 11 \r7EA 06 41 20 00 00 00 01 \r7EB 06 41 20 00 00 00 01 \r\r' - -> 0121 -< '7E8 04 41 21 00 0B \r\r' - -> 0122 -< 'CAN ERROR\r\r' - -> 0123 -< 'NO DATA\r\r' - -> 0122 -< 'NO DATA\r\r' - -> 0122 -< 'NO DATA\r\r' - -> 0124 -< 'NO DATA\r\r' - -> 0125 -< 'NO DATA\r\r' - -> 0126 -< 'NO DATA\r\r' - -> 0127 -< 'NO DATA\r\r' - -> EXIT -< '?\r\r' - -> exit -[ethan@archlinux obdium]$ cargo run - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.05s - Running `target/debug/obdium` -error when getting vin. vin length invalid. must be 17 characters - -======================== DIAGNOSTICS ======================== -ECU: 7E8 -ECU: 7EA -ECU: 7EA -ECU: 7E8 -ECU: 7E8 -ECU: 7EB -ECU: 7E8 -Supported pids for ECUs -ECU 7E8: - 01 03 04 05 06 07 0A 0B 0C 0D - 0E 0F 10 11 13 14 15 1C 1F 20 - 21 2E 2F 30 31 32 33 3C 40 41 - 42 43 44 45 46 47 49 4A 4C 4F - 51 60 68 -ECU 7EB: - 42 -ECU 7EA: - 01 20 40 -Check engine light: false -Number of trouble codes: 0 -OBD standard: No data -Auxiliary input status: Inactive -Control module voltage: NO DATA -Distance traveled with malfunction indicator lamp: NO DATA -TIme run with malfunction indicator lamp: NO DATA -Time since codes cleared: NO DATA -Warm-ups since codes cleared: NO DATA - -======================== ENGINE ======================== -Engine type: Unkown -Engine speed: NO DATA -Engine load: NO DATA -Coolant temperature: NO DATA -Coolant temperatue from sensors - Sensor 1: NO DATA - Sensor 2: NO DATA -Engine fuel rate: NO DATA -Engine runtime: NO DATA -Engine runtime (diesel): NO DATA -Engine mileage: NO DATA -Engine oil temperature (Mode 1): NO DATA -Engine oil temperature (Mode 22): 42°C -Engine oil temperatue from sensors - Sensor 1: NO DATA - Sensor 2: NO DATA -Engine oil pressure: 0kPa -Drivers demand engine torque: NO DATA -Actual engine torque: NO DATA -Reference engine torque: NO DATA -Engine percent torque data: - Idle: NO DATA - Engine point 1: NO DATA - Engine point 2: NO DATA - Engine point 3: NO DATA - Engine point 4: NO DATA - -======================== FUEL SYSTEM ======================== -Short term fuel trim: - Bank 1: NO DATA - Bank 2: NO DATA -Long term fuel trim: - Bank 1: NO DATA - Bank 2: NO DATA -Fuel system status: -Fuel system 1: Status("Unknown fuel system status") -Fuel system 2: Status("Unknown fuel system status") -Fuel pressure: NO DATA -Fuel tank level: NO DATA -Fuel rail pressure: NO DATA -Fuel rail gauge pressure: NO DATA -Fuel type: Type("Unknown") -Ethanol fuel percentage: NO DATA -Fuel injection timing: NO DATA -Commanded EVAP purge: NO DATA -EVAP system vapor pressure: NO DATA -Cylinder fuel rate: NO DATA - -======================== SENSOR DATA ======================== -Vehicle speed: NO DATA -Timing advance: NO DATA -Throttle position: NO DATA -Relative throttle position: NO DATA -Absolute throttle position B: NO DATA -Absolute throttle position C: NO DATA -Accelerator pedal position D: NO DATA -Accelerator pedal position E: NO DATA -Accelerator pedal position F: NO DATA - -======================== AIR DATA ======================== -Oxygen Sensors: -Sensor Voltage Short Term Trim (%) AFR / Voltage -1 NO DATAv NO DATA NO DATA / NO DATA -2 NO DATAv NO DATA NO DATA / NO DATA -3 NO DATAv NO DATA NO DATA / NO DATA -4 NO DATAv NO DATA NO DATA / NO DATA -5 NO DATAv NO DATA NO DATA / NO DATA -6 NO DATAv NO DATA NO DATA / NO DATA -7 NO DATAv NO DATA NO DATA / NO DATA -8 NO DATAv NO DATA NO DATA / NO DATA -Mass air flow sensor: - Sensor A: NO DATA - Sensor B: NO DATA -Maximum values for: - Fuel-air equivalance ratio: NO DATA - Oxygen sensor voltage: NO DATA - Oxygen sensor current: NO DATA - Intake manifold absolute pressure: NO DATA -Intake air temperature: NO DATA -Mass air-flow sensor rate: NO DATA -Ambient air temperature: NO DATA -Maximum air-flow rate from mass air-flow sensor: NO DATA -Secondary air status: Status("Unknown secondary air status") -Absolute barometric pressure: NO DATA - -======================== SENDING MANUAL COMMANDS ======================== - -> exit -[ethan@archlinux obdium]$ cargo clippy - Checking obdium v0.1.0 (/home/ethan/obdium) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.78s -[ethan@archlinux obdium]$ cargo run - Compiling obdium v0.1.0 (/home/ethan/obdium) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 3.71s - Running `target/debug/obdium` -parsing iso_tp response: SEARCHING...\r7E8 10 14 49 02 01 4B 4C 34 \r7E8 21 43 4A 41 53 42 36 4A \r7E8 22 42 36 36 30 39 32 39 \r\r -Bytes: ["7E8", "10", "14", "49", "02", "01", "4B", "4C", "34"] -Bytes: ["7E8", "21", "43", "4A", "41", "53", "42", "36", "4A"] -Bytes: ["7E8", "22", "42", "36", "36", "30", "39", "32", "39"] -vin response: KL4!CJASB6J"B660929 -error when getting vin. vin length invalid. must be 17 characters - -======================== DIAGNOSTICS ======================== -ECU: 7EB -ECU: 7EA -ECU: 7E8 -ECU: 7EA -ECU: 7EB -ECU: 7E8 -ECU: 7E8 -Supported pids for ECUs -ECU 7EA: - 01 20 40 -ECU 7EB: - 01 0A 20 42 -ECU 7E8: - 21 2E 2F 30 31 32 33 3C 40 41 - 42 43 44 45 46 47 49 4A 4C 4F - 51 60 68 -Check engine light: false -Number of trouble codes: 3 -OBD standard: JOBD and OBD-II -Auxiliary input status: Inactive -Control module voltage: 0V -Distance traveled with malfunction indicator lamp: 11km -^C -[ethan@archlinux obdium]$ cargo run - Compiling obdium v0.1.0 (/home/ethan/obdium) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 3.61s - Running `target/debug/obdium` -parsing iso_tp response: SEARCHING...\rUNABLE TO CONNECT\r\r -Bytes: ["UNABLE", "TO", "CONNECT"] -payload: [] -vin response: -error when getting vin. vin length invalid. must be 17 characters - -======================== DIAGNOSTICS ======================== -^C -[ethan@archlinux obdium]$ cargo run - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.08s - Running `target/debug/obdium` -parsing iso_tp response: SEARCHING...\rUNABLE TO CONNECT\r\r -Bytes: ["UNABLE", "TO", "CONNECT"] -payload: [] -vin response: -error when getting vin. vin length invalid. must be 17 characters - -======================== DIAGNOSTICS ======================== -^C -[ethan@archlinux obdium]$ cargo run - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.06s - Running `target/debug/obdium` -parsing iso_tp response: SEARCHING...\r7E8 10 14 49 02 01 4B 4C 34 \r7E8 21 43 4A 41 53 42 36 4A \r7E8 22 42 36 36 30 39 32 39 \r\r -Bytes: ["7E8", "10", "14", "49", "02", "01", "4B", "4C", "34"] -Bytes: ["7E8", "21", "43", "4A", "41", "53", "42", "36", "4A"] -Bytes: ["7E8", "22", "42", "36", "36", "30", "39", "32", "39"] -payload: ["01", "4B", "4C", "34", "21", "43", "4A", "41", "53", "42", "36", "4A", "22", "42", "36", "36", "30", "39", "32", "39"] -vin response: KL4!CJASB6J"B660929 -error when getting vin. vin length invalid. must be 17 characters - -======================== DIAGNOSTICS ======================== -ECU: 7E8 -ECU: 7EB -ECU: 7E8 -ECU: 7EB -ECU: 7E8 -ECU: 7EB -ECU: 7E8 -Supported pids for ECUs -ECU 7EB: - 01 0A 20 40 42 -ECU 7E8: - 01 03 04 05 06 07 0A 0B 0C 0D - 0E 0F 10 11 13 14 15 1C 1F 20 - 21 2E 2F 30 31 32 33 3C 40 41 - 42 43 44 45 46 47 49 4A 4C 4F - 51 60 68 -Check engine light: false -Number of trouble codes: 3 -OBD standard: JOBD and OBD-II -Auxiliary input status: Inactive -Control module voltage: 14.705V -Distance traveled with malfunction indicator lamp: 11km -TIme run with malfunction indicator lamp: NO DATA -Time since codes cleared: NO DATA -Warm-ups since codes cleared: NO DATA - -======================== ENGINE ======================== -Engine type: Internal Combustion Engine -Engine speed: 1458RPM -Engine load: 27.450981% -^C -[ethan@archlinux obdium]$ cargo run - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.09s - Running `target/debug/obdium` -parsing iso_tp response: SEARCHING...\r7E8 10 14 49 02 01 4B 4C 34 \r7E8 21 43 4A 41 53 42 36 4A \r7E8 22 42 36 36 30 39 32 39 \r\r -Bytes: ["7E8", "10", "14", "49", "02", "01", "4B", "4C", "34"] -Bytes: ["7E8", "21", "43", "4A", "41", "53", "42", "36", "4A"] -Bytes: ["7E8", "22", "42", "36", "36", "30", "39", "32", "39"] -payload: ["01", "4B", "4C", "34", "21", "43", "4A", "41", "53", "42", "36", "4A", "22", "42", "36", "36", "30", "39", "32", "39"] -vin response: KL4!CJASB6J"B660929 -error when getting vin. vin length invalid. must be 17 characters - -======================== DIAGNOSTICS ======================== -ECU: 7EA -ECU: 7EB -ECU: 7EA -ECU: 7EB -ECU: 7EA -ECU: 7E8 -ECU: 7E8 -Supported pids for ECUs -ECU 7EB: - 01 0A 20 40 -ECU 7EA: - 01 20 40 42 -ECU 7E8: - 41 42 43 44 45 46 47 49 4A 4C - 4F 51 60 68 -Check engine light: false -Number of trouble codes: 0 -OBD standard: JOBD and OBD-II -Auxiliary input status: Inactive -Control module voltage: 14.646V -Distance traveled with malfunction indicator lamp: 11km -TIme run with malfunction indicator lamp: NO DATA -Time since codes cleared: NO DATA -Warm-ups since codes cleared: NO DATA - -======================== ENGINE ======================== -Engine type: Internal Combustion Engine -Engine speed: 741.75RPM -Engine load: 21.176472% -Coolant temperature: 53°C -Coolant temperatue from sensors - Sensor 1: NO DATA - Sensor 2: NO DATA -Engine fuel rate: NO DATA -Engine runtime: 1792s -Engine runtime (diesel): NO DATA -Engine mileage: NO DATA -Engine oil temperature (Mode 1): NO DATA -Engine oil temperature (Mode 22): 43°C -Engine oil temperatue from sensors - Sensor 1: NO DATA - Sensor 2: NO DATA -Engine oil pressure: 0kPa -Drivers demand engine torque: NO DATA -Actual engine torque: NO DATA -Reference engine torque: NO DATA -Engine percent torque data: - Idle: NO DATA - Engine point 1: NO DATA - Engine point 2: NO DATA - Engine point 3: NO DATA - Engine point 4: NO DATA - -======================== FUEL SYSTEM ======================== -Short term fuel trim: - Bank 1: 3.90625% - Bank 2: NO DATA -Long term fuel trim: - Bank 1: 0.78125% - Bank 2: NO DATA -Fuel system status: -Fuel system 1: Status("Closed loop, using O2 sensor feedback for fuel mix") -Fuel system 2: Status("Motor is off") -Fuel pressure: 294kPa -Fuel tank level: 26.27451% -Fuel rail pressure: NO DATA -Fuel rail gauge pressure: NO DATA -Fuel type: Type("Gasoline") -Ethanol fuel percentage: NO DATA -Fuel injection timing: NO DATA -Commanded EVAP purge: 0% -EVAP system vapor pressure: 16383Pa -Cylinder fuel rate: NO DATA - -======================== SENSOR DATA ======================== -Vehicle speed: 0Kmh -Timing advance: 2° -Throttle position: 21.176472% -Relative throttle position: 7.4509807% -Absolute throttle position B: 20.784313% -Absolute throttle position C: NO DATA -Accelerator pedal position D: 19.607843% -Accelerator pedal position E: 9.803922% -Accelerator pedal position F: NO DATA - -======================== AIR DATA ======================== -Oxygen Sensors: -Sensor Voltage Short Term Trim (%) AFR / Voltage -1 0.78Vv -1.5625% NO DATA / NO DATA -2 1.275Vv 99.21875% NO DATA / NO DATA -3 NO DATAv NO DATA NO DATA / NO DATA -4 NO DATAv NO DATA NO DATA / NO DATA -5 NO DATAv NO DATA NO DATA / NO DATA -6 NO DATAv NO DATA NO DATA / NO DATA -7 NO DATAv NO DATA NO DATA / NO DATA -8 NO DATAv NO DATA NO DATA / NO DATA -Mass air flow sensor: - Sensor A: NO DATA - Sensor B: NO DATA -Maximum values for: - Fuel-air equivalance ratio: 0ratio - Oxygen sensor voltage: 0V - Oxygen sensor current: 0mA - Intake manifold absolute pressure: 310kPa -Intake air temperature: 29°C -Mass air-flow sensor rate: 2.33g/s -Ambient air temperature: 26°C -Maximum air-flow rate from mass air-flow sensor: NO DATA -Secondary air status: Status("Unknown secondary air status") -Absolute barometric pressure: 98kPa - -======================== SENDING MANUAL COMMANDS ======================== \ No newline at end of file diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 948bbdb..0000000 --- a/src/main.rs +++ /dev/null @@ -1,281 +0,0 @@ -use obdium::{ - obd::{ - BankNumber, - Error, - SensorNumber, - Service, - OBD - }, - diagnostics::Test -}; - -use std::fmt::Write; - -fn print_tests_table(title: &str, tests: &[Test]) { - let mut table = String::new(); - writeln!(table, "{title}").unwrap(); - writeln!( - table, - "{:<35} | {:<10} | {:<10}", - "Test Name", "Available", "Complete" - ) - .unwrap(); - writeln!(table, "{:-<35}-+-{:-<10}-+-{:-<10}", "", "", "").unwrap(); - - for test in tests { - writeln!( - table, - "{:<35} | {:<10} | {:<10}", - test.name, - if test.available { "Yes" } else { "No" }, - if test.complete { "Yes" } else { "No" }, - ) - .unwrap(); - } - - println!("{table}"); -} - -fn main() -> Result<(), Error> { - let mut obd = OBD::new(); - //obd.replay_requests(true); - //obd.record_requests(true); - obd.connect("COM4", 38400)?; - - println!("\n{} DIAGNOSTICS {}", "=".repeat(24), "=".repeat(24)); - let supported_pids = obd.get_service_supported_pids("01"); - - println!("Supported pids for ECUs"); - for (ecu_name, pids) in supported_pids.iter() { - print!("ECU {ecu_name}:"); - for (index, pid) in pids.iter().enumerate() { - if index % 10 == 0 { - print!("\n\t"); - } - - print!("{pid} "); - if index == pids.len() - 1 { - println!() - } - } - } - - println!("Check engine light: {}", obd.check_engine_light()); - println!("Number of trouble codes: {}", obd.get_num_trouble_codes()); - - let codes = obd.get_trouble_codes(); - for code in codes { - println!("{}\n", code); - } - - println!("OBD standard: {}", obd.obd_standards()); - println!("Auxiliary input status: {}", obd.aux_input_status()); - println!("Control module voltage: {}", obd.control_module_voltage()); - println!( - "Distance traveled with malfunction indicator lamp: {}", - obd.distance_traveled_with_mil() - ); - println!( - "TIme run with malfunction indicator lamp: {}", - obd.time_run_with_mil() - ); - println!( - "Time since codes cleared: {}", - obd.time_since_codes_cleared() - ); - println!( - "Warm-ups since codes cleared: {}", - obd.warm_ups_since_codes_cleared() - ); - println!("Protocol: {}", obd.get_protocol().unwrap()); - - println!(); - print_tests_table("Common tests", &obd.get_common_tests_status()); - print_tests_table("Advanced tests", &obd.get_advanced_tests_status()); - - println!("{} ENGINE {}", "=".repeat(24), "=".repeat(24)); - println!("Engine type: {}", obd.get_engine_type()); - println!("Engine speed: {}", obd.rpm()); - println!("Engine load: {}", obd.engine_load()); - - let coolant_temp = obd.coolant_temp_sensors(); - println!("Coolant temperature: {}", obd.coolant_temp()); - println!( - "Coolant temperatue from sensors - Sensor 1: {} - Sensor 2: {} ", - coolant_temp.0, coolant_temp.1 - ); - println!("Engine fuel rate: {}", obd.engine_fuel_rate()); - println!("Engine runtime: {}", obd.engine_runtime()); - println!("Engine runtime (diesel): {}", obd.engine_runtime_diesel()); - println!("Engine mileage: {}", obd.odometer()); - - let oil_temp = obd.engine_oil_temp_sensors(); - println!( - "Engine oil temperature (Mode 1): {}", - obd.engine_oil_temp(Service::Mode01) - ); - println!( - "Engine oil temperature (Mode 22): {}", - obd.engine_oil_temp(Service::Mode22) - ); - println!( - "Engine oil temperatue from sensors - Sensor 1: {} - Sensor 2: {} ", - oil_temp.0, oil_temp.1 - ); - println!("Engine oil pressure: {}", obd.engine_oil_pressure()); // Mode 22 PID - - println!( - "Drivers demand engine torque: {}", - obd.drivers_demand_engine_torque() - ); - println!("Actual engine torque: {}", obd.actual_engine_torque()); - println!("Reference engine torque: {}", obd.reference_engine_torque()); - - let percent_torque_data = obd.engine_percent_torque_data(); - println!("Engine percent torque data:"); - println!("\tIdle: {}", percent_torque_data.0); - println!("\tEngine point 1: {}", percent_torque_data.1); - println!("\tEngine point 2: {}", percent_torque_data.2); - println!("\tEngine point 3: {}", percent_torque_data.3); - println!("\tEngine point 4: {}", percent_torque_data.4); - - println!("\n{} FUEL SYSTEM {}", "=".repeat(24), "=".repeat(24)); - - println!("Short term fuel trim:"); - println!("\tBank 1: {}", obd.short_term_fuel_trim(BankNumber::Bank1)); - println!("\tBank 2: {}", obd.short_term_fuel_trim(BankNumber::Bank2)); - - println!("Long term fuel trim:"); - println!("\tBank 1: {}", obd.long_term_fuel_trim(BankNumber::Bank1)); - println!("\tBank 2: {}", obd.long_term_fuel_trim(BankNumber::Bank2)); - - let fuel_system_status = obd.fuel_system_status(); - println!("Fuel system status:"); - println!("Fuel system 1: {:?}", fuel_system_status.0); - println!("Fuel system 2: {:?}", fuel_system_status.1); - - println!("Fuel pressure: {}", obd.fuel_pressure()); - println!("Fuel tank level: {}", obd.fuel_tank_level()); - println!("Fuel rail pressure: {}", obd.fuel_rail_pressure()); - println!( - "Fuel rail gauge pressure: {}", - obd.fuel_rail_guage_pressure() - ); - println!("Fuel type: {:?}", obd.fuel_type()); - println!("Ethanol fuel percentage: {}", obd.ethanol_fuel_percentage()); - println!("Fuel injection timing: {}", obd.fuel_injection_timing()); - println!("Commanded EVAP purge: {}", obd.commanded_evap_purge()); - println!( - "EVAP system vapor pressure: {}", - obd.evap_system_vapor_pressure() - ); - println!("Cylinder fuel rate: {}", obd.cylinder_fuel_rate()); - - println!("\n{} SENSOR DATA {}", "=".repeat(24), "=".repeat(24)); - println!("Vehicle speed: {}", obd.vehicle_speed()); - println!("Timing advance: {}", obd.timing_advance()); - - println!("Throttle position: {}", obd.throttle_position()); - println!( - "Relative throttle position: {}", - obd.relative_throttle_pos() - ); - println!( - "Absolute throttle position B: {}", - obd.abs_throttle_position_b() - ); - println!( - "Absolute throttle position C: {}", - obd.abs_throttle_position_c() - ); - println!( - "Accelerator pedal position D: {}", - obd.acc_pedal_position_d() - ); - println!( - "Accelerator pedal position E: {}", - obd.acc_pedal_position_e() - ); - println!( - "Accelerator pedal position F: {}", - obd.acc_pedal_position_f() - ); - - // Read oxcygen sensors 1-8 - let sensors = [ - SensorNumber::Sensor1, - SensorNumber::Sensor2, - SensorNumber::Sensor3, - SensorNumber::Sensor4, - SensorNumber::Sensor5, - SensorNumber::Sensor6, - SensorNumber::Sensor7, - SensorNumber::Sensor8, - ]; - - let mut data = Vec::new(); - - for (i, sensor) in sensors.iter().enumerate() { - let (voltage1, trim) = obd.read_oxygen_sensor(sensor); - let (afr, voltage2) = obd.o2_sensor_air_fuel_ratio(sensor); - data.push((i + 1, voltage1, trim, afr, voltage2)); - } - - println!("\n{} AIR DATA {}", "=".repeat(24), "=".repeat(24)); - println!("Oxygen Sensors:"); - println!( - "{:<8} | {:<10} | {:<22} | {:<22}", - "Sensor", "Voltage", "Short Term Trim (%)", "AFR / Voltage" - ); - println!("{:-<8}-+-{:-<10}-+-{:-<22}-+-{:-<22}", "", "", "", ""); - - for (sensor_id, v1, trim, afr, v2) in data { - println!( - "{:<8} | {:<10} | {:<22} | {:<22}", - sensor_id, - format!("{v1}"), - format!("{trim}"), - format!("{afr} / {v2}") - ); - } - - let maf = obd.read_mass_air_flow_sensor(); - println!("Mass air flow sensor:"); - println!("\tSensor A: {}", maf.0); - println!("\tSensor B: {}", maf.1); - - let max_values_for = obd.max_values_for(); - println!("Maximum values for:"); - println!("\tFuel-air equivalance ratio: {}", max_values_for.0); - println!("\tOxygen sensor voltage: {}", max_values_for.1); - println!("\tOxygen sensor current: {}", max_values_for.2); - println!("\tIntake manifold absolute pressure: {}", max_values_for.3); - - println!("Intake air temperature: {}", obd.intake_air_temp()); - println!("Mass air-flow sensor rate: {}", obd.maf_air_flow_rate()); - println!("Ambient air temperature: {}", obd.ambient_air_temp()); - println!( - "Maximum air-flow rate from mass air-flow sensor: {}", - obd.max_air_flow_rate_from_maf() - ); - - println!("Secondary air status: {:?}", obd.secondary_air_status()); - println!( - "Absolute barometric pressure: {}", - obd.abs_barometric_pressure() - ); - - println!( - "\n{} SENDING MANUAL COMMANDS {}", - "=".repeat(24), - "=".repeat(24) - ); - - if let Some(vin) = obd.get_vin() { - obd.test_mode_22_pids(&vin); - } - - obd.read_from_user_input(); - - Ok(()) -}