From d647e84db069455cf28e118f2174a1507e8ce945 Mon Sep 17 00:00:00 2001 From: Blank038 Date: Sat, 29 Nov 2025 17:31:00 +0800 Subject: [PATCH] feat: Initial commit --- .gitignore | 4 + Cargo.lock | 2257 +++++++++++++++++ Cargo.toml | 19 + README.md | 21 + examples/VARIABLES.md | 10 + examples/default/.gitignore | 4 + .../default/behavior_pack/BoxData/.gitkeep | 0 .../behavior_pack/Galaxy/Macro/.gitkeep | 0 .../behavior_pack/Galaxy/Template/.gitkeep | 0 examples/default/behavior_pack/Parts/.gitkeep | 0 .../default/behavior_pack/Presets/.gitkeep | 0 .../default/behavior_pack/entities/.gitkeep | 0 .../exampleScripts/Parts/__init__.py | 0 .../behavior_pack/exampleScripts/__init__.py | 0 .../exampleScripts/enums/__init__.py | 0 .../exampleScripts/enums/serverEvents.py | 3 + .../exampleScripts/listen/__init__.py | 0 .../exampleScripts/listen/listen.py | 25 + .../exampleScripts/modCommon/__init__.py | 0 .../exampleScripts/modCommon/emodSystem.py | 22 + .../exampleScripts/modCommon/modConfig.py | 7 + .../behavior_pack/exampleScripts/modMain.py | 28 + .../exampleScripts/modServer/__init__.py | 0 .../exampleScripts/modServer/serverSystem.py | 18 + examples/default/behavior_pack/items/.gitkeep | 0 .../behavior_pack/loot_tables/.gitkeep | 0 .../netease_feature_rules/.gitkeep | 0 .../behavior_pack/netease_features/.gitkeep | 0 .../behavior_pack/netease_items_beh/.gitkeep | 0 examples/default/behavior_pack/pack_icon.jpg | Bin 0 -> 46196 bytes .../default/behavior_pack/pack_manifest.json | 31 + .../default/behavior_pack/recipes/.gitkeep | 0 .../behavior_pack/spawn_rules/.gitkeep | 0 .../behavior_pack/storyline/level/.gitkeep | 0 .../default/behavior_pack/structures/.gitkeep | 0 .../default/behavior_pack/trading/.gitkeep | 0 .../animation_controllers/.gitkeep | 0 .../default/resource_pack/animations/.gitkeep | 0 .../resource_pack/attachables/.gitkeep | 0 examples/default/resource_pack/blocks.json | 7 + .../default/resource_pack/effects/.gitkeep | 0 .../default/resource_pack/entity/.gitkeep | 0 examples/default/resource_pack/font/.gitkeep | 0 .../default/resource_pack/materials/.gitkeep | 0 .../resource_pack/models/animation/.gitkeep | 0 .../models/editor_materials/.gitkeep | 0 .../resource_pack/models/effect/.gitkeep | 0 .../resource_pack/models/geometry/.gitkeep | 0 .../resource_pack/models/mesh/.gitkeep | 0 .../models/netease_block/.gitkeep | 0 .../skeleton/invisible_bind_skeleton.json | 56 + examples/default/resource_pack/pack_icon.jpg | Bin 0 -> 46196 bytes .../default/resource_pack/pack_manifest.json | 30 + .../resource_pack/render_controllers/.gitkeep | 0 .../resource_pack/shaders/glsl/.gitkeep | 0 .../default/resource_pack/sounds/.gitkeep | 0 .../default/resource_pack/texts/zh_CN.lang | 0 .../textures/blocks/custom_brah.png | Bin 0 -> 286 bytes .../textures/blocks/custom_dirt.png | Bin 0 -> 295 bytes .../resource_pack/textures/entity/.gitkeep | 0 .../textures/items/custom_apple.png | Bin 0 -> 257 bytes .../resource_pack/textures/models/.gitkeep | 0 .../resource_pack/textures/particle/.gitkeep | 0 .../textures/sfxs/custom_sun.png | Bin 0 -> 6915 bytes .../textures/terrain_texture.json | 7 + .../resource_pack/textures/ui/.gitkeep | 0 examples/default/resource_pack/ui/.gitkeep | 0 examples/default/world_behavior_packs.json | 11 + examples/default/world_resource_packs.json | 11 + src/commands/components.rs | 222 ++ src/commands/create.rs | 183 ++ src/commands/mod.rs | 68 + src/commands/release.rs | 200 ++ src/config.rs | 40 + src/entity/mod.rs | 50 + src/entity/project.rs | 15 + src/error.rs | 78 + src/main.rs | 28 + src/utils/file.rs | 53 + src/utils/git.rs | 11 + src/utils/http.rs | 26 + src/utils/mod.rs | 3 + 82 files changed, 3548 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 README.md create mode 100644 examples/VARIABLES.md create mode 100644 examples/default/.gitignore create mode 100644 examples/default/behavior_pack/BoxData/.gitkeep create mode 100644 examples/default/behavior_pack/Galaxy/Macro/.gitkeep create mode 100644 examples/default/behavior_pack/Galaxy/Template/.gitkeep create mode 100644 examples/default/behavior_pack/Parts/.gitkeep create mode 100644 examples/default/behavior_pack/Presets/.gitkeep create mode 100644 examples/default/behavior_pack/entities/.gitkeep create mode 100644 examples/default/behavior_pack/exampleScripts/Parts/__init__.py create mode 100644 examples/default/behavior_pack/exampleScripts/__init__.py create mode 100644 examples/default/behavior_pack/exampleScripts/enums/__init__.py create mode 100644 examples/default/behavior_pack/exampleScripts/enums/serverEvents.py create mode 100644 examples/default/behavior_pack/exampleScripts/listen/__init__.py create mode 100644 examples/default/behavior_pack/exampleScripts/listen/listen.py create mode 100644 examples/default/behavior_pack/exampleScripts/modCommon/__init__.py create mode 100644 examples/default/behavior_pack/exampleScripts/modCommon/emodSystem.py create mode 100644 examples/default/behavior_pack/exampleScripts/modCommon/modConfig.py create mode 100644 examples/default/behavior_pack/exampleScripts/modMain.py create mode 100644 examples/default/behavior_pack/exampleScripts/modServer/__init__.py create mode 100644 examples/default/behavior_pack/exampleScripts/modServer/serverSystem.py create mode 100644 examples/default/behavior_pack/items/.gitkeep create mode 100644 examples/default/behavior_pack/loot_tables/.gitkeep create mode 100644 examples/default/behavior_pack/netease_feature_rules/.gitkeep create mode 100644 examples/default/behavior_pack/netease_features/.gitkeep create mode 100644 examples/default/behavior_pack/netease_items_beh/.gitkeep create mode 100644 examples/default/behavior_pack/pack_icon.jpg create mode 100644 examples/default/behavior_pack/pack_manifest.json create mode 100644 examples/default/behavior_pack/recipes/.gitkeep create mode 100644 examples/default/behavior_pack/spawn_rules/.gitkeep create mode 100644 examples/default/behavior_pack/storyline/level/.gitkeep create mode 100644 examples/default/behavior_pack/structures/.gitkeep create mode 100644 examples/default/behavior_pack/trading/.gitkeep create mode 100644 examples/default/resource_pack/animation_controllers/.gitkeep create mode 100644 examples/default/resource_pack/animations/.gitkeep create mode 100644 examples/default/resource_pack/attachables/.gitkeep create mode 100644 examples/default/resource_pack/blocks.json create mode 100644 examples/default/resource_pack/effects/.gitkeep create mode 100644 examples/default/resource_pack/entity/.gitkeep create mode 100644 examples/default/resource_pack/font/.gitkeep create mode 100644 examples/default/resource_pack/materials/.gitkeep create mode 100644 examples/default/resource_pack/models/animation/.gitkeep create mode 100644 examples/default/resource_pack/models/editor_materials/.gitkeep create mode 100644 examples/default/resource_pack/models/effect/.gitkeep create mode 100644 examples/default/resource_pack/models/geometry/.gitkeep create mode 100644 examples/default/resource_pack/models/mesh/.gitkeep create mode 100644 examples/default/resource_pack/models/netease_block/.gitkeep create mode 100644 examples/default/resource_pack/models/skeleton/invisible_bind_skeleton.json create mode 100644 examples/default/resource_pack/pack_icon.jpg create mode 100644 examples/default/resource_pack/pack_manifest.json create mode 100644 examples/default/resource_pack/render_controllers/.gitkeep create mode 100644 examples/default/resource_pack/shaders/glsl/.gitkeep create mode 100644 examples/default/resource_pack/sounds/.gitkeep create mode 100644 examples/default/resource_pack/texts/zh_CN.lang create mode 100644 examples/default/resource_pack/textures/blocks/custom_brah.png create mode 100644 examples/default/resource_pack/textures/blocks/custom_dirt.png create mode 100644 examples/default/resource_pack/textures/entity/.gitkeep create mode 100644 examples/default/resource_pack/textures/items/custom_apple.png create mode 100644 examples/default/resource_pack/textures/models/.gitkeep create mode 100644 examples/default/resource_pack/textures/particle/.gitkeep create mode 100644 examples/default/resource_pack/textures/sfxs/custom_sun.png create mode 100644 examples/default/resource_pack/textures/terrain_texture.json create mode 100644 examples/default/resource_pack/textures/ui/.gitkeep create mode 100644 examples/default/resource_pack/ui/.gitkeep create mode 100644 examples/default/world_behavior_packs.json create mode 100644 examples/default/world_resource_packs.json create mode 100644 src/commands/components.rs create mode 100644 src/commands/create.rs create mode 100644 src/commands/mod.rs create mode 100644 src/commands/release.rs create mode 100644 src/config.rs create mode 100644 src/entity/mod.rs create mode 100644 src/entity/project.rs create mode 100644 src/error.rs create mode 100644 src/main.rs create mode 100644 src/utils/file.rs create mode 100644 src/utils/git.rs create mode 100644 src/utils/http.rs create mode 100644 src/utils/mod.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2b6e2d2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/target +.idea/ +.claude/ +.qoder/ \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..647df74 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2257 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +dependencies = [ + "anstyle", + "windows-sys 0.59.0", +] + +[[package]] +name = "anyhow" +version = "1.0.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" + +[[package]] +name = "arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +dependencies = [ + "derive_arbitrary", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[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 = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" + +[[package]] +name = "bzip2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "cc" +version = "1.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clap" +version = "4.5.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6088f3ae8c3608d19260cd7445411865a485688711b78b5be70d78cd96136f83" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a7ef7f676155edfb82daa97f99441f3ebf4a58d5e32f295a56259f1b6facc8" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[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.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +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 = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "deflate64" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da692b8d1080ea3045efaab14434d40468c3d8657e42abddfffca87b428f4c1b" + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive_arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "emod-cli" +version = "0.1.0-dev" +dependencies = [ + "anyhow", + "clap", + "dirs", + "reqwest", + "serde", + "serde_json", + "uuid", + "walkdir", + "zip", +] + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "flate2" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "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.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "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.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "h2" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "http" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" + +[[package]] +name = "hyper" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" +dependencies = [ + "futures-util", + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "ipnet" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itoa" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "libredox" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" +dependencies = [ + "bitflags", + "libc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + +[[package]] +name = "lockfree-object-pool" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "lzma-rs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297e814c836ae64db86b36cf2a557ba54368d03f6afcd7d947c266692f71115e" +dependencies = [ + "byteorder", + "crc", +] + +[[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.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.52.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-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "openssl" +version = "0.10.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" +dependencies = [ + "bitflags", + "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-sys" +version = "0.9.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest", + "hmac", +] + +[[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.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[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.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom", + "libredox", + "thiserror 1.0.69", +] + +[[package]] +name = "reqwest" +version = "0.12.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe060fe50f524be480214aba758c71f99f90ee8c83c5a36b5e9e1d568eb4eb3" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "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", + "tower", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-registry", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.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.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustls" +version = "0.23.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[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.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1863fd3768cd83c56a7f60faa4dc0d403f1b6df0a38c3c25f44b7894e45370d5" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.134" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" +dependencies = [ + "itoa", + "memchr", + "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 = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +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 = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +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" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ae51629bf965c5c098cc9e87908a3df5301051a9e087d6f9bef5c9771ed126" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +dependencies = [ + "cfg-if", + "fastrand", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f072643fd0190df67a8bab670c20ef5d8737177d6ac6b2e9a236cb096206b2cc" +dependencies = [ + "thiserror-impl 2.0.9", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "windows-sys 0.52.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-rustls" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", +] + +[[package]] +name = "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-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" +dependencies = [ + "getrandom", + "rand", + "uuid-macro-internal", +] + +[[package]] +name = "uuid-macro-internal" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b91f57fe13a38d0ce9e28a03463d8d3c2468ed03d75375110ec71d93b449a08" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "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.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" + +[[package]] +name = "web-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.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-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_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 = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zip" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae9c1ea7b3a5e1f4b922ff856a129881167511563dc219869afe3787fc0c1a45" +dependencies = [ + "aes", + "arbitrary", + "bzip2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils", + "deflate64", + "displaydoc", + "flate2", + "hmac", + "indexmap", + "lzma-rs", + "memchr", + "pbkdf2", + "rand", + "sha1", + "thiserror 2.0.9", + "time", + "zeroize", + "zopfli", + "zstd", +] + +[[package]] +name = "zopfli" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5019f391bac5cf252e93bbcc53d039ffd62c7bfb7c150414d61369afe57e946" +dependencies = [ + "bumpalo", + "crc32fast", + "lockfree-object-pool", + "log", + "once_cell", + "simd-adler32", +] + +[[package]] +name = "zstd" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.13+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..e516454 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,19 @@ +[workspace] +resolver = "2" +members = [] + +[package] +name = "emod-cli" +version = "0.1.0-dev" +edition = "2024" + +[dependencies] +clap = { version = "4.5.32", features = ["derive"] } +reqwest = { version = "0.12", features = ["json", "blocking"] } +uuid = { version = "1.4", features = ["v4", "fast-rng", "macro-diagnostics"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +zip = "2.2.2" +walkdir = "2" +anyhow = "1.0.97" +dirs = "5.0" \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..b963a2d --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# emod-cli + +> 🚧 WIP 请勿使用,项目处于快速原型开发实验中。 + +## 介绍 + +基于网易我的世界组件开发的 cli 工具,用于管理组件的创建、打包等 + +## 如何使用 + +```bash +# 创建一个 Addon 项目 +emod-cli create --name <项目名> --target [目标例子] +# 打包一个 Addon 项目 +emod-cli release --path <项目路径> --version [发布版本] +``` + +## 未来计划 + +- [ ] 重构代码,使代码结构更加合理 +- [ ] 更新预设命令,可一行创建预设资源 diff --git a/examples/VARIABLES.md b/examples/VARIABLES.md new file mode 100644 index 0000000..2772a18 --- /dev/null +++ b/examples/VARIABLES.md @@ -0,0 +1,10 @@ +# VARIABLES + +示例中的变量替换 + +## 变量列表 + +|变量名|描述| +|:----|:----| +|`__mod_name__`|项目名| +|`__mod_name_lower__`|项目名小写驼峰| diff --git a/examples/default/.gitignore b/examples/default/.gitignore new file mode 100644 index 0000000..a89292c --- /dev/null +++ b/examples/default/.gitignore @@ -0,0 +1,4 @@ +.idea/ +studio.json +.mcs/editorSave.json +.mcs/images/ \ No newline at end of file diff --git a/examples/default/behavior_pack/BoxData/.gitkeep b/examples/default/behavior_pack/BoxData/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/Galaxy/Macro/.gitkeep b/examples/default/behavior_pack/Galaxy/Macro/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/Galaxy/Template/.gitkeep b/examples/default/behavior_pack/Galaxy/Template/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/Parts/.gitkeep b/examples/default/behavior_pack/Parts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/Presets/.gitkeep b/examples/default/behavior_pack/Presets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/entities/.gitkeep b/examples/default/behavior_pack/entities/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/exampleScripts/Parts/__init__.py b/examples/default/behavior_pack/exampleScripts/Parts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/exampleScripts/__init__.py b/examples/default/behavior_pack/exampleScripts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/exampleScripts/enums/__init__.py b/examples/default/behavior_pack/exampleScripts/enums/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/exampleScripts/enums/serverEvents.py b/examples/default/behavior_pack/exampleScripts/enums/serverEvents.py new file mode 100644 index 0000000..09e5cf0 --- /dev/null +++ b/examples/default/behavior_pack/exampleScripts/enums/serverEvents.py @@ -0,0 +1,3 @@ +class ServerEvents(object): + BlockRandomTickServerEvent = "BlockRandomTickServerEvent" + ServerBlockEntityTickEvent = "ServerBlockEntityTickEvent" diff --git a/examples/default/behavior_pack/exampleScripts/listen/__init__.py b/examples/default/behavior_pack/exampleScripts/listen/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/exampleScripts/listen/listen.py b/examples/default/behavior_pack/exampleScripts/listen/listen.py new file mode 100644 index 0000000..64c789a --- /dev/null +++ b/examples/default/behavior_pack/exampleScripts/listen/listen.py @@ -0,0 +1,25 @@ +from mod.common.system.baseSystem import BaseSystem + + +def listen(event, namespace=None, system_name=None): + def decorator(func): + func._annotation_listen = event + func._listen_namespace = namespace + func._listen_system_name = system_name + return func + + return decorator + + +def inject_listener(instance, system, namespace, system_name): # type: (object, BaseSystem, str, str) -> None + for name, method in instance.__class__.__dict__.items(): + if (callable(method) and hasattr(method, '_annotation_listen') + and hasattr(method, '_listen_namespace') + and hasattr(method, '_listen_system_name')): + event = method._annotation_listen + anno_namespace = method._listen_namespace + anno_system_name = method._listen_system_name + final_namespace = anno_namespace if anno_system_name is not None else namespace + final_system_name = anno_system_name if anno_system_name is not None else system_name + system.ListenForEvent(final_namespace, final_system_name, event, instance, method) + print(event) diff --git a/examples/default/behavior_pack/exampleScripts/modCommon/__init__.py b/examples/default/behavior_pack/exampleScripts/modCommon/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/exampleScripts/modCommon/emodSystem.py b/examples/default/behavior_pack/exampleScripts/modCommon/emodSystem.py new file mode 100644 index 0000000..e53562d --- /dev/null +++ b/examples/default/behavior_pack/exampleScripts/modCommon/emodSystem.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +import mod.server.extraServerApi as serverApi +import mod.client.extraClientApi as clientApi + +from mod.common.system.baseSystem import BaseSystem + +from __mod_name_lower__Scripts.listen.listen import inject_listener + + +class EasyModBaseSystem(serverApi.GetServerSystemCls()): + + def __init__(self, namespace, system_name, engine_namespace, engine_system_name): + super(EasyModBaseSystem, self).__init__(namespace, system_name) + inject_listener(self.__class__, self, engine_namespace, engine_system_name) + +class EasyModServerSystem(EasyModBaseSystem, ServerSystem): + + def __init__(self, namespace, system_name, engine_namespace, engine_system_name): + super(EasyModServerSystem, self).__init__(namespace, system_name, engine_namespace, engine_system_name) + +class EasyModClientSystem(EasyModBaseSystem): diff --git a/examples/default/behavior_pack/exampleScripts/modCommon/modConfig.py b/examples/default/behavior_pack/exampleScripts/modCommon/modConfig.py new file mode 100644 index 0000000..b6d4e87 --- /dev/null +++ b/examples/default/behavior_pack/exampleScripts/modCommon/modConfig.py @@ -0,0 +1,7 @@ +ProjectName = "Circus" + +ServerSystemName = "CircusServerSystem" +ServerSystemPath = "circusScripts.modServer.serverSystem.CircusServerSystem" + +ClientSystemName = "CircusClientSystem" +ClientSystemPath = "circusScripts.modClient.clientSystem.CircusClientSystem" \ No newline at end of file diff --git a/examples/default/behavior_pack/exampleScripts/modMain.py b/examples/default/behavior_pack/exampleScripts/modMain.py new file mode 100644 index 0000000..9c048f7 --- /dev/null +++ b/examples/default/behavior_pack/exampleScripts/modMain.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- + +from mod.common.mod import Mod +import mod.server.extraServerApi as serverApi + + +@Mod.Binding(name="__mod_name__", version="0.0.1") +class __mod_name__(object): + + def __init__(self): + print("===== init __mod_name__ mod =====") + + @Mod.InitServer() + def on_server_init(self): + print("===== init __mod_name__ server =====") + serverApi.RegisterSystem("__mod_name__", "__mod_name__ServerSystem", "__mod_name_lower__Scripts.modServer.serverSystem.__mod_name__ServerSystem") + + @Mod.DestroyServer() + def on_server_destroy(self): + pass + + @Mod.InitClient() + def on_init_client(self): + pass + + @Mod.DestroyClient() + def on_init_destroy(self): + pass diff --git a/examples/default/behavior_pack/exampleScripts/modServer/__init__.py b/examples/default/behavior_pack/exampleScripts/modServer/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/exampleScripts/modServer/serverSystem.py b/examples/default/behavior_pack/exampleScripts/modServer/serverSystem.py new file mode 100644 index 0000000..26dec7b --- /dev/null +++ b/examples/default/behavior_pack/exampleScripts/modServer/serverSystem.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- + +import mod.server.extraServerApi as serverApi + +from __mod_name_lower__Scripts.modCommon.emodSystem import EasyModBaseSystem + +ServerSystem = serverApi.GetServerSystemCls() +compFactory = serverApi.GetEngineCompFactory() +namespace = serverApi.GetEngineNamespace() +engineSystemName = serverApi.GetEngineSystemName() + + +class __mod_name__ServerSystem(EasyModServerSystem): + + def __init__(self, namespace, systemName): + super(__mod_name__ServerSystem, self).__init__(namespace, systemName) + print("===== __mod_name__ServerSystem init =====") + diff --git a/examples/default/behavior_pack/items/.gitkeep b/examples/default/behavior_pack/items/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/loot_tables/.gitkeep b/examples/default/behavior_pack/loot_tables/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/netease_feature_rules/.gitkeep b/examples/default/behavior_pack/netease_feature_rules/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/netease_features/.gitkeep b/examples/default/behavior_pack/netease_features/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/netease_items_beh/.gitkeep b/examples/default/behavior_pack/netease_items_beh/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/pack_icon.jpg b/examples/default/behavior_pack/pack_icon.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d2fa3bcb8404c925e2b3c6d6eb831b23125ea107 GIT binary patch literal 46196 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 IKeK=T*_q1nUjP6A literal 0 HcmV?d00001 diff --git a/examples/default/behavior_pack/pack_manifest.json b/examples/default/behavior_pack/pack_manifest.json new file mode 100644 index 0000000..9cacfe7 --- /dev/null +++ b/examples/default/behavior_pack/pack_manifest.json @@ -0,0 +1,31 @@ +{ + "modules": [ + { + "description": "", + "type": "data", + "uuid": "{behavior_module_uuid}", + "version": [ + 0, + 0, + 1 + ] + } + ], + "header": { + "description": "", + "name": "behavior_pack", + "uuid": "{behavior_pack_uuid}", + "version": [ + 0, + 0, + 1 + ], + "min_engine_version": [ + 1, + 18, + 0 + ] + }, + "dependencies": [], + "format_version": 1 +} \ No newline at end of file diff --git a/examples/default/behavior_pack/recipes/.gitkeep b/examples/default/behavior_pack/recipes/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/spawn_rules/.gitkeep b/examples/default/behavior_pack/spawn_rules/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/storyline/level/.gitkeep b/examples/default/behavior_pack/storyline/level/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/structures/.gitkeep b/examples/default/behavior_pack/structures/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/behavior_pack/trading/.gitkeep b/examples/default/behavior_pack/trading/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/resource_pack/animation_controllers/.gitkeep b/examples/default/resource_pack/animation_controllers/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/resource_pack/animations/.gitkeep b/examples/default/resource_pack/animations/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/resource_pack/attachables/.gitkeep b/examples/default/resource_pack/attachables/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/resource_pack/blocks.json b/examples/default/resource_pack/blocks.json new file mode 100644 index 0000000..9af8c1e --- /dev/null +++ b/examples/default/resource_pack/blocks.json @@ -0,0 +1,7 @@ +{ + "format_version": [ + 1, + 1, + 0 + ] +} \ No newline at end of file diff --git a/examples/default/resource_pack/effects/.gitkeep b/examples/default/resource_pack/effects/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/resource_pack/entity/.gitkeep b/examples/default/resource_pack/entity/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/resource_pack/font/.gitkeep b/examples/default/resource_pack/font/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/resource_pack/materials/.gitkeep b/examples/default/resource_pack/materials/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/resource_pack/models/animation/.gitkeep b/examples/default/resource_pack/models/animation/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/resource_pack/models/editor_materials/.gitkeep b/examples/default/resource_pack/models/editor_materials/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/resource_pack/models/effect/.gitkeep b/examples/default/resource_pack/models/effect/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/resource_pack/models/geometry/.gitkeep b/examples/default/resource_pack/models/geometry/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/resource_pack/models/mesh/.gitkeep b/examples/default/resource_pack/models/mesh/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/resource_pack/models/netease_block/.gitkeep b/examples/default/resource_pack/models/netease_block/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/resource_pack/models/skeleton/invisible_bind_skeleton.json b/examples/default/resource_pack/models/skeleton/invisible_bind_skeleton.json new file mode 100644 index 0000000..fb45f00 --- /dev/null +++ b/examples/default/resource_pack/models/skeleton/invisible_bind_skeleton.json @@ -0,0 +1,56 @@ +{ + "skeleton": [ + { + "name": "root", + "parent": "root", + "initpos": [ + 0.0, + 0.0, + -0.0 + ], + "initquaternion": [ + -0.0000016026669982238673, + -0.0000015070728522914579, + 0.697554349899292, + 0.7165318727493286 + ], + "initscale": [ + 1.0, + 1.0, + 1.0 + ], + "offmtx": [ + [ + 0.026835869997739793, + 0.9996398091316223, + -1.1985919456947159e-7, + -2.22485263889673e-17 + ], + [ + -0.9996398091316223, + 0.026835869997739793, + -0.000004400427314976696, + -8.168171115038121e-16 + ], + [ + -0.000004395626092446037, + 2.3790533987266827e-7, + 1.0, + 1.856222120455442e-10 + ] + ] + } + ], + "boundingbox": [ + [ + -0.007048234809190035, + -7.17939763195119e-10, + -0.012045030482113362 + ], + [ + 0.007048234809190035, + 0.01892676018178463, + 0.012045029550790787 + ] + ] +} \ No newline at end of file diff --git a/examples/default/resource_pack/pack_icon.jpg b/examples/default/resource_pack/pack_icon.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d2fa3bcb8404c925e2b3c6d6eb831b23125ea107 GIT binary patch literal 46196 zcmeFZcT^S4@+dmwpb`a?oK9d1^_D*ir-~Nl$$?kP(d1Q0L%eK@b8Yob5XtumJ>o80Q8@2 zi@@VBfO~Qe0B#WcI^MQ{SwUzu?O_NQ+#cpiDh0JUoJ{ zczAeMks03AA594V8wTfZ077iwIq)0}g&sg9L_s4&IUffHiF@9PA_+=~fpU>RfsqLf zKtV;vz{JAF!My|;!9S5G04mxqBmsbej)I1Yj*5YWiH(7FnHNM7qM_3fabw)RV@XW! z7Q};jH9E6Qnt_o->#Y?ppZonD87!t4?aiqzYdAk?R`~;F*;pMLxt45%09mi@G-SKt z;k!PMnH~8XaXG=S<6HY@cXKP>56tc9*?K-o$g64_oc}JUpl|0Dl9*rJKD4k;2%w^Z z(xP9;goTO0e<1=LHxW80fg3$B22W7*Rip%OwR$#r8Lg(=@5jh!lUT#~wwN%H0$?%o zxAcNSWRuy*=?Wkq)4xUdpC!2Qmk8%yfy-zYeG&qaz@AQw64Ncl7$s#T#u%*_CC0d% z{|TUR{^j4Pb5n-u)^EtP9IHzSh%Z2{RxF8c)$t!)c9LIVI|rK2A{;n0PAqndK7A51 zY0wkdD62gycBV)xe>2%z`C#lEP#ZX|I)@Y##l(#>-K$JS7pEBbLQW)=QH zhxNA6rxWg|$o<=O^@6KdJH^(8g>Z_)4ZG8-dfn**e@Wh#W87Q?9#x}jPw@sHtO=N$ z1Dnov+ll4YeT&uuvWdQ`PJ-0xJyp7qfp~1T)RQ?W(-D(#Nj@gANr|M-owXQalw%>_ z*p;=wEDlsa{&~;84pY99^<`xF5blb7qIfHS6_%={oj4d!fryM){rI|>_6d|<#=mTO zzSCGcFdn{Ql4pLgU69OZBl7Dhrr^m6Da;^$`5ahF{S=+PvQ<(&Kw`<; z|EhMz7%e}z-8_2b9Rwhy-aBPIA9m#qbAy9g-1u8}$) znVkc>p4RwH7~I&tYB&4rTV_w!m{moqDXVV3Uv=W>>LVQ z*QCMaesd0tdRR;oP2%yM&Mfzx<+bn-o@oWDH7_-`_n!krBc?vJGR(^HBT!Qp1ZuksWQO$ti&mq zvX^oQ2i*}{yv2#Fq+r~ogk;Eo!*5K=$q2pnv)d87W6p?8Oc-_NwNX}AKWen(`Df@< zM)NhyRc*S)Yp>QIE*x%~0MxCAWiiizgB9z<+CTfHu5OK05nD)Al>v=_pwEbILIo^; zH)`ox`&rl-iD!Xo4UZMAs%{vSo(!X%E%VZOFK8wvG=qU9R8C~Yros2;tp^?(_0fxTg0YtiOU;afXa_;9U{zf0%^z6aX(8)sK8P27Z#KBH;mo$dFVS|q!Y|Ug;g=+lS z98Dx1b#HzT9Bl5rHS@uiHynFvno|F`%u1|{o0t|F;cv=WL}TXW>o@tNFL|t?jjGf~ zGPCGxWn$7}Q1Fz*e6Q2Vz!$~;C+P_;xhDODS^V38OqJe_r`|;zkNJ7uD%I~ zbT_)$oC9CT^C!BiqK_HQflM(}l^*xN_meVZ53QR{?AjvnCvF_7)<~Wm)U4O3RQVT}I(KaHn+HV6|(Rw4RLo3ze>J&~k15;_!k29rdJrS#=3mjZD{QzM5u)&-tF?%mrL;BtMOw1DNMPZ?SpFIbguvl}$l` z7YLc-9XM8;-tH@r+?Mz>f0mvSsInaR;FM;Gb3QQaF0s-vrs;s0L{xFr$L`pw@_LF> z+vc;XT1S)h`1t6aqXFpgl}I#>yl4DPk~00TCTTu%H`h(}^&E*hozmnL%5ERJ`_;6Q zDmvX9P&OYbowSo!rCa;d4|$#l16LW3M5&_>8DG{=W1#QcQrsy0n_$n+fuQPh0JY-e z#*y5FhkBuz*MQhWb{{*VD0w^gI|aVV{CYVv# zoxq1pZxa+Si?tW%0~PBFo=G%UJbSt0XI|K>Rj1;xbgKK^*#A*MIfZtZ-0ivIvJxlq zwvo!nGnc4Jj}GsHJ!|WM2pLap846REdGfbq5krS`gf?@XY%$ET8RO04FlkiOduWZ4 z=Y4y+&jut)5YU2iKwt2h#JAqJa3$+EYa2z?p531&UiYep=MuXy->BhxKp;nez2zNQ zyhndRoqCcUo0j6KcZ;+~CLR0Hb^3x8m%u!0|Gje{=gg_^l>XgO`(D;r9rwzWUAF>j zGf=O-+mcFlC%Wb`G-u=IK-ex#kcMJS{|a@Vwoz*j**+&cVZ`vm%I z#?*Q=F@16lJYV_efYL;nc#+)$BT1mDscO==?rlr9s@XGbu0`iX0X~t*HK)uLiwY-tmy@XpU-O*s|7=(-V-tDIz=r;^_pQVQ9Hbm4#KMt3bf2(+X*x>LWVQP-oU+{J1 z+DRmAy)kls@ErK$E24;c8{J-7vGLOMp?B33WHQ7pg}cZ@9U;G#KWY=$!t3&w)qDk> zv{5uJRdMe-8chSs%TiFc4Mnby`*?-CggES-7b3{eb$03 zV^gnsto!u)OH0}Nl-RSvB?Jm~{BMcE!?s|Btdwg_Az>`y)qLIchj>T$XVUANO$EEq zYH;NgqTH7x7P{2bDqc()UCn4}t-gQutm$ZU=`5xH%+35mj1W#->3yTnb3pj$&N)zU z7rZo7(xJrx65dOt>w$~xlP|{2CUSd%_18Uy)pw~JFsZ*t%5G>0)U{RYdihmv*n%sa zNF5XI%Yx8RT{ah8E}3g@$iHCCR~CP-RI`S}L4=hV9x6^=$_A_naLO?^&igO!j>NhT z-U{FswsM!i)%JW-ZgYK6OUbBStbkLjo6yLhey;4hNBbaNsqfC3pZPi9Z`N8-eAL)e z{HaiAn)?}|!JxB{f~v-=qIVRWQ$xBF=BbflT5VPy(=YM1H=X9^KFu@Z4Pxp+TqS7wo-+acOTwcy1LcU)4Fi>~Hk$jK>7yfyEQu!!$sBoEzKS@x` zzaA$j(qV2-a70fg&~Nlew0Wv|#?h31OBq@h_RODDB&Cqow1{gyozH#QHL#6SEAQ2( zRmbfP0(R?0G8(}Om&)47{#`v7Z-;6}HwhuTw}g?zl`*k?Z&|zCfY?P9$>P0KXvDpf z&ePA-UmcS?5@<5D12@*ei$J&U?6zc^o=TGZ4Gjov^|*)=?W|Ip6R)9JuQr8` zLrSL2b{ZE>7H%@e4A{TqO&-E_Mfb^9Vq~wZsAGC}-{V%VItu)2+x>-xch|nCq-xBU zMeGYRvDHg%c?_sPI~Kna$pn39-ynZv!+Xf?wYX|`>SHyqhnVRfYijgf^8P#!w|G+M z{k<3dY!?5na}Lu2;R{-TXUfk9E& zOVf-b@OsOdOa;U2JKB(aTcaR!yk)wT+^AdofNd_6Xli9a*9w6332DcKL-`>6Q3p=CzQ|(L={~xTl_ZMMzfiC z7W^tuba&L*>pQF7_})-K*`o$rZV@;>b+Fb(<2jIZ4!j{%hiNSv&Ysq@tlsk&-cQT; z-YEdyfdyszL@l<_Oh|xt)TClGy8{O8+MIN65027gz8ukLWQ>X%RvC??N~DV`bes&C zecRAD_5hcZYtJSPo!&VW95n`;t2w>))Q$Gk4oOS!4KF=PDJQ)KV54H)Q{uFzSzvVc zrlLCsg4@s5%;xUilWDy>Im1&m3acENv@WSV2h>L?O=hoUP|To)HcHJi10D zLrw(v7-YO3*y6Zj;2lEgMI*Rx#?BaouGmkFt8(Z0zdSHI?$Q*d$&?uL;VWFpWAAiL zI4pm34upVrUTCG@ofqE?p%!K>F>Wg5#nz5~xtQvKiC{aEWi%SSXjRJco zcLSr%m-LIc!;2%V$*;8mgOynTn$+OELPS$yNbjqWkVjqdyjtod@TlIZp)>y|y}=v& zpHln!6cy%Z_SGXVGf)N=1z3TS>DvaL5B=5<@*!Wl{nYX(L{DWrv8U5*9Z~m5-$A=u zw17RMV&ojS2j2Du3e|+KQck4V7d6E5~sF+)p6u+!hh zU8fFY#Jb#GOE{@?4ulVV_}F6Go^uX#9n%nzKOujZSU7vCeN-FgW!$%nCsy~|Q8GaI z<(-NXbAMBx1c9TF2T-?jpgTRQlIDq}=o9?slKZMyu^+y)HaW-aTApzn0lf8$hrZ2+ zp%wc5utNUU=@i8cNR{YW)XR#q&>Pc2SV|fBXAgru%$~hCYBDoxTU12fBu&Q}XsYj5 z6dLx#{S=TewZwzJp!N#9#0?gf`9{(xEqRMfO>0L6`d0Cm95!aVS7m0jb}!1T@SX#3 zQpIhV-P|+Qc0|;cPnb%ImwxpcjQljc)`j*QV4wUv2~HvXa{#^WXr-iJ)Ku+q@jd=< zdjQ~bGV0mYiP3SN{}4Ae=O3~dm2G=%2IbCGQ2p|a$gPFI|Fm=RFJ|-C#*4=J$oU%O z>%Vpxc{#WMA!#Kwbf$~VE`p2vZ`lP-L7bF5%zBszr(Sk?(i?-Sh-be~*2L!SW68(cG#9iIe1)?Ko zpaX(_boQfxraKH~s|`VTxN2BAT7yVJ;5Oh0cmQw!0YCs+z~&-%1>8Xx1h4`ukxT(x z*Wc~H+66;tX9V=8Y?rM(9Gnpj&Fq3~^_v{m6Jm{kxyxE2ERiF)5K_}l6aLFS zkYyw>ctnZ~s6uRiu=$s6b-;b`|J1Fvwet_Srn|M2A(F#IBCvLcx$4_Pz>^Ewssq&S zm-_IK2rW=1X&3?lb8&`2?S3}7{0oB=;cxIOzu;O9cJ_ZqT>6CoW&2H!oHb}`KV0 zXs{O&>|H<=0Zv<65aSHy;GRF2P<}!(pC$i>@La%+!2A~t{{;kT`9C2SJP*J+0Js9c z`F~7ki%9f;M4kWN;4XB5jpY4n9->Nt!vz07^+t^>U3e;f=#d;*MNqn=UMJ;qLs8%f^NB{|Qlp+x_#>f@$fD(6O}p2Nj+* z#MxN~;*C&(E9$7J{#vrIe}Vr&jAIXT_r2}xVE0Q?_&)}(_zMgw0LunqYw2;ZgyMKY z+!6nQT<;h7pX8UU>||ihF!#SHm+%LFX@%biq>j~LP^7ML5HMHpq6~-peT~9(1{bq` zgI>0}Sp5DCehECq_Ww$LG5>BNI|43)e^klMi}H`TMtD(1`LPzEBfXtJ3>xL46_Oqx zegkI6sq*~CALZM{WCTDz;x*7O_{VSf$8Y$@Z}`V=_{VSf$8Y$@Z}`V=_{VSf$8Y$@ zZ}`V=_{VSf$8Y$@Z}`V=_{VSf$8Y$@Z}|VI-|%8Dj}F|u0{~O-5AODXjy%u-X9K`M zR~yp(rU}@CWd!(#Uz9*60q7L_-&4>6GT@IE-~qV6EqOj9;~#s9KX&c00Bo=$@RjoO zDLg)V1j1E>lM@Q(utdg6a9G1!IK3@hIk`EwH~}$9Z&yoeCkTSp3Igt0i_>q^H`CKP z*of2X^Q&>GxynH79Ta`tA=Lx9~H8KEI4%)!ksASf)zb`i0`$tA?e z!^O@eEW*z#!o@@TGtq;+x!c%^Xvxa|>6gW$@tX>RIQrYe{S&Wyt%mi z?gEaG^8|XnBFVqDa3ATWoyIE%`GUzZY3ZLVHbu7^Kx+ub8%Y>L4I-j z;SaKO{ySHsR5l<-h&7LukfneSyD+bS6+0iq%9hG zBBJO32T!2S&sm}kar;?vcA&km3=vCfq^Dh+-WqwTAvW|s!4CgHAOBU)KihkO{^9@a z+5gcy9A=B~vUG>swgYwd-fj=7fqk;b)Y2dFXKnN7P zweSL;@4)zT=8LB`z(xxBXo&`pprc{p{&>d@1pG=Dap^yzzW=Kn^{<5XJN>OCG71~@ zH{!o7oVS2+=_qU{Y-lK8Aoq{B^j0uL9U0t@iiU!G;Qo=oSab|bG;~}PR1k>7{DlHA zvCuKF(NIy4(dfuna7<8;3p6?^8U`kSf>44c8dOv) zG;B;PFw!0D1Qi7hoe+bL2;ja=Pka^g4v#beEtjR676XY?kd?a(V>GWeoQV`mGxL6o zwQE*vHlM6cT&tX}{2&n+Esu(N1sekg6YD}O6jU^TkPe+28Gs%HM!&!9A)*I)ZSoK^ zU`S0#YhBf}iplDo=4Iq_-EzNQ-XilLHk*VWQ(J%-47Nu@L&ZSy7o+M{Rlco17q#M_mEH~-~3e4|LNg&Zv<69qCH2k9p8eR|KGV`sf<|Oo$w41 z-mH}n{QM%#d7ppm`QN%h6(3zWgC5JIHfm_3lp3lDtRz8S{S6PW+&#M$?=@gtefOgmBpBVX4;m_25_T)uH z-E^r9mArp&NQcjfM!+T3clSFt_Zyman_|j~Rq_6M`4+fdjnF3vb-O-Qe%EQXNwW95 zw*|gn_gehJ4}9|JuSzk@1-DPm?g0;S$;DucM}dZiXM+`*Pq>hM;m;kau_bxhn^smj zCAWcJmjE?vW9crQKkt`p_{F6>>!^_K2}g=m?Z?UW_>IbZSh^xNFD%!PM~-&B-TFQVNxI z(lPTTbNbj&`4=pOuNM0eW*(4~wpWucmhdvmT4x*l+2U9fhF!O5Z$Tdkjyv50P(B>^ zs=1~0>oyGpYK(U2sq;2Xmj>b#@YZg8O+8(jyEF!1Qtpv3s5vKj^}4!Eum zplkRRK4h%XMJB+rntoCqi8ws4O%)J`Iv{s1VTd|#T!ONOWJa; zKj1xhxqfOcaG%NdrkP4!O4f1d^L3d;JpFh50I%6{@wV}E$9up;x@KdsES?sYPIv2J z?pmZvU3_XU-}s7?&Y<8YYu{6nt!|kQU&WIEfO{otnHm%o0Hxc{;-u(`|h zd9fN_jx%VcHj*+r&$`@)e6MJBFXwz`CsOoaSiBUy(MfYT`W`?dP8HbwimgHx7^3#8 zLflU(yI06t(}e30Ou+V#Lk>dcu0nhz+DxPlb_Bk5yP#cGJAFN7X}2o2oL70Z_{~^= zNqvbfj2l2XX_j#I(@terYXZ=sw|4uM1-dE;gk`C2_Cg?gdb?c-*C?t#R;N{!=H3GU zn$DfMo!Y~wzTLy-O2+R&#;&v+X?DD$>lXFk`=(B~Ob<`BVnTS!mD@Q?Ptq;(G?;o%34cn989Z$pyLc2rq|sWeYIwvnyiHBCqOni{7t zjg(9y)nYy(wkR@NdYRM&WV?^QbTNEOMGWyvUFyx3G=(V|AvD_%smiG zpLSNbKwKf*k0b@qDlBG4eUA)nrnJ=4%HKWr?8g-wb9!^6I{i5kv^D~eMDp^z#pJLD zA2-AH>pC(5Uq%Uvfbqy1vj7%%#LA?H;kH>Ugj2zDN5{@%^~4`>8cC&>{=U$;S9t2^ z1W@fMZtpRt+!aE0W)-ETwVU@TxT`0ke~DzGGkUH1#>~>{;psNDxql+ojj^5M?-CL< z&KcJ>+)6_k$zN!x<${LGL3X1R0LU9}8ztK*j#z+T<+HB#e1UwYOLXxqB~0k<^#uv7Zg}7LvzmU0%KmkcmODxMM9CBh)VuG0Rsz= z24&&kv|+$`#^A*zBk6wUAAA9{+|^eVS}VnijW01Hyo|m9fFBKw9yJYZt?ui#y#e?$ zL8XeHqyTV2uY{L}9dDm~Wxk@=&Kev@YKdg&-2uDKt?`CE;)(BK{=Y9^f!8qP zMmGuu>KRMbHj`0e&~b1c!HIL~-8bf_Wu1AbnDVk8tSj!V&MADAz;J%7a|-!RO|tqe z^pMC)BWV2KQLTGGqFPi^os_)Z3gHVQN{u({CXMQaEU+=A7XymhBoq2jk(tgm^Sd7J zx5eja?n?TlH=r%}WItuMPwPldOZEc3rQhbIoYIg9o2jEcGL?xi*4zycVHHZoBd-Jr zvp5nt8Tm&emq%`OjRi5pkcy&Lt3ZW%S56vzOXpP53VB1NzbuQ?;!TH&JA5{o6}&V( zI$f$MzP2%!aOP4l#M9j=s3LKU2+%CkGI=phTM~WPm72C+Ej#~Yx#hVtA*uc9{&hYU zDaBy+b;8_^0gL*o&bTXFm%7;u)*Ux)YbX!qB+m+qu3hQkRQc%f*(&~)cIA5$%hNZP zqeclH3Ph&per{GJYV3+j!8t`Sv|zNUi1uOOd3<$twK!4*{c^=*)Kt36Qh60$xB9*6K6)zwbfu|DO=nJU$7 z5H?R5^S7k5af59$Hfl#P<=Wg}gh$kr$ZxOt7NY19zik`!p?vVRY}?wkJ(7$){K`J{_d3STB`D3w%9HTl>g+|;W-+6l`1X{_`o)*w zr+7x<9nZ`{g|CpPEoLxP+;G3{vO`8z*B36DJ}FgsKeD|h4E4#gZkVPb&wIaD1wGE2 z(|mMI!Ygy=Oq4-AZ}jDHBDUrV3rSeoLr6xOHLJGsNxKxsUyRXVn69}~Cd_SIm%g#r zM6&hmnU12SZ*_Bm(Hya$?IJ<>J?89n!eX9Cs~L}K$UYW8p*@J>#FrR#c~sEug{N0@ z0>SnZ24?+NLTK#|p=yIgjVA4IXsO=%7D?%zQwU`KY)1eeR^`g0M`U&7xGAn1AK|9K zjb}_nrZP)Hc}Xo@eVli^P}^>u`5mqWw|LeAg73mdY>G$vYT5}L{LC|_?eB{j{lW^E z1n^xw4bdsx${}71*^Eq`C7Vgy^oEB;nrKt8mn4El7c5TosSg#6R_7jr@$aZr6htOv z%GpmWD>c4`eI}!^-fD;LT(1rFiVhD>O!mYN;)wB%6qpVrhTq+%A{W0uWcj*z=1%w+ zzi};R`-%EX4_C%omy~yup`>Ig)j^TvJC~NN#I|2K@_%Z;e^h(z6WVBFlB!9UkA%Ko@)S+<%COj{f>Xwzy9>r~ZW&6PqwT&8`u(zeMX&z=6JqEOTNUanJ|Luj6nSe909VaUP89ya*h5jw552K^}X zns;|&K_9r9Kop8^9c1m*v^WZ6sMY3Kg5< zyq~|oQ>%Bs0Bz3B=~b0xvBZRmgErraT3~sfdef{Rv3cG;%GxIzNI;4~Aw!q4=F3=P z!JwNM)@NgM@hRVjN;A#@{u$~~8Fies>D12(oBLGl-w5xx*`KLiteU7lR?Vmo5f#c8 zN_3oDi|co>xlaw9%ZJw>uda&Wzsc_S@+eoy$i3g_TKEAa5x_?|m}X&}d_J+?xEn-n68lKc=ABdKn=nY~qu>DD zw{jK&ZtWBfoQ8BG6UCax!{xLoBW`V9)fcRY@^G)E5%Dtf5W;SgP2D0DD-=EPaK^(c!=T7J6h@VPs^~SU%wunu2Ru-uZtt5a=@>oCz|=RsyF-8 zJEH2*Q<=rV!x>zOeK`?dR4sy5zpCAO zgxTq1>@1Wij!jKUwE-7*^_!R$VJ|C?nczQouShi|PIGwe;Cj!q@VJUNJ4dPv4YHVy zy($=mHie^c5vDkoDV{*c9Xd_@fx6kxRU}f?S7{$S?2d?${LuM3plPkTt(&4k zdbvb?b*8?GK>V&3MD$39sfNt$e#kBEj5X`Uj1u-rg#3Gwn~OjhwIJe$5CDM|6bvr#pHkD^f$9c$0*5Fsc<#Y1cnRsGe_f`uN= zIUFv{FQ%o?TS+*=3TS{7MJLNyZTgt;M7lypgW?Qhp^ek^+Lwne5!ya;j{%GPw%Z$8 zUameqr}%{yYispvyh&qm@S1ogqh;+b2C`e^6T&u+U{o~<`IOa3;3p;4%7wbbq0WxG zinYZKB8!QvJ#G7r5dX!2Ogx80p~S7P4;{C32J$6M(qWP$PV&x|0xGr!S5MfV`JURk zeUcMV@E&J37?%(i>hh&ZbxANBvij!L-?V14p};g3!Twy1ZXY+W{?z7bLQc?j%0y-1 z)%IEQjaDTNwzf2v?34u8;MSE#{!<@m&I znv&5&vdco*k~O^j3|Ux)ck>==J_drADP z<3R>LwWrN?(;43_&S~0NvXtN>Ubk=g0*ufyI)y^|BpX|?)y~^>(`r#T<=pY z4el3Nnap!3y-n}lD3R)x6`0Ercu~;^r`nzmrooBlO8=&1gHd+bqHWtzW8vPXCIK!P z+3JKFvAg~(hb@o36?rLh-}~bH64PtgzbCc-LCAyVjBYgUZ)sQa!X5oZ_RNRw$a9e^ zBx48f(k4*C8EsN9@SB$KtTc1iYJ9MGUERssA2J4f)U4dNW4EDRz9R}*z;aEXh_!yh zkcQFaTYJAQ-?Q2LzKb7Oi=MS#E4xdfJ6;&|N{QIKf?N%>og_$ms?o{!=|h*UTcXl+ zQW$n(LPfaYZm&h288j;dk-o}^$GN2N5G8qq3lmR?e=nCD4?c$te?sr5vbI9^P9;>V zl3X5O?qb4Lv0q9L{9Xsn$1`It2p%aSmnSdC3u%i#3My?)kZt%ST3 z?awMTPg^%j%XY8yzh-I`nfU7UoXO$#u0%2WiQOFcb#STeK))K<6?_i7TrDljed4!k`jV0KVD_?VK3xf#aUOLmKN=TR{Bo70zA5=%9>jbeh~6wR)9F|)~PMET2*gQD`D*jM9AIfmNkeV)u^dW3F= z+a|q()g)ss)l{0BFB}*_U4$4VU_sqzbOPgSygIZAjO0_}u^FFg&#}_Q?zVe=hHYTY z8bgMvS_vcVX0q<}^>tMxexxlvcsw~mR2J zK~ymyWmj~syQ3vPFgaYFrG>goPuyyiX@fH1DV%gB5>{qTHk-cMG4WiIjceuBe6kGt ze$KmHn?sEadWKU5(?g)wenmRPJmzeh`NrzuErV{ov=xWRr;rdu6NHN8q0+UyuJ(3s z$Ue9^V)?e|438Bx`(u+RR^4{)kqE>c`3z0P*GGe~%>%~_?j z_&PwQa3E-{2wR3NPc28${jNPVudF{2ge}h}K&D_&19A!dTXizg>+3n&ETxhpy_mGN z>P3O{nD*|au3z6+@*loh&MwepjttY8@wy0W+!i+ih8CqXtc|BS>Di5tGyk%nX#YNdHwL6K1aL2PnvC;EP z$vwd8^~03;)CB9`_ob)-{n^_S+6HFqv61*EJ4r+Jx!mW#!Z|P@-!Tn-%%YI^r3f*$ z&vNnz3PrijM#}w-d_4-==hYOtx4vtOB2x7@6c!q~>tSO~YleN4s)-~!ksq)(S&H*f zrRG0KTjB8gzaN*oUSxZJ&S1aGY|W-RjFCW2Y*%+bXDlz<+at~^5S_Q1?Hf~tNL_1R zk<~6x-9XCuz3hhb^Q#q28w~~iGB*@;GHVU@+v@9J?H&elq!HN;J`jo1k@wlr;c1)$o#O9l^7U%f{Z&p@{EOKZ`@w^dcO3q09GM3u7 zZuG;i*L**t&Q0hw&YWfqrksi-6;(HktjOw~1G5g>y(J_@4P+(jIB()3r8}4MdW&=R z%Gp~A_JY*1?ZdLf-rhWsdUAGy8yXYEg>JWwOUIk4e37cv_{px}dMtOm7Dd zi~FW4eRsUK#j4qyMfBdZaj@M8woOv^D$bM-JMle?CK;#OT1>I7>?BW;-AFp3(}!)B z30gxGmKQ|PO#Ni9nqt7Kx6J!9nSK$y3u}o1wf6j_G&S>wbDeGbyWlrP=dOrL2W3ik z)F+VDI5dAXs+*?Vz3RC?(D*3O)+D~Q;=pt{_x{}%C5QKgPU9%_2LkpAz2f>_;5v_B zQWg5RcfZMgU6?2h9lP#8FnXE6BWHMa{i)!}qk&9+WA=&2?blm(K5^k`YS~z_`Gi&v z?>AT&Qr*}~9s_Fcug87{zu)3-MqW=A@d-zZcYu4AVTHq$pE zHoC((Ef+q>B~9+a<3cYbQyHT1=;3EpGY>=3%dsKrdEs}9b#H%j5gu4h6tC9w?zQEX z;mj|8{UA;w#ay{)zo4(HP@tsOSh1@kxdm(1^oyU&p&G+g492b-(N9Bem(q50j@PKo zSXeHam%MOeH_isWBHX!klyV2OgCuHgLMx3-Zi6>&ggFayr5Y17y&|{|Pe0r5F!xQd z+}4k{=N5k8^Z1U&TnevV&PvEb=HQU({Nh&1v^p!pwQi0lEVY1Minj8R zQkS~@WMNZ$-d2>T&daCd0&soP?eFtFxr(Hvd3!4cY;eKrswq{4GDE(EdKRwX^Gi$h zA3I}e*i+G7grq_m2jjA&YW=b=IY3xR-(#|ddf3$D*Cx}e+~S3^5cQ0(>Jy=j|XDmPgy5yyO%X)_%;^U?7=l)}bdF`q+` zBub>{X@=+Ih=vhEeL*=9Zz}U76ZG3SjSeFIM#Q~u>6fqsGhuo(%EWg+V%zx)m_3Jx z1Vwan6hZ|(7?iun8Jc&DMpy-cZ;(eBZ`JEs+)!$9-eHA>;kp^#kcY-64$V3E#4~@q za)XRSDBH94j!*8l(fTY&-8xvXbDX!weAEthvMzV`j0XcwB+Id+qQde#41-E53MWLz z4JBU(s>^Z<^Q0dRZLb>jPC4#rHZN5(7sx0oj^@^z)E(HeElUPaBVAk$x1b%Ce0WK( zG>DZG7!-$M1ofV32jHE`U8@PqyE9d@j7K2vR>It#G^bh-tngsoda20qLA}|XbAWFp zstx=IS&~3I_+8PxkkLr`253|zHQm*5^NmQsk!u6rt>5pUJdyMjQyAB~U1)Mg3;krN zP>ryzQ%M8Aekj>sM>Pty#i#fU<~D9S z#!aaM-`=ZG_0$Aks=4dfq64pTO*BYDdEcrj7qYGl3nZNkK$OYYZLa#7KQMK@6r0px z%ka3W;nuNeS-aNlH;SV)d(G?q9p^wX_*JKM1+2uNlfJVaY6|ungd%%#{4LQtQsnvR z%*P)Mo0R&F)qXs6{J1~yE}W@hYmEyI8a%-wH@GQDSGQmHtR>Y=+i>>4=fJ5~LdHKD zqQs?@*(!`y{>|Cp`Q0ZIp44^hQx9~Dit@BS((-+}PapME*=s+wM&zT|RVK7sBgsN5 zDxK_vJPxzTYTR!P^+XWwa=!^dtou?6@Gyfrz4zR`Rd30lYdy@z84=nlT+OE*Q6NiU zAhIiwTnil48_wg_bsU?f%QFk|ne9sUz2nZ2yUxQT;=ArcW6IE%uL{Jo3!#eGei5lNm>qcKwfWJZ4K)jm1*l%? zyX?>>LiPF~YE9c^#$4LsgU~Bp2*lK&F4MbaEIC(Pg^_`)BeNUie8yxJVm;Ziy2|y8 zPJ6Avk*?Y+Uo8arnG_~Y7m}+q7deUun*ZKrkSxU`b)Vn#~=hMuX`$W#mDN? z+|+kN624DMJ`jbF3utBWz#Vf8*88%Px8L8-&VTy4v_D%dJF=C)d0R;5iLP$mzVv_z zInj;qqu1L)hp&QCkMi-w?UT8T<_eYPE57J8hox*fi8+)#82F@#)n|NXh=EU%&z=*MTP>Im;=CrIx<(ab{MtkzZCu*;W_*WKb5C&RNe4zdxqU#fC zH1J16OFsGJd7H$Bq~sJ0`k14kwloPf>TxJuNp&4hHY}zz;c!?V1i6v2afe zP2k9N<(FJzJA~7wR8GK|o_(6Ko7&T8?C0Zk){(F3 zc_17IR{n2od*cZU5>+ye*EH< zS`3z}N7ycLYOYjXp=C)Hql;+8E3!^wiz0a$h zx4L&egoQYJf4X^j#2LYZnv{7T<4D|1q;sbsE#Joba!@{dhRPPphx9AaQd+K56_Mm0 z%L5iq?FNo}j=Br?vqN78M3o4o8h$93)Zh)UWgK--Y+(Ai>Z725Po?JoM4IeLjhHd9b?M~ShA4Z>6a&3QJV6lH}h;%{9E7j=SQ?^ojS@mYN0x0 z5yWjQnDx5$$>P0fDk5?(vg6;z%pKf>c2y;BWo_B$T$hIA2zV#p=A}A&elT*&>(LTl)e$Q31&m1rH+^Afl zxF+f5hqxT>Yj@bN;lvNt7iA#9&~ol?JS4Sh8cyW|^no2cKA&GS6p;DU>`>lsIktW~ zH*CJWsNOJDw^U;7*22KcG$?CRAlszQ=#^&Co3dKtl72~N0z>Yt_U+la^p!ZjqR!|Y zQbJL}u=`5(cl?!d$2Oc>NGj{EBtT>x+LZ4oUdP<0DtBvpIwJqBHl9qNWHN6|L@A4v zzd)!e?4ytp{c7tYV}x0Nkqw7IYx(B=Clkb4BU$WO?-A)E0ipyG2IDEcaauyBkmrS8 z)&^Ty0*A()vCywER`1Lv`TGV^tgJ^?a$N8E&^WOUJ1P${BD5@MD!%mWti zMITEKF)2s9R!OT|mUW)iSutwq@M73#_L*&N(vo~&p&LOW`h1<%47StvNYl4*gzaWA z>{Xw$D?P4%s1bGZG_4%OA-wXq=WUkDOD#oj2O7sb*4-7^(J0+f=N($K9**#G40v5L zz91>D%k7Y~H$K()tfZ9uBj-5YN4VZl0CecI}AKVXT>|`1Kd8H`IJ@ zR=9@QLjo}eFcKD12+ZQUK9KuH@R>iG9;k3bl{S{mU8PwCt1xE>v78#NX2*| zG;;G=sr}Oe7LI!;UaUEq`E#6#6>sJEah2$=uZ1$_klhhC;wSn(f|#9oo*hG}P^?Z< z;HhaaFtqjXw)ox`O6T`&V}t@@sM2Vtsx1~WI&_RCWZlu;QYxOV^qEc>C`Dk+zR|up27rw9A5QF_AymNI3%)|)jsV-7b*GE^?)whj&UzNB+@`*+4CI{^s8}JLcgl?Ht zI;If}X<=%VE-TNBX{iE3zVf!%(dU^&i7}VYK4E?>c$MVtttFHMD&vS0!S@xNt~ED9 zb?NV~AHMN%Z0y(6HF`>#x|c4e*6@-Ctsm!=3FEq=V_}^cF?o=)32Cz8VkdgkeSRqT zweHwchkW1O50R8y=Rl1)(TVt@&`%T}#Qn>1(HK74*0fyF4Y~EPu=sueaabZQ?xP4( zwh9Vxj*}>0U3Y(+)A}ehlIuX9knwDTDJs84cwY2oDW!A&+{~-d%~qbiz+}PB_02|K zeoAY_8O^w$F9!^7i`GhQ%<&@BhYw@lo z;@oya*D2Y%BhD%A8y~H~BloC_GKK%G`mCp85_2CD0aamk^qu#wM@V!r2d?xUOjXSD zXw!W%^0sI9Po7yCt{cfs6%Kc#Yo&7WTUE3#z<)L0!zNMZ;As{qKfM=c@I3Jn)I&*) zOF5faEna_bevy8&K`o}QIhH&7h2k}bT>}yA-!o(&y zJ`=LN$;<`&w_%>d9G!0~azwtOU1I9bY{Q#(o3B%*ZRCE64|3sg`@Id-HXI++q~7>b zo?3T5QLn9FR>cz#RwRtCrlXIuq>2ZR{9U(an!=)Nrhbh!*f)t&zRxAPOE5S_U^$#3 zqLwL2%ZRHS{Izou>_)bjja9&Ski)Iuk%i0dTz}{5R~EgDQJmP{(OdQ4Y7Q>SXtFRc z{mWeO;}i1$if;wqK8Gi9je3c2K9fAhJzWu~5v-EK{B>y*KG^(5x^v;>lqU;uuQ|PC z2GN1(=A(bn^UzoRbTf*^nh&h*8q&|e|F|&=*QlOgN=P+TJCS~OO7^rLlDy3Pr5xn) znKI96t}oIGr`FX6e79uhoBQ+dRhwpSY#G0~}cG#aOX z_}jphpM8p9%!q5x^S<-&3w@1ztgD})m)MzT3Yjq471PiIp#?%jFxP;oaaZJ4lNGLR z&{@2{o^ATw+=^E8R$;gq%dV}v`Jy_8lhC2*AApO@d`SX)M_6`CU?RD`Lxq(mXhp1< z&fAz99|F+{!)Zqj1LqX8!885EPZbY4DvZ1tTfBn&%Q=5Anno;uE6+p?3fC`~x8}e` zmrc94+DaA#(>yu}@p{EIU(*5&5KTlA8WMnWH%vtPPElygIU%wFA<5kD3MHYf?vt!s zulb0N8x^kFF_AJIW9INwD_`iV_1C1jJW44P3s(2EK-Xmp$5d+9J`Vg$LT%j{W$Yxy zjuGOJbC2;XaAS2P08}03Rhn$)5?oekC>w4ATZ9&S78FyD+ZG^rR4WMf8XlAeUT&Ty z+&h}qM>IKpG<8;TF5o7c8~YuHb!?4nk1@eYK!Dn3QA*)GamU2H2AmX6eT}gfMd(Rl z?s=2SDy2`5seLR(H@+4q%K%uDQLTvv_ttJ#=%SiadNDphHek{hDa9wgPn%KV?9g~; zwPFw@poCty_5PJ1Z_;y2&LE0Tz^=o)Fs6HoqXA}!f@eR(P}ZO(L&8~B>vej4->pFL z(ZLnp7*+ZJEz^=2I#qx;p}tH~u%4L@`jg3lp|PdHNVs%HlxBOSI4S32QiO*=n-a0M zwr?3*8BIq(QRYRna$JKxqxu1oiNJ!&`w8PJ2!RG(nY(V8a;&#f7gPRieHZS@08#Z= z%30~GstXRWv~#$+zVoq?(Kl!TL+j(_hz4YL#0MI-J%`Hl47{kNYbsT5Z4&Kr2eue@Y2q~0mA7gM-ZO2lk_gQ&TR%^FWoE0X z&qj6Mh@wYFJ6B)c@`yMUM^f$+td2%{u_p}reORpHOp4t_J&Cj-T7j$C|s$K^X5w=87*i}Zj(ppwV5VXTau)>R~8z&20A$6LTzdmeI{K#lO)_JU+= zn&f(v`<)LWZ}rOgli6=_b_uR!~)pNJH?F20~GO9NEP~(3E$HFHF?nW?HjSd1vIkqz$DD>Ys@!d z{SOWp(Mf?~*%l2Hi7b`Px7g!L?XU8W=zhXtQW@&C%=`|{^qsMKdKYk zM#EfvxpE>=g`E0W6WyJ0dJXw7D{ewCV6Gs1tM|{=4N-tJ2~FUM6F%bujuJ^Oya6t*|u%6yLKu$8UKM+@I^e;g4eK%0IS( zwoO(qjgsTn^=i95G%bLu_Y~)Ni>r4KG1V7ykLcfmk7*^}em<>A=WHOk@u|Vke$@f( z)xxEkMxERrFv4w^Xld{KYhh)|D)DjsDUveAjl#}NxWA1@;YPntcGx4E+x$+yFX-2< z(z}e<-)?;oDBtY)!KjZlS0ygAGUh?@3L0vsMKxD!rfzp_X8fD9;tA|bDTaq-cGVZI zYI73vbp*@PZ5C5|C2y*`soE(Lzt1fY*rsuJ;5p#jvN@!Q{7CM-%5B?QlUTnO!br-q zc`d0y5Q9>5PNKK)zwwPLC`V z?774YXJZDr;-Qvw9h)?}ty1{<4!=Ji?TuuUQQ7F>w{Jm8n`f;)QS6Ewju2~}Ag&j- zW<%aCc<<*CiJKmdW^#1uLzqfQh|4D$I@}7xtd*V+Spw+ z<*49OxMe@duHJ}mol-piovgRo{Yqq)2eOus?oc}6^UZ&FF)PvWWIV4+R@rJp2K|Vg=@a0@rXoY54GC1bd{~LS<^mx?U=4s_RpVJ z!tGRS@vkwtqH<(t$1|KLY?|URKO$Ca5GCy&PTP{XqJKwwiR8LrX6_F89+U7GdehF+ z(+=tlYI^6kh_H!e4{ zGTsq*(kaMNp03Rm(f`S-=GmrnjtCa_isiniL-@x7aiZ}X6>TM^+rkp!zmMuqc4$g# z`6_8x?C<_S`jtHuSshExgZ+ZvEN&R{Z`7h@zyEdKpldd!Vs3F1JAF6&7^*eIslN2~ znXkEy_jDoZx28bIexXKwo91aTPwVYMTDX9QPE}vr?UL$YwMSp$bVc8(W|7dZ8 zpT)W{`+zOa%Q^OiVREuj0pD(^H*f8DU${Kp5aVBJOaK#oq;YRL+O7V$NlvY8rzu}_ zJq_RTUwLAegRM$h+Mn1et^&?Ddh0k4Zar%5*4{L#Zuox>1LoIQAA}AAbjxz=VATSL zLj$j@bEKm-I<#LWoXEVuTD*a8Cf6dl2VNM9nN9|tI3h$fMPjEZ@sw2*S?pQK=U{Mk zazl<~Tcv~Lu_%kR%R!NWZK?kC4+=Y3sX5kitV$r`w?ctuTUAzZR7K*%`x5$b-fwfX zu?#0)aVu=PT{`mzT_Gv5huy^oJ5h!CRz8%0UxrLmyPTdx9K%Iuk`Kh}89#yr&!5HS zBO@BF?sm5%WcA+FkSQKu*8e061*7;oMSt`u8!gVS0*BS4Q=yLBaJVxNsFD%u8ye`( z_42CABs9EH8FFX+F3vJ3($H3hx#8&a`u5bnn*ARDE=puVi)yJw#>+$XPXg=9T9Q)( z%C_Z#I-AmO?!aYXPE)17>mg9)Adc(DSFGqg+q({jH!A|mt#dlB8!Af)UD@vMDb3e+ z)VxIbxL#%J;Hh*UTTOfl7rJ^TGWd1t`lCFCuP&X9t?C<#y{ezbGLzSa!<)Bnix~4% zSonAfJ6cG;Wn6tCh$;<9F&A5*xOKw|S$3&76i?U)n(D#%T2tB~mu0G7r{-dxOUBy! zir6f9RV22Kr1);$b`*Qz0=2`QeOqk0y~@+>byEnlaFr0^E-*NLTbkB;4E2zMpd|hd zq4^J>f+khRVqKeGZys0-@YvlbZX<~>vDbEV${U8L&vcuPd{WU57C?aUlR5CK^-0Kp z3JU$&x+?rxF3EEqU!`XJ4wSFRhN81;z921)$Gq@XGJ5W`0fd4AvH)ToFxUhHFXvG0 z=AJ)Ul8CyR{SlE8uz^{*??KeGz$71d3C4@6IsMk2uUL<5pkHpxdd32)1FXE^WfrCW z$>Xf2t77nYLG6^d?IoE`txDzAZmeu*U1430nOQMA1W=wDM+Imr!x4^PaAp<9$*8U` z#K*K3cY`|~n!M7=JfW`OCbjd7_GS6KRQPQTABwpOPBp$Il3)C~+lWtk7~wkPfu)nz zqj93}!XHO$@IuU0a*eoOM0kK~F?Z(NMsH$R_raosXBhH!khpIw< zRCHA9d;NCx3(p{sCw|lK=?}j^llsIyj{7WCnoJJ;3J)_2L#Ui3$pMOcgeF7DE51z5 z%75XvFfqJi4g=DUX4sz|JZ*Q?KNx89*T-tM=&A0+E-dM3q`k>!HdGJz`oeXp zUwI)X^|DM8Wu1-loHroPE(YA|z8=tE>)j%-+ibYSVAnokP_pwi^r26w(*GUMsz96X ztcy_X@<`eIN655+kz9mR9!A`|?4u)s+Eh^GTWVW%BgeabN{)UO997grxz zWDgQsu=IfJ1aTVGQ<(WIaS=KS18yZn#>TO14a6eIOvM znKa-l5yvYqEl5OPbq^nt6RVlcQ&>%i^qQ&=C2fYR_Sy&oW<>~XWB4laE4?B(akGzs zFVYc0IEadH%*|?H;ut ziitYjTLVuY+o(e_aD|P;K3dmq97@a_73n+n;pVhV5*A=mSJ%mg%p^t%hmhV~pP6;k z^nhYps9Mno>G-&eHHS`(x`p8}v2Fa>VpwfMq&Pv;xUH8IVKbVGeQc2K6x6BeHD9zP zDwP=0k*?joWjZRS$3YHqT)G+}sp{%AX+vQVI))@M&xNv-f*B+~&TK-%`0Sh90?B#{){0%mC+rb!HV`lMG zG^2Pd1bNk0%!8dtg>9&2sRXkX~+$HN}Mfr6C)X^I5w zFzXc(%22!gYX3-dS-9T#ogM=o(YRV`z;bpZ*wZ+vw9hg0+hCY9W^DT_pN(HrtO0B4 zx_mpfl(A%SpZ4$rN+T|<(dVE|{7e=)*e%1WyEYN!VRb7J#t0AAa8F4Z4L8zJDc>pf zld}Z_gYLNBe)6rJIC$)^Ypl{uo6qGtBNJjOjGns_+IN&@%bFTAT5Cx9VLEHO?7Ur_$NR z#jS%llbK!YgcQ7(s6)Qcr8r?~pwYp7c%v_~OvfmOgCry5GBIsI>;6O%NX+x8*Jx{?OTdTO?2h{!6r8Aj=B4qO1 zj<#S5JLN$?C5{eMW^y6`Fu{OF!~xFOaKx|$#Qe;v8<++!nU@e0U|a655K=5>=lo!T z#i08^Tao1rDY;uL73=!(JnrO|GggMjOVn2DB|9!s%T1`BEXSt#E0D9WBB(S|C>j+_ z%x?2Ka=~1d6|QiQZm0zfeNCS+M4nT75KJ-=c3k0Rea;HPz6Y_lHtqcPzuTis13yNZP!2p6mED4|^ zi(*{~LKQ-H1G_nB{kj;RT}-Y+4rgY#n9qsS={1Y&VCMMoS6JJ)Ax!(#dirM;ra2M% zU7t57%3{cBYKA>AZMcI?0s-pAlM-?pW5U3x@+c&4+bP-&!k55O&{R&$r|~kI*U}XQ zLWuinL49>r)y~);s9guc=U6pb);GbF1=AW6i;LU*)_~J0gON;+a*<_(;r##~KH}v+ z@Gx{sInEQ27@;VT zP6PvGzTET@N@eqdpEKRTccS;s?lp)bq*2E5t;pV@qSf$8i(3c@IiC_JuAv5Lm7pTz`^^vG!1%_E$ zCDk+=%a+PPK=34Zfjxs?U5Hhuq@S=4msnb0p;IubY?qoU^r5$__CWQMzbORb|HUbP z{!%Cu^%L2S<03&6q-l_h3J(U$JhDJE7|=hX2s-WVmcMezHw6cLP0_95ih*IyJ1?i& zVqkh72Pu8Ba5c(C?HctV6;Zf#n%M6d}{3O;*_tBl4CzEf`+FLOh2|5O#xbk zo~TVqMC+99g^vDGSV=8*`LVcQfKLDB{P)|3|AucF5k>~zO=~>lO}tnvvF7N!6|Xx$ zAAZaYm_6eZPRN4%P-Yyj-GzYjY{sTaN)L?i{bx{OcQ6W|a$+3k) z=Z&86V?u{+ACy2jK$Qh!8G{#{073_m`YI3DEEuqQp5{cN#JeL;dzj!kh+Omv>90WT z3s>0lcZ!JwBdpQSV@l_P(5rxzBc{rt^~xRmzHPG^!H(rfrawFgv=O_YS7|)1KYr72 zxSY31yq)K$Hu<5At3aJ`lp*%UMi>wbm>uWQ8az*_jA`75>}#w>d z-)-~rs%AFh5(mCV{vQvy5>pO*t38byC ziuf4aRn}=nx+&;6&ZoIm=C1=1*zu_Y6y7L1v)fmw*ScAixyU}Gn(=8dm{470oX$)@ z&*z=Uj2+#bK`uqHPXr^Iev<`~IHA`ehn2cBNMN6;Wwi`Zoaq(O##C!$q+h;nb<5u) zaFEx{>A%PZ58Q>RH(gsw9R*p??{cMnZKU{H9O4HxV8?>*(i8|Fb03}Yc6L*!nii3J zT1xX&KUhT~@V=2ds~pG~aW%nC1dKvKeu7I20b-Q7!%_l=e8SyDzJoV?L3#b`SDT5?19z9aPO#h#qQvj*9DUmfn$Ripq%f4S6tLA@3f}XN`;PDW`zvrQ|;H~NNREk#Swm70~3H7mEM zc2-Rh(Np7{zF(rZy=JP0vLB%e;KKL-4}NANG>w3w$L^i ze^D3iNNVHkTwwe-;j^QQ#7p4%9EJOF6rYBy^TsGON0E2Y?kUG_OScnhdf+TeV>=U%LB9Di`GMyn(y9H(TO{~BV;{|D zbiF?a6#J#(?#-|LNH)vice`J%cUGKk47&>S6eQ$+|o=e~o{`jY{{9?qNQ#@J~T9obw;RJZ4W1CptC&ceEzSor&&u zQ+gwMvQ`Ms3lm;#SL67vP5GwD$HWMFZX+(62QuK#G^{UHNN;IA^Zz-<6!$F`jj(AX z4Z!Mr>k)KZ`KGHqX$Sv>e_e1CEbmEk@PXlp$B7}3`HS;~R{bs3c9%MM%@&rJ zs{3n69nrr!e-#bikG*9c?0R~wQweG8!aQ_64_iaO(L+ec2R%1yZR0~l0FJMZ*5G4Romr@!4Vtu72sn<+ZF6XTjn2X)#SUa-gs~^WvA3%j|5w=tdQ#7V!}I9~x6A4qpe4zOcC56+Fr) z&q(`M)eajf{AT>cex>^B^M~qi*)!?TTa`|+j6=GZc;mA-Im%>#yrI&V`*!&E=*1!* zw&1T*&XHhvr8&K0M0Z#98|El!?&(Wn2fu{G_$X-`D;0khM|8eSBszsAl*uG=h$_F% zC>^B;2^IUcr?qN|1##(fmR1a5L~>42d=yl=y_E z+Y}ITx&Ok9cU_*lvqS!NuXZ?aP$%usu4I)qcus@Q(~esQ@xH*@ZQIalE$nlJNlQ%L z4L@YyVOR|?zpSz}Ju{%$!u<55koHedFtH7d0VXQ?Vc^;o2WaN5_m0j}mj@C)&vQ~x z0|%VFv37!nY=r2sZn4}E6MYD)%YXSs6q7l$yCHMlV^x|3dT8+M^AF$!;Qrs$`~Q8z zM)HdHWWQI%=o(}7(`sDi2NisH{6q0sJx|%_YF<*k;oI6S_iFoUd0^P94fmaI_$9Tb zM+JR}@rd2DlLiL7w97w?#_R=sZzaxX~?cGV+MW1$yu7E7&x#ASpaYtbZ zK|zZSj*g4dNK`Xg1J&}kUx-_#kAK8iUaPtg*bN1H_!Fx=5>yEmej!Ol(X$xPa?;On z$~erJR(-$w7*q)dLf|ipN{fsg0{;PISbEDLG5ZhvF!C|@1L!GEA95hLhUkRiIN%P} zZzRlWcKYGqi61(R4RcN?c6h9=zdR@fifc}f*+Yh?15DSE8 z9dhrmEZ;jiyKIsfq)YLt?|4m{zHBCzUFI|IHu~v6)x<0`Jq2rZ#t1An$j0C1hCJ5T zwT2yA!`EVt$fBClJ+;ex}PKgrbm!ymDMWr}Jk%X58hYw{~Cx;StvDzH=BQ7{THE4hL4 zr%@tK(mxS-Wz{F>5gjZ1`QFVy-!>3h6FYpJ{+IUhG^s1&xaK-~fXX(3*-56whP78L zdd|H*{rqc7w_k;Go1uQm)9m}d?kc(JT_1m+FAS0LX*pc%&!9|ZC{Ek!(aatG14yTeO1xV8ZT-@JNGH;U7;ox#!jGRlIx;~dS_E$0A~{8&iyqYNbu7KhwkJ+vLg4$ zr-ww3jH|~x5F@SWDxu`kLUl&TX!24hjeGv+l;3*n>Q-RG{QGiTaTftI6gSmj6X|cV zkAZlq{{U3@PHlFs=XYuP?{yE@rN_xb@_LY`;in=GH@%U{>58THufO%*hebA)eNx7I z>Q>T!9rYlBgDaWw=le+gVV7Zf7x>KwAXR#Pa>(Z>fFXb%$iom2QD0q9BQ(|t)NHV_Qt=V-5WK|pHRYO3wQnj zbp5P{IM*$HF!tdf<8Wihf6jSd2gskM_Tv*u?dZrHz!UTFIOQK^lc4`oDe&V+NNn5v z9xu7MNx|-?e(@|z;q~{2zhn}^qzZ3s{;*c{ZRdoWx&7?X>Q;HuEpFxV^?2_rpePsA z{z^k^E$8Zk0F`i)s*nV^)bYUHr1XcSGdVPrN|hTrh2?y_y`rbCYqdi*dfDQHxAE7N z>DXX&t<5~nIN02*(fthvFzKA^@u%5P7^x3*WHGP}@en;7B7=u0h#9?Y`%a)XA@2Xo z8`;n@YE-FCO&8nC!7SMIfR~*|J|+KMz7_Y&`H#vwTz*bXtft?p_&SE^!)gVcK?LVw z$kUH>gx__zyZIJvODiHRVxL2tilgL{FUO+BMQAixiza^{8FIMFxnw-)xUM_8u~>3`%PuA7{Q0t zB|oe=X#noG4qmBd4BVIO7lmTaq)+slG9W;8@n_D5u3&%Jidl}!z_)+Ig6}GpGc{69 z`eg{)mPT*Ch5iG;D-wfA+keF|&yjl#XpC1nF)nd^d?)U_D*F5~UfPpNv?qTO3m%_g z$13>B7;*43RNRC_(mc=n%jrb%d*h`;ufL-UOouq))CtU7=<#E7}o;$87;c_Q*DZ2`CfybK#8B3GwTQ=X(k9tS)vpI<>od&*Pd`z3AYg20YiGFzt z9TTTR9vvo_3%`Dzet8{Xqr3=p{zvHYUro6GFNW0mzmGlBSc{2e9G62Aj|8$W4x5OAR6Zwz#Up_ZA5Dx&L2Y}$XvoCsaT=Xw=alV0I z84zwF0B@8F)&~H5VUWFkp=Be(XkdIV2h#7*1CSd5GDrX`7yw||NDKf_1K3cIW?npO zz89*tH~>%s_!kWRnjG-5?O*$sdXHrG0w*DY{p!ooL}zZ zf9x&zU#vL*RrTe%9wtICfaSltSU%C1x&vPt|6b$2nC^cY|3SAS|DVH|{@wI~U;nT9 z{kNk3Z#|1|$C=+_lk|Ht|Np@H{5xgGrH>P!TxfDg@j zVM*?av)3`yY7@fNc9zd11hjmn>nBtkp=cr!erJz~wM%gcL@t{wO$WQ$icBArr zY#8c`HSEu2e-}1@^L0mQVxZPJB-BcQWrIPF_AG##6!L|A+V=B+Mv}UZaThzuU@(oGR1&5*I3mMwCK{@U6Kn(lp{TJ7Ac0RX2kaS% z2ny;Zw6M78^=0H5&y~&e>0uBu4^jsZah^~YQ6CD#4Fsq=RYby9N_TBhdz*KT!J#pe zoVBxP904QikaTcmw7hGFa)FM22k>)qnjH# zg3<$+c?vKtG0{#di5rwJj3-$y32*{|XrtxssC@SP+Csw8GirCK5die8=#{{3tAruX zSfHb!V{L3uR|mUNGW|j(C*5_@ZW{x##k8(3&0;E+v1wzE<%3M2q)W5Rkc?jNg?FkD zps~a$Ny=bMg;IyhPAHYlvF8SeEcBN!0CV0516i1X#SWZTIS5d#8->X0;?c%4u}=?K zBw@uziQlMJVn`p;wGq%FG&#SjnvEpV2Ou;y*5%IX=|l zGUuY9!9azwfH8z8r7RQ(Te)KIEe=8g5Cc#v`vB%;11O(~Ybjv%!mK?+m@UNjh0i0b zmeH4%Rl6qoT%cr?GlFINx*8YaMbDZiOE8E)L3?&7mXw~w{ zb&*(B2V`X}!6dz_c#=uWBJE6uk4sU06mq=)gGX!kbDY>1IPy!78ET`~UzE6dQB|!+ zTq{&6Ki^3)J3>g_3#NL?Hui>Qg8dOaHtxFlVd7v4@-wNRtm}TdS&l5gdvr?{_mBipjcZwu$`B*6(}gi&xAs-iaxQB`5wI zyU8U*Np=!w#;Coe32PP_@^HjcmNcDsoGEp4gL9^`6@9M92ca7kdJ{3%$`=U|*T(f? zQj-Q6bMx#c`96b3PoU_CBS^mw*!rQbm2LK)zZ-M|FBioluy*Y(3+%bm+(34!l&4BB;oNkkJH1$gCXAJBQG zXl37hVd{DjZdTv#>kVoun2f|vom~K~fW}d|nDQ}VALPXtI;)EAm?Q{J;A>8O8gG!6 zkO}FJIg&GR0Qi+PSp2Ddn{z?PJeDtLBvsZ}Z75Zkh8HjCGzEW2lkD`_SD%kvcm0$|a`7FzG_Ksc4N z{nQtt!}h5j8D1R_P3EFJDk$;BjL};D1Hi|r=~FT2*T{8c9w$jdM@1R4D&#^DeutVY zz^>k*r&c{9O-#;^TzjCZEd#XGhW6+pTdW_`kHDW)>b^tXB!&#oLz|vuVnN%qi67u- zOFK+8mZih0aW}f0qSU?EYZ}eniL$1Bl4hsCBj*VbB==+Ph+z>=i(F>HpPfFRl#mBq z>=px{rUyhkW=vG%~VwZ%e}sIh;Q?m*pek3X9$e2e*l#j z%JcwOVG;%bl@z4y@@$(KLo$1gP*i@K7{z;e4DR3X#1%q9&!tMXbcE{Fw6ZWHXgK=4 zE*42gik}XGzr`0J;}2y~2E>rzyn7VC)rR8J?~q&(A^>gno7TAf zMSEqwZrLYjW!bmyEHt83#hm+-4j{|%AHJ`!5!UDMK8h6KFPCVwrc~oJS|%f*!E>&* zNGJ;~bgnWx_l&T_CpKA#C4H%h@etMmKO4H;t)DtQM-!s%eu!Mv1+`Kq@Nc4*Y%Gis zk7~75{$D~T|v53rVV7a61aWC;TyhvC~o+_Zc6Im;8UPuP|!{MAV+uEphKl-b3q zA>w@(8Cmp(pX%2%&)bnDQpGNHfS3f+F}6Xs{WNt2hx}ua)Dwu@LUXR)-;~oo_M%wtuKh<4`xpx>ov(}C!#OVEC+^fVHbnXo1{g{~K zfUglosvoiZBXq5m4~8K}n-$>ljf`v1QXe}jZIB0z2mr%vsx3%XXTZfmQb3t^Oa_|3 z<r{<2nb8%AU-LmP?KFJhi;~DBXxWXn=rnvgJc1Ym}P9Qe2)Xcf2U` z_tLKw^kHg00@z9gkxR1&(2$*w2)lvjubs<$RK$?csPy2J(5j7_xt{N(!c59Cqn@b% zPW6SH_JFu+S$ms1WM~w5bY+0$2ne)~!fZK}i5g5$1(rj56<3I4qUSl4>jL3#8VDwE zTT%}XT;9?Ah(63RwWJOO70C0ailkkCRTn@qqMWQYQ2!N@ zm(b4ToWDmFAS|57lvXtIL6I`8t(|!t_u5jJ>VN@52A**JHnbE&jq$HtgHimQ%r8TB zHf^GbA;&`r+fVb za{{||n`I&r`X}7SKwK%_v@p|vUB(-kITO1&6|Z=VfaMp}-pkx*h9Cx?8XQq}4Uzjv z$KWyjGSa_*!q5QSa?l@U0JJ_CYV`2PI{Yr2Ff-jU(sPw)&R0wChIw{qRKuCPQgEtm z&f~BN2+M+!0r>=jQXtE9&EF*E8PjZiu7|5u@3KDH^BQvgNH-hdPc$H9Kp=|mUPF^F z3qf$b^nP*pFYrCtUbum%gH0%Be~=rrr0r0T;WLWmgwhK27grLOuu@zYY3h>C>H{&w zJBwmdcL)8vd~=&Uc_zMoEl$ZtnG-o=Dn_tx5v$40;Y6ricXiLzV$K#+)1Kku7Aajb zOok7>sW`Uj^0-_$MI27L@FPhRgXwElMK{>~2G$2+k3G!&hBmKCZ(jSeuaFs<{xG3G zM%2wWCQ@iM>Qiop?*VDPf#KUM2vpc=z_G0QZIOV+y0q_%HV6+3Rp^NqAP~C|8h=MQ z%G8o2oizuAWC7GPKdc@BstK7+djcj!WD@te76HAAVp?*$(o8R3B&t{yh8FokXSG-( zBpig=a-7MCa}HTEY#f`p4>>$rnFwL7s2s3P;oHdfSpZj2hZ{@zg&ju>2GN^V2k=$0 zlUg~(DU{HnH!?E_@N_|y`=SU#gOPW+6~v+NHF`$bI9_ozaU_I2^SiA+cA(Bgjjw5q z@2$caWKUJCmK>Uf8sm`&oFF6%jVQ$Qr@H~$cTJJSqkwcGhph<>*&@7{Bj)w%)tdVk z1$}fn`+z|ii~ZrBRJa|{`7JH(4aAwpdLX_Dt(5?TIzHGg66}^d^R?vWT?#txCBR=} z>C3~GiJnHa;XPnt2S-VtJ?U(^rJJP;jcLG$!jc#}sfQSnLW|~jz`h`(1fEwcFFKH2 zy_RKa)YW5Z$n?!myRniT0Y%WSG_s-ie|>c+^Y z8Uj>jA&H-f(D=hhL4ZWk9DXts?LnO6eGHKPQpAu0X$mR^nu-M?nvF!=XHbRMHi{%O z3>~QtsrRSwKzDWL6uuqcli?I$=N@a->3RZj8m|3`9;`{+tvSD{vx@a7bTT_aAr}{=H$%YTxqv}le=Or=}*&i1PG;+4M^@XBEV2j+; zIkFfX^*LRe%LSS0eWRcmX+(yI10G1`w8>C#>mm}9p+$G4%vxP?gaT}l^H@+E27#6& z$1;6`XG9w6RupSaeGpG#e-!R1)xA-c@{i^xArnZzs^HtIV;~Yo!W7iG4@~5%yT4tZunHk>BL$U~mvG`3ZFadBD^Wp0&!I5K}Hdon5t@wTdb@0OYVT2T-&0kbtEXmstj2^15v~`HXubk1 z7E>4TCL$rhumEa=PpZDmd|Q?m^RP*84jdU3x5*=IW)8BzZna8e1~owgAo4W__YPEJ zl^@D|pWkA6Iq?wN??z5^9=3_BUIp`@rd?}9;$GpX;XF$!Ya$)$G9gR{mg`^(9YRJl zN+)!fBl_)Uu^5r$02L_LFiRO2KnB<&r=Jk^CXn`8TDcibhfp$<{Rzk$q*k`ApVOx^ z(EJY|jKt4w*;-j`7)=&5Zr_r_&%lPfO+;;#5}3hAX(Z8``_`;o;+eG5_0H7E=>vXR z6SE5mu^hjo1`r+fAlok= zHqYv;JUX9&e(RNpvgiGjXcp`)3$`TL>^xm*`9TRmUP#R8Jh9N5#9%-bk?{i9@#9;T zeY1`QeShD^zc&5`>nM@E`WpB4|(FVVAh9WRks7WJ1g-p9irtf zvL$p`Ps+>2x`0Dz26Ec;Wzy0?81%}h5N!&nsD;|}Yc{7a%Oxy)HW}Lr{9PxEO+{$y zliXpkn&3Na3MfJWnB`N0Y2WWl5W7pZ6f6e?Oe7*zH)`9e&=*_mzT?{||3U1Snw6ta z&Vm8yqAMo~1HMzVr0D48CBiYbjUfF8pxkWGFB@mI375sK z2`O_G4ulI(vS~uisn3}&tnfdxEQM5R6ZD|Hk|CRCY%Cfaso+%D_jde3TH>B~rRySe zu=F{zNQUpTOg@H^NjVkVKEQ ziksUCAABZ~Kaq1J38f-ll0m1}$fDv(c0{#MpTp%4IMUUhMFyZ_cE{x(Uvu%pM@1GA zMF@pww-+CXE_?VYjdg?X*++z`_1_zu?+8)p)!oQv>x_?Dg zZHQjNtS)pG`a%J~N0kc%h@w0t%57}{7&ICX&;iA%ep*YF?H%?EO{4w+5s@2+mPELj z^ThzIuu55Z1R-o9$stlu0l_>BTxV5pLd{`hgp%+P8CnIS*H9H;DEjxwP=!? z>I^_IrbSK$D>rlL-dEf(yshUp1uUu}`Y~Aw=`&|gz{4UHh$YJ{SkTr?x&WgB!3sl{ z0M$zc&1-rh&Z4dwiLywGS4umP7zoyT5x#7y(7>F6#Ijt1`cw0Ph!PW{T~`P(AoXw5 zmSP%AcS&MIl44JWS=(1ZV3WVEtvpMC%B-5AFpz>c0e6{}cA+^+#NVI=LbEe7H<`T7 zX7k}7)`P5V4H8&xnIut~lDowOdy*npAhS-N#iC+JuCQj*c0d3S0bl~a7(CNd%rt@~ zEeRz8K?+FDWUR0ZE(wLO$`6wgjt6swR*{?#Q1DN2`bL&+4ha-siVE~DxEf#vf&;3) z7`y`)Kv%IsNgA_>yFD&slG9DH6+tAnKV+ooARFwUBy7)%6EE`2LXIpMrZakO~m$h6l~PQund!y zh&u^_u{%^PTmWDI1ONaBg{EBv!z9{FEUt)XZXp0B9bV?QV9*PAfZ~Kf5z!kZ370By z!#iz+I}v>n0R%)L5x9+$%w>fk$)p$;AoW6(7d~nx`A)Vl0^S4RU}Ws!G)s-dY9zfYC&82s<(o7#UHFA^D%f;I^hm=){+urq)UiW`xV4FxD5b|6WXKmueUk&A@O)Gl9u1(Dla z^iB&^5<--uZ?x7QBe@FztYQ<@7B{$-n+ibD%}zKF2m0O0ubHvPgfk=)Dv7HVi@dh8 zoNDAc7R}XZ@=7`H5?FHv!VL(}5wel_DFZq;gOJ+^HWW}?qLQ-kP1kV^){LxDj0vZbiaFAVUHxK7z3luPW50_To@Wu*%REO0hAqWf_L0 z)l5D&W3-MWJgG&P)Oq3>2XRBVw17`smA>beE2I!$RPG7e%H&T*fcShPl43VHMcu1t zMI;@nNFfn~O%bwq8A-cwfL+@d#bsIO;eGuZA><_Ccp0QB=>iV`c8y+ToIc$kT$f)J z5M|;nr?DdH-(Nx-ZZ_Qo?<+gE@{aXObCK?dGTI@>iARc!kd84VV(j5l!`T=kkozgk zf{F2pK#(Eg~o<3&4r~_RbLmA*&}f;^klb3(ohv(D<+icmHhZS=x|!#PBG0l+TKgyLaYsD zoD8cO40+KF5;CN5NhW3zDD`H{LAFenw=PE<`aqKd9^_Nw3@>I9qj)aNR@u0ew^hxq2Ke%792gIZir{A>5*?hEa~h>j8CNBw)H}Kflz?oKbz)DvqditYxOws^p2< zKJclQ+h4;!cC|W|)%b<-rh7CI+YR&QintS^Vr)9vvoPKh+z*Aq-Kd#Rd-hFDaPM}cm|@ZX9B5E7NzbYVMPz9{T}b(^i3W@B2EIU|RuT+xF2rSxJQlim{GMaYi6v(Jw2q@Sb8BR@}yhg}Z+a$2zjs8mnI zYXT+RB{fU0tbhd&juM#RGif&^@2qC)=}s9?1=Vl{t5yOW9OO8rI2)JOj#*C7EIfO* zNGPV}mt_#2;#n>z{Tqf<0d-sfs??(~L?+!AUsC-N`Z-d-IBXh)ob)KAz#tezZX;xF zKSQB^MT1mq6LbRCl%bguM9Gk#x)cmp1)rm131l(g3(kNLfd~yE7~os(qrA?15gy IKeK=T*_q1nUjP6A literal 0 HcmV?d00001 diff --git a/examples/default/resource_pack/pack_manifest.json b/examples/default/resource_pack/pack_manifest.json new file mode 100644 index 0000000..7f67a0a --- /dev/null +++ b/examples/default/resource_pack/pack_manifest.json @@ -0,0 +1,30 @@ +{ + "format_version": 1, + "header": { + "description": "", + "min_engine_version": [ + 1, + 18, + 0 + ], + "name": "resource_pack", + "uuid": "{resource_pack_uuid}", + "version": [ + 0, + 0, + 1 + ] + }, + "modules": [ + { + "description": "", + "type": "resources", + "uuid": "{resource_module_uuid}", + "version": [ + 0, + 0, + 1 + ] + } + ] +} \ No newline at end of file diff --git a/examples/default/resource_pack/render_controllers/.gitkeep b/examples/default/resource_pack/render_controllers/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/resource_pack/shaders/glsl/.gitkeep b/examples/default/resource_pack/shaders/glsl/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/resource_pack/sounds/.gitkeep b/examples/default/resource_pack/sounds/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/resource_pack/texts/zh_CN.lang b/examples/default/resource_pack/texts/zh_CN.lang new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/resource_pack/textures/blocks/custom_brah.png b/examples/default/resource_pack/textures/blocks/custom_brah.png new file mode 100644 index 0000000000000000000000000000000000000000..89dbd8d5a94db5730d2f3197508e811f03e15826 GIT binary patch literal 286 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyaaMM3p^r=85sBugD~Uq{1quc!Ofm7jv*GOTZ0UR4k&Ouj?~lZ+hzIdfBlWa zyDJ)a%KF7#`88X4p3Py8x@`A>B}I3Erjk*F%Yv4ZI!785UR6o4 z-#a>8+9H6%|2dD6xWeP#78*-)&M`VA^Ef|}nzuHl^TZxWf3_((ESu8yeP)bn^k`Y` zI`fXMi{y{zFJ}Jp5J(WOw_Nb8=s{=Xjx=tM$#YW{#q5v%a8{w>;+xJxy@Ac@?R e_;ge^vUAy=S(Px#(Md!>R5;6ZlCcd!F$_e#4l5whQPCrT#0V*A7y$hZ z*oEmp7wMw+@8=g*65BcZ&aUtK@%yw(x7YR9ZRWe54y(A&(nX0((0f^y;WHrbipk1o zuEIB~F^732wAR{iu$!ckT?_yR70_pLC!h+YuiREva;wya_aS0(lz2>_;-u-bGC9ZR zZf5=tkWQX%IX^Qt-Gk(wyh){UJmhR(`$@%G)r=P_Xmq5&G51YOXM*gRyIN6@J#XiY taHcWa(8?q#O#WGD1CTplk@n{A0)O^}D66O1i$DMX002ovPDHLkV1i?sfdl{m literal 0 HcmV?d00001 diff --git a/examples/default/resource_pack/textures/entity/.gitkeep b/examples/default/resource_pack/textures/entity/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/resource_pack/textures/items/custom_apple.png b/examples/default/resource_pack/textures/items/custom_apple.png new file mode 100644 index 0000000000000000000000000000000000000000..c25b5177db0e5c1766efa2c9bb4e0502bb3fd506 GIT binary patch literal 257 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 literal 0 HcmV?d00001 diff --git a/examples/default/resource_pack/textures/terrain_texture.json b/examples/default/resource_pack/textures/terrain_texture.json new file mode 100644 index 0000000..f98ab0d --- /dev/null +++ b/examples/default/resource_pack/textures/terrain_texture.json @@ -0,0 +1,7 @@ +{ + "resource_pack_name": "vanilla", + "texture_data": { + + }, + "texture_name": "atlas.terrain" +} \ No newline at end of file diff --git a/examples/default/resource_pack/textures/ui/.gitkeep b/examples/default/resource_pack/textures/ui/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/resource_pack/ui/.gitkeep b/examples/default/resource_pack/ui/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/examples/default/world_behavior_packs.json b/examples/default/world_behavior_packs.json new file mode 100644 index 0000000..edf507d --- /dev/null +++ b/examples/default/world_behavior_packs.json @@ -0,0 +1,11 @@ +[ + { + "pack_id": "{behavior_pack_uuid}", + "type": "Addon", + "version": [ + 0, + 0, + 1 + ] + } +] \ No newline at end of file diff --git a/examples/default/world_resource_packs.json b/examples/default/world_resource_packs.json new file mode 100644 index 0000000..3dfd670 --- /dev/null +++ b/examples/default/world_resource_packs.json @@ -0,0 +1,11 @@ +[ + { + "pack_id": "{resource_pack_uuid}", + "type": "Addon", + "version": [ + 0, + 0, + 1 + ] + } +] \ No newline at end of file diff --git a/src/commands/components.rs b/src/commands/components.rs new file mode 100644 index 0000000..514cf47 --- /dev/null +++ b/src/commands/components.rs @@ -0,0 +1,222 @@ +use crate::commands::ComponentsArgs; +use crate::entity; +use crate::utils::file; +use crate::error::Result; +use serde_json::{json, to_string_pretty}; +use std::fs; +use std::path::PathBuf; + +const COMPONENT_3D_ITEM: &str = "3ditem"; + +pub fn execute(args: &ComponentsArgs) { + if let Err(e) = run_components(args) { + eprintln!("错误: {}", e); + return; + } + println!("成功: 组件已创建"); +} + +fn run_components(args: &ComponentsArgs) -> Result<()> { + let project_path = file::find_project_dir(&args.path)?; + + validate_input_files(&args.geo, &args.texture)?; + + let identifier = args.identifier.as_deref().unwrap_or("unknown"); + + match args.component.as_str() { + COMPONENT_3D_ITEM => create_3dmodel( + args.geo.as_deref().unwrap_or("./model.geo.json"), + args.texture.as_deref().unwrap_or("./texture.png"), + identifier, + &project_path + ), + _ => Err(crate::error::CliError::NotFound( + format!("组件 '{}' 不存在", args.component) + )), + } +} + +fn validate_input_files(geo: &Option, texture: &Option) -> Result<()> { + let geo_path = geo.as_deref().unwrap_or("./model.geo.json"); + let texture_path = texture.as_deref().unwrap_or("./texture.png"); + + if !PathBuf::from(geo_path).exists() { + return Err(crate::error::CliError::NotFound( + format!("几何文件 {} 不存在", geo_path) + )); + } + + if !PathBuf::from(texture_path).exists() { + return Err(crate::error::CliError::NotFound( + format!("材质文件 {} 不存在", texture_path) + )); + } + + Ok(()) +} + +fn create_3dmodel( + geo: &str, + texture: &str, + identifier: &str, + project_path: &PathBuf, +) -> Result<()> { + let project_info = entity::get_current_release_info(&project_path)?; + + let beh_path = project_path.join(format!( + "behavior_pack_{}", + project_info.behavior_identifier + )); + let res_path = project_path.join(format!( + "resource_pack_{}", + project_info.resource_identifier + )); + + create_item_files(&beh_path, &res_path, identifier)?; + copy_assets(&res_path, geo, texture, identifier)?; + create_attachable_file(&res_path, identifier)?; + + Ok(()) +} + +fn create_item_files(beh_path: &PathBuf, res_path: &PathBuf, identifier: &str) -> Result<()> { + let behavior_item = create_behavior_item_json(identifier); + let resource_item = create_resource_item_json(identifier); + + let f_identifier = identifier.replace(":", "_"); + + let items_beh_dir = beh_path.join("netease_items_beh"); + let items_res_dir = res_path.join("netease_items_res"); + + fs::create_dir_all(&items_beh_dir)?; + fs::create_dir_all(&items_res_dir)?; + + let beh_item_path = items_beh_dir.join(format!("{}.json", f_identifier)); + let res_item_path = items_res_dir.join(format!("{}.json", f_identifier)); + + fs::write(&beh_item_path, to_string_pretty(&behavior_item)?)?; + fs::write(&res_item_path, to_string_pretty(&resource_item)?)?; + + Ok(()) +} + +fn create_behavior_item_json(identifier: &str) -> serde_json::Value { + json!({ + "format_version": "1.10", + "minecraft:item": { + "components": { + "minecraft:max_damage": 10, + "netease:armor": { + "armor_slot": 3, + "defense": 20, + "enchantment": 10 + } + }, + "description": { + "category": "Equipment", + "identifier": identifier, + "register_to_create_menu": true + } + } + }) +} + +fn create_resource_item_json(identifier: &str) -> serde_json::Value { + json!({ + "format_version": "1.10", + "minecraft:item": { + "components": { + "minecraft:icon": identifier + }, + "description": { + "category": "Equipment", + "identifier": identifier, + "register_to_create_menu": true + } + } + }) +} + +fn copy_assets( + res_path: &PathBuf, + geo: &str, + texture: &str, + identifier: &str, +) -> Result<()> { + let f_identifier = identifier.replace(":", "_"); + + copy_texture(res_path, texture, &f_identifier)?; + copy_geometry(res_path, geo, identifier, &f_identifier)?; + + Ok(()) +} + +fn copy_texture(res_path: &PathBuf, texture: &str, f_identifier: &str) -> Result<()> { + let texture_dir = res_path.join("textures/models"); + fs::create_dir_all(&texture_dir)?; + + let target_texture = texture_dir.join(format!("{}.png", f_identifier)); + fs::copy(texture, target_texture)?; + + Ok(()) +} + +fn copy_geometry( + res_path: &PathBuf, + geo: &str, + identifier: &str, + f_identifier: &str, +) -> Result<()> { + let geo_dir = res_path.join("models/entity"); + fs::create_dir_all(&geo_dir)?; + + let mut geo_value = file::read_file_to_json(&PathBuf::from(geo))?; + + let geo_name = format!("geometry.{}", identifier.replace(":", ".")); + geo_value["format_version"] = json!("1.12.0"); + geo_value["minecraft:geometry"][0]["description"]["identifier"] = json!(geo_name); + + let target_geo = geo_dir.join(format!("{}.geo.json", f_identifier)); + file::write_json_to_file(&target_geo, &geo_value)?; + + Ok(()) +} + +fn create_attachable_file(res_path: &PathBuf, identifier: &str) -> Result<()> { + let attachable_dir = res_path.join("attachables"); + fs::create_dir_all(&attachable_dir)?; + + let f_identifier = identifier.replace(":", "_"); + let geo_name = identifier.replace(":", "."); + + let attachable = json!({ + "format_version": "1.10.0", + "minecraft:attachable": { + "description": { + "geometry": { + "default": format!("geometry.{}", &geo_name) + }, + "identifier": identifier, + "materials": { + "default": "armor", + "enchanted": "armor_enchanted" + }, + "render_controllers": [ + "controller.render.armor" + ], + "scripts": { + "parent_setup": "variable.chest_layer_visible = 0.0;" + }, + "textures": { + "default": format!("textures/models/{}", &f_identifier), + "enchanted": "textures/misc/enchanted_item_glint" + } + } + } + }); + + let target_file = attachable_dir.join(format!("{}.json", &f_identifier)); + fs::write(target_file, to_string_pretty(&attachable)?)?; + + Ok(()) +} diff --git a/src/commands/create.rs b/src/commands/create.rs new file mode 100644 index 0000000..4e954b2 --- /dev/null +++ b/src/commands/create.rs @@ -0,0 +1,183 @@ +use crate::{ + config::Config, + entity::project::ProjectInfo, + utils::{file, http::HttpClient}, +}; +use std::{fs, path::PathBuf}; + +use crate::commands::CreateArgs; +use crate::error::Result; +use crate::utils::git; +use uuid::Uuid; + +pub fn execute(args: &CreateArgs, temp_dir: &PathBuf) { + if let Err(e) = create_project(&args.name, args.target.as_deref(), temp_dir) { + eprintln!("错误: {}", e); + return; + } + println!("成功: 项目已创建"); +} + +fn create_project(name: &str, target: Option<&str>, temp_dir: &PathBuf) -> Result<()> { + let target = target.unwrap_or("default"); + + check_example_exists(target)?; + + let local_dir = PathBuf::from(format!("./{}", name)); + fs::create_dir(&local_dir)?; + + clone_and_copy_template(target, temp_dir, &local_dir)?; + + initialize_project(&local_dir, name)?; + + Ok(()) +} + +fn check_example_exists(target: &str) -> Result<()> { + let check_url = format!( + "https://api.github.com/repos/AiYo-Studio/emod-cli/contents/examples/{}", + target + ); + + let client = if cfg!(debug_assertions) { + HttpClient::new_with_proxy("http://127.0.0.1:1080")? + } else { + HttpClient::new()? + }; + + let resp = client.get(&check_url)?; + + if !resp.status().is_success() { + return Err(crate::error::CliError::NotFound(format!( + "示例模板 '{}' 不存在", + target + ))); + } + + Ok(()) +} + +fn clone_and_copy_template(target: &str, temp_dir: &PathBuf, local_dir: &PathBuf) -> Result<()> { + let _ = fs::remove_dir_all(format!("{}/tmp", temp_dir.display())); + + let config = Config::load(); + let url = &config.repo_url; + git::clone_remote_project(url.to_string(), temp_dir)?; + + let target_dir = PathBuf::from(format!("{}/tmp/examples/{}", temp_dir.display(), target)); + file::copy_folder(&target_dir, local_dir)?; + + Ok(()) +} + +fn initialize_project(local_dir: &PathBuf, name: &str) -> Result<()> { + let lower_name = format!( + "{}{}", + name.chars().next().unwrap().to_lowercase(), + &name[1..] + ); + + println!("项目名称: {}", name); + println!("标识名称: {}", lower_name); + + let scripts_dir = local_dir.join(format!("behavior_pack/{}Scripts", lower_name)); + fs::rename(local_dir.join("behavior_pack/exampleScripts"), &scripts_dir)?; + + let project_info = generate_project_info(name, &lower_name); + + apply_project_info(local_dir, &scripts_dir, &project_info)?; + + rename_pack_folders(local_dir, &project_info)?; + + Ok(()) +} + +fn generate_project_info(name: &str, lower_name: &str) -> ProjectInfo { + ProjectInfo { + name: name.to_string(), + lower_name: lower_name.to_string(), + behavior_pack_uuid: Uuid::new_v4().to_string(), + resource_pack_uuid: Uuid::new_v4().to_string(), + behavior_module_uuid: Uuid::new_v4().to_string(), + resource_module_uuid: Uuid::new_v4().to_string(), + } +} + +fn apply_project_info( + local_dir: &PathBuf, + scripts_dir: &PathBuf, + info: &ProjectInfo, +) -> Result<()> { + let manifest_files = vec![ + local_dir.join("world_behavior_packs.json"), + local_dir.join("world_resource_packs.json"), + local_dir.join("behavior_pack/pack_manifest.json"), + local_dir.join("resource_pack/pack_manifest.json"), + ]; + + for path in manifest_files { + apply_info_to_json(&path, info)?; + } + + process_python_files(scripts_dir, info)?; + + Ok(()) +} + +fn apply_info_to_json(path: &PathBuf, info: &ProjectInfo) -> Result<()> { + println!(" - 修改文件: {}", path.display()); + file::update_json_file(path, |json| { + let content = serde_json::to_string(json)?; + let updated = content + .replace("{behavior_pack_uuid}", &info.behavior_pack_uuid) + .replace("{resource_pack_uuid}", &info.resource_pack_uuid) + .replace("{behavior_module_uuid}", &info.behavior_module_uuid) + .replace("{resource_module_uuid}", &info.resource_module_uuid) + .replace("__mod_name__", &info.name) + .replace("__mod_name_lower__", &info.lower_name); + *json = serde_json::from_str(&updated)?; + Ok(()) + }) +} + +fn process_python_files(dir: &PathBuf, info: &ProjectInfo) -> Result<()> { + if !dir.exists() { + return Ok(()); + } + + if dir.is_dir() { + for entry in fs::read_dir(dir)? { + let entry = entry?; + process_python_files(&entry.path(), info)?; + } + } else if dir.extension().and_then(|s| s.to_str()) == Some("py") { + apply_info_to_python(dir, info)?; + } + + Ok(()) +} + +fn apply_info_to_python(path: &PathBuf, info: &ProjectInfo) -> Result<()> { + let content = fs::read_to_string(path)?; + let updated = content + .replace("__mod_name__", &info.name) + .replace("__mod_name_lower__", &info.lower_name); + fs::write(path, updated)?; + Ok(()) +} + +fn rename_pack_folders(local_dir: &PathBuf, info: &ProjectInfo) -> Result<()> { + let behavior_suffix: String = info.behavior_pack_uuid.chars().take(8).collect(); + let resource_suffix: String = info.resource_pack_uuid.chars().take(8).collect(); + + fs::rename( + local_dir.join("behavior_pack"), + local_dir.join(format!("behavior_pack_{}", behavior_suffix)), + )?; + fs::rename( + local_dir.join("resource_pack"), + local_dir.join(format!("resource_pack_{}", resource_suffix)), + )?; + + Ok(()) +} \ No newline at end of file diff --git a/src/commands/mod.rs b/src/commands/mod.rs new file mode 100644 index 0000000..281043a --- /dev/null +++ b/src/commands/mod.rs @@ -0,0 +1,68 @@ +use clap::{arg, Args, Parser, Subcommand}; + +pub mod components; +pub mod create; +pub mod release; + +#[derive(Parser)] +#[command( + name = "emod-cli", + version = "1.0.0", + about = "Convenient Management of NetEase Minecraft Mod Project", + allow_external_subcommands = true, + long_about = None, + propagate_version = true +)] +pub struct Cli { + #[command(subcommand)] + pub command: Commands, +} + +#[derive(Subcommand)] +pub enum Commands { + /// Release a new version + Release(ReleaseArgs), + /// Create a new mod project + Create(CreateArgs), + /// Create a new component + Components(ComponentsArgs), +} + +#[derive(Args)] +pub struct ReleaseArgs { + /// The path of the project + #[arg(short, long)] + pub path: Option, + /// The version of the project + #[arg(short, long)] + pub ver: Option, +} + +#[derive(Args)] +pub struct CreateArgs { + /// The name of the mod + #[arg(short, long)] + pub name: String, + /// Example target, default example is 'default' + #[arg(short, long)] + pub target: Option, +} + +#[derive(Args)] +pub struct ComponentsArgs { + /// The path of the project + #[arg(short, long)] + pub path: Option, + /// The name of the component + #[arg(short, long)] + pub component: String, + /// Import the path of the geo file. + #[arg(short, long)] + pub geo: Option, + /// Import the path of the texture file. + #[arg(short, long)] + pub texture: Option, + /// The item's identifier + #[arg(short, long)] + pub identifier: Option +} diff --git a/src/commands/release.rs b/src/commands/release.rs new file mode 100644 index 0000000..6745f6d --- /dev/null +++ b/src/commands/release.rs @@ -0,0 +1,200 @@ +use std::{ + fs::{self, File}, + io::{Read, Write}, + path::{Path, PathBuf}, +}; + +use serde_json::Value; +use walkdir; +use zip::write::SimpleFileOptions; + +use crate::commands::ReleaseArgs; +use crate::utils::file; +use crate::{entity, entity::project::ReleaseInfo}; +use crate::error::Result; + +pub fn execute(args: &ReleaseArgs) { + if let Err(e) = run_release(args) { + eprintln!("❌ 组件打包失败: {}", e); + return; + } + println!("🍀 组件打包完成"); +} + +fn run_release(args: &ReleaseArgs) -> Result<()> { + let project_dir = file::find_project_dir(&args.path)?; + let release_info = entity::get_current_release_info(&project_dir)?; + + println!("🔖 当前行为包版本: {:?}", release_info.behavior_version); + println!("🔖 当前资源包版本: {:?}", release_info.resource_version); + + release(&args.ver, &project_dir, &release_info)?; + + Ok(()) +} + +fn release( + version: &Option, + project_dir: &PathBuf, + release_info: &ReleaseInfo, +) -> Result<()> { + let new_version = calculate_version(version, &release_info.behavior_version)?; + let version_value = Value::Array(new_version.iter().map(|v| Value::from(*v)).collect()); + + println!("📦 开始打包, 版本号: {:?}", &new_version); + + update_versions(&project_dir, &release_info, &version_value)?; + + let version_str = format!("{}.{}.{}", new_version[0], new_version[1], new_version[2]); + let output_path = package_project(&project_dir, &release_info, &version_str)?; + + println!("📦 打包完成: {}", output_path.replace("\\", "/")); + Ok(()) +} + +fn calculate_version(version: &Option, current: &[u32]) -> Result> { + if let Some(ver_str) = version { + ver_str + .split(".") + .map(|s| s.parse::().map_err(|e| e.into())) + .collect() + } else { + Ok(vec![current[0], current[1], current[2] + 1]) + } +} + +fn update_versions( + project_dir: &PathBuf, + release_info: &ReleaseInfo, + version: &Value, +) -> Result<()> { + update_pack_json(&project_dir, &version)?; + update_manifest_json(&project_dir, &release_info, &version)?; + Ok(()) +} + +fn update_pack_json(project_dir: &PathBuf, version: &Value) -> Result<()> { + let paths = vec![ + project_dir.join("world_behavior_packs.json"), + project_dir.join("world_resource_packs.json"), + ]; + + for path in paths { + file::update_json_file(&path, |json| { + json[0]["version"] = version.clone(); + Ok(()) + })?; + } + + Ok(()) +} + +fn update_manifest_json( + project_dir: &PathBuf, + release_info: &ReleaseInfo, + version: &Value, +) -> Result<()> { + let behavior_dir = project_dir.join(format!( + "behavior_pack_{}", + release_info.behavior_identifier + )); + let resource_dir = project_dir.join(format!( + "resource_pack_{}", + release_info.resource_identifier + )); + + for pack_dir in [behavior_dir, resource_dir] { + let manifest_path = pack_dir.join("pack_manifest.json"); + file::update_json_file(&manifest_path, |json| { + json["header"]["version"] = version.clone(); + json["modules"][0]["version"] = version.clone(); + Ok(()) + })?; + } + + Ok(()) +} + +fn package_project( + project_dir: &PathBuf, + release_info: &ReleaseInfo, + version: &str, +) -> Result { + let output_path = format!("{}/release_{}.zip", project_dir.display(), version); + let file = fs::File::create(&output_path)?; + let mut zip = zip::ZipWriter::new(file); + + let behavior_dir = project_dir.join(format!( + "behavior_pack_{}", + release_info.behavior_identifier + )); + let resource_dir = project_dir.join(format!( + "resource_pack_{}", + release_info.resource_identifier + )); + + add_directory_to_zip(&mut zip, &project_dir, &behavior_dir)?; + add_directory_to_zip(&mut zip, &project_dir, &resource_dir)?; + + zip.finish()?; + Ok(output_path) +} + +fn add_directory_to_zip( + zip: &mut zip::ZipWriter, + project_dir: &PathBuf, + src_dir: &PathBuf, +) -> Result<()> { + if !src_dir.is_dir() { + return Err(crate::error::CliError::InvalidData( + format!("{} 不是目录", src_dir.display()) + )); + } + + if count_files(src_dir)? == 0 { + return Ok(()); + } + + let options = SimpleFileOptions::default(); + let mut buffer = Vec::new(); + + for entry in walkdir::WalkDir::new(src_dir) { + let entry = entry?; + let path = entry.path(); + let relative_path = path.strip_prefix(project_dir) + .map_err(|e| crate::error::CliError::InvalidData(e.to_string()))?; + + let path_str = relative_path + .to_str() + .ok_or_else(|| crate::error::CliError::InvalidData( + format!("{:?} 不是有效的 UTF-8 路径", relative_path) + ))?; + + if path.is_file() { + if path_str.ends_with(".gitkeep") { + continue; + } + zip.start_file(path_str, options)?; + let mut f = File::open(path)?; + f.read_to_end(&mut buffer)?; + zip.write_all(&buffer)?; + buffer.clear(); + } else if !relative_path.as_os_str().is_empty() && count_files(path)? > 0 { + zip.add_directory(path_str, options)?; + } + } + + Ok(()) +} + +fn count_files(dir: &Path) -> Result { + let mut count = 0; + for entry in walkdir::WalkDir::new(dir) { + let entry = entry?; + if entry.path().is_file() + && !entry.path().display().to_string().ends_with(".gitkeep") { + count += 1; + } + } + Ok(count) +} diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..76d1a7d --- /dev/null +++ b/src/config.rs @@ -0,0 +1,40 @@ +use serde::{Deserialize, Serialize}; +use std::fs; +use std::path::PathBuf; + +#[derive(Debug, Deserialize, Serialize, Clone)] +pub struct Config { + #[serde(default = "default_repo_url")] + pub repo_url: String, +} + +fn default_repo_url() -> String { + "https://github.com/AiYo-Studio/emod-cli.git".to_string() +} + +impl Default for Config { + fn default() -> Self { + Self { + repo_url: default_repo_url(), + } + } +} + +impl Config { + pub fn load() -> Self { + let config_path = Self::config_path(); + + if let Ok(content) = fs::read_to_string(&config_path) { + if let Ok(config) = serde_json::from_str(&content) { + return config; + } + } + + Self::default() + } + + fn config_path() -> PathBuf { + let home = dirs::home_dir().expect("无法获取用户主目录"); + home.join(".emod-cli.json") + } +} diff --git a/src/entity/mod.rs b/src/entity/mod.rs new file mode 100644 index 0000000..8436af3 --- /dev/null +++ b/src/entity/mod.rs @@ -0,0 +1,50 @@ +use crate::entity::project::ReleaseInfo; +use crate::error::Result; +use crate::utils::file::read_file_to_json; +use std::path::PathBuf; + +pub mod project; + +pub fn get_current_release_info(project_dir: &PathBuf) -> Result { + let behavior_path = project_dir.join("world_behavior_packs.json"); + let resource_path = project_dir.join("world_resource_packs.json"); + + let behavior_json = read_file_to_json(&behavior_path)?; + let resource_json = read_file_to_json(&resource_path)?; + + let behavior_version = parse_version_array(&behavior_json[0]["version"])?; + let resource_version = parse_version_array(&resource_json[0]["version"])?; + + let behavior_pack_uuid = behavior_json[0]["pack_id"] + .as_str() + .ok_or_else(|| crate::error::CliError::InvalidData("无效的 behavior pack_id".into()))? + .to_string(); + + let resource_pack_uuid = resource_json[0]["pack_id"] + .as_str() + .ok_or_else(|| crate::error::CliError::InvalidData("无效的 resource pack_id".into()))? + .to_string(); + + let behavior_identifier: String = behavior_pack_uuid.chars().take(8).collect(); + let resource_identifier: String = resource_pack_uuid.chars().take(8).collect(); + + Ok(ReleaseInfo { + behavior_version, + resource_version, + behavior_identifier, + resource_identifier, + }) +} + +fn parse_version_array(value: &serde_json::Value) -> Result> { + value + .as_array() + .ok_or_else(|| crate::error::CliError::InvalidData("版本格式无效".into()))? + .iter() + .map(|v| { + v.as_u64() + .map(|n| n as u32) + .ok_or_else(|| crate::error::CliError::InvalidData("版本号格式无效".into())) + }) + .collect() +} diff --git a/src/entity/project.rs b/src/entity/project.rs new file mode 100644 index 0000000..cb1ea59 --- /dev/null +++ b/src/entity/project.rs @@ -0,0 +1,15 @@ +pub struct ProjectInfo { + pub name: String, + pub lower_name: String, + pub behavior_pack_uuid: String, + pub resource_pack_uuid: String, + pub behavior_module_uuid: String, + pub resource_module_uuid: String, +} + +pub struct ReleaseInfo { + pub behavior_version: Vec, + pub resource_version: Vec, + pub behavior_identifier: String, + pub resource_identifier: String, +} \ No newline at end of file diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..0c004ec --- /dev/null +++ b/src/error.rs @@ -0,0 +1,78 @@ +use std::io; +use std::fmt; +use std::num::ParseIntError; + +#[derive(Debug)] +pub enum CliError { + Io(io::Error), + Json(serde_json::Error), + Network(reqwest::Error), + Anyhow(anyhow::Error), + Zip(zip::result::ZipError), + Walkdir(walkdir::Error), + Parse(ParseIntError), + NotFound(String), + InvalidData(String), +} + +impl fmt::Display for CliError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + CliError::Io(e) => write!(f, "IO错误: {}", e), + CliError::Json(e) => write!(f, "JSON解析错误: {}", e), + CliError::Network(e) => write!(f, "网络错误: {}", e), + CliError::Anyhow(e) => write!(f, "{}", e), + CliError::Zip(e) => write!(f, "压缩错误: {}", e), + CliError::Walkdir(e) => write!(f, "目录遍历错误: {}", e), + CliError::Parse(e) => write!(f, "解析错误: {}", e), + CliError::NotFound(msg) => write!(f, "未找到: {}", msg), + CliError::InvalidData(msg) => write!(f, "无效数据: {}", msg), + } + } +} + +impl std::error::Error for CliError {} + +impl From for CliError { + fn from(err: io::Error) -> Self { + CliError::Io(err) + } +} + +impl From for CliError { + fn from(err: serde_json::Error) -> Self { + CliError::Json(err) + } +} + +impl From for CliError { + fn from(err: reqwest::Error) -> Self { + CliError::Network(err) + } +} + +impl From for CliError { + fn from(err: anyhow::Error) -> Self { + CliError::Anyhow(err) + } +} + +impl From for CliError { + fn from(err: zip::result::ZipError) -> Self { + CliError::Zip(err) + } +} + +impl From for CliError { + fn from(err: walkdir::Error) -> Self { + CliError::Walkdir(err) + } +} + +impl From for CliError { + fn from(err: ParseIntError) -> Self { + CliError::Parse(err) + } +} + +pub type Result = std::result::Result; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..92865c3 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,28 @@ +mod commands; +mod entity; +mod utils; +mod error; +mod config; + +use crate::commands::{Cli, Commands}; +use clap::Parser; +use std::{env, fs, path::PathBuf}; + +fn main() { + let cli = Cli::parse(); + let temp_dir = check_temp_dir(); + match &cli.command { + Commands::Release(args) => commands::release::execute(args), + Commands::Create(args) => commands::create::execute(args, &temp_dir), + Commands::Components(args) => commands::components::execute(args), + } +} + +fn check_temp_dir() -> PathBuf { + let mut temp_dir = env::temp_dir(); + temp_dir.push("emod-cli"); + if let Err(e) = fs::create_dir_all(&temp_dir) { + eprintln!("Error: Failed to create temp directory: {}", e); + } + temp_dir +} \ No newline at end of file diff --git a/src/utils/file.rs b/src/utils/file.rs new file mode 100644 index 0000000..e87088d --- /dev/null +++ b/src/utils/file.rs @@ -0,0 +1,53 @@ +use crate::error::Result; +use serde_json::Value; +use std::{fs, path::PathBuf}; + +pub fn copy_folder(src: &PathBuf, dest: &PathBuf) -> Result<()> { + if !src.exists() || !src.is_dir() { + return Err(crate::error::CliError::NotFound(format!( + "源目录不存在: {}", + src.display() + ))); + } + if !dest.exists() { + fs::create_dir_all(dest)?; + } + for entry in fs::read_dir(src)? { + let entry = entry?; + let src_path = entry.path(); + let dest_path = dest.join(src_path.file_name().unwrap()); + if src_path.is_file() { + fs::copy(&src_path, &dest_path)?; + } else if src_path.is_dir() { + copy_folder(&src_path, &dest_path)?; + } + } + Ok(()) +} + +pub fn read_file_to_json(path: &PathBuf) -> Result { + let file = fs::read_to_string(path)?; + let json: Value = serde_json::from_str(&file)?; + Ok(json) +} + +pub fn write_json_to_file(path: &PathBuf, value: &Value) -> Result<()> { + let content = serde_json::to_string_pretty(value)?; + fs::write(path, content)?; + Ok(()) +} + +pub fn update_json_file(path: &PathBuf, updater: F) -> Result<()> +where + F: FnOnce(&mut Value) -> Result<()>, +{ + let mut json = read_file_to_json(path)?; + updater(&mut json)?; + write_json_to_file(path, &json)?; + Ok(()) +} + +pub fn find_project_dir(path: &Option) -> Result { + let path = path.as_deref().unwrap_or("."); + Ok(PathBuf::from(path)) +} diff --git a/src/utils/git.rs b/src/utils/git.rs new file mode 100644 index 0000000..3351b22 --- /dev/null +++ b/src/utils/git.rs @@ -0,0 +1,11 @@ +use std::path::PathBuf; +use crate::error::Result; + +pub fn clone_remote_project(url: String, temp_dir: &PathBuf) -> Result<()> { + std::process::Command::new("git") + .arg("clone") + .arg(url) + .arg(format!("{}/tmp", temp_dir.display())) + .output()?; + Ok(()) +} \ No newline at end of file diff --git a/src/utils/http.rs b/src/utils/http.rs new file mode 100644 index 0000000..d25a2eb --- /dev/null +++ b/src/utils/http.rs @@ -0,0 +1,26 @@ +use reqwest::blocking::Client; +use crate::error::Result; + +pub struct HttpClient { + client: Client, +} + +impl HttpClient { + pub fn new() -> Result { + let client = Client::builder().build()?; + Ok(Self { client }) + } + + pub fn new_with_proxy(proxy_url: &str) -> Result { + let proxy = reqwest::Proxy::all(proxy_url)?; + let client = Client::builder().proxy(proxy).build()?; + Ok(Self { client }) + } + + pub fn get(&self, url: &str) -> Result { + Ok(self.client + .get(url) + .header("User-Agent", "emod-cli") + .send()?) + } +} diff --git a/src/utils/mod.rs b/src/utils/mod.rs new file mode 100644 index 0000000..7da93c1 --- /dev/null +++ b/src/utils/mod.rs @@ -0,0 +1,3 @@ +pub mod git; +pub mod file; +pub mod http; \ No newline at end of file