diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml new file mode 100644 index 0000000..d7e5834 --- /dev/null +++ b/.github/workflows/action.yml @@ -0,0 +1,30 @@ +name: GitHub Actions +on: [push] +jobs: + action-run: + # runs-on: ubuntu-22.04 + runs-on: ubuntu-latest + steps: + - run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event." + - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" + - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." + - name: Check out repository code + uses: actions/checkout@v3 + - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner." + - run: echo "The ${{ github.workspace }} is now ready to test your code on the runner." + - run: ls ${{ github.workspace }} + - run: sudo apt update + - run: sudo apt install libxcb-composite0-dev + + - run: echo "start install Rust..." + - name: Install Rust + uses: actions-rs/toolchain@v1 + - run: echo "end install Rust..." + + - run: echo "start build..." + - name: Install Cargo + uses: actions-rs/cargo@v1 + with: + command: build + - run: echo "end build..." + - run: echo "🍏 This job's status is ${{ job.status }}." diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6b917fc --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +error.log +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..fab7a34 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,6794 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ab_glyph" +version = "0.2.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79faae4620f45232f599d9bc7b290f88247a0834162c4495ab2f02d60004adfb" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" + +[[package]] +name = "accesskit" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4700bdc115b306d6c43381c344dc307f03b7f0460c304e4892c309930322bd7" + +[[package]] +name = "accesskit_atspi_common" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1de72dc7093910a1284cef784b6b143bab0a34d67f6178e4fc3aaaf29a09f8b" +dependencies = [ + "accesskit", + "accesskit_consumer", + "atspi-common", + "serde", + "thiserror", + "zvariant", +] + +[[package]] +name = "accesskit_consumer" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe3a07a32ab5837ad83db3230ac490c8504c2cd5b90ac8c00db6535f6ed65d0b" +dependencies = [ + "accesskit", + "immutable-chunkmap", +] + +[[package]] +name = "accesskit_macos" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a189d159c153ae0fce5f9eefdcfec4a27885f453ce5ef0ccf078f72a73c39d34" +dependencies = [ + "accesskit", + "accesskit_consumer", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "once_cell", +] + +[[package]] +name = "accesskit_unix" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b76c448cfd96d16131a9ad3ab786d06951eb341cdac1db908978ab010245a19d" +dependencies = [ + "accesskit", + "accesskit_atspi_common", + "async-channel", + "async-executor", + "async-task", + "atspi", + "futures-lite 1.13.0", + "futures-util", + "serde", + "zbus", +] + +[[package]] +name = "accesskit_windows" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "682d8c4fb425606f97408e7577793f32e96310b646fa77662eb4216293eddc7f" +dependencies = [ + "accesskit", + "accesskit_consumer", + "paste", + "static_assertions", + "windows 0.54.0", +] + +[[package]] +name = "accesskit_winit" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afbd6d598b7c035639ad2b664aa0edc94c93dc1fc3ebb4b40d8a95fcd43ffac" +dependencies = [ + "accesskit", + "accesskit_macos", + "accesskit_unix", + "accesskit_windows", + "raw-window-handle", + "winit", +] + +[[package]] +name = "addr2line" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", + "opaque-debug", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "android-activity" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee91c0c2905bae44f84bfa4e044536541df26b7703fd0888deeb9060fcc44289" +dependencies = [ + "android-properties", + "bitflags 2.6.0", + "cc", + "cesu8", + "jni", + "jni-sys", + "libc", + "log", + "ndk 0.8.0", + "ndk-context", + "ndk-sys 0.5.0+25.2.9519653", + "num_enum", + "thiserror", +] + +[[package]] +name = "android-activity" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" +dependencies = [ + "android-properties", + "bitflags 2.6.0", + "cc", + "cesu8", + "jni", + "jni-sys", + "libc", + "log", + "ndk 0.9.0", + "ndk-context", + "ndk-sys 0.6.0+11769913", + "num_enum", + "thiserror", +] + +[[package]] +name = "android-properties" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_log-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ecc8056bf6ab9892dcd53216c83d1597487d7dacac16c8df6b877d127df9937" + +[[package]] +name = "android_logger" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c494134f746c14dc653a35a4ea5aca24ac368529da5370ecf41fe0341c35772f" +dependencies = [ + "android_log-sys", + "env_logger", + "log", + "once_cell", +] + +[[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.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "as-raw-xcb-connection" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" + +[[package]] +name = "async-broadcast" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c48ccdbf6ca6b121e0f586cbc0e73ae440e56c67c30fa0873b4e110d9c26d2b" +dependencies = [ + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7ebdfa2ebdab6b1760375fa7d6f382b9f486eac35fc994625a00e89280bdbb7" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand 2.1.0", + "futures-lite 2.3.0", + "slab", +] + +[[package]] +name = "async-fs" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "blocking", + "futures-lite 1.13.0", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite 1.13.0", + "log", + "parking", + "polling 2.8.0", + "rustix 0.37.27", + "slab", + "socket2 0.4.10", + "waker-fn", +] + +[[package]] +name = "async-io" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" +dependencies = [ + "async-lock 3.4.0", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite 2.3.0", + "parking", + "polling 3.7.2", + "rustix 0.38.34", + "slab", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener 2.5.3", +] + +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener 5.3.1", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-process" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +dependencies = [ + "async-io 1.13.0", + "async-lock 2.8.0", + "async-signal", + "blocking", + "cfg-if", + "event-listener 3.1.0", + "futures-lite 1.13.0", + "rustix 0.38.34", + "windows-sys 0.48.0", +] + +[[package]] +name = "async-recursion" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "async-signal" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb3634b73397aa844481f814fad23bbf07fdb0eabec10f2eb95e58944b1ec32" +dependencies = [ + "async-io 2.3.3", + "async-lock 3.4.0", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 0.38.34", + "signal-hook-registry", + "slab", + "windows-sys 0.52.0", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "atspi" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6059f350ab6f593ea00727b334265c4dfc7fd442ee32d264794bd9bdc68e87ca" +dependencies = [ + "atspi-common", + "atspi-connection", + "atspi-proxies", +] + +[[package]] +name = "atspi-common" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92af95f966d2431f962bc632c2e68eda7777330158bf640c4af4249349b2cdf5" +dependencies = [ + "enumflags2", + "serde", + "static_assertions", + "zbus", + "zbus_names", + "zvariant", +] + +[[package]] +name = "atspi-connection" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c65e7d70f86d4c0e3b2d585d9bf3f979f0b19d635a336725a88d279f76b939" +dependencies = [ + "atspi-common", + "atspi-proxies", + "futures-lite 1.13.0", + "zbus", +] + +[[package]] +name = "atspi-proxies" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6495661273703e7a229356dcbe8c8f38223d697aacfaf0e13590a9ac9977bb52" +dependencies = [ + "atspi-common", + "serde", + "zbus", +] + +[[package]] +name = "auto_enums" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1899bfcfd9340ceea3533ea157360ba8fa864354eccbceab58e1006ecab35393" +dependencies = [ + "derive_utils", + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "backtrace" +version = "0.3.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[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 = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bindgen" +version = "0.69.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +dependencies = [ + "bitflags 2.6.0", + "cexpr", + "clang-sys", + "itertools 0.12.1", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.71", + "which", +] + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +dependencies = [ + "serde", +] + +[[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 = "block-modes" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cb03d1bed155d89dce0f845b7899b18a9a163e148fd004e1c28421a783e2d8e" +dependencies = [ + "block-padding", + "cipher", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "block2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +dependencies = [ + "objc2", +] + +[[package]] +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel", + "async-task", + "futures-io", + "futures-lite 2.3.0", + "piper", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "by_address" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" + +[[package]] +name = "bytemuck" +version = "1.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee891b04274a59bd38b412188e24b849617b2e45a0fd8d057deb63e7403761b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" + +[[package]] +name = "calloop" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" +dependencies = [ + "bitflags 2.6.0", + "log", + "polling 3.7.2", + "rustix 0.38.34", + "slab", + "thiserror", +] + +[[package]] +name = "calloop" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" +dependencies = [ + "bitflags 2.6.0", + "log", + "polling 3.7.2", + "rustix 0.38.34", + "slab", + "thiserror", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" +dependencies = [ + "calloop 0.13.0", + "rustix 0.38.34", + "wayland-backend", + "wayland-client", +] + +[[package]] +name = "cc" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "324c74f2155653c90b04f25b2a47a8a631360cb908f92a772695f430c7e31052" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "cgl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" +dependencies = [ + "libc", +] + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.52.6", +] + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading 0.8.4", +] + +[[package]] +name = "clipboard" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a904646c0340239dcf7c51677b33928bf24fdf424b79a57909c0109075b2e7" +dependencies = [ + "clipboard-win 2.2.0", + "objc", + "objc-foundation", + "objc_id", + "x11-clipboard 0.3.3", +] + +[[package]] +name = "clipboard-win" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a093d6fed558e5fe24c3dfc85a68bb68f1c824f440d3ba5aca189e2998786b" +dependencies = [ + "winapi", +] + +[[package]] +name = "clipboard-win" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fdf5e01086b6be750428ba4a40619f847eb2e95756eee84b18e06e5f0b50342" +dependencies = [ + "lazy-bytes-cast", + "winapi", +] + +[[package]] +name = "clipboard-win" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7191c27c2357d9b7ef96baac1773290d4ca63b24205b82a3fd8a0637afcf0362" +dependencies = [ + "error-code", + "str-buf", + "winapi", +] + +[[package]] +name = "clipboard_macos" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "145a7f9e9b89453bc0a5e32d166456405d389cea5b578f57f1274b1397588a95" +dependencies = [ + "objc", + "objc-foundation", + "objc_id", +] + +[[package]] +name = "clru" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbd0f76e066e64fdc5631e3bb46381254deab9ef1158292f27c8c57e3bf3fe59" + +[[package]] +name = "cmd_lib" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718f77610af91e4d648fe9da0150ae58698cbcfb93bf63e764907fbefd56ffe8" +dependencies = [ + "cmd_lib_macros", + "env_logger", + "faccess", + "lazy_static", + "log", + "os_pipe", +] + +[[package]] +name = "cmd_lib_macros" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a80fac05ed12fe97a70b5dfdd910c9b90b53f4de69002c3179e29ac2d066abc" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cocoa" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" +dependencies = [ + "bitflags 1.3.2", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics", + "foreign-types 0.5.0", + "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", + "core-graphics-types", + "libc", + "objc", +] + +[[package]] +name = "codemap" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e769b5c8c8283982a987c6e948e540254f1058d5a74b8794914d4ef5fc2a24" + +[[package]] +name = "codemap-diagnostic" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc20770be05b566a963bf91505e60412c4a2d016d1ef95c5512823bb085a8122" +dependencies = [ + "codemap", + "termcolor", +] + +[[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 = "commoncrypto" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" +dependencies = [ + "commoncrypto-sys", +] + +[[package]] +name = "commoncrypto-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" +dependencies = [ + "libc", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const-field-offset" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fcde4ca1211b5a94b573083c472ee19e86b19a441913f66e1cc5c41daf0255" +dependencies = [ + "const-field-offset-macro", + "field-offset", +] + +[[package]] +name = "const-field-offset-macro" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5387f5bbc9e9e6c96436ea125afa12614cebf8ac67f49abc08c1e7a891466c90" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "copypasta" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deb85422867ca93da58b7f95fb5c0c10f6183ed6e1ef8841568968a896d3a858" +dependencies = [ + "clipboard-win 3.1.1", + "objc", + "objc-foundation", + "objc_id", + "smithay-clipboard", + "x11-clipboard 0.9.2", +] + +[[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-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "core-graphics" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types 0.5.0", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + +[[package]] +name = "core-text" +version = "20.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d2790b5c08465d49f8dc05c8bcae9fea467855947db39b0f8145c091aaced5" +dependencies = [ + "core-foundation", + "core-graphics", + "foreign-types 0.5.0", + "libc", +] + +[[package]] +name = "countme" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636" + +[[package]] +name = "cpp" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa65869ef853e45c60e9828aa08cdd1398cb6e13f3911d9cb2a079b144fcd64" +dependencies = [ + "cpp_macros", +] + +[[package]] +name = "cpp_build" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e361fae2caf9758164b24da3eedd7f7d7451be30d90d8e7b5d2be29a2f0cf5b" +dependencies = [ + "cc", + "cpp_common", + "lazy_static", + "proc-macro2", + "regex", + "syn 2.0.71", + "unicode-xid", +] + +[[package]] +name = "cpp_common" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e1a2532e4ed4ea13031c13bc7bc0dbca4aae32df48e9d77f0d1e743179f2ea1" +dependencies = [ + "lazy_static", + "proc-macro2", + "syn 2.0.71", +] + +[[package]] +name = "cpp_macros" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47ec9cc90633446f779ef481a9ce5a0077107dd5b87016440448d908625a83fd" +dependencies = [ + "aho-corasick", + "byteorder", + "cpp_common", + "lazy_static", + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "critical-section" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +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-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[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 = "crypto-hash" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a77162240fd97248d19a564a565eb563a3f592b386e4136fb300909e67dddca" +dependencies = [ + "commoncrypto", + "hex 0.3.2", + "openssl", + "winapi", +] + +[[package]] +name = "css-color-parser2" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8ed1639f4b56ec6f31d007ff66ce4a13099dce5a9995d48368a30d62bf04bd" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "ctor-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f791803201ab277ace03903de1594460708d2d54df6053f2d9e82f592b19e3b" + +[[package]] +name = "cursor-icon" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" + +[[package]] +name = "cutil" +version = "0.1.0" +dependencies = [ + "aes", + "anyhow", + "block-modes", + "bytes", + "chrono", + "crypto-hash", + "hex 0.4.3", + "rand", + "reqwest", +] + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.71", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "data-url" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a" + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "0.99.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.71", +] + +[[package]] +name = "derive_utils" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61bb5a1014ce6dfc2a378578509abe775a5aa06bff584a547555d9efdb81b926" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs-next" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf36e65a80337bea855cd4ef9b8401ffce06a7baedf2e85ec467b1ac3f6e82b6" +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 = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading 0.8.4", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "dpi" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" + +[[package]] +name = "drm" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edf9159ef4bcecd0c5e4cbeb573b8d0037493403d542780dba5d840bbf9df56f" +dependencies = [ + "bitflags 1.3.2", + "bytemuck", + "drm-ffi", + "drm-fourcc", + "nix 0.26.4", +] + +[[package]] +name = "drm-ffi" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1352481b7b90e27a8a1bf8ef6b33cf18b98dba7c410e75c24bb3eef2f0d8d525" +dependencies = [ + "drm-sys", + "nix 0.26.4", +] + +[[package]] +name = "drm-fourcc" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4" + +[[package]] +name = "drm-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1369f1679d6b706d234c4c1e0613c415c2c74b598a09ad28080ba2474b72e42d" +dependencies = [ + "libc", +] + +[[package]] +name = "dwrote" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439a1c2ba5611ad3ed731280541d36d2e9c4ac5e7fb818a27b604bdc5a6aa65b" +dependencies = [ + "lazy_static", + "libc", + "serde", + "serde_derive", + "winapi", + "wio", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +dependencies = [ + "serde", +] + +[[package]] +name = "embed-resource" +version = "2.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4edcacde9351c33139a41e3c97eb2334351a81a2791bebb0b243df837128f602" +dependencies = [ + "cc", + "memchr", + "rustc_version", + "toml", + "vswhom", + "winreg 0.52.0", +] + +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enumflags2" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "env_logger" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "error-code" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21" +dependencies = [ + "libc", + "str-buf", +] + +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + +[[package]] +name = "euclid" +version = "0.22.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0f0eb73b934648cd7a4a61f1b15391cd95dab0b4da6e2e66c2a072c144b4a20" +dependencies = [ + "num-traits", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "5.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +dependencies = [ + "event-listener 5.3.1", + "pin-project-lite", +] + +[[package]] +name = "exr" +version = "1.72.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + +[[package]] +name = "faccess" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ae66425802d6a903e268ae1a08b8c38ba143520f227a205edf4e9c7e3e26d5" +dependencies = [ + "bitflags 1.3.2", + "libc", + "winapi", +] + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[package]] +name = "fdeflate" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "femtovg" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47921d14afc4daad9bedc926099bc6edcaa23e37a957448f86cdefcbafe2f632" +dependencies = [ + "bitflags 2.6.0", + "fnv", + "glow", + "image 0.25.1", + "imgref", + "log", + "lru", + "rgb", + "rustybuzz", + "slotmap", + "unicode-bidi", + "unicode-segmentation", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset 0.9.1", + "rustc_version", +] + +[[package]] +name = "filetime" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", +] + +[[package]] +name = "flate2" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "futures-core", + "futures-sink", + "spin", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "fontconfig-parser" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a595cb550439a117696039dfc69830492058211b771a2a165379f2a1a53d84d" +dependencies = [ + "roxmltree 0.19.0", +] + +[[package]] +name = "fontdb" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e32eac81c1135c1df01d4e6d4233c47ba11f6a6d07f33e0bba09d18797077770" +dependencies = [ + "fontconfig-parser", + "log", + "memmap2 0.9.4", + "slotmap", + "tinyvec", + "ttf-parser 0.21.1", +] + +[[package]] +name = "fontdue" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efe23d02309319171d00d794c9ff48d4f903c0e481375b1b04b017470838af04" +dependencies = [ + "hashbrown 0.14.5", + "ttf-parser 0.21.1", +] + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared 0.1.1", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared 0.3.1", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-lite" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "fastrand 2.1.0", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "gbm" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ec389cda876966cf824111bf6e533fb934c711d473498279964a990853b3c6" +dependencies = [ + "bitflags 1.3.2", + "drm", + "drm-fourcc", + "gbm-sys", + "libc", +] + +[[package]] +name = "gbm-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63eba9b9b7a231514482deb08759301c9f9f049ac6869403f381834ebfeaf67" +dependencies = [ + "libc", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "gethostname" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb65d4ba3173c56a500b555b532f72c42e8d1fe64962b518897f8959fae2c177" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "gethostname" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +dependencies = [ + "libc", + "windows-targets 0.48.5", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "gimli" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" + +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "glow" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glutin" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2491aa3090f682ddd920b184491844440fdd14379c7eef8f5bc10ef7fb3242fd" +dependencies = [ + "bitflags 2.6.0", + "cfg_aliases", + "cgl", + "core-foundation", + "dispatch", + "glutin_egl_sys", + "glutin_glx_sys", + "glutin_wgl_sys", + "libloading 0.8.4", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "once_cell", + "raw-window-handle", + "wayland-sys", + "windows-sys 0.52.0", + "x11-dl", +] + +[[package]] +name = "glutin-winit" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85edca7075f8fc728f28cb8fbb111a96c3b89e930574369e3e9c27eb75d3788f" +dependencies = [ + "cfg_aliases", + "glutin", + "raw-window-handle", + "winit", +] + +[[package]] +name = "glutin_egl_sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cae99fff4d2850dbe6fb8c1fa8e4fead5525bab715beaacfccf3fb994e01c827" +dependencies = [ + "gl_generator", + "windows-sys 0.52.0", +] + +[[package]] +name = "glutin_glx_sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c2b2d3918e76e18e08796b55eb64e8fe6ec67d5a6b2e2a7e2edce224ad24c63" +dependencies = [ + "gl_generator", + "x11-dl", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a4e1951bbd9434a81aa496fe59ccc2235af3820d27b85f9314e279609211e2c" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.2.6", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.5", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] +name = "hex" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.5.7", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "i-slint-backend-android-activity" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2da124c519f5defb8f25a3bb000396e11b0c32c799237e45ac1f1514be36472f" +dependencies = [ + "android-activity 0.5.2", + "android-activity 0.6.0", + "i-slint-core", + "i-slint-renderer-skia", + "jni", + "ndk 0.9.0", + "raw-window-handle", +] + +[[package]] +name = "i-slint-backend-linuxkms" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17924cec94f3411fb3b2ef25259ceca0eae837db5387e13c4052c3e1fcccc190" +dependencies = [ + "bytemuck", + "calloop 0.12.4", + "drm", + "gbm", + "gbm-sys", + "glutin", + "i-slint-common", + "i-slint-core", + "i-slint-renderer-femtovg", + "input", + "memmap2 0.9.4", + "nix 0.27.1", + "raw-window-handle", + "xkbcommon", +] + +[[package]] +name = "i-slint-backend-qt" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bc990b005abc9dd10b133e01398a76d3894af8763740fe683304056006f2d88" +dependencies = [ + "const-field-offset", + "cpp", + "cpp_build", + "i-slint-common", + "i-slint-core", + "i-slint-core-macros", + "lyon_path", + "once_cell", + "pin-project", + "pin-weak", + "qttypes", + "vtable", +] + +[[package]] +name = "i-slint-backend-selector" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1398edffc061119b3fc547e5cde49683d47de806f1d8e431faa913a995c66d12" +dependencies = [ + "cfg-if", + "i-slint-backend-linuxkms", + "i-slint-backend-qt", + "i-slint-backend-winit", + "i-slint-common", + "i-slint-core", +] + +[[package]] +name = "i-slint-backend-winit" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc34a993838bd2d3625f1f64ae4324b490dbb0e1e410a0be71fffaae1df825" +dependencies = [ + "accesskit", + "accesskit_winit", + "bytemuck", + "cfg-if", + "cfg_aliases", + "cocoa", + "const-field-offset", + "copypasta", + "derive_more", + "glutin", + "glutin-winit", + "i-slint-common", + "i-slint-core", + "i-slint-core-macros", + "i-slint-renderer-femtovg", + "i-slint-renderer-skia", + "imgref", + "lyon_path", + "once_cell", + "pin-weak", + "raw-window-handle", + "rgb", + "scoped-tls-hkt", + "scopeguard", + "softbuffer", + "wasm-bindgen", + "web-sys", + "winit", +] + +[[package]] +name = "i-slint-common" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79721ae5b531dc2c5e1ecc2160e042c2563e0bf7cde688e0f27fc3feb90ccd60" +dependencies = [ + "cfg-if", + "derive_more", + "fontdb", + "libloading 0.8.4", +] + +[[package]] +name = "i-slint-compiler" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cc4854b2842ef0858d6c5a483e0125b8db70a84d270497743d104f322314b97" +dependencies = [ + "by_address", + "codemap", + "codemap-diagnostic", + "css-color-parser2", + "derive_more", + "fontdue", + "i-slint-common", + "image 0.24.9", + "itertools 0.13.0", + "linked_hash_set", + "lyon_extra", + "lyon_path", + "num_enum", + "once_cell", + "proc-macro2", + "quote", + "resvg", + "rowan", + "smol_str", + "strum", + "thiserror", + "url", +] + +[[package]] +name = "i-slint-core" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d980dabb573ca810538a47647c9ab98c58daa97a06d51d912300ba5abc719bb0" +dependencies = [ + "auto_enums", + "bitflags 2.6.0", + "bytemuck", + "cfg-if", + "chrono", + "clru", + "const-field-offset", + "derive_more", + "euclid", + "fontdue", + "i-slint-common", + "i-slint-core-macros", + "image 0.24.9", + "integer-sqrt", + "lyon_algorithms", + "lyon_extra", + "lyon_geom", + "lyon_path", + "num-traits", + "once_cell", + "pin-project", + "pin-weak", + "portable-atomic", + "raw-window-handle", + "resvg", + "rgb", + "rustybuzz", + "scoped-tls-hkt", + "scopeguard", + "slab", + "static_assertions", + "strum", + "unicode-linebreak", + "unicode-script", + "unicode-segmentation", + "vtable", + "wasm-bindgen", + "web-sys", + "web-time", +] + +[[package]] +name = "i-slint-core-macros" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f38c93191fc4264887ac9fdcd8537f81353df9be20254039d880f36bad97ac1" +dependencies = [ + "quote", + "syn 2.0.71", +] + +[[package]] +name = "i-slint-renderer-femtovg" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b85a2de6699a2e2d4faaa6780621366c5363de8580af53dc5edeafa408b92686" +dependencies = [ + "cfg-if", + "const-field-offset", + "core-foundation", + "core-text", + "derive_more", + "dwrote", + "femtovg", + "glow", + "i-slint-common", + "i-slint-core", + "i-slint-core-macros", + "imgref", + "lyon_path", + "once_cell", + "pin-weak", + "rgb", + "scoped-tls-hkt", + "ttf-parser 0.21.1", + "unicode-script", + "unicode-segmentation", + "wasm-bindgen", + "web-sys", + "winapi", +] + +[[package]] +name = "i-slint-renderer-skia" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "535141cb4349f3677d097a46170b07cc11672dbb1dbdc7eade4a3b6f4ed2a110" +dependencies = [ + "bytemuck", + "cfg-if", + "cfg_aliases", + "cocoa", + "const-field-offset", + "core-foundation", + "core-graphics-types", + "derive_more", + "foreign-types 0.5.0", + "glow", + "glutin", + "i-slint-common", + "i-slint-core", + "i-slint-core-macros", + "lyon_path", + "metal", + "objc", + "once_cell", + "pin-weak", + "raw-window-handle", + "scoped-tls-hkt", + "skia-safe", + "softbuffer", + "unicode-segmentation", + "vtable", + "windows 0.56.0", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core 0.52.0", +] + +[[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 = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "image" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "jpeg-decoder", + "num-traits", + "png", + "qoi", + "tiff", +] + +[[package]] +name = "image" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11" +dependencies = [ + "bytemuck", + "byteorder", + "num-traits", +] + +[[package]] +name = "imagesize" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284" + +[[package]] +name = "imgref" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" + +[[package]] +name = "immutable-chunkmap" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4419f022e55cc63d5bbd6b44b71e1d226b9c9480a47824c706e9d54e5c40c5eb" +dependencies = [ + "arrayvec", +] + +[[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.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.5", + "serde", +] + +[[package]] +name = "input" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e74cd82cedcd66db78742a8337bdc48f188c4d2c12742cbc5cd85113f0b059" +dependencies = [ + "bitflags 1.3.2", + "input-sys", + "io-lifetimes", + "libc", + "log", + "udev", +] + +[[package]] +name = "input-sys" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd4f5b4d1c00331c5245163aacfe5f20be75b564c7112d45893d4ae038119eb0" + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "integer-sqrt" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" +dependencies = [ + "num-traits", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "is-terminal" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "java-locator" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2abecabd9961c5e01405a6426687fcf1bd94a269927137e4c3cc1a7419b93fd" +dependencies = [ + "glob", + "lazy_static", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "java-locator", + "jni-sys", + "libloading 0.7.4", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +dependencies = [ + "libc", +] + +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" +dependencies = [ + "rayon", +] + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + +[[package]] +name = "kurbo" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5aa9f0f96a938266bdb12928a67169e8d22c6a786fda8ed984b85e6ba93c3c" +dependencies = [ + "arrayvec", + "smallvec", +] + +[[package]] +name = "lazy-bytes-cast" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10257499f089cd156ad82d0a9cd57d9501fa2c989068992a97eb3c27836f206b" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libloading" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d" +dependencies = [ + "cfg-if", + "windows-targets 0.52.6", +] + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607" +dependencies = [ + "bitflags 2.6.0", + "libc", + "redox_syscall 0.4.1", +] + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[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 = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linked_hash_set" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47186c6da4d81ca383c7c47c1bfc80f4b95f4720514d860a5407aaf4233f9588" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "lru" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" + +[[package]] +name = "lyon_algorithms" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3bca95f9a4955b3e4a821fbbcd5edfbd9be2a9a50bb5758173e5358bfb4c623" +dependencies = [ + "lyon_path", + "num-traits", +] + +[[package]] +name = "lyon_extra" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c4a243ce61e7e5f3ae6c72a88d8fb081b6c69f13500c15e99cfd1159a833b20" +dependencies = [ + "lyon_path", + "thiserror", +] + +[[package]] +name = "lyon_geom" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edecfb8d234a2b0be031ab02ebcdd9f3b9ee418fb35e265f7a540a48d197bff9" +dependencies = [ + "arrayvec", + "euclid", + "num-traits", +] + +[[package]] +name = "lyon_path" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c08a606c7a59638d6c6aa18ac91a06aa9fb5f765a7efb27e6a4da58700740d7" +dependencies = [ + "lyon_geom", + "num-traits", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memmap2" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a5a03cefb0d953ec0be133036f14e109412fa594edc2f77227249db66cc3ed" +dependencies = [ + "libc", +] + +[[package]] +name = "memmap2" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "metal" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43f73953f8cbe511f021b58f18c3ce1c3d1ae13fe953293e13345bf83217f25" +dependencies = [ + "bitflags 2.6.0", + "block", + "core-graphics-types", + "foreign-types 0.5.0", + "log", + "objc", + "paste", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "native-tls" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "ndk" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" +dependencies = [ + "bitflags 2.6.0", + "jni-sys", + "log", + "ndk-sys 0.5.0+25.2.9519653", + "num_enum", + "thiserror", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.6.0", + "jni-sys", + "log", + "ndk-sys 0.6.0+11769913", + "num_enum", + "raw-window-handle", + "thiserror", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.5.0+25.2.9519653" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.7.1", +] + +[[package]] +name = "nix" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "libc", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.9", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +dependencies = [ + "proc-macro-crate 3.1.0", + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[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-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags 2.6.0", + "block2", + "libc", + "objc2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation", + "objc2-quartz-core", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-image" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-core-location" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +dependencies = [ + "block2", + "objc2", + "objc2-contacts", + "objc2-foundation", +] + +[[package]] +name = "objc2-encode" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.6.0", + "block2", + "dispatch", + "libc", + "objc2", +] + +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2", + "objc2", + "objc2-app-kit", + "objc2-foundation", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation", + "objc2-link-presentation", + "objc2-quartz-core", + "objc2-symbols", + "objc2-uniform-type-identifiers", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-uniform-type-identifiers" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +dependencies = [ + "critical-section", + "portable-atomic", +] + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "foreign-types 0.3.2", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-src" +version = "300.3.1+3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7259953d42a81bf137fbbd73bd30a8e1914d6dce43c2b90ed575783a22608b91" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +dependencies = [ + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "orbclient" +version = "0.3.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166" +dependencies = [ + "libredox 0.0.2", +] + +[[package]] +name = "ordered-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "os_pipe" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29d73ba8daf8fac13b0501d1abeddcfe21ba7401ada61a819144b6c2a4f32209" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "owned_ttf_parser" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490d3a563d3122bf7c911a59b0add9389e5ec0f5f0c3ac6b91ff235a0e6a7f90" +dependencies = [ + "ttf-parser 0.24.0", +] + +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.5.3", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pin-weak" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b330c9d1b92dfe68442ca20b009c717d5f0b1e3cf4965e62f704c3c6e95a1305" + +[[package]] +name = "piper" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391" +dependencies = [ + "atomic-waker", + "fastrand 2.1.0", + "futures-io", +] + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "platform-dirs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e188d043c1a692985f78b5464853a263f1a27e5bd6322bad3a4078ee3c998a38" +dependencies = [ + "dirs-next", +] + +[[package]] +name = "png" +version = "0.17.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + +[[package]] +name = "polling" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.4.0", + "pin-project-lite", + "rustix 0.38.34", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" +dependencies = [ + "critical-section", +] + +[[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.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "prettyplease" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +dependencies = [ + "proc-macro2", + "syn 2.0.71", +] + +[[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.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.1", +] + +[[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-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "qrcode" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "166f136dfdb199f98186f3649cf7a0536534a61417a1a30221b492b4fb60ce3f" +dependencies = [ + "image 0.24.9", +] + +[[package]] +name = "qttypes" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d405b0934e4176fb264d6ca597e5c8c2fba562fa155cba681ca160c1eb7edc6e" +dependencies = [ + "cpp", + "cpp_build", + "semver", +] + +[[package]] +name = "quick-xml" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f24d770aeca0eacb81ac29dfbc55ebcc09312fdd1f8bbecdc7e4a84e000e3b4" +dependencies = [ + "memchr", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "redox_users" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +dependencies = [ + "getrandom", + "libredox 0.1.3", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-socks", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg 0.50.0", +] + +[[package]] +name = "resvg" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "944d052815156ac8fa77eaac055220e95ba0b01fa8887108ca710c03805d9051" +dependencies = [ + "log", + "pico-args", + "rgb", + "svgtypes", + "tiny-skia", + "usvg", +] + +[[package]] +name = "rgb" +version = "0.8.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade4539f42266ded9e755c605bdddf546242b2c961b03b06a7375260788a0523" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "rowan" +version = "0.15.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a58fa8a7ccff2aec4f39cc45bf5f985cec7125ab271cf681c279fd00192b49" +dependencies = [ + "countme", + "hashbrown 0.14.5", + "memoffset 0.9.1", + "rustc-hash", + "text-size", +] + +[[package]] +name = "roxmltree" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f" + +[[package]] +name = "roxmltree" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" + +[[package]] +name = "rsa" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.37.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys 0.4.14", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "rustybuzz" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c" +dependencies = [ + "bitflags 2.6.0", + "bytemuck", + "smallvec", + "ttf-parser 0.21.1", + "unicode-bidi-mirroring", + "unicode-ccc", + "unicode-properties", + "unicode-script", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scoped-tls-hkt" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ddc765d3410d9f6c6ca071bf0b67f6b01e3ec4595dc3892f02677e75819dddc" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sctk-adwaita" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" +dependencies = [ + "ab_glyph", + "log", + "memmap2 0.9.4", + "smithay-client-toolkit", + "tiny-skia", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "serde" +version = "1.0.204" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.204" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "serde_json" +version = "1.0.120" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "serde_spanned" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex 0.4.3", + "indexmap 1.9.3", + "indexmap 2.2.6", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "simplecss" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a11be7c62927d9427e9f40f3444d5499d868648e2edbc4e2116de69e7ec0e89d" +dependencies = [ + "log", +] + +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + +[[package]] +name = "skia-bindings" +version = "0.75.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06e19e97660b09a381c6eb566849b63556b1a90b8e2c6ba2d146b3f5066847b" +dependencies = [ + "bindgen", + "cc", + "flate2", + "heck 0.5.0", + "lazy_static", + "regex", + "serde_json", + "tar", + "toml", +] + +[[package]] +name = "skia-safe" +version = "0.75.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad6e6f369522471b585c99427720b53aad04016fa4314e0a8cf23f17083a4e4c" +dependencies = [ + "bitflags 2.6.0", + "lazy_static", + "skia-bindings", + "windows 0.56.0", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slint" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37776c51062d2c7ab7b9d00612a0d425fd792216fd777c473aee41c531490e4" +dependencies = [ + "const-field-offset", + "i-slint-backend-android-activity", + "i-slint-backend-qt", + "i-slint-backend-selector", + "i-slint-core", + "i-slint-renderer-femtovg", + "num-traits", + "once_cell", + "pin-weak", + "slint-macros", + "vtable", +] + +[[package]] +name = "slint-build" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719fe028aee2f051b9eea782e4d7068fb9b0a1de18426f00d3b2097c79e0e659" +dependencies = [ + "i-slint-compiler", + "spin_on", + "thiserror", + "toml_edit 0.22.16", +] + +[[package]] +name = "slint-macros" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d30b8166c46cf34a91d17bc63281f01fe78fd9017b405ae1624e9740f15fe89" +dependencies = [ + "i-slint-compiler", + "proc-macro2", + "quote", + "spin_on", +] + +[[package]] +name = "slint-template" +version = "0.1.0" +dependencies = [ + "android_logger", + "anyhow", + "cfg-if", + "clipboard", + "cmd_lib", + "cutil", + "derivative", + "embed-resource", + "env_logger", + "image 0.24.9", + "log", + "once_cell", + "platform-dirs", + "qrcode", + "serde", + "serde_json", + "serde_with", + "slint", + "slint-build", + "sqldb", + "terminal-clipboard", + "tokio", + "toml", + "uuid", + "webbrowser", +] + +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "smithay-client-toolkit" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" +dependencies = [ + "bitflags 2.6.0", + "calloop 0.13.0", + "calloop-wayland-source", + "cursor-icon", + "libc", + "log", + "memmap2 0.9.4", + "rustix 0.38.34", + "thiserror", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", +] + +[[package]] +name = "smithay-clipboard" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc8216eec463674a0e90f29e0ae41a4db573ec5b56b1c6c1c71615d249b6d846" +dependencies = [ + "libc", + "smithay-client-toolkit", + "wayland-backend", +] + +[[package]] +name = "smol_str" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +dependencies = [ + "serde", +] + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "softbuffer" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d623bff5d06f60d738990980d782c8c866997d9194cfe79ecad00aa2f76826dd" +dependencies = [ + "as-raw-xcb-connection", + "bytemuck", + "cfg_aliases", + "core-graphics", + "fastrand 2.1.0", + "foreign-types 0.5.0", + "js-sys", + "log", + "memmap2 0.9.4", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-quartz-core", + "raw-window-handle", + "redox_syscall 0.5.3", + "rustix 0.38.34", + "tiny-xlib", + "wasm-bindgen", + "wayland-backend", + "wayland-client", + "wayland-sys", + "web-sys", + "windows-sys 0.52.0", + "x11rb 0.13.1", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spin_on" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "076e103ed41b9864aa838287efe5f4e3a7a0362dd00671ae62a212e5e4612da2" +dependencies = [ + "pin-utils", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqldb" +version = "0.1.0" +dependencies = [ + "anyhow", + "once_cell", + "serde", + "sqlx", + "tokio", +] + +[[package]] +name = "sqlformat" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f895e3734318cc55f1fe66258926c9b910c124d47520339efecbb6c59cec7c1f" +dependencies = [ + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9a2ccff1a000a5a59cd33da541d9f2fdcd9e6e8229cc200565942bff36d0aaa" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6" +dependencies = [ + "ahash", + "atoi", + "byteorder", + "bytes", + "crc", + "crossbeam-queue", + "either", + "event-listener 2.5.3", + "futures-channel", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashlink", + "hex 0.4.3", + "indexmap 2.2.6", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlformat", + "thiserror", + "tokio", + "tokio-stream", + "tracing", + "url", +] + +[[package]] +name = "sqlx-macros" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea40e2345eb2faa9e1e5e326db8c34711317d2b5e08d0d5741619048a803127" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 1.0.109", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8" +dependencies = [ + "dotenvy", + "either", + "heck 0.4.1", + "hex 0.4.3", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-sqlite", + "syn 1.0.109", + "tempfile", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418" +dependencies = [ + "atoi", + "base64 0.21.7", + "bitflags 2.6.0", + "byteorder", + "bytes", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex 0.4.3", + "hkdf", + "hmac", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e" +dependencies = [ + "atoi", + "base64 0.21.7", + "bitflags 2.6.0", + "byteorder", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex 0.4.3", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "rand", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "sqlx-core", + "tracing", + "url", + "urlencoding", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "str-buf" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0" + +[[package]] +name = "strict-num" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" +dependencies = [ + "float-cmp", +] + +[[package]] +name = "stringprep" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", + "unicode-properties", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.71", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "svgtypes" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fae3064df9b89391c9a76a0425a69d124aee9c5c28455204709e72c39868a43c" +dependencies = [ + "kurbo", + "siphasher", +] + +[[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.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tar" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand 2.1.0", + "rustix 0.38.34", + "windows-sys 0.52.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "terminal-clipboard" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e0fd8cb5cf744b501e657eb27df7909ff917eacbfee34bc4bb13d4e6411a131" +dependencies = [ + "clipboard-win 4.5.0", + "clipboard_macos", + "once_cell", + "termux-clipboard", + "x11-clipboard 0.8.1", +] + +[[package]] +name = "termux-clipboard" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f6aff13ca3293315b94f6dbd9c69e1c958fe421c294681e2ffda80c9858e36f" + +[[package]] +name = "text-size" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233" + +[[package]] +name = "thiserror" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tiny-skia" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" +dependencies = [ + "arrayref", + "arrayvec", + "bytemuck", + "cfg-if", + "log", + "png", + "tiny-skia-path", +] + +[[package]] +name = "tiny-skia-path" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" +dependencies = [ + "arrayref", + "bytemuck", + "strict-num", +] + +[[package]] +name = "tiny-xlib" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d52f22673960ad13af14ff4025997312def1223bfa7c8e4949d099e6b3d5d1c" +dependencies = [ + "as-raw-xcb-connection", + "ctor-lite", + "libloading 0.8.4", + "pkg-config", + "tracing", +] + +[[package]] +name = "tinyvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.38.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.5.7", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-socks" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51165dfa029d2a65969413a6cc96f354b86b464498702f174a4efa13608fd8c0" +dependencies = [ + "either", + "futures-util", + "thiserror", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac2caab0bf757388c6c0ae23b3293fdb463fee59434529014f85e3263b995c28" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.22.16", +] + +[[package]] +name = "toml_datetime" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +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.2.6", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788" +dependencies = [ + "indexmap 2.2.6", + "serde", + "serde_spanned", + "toml_datetime", + "winnow 0.6.13", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "ttf-parser" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" + +[[package]] +name = "ttf-parser" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8686b91785aff82828ed725225925b33b4fde44c4bb15876e5f7c832724c420a" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "udev" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebdbbd670373442a12fe9ef7aeb53aec4147a5a27a00bbc3ab639f08f48191a" +dependencies = [ + "libc", + "libudev-sys", + "pkg-config", +] + +[[package]] +name = "uds_windows" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" +dependencies = [ + "memoffset 0.9.1", + "tempfile", + "winapi", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-bidi-mirroring" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cb788ffebc92c5948d0e997106233eeb1d8b9512f93f41651f52b6c5f5af86" + +[[package]] +name = "unicode-ccc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-properties" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" + +[[package]] +name = "unicode-script" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8d71f5726e5f285a935e9fe8edfd53f0491eb6e9a5774097fdabee7cd8c9cd" + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unicode-vo" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "url" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "usvg" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b84ea542ae85c715f07b082438a4231c3760539d902e11d093847a0b22963032" +dependencies = [ + "base64 0.22.1", + "data-url", + "flate2", + "fontdb", + "imagesize", + "kurbo", + "log", + "pico-args", + "roxmltree 0.20.0", + "rustybuzz", + "simplecss", + "siphasher", + "strict-num", + "svgtypes", + "tiny-skia-path", + "unicode-bidi", + "unicode-script", + "unicode-vo", + "xmlwriter", +] + +[[package]] +name = "uuid" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +dependencies = [ + "getrandom", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3b17ae1f6c8a2b28506cd96d412eebf83b4a0ff2cbefeeb952f2f9dfa44ba18" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "vtable" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "379cd4a9d99f35bcf1687282268b94b59f14b098cba210632605f39709230963" +dependencies = [ + "const-field-offset", + "portable-atomic", + "stable_deref_trait", + "vtable-macro", +] + +[[package]] +name = "vtable-macro" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68c1b85ec843d3bc60e9d65fa7e00ce6549416a25c267b5ea93e6c81e3aa66e5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "waker-fn" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.71", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "wayland-backend" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90e11ce2ca99c97b940ee83edbae9da2d56a08f9ea8158550fd77fa31722993" +dependencies = [ + "cc", + "downcast-rs", + "rustix 0.38.34", + "scoped-tls", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-client" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e321577a0a165911bdcfb39cf029302479d7527b517ee58ab0f6ad09edf0943" +dependencies = [ + "bitflags 2.6.0", + "rustix 0.38.34", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-csd-frame" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" +dependencies = [ + "bitflags 2.6.0", + "cursor-icon", + "wayland-backend", +] + +[[package]] +name = "wayland-cursor" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ef9489a8df197ebf3a8ce8a7a7f0a2320035c3743f3c1bd0bdbccf07ce64f95" +dependencies = [ + "rustix 0.38.34", + "wayland-client", + "xcursor", +] + +[[package]] +name = "wayland-protocols" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62989625a776e827cc0f15d41444a3cea5205b963c3a25be48ae1b52d6b4daaa" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-plasma" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f79f2d57c7fcc6ab4d602adba364bf59a5c24de57bd194486bf9b8360e06bfc4" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd993de54a40a40fbe5601d9f1fbcaef0aebcc5fda447d7dc8f6dcbaae4f8953" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.31.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7b56f89937f1cf2ee1f1259cf2936a17a1f45d8f0aa1019fae6d470d304cfa6" +dependencies = [ + "proc-macro2", + "quick-xml", + "quote", +] + +[[package]] +name = "wayland-sys" +version = "0.31.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43676fe2daf68754ecf1d72026e4e6c15483198b5d24e888b74d3f22f887a148" +dependencies = [ + "dlib", + "log", + "once_cell", + "pkg-config", +] + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webbrowser" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "425ba64c1e13b1c6e8c5d2541c8fac10022ca584f33da781db01b5756aef1f4e" +dependencies = [ + "block2", + "core-foundation", + "home", + "jni", + "log", + "ndk-context", + "objc2", + "objc2-foundation", + "url", + "web-sys", +] + +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix 0.38.34", +] + +[[package]] +name = "whoami" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" +dependencies = [ + "redox_syscall 0.4.1", + "wasite", +] + +[[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.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "winapi-wsapoll" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1eafc5f679c576995526e81635d0cf9695841736712b4e892f87abbe6fed3f28" +dependencies = [ + "winapi", +] + +[[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.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" +dependencies = [ + "windows-core 0.54.0", + "windows-implement 0.53.0", + "windows-interface 0.53.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1de69df01bdf1ead2f4ac895dc77c9351aefff65b2f3db429a343f9cbf05e132" +dependencies = [ + "windows-core 0.56.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4698e52ed2d08f8658ab0c39512a7c00ee5fe2688c65f8c0a4f06750d729f2a6" +dependencies = [ + "windows-implement 0.56.0", + "windows-interface 0.56.0", + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-implement" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942ac266be9249c84ca862f0a164a39533dc2f6f33dc98ec89c8da99b82ea0bd" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "windows-implement" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "windows-interface" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da33557140a288fae4e1d5f8873aaf9eb6613a9cf82c3e070223ff177f598b60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "windows-interface" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.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.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winit" +version = "0.30.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4225ddd8ab67b8b59a2fee4b34889ebf13c0460c1c3fa297c58e21eb87801b33" +dependencies = [ + "ahash", + "android-activity 0.6.0", + "atomic-waker", + "bitflags 2.6.0", + "block2", + "bytemuck", + "calloop 0.13.0", + "cfg_aliases", + "concurrent-queue", + "core-foundation", + "core-graphics", + "cursor-icon", + "dpi", + "js-sys", + "libc", + "memmap2 0.9.4", + "ndk 0.9.0", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", + "orbclient", + "percent-encoding", + "pin-project", + "raw-window-handle", + "redox_syscall 0.4.1", + "rustix 0.38.34", + "sctk-adwaita", + "smithay-client-toolkit", + "smol_str", + "tracing", + "unicode-segmentation", + "wasm-bindgen", + "wasm-bindgen-futures", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-protocols-plasma", + "web-sys", + "web-time", + "windows-sys 0.52.0", + "x11-dl", + "x11rb 0.13.1", + "xkbcommon-dl", +] + +[[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.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[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 = "wio" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" +dependencies = [ + "winapi", +] + +[[package]] +name = "x11-clipboard" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89bd49c06c9eb5d98e6ba6536cf64ac9f7ee3a009b2f53996d405b3944f6bcea" +dependencies = [ + "xcb", +] + +[[package]] +name = "x11-clipboard" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b41aca1115b1f195f21c541c5efb423470848d48143127d0f07f8b90c27440df" +dependencies = [ + "x11rb 0.12.0", +] + +[[package]] +name = "x11-clipboard" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98785a09322d7446e28a13203d2cae1059a0dd3dfb32cb06d0a225f023d8286" +dependencies = [ + "libc", + "x11rb 0.13.1", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "x11rb" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1641b26d4dec61337c35a1b1aaf9e3cba8f46f0b43636c609ab0291a648040a" +dependencies = [ + "gethostname 0.3.0", + "nix 0.26.4", + "winapi", + "winapi-wsapoll", + "x11rb-protocol 0.12.0", +] + +[[package]] +name = "x11rb" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" +dependencies = [ + "as-raw-xcb-connection", + "gethostname 0.4.3", + "libc", + "libloading 0.8.4", + "once_cell", + "rustix 0.38.34", + "x11rb-protocol 0.13.1", +] + +[[package]] +name = "x11rb-protocol" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82d6c3f9a0fb6701fab8f6cea9b0c0bd5d6876f1f89f7fada07e558077c344bc" +dependencies = [ + "nix 0.26.4", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" + +[[package]] +name = "xattr" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +dependencies = [ + "libc", + "linux-raw-sys 0.4.14", + "rustix 0.38.34", +] + +[[package]] +name = "xcb" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e917a3f24142e9ff8be2414e36c649d47d6cc2ba81f16201cdef96e533e02de" +dependencies = [ + "libc", + "log", +] + +[[package]] +name = "xcursor" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a0ccd7b4a5345edfcd0c3535718a4e9ff7798ffc536bb5b5a0e26ff84732911" + +[[package]] +name = "xdg-home" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca91dcf8f93db085f3a0a29358cd0b9d670915468f4290e8b85d118a34211ab8" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "xkbcommon" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13867d259930edc7091a6c41b4ce6eee464328c6ff9659b7e4c668ca20d4c91e" +dependencies = [ + "libc", + "memmap2 0.8.0", + "xkeysym", +] + +[[package]] +name = "xkbcommon-dl" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" +dependencies = [ + "bitflags 2.6.0", + "dlib", + "log", + "once_cell", + "xkeysym", +] + +[[package]] +name = "xkeysym" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" + +[[package]] +name = "xml-rs" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" + +[[package]] +name = "xmlwriter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" + +[[package]] +name = "zbus" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "675d170b632a6ad49804c8cf2105d7c31eddd3312555cffd4b740e08e97c25e6" +dependencies = [ + "async-broadcast", + "async-executor", + "async-fs", + "async-io 1.13.0", + "async-lock 2.8.0", + "async-process", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "byteorder", + "derivative", + "enumflags2", + "event-listener 2.5.3", + "futures-core", + "futures-sink", + "futures-util", + "hex 0.4.3", + "nix 0.26.4", + "once_cell", + "ordered-stream", + "rand", + "serde", + "serde_repr", + "sha1", + "static_assertions", + "tracing", + "uds_windows", + "winapi", + "xdg-home", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7131497b0f887e8061b430c530240063d33bf9455fa34438f388a245da69e0a5" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "regex", + "syn 1.0.109", + "zvariant_utils", +] + +[[package]] +name = "zbus_names" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "437d738d3750bed6ca9b8d423ccc7a8eb284f6b1d6d4e225a0e4e6258d864c8d" +dependencies = [ + "serde", + "static_assertions", + "zvariant", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.71", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "zvariant" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eef2be88ba09b358d3b58aca6e41cd853631d44787f319a1383ca83424fb2db" +dependencies = [ + "byteorder", + "enumflags2", + "libc", + "serde", + "static_assertions", + "zvariant_derive", +] + +[[package]] +name = "zvariant_derive" +version = "3.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37c24dc0bed72f5f90d1f8bb5b07228cbf63b3c6e9f82d82559d4bae666e7ed9" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7234f0d811589db492d16893e3f21e8e2fd282e6d01b0cddee310322062cc200" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..20415ac --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,102 @@ +[package] +name = "slint-template" +version = "0.1.0" +edition = "2021" +authors = ["Heng30 "] +readme = "README.md" +keywords = ["rust"] +license = "MIT" +# homepage = "https://github.com/Heng30/solana-wallet-sollaw" +# repository = "https://github.com/Heng30/solana-wallet-sollaw" + +[dependencies] +log = "0.4" +toml = "0.8" +slint = "1.7" +anyhow = "1.0" +cfg-if = "1.0.0" +once_cell = "1.19" +webbrowser = "1.0" +derivative = "2.2" +serde_with = "3.8" +serde_json = "1.0" + +uuid = { version = "1.9", features = ["v4"] } +tokio = { version = "1.38", features = ["full"] } +serde = { version = "1.0", features = ["serde_derive"] } + +sqldb = { version = "0.1", path = "./libs/sqldb" } +cutil = { version = "0.1", path = "./libs/cutil", features = [ + "default", + "crypto", + "time", + "http", +] } + +image = { version = "0.24", optional = true } +qrcode = { version = "0.13", optional = true } + +[target.'cfg(not(target_os = "android"))'.dependencies] +clipboard = "0.5" +env_logger = "0.10" +platform-dirs = "0.3" + +[target.'cfg(target_os = "android")'.dependencies] +android_logger = "0.13" +terminal-clipboard = "0.4" + +[build-dependencies] +cmd_lib = "1.9" +slint-build = "1.7" + +[target.'cfg(target_os = "windows")'.build-dependencies] +embed-resource = "2.4" + +[features] +default = ["cutil/native-tls-vendored", "slint/backend-android-activity-06"] +qrcode = [ "dep:image", "dep:qrcode"] +desktop = [ ] + +[lib] +crate-type = ["cdylib", "lib"] + +[[bin]] +path = "src/desktop.rs" +name = "slint-template" +required-features = ["desktop"] + +[package.metadata.android] +package = "xyz.heng30.sollaw" +build_targets = ["aarch64-linux-android"] +resources = "./res" +strip = "strip" + +[package.metadata.android.signing.dev] +path = "./keystore/debug.keystore" +keystore_password = "123456" + +[package.metadata.android.signing.release] +path = "./keystore/release.keystore" +keystore_password = "123456" + +[package.metadata.android.sdk] +min_sdk_version = 23 +target_sdk_version = 32 + +[[package.metadata.android.uses_permission]] +name = "android.permission.INTERNET" + +[[package.metadata.android.uses_permission]] +name = "android.permission.WRITE_EXTERNAL_STORAGE" + +[[package.metadata.android.uses_permission]] +name = "android.permission.READ_EXTERNAL_STORAGE" + +[package.metadata.android.application] +icon = "@mipmap/ic_launcher" +theme = "@style/AppTheme" + +[package.metadata.android.application.activity] +orientation = "portrait" +launch_mode = "singleTop" +always_retain_task_state = true diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..243fcd6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) 2020 Tokio Contributors + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5919f81 --- /dev/null +++ b/Makefile @@ -0,0 +1,93 @@ +#!/bin/sh + +pwd=${shell pwd} +build-evn=SLINT_STYLE=material +run-evn=RUST_LOG=error,warn,info,debug,sqlx=off,reqwest=off +version=`git describe --tags --abbrev=0` + +all: build-release + +build: + $(build-evn) cargo apk build --lib + +build-release: + $(build-evn) cargo apk build --lib --release + cp -f target/release/apk/slint-template.apk target/slint-template-${version}.apk + +build-release-mold: + $(build-evn) mold --run cargo apk build --lib --release + cp -f target/release/apk/slint-template.apk target/slint-template-${version}.apk + +run: + RUST_BACKTRACE=1 $(run-evn) cargo apk run --lib + +run-release: + RUST_BACKTRACE=1 $(run-evn) cargo apk run --lib --release + +run-release-mold: + RUST_BACKTRACE=1 $(run-evn) mold --run cargo apk run --lib --release + +install: + $(build-evn) $(run-evn) cargo apk run --lib --release + +debug: + $(build-evn) $(run-evn) cargo run --features=desktop + +debug-mold: + $(build-evn) $(run-evn) mold --run cargo run --features=desktop + +debug-local: + $(run-evn) ./target/debug/slint-template-desktop + +release-local: + $(run-evn) ./target/release/slint-template-desktop + +build-desktop-debug-mold: + $(build-evn) $(run-evn) mold --run cargo build --features=desktop + +build-desktop-debug-job1: + $(build-evn) $(run-evn) cargo build --jobs 1 --features=desktop + +build-desktop-debug: + $(build-evn) $(run-evn) cargo build --features=desktop + +build-desktop-release: + $(build-evn) $(run-evn) cargo build --release --features=desktop + +build-desktop-release-job1: + $(build-evn) $(run-evn) cargo build --release --jobs 1 --features=desktop + +build-desktop-release-nixos: + nix-shell --run "$(build-evn) $(run-evn) cargo build --release --features=desktop" + +install-desktop: + cp -f target/release/slint-template ~/bin/slint-template + +test: + $(build-evn) $(run-evn) cargo test -- --nocapture + +clippy: + cargo clippy + +clean-incremental: + rm -rf ./target/debug/incremental/* + rm -rf ./target/aarch64-linux-android/debug/incremental + +clean-unused-dependences: + cargo machete + +clean: + cargo clean + +slint-view: + slint-viewer --style material --auto-reload -I ui ./ui/appwindow.slint + +slint-view-light: + slint-viewer --style material-light --auto-reload -I ui ./ui/appwindow.slint + +slint-view-dark: + slint-viewer --style material-dark --auto-reload -I ui ./ui/appwindow.slint + +get-font-name: + fc-scan ./ui/fonts/SourceHanSerifCN.ttf | grep fullname + fc-scan ./ui/fonts/Plaster-Regular.ttf | grep fullname diff --git a/README.md b/README.md new file mode 100644 index 0000000..c3de647 --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +
+ + + + + + + + +
+ +[中文文档](./README.zh-CN.md) + +### Introduction + +### Features + +### Android platform build information +- `min-sdk-version = 23` +- `target-sdk-version = 32` + +#### How to build? +- Install `Rust` and `Cargo` +- Install Android `sdk`, `ndk`, `jdk17`, and set environment variables +- Run `make` to build a release version android APK +- Run `make debug` to run it on desktop platform +- Run `make build-desktop-release` to build a release version desktop APK +- Refer to [Makefile](./Makefile) for more information + +### Reference +- [Slint Language Documentation](https://slint-ui.com/releases/1.0.0/docs/slint/) +- [github/slint-ui](https://github.com/slint-ui/slint) +- [Viewer for Slint](https://github.com/slint-ui/slint/tree/master/tools/viewer) +- [LSP (Language Server Protocol) Server for Slint](https://github.com/slint-ui/slint/tree/master/tools/lsp) +- [developer.android.com](https://developer.android.com/guide) diff --git a/README.zh-CN.md b/README.zh-CN.md new file mode 100644 index 0000000..22d7143 --- /dev/null +++ b/README.zh-CN.md @@ -0,0 +1,35 @@ +
+ + + + + + + + +
+ +[English Documentation](./README.md) + +### 简介 + +### 功能 + +### 安卓平台编译信息 +- `min-sdk-version = 23` +- `target-sdk-version = 32` + +### 如何构建? +- 安装 `Rust` 和 `Cargo` +- 安装 Android `sdk`, `ndk`, `jdk17`, 和设置对应的环境变量 +- 运行 `make` 编译安卓平台程序 +- 运行 `make debug` 调试桌面平台程序 +- 运行 `make build-desktop-release` 编译桌面平台程序 +- 参考 [Makefile](./Makefile) 了解更多信息 + +### 参考 +- [Slint Language Documentation](https://slint-ui.com/releases/1.0.0/docs/slint/) +- [github/slint-ui](https://github.com/slint-ui/slint) +- [Viewer for Slint](https://github.com/slint-ui/slint/tree/master/tools/viewer) +- [LSP (Language Server Protocol) Server for Slint](https://github.com/slint-ui/slint/tree/master/tools/lsp) +- [developer.android.com](https://developer.android.com/guide) diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..9546dcb --- /dev/null +++ b/build.rs @@ -0,0 +1,34 @@ +use cmd_lib::run_fun; + +fn main() { + slint_build::compile("ui/appwindow.slint").unwrap(); + + #[cfg(target_os = "windows")] + { + set_win_info(); + } + + let _ = write_app_version(); +} + +fn write_app_version() -> Result<(), Box> { + let tags = run_fun!(git describe --tags --abbrev=0)? + .split(char::is_whitespace) + .map(|s| s.to_owned()) + .collect::>(); + + let output = if let Some(version) = tags.last() { + format!(r#"pub static VERSION: &str = "{}";"#, version) + } else { + format!(r#"pub static VERSION: &str = "{}";"#, "0.0.1") + }; + + let _ = std::fs::write("src/version.rs", output); + + Ok(()) +} + +#[cfg(target_os = "windows")] +fn set_win_info() { + embed_resource::compile("./win/icon.rc", embed_resource::NONE); +} diff --git a/keystore/debug.keystore b/keystore/debug.keystore new file mode 100644 index 0000000..9ad8c6a Binary files /dev/null and b/keystore/debug.keystore differ diff --git a/keystore/release.keystore b/keystore/release.keystore new file mode 100644 index 0000000..967297d Binary files /dev/null and b/keystore/release.keystore differ diff --git a/libs/cutil/.gitignore b/libs/cutil/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/libs/cutil/.gitignore @@ -0,0 +1 @@ +/target diff --git a/libs/cutil/Cargo.lock b/libs/cutil/Cargo.lock new file mode 100644 index 0000000..6b34397 --- /dev/null +++ b/libs/cutil/Cargo.lock @@ -0,0 +1,1412 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", + "opaque-debug", +] + +[[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.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "backtrace" +version = "0.3.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "block-modes" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cb03d1bed155d89dce0f845b7899b18a9a163e148fd004e1c28421a783e2d8e" +dependencies = [ + "block-padding", + "cipher", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" + +[[package]] +name = "cc" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490" + +[[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.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.6", +] + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + +[[package]] +name = "commoncrypto" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" +dependencies = [ + "commoncrypto-sys", +] + +[[package]] +name = "commoncrypto-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" +dependencies = [ + "libc", +] + +[[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-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-hash" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a77162240fd97248d19a564a565eb563a3f592b386e4136fb300909e67dddca" +dependencies = [ + "commoncrypto", + "hex 0.3.2", + "openssl", + "winapi", +] + +[[package]] +name = "cutil" +version = "0.1.0" +dependencies = [ + "aes", + "anyhow", + "block-modes", + "chrono", + "crypto-hash", + "hex 0.4.3", + "rand", + "reqwest", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[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 = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[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.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hex" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "native-tls" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-src" +version = "300.3.1+3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7259953d42a81bf137fbbd73bd30a8e1914d6dce43c2b90ed575783a22608b91" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +dependencies = [ + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-socks", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "security-framework" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.120" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "syn" +version = "2.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "thiserror" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tinyvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c55115c6fbe2d2bef26eb09ad74bde02d8255476fc0c7b515ef09fbb35742d82" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-socks" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51165dfa029d2a65969413a6cc96f354b86b464498702f174a4efa13608fd8c0" +dependencies = [ + "either", + "futures-util", + "thiserror", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[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-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + +[[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.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +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_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.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.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.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.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.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.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 = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] diff --git a/libs/cutil/Cargo.toml b/libs/cutil/Cargo.toml new file mode 100644 index 0000000..64ed7b4 --- /dev/null +++ b/libs/cutil/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "cutil" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = "1.0" +rand = "0.8" +hex = "0.4" +chrono = "0.4" +bytes = "1.0" + +aes = { version = "0.7", optional = true } +block-modes = { version = "0.8", optional = true } +crypto-hash = { version = "0.3", optional = true } +reqwest = { version = "0.11", optional = true } + +[features] +default = [] +time = [] +http = ["reqwest/json", "reqwest/socks"] +native-tls-vendored = ["reqwest/native-tls-vendored"] +crypto = ["dep:aes", "dep:block-modes", "dep:crypto-hash"] diff --git a/libs/cutil/src/crypto.rs b/libs/cutil/src/crypto.rs new file mode 100644 index 0000000..c3d2ed6 --- /dev/null +++ b/libs/cutil/src/crypto.rs @@ -0,0 +1,84 @@ +use aes::Aes256; +use anyhow::{anyhow, Context, Result}; +use block_modes::{block_padding, BlockMode, Cbc}; +use crypto_hash::{hex_digest, Algorithm}; + +type Aes256Cbc = Cbc; + +fn key_iv(password: &str) -> Result<(Vec, Vec)> { + let key = hex_digest(Algorithm::SHA256, password.as_bytes()); + let key = hex::decode(key).context("Decoding key failed")?; + + let iv = hex_digest(Algorithm::MD5, password.as_bytes()); + let iv = hex::decode(iv).context("Decoding iv failed")?; + Ok((key, iv)) +} + +pub fn encrypt(password: &str, plain_text: &[u8]) -> Result { + let (key, iv) = key_iv(password)?; + let cipher = Aes256Cbc::new_from_slices(&key, &iv)?; + + let pos = plain_text.len(); + if pos > 4096 { + return Err(anyhow!( + "input text is too long, the max text len is 4096 bytes." + )); + } + + let mut buffer = [0u8; 4096]; + buffer[..pos].copy_from_slice(plain_text); + let text = cipher.encrypt(&mut buffer, pos)?; + + Ok(hex::encode(text)) +} + +pub fn decrypt(password: &str, encrypt_text: &str) -> Result> { + let (key, iv) = key_iv(password)?; + + let cipher = Aes256Cbc::new_from_slices(&key, &iv)?; + let mut buf = hex::decode(encrypt_text.as_bytes())?.to_vec(); + let text = cipher.decrypt(&mut buf)?; + Ok(Vec::from(text)) +} + +pub fn hash(text: &str) -> String { + hex_digest( + Algorithm::MD5, + hex_digest(Algorithm::SHA256, text.as_bytes()).as_bytes(), + ) +} + +#[cfg(test)] +mod tests { + use super::*; + use super::super::str::random_string; + + #[test] + fn test_random_string() { + for i in 1..100 { + assert_eq!(random_string(i).len(), i); + } + } + + #[test] + fn test_hash() { + for i in 1..100 { + let rs = random_string(i); + let (h1, h2) = (hash(&rs), hash(&rs)); + assert_eq!(h1.len(), 32); + assert_eq!(h1, h2); + } + } + + #[test] + fn test_encrypt_decrypt() -> Result<()> { + for i in 1..100 { + let (text, password) = (random_string(i + 10), random_string(i)); + let enc_text = encrypt(&password, &text.as_bytes())?; + let dec_text = decrypt(&password, &enc_text)?; + assert_eq!(text.as_bytes(), dec_text) + } + + Ok(()) + } +} diff --git a/libs/cutil/src/fs.rs b/libs/cutil/src/fs.rs new file mode 100644 index 0000000..dc96a1e --- /dev/null +++ b/libs/cutil/src/fs.rs @@ -0,0 +1,44 @@ +use anyhow::Result; +use std::path::PathBuf; +use std::{env, fs, io}; + +pub fn working_dir() -> Result { + let mut dir = env::current_exe()?; + dir.pop(); + + match dir.to_str() { + Some(path) => Ok(PathBuf::from(path)), + _ => Err(anyhow::anyhow!("convert {:?} failed", dir)), + } +} + +pub fn remove_dir_files(path: &str) -> io::Result<()> { + for entry in fs::read_dir(path)? { + let entry = entry?; + if entry.file_type()?.is_file() { + fs::remove_file(entry.path())?; + } + } + Ok(()) +} + +pub fn file_exist(path: &str) -> bool { + match fs::metadata(path) { + Ok(md) => md.is_file(), + _ => false, + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_working_dir() -> Result<()> { + let wd = working_dir()?; + // println!("{:?}", wd); + assert!(wd.is_dir()); + + Ok(()) + } +} diff --git a/libs/cutil/src/http.rs b/libs/cutil/src/http.rs new file mode 100644 index 0000000..2f473fb --- /dev/null +++ b/libs/cutil/src/http.rs @@ -0,0 +1,82 @@ +use anyhow::Result; +use bytes::Bytes; +use reqwest::{ + header::{HeaderMap, ACCEPT, CACHE_CONTROL, USER_AGENT}, + Client, Proxy, Url, +}; +use std::{ffi::OsStr, path::Path, time::Duration}; + +pub enum ProxyType { + Http, + Socks5, + Unknown, +} + +impl From<&str> for ProxyType { + fn from(pt: &str) -> Self { + match pt.to_lowercase().as_str() { + "http" => ProxyType::Http, + "socks5" => ProxyType::Socks5, + _ => ProxyType::Unknown, + } + } +} + +pub fn headers() -> HeaderMap { + let mut headers = HeaderMap::new(); + headers.insert(USER_AGENT, "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36".parse().unwrap()); + headers.insert(ACCEPT, "*/*".parse().unwrap()); + + headers.insert(CACHE_CONTROL, "no-cache".parse().unwrap()); + headers +} + +pub fn client(conf: Option<(ProxyType, String, u16)>) -> Result { + match conf { + Some((proxy, url, port)) => { + let proxy_url = match proxy { + ProxyType::Http => Proxy::all(format!("http://{}:{}", url, port))?, + ProxyType::Socks5 => Proxy::all(format!("socks5://{}:{}", url, port))?, + _ => return Ok(Client::new()), + }; + Ok(Client::builder().proxy(proxy_url).build()?) + } + None => Ok(Client::new()), + } +} + +pub async fn get_bytes(url: &str, conf: Option<(ProxyType, String, u16)>) -> Result { + let client = client(conf)?; + let data = client + .get(url) + .timeout(Duration::from_secs(60)) + .send() + .await? + .bytes() + .await?; + Ok(data) +} + +pub fn file_extension(url: &str) -> Result> { + let url = Url::parse(url)?; + let path = url.path(); + + Ok(Path::new(path) + .file_name() + .and_then(|item| Some(Path::new(item))) + .and_then(Path::extension) + .and_then(OsStr::to_str) + .and_then(|item| Some(String::from(item)))) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_file_extension() -> Result<()> { + let url = "https://www.example.com/test.pdf"; + assert_eq!(Some("pdf".to_string()), file_extension(url)?); + Ok(()) + } +} diff --git a/libs/cutil/src/lib.rs b/libs/cutil/src/lib.rs new file mode 100644 index 0000000..a47605a --- /dev/null +++ b/libs/cutil/src/lib.rs @@ -0,0 +1,19 @@ +#[cfg(feature = "crypto")] +pub mod crypto; + +#[cfg(feature = "http")] +pub mod http; + +#[cfg(feature = "http")] +pub use reqwest; + +#[cfg(feature = "time")] +pub mod time; + +pub use rand; +pub use hex; +pub use chrono; + +pub mod fs; +pub mod number; +pub mod str; diff --git a/libs/cutil/src/number.rs b/libs/cutil/src/number.rs new file mode 100644 index 0000000..9de9502 --- /dev/null +++ b/libs/cutil/src/number.rs @@ -0,0 +1,51 @@ +pub fn format_number_with_commas(number_str: &str) -> String { + if number_str.is_empty() { + return String::default(); + } + + let chars: Vec = number_str.chars().collect(); + let decimal_index = chars.iter().position(|&c| c == '.').unwrap_or(chars.len()); + + let left_part = &mut chars[0..decimal_index] + .iter() + .rev() + .copied() + .collect::>(); + + let right_part = &number_str[decimal_index..]; + + let mut chs = vec![]; + for (i, ch) in left_part.iter().enumerate() { + chs.push(*ch); + if (i + 1) % 3 == 0 { + chs.push(','); + } + } + + if chs[chs.len() - 1] == ',' { + chs.pop(); + } + + format!("{}{}", chs.iter().rev().collect::(), right_part) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_format_number_with_commas() { + let verify = vec![ + "", "1.23", "12.12", "123.12", "1,234.12", "1", "12", "123", "1,234", "123,456", + ]; + + let mut output = vec![]; + for item in vec![ + "", "1.23", "12.12", "123.12", "1234.12", "1", "12", "123", "1234", "123456", + ] { + output.push(format_number_with_commas(&item)); + } + + assert_eq!(verify, output); + } +} diff --git a/libs/cutil/src/str.rs b/libs/cutil/src/str.rs new file mode 100644 index 0000000..a3f7e99 --- /dev/null +++ b/libs/cutil/src/str.rs @@ -0,0 +1,27 @@ +use rand::Rng; + +pub fn split_string_to_fixed_length_parts(input: &str, length: usize) -> Vec { + input + .chars() + .collect::>() + .chunks(length) + .map(|chunk| chunk.iter().collect::()) + .collect() +} + +pub fn pretty_size_string(size: u64) -> String { + match size { + s if s < 1024 => format!("{}B", size), + s if s < 1024 * 1024 => format!("{}K", size / 1024), + s if s < 1024 * 1024 * 1024 => format!("{}M", size / (1024 * 1024)), + _ => format!("{}G", size / (1024 * 1024 * 1024)), + } +} + +pub fn random_string(length: usize) -> String { + let mut rng = rand::thread_rng(); + let chars: Vec = ('a'..='z').collect(); + (0..length) + .map(|_| chars[rng.gen_range(0..chars.len())]) + .collect() +} diff --git a/libs/cutil/src/time.rs b/libs/cutil/src/time.rs new file mode 100644 index 0000000..d126567 --- /dev/null +++ b/libs/cutil/src/time.rs @@ -0,0 +1,5 @@ +use chrono::Local; + +pub fn local_now(format: &str) -> String { + return Local::now().format(format).to_string(); +} diff --git a/libs/sqldb/.gitignore b/libs/sqldb/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/libs/sqldb/.gitignore @@ -0,0 +1 @@ +/target diff --git a/libs/sqldb/Cargo.lock b/libs/sqldb/Cargo.lock new file mode 100644 index 0000000..3be347a --- /dev/null +++ b/libs/sqldb/Cargo.lock @@ -0,0 +1,1377 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "atoi" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" +dependencies = [ + "num-traits", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "backtrace" +version = "0.3.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" + +[[package]] +name = "cc" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[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-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[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 = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "pin-project", + "spin", +] + +[[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 = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot 0.11.2", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash 0.8.11", + "allocator-api2", +] + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.5", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[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", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "libsqlite3-sys" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "native-tls" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + +[[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 0.9.10", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.5.2", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "security-framework" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[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.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "sqldb" +version = "0.1.0" +dependencies = [ + "anyhow", + "once_cell", + "serde", + "sqlx", + "tokio", +] + +[[package]] +name = "sqlformat" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f895e3734318cc55f1fe66258926c9b910c124d47520339efecbb6c59cec7c1f" +dependencies = [ + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8de3b03a925878ed54a954f621e64bf55a3c1bd29652d0d1a17830405350188" +dependencies = [ + "sqlx-core", + "sqlx-macros", +] + +[[package]] +name = "sqlx-core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" +dependencies = [ + "ahash 0.7.8", + "atoi", + "bitflags 1.3.2", + "byteorder", + "bytes", + "crc", + "crossbeam-queue", + "dotenvy", + "either", + "event-listener", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "hashlink", + "hex", + "indexmap", + "itoa", + "libc", + "libsqlite3-sys", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "sha2", + "smallvec", + "sqlformat", + "sqlx-rt", + "stringprep", + "thiserror", + "tokio-stream", + "url", +] + +[[package]] +name = "sqlx-macros" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9966e64ae989e7e575b19d7265cb79d7fc3cbbdf179835cb0d716f294c2049c9" +dependencies = [ + "dotenvy", + "either", + "heck", + "once_cell", + "proc-macro2", + "quote", + "sha2", + "sqlx-core", + "sqlx-rt", + "syn 1.0.109", + "url", +] + +[[package]] +name = "sqlx-rt" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "804d3f245f894e61b1e6263c84b23ca675d96753b5abfd5cc8597d86806e8024" +dependencies = [ + "native-tls", + "once_cell", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "stringprep" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", + "unicode-properties", +] + +[[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.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "thiserror" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "tinyvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c55115c6fbe2d2bef26eb09ad74bde02d8255476fc0c7b515ef09fbb35742d82" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot 0.12.3", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-properties" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "url" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[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-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[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.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +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_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.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.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.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.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.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.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 = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] diff --git a/libs/sqldb/Cargo.toml b/libs/sqldb/Cargo.toml new file mode 100644 index 0000000..4662bc5 --- /dev/null +++ b/libs/sqldb/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "sqldb" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = "1.0" +once_cell = "1.0" +tokio = { version = "1.0", features = ["sync"] } +serde = { version = "1.0", features = ["serde_derive"] } +sqlx = { version = "0.7", features = ["runtime-tokio", "sqlite"] } + +[dev-dependencies] +tokio = { version = "1.0", features = ["full"] } diff --git a/libs/sqldb/src/entry.rs b/libs/sqldb/src/entry.rs new file mode 100644 index 0000000..6286baf --- /dev/null +++ b/libs/sqldb/src/entry.rs @@ -0,0 +1,218 @@ +use super::{pool, ComEntry}; +use anyhow::Result; + +pub async fn new(table: &str) -> Result<()> { + sqlx::query(&format!( + "CREATE TABLE IF NOT EXISTS {table} ( + id INTEGER PRIMARY KEY, + uuid TEXT NOT NULL UNIQUE, + data TEXT NOT NULL + )" + )) + .execute(&pool().await) + .await?; + + Ok(()) +} + +pub async fn delete(table: &str, uuid: &str) -> Result<()> { + sqlx::query(&format!("DELETE FROM {table} WHERE uuid=?")) + .bind(uuid) + .execute(&pool().await) + .await?; + Ok(()) +} + +pub async fn delete_all(table: &str) -> Result<()> { + sqlx::query(&format!("DELETE FROM {table}")) + .execute(&pool().await) + .await?; + Ok(()) +} + +pub async fn insert(table: &str, uuid: &str, data: &str) -> Result<()> { + sqlx::query(&format!("INSERT INTO {table} (uuid, data) VALUES (?, ?)")) + .bind(uuid) + .bind(data) + .execute(&pool().await) + .await?; + Ok(()) +} + +pub async fn update(table: &str, uuid: &str, data: &str) -> Result<()> { + sqlx::query(&format!("UPDATE {table} SET data=? WHERE uuid=?")) + .bind(data) + .bind(uuid) + .execute(&pool().await) + .await?; + + Ok(()) +} + +pub async fn select(table: &str, uuid: &str) -> Result { + Ok( + sqlx::query_as::<_, ComEntry>(&format!("SELECT * FROM {table} WHERE uuid=?")) + .bind(uuid) + .fetch_one(&pool().await) + .await?, + ) +} + +pub async fn select_all(table: &str) -> Result> { + Ok( + sqlx::query_as::<_, ComEntry>(&format!("SELECT * FROM {table}")) + .fetch_all(&pool().await) + .await?, + ) +} + +pub async fn row_counts(table: &str) -> Result { + let count: (i64,) = sqlx::query_as(&format!("SELECT COUNT(*) FROM {table}")) + .fetch_one(&pool().await) + .await?; + + Ok(count.0) +} + +pub async fn is_exist(table: &str, uuid: &str) -> Result<()> { + select(table, uuid).await?; + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + use once_cell::sync::Lazy; + use tokio::sync::Mutex; + + static MTX: Lazy> = Lazy::new(|| Mutex::new(())); + const DB_PATH: &str = "/tmp/entry-db-test.db"; + const TABLE_NAME: &str = "test"; + + pub async fn init(db_path: &str) { + super::super::create_db(db_path).await.expect("create db"); + new(TABLE_NAME).await.expect("account table failed"); + } + + #[tokio::test] + async fn test_table_new() -> Result<()> { + let _mtx = MTX.lock().await; + init(DB_PATH).await; + Ok(()) + } + + #[tokio::test] + async fn test_delete_all() -> Result<()> { + let _mtx = MTX.lock().await; + init(DB_PATH).await; + new(TABLE_NAME).await?; + delete_all(TABLE_NAME).await?; + Ok(()) + } + + #[tokio::test] + async fn test_delete_one() -> Result<()> { + let _mtx = MTX.lock().await; + init(DB_PATH).await; + new(TABLE_NAME).await?; + + delete_all(TABLE_NAME).await?; + insert(TABLE_NAME, "uuid-1", "data-1").await?; + delete(TABLE_NAME, "uuid-1").await?; + Ok(()) + } + + #[tokio::test] + async fn test_insert() -> Result<()> { + let _mtx = MTX.lock().await; + init(DB_PATH).await; + new(TABLE_NAME).await?; + delete_all(TABLE_NAME).await?; + + insert(TABLE_NAME, "uuid-1", "data-1").await?; + insert(TABLE_NAME, "uuid-2", "data-2").await?; + + Ok(()) + } + + #[tokio::test] + async fn test_update() -> Result<()> { + let _mtx = MTX.lock().await; + init(DB_PATH).await; + new(TABLE_NAME).await?; + delete_all(TABLE_NAME).await?; + + insert(TABLE_NAME, "uuid-1", "data-1").await?; + update(TABLE_NAME, "uuid-1", "data-1-1").await?; + + assert_eq!( + select(TABLE_NAME, "uuid-1").await?.data, + "data-1-1".to_string() + ); + + Ok(()) + } + + #[tokio::test] + async fn test_select_one() -> Result<()> { + let _mtx = MTX.lock().await; + + init(DB_PATH).await; + new(TABLE_NAME).await?; + delete_all(TABLE_NAME).await?; + + assert!(select(TABLE_NAME, "uuid-1").await.is_err()); + + insert(TABLE_NAME, "uuid-1", "data-1").await?; + let item = select(TABLE_NAME, "uuid-1").await?; + assert_eq!(item.uuid, "uuid-1"); + assert_eq!(item.data, "data-1"); + Ok(()) + } + + #[tokio::test] + async fn test_select_all() -> Result<()> { + let _mtx = MTX.lock().await; + + init(DB_PATH).await; + new(TABLE_NAME).await?; + delete_all(TABLE_NAME).await?; + + insert(TABLE_NAME, "uuid-1", "data-1").await?; + insert(TABLE_NAME, "uuid-2", "data-2").await?; + + let v = select_all(TABLE_NAME).await?; + assert_eq!(v[0].uuid, "uuid-1"); + assert_eq!(v[0].data, "data-1"); + assert_eq!(v[1].uuid, "uuid-2"); + assert_eq!(v[1].data, "data-2"); + Ok(()) + } + + #[tokio::test] + async fn test_row_counts() -> Result<()> { + let _mtx = MTX.lock().await; + init(DB_PATH).await; + new(TABLE_NAME).await?; + delete_all(TABLE_NAME).await?; + + assert!(row_counts(TABLE_NAME).await? == 0); + insert(TABLE_NAME, "uuid-1", "data-1").await?; + assert!(row_counts(TABLE_NAME).await? == 1); + + Ok(()) + } + + #[tokio::test] + async fn test_is_exist() -> Result<()> { + let _mtx = MTX.lock().await; + init(DB_PATH).await; + new(TABLE_NAME).await?; + delete_all(TABLE_NAME).await?; + insert(TABLE_NAME, "uuid-1", "data-1").await?; + + assert!(is_exist(TABLE_NAME, "uuid-0").await.is_err()); + assert!(is_exist(TABLE_NAME, "uuid-1").await.is_ok()); + Ok(()) + } +} diff --git a/libs/sqldb/src/lib.rs b/libs/sqldb/src/lib.rs new file mode 100644 index 0000000..358ed38 --- /dev/null +++ b/libs/sqldb/src/lib.rs @@ -0,0 +1,88 @@ +use anyhow::Result; +use once_cell::sync::Lazy; +use serde::{Deserialize, Serialize}; +use sqlx::{ + migrate::MigrateDatabase, + sqlite::{Sqlite, SqlitePoolOptions}, + Pool, +}; +use tokio::sync::Mutex; + +pub mod entry; + +const MAX_CONNECTIONS: u32 = 3; + +#[derive(Serialize, Deserialize, Debug, Clone, sqlx::FromRow)] +pub struct ComEntry { + pub uuid: String, + pub data: String, +} + +static POOL: Lazy>>> = Lazy::new(|| Mutex::new(None)); + +async fn pool() -> Pool { + POOL.lock().await.clone().unwrap() +} + +pub async fn create_db(db_path: &str) -> Result<()> { + Sqlite::create_database(db_path).await?; + + let pool = SqlitePoolOptions::new() + .max_connections(MAX_CONNECTIONS) + .connect(&format!("sqlite:{}", db_path)) + .await?; + + *POOL.lock().await = Some(pool); + + Ok(()) +} + +pub async fn is_table_exist(table_name: &str) -> Result<()> { + sqlx::query("SELECT name FROM sqlite_master WHERE type='table' AND name=?") + .bind(table_name) + .fetch_one(&pool().await) + .await?; + + Ok(()) +} + +pub async fn drop_table(table_name: &str) -> Result<()> { + sqlx::query(&format!("DROP TABLE {}", table_name)) + .execute(&pool().await) + .await?; + + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + + static MTX: Lazy> = Lazy::new(|| Mutex::new(())); + const DB_PATH: &str = "/tmp/db-test.db"; + + pub async fn init(db_path: &str) { + create_db(db_path).await.expect("create db"); + entry::new("test").await.expect("account table failed"); + } + + #[tokio::test] + async fn test_db_is_table_exist() -> Result<()> { + let _mtx = MTX.lock().await; + + init(DB_PATH).await; + assert!(is_table_exist("hello").await.is_err()); + assert!(is_table_exist("test").await.is_ok()); + Ok(()) + } + + #[tokio::test] + async fn test_db_drop_table() -> Result<()> { + let _mtx = MTX.lock().await; + + init(DB_PATH).await; + assert!(drop_table("hello").await.is_err()); + assert!(drop_table("test").await.is_ok()); + Ok(()) + } +} diff --git a/res/drawable-hdpi/android12splash.png b/res/drawable-hdpi/android12splash.png new file mode 100644 index 0000000..d4b4330 Binary files /dev/null and b/res/drawable-hdpi/android12splash.png differ diff --git a/res/drawable-hdpi/splash.png b/res/drawable-hdpi/splash.png new file mode 100644 index 0000000..d4b4330 Binary files /dev/null and b/res/drawable-hdpi/splash.png differ diff --git a/res/drawable-mdpi/android12splash.png b/res/drawable-mdpi/android12splash.png new file mode 100644 index 0000000..d4b4330 Binary files /dev/null and b/res/drawable-mdpi/android12splash.png differ diff --git a/res/drawable-mdpi/splash.png b/res/drawable-mdpi/splash.png new file mode 100644 index 0000000..d4b4330 Binary files /dev/null and b/res/drawable-mdpi/splash.png differ diff --git a/res/drawable-v21/background.png b/res/drawable-v21/background.png new file mode 100644 index 0000000..ee53b59 Binary files /dev/null and b/res/drawable-v21/background.png differ diff --git a/res/drawable-v21/launch_background.xml b/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..3cc4948 --- /dev/null +++ b/res/drawable-v21/launch_background.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/res/drawable-xhdpi/android12splash.png b/res/drawable-xhdpi/android12splash.png new file mode 100644 index 0000000..d4b4330 Binary files /dev/null and b/res/drawable-xhdpi/android12splash.png differ diff --git a/res/drawable-xhdpi/splash.png b/res/drawable-xhdpi/splash.png new file mode 100644 index 0000000..d4b4330 Binary files /dev/null and b/res/drawable-xhdpi/splash.png differ diff --git a/res/drawable-xxhdpi/android12splash.png b/res/drawable-xxhdpi/android12splash.png new file mode 100644 index 0000000..d4b4330 Binary files /dev/null and b/res/drawable-xxhdpi/android12splash.png differ diff --git a/res/drawable-xxhdpi/splash.png b/res/drawable-xxhdpi/splash.png new file mode 100644 index 0000000..d4b4330 Binary files /dev/null and b/res/drawable-xxhdpi/splash.png differ diff --git a/res/drawable-xxxhdpi/android12splash.png b/res/drawable-xxxhdpi/android12splash.png new file mode 100644 index 0000000..d4b4330 Binary files /dev/null and b/res/drawable-xxxhdpi/android12splash.png differ diff --git a/res/drawable-xxxhdpi/splash.png b/res/drawable-xxxhdpi/splash.png new file mode 100644 index 0000000..d4b4330 Binary files /dev/null and b/res/drawable-xxxhdpi/splash.png differ diff --git a/res/drawable/background.png b/res/drawable/background.png new file mode 100644 index 0000000..ee53b59 Binary files /dev/null and b/res/drawable/background.png differ diff --git a/res/drawable/launch_background.xml b/res/drawable/launch_background.xml new file mode 100644 index 0000000..3cc4948 --- /dev/null +++ b/res/drawable/launch_background.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/res/layout/activity_main.xml b/res/layout/activity_main.xml new file mode 100644 index 0000000..8c960d1 --- /dev/null +++ b/res/layout/activity_main.xml @@ -0,0 +1,7 @@ + + + diff --git a/res/mipmap-hdpi/ic_launcher.png b/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..c925178 Binary files /dev/null and b/res/mipmap-hdpi/ic_launcher.png differ diff --git a/res/mipmap-ldpi/ic_launcher.png b/res/mipmap-ldpi/ic_launcher.png new file mode 100644 index 0000000..c925178 Binary files /dev/null and b/res/mipmap-ldpi/ic_launcher.png differ diff --git a/res/mipmap-mdpi/ic_launcher.png b/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..c925178 Binary files /dev/null and b/res/mipmap-mdpi/ic_launcher.png differ diff --git a/res/mipmap-xhdpi/ic_launcher.png b/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..c925178 Binary files /dev/null and b/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/res/mipmap-xxhdpi/ic_launcher.png b/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..c925178 Binary files /dev/null and b/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/res/mipmap-xxxhdpi/ic_launcher.png b/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..c925178 Binary files /dev/null and b/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/res/values-v31/colors.xml b/res/values-v31/colors.xml new file mode 100644 index 0000000..c326930 --- /dev/null +++ b/res/values-v31/colors.xml @@ -0,0 +1,7 @@ + + + + #3F51B5 + #FFFFFF + #303F9F + diff --git a/res/values-v31/styles.xml b/res/values-v31/styles.xml new file mode 100644 index 0000000..ea4d460 --- /dev/null +++ b/res/values-v31/styles.xml @@ -0,0 +1,14 @@ + + + + diff --git a/res/values/colors.xml b/res/values/colors.xml new file mode 100644 index 0000000..c326930 --- /dev/null +++ b/res/values/colors.xml @@ -0,0 +1,7 @@ + + + + #3F51B5 + #FFFFFF + #303F9F + diff --git a/res/values/styles.xml b/res/values/styles.xml new file mode 100644 index 0000000..208f652 --- /dev/null +++ b/res/values/styles.xml @@ -0,0 +1,12 @@ + + + + diff --git a/rust-toolchain b/rust-toolchain new file mode 100644 index 0000000..2bf5ad0 --- /dev/null +++ b/rust-toolchain @@ -0,0 +1 @@ +stable diff --git a/script/.gitignore b/script/.gitignore new file mode 100644 index 0000000..0cf8558 --- /dev/null +++ b/script/.gitignore @@ -0,0 +1,2 @@ +./json +./re diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..42e1add --- /dev/null +++ b/shell.nix @@ -0,0 +1,5 @@ +{ pkgs ? import { } }: +pkgs.mkShell { + buildInputs = with pkgs; [ libGL.dev openssl qt5.full xorg.libxcb ]; + nativeBuildInputs = with pkgs; [ pkg-config python3 libsForQt5.qmake ]; +} diff --git a/src/config/conf.rs b/src/config/conf.rs new file mode 100644 index 0000000..dca053d --- /dev/null +++ b/src/config/conf.rs @@ -0,0 +1,151 @@ +use super::data::{self, Config}; +use anyhow::{Context, Result}; +use log::debug; +use once_cell::sync::Lazy; +use std::{fs, path::PathBuf, sync::Mutex}; + +static CONFIG: Lazy> = Lazy::new(|| Mutex::new(Config::default())); + +#[cfg(not(target_os = "android"))] +use platform_dirs::AppDirs; + +#[cfg(target_os = "android")] +pub struct AppDirs { + pub config_dir: PathBuf, + pub data_dir: PathBuf, +} + +#[cfg(target_os = "android")] +impl AppDirs { + pub fn new(name: Option<&str>, _: bool) -> Option { + let root_dir = "/data/data"; + let name = name.unwrap(); + + Some(Self { + config_dir: PathBuf::from(&format!("{root_dir}/{name}/config")), + data_dir: PathBuf::from(&format!("{root_dir}/{name}/data")), + }) + } +} + +pub fn init() { + if let Err(e) = CONFIG.lock().unwrap().init() { + log::error!("{e:?}"); + panic!("{:?}", e); + } +} + +#[allow(dead_code)] +pub fn appid() -> String { + CONFIG.lock().unwrap().appid.clone() +} + +pub fn is_first_run() -> bool { + CONFIG.lock().unwrap().is_first_run +} + +pub fn all() -> data::Config { + CONFIG.lock().unwrap().clone() +} + +#[allow(dead_code)] +pub fn reset(mut conf: Config) { + let mut c = CONFIG.lock().unwrap(); + + conf.config_path = c.config_path.clone(); + conf.db_path = c.db_path.clone(); + conf.cache_dir = c.cache_dir.clone(); + conf.is_first_run = c.is_first_run; + + *c = conf; + _ = c.save(); +} + +pub fn ui() -> data::UI { + CONFIG.lock().unwrap().ui.clone() +} + +pub fn db_path() -> PathBuf { + CONFIG.lock().unwrap().db_path.clone() +} + +#[allow(dead_code)] +pub fn cache_dir() -> PathBuf { + CONFIG.lock().unwrap().cache_dir.clone() +} + +pub fn save(conf: data::Config) -> Result<()> { + let mut config = CONFIG.lock().unwrap(); + *config = conf; + config.save() +} + +impl Config { + pub fn init(&mut self) -> Result<()> { + let app_name = if cfg!(not(target_os = "android")) { + "slint" + } else { + if cfg!(debug_assertions) { + "xyz.heng30.slint" + } else { + "xyz.heng30.slint" + } + }; + + let app_dirs = AppDirs::new(Some(app_name), true).unwrap(); + self.init_config(&app_dirs)?; + self.load().with_context(|| "load config file failed")?; + debug!("{:?}", self); + Ok(()) + } + + fn init_config(&mut self, app_dirs: &AppDirs) -> Result<()> { + self.db_path = app_dirs.data_dir.join("slint.db"); + self.config_path = app_dirs.config_dir.join("slint.toml"); + self.cache_dir = app_dirs.data_dir.join("cache"); + + if self.appid.is_empty() { + self.appid = super::data::appid_default(); + } + + fs::create_dir_all(&app_dirs.data_dir)?; + fs::create_dir_all(&app_dirs.config_dir)?; + fs::create_dir_all(&self.cache_dir)?; + + Ok(()) + } + + fn load(&mut self) -> Result<()> { + match fs::read_to_string(&self.config_path) { + Ok(text) => match toml::from_str::(&text) { + Ok(c) => { + self.appid = c.appid; + self.ui = c.ui; + Ok(()) + } + Err(_) => { + self.is_first_run = true; + match toml::to_string_pretty(self) { + Ok(text) => Ok(fs::write(&self.config_path, text)?), + Err(e) => Err(e.into()), + } + } + }, + Err(_) => { + self.is_first_run = true; + match toml::to_string_pretty(self) { + Ok(text) => Ok(fs::write(&self.config_path, text)?), + Err(e) => Err(e.into()), + } + } + } + } + + pub fn save(&self) -> Result<()> { + match toml::to_string_pretty(self) { + Ok(text) => Ok(fs::write(&self.config_path, text) + .with_context(|| format!("save config failed"))?), + Err(e) => anyhow::bail!(format!("convert config from toml format failed. {e:?}")), + } + } +} diff --git a/src/config/data.rs b/src/config/data.rs new file mode 100644 index 0000000..8f4fa49 --- /dev/null +++ b/src/config/data.rs @@ -0,0 +1,42 @@ +use serde::{Deserialize, Serialize}; +use std::path::PathBuf; +use uuid::Uuid; + +#[derive(Serialize, Deserialize, Default, Debug, Clone)] +pub struct Config { + #[serde(skip)] + pub config_path: PathBuf, + + #[serde(skip)] + pub db_path: PathBuf, + + #[serde(skip)] + pub cache_dir: PathBuf, + + #[serde(skip)] + pub is_first_run: bool, + + #[serde(default = "appid_default")] + pub appid: String, + + pub ui: UI, +} + +#[derive(Serialize, Deserialize, Debug, Clone, Derivative)] +#[derivative(Default)] +pub struct UI { + #[derivative(Default(value = "16"))] + pub font_size: u32, + + #[derivative(Default(value = "\"Default\".to_string()"))] + pub font_family: String, + + #[derivative(Default(value = "\"cn\".to_string()"))] + pub language: String, + + pub is_dark: bool, +} + +pub fn appid_default() -> String { + Uuid::new_v4().to_string() +} diff --git a/src/config/mod.rs b/src/config/mod.rs new file mode 100644 index 0000000..b69a112 --- /dev/null +++ b/src/config/mod.rs @@ -0,0 +1,4 @@ +mod conf; +mod data; + +pub use conf::{all, db_path, init, is_first_run, save, ui}; diff --git a/src/db/def.rs b/src/db/def.rs new file mode 100644 index 0000000..f28b340 --- /dev/null +++ b/src/db/def.rs @@ -0,0 +1,90 @@ +// use serde::{Deserialize, Deserializer, Serialize, Serializer}; +// use serde_with::{serde_as, DeserializeAs, SerializeAs}; + +// use crate::slint_generatedAppWindow::{ +// AccountEntry as UIAccountEntry, AddressBookEntry as UIAddressBookEntry, +// TokenTileEntry as UITokenTileEntry, TransactionTileEntry as UIHistoryEntry, +// TransactionTileStatus, +// }; +// pub const ACCOUNTS_TABLE: &str = "accounts"; +// pub const ADDRESS_BOOK_TABLE: &str = "address_book"; +// pub const HISTORY_TABLE: &str = "history"; +// pub const TOKENS_TABLE: &str = "tokens"; + +// #[derive(Serialize, Deserialize, Debug, Clone, Default)] +// pub struct AccountEntry { +// pub uuid: String, +// pub name: String, +// pub pubkey: String, +// pub derive_index: i32, +// pub avatar_index: i32, +// } + +// impl From for AccountEntry { +// fn from(entry: UIAccountEntry) -> Self { +// AccountEntry { +// uuid: entry.uuid.into(), +// name: entry.name.into(), +// pubkey: entry.pubkey.into(), +// derive_index: entry.derive_index, +// avatar_index: entry.avatar_index, +// } +// } +// } + +// impl From for UIAccountEntry { +// fn from(entry: AccountEntry) -> Self { +// UIAccountEntry { +// uuid: entry.uuid.into(), +// name: entry.name.into(), +// pubkey: entry.pubkey.into(), +// derive_index: entry.derive_index, +// avatar_index: entry.avatar_index, +// } +// } +// } + +// #[serde_as] +// #[derive(Serialize, Deserialize, Debug, Clone, Default)] +// pub struct HistoryEntry { +// pub uuid: String, +// pub network: String, +// pub hash: String, +// pub balance: String, +// pub time: String, + +// #[serde_as(as = "TranStatus")] +// pub status: TransactionTileStatus, +// } + +// struct TranStatus; +// impl SerializeAs for TranStatus { +// fn serialize_as(source: &TransactionTileStatus, serializer: S) -> Result +// where +// S: Serializer, +// { +// let status = match source { +// TransactionTileStatus::Success => "Success", +// TransactionTileStatus::Pending => "Pending", +// _ => "Error", +// }; + +// serializer.serialize_str(status) +// } +// } + +// impl<'de> DeserializeAs<'de, TransactionTileStatus> for TranStatus { +// fn deserialize_as(deserializer: D) -> Result +// where +// D: Deserializer<'de>, +// { +// let status = String::deserialize(deserializer)?; +// let status = match status.as_str() { +// "Success" => TransactionTileStatus::Success, +// "Pending" => TransactionTileStatus::Pending, +// _ => TransactionTileStatus::Error, +// }; +// Ok(status) +// } +// } + diff --git a/src/db/mod.rs b/src/db/mod.rs new file mode 100644 index 0000000..f038d77 --- /dev/null +++ b/src/db/mod.rs @@ -0,0 +1,11 @@ +pub mod def; + +// pub use sqldb::{create_db, entry}; + +pub async fn init(_db_path: &str) { + // create_db(db_path).await.expect("create db"); + // entry::new(def::ACCOUNTS_TABLE) + // .await + // .expect("account table failed"); + +} diff --git a/src/desktop.rs b/src/desktop.rs new file mode 100644 index 0000000..94432a0 --- /dev/null +++ b/src/desktop.rs @@ -0,0 +1,6 @@ +#[cfg(not(target_os = "android"))] +#[tokio::main] +async fn main() { + extern crate slint_template; + slint_template::desktop_main().await; +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..cc71104 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,97 @@ +#![windows_subsystem = "windows"] + +slint::include_modules!(); + +#[macro_use] +extern crate derivative; + +mod config; +mod db; +mod logic; +mod version; + +#[cfg(not(target_os = "android"))] +pub fn init_logger() { + use cutil::chrono::Local; + use env_logger::fmt::Color; + use std::io::Write; + + env_logger::builder() + .format(|buf, record| { + let ts = Local::now().format("%Y-%m-%d %H:%M:%S"); + let mut level_style = buf.style(); + match record.level() { + log::Level::Warn | log::Level::Error => { + level_style.set_color(Color::Red).set_bold(true) + } + _ => level_style.set_color(Color::Blue).set_bold(true), + }; + + writeln!( + buf, + "[{} {} {} {}] {}", + ts, + level_style.value(record.level()), + record + .file() + .unwrap_or("None") + .split('/') + .last() + .unwrap_or("None"), + record.line().unwrap_or(0), + record.args() + ) + }) + .init(); +} + +#[cfg(target_os = "android")] +fn init_logger() { + android_logger::init_once( + android_logger::Config::default() + .with_max_level(log::LevelFilter::Trace) + .with_filter( + android_logger::FilterBuilder::new() + .filter_level(log::LevelFilter::Debug) + .build(), + ), + ); +} + +async fn ui_before() { + init_logger(); + config::init(); + db::init(config::db_path().to_str().expect("invalid db path")).await; +} + +fn ui_after(ui: &AppWindow) { + logic::init(ui); +} + +#[cfg(target_os = "android")] +#[no_mangle] +#[tokio::main] +async fn android_main(app: slint::android::AndroidApp) { + log::debug!("start..."); + + slint::android::init(app).unwrap(); + ui_before().await; + let ui = AppWindow::new().unwrap(); + ui_after(&ui); + ui.run().unwrap(); + + log::debug!("exit..."); +} + +#[cfg(not(target_os = "android"))] +pub async fn desktop_main() { + log::debug!("start..."); + + ui_before().await; + let ui = AppWindow::new().unwrap(); + ui_after(&ui); + + ui.run().unwrap(); + + log::debug!("exit..."); +} diff --git a/src/logic/about.rs b/src/logic/about.rs new file mode 100644 index 0000000..02343af --- /dev/null +++ b/src/logic/about.rs @@ -0,0 +1,14 @@ +use crate::slint_generatedAppWindow::{AboutSetting, AppWindow}; +use crate::version::VERSION; +use slint::ComponentHandle; + +pub fn init(ui: &AppWindow) { + ui.global::().set_title(slint::format!( + "sollaw {}", + if VERSION.is_empty() { + "v0.0.1" + } else { + VERSION + } + )); +} diff --git a/src/logic/clipboard.rs b/src/logic/clipboard.rs new file mode 100644 index 0000000..3167756 --- /dev/null +++ b/src/logic/clipboard.rs @@ -0,0 +1,88 @@ +use super::tr::tr; +use crate::{ + toast_success, toast_warn, + slint_generatedAppWindow::{AppWindow, Logic}, +}; +use anyhow::{bail, Result}; +use slint::ComponentHandle; + +#[cfg(not(target_os = "android"))] +fn copy_to_clipboard(msg: &str) -> Result<()> { + use clipboard::{ClipboardContext, ClipboardProvider}; + let ctx: Result = ClipboardProvider::new(); + + match ctx { + Ok(mut ctx) => match ctx.set_contents(msg.to_string()) { + Err(e) => bail!("{e:?}"), + _ => Ok(()), + }, + Err(e) => bail!("{e:?}"), + } +} + +#[cfg(not(target_os = "android"))] +fn copy_from_clipboard() -> Result { + use clipboard::{ClipboardContext, ClipboardProvider}; + let ctx: Result = ClipboardProvider::new(); + + match ctx { + Ok(mut ctx) => match ctx.get_contents() { + Err(e) => bail!("{e:?}"), + Ok(msg) => Ok(msg), + }, + Err(e) => bail!("{e:?}"), + } +} + +#[cfg(target_os = "android")] +fn copy_to_clipboard(msg: &str) -> Result<()> { + match terminal_clipboard::set_string(msg) { + Err(e) => bail!("{e:?}"), + _ => Ok(()), + } +} + +#[cfg(target_os = "android")] +fn copy_from_clipboard() -> Result { + match terminal_clipboard::get_string() { + Err(e) => bail!("{e:?}"), + Ok(msg) => Ok(msg), + } +} + +pub fn init(ui: &AppWindow) { + let ui_handle = ui.as_weak(); + ui.global::().on_copy_to_clipboard(move |msg| { + let ui = ui_handle.unwrap(); + match copy_to_clipboard(&msg) { + Err(e) => toast_warn!(ui, format!("{}. {}: {e:?}", tr("复制失败"), tr("原因"))), + _ => toast_success!(ui, tr("复制成功")), + } + }); + + let ui_handle = ui.as_weak(); + ui.global::().on_copy_from_clipboard(move || { + let ui = ui_handle.unwrap(); + match copy_from_clipboard() { + Err(e) => { + toast_warn!(ui, format!("{}. {}: {e:?}", tr("粘贴失败"), tr("原因"))); + slint::SharedString::default() + } + Ok(msg) => msg.into(), + } + }); +} + +#[cfg(test)] +mod tests { + use super::*; + + fn test_clipboard() -> Result<()> { + let msg = "hello world"; + copy_to_clipboard(msg)?; + let res = copy_from_clipboard()?; + + assert_eq!(msg, res); + Ok(()) + } +} diff --git a/src/logic/confirm_dialog.rs b/src/logic/confirm_dialog.rs new file mode 100644 index 0000000..46a4530 --- /dev/null +++ b/src/logic/confirm_dialog.rs @@ -0,0 +1,17 @@ +use crate::slint_generatedAppWindow::{AppWindow, Logic}; +use slint::ComponentHandle; + +pub fn init(ui: &AppWindow) { + let ui_handle = ui.as_weak(); + ui.global::() + .on_handle_confirm_dialog(move |handle_type, _user_data| { + let _ui = ui_handle.unwrap(); + + match handle_type.as_str() { + // "remove-all-cache" => { + // ui.global::().invoke_remove_all_cache(); + // } + _ => (), + } + }); +} diff --git a/src/logic/mod.rs b/src/logic/mod.rs new file mode 100644 index 0000000..137a8ea --- /dev/null +++ b/src/logic/mod.rs @@ -0,0 +1,18 @@ +use crate::slint_generatedAppWindow::AppWindow; + +mod about; +mod clipboard; +mod toast; +mod confirm_dialog; +mod setting; +mod tr; +mod util; + +pub fn init(ui: &AppWindow) { + util::init(&ui); + clipboard::init(&ui); + toast::init(&ui); + confirm_dialog::init(&ui); + about::init(&ui); + setting::init(&ui); +} diff --git a/src/logic/setting.rs b/src/logic/setting.rs new file mode 100644 index 0000000..6ca372e --- /dev/null +++ b/src/logic/setting.rs @@ -0,0 +1,57 @@ +use super::tr::tr; +use crate::{ + config, + slint_generatedAppWindow::{AppWindow, Logic, Store, Theme}, +}; +use slint::ComponentHandle; + +pub fn init(ui: &AppWindow) { + init_setting(&ui); + + ui.global::() + .set_is_first_run(config::is_first_run()); + + ui.global::() + .set_is_show_landing_page(config::is_first_run()); + + ui.global::() + .on_tr(move |_is_cn, text| tr(text.as_str()).into()); + + let ui_handle = ui.as_weak(); + ui.global::().on_get_setting_ui(move || { + let ui = ui_handle.unwrap(); + ui.global::().get_setting_ui() + }); + + let ui_handle = ui.as_weak(); + ui.global::().on_set_setting_ui(move |mut setting| { + let font_size = u32::min(50, u32::max(10, setting.font_size.parse().unwrap_or(16))); + setting.font_size = slint::format!("{}", font_size); + + ui_handle + .unwrap() + .global::() + .set_setting_ui(setting.clone()); + + let mut all = config::all(); + all.ui.font_size = font_size.into(); + all.ui.font_family = setting.font_family.into(); + all.ui.language = setting.language.into(); + all.ui.is_dark = setting.is_dark; + _ = config::save(all); + }); +} + +fn init_setting(ui: &AppWindow) { + let config = config::ui(); + let mut ui_setting = ui.global::().get_setting_ui(); + + let font_size = u32::min(50, u32::max(10, config.font_size)); + ui_setting.font_size = slint::format!("{}", font_size); + ui_setting.font_family = config.font_family.into(); + ui_setting.language = config.language.into(); + ui_setting.is_dark = config.is_dark; + + ui.global::().invoke_set_dark(config.is_dark); + ui.global::().set_setting_ui(ui_setting); +} diff --git a/src/logic/toast.rs b/src/logic/toast.rs new file mode 100644 index 0000000..1f14117 --- /dev/null +++ b/src/logic/toast.rs @@ -0,0 +1,82 @@ +use crate::slint_generatedAppWindow::{AppWindow, ToastSetting, Util}; +use slint::{ComponentHandle, Timer, TimerMode, Weak}; + +#[macro_export] +macro_rules! toast_warn { + ($ui:expr, $msg:expr) => { + $ui.global::() + .invoke_show_toast(slint::format!("{}", $msg), "warning".into()) + }; +} + +#[macro_export] +macro_rules! toast_success { + ($ui:expr, $msg:expr) => { + $ui.global::() + .invoke_show_toast(slint::format!("{}", $msg), "success".into()) + }; +} + +#[allow(dead_code)] +#[macro_export] +macro_rules! toast_info { + ($ui:expr, $msg:expr) => { + $ui.global::() + .invoke_show_toast(slint::format!("{}", $msg), "info".into()) + }; +} + +#[allow(dead_code)] +pub fn async_toast_warn(ui: Weak, msg: String) { + let _ = slint::invoke_from_event_loop(move || { + ui.unwrap() + .global::() + .invoke_show_toast(slint::format!("{}", msg), "warning".into()); + }); +} + +#[allow(dead_code)] +pub fn async_toast_success(ui: Weak, msg: String) { + let _ = slint::invoke_from_event_loop(move || { + ui.unwrap() + .global::() + .invoke_show_toast(slint::format!("{}", msg), "success".into()); + }); +} + +#[allow(dead_code)] +pub fn async_toast_info(ui: Weak, msg: String) { + let _ = slint::invoke_from_event_loop(move || { + ui.unwrap() + .global::() + .invoke_show_toast(slint::format!("{}", msg), "info".into()); + }); +} + +pub fn init(ui: &AppWindow) { + let timer = Timer::default(); + let ui_handle = ui.as_weak(); + ui.global::().on_show_toast(move |msg, msg_type| { + let ui = ui_handle.unwrap(); + + if timer.running() { + timer.stop(); + } + + let interval = if msg.chars().collect::>().len() > 20 { + 5 + } else { + 2 + }; + + ui.global::().invoke_set(msg, msg_type); + + timer.start( + TimerMode::SingleShot, + std::time::Duration::from_secs(interval), + move || { + ui.global::().invoke_set("".into(), "".into()); + }, + ); + }); +} diff --git a/src/logic/tr.rs b/src/logic/tr.rs new file mode 100644 index 0000000..a50d171 --- /dev/null +++ b/src/logic/tr.rs @@ -0,0 +1,307 @@ +use crate::config; +use std::collections::HashMap; + +pub fn tr(text: &str) -> String { + if config::ui().language == "cn" { + return text.to_string(); + } + + let mut items: HashMap<&str, &str> = HashMap::new(); + items.insert("出错", "Error"); + items.insert("原因", "Reason"); + items.insert("取消", "Cancel"); + items.insert("确认", "Confirm"); + items.insert("确定", "Confirm"); + items.insert("编辑", "Edit"); + items.insert("删除", "Delete"); + items.insert("清空", "Clear"); + items.insert("发送", "Send"); + + items.insert("删除成功", "Delete success"); + items.insert("删除失败", "Delete failed"); + items.insert("添加成功", "Add success"); + items.insert("添加失败", "Add failed"); + items.insert("复制失败", "Copy failed"); + items.insert("复制成功", "Copy success"); + items.insert("清空失败", "Delete failed"); + items.insert("清空成功", "Delete success"); + items.insert("保存失败", "Save failed"); + items.insert("保存成功", "Save success"); + items.insert("重置成功", "Reset success"); + items.insert("刷新成功", "Refresh success"); + items.insert("刷新失败", "Refresh failed"); + items.insert("发送失败", "Send failed"); + items.insert("下载成功", "Download success"); + items.insert("下载失败", "Download failed"); + items.insert("加载失败", "Load failed"); + items.insert("非法输入", "Invalid input"); + items.insert("打开链接失败", "Open link failed"); + + items.insert("新建成功", "New success"); + items.insert("新建失败", "New failed"); + items.insert("编辑成功", "Edit success"); + items.insert("编辑失败", "Edit failed"); + + items.insert("微信支付", "Wechat pay"); + items.insert("小狐狸(加密)支付", "MetaMask crypto pay"); + + items.insert("收藏成功", "Favorite success"); + items.insert("收藏失败", "Favorite failed"); + items.insert("取消收藏成功", "Cancel favorite success"); + items.insert("取消收藏失败", "Cancel favorite failed"); + + items.insert("正在刷新...", "Refreshing..."); + items.insert("正在同步...", "Syncing..."); + items.insert("同步成功", "Refresh success"); + items.insert("同步完成", "Refresh finished"); + items.insert("查找完成", "Search finish"); + items.insert("返回为空", "Empty data"); + + items.insert("是否删除?", "Delete or not?"); + items.insert("是否删除全部?", "Delete all entrys or not?"); + items.insert("是否删除全部缓存?", "Delete all cache or not?"); + items.insert("清除缓存失败", "Remove cache failed"); + items.insert("清除缓存成功", "Remove cache success"); + items.insert("超过1000字数限制", "Over the limit of 2048 word counts"); + + items.insert("界 面", "UI"); + items.insert("偏好设置", "Preference"); + items.insert("账户管理", "Account"); + items.insert("阅 读", "Reading"); + items.insert("同 步", "Sync"); + items.insert("代 理", "Proxy"); + items.insert("缓 存", "Cache"); + items.insert("关 于", "About"); + items.insert("帮 助", "Help"); + items.insert("反 馈", "Feedback"); + items.insert("捐 赠", "Donate"); + + items.insert("新建", "New"); + items.insert("没有订阅", "No RSS"); + items.insert("RSS名称和图标", "RSS name and icon"); + items.insert("请输入RSS名称", "Please input RSS name"); + items.insert("RSS源地址", "RSS URL"); + items.insert("请输入RSS源地址", "Please input RSS URL"); + items.insert("RSS源格式", "RSS format"); + items.insert("已启用Http代理", "Enabled Http proxy"); + items.insert("未启用Http代理", "Disable Http proxy"); + items.insert("已启用Socks5代理", "Enabled Socks5 proxy"); + items.insert("未启用Socks5代理", "Disable Socks5 proxy"); + items.insert("已收藏", "Star"); + items.insert("未收藏", "Not star"); + items.insert("图标库", "Icons"); + items.insert("请选择条目", "Please select entry"); + items.insert("请添加RSS源", "Please add RSS URL"); + items.insert("选择浏览器", "Select browser"); + items.insert("已启用阅后即焚", "Enabled delete after reading"); + items.insert("未启用阅后即焚", "Disable delete after reading"); + + items.insert("字体大小", "Font size"); + items.insert("字体样式", "Font family"); + items.insert("选择语言", "Choose language"); + items.insert("同步时间间隔(分钟)", "Sync time interval(minute)"); + items.insert("请输入时间间隔", "Please input time interval"); + items.insert("同步超时(秒)", "Sync timeout(second)"); + items.insert("请输入同步超时", "Please input sync timeout"); + items.insert("已启用自动同步", "Enabled auto sync"); + items.insert("未启用自动同步", "Disable auto sync"); + items.insert( + "程序启动时,马上进行一次同步", + "Starting sync once, when application starting", + ); + items.insert( + "程序启动时,不马上进行一次同步", + "Don't start sync, when application starting", + ); + items.insert("代理地址", "Proxy address"); + items.insert("代理端口", "Proxy port"); + + items.insert("警告", "Warning"); + items.insert("订阅", "RSS"); + items.insert("收藏夹", "Collection"); + items.insert("发现", "Find"); + items.insert("添加", "Add"); + items.insert("设置", "Setting"); + + items.insert("成功移除黑名单", "Remove from blacklist success"); + items.insert("没有数据", "No Data"); + items.insert("没有消息", "No Message"); + items.insert("输入关键字", "Input keyword"); + + items.insert("备份与恢复", "Backup and recover"); + items.insert("API 令牌", "API token"); + items.insert("请输入API令牌", "Please input API token"); + items.insert("备份与恢复选项", "Backup and recover options"); + items.insert("RSS列表", "RSS list"); + items.insert("用户设置", "User setting"); + items.insert("备份", "Backup"); + items.insert("恢复", "Recover"); + items.insert("备份成功", "Backup success"); + items.insert("备份失败", "Backup failed"); + items.insert("恢复成功", "Recover success"); + items.insert("恢复失败", "Recover failed"); + items.insert("是否备份?", "Backup or not?"); + items.insert("是否恢复?", "Recover or not?"); + + items.insert("获取最新版本", "Latest version"); + items.insert("版本信息", "Current version"); + items.insert("当前版本", "Latest version"); + items.insert("更新信息", "Update detail"); + items.insert("下载最新版本", "Download"); + items.insert("选择主题", "Choose Theme"); + items.insert("白天", "Light"); + items.insert("黑暗", "Dark"); + items.insert("跳过", "Skip"); + items.insert("下一步", "Next"); + items.insert("完成", "Finish"); + items.insert("返回", "Back"); + items.insert("请选择语言", "Please select language"); + items.insert("没有记录", "No record"); + items.insert("没有地址", "No address"); + items.insert("请输入用户名", "Please enter username"); + items.insert("用户名", "Username"); + items.insert("请输入密码", "Please enter password"); + items.insert("请再次输入密码", "Please enter password again"); + items.insert("至少8个字符", "At least 8 chars"); + items.insert("创建账户", "Create account"); + items.insert("恢复账户", "Recover account"); + items.insert("生成组记词失败", "New mnemonic failed"); + items.insert("登录", "Login"); + items.insert( + "组记词数量不对,仅支持12和24个组记词", + "Mnemonic counts is no correct. Only support 12 or 24 word counts mnemonic", + ); + items.insert("非法组记词", "Invalid mnemonic"); + items.insert("用户名不能为空", "Username can not be empty"); + items.insert("密码不相同", "Two passwords is different"); + items.insert("密码不能小于8位", "Password can not less than 8 chars"); + items.insert("更新账户成功", "Update account success"); + items.insert( + "更新账户失败. 账户不存在", + "Update account failed. The account don't exist", + ); + items.insert("不允许删除当前用户", "Not allow delete current account"); + items.insert("不允许删除主账号", "Not allow delete the main account"); + items.insert("删除账户成功", "Delete account success"); + items.insert("移除账户成功", "Remove account success"); + items.insert("切换账户成功", "Switch account success"); + items.insert( + "切换账户失败. 账户不存在", + "Switch account failed. The account don't exist", + ); + items.insert( + "创建用户失败. 非法密码", + "Create account failed. Invalid password", + ); + items.insert("创建用户成功", "Create account success"); + items.insert("创建用户失败", "Create account failed"); + items.insert("账户管理", "Account Management"); + items.insert("是否删除账户?", "Delete account or not?"); + items.insert("内部错误", "Internal error"); + items.insert("密码错误", "Password is wrong"); + items.insert("组记词", "Mnemonic"); + items.insert("地址簿", "Address Book"); + items.insert("移除地址", "Delete address"); + items.insert("是否删除地址?", "Delete address or not?"); + items.insert("地址名称", "Address name"); + items.insert("账户地址", "Account address"); + items.insert("地 址", "Address"); + items.insert("删除地址成功", "Delete address success"); + items.insert("更新地址成功", "Update address success"); + items.insert("更新地址失败", "Update address failed"); + items.insert("切换账户", "Switch account"); + items.insert("是否删除所有账户?", "Delete all account or not?"); + items.insert("删除所有账户成功", "Delete all accounts success"); + items.insert("打开成功", "Open link success"); + items.insert("打开失败", "Open link failed"); + items.insert("安全与隐私", "Security & Privacy "); + items.insert("重置账户", "Reset account"); + items.insert("是否重置账户?", "Reset account or not?"); + items.insert("请输入旧密码", "Please input old password"); + items.insert("请输入新密码", "Please input new password"); + items.insert("请再次输入新密码", "Please input new password again"); + items.insert("测试模式", "Test model"); + items.insert("主网络", "Main Network"); + items.insert("测试网络", "Test Network"); + items.insert("开发网络", "Dev Network"); + items.insert("未知网络", "Unknown Network"); + items.insert("注意: 当前处于", "Warning: Current Network is "); + items.insert("主页", "Home"); + items.insert("接收", "Recipient"); + items.insert("接收代币", "Recipient"); + items.insert("历史", "History"); + items.insert("历史记录", "History"); + items.insert("开发者模式", "Developer Mode"); + items.insert("账户名称", "Account name"); + items.insert("显示组记词", "Show mnemonics"); + items.insert("移除账户", "Remove account"); + items.insert("更改密码", "Change password"); + items.insert("位组记词", "mnemonics"); + items.insert("刷新完成", "Refresh finished"); + items.insert("管理代币", "Manage token"); + items.insert("发送代币", "Send token"); + items.insert("获取Token失败", "Fetch account tokens failed"); + items.insert("更新账户余额成功", "Refresh account balance success"); + items.insert("请求空投", "Request airdrop"); + items.insert("请求空投成功", "Request airdrop success"); + items.insert("请求空投失败", "Request airdrop failed"); + items.insert("请耐心等待...", "It may takes a long time. Please wait..."); + items.insert("估计交易费用失败", "Evaluating transaction fee failed"); + items.insert("正在估计交易费用...", "Evaluating gas fee..."); + items.insert("交易记录", "Transaction signature"); + items.insert("区块网络", "Blockchain network"); + items.insert("发送数量", "Send amount"); + items.insert("交易记录", "Transaction history"); + items.insert("关闭", "Close"); + items.insert("交易失败", "Transaction failed"); + items.insert("等待交易确认...", "Waiting transaction confirmed..."); + items.insert("交易信息", "Transaction detail"); + items.insert("发送地址", "Send address"); + items.insert("接收地址", "Recipient address"); + items.insert("交易费用", "Transaction fee"); + items.insert("交易已经确认", "Transaction has been confirmed"); + items.insert("交易成功", "Transaction success"); + items.insert("非法地址", "Invalid address"); + items.insert("账户", "Account"); + items.insert("创建账户费用", "Create token account fee"); + items.insert("创建组记词", "Create mnemonic"); + items.insert("恢复账户", "Recover account"); + items.insert("二维码", "QrCode"); + items.insert("高级设置", "Advance setting"); + items.insert("备注", "Memo"); + items.insert("优先费用", "Prioritization fee"); + items.insert("基础费用", "Base fee"); + items.insert("最大优先费用", "Max prioritization fee"); + items.insert("最大优先费用为", "Max prioritization fee is"); + items.insert("慢", "Slow"); + items.insert("正常", "Normal"); + items.insert("快", "Fast"); + items.insert("非法优先费用", "Invalid prioritization fee"); + items.insert("请设置更大的优先费用", "Please setting max prioritization fee"); + items.insert("登出账户", "Logout account"); + items.insert("密码错误", "Wrong password"); + items.insert("内部错误. 密码不存在", "Internal error. Password not exist"); + items.insert( + "更新账户余额失败. 账户不存在", + "Refresh account balance failed. The account is not found", + ); + + items.insert( + "创建账户和使用组记词恢复账户", + "Create account and recover account from mnemonics", + ); + items.insert( + "查看、发送和接收Sol代币和Solana的通证", + "Show, send and receive Sol and tokens of Solana", + ); + items.insert( + "欢迎使用,享受你的加密之旅", + "Welcome! Enjoying you journey of crypto", + ); + + if let Some(txt) = items.get(text) { + return txt.to_string(); + } + + text.to_string() +} diff --git a/src/logic/util.rs b/src/logic/util.rs new file mode 100644 index 0000000..77e4301 --- /dev/null +++ b/src/logic/util.rs @@ -0,0 +1,95 @@ +use super::tr::tr; +use crate::{ + slint_generatedAppWindow::{AppWindow, Util}, + toast_warn, +}; +use cutil::{ + self, number, + rand::{self, Rng}, + time, +}; +use slint::ComponentHandle; +use std::str::FromStr; +use webbrowser::{self, Browser}; + +pub fn init(ui: &AppWindow) { + ui.global::().on_string_fixed2(move |n| { + let n = n.to_string().parse::().unwrap_or(0.0f32); + slint::format!("{:2}", (n * 100.0).round() / 100.0) + }); + + ui.global::() + .on_float_fixed2(move |n| slint::format!("{:2}", (n * 100.0).round() / 100.0)); + + let ui_handle = ui.as_weak(); + ui.global::().on_open_url(move |browser, url| { + let ui = ui_handle.unwrap(); + + let browser = Browser::from_str(&browser.to_lowercase()).unwrap_or_default(); + + let browser = if browser.exists() { + browser + } else { + Browser::Default + }; + + if let Err(e) = webbrowser::open_browser(browser, url.as_str()) { + toast_warn!(ui, format!("{}{}: {:?}", tr("打开链接失败"), tr("原因"), e)); + } + }); + + ui.global::() + .on_format_number_with_commas(move |number_str| { + number::format_number_with_commas(number_str.as_str()).into() + }); + + ui.global::() + .on_local_now(move |format| time::local_now(format.as_str()).into()); + + ui.global::().on_text_len(move |text| { + let chars_text = text.chars().collect::>(); + chars_text.len() as i32 + }); + + ui.global::() + .on_rand_int(move |low, up| rand::thread_rng().gen_range(low..up) as i32); + + ui.global::() + .on_split_and_join_string(move |input, length, sep| { + cutil::str::split_string_to_fixed_length_parts(input.as_str(), length as usize) + .join(sep.as_str()) + .into() + }); + + cfg_if::cfg_if! { + if #[cfg(feature = "qrcode")] { + init_qrcode(ui); + } + } +} + +#[cfg(feature = "qrcode")] +pub fn init_qrcode(ui: &AppWindow) { + use crate::slint_generatedAppWindow::Icons; + use image::Rgb; + use qrcode::QrCode; + use slint::{Image, Rgb8Pixel, SharedPixelBuffer}; + + let ui_handle = ui.as_weak(); + ui.global::().on_qr_code(move |text| { + let ui = ui_handle.unwrap(); + match QrCode::new(text) { + Ok(code) => { + let qrc = code.render::>().build(); + + let buffer = SharedPixelBuffer::::clone_from_slice( + qrc.as_raw(), + qrc.width(), + qrc.height(), + ); + Image::from_rgb8(buffer) + } + _ => ui.global::().get_no_data(), + } + }); +} diff --git a/src/version.rs b/src/version.rs new file mode 100644 index 0000000..ad45a2b --- /dev/null +++ b/src/version.rs @@ -0,0 +1 @@ +pub static VERSION: &str = "v0.1.3"; \ No newline at end of file diff --git a/ui/appwindow.slint b/ui/appwindow.slint new file mode 100644 index 0000000..cb2c0f3 --- /dev/null +++ b/ui/appwindow.slint @@ -0,0 +1,70 @@ +import { Theme, Icons } from "./theme.slint"; +import { Logic } from "./logic.slint"; +import { Store, SettingDetailIndex } from "./store.slint"; +import { Util } from "./util.slint"; +import { Panel } from "./panel/panel.slint"; +import { LoadingStatus, Toast, IconsDialogSetting, IconsDialog, ConfirmDialogDialog, ConfirmDialogSetting, Blanket, LandingPage, AboutSetting, ToastSetting } from "./base/widgets.slint"; + +export component AppWindow inherits Window { + default-font-size: Theme.default-font-size; + default-font-family: Theme.default-font-family; + preferred-width: Theme.default-width; + preferred-height: Theme.default-height; + + background: Theme.base-background; + icon: Icons.brand; + title: "slint-template"; + + Panel { } + + if IconsDialogSetting.show || ConfirmDialogSetting.show: Blanket { + clicked => { + IconsDialogSetting.show = false; + ConfirmDialogSetting.show = false; + } + } + + if IconsDialogSetting.show: IconsDialog { + is-prevent-event-forward: true; + select-index(handle-type, index, user-data) => { + } + } + + if ConfirmDialogSetting.show: ConfirmDialogDialog { + is-prevent-event-forward: true; + width: Math.min(root.width * 0.9, 380px); + } + + if ToastSetting.text != "": Toast { + x: root.width / 2 - self.width / 2; + y: 50px; + inner-max-width: root.width * 80%; + text: ToastSetting.text; + type: ToastSetting.text-type; + clicked => { + Logic.copy-to-clipboard(self.text); + } + } + + if Store.is-show-landing-page: LandingPage { + details: [ + { + picture: Icons.landing-account, + description: "", + }, + { + picture: Icons.landing-send, + description: "", + }, + { + picture: Icons.landing-welcome, + description: "", + } + ]; + skipped => { + Store.is-show-landing-page = false; + } + } +} + +export { Util, Logic, Store, Theme, Icons, IconsDialogSetting, LoadingStatus, SettingDetailIndex, AboutSetting, ToastSetting } diff --git a/ui/base/about.slint b/ui/base/about.slint new file mode 100644 index 0000000..ef3c2cd --- /dev/null +++ b/ui/base/about.slint @@ -0,0 +1,87 @@ +import { Logic } from "../logic.slint"; +import { Store } from "../store.slint"; +import { Util } from "../util.slint"; +import { Theme, Icons } from "../theme.slint"; +import { SettingDetail } from "setting-detail.slint"; +import { Label } from "label.slint"; +import { IconBtn } from "icon-btn.slint"; +import { Link } from "link.slint"; +import { Brand } from "brand.slint"; + + + + +export global AboutSetting { + in-out property title: "sollaw v0.0.1"; + in-out property sponsor: "0xf1199999751b1a3A74590adBf95401D19AB30014"; + in-out property text: "Based on Slint-UI. Copyright 2022-2030. All rights reserved. The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE."; +} + +export component About inherits SettingDetail { + title: Logic.tr(Store.is-cn, "关 于"); + + VerticalLayout { + alignment: start; + spacing: Theme.spacing * 4; + padding: Theme.padding * 2; + padding-top: Theme.padding * 4; + + HorizontalLayout { + alignment: center; + + Label { + color: Theme.brand-color; + text: AboutSetting.title; + font-size: Theme.title1-font-size; + } + } + + Label { + horizontal-alignment: center; + text: AboutSetting.text; + wrap: word-wrap; + } + + VerticalLayout { + spacing: Theme.spacing * 2; + HorizontalLayout { + alignment: center; + spacing: Theme.spacing * 2; + + Label { + text: "🎉❤Buy Me a Coffee(MetaMask)❤🎉"; + } + + IconBtn { + icon: Icons.copy; + clicked => { + Logic.copy-to-clipboard(AboutSetting.sponsor); + } + } + } + + HorizontalLayout { + alignment: center; + Link { + wrap: word-wrap; + text: AboutSetting.sponsor; + color: Theme.placeholder-text-color; + font-size: Theme.default-font-size - 2px; + + clicked => { + Util.open-url("Default", "https://etherscan.io/address/" + AboutSetting.sponsor); + } + } + } + } + + HorizontalLayout { + alignment: center; + padding-top: Theme.padding * 5; + + Brand { + width: Math.min(root.width * 50%, 300px); + } + } + } +} diff --git a/ui/base/account-balance.slint b/ui/base/account-balance.slint new file mode 100644 index 0000000..196d6df --- /dev/null +++ b/ui/base/account-balance.slint @@ -0,0 +1,41 @@ +import { Theme, Icons } from "../theme.slint"; +import { IconBtn } from "icon-btn.slint"; +import { TextBtn } from "btn.slint"; +import { Label } from "label.slint"; +import { Link } from "link.slint"; + +export component AccountBalance inherits Rectangle { + in-out property account-name <=> account.text; + in-out property balance <=> balance-label.text; + + callback account-clicked <=> account.clicked; + callback copy <=> copy-btn.clicked; + + VerticalLayout { + padding-top: Theme.padding * 5; + padding-bottom: Theme.padding * 5; + spacing: Theme.spacing * 2; + alignment: LayoutAlignment.start; + + HorizontalLayout { + alignment: LayoutAlignment.center; + spacing: Theme.spacing * 2; + + account := Link { + horizontal-alignment: TextHorizontalAlignment.center; + font-weight: 0.5; + font-size: Theme.title2-font-size; + } + + copy-btn := IconBtn { + icon: Icons.copy; + } + } + + balance-label := Label { + horizontal-alignment: TextHorizontalAlignment.center; + font-weight: 0.5; + font-size: Theme.title1-font-size * 1.5; + } + } +} diff --git a/ui/base/address-book.slint b/ui/base/address-book.slint new file mode 100644 index 0000000..7697c8b --- /dev/null +++ b/ui/base/address-book.slint @@ -0,0 +1,203 @@ +import { Theme, Icons } from "../theme.slint"; +import { Logic } from "../logic.slint"; +import { Store } from "../store.slint"; +import { SettingDetail, SettingDetailInner, SettingDetailInnerVbox, SettingDetailLabel } from "setting-detail.slint"; +import { SettingEntry } from "setting-entry.slint"; +import { ElevatedBtn } from "elevated-btn.slint"; +import { ListTile } from "list-tile.slint"; +import { NoDataImg } from "no-data.slint"; +import { CancelBtn } from "btn.slint"; +import { LineInput } from "line-input.slint"; +import { ConfirmDialogSetting } from "confirm-dialog.slint"; +import { IconBtn } from "icon-btn.slint"; + +export struct AddressBookEntry { + uuid: string, + name: string, + address: string, +} + +export global AddressBookSetting { + in-out property <[AddressBookEntry]> entries: [ + { + uuid: "uuid-1", + name: "Address-1", + address: "0xf1199999751b1a3A74590adBf95401D19AB30014" + }, + { + uuid: "uuid-1", + name: "Address-1", + address: "0xf1199999751b1a3A74590adBf95401D19AB30014" + } + ]; + + in-out property current-entry; + in-out property enabled-input; + + public function clear() { + self.entries = []; + } +} + +export component AddressBook inherits Rectangle { + in-out property item-height: 80px; + in property is-show-add-btn; + + callback back <=> sd.back; + callback add(); + callback tap(AddressBookEntry); + + if AddressBookSetting.entries.length == 0: NoDataImg { + width: 80%; + text: Logic.tr(Store.is-cn, "没有数据"); + } + + sd := SettingDetail { + title: Logic.tr(Store.is-cn, "地址簿"); + + SettingDetailInner { + vbox-spacing: Theme.spacing * 2; + for item[index] in AddressBookSetting.entries: ListTile { + height: item-height; + background: self.has-hover ? Theme.base-background.darker(3%) : Theme.base-background; + border-radius: Theme.border-radius; + drop-shadow-blur: Theme.padding * 2; + drop-shadow-color: Theme.base-background-drop-shadow; + + title-text: item.name; + subtitle-text: item.address; + subtitle-font-size: Theme.default-font-size - 2px; + middle-mouse-cursor: MouseCursor.pointer; + + is-show-right-icon: true; + right-icon: Icons.copy; + + middle-clicked => { + AddressBookSetting.current-entry = item; + root.tap(item); + } + + right-clicked => { + Logic.copy-to-clipboard(self.subtitle-text); + } + } + } + } + + if is-show-add-btn: ElevatedBtn { + x: root.width - self.width - Theme.padding * 4; + y: root.height - self.height - Theme.padding * 4 - Theme.footer-height; + icon: Icons.add-light; + + clicked => { + root.add(); + } + } +} + +export component AddressBookDetail inherits SettingDetail { + private property entry: AddressBookSetting.current-entry; + in property qr-code: Icons.no-data; + in-out property address <=> address-input.text; + + // (uuid, name) -> void + callback update-name(string, string); + + // (uuid, address) -> void + callback update-address(string, string); + + title: Logic.tr(Store.is-cn, "地 址"); + + SettingDetailInner { + HorizontalLayout { + private property icon-size: Math.min(300px, root.width - Theme.padding * 4); + alignment: LayoutAlignment.center; + + IconBtn { + width: parent.icon-size; + height: self.width; + colorize: Colors.transparent; + icon-size: parent.icon-size; + icon: qr-code; + show-icon-hover-background: false; + + clicked => { + Logic.copy-to-clipboard(address-input.text); + } + } + } + + SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "地址名称"); + } + + LineInput { + enabled: AddressBookSetting.enabled-input; + width: root.width - Theme.padding * 4; + text: entry.name; + icon: self.enabled ? Icons.checked-box : Icons.edit; + clicked => { + self.enabled = !self.enabled; + + if (self.enabled) { + self.focus(); + } else { + root.update-name(entry.uuid, self.text); + } + } + + accepted => { + self.clear-focus(); + self.enabled = !self.enabled; + root.update-name(entry.uuid, self.text); + } + } + } + + SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "账户地址"); + } + + address-input := LineInput { + enabled: AddressBookSetting.enabled-input; + width: root.width - Theme.padding * 4; + text: entry.address; + + icon: self.enabled ? Icons.checked-box : Icons.edit; + clicked => { + self.enabled = !self.enabled; + + if (self.enabled) { + self.focus(); + } else { + root.update-address(entry.uuid, self.text); + } + } + + accepted => { + self.clear-focus(); + self.enabled = !self.enabled; + root.update-address(entry.uuid, self.text); + } + } + } + + VerticalLayout { + padding-top: Theme.padding * 5; + CancelBtn { + icon: Icons.delete; + colorize: Theme.danger-color; + text-color: Theme.danger-color; + border-radius: Theme.border-radius; + font-size: Theme.title3-font-size; + text: Logic.tr(Store.is-cn, "移除地址"); + + clicked => { + ConfirmDialogSetting.set(true, "warning", Logic.tr(Store.is-cn, "警告"), Logic.tr(Store.is-cn, "是否删除地址?"), "remove-address-book-entry", entry.uuid); + } + } + } + } +} diff --git a/ui/base/avatar.slint b/ui/base/avatar.slint new file mode 100644 index 0000000..a41d1b7 --- /dev/null +++ b/ui/base/avatar.slint @@ -0,0 +1,32 @@ +import { Theme } from "../theme.slint"; + +export component Avatar inherits Rectangle { + in-out property icon <=> img.source; + in-out property icon-colorize <=> img.colorize; + in-out property icon-size-rate: 0.7; + + callback clicked <=> touch.clicked; + + width: Theme.avatar-size; + height: self.width; + border-radius: self.height / 2; + border-width: 1px; + border-color: touch.has-hover ? Theme.brand-color : Colors.transparent; + background: @radial-gradient(circle, Theme.base-background 0%, Theme.secondary-background 100%); + + animate border-color { + duration: Theme.default-animate-duration * 2; + easing: ease-in-out; + } + + img := Image { + width: root.width * icon-size-rate; + height: self.width; + image-fit: ImageFit.contain; + colorize: Theme.avatar-color; + } + + touch := TouchArea { + mouse-cursor: self.has-hover ? pointer : default; + } +} diff --git a/ui/base/banner.slint b/ui/base/banner.slint new file mode 100644 index 0000000..53912d1 --- /dev/null +++ b/ui/base/banner.slint @@ -0,0 +1,20 @@ +import { Theme } from "../theme.slint"; +import { Label } from "label.slint"; + +export component Banner inherits HorizontalLayout { + in-out property background <=> rec.background; + in-out property border-radius <=> rec.border-radius; + in-out property text <=> label.text; + in-out property font-size <=> label.font-size; + in-out property text-color <=> label.color; + + rec := Rectangle { + background: Theme.warning-color; + height: label.preferred-height + Theme.padding * 2; + + label := Label { + font-size: Theme.title4-font-size; + color: Theme.invert-base-color; + } + } +} diff --git a/ui/base/blanket.slint b/ui/base/blanket.slint new file mode 100644 index 0000000..525e069 --- /dev/null +++ b/ui/base/blanket.slint @@ -0,0 +1,12 @@ +import { Theme } from "../theme.slint"; + +export component Blanket inherits Rectangle { + opacity: 0.3; + background: Theme.is-dark ? Theme.secondary-background.brighter(50%) : Theme.invert-base-color; + + callback clicked <=> ta.clicked; + + ta := TouchArea { + mouse-cursor: MouseCursor.pointer; + } +} diff --git a/ui/base/brand.slint b/ui/base/brand.slint new file mode 100644 index 0000000..49b2d04 --- /dev/null +++ b/ui/base/brand.slint @@ -0,0 +1,6 @@ +import { Theme, Icons } from "../theme.slint"; + +export component Brand inherits Image { + width: 50%; + source: Icons.brand; +} diff --git a/ui/base/btn.slint b/ui/base/btn.slint new file mode 100644 index 0000000..a1aa639 --- /dev/null +++ b/ui/base/btn.slint @@ -0,0 +1,27 @@ +import { Theme, Icons } from "../theme.slint"; +import { IconBtn } from "./icon-btn.slint"; + +export component CancelBtn inherits IconBtn { + use-auto-size: true; + icon: Icons.cancel; + icon-width: Theme.icon-size; + border-radius: self.height / 2; + bg-color: Theme.info-color.brighter(50%); + bg-pressed-color: self.bg-color.darker(30%); + colorize: self.bg-pressed-color.darker(100%); +} + +export component ConfirmBtn inherits IconBtn { + use-auto-size: true; + icon: Icons.success; + border-radius: self.height / 2; + bg-color: Theme.success-color.darker(20%); + bg-pressed-color: self.bg-color.darker(30%); + colorize: Theme.base-color; +} + +export component TextBtn inherits IconBtn { + use-auto-size: true; + background: Colors.transparent; + colorize: Theme.secondary-brand-color; +} diff --git a/ui/base/center-layout.slint b/ui/base/center-layout.slint new file mode 100644 index 0000000..2ddcce1 --- /dev/null +++ b/ui/base/center-layout.slint @@ -0,0 +1,7 @@ +export component CenterLayout inherits HorizontalLayout { + alignment: center; + VerticalLayout { + alignment: center; + @children + } +} diff --git a/ui/base/confirm-dialog.slint b/ui/base/confirm-dialog.slint new file mode 100644 index 0000000..d2ec39d --- /dev/null +++ b/ui/base/confirm-dialog.slint @@ -0,0 +1,80 @@ +import { Dialog } from "./dialog.slint"; +import { Store } from "../store.slint"; +import { Util } from "../util.slint"; +import { Logic } from "../logic.slint"; +import { Theme, Icons } from "../theme.slint"; +import { Label } from "./label.slint"; +import { CancelBtn, TextBtn } from "./btn.slint"; + +export global ConfirmDialogSetting { + in-out property show; + out property title-type: "warning"; + out property title-text: "警告"; + out property body-text; + out property handle-type; + out property user-data; + + public function set(show: bool, title-type: string, title-text: string, body-text: string, handle-type: string, user-data: string) { + self.show = show; + self.title-type = title-type; + self.title-text = title-text; + self.body-text = body-text; + self.handle-type = handle-type; + self.user-data = user-data; + } +} + +export component ConfirmDialogDialog inherits Rectangle { + preferred-width: 200px; + height: vbox.preferred-height; + background: Theme.base-background; + border-radius: Theme.border-radius; + + in-out property is-prevent-event-forward: false; + in-out property title: ConfirmDialogSetting.title-text; + + if is-prevent-event-forward: TouchArea { } + + vbox := VerticalLayout { + alignment: start; + padding: Theme.padding * 4; + spacing: Theme.spacing * 4; + + title-label := Label { + text: root.title; + color: Theme.primary-text-color; + font-size: Theme.title1-font-size; + } + + Label { + wrap: word-wrap; + color: Theme.secondary-text-color; + font-size: Theme.title4-font-size; + text: ConfirmDialogSetting.body-text; + } + + HorizontalLayout { + alignment: end; + spacing: Theme.spacing * 4; + + TextBtn { + text: Logic.tr(Store.is-cn, "取消"); + icon: Icons.cancel; + + clicked => { + ConfirmDialogSetting.show = false; + } + } + + TextBtn { + icon: Icons.success; + text: Logic.tr(Store.is-cn, "确认"); + + clicked => { + Logic.handle-confirm-dialog(ConfirmDialogSetting.handle-type, ConfirmDialogSetting.user-data); + ConfirmDialogSetting.show = false; + } + } + } + } +} diff --git a/ui/base/def.slint b/ui/base/def.slint new file mode 100644 index 0000000..6aa9a30 --- /dev/null +++ b/ui/base/def.slint @@ -0,0 +1,11 @@ +export enum LoadingStatus { + Loading, + Fail, + Success, +} + +export enum PrioritizationFeeStatus { + Slow, + Normal, + Fast, +} diff --git a/ui/base/dialog.slint b/ui/base/dialog.slint new file mode 100644 index 0000000..6e52899 --- /dev/null +++ b/ui/base/dialog.slint @@ -0,0 +1,79 @@ +import { Theme, Icons } from "../theme.slint"; +import { Store } from "../store.slint"; +import { Logic } from "../logic.slint"; +import { IconBtn } from "./icon-btn.slint"; +import { CenterLayout } from "./center-layout.slint"; +import { CancelBtn, ConfirmBtn } from "./btn.slint"; + +export component Dialog inherits Rectangle { + in-out property title; + in-out property title-bg: Theme.secondary-brand-color; + in-out property is-hide-btns: false; + in-out property is-hide-close-btns: false; + in-out property is-prevent-event-forward: false; + + callback cancel-clicked(); + callback ok-clicked(); + + width: 800px; + height: vbox.preferred-height; + background: Theme.base-background; + border-radius: Theme.border-radius; + clip: true; + + if is-prevent-event-forward: TouchArea { } + + vbox := VerticalLayout { + alignment: space-between; + + if root.title != "": Rectangle { + height: txt.preferred-height * 1.33; + background: root.title-bg; + txt := Text { + color: Colors.white; + font-size: Theme.title3-font-size; + text: root.title; + } + + if is-hide-btns && !is-hide-close-btns: HorizontalLayout { + alignment: end; + padding-right: Theme.padding; + CenterLayout { + IconBtn { + width: Theme.icon-size; + icon: Icons.close; + colorize: txt.color; + show-icon-hover-background: false; + clicked => { + root.cancel-clicked(); + } + } + } + } + } + + VerticalLayout { + @children + } + + if !is-hide-btns: HorizontalLayout { + alignment: center; + spacing: Theme.spacing * 8; + padding: Theme.padding * 2; + + cancel-btn := CancelBtn { + text: Logic.tr(Store.is-cn, "取消"); + clicked => { + root.cancel-clicked(); + } + } + + ConfirmBtn { + text: Logic.tr(Store.is-cn, "确认"); + clicked => { + root.ok-clicked(); + } + } + } + } +} diff --git a/ui/base/divider.slint b/ui/base/divider.slint new file mode 100644 index 0000000..ff7d210 --- /dev/null +++ b/ui/base/divider.slint @@ -0,0 +1,6 @@ +import { Theme } from "../theme.slint"; + +export component Divider inherits Rectangle { + height: 1px; + background: Theme.base-border-color; +} diff --git a/ui/base/drawer.slint b/ui/base/drawer.slint new file mode 100644 index 0000000..c42fe97 --- /dev/null +++ b/ui/base/drawer.slint @@ -0,0 +1,113 @@ +import { Theme } from "../theme.slint"; +import { Blanket } from "./blanket.slint"; + +// Example: +// Rectangle { +// drawer := Drawer { +// is-show: true; +// position: DrawerPosition.Right; +// drawer-size: 300px; +// Rectangle { +// background: blue; +// } +// } +// HorizontalLayout { +// y: 0; +// height: 50px; +// spacing: 30px; +// TextBtn { +// text: "Show"; +// background: pink; +// clicked => { +// drawer.show(); +// } +// } +// TextBtn { +// text: "Hide"; +// background: pink; +// clicked => { +// drawer.hide(); +// } +// } +// } +// } + +export enum DrawerPosition { + Top, + Right, + Bottom, + Left, +} + +export component Drawer inherits Rectangle { + in-out property is-show; + in property drawer-size: 200px; + in property position: DrawerPosition.Bottom; + + public function show() { + root.is-show = true; + } + + public function hide() { + root.is-show = false; + } + + pure function drawer-x() -> length { + if (root.position == DrawerPosition.Left) { + if (root.is-show) { + return 0px; + } else { + return -root.width; + } + } else if (root.position == DrawerPosition.Right) { + if (root.is-show) { + return 0px; + } else { + return root.width; + } + } + return 0px; + } + + pure function drawer-y() -> length { + if (root.position == DrawerPosition.Top) { + if (root.is-show) { + return 0px; + } else { + return -root.height; + } + } else if (root.position == DrawerPosition.Bottom) { + if (root.is-show) { + return 0px; + } else { + return root.height; + } + } + return 0px; + } + + x: drawer-x(); + y: drawer-y(); + + animate x, y { + duration: Theme.default-animate-duration; + easing: ease-in-out; + } + + if root.is-show: Blanket { + clicked => { + root.is-show = false; + } + } + + VerticalLayout { + x: root.position == DrawerPosition.Right ? root.width - self.width : 0px; + y: root.position == DrawerPosition.Bottom ? root.height - self.height : 0px; + width: root.position == DrawerPosition.Right || root.position == DrawerPosition.Left ? drawer-size : root.width; + height: root.position == DrawerPosition.Top || root.position == DrawerPosition.Bottom ? drawer-size : root.height; + + TouchArea { + @children + } + } +} diff --git a/ui/base/elevated-btn.slint b/ui/base/elevated-btn.slint new file mode 100644 index 0000000..3e6ee7a --- /dev/null +++ b/ui/base/elevated-btn.slint @@ -0,0 +1,21 @@ +import { Theme } from "../theme.slint"; +import { IconBtn } from "icon-btn.slint"; + +export component ElevatedBtn inherits Rectangle { + width: Math.max(45px, Theme.default-font-size + 30px); + height: self.width; + border-radius: root.width / 2; + background: btn.has-hover ? Theme.secondary-background.darker(10%) : Theme.secondary-background; + drop-shadow-blur: Theme.padding; + drop-shadow-color: Theme.secondary-background-drop-shadow; + + in-out property icon <=> btn.icon; + in-out property rotation-type <=> btn.rotation-type; + + callback clicked <=> btn.clicked; + + btn := IconBtn { + icon-width: root.width * 0.65; + show-icon-hover-background: false; + } +} diff --git a/ui/base/head.slint b/ui/base/head.slint new file mode 100644 index 0000000..39b2f72 --- /dev/null +++ b/ui/base/head.slint @@ -0,0 +1,37 @@ +import { Theme, Icons } from "../theme.slint"; +import { IconBtn } from "./icon-btn.slint"; +import { Divider } from "./divider.slint"; + +export component Head inherits Rectangle { + height: Theme.header-height; + background: Theme.base-background; + + in-out property is-show-divider; + in-out property title; + in-out property icon <=> ic.icon; + in-out property icon-width <=> ic.icon-width; + in-out property hbox-alignment: LayoutAlignment.stretch; + + callback clicked <=> ic.clicked; + + hbox := HorizontalLayout { + alignment: hbox-alignment; + padding-left: Theme.padding; + padding-right: Theme.padding; + + ic := IconBtn { + icon-width: Theme.icon-size; + background: Colors.transparent; + icon: Icons.back; + text: root.title; + } + + @children + } + + if is-show-divider : Divider { + x: 0; + y: root.height - self.height; + background: Theme.base-border-color; + } +} diff --git a/ui/base/help.slint b/ui/base/help.slint new file mode 100644 index 0000000..aca3390 --- /dev/null +++ b/ui/base/help.slint @@ -0,0 +1,31 @@ +import { Theme } from "../theme.slint"; +import { Store } from "../store.slint"; +import { Logic } from "../logic.slint"; +import { SettingDetail, SettingDetailInner } from "setting-detail.slint"; +import { Label } from "label.slint"; + +export component Help inherits SettingDetail { + title: Logic.tr(Store.is-cn, "帮 助"); + in-out property <[string]> entries; + + SettingDetailInner { + for item in entries: HorizontalLayout { + spacing: Theme.spacing * 4; + + VerticalLayout { + alignment: LayoutAlignment.center; + Rectangle { + width: 10px; + height: self.width; + background: Theme.regular-text-color.brighter(50%); + border-radius: self.width / 2; + } + } + + Label { + wrap: word-wrap; + text: item; + } + } + } +} diff --git a/ui/base/icon-btn.slint b/ui/base/icon-btn.slint new file mode 100644 index 0000000..4422135 --- /dev/null +++ b/ui/base/icon-btn.slint @@ -0,0 +1,102 @@ +import { Palette } from "std-widgets.slint"; +import { Theme } from "../theme.slint"; +import { Label } from "./label.slint"; + +export enum RotationType { + Auto, + Click, + None, +} + +export component IconBtn inherits Rectangle { + in-out property icon <=> img.source; + in-out property colorize <=> img.colorize; + in-out property icon-width <=> img.width; + in-out property icon-size <=> img.width; + in-out property icon-rotation-angle <=> img.rotation-angle; + in-out property mouse-cursor <=> touch.mouse-cursor; + in-out property enabled-toucharea <=> touch.enabled; + out property has-hover <=> touch.has-hover; + + in-out property show-icon-hover-background: true; + in-out property is-ltr: true; + in-out property rotation-type: RotationType.None; + in-out property use-auto-size: false; + + in-out property text; + in-out property font-size: Theme.title4-font-size; + in-out property text-color: root.colorize; + in-out property icon-rotation-iteration-count; + + callback clicked(); + + in-out property bg-color: Colors.transparent; + in-out property bg-pressed-color: Colors.transparent; + + border-radius: Theme.border-radius; + background: touch.has-hover ? bg-color.darker(10%) : (touch.pressed ? bg-pressed-color : bg-color); + + animate background { + duration: Theme.default-animate-duration; + easing: ease-in-out; + } + + // only is a icon showing this hover color + if (text == "" && show-icon-hover-background): Rectangle { + x: img.x - Theme.spacing * 2 - (Math.max(Theme.icon-size, root.icon-width) - img.width) / 2; + width: Math.max(Theme.icon-size, root.icon-width) + Theme.spacing * 4; + height: self.width; + border-radius: self.width / 2; + background: touch.has-hover ? Palette.background : Colors.transparent; + } + + hbox := HorizontalLayout { + alignment: center; + spacing: Theme.spacing * 2; + + padding: root.use-auto-size ? Theme.padding : 0; + padding-left: root.use-auto-size ? Theme.padding * 4 : 0; + padding-right: root.use-auto-size ? Theme.padding * 4 : 0; + + if !root.is-ltr && root.text != "": Label { + color: root.text-color; + font-size: root.font-size; + text: root.text; + } + + img := Image { + width: Theme.icon-size; + colorize: Theme.icon-color; + rotation-angle: 0; + + animate rotation-angle { + duration: Theme.default-animate-duration; + easing: ease-in-out; + iteration-count: root.rotation-type == RotationType.Auto ? -1 : root.icon-rotation-iteration-count; + } + } + + if root.is-ltr && root.text != "": Label { + color: root.text-color; + font-size: root.font-size; + text: root.text; + } + } + + fs := FocusScope { } + + touch := TouchArea { + mouse-cursor: MouseCursor.pointer; + clicked => { + if (RotationType.Click == root.rotation-type) { + if (icon-rotation-angle == 0) { + icon-rotation-angle = 360deg; + } else { + icon-rotation-angle = 0deg; + } + } + fs.focus(); + root.clicked(); + } + } +} diff --git a/ui/base/icons-dialog.slint b/ui/base/icons-dialog.slint new file mode 100644 index 0000000..3049a22 --- /dev/null +++ b/ui/base/icons-dialog.slint @@ -0,0 +1,147 @@ +import { Dialog } from "./dialog.slint"; +import { Theme } from "../theme.slint"; +import { Store } from "../store.slint"; +import { Logic } from "../logic.slint"; +import { Util } from "../util.slint"; + +export global IconsDialogSetting { + in-out property show; + out property handle-type; + out property user-data; + + public function set(show: bool, handle-type: string, user-data: string) { + self.show = show; + self.handle-type = handle-type; + self.user-data = user-data; + } + + public function rand-icon-index() -> int { + return Util.rand-int(0, IconsDialogSetting.icons.length); + } + + pure public function icon(index: int) -> image { + return icons[Util.bound(0, index, icons.length - 1)]; + } + + out property <[image]> icons: [ + @image-url("./icons/1.svg"), + @image-url("./icons/2.svg"), + @image-url("./icons/3.svg"), + @image-url("./icons/4.svg"), + @image-url("./icons/5.svg"), + @image-url("./icons/6.svg"), + @image-url("./icons/7.svg"), + @image-url("./icons/8.svg"), + @image-url("./icons/9.svg"), + @image-url("./icons/10.svg"), + @image-url("./icons/11.svg"), + @image-url("./icons/12.svg"), + @image-url("./icons/13.svg"), + @image-url("./icons/14.svg"), + @image-url("./icons/15.svg"), + @image-url("./icons/16.svg"), + @image-url("./icons/17.svg"), + @image-url("./icons/18.svg"), + @image-url("./icons/19.svg"), + @image-url("./icons/20.svg"), + @image-url("./icons/21.svg"), + @image-url("./icons/22.svg"), + @image-url("./icons/23.svg"), + @image-url("./icons/24.svg"), + @image-url("./icons/25.svg"), + @image-url("./icons/26.svg"), + @image-url("./icons/27.svg"), + @image-url("./icons/28.svg"), + @image-url("./icons/29.svg"), + @image-url("./icons/30.svg"), + @image-url("./icons/31.svg"), + @image-url("./icons/32.svg"), + @image-url("./icons/33.svg"), + @image-url("./icons/34.svg"), + @image-url("./icons/35.svg"), + @image-url("./icons/36.svg"), + @image-url("./icons/37.svg"), + @image-url("./icons/38.svg"), + @image-url("./icons/39.svg"), + @image-url("./icons/40.svg"), + @image-url("./icons/41.svg"), + @image-url("./icons/42.svg"), + @image-url("./icons/43.svg"), + @image-url("./icons/44.svg"), + @image-url("./icons/45.svg"), + @image-url("./icons/46.svg"), + @image-url("./icons/47.svg"), + @image-url("./icons/48.svg"), + @image-url("./icons/49.svg"), + @image-url("./icons/50.svg"), + ]; +} + +export component IconsDialog inherits Dialog { + title: Logic.tr(Store.is-cn, "图标库"); + width: (icon-size + icon-spacing) * column-count - icon-spacing + Theme.padding * 2; + is-hide-btns: true; + + property icon-size: 60px; + property icon-spacing: Theme.spacing; + property column-count: 5; + + callback select-index(string, int, string); // (handle-type, icon-index, user-data) -> void + + flick := Flickable { + height: 300px; + viewport-height: (icon-size + icon-spacing) * Math.ceil(IconsDialogSetting.icons.length / column-count) - icon-spacing + Theme.padding * 2; + + vbox := VerticalLayout { + padding: Theme.padding; + + Rectangle { + for icon[index] in IconsDialogSetting.icons: Rectangle { + x: (icon-size + icon-spacing) * Math.mod(index, column-count); + y: (icon-size + icon-spacing) * Math.floor(index / column-count); + width: icon-size; + height: icon-size; + border-radius: Theme.border-radius; + + VerticalLayout { + alignment: center; + HorizontalLayout { + alignment: center; + Image { + width: icon-size * 0.5; + height: self.width; + colorize: Theme.regular-text-color; + source: icon; + } + } + + HorizontalLayout { + alignment: center; + Text { + text: index + 1; + font-size: Theme.default-font-size; + color: Theme.regular-text-color; + } + } + } + + touch := TouchArea { + mouse-cursor: self.has-hover ? pointer : default; + clicked => { + root.select-index(IconsDialogSetting.handle-type, index, IconsDialogSetting.user-data); + IconsDialogSetting.show = false; + } + } + } + } + } + } + + cancel-clicked => { + IconsDialogSetting.show = false; + } + + ok-clicked => { + IconsDialogSetting.show = false; + } +} diff --git a/ui/base/icons/1.svg b/ui/base/icons/1.svg new file mode 100644 index 0000000..e18efa1 --- /dev/null +++ b/ui/base/icons/1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/10.svg b/ui/base/icons/10.svg new file mode 100644 index 0000000..1de339d --- /dev/null +++ b/ui/base/icons/10.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/11.svg b/ui/base/icons/11.svg new file mode 100644 index 0000000..0398b48 --- /dev/null +++ b/ui/base/icons/11.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/12.svg b/ui/base/icons/12.svg new file mode 100644 index 0000000..0fc5e3d --- /dev/null +++ b/ui/base/icons/12.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/13.svg b/ui/base/icons/13.svg new file mode 100644 index 0000000..ba3d3a7 --- /dev/null +++ b/ui/base/icons/13.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/14.svg b/ui/base/icons/14.svg new file mode 100644 index 0000000..c05817d --- /dev/null +++ b/ui/base/icons/14.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/15.svg b/ui/base/icons/15.svg new file mode 100644 index 0000000..bfb57b9 --- /dev/null +++ b/ui/base/icons/15.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/16.svg b/ui/base/icons/16.svg new file mode 100644 index 0000000..4d33d13 --- /dev/null +++ b/ui/base/icons/16.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/17.svg b/ui/base/icons/17.svg new file mode 100644 index 0000000..524a708 --- /dev/null +++ b/ui/base/icons/17.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ui/base/icons/18.svg b/ui/base/icons/18.svg new file mode 100644 index 0000000..7fd9dc4 --- /dev/null +++ b/ui/base/icons/18.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/ui/base/icons/19.svg b/ui/base/icons/19.svg new file mode 100644 index 0000000..8716939 --- /dev/null +++ b/ui/base/icons/19.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/2.svg b/ui/base/icons/2.svg new file mode 100644 index 0000000..2e814ab --- /dev/null +++ b/ui/base/icons/2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/20.svg b/ui/base/icons/20.svg new file mode 100644 index 0000000..1f11e8b --- /dev/null +++ b/ui/base/icons/20.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/ui/base/icons/21.svg b/ui/base/icons/21.svg new file mode 100644 index 0000000..f31ce9d --- /dev/null +++ b/ui/base/icons/21.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/22.svg b/ui/base/icons/22.svg new file mode 100644 index 0000000..705514d --- /dev/null +++ b/ui/base/icons/22.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/ui/base/icons/23.svg b/ui/base/icons/23.svg new file mode 100644 index 0000000..0498bb4 --- /dev/null +++ b/ui/base/icons/23.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ui/base/icons/24.svg b/ui/base/icons/24.svg new file mode 100644 index 0000000..cb68e7a --- /dev/null +++ b/ui/base/icons/24.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ui/base/icons/25.svg b/ui/base/icons/25.svg new file mode 100644 index 0000000..c829c46 --- /dev/null +++ b/ui/base/icons/25.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ui/base/icons/26.svg b/ui/base/icons/26.svg new file mode 100644 index 0000000..fe8df7c --- /dev/null +++ b/ui/base/icons/26.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/27.svg b/ui/base/icons/27.svg new file mode 100644 index 0000000..0b0a391 --- /dev/null +++ b/ui/base/icons/27.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/28.svg b/ui/base/icons/28.svg new file mode 100644 index 0000000..3f7db98 --- /dev/null +++ b/ui/base/icons/28.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/29.svg b/ui/base/icons/29.svg new file mode 100644 index 0000000..e165ed9 --- /dev/null +++ b/ui/base/icons/29.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/3.svg b/ui/base/icons/3.svg new file mode 100644 index 0000000..f9eb63d --- /dev/null +++ b/ui/base/icons/3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/30.svg b/ui/base/icons/30.svg new file mode 100644 index 0000000..485dd76 --- /dev/null +++ b/ui/base/icons/30.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/31.svg b/ui/base/icons/31.svg new file mode 100644 index 0000000..cdbf038 --- /dev/null +++ b/ui/base/icons/31.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/32.svg b/ui/base/icons/32.svg new file mode 100644 index 0000000..b041b52 --- /dev/null +++ b/ui/base/icons/32.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/33.svg b/ui/base/icons/33.svg new file mode 100644 index 0000000..1a32b64 --- /dev/null +++ b/ui/base/icons/33.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/34.svg b/ui/base/icons/34.svg new file mode 100644 index 0000000..4319f2b --- /dev/null +++ b/ui/base/icons/34.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/35.svg b/ui/base/icons/35.svg new file mode 100644 index 0000000..187849b --- /dev/null +++ b/ui/base/icons/35.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/36.svg b/ui/base/icons/36.svg new file mode 100644 index 0000000..d81f96c --- /dev/null +++ b/ui/base/icons/36.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/37.svg b/ui/base/icons/37.svg new file mode 100644 index 0000000..e5f7e18 --- /dev/null +++ b/ui/base/icons/37.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/38.svg b/ui/base/icons/38.svg new file mode 100644 index 0000000..22db685 --- /dev/null +++ b/ui/base/icons/38.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ui/base/icons/39.svg b/ui/base/icons/39.svg new file mode 100644 index 0000000..6494b13 --- /dev/null +++ b/ui/base/icons/39.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/4.svg b/ui/base/icons/4.svg new file mode 100644 index 0000000..3fe5400 --- /dev/null +++ b/ui/base/icons/4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/40.svg b/ui/base/icons/40.svg new file mode 100644 index 0000000..bd82a80 --- /dev/null +++ b/ui/base/icons/40.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/41.svg b/ui/base/icons/41.svg new file mode 100644 index 0000000..2641060 --- /dev/null +++ b/ui/base/icons/41.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/42.svg b/ui/base/icons/42.svg new file mode 100644 index 0000000..330385d --- /dev/null +++ b/ui/base/icons/42.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/43.svg b/ui/base/icons/43.svg new file mode 100644 index 0000000..40b7861 --- /dev/null +++ b/ui/base/icons/43.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/44.svg b/ui/base/icons/44.svg new file mode 100644 index 0000000..25afca6 --- /dev/null +++ b/ui/base/icons/44.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/45.svg b/ui/base/icons/45.svg new file mode 100644 index 0000000..6771674 --- /dev/null +++ b/ui/base/icons/45.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/46.svg b/ui/base/icons/46.svg new file mode 100644 index 0000000..477a448 --- /dev/null +++ b/ui/base/icons/46.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/47.svg b/ui/base/icons/47.svg new file mode 100644 index 0000000..ad89746 --- /dev/null +++ b/ui/base/icons/47.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/48.svg b/ui/base/icons/48.svg new file mode 100644 index 0000000..68461ca --- /dev/null +++ b/ui/base/icons/48.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/ui/base/icons/49.svg b/ui/base/icons/49.svg new file mode 100644 index 0000000..c7d7dce --- /dev/null +++ b/ui/base/icons/49.svg @@ -0,0 +1 @@ + diff --git a/ui/base/icons/5.svg b/ui/base/icons/5.svg new file mode 100644 index 0000000..9959f30 --- /dev/null +++ b/ui/base/icons/5.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/50.svg b/ui/base/icons/50.svg new file mode 100644 index 0000000..16d5475 --- /dev/null +++ b/ui/base/icons/50.svg @@ -0,0 +1 @@ + diff --git a/ui/base/icons/6.svg b/ui/base/icons/6.svg new file mode 100644 index 0000000..2a60930 --- /dev/null +++ b/ui/base/icons/6.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/7.svg b/ui/base/icons/7.svg new file mode 100644 index 0000000..27455ec --- /dev/null +++ b/ui/base/icons/7.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/8.svg b/ui/base/icons/8.svg new file mode 100644 index 0000000..d8d5c3b --- /dev/null +++ b/ui/base/icons/8.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/icons/9.svg b/ui/base/icons/9.svg new file mode 100644 index 0000000..c524eed --- /dev/null +++ b/ui/base/icons/9.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/base/label.slint b/ui/base/label.slint new file mode 100644 index 0000000..1470183 --- /dev/null +++ b/ui/base/label.slint @@ -0,0 +1,7 @@ +import { Theme } from "../theme.slint"; + +export component Label inherits Text { + vertical-alignment: center; + color: Theme.primary-text-color; + font-size: Theme.default-font-size; +} diff --git a/ui/base/landing-page.slint b/ui/base/landing-page.slint new file mode 100644 index 0000000..13c1d3f --- /dev/null +++ b/ui/base/landing-page.slint @@ -0,0 +1,152 @@ +import { Theme, Icons } from "../theme.slint"; +import { Logic } from "../logic.slint"; +import { Store} from "../store.slint"; +import { TextBtn } from "./btn.slint"; +import { CenterLayout } from "center-layout.slint"; +import { Label} from "label.slint"; +import { RadioBtn } from "./radio-btn.slint"; + +export struct LandingDetail { + picture: image, + description: string, +} + +component LangPage inherits Rectangle { + in property root-width: 100px; + in property root-height: 100px; + + HorizontalLayout { + height: root.height; + alignment: LayoutAlignment.center; + + VerticalLayout { + vertical-stretch: 1; + alignment: LayoutAlignment.center; + spacing: Theme.spacing * 5; + + Image { + width: min(root-height, root-width) * 0.5; + height: self.width; + source: Icons.landing-language-switch; + } + + Label { + text: Logic.tr(Store.is-cn, "请选择语言"); + font-size: Theme.title3-font-size; + color: Theme.secondary-brand-color; + } + + RadioBtn { + text: "中文"; + checked: Store.setting-ui.language == "cn"; + check => { + Store.setting-ui.language = "cn"; + Logic.set-setting-ui(Store.setting-ui); + } + } + + RadioBtn { + text: "English"; + checked: Store.setting-ui.language == "en"; + check => { + Store.setting-ui.language = "en"; + Logic.set-setting-ui(Store.setting-ui); + } + } + } + } +} + +component DetailsPage inherits Rectangle { + in property root-width: 100px; + in property root-height: 100px; + in property <[LandingDetail]> details; + in property current-index: 0; + + for detail[index] in details: Rectangle { + if current-index == index: VerticalLayout { + vertical-stretch: 1; + alignment: LayoutAlignment.center; + spacing: Theme.spacing * 5; + + Rectangle { + Image { + width: min(root-height, root-width) * 0.8; + height: self.width; + source: detail.picture; + } + } + + Label { + horizontal-stretch: 1; + horizontal-alignment: TextHorizontalAlignment.center; + color: Theme.secondary-brand-color; + text: detail.description; + wrap: TextWrap.word-wrap; + } + } + } +} + +export component LandingPage inherits Rectangle { + background: Theme.base-background; + + callback skipped <=> skip-btn.clicked; + + private property current-index: -1; + in property <[LandingDetail]> details; + + VerticalLayout { + padding: Theme.padding * 5; + padding-left: Theme.padding * 2; + padding-right: Theme.padding * 2; + spacing: Theme.spacing * 2; + + HorizontalLayout { + alignment: LayoutAlignment.end; + skip-btn := TextBtn { + text: Logic.tr(Store.is-cn, "跳过"); + colorize: Theme.have-read-text-color; + font-size: Theme.default-font-size - 2px; + } + } + + if current-index < 0: LangPage { + root-width: root.width; + root-height: root.height; + } + + if current-index >= 0: DetailsPage { + root-width: root.width; + root-height: root.height; + details: details; + current-index: current-index; + } + + HorizontalLayout { + alignment: current-index == -1 ? LayoutAlignment.end : LayoutAlignment.space-between; + + if current-index > -1: TextBtn { + text: Logic.tr(Store.is-cn, "返回"); + colorize: Theme.have-read-text-color; + font-size: Theme.default-font-size - 2px; + clicked => { + current-index -= 1; + } + } + + TextBtn { + font-size: Theme.default-font-size - 2px; + text: Logic.tr(Store.is-cn, + details.length == current-index + 1 ? "完成" : "下一步"); + clicked => { + current-index += 1; + + if (details.length == current-index) { + root.skipped(); + } + } + } + } + } +} diff --git a/ui/base/language-dialog.slint b/ui/base/language-dialog.slint new file mode 100644 index 0000000..c0bf541 --- /dev/null +++ b/ui/base/language-dialog.slint @@ -0,0 +1,49 @@ +import { Theme } from "../theme.slint"; +import { Store } from "../store.slint"; +import { Logic } from "../logic.slint"; +import { Dialog } from "./dialog.slint"; +import { ConfirmBtn } from "./btn.slint"; +import { RadioBtn } from "./radio-btn.slint"; + +export component LanguageDialog inherits Dialog { + title: Logic.tr(Store.is-cn, "请选择语言"); + is-hide-btns: true; + + in-out property language: "cn"; + + VerticalLayout { + padding: Theme.padding * 4; + spacing: Theme.spacing * 4; + + VerticalLayout { + alignment: center; + spacing: Theme.spacing * 4; + + cn-radio := RadioBtn { + text: "中文"; + checked: root.language == "cn"; + check => { root.language = "cn"; } + } + + en-radio := RadioBtn { + text: "English"; + checked: root.language == "en"; + check => { root.language = "en"; } + } + } + + HorizontalLayout { + alignment: end; + + ConfirmBtn { + text: Logic.tr(Store.is-cn, "确认"); + clicked => { + Store.setting-ui.language = root.language; + Logic.set-setting-ui(Store.setting-ui); + Store.is-first-run = false; + } + } + } + } + +} diff --git a/ui/base/line-input.slint b/ui/base/line-input.slint new file mode 100644 index 0000000..59f39fe --- /dev/null +++ b/ui/base/line-input.slint @@ -0,0 +1,79 @@ +import { Palette } from "std-widgets.slint"; +import { Theme } from "../theme.slint"; +import { Label } from "./label.slint"; +import { IconBtn } from "./icon-btn.slint"; + +export component LineInput inherits Rectangle { + in-out property text <=> text-input.text; + in property input-type <=> text-input.input-type; + + in property icon; + in property placeholder-text; + in property enabled <=> text-input.enabled; + in property is-show-icon: true; + + callback clicked <=> icon.clicked; + callback edited <=> text-input.edited; + callback accepted <=> text-input.accepted; + + width: 100px; + forward-focus: text-input; + border-radius: Theme.border-radius; + border-width: text-input.has-focus ? 2px : 1px; + border-color: text-input.has-focus ? Palette.accent-background : Palette.border; + + public function paste() { + text-input.paste(); + } + + public function copy() { + text-input.copy(); + } + + HorizontalLayout { + spacing: Theme.spacing * 2; + padding-top: Theme.padding * 3; + padding-bottom: Theme.padding * 3; + padding-left: Theme.padding * 4; + padding-right: Theme.padding * 3; + alignment: LayoutAlignment.space-between; + + Flickable { + viewport-width: text-input.preferred-width + Theme.padding; + width: root.width - (is-show-icon ? icon.width : 0) - parent.padding-left - parent.padding-right - (is-show-icon ? parent.spacing * 2 : 0); + + Rectangle { + x: 0; + width: Math.max(parent.width, text-input.preferred-width); + + text-input := TextInput { + single-line: true; + vertical-alignment: TextVerticalAlignment.center; + } + + if text-input.text == "": Label { + x: 0; + text: root.placeholder-text; + color: Theme.placeholder-text-color; + } + + ta := TouchArea { + enabled: text-input.text == ""; + mouse-cursor: MouseCursor.text; + + clicked => { + text-input.focus(); + } + } + } + } + + icon := IconBtn { + visible: root.is-show-icon; + width: text-input.height; + height: Theme.icon-size; + icon: root.icon; + icon-width: Theme.icon-size; + } + } +} diff --git a/ui/base/link.slint b/ui/base/link.slint new file mode 100644 index 0000000..13d96b7 --- /dev/null +++ b/ui/base/link.slint @@ -0,0 +1,16 @@ +import { Theme } from "../theme.slint"; + +export component Link inherits Text { + in-out property is-read; + + callback clicked <=> touch.clicked; + out property has-hover <=> touch.has-hover; + + wrap: word-wrap; + font-size: Theme.title5-font-size; + color: root.is-read ? Theme.have-read-text-color : Theme.link-text-color; + + touch := TouchArea { + mouse-cursor: MouseCursor.pointer; + } +} diff --git a/ui/base/list-tile.slint b/ui/base/list-tile.slint new file mode 100644 index 0000000..32866d7 --- /dev/null +++ b/ui/base/list-tile.slint @@ -0,0 +1,159 @@ +import { Theme, Icons } from "../theme.slint"; +import { IconBtn } from "./icon-btn.slint"; +import { Label } from "./label.slint"; + +// Example: +// VerticalLayout { +// alignment: LayoutAlignment.center; + +// ListTile { +// height: item-height; +// background: Theme.secondary-background; +// border-radius: Theme.border-radius; +// is-show-left-icon: true; +// left-icon-size: item-height / 2; +// left-icon-background: Theme.secondary-brand-color; +// left-icon: Icons.Home; +// left-icon-is-avatar: true; + +// title-text: item.name; +// subtitle-text: "$" + item.balance; +// middle-mouse-cursor: MouseCursor.pointer; + +// is-show-right-icon: true; +// right-icon: Icons.delete; +// } +// } + +export component ListTile inherits Rectangle { + height: vbox.preferred-height; + background: Theme.base-background; + + callback left-clicked(); + callback right-clicked(); + callback middle-clicked(); + + out property has-hover: middle-area.has-hover || ta.has-hover; + + in property is-show-left-icon; + in property left-icon-is-avatar; + in property left-icon; + in property left-icon-size: Theme.icon-size; + in property left-icon-colorize; + in property left-icon-background; + in property left-icon-hover-background; + in property left-icon-border-radius: Theme.border-radius; + in property left-icon-border-width; + in property left-icon-border-color; + + in property middle-background; + in property middle-hover-background; + in property middle-text-wrap: TextWrap.no-wrap; + in property middle-text-overflow: TextOverflow.elide; + + in property is-show-right-icon; + in property right-icon-size: Theme.icon-size; + in property right-colorize: Theme.icon-color; + in property right-icon; + + in property title-text; + in property title-font-size: Theme.title3-font-size; + + in property subtitle-text; + in property subtitle-font-size: Theme.default-font-size; + + in property middle-mouse-cursor <=> middle-area.mouse-cursor; + + private property horizontal-alignment: is-show-right-icon ? LayoutAlignment.space-between : is-show-left-icon ? LayoutAlignment.start : LayoutAlignment.stretch; + + ta := TouchArea { + mouse-cursor: middle-area.mouse-cursor; + clicked => { + middle-clicked(); + } + } + + hbox := HorizontalLayout { + padding: Theme.padding; + spacing: Theme.spacing * 2; + alignment: root.horizontal-alignment; + + HorizontalLayout { + horizontal-stretch: 1; + spacing: Theme.spacing * 2; + + if is-show-left-icon: VerticalLayout { + alignment: LayoutAlignment.center; + Rectangle { + width: root.left-icon-size + Theme.padding * 4; + height: self.width; + border-width: left-icon-border-width; + border-color: left-icon-border-color; + border-radius: left-icon-is-avatar ? self.width / 2 : left-icon-border-radius; + background: img-area.has-hover ? root.left-icon-hover-background : root.left-icon-background; + + img := Image { + height: root.left-icon-size; + width: self.height; + source: root.left-icon; + colorize: root.left-icon-colorize; + } + + img-area := TouchArea { + mouse-cursor: MouseCursor.pointer; + clicked => { + root.left-clicked(); + } + } + } + } + + Rectangle { + clip: true; + border-radius: Theme.border-radius; + background: middle-area.has-hover ? root.middle-hover-background : root.middle-background; + + middle-area := TouchArea { + clicked => { + root.middle-clicked(); + } + } + + vbox := VerticalLayout { + alignment: LayoutAlignment.start; + spacing: Theme.spacing * 2; + padding: Theme.padding * 2; + + if root.title-text != "": Label { + font-size: root.title-font-size; + text: root.title-text; + wrap: root.middle-text-wrap; + overflow: root.middle-text-overflow; + font-weight: 0.5; + } + + if root.subtitle-text != "": Label { + font-size: root.subtitle-font-size; + text: root.subtitle-text; + overflow: root.middle-text-overflow; + wrap: root.middle-text-wrap; + } + } + } + } + + if is-show-right-icon: Rectangle { + width: root.right-icon-size + Theme.padding * 4; + + IconBtn { + icon-size: root.right-icon-size; + icon: root.right-icon; + colorize: root.right-colorize; + + clicked => { + root.right-clicked(); + } + } + } + } +} diff --git a/ui/base/loading.slint b/ui/base/loading.slint new file mode 100644 index 0000000..bd511f4 --- /dev/null +++ b/ui/base/loading.slint @@ -0,0 +1,53 @@ +import { Theme, Icons } from "../theme.slint"; +import { Label } from "./label.slint"; +import { Logic } from "../logic.slint"; + +export component Loading inherits Rectangle { + in property loading-text: "Loading..."; + in property duration: 0.5s; + in property loading-icon: Icons.loading; + in property icon-size: Theme.icon-size; + in property colorize: Theme.primary-text-color; + in property font-size: Theme.default-font-size; + in property gap: Theme.spacing * 2; + in property is-show-animation: true; + + public function close() { + self.visible = false; + } + + public function open() { + self.visible = true; + } + + if root.visible: VerticalLayout { + alignment: center; + spacing: root.gap; + Rectangle { + height: icon.height; + width: parent.width; + icon := Image { + height: root.icon-size; + width: self.height; + rotation-angle: !root.is-show-animation ? 0deg : 240deg * animation-tick() / root.duration; + source: root.loading-icon; + colorize: root.colorize; + animate rotation-angle { + easing: ease-in-out; + iteration-count: -1; + } + } + } + + HorizontalLayout { + alignment: LayoutAlignment.center; + Label { + text: root.loading-text; + font-size: root.font-size; + color: root.colorize; + } + } + } + + TouchArea { } +} diff --git a/ui/base/login.slint b/ui/base/login.slint new file mode 100644 index 0000000..88144f5 --- /dev/null +++ b/ui/base/login.slint @@ -0,0 +1,124 @@ +import { Palette } from "std-widgets.slint"; +import { Theme, Icons } from "../theme.slint"; +import { Logic } from "../logic.slint"; +import { Store } from "../store.slint"; +import { IconBtn } from "./icon-btn.slint"; +import { Label } from "./label.slint"; +import { Head } from "./head.slint"; +import { LineInput } from "./line-input.slint"; +import { CancelBtn, ConfirmBtn } from "./btn.slint"; +import { SettingDetailInner, SettingDetailInnerVbox, SettingDetailLabel } from "./setting-detail.slint"; + +export component Login inherits Rectangle { + in property is-show-header: true; + + private property error-message; + + callback back(); + callback cancel(); + + // (username, password) -> string + callback confirm(string, string) -> string; + + public function reset() { + error-message = ""; + username-lineedit.text = ""; + password-lineedit.text = ""; + } + + forward-focus: username-lineedit; + + vbox := VerticalLayout { + if is-show-header: Head { + title: Logic.tr(Store.is-cn, "返回"); + hbox-alignment: LayoutAlignment.start; + clicked => { + root.back(); + } + } + + SettingDetailInner { + vbox-alignment: LayoutAlignment.center; + + SettingDetailInnerVbox { + username-txt := SettingDetailLabel { + text: Logic.tr(Store.is-cn, "请输入用户名"); + } + + HorizontalLayout { + spacing: Theme.spacing; + + username-lineedit := LineInput { + icon: Icons.paste; + width: root.width - Theme.padding * 4; + placeholder-text: Logic.tr(Store.is-cn, "用户名"); + + edited => { + root.error-message = ""; + } + + clicked => { + username-lineedit.text = ""; + username-lineedit.paste(); + } + } + } + } + + SettingDetailInnerVbox { + private property is-show-password; + + password-txt := SettingDetailLabel { + text: Logic.tr(Store.is-cn, "请输入密码"); + } + + password-lineedit := LineInput { + icon: parent.is-show-password ? Icons.eye : Icons.close-eye; + width: root.width - Theme.padding * 4; + placeholder-text: Logic.tr(Store.is-cn, "至少8个字符"); + input-type: is-show-password ? InputType.text : InputType.password; + + edited => { + root.error-message = ""; + } + + accepted => { + confirm-btn.clicked(); + } + + clicked => { + parent.is-show-password = !parent.is-show-password; + } + } + } + + if root.error-message != "": SettingDetailInnerVbox { + SettingDetailLabel { + color: Theme.danger-color; + text: root.error-message; + } + } + + HorizontalLayout { + spacing: Theme.spacing * 10; + padding: Theme.padding * 5; + + CancelBtn { + text: Logic.tr(Store.is-cn, "取消"); + clicked => { + root.reset(); + root.cancel(); + } + } + + confirm-btn := ConfirmBtn { + text: Logic.tr(Store.is-cn, "确认"); + + clicked => { + root.error-message = root.confirm(username-lineedit.text, password-lineedit.text); + } + } + } + } + } +} diff --git a/ui/base/mnemonic.slint b/ui/base/mnemonic.slint new file mode 100644 index 0000000..13b43a2 --- /dev/null +++ b/ui/base/mnemonic.slint @@ -0,0 +1,220 @@ +import { LineEdit } from "std-widgets.slint"; +import { Theme, Icons } from "../theme.slint"; +import { Store } from "../store.slint"; +import { Logic } from "../logic.slint"; +import { Util } from "../util.slint"; +import { IconBtn } from "icon-btn.slint"; +import { CancelBtn, ConfirmBtn, TextBtn } from "btn.slint"; +import { Label } from "label.slint"; +import { Head } from "head.slint"; + +export component Mnemonic inherits Rectangle { + in-out property <[string]> mnemonics; + in property is-read-only; + in property is-show-btns; + in property is-show-header; + in property is-show-refresh-btn; + in property is-show-switch-mnemonic-counts-btn; + in property header-title; + + private property cell-pre-row: 2; + private property label-width: 20px; + private property max-blocks: mnemonics.length == 24 ? 2 : (mnemonics.length == 12 ? 1 : 0); + + out property is-mnemonic-counts-12: max-blocks != 2; + private property switch-mnemonic-counts-btn-text: (is-mnemonic-counts-12 ? "24" : "12") + Logic.tr(Store.is-cn, "位组记词"); + + callback back(); + callback copy([string]); + callback paste(); + callback refresh(int); + callback cancel(); + callback confirm(); + callback switch-mnemonic-counts(int); + + public function reset-mnemonics(counts: int) { + if (counts == 12) { + mnemonics = [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + ]; + } else if (counts == 24) { + mnemonics = [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + ]; + } else { + mnemonics = []; + } + } + + init => { + if root.mnemonics.length == 0 { + root.reset-mnemonics(12); + } + } + + VerticalLayout { + if is-show-header: Head { + title: Logic.tr(Store.is-cn, root.header-title); + hbox-alignment: LayoutAlignment.start; + clicked => { + root.back(); + } + } + + Flickable { + VerticalLayout { + padding: Theme.padding * 5; + spacing: Theme.spacing * 2; + alignment: LayoutAlignment.center; + + HorizontalLayout { + alignment: LayoutAlignment.end; + spacing: Theme.padding * 4; + + if is-show-refresh-btn: IconBtn { + icon: Icons.refresh; + + clicked => { + refresh(is-mnemonic-counts-12 ? 12 : 24); + } + } + + if is-read-only: IconBtn { + icon: Icons.copy; + clicked => { + copy(mnemonics); + } + } + + if !is-read-only: IconBtn { + icon: Icons.paste; + clicked => { + paste(); + } + } + } + + for block-index in max-blocks: VerticalLayout { + private property block-start-index: 12 * block-index; + + VerticalLayout { + spacing: Theme.spacing * 2; + + for index in 6: HorizontalLayout { + spacing: Theme.spacing * 5; + + private property cell-start-index: index * cell-pre-row + block-start-index; + + HorizontalLayout { + spacing: Theme.spacing; + horizontal-stretch: 1; + + Label { + width: label-width; + text: cell-start-index + 1; + horizontal-alignment: TextHorizontalAlignment.right; + } + + LineEdit { + horizontal-stretch: 1; + read-only: is-read-only; + text: mnemonics[cell-start-index]; + + edited => { + mnemonics[cell-start-index] = self.text; + } + } + } + + HorizontalLayout { + horizontal-stretch: 1; + spacing: Theme.spacing; + + Label { + width: label-width; + text: cell-start-index + 2; + horizontal-alignment: TextHorizontalAlignment.right; + } + + LineEdit { + horizontal-stretch: 1; + read-only: is-read-only; + text: mnemonics[cell-start-index + 1]; + + edited => { + mnemonics[cell-start-index + 1] = self.text; + } + } + } + } + } + } + + if is-show-switch-mnemonic-counts-btn: TextBtn { + icon: Icons.switch; + text: switch-mnemonic-counts-btn-text; + clicked => { + if (is-read-only) { + switch-mnemonic-counts(is-mnemonic-counts-12 ? 24 : 12); + } else { + reset-mnemonics(is-mnemonic-counts-12 ? 24 : 12); + } + } + } + + if is-show-btns: HorizontalLayout { + padding: Theme.padding * 5; + spacing: Theme.spacing * 10; + + CancelBtn { + text: Logic.tr(Store.is-cn, "取消"); + clicked => { + root.cancel(); + } + } + + ConfirmBtn { + text: Logic.tr(Store.is-cn, "确认"); + clicked => { + root.confirm(); + } + } + } + } + } + } +} diff --git a/ui/base/news.slint b/ui/base/news.slint new file mode 100644 index 0000000..d02314d --- /dev/null +++ b/ui/base/news.slint @@ -0,0 +1,58 @@ +import { Theme } from "../theme.slint"; +import { Link } from "./link.slint"; + +export component News inherits Rectangle { + height: vbox.preferred-height; + + callback link-clicked(); + + in property link-text; + in property pub-date; + in property summary; + in property author; + in property is-read; + + background: Theme.base-background; + border-radius: Theme.border-radius; + drop-shadow-blur: Theme.padding * 2; + drop-shadow-color: Theme.base-background-drop-shadow; + + vbox := VerticalLayout { + padding: Theme.padding * 2; + spacing: Theme.spacing * 2; + alignment: start; + + link := Link { + is-read: root.is-read; + text: root.link-text; + + clicked => { + root.link-clicked(); + } + } + + Text { + font-size: Theme.default-font-size - 1px; + color: root.is-read ? Theme.have-read-text-color : Theme.regular-text-color; + text: root.summary; + wrap: word-wrap; + } + + HorizontalLayout { + alignment: end; + spacing: Theme.padding * 4; + + if root.author != "": Text { + font-size: Theme.default-font-size - 4px; + color: Theme.placeholder-text-color; + text: root.author; + } + + if pub-date != "": Text { + font-size: Theme.default-font-size - 4px; + color: Theme.placeholder-text-color; + text: root.pub-date; + } + } + } +} diff --git a/ui/base/no-data.slint b/ui/base/no-data.slint new file mode 100644 index 0000000..51153c7 --- /dev/null +++ b/ui/base/no-data.slint @@ -0,0 +1,28 @@ +import { Theme, Icons } from "../theme.slint"; +import { CenterLayout } from "./center-layout.slint"; + +export component NoDataImg inherits Rectangle { + in-out property img-width <=> img.width; + in-out property text <=> txt.text; + + width: 300px; + opacity: 0.5; + + CenterLayout { + CenterLayout { + img := Image { + width: root.width * 0.6; + source: Icons.no-data; + } + } + + CenterLayout { + txt := Text { + opacity: 0.5; + color: Theme.regular-text-color; + font-size: Theme.default-font-size + 4px; + } + } + } + +} diff --git a/ui/base/no-message.slint b/ui/base/no-message.slint new file mode 100644 index 0000000..3fe46a8 --- /dev/null +++ b/ui/base/no-message.slint @@ -0,0 +1,28 @@ +import { Theme, Icons } from "../theme.slint"; +import { CenterLayout } from "./center-layout.slint"; + +export component NoMessageImg inherits Rectangle { + in-out property img-width <=> img.width; + in-out property text <=> txt.text; + width: 300px; + + opacity: 0.5; + + CenterLayout { + CenterLayout { + img := Image { + width: root.width * 0.6; + source: Icons.no-message; + } + } + + CenterLayout { + txt := Text { + opacity: 0.5; + color: Theme.regular-text-color; + font-size: Theme.default-font-size + 4px; + } + } + } + +} diff --git a/ui/base/password.slint b/ui/base/password.slint new file mode 100644 index 0000000..1995858 --- /dev/null +++ b/ui/base/password.slint @@ -0,0 +1,111 @@ +import { Palette } from "std-widgets.slint"; +import { Theme, Icons } from "../theme.slint"; +import { Logic } from "../logic.slint"; +import { Store } from "../store.slint"; +import { IconBtn } from "./icon-btn.slint"; +import { Label } from "./label.slint"; +import { Head } from "./head.slint"; +import { LineInput } from "./line-input.slint"; +import { CancelBtn, ConfirmBtn } from "./btn.slint"; +import { SettingDetailInner, SettingDetailInnerVbox, SettingDetailLabel } from "./setting-detail.slint"; + +export global PasswordSetting { + in-out property show; + out property handle-type; + out property user-data; + + public function set(show: bool, handle-type: string, user-data: string) { + self.show = show; + self.handle-type = handle-type; + self.user-data = user-data; + } +} + +export component Password inherits Rectangle { + in property is-show-header: true; + in property confirm-btn-text <=> confirm-btn.text; + private property error-message; + + callback back(); + callback cancel(); + + // (handle-type, password, user-data) -> string + callback confirm(string, string, string) -> string; + + forward-focus: password-lineedit; + background: Theme.base-background; + + public function reset() { + error-message = ""; + password-lineedit.text = ""; + } + + vbox := VerticalLayout { + if is-show-header: Head { + title: Logic.tr(Store.is-cn, "返回"); + hbox-alignment: LayoutAlignment.start; + clicked => { + root.back(); + } + } + + SettingDetailInner { + vbox-alignment: LayoutAlignment.center; + + SettingDetailInnerVbox { + private property is-show-password; + + password-txt := SettingDetailLabel { + text: Logic.tr(Store.is-cn, "请输入密码"); + } + + password-lineedit := LineInput { + icon: parent.is-show-password ? Icons.eye : Icons.close-eye; + width: root.width - Theme.padding * 4; + placeholder-text: Logic.tr(Store.is-cn, "至少8个字符"); + input-type: is-show-password ? InputType.text : InputType.password; + + edited => { + root.error-message = ""; + } + + accepted => { + confirm-btn.clicked(); + } + + clicked => { + parent.is-show-password = !parent.is-show-password; + } + } + } + + if root.error-message != "": SettingDetailInnerVbox { + SettingDetailLabel { + color: Theme.danger-color; + text: root.error-message; + } + } + + HorizontalLayout { + spacing: Theme.spacing * 10; + padding: Theme.padding * 5; + + CancelBtn { + text: Logic.tr(Store.is-cn, "取消"); + clicked => { + root.reset(); + root.cancel(); + } + } + + confirm-btn := ConfirmBtn { + text: Logic.tr(Store.is-cn, "确认"); + + clicked => { + root.error-message = root.confirm(PasswordSetting.handle-type, password-lineedit.text, PasswordSetting.user-data); + } + } + } + } + } +} diff --git a/ui/base/radio-btn.slint b/ui/base/radio-btn.slint new file mode 100644 index 0000000..80a66b5 --- /dev/null +++ b/ui/base/radio-btn.slint @@ -0,0 +1,59 @@ +import { Theme } from "../theme.slint"; +import { Label } from "./label.slint"; +import { Palette } from "std-widgets.slint"; + +export component RadioBtn inherits Rectangle { + in-out property text <=> txt.text; + in-out property enabled <=> ta.enabled; + in-out property checked; + + width: hbox.preferred-width; + height: hbox.preferred-height; + + callback check(); + + Rectangle { + x: hbox.x - (self.width - inner.width) / 2; + width: inner.width + Theme.spacing * 4; + height: self.width; + border-radius: self.width / 2; + background: ta.has-hover ? Palette.background : Colors.transparent; + } + + hbox := HorizontalLayout { + spacing: Theme.spacing * 4; + alignment: start; + + VerticalLayout { + alignment: center; + inner := Rectangle { + width: Theme.default-font-size * 1.1; + height: self.width; + border-width: 2px; + border-radius: self.width / 2; + border-color: root.checked ? Palette.accent-background : Theme.secondary-text-color; + + if root.checked: Rectangle { + width: 60%; + height: self.width; + background: parent.border-color; + border-radius: self.width / 2; + } + } + } + + VerticalLayout { + alignment: center; + txt := Label { } + } + } + + ta := TouchArea { + mouse-cursor: MouseCursor.pointer; + clicked => { + if (!root.checked) { + root.check(); + } + } + } +} diff --git a/ui/base/reset-password.slint b/ui/base/reset-password.slint new file mode 100644 index 0000000..19bb4c1 --- /dev/null +++ b/ui/base/reset-password.slint @@ -0,0 +1,152 @@ +import { Theme, Icons } from "../theme.slint"; +import { Logic } from "../logic.slint"; +import { Store } from "../store.slint"; +import { IconBtn } from "./icon-btn.slint"; +import { Label } from "./label.slint"; +import { Head } from "./head.slint"; +import { CancelBtn, ConfirmBtn } from "./btn.slint"; +import { LineInput } from "line-input.slint"; +import { SettingDetailInner, SettingDetailInnerVbox, SettingDetailLabel } from "./setting-detail.slint"; + +export component ResetPassword inherits Rectangle { + in property is-show-header: true; + + private property error-message; + + callback cancel(); + callback back(); + + //(old-password, new-password-first, new-password-second) -> error-message + callback confirm(string, string, string) -> string; + + public function reset() { + error-message = ""; + password-first-lineedit.text = ""; + password-second-lineedit.text = ""; + } + + forward-focus: password-old-lineedit; + + vbox := VerticalLayout { + if is-show-header: Head { + title: Logic.tr(Store.is-cn, "返回"); + hbox-alignment: LayoutAlignment.start; + clicked => { + root.back(); + } + } + + SettingDetailInner { + vbox-alignment: LayoutAlignment.center; + + SettingDetailInnerVbox { + password-old-txt := SettingDetailLabel { + text: Logic.tr(Store.is-cn, "请输入旧密码"); + } + + HorizontalLayout { + spacing: Theme.spacing; + + private property is-show-password; + + password-old-lineedit := LineInput { + width: root.width - Theme.padding * 4; + placeholder-text: Logic.tr(Store.is-cn, "至少8个字符"); + icon: parent.is-show-password ? Icons.eye : Icons.close-eye; + input-type: parent.is-show-password ? InputType.text : InputType.password; + + edited => { + root.error-message = ""; + } + + clicked => { + parent.is-show-password = !parent.is-show-password; + } + } + } + } + + SettingDetailInnerVbox { + password-first-txt := SettingDetailLabel { + text: Logic.tr(Store.is-cn, "请输入新密码"); + } + + HorizontalLayout { + spacing: Theme.spacing; + + private property is-show-password; + + password-first-lineedit := LineInput { + width: root.width - Theme.padding * 4; + placeholder-text: Logic.tr(Store.is-cn, "至少8个字符"); + icon: parent.is-show-password ? Icons.eye : Icons.close-eye; + input-type: parent.is-show-password ? InputType.text : InputType.password; + + edited => { + root.error-message = ""; + } + + clicked => { + parent.is-show-password = !parent.is-show-password; + } + } + } + } + + SettingDetailInnerVbox { + password-second-txt := SettingDetailLabel { + text: Logic.tr(Store.is-cn, "请再次输入新密码"); + } + + HorizontalLayout { + spacing: Theme.spacing; + + private property is-show-password; + + password-second-lineedit := LineInput { + width: root.width - Theme.padding * 4; + placeholder-text: Logic.tr(Store.is-cn, "至少8个字符"); + icon: parent.is-show-password ? Icons.eye : Icons.close-eye; + input-type: is-show-password ? InputType.text : InputType.password; + + edited => { + root.error-message = ""; + } + + clicked => { + parent.is-show-password = !parent.is-show-password; + } + } + } + } + + if root.error-message != "": SettingDetailInnerVbox { + SettingDetailLabel { + color: Theme.danger-color; + text: root.error-message; + } + } + + HorizontalLayout { + spacing: Theme.spacing * 10; + padding: Theme.padding * 5; + + CancelBtn { + text: Logic.tr(Store.is-cn, "取消"); + clicked => { + root.reset(); + root.cancel(); + } + } + + ConfirmBtn { + text: Logic.tr(Store.is-cn, "确认"); + + clicked => { + root.error-message = root.confirm(password-old-lineedit.text, password-first-lineedit.text, password-second-lineedit.text); + } + } + } + } + } +} diff --git a/ui/base/setting-detail.slint b/ui/base/setting-detail.slint new file mode 100644 index 0000000..aa90659 --- /dev/null +++ b/ui/base/setting-detail.slint @@ -0,0 +1,80 @@ +import { Switch } from "std-widgets.slint"; +import { Theme, Icons } from "../theme.slint"; +import { IconBtn } from "./icon-btn.slint"; +import { Label } from "./label.slint"; +import { Head } from "./head.slint"; + +export component SettingDetail inherits Rectangle { + callback back; + + in-out property title; + in-out property is-show-header: true; + in-out property is-show-divider; + + VerticalLayout { + if is-show-header: Head { + title: root.title; + is-show-divider: root.is-show-divider; + hbox-alignment: LayoutAlignment.start; + clicked => { + root.back(); + } + } + + @children + } +} + +export component SettingDetailInner inherits Flickable { + in-out property vbox-alignment: LayoutAlignment.start; + in-out property vbox-padding <=> vbox.padding; + in-out property vbox-spacing <=> vbox.spacing; + + vbox := VerticalLayout { + alignment: root.vbox-alignment; + padding: Theme.padding * 2; + spacing: Theme.spacing * 4; + + @children + } +} + +export component SettingDetailInnerVbox inherits VerticalLayout { + spacing: Theme.spacing; + @children +} + +export component SettingDetailLabel inherits Label { + font-size: Theme.title4-font-size; +} + +export component SettingDetailSwitch inherits Rectangle { + in-out property text <=> sib.text; + in-out property font-size <=> sib.font-size; + in-out property icon <=> sib.icon; + in-out property icon-colorize <=> sib.colorize; + in-out property icon-width <=> sib.icon-width; + in-out property enabled <=> eib.enabled; + in-out property checked <=> eib.checked; + + height: vbox.preferred-height; + background: Theme.secondary-background; + border-radius: Theme.border-radius; + + callback toggle <=> eib.toggled; + + ta := TouchArea { + mouse-cursor: root.enabled ? MouseCursor.pointer : MouseCursor.none; + } + + vbox := HorizontalLayout { + padding: Theme.padding * 2; + alignment: space-between; + + sib := IconBtn { + background: Colors.transparent; + } + + eib := Switch { } + } +} diff --git a/ui/base/setting-entry.slint b/ui/base/setting-entry.slint new file mode 100644 index 0000000..572daa2 --- /dev/null +++ b/ui/base/setting-entry.slint @@ -0,0 +1,38 @@ +import { Theme, Icons } from "../theme.slint"; +import { IconBtn } from "./icon-btn.slint"; +import { Label } from "./label.slint"; + +export component SettingEntry inherits Rectangle { + in-out property text <=> sib.text; + in-out property font-size <=> sib.font-size; + in-out property icon <=> sib.icon; + in-out property icon-colorize <=> sib.colorize; + in-out property icon-width <=> sib.icon-width; + in-out property attach-text <=> eib.text; + + background: Theme.secondary-background; + border-radius: Theme.border-radius; + + callback clicked <=> ta.clicked; + + HorizontalLayout { + padding: Theme.padding * 2; + alignment: space-between; + + sib := IconBtn { + background: Colors.transparent; + } + + eib := IconBtn { + background: Colors.transparent; + icon: Icons.back; + icon-rotation-angle: 180deg; + colorize: root.background.darker(30%); + is-ltr: false; + } + } + + ta := TouchArea { + mouse-cursor: MouseCursor.pointer; + } +} diff --git a/ui/base/sign-in.slint b/ui/base/sign-in.slint new file mode 100644 index 0000000..01a56d4 --- /dev/null +++ b/ui/base/sign-in.slint @@ -0,0 +1,151 @@ +import { Theme, Icons } from "../theme.slint"; +import { Logic } from "../logic.slint"; +import { Store } from "../store.slint"; +import { IconBtn } from "./icon-btn.slint"; +import { Label } from "./label.slint"; +import { Head } from "./head.slint"; +import { CancelBtn, ConfirmBtn } from "./btn.slint"; +import { LineInput } from "line-input.slint"; +import { SettingDetailInner, SettingDetailInnerVbox, SettingDetailLabel } from "./setting-detail.slint"; + +export component SignIn inherits Rectangle { + in property is-show-header: true; + + private property error-message; + + callback cancel(); + callback back(); + + //(username, password-frist, password-second) -> error-message + callback confirm(string, string, string) -> string; + + public function reset() { + error-message = ""; + username-lineedit.text = ""; + password-first-lineedit.text = ""; + password-second-lineedit.text = ""; + } + + forward-focus: username-lineedit; + + vbox := VerticalLayout { + if is-show-header: Head { + title: Logic.tr(Store.is-cn, "返回"); + hbox-alignment: LayoutAlignment.start; + clicked => { + root.back(); + } + } + + SettingDetailInner { + vbox-alignment: LayoutAlignment.center; + + SettingDetailInnerVbox { + username-txt := SettingDetailLabel { + text: Logic.tr(Store.is-cn, "请输入用户名"); + } + + HorizontalLayout { + spacing: Theme.spacing; + + username-lineedit := LineInput { + icon: Icons.paste; + width: root.width - Theme.padding * 4; + placeholder-text: Logic.tr(Store.is-cn, "用户名"); + + edited => { + root.error-message = ""; + } + + clicked => { + username-lineedit.text = ""; + username-lineedit.paste(); + } + } + } + } + + SettingDetailInnerVbox { + password-first-txt := SettingDetailLabel { + text: Logic.tr(Store.is-cn, "请输入密码"); + } + + HorizontalLayout { + spacing: Theme.spacing; + + private property is-show-password; + + password-first-lineedit := LineInput { + width: root.width - Theme.padding * 4; + placeholder-text: Logic.tr(Store.is-cn, "至少8个字符"); + icon: parent.is-show-password ? Icons.eye : Icons.close-eye; + input-type: parent.is-show-password ? InputType.text : InputType.password; + + edited => { + root.error-message = ""; + } + + clicked => { + parent.is-show-password = !parent.is-show-password; + } + } + } + } + + SettingDetailInnerVbox { + password-second-txt := SettingDetailLabel { + text: Logic.tr(Store.is-cn, "请再次输入密码"); + } + + HorizontalLayout { + spacing: Theme.spacing; + + private property is-show-password; + + password-second-lineedit := LineInput { + width: root.width - Theme.padding * 4; + placeholder-text: Logic.tr(Store.is-cn, "至少8个字符"); + icon: parent.is-show-password ? Icons.eye : Icons.close-eye; + input-type: is-show-password ? InputType.text : InputType.password; + + edited => { + root.error-message = ""; + } + + clicked => { + parent.is-show-password = !parent.is-show-password; + } + } + } + } + + if root.error-message != "": SettingDetailInnerVbox { + SettingDetailLabel { + color: Theme.danger-color; + text: root.error-message; + } + } + + HorizontalLayout { + spacing: Theme.spacing * 10; + padding: Theme.padding * 5; + + CancelBtn { + text: Logic.tr(Store.is-cn, "取消"); + clicked => { + root.reset(); + root.cancel(); + } + } + + ConfirmBtn { + text: Logic.tr(Store.is-cn, "登录"); + + clicked => { + root.error-message = root.confirm(username-lineedit.text, password-first-lineedit.text, password-second-lineedit.text); + } + } + } + } + } +} diff --git a/ui/base/slide-card.slint b/ui/base/slide-card.slint new file mode 100644 index 0000000..de4a68e --- /dev/null +++ b/ui/base/slide-card.slint @@ -0,0 +1,118 @@ +import { Theme } from "../theme.slint"; +import { IconBtn } from "./icon-btn.slint"; +import { Label } from "./label.slint"; + + +// Example: +// SlideCard { +// background: blue; +// icons-background: white; +// icons: [ +// { +// icon: Icons.delete, +// text: "Delete", +// colorize: Colors.red, +// }, +// { +// icon: Icons.edit, +// text: "Edit", +// colorize: Colors.red, +// }, +// ]; +// Rectangle { +// height: 80px; +// background: pink; +// } +// } + +export component SlideCard inherits Rectangle { + height: vbox.preferred-height; + + callback icon-clicked(int); + + in-out property mouse-cursor <=> ta.mouse-cursor; + in property <[{icon: image, text: string, colorize: color}]> icons; + in property icons-background; + in property hide-icons-after-clicked: true; + in property gap: 0px; + + private property max-move-pixels-up-bound: self.width * 0.04; + private property max-move-pixels-low-bound: self.width * 0.02; + private property is-show-icons: false; + private property is-hide-icons: true; + + public function show-icons() { + root.x = -icons-scope.width - gap; + root.is-show-icons = true; + root.is-hide-icons = false; + } + + public function hide-icons() { + root.x = 0; + root.is-hide-icons = true; + root.is-show-icons = false; + } + + animate x { + duration: Theme.default-animate-duration; + easing: ease-in-out; + } + + ta := TouchArea { + moved => { + if (!root.is-show-icons) { + if (self.pressed-x - self.mouse-x > parent.max-move-pixels-up-bound) { + show-icons(); + } + } + if (!root.is-hide-icons) { + if (self.mouse-x - self.pressed-x > parent.max-move-pixels-up-bound) { + hide-icons(); + } + } + } + } + + vbox := VerticalLayout { + @children + } + + icons-scope := Rectangle { + x: root.width + gap; + background: root.icons-background; + width: Math.max(root.width * 0.15, Theme.icon-size * 2) * icons.length; + + HorizontalLayout { + spacing: Theme.spacing; + for item[index] in root.icons: Rectangle { + VerticalLayout { + spacing: Theme.spacing; + alignment: LayoutAlignment.center; + + IconBtn { + icon: item.icon; + colorize: item.colorize; + } + + if item.text != "": HorizontalLayout { + alignment: LayoutAlignment.center; + Label { + text: item.text; + color: item.colorize; + } + } + } + + TouchArea { + mouse-cursor: MouseCursor.pointer; + clicked => { + if (hide-icons-after-clicked) { + root.hide-icons(); + } + root.icon-clicked(index); + } + } + } + } + } +} diff --git a/ui/base/tab-btn.slint b/ui/base/tab-btn.slint new file mode 100644 index 0000000..4cbd77e --- /dev/null +++ b/ui/base/tab-btn.slint @@ -0,0 +1,53 @@ +import { Theme } from "../theme.slint"; + +export component TabBtn inherits Rectangle { + in-out property icon <=> img.source; + in-out property icon-width <=> img.width; + in-out property icon-rotation-angle <=> img.rotation-angle; + in-out property text <=> txt.text; + + in-out property icon-size: Theme.icon-size; + in-out property colorize: Theme.icon-color; + in-out property checked: false; + + callback clicked(); + + in-out property bg-color: Colors.transparent; + in-out property bg-pressed-color: Colors.transparent; + + background: touch.pressed ? bg-pressed-color : bg-color; + + animate background { + duration: Theme.default-animate-duration; + easing: ease-in-out; + } + + VerticalLayout { + padding: 1px; + HorizontalLayout { + alignment: center; + img := Image { + width: root.icon-size; + colorize: root.checked ? Theme.brand-color : root.colorize; + } + } + + HorizontalLayout { + alignment: center; + txt := Text { + font-size: img.width * 0.4; + color: img.colorize; + } + } + } + + fs := FocusScope {} + + touch := TouchArea { + mouse-cursor: MouseCursor.pointer; + clicked => { + fs.focus(); + root.clicked(); + } + } +} diff --git a/ui/base/tag.slint b/ui/base/tag.slint new file mode 100644 index 0000000..14ef2d5 --- /dev/null +++ b/ui/base/tag.slint @@ -0,0 +1,40 @@ +import { Theme } from "../theme.slint"; +import { IconBtn } from "./icon-btn.slint"; +import { CenterLayout } from "./center-layout.slint"; + +export component Tag inherits Rectangle { + in-out property text <=> tag.text; + in-out property text-color <=> tag.color; + in-out property font-size <=> tag.font-size; + in-out property is-show-close-btn: false; + in-out property h-padding: Theme.padding; + in-out property v-padding: 0px; + + callback close <=> close-btn.clicked; + + border-radius: Theme.border-radius; + background: Theme.brand-color.darker(20%); + + HorizontalLayout { + padding-left: root.h-padding; + padding-right: root.h-padding; + padding-top: root.v-padding; + padding-bottom: root.v-padding; + + tag := Text { + vertical-alignment: center; + font-size: Theme.default-font-size - 4px; + color: Theme.base-color; + } + + CenterLayout { + width: root.is-show-close-btn ? self.preferred-width : 0px; + padding-left: Theme.padding; + close-btn := IconBtn { + visible: root.is-show-close-btn; + icon: @image-url("../images/close.svg"); + width: tag.preferred-height * 0.6; + } + } + } +} diff --git a/ui/base/tip.slint b/ui/base/tip.slint new file mode 100644 index 0000000..7177ea7 --- /dev/null +++ b/ui/base/tip.slint @@ -0,0 +1,26 @@ +import { Theme } from "../theme.slint"; + +export component Tip inherits Rectangle { + in-out property pos: "up"; + in-out property text <=> tip-txt.text; + in property parent-width: 0px; + in property parent-height: 0px; + + x: pos == "left" ? (-self.width - Theme.padding) : (pos == "right" ? (parent-width + Theme.padding) : -(self.width - parent-width) / 2); + + y: (pos == "left" || pos == "right") ? (parent-height - self.height) / 2 : (pos == "bottom" ? parent-height + Theme.padding : -self.height - Theme.padding); + + width: tip-txt.preferred-width + Theme.padding * 2; + height: tip-txt.preferred-height + Theme.padding / 2; + + background: Theme.base-background; + border-color: Theme.base-border-color; + border-width: 1px; + + tip-txt := Text { + horizontal-alignment: center; + vertical-alignment: center; + font-size: Theme.default-font-size - 2px; + color: Theme.primary-text-color; + } +} diff --git a/ui/base/toast.slint b/ui/base/toast.slint new file mode 100644 index 0000000..f29378c --- /dev/null +++ b/ui/base/toast.slint @@ -0,0 +1,52 @@ +import { Theme } from "../theme.slint"; +import { Util } from "../util.slint"; +import { Label } from "./label.slint"; +import { CenterLayout } from "./center-layout.slint"; + +export global ToastSetting { + in-out property text; + in-out property text-type; + + public function set(text: string, text-type: string) { + self.text = text; + self.text-type = text-type; + } +} + +export component Toast inherits Rectangle { + in-out property type: "success"; + in-out property inner-max-width: 300px; + in-out property text <=> txt.text; + + callback clicked <=> touch.clicked; + + width: hbox.preferred-width + Theme.padding * 2; + height: hbox.preferred-height; + border-radius: Theme.border-radius; + border-color: Theme.base-border-color; + background: Util.text-color(root.type); + + hbox := HorizontalLayout { + alignment: LayoutAlignment.center; + spacing: Theme.spacing; + padding: Theme.padding * 2; + + CenterLayout { + img := Image { + width: txt.font-size * 1.2; + height: self.width; + source: Util.icon-source(root.type); + colorize: Colors.white; + } + } + + txt := Label { + max-width: root.inner-max-width; + font-size: Theme.title4-font-size; + color: img.colorize; + wrap: word-wrap; + } + } + + touch := TouchArea { } +} diff --git a/ui/base/token-list.slint b/ui/base/token-list.slint new file mode 100644 index 0000000..f5b7348 --- /dev/null +++ b/ui/base/token-list.slint @@ -0,0 +1,62 @@ +import { Theme } from "../theme.slint"; +import { Store } from "../store.slint"; +import { Logic } from "../logic.slint"; +import { TokenTile, TokenTileWithSwitch, TokenTileEntry, TokenTileWithSwitchEntry } from "token-tile.slint"; +import { SettingDetail, SettingDetailInner } from "setting-detail.slint"; +import { Loading } from "loading.slint"; +import { NoDataImg } from "no-data.slint"; + +export component TokenList inherits SettingDetailInner { + in-out property <[TokenTileEntry]> entries; + + vbox-alignment: LayoutAlignment.start; + vbox-spacing: Theme.spacing * 2; + + callback clicked(TokenTileEntry); + + for item[index] in entries: TokenTile { + entry: item; + + clicked => { + root.clicked(item); + } + } +} + +export component TokenListWithSwitch inherits SettingDetail { + in-out property <[TokenTileWithSwitchEntry]> entries; + in-out property is-loading; + + callback clicked(TokenTileEntry); + callback toggled(bool, TokenTileEntry); + + if !is-loading && entries.length > 0: SettingDetailInner { + vbox-alignment: LayoutAlignment.start; + vbox-spacing: Theme.spacing * 2; + + for item[index] in entries: TokenTileWithSwitch { + entry: item.entry; + checked: item.checked; + + clicked => { + root.clicked(item.entry); + } + + toggled => { + root.toggled(self.checked, item.entry); + } + } + } + + if is-loading: Loading { + loading-text: Logic.tr(Store.is-cn, "正在刷新..."); + colorize: Theme.secondary-brand-color; + icon-size: Theme.icon-size * 2; + } + + if !is-loading && entries.length == 0: Rectangle { + NoDataImg { + text: Logic.tr(Store.is-cn, "没有数据"); + } + } +} diff --git a/ui/base/token-recipient.slint b/ui/base/token-recipient.slint new file mode 100644 index 0000000..a214173 --- /dev/null +++ b/ui/base/token-recipient.slint @@ -0,0 +1,54 @@ +import { Theme, Icons } from "../theme.slint"; +import { IconBtn } from "icon-btn.slint"; +import { Label } from "label.slint"; +import { Link } from "link.slint"; +import { SettingDetailInner, SettingDetail } from "setting-detail.slint"; + +export component TokenRecipient inherits SettingDetail { + in property account-name <=> account-name-label.text; + in property address <=> address-link.text; + in property qrcode <=> img.source; + + callback clicked-address <=> address-link.clicked; + callback copy-address <=> btn.clicked; + + SettingDetailInner { + vbox-alignment: LayoutAlignment.center; + vbox-spacing: Theme.spacing * 2; + + HorizontalLayout { + alignment: LayoutAlignment.center; + + account-name-label := Label { + font-size: Theme.title2-font-size; + font-weight: 0.5; + } + } + + HorizontalLayout { + alignment: LayoutAlignment.center; + + img := Image { + width: Math.min(300px, root.width * 0.8); + height: self.width; + } + } + + HorizontalLayout { + spacing: Theme.spacing * 2; + alignment: LayoutAlignment.center; + + address-link := Link { + overflow: elide; + horizontal-stretch: 1; + wrap: TextWrap.no-wrap; + font-size: Theme.default-font-size; + color: self.has-hover ? Theme.link-text-color : Theme.primary-text-color; + } + + btn := IconBtn { + icon: Icons.copy; + } + } + } +} diff --git a/ui/base/token-sender.slint b/ui/base/token-sender.slint new file mode 100644 index 0000000..b776fb6 --- /dev/null +++ b/ui/base/token-sender.slint @@ -0,0 +1,285 @@ +import { Theme, Icons } from "../theme.slint"; +import { Logic } from "../logic.slint"; +import { Store } from "../store.slint"; +import { Label } from "label.slint"; +import { Avatar } from "avatar.slint"; +import { LineInput } from "line-input.slint"; +import { CancelBtn, ConfirmBtn, TextBtn } from "btn.slint"; +import { SettingDetail, SettingDetailInner, SettingDetailInnerVbox, SettingDetailLabel } from "setting-detail.slint"; +import { PrioritizationFeeStatus } from "def.slint"; + +export component TokenSender inherits SettingDetail { + in property avatar <=> ava.icon; + in property name <=> name-label.text; + in property network <=> network-input.text; + in property send-token <=> send-token-input.text; + in property send-address <=> send-address-input.text; + in property recipient-address <=> recipient-address-input.text; + in-out property send-amount <=> amount-input.text; + in property total-balance <=> total-balance-label.text; + in property total-balance-usdt <=> total-balance-usdt-label.text; + + in property recipient-address-error-message; + in property prioritization-fee-error-message; + in-out property memo; + in-out property prioritization-fee; + in-out property is-show-advance-setting; + + private property is-token-edit; + + callback update-send-token-name(); + callback recipient-address-edited(string); + callback prioritization-fee-edited(string); + callback copy-send-address <=> send-address-input.clicked; + callback open-address-book <=> recipient-address-input.clicked; + callback open-network <=> network-input.clicked; + callback cancel <=> cancel-btn.clicked; + callback confirm <=> confirm-btn.clicked; + + callback get-prioritization-fee(PrioritizationFeeStatus) -> int; + + public function reset-advance-setting() { + root.memo = ""; + root.prioritization-fee = ""; + } + + title: Logic.tr(Store.is-cn, "发送代币"); + + SettingDetailInner { + HorizontalLayout { + alignment: LayoutAlignment.center; + ava := Avatar { + background: Theme.base-background.darker(3%); + width: Math.min(200px, root.height * 0.2); + icon: Icons.about-light; + icon-size-rate: 0.8; + } + } + + HorizontalLayout { + alignment: LayoutAlignment.center; + name-label := Label { + text: "Account1"; + font-size: Theme.title2-font-size; + color: Theme.brand-color; + } + } + + SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "区块网络"); + } + + network-input := LineInput { + width: root.width - Theme.spacing * 4; + text: "test"; + icon: Icons.browser-access; + enabled: false; + } + } + + SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "发送代币"); + } + + send-token-input := LineInput { + width: root.width - Theme.spacing * 4; + text: "ETH"; + icon: is-token-edit ? Icons.checked-box : Icons.edit; + enabled: is-token-edit; + + clicked => { + is-token-edit = !is-token-edit; + if (!is-token-edit) { + update-send-token-name(); + } + } + + accepted => { + update-send-token-name(); + } + } + } + + SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "发送地址"); + } + + send-address-input := LineInput { + width: root.width - Theme.spacing * 4; + text: "0xf1199999751b1a3A74590adBf95401D19AB30014"; + icon: Icons.copy; + enabled: false; + } + } + + SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "接收地址"); + } + + recipient-address-input := LineInput { + width: root.width - Theme.spacing * 4; + text: "GEScvfEF1Xt2oyrnJij5V5DYSmPjuUt45DfUs3VFrsED"; + icon: Icons.address-book; + + edited => { + root.recipient-address-edited(self.text); + } + } + + if root.recipient-address-error-message != "": SettingDetailLabel { + color: Theme.danger-color; + text: root.recipient-address-error-message; + } + } + + SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "发送数量"); + } + + amount-input := LineInput { + width: root.width - Theme.spacing * 4; + text: "0"; + icon: Icons.max; + input-type: InputType.decimal; + + clicked => { + self.text = root.total-balance; + } + } + + HorizontalLayout { + padding-left: Theme.padding * 2; + padding-right: Theme.padding * 2; + + alignment: LayoutAlignment.space-between; + + total-balance-label := Label { + text: "0.00"; + color: Theme.have-read-text-color; + } + + total-balance-usdt-label := Label { + text: "$0.00"; + color: Theme.have-read-text-color; + } + } + } + + TextBtn { + text: Logic.tr(Store.is-cn, "高级设置"); + icon: Icons.advance-setting; + + clicked => { + root.is-show-advance-setting = !root.is-show-advance-setting; + } + } + + if is-show-advance-setting: SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "备注"); + } + + memo-input := LineInput { + width: root.width - Theme.spacing * 4; + icon: Icons.cancel; + text: root.memo; + + clicked => { + self.text = ""; + } + + edited => { + root.memo = self.text; + } + } + } + + if is-show-advance-setting: SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "优先费用"); + } + + prioritization-fee-input := LineInput { + width: root.width - Theme.spacing * 4; + icon: Icons.cancel; + input-type: InputType.number; + placeholder-text: "micro lamports"; + text: root.prioritization-fee; + + clicked => { + self.text = ""; + } + + edited => { + root.prioritization-fee = self.text; + root.prioritization-fee-edited(self.text); + } + } + + HorizontalLayout { + alignment: LayoutAlignment.start; + spacing: Theme.spacing * 2; + + TextBtn { + text: Logic.tr(Store.is-cn, "慢"); + bg-color: Theme.info-color; + use-auto-size: true; + icon: Icons.turtle; + + clicked => { + prioritization-fee-input.text = root.get-prioritization-fee(PrioritizationFeeStatus.Slow); + root.prioritization-fee = prioritization-fee-input.text; + } + } + + TextBtn { + text: Logic.tr(Store.is-cn,"正常"); + use-auto-size: true; + icon: Icons.rabbit; + + clicked => { + prioritization-fee-input.text = root.get-prioritization-fee(PrioritizationFeeStatus.Normal); + root.prioritization-fee = prioritization-fee-input.text; + } + } + + TextBtn { + text: Logic.tr(Store.is-cn,"快"); + use-auto-size: true; + icon: Icons.horse; + + clicked => { + prioritization-fee-input.text = root.get-prioritization-fee(PrioritizationFeeStatus.Fast); + root.prioritization-fee = prioritization-fee-input.text; + } + } + } + + if root.prioritization-fee-error-message != "": SettingDetailLabel { + color: Theme.danger-color; + text: root.prioritization-fee-error-message; + } + } + + HorizontalLayout { + alignment: LayoutAlignment.center; + padding-top: Theme.padding * 5; + padding-bottom: Theme.padding * 5; + spacing: Theme.spacing * 10; + + cancel-btn := CancelBtn { + text: Logic.tr(Store.is-cn, "取消"); + } + + confirm-btn := ConfirmBtn { + icon: Icons.send; + text: Logic.tr(Store.is-cn, "确认"); + } + } + } +} diff --git a/ui/base/token-tile.slint b/ui/base/token-tile.slint new file mode 100644 index 0000000..3f93e6c --- /dev/null +++ b/ui/base/token-tile.slint @@ -0,0 +1,118 @@ +import { Switch } from "std-widgets.slint"; +import { Theme, Icons } from "../theme.slint"; +import { ListTile } from "list-tile.slint"; +import { Label } from "label.slint"; +import { IconBtn } from "icon-btn.slint"; +import { Util } from "../util.slint"; + +export struct TokenTileEntry { + uuid: string, + network: string, + symbol: string, + icon-extension: string, + account-address: string, + mint-address: string, + balance: string, + balance-usdt: string, + + token-account-address: string, // for spl token + decimals: int, // for spl token +} + +export struct TokenTileWithSwitchEntry { + entry: TokenTileEntry, + checked: bool, +} + +component Tile inherits Rectangle { + in-out property entry; + + in property icon-size: Theme.icon-size * 1.5; + in property icon-colorize; + + in property symbol-font-size: Theme.title3-font-size; + in property balance-font-size: Theme.default-font-size; + in property balance-usdt-font-size: Theme.title3-font-size; + + out property has-hover: ta.has-hover; + + callback clicked <=> ta.clicked; + + height: hbox.preferred-height; + background: has-hover ? Theme.base-background.darker(3%) : Theme.base-background; + border-radius: Theme.border-radius; + drop-shadow-blur: Theme.padding * 2; + drop-shadow-color: Theme.base-background-drop-shadow; + + ta := TouchArea { + mouse-cursor: MouseCursor.pointer; + } + + hbox := HorizontalLayout { + padding: Theme.padding * 2; + spacing: Theme.spacing * 2; + alignment: LayoutAlignment.space-between; + + HorizontalLayout { + horizontal-stretch: 1; + spacing: Theme.spacing * 4; + + VerticalLayout { + alignment: LayoutAlignment.center; + Rectangle { + width: root.icon-size + Theme.padding * 4; + height: self.width; + background: Theme.secondary-background; + border-radius: self.width / 2; + + img := Image { + height: root.icon-size; + width: self.height; + source: Util.get-token-icon(entry.symbol, entry.mint-address, entry.icon-extension); + colorize: root.icon-colorize; + } + } + } + + VerticalLayout { + alignment: LayoutAlignment.space-between; + spacing: Theme.spacing * 2; + padding-top: Theme.padding; + padding-bottom: Theme.padding; + + Label { + font-size: root.symbol-font-size; + text: entry.symbol; + wrap: TextWrap.no-wrap; + overflow: TextOverflow.elide; + font-weight: 0.5; + } + + Label { + font-size: root.balance-font-size; + text: entry.balance; + wrap: TextWrap.no-wrap; + overflow: TextOverflow.elide; + } + } + } + + @children + } +} + +export component TokenTile inherits Tile { + Label { + font-size: root.balance-usdt-font-size; + text: root.entry.balance-usdt; + } +} + +export component TokenTileWithSwitch inherits Tile { + in-out property checked <=> sw.checked; + in-out property enabled <=> sw.enabled; + + callback toggled <=> sw.toggled; + + sw := Switch { } +} diff --git a/ui/base/transaction-fee.slint b/ui/base/transaction-fee.slint new file mode 100644 index 0000000..b02b0e6 --- /dev/null +++ b/ui/base/transaction-fee.slint @@ -0,0 +1,204 @@ +import { Theme, Icons } from "../theme.slint"; +import { Logic } from "../logic.slint"; +import { Store } from "../store.slint"; +import { Label } from "label.slint"; +import { LineInput } from "line-input.slint"; +import { CancelBtn, ConfirmBtn } from "btn.slint"; +import { SettingDetail, SettingDetailInner, SettingDetailInnerVbox, SettingDetailLabel } from "setting-detail.slint"; +import { Loading } from "loading.slint"; +import { LoadingStatus } from "def.slint"; + +export component TransactionFee inherits SettingDetail { + in property network <=> network-input.text; + in property send-token <=> send-token-input.text; + in property send-address <=> send-address-input.text; + in property recipient-address <=> recipient-address-input.text; + in property send-amount <=> amount-input.text; + in property send-amount-usdt; + in property fee; + in property fee-usdt; + in property create-token-account-fee; + in property create-token-account-fee-usdt; + in property memo; + in property prioritization-fee; + + in property loading-status; + + callback cancel(); + callback confirm(); + + title: Logic.tr(Store.is-cn, "交易信息"); + + SettingDetailInner { + if loading-status == LoadingStatus.Loading: Loading { + height: 150px; + loading-text: Logic.tr(Store.is-cn, "正在估计交易费用..."); + colorize: Theme.secondary-brand-color; + icon-size: Theme.icon-size * 2; + } + + SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "区块网络"); + } + + network-input := LineInput { + width: root.width - Theme.spacing * 4; + text: "test"; + enabled: false; + is-show-icon: false; + } + } + + SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "发送代币"); + } + + send-token-input := LineInput { + width: root.width - Theme.spacing * 4; + text: "ETH"; + enabled: false; + is-show-icon: false; + } + } + + SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "发送地址"); + } + + send-address-input := LineInput { + width: root.width - Theme.spacing * 4; + text: "0xf1199999751b1a3A74590adBf95401D19AB30014"; + enabled: false; + is-show-icon: false; + } + } + + SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "接收地址"); + } + + recipient-address-input := LineInput { + width: root.width - Theme.spacing * 4; + text: "GEScvfEF1Xt2oyrnJij5V5DYSmPjuUt45DfUs3VFrsED"; + enabled: false; + is-show-icon: false; + } + } + + SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "发送数量"); + } + + amount-input := LineInput { + width: root.width - Theme.spacing * 4; + text: "0"; + input-type: InputType.decimal; + is-show-icon: false; + enabled: false; + } + + if send-amount-usdt != "": Label { + text: root.send-amount-usdt; + color: Theme.have-read-text-color; + } + } + + if loading-status == LoadingStatus.Success: SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "基础费用"); + } + + LineInput { + width: root.width - Theme.spacing * 4; + text: root.fee; + is-show-icon: false; + enabled: false; + } + + if fee-usdt != "": Label { + text: root.fee-usdt; + color: Theme.have-read-text-color; + } + } + + if root.prioritization-fee != "": SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "优先费用"); + } + + LineInput { + width: root.width - Theme.spacing * 4; + text: root.prioritization-fee; + is-show-icon: false; + enabled: false; + } + } + + if loading-status == LoadingStatus.Success && root.create-token-account-fee != "": SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "创建账户费用"); + } + + LineInput { + width: root.width - Theme.spacing * 4; + text: root.create-token-account-fee; + is-show-icon: false; + enabled: false; + } + + if root.create-token-account-fee-usdt != "": Label { + text: root.create-token-account-fee-usdt; + color: Theme.have-read-text-color; + } + } + + if root.memo != "": SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "备注"); + } + + LineInput { + width: root.width - Theme.spacing * 4; + text: root.memo; + is-show-icon: false; + enabled: false; + } + } + + HorizontalLayout { + padding-top: Theme.padding * 5; + padding-bottom: Theme.padding * 5; + + if loading-status == LoadingStatus.Loading: CancelBtn { + border-radius: Theme.border-radius; + text: Logic.tr(Store.is-cn, "取消"); + clicked => { + root.cancel(); + } + } + + if loading-status == LoadingStatus.Fail: CancelBtn { + border-radius: Theme.border-radius; + bg-color: Theme.warning-color; + text: Logic.tr(Store.is-cn, "估计交易费用失败"); + icon: Icons.warning; + clicked => { + root.back(); + } + } + + if loading-status == LoadingStatus.Success: ConfirmBtn { + border-radius: Theme.border-radius; + text: Logic.tr(Store.is-cn, "确认"); + clicked => { + root.confirm(); + } + } + } + } +} diff --git a/ui/base/transaction-tile.slint b/ui/base/transaction-tile.slint new file mode 100644 index 0000000..7e39598 --- /dev/null +++ b/ui/base/transaction-tile.slint @@ -0,0 +1,114 @@ +import { Theme, Icons } from "../theme.slint"; +import { IconBtn, RotationType } from "./icon-btn.slint"; +import { Label } from "./label.slint"; + +export enum TransactionTileStatus { + Success, + Pending, + Error, + Loading, +} + +export struct TransactionTileEntry { + uuid: string, + network: string, + hash: string, + balance: string, + time: string, + status: TransactionTileStatus, +} + +export component TransactionTile inherits Rectangle { + callback icon-clicked <=> icon-btn.clicked; + callback hash-clicked <=> hash-ta.clicked; + + in property icon: status-icon(entry.status); + in property icon-colorize: status-icon-colorize(entry.status); + in property icon-size: Theme.icon-size; + + in-out property entry; + + pure public function status-icon(status: TransactionTileStatus) -> image { + if (status == TransactionTileStatus.Success) { + return Icons.success-big-fill; + } else if (status == TransactionTileStatus.Pending) { + return Icons.pending-fill; + } else if (status == TransactionTileStatus.Loading) { + return Icons.loading; + } else { + return Icons.error-fill; + } + } + + pure public function status-icon-colorize(status: TransactionTileStatus) -> color { + if (status == TransactionTileStatus.Success) { + return Theme.success-color; + } else if (status == TransactionTileStatus.Pending) { + return Theme.warning-color; + } else if (status == TransactionTileStatus.Loading) { + return Theme.secondary-brand-color; + } else { + return Theme.danger-color; + } + } + + background: Theme.base-background; + drop-shadow-blur: Theme.padding * 2; + drop-shadow-color: Theme.base-background-drop-shadow; + + HorizontalLayout { + padding: Theme.padding * 2; + spacing: Theme.spacing * 2; + alignment: LayoutAlignment.space-between; + + VerticalLayout { + width: root.width - icon-rect.width - parent.spacing - parent.padding * 2; + alignment: LayoutAlignment.space-between; + horizontal-stretch: 1; + + Label { + font-size: Theme.title4-font-size; + text: entry.hash; + wrap: TextWrap.no-wrap; + overflow: TextOverflow.elide; + font-weight: 0.5; + + hash-ta := TouchArea { + mouse-cursor: MouseCursor.pointer; + } + } + + HorizontalLayout { + alignment: LayoutAlignment.space-between; + spacing: Theme.spacing; + + Label { + text: entry.balance; + wrap: TextWrap.no-wrap; + overflow: TextOverflow.elide; + color: Theme.have-read-text-color; + } + + Label { + text: entry.time; + wrap: TextWrap.no-wrap; + overflow: TextOverflow.elide; + color: Theme.have-read-text-color; + font-size: Theme.default-font-size - 2px; + } + } + } + + icon-rect := Rectangle { + width: root.icon-size + Theme.padding * 4; + + icon-btn := IconBtn { + icon-size: root.icon-size; + colorize: root.icon-colorize; + icon: root.icon; + rotation-type: TransactionTileStatus.Loading == entry.status ? RotationType.Auto : RotationType.None; + icon-rotation-angle: TransactionTileStatus.Loading == entry.status ? 240deg * animation-tick() / 0.5s : 0; + } + } + } +} diff --git a/ui/base/txtedit.slint b/ui/base/txtedit.slint new file mode 100644 index 0000000..42678df --- /dev/null +++ b/ui/base/txtedit.slint @@ -0,0 +1,26 @@ +import { TextEdit, Palette } from "std-widgets.slint"; +import { Theme } from "../theme.slint"; + +export component TxtEdit inherits Rectangle { + clip: true; + forward-focus: edit; + border-width: edit.has-focus ? 2px : 1px; + border-radius: Theme.border-radius; + border-color: edit.has-focus ? Palette.accent-background : Palette.border; + + in-out property text <=> edit.text; + callback edited <=> edit.edited; + + public function clear() { + root.text = ""; + } + + hbox := HorizontalLayout { + padding: Theme.padding * 2; + padding-right: 0; + + edit := TextEdit { + font-size: Theme.default-font-size; + } + } +} diff --git a/ui/base/wait-transaction-confirmed.slint b/ui/base/wait-transaction-confirmed.slint new file mode 100644 index 0000000..c8106de --- /dev/null +++ b/ui/base/wait-transaction-confirmed.slint @@ -0,0 +1,119 @@ +import { Theme, Icons } from "../theme.slint"; +import { Logic } from "../logic.slint"; +import { Store } from "../store.slint"; +import { Label } from "label.slint"; +import { LineInput } from "line-input.slint"; +import { CancelBtn, ConfirmBtn } from "btn.slint"; +import { SettingDetail, SettingDetailInner, SettingDetailInnerVbox, SettingDetailLabel } from "setting-detail.slint"; +import { Loading } from "loading.slint"; +import { LoadingStatus } from "def.slint"; + +export component WaitTransactionConfirmed inherits SettingDetail { + in property network <=> network-input.text; + in property send-token <=> send-token-input.text; + in property send-amount <=> amount-input.text; + in property send-amount-usdt; + in property signature <=> signature-input.text; + in property loading-status; + + callback open-signature <=> signature-input.clicked; + + title: Logic.tr(Store.is-cn, "交易记录"); + + SettingDetailInner { + if loading-status == LoadingStatus.Loading: Loading { + height: 150px; + loading-text: Logic.tr(Store.is-cn, "等待交易确认..."); + colorize: Theme.secondary-brand-color; + icon-size: Theme.icon-size * 2; + } + + SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "区块网络"); + } + + network-input := LineInput { + width: root.width - Theme.spacing * 4; + text: "test"; + enabled: false; + is-show-icon: false; + } + } + + SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "发送代币"); + } + + send-token-input := LineInput { + width: root.width - Theme.spacing * 4; + text: "ETH"; + enabled: false; + is-show-icon: false; + } + } + + SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "发送数量"); + } + + amount-input := LineInput { + width: root.width - Theme.spacing * 4; + text: "0"; + input-type: InputType.decimal; + is-show-icon: false; + enabled: false; + } + + if send-amount-usdt != "": Label { + text: root.send-amount-usdt; + color: Theme.have-read-text-color; + } + } + + SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "交易记录"); + } + + signature-input := LineInput { + width: root.width - Theme.spacing * 4; + enabled: false; + icon: Icons.browser-access; + } + } + + HorizontalLayout { + padding-top: Theme.padding * 5; + padding-bottom: Theme.padding * 5; + + if loading-status == LoadingStatus.Loading: CancelBtn { + border-radius: Theme.border-radius; + text: Logic.tr(Store.is-cn, "关闭"); + clicked => { + root.back(); + } + } + + if loading-status == LoadingStatus.Fail: CancelBtn { + border-radius: Theme.border-radius; + bg-color: Theme.warning-color; + text: Logic.tr(Store.is-cn, "交易失败"); + icon: Icons.warning; + clicked => { + root.back(); + } + } + + if loading-status == LoadingStatus.Success: ConfirmBtn { + border-radius: Theme.border-radius; + text: Logic.tr(Store.is-cn, "交易成功"); + clicked => { + root.back(); + } + } + } + } +} diff --git a/ui/base/widgets.slint b/ui/base/widgets.slint new file mode 100644 index 0000000..49ea347 --- /dev/null +++ b/ui/base/widgets.slint @@ -0,0 +1,125 @@ +import { LoadingStatus, PrioritizationFeeStatus } from "def.slint"; +import { Toast, ToastSetting } from "toast.slint"; +import { TabBtn } from "tab-btn.slint"; +import { IconBtn, RotationType } from "icon-btn.slint"; +import { Label } from "label.slint"; +import { Tag } from "tag.slint"; +import { CenterLayout } from "center-layout.slint"; +import { NoMessageImg } from "no-message.slint"; +import { NoDataImg } from "no-data.slint"; +import { Divider } from "divider.slint"; +import { Link } from "link.slint"; +import { Dialog } from "dialog.slint"; +import { ConfirmDialogDialog, ConfirmDialogSetting } from "confirm-dialog.slint"; +import { Blanket } from "blanket.slint"; +import { CancelBtn, ConfirmBtn, TextBtn } from "btn.slint"; +import { IconsDialog, IconsDialogSetting } from "icons-dialog.slint"; +import { Head } from "head.slint"; +import { SettingEntry } from "setting-entry.slint"; +import { SettingDetail, SettingDetailInner, SettingDetailLabel, SettingDetailInnerVbox, SettingDetailSwitch } from "setting-detail.slint"; +import { Brand } from "brand.slint"; +import { TxtEdit } from "txtedit.slint"; +import { LanguageDialog } from "language-dialog.slint"; +import { RadioBtn } from "radio-btn.slint"; +import { LineInput } from "line-input.slint"; +import { ElevatedBtn } from "elevated-btn.slint"; +import { LandingPage } from "landing-page.slint"; +import { Tip } from "tip.slint"; +import { Loading } from "loading.slint"; +import { ListTile } from "list-tile.slint"; +import { News } from "news.slint"; +import { SlideCard } from "slide-card.slint"; +import { Drawer, DrawerPosition } from "drawer.slint"; +import { SignIn } from "sign-in.slint"; +import { Login } from "login.slint"; +import { Password, PasswordSetting } from "password.slint"; +import { Mnemonic } from "mnemonic.slint"; +import { Avatar } from "avatar.slint"; +import { AddressBook, AddressBookDetail, AddressBookEntry, AddressBookSetting } from "address-book.slint"; +import { TransactionTile, TransactionTileEntry, TransactionTileStatus } from "transaction-tile.slint"; +import { About, AboutSetting } from "about.slint"; +import { Help } from "help.slint"; +import { ResetPassword } from "reset-password.slint"; +import { Banner } from "banner.slint"; +import { AccountBalance } from "account-balance.slint"; +import { TokenTile, TokenTileEntry, TokenTileWithSwitchEntry } from "token-tile.slint"; +import { TokenList, TokenListWithSwitch } from "token-list.slint"; +import { TokenSender } from "token-sender.slint"; +import { TokenRecipient } from "token-recipient.slint"; +import { TransactionFee } from "transaction-fee.slint"; +import { WaitTransactionConfirmed } from "wait-transaction-confirmed.slint"; + +export { + LoadingStatus, + PrioritizationFeeStatus, + Toast, + ToastSetting, + TabBtn, + IconBtn, + RotationType, + ElevatedBtn, + Label, + CenterLayout, + Tag, + NoMessageImg, + NoDataImg, + Divider, + Link, + Dialog, + ConfirmDialogDialog, + ConfirmDialogSetting, + Blanket, + CancelBtn, + ConfirmBtn, + TextBtn, + IconsDialog, + IconsDialogSetting, + Head, + SettingEntry, + SettingDetail, + SettingDetailInner, + SettingDetailLabel, + SettingDetailSwitch, + SettingDetailInnerVbox, + TxtEdit, + Brand, + LanguageDialog, + RadioBtn, + LineInput, + LandingPage, + Tip, + Loading, + ListTile, + News, + SlideCard, + Drawer, + DrawerPosition, + SignIn, + Login, + Password, + PasswordSetting, + Mnemonic, + Avatar, + AddressBook, + AddressBookDetail, + AddressBookEntry, + AddressBookSetting, + TransactionTile, + TransactionTileEntry, + TransactionTileStatus, + About, + AboutSetting, + Help, + ResetPassword, + Banner, + AccountBalance, + TokenTile, + TokenTileEntry, + TokenTileWithSwitchEntry, + TokenList, + TokenListWithSwitch, + TokenSender, + TokenRecipient, + TransactionFee, + WaitTransactionConfirmed +} diff --git a/ui/fonts/SourceHanSansCN.otf b/ui/fonts/SourceHanSansCN.otf new file mode 100644 index 0000000..c13789b Binary files /dev/null and b/ui/fonts/SourceHanSansCN.otf differ diff --git a/ui/fonts/SourceHanSerifCN.ttf b/ui/fonts/SourceHanSerifCN.ttf new file mode 100644 index 0000000..dbafe4e Binary files /dev/null and b/ui/fonts/SourceHanSerifCN.ttf differ diff --git a/ui/images/about-light.svg b/ui/images/about-light.svg new file mode 100644 index 0000000..3c03dfd --- /dev/null +++ b/ui/images/about-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/about.svg b/ui/images/about.svg new file mode 100644 index 0000000..379d750 --- /dev/null +++ b/ui/images/about.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/account.svg b/ui/images/account.svg new file mode 100644 index 0000000..9186aee --- /dev/null +++ b/ui/images/account.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/add-fill.svg b/ui/images/add-fill.svg new file mode 100644 index 0000000..d7908f2 --- /dev/null +++ b/ui/images/add-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/add-image.svg b/ui/images/add-image.svg new file mode 100644 index 0000000..df51190 --- /dev/null +++ b/ui/images/add-image.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/add-in-rect.svg b/ui/images/add-in-rect.svg new file mode 100644 index 0000000..d81e869 --- /dev/null +++ b/ui/images/add-in-rect.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/add-light.svg b/ui/images/add-light.svg new file mode 100644 index 0000000..65fd986 --- /dev/null +++ b/ui/images/add-light.svg @@ -0,0 +1 @@ + diff --git a/ui/images/add-small.svg b/ui/images/add-small.svg new file mode 100644 index 0000000..4c77265 --- /dev/null +++ b/ui/images/add-small.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/addition.svg b/ui/images/addition.svg new file mode 100644 index 0000000..f27cd55 --- /dev/null +++ b/ui/images/addition.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/address-book.svg b/ui/images/address-book.svg new file mode 100644 index 0000000..7ee71dc --- /dev/null +++ b/ui/images/address-book.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/address.svg b/ui/images/address.svg new file mode 100644 index 0000000..1bb7db7 --- /dev/null +++ b/ui/images/address.svg @@ -0,0 +1 @@ + diff --git a/ui/images/advance-setting.svg b/ui/images/advance-setting.svg new file mode 100644 index 0000000..dc76d14 --- /dev/null +++ b/ui/images/advance-setting.svg @@ -0,0 +1 @@ + diff --git a/ui/images/airdrop.svg b/ui/images/airdrop.svg new file mode 100644 index 0000000..d765d8f --- /dev/null +++ b/ui/images/airdrop.svg @@ -0,0 +1 @@ + diff --git a/ui/images/arrow-down.svg b/ui/images/arrow-down.svg new file mode 100644 index 0000000..83dfb7f --- /dev/null +++ b/ui/images/arrow-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/arrow-left.svg b/ui/images/arrow-left.svg new file mode 100644 index 0000000..e352e4c --- /dev/null +++ b/ui/images/arrow-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/arrow-right.svg b/ui/images/arrow-right.svg new file mode 100644 index 0000000..8028846 --- /dev/null +++ b/ui/images/arrow-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/arrow-up.svg b/ui/images/arrow-up.svg new file mode 100644 index 0000000..818eb25 --- /dev/null +++ b/ui/images/arrow-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/back.svg b/ui/images/back.svg new file mode 100644 index 0000000..24dec50 --- /dev/null +++ b/ui/images/back.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/backup-recover.svg b/ui/images/backup-recover.svg new file mode 100644 index 0000000..e306d50 --- /dev/null +++ b/ui/images/backup-recover.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/bot.svg b/ui/images/bot.svg new file mode 100644 index 0000000..65c31d3 --- /dev/null +++ b/ui/images/bot.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/brand.png b/ui/images/brand.png new file mode 100644 index 0000000..a9a4912 Binary files /dev/null and b/ui/images/brand.png differ diff --git a/ui/images/broken-image.svg b/ui/images/broken-image.svg new file mode 100644 index 0000000..591fcef --- /dev/null +++ b/ui/images/broken-image.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/browser-access.svg b/ui/images/browser-access.svg new file mode 100644 index 0000000..437c7ec --- /dev/null +++ b/ui/images/browser-access.svg @@ -0,0 +1 @@ + diff --git a/ui/images/browser.svg b/ui/images/browser.svg new file mode 100644 index 0000000..d00ad84 --- /dev/null +++ b/ui/images/browser.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/btc.svg b/ui/images/btc.svg new file mode 100644 index 0000000..3a51b9b --- /dev/null +++ b/ui/images/btc.svg @@ -0,0 +1 @@ + diff --git a/ui/images/btn-up.svg b/ui/images/btn-up.svg new file mode 100644 index 0000000..24b03df --- /dev/null +++ b/ui/images/btn-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/bxs-archive.svg b/ui/images/bxs-archive.svg new file mode 100644 index 0000000..9b2122f --- /dev/null +++ b/ui/images/bxs-archive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/cancel-fill.svg b/ui/images/cancel-fill.svg new file mode 100644 index 0000000..ec97aa6 --- /dev/null +++ b/ui/images/cancel-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/cancel-light.svg b/ui/images/cancel-light.svg new file mode 100644 index 0000000..887bc06 --- /dev/null +++ b/ui/images/cancel-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/chat.svg b/ui/images/chat.svg new file mode 100644 index 0000000..8748cdf --- /dev/null +++ b/ui/images/chat.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/checked-box.svg b/ui/images/checked-box.svg new file mode 100644 index 0000000..5d7f7b3 --- /dev/null +++ b/ui/images/checked-box.svg @@ -0,0 +1 @@ + diff --git a/ui/images/clear-light.svg b/ui/images/clear-light.svg new file mode 100644 index 0000000..53fca26 --- /dev/null +++ b/ui/images/clear-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/close-eye.svg b/ui/images/close-eye.svg new file mode 100644 index 0000000..374d82b --- /dev/null +++ b/ui/images/close-eye.svg @@ -0,0 +1 @@ + diff --git a/ui/images/close.svg b/ui/images/close.svg new file mode 100644 index 0000000..a97fb66 --- /dev/null +++ b/ui/images/close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/convert2text.svg b/ui/images/convert2text.svg new file mode 100644 index 0000000..a10c45f --- /dev/null +++ b/ui/images/convert2text.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/copy.svg b/ui/images/copy.svg new file mode 100644 index 0000000..6a919e6 --- /dev/null +++ b/ui/images/copy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/crypto.svg b/ui/images/crypto.svg new file mode 100644 index 0000000..f622f03 --- /dev/null +++ b/ui/images/crypto.svg @@ -0,0 +1 @@ + diff --git a/ui/images/curve.svg b/ui/images/curve.svg new file mode 100644 index 0000000..7af9528 --- /dev/null +++ b/ui/images/curve.svg @@ -0,0 +1 @@ + diff --git a/ui/images/danger.svg b/ui/images/danger.svg new file mode 100644 index 0000000..cbfe608 --- /dev/null +++ b/ui/images/danger.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/data-archive.svg b/ui/images/data-archive.svg new file mode 100644 index 0000000..4ec351b --- /dev/null +++ b/ui/images/data-archive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/debug-light.svg b/ui/images/debug-light.svg new file mode 100644 index 0000000..5638f3e --- /dev/null +++ b/ui/images/debug-light.svg @@ -0,0 +1 @@ + diff --git a/ui/images/delete-light.svg b/ui/images/delete-light.svg new file mode 100644 index 0000000..a645384 --- /dev/null +++ b/ui/images/delete-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/delete.svg b/ui/images/delete.svg new file mode 100644 index 0000000..f6d5207 --- /dev/null +++ b/ui/images/delete.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/developer.svg b/ui/images/developer.svg new file mode 100644 index 0000000..50e8b47 --- /dev/null +++ b/ui/images/developer.svg @@ -0,0 +1 @@ + diff --git a/ui/images/disable.svg b/ui/images/disable.svg new file mode 100644 index 0000000..1d1cfb5 --- /dev/null +++ b/ui/images/disable.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/doge.svg b/ui/images/doge.svg new file mode 100644 index 0000000..705d5e6 --- /dev/null +++ b/ui/images/doge.svg @@ -0,0 +1 @@ + diff --git a/ui/images/donate.svg b/ui/images/donate.svg new file mode 100644 index 0000000..ab9d535 --- /dev/null +++ b/ui/images/donate.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/download-cloud.svg b/ui/images/download-cloud.svg new file mode 100644 index 0000000..8b4f393 --- /dev/null +++ b/ui/images/download-cloud.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/download.svg b/ui/images/download.svg new file mode 100644 index 0000000..ff2211f --- /dev/null +++ b/ui/images/download.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/edit-text.svg b/ui/images/edit-text.svg new file mode 100644 index 0000000..e8b7ca5 --- /dev/null +++ b/ui/images/edit-text.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/edit.svg b/ui/images/edit.svg new file mode 100644 index 0000000..6142105 --- /dev/null +++ b/ui/images/edit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/error-fill.svg b/ui/images/error-fill.svg new file mode 100644 index 0000000..b218b59 --- /dev/null +++ b/ui/images/error-fill.svg @@ -0,0 +1 @@ + diff --git a/ui/images/eth.svg b/ui/images/eth.svg new file mode 100644 index 0000000..2579e3d --- /dev/null +++ b/ui/images/eth.svg @@ -0,0 +1 @@ + diff --git a/ui/images/export.svg b/ui/images/export.svg new file mode 100644 index 0000000..2bdd392 --- /dev/null +++ b/ui/images/export.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/eye-close.svg b/ui/images/eye-close.svg new file mode 100644 index 0000000..79dc9c2 --- /dev/null +++ b/ui/images/eye-close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/eye.svg b/ui/images/eye.svg new file mode 100644 index 0000000..03dfaa9 --- /dev/null +++ b/ui/images/eye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/favorite-fill.svg b/ui/images/favorite-fill.svg new file mode 100644 index 0000000..9aadd36 --- /dev/null +++ b/ui/images/favorite-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/feedback.svg b/ui/images/feedback.svg new file mode 100644 index 0000000..70f801e --- /dev/null +++ b/ui/images/feedback.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/file-archive.svg b/ui/images/file-archive.svg new file mode 100644 index 0000000..faea14b --- /dev/null +++ b/ui/images/file-archive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/file-open-fill.svg b/ui/images/file-open-fill.svg new file mode 100644 index 0000000..3f7eda6 --- /dev/null +++ b/ui/images/file-open-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/file-open.svg b/ui/images/file-open.svg new file mode 100644 index 0000000..21e79ca --- /dev/null +++ b/ui/images/file-open.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/file.svg b/ui/images/file.svg new file mode 100644 index 0000000..16356dd --- /dev/null +++ b/ui/images/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/find.svg b/ui/images/find.svg new file mode 100644 index 0000000..9c33a54 --- /dev/null +++ b/ui/images/find.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/format-clear.svg b/ui/images/format-clear.svg new file mode 100644 index 0000000..78377f9 --- /dev/null +++ b/ui/images/format-clear.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/github.svg b/ui/images/github.svg new file mode 100644 index 0000000..7e2f0d9 --- /dev/null +++ b/ui/images/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/help-light.svg b/ui/images/help-light.svg new file mode 100644 index 0000000..495bb2e --- /dev/null +++ b/ui/images/help-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/help.svg b/ui/images/help.svg new file mode 100644 index 0000000..16a06f8 --- /dev/null +++ b/ui/images/help.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/hide.svg b/ui/images/hide.svg new file mode 100644 index 0000000..971b3aa --- /dev/null +++ b/ui/images/hide.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/history.svg b/ui/images/history.svg new file mode 100644 index 0000000..aacd5fa --- /dev/null +++ b/ui/images/history.svg @@ -0,0 +1 @@ + diff --git a/ui/images/home-fill.svg b/ui/images/home-fill.svg new file mode 100644 index 0000000..d2f26d8 --- /dev/null +++ b/ui/images/home-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/home-light.svg b/ui/images/home-light.svg new file mode 100644 index 0000000..cc31d7a --- /dev/null +++ b/ui/images/home-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/horse.svg b/ui/images/horse.svg new file mode 100644 index 0000000..20013ef --- /dev/null +++ b/ui/images/horse.svg @@ -0,0 +1 @@ + diff --git a/ui/images/image.svg b/ui/images/image.svg new file mode 100644 index 0000000..75cdf2a --- /dev/null +++ b/ui/images/image.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/import.svg b/ui/images/import.svg new file mode 100644 index 0000000..bd2e6c5 --- /dev/null +++ b/ui/images/import.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/info-dark.svg b/ui/images/info-dark.svg new file mode 100644 index 0000000..969ed5c --- /dev/null +++ b/ui/images/info-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/info.svg b/ui/images/info.svg new file mode 100644 index 0000000..13eba17 --- /dev/null +++ b/ui/images/info.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/landing-account.svg b/ui/images/landing-account.svg new file mode 100644 index 0000000..ed0d2cd --- /dev/null +++ b/ui/images/landing-account.svg @@ -0,0 +1 @@ + diff --git a/ui/images/landing-language-switch.svg b/ui/images/landing-language-switch.svg new file mode 100644 index 0000000..872f814 --- /dev/null +++ b/ui/images/landing-language-switch.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/landing-reading.svg b/ui/images/landing-reading.svg new file mode 100644 index 0000000..cca8729 --- /dev/null +++ b/ui/images/landing-reading.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/landing-send.svg b/ui/images/landing-send.svg new file mode 100644 index 0000000..eeec885 --- /dev/null +++ b/ui/images/landing-send.svg @@ -0,0 +1 @@ + diff --git a/ui/images/landing-subscription.svg b/ui/images/landing-subscription.svg new file mode 100644 index 0000000..ddfe675 --- /dev/null +++ b/ui/images/landing-subscription.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui/images/landing-welcome.svg b/ui/images/landing-welcome.svg new file mode 100644 index 0000000..9c388a2 --- /dev/null +++ b/ui/images/landing-welcome.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/launching-screen.svg b/ui/images/launching-screen.svg new file mode 100644 index 0000000..30f5a78 --- /dev/null +++ b/ui/images/launching-screen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/list.svg b/ui/images/list.svg new file mode 100644 index 0000000..1be4263 --- /dev/null +++ b/ui/images/list.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/loading.svg b/ui/images/loading.svg new file mode 100644 index 0000000..f19a60c --- /dev/null +++ b/ui/images/loading.svg @@ -0,0 +1 @@ + diff --git a/ui/images/logout-fill.svg b/ui/images/logout-fill.svg new file mode 100644 index 0000000..94ce68e --- /dev/null +++ b/ui/images/logout-fill.svg @@ -0,0 +1 @@ + diff --git a/ui/images/logout.svg b/ui/images/logout.svg new file mode 100644 index 0000000..0d6f3df --- /dev/null +++ b/ui/images/logout.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/management.svg b/ui/images/management.svg new file mode 100644 index 0000000..88aecfd --- /dev/null +++ b/ui/images/management.svg @@ -0,0 +1 @@ + diff --git a/ui/images/max.svg b/ui/images/max.svg new file mode 100644 index 0000000..24ae155 --- /dev/null +++ b/ui/images/max.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/menu.svg b/ui/images/menu.svg new file mode 100644 index 0000000..c71e8ee --- /dev/null +++ b/ui/images/menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/metamask-light.svg b/ui/images/metamask-light.svg new file mode 100644 index 0000000..8e0f838 --- /dev/null +++ b/ui/images/metamask-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/metamask-pay.png b/ui/images/metamask-pay.png new file mode 100644 index 0000000..70841b0 Binary files /dev/null and b/ui/images/metamask-pay.png differ diff --git a/ui/images/metamask.svg b/ui/images/metamask.svg new file mode 100644 index 0000000..949efce --- /dev/null +++ b/ui/images/metamask.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/mnemonic.svg b/ui/images/mnemonic.svg new file mode 100644 index 0000000..ef9b986 --- /dev/null +++ b/ui/images/mnemonic.svg @@ -0,0 +1 @@ + diff --git a/ui/images/mute-light.svg b/ui/images/mute-light.svg new file mode 100644 index 0000000..9c493f1 --- /dev/null +++ b/ui/images/mute-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/mute.svg b/ui/images/mute.svg new file mode 100644 index 0000000..09334d4 --- /dev/null +++ b/ui/images/mute.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/network-activity.svg b/ui/images/network-activity.svg new file mode 100644 index 0000000..524fc8f --- /dev/null +++ b/ui/images/network-activity.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/network.svg b/ui/images/network.svg new file mode 100644 index 0000000..fb18f96 --- /dev/null +++ b/ui/images/network.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/no-data.svg b/ui/images/no-data.svg new file mode 100644 index 0000000..4df6e01 --- /dev/null +++ b/ui/images/no-data.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/no-image.svg b/ui/images/no-image.svg new file mode 100644 index 0000000..e421a95 --- /dev/null +++ b/ui/images/no-image.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/no-message.svg b/ui/images/no-message.svg new file mode 100644 index 0000000..45e6827 --- /dev/null +++ b/ui/images/no-message.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/noeye.svg b/ui/images/noeye.svg new file mode 100644 index 0000000..fda2ada --- /dev/null +++ b/ui/images/noeye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/ok.svg b/ui/images/ok.svg new file mode 100644 index 0000000..4a42c0f --- /dev/null +++ b/ui/images/ok.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/password.svg b/ui/images/password.svg new file mode 100644 index 0000000..f62431e --- /dev/null +++ b/ui/images/password.svg @@ -0,0 +1 @@ + diff --git a/ui/images/paste.svg b/ui/images/paste.svg new file mode 100644 index 0000000..265f8e8 --- /dev/null +++ b/ui/images/paste.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/pending-fill.svg b/ui/images/pending-fill.svg new file mode 100644 index 0000000..cf63a40 --- /dev/null +++ b/ui/images/pending-fill.svg @@ -0,0 +1 @@ + diff --git a/ui/images/preference.svg b/ui/images/preference.svg new file mode 100644 index 0000000..d90828c --- /dev/null +++ b/ui/images/preference.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/proxy-light.svg b/ui/images/proxy-light.svg new file mode 100644 index 0000000..8d7e1ee --- /dev/null +++ b/ui/images/proxy-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/proxy.svg b/ui/images/proxy.svg new file mode 100644 index 0000000..c0780c6 --- /dev/null +++ b/ui/images/proxy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/qrcode.svg b/ui/images/qrcode.svg new file mode 100644 index 0000000..0b03abf --- /dev/null +++ b/ui/images/qrcode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/rabbit.svg b/ui/images/rabbit.svg new file mode 100644 index 0000000..075e0bd --- /dev/null +++ b/ui/images/rabbit.svg @@ -0,0 +1 @@ + diff --git a/ui/images/reading.svg b/ui/images/reading.svg new file mode 100644 index 0000000..cb1a553 --- /dev/null +++ b/ui/images/reading.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/receive.svg b/ui/images/receive.svg new file mode 100644 index 0000000..078a932 --- /dev/null +++ b/ui/images/receive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/recipient.svg b/ui/images/recipient.svg new file mode 100644 index 0000000..6de6f52 --- /dev/null +++ b/ui/images/recipient.svg @@ -0,0 +1 @@ + diff --git a/ui/images/record-off.svg b/ui/images/record-off.svg new file mode 100644 index 0000000..1fb23a4 --- /dev/null +++ b/ui/images/record-off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/recording.svg b/ui/images/recording.svg new file mode 100644 index 0000000..144f755 --- /dev/null +++ b/ui/images/recording.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/recover-from-trash.svg b/ui/images/recover-from-trash.svg new file mode 100644 index 0000000..010d577 --- /dev/null +++ b/ui/images/recover-from-trash.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/recover.svg b/ui/images/recover.svg new file mode 100644 index 0000000..ddd5c7b --- /dev/null +++ b/ui/images/recover.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/refresh.svg b/ui/images/refresh.svg new file mode 100644 index 0000000..d7b4848 --- /dev/null +++ b/ui/images/refresh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/reset-in-trash.svg b/ui/images/reset-in-trash.svg new file mode 100644 index 0000000..2679b86 --- /dev/null +++ b/ui/images/reset-in-trash.svg @@ -0,0 +1 @@ + diff --git a/ui/images/reset.svg b/ui/images/reset.svg new file mode 100644 index 0000000..cc1fd74 --- /dev/null +++ b/ui/images/reset.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/rss-fill.svg b/ui/images/rss-fill.svg new file mode 100644 index 0000000..70b812a --- /dev/null +++ b/ui/images/rss-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/rss-light.svg b/ui/images/rss-light.svg new file mode 100644 index 0000000..0d1a817 --- /dev/null +++ b/ui/images/rss-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/save-archive.svg b/ui/images/save-archive.svg new file mode 100644 index 0000000..46695dd --- /dev/null +++ b/ui/images/save-archive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/save.svg b/ui/images/save.svg new file mode 100644 index 0000000..c8b809c --- /dev/null +++ b/ui/images/save.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/search.svg b/ui/images/search.svg new file mode 100644 index 0000000..731ab7e --- /dev/null +++ b/ui/images/search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/security.svg b/ui/images/security.svg new file mode 100644 index 0000000..d6c3fa8 --- /dev/null +++ b/ui/images/security.svg @@ -0,0 +1 @@ + diff --git a/ui/images/send.svg b/ui/images/send.svg new file mode 100644 index 0000000..e1d6fd7 --- /dev/null +++ b/ui/images/send.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/setting-fill.svg b/ui/images/setting-fill.svg new file mode 100644 index 0000000..e5469ed --- /dev/null +++ b/ui/images/setting-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/setting-light.svg b/ui/images/setting-light.svg new file mode 100644 index 0000000..1899220 --- /dev/null +++ b/ui/images/setting-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/skull.svg b/ui/images/skull.svg new file mode 100644 index 0000000..cd615d0 --- /dev/null +++ b/ui/images/skull.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/solana.svg b/ui/images/solana.svg new file mode 100644 index 0000000..8629b06 --- /dev/null +++ b/ui/images/solana.svg @@ -0,0 +1 @@ + diff --git a/ui/images/speak.svg b/ui/images/speak.svg new file mode 100644 index 0000000..ea74559 --- /dev/null +++ b/ui/images/speak.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/speaker-fill.svg b/ui/images/speaker-fill.svg new file mode 100644 index 0000000..e1136df --- /dev/null +++ b/ui/images/speaker-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/speaker.svg b/ui/images/speaker.svg new file mode 100644 index 0000000..153070c --- /dev/null +++ b/ui/images/speaker.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/star.svg b/ui/images/star.svg new file mode 100644 index 0000000..590960b --- /dev/null +++ b/ui/images/star.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/start.svg b/ui/images/start.svg new file mode 100644 index 0000000..d120624 --- /dev/null +++ b/ui/images/start.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/stop.svg b/ui/images/stop.svg new file mode 100644 index 0000000..23c77da --- /dev/null +++ b/ui/images/stop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/success-big-fill.svg b/ui/images/success-big-fill.svg new file mode 100644 index 0000000..cccfb85 --- /dev/null +++ b/ui/images/success-big-fill.svg @@ -0,0 +1 @@ + diff --git a/ui/images/success-fill.svg b/ui/images/success-fill.svg new file mode 100644 index 0000000..ad79e73 --- /dev/null +++ b/ui/images/success-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/success.svg b/ui/images/success.svg new file mode 100644 index 0000000..a0ce298 --- /dev/null +++ b/ui/images/success.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/switch.svg b/ui/images/switch.svg new file mode 100644 index 0000000..726f4f6 --- /dev/null +++ b/ui/images/switch.svg @@ -0,0 +1 @@ + diff --git a/ui/images/sync-failed.svg b/ui/images/sync-failed.svg new file mode 100644 index 0000000..6f77612 --- /dev/null +++ b/ui/images/sync-failed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/sync.svg b/ui/images/sync.svg new file mode 100644 index 0000000..517395f --- /dev/null +++ b/ui/images/sync.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/test-network.svg b/ui/images/test-network.svg new file mode 100644 index 0000000..941bd7d --- /dev/null +++ b/ui/images/test-network.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/text.svg b/ui/images/text.svg new file mode 100644 index 0000000..6ff9a71 --- /dev/null +++ b/ui/images/text.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/token.svg b/ui/images/token.svg new file mode 100644 index 0000000..e5b8a7d --- /dev/null +++ b/ui/images/token.svg @@ -0,0 +1 @@ + diff --git a/ui/images/turtle.svg b/ui/images/turtle.svg new file mode 100644 index 0000000..ccf1dc0 --- /dev/null +++ b/ui/images/turtle.svg @@ -0,0 +1 @@ + diff --git a/ui/images/ui.svg b/ui/images/ui.svg new file mode 100644 index 0000000..77c7c8f --- /dev/null +++ b/ui/images/ui.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/up-circle.svg b/ui/images/up-circle.svg new file mode 100644 index 0000000..3f522b8 --- /dev/null +++ b/ui/images/up-circle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/up-rect.svg b/ui/images/up-rect.svg new file mode 100644 index 0000000..53a585b --- /dev/null +++ b/ui/images/up-rect.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/upload-cloud.svg b/ui/images/upload-cloud.svg new file mode 100644 index 0000000..9b76b3d --- /dev/null +++ b/ui/images/upload-cloud.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/usdc.svg b/ui/images/usdc.svg new file mode 100644 index 0000000..f297a4c --- /dev/null +++ b/ui/images/usdc.svg @@ -0,0 +1 @@ + diff --git a/ui/images/usdt.svg b/ui/images/usdt.svg new file mode 100644 index 0000000..47b1599 --- /dev/null +++ b/ui/images/usdt.svg @@ -0,0 +1 @@ + diff --git a/ui/images/user.svg b/ui/images/user.svg new file mode 100644 index 0000000..8c951e2 --- /dev/null +++ b/ui/images/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/version.svg b/ui/images/version.svg new file mode 100644 index 0000000..5995203 --- /dev/null +++ b/ui/images/version.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/voiceprint.svg b/ui/images/voiceprint.svg new file mode 100644 index 0000000..bb79695 --- /dev/null +++ b/ui/images/voiceprint.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/warning.svg b/ui/images/warning.svg new file mode 100644 index 0000000..75d447c --- /dev/null +++ b/ui/images/warning.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/wechat-fill.svg b/ui/images/wechat-fill.svg new file mode 100644 index 0000000..e146165 --- /dev/null +++ b/ui/images/wechat-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/wechat-light.svg b/ui/images/wechat-light.svg new file mode 100644 index 0000000..4868a83 --- /dev/null +++ b/ui/images/wechat-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/wechat-pay.png b/ui/images/wechat-pay.png new file mode 100644 index 0000000..1679643 Binary files /dev/null and b/ui/images/wechat-pay.png differ diff --git a/ui/images/zoom-in.svg b/ui/images/zoom-in.svg new file mode 100644 index 0000000..d7c0940 --- /dev/null +++ b/ui/images/zoom-in.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/images/zoom-out.svg b/ui/images/zoom-out.svg new file mode 100644 index 0000000..245f4db --- /dev/null +++ b/ui/images/zoom-out.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/logic.slint b/ui/logic.slint new file mode 100644 index 0000000..0abceac --- /dev/null +++ b/ui/logic.slint @@ -0,0 +1,39 @@ +import { Store, SettingUI } from "store.slint"; +import { Icons } from "theme.slint"; +import { TransactionTileEntry, TransactionTileStatus } from "base/transaction-tile.slint"; +import { TokenTileEntry } from "base/token-tile.slint"; +import { PrioritizationFeeStatus } from "base/def.slint"; + +export global Logic { + pure callback new-mnemonics(int) -> [string]; + pure callback paste-mnemonics() -> [string]; + pure callback join-mnemonics([string]) -> string; + pure callback is-valid-mnemonic([string]) -> bool; + pure callback split-mnemonic(string) -> [string]; + + + callback show-toast(string, string); + + pure callback qr-code(string) -> image; + qr-code => { + return Icons.no-data; + } + + // (password) -> void + callback login(string); + + callback update-cache-size(); + callback remove-all-cache(); + + callback copy-to-clipboard(string); + callback copy-from-clipboard() -> string; + callback handle-confirm-dialog(string, string); + + callback get-setting-ui() -> SettingUI; + callback set-setting-ui(SettingUI); + + pure callback tr(bool, string) -> string; + tr(is-cn, text) => { + return text; + } +} diff --git a/ui/panel/bodyer/home.slint b/ui/panel/bodyer/home.slint new file mode 100644 index 0000000..1f5f4f3 --- /dev/null +++ b/ui/panel/bodyer/home.slint @@ -0,0 +1,19 @@ +import { Theme, Icons } from "../../theme.slint"; +import { Store } from "../../store.slint"; +import { Logic } from "../../logic.slint"; +import { Head } from "../../base/widgets.slint"; + +component TopHead inherits Head { + icon: Icons.home-light; + title: Logic.tr(Store.is-cn, "主页"); + hbox-alignment: LayoutAlignment.start; +} + +component Body inherits Rectangle { } + +export component Home inherits Rectangle { + VerticalLayout { + TopHead { } + Body { } + } +} diff --git a/ui/panel/bodyer/panel.slint b/ui/panel/bodyer/panel.slint new file mode 100644 index 0000000..552beeb --- /dev/null +++ b/ui/panel/bodyer/panel.slint @@ -0,0 +1,10 @@ +import { Theme } from "../../theme.slint"; +import { Store, TabIndex } from "../../store.slint"; +import { Home } from "./home.slint"; +import { Setting } from "./setting.slint"; + +export component Bodyer inherits Rectangle { + if TabIndex.Home == Store.current-tab-index : Home {} + if TabIndex.Setting == Store.current-tab-index : Setting {} +} + diff --git a/ui/panel/bodyer/setting.slint b/ui/panel/bodyer/setting.slint new file mode 100644 index 0000000..be32c1d --- /dev/null +++ b/ui/panel/bodyer/setting.slint @@ -0,0 +1,256 @@ +import { LineEdit, CheckBox, ComboBox } from "std-widgets.slint"; +import { Theme, Icons } from "../../theme.slint"; +import { Logic } from "../../logic.slint"; +import { Util } from "../../util.slint"; +import { Store, SettingUI, SettingDetailIndex } from "../../store.slint"; +import { LineInput, CenterLayout, ConfirmDialogSetting, Divider, Link, Brand, IconBtn, Label, Head, SettingEntry, SettingDetail, SettingDetailInner, TabBtn, SettingDetailInnerVbox, SettingDetailLabel, TxtEdit, CancelBtn, ConfirmBtn, NoDataImg, Tag, RadioBtn, TokenRecipient, SlideCard, ListTile, IconsDialogSetting, ElevatedBtn, Help, SettingDetailSwitch, About } from "../../base/widgets.slint"; + +component UI inherits SettingDetail { + title: Logic.tr(Store.is-cn, "偏好设置"); + + public function get() -> SettingUI { + font-size-lineedit.clear-focus(); + + return { + font-size: font-size-lineedit.text, + font-family: fonts-combox.current-value, + language: Store.setting-ui.language, + is-dark: Store.setting-ui.is-dark, + }; + } + + init => { + font-size-lineedit.text = Store.setting-ui.font-size; + fonts-combox.current-value = Store.setting-ui.font-family; + } + + SettingDetailInner { + SettingDetailInnerVbox { + font-size-txt := SettingDetailLabel { + text: Logic.tr(Store.is-cn, "字体大小"); + } + + font-size-lineedit := LineEdit { + input-type: number; + height: font-size-txt.preferred-height * 1.6; + placeholder-text: Logic.tr(Store.is-cn, "10 ~ 50"); + text: Store.setting-ui.font-size; + } + } + + SettingDetailInnerVbox { + fonts-label := SettingDetailLabel { + text: Logic.tr(Store.is-cn, "字体样式"); + } + + fonts-combox := ComboBox { + height: fonts-label.preferred-height * 1.6; + model: ["Default", "Source Han Serif CN", "Source Han Sans CN"]; + current-value: Store.setting-ui.font-family; + } + } + + SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "选择语言"); + } + + HorizontalLayout { + HorizontalLayout { + width: 50%; + cn-radio := RadioBtn { + text: "中文"; + checked: Store.setting-ui.language == "cn"; + check => { + Store.setting-ui.language = "cn"; + } + } + } + + en-radio := RadioBtn { + text: "English"; + checked: Store.setting-ui.language == "en"; + check => { + Store.setting-ui.language = "en"; + } + } + } + } + + SettingDetailInnerVbox { + SettingDetailLabel { + text: Logic.tr(Store.is-cn, "选择主题"); + } + + HorizontalLayout { + HorizontalLayout { + width: 50%; + RadioBtn { + text: Logic.tr(Store.is-cn, "白天"); + checked: !Theme.is-dark; + check => { + Theme.toggle(); + } + } + } + + RadioBtn { + text: Logic.tr(Store.is-cn, "黑暗"); + checked: Theme.is-dark; + check => { + Theme.toggle(); + } + } + } + } + } +} + +component Donate inherits SettingDetail { + title: Logic.tr(Store.is-cn, "捐 赠"); + + private property is-wechat: true; + + SettingDetailInner { + vbox-alignment: LayoutAlignment.stretch; + + HorizontalLayout { + TabBtn { + width: 50%; + height: Theme.footer-height; + icon: Icons.wechat-light; + text: Logic.tr(Store.is-cn, "微信支付"); + checked: root.is-wechat; + clicked => { + root.is-wechat = true; + } + } + + TabBtn { + height: Theme.footer-height; + icon: Icons.metamask-light; + text: Logic.tr(Store.is-cn, "小狐狸(加密)支付"); + checked: !root.is-wechat; + clicked => { + root.is-wechat = false; + } + } + } + + Rectangle { + if root.is-wechat: Image { + source: Icons.wechat-pay; + width: Math.min(root.width * 0.8, root.height * 0.8); + height: self.width; + } + + if !root.is-wechat: Image { + source: Icons.metamask-pay; + width: Math.min(root.width * 0.6, root.height * 0.6); + height: self.width; + } + } + } +} + +component Body inherits VerticalLayout { + alignment: start; + spacing: Theme.spacing; + + in-out property current-setting-detail-index <=> Store.current-setting-detail-index; + + callback switch(SettingDetailIndex); + + head := Head { + hbox-alignment: LayoutAlignment.start; + icon: Icons.setting-fill; + title: Logic.tr(Store.is-cn, "设置"); + } + + Flickable { + viewport-height: vbox.preferred-height; + + vbox := VerticalLayout { + spacing: Theme.spacing * 2; + + SettingEntry { + text: Logic.tr(Store.is-cn, "偏好设置"); + icon: Icons.ui; + + clicked => { + root.current-setting-detail-index = SettingDetailIndex.UI; + } + } + + SettingEntry { + text: Logic.tr(Store.is-cn, "关 于"); + icon: Icons.about-light; + clicked => { + root.current-setting-detail-index = SettingDetailIndex.About; + } + } + + SettingEntry { + text: Logic.tr(Store.is-cn, "帮 助"); + icon: Icons.help-light; + clicked => { + root.current-setting-detail-index = SettingDetailIndex.Help; + } + } + + SettingEntry { + text: Logic.tr(Store.is-cn, "捐 赠"); + icon: Icons.donate; + clicked => { + root.current-setting-detail-index = SettingDetailIndex.Donate; + } + } + + SettingEntry { + text: Logic.tr(Store.is-cn, "Github"); + icon: Icons.github; + clicked => { + Util.open-url("Default","https://github.com/Heng30/solana-wallet-sollaw"); + } + } + } + } +} + +export component Setting inherits Rectangle { + private property selected-account-index; + + if Store.current-setting-detail-index == SettingDetailIndex.Home: Body { } + + if Store.current-setting-detail-index != SettingDetailIndex.Home: Rectangle { + if Store.current-setting-detail-index == SettingDetailIndex.UI: UI { + back => { + if (self.get().font-size == "") { + Util.show-toast(Logic.tr(Store.is-cn, "非法输入,输入不能为空"), "warning"); + return; + } + Store.current-setting-detail-index = SettingDetailIndex.Home; + Logic.set-setting-ui(self.get()); + } + } + + if Store.current-setting-detail-index == SettingDetailIndex.About: About { + back => { + Store.current-setting-detail-index = SettingDetailIndex.Home; + } + } + + if Store.current-setting-detail-index == SettingDetailIndex.Help: Help { + entries: Store.helps; + back => { + Store.current-setting-detail-index = SettingDetailIndex.Home; + } + } + + if Store.current-setting-detail-index == SettingDetailIndex.Donate: Donate { + back => { + Store.current-setting-detail-index = SettingDetailIndex.Home; + } + } + } +} diff --git a/ui/panel/footer.slint b/ui/panel/footer.slint new file mode 100644 index 0000000..fee204f --- /dev/null +++ b/ui/panel/footer.slint @@ -0,0 +1,44 @@ +import { Theme, Icons } from "../theme.slint"; +import { Store, TabIndex } from "../store.slint"; +import { Logic } from "../logic.slint"; +import { TabBtn, Divider } from "../base/widgets.slint"; + +export component Footer inherits Rectangle { + private property btn-height: self.height * 0.9; + private property btn-width: self.width * 0.5; + height: Theme.footer-height; + + Divider { + x: 0; + y: 0; + background: Theme.base-border-color; + } + + HorizontalLayout { + padding-top: Theme.padding; + + TabBtn { + width: root.btn-width; + height: root.btn-height; + icon: Icons.home-light; + text: Logic.tr(Store.is-cn, "主页"); + checked: Store.current-tab-index == TabIndex.Home; + + clicked => { + Store.switch-tab(TabIndex.Home); + } + } + + TabBtn { + width: root.btn-width; + height: root.btn-height; + icon: Icons.setting-light; + text: Logic.tr(Store.is-cn, "设置"); + checked: Store.current-tab-index == TabIndex.Setting; + + clicked => { + Store.switch-tab(TabIndex.Setting); + } + } + } +} diff --git a/ui/panel/panel.slint b/ui/panel/panel.slint new file mode 100644 index 0000000..ff9c7ef --- /dev/null +++ b/ui/panel/panel.slint @@ -0,0 +1,18 @@ +import { Theme } from "../theme.slint"; +import { Logic } from "../logic.slint"; +import { Store, SettingDetailIndex, TabIndex } from "../store.slint"; +import { Bodyer } from "./bodyer/panel.slint"; +import { Footer } from "./footer.slint"; + +export component Panel inherits VerticalLayout { + padding-left: Theme.padding; + padding-right: Theme.padding; + + property isShowFooter: Store.current-tab-index == TabIndex.Home || (Store.current-tab-index == TabIndex.Setting && Store.current-setting-detail-index == SettingDetailIndex.Home); + + Bodyer { + height: parent.height - (isShowFooter ? (Theme.footer-height + Theme.padding) : 0); + } + + if isShowFooter: Footer { } +} diff --git a/ui/store.slint b/ui/store.slint new file mode 100644 index 0000000..e6ed68b --- /dev/null +++ b/ui/store.slint @@ -0,0 +1,51 @@ +export enum TabIndex { + Home, + Setting, + None, +} + +export enum SettingDetailIndex { + Home, + UI, + About, + Help, + Donate, +} + + + +export struct SettingUI { + font-size: string, + font-family: string, + language: string, + is-dark: bool, +} + + +export global Store { + in-out property is-first-run; + in-out property current-tab-index: TabIndex.Home; + in-out property current-setting-detail-index: SettingDetailIndex.Home; + + in-out property is-show-landing-page; + + in-out property is-cn: setting-ui.language == "cn"; + in-out property setting-ui: { + font-size: "16", + font-family: "Source Han Sans CN", + language: "cn", + is-dark: false, + }; + + in-out property <[string]> helps: is-cn ? [ + "配置文件保存目录: ~/.config/", + "数据库保存目录: ~/.local/share/", + ] : [ + "Config directory: ~/.config/", + "Data directory: ~/.local/share/", + ]; + + public function switch-tab(tab-index: TabIndex) { + current-tab-index = tab-index; + } +} diff --git a/ui/theme.slint b/ui/theme.slint new file mode 100644 index 0000000..d14a9e6 --- /dev/null +++ b/ui/theme.slint @@ -0,0 +1,180 @@ +import { Palette } from "std-widgets.slint"; +import { Store } from "./store.slint"; +import "./fonts/SourceHanSerifCN.ttf"; +import "./fonts/SourceHanSansCN.otf"; + +export global Theme { + out property is-dark: Store.setting-ui.is-dark; + out property padding: Math.max(4px, Math.round(default-font-size / 4px) * 1px); + out property spacing: padding; + out property border-radius: padding; + out property scroll-width: 12px; + out property dialog-max-width: 600px; + out property header-height: Math.max(35px, icon-size + padding * 4); + out property footer-height: Math.max(40px, icon-size * 2); + + in-out property default-width: Math.max(500px, default-font-size * 30); + in-out property default-height: Math.max(800px, default-width + 300px); + in-out property default-font-size: Store.setting-ui.font-size.to-float() * 1px; + in-out property title5-font-size: default-font-size + 1px; + in-out property title4-font-size: default-font-size + 2px; + in-out property title3-font-size: default-font-size + 4px; + in-out property title2-font-size: default-font-size + 6px; + in-out property title1-font-size: default-font-size + 8px; + + in-out property default-font-family: Store.setting-ui.font-family; + + out property icon-size: Math.max(24px, default-font-size + 9px); + out property avatar-size: icon-size + 8px; + out property default-animate-duration: 200ms; + + out property brand-color: is-dark ? #3F51B5 : #0000B8; + out property secondary-brand-color: is-dark ? #324090 : #3F51B5; + out property third-brand-color: secondary-brand-color.brighter(50%); + out property success-color: is-dark ? #336633 : #67C23A; + out property warning-color: is-dark ? #996600 : #E6A23C; + out property danger-color: is-dark ? #CC3333 : #F56C6C; + out property info-color:is-dark ? #6F6F6F : #909399; + out property mark-color: Theme.warning-color; + out property unmark-color: is-dark ? #646464 : #E8F2FD; + + out property base-color: is-dark ? #000000 : #FFFFFF; + out property invert-base-color: is-dark ? #FFFFFF : #000000; + out property base-background: is-dark ? Palette.alternate-background : #FCFCFC; + out property secondary-background: is-dark ? base-background.brighter(20%) : base-background.darker(10%); + out property base-background-drop-shadow: is-dark ? base-background.brighter(60%) : base-background.darker(15%); + out property secondary-background-drop-shadow: is-dark ? secondary-background.brighter(5%) : secondary-background.darker(5%); + + out property primary-text-color: is-dark ? #969696 : #202123; + out property secondary-text-color: + is-dark ? primary-text-color.darker(50%) : primary-text-color.brighter(50%); + out property regular-text-color: is-dark ? primary-text-color.darker(20%) : primary-text-color.brighter(20%); + out property placeholder-text-color: is-dark ? #4B4B4B : #A8ABB2; + + out property avatar-color: primary-text-color.brighter(50%); + out property icon-color: is-dark ? #AAAAAA : #515151; + out property base-border-color: is-dark ? #2a2a2a : #DCDFE6; + + out property have-read-text-color: is-dark ? #555555 : #606060; + out property link-text-color: is-dark ? #0066AA : #0000B8; + + out property <[color]> tag-colors: is-dark ? [#a3b3cc, #94c2af, #9ac0c4, #b2acca, #cca8a3, #caa6bc, #a8c085, #b0b2b6] : [#CCE0FF, #BAF3DB, #C1F0F5, #DFD8FD, #FFD2CC, #FDD0EC, #D3F1A7, #DCDFE4]; + + public function set-dark(flag: bool) { + Store.setting-ui.is-dark = flag; + Palette.color-scheme = is-dark ? ColorScheme.dark : ColorScheme.light; + } + + public function toggle() { + Store.setting-ui.is-dark = !Store.setting-ui.is-dark; + Palette.color-scheme = is-dark ? ColorScheme.dark : ColorScheme.light; + } +} + +export global Icons { + out property empty-image; + out property wechat-pay: @image-url("./images/wechat-pay.png"); + out property metamask-pay: @image-url("./images/metamask-pay.png"); + out property brand: @image-url("./images/brand.png"); + out property github: @image-url("./images/github.svg"); + out property rss-fill: @image-url("./images/rss-fill.svg"); + out property rss-light: @image-url("./images/rss-light.svg"); + out property setting-fill: @image-url("./images/setting-fill.svg"); + out property setting-light: @image-url("./images/setting-light.svg"); + out property add-fill: @image-url("./images/add-fill.svg"); + out property add-small: @image-url("./images/add-small.svg"); + out property add-in-rect: @image-url("./images/add-in-rect.svg"); + out property back: @image-url("./images/back.svg"); + out property menu: @image-url("./images/menu.svg"); + out property star: @image-url("./images/star.svg"); + out property no-message: @image-url("./images/no-message.svg"); + out property no-data: @image-url("./images/no-data.svg"); + out property delete: @image-url("./images/delete-light.svg"); + out property refresh: @image-url("./images/refresh.svg"); + out property cancel-fill: @image-url("./images/cancel-fill.svg"); + out property cancel: @image-url("./images/cancel-light.svg"); + out property success-fill: @image-url("./images/success-fill.svg"); + out property success: @image-url("./images/success.svg"); + out property close: @image-url("./images/close.svg"); + out property favorite-fill: @image-url("./images/favorite-fill.svg"); + out property find-light: @image-url("./images/find.svg"); + out property edit: @image-url("./images/edit.svg"); + out property copy: @image-url("./images/copy.svg"); + out property paste: @image-url("./images/paste.svg"); + out property recover: @image-url("./images/recover.svg"); + out property backup-recover: @image-url("./images/backup-recover.svg"); + out property recover-from-trash: @image-url("./images/recover-from-trash.svg"); + out property upload-cloud: @image-url("./images/upload-cloud.svg"); + out property download-cloud: @image-url("./images/download-cloud.svg"); + + out property ui: @image-url("./images/ui.svg"); + out property sync: @image-url("./images/sync.svg"); + out property sync-failed: @image-url("./images/sync-failed.svg"); + out property proxy-light: @image-url("./images/proxy-light.svg"); + out property cache-light: @image-url("./images/clear-light.svg"); + out property about-light: @image-url("./images/about-light.svg"); + out property help-light: @image-url("./images/help-light.svg"); + out property reading: @image-url("./images/reading.svg"); + out property feedback: @image-url("./images/feedback.svg"); + out property donate: @image-url("./images/donate.svg"); + out property send: @image-url("./images/send.svg"); + out property search: @image-url("./images/search.svg"); + out property version: @image-url("./images/version.svg"); + out property download: @image-url("./images/download.svg"); + out property hide: @image-url("./images/hide.svg"); + out property loading: @image-url("./images/loading.svg"); + out property crypto: @image-url("./images/crypto.svg"); + out property recipient: @image-url("./images/recipient.svg"); + out property history: @image-url("./images/history.svg"); + out property address: @image-url("./images/address.svg"); + out property address-book: @image-url("./images/address-book.svg"); + out property eye: @image-url("./images/eye.svg"); + out property noeye: @image-url("./images/noeye.svg"); + out property close-eye: @image-url("./images/close-eye.svg"); + out property account: @image-url("./images/account.svg"); + out property switch: @image-url("./images/switch.svg"); + out property checked-box: @image-url("./images/checked-box.svg"); + out property mnemonic: @image-url("./images/mnemonic.svg"); + out property pending-fill: @image-url("./images/pending-fill.svg"); + out property error-fill: @image-url("./images/error-fill.svg"); + out property success-big-fill: @image-url("./images/success-big-fill.svg"); + out property security: @image-url("./images/security.svg"); + out property developer: @image-url("./images/developer.svg"); + out property password: @image-url("./images/password.svg"); + out property reset-in-trash: @image-url("./images/reset-in-trash.svg"); + out property debug-light: @image-url("./images/debug-light.svg"); + out property add-light: @image-url("./images/add-light.svg"); + out property management: @image-url("./images/management.svg"); + out property airdrop: @image-url("./images/airdrop.svg"); + out property max: @image-url("./images/max.svg"); + out property browser-access: @image-url("./images/browser-access.svg"); + out property warning: @image-url("./images/warning.svg"); + out property qrcode: @image-url("./images/qrcode.svg"); + out property advance-setting: @image-url("./images/advance-setting.svg"); + out property turtle: @image-url("./images/turtle.svg"); + out property rabbit: @image-url("./images/rabbit.svg"); + out property horse: @image-url("./images/horse.svg"); + out property logout: @image-url("./images/logout.svg"); + out property logout-fill: @image-url("./images/logout-fill.svg"); + + out property solana: @image-url("./images/solana.svg"); + out property usdt: @image-url("./images/usdt.svg"); + out property usdc: @image-url("./images/usdc.svg"); + out property eth: @image-url("./images/eth.svg"); + out property doge: @image-url("./images/doge.svg"); + out property curve: @image-url("./images/curve.svg"); + out property token: @image-url("./images/token.svg"); + + out property wechat-fill: @image-url("./images/wechat-fill.svg"); + out property wechat-light: @image-url("./images/wechat-light.svg"); + out property metamask-light: @image-url("./images/metamask-light.svg"); + + out property landing-subscription: @image-url("./images/landing-subscription.svg"); + out property landing-reading: @image-url("./images/landing-reading.svg"); + out property landing-welcome: @image-url("./images/landing-welcome.svg"); + out property landing-language-switch: @image-url("./images/landing-language-switch.svg"); + out property landing-account: @image-url("./images/landing-account.svg"); + out property landing-send: @image-url("./images/landing-send.svg"); + out property home-light: @image-url("./images/home-light.svg"); + out property home-fill: @image-url("./images/home-fill.svg"); +} diff --git a/ui/util.slint b/ui/util.slint new file mode 100644 index 0000000..37aa971 --- /dev/null +++ b/ui/util.slint @@ -0,0 +1,63 @@ +import { Theme, Icons } from "theme.slint"; + +export global Util { + callback show-toast(string, string); + + pure callback qr-code(string) -> image; + + callback string-fixed2(string) -> string; + callback float-fixed2(float) -> string; + + // (browser, url) => void + callback open-url(string, string); + + pure callback text-len(string) -> int; + + // (low-bound, up-bound) => void + pure callback rand-int(int, int) -> int; + + pure callback local-now(string) -> string; + local-now => { + return "12:34:45"; + } + + pure callback format_number_with_commas(string) -> string; + format_number-with-commas(number-str) => { + return number-str; + } + + pure callback split-and-join-string(string, int, string) -> string; + split-and-join-string(input, length, sep) => { + return input; + } + + public pure function text-color(type: string) -> color { + if (type == "success") { + return Theme.success-color; + } else if (type == "warning") { + return Theme.warning-color.darker(10%); + } else if (type == "danger") { + return Theme.danger-color; + } + return Theme.info-color; + } + + public pure function icon-source(type: string) -> image { + if (type == "success") { + return @image-url("./images/success.svg"); + } else if (type == "warning") { + return @image-url("./images/warning.svg"); + } else if (type == "danger") { + return @image-url("./images/danger.svg"); + } + return @image-url("./images/info.svg"); + } + + public pure function bound(low: int, value: int, height: int) -> int { + return Math.max(low, Math.min(value, height)); + } + + pure public function get-token-icon(symbol: string, mint-address: string, icon-extension: string) -> image { + return Icons.token; + } +} diff --git a/win/icon.ico b/win/icon.ico new file mode 100644 index 0000000..540fd62 Binary files /dev/null and b/win/icon.ico differ diff --git a/win/icon.rc b/win/icon.rc new file mode 100644 index 0000000..19b497f --- /dev/null +++ b/win/icon.rc @@ -0,0 +1,41 @@ +#include +#include + +#include "version.h" + +IDI_ICON1 ICON PRODUCT_ICON + +// 版本信息 +VS_VERSION_INFO VERSIONINFO + FILEVERSION FILE_VERSION + PRODUCTVERSION PRODUCT_VERSION + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080404b0" + BEGIN + VALUE "CompanyName", COMPANY_NAME + VALUE "FileDescription", FILE_DESCRIPTION + VALUE "FileVersion", FILE_VERSION_STR + VALUE "InternalName", INTERNAL_NAME + VALUE "LegalCopyright", LEGAL_COPYRIGHT + VALUE "OriginalFilename", ORIGINAL_FILE_NAME + VALUE "ProductName", PRODUCT_NAME + VALUE "ProductVersion", PRODUCT_VERSION_STR + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x804, 1200 + END +END + diff --git a/win/version.h b/win/version.h new file mode 100644 index 0000000..958ea0f --- /dev/null +++ b/win/version.h @@ -0,0 +1,18 @@ +#ifndef VERSION_H +#define VERSION_H + +#define PRODUCT_ICON "icon.ico" // 图标 +#define PRODUCT_NAME "slint-template" // 产品名称 + +#define FILE_VERSION 0,1,0 // 文件版本 +#define FILE_VERSION_STR "0.1.0" +#define PRODUCT_VERSION 0,1,0 // 产品版本 +#define PRODUCT_VERSION_STR "0.1.0" +#define COMPANY_NAME "Heng30" +#define INTERNAL_NAME "slint-template.exe" +#define FILE_DESCRIPTION "" // 文件说明 +#define LEGAL_COPYRIGHT "Copyright 2023-2033 The Heng30 Company Ltd. All rights reserved." // 版权 +#define ORIGINAL_FILE_NAME "slint-template.exe" // 原始文件名 +#define ORGANIZATION_DOMAIN "https://heng30.xyz" // 域名 + +#endif // VERSION_H