diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index a25e2e7..df64d9c 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,70 +1,70 @@
-name: Build
-on:
- push:
- branches:
- - main
- pull_request:
- branches:
- - main
-
-jobs:
- build-server:
- name: Server
- runs-on: ubuntu-latest
- container: golang:alpine
- steps:
- - uses: actions/checkout@v4
- - uses: arduino/setup-task@v2
- with:
- version: 3.x
- repo-token: ${{ secrets.GITHUB_TOKEN }}
- - uses: actions/setup-go@v5
- - run: task server:build
- - uses: actions/upload-artifact@v4
- with:
- path: server/build/botw-iss
- name: server
- retention-days: 3
-
- build-manual:
- name: Manual
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: arduino/setup-task@v2
- with:
- version: 3.x
- repo-token: ${{ secrets.GITHUB_TOKEN }}
- - uses: cargo-bins/cargo-binstall@main
- - run: cargo-binstall --no-confirm mdbook
- - run: task manual:build
- - uses: actions/upload-artifact@v4
- with:
- path: manual/book
- name: manual
- retention-days: 3
-
- build-legacy:
- name: Legacy App
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: arduino/setup-task@v2
- with:
- version: 3.x
- repo-token: ${{ secrets.GITHUB_TOKEN }}
- - uses: actions/setup-python@v5
- with:
- python-version: '3.11'
- - uses: actions/setup-node@v4
- with:
- node-version: 18.x
- - run: task leg:ci
- - run: task leg:build
- - uses: actions/upload-artifact@v4
- with:
- path: legacy/dist
- name: legacy
- retention-days: 3
+# name: Build
+# on:
+# push:
+# branches:
+# - main
+# pull_request:
+# branches:
+# - main
+#
+# jobs:
+# build-server:
+# name: Server
+# runs-on: ubuntu-latest
+# container: golang:alpine
+# steps:
+# - uses: actions/checkout@v4
+# - uses: arduino/setup-task@v2
+# with:
+# version: 3.x
+# repo-token: ${{ secrets.GITHUB_TOKEN }}
+# - uses: actions/setup-go@v5
+# - run: task server:build
+# - uses: actions/upload-artifact@v4
+# with:
+# path: server/build/botw-iss
+# name: server
+# retention-days: 3
+#
+# build-manual:
+# name: Manual
+# runs-on: ubuntu-latest
+# steps:
+# - uses: actions/checkout@v4
+# - uses: arduino/setup-task@v2
+# with:
+# version: 3.x
+# repo-token: ${{ secrets.GITHUB_TOKEN }}
+# - uses: cargo-bins/cargo-binstall@main
+# - run: cargo-binstall --no-confirm mdbook
+# - run: task manual:build
+# - uses: actions/upload-artifact@v4
+# with:
+# path: manual/book
+# name: manual
+# retention-days: 3
+ # build-legacy:
+ # name: Legacy App
+ # runs-on: ubuntu-latest
+ # steps:
+ # - uses: actions/checkout@v4
+ # - uses: arduino/setup-task@v2
+ # with:
+ # version: 3.x
+ # repo-token: ${{ secrets.GITHUB_TOKEN }}
+ # - uses: actions/setup-python@v5
+ # with:
+ # python-version: '3.11'
+ # - uses: actions/setup-node@v4
+ # with:
+ # node-version: 18.x
+ # - run: task leg:ci
+ # - run: task leg:build
+ # - uses: actions/upload-artifact@v4
+ # with:
+ # path: legacy/dist
+ # name: legacy
+ # retention-days: 3
+ #
diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index a05d4e9..dbd8cfc 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -1,40 +1,22 @@
-name: Check
-on:
- push:
- branches:
- - main
- pull_request:
- branches:
- - main
-
-jobs:
- check-server:
- name: Server
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: arduino/setup-task@v2
- with:
- version: 3.x
- repo-token: ${{ secrets.GITHUB_TOKEN }}
- - uses: actions/setup-go@v5
- - run: task server:check
-
- check-legacy:
- name: Legacy App
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: arduino/setup-task@v2
- with:
- version: 3.x
- repo-token: ${{ secrets.GITHUB_TOKEN }}
- - uses: actions/setup-python@v5
- with:
- python-version: '3.11'
- - uses: actions/setup-node@v4
- with:
- node-version: 18.x
- - run: task leg:ci
- - run: task leg:test
- - run: task leg:check
+# name: Check
+# on:
+# push:
+# branches:
+# - main
+# pull_request:
+# branches:
+# - main
+#
+# jobs:
+# check-server:
+# name: Server
+# runs-on: ubuntu-latest
+# steps:
+# - uses: actions/checkout@v4
+# - uses: arduino/setup-task@v2
+# with:
+# version: 3.x
+# repo-token: ${{ secrets.GITHUB_TOKEN }}
+# - uses: actions/setup-go@v5
+# - run: task server:check
+#
diff --git a/.gitignore b/.gitignore
index 5d89c61..9edab59 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,8 @@
# Cargo
/target
+
+# NPM
+/node_modules
+
+/packages/workex
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000..be17ce9
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,3 @@
+*.yaml
+*.yml
+*.gen.ts
diff --git a/Cargo.lock b/Cargo.lock
index 126b08e..f27fa22 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,6 +2,16 @@
# It is not intended for manual editing.
version = 4
+[[package]]
+name = "actor-sys"
+version = "0.0.0"
+
+[[package]]
+name = "adler2"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
+
[[package]]
name = "aho-corasick"
version = "1.1.3"
@@ -11,6 +21,12 @@ dependencies = [
"memchr",
]
+[[package]]
+name = "aligned-vec"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1"
+
[[package]]
name = "allocator-api2"
version = "0.2.20"
@@ -83,9 +99,32 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.93"
+version = "1.0.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
+
+[[package]]
+name = "arbitrary"
+version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775"
+checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"
+
+[[package]]
+name = "arg_enum_proc_macro"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.92",
+]
+
+[[package]]
+name = "arrayvec"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
name = "autocfg"
@@ -93,34 +132,136 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
+[[package]]
+name = "av1-grain"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf"
+dependencies = [
+ "anyhow",
+ "arrayvec",
+ "log",
+ "nom",
+ "num-rational",
+ "v_frame",
+]
+
+[[package]]
+name = "avif-serialize"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e335041290c43101ca215eed6f43ec437eb5a42125573f600fc3fa42b9bddd62"
+dependencies = [
+ "arrayvec",
+]
+
[[package]]
name = "beef"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1"
+[[package]]
+name = "bit_field"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
[[package]]
name = "bitflags"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+[[package]]
+name = "bitstream-io"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2"
+
+[[package]]
+name = "bitvec"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
+dependencies = [
+ "funty",
+ "radium",
+ "tap",
+ "wyz",
+]
+
+[[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 = "blueflame"
+version = "0.0.0"
+dependencies = [
+ "derive_more",
+ "enumset",
+ "rand_xoshiro",
+ "sha2",
+ "thiserror 2.0.9",
+ "uking-relocate-lib",
+]
+
+[[package]]
+name = "blueflame-macros"
+version = "0.0.0"
+
[[package]]
name = "botw-ist-command"
version = "0.0.0"
dependencies = [
- "logos",
+ "logos 0.14.2",
"phf",
- "teleparse",
+ "teleparse 0.0.4",
"thiserror 1.0.64",
]
+[[package]]
+name = "built"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c360505aed52b7ec96a3636c3f039d99103c37d1d9b4f7a8c743d3ea9ffcd03b"
+
[[package]]
name = "bumpalo"
version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
+[[package]]
+name = "bytemuck"
+version = "1.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3"
+
+[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
+name = "byteorder-lite"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
+
[[package]]
name = "cassowary"
version = "0.3.0"
@@ -142,9 +283,21 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47"
dependencies = [
+ "jobserver",
+ "libc",
"shlex",
]
+[[package]]
+name = "cfg-expr"
+version = "0.15.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02"
+dependencies = [
+ "smallvec",
+ "target-lexicon",
+]
+
[[package]]
name = "cfg-if"
version = "1.0.0"
@@ -173,9 +326,9 @@ dependencies = [
[[package]]
name = "clap"
-version = "4.5.21"
+version = "4.5.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f"
+checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84"
dependencies = [
"clap_builder",
"clap_derive",
@@ -183,9 +336,9 @@ dependencies = [
[[package]]
name = "clap_builder"
-version = "4.5.21"
+version = "4.5.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec"
+checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838"
dependencies = [
"anstream",
"anstyle",
@@ -202,14 +355,29 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
- "syn 2.0.89",
+ "syn 2.0.92",
]
[[package]]
name = "clap_lex"
-version = "0.7.3"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
+
+[[package]]
+name = "codize"
+version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7"
+checksum = "9fc5c2a8623ba8c093aeadf57a112769a87bd364233c0a466643210b78208fbd"
+dependencies = [
+ "derivative",
+]
+
+[[package]]
+name = "color_quant"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "colorchoice"
@@ -246,13 +414,56 @@ 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 = "crc32fast"
+version = "1.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
+dependencies = [
+ "crossbeam-epoch",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
+
[[package]]
name = "crossterm"
version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
dependencies = [
- "bitflags",
+ "bitflags 2.6.0",
"crossterm_winapi",
"mio",
"parking_lot",
@@ -271,6 +482,22 @@ dependencies = [
"winapi",
]
+[[package]]
+name = "crunchy"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
+
+[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
[[package]]
name = "ctrlc"
version = "3.4.5"
@@ -302,7 +529,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim",
- "syn 2.0.89",
+ "syn 2.0.92",
]
[[package]]
@@ -313,7 +540,32 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
dependencies = [
"darling_core",
"quote",
- "syn 2.0.89",
+ "syn 2.0.92",
+]
+
+[[package]]
+name = "deku"
+version = "0.18.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9711031e209dc1306d66985363b4397d4c7b911597580340b93c9729b55f6eb"
+dependencies = [
+ "bitvec",
+ "deku_derive",
+ "no_std_io2",
+ "rustversion",
+]
+
+[[package]]
+name = "deku_derive"
+version = "0.18.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58cb0719583cbe4e81fb40434ace2f0d22ccc3e39a74bb3796c22b451b4f139d"
+dependencies = [
+ "darling",
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.92",
]
[[package]]
@@ -356,7 +608,7 @@ dependencies = [
"convert_case",
"proc-macro2",
"quote",
- "syn 2.0.89",
+ "syn 2.0.92",
"unicode-xid",
]
@@ -366,12 +618,43 @@ version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
+[[package]]
+name = "digest"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
+dependencies = [
+ "block-buffer",
+ "crypto-common",
+]
+
[[package]]
name = "either"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
+[[package]]
+name = "enumset"
+version = "1.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d07a4b049558765cef5f0c1a273c3fc57084d768b44d2f98127aef4cceb17293"
+dependencies = [
+ "enumset_derive",
+]
+
+[[package]]
+name = "enumset_derive"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59c3b24c345d8c314966bdc1832f6c2635bfcce8e7cf363bd115987bba2ee242"
+dependencies = [
+ "darling",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.92",
+]
+
[[package]]
name = "equivalent"
version = "1.0.1"
@@ -388,6 +671,40 @@ dependencies = [
"windows-sys 0.52.0",
]
+[[package]]
+name = "exr"
+version = "1.73.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0"
+dependencies = [
+ "bit_field",
+ "half",
+ "lebe",
+ "miniz_oxide",
+ "rayon-core",
+ "smallvec",
+ "zune-inflate",
+]
+
+[[package]]
+name = "fdeflate"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c"
+dependencies = [
+ "simd-adler32",
+]
+
+[[package]]
+name = "flate2"
+version = "1.0.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c"
+dependencies = [
+ "crc32fast",
+ "miniz_oxide",
+]
+
[[package]]
name = "fnv"
version = "1.0.7"
@@ -400,6 +717,59 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2"
+[[package]]
+name = "funty"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
+
+[[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 = "gif"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2"
+dependencies = [
+ "color_quant",
+ "weezl",
+]
+
+[[package]]
+name = "glob"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
+
+[[package]]
+name = "half"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888"
+dependencies = [
+ "cfg-if",
+ "crunchy",
+]
+
[[package]]
name = "hashbrown"
version = "0.15.0"
@@ -452,6 +822,57 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+[[package]]
+name = "image"
+version = "0.24.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d"
+dependencies = [
+ "bytemuck",
+ "byteorder",
+ "color_quant",
+ "num-traits",
+]
+
+[[package]]
+name = "image"
+version = "0.25.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b"
+dependencies = [
+ "bytemuck",
+ "byteorder-lite",
+ "color_quant",
+ "exr",
+ "gif",
+ "image-webp",
+ "num-traits",
+ "png",
+ "qoi",
+ "ravif",
+ "rayon",
+ "rgb",
+ "tiff",
+ "zune-core",
+ "zune-jpeg",
+]
+
+[[package]]
+name = "image-webp"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e031e8e3d94711a9ccb5d6ea357439ef3dcbed361798bd4071dc4d9793fbe22f"
+dependencies = [
+ "byteorder-lite",
+ "quick-error",
+]
+
+[[package]]
+name = "imgref"
+version = "1.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408"
+
[[package]]
name = "indexmap"
version = "2.6.0"
@@ -479,7 +900,18 @@ dependencies = [
"pretty_assertions",
"proc-macro2",
"quote",
- "syn 2.0.89",
+ "syn 2.0.92",
+]
+
+[[package]]
+name = "interpolate_name"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.92",
]
[[package]]
@@ -489,18 +921,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
-name = "ist-parser"
-version = "0.0.0"
-dependencies = [
- "logos",
- "teleparse",
-]
-
-[[package]]
-name = "ist-runtime"
-version = "0.0.0"
+name = "itertools"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
dependencies = [
- "ist-parser",
+ "either",
]
[[package]]
@@ -518,12 +944,28 @@ version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2"
+[[package]]
+name = "jobserver"
+version = "0.1.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "jpeg-decoder"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0"
+
[[package]]
name = "js-sys"
-version = "0.3.70"
+version = "0.3.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a"
+checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7"
dependencies = [
+ "once_cell",
"wasm-bindgen",
]
@@ -533,12 +975,51 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
+[[package]]
+name = "lebe"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
+
[[package]]
name = "libc"
version = "0.2.164"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f"
+[[package]]
+name = "libfuzzer-sys"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b9569d2f74e257076d8c6bfa73fb505b46b851e51ddaecc825944aa3bed17fa"
+dependencies = [
+ "arbitrary",
+ "cc",
+]
+
+[[package]]
+name = "libwebp-sys"
+version = "0.9.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "54cd30df7c7165ce74a456e4ca9732c603e8dc5e60784558c1c6dc047f876733"
+dependencies = [
+ "cc",
+ "glob",
+]
+
+[[package]]
+name = "libwebp-sys2"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3196c90eb6895d0b6b9520bcc942afa0daf836f928bee77035cc78d4fa1ca163"
+dependencies = [
+ "cc",
+ "cfg-if",
+ "libc",
+ "pkg-config",
+ "vcpkg",
+]
+
[[package]]
name = "linux-raw-sys"
version = "0.4.14"
@@ -567,7 +1048,16 @@ version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c6b6e02facda28ca5fb8dbe4b152496ba3b1bd5a4b40bb2b1b2d8ad74e0f39b"
dependencies = [
- "logos-derive",
+ "logos-derive 0.14.2",
+]
+
+[[package]]
+name = "logos"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab6f536c1af4c7cc81edf73da1f8029896e7e1e16a219ef09b184e76a296f3db"
+dependencies = [
+ "logos-derive 0.15.0",
]
[[package]]
@@ -582,7 +1072,23 @@ dependencies = [
"proc-macro2",
"quote",
"regex-syntax",
- "syn 2.0.89",
+ "syn 2.0.92",
+]
+
+[[package]]
+name = "logos-codegen"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "189bbfd0b61330abea797e5e9276408f2edbe4f822d7ad08685d67419aafb34e"
+dependencies = [
+ "beef",
+ "fnv",
+ "lazy_static",
+ "proc-macro2",
+ "quote",
+ "regex-syntax",
+ "rustc_version",
+ "syn 2.0.92",
]
[[package]]
@@ -591,7 +1097,25 @@ version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e5d0c5463c911ef55624739fc353238b4e310f0144be1f875dc42fec6bfd5ec"
dependencies = [
- "logos-codegen",
+ "logos-codegen 0.14.2",
+]
+
+[[package]]
+name = "logos-derive"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebfe8e1a19049ddbfccbd14ac834b215e11b85b90bab0c2dba7c7b92fb5d5cba"
+dependencies = [
+ "logos-codegen 0.15.0",
+]
+
+[[package]]
+name = "loop9"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062"
+dependencies = [
+ "imgref",
]
[[package]]
@@ -603,12 +1127,38 @@ dependencies = [
"hashbrown",
]
+[[package]]
+name = "maybe-rayon"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519"
+dependencies = [
+ "cfg-if",
+ "rayon",
+]
+
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
+[[package]]
+name = "miniz_oxide"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394"
+dependencies = [
+ "adler2",
+ "simd-adler32",
+]
+
[[package]]
name = "mio"
version = "1.0.2"
@@ -622,18 +1172,49 @@ dependencies = [
"windows-sys 0.52.0",
]
+[[package]]
+name = "new_debug_unreachable"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
+
[[package]]
name = "nix"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
dependencies = [
- "bitflags",
+ "bitflags 2.6.0",
"cfg-if",
"cfg_aliases",
"libc",
]
+[[package]]
+name = "no_std_io2"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a3564ce7035b1e4778d8cb6cacebb5d766b5e8fe5a75b9e441e33fb61a872c6"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "nom"
+version = "7.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
+[[package]]
+name = "noop_proc_macro"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
+
[[package]]
name = "num"
version = "0.4.3"
@@ -667,6 +1248,17 @@ dependencies = [
"num-traits",
]
+[[package]]
+name = "num-derive"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.92",
+]
+
[[package]]
name = "num-integer"
version = "0.1.46"
@@ -775,7 +1367,7 @@ dependencies = [
"phf_shared",
"proc-macro2",
"quote",
- "syn 2.0.89",
+ "syn 2.0.92",
]
[[package]]
@@ -787,12 +1379,40 @@ dependencies = [
"siphasher",
]
+[[package]]
+name = "pkg-config"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
+
+[[package]]
+name = "png"
+version = "0.17.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526"
+dependencies = [
+ "bitflags 1.3.2",
+ "crc32fast",
+ "fdeflate",
+ "flate2",
+ "miniz_oxide",
+]
+
[[package]]
name = "portable-atomic"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2"
+[[package]]
+name = "ppv-lite86"
+version = "0.2.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
+dependencies = [
+ "zerocopy",
+]
+
[[package]]
name = "pretty_assertions"
version = "1.4.1"
@@ -821,29 +1441,93 @@ dependencies = [
"unicode-ident",
]
+[[package]]
+name = "profiling"
+version = "1.0.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d"
+dependencies = [
+ "profiling-procmacros",
+]
+
+[[package]]
+name = "profiling-procmacros"
+version = "1.0.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30"
+dependencies = [
+ "quote",
+ "syn 2.0.92",
+]
+
+[[package]]
+name = "qoi"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001"
+dependencies = [
+ "bytemuck",
+]
+
+[[package]]
+name = "quick-error"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
+
[[package]]
name = "quote"
-version = "1.0.37"
+version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
+checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
dependencies = [
"proc-macro2",
]
+[[package]]
+name = "radium"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
+
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
- "rand_core",
+ "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 = "rand_core"
-version = "0.6.4"
+name = "rand_xoshiro"
+version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa"
+dependencies = [
+ "rand_core",
+]
[[package]]
name = "ratatui"
@@ -851,13 +1535,13 @@ version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b"
dependencies = [
- "bitflags",
+ "bitflags 2.6.0",
"cassowary",
"compact_str",
"crossterm",
"indoc",
"instability",
- "itertools",
+ "itertools 0.13.0",
"lru",
"paste",
"strum",
@@ -866,20 +1550,90 @@ dependencies = [
"unicode-width 0.2.0",
]
+[[package]]
+name = "rav1e"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9"
+dependencies = [
+ "arbitrary",
+ "arg_enum_proc_macro",
+ "arrayvec",
+ "av1-grain",
+ "bitstream-io",
+ "built",
+ "cfg-if",
+ "interpolate_name",
+ "itertools 0.12.1",
+ "libc",
+ "libfuzzer-sys",
+ "log",
+ "maybe-rayon",
+ "new_debug_unreachable",
+ "noop_proc_macro",
+ "num-derive",
+ "num-traits",
+ "once_cell",
+ "paste",
+ "profiling",
+ "rand",
+ "rand_chacha",
+ "simd_helpers",
+ "system-deps",
+ "thiserror 1.0.64",
+ "v_frame",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "ravif"
+version = "0.11.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2413fd96bd0ea5cdeeb37eaf446a22e6ed7b981d792828721e74ded1980a45c6"
+dependencies = [
+ "avif-serialize",
+ "imgref",
+ "loop9",
+ "quick-error",
+ "rav1e",
+ "rayon",
+ "rgb",
+]
+
+[[package]]
+name = "rayon"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
+dependencies = [
+ "either",
+ "rayon-core",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
+dependencies = [
+ "crossbeam-deque",
+ "crossbeam-utils",
+]
+
[[package]]
name = "redox_syscall"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
dependencies = [
- "bitflags",
+ "bitflags 2.6.0",
]
[[package]]
name = "regex"
-version = "1.11.0"
+version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8"
+checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
@@ -904,13 +1658,28 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
+[[package]]
+name = "rgb"
+version = "0.8.50"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a"
+
+[[package]]
+name = "rustc_version"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
+dependencies = [
+ "semver",
+]
+
[[package]]
name = "rustix"
version = "0.38.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6"
dependencies = [
- "bitflags",
+ "bitflags 2.6.0",
"errno",
"libc",
"linux-raw-sys",
@@ -935,31 +1704,37 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+[[package]]
+name = "semver"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba"
+
[[package]]
name = "serde"
-version = "1.0.215"
+version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
+checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.215"
+version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
+checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.89",
+ "syn 2.0.92",
]
[[package]]
name = "serde_json"
-version = "1.0.133"
+version = "1.0.134"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
+checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d"
dependencies = [
"itoa",
"memchr",
@@ -967,6 +1742,48 @@ dependencies = [
"serde",
]
+[[package]]
+name = "serde_spanned"
+version = "0.6.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "serde_variant"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a0068df419f9d9b6488fdded3f1c818522cdea328e02ce9d9f147380265a432"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "serde_yaml_ng"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b4db627b98b36d4203a7b458cf3573730f2bb591b28871d916dfa9efabfd41f"
+dependencies = [
+ "indexmap",
+ "itoa",
+ "ryu",
+ "serde",
+ "unsafe-libyaml",
+]
+
+[[package]]
+name = "sha2"
+version = "0.10.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
[[package]]
name = "shlex"
version = "1.3.0"
@@ -1004,12 +1821,18 @@ dependencies = [
]
[[package]]
-name = "sim"
-version = "0.0.0"
+name = "simd-adler32"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
+
+[[package]]
+name = "simd_helpers"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6"
dependencies = [
- "ist-parser",
- "ist-runtime",
- "wasm-bindgen",
+ "quote",
]
[[package]]
@@ -1018,6 +1841,69 @@ version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
+[[package]]
+name = "skybook-acorn"
+version = "0.0.0"
+dependencies = [
+ "enumset",
+ "heck",
+ "serde",
+ "serde_variant",
+ "serde_yaml_ng",
+]
+
+[[package]]
+name = "skybook-item-animated-encode"
+version = "0.0.0"
+dependencies = [
+ "anyhow",
+ "clap",
+ "image 0.25.5",
+ "serde",
+ "serde_yaml_ng",
+ "webp-animation",
+]
+
+[[package]]
+name = "skybook-item-sprites-generator"
+version = "0.0.0"
+dependencies = [
+ "anyhow",
+ "codize",
+ "image 0.25.5",
+ "serde",
+ "serde_json",
+ "thiserror 2.0.9",
+ "webp",
+]
+
+[[package]]
+name = "skybook-parser"
+version = "0.0.0"
+dependencies = [
+ "derive_more",
+ "teleparse 0.0.5",
+ "thiserror 2.0.9",
+]
+
+[[package]]
+name = "skybook-runtime"
+version = "0.0.0"
+dependencies = [
+ "blueflame",
+ "skybook-parser",
+]
+
+[[package]]
+name = "skybook-runtime-wasm"
+version = "0.0.0"
+dependencies = [
+ "skybook-parser",
+ "skybook-runtime",
+ "teleparse 0.0.5",
+ "wasm-bindgen",
+]
+
[[package]]
name = "skybook-trace-view"
version = "0.0.0"
@@ -1031,7 +1917,7 @@ dependencies = [
"ratatui",
"serde",
"serde_json",
- "thiserror 2.0.3",
+ "thiserror 2.0.9",
]
[[package]]
@@ -1071,7 +1957,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
- "syn 2.0.89",
+ "syn 2.0.92",
]
[[package]]
@@ -1087,15 +1973,40 @@ dependencies = [
[[package]]
name = "syn"
-version = "2.0.89"
+version = "2.0.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e"
+checksum = "70ae51629bf965c5c098cc9e87908a3df5301051a9e087d6f9bef5c9771ed126"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
+[[package]]
+name = "system-deps"
+version = "6.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349"
+dependencies = [
+ "cfg-expr",
+ "heck",
+ "pkg-config",
+ "toml",
+ "version-compare",
+]
+
+[[package]]
+name = "tap"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
+
+[[package]]
+name = "target-lexicon"
+version = "0.12.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
+
[[package]]
name = "teleparse"
version = "0.0.4"
@@ -1104,13 +2015,28 @@ checksum = "80436d09591939259a48971e0958fa1f448ccfc52cd866aa6e3a2ac22f453a7a"
dependencies = [
"deref-derive",
"derivative",
- "itertools",
- "logos",
+ "itertools 0.13.0",
+ "logos 0.14.2",
"num",
- "teleparse-macros",
+ "teleparse-macros 0.0.4",
"thiserror 1.0.64",
]
+[[package]]
+name = "teleparse"
+version = "0.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e9f9b8e0b35f32a2a8764f1ec9ca73cf7e5f891b1fd202732d7aef44cd754046"
+dependencies = [
+ "deref-derive",
+ "derivative",
+ "itertools 0.13.0",
+ "logos 0.15.0",
+ "num",
+ "teleparse-macros 0.0.5",
+ "thiserror 2.0.9",
+]
+
[[package]]
name = "teleparse-macros"
version = "0.0.4"
@@ -1121,7 +2047,20 @@ dependencies = [
"proc-macro2",
"quote",
"regex",
- "syn 2.0.89",
+ "syn 2.0.92",
+]
+
+[[package]]
+name = "teleparse-macros"
+version = "0.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef3618b9de151b5026c7de82b32a4f4445a97fe6c97959d1f274896d7c4e18aa"
+dependencies = [
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "regex",
+ "syn 2.0.92",
]
[[package]]
@@ -1135,11 +2074,11 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "2.0.3"
+version = "2.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa"
+checksum = "f072643fd0190df67a8bab670c20ef5d8737177d6ac6b2e9a236cb096206b2cc"
dependencies = [
- "thiserror-impl 2.0.3",
+ "thiserror-impl 2.0.9",
]
[[package]]
@@ -1150,18 +2089,41 @@ checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.89",
+ "syn 2.0.92",
]
[[package]]
name = "thiserror-impl"
-version = "2.0.3"
+version = "2.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568"
+checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.89",
+ "syn 2.0.92",
+]
+
+[[package]]
+name = "tiff"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e"
+dependencies = [
+ "flate2",
+ "jpeg-decoder",
+ "weezl",
+]
+
+[[package]]
+name = "toml"
+version = "0.8.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
+dependencies = [
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_edit",
]
[[package]]
@@ -1169,6 +2131,9 @@ name = "toml_datetime"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
+dependencies = [
+ "serde",
+]
[[package]]
name = "toml_edit"
@@ -1177,10 +2142,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
dependencies = [
"indexmap",
+ "serde",
+ "serde_spanned",
"toml_datetime",
"winnow",
]
+[[package]]
+name = "typenum"
+version = "1.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
+
+[[package]]
+name = "uking-relocate-lib"
+version = "0.0.0"
+source = "git+https://github.com/Pistonight/symbotw?rev=57e51a922e4e3c83d13d97d6e183a32f0533113e#57e51a922e4e3c83d13d97d6e183a32f0533113e"
+dependencies = [
+ "deku",
+ "flate2",
+ "serde",
+ "thiserror 2.0.9",
+]
+
[[package]]
name = "unicode-ident"
version = "1.0.13"
@@ -1199,7 +2183,7 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf"
dependencies = [
- "itertools",
+ "itertools 0.13.0",
"unicode-segmentation",
"unicode-width 0.1.14",
]
@@ -1222,12 +2206,47 @@ version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
+[[package]]
+name = "unsafe-libyaml"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
+
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
+[[package]]
+name = "v_frame"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b"
+dependencies = [
+ "aligned-vec",
+ "num-traits",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+
+[[package]]
+name = "version-compare"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b"
+
+[[package]]
+name = "version_check"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
+
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
@@ -1236,35 +2255,36 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
-version = "0.2.93"
+version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5"
+checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396"
dependencies = [
"cfg-if",
"once_cell",
+ "serde",
+ "serde_json",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
-version = "0.2.93"
+version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b"
+checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79"
dependencies = [
"bumpalo",
"log",
- "once_cell",
"proc-macro2",
"quote",
- "syn 2.0.89",
+ "syn 2.0.92",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.93"
+version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf"
+checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -1272,22 +2292,49 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.93"
+version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
+checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.89",
+ "syn 2.0.92",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.93"
+version = "0.2.99"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6"
+
+[[package]]
+name = "webp"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f53152f51fb5af0c08484c33d16cca96175881d1f3dec068c23b31a158c2d99"
+dependencies = [
+ "image 0.25.5",
+ "libwebp-sys",
+]
+
+[[package]]
+name = "webp-animation"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3a656b424e13a9e8b35f2cb7f96ff81c9d796b7ce3b6966cd4f8fd4a15feba4"
+dependencies = [
+ "image 0.24.9",
+ "libwebp-sys2",
+ "log",
+]
+
+[[package]]
+name = "weezl"
+version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
+checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082"
[[package]]
name = "winapi"
@@ -1411,8 +2458,62 @@ dependencies = [
"memchr",
]
+[[package]]
+name = "wyz"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
+dependencies = [
+ "tap",
+]
+
[[package]]
name = "yansi"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
+
+[[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 2.0.92",
+]
+
+[[package]]
+name = "zune-core"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
+
+[[package]]
+name = "zune-inflate"
+version = "0.2.54"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02"
+dependencies = [
+ "simd-adler32",
+]
+
+[[package]]
+name = "zune-jpeg"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "99a5bab8d7dedf81405c4bb1f2b83ea057643d9cb28778cea9eecddeedd2e028"
+dependencies = [
+ "zune-core",
+]
diff --git a/Cargo.toml b/Cargo.toml
index 4039500..df205d2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,7 +1,15 @@
[workspace]
resolver = "2"
-members = [ "app/src/sim",
- "sim/parser",
- "sim/runtime",
- "next/botw-ist-command", "research/trace-view",
+members = [
+ "packages/runtime",
+ "next/botw-ist-command",
+ "research/trace-view",
+ "packages/actor-sys",
+ "packages/item-assets",
+ "packages/item-animated",
+ "packages/parser",
+ "packages/runtime-wasm",
+ "packages/acorn",
+ "packages/blueflame",
+ "packages/blueflame-macros",
]
diff --git a/Taskfile.yml b/Taskfile.yml
index f8169e5..242dc6d 100644
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -8,8 +8,12 @@ dotenv: [".env"]
includes:
app:
- taskfile: ./app
- dir: ./app
+ taskfile: ./packages/app
+ dir: ./packages/app
+
+ monaco-editor:
+ taskfile: ./packages/monaco-editor-contrib
+ dir: ./packages/monaco-editor-contrib
manual:
aliases: [man]
@@ -36,7 +40,22 @@ includes:
dir: ./research/trace-view
tasks:
- install:
+ npm-install:
+ aliases: [npmi]
+ desc: Wrapper for npm install to put everything in the right place
+ cmds:
+ - task: monaco-editor:clean
+ - npm install
+ - task: fix-npm-installs
+
+ fix-npm-installs:
+ cmds:
+ - mv node_modules/monaco-editor packages/monaco-editor-contrib/lib
+ - task: monaco-editor:patch
+
+
+
+ install-tools:
desc: Install tools
cmds:
- cargo install mdbook live-server cargo-watch wasm-pack
diff --git a/app/package-lock.json b/app/package-lock.json
deleted file mode 100644
index c251228..0000000
--- a/app/package-lock.json
+++ /dev/null
@@ -1,3063 +0,0 @@
-{
- "name": "botw-ist",
- "version": "0.0.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "botw-ist",
- "version": "0.0.0",
- "dependencies": {
- "react": "^18.3.1",
- "react-dom": "^18.3.1"
- },
- "devDependencies": {
- "@eslint/js": "^9.9.0",
- "@types/react": "^18.3.3",
- "@types/react-dom": "^18.3.0",
- "@vitejs/plugin-react": "^4.3.1",
- "eslint": "^9.9.0",
- "eslint-plugin-react-hooks": "^5.1.0-rc.0",
- "eslint-plugin-react-refresh": "^0.4.9",
- "globals": "^15.9.0",
- "prettier": "^3.3.3",
- "typescript": "^5.5.3",
- "typescript-eslint": "^8.0.1",
- "vite": "^5.4.1"
- }
- },
- "node_modules/@ampproject/remapping": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
- "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
- "dev": true,
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/code-frame": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
- "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
- "dev": true,
- "dependencies": {
- "@babel/highlight": "^7.24.7",
- "picocolors": "^1.0.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/compat-data": {
- "version": "7.25.4",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz",
- "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/core": {
- "version": "7.25.2",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz",
- "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==",
- "dev": true,
- "dependencies": {
- "@ampproject/remapping": "^2.2.0",
- "@babel/code-frame": "^7.24.7",
- "@babel/generator": "^7.25.0",
- "@babel/helper-compilation-targets": "^7.25.2",
- "@babel/helper-module-transforms": "^7.25.2",
- "@babel/helpers": "^7.25.0",
- "@babel/parser": "^7.25.0",
- "@babel/template": "^7.25.0",
- "@babel/traverse": "^7.25.2",
- "@babel/types": "^7.25.2",
- "convert-source-map": "^2.0.0",
- "debug": "^4.1.0",
- "gensync": "^1.0.0-beta.2",
- "json5": "^2.2.3",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/babel"
- }
- },
- "node_modules/@babel/generator": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz",
- "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.25.6",
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.25",
- "jsesc": "^2.5.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-compilation-targets": {
- "version": "7.25.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz",
- "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==",
- "dev": true,
- "dependencies": {
- "@babel/compat-data": "^7.25.2",
- "@babel/helper-validator-option": "^7.24.8",
- "browserslist": "^4.23.1",
- "lru-cache": "^5.1.1",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-imports": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz",
- "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==",
- "dev": true,
- "dependencies": {
- "@babel/traverse": "^7.24.7",
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-transforms": {
- "version": "7.25.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz",
- "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==",
- "dev": true,
- "dependencies": {
- "@babel/helper-module-imports": "^7.24.7",
- "@babel/helper-simple-access": "^7.24.7",
- "@babel/helper-validator-identifier": "^7.24.7",
- "@babel/traverse": "^7.25.2"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-plugin-utils": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz",
- "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-simple-access": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz",
- "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==",
- "dev": true,
- "dependencies": {
- "@babel/traverse": "^7.24.7",
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-string-parser": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
- "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
- "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-option": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz",
- "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helpers": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz",
- "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==",
- "dev": true,
- "dependencies": {
- "@babel/template": "^7.25.0",
- "@babel/types": "^7.25.6"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/highlight": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
- "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
- "dev": true,
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.24.7",
- "chalk": "^2.4.2",
- "js-tokens": "^4.0.0",
- "picocolors": "^1.0.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz",
- "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.25.6"
- },
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/plugin-transform-react-jsx-self": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.7.tgz",
- "integrity": "sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-react-jsx-source": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.7.tgz",
- "integrity": "sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/template": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz",
- "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==",
- "dev": true,
- "dependencies": {
- "@babel/code-frame": "^7.24.7",
- "@babel/parser": "^7.25.0",
- "@babel/types": "^7.25.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/traverse": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz",
- "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==",
- "dev": true,
- "dependencies": {
- "@babel/code-frame": "^7.24.7",
- "@babel/generator": "^7.25.6",
- "@babel/parser": "^7.25.6",
- "@babel/template": "^7.25.0",
- "@babel/types": "^7.25.6",
- "debug": "^4.3.1",
- "globals": "^11.1.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/traverse/node_modules/globals": {
- "version": "11.12.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
- "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/@babel/types": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz",
- "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==",
- "dev": true,
- "dependencies": {
- "@babel/helper-string-parser": "^7.24.8",
- "@babel/helper-validator-identifier": "^7.24.7",
- "to-fast-properties": "^2.0.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@esbuild/aix-ppc64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
- "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "aix"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/android-arm": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
- "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/android-arm64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
- "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/android-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
- "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
- "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/darwin-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
- "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/freebsd-arm64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
- "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/freebsd-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
- "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-arm": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
- "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-arm64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
- "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-ia32": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
- "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
- "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-mips64el": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
- "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-ppc64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
- "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-riscv64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
- "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-s390x": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
- "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
- "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/netbsd-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
- "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/openbsd-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
- "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/sunos-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
- "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/win32-arm64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
- "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/win32-ia32": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
- "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/win32-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
- "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@eslint-community/eslint-utils": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
- "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
- "dev": true,
- "dependencies": {
- "eslint-visitor-keys": "^3.3.0"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "peerDependencies": {
- "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
- }
- },
- "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
- "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
- "dev": true,
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/@eslint-community/regexpp": {
- "version": "4.11.1",
- "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz",
- "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==",
- "dev": true,
- "engines": {
- "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
- }
- },
- "node_modules/@eslint/config-array": {
- "version": "0.18.0",
- "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz",
- "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==",
- "dev": true,
- "dependencies": {
- "@eslint/object-schema": "^2.1.4",
- "debug": "^4.3.1",
- "minimatch": "^3.1.2"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/core": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz",
- "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==",
- "dev": true,
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/eslintrc": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz",
- "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==",
- "dev": true,
- "dependencies": {
- "ajv": "^6.12.4",
- "debug": "^4.3.2",
- "espree": "^10.0.1",
- "globals": "^14.0.0",
- "ignore": "^5.2.0",
- "import-fresh": "^3.2.1",
- "js-yaml": "^4.1.0",
- "minimatch": "^3.1.2",
- "strip-json-comments": "^3.1.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/@eslint/eslintrc/node_modules/globals": {
- "version": "14.0.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
- "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
- "dev": true,
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@eslint/js": {
- "version": "9.11.1",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.11.1.tgz",
- "integrity": "sha512-/qu+TWz8WwPWc7/HcIJKi+c+MOm46GdVaSlTTQcaqaL53+GsoA6MxWp5PtTx48qbSP7ylM1Kn7nhvkugfJvRSA==",
- "dev": true,
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/object-schema": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz",
- "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==",
- "dev": true,
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/plugin-kit": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz",
- "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==",
- "dev": true,
- "dependencies": {
- "levn": "^0.4.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@humanwhocodes/module-importer": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
- "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
- "dev": true,
- "engines": {
- "node": ">=12.22"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/nzakas"
- }
- },
- "node_modules/@humanwhocodes/retry": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz",
- "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==",
- "dev": true,
- "engines": {
- "node": ">=18.18"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/nzakas"
- }
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
- "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
- "dev": true,
- "dependencies": {
- "@jridgewell/set-array": "^1.2.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.24"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "dev": true,
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/set-array": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
- "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
- "dev": true,
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
- "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
- "dev": true
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.25",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
- "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
- "dev": true,
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@nodelib/fs.scandir": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
- "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
- "dev": true,
- "dependencies": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.stat": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
- "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
- "dev": true,
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.walk": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
- "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
- "dev": true,
- "dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.5.tgz",
- "integrity": "sha512-SU5cvamg0Eyu/F+kLeMXS7GoahL+OoizlclVFX3l5Ql6yNlywJJ0OuqTzUx0v+aHhPHEB/56CT06GQrRrGNYww==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "android"
- ]
- },
- "node_modules/@rollup/rollup-android-arm64": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.5.tgz",
- "integrity": "sha512-S4pit5BP6E5R5C8S6tgU/drvgjtYW76FBuG6+ibG3tMvlD1h9LHVF9KmlmaUBQ8Obou7hEyS+0w+IR/VtxwNMQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "android"
- ]
- },
- "node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.5.tgz",
- "integrity": "sha512-250ZGg4ipTL0TGvLlfACkIxS9+KLtIbn7BCZjsZj88zSg2Lvu3Xdw6dhAhfe/FjjXPVNCtcSp+WZjVsD3a/Zlw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.5.tgz",
- "integrity": "sha512-D8brJEFg5D+QxFcW6jYANu+Rr9SlKtTenmsX5hOSzNYVrK5oLAEMTUgKWYJP+wdKyCdeSwnapLsn+OVRFycuQg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.5.tgz",
- "integrity": "sha512-PNqXYmdNFyWNg0ma5LdY8wP+eQfdvyaBAojAXgO7/gs0Q/6TQJVXAXe8gwW9URjbS0YAammur0fynYGiWsKlXw==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.5.tgz",
- "integrity": "sha512-kSSCZOKz3HqlrEuwKd9TYv7vxPYD77vHSUvM2y0YaTGnFc8AdI5TTQRrM1yIp3tXCKrSL9A7JLoILjtad5t8pQ==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.5.tgz",
- "integrity": "sha512-oTXQeJHRbOnwRnRffb6bmqmUugz0glXaPyspp4gbQOPVApdpRrY/j7KP3lr7M8kTfQTyrBUzFjj5EuHAhqH4/w==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.5.tgz",
- "integrity": "sha512-qnOTIIs6tIGFKCHdhYitgC2XQ2X25InIbZFor5wh+mALH84qnFHvc+vmWUpyX97B0hNvwNUL4B+MB8vJvH65Fw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.5.tgz",
- "integrity": "sha512-TMYu+DUdNlgBXING13rHSfUc3Ky5nLPbWs4bFnT+R6Vu3OvXkTkixvvBKk8uO4MT5Ab6lC3U7x8S8El2q5o56w==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.5.tgz",
- "integrity": "sha512-PTQq1Kz22ZRvuhr3uURH+U/Q/a0pbxJoICGSprNLAoBEkyD3Sh9qP5I0Asn0y0wejXQBbsVMRZRxlbGFD9OK4A==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.5.tgz",
- "integrity": "sha512-bR5nCojtpuMss6TDEmf/jnBnzlo+6n1UhgwqUvRoe4VIotC7FG1IKkyJbwsT7JDsF2jxR+NTnuOwiGv0hLyDoQ==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.5.tgz",
- "integrity": "sha512-N0jPPhHjGShcB9/XXZQWuWBKZQnC1F36Ce3sDqWpujsGjDz/CQtOL9LgTrJ+rJC8MJeesMWrMWVLKKNR/tMOCA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.5.tgz",
- "integrity": "sha512-uBa2e28ohzNNwjr6Uxm4XyaA1M/8aTgfF2T7UIlElLaeXkgpmIJ2EitVNQxjO9xLLLy60YqAgKn/AqSpCUkE9g==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.5.tgz",
- "integrity": "sha512-RXT8S1HP8AFN/Kr3tg4fuYrNxZ/pZf1HemC5Tsddc6HzgGnJm0+Lh5rAHJkDuW3StI0ynNXukidROMXYl6ew8w==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.5.tgz",
- "integrity": "sha512-ElTYOh50InL8kzyUD6XsnPit7jYCKrphmddKAe1/Ytt74apOxDq5YEcbsiKs0fR3vff3jEneMM+3I7jbqaMyBg==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.5.tgz",
- "integrity": "sha512-+lvL/4mQxSV8MukpkKyyvfwhH266COcWlXE/1qxwN08ajovta3459zrjLghYMgDerlzNwLAcFpvU+WWE5y6nAQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@types/babel__core": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
- "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
- "dev": true,
- "dependencies": {
- "@babel/parser": "^7.20.7",
- "@babel/types": "^7.20.7",
- "@types/babel__generator": "*",
- "@types/babel__template": "*",
- "@types/babel__traverse": "*"
- }
- },
- "node_modules/@types/babel__generator": {
- "version": "7.6.8",
- "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz",
- "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.0.0"
- }
- },
- "node_modules/@types/babel__template": {
- "version": "7.4.4",
- "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
- "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
- "dev": true,
- "dependencies": {
- "@babel/parser": "^7.1.0",
- "@babel/types": "^7.0.0"
- }
- },
- "node_modules/@types/babel__traverse": {
- "version": "7.20.6",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz",
- "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.20.7"
- }
- },
- "node_modules/@types/estree": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
- "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
- "dev": true
- },
- "node_modules/@types/json-schema": {
- "version": "7.0.15",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
- "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
- "dev": true
- },
- "node_modules/@types/prop-types": {
- "version": "15.7.13",
- "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz",
- "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==",
- "dev": true
- },
- "node_modules/@types/react": {
- "version": "18.3.10",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.10.tgz",
- "integrity": "sha512-02sAAlBnP39JgXwkAq3PeU9DVaaGpZyF3MGcC0MKgQVkZor5IiiDAipVaxQHtDJAmO4GIy/rVBy/LzVj76Cyqg==",
- "dev": true,
- "dependencies": {
- "@types/prop-types": "*",
- "csstype": "^3.0.2"
- }
- },
- "node_modules/@types/react-dom": {
- "version": "18.3.0",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz",
- "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==",
- "dev": true,
- "dependencies": {
- "@types/react": "*"
- }
- },
- "node_modules/@typescript-eslint/eslint-plugin": {
- "version": "8.7.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.7.0.tgz",
- "integrity": "sha512-RIHOoznhA3CCfSTFiB6kBGLQtB/sox+pJ6jeFu6FxJvqL8qRxq/FfGO/UhsGgQM9oGdXkV4xUgli+dt26biB6A==",
- "dev": true,
- "dependencies": {
- "@eslint-community/regexpp": "^4.10.0",
- "@typescript-eslint/scope-manager": "8.7.0",
- "@typescript-eslint/type-utils": "8.7.0",
- "@typescript-eslint/utils": "8.7.0",
- "@typescript-eslint/visitor-keys": "8.7.0",
- "graphemer": "^1.4.0",
- "ignore": "^5.3.1",
- "natural-compare": "^1.4.0",
- "ts-api-utils": "^1.3.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
- "eslint": "^8.57.0 || ^9.0.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/parser": {
- "version": "8.7.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.7.0.tgz",
- "integrity": "sha512-lN0btVpj2unxHlNYLI//BQ7nzbMJYBVQX5+pbNXvGYazdlgYonMn4AhhHifQ+J4fGRYA/m1DjaQjx+fDetqBOQ==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/scope-manager": "8.7.0",
- "@typescript-eslint/types": "8.7.0",
- "@typescript-eslint/typescript-estree": "8.7.0",
- "@typescript-eslint/visitor-keys": "8.7.0",
- "debug": "^4.3.4"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/scope-manager": {
- "version": "8.7.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.7.0.tgz",
- "integrity": "sha512-87rC0k3ZlDOuz82zzXRtQ7Akv3GKhHs0ti4YcbAJtaomllXoSO8hi7Ix3ccEvCd824dy9aIX+j3d2UMAfCtVpg==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/types": "8.7.0",
- "@typescript-eslint/visitor-keys": "8.7.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/type-utils": {
- "version": "8.7.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.7.0.tgz",
- "integrity": "sha512-tl0N0Mj3hMSkEYhLkjREp54OSb/FI6qyCzfiiclvJvOqre6hsZTGSnHtmFLDU8TIM62G7ygEa1bI08lcuRwEnQ==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/typescript-estree": "8.7.0",
- "@typescript-eslint/utils": "8.7.0",
- "debug": "^4.3.4",
- "ts-api-utils": "^1.3.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/types": {
- "version": "8.7.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.7.0.tgz",
- "integrity": "sha512-LLt4BLHFwSfASHSF2K29SZ+ZCsbQOM+LuarPjRUuHm+Qd09hSe3GCeaQbcCr+Mik+0QFRmep/FyZBO6fJ64U3w==",
- "dev": true,
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree": {
- "version": "8.7.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.7.0.tgz",
- "integrity": "sha512-MC8nmcGHsmfAKxwnluTQpNqceniT8SteVwd2voYlmiSWGOtjvGXdPl17dYu2797GVscK30Z04WRM28CrKS9WOg==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/types": "8.7.0",
- "@typescript-eslint/visitor-keys": "8.7.0",
- "debug": "^4.3.4",
- "fast-glob": "^3.3.2",
- "is-glob": "^4.0.3",
- "minimatch": "^9.0.4",
- "semver": "^7.6.0",
- "ts-api-utils": "^1.3.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
- "dev": true,
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
- "dev": true,
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
- "version": "7.6.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
- "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
- "dev": true,
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@typescript-eslint/utils": {
- "version": "8.7.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.7.0.tgz",
- "integrity": "sha512-ZbdUdwsl2X/s3CiyAu3gOlfQzpbuG3nTWKPoIvAu1pu5r8viiJvv2NPN2AqArL35NCYtw/lrPPfM4gxrMLNLPw==",
- "dev": true,
- "dependencies": {
- "@eslint-community/eslint-utils": "^4.4.0",
- "@typescript-eslint/scope-manager": "8.7.0",
- "@typescript-eslint/types": "8.7.0",
- "@typescript-eslint/typescript-estree": "8.7.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0"
- }
- },
- "node_modules/@typescript-eslint/visitor-keys": {
- "version": "8.7.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.7.0.tgz",
- "integrity": "sha512-b1tx0orFCCh/THWPQa2ZwWzvOeyzzp36vkJYOpVg0u8UVOIsfVrnuC9FqAw9gRKn+rG2VmWQ/zDJZzkxUnj/XQ==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/types": "8.7.0",
- "eslint-visitor-keys": "^3.4.3"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
- "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
- "dev": true,
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/@vitejs/plugin-react": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.2.tgz",
- "integrity": "sha512-hieu+o05v4glEBucTcKMK3dlES0OeJlD9YVOAPraVMOInBCwzumaIFiUjr4bHK7NPgnAHgiskUoceKercrN8vg==",
- "dev": true,
- "dependencies": {
- "@babel/core": "^7.25.2",
- "@babel/plugin-transform-react-jsx-self": "^7.24.7",
- "@babel/plugin-transform-react-jsx-source": "^7.24.7",
- "@types/babel__core": "^7.20.5",
- "react-refresh": "^0.14.2"
- },
- "engines": {
- "node": "^14.18.0 || >=16.0.0"
- },
- "peerDependencies": {
- "vite": "^4.2.0 || ^5.0.0"
- }
- },
- "node_modules/acorn": {
- "version": "8.12.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
- "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
- "dev": true,
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/acorn-jsx": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
- "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
- "dev": true,
- "peerDependencies": {
- "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
- }
- },
- "node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "dev": true,
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dev": true,
- "dependencies": {
- "color-convert": "^1.9.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
- },
- "node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true
- },
- "node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "dev": true,
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/browserslist": {
- "version": "4.24.0",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz",
- "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "dependencies": {
- "caniuse-lite": "^1.0.30001663",
- "electron-to-chromium": "^1.5.28",
- "node-releases": "^2.0.18",
- "update-browserslist-db": "^1.1.0"
- },
- "bin": {
- "browserslist": "cli.js"
- },
- "engines": {
- "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
- }
- },
- "node_modules/callsites": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
- "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/caniuse-lite": {
- "version": "1.0.30001664",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001664.tgz",
- "integrity": "sha512-AmE7k4dXiNKQipgn7a2xg558IRqPN3jMQY/rOsbxDhrd0tyChwbITBfiwtnqz8bi2M5mIWbxAYBvk7W7QBUS2g==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ]
- },
- "node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "dev": true,
- "dependencies": {
- "color-name": "1.1.3"
- }
- },
- "node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "dev": true
- },
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true
- },
- "node_modules/convert-source-map": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
- "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
- "dev": true
- },
- "node_modules/cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
- "dev": true,
- "dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/csstype": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
- "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
- "dev": true
- },
- "node_modules/debug": {
- "version": "4.3.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
- "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
- "dev": true,
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/deep-is": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
- "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
- "dev": true
- },
- "node_modules/electron-to-chromium": {
- "version": "1.5.29",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.29.tgz",
- "integrity": "sha512-PF8n2AlIhCKXQ+gTpiJi0VhcHDb69kYX4MtCiivctc2QD3XuNZ/XIOlbGzt7WAjjEev0TtaH6Cu3arZExm5DOw==",
- "dev": true
- },
- "node_modules/esbuild": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
- "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
- "dev": true,
- "hasInstallScript": true,
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=12"
- },
- "optionalDependencies": {
- "@esbuild/aix-ppc64": "0.21.5",
- "@esbuild/android-arm": "0.21.5",
- "@esbuild/android-arm64": "0.21.5",
- "@esbuild/android-x64": "0.21.5",
- "@esbuild/darwin-arm64": "0.21.5",
- "@esbuild/darwin-x64": "0.21.5",
- "@esbuild/freebsd-arm64": "0.21.5",
- "@esbuild/freebsd-x64": "0.21.5",
- "@esbuild/linux-arm": "0.21.5",
- "@esbuild/linux-arm64": "0.21.5",
- "@esbuild/linux-ia32": "0.21.5",
- "@esbuild/linux-loong64": "0.21.5",
- "@esbuild/linux-mips64el": "0.21.5",
- "@esbuild/linux-ppc64": "0.21.5",
- "@esbuild/linux-riscv64": "0.21.5",
- "@esbuild/linux-s390x": "0.21.5",
- "@esbuild/linux-x64": "0.21.5",
- "@esbuild/netbsd-x64": "0.21.5",
- "@esbuild/openbsd-x64": "0.21.5",
- "@esbuild/sunos-x64": "0.21.5",
- "@esbuild/win32-arm64": "0.21.5",
- "@esbuild/win32-ia32": "0.21.5",
- "@esbuild/win32-x64": "0.21.5"
- }
- },
- "node_modules/escalade": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
- "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "dev": true,
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/eslint": {
- "version": "9.11.1",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.11.1.tgz",
- "integrity": "sha512-MobhYKIoAO1s1e4VUrgx1l1Sk2JBR/Gqjjgw8+mfgoLE2xwsHur4gdfTxyTgShrhvdVFTaJSgMiQBl1jv/AWxg==",
- "dev": true,
- "dependencies": {
- "@eslint-community/eslint-utils": "^4.2.0",
- "@eslint-community/regexpp": "^4.11.0",
- "@eslint/config-array": "^0.18.0",
- "@eslint/core": "^0.6.0",
- "@eslint/eslintrc": "^3.1.0",
- "@eslint/js": "9.11.1",
- "@eslint/plugin-kit": "^0.2.0",
- "@humanwhocodes/module-importer": "^1.0.1",
- "@humanwhocodes/retry": "^0.3.0",
- "@nodelib/fs.walk": "^1.2.8",
- "@types/estree": "^1.0.6",
- "@types/json-schema": "^7.0.15",
- "ajv": "^6.12.4",
- "chalk": "^4.0.0",
- "cross-spawn": "^7.0.2",
- "debug": "^4.3.2",
- "escape-string-regexp": "^4.0.0",
- "eslint-scope": "^8.0.2",
- "eslint-visitor-keys": "^4.0.0",
- "espree": "^10.1.0",
- "esquery": "^1.5.0",
- "esutils": "^2.0.2",
- "fast-deep-equal": "^3.1.3",
- "file-entry-cache": "^8.0.0",
- "find-up": "^5.0.0",
- "glob-parent": "^6.0.2",
- "ignore": "^5.2.0",
- "imurmurhash": "^0.1.4",
- "is-glob": "^4.0.0",
- "is-path-inside": "^3.0.3",
- "json-stable-stringify-without-jsonify": "^1.0.1",
- "lodash.merge": "^4.6.2",
- "minimatch": "^3.1.2",
- "natural-compare": "^1.4.0",
- "optionator": "^0.9.3",
- "strip-ansi": "^6.0.1",
- "text-table": "^0.2.0"
- },
- "bin": {
- "eslint": "bin/eslint.js"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://eslint.org/donate"
- },
- "peerDependencies": {
- "jiti": "*"
- },
- "peerDependenciesMeta": {
- "jiti": {
- "optional": true
- }
- }
- },
- "node_modules/eslint-plugin-react-hooks": {
- "version": "5.1.0-rc-fb9a90fa48-20240614",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0-rc-fb9a90fa48-20240614.tgz",
- "integrity": "sha512-xsiRwaDNF5wWNC4ZHLut+x/YcAxksUd9Rizt7LaEn3bV8VyYRpXnRJQlLOfYaVy9esk4DFP4zPPnoNVjq5Gc0w==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
- }
- },
- "node_modules/eslint-plugin-react-refresh": {
- "version": "0.4.12",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.12.tgz",
- "integrity": "sha512-9neVjoGv20FwYtCP6CB1dzR1vr57ZDNOXst21wd2xJ/cTlM2xLq0GWVlSNTdMn/4BtP6cHYBMCSp1wFBJ9jBsg==",
- "dev": true,
- "peerDependencies": {
- "eslint": ">=7"
- }
- },
- "node_modules/eslint-scope": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz",
- "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==",
- "dev": true,
- "dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^5.2.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/eslint-visitor-keys": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz",
- "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==",
- "dev": true,
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/eslint/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/eslint/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/eslint/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/eslint/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/eslint/node_modules/escape-string-regexp": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
- "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/eslint/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/eslint/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/espree": {
- "version": "10.2.0",
- "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz",
- "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==",
- "dev": true,
- "dependencies": {
- "acorn": "^8.12.0",
- "acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^4.1.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/esquery": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
- "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
- "dev": true,
- "dependencies": {
- "estraverse": "^5.1.0"
- },
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/esrecurse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
- "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
- "dev": true,
- "dependencies": {
- "estraverse": "^5.2.0"
- },
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/estraverse": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
- "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
- "dev": true,
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/esutils": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
- "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/fast-deep-equal": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true
- },
- "node_modules/fast-glob": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
- "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
- "dev": true,
- "dependencies": {
- "@nodelib/fs.stat": "^2.0.2",
- "@nodelib/fs.walk": "^1.2.3",
- "glob-parent": "^5.1.2",
- "merge2": "^1.3.0",
- "micromatch": "^4.0.4"
- },
- "engines": {
- "node": ">=8.6.0"
- }
- },
- "node_modules/fast-glob/node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/fast-json-stable-stringify": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
- "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
- "dev": true
- },
- "node_modules/fast-levenshtein": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
- "dev": true
- },
- "node_modules/fastq": {
- "version": "1.17.1",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
- "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
- "dev": true,
- "dependencies": {
- "reusify": "^1.0.4"
- }
- },
- "node_modules/file-entry-cache": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
- "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
- "dev": true,
- "dependencies": {
- "flat-cache": "^4.0.0"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "dev": true,
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/find-up": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "dev": true,
- "dependencies": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/flat-cache": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
- "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
- "dev": true,
- "dependencies": {
- "flatted": "^3.2.9",
- "keyv": "^4.5.4"
- },
- "engines": {
- "node": ">=16"
- }
- },
- "node_modules/flatted": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
- "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
- "dev": true
- },
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
- "hasInstallScript": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/gensync": {
- "version": "1.0.0-beta.2",
- "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
- "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/glob-parent": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
- "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
- "dev": true,
- "dependencies": {
- "is-glob": "^4.0.3"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/globals": {
- "version": "15.9.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz",
- "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==",
- "dev": true,
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/graphemer": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
- "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
- "dev": true
- },
- "node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/ignore": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
- "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
- "dev": true,
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/import-fresh": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
- "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
- "dev": true,
- "dependencies": {
- "parent-module": "^1.0.0",
- "resolve-from": "^4.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
- "dev": true,
- "engines": {
- "node": ">=0.8.19"
- }
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/is-path-inside": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
- "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "dev": true
- },
- "node_modules/js-tokens": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
- },
- "node_modules/js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dev": true,
- "dependencies": {
- "argparse": "^2.0.1"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/jsesc": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
- "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
- "dev": true,
- "bin": {
- "jsesc": "bin/jsesc"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/json-buffer": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
- "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
- "dev": true
- },
- "node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true
- },
- "node_modules/json-stable-stringify-without-jsonify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
- "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
- "dev": true
- },
- "node_modules/json5": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
- "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
- "dev": true,
- "bin": {
- "json5": "lib/cli.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/keyv": {
- "version": "4.5.4",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
- "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
- "dev": true,
- "dependencies": {
- "json-buffer": "3.0.1"
- }
- },
- "node_modules/levn": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
- "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
- "dev": true,
- "dependencies": {
- "prelude-ls": "^1.2.1",
- "type-check": "~0.4.0"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "dev": true,
- "dependencies": {
- "p-locate": "^5.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/lodash.merge": {
- "version": "4.6.2",
- "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
- "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
- "dev": true
- },
- "node_modules/loose-envify": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
- "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
- "dependencies": {
- "js-tokens": "^3.0.0 || ^4.0.0"
- },
- "bin": {
- "loose-envify": "cli.js"
- }
- },
- "node_modules/lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "dev": true,
- "dependencies": {
- "yallist": "^3.0.2"
- }
- },
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "dev": true,
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/micromatch": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "dev": true,
- "dependencies": {
- "braces": "^3.0.3",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true
- },
- "node_modules/nanoid": {
- "version": "3.3.7",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
- "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
- "node_modules/natural-compare": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
- "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
- "dev": true
- },
- "node_modules/node-releases": {
- "version": "2.0.18",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
- "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
- "dev": true
- },
- "node_modules/optionator": {
- "version": "0.9.4",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
- "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
- "dev": true,
- "dependencies": {
- "deep-is": "^0.1.3",
- "fast-levenshtein": "^2.0.6",
- "levn": "^0.4.1",
- "prelude-ls": "^1.2.1",
- "type-check": "^0.4.0",
- "word-wrap": "^1.2.5"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dev": true,
- "dependencies": {
- "yocto-queue": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "dev": true,
- "dependencies": {
- "p-limit": "^3.0.2"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/parent-module": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
- "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
- "dev": true,
- "dependencies": {
- "callsites": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/picocolors": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
- "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
- "dev": true
- },
- "node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "dev": true,
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/postcss": {
- "version": "8.4.47",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
- "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "dependencies": {
- "nanoid": "^3.3.7",
- "picocolors": "^1.1.0",
- "source-map-js": "^1.2.1"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "node_modules/prelude-ls": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
- "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
- "dev": true,
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/prettier": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
- "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
- "dev": true,
- "bin": {
- "prettier": "bin/prettier.cjs"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/prettier/prettier?sponsor=1"
- }
- },
- "node_modules/punycode": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
- "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/queue-microtask": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
- "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ]
- },
- "node_modules/react": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
- "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
- "dependencies": {
- "loose-envify": "^1.1.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/react-dom": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
- "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
- "dependencies": {
- "loose-envify": "^1.1.0",
- "scheduler": "^0.23.2"
- },
- "peerDependencies": {
- "react": "^18.3.1"
- }
- },
- "node_modules/react-refresh": {
- "version": "0.14.2",
- "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
- "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/resolve-from": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
- "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/reusify": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
- "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
- "dev": true,
- "engines": {
- "iojs": ">=1.0.0",
- "node": ">=0.10.0"
- }
- },
- "node_modules/rollup": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.5.tgz",
- "integrity": "sha512-WoinX7GeQOFMGznEcWA1WrTQCd/tpEbMkc3nuMs9BT0CPjMdSjPMTVClwWd4pgSQwJdP65SK9mTCNvItlr5o7w==",
- "dev": true,
- "dependencies": {
- "@types/estree": "1.0.6"
- },
- "bin": {
- "rollup": "dist/bin/rollup"
- },
- "engines": {
- "node": ">=18.0.0",
- "npm": ">=8.0.0"
- },
- "optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.22.5",
- "@rollup/rollup-android-arm64": "4.22.5",
- "@rollup/rollup-darwin-arm64": "4.22.5",
- "@rollup/rollup-darwin-x64": "4.22.5",
- "@rollup/rollup-linux-arm-gnueabihf": "4.22.5",
- "@rollup/rollup-linux-arm-musleabihf": "4.22.5",
- "@rollup/rollup-linux-arm64-gnu": "4.22.5",
- "@rollup/rollup-linux-arm64-musl": "4.22.5",
- "@rollup/rollup-linux-powerpc64le-gnu": "4.22.5",
- "@rollup/rollup-linux-riscv64-gnu": "4.22.5",
- "@rollup/rollup-linux-s390x-gnu": "4.22.5",
- "@rollup/rollup-linux-x64-gnu": "4.22.5",
- "@rollup/rollup-linux-x64-musl": "4.22.5",
- "@rollup/rollup-win32-arm64-msvc": "4.22.5",
- "@rollup/rollup-win32-ia32-msvc": "4.22.5",
- "@rollup/rollup-win32-x64-msvc": "4.22.5",
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/run-parallel": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
- "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "dependencies": {
- "queue-microtask": "^1.2.2"
- }
- },
- "node_modules/scheduler": {
- "version": "0.23.2",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
- "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
- "dependencies": {
- "loose-envify": "^1.1.0"
- }
- },
- "node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "dev": true,
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/shebang-command": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
- "dev": true,
- "dependencies": {
- "shebang-regex": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/shebang-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-json-comments": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
- "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
- "dev": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
- "dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/text-table": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
- "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
- "dev": true
- },
- "node_modules/to-fast-properties": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
- "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/ts-api-utils": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
- "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
- "dev": true,
- "engines": {
- "node": ">=16"
- },
- "peerDependencies": {
- "typescript": ">=4.2.0"
- }
- },
- "node_modules/type-check": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
- "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
- "dev": true,
- "dependencies": {
- "prelude-ls": "^1.2.1"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/typescript": {
- "version": "5.6.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz",
- "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==",
- "dev": true,
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- },
- "node_modules/typescript-eslint": {
- "version": "8.7.0",
- "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.7.0.tgz",
- "integrity": "sha512-nEHbEYJyHwsuf7c3V3RS7Saq+1+la3i0ieR3qP0yjqWSzVmh8Drp47uOl9LjbPANac4S7EFSqvcYIKXUUwIfIQ==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/eslint-plugin": "8.7.0",
- "@typescript-eslint/parser": "8.7.0",
- "@typescript-eslint/utils": "8.7.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/update-browserslist-db": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
- "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "dependencies": {
- "escalade": "^3.2.0",
- "picocolors": "^1.1.0"
- },
- "bin": {
- "update-browserslist-db": "cli.js"
- },
- "peerDependencies": {
- "browserslist": ">= 4.21.0"
- }
- },
- "node_modules/uri-js": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
- "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
- "dev": true,
- "dependencies": {
- "punycode": "^2.1.0"
- }
- },
- "node_modules/vite": {
- "version": "5.4.8",
- "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz",
- "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==",
- "dev": true,
- "dependencies": {
- "esbuild": "^0.21.3",
- "postcss": "^8.4.43",
- "rollup": "^4.20.0"
- },
- "bin": {
- "vite": "bin/vite.js"
- },
- "engines": {
- "node": "^18.0.0 || >=20.0.0"
- },
- "funding": {
- "url": "https://github.com/vitejs/vite?sponsor=1"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.3"
- },
- "peerDependencies": {
- "@types/node": "^18.0.0 || >=20.0.0",
- "less": "*",
- "lightningcss": "^1.21.0",
- "sass": "*",
- "sass-embedded": "*",
- "stylus": "*",
- "sugarss": "*",
- "terser": "^5.4.0"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- },
- "less": {
- "optional": true
- },
- "lightningcss": {
- "optional": true
- },
- "sass": {
- "optional": true
- },
- "sass-embedded": {
- "optional": true
- },
- "stylus": {
- "optional": true
- },
- "sugarss": {
- "optional": true
- },
- "terser": {
- "optional": true
- }
- }
- },
- "node_modules/which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "dev": true,
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "node-which": "bin/node-which"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/word-wrap": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
- "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/yallist": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
- "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
- "dev": true
- },
- "node_modules/yocto-queue": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
- "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- }
- }
-}
diff --git a/app/package.json b/app/package.json
deleted file mode 100644
index 0e21f2e..0000000
--- a/app/package.json
+++ /dev/null
@@ -1,34 +0,0 @@
-{
- "name": "botw-ist",
- "private": true,
- "version": "0.0.0",
- "type": "module",
- "scripts": {
- "dev": "vite",
- "build": "tsc -b && vite build",
- "lint": "eslint .",
- "preview": "vite preview"
- },
- "dependencies": {
- "react": "^18.3.1",
- "react-dom": "^18.3.1"
- },
- "devDependencies": {
- "@eslint/js": "^9.9.0",
- "@types/react": "^18.3.3",
- "@types/react-dom": "^18.3.0",
- "@vitejs/plugin-react": "^4.3.1",
- "eslint": "^9.9.0",
- "eslint-plugin-react-hooks": "^5.1.0-rc.0",
- "eslint-plugin-react-refresh": "^0.4.9",
- "globals": "^15.9.0",
- "prettier": "^3.3.3",
- "typescript": "^5.5.3",
- "typescript-eslint": "^8.0.1",
- "vite": "^5.4.1"
- },
- "prettier": {
- "tabWidth": 4,
- "endOfLine": "auto"
- }
-}
diff --git a/app/public/vite.svg b/app/public/vite.svg
deleted file mode 100644
index e7b8dfb..0000000
--- a/app/public/vite.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/app/src/App.css b/app/src/App.css
deleted file mode 100644
index b9d355d..0000000
--- a/app/src/App.css
+++ /dev/null
@@ -1,42 +0,0 @@
-#root {
- max-width: 1280px;
- margin: 0 auto;
- padding: 2rem;
- text-align: center;
-}
-
-.logo {
- height: 6em;
- padding: 1.5em;
- will-change: filter;
- transition: filter 300ms;
-}
-.logo:hover {
- filter: drop-shadow(0 0 2em #646cffaa);
-}
-.logo.react:hover {
- filter: drop-shadow(0 0 2em #61dafbaa);
-}
-
-@keyframes logo-spin {
- from {
- transform: rotate(0deg);
- }
- to {
- transform: rotate(360deg);
- }
-}
-
-@media (prefers-reduced-motion: no-preference) {
- a:nth-of-type(2) .logo {
- animation: logo-spin infinite 20s linear;
- }
-}
-
-.card {
- padding: 2em;
-}
-
-.read-the-docs {
- color: #888;
-}
diff --git a/app/src/App.tsx b/app/src/App.tsx
deleted file mode 100644
index afe48ac..0000000
--- a/app/src/App.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import { useState } from 'react'
-import reactLogo from './assets/react.svg'
-import viteLogo from '/vite.svg'
-import './App.css'
-
-function App() {
- const [count, setCount] = useState(0)
-
- return (
- <>
-
- Vite + React
-
-
setCount((count) => count + 1)}>
- count is {count}
-
-
- Edit src/App.tsx
and save to test HMR
-
-
-
- Click on the Vite and React logos to learn more
-
- >
- )
-}
-
-export default App
diff --git a/app/src/assets/react.svg b/app/src/assets/react.svg
deleted file mode 100644
index 6c87de9..0000000
--- a/app/src/assets/react.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/app/src/index.css b/app/src/index.css
deleted file mode 100644
index 6119ad9..0000000
--- a/app/src/index.css
+++ /dev/null
@@ -1,68 +0,0 @@
-:root {
- font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
- line-height: 1.5;
- font-weight: 400;
-
- color-scheme: light dark;
- color: rgba(255, 255, 255, 0.87);
- background-color: #242424;
-
- font-synthesis: none;
- text-rendering: optimizeLegibility;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-a {
- font-weight: 500;
- color: #646cff;
- text-decoration: inherit;
-}
-a:hover {
- color: #535bf2;
-}
-
-body {
- margin: 0;
- display: flex;
- place-items: center;
- min-width: 320px;
- min-height: 100vh;
-}
-
-h1 {
- font-size: 3.2em;
- line-height: 1.1;
-}
-
-button {
- border-radius: 8px;
- border: 1px solid transparent;
- padding: 0.6em 1.2em;
- font-size: 1em;
- font-weight: 500;
- font-family: inherit;
- background-color: #1a1a1a;
- cursor: pointer;
- transition: border-color 0.25s;
-}
-button:hover {
- border-color: #646cff;
-}
-button:focus,
-button:focus-visible {
- outline: 4px auto -webkit-focus-ring-color;
-}
-
-@media (prefers-color-scheme: light) {
- :root {
- color: #213547;
- background-color: #ffffff;
- }
- a:hover {
- color: #747bff;
- }
- button {
- background-color: #f9f9f9;
- }
-}
diff --git a/app/src/main.tsx b/app/src/main.tsx
deleted file mode 100644
index 6f4ac9b..0000000
--- a/app/src/main.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import { StrictMode } from 'react'
-import { createRoot } from 'react-dom/client'
-import App from './App.tsx'
-import './index.css'
-
-createRoot(document.getElementById('root')!).render(
-
-
- ,
-)
diff --git a/app/src/sim/Cargo.toml b/app/src/sim/Cargo.toml
deleted file mode 100644
index 8fc2eb0..0000000
--- a/app/src/sim/Cargo.toml
+++ /dev/null
@@ -1,10 +0,0 @@
-[package]
-name = "sim"
-version = "0.0.0"
-edition = "2021"
-publish = false
-
-[dependencies]
-ist-parser = { path = "../../../sim/parser" }
-ist-runtime = { path = "../../../sim/runtime" }
-wasm-bindgen = "0.2.93"
diff --git a/app/src/vite-env.d.ts b/app/src/vite-env.d.ts
deleted file mode 100644
index 11f02fe..0000000
--- a/app/src/vite-env.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-///
diff --git a/app/vite.config.ts b/app/vite.config.ts
deleted file mode 100644
index 5a33944..0000000
--- a/app/vite.config.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { defineConfig } from 'vite'
-import react from '@vitejs/plugin-react'
-
-// https://vitejs.dev/config/
-export default defineConfig({
- plugins: [react()],
-})
diff --git a/app/tsconfig.node.json b/config/tsconfig-tool.json
similarity index 75%
rename from app/tsconfig.node.json
rename to config/tsconfig-tool.json
index 0d3d714..4f53603 100644
--- a/app/tsconfig.node.json
+++ b/config/tsconfig-tool.json
@@ -6,7 +6,7 @@
"skipLibCheck": true,
/* Bundler mode */
- "moduleResolution": "bundler",
+ "moduleResolution": "Bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
@@ -16,7 +16,7 @@
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
- "noFallthroughCasesInSwitch": true
- },
- "include": ["vite.config.ts"]
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ }
}
diff --git a/config/tsconfig-vite-app.json b/config/tsconfig-vite-app.json
new file mode 100644
index 0000000..286c69d
--- /dev/null
+++ b/config/tsconfig-vite-app.json
@@ -0,0 +1,24 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "Bundler",
+ "allowImportingTsExtensions": true,
+ "isolatedModules": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+ "jsx": "react-jsx",
+
+ /* Linting */
+ "strict": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true,
+
+ "types": ["vite/client"],
+ }
+}
diff --git a/legacy/public/assets/Background.png b/legacy/public/assets/Background.png
deleted file mode 100644
index 605800d..0000000
Binary files a/legacy/public/assets/Background.png and /dev/null differ
diff --git a/legacy/public/assets/font/DejaVuSansMono.ttf b/legacy/public/assets/font/DejaVuSansMono.ttf
deleted file mode 100644
index f578602..0000000
Binary files a/legacy/public/assets/font/DejaVuSansMono.ttf and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/AmberEarrings.png b/legacy/public/assets/img/Armor/AmberEarrings.png
deleted file mode 100644
index d532ba6..0000000
Binary files a/legacy/public/assets/img/Armor/AmberEarrings.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/AncientCuirass.png b/legacy/public/assets/img/Armor/AncientCuirass.png
deleted file mode 100644
index 8c33a27..0000000
Binary files a/legacy/public/assets/img/Armor/AncientCuirass.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/AncientGreaves.png b/legacy/public/assets/img/Armor/AncientGreaves.png
deleted file mode 100644
index fc6c167..0000000
Binary files a/legacy/public/assets/img/Armor/AncientGreaves.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/AncientHelm.png b/legacy/public/assets/img/Armor/AncientHelm.png
deleted file mode 100644
index 4c77ac8..0000000
Binary files a/legacy/public/assets/img/Armor/AncientHelm.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/BarbarianArmor.png b/legacy/public/assets/img/Armor/BarbarianArmor.png
deleted file mode 100644
index 98f5ca0..0000000
Binary files a/legacy/public/assets/img/Armor/BarbarianArmor.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/BarbarianHelm.png b/legacy/public/assets/img/Armor/BarbarianHelm.png
deleted file mode 100644
index 1e45592..0000000
Binary files a/legacy/public/assets/img/Armor/BarbarianHelm.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/BarbarianLegWraps.png b/legacy/public/assets/img/Armor/BarbarianLegWraps.png
deleted file mode 100644
index 67d6589..0000000
Binary files a/legacy/public/assets/img/Armor/BarbarianLegWraps.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/BokoblinMask.png b/legacy/public/assets/img/Armor/BokoblinMask.png
deleted file mode 100644
index a0362df..0000000
Binary files a/legacy/public/assets/img/Armor/BokoblinMask.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/CapOfTheHero.png b/legacy/public/assets/img/Armor/CapOfTheHero.png
deleted file mode 100644
index 72774a0..0000000
Binary files a/legacy/public/assets/img/Armor/CapOfTheHero.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/CapOfTheSky.png b/legacy/public/assets/img/Armor/CapOfTheSky.png
deleted file mode 100644
index a285291..0000000
Binary files a/legacy/public/assets/img/Armor/CapOfTheSky.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/CapOfTheWild.png b/legacy/public/assets/img/Armor/CapOfTheWild.png
deleted file mode 100644
index e5b7ddb..0000000
Binary files a/legacy/public/assets/img/Armor/CapOfTheWild.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/CapOfTheWind.png b/legacy/public/assets/img/Armor/CapOfTheWind.png
deleted file mode 100644
index 49d7bc6..0000000
Binary files a/legacy/public/assets/img/Armor/CapOfTheWind.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/CapOfTime.png b/legacy/public/assets/img/Armor/CapOfTime.png
deleted file mode 100644
index 1c5842a..0000000
Binary files a/legacy/public/assets/img/Armor/CapOfTime.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/CapOfTwilight.png b/legacy/public/assets/img/Armor/CapOfTwilight.png
deleted file mode 100644
index a43685d..0000000
Binary files a/legacy/public/assets/img/Armor/CapOfTwilight.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/ChampionsTunic.png b/legacy/public/assets/img/Armor/ChampionsTunic.png
deleted file mode 100644
index bafa5ea..0000000
Binary files a/legacy/public/assets/img/Armor/ChampionsTunic.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/ClimbersBandanna.png b/legacy/public/assets/img/Armor/ClimbersBandanna.png
deleted file mode 100644
index 5067253..0000000
Binary files a/legacy/public/assets/img/Armor/ClimbersBandanna.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/ClimbingBoots.png b/legacy/public/assets/img/Armor/ClimbingBoots.png
deleted file mode 100644
index 40665cd..0000000
Binary files a/legacy/public/assets/img/Armor/ClimbingBoots.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/ClimbingGear.png b/legacy/public/assets/img/Armor/ClimbingGear.png
deleted file mode 100644
index 6403188..0000000
Binary files a/legacy/public/assets/img/Armor/ClimbingGear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/DarkHood.png b/legacy/public/assets/img/Armor/DarkHood.png
deleted file mode 100644
index 19a7117..0000000
Binary files a/legacy/public/assets/img/Armor/DarkHood.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/DarkTrousers.png b/legacy/public/assets/img/Armor/DarkTrousers.png
deleted file mode 100644
index 290ff64..0000000
Binary files a/legacy/public/assets/img/Armor/DarkTrousers.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/DarkTunic.png b/legacy/public/assets/img/Armor/DarkTunic.png
deleted file mode 100644
index f2ea179..0000000
Binary files a/legacy/public/assets/img/Armor/DarkTunic.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/DesertVoeHeadband.png b/legacy/public/assets/img/Armor/DesertVoeHeadband.png
deleted file mode 100644
index dd47c82..0000000
Binary files a/legacy/public/assets/img/Armor/DesertVoeHeadband.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/DesertVoeSpaulder.png b/legacy/public/assets/img/Armor/DesertVoeSpaulder.png
deleted file mode 100644
index 7e14a3e..0000000
Binary files a/legacy/public/assets/img/Armor/DesertVoeSpaulder.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/DesertVoeTrousers.png b/legacy/public/assets/img/Armor/DesertVoeTrousers.png
deleted file mode 100644
index 8d8cadc..0000000
Binary files a/legacy/public/assets/img/Armor/DesertVoeTrousers.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/DiamondCirclet.png b/legacy/public/assets/img/Armor/DiamondCirclet.png
deleted file mode 100644
index d923fca..0000000
Binary files a/legacy/public/assets/img/Armor/DiamondCirclet.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/FierceDeityArmor.png b/legacy/public/assets/img/Armor/FierceDeityArmor.png
deleted file mode 100644
index 3463bcf..0000000
Binary files a/legacy/public/assets/img/Armor/FierceDeityArmor.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/FierceDeityBoots.png b/legacy/public/assets/img/Armor/FierceDeityBoots.png
deleted file mode 100644
index 6e74133..0000000
Binary files a/legacy/public/assets/img/Armor/FierceDeityBoots.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/FierceDeityMask.png b/legacy/public/assets/img/Armor/FierceDeityMask.png
deleted file mode 100644
index 2a1c322..0000000
Binary files a/legacy/public/assets/img/Armor/FierceDeityMask.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/FlamebreakerArmor.png b/legacy/public/assets/img/Armor/FlamebreakerArmor.png
deleted file mode 100644
index 9c16728..0000000
Binary files a/legacy/public/assets/img/Armor/FlamebreakerArmor.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/FlamebreakerBoots.png b/legacy/public/assets/img/Armor/FlamebreakerBoots.png
deleted file mode 100644
index c3ae20d..0000000
Binary files a/legacy/public/assets/img/Armor/FlamebreakerBoots.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/FlamebreakerHelm.png b/legacy/public/assets/img/Armor/FlamebreakerHelm.png
deleted file mode 100644
index 5d76e9a..0000000
Binary files a/legacy/public/assets/img/Armor/FlamebreakerHelm.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/GerudoSirwal.png b/legacy/public/assets/img/Armor/GerudoSirwal.png
deleted file mode 100644
index cef69c4..0000000
Binary files a/legacy/public/assets/img/Armor/GerudoSirwal.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/GerudoTop.png b/legacy/public/assets/img/Armor/GerudoTop.png
deleted file mode 100644
index 568f03f..0000000
Binary files a/legacy/public/assets/img/Armor/GerudoTop.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/GerudoVeil.png b/legacy/public/assets/img/Armor/GerudoVeil.png
deleted file mode 100644
index b2ce8cc..0000000
Binary files a/legacy/public/assets/img/Armor/GerudoVeil.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/HylianHood.png b/legacy/public/assets/img/Armor/HylianHood.png
deleted file mode 100644
index 8752ee6..0000000
Binary files a/legacy/public/assets/img/Armor/HylianHood.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/HylianTrousers.png b/legacy/public/assets/img/Armor/HylianTrousers.png
deleted file mode 100644
index 6279626..0000000
Binary files a/legacy/public/assets/img/Armor/HylianTrousers.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/HylianTunic.png b/legacy/public/assets/img/Armor/HylianTunic.png
deleted file mode 100644
index 1967936..0000000
Binary files a/legacy/public/assets/img/Armor/HylianTunic.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/IslandLobsterShirt.png b/legacy/public/assets/img/Armor/IslandLobsterShirt.png
deleted file mode 100644
index c1adeb8..0000000
Binary files a/legacy/public/assets/img/Armor/IslandLobsterShirt.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/KorokMask.png b/legacy/public/assets/img/Armor/KorokMask.png
deleted file mode 100644
index 1cc62f4..0000000
Binary files a/legacy/public/assets/img/Armor/KorokMask.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/LizalfosMask.png b/legacy/public/assets/img/Armor/LizalfosMask.png
deleted file mode 100644
index 41cb31c..0000000
Binary files a/legacy/public/assets/img/Armor/LizalfosMask.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/LynelMask.png b/legacy/public/assets/img/Armor/LynelMask.png
deleted file mode 100644
index 1e5dce7..0000000
Binary files a/legacy/public/assets/img/Armor/LynelMask.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/MajorasMask.png b/legacy/public/assets/img/Armor/MajorasMask.png
deleted file mode 100644
index 20dc8aa..0000000
Binary files a/legacy/public/assets/img/Armor/MajorasMask.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/MidnasHelmet.png b/legacy/public/assets/img/Armor/MidnasHelmet.png
deleted file mode 100644
index 5590c49..0000000
Binary files a/legacy/public/assets/img/Armor/MidnasHelmet.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/MoblinMask.png b/legacy/public/assets/img/Armor/MoblinMask.png
deleted file mode 100644
index 9b71698..0000000
Binary files a/legacy/public/assets/img/Armor/MoblinMask.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/NintendoSwitchShirt.png b/legacy/public/assets/img/Armor/NintendoSwitchShirt.png
deleted file mode 100644
index 31db1da..0000000
Binary files a/legacy/public/assets/img/Armor/NintendoSwitchShirt.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/OldShirt.png b/legacy/public/assets/img/Armor/OldShirt.png
deleted file mode 100644
index 57ac0a2..0000000
Binary files a/legacy/public/assets/img/Armor/OldShirt.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/OpalEarrings.png b/legacy/public/assets/img/Armor/OpalEarrings.png
deleted file mode 100644
index 3243d6d..0000000
Binary files a/legacy/public/assets/img/Armor/OpalEarrings.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/PhantomArmor.png b/legacy/public/assets/img/Armor/PhantomArmor.png
deleted file mode 100644
index 68866f4..0000000
Binary files a/legacy/public/assets/img/Armor/PhantomArmor.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/PhantomGanonArmor.png b/legacy/public/assets/img/Armor/PhantomGanonArmor.png
deleted file mode 100644
index 87ca398..0000000
Binary files a/legacy/public/assets/img/Armor/PhantomGanonArmor.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/PhantomGanonGreaves.png b/legacy/public/assets/img/Armor/PhantomGanonGreaves.png
deleted file mode 100644
index b63a8e2..0000000
Binary files a/legacy/public/assets/img/Armor/PhantomGanonGreaves.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/PhantomGanonSkull.png b/legacy/public/assets/img/Armor/PhantomGanonSkull.png
deleted file mode 100644
index 974fbad..0000000
Binary files a/legacy/public/assets/img/Armor/PhantomGanonSkull.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/PhantomGreaves.png b/legacy/public/assets/img/Armor/PhantomGreaves.png
deleted file mode 100644
index e9fe0cd..0000000
Binary files a/legacy/public/assets/img/Armor/PhantomGreaves.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/PhantomHelmet.png b/legacy/public/assets/img/Armor/PhantomHelmet.png
deleted file mode 100644
index 7e446ad..0000000
Binary files a/legacy/public/assets/img/Armor/PhantomHelmet.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/RadiantMask.png b/legacy/public/assets/img/Armor/RadiantMask.png
deleted file mode 100644
index a06f2fc..0000000
Binary files a/legacy/public/assets/img/Armor/RadiantMask.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/RadiantShirt.png b/legacy/public/assets/img/Armor/RadiantShirt.png
deleted file mode 100644
index 703a8bb..0000000
Binary files a/legacy/public/assets/img/Armor/RadiantShirt.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/RadiantTights.png b/legacy/public/assets/img/Armor/RadiantTights.png
deleted file mode 100644
index 0e3d50b..0000000
Binary files a/legacy/public/assets/img/Armor/RadiantTights.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/RaviosHood.png b/legacy/public/assets/img/Armor/RaviosHood.png
deleted file mode 100644
index 6288cd6..0000000
Binary files a/legacy/public/assets/img/Armor/RaviosHood.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/RoyalGuardBoots.png b/legacy/public/assets/img/Armor/RoyalGuardBoots.png
deleted file mode 100644
index 3ce627c..0000000
Binary files a/legacy/public/assets/img/Armor/RoyalGuardBoots.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/RoyalGuardCap.png b/legacy/public/assets/img/Armor/RoyalGuardCap.png
deleted file mode 100644
index 42c90d8..0000000
Binary files a/legacy/public/assets/img/Armor/RoyalGuardCap.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/RoyalGuardUniform.png b/legacy/public/assets/img/Armor/RoyalGuardUniform.png
deleted file mode 100644
index 927faf2..0000000
Binary files a/legacy/public/assets/img/Armor/RoyalGuardUniform.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/RubberArmor.png b/legacy/public/assets/img/Armor/RubberArmor.png
deleted file mode 100644
index 84a2408..0000000
Binary files a/legacy/public/assets/img/Armor/RubberArmor.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/RubberHelm.png b/legacy/public/assets/img/Armor/RubberHelm.png
deleted file mode 100644
index 660fa88..0000000
Binary files a/legacy/public/assets/img/Armor/RubberHelm.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/RubberTights.png b/legacy/public/assets/img/Armor/RubberTights.png
deleted file mode 100644
index abb7468..0000000
Binary files a/legacy/public/assets/img/Armor/RubberTights.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/RubyCirclet.png b/legacy/public/assets/img/Armor/RubyCirclet.png
deleted file mode 100644
index 89b8d82..0000000
Binary files a/legacy/public/assets/img/Armor/RubyCirclet.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/SalvagerHeadwear.png b/legacy/public/assets/img/Armor/SalvagerHeadwear.png
deleted file mode 100644
index 159e316..0000000
Binary files a/legacy/public/assets/img/Armor/SalvagerHeadwear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/SalvagerTrousers.png b/legacy/public/assets/img/Armor/SalvagerTrousers.png
deleted file mode 100644
index 39df17d..0000000
Binary files a/legacy/public/assets/img/Armor/SalvagerTrousers.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/SalvagerVest.png b/legacy/public/assets/img/Armor/SalvagerVest.png
deleted file mode 100644
index ab39351..0000000
Binary files a/legacy/public/assets/img/Armor/SalvagerVest.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/SandBoots.png b/legacy/public/assets/img/Armor/SandBoots.png
deleted file mode 100644
index b4a55aa..0000000
Binary files a/legacy/public/assets/img/Armor/SandBoots.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/SapphireCirclet.png b/legacy/public/assets/img/Armor/SapphireCirclet.png
deleted file mode 100644
index b58c946..0000000
Binary files a/legacy/public/assets/img/Armor/SapphireCirclet.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/SheiksMask.png b/legacy/public/assets/img/Armor/SheiksMask.png
deleted file mode 100644
index b70c772..0000000
Binary files a/legacy/public/assets/img/Armor/SheiksMask.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/SnowBoots.png b/legacy/public/assets/img/Armor/SnowBoots.png
deleted file mode 100644
index 37da564..0000000
Binary files a/legacy/public/assets/img/Armor/SnowBoots.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/SnowquillHeaddress.png b/legacy/public/assets/img/Armor/SnowquillHeaddress.png
deleted file mode 100644
index a344942..0000000
Binary files a/legacy/public/assets/img/Armor/SnowquillHeaddress.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/SnowquillTrousers.png b/legacy/public/assets/img/Armor/SnowquillTrousers.png
deleted file mode 100644
index bcdd7ef..0000000
Binary files a/legacy/public/assets/img/Armor/SnowquillTrousers.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/SnowquillTunic.png b/legacy/public/assets/img/Armor/SnowquillTunic.png
deleted file mode 100644
index 63d8d4c..0000000
Binary files a/legacy/public/assets/img/Armor/SnowquillTunic.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/SoldiersArmor.png b/legacy/public/assets/img/Armor/SoldiersArmor.png
deleted file mode 100644
index 5f7e386..0000000
Binary files a/legacy/public/assets/img/Armor/SoldiersArmor.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/SoldiersGreaves.png b/legacy/public/assets/img/Armor/SoldiersGreaves.png
deleted file mode 100644
index d1e5e7a..0000000
Binary files a/legacy/public/assets/img/Armor/SoldiersGreaves.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/SoldiersHelm.png b/legacy/public/assets/img/Armor/SoldiersHelm.png
deleted file mode 100644
index 37c44fc..0000000
Binary files a/legacy/public/assets/img/Armor/SoldiersHelm.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/StealthChestGuard.png b/legacy/public/assets/img/Armor/StealthChestGuard.png
deleted file mode 100644
index 517c081..0000000
Binary files a/legacy/public/assets/img/Armor/StealthChestGuard.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/StealthMask.png b/legacy/public/assets/img/Armor/StealthMask.png
deleted file mode 100644
index e649df4..0000000
Binary files a/legacy/public/assets/img/Armor/StealthMask.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/StealthTights.png b/legacy/public/assets/img/Armor/StealthTights.png
deleted file mode 100644
index 0bd8496..0000000
Binary files a/legacy/public/assets/img/Armor/StealthTights.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/ThunderHelm.png b/legacy/public/assets/img/Armor/ThunderHelm.png
deleted file mode 100644
index ac3a190..0000000
Binary files a/legacy/public/assets/img/Armor/ThunderHelm.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/TinglesHood.png b/legacy/public/assets/img/Armor/TinglesHood.png
deleted file mode 100644
index bc9cbcd..0000000
Binary files a/legacy/public/assets/img/Armor/TinglesHood.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/TinglesShirt.png b/legacy/public/assets/img/Armor/TinglesShirt.png
deleted file mode 100644
index 1d8d401..0000000
Binary files a/legacy/public/assets/img/Armor/TinglesShirt.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/TinglesTights.png b/legacy/public/assets/img/Armor/TinglesTights.png
deleted file mode 100644
index 0f005d1..0000000
Binary files a/legacy/public/assets/img/Armor/TinglesTights.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/TopazEarrings.png b/legacy/public/assets/img/Armor/TopazEarrings.png
deleted file mode 100644
index fa28270..0000000
Binary files a/legacy/public/assets/img/Armor/TopazEarrings.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/TrousersOfTheHero.png b/legacy/public/assets/img/Armor/TrousersOfTheHero.png
deleted file mode 100644
index cfddec0..0000000
Binary files a/legacy/public/assets/img/Armor/TrousersOfTheHero.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/TrousersOfTheSky.png b/legacy/public/assets/img/Armor/TrousersOfTheSky.png
deleted file mode 100644
index 73c2817..0000000
Binary files a/legacy/public/assets/img/Armor/TrousersOfTheSky.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/TrousersOfTheWild.png b/legacy/public/assets/img/Armor/TrousersOfTheWild.png
deleted file mode 100644
index ffff934..0000000
Binary files a/legacy/public/assets/img/Armor/TrousersOfTheWild.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/TrousersOfTheWind.png b/legacy/public/assets/img/Armor/TrousersOfTheWind.png
deleted file mode 100644
index 9ab8a3e..0000000
Binary files a/legacy/public/assets/img/Armor/TrousersOfTheWind.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/TrousersOfTime.png b/legacy/public/assets/img/Armor/TrousersOfTime.png
deleted file mode 100644
index ceb183d..0000000
Binary files a/legacy/public/assets/img/Armor/TrousersOfTime.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/TrousersOfTwilight.png b/legacy/public/assets/img/Armor/TrousersOfTwilight.png
deleted file mode 100644
index 96ace0f..0000000
Binary files a/legacy/public/assets/img/Armor/TrousersOfTwilight.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/TunicOfTheHero.png b/legacy/public/assets/img/Armor/TunicOfTheHero.png
deleted file mode 100644
index f249843..0000000
Binary files a/legacy/public/assets/img/Armor/TunicOfTheHero.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/TunicOfTheSky.png b/legacy/public/assets/img/Armor/TunicOfTheSky.png
deleted file mode 100644
index 0fa572d..0000000
Binary files a/legacy/public/assets/img/Armor/TunicOfTheSky.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/TunicOfTheWild.png b/legacy/public/assets/img/Armor/TunicOfTheWild.png
deleted file mode 100644
index f858819..0000000
Binary files a/legacy/public/assets/img/Armor/TunicOfTheWild.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/TunicOfTheWind.png b/legacy/public/assets/img/Armor/TunicOfTheWind.png
deleted file mode 100644
index 407fa4e..0000000
Binary files a/legacy/public/assets/img/Armor/TunicOfTheWind.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/TunicOfTime.png b/legacy/public/assets/img/Armor/TunicOfTime.png
deleted file mode 100644
index 61265e1..0000000
Binary files a/legacy/public/assets/img/Armor/TunicOfTime.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/TunicOfTwilight.png b/legacy/public/assets/img/Armor/TunicOfTwilight.png
deleted file mode 100644
index a72f0b7..0000000
Binary files a/legacy/public/assets/img/Armor/TunicOfTwilight.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/VahMedohDivineHelm.png b/legacy/public/assets/img/Armor/VahMedohDivineHelm.png
deleted file mode 100644
index 2cabe4b..0000000
Binary files a/legacy/public/assets/img/Armor/VahMedohDivineHelm.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/VahNaborisDivineHelm.png b/legacy/public/assets/img/Armor/VahNaborisDivineHelm.png
deleted file mode 100644
index 78d9198..0000000
Binary files a/legacy/public/assets/img/Armor/VahNaborisDivineHelm.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/VahRudaniaDivineHelm.png b/legacy/public/assets/img/Armor/VahRudaniaDivineHelm.png
deleted file mode 100644
index 0abac99..0000000
Binary files a/legacy/public/assets/img/Armor/VahRudaniaDivineHelm.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/VahRutaDivineHelm.png b/legacy/public/assets/img/Armor/VahRutaDivineHelm.png
deleted file mode 100644
index 7e220e7..0000000
Binary files a/legacy/public/assets/img/Armor/VahRutaDivineHelm.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/WarmDoublet.png b/legacy/public/assets/img/Armor/WarmDoublet.png
deleted file mode 100644
index c1918df..0000000
Binary files a/legacy/public/assets/img/Armor/WarmDoublet.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/WellWornTrousers.png b/legacy/public/assets/img/Armor/WellWornTrousers.png
deleted file mode 100644
index fc81d06..0000000
Binary files a/legacy/public/assets/img/Armor/WellWornTrousers.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/ZantsHelmet.png b/legacy/public/assets/img/Armor/ZantsHelmet.png
deleted file mode 100644
index a01042d..0000000
Binary files a/legacy/public/assets/img/Armor/ZantsHelmet.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/ZoraArmor.png b/legacy/public/assets/img/Armor/ZoraArmor.png
deleted file mode 100644
index 3f33f43..0000000
Binary files a/legacy/public/assets/img/Armor/ZoraArmor.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/ZoraGreaves.png b/legacy/public/assets/img/Armor/ZoraGreaves.png
deleted file mode 100644
index b9912cc..0000000
Binary files a/legacy/public/assets/img/Armor/ZoraGreaves.png and /dev/null differ
diff --git a/legacy/public/assets/img/Armor/ZoraHelm.png b/legacy/public/assets/img/Armor/ZoraHelm.png
deleted file mode 100644
index a702f59..0000000
Binary files a/legacy/public/assets/img/Armor/ZoraHelm.png and /dev/null differ
diff --git a/legacy/public/assets/img/Arrow/AncientArrow.png b/legacy/public/assets/img/Arrow/AncientArrow.png
deleted file mode 100644
index 6b82f69..0000000
Binary files a/legacy/public/assets/img/Arrow/AncientArrow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Arrow/BombArrow.png b/legacy/public/assets/img/Arrow/BombArrow.png
deleted file mode 100644
index f63de4c..0000000
Binary files a/legacy/public/assets/img/Arrow/BombArrow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Arrow/FireArrow.png b/legacy/public/assets/img/Arrow/FireArrow.png
deleted file mode 100644
index c929ac6..0000000
Binary files a/legacy/public/assets/img/Arrow/FireArrow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Arrow/IceArrow.png b/legacy/public/assets/img/Arrow/IceArrow.png
deleted file mode 100644
index ba10f0c..0000000
Binary files a/legacy/public/assets/img/Arrow/IceArrow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Arrow/NormalArrow.png b/legacy/public/assets/img/Arrow/NormalArrow.png
deleted file mode 100644
index a8f8c4d..0000000
Binary files a/legacy/public/assets/img/Arrow/NormalArrow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Arrow/ShockArrow.png b/legacy/public/assets/img/Arrow/ShockArrow.png
deleted file mode 100644
index d85eae7..0000000
Binary files a/legacy/public/assets/img/Arrow/ShockArrow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/AncientBow.png b/legacy/public/assets/img/Bow/AncientBow.png
deleted file mode 100644
index 3d62d47..0000000
Binary files a/legacy/public/assets/img/Bow/AncientBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/BokoBow.png b/legacy/public/assets/img/Bow/BokoBow.png
deleted file mode 100644
index a530dbb..0000000
Binary files a/legacy/public/assets/img/Bow/BokoBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/Bow.png b/legacy/public/assets/img/Bow/Bow.png
deleted file mode 100644
index 8dcbc1d..0000000
Binary files a/legacy/public/assets/img/Bow/Bow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/BowOfLight.png b/legacy/public/assets/img/Bow/BowOfLight.png
deleted file mode 100644
index 2f9aef1..0000000
Binary files a/legacy/public/assets/img/Bow/BowOfLight.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/DragonBoneBokoBow.png b/legacy/public/assets/img/Bow/DragonBoneBokoBow.png
deleted file mode 100644
index 4895fc7..0000000
Binary files a/legacy/public/assets/img/Bow/DragonBoneBokoBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/DuplexBow.png b/legacy/public/assets/img/Bow/DuplexBow.png
deleted file mode 100644
index e73aa4f..0000000
Binary files a/legacy/public/assets/img/Bow/DuplexBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/FalconBow.png b/legacy/public/assets/img/Bow/FalconBow.png
deleted file mode 100644
index 341a35b..0000000
Binary files a/legacy/public/assets/img/Bow/FalconBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/ForestDwellersBow.png b/legacy/public/assets/img/Bow/ForestDwellersBow.png
deleted file mode 100644
index 042dfea..0000000
Binary files a/legacy/public/assets/img/Bow/ForestDwellersBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/GoldenBow.png b/legacy/public/assets/img/Bow/GoldenBow.png
deleted file mode 100644
index 2acc15e..0000000
Binary files a/legacy/public/assets/img/Bow/GoldenBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/GreatEagleBow.png b/legacy/public/assets/img/Bow/GreatEagleBow.png
deleted file mode 100644
index 8c7c581..0000000
Binary files a/legacy/public/assets/img/Bow/GreatEagleBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/KnightsBow.png b/legacy/public/assets/img/Bow/KnightsBow.png
deleted file mode 100644
index a876620..0000000
Binary files a/legacy/public/assets/img/Bow/KnightsBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/LizalBow.png b/legacy/public/assets/img/Bow/LizalBow.png
deleted file mode 100644
index 3273e6a..0000000
Binary files a/legacy/public/assets/img/Bow/LizalBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/LynelBow.png b/legacy/public/assets/img/Bow/LynelBow.png
deleted file mode 100644
index aa1d2ec..0000000
Binary files a/legacy/public/assets/img/Bow/LynelBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/MightyLynelBow.png b/legacy/public/assets/img/Bow/MightyLynelBow.png
deleted file mode 100644
index 4dbef9f..0000000
Binary files a/legacy/public/assets/img/Bow/MightyLynelBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/PhrenicBow.png b/legacy/public/assets/img/Bow/PhrenicBow.png
deleted file mode 100644
index a9011c9..0000000
Binary files a/legacy/public/assets/img/Bow/PhrenicBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/RoyalBow.png b/legacy/public/assets/img/Bow/RoyalBow.png
deleted file mode 100644
index d19d626..0000000
Binary files a/legacy/public/assets/img/Bow/RoyalBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/RoyalGuardsBow.png b/legacy/public/assets/img/Bow/RoyalGuardsBow.png
deleted file mode 100644
index 98e3379..0000000
Binary files a/legacy/public/assets/img/Bow/RoyalGuardsBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/SavageLynelBow.png b/legacy/public/assets/img/Bow/SavageLynelBow.png
deleted file mode 100644
index f7a4ec3..0000000
Binary files a/legacy/public/assets/img/Bow/SavageLynelBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/SilverBow.png b/legacy/public/assets/img/Bow/SilverBow.png
deleted file mode 100644
index 46c531e..0000000
Binary files a/legacy/public/assets/img/Bow/SilverBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/SoldiersBow.png b/legacy/public/assets/img/Bow/SoldiersBow.png
deleted file mode 100644
index 9060587..0000000
Binary files a/legacy/public/assets/img/Bow/SoldiersBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/SpikedBokoBow.png b/legacy/public/assets/img/Bow/SpikedBokoBow.png
deleted file mode 100644
index 4867177..0000000
Binary files a/legacy/public/assets/img/Bow/SpikedBokoBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/SteelLizalBow.png b/legacy/public/assets/img/Bow/SteelLizalBow.png
deleted file mode 100644
index df19b24..0000000
Binary files a/legacy/public/assets/img/Bow/SteelLizalBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/StrengthenedLizalBow.png b/legacy/public/assets/img/Bow/StrengthenedLizalBow.png
deleted file mode 100644
index d088e4c..0000000
Binary files a/legacy/public/assets/img/Bow/StrengthenedLizalBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/SwallowBow.png b/legacy/public/assets/img/Bow/SwallowBow.png
deleted file mode 100644
index 70204d2..0000000
Binary files a/legacy/public/assets/img/Bow/SwallowBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/TravelersBow.png b/legacy/public/assets/img/Bow/TravelersBow.png
deleted file mode 100644
index b13c63f..0000000
Binary files a/legacy/public/assets/img/Bow/TravelersBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/TwilightBow.png b/legacy/public/assets/img/Bow/TwilightBow.png
deleted file mode 100644
index 5913313..0000000
Binary files a/legacy/public/assets/img/Bow/TwilightBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Bow/WoodenBow.png b/legacy/public/assets/img/Bow/WoodenBow.png
deleted file mode 100644
index a56d2bf..0000000
Binary files a/legacy/public/assets/img/Bow/WoodenBow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/ApplePie.png b/legacy/public/assets/img/Food/ApplePie.png
deleted file mode 100644
index 65406e2..0000000
Binary files a/legacy/public/assets/img/Food/ApplePie.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/BakedApple.png b/legacy/public/assets/img/Food/BakedApple.png
deleted file mode 100644
index d78fdce..0000000
Binary files a/legacy/public/assets/img/Food/BakedApple.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/BakedFortifiedPumpkin.png b/legacy/public/assets/img/Food/BakedFortifiedPumpkin.png
deleted file mode 100644
index dee57c9..0000000
Binary files a/legacy/public/assets/img/Food/BakedFortifiedPumpkin.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/BakedPalmFruit.png b/legacy/public/assets/img/Food/BakedPalmFruit.png
deleted file mode 100644
index 623b06c..0000000
Binary files a/legacy/public/assets/img/Food/BakedPalmFruit.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/BlackenedCrab.png b/legacy/public/assets/img/Food/BlackenedCrab.png
deleted file mode 100644
index fca4f44..0000000
Binary files a/legacy/public/assets/img/Food/BlackenedCrab.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/BlueshellEscargot.png b/legacy/public/assets/img/Food/BlueshellEscargot.png
deleted file mode 100644
index d95b694..0000000
Binary files a/legacy/public/assets/img/Food/BlueshellEscargot.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/CampfireEgg.png b/legacy/public/assets/img/Food/CampfireEgg.png
deleted file mode 100644
index 4e74a68..0000000
Binary files a/legacy/public/assets/img/Food/CampfireEgg.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/CarrotCake.png b/legacy/public/assets/img/Food/CarrotCake.png
deleted file mode 100644
index bf2f922..0000000
Binary files a/legacy/public/assets/img/Food/CarrotCake.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/CarrotStew.png b/legacy/public/assets/img/Food/CarrotStew.png
deleted file mode 100644
index 4cf1f31..0000000
Binary files a/legacy/public/assets/img/Food/CarrotStew.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/CharredPepper.png b/legacy/public/assets/img/Food/CharredPepper.png
deleted file mode 100644
index 099e5db..0000000
Binary files a/legacy/public/assets/img/Food/CharredPepper.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/ChillyElixir.png b/legacy/public/assets/img/Food/ChillyElixir.png
deleted file mode 100644
index 809b01a..0000000
Binary files a/legacy/public/assets/img/Food/ChillyElixir.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/ClamChowder.png b/legacy/public/assets/img/Food/ClamChowder.png
deleted file mode 100644
index 51199f0..0000000
Binary files a/legacy/public/assets/img/Food/ClamChowder.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/CopiousFriedWildGreens.png b/legacy/public/assets/img/Food/CopiousFriedWildGreens.png
deleted file mode 100644
index 4280557..0000000
Binary files a/legacy/public/assets/img/Food/CopiousFriedWildGreens.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/CopiousMeatSkewers.png b/legacy/public/assets/img/Food/CopiousMeatSkewers.png
deleted file mode 100644
index f5122e3..0000000
Binary files a/legacy/public/assets/img/Food/CopiousMeatSkewers.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/CopiousMushroomSkewers.png b/legacy/public/assets/img/Food/CopiousMushroomSkewers.png
deleted file mode 100644
index a56a1a5..0000000
Binary files a/legacy/public/assets/img/Food/CopiousMushroomSkewers.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/CopiousSeafoodSkewers.png b/legacy/public/assets/img/Food/CopiousSeafoodSkewers.png
deleted file mode 100644
index 8e0b221..0000000
Binary files a/legacy/public/assets/img/Food/CopiousSeafoodSkewers.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/CopiousSimmeredFruit.png b/legacy/public/assets/img/Food/CopiousSimmeredFruit.png
deleted file mode 100644
index a3ee5cb..0000000
Binary files a/legacy/public/assets/img/Food/CopiousSimmeredFruit.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/CrabOmeletWithRice.png b/legacy/public/assets/img/Food/CrabOmeletWithRice.png
deleted file mode 100644
index a9896a3..0000000
Binary files a/legacy/public/assets/img/Food/CrabOmeletWithRice.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/CrabRisotto.png b/legacy/public/assets/img/Food/CrabRisotto.png
deleted file mode 100644
index b5b77d9..0000000
Binary files a/legacy/public/assets/img/Food/CrabRisotto.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/CrabStirFry.png b/legacy/public/assets/img/Food/CrabStirFry.png
deleted file mode 100644
index 7006b5a..0000000
Binary files a/legacy/public/assets/img/Food/CrabStirFry.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/CreamOfMushroomSoup.png b/legacy/public/assets/img/Food/CreamOfMushroomSoup.png
deleted file mode 100644
index a4d7c04..0000000
Binary files a/legacy/public/assets/img/Food/CreamOfMushroomSoup.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/CreamOfVegetableSoup.png b/legacy/public/assets/img/Food/CreamOfVegetableSoup.png
deleted file mode 100644
index dd940a1..0000000
Binary files a/legacy/public/assets/img/Food/CreamOfVegetableSoup.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/CreamyHeartSoup.png b/legacy/public/assets/img/Food/CreamyHeartSoup.png
deleted file mode 100644
index 3256612..0000000
Binary files a/legacy/public/assets/img/Food/CreamyHeartSoup.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/CreamyMeatSoup.png b/legacy/public/assets/img/Food/CreamyMeatSoup.png
deleted file mode 100644
index 65fef54..0000000
Binary files a/legacy/public/assets/img/Food/CreamyMeatSoup.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/CreamySeafoodSoup.png b/legacy/public/assets/img/Food/CreamySeafoodSoup.png
deleted file mode 100644
index 1178b18..0000000
Binary files a/legacy/public/assets/img/Food/CreamySeafoodSoup.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/CurryPilaf.png b/legacy/public/assets/img/Food/CurryPilaf.png
deleted file mode 100644
index 82be501..0000000
Binary files a/legacy/public/assets/img/Food/CurryPilaf.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/CurryRice.png b/legacy/public/assets/img/Food/CurryRice.png
deleted file mode 100644
index 2724c9b..0000000
Binary files a/legacy/public/assets/img/Food/CurryRice.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/DubiousFood.png b/legacy/public/assets/img/Food/DubiousFood.png
deleted file mode 100644
index a24bc27..0000000
Binary files a/legacy/public/assets/img/Food/DubiousFood.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/EggPudding.png b/legacy/public/assets/img/Food/EggPudding.png
deleted file mode 100644
index 07f2619..0000000
Binary files a/legacy/public/assets/img/Food/EggPudding.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/EggTart.png b/legacy/public/assets/img/Food/EggTart.png
deleted file mode 100644
index 0b9b42a..0000000
Binary files a/legacy/public/assets/img/Food/EggTart.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/ElectroElixir.png b/legacy/public/assets/img/Food/ElectroElixir.png
deleted file mode 100644
index ede2c45..0000000
Binary files a/legacy/public/assets/img/Food/ElectroElixir.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/Elixir.png b/legacy/public/assets/img/Food/Elixir.png
deleted file mode 100644
index f287a2d..0000000
Binary files a/legacy/public/assets/img/Food/Elixir.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/EnduringElixir.png b/legacy/public/assets/img/Food/EnduringElixir.png
deleted file mode 100644
index 0eeefc7..0000000
Binary files a/legacy/public/assets/img/Food/EnduringElixir.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/EnergizingElixir.png b/legacy/public/assets/img/Food/EnergizingElixir.png
deleted file mode 100644
index dbbf078..0000000
Binary files a/legacy/public/assets/img/Food/EnergizingElixir.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FairyTonic.png b/legacy/public/assets/img/Food/FairyTonic.png
deleted file mode 100644
index 2f4fad4..0000000
Binary files a/legacy/public/assets/img/Food/FairyTonic.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FireproofElixir.png b/legacy/public/assets/img/Food/FireproofElixir.png
deleted file mode 100644
index 1ddd662..0000000
Binary files a/legacy/public/assets/img/Food/FireproofElixir.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FishAndMushroomSkewer.png b/legacy/public/assets/img/Food/FishAndMushroomSkewer.png
deleted file mode 100644
index 7c9ba2a..0000000
Binary files a/legacy/public/assets/img/Food/FishAndMushroomSkewer.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FishPie.png b/legacy/public/assets/img/Food/FishPie.png
deleted file mode 100644
index 4305254..0000000
Binary files a/legacy/public/assets/img/Food/FishPie.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FishSkewer.png b/legacy/public/assets/img/Food/FishSkewer.png
deleted file mode 100644
index a5c7274..0000000
Binary files a/legacy/public/assets/img/Food/FishSkewer.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FragrantMushroomSaute.png b/legacy/public/assets/img/Food/FragrantMushroomSaute.png
deleted file mode 100644
index 2ebbd9e..0000000
Binary files a/legacy/public/assets/img/Food/FragrantMushroomSaute.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FriedBananas.png b/legacy/public/assets/img/Food/FriedBananas.png
deleted file mode 100644
index 9391ae0..0000000
Binary files a/legacy/public/assets/img/Food/FriedBananas.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FriedEggAndRice.png b/legacy/public/assets/img/Food/FriedEggAndRice.png
deleted file mode 100644
index 87a001c..0000000
Binary files a/legacy/public/assets/img/Food/FriedEggAndRice.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FriedWildGreens.png b/legacy/public/assets/img/Food/FriedWildGreens.png
deleted file mode 100644
index 580d068..0000000
Binary files a/legacy/public/assets/img/Food/FriedWildGreens.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FrozenBass.png b/legacy/public/assets/img/Food/FrozenBass.png
deleted file mode 100644
index 75098fe..0000000
Binary files a/legacy/public/assets/img/Food/FrozenBass.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FrozenBirdDrumstick.png b/legacy/public/assets/img/Food/FrozenBirdDrumstick.png
deleted file mode 100644
index 733aaa9..0000000
Binary files a/legacy/public/assets/img/Food/FrozenBirdDrumstick.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FrozenBirdThigh.png b/legacy/public/assets/img/Food/FrozenBirdThigh.png
deleted file mode 100644
index 84566e8..0000000
Binary files a/legacy/public/assets/img/Food/FrozenBirdThigh.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FrozenCarp.png b/legacy/public/assets/img/Food/FrozenCarp.png
deleted file mode 100644
index 7faaff4..0000000
Binary files a/legacy/public/assets/img/Food/FrozenCarp.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FrozenCrab.png b/legacy/public/assets/img/Food/FrozenCrab.png
deleted file mode 100644
index e2b163b..0000000
Binary files a/legacy/public/assets/img/Food/FrozenCrab.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FrozenHeartyBass.png b/legacy/public/assets/img/Food/FrozenHeartyBass.png
deleted file mode 100644
index 7af6bd3..0000000
Binary files a/legacy/public/assets/img/Food/FrozenHeartyBass.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FrozenHeartySalmon.png b/legacy/public/assets/img/Food/FrozenHeartySalmon.png
deleted file mode 100644
index 9e22915..0000000
Binary files a/legacy/public/assets/img/Food/FrozenHeartySalmon.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FrozenPorgy.png b/legacy/public/assets/img/Food/FrozenPorgy.png
deleted file mode 100644
index 5caf988..0000000
Binary files a/legacy/public/assets/img/Food/FrozenPorgy.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FrozenRiverSnail.png b/legacy/public/assets/img/Food/FrozenRiverSnail.png
deleted file mode 100644
index f9319fd..0000000
Binary files a/legacy/public/assets/img/Food/FrozenRiverSnail.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FrozenTrout.png b/legacy/public/assets/img/Food/FrozenTrout.png
deleted file mode 100644
index 8cb0e8f..0000000
Binary files a/legacy/public/assets/img/Food/FrozenTrout.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FrozenWholeBird.png b/legacy/public/assets/img/Food/FrozenWholeBird.png
deleted file mode 100644
index 73faf7a..0000000
Binary files a/legacy/public/assets/img/Food/FrozenWholeBird.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FruitAndMushroomMix.png b/legacy/public/assets/img/Food/FruitAndMushroomMix.png
deleted file mode 100644
index 6323775..0000000
Binary files a/legacy/public/assets/img/Food/FruitAndMushroomMix.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/FruitPie.png b/legacy/public/assets/img/Food/FruitPie.png
deleted file mode 100644
index cc86e7d..0000000
Binary files a/legacy/public/assets/img/Food/FruitPie.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/Fruitcake.png b/legacy/public/assets/img/Food/Fruitcake.png
deleted file mode 100644
index 90de50c..0000000
Binary files a/legacy/public/assets/img/Food/Fruitcake.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/GlazedMeat.png b/legacy/public/assets/img/Food/GlazedMeat.png
deleted file mode 100644
index 1220418..0000000
Binary files a/legacy/public/assets/img/Food/GlazedMeat.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/GlazedMushrooms.png b/legacy/public/assets/img/Food/GlazedMushrooms.png
deleted file mode 100644
index bd8c6e7..0000000
Binary files a/legacy/public/assets/img/Food/GlazedMushrooms.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/GlazedSeafood.png b/legacy/public/assets/img/Food/GlazedSeafood.png
deleted file mode 100644
index a40879d..0000000
Binary files a/legacy/public/assets/img/Food/GlazedSeafood.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/GlazedVeggies.png b/legacy/public/assets/img/Food/GlazedVeggies.png
deleted file mode 100644
index 37408cd..0000000
Binary files a/legacy/public/assets/img/Food/GlazedVeggies.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/GourmetMeatAndRiceBowl.png b/legacy/public/assets/img/Food/GourmetMeatAndRiceBowl.png
deleted file mode 100644
index bbdf415..0000000
Binary files a/legacy/public/assets/img/Food/GourmetMeatAndRiceBowl.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/GourmetMeatAndSeafoodFry.png b/legacy/public/assets/img/Food/GourmetMeatAndSeafoodFry.png
deleted file mode 100644
index a137614..0000000
Binary files a/legacy/public/assets/img/Food/GourmetMeatAndSeafoodFry.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/GourmetMeatCurry.png b/legacy/public/assets/img/Food/GourmetMeatCurry.png
deleted file mode 100644
index e654ca7..0000000
Binary files a/legacy/public/assets/img/Food/GourmetMeatCurry.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/GourmetMeatStew.png b/legacy/public/assets/img/Food/GourmetMeatStew.png
deleted file mode 100644
index c0fed10..0000000
Binary files a/legacy/public/assets/img/Food/GourmetMeatStew.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/GourmetPoultryCurry.png b/legacy/public/assets/img/Food/GourmetPoultryCurry.png
deleted file mode 100644
index d53ff16..0000000
Binary files a/legacy/public/assets/img/Food/GourmetPoultryCurry.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/GourmetPoultryPilaf.png b/legacy/public/assets/img/Food/GourmetPoultryPilaf.png
deleted file mode 100644
index 2a12153..0000000
Binary files a/legacy/public/assets/img/Food/GourmetPoultryPilaf.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/GourmetSpicedMeatSkewer.png b/legacy/public/assets/img/Food/GourmetSpicedMeatSkewer.png
deleted file mode 100644
index c42f7b0..0000000
Binary files a/legacy/public/assets/img/Food/GourmetSpicedMeatSkewer.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/HardBoiledEgg.png b/legacy/public/assets/img/Food/HardBoiledEgg.png
deleted file mode 100644
index c659881..0000000
Binary files a/legacy/public/assets/img/Food/HardBoiledEgg.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/HastyElixir.png b/legacy/public/assets/img/Food/HastyElixir.png
deleted file mode 100644
index 99d51b9..0000000
Binary files a/legacy/public/assets/img/Food/HastyElixir.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/HeartyElixir.png b/legacy/public/assets/img/Food/HeartyElixir.png
deleted file mode 100644
index 7ea873b..0000000
Binary files a/legacy/public/assets/img/Food/HeartyElixir.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/HerbSaute.png b/legacy/public/assets/img/Food/HerbSaute.png
deleted file mode 100644
index a1b03bb..0000000
Binary files a/legacy/public/assets/img/Food/HerbSaute.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/HoneyCandy.png b/legacy/public/assets/img/Food/HoneyCandy.png
deleted file mode 100644
index d92738f..0000000
Binary files a/legacy/public/assets/img/Food/HoneyCandy.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/HoneyCrepe.png b/legacy/public/assets/img/Food/HoneyCrepe.png
deleted file mode 100644
index 01f5144..0000000
Binary files a/legacy/public/assets/img/Food/HoneyCrepe.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/HoneyedApple.png b/legacy/public/assets/img/Food/HoneyedApple.png
deleted file mode 100644
index 9fc2100..0000000
Binary files a/legacy/public/assets/img/Food/HoneyedApple.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/HoneyedFruits.png b/legacy/public/assets/img/Food/HoneyedFruits.png
deleted file mode 100644
index 2353d5a..0000000
Binary files a/legacy/public/assets/img/Food/HoneyedFruits.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/HotButteredApple.png b/legacy/public/assets/img/Food/HotButteredApple.png
deleted file mode 100644
index 21a2526..0000000
Binary files a/legacy/public/assets/img/Food/HotButteredApple.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/IcyGourmetMeat.png b/legacy/public/assets/img/Food/IcyGourmetMeat.png
deleted file mode 100644
index 899ed2e..0000000
Binary files a/legacy/public/assets/img/Food/IcyGourmetMeat.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/IcyHeartyBlueshellSnail.png b/legacy/public/assets/img/Food/IcyHeartyBlueshellSnail.png
deleted file mode 100644
index fe43661..0000000
Binary files a/legacy/public/assets/img/Food/IcyHeartyBlueshellSnail.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/IcyMeat.png b/legacy/public/assets/img/Food/IcyMeat.png
deleted file mode 100644
index c4198dd..0000000
Binary files a/legacy/public/assets/img/Food/IcyMeat.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/IcyPrimeMeat.png b/legacy/public/assets/img/Food/IcyPrimeMeat.png
deleted file mode 100644
index e7e2963..0000000
Binary files a/legacy/public/assets/img/Food/IcyPrimeMeat.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/MeatAndMushroomSkewer.png b/legacy/public/assets/img/Food/MeatAndMushroomSkewer.png
deleted file mode 100644
index f073d98..0000000
Binary files a/legacy/public/assets/img/Food/MeatAndMushroomSkewer.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/MeatAndRiceBowl.png b/legacy/public/assets/img/Food/MeatAndRiceBowl.png
deleted file mode 100644
index 5398968..0000000
Binary files a/legacy/public/assets/img/Food/MeatAndRiceBowl.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/MeatAndSeafoodFry.png b/legacy/public/assets/img/Food/MeatAndSeafoodFry.png
deleted file mode 100644
index 92b26ac..0000000
Binary files a/legacy/public/assets/img/Food/MeatAndSeafoodFry.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/MeatCurry.png b/legacy/public/assets/img/Food/MeatCurry.png
deleted file mode 100644
index 054edb9..0000000
Binary files a/legacy/public/assets/img/Food/MeatCurry.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/MeatPie.png b/legacy/public/assets/img/Food/MeatPie.png
deleted file mode 100644
index 6318cba..0000000
Binary files a/legacy/public/assets/img/Food/MeatPie.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/MeatSkewer.png b/legacy/public/assets/img/Food/MeatSkewer.png
deleted file mode 100644
index 41a455c..0000000
Binary files a/legacy/public/assets/img/Food/MeatSkewer.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/MeatStew.png b/legacy/public/assets/img/Food/MeatStew.png
deleted file mode 100644
index 4c96362..0000000
Binary files a/legacy/public/assets/img/Food/MeatStew.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/MeatStuffedPumpkin.png b/legacy/public/assets/img/Food/MeatStuffedPumpkin.png
deleted file mode 100644
index 3bf1072..0000000
Binary files a/legacy/public/assets/img/Food/MeatStuffedPumpkin.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/MeatyRiceBalls.png b/legacy/public/assets/img/Food/MeatyRiceBalls.png
deleted file mode 100644
index f4b98fb..0000000
Binary files a/legacy/public/assets/img/Food/MeatyRiceBalls.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/MightyElixir.png b/legacy/public/assets/img/Food/MightyElixir.png
deleted file mode 100644
index c000f0d..0000000
Binary files a/legacy/public/assets/img/Food/MightyElixir.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/MonsterCake.png b/legacy/public/assets/img/Food/MonsterCake.png
deleted file mode 100644
index ea8fad6..0000000
Binary files a/legacy/public/assets/img/Food/MonsterCake.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/MonsterCurry.png b/legacy/public/assets/img/Food/MonsterCurry.png
deleted file mode 100644
index f9a28b2..0000000
Binary files a/legacy/public/assets/img/Food/MonsterCurry.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/MonsterRiceBalls.png b/legacy/public/assets/img/Food/MonsterRiceBalls.png
deleted file mode 100644
index b950a0f..0000000
Binary files a/legacy/public/assets/img/Food/MonsterRiceBalls.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/MonsterSoup.png b/legacy/public/assets/img/Food/MonsterSoup.png
deleted file mode 100644
index 1dd5159..0000000
Binary files a/legacy/public/assets/img/Food/MonsterSoup.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/MonsterStew.png b/legacy/public/assets/img/Food/MonsterStew.png
deleted file mode 100644
index 005187e..0000000
Binary files a/legacy/public/assets/img/Food/MonsterStew.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/MushroomOmelet.png b/legacy/public/assets/img/Food/MushroomOmelet.png
deleted file mode 100644
index 956291c..0000000
Binary files a/legacy/public/assets/img/Food/MushroomOmelet.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/MushroomRiceBalls.png b/legacy/public/assets/img/Food/MushroomRiceBalls.png
deleted file mode 100644
index 133cf40..0000000
Binary files a/legacy/public/assets/img/Food/MushroomRiceBalls.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/MushroomRisotto.png b/legacy/public/assets/img/Food/MushroomRisotto.png
deleted file mode 100644
index 1fbbca3..0000000
Binary files a/legacy/public/assets/img/Food/MushroomRisotto.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/MushroomSkewer.png b/legacy/public/assets/img/Food/MushroomSkewer.png
deleted file mode 100644
index f31229b..0000000
Binary files a/legacy/public/assets/img/Food/MushroomSkewer.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/Nutcake.png b/legacy/public/assets/img/Food/Nutcake.png
deleted file mode 100644
index 72446db..0000000
Binary files a/legacy/public/assets/img/Food/Nutcake.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/Omelet.png b/legacy/public/assets/img/Food/Omelet.png
deleted file mode 100644
index 4e478b0..0000000
Binary files a/legacy/public/assets/img/Food/Omelet.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/PepperSeafood.png b/legacy/public/assets/img/Food/PepperSeafood.png
deleted file mode 100644
index 62d3b93..0000000
Binary files a/legacy/public/assets/img/Food/PepperSeafood.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/PepperSteak.png b/legacy/public/assets/img/Food/PepperSteak.png
deleted file mode 100644
index 15adc23..0000000
Binary files a/legacy/public/assets/img/Food/PepperSteak.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/PlainCrepe.png b/legacy/public/assets/img/Food/PlainCrepe.png
deleted file mode 100644
index 49fb4d3..0000000
Binary files a/legacy/public/assets/img/Food/PlainCrepe.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/PorgyMeuniere.png b/legacy/public/assets/img/Food/PorgyMeuniere.png
deleted file mode 100644
index 7938ca6..0000000
Binary files a/legacy/public/assets/img/Food/PorgyMeuniere.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/PoultryCurry.png b/legacy/public/assets/img/Food/PoultryCurry.png
deleted file mode 100644
index b23f74b..0000000
Binary files a/legacy/public/assets/img/Food/PoultryCurry.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/PoultryPilaf.png b/legacy/public/assets/img/Food/PoultryPilaf.png
deleted file mode 100644
index f6c0c91..0000000
Binary files a/legacy/public/assets/img/Food/PoultryPilaf.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/PrimeMeatAndRiceBowl.png b/legacy/public/assets/img/Food/PrimeMeatAndRiceBowl.png
deleted file mode 100644
index 981b567..0000000
Binary files a/legacy/public/assets/img/Food/PrimeMeatAndRiceBowl.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/PrimeMeatAndSeafoodFry.png b/legacy/public/assets/img/Food/PrimeMeatAndSeafoodFry.png
deleted file mode 100644
index cd1014f..0000000
Binary files a/legacy/public/assets/img/Food/PrimeMeatAndSeafoodFry.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/PrimeMeatCurry.png b/legacy/public/assets/img/Food/PrimeMeatCurry.png
deleted file mode 100644
index 74f4925..0000000
Binary files a/legacy/public/assets/img/Food/PrimeMeatCurry.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/PrimeMeatStew.png b/legacy/public/assets/img/Food/PrimeMeatStew.png
deleted file mode 100644
index fc02b80..0000000
Binary files a/legacy/public/assets/img/Food/PrimeMeatStew.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/PrimePoultryCurry.png b/legacy/public/assets/img/Food/PrimePoultryCurry.png
deleted file mode 100644
index e344a32..0000000
Binary files a/legacy/public/assets/img/Food/PrimePoultryCurry.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/PrimePoultryPilaf.png b/legacy/public/assets/img/Food/PrimePoultryPilaf.png
deleted file mode 100644
index 6087e4e..0000000
Binary files a/legacy/public/assets/img/Food/PrimePoultryPilaf.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/PrimeSpicedMeatSkewer.png b/legacy/public/assets/img/Food/PrimeSpicedMeatSkewer.png
deleted file mode 100644
index 86cc321..0000000
Binary files a/legacy/public/assets/img/Food/PrimeSpicedMeatSkewer.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/PumpkinPie.png b/legacy/public/assets/img/Food/PumpkinPie.png
deleted file mode 100644
index 833282d..0000000
Binary files a/legacy/public/assets/img/Food/PumpkinPie.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/PumpkinStew.png b/legacy/public/assets/img/Food/PumpkinStew.png
deleted file mode 100644
index fdcb607..0000000
Binary files a/legacy/public/assets/img/Food/PumpkinStew.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedAcorn.png b/legacy/public/assets/img/Food/RoastedAcorn.png
deleted file mode 100644
index 8bf7348..0000000
Binary files a/legacy/public/assets/img/Food/RoastedAcorn.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedArmoranth.png b/legacy/public/assets/img/Food/RoastedArmoranth.png
deleted file mode 100644
index 4cf7497..0000000
Binary files a/legacy/public/assets/img/Food/RoastedArmoranth.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedBass.png b/legacy/public/assets/img/Food/RoastedBass.png
deleted file mode 100644
index da9d1ad..0000000
Binary files a/legacy/public/assets/img/Food/RoastedBass.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedBigRadish.png b/legacy/public/assets/img/Food/RoastedBigRadish.png
deleted file mode 100644
index 6e3374c..0000000
Binary files a/legacy/public/assets/img/Food/RoastedBigRadish.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedBirdDrumstick.png b/legacy/public/assets/img/Food/RoastedBirdDrumstick.png
deleted file mode 100644
index c5583c2..0000000
Binary files a/legacy/public/assets/img/Food/RoastedBirdDrumstick.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedBirdThigh.png b/legacy/public/assets/img/Food/RoastedBirdThigh.png
deleted file mode 100644
index 9cd80f8..0000000
Binary files a/legacy/public/assets/img/Food/RoastedBirdThigh.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedCarp.png b/legacy/public/assets/img/Food/RoastedCarp.png
deleted file mode 100644
index e75ec58..0000000
Binary files a/legacy/public/assets/img/Food/RoastedCarp.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedEnduraCarrot.png b/legacy/public/assets/img/Food/RoastedEnduraCarrot.png
deleted file mode 100644
index cf7ac6c..0000000
Binary files a/legacy/public/assets/img/Food/RoastedEnduraCarrot.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedHeartyBass.png b/legacy/public/assets/img/Food/RoastedHeartyBass.png
deleted file mode 100644
index 5713460..0000000
Binary files a/legacy/public/assets/img/Food/RoastedHeartyBass.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedHeartyDurian.png b/legacy/public/assets/img/Food/RoastedHeartyDurian.png
deleted file mode 100644
index 0d82069..0000000
Binary files a/legacy/public/assets/img/Food/RoastedHeartyDurian.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedHeartySalmon.png b/legacy/public/assets/img/Food/RoastedHeartySalmon.png
deleted file mode 100644
index e015d42..0000000
Binary files a/legacy/public/assets/img/Food/RoastedHeartySalmon.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedHydromelon.png b/legacy/public/assets/img/Food/RoastedHydromelon.png
deleted file mode 100644
index 32ff855..0000000
Binary files a/legacy/public/assets/img/Food/RoastedHydromelon.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedLotusSeeds.png b/legacy/public/assets/img/Food/RoastedLotusSeeds.png
deleted file mode 100644
index e1c5ec0..0000000
Binary files a/legacy/public/assets/img/Food/RoastedLotusSeeds.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedMightyBananas.png b/legacy/public/assets/img/Food/RoastedMightyBananas.png
deleted file mode 100644
index 2046493..0000000
Binary files a/legacy/public/assets/img/Food/RoastedMightyBananas.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedMightyThistle.png b/legacy/public/assets/img/Food/RoastedMightyThistle.png
deleted file mode 100644
index e5ba2ae..0000000
Binary files a/legacy/public/assets/img/Food/RoastedMightyThistle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedPorgy.png b/legacy/public/assets/img/Food/RoastedPorgy.png
deleted file mode 100644
index 18b364d..0000000
Binary files a/legacy/public/assets/img/Food/RoastedPorgy.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedRadish.png b/legacy/public/assets/img/Food/RoastedRadish.png
deleted file mode 100644
index 1773258..0000000
Binary files a/legacy/public/assets/img/Food/RoastedRadish.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedSwiftCarrot.png b/legacy/public/assets/img/Food/RoastedSwiftCarrot.png
deleted file mode 100644
index fc18c0d..0000000
Binary files a/legacy/public/assets/img/Food/RoastedSwiftCarrot.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedTreeNut.png b/legacy/public/assets/img/Food/RoastedTreeNut.png
deleted file mode 100644
index a0ee91a..0000000
Binary files a/legacy/public/assets/img/Food/RoastedTreeNut.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedTrout.png b/legacy/public/assets/img/Food/RoastedTrout.png
deleted file mode 100644
index e66e9da..0000000
Binary files a/legacy/public/assets/img/Food/RoastedTrout.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedVoltfruit.png b/legacy/public/assets/img/Food/RoastedVoltfruit.png
deleted file mode 100644
index 6b523a7..0000000
Binary files a/legacy/public/assets/img/Food/RoastedVoltfruit.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedWholeBird.png b/legacy/public/assets/img/Food/RoastedWholeBird.png
deleted file mode 100644
index 3fa070e..0000000
Binary files a/legacy/public/assets/img/Food/RoastedWholeBird.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RoastedWildberry.png b/legacy/public/assets/img/Food/RoastedWildberry.png
deleted file mode 100644
index cd283be..0000000
Binary files a/legacy/public/assets/img/Food/RoastedWildberry.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/RockHardFood.png b/legacy/public/assets/img/Food/RockHardFood.png
deleted file mode 100644
index e126f65..0000000
Binary files a/legacy/public/assets/img/Food/RockHardFood.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SalmonMeuniere.png b/legacy/public/assets/img/Food/SalmonMeuniere.png
deleted file mode 100644
index beb8c7e..0000000
Binary files a/legacy/public/assets/img/Food/SalmonMeuniere.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SalmonRisotto.png b/legacy/public/assets/img/Food/SalmonRisotto.png
deleted file mode 100644
index 5b4eefa..0000000
Binary files a/legacy/public/assets/img/Food/SalmonRisotto.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SaltGrilledCrab.png b/legacy/public/assets/img/Food/SaltGrilledCrab.png
deleted file mode 100644
index 67050db..0000000
Binary files a/legacy/public/assets/img/Food/SaltGrilledCrab.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SaltGrilledFish.png b/legacy/public/assets/img/Food/SaltGrilledFish.png
deleted file mode 100644
index 3a9d17e..0000000
Binary files a/legacy/public/assets/img/Food/SaltGrilledFish.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SaltGrilledGourmetMeat.png b/legacy/public/assets/img/Food/SaltGrilledGourmetMeat.png
deleted file mode 100644
index 519c339..0000000
Binary files a/legacy/public/assets/img/Food/SaltGrilledGourmetMeat.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SaltGrilledGreens.png b/legacy/public/assets/img/Food/SaltGrilledGreens.png
deleted file mode 100644
index 32b24f2..0000000
Binary files a/legacy/public/assets/img/Food/SaltGrilledGreens.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SaltGrilledMeat.png b/legacy/public/assets/img/Food/SaltGrilledMeat.png
deleted file mode 100644
index 74eca71..0000000
Binary files a/legacy/public/assets/img/Food/SaltGrilledMeat.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SaltGrilledMushrooms.png b/legacy/public/assets/img/Food/SaltGrilledMushrooms.png
deleted file mode 100644
index ee62ea6..0000000
Binary files a/legacy/public/assets/img/Food/SaltGrilledMushrooms.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SaltGrilledPrimeMeat.png b/legacy/public/assets/img/Food/SaltGrilledPrimeMeat.png
deleted file mode 100644
index 0682359..0000000
Binary files a/legacy/public/assets/img/Food/SaltGrilledPrimeMeat.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SauteedNuts.png b/legacy/public/assets/img/Food/SauteedNuts.png
deleted file mode 100644
index b79a7df..0000000
Binary files a/legacy/public/assets/img/Food/SauteedNuts.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SauteedPeppers.png b/legacy/public/assets/img/Food/SauteedPeppers.png
deleted file mode 100644
index b4b04b3..0000000
Binary files a/legacy/public/assets/img/Food/SauteedPeppers.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SeafoodCurry.png b/legacy/public/assets/img/Food/SeafoodCurry.png
deleted file mode 100644
index 68a0591..0000000
Binary files a/legacy/public/assets/img/Food/SeafoodCurry.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SeafoodFriedRice.png b/legacy/public/assets/img/Food/SeafoodFriedRice.png
deleted file mode 100644
index f682bb8..0000000
Binary files a/legacy/public/assets/img/Food/SeafoodFriedRice.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SeafoodMeuniere.png b/legacy/public/assets/img/Food/SeafoodMeuniere.png
deleted file mode 100644
index 3dfa7de..0000000
Binary files a/legacy/public/assets/img/Food/SeafoodMeuniere.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SeafoodPaella.png b/legacy/public/assets/img/Food/SeafoodPaella.png
deleted file mode 100644
index d19f51d..0000000
Binary files a/legacy/public/assets/img/Food/SeafoodPaella.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SeafoodRiceBalls.png b/legacy/public/assets/img/Food/SeafoodRiceBalls.png
deleted file mode 100644
index 3f29921..0000000
Binary files a/legacy/public/assets/img/Food/SeafoodRiceBalls.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SeafoodSkewer.png b/legacy/public/assets/img/Food/SeafoodSkewer.png
deleted file mode 100644
index ade7c9f..0000000
Binary files a/legacy/public/assets/img/Food/SeafoodSkewer.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SearedGourmetSteak.png b/legacy/public/assets/img/Food/SearedGourmetSteak.png
deleted file mode 100644
index 07d7cc6..0000000
Binary files a/legacy/public/assets/img/Food/SearedGourmetSteak.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SearedPrimeSteak.png b/legacy/public/assets/img/Food/SearedPrimeSteak.png
deleted file mode 100644
index b72501e..0000000
Binary files a/legacy/public/assets/img/Food/SearedPrimeSteak.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SearedSteak.png b/legacy/public/assets/img/Food/SearedSteak.png
deleted file mode 100644
index 1afe004..0000000
Binary files a/legacy/public/assets/img/Food/SearedSteak.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SimmeredFruit.png b/legacy/public/assets/img/Food/SimmeredFruit.png
deleted file mode 100644
index 2a85991..0000000
Binary files a/legacy/public/assets/img/Food/SimmeredFruit.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SneakyElixir.png b/legacy/public/assets/img/Food/SneakyElixir.png
deleted file mode 100644
index f0240bc..0000000
Binary files a/legacy/public/assets/img/Food/SneakyElixir.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SneakyRiverEscargot.png b/legacy/public/assets/img/Food/SneakyRiverEscargot.png
deleted file mode 100644
index 61e62fa..0000000
Binary files a/legacy/public/assets/img/Food/SneakyRiverEscargot.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SpicedMeatSkewer.png b/legacy/public/assets/img/Food/SpicedMeatSkewer.png
deleted file mode 100644
index 49c2820..0000000
Binary files a/legacy/public/assets/img/Food/SpicedMeatSkewer.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SpicyElixir.png b/legacy/public/assets/img/Food/SpicyElixir.png
deleted file mode 100644
index b9988f1..0000000
Binary files a/legacy/public/assets/img/Food/SpicyElixir.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SteamedFish.png b/legacy/public/assets/img/Food/SteamedFish.png
deleted file mode 100644
index f43acf1..0000000
Binary files a/legacy/public/assets/img/Food/SteamedFish.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SteamedFruit.png b/legacy/public/assets/img/Food/SteamedFruit.png
deleted file mode 100644
index c6a465b..0000000
Binary files a/legacy/public/assets/img/Food/SteamedFruit.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SteamedMeat.png b/legacy/public/assets/img/Food/SteamedMeat.png
deleted file mode 100644
index 6fb612f..0000000
Binary files a/legacy/public/assets/img/Food/SteamedMeat.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/SteamedMushrooms.png b/legacy/public/assets/img/Food/SteamedMushrooms.png
deleted file mode 100644
index 3c4028e..0000000
Binary files a/legacy/public/assets/img/Food/SteamedMushrooms.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/ToastedBigHeartyTruffle.png b/legacy/public/assets/img/Food/ToastedBigHeartyTruffle.png
deleted file mode 100644
index c0f8bbc..0000000
Binary files a/legacy/public/assets/img/Food/ToastedBigHeartyTruffle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/ToastedHeartyTruffle.png b/legacy/public/assets/img/Food/ToastedHeartyTruffle.png
deleted file mode 100644
index 9f22551..0000000
Binary files a/legacy/public/assets/img/Food/ToastedHeartyTruffle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/ToastyChillshroom.png b/legacy/public/assets/img/Food/ToastyChillshroom.png
deleted file mode 100644
index 393044b..0000000
Binary files a/legacy/public/assets/img/Food/ToastyChillshroom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/ToastyEnduraShroom.png b/legacy/public/assets/img/Food/ToastyEnduraShroom.png
deleted file mode 100644
index 6d146ba..0000000
Binary files a/legacy/public/assets/img/Food/ToastyEnduraShroom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/ToastyHylianShroom.png b/legacy/public/assets/img/Food/ToastyHylianShroom.png
deleted file mode 100644
index bd54a66..0000000
Binary files a/legacy/public/assets/img/Food/ToastyHylianShroom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/ToastyIronshroom.png b/legacy/public/assets/img/Food/ToastyIronshroom.png
deleted file mode 100644
index 1e54c4e..0000000
Binary files a/legacy/public/assets/img/Food/ToastyIronshroom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/ToastyRazorshroom.png b/legacy/public/assets/img/Food/ToastyRazorshroom.png
deleted file mode 100644
index 4e55f7c..0000000
Binary files a/legacy/public/assets/img/Food/ToastyRazorshroom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/ToastyRushroom.png b/legacy/public/assets/img/Food/ToastyRushroom.png
deleted file mode 100644
index 359250b..0000000
Binary files a/legacy/public/assets/img/Food/ToastyRushroom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/ToastySilentShroom.png b/legacy/public/assets/img/Food/ToastySilentShroom.png
deleted file mode 100644
index 6a61e2d..0000000
Binary files a/legacy/public/assets/img/Food/ToastySilentShroom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/ToastyStamellaShroom.png b/legacy/public/assets/img/Food/ToastyStamellaShroom.png
deleted file mode 100644
index e07c8af..0000000
Binary files a/legacy/public/assets/img/Food/ToastyStamellaShroom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/ToastySunshroom.png b/legacy/public/assets/img/Food/ToastySunshroom.png
deleted file mode 100644
index 0f3cc6f..0000000
Binary files a/legacy/public/assets/img/Food/ToastySunshroom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/ToastyZapshroom.png b/legacy/public/assets/img/Food/ToastyZapshroom.png
deleted file mode 100644
index 37b4d98..0000000
Binary files a/legacy/public/assets/img/Food/ToastyZapshroom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/ToughElixir.png b/legacy/public/assets/img/Food/ToughElixir.png
deleted file mode 100644
index a3213d2..0000000
Binary files a/legacy/public/assets/img/Food/ToughElixir.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/VegetableCurry.png b/legacy/public/assets/img/Food/VegetableCurry.png
deleted file mode 100644
index c70a8a9..0000000
Binary files a/legacy/public/assets/img/Food/VegetableCurry.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/VegetableOmelet.png b/legacy/public/assets/img/Food/VegetableOmelet.png
deleted file mode 100644
index 19cd510..0000000
Binary files a/legacy/public/assets/img/Food/VegetableOmelet.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/VegetableRisotto.png b/legacy/public/assets/img/Food/VegetableRisotto.png
deleted file mode 100644
index c8abf48..0000000
Binary files a/legacy/public/assets/img/Food/VegetableRisotto.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/VeggieCreamSoup.png b/legacy/public/assets/img/Food/VeggieCreamSoup.png
deleted file mode 100644
index bf30f2e..0000000
Binary files a/legacy/public/assets/img/Food/VeggieCreamSoup.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/VeggieRiceBalls.png b/legacy/public/assets/img/Food/VeggieRiceBalls.png
deleted file mode 100644
index 5aaffc2..0000000
Binary files a/legacy/public/assets/img/Food/VeggieRiceBalls.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/WarmMilk.png b/legacy/public/assets/img/Food/WarmMilk.png
deleted file mode 100644
index a65309a..0000000
Binary files a/legacy/public/assets/img/Food/WarmMilk.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/WheatBread.png b/legacy/public/assets/img/Food/WheatBread.png
deleted file mode 100644
index 941b5d6..0000000
Binary files a/legacy/public/assets/img/Food/WheatBread.png and /dev/null differ
diff --git a/legacy/public/assets/img/Food/WildberryCrepe.png b/legacy/public/assets/img/Food/WildberryCrepe.png
deleted file mode 100644
index cc29d87..0000000
Binary files a/legacy/public/assets/img/Food/WildberryCrepe.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/AncientBridle.png b/legacy/public/assets/img/Key/AncientBridle.png
deleted file mode 100644
index f5b7609..0000000
Binary files a/legacy/public/assets/img/Key/AncientBridle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/AncientSaddle.png b/legacy/public/assets/img/Key/AncientSaddle.png
deleted file mode 100644
index 4136d86..0000000
Binary files a/legacy/public/assets/img/Key/AncientSaddle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/ClassifiedEnvelope.png b/legacy/public/assets/img/Key/ClassifiedEnvelope.png
deleted file mode 100644
index a362418..0000000
Binary files a/legacy/public/assets/img/Key/ClassifiedEnvelope.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/DaruksProtection.png b/legacy/public/assets/img/Key/DaruksProtection.png
deleted file mode 100644
index 276f4b5..0000000
Binary files a/legacy/public/assets/img/Key/DaruksProtection.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/DaruksProtectionDisabled.png b/legacy/public/assets/img/Key/DaruksProtectionDisabled.png
deleted file mode 100644
index 00ab23b..0000000
Binary files a/legacy/public/assets/img/Key/DaruksProtectionDisabled.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/DaruksProtectionPlus.png b/legacy/public/assets/img/Key/DaruksProtectionPlus.png
deleted file mode 100644
index dc5cbef..0000000
Binary files a/legacy/public/assets/img/Key/DaruksProtectionPlus.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/DaruksProtectionPlusDisabled.png b/legacy/public/assets/img/Key/DaruksProtectionPlusDisabled.png
deleted file mode 100644
index f2d2c3e..0000000
Binary files a/legacy/public/assets/img/Key/DaruksProtectionPlusDisabled.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/ExtravagantBridle.png b/legacy/public/assets/img/Key/ExtravagantBridle.png
deleted file mode 100644
index 4b3cded..0000000
Binary files a/legacy/public/assets/img/Key/ExtravagantBridle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/ExtravagantSaddle.png b/legacy/public/assets/img/Key/ExtravagantSaddle.png
deleted file mode 100644
index 8d69873..0000000
Binary files a/legacy/public/assets/img/Key/ExtravagantSaddle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/HestusGift.png b/legacy/public/assets/img/Key/HestusGift.png
deleted file mode 100644
index 58ba61a..0000000
Binary files a/legacy/public/assets/img/Key/HestusGift.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/HestusMaracas.png b/legacy/public/assets/img/Key/HestusMaracas.png
deleted file mode 100644
index 076da5a..0000000
Binary files a/legacy/public/assets/img/Key/HestusMaracas.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/KnightsBridle.png b/legacy/public/assets/img/Key/KnightsBridle.png
deleted file mode 100644
index 9ee65a6..0000000
Binary files a/legacy/public/assets/img/Key/KnightsBridle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/KnightsSaddle.png b/legacy/public/assets/img/Key/KnightsSaddle.png
deleted file mode 100644
index 04cf883..0000000
Binary files a/legacy/public/assets/img/Key/KnightsSaddle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/KorokSeed.png b/legacy/public/assets/img/Key/KorokSeed.png
deleted file mode 100644
index cd893a5..0000000
Binary files a/legacy/public/assets/img/Key/KorokSeed.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/MedalOfHonorHinox.png b/legacy/public/assets/img/Key/MedalOfHonorHinox.png
deleted file mode 100644
index a224341..0000000
Binary files a/legacy/public/assets/img/Key/MedalOfHonorHinox.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/MedalOfHonorMolduga.png b/legacy/public/assets/img/Key/MedalOfHonorMolduga.png
deleted file mode 100644
index 88a8918..0000000
Binary files a/legacy/public/assets/img/Key/MedalOfHonorMolduga.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/MedalOfHonorTalus.png b/legacy/public/assets/img/Key/MedalOfHonorTalus.png
deleted file mode 100644
index 17c2e84..0000000
Binary files a/legacy/public/assets/img/Key/MedalOfHonorTalus.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/MedohsEmblem.png b/legacy/public/assets/img/Key/MedohsEmblem.png
deleted file mode 100644
index 23a38be..0000000
Binary files a/legacy/public/assets/img/Key/MedohsEmblem.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/MiphasGrace.png b/legacy/public/assets/img/Key/MiphasGrace.png
deleted file mode 100644
index f8f5074..0000000
Binary files a/legacy/public/assets/img/Key/MiphasGrace.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/MiphasGraceDisabled.png b/legacy/public/assets/img/Key/MiphasGraceDisabled.png
deleted file mode 100644
index a182bde..0000000
Binary files a/legacy/public/assets/img/Key/MiphasGraceDisabled.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/MiphasGracePlus.png b/legacy/public/assets/img/Key/MiphasGracePlus.png
deleted file mode 100644
index 5f3d80f..0000000
Binary files a/legacy/public/assets/img/Key/MiphasGracePlus.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/MiphasGracePlusDisabled.png b/legacy/public/assets/img/Key/MiphasGracePlusDisabled.png
deleted file mode 100644
index 648bb95..0000000
Binary files a/legacy/public/assets/img/Key/MiphasGracePlusDisabled.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/MonsterBridle.png b/legacy/public/assets/img/Key/MonsterBridle.png
deleted file mode 100644
index b2fa2f9..0000000
Binary files a/legacy/public/assets/img/Key/MonsterBridle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/MonsterSaddle.png b/legacy/public/assets/img/Key/MonsterSaddle.png
deleted file mode 100644
index 47b0500..0000000
Binary files a/legacy/public/assets/img/Key/MonsterSaddle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/NaborissEmblem.png b/legacy/public/assets/img/Key/NaborissEmblem.png
deleted file mode 100644
index fb49afe..0000000
Binary files a/legacy/public/assets/img/Key/NaborissEmblem.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/Paraglider.png b/legacy/public/assets/img/Key/Paraglider.png
deleted file mode 100644
index 9f7e3de..0000000
Binary files a/legacy/public/assets/img/Key/Paraglider.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/PictureOfTheChampions.png b/legacy/public/assets/img/Key/PictureOfTheChampions.png
deleted file mode 100644
index a378160..0000000
Binary files a/legacy/public/assets/img/Key/PictureOfTheChampions.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/RevalisGale.png b/legacy/public/assets/img/Key/RevalisGale.png
deleted file mode 100644
index 5349613..0000000
Binary files a/legacy/public/assets/img/Key/RevalisGale.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/RevalisGaleDisabled.png b/legacy/public/assets/img/Key/RevalisGaleDisabled.png
deleted file mode 100644
index bd4bc0d..0000000
Binary files a/legacy/public/assets/img/Key/RevalisGaleDisabled.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/RevalisGalePlus.png b/legacy/public/assets/img/Key/RevalisGalePlus.png
deleted file mode 100644
index c01ca1f..0000000
Binary files a/legacy/public/assets/img/Key/RevalisGalePlus.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/RevalisGalePlusDisabled.png b/legacy/public/assets/img/Key/RevalisGalePlusDisabled.png
deleted file mode 100644
index 5d28bc5..0000000
Binary files a/legacy/public/assets/img/Key/RevalisGalePlusDisabled.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/RoyalBridle.png b/legacy/public/assets/img/Key/RoyalBridle.png
deleted file mode 100644
index bbe52f2..0000000
Binary files a/legacy/public/assets/img/Key/RoyalBridle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/RoyalSaddle.png b/legacy/public/assets/img/Key/RoyalSaddle.png
deleted file mode 100644
index b2e2cda..0000000
Binary files a/legacy/public/assets/img/Key/RoyalSaddle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/RudaniasEmblem.png b/legacy/public/assets/img/Key/RudaniasEmblem.png
deleted file mode 100644
index 91b6efb..0000000
Binary files a/legacy/public/assets/img/Key/RudaniasEmblem.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/RutasEmblem.png b/legacy/public/assets/img/Key/RutasEmblem.png
deleted file mode 100644
index 6e72bf1..0000000
Binary files a/legacy/public/assets/img/Key/RutasEmblem.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/SheikahSlate.png b/legacy/public/assets/img/Key/SheikahSlate.png
deleted file mode 100644
index 5f86b15..0000000
Binary files a/legacy/public/assets/img/Key/SheikahSlate.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/SpiritOrb.png b/legacy/public/assets/img/Key/SpiritOrb.png
deleted file mode 100644
index 00e8ea4..0000000
Binary files a/legacy/public/assets/img/Key/SpiritOrb.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/SpiritOrbAnimated.webp b/legacy/public/assets/img/Key/SpiritOrbAnimated.webp
deleted file mode 100644
index 31cb3fd..0000000
Binary files a/legacy/public/assets/img/Key/SpiritOrbAnimated.webp and /dev/null differ
diff --git a/legacy/public/assets/img/Key/ThunderHelmKey.png b/legacy/public/assets/img/Key/ThunderHelmKey.png
deleted file mode 100644
index 8365fa4..0000000
Binary files a/legacy/public/assets/img/Key/ThunderHelmKey.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/TravelMedallion.png b/legacy/public/assets/img/Key/TravelMedallion.png
deleted file mode 100644
index c216dc0..0000000
Binary files a/legacy/public/assets/img/Key/TravelMedallion.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/TravelMedallionAnimated.webp b/legacy/public/assets/img/Key/TravelMedallionAnimated.webp
deleted file mode 100644
index b3e3c8c..0000000
Binary files a/legacy/public/assets/img/Key/TravelMedallionAnimated.webp and /dev/null differ
diff --git a/legacy/public/assets/img/Key/TravelersBridle.png b/legacy/public/assets/img/Key/TravelersBridle.png
deleted file mode 100644
index ef6a809..0000000
Binary files a/legacy/public/assets/img/Key/TravelersBridle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/TravelersSaddle.png b/legacy/public/assets/img/Key/TravelersSaddle.png
deleted file mode 100644
index e2e2a8d..0000000
Binary files a/legacy/public/assets/img/Key/TravelersSaddle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/UrbosasFury.png b/legacy/public/assets/img/Key/UrbosasFury.png
deleted file mode 100644
index 050256c..0000000
Binary files a/legacy/public/assets/img/Key/UrbosasFury.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/UrbosasFuryDisabled.png b/legacy/public/assets/img/Key/UrbosasFuryDisabled.png
deleted file mode 100644
index 9402a55..0000000
Binary files a/legacy/public/assets/img/Key/UrbosasFuryDisabled.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/UrbosasFuryPlus.png b/legacy/public/assets/img/Key/UrbosasFuryPlus.png
deleted file mode 100644
index b7160b7..0000000
Binary files a/legacy/public/assets/img/Key/UrbosasFuryPlus.png and /dev/null differ
diff --git a/legacy/public/assets/img/Key/UrbosasFuryPlusDisabled.png b/legacy/public/assets/img/Key/UrbosasFuryPlusDisabled.png
deleted file mode 100644
index 9ab79d7..0000000
Binary files a/legacy/public/assets/img/Key/UrbosasFuryPlusDisabled.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Acorn.png b/legacy/public/assets/img/Material/Acorn.png
deleted file mode 100644
index 74c1fc1..0000000
Binary files a/legacy/public/assets/img/Material/Acorn.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Amber.png b/legacy/public/assets/img/Material/Amber.png
deleted file mode 100644
index 2eafba2..0000000
Binary files a/legacy/public/assets/img/Material/Amber.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/AncientCore.png b/legacy/public/assets/img/Material/AncientCore.png
deleted file mode 100644
index 934253f..0000000
Binary files a/legacy/public/assets/img/Material/AncientCore.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/AncientGear.png b/legacy/public/assets/img/Material/AncientGear.png
deleted file mode 100644
index 893370e..0000000
Binary files a/legacy/public/assets/img/Material/AncientGear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/AncientScrew.png b/legacy/public/assets/img/Material/AncientScrew.png
deleted file mode 100644
index 08d7f16..0000000
Binary files a/legacy/public/assets/img/Material/AncientScrew.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/AncientShaft.png b/legacy/public/assets/img/Material/AncientShaft.png
deleted file mode 100644
index 867bfbb..0000000
Binary files a/legacy/public/assets/img/Material/AncientShaft.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/AncientSpring.png b/legacy/public/assets/img/Material/AncientSpring.png
deleted file mode 100644
index c1f211d..0000000
Binary files a/legacy/public/assets/img/Material/AncientSpring.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Apple.png b/legacy/public/assets/img/Material/Apple.png
deleted file mode 100644
index e6e9973..0000000
Binary files a/legacy/public/assets/img/Material/Apple.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Armoranth.png b/legacy/public/assets/img/Material/Armoranth.png
deleted file mode 100644
index 564cb9c..0000000
Binary files a/legacy/public/assets/img/Material/Armoranth.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/ArmoredCarp.png b/legacy/public/assets/img/Material/ArmoredCarp.png
deleted file mode 100644
index 586fbf7..0000000
Binary files a/legacy/public/assets/img/Material/ArmoredCarp.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/ArmoredPorgy.png b/legacy/public/assets/img/Material/ArmoredPorgy.png
deleted file mode 100644
index b7cac60..0000000
Binary files a/legacy/public/assets/img/Material/ArmoredPorgy.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/BigHeartyRadish.png b/legacy/public/assets/img/Material/BigHeartyRadish.png
deleted file mode 100644
index 04e70de..0000000
Binary files a/legacy/public/assets/img/Material/BigHeartyRadish.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/BigHeartyTruffle.png b/legacy/public/assets/img/Material/BigHeartyTruffle.png
deleted file mode 100644
index 0526d5b..0000000
Binary files a/legacy/public/assets/img/Material/BigHeartyTruffle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/BirdEgg.png b/legacy/public/assets/img/Material/BirdEgg.png
deleted file mode 100644
index 8a4508f..0000000
Binary files a/legacy/public/assets/img/Material/BirdEgg.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/BladedRhinoBeetle.png b/legacy/public/assets/img/Material/BladedRhinoBeetle.png
deleted file mode 100644
index d947cd7..0000000
Binary files a/legacy/public/assets/img/Material/BladedRhinoBeetle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/BlueNightshade.png b/legacy/public/assets/img/Material/BlueNightshade.png
deleted file mode 100644
index 268812f..0000000
Binary files a/legacy/public/assets/img/Material/BlueNightshade.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/BokoblinFang.png b/legacy/public/assets/img/Material/BokoblinFang.png
deleted file mode 100644
index 2107711..0000000
Binary files a/legacy/public/assets/img/Material/BokoblinFang.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/BokoblinGuts.png b/legacy/public/assets/img/Material/BokoblinGuts.png
deleted file mode 100644
index 36d102a..0000000
Binary files a/legacy/public/assets/img/Material/BokoblinGuts.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/BokoblinHorn.png b/legacy/public/assets/img/Material/BokoblinHorn.png
deleted file mode 100644
index 5e8c85e..0000000
Binary files a/legacy/public/assets/img/Material/BokoblinHorn.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/BrightEyedCrab.png b/legacy/public/assets/img/Material/BrightEyedCrab.png
deleted file mode 100644
index e756ecf..0000000
Binary files a/legacy/public/assets/img/Material/BrightEyedCrab.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/CaneSugar.png b/legacy/public/assets/img/Material/CaneSugar.png
deleted file mode 100644
index b40339e..0000000
Binary files a/legacy/public/assets/img/Material/CaneSugar.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/ChickalooTreeNut.png b/legacy/public/assets/img/Material/ChickalooTreeNut.png
deleted file mode 100644
index 6cdb6be..0000000
Binary files a/legacy/public/assets/img/Material/ChickalooTreeNut.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/ChillfinTrout.png b/legacy/public/assets/img/Material/ChillfinTrout.png
deleted file mode 100644
index 803da56..0000000
Binary files a/legacy/public/assets/img/Material/ChillfinTrout.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Chillshroom.png b/legacy/public/assets/img/Material/Chillshroom.png
deleted file mode 100644
index 517e009..0000000
Binary files a/legacy/public/assets/img/Material/Chillshroom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/ChuchuJelly.png b/legacy/public/assets/img/Material/ChuchuJelly.png
deleted file mode 100644
index ae9940c..0000000
Binary files a/legacy/public/assets/img/Material/ChuchuJelly.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/ColdDarner.png b/legacy/public/assets/img/Material/ColdDarner.png
deleted file mode 100644
index 412835b..0000000
Binary files a/legacy/public/assets/img/Material/ColdDarner.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/CoolSafflina.png b/legacy/public/assets/img/Material/CoolSafflina.png
deleted file mode 100644
index 225faf5..0000000
Binary files a/legacy/public/assets/img/Material/CoolSafflina.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/CourserBeeHoney.png b/legacy/public/assets/img/Material/CourserBeeHoney.png
deleted file mode 100644
index cde2c7e..0000000
Binary files a/legacy/public/assets/img/Material/CourserBeeHoney.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Diamond.png b/legacy/public/assets/img/Material/Diamond.png
deleted file mode 100644
index bb3e125..0000000
Binary files a/legacy/public/assets/img/Material/Diamond.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/DinraalsClaw.png b/legacy/public/assets/img/Material/DinraalsClaw.png
deleted file mode 100644
index bc950b2..0000000
Binary files a/legacy/public/assets/img/Material/DinraalsClaw.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/DinraalsScale.png b/legacy/public/assets/img/Material/DinraalsScale.png
deleted file mode 100644
index 8f052cc..0000000
Binary files a/legacy/public/assets/img/Material/DinraalsScale.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/ElectricDarner.png b/legacy/public/assets/img/Material/ElectricDarner.png
deleted file mode 100644
index 76f67ff..0000000
Binary files a/legacy/public/assets/img/Material/ElectricDarner.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/ElectricKeeseWing.png b/legacy/public/assets/img/Material/ElectricKeeseWing.png
deleted file mode 100644
index f4d062a..0000000
Binary files a/legacy/public/assets/img/Material/ElectricKeeseWing.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/ElectricSafflina.png b/legacy/public/assets/img/Material/ElectricSafflina.png
deleted file mode 100644
index c386eae..0000000
Binary files a/legacy/public/assets/img/Material/ElectricSafflina.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/EnduraCarrot.png b/legacy/public/assets/img/Material/EnduraCarrot.png
deleted file mode 100644
index 6e61753..0000000
Binary files a/legacy/public/assets/img/Material/EnduraCarrot.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/EnduraShroom.png b/legacy/public/assets/img/Material/EnduraShroom.png
deleted file mode 100644
index 499e386..0000000
Binary files a/legacy/public/assets/img/Material/EnduraShroom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/EnergeticRhinoBeetle.png b/legacy/public/assets/img/Material/EnergeticRhinoBeetle.png
deleted file mode 100644
index 4603e48..0000000
Binary files a/legacy/public/assets/img/Material/EnergeticRhinoBeetle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Fairy.png b/legacy/public/assets/img/Material/Fairy.png
deleted file mode 100644
index b4ada1b..0000000
Binary files a/legacy/public/assets/img/Material/Fairy.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/FaroshsClaw.png b/legacy/public/assets/img/Material/FaroshsClaw.png
deleted file mode 100644
index 2f7c53a..0000000
Binary files a/legacy/public/assets/img/Material/FaroshsClaw.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/FaroshsScale.png b/legacy/public/assets/img/Material/FaroshsScale.png
deleted file mode 100644
index 32dd3e2..0000000
Binary files a/legacy/public/assets/img/Material/FaroshsScale.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/FireKeeseWing.png b/legacy/public/assets/img/Material/FireKeeseWing.png
deleted file mode 100644
index 1cd89a5..0000000
Binary files a/legacy/public/assets/img/Material/FireKeeseWing.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/FireproofLizard.png b/legacy/public/assets/img/Material/FireproofLizard.png
deleted file mode 100644
index 1f79467..0000000
Binary files a/legacy/public/assets/img/Material/FireproofLizard.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/FleetLotusSeeds.png b/legacy/public/assets/img/Material/FleetLotusSeeds.png
deleted file mode 100644
index 9816493..0000000
Binary files a/legacy/public/assets/img/Material/FleetLotusSeeds.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Flint.png b/legacy/public/assets/img/Material/Flint.png
deleted file mode 100644
index 53903d3..0000000
Binary files a/legacy/public/assets/img/Material/Flint.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/FortifiedPumpkin.png b/legacy/public/assets/img/Material/FortifiedPumpkin.png
deleted file mode 100644
index dbace0a..0000000
Binary files a/legacy/public/assets/img/Material/FortifiedPumpkin.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/FreshMilk.png b/legacy/public/assets/img/Material/FreshMilk.png
deleted file mode 100644
index 4804627..0000000
Binary files a/legacy/public/assets/img/Material/FreshMilk.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/GiantAncientCore.png b/legacy/public/assets/img/Material/GiantAncientCore.png
deleted file mode 100644
index 8e1496d..0000000
Binary files a/legacy/public/assets/img/Material/GiantAncientCore.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/GoatButter.png b/legacy/public/assets/img/Material/GoatButter.png
deleted file mode 100644
index 72a8da1..0000000
Binary files a/legacy/public/assets/img/Material/GoatButter.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/GoronSpice.png b/legacy/public/assets/img/Material/GoronSpice.png
deleted file mode 100644
index 291caae..0000000
Binary files a/legacy/public/assets/img/Material/GoronSpice.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/HeartyBass.png b/legacy/public/assets/img/Material/HeartyBass.png
deleted file mode 100644
index 7e1cbe4..0000000
Binary files a/legacy/public/assets/img/Material/HeartyBass.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/HeartyBlueshellSnail.png b/legacy/public/assets/img/Material/HeartyBlueshellSnail.png
deleted file mode 100644
index a710bda..0000000
Binary files a/legacy/public/assets/img/Material/HeartyBlueshellSnail.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/HeartyDurian.png b/legacy/public/assets/img/Material/HeartyDurian.png
deleted file mode 100644
index ccd5f2f..0000000
Binary files a/legacy/public/assets/img/Material/HeartyDurian.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/HeartyLizard.png b/legacy/public/assets/img/Material/HeartyLizard.png
deleted file mode 100644
index f5513c6..0000000
Binary files a/legacy/public/assets/img/Material/HeartyLizard.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/HeartyRadish.png b/legacy/public/assets/img/Material/HeartyRadish.png
deleted file mode 100644
index 254e45d..0000000
Binary files a/legacy/public/assets/img/Material/HeartyRadish.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/HeartySalmon.png b/legacy/public/assets/img/Material/HeartySalmon.png
deleted file mode 100644
index 58f5bcb..0000000
Binary files a/legacy/public/assets/img/Material/HeartySalmon.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/HeartyTruffle.png b/legacy/public/assets/img/Material/HeartyTruffle.png
deleted file mode 100644
index be74661..0000000
Binary files a/legacy/public/assets/img/Material/HeartyTruffle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/HightailLizard.png b/legacy/public/assets/img/Material/HightailLizard.png
deleted file mode 100644
index ae17b3f..0000000
Binary files a/legacy/public/assets/img/Material/HightailLizard.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/HinoxGuts.png b/legacy/public/assets/img/Material/HinoxGuts.png
deleted file mode 100644
index 3300c0f..0000000
Binary files a/legacy/public/assets/img/Material/HinoxGuts.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/HinoxToenail.png b/legacy/public/assets/img/Material/HinoxToenail.png
deleted file mode 100644
index df4b533..0000000
Binary files a/legacy/public/assets/img/Material/HinoxToenail.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/HinoxTooth.png b/legacy/public/assets/img/Material/HinoxTooth.png
deleted file mode 100644
index 51a0055..0000000
Binary files a/legacy/public/assets/img/Material/HinoxTooth.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/HotFootedFrog.png b/legacy/public/assets/img/Material/HotFootedFrog.png
deleted file mode 100644
index 8da91ea..0000000
Binary files a/legacy/public/assets/img/Material/HotFootedFrog.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Hydromelon.png b/legacy/public/assets/img/Material/Hydromelon.png
deleted file mode 100644
index 7d2699b..0000000
Binary files a/legacy/public/assets/img/Material/Hydromelon.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/HylianRice.png b/legacy/public/assets/img/Material/HylianRice.png
deleted file mode 100644
index a905059..0000000
Binary files a/legacy/public/assets/img/Material/HylianRice.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/HylianShroom.png b/legacy/public/assets/img/Material/HylianShroom.png
deleted file mode 100644
index 979c3b4..0000000
Binary files a/legacy/public/assets/img/Material/HylianShroom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/HyruleBass.png b/legacy/public/assets/img/Material/HyruleBass.png
deleted file mode 100644
index 6775618..0000000
Binary files a/legacy/public/assets/img/Material/HyruleBass.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/HyruleHerb.png b/legacy/public/assets/img/Material/HyruleHerb.png
deleted file mode 100644
index bcfd018..0000000
Binary files a/legacy/public/assets/img/Material/HyruleHerb.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/IceKeeseWing.png b/legacy/public/assets/img/Material/IceKeeseWing.png
deleted file mode 100644
index de86620..0000000
Binary files a/legacy/public/assets/img/Material/IceKeeseWing.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/IcyLizalfosTail.png b/legacy/public/assets/img/Material/IcyLizalfosTail.png
deleted file mode 100644
index 30e97d2..0000000
Binary files a/legacy/public/assets/img/Material/IcyLizalfosTail.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/IronshellCrab.png b/legacy/public/assets/img/Material/IronshellCrab.png
deleted file mode 100644
index 398983b..0000000
Binary files a/legacy/public/assets/img/Material/IronshellCrab.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Ironshroom.png b/legacy/public/assets/img/Material/Ironshroom.png
deleted file mode 100644
index cc3cec8..0000000
Binary files a/legacy/public/assets/img/Material/Ironshroom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/KeeseEyeball.png b/legacy/public/assets/img/Material/KeeseEyeball.png
deleted file mode 100644
index 1cff751..0000000
Binary files a/legacy/public/assets/img/Material/KeeseEyeball.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/KeeseWing.png b/legacy/public/assets/img/Material/KeeseWing.png
deleted file mode 100644
index 9f031d7..0000000
Binary files a/legacy/public/assets/img/Material/KeeseWing.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/LizalfosHorn.png b/legacy/public/assets/img/Material/LizalfosHorn.png
deleted file mode 100644
index da8dbaf..0000000
Binary files a/legacy/public/assets/img/Material/LizalfosHorn.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/LizalfosTail.png b/legacy/public/assets/img/Material/LizalfosTail.png
deleted file mode 100644
index 0dccf6a..0000000
Binary files a/legacy/public/assets/img/Material/LizalfosTail.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/LizalfosTalon.png b/legacy/public/assets/img/Material/LizalfosTalon.png
deleted file mode 100644
index a6c7f6f..0000000
Binary files a/legacy/public/assets/img/Material/LizalfosTalon.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/LuminousStone.png b/legacy/public/assets/img/Material/LuminousStone.png
deleted file mode 100644
index f173c3d..0000000
Binary files a/legacy/public/assets/img/Material/LuminousStone.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/LynelGuts.png b/legacy/public/assets/img/Material/LynelGuts.png
deleted file mode 100644
index 13f1fb4..0000000
Binary files a/legacy/public/assets/img/Material/LynelGuts.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/LynelHoof.png b/legacy/public/assets/img/Material/LynelHoof.png
deleted file mode 100644
index 0201907..0000000
Binary files a/legacy/public/assets/img/Material/LynelHoof.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/LynelHorn.png b/legacy/public/assets/img/Material/LynelHorn.png
deleted file mode 100644
index bd57d3e..0000000
Binary files a/legacy/public/assets/img/Material/LynelHorn.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/MightyBananas.png b/legacy/public/assets/img/Material/MightyBananas.png
deleted file mode 100644
index ab57ee3..0000000
Binary files a/legacy/public/assets/img/Material/MightyBananas.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/MightyCarp.png b/legacy/public/assets/img/Material/MightyCarp.png
deleted file mode 100644
index a6b07b6..0000000
Binary files a/legacy/public/assets/img/Material/MightyCarp.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/MightyPorgy.png b/legacy/public/assets/img/Material/MightyPorgy.png
deleted file mode 100644
index 08c822e..0000000
Binary files a/legacy/public/assets/img/Material/MightyPorgy.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/MightyThistle.png b/legacy/public/assets/img/Material/MightyThistle.png
deleted file mode 100644
index 3235411..0000000
Binary files a/legacy/public/assets/img/Material/MightyThistle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/MoblinFang.png b/legacy/public/assets/img/Material/MoblinFang.png
deleted file mode 100644
index f9ca78a..0000000
Binary files a/legacy/public/assets/img/Material/MoblinFang.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/MoblinGuts.png b/legacy/public/assets/img/Material/MoblinGuts.png
deleted file mode 100644
index c271f26..0000000
Binary files a/legacy/public/assets/img/Material/MoblinGuts.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/MoblinHorn.png b/legacy/public/assets/img/Material/MoblinHorn.png
deleted file mode 100644
index 0fcb4cc..0000000
Binary files a/legacy/public/assets/img/Material/MoblinHorn.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/MoldugaFin.png b/legacy/public/assets/img/Material/MoldugaFin.png
deleted file mode 100644
index 6b44fb0..0000000
Binary files a/legacy/public/assets/img/Material/MoldugaFin.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/MoldugaGuts.png b/legacy/public/assets/img/Material/MoldugaGuts.png
deleted file mode 100644
index 6685f21..0000000
Binary files a/legacy/public/assets/img/Material/MoldugaGuts.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/MonsterExtract.png b/legacy/public/assets/img/Material/MonsterExtract.png
deleted file mode 100644
index 3625478..0000000
Binary files a/legacy/public/assets/img/Material/MonsterExtract.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/NaydrasClaw.png b/legacy/public/assets/img/Material/NaydrasClaw.png
deleted file mode 100644
index fb9a595..0000000
Binary files a/legacy/public/assets/img/Material/NaydrasClaw.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/NaydrasScale.png b/legacy/public/assets/img/Material/NaydrasScale.png
deleted file mode 100644
index 3f87f52..0000000
Binary files a/legacy/public/assets/img/Material/NaydrasScale.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/OctoBalloon.png b/legacy/public/assets/img/Material/OctoBalloon.png
deleted file mode 100644
index c9c885a..0000000
Binary files a/legacy/public/assets/img/Material/OctoBalloon.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/OctorokEyeball.png b/legacy/public/assets/img/Material/OctorokEyeball.png
deleted file mode 100644
index f7c5ce2..0000000
Binary files a/legacy/public/assets/img/Material/OctorokEyeball.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/OctorokTentacle.png b/legacy/public/assets/img/Material/OctorokTentacle.png
deleted file mode 100644
index d9d3697..0000000
Binary files a/legacy/public/assets/img/Material/OctorokTentacle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Opal.png b/legacy/public/assets/img/Material/Opal.png
deleted file mode 100644
index e0bf890..0000000
Binary files a/legacy/public/assets/img/Material/Opal.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/PalmFruit.png b/legacy/public/assets/img/Material/PalmFruit.png
deleted file mode 100644
index 228f6e9..0000000
Binary files a/legacy/public/assets/img/Material/PalmFruit.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/RawBirdDrumstick.png b/legacy/public/assets/img/Material/RawBirdDrumstick.png
deleted file mode 100644
index c528926..0000000
Binary files a/legacy/public/assets/img/Material/RawBirdDrumstick.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/RawBirdThigh.png b/legacy/public/assets/img/Material/RawBirdThigh.png
deleted file mode 100644
index 920a91f..0000000
Binary files a/legacy/public/assets/img/Material/RawBirdThigh.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/RawGourmetMeat.png b/legacy/public/assets/img/Material/RawGourmetMeat.png
deleted file mode 100644
index 3e86e1d..0000000
Binary files a/legacy/public/assets/img/Material/RawGourmetMeat.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/RawMeat.png b/legacy/public/assets/img/Material/RawMeat.png
deleted file mode 100644
index d547266..0000000
Binary files a/legacy/public/assets/img/Material/RawMeat.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/RawPrimeMeat.png b/legacy/public/assets/img/Material/RawPrimeMeat.png
deleted file mode 100644
index a9f8fbf..0000000
Binary files a/legacy/public/assets/img/Material/RawPrimeMeat.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/RawWholeBird.png b/legacy/public/assets/img/Material/RawWholeBird.png
deleted file mode 100644
index b1ada3f..0000000
Binary files a/legacy/public/assets/img/Material/RawWholeBird.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/RazorclawCrab.png b/legacy/public/assets/img/Material/RazorclawCrab.png
deleted file mode 100644
index a7c757d..0000000
Binary files a/legacy/public/assets/img/Material/RazorclawCrab.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Razorshroom.png b/legacy/public/assets/img/Material/Razorshroom.png
deleted file mode 100644
index bdf9d4a..0000000
Binary files a/legacy/public/assets/img/Material/Razorshroom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/RedChuchuJelly.png b/legacy/public/assets/img/Material/RedChuchuJelly.png
deleted file mode 100644
index e03d676..0000000
Binary files a/legacy/public/assets/img/Material/RedChuchuJelly.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/RedLizalfosTail.png b/legacy/public/assets/img/Material/RedLizalfosTail.png
deleted file mode 100644
index 3299018..0000000
Binary files a/legacy/public/assets/img/Material/RedLizalfosTail.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/RestlessCricket.png b/legacy/public/assets/img/Material/RestlessCricket.png
deleted file mode 100644
index b856998..0000000
Binary files a/legacy/public/assets/img/Material/RestlessCricket.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/RockSalt.png b/legacy/public/assets/img/Material/RockSalt.png
deleted file mode 100644
index f357f00..0000000
Binary files a/legacy/public/assets/img/Material/RockSalt.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Ruby.png b/legacy/public/assets/img/Material/Ruby.png
deleted file mode 100644
index 9f47d17..0000000
Binary files a/legacy/public/assets/img/Material/Ruby.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/RuggedRhinoBeetle.png b/legacy/public/assets/img/Material/RuggedRhinoBeetle.png
deleted file mode 100644
index 2c7d600..0000000
Binary files a/legacy/public/assets/img/Material/RuggedRhinoBeetle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Rushroom.png b/legacy/public/assets/img/Material/Rushroom.png
deleted file mode 100644
index a73e6fa..0000000
Binary files a/legacy/public/assets/img/Material/Rushroom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/SankeCarp.png b/legacy/public/assets/img/Material/SankeCarp.png
deleted file mode 100644
index 7d2fe86..0000000
Binary files a/legacy/public/assets/img/Material/SankeCarp.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Sapphire.png b/legacy/public/assets/img/Material/Sapphire.png
deleted file mode 100644
index cbba302..0000000
Binary files a/legacy/public/assets/img/Material/Sapphire.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/ShardOfDinraalsFang.png b/legacy/public/assets/img/Material/ShardOfDinraalsFang.png
deleted file mode 100644
index a4baf5d..0000000
Binary files a/legacy/public/assets/img/Material/ShardOfDinraalsFang.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/ShardOfDinraalsHorn.png b/legacy/public/assets/img/Material/ShardOfDinraalsHorn.png
deleted file mode 100644
index c4dadac..0000000
Binary files a/legacy/public/assets/img/Material/ShardOfDinraalsHorn.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/ShardOfFaroshsFang.png b/legacy/public/assets/img/Material/ShardOfFaroshsFang.png
deleted file mode 100644
index 2e341f5..0000000
Binary files a/legacy/public/assets/img/Material/ShardOfFaroshsFang.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/ShardOfFaroshsHorn.png b/legacy/public/assets/img/Material/ShardOfFaroshsHorn.png
deleted file mode 100644
index cb8ce9a..0000000
Binary files a/legacy/public/assets/img/Material/ShardOfFaroshsHorn.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/ShardOfNaydrasFang.png b/legacy/public/assets/img/Material/ShardOfNaydrasFang.png
deleted file mode 100644
index 082b6ea..0000000
Binary files a/legacy/public/assets/img/Material/ShardOfNaydrasFang.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/ShardOfNaydrasHorn.png b/legacy/public/assets/img/Material/ShardOfNaydrasHorn.png
deleted file mode 100644
index 59e61c3..0000000
Binary files a/legacy/public/assets/img/Material/ShardOfNaydrasHorn.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/SilentPrincess.png b/legacy/public/assets/img/Material/SilentPrincess.png
deleted file mode 100644
index 61ae3f8..0000000
Binary files a/legacy/public/assets/img/Material/SilentPrincess.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/SilentShroom.png b/legacy/public/assets/img/Material/SilentShroom.png
deleted file mode 100644
index 2bb7cc3..0000000
Binary files a/legacy/public/assets/img/Material/SilentShroom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/SizzlefinTrout.png b/legacy/public/assets/img/Material/SizzlefinTrout.png
deleted file mode 100644
index 949654f..0000000
Binary files a/legacy/public/assets/img/Material/SizzlefinTrout.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/SmotherwingButterfly.png b/legacy/public/assets/img/Material/SmotherwingButterfly.png
deleted file mode 100644
index d22b45f..0000000
Binary files a/legacy/public/assets/img/Material/SmotherwingButterfly.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/SneakyRiverSnail.png b/legacy/public/assets/img/Material/SneakyRiverSnail.png
deleted file mode 100644
index fde9200..0000000
Binary files a/legacy/public/assets/img/Material/SneakyRiverSnail.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/SpicyPepper.png b/legacy/public/assets/img/Material/SpicyPepper.png
deleted file mode 100644
index e8b5d41..0000000
Binary files a/legacy/public/assets/img/Material/SpicyPepper.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/StamellaShroom.png b/legacy/public/assets/img/Material/StamellaShroom.png
deleted file mode 100644
index a0d9811..0000000
Binary files a/legacy/public/assets/img/Material/StamellaShroom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/StaminokaBass.png b/legacy/public/assets/img/Material/StaminokaBass.png
deleted file mode 100644
index ad97a38..0000000
Binary files a/legacy/public/assets/img/Material/StaminokaBass.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/StarFragment.png b/legacy/public/assets/img/Material/StarFragment.png
deleted file mode 100644
index be4ec7c..0000000
Binary files a/legacy/public/assets/img/Material/StarFragment.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/StealthfinTrout.png b/legacy/public/assets/img/Material/StealthfinTrout.png
deleted file mode 100644
index c09cd05..0000000
Binary files a/legacy/public/assets/img/Material/StealthfinTrout.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/SummerwingButterfly.png b/legacy/public/assets/img/Material/SummerwingButterfly.png
deleted file mode 100644
index 7885d60..0000000
Binary files a/legacy/public/assets/img/Material/SummerwingButterfly.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/SunsetFirefly.png b/legacy/public/assets/img/Material/SunsetFirefly.png
deleted file mode 100644
index 705cd39..0000000
Binary files a/legacy/public/assets/img/Material/SunsetFirefly.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Sunshroom.png b/legacy/public/assets/img/Material/Sunshroom.png
deleted file mode 100644
index 282a456..0000000
Binary files a/legacy/public/assets/img/Material/Sunshroom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/SwiftCarrot.png b/legacy/public/assets/img/Material/SwiftCarrot.png
deleted file mode 100644
index 65b6f10..0000000
Binary files a/legacy/public/assets/img/Material/SwiftCarrot.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/SwiftViolet.png b/legacy/public/assets/img/Material/SwiftViolet.png
deleted file mode 100644
index ec8a297..0000000
Binary files a/legacy/public/assets/img/Material/SwiftViolet.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/TabanthaWheat.png b/legacy/public/assets/img/Material/TabanthaWheat.png
deleted file mode 100644
index 8e57359..0000000
Binary files a/legacy/public/assets/img/Material/TabanthaWheat.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/ThunderwingButterfly.png b/legacy/public/assets/img/Material/ThunderwingButterfly.png
deleted file mode 100644
index 8121300..0000000
Binary files a/legacy/public/assets/img/Material/ThunderwingButterfly.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/TirelessFrog.png b/legacy/public/assets/img/Material/TirelessFrog.png
deleted file mode 100644
index 6409c12..0000000
Binary files a/legacy/public/assets/img/Material/TirelessFrog.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Topaz.png b/legacy/public/assets/img/Material/Topaz.png
deleted file mode 100644
index 2ba8472..0000000
Binary files a/legacy/public/assets/img/Material/Topaz.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/VoltfinTrout.png b/legacy/public/assets/img/Material/VoltfinTrout.png
deleted file mode 100644
index f30ccf2..0000000
Binary files a/legacy/public/assets/img/Material/VoltfinTrout.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Voltfruit.png b/legacy/public/assets/img/Material/Voltfruit.png
deleted file mode 100644
index e824ce6..0000000
Binary files a/legacy/public/assets/img/Material/Voltfruit.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/WarmDarner.png b/legacy/public/assets/img/Material/WarmDarner.png
deleted file mode 100644
index 2588263..0000000
Binary files a/legacy/public/assets/img/Material/WarmDarner.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/WarmSafflina.png b/legacy/public/assets/img/Material/WarmSafflina.png
deleted file mode 100644
index 77722db..0000000
Binary files a/legacy/public/assets/img/Material/WarmSafflina.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/WhiteChuchuJelly.png b/legacy/public/assets/img/Material/WhiteChuchuJelly.png
deleted file mode 100644
index 41e1c04..0000000
Binary files a/legacy/public/assets/img/Material/WhiteChuchuJelly.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Wildberry.png b/legacy/public/assets/img/Material/Wildberry.png
deleted file mode 100644
index 2d20ec1..0000000
Binary files a/legacy/public/assets/img/Material/Wildberry.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/WinterwingButterfly.png b/legacy/public/assets/img/Material/WinterwingButterfly.png
deleted file mode 100644
index ac08f92..0000000
Binary files a/legacy/public/assets/img/Material/WinterwingButterfly.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Wood.png b/legacy/public/assets/img/Material/Wood.png
deleted file mode 100644
index b520c1e..0000000
Binary files a/legacy/public/assets/img/Material/Wood.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/YellowChuchuJelly.png b/legacy/public/assets/img/Material/YellowChuchuJelly.png
deleted file mode 100644
index 0e56afd..0000000
Binary files a/legacy/public/assets/img/Material/YellowChuchuJelly.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/YellowLizalfosTail.png b/legacy/public/assets/img/Material/YellowLizalfosTail.png
deleted file mode 100644
index 9582213..0000000
Binary files a/legacy/public/assets/img/Material/YellowLizalfosTail.png and /dev/null differ
diff --git a/legacy/public/assets/img/Material/Zapshroom.png b/legacy/public/assets/img/Material/Zapshroom.png
deleted file mode 100644
index bbaad3a..0000000
Binary files a/legacy/public/assets/img/Material/Zapshroom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/BowAttackUp.png b/legacy/public/assets/img/Modifiers/BowAttackUp.png
deleted file mode 100644
index fba59a1..0000000
Binary files a/legacy/public/assets/img/Modifiers/BowAttackUp.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/BowAttackUpYellow.png b/legacy/public/assets/img/Modifiers/BowAttackUpYellow.png
deleted file mode 100644
index 0236b11..0000000
Binary files a/legacy/public/assets/img/Modifiers/BowAttackUpYellow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/CookChilly.png b/legacy/public/assets/img/Modifiers/CookChilly.png
deleted file mode 100644
index d513cb1..0000000
Binary files a/legacy/public/assets/img/Modifiers/CookChilly.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/CookElectro.png b/legacy/public/assets/img/Modifiers/CookElectro.png
deleted file mode 100644
index adbe8f8..0000000
Binary files a/legacy/public/assets/img/Modifiers/CookElectro.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/CookEnduring.png b/legacy/public/assets/img/Modifiers/CookEnduring.png
deleted file mode 100644
index eb7f522..0000000
Binary files a/legacy/public/assets/img/Modifiers/CookEnduring.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/CookEnergizing.png b/legacy/public/assets/img/Modifiers/CookEnergizing.png
deleted file mode 100644
index 0d0b336..0000000
Binary files a/legacy/public/assets/img/Modifiers/CookEnergizing.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/CookFireproof.png b/legacy/public/assets/img/Modifiers/CookFireproof.png
deleted file mode 100644
index 3e92a3f..0000000
Binary files a/legacy/public/assets/img/Modifiers/CookFireproof.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/CookHasty.png b/legacy/public/assets/img/Modifiers/CookHasty.png
deleted file mode 100644
index 8638ea4..0000000
Binary files a/legacy/public/assets/img/Modifiers/CookHasty.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/CookHearty.png b/legacy/public/assets/img/Modifiers/CookHearty.png
deleted file mode 100644
index e9187b0..0000000
Binary files a/legacy/public/assets/img/Modifiers/CookHearty.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/CookMighty.png b/legacy/public/assets/img/Modifiers/CookMighty.png
deleted file mode 100644
index 885db62..0000000
Binary files a/legacy/public/assets/img/Modifiers/CookMighty.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/CookSneaky.png b/legacy/public/assets/img/Modifiers/CookSneaky.png
deleted file mode 100644
index 073f63c..0000000
Binary files a/legacy/public/assets/img/Modifiers/CookSneaky.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/CookSpicy.png b/legacy/public/assets/img/Modifiers/CookSpicy.png
deleted file mode 100644
index 582d735..0000000
Binary files a/legacy/public/assets/img/Modifiers/CookSpicy.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/CookTough.png b/legacy/public/assets/img/Modifiers/CookTough.png
deleted file mode 100644
index e402a63..0000000
Binary files a/legacy/public/assets/img/Modifiers/CookTough.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/CriticalHit.png b/legacy/public/assets/img/Modifiers/CriticalHit.png
deleted file mode 100644
index 22d1be7..0000000
Binary files a/legacy/public/assets/img/Modifiers/CriticalHit.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/CriticalHitYellow.png b/legacy/public/assets/img/Modifiers/CriticalHitYellow.png
deleted file mode 100644
index c153f8d..0000000
Binary files a/legacy/public/assets/img/Modifiers/CriticalHitYellow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/DurabilityUp.png b/legacy/public/assets/img/Modifiers/DurabilityUp.png
deleted file mode 100644
index 231cedb..0000000
Binary files a/legacy/public/assets/img/Modifiers/DurabilityUp.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/DurabilityUpYellow.png b/legacy/public/assets/img/Modifiers/DurabilityUpYellow.png
deleted file mode 100644
index 8e2d869..0000000
Binary files a/legacy/public/assets/img/Modifiers/DurabilityUpYellow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/GuardUp.png b/legacy/public/assets/img/Modifiers/GuardUp.png
deleted file mode 100644
index b588f96..0000000
Binary files a/legacy/public/assets/img/Modifiers/GuardUp.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/GuardUpYellow.png b/legacy/public/assets/img/Modifiers/GuardUpYellow.png
deleted file mode 100644
index 2234e28..0000000
Binary files a/legacy/public/assets/img/Modifiers/GuardUpYellow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/LongThrow.png b/legacy/public/assets/img/Modifiers/LongThrow.png
deleted file mode 100644
index 1f70382..0000000
Binary files a/legacy/public/assets/img/Modifiers/LongThrow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/LongThrowYellow.png b/legacy/public/assets/img/Modifiers/LongThrowYellow.png
deleted file mode 100644
index c0c3b50..0000000
Binary files a/legacy/public/assets/img/Modifiers/LongThrowYellow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/Multishot3.png b/legacy/public/assets/img/Modifiers/Multishot3.png
deleted file mode 100644
index fe25956..0000000
Binary files a/legacy/public/assets/img/Modifiers/Multishot3.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/Multishot5.png b/legacy/public/assets/img/Modifiers/Multishot5.png
deleted file mode 100644
index ecc2631..0000000
Binary files a/legacy/public/assets/img/Modifiers/Multishot5.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/MultishotX.png b/legacy/public/assets/img/Modifiers/MultishotX.png
deleted file mode 100644
index 86308c9..0000000
Binary files a/legacy/public/assets/img/Modifiers/MultishotX.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/QuickShot.png b/legacy/public/assets/img/Modifiers/QuickShot.png
deleted file mode 100644
index 35474a9..0000000
Binary files a/legacy/public/assets/img/Modifiers/QuickShot.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/QuickShotYellow.png b/legacy/public/assets/img/Modifiers/QuickShotYellow.png
deleted file mode 100644
index 83b6599..0000000
Binary files a/legacy/public/assets/img/Modifiers/QuickShotYellow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/SurfMaster.png b/legacy/public/assets/img/Modifiers/SurfMaster.png
deleted file mode 100644
index 2e46f06..0000000
Binary files a/legacy/public/assets/img/Modifiers/SurfMaster.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/SurfMasterYellow.png b/legacy/public/assets/img/Modifiers/SurfMasterYellow.png
deleted file mode 100644
index 98501d4..0000000
Binary files a/legacy/public/assets/img/Modifiers/SurfMasterYellow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/WeaponAttackUp.png b/legacy/public/assets/img/Modifiers/WeaponAttackUp.png
deleted file mode 100644
index 885db62..0000000
Binary files a/legacy/public/assets/img/Modifiers/WeaponAttackUp.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/WeaponAttackUpYellow.png b/legacy/public/assets/img/Modifiers/WeaponAttackUpYellow.png
deleted file mode 100644
index bf2815c..0000000
Binary files a/legacy/public/assets/img/Modifiers/WeaponAttackUpYellow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/Zoom.png b/legacy/public/assets/img/Modifiers/Zoom.png
deleted file mode 100644
index a6fab98..0000000
Binary files a/legacy/public/assets/img/Modifiers/Zoom.png and /dev/null differ
diff --git a/legacy/public/assets/img/Modifiers/ZoomYellow.png b/legacy/public/assets/img/Modifiers/ZoomYellow.png
deleted file mode 100644
index 4eafe1d..0000000
Binary files a/legacy/public/assets/img/Modifiers/ZoomYellow.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/AncientShield.png b/legacy/public/assets/img/Shield/AncientShield.png
deleted file mode 100644
index f20c2e6..0000000
Binary files a/legacy/public/assets/img/Shield/AncientShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/BokoShield.png b/legacy/public/assets/img/Shield/BokoShield.png
deleted file mode 100644
index 61bf94e..0000000
Binary files a/legacy/public/assets/img/Shield/BokoShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/Daybreaker.png b/legacy/public/assets/img/Shield/Daybreaker.png
deleted file mode 100644
index 15a1224..0000000
Binary files a/legacy/public/assets/img/Shield/Daybreaker.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/DragonboneBokoShield.png b/legacy/public/assets/img/Shield/DragonboneBokoShield.png
deleted file mode 100644
index 5f5d4cc..0000000
Binary files a/legacy/public/assets/img/Shield/DragonboneBokoShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/EmblazonedShield.png b/legacy/public/assets/img/Shield/EmblazonedShield.png
deleted file mode 100644
index 8bf1013..0000000
Binary files a/legacy/public/assets/img/Shield/EmblazonedShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/FishermansShield.png b/legacy/public/assets/img/Shield/FishermansShield.png
deleted file mode 100644
index 437e8eb..0000000
Binary files a/legacy/public/assets/img/Shield/FishermansShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/ForestDwellersShield.png b/legacy/public/assets/img/Shield/ForestDwellersShield.png
deleted file mode 100644
index fbe1605..0000000
Binary files a/legacy/public/assets/img/Shield/ForestDwellersShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/GerudoShield.png b/legacy/public/assets/img/Shield/GerudoShield.png
deleted file mode 100644
index 18f9258..0000000
Binary files a/legacy/public/assets/img/Shield/GerudoShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/GuardianShield.png b/legacy/public/assets/img/Shield/GuardianShield.png
deleted file mode 100644
index b9c7eb2..0000000
Binary files a/legacy/public/assets/img/Shield/GuardianShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/GuardianShieldPlus.png b/legacy/public/assets/img/Shield/GuardianShieldPlus.png
deleted file mode 100644
index 6f24b7b..0000000
Binary files a/legacy/public/assets/img/Shield/GuardianShieldPlus.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/GuardianShieldPlusPlus.png b/legacy/public/assets/img/Shield/GuardianShieldPlusPlus.png
deleted file mode 100644
index f1aeb2c..0000000
Binary files a/legacy/public/assets/img/Shield/GuardianShieldPlusPlus.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/HerosShield.png b/legacy/public/assets/img/Shield/HerosShield.png
deleted file mode 100644
index a96c559..0000000
Binary files a/legacy/public/assets/img/Shield/HerosShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/HuntersShield.png b/legacy/public/assets/img/Shield/HuntersShield.png
deleted file mode 100644
index 0c9e153..0000000
Binary files a/legacy/public/assets/img/Shield/HuntersShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/HylianShield.png b/legacy/public/assets/img/Shield/HylianShield.png
deleted file mode 100644
index 854ddcc..0000000
Binary files a/legacy/public/assets/img/Shield/HylianShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/KiteShield.png b/legacy/public/assets/img/Shield/KiteShield.png
deleted file mode 100644
index df2017e..0000000
Binary files a/legacy/public/assets/img/Shield/KiteShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/KnightsShield.png b/legacy/public/assets/img/Shield/KnightsShield.png
deleted file mode 100644
index 5f6b6da..0000000
Binary files a/legacy/public/assets/img/Shield/KnightsShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/LizalShield.png b/legacy/public/assets/img/Shield/LizalShield.png
deleted file mode 100644
index 8054384..0000000
Binary files a/legacy/public/assets/img/Shield/LizalShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/LynelShield.png b/legacy/public/assets/img/Shield/LynelShield.png
deleted file mode 100644
index 2aa0f3f..0000000
Binary files a/legacy/public/assets/img/Shield/LynelShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/MightyLynelShield.png b/legacy/public/assets/img/Shield/MightyLynelShield.png
deleted file mode 100644
index 2f9ffb0..0000000
Binary files a/legacy/public/assets/img/Shield/MightyLynelShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/PotLid.png b/legacy/public/assets/img/Shield/PotLid.png
deleted file mode 100644
index 7522bfa..0000000
Binary files a/legacy/public/assets/img/Shield/PotLid.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/RadiantShield.png b/legacy/public/assets/img/Shield/RadiantShield.png
deleted file mode 100644
index 68af939..0000000
Binary files a/legacy/public/assets/img/Shield/RadiantShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/ReinforcedLizalShield.png b/legacy/public/assets/img/Shield/ReinforcedLizalShield.png
deleted file mode 100644
index 9b7af5c..0000000
Binary files a/legacy/public/assets/img/Shield/ReinforcedLizalShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/RoyalGuardsShield.png b/legacy/public/assets/img/Shield/RoyalGuardsShield.png
deleted file mode 100644
index 7510f1d..0000000
Binary files a/legacy/public/assets/img/Shield/RoyalGuardsShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/RoyalShield.png b/legacy/public/assets/img/Shield/RoyalShield.png
deleted file mode 100644
index 963db4d..0000000
Binary files a/legacy/public/assets/img/Shield/RoyalShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/RustyShield.png b/legacy/public/assets/img/Shield/RustyShield.png
deleted file mode 100644
index d7e841a..0000000
Binary files a/legacy/public/assets/img/Shield/RustyShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/SavageLynelShield.png b/legacy/public/assets/img/Shield/SavageLynelShield.png
deleted file mode 100644
index 69c562a..0000000
Binary files a/legacy/public/assets/img/Shield/SavageLynelShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/Shield.png b/legacy/public/assets/img/Shield/Shield.png
deleted file mode 100644
index 59bcc7a..0000000
Binary files a/legacy/public/assets/img/Shield/Shield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/ShieldOfTheMindsEye.png b/legacy/public/assets/img/Shield/ShieldOfTheMindsEye.png
deleted file mode 100644
index 066ce68..0000000
Binary files a/legacy/public/assets/img/Shield/ShieldOfTheMindsEye.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/SilverShield.png b/legacy/public/assets/img/Shield/SilverShield.png
deleted file mode 100644
index a1d8e16..0000000
Binary files a/legacy/public/assets/img/Shield/SilverShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/SoldiersShield.png b/legacy/public/assets/img/Shield/SoldiersShield.png
deleted file mode 100644
index 6c35f33..0000000
Binary files a/legacy/public/assets/img/Shield/SoldiersShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/SpikedBokoShield.png b/legacy/public/assets/img/Shield/SpikedBokoShield.png
deleted file mode 100644
index 128dcca..0000000
Binary files a/legacy/public/assets/img/Shield/SpikedBokoShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/SteelLizalShield.png b/legacy/public/assets/img/Shield/SteelLizalShield.png
deleted file mode 100644
index 39fb36c..0000000
Binary files a/legacy/public/assets/img/Shield/SteelLizalShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/TravelersShield.png b/legacy/public/assets/img/Shield/TravelersShield.png
deleted file mode 100644
index 93ad6cd..0000000
Binary files a/legacy/public/assets/img/Shield/TravelersShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Shield/WoodenShield.png b/legacy/public/assets/img/Shield/WoodenShield.png
deleted file mode 100644
index 593131e..0000000
Binary files a/legacy/public/assets/img/Shield/WoodenShield.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/AncientBattleAxe.png b/legacy/public/assets/img/Weapon/AncientBattleAxe.png
deleted file mode 100644
index f9cf27f..0000000
Binary files a/legacy/public/assets/img/Weapon/AncientBattleAxe.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/AncientBattleAxePlus.png b/legacy/public/assets/img/Weapon/AncientBattleAxePlus.png
deleted file mode 100644
index f8cb3f6..0000000
Binary files a/legacy/public/assets/img/Weapon/AncientBattleAxePlus.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/AncientBattleAxePlusPlus.png b/legacy/public/assets/img/Weapon/AncientBattleAxePlusPlus.png
deleted file mode 100644
index 6dc89b2..0000000
Binary files a/legacy/public/assets/img/Weapon/AncientBattleAxePlusPlus.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/AncientBladesaw.png b/legacy/public/assets/img/Weapon/AncientBladesaw.png
deleted file mode 100644
index e1362f9..0000000
Binary files a/legacy/public/assets/img/Weapon/AncientBladesaw.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/AncientShortSword.png b/legacy/public/assets/img/Weapon/AncientShortSword.png
deleted file mode 100644
index c7b8b75..0000000
Binary files a/legacy/public/assets/img/Weapon/AncientShortSword.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/AncientSpear.png b/legacy/public/assets/img/Weapon/AncientSpear.png
deleted file mode 100644
index 2c979e6..0000000
Binary files a/legacy/public/assets/img/Weapon/AncientSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/BiggoronsSword.png b/legacy/public/assets/img/Weapon/BiggoronsSword.png
deleted file mode 100644
index 566bb91..0000000
Binary files a/legacy/public/assets/img/Weapon/BiggoronsSword.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/BlizzardRod.png b/legacy/public/assets/img/Weapon/BlizzardRod.png
deleted file mode 100644
index e09d056..0000000
Binary files a/legacy/public/assets/img/Weapon/BlizzardRod.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/BoatOar.png b/legacy/public/assets/img/Weapon/BoatOar.png
deleted file mode 100644
index e190184..0000000
Binary files a/legacy/public/assets/img/Weapon/BoatOar.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/BokoBat.png b/legacy/public/assets/img/Weapon/BokoBat.png
deleted file mode 100644
index 8f56045..0000000
Binary files a/legacy/public/assets/img/Weapon/BokoBat.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/BokoClub.png b/legacy/public/assets/img/Weapon/BokoClub.png
deleted file mode 100644
index 94ec8fc..0000000
Binary files a/legacy/public/assets/img/Weapon/BokoClub.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/BokoSpear.png b/legacy/public/assets/img/Weapon/BokoSpear.png
deleted file mode 100644
index e88c308..0000000
Binary files a/legacy/public/assets/img/Weapon/BokoSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/BokoblinArm.png b/legacy/public/assets/img/Weapon/BokoblinArm.png
deleted file mode 100644
index db5c541..0000000
Binary files a/legacy/public/assets/img/Weapon/BokoblinArm.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/Boomerang.png b/legacy/public/assets/img/Weapon/Boomerang.png
deleted file mode 100644
index 2b832ce..0000000
Binary files a/legacy/public/assets/img/Weapon/Boomerang.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/BoulderBreaker.png b/legacy/public/assets/img/Weapon/BoulderBreaker.png
deleted file mode 100644
index 77dd5c5..0000000
Binary files a/legacy/public/assets/img/Weapon/BoulderBreaker.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/CeremonialTrident.png b/legacy/public/assets/img/Weapon/CeremonialTrident.png
deleted file mode 100644
index c45f117..0000000
Binary files a/legacy/public/assets/img/Weapon/CeremonialTrident.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/CobbleCrusher.png b/legacy/public/assets/img/Weapon/CobbleCrusher.png
deleted file mode 100644
index 96d503f..0000000
Binary files a/legacy/public/assets/img/Weapon/CobbleCrusher.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/DemonCarver.png b/legacy/public/assets/img/Weapon/DemonCarver.png
deleted file mode 100644
index a2bbf5d..0000000
Binary files a/legacy/public/assets/img/Weapon/DemonCarver.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/DoubleAxe.png b/legacy/public/assets/img/Weapon/DoubleAxe.png
deleted file mode 100644
index adcff56..0000000
Binary files a/legacy/public/assets/img/Weapon/DoubleAxe.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/DragonboneBokoBat.png b/legacy/public/assets/img/Weapon/DragonboneBokoBat.png
deleted file mode 100644
index 6194572..0000000
Binary files a/legacy/public/assets/img/Weapon/DragonboneBokoBat.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/DragonboneBokoClub.png b/legacy/public/assets/img/Weapon/DragonboneBokoClub.png
deleted file mode 100644
index e568ec2..0000000
Binary files a/legacy/public/assets/img/Weapon/DragonboneBokoClub.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/DragonboneBokoSpear.png b/legacy/public/assets/img/Weapon/DragonboneBokoSpear.png
deleted file mode 100644
index abcd2c4..0000000
Binary files a/legacy/public/assets/img/Weapon/DragonboneBokoSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/DragonboneMoblinClub.png b/legacy/public/assets/img/Weapon/DragonboneMoblinClub.png
deleted file mode 100644
index 5f7d41c..0000000
Binary files a/legacy/public/assets/img/Weapon/DragonboneMoblinClub.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/DragonboneMoblinSpear.png b/legacy/public/assets/img/Weapon/DragonboneMoblinSpear.png
deleted file mode 100644
index 9be608f..0000000
Binary files a/legacy/public/assets/img/Weapon/DragonboneMoblinSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/Drillshaft.png b/legacy/public/assets/img/Weapon/Drillshaft.png
deleted file mode 100644
index 453ce59..0000000
Binary files a/legacy/public/assets/img/Weapon/Drillshaft.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/EdgeOfDuality.png b/legacy/public/assets/img/Weapon/EdgeOfDuality.png
deleted file mode 100644
index fadf85f..0000000
Binary files a/legacy/public/assets/img/Weapon/EdgeOfDuality.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/EightfoldBlade.png b/legacy/public/assets/img/Weapon/EightfoldBlade.png
deleted file mode 100644
index 9a26531..0000000
Binary files a/legacy/public/assets/img/Weapon/EightfoldBlade.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/EightfoldLongblade.png b/legacy/public/assets/img/Weapon/EightfoldLongblade.png
deleted file mode 100644
index 1477db3..0000000
Binary files a/legacy/public/assets/img/Weapon/EightfoldLongblade.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/EnhancedLizalSpear.png b/legacy/public/assets/img/Weapon/EnhancedLizalSpear.png
deleted file mode 100644
index ff0cad8..0000000
Binary files a/legacy/public/assets/img/Weapon/EnhancedLizalSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/FarmersPitchfork.png b/legacy/public/assets/img/Weapon/FarmersPitchfork.png
deleted file mode 100644
index 796fe11..0000000
Binary files a/legacy/public/assets/img/Weapon/FarmersPitchfork.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/FarmingHoe.png b/legacy/public/assets/img/Weapon/FarmingHoe.png
deleted file mode 100644
index a61eb10..0000000
Binary files a/legacy/public/assets/img/Weapon/FarmingHoe.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/FeatheredEdge.png b/legacy/public/assets/img/Weapon/FeatheredEdge.png
deleted file mode 100644
index 03c05c4..0000000
Binary files a/legacy/public/assets/img/Weapon/FeatheredEdge.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/FeatheredSpear.png b/legacy/public/assets/img/Weapon/FeatheredSpear.png
deleted file mode 100644
index 9674d04..0000000
Binary files a/legacy/public/assets/img/Weapon/FeatheredSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/FierceDeitySword.png b/legacy/public/assets/img/Weapon/FierceDeitySword.png
deleted file mode 100644
index b7af721..0000000
Binary files a/legacy/public/assets/img/Weapon/FierceDeitySword.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/FireRod.png b/legacy/public/assets/img/Weapon/FireRod.png
deleted file mode 100644
index 603fe21..0000000
Binary files a/legacy/public/assets/img/Weapon/FireRod.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/FishingHarpoon.png b/legacy/public/assets/img/Weapon/FishingHarpoon.png
deleted file mode 100644
index 318a80e..0000000
Binary files a/legacy/public/assets/img/Weapon/FishingHarpoon.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/Flameblade.png b/legacy/public/assets/img/Weapon/Flameblade.png
deleted file mode 100644
index 00f2d8a..0000000
Binary files a/legacy/public/assets/img/Weapon/Flameblade.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/Flamespear.png b/legacy/public/assets/img/Weapon/Flamespear.png
deleted file mode 100644
index 494cd70..0000000
Binary files a/legacy/public/assets/img/Weapon/Flamespear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/ForestDwellersSpear.png b/legacy/public/assets/img/Weapon/ForestDwellersSpear.png
deleted file mode 100644
index e4d465f..0000000
Binary files a/legacy/public/assets/img/Weapon/ForestDwellersSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/ForestDwellersSword.png b/legacy/public/assets/img/Weapon/ForestDwellersSword.png
deleted file mode 100644
index 1eea0a0..0000000
Binary files a/legacy/public/assets/img/Weapon/ForestDwellersSword.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/ForkedLizalSpear.png b/legacy/public/assets/img/Weapon/ForkedLizalSpear.png
deleted file mode 100644
index ba529e5..0000000
Binary files a/legacy/public/assets/img/Weapon/ForkedLizalSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/Frostblade.png b/legacy/public/assets/img/Weapon/Frostblade.png
deleted file mode 100644
index 2732bc2..0000000
Binary files a/legacy/public/assets/img/Weapon/Frostblade.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/Frostspear.png b/legacy/public/assets/img/Weapon/Frostspear.png
deleted file mode 100644
index ad06c40..0000000
Binary files a/legacy/public/assets/img/Weapon/Frostspear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/GerudoScimitar.png b/legacy/public/assets/img/Weapon/GerudoScimitar.png
deleted file mode 100644
index 1ef706b..0000000
Binary files a/legacy/public/assets/img/Weapon/GerudoScimitar.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/GerudoSpear.png b/legacy/public/assets/img/Weapon/GerudoSpear.png
deleted file mode 100644
index e51eefb..0000000
Binary files a/legacy/public/assets/img/Weapon/GerudoSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/GiantBoomerang.png b/legacy/public/assets/img/Weapon/GiantBoomerang.png
deleted file mode 100644
index f71258e..0000000
Binary files a/legacy/public/assets/img/Weapon/GiantBoomerang.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/GoddessSword.png b/legacy/public/assets/img/Weapon/GoddessSword.png
deleted file mode 100644
index a25590c..0000000
Binary files a/legacy/public/assets/img/Weapon/GoddessSword.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/GoldenClaymore.png b/legacy/public/assets/img/Weapon/GoldenClaymore.png
deleted file mode 100644
index 37caf0f..0000000
Binary files a/legacy/public/assets/img/Weapon/GoldenClaymore.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/GreatFlameblade.png b/legacy/public/assets/img/Weapon/GreatFlameblade.png
deleted file mode 100644
index 5546780..0000000
Binary files a/legacy/public/assets/img/Weapon/GreatFlameblade.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/GreatFrostblade.png b/legacy/public/assets/img/Weapon/GreatFrostblade.png
deleted file mode 100644
index d4c4f7a..0000000
Binary files a/legacy/public/assets/img/Weapon/GreatFrostblade.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/GreatThunderblade.png b/legacy/public/assets/img/Weapon/GreatThunderblade.png
deleted file mode 100644
index 31015c0..0000000
Binary files a/legacy/public/assets/img/Weapon/GreatThunderblade.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/GuardianSpear.png b/legacy/public/assets/img/Weapon/GuardianSpear.png
deleted file mode 100644
index 333ef82..0000000
Binary files a/legacy/public/assets/img/Weapon/GuardianSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/GuardianSpearPlus.png b/legacy/public/assets/img/Weapon/GuardianSpearPlus.png
deleted file mode 100644
index 710729d..0000000
Binary files a/legacy/public/assets/img/Weapon/GuardianSpearPlus.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/GuardianSpearPlusPlus.png b/legacy/public/assets/img/Weapon/GuardianSpearPlusPlus.png
deleted file mode 100644
index a06f028..0000000
Binary files a/legacy/public/assets/img/Weapon/GuardianSpearPlusPlus.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/GuardianSword.png b/legacy/public/assets/img/Weapon/GuardianSword.png
deleted file mode 100644
index 43b2943..0000000
Binary files a/legacy/public/assets/img/Weapon/GuardianSword.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/GuardianSwordPlus.png b/legacy/public/assets/img/Weapon/GuardianSwordPlus.png
deleted file mode 100644
index 5983f47..0000000
Binary files a/legacy/public/assets/img/Weapon/GuardianSwordPlus.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/GuardianSwordPlusPlus.png b/legacy/public/assets/img/Weapon/GuardianSwordPlusPlus.png
deleted file mode 100644
index 2d389e7..0000000
Binary files a/legacy/public/assets/img/Weapon/GuardianSwordPlusPlus.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/IceRod.png b/legacy/public/assets/img/Weapon/IceRod.png
deleted file mode 100644
index 7cb5ac5..0000000
Binary files a/legacy/public/assets/img/Weapon/IceRod.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/IronSledgehammer.png b/legacy/public/assets/img/Weapon/IronSledgehammer.png
deleted file mode 100644
index 8d82a5d..0000000
Binary files a/legacy/public/assets/img/Weapon/IronSledgehammer.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/KnightsBroadsword.png b/legacy/public/assets/img/Weapon/KnightsBroadsword.png
deleted file mode 100644
index 2ad9021..0000000
Binary files a/legacy/public/assets/img/Weapon/KnightsBroadsword.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/KnightsClaymore.png b/legacy/public/assets/img/Weapon/KnightsClaymore.png
deleted file mode 100644
index ab3f6eb..0000000
Binary files a/legacy/public/assets/img/Weapon/KnightsClaymore.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/KnightsHalberd.png b/legacy/public/assets/img/Weapon/KnightsHalberd.png
deleted file mode 100644
index 36aae0d..0000000
Binary files a/legacy/public/assets/img/Weapon/KnightsHalberd.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/KorokLeaf.png b/legacy/public/assets/img/Weapon/KorokLeaf.png
deleted file mode 100644
index 78d5ac2..0000000
Binary files a/legacy/public/assets/img/Weapon/KorokLeaf.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/LightningRod.png b/legacy/public/assets/img/Weapon/LightningRod.png
deleted file mode 100644
index 25807fb..0000000
Binary files a/legacy/public/assets/img/Weapon/LightningRod.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/LightscaleTrident.png b/legacy/public/assets/img/Weapon/LightscaleTrident.png
deleted file mode 100644
index c45f117..0000000
Binary files a/legacy/public/assets/img/Weapon/LightscaleTrident.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/LizalBoomerang.png b/legacy/public/assets/img/Weapon/LizalBoomerang.png
deleted file mode 100644
index 6d43b4b..0000000
Binary files a/legacy/public/assets/img/Weapon/LizalBoomerang.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/LizalForkedBoomerang.png b/legacy/public/assets/img/Weapon/LizalForkedBoomerang.png
deleted file mode 100644
index 4c493a0..0000000
Binary files a/legacy/public/assets/img/Weapon/LizalForkedBoomerang.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/LizalSpear.png b/legacy/public/assets/img/Weapon/LizalSpear.png
deleted file mode 100644
index c23bc69..0000000
Binary files a/legacy/public/assets/img/Weapon/LizalSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/LizalTriBoomerang.png b/legacy/public/assets/img/Weapon/LizalTriBoomerang.png
deleted file mode 100644
index 7a40880..0000000
Binary files a/legacy/public/assets/img/Weapon/LizalTriBoomerang.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/LizalfosArm.png b/legacy/public/assets/img/Weapon/LizalfosArm.png
deleted file mode 100644
index 00e4a53..0000000
Binary files a/legacy/public/assets/img/Weapon/LizalfosArm.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/LynelCrusher.png b/legacy/public/assets/img/Weapon/LynelCrusher.png
deleted file mode 100644
index 8db1b3d..0000000
Binary files a/legacy/public/assets/img/Weapon/LynelCrusher.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/LynelSpear.png b/legacy/public/assets/img/Weapon/LynelSpear.png
deleted file mode 100644
index 13b4e35..0000000
Binary files a/legacy/public/assets/img/Weapon/LynelSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/LynelSword.png b/legacy/public/assets/img/Weapon/LynelSword.png
deleted file mode 100644
index 8d8c98e..0000000
Binary files a/legacy/public/assets/img/Weapon/LynelSword.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/MasterSword.png b/legacy/public/assets/img/Weapon/MasterSword.png
deleted file mode 100644
index a1eccfb..0000000
Binary files a/legacy/public/assets/img/Weapon/MasterSword.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/MasterSwordAwakened.png b/legacy/public/assets/img/Weapon/MasterSwordAwakened.png
deleted file mode 100644
index 058d492..0000000
Binary files a/legacy/public/assets/img/Weapon/MasterSwordAwakened.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/MeteorRod.png b/legacy/public/assets/img/Weapon/MeteorRod.png
deleted file mode 100644
index 15aa939..0000000
Binary files a/legacy/public/assets/img/Weapon/MeteorRod.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/MightyLynelCrusher.png b/legacy/public/assets/img/Weapon/MightyLynelCrusher.png
deleted file mode 100644
index 16116dd..0000000
Binary files a/legacy/public/assets/img/Weapon/MightyLynelCrusher.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/MightyLynelSpear.png b/legacy/public/assets/img/Weapon/MightyLynelSpear.png
deleted file mode 100644
index 80aeb99..0000000
Binary files a/legacy/public/assets/img/Weapon/MightyLynelSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/MightyLynelSword.png b/legacy/public/assets/img/Weapon/MightyLynelSword.png
deleted file mode 100644
index 1ec726f..0000000
Binary files a/legacy/public/assets/img/Weapon/MightyLynelSword.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/MoblinArm.png b/legacy/public/assets/img/Weapon/MoblinArm.png
deleted file mode 100644
index bd383e2..0000000
Binary files a/legacy/public/assets/img/Weapon/MoblinArm.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/MoblinClub.png b/legacy/public/assets/img/Weapon/MoblinClub.png
deleted file mode 100644
index 67b054f..0000000
Binary files a/legacy/public/assets/img/Weapon/MoblinClub.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/MoblinSpear.png b/legacy/public/assets/img/Weapon/MoblinSpear.png
deleted file mode 100644
index 11f398d..0000000
Binary files a/legacy/public/assets/img/Weapon/MoblinSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/MoonlightScimitar.png b/legacy/public/assets/img/Weapon/MoonlightScimitar.png
deleted file mode 100644
index b24cc0b..0000000
Binary files a/legacy/public/assets/img/Weapon/MoonlightScimitar.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/OneHitObliterator.png b/legacy/public/assets/img/Weapon/OneHitObliterator.png
deleted file mode 100644
index cd59e38..0000000
Binary files a/legacy/public/assets/img/Weapon/OneHitObliterator.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/OneHitObliteratorCharged.png b/legacy/public/assets/img/Weapon/OneHitObliteratorCharged.png
deleted file mode 100644
index 9843e3e..0000000
Binary files a/legacy/public/assets/img/Weapon/OneHitObliteratorCharged.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/RoyalBroadsword.png b/legacy/public/assets/img/Weapon/RoyalBroadsword.png
deleted file mode 100644
index 5d916fa..0000000
Binary files a/legacy/public/assets/img/Weapon/RoyalBroadsword.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/RoyalClaymore.png b/legacy/public/assets/img/Weapon/RoyalClaymore.png
deleted file mode 100644
index ff938be..0000000
Binary files a/legacy/public/assets/img/Weapon/RoyalClaymore.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/RoyalGuardsClaymore.png b/legacy/public/assets/img/Weapon/RoyalGuardsClaymore.png
deleted file mode 100644
index f9ddfb1..0000000
Binary files a/legacy/public/assets/img/Weapon/RoyalGuardsClaymore.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/RoyalGuardsSpear.png b/legacy/public/assets/img/Weapon/RoyalGuardsSpear.png
deleted file mode 100644
index 05d7c7d..0000000
Binary files a/legacy/public/assets/img/Weapon/RoyalGuardsSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/RoyalGuardsSword.png b/legacy/public/assets/img/Weapon/RoyalGuardsSword.png
deleted file mode 100644
index f217714..0000000
Binary files a/legacy/public/assets/img/Weapon/RoyalGuardsSword.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/RoyalHalberd.png b/legacy/public/assets/img/Weapon/RoyalHalberd.png
deleted file mode 100644
index 3dedca5..0000000
Binary files a/legacy/public/assets/img/Weapon/RoyalHalberd.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/RustyBroadsword.png b/legacy/public/assets/img/Weapon/RustyBroadsword.png
deleted file mode 100644
index f1442e3..0000000
Binary files a/legacy/public/assets/img/Weapon/RustyBroadsword.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/RustyClaymore.png b/legacy/public/assets/img/Weapon/RustyClaymore.png
deleted file mode 100644
index 6ac6305..0000000
Binary files a/legacy/public/assets/img/Weapon/RustyClaymore.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/RustyHalberd.png b/legacy/public/assets/img/Weapon/RustyHalberd.png
deleted file mode 100644
index 28f2dc4..0000000
Binary files a/legacy/public/assets/img/Weapon/RustyHalberd.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/SavageLynelCrusher.png b/legacy/public/assets/img/Weapon/SavageLynelCrusher.png
deleted file mode 100644
index 937953f..0000000
Binary files a/legacy/public/assets/img/Weapon/SavageLynelCrusher.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/SavageLynelSpear.png b/legacy/public/assets/img/Weapon/SavageLynelSpear.png
deleted file mode 100644
index eaeff0f..0000000
Binary files a/legacy/public/assets/img/Weapon/SavageLynelSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/SavageLynelSword.png b/legacy/public/assets/img/Weapon/SavageLynelSword.png
deleted file mode 100644
index c748a7c..0000000
Binary files a/legacy/public/assets/img/Weapon/SavageLynelSword.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/ScimitarOfTheSeven.png b/legacy/public/assets/img/Weapon/ScimitarOfTheSeven.png
deleted file mode 100644
index 60c1145..0000000
Binary files a/legacy/public/assets/img/Weapon/ScimitarOfTheSeven.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/SeaBreezeBoomerang.png b/legacy/public/assets/img/Weapon/SeaBreezeBoomerang.png
deleted file mode 100644
index 657f4d9..0000000
Binary files a/legacy/public/assets/img/Weapon/SeaBreezeBoomerang.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/SerpentineSpear.png b/legacy/public/assets/img/Weapon/SerpentineSpear.png
deleted file mode 100644
index 3d38f0c..0000000
Binary files a/legacy/public/assets/img/Weapon/SerpentineSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/SilverLongsword.png b/legacy/public/assets/img/Weapon/SilverLongsword.png
deleted file mode 100644
index 5ec6f5b..0000000
Binary files a/legacy/public/assets/img/Weapon/SilverLongsword.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/SilverscaleSpear.png b/legacy/public/assets/img/Weapon/SilverscaleSpear.png
deleted file mode 100644
index d6da890..0000000
Binary files a/legacy/public/assets/img/Weapon/SilverscaleSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/SoldiersBroadsword.png b/legacy/public/assets/img/Weapon/SoldiersBroadsword.png
deleted file mode 100644
index 4352bb1..0000000
Binary files a/legacy/public/assets/img/Weapon/SoldiersBroadsword.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/SoldiersClaymore.png b/legacy/public/assets/img/Weapon/SoldiersClaymore.png
deleted file mode 100644
index 2313e85..0000000
Binary files a/legacy/public/assets/img/Weapon/SoldiersClaymore.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/SoldiersSpear.png b/legacy/public/assets/img/Weapon/SoldiersSpear.png
deleted file mode 100644
index 299e354..0000000
Binary files a/legacy/public/assets/img/Weapon/SoldiersSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/SoupLadle.png b/legacy/public/assets/img/Weapon/SoupLadle.png
deleted file mode 100644
index 4642dfd..0000000
Binary files a/legacy/public/assets/img/Weapon/SoupLadle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/SpikedBokoBat.png b/legacy/public/assets/img/Weapon/SpikedBokoBat.png
deleted file mode 100644
index d838826..0000000
Binary files a/legacy/public/assets/img/Weapon/SpikedBokoBat.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/SpikedBokoClub.png b/legacy/public/assets/img/Weapon/SpikedBokoClub.png
deleted file mode 100644
index d503731..0000000
Binary files a/legacy/public/assets/img/Weapon/SpikedBokoClub.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/SpikedBokoSpear.png b/legacy/public/assets/img/Weapon/SpikedBokoSpear.png
deleted file mode 100644
index 1d33e3b..0000000
Binary files a/legacy/public/assets/img/Weapon/SpikedBokoSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/SpikedMoblinClub.png b/legacy/public/assets/img/Weapon/SpikedMoblinClub.png
deleted file mode 100644
index 7e5a7c7..0000000
Binary files a/legacy/public/assets/img/Weapon/SpikedMoblinClub.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/SpikedMoblinSpear.png b/legacy/public/assets/img/Weapon/SpikedMoblinSpear.png
deleted file mode 100644
index ad14d2c..0000000
Binary files a/legacy/public/assets/img/Weapon/SpikedMoblinSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/SpringLoadedHammer.png b/legacy/public/assets/img/Weapon/SpringLoadedHammer.png
deleted file mode 100644
index d8bbce8..0000000
Binary files a/legacy/public/assets/img/Weapon/SpringLoadedHammer.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/StoneSmasher.png b/legacy/public/assets/img/Weapon/StoneSmasher.png
deleted file mode 100644
index 8366fd4..0000000
Binary files a/legacy/public/assets/img/Weapon/StoneSmasher.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/Sword.png b/legacy/public/assets/img/Weapon/Sword.png
deleted file mode 100644
index 97e8158..0000000
Binary files a/legacy/public/assets/img/Weapon/Sword.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/SwordOfTheSixSages.png b/legacy/public/assets/img/Weapon/SwordOfTheSixSages.png
deleted file mode 100644
index 7bc9a33..0000000
Binary files a/legacy/public/assets/img/Weapon/SwordOfTheSixSages.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/ThrowingSpear.png b/legacy/public/assets/img/Weapon/ThrowingSpear.png
deleted file mode 100644
index eb34cc2..0000000
Binary files a/legacy/public/assets/img/Weapon/ThrowingSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/Thunderblade.png b/legacy/public/assets/img/Weapon/Thunderblade.png
deleted file mode 100644
index e2eb0ac..0000000
Binary files a/legacy/public/assets/img/Weapon/Thunderblade.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/Thunderspear.png b/legacy/public/assets/img/Weapon/Thunderspear.png
deleted file mode 100644
index 73dbc9b..0000000
Binary files a/legacy/public/assets/img/Weapon/Thunderspear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/ThunderstormRod.png b/legacy/public/assets/img/Weapon/ThunderstormRod.png
deleted file mode 100644
index ea51e73..0000000
Binary files a/legacy/public/assets/img/Weapon/ThunderstormRod.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/Torch.png b/legacy/public/assets/img/Weapon/Torch.png
deleted file mode 100644
index db00bb3..0000000
Binary files a/legacy/public/assets/img/Weapon/Torch.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/TravelersClaymore.png b/legacy/public/assets/img/Weapon/TravelersClaymore.png
deleted file mode 100644
index 781445b..0000000
Binary files a/legacy/public/assets/img/Weapon/TravelersClaymore.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/TravelersSpear.png b/legacy/public/assets/img/Weapon/TravelersSpear.png
deleted file mode 100644
index c4c55e9..0000000
Binary files a/legacy/public/assets/img/Weapon/TravelersSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/TravelersSword.png b/legacy/public/assets/img/Weapon/TravelersSword.png
deleted file mode 100644
index e02635c..0000000
Binary files a/legacy/public/assets/img/Weapon/TravelersSword.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/TreeBranch.png b/legacy/public/assets/img/Weapon/TreeBranch.png
deleted file mode 100644
index 05eec11..0000000
Binary files a/legacy/public/assets/img/Weapon/TreeBranch.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/ViciousSickle.png b/legacy/public/assets/img/Weapon/ViciousSickle.png
deleted file mode 100644
index a685098..0000000
Binary files a/legacy/public/assets/img/Weapon/ViciousSickle.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/Weapon.png b/legacy/public/assets/img/Weapon/Weapon.png
deleted file mode 100644
index 509467a..0000000
Binary files a/legacy/public/assets/img/Weapon/Weapon.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/Windcleaver.png b/legacy/public/assets/img/Weapon/Windcleaver.png
deleted file mode 100644
index 6e64a15..0000000
Binary files a/legacy/public/assets/img/Weapon/Windcleaver.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/WoodcuttersAxe.png b/legacy/public/assets/img/Weapon/WoodcuttersAxe.png
deleted file mode 100644
index 31b4359..0000000
Binary files a/legacy/public/assets/img/Weapon/WoodcuttersAxe.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/WoodenMop.png b/legacy/public/assets/img/Weapon/WoodenMop.png
deleted file mode 100644
index a3706c1..0000000
Binary files a/legacy/public/assets/img/Weapon/WoodenMop.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/ZoraSpear.png b/legacy/public/assets/img/Weapon/ZoraSpear.png
deleted file mode 100644
index 7468cd9..0000000
Binary files a/legacy/public/assets/img/Weapon/ZoraSpear.png and /dev/null differ
diff --git a/legacy/public/assets/img/Weapon/ZoraSword.png b/legacy/public/assets/img/Weapon/ZoraSword.png
deleted file mode 100644
index 4e235f9..0000000
Binary files a/legacy/public/assets/img/Weapon/ZoraSword.png and /dev/null differ
diff --git a/manual/COMMANDS.md b/manual/COMMANDS.md
index 76d44fa..51fb885 100644
--- a/manual/COMMANDS.md
+++ b/manual/COMMANDS.md
@@ -8,10 +8,8 @@ core commands:
# PMDM
# Stage 1
- !core-add ITEM:
- Add ITEM to PMDM
- !core-add-one ITEM:
- Add one ITEM to PMDM
+ !core-add Item:
+ Add Item to PMDM
!core-remove-held:
Remove held items
!core-hold SLOT:
@@ -54,6 +52,10 @@ core commands:
!core-set-gdt FLAG VALUE:
Set GDT FLAG to VALUE
+ !core-aslr NUMBER:
+ Set the upper 32 bits of address in ASLR region.
+ This can only be done when the game is closed
+
extra:
@@ -107,9 +109,9 @@ runtime:
annotations:
global:
// I guess these are technically features?
- (FEATURE)
+ :enable FEATURE
Enable Feature
- (no-FEATURE)
+ :disable FEATURE
Disable Feature
(menu-overload)
Start menu overload
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..08918ba
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,8196 @@
+{
+ "name": "botw-ist",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "workspaces": [
+ "packages/app",
+ "packages/extension-api",
+ "packages/intwc",
+ "packages/item-assets",
+ "packages/item-system",
+ "packages/localization",
+ "packages/monaco-typescript-contrib",
+ "packages/monaco-editor-contrib",
+ "packages/runtime-wasm/pkg",
+ "packages/workex"
+ ],
+ "devDependencies": {
+ "@eslint/js": "^9.17.0",
+ "@modyfi/vite-plugin-yaml": "^1.1.0",
+ "@types/react": "^18.3.16",
+ "@types/react-dom": "^18.3.5",
+ "@vitejs/plugin-react": "^4.3.4",
+ "eslint": "^9.17.0",
+ "eslint-plugin-react": "^7.37.2",
+ "eslint-plugin-react-hooks": "^5.1.0",
+ "eslint-plugin-react-refresh": "^0.4.16",
+ "globals": "^15.13.0",
+ "prettier": "^3.4.2",
+ "storybook": "^8.4.7",
+ "typescript": "^5.7.2",
+ "typescript-eslint": "^8.18.0",
+ "vite": "^5.4.11",
+ "vite-tsconfig-paths": "^5.1.4"
+ }
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.26.2",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
+ "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.26.3",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.3.tgz",
+ "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz",
+ "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@ampproject/remapping": "^2.2.0",
+ "@babel/code-frame": "^7.26.0",
+ "@babel/generator": "^7.26.0",
+ "@babel/helper-compilation-targets": "^7.25.9",
+ "@babel/helper-module-transforms": "^7.26.0",
+ "@babel/helpers": "^7.26.0",
+ "@babel/parser": "^7.26.0",
+ "@babel/template": "^7.25.9",
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.26.0",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.26.3",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz",
+ "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.26.3",
+ "@babel/types": "^7.26.3",
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz",
+ "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.25.9",
+ "@babel/helper-validator-option": "^7.25.9",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz",
+ "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz",
+ "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz",
+ "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
+ "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
+ "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz",
+ "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz",
+ "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.25.9",
+ "@babel/types": "^7.26.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.26.3",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz",
+ "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.26.3"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz",
+ "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-source": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz",
+ "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz",
+ "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==",
+ "license": "MIT",
+ "dependencies": {
+ "regenerator-runtime": "^0.14.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz",
+ "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.25.9",
+ "@babel/parser": "^7.25.9",
+ "@babel/types": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.26.4",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz",
+ "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.26.2",
+ "@babel/generator": "^7.26.3",
+ "@babel/parser": "^7.26.3",
+ "@babel/template": "^7.25.9",
+ "@babel/types": "^7.26.3",
+ "debug": "^4.3.1",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.26.3",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz",
+ "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@catppuccin/palette": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/@catppuccin/palette/-/palette-1.7.1.tgz",
+ "integrity": "sha512-aRc1tbzrevOTV7nFTT9SRdF26w/MIwT4Jwt4fDMc9itRZUDXCuEDBLyz4TQMlqO9ZP8mf5Hu4Jr6D03NLFc6Gw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/catppuccin"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/catppuccin"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/@emotion/hash": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz",
+ "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==",
+ "license": "MIT"
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+ "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+ "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+ "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+ "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+ "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+ "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+ "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+ "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+ "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+ "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+ "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+ "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+ "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+ "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+ "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+ "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+ "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+ "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+ "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz",
+ "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+ "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz",
+ "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.5",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/core": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.1.tgz",
+ "integrity": "sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz",
+ "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "9.17.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz",
+ "integrity": "sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz",
+ "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz",
+ "integrity": "sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@floating-ui/core": {
+ "version": "1.6.8",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz",
+ "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/utils": "^0.2.8"
+ }
+ },
+ "node_modules/@floating-ui/devtools": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@floating-ui/devtools/-/devtools-0.2.1.tgz",
+ "integrity": "sha512-8PHJLbD6VhBh+LJ1uty/Bz30qs02NXCE5u8WpOhSewlYXUWl03GNXknr9AS2yaAWJEQaY27x7eByJs44gODBcw==",
+ "peerDependencies": {
+ "@floating-ui/dom": ">=1.5.4"
+ }
+ },
+ "node_modules/@floating-ui/dom": {
+ "version": "1.6.12",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz",
+ "integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/core": "^1.6.0",
+ "@floating-ui/utils": "^0.2.8"
+ }
+ },
+ "node_modules/@floating-ui/utils": {
+ "version": "0.2.8",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz",
+ "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==",
+ "license": "MIT"
+ },
+ "node_modules/@fluentui/keyboard-keys": {
+ "version": "9.0.8",
+ "resolved": "https://registry.npmjs.org/@fluentui/keyboard-keys/-/keyboard-keys-9.0.8.tgz",
+ "integrity": "sha512-iUSJUUHAyTosnXK8O2Ilbfxma+ZyZPMua5vB028Ys96z80v+LFwntoehlFsdH3rMuPsA8GaC1RE7LMezwPBPdw==",
+ "license": "MIT",
+ "dependencies": {
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "node_modules/@fluentui/priority-overflow": {
+ "version": "9.1.14",
+ "resolved": "https://registry.npmjs.org/@fluentui/priority-overflow/-/priority-overflow-9.1.14.tgz",
+ "integrity": "sha512-tIH8EhvjZF4MhxSjqrWOyodrQQW+RlVZqxuNFQF5OWRdSqcIK8g+Z+UbC5fYHQooCgVsthk2mFurfGMKFtf9ug==",
+ "license": "MIT",
+ "dependencies": {
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "node_modules/@fluentui/react-accordion": {
+ "version": "9.5.12",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-accordion/-/react-accordion-9.5.12.tgz",
+ "integrity": "sha512-xpY78JuTyxZF+id+GUxIMfFQG5mGkW5WvNW/H2t9kPKohYHfzQXTp7XUIkfSaqGMg/XjezqjtkJcCd+z9oKXnw==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-aria": "^9.13.12",
+ "@fluentui/react-context-selector": "^9.1.71",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-motion": "^9.6.5",
+ "@fluentui/react-motion-components-preview": "^0.4.1",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-accordion/node_modules/@fluentui/react-context-selector": {
+ "version": "9.1.71",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.1.71.tgz",
+ "integrity": "sha512-rBm3+e/RPERRdW8xbL7+JgUHApNkoVOXoRfzva4qWF4dOudmDytPobzNNAyNXQXSbFZoeBYiCQ62OZf7wVpE5A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.18.19",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": ">=0.19.0 <=0.23.0"
+ }
+ },
+ "node_modules/@fluentui/react-accordion/node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/@fluentui/react-alert": {
+ "version": "9.0.0-beta.124",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-alert/-/react-alert-9.0.0-beta.124.tgz",
+ "integrity": "sha512-yFBo3B5H9hnoaXxlkuz8wRz04DEyQ+ElYA/p5p+Vojf19Zuta8DmFZZ6JtWdtxcdnnQ4LvAfC5OYYlzdReozPA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-avatar": "^9.6.29",
+ "@fluentui/react-button": "^9.3.83",
+ "@fluentui/react-icons": "^2.0.239",
+ "@fluentui/react-jsx-runtime": "^9.0.39",
+ "@fluentui/react-tabster": "^9.21.5",
+ "@fluentui/react-theme": "^9.1.19",
+ "@fluentui/react-utilities": "^9.18.10",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-aria": {
+ "version": "9.13.12",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-aria/-/react-aria-9.13.12.tgz",
+ "integrity": "sha512-1qNa4Yux3X3l9pQMGnANkZcNJA4rtCNnaImW5rHDAXhRzvIkQtypN0bRIsWVZqeQEc5bABh9QJaItdOo+TPelw==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-avatar": {
+ "version": "9.6.47",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-avatar/-/react-avatar-9.6.47.tgz",
+ "integrity": "sha512-ykEF6XVd+2vB7RghJaqcMZRpqbf6ZM7UgOVKLFIEAy8qiX2Fwa2VzzA3rhTQoBB2QvaXGrFKeDzN+bTkMkXKBg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-badge": "^9.2.48",
+ "@fluentui/react-context-selector": "^9.1.71",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-popover": "^9.9.29",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-tooltip": "^9.5.2",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-avatar/node_modules/@fluentui/react-context-selector": {
+ "version": "9.1.71",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.1.71.tgz",
+ "integrity": "sha512-rBm3+e/RPERRdW8xbL7+JgUHApNkoVOXoRfzva4qWF4dOudmDytPobzNNAyNXQXSbFZoeBYiCQ62OZf7wVpE5A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.18.19",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": ">=0.19.0 <=0.23.0"
+ }
+ },
+ "node_modules/@fluentui/react-avatar/node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/@fluentui/react-badge": {
+ "version": "9.2.48",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-badge/-/react-badge-9.2.48.tgz",
+ "integrity": "sha512-yVP4SaLVjr97IvicxhlfECxB92MbDLIn+nevcGWV28/H7qWypZiCC8DXfJKE/QDVyrClefozqEIeww7lhUjcJg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-breadcrumb": {
+ "version": "9.0.47",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-breadcrumb/-/react-breadcrumb-9.0.47.tgz",
+ "integrity": "sha512-r+sDXZWWVuwsS4JW+0tpOoC4F3iDCEWMtD0EOtc5wpwF/WASQWIvikzUDOS1N9ACTHVoyq1gPqQmECBHWCloQw==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-aria": "^9.13.12",
+ "@fluentui/react-button": "^9.3.98",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-link": "^9.3.5",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-button": {
+ "version": "9.3.98",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-button/-/react-button-9.3.98.tgz",
+ "integrity": "sha512-ET548xw82eXBz43tyxoswv51XnusSK2sq/mm9KrlNpSVbzjyOHxfG0ZQ88KZCIcFSqq/8ZpLG23tihlKOl/n+g==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-aria": "^9.13.12",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-card": {
+ "version": "9.0.100",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-card/-/react-card-9.0.100.tgz",
+ "integrity": "sha512-PLSWvFzNR9HvVQcMGbG1OIj2TjSlGVMV/6Nli/YaICRvGjjEX1f37NAu3yotEbxqZavJg7j8ekJ/dQqXPGv5HA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-text": "^9.4.30",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-carousel": {
+ "version": "9.4.3",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-carousel/-/react-carousel-9.4.3.tgz",
+ "integrity": "sha512-wOd+cWV8b+2OOfITVmFY7fjouk28JtPTm5i7b3+1n0O8GMkkoI6dvpMyp+VXj4NnoYD86umrpXFGoSLX2UAqXw==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-aria": "^9.13.12",
+ "@fluentui/react-button": "^9.3.98",
+ "@fluentui/react-context-selector": "^9.1.71",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1",
+ "embla-carousel": "^8.5.1",
+ "embla-carousel-autoplay": "^8.5.1",
+ "embla-carousel-fade": "^8.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-carousel/node_modules/@fluentui/react-context-selector": {
+ "version": "9.1.71",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.1.71.tgz",
+ "integrity": "sha512-rBm3+e/RPERRdW8xbL7+JgUHApNkoVOXoRfzva4qWF4dOudmDytPobzNNAyNXQXSbFZoeBYiCQ62OZf7wVpE5A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.18.19",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": ">=0.19.0 <=0.23.0"
+ }
+ },
+ "node_modules/@fluentui/react-carousel/node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/@fluentui/react-checkbox": {
+ "version": "9.2.44",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-checkbox/-/react-checkbox-9.2.44.tgz",
+ "integrity": "sha512-sVY0kKg3FMgzMMfGPbcM71dVqWYbOrkF7qtDDwwFeSCnk3km1SHxeNCR4KRIvtTriosvjkoo3u981ldLsufSWw==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.83",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-label": "^9.1.81",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-combobox": {
+ "version": "9.13.15",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-combobox/-/react-combobox-9.13.15.tgz",
+ "integrity": "sha512-v03PcpOfeylfmF48SQ+FMEctafysMcScbVXej63fTiCXBZMxrdv3sJUG2Lf8ZbvQGVdEYad6l9J+Xsk1mhjr9Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-aria": "^9.13.12",
+ "@fluentui/react-context-selector": "^9.1.71",
+ "@fluentui/react-field": "^9.1.83",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-portal": "^9.4.40",
+ "@fluentui/react-positioning": "^9.16.0",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-combobox/node_modules/@fluentui/react-context-selector": {
+ "version": "9.1.71",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.1.71.tgz",
+ "integrity": "sha512-rBm3+e/RPERRdW8xbL7+JgUHApNkoVOXoRfzva4qWF4dOudmDytPobzNNAyNXQXSbFZoeBYiCQ62OZf7wVpE5A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.18.19",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": ">=0.19.0 <=0.23.0"
+ }
+ },
+ "node_modules/@fluentui/react-combobox/node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/@fluentui/react-components": {
+ "version": "9.56.8",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-components/-/react-components-9.56.8.tgz",
+ "integrity": "sha512-7Japh4zntMzCha2iuDYPPPCabvETpmJpxiLJptVR/iq7NdjYgpSX7RUkuIjjJOyYyvk6e1bQW9KXO6Eg3HyMPA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-accordion": "^9.5.12",
+ "@fluentui/react-alert": "9.0.0-beta.124",
+ "@fluentui/react-aria": "^9.13.12",
+ "@fluentui/react-avatar": "^9.6.47",
+ "@fluentui/react-badge": "^9.2.48",
+ "@fluentui/react-breadcrumb": "^9.0.47",
+ "@fluentui/react-button": "^9.3.98",
+ "@fluentui/react-card": "^9.0.100",
+ "@fluentui/react-carousel": "^9.4.3",
+ "@fluentui/react-checkbox": "^9.2.44",
+ "@fluentui/react-combobox": "^9.13.15",
+ "@fluentui/react-dialog": "^9.11.26",
+ "@fluentui/react-divider": "^9.2.80",
+ "@fluentui/react-drawer": "^9.6.6",
+ "@fluentui/react-field": "^9.1.83",
+ "@fluentui/react-image": "^9.1.78",
+ "@fluentui/react-infobutton": "9.0.0-beta.102",
+ "@fluentui/react-infolabel": "^9.0.54",
+ "@fluentui/react-input": "^9.4.96",
+ "@fluentui/react-label": "^9.1.81",
+ "@fluentui/react-link": "^9.3.5",
+ "@fluentui/react-menu": "^9.14.24",
+ "@fluentui/react-message-bar": "^9.2.19",
+ "@fluentui/react-motion": "^9.6.5",
+ "@fluentui/react-overflow": "^9.2.5",
+ "@fluentui/react-persona": "^9.2.106",
+ "@fluentui/react-popover": "^9.9.29",
+ "@fluentui/react-portal": "^9.4.40",
+ "@fluentui/react-positioning": "^9.16.0",
+ "@fluentui/react-progress": "^9.1.94",
+ "@fluentui/react-provider": "^9.18.2",
+ "@fluentui/react-radio": "^9.2.39",
+ "@fluentui/react-rating": "^9.0.26",
+ "@fluentui/react-search": "^9.0.26",
+ "@fluentui/react-select": "^9.1.94",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-skeleton": "^9.1.23",
+ "@fluentui/react-slider": "^9.2.3",
+ "@fluentui/react-spinbutton": "^9.2.95",
+ "@fluentui/react-spinner": "^9.5.5",
+ "@fluentui/react-swatch-picker": "^9.1.17",
+ "@fluentui/react-switch": "^9.1.101",
+ "@fluentui/react-table": "^9.15.26",
+ "@fluentui/react-tabs": "^9.6.5",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-tag-picker": "^9.3.13",
+ "@fluentui/react-tags": "^9.3.27",
+ "@fluentui/react-teaching-popover": "^9.1.26",
+ "@fluentui/react-text": "^9.4.30",
+ "@fluentui/react-textarea": "^9.3.95",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-toast": "^9.3.63",
+ "@fluentui/react-toolbar": "^9.2.13",
+ "@fluentui/react-tooltip": "^9.5.2",
+ "@fluentui/react-tree": "^9.8.11",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@fluentui/react-virtualizer": "9.0.0-alpha.89",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-dialog": {
+ "version": "9.11.26",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-dialog/-/react-dialog-9.11.26.tgz",
+ "integrity": "sha512-I5/5zn843DQyOQ4mYuLqvgiA1UHS7wMYdwLFt5wGIQdk8oXgoCMwCJakFGU3/6JLWBl+YRxCd0RYMkCPuYdk1g==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-aria": "^9.13.12",
+ "@fluentui/react-context-selector": "^9.1.71",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-motion": "^9.6.5",
+ "@fluentui/react-motion-components-preview": "^0.4.1",
+ "@fluentui/react-portal": "^9.4.40",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-dialog/node_modules/@fluentui/react-context-selector": {
+ "version": "9.1.71",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.1.71.tgz",
+ "integrity": "sha512-rBm3+e/RPERRdW8xbL7+JgUHApNkoVOXoRfzva4qWF4dOudmDytPobzNNAyNXQXSbFZoeBYiCQ62OZf7wVpE5A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.18.19",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": ">=0.19.0 <=0.23.0"
+ }
+ },
+ "node_modules/@fluentui/react-dialog/node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/@fluentui/react-divider": {
+ "version": "9.2.80",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-divider/-/react-divider-9.2.80.tgz",
+ "integrity": "sha512-8SahbCicYzoi75etgJwOI+YDh09/eGA9Pf0PUbpymY8c8+voH/o7OOxwiV45A8VlxZFd5K9TwA0MVtmxsiClDQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-drawer": {
+ "version": "9.6.6",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-drawer/-/react-drawer-9.6.6.tgz",
+ "integrity": "sha512-Ky9Si3u5domFfkVMa/CclebHkj4OG+NQ4ut2yY0GYGAVnON0F1B3HWlqtmBId63gQNzdarosKM5WMjsSaDRMFA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-dialog": "^9.11.26",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-motion": "^9.6.5",
+ "@fluentui/react-portal": "^9.4.40",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-field": {
+ "version": "9.1.83",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-field/-/react-field-9.1.83.tgz",
+ "integrity": "sha512-+Gm6RWcr32C+t+PVpqPRTzDNDDG01IUnevPJR2t2ROcr+rDmqGA8tQ0eT7Nl6ZpWDZeOHOHXR13YtMPEjq6VPw==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-context-selector": "^9.1.71",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-label": "^9.1.81",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-field/node_modules/@fluentui/react-context-selector": {
+ "version": "9.1.71",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.1.71.tgz",
+ "integrity": "sha512-rBm3+e/RPERRdW8xbL7+JgUHApNkoVOXoRfzva4qWF4dOudmDytPobzNNAyNXQXSbFZoeBYiCQ62OZf7wVpE5A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.18.19",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": ">=0.19.0 <=0.23.0"
+ }
+ },
+ "node_modules/@fluentui/react-field/node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/@fluentui/react-icons": {
+ "version": "2.0.270",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-icons/-/react-icons-2.0.270.tgz",
+ "integrity": "sha512-XFAUxbOTH5gb/eTZ5UDR/841tbNskr2SNa/hshsQdojyEKMjBxNNcXo2ruesdfCGKsz/KOlmSh2sZu7NmN2N7Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@griffel/react": "^1.0.0",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-image": {
+ "version": "9.1.78",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-image/-/react-image-9.1.78.tgz",
+ "integrity": "sha512-/5bfyURPVgW2yJyFwsW5x+rCcS3yxZk+7vhrDPIQn/WzZ4cpO7XNQQvoeqZlpC/DbmPHJWjPzRi2kDwikuZgNg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-infobutton": {
+ "version": "9.0.0-beta.102",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-infobutton/-/react-infobutton-9.0.0-beta.102.tgz",
+ "integrity": "sha512-3kA4F0Vga8Ds6JGlBajLCCDOo/LmPuS786Wg7ui4ZTDYVIMzy1yp2XuVcZniifBFvEp0HQCUoDPWUV0VI3FfzQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-icons": "^2.0.237",
+ "@fluentui/react-jsx-runtime": "^9.0.36",
+ "@fluentui/react-label": "^9.1.68",
+ "@fluentui/react-popover": "^9.9.6",
+ "@fluentui/react-tabster": "^9.21.0",
+ "@fluentui/react-theme": "^9.1.19",
+ "@fluentui/react-utilities": "^9.18.7",
+ "@griffel/react": "^1.5.14",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-infolabel": {
+ "version": "9.0.54",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-infolabel/-/react-infolabel-9.0.54.tgz",
+ "integrity": "sha512-DiU/mnt4TYAyrAYgfv8yFkYyrsKGsrkw09zUBl4yPXxz6fjtULQaAc1ahty8bndjuCrz3edDr8jbrHLVDB18Lg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-label": "^9.1.81",
+ "@fluentui/react-popover": "^9.9.29",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "@types/react-dom": ">=16.8.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-input": {
+ "version": "9.4.96",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-input/-/react-input-9.4.96.tgz",
+ "integrity": "sha512-Fry5AwRwGotZmuSEYj7WNyGI2yYR+7kSO+2tqPy1HtajUVz+JfHbn95wem1ZoSkOUnuj15fmSuXJAAN5q967ug==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.83",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-jsx-runtime": {
+ "version": "9.0.48",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-jsx-runtime/-/react-jsx-runtime-9.0.48.tgz",
+ "integrity": "sha512-Awk9rsbXsANqR+yCRSHlbVySn2jjP9FU94Jn+phe+USV93Pi32qJCwjL0zymIOIEYIeqdwngGHvSa+nrAx+jRQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.18.19",
+ "@swc/helpers": "^0.5.1",
+ "react-is": "^17.0.2"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-jsx-runtime/node_modules/react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "license": "MIT"
+ },
+ "node_modules/@fluentui/react-label": {
+ "version": "9.1.81",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-label/-/react-label-9.1.81.tgz",
+ "integrity": "sha512-Hv+rEbZDdLDTwrNqiDG66Yy21Qh2kpXg+etCfbqjF5ENua5J+I2iAdxDYwUUip7Hq12VckKnsqjytgdIhwyO/A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-link": {
+ "version": "9.3.5",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-link/-/react-link-9.3.5.tgz",
+ "integrity": "sha512-YAsnt0WOQvPA2esHjK9uuoxVuQVAN12nBO/DuNlqW9sv7Rpc2jHU/4de3gR608uGEWtp/K0bwyafo+oTtMzJKQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-menu": {
+ "version": "9.14.24",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-menu/-/react-menu-9.14.24.tgz",
+ "integrity": "sha512-IJxvGQdJ2bMIYmpIpJixpJ55OqMLJUF6eAmLGZOMlk9TJiQxFKO04v6LYIffMFAuMknhwNfW3hbt6uU+hHcItA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-aria": "^9.13.12",
+ "@fluentui/react-context-selector": "^9.1.71",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-portal": "^9.4.40",
+ "@fluentui/react-positioning": "^9.16.0",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-menu/node_modules/@fluentui/react-context-selector": {
+ "version": "9.1.71",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.1.71.tgz",
+ "integrity": "sha512-rBm3+e/RPERRdW8xbL7+JgUHApNkoVOXoRfzva4qWF4dOudmDytPobzNNAyNXQXSbFZoeBYiCQ62OZf7wVpE5A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.18.19",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": ">=0.19.0 <=0.23.0"
+ }
+ },
+ "node_modules/@fluentui/react-menu/node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/@fluentui/react-message-bar": {
+ "version": "9.2.19",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-message-bar/-/react-message-bar-9.2.19.tgz",
+ "integrity": "sha512-wiO3kW8rCuCTscBZMUS9Lmt8e6DZiziwspjM/5ELu7DF6TQtIgPRe0CStL2UZEXvyLcGTpCCCj64LiTQ7UQhtA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-button": "^9.3.98",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-link": "^9.3.5",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1",
+ "react-transition-group": "^4.4.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "@types/react-dom": ">=16.8.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-motion": {
+ "version": "9.6.5",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-motion/-/react-motion-9.6.5.tgz",
+ "integrity": "sha512-EDgB/BqqIQuFiQk5dei92RR+/W9zZ15DaeDzDMqCMYgkipnYuJ2xE18cEHyuDpUVCQL4Uw25y3oLqLxb4fI6iA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@swc/helpers": "^0.5.1",
+ "react-is": "^17.0.2"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "@types/react-dom": ">=16.8.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-motion-components-preview": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-motion-components-preview/-/react-motion-components-preview-0.4.1.tgz",
+ "integrity": "sha512-wHiwrhKpOACGHW4ozJjq8L598OKPk2IiSOT14IXOQ8XMOpKtusYO6CJ1nHukzFl3sQ/cx2ADIFoqaFJ1/1zYXg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-motion": "*",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-motion/node_modules/react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "license": "MIT"
+ },
+ "node_modules/@fluentui/react-overflow": {
+ "version": "9.2.5",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-overflow/-/react-overflow-9.2.5.tgz",
+ "integrity": "sha512-eH4QseZFy3S9qhOEG+0t8d2o5vY/0jqeJqcjsoXyh6WZskxhCpCxEWcvufPxTe0Y3YolMzYvIzTBmSgpRNljzg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/priority-overflow": "^9.1.14",
+ "@fluentui/react-context-selector": "^9.1.71",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-overflow/node_modules/@fluentui/react-context-selector": {
+ "version": "9.1.71",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.1.71.tgz",
+ "integrity": "sha512-rBm3+e/RPERRdW8xbL7+JgUHApNkoVOXoRfzva4qWF4dOudmDytPobzNNAyNXQXSbFZoeBYiCQ62OZf7wVpE5A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.18.19",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": ">=0.19.0 <=0.23.0"
+ }
+ },
+ "node_modules/@fluentui/react-overflow/node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/@fluentui/react-persona": {
+ "version": "9.2.106",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-persona/-/react-persona-9.2.106.tgz",
+ "integrity": "sha512-QMU4RhGG4tVF09zniSlWtsg9p9RQ0MT8XOSIOSsaypATml8I8L3bVrIluKbJjLqR5BrxVpt/TAzrB0H0qUcD1g==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-avatar": "^9.6.47",
+ "@fluentui/react-badge": "^9.2.48",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-popover": {
+ "version": "9.9.29",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-popover/-/react-popover-9.9.29.tgz",
+ "integrity": "sha512-RAkL9rqUetCL+ie6AoChNwjKEVZweEyOGwExOIZW0U3kZ9dv87RHWFZrzl3EtiXaJ0c3BpvuMgZWpCVc+XKw2g==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-aria": "^9.13.12",
+ "@fluentui/react-context-selector": "^9.1.71",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-portal": "^9.4.40",
+ "@fluentui/react-positioning": "^9.16.0",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-popover/node_modules/@fluentui/react-context-selector": {
+ "version": "9.1.71",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.1.71.tgz",
+ "integrity": "sha512-rBm3+e/RPERRdW8xbL7+JgUHApNkoVOXoRfzva4qWF4dOudmDytPobzNNAyNXQXSbFZoeBYiCQ62OZf7wVpE5A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.18.19",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": ">=0.19.0 <=0.23.0"
+ }
+ },
+ "node_modules/@fluentui/react-popover/node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/@fluentui/react-portal": {
+ "version": "9.4.40",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-portal/-/react-portal-9.4.40.tgz",
+ "integrity": "sha512-YLpazsKAsc9u6x7z9E7vAIUcn8829PTECOtWNwDXLc9iSFKtTIO1HntybGkEtptb+2TYiquJgG+Lpg9YKFkaYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1",
+ "use-disposable": "^1.0.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-positioning": {
+ "version": "9.16.0",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-positioning/-/react-positioning-9.16.0.tgz",
+ "integrity": "sha512-tVmsiH8bv654+dJYm6bmDA5E+Oo7j9J15tzlWvl7EowE9EBPNqZah5rTAyCoODkdU23pJcq43o2QpLGjPc36XQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/devtools": "0.2.1",
+ "@floating-ui/dom": "^1.2.0",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-progress": {
+ "version": "9.1.94",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-progress/-/react-progress-9.1.94.tgz",
+ "integrity": "sha512-Tfff8O5xMpji2oBeOuhp/yQolUqkpTQ1Ml8kIS/QS+nQ36XRAd/CSnI/OGyd/2Qsa9g93+XgXyopUemz1bUPAA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.83",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-provider": {
+ "version": "9.18.2",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-provider/-/react-provider-9.18.2.tgz",
+ "integrity": "sha512-OVOGSYtcgl13nsQEIDEvhdL/d9LbA0gS87r4Kb2lWIn3iK3bLSjeYbNi++WLMQspaAI38jLSLrXyEoInN1WOdg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/core": "^1.16.0",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-radio": {
+ "version": "9.2.39",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-radio/-/react-radio-9.2.39.tgz",
+ "integrity": "sha512-avEG2oM31ty69D4+OrZCakClleGgkJiqPyx6aVqyskH7Hy0/iC3TDMDpwkSY5QeLOvy+dNyhCNxY+rMuuVHAgA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.83",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-label": "^9.1.81",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-rating": {
+ "version": "9.0.26",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-rating/-/react-rating-9.0.26.tgz",
+ "integrity": "sha512-SEL1uiiij+DMUTtvrJnawnni7xzbl1JQ3IvMN1I5PYw8uJNTL+JylF1P8/rltOd9xOCat1wsu7WsmzsahKnIUA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "@types/react-dom": ">=16.8.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-search": {
+ "version": "9.0.26",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-search/-/react-search-9.0.26.tgz",
+ "integrity": "sha512-pXmIG6L1bQk2eWPnnvFDczn67PcXjAuI/tT1N9tD+/iAc0SCz0sWN9S2rKTaYrrSVhDbUbM1EKyGci+MVlsW/A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-input": "^9.4.96",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-select": {
+ "version": "9.1.94",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-select/-/react-select-9.1.94.tgz",
+ "integrity": "sha512-kb0yeBQ41BlWNQZ/pjbgl21VFwlZc9hmm8YYriR+bc6cvRSj/oLAFj5/3XtB0DhjYO/IorvxCVI5vkSZnGgrnQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.83",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-shared-contexts": {
+ "version": "9.21.2",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-shared-contexts/-/react-shared-contexts-9.21.2.tgz",
+ "integrity": "sha512-5hw9CfCmKaEbxmFi+ZF4EZzYWFKrfRLq9pXFIoJWprP1D3ZAds/ymtIOG/CsJzig8zQ1LQ3cNSUzNB75XWg6IQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-theme": "^9.1.24",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-skeleton": {
+ "version": "9.1.23",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-skeleton/-/react-skeleton-9.1.23.tgz",
+ "integrity": "sha512-lDNP5xYnWJj6IHNd7FHVCi+p2XV7d2cIkwMJ5usKeoTTnWr/1E2T8P+pNsOyku68/r6zuozqtCOmCI2u/OLo4g==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.83",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-slider": {
+ "version": "9.2.3",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-slider/-/react-slider-9.2.3.tgz",
+ "integrity": "sha512-2vaAR6eTDwhQf5t5d7nb+oHEbzD3nKbBnkdOVAieknmQV/Xxum8P6v1KY8FmYmwFhjxKaUYIZ9j9/mT95DEo+A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.83",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-spinbutton": {
+ "version": "9.2.95",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-spinbutton/-/react-spinbutton-9.2.95.tgz",
+ "integrity": "sha512-hJMXr+7X0wJhLQq0XmfQ2FLxvUxDTeUkHlEowtYjJJJDoepzuTm4chdyLz+Q4MSEV+NiKioLVMfNs750S7Z0Lw==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-field": "^9.1.83",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-spinner": {
+ "version": "9.5.5",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-spinner/-/react-spinner-9.5.5.tgz",
+ "integrity": "sha512-PQSU0kJxOXBLwR/bNO996HkSqZ6mVWhDeT6Bt0gP+D+USl3Akj9cUnNtlzw5781tcdks/7U7SovqqKym3HTKoA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-label": "^9.1.81",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-swatch-picker": {
+ "version": "9.1.17",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-swatch-picker/-/react-swatch-picker-9.1.17.tgz",
+ "integrity": "sha512-VG44DspajQFOvFpe71NyB7q1fBovtB41udvJCiaD5NVsUFo7THgtjJrgGjd4EUeruuoQ4SxJEv3T7HymFL64BA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-context-selector": "^9.1.71",
+ "@fluentui/react-field": "^9.1.83",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "@types/react-dom": ">=16.8.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-swatch-picker/node_modules/@fluentui/react-context-selector": {
+ "version": "9.1.71",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.1.71.tgz",
+ "integrity": "sha512-rBm3+e/RPERRdW8xbL7+JgUHApNkoVOXoRfzva4qWF4dOudmDytPobzNNAyNXQXSbFZoeBYiCQ62OZf7wVpE5A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.18.19",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": ">=0.19.0 <=0.23.0"
+ }
+ },
+ "node_modules/@fluentui/react-swatch-picker/node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/@fluentui/react-switch": {
+ "version": "9.1.101",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-switch/-/react-switch-9.1.101.tgz",
+ "integrity": "sha512-7m7FiKVAyVOQbdeoiHWMbtnGxlcnSm7quhs9OySuP4fGRd0nR1DalmjOE4h/tbysyF/n0FcgGu3bD0dh5VgD7g==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.83",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-label": "^9.1.81",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-table": {
+ "version": "9.15.26",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-table/-/react-table-9.15.26.tgz",
+ "integrity": "sha512-EMYQXxjtVYj6moL5lVQiA5hVEqm2raDv1nphX2wUGRb6Yy8YS5gS42B5DtNMPPnc6sDPwxhrqJL7BIeIHy5ILA==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-aria": "^9.13.12",
+ "@fluentui/react-avatar": "^9.6.47",
+ "@fluentui/react-checkbox": "^9.2.44",
+ "@fluentui/react-context-selector": "^9.1.71",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-radio": "^9.2.39",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-table/node_modules/@fluentui/react-context-selector": {
+ "version": "9.1.71",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.1.71.tgz",
+ "integrity": "sha512-rBm3+e/RPERRdW8xbL7+JgUHApNkoVOXoRfzva4qWF4dOudmDytPobzNNAyNXQXSbFZoeBYiCQ62OZf7wVpE5A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.18.19",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": ">=0.19.0 <=0.23.0"
+ }
+ },
+ "node_modules/@fluentui/react-table/node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/@fluentui/react-tabs": {
+ "version": "9.6.5",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tabs/-/react-tabs-9.6.5.tgz",
+ "integrity": "sha512-IulnVxI6gQEfmsdlVjmP33qtyzzAw2J/oBlXfSPz2JbARx6KEUMak7YNnIWm1Jv35lphQBuL6WVItDWY+9+xFg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-context-selector": "^9.1.71",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-tabs/node_modules/@fluentui/react-context-selector": {
+ "version": "9.1.71",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.1.71.tgz",
+ "integrity": "sha512-rBm3+e/RPERRdW8xbL7+JgUHApNkoVOXoRfzva4qWF4dOudmDytPobzNNAyNXQXSbFZoeBYiCQ62OZf7wVpE5A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.18.19",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": ">=0.19.0 <=0.23.0"
+ }
+ },
+ "node_modules/@fluentui/react-tabs/node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/@fluentui/react-tabster": {
+ "version": "9.23.2",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tabster/-/react-tabster-9.23.2.tgz",
+ "integrity": "sha512-DG1rZy8dkD24urQQywhRPfo13qEALCHUWSBmuAYnZ9wAHkGRbDVgdGZLEEUkvP5a6PxdDsFD5AGnC4C+56gKOg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1",
+ "keyborg": "^2.6.0",
+ "tabster": "^8.2.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-tag-picker": {
+ "version": "9.3.13",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tag-picker/-/react-tag-picker-9.3.13.tgz",
+ "integrity": "sha512-F4TLdVR+ikGqFZVuM6CqVdCTqNYzJm5YY6cvMXlbN/nOFM6/sW/cxrdtNQ2tfgp+k4HXIzqOvd2ohtCca9DOBQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-aria": "^9.13.12",
+ "@fluentui/react-combobox": "^9.13.15",
+ "@fluentui/react-context-selector": "^9.1.71",
+ "@fluentui/react-field": "^9.1.83",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-portal": "^9.4.40",
+ "@fluentui/react-positioning": "^9.16.0",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-tags": "^9.3.27",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-tag-picker/node_modules/@fluentui/react-context-selector": {
+ "version": "9.1.71",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.1.71.tgz",
+ "integrity": "sha512-rBm3+e/RPERRdW8xbL7+JgUHApNkoVOXoRfzva4qWF4dOudmDytPobzNNAyNXQXSbFZoeBYiCQ62OZf7wVpE5A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.18.19",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": ">=0.19.0 <=0.23.0"
+ }
+ },
+ "node_modules/@fluentui/react-tag-picker/node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/@fluentui/react-tags": {
+ "version": "9.3.27",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tags/-/react-tags-9.3.27.tgz",
+ "integrity": "sha512-lJDXEI8KClPMZTnnviVegcvGIvWQXXT/fAq6cZm30EnzmM3hRLJFMDFpCLoCAWoYsK2Nyh2xyTny4Vr+/dE4Vg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-aria": "^9.13.12",
+ "@fluentui/react-avatar": "^9.6.47",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-teaching-popover": {
+ "version": "9.1.26",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-teaching-popover/-/react-teaching-popover-9.1.26.tgz",
+ "integrity": "sha512-AtMHNS8cQDVJoWpJsSInvNFcwUA+4bC+qXSAjxXK9CYAxztkqGmFoADqlvxSU7QufNwI/9aBR0AcmkefyM4/Ew==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-aria": "^9.13.12",
+ "@fluentui/react-button": "^9.3.98",
+ "@fluentui/react-context-selector": "^9.1.71",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-popover": "^9.9.29",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1",
+ "use-sync-external-store": "^1.2.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "@types/react-dom": ">=16.8.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-teaching-popover/node_modules/@fluentui/react-context-selector": {
+ "version": "9.1.71",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.1.71.tgz",
+ "integrity": "sha512-rBm3+e/RPERRdW8xbL7+JgUHApNkoVOXoRfzva4qWF4dOudmDytPobzNNAyNXQXSbFZoeBYiCQ62OZf7wVpE5A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.18.19",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": ">=0.19.0 <=0.23.0"
+ }
+ },
+ "node_modules/@fluentui/react-teaching-popover/node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/@fluentui/react-text": {
+ "version": "9.4.30",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-text/-/react-text-9.4.30.tgz",
+ "integrity": "sha512-LwJL+daufTuTmelIKIYfzKjb6WdHzq4GiOD1COjElyAd8K5/hrsUB+oqKs6UxCRRDzHmuChLvInGiVIyAVunPw==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-textarea": {
+ "version": "9.3.95",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-textarea/-/react-textarea-9.3.95.tgz",
+ "integrity": "sha512-f9MUl9nPDnVMINmK+rnJbxP6RjSadg2DxM2YubxivCMGEapnfeOLuWnBO82RXSMs60o66Zt3FUVmsGjCZ/HJ1A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-field": "^9.1.83",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-theme": {
+ "version": "9.1.24",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-theme/-/react-theme-9.1.24.tgz",
+ "integrity": "sha512-OhVKYD7CMYHxzJEn4PtIszledj8hbQJNWBMfIZsp4Sytdp9vCi0txIQUx4BhS1WqtQPhNGCF16eW9Q3NRrnIrQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/tokens": "1.0.0-alpha.21",
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "node_modules/@fluentui/react-toast": {
+ "version": "9.3.63",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-toast/-/react-toast-9.3.63.tgz",
+ "integrity": "sha512-jNl7pcPpkUL31C9bc/Njikojd6ozfOUqa2l9PaKdfXg4FUDC/3lMELhFyjUfyWZD8cGsRaqRTp45DgCajd7ahg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-aria": "^9.13.12",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-motion": "^9.6.5",
+ "@fluentui/react-motion-components-preview": "^0.4.1",
+ "@fluentui/react-portal": "^9.4.40",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-toolbar": {
+ "version": "9.2.13",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-toolbar/-/react-toolbar-9.2.13.tgz",
+ "integrity": "sha512-6lY8YgxxstywsMh+6c66JNr1PtGE2FmPHRU5yNt0qYaZftXpOFg9UZrDcK00Um2sHTGXDZe+XlsWe4rsI1UdYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-button": "^9.3.98",
+ "@fluentui/react-context-selector": "^9.1.71",
+ "@fluentui/react-divider": "^9.2.80",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-radio": "^9.2.39",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-toolbar/node_modules/@fluentui/react-context-selector": {
+ "version": "9.1.71",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.1.71.tgz",
+ "integrity": "sha512-rBm3+e/RPERRdW8xbL7+JgUHApNkoVOXoRfzva4qWF4dOudmDytPobzNNAyNXQXSbFZoeBYiCQ62OZf7wVpE5A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.18.19",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": ">=0.19.0 <=0.23.0"
+ }
+ },
+ "node_modules/@fluentui/react-toolbar/node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/@fluentui/react-tooltip": {
+ "version": "9.5.2",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tooltip/-/react-tooltip-9.5.2.tgz",
+ "integrity": "sha512-hFx63frEUB0irYg7nBbTZh/1u4Ho57BBcpmrTTV/rq5NFlVAJJGWI9jj84utk7T+nFnnA9NUfvdy8KorCoxtkQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-portal": "^9.4.40",
+ "@fluentui/react-positioning": "^9.16.0",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-tree": {
+ "version": "9.8.11",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-tree/-/react-tree-9.8.11.tgz",
+ "integrity": "sha512-gKWzjgfjl4uVzX6fh9TAgVmil4ihBW1q84y1TIRdfB+nkLfE91KUqJRVgKqfKj3tL6mjkcvicJOZz0EKvt6iOg==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-aria": "^9.13.12",
+ "@fluentui/react-avatar": "^9.6.47",
+ "@fluentui/react-button": "^9.3.98",
+ "@fluentui/react-checkbox": "^9.2.44",
+ "@fluentui/react-context-selector": "^9.1.71",
+ "@fluentui/react-icons": "^2.0.245",
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-motion": "^9.6.5",
+ "@fluentui/react-motion-components-preview": "^0.4.1",
+ "@fluentui/react-radio": "^9.2.39",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-tabster": "^9.23.2",
+ "@fluentui/react-theme": "^9.1.24",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-tree/node_modules/@fluentui/react-context-selector": {
+ "version": "9.1.71",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-context-selector/-/react-context-selector-9.1.71.tgz",
+ "integrity": "sha512-rBm3+e/RPERRdW8xbL7+JgUHApNkoVOXoRfzva4qWF4dOudmDytPobzNNAyNXQXSbFZoeBYiCQ62OZf7wVpE5A==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-utilities": "^9.18.19",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0",
+ "scheduler": ">=0.19.0 <=0.23.0"
+ }
+ },
+ "node_modules/@fluentui/react-tree/node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/@fluentui/react-utilities": {
+ "version": "9.18.19",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-utilities/-/react-utilities-9.18.19.tgz",
+ "integrity": "sha512-cBYq2cRc+ofVv4DTgULX5ez6IN/DiZw8IC17giA7NyxGw9ed0Y2p7nqnz/tIa655tY/ZIw5oz+bRJrEPkpzA2g==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/keyboard-keys": "^9.0.8",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/react-virtualizer": {
+ "version": "9.0.0-alpha.89",
+ "resolved": "https://registry.npmjs.org/@fluentui/react-virtualizer/-/react-virtualizer-9.0.0-alpha.89.tgz",
+ "integrity": "sha512-O4nw6FxlVZHQ6B8jCqpsDo308CEyyNNCFOqqC83c7KhA43QczwX0wif8UVlkGKPjY4iwBfEB4fGRO68khN/KRQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@fluentui/react-jsx-runtime": "^9.0.48",
+ "@fluentui/react-shared-contexts": "^9.21.2",
+ "@fluentui/react-utilities": "^9.18.19",
+ "@griffel/react": "^1.5.22",
+ "@swc/helpers": "^0.5.1"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.14.0 <19.0.0",
+ "@types/react-dom": ">=16.9.0 <19.0.0",
+ "react": ">=16.14.0 <19.0.0",
+ "react-dom": ">=16.14.0 <19.0.0"
+ }
+ },
+ "node_modules/@fluentui/tokens": {
+ "version": "1.0.0-alpha.21",
+ "resolved": "https://registry.npmjs.org/@fluentui/tokens/-/tokens-1.0.0-alpha.21.tgz",
+ "integrity": "sha512-xQ1T56sNgDFGl+kJdIwhz67mHng8vcwO7Dvx5Uja4t+NRULQBgMcJ4reUo4FGF3TjufHj08pP0/OnKQgnOaSVg==",
+ "license": "MIT",
+ "dependencies": {
+ "@swc/helpers": "^0.5.1"
+ }
+ },
+ "node_modules/@griffel/core": {
+ "version": "1.18.2",
+ "resolved": "https://registry.npmjs.org/@griffel/core/-/core-1.18.2.tgz",
+ "integrity": "sha512-odJspTMohsYZLSlO/oKsf6El6px1vg1461CpPverOzS9f0xaUKh/ZGenW+MjyyZ3aQ6adkPzcr/my6JFH/zdXQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@emotion/hash": "^0.9.0",
+ "@griffel/style-types": "^1.3.0",
+ "csstype": "^3.1.3",
+ "rtl-css-js": "^1.16.1",
+ "stylis": "^4.2.0",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@griffel/react": {
+ "version": "1.5.27",
+ "resolved": "https://registry.npmjs.org/@griffel/react/-/react-1.5.27.tgz",
+ "integrity": "sha512-985A8iEBo++h9u96dbj3Kj5hdsBWbpkkwFpy0W8EGL0VRCzZmpb0AlWuq9pDJZACS6eZ2GAb/f9CqgVAgnTnOg==",
+ "license": "MIT",
+ "dependencies": {
+ "@griffel/core": "^1.18.2",
+ "tslib": "^2.1.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/@griffel/style-types": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@griffel/style-types/-/style-types-1.3.0.tgz",
+ "integrity": "sha512-bHwD3sUE84Xwv4dH011gOKe1jul77M1S6ZFN9Tnq8pvZ48UMdY//vtES6fv7GRS5wXYT4iqxQPBluAiYAfkpmw==",
+ "license": "MIT",
+ "dependencies": {
+ "csstype": "^3.1.3"
+ }
+ },
+ "node_modules/@humanfs/core": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
+ "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node": {
+ "version": "0.16.6",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz",
+ "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanfs/core": "^0.19.1",
+ "@humanwhocodes/retry": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz",
+ "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz",
+ "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
+ "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/set-array": "^1.2.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@modyfi/vite-plugin-yaml": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@modyfi/vite-plugin-yaml/-/vite-plugin-yaml-1.1.0.tgz",
+ "integrity": "sha512-L26xfzkSo1yamODCAtk/ipVlL6OEw2bcJ92zunyHu8zxi7+meV0zefA9xscRMDCsMY8xL3C3wi3DhMiPxcbxbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rollup/pluginutils": "5.1.0",
+ "js-yaml": "4.1.0",
+ "tosource": "2.0.0-alpha.3"
+ },
+ "peerDependencies": {
+ "vite": "^3.2.7 || ^4.0.5 || ^5.0.5"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@pistonite/intwc": {
+ "resolved": "packages/intwc",
+ "link": true
+ },
+ "node_modules/@pistonite/monaco-typescript-contrib": {
+ "resolved": "packages/monaco-typescript-contrib",
+ "link": true
+ },
+ "node_modules/@pistonite/pure": {
+ "version": "0.0.17",
+ "resolved": "https://registry.npmjs.org/@pistonite/pure/-/pure-0.0.17.tgz",
+ "integrity": "sha512-5f31NlEEkuWu8I33tf9NG+YmrKf6SbKt/hPNVIakcrBs40F9tMN2GYijFdtr0S5/dnzp6btGrbOXhmhqlSsY7A==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/file-saver": "^2.0.7",
+ "denque": "2.1.0",
+ "file-saver": "2.0.5"
+ }
+ },
+ "node_modules/@pistonite/pure-react": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/@pistonite/pure-react/-/pure-react-0.0.5.tgz",
+ "integrity": "sha512-MzWsQzTczPY2BkOWFdCz49LSvljfwyCFbenQzOVHzvlCbmeTuwY2nzUMxMSJh1cvBv5aVQM9ih1erio//HM3Kg==",
+ "license": "MIT",
+ "dependencies": {
+ "@pistonite/pure": "^0.0.14"
+ },
+ "peerDependencies": {
+ "react": "^18"
+ }
+ },
+ "node_modules/@pistonite/pure-react/node_modules/@pistonite/pure": {
+ "version": "0.0.14",
+ "resolved": "https://registry.npmjs.org/@pistonite/pure/-/pure-0.0.14.tgz",
+ "integrity": "sha512-p0GOg8wQ1ZUwsQGwNoS/rL1/nlzVsorBgPP4p+GFhMUHzC+wJbnzR76c+ucyATjTLBTsvBZCBdkXrdRqrdT3Ig==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/file-saver": "^2.0.7",
+ "denque": "2.1.0",
+ "file-saver": "2.0.5"
+ }
+ },
+ "node_modules/@pistonite/skybook-extension-api": {
+ "resolved": "packages/extension-api",
+ "link": true
+ },
+ "node_modules/@rollup/plugin-virtual": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-virtual/-/plugin-virtual-3.0.2.tgz",
+ "integrity": "sha512-10monEYsBp3scM4/ND4LNH5Rxvh3e/cVeL3jWTgZ2SrQ+BmUoQcopVQvnaMcOnykb1VkxUFuDAN+0FnpTFRy2A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/pluginutils": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz",
+ "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "estree-walker": "^2.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "rollup": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.1.tgz",
+ "integrity": "sha512-2aZp8AES04KI2dy3Ss6/MDjXbwBzj+i0GqKtWXgw2/Ma6E4jJvujryO6gJAghIRVz7Vwr9Gtl/8na3nDUKpraQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.28.1.tgz",
+ "integrity": "sha512-EbkK285O+1YMrg57xVA+Dp0tDBRB93/BZKph9XhMjezf6F4TpYjaUSuPt5J0fZXlSag0LmZAsTmdGGqPp4pQFA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.28.1.tgz",
+ "integrity": "sha512-prduvrMKU6NzMq6nxzQw445zXgaDBbMQvmKSJaxpaZ5R1QDM8w+eGxo6Y/jhT/cLoCvnZI42oEqf9KQNYz1fqQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.28.1.tgz",
+ "integrity": "sha512-WsvbOunsUk0wccO/TV4o7IKgloJ942hVFK1CLatwv6TJspcCZb9umQkPdvB7FihmdxgaKR5JyxDjWpCOp4uZlQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.28.1.tgz",
+ "integrity": "sha512-HTDPdY1caUcU4qK23FeeGxCdJF64cKkqajU0iBnTVxS8F7H/7BewvYoG+va1KPSL63kQ1PGNyiwKOfReavzvNA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.28.1.tgz",
+ "integrity": "sha512-m/uYasxkUevcFTeRSM9TeLyPe2QDuqtjkeoTpP9SW0XxUWfcYrGDMkO/m2tTw+4NMAF9P2fU3Mw4ahNvo7QmsQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.28.1.tgz",
+ "integrity": "sha512-QAg11ZIt6mcmzpNE6JZBpKfJaKkqTm1A9+y9O+frdZJEuhQxiugM05gnCWiANHj4RmbgeVJpTdmKRmH/a+0QbA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.28.1.tgz",
+ "integrity": "sha512-dRP9PEBfolq1dmMcFqbEPSd9VlRuVWEGSmbxVEfiq2cs2jlZAl0YNxFzAQS2OrQmsLBLAATDMb3Z6MFv5vOcXg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.28.1.tgz",
+ "integrity": "sha512-uGr8khxO+CKT4XU8ZUH1TTEUtlktK6Kgtv0+6bIFSeiSlnGJHG1tSFSjm41uQ9sAO/5ULx9mWOz70jYLyv1QkA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.28.1.tgz",
+ "integrity": "sha512-QF54q8MYGAqMLrX2t7tNpi01nvq5RI59UBNx+3+37zoKX5KViPo/gk2QLhsuqok05sSCRluj0D00LzCwBikb0A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.28.1.tgz",
+ "integrity": "sha512-vPul4uodvWvLhRco2w0GcyZcdyBfpfDRgNKU+p35AWEbJ/HPs1tOUrkSueVbBS0RQHAf/A+nNtDpvw95PeVKOA==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.28.1.tgz",
+ "integrity": "sha512-pTnTdBuC2+pt1Rmm2SV7JWRqzhYpEILML4PKODqLz+C7Ou2apEV52h19CR7es+u04KlqplggmN9sqZlekg3R1A==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.28.1.tgz",
+ "integrity": "sha512-vWXy1Nfg7TPBSuAncfInmAI/WZDd5vOklyLJDdIRKABcZWojNDY0NJwruY2AcnCLnRJKSaBgf/GiJfauu8cQZA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.28.1.tgz",
+ "integrity": "sha512-/yqC2Y53oZjb0yz8PVuGOQQNOTwxcizudunl/tFs1aLvObTclTwZ0JhXF2XcPT/zuaymemCDSuuUPXJJyqeDOg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.28.1.tgz",
+ "integrity": "sha512-fzgeABz7rrAlKYB0y2kSEiURrI0691CSL0+KXwKwhxvj92VULEDQLpBYLHpF49MSiPG4sq5CK3qHMnb9tlCjBw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.28.1.tgz",
+ "integrity": "sha512-xQTDVzSGiMlSshpJCtudbWyRfLaNiVPXt1WgdWTwWz9n0U12cI2ZVtWe/Jgwyv/6wjL7b66uu61Vg0POWVfz4g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.28.1.tgz",
+ "integrity": "sha512-wSXmDRVupJstFP7elGMgv+2HqXelQhuNf+IS4V+nUpNVi/GUiBgDmfwD0UGN3pcAnWsgKG3I52wMOBnk1VHr/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.28.1.tgz",
+ "integrity": "sha512-ZkyTJ/9vkgrE/Rk9vhMXhf8l9D+eAhbAVbsGsXKy2ohmJaWg0LPQLnIxRdRp/bKyr8tXuPlXhIoGlEB5XpJnGA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.28.1.tgz",
+ "integrity": "sha512-ZvK2jBafvttJjoIdKm/Q/Bh7IJ1Ose9IBOwpOXcOvW3ikGTQGmKDgxTC6oCAzW6PynbkKP8+um1du81XJHZ0JA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@storybook/core": {
+ "version": "8.4.7",
+ "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.4.7.tgz",
+ "integrity": "sha512-7Z8Z0A+1YnhrrSXoKKwFFI4gnsLbWzr8fnDCU6+6HlDukFYh8GHRcZ9zKfqmy6U3hw2h8H5DrHsxWfyaYUUOoA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/csf": "^0.1.11",
+ "better-opn": "^3.0.2",
+ "browser-assert": "^1.2.1",
+ "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0",
+ "esbuild-register": "^3.5.0",
+ "jsdoc-type-pratt-parser": "^4.0.0",
+ "process": "^0.11.10",
+ "recast": "^0.23.5",
+ "semver": "^7.6.2",
+ "util": "^0.12.5",
+ "ws": "^8.2.3"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "prettier": "^2 || ^3"
+ },
+ "peerDependenciesMeta": {
+ "prettier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@storybook/core/node_modules/semver": {
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@storybook/csf": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.12.tgz",
+ "integrity": "sha512-9/exVhabisyIVL0VxTCxo01Tdm8wefIXKXfltAPTSr8cbLn5JAxGQ6QV3mjdecLGEOucfoVhAKtJfVHxEK1iqw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^2.19.0"
+ }
+ },
+ "node_modules/@swc/core": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.1.tgz",
+ "integrity": "sha512-rQ4dS6GAdmtzKiCRt3LFVxl37FaY1cgL9kSUTnhQ2xc3fmHOd7jdJK/V4pSZMG1ruGTd0bsi34O2R0Olg9Zo/w==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/counter": "^0.1.3",
+ "@swc/types": "^0.1.17"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/swc"
+ },
+ "optionalDependencies": {
+ "@swc/core-darwin-arm64": "1.10.1",
+ "@swc/core-darwin-x64": "1.10.1",
+ "@swc/core-linux-arm-gnueabihf": "1.10.1",
+ "@swc/core-linux-arm64-gnu": "1.10.1",
+ "@swc/core-linux-arm64-musl": "1.10.1",
+ "@swc/core-linux-x64-gnu": "1.10.1",
+ "@swc/core-linux-x64-musl": "1.10.1",
+ "@swc/core-win32-arm64-msvc": "1.10.1",
+ "@swc/core-win32-ia32-msvc": "1.10.1",
+ "@swc/core-win32-x64-msvc": "1.10.1"
+ },
+ "peerDependencies": {
+ "@swc/helpers": "*"
+ },
+ "peerDependenciesMeta": {
+ "@swc/helpers": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@swc/core-darwin-arm64": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.1.tgz",
+ "integrity": "sha512-NyELPp8EsVZtxH/mEqvzSyWpfPJ1lugpTQcSlMduZLj1EASLO4sC8wt8hmL1aizRlsbjCX+r0PyL+l0xQ64/6Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-darwin-x64": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.1.tgz",
+ "integrity": "sha512-L4BNt1fdQ5ZZhAk5qoDfUnXRabDOXKnXBxMDJ+PWLSxOGBbWE6aJTnu4zbGjJvtot0KM46m2LPAPY8ttknqaZA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm-gnueabihf": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.1.tgz",
+ "integrity": "sha512-Y1u9OqCHgvVp2tYQAJ7hcU9qO5brDMIrA5R31rwWQIAKDkJKtv3IlTHF0hrbWk1wPR0ZdngkQSJZple7G+Grvw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm64-gnu": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.1.tgz",
+ "integrity": "sha512-tNQHO/UKdtnqjc7o04iRXng1wTUXPgVd8Y6LI4qIbHVoVPwksZydISjMcilKNLKIwOoUQAkxyJ16SlOAeADzhQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm64-musl": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.1.tgz",
+ "integrity": "sha512-x0L2Pd9weQ6n8dI1z1Isq00VHFvpBClwQJvrt3NHzmR+1wCT/gcYl1tp9P5xHh3ldM8Cn4UjWCw+7PaUgg8FcQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-x64-gnu": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.1.tgz",
+ "integrity": "sha512-yyYEwQcObV3AUsC79rSzN9z6kiWxKAVJ6Ntwq2N9YoZqSPYph+4/Am5fM1xEQYf/kb99csj0FgOelomJSobxQA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-x64-musl": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.1.tgz",
+ "integrity": "sha512-tcaS43Ydd7Fk7sW5ROpaf2Kq1zR+sI5K0RM+0qYLYYurvsJruj3GhBCaiN3gkzd8m/8wkqNqtVklWaQYSDsyqA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-arm64-msvc": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.1.tgz",
+ "integrity": "sha512-D3Qo1voA7AkbOzQ2UGuKNHfYGKL6eejN8VWOoQYtGHHQi1p5KK/Q7V1ku55oxXBsj79Ny5FRMqiRJpVGad7bjQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-ia32-msvc": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.1.tgz",
+ "integrity": "sha512-WalYdFoU3454Og+sDKHM1MrjvxUGwA2oralknXkXL8S0I/8RkWZOB++p3pLaGbTvOO++T+6znFbQdR8KRaa7DA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-x64-msvc": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.1.tgz",
+ "integrity": "sha512-JWobfQDbTnoqaIwPKQ3DVSywihVXlQMbDuwik/dDWlj33A8oEHcjPOGs4OqcA3RHv24i+lfCQpM3Mn4FAMfacA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "Apache-2.0 AND MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/counter": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
+ "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/@swc/helpers": {
+ "version": "0.5.15",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
+ "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@swc/types": {
+ "version": "0.1.17",
+ "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.17.tgz",
+ "integrity": "sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/counter": "^0.1.3"
+ }
+ },
+ "node_modules/@tanstack/query-core": {
+ "version": "5.62.9",
+ "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.62.9.tgz",
+ "integrity": "sha512-lwePd8hNYhyQ4nM/iRQ+Wz2cDtspGeZZHFZmCzHJ7mfKXt+9S301fULiY2IR2byJYY6Z03T427E5PoVfMexHjw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ }
+ },
+ "node_modules/@tanstack/react-query": {
+ "version": "5.62.11",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.62.11.tgz",
+ "integrity": "sha512-Xb1nw0cYMdtFmwkvH9+y5yYFhXvLRCnXoqlzSw7UkqtCVFq3cG8q+rHZ2Yz1XrC+/ysUaTqbLKJqk95mCgC1oQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@tanstack/query-core": "5.62.9"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "react": "^18 || ^19"
+ }
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.6.8",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz",
+ "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.20.6",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz",
+ "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.20.7"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/file-saver": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.7.tgz",
+ "integrity": "sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==",
+ "license": "MIT"
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "22.10.2",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz",
+ "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.20.0"
+ }
+ },
+ "node_modules/@types/prop-types": {
+ "version": "15.7.14",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz",
+ "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==",
+ "license": "MIT"
+ },
+ "node_modules/@types/react": {
+ "version": "18.3.16",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.16.tgz",
+ "integrity": "sha512-oh8AMIC4Y2ciKufU8hnKgs+ufgbA/dhPTACaZPM86AbwX9QwnFtSoPWEeRUj8fge+v6kFt78BXcDhAU1SrrAsw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/prop-types": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "18.3.5",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.5.tgz",
+ "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "^18.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.18.0.tgz",
+ "integrity": "sha512-NR2yS7qUqCL7AIxdJUQf2MKKNDVNaig/dEB0GBLU7D+ZdHgK1NoH/3wsgO3OnPVipn51tG3MAwaODEGil70WEw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.10.0",
+ "@typescript-eslint/scope-manager": "8.18.0",
+ "@typescript-eslint/type-utils": "8.18.0",
+ "@typescript-eslint/utils": "8.18.0",
+ "@typescript-eslint/visitor-keys": "8.18.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.3.1",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^1.3.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.8.0"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.18.0.tgz",
+ "integrity": "sha512-hgUZ3kTEpVzKaK3uNibExUYm6SKKOmTU2BOxBSvOYwtJEPdVQ70kZJpPjstlnhCHcuc2WGfSbpKlb/69ttyN5Q==",
+ "dev": true,
+ "license": "MITClause",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "8.18.0",
+ "@typescript-eslint/types": "8.18.0",
+ "@typescript-eslint/typescript-estree": "8.18.0",
+ "@typescript-eslint/visitor-keys": "8.18.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.8.0"
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.18.0.tgz",
+ "integrity": "sha512-PNGcHop0jkK2WVYGotk/hxj+UFLhXtGPiGtiaWgVBVP1jhMoMCHlTyJA+hEj4rszoSdLTK3fN4oOatrL0Cp+Xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.18.0",
+ "@typescript-eslint/visitor-keys": "8.18.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.18.0.tgz",
+ "integrity": "sha512-er224jRepVAVLnMF2Q7MZJCq5CsdH2oqjP4dT7K6ij09Kyd+R21r7UVJrF0buMVdZS5QRhDzpvzAxHxabQadow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "8.18.0",
+ "@typescript-eslint/utils": "8.18.0",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^1.3.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.8.0"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.18.0.tgz",
+ "integrity": "sha512-FNYxgyTCAnFwTrzpBGq+zrnoTO4x0c1CKYY5MuUTzpScqmY5fmsh2o3+57lqdI3NZucBDCzDgdEbIaNfAjAHQA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.18.0.tgz",
+ "integrity": "sha512-rqQgFRu6yPkauz+ms3nQpohwejS8bvgbPyIDq13cgEDbkXt4LH4OkDMT0/fN1RUtzG8e8AKJyDBoocuQh8qNeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.18.0",
+ "@typescript-eslint/visitor-keys": "8.18.0",
+ "debug": "^4.3.4",
+ "fast-glob": "^3.3.2",
+ "is-glob": "^4.0.3",
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^1.3.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <5.8.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.18.0.tgz",
+ "integrity": "sha512-p6GLdY383i7h5b0Qrfbix3Vc3+J2k6QWw6UMUeY5JGfm3C5LbZ4QIZzJNoNOfgyRe0uuYKjvVOsO/jD4SJO+xg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@typescript-eslint/scope-manager": "8.18.0",
+ "@typescript-eslint/types": "8.18.0",
+ "@typescript-eslint/typescript-estree": "8.18.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.8.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.18.0.tgz",
+ "integrity": "sha512-pCh/qEA8Lb1wVIqNvBke8UaRjJ6wrAWkJO5yyIbs8Yx6TNGYyfNjOo61tLv+WwLvoLPp4BQ8B7AHKijl8NGUfw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.18.0",
+ "eslint-visitor-keys": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@vitejs/plugin-react": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz",
+ "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.26.0",
+ "@babel/plugin-transform-react-jsx-self": "^7.25.9",
+ "@babel/plugin-transform-react-jsx-source": "^7.25.9",
+ "@types/babel__core": "^7.20.5",
+ "react-refresh": "^0.14.2"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.14.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
+ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
+ "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.5",
+ "is-array-buffer": "^3.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array-includes": {
+ "version": "3.1.8",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz",
+ "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "is-string": "^1.0.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.findlast": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz",
+ "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz",
+ "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "es-shim-unscopables": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz",
+ "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "es-shim-unscopables": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.tosorted": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz",
+ "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.3",
+ "es-errors": "^1.3.0",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/arraybuffer.prototype.slice": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz",
+ "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.1",
+ "call-bind": "^1.0.5",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.22.3",
+ "es-errors": "^1.2.1",
+ "get-intrinsic": "^1.2.3",
+ "is-array-buffer": "^3.0.4",
+ "is-shared-array-buffer": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ast-types": {
+ "version": "0.16.1",
+ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz",
+ "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/better-opn": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-3.0.2.tgz",
+ "integrity": "sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "open": "^8.0.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/botw-ist": {
+ "resolved": "packages/app",
+ "link": true
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browser-assert": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/browser-assert/-/browser-assert-1.2.1.tgz",
+ "integrity": "sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==",
+ "dev": true
+ },
+ "node_modules/browserslist": {
+ "version": "4.24.3",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.3.tgz",
+ "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001688",
+ "electron-to-chromium": "^1.5.73",
+ "node-releases": "^2.0.19",
+ "update-browserslist-db": "^1.1.1"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
+ "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz",
+ "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.2.tgz",
+ "integrity": "sha512-0lk0PHFe/uz0vl527fG9CgdE9WdafjDbCXvBbs+LUv000TVt2Jjhqbs4Jwm8gz070w8xXyEAxrPOMullsxXeGg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "get-intrinsic": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001688",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001688.tgz",
+ "integrity": "sha512-Nmqpru91cuABu/DTCXbM2NSRHzM2uVHfPnhJ/1zEAJx/ILBRVmz3pzH4N7DZqbdG0gWClsCC05Oj0mJ/1AWMbA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+ "license": "MIT"
+ },
+ "node_modules/data-view-buffer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz",
+ "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz",
+ "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-offset": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz",
+ "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/define-lazy-prop": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
+ "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/denque": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
+ "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/dom-helpers": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
+ "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.8.7",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.0.tgz",
+ "integrity": "sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.73",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.73.tgz",
+ "integrity": "sha512-8wGNxG9tAG5KhGd3eeA0o6ixhiNdgr0DcHWm85XPCphwZgD1lIEoi6t3VERayWao7SF7AAZTw6oARGJeVjH8Kg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/embla-carousel": {
+ "version": "8.5.1",
+ "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.5.1.tgz",
+ "integrity": "sha512-JUb5+FOHobSiWQ2EJNaueCNT/cQU9L6XWBbWmorWPQT9bkbk+fhsuLr8wWrzXKagO3oWszBO7MSx+GfaRk4E6A==",
+ "license": "MIT"
+ },
+ "node_modules/embla-carousel-autoplay": {
+ "version": "8.5.1",
+ "resolved": "https://registry.npmjs.org/embla-carousel-autoplay/-/embla-carousel-autoplay-8.5.1.tgz",
+ "integrity": "sha512-FnZklFpePfp8wbj177UwVaGFehgs+ASVcJvYLWTtHuYKURynCc3IdDn2qrn0E5Qpa3g9yeGwCS4p8QkrZmO8xg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "embla-carousel": "8.5.1"
+ }
+ },
+ "node_modules/embla-carousel-fade": {
+ "version": "8.5.1",
+ "resolved": "https://registry.npmjs.org/embla-carousel-fade/-/embla-carousel-fade-8.5.1.tgz",
+ "integrity": "sha512-n7vRe2tsTW0vc0Xxtk3APoxhUSXIGh/lGRKYtBJS/SWDeXf9E3qVUst4MfHhwXaHlfu5PLqG3xIEDAr2gwbbNA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "embla-carousel": "8.5.1"
+ }
+ },
+ "node_modules/es-abstract": {
+ "version": "1.23.5",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.5.tgz",
+ "integrity": "sha512-vlmniQ0WNPwXqA0BnmwV3Ng7HxiGlh6r5U6JcTMNx8OilcAGqVJBHJcPjqOMaczU9fRuRK5Px2BdVyPRnKMMVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.1",
+ "arraybuffer.prototype.slice": "^1.0.3",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
+ "data-view-buffer": "^1.0.1",
+ "data-view-byte-length": "^1.0.1",
+ "data-view-byte-offset": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-set-tostringtag": "^2.0.3",
+ "es-to-primitive": "^1.2.1",
+ "function.prototype.name": "^1.1.6",
+ "get-intrinsic": "^1.2.4",
+ "get-symbol-description": "^1.0.2",
+ "globalthis": "^1.0.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.0.3",
+ "has-symbols": "^1.0.3",
+ "hasown": "^2.0.2",
+ "internal-slot": "^1.0.7",
+ "is-array-buffer": "^3.0.4",
+ "is-callable": "^1.2.7",
+ "is-data-view": "^1.0.1",
+ "is-negative-zero": "^2.0.3",
+ "is-regex": "^1.1.4",
+ "is-shared-array-buffer": "^1.0.3",
+ "is-string": "^1.0.7",
+ "is-typed-array": "^1.1.13",
+ "is-weakref": "^1.0.2",
+ "object-inspect": "^1.13.3",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.5",
+ "regexp.prototype.flags": "^1.5.3",
+ "safe-array-concat": "^1.1.2",
+ "safe-regex-test": "^1.0.3",
+ "string.prototype.trim": "^1.2.9",
+ "string.prototype.trimend": "^1.0.8",
+ "string.prototype.trimstart": "^1.0.8",
+ "typed-array-buffer": "^1.0.2",
+ "typed-array-byte-length": "^1.0.1",
+ "typed-array-byte-offset": "^1.0.2",
+ "typed-array-length": "^1.0.6",
+ "unbox-primitive": "^1.0.2",
+ "which-typed-array": "^1.1.15"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-iterator-helpers": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.0.tgz",
+ "integrity": "sha512-tpxqxncxnpw3c93u8n3VOzACmRFoVmWJqbWXvX/JfKbkhBw1oslgPrUfeSt2psuqyEJFD6N/9lg5i7bsKpoq+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.3",
+ "es-errors": "^1.3.0",
+ "es-set-tostringtag": "^2.0.3",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "globalthis": "^1.0.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.0.3",
+ "has-symbols": "^1.0.3",
+ "internal-slot": "^1.0.7",
+ "iterator.prototype": "^1.1.3",
+ "safe-array-concat": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
+ "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz",
+ "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.2.4",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-shim-unscopables": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz",
+ "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.0"
+ }
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz",
+ "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7",
+ "is-date-object": "^1.0.5",
+ "is-symbol": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+ "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.21.5",
+ "@esbuild/android-arm": "0.21.5",
+ "@esbuild/android-arm64": "0.21.5",
+ "@esbuild/android-x64": "0.21.5",
+ "@esbuild/darwin-arm64": "0.21.5",
+ "@esbuild/darwin-x64": "0.21.5",
+ "@esbuild/freebsd-arm64": "0.21.5",
+ "@esbuild/freebsd-x64": "0.21.5",
+ "@esbuild/linux-arm": "0.21.5",
+ "@esbuild/linux-arm64": "0.21.5",
+ "@esbuild/linux-ia32": "0.21.5",
+ "@esbuild/linux-loong64": "0.21.5",
+ "@esbuild/linux-mips64el": "0.21.5",
+ "@esbuild/linux-ppc64": "0.21.5",
+ "@esbuild/linux-riscv64": "0.21.5",
+ "@esbuild/linux-s390x": "0.21.5",
+ "@esbuild/linux-x64": "0.21.5",
+ "@esbuild/netbsd-x64": "0.21.5",
+ "@esbuild/openbsd-x64": "0.21.5",
+ "@esbuild/sunos-x64": "0.21.5",
+ "@esbuild/win32-arm64": "0.21.5",
+ "@esbuild/win32-ia32": "0.21.5",
+ "@esbuild/win32-x64": "0.21.5"
+ }
+ },
+ "node_modules/esbuild-register": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz",
+ "integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.4"
+ },
+ "peerDependencies": {
+ "esbuild": ">=0.12 <1"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "9.17.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.17.0.tgz",
+ "integrity": "sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.19.0",
+ "@eslint/core": "^0.9.0",
+ "@eslint/eslintrc": "^3.2.0",
+ "@eslint/js": "9.17.0",
+ "@eslint/plugin-kit": "^0.2.3",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.1",
+ "@types/estree": "^1.0.6",
+ "@types/json-schema": "^7.0.15",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.2.0",
+ "eslint-visitor-keys": "^4.2.0",
+ "espree": "^10.3.0",
+ "esquery": "^1.5.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-plugin-react": {
+ "version": "7.37.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.2.tgz",
+ "integrity": "sha512-EsTAnj9fLVr/GZleBLFbj/sSuXeWmp1eXIN60ceYnZveqEaUCyW4X+Vh4WTdUhCkW4xutXYqTXCUSyqD4rB75w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-includes": "^3.1.8",
+ "array.prototype.findlast": "^1.2.5",
+ "array.prototype.flatmap": "^1.3.2",
+ "array.prototype.tosorted": "^1.1.4",
+ "doctrine": "^2.1.0",
+ "es-iterator-helpers": "^1.1.0",
+ "estraverse": "^5.3.0",
+ "hasown": "^2.0.2",
+ "jsx-ast-utils": "^2.4.1 || ^3.0.0",
+ "minimatch": "^3.1.2",
+ "object.entries": "^1.1.8",
+ "object.fromentries": "^2.0.8",
+ "object.values": "^1.2.0",
+ "prop-types": "^15.8.1",
+ "resolve": "^2.0.0-next.5",
+ "semver": "^6.3.1",
+ "string.prototype.matchall": "^4.0.11",
+ "string.prototype.repeat": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7"
+ }
+ },
+ "node_modules/eslint-plugin-react-hooks": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0.tgz",
+ "integrity": "sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-react-refresh": {
+ "version": "0.4.16",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.16.tgz",
+ "integrity": "sha512-slterMlxAhov/DZO8NScf6mEeMBBXodFUolijDvrtTxyezyLoTQaa73FyYus/VbTdftd8wBgBxPMRk3poleXNQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "eslint": ">=8.40"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz",
+ "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
+ "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz",
+ "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.14.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
+ "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fastq": {
+ "version": "1.17.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
+ "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/file-saver": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
+ "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==",
+ "license": "MIT"
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz",
+ "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/for-each": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+ "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.1.3"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/function.prototype.name": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz",
+ "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "functions-have-names": "^1.2.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz",
+ "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "dunder-proto": "^1.0.0",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "function-bind": "^1.1.2",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-symbol-description": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz",
+ "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "15.13.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-15.13.0.tgz",
+ "integrity": "sha512-49TewVEz0UxZjr1WYYsWpPrhyC/B/pA8Bq0fUmet2n+eR7yn0IvNzNaoBwnK6mdkzcN+se7Ez9zUgULTz2QH4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globalthis": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
+ "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-properties": "^1.2.1",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/globrex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz",
+ "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/has-bigints": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+ "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
+ "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/html-parse-stringify": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
+ "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
+ "license": "MIT",
+ "dependencies": {
+ "void-elements": "3.1.0"
+ }
+ },
+ "node_modules/i18next": {
+ "version": "24.2.0",
+ "resolved": "https://registry.npmjs.org/i18next/-/i18next-24.2.0.tgz",
+ "integrity": "sha512-ArJJTS1lV6lgKH7yEf4EpgNZ7+THl7bsGxxougPYiXRTJ/Fe1j08/TBpV9QsXCIYVfdE/HWG/xLezJ5DOlfBOA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://locize.com"
+ },
+ {
+ "type": "individual",
+ "url": "https://locize.com/i18next.html"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.23.2"
+ },
+ "peerDependencies": {
+ "typescript": "^5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/internal-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
+ "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-arguments": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz",
+ "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-array-buffer": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
+ "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-async-function": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz",
+ "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-bigint": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
+ "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-bigints": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz",
+ "integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.0.tgz",
+ "integrity": "sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-data-view": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
+ "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
+ "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-docker": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+ "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-finalizationregistry": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.0.tgz",
+ "integrity": "sha512-qfMdqbAQEwBw78ZyReKnlA8ezmPdb9BemzIIip/JkjaZUhitfXDkkr+3QTboW0JrSXT1QWyYShpvnNHGZ4c4yA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-generator-function": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
+ "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-map": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
+ "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+ "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.0.tgz",
+ "integrity": "sha512-KVSZV0Dunv9DTPkhXwcZ3Q+tUc9TsaE1ZwX5J2WMvsSGS6Md8TFPun5uwh0yRdrNerI6vf/tbJxqSx4c1ZI1Lw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-regex": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
+ "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-set": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
+ "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-shared-array-buffer": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.0.tgz",
+ "integrity": "sha512-PlfzajuF9vSo5wErv3MJAKD/nqf9ngAs1NFQYm16nUYFO2IzxJ2hcm+IOCg+EEopdykNNUhVq5cz35cAUxU8+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
+ "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "safe-regex-test": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz",
+ "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "which-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakmap": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
+ "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakref": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz",
+ "integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-weakset": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz",
+ "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "get-intrinsic": "^1.2.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-docker": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/iterator.prototype": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.4.tgz",
+ "integrity": "sha512-x4WH0BWmrMmg4oHHl+duwubhrvczGlyuGAZu3nvrf0UXOfPu8IhZObFEr7DE/iv01YgVZrsOiRcqw2srkKEDIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.6",
+ "has-symbols": "^1.1.0",
+ "reflect.getprototypeof": "^1.0.8",
+ "set-function-name": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsdoc-type-pratt-parser": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz",
+ "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/jsx-ast-utils": {
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
+ "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-includes": "^3.1.6",
+ "array.prototype.flat": "^1.3.1",
+ "object.assign": "^4.1.4",
+ "object.values": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/keyborg": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/keyborg/-/keyborg-2.6.0.tgz",
+ "integrity": "sha512-o5kvLbuTF+o326CMVYpjlaykxqYP9DphFQZ2ZpgrvBouyvOxyEB7oqe8nOLFpiV5VCtz0D3pt8gXQYWpLpBnmA==",
+ "license": "MIT"
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "license": "MIT",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.0.0.tgz",
+ "integrity": "sha512-4MqMiKP90ybymYvsut0CH2g4XWbfLtmlCkXmtmdcDCxNB+mQcu1w/1+L/VD7vi/PSv7X2JYV7SCcR+jiPXnQtA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/mobile-device-detect": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/mobile-device-detect/-/mobile-device-detect-0.4.3.tgz",
+ "integrity": "sha512-SN9EBE9SoJgkb83kuUVoIp3R9OGYE5dYEnLEz2oLooh0DzgtQ72BJmpNGqrgFvmfE4iLR2CaVJ3RjUcStheVZg==",
+ "license": "MIT"
+ },
+ "node_modules/monaco-editor": {
+ "version": "0.52.2",
+ "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.2.tgz",
+ "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/monaco-editor-contrib": {
+ "resolved": "packages/monaco-editor-contrib",
+ "link": true
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.8",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
+ "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.19",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
+ "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
+ "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
+ "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.5",
+ "define-properties": "^1.2.1",
+ "has-symbols": "^1.0.3",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.entries": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz",
+ "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.fromentries": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz",
+ "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.values": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz",
+ "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/open": {
+ "version": "8.4.2",
+ "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",
+ "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-lazy-prop": "^2.0.0",
+ "is-docker": "^2.1.1",
+ "is-wsl": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/possible-typed-array-names": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
+ "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.4.49",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
+ "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz",
+ "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
+ "node_modules/prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/react": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
+ "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
+ "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.2"
+ },
+ "peerDependencies": {
+ "react": "^18.3.1"
+ }
+ },
+ "node_modules/react-i18next": {
+ "version": "15.2.0",
+ "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.2.0.tgz",
+ "integrity": "sha512-iJNc8111EaDtVTVMKigvBtPHyrJV+KblWG73cUxqp+WmJCcwkzhWNFXmkAD5pwP2Z4woeDj/oXDdbjDsb3Gutg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.25.0",
+ "html-parse-stringify": "^3.0.1"
+ },
+ "peerDependencies": {
+ "i18next": ">= 23.2.3",
+ "react": ">= 16.8.0"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "license": "MIT"
+ },
+ "node_modules/react-refresh": {
+ "version": "0.14.2",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
+ "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-transition-group": {
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
+ "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@babel/runtime": "^7.5.5",
+ "dom-helpers": "^5.0.1",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2"
+ },
+ "peerDependencies": {
+ "react": ">=16.6.0",
+ "react-dom": ">=16.6.0"
+ }
+ },
+ "node_modules/recast": {
+ "version": "0.23.9",
+ "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.9.tgz",
+ "integrity": "sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ast-types": "^0.16.1",
+ "esprima": "~4.0.0",
+ "source-map": "~0.6.1",
+ "tiny-invariant": "^1.3.3",
+ "tslib": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/reflect.getprototypeof": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.8.tgz",
+ "integrity": "sha512-B5dj6usc5dkk8uFliwjwDHM8To5/QwdKz9JcBZ8Ic4G1f0YmeeJTtE/ZTdgRFPAfxZFiUaPhZ1Jcs4qeagItGQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "define-properties": "^1.2.1",
+ "dunder-proto": "^1.0.0",
+ "es-abstract": "^1.23.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.2.0",
+ "which-builtin-type": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regenerator-runtime": {
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
+ "license": "MIT"
+ },
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz",
+ "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "set-function-name": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/reselect": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz",
+ "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==",
+ "license": "MIT"
+ },
+ "node_modules/resolve": {
+ "version": "2.0.0-next.5",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz",
+ "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.28.1.tgz",
+ "integrity": "sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.6"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.28.1",
+ "@rollup/rollup-android-arm64": "4.28.1",
+ "@rollup/rollup-darwin-arm64": "4.28.1",
+ "@rollup/rollup-darwin-x64": "4.28.1",
+ "@rollup/rollup-freebsd-arm64": "4.28.1",
+ "@rollup/rollup-freebsd-x64": "4.28.1",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.28.1",
+ "@rollup/rollup-linux-arm-musleabihf": "4.28.1",
+ "@rollup/rollup-linux-arm64-gnu": "4.28.1",
+ "@rollup/rollup-linux-arm64-musl": "4.28.1",
+ "@rollup/rollup-linux-loongarch64-gnu": "4.28.1",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.28.1",
+ "@rollup/rollup-linux-riscv64-gnu": "4.28.1",
+ "@rollup/rollup-linux-s390x-gnu": "4.28.1",
+ "@rollup/rollup-linux-x64-gnu": "4.28.1",
+ "@rollup/rollup-linux-x64-musl": "4.28.1",
+ "@rollup/rollup-win32-arm64-msvc": "4.28.1",
+ "@rollup/rollup-win32-ia32-msvc": "4.28.1",
+ "@rollup/rollup-win32-x64-msvc": "4.28.1",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/rtl-css-js": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz",
+ "integrity": "sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.1.2"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-array-concat": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz",
+ "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "has-symbols": "^1.1.0",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">=0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+ "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/scheduler": {
+ "version": "0.23.2",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
+ "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-function-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/skybook-item-assets": {
+ "resolved": "packages/item-assets",
+ "link": true
+ },
+ "node_modules/skybook-item-system": {
+ "resolved": "packages/item-system",
+ "link": true
+ },
+ "node_modules/skybook-localization": {
+ "resolved": "packages/localization",
+ "link": true
+ },
+ "node_modules/skybook-runtime-wasm": {
+ "resolved": "packages/runtime-wasm/pkg",
+ "link": true
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/storybook": {
+ "version": "8.4.7",
+ "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.4.7.tgz",
+ "integrity": "sha512-RP/nMJxiWyFc8EVMH5gp20ID032Wvk+Yr3lmKidoegto5Iy+2dVQnUoElZb2zpbVXNHWakGuAkfI0dY1Hfp/vw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@storybook/core": "8.4.7"
+ },
+ "bin": {
+ "getstorybook": "bin/index.cjs",
+ "sb": "bin/index.cjs",
+ "storybook": "bin/index.cjs"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "prettier": "^2 || ^3"
+ },
+ "peerDependenciesMeta": {
+ "prettier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/string.prototype.matchall": {
+ "version": "4.0.11",
+ "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz",
+ "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-symbols": "^1.0.3",
+ "internal-slot": "^1.0.7",
+ "regexp.prototype.flags": "^1.5.2",
+ "set-function-name": "^2.0.2",
+ "side-channel": "^1.0.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.repeat": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz",
+ "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5"
+ }
+ },
+ "node_modules/string.prototype.trim": {
+ "version": "1.2.10",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz",
+ "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-data-property": "^1.1.4",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.5",
+ "es-object-atoms": "^1.0.0",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz",
+ "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/stylis": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.4.tgz",
+ "integrity": "sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==",
+ "license": "MIT"
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/tabster": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/tabster/-/tabster-8.2.0.tgz",
+ "integrity": "sha512-Gvplk/Yl/12aVFA6FPOqGcq31Qv8hbPfYO0N+6IxrRgRT6eSLsipT6gkZBYjyOwGsp6BD5XlZAuJgupfG/GHoA==",
+ "license": "MIT",
+ "dependencies": {
+ "keyborg": "2.6.0",
+ "tslib": "^2.3.1"
+ }
+ },
+ "node_modules/tiny-invariant": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
+ "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/tosource": {
+ "version": "2.0.0-alpha.3",
+ "resolved": "https://registry.npmjs.org/tosource/-/tosource-2.0.0-alpha.3.tgz",
+ "integrity": "sha512-KAB2lrSS48y91MzFPFuDg4hLbvDiyTjOVgaK7Erw+5AmZXNq4sFRVn8r6yxSLuNs15PaokrDRpS61ERY9uZOug==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ts-api-utils": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz",
+ "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.2.0"
+ }
+ },
+ "node_modules/tsconfck": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.4.tgz",
+ "integrity": "sha512-kdqWFGVJqe+KGYvlSO9NIaWn9jT1Ny4oKVzAJsKii5eoE9snzTJzL4+MMVOMn+fikWGFmKEylcXL710V/kIPJQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "tsconfck": "bin/tsconfck.js"
+ },
+ "engines": {
+ "node": "^18 || >=20"
+ },
+ "peerDependencies": {
+ "typescript": "^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
+ "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=12.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typed-array-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz",
+ "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "es-errors": "^1.3.0",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/typed-array-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz",
+ "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-byte-offset": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.3.tgz",
+ "integrity": "sha512-GsvTyUHTriq6o/bHcTd0vM7OQ9JEdlvluu9YISaA7+KzDzPaIzEeDFNkTfhdE3MYcNhNi0vq/LlegYgIs5yPAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13",
+ "reflect.getprototypeof": "^1.0.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-length": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz",
+ "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "is-typed-array": "^1.1.13",
+ "possible-typed-array-names": "^1.0.0",
+ "reflect.getprototypeof": "^1.0.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz",
+ "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==",
+ "devOptional": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/typescript-eslint": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.18.0.tgz",
+ "integrity": "sha512-Xq2rRjn6tzVpAyHr3+nmSg1/9k9aIHnJ2iZeOH7cfGOWqTkXTm3kwpQglEuLGdNrYvPF+2gtAs+/KF5rjVo+WQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/eslint-plugin": "8.18.0",
+ "@typescript-eslint/parser": "8.18.0",
+ "@typescript-eslint/utils": "8.18.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.8.0"
+ }
+ },
+ "node_modules/unbox-primitive": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
+ "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.0.3",
+ "which-boxed-primitive": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "6.20.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
+ "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
+ "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.0"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/use-disposable": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/use-disposable/-/use-disposable-1.0.4.tgz",
+ "integrity": "sha512-j83t6AMLWUyb5zwlTDqf6dP9LezM9R0yTbI/b6olmdaGtCKQUe9pgJWV6dRaaQLcozypjIEp4EmZr2DkZGKLSg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": ">=16.8.0 <19.0.0",
+ "@types/react-dom": ">=16.8.0 <19.0.0",
+ "react": ">=16.8.0 <19.0.0",
+ "react-dom": ">=16.8.0 <19.0.0"
+ }
+ },
+ "node_modules/use-sync-external-store": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz",
+ "integrity": "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/util": {
+ "version": "0.12.5",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
+ "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "is-arguments": "^1.0.4",
+ "is-generator-function": "^1.0.7",
+ "is-typed-array": "^1.1.3",
+ "which-typed-array": "^1.1.2"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
+ "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
+ "dev": true,
+ "funding": [
+ "https://github.com/sponsors/broofa",
+ "https://github.com/sponsors/ctavan"
+ ],
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/vite": {
+ "version": "5.4.11",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz",
+ "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.21.3",
+ "postcss": "^8.4.43",
+ "rollup": "^4.20.0"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || >=20.0.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-plugin-top-level-await": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/vite-plugin-top-level-await/-/vite-plugin-top-level-await-1.4.4.tgz",
+ "integrity": "sha512-QyxQbvcMkgt+kDb12m2P8Ed35Sp6nXP+l8ptGrnHV9zgYDUpraO0CPdlqLSeBqvY2DToR52nutDG7mIHuysdiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rollup/plugin-virtual": "^3.0.2",
+ "@swc/core": "^1.7.0",
+ "uuid": "^10.0.0"
+ },
+ "peerDependencies": {
+ "vite": ">=2.8"
+ }
+ },
+ "node_modules/vite-plugin-wasm": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-wasm/-/vite-plugin-wasm-3.3.0.tgz",
+ "integrity": "sha512-tVhz6w+W9MVsOCHzxo6SSMSswCeIw4HTrXEi6qL3IRzATl83jl09JVO1djBqPSwfjgnpVHNLYcaMbaDX5WB/pg==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "vite": "^2 || ^3 || ^4 || ^5"
+ }
+ },
+ "node_modules/vite-tsconfig-paths": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-5.1.4.tgz",
+ "integrity": "sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.1.1",
+ "globrex": "^0.1.2",
+ "tsconfck": "^3.0.3"
+ },
+ "peerDependencies": {
+ "vite": "*"
+ },
+ "peerDependenciesMeta": {
+ "vite": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/void-elements": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
+ "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/which-boxed-primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.0.tgz",
+ "integrity": "sha512-Ei7Miu/AXe2JJ4iNF5j/UphAgRoma4trE6PtisM09bPygb3egMH3YLW/befsWb1A1AxvNSFidOFTB18XtnIIng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-bigint": "^1.1.0",
+ "is-boolean-object": "^1.2.0",
+ "is-number-object": "^1.1.0",
+ "is-string": "^1.1.0",
+ "is-symbol": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-builtin-type": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
+ "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "function.prototype.name": "^1.1.6",
+ "has-tostringtag": "^1.0.2",
+ "is-async-function": "^2.0.0",
+ "is-date-object": "^1.1.0",
+ "is-finalizationregistry": "^1.1.0",
+ "is-generator-function": "^1.0.10",
+ "is-regex": "^1.2.1",
+ "is-weakref": "^1.0.2",
+ "isarray": "^2.0.5",
+ "which-boxed-primitive": "^1.1.0",
+ "which-collection": "^1.0.2",
+ "which-typed-array": "^1.1.16"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-collection": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
+ "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.16",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.16.tgz",
+ "integrity": "sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/workex": {
+ "resolved": "packages/workex",
+ "link": true
+ },
+ "node_modules/ws": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
+ "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/zustand": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.2.tgz",
+ "integrity": "sha512-8qNdnJVJlHlrKXi50LDqqUNmUbuBjoKLrYQBnoChIbVph7vni+sY+YpvdjXG9YLd/Bxr6scMcR+rm5H3aSqPaw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.20.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=18.0.0",
+ "immer": ">=9.0.6",
+ "react": ">=18.0.0",
+ "use-sync-external-store": ">=1.2.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "immer": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "use-sync-external-store": {
+ "optional": true
+ }
+ }
+ },
+ "packages/app": {
+ "name": "botw-ist",
+ "version": "0.0.0",
+ "dependencies": {
+ "@fluentui/react-components": "^9.56.8",
+ "@fluentui/react-icons": "^2.0.270",
+ "@pistonite/intwc": "0.0.1",
+ "@pistonite/pure": "^0.0.17",
+ "@pistonite/pure-react": "^0.0.5",
+ "@pistonite/skybook-extension-api": "*",
+ "@tanstack/react-query": "^5.62.11",
+ "mobile-device-detect": "^0.4.3",
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
+ "reselect": "^5.1.1",
+ "skybook-localization": "*",
+ "skybook-runtime-wasm": "*",
+ "workex": "*",
+ "zustand": "^5.0.2"
+ },
+ "devDependencies": {
+ "vite-plugin-top-level-await": "^1.4.4",
+ "vite-plugin-wasm": "^3.3.0"
+ }
+ },
+ "packages/extension-api": {
+ "name": "@pistonite/skybook-extension-api",
+ "version": "0.0.1",
+ "license": "MIT",
+ "dependencies": {
+ "@pistonite/pure": "*"
+ }
+ },
+ "packages/intwc": {
+ "name": "@pistonite/intwc",
+ "version": "0.0.1",
+ "license": "MIT",
+ "dependencies": {
+ "@pistonite/monaco-typescript-contrib": "0.0.1",
+ "@pistonite/pure": "*",
+ "monaco-editor-contrib": "0.52.2"
+ },
+ "devDependencies": {
+ "@catppuccin/palette": "^1.7.1",
+ "@types/react": "^18.3.16",
+ "react": "^18.3.1",
+ "vite": "^5.4.11"
+ }
+ },
+ "packages/item-assets": {
+ "name": "skybook-item-assets",
+ "version": "0.0.0",
+ "peerDependencies": {
+ "@griffel/react": "*",
+ "@types/react": "*",
+ "react": "*"
+ }
+ },
+ "packages/item-display": {
+ "name": "skybook-item-display",
+ "version": "0.0.0",
+ "extraneous": true,
+ "dependencies": {
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1"
+ },
+ "devDependencies": {
+ "@chromatic-com/storybook": "^3.2.3",
+ "@storybook/addon-essentials": "^8.4.7",
+ "@storybook/addon-interactions": "^8.4.7",
+ "@storybook/addon-onboarding": "^8.4.7",
+ "@storybook/blocks": "^8.4.7",
+ "@storybook/react": "^8.4.7",
+ "@storybook/react-vite": "^8.4.7",
+ "@storybook/test": "^8.4.7",
+ "prop-types": "^15.8.1",
+ "storybook": "^8.4.7"
+ }
+ },
+ "packages/item-slots": {
+ "name": "skybook-item-slots",
+ "version": "0.0.0",
+ "extraneous": true,
+ "dependencies": {
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
+ "skybook-item-sprites": "*"
+ },
+ "devDependencies": {}
+ },
+ "packages/item-sprites": {
+ "name": "skybook-item-sprites",
+ "version": "0.0.0",
+ "extraneous": true,
+ "peerDependencies": {
+ "@griffel/react": "*",
+ "@types/react": "*",
+ "react": "*"
+ }
+ },
+ "packages/item-system": {
+ "name": "skybook-item-system",
+ "version": "0.0.0",
+ "dependencies": {
+ "@fluentui/react-components": "*",
+ "@fluentui/react-icons": "*",
+ "react": "*",
+ "react-dom": "*",
+ "skybook-item-assets": "*",
+ "skybook-localization": "*"
+ }
+ },
+ "packages/localization": {
+ "name": "skybook-localization",
+ "version": "0.0.0",
+ "dependencies": {
+ "@pistonite/pure": "*",
+ "i18next": "^24.2.0",
+ "react-i18next": "^15.2.0"
+ }
+ },
+ "packages/monaco-editor-contrib": {
+ "version": "0.52.2",
+ "license": "MIT",
+ "devDependencies": {
+ "@types/node": "^22.10.2",
+ "monaco-editor": "0.52.2"
+ }
+ },
+ "packages/monaco-typescript-contrib": {
+ "name": "@pistonite/monaco-typescript-contrib",
+ "version": "0.0.1",
+ "license": "MIT",
+ "devDependencies": {
+ "monaco-editor-contrib": "0.52.2"
+ }
+ },
+ "packages/runtime-wasm/pkg": {
+ "name": "skybook-runtime-wasm",
+ "version": "0.0.0"
+ },
+ "packages/workex": {
+ "version": "0.0.4"
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..dcc91ce
--- /dev/null
+++ b/package.json
@@ -0,0 +1,36 @@
+{
+ "workspaces": [
+ "packages/app",
+ "packages/extension-api",
+ "packages/intwc",
+ "packages/item-assets",
+ "packages/item-system",
+ "packages/localization",
+ "packages/monaco-typescript-contrib",
+ "packages/monaco-editor-contrib",
+ "packages/runtime-wasm/pkg",
+ "packages/workex"
+ ],
+ "devDependencies": {
+ "@eslint/js": "^9.17.0",
+ "@modyfi/vite-plugin-yaml": "^1.1.0",
+ "@types/react": "^18.3.16",
+ "@types/react-dom": "^18.3.5",
+ "@vitejs/plugin-react": "^4.3.4",
+ "eslint": "^9.17.0",
+ "eslint-plugin-react": "^7.37.2",
+ "eslint-plugin-react-hooks": "^5.1.0",
+ "eslint-plugin-react-refresh": "^0.4.16",
+ "globals": "^15.13.0",
+ "prettier": "^3.4.2",
+ "storybook": "^8.4.7",
+ "typescript": "^5.7.2",
+ "typescript-eslint": "^8.18.0",
+ "vite": "^5.4.11",
+ "vite-tsconfig-paths": "^5.1.4"
+ },
+ "prettier": {
+ "tabWidth": 4,
+ "endOfLine": "auto"
+ }
+}
diff --git a/packages/acorn/Cargo.toml b/packages/acorn/Cargo.toml
new file mode 100644
index 0000000..23f4c9f
--- /dev/null
+++ b/packages/acorn/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "skybook-acorn"
+version = "0.0.0"
+description = "Core of the skybook IST simulator"
+edition = "2021"
+
+[dependencies]
+enumset = "1.1.5"
+heck = "0.5.0"
+serde = { version = "1.0.217", features = ["derive"] }
+serde_variant = "0.1.3"
+serde_yaml_ng = "0.10.0"
diff --git a/packages/acorn/src/command/arg.rs b/packages/acorn/src/command/arg.rs
new file mode 100644
index 0000000..35a95ce
--- /dev/null
+++ b/packages/acorn/src/command/arg.rs
@@ -0,0 +1,70 @@
+pub struct StartGameArgs {}
+
+
+pub struct GetItemArgs {
+ /// Name of the item actor to get
+ pub actor: String,
+
+ /// Value to use for the item if given.
+ ///
+ /// If not given, equipment should receive their default durability
+ /// (generalLife). Other items should use 1 as the value
+ pub value: Option,
+
+ pub modifier: Option,
+
+ pub cook_item: Option,
+}
+
+/// uking::CookItem in cookManager.h
+pub struct CookItemData {
+ pub ingredients: Vec,
+ pub life_recover: f32,
+ pub effect_time: i32,
+ pub sell_price: i32,
+ pub effect_id: CookEffect,
+ pub effect_level: f32,
+ pub is_crit: bool
+}
+
+/// uking::CookEffectId in cookManager.h
+#[repr(i32)]
+pub enum CookEffect {
+ None = -1,
+ LifeRecover = 1,
+ LifeMaxUp = 2,
+ ResistHot = 4,
+ ResistCold = 5,
+ ResistElectric = 6,
+ AttackUp = 10,
+ DefenseUp = 11,
+ Quietness = 12,
+ // note the name we use internally for skybook is different
+ // for decomp, it's MovingSpeed
+ AllSpeed = 13,
+ GutsRecover = 14,
+ ExGutsMaxUp = 15,
+ Fireproof = 16,
+}
+
+/// uking::act::WeaponModifierInfo in actWeapon.h
+pub struct WeaponModifierInfo {
+ pub flags: u32,
+ pub value: i32
+}
+
+#[repr(u32)]
+pub enum WeaponModifier {
+ None = 0,
+ AddPower = 0x1,
+ AddLife = 0x2,
+ Critical = 0x4,
+ LongThrow = 0x8,
+ SpreadFire = 0x10,
+ Zoom = 0x20,
+ RapidFire = 0x40,
+ SurfMaster = 0x80,
+ AddGuard = 0x100,
+ Yellow = 0x80000000,
+}
+
diff --git a/packages/acorn/src/command/core_command.rs b/packages/acorn/src/command/core_command.rs
new file mode 100644
index 0000000..f777f9e
--- /dev/null
+++ b/packages/acorn/src/command/core_command.rs
@@ -0,0 +1,11 @@
+use super::arg::{GetItemArgs, StartGameArgs};
+
+
+pub enum CoreCommand {
+ /// Start the game (!core-start)
+ StartGame(StartGameArgs),
+ /// Add an item to inventory (!core-add)
+ ///
+ /// If value is not given, this uses the logic for doGetItem (0x0073A464)
+ Add(GetItemArgs),
+}
diff --git a/packages/acorn/src/command/mod.rs b/packages/acorn/src/command/mod.rs
new file mode 100644
index 0000000..ecf058e
--- /dev/null
+++ b/packages/acorn/src/command/mod.rs
@@ -0,0 +1,2 @@
+mod arg;
+mod core_command;
diff --git a/packages/acorn/src/error.rs b/packages/acorn/src/error.rs
new file mode 100644
index 0000000..29015dd
--- /dev/null
+++ b/packages/acorn/src/error.rs
@@ -0,0 +1,79 @@
+use crate::{registers::Registers, PageTable};
+
+
+pub struct Crash {
+ /// The instruction location that is being
+ /// executed when the crash happened
+ pub pc: u64,
+
+ pub registers: Registers,
+
+ pub reason: CrashReason,
+
+ /// If memory dump on crash (:enable memory-dump) is enabled, this will contain the memory
+ /// snapshot at the time of the crash
+ pub memory: Option,
+}
+
+pub enum CrashReason {
+ /// Trying to execute an instruction that is bad/malformed
+ BadInstruction(u32),
+ /// Trying to execute an instruction that is recognized, but not
+ /// supported on the (emulated) hardware
+ Unsupported(u32),
+ /// Trying to execute an instruction that is recognized but not implemented
+ Unimplemented(u32),
+ /// The program does not have permission to execute the instruction.
+ ///
+ /// Suppressed by :enable allow-privileged
+ PrivilegeRequired(u32),
+ /// Trying to access an unaligned address
+ ///
+ /// Suppressed by :disable memory-alignment, except when
+ /// the access is across a page boundary, in which case the exception
+ /// will still occur
+ Unaligned(MemAccess),
+ /// Trying to access an address without the proper permissions
+ ///
+ /// Suppressed by :disable memory-permissions, in which case
+ /// all memory addresses have full RWX permissions
+ PermissionDenied(MemAccess),
+ /// Trying to read from an unallocated page (for example, a NULL pointer)
+ ///
+ /// Suppressed by :disable memory-faults, in which
+ /// case 0s should be returned by memory reads
+ PageFault(MemAccess),
+ /// Error during arithmetic operations
+ Arithmetic(ArithmeticError),
+}
+
+pub enum ArithmeticError {
+ /// Integer division by zero
+ ///
+ /// Suppressed by :disable divide-by-zero
+ DivideByZero,
+ /// Integer Overflow
+ ///
+ /// Disabled by default. Enable with :enable integer-bounds
+ Overflow,
+ /// Integer Underflow
+ ///
+ /// Disabled by default. Enable with :enable integer-bounds
+ Underflow,
+}
+
+/// Information for accessing memory
+pub struct MemAccess {
+ pub access_type: MemAccessType,
+ pub addr: u64,
+ pub bytes: u32,
+}
+
+pub enum MemAccessType {
+ /// Reading data from the memory
+ Read,
+ /// Writing data to the memory
+ Write,
+ /// Reading instruction from memory
+ Execute,
+}
diff --git a/packages/acorn/src/features.rs b/packages/acorn/src/features.rs
new file mode 100644
index 0000000..4c9458d
--- /dev/null
+++ b/packages/acorn/src/features.rs
@@ -0,0 +1,66 @@
+use enumset::{EnumSet, EnumSetType};
+use heck::AsKebabCase;
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Hash, EnumSetType, Serialize, Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum CoreFeature {
+ /// Allow privileged instructions (disabled by default)
+ AllowPrivileged,
+
+ /// Enforce aligned memory access within a page
+ MemoryAlignment,
+
+ /// Enforce memory access permissions
+ MemoryPermissions,
+
+ /// Fault when reading unallocated memory
+ MemoryFaults,
+
+ /// Detect integer division by zero
+ DivideByZero,
+
+ /// Detect wrapping operations on signed and unsigned integers (disabled by default)
+ IntegerBounds,
+
+ /// Dump all allocated memory just before crash
+ MemoryDump,
+}
+
+impl std::fmt::Display for CoreFeature {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{}", serde_variant::to_variant_name(self).unwrap())
+ }
+}
+
+impl CoreFeature {
+ /// Convert from a string, returns None if the feature is not recognized
+ pub fn from_str(s: &str) -> Option {
+ serde_yaml_ng::from_str(s).ok()
+ }
+}
+
+/// Get the default feature sets
+pub fn default_features() -> EnumSet {
+ CoreFeature::MemoryAlignment
+ | CoreFeature::MemoryPermissions
+ | CoreFeature::MemoryFaults
+ | CoreFeature::DivideByZero
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[test]
+ fn test_to_string() {
+ assert_eq!("memory-alignment", CoreFeature::MemoryAlignment.to_string());
+ assert_eq!("divide-by-zero", CoreFeature::DivideByZero.to_string());
+ }
+ #[test]
+ fn test_from_string() {
+ assert_eq!(CoreFeature::from_str("memory-alignment"), Some(CoreFeature::MemoryAlignment));
+ assert_eq!(CoreFeature::from_str("divide-by-zero"), Some(CoreFeature::DivideByZero));
+ assert_eq!(CoreFeature::from_str("memory"), None);
+ }
+}
diff --git a/packages/acorn/src/lib.rs b/packages/acorn/src/lib.rs
new file mode 100644
index 0000000..994822a
--- /dev/null
+++ b/packages/acorn/src/lib.rs
@@ -0,0 +1,83 @@
+use std::{borrow::{Borrow, BorrowMut}, collections::HashMap, sync::Arc};
+
+mod command;
+mod error;
+mod registers;
+mod features;
+mod util;
+mod processor;
+
+/// A read-only snapshot of memory pages at a certain
+/// simulation step
+pub struct MemorySnapshot {
+}
+
+const PAGE_SIZE: usize = 4096;
+
+#[derive(Debug, Clone)]
+pub struct Page {
+ data: [u8; PAGE_SIZE],
+ // other metadata, like permission., etc
+}
+
+impl Page {
+ pub fn new() -> Self {
+ Self {
+ data: [0; PAGE_SIZE],
+ // other ...
+ }
+ }
+}
+
+#[derive(Debug, Clone)]
+pub struct PageTable {
+ pages: HashMap>,
+}
+
+impl PageTable {
+ /// Get read access to page at addr
+ ///
+ /// Returns None if the page is not allocated, i.e. a page fault
+ pub fn read(&self, addr: u64) -> Option<&Page> {
+ self.pages.get(&addr).map(|page| page.as_ref())
+ }
+
+ /// Get write access to page at addr
+ ///
+ /// Allocates the page if it's not allocated. Clones the page if it's shared
+ pub fn write(&mut self, addr: u64) -> &mut Page {
+ let arc_page = self.pages.entry(addr).or_insert_with(|| Arc::new(Page::new()));
+ Arc::make_mut(arc_page)
+ }
+}
+
+
+// pub struct Core<'m> {
+// registers: Registers,
+// // having lifetime here is OK.
+// // Core is not meant to be a short-lived object,
+// // only to associate the CPU functions with the memory
+// memory: &'m mut PageTable,
+// }
+//
+// impl<'m> Core<'m> {
+// pub fn attach(memory: &'m mut PageTable) -> Self {
+// Self {
+// registers: Registers::new(),
+// memory,
+// }
+// }
+//
+// pub fn init_memory(&mut self, executable: Executable) -> SingletonTable {
+// // load the executable, call ctors, etc...
+// // executable could be the partial one we provide
+// // or the full one user provides
+// //
+// // Returns a table of proxy to singletons, like PMDM,
+// // to provide read-only access to the memory
+// }
+//
+// pub fn execute_command(&mut self, core_command: CoreCommand) {
+// // ...
+// }
+// }
diff --git a/packages/acorn/src/processor.rs b/packages/acorn/src/processor.rs
new file mode 100644
index 0000000..49ca573
--- /dev/null
+++ b/packages/acorn/src/processor.rs
@@ -0,0 +1,20 @@
+use crate::registers::Registers;
+
+
+pub struct Processor {
+ pub registers: Registers,
+ pub pc: u64,
+ pub flags: Flags,
+}
+
+/// Condition flags
+pub struct Flags {
+ /// Negative
+ pub n: bool,
+ /// Zero
+ pub z: bool,
+ /// Carry
+ pub c: bool,
+ /// Overflow
+ pub v: bool,
+}
diff --git a/packages/acorn/src/registers.rs b/packages/acorn/src/registers.rs
new file mode 100644
index 0000000..05a82b7
--- /dev/null
+++ b/packages/acorn/src/registers.rs
@@ -0,0 +1,29 @@
+#[derive(Debug, Clone, PartialEq)]
+// https://developer.arm.com/documentation/dui0801/l/Overview-of-AArch64-state/Registers-in-AArch64-state
+#[allow(dead_code)]
+pub struct Registers {
+ // 31 general-purpose registers (called X0-X30 in code)
+ // X30 is used as the link register (LR)
+ pub x: [i64; 31],
+ // 32 floating-point registers (called S0-S31 in code) - 128 bits each
+ pub s: [f64; 32],
+ // 4 stack pointer registers
+ // https://developer.arm.com/documentation/dui0801/l/Overview-of-AArch64-state/Stack-Pointer-register?lang=en
+ // sp_el0 is the classic "SP" register
+ // The other 3 are stack pointers for each of the 3 exception levels
+ // This is why the exception link/program status registers go from 1-3 rather than 0-2
+ pub sp_el0: u64,
+ pub sp_el1: u64,
+ pub sp_el2: u64,
+ pub sp_el3: u64,
+ // 3 exception link registers
+ pub elr_el1: i64,
+ pub elr_el2: i64,
+ pub elr_el3: i64,
+ // 3 saved program status registers (these are 32 bits)
+ pub spsr_el1: i32,
+ pub spsr_el2: i32,
+ pub spsr_el3: i32,
+ // Floating point status control register
+ pub fpscr: i32,
+}
diff --git a/packages/acorn/src/util.rs b/packages/acorn/src/util.rs
new file mode 100644
index 0000000..477b45e
--- /dev/null
+++ b/packages/acorn/src/util.rs
@@ -0,0 +1,5 @@
+use enumset::{EnumSet, EnumSetType};
+
+pub struct FlagStack {
+ stack: Vec>,
+}
diff --git a/packages/actor-sys/Cargo.toml b/packages/actor-sys/Cargo.toml
new file mode 100644
index 0000000..d8b758b
--- /dev/null
+++ b/packages/actor-sys/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "actor-sys"
+private = true
+version = "0.0.0"
+edition = "2021"
+description = "Binding for actor parameters"
+
+[dependencies]
+
+
+[[bin]] # Script to generate the source files
+name = "actor-sys-generate"
+path = "generate.rs"
+
+# The features are auto-generated!!!
+[features]
diff --git a/sim/core/.gitkeep b/packages/actor-sys/generate.rs
similarity index 100%
rename from sim/core/.gitkeep
rename to packages/actor-sys/generate.rs
diff --git a/app/src/sim/src/lib.rs b/packages/actor-sys/src/lib.rs
similarity index 100%
rename from app/src/sim/src/lib.rs
rename to packages/actor-sys/src/lib.rs
diff --git a/app/.gitignore b/packages/app/.gitignore
similarity index 100%
rename from app/.gitignore
rename to packages/app/.gitignore
diff --git a/app/README.md b/packages/app/README.md
similarity index 100%
rename from app/README.md
rename to packages/app/README.md
diff --git a/app/Taskfile.yml b/packages/app/Taskfile.yml
similarity index 88%
rename from app/Taskfile.yml
rename to packages/app/Taskfile.yml
index 5f05bce..77e1498 100644
--- a/app/Taskfile.yml
+++ b/packages/app/Taskfile.yml
@@ -6,6 +6,10 @@ tasks:
cmds:
- npx vite --host
+ runtime-workex:
+ cmds:
+ - workex -p runtime src/runtime/protocol.ts --lib-path workex --no-lib
+
build:
desc: Build production bundle
cmds:
diff --git a/app/eslint.config.js b/packages/app/eslint.config.js
similarity index 100%
rename from app/eslint.config.js
rename to packages/app/eslint.config.js
diff --git a/packages/app/icon.ts b/packages/app/icon.ts
new file mode 100644
index 0000000..9caeaac
--- /dev/null
+++ b/packages/app/icon.ts
@@ -0,0 +1,95 @@
+scale(1)
+unit(1)
+
+const color_core1 = "#F0C83D83";
+const color_core2 = "#FE8F0088";
+const color_core3 = "red";
+const color_shell1 = "#AD8867";
+const color_shell2 = "#5C4D48";
+const color_shell3 = "#E7DED5";
+const color_light = "#73FBFD";
+
+function render_core(t: Point) {
+ const pillar = point(0, 0, 0).sized(14, 6, 6);
+ const pillar2 = pillar.translated("y", 8).union(pillar);
+ const pillar4 = pillar2.translated("z", 8).union(pillar2);
+ const pillar_cut = point(0, 3, 3).sized(14, 8, 8);
+ const side_cut = point(3, 0, 3).sized(8, 14, 8);
+ const top_cut = point(3, 3, 0).sized(8, 8, 14);
+
+ const corner = point(0,0,0).sized(2,2,2);
+ const corner2 = corner.translated("x", 12).union(corner);
+ const corner4 = corner2.translated("y", 12).union(corner2);
+ const corner8 = corner4.translated("z", 12).union(corner4);
+
+ const core = point(1,1,1).sized(12,12,12);
+ const core_in = point(2,2,2).sized(10,10,10);
+ const core_in2 = point(3,3,3).sized(8,8,8);
+
+ const center_pillar_out = point(0, 5, 5).sized(14, 4, 4);
+ const center_pillar_in = point(0, 6, 6).sized(14, 2, 2);
+
+ center_pillar_out
+ .difference(center_pillar_in)
+ .difference(core)
+ .translated(t)
+ .render(color_shell3);
+
+ center_pillar_in
+ .difference(core)
+ .translated(t)
+ .render(color_light)
+
+ pillar4
+ .difference(corner8)
+ .difference(pillar_cut)
+ .difference(side_cut)
+ .difference(top_cut)
+ .difference(core)
+ .translated(t)
+ .render(color_shell2);
+
+ core
+ .difference(corner8)
+ .translated(t)
+ .render(color_core1)
+
+ core_in.translated(t).render(color_core2)
+ core_in2.translated(t).render(color_core3)
+
+ core.intersection(corner8)
+ .translated(t)
+ .render(color_shell2)
+}
+
+function render_ring(x: number, width: number) {
+ const center_cut = point(0, 1, 1).sized(14, 16, 16);
+ const middle_ring = point(x, 0, 0).sized(width, 18, 18);
+
+ middle_ring
+ .difference(center_cut)
+ .render(color_light)
+}
+
+function render_hring() {
+ const center_cut = point(1,1,1).sized(16,18,18);
+ const ring = point(0, 0, 7).sized(18,20,3);
+ const ring2 = point(0, 0, 8).sized(18,20,1);
+
+ ring
+ .difference(center_cut)
+ //.difference(ring2)
+ .translated(-1, 0, 0)
+ .render(color_shell1)
+
+ // ring2
+ // .difference(center_cut)
+ // .translated(-1, 0, 0)
+ // .render(color_shell2)
+}
+
+render_core(point(0,2,2))
+//render_ring(2, 1)
+render_ring(6, 2)
+//render_ring(11, 1)
+render_hring()
diff --git a/packages/app/index.html b/packages/app/index.html
new file mode 100644
index 0000000..6986c54
--- /dev/null
+++ b/packages/app/index.html
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+ IST Simulator
+
+
+
+
+
+
+
diff --git a/packages/app/package.json b/packages/app/package.json
new file mode 100644
index 0000000..d432175
--- /dev/null
+++ b/packages/app/package.json
@@ -0,0 +1,37 @@
+{
+ "name": "botw-ist",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc -b && vite build",
+ "lint": "eslint .",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@fluentui/react-components": "^9.56.8",
+ "@fluentui/react-icons": "^2.0.270",
+ "@pistonite/intwc": "0.0.1",
+ "@pistonite/pure": "^0.0.17",
+ "@pistonite/pure-react": "^0.0.5",
+ "@pistonite/skybook-extension-api": "*",
+ "@tanstack/react-query": "^5.62.11",
+ "mobile-device-detect": "^0.4.3",
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
+ "reselect": "^5.1.1",
+ "skybook-localization": "*",
+ "skybook-runtime-wasm": "*",
+ "workex": "*",
+ "zustand": "^5.0.2"
+ },
+ "devDependencies": {
+ "vite-plugin-top-level-await": "^1.4.4",
+ "vite-plugin-wasm": "^3.3.0"
+ },
+ "prettier": {
+ "tabWidth": 4,
+ "endOfLine": "auto"
+ }
+}
diff --git a/packages/app/public/CNAME b/packages/app/public/CNAME
new file mode 100644
index 0000000..a2e8f8f
--- /dev/null
+++ b/packages/app/public/CNAME
@@ -0,0 +1 @@
+tspoc.pistonite.dev
diff --git a/packages/app/public/icon.svg b/packages/app/public/icon.svg
new file mode 100644
index 0000000..025a4b4
--- /dev/null
+++ b/packages/app/public/icon.svg
@@ -0,0 +1 @@
+
diff --git a/packages/app/public/manifest.json b/packages/app/public/manifest.json
new file mode 100644
index 0000000..c1b20fa
--- /dev/null
+++ b/packages/app/public/manifest.json
@@ -0,0 +1,7 @@
+{
+ "short_name": "Skybook",
+ "name": "Skybook",
+ "background_color.todo": "",
+ "display": "fullscreen",
+ "start_url": "/"
+}
diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx
new file mode 100644
index 0000000..8dd8f65
--- /dev/null
+++ b/packages/app/src/App.tsx
@@ -0,0 +1,57 @@
+
+import { makeStyles } from "@fluentui/react-components"
+import { SideToolbar } from "./SideToolbar";
+import { useIsShowingExtensionPanel } from "./application/extensionStore";
+import { ExtensionPanel } from "ui/ExtensionPanel";
+import { useNarrow } from "pure-contrib/narrow";
+import { ResizeLayout } from "ui/components/ResizeLayout";
+import { useUIStore } from "ui/store";
+import { isLessProductive } from "ui/platform";
+
+const useStyles = makeStyles({
+ root: {
+ width: "100vw",
+ height: "100vh",
+ },
+ side: {
+ width: "100%",
+ height: "100%",
+ display: "flex",
+ flexDirection: "column",
+ }
+})
+
+function App() {
+ const narrow = useNarrow();
+ const styles = useStyles();
+
+ const showExtensionPanel = useIsShowingExtensionPanel();
+
+ const extensionPanelPercentage = useUIStore(state => state.extensionPanelPercentage);
+ const setExtensionPanelPercentage = useUIStore(state => state.setExtensionPanelPercentage);
+
+ return (
+
+
+
+ { showExtensionPanel && }
+
+
+ main
+
+
+ );
+
+}
+
+export default App
diff --git a/packages/app/src/ExtensionWrapper.tsx b/packages/app/src/ExtensionWrapper.tsx
new file mode 100644
index 0000000..45aec56
--- /dev/null
+++ b/packages/app/src/ExtensionWrapper.tsx
@@ -0,0 +1,7 @@
+import { Extension } from "@pistonite/skybook-extension-api"
+
+export type ExtensionComponentProps = {
+ extClient: Extension
+}
+
+export type ExtensionComponent = React.ComponentType
diff --git a/packages/app/src/SideToolbar.tsx b/packages/app/src/SideToolbar.tsx
new file mode 100644
index 0000000..c6a6c97
--- /dev/null
+++ b/packages/app/src/SideToolbar.tsx
@@ -0,0 +1,38 @@
+import { Button, Card, CardPreview, makeStyles, tokens } from "@fluentui/react-components";
+import { useIsShowingExtensionPanel } from "application/extensionStore";
+import { ExtensionOpenButton } from "ui/ExtensionOpenButton";
+import icon from "./icon.svg";
+import { BookQuestionMark20Regular, Globe20Regular, Settings20Regular } from "@fluentui/react-icons";
+
+const useStyles = makeStyles({
+ container: {
+ backgroundColor: tokens.colorNeutralBackground2,
+ display: "flex",
+ flexDirection: "row",
+ }
+});
+
+export const SideToolbar: React.FC = () => {
+ const styles = useStyles();
+ const showingExtensionPanel = useIsShowingExtensionPanel();
+ return (
+
+
+
+ v4.0.0
+
+
+
}>
+
+
}/>
+
}/>
+
}/>
+ {
+ !showingExtensionPanel &&
+ }
+
+ 5 errors
+
+
+ );
+}
diff --git a/packages/app/src/application/ApplicationProvider.tsx b/packages/app/src/application/ApplicationProvider.tsx
new file mode 100644
index 0000000..547576a
--- /dev/null
+++ b/packages/app/src/application/ApplicationProvider.tsx
@@ -0,0 +1,13 @@
+import { PropsWithChildren } from "react";
+import { Application } from "@pistonite/skybook-extension-api";
+
+import { ApplicationContext } from "./useApplication.ts";
+
+
+export const ApplicationProvider: React.FC> = ({app, children}) => {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/packages/app/src/application/api.ts b/packages/app/src/application/api.ts
new file mode 100644
index 0000000..246bcb9
--- /dev/null
+++ b/packages/app/src/application/api.ts
@@ -0,0 +1,22 @@
+import { Application } from "@pistonite/skybook-extension-api";
+import { useApplicationStore } from "./store";
+import { debounce } from "@pistonite/pure/sync";
+
+const setScript = debounce({
+ fn: (script: string) => {
+ useApplicationStore.setState({script});
+ },
+ interval: 200,
+});
+
+export class ApplicationApi implements Application {
+ public async getScript() {
+ return {val: useApplicationStore.getState().script};
+ }
+ public async setScript(script: string) {
+ // await setScript(script);
+ // return {};
+ useApplicationStore.setState({script});
+ return {};
+ }
+}
diff --git a/packages/app/src/application/extensionManager.ts b/packages/app/src/application/extensionManager.ts
new file mode 100644
index 0000000..42e0ca7
--- /dev/null
+++ b/packages/app/src/application/extensionManager.ts
@@ -0,0 +1,46 @@
+import { addDarkSubscriber, addLocaleSubscriber } from "@pistonite/pure/pref";
+import { Extension } from "@pistonite/skybook-extension-api";
+import { useApplicationStore } from "./store";
+
+
+/** Running instances of extensions */
+const instances: Extension[] = [];
+
+export const initExtensionManager = () => {
+ const store = useApplicationStore;
+ store.subscribe((curr, prev) => {
+ if (prev.script !== curr.script) {
+ instances.forEach((x) => {
+ void x.onScriptChanged(curr.script);
+ });
+ }
+ });
+}
+
+/**
+ * Registers an extension as running and connect it to the app.
+ *
+ * Returns a function to disconnect the extension from the app.
+ */
+export const connectExtensionToApp = (extension: Extension): () => void => {
+ const unsubscribeDark = addDarkSubscriber((x) => {
+ void extension.onDarkModeChanged(x);
+ }, true);
+ const unsubscribeLocale = addLocaleSubscriber((x) => {
+ void extension.onLocaleChanged(x);
+ }, true);
+ void extension.onScriptChanged(useApplicationStore.getState().script);
+ instances.push(extension);
+ return () => {
+ const index = instances.indexOf(extension);
+ if (index >= 0) {
+ instances.splice(index, 1);
+ }
+ unsubscribeLocale();
+ unsubscribeDark();
+ }
+}
+
+export const openExtensionPopup = (id: string) => {
+ console.error("Not implemented", id);
+}
diff --git a/packages/app/src/application/extensionStore.ts b/packages/app/src/application/extensionStore.ts
new file mode 100644
index 0000000..a32564a
--- /dev/null
+++ b/packages/app/src/application/extensionStore.ts
@@ -0,0 +1,203 @@
+import { create } from "zustand";
+import { persist } from "zustand/middleware";
+import { openExtensionPopup } from "./extensionManager";
+import { createSelector } from "reselect";
+import { isLessProductive } from "ui/platform";
+
+export const ExtensionIds = ["editor", "stub1", "stub2"] as const;
+// Use the sort index to display the extensions in a deterministic order
+const ExtensionIdToSortIndex: Record = (() => {
+ const result: Record = {};
+ ExtensionIds.forEach((id, index) => {
+ result[id] = index;
+ });
+ return result;
+})();
+
+export type ExtensionStore = {
+ /**
+ * Ids of the extensions in the primary slot
+ */
+ primaryIds: string[];
+
+ /**
+ * Ids of the extensions in the secondary slot
+ */
+ secondaryIds: string[];
+
+ currentPrimary: string;
+
+ currentSecondary: string;
+
+ /**
+ * Set the open preference for the extension with the id
+ */
+ // setExtensionPreference(id: string, preference: "primary" | "secondary" | "none"): void;
+
+ /**
+ * Open an extension in the primary or secondary slot, optionally
+ * update the open mode for the extension for the future
+ */
+ open: (id: string, slot: "primary" | "secondary", updateOpenMode?: boolean) => void;
+
+ /**
+ * Update the open mode for the extension with the id
+ */
+ updateOpenMode: (id: string, openMode: ExtensionOpenMode) => void;
+
+ /**
+ * Close the primary extension window
+ */
+ closePrimary: () => void;
+
+ /**
+ * Close the secondary extension window
+ */
+ closeSecondary: () => void;
+}
+
+export type ExtensionOpenMode = "primary" | "secondary" | "popout";
+
+export const useExtensionStore = create()((set) => ({
+ primaryIds: ["editor", "stub2"],
+ secondaryIds: ["stub1"],
+ currentPrimary: "editor",
+ currentSecondary: "stub1",
+
+ open: (id: string, slot: "primary" | "secondary", updateOpenMode = false) => {
+ set(({primaryIds, secondaryIds}) => {
+ const newState: Partial = { };
+ if (slot === "primary") {
+ newState.currentPrimary = id;
+ if (updateOpenMode) {
+ if (secondaryIds.includes(id)) {
+ newState.secondaryIds = secondaryIds.filter((i) => i !== id);
+ }
+ if (!primaryIds.includes(id)) {
+ newState.primaryIds = [...primaryIds, id];
+ }
+ }
+ } else {
+ newState.currentSecondary = id;
+ if (updateOpenMode) {
+ if (primaryIds.includes(id)) {
+ newState.primaryIds = primaryIds.filter((i) => i !== id);
+ }
+ if (!secondaryIds.includes(id)) {
+ newState.secondaryIds = [...secondaryIds, id];
+ }
+ }
+ }
+ return newState;
+ });
+ },
+
+ updateOpenMode: (id: string, openMode: ExtensionOpenMode) => {
+ set(({primaryIds, secondaryIds}) => {
+ const newState: Partial = { };
+ if (openMode === "primary") {
+ if (secondaryIds.includes(id)) {
+ newState.secondaryIds = secondaryIds.filter((i) => i !== id);
+ }
+ if (!primaryIds.includes(id)) {
+ newState.primaryIds = [...primaryIds, id];
+ }
+ } else if (openMode === "secondary") {
+ newState.currentSecondary = id;
+ if (primaryIds.includes(id)) {
+ newState.primaryIds = primaryIds.filter((i) => i !== id);
+ }
+ if (!secondaryIds.includes(id)) {
+ newState.secondaryIds = [...secondaryIds, id];
+ }
+ } else {
+ if (primaryIds.includes(id)) {
+ newState.primaryIds = primaryIds.filter((i) => i !== id);
+ }
+ if (secondaryIds.includes(id)) {
+ newState.secondaryIds = secondaryIds.filter((i) => i !== id);
+ }
+ }
+ return newState;
+ });
+ },
+
+ closePrimary: () => {
+ set({currentPrimary: ""});
+ },
+
+ closeSecondary: () => {
+ set({currentSecondary: ""});
+ }
+
+}));
+// ,{
+// name: "Skybook.Extensions",
+// version: 1,
+// }));
+//
+
+export const useAllExtensionIds = () => {
+ return ExtensionIds;
+}
+
+const getAllNonPopoutExtensionIds = createSelector([
+ (state: ExtensionStore) => state.primaryIds,
+ (state: ExtensionStore) => state.secondaryIds
+], (p, s) => {
+ return sortExtensionIds([...p, ...s]);
+ });
+export const useAllNonPopoutExtensionIds = () => {
+ return useExtensionStore(getAllNonPopoutExtensionIds);
+}
+
+const getPrimaryExtensionIds = createSelector([
+ (state: ExtensionStore) => state.primaryIds
+], (p) => {
+ return sortExtensionIds([...p]);
+});
+export const usePrimaryExtensionIds = () => {
+ return useExtensionStore(getPrimaryExtensionIds);
+}
+
+const getSecondaryExtensionIds = createSelector([
+ (state: ExtensionStore) => state.secondaryIds
+], (s) => {
+ return sortExtensionIds([...s]);
+});
+export const useSecondaryExtensionIds = () => {
+ return useExtensionStore(getSecondaryExtensionIds);
+}
+
+const sortExtensionIds = (ids: string[]): string[] => {
+ // toSorted
+ return ids.sort((a, b) => {
+ const aIndex = a in ExtensionIdToSortIndex ? ExtensionIdToSortIndex[a] : 9999;
+ const bIndex = b in ExtensionIdToSortIndex ? ExtensionIdToSortIndex[b] : 9999;
+ return aIndex - bIndex;
+ });
+}
+
+export const useCurrentPrimaryExtensionId = () => {
+ return useExtensionStore((state) => state.currentPrimary);
+}
+
+const getSecondaryExtensionId = createSelector([
+ (state: ExtensionStore) => state.currentSecondary,
+], (id) => {
+ // don't show secondary extension if on less productive platform
+ return isLessProductive ? "" : id;
+});
+export const useCurrentSecondaryExtensionId = () => {
+ return useExtensionStore(getSecondaryExtensionId);
+}
+
+const getIsShowingSecondaryExtension = createSelector([
+ (state: ExtensionStore) => state.currentPrimary,
+ getSecondaryExtensionId
+], (p, s) => {
+ return p || s;
+});
+export const useIsShowingExtensionPanel = () => {
+ return useExtensionStore(getIsShowingSecondaryExtension);
+}
diff --git a/packages/app/src/application/store.ts b/packages/app/src/application/store.ts
new file mode 100644
index 0000000..04fa6b9
--- /dev/null
+++ b/packages/app/src/application/store.ts
@@ -0,0 +1,12 @@
+import { create } from "zustand";
+import { persist } from "zustand/middleware";
+
+export type ApplicationStore = {
+ script: string;
+}
+
+export const useApplicationStore = create()(persist((set)=>({
+ script: "",
+}), {
+ name: "Skybook.Application",
+ }))
diff --git a/packages/app/src/application/useApplication.ts b/packages/app/src/application/useApplication.ts
new file mode 100644
index 0000000..f5a966a
--- /dev/null
+++ b/packages/app/src/application/useApplication.ts
@@ -0,0 +1,8 @@
+import { createContext, useContext } from "react";
+import { Application } from "@pistonite/skybook-extension-api";
+
+export const ApplicationContext = createContext({} as unknown as Application);
+
+export const useApplication = () => {
+ return useContext(ApplicationContext);
+}
diff --git a/packages/app/src/extensions/ExtensionWindow.tsx b/packages/app/src/extensions/ExtensionWindow.tsx
new file mode 100644
index 0000000..79479c0
--- /dev/null
+++ b/packages/app/src/extensions/ExtensionWindow.tsx
@@ -0,0 +1,78 @@
+import { Dropdown, makeStyles, Option } from "@fluentui/react-components";
+import { useQuery } from "@tanstack/react-query";
+
+import { useUITranslation } from "skybook-localization";
+
+import { getExtensionComponent } from "./registry";
+import { connectExtensionToApp } from "application/extensionManager";
+
+export type ExtensionWindowProps = {
+ primary: boolean;
+ ids: string[];
+ currentId: string;
+ onSelect: (id: string) => void;
+}
+
+const useStyles = makeStyles({
+ container: {
+ display: "flex",
+ flexDirection: "column",
+ height: "100%",
+ },
+ extension: {
+ flex: 1,
+ }
+});
+
+export const ExtensionWindow: React.FC = ({ primary, ids, currentId, onSelect }) => {
+ const t = useUITranslation();
+ const styles = useStyles();
+ return (
+
+
{
+ console.log(optionValue)
+ }}
+ >
+ {
+ ids.map((id, i) => (
+ {t(`extension.${id}.name`)}
+ ))
+ }
+
+ {
+ ids.map((id, i) => (
+
+
+
+ ))
+ }
+
+ );
+
+}
+
+
+export type ExtensionWrapperProps = {
+ id: string;
+}
+
+export const ExtensionWrapper: React.FC = ({ id }) => {
+ const {isPending, data: ExtComp } = useQuery({
+ queryKey: ["extension", id],
+ queryFn: () => {
+ return getExtensionComponent(id);
+ },
+ });
+ if (isPending || !ExtComp) {
+ return Loading...
+ }
+ return ;
+}
diff --git a/packages/app/src/extensions/Stub1.tsx b/packages/app/src/extensions/Stub1.tsx
new file mode 100644
index 0000000..02e6792
--- /dev/null
+++ b/packages/app/src/extensions/Stub1.tsx
@@ -0,0 +1,2 @@
+
+export const makeStub = (id: number) => () => Stub {id}
;
diff --git a/packages/app/src/extensions/Wrapper.tsx b/packages/app/src/extensions/Wrapper.tsx
new file mode 100644
index 0000000..bfea5f2
--- /dev/null
+++ b/packages/app/src/extensions/Wrapper.tsx
@@ -0,0 +1,19 @@
+import { useQuery } from "@tanstack/react-query";
+import { getExtensionComponent } from "./registry";
+
+export type ExtensionWrapperProps = {
+ id: string;
+}
+
+export const ExtensionWrapper: React.FC = ({ id }) => {
+ const {isPending, data: ExtComp } = useQuery({
+ queryKey: ["extension", id],
+ queryFn: () => {
+ return getExtensionComponent(id);
+ },
+ });
+ if (isPending || !ExtComp) {
+ return Loading...
+ }
+ return ;
+}
diff --git a/packages/app/src/extensions/editor/EditorComponent.tsx b/packages/app/src/extensions/editor/EditorComponent.tsx
new file mode 100644
index 0000000..4a2b4ca
--- /dev/null
+++ b/packages/app/src/extensions/editor/EditorComponent.tsx
@@ -0,0 +1,40 @@
+// import { useEffect } from "react";
+
+import type { ExtensionComponentProps } from "../types.ts"
+import { initLanguage } from "./Language.ts"
+import { CodeEditor } from "@pistonite/intwc";
+import { EditorExtension } from "./editor.ts";
+import { useApplication } from "application/useApplication.ts";
+
+
+const FILE = "script.skyb";
+
+
+export const EditorComponent: React.FC = ({
+ standalone, connect
+}) => {
+ const app = useApplication();
+ initLanguage();
+ // useEffect(() => {
+ // }, []);
+ return (
+ {
+ const unsubscribeEditor = editor.subscribe((filename) => {
+ if (filename !== FILE) {
+ return;
+ }
+ void app.setScript(editor.getFileContent(FILE));
+ });
+ const instance = new EditorExtension(FILE, standalone, editor);
+ const disconnect = connect(instance);
+ console.log("EditorComponent: onCreated");
+ return () => {
+ unsubscribeEditor();
+ disconnect();
+ };
+ }}
+ />
+ );
+}
diff --git a/packages/app/src/extensions/editor/Language.ts b/packages/app/src/extensions/editor/Language.ts
new file mode 100644
index 0000000..6b360b4
--- /dev/null
+++ b/packages/app/src/extensions/editor/Language.ts
@@ -0,0 +1,79 @@
+import { initCodeEditor, LanguageConfiguration, LanguageTokenizer } from "@pistonite/intwc";
+
+let initialized = false;
+
+export const initLanguage = () => {
+ if (initialized) {
+ return;
+ }
+ initialized = true;
+ initCodeEditor({
+ language: {
+ custom: [
+ {
+ getId: () => "skyb",
+ getExtensions: () => [".skyb"],
+ getTokenizer: () => language,
+ getConfiguration: () => configuration,
+ }
+ ]
+ }
+ });
+}
+
+export const configuration: LanguageConfiguration = {
+ comments: {
+ lineComment: "#",
+ },
+
+ brackets: [
+ ["{", "}"],
+ ["[", "]"],
+ ["(", ")"],
+ ["<", ">"],
+ ],
+ autoClosingPairs: [
+ { open: '{', close: '}' },
+ { open: '[', close: ']' },
+ { open: '(', close: ')' },
+ { open: '<', close: '>' },
+ { open: '"', close: '"', notIn: ['string'] },
+ ],
+}
+
+export const language: LanguageTokenizer = {
+ defaultToken: 'invalid',
+ tokenPostfix: '.skyb',
+
+ commands: [
+ "init"
+ ],
+ supercommands: [],
+ annotations: [],
+ keywords: [],
+
+ word: /[_a-zA-Z][-0-9a-zA-Z_]*/,
+
+ tokenizer: {
+ root: [
+ [/\s+/, "white"],
+ [/\/\/.*$/, "comment"],
+ [/#.*$/, "comment"],
+ [/[{}()[\]]/, "@brackets"],
+ [/[=:,;]/, "delimiter"],
+ [/(\d(_?\d)*)|(0x[\da-fA-F](_?[\da-fA-F])*)/, "number"],
+ [/<@word>/, "string.item.literal"],
+ [/"@word"/, "string.item.quoted"],
+ [/!@word/, "function.command.super"],
+ [/:@word/, "keyword.annotation"],
+ [/(true|false)/, "constant.language.boolean"],
+ [/@word/, {
+ cases: {
+ "@keywords": "keyword",
+ "@commands": "function.command",
+ "@default": "string.item",
+ }
+ }]
+ ]
+ }
+}
diff --git a/packages/app/src/extensions/editor/editor.ts b/packages/app/src/extensions/editor/editor.ts
new file mode 100644
index 0000000..b1622cb
--- /dev/null
+++ b/packages/app/src/extensions/editor/editor.ts
@@ -0,0 +1,33 @@
+import { CodeEditorApi } from "@pistonite/intwc";
+import { setDark, setLocale } from "@pistonite/pure/pref";
+import { Extension } from "@pistonite/skybook-extension-api";
+import { WorkexPromise } from "workex";
+
+
+export class EditorExtension implements Extension {
+
+ constructor(
+ private scriptFile: string,
+ private standalone: boolean, private editor: CodeEditorApi) {
+ }
+ public async onDarkModeChanged(dark: boolean): WorkexPromise {
+ if (this.standalone) {
+ setDark(dark);
+ }
+ return {};
+ }
+ public async onLocaleChanged(locale: string): WorkexPromise {
+ if (this.standalone) {
+ setLocale(locale);
+ }
+ return {};
+ }
+ public async onScriptChanged(script: string): WorkexPromise {
+ if (!this.editor.getFiles().includes(this.scriptFile)) {
+ this.editor.openFile(this.scriptFile, script, "skyb");
+ } else {
+ this.editor.setFileContent(this.scriptFile, script);
+ }
+ return {};
+ }
+}
diff --git a/packages/app/src/extensions/registry.ts b/packages/app/src/extensions/registry.ts
new file mode 100644
index 0000000..7794ea5
--- /dev/null
+++ b/packages/app/src/extensions/registry.ts
@@ -0,0 +1,17 @@
+import { makeStub } from "./Stub1.tsx";
+import type { ExtensionComponentProps } from "./types.ts";
+
+
+export const getExtensionComponent = async (id: string): Promise | undefined> => {
+ switch (id) {
+ case "editor":
+ return (await import("./editor/EditorComponent.tsx")).EditorComponent;
+ case "stub1":
+ return makeStub(1);
+ case "stub2":
+ return makeStub(2);
+
+ }
+
+ return undefined;
+}
diff --git a/packages/app/src/extensions/types.ts b/packages/app/src/extensions/types.ts
new file mode 100644
index 0000000..3dfd5f0
--- /dev/null
+++ b/packages/app/src/extensions/types.ts
@@ -0,0 +1,23 @@
+import { Extension } from "@pistonite/skybook-extension-api"
+
+export type ExtensionComponentProps = {
+ /**
+ * If the extension is loaded as part of the app,
+ * or in its standalone window
+ */
+ standalone: boolean;
+
+ /**
+ * Callback to connect the extension to the app, once it's ready
+ */
+ connect: (ext: Extension) => () => void;
+}
+
+export type ExtensionComponent = React.ComponentType
+
+export type ExtensionMetadata = {
+ //type: "builtin";
+ id: string;
+
+ render: React.ComponentType;
+}
diff --git a/packages/app/src/icon.svg b/packages/app/src/icon.svg
new file mode 100644
index 0000000..774d16a
--- /dev/null
+++ b/packages/app/src/icon.svg
@@ -0,0 +1 @@
+
diff --git a/packages/app/src/main.tsx b/packages/app/src/main.tsx
new file mode 100644
index 0000000..db87b35
--- /dev/null
+++ b/packages/app/src/main.tsx
@@ -0,0 +1,74 @@
+import { StrictMode } from 'react'
+import { createRoot } from 'react-dom/client'
+import App from './App.tsx'
+import { ThemeProvider } from './theme/ThemeProvider.tsx'
+import { initDark } from '@pistonite/pure/pref'
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
+import { initI18n } from 'skybook-localization'
+import { initExtensionManager } from './application/extensionManager.ts'
+import { initRuntime } from 'runtime/init.ts'
+import { ApplicationApi } from 'application/api.ts'
+import { ApplicationProvider } from 'application/ApplicationProvider.tsx'
+import { initNarrow } from 'pure-contrib/narrow.ts'
+import { isLessProductive } from 'ui/platform.ts'
+
+async function boot() {
+ const root = document.getElementById('-root-') as HTMLDivElement;
+ if (isLessProductive) {
+ // window.setStatus
+ // await new Promise((resolve) => {
+ // const button = document.createElement('button');
+ // button.innerText = 'fullscreen' + window.innerWidth;
+ // button.onclick = async () => {
+ // // document.body.style.height = 'calc ( 100vh + 1px )';
+ // // document.body.style.overflow = 'visible';
+ // // root.style.height = 'calc ( 100vh + 1px )';
+ // // window.scrollTo(0, 100);
+ // await document.body.requestFullscreen({
+ // navigationUI: "hide"});
+ // resolve();
+ // };
+ // root.appendChild(button);
+ // });
+ initNarrow({
+ threshold: 800,
+ override: (narrow) => {
+ if (window.innerWidth < window.innerHeight) {
+ return true;
+ }
+ if (narrow && window.innerHeight < window.innerWidth) {
+ return false;
+ }
+ return narrow;
+ },
+ });
+ } else {
+ initNarrow({
+ threshold: 800,
+ });
+ }
+ initDark({
+ persist: false,
+ });
+ await initI18n();
+ initExtensionManager();
+ const queryClient = new QueryClient();
+
+ const runtime = await initRuntime();
+
+ const app = new ApplicationApi();
+
+
+ createRoot(root).render(
+
+
+
+
+
+
+
+
+ ,
+ )
+}
+void boot()
diff --git a/packages/app/src/pure-contrib/narrow.ts b/packages/app/src/pure-contrib/narrow.ts
new file mode 100644
index 0000000..0e4eca4
--- /dev/null
+++ b/packages/app/src/pure-contrib/narrow.ts
@@ -0,0 +1,71 @@
+import { cell } from "@pistonite/pure/sync";
+import { useSyncExternalStore } from "react";
+
+const narrow = cell({ initial: false });
+
+/** Options for narrow mode detection */
+export type NarrowOptions = {
+ /**
+ * Width threshold to start displaying the app in narrow mode
+ */
+ threshold: number;
+
+ /**
+ * A function called to override the detected value
+ */
+ override?: (detected: boolean) => boolean;
+
+ /**
+ * Set the initial value, if the platform doesn't support detecting
+ * viewport width.
+ */
+ initial?: boolean;
+};
+
+/**
+ * Initialize narrow mode detection
+ *
+ * Note that this is not necessary in some simple use cases. For example,
+ * adjusting styles based on the viewport width can be done with CSS:
+ * ```css
+ * @media screen and (max-width: 800px) {
+ * /* styles for narrow mode * /
+ * }
+ * ```
+ *
+ * Use this only if narrow mode needs to be detected programmatically.
+ */
+export const initNarrow = (options: NarrowOptions) => {
+ const threshold = options.threshold;
+ const override = options.override;
+ if (window && window.addEventListener && window.innerWidth !== undefined) {
+ const callback =
+ () => {
+ const newNarrow = window.innerWidth < threshold;
+ if (override) {
+ narrow.set(override(newNarrow));
+ } else {
+ narrow.set(newNarrow);
+ }
+ }
+ window.addEventListener("resize", callback);
+ callback();
+ } else if (options.initial !== undefined) {
+ narrow.set(options.initial);
+ }
+};
+
+/** Subscribe to narrow mode changes */
+export const addNarrowSubscriber = (subscriber: (narrow: boolean) => void, notifyImmediately?: boolean) => {
+ return narrow.subscribe(subscriber, notifyImmediately);
+}
+
+/** Check if the app is in narrow mode */
+export const isNarrow = (): boolean => {
+ return narrow.get();
+}
+
+/** React hook to use narrow mode detection */
+export const useNarrow = () => {
+ return useSyncExternalStore(addNarrowSubscriber, isNarrow);
+}
diff --git a/packages/app/src/pure-contrib/platform.ts b/packages/app/src/pure-contrib/platform.ts
new file mode 100644
index 0000000..30e8224
--- /dev/null
+++ b/packages/app/src/pure-contrib/platform.ts
@@ -0,0 +1,20 @@
+import { cell } from "@pistonite/pure/sync";
+
+import { isMobile, isSmartTV, isWearable } from "mobile-device-detect";
+
+const lessProductive = cell({ initial: isMobile || isSmartTV || isWearable })
+
+export type PlatformOptions = {
+ /** Width threshold to start displaying the app in narrow mode */
+ narrowModeThreadhold: number;
+};
+
+
+export const initPlatform = async (options: PlatformOptions) => {}
+
+/**
+ * Detect if the platform is less productive than the conventional
+ * KVM setup - for example, mobile, tablet, wearable, etc.
+ */
+export const isLessProductive= (): boolean => {
+}
diff --git a/packages/app/src/runtime/.gitignore b/packages/app/src/runtime/.gitignore
new file mode 100644
index 0000000..f9cee21
--- /dev/null
+++ b/packages/app/src/runtime/.gitignore
@@ -0,0 +1,3 @@
+# workex generated files
+/interfaces/
+/sides/
diff --git a/packages/app/src/runtime/init.ts b/packages/app/src/runtime/init.ts
new file mode 100644
index 0000000..cedc28b
--- /dev/null
+++ b/packages/app/src/runtime/init.ts
@@ -0,0 +1,12 @@
+import { RuntimeApiClient } from "./interfaces/RuntimeApi.send.ts";
+import RuntimeWorker from "./worker.ts?worker";
+
+/**
+ * Initialize the simulator runtime and make sure it's ready
+ */
+export async function initRuntime() {
+ const worker = new RuntimeWorker();
+ const runtime = new RuntimeApiClient({worker});
+ await runtime.handshake().established();
+ return runtime;
+}
diff --git a/packages/app/src/runtime/protocol.ts b/packages/app/src/runtime/protocol.ts
new file mode 100644
index 0000000..ff9f612
--- /dev/null
+++ b/packages/app/src/runtime/protocol.ts
@@ -0,0 +1,16 @@
+import { WorkexPromise } from "workex";
+
+/**
+ * API provided by the simulator runtime
+ *
+ * @workex:send app
+ * @workex:recv runtime
+ */
+export interface RuntimeApi {
+
+ /**
+ * Set the script for the runtime, which starts executing
+ * the script immediately
+ */
+ setScript(script: string): WorkexPromise;
+}
diff --git a/packages/app/src/runtime/worker.ts b/packages/app/src/runtime/worker.ts
new file mode 100644
index 0000000..908f58c
--- /dev/null
+++ b/packages/app/src/runtime/worker.ts
@@ -0,0 +1,21 @@
+// import wasmUrl from "skybook-runtime-wasm/skybook_runtime_wasm_bg.wasm?url";
+import { parse_script } from "skybook-runtime-wasm";
+
+import { Delegate, hostFromDelegate } from "workex";
+
+import { bindRuntimeApiHost } from "./interfaces/RuntimeApi.recv";
+import { RuntimeApi } from "./protocol.ts";
+
+async function boot() {
+
+ const api = {
+ setScript: async (script) => {
+ return parse_script(script);
+ },
+ } satisfies Delegate;
+
+ const handshake = bindRuntimeApiHost(hostFromDelegate(api), { worker: self });
+ await handshake.initiate();
+}
+
+void boot();
diff --git a/packages/app/src/theme/ThemeProvider.tsx b/packages/app/src/theme/ThemeProvider.tsx
new file mode 100644
index 0000000..d798c77
--- /dev/null
+++ b/packages/app/src/theme/ThemeProvider.tsx
@@ -0,0 +1,23 @@
+import { FluentProvider, makeStyles, webDarkTheme, webLightTheme } from "@fluentui/react-components";
+import { useDark } from "@pistonite/pure-react";
+import type { PropsWithChildren } from "react";
+
+
+// const useStyles = makeStyles({
+// root: {
+// width: "100%",
+// height: "100%",
+// }
+// });
+
+export const ThemeProvider: React.FC = ({ children }) => {
+ const dark = useDark();
+ console.log("dark", dark);
+ // const styles = useStyles();
+ const theme = dark ? webDarkTheme : webLightTheme;
+ return (
+
+ {children}
+
+ );
+}
diff --git a/packages/app/src/ui/ExtensionOpenButton.tsx b/packages/app/src/ui/ExtensionOpenButton.tsx
new file mode 100644
index 0000000..bc31688
--- /dev/null
+++ b/packages/app/src/ui/ExtensionOpenButton.tsx
@@ -0,0 +1,93 @@
+import { Text, Button, Dialog, DialogActions, DialogBody, DialogContent, DialogSurface, DialogTitle, DialogTrigger, Tooltip, Field, Combobox, RadioGroup, Radio, Checkbox } from "@fluentui/react-components";
+import { WindowDevTools20Regular } from "@fluentui/react-icons";
+import { ExtensionOpenMode } from "application/extensionStore";
+import { useNarrow } from "pure-contrib/narrow";
+import { useState } from "react";
+import { useUITranslation } from "skybook-localization";
+import { isLessProductive } from "./platform";
+
+export const ExtensionOpenButton: React.FC = () => {
+ const t = useUITranslation();
+
+ const narrow = useNarrow();
+
+ const [selectedId, setSelectedId] = useState("");
+ const [selectedOpenMode, setSelectedOpenMode] = useState("secondary");
+ const [isPersistChecked, setIsPersistChecked] = useState(true);
+
+ let displayedOpenMode = selectedOpenMode;
+ const secondaryAvailable = !narrow && !isLessProductive;
+ if (!secondaryAvailable && selectedOpenMode === "secondary") {
+ displayedOpenMode = "primary";
+ }
+
+
+ return (
+
+
+
+ }
+ appearance="subtle"
+ />
+
+
+
+
+ {t("dialog.extensions.title")}
+
+ {t("dialog.extensions.desc")}
+
+
+
+
+ {
+ setSelectedOpenMode(value as ExtensionOpenMode);
+ }}>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Close
+
+ Do Something
+
+
+
+
+ );
+};
diff --git a/packages/app/src/ui/ExtensionPanel.tsx b/packages/app/src/ui/ExtensionPanel.tsx
new file mode 100644
index 0000000..531fef2
--- /dev/null
+++ b/packages/app/src/ui/ExtensionPanel.tsx
@@ -0,0 +1,92 @@
+import { memo } from "react";
+import { ExtensionTitlebar, ExtensionTitlebarMobile } from "./ExtensionTitlebar";
+import { isLessProductive } from "./platform";
+import { makeStyles } from "@fluentui/react-components";
+import { useCurrentPrimaryExtensionId, useCurrentSecondaryExtensionId, usePrimaryExtensionIds, useSecondaryExtensionIds } from "application/extensionStore";
+import { ExtensionWrapper } from "extensions/ExtensionWindow";
+import { useUIStore } from "./store";
+import { ResizeLayout } from "./components/ResizeLayout";
+
+const useStyles = makeStyles({
+ container: {
+ flex: 1,
+ display: "flex",
+ flexDirection: "column",
+ },
+ main: {
+ flex: 1,
+ },
+ extensionWindow: {
+ width: "100%",
+ height: "100%",
+ },
+});
+
+const ExtensionPanelConnected: React.FC = () => {
+ const styles = useStyles();
+ const primaryIds = usePrimaryExtensionIds();
+ const secondaryIds = useSecondaryExtensionIds();
+ const currentPrimaryId = useCurrentPrimaryExtensionId();
+ const currentSecondaryId = useCurrentSecondaryExtensionId();
+
+ const primaryExtensionWindowPercentage = useUIStore(state => state.primaryExtensionWindowPercentage);
+ const setPrimaryExtensionWindowPercentage = useUIStore(state => state.setPrimaryExtensionWindowPercentage);
+
+ const primaryWindow = (
+ primaryIds.map((id, i) => (
+
+
+
+ ))
+ );
+ const secondaryWindow = (
+ secondaryIds.map((id, i) => (
+
+
+
+ ))
+ );
+ const hasTwoWindows = currentPrimaryId && currentSecondaryId;
+ return (
+
+ {
+ isLessProductive ?
+
+ :
+
+ }
+
+ {
+ !hasTwoWindows && primaryWindow
+ }
+ {
+ !hasTwoWindows && secondaryWindow
+ }
+ {
+ hasTwoWindows && (
+
+
+ {primaryWindow}
+
+
+ {secondaryWindow}
+
+
+
+ )
+ }
+
+
+ );
+};
+
+export const ExtensionPanel = memo(ExtensionPanelConnected);
diff --git a/packages/app/src/ui/ExtensionTitlebar.tsx b/packages/app/src/ui/ExtensionTitlebar.tsx
new file mode 100644
index 0000000..83c98a9
--- /dev/null
+++ b/packages/app/src/ui/ExtensionTitlebar.tsx
@@ -0,0 +1,134 @@
+import { Divider, makeStyles } from "@fluentui/react-components";
+import { useAllNonPopoutExtensionIds, useCurrentPrimaryExtensionId, useCurrentSecondaryExtensionId, useExtensionStore, usePrimaryExtensionIds, useSecondaryExtensionIds } from "application/extensionStore";
+import { ExtensionToolbar } from "./components/ExtensionToolbar";
+import { openExtensionPopup } from "application/extensionManager";
+import { ExtensionOpenButton } from "./ExtensionOpenButton";
+import { memo, useEffect, useState } from "react";
+import { isLessProductive } from "./platform";
+
+const useStyles = makeStyles({
+ bar: {
+ display: "flex",
+ flexDirection: "row",
+ gap: "4px",
+ },
+ divider: {
+ maxWidth: "2px",
+ }
+});
+
+const ExtensionTitlebarConnected: React.FC = () => {
+ const styles = useStyles();
+
+ const currentPrimaryId = useCurrentPrimaryExtensionId();
+ const currentSecondaryId = useCurrentSecondaryExtensionId();
+ const primaryIds = usePrimaryExtensionIds();
+ const secondaryIds = useSecondaryExtensionIds();
+ const openExtension = useExtensionStore(state => state.open);
+ const closePrimary = useExtensionStore(state => state.closePrimary);
+ const closeSecondary = useExtensionStore(state => state.closeSecondary);
+
+ const [barRef, setBarRef] = useState(null);
+ const [isNarrowLayout, setIsNarrowLayout] = useState(false);
+
+ useEffect(() => {
+ if (!barRef) {
+ return;
+ }
+ const observer = new ResizeObserver(() => {
+ const {width} = barRef.getBoundingClientRect();
+ setIsNarrowLayout(width<660);
+ });
+ observer.observe(barRef);
+ return () => observer.disconnect();
+ }, [barRef]);
+
+ const primaryToolbar =
+ currentPrimaryId && (
+ {
+ openExtensionPopup(currentPrimaryId);
+ closePrimary();
+ }}
+ onSelect={(id) => {
+ openExtension(id, "primary");
+ }}
+ />
+ );
+
+ const secondaryToolbar =
+ currentSecondaryId && (
+ {
+ openExtensionPopup(currentSecondaryId);
+ closeSecondary();
+ }}
+ onSelect={(id) => {
+ openExtension(id, "secondary");
+ }}
+ onClickClose={closeSecondary}
+ />);
+
+ const twoLine = isNarrowLayout && currentPrimaryId && currentSecondaryId;
+ if (twoLine) {
+ return (
+
+
+ {primaryToolbar}
+
+
+ {secondaryToolbar}
+
+ );
+ }
+
+ return (
+
+ {primaryToolbar}
+ {
+ currentPrimaryId && currentSecondaryId && (
+
+ )
+ }
+ {secondaryToolbar}
+ {
+ currentPrimaryId && currentSecondaryId && (
+
+ )
+ }
+
+
+ );
+
+};
+
+export const ExtensionTitlebar = memo(ExtensionTitlebarConnected);
+
+/** Titlebar for mobile platform with simplified controls */
+const ExtensionTitlebarMobileConnected: React.FC = () => {
+ const styles = useStyles();
+
+ const allIds = useAllNonPopoutExtensionIds();
+ const currentId = useCurrentPrimaryExtensionId();
+ const openExtension = useExtensionStore(state => state.open);
+
+
+ return (
+
+ {
+ openExtension(id, "primary");
+ }}
+ fullWidth
+ />
+
+ );
+};
+
+export const ExtensionTitlebarMobile = memo(ExtensionTitlebarMobileConnected);
diff --git a/packages/app/src/ui/components/ExtensionToolbar.tsx b/packages/app/src/ui/components/ExtensionToolbar.tsx
new file mode 100644
index 0000000..a7b4034
--- /dev/null
+++ b/packages/app/src/ui/components/ExtensionToolbar.tsx
@@ -0,0 +1,125 @@
+import { Button, Dropdown, Option, Tooltip, makeStyles, mergeClasses } from "@fluentui/react-components";
+import { Dismiss20Regular, WindowNew20Regular } from "@fluentui/react-icons";
+
+import { useUITranslation } from "skybook-localization";
+
+export type ExtensionToolbarProps = {
+ /** Id of the current opened extension */
+ id: string;
+
+ /**
+ * Id of all extensions selectable from this toolbar
+ *
+ * The options will be displayed using the `extension.${id}.name` translation
+ */
+ allIds: string[];
+
+ /**
+ * Callback when the pop out button is pressed
+ *
+ * If not provided, the pop out button will be hidden
+ */
+ onClickPopout?: () => void;
+
+ /**
+ * Callback when the close button is pressed
+ *
+ * If not provided, the close button will be hidden
+ */
+ onClickClose?: () => void;
+
+ /**
+ * Callback when an extension is selected from the drop down
+ *
+ * Will not be invoked if the current extension is selected again
+ * from the drop down
+ */
+ onSelect: (id: string) => void;
+
+ /**
+ * If enabled, will add flex: 1 to the container and dropdown container
+ * so it's full width in the flex box parent
+ */
+ fullWidth?: boolean;
+};
+
+const useStyles = makeStyles({
+ container: {
+ display: "flex",
+ flexDirection: "row",
+ gap: "4px",
+ },
+ fullWidth: {
+ flex: 1,
+ },
+ selectorButton: {
+ // truncate text
+ overflowX: "hidden",
+ textOverflow: "ellipsis",
+ whiteSpace: "nowrap",
+ maxWidth: "200px",
+ }
+});
+
+export const ExtensionToolbar: React.FC = ({
+ id, allIds, onClickPopout, onClickClose, onSelect, fullWidth
+}) => {
+ const t = useUITranslation();
+ const styles = useStyles();
+ return (
+
+
+ {t(`extension.${id}.name`)}
+
+ }
+ selectedOptions={[id]}
+ onOptionSelect={(_, {optionValue}) => {
+ if (optionValue && optionValue !== id) {
+ onSelect(optionValue);
+ }
+ }}
+ >
+ {
+ allIds.map((id, i) => (
+
+
+ {t(`extension.${id}.name`)}
+
+
+ ))
+ }
+
+ { onClickPopout && (
+
+ }
+ appearance="subtle"
+ />
+ )
+ }
+ {
+ onClickClose && (
+
+ }
+ />
+
+ )
+ }
+
+
+ );
+};
diff --git a/packages/app/src/ui/components/ResizeLayout.tsx b/packages/app/src/ui/components/ResizeLayout.tsx
new file mode 100644
index 0000000..0ad7a17
--- /dev/null
+++ b/packages/app/src/ui/components/ResizeLayout.tsx
@@ -0,0 +1,222 @@
+import { Divider, makeStyles, mergeClasses, tokens } from "@fluentui/react-components";
+import { Children, useRef, useState, type PropsWithChildren } from "react";
+
+
+export type ResizeLayoutProps = {
+ /** If the resize layout should be horizontal or vertical */
+ vertical?: boolean;
+
+ /** The minimum pixel width of the first child */
+ minWidth?: number;
+
+ /** The minimum pixel height of the first child */
+ minHeight?: number;
+
+ /** The current percentage size of the first child */
+ valuePercent: number;
+
+ /** Callback to set the percentage size of the first child */
+ setValuePercent: (percent: number) => void;
+
+ /** If the resizing is disabled */
+ disabled?: boolean;
+
+ /** Use the natural size instead of valuePercent */
+ naturalSize?: boolean;
+
+ /** Optimize for touch screen */
+ touch?: boolean;
+} & Omit, "ref" | "onMouseUp" | "onMouseLeave">;
+
+const useStyles = makeStyles({
+ container: {
+ display: "flex",
+ },
+ containerVertical: {
+ flexDirection: "column",
+ },
+ containerHorizontal: {
+ flexDirection: "row",
+ },
+ childContainer: {
+ // needed to anchor drag handle with position: absolute
+ position: "relative",
+ },
+ secondChild: {
+ flex: 1,
+ },
+ dragHandle: {
+ position: "absolute",
+ transition: "background-color 0.2s",
+ },
+ dragHandleFirst: {
+ bottom: 0,
+ right: 0,
+ },
+ dragHandleSecond: {
+ top: 0,
+ left: 0,
+ },
+ dragHandleVertical: {
+ // for vertical resize, the handle itself is "horizontal"
+ width: "100%",
+ height: "3px",
+ cursor: "ns-resize",
+ },
+ dragHandleHorizontal: {
+ // for horizontal resize, the handle itself is "vertical"
+ width: "3px",
+ height: "100%",
+ cursor: "ew-resize",
+ },
+ dragHandleResizing: {
+ backgroundColor: "rgba(0, 0, 0, 0.1)",
+ zIndex: 10000,
+ },
+ // dragHandleVisible: {
+ // transition: "background-color 0.2s",
+ // display: "flex",
+ // },
+ dragHandleTouchVertical: {
+ height: "20px",
+ width: "100%",
+ },
+ dragHandleTouchHorizontal: {
+ width: "20px",
+ height: "100%",
+ },
+});
+
+/**
+ * A flex-box layout of 2 children, with a draggable divider between them.
+ */
+export const ResizeLayout: React.FC> = ({
+ vertical, valuePercent, setValuePercent, disabled, naturalSize, minWidth,
+ minHeight,
+ touch,
+ children, ...props
+}) => {
+ const [firstChild, secondChild] = Children.toArray(children);
+
+ const styles = useStyles();
+ const containerRef = useRef(null);
+ const firstRef = useRef(null);
+ // [startX, startY, startWidth, startHeight]
+ const [resizing, setResizing] = useState(undefined);
+
+ const startResize = (e: React.MouseEvent | React.TouchEvent) => {
+ if (disabled || !firstRef.current) {
+ return;
+ }
+ const coords = getEventClientCoords(e);
+ if (!coords) {
+ return;
+ }
+ try {
+ e.preventDefault();
+ e.stopPropagation();
+ } catch {
+ // prevent default will fail for touch events
+ }
+ const first = firstRef.current.getBoundingClientRect();
+ setResizing([coords.clientX, coords.clientY, first.width, first.height])
+ };
+
+ const handleResize = (e: React.MouseEvent | React.TouchEvent) => {
+ if (disabled || !resizing || !containerRef.current || !firstRef.current) {
+ return;
+ }
+ const coords = getEventClientCoords(e);
+ if (!coords) {
+ return;
+ }
+ const { width: containerWidth, height: containerHeight } = containerRef.current.getBoundingClientRect();
+ const [startX, startY, startWidth, startHeight] = resizing;
+ const deltaX = coords.clientX - startX;
+ const deltaY = coords.clientY - startY;
+ if (vertical) {
+ const newHeight = startHeight + deltaY;
+ setValuePercent((newHeight / containerHeight) * 100)
+ } else {
+ const newWidth = startWidth + deltaX;
+ setValuePercent((newWidth / containerWidth) * 100)
+ }
+ };
+ return (
+ { setResizing(undefined) }}
+ onMouseLeave={() => { setResizing(undefined) }}
+ onTouchEnd={() => { setResizing(undefined) }}
+ onMouseMove={handleResize}
+ onTouchMove={handleResize}
+ >
+
+ {firstChild}
+ {
+ !disabled && (
+
+ )
+ }
+
+
+ {
+ !disabled && (
+
+ )
+ }
+ {secondChild}
+
+
+ );
+};
+
+const getEventClientCoords = (e: React.TouchEvent | React.MouseEvent) => {
+ if ("touches" in e && e.touches[0]) {
+ const touch = e.touches[0];
+ return {
+ clientX: touch.clientX,
+ clientY: touch.clientY
+ };
+ }
+ if ("clientX" in e && "clientY" in e) {
+ return {
+ clientX: e.clientX,
+ clientY: e.clientY
+ };
+ }
+ return undefined;
+}
diff --git a/packages/app/src/ui/platform.ts b/packages/app/src/ui/platform.ts
new file mode 100644
index 0000000..e75a113
--- /dev/null
+++ b/packages/app/src/ui/platform.ts
@@ -0,0 +1,7 @@
+
+import { isMobile, isSmartTV, isWearable } from "mobile-device-detect";
+/**
+ * Detect if the platform is less productive than the conventional
+ * KVM setup - for example, mobile, tablet, wearable, etc.
+ */
+export const isLessProductive= isMobile || isSmartTV || isWearable;
diff --git a/packages/app/src/ui/store.ts b/packages/app/src/ui/store.ts
new file mode 100644
index 0000000..96878f9
--- /dev/null
+++ b/packages/app/src/ui/store.ts
@@ -0,0 +1,24 @@
+import { create } from "zustand";
+import { persist } from "zustand/middleware";
+
+export type UIStore = {
+ /** Percentage size of the extension panel */
+ extensionPanelPercentage: number;
+ setExtensionPanelPercentage: (percentage: number) => void;
+
+ /** Percentage size of the primary extension window */
+ primaryExtensionWindowPercentage: number;
+ setPrimaryExtensionWindowPercentage: (percentage: number) => void;
+};
+
+export const useUIStore = create()(persist((set) => ({
+ extensionPanelPercentage: 40,
+ setExtensionPanelPercentage: (percentage) => set({ extensionPanelPercentage: percentage }),
+
+ primaryExtensionWindowPercentage: 50,
+ setPrimaryExtensionWindowPercentage: (percentage) => set({ primaryExtensionWindowPercentage: percentage }),
+
+}),{
+ name: "Skybook.UI",
+ version: 1,
+ }));
diff --git a/packages/app/tsconfig.app.json b/packages/app/tsconfig.app.json
new file mode 100644
index 0000000..3ec77ac
--- /dev/null
+++ b/packages/app/tsconfig.app.json
@@ -0,0 +1,7 @@
+{
+ "extends": "../../config/tsconfig-vite-app.json",
+ "compilerOptions": {
+ "baseUrl": "src",
+ },
+ "include": ["src"]
+}
diff --git a/app/tsconfig.json b/packages/app/tsconfig.json
similarity index 100%
rename from app/tsconfig.json
rename to packages/app/tsconfig.json
diff --git a/packages/app/tsconfig.node.json b/packages/app/tsconfig.node.json
new file mode 100644
index 0000000..3dc1b02
--- /dev/null
+++ b/packages/app/tsconfig.node.json
@@ -0,0 +1,4 @@
+{
+ "extends": "../../config/tsconfig-tool.json",
+ "include": ["vite.config.ts"]
+}
diff --git a/packages/app/vite.config.ts b/packages/app/vite.config.ts
new file mode 100644
index 0000000..ff63811
--- /dev/null
+++ b/packages/app/vite.config.ts
@@ -0,0 +1,31 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+import yaml from "@modyfi/vite-plugin-yaml";
+import wasm from "vite-plugin-wasm";
+import topLevelAwait from "vite-plugin-top-level-await";
+import tsConfigPaths from "vite-tsconfig-paths";
+
+// import esbuildImportMetaUrlPlugin from "@codingame/esbuild-import-meta-url-plugin";
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [react(), tsConfigPaths(), yaml(), wasm(), topLevelAwait()],
+ worker: {
+ plugins: () => [yaml(), tsConfigPaths(),
+ wasm(), topLevelAwait()
+ ],
+ format: "iife",
+
+ },
+ resolve: {
+ dedupe: ["@pistonite/pure"]
+ }
+
+
+ // optimizeDeps: {
+ // esbuildOptions: {
+ // plugins: [esbuildImportMetaUrlPlugin]
+ // }
+ // }
+})
+
diff --git a/packages/blueflame-macros/Cargo.toml b/packages/blueflame-macros/Cargo.toml
new file mode 100644
index 0000000..3d86c76
--- /dev/null
+++ b/packages/blueflame-macros/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "blueflame-macros"
+version = "0.0.0"
+edition = "2021"
+description = "proc-macro crate for blueflame"
+
+[dependencies]
+
+[lib]
+proc-macro = true
diff --git a/packages/blueflame-macros/src/lib.rs b/packages/blueflame-macros/src/lib.rs
new file mode 100644
index 0000000..e69de29
diff --git a/packages/blueflame/Cargo.toml b/packages/blueflame/Cargo.toml
new file mode 100644
index 0000000..2de1b1c
--- /dev/null
+++ b/packages/blueflame/Cargo.toml
@@ -0,0 +1,15 @@
+[package]
+name = "blueflame"
+version = "0.0.0"
+edition = "2021"
+
+[dependencies]
+derive_more = { version = "1.0.0", features = ["constructor", "deref", "deref_mut"] }
+enumset = "1.1.5"
+rand_xoshiro = "0.6.0"
+sha2 = "0.10.8"
+thiserror = "2.0.9"
+
+[dependencies.uking-relocate-lib]
+git = "https://github.com/Pistonight/symbotw"
+rev = "57e51a922e4e3c83d13d97d6e183a32f0533113e"
diff --git a/packages/blueflame/src/boot.rs b/packages/blueflame/src/boot.rs
new file mode 100644
index 0000000..a584658
--- /dev/null
+++ b/packages/blueflame/src/boot.rs
@@ -0,0 +1,183 @@
+use std::sync::Arc;
+
+use uking_relocate_lib::singleton::{ObjType, Singleton, SingletonCreator};
+use uking_relocate_lib::{Env, Program};
+
+use crate::error::Error as CrateError;
+use crate::memory::{align_down, align_up, Memory, MemoryFlags, Proxies, Region, RegionType, SimpleHeap, PAGE_SIZE, REGION_ALIGN};
+use crate::processor::Processor;
+use crate::Core;
+
+/// Error that only happens during boot
+#[derive(Debug, Clone, thiserror::Error)]
+pub enum Error {
+ #[error("no PMDM singleton found in program image")]
+ NoPmdm,
+ #[error("PMDM address is impossible to satisfy: 0x{0:08x}")]
+ InvalidPmdmAddress(u64),
+ #[error("heap is too small: need at least {0} bytes")]
+ HeapTooSmall(u32),
+ #[error("region overlap: {0} and {1}")]
+ RegionOverlap(RegionType, RegionType),
+}
+
+
+/// Initialize memory for the process
+///
+/// Return the memory state after all singletons are created and initialized
+pub fn init_memory(
+ image: &Program,
+ stack_start: u64,
+ stack_size: u32,
+ pmdm_address: u64,
+ heap_size: u32,
+) -> Result<(Memory, Proxies), CrateError> {
+
+ // calculate heap start address
+ // we need the heap to be as small as possible,
+ // but the relative address of the singleton could be really big
+ // (e.g. a few GBs), so we need to adjust the heap start accordingly
+ //
+ // 0 heap_start s1 pmdm s2
+ // |<--heap_adjustment-->|
+ // |<----pmdm_rel_address--->|
+ // |<----------pmdm.rel_start--------------------->|
+ // |<----------min_rel_start------->|
+ // |<---------------------------max_rel_start--------------------->|
+ // |<------------------------pmdm_address------------------>|
+ // ||
+ //
+ // for any singleton:
+ // rel_start - heap_adjustment + heap_start = address
+ //
+ // heap_adjustment is positive and guarateed to be less than rel_start
+ // of any singleton
+ let pmdm = image.singleton_by_id(Singleton::PauseMenuDataMgr).ok_or(Error::NoPmdm)?;
+ if pmdm.rel_start as u64 > pmdm_address {
+ return Err(Error::InvalidPmdmAddress(pmdm_address).into());
+ }
+ let min_heap_start = pmdm_address - pmdm.rel_start as u64;
+ let min_rel_start = image.singletons().iter().map(|s| s.rel_start).min().unwrap_or_default();
+ let max_heap_start = min_heap_start + min_rel_start as u64;
+ let heap_start = align_down!(max_heap_start, REGION_ALIGN);
+ if heap_start < min_heap_start {
+ // somehow align down made it smaller
+ // maybe possible with some pmdm_address
+ return Err(Error::InvalidPmdmAddress(pmdm_address).into());
+ }
+ let heap_adjustment = heap_start - min_heap_start;
+
+ // calculate how much space will be needed for all the singletons
+ let max_rel_start = image.singletons().iter().map(|s| s.rel_start).max().unwrap_or_default();
+ let heap_end = min_heap_start + max_rel_start as u64;
+ // align up to the next page, and reserve 1 page for some spacing
+ let heap_singletons_end = align_up!(heap_end, PAGE_SIZE as u64) + PAGE_SIZE as u64;
+ let heap_singletons_size = (heap_singletons_end - heap_start) as u32;
+ // make the first alloc look random
+ let page_off_alloc_start = 0x428;
+ let heap_min_size = heap_singletons_size + page_off_alloc_start;
+ let heap_size = align_up!(heap_size, PAGE_SIZE);
+
+ if heap_size < heap_min_size {
+ return Err(Error::HeapTooSmall(heap_min_size).into());
+ }
+
+ // check the regions don't overlap before allocating memory
+ if overlaps(image.program_start, image.program_size, stack_start, stack_size) {
+ return Err(Error::RegionOverlap(RegionType::Program, RegionType::Stack).into());
+ }
+ if overlaps(image.program_start, image.program_size, heap_start, heap_size) {
+ return Err(Error::RegionOverlap(RegionType::Program, RegionType::Heap).into());
+ }
+ if overlaps(stack_start, stack_size, heap_start, heap_size) {
+ return Err(Error::RegionOverlap(RegionType::Stack, RegionType::Heap).into());
+ }
+
+ // construct the memory
+
+
+ let program_region = Arc::new(Region::new_program(
+ image.program_start,
+ image.program_size,
+ image.regions()).unwrap()); // TODO: error type
+ //
+ let stack_region = Arc::new(Region::new_rw(RegionType::Stack, stack_start, stack_size));
+ let heap_region = Arc::new(SimpleHeap::new(
+ heap_start, heap_size, heap_min_size as u64 + heap_start));
+
+ let flags = MemoryFlags {
+ enable_strict_region: true,
+ enable_permission_check: true,
+ enable_allocated_check: true,
+ };
+
+ let mut memory = Memory::new(flags, program_region, stack_region, heap_region);
+
+ // create a temporary processor to initialize the singletons
+
+ let mut processor = Processor::default();
+ let mut proxies = Proxies::default();
+
+ let mut singleton_init = SingletonInit {
+ env: image.env,
+ program_start: image.program_start,
+ core: processor.attach(&mut memory, &mut proxies),
+ heap_start_adjusted: heap_start - heap_adjustment,
+ };
+
+ for singleton in image.singletons() {
+ singleton.create_instance(&mut singleton_init)?;
+ }
+
+ Ok((memory, proxies))
+}
+
+fn overlaps(a_start: u64, a_size: u32, b_start: u64, b_size: u32) -> bool {
+ let a_end = a_start + a_size as u64;
+ let b_end = b_start + b_size as u64;
+ (b_start < a_end && b_start >= a_start) || (b_end < a_end && b_end >= a_start)
+}
+
+pub struct SingletonInit<'p, 'm, 'x> {
+ env: Env,
+ program_start: u64,
+ core: Core<'p, 'm, 'x>,
+ heap_start_adjusted: u64,
+}
+
+impl SingletonCreator for SingletonInit<'_, '_, '_> {
+ type Error = CrateError;
+
+ fn set_main_rel_pc(&mut self, pc: u32) -> Result<(), Self::Error> {
+ let main_offset = self.env.main_offset();
+ // physical address of the instruction we need to set PC to
+ let address = self.program_start + main_offset as u64 + pc as u64;
+
+ todo!()
+ }
+
+ fn enter(&mut self, target: u32) -> Result<(), Self::Error> {
+ todo!()
+ }
+
+ fn execute_until(&mut self, target: u32) -> Result<(), Self::Error> {
+ todo!()
+ }
+
+ fn allocate(&mut self, rel_start: u32, size: u32) -> Result<(), Self::Error> {
+ let singleton_address = self.heap_start_adjusted + rel_start as u64;
+ todo!() // store the address in X0
+ }
+
+ fn execute_to_return(&mut self) -> Result<(), Self::Error> {
+ todo!()
+ }
+
+ fn stop(&mut self) -> Result<(), Self::Error> {
+ todo!()
+ }
+
+ fn make_proxy(&mut self, obj_type: ObjType, reg: u32) -> Result<(), Self::Error> {
+ todo!()
+ }
+}
diff --git a/packages/blueflame/src/error.rs b/packages/blueflame/src/error.rs
new file mode 100644
index 0000000..8f8d71a
--- /dev/null
+++ b/packages/blueflame/src/error.rs
@@ -0,0 +1,12 @@
+#[derive(Debug, Clone, thiserror::Error)]
+pub enum Error {
+
+ #[error("boot crash: {0}")]
+ Boot(#[from] crate::boot::Error),
+
+ #[error("execution error")]
+ Cpu, // TODO: CPU errors
+
+ #[error("memory error: {0}")]
+ Mem(crate::memory::Error),
+}
diff --git a/packages/blueflame/src/lib.rs b/packages/blueflame/src/lib.rs
new file mode 100644
index 0000000..53bede0
--- /dev/null
+++ b/packages/blueflame/src/lib.rs
@@ -0,0 +1,41 @@
+use memory::{Memory, Proxies};
+use processor::Processor;
+
+pub struct Core<'p, 'm, 'x> {
+ pub cpu: &'p mut Processor,
+ pub mem: &'m mut Memory,
+ pub proxies: &'x mut Proxies,
+}
+
+/// Internal bindings to invoke functions
+impl Core<'_, '_, '_> {
+
+ // these functions are called internally by the call
+ // to execute commands
+ //
+ // these need to put the argument on the stack, set SP and PC
+ // correctly, and then run the function using the Processor
+
+
+ // 0x96efb8
+ pub fn pmdm_item_get(&self, actor: &str, value: i32, modifier_info: u64) ->
+ Result<(), error::Error> {
+ todo!();
+ }
+}
+
+/// Memory implementation
+pub mod memory;
+
+
+pub mod error;
+
+mod loader;
+
+pub mod processor;
+
+/// Initialization for the memory
+mod boot;
+
+/// Proxy objects
+mod proxy;
diff --git a/packages/blueflame/src/loader.rs b/packages/blueflame/src/loader.rs
new file mode 100644
index 0000000..61d464d
--- /dev/null
+++ b/packages/blueflame/src/loader.rs
@@ -0,0 +1,76 @@
+use std::collections::HashMap;
+
+use crate::Core;
+
+
+// loader creates Memory and Processor instances
+// it needs to do the following: (in this order)
+// - create the executable memory pages and copy the executable in
+// - relocate the executable, which means
+// - put the real addresses of the symbols in the .got.plt
+// - put the real addresses of functions in vtables
+//
+// - create and allocate the stack pages (4MB)
+// - create the heap region
+// - for each singleton:
+// - allocate the memory in the heap region for its instance
+// - where the memory is is defined by configuration, as we
+// need to put those singletons in the same spot the real game would put it
+// - simulate the createInstance function for the singleton, which
+// - allocates memory (this is already done, just return the pointer from previous step)
+// - call ctor of the Disposer - skip this for now and leave the disposer uninitialized, as we
+// don't really care about it
+// - call the ctor of the singleton - we DO care about this
+// - write the singleton address to the sInstance field (in .data section)
+//
+//
+//
+
+pub trait LoaderInfo {
+
+
+ /// Create a table of stub functions.
+ ///
+ /// If the PC of the processor matches a key, then the corresponding
+ /// function is called and returned
+ fn create_stub_function_table(&self) -> HashMap Result<(), ()>>>;
+
+ /// physical address in .got.plt -> key for stub function table
+ fn get_external_symbol_table(&self) -> HashMap;
+
+ /// Get the region information for the program, stack, and heap
+ fn get_regions(&self) -> Regions;
+
+ fn get_executable(&self) -> Executable;
+
+ /// Get the relative addresses of the singletons
+ /// to heap start
+ fn get_singletons(&self) -> Singletons;
+
+
+
+}
+
+pub struct Regions {
+ pub program: RegionInfo,
+ pub stack: RegionInfo,
+ pub heap: RegionInfo,
+}
+
+pub struct RegionInfo {
+ pub start: u64,
+ pub size: usize,
+}
+
+pub struct Executable {
+ data: Vec
+}
+
+pub struct ExecutableSegment {
+ pub start: u32,
+ pub data: Vec
+}
+
+pub struct Singletons {
+ pub pmdm: u64,
+}
diff --git a/packages/blueflame/src/memory/access.rs b/packages/blueflame/src/memory/access.rs
new file mode 100644
index 0000000..b7ef89d
--- /dev/null
+++ b/packages/blueflame/src/memory/access.rs
@@ -0,0 +1,69 @@
+use enumset::{enum_set, EnumSet, EnumSetType};
+
+
+/// Information for accessing memory for tracking and reporting
+#[derive(Debug, Clone)]
+pub struct MemAccess {
+ /// The type of access
+ pub typ: AccessType,
+ /// The physical address being accessed
+ pub addr: u64,
+ /// The number of bytes being accessed
+ pub bytes: u32,
+}
+
+impl std::fmt::Display for MemAccess {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(
+ f,
+ "{:?} access to 0x{:x} for {} bytes",
+ self.typ, self.addr, self.bytes
+ )
+ }
+}
+
+#[derive(Debug, EnumSetType)]
+pub enum AccessType {
+ /// Reading data from the memory
+ Read,
+ /// Writing data to the memory
+ Write,
+ /// Reading instruction from memory
+ Execute,
+}
+
+impl AccessType {
+ /// Convert a permission bitmask to a permission set
+ /// The mask is:
+ /// - 0x4 for read
+ /// - 0x2 for write
+ /// - 0x1 for execute
+ pub const fn from_perms(perm: u32) -> EnumSet {
+ match perm {
+ 0x4 => enum_set!(AccessType::Read),
+ 0x2 => enum_set!(AccessType::Write),
+ 0x1 => enum_set!(AccessType::Execute),
+ 0x6 => enum_set!(AccessType::Read | AccessType::Write),
+ 0x5 => enum_set!(AccessType::Read | AccessType::Execute),
+ 0x3 => enum_set!(AccessType::Write | AccessType::Execute),
+ 0x7 => enum_set!(AccessType::Read | AccessType::Write | AccessType::Execute),
+ _ => EnumSet::empty(),
+ }
+ }
+
+ pub fn to_perm(&self) -> u32 {
+ match self {
+ AccessType::Read => 0x4,
+ AccessType::Write => 0x2,
+ AccessType::Execute => 0x1,
+ }
+ }
+
+ pub fn to_perms(set: &EnumSet) -> u32 {
+ let mut perms = 0;
+ for perm in set.iter() {
+ perms |= perm.to_perm();
+ }
+ perms
+ }
+}
diff --git a/packages/blueflame/src/memory/error.rs b/packages/blueflame/src/memory/error.rs
new file mode 100644
index 0000000..c908829
--- /dev/null
+++ b/packages/blueflame/src/memory/error.rs
@@ -0,0 +1,38 @@
+use enumset::EnumSet;
+
+use super::region::RegionType;
+use super::access::MemAccess;
+
+/// Memory errors
+#[derive(Debug, Clone, thiserror::Error)]
+pub enum Error {
+ #[error("permission denied: {0}")]
+ PermissionDenied(MemAccess),
+ #[error("page boundary hit: {0}")]
+ PageBoundary(MemAccess),
+ #[error("attempt to access invalid memory region: 0x{0:08x}")]
+ InvalidRegion(u64),
+ #[error("attempt to access address: 0x{0:08x}, which is not in {1:?}")]
+ DisallowedRegion(u64, EnumSet),
+
+ /// Region must be valid, but it's not allocated
+ /// (suppressable with :disable mem-check-allocated
+ #[error("attempt to access unallocated memory: 0x{0:08x}")]
+ Unallocated(u64),
+ #[error("{1} region out of memory: 0x{0:08x}")]
+ OutOfMemory(u64, RegionType),
+
+ #[error("proxy object is too small: {0} bytes, need at least 4 bytes")]
+ InvalidProxyObjectSize(u32),
+ #[error("proxy object 0x{1:08x} is corrupted: handle {0} is invalid")]
+ InvalidProxyHandle(u32, u64),
+ #[error("proxy object 0x{1:08x}#{0} is corrupted: written outside of proxy. size: {2}")]
+ CorruptedProxyObject(u32, u64, u32),
+ #[error("too many proxy objects")]
+ ProxyOutOfMemory,
+
+ #[error("unexpected error: {0}")]
+ Unexpected(String),
+
+
+}
diff --git a/packages/blueflame/src/memory/heap.rs b/packages/blueflame/src/memory/heap.rs
new file mode 100644
index 0000000..3de7d75
--- /dev/null
+++ b/packages/blueflame/src/memory/heap.rs
@@ -0,0 +1,64 @@
+use derive_more::derive::{Deref, DerefMut};
+
+use super::{align_up, error::Error, region::{Region, RegionType}};
+
+
+/// A simple heap region implementation
+///
+/// It makes sure that:
+/// - The region start is page-aligned
+/// - Singleton allocations are allocated so they have the same
+/// offsets relative to each other regardless of the heap start
+/// - All newer allocations come after the singletons
+///
+/// Since the simulator doesn't make much heap allocation (usually),
+/// freed memory are never reclaimed. This is fine, because
+/// each re-run of the simulation will have a fresh heap.
+///
+/// It doesn't track which regions are freed, so UAF won't be detected
+/// and is completely safe in the simulation since there is essentially
+/// no free. However, it does track which region are not yet
+/// allocated and throw error
+#[derive(Debug, Clone, Deref, DerefMut)]
+pub struct SimpleHeap {
+ /// Internal storage of the heap
+ #[deref]
+ #[deref_mut]
+ region: Region,
+
+ /// Address of the next allocation
+ next_alloc: u64,
+}
+
+impl SimpleHeap {
+ /// Create a new heap region. `start_alloc` is where
+ /// the first allocation will be placed
+ pub fn new(heap_start: u64, heap_size: u32, start_alloc: u64) -> Self {
+ let region = Region::new_rw(RegionType::Heap, heap_start, heap_size);
+ Self {
+ region,
+ next_alloc: start_alloc,
+ }
+ }
+
+ /// Allocate new space in the heap
+ ///
+ /// To keep things simple, the alignment is assumed to be 8
+ pub fn alloc(&mut self, size: u32) -> Result {
+ let start = align_up!(self.next_alloc, 8);
+ if u64::MAX - start < size as u64 {
+ return Err(Error::OutOfMemory(start, RegionType::Heap));
+ }
+ let end = start + size as u64;
+ if end >= self.region.start + self.region.capacity as u64 {
+ return Err(Error::OutOfMemory(end, RegionType::Heap));
+ }
+ self.next_alloc = end;
+ Ok(start)
+ }
+
+ /// Return if the address is in the allocated region of the heap
+ pub fn is_allocated(&self, addr: u64) -> bool {
+ return addr < self.next_alloc;
+ }
+}
diff --git a/packages/blueflame/src/memory/memory.rs b/packages/blueflame/src/memory/memory.rs
new file mode 100644
index 0000000..2ead545
--- /dev/null
+++ b/packages/blueflame/src/memory/memory.rs
@@ -0,0 +1,169 @@
+use std::ops::DerefMut;
+use std::sync::Arc;
+
+use derive_more::derive::Constructor;
+use enumset::EnumSet;
+
+use super::error::Error;
+use super::heap::SimpleHeap;
+use super::page::Page;
+use super::read::Reader;
+use super::region::{Region, RegionType};
+use super::write::Writer;
+
+/// Memory of the simulated process
+#[derive(Debug, Clone, Constructor)]
+pub struct Memory {
+ /// Memory feature flags
+ pub flags: MemoryFlags,
+ /// program region
+ program: Arc,
+ /// stack region
+ stack: Arc,
+ /// heap region
+ pub heap: Arc,
+}
+
+impl Memory {
+ /// Create a reader to start reading at address
+ ///
+ /// Only allow reading from certain regions if `region` is specified
+ pub fn read(&self, address: u64, region: Option>, execute: bool) -> Result {
+ let regions = if self.flags.enable_strict_region {
+ region.unwrap_or(EnumSet::all())
+ } else {
+ EnumSet::all()
+ };
+ if let Some((region, page, page_idx, off)) = self.get_region_by_addr(address) {
+ if !regions.contains(region.typ) {
+ return Err(Error::DisallowedRegion(address, regions));
+ }
+ return Ok(Reader::new(self, region, page, page_idx, off, execute));
+ }
+ // region read_by_addr will fail if the address is not allocated,
+ // in those cases, we want to return Unallocated error
+ if self.program.is_addr_in_region(address) {
+ return Err(Error::Unallocated(address))
+ }
+ if self.stack.is_addr_in_region(address) {
+ return Err(Error::Unallocated(address))
+ }
+ if self.heap.is_addr_in_region(address) {
+ return Err(Error::Unallocated(address))
+ }
+ Err(Error::InvalidRegion(address))
+ }
+
+ /// Create a writer to start writing at address
+ ///
+ /// Only allow writing to certain regions if `region` is specified
+ pub fn write(&mut self, address: u64, region: Option>) -> Result {
+ let regions = if self.flags.enable_strict_region {
+ region.unwrap_or(EnumSet::all())
+ } else {
+ EnumSet::all()
+ };
+ if let Some((region, _, page_idx, off)) = self.get_region_by_addr(address) {
+ if !regions.contains(region.typ) {
+ return Err(Error::DisallowedRegion(address, regions));
+ }
+ return Ok(Writer::new(self, region.typ, page_idx, off));
+ }
+ // region read_by_addr will fail if the address is not allocated,
+ // in those cases, we want to return Unallocated error
+ if self.program.is_addr_in_region(address) {
+ return Err(Error::Unallocated(address))
+ }
+ if self.stack.is_addr_in_region(address) {
+ return Err(Error::Unallocated(address))
+ }
+ if self.heap.is_addr_in_region(address) {
+ return Err(Error::Unallocated(address))
+ }
+ Err(Error::InvalidRegion(address))
+
+ }
+
+ /// If `address` is inside a region, return the region, page, region page index, and page offset
+ ///
+ /// This does not check permissions or if the address
+ /// is in an unallocated part of the region
+ pub fn get_region_by_addr(&self, address: u64) -> Option<(&Region, &Page, u32, u32)> {
+ if let Some((page, idx, off)) = self.program.read_at_addr(address) {
+ return Some((self.program.as_ref(), page, idx, off));
+ }
+ if let Some((page, idx, off)) = self.stack.read_at_addr(address) {
+ return Some((self.stack.as_ref(), page, idx, off));
+ }
+ if let Some((page, idx, off)) = self.heap.read_at_addr(address) {
+ return Some((self.heap.as_ref(), page, idx, off));
+ }
+ None
+ }
+
+ // // remove this if not needed
+ // pub fn get_cloest_next_region_by_addr(&self, address: u64) -> Option<&Region> {
+ // if let Some((region, _, _, _)) = self.get_region_by_addr(address) {
+ // return Some(region);
+ // }
+ // let mut closest = None;
+ // let mut closest_dist = u64::MAX;
+ // if address < self.program.start {
+ // let dist = self.program.start - address;
+ // if dist < closest_dist {
+ // closest = Some(self.program.as_ref());
+ // closest_dist = dist;
+ // }
+ // }
+ // if address < self.stack.start {
+ // let dist = self.stack.start - address;
+ // if dist < closest_dist {
+ // closest = Some(self.stack.as_ref());
+ // closest_dist = dist;
+ // }
+ // }
+ // if address < self.heap.start {
+ // let dist = self.heap.start - address;
+ // if dist < closest_dist {
+ // closest = Some(self.heap.as_ref());
+ // }
+ // }
+ // closest
+ // }
+ //
+ pub fn get_region(&self, typ: RegionType) -> &Region {
+ match typ {
+ RegionType::Program => self.program.as_ref(),
+ RegionType::Stack => self.stack.as_ref(),
+ RegionType::Heap => self.heap.as_ref(),
+ }
+ }
+
+ /// Get region by type for mutation. The region's page table
+ /// will be cloned on write if it is shared
+ pub fn mut_region(&mut self, typ: RegionType) -> &mut Region {
+ match typ {
+ RegionType::Program => Arc::make_mut(&mut self.program),
+ RegionType::Stack => Arc::make_mut(&mut self.stack),
+ RegionType::Heap => Arc::make_mut(&mut self.heap).deref_mut()
+ }
+ }
+
+ pub fn heap_mut(&mut self) -> &mut SimpleHeap {
+ Arc::make_mut(&mut self.heap)
+ }
+}
+
+#[derive(Debug, Clone)]
+pub struct MemoryFlags {
+ /// If enabled, region must be specified when accessing memory.
+ /// If the address is not in the specified regions, an error will be thrown
+ pub enable_strict_region: bool,
+
+ /// If permission checks are enabled
+ pub enable_permission_check: bool,
+
+ /// If an address is in the heap region, check
+ /// if it is in the allocated part of the region
+ pub enable_allocated_check: bool,
+}
diff --git a/packages/blueflame/src/memory/mod.rs b/packages/blueflame/src/memory/mod.rs
new file mode 100644
index 0000000..573542e
--- /dev/null
+++ b/packages/blueflame/src/memory/mod.rs
@@ -0,0 +1,58 @@
+mod page;
+pub use page::*;
+mod error;
+pub use error::*;
+mod heap;
+pub use heap::*;
+mod region;
+pub use region::*;
+mod access;
+pub use access::*;
+mod read;
+pub use read::*;
+mod write;
+pub use write::*;
+mod memory;
+pub use memory::*;
+mod proxy;
+pub use proxy::*;
+
+macro_rules! align_down {
+ ($addr:expr, $align:expr) => {
+ $addr & !($align - 1)
+ };
+}
+pub(crate) use align_down;
+
+macro_rules! align_up {
+ ($addr:expr, $align:expr) => {{
+ let align = $align;
+ $crate::memory::align_down!($addr + align - 1, align)
+ }};
+}
+pub(crate) use align_up;
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[test]
+ fn test_align_down() {
+ assert_eq!(align_down!(0x1000, 0x1000), 0x1000);
+ assert_eq!(align_down!(0x1001, 0x1000), 0x1000);
+ assert_eq!(align_down!(0x1456, 0x1000), 0x1000);
+ assert_eq!(align_down!(0x14567, 0x10000), 0x10000);
+ assert_eq!(align_down!(0x1fff, 0x1000), 0x1000);
+ assert_eq!(align_down!(0x2000, 0x1000), 0x2000);
+ }
+
+ #[test]
+ fn test_align_up() {
+ assert_eq!(align_down!(0x1000, 0x1000), 0x1000);
+ assert_eq!(align_down!(0x1001, 0x1000), 0x2000);
+ assert_eq!(align_down!(0x1456, 0x1000), 0x2000);
+ assert_eq!(align_down!(0x14567, 0x10000), 0x20000);
+ assert_eq!(align_down!(0x1fff, 0x1000), 0x2000);
+ assert_eq!(align_down!(0x2000, 0x1000), 0x2000);
+ }
+}
diff --git a/packages/blueflame/src/memory/page.rs b/packages/blueflame/src/memory/page.rs
new file mode 100644
index 0000000..7e1db68
--- /dev/null
+++ b/packages/blueflame/src/memory/page.rs
@@ -0,0 +1,101 @@
+use enumset::EnumSet;
+
+use super::access::AccessType;
+
+pub const PAGE_SIZE: u32 = 0x1000;
+
+/// A page in memory
+#[derive(Debug, Clone)]
+pub struct Page {
+ data: [u8; PAGE_SIZE as usize],
+ perm: EnumSet,
+}
+
+impl Page {
+ /// Create a new page with the given permissions and zeroed data
+ pub fn zeroed(perm: EnumSet) -> Self {
+ Self {
+ data: [0; PAGE_SIZE as usize],
+ perm,
+ }
+ }
+
+ pub fn from_slice(data: &[u8], perm: EnumSet) -> Self {
+ let mut page = Self::zeroed(perm);
+ page.data[..data.len()].copy_from_slice(data);
+ page
+ }
+
+ /// Check if the page has all of the given permission set
+ pub fn has_permission(&self, perm: impl Into>) -> bool {
+ !self.perm.intersection(perm.into()).is_empty()
+ }
+
+ /// Read a u8 at offset without checking permissions
+ #[inline]
+ pub fn read_u8(&self, off: u32) -> u8 {
+ self.data[off as usize]
+ }
+
+ /// Write a u8 at offset without checking permissions
+ #[inline]
+ pub fn write_u8(&mut self, off: u32, val: u8) {
+ self.data[off as usize] = val;
+ }
+
+ /// Read a u16 at offset without checking permissions or bounds
+ #[inline]
+ pub fn read_u16(&self, off: u32) -> u16 {
+ u16::from_le_bytes([self.data[off as usize], self.data[off as usize+ 1]])
+ }
+
+ /// Write a u16 at offset without checking permissions or bounds
+ #[inline]
+ pub fn write_u16(&mut self, off: u32, val: u16) {
+ for (i, b) in val.to_le_bytes().into_iter().enumerate() {
+ self.data[off as usize + i] = b;
+ }
+ }
+
+ /// Read a u32 at offset without checking permissions or bounds
+ #[inline]
+ pub fn read_u32(&self, off: u32) -> u32 {
+ u32::from_le_bytes([
+ self.data[off as usize],
+ self.data[off as usize + 1],
+ self.data[off as usize + 2],
+ self.data[off as usize + 3],
+ ])
+ }
+
+ /// Write a u32 at offset without checking permissions or bounds
+ #[inline]
+ pub fn write_u32(&mut self, off: u32, val: u32) {
+ for (i, b) in val.to_le_bytes().into_iter().enumerate() {
+ self.data[off as usize + i] = b;
+ }
+ }
+
+ /// Read a u64 at offset without checking permissions or bounds
+ #[inline]
+ pub fn read_u64(&self, off: u32) -> u64 {
+ u64::from_le_bytes([
+ self.data[off as usize],
+ self.data[off as usize + 1],
+ self.data[off as usize + 2],
+ self.data[off as usize + 3],
+ self.data[off as usize + 4],
+ self.data[off as usize + 5],
+ self.data[off as usize + 6],
+ self.data[off as usize + 7],
+ ])
+ }
+
+ /// Write a u64 at offset without checking permissions or bounds
+ #[inline]
+ pub fn write_u64(&mut self, off: u32, val: u64) {
+ for (i, b) in val.to_le_bytes().into_iter().enumerate() {
+ self.data[off as usize + i] = b;
+ }
+ }
+}
diff --git a/packages/blueflame/src/memory/proxy.rs b/packages/blueflame/src/memory/proxy.rs
new file mode 100644
index 0000000..bed4b86
--- /dev/null
+++ b/packages/blueflame/src/memory/proxy.rs
@@ -0,0 +1,198 @@
+use std::sync::Arc;
+
+use rand_xoshiro::rand_core::{RngCore, SeedableRng};
+use rand_xoshiro::Xoshiro256PlusPlus;
+use sha2::{Digest, Sha256};
+
+use super::error::Error;
+use super::memory::Memory;
+use super::region::RegionType;
+
+/// The maximum number of proxy objects per type
+pub const MAX_OBJECTS: u32 = 1024000;
+
+/// Holds all proxy objects in memory
+#[derive(Default, Clone)]
+pub struct Proxies {
+ // just as a placeholder
+ string_proxies: Arc>,
+}
+
+impl Proxies {
+ /// (EXAMPLE) operate on a string proxy at the given address
+ pub fn get_string(&self, mem: &Memory, address: u64) -> Result<&String, Error> {
+ self.string_proxies.get_at_addr(mem, address)
+ }
+
+ /// (EXAMPLE) operate on a string proxy at the given address for mutation
+ pub fn mut_string<'s>(&'s mut self, mem: &mut Memory, address: u64) -> Result<&'s mut String, Error> {
+ Arc::make_mut(&mut self.string_proxies).mut_at_addr(mem, address)
+ }
+
+ /// (EXAMPLE) allocate a string proxy in memory and returns a pointer to it
+ pub fn allocate_string(&mut self, mem: &mut Memory, s: String) -> Result {
+ Arc::make_mut(&mut self.string_proxies).allocate(mem, s)
+ }
+
+}
+
+impl ProxyObject for String {
+ fn mem_size(&self) -> u32 {
+ 0x100
+ }
+}
+
+#[derive(Clone)]
+pub struct ProxyList {
+ rng: Xoshiro256PlusPlus,
+ objects: Vec>>,
+}
+
+impl Default for ProxyList {
+ fn default() -> Self {
+ Self {
+ // same seed for every run
+ rng: Xoshiro256PlusPlus::seed_from_u64(0),
+ objects: Vec::new(),
+ }
+ }
+}
+
+#[derive(Clone)]
+struct Entry {
+ /// The proxy object (clone on write)
+ obj: T,
+ /// The hash of the object data in memory, initialized as random
+ integrity: [u8; 32],
+}
+
+impl ProxyList {
+ /// Allocate a new proxy object in memory and return its address
+ pub fn allocate(&mut self, mem: &mut Memory, t: T) -> Result {
+ // allocate the proxy object in memory
+ let pointer = mem.heap_mut().alloc(t.mem_size())?;
+ self.create_entry(mem, pointer, t)?;
+ Ok(pointer)
+ }
+
+ /// Create a new proxy object at the given pointer.
+ ///
+ /// Return the handle to the proxy object
+ ///
+ /// # Error
+ /// If error occurs, a potentially corrupted object will be left in memory,
+ /// and the entry is not created
+ fn create_entry(&mut self, mem: &mut Memory, pointer: u64, t: T) -> Result {
+ // allocate new entry and handle
+ if self.objects.len() >= MAX_OBJECTS as usize {
+ return Err(Error::ProxyOutOfMemory);
+ }
+ let mut integrity = [0; 32];
+ let handle = self.objects.len() as u32;
+ Self::write_proxy_object(&mut self.rng, mem, pointer, handle, &t, &mut integrity)?;
+ // creating entry here to help elide copying
+ self.objects.push(Arc::new(Entry {
+ obj: t,
+ integrity
+ }));
+ Ok(handle)
+ }
+
+ /// Write a proxy object to memory
+ fn write_proxy_object(rng: &mut Xoshiro256PlusPlus, mem: &mut Memory, pointer: u64, handle: u32, t: &T, hash_out: &mut [u8; 32]) -> Result<(), Error> {
+ let size = t.mem_size();
+ if size < 4 {
+ return Err(Error::InvalidProxyObjectSize(size));
+ }
+ let mut hash = Sha256::new();
+ let mut w = mem.write(pointer, Some(RegionType::Heap.into()))?;
+ w.write_u32(handle)?;
+ hash.update(handle.to_le_bytes());
+
+ // create garbage data
+ let garbage_size = size - 4;
+ let chunks = garbage_size / 8;
+ for _ in 0..chunks {
+ let n = rng.next_u64();
+ w.write_u64(n)?;
+ hash.update(&n.to_le_bytes());
+ }
+ let remaining = garbage_size % 8;
+ if remaining > 0 {
+ let n = rng.next_u64();
+ let bytes = n.to_le_bytes();
+ for i in 0..remaining {
+ w.write_u8(bytes[i as usize])?;
+ }
+ hash.update(&bytes[..remaining as usize]);
+ }
+ *hash_out = hash.finalize().into();
+ Ok(())
+ }
+
+ /// Get the object at the given address in memory as a proxy object
+ pub fn get_at_addr(&self, mem: &Memory, address: u64) -> Result<&T, Error> {
+ let handle = self.get_checked_handle(mem, address)?;
+ let e = &self.objects[handle as usize];
+ Ok(&e.obj)
+ }
+
+ /// Get the object at the given address in memory as a proxy object
+ /// for mutation.
+ ///
+ /// The proxy object is currently shared, it will be cloned,
+ /// and the proxy will receive a new integrity hash. However,
+ /// no cloning or updating will occur if the object is not shared.
+ pub fn mut_at_addr<'s>(&'s mut self, mem: &mut Memory, pointer: u64) -> Result<&'s mut T, Error> {
+ let handle = self.get_checked_handle(mem, pointer)?;
+ // get mut object, clone on write
+ // use pointer equality to check if it's cloned
+ // note we cannot make multiple make_mut or get_mut calls,
+ // because it's possible the object is changed in between
+ let ptr_old = Arc::as_ptr(&self.objects[handle as usize]) as usize;
+ let entry = Arc::make_mut(&mut self.objects[handle as usize]);
+ let copied = (std::ptr::from_ref(entry) as usize) != ptr_old;
+
+ // update the object in memory to a fresh copy
+ if copied {
+ Self::write_proxy_object(&mut self.rng, mem, pointer, handle, &entry.obj, &mut entry.integrity)?;
+ }
+ Ok(&mut entry.obj)
+ }
+
+ /// Read the object at the given address and check its integrity.
+ /// If OK, return the handle
+ ///
+ /// The entry is not returned to avoid borrowing
+ fn get_checked_handle(&self, mem: &Memory, pointer: u64) -> Result {
+ let mut hash = Sha256::new();
+ // read the handle
+ let mut r = mem.read(pointer, Some(RegionType::Heap.into()), false)?;
+ let handle: u32 = r.read_u32()?;
+ hash.update(handle.to_le_bytes());
+ let entry = match self.objects.get(handle as usize) {
+ Some(obj) => obj,
+ None => return Err(Error::InvalidProxyHandle(handle, pointer)),
+ };
+ let size = entry.obj.mem_size();
+ let mut data = Vec::with_capacity(size as usize);
+ for _ in 4..size {
+ data.push(r.read_u8()?);
+ }
+ hash.update(&data);
+ let integrity: [u8; 32] = hash.finalize().into();
+ if integrity != entry.integrity {
+ return Err(Error::CorruptedProxyObject(handle, pointer, size));
+ }
+
+ Ok(handle)
+ }
+
+
+}
+
+pub trait ProxyObject: Clone + Send + Sync {
+ /// Get the size of the object to mock in memory
+ /// The size must be at least 4 bytes
+ fn mem_size(&self) -> u32;
+}
diff --git a/packages/blueflame/src/memory/read.rs b/packages/blueflame/src/memory/read.rs
new file mode 100644
index 0000000..bbc0c16
--- /dev/null
+++ b/packages/blueflame/src/memory/read.rs
@@ -0,0 +1,194 @@
+use super::access::{AccessType, MemAccess};
+use super::error::Error;
+use super::page::{Page, PAGE_SIZE};
+use super::region::{Region, RegionType};
+use super::Memory;
+
+/// Stream reader from memory
+pub struct Reader<'m> {
+ /// Memory being read
+ memory: &'m Memory,
+ /// The current region being read
+ region: &'m Region,
+ /// The current page being read
+ page: &'m Page,
+ /// Index of the page in the current region
+ region_page_idx: u32,
+ /// Current offset into the current page
+ page_off: u32,
+ /// If the read is for execution, so the execute permission is checked
+ execute: bool,
+}
+
+impl<'m> Reader<'m> {
+ pub fn new(memory: &'m Memory, region: &'m Region, page: &'m Page, region_page_idx: u32, page_off: u32, execute: bool) -> Self {
+ Self {
+ memory,
+ region,
+ page,
+ region_page_idx,
+ page_off,
+ execute,
+ }
+ }
+
+ /// Skip `len` bytes in the memory
+ #[inline]
+ pub fn skip(&mut self, len: u32) {
+ self.page_off += len;
+ // checks are done in prep_read, the next time a read is performed
+ // this is so that if we read the last data and advance into
+ // invalid memory, no exception will be thrown
+ }
+
+ /// Get the current reading physical address
+ pub fn current_addr(&self) -> u64 {
+ self.region.start + (self.region_page_idx as u64 * PAGE_SIZE as u64) + self.page_off as u64
+ }
+
+ /// Read a `u8` from the memory, advance by 1 byte
+ #[inline]
+ pub fn read_u8>(&mut self) -> Result {
+ self.prep_read(1)?;
+ let val = self.page.read_u8(self.page_off);
+ self.skip(1);
+
+ Ok(val.into())
+ }
+
+ /// Read a `i8` from the memory, advance by 1 byte
+ pub fn read_i8>(&mut self) -> Result {
+ let val: u8 = self.read_u8()?;
+ Ok((val as i8).into())
+ }
+
+ /// Read a `u16` from the memory, advance by 2 bytes
+ #[inline]
+ pub fn read_u16>(&mut self) -> Result {
+ self.prep_read(2)?;
+ let val = self.page.read_u16(self.page_off);
+ self.skip(2);
+
+ Ok(val.into())
+ }
+
+ /// Read a `i16` from the memory, advance by 2 bytes
+ pub fn read_i16>(&mut self) -> Result {
+ let val: u16 = self.read_u16()?;
+ Ok((val as i16).into())
+ }
+
+ /// Read a `u32` from the memory, advance by 4 bytes
+ #[inline]
+ pub fn read_u32>(&mut self) -> Result {
+ self.prep_read(4)?;
+ let val = self.page.read_u32(self.page_off);
+ self.skip(4);
+
+ Ok(val.into())
+ }
+
+ /// Read a `i32` from the memory, advance by 4 bytes
+ pub fn read_i32>(&mut self) -> Result {
+ let val: u32 = self.read_u32()?;
+ Ok((val as i32).into())
+ }
+
+ /// Read a `u64` from the memory, advance by 8 bytes
+ #[inline]
+ pub fn read_u64>(&mut self) -> Result {
+ self.prep_read(8)?;
+ let val = self.page.read_u64(self.page_off);
+ self.skip(8);
+
+ Ok(val.into())
+ }
+
+ /// Read a `i64` from the memory, advance by 8 bytes
+ pub fn read_i64>(&mut self) -> Result {
+ let val: u64 = self.read_u64()?;
+ Ok((val as i64).into())
+ }
+
+ /// Read a `f32` from the memory, advance by 4 bytes
+ pub fn read_f32>(&mut self) -> Result {
+ let val: u32 = self.read_u32()?;
+ Ok(f32::from_bits(val).into())
+ }
+
+ /// Read a `f64` from the memory, advance by 8 bytes
+ pub fn read_f64>(&mut self) -> Result {
+ let val: u64 = self.read_u64()?;
+ Ok(f64::from_bits(val).into())
+ }
+
+ /// Prepare a read
+ ///
+ /// First it will make sure the region and page reference are valid,
+ /// then, it will check if the read is allowed
+ fn prep_read(&mut self, len: u32) -> Result<(), Error> {
+ // first check if we are still inside the region
+ let current_addr = self.current_addr();
+ if current_addr >= self.region.get_end() {
+ // advance to next region if possible
+ match self.memory.get_region_by_addr(current_addr) {
+ None => {
+ return Err(Error::InvalidRegion(current_addr));
+ }
+ Some((region, page, idx, off)) => {
+ // fix up the state
+ self.region = region;
+ self.page = page;
+ self.region_page_idx = idx;
+ self.page_off = off;
+ }
+ }
+ }
+ // advance to the next page in the region if needed
+ if self.page_off >= PAGE_SIZE {
+ self.region_page_idx += self.page_off / PAGE_SIZE;
+ self.page_off = self.page_off % PAGE_SIZE;
+ self.page = match self.region.get(self.region_page_idx) {
+ Some(page) => page.as_ref(),
+ None => return Err(Error::Unallocated(current_addr)),
+ }
+ }
+
+ // now check we can actually read `len` bytes at the current address
+ if self.memory.flags.enable_allocated_check && self.region.typ == RegionType::Heap {
+ if !self.memory.heap.is_allocated(current_addr) {
+ return Err(Error::Unallocated(current_addr));
+ }
+ }
+
+ if self.memory.flags.enable_permission_check {
+ if self.execute {
+ if !self.page.has_permission(AccessType::Read | AccessType::Execute) {
+ return Err(Error::PermissionDenied(MemAccess {
+ typ: AccessType::Execute,
+ addr: self.current_addr(),
+ bytes: len,
+ }));
+ }
+ }else {
+ if !self.page.has_permission(AccessType::Read) {
+ return Err(Error::PermissionDenied(MemAccess {
+ typ: AccessType::Read,
+ addr: self.current_addr(),
+ bytes: len,
+ }));
+ }
+ }
+ }
+
+ if self.page_off + len > PAGE_SIZE {
+ return Err(Error::PageBoundary(MemAccess {
+ typ: AccessType::Read,
+ addr: self.current_addr(),
+ bytes: len,
+ }));
+ }
+
+ Ok(())
+ }
+}
diff --git a/packages/blueflame/src/memory/region.rs b/packages/blueflame/src/memory/region.rs
new file mode 100644
index 0000000..e62d5de
--- /dev/null
+++ b/packages/blueflame/src/memory/region.rs
@@ -0,0 +1,206 @@
+use std::{sync::Arc};
+
+use enumset::{EnumSet, EnumSetType};
+use uking_relocate_lib::ProgramRegion;
+
+
+use super::access::AccessType;
+use super::error::Error;
+use super::page::{Page, PAGE_SIZE};
+use super::{align_down, align_up};
+
+
+pub const REGION_ALIGN: u64 = 0x10000;
+
+
+/// Memory region implementation
+///
+/// A region is a contiguous block of physical memory with
+/// a starting address aligned to 0x10000 and a fixed size.
+///
+/// Cloning a region will clone the page table,
+/// but the page contents are clone-on-write
+#[derive(Debug, Clone)]
+pub struct Region {
+ pub typ: RegionType,
+ /// Physical start address of the region. Must be aligned to 0x10000
+ pub start: u64,
+ /// Maximum capacity of the region in bytes
+ pub capacity: u32,
+
+ pages: Vec>,
+}
+
+impl Region {
+ /// Construct a program region from program region definition
+ ///
+ /// All pages in the program region are eagerly allocated. For simplicity,
+ /// this also include blank pages excluded from the image, which are zeroed.
+ /// The entire program region is around 70MB, which should be well under
+ /// the memory limit for WASM32
+ ///
+ /// The program region is assumed to be page-aligned, but as fail-safe,
+ /// it will be aligned up to the next page boundary
+ ///
+ /// `program_start` is the physical address where the program is loaded
+ /// will be aligned down to the nearest 0x10000, if not already
+ pub fn new_program(program_start: u64, program_size: u32, regions: &[ProgramRegion]) -> Result< Self, Error> {
+ let start = align_down!(program_start, REGION_ALIGN);
+ let num_pages = align_up!(program_size, PAGE_SIZE) / PAGE_SIZE;
+ let mut pages = Vec::with_capacity(num_pages as usize);
+ // construct all the pages
+ let mut current_start: u32 = 0;
+ for region in regions {
+ // align down just for safety, if the program image is not aligned,
+ // it's bad anyway
+ let region_start = align_down!(region.rel_start, PAGE_SIZE);
+ if current_start > region_start {
+ // should not happen unless the program image is bad
+ return Err(Error::Unexpected(format!("program image has overlapping regions! current: 0x{:08x} > next: 0x{:08x}", current_start, region_start)));
+ }
+ while current_start < region_start {
+ // invalid regions are supposed to be inaccessible,
+ // so we don't give any permission
+ let page = Arc::new(Page::zeroed(EnumSet::empty()));
+ pages.push(page);
+ current_start += PAGE_SIZE;
+ }
+ // number of pages for this region in the image, align just for safety
+ let data_len = region.data().len() as u32;
+ let permissions = AccessType::from_perms(region.permissions);
+ let num_pages_curr = align_up!(data_len, PAGE_SIZE) / PAGE_SIZE;
+ for i in 0..num_pages_curr {
+ // usize should be either 32 or 64 on our supported platforms
+ let s = (i * PAGE_SIZE) as usize;
+ let e = ((i + 1) * PAGE_SIZE).min(data_len) as usize;
+ let page = Arc::new(Page::from_slice(region.data()[s..e].as_ref(), permissions));
+ pages.push(page);
+ current_start += PAGE_SIZE;
+ }
+ }
+
+ while current_start < program_size {
+ let page = Arc::new(Page::zeroed(EnumSet::empty()));
+ pages.push(page);
+ current_start += PAGE_SIZE;
+ }
+ Ok(Self {
+ typ: RegionType::Program,
+ start,
+ capacity: program_size,
+ pages,
+ })
+ }
+
+ /// Construct a dynamic RW region
+ ///
+ /// The dynamic regions are used for stack and heap. In the simulator,
+ /// they are all pretty small, so we also pre-allocate all the pages
+ /// for simplicity
+ pub fn new_rw(region_type: RegionType, start: u64, size: u32) -> Self {
+ let start = align_down!(start, REGION_ALIGN);
+ let num_pages = align_up!(size, PAGE_SIZE) / PAGE_SIZE;
+ let mut pages = Vec::with_capacity(num_pages as usize);
+ for _ in 0..num_pages {
+ let page = Arc::new(Page::zeroed(AccessType::Read | AccessType::Write));
+ pages.push(page);
+ }
+ Self {
+ typ: region_type,
+ start,
+ capacity: size,
+ pages,
+ }
+ }
+
+ /// Get the allocated size of the region in bytes
+ ///
+ /// In the current implementation, this is always equal to the capacity
+ pub fn len_bytes(&self) -> u32 {
+ self.pages.len() as u32 * PAGE_SIZE
+ }
+
+ /// Get the end physical address of the region (exclusive)
+ pub fn get_end(&self) -> u64 {
+ self.start + self.capacity as u64
+ }
+
+ /// Get page by page index, returns None if the page is not allocated
+ pub fn get(&self, page_idx: u32) -> Option<&Arc> {
+ self.pages.get(page_idx as usize)
+ }
+
+ /// Get mutable page reference by page index, returns None if the page is not allocated
+ ///
+ /// If the page is currently shared, it will be cloned (clone-on-write)
+ pub fn get_mut(&mut self, page_idx: u32) -> Option<&mut Page> {
+ self.pages.get_mut(page_idx as usize).map(|page| Arc::make_mut(page))
+ }
+
+ /// Return true if the address is in addresses reserved for this region
+ pub fn is_addr_in_region(&self, addr: u64) -> bool {
+ addr >= self.start && addr < self.start + self.capacity as u64
+ }
+
+
+ /// Get the page for the given address as (Page, page_index, page_offset)
+ ///
+ /// Returns `None` if the address is not in this region,
+ /// or if the page is unallocated.
+ pub fn read_at_addr(&self, addr: u64) -> Option<(&Page, u32, u32)> {
+ if addr < self.start || addr >= self.start + self.len_bytes() as u64{
+ return None;
+ }
+ // relative address in the region
+ let rel_addr = addr - self.start;
+ let region_page_idx = (rel_addr / PAGE_SIZE as u64) as u32;
+ let page = self.pages.get(region_page_idx as usize)?;
+ let page_off = (rel_addr % PAGE_SIZE as u64) as u32;
+ Some((page.as_ref(), region_page_idx, page_off))
+ }
+
+ // /// Split the address into region page index and offset
+ // ///
+ // /// Returns (0, 0) if the address is not in this region -
+ // /// only use if you have already checked that the address is in this region
+ // pub fn split_addr(&self, addr: u64) -> (usize, usize) {
+ // if addr < self.start || addr >= self.start + self.len_bytes() {
+ // return (0, 0);
+ // }
+ // let region_addr = addr - self.start;
+ // let region_page_idx = region_addr / PAGE_SIZE as u64;
+ // let page_off = (region_addr % PAGE_SIZE as u64) as usize;
+ // (region_page_idx as usize, page_off)
+ // }
+}
+
+
+/// Type of the region used for tracking and debugging purposes
+///
+/// Unlike a regular OS where the regions are ordered program -> heap -> stack
+/// from low to high virtual addresses. NX does not have such system
+/// and these regions are physical memory that can be in any order.
+#[derive(Debug, EnumSetType)]
+pub enum RegionType {
+ /// The program segments
+ Program,
+ /// The stack segment
+ ///
+ /// Usually this contains stacks for all threads,
+ /// but the simulator will only have one thread
+ Stack,
+ /// The heap segment
+ Heap
+
+ // do we need TLS (Thread Local)?
+}
+
+impl std::fmt::Display for RegionType {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ RegionType::Program => write!(f, "program"),
+ RegionType::Stack => write!(f, "stack"),
+ RegionType::Heap => write!(f, "heap"),
+ }
+ }
+}
diff --git a/packages/blueflame/src/memory/write.rs b/packages/blueflame/src/memory/write.rs
new file mode 100644
index 0000000..f18db10
--- /dev/null
+++ b/packages/blueflame/src/memory/write.rs
@@ -0,0 +1,182 @@
+use super::{access::{AccessType, MemAccess}, error::Error, page::{Page, PAGE_SIZE}, region::{Region, RegionType}, Memory};
+
+/// Stream writer to memory
+pub struct Writer<'m> {
+ /// Memory being written to
+ ///
+ /// Since only one mutable reference can exist in Rust,
+ /// we have to get the mutable page reference
+ /// for every write operation
+ memory: &'m mut Memory,
+ /// Current region being written to
+ region_type: RegionType,
+ /// Index of the page currently being written to
+ region_page_idx: u32,
+ /// Offset into the current page
+ page_off: u32,
+}
+
+impl<'m> Writer<'m> {
+ pub fn new(memory: &'m mut Memory, region_type: RegionType, region_page_idx: u32, page_off: u32) -> Self {
+ Self {
+ memory,
+ region_type,
+ region_page_idx,
+ page_off,
+ }
+ }
+ /// Skip `len` bytes in the memory
+ pub fn skip(&mut self, len: u32) {
+ self.page_off += len;
+ }
+
+ fn region(&self) -> &Region {
+ self.memory.get_region(self.region_type)
+ }
+
+ fn region_mut(&mut self) -> &mut Region {
+ self.memory.mut_region(self.region_type)
+ }
+
+ /// Get the current reading address
+ pub fn current_addr(&self) -> u64 {
+ self.region().start + (self.region_page_idx as u64 * PAGE_SIZE as u64) + self.page_off as u64
+ }
+
+ /// Write a `u8` to the memory, advance by 1 byte
+ #[inline]
+ pub fn write_u8(&mut self, val: impl Into) -> Result<(), Error> {
+ self.checked_page_mut(1, |page, off| {
+ page.write_u8(off, val.into())
+ })
+ }
+
+ /// Read a `i8` from the memory, advance by 1 byte
+ pub fn write_i8(&mut self, val: impl Into) -> Result<(), Error> {
+ self.write_u8(val.into() as u8)
+ }
+
+ /// Write a `u16` to the memory, advance by 2 bytes
+ #[inline]
+ pub fn write_u16(&mut self, val: impl Into) -> Result<(), Error> {
+ self.checked_page_mut(2, |page, off| {
+ page.write_u16(off, val.into())
+ })
+ }
+
+ /// Write a `i16` to the memory, advance by 2 bytes
+ pub fn write_i16(&mut self, val: impl Into) -> Result<(), Error> {
+ self.write_u16(val.into() as u16)
+ }
+
+ /// Write a `u32` to the memory, advance by 4 bytes
+ #[inline]
+ pub fn write_u32(&mut self, val: impl Into) -> Result<(), Error> {
+ self.checked_page_mut(4, |page, off| {
+ page.write_u32(off, val.into())
+ })
+ }
+
+ /// Write a `i32` to the memory, advance by 4 bytes
+ pub fn write_i32(&mut self, val: impl Into) -> Result<(), Error> {
+ self.write_u32(val.into() as u32)
+ }
+
+ /// Write a `u64` to the memory, advance by 8 bytes
+ #[inline]
+ pub fn write_u64(&mut self, val: impl Into) -> Result<(), Error> {
+ self.checked_page_mut(8, |page, off| {
+ page.write_u64(off, val.into())
+ })
+ }
+
+ /// Write a `i64` to the memory, advance by 8 bytes
+ pub fn write_i64(&mut self, val: impl Into) -> Result<(), Error> {
+ self.write_u64(val.into() as u64)
+ }
+
+ /// Write a `f32` to the memory, advance by 4 bytes
+ pub fn write_f32(&mut self, val: impl Into) -> Result<(), Error> {
+ let val: u32 = val.into().to_bits();
+ self.write_u32(val)
+ }
+
+ /// Write a `f64` to the memory, advance by 8 bytes
+ pub fn write_f64(&mut self, val: impl Into) -> Result<(), Error> {
+ let val: u64 = val.into().to_bits();
+ self.write_u64(val)
+ }
+
+ /// Prepare a write, then operate on the page
+ ///
+ /// This must be done through a FnOnce closure because of borrowing rules
+ fn checked_page_mut(
+ &mut self, len: u32, f:F) -> Result<(), Error> {
+ {
+ // first check if we are still inside the region
+ let region = self.region();
+ let current_addr = region.start + (self.region_page_idx as u64 * PAGE_SIZE as u64) + self.page_off as u64;
+ if current_addr >= region.get_end() {
+ // advance to next region if possible
+ match self.memory.get_region_by_addr(current_addr) {
+ None => {
+ return Err(Error::InvalidRegion(current_addr));
+ }
+ Some((region, _, idx, off)) => {
+ // fix up the state
+ self.region_type = region.typ;
+ self.region_page_idx = idx;
+ self.page_off = off;
+ }
+ }
+ }
+ }
+ // advance to the next page in the region if needed
+ if self.page_off >= PAGE_SIZE {
+ self.region_page_idx += self.page_off / PAGE_SIZE;
+ self.page_off = self.page_off % PAGE_SIZE;
+ if self.region().get(self.region_page_idx).is_none() {
+ return Err(Error::Unallocated(self.current_addr()));
+ }
+ }
+
+ // now check we can actually read `len` bytes at the current address
+ if self.memory.flags.enable_allocated_check && self.region().typ == RegionType::Heap {
+ let current_addr = self.current_addr();
+ if !self.memory.heap.is_allocated(current_addr) {
+ return Err(Error::Unallocated(current_addr));
+ }
+ }
+ // copy these value out since we will lose immutable borrow to self
+ let region_page_idx = self.region_page_idx;
+ let check_permission = self.memory.flags.enable_permission_check;
+ let page_off = self.page_off;
+ // re-borrow the region as mutable and clone on write
+ let region = self.region_mut();
+ let page = match region.get_mut(region_page_idx) {
+ Some(page) => page,
+ None => return Err(Error::Unallocated(self.current_addr())),
+ };
+
+ if check_permission && !page.has_permission(AccessType::Write) {
+ return Err(Error::PermissionDenied(MemAccess {
+ typ: AccessType::Write,
+ addr: self.current_addr(),
+ bytes: len,
+ }));
+ }
+
+ if page_off + len > PAGE_SIZE {
+ return Err(Error::PageBoundary(MemAccess {
+ typ: AccessType::Write,
+ addr: self.current_addr(),
+ bytes: len,
+ }));
+ }
+
+ f(page, page_off);
+
+ self.page_off += len;
+ Ok(())
+ }
+}
diff --git a/packages/blueflame/src/processor/mod.rs b/packages/blueflame/src/processor/mod.rs
new file mode 100644
index 0000000..fbe241b
--- /dev/null
+++ b/packages/blueflame/src/processor/mod.rs
@@ -0,0 +1,26 @@
+
+use std::collections::HashMap;
+
+use crate::{memory::{Memory, Proxies}, Core};
+
+pub struct Processor {
+ // TODO: registers
+ pub stub_functions: HashMap Result<(), ()>>>,
+}
+
+impl Default for Processor {
+ fn default() -> Self {
+ todo!()
+ }
+}
+
+impl Processor {
+ /// Attach the processor to a memory instance
+ pub fn attach<'p, 'm, 'x>(&'p mut self, mem: &'m mut Memory, proxies: &'x mut Proxies) -> Core<'p, 'm, 'x> {
+ Core {
+ cpu: self,
+ mem,
+ proxies,
+ }
+ }
+}
diff --git a/packages/blueflame/src/proxy/mod.rs b/packages/blueflame/src/proxy/mod.rs
new file mode 100644
index 0000000..348344e
--- /dev/null
+++ b/packages/blueflame/src/proxy/mod.rs
@@ -0,0 +1,4 @@
+
+/// TODO: TriggerParam
+pub struct GdtTriggerParam {
+}
diff --git a/packages/extension-api/Taskfile.yml b/packages/extension-api/Taskfile.yml
new file mode 100644
index 0000000..6778374
--- /dev/null
+++ b/packages/extension-api/Taskfile.yml
@@ -0,0 +1,6 @@
+version: '3'
+
+tasks:
+ build:
+ cmds:
+ - workex -p skyb-0.0.1 src/protocol.ts --lib-path workex --no-lib
diff --git a/packages/extension-api/package.json b/packages/extension-api/package.json
new file mode 100644
index 0000000..2fb9653
--- /dev/null
+++ b/packages/extension-api/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "@pistonite/skybook-extension-api",
+ "private": true,
+ "version": "0.0.1",
+ "description": "TODO",
+ "homepage": "TODO",
+ "bugs": {
+ "url": "TODO"
+ },
+ "license": "MIT",
+ "author": "Pistonight ",
+ "files": [
+ "src/**/*"
+ ],
+ "exports": {
+ ".": "./src/index.ts",
+ "./workex": "./src/workex/index.ts",
+ "./sides/*": "./src/sides/*.ts",
+ "./interfaces/*": "./src/interfaces/*.ts"
+ },
+ "todo.repository": {
+ "type": "git",
+ "url": "https://github.com"
+ },
+ "dependencies": {
+ "@pistonite/pure": "*"
+ }
+}
diff --git a/packages/extension-api/src/.gitignore b/packages/extension-api/src/.gitignore
new file mode 100644
index 0000000..52438e2
--- /dev/null
+++ b/packages/extension-api/src/.gitignore
@@ -0,0 +1,4 @@
+# workex generated files
+workex
+/interfaces/
+/sides/
diff --git a/packages/extension-api/src/index.ts b/packages/extension-api/src/index.ts
new file mode 100644
index 0000000..e82a051
--- /dev/null
+++ b/packages/extension-api/src/index.ts
@@ -0,0 +1,2 @@
+export * from "./protocol.ts";
+export * from "./types.ts";
diff --git a/packages/extension-api/src/protocol.ts b/packages/extension-api/src/protocol.ts
new file mode 100644
index 0000000..0469d7a
--- /dev/null
+++ b/packages/extension-api/src/protocol.ts
@@ -0,0 +1,50 @@
+import { WorkexPromise } from "workex";
+
+/**
+ * API implemented by the extension and called by the application.
+ *
+ * @workex:send app
+ * @workex:recv ext
+ */
+export interface Extension {
+ /**
+ * Notify the extension that the dark mode preference has changed.
+ *
+ * The extension can update the theme based on this event
+ */
+ onDarkModeChanged(dark: boolean): WorkexPromise;
+
+ /**
+ * Notify the extension that the locale perference has changed.
+ *
+ * The locale string is one of the supported locales by the application,
+ * such as `en-US`, `fr-FR`, etc.
+ *
+ * The extension can update the UI strings based on this event.
+ */
+ onLocaleChanged(locale: string): WorkexPromise;
+
+ /**
+ * Notify the extension that the script has changed.
+ */
+ onScriptChanged(script: string): WorkexPromise;
+
+}
+
+/**
+ * API implemented by the application and called by the extension.
+ *
+ * @workex:send ext
+ * @workex:recv app
+ */
+export interface Application {
+
+ /** Get the current simulator script. */
+ getScript(): WorkexPromise;
+
+ /** Set the simulator script. */
+ setScript(script: string): WorkexPromise;
+
+ // /** Get the semantic tokens for the current script */
+ // provideSemanticTokens(start: number, end: number): WorkexPromise;
+}
diff --git a/packages/extension-api/src/types.ts b/packages/extension-api/src/types.ts
new file mode 100644
index 0000000..e69de29
diff --git a/packages/extension-api/tsconfig.json b/packages/extension-api/tsconfig.json
new file mode 100644
index 0000000..1f7887e
--- /dev/null
+++ b/packages/extension-api/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "../../config/tsconfig-vite-app.json",
+ "include": ["src"],
+}
diff --git a/packages/intwc/.gitignore b/packages/intwc/.gitignore
new file mode 100644
index 0000000..293dd6e
--- /dev/null
+++ b/packages/intwc/.gitignore
@@ -0,0 +1,2 @@
+/node_modules
+*.gen.ts
diff --git a/packages/intwc/README.md b/packages/intwc/README.md
new file mode 100644
index 0000000..261171e
--- /dev/null
+++ b/packages/intwc/README.md
@@ -0,0 +1,33 @@
+# intwc
+I-Need-To-Write-Code
+
+Code editor wrapper component for writing code in a browser for my projects.
+
+Currently, it only supports Vite + React.
+
+## Features
+- Syntax highlighting and validation
+- TypeScript custom type library and type checking
+- Support for a custom language:
+ - semantic token
+ - completion
+ - diagnostics
+ - definition
+- Tuned Cattppuccin theme for supported languages
+- Vim and Emacs mode
+
+## Non-features
+- Project-wide TypeScript language features (e.g. go to definition, find references)
+- ES Modules
+- Run sandboxed TypeScript code (will be another project)
+
+## Tech
+Under the hood, this project uses [monaco-editor](https://github.com/microsoft/monaco-editor),
+which is VS Code with shims to run in a browser. This ensures
+the code editor has all the basic features, including accessbility.
+This project does not use the existing wrappers/replacements for monaco-editor that adds support
+for VSCode API. As a result, it has much less complexity at the cost
+of not having the full feature and extension support of VS Code.
+
+## TODO
+- [ ] Add multiple file support
diff --git a/packages/intwc/Taskfile.yml b/packages/intwc/Taskfile.yml
new file mode 100644
index 0000000..7fffe4b
--- /dev/null
+++ b/packages/intwc/Taskfile.yml
@@ -0,0 +1,6 @@
+version: '3'
+
+tasks:
+ build:
+ cmds:
+ - deno generateThemes.ts > src/theme/themes.gen.ts
diff --git a/packages/intwc/generateThemes.ts b/packages/intwc/generateThemes.ts
new file mode 100644
index 0000000..356a8c1
--- /dev/null
+++ b/packages/intwc/generateThemes.ts
@@ -0,0 +1,211 @@
+// To enable maximum tree-shaking, we don't depend on catppuccin at runtime. Instead,
+// we generate the themes at build time and only reference the colors we need
+//
+// Output is written to stdout, so any engine that supports TypeScript can run this script
+import { ColorFormat, flavors } from "@catppuccin/palette";
+
+function opacity(color: ColorFormat, alpha: number) {
+ const alphaInt = Math.max(Math.min(Math.floor(alpha * 255), 255), 0);
+ const alphaHex = alphaInt.toString(16).padStart(2, "0");
+ return color.hex + alphaHex;
+}
+function createTokenStyle(tokens: string[], style: Record) {
+ return tokens.map(token => ({
+ token,
+ ...style
+ }));
+}
+
+function createCommentTokenStyle(style: Record) {
+ return createTokenStyle(["comment"], style);
+}
+
+function createPunctuationTokenStyle(style: Record) {
+ return createTokenStyle([
+ "punctuation",
+ "delimiter",
+ "meta.brace",
+ ], style);
+}
+
+function createKeywordTokenStyle(style: Record) {
+ return createTokenStyle([
+ "keyword",
+ ], style);
+}
+
+function createOperatorTokenStyle(style: Record) {
+ return createTokenStyle([
+ "keyword.operator",
+ "operator",
+ ], style);
+}
+
+function createVariableTokenStyle(style: Record) {
+ return createTokenStyle([
+ "variable",
+ "variable.parameter",
+ ], style);
+}
+
+function createVariableLibraryTokenStyle(style: Record) {
+ return createTokenStyle([
+ "variable.language",
+ ], style);
+}
+
+function createVariableConstTokenStyle(style: Record) {
+ return createTokenStyle([
+ "variable.readonly",
+ ], style);
+}
+
+function createFunctionTokenStyle(style: Record) {
+ return createTokenStyle([
+ "support.function",
+ "function"
+ ], style);
+}
+
+function createMacroTokenStyle(style: Record) {
+ return createTokenStyle([
+ "meta.macro",
+ ], style);
+}
+
+function createTypeTokenStyle(style: Record) {
+ return createTokenStyle([
+ "class",
+ "type",
+ "namespace",
+ "support.type",
+ ], style);
+}
+
+function createLiteralConstantTokenStyle(style: Record) {
+ return createTokenStyle([
+ "constant",
+ "number",
+ ], style);
+}
+
+function createLiteralStringTokenStyle(style: Record) {
+ return createTokenStyle([
+ "string",
+ ], style);
+}
+
+function createLiteralRegExpTokenStyle(style: Record) {
+ return createTokenStyle([
+ "string.regexp",
+ "regexp",
+ ], style);
+}
+
+function createSourceTokenStyle(style: Record) {
+ return createTokenStyle([
+ "source",
+ ], style);
+}
+
+function createEscapeTokenStyle(style: Record) {
+ return createTokenStyle([
+ "constant.character.escape",
+ "string.escape",
+ ], style);
+}
+
+
+
+function createDarkTheme() {
+ const mocha = flavors.mocha.colors;
+ const frappe = flavors.frappe.colors;
+ return {
+ editorColors: {
+ "foreground": mocha.text.hex,
+ "descriptionForeground": mocha.text.hex,
+ "errorForeground": mocha.red.hex,
+ "selection.background": opacity(mocha.text, 0.1),
+ "focusBorder": mocha.lavender.hex,
+
+ "editor.background": mocha.base.hex,
+ "editor.foreground": mocha.text.hex,
+ "editorWidget.background": frappe.base.hex,
+ "editorWidget.border": frappe.mantle.hex,
+ "editorCursor.foreground": mocha.rosewater.hex,
+ "editorIndentGuide.background": mocha.surface0.hex,
+ "editorBracketMatch.background": opacity(mocha.text, 0.1),
+ "editorBracketMatch.border": mocha.peach.hex,
+ "editorError.foreground": mocha.red.hex,
+ "editorWarning.foreground": mocha.yellow.hex,
+ "editorMarkerNagivationError.background": mocha.red.hex,
+ "editorLineNumber.foreground": mocha.overlay2.hex,
+ "editorLineNumber.activeForeground": mocha.overlay2.hex,
+ "editor.lineHighlightBackground": opacity(mocha.text, 0.1),
+
+ "input.background": mocha.mantle.hex,
+ "input.foreground": mocha.text.hex,
+ "input.placeholderForeground": mocha.surface0.hex,
+ },
+ tokenColors: [
+ ...createCommentTokenStyle({
+ foreground: mocha.overlay2.hex,
+ fontStyle: "italic"
+ }),
+ ...createPunctuationTokenStyle({
+ foreground: mocha.overlay2.hex
+ }),
+ ...createKeywordTokenStyle({
+ foreground: mocha.mauve.hex
+ }),
+ ...createOperatorTokenStyle({
+ foreground: mocha.sapphire.hex
+ }),
+ ...createVariableTokenStyle({
+ foreground: mocha.lavender.hex
+ }),
+ ...createVariableLibraryTokenStyle({
+ foreground: mocha.red.hex
+ }),
+ ...createVariableConstTokenStyle({
+ foreground: mocha.peach.hex
+ }),
+ ...createFunctionTokenStyle({
+ foreground: mocha.yellow.hex
+ }),
+ ...createMacroTokenStyle({
+ foreground: mocha.peach.hex
+ }),
+ ...createTypeTokenStyle({
+ foreground: mocha.blue.hex
+ }),
+ ...createLiteralConstantTokenStyle({
+ foreground: mocha.peach.hex
+ }),
+ ...createLiteralStringTokenStyle({
+ foreground: mocha.green.hex
+ }),
+ ...createLiteralRegExpTokenStyle({
+ foreground: mocha.red.hex
+ }),
+ ...createSourceTokenStyle({
+ foreground: mocha.text.hex
+ }),
+ ...createEscapeTokenStyle({
+ foreground: mocha.pink.hex
+ }),
+ ]
+ } as const;
+}
+
+type Theme = ReturnType;
+
+function emitTheme(ident: string, theme: Theme) {
+ console.log(`export const ${ident} = ` + JSON.stringify(theme, null, 4) + ";");
+}
+
+
+
+emitTheme("DarkTheme", createDarkTheme());
+
+console.log("export type Theme = typeof DarkTheme;");
diff --git a/packages/intwc/package.json b/packages/intwc/package.json
new file mode 100644
index 0000000..8b00c1f
--- /dev/null
+++ b/packages/intwc/package.json
@@ -0,0 +1,33 @@
+{
+ "name": "@pistonite/intwc",
+ "private": true,
+ "version": "0.0.1",
+ "description": "TODO",
+ "homepage": "TODO",
+ "bugs": {
+ "url": "TODO"
+ },
+ "license": "MIT",
+ "author": "Pistonight ",
+ "files": [
+ "src/**/*"
+ ],
+ "exports": {
+ ".": "./src/index.ts"
+ },
+ "todo.repository": {
+ "type": "git",
+ "url": "https://github.com"
+ },
+ "dependencies": {
+ "@pistonite/pure": "*",
+ "@pistonite/monaco-typescript-contrib": "0.0.1",
+ "monaco-editor-contrib": "0.52.2"
+ },
+ "devDependencies": {
+ "@catppuccin/palette": "^1.7.1",
+ "@types/react": "^18.3.16",
+ "react": "^18.3.1",
+ "vite": "^5.4.11"
+ }
+}
diff --git a/packages/intwc/src/CodeEditor.tsx b/packages/intwc/src/CodeEditor.tsx
new file mode 100644
index 0000000..1e5dd4f
--- /dev/null
+++ b/packages/intwc/src/CodeEditor.tsx
@@ -0,0 +1,31 @@
+import { useEffect, useState } from "react";
+
+import { CodeEditorApi, EditorState } from "./EditorState.ts";
+
+export type CodeEditorProps = {
+ /**
+ * Callback when the editor is first created. You can return
+ * a callback to be called when the editor is about to be destroyed.
+ *
+ * Use this to open initial file(s)
+ */
+ onCreated?: (api: CodeEditorApi) => (() => void) | void;
+} & React.HTMLAttributes;
+
+export const CodeEditor: React.FC = ({onCreated, ...props}) => {
+ const [ref, setRef] = useState(null);
+
+ useEffect(() => {
+ if (!ref) {
+ return;
+ }
+ const editor = new EditorState(ref);
+ const cleanup = onCreated?.(editor);
+ return () => {
+ cleanup?.();
+ editor.dispose();
+ };
+ }, [ ref]);
+
+ return (
);
+};
diff --git a/packages/intwc/src/EditorState.ts b/packages/intwc/src/EditorState.ts
new file mode 100644
index 0000000..9d3de5a
--- /dev/null
+++ b/packages/intwc/src/EditorState.ts
@@ -0,0 +1,168 @@
+// import { isDark } from '@pistonite/pure/pref';
+import * as monaco from 'monaco-editor-contrib';
+import { getProvideMarkersCallback } from './language/MarkerProviderRegistry';
+import { EditorOption } from './types.ts';
+
+
+export type CodeEditorApi = {
+ /** Get the list of opened files */
+ getFiles: () => string[];
+
+ /** Get the current opened file in the editor */
+ getCurrentFile: () => string | undefined;
+ /**
+ * Switch to the given file in the editor
+ *
+ * Does nothing if the file doesn't exist in the opened files
+ */
+ switchToFile: (filename: string) => void;
+ /**
+ * Close the given file in the editor
+ *
+ * Does nothing if the file doesn't exist in the opened files
+ */
+ closeFile: (filename: string) => void;
+ /**
+ * Open a new file and switch to it in the editor.
+ *
+ * If the file is already opened, just switch to it.
+ */
+ openFile(filename: string, content: string, language: string): void;
+
+ /** Get the content of the given file */
+ getFileContent: (filename: string) => string;
+
+ /** Set the content of the given file in the editor */
+ setFileContent: (filename: string, content: string) => void;
+
+ /** Subscribe to when files are changed */
+ subscribe: (callback: (filename: string) => void) => () => void;
+}
+
+let editorOptions: EditorOption = {
+ options: {},
+}
+
+export const setEditorOptions = (options: EditorOption) => {
+ editorOptions = options;
+}
+
+export class EditorState implements CodeEditorApi {
+ private instance: monaco.editor.IStandaloneCodeEditor;
+ private models: Map;
+ private extraCleanup: () => void;
+ private subscribers: ((filename: string) => void)[];
+
+ constructor(node: HTMLDivElement) {
+ this.models = new Map();
+ this.subscribers = [];
+
+ this.instance = monaco.editor.create(node, {
+ autoDetectHighContrast: true,
+ wordBasedSuggestions: "off",
+ bracketPairColorization: {
+ enabled: false,
+ independentColorPoolPerBracketType: false,
+ },
+ "semanticHighlighting.enabled": true,
+ automaticLayout: true,
+ tabSize: 2,
+ insertSpaces: true,
+ ...editorOptions.options,
+ });
+
+ this.extraCleanup = () => {
+
+ };
+ }
+
+ /** Dispose the editor */
+ public dispose() {
+ this.extraCleanup();
+ this.instance.setModel(null);
+ for (const model of this.models.values()) {
+ model.dispose();
+ }
+ this.instance.dispose();
+ }
+
+ public getFiles(): string[] {
+ return Array.from(this.models.keys());
+ }
+
+ public getCurrentFile(): string | undefined {
+ return this.instance.getModel()?.uri.path;
+ }
+
+ public closeFile(filename: string) {
+ const model = this.models.get(filename);
+ if (model) {
+ if (model === this.instance.getModel()) {
+ this.instance.setModel(null);
+ }
+ model.dispose();
+ this.models.delete(filename);
+ }
+ }
+
+ public getFileContent(filename: string): string {
+ const model = this.models.get(filename);
+ if (model) {
+ console.log("get", model.getValue());
+ return model.getValue();
+ }
+ return "";
+ }
+
+ public setFileContent(filename: string, content: string) {
+ const model = this.models.get(filename);
+ if (model && model.getValue() !== content) {
+ console.log(model.getValue(), content);
+ // model.setValue(content);
+ }
+ }
+
+ public subscribe(callback: (filename: string) => void): () => void {
+ this.subscribers.push(callback);
+ return () => {
+ const index = this.subscribers.indexOf(callback);
+ if (index !== -1) {
+ this.subscribers.splice(index, 1);
+ }
+ };
+ }
+
+
+ public openFile(filename: string, content: string, language: string) {
+ const model = this.models.get(filename);
+ if (!model) {
+ const model = monaco.editor.createModel(content, language, monaco.Uri.file(filename));
+ const provideMarkersCallback = getProvideMarkersCallback();
+ // there can be only one change event listener, so this is not exposed
+ model.onDidChangeContent(() => {
+ console.log("changed", model.getValue());
+ provideMarkersCallback(model);
+ this.subscribers.forEach(subscriber => subscriber(filename));
+ });
+ model.updateOptions({
+ tabSize: 2,
+ indentSize: 2,
+ insertSpaces: true,
+ trimAutoWhitespace: true,
+ bracketColorizationOptions: {
+ enabled: false,
+ independentColorPoolPerBracketType: false,
+ }
+ });
+ this.models.set(filename, model);
+ }
+ this.switchToFile(filename);
+ }
+
+ public switchToFile(filename: string) {
+ const model = this.models.get(filename);
+ if (model) {
+ this.instance.setModel(model);
+ }
+ }
+}
diff --git a/packages/intwc/src/index.ts b/packages/intwc/src/index.ts
new file mode 100644
index 0000000..0092a5a
--- /dev/null
+++ b/packages/intwc/src/index.ts
@@ -0,0 +1,6 @@
+export * from './EditorState.ts';
+export * from './CodeEditor.tsx';
+export * from "./types.ts";
+export * from "./init.ts";
+export * from "./language/LanguageClient.ts";
+
diff --git a/packages/intwc/src/init.ts b/packages/intwc/src/init.ts
new file mode 100644
index 0000000..8a57419
--- /dev/null
+++ b/packages/intwc/src/init.ts
@@ -0,0 +1,122 @@
+import * as monaco from 'monaco-editor-contrib';
+
+import { initPreference } from "./preference.ts";
+import { InitOption } from "./types.ts";
+import { initThemes } from './theme';
+
+import { patchMonacoTypeScript } from "@pistonite/monaco-typescript-contrib";
+import { registerMarkerProvider } from './language/MarkerProviderRegistry.ts';
+import { setEditorOptions } from './EditorState.ts';
+
+export function initCodeEditor({preferences, language, editor}: InitOption) {
+ initPreference(preferences || {});
+
+ const {typescript, json, css, html, custom} = language || {};
+
+ // initialize monaco
+ window.MonacoEnvironment = {
+ getWorker: async (_, label: string) => {
+ if (typescript && (label === "typescript" || label === "javascript" || label==="tsx" || label==="jsx")) {
+ const TypeScriptWorker = (await import('monaco-editor-contrib/esm/vs/language/typescript/ts.worker.js?worker')).default;
+ return new TypeScriptWorker();
+ }
+ if (json && (label === "json"|| label === "jsonc")) {
+ const JsonWorker = (await import('monaco-editor-contrib/esm/vs/language/json/json.worker.js?worker')).default;
+ return new JsonWorker();
+ }
+ if (css && (label === "css"|| label === "scss" || label === "sass" || label === "less")) {
+ const CssWorker = (await import('monaco-editor-contrib/esm/vs/language/css/css.worker.js?worker')).default;
+ return new CssWorker();
+ }
+ if (html && (label === "html"|| label === "htm")) {
+ const HtmlWorker = (await import('monaco-editor-contrib/esm/vs/language/html/html.worker.js?worker')).default;
+ return new HtmlWorker();
+ }
+ const EditorWorker = (await import('monaco-editor-contrib/esm/vs/editor/editor.worker.js?worker')).default;
+ return new EditorWorker();
+ }
+ };
+
+ initThemes();
+
+ // initialize TypeScript options
+ if (typescript) {
+
+ const dom = typescript.dom ?? true;
+ monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
+ target: monaco.languages.typescript.ScriptTarget.ESNext,
+ lib: dom ? undefined : ["esnext"],
+ noEmit: true,
+ strict: true,
+ // jsx: "preserve",
+ noUnusedLocals: true,
+ noUnusedParameters: true,
+ noFallthroughCasesInSwitch: true,
+ });
+
+ if (typescript.extraLibs) {
+ typescript.extraLibs.forEach((lib) => {
+ monaco.languages.typescript.typescriptDefaults.addExtraLib(lib.content, `file:///_lib_${lib.name}.ts`);
+ });
+ }
+
+ patchMonacoTypeScript({
+ semanticTokensMaxLength: -1
+ });
+ }
+
+ if (custom) {
+ custom.forEach((client) => {
+ console.log("registering", client.getId(), client);
+ const id = client.getId();
+ monaco.languages.register({
+ id ,
+ extensions: client.getExtensions?.()
+ });
+ const tokenizer = client.getTokenizer?.();
+ if (tokenizer) {
+ monaco.languages.registerTokensProviderFactory(id, {
+ create: () => tokenizer
+ });
+ // monaco.languages.setMonarchTokensProvider(id, tokenizer);
+ }
+ const configuration = client.getConfiguration?.();
+ if (configuration) {
+ monaco.languages.setLanguageConfiguration(id, configuration);
+ }
+
+ const getLegend = client.getSemanticTokensLegend?.bind(client);
+ const provideDocumentRangeSemanticTokens = client.provideDocumentRangeSemanticTokens?.bind(client);
+
+ if (getLegend && provideDocumentRangeSemanticTokens) {
+ monaco.languages.registerDocumentRangeSemanticTokensProvider(id, {
+ getLegend,
+ provideDocumentRangeSemanticTokens
+ });
+ }
+
+ const provideMarkers = client.provideMarkers?.bind(client);
+ if (provideMarkers) {
+ registerMarkerProvider(id, {
+ owner: client.getMarkerOwner?.() || id,
+ provide: provideMarkers
+ });
+ }
+
+ const provideCompletionItems = client.provideCompletionItems?.bind(client);
+ if (provideCompletionItems) {
+ const completionTriggerCharacters = client.getCompletionTriggerCharacters?.();
+ const resolveCompletionItem = client.resolveCompletionItem?.bind(client);
+ monaco.languages.registerCompletionItemProvider(id, {
+ triggerCharacters: completionTriggerCharacters,
+ provideCompletionItems,
+ resolveCompletionItem
+ });
+ }
+ });
+ }
+
+ if (editor) {
+ setEditorOptions(editor);
+ }
+}
diff --git a/packages/intwc/src/language/LanguageClient.ts b/packages/intwc/src/language/LanguageClient.ts
new file mode 100644
index 0000000..84068bd
--- /dev/null
+++ b/packages/intwc/src/language/LanguageClient.ts
@@ -0,0 +1,46 @@
+import * as monaco from 'monaco-editor-contrib';
+
+
+export type TextModel = monaco.editor.ITextModel;
+export type MarkerData = monaco.editor.IMarkerData;
+export type Range = monaco.Range;
+export type Position = monaco.Position;
+export type CancellationToken = monaco.CancellationToken;
+export type SemanticTokensProvider = monaco.languages.DocumentRangeSemanticTokensProvider;
+export type SemanticTokensLegend = monaco.languages.SemanticTokensLegend;
+export type SemanticTokensResult = monaco.languages.ProviderResult;
+export type CompletionItemProvider = monaco.languages.CompletionItemProvider;
+export type CompletionItem = monaco.languages.CompletionItem;
+export type CompletionList = monaco.languages.CompletionList;
+export type CompletionResult = monaco.languages.ProviderResult;
+export type MarkerResult = monaco.languages.ProviderResult;
+
+
+export type LanguageTokenizer = monaco.languages.IMonarchLanguage;
+export type LanguageConfiguration = monaco.languages.LanguageConfiguration;
+
+export type LanguageClient = {
+ /** Get the language id */
+ getId: () => string;
+ getExtensions?: () => string[];
+ /** Get the tokenizer to register on initialization */
+ getTokenizer?: () => LanguageTokenizer;
+ /** Get the configuration to register on initialization */
+ getConfiguration?: () => LanguageConfiguration;
+
+ getSemanticTokensLegend?: () => SemanticTokensLegend;
+
+ provideDocumentRangeSemanticTokens?: (model: TextModel, range: Range, token: CancellationToken) => SemanticTokensResult;
+
+ getMarkerOwner?: () => string;
+
+ provideMarkers?: (model: TextModel) => MarkerResult;
+
+ getCompletionTriggerCharacters?: () => string[];
+
+ provideCompletionItems?: (model: TextModel, position: Position, context: monaco.languages.CompletionContext, token: CancellationToken) => CompletionResult;
+
+ resolveCompletionItem?: (item: CompletionItem, token: CancellationToken) => CompletionItem,
+};
+
+monaco.languages.registerCompletionItemProvider
diff --git a/packages/intwc/src/language/MarkerProviderRegistry.ts b/packages/intwc/src/language/MarkerProviderRegistry.ts
new file mode 100644
index 0000000..cde8869
--- /dev/null
+++ b/packages/intwc/src/language/MarkerProviderRegistry.ts
@@ -0,0 +1,49 @@
+import * as monaco from 'monaco-editor-contrib';
+import { serial } from '@pistonite/pure/sync';
+
+import type { MarkerResult, TextModel } from "./LanguageClient.ts";
+
+export type MarkerProvider = {
+ owner: string;
+ provide: (model: TextModel, checkCancel: () => void) => MarkerResult;
+};
+const registeredProviders = new Map();
+
+export const registerMarkerProvider = (languageId: string, provider: MarkerProvider) => {
+ const providers = registeredProviders.get(languageId);
+ if (!providers) {
+ registeredProviders.set(languageId, [provider]);
+ return;
+ }
+ providers.push(provider);
+}
+
+const provideMarkersCallback =
+ serial({
+ fn: (checkCancel) => (model: TextModel) => {
+ return provideMarkers(model, checkCancel);
+ }
+ });
+
+export const getProvideMarkersCallback = (): (model: TextModel) => void => {
+ return provideMarkersCallback;
+}
+
+const provideMarkers = async (model: TextModel, checkCancel: () => void) => {
+ const languageId = model.getLanguageId();
+ const providers = registeredProviders.get(languageId);
+ if (!providers) {
+ return [];
+ }
+ const length = providers.length;
+ for (let i = 0; i < length; i++) {
+ const provider = providers[i];
+ const markers = await provider.provide(model, checkCancel);
+ checkCancel();
+ if (markers) {
+ monaco.editor.setModelMarkers(model, provider.owner, markers);
+ }
+ }
+}
+
+
diff --git a/packages/intwc/src/preference.ts b/packages/intwc/src/preference.ts
new file mode 100644
index 0000000..d22f54e
--- /dev/null
+++ b/packages/intwc/src/preference.ts
@@ -0,0 +1,78 @@
+import { useSyncExternalStore } from "react";
+import { persist } from "@pistonite/pure/sync";
+
+import { InputMode, Preference, PreferenceOption } from "./types.ts";
+
+const getDefaultPreference = (): Preference => {
+ return {
+ inputMode: "code"
+ };
+}
+const deserializePreference = (value: string): Preference => {
+ try {
+ return validatePreference(JSON.parse(value));
+ } catch {
+ return getDefaultPreference();
+ }
+}
+
+const validatePreference = (obj: unknown): Preference => {
+ if (!obj || typeof obj !== "object") {
+ return getDefaultPreference();
+ }
+ let inputMode: InputMode = "code";
+ if ("inputMode" in obj) {
+ const value = obj.inputMode;
+ if (value === "vim" || value === "emacs") {
+ inputMode = value;
+ }
+ }
+ return {
+ ...getDefaultPreference(),
+ inputMode,
+ }
+}
+
+const preference = persist({
+ storage: localStorage,
+ initial: getDefaultPreference(),
+ key: "Intwc.Preference",
+ deserialize: deserializePreference,
+});
+
+export const initPreference = ({persist, defaults}: PreferenceOption) => {
+ let value: Preference = {
+ ...getDefaultPreference(),
+ ...defaults,
+ }
+ if (persist) {
+ preference.init(value);
+ } else {
+ preference.disable();
+ preference.set(value);
+ }
+}
+
+export const addPreferenceSubscriber = (subscriber: (preference: Preference) => void
+ , notifyImmediately?: boolean
+): () => void => {
+ return preference.subscribe(subscriber, notifyImmediately);
+}
+
+export function getPreference(): Preference {
+ return preference.get();
+}
+
+export const setPreference = (newPreference: Partial) => {
+ const newPreferenceMerged = {
+ ...preference.get(),
+ ...newPreference,
+ };
+ preference.set(newPreferenceMerged);
+}
+
+export function useInputMode(): InputMode {
+ const preference = useSyncExternalStore(addPreferenceSubscriber, getPreference);
+ return preference.inputMode;
+}
+
diff --git a/packages/intwc/src/theme/index.ts b/packages/intwc/src/theme/index.ts
new file mode 100644
index 0000000..a989352
--- /dev/null
+++ b/packages/intwc/src/theme/index.ts
@@ -0,0 +1,19 @@
+import * as monaco from 'monaco-editor-contrib';
+
+import { DarkTheme, type Theme } from './themes.gen.ts';
+
+export const initThemes = () => {
+ defineTheme("intwc-dark", "vs-dark", DarkTheme);
+
+ monaco.editor.setTheme("intwc-dark");
+}
+
+const defineTheme = (name: string, base: "vs" | "vs-dark", theme: Theme) => {
+ monaco.editor.defineTheme(name, {
+ base,
+ inherit: true,
+ colors: theme.editorColors,
+ rules: theme.tokenColors,
+ });
+}
+
diff --git a/packages/intwc/src/types.ts b/packages/intwc/src/types.ts
new file mode 100644
index 0000000..49be318
--- /dev/null
+++ b/packages/intwc/src/types.ts
@@ -0,0 +1,97 @@
+import * as monaco from "monaco-editor-contrib";
+import type { LanguageClient } from "./language/LanguageClient.ts";
+
+/** Option to pass in to init */
+export type InitOption = {
+ /**
+ * Preferences for the editor
+ */
+ preferences?: PreferenceOption;
+
+ /**
+ * Language support configurations
+ */
+ language?: LanguageOption;
+
+ /**
+ * Option for the editor
+ */
+ editor?: EditorOption;
+}
+
+export type PreferenceOption = {
+ /** If the preference should be persisted to and loaded from localStorage */
+ persist?: boolean;
+
+ /**
+ * Override the default preference
+ *
+ * These will not be applied to the persisted preference
+ */
+ defaults?: Partial;
+}
+
+export type Preference = {
+ /**
+ * Input mode for the editor, defaults to "code"
+ */
+ inputMode: InputMode;
+}
+
+export type LanguageOption = {
+ /**
+ * TypeScript Configuration
+ *
+ * If this is not specified, TypeScript features will not be enabled
+ */
+ typescript?: TSOption;
+
+ /** If JSON language support should be enabled */
+ json?: boolean;
+
+ /** If CSS language support should be enabled */
+ css?: boolean;
+
+ /** If HTML language support should be enabled */
+ html?: boolean;
+
+ /** Custom language support */
+ custom: LanguageClient[];
+}
+
+export type EditorOption = {
+ /**
+ * Options used when constructing the editor
+ *
+ * These are added on top of the defaults provided by this wrapper
+ */
+ options: monaco.editor.IEditorOptions & monaco.editor.IGlobalEditorOptions
+}
+
+export type TSOption = {
+ /**
+ * If DOM API should be enabled for type checking
+ *
+ * Default is true
+ */
+ dom?: boolean;
+ /**
+ * Extra libraries to load
+ */
+ extraLibs?: TSExtraLib[];
+};
+
+export type TSExtraLib = {
+ /**
+ * The library name. This is used to make the file uri.
+ * For example, if the name is "foo", the file uri will
+ * be "_lib_foo.ts"
+ */
+ name: string,
+ /** The type definition file content */
+ content: string
+}
+
+
+/** Input mode of the editor */
+export type InputMode = "code" | "vim" | "emacs";
diff --git a/packages/intwc/tsconfig.json b/packages/intwc/tsconfig.json
new file mode 100644
index 0000000..ddc7ff6
--- /dev/null
+++ b/packages/intwc/tsconfig.json
@@ -0,0 +1,26 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "isolatedModules": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+ "jsx": "react-jsx",
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
+
+ "types": ["vite/client"],
+ },
+ "include": ["src"]
+}
diff --git a/packages/item-animated/.gitignore b/packages/item-animated/.gitignore
new file mode 100644
index 0000000..084490d
--- /dev/null
+++ b/packages/item-animated/.gitignore
@@ -0,0 +1,9 @@
+/target
+/venv
+/video
+*.webp
+*.mp4
+*.mkb
+*.exe
+*.lock
+*.png
diff --git a/packages/item-animated/Cargo.toml b/packages/item-animated/Cargo.toml
new file mode 100644
index 0000000..7b7d4c6
--- /dev/null
+++ b/packages/item-animated/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "skybook-item-animated-encode"
+version = "0.0.0"
+edition = "2021"
+description = "Encoder for animated icons"
+
+[dependencies]
+anyhow = "1.0.95"
+clap = { version = "4.5.23", features = ["derive"] }
+image = "0.25.5"
+serde = { version = "1.0.216", features = ["derive"] }
+serde_yaml_ng = "0.10.0"
+webp-animation = { version = "0.9.0", features = ["image"] }
+
+[[bin]]
+name = "skybook-item-animated-encode"
+path = "encode.rs"
+
diff --git a/packages/item-animated/Taskfile.yml b/packages/item-animated/Taskfile.yml
new file mode 100644
index 0000000..bba4297
--- /dev/null
+++ b/packages/item-animated/Taskfile.yml
@@ -0,0 +1,34 @@
+version: '3'
+
+tasks:
+ pull-priv:
+ desc: Pull private assets for the package. Requires gcloud access
+ cmds:
+ - rm -rf video
+ - mkdir -p video
+ - gcloud storage cp -r gs://ist-private/video .
+
+ decode:
+ desc: Decode the object
+ cmds:
+ - python decode.py {{.CLI_ARGS}}
+
+ encode:
+ desc: Encode the object
+ cmds:
+ - cargo run --release -- {{.CLI_ARGS}}
+
+ push:
+ desc: Push generated files. Requires gcloud access
+ cmds:
+ # The square ones are included in the sprite sheet (/Item)
+ - gcloud storage cp target/encode/Obj_DungeonClearSeal.png gs://ist-private/icons/Item
+ - gcloud storage cp target/encode/Obj_DLC_HeroSeal_*.png gs://ist-private/icons/Item
+ - gcloud storage cp target/encode/Obj_WarpDLC.png gs://ist-private/icons/Item
+ - gcloud storage cp target/encode/Obj_HeroSoul_*_Disabled.png gs://ist-private/icons/Item
+ - gcloud storage cp target/encode/Obj_DLC_HeroSoul_*_Disabled.png gs://ist-private/icons/Item
+ # # Activated abilities are not regular sized, so cannot be in sprite sheet
+ - gcloud storage cp target/encode/Obj_HeroSoul_*.png gs://ist-private/icons/SP/Item
+ - gcloud storage cp target/encode/Obj_DLC_HeroSoul_*.png gs://ist-private/icons/SP/Item
+ # # Put WebPs there as well
+ - gcloud storage cp target/encode/*.webp gs://ist-private/icons/SP/Item
diff --git a/packages/item-animated/config.yaml b/packages/item-animated/config.yaml
new file mode 100644
index 0000000..61377e3
--- /dev/null
+++ b/packages/item-animated/config.yaml
@@ -0,0 +1,150 @@
+encoder:
+ # "Normal" input frame size - match the decoder config
+ base_dimension: 118
+ # Target frame size. If size == base then output == target
+ target_dimension: 64
+
+ # These values are optimized for size at 64x64
+ # while still looking good
+
+ # range: [0 = off .. 100 = strongest]
+ # higher value will be smoother
+ filter_strength: 0
+ # range: [0 = off .. 7 = least sharp]
+ filter_sharpness: 0
+ # 0 - none, 1 - fast, 2 - best
+ alpha_filtering: 2
+ # Between 0 (smallest size) and 100 (lossless).
+ alpha_quality: 50
+ # number of entropy-analysis passes (in [1..10])
+ pass: 10
+ # overall quality
+ quality: 90
+ # Quality/speed trade-off (0=fast, 6=slower-better)
+ method: 6
+ # 1-4
+ segments: 4
+
+decoder:
+ measurements:
+ border_to_first_inner_left: 187
+ border_to_first_inner_top: 335
+ cell_offset: 147
+ base_size: 118
+ background_threshold: 0x10
+ orb_erase_x:
+ width: 22
+ height: 20
+ orb_erase_digit:
+ left: 22
+ bottom: 28
+ width: 18
+ height: 23
+ erase_threshold: 72
+ erase_context: 1
+ fixup_left: 41 # color used to "fix" the erased part
+ fixup_bottom: 23
+ fixup_weight: 0.8
+ fixup_iteration: 2
+ fixup_context: 1
+ border_erase_threshold: 0x40
+ profiles:
+ orb:
+ frames: 240
+ top_expand: 0
+ erase_count: true
+ travel:
+ frames: 960
+ top_expand: 0
+ erase_count: false
+ souloff:
+ frames: 240
+ top_expand: 0
+ erase_count: false
+ soulon:
+ frames: 240
+ top_expand: 21
+ erase_count: false
+ souloffdlc:
+ frames: 240
+ top_expand: 0
+ erase_count: false
+ souldlc:
+ frames: 240
+ top_expand: 40
+ erase_count: false
+ top_clean: 9
+ side_expand: 3
+
+
+objects:
+ orb:Obj_DungeonClearSeal:
+ file: video/spirit_orb.mp4
+ row_col: [3, 3]
+ orb:Obj_DLC_HeroSeal_Gerudo:
+ file: video/naboris_orb.mp4
+ row_col: [2, 1]
+ orb:Obj_DLC_HeroSeal_Goron:
+ file: video/rudania_orb.mp4
+ row_col: [2, 2]
+ orb:Obj_DLC_HeroSeal_Rito:
+ file: video/medoh_orb.mp4
+ row_col: [1, 4]
+ orb:Obj_DLC_HeroSeal_Zora:
+ file: video/ruta_orb.mp4
+ row_col: [2, 0]
+ travel:Obj_WarpDLC:
+ file: video/travel.mp4
+ row_col: [2, 3]
+ souloff:Obj_HeroSoul_Gerudo_Disabled:
+ file: video/soul.mp4
+ row_col: [0, 4]
+ souloff:Obj_HeroSoul_Goron_Disabled:
+ file: video/soul.mp4
+ row_col: [1, 1]
+ souloff:Obj_HeroSoul_Rito_Disabled:
+ file: video/soul.mp4
+ row_col: [0, 2]
+ souloff:Obj_HeroSoul_Zora_Disabled:
+ file: video/soul.mp4
+ row_col: [1, 0]
+ soulon:Obj_HeroSoul_Gerudo:
+ file: video/soulon.mp4
+ row_col: [0, 4]
+ soulon:Obj_HeroSoul_Goron:
+ file: video/soulon.mp4
+ row_col: [1, 1]
+ soulon:Obj_HeroSoul_Rito:
+ file: video/soulon.mp4
+ row_col: [0, 2]
+ soulon:Obj_HeroSoul_Zora:
+ file: video/soulon.mp4
+ row_col: [1, 0]
+ souloffdlc:Obj_DLC_HeroSoul_Gerudo_Disabled:
+ file: video/souloffdlc.mp4
+ row_col: [1, 4]
+ souloffdlc:Obj_DLC_HeroSoul_Goron_Disabled:
+ file: video/souloffdlc.mp4
+ row_col: [1, 2]
+ souloffdlc:Obj_DLC_HeroSoul_Rito_Disabled:
+ file: video/souloffdlc.mp4
+ row_col: [1, 3]
+ souloffdlc:Obj_DLC_HeroSoul_Zora_Disabled:
+ file: video/souloffdlc.mp4
+ row_col: [0, 1]
+ souldlc:Obj_DLC_HeroSoul_Gerudo:
+ file: video/souldlc.mp4
+ row_col: [1, 4]
+ top_clean_frame: 96
+ souldlc:Obj_DLC_HeroSoul_Goron:
+ file: video/souldlc.mp4
+ row_col: [1, 2]
+ top_clean_frame: 96
+ souldlc:Obj_DLC_HeroSoul_Rito:
+ file: video/souldlc.mp4
+ row_col: [1, 3]
+ top_clean_frame: 96
+ souldlc:Obj_DLC_HeroSoul_Zora:
+ file: video/souldlc2.mp4 # had to take another one because first row are clipped off
+ row_col: [1, 0]
+ top_clean_frame: 0
diff --git a/packages/item-animated/decode.py b/packages/item-animated/decode.py
new file mode 100644
index 0000000..c249b07
--- /dev/null
+++ b/packages/item-animated/decode.py
@@ -0,0 +1,379 @@
+"""
+ Step 2: Decode video into frames
+ Usage: python decode.py ...
+
+ This will decode the video and crop the item in the row and col (0-based)
+
+ Outputs are in target/decode//frame_X.png
+
+ Check the quality of the frames before preceeding
+"""
+
+
+import cv2
+import os
+import sys
+import shutil
+import yaml
+import multiprocessing
+import json
+
+def load_config():
+ home = os.path.dirname(__file__)
+ config = os.path.join(home, "config.yaml")
+ with open(config, "r", encoding="utf-8") as f:
+ return yaml.safe_load(f)
+
+def main():
+ objects = sys.argv[1:]
+ expanded_objects = set()
+
+ home = os.path.dirname(__file__)
+
+ config = load_config()
+ if not objects:
+ objects = ["*"]
+ for obj in objects:
+ if obj.endswith("*"):
+ prefix = obj[:-1]
+ for key in config["objects"]:
+ profile, name = key.split(":", 1)
+ if not prefix or name.startswith(prefix):
+ expanded_objects.add((profile, name))
+ else:
+ for key in config["objects"]:
+ profile, name = key.split(":", 1)
+ if name == obj or profile == obj:
+ expanded_objects.add((profile, name))
+
+ args = []
+ for profile, name in expanded_objects:
+ object_config = config["objects"][profile+":"+name]
+ video_file = object_config["file"]
+ [row, col] = object_config["row_col"]
+ profile_data = config["decoder"]["profiles"][profile]
+ top_expand = profile_data["top_expand"]
+ expected_frame_count = profile_data["frames"]
+ erase_count = profile_data["erase_count"]
+ side_expand = 0
+ if "side_expand" in profile_data:
+ side_expand = profile_data["side_expand"]
+ top_clean = 0
+ if "top_clean" in profile_data:
+ top_clean = profile_data["top_clean"]
+ top_clean_frame = -1
+ if "top_clean_frame" in object_config:
+ top_clean_frame = object_config["top_clean_frame"]
+ args.append((config, video_file, profile, name, row, col, top_expand, expected_frame_count, erase_count, side_expand, top_clean, top_clean_frame))
+
+ frame_args = []
+ for config, _, _, name, _, _, top_expand, frame_count, erase_count, side_expand, top_clean, _ in args:
+ output_dir = os.path.join(home, "target", "decode", name)
+ for i in range(frame_count):
+ frame_path = os.path.join(output_dir, f"frame_{i}.png")
+ frame_args.append((config, frame_path, i, name, erase_count, top_expand, side_expand, top_clean))
+
+ with multiprocessing.Pool() as pool:
+ # python is pretty limited and it's not worth to optimize here
+ # just decode frames first, then fix frames
+ for _ in pool.imap_unordered(decode_frames_shim, args):
+ pass
+ for _ in pool.imap_unordered(fix_frame_shim, frame_args):
+ pass
+
+ print("all done")
+
+
+def decode_frames_shim(args):
+ config, video_file, profile, object_name, row, col, top_expand, expected_frame_count, _erase_count, side_expand, top_clean, top_clean_frame = args
+ decode_frames(config, video_file, profile, object_name, row, col, top_expand, expected_frame_count, side_expand, top_clean, top_clean_frame)
+def decode_frames(config, video_file, profile, object_name, row, col, top_expand, expected_frame_count, side_expand, top_clean, top_clean_frame):
+ print(f"[{video_file}] decoding frames (row={row}, col={col})")
+ home = os.path.dirname(__file__)
+ cap = cv2.VideoCapture(os.path.join(home, video_file))
+ frame_count = 0
+ # Measurements
+
+ decoder = config["decoder"]
+ measurements = decoder["measurements"]
+ profile = decoder["profiles"][profile]
+ BORDER_TO_FIRST_INNER_LEFT = measurements["border_to_first_inner_left"]
+ BORDER_TO_FIRST_INNER_TOP = measurements["border_to_first_inner_top"]
+ CELL_OFFSET = measurements["cell_offset"]
+ BASE_SIZE = measurements["base_size"]
+ TOP_EXPAND = top_expand
+
+ crop_x = BORDER_TO_FIRST_INNER_LEFT + col * CELL_OFFSET - side_expand
+ crop_y = BORDER_TO_FIRST_INNER_TOP + row * CELL_OFFSET - TOP_EXPAND
+ crop_x_end = crop_x + BASE_SIZE + side_expand * 2
+ crop_y_end = crop_y + BASE_SIZE + TOP_EXPAND
+
+ output_dir = os.path.join(home, "target", "decode", object_name)
+ if os.path.exists(output_dir):
+ shutil.rmtree(output_dir)
+ os.makedirs(output_dir, exist_ok=True)
+ try:
+ while True:
+ ok, frame = cap.read()
+ if not ok:
+ break
+
+ frame_filename = os.path.join(output_dir, f"frame_{frame_count}.png")
+ cropped = frame[crop_y:crop_y_end, crop_x:crop_x_end]
+ if frame_count % 30 == 0:
+ print(f"[{video_file}] saving frame {frame_count}")
+ cv2.imwrite(frame_filename, cropped)
+
+ if frame_count == top_clean_frame:
+ # extract clean frame data (y,x)[]
+ # these are pixels that are not black but need to be set black
+ clean_frame_data = []
+ BACKGROUND_THRESHOLD = measurements["background_threshold"]
+ _, width, _ = cropped.shape
+ for y in range(top_clean):
+ for x in range(width):
+ (r,g,b) = getrgb(cropped, y, x)
+ if r >= BACKGROUND_THRESHOLD or g >= BACKGROUND_THRESHOLD or b >= BACKGROUND_THRESHOLD:
+ clean_frame_data.append((y,x))
+ clean_filename = os.path.join(output_dir, f"frame_clean.json")
+ with open(clean_filename, "w", encoding="utf-8") as clean_file:
+ json.dump(clean_frame_data, clean_file)
+ print(f"[{video_file}] saved clean frame data")
+
+ frame_count += 1
+ except Exception as e:
+ cap.release()
+ raise e
+
+ print(f"[{video_file}] saved {frame_count} frames")
+
+ if frame_count != expected_frame_count:
+ raise ValueError(f"[{video_file}] expected {expected_frame_count} frames, got {frame_count} frames")
+
+def fix_frame_shim(args):
+ config, frame_path, ithframe, object_name, erase_count, top_expand, side_expand, top_clean = args
+ fix_frame(config, frame_path, ithframe, object_name, erase_count, top_expand, side_expand, top_clean)
+def fix_frame(config, frame_path, ithframe, object_name, erase_count, top_expand, side_expand, top_clean):
+ MEASUREMENTS = config["decoder"]["measurements"]
+ BACKGROUND_THRESHOLD = MEASUREMENTS["background_threshold"]
+
+ frame = cv2.imread(frame_path)
+
+ def fix_top_clean(frame):
+ clean_filename = os.path.join(os.path.dirname(frame_path), "frame_clean.json")
+ with open(clean_filename, "r", encoding="utf-8") as clean_file:
+ clean_data = json.load(clean_file)
+ for y, x in clean_data:
+ setblack(frame, y, x)
+
+ def fix_black(frame):
+ """Clean up the black pixels"""
+ height, width, _ = frame.shape
+ for y in range(height):
+ for x in range(width):
+ (r,g,b) = getrgb(frame, y ,x)
+ if is_black(r, g, b):
+ setblack(frame, y, x)
+ BORDER_THRESHOLD = MEASUREMENTS["border_erase_threshold"]
+ for y in range(top_expand):
+ for x in range(width):
+ (r,g,b) = getrgb(frame, y ,x)
+ if b < BORDER_THRESHOLD and g < BORDER_THRESHOLD and r < BORDER_THRESHOLD:
+ setblack(frame, y, x)
+ else:
+ break
+ for x in range(width):
+ x = width - x - 1
+ (r,g,b) = getrgb(frame, y ,x)
+ if b < BORDER_THRESHOLD and g < BORDER_THRESHOLD and r < BORDER_THRESHOLD:
+ setblack(frame, y, x)
+ else:
+ break
+ if side_expand:
+ # vertical borders on the sides
+ for y in range(height):
+ for x in range(side_expand):
+ (r,g,b) = getrgb(frame, y ,x)
+ if b < BORDER_THRESHOLD and g < BORDER_THRESHOLD and r < BORDER_THRESHOLD:
+ setblack(frame, y, x)
+ (r,g,b) = getrgb(frame, y ,width - x - 1)
+ if b < BORDER_THRESHOLD and g < BORDER_THRESHOLD and r < BORDER_THRESHOLD:
+ setblack(frame, y, width - x - 1)
+
+
+ def fix_orb_count(frame):
+ """Cleans up single digit orb count in the lower left corner"""
+ height, _, _ = frame.shape
+ # Delete the "x"
+ ERASE_X_WIDTH = MEASUREMENTS["orb_erase_x"]["width"]
+ ERASE_X_HEIGHT = MEASUREMENTS["orb_erase_x"]["height"]
+ for y in range(height - ERASE_X_HEIGHT, height):
+ for x in range(0, ERASE_X_WIDTH):
+ setblack(frame, y, x)
+
+ # Delete the digit
+ ERASE_DIGIT = MEASUREMENTS["orb_erase_digit"]
+ ERASE_DIGIT_LEFT = ERASE_DIGIT["left"]
+ ERASE_DIGIT_BOTTOM = ERASE_DIGIT["bottom"]
+ ERASE_DIGIT_WIDTH = ERASE_DIGIT["width"]
+ ERASE_DIGIT_HEIGHT = ERASE_DIGIT["height"]
+
+ # Dim the digit until it's not visible
+ pixels = erase_digit(
+ frame,
+ height - ERASE_DIGIT_BOTTOM,
+ height - ERASE_DIGIT_BOTTOM + ERASE_DIGIT_HEIGHT,
+ ERASE_DIGIT_LEFT,
+ ERASE_DIGIT_LEFT + ERASE_DIGIT_WIDTH,
+ 1,
+ 72,
+ )
+
+ need_fix_pixels = set()
+ fix_window = 1
+ for (y, x) in pixels:
+ for yy in range(y-fix_window, y+fix_window+1):
+ for xx in range(x-fix_window, x+fix_window+1):
+ (r,g,b) = getrgb(frame, yy, xx)
+ if not is_black(r,g,b):
+ need_fix_pixels.add((yy,xx))
+
+ FIXUP_X = ERASE_DIGIT["fixup_left"]
+ FIXUP_Y = height - ERASE_DIGIT["fixup_bottom"]
+ (fix_r, fix_g, fix_b) = getrgb(frame, FIXUP_Y, FIXUP_X)
+ FIX_WEIGHT = ERASE_DIGIT["fixup_weight"]
+ def add_fix(ct, tt, fix_c):
+ return round(float(ct // tt) * (1 - FIX_WEIGHT) + float(fix_c) * FIX_WEIGHT)
+ ITERATION = ERASE_DIGIT["fixup_iteration"]
+ FIX_CONTEXT = ERASE_DIGIT["fixup_context"]
+ for _ in range(ITERATION):
+ new_pixels = [] # y, x, r, g, b
+ for (y, x) in need_fix_pixels:
+ (r, g, b) = getrgb(frame, yy, xx)
+ rt = 0
+ gt = 0
+ bt = 0
+ tt = 0
+ for yy in range(y-FIX_CONTEXT, y+FIX_CONTEXT+1):
+ for xx in range(x-FIX_CONTEXT,x+FIX_CONTEXT+1):
+ (r, g, b) = getrgb(frame, yy, xx)
+ rt += int(r)
+ gt += int(g)
+ bt += int(b)
+ tt += 1
+
+ r = add_fix(rt, tt, fix_r)
+ g = add_fix(gt, tt, fix_g)
+ b = add_fix(bt, tt, fix_b)
+ new_pixels.append((y, x, r, g, b))
+ for (y, x, r,g,b) in new_pixels:
+ setrgb(frame, y , x,r,g,b)
+
+
+ def erase_digit(frame, min_y, max_y, min_x, max_x, context, thres):
+ """
+ Fix pixels in the bound according to luminence
+ if dimming = True, pixels will be less bright
+ otherwise will be more bright
+ black pixels are ignored when un-dimming
+ """
+ touched_pixels = set()
+ while True:
+ # (y, x)
+ pixels = []
+ for y in range(min_y, max_y):
+ for x in range(min_x, max_x):
+ (r, g, b) = getrgb(frame, y, x)
+ l = luminence(r, g, b)
+ if l > thres:
+ pixels.append((y, x))
+ if not pixels:
+ break
+ # for each pixel, take the average of its non-matched neighbors-
+ # (y, x, r, g, b)
+ new_pixels = []
+ for (y, x) in pixels:
+ # non-black lo lumi
+ r_tot = 0
+ g_tot = 0
+ b_tot = 0
+ count = 0
+ all_count = 0 # non-black low lumi
+ all_black = True # black + non-black low lumi
+
+ for yy in range(y-context,y+context+1):
+ for xx in range(x-context,x+context+1):
+ #if yy == y and xx == x:
+ # continue
+ (r, g, b) = getrgb(frame, yy, xx)
+ l = luminence(r, g, b)
+ if l <= thres:
+ all_count += 1
+ if is_black(r, g, b):
+ continue
+ count += 1
+ all_black = False
+ r_tot += int(r)
+ g_tot += int(g)
+ b_tot += int(b)
+
+ if not all_count:
+ # pixel is surrounded by other pixels
+ continue
+ if all_black:
+ # turn pixel into black as well
+ new_pixels.append((y, x, 0, 0, 0))
+ continue
+
+ if count == 0:
+ raise Exception("should not happen")
+
+ r = round(r_tot / count)
+ g = round(g_tot / count)
+ b = round(b_tot / count)
+ new_pixels.append((y, x, r, g, b))
+ # apply edits
+ if not new_pixels:
+ break
+
+ for (y, x, r, g, b) in new_pixels:
+ touched_pixels.add((y,x ))
+ setrgb(frame, y, x, r, g, b)
+
+ return touched_pixels
+
+ def luminence(r, g, b):
+ return 0.299 * r + 0.587 * g + 0.114 * b
+
+ def setrgb(frame, y, x, r, g, b):
+ if is_black(r,g,b):
+ setblack(frame,y,x)
+ else:
+ frame[y,x]=[b,g,r]
+
+ def is_black(r, g, b):
+ return r < BACKGROUND_THRESHOLD and g < BACKGROUND_THRESHOLD and b < BACKGROUND_THRESHOLD
+
+
+ def setblack(frame, y, x):
+ frame[y,x]=[0,0,0]
+
+ if top_clean:
+ fix_top_clean(frame)
+ if erase_count:
+ fix_orb_count(frame)
+ fix_black(frame)
+
+ cv2.imwrite(frame_path, frame)
+ if ithframe % 30 == 0:
+ print(f"[{object_name}] fixed-up frame {ithframe}")
+
+def getrgb(frame, y, x):
+ (b,g,r) = frame[y, x]
+ return (r,g,b)
+
+
+
+if __name__ == "__main__":
+ main()
+
diff --git a/packages/item-animated/encode.rs b/packages/item-animated/encode.rs
new file mode 100644
index 0000000..d357e08
--- /dev/null
+++ b/packages/item-animated/encode.rs
@@ -0,0 +1,263 @@
+//! Step 3: encode frames into image
+//! cargo run --release
+//! This will find target/decode// and encode the image to target/encode/.webp
+
+use std::{
+ collections::{BTreeMap, BTreeSet},
+ path::{Path, PathBuf},
+ sync::Arc,
+};
+
+use clap::Parser;
+use image::{
+ imageops::{self, FilterType},
+ DynamicImage, GenericImage, GenericImageView, Rgba,
+};
+
+use anyhow::{anyhow, bail};
+use serde::Deserialize;
+use serde_yaml_ng::Value;
+use webp_animation::{
+ AnimParams, ColorMode, Encoder, EncoderOptions, EncodingConfig, EncodingType,
+ LossyEncodingConfig,
+};
+
+#[derive(Debug, Deserialize)]
+struct Config {
+ objects: BTreeMap, // the value is unused here
+ encoder: EncoderProfile,
+}
+#[derive(Debug, Deserialize)]
+struct EncoderProfile {
+ base_dimension: u32,
+ target_dimension: u32,
+ filter_strength: usize,
+ filter_sharpness: usize,
+ alpha_filtering: usize,
+ alpha_quality: usize,
+ pass: usize,
+ quality: f32,
+ method: usize,
+ segments: usize,
+}
+
+#[derive(Debug, Clone, Parser)]
+struct Cli {
+ objects: Vec,
+}
+
+fn main() -> anyhow::Result<()> {
+ let mut cli = Cli::parse();
+ // load config
+ let config_file = std::fs::read("config.yaml")?;
+ let config: Config = serde_yaml_ng::from_slice(&config_file)?;
+ let mut expanded_objects = BTreeSet::new();
+
+ // parse inputs
+ if cli.objects.is_empty() {
+ cli.objects.push("*".to_string());
+ }
+ for obj in cli.objects {
+ if let Some(object) = obj.strip_suffix('*') {
+ if object.is_empty() {
+ for key in config.objects.keys() {
+ let name = key.splitn(2, ":").skip(1).next().unwrap();
+ expanded_objects.insert(name.to_string());
+ }
+ } else {
+ for key in config.objects.keys() {
+ let name = key.splitn(2, ":").skip(1).next().unwrap();
+ if name.starts_with(object) {
+ expanded_objects.insert(name.to_string());
+ }
+ }
+ }
+ } else {
+ for key in config.objects.keys() {
+ let mut parts = key.splitn(2, ":");
+ let profile = parts.next().unwrap();
+ let name = parts.next().unwrap();
+ if name == obj || profile == obj {
+ expanded_objects.insert(name.to_string());
+ }
+ }
+ }
+ }
+
+ // encode each object
+ let profile = Arc::new(config.encoder);
+ let mut handles = Vec::new();
+ for object in expanded_objects {
+ let profile = Arc::clone(&profile);
+ let handle =
+ std::thread::spawn(move || encode(&object, &profile).map_err(|x| format!("{x:?}")));
+ handles.push(handle);
+ }
+
+ for handle in handles {
+ match handle.join() {
+ Err(_) => {}
+ Ok(x) => x.map_err(|x| anyhow!(x))?,
+ }
+ }
+
+ Ok(())
+}
+
+fn encode(object: &str, profile: &EncoderProfile) -> anyhow::Result<()> {
+ println!("input: {object}");
+ let frames_dir = Path::new("target").join("decode").join(object);
+ let output_dir = Path::new("target").join("encode");
+ if !output_dir.exists() {
+ std::fs::create_dir_all(&output_dir)?;
+ }
+ let mut output_name = PathBuf::from(frames_dir.file_name().unwrap());
+ output_name.set_extension("webp");
+ let input_path = frames_dir.join("frame_0.png");
+ if !input_path.exists() {
+ bail!("[{object}] cannot find first frame");
+ }
+ let image = image::open(input_path)?;
+ let (w, h) = image.dimensions();
+ // save the first frame as png in original resolution
+ let first_frame = process_image(&image, w, h);
+ let mut output_png = output_name.clone();
+ output_png.set_extension("png");
+ first_frame.save(output_dir.join(output_png))?;
+ println!("[{object}] saved first frame");
+
+ // try to avoid precision loss when converting to target dimension
+ let ratio = profile.target_dimension as f64 / profile.base_dimension as f64;
+ let target_w = if w == profile.base_dimension {
+ profile.target_dimension
+ } else {
+ (w as f64 * ratio) as u32
+ };
+ let target_h = if w == h {
+ target_w
+ } else {
+ (h as f64 * ratio) as u32
+ };
+
+ println!("[{object}] webp dimension will be {target_w}x{target_h}");
+
+ println!("[{object}] loading and transforming frames...");
+
+ let mut frame_images = Vec::new();
+ for i in 0.. {
+ let input_path = frames_dir.join(format!("frame_{i}.png"));
+ if !input_path.exists() {
+ break;
+ }
+ let image = image::open(input_path)?;
+ let image = process_image(&image, target_w, target_h);
+ frame_images.push(image);
+ }
+ println!(
+ "[{object}] loaded {} frames, encoding...",
+ frame_images.len()
+ );
+
+ let lossy_config = LossyEncodingConfig {
+ target_size: 0, // off
+ target_psnr: 0f32, // off
+ segments: profile.segments,
+ sns_strength: 100,
+ filter_strength: profile.filter_strength,
+ filter_sharpness: profile.filter_sharpness,
+ filter_type: 1,
+ autofilter: true,
+ alpha_compression: true,
+ alpha_filtering: profile.alpha_filtering,
+ alpha_quality: profile.alpha_quality,
+ pass: profile.pass,
+ show_compressed: false,
+ preprocessing: true,
+ partitions: 0,
+ partition_limit: 0,
+ use_sharp_yuv: true,
+ };
+ let encoding_config = EncodingConfig {
+ encoding_type: EncodingType::Lossy(lossy_config),
+ quality: profile.quality,
+ method: profile.method,
+ };
+ let anim_params = AnimParams {
+ loop_count: 0, // inf
+ };
+ let encoder_options = EncoderOptions {
+ anim_params,
+ minimize_size: true,
+ verbose: false,
+ color_mode: ColorMode::Rgba,
+ encoding_config: Some(encoding_config),
+ ..Default::default()
+ };
+ let mut encoder = Encoder::new_with_options((target_w, target_h), encoder_options)?;
+ for (i, image) in frame_images.iter().enumerate() {
+ if i % 30 == 0 {
+ println!("[{object}] encoding frame {i}");
+ }
+ encoder.add_frame(image.as_bytes(), timestamp(i as u32))?;
+ }
+
+ let encoded = encoder.finalize(timestamp(frame_images.len() as u32))?;
+ let size = encoded.len();
+ let output_path = output_dir.join(output_name);
+ std::fs::write(output_path, &*encoded)?;
+ println!("[{object}] done ({size} bytes)");
+
+ Ok(())
+}
+
+fn timestamp(i: u32) -> i32 {
+ // 30 fps
+ let whole = i as i32 / 3 * 100;
+ match i % 3 {
+ 0 => whole,
+ 1 => whole + 33,
+ 2 => whole + 67,
+ _ => unreachable!(),
+ }
+}
+
+fn process_image(input: &DynamicImage, target_w: u32, target_h: u32) -> DynamicImage {
+ let (w, h) = input.dimensions();
+ let mut output = DynamicImage::new_rgba8(w, h);
+ for x in 0..w {
+ for y in 0..h {
+ let [r, g, b, _] = input.get_pixel(x, y).0;
+ let (r, g, b, a) = add_alpha(r, g, b);
+ output.put_pixel(x, y, Rgba([r, g, b, a]))
+ }
+ }
+ let resized = imageops::resize(&output, target_w, target_h, FilterType::Lanczos3);
+ resized.into()
+}
+
+fn add_alpha(r: u8, g: u8, b: u8) -> (u8, u8, u8, u8) {
+ let rf = r as f64;
+ let gf = g as f64;
+ let bf = b as f64;
+ let alpha_weight = (rf * rf + gf * gf + bf * bf).sqrt();
+
+ // let lumi = 0.299 * r as f64 + 0.587 * g as f64 + 0.114 * b as f64;
+ let alpha_weight = (alpha_weight / 255.0).min(1.0);
+ // sqrt to curve it?
+ let alpha = alpha_weight; //.sqrt();
+
+ #[inline]
+ fn fix(x: u8, a: f64) -> u8 {
+ // since alpha max is 1.0, this should not overflow
+ // check just in case
+ let xa = (x as f64 / a).floor();
+ if xa > 255.0 {
+ 255
+ } else {
+ xa as u8
+ }
+ }
+
+ let a = (alpha * 255.0).floor() as u8;
+ (fix(r, alpha), fix(g, alpha), fix(b, alpha), a)
+}
diff --git a/packages/item-animated/requirements.txt b/packages/item-animated/requirements.txt
new file mode 100644
index 0000000..b3bd165
--- /dev/null
+++ b/packages/item-animated/requirements.txt
@@ -0,0 +1,2 @@
+opencv-python
+pyyaml
diff --git a/packages/item-animated/splice.ps1 b/packages/item-animated/splice.ps1
new file mode 100644
index 0000000..0c617b8
--- /dev/null
+++ b/packages/item-animated/splice.ps1
@@ -0,0 +1,42 @@
+# Preparation:
+# Get the items, go to Ketoh Wawai and go to a spot where it's completely dark, look up, open inventory
+# Make sure the cursor is not on or next to any item you want to extract
+# Use OBS to record ~1 min video to work with. I have 6000 Kbps
+# Then, use a tool like avidemux or mpv to find the timecode to splice from the video
+#
+# Step 1: Splice
+# ./splice.ps1
+# Re-encode the video so each frame correspond to one frame of the animation
+# Needs mpv and ffmpeg, args for Nvidia GPU only
+# Time code formats are HH:MM:SS.mmm
+
+$file = $args[0]
+$from = $args[1]
+$to = $args[2]
+$temp = "temp.mp4"
+$output = $args[3]
+
+$from = python tc.py -mt $from
+$to = python tc.py -mt $to
+while($true) {
+ $vframes = python tc.py -s $to $from
+ $duration = python tc.py -at $vframes 3
+ ./ffmpeg.exe -y -hwaccel nvdec -hwaccel_output_format cuda -ss $from -i $file -framerate 30 -filter_complex "scale_cuda=1920:1080,hwdownload,format=nv12 [base]" -map "[base]" -c:v h264_nvenc -b:v "6M" -fps_mode passthrough -vframes $vframes -to $duration $temp
+ mpv $temp --loop=inf --keep-open
+ $selection = Read-Host "Enter adjustment or empty to stop"
+ if ("" -eq $selection) {
+ Write-Output "Final: $from $to"
+ break
+ }
+ $adjustment = $selection -Split ";"
+ if ("m" -eq $adjustment[2]){
+ $from = python tc.py -mat $from $adjustment[0]
+ $to = python tc.py -mat $to $adjustment[1]
+ }else{
+ $from = python tc.py -at $from $adjustment[0]
+ $to = python tc.py -at $to $adjustment[1]
+ }
+}
+
+Move-Item -Path $temp -Destination $output -Force
+
diff --git a/packages/item-animated/tc.py b/packages/item-animated/tc.py
new file mode 100644
index 0000000..694b790
--- /dev/null
+++ b/packages/item-animated/tc.py
@@ -0,0 +1,170 @@
+import sys
+import re
+import argparse
+
+FRAME_PER_SECOND = 30
+MS_PER_SECOND = 1000
+SECOND_PER_MINUTE = 60
+MINUTE_PER_HOUR = 60
+
+def is_strh(strh):
+ # 0123456789abc
+ # hh:mm:ss.mss
+ strh = str(strh)
+ if len(strh) != 12:
+ return False
+ return re.search("^[0-9][0-9]+:[0-9][0-9]:[0-9][0-9]\\.[0-9][0-9][0-9]$", strh) is not None
+
+def is_frame(frame):
+ return re.search("^-?[0-9]+$", str(frame)) is not None
+
+def frm_to_strh(frames):
+ negative = frames < 0
+ if negative:
+ frames = -frames
+ millisecond_frames = frames % FRAME_PER_SECOND
+ seconds = (frames - millisecond_frames) / FRAME_PER_SECOND
+ minute_seconds = seconds % SECOND_PER_MINUTE
+ minutes = (seconds - minute_seconds) / SECOND_PER_MINUTE
+ hour_minutes = minutes % MINUTE_PER_HOUR
+ hours = (minutes - hour_minutes) / MINUTE_PER_HOUR
+
+ rest_millisecond = millisecond_frames % (FRAME_PER_SECOND/10)
+ hundred_millisecond = (millisecond_frames - rest_millisecond) / (FRAME_PER_SECOND/10)
+
+ if rest_millisecond == 0:
+ rest_millisecond = 0
+ elif rest_millisecond == 1:
+ rest_millisecond = 33
+ else:
+ rest_millisecond = 67
+
+ return format_strh(negative, hours, hour_minutes, minute_seconds, hundred_millisecond*100+rest_millisecond)
+
+def strh_to_frm(strh):
+ # 0123456789abc
+ # hh:mm:ss.mss
+ hours = int(strh[0:2])
+ minutes = int(strh[3:5])
+ seconds = int(strh[6:8])
+ ms_hundred = int(strh[9:10])
+ ms_rest = int(strh[10:])
+ if ms_rest > 60:
+ frames = 2
+ elif ms_rest>30:
+ frames = 1
+ else:
+ frames = 0
+ frames+=ms_hundred*(FRAME_PER_SECOND/10)
+ frames+=seconds*FRAME_PER_SECOND
+ frames+=minutes*SECOND_PER_MINUTE*FRAME_PER_SECOND
+ frames+=hours*MINUTE_PER_HOUR*SECOND_PER_MINUTE*FRAME_PER_SECOND
+ return int(frames)
+
+def ms_to_strh(ms):
+ negative = ms < 0
+ if negative:
+ ms = -ms
+ millisecond = ms % MS_PER_SECOND
+ seconds = (ms - millisecond) / MS_PER_SECOND
+ minute_seconds = seconds % SECOND_PER_MINUTE
+ minutes = (seconds - minute_seconds) / SECOND_PER_MINUTE
+ hour_minutes = minutes % MINUTE_PER_HOUR
+ hours = (minutes - hour_minutes) / MINUTE_PER_HOUR
+
+ return format_strh(negative, hours, hour_minutes, minute_seconds, millisecond)
+
+def strh_to_ms(strh):
+ # 0123456789abc
+ # hh:mm:ss.mss
+ hours = int(strh[0:2])
+ minutes = int(strh[3:5])
+ seconds = int(strh[6:8])
+ ms = int(strh[9:])
+
+ ms+=seconds*MS_PER_SECOND
+ ms+=minutes*SECOND_PER_MINUTE*MS_PER_SECOND
+ ms+=hours*MINUTE_PER_HOUR*SECOND_PER_MINUTE*MS_PER_SECOND
+ return int(ms)
+
+def format_strh(negative, hours, minutes, seconds, ms):
+ negative_string = "-" if negative else ""
+ second_string = f"{int(seconds)}"
+ if seconds < 10:
+ second_string = "0" + second_string
+
+ minute_string = f"{int(minutes)}"
+ if minutes < 10:
+ minute_string = "0" + minute_string
+
+ hour_string = f"{int(hours)}:"
+ if hours < 10:
+ hour_string = "0" + hour_string
+
+ if ms < 10:
+ ms_string = f".00{int(ms)}"
+ elif ms < 100:
+ ms_string = f".0{int(ms)}"
+ else:
+ ms_string = f".{int(ms)}"
+
+ return f"{negative_string}{hour_string}{minute_string}:{second_string}{ms_string}"
+MODE_CONVERT = 0
+MODE_ADD = 1
+MODE_SUBTRACT = 2
+
+def run():
+ parser = argparse.ArgumentParser(description='Process some times.')
+ parser.add_argument('-a', action='store_true', help="Add the arguments")
+ parser.add_argument('-s', action='store_true', help="Subtract the arguments")
+ parser.add_argument('-c', action='store_true', help="Convert the arguments (default)")
+ parser.add_argument('-f', action='store_true', help="Output frames (30 fps)")
+ parser.add_argument('-t', action='store_true', help="Output time code")
+ parser.add_argument('-m', action='store_true', help="Millisecond mode. Input numbers are treated as ms and will not align to 30 fps")
+
+ parser.add_argument('times', metavar='T', type=str, nargs='+', help='time input, can be frames or time code (hh:mm:ss.mss)')
+
+ args = parser.parse_args()
+ mode = MODE_CONVERT
+ if args.c:
+ mode = MODE_CONVERT
+ elif args.a:
+ mode = MODE_ADD
+ elif args.s:
+ mode = MODE_SUBTRACT
+
+ ms_mode = args.m
+
+ storage = []
+ for t in args.times:
+ if is_strh(t):
+ if ms_mode:
+ current = strh_to_ms(t)
+ else:
+ current = strh_to_frm(t)
+ elif is_frame(t):
+ current = int(t)
+ else:
+ print(f"Error: not recognized: {t}")
+ sys.exit(1)
+ if len(storage) == 0 or mode == MODE_CONVERT:
+ storage.append(current)
+ elif mode == MODE_ADD:
+ storage[0] = storage[0] + current
+ elif mode == MODE_SUBTRACT:
+ storage[0] = storage[0] - current
+
+ if args.t:
+ for s in storage:
+ if ms_mode:
+ print(ms_to_strh(s))
+ else:
+ print(frm_to_strh(s))
+ else:
+ for s in storage:
+ print(s)
+
+
+if __name__ == "__main__":
+ run()
+
diff --git a/packages/item-animated/test.html b/packages/item-animated/test.html
new file mode 100644
index 0000000..0788316
--- /dev/null
+++ b/packages/item-animated/test.html
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/item-assets/.gitignore b/packages/item-assets/.gitignore
new file mode 100644
index 0000000..aa2ee90
--- /dev/null
+++ b/packages/item-assets/.gitignore
@@ -0,0 +1,4 @@
+/data
+/icons
+*.webp
+*.png
diff --git a/packages/item-assets/Cargo.toml b/packages/item-assets/Cargo.toml
new file mode 100644
index 0000000..901c3f4
--- /dev/null
+++ b/packages/item-assets/Cargo.toml
@@ -0,0 +1,19 @@
+[package]
+name = "skybook-item-sprites-generator"
+version = "0.0.0"
+publish = false
+edition = "2021"
+
+[dependencies]
+anyhow = "1.0.94"
+codize = "0.3.3"
+image = "0.25.5"
+serde = { version = "1.0.216", features = ["derive"] }
+serde_json = "1.0.134"
+thiserror = "2.0.9"
+webp = "0.3.0"
+
+
+[[bin]]
+name = "skybook-item-sprites-generator"
+path = "generator/main.rs"
diff --git a/packages/item-assets/Taskfile.yml b/packages/item-assets/Taskfile.yml
new file mode 100644
index 0000000..6bb3a3d
--- /dev/null
+++ b/packages/item-assets/Taskfile.yml
@@ -0,0 +1,31 @@
+version: '3'
+
+tasks:
+ pull-priv:
+ desc: Pull private assets for building the package. Requires gcloud access
+ cmds:
+ - rm -rf icons src/images/*.png
+ - gcloud storage cp -r gs://ist-private/icons .
+ - gcloud storage cp -r gs://ist-private/images src
+
+
+ build:
+ desc: Build the sprite sheets
+ cmds:
+ - rm -rf src/special src/sprites
+ - cargo run --release
+ - cp -R icons/SP/Item src/special
+
+ pull:
+ desc: Pull the assets for development
+ cmds:
+ - cmd: echo "this command is not yet available"
+ silent: true
+
+ push:
+ desc: Push the generated assets. Requires gcloud access
+ cmds:
+ - gcloud storage cp src/sprites/*.webp gs://ist-private/sprites
+
+
+
diff --git a/packages/item-assets/generator/canvas.rs b/packages/item-assets/generator/canvas.rs
new file mode 100644
index 0000000..9d10409
--- /dev/null
+++ b/packages/item-assets/generator/canvas.rs
@@ -0,0 +1,82 @@
+use std::path::PathBuf;
+
+use anyhow::{anyhow, bail};
+use image::imageops::{self, FilterType};
+use image::DynamicImage;
+use webp::Encoder;
+
+use crate::error::Error;
+
+#[derive(Debug, Clone)]
+pub struct Canvas {
+ /// The output path of the sprite sheet
+ pub output: PathBuf,
+ /// Number of sprite on each side of the canvas
+ ///
+ /// Total number is this squared
+ pub sprite_per_side: u32,
+ /// Padding around each sprite
+ pub padding: u32,
+ /// Resolution to scale each sprite to
+ pub scale_to: u32,
+
+ /// The encoding quality
+ pub quality: f32,
+
+ image: DynamicImage
+}
+
+impl Canvas {
+ pub fn new(output: PathBuf, sprite_per_side: u32, outer_resolution: u32, inner_resolution: u32, quality: f32) -> Self {
+ let padding2 = outer_resolution - inner_resolution;
+ if padding2 % 2 != 0 {
+ panic!("padding must be even");
+ }
+ let padding = padding2 / 2;
+
+ let canvas_size = sprite_per_side * outer_resolution;
+ let image = DynamicImage::new_rgba8(canvas_size, canvas_size);
+
+ Self {
+ output,
+ sprite_per_side,
+ padding,
+ scale_to: inner_resolution,
+ quality,
+ image
+ }
+ }
+
+ pub fn load_image(&mut self, position: usize, image: &DynamicImage) -> anyhow::Result<()>{
+ if position >= self.sprite_per_side as usize * self.sprite_per_side as usize {
+ bail!("position out of bounds");
+ }
+ let resized =
+ DynamicImage::ImageRgba8(imageops::resize(image, self.scale_to, self.scale_to, FilterType::Lanczos3));
+ let outer_res = self.scale_to + self.padding * 2;
+ let y = (position / self.sprite_per_side as usize) * (outer_res as usize);
+ let y = y as u32 + self.padding;
+ let x = (position % self.sprite_per_side as usize) * (outer_res as usize);
+ let x = x as u32 + self.padding;
+ imageops::overlay(&mut self.image, &resized, x as i64, y as i64);
+
+ Ok(())
+ }
+
+/// Encode a webp image and write it to a file
+///
+/// Return the file size
+pub fn write(&self) -> anyhow::Result {
+ let encoder = match Encoder::from_image(&self.image) {
+ Ok(e) => e,
+ Err(e) => Err(anyhow!("Could not create encoder: {}", e))?,
+ };
+
+ let memory = encoder.encode_simple(false, self.quality).map_err(Error::from)?;
+ let len = memory.len();
+
+ std::fs::write(&self.output, &*memory)?;
+
+ Ok(len)
+}
+}
diff --git a/packages/item-assets/generator/error.rs b/packages/item-assets/generator/error.rs
new file mode 100644
index 0000000..90b54a8
--- /dev/null
+++ b/packages/item-assets/generator/error.rs
@@ -0,0 +1,26 @@
+use std::sync::PoisonError;
+
+use webp::WebPEncodingError;
+
+
+#[derive(Debug, thiserror::Error)]
+pub enum Error {
+ #[error("lock is poisoned: {0}")]
+ Poison(String),
+ #[error("image is not square: {0}, width={1}, height={2}")]
+ NotSquare(String, u32, u32),
+ #[error("could not encode image: {0}")]
+ WebpEncode(String),
+}
+
+impl From> for Error {
+ fn from(e: PoisonError) -> Self {
+ Error::Poison(format!("{}", e))
+ }
+}
+
+impl From for Error {
+ fn from(e: WebPEncodingError) -> Self {
+ Error::WebpEncode(format!("{:?}", e))
+ }
+}
diff --git a/packages/item-assets/generator/main.rs b/packages/item-assets/generator/main.rs
new file mode 100644
index 0000000..e73dd57
--- /dev/null
+++ b/packages/item-assets/generator/main.rs
@@ -0,0 +1,253 @@
+// use clap::Parser;
+
+use std::path::{Path, PathBuf};
+
+use anyhow::{anyhow, bail};
+use canvas::Canvas;
+use codize::{cblock, cconcat, clist};
+
+mod error;
+use error::Error;
+
+mod sprite_sheet;
+use sprite_sheet::{Metadata, SpriteSheet};
+
+mod canvas;
+
+fn main() {
+ if let Err(e) = generate() {
+ eprintln!("error: {:?}", e);
+ }
+}
+
+fn generate() -> anyhow::Result<()> {
+ let home = find_home()?;
+ let icons_dir = home.join("icons");
+ if !icons_dir.exists() {
+ bail!("icons directory does not exist: {}", icons_dir.display());
+ }
+
+ let sprites_dir = home.join("src").join("sprites");
+ if !sprites_dir.exists() {
+ std::fs::create_dir_all(&sprites_dir)?;
+ }
+ println!("configuring actor chunks...");
+
+ let mut chunks = vec![
+ // chunk 0
+ find_images(&icons_dir, &["CapturedActor", "Item", "PlayerItem"])?,
+ // chunk 1
+ find_images(
+ &icons_dir,
+ &[
+ "Bullet",
+ "WeaponBow",
+ "WeaponLargeSword",
+ "WeaponShield",
+ "WeaponSmallSword",
+ "WeaponSpear",
+ ],
+ )?,
+ // chunk 2
+ find_images(
+ &icons_dir,
+ &[
+ "ArmorHead",
+ "ArmorLower",
+ "ArmorUpper",
+ "HorseReins",
+ "HorseSaddle",
+ "CookResult",
+ ],
+ )?,
+ ];
+
+ let special_dir = icons_dir.join("SP");
+
+ // add the fallback "dummy" image
+ let dummy_path = special_dir.join("Dummy.png");
+ if !dummy_path.exists() {
+ bail!("Dummy image does not exist: {}", dummy_path.display());
+ }
+ println!("adding dummy image to last chunk");
+ chunks.last_mut().unwrap().push(dummy_path);
+
+ // print stat
+ for (i, chunk) in chunks.iter().enumerate() {
+ println!("chunk {}: {} images", i, chunk.len());
+ }
+ println!("loading actor sprites...");
+
+ // load the individual icons into sprite sheets
+ let mut sprite_sheets = (0..chunks.len())
+ .map(|i| {
+ let mut sprite_sheet = SpriteSheet::new(i as u16);
+ let lo_res_path = sprites_dir.join(format!("chunk{}x32.webp", i));
+ let lo_res = Canvas::new(lo_res_path, 16, 32, 28, 75f32);
+ let hi_res_path = sprites_dir.join(format!("chunk{}x64.webp", i));
+ let hi_res = Canvas::new(hi_res_path, 16, 64, 56, 90f32);
+ sprite_sheet.add_canvas(lo_res);
+ sprite_sheet.add_canvas(hi_res);
+ sprite_sheet
+ })
+ .collect::>();
+
+ for (sheet, chunk) in sprite_sheets.iter_mut().zip(chunks) {
+ for file in chunk {
+ let name = file.file_stem().unwrap().to_string_lossy().into_owned();
+ sheet.add_sprite(&name, file)?;
+ }
+ }
+
+
+ println!("encoding actor sprite sheets...");
+ for (i, sheet) in sprite_sheets.iter().enumerate() {
+ println!("-- chunk {}", i);
+ let sizes = sheet.write()?;
+ println!(" low resolution: {} bytes", sizes[0]);
+ println!(" high resolution: {} bytes", sizes[1]);
+ }
+
+ println!("writing actor metadata...");
+ let mut metadata = Metadata::default();
+ for sheet in &sprite_sheets {
+ sheet.add_metadata(&mut metadata)?;
+ }
+ let ts_chunk_type = (0..sprite_sheets.len())
+ .map(|i| i.to_string())
+ .collect::>()
+ .join("|");
+ let metadata = serde_json::to_string(&metadata)?;
+ let metadata_ts = cconcat![
+ // imports
+ cconcat!((0..sprite_sheets.len())
+ .map(|i| { format!("import chunk{i}x32 from \"./chunk{i}x32.webp?url\";") })),
+ cconcat!((0..sprite_sheets.len())
+ .map(|i| { format!("import chunk{i}x64 from \"./chunk{i}x64.webp?url\";") })),
+
+ // chunkmap classnames
+ cblock! {
+ "export const ActorChunkClasses = {",
+ [
+ clist!("" => (0..sprite_sheets.len()).map(|i| {
+ format!("\".sprite-chunk{i}x32\": {{ backgroundImage: `url(${{chunk{i}x32}})` }},")
+ })),
+ clist!("" => (0..sprite_sheets.len()).map(|i| {
+ format!("\".sprite-chunk{i}x64\": {{ backgroundImage: `url(${{chunk{i}x64}})` }},")
+ })),
+ clist!("" => (0..sprite_sheets.len()).map(|i| {
+ format!("\".sprite-mask-chunk{i}x32\": {{ maskImage: `url(${{chunk{i}x32}})` }},")
+ })),
+ clist!("" => (0..sprite_sheets.len()).map(|i| {
+ format!("\".sprite-mask-chunk{i}x64\": {{ maskImage: `url(${{chunk{i}x64}})` }},")
+ })),
+ ],
+ "} as const;"
+ },
+
+ // metadata for finding where an actor is
+ "/** Actor => [Chunk, Position]*/",
+ format!(
+ "export type ActorMetadata = Record;",
+ ts_chunk_type
+ ),
+ format!(
+ "export const ActorMetadata: ActorMetadata = JSON.parse(`{}`)",
+ metadata
+ ),
+ ];
+
+ std::fs::write(sprites_dir.join("ActorMetadata.gen.ts"), metadata_ts.to_string())?;
+
+ println!("configuring modifier chunks...");
+ let modifier_chunk = find_images(&icons_dir, &["SpecialStatus"])?;
+ let mut modifier_sheet = SpriteSheet::new(0);
+ let modifier_path = sprites_dir.join("modifiers.webp");
+ let modifier_canvas = Canvas::new(modifier_path, 8, 48, 48, 90f32);
+ modifier_sheet.add_canvas(modifier_canvas);
+
+ println!("loading modifier sprites...");
+ for file in modifier_chunk {
+ let name = file.file_stem().unwrap().to_string_lossy().into_owned();
+ modifier_sheet.add_sprite(&name, file)?;
+ }
+
+ println!("encoding modifier sprite sheet...");
+ let sizes = modifier_sheet.write()?;
+ println!(" modifiers: {} bytes", sizes[0]);
+
+ println!("writing modifier metadata...");
+ let mut metadata = Metadata::default();
+ modifier_sheet.add_metadata(&mut metadata)?;
+ let metadata = serde_json::to_string(&metadata)?;
+ let metadata_ts = cconcat![
+ // imports
+ "import modifiers from \"./modifiers.webp?url\";",
+
+ // chunkmap classnames
+ cblock! {
+ "export const ModifierChunkClasses = {",
+ [
+ "\".sprite-modifiers\": { backgroundImage: `url(${modifiers})` },",
+ ],
+ "} as const;"
+ },
+
+ "/** Modifier => [Chunk, Position]*/",
+ "export type ModifierMetadata = Record;",
+ format!(
+ "export const ModifierMetadata: ModifierMetadata = JSON.parse(`{}`)",
+ metadata
+ ),
+ ];
+
+ std::fs::write(sprites_dir.join("ModifierMetadata.gen.ts"), metadata_ts.to_string())?;
+
+ println!("done!");
+
+ Ok(())
+}
+
+fn find_images(data_dir: &Path, profiles: &[&str]) -> anyhow::Result> {
+ // we need to synchronously list all images to guarantee
+ // consistent ordering in the output
+ let mut out = Vec::new();
+ for profile in profiles {
+ let profile_dir = data_dir.join(profile);
+ if !profile_dir.exists() {
+ bail!(
+ "Profile directory does not exist: {}",
+ profile_dir.display()
+ );
+ }
+
+ let mut images = Vec::new();
+ for entry in profile_dir.read_dir()? {
+ let entry = entry?;
+ let path = entry.path();
+ if !path.is_file() {
+ bail!("Not a file: {}", path.display());
+ }
+ images.push(path);
+ }
+ println!("profile: {} ({} actors)", profile, images.len());
+ images.sort();
+ out.extend(images);
+ }
+ Ok(out)
+}
+
+/// Find the item-assets package directory
+/// if running from cargo
+fn find_home() -> anyhow::Result {
+ let e = std::env::current_exe()?;
+ let root_path = e
+ .parent() // /target/release
+ .and_then(|x| x.parent()) // /target
+ .and_then(|x| x.parent()) // /
+ .ok_or_else(|| anyhow!("Could not find parent of exe"))?;
+ let mut path = root_path.to_path_buf();
+ path.push("packages");
+ path.push("item-assets");
+ Ok(path)
+}
diff --git a/packages/item-assets/generator/sprite_sheet.rs b/packages/item-assets/generator/sprite_sheet.rs
new file mode 100644
index 0000000..f935f0e
--- /dev/null
+++ b/packages/item-assets/generator/sprite_sheet.rs
@@ -0,0 +1,103 @@
+use std::collections::BTreeMap;
+use std::path::Path;
+
+use anyhow::{bail, Context};
+use image::GenericImageView;
+use serde::{Deserialize, Serialize};
+
+use crate::canvas::Canvas;
+use crate::Error;
+
+#[derive(Debug, Clone)]
+pub struct SpriteSheet {
+ /// The chunk number
+ pub chunk: u16,
+ /// The name of the sprites
+ pub sprites: Vec,
+ /// The canvases for the sprite sheet, each canvas is a different resolution/ config
+ pub canvases: Vec,
+}
+
+impl SpriteSheet {
+ pub fn new(chunk: u16) -> Self {
+ Self {
+ chunk,
+ sprites: Vec::new(),
+ canvases: Vec::new(),
+ }
+ }
+
+ /// Add a canvas configuration for output
+ pub fn add_canvas(&mut self, canvas: Canvas) {
+ self.canvases.push(canvas);
+ }
+
+
+ /// Add the metadata of the sprite sheet to the metadata object
+ ///
+ /// Returns how many sprites were added
+ pub fn add_metadata(&self, metadata: &mut Metadata) -> anyhow::Result {
+ for (pos, name) in self.sprites.iter().enumerate() {
+ metadata.register(name, self.chunk, pos)?;
+ }
+ Ok(self.sprites.len())
+ }
+
+ /// Load an image from a file and encode it into the sprite sheet
+ pub fn add_sprite(&mut self, name: &str, path: impl AsRef) -> anyhow::Result<()> {
+ let position = {
+ let position = self.sprites.len();
+ self.sprites.push(name.to_string());
+ position
+ };
+ self.load_image(path, position)?;
+ Ok(())
+ }
+ /// Load an image file into sprite sheet canvas
+ fn load_image(
+ &mut self,
+ path: impl AsRef,
+ position: usize,
+ ) -> anyhow::Result<()> {
+ let path = path.as_ref();
+ let image = image::open(&path).context(format!("Could not open image: {}", path.display()))?;
+ let (w, h) = image.dimensions();
+ if w != h {
+ Err(Error::NotSquare(path.display().to_string(), w, h))?;
+ }
+ for canvas in &mut self.canvases {
+ canvas.load_image(position, &image)?;
+ }
+
+ Ok(())
+ }
+
+ /// Write the sprite sheets to output files
+ ///
+ /// Returns the sizes of the canvases
+ pub fn write(&self) -> anyhow::Result> {
+ let mut sizes = Vec::with_capacity(self.canvases.len());
+ for canvas in &self.canvases {
+ sizes.push(canvas.write()?);
+ }
+ Ok(sizes)
+ }
+}
+
+/// The data of a sprite sheet
+#[derive(Debug, Clone, Default, Serialize, Deserialize)]
+#[repr(transparent)]
+#[serde(transparent)]
+pub struct Metadata(BTreeMap);
+impl Metadata {
+ pub fn register(&mut self, name: &str, chunk: u16, position: usize) -> anyhow::Result<()> {
+ if self
+ .0
+ .insert(name.to_string(), (chunk, position.try_into()?))
+ .is_some()
+ {
+ bail!("Sprite {name} registered more than once");
+ }
+ Ok(())
+ }
+}
diff --git a/packages/item-assets/package.json b/packages/item-assets/package.json
new file mode 100644
index 0000000..e20887d
--- /dev/null
+++ b/packages/item-assets/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "skybook-item-assets",
+ "private": true,
+ "version": "0.0.0",
+ "files": [
+ "src/**/*"
+ ],
+ "exports": {
+ ".": "./src/index.ts"
+ },
+ "peerDependencies": {
+ "@griffel/react": "*",
+ "@types/react": "*",
+ "react": "*"
+ }
+}
diff --git a/packages/item-assets/src/ActorRemap.gen.ts b/packages/item-assets/src/ActorRemap.gen.ts
new file mode 100644
index 0000000..dde8535
--- /dev/null
+++ b/packages/item-assets/src/ActorRemap.gen.ts
@@ -0,0 +1,10 @@
+
+/**
+ * This file is generated by resolve-icon-actor.py
+ * DO NOT EDIT MANUALLY
+ */
+
+/** Actor name -> icon actor name, if different */
+export type ActorRemap = Record;
+
+export const ActorRemap: ActorRemap = JSON.parse(`{"Armor_086_Upper":"Armor_014_Upper","Armor_084_Upper":"Armor_014_Upper","Armor_085_Upper":"Armor_014_Upper","Armor_083_Upper":"Armor_014_Upper","Armor_234_Head":"Armor_230_Head","Armor_231_Head":"Armor_230_Head","Armor_233_Head":"Armor_230_Head","Armor_232_Head":"Armor_230_Head","Armor_229_Head":"Armor_225_Head","Armor_228_Head":"Armor_225_Head","Armor_227_Head":"Armor_225_Head","Armor_226_Head":"Armor_225_Head","Armor_097_Lower":"Armor_020_Lower","Armor_096_Lower":"Armor_020_Lower","Armor_095_Lower":"Armor_020_Lower","Armor_098_Lower":"Armor_020_Lower","Armor_214_Lower":"Armor_210_Lower","Armor_213_Lower":"Armor_210_Lower","Armor_211_Lower":"Armor_210_Lower","Armor_212_Lower":"Armor_210_Lower","Armor_226_Upper":"Armor_225_Upper","Armor_228_Upper":"Armor_225_Upper","Armor_227_Upper":"Armor_225_Upper","Armor_229_Upper":"Armor_225_Upper","Armor_204_Lower":"Armor_200_Lower","Armor_203_Lower":"Armor_200_Lower","Armor_201_Lower":"Armor_200_Lower","Armor_202_Lower":"Armor_200_Lower","Armor_208_Upper":"Armor_205_Upper","Armor_207_Upper":"Armor_205_Upper","Armor_206_Upper":"Armor_205_Upper","Armor_209_Upper":"Armor_205_Upper","Armor_217_Lower":"Armor_215_Lower","Armor_219_Lower":"Armor_215_Lower","Armor_216_Lower":"Armor_215_Lower","Armor_218_Lower":"Armor_215_Lower","Armor_004_Head":"Armor_001_Head","Armor_002_Head":"Armor_001_Head","Armor_003_Head":"Armor_001_Head","Armor_015_Head":"Armor_001_Head","Armor_036_Upper":"Armor_009_Upper","Armor_073_Upper":"Armor_009_Upper","Armor_072_Upper":"Armor_009_Upper","Armor_071_Upper":"Armor_009_Upper","Armor_132_Head":"Obj_Head_027","Armor_129_Head":"Obj_Head_027","Armor_027_Head":"Obj_Head_027","Armor_131_Head":"Obj_Head_027","Armor_130_Head":"Obj_Head_027","Armor_187_Head":"Armor_181_Head","Armor_188_Head":"Armor_181_Head","Armor_189_Head":"Armor_181_Head","Armor_186_Head":"Armor_181_Head","Armor_063_Lower":"Armor_006_Lower","Armor_064_Lower":"Armor_006_Lower","Armor_007_Lower":"Armor_006_Lower","Armor_062_Lower":"Armor_006_Lower","Armor_100_Upper":"Armor_021_Upper","Armor_102_Upper":"Armor_021_Upper","Armor_099_Upper":"Armor_021_Upper","Armor_101_Upper":"Armor_021_Upper","Armor_117_Head":"Obj_Head_024","Armor_119_Head":"Obj_Head_024","Armor_120_Head":"Obj_Head_024","Armor_024_Head":"Obj_Head_024","Armor_118_Head":"Obj_Head_024","Armor_063_Upper":"Armor_006_Upper","Armor_064_Upper":"Armor_006_Upper","Armor_062_Upper":"Armor_006_Upper","Armor_007_Upper":"Armor_006_Upper","Armor_084_Head":"Armor_014_Head","Armor_083_Head":"Armor_014_Head","Armor_086_Head":"Armor_014_Head","Armor_085_Head":"Armor_014_Head","Armor_214_Upper":"Armor_210_Upper","Armor_211_Upper":"Armor_210_Upper","Armor_213_Upper":"Armor_210_Upper","Armor_212_Upper":"Armor_210_Upper","Armor_036_Lower":"Armor_009_Lower","Armor_073_Lower":"Armor_009_Lower","Armor_072_Lower":"Armor_009_Lower","Armor_071_Lower":"Armor_009_Lower","Armor_111_Upper":"Armor_048_Upper","Armor_114_Upper":"Armor_048_Upper","Armor_113_Upper":"Armor_048_Upper","Armor_112_Upper":"Armor_048_Upper","Armor_100_Head":"Armor_021_Head","Armor_101_Head":"Armor_021_Head","Armor_099_Head":"Armor_021_Head","Armor_102_Head":"Armor_021_Head","Armor_156_Lower":"Armor_141_Lower","Armor_157_Lower":"Armor_141_Lower","Armor_140_Lower":"Armor_141_Lower","Armor_158_Lower":"Armor_141_Lower","Armor_159_Lower":"Armor_141_Lower","Armor_062_Head":"Armor_006_Head","Armor_063_Head":"Armor_006_Head","Armor_007_Head":"Armor_006_Head","Armor_064_Head":"Armor_006_Head","Armor_096_Upper":"Armor_020_Upper","Armor_098_Upper":"Armor_020_Upper","Armor_097_Upper":"Armor_020_Upper","Armor_095_Upper":"Armor_020_Upper","Weapon_Sword_072":"Weapon_Sword_070","Weapon_Sword_071":"Weapon_Sword_070","Weapon_Sword_081":"Weapon_Sword_070","Weapon_Sword_080":"Weapon_Sword_070","Armor_037_Upper":"Armor_011_Upper","Armor_075_Upper":"Armor_011_Upper","Armor_074_Upper":"Armor_011_Upper","Armor_076_Upper":"Armor_011_Upper","Armor_106_Lower":"Armor_046_Lower","Armor_105_Lower":"Armor_046_Lower","Armor_104_Lower":"Armor_046_Lower","Armor_103_Lower":"Armor_046_Lower","Armor_060_Head":"Armor_005_Head","Armor_039_Head":"Armor_005_Head","Armor_061_Head":"Armor_005_Head","Armor_035_Head":"Armor_005_Head","Armor_096_Head":"Armor_020_Head","Armor_097_Head":"Armor_020_Head","Armor_095_Head":"Armor_020_Head","Armor_098_Head":"Armor_020_Head","Armor_077_Lower":"Armor_012_Lower","Armor_042_Lower":"Armor_012_Lower","Armor_079_Lower":"Armor_012_Lower","Armor_078_Lower":"Armor_012_Lower","Armor_168_Head":"Armor_184_Head","Armor_198_Head":"Armor_184_Head","Armor_199_Head":"Armor_184_Head","Armor_169_Head":"Armor_184_Head","Armor_106_Upper":"Armor_046_Upper","Armor_103_Upper":"Armor_046_Upper","Armor_104_Upper":"Armor_046_Upper","Armor_105_Upper":"Armor_046_Upper","Armor_039_Upper":"Armor_005_Upper","Armor_061_Upper":"Armor_005_Upper","Armor_035_Upper":"Armor_005_Upper","Armor_060_Upper":"Armor_005_Upper","Armor_087_Lower":"Armor_017_Lower","Armor_090_Lower":"Armor_017_Lower","Armor_088_Lower":"Armor_017_Lower","Armor_089_Lower":"Armor_017_Lower","Armor_066_Lower":"Armor_008_Lower","Armor_040_Lower":"Armor_008_Lower","Armor_067_Lower":"Armor_008_Lower","Armor_065_Lower":"Armor_008_Lower","Armor_083_Lower":"Armor_014_Lower","Armor_085_Lower":"Armor_014_Lower","Armor_084_Lower":"Armor_014_Lower","Armor_086_Lower":"Armor_014_Lower","Armor_112_Lower":"Armor_048_Lower","Armor_113_Lower":"Armor_048_Lower","Armor_114_Lower":"Armor_048_Lower","Armor_111_Lower":"Armor_048_Lower","Armor_231_Upper":"Armor_230_Upper","Armor_233_Upper":"Armor_230_Upper","Armor_234_Upper":"Armor_230_Upper","Armor_232_Upper":"Armor_230_Upper","Armor_202_Upper":"Armor_200_Upper","Armor_201_Upper":"Armor_200_Upper","Armor_203_Upper":"Armor_200_Upper","Armor_204_Upper":"Armor_200_Upper","Armor_040_Upper":"Armor_008_Upper","Armor_065_Upper":"Armor_008_Upper","Armor_066_Upper":"Armor_008_Upper","Armor_067_Upper":"Armor_008_Upper","Armor_137_Head":"Obj_Head_029","Armor_140_Head":"Obj_Head_029","Armor_029_Head":"Obj_Head_029","Armor_139_Head":"Obj_Head_029","Armor_138_Head":"Obj_Head_029","Armor_211_Head":"Armor_210_Head","Armor_212_Head":"Armor_210_Head","Armor_213_Head":"Armor_210_Head","Armor_214_Head":"Armor_210_Head","Armor_123_Head":"Obj_Head_025","Armor_122_Head":"Obj_Head_025","Armor_124_Head":"Obj_Head_025","Armor_121_Head":"Obj_Head_025","Armor_025_Head":"Obj_Head_025","Armor_153_Lower":"Armor_049_Lower","Armor_152_Lower":"Armor_049_Lower","Armor_155_Lower":"Armor_049_Lower","Armor_154_Lower":"Armor_049_Lower","Armor_002_Lower":"Armor_001_Lower","Armor_015_Lower":"Armor_001_Lower","Armor_003_Lower":"Armor_001_Lower","Armor_004_Lower":"Armor_001_Lower","Armor_077_Upper":"Armor_012_Upper","Armor_079_Upper":"Armor_012_Upper","Armor_078_Upper":"Armor_012_Upper","Armor_042_Upper":"Armor_012_Upper","Armor_088_Upper":"Armor_017_Upper","Armor_089_Upper":"Armor_017_Upper","Armor_087_Upper":"Armor_017_Upper","Armor_090_Upper":"Armor_017_Upper","Armor_075_Head":"Armor_011_Head","Armor_037_Head":"Armor_011_Head","Armor_074_Head":"Armor_011_Head","Armor_076_Head":"Armor_011_Head","Armor_100_Lower":"Armor_021_Lower","Armor_101_Lower":"Armor_021_Lower","Armor_099_Lower":"Armor_021_Lower","Armor_102_Lower":"Armor_021_Lower","Armor_223_Head":"Armor_220_Head","Armor_222_Head":"Armor_220_Head","Armor_221_Head":"Armor_220_Head","Armor_224_Head":"Armor_220_Head","Armor_193_Head":"Armor_182_Head","Armor_192_Head":"Armor_182_Head","Armor_191_Head":"Armor_182_Head","Armor_190_Head":"Armor_182_Head","Armor_229_Lower":"Armor_225_Lower","Armor_227_Lower":"Armor_225_Lower","Armor_226_Lower":"Armor_225_Lower","Armor_228_Lower":"Armor_225_Lower","Armor_072_Head":"Armor_009_Head","Armor_071_Head":"Armor_009_Head","Armor_073_Head":"Armor_009_Head","Armor_036_Head":"Armor_009_Head","Armor_231_Lower":"Armor_230_Lower","Armor_233_Lower":"Armor_230_Lower","Armor_234_Lower":"Armor_230_Lower","Armor_232_Lower":"Armor_230_Lower","Armor_015_Upper":"Armor_001_Upper","Armor_004_Upper":"Armor_001_Upper","Armor_002_Upper":"Armor_001_Upper","Armor_003_Upper":"Armor_001_Upper","Armor_077_Head":"Armor_012_Head","Armor_078_Head":"Armor_012_Head","Armor_079_Head":"Armor_012_Head","Armor_042_Head":"Armor_012_Head","Armor_065_Head":"Armor_008_Head","Armor_067_Head":"Armor_008_Head","Armor_066_Head":"Armor_008_Head","Armor_040_Head":"Armor_008_Head","Armor_134_Head":"Obj_Head_028","Armor_136_Head":"Obj_Head_028","Armor_028_Head":"Obj_Head_028","Armor_135_Head":"Obj_Head_028","Armor_133_Head":"Obj_Head_028","Armor_039_Lower":"Armor_005_Lower","Armor_035_Lower":"Armor_005_Lower","Armor_061_Lower":"Armor_005_Lower","Armor_060_Lower":"Armor_005_Lower","Armor_219_Head":"Armor_215_Head","Armor_217_Head":"Armor_215_Head","Armor_216_Head":"Armor_215_Head","Armor_218_Head":"Armor_215_Head","Armor_089_Head":"Armor_017_Head","Armor_090_Head":"Armor_017_Head","Armor_088_Head":"Armor_017_Head","Armor_087_Head":"Armor_017_Head","Armor_074_Lower":"Armor_011_Lower","Armor_075_Lower":"Armor_011_Lower","Armor_037_Lower":"Armor_011_Lower","Armor_076_Lower":"Armor_011_Lower","Armor_194_Head":"Armor_183_Head","Armor_196_Head":"Armor_183_Head","Armor_197_Head":"Armor_183_Head","Armor_195_Head":"Armor_183_Head","Armor_125_Head":"Obj_Head_026","Armor_026_Head":"Obj_Head_026","Armor_126_Head":"Obj_Head_026","Armor_128_Head":"Obj_Head_026","Armor_127_Head":"Obj_Head_026","Armor_113_Head":"Armor_048_Head","Armor_114_Head":"Armor_048_Head","Armor_111_Head":"Armor_048_Head","Armor_112_Head":"Armor_048_Head","Armor_103_Head":"Armor_046_Head","Armor_106_Head":"Armor_046_Head","Armor_104_Head":"Armor_046_Head","Armor_105_Head":"Armor_046_Head","Obj_SheikPadLv2":"Obj_DRStone_Get","Armor_148_Upper":"Armor_116_Upper","Armor_149_Upper":"Armor_116_Upper","Armor_151_Upper":"Armor_116_Upper","Armor_150_Upper":"Armor_116_Upper","Armor_206_Lower":"Armor_205_Lower","Armor_207_Lower":"Armor_205_Lower","Armor_208_Lower":"Armor_205_Lower","Armor_209_Lower":"Armor_205_Lower","Armor_208_Head":"Armor_205_Head","Armor_206_Head":"Armor_205_Head","Armor_209_Head":"Armor_205_Head","Armor_207_Head":"Armor_205_Head","Armor_218_Upper":"Armor_215_Upper","Armor_219_Upper":"Armor_215_Upper","Armor_216_Upper":"Armor_215_Upper","Armor_217_Upper":"Armor_215_Upper","Armor_202_Head":"Armor_200_Head","Armor_203_Head":"Armor_200_Head","Armor_204_Head":"Armor_200_Head","Armor_201_Head":"Armor_200_Head"}`);
diff --git a/packages/item-assets/src/ActorSprite.tsx b/packages/item-assets/src/ActorSprite.tsx
new file mode 100644
index 0000000..40ebca3
--- /dev/null
+++ b/packages/item-assets/src/ActorSprite.tsx
@@ -0,0 +1,281 @@
+import { memo } from "react";
+import { makeStaticStyles, makeStyles, mergeClasses } from "@griffel/react";
+
+import { ActorChunkClasses, ActorMetadata } from "./sprites/ActorMetadata.gen.ts";
+import { ActorRemap } from "./ActorRemap.gen.ts";
+
+export type ActorSpriteProps = {
+ /** Name of the Actor to display */
+ actor: string;
+
+ /**
+ * Name of the Cook effect if any (as in msyt translation files)
+ *
+ * This is to display the correct icon for elixirs.
+ * Ignored if Actor is not "Item_Cook_C_17"
+ */
+ effect?: string;
+
+ /**
+ * Use the low resolution/quality version of images. Also
+ * disables animations
+ */
+ cheap?: boolean;
+
+ /**
+ * Disable all animations even if `cheap` is false
+ */
+ disableAnimation?: boolean;
+
+ /**
+ * Use styles to indicate that this slot is supposed to
+ * not have an icon in the game (like multiple animated slots)
+ */
+ blank?: boolean;
+
+ /**
+ * Display the red effect for badly damaged
+ *
+ * The implementation only shows for non-animated images, which
+ * is true for all weapons
+ */
+ badlyDamaged?: boolean;
+
+ /**
+ * Use the deactivated state of certain actors
+ * - Master Sword (any): The state where the sword is recharging
+ * - One-hit Obliterator (502): The state where weapon is recharging
+ * - Champion Abilities: disabled state
+ */
+ deactive?: boolean;
+
+ /**
+ * Use the "powered up" state for Master Sword
+ */
+ powered?: boolean;
+};
+
+const useChunkClasses = makeStaticStyles(ActorChunkClasses);
+
+const useStyles = makeStyles({
+ sprite: {
+ backgroundRepeat: "no-repeat",
+ width: "64px",
+ height: "64px",
+ display: "block",
+ },
+ cheap: {
+ backgroundSize: "1024px", // for some reason 200% doesn't work
+ },
+ spriteSoulImage: {
+ position: "relative",
+ },
+ animatedSimple: {
+ backgroundSize: "64px",
+ },
+ soulOffset: {
+ top: "-11.4px",
+ },
+ soulOffsetDLC: {
+ top: "-19px",
+ left: "0px",
+ },
+ blank: {
+ filter: "grayscale(100%)",
+ opacity: 0.8,
+ },
+ deactiveMasterSword: {
+ opacity: 0.5,
+ },
+ damageContainer:{
+ overflow: "hidden",
+ },
+ damage: {
+ width: "1024px",
+ height: "1024px",
+ backgroundColor: "rgba(255, 0, 0, 0.6)",
+ },
+ damageCheap: {
+ transformOrigin: "top left",
+ scale: 2,
+ width: "512px",
+ height: "512px",
+ backgroundColor: "rgba(255, 0, 0, 0.6)",
+ },
+ damageAnimation: {
+ animationIterationCount: "infinite",
+ animationDuration: "1s",
+ animationName: {
+ "0%": {
+ opacity: 1,
+ },
+ "25%": {
+ opacity: 0.9,
+ },
+ "50%": {
+ opacity: 0.7,
+ },
+ "75%": {
+ opacity: 0.4,
+ },
+ "100%": {
+ opacity: 0,
+ },
+ }
+ }
+});
+
+const SpriteImpl: React.FC = ({ actor, effect, cheap, disableAnimation, deactive, powered, blank, badlyDamaged}) => {
+ useChunkClasses();
+ const styles = useStyles();
+
+ let baseClass = mergeClasses(styles.sprite, blank && styles.blank);
+
+ disableAnimation = disableAnimation || cheap;
+
+ // Handle simple animated images - Travel Medallion, 5 orbs
+ // if not animated, it's in the sprite sheet
+ if (!disableAnimation) {
+ if (/Obj_(WarpDLC|DungeonClearSeal|HeroSeal_(Gerudo|Goron|Rito|Zora))/.test(actor)) {
+ return (
+
+ );
+ }
+ }
+
+ const iconActor = mapActor(actor, !!deactive, !!powered, effect);
+ if (iconActor === "Weapon_Sword_070_Disabled") {
+ baseClass = mergeClasses(baseClass, styles.deactiveMasterSword);
+ }
+
+ // Special handling for Champion Abilities:
+ // - Active ones are larger and needs to be offseted
+ // - Deactive ones has animation
+ if (isChampionAbility(iconActor)) {
+ const dlc = iconActor.includes("DLC");
+ // active - either animated or not, with offset
+ if (!deactive) {
+ const ext = disableAnimation ? "png" : "webp";
+ return (
+
+
+
+
+ );
+ }
+ // inactive - if animated, use different sprite
+ if (!disableAnimation) {
+ return (
+
+ );
+ }
+ }
+
+ const [chunk, position] = ActorMetadata[iconActor];
+ const backgroundPosition = getBackgroundPosition(position);
+
+ const chunkClass = `chunk${chunk}x${cheap ? "32" : "64"}`
+
+ return (
+
+ {
+ badlyDamaged && (
+
+ )
+ }
+
+ );
+};
+
+export const ActorSprite = memo(SpriteImpl);
+
+/**
+ * Remap an actor to its icon actor name
+ */
+const mapActor = (
+ actor: string,
+ deactive: boolean,
+ powered: boolean,
+ effect: string | undefined
+): string => {
+ // cannot manually pass in a "Disabled" actor
+ if (actor.endsWith("_Disabled")) {
+ return "Dummy";
+ }
+ // Remap actor name to icon actor name
+ if (actor in ActorRemap) {
+ actor = ActorRemap[actor];
+ }
+
+ // Master Sword
+ if (actor === "Weapon_Sword_070") {
+ if (deactive) {
+ return "Weapon_Sword_070_Disabled";
+ }
+ if (powered) {
+ return "Weapon_Sword_072";
+ }
+ }
+
+ // regular OHO, use powered up icon unless deactivated
+ if (!deactive && actor === "Weapon_Sword_502") {
+ actor = "Weapon_Sword_503";
+ }
+
+ // Champion Abilities
+ if (isChampionAbility(actor)) {
+ // need to return here because animated images are not
+ // in Dummy
+ if (deactive) {
+ return `${actor}_Disabled`;
+ }
+ return actor;
+ }
+
+ // Elixirs - they are the same actor, but icon
+ // depends on the effect
+ if (effect && actor === "Item_Cook_C_17") {
+ actor = `${actor}_${effect}`;
+ }
+
+ if (!(actor in ActorMetadata)) {
+ return "Dummy";
+ }
+ return actor;
+};
+
+
+const getBackgroundPosition = (position: number) => {
+ const NUM = 16;
+ const SIZE = 64;
+ const x = position % NUM;
+ const y = Math.floor(position / NUM);
+ return `-${x * SIZE}px -${y * SIZE}px`;
+}
+
+const isChampionAbility = (actor: string) => {
+ return /^Obj_(DLC_)?HeroSoul_(Gerudo|Goron|Rito|Zora)(_Disabled)?$/.test(actor);
+}
diff --git a/packages/item-assets/src/ModifierSprite.tsx b/packages/item-assets/src/ModifierSprite.tsx
new file mode 100644
index 0000000..b86038c
--- /dev/null
+++ b/packages/item-assets/src/ModifierSprite.tsx
@@ -0,0 +1,51 @@
+import { makeStaticStyles, makeStyles, mergeClasses } from "@griffel/react";
+import { memo } from "react";
+
+import { ModifierChunkClasses, ModifierMetadata } from "./sprites/ModifierMetadata.gen.ts";
+
+export type ModifierSpriteProps = {
+ /** Name of the special status to show */
+ status: string;
+}
+
+const useChunkClasses = makeStaticStyles(ModifierChunkClasses);
+
+const useStyles = makeStyles({
+ sprite: {
+ backgroundRepeat: "no-repeat",
+ backgroundSize: "160px 160px", // 20px * 8
+ width: "20px",
+ height: "20px",
+ display: "block",
+ }
+});
+
+const SpriteImpl: React.FC = ({ status }) => {
+ useChunkClasses();
+ const styles = useStyles();
+ if (!ModifierMetadata[status]) {
+ return null;
+ }
+ const [_, position] = ModifierMetadata[status];
+ const backgroundPosition = getBackgroundPosition(position);
+
+
+ return (
+
+
+ );
+};
+
+export const ModifierSprite = memo(SpriteImpl);
+
+const getBackgroundPosition = (position: number) => {
+ const NUM = 8;
+ const SIZE = 20;
+ const x = position % NUM;
+ const y = Math.floor(position / NUM);
+ return `-${x * SIZE}px -${y * SIZE}px`;
+}
diff --git a/packages/item-assets/src/images/index.ts b/packages/item-assets/src/images/index.ts
new file mode 100644
index 0000000..dc6af88
--- /dev/null
+++ b/packages/item-assets/src/images/index.ts
@@ -0,0 +1,10 @@
+import { makeStyles } from "@griffel/react";
+import sheikahBg from "./SheikahBackground.png?url";
+
+/** Get the styles for using static assets */
+export const useStaticAssetStyles = makeStyles({
+ /** Use the sheikah background image */
+ sheikahBg: {
+ backgroundImage: `url(${sheikahBg})`,
+ }
+});
diff --git a/packages/item-assets/src/index.ts b/packages/item-assets/src/index.ts
new file mode 100644
index 0000000..a034100
--- /dev/null
+++ b/packages/item-assets/src/index.ts
@@ -0,0 +1,5 @@
+export * from "./images/index.ts";
+export * from "./sprites/ActorMetadata.gen.ts";
+export * from "./sprites/ModifierMetadata.gen.ts";
+export * from "./ActorSprite.tsx";
+export * from "./ModifierSprite.tsx";
diff --git a/packages/item-assets/src/sprites/ActorMetadata.gen.ts b/packages/item-assets/src/sprites/ActorMetadata.gen.ts
new file mode 100644
index 0000000..dffed1e
--- /dev/null
+++ b/packages/item-assets/src/sprites/ActorMetadata.gen.ts
@@ -0,0 +1,23 @@
+import chunk0x32 from "./chunk0x32.webp?url";
+import chunk1x32 from "./chunk1x32.webp?url";
+import chunk2x32 from "./chunk2x32.webp?url";
+import chunk0x64 from "./chunk0x64.webp?url";
+import chunk1x64 from "./chunk1x64.webp?url";
+import chunk2x64 from "./chunk2x64.webp?url";
+export const ActorChunkClasses = {
+ ".sprite-chunk0x32": { backgroundImage: `url(${chunk0x32})` },
+ ".sprite-chunk1x32": { backgroundImage: `url(${chunk1x32})` },
+ ".sprite-chunk2x32": { backgroundImage: `url(${chunk2x32})` },
+ ".sprite-chunk0x64": { backgroundImage: `url(${chunk0x64})` },
+ ".sprite-chunk1x64": { backgroundImage: `url(${chunk1x64})` },
+ ".sprite-chunk2x64": { backgroundImage: `url(${chunk2x64})` },
+ ".sprite-mask-chunk0x32": { maskImage: `url(${chunk0x32})` },
+ ".sprite-mask-chunk1x32": { maskImage: `url(${chunk1x32})` },
+ ".sprite-mask-chunk2x32": { maskImage: `url(${chunk2x32})` },
+ ".sprite-mask-chunk0x64": { maskImage: `url(${chunk0x64})` },
+ ".sprite-mask-chunk1x64": { maskImage: `url(${chunk1x64})` },
+ ".sprite-mask-chunk2x64": { maskImage: `url(${chunk2x64})` },
+} as const;
+/** Actor => [Chunk, Position]*/
+export type ActorMetadata = Record;
+export const ActorMetadata: ActorMetadata = JSON.parse(`{"AncientArrow":[1,0],"Animal_Insect_A":[0,0],"Animal_Insect_AA":[0,1],"Animal_Insect_AB":[0,2],"Animal_Insect_B":[0,3],"Animal_Insect_C":[0,4],"Animal_Insect_E":[0,5],"Animal_Insect_F":[0,6],"Animal_Insect_G":[0,7],"Animal_Insect_H":[0,8],"Animal_Insect_I":[0,9],"Animal_Insect_M":[0,10],"Animal_Insect_N":[0,11],"Animal_Insect_P":[0,12],"Animal_Insect_Q":[0,13],"Animal_Insect_R":[0,14],"Animal_Insect_S":[0,15],"Animal_Insect_T":[0,16],"Animal_Insect_X":[0,17],"Armor_001_Head":[2,0],"Armor_001_Lower":[2,47],"Armor_001_Upper":[2,76],"Armor_005_Head":[2,1],"Armor_005_Lower":[2,48],"Armor_005_Upper":[2,77],"Armor_006_Head":[2,2],"Armor_006_Lower":[2,49],"Armor_006_Upper":[2,78],"Armor_008_Head":[2,3],"Armor_008_Lower":[2,50],"Armor_008_Upper":[2,79],"Armor_009_Head":[2,4],"Armor_009_Lower":[2,51],"Armor_009_Upper":[2,80],"Armor_011_Head":[2,5],"Armor_011_Lower":[2,52],"Armor_011_Upper":[2,81],"Armor_012_Head":[2,6],"Armor_012_Lower":[2,53],"Armor_012_Upper":[2,82],"Armor_014_Head":[2,7],"Armor_014_Lower":[2,54],"Armor_014_Upper":[2,83],"Armor_017_Head":[2,8],"Armor_017_Lower":[2,55],"Armor_017_Upper":[2,84],"Armor_020_Head":[2,9],"Armor_020_Lower":[2,56],"Armor_020_Upper":[2,85],"Armor_021_Head":[2,10],"Armor_021_Lower":[2,57],"Armor_021_Upper":[2,86],"Armor_022_Head":[2,11],"Armor_043_Lower":[2,58],"Armor_043_Upper":[2,87],"Armor_044_Upper":[2,88],"Armor_045_Head":[2,12],"Armor_046_Head":[2,13],"Armor_046_Lower":[2,59],"Armor_046_Upper":[2,89],"Armor_048_Head":[2,14],"Armor_048_Lower":[2,60],"Armor_048_Upper":[2,90],"Armor_049_Lower":[2,61],"Armor_053_Head":[2,15],"Armor_053_Lower":[2,62],"Armor_053_Upper":[2,91],"Armor_055_Head":[2,16],"Armor_056_Head":[2,17],"Armor_115_Head":[2,18],"Armor_116_Upper":[2,92],"Armor_141_Lower":[2,63],"Armor_160_Head":[2,19],"Armor_160_Lower":[2,64],"Armor_160_Upper":[2,93],"Armor_170_Upper":[2,94],"Armor_171_Head":[2,20],"Armor_171_Lower":[2,65],"Armor_171_Upper":[2,95],"Armor_172_Head":[2,21],"Armor_173_Head":[2,22],"Armor_174_Head":[2,23],"Armor_174_Lower":[2,66],"Armor_174_Upper":[2,96],"Armor_175_Upper":[2,97],"Armor_176_Head":[2,24],"Armor_177_Head":[2,25],"Armor_178_Head":[2,26],"Armor_179_Head":[2,27],"Armor_179_Lower":[2,67],"Armor_179_Upper":[2,98],"Armor_180_Head":[2,28],"Armor_180_Lower":[2,68],"Armor_180_Upper":[2,99],"Armor_181_Head":[2,29],"Armor_182_Head":[2,30],"Armor_183_Head":[2,31],"Armor_184_Head":[2,32],"Armor_185_Head":[2,33],"Armor_185_Lower":[2,69],"Armor_185_Upper":[2,100],"Armor_200_Head":[2,34],"Armor_200_Lower":[2,70],"Armor_200_Upper":[2,101],"Armor_205_Head":[2,35],"Armor_205_Lower":[2,71],"Armor_205_Upper":[2,102],"Armor_210_Head":[2,36],"Armor_210_Lower":[2,72],"Armor_210_Upper":[2,103],"Armor_215_Head":[2,37],"Armor_215_Lower":[2,73],"Armor_215_Upper":[2,104],"Armor_220_Head":[2,38],"Armor_225_Head":[2,39],"Armor_225_Lower":[2,74],"Armor_225_Upper":[2,105],"Armor_230_Head":[2,40],"Armor_230_Lower":[2,75],"Armor_230_Upper":[2,106],"BeeHome":[0,18],"BombArrow_A":[1,1],"BrightArrow":[1,2],"BrightArrowTP":[1,3],"Dummy":[2,248],"ElectricArrow":[1,4],"FireArrow":[1,5],"GameRomHorseReins_01":[2,107],"GameRomHorseReins_02":[2,108],"GameRomHorseReins_03":[2,109],"GameRomHorseReins_04":[2,110],"GameRomHorseReins_05":[2,111],"GameRomHorseReins_10":[2,112],"GameRomHorseSaddle_01":[2,113],"GameRomHorseSaddle_02":[2,114],"GameRomHorseSaddle_03":[2,115],"GameRomHorseSaddle_04":[2,116],"GameRomHorseSaddle_05":[2,117],"GameRomHorseSaddle_10":[2,118],"Get_TwnObj_DLC_MemorialPicture_A_01":[0,19],"IceArrow":[1,6],"Item_Boiled_01":[0,20],"Item_ChilledFish_01":[0,21],"Item_ChilledFish_02":[0,22],"Item_ChilledFish_03":[0,23],"Item_ChilledFish_04":[0,24],"Item_ChilledFish_05":[0,25],"Item_ChilledFish_06":[0,26],"Item_ChilledFish_07":[0,27],"Item_ChilledFish_08":[0,28],"Item_ChilledFish_09":[0,29],"Item_Chilled_01":[0,30],"Item_Chilled_02":[0,31],"Item_Chilled_03":[0,32],"Item_Chilled_04":[0,33],"Item_Chilled_05":[0,34],"Item_Chilled_06":[0,35],"Item_Cook_A_01":[2,119],"Item_Cook_A_02":[2,120],"Item_Cook_A_03":[2,121],"Item_Cook_A_04":[2,122],"Item_Cook_A_05":[2,123],"Item_Cook_A_07":[2,124],"Item_Cook_A_08":[2,125],"Item_Cook_A_09":[2,126],"Item_Cook_A_10":[2,127],"Item_Cook_A_11":[2,128],"Item_Cook_A_12":[2,129],"Item_Cook_A_13":[2,130],"Item_Cook_A_14":[2,131],"Item_Cook_B_01":[2,132],"Item_Cook_B_02":[2,133],"Item_Cook_B_05":[2,134],"Item_Cook_B_06":[2,135],"Item_Cook_B_11":[2,136],"Item_Cook_B_12":[2,137],"Item_Cook_B_13":[2,138],"Item_Cook_B_15":[2,139],"Item_Cook_B_16":[2,140],"Item_Cook_B_17":[2,141],"Item_Cook_B_18":[2,142],"Item_Cook_B_19":[2,143],"Item_Cook_B_20":[2,144],"Item_Cook_B_21":[2,145],"Item_Cook_B_22":[2,146],"Item_Cook_B_23":[2,147],"Item_Cook_C_16":[2,148],"Item_Cook_C_17":[2,149],"Item_Cook_C_17_AllSpeed":[2,150],"Item_Cook_C_17_AttackUp":[2,151],"Item_Cook_C_17_DefenseUp":[2,152],"Item_Cook_C_17_ExGutsMaxUp":[2,153],"Item_Cook_C_17_Fireproof":[2,154],"Item_Cook_C_17_GutsRecover":[2,155],"Item_Cook_C_17_LifeMaxUp":[2,156],"Item_Cook_C_17_Quietness":[2,157],"Item_Cook_C_17_ResistCold":[2,158],"Item_Cook_C_17_ResistElectric":[2,159],"Item_Cook_C_17_ResistHot":[2,160],"Item_Cook_D_01":[2,161],"Item_Cook_D_02":[2,162],"Item_Cook_D_03":[2,163],"Item_Cook_D_04":[2,164],"Item_Cook_D_05":[2,165],"Item_Cook_D_06":[2,166],"Item_Cook_D_07":[2,167],"Item_Cook_D_08":[2,168],"Item_Cook_D_09":[2,169],"Item_Cook_D_10":[2,170],"Item_Cook_E_01":[2,171],"Item_Cook_E_02":[2,172],"Item_Cook_E_03":[2,173],"Item_Cook_E_04":[2,174],"Item_Cook_F_01":[2,175],"Item_Cook_F_02":[2,176],"Item_Cook_F_03":[2,177],"Item_Cook_F_04":[2,178],"Item_Cook_G_02":[2,179],"Item_Cook_G_03":[2,180],"Item_Cook_G_04":[2,181],"Item_Cook_G_05":[2,182],"Item_Cook_G_06":[2,183],"Item_Cook_G_09":[2,184],"Item_Cook_G_10":[2,185],"Item_Cook_G_11":[2,186],"Item_Cook_G_12":[2,187],"Item_Cook_G_13":[2,188],"Item_Cook_G_14":[2,189],"Item_Cook_G_15":[2,190],"Item_Cook_G_16":[2,191],"Item_Cook_G_17":[2,192],"Item_Cook_H_01":[2,193],"Item_Cook_H_02":[2,194],"Item_Cook_H_03":[2,195],"Item_Cook_I_01":[2,196],"Item_Cook_I_02":[2,197],"Item_Cook_I_03":[2,198],"Item_Cook_I_04":[2,199],"Item_Cook_I_05":[2,200],"Item_Cook_I_06":[2,201],"Item_Cook_I_07":[2,202],"Item_Cook_I_08":[2,203],"Item_Cook_I_09":[2,204],"Item_Cook_I_10":[2,205],"Item_Cook_I_11":[2,206],"Item_Cook_I_12":[2,207],"Item_Cook_I_13":[2,208],"Item_Cook_I_14":[2,209],"Item_Cook_I_15":[2,210],"Item_Cook_I_16":[2,211],"Item_Cook_I_17":[2,212],"Item_Cook_J_01":[2,213],"Item_Cook_J_02":[2,214],"Item_Cook_J_03":[2,215],"Item_Cook_J_04":[2,216],"Item_Cook_J_05":[2,217],"Item_Cook_J_06":[2,218],"Item_Cook_J_07":[2,219],"Item_Cook_J_08":[2,220],"Item_Cook_J_09":[2,221],"Item_Cook_K_01":[2,222],"Item_Cook_K_02":[2,223],"Item_Cook_K_03":[2,224],"Item_Cook_K_04":[2,225],"Item_Cook_K_05":[2,226],"Item_Cook_K_06":[2,227],"Item_Cook_K_07":[2,228],"Item_Cook_K_08":[2,229],"Item_Cook_K_09":[2,230],"Item_Cook_L_01":[2,231],"Item_Cook_L_02":[2,232],"Item_Cook_L_03":[2,233],"Item_Cook_L_04":[2,234],"Item_Cook_L_05":[2,235],"Item_Cook_M_01":[2,236],"Item_Cook_N_01":[2,237],"Item_Cook_N_02":[2,238],"Item_Cook_N_03":[2,239],"Item_Cook_N_04":[2,240],"Item_Cook_O_01":[2,241],"Item_Cook_O_02":[2,242],"Item_Cook_P_01":[2,243],"Item_Cook_P_02":[2,244],"Item_Cook_P_03":[2,245],"Item_Cook_P_04":[2,246],"Item_Cook_P_05":[2,247],"Item_Enemy_00":[0,36],"Item_Enemy_01":[0,37],"Item_Enemy_02":[0,38],"Item_Enemy_03":[0,39],"Item_Enemy_04":[0,40],"Item_Enemy_05":[0,41],"Item_Enemy_06":[0,42],"Item_Enemy_07":[0,43],"Item_Enemy_08":[0,44],"Item_Enemy_12":[0,45],"Item_Enemy_13":[0,46],"Item_Enemy_14":[0,47],"Item_Enemy_15":[0,48],"Item_Enemy_16":[0,49],"Item_Enemy_17":[0,50],"Item_Enemy_18":[0,51],"Item_Enemy_19":[0,52],"Item_Enemy_20":[0,53],"Item_Enemy_21":[0,54],"Item_Enemy_24":[0,55],"Item_Enemy_25":[0,56],"Item_Enemy_26":[0,57],"Item_Enemy_27":[0,58],"Item_Enemy_28":[0,59],"Item_Enemy_29":[0,60],"Item_Enemy_30":[0,61],"Item_Enemy_31":[0,62],"Item_Enemy_32":[0,63],"Item_Enemy_33":[0,64],"Item_Enemy_34":[0,65],"Item_Enemy_38":[0,66],"Item_Enemy_39":[0,67],"Item_Enemy_40":[0,68],"Item_Enemy_41":[0,69],"Item_Enemy_42":[0,70],"Item_Enemy_43":[0,71],"Item_Enemy_44":[0,72],"Item_Enemy_45":[0,73],"Item_Enemy_46":[0,74],"Item_Enemy_47":[0,75],"Item_Enemy_48":[0,76],"Item_Enemy_49":[0,77],"Item_Enemy_50":[0,78],"Item_Enemy_51":[0,79],"Item_Enemy_52":[0,80],"Item_Enemy_53":[0,81],"Item_Enemy_54":[0,82],"Item_Enemy_55":[0,83],"Item_Enemy_56":[0,84],"Item_Enemy_57":[0,85],"Item_FishGet_A":[0,86],"Item_FishGet_B":[0,87],"Item_FishGet_C":[0,88],"Item_FishGet_D":[0,89],"Item_FishGet_E":[0,90],"Item_FishGet_F":[0,91],"Item_FishGet_G":[0,92],"Item_FishGet_H":[0,93],"Item_FishGet_I":[0,94],"Item_FishGet_J":[0,95],"Item_FishGet_K":[0,96],"Item_FishGet_L":[0,97],"Item_FishGet_M":[0,98],"Item_FishGet_X":[0,99],"Item_FishGet_Z":[0,100],"Item_Fruit_A":[0,101],"Item_Fruit_B":[0,102],"Item_Fruit_C":[0,103],"Item_Fruit_D":[0,104],"Item_Fruit_E":[0,105],"Item_Fruit_F":[0,106],"Item_Fruit_G":[0,107],"Item_Fruit_H":[0,108],"Item_Fruit_I":[0,109],"Item_Fruit_J":[0,110],"Item_Fruit_K":[0,111],"Item_Fruit_L":[0,112],"Item_InsectGet_K":[0,113],"Item_InsectGet_O":[0,114],"Item_InsectGet_Z":[0,115],"Item_Material_01":[0,116],"Item_Material_02":[0,117],"Item_Material_03":[0,118],"Item_Material_04":[0,119],"Item_Material_05":[0,120],"Item_Material_06":[0,121],"Item_Material_07":[0,122],"Item_Material_08":[0,123],"Item_Meat_01":[0,124],"Item_Meat_02":[0,125],"Item_Meat_06":[0,126],"Item_Meat_07":[0,127],"Item_Meat_11":[0,128],"Item_Meat_12":[0,129],"Item_MushroomGet_D":[0,130],"Item_Mushroom_A":[0,131],"Item_Mushroom_B":[0,132],"Item_Mushroom_C":[0,133],"Item_Mushroom_E":[0,134],"Item_Mushroom_F":[0,135],"Item_Mushroom_H":[0,136],"Item_Mushroom_J":[0,137],"Item_Mushroom_L":[0,138],"Item_Mushroom_M":[0,139],"Item_Mushroom_N":[0,140],"Item_Mushroom_O":[0,141],"Item_Ore_A":[0,142],"Item_Ore_B":[0,143],"Item_Ore_C":[0,144],"Item_Ore_D":[0,145],"Item_Ore_E":[0,146],"Item_Ore_F":[0,147],"Item_Ore_G":[0,148],"Item_Ore_H":[0,149],"Item_Ore_I":[0,150],"Item_Ore_J":[0,151],"Item_PlantGet_A":[0,152],"Item_PlantGet_B":[0,153],"Item_PlantGet_C":[0,154],"Item_PlantGet_E":[0,155],"Item_PlantGet_F":[0,156],"Item_PlantGet_G":[0,157],"Item_PlantGet_H":[0,158],"Item_PlantGet_I":[0,159],"Item_PlantGet_J":[0,160],"Item_PlantGet_L":[0,161],"Item_PlantGet_M":[0,162],"Item_PlantGet_O":[0,163],"Item_PlantGet_Q":[0,164],"Item_RoastFish_01":[0,165],"Item_RoastFish_02":[0,166],"Item_RoastFish_03":[0,167],"Item_RoastFish_04":[0,168],"Item_RoastFish_07":[0,169],"Item_RoastFish_09":[0,170],"Item_RoastFish_11":[0,171],"Item_RoastFish_13":[0,172],"Item_RoastFish_15":[0,173],"Item_Roast_01":[0,174],"Item_Roast_02":[0,175],"Item_Roast_03":[0,176],"Item_Roast_04":[0,177],"Item_Roast_05":[0,178],"Item_Roast_06":[0,179],"Item_Roast_07":[0,180],"Item_Roast_08":[0,181],"Item_Roast_09":[0,182],"Item_Roast_10":[0,183],"Item_Roast_11":[0,184],"Item_Roast_12":[0,185],"Item_Roast_13":[0,186],"Item_Roast_15":[0,187],"Item_Roast_16":[0,188],"Item_Roast_18":[0,189],"Item_Roast_19":[0,190],"Item_Roast_24":[0,191],"Item_Roast_27":[0,192],"Item_Roast_28":[0,193],"Item_Roast_31":[0,194],"Item_Roast_32":[0,195],"Item_Roast_33":[0,196],"Item_Roast_36":[0,197],"Item_Roast_37":[0,198],"Item_Roast_38":[0,199],"Item_Roast_39":[0,200],"Item_Roast_40":[0,201],"Item_Roast_41":[0,202],"Item_Roast_45":[0,203],"Item_Roast_46":[0,204],"Item_Roast_48":[0,205],"Item_Roast_49":[0,206],"Item_Roast_50":[0,207],"Item_Roast_51":[0,208],"Item_Roast_52":[0,209],"Item_Roast_53":[0,210],"NormalArrow":[1,7],"Obj_Armor_115_Head":[0,211],"Obj_DLC_HeroSeal_Gerudo":[0,212],"Obj_DLC_HeroSeal_Goron":[0,213],"Obj_DLC_HeroSeal_Rito":[0,214],"Obj_DLC_HeroSeal_Zora":[0,215],"Obj_DLC_HeroSoul_Gerudo_Disabled":[0,216],"Obj_DLC_HeroSoul_Goron_Disabled":[0,217],"Obj_DLC_HeroSoul_Rito_Disabled":[0,218],"Obj_DLC_HeroSoul_Zora_Disabled":[0,219],"Obj_DRStone_Get":[0,231],"Obj_DungeonClearSeal":[0,220],"Obj_FireWoodBundle":[0,221],"Obj_Head_024":[2,41],"Obj_Head_025":[2,42],"Obj_Head_026":[2,43],"Obj_Head_027":[2,44],"Obj_Head_028":[2,45],"Obj_Head_029":[2,46],"Obj_HeroSoul_Gerudo_Disabled":[0,222],"Obj_HeroSoul_Goron_Disabled":[0,223],"Obj_HeroSoul_Rito_Disabled":[0,224],"Obj_HeroSoul_Zora_Disabled":[0,225],"Obj_KorokNuts":[0,226],"Obj_Maracas":[0,227],"Obj_ProofBook":[0,228],"Obj_ProofKorok":[0,229],"Obj_WarpDLC":[0,230],"PlayerStole2":[0,232],"Weapon_Bow_001":[1,8],"Weapon_Bow_002":[1,9],"Weapon_Bow_003":[1,10],"Weapon_Bow_004":[1,11],"Weapon_Bow_006":[1,12],"Weapon_Bow_009":[1,13],"Weapon_Bow_011":[1,14],"Weapon_Bow_013":[1,15],"Weapon_Bow_014":[1,16],"Weapon_Bow_015":[1,17],"Weapon_Bow_016":[1,18],"Weapon_Bow_017":[1,19],"Weapon_Bow_023":[1,20],"Weapon_Bow_026":[1,21],"Weapon_Bow_027":[1,22],"Weapon_Bow_028":[1,23],"Weapon_Bow_029":[1,24],"Weapon_Bow_030":[1,25],"Weapon_Bow_032":[1,26],"Weapon_Bow_033":[1,27],"Weapon_Bow_035":[1,28],"Weapon_Bow_036":[1,29],"Weapon_Bow_038":[1,30],"Weapon_Bow_040":[1,31],"Weapon_Bow_071":[1,32],"Weapon_Bow_072":[1,33],"Weapon_Lsword_001":[1,34],"Weapon_Lsword_002":[1,35],"Weapon_Lsword_003":[1,36],"Weapon_Lsword_004":[1,37],"Weapon_Lsword_005":[1,38],"Weapon_Lsword_006":[1,39],"Weapon_Lsword_010":[1,40],"Weapon_Lsword_011":[1,41],"Weapon_Lsword_012":[1,42],"Weapon_Lsword_013":[1,43],"Weapon_Lsword_014":[1,44],"Weapon_Lsword_015":[1,45],"Weapon_Lsword_016":[1,46],"Weapon_Lsword_017":[1,47],"Weapon_Lsword_018":[1,48],"Weapon_Lsword_019":[1,49],"Weapon_Lsword_020":[1,50],"Weapon_Lsword_023":[1,51],"Weapon_Lsword_024":[1,52],"Weapon_Lsword_027":[1,53],"Weapon_Lsword_029":[1,54],"Weapon_Lsword_030":[1,55],"Weapon_Lsword_031":[1,56],"Weapon_Lsword_032":[1,57],"Weapon_Lsword_033":[1,58],"Weapon_Lsword_034":[1,59],"Weapon_Lsword_035":[1,60],"Weapon_Lsword_036":[1,61],"Weapon_Lsword_037":[1,62],"Weapon_Lsword_038":[1,63],"Weapon_Lsword_041":[1,64],"Weapon_Lsword_045":[1,65],"Weapon_Lsword_047":[1,66],"Weapon_Lsword_051":[1,67],"Weapon_Lsword_054":[1,68],"Weapon_Lsword_055":[1,69],"Weapon_Lsword_056":[1,70],"Weapon_Lsword_057":[1,71],"Weapon_Lsword_059":[1,72],"Weapon_Lsword_060":[1,73],"Weapon_Lsword_074":[1,74],"Weapon_Shield_001":[1,75],"Weapon_Shield_002":[1,76],"Weapon_Shield_003":[1,77],"Weapon_Shield_004":[1,78],"Weapon_Shield_005":[1,79],"Weapon_Shield_006":[1,80],"Weapon_Shield_007":[1,81],"Weapon_Shield_008":[1,82],"Weapon_Shield_009":[1,83],"Weapon_Shield_013":[1,84],"Weapon_Shield_014":[1,85],"Weapon_Shield_015":[1,86],"Weapon_Shield_016":[1,87],"Weapon_Shield_017":[1,88],"Weapon_Shield_018":[1,89],"Weapon_Shield_021":[1,90],"Weapon_Shield_022":[1,91],"Weapon_Shield_023":[1,92],"Weapon_Shield_025":[1,93],"Weapon_Shield_026":[1,94],"Weapon_Shield_030":[1,95],"Weapon_Shield_031":[1,96],"Weapon_Shield_032":[1,97],"Weapon_Shield_033":[1,98],"Weapon_Shield_034":[1,99],"Weapon_Shield_035":[1,100],"Weapon_Shield_036":[1,101],"Weapon_Shield_037":[1,102],"Weapon_Shield_038":[1,103],"Weapon_Shield_040":[1,104],"Weapon_Shield_041":[1,105],"Weapon_Shield_042":[1,106],"Weapon_Shield_057":[1,107],"Weapon_Spear_001":[1,160],"Weapon_Spear_002":[1,161],"Weapon_Spear_003":[1,162],"Weapon_Spear_004":[1,163],"Weapon_Spear_005":[1,164],"Weapon_Spear_006":[1,165],"Weapon_Spear_007":[1,166],"Weapon_Spear_008":[1,167],"Weapon_Spear_009":[1,168],"Weapon_Spear_010":[1,169],"Weapon_Spear_011":[1,170],"Weapon_Spear_012":[1,171],"Weapon_Spear_013":[1,172],"Weapon_Spear_014":[1,173],"Weapon_Spear_015":[1,174],"Weapon_Spear_016":[1,175],"Weapon_Spear_017":[1,176],"Weapon_Spear_018":[1,177],"Weapon_Spear_021":[1,178],"Weapon_Spear_022":[1,179],"Weapon_Spear_023":[1,180],"Weapon_Spear_024":[1,181],"Weapon_Spear_025":[1,182],"Weapon_Spear_027":[1,183],"Weapon_Spear_028":[1,184],"Weapon_Spear_029":[1,185],"Weapon_Spear_030":[1,186],"Weapon_Spear_031":[1,187],"Weapon_Spear_032":[1,188],"Weapon_Spear_033":[1,189],"Weapon_Spear_034":[1,190],"Weapon_Spear_035":[1,191],"Weapon_Spear_036":[1,192],"Weapon_Spear_037":[1,193],"Weapon_Spear_038":[1,194],"Weapon_Spear_047":[1,195],"Weapon_Spear_049":[1,196],"Weapon_Spear_050":[1,197],"Weapon_Sword_001":[1,108],"Weapon_Sword_002":[1,109],"Weapon_Sword_003":[1,110],"Weapon_Sword_004":[1,111],"Weapon_Sword_005":[1,112],"Weapon_Sword_006":[1,113],"Weapon_Sword_007":[1,114],"Weapon_Sword_008":[1,115],"Weapon_Sword_009":[1,116],"Weapon_Sword_013":[1,117],"Weapon_Sword_014":[1,118],"Weapon_Sword_015":[1,119],"Weapon_Sword_016":[1,120],"Weapon_Sword_017":[1,121],"Weapon_Sword_018":[1,122],"Weapon_Sword_019":[1,123],"Weapon_Sword_020":[1,124],"Weapon_Sword_021":[1,125],"Weapon_Sword_022":[1,126],"Weapon_Sword_023":[1,127],"Weapon_Sword_024":[1,128],"Weapon_Sword_025":[1,129],"Weapon_Sword_027":[1,130],"Weapon_Sword_029":[1,131],"Weapon_Sword_030":[1,132],"Weapon_Sword_031":[1,133],"Weapon_Sword_033":[1,134],"Weapon_Sword_034":[1,135],"Weapon_Sword_035":[1,136],"Weapon_Sword_040":[1,137],"Weapon_Sword_041":[1,138],"Weapon_Sword_043":[1,139],"Weapon_Sword_044":[1,140],"Weapon_Sword_047":[1,141],"Weapon_Sword_048":[1,142],"Weapon_Sword_049":[1,143],"Weapon_Sword_050":[1,144],"Weapon_Sword_051":[1,145],"Weapon_Sword_052":[1,146],"Weapon_Sword_053":[1,147],"Weapon_Sword_057":[1,148],"Weapon_Sword_058":[1,149],"Weapon_Sword_059":[1,150],"Weapon_Sword_060":[1,151],"Weapon_Sword_061":[1,152],"Weapon_Sword_062":[1,153],"Weapon_Sword_070":[1,154],"Weapon_Sword_070_Disabled":[1,155],"Weapon_Sword_072":[1,156],"Weapon_Sword_073":[1,157],"Weapon_Sword_502":[1,158],"Weapon_Sword_503":[1,159]}`)
\ No newline at end of file
diff --git a/packages/item-assets/src/sprites/ModifierMetadata.gen.ts b/packages/item-assets/src/sprites/ModifierMetadata.gen.ts
new file mode 100644
index 0000000..572627c
--- /dev/null
+++ b/packages/item-assets/src/sprites/ModifierMetadata.gen.ts
@@ -0,0 +1,7 @@
+import modifiers from "./modifiers.webp?url";
+export const ModifierChunkClasses = {
+ ".sprite-modifiers": { backgroundImage: `url(${modifiers})` },
+} as const;
+/** Modifier => [Chunk, Position]*/
+export type ModifierMetadata = Record;
+export const ModifierMetadata: ModifierMetadata = JSON.parse(`{"AddGuard":[0,0],"AddGuardPlus":[0,1],"AddLife":[0,2],"AddLifePlus":[0,3],"AddPower":[0,4],"AddPowerPlus":[0,5],"AddPowerPlus_Bow":[0,6],"AddPower_Bow":[0,7],"AllSpeed":[0,8],"AttackUp":[0,9],"ClimbSpeedUp":[0,10],"Critical":[0,11],"DefenseUp":[0,12],"ExGutsMaxUp":[0,13],"Fireproof":[0,14],"GutsRecover":[0,15],"LifeMaxUp":[0,16],"LifeRecover":[0,17],"LongThrow":[0,18],"Quietness":[0,19],"RapidFire":[0,20],"ReduceAncientEnemyDamge":[0,21],"ResistCold":[0,22],"ResistElectric":[0,23],"ResistFreeze":[0,24],"ResistHot":[0,25],"ResistLightning":[0,26],"SandMoveSpeedUp":[0,27],"SnowMovingSpeed":[0,28],"SpreadFire_3":[0,29],"SpreadFire_5":[0,30],"SpreadFire_X":[0,31],"SurfMaster":[0,32],"SurfMaster_White":[0,33],"SwimSpeedUp":[0,34],"Zoom":[0,35],"Zoom_White":[0,36]}`)
\ No newline at end of file
diff --git a/packages/item-assets/tsconfig.json b/packages/item-assets/tsconfig.json
new file mode 100644
index 0000000..1f7887e
--- /dev/null
+++ b/packages/item-assets/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "../../config/tsconfig-vite-app.json",
+ "include": ["src"],
+}
diff --git a/packages/item-system/.gitignore b/packages/item-system/.gitignore
new file mode 100644
index 0000000..07e6e47
--- /dev/null
+++ b/packages/item-system/.gitignore
@@ -0,0 +1 @@
+/node_modules
diff --git a/app/index.html b/packages/item-system/index.html
similarity index 57%
rename from app/index.html
rename to packages/item-system/index.html
index e4b78ea..ebdc13e 100644
--- a/app/index.html
+++ b/packages/item-system/index.html
@@ -2,12 +2,11 @@
-
- Vite + React + TS
+ Item Slots Test
-
+
diff --git a/packages/item-system/package.json b/packages/item-system/package.json
new file mode 100644
index 0000000..5f39276
--- /dev/null
+++ b/packages/item-system/package.json
@@ -0,0 +1,23 @@
+{
+ "name": "skybook-item-system",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc -b && vite build",
+ "lint": "eslint .",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@fluentui/react-components": "*",
+ "@fluentui/react-icons": "*",
+ "react": "*",
+ "react-dom": "*",
+ "skybook-item-assets": "*",
+ "skybook-localization": "*"
+ },
+ "exports": {
+ ".": "./src/index.ts"
+ }
+}
diff --git a/legacy/public/assets/font/Calamity-Regular.otf b/packages/item-system/src/Calamity-Regular.otf
similarity index 100%
rename from legacy/public/assets/font/Calamity-Regular.otf
rename to packages/item-system/src/Calamity-Regular.otf
diff --git a/packages/item-system/src/CalamitySans.css b/packages/item-system/src/CalamitySans.css
new file mode 100644
index 0000000..a5d8e18
--- /dev/null
+++ b/packages/item-system/src/CalamitySans.css
@@ -0,0 +1,5 @@
+@font-face {
+ font-family: CalamitySans;
+ src: url("./Calamity-Regular.otf") format("opentype");
+}
+
diff --git a/packages/item-system/src/ItemSlot.tsx b/packages/item-system/src/ItemSlot.tsx
new file mode 100644
index 0000000..60fe722
--- /dev/null
+++ b/packages/item-system/src/ItemSlot.tsx
@@ -0,0 +1,304 @@
+import "./CalamitySans.css";
+import { makeStyles, mergeClasses } from "@griffel/react";
+import { Text } from "@fluentui/react-components";
+
+import { ActorSprite, ActorSpriteProps, ModifierSprite } from "skybook-item-assets";
+
+import { type ItemSlotInfo } from "./data/ItemSlotInfo.ts";
+import { Link24Regular, Link32Regular } from "@fluentui/react-icons";
+import { CookEffect, PouchItemType, SpecialStatus } from "./data/enums.ts";
+import { getModifierInfo } from "./data/ModifierInfo.ts";
+import { getActorParam } from "./data/ActorData.ts";
+
+const useStyles = makeStyles({
+ container: {
+ position: "relative",
+ width: "72px",
+ height: "72px",
+ "& *": {
+ pointerEvents: "none",
+ }
+ },
+ broken: {
+ backgroundColor: "#660000",
+ },
+ // main item slot box
+ boxOutline: {
+ position: "absolute",
+ width: "64px",
+ height: "64px",
+ top: "4px",
+ left: "4px",
+ },
+ boxOutlineColor: {
+ backgroundColor: "#333333bb",
+ },
+ // the darker inside + lighter border
+ boxInside: {
+ position: "absolute",
+ boxSizing: "border-box",
+ width: "62px",
+ height: "62px",
+ top: "5px",
+ left: "5px",
+ },
+ boxInsideBorder: {
+ border: "1px solid #999999",
+ },
+ boxInsideHighlightBorder: {
+ border: "1px solid #ffee00",
+ },
+ boxInsideColor: {
+ backgroundColor: "#000000cc",
+ },
+ equipped: {
+ backgroundColor: "#0088ff",
+ boxShadow: "inset -2px -2px 5px 0px #ffffffaa, inset 2px 2px 5px 0px #ffffffaa"
+ },
+ layer: {
+ // dimension of the slot, including spaces outside of the box
+ boxSizing: "border-box",
+ width: "72px",
+ height: "72px",
+ position: "absolute",
+ top: 0,
+ left: 0,
+ },
+ // container for the image
+ image: {
+ padding: "4px",
+ },
+ imageTranslucent: {
+ opacity: 0.6,
+ },
+ // The "xCOUNT" text
+ itemCount: {
+ fontFamily: "CalamitySans",
+ fontSize: "10pt",
+ position: "absolute",
+ left: "10px",
+ top: "48px",
+ color: "#eeeeee",
+ },
+ itemCountShadow: {
+ // make it more readable over the image
+ textShadow: "1px 1px #000000",
+ },
+ overlayText: {
+ color: "#eeeeee",
+ backgroundColor: "#333b",
+ boxSizing: "border-box",
+ border: "1px solid #999999",
+ position: "absolute",
+ display: "flex",
+ minWidth: "20px",
+ height: "20px",
+ "& span": {
+ position: "relative",
+ display: "inline-block",
+ top: "1px",
+ flex: "1",
+ textAlign: "center",
+ }
+ },
+ durability: {
+ padding: "0px 2px",
+ left: "2px",
+ bottom: "2px",
+ },
+ holding: {
+ position: "absolute",
+ top: "8px",
+ left: "8px",
+ display: "flex",
+ gap: "1px",
+ },
+ holdingElement: {
+ backgroundColor: "#ffee00",
+ display: "block",
+ width: "8px",
+ height: "8px",
+ borderRadius: "4px",
+ border: "1px solid #333333",
+ },
+ entangle: {
+ color: "#b7f1ff",
+ display: "flex",
+ alignItems: "center",
+ justifyContent: "center",
+ filter: "drop-shadow(0 0 5px #3aa0ff)",
+ position: "absolute",
+ bottom: "0px",
+ right: "4px",
+ },
+ entangleAnimation: {
+ animationDuration: "1s",
+ animationIterationCount: "infinite",
+ animationName: {
+ "0%": {
+ opacity: 1,
+ },
+ "50%": {
+ opacity: 0,
+ },
+ }
+ },
+ modifierOverlay: {
+ top: "2px",
+ left: "2px",
+ },
+ modifier: {
+ position: "relative",
+ top: "-1px",
+ left: "-1px",
+ width: "18px",
+ },
+ modifierText: {
+ paddingRight: "2px",
+ color: "#64E793",
+ },
+ modifierTextBeginPad: {
+ paddingLeft: "2px",
+ }
+});
+
+export type ItemSlotProps = {
+ info: ItemSlotInfo;
+} & Pick;
+
+/** The Item slot display */
+export const ItemSlot: React.FC = ({ info, cheap, deactive, disableAnimation }) => {
+ const styles = useStyles();
+ const {
+ actorName,
+ modEffectId,
+ itemType,
+ value,
+ isEquipped,
+ isInBrokenSlot,
+ isInInventory,
+ holdingCount,
+ promptEntangled
+ } = info;
+
+ disableAnimation = disableAnimation || cheap;
+
+ const canStack = getActorParam(actorName, "canStack");
+
+ const isEquipment = itemType === PouchItemType.Sword || itemType === PouchItemType.Shield || itemType === PouchItemType.Bow;
+ const badlyDamaged = isEquipment && value < 300;
+
+ const modifier = getModifierInfo(info);
+ return (
+
+ {/* Background & box*/}
+
+
+
0 ? styles.boxInsideHighlightBorder : styles.boxInsideBorder,
+ isEquipped && styles.equipped
+ )} >
+
+
+ {holdingCount > 0 &&
+
+ {/* Using DOM instead of Unicode, in case user is missing font */}
+
+ {
+ Array.from({ length: holdingCount }).map((_, i) => (
+
+ ))
+ }
+
+
+ }
+ {
+ isEquipment &&
+
+
+ {formatDurability(value)}
+
+
+
+ }
+ {
+ // > 1 for displaying corrupted stacks
+ !isEquipment && (canStack || value > 1) &&
+
+ x{value}
+
+
+ }
+ {
+ promptEntangled &&<>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ }
+ {
+ (!!modifier.iconValue || modifier.status !== SpecialStatus.None) && (
+
+
+ {
+ modifier.status !== SpecialStatus.None && modifier.statusIcon && (
+
+
+
+ )
+ }
+ {
+ modifier.iconValue && (
+ {modifier.iconValue}
+ )
+ }
+
+
+ )
+ }
+
+ );
+};
+
+const formatDurability = (value: number): string => {
+ const durability = value / 100;
+ if (Number.isInteger(durability)) {
+ return durability.toString();
+ }
+ return durability.toFixed(2);
+}
diff --git a/packages/item-system/src/ItemTooltip.tsx b/packages/item-system/src/ItemTooltip.tsx
new file mode 100644
index 0000000..2b883ff
--- /dev/null
+++ b/packages/item-system/src/ItemTooltip.tsx
@@ -0,0 +1,29 @@
+import React, {
+ useEffect,
+ useState,
+ PropsWithChildren,
+} from "react";
+
+import type { ItemTooltipContentProps } from "./ItemTooltipContent.tsx";
+import { useSetItemTooltip } from "./ItemTooltipProvider.tsx";
+
+/** Wrapper to show tooltip for an ItemSlot */
+export const ItemTooltip: React.FC> = ({
+ info,
+ children,
+}) => {
+ const setTooltip = useSetItemTooltip();
+
+ return (
+ {
+ setTooltip(e.clientX, e.clientY, info);
+ }}
+ onMouseLeave={() => {
+ setTooltip(-1, -1, undefined);
+ }}
+ >
+ {children}
+
+ );
+};
diff --git a/packages/item-system/src/ItemTooltipContent.tsx b/packages/item-system/src/ItemTooltipContent.tsx
new file mode 100644
index 0000000..20f9baa
--- /dev/null
+++ b/packages/item-system/src/ItemTooltipContent.tsx
@@ -0,0 +1,222 @@
+import { makeStyles, mergeClasses } from "@griffel/react";
+import { Text } from "@fluentui/react-components";
+
+import { ModifierSprite, useStaticAssetStyles } from "skybook-item-assets";
+import { useGeneratedTranslation, useUITranslation } from "skybook-localization";
+import type { ItemSlotInfo } from "./data/ItemSlotInfo.ts";
+import { CookEffect, effectToStatus, ItemUse, PouchItemType, SpecialStatus } from "./data/enums.ts";
+import { getActorParam } from "./data/ActorData.ts";
+import { Star16Filled, Star20Filled } from "@fluentui/react-icons";
+import { getModifierInfo } from "./data/ModifierInfo.ts";
+
+export type ItemTooltipContentProps = {
+ info: ItemSlotInfo;
+}
+
+const useStyles = makeStyles({
+ text: {
+ color: "white",
+ }
+});
+
+export const ItemTooltipContent: React.FC =
+({ info }) => {
+ const staticAssets = useStaticAssetStyles();
+ const styles = useStyles();
+
+ const t = useGeneratedTranslation();
+ const ui = useUITranslation();
+ const { actorName, modEffectId, value, isEquipped, isInInventory
+ ,holdingCount, itemType,itemUse, modEffectValue, modEffectLevel,
+ modEffectDuration ,modSellPrice
+ } = info;
+
+ let nameTranslationArgs;
+ const cookEffectName = CookEffect[modEffectId];
+ if (cookEffectName && modEffectId > 0) {
+ nameTranslationArgs = {
+ effect: t(`cook.${cookEffectName}.name`),
+ effect_feminine: t(`cook.${cookEffectName}.name_feminine`),
+ effect_masculine: t(`cook.${cookEffectName}.name_masculine`),
+ effect_neuter: t(`cook.${cookEffectName}.name_neuter`),
+ effect_plural: t(`cook.${cookEffectName}.name_plural`),
+ };
+ } else {
+ nameTranslationArgs = {
+ effect: "",
+ effect_femenine: "",
+ effect_masculine: "",
+ effect_neuter: "",
+ effect_plural: "",
+ };
+ }
+
+ const starNum = getActorParam(actorName, "armorStarNum");
+ const isEquipment = itemType === PouchItemType.Sword || itemType === PouchItemType.Bow ||itemType === PouchItemType.Shield;
+ const isFood = itemType === PouchItemType.Food;
+ const modifier = getModifierInfo(info);
+
+ const foodStatus = effectToStatus(modEffectId);
+
+ return (
+
+
+
+ {t(`actor.${actorName}.name`, nameTranslationArgs)}
+ {starNum > 1 && Array.from({length: starNum - 1}).map((_, i) => (
+
+ ))}
+
+
+ {actorName}
+
+
+ {ui("tooltip.value", { value })}
+
+ {
+ isEquipped && (
+
+ {ui("tooltip.equipped")}
+
+ )
+ }
+ {
+ !isInInventory && (
+
+ {ui("tooltip.translucent")}
+
+ )
+ }
+ {
+ holdingCount > 0 && (
+
+ {ui("tooltip.holding", { holding: holdingCount })}
+
+ )
+ }
+ {
+ isEquipment && modifier.details.map(({status,statusIcon, modifierValue}, i) => (
+
+
+
+ {t(`status.${SpecialStatus[status]}`, { modifier_value: modifierValue })}
+
+
+ ))
+ }
+ {
+ // Hearts
+ isFood && (
+
+
+ {
+ modEffectId === CookEffect.LifeMaxUp ? (
+ <>
+
+ +{modEffectValue}{" "}
+ {
+ t(`status.${SpecialStatus[foodStatus]}`)
+ }
+ >
+ ) : (
+ <>
+
+ +{modEffectValue / 4}
+ >
+ )
+ }
+
+
+ )
+ }
+ {
+ // Stamina/Endura
+ isFood && (modEffectId === CookEffect.GutsRecover || modEffectId===CookEffect.ExGutsMaxUp) && (
+
+
+
+ +{modEffectLevel}{" "}
+ {
+ t(`status.${SpecialStatus[foodStatus]}`)
+ }
+
+
+ )
+ }
+ {
+ // Timed effects
+ isFood && (
+ modEffectId !== CookEffect.None
+ && modEffectId !== CookEffect.LifeMaxUp
+ && modEffectId !== CookEffect.LifeRecover
+ && modEffectId !== CookEffect.GutsRecover
+ && modEffectId !== CookEffect.ExGutsMaxUp) && (
+
+
+ {
+ (modEffectLevel < 4 && Number.isInteger(modEffectLevel)) ? (
+ (Array.from({length: modEffectLevel})).map((_, i) => (
+
+ ))
+ ) : (
+ <>
+
+ Lv. {modEffectLevel}
+ >
+ )
+ }
+ {
+ t(`status.${SpecialStatus[foodStatus]}`)
+ }
+ {
+ modEffectDuration >= 3600 ?
+ new Date(modEffectDuration * 1000).toLocaleTimeString("en-US", {
+ timeZone: "UTC",
+ hour12: false,
+ hour: "2-digit",
+ minute: "2-digit",
+ second: "2-digit",
+ })
+ :
+ new Date(modEffectDuration * 1000).toLocaleTimeString("en-US", {
+ timeZone: "UTC",
+ hour12: false,
+ minute: "2-digit",
+ second: "2-digit",
+ })
+ }
+
+
+ )
+ }
+ {
+ isFood && (
+
+ {ui("tooltip.cook.price", { price: modSellPrice })}
+
+ )
+ }
+
+ {
+ itemType in PouchItemType ? PouchItemType[itemType] : "???"
+ }
+ {`[${itemType}]/`}
+ {
+ itemUse in ItemUse ? ItemUse[itemUse] : "???"
+ }
+ {`[${itemUse}]`}
+
+
+ {getActorParam(actorName, "profile")}
+
+
+
+
+
+ )
+};
diff --git a/packages/item-system/src/ItemTooltipProvider.tsx b/packages/item-system/src/ItemTooltipProvider.tsx
new file mode 100644
index 0000000..ec71c71
--- /dev/null
+++ b/packages/item-system/src/ItemTooltipProvider.tsx
@@ -0,0 +1,91 @@
+import { type PropsWithChildren, createContext, useRef, useState, useCallback, useEffect, useContext, useLayoutEffect, Suspense } from "react";
+import { makeStyles, mergeClasses } from "@griffel/react";
+
+import { useStaticAssetStyles } from "skybook-item-assets";
+
+import type { ItemSlotInfo } from "./data/ItemSlotInfo.ts";
+import { ItemTooltipContent } from "./ItemTooltipContent.tsx";
+
+export type SetItemTooltipFn = (x: number, y: number, info: ItemSlotInfo | undefined) => void;
+
+const useStyles = makeStyles({
+ container: {
+ position: "absolute",
+ }
+});
+
+const ItemTooltipContext = createContext(() => {
+ /* empty */
+});
+
+/** Provider for the ItemTooltipContext */
+export const ItemTooltipProvider: React.FC = ({ children }) => {
+ const staticAssets = useStaticAssetStyles();
+ const styles = useStyles();
+
+ const toolTipDivRef = useRef(null);
+ const [tooltipInfo, setTooltipInfo] = useState();
+ const setTooltip: SetItemTooltipFn = useCallback(
+ (x , y, info) => {
+ if (!toolTipDivRef.current) {
+ return;
+ }
+ const tooltipDiv = toolTipDivRef.current;
+ if (info === undefined) {
+ tooltipDiv.style.display = "none";
+ return;
+ }
+ tooltipDiv.style.display = "unset";
+ // This might initially be wrong the first time
+ // the info is changed. However, most of the time, it will be
+ // called again with the correct x and y when the mouse moves.
+ positionTooltipDiv(tooltipDiv, x, y);
+ setTooltipInfo(info);
+ },
+ [tooltipInfo],
+ );
+
+ return (
+
+ {children}
+
+ {tooltipInfo && }
+
+
+ );
+};
+
+const positionTooltipDiv = (tooltipDiv: HTMLDivElement, x: number, y: number) => {
+ x += 10;
+ y += 10;
+ const oldX = x;
+ const oldY = y;
+ tooltipDiv.style.left = `${x}px`;
+ tooltipDiv.style.top = `${y}px`;
+ const rect = tooltipDiv.getBoundingClientRect();
+ if (rect.bottom > window.innerHeight) {
+ y -= rect.height + 20;
+ }
+ if (rect.right > window.innerWidth) {
+ x -= rect.width + 20;
+ }
+ if (x < 0) {
+ x = 0;
+ }
+ if (y < 0) {
+ y = 0;
+ }
+ if (x !== oldX) {
+ tooltipDiv.style.left = `${x}px`;
+ }
+ if (y !== oldY) {
+ tooltipDiv.style.top = `${y}px`;
+ }
+}
+
+export const useSetItemTooltip = () => {
+ return useContext(ItemTooltipContext);
+}
diff --git a/packages/item-system/src/data/ActorData.gen.ts b/packages/item-system/src/data/ActorData.gen.ts
new file mode 100644
index 0000000..150f5af
--- /dev/null
+++ b/packages/item-system/src/data/ActorData.gen.ts
@@ -0,0 +1,8 @@
+
+/**
+ * This file is generated by generate-param.py
+ * DO NOT EDIT MANUALLY
+ */
+import type { ActorData } from "./ActorData.ts";
+
+export const ActorDataMap: Record> = JSON.parse(`{"AncientArrow":{"attackPower":50,"canStack":true,"cannotSell":true,"itemBuyingPrice":100,"itemCreatingPrice":90,"profile":"Bullet"},"Animal_Fish_A":{"canStack":true,"generalLife":1,"itemBuyingPrice":24,"itemSellingPrice":6,"profile":"CapturedActor"},"Animal_Fish_B":{"canStack":true,"generalLife":1,"itemBuyingPrice":72,"itemSellingPrice":18,"profile":"CapturedActor"},"Animal_Fish_C":{"canStack":true,"generalLife":1,"itemBuyingPrice":24,"itemSellingPrice":6,"profile":"CapturedActor"},"Animal_Fish_D":{"canStack":true,"generalLife":1,"itemBuyingPrice":24,"itemSellingPrice":6,"profile":"CapturedActor"},"Animal_Fish_E":{"canStack":true,"generalLife":1,"itemBuyingPrice":40,"itemSellingPrice":10,"profile":"CapturedActor"},"Animal_Fish_F":{"canStack":true,"generalLife":1,"itemBuyingPrice":40,"itemSellingPrice":10,"profile":"CapturedActor"},"Animal_Fish_G":{"canStack":true,"generalLife":1,"itemBuyingPrice":40,"itemSellingPrice":10,"profile":"CapturedActor"},"Animal_Fish_H":{"canStack":true,"generalLife":1,"itemBuyingPrice":40,"itemSellingPrice":10,"profile":"CapturedActor"},"Animal_Fish_I":{"canStack":true,"generalLife":1,"itemBuyingPrice":40,"itemSellingPrice":10,"profile":"CapturedActor"},"Animal_Fish_J":{"canStack":true,"generalLife":1,"itemBuyingPrice":24,"itemSellingPrice":6,"profile":"CapturedActor"},"Animal_Fish_K":{"canStack":true,"generalLife":1,"itemBuyingPrice":60,"itemSellingPrice":15,"profile":"CapturedActor"},"Animal_Fish_L":{"canStack":true,"generalLife":1,"itemBuyingPrice":72,"itemSellingPrice":18,"profile":"CapturedActor"},"Animal_Fish_M":{"canStack":true,"generalLife":1,"itemBuyingPrice":24,"itemSellingPrice":6,"profile":"CapturedActor"},"Animal_Fish_X":{"canStack":true,"generalLife":1,"itemBuyingPrice":40,"itemSellingPrice":10,"profile":"CapturedActor"},"Animal_Fish_Z":{"canStack":true,"generalLife":1,"itemBuyingPrice":80,"itemSellingPrice":20,"profile":"CapturedActor"},"Animal_Insect_A":{"canStack":true,"generalLife":1,"itemBuyingPrice":10,"itemSellingPrice":2,"itemStainColor":7,"profile":"CapturedActor"},"Animal_Insect_AA":{"canStack":true,"generalLife":1,"itemBuyingPrice":150,"itemSellingPrice":30,"itemStainColor":3,"profile":"CapturedActor"},"Animal_Insect_AB":{"canStack":true,"generalLife":1,"itemBuyingPrice":10,"itemSellingPrice":2,"itemStainColor":15,"profile":"CapturedActor"},"Animal_Insect_B":{"canStack":true,"generalLife":1,"itemBuyingPrice":100,"itemSellingPrice":20,"itemStainColor":12,"profile":"CapturedActor"},"Animal_Insect_C":{"canStack":true,"generalLife":1,"itemBuyingPrice":10,"itemSellingPrice":2,"itemStainColor":1,"profile":"CapturedActor"},"Animal_Insect_E":{"canStack":true,"generalLife":1,"itemBuyingPrice":10,"itemSellingPrice":2,"itemStainColor":6,"profile":"CapturedActor"},"Animal_Insect_F":{"canStack":true,"generalLife":1,"itemBuyingPrice":10,"itemSellingPrice":2,"profile":"CapturedActor"},"Animal_Insect_G":{"canStack":true,"generalLife":1,"itemBuyingPrice":20,"itemSellingPrice":4,"itemStainColor":9,"profile":"CapturedActor"},"Animal_Insect_H":{"canStack":true,"generalLife":1,"itemBuyingPrice":10,"itemSellingPrice":2,"itemStainColor":7,"profile":"CapturedActor"},"Animal_Insect_I":{"canStack":true,"generalLife":1,"itemBuyingPrice":10,"itemSellingPrice":2,"itemStainColor":3,"profile":"CapturedActor"},"Animal_Insect_K":{"canStack":true,"generalLife":1,"itemBuyingPrice":32,"itemSellingPrice":8,"profile":"CapturedActor"},"Animal_Insect_M":{"canStack":true,"generalLife":1,"itemBuyingPrice":100,"itemSellingPrice":20,"itemStainColor":1,"profile":"CapturedActor"},"Animal_Insect_N":{"canStack":true,"generalLife":1,"itemBuyingPrice":10,"itemSellingPrice":2,"itemStainColor":1,"profile":"CapturedActor"},"Animal_Insect_O":{"canStack":true,"generalLife":1,"itemBuyingPrice":32,"itemSellingPrice":8,"profile":"CapturedActor"},"Animal_Insect_P":{"canStack":true,"generalLife":1,"itemBuyingPrice":20,"itemSellingPrice":4,"itemStainColor":7,"profile":"CapturedActor"},"Animal_Insect_Q":{"canStack":true,"generalLife":1,"itemBuyingPrice":10,"itemSellingPrice":2,"itemStainColor":2,"profile":"CapturedActor"},"Animal_Insect_R":{"canStack":true,"generalLife":1,"itemBuyingPrice":10,"itemSellingPrice":2,"itemStainColor":3,"profile":"CapturedActor"},"Animal_Insect_S":{"canStack":true,"generalLife":1,"itemBuyingPrice":10,"itemSellingPrice":2,"itemStainColor":14,"profile":"CapturedActor"},"Animal_Insect_T":{"canStack":true,"generalLife":1,"itemBuyingPrice":10,"itemSellingPrice":2,"itemStainColor":2,"profile":"CapturedActor"},"Animal_Insect_X":{"canStack":true,"generalLife":1,"itemBuyingPrice":25,"itemSellingPrice":5,"itemStainColor":15,"profile":"CapturedActor"},"Animal_Insect_Z":{"canStack":true,"generalLife":1,"itemBuyingPrice":40,"itemSellingPrice":10,"profile":"CapturedActor"},"Armor_001_Head":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":15,"profile":"ArmorHead"},"Armor_001_Head_B":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":15,"profile":"ArmorHead"},"Armor_001_Lower":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":90,"itemCreatingPrice":0,"itemSellingPrice":25,"profile":"ArmorLower"},"Armor_001_Upper":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":120,"itemCreatingPrice":0,"itemSellingPrice":30,"profile":"ArmorUpper"},"Armor_002_Head":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":75,"itemCreatingPrice":0,"itemSellingPrice":20,"profile":"ArmorHead"},"Armor_002_Head_B":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":75,"itemCreatingPrice":0,"itemSellingPrice":20,"profile":"ArmorHead"},"Armor_002_Lower":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":105,"itemCreatingPrice":0,"itemSellingPrice":30,"profile":"ArmorLower"},"Armor_002_Upper":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":135,"itemCreatingPrice":0,"itemSellingPrice":35,"profile":"ArmorUpper"},"Armor_003_Head":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":139,"itemCreatingPrice":0,"itemSellingPrice":35,"profile":"ArmorHead"},"Armor_003_Head_B":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":139,"itemCreatingPrice":0,"itemSellingPrice":35,"profile":"ArmorHead"},"Armor_003_Lower":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":169,"itemCreatingPrice":0,"itemSellingPrice":40,"profile":"ArmorLower"},"Armor_003_Upper":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":199,"itemCreatingPrice":0,"itemSellingPrice":50,"profile":"ArmorUpper"},"Armor_004_Head":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":319,"itemCreatingPrice":0,"itemSellingPrice":80,"profile":"ArmorHead"},"Armor_004_Head_B":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":319,"itemCreatingPrice":0,"itemSellingPrice":80,"profile":"ArmorHead"},"Armor_004_Lower":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":349,"itemCreatingPrice":0,"itemSellingPrice":85,"profile":"ArmorLower"},"Armor_004_Upper":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":379,"itemCreatingPrice":0,"itemSellingPrice":95,"profile":"ArmorUpper"},"Armor_005_Head":{"armorDefenceAddLevel":4,"armorStarNum":1,"cannotSell":true,"itemBuyingPrice":100,"itemCreatingPrice":0,"itemSellingPrice":25,"profile":"ArmorHead"},"Armor_005_Lower":{"armorDefenceAddLevel":4,"armorStarNum":1,"cannotSell":true,"itemBuyingPrice":100,"itemCreatingPrice":0,"itemSellingPrice":25,"profile":"ArmorLower"},"Armor_005_Upper":{"armorDefenceAddLevel":4,"armorStarNum":1,"cannotSell":true,"itemBuyingPrice":100,"itemCreatingPrice":0,"itemSellingPrice":25,"profile":"ArmorUpper"},"Armor_006_Head":{"armorDefenceAddLevel":3,"armorEffectEffectType":"SwimSpeed","armorStarNum":1,"cannotSell":true,"itemBuyingPrice":100,"itemCreatingPrice":0,"itemSellingPrice":25,"profile":"ArmorHead","specialStatus":29},"Armor_006_Lower":{"armorDefenceAddLevel":3,"armorEffectEffectType":"SwimSpeed","armorStarNum":1,"cannotSell":true,"itemBuyingPrice":100,"itemCreatingPrice":0,"itemSellingPrice":25,"profile":"ArmorLower","specialStatus":29},"Armor_006_Upper":{"armorDefenceAddLevel":3,"armorEffectEffectType":"SwimSpeed","armorStarNum":1,"cannotSell":true,"itemBuyingPrice":100,"itemCreatingPrice":0,"itemSellingPrice":25,"profile":"ArmorUpper","specialStatus":29},"Armor_007_Head":{"armorDefenceAddLevel":5,"armorEffectEffectType":"SwimSpeed","armorStarNum":2,"cannotSell":true,"itemBuyingPrice":130,"itemCreatingPrice":0,"itemSellingPrice":35,"profile":"ArmorHead","specialStatus":29},"Armor_007_Lower":{"armorDefenceAddLevel":5,"armorEffectEffectType":"SwimSpeed","armorStarNum":2,"cannotSell":true,"itemBuyingPrice":130,"itemCreatingPrice":0,"itemSellingPrice":35,"profile":"ArmorLower","specialStatus":29},"Armor_007_Upper":{"armorDefenceAddLevel":5,"armorEffectEffectType":"SwimSpeed","armorStarNum":2,"cannotSell":true,"itemBuyingPrice":130,"itemCreatingPrice":0,"itemSellingPrice":35,"profile":"ArmorUpper","specialStatus":29},"Armor_008_Head":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ResistHot","armorStarNum":1,"itemBuyingPrice":450,"itemCreatingPrice":0,"itemSellingPrice":115,"profile":"ArmorHead","specialStatus":23},"Armor_008_Lower":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ResistHot","armorStarNum":1,"itemBuyingPrice":650,"itemCreatingPrice":0,"itemSellingPrice":165,"profile":"ArmorLower","specialStatus":23},"Armor_008_Upper":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ResistHot","armorStarNum":1,"itemBuyingPrice":1300,"itemCreatingPrice":0,"itemSellingPrice":325,"profile":"ArmorUpper","specialStatus":23},"Armor_009_Head":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ResistCold","armorStarNum":1,"itemBuyingPrice":1000,"itemCreatingPrice":0,"itemSellingPrice":250,"profile":"ArmorHead","specialStatus":20},"Armor_009_Lower":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ResistCold","armorStarNum":1,"itemBuyingPrice":550,"itemCreatingPrice":0,"itemSellingPrice":140,"profile":"ArmorLower","specialStatus":20},"Armor_009_Upper":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ResistCold","armorStarNum":1,"itemBuyingPrice":600,"itemCreatingPrice":0,"itemSellingPrice":150,"profile":"ArmorUpper","specialStatus":20},"Armor_011_Head":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ResistBurn","armorStarNum":1,"itemBuyingPrice":2000,"itemCreatingPrice":0,"itemSellingPrice":500,"profile":"ArmorHead","specialStatus":13},"Armor_011_Lower":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ResistBurn","armorStarNum":1,"itemBuyingPrice":700,"itemCreatingPrice":0,"itemSellingPrice":175,"profile":"ArmorLower","specialStatus":13},"Armor_011_Upper":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ResistBurn","armorStarNum":1,"itemBuyingPrice":600,"itemCreatingPrice":0,"itemSellingPrice":150,"profile":"ArmorUpper","specialStatus":13},"Armor_012_Head":{"armorDefenceAddLevel":2,"armorEffectEffectType":"Quietness","armorStarNum":1,"itemBuyingPrice":500,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorHead","specialStatus":17},"Armor_012_Head_B":{"armorDefenceAddLevel":2,"armorEffectEffectType":"Quietness","armorStarNum":1,"itemBuyingPrice":500,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorHead","specialStatus":17},"Armor_012_Lower":{"armorDefenceAddLevel":2,"armorEffectEffectType":"Quietness","armorStarNum":1,"itemBuyingPrice":600,"itemCreatingPrice":0,"itemSellingPrice":150,"profile":"ArmorLower","specialStatus":17},"Armor_012_Upper":{"armorDefenceAddLevel":2,"armorEffectEffectType":"Quietness","armorStarNum":1,"itemBuyingPrice":700,"itemCreatingPrice":0,"itemSellingPrice":175,"profile":"ArmorUpper","specialStatus":17},"Armor_014_Head":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ClimbSpeed","armorStarNum":1,"itemBuyingPrice":4000,"itemCreatingPrice":0,"itemSellingPrice":600,"profile":"ArmorHead","specialStatus":9},"Armor_014_Lower":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ClimbSpeed","armorStarNum":1,"itemBuyingPrice":4000,"itemCreatingPrice":0,"itemSellingPrice":600,"profile":"ArmorLower","specialStatus":9},"Armor_014_Upper":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ClimbSpeed","armorStarNum":1,"itemBuyingPrice":4000,"itemCreatingPrice":0,"itemSellingPrice":600,"profile":"ArmorUpper","specialStatus":9},"Armor_015_Head":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":1069,"itemCreatingPrice":0,"itemSellingPrice":265,"profile":"ArmorHead"},"Armor_015_Head_B":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":1069,"itemCreatingPrice":0,"itemSellingPrice":265,"profile":"ArmorHead"},"Armor_015_Lower":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":1099,"itemCreatingPrice":0,"itemSellingPrice":275,"profile":"ArmorLower"},"Armor_015_Upper":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":1129,"itemCreatingPrice":0,"itemSellingPrice":280,"profile":"ArmorUpper"},"Armor_017_Head":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":800,"itemCreatingPrice":800,"itemSellingPrice":200,"profile":"ArmorHead"},"Armor_017_Lower":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":800,"itemCreatingPrice":800,"itemSellingPrice":200,"profile":"ArmorLower"},"Armor_017_Upper":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":800,"itemCreatingPrice":800,"itemSellingPrice":200,"profile":"ArmorUpper"},"Armor_020_Head":{"armorDefenceAddLevel":4,"armorStarNum":1,"itemBuyingPrice":180,"itemCreatingPrice":0,"itemSellingPrice":45,"profile":"ArmorHead"},"Armor_020_Lower":{"armorDefenceAddLevel":4,"armorStarNum":1,"itemBuyingPrice":200,"itemCreatingPrice":0,"itemSellingPrice":50,"profile":"ArmorLower"},"Armor_020_Upper":{"armorDefenceAddLevel":4,"armorStarNum":1,"itemBuyingPrice":250,"itemCreatingPrice":0,"itemSellingPrice":65,"profile":"ArmorUpper"},"Armor_021_Head":{"armorDefenceAddLevel":4,"armorEffectEffectType":"ResistAncient","armorStarNum":1,"itemBuyingPrice":500,"itemCreatingPrice":2000,"itemSellingPrice":125,"profile":"ArmorHead","specialStatus":19},"Armor_021_Lower":{"armorDefenceAddLevel":4,"armorEffectEffectType":"ResistAncient","armorStarNum":1,"itemBuyingPrice":500,"itemCreatingPrice":2000,"itemSellingPrice":125,"profile":"ArmorLower","specialStatus":19},"Armor_021_Upper":{"armorDefenceAddLevel":4,"armorEffectEffectType":"ResistAncient","armorStarNum":1,"itemBuyingPrice":500,"itemCreatingPrice":2000,"itemSellingPrice":125,"profile":"ArmorUpper","specialStatus":19},"Armor_022_Head":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":40,"itemCreatingPrice":0,"itemSellingPrice":9,"profile":"ArmorHead"},"Armor_022_Head_B":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":40,"itemCreatingPrice":0,"itemSellingPrice":9,"profile":"ArmorHead"},"Armor_024_Head":{"armorDefenceAddLevel":4,"armorEffectEffectType":"ResistAncient","armorStarNum":1,"itemBuyingPrice":800,"itemCreatingPrice":1500,"itemSellingPrice":375,"profile":"ArmorHead","specialStatus":19},"Armor_025_Head":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ResistCold","armorStarNum":1,"itemBuyingPrice":500,"itemCreatingPrice":500,"itemSellingPrice":125,"profile":"ArmorHead","specialStatus":20},"Armor_026_Head":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ResistHot","armorStarNum":1,"itemBuyingPrice":600,"itemCreatingPrice":800,"itemSellingPrice":150,"profile":"ArmorHead","specialStatus":23},"Armor_027_Head":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ResistElectric","armorStarNum":1,"itemBuyingPrice":400,"itemCreatingPrice":500,"itemSellingPrice":100,"profile":"ArmorHead","specialStatus":21},"Armor_028_Head":{"armorDefenceAddLevel":3,"armorEffectEffectType":"SwimSpeed","armorStarNum":1,"itemBuyingPrice":150,"itemCreatingPrice":200,"itemSellingPrice":40,"profile":"ArmorHead","specialStatus":29},"Armor_029_Head":{"armorDefenceAddLevel":4,"armorStarNum":1,"itemBuyingPrice":90,"itemCreatingPrice":100,"itemSellingPrice":25,"profile":"ArmorHead"},"Armor_035_Head":{"armorDefenceAddLevel":7,"armorStarNum":2,"cannotSell":true,"itemBuyingPrice":420,"itemCreatingPrice":0,"itemSellingPrice":105,"profile":"ArmorHead"},"Armor_035_Lower":{"armorDefenceAddLevel":7,"armorStarNum":2,"cannotSell":true,"itemBuyingPrice":420,"itemCreatingPrice":0,"itemSellingPrice":105,"profile":"ArmorLower"},"Armor_035_Upper":{"armorDefenceAddLevel":7,"armorStarNum":2,"cannotSell":true,"itemBuyingPrice":420,"itemCreatingPrice":0,"itemSellingPrice":105,"profile":"ArmorUpper"},"Armor_036_Head":{"armorDefenceAddLevel":5,"armorEffectEffectType":"ResistCold","armorStarNum":2,"itemBuyingPrice":1015,"itemCreatingPrice":0,"itemSellingPrice":255,"profile":"ArmorHead","specialStatus":20},"Armor_036_Lower":{"armorDefenceAddLevel":5,"armorEffectEffectType":"ResistCold","armorStarNum":2,"itemBuyingPrice":565,"itemCreatingPrice":0,"itemSellingPrice":145,"profile":"ArmorLower","specialStatus":20},"Armor_036_Upper":{"armorDefenceAddLevel":5,"armorEffectEffectType":"ResistCold","armorStarNum":2,"itemBuyingPrice":615,"itemCreatingPrice":0,"itemSellingPrice":155,"profile":"ArmorUpper","specialStatus":20},"Armor_037_Head":{"armorDefenceAddLevel":5,"armorEffectEffectType":"ResistBurn","armorStarNum":2,"itemBuyingPrice":2015,"itemCreatingPrice":0,"itemSellingPrice":505,"profile":"ArmorHead","specialStatus":13},"Armor_037_Lower":{"armorDefenceAddLevel":5,"armorEffectEffectType":"ResistBurn","armorStarNum":2,"itemBuyingPrice":715,"itemCreatingPrice":0,"itemSellingPrice":180,"profile":"ArmorLower","specialStatus":13},"Armor_037_Upper":{"armorDefenceAddLevel":5,"armorEffectEffectType":"ResistBurn","armorStarNum":2,"itemBuyingPrice":615,"itemCreatingPrice":0,"itemSellingPrice":155,"profile":"ArmorUpper","specialStatus":13},"Armor_039_Head":{"armorDefenceAddLevel":12,"armorStarNum":3,"cannotSell":true,"itemBuyingPrice":880,"itemCreatingPrice":0,"itemSellingPrice":220,"profile":"ArmorHead"},"Armor_039_Lower":{"armorDefenceAddLevel":12,"armorStarNum":3,"cannotSell":true,"itemBuyingPrice":880,"itemCreatingPrice":0,"itemSellingPrice":220,"profile":"ArmorLower"},"Armor_039_Upper":{"armorDefenceAddLevel":12,"armorStarNum":3,"cannotSell":true,"itemBuyingPrice":880,"itemCreatingPrice":0,"itemSellingPrice":220,"profile":"ArmorUpper"},"Armor_040_Head":{"armorDefenceAddLevel":5,"armorEffectEffectType":"ResistHot","armorStarNum":2,"itemBuyingPrice":465,"itemCreatingPrice":0,"itemSellingPrice":120,"profile":"ArmorHead","specialStatus":23},"Armor_040_Lower":{"armorDefenceAddLevel":5,"armorEffectEffectType":"ResistHot","armorStarNum":2,"itemBuyingPrice":665,"itemCreatingPrice":0,"itemSellingPrice":170,"profile":"ArmorLower","specialStatus":23},"Armor_040_Upper":{"armorDefenceAddLevel":5,"armorEffectEffectType":"ResistHot","armorStarNum":2,"itemBuyingPrice":1315,"itemCreatingPrice":0,"itemSellingPrice":330,"profile":"ArmorUpper","specialStatus":23},"Armor_042_Head":{"armorDefenceAddLevel":4,"armorEffectEffectType":"Quietness","armorStarNum":2,"itemBuyingPrice":512,"itemCreatingPrice":0,"itemSellingPrice":130,"profile":"ArmorHead","specialStatus":17},"Armor_042_Head_B":{"armorDefenceAddLevel":4,"armorEffectEffectType":"Quietness","armorStarNum":2,"itemBuyingPrice":512,"itemCreatingPrice":0,"itemSellingPrice":130,"profile":"ArmorHead","specialStatus":17},"Armor_042_Lower":{"armorDefenceAddLevel":4,"armorEffectEffectType":"Quietness","armorStarNum":2,"itemBuyingPrice":612,"itemCreatingPrice":0,"itemSellingPrice":155,"profile":"ArmorLower","specialStatus":17},"Armor_042_Upper":{"armorDefenceAddLevel":4,"armorEffectEffectType":"Quietness","armorStarNum":2,"itemBuyingPrice":712,"itemCreatingPrice":0,"itemSellingPrice":180,"profile":"ArmorUpper","specialStatus":17},"Armor_043_Lower":{"armorDefenceAddLevel":1,"armorStarNum":1,"itemBuyingPrice":50,"itemCreatingPrice":0,"itemSellingPrice":15,"profile":"ArmorLower"},"Armor_043_Upper":{"armorDefenceAddLevel":1,"armorStarNum":1,"itemBuyingPrice":50,"itemCreatingPrice":0,"itemSellingPrice":15,"profile":"ArmorUpper"},"Armor_044_Upper":{"armorDefenceAddLevel":1,"armorEffectEffectType":"ResistCold","armorStarNum":1,"itemBuyingPrice":80,"itemCreatingPrice":0,"itemSellingPrice":20,"profile":"ArmorUpper","specialStatus":20},"Armor_045_Head":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":80,"itemCreatingPrice":0,"itemSellingPrice":19,"profile":"ArmorHead"},"Armor_046_Head":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ResistElectric","armorStarNum":1,"itemBuyingPrice":4000,"itemCreatingPrice":0,"itemSellingPrice":600,"profile":"ArmorHead","specialStatus":21},"Armor_046_Lower":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ResistElectric","armorStarNum":1,"itemBuyingPrice":4000,"itemCreatingPrice":0,"itemSellingPrice":600,"profile":"ArmorLower","specialStatus":21},"Armor_046_Upper":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ResistElectric","armorStarNum":1,"itemBuyingPrice":4000,"itemCreatingPrice":0,"itemSellingPrice":600,"profile":"ArmorUpper","specialStatus":21},"Armor_048_Head":{"armorDefenceAddLevel":3,"armorEffectEffectType":"AttackUp","armorStarNum":1,"itemBuyingPrice":4000,"itemCreatingPrice":0,"itemSellingPrice":600,"profile":"ArmorHead","specialStatus":8},"Armor_048_Lower":{"armorDefenceAddLevel":3,"armorEffectEffectType":"AttackUp","armorStarNum":1,"itemBuyingPrice":4000,"itemCreatingPrice":0,"itemSellingPrice":600,"profile":"ArmorLower","specialStatus":8},"Armor_048_Upper":{"armorDefenceAddLevel":3,"armorEffectEffectType":"AttackUp","armorStarNum":1,"itemBuyingPrice":4000,"itemCreatingPrice":0,"itemSellingPrice":600,"profile":"ArmorUpper","specialStatus":8},"Armor_049_Lower":{"armorDefenceAddLevel":3,"armorEffectEffectType":"SandMove","armorStarNum":1,"itemBuyingPrice":800,"itemCreatingPrice":0,"itemSellingPrice":200,"profile":"ArmorLower","specialStatus":25},"Armor_053_Head":{"armorDefenceAddLevel":1,"armorStarNum":1,"itemBuyingPrice":180,"itemCreatingPrice":0,"itemSellingPrice":45,"profile":"ArmorHead"},"Armor_053_Lower":{"armorDefenceAddLevel":1,"armorStarNum":1,"itemBuyingPrice":180,"itemCreatingPrice":0,"itemSellingPrice":45,"profile":"ArmorLower"},"Armor_053_Upper":{"armorDefenceAddLevel":1,"armorStarNum":1,"itemBuyingPrice":180,"itemCreatingPrice":0,"itemSellingPrice":45,"profile":"ArmorUpper"},"Armor_055_Head":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":120,"itemCreatingPrice":0,"itemSellingPrice":29,"profile":"ArmorHead"},"Armor_056_Head":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":320,"itemCreatingPrice":0,"itemSellingPrice":39,"profile":"ArmorHead"},"Armor_060_Head":{"armorDefenceAddLevel":18,"armorStarNum":4,"cannotSell":true,"itemBuyingPrice":1530,"itemCreatingPrice":0,"itemSellingPrice":385,"profile":"ArmorHead"},"Armor_060_Lower":{"armorDefenceAddLevel":18,"armorStarNum":4,"cannotSell":true,"itemBuyingPrice":1530,"itemCreatingPrice":0,"itemSellingPrice":385,"profile":"ArmorLower"},"Armor_060_Upper":{"armorDefenceAddLevel":18,"armorStarNum":4,"cannotSell":true,"itemBuyingPrice":1530,"itemCreatingPrice":0,"itemSellingPrice":385,"profile":"ArmorUpper"},"Armor_061_Head":{"armorDefenceAddLevel":28,"armorStarNum":5,"cannotSell":true,"itemBuyingPrice":2430,"itemCreatingPrice":0,"itemSellingPrice":610,"profile":"ArmorHead"},"Armor_061_Lower":{"armorDefenceAddLevel":28,"armorStarNum":5,"cannotSell":true,"itemBuyingPrice":2430,"itemCreatingPrice":0,"itemSellingPrice":610,"profile":"ArmorLower"},"Armor_061_Upper":{"armorDefenceAddLevel":28,"armorStarNum":5,"cannotSell":true,"itemBuyingPrice":2430,"itemCreatingPrice":0,"itemSellingPrice":610,"profile":"ArmorUpper"},"Armor_062_Head":{"armorDefenceAddLevel":8,"armorEffectEffectType":"SwimSpeed","armorStarNum":3,"cannotSell":true,"itemBuyingPrice":235,"itemCreatingPrice":0,"itemSellingPrice":60,"profile":"ArmorHead","specialStatus":29},"Armor_062_Lower":{"armorDefenceAddLevel":8,"armorEffectEffectType":"SwimSpeed","armorStarNum":3,"cannotSell":true,"itemBuyingPrice":235,"itemCreatingPrice":0,"itemSellingPrice":60,"profile":"ArmorLower","specialStatus":29},"Armor_062_Upper":{"armorDefenceAddLevel":8,"armorEffectEffectType":"SwimSpeed","armorStarNum":3,"cannotSell":true,"itemBuyingPrice":235,"itemCreatingPrice":0,"itemSellingPrice":60,"profile":"ArmorUpper","specialStatus":29},"Armor_063_Head":{"armorDefenceAddLevel":12,"armorEffectEffectType":"SwimSpeed","armorStarNum":4,"cannotSell":true,"itemBuyingPrice":465,"itemCreatingPrice":0,"itemSellingPrice":115,"profile":"ArmorHead","specialStatus":29},"Armor_063_Lower":{"armorDefenceAddLevel":12,"armorEffectEffectType":"SwimSpeed","armorStarNum":4,"cannotSell":true,"itemBuyingPrice":465,"itemCreatingPrice":0,"itemSellingPrice":115,"profile":"ArmorLower","specialStatus":29},"Armor_063_Upper":{"armorDefenceAddLevel":12,"armorEffectEffectType":"SwimSpeed","armorStarNum":4,"cannotSell":true,"itemBuyingPrice":465,"itemCreatingPrice":0,"itemSellingPrice":115,"profile":"ArmorUpper","specialStatus":29},"Armor_064_Head":{"armorDefenceAddLevel":20,"armorEffectEffectType":"SwimSpeed","armorStarNum":5,"cannotSell":true,"itemBuyingPrice":1645,"itemCreatingPrice":0,"itemSellingPrice":410,"profile":"ArmorHead","specialStatus":29},"Armor_064_Lower":{"armorDefenceAddLevel":20,"armorEffectEffectType":"SwimSpeed","armorStarNum":5,"cannotSell":true,"itemBuyingPrice":1645,"itemCreatingPrice":0,"itemSellingPrice":410,"profile":"ArmorLower","specialStatus":29},"Armor_064_Upper":{"armorDefenceAddLevel":20,"armorEffectEffectType":"SwimSpeed","armorStarNum":5,"cannotSell":true,"itemBuyingPrice":1645,"itemCreatingPrice":0,"itemSellingPrice":410,"profile":"ArmorUpper","specialStatus":29},"Armor_065_Head":{"armorDefenceAddLevel":8,"armorEffectEffectType":"ResistHot","armorStarNum":3,"itemBuyingPrice":508,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorHead","specialStatus":23},"Armor_065_Lower":{"armorDefenceAddLevel":8,"armorEffectEffectType":"ResistHot","armorStarNum":3,"itemBuyingPrice":708,"itemCreatingPrice":0,"itemSellingPrice":175,"profile":"ArmorLower","specialStatus":23},"Armor_065_Upper":{"armorDefenceAddLevel":8,"armorEffectEffectType":"ResistHot","armorStarNum":3,"itemBuyingPrice":1358,"itemCreatingPrice":0,"itemSellingPrice":340,"profile":"ArmorUpper","specialStatus":23},"Armor_066_Head":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistHot","armorStarNum":4,"itemBuyingPrice":661,"itemCreatingPrice":0,"itemSellingPrice":165,"profile":"ArmorHead","specialStatus":23},"Armor_066_Lower":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistHot","armorStarNum":4,"itemBuyingPrice":861,"itemCreatingPrice":0,"itemSellingPrice":215,"profile":"ArmorLower","specialStatus":23},"Armor_066_Upper":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistHot","armorStarNum":4,"itemBuyingPrice":1511,"itemCreatingPrice":0,"itemSellingPrice":380,"profile":"ArmorUpper","specialStatus":23},"Armor_067_Head":{"armorDefenceAddLevel":20,"armorEffectEffectType":"ResistHot","armorStarNum":5,"itemBuyingPrice":2311,"itemCreatingPrice":0,"itemSellingPrice":580,"profile":"ArmorHead","specialStatus":23},"Armor_067_Lower":{"armorDefenceAddLevel":20,"armorEffectEffectType":"ResistHot","armorStarNum":5,"itemBuyingPrice":2511,"itemCreatingPrice":0,"itemSellingPrice":630,"profile":"ArmorLower","specialStatus":23},"Armor_067_Upper":{"armorDefenceAddLevel":20,"armorEffectEffectType":"ResistHot","armorStarNum":5,"itemBuyingPrice":3161,"itemCreatingPrice":0,"itemSellingPrice":800,"profile":"ArmorUpper","specialStatus":23},"Armor_071_Head":{"armorDefenceAddLevel":8,"armorEffectEffectType":"ResistCold","armorStarNum":3,"itemBuyingPrice":1049,"itemCreatingPrice":0,"itemSellingPrice":260,"profile":"ArmorHead","specialStatus":20},"Armor_071_Lower":{"armorDefenceAddLevel":8,"armorEffectEffectType":"ResistCold","armorStarNum":3,"itemBuyingPrice":599,"itemCreatingPrice":0,"itemSellingPrice":150,"profile":"ArmorLower","specialStatus":20},"Armor_071_Upper":{"armorDefenceAddLevel":8,"armorEffectEffectType":"ResistCold","armorStarNum":3,"itemBuyingPrice":649,"itemCreatingPrice":0,"itemSellingPrice":160,"profile":"ArmorUpper","specialStatus":20},"Armor_072_Head":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistCold","armorStarNum":4,"itemBuyingPrice":1117,"itemCreatingPrice":0,"itemSellingPrice":280,"profile":"ArmorHead","specialStatus":20},"Armor_072_Lower":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistCold","armorStarNum":4,"itemBuyingPrice":699,"itemCreatingPrice":0,"itemSellingPrice":165,"profile":"ArmorLower","specialStatus":20},"Armor_072_Upper":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistCold","armorStarNum":4,"itemBuyingPrice":749,"itemCreatingPrice":0,"itemSellingPrice":185,"profile":"ArmorUpper","specialStatus":20},"Armor_073_Head":{"armorDefenceAddLevel":20,"armorEffectEffectType":"ResistCold","armorStarNum":5,"itemBuyingPrice":2517,"itemCreatingPrice":0,"itemSellingPrice":630,"profile":"ArmorHead","specialStatus":20},"Armor_073_Lower":{"armorDefenceAddLevel":20,"armorEffectEffectType":"ResistCold","armorStarNum":5,"itemBuyingPrice":2067,"itemCreatingPrice":0,"itemSellingPrice":515,"profile":"ArmorLower","specialStatus":20},"Armor_073_Upper":{"armorDefenceAddLevel":20,"armorEffectEffectType":"ResistCold","armorStarNum":5,"itemBuyingPrice":2117,"itemCreatingPrice":0,"itemSellingPrice":530,"profile":"ArmorUpper","specialStatus":20},"Armor_074_Head":{"armorDefenceAddLevel":8,"armorEffectEffectType":"ResistBurn","armorStarNum":3,"itemBuyingPrice":2078,"itemCreatingPrice":0,"itemSellingPrice":520,"profile":"ArmorHead","specialStatus":13},"Armor_074_Lower":{"armorDefenceAddLevel":8,"armorEffectEffectType":"ResistBurn","armorStarNum":3,"itemBuyingPrice":778,"itemCreatingPrice":0,"itemSellingPrice":195,"profile":"ArmorLower","specialStatus":13},"Armor_074_Upper":{"armorDefenceAddLevel":8,"armorEffectEffectType":"ResistBurn","armorStarNum":3,"itemBuyingPrice":678,"itemCreatingPrice":0,"itemSellingPrice":170,"profile":"ArmorUpper","specialStatus":13},"Armor_075_Head":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistBurn","armorStarNum":4,"itemBuyingPrice":2183,"itemCreatingPrice":0,"itemSellingPrice":545,"profile":"ArmorHead","specialStatus":13},"Armor_075_Lower":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistBurn","armorStarNum":4,"itemBuyingPrice":883,"itemCreatingPrice":0,"itemSellingPrice":220,"profile":"ArmorLower","specialStatus":13},"Armor_075_Upper":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistBurn","armorStarNum":4,"itemBuyingPrice":783,"itemCreatingPrice":0,"itemSellingPrice":195,"profile":"ArmorUpper","specialStatus":13},"Armor_076_Head":{"armorDefenceAddLevel":20,"armorEffectEffectType":"ResistBurn","armorStarNum":5,"itemBuyingPrice":2393,"itemCreatingPrice":0,"itemSellingPrice":600,"profile":"ArmorHead","specialStatus":13},"Armor_076_Lower":{"armorDefenceAddLevel":20,"armorEffectEffectType":"ResistBurn","armorStarNum":5,"itemBuyingPrice":1093,"itemCreatingPrice":0,"itemSellingPrice":275,"profile":"ArmorLower","specialStatus":13},"Armor_076_Upper":{"armorDefenceAddLevel":20,"armorEffectEffectType":"ResistBurn","armorStarNum":5,"itemBuyingPrice":993,"itemCreatingPrice":0,"itemSellingPrice":250,"profile":"ArmorUpper","specialStatus":13},"Armor_077_Head":{"armorDefenceAddLevel":6,"armorEffectEffectType":"Quietness","armorStarNum":3,"itemBuyingPrice":542,"itemCreatingPrice":0,"itemSellingPrice":135,"profile":"ArmorHead","specialStatus":17},"Armor_077_Head_B":{"armorDefenceAddLevel":6,"armorEffectEffectType":"Quietness","armorStarNum":3,"itemBuyingPrice":542,"itemCreatingPrice":0,"itemSellingPrice":135,"profile":"ArmorHead","specialStatus":17},"Armor_077_Lower":{"armorDefenceAddLevel":6,"armorEffectEffectType":"Quietness","armorStarNum":3,"itemBuyingPrice":642,"itemCreatingPrice":0,"itemSellingPrice":160,"profile":"ArmorLower","specialStatus":17},"Armor_077_Upper":{"armorDefenceAddLevel":6,"armorEffectEffectType":"Quietness","armorStarNum":3,"itemBuyingPrice":742,"itemCreatingPrice":0,"itemSellingPrice":185,"profile":"ArmorUpper","specialStatus":17},"Armor_078_Head":{"armorDefenceAddLevel":9,"armorEffectEffectType":"Quietness","armorStarNum":4,"itemBuyingPrice":596,"itemCreatingPrice":0,"itemSellingPrice":150,"profile":"ArmorHead","specialStatus":17},"Armor_078_Head_B":{"armorDefenceAddLevel":9,"armorEffectEffectType":"Quietness","armorStarNum":4,"itemBuyingPrice":596,"itemCreatingPrice":0,"itemSellingPrice":150,"profile":"ArmorHead","specialStatus":17},"Armor_078_Lower":{"armorDefenceAddLevel":9,"armorEffectEffectType":"Quietness","armorStarNum":4,"itemBuyingPrice":696,"itemCreatingPrice":0,"itemSellingPrice":175,"profile":"ArmorLower","specialStatus":17},"Armor_078_Upper":{"armorDefenceAddLevel":9,"armorEffectEffectType":"Quietness","armorStarNum":4,"itemBuyingPrice":796,"itemCreatingPrice":0,"itemSellingPrice":200,"profile":"ArmorUpper","specialStatus":17},"Armor_079_Head":{"armorDefenceAddLevel":16,"armorEffectEffectType":"Quietness","armorStarNum":5,"itemBuyingPrice":896,"itemCreatingPrice":0,"itemSellingPrice":225,"profile":"ArmorHead","specialStatus":17},"Armor_079_Head_B":{"armorDefenceAddLevel":16,"armorEffectEffectType":"Quietness","armorStarNum":5,"itemBuyingPrice":896,"itemCreatingPrice":0,"itemSellingPrice":225,"profile":"ArmorHead","specialStatus":17},"Armor_079_Lower":{"armorDefenceAddLevel":16,"armorEffectEffectType":"Quietness","armorStarNum":5,"itemBuyingPrice":996,"itemCreatingPrice":0,"itemSellingPrice":250,"profile":"ArmorLower","specialStatus":17},"Armor_079_Upper":{"armorDefenceAddLevel":16,"armorEffectEffectType":"Quietness","armorStarNum":5,"itemBuyingPrice":1095,"itemCreatingPrice":0,"itemSellingPrice":275,"profile":"ArmorUpper","specialStatus":17},"Armor_083_Head":{"armorDefenceAddLevel":5,"armorEffectEffectType":"ClimbSpeed","armorStarNum":2,"itemBuyingPrice":4018,"itemCreatingPrice":0,"itemSellingPrice":605,"profile":"ArmorHead","specialStatus":9},"Armor_083_Lower":{"armorDefenceAddLevel":5,"armorEffectEffectType":"ClimbSpeed","armorStarNum":2,"itemBuyingPrice":4018,"itemCreatingPrice":0,"itemSellingPrice":605,"profile":"ArmorLower","specialStatus":9},"Armor_083_Upper":{"armorDefenceAddLevel":5,"armorEffectEffectType":"ClimbSpeed","armorStarNum":2,"itemBuyingPrice":4018,"itemCreatingPrice":0,"itemSellingPrice":605,"profile":"ArmorUpper","specialStatus":9},"Armor_084_Head":{"armorDefenceAddLevel":8,"armorEffectEffectType":"ClimbSpeed","armorStarNum":3,"itemBuyingPrice":4060,"itemCreatingPrice":0,"itemSellingPrice":610,"profile":"ArmorHead","specialStatus":9},"Armor_084_Lower":{"armorDefenceAddLevel":8,"armorEffectEffectType":"ClimbSpeed","armorStarNum":3,"itemBuyingPrice":4060,"itemCreatingPrice":0,"itemSellingPrice":610,"profile":"ArmorLower","specialStatus":9},"Armor_084_Upper":{"armorDefenceAddLevel":8,"armorEffectEffectType":"ClimbSpeed","armorStarNum":3,"itemBuyingPrice":4060,"itemCreatingPrice":0,"itemSellingPrice":610,"profile":"ArmorUpper","specialStatus":9},"Armor_085_Head":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ClimbSpeed","armorStarNum":4,"itemBuyingPrice":4120,"itemCreatingPrice":0,"itemSellingPrice":620,"profile":"ArmorHead","specialStatus":9},"Armor_085_Lower":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ClimbSpeed","armorStarNum":4,"itemBuyingPrice":4120,"itemCreatingPrice":0,"itemSellingPrice":620,"profile":"ArmorLower","specialStatus":9},"Armor_085_Upper":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ClimbSpeed","armorStarNum":4,"itemBuyingPrice":4120,"itemCreatingPrice":0,"itemSellingPrice":620,"profile":"ArmorUpper","specialStatus":9},"Armor_086_Head":{"armorDefenceAddLevel":20,"armorEffectEffectType":"ClimbSpeed","armorStarNum":5,"itemBuyingPrice":4300,"itemCreatingPrice":0,"itemSellingPrice":645,"profile":"ArmorHead","specialStatus":9},"Armor_086_Lower":{"armorDefenceAddLevel":20,"armorEffectEffectType":"ClimbSpeed","armorStarNum":5,"itemBuyingPrice":4300,"itemCreatingPrice":0,"itemSellingPrice":645,"profile":"ArmorLower","specialStatus":9},"Armor_086_Upper":{"armorDefenceAddLevel":20,"armorEffectEffectType":"ClimbSpeed","armorStarNum":5,"itemBuyingPrice":4300,"itemCreatingPrice":0,"itemSellingPrice":645,"profile":"ArmorUpper","specialStatus":9},"Armor_087_Head":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":1210,"itemCreatingPrice":0,"itemSellingPrice":305,"profile":"ArmorHead"},"Armor_087_Lower":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":1210,"itemCreatingPrice":0,"itemSellingPrice":305,"profile":"ArmorLower"},"Armor_087_Upper":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":1210,"itemCreatingPrice":0,"itemSellingPrice":305,"profile":"ArmorUpper"},"Armor_088_Head":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":1845,"itemCreatingPrice":0,"itemSellingPrice":460,"profile":"ArmorHead"},"Armor_088_Lower":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":1845,"itemCreatingPrice":0,"itemSellingPrice":460,"profile":"ArmorLower"},"Armor_088_Upper":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":1845,"itemCreatingPrice":0,"itemSellingPrice":460,"profile":"ArmorUpper"},"Armor_089_Head":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":2765,"itemCreatingPrice":0,"itemSellingPrice":690,"profile":"ArmorHead"},"Armor_089_Lower":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":2765,"itemCreatingPrice":0,"itemSellingPrice":690,"profile":"ArmorLower"},"Armor_089_Upper":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":2765,"itemCreatingPrice":0,"itemSellingPrice":690,"profile":"ArmorUpper"},"Armor_090_Head":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":4365,"itemCreatingPrice":0,"itemSellingPrice":1090,"profile":"ArmorHead"},"Armor_090_Lower":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":4365,"itemCreatingPrice":0,"itemSellingPrice":1090,"profile":"ArmorLower"},"Armor_090_Upper":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":4365,"itemCreatingPrice":0,"itemSellingPrice":1090,"profile":"ArmorUpper"},"Armor_095_Head":{"armorDefenceAddLevel":7,"armorStarNum":2,"itemBuyingPrice":250,"itemCreatingPrice":0,"itemSellingPrice":65,"profile":"ArmorHead"},"Armor_095_Lower":{"armorDefenceAddLevel":7,"armorStarNum":2,"itemBuyingPrice":270,"itemCreatingPrice":0,"itemSellingPrice":70,"profile":"ArmorLower"},"Armor_095_Upper":{"armorDefenceAddLevel":7,"armorStarNum":2,"itemBuyingPrice":320,"itemCreatingPrice":0,"itemSellingPrice":80,"profile":"ArmorUpper"},"Armor_096_Head":{"armorDefenceAddLevel":12,"armorStarNum":3,"itemBuyingPrice":385,"itemCreatingPrice":0,"itemSellingPrice":95,"profile":"ArmorHead"},"Armor_096_Lower":{"armorDefenceAddLevel":12,"armorStarNum":3,"itemBuyingPrice":405,"itemCreatingPrice":0,"itemSellingPrice":100,"profile":"ArmorLower"},"Armor_096_Upper":{"armorDefenceAddLevel":12,"armorStarNum":3,"itemBuyingPrice":455,"itemCreatingPrice":0,"itemSellingPrice":115,"profile":"ArmorUpper"},"Armor_097_Head":{"armorDefenceAddLevel":18,"armorStarNum":4,"itemBuyingPrice":601,"itemCreatingPrice":0,"itemSellingPrice":150,"profile":"ArmorHead"},"Armor_097_Lower":{"armorDefenceAddLevel":18,"armorStarNum":4,"itemBuyingPrice":569,"itemCreatingPrice":0,"itemSellingPrice":140,"profile":"ArmorLower"},"Armor_097_Upper":{"armorDefenceAddLevel":18,"armorStarNum":4,"itemBuyingPrice":619,"itemCreatingPrice":0,"itemSellingPrice":155,"profile":"ArmorUpper"},"Armor_098_Head":{"armorDefenceAddLevel":28,"armorStarNum":5,"itemBuyingPrice":1101,"itemCreatingPrice":0,"itemSellingPrice":275,"profile":"ArmorHead"},"Armor_098_Lower":{"armorDefenceAddLevel":28,"armorStarNum":5,"itemBuyingPrice":1069,"itemCreatingPrice":0,"itemSellingPrice":265,"profile":"ArmorLower"},"Armor_098_Upper":{"armorDefenceAddLevel":28,"armorStarNum":5,"itemBuyingPrice":1169,"itemCreatingPrice":0,"itemSellingPrice":290,"profile":"ArmorUpper"},"Armor_099_Head":{"armorDefenceAddLevel":7,"armorEffectEffectType":"ResistAncient","armorStarNum":2,"itemBuyingPrice":635,"itemCreatingPrice":3000,"itemSellingPrice":160,"profile":"ArmorHead","specialStatus":19},"Armor_099_Lower":{"armorDefenceAddLevel":7,"armorEffectEffectType":"ResistAncient","armorStarNum":2,"itemBuyingPrice":635,"itemCreatingPrice":3000,"itemSellingPrice":160,"profile":"ArmorLower","specialStatus":19},"Armor_099_Upper":{"armorDefenceAddLevel":7,"armorEffectEffectType":"ResistAncient","armorStarNum":2,"itemBuyingPrice":635,"itemCreatingPrice":3000,"itemSellingPrice":160,"profile":"ArmorUpper","specialStatus":19},"Armor_100_Head":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistAncient","armorStarNum":3,"itemBuyingPrice":1160,"itemCreatingPrice":4000,"itemSellingPrice":290,"profile":"ArmorHead","specialStatus":19},"Armor_100_Lower":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistAncient","armorStarNum":3,"itemBuyingPrice":1160,"itemCreatingPrice":4000,"itemSellingPrice":290,"profile":"ArmorLower","specialStatus":19},"Armor_100_Upper":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistAncient","armorStarNum":3,"itemBuyingPrice":1160,"itemCreatingPrice":4000,"itemSellingPrice":290,"profile":"ArmorUpper","specialStatus":19},"Armor_101_Head":{"armorDefenceAddLevel":18,"armorEffectEffectType":"ResistAncient","armorStarNum":4,"itemBuyingPrice":2235,"itemCreatingPrice":5000,"itemSellingPrice":560,"profile":"ArmorHead","specialStatus":19},"Armor_101_Lower":{"armorDefenceAddLevel":18,"armorEffectEffectType":"ResistAncient","armorStarNum":4,"itemBuyingPrice":2235,"itemCreatingPrice":5000,"itemSellingPrice":560,"profile":"ArmorLower","specialStatus":19},"Armor_101_Upper":{"armorDefenceAddLevel":18,"armorEffectEffectType":"ResistAncient","armorStarNum":4,"itemBuyingPrice":2235,"itemCreatingPrice":5000,"itemSellingPrice":560,"profile":"ArmorUpper","specialStatus":19},"Armor_102_Head":{"armorDefenceAddLevel":28,"armorEffectEffectType":"ResistAncient","armorStarNum":5,"itemBuyingPrice":2935,"itemCreatingPrice":6000,"itemSellingPrice":735,"profile":"ArmorHead","specialStatus":19},"Armor_102_Lower":{"armorDefenceAddLevel":28,"armorEffectEffectType":"ResistAncient","armorStarNum":5,"itemBuyingPrice":2935,"itemCreatingPrice":6000,"itemSellingPrice":735,"profile":"ArmorLower","specialStatus":19},"Armor_102_Upper":{"armorDefenceAddLevel":28,"armorEffectEffectType":"ResistAncient","armorStarNum":5,"itemBuyingPrice":2935,"itemCreatingPrice":6000,"itemSellingPrice":735,"profile":"ArmorUpper","specialStatus":19},"Armor_103_Head":{"armorDefenceAddLevel":5,"armorEffectEffectType":"ResistElectric","armorStarNum":2,"itemBuyingPrice":4015,"itemCreatingPrice":0,"itemSellingPrice":600,"profile":"ArmorHead","specialStatus":21},"Armor_103_Lower":{"armorDefenceAddLevel":5,"armorEffectEffectType":"ResistElectric","armorStarNum":2,"itemBuyingPrice":4015,"itemCreatingPrice":0,"itemSellingPrice":600,"profile":"ArmorLower","specialStatus":21},"Armor_103_Upper":{"armorDefenceAddLevel":5,"armorEffectEffectType":"ResistElectric","armorStarNum":2,"itemBuyingPrice":4015,"itemCreatingPrice":0,"itemSellingPrice":600,"profile":"ArmorUpper","specialStatus":21},"Armor_104_Head":{"armorDefenceAddLevel":8,"armorEffectEffectType":"ResistElectric","armorStarNum":3,"itemBuyingPrice":4058,"itemCreatingPrice":0,"itemSellingPrice":610,"profile":"ArmorHead","specialStatus":21},"Armor_104_Lower":{"armorDefenceAddLevel":8,"armorEffectEffectType":"ResistElectric","armorStarNum":3,"itemBuyingPrice":4058,"itemCreatingPrice":0,"itemSellingPrice":610,"profile":"ArmorLower","specialStatus":21},"Armor_104_Upper":{"armorDefenceAddLevel":8,"armorEffectEffectType":"ResistElectric","armorStarNum":3,"itemBuyingPrice":4058,"itemCreatingPrice":0,"itemSellingPrice":610,"profile":"ArmorUpper","specialStatus":21},"Armor_105_Head":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistElectric","armorStarNum":4,"itemBuyingPrice":4253,"itemCreatingPrice":0,"itemSellingPrice":640,"profile":"ArmorHead","specialStatus":21},"Armor_105_Lower":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistElectric","armorStarNum":4,"itemBuyingPrice":4253,"itemCreatingPrice":0,"itemSellingPrice":640,"profile":"ArmorLower","specialStatus":21},"Armor_105_Upper":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistElectric","armorStarNum":4,"itemBuyingPrice":4253,"itemCreatingPrice":0,"itemSellingPrice":640,"profile":"ArmorUpper","specialStatus":21},"Armor_106_Head":{"armorDefenceAddLevel":20,"armorEffectEffectType":"ResistElectric","armorStarNum":5,"itemBuyingPrice":6403,"itemCreatingPrice":0,"itemSellingPrice":960,"profile":"ArmorHead","specialStatus":21},"Armor_106_Lower":{"armorDefenceAddLevel":20,"armorEffectEffectType":"ResistElectric","armorStarNum":5,"itemBuyingPrice":6403,"itemCreatingPrice":0,"itemSellingPrice":960,"profile":"ArmorLower","specialStatus":21},"Armor_106_Upper":{"armorDefenceAddLevel":20,"armorEffectEffectType":"ResistElectric","armorStarNum":5,"itemBuyingPrice":6403,"itemCreatingPrice":0,"itemSellingPrice":960,"profile":"ArmorUpper","specialStatus":21},"Armor_111_Head":{"armorDefenceAddLevel":5,"armorEffectEffectType":"AttackUp","armorStarNum":2,"itemBuyingPrice":4040,"itemCreatingPrice":0,"itemSellingPrice":700,"profile":"ArmorHead","specialStatus":8},"Armor_111_Lower":{"armorDefenceAddLevel":5,"armorEffectEffectType":"AttackUp","armorStarNum":2,"itemBuyingPrice":4040,"itemCreatingPrice":0,"itemSellingPrice":700,"profile":"ArmorLower","specialStatus":8},"Armor_111_Upper":{"armorDefenceAddLevel":5,"armorEffectEffectType":"AttackUp","armorStarNum":2,"itemBuyingPrice":4040,"itemCreatingPrice":0,"itemSellingPrice":700,"profile":"ArmorUpper","specialStatus":8},"Armor_112_Head":{"armorDefenceAddLevel":8,"armorEffectEffectType":"AttackUp","armorStarNum":3,"itemBuyingPrice":4260,"itemCreatingPrice":0,"itemSellingPrice":640,"profile":"ArmorHead","specialStatus":8},"Armor_112_Lower":{"armorDefenceAddLevel":8,"armorEffectEffectType":"AttackUp","armorStarNum":3,"itemBuyingPrice":4260,"itemCreatingPrice":0,"itemSellingPrice":640,"profile":"ArmorLower","specialStatus":8},"Armor_112_Upper":{"armorDefenceAddLevel":8,"armorEffectEffectType":"AttackUp","armorStarNum":3,"itemBuyingPrice":4260,"itemCreatingPrice":0,"itemSellingPrice":640,"profile":"ArmorUpper","specialStatus":8},"Armor_113_Head":{"armorDefenceAddLevel":12,"armorEffectEffectType":"AttackUp","armorStarNum":4,"itemBuyingPrice":4660,"itemCreatingPrice":0,"itemSellingPrice":700,"profile":"ArmorHead","specialStatus":8},"Armor_113_Lower":{"armorDefenceAddLevel":12,"armorEffectEffectType":"AttackUp","armorStarNum":4,"itemBuyingPrice":4660,"itemCreatingPrice":0,"itemSellingPrice":700,"profile":"ArmorLower","specialStatus":8},"Armor_113_Upper":{"armorDefenceAddLevel":12,"armorEffectEffectType":"AttackUp","armorStarNum":4,"itemBuyingPrice":4660,"itemCreatingPrice":0,"itemSellingPrice":700,"profile":"ArmorUpper","specialStatus":8},"Armor_114_Head":{"armorDefenceAddLevel":20,"armorEffectEffectType":"AttackUp","armorStarNum":5,"itemBuyingPrice":5360,"itemCreatingPrice":0,"itemSellingPrice":805,"profile":"ArmorHead","specialStatus":8},"Armor_114_Lower":{"armorDefenceAddLevel":20,"armorEffectEffectType":"AttackUp","armorStarNum":5,"itemBuyingPrice":5360,"itemCreatingPrice":0,"itemSellingPrice":805,"profile":"ArmorLower","specialStatus":8},"Armor_114_Upper":{"armorDefenceAddLevel":20,"armorEffectEffectType":"AttackUp","armorStarNum":5,"itemBuyingPrice":5360,"itemCreatingPrice":0,"itemSellingPrice":805,"profile":"ArmorUpper","specialStatus":8},"Armor_115_Head":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ResistLightning","armorStarNum":1,"cannotSell":true,"itemBuyingPrice":1000,"itemCreatingPrice":0,"itemSellingPrice":250,"profile":"ArmorHead","specialStatus":24},"Armor_116_Upper":{"armorDefenceAddLevel":5,"armorStarNum":1,"cannotSell":true,"itemBuyingPrice":1000,"itemCreatingPrice":0,"itemSellingPrice":250,"profile":"ArmorUpper"},"Armor_117_Head":{"armorDefenceAddLevel":7,"armorEffectEffectType":"ResistAncient","armorStarNum":2,"itemBuyingPrice":1800,"itemCreatingPrice":0,"itemSellingPrice":630,"profile":"ArmorHead","specialStatus":19},"Armor_118_Head":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistAncient","armorStarNum":3,"itemBuyingPrice":3800,"itemCreatingPrice":0,"itemSellingPrice":1135,"profile":"ArmorHead","specialStatus":19},"Armor_119_Head":{"armorDefenceAddLevel":18,"armorEffectEffectType":"ResistAncient","armorStarNum":4,"itemBuyingPrice":6800,"itemCreatingPrice":0,"itemSellingPrice":1960,"profile":"ArmorHead","specialStatus":19},"Armor_120_Head":{"armorDefenceAddLevel":28,"armorEffectEffectType":"ResistAncient","armorStarNum":5,"itemBuyingPrice":11800,"itemCreatingPrice":0,"itemSellingPrice":3285,"profile":"ArmorHead","specialStatus":19},"Armor_121_Head":{"armorDefenceAddLevel":5,"armorEffectEffectType":"ResistCold","armorStarNum":2,"itemBuyingPrice":935,"itemCreatingPrice":0,"itemSellingPrice":235,"profile":"ArmorHead","specialStatus":20},"Armor_122_Head":{"armorDefenceAddLevel":8,"armorEffectEffectType":"ResistCold","armorStarNum":3,"itemBuyingPrice":1790,"itemCreatingPrice":0,"itemSellingPrice":450,"profile":"ArmorHead","specialStatus":20},"Armor_123_Head":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistCold","armorStarNum":4,"itemBuyingPrice":3350,"itemCreatingPrice":0,"itemSellingPrice":840,"profile":"ArmorHead","specialStatus":20},"Armor_124_Head":{"armorDefenceAddLevel":20,"armorEffectEffectType":"ResistCold","armorStarNum":5,"itemBuyingPrice":5750,"itemCreatingPrice":0,"itemSellingPrice":1440,"profile":"ArmorHead","specialStatus":20},"Armor_125_Head":{"armorDefenceAddLevel":5,"armorEffectEffectType":"ResistHot","armorStarNum":2,"itemBuyingPrice":1135,"itemCreatingPrice":0,"itemSellingPrice":285,"profile":"ArmorHead","specialStatus":23},"Armor_126_Head":{"armorDefenceAddLevel":8,"armorEffectEffectType":"ResistHot","armorStarNum":3,"itemBuyingPrice":2190,"itemCreatingPrice":0,"itemSellingPrice":550,"profile":"ArmorHead","specialStatus":23},"Armor_127_Head":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistHot","armorStarNum":4,"itemBuyingPrice":4050,"itemCreatingPrice":0,"itemSellingPrice":1015,"profile":"ArmorHead","specialStatus":23},"Armor_128_Head":{"armorDefenceAddLevel":20,"armorEffectEffectType":"ResistHot","armorStarNum":5,"itemBuyingPrice":6950,"itemCreatingPrice":0,"itemSellingPrice":1740,"profile":"ArmorHead","specialStatus":23},"Armor_129_Head":{"armorDefenceAddLevel":5,"armorEffectEffectType":"ResistElectric","armorStarNum":2,"itemBuyingPrice":775,"itemCreatingPrice":0,"itemSellingPrice":195,"profile":"ArmorHead","specialStatus":21},"Armor_130_Head":{"armorDefenceAddLevel":8,"armorEffectEffectType":"ResistElectric","armorStarNum":3,"itemBuyingPrice":1510,"itemCreatingPrice":0,"itemSellingPrice":380,"profile":"ArmorHead","specialStatus":21},"Armor_131_Head":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistElectric","armorStarNum":4,"itemBuyingPrice":2890,"itemCreatingPrice":0,"itemSellingPrice":725,"profile":"ArmorHead","specialStatus":21},"Armor_132_Head":{"armorDefenceAddLevel":18,"armorEffectEffectType":"ResistElectric","armorStarNum":5,"itemBuyingPrice":4990,"itemCreatingPrice":0,"itemSellingPrice":1250,"profile":"ArmorHead","specialStatus":21},"Armor_133_Head":{"armorDefenceAddLevel":5,"armorEffectEffectType":"SwimSpeed","armorStarNum":2,"itemBuyingPrice":465,"itemCreatingPrice":0,"itemSellingPrice":115,"profile":"ArmorHead","specialStatus":29},"Armor_134_Head":{"armorDefenceAddLevel":8,"armorEffectEffectType":"SwimSpeed","armorStarNum":3,"itemBuyingPrice":960,"itemCreatingPrice":0,"itemSellingPrice":240,"profile":"ArmorHead","specialStatus":29},"Armor_135_Head":{"armorDefenceAddLevel":12,"armorEffectEffectType":"SwimSpeed","armorStarNum":4,"itemBuyingPrice":1935,"itemCreatingPrice":0,"itemSellingPrice":485,"profile":"ArmorHead","specialStatus":29},"Armor_136_Head":{"armorDefenceAddLevel":20,"armorEffectEffectType":"SwimSpeed","armorStarNum":5,"itemBuyingPrice":3150,"itemCreatingPrice":0,"itemSellingPrice":790,"profile":"ArmorHead","specialStatus":29},"Armor_137_Head":{"armorDefenceAddLevel":7,"armorStarNum":2,"itemBuyingPrice":255,"itemCreatingPrice":0,"itemSellingPrice":65,"profile":"ArmorHead"},"Armor_138_Head":{"armorDefenceAddLevel":12,"armorStarNum":3,"itemBuyingPrice":570,"itemCreatingPrice":0,"itemSellingPrice":145,"profile":"ArmorHead"},"Armor_139_Head":{"armorDefenceAddLevel":18,"armorStarNum":4,"itemBuyingPrice":1185,"itemCreatingPrice":0,"itemSellingPrice":295,"profile":"ArmorHead"},"Armor_140_Head":{"armorDefenceAddLevel":28,"armorStarNum":5,"itemBuyingPrice":2100,"itemCreatingPrice":0,"itemSellingPrice":525,"profile":"ArmorHead"},"Armor_140_Lower":{"armorDefenceAddLevel":3,"armorEffectEffectType":"SnowMove","armorStarNum":1,"cannotSell":true,"itemBuyingPrice":800,"itemCreatingPrice":0,"itemSellingPrice":200,"profile":"ArmorLower","specialStatus":26},"Armor_141_Lower":{"armorDefenceAddLevel":3,"armorEffectEffectType":"SnowMove","armorStarNum":1,"itemBuyingPrice":800,"itemCreatingPrice":0,"itemSellingPrice":200,"profile":"ArmorLower","specialStatus":26},"Armor_148_Upper":{"armorDefenceAddLevel":8,"armorStarNum":2,"cannotSell":true,"itemBuyingPrice":1120,"itemCreatingPrice":0,"itemSellingPrice":280,"profile":"ArmorUpper"},"Armor_149_Upper":{"armorDefenceAddLevel":14,"armorStarNum":3,"cannotSell":true,"itemBuyingPrice":1840,"itemCreatingPrice":0,"itemSellingPrice":460,"profile":"ArmorUpper"},"Armor_150_Upper":{"armorDefenceAddLevel":22,"armorStarNum":4,"cannotSell":true,"itemBuyingPrice":2640,"itemCreatingPrice":0,"itemSellingPrice":660,"profile":"ArmorUpper"},"Armor_151_Upper":{"armorDefenceAddLevel":32,"armorStarNum":5,"cannotSell":true,"itemBuyingPrice":3640,"itemCreatingPrice":0,"itemSellingPrice":910,"profile":"ArmorUpper"},"Armor_152_Lower":{"armorDefenceAddLevel":5,"armorEffectEffectType":"SandMove","armorStarNum":2,"itemBuyingPrice":980,"itemCreatingPrice":0,"itemSellingPrice":245,"profile":"ArmorLower","specialStatus":25},"Armor_153_Lower":{"armorDefenceAddLevel":8,"armorEffectEffectType":"SandMove","armorStarNum":3,"itemBuyingPrice":1320,"itemCreatingPrice":0,"itemSellingPrice":330,"profile":"ArmorLower","specialStatus":25},"Armor_154_Lower":{"armorDefenceAddLevel":12,"armorEffectEffectType":"SandMove","armorStarNum":4,"itemBuyingPrice":1585,"itemCreatingPrice":0,"itemSellingPrice":395,"profile":"ArmorLower","specialStatus":25},"Armor_155_Lower":{"armorDefenceAddLevel":20,"armorEffectEffectType":"SandMove","armorStarNum":5,"itemBuyingPrice":2175,"itemCreatingPrice":0,"itemSellingPrice":545,"profile":"ArmorLower","specialStatus":25},"Armor_156_Lower":{"armorDefenceAddLevel":5,"armorEffectEffectType":"SnowMove","armorStarNum":2,"itemBuyingPrice":870,"itemCreatingPrice":0,"itemSellingPrice":220,"profile":"ArmorLower","specialStatus":26},"Armor_157_Lower":{"armorDefenceAddLevel":8,"armorEffectEffectType":"SnowMove","armorStarNum":3,"itemBuyingPrice":935,"itemCreatingPrice":0,"itemSellingPrice":235,"profile":"ArmorLower","specialStatus":26},"Armor_158_Lower":{"armorDefenceAddLevel":12,"armorEffectEffectType":"SnowMove","armorStarNum":4,"itemBuyingPrice":1070,"itemCreatingPrice":0,"itemSellingPrice":270,"profile":"ArmorLower","specialStatus":26},"Armor_159_Lower":{"armorDefenceAddLevel":20,"armorEffectEffectType":"SnowMove","armorStarNum":5,"itemBuyingPrice":1530,"itemCreatingPrice":0,"itemSellingPrice":385,"profile":"ArmorLower","specialStatus":26},"Armor_160_Head":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":40,"itemCreatingPrice":0,"itemSellingPrice":9,"profile":"ArmorHead"},"Armor_160_Lower":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":40,"itemCreatingPrice":0,"itemSellingPrice":9,"profile":"ArmorLower"},"Armor_160_Upper":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":40,"itemCreatingPrice":0,"itemSellingPrice":9,"profile":"ArmorUpper"},"Armor_168_Head":{"armorDefenceAddLevel":18,"armorEffectEffectType":"ResistElectricAndResistAncient","armorStarNum":4,"itemBuyingPrice":2235,"itemCreatingPrice":5000,"itemSellingPrice":560,"profile":"ArmorHead","specialStatus":21},"Armor_169_Head":{"armorDefenceAddLevel":28,"armorEffectEffectType":"ResistElectricAndResistAncient","armorStarNum":5,"itemBuyingPrice":2935,"itemCreatingPrice":6000,"itemSellingPrice":735,"profile":"ArmorHead","specialStatus":21},"Armor_170_Upper":{"armorDefenceAddLevel":1,"armorStarNum":1,"itemBuyingPrice":50,"itemCreatingPrice":0,"itemSellingPrice":15,"profile":"ArmorUpper"},"Armor_171_Head":{"armorDefenceAddLevel":8,"armorEffectEffectType":"AttackUp","armorStarNum":1,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"ArmorHead","specialStatus":8},"Armor_171_Lower":{"armorDefenceAddLevel":8,"armorEffectEffectType":"AttackUp","armorStarNum":1,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"ArmorLower","specialStatus":8},"Armor_171_Upper":{"armorDefenceAddLevel":8,"armorEffectEffectType":"AttackUp","armorStarNum":1,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"ArmorUpper","specialStatus":8},"Armor_172_Head":{"armorDefenceAddLevel":1,"armorStarNum":1,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"ArmorHead"},"Armor_173_Head":{"armorDefenceAddLevel":7,"armorEffectEffectType":"ResistAncient","armorStarNum":1,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"ArmorHead","specialStatus":19},"Armor_174_Head":{"armorDefenceAddLevel":2,"armorStarNum":1,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"ArmorHead"},"Armor_174_Lower":{"armorDefenceAddLevel":2,"armorStarNum":1,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"ArmorLower"},"Armor_174_Upper":{"armorDefenceAddLevel":2,"armorStarNum":1,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"ArmorUpper"},"Armor_175_Upper":{"armorDefenceAddLevel":1,"armorEffectEffectType":"ResistHotAndWakeWind","armorStarNum":1,"itemBuyingPrice":50,"itemCreatingPrice":0,"itemSellingPrice":15,"profile":"ArmorUpper","specialStatus":23},"Armor_176_Head":{"armorDefenceAddLevel":1,"armorStarNum":1,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"ArmorHead"},"Armor_177_Head":{"armorDefenceAddLevel":2,"armorEffectEffectType":"ClimbSpeedAndBeamPowerUp","armorStarNum":1,"itemBuyingPrice":50,"itemCreatingPrice":0,"itemSellingPrice":15,"profile":"ArmorHead","specialStatus":9},"Armor_177_Head_B":{"armorDefenceAddLevel":2,"armorEffectEffectType":"ClimbSpeedAndBeamPowerUp","armorStarNum":1,"itemBuyingPrice":50,"itemCreatingPrice":0,"itemSellingPrice":15,"profile":"ArmorHead","specialStatus":9},"Armor_178_Head":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ResistFreeze","armorStarNum":1,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"ArmorHead","specialStatus":22},"Armor_178_Head_B":{"armorDefenceAddLevel":3,"armorEffectEffectType":"ResistFreeze","armorStarNum":1,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"ArmorHead","specialStatus":22},"Armor_179_Head":{"armorDefenceAddLevel":4,"armorStarNum":1,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"ArmorHead"},"Armor_179_Lower":{"armorDefenceAddLevel":4,"armorStarNum":1,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"ArmorLower"},"Armor_179_Upper":{"armorDefenceAddLevel":4,"armorStarNum":1,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"ArmorUpper"},"Armor_180_Head":{"armorDefenceAddLevel":4,"armorEffectEffectType":"Quietness","armorStarNum":1,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"ArmorHead","specialStatus":17},"Armor_180_Lower":{"armorDefenceAddLevel":4,"armorEffectEffectType":"Quietness","armorStarNum":1,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"ArmorLower","specialStatus":17},"Armor_180_Upper":{"armorDefenceAddLevel":4,"armorEffectEffectType":"Quietness","armorStarNum":1,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"ArmorUpper","specialStatus":17},"Armor_181_Head":{"armorDefenceAddLevel":4,"armorEffectEffectType":"SwimSpeedAndResistAncient","armorStarNum":1,"itemBuyingPrice":500,"itemCreatingPrice":2000,"itemSellingPrice":125,"profile":"ArmorHead","specialStatus":29},"Armor_182_Head":{"armorDefenceAddLevel":4,"armorEffectEffectType":"ResistColdAndResistAncient","armorStarNum":1,"itemBuyingPrice":500,"itemCreatingPrice":2000,"itemSellingPrice":125,"profile":"ArmorHead","specialStatus":20},"Armor_183_Head":{"armorDefenceAddLevel":4,"armorEffectEffectType":"ResistBurnAndResistAncient","armorStarNum":1,"itemBuyingPrice":500,"itemCreatingPrice":2000,"itemSellingPrice":125,"profile":"ArmorHead","specialStatus":13},"Armor_184_Head":{"armorDefenceAddLevel":4,"armorEffectEffectType":"ResistElectricAndResistAncient","armorStarNum":1,"itemBuyingPrice":500,"itemCreatingPrice":2000,"itemSellingPrice":125,"profile":"ArmorHead","specialStatus":21},"Armor_185_Head":{"armorDefenceAddLevel":5,"armorEffectEffectType":"SwimSpeed","armorStarNum":1,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"ArmorHead","specialStatus":29},"Armor_185_Lower":{"armorDefenceAddLevel":5,"armorEffectEffectType":"SwimSpeed","armorStarNum":1,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"ArmorLower","specialStatus":29},"Armor_185_Upper":{"armorDefenceAddLevel":5,"armorEffectEffectType":"SwimSpeed","armorStarNum":1,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"ArmorUpper","specialStatus":29},"Armor_186_Head":{"armorDefenceAddLevel":7,"armorEffectEffectType":"SwimSpeedAndResistAncient","armorStarNum":2,"itemBuyingPrice":635,"itemCreatingPrice":3000,"itemSellingPrice":160,"profile":"ArmorHead","specialStatus":29},"Armor_187_Head":{"armorDefenceAddLevel":12,"armorEffectEffectType":"SwimSpeedAndResistAncient","armorStarNum":3,"itemBuyingPrice":1160,"itemCreatingPrice":4000,"itemSellingPrice":290,"profile":"ArmorHead","specialStatus":29},"Armor_188_Head":{"armorDefenceAddLevel":18,"armorEffectEffectType":"SwimSpeedAndResistAncient","armorStarNum":4,"itemBuyingPrice":2235,"itemCreatingPrice":5000,"itemSellingPrice":560,"profile":"ArmorHead","specialStatus":29},"Armor_189_Head":{"armorDefenceAddLevel":28,"armorEffectEffectType":"SwimSpeedAndResistAncient","armorStarNum":5,"itemBuyingPrice":2935,"itemCreatingPrice":6000,"itemSellingPrice":735,"profile":"ArmorHead","specialStatus":29},"Armor_190_Head":{"armorDefenceAddLevel":7,"armorEffectEffectType":"ResistColdAndResistAncient","armorStarNum":2,"itemBuyingPrice":635,"itemCreatingPrice":3000,"itemSellingPrice":160,"profile":"ArmorHead","specialStatus":20},"Armor_191_Head":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistColdAndResistAncient","armorStarNum":3,"itemBuyingPrice":1160,"itemCreatingPrice":4000,"itemSellingPrice":290,"profile":"ArmorHead","specialStatus":20},"Armor_192_Head":{"armorDefenceAddLevel":18,"armorEffectEffectType":"ResistColdAndResistAncient","armorStarNum":4,"itemBuyingPrice":2235,"itemCreatingPrice":5000,"itemSellingPrice":560,"profile":"ArmorHead","specialStatus":20},"Armor_193_Head":{"armorDefenceAddLevel":28,"armorEffectEffectType":"ResistColdAndResistAncient","armorStarNum":5,"itemBuyingPrice":2935,"itemCreatingPrice":6000,"itemSellingPrice":735,"profile":"ArmorHead","specialStatus":20},"Armor_194_Head":{"armorDefenceAddLevel":7,"armorEffectEffectType":"ResistBurnAndResistAncient","armorStarNum":2,"itemBuyingPrice":635,"itemCreatingPrice":3000,"itemSellingPrice":160,"profile":"ArmorHead","specialStatus":13},"Armor_195_Head":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistBurnAndResistAncient","armorStarNum":3,"itemBuyingPrice":1160,"itemCreatingPrice":4000,"itemSellingPrice":290,"profile":"ArmorHead","specialStatus":13},"Armor_196_Head":{"armorDefenceAddLevel":18,"armorEffectEffectType":"ResistBurnAndResistAncient","armorStarNum":4,"itemBuyingPrice":2235,"itemCreatingPrice":5000,"itemSellingPrice":560,"profile":"ArmorHead","specialStatus":13},"Armor_197_Head":{"armorDefenceAddLevel":28,"armorEffectEffectType":"ResistBurnAndResistAncient","armorStarNum":5,"itemBuyingPrice":2935,"itemCreatingPrice":6000,"itemSellingPrice":735,"profile":"ArmorHead","specialStatus":13},"Armor_198_Head":{"armorDefenceAddLevel":7,"armorEffectEffectType":"ResistElectricAndResistAncient","armorStarNum":2,"itemBuyingPrice":635,"itemCreatingPrice":3000,"itemSellingPrice":160,"profile":"ArmorHead","specialStatus":21},"Armor_199_Head":{"armorDefenceAddLevel":12,"armorEffectEffectType":"ResistElectricAndResistAncient","armorStarNum":3,"itemBuyingPrice":1160,"itemCreatingPrice":4000,"itemSellingPrice":290,"profile":"ArmorHead","specialStatus":21},"Armor_200_Head":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorHead"},"Armor_200_Lower":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorLower"},"Armor_200_Upper":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorUpper"},"Armor_201_Head":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":225,"profile":"ArmorHead"},"Armor_201_Lower":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":225,"profile":"ArmorLower"},"Armor_201_Upper":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":225,"profile":"ArmorUpper"},"Armor_202_Head":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":335,"profile":"ArmorHead"},"Armor_202_Lower":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":335,"profile":"ArmorLower"},"Armor_202_Upper":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":335,"profile":"ArmorUpper"},"Armor_203_Head":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":525,"profile":"ArmorHead"},"Armor_203_Lower":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":525,"profile":"ArmorLower"},"Armor_203_Upper":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":525,"profile":"ArmorUpper"},"Armor_204_Head":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":825,"profile":"ArmorHead"},"Armor_204_Lower":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":825,"profile":"ArmorLower"},"Armor_204_Upper":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":825,"profile":"ArmorUpper"},"Armor_205_Head":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorHead"},"Armor_205_Lower":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorLower"},"Armor_205_Upper":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorUpper"},"Armor_206_Head":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":245,"profile":"ArmorHead"},"Armor_206_Lower":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":245,"profile":"ArmorLower"},"Armor_206_Upper":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":245,"profile":"ArmorUpper"},"Armor_207_Head":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":395,"profile":"ArmorHead"},"Armor_207_Lower":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":395,"profile":"ArmorLower"},"Armor_207_Upper":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":395,"profile":"ArmorUpper"},"Armor_208_Head":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":620,"profile":"ArmorHead"},"Armor_208_Lower":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":620,"profile":"ArmorLower"},"Armor_208_Upper":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":620,"profile":"ArmorUpper"},"Armor_209_Head":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":995,"profile":"ArmorHead"},"Armor_209_Lower":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":995,"profile":"ArmorLower"},"Armor_209_Upper":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":995,"profile":"ArmorUpper"},"Armor_210_Head":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorHead"},"Armor_210_Lower":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorLower"},"Armor_210_Upper":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorUpper"},"Armor_211_Head":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":245,"profile":"ArmorHead"},"Armor_211_Lower":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":245,"profile":"ArmorLower"},"Armor_211_Upper":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":245,"profile":"ArmorUpper"},"Armor_212_Head":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":455,"profile":"ArmorHead"},"Armor_212_Lower":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":455,"profile":"ArmorLower"},"Armor_212_Upper":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":455,"profile":"ArmorUpper"},"Armor_213_Head":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":755,"profile":"ArmorHead"},"Armor_213_Lower":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":755,"profile":"ArmorLower"},"Armor_213_Upper":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":755,"profile":"ArmorUpper"},"Armor_214_Head":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":1280,"profile":"ArmorHead"},"Armor_214_Lower":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":1280,"profile":"ArmorLower"},"Armor_214_Upper":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":1280,"profile":"ArmorUpper"},"Armor_215_Head":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorHead"},"Armor_215_Lower":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorLower"},"Armor_215_Upper":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorUpper"},"Armor_216_Head":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":265,"profile":"ArmorHead"},"Armor_216_Lower":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":265,"profile":"ArmorLower"},"Armor_216_Upper":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":265,"profile":"ArmorUpper"},"Armor_217_Head":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":535,"profile":"ArmorHead"},"Armor_217_Lower":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":535,"profile":"ArmorLower"},"Armor_217_Upper":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":535,"profile":"ArmorUpper"},"Armor_218_Head":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":935,"profile":"ArmorHead"},"Armor_218_Lower":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":935,"profile":"ArmorLower"},"Armor_218_Upper":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":935,"profile":"ArmorUpper"},"Armor_219_Head":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":1660,"profile":"ArmorHead"},"Armor_219_Lower":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":1660,"profile":"ArmorLower"},"Armor_219_Upper":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":1660,"profile":"ArmorUpper"},"Armor_220_Head":{"armorDefenceAddLevel":2,"armorEffectEffectType":"Quietness","armorStarNum":1,"itemBuyingPrice":400,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorHead","specialStatus":17},"Armor_220_Head_B":{"armorDefenceAddLevel":2,"armorEffectEffectType":"Quietness","armorStarNum":1,"itemBuyingPrice":400,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorHead","specialStatus":17},"Armor_221_Head":{"armorDefenceAddLevel":4,"armorEffectEffectType":"Quietness","armorStarNum":2,"itemBuyingPrice":400,"itemCreatingPrice":0,"itemSellingPrice":210,"profile":"ArmorHead","specialStatus":17},"Armor_221_Head_B":{"armorDefenceAddLevel":4,"armorEffectEffectType":"Quietness","armorStarNum":2,"itemBuyingPrice":400,"itemCreatingPrice":0,"itemSellingPrice":210,"profile":"ArmorHead","specialStatus":17},"Armor_222_Head":{"armorDefenceAddLevel":6,"armorEffectEffectType":"Quietness","armorStarNum":3,"itemBuyingPrice":400,"itemCreatingPrice":0,"itemSellingPrice":305,"profile":"ArmorHead","specialStatus":17},"Armor_222_Head_B":{"armorDefenceAddLevel":6,"armorEffectEffectType":"Quietness","armorStarNum":3,"itemBuyingPrice":400,"itemCreatingPrice":0,"itemSellingPrice":305,"profile":"ArmorHead","specialStatus":17},"Armor_223_Head":{"armorDefenceAddLevel":9,"armorEffectEffectType":"Quietness","armorStarNum":4,"itemBuyingPrice":400,"itemCreatingPrice":0,"itemSellingPrice":410,"profile":"ArmorHead","specialStatus":17},"Armor_223_Head_B":{"armorDefenceAddLevel":9,"armorEffectEffectType":"Quietness","armorStarNum":4,"itemBuyingPrice":400,"itemCreatingPrice":0,"itemSellingPrice":410,"profile":"ArmorHead","specialStatus":17},"Armor_224_Head":{"armorDefenceAddLevel":16,"armorEffectEffectType":"Quietness","armorStarNum":5,"itemBuyingPrice":400,"itemCreatingPrice":0,"itemSellingPrice":525,"profile":"ArmorHead","specialStatus":17},"Armor_224_Head_B":{"armorDefenceAddLevel":16,"armorEffectEffectType":"Quietness","armorStarNum":5,"itemBuyingPrice":400,"itemCreatingPrice":0,"itemSellingPrice":525,"profile":"ArmorHead","specialStatus":17},"Armor_225_Head":{"armorDefenceAddLevel":3,"armorEffectEffectType":"AttackUp","armorStarNum":1,"itemBuyingPrice":500,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorHead","specialStatus":8},"Armor_225_Lower":{"armorDefenceAddLevel":3,"armorEffectEffectType":"AttackUp","armorStarNum":1,"itemBuyingPrice":500,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorLower","specialStatus":8},"Armor_225_Upper":{"armorDefenceAddLevel":3,"armorEffectEffectType":"AttackUp","armorStarNum":1,"itemBuyingPrice":500,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorUpper","specialStatus":8},"Armor_226_Head":{"armorDefenceAddLevel":5,"armorEffectEffectType":"AttackUp","armorStarNum":2,"itemBuyingPrice":750,"itemCreatingPrice":0,"itemSellingPrice":190,"profile":"ArmorHead","specialStatus":8},"Armor_226_Lower":{"armorDefenceAddLevel":5,"armorEffectEffectType":"AttackUp","armorStarNum":2,"itemBuyingPrice":750,"itemCreatingPrice":0,"itemSellingPrice":190,"profile":"ArmorLower","specialStatus":8},"Armor_226_Upper":{"armorDefenceAddLevel":5,"armorEffectEffectType":"AttackUp","armorStarNum":2,"itemBuyingPrice":750,"itemCreatingPrice":0,"itemSellingPrice":190,"profile":"ArmorUpper","specialStatus":8},"Armor_227_Head":{"armorDefenceAddLevel":8,"armorEffectEffectType":"AttackUp","armorStarNum":3,"itemBuyingPrice":1105,"itemCreatingPrice":0,"itemSellingPrice":275,"profile":"ArmorHead","specialStatus":8},"Armor_227_Lower":{"armorDefenceAddLevel":8,"armorEffectEffectType":"AttackUp","armorStarNum":3,"itemBuyingPrice":1105,"itemCreatingPrice":0,"itemSellingPrice":275,"profile":"ArmorLower","specialStatus":8},"Armor_227_Upper":{"armorDefenceAddLevel":8,"armorEffectEffectType":"AttackUp","armorStarNum":3,"itemBuyingPrice":1105,"itemCreatingPrice":0,"itemSellingPrice":275,"profile":"ArmorUpper","specialStatus":8},"Armor_228_Head":{"armorDefenceAddLevel":12,"armorEffectEffectType":"AttackUp","armorStarNum":4,"itemBuyingPrice":1515,"itemCreatingPrice":0,"itemSellingPrice":380,"profile":"ArmorHead","specialStatus":8},"Armor_228_Lower":{"armorDefenceAddLevel":12,"armorEffectEffectType":"AttackUp","armorStarNum":4,"itemBuyingPrice":1515,"itemCreatingPrice":0,"itemSellingPrice":380,"profile":"ArmorLower","specialStatus":8},"Armor_228_Upper":{"armorDefenceAddLevel":12,"armorEffectEffectType":"AttackUp","armorStarNum":4,"itemBuyingPrice":1515,"itemCreatingPrice":0,"itemSellingPrice":380,"profile":"ArmorUpper","specialStatus":8},"Armor_229_Head":{"armorDefenceAddLevel":20,"armorEffectEffectType":"AttackUp","armorStarNum":5,"itemBuyingPrice":2215,"itemCreatingPrice":0,"itemSellingPrice":555,"profile":"ArmorHead","specialStatus":8},"Armor_229_Lower":{"armorDefenceAddLevel":20,"armorEffectEffectType":"AttackUp","armorStarNum":5,"itemBuyingPrice":2215,"itemCreatingPrice":0,"itemSellingPrice":555,"profile":"ArmorLower","specialStatus":8},"Armor_229_Upper":{"armorDefenceAddLevel":20,"armorEffectEffectType":"AttackUp","armorStarNum":5,"itemBuyingPrice":2215,"itemCreatingPrice":0,"itemSellingPrice":555,"profile":"ArmorUpper","specialStatus":8},"Armor_230_Head":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorHead"},"Armor_230_Lower":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorLower"},"Armor_230_Upper":{"armorDefenceAddLevel":3,"armorStarNum":1,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":125,"profile":"ArmorUpper"},"Armor_231_Head":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":255,"profile":"ArmorHead"},"Armor_231_Lower":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":255,"profile":"ArmorLower"},"Armor_231_Upper":{"armorDefenceAddLevel":5,"armorStarNum":2,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":255,"profile":"ArmorUpper"},"Armor_232_Head":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":485,"profile":"ArmorHead"},"Armor_232_Lower":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":485,"profile":"ArmorLower"},"Armor_232_Upper":{"armorDefenceAddLevel":8,"armorStarNum":3,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":485,"profile":"ArmorUpper"},"Armor_233_Head":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":825,"profile":"ArmorHead"},"Armor_233_Lower":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":825,"profile":"ArmorLower"},"Armor_233_Upper":{"armorDefenceAddLevel":12,"armorStarNum":4,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":825,"profile":"ArmorUpper"},"Armor_234_Head":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":1425,"profile":"ArmorHead"},"Armor_234_Lower":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":1425,"profile":"ArmorLower"},"Armor_234_Upper":{"armorDefenceAddLevel":20,"armorStarNum":5,"itemBuyingPrice":60,"itemCreatingPrice":0,"itemSellingPrice":1425,"profile":"ArmorUpper"},"ArrowRainChild":{"attackPower":16,"profile":"Bullet"},"AssassinIronBall":{"attackPower":16,"profile":"Bullet"},"AssassinRockBall":{"attackPower":12,"profile":"Bullet"},"BeamosBeam":{"attackPower":12,"profile":"LineBeam"},"BeeHome":{"canStack":true,"generalLife":1,"itemBuyingPrice":40,"itemSellingPrice":10,"itemStainColor":10,"profile":"CapturedActor"},"BombArrow_A":{"attackPower":40,"canStack":true,"cannotSell":true,"itemBuyingPrice":50,"itemSellingPrice":1,"profile":"Bullet"},"BrightArrow":{"attackPower":100,"cannotSell":true,"itemSellingPrice":1,"profile":"Bullet"},"BrightArrowTP":{"attackPower":100,"cannotSell":true,"itemSellingPrice":1,"profile":"Bullet"},"BrokenSnowBall":{"attackPower":1,"profile":"MapDynamicActive"},"CurseGanonBeam":{"attackPower":40,"profile":"Beam"},"DLC_RockBall":{"attackPower":12,"profile":"MapDynamicActive"},"DLC_WallSpike132":{"attackPower":4,"profile":"MapConstActive"},"DLC_WallSpikeMovableBox_A":{"attackPower":4,"profile":"MapDynamicActive"},"DLC_WallSpikeMovableBox_B":{"attackPower":4,"profile":"MapDynamicActive"},"DgnObj_DLC_IbutsuEXD_FirePillar_A_01":{"attackPower":4,"profile":"MapDynamicActive"},"DgnObj_DLC_IbutsuEXD_FirePillar_A_02":{"attackPower":4,"profile":"MapDynamicActive"},"DgnObj_DLC_IbutsuExD_WallSpike_A_01":{"attackPower":4,"profile":"MapConstActive"},"DgnObj_DLC_IbutsuEx_C_Propeller_A_01":{"attackPower":5,"profile":"MapDynamicActive"},"DgnObj_DLC_IbutsuShaft_A_05":{"attackPower":5,"profile":"MapDynamicActive"},"DgnObj_DLC_WallSpikeMovable":{"attackPower":4,"profile":"MapDynamicActive"},"DgnObj_DLC_Weapon_Sword_502":{"attackPower":1,"attackRange":1.6,"generalLife":40,"itemBuyingPrice":1,"itemSellingPrice":1,"profile":"WeaponSmallSword"},"DgnObj_FirePillar":{"attackPower":4,"profile":"MapDynamicActive"},"DgnObj_FirePillar_B":{"attackPower":4,"profile":"MapDynamicActive"},"DgnObj_FirePillar_C":{"attackPower":4,"profile":"MapDynamicActive"},"DgnObj_FirePillar_C_01":{"attackPower":4,"profile":"MapDynamicActive"},"DgnObj_FirePillar_C_02":{"attackPower":4,"profile":"MapDynamicActive"},"DgnObj_FirePillar_C_03":{"attackPower":4,"profile":"MapDynamicActive"},"DgnObj_FirePillar_C_04":{"attackPower":4,"profile":"MapDynamicActive"},"DgnObj_FirePillar_C_Physics":{"attackPower":4,"profile":"MapDynamicActive"},"DgnObj_FloorSpike_A_01":{"attackPower":4,"profile":"MapConstActive"},"DgnObj_SliderSpike_A":{"attackPower":4,"profile":"MapDynamicActive"},"DgnObj_SpikeBall_028":{"attackPower":12,"profile":"MapDynamicActive"},"DgnObj_SpikeBall_051":{"attackPower":12,"profile":"MapDynamicActive"},"DgnObj_SpikeBall_A":{"attackPower":12,"profile":"MapDynamicActive"},"DgnObj_SpikeBall_B":{"attackPower":12,"profile":"MapDynamicActive"},"DgnObj_SpikeBall_NoHitRope":{"attackPower":12,"profile":"MapDynamicActive"},"DgnObj_WallSpike_067":{"attackPower":4,"profile":"MapConstActive"},"DgnObj_WallSpike_067_None":{"attackPower":4,"profile":"MapConstActive"},"DgnObj_WallSpike_B_01":{"attackPower":4,"profile":"MapConstActive"},"Dm_GameROMMotorcycle":{"attackPower":5,"attackRange":1.0,"generalLife":1,"profile":"DemoNPC"},"DragonFlameBall":{"attackPower":24,"attackRange":30.0,"profile":"Bullet"},"DragonIceBall":{"attackPower":50,"attackRange":30.0,"profile":"Bullet"},"DragonThunderBall":{"attackPower":24,"attackRange":30.0,"profile":"Bullet"},"ElectricArrow":{"canStack":true,"cannotSell":true,"itemBuyingPrice":20,"itemSellingPrice":1,"profile":"Bullet"},"ElectricWaterBall":{"attackPower":40,"profile":"Bullet"},"Enemy_Assassin_Azito_Middle":{"attackPower":10,"attackRange":20.0,"generalLife":600,"profile":"Enemy"},"Enemy_Assassin_Azito_Middle_DLC2":{"attackPower":10,"attackRange":20.0,"generalLife":600,"profile":"Enemy"},"Enemy_Assassin_Middle":{"attackPower":10,"attackRange":20.0,"generalLife":400,"profile":"Enemy"},"Enemy_Assassin_Middle_Quest":{"attackPower":10,"attackRange":20.0,"generalLife":400,"profile":"Enemy"},"Enemy_Bokoblin_Bone_Junior":{"attackPower":4,"attackRange":1.0,"generalLife":1,"profile":"Enemy"},"Enemy_Bokoblin_Bone_Junior_AllDay":{"attackPower":4,"attackRange":1.0,"generalLife":1,"profile":"Enemy"},"Enemy_Bokoblin_Guard_Junior_Ambush":{"attackPower":4,"attackRange":1.0,"generalLife":13,"profile":"Enemy"},"Enemy_Bokoblin_Guard_Junior_TreeHouseTop":{"attackPower":4,"attackRange":1.0,"generalLife":13,"profile":"Enemy"},"Enemy_Bokoblin_Junior":{"attackPower":4,"attackRange":1.0,"generalLife":13,"profile":"Enemy"},"Enemy_Chuchu_Electric_Junior":{"attackPower":2,"attackRange":0.5,"generalLife":12,"profile":"GelEnemy"},"Enemy_Chuchu_Electric_Middle":{"attackPower":2,"attackRange":0.5,"generalLife":20,"profile":"GelEnemy"},"Enemy_Chuchu_Electric_Senior":{"attackPower":2,"attackRange":0.5,"generalLife":48,"profile":"GelEnemy"},"Enemy_Chuchu_Fire_Junior":{"attackPower":2,"attackRange":0.5,"generalLife":12,"profile":"GelEnemy"},"Enemy_Chuchu_Fire_Middle":{"attackPower":2,"attackRange":0.5,"generalLife":20,"profile":"GelEnemy"},"Enemy_Chuchu_Fire_Senior":{"attackPower":2,"attackRange":0.5,"generalLife":48,"profile":"GelEnemy"},"Enemy_Chuchu_Ice_Junior":{"attackPower":2,"attackRange":0.5,"generalLife":12,"profile":"GelEnemy"},"Enemy_Chuchu_Ice_Middle":{"attackPower":2,"attackRange":0.5,"generalLife":20,"profile":"GelEnemy"},"Enemy_Chuchu_Ice_Senior":{"attackPower":2,"attackRange":0.5,"generalLife":48,"profile":"GelEnemy"},"Enemy_Chuchu_Junior":{"attackPower":2,"attackRange":0.5,"generalLife":3,"profile":"GelEnemy"},"Enemy_Chuchu_Middle":{"attackPower":2,"attackRange":0.5,"generalLife":20,"profile":"GelEnemy"},"Enemy_Chuchu_Senior":{"attackPower":2,"attackRange":0.5,"generalLife":48,"profile":"GelEnemy"},"Enemy_Ganon":{"attackPower":60,"attackRange":100.0,"generalLife":8000,"profile":"LastBoss"},"Enemy_Ganon_Lsword_Weapon":{"attackPower":1,"attackRange":1.6,"generalLife":35,"profile":"WeaponLargeSword"},"Enemy_Ganon_Sword_Weapon_FL":{"attackPower":1,"attackRange":1.6,"generalLife":35,"itemBuyingPrice":20,"itemSellingPrice":5,"profile":"WeaponSmallSword"},"Enemy_Ganon_Sword_Weapon_FR":{"attackPower":1,"attackRange":1.6,"generalLife":35,"itemBuyingPrice":20,"itemSellingPrice":5,"profile":"WeaponSmallSword"},"Enemy_Ganon_Sword_Weapon_MR":{"attackPower":1,"attackRange":1.6,"generalLife":35,"itemBuyingPrice":20,"itemSellingPrice":5,"profile":"WeaponSmallSword"},"Enemy_Giant_Bone":{"attackPower":60,"attackRange":7.0,"generalLife":1000,"profile":"GiantEnemy"},"Enemy_Giant_Bone_AllDay":{"attackPower":60,"attackRange":7.0,"generalLife":1000,"profile":"GiantEnemy"},"Enemy_Giant_Bone_Arm_L":{"attackPower":16,"profile":"Bullet"},"Enemy_Giant_Bone_Chin":{"attackPower":12,"profile":"Bullet"},"Enemy_Giant_Bone_Rib":{"attackPower":12,"profile":"Bullet"},"Enemy_Giant_Junior":{"attackPower":24,"attackRange":7.0,"generalLife":600,"profile":"GiantEnemy"},"Enemy_Giant_Middle":{"attackPower":48,"attackRange":7.0,"generalLife":800,"profile":"GiantEnemy"},"Enemy_Giant_Senior":{"attackPower":72,"attackRange":7.0,"generalLife":1000,"profile":"GiantEnemy"},"Enemy_Golem_Fire":{"attackPower":10,"attackRange":10.0,"generalLife":800,"profile":"GiantEnemy"},"Enemy_Golem_Fire_Lower_Arm_L":{"attackPower":8,"profile":"Bullet"},"Enemy_Golem_Fire_Lower_Arm_R":{"attackPower":8,"profile":"Bullet"},"Enemy_Golem_Fire_R":{"attackPower":10,"attackRange":10.0,"generalLife":1600,"profile":"GiantEnemy"},"Enemy_Golem_Fire_R_Lower_Arm_L":{"attackPower":60,"profile":"Bullet"},"Enemy_Golem_Fire_R_Lower_Arm_R":{"attackPower":60,"profile":"Bullet"},"Enemy_Golem_Fire_R_Upper_Arm_L":{"attackPower":60,"profile":"Bullet"},"Enemy_Golem_Fire_R_Upper_Arm_R":{"attackPower":60,"profile":"Bullet"},"Enemy_Golem_Fire_Upper_Arm_L":{"attackPower":8,"profile":"Bullet"},"Enemy_Golem_Fire_Upper_Arm_R":{"attackPower":8,"profile":"Bullet"},"Enemy_Golem_Ice":{"attackPower":10,"attackRange":10.0,"generalLife":800,"profile":"GiantEnemy"},"Enemy_Golem_Ice_Lower_Arm_L":{"attackPower":8,"profile":"Bullet"},"Enemy_Golem_Ice_Lower_Arm_R":{"attackPower":8,"profile":"Bullet"},"Enemy_Golem_Ice_Upper_Arm_L":{"attackPower":8,"profile":"Bullet"},"Enemy_Golem_Ice_Upper_Arm_R":{"attackPower":8,"profile":"Bullet"},"Enemy_Golem_Junior":{"attackPower":10,"attackRange":10.0,"generalLife":300,"profile":"GiantEnemy"},"Enemy_Golem_Little":{"attackPower":10,"attackRange":1.5,"generalLife":20,"profile":"Enemy"},"Enemy_Golem_Little_Fire":{"attackPower":10,"attackRange":1.5,"generalLife":20,"profile":"Enemy"},"Enemy_Golem_Little_Ice":{"attackPower":10,"attackRange":1.5,"generalLife":20,"profile":"Enemy"},"Enemy_Golem_Lower_Arm_L":{"attackPower":8,"profile":"Bullet"},"Enemy_Golem_Lower_Arm_R":{"attackPower":8,"profile":"Bullet"},"Enemy_Golem_Middle":{"attackPower":10,"attackRange":10.0,"generalLife":600,"profile":"GiantEnemy"},"Enemy_Golem_Senior":{"attackPower":10,"attackRange":10.0,"generalLife":900,"profile":"GiantEnemy"},"Enemy_Golem_Upper_Arm_L":{"attackPower":8,"profile":"Bullet"},"Enemy_Golem_Upper_Arm_R":{"attackPower":8,"profile":"Bullet"},"Enemy_Lynel_Junior":{"attackPower":15,"attackRange":5.0,"generalLife":2000,"profile":"Enemy"},"Enemy_Lynel_Junior_Mountain":{"attackPower":15,"attackRange":5.0,"generalLife":2000,"profile":"Enemy"},"Enemy_Octarock":{"attackPower":10,"attackRange":35.0,"generalLife":8,"profile":"Enemy"},"Enemy_Octarock_Desert":{"attackPower":10,"attackRange":35.0,"generalLife":8,"profile":"Enemy"},"Enemy_Octarock_Forest":{"attackPower":10,"attackRange":35.0,"generalLife":8,"profile":"Enemy"},"Enemy_Octarock_Snow":{"attackPower":10,"attackRange":35.0,"generalLife":8,"profile":"Enemy"},"Enemy_Octarock_Stone":{"attackPower":10,"attackRange":35.0,"generalLife":8,"profile":"Enemy"},"Enemy_SiteBoss_Lsword_Weapon":{"attackPower":1,"attackRange":1.6,"generalLife":35,"profile":"WeaponLargeSword"},"Enemy_SiteBoss_Spear_Weapon":{"attackPower":1,"attackRange":3.0,"profile":"WeaponSpear"},"Enemy_SiteBoss_Sword_Weapon":{"attackPower":1,"attackRange":1.6,"generalLife":35,"profile":"WeaponSmallSword"},"Explode":{"attackPower":10,"profile":"Bullet"},"FireArrow":{"canStack":true,"cannotSell":true,"itemBuyingPrice":20,"itemSellingPrice":1,"profile":"Bullet"},"FireRodLv1Fire":{"attackPower":24,"attackRange":30.0,"profile":"Bullet"},"FireRodLv2Fire":{"attackPower":24,"attackRange":30.0,"profile":"Bullet"},"FireRodLv2FireChild":{"attackPower":24,"attackRange":30.0,"profile":"Bullet"},"FldObj_GoronCannonBall_A_01":{"attackPower":1000,"profile":"MapDynamicActive"},"FldObj_GoronCannonBall_YunBo":{"attackPower":1000,"profile":"MapDynamicActive"},"FldObj_VolcanicBomb_A_01":{"attackPower":20,"profile":"MapDynamicActive"},"FldObj_VolcanicBomb_Field":{"attackPower":20,"profile":"MapDynamicActive"},"GaleArrow":{"attackPower":24,"profile":"Bullet"},"GameROMMotorcycle":{"attackPower":5,"attackRange":1.0,"generalLife":1,"profile":"Motorcycle"},"GameRomHorse":{"attackPower":5,"attackRange":1.0,"generalLife":220,"profile":"Horse"},"GameRomHorse00L":{"attackPower":10,"attackRange":1.0,"generalLife":300,"profile":"Horse"},"GameRomHorse00S":{"attackPower":5,"attackRange":1.0,"generalLife":120,"profile":"Horse"},"GameRomHorse01":{"attackPower":5,"attackRange":1.0,"generalLife":130,"profile":"Horse"},"GameRomHorse02":{"attackPower":5,"attackRange":1.0,"generalLife":130,"profile":"Horse"},"GameRomHorse03":{"attackPower":5,"attackRange":1.0,"generalLife":80,"profile":"Horse"},"GameRomHorse04":{"attackPower":5,"attackRange":1.0,"generalLife":130,"profile":"Horse"},"GameRomHorse05":{"attackPower":5,"attackRange":1.0,"generalLife":80,"profile":"Horse"},"GameRomHorse06":{"attackPower":5,"attackRange":1.0,"generalLife":80,"profile":"Horse"},"GameRomHorse07":{"attackPower":5,"attackRange":1.0,"generalLife":80,"profile":"Horse"},"GameRomHorse08":{"attackPower":5,"attackRange":1.0,"generalLife":160,"profile":"Horse"},"GameRomHorse09":{"attackPower":5,"attackRange":1.0,"generalLife":240,"profile":"Horse"},"GameRomHorse10":{"attackPower":5,"attackRange":1.0,"generalLife":80,"profile":"Horse"},"GameRomHorse11":{"attackPower":5,"attackRange":1.0,"generalLife":130,"profile":"Horse"},"GameRomHorse12":{"attackPower":5,"attackRange":1.0,"generalLife":250,"profile":"Horse"},"GameRomHorse13":{"attackPower":5,"attackRange":1.0,"generalLife":80,"profile":"Horse"},"GameRomHorse14":{"attackPower":5,"attackRange":1.0,"generalLife":80,"profile":"Horse"},"GameRomHorse15":{"attackPower":5,"attackRange":1.0,"generalLife":240,"profile":"Horse"},"GameRomHorse16":{"attackPower":5,"attackRange":1.0,"generalLife":150,"profile":"Horse"},"GameRomHorse17":{"attackPower":5,"attackRange":1.0,"generalLife":110,"profile":"Horse"},"GameRomHorse18":{"attackPower":5,"attackRange":1.0,"generalLife":110,"profile":"Horse"},"GameRomHorse19":{"attackPower":5,"attackRange":1.0,"generalLife":300,"profile":"Horse"},"GameRomHorse20":{"attackPower":5,"attackRange":1.0,"generalLife":220,"profile":"Horse"},"GameRomHorse21":{"attackPower":5,"attackRange":1.0,"generalLife":150,"profile":"Horse"},"GameRomHorse22":{"attackPower":5,"attackRange":1.0,"generalLife":150,"profile":"Horse"},"GameRomHorse23":{"attackPower":5,"attackRange":1.0,"profile":"Horse"},"GameRomHorseBone":{"attackPower":5,"attackRange":1.0,"profile":"Horse"},"GameRomHorseBone_AllDay":{"attackPower":5,"attackRange":1.0,"profile":"Horse"},"GameRomHorseEpona":{"attackPower":5,"attackRange":1.0,"generalLife":220,"profile":"Horse"},"GameRomHorseNushi":{"attackPower":5,"attackRange":1.0,"profile":"Horse"},"GameRomHorseReins_01":{"cannotSell":true,"profile":"HorseReins"},"GameRomHorseReins_02":{"cannotSell":true,"profile":"HorseReins"},"GameRomHorseReins_03":{"cannotSell":true,"profile":"HorseReins"},"GameRomHorseReins_04":{"cannotSell":true,"profile":"HorseReins"},"GameRomHorseReins_05":{"cannotSell":true,"profile":"HorseReins"},"GameRomHorseReins_10":{"cannotSell":true,"profile":"HorseReins"},"GameRomHorseSaddle_01":{"cannotSell":true,"profile":"HorseSaddle"},"GameRomHorseSaddle_02":{"cannotSell":true,"profile":"HorseSaddle"},"GameRomHorseSaddle_03":{"cannotSell":true,"profile":"HorseSaddle"},"GameRomHorseSaddle_04":{"cannotSell":true,"profile":"HorseSaddle"},"GameRomHorseSaddle_05":{"cannotSell":true,"profile":"HorseSaddle"},"GameRomHorseSaddle_10":{"cannotSell":true,"profile":"HorseSaddle"},"GameRomHorseZelda":{"attackPower":5,"attackRange":1.0,"generalLife":220,"profile":"Horse"},"GanonBeam":{"attackPower":40,"profile":"Beam"},"GanonBeastBeam":{"attackPower":72,"profile":"LineBeam"},"GanonFlameBall":{"attackPower":24,"attackRange":30.0,"profile":"Bullet"},"GanonIceBullet":{"attackPower":24,"profile":"Bullet"},"GanonNormalArrow":{"attackPower":16,"profile":"Bullet"},"GanonPillarOfFlame":{"attackPower":24,"attackRange":30.0,"profile":"Bullet"},"GanonSeaOfFlame":{"attackPower":24,"attackRange":30.0,"profile":"Bullet"},"GanonSpearForThrowing":{"attackPower":16,"profile":"Bullet"},"GanonThunder":{"attackPower":24,"profile":"Bullet"},"GanonTornado":{"attackPower":24,"profile":"Bullet"},"Get_TwnObj_DLC_MemorialPicture_A_01":{"cannotSell":true,"profile":"Item"},"Giant_Bomb_Weapon":{"attackPower":30,"profile":"Bullet"},"Giant_Rock_Weapon":{"attackPower":8,"profile":"Bullet"},"GuardianBeam":{"attackPower":52,"profile":"Beam"},"GuardianBeam_RemainsWind":{"attackPower":52,"profile":"Beam"},"GuardianMiniBeam":{"attackPower":1,"attackRange":100.0,"profile":"Beam"},"GuardianMiniBeam_Junior":{"attackPower":10,"attackRange":100.0,"profile":"Beam"},"GuardianMiniBeam_Middle":{"attackPower":15,"attackRange":100.0,"profile":"Beam"},"GuardianMiniBeam_Senior":{"attackPower":20,"attackRange":100.0,"profile":"Beam"},"GuardianMiniFinalBeam":{"attackPower":1,"profile":"Beam"},"GuardianMiniFinalBeam_Junior":{"attackPower":20,"profile":"Beam"},"GuardianMiniFinalBeam_Middle":{"attackPower":30,"profile":"Beam"},"GuardianMiniFinalBeam_Senior":{"attackPower":40,"profile":"Beam"},"GuardianMiniLineBeam":{"attackPower":1,"profile":"LineBeam"},"GuardianMiniLineBeam_Junior":{"attackPower":16,"profile":"LineBeam"},"GuardianMiniLineBeam_Middle":{"attackPower":24,"profile":"LineBeam"},"GuardianMiniLineBeam_Senior":{"attackPower":32,"profile":"LineBeam"},"IceArrow":{"canStack":true,"cannotSell":true,"itemBuyingPrice":20,"itemSellingPrice":1,"profile":"Bullet"},"IceRodLv1Ice":{"attackPower":50,"attackRange":30.0,"profile":"Bullet"},"IceRodLv2Ice":{"attackPower":50,"attackRange":30.0,"profile":"Bullet"},"Item_Boiled_01":{"canStack":true,"itemBuyingPrice":20,"itemSellingPrice":5,"profile":"Item"},"Item_ChilledFish_01":{"canStack":true,"itemBuyingPrice":32,"itemSellingPrice":14,"profile":"Item"},"Item_ChilledFish_02":{"canStack":true,"itemBuyingPrice":40,"itemSellingPrice":18,"profile":"Item"},"Item_ChilledFish_03":{"canStack":true,"itemBuyingPrice":25,"itemSellingPrice":10,"profile":"Item"},"Item_ChilledFish_04":{"canStack":true,"itemBuyingPrice":40,"itemSellingPrice":18,"profile":"Item"},"Item_ChilledFish_05":{"canStack":true,"itemBuyingPrice":40,"itemSellingPrice":18,"profile":"Item"},"Item_ChilledFish_06":{"canStack":true,"itemBuyingPrice":32,"itemSellingPrice":14,"profile":"Item"},"Item_ChilledFish_07":{"canStack":true,"itemBuyingPrice":32,"itemSellingPrice":14,"profile":"Item"},"Item_ChilledFish_08":{"canStack":true,"itemBuyingPrice":25,"itemSellingPrice":10,"profile":"Item"},"Item_ChilledFish_09":{"canStack":true,"itemBuyingPrice":40,"itemSellingPrice":18,"profile":"Item"},"Item_Chilled_01":{"canStack":true,"itemBuyingPrice":35,"itemSellingPrice":15,"profile":"Item"},"Item_Chilled_02":{"canStack":true,"itemBuyingPrice":60,"itemSellingPrice":28,"profile":"Item"},"Item_Chilled_03":{"canStack":true,"itemBuyingPrice":150,"itemSellingPrice":40,"profile":"Item"},"Item_Chilled_04":{"canStack":true,"itemBuyingPrice":35,"itemSellingPrice":15,"profile":"Item"},"Item_Chilled_05":{"canStack":true,"itemBuyingPrice":60,"itemSellingPrice":28,"profile":"Item"},"Item_Chilled_06":{"canStack":true,"itemBuyingPrice":150,"itemSellingPrice":40,"profile":"Item"},"Item_Cook_A_01":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_A_02":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_A_03":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_A_04":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_A_05":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_A_07":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_A_08":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_A_09":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_A_10":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_A_11":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_A_12":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_A_13":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_A_14":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_B_01":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_B_02":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_B_03":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_B_04":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_B_05":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_B_06":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_B_11":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_B_12":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_B_13":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_B_14":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_B_15":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_B_16":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_B_17":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_B_18":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_B_19":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_B_20":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_B_21":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_B_22":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_B_23":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_C_01":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_C_02":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_C_05":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_C_06":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_C_07":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_C_08":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_C_11":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_C_12":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_C_13":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_C_14":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_C_15":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_C_16":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_C_17":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_C_17_00":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_D_01":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_D_02":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_D_03":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_D_04":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_D_05":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_D_06":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_D_07":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_D_08":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_D_09":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_D_10":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_E_01":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_E_02":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_E_03":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_E_04":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_F_01":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_F_02":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_F_03":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_F_04":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_G_02":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_G_03":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_G_04":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_G_05":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_G_06":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_G_07":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_G_08":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_G_09":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_G_10":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_G_11":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_G_12":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_G_13":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_G_14":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_G_15":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_G_16":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_G_17":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_H_01":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_H_02":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_H_03":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_I_01":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_I_02":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_I_03":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_I_04":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_I_05":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_I_06":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_I_07":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_I_08":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_I_09":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_I_10":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_I_11":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_I_12":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_I_13":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_I_14":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_I_15":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_I_16":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_I_17":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_J_01":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_J_02":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_J_03":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_J_04":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_J_05":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_J_06":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_J_07":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_J_08":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_J_09":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_K_01":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_K_02":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_K_03":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_K_04":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_K_05":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_K_06":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_K_07":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_K_08":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_K_09":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_L_01":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_L_02":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_L_03":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_L_04":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_L_05":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_M_01":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_N_01":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_N_02":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_N_03":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_N_04":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_O_01":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_O_02":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_P_01":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_P_02":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_P_03":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_P_04":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Cook_P_05":{"itemSellingPrice":1,"profile":"CookResult"},"Item_Enemy_00":{"canStack":true,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":15,"profile":"Item"},"Item_Enemy_01":{"canStack":true,"itemBuyingPrice":32,"itemSellingPrice":8,"itemStainColor":13,"profile":"Item"},"Item_Enemy_02":{"canStack":true,"itemBuyingPrice":80,"itemSellingPrice":20,"itemStainColor":6,"profile":"Item"},"Item_Enemy_03":{"canStack":true,"itemBuyingPrice":40,"itemSellingPrice":10,"itemStainColor":15,"profile":"Item"},"Item_Enemy_04":{"canStack":true,"itemBuyingPrice":60,"itemSellingPrice":15,"itemStainColor":15,"profile":"Item"},"Item_Enemy_05":{"canStack":true,"itemBuyingPrice":112,"itemSellingPrice":28,"itemStainColor":7,"profile":"Item"},"Item_Enemy_06":{"canStack":true,"itemBuyingPrice":20,"itemSellingPrice":5,"itemStainColor":15,"profile":"Item"},"Item_Enemy_07":{"canStack":true,"itemBuyingPrice":45,"itemSellingPrice":12,"itemStainColor":15,"profile":"Item"},"Item_Enemy_08":{"canStack":true,"itemBuyingPrice":100,"itemSellingPrice":25,"itemStainColor":8,"profile":"Item"},"Item_Enemy_12":{"canStack":true,"itemBuyingPrice":160,"itemSellingPrice":40,"itemStainColor":4,"profile":"Item"},"Item_Enemy_13":{"canStack":true,"itemBuyingPrice":200,"itemSellingPrice":50,"itemStainColor":5,"profile":"Item"},"Item_Enemy_14":{"canStack":true,"itemBuyingPrice":800,"itemSellingPrice":200,"itemStainColor":12,"profile":"Item"},"Item_Enemy_15":{"canStack":true,"generalLife":1,"itemBuyingPrice":40,"itemSellingPrice":10,"itemStainColor":2,"profile":"Item"},"Item_Enemy_16":{"canStack":true,"generalLife":1,"itemBuyingPrice":40,"itemSellingPrice":10,"itemStainColor":3,"profile":"Item"},"Item_Enemy_17":{"canStack":true,"generalLife":1,"itemBuyingPrice":40,"itemSellingPrice":10,"itemStainColor":4,"profile":"Item"},"Item_Enemy_18":{"canStack":true,"itemBuyingPrice":8,"itemSellingPrice":2,"itemStainColor":15,"profile":"Item"},"Item_Enemy_19":{"canStack":true,"itemBuyingPrice":80,"itemSellingPrice":20,"itemStainColor":10,"profile":"Item"},"Item_Enemy_20":{"canStack":true,"itemBuyingPrice":40,"itemSellingPrice":10,"itemStainColor":8,"profile":"Item"},"Item_Enemy_21":{"canStack":true,"itemBuyingPrice":100,"itemSellingPrice":25,"itemStainColor":3,"profile":"Item"},"Item_Enemy_24":{"canStack":true,"itemBuyingPrice":120,"itemSellingPrice":30,"itemStainColor":14,"profile":"Item"},"Item_Enemy_25":{"canStack":true,"itemBuyingPrice":440,"itemSellingPrice":110,"itemStainColor":7,"profile":"Item"},"Item_Enemy_26":{"canStack":true,"itemBuyingPrice":120,"itemSellingPrice":30,"itemStainColor":15,"profile":"Item"},"Item_Enemy_27":{"canStack":true,"itemBuyingPrice":48,"itemSellingPrice":12,"itemStainColor":15,"profile":"Item"},"Item_Enemy_28":{"canStack":true,"itemBuyingPrice":60,"itemSellingPrice":15,"itemStainColor":15,"profile":"Item"},"Item_Enemy_29":{"canStack":true,"itemBuyingPrice":160,"itemSellingPrice":40,"itemStainColor":15,"profile":"Item"},"Item_Enemy_30":{"canStack":true,"generalLife":1,"itemBuyingPrice":320,"itemSellingPrice":80,"itemStainColor":15,"profile":"Item"},"Item_Enemy_31":{"canStack":true,"generalLife":1,"itemBuyingPrice":800,"itemSellingPrice":200,"itemStainColor":15,"profile":"Item"},"Item_Enemy_32":{"canStack":true,"itemBuyingPrice":80,"itemSellingPrice":20,"itemStainColor":14,"profile":"Item"},"Item_Enemy_33":{"canStack":true,"itemBuyingPrice":140,"itemSellingPrice":35,"itemStainColor":14,"profile":"Item"},"Item_Enemy_34":{"canStack":true,"itemBuyingPrice":320,"itemSellingPrice":80,"itemStainColor":3,"profile":"Item"},"Item_Enemy_38":{"canStack":true,"itemBuyingPrice":600,"itemSellingPrice":150,"itemStainColor":12,"profile":"Item"},"Item_Enemy_39":{"canStack":true,"itemBuyingPrice":720,"itemSellingPrice":180,"itemStainColor":12,"profile":"Item"},"Item_Enemy_40":{"canStack":true,"generalLife":1,"itemBuyingPrice":20,"itemSellingPrice":5,"itemStainColor":8,"profile":"Item"},"Item_Enemy_41":{"canStack":true,"itemBuyingPrice":140,"itemSellingPrice":35,"itemStainColor":2,"profile":"Item"},"Item_Enemy_42":{"canStack":true,"itemBuyingPrice":140,"itemSellingPrice":35,"itemStainColor":1,"profile":"Item"},"Item_Enemy_43":{"canStack":true,"itemBuyingPrice":140,"itemSellingPrice":35,"itemStainColor":3,"profile":"Item"},"Item_Enemy_44":{"canStack":true,"itemBuyingPrice":24,"itemSellingPrice":6,"itemStainColor":2,"profile":"Item"},"Item_Enemy_45":{"canStack":true,"itemBuyingPrice":24,"itemSellingPrice":6,"itemStainColor":3,"profile":"Item"},"Item_Enemy_46":{"canStack":true,"itemBuyingPrice":24,"itemSellingPrice":6,"itemStainColor":1,"profile":"Item"},"Item_Enemy_47":{"canStack":true,"itemBuyingPrice":1000,"itemSellingPrice":250,"itemStainColor":12,"profile":"Item"},"Item_Enemy_48":{"canStack":true,"itemBuyingPrice":1200,"itemSellingPrice":300,"itemStainColor":12,"profile":"Item"},"Item_Enemy_49":{"canStack":true,"itemBuyingPrice":600,"itemSellingPrice":150,"itemStainColor":8,"profile":"Item"},"Item_Enemy_50":{"canStack":true,"itemBuyingPrice":720,"itemSellingPrice":180,"itemStainColor":8,"profile":"Item"},"Item_Enemy_51":{"canStack":true,"itemBuyingPrice":1000,"itemSellingPrice":250,"itemStainColor":8,"profile":"Item"},"Item_Enemy_52":{"canStack":true,"itemBuyingPrice":1200,"itemSellingPrice":300,"itemStainColor":8,"profile":"Item"},"Item_Enemy_53":{"canStack":true,"itemBuyingPrice":600,"itemSellingPrice":150,"itemStainColor":13,"profile":"Item"},"Item_Enemy_54":{"canStack":true,"itemBuyingPrice":720,"itemSellingPrice":180,"itemStainColor":13,"profile":"Item"},"Item_Enemy_55":{"canStack":true,"itemBuyingPrice":1000,"itemSellingPrice":250,"itemStainColor":13,"profile":"Item"},"Item_Enemy_56":{"canStack":true,"itemBuyingPrice":1200,"itemSellingPrice":300,"itemStainColor":13,"profile":"Item"},"Item_Enemy_57":{"canStack":true,"generalLife":1,"itemBuyingPrice":20,"itemSellingPrice":5,"itemStainColor":6,"profile":"Item"},"Item_Enemy_Put_57":{"canStack":true,"generalLife":1,"itemBuyingPrice":20,"itemSellingPrice":5,"itemStainColor":6,"profile":"Item"},"Item_FishGet_A":{"canStack":true,"generalLife":1,"itemBuyingPrice":24,"itemSellingPrice":6,"profile":"Item"},"Item_FishGet_B":{"canStack":true,"generalLife":1,"itemBuyingPrice":72,"itemSellingPrice":18,"profile":"Item"},"Item_FishGet_C":{"canStack":true,"generalLife":1,"itemBuyingPrice":24,"itemSellingPrice":6,"profile":"Item"},"Item_FishGet_D":{"canStack":true,"generalLife":1,"itemBuyingPrice":24,"itemSellingPrice":6,"profile":"Item"},"Item_FishGet_E":{"canStack":true,"generalLife":1,"itemBuyingPrice":40,"itemSellingPrice":10,"profile":"Item"},"Item_FishGet_F":{"canStack":true,"generalLife":1,"itemBuyingPrice":40,"itemSellingPrice":10,"profile":"Item"},"Item_FishGet_G":{"canStack":true,"generalLife":1,"itemBuyingPrice":40,"itemSellingPrice":10,"profile":"Item"},"Item_FishGet_H":{"canStack":true,"generalLife":1,"itemBuyingPrice":40,"itemSellingPrice":10,"profile":"Item"},"Item_FishGet_I":{"canStack":true,"generalLife":1,"itemBuyingPrice":40,"itemSellingPrice":10,"profile":"Item"},"Item_FishGet_J":{"canStack":true,"generalLife":1,"itemBuyingPrice":24,"itemSellingPrice":6,"profile":"Item"},"Item_FishGet_K":{"canStack":true,"generalLife":1,"itemBuyingPrice":60,"itemSellingPrice":15,"profile":"Item"},"Item_FishGet_L":{"canStack":true,"generalLife":1,"itemBuyingPrice":72,"itemSellingPrice":18,"profile":"Item"},"Item_FishGet_M":{"canStack":true,"generalLife":1,"itemBuyingPrice":24,"itemSellingPrice":6,"profile":"Item"},"Item_FishGet_X":{"canStack":true,"generalLife":1,"itemBuyingPrice":40,"itemSellingPrice":10,"profile":"Item"},"Item_FishGet_Z":{"canStack":true,"generalLife":1,"itemBuyingPrice":80,"itemSellingPrice":20,"profile":"Item"},"Item_Fruit_A":{"canStack":true,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":2,"profile":"Item"},"Item_Fruit_B":{"canStack":true,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":11,"profile":"Item"},"Item_Fruit_C":{"canStack":true,"itemBuyingPrice":16,"itemSellingPrice":4,"itemStainColor":10,"profile":"Item"},"Item_Fruit_D":{"canStack":true,"itemBuyingPrice":60,"itemSellingPrice":15,"itemStainColor":13,"profile":"Item"},"Item_Fruit_E":{"canStack":true,"itemBuyingPrice":20,"itemSellingPrice":5,"itemStainColor":7,"profile":"Item"},"Item_Fruit_F":{"canStack":true,"itemBuyingPrice":16,"itemSellingPrice":4,"itemStainColor":7,"profile":"Item"},"Item_Fruit_G":{"canStack":true,"itemBuyingPrice":16,"itemSellingPrice":4,"itemStainColor":13,"profile":"Item"},"Item_Fruit_H":{"canStack":true,"itemBuyingPrice":20,"itemSellingPrice":5,"itemStainColor":3,"profile":"Item"},"Item_Fruit_I":{"canStack":true,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":2,"profile":"Item"},"Item_Fruit_J":{"canStack":true,"itemBuyingPrice":20,"itemSellingPrice":5,"itemStainColor":10,"profile":"Item"},"Item_Fruit_K":{"canStack":true,"itemBuyingPrice":8,"itemSellingPrice":2,"itemStainColor":14,"profile":"Item"},"Item_Fruit_L":{"canStack":true,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":12,"profile":"Item"},"Item_InsectGet_K":{"canStack":true,"generalLife":1,"itemBuyingPrice":32,"itemSellingPrice":8,"profile":"Item"},"Item_InsectGet_O":{"canStack":true,"generalLife":1,"itemBuyingPrice":32,"itemSellingPrice":8,"profile":"Item"},"Item_InsectGet_Z":{"canStack":true,"generalLife":1,"itemBuyingPrice":40,"itemSellingPrice":10,"profile":"Item"},"Item_Material_01":{"canStack":true,"generalLife":1,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":7,"profile":"Item"},"Item_Material_02":{"canStack":true,"generalLife":1,"itemBuyingPrice":16,"itemSellingPrice":4,"itemStainColor":12,"profile":"Item"},"Item_Material_03":{"canStack":true,"generalLife":1,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":4,"profile":"Item"},"Item_Material_04":{"canStack":true,"generalLife":1,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":3,"profile":"Item"},"Item_Material_05":{"canStack":true,"generalLife":1,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":4,"profile":"Item"},"Item_Material_05_00":{"generalLife":1,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":4,"profile":"Item"},"Item_Material_06":{"canStack":true,"generalLife":1,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":13,"profile":"Item"},"Item_Material_07":{"canStack":true,"generalLife":1,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":13,"profile":"Item"},"Item_Material_08":{"canStack":true,"generalLife":1,"itemBuyingPrice":10,"itemSellingPrice":3,"itemStainColor":6,"profile":"Item"},"Item_Meat_01":{"canStack":true,"itemBuyingPrice":32,"itemSellingPrice":8,"profile":"Item"},"Item_Meat_02":{"canStack":true,"itemBuyingPrice":60,"itemSellingPrice":15,"profile":"Item"},"Item_Meat_06":{"canStack":true,"itemBuyingPrice":32,"itemSellingPrice":8,"profile":"Item"},"Item_Meat_07":{"canStack":true,"itemBuyingPrice":60,"itemSellingPrice":15,"profile":"Item"},"Item_Meat_11":{"canStack":true,"itemBuyingPrice":140,"itemSellingPrice":35,"profile":"Item"},"Item_Meat_12":{"canStack":true,"itemBuyingPrice":140,"itemSellingPrice":35,"profile":"Item"},"Item_MushroomGet_D":{"canStack":true,"generalLife":1,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":6,"profile":"Item"},"Item_Mushroom_A":{"canStack":true,"itemBuyingPrice":20,"itemSellingPrice":5,"itemStainColor":7,"profile":"Item"},"Item_Mushroom_B":{"canStack":true,"itemBuyingPrice":16,"itemSellingPrice":4,"itemStainColor":1,"profile":"Item"},"Item_Mushroom_C":{"canStack":true,"itemBuyingPrice":16,"itemSellingPrice":4,"itemStainColor":2,"profile":"Item"},"Item_Mushroom_D":{"canStack":true,"generalLife":1,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":6,"profile":"Item"},"Item_Mushroom_E":{"canStack":true,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":2,"profile":"Item"},"Item_Mushroom_F":{"canStack":true,"itemBuyingPrice":24,"itemSellingPrice":6,"itemStainColor":5,"profile":"Item"},"Item_Mushroom_F_00":{"itemBuyingPrice":24,"itemSellingPrice":6,"itemStainColor":5,"profile":"Item"},"Item_Mushroom_H":{"canStack":true,"itemBuyingPrice":16,"itemSellingPrice":4,"itemStainColor":3,"profile":"Item"},"Item_Mushroom_J":{"canStack":true,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":8,"profile":"Item"},"Item_Mushroom_L":{"canStack":true,"itemBuyingPrice":20,"itemSellingPrice":5,"itemStainColor":12,"profile":"Item"},"Item_Mushroom_M":{"canStack":true,"itemBuyingPrice":20,"itemSellingPrice":5,"itemStainColor":14,"profile":"Item"},"Item_Mushroom_N":{"canStack":true,"itemBuyingPrice":60,"itemSellingPrice":15,"itemStainColor":5,"profile":"Item"},"Item_Mushroom_N_00":{"itemBuyingPrice":60,"itemSellingPrice":15,"itemStainColor":5,"profile":"Item"},"Item_Mushroom_O":{"canStack":true,"itemBuyingPrice":24,"itemSellingPrice":6,"itemStainColor":10,"profile":"Item"},"Item_Ore_A":{"canStack":true,"itemBuyingPrice":2000,"itemSellingPrice":500,"itemStainColor":4,"profile":"Item"},"Item_Ore_A_00":{"itemBuyingPrice":2000,"itemSellingPrice":500,"itemStainColor":4,"profile":"Item"},"Item_Ore_B":{"canStack":true,"itemBuyingPrice":840,"itemSellingPrice":210,"itemStainColor":2,"profile":"Item"},"Item_Ore_C":{"canStack":true,"itemBuyingPrice":1040,"itemSellingPrice":260,"itemStainColor":1,"profile":"Item"},"Item_Ore_D":{"canStack":true,"itemBuyingPrice":720,"itemSellingPrice":180,"itemStainColor":3,"profile":"Item"},"Item_Ore_E":{"canStack":true,"itemBuyingPrice":240,"itemSellingPrice":60,"itemStainColor":13,"profile":"Item"},"Item_Ore_F":{"canStack":true,"itemBuyingPrice":120,"itemSellingPrice":30,"itemStainColor":10,"profile":"Item"},"Item_Ore_G":{"canStack":true,"itemBuyingPrice":280,"itemSellingPrice":70,"itemStainColor":9,"profile":"Item"},"Item_Ore_H":{"canStack":true,"itemBuyingPrice":12,"itemSellingPrice":2,"itemStainColor":11,"profile":"Item"},"Item_Ore_I":{"canStack":true,"generalLife":1,"itemBuyingPrice":20,"itemSellingPrice":5,"itemStainColor":5,"profile":"Item"},"Item_Ore_J":{"canStack":true,"itemBuyingPrice":1500,"itemSellingPrice":300,"itemStainColor":4,"profile":"Item"},"Item_PlantGet_A":{"canStack":true,"generalLife":1,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":7,"profile":"Item"},"Item_PlantGet_B":{"canStack":true,"generalLife":1,"itemBuyingPrice":32,"itemSellingPrice":8,"itemStainColor":11,"profile":"Item"},"Item_PlantGet_C":{"canStack":true,"generalLife":1,"itemBuyingPrice":60,"itemSellingPrice":15,"itemStainColor":11,"profile":"Item"},"Item_PlantGet_E":{"canStack":true,"generalLife":1,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":8,"profile":"Item"},"Item_PlantGet_F":{"canStack":true,"generalLife":1,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":10,"profile":"Item"},"Item_PlantGet_G":{"canStack":true,"generalLife":1,"itemBuyingPrice":20,"itemSellingPrice":5,"itemStainColor":10,"profile":"Item"},"Item_PlantGet_H":{"canStack":true,"generalLife":1,"itemBuyingPrice":20,"itemSellingPrice":5,"itemStainColor":6,"profile":"Item"},"Item_PlantGet_I":{"canStack":true,"generalLife":1,"itemBuyingPrice":16,"itemSellingPrice":4,"itemStainColor":1,"profile":"Item"},"Item_PlantGet_J":{"canStack":true,"generalLife":1,"itemBuyingPrice":30,"itemSellingPrice":10,"itemStainColor":4,"profile":"Item"},"Item_PlantGet_L":{"canStack":true,"generalLife":1,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":13,"profile":"Item"},"Item_PlantGet_M":{"canStack":true,"generalLife":1,"itemBuyingPrice":16,"itemSellingPrice":4,"itemStainColor":10,"profile":"Item"},"Item_PlantGet_O":{"canStack":true,"generalLife":1,"itemBuyingPrice":40,"itemSellingPrice":10,"itemStainColor":6,"profile":"Item"},"Item_PlantGet_Q":{"canStack":true,"generalLife":1,"itemBuyingPrice":120,"itemSellingPrice":30,"itemStainColor":13,"profile":"Item"},"Item_Plant_A":{"canStack":true,"generalLife":1,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":7,"profile":"Item"},"Item_Plant_B":{"canStack":true,"generalLife":1,"itemBuyingPrice":32,"itemSellingPrice":8,"itemStainColor":11,"profile":"Item"},"Item_Plant_C":{"canStack":true,"generalLife":1,"itemBuyingPrice":60,"itemSellingPrice":15,"itemStainColor":11,"profile":"Item"},"Item_Plant_E":{"canStack":true,"generalLife":1,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":8,"profile":"Item"},"Item_Plant_F":{"canStack":true,"generalLife":1,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":10,"profile":"Item"},"Item_Plant_G":{"canStack":true,"generalLife":1,"itemBuyingPrice":20,"itemSellingPrice":5,"itemStainColor":10,"profile":"Item"},"Item_Plant_H":{"canStack":true,"generalLife":1,"itemBuyingPrice":20,"itemSellingPrice":5,"itemStainColor":6,"profile":"Item"},"Item_Plant_I":{"canStack":true,"generalLife":1,"itemBuyingPrice":16,"itemSellingPrice":4,"itemStainColor":1,"profile":"Item"},"Item_Plant_J":{"canStack":true,"generalLife":1,"itemBuyingPrice":80,"itemSellingPrice":40,"itemStainColor":4,"profile":"Item"},"Item_Plant_L":{"canStack":true,"generalLife":1,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":13,"profile":"Item"},"Item_Plant_M":{"canStack":true,"generalLife":1,"itemBuyingPrice":16,"itemSellingPrice":4,"itemStainColor":10,"profile":"Item"},"Item_Plant_O":{"canStack":true,"generalLife":1,"itemBuyingPrice":40,"itemSellingPrice":10,"itemStainColor":6,"profile":"Item"},"Item_Plant_Q":{"canStack":true,"generalLife":1,"itemBuyingPrice":120,"itemSellingPrice":30,"itemStainColor":13,"profile":"Item"},"Item_RoastFish_01":{"canStack":true,"itemBuyingPrice":23,"itemSellingPrice":9,"profile":"Item"},"Item_RoastFish_02":{"canStack":true,"itemBuyingPrice":30,"itemSellingPrice":12,"profile":"Item"},"Item_RoastFish_03":{"canStack":true,"itemBuyingPrice":23,"itemSellingPrice":9,"profile":"Item"},"Item_RoastFish_04":{"canStack":true,"itemBuyingPrice":38,"itemSellingPrice":15,"profile":"Item"},"Item_RoastFish_07":{"canStack":true,"itemBuyingPrice":38,"itemSellingPrice":15,"profile":"Item"},"Item_RoastFish_09":{"canStack":true,"itemBuyingPrice":38,"itemSellingPrice":15,"profile":"Item"},"Item_RoastFish_11":{"canStack":true,"itemBuyingPrice":38,"itemSellingPrice":15,"profile":"Item"},"Item_RoastFish_13":{"canStack":true,"itemBuyingPrice":23,"itemSellingPrice":9,"profile":"Item"},"Item_RoastFish_15":{"canStack":true,"itemBuyingPrice":30,"itemSellingPrice":12,"profile":"Item"},"Item_Roast_01":{"canStack":true,"itemBuyingPrice":30,"itemSellingPrice":12,"profile":"Item"},"Item_Roast_02":{"canStack":true,"itemBuyingPrice":30,"itemSellingPrice":12,"profile":"Item"},"Item_Roast_03":{"canStack":true,"itemBuyingPrice":8,"itemSellingPrice":3,"profile":"Item"},"Item_Roast_04":{"canStack":true,"itemBuyingPrice":13,"itemSellingPrice":5,"profile":"Item"},"Item_Roast_05":{"canStack":true,"itemBuyingPrice":20,"itemSellingPrice":8,"profile":"Item"},"Item_Roast_06":{"canStack":true,"itemBuyingPrice":12,"itemSellingPrice":3,"itemStainColor":2,"profile":"Item"},"Item_Roast_07":{"canStack":true,"itemBuyingPrice":13,"itemSellingPrice":5,"profile":"Item"},"Item_Roast_08":{"canStack":true,"itemBuyingPrice":20,"itemSellingPrice":8,"profile":"Item"},"Item_Roast_09":{"canStack":true,"itemBuyingPrice":30,"itemSellingPrice":12,"profile":"Item"},"Item_Roast_10":{"canStack":true,"itemBuyingPrice":15,"itemSellingPrice":6,"profile":"Item"},"Item_Roast_11":{"canStack":true,"itemBuyingPrice":20,"itemSellingPrice":8,"profile":"Item"},"Item_Roast_12":{"canStack":true,"itemBuyingPrice":20,"itemSellingPrice":8,"profile":"Item"},"Item_Roast_13":{"canStack":true,"itemBuyingPrice":13,"itemSellingPrice":5,"profile":"Item"},"Item_Roast_15":{"canStack":true,"itemBuyingPrice":20,"itemSellingPrice":8,"profile":"Item"},"Item_Roast_16":{"canStack":true,"itemBuyingPrice":20,"itemSellingPrice":8,"profile":"Item"},"Item_Roast_18":{"canStack":true,"itemBuyingPrice":30,"itemSellingPrice":12,"profile":"Item"},"Item_Roast_19":{"canStack":true,"itemBuyingPrice":58,"itemSellingPrice":24,"profile":"Item"},"Item_Roast_24":{"canStack":true,"itemBuyingPrice":15,"itemSellingPrice":6,"profile":"Item"},"Item_Roast_27":{"canStack":true,"itemBuyingPrice":20,"itemSellingPrice":8,"profile":"Item"},"Item_Roast_28":{"canStack":true,"itemBuyingPrice":20,"itemSellingPrice":8,"profile":"Item"},"Item_Roast_31":{"canStack":true,"itemBuyingPrice":15,"itemSellingPrice":6,"profile":"Item"},"Item_Roast_32":{"canStack":true,"itemBuyingPrice":15,"itemSellingPrice":6,"profile":"Item"},"Item_Roast_33":{"canStack":true,"itemBuyingPrice":15,"itemSellingPrice":6,"profile":"Item"},"Item_Roast_36":{"canStack":true,"itemBuyingPrice":13,"itemSellingPrice":5,"profile":"Item"},"Item_Roast_37":{"canStack":true,"itemBuyingPrice":13,"itemSellingPrice":5,"profile":"Item"},"Item_Roast_38":{"canStack":true,"itemBuyingPrice":13,"itemSellingPrice":5,"profile":"Item"},"Item_Roast_39":{"canStack":true,"itemBuyingPrice":8,"itemSellingPrice":3,"profile":"Item"},"Item_Roast_40":{"canStack":true,"itemBuyingPrice":58,"itemSellingPrice":24,"profile":"Item"},"Item_Roast_41":{"canStack":true,"itemBuyingPrice":28,"itemSellingPrice":24,"profile":"Item"},"Item_Roast_45":{"canStack":true,"itemBuyingPrice":140,"itemSellingPrice":35,"profile":"Item"},"Item_Roast_46":{"canStack":true,"itemBuyingPrice":140,"itemSellingPrice":35,"profile":"Item"},"Item_Roast_48":{"canStack":true,"itemBuyingPrice":5,"itemSellingPrice":2,"profile":"Item"},"Item_Roast_49":{"canStack":true,"itemBuyingPrice":58,"itemSellingPrice":24,"profile":"Item"},"Item_Roast_50":{"canStack":true,"itemBuyingPrice":95,"itemSellingPrice":38,"profile":"Item"},"Item_Roast_51":{"canStack":true,"itemBuyingPrice":20,"itemSellingPrice":5,"profile":"Item"},"Item_Roast_52":{"canStack":true,"itemBuyingPrice":5,"itemSellingPrice":2,"profile":"Item"},"Item_Roast_53":{"canStack":true,"itemBuyingPrice":13,"itemSellingPrice":5,"profile":"Item"},"Kokko_Simple":{"attackPower":2,"profile":"MapDynamicActive"},"LastBossThunder":{"attackPower":24,"profile":"Bullet"},"LizalfosFlame":{"attackPower":24,"attackRange":10.0,"profile":"Bullet"},"Lizalfos_ElectricWaterBall":{"attackPower":40,"profile":"Bullet"},"Lizalfos_IceBall":{"attackRange":100.0,"profile":"Bullet"},"Lizalfos_Lava":{"attackRange":30.0,"profile":"Bullet"},"Lizalfos_Water":{"attackRange":30.0,"profile":"Bullet"},"LynelFlame":{"attackPower":1,"attackRange":5.0,"profile":"Bullet"},"NormalArrow":{"canStack":true,"cannotSell":true,"itemBuyingPrice":5,"itemSellingPrice":1,"profile":"Bullet"},"Obj_AncientArrow_A_01":{"canStack":true,"cannotSell":true,"itemBuyingPrice":100,"itemCreatingPrice":90,"profile":"Item"},"Obj_AncientArrow_B_01":{"canStack":true,"cannotSell":true,"itemBuyingPrice":400,"itemCreatingPrice":400,"profile":"Item"},"Obj_AncientArrow_C_01":{"canStack":true,"cannotSell":true,"itemBuyingPrice":250,"itemCreatingPrice":250,"profile":"Item"},"Obj_Armor_115_Head":{"cannotSell":true,"profile":"Item"},"Obj_ArrowBundle_A_01":{"canStack":true,"cannotSell":true,"itemBuyingPrice":20,"profile":"Item"},"Obj_ArrowBundle_A_02":{"canStack":true,"cannotSell":true,"itemBuyingPrice":35,"profile":"Item"},"Obj_ArrowBundle_A_10":{"canStack":true,"cannotSell":true,"itemBuyingPrice":35,"profile":"Item"},"Obj_ArrowNormal_A_01":{"canStack":true,"cannotSell":true,"itemBuyingPrice":5,"itemSellingPrice":1,"profile":"Item"},"Obj_BombArrow_A_01":{"canStack":true,"cannotSell":true,"itemBuyingPrice":50,"itemSellingPrice":1,"profile":"Item"},"Obj_BombArrow_A_02":{"canStack":true,"cannotSell":true,"itemBuyingPrice":200,"profile":"Item"},"Obj_BombArrow_A_03":{"canStack":true,"cannotSell":true,"itemBuyingPrice":350,"profile":"Item"},"Obj_BombArrow_A_04":{"canStack":true,"cannotSell":true,"itemBuyingPrice":600,"profile":"Item"},"Obj_Cushion":{"itemBuyingPrice":500,"itemCreatingPrice":500,"itemSellingPrice":500,"profile":"Item"},"Obj_DLC_HeroSeal_Gerudo":{"canStack":true,"cannotSell":true,"profile":"Item"},"Obj_DLC_HeroSeal_Goron":{"canStack":true,"cannotSell":true,"profile":"Item"},"Obj_DLC_HeroSeal_Rito":{"canStack":true,"cannotSell":true,"profile":"Item"},"Obj_DLC_HeroSeal_Zora":{"canStack":true,"cannotSell":true,"profile":"Item"},"Obj_DLC_HeroSoul_Gerudo":{"cannotSell":true,"profile":"Item"},"Obj_DLC_HeroSoul_Goron":{"cannotSell":true,"profile":"Item"},"Obj_DLC_HeroSoul_Rito":{"cannotSell":true,"profile":"Item"},"Obj_DLC_HeroSoul_Zora":{"cannotSell":true,"profile":"Item"},"Obj_DRStone_Get":{"cannotSell":true,"profile":"PlayerItem"},"Obj_DungeonClearSeal":{"canStack":true,"cannotSell":true,"profile":"Item"},"Obj_ElectricArrow_A_01":{"canStack":true,"cannotSell":true,"itemBuyingPrice":20,"itemSellingPrice":1,"profile":"Item"},"Obj_ElectricArrow_A_02":{"canStack":true,"cannotSell":true,"itemBuyingPrice":140,"itemCreatingPrice":10,"profile":"Item"},"Obj_ElectricArrow_A_03":{"canStack":true,"cannotSell":true,"itemBuyingPrice":80,"itemCreatingPrice":10,"profile":"Item"},"Obj_ElectricArrow_B_01":{"canStack":true,"cannotSell":true,"itemBuyingPrice":20,"itemSellingPrice":1,"profile":"Item"},"Obj_FireArrow_A_01":{"canStack":true,"cannotSell":true,"itemBuyingPrice":20,"itemSellingPrice":1,"profile":"Item"},"Obj_FireArrow_A_02":{"canStack":true,"cannotSell":true,"itemBuyingPrice":140,"itemCreatingPrice":10,"itemSellingPrice":2,"profile":"Item"},"Obj_FireArrow_A_03":{"canStack":true,"cannotSell":true,"itemBuyingPrice":80,"itemCreatingPrice":10,"itemSellingPrice":2,"profile":"Item"},"Obj_FireWoodBundle":{"canStack":true,"itemBuyingPrice":12,"itemSellingPrice":2,"profile":"Item"},"Obj_Head_024":{"itemBuyingPrice":800,"itemCreatingPrice":800,"itemSellingPrice":800,"profile":"Item"},"Obj_Head_025":{"itemBuyingPrice":500,"itemCreatingPrice":500,"itemSellingPrice":500,"profile":"Item"},"Obj_Head_026":{"itemBuyingPrice":500,"itemCreatingPrice":500,"itemSellingPrice":500,"profile":"Item"},"Obj_Head_027":{"itemBuyingPrice":400,"itemCreatingPrice":400,"itemSellingPrice":400,"profile":"Item"},"Obj_Head_028":{"itemBuyingPrice":200,"itemCreatingPrice":200,"itemSellingPrice":200,"profile":"Item"},"Obj_Head_029":{"itemBuyingPrice":80,"itemCreatingPrice":80,"itemSellingPrice":80,"profile":"Item"},"Obj_HeroSoul_Gerudo":{"cannotSell":true,"profile":"Item"},"Obj_HeroSoul_Goron":{"cannotSell":true,"profile":"Item"},"Obj_HeroSoul_Rito":{"cannotSell":true,"profile":"Item"},"Obj_HeroSoul_Zora":{"cannotSell":true,"profile":"Item"},"Obj_IceArrow_A_01":{"canStack":true,"cannotSell":true,"itemBuyingPrice":20,"itemSellingPrice":1,"profile":"Item"},"Obj_IceArrow_A_02":{"canStack":true,"cannotSell":true,"itemBuyingPrice":140,"itemCreatingPrice":10,"profile":"Item"},"Obj_IceArrow_A_03":{"canStack":true,"cannotSell":true,"itemBuyingPrice":80,"itemCreatingPrice":10,"profile":"Item"},"Obj_KorokNuts":{"canStack":true,"cannotSell":true,"profile":"Item"},"Obj_Maracas":{"cannotSell":true,"profile":"Item"},"Obj_Photo_Animal":{"cannotSell":true,"itemBuyingPrice":100,"profile":"Item"},"Obj_Photo_BossEnemy":{"cannotSell":true,"itemBuyingPrice":500,"profile":"Item"},"Obj_Photo_Enemy":{"cannotSell":true,"itemBuyingPrice":100,"profile":"Item"},"Obj_Photo_Material":{"cannotSell":true,"itemBuyingPrice":100,"profile":"Item"},"Obj_Photo_Other":{"cannotSell":true,"itemBuyingPrice":100,"profile":"Item"},"Obj_Photo_Weapon":{"cannotSell":true,"itemBuyingPrice":100,"profile":"Item"},"Obj_ProofBook":{"cannotSell":true,"profile":"Item"},"Obj_ProofGiantKiller":{"cannotSell":true,"profile":"Item"},"Obj_ProofGolemKiller":{"cannotSell":true,"profile":"Item"},"Obj_ProofKorok":{"cannotSell":true,"profile":"Item"},"Obj_ProofSandwormKiller":{"cannotSell":true,"profile":"Item"},"Obj_WarpDLC":{"cannotSell":true,"profile":"Item"},"Octarock_Bullet":{"attackPower":2,"profile":"Bullet"},"Octarock_Bullet_L":{"attackPower":1,"profile":"Bullet"},"Octarock_SnowBullet":{"attackPower":2,"profile":"Bullet"},"PlayerBeam":{"attackPower":10,"profile":"Bullet"},"PlayerStole2":{"cannotSell":true,"profile":"PlayerItem"},"PriestBossThunder":{"attackPower":24,"profile":"Bullet"},"Priest_Boss_Beam":{"attackPower":40,"profile":"Beam"},"Priest_Boss_ElectricArrow":{"canStack":true,"cannotSell":true,"itemBuyingPrice":20,"itemSellingPrice":1,"profile":"Bullet"},"Priest_Boss_FireArrow":{"canStack":true,"cannotSell":true,"itemBuyingPrice":20,"itemSellingPrice":1,"profile":"Bullet"},"Priest_Boss_IceArrow":{"canStack":true,"cannotSell":true,"itemBuyingPrice":20,"itemSellingPrice":1,"profile":"Bullet"},"Priest_Boss_IronBall":{"attackPower":20,"profile":"MapDynamicActive"},"Priest_Boss_Weapon_Bow_029":{"attackPower":10,"attackRange":40.0,"bowIsLongRange":true,"cannotSell":true,"generalLife":45,"itemBuyingPrice":50,"itemSellingPrice":10,"profile":"WeaponBow"},"Priest_Boss_Weapon_Sword_015":{"attackPower":40,"attackRange":1.6,"cannotSell":true,"generalLife":32,"itemBuyingPrice":114,"itemSellingPrice":45,"profile":"WeaponSmallSword"},"RemainsElectric":{"attackPower":70,"profile":"Remains"},"RemainsElectricCannon":{"attackPower":60,"attackRange":100.0,"generalLife":2000,"profile":"Enemy"},"RemainsElectric_Far":{"attackPower":70,"profile":"Remains"},"RemainsWaterChaseBullet":{"attackPower":4,"profile":"Bullet"},"RemainsWaterExplodeBullet":{"attackPower":4,"profile":"Bullet"},"RemainsWind":{"attackPower":4,"profile":"Remains"},"RemainsWind_Barrier_A_01":{"attackPower":4,"profile":"MapDynamicActive"},"RemainsWind_Far":{"attackPower":4,"profile":"Remains"},"RockBall":{"attackPower":12,"profile":"MapDynamicActive"},"Rock_Moriblin":{"attackPower":1,"attackRange":5.0,"profile":"Bullet"},"Rock_Weapon":{"attackPower":1,"attackRange":5.0,"profile":"Bullet"},"SimpleBeam":{"attackPower":52,"profile":"Beam"},"SiteBossBigFlameBall":{"attackPower":24,"attackRange":30.0,"profile":"Bullet"},"SiteBossDrawingFlameTornado":{"attackPower":24,"attackRange":30.0,"profile":"Bullet"},"SiteBossFlameBall":{"attackPower":24,"attackRange":30.0,"profile":"Bullet"},"SiteBossGaleArrow":{"attackPower":24,"profile":"Bullet"},"SiteBossNormalArrow":{"attackPower":16,"profile":"Bullet"},"SiteBossPillarOfFlame":{"attackPower":24,"attackRange":30.0,"profile":"Bullet"},"SiteBossReflectArrow":{"attackPower":16,"profile":"Bullet"},"SiteBossSeaOfFlame":{"attackPower":24,"attackRange":30.0,"profile":"Bullet"},"SiteBossSeaOfFlameRotate":{"attackPower":24,"attackRange":30.0,"profile":"Bullet"},"SiteBossSpearForThrowing":{"attackPower":16,"profile":"Bullet"},"SiteBossSpearIceBullet":{"attackPower":24,"profile":"Bullet"},"SiteBossTornado":{"attackPower":24,"profile":"Bullet"},"SiteBossWearFlame":{"attackPower":24,"attackRange":30.0,"profile":"Bullet"},"ThunderRodLv1Thunder":{"attackPower":24,"attackRange":30.0,"profile":"Bullet"},"ThunderRodLv2Thunder":{"attackPower":24,"attackRange":30.0,"profile":"Bullet"},"ThunderRodLv2ThunderChild":{"attackPower":24,"attackRange":30.0,"profile":"Bullet"},"WallSpike":{"attackPower":4,"profile":"MapConstActive"},"WallSpikeTgt":{"attackPower":4,"profile":"MapConstActive"},"Weapon_Arrow_020":{"attackPower":40,"itemBuyingPrice":50,"itemSellingPrice":1,"profile":"Bullet"},"Weapon_Bow_001":{"attackPower":5,"attackRange":20.0,"cannotSell":true,"generalLife":22,"itemBuyingPrice":20,"itemSellingPrice":5,"profile":"WeaponBow"},"Weapon_Bow_002":{"attackPower":14,"attackRange":20.0,"cannotSell":true,"generalLife":36,"itemBuyingPrice":70,"itemSellingPrice":18,"profile":"WeaponBow"},"Weapon_Bow_003":{"attackPower":12,"attackRange":20.0,"bowLeadShotAng":13.0,"bowLeadShotInterval":1,"bowLeadShotNum":3,"cannotSell":true,"generalLife":20,"itemBuyingPrice":30,"itemSellingPrice":10,"profile":"WeaponBow"},"Weapon_Bow_004":{"attackPower":4,"attackRange":20.0,"cannotSell":true,"generalLife":16,"itemBuyingPrice":9,"itemSellingPrice":3,"profile":"WeaponBow"},"Weapon_Bow_006":{"attackPower":14,"attackRange":20.0,"cannotSell":true,"generalLife":25,"itemBuyingPrice":24,"itemSellingPrice":8,"profile":"WeaponBow"},"Weapon_Bow_009":{"attackPower":10,"attackRange":20.0,"bowLeadShotAng":3.0,"bowLeadShotInterval":1,"bowLeadShotNum":3,"cannotSell":true,"generalLife":30,"itemBuyingPrice":54,"itemSellingPrice":18,"profile":"WeaponBow","specialStatus":27},"Weapon_Bow_011":{"attackPower":25,"attackRange":20.0,"bowLeadShotAng":13.0,"bowLeadShotInterval":1,"bowLeadShotNum":3,"cannotSell":true,"generalLife":35,"itemBuyingPrice":30,"itemSellingPrice":10,"profile":"WeaponBow"},"Weapon_Bow_013":{"attackPower":15,"attackRange":20.0,"bowArrowChargeRate":1.6,"bowArrowFirstSpeed":4.0,"bowLeadShotAng":3.0,"bowLeadShotInterval":1,"bowLeadShotNum":3,"cannotSell":true,"generalLife":35,"itemBuyingPrice":30,"itemSellingPrice":7,"profile":"WeaponBow","specialStatus":27},"Weapon_Bow_014":{"attackPower":15,"attackRange":20.0,"bowArrowGravity":-7.0,"cannotSell":true,"generalLife":40,"itemBuyingPrice":65,"itemSellingPrice":16,"profile":"WeaponBow"},"Weapon_Bow_015":{"attackPower":14,"attackRange":40.0,"bowIsLongRange":true,"cannotSell":true,"generalLife":60,"itemBuyingPrice":85,"itemSellingPrice":21,"profile":"WeaponBow"},"Weapon_Bow_016":{"attackPower":9,"attackRange":40.0,"bowArrowChargeRate":1.3,"cannotSell":true,"generalLife":30,"itemBuyingPrice":40,"itemSellingPrice":10,"profile":"WeaponBow"},"Weapon_Bow_017":{"attackPower":20,"attackRange":40.0,"bowArrowChargeRate":1.6,"bowLeadShotAng":13.0,"bowLeadShotInterval":1,"bowLeadShotNum":3,"cannotSell":true,"generalLife":50,"itemBuyingPrice":190,"itemSellingPrice":48,"profile":"WeaponBow"},"Weapon_Bow_023":{"attackPower":44,"attackRange":40.0,"bowArrowChargeRate":0.7,"bowArrowGravity":-2.8,"bowArrowStabilitySpeed":4.0,"bowIsGuardPierce":true,"cannotSell":true,"generalLife":120,"itemBuyingPrice":20,"itemCreatingPrice":1000,"itemSellingPrice":5,"profile":"WeaponBow"},"Weapon_Bow_026":{"attackPower":20,"attackRange":20.0,"bowLeadShotAng":3.0,"bowLeadShotInterval":1,"bowLeadShotNum":3,"cannotSell":true,"generalLife":35,"itemBuyingPrice":105,"itemSellingPrice":35,"profile":"WeaponBow","specialStatus":27},"Weapon_Bow_027":{"attackPower":24,"attackRange":20.0,"bowLeadShotAng":20.0,"bowLeadShotInterval":1,"bowLeadShotNum":5,"cannotSell":true,"generalLife":30,"itemBuyingPrice":50,"itemSellingPrice":15,"profile":"WeaponBow"},"Weapon_Bow_028":{"attackPower":28,"attackRange":40.0,"bowArrowChargeRate":1.8,"bowLeadShotAng":3.0,"bowLeadShotInterval":1,"bowLeadShotNum":3,"cannotSell":true,"generalLife":60,"itemBuyingPrice":380,"itemSellingPrice":120,"profile":"WeaponBow","specialStatus":27},"Weapon_Bow_029":{"attackPower":10,"attackRange":40.0,"bowIsLongRange":true,"cannotSell":true,"generalLife":45,"itemBuyingPrice":50,"itemSellingPrice":10,"profile":"WeaponBow"},"Weapon_Bow_030":{"attackPower":36,"attackRange":20.0,"bowLeadShotAng":20.0,"bowLeadShotInterval":1,"bowLeadShotNum":5,"cannotSell":true,"generalLife":50,"itemBuyingPrice":50,"itemSellingPrice":16,"profile":"WeaponBow"},"Weapon_Bow_032":{"attackPower":32,"attackRange":20.0,"bowLeadShotAng":3.0,"bowLeadShotInterval":1,"bowLeadShotNum":3,"cannotSell":true,"generalLife":45,"itemBuyingPrice":156,"itemSellingPrice":52,"profile":"WeaponBow","specialStatus":27},"Weapon_Bow_033":{"attackPower":50,"attackRange":30.0,"bowArrowChargeRate":1.5,"bowArrowFirstSpeed":8.0,"bowArrowReloadRate":0.8,"bowArrowStabilitySpeed":4.0,"cannotSell":true,"generalLife":20,"itemBuyingPrice":300,"itemSellingPrice":100,"profile":"WeaponBow"},"Weapon_Bow_035":{"attackPower":26,"attackRange":20.0,"cannotSell":true,"generalLife":48,"itemBuyingPrice":70,"itemSellingPrice":18,"profile":"WeaponBow"},"Weapon_Bow_036":{"attackPower":38,"attackRange":20.0,"cannotSell":true,"generalLife":60,"itemBuyingPrice":70,"itemSellingPrice":18,"profile":"WeaponBow"},"Weapon_Bow_038":{"attackPower":4,"attackRange":20.0,"cannotSell":true,"generalLife":20,"itemBuyingPrice":20,"itemSellingPrice":5,"profile":"WeaponBow"},"Weapon_Bow_040":{"attackPower":14,"attackRange":40.0,"bowRapidFireNum":2,"cannotSell":true,"generalLife":18,"profile":"WeaponBow"},"Weapon_Bow_071":{"attackPower":100,"attackRange":500.0,"bowArrowFirstSpeed":7.0,"bowArrowGravity":-5.0,"bowArrowStabilitySpeed":5.0,"cannotSell":true,"profile":"WeaponBow"},"Weapon_Bow_072":{"attackPower":30,"attackRange":8000.0,"bowArrowFirstSpeed":7.0,"bowArrowGravity":-5.0,"bowArrowStabilitySpeed":5.0,"cannotSell":true,"profile":"WeaponBow"},"Weapon_Bow_080":{"attackPower":28,"attackRange":40.0,"bowArrowChargeRate":1.8,"bowLeadShotAng":3.0,"bowLeadShotInterval":1,"bowLeadShotNum":3,"generalLife":60,"itemBuyingPrice":380,"itemSellingPrice":120,"profile":"WeaponBow","specialStatus":27},"Weapon_Goron_Knuckle":{"attackPower":5,"attackRange":1.6,"profile":"WeaponSmallSword"},"Weapon_Lsword_001":{"attackPower":10,"attackRange":1.8,"cannotSell":true,"generalLife":20,"itemBuyingPrice":30,"itemSellingPrice":8,"profile":"WeaponLargeSword"},"Weapon_Lsword_002":{"attackPower":20,"attackRange":1.8,"cannotSell":true,"generalLife":25,"itemBuyingPrice":75,"itemSellingPrice":18,"profile":"WeaponLargeSword"},"Weapon_Lsword_003":{"attackPower":38,"attackRange":1.8,"cannotSell":true,"generalLife":30,"itemBuyingPrice":165,"itemSellingPrice":42,"profile":"WeaponLargeSword"},"Weapon_Lsword_004":{"attackPower":6,"attackRange":1.8,"cannotSell":true,"generalLife":8,"itemBuyingPrice":9,"itemSellingPrice":5,"profile":"WeaponLargeSword"},"Weapon_Lsword_005":{"attackPower":18,"attackRange":1.8,"cannotSell":true,"generalLife":12,"itemBuyingPrice":15,"itemSellingPrice":10,"profile":"WeaponLargeSword"},"Weapon_Lsword_006":{"attackPower":36,"attackRange":1.8,"cannotSell":true,"generalLife":16,"itemBuyingPrice":30,"itemSellingPrice":15,"profile":"WeaponLargeSword"},"Weapon_Lsword_010":{"attackPower":9,"attackRange":1.8,"cannotSell":true,"generalLife":12,"itemBuyingPrice":39,"itemSellingPrice":12,"profile":"WeaponLargeSword"},"Weapon_Lsword_011":{"attackPower":27,"attackRange":1.8,"cannotSell":true,"generalLife":18,"itemBuyingPrice":69,"itemSellingPrice":25,"profile":"WeaponLargeSword"},"Weapon_Lsword_012":{"attackPower":45,"attackRange":1.8,"cannotSell":true,"generalLife":24,"itemBuyingPrice":99,"itemSellingPrice":38,"profile":"WeaponLargeSword"},"Weapon_Lsword_013":{"attackPower":30,"attackRange":1.8,"cannotSell":true,"generalLife":15,"itemBuyingPrice":45,"itemSellingPrice":18,"profile":"WeaponLargeSword"},"Weapon_Lsword_014":{"attackPower":45,"attackRange":1.8,"cannotSell":true,"generalLife":20,"itemBuyingPrice":84,"itemSellingPrice":35,"profile":"WeaponLargeSword"},"Weapon_Lsword_015":{"attackPower":60,"attackRange":1.8,"cannotSell":true,"generalLife":25,"itemBuyingPrice":120,"itemSellingPrice":52,"profile":"WeaponLargeSword"},"Weapon_Lsword_016":{"attackPower":36,"attackRange":1.8,"cannotSell":true,"generalLife":20,"itemBuyingPrice":54,"itemSellingPrice":22,"profile":"WeaponLargeSword"},"Weapon_Lsword_017":{"attackPower":54,"attackRange":1.8,"cannotSell":true,"generalLife":25,"itemBuyingPrice":99,"itemSellingPrice":45,"profile":"WeaponLargeSword"},"Weapon_Lsword_018":{"attackPower":78,"attackRange":1.8,"cannotSell":true,"generalLife":35,"itemBuyingPrice":144,"itemSellingPrice":68,"profile":"WeaponLargeSword"},"Weapon_Lsword_019":{"attackPower":15,"attackRange":1.8,"cannotSell":true,"generalLife":5,"profile":"WeaponLargeSword"},"Weapon_Lsword_020":{"attackPower":12,"attackRange":1.8,"cannotSell":true,"generalLife":10,"profile":"WeaponLargeSword"},"Weapon_Lsword_023":{"attackPower":55,"attackRange":1.8,"cannotSell":true,"generalLife":50,"itemBuyingPrice":30,"itemCreatingPrice":1000,"itemSellingPrice":8,"profile":"WeaponLargeSword"},"Weapon_Lsword_024":{"attackPower":52,"attackRange":1.8,"cannotSell":true,"generalLife":40,"itemBuyingPrice":300,"itemSellingPrice":75,"profile":"WeaponLargeSword"},"Weapon_Lsword_027":{"attackPower":22,"attackRange":1.8,"cannotSell":true,"generalLife":30,"itemBuyingPrice":55,"itemSellingPrice":14,"profile":"WeaponLargeSword"},"Weapon_Lsword_029":{"attackPower":28,"attackRange":1.8,"cannotSell":true,"generalLife":30,"itemBuyingPrice":120,"itemSellingPrice":30,"profile":"WeaponLargeSword"},"Weapon_Lsword_030":{"attackPower":18,"attackRange":1.8,"cannotSell":true,"generalLife":52,"itemBuyingPrice":24,"itemSellingPrice":4,"profile":"WeaponLargeSword"},"Weapon_Lsword_031":{"attackPower":12,"attackRange":1.8,"cannotSell":true,"generalLife":40,"itemBuyingPrice":24,"itemSellingPrice":4,"profile":"WeaponLargeSword"},"Weapon_Lsword_032":{"attackPower":3,"attackRange":1.8,"cannotSell":true,"generalLife":47,"itemBuyingPrice":24,"itemSellingPrice":4,"profile":"WeaponLargeSword"},"Weapon_Lsword_033":{"attackPower":34,"attackRange":1.8,"cannotSell":true,"generalLife":50,"itemBuyingPrice":150,"itemSellingPrice":150,"profile":"WeaponLargeSword"},"Weapon_Lsword_034":{"attackPower":30,"attackRange":1.8,"cannotSell":true,"generalLife":40,"itemBuyingPrice":150,"itemSellingPrice":150,"profile":"WeaponLargeSword"},"Weapon_Lsword_035":{"attackPower":32,"attackRange":1.8,"cannotSell":true,"generalLife":50,"itemBuyingPrice":150,"itemSellingPrice":150,"profile":"WeaponLargeSword"},"Weapon_Lsword_036":{"attackPower":15,"attackRange":1.8,"cannotSell":true,"generalLife":30,"itemBuyingPrice":110,"itemSellingPrice":28,"profile":"WeaponLargeSword"},"Weapon_Lsword_037":{"attackPower":42,"attackRange":1.8,"cannotSell":true,"generalLife":40,"itemBuyingPrice":325,"itemSellingPrice":80,"profile":"WeaponLargeSword"},"Weapon_Lsword_038":{"attackPower":14,"attackRange":1.8,"cannotSell":true,"generalLife":8,"itemBuyingPrice":3,"itemSellingPrice":1,"profile":"WeaponLargeSword"},"Weapon_Lsword_041":{"attackPower":32,"attackRange":1.8,"cannotSell":true,"generalLife":25,"itemBuyingPrice":120,"itemSellingPrice":30,"profile":"WeaponLargeSword"},"Weapon_Lsword_045":{"attackPower":16,"attackRange":1.8,"cannotSell":true,"generalLife":6,"itemBuyingPrice":3,"itemSellingPrice":1,"profile":"WeaponLargeSword"},"Weapon_Lsword_047":{"attackPower":72,"attackRange":1.8,"cannotSell":true,"generalLife":15,"itemBuyingPrice":120,"itemSellingPrice":100,"profile":"WeaponLargeSword"},"Weapon_Lsword_051":{"attackPower":25,"attackRange":1.8,"cannotSell":true,"generalLife":40,"itemBuyingPrice":300,"itemSellingPrice":75,"profile":"WeaponLargeSword"},"Weapon_Lsword_054":{"attackPower":60,"attackRange":1.8,"cannotSell":true,"generalLife":60,"itemBuyingPrice":540,"itemSellingPrice":135,"profile":"WeaponLargeSword"},"Weapon_Lsword_055":{"attackPower":50,"attackRange":1.8,"cannotSell":true,"generalLife":35,"itemBuyingPrice":450,"itemSellingPrice":112,"profile":"WeaponLargeSword"},"Weapon_Lsword_056":{"attackPower":1,"attackRange":1.8,"cannotSell":true,"generalLife":25,"itemBuyingPrice":450,"itemSellingPrice":112,"profile":"WeaponLargeSword"},"Weapon_Lsword_057":{"attackPower":48,"attackRange":1.8,"cannotSell":true,"generalLife":50,"itemBuyingPrice":30,"itemSellingPrice":8,"profile":"WeaponLargeSword"},"Weapon_Lsword_059":{"attackPower":50,"attackRange":1.8,"cannotSell":true,"generalLife":60,"itemBuyingPrice":30,"itemSellingPrice":8,"profile":"WeaponLargeSword"},"Weapon_Lsword_060":{"attackPower":60,"attackRange":1.8,"cannotSell":true,"generalLife":35,"itemBuyingPrice":30,"itemSellingPrice":8,"profile":"WeaponLargeSword"},"Weapon_Lsword_074":{"attackPower":40,"attackRange":15.0,"cannotSell":true,"generalLife":25,"profile":"WeaponLargeSword"},"Weapon_Shield_001":{"cannotSell":true,"generalLife":12,"itemBuyingPrice":25,"itemCreatingPrice":10,"itemSellingPrice":6,"profile":"WeaponShield","weaponCommonGuardPower":2},"Weapon_Shield_002":{"cannotSell":true,"generalLife":16,"itemBuyingPrice":70,"itemCreatingPrice":10,"itemSellingPrice":18,"profile":"WeaponShield","weaponCommonGuardPower":16},"Weapon_Shield_003":{"cannotSell":true,"generalLife":23,"itemBuyingPrice":180,"itemCreatingPrice":10,"itemSellingPrice":45,"profile":"WeaponShield","weaponCommonGuardPower":40},"Weapon_Shield_004":{"cannotSell":true,"generalLife":5,"itemBuyingPrice":9,"itemCreatingPrice":10,"itemSellingPrice":5,"profile":"WeaponShield","weaponCommonGuardPower":3},"Weapon_Shield_005":{"cannotSell":true,"generalLife":7,"itemBuyingPrice":15,"itemCreatingPrice":10,"itemSellingPrice":10,"profile":"WeaponShield","weaponCommonGuardPower":10},"Weapon_Shield_006":{"cannotSell":true,"generalLife":8,"itemBuyingPrice":24,"itemCreatingPrice":10,"itemSellingPrice":15,"profile":"WeaponShield","weaponCommonGuardPower":25},"Weapon_Shield_007":{"cannotSell":true,"generalLife":8,"itemBuyingPrice":30,"itemCreatingPrice":10,"itemSellingPrice":10,"profile":"WeaponShield","weaponCommonGuardPower":15},"Weapon_Shield_008":{"cannotSell":true,"generalLife":12,"itemBuyingPrice":60,"itemCreatingPrice":10,"itemSellingPrice":20,"profile":"WeaponShield","weaponCommonGuardPower":22},"Weapon_Shield_009":{"cannotSell":true,"generalLife":15,"itemBuyingPrice":90,"itemCreatingPrice":10,"itemSellingPrice":30,"profile":"WeaponShield","weaponCommonGuardPower":35},"Weapon_Shield_013":{"attackRange":0.5,"cannotSell":true,"generalLife":10,"itemBuyingPrice":45,"itemCreatingPrice":10,"itemSellingPrice":15,"profile":"WeaponShield","weaponCommonGuardPower":18},"Weapon_Shield_014":{"attackRange":0.5,"cannotSell":true,"generalLife":13,"itemBuyingPrice":90,"itemCreatingPrice":10,"itemSellingPrice":30,"profile":"WeaponShield","weaponCommonGuardPower":30},"Weapon_Shield_015":{"attackRange":0.5,"cannotSell":true,"generalLife":20,"itemBuyingPrice":135,"itemCreatingPrice":10,"itemSellingPrice":45,"profile":"WeaponShield","weaponCommonGuardPower":42},"Weapon_Shield_016":{"attackPower":7,"attackRange":0.5,"cannotSell":true,"generalLife":12,"itemBuyingPrice":54,"itemCreatingPrice":10,"itemSellingPrice":18,"profile":"WeaponShield","weaponCommonGuardPower":30},"Weapon_Shield_017":{"attackPower":13,"attackRange":0.5,"cannotSell":true,"generalLife":15,"itemBuyingPrice":105,"itemCreatingPrice":10,"itemSellingPrice":35,"profile":"WeaponShield","weaponCommonGuardPower":44},"Weapon_Shield_018":{"attackPower":21,"attackRange":0.5,"cannotSell":true,"generalLife":20,"itemBuyingPrice":156,"itemCreatingPrice":10,"itemSellingPrice":52,"profile":"WeaponShield","weaponCommonGuardPower":62},"Weapon_Shield_021":{"cannotSell":true,"generalLife":16,"profile":"WeaponShield","weaponCommonGuardPower":3},"Weapon_Shield_022":{"attackRange":0.5,"cannotSell":true,"generalLife":29,"itemBuyingPrice":320,"itemCreatingPrice":10,"itemSellingPrice":80,"profile":"WeaponShield","weaponCommonGuardPower":55},"Weapon_Shield_023":{"attackRange":0.5,"cannotSell":true,"generalLife":18,"itemBuyingPrice":30,"itemCreatingPrice":10,"itemSellingPrice":8,"profile":"WeaponShield","weaponCommonGuardPower":30},"Weapon_Shield_025":{"attackRange":0.5,"cannotSell":true,"generalLife":20,"itemBuyingPrice":220,"itemCreatingPrice":10,"itemSellingPrice":55,"profile":"WeaponShield","weaponCommonGuardPower":18},"Weapon_Shield_026":{"attackRange":0.5,"cannotSell":true,"generalLife":20,"itemBuyingPrice":80,"itemCreatingPrice":10,"itemSellingPrice":20,"profile":"WeaponShield","weaponCommonGuardPower":20},"Weapon_Shield_030":{"cannotSell":true,"generalLife":800,"itemBuyingPrice":3000,"itemCreatingPrice":10,"itemSellingPrice":750,"profile":"WeaponShield","weaponCommonGuardPower":90},"Weapon_Shield_031":{"attackRange":0.5,"cannotSell":true,"generalLife":10,"itemBuyingPrice":15,"itemCreatingPrice":10,"itemSellingPrice":4,"profile":"WeaponShield","weaponCommonGuardPower":3},"Weapon_Shield_032":{"cannotSell":true,"generalLife":10,"itemBuyingPrice":18,"itemCreatingPrice":10,"itemSellingPrice":4,"profile":"WeaponShield","weaponCommonGuardPower":3},"Weapon_Shield_033":{"attackRange":0.5,"cannotSell":true,"generalLife":14,"itemBuyingPrice":300,"itemCreatingPrice":10,"itemSellingPrice":100,"profile":"WeaponShield","weaponCommonGuardPower":70},"Weapon_Shield_034":{"cannotSell":true,"generalLife":12,"itemBuyingPrice":20,"itemCreatingPrice":10,"itemSellingPrice":5,"profile":"WeaponShield","weaponCommonGuardPower":3},"Weapon_Shield_035":{"cannotSell":true,"generalLife":12,"profile":"WeaponShield","weaponCommonGuardPower":4},"Weapon_Shield_036":{"cannotSell":true,"generalLife":26,"itemBuyingPrice":210,"itemCreatingPrice":10,"itemSellingPrice":52,"profile":"WeaponShield","weaponCommonGuardPower":35},"Weapon_Shield_037":{"cannotSell":true,"generalLife":60,"itemBuyingPrice":390,"itemCreatingPrice":10,"itemSellingPrice":98,"profile":"WeaponShield","weaponCommonGuardPower":48},"Weapon_Shield_038":{"cannotSell":true,"generalLife":32,"itemBuyingPrice":375,"itemCreatingPrice":1000,"itemSellingPrice":125,"profile":"WeaponShield","weaponCommonGuardPower":70},"Weapon_Shield_040":{"cannotSell":true,"generalLife":10,"itemBuyingPrice":25,"itemCreatingPrice":10,"itemSellingPrice":6,"profile":"WeaponShield","weaponCommonGuardPower":1},"Weapon_Shield_041":{"cannotSell":true,"generalLife":16,"itemBuyingPrice":25,"itemCreatingPrice":10,"itemSellingPrice":6,"profile":"WeaponShield","weaponCommonGuardPower":16},"Weapon_Shield_042":{"cannotSell":true,"generalLife":16,"itemBuyingPrice":25,"itemCreatingPrice":10,"itemSellingPrice":6,"profile":"WeaponShield","weaponCommonGuardPower":14},"Weapon_Shield_057":{"attackRange":0.5,"cannotSell":true,"generalLife":90,"itemBuyingPrice":320,"itemCreatingPrice":10,"itemSellingPrice":80,"profile":"WeaponShield","weaponCommonGuardPower":65},"Weapon_Spear_001":{"attackPower":3,"attackRange":5.0,"cannotSell":true,"generalLife":30,"itemBuyingPrice":20,"itemSellingPrice":7,"profile":"WeaponSpear"},"Weapon_Spear_002":{"attackPower":7,"attackRange":5.0,"cannotSell":true,"generalLife":35,"itemBuyingPrice":70,"itemSellingPrice":18,"profile":"WeaponSpear"},"Weapon_Spear_003":{"attackPower":13,"attackRange":5.0,"cannotSell":true,"generalLife":40,"itemBuyingPrice":180,"itemSellingPrice":45,"profile":"WeaponSpear"},"Weapon_Spear_004":{"attackPower":2,"attackRange":5.0,"cannotSell":true,"generalLife":12,"itemBuyingPrice":9,"itemSellingPrice":5,"profile":"WeaponSpear"},"Weapon_Spear_005":{"attackPower":6,"attackRange":5.0,"cannotSell":true,"generalLife":15,"itemBuyingPrice":15,"itemSellingPrice":10,"profile":"WeaponSpear"},"Weapon_Spear_006":{"attackPower":12,"attackRange":5.0,"cannotSell":true,"generalLife":20,"itemBuyingPrice":24,"itemSellingPrice":15,"profile":"WeaponSpear"},"Weapon_Spear_007":{"attackPower":7,"attackRange":5.0,"cannotSell":true,"generalLife":18,"itemBuyingPrice":24,"itemSellingPrice":10,"profile":"WeaponSpear"},"Weapon_Spear_008":{"attackPower":12,"attackRange":5.0,"cannotSell":true,"generalLife":22,"itemBuyingPrice":45,"itemSellingPrice":20,"profile":"WeaponSpear"},"Weapon_Spear_009":{"attackPower":18,"attackRange":5.0,"cannotSell":true,"generalLife":28,"itemBuyingPrice":69,"itemSellingPrice":30,"profile":"WeaponSpear"},"Weapon_Spear_010":{"attackPower":4,"attackRange":5.0,"cannotSell":true,"generalLife":15,"itemBuyingPrice":30,"itemSellingPrice":12,"profile":"WeaponSpear"},"Weapon_Spear_011":{"attackPower":9,"attackRange":5.0,"cannotSell":true,"generalLife":20,"itemBuyingPrice":60,"itemSellingPrice":25,"profile":"WeaponSpear"},"Weapon_Spear_012":{"attackPower":15,"attackRange":5.0,"cannotSell":true,"generalLife":25,"itemBuyingPrice":90,"itemSellingPrice":38,"profile":"WeaponSpear"},"Weapon_Spear_013":{"attackPower":10,"attackRange":5.0,"cannotSell":true,"generalLife":20,"itemBuyingPrice":39,"itemSellingPrice":18,"profile":"WeaponSpear"},"Weapon_Spear_014":{"attackPower":15,"attackRange":5.0,"cannotSell":true,"generalLife":25,"itemBuyingPrice":75,"itemSellingPrice":35,"profile":"WeaponSpear"},"Weapon_Spear_015":{"attackPower":20,"attackRange":5.0,"cannotSell":true,"generalLife":35,"itemBuyingPrice":114,"itemSellingPrice":52,"profile":"WeaponSpear"},"Weapon_Spear_016":{"attackPower":14,"attackRange":5.0,"cannotSell":true,"generalLife":25,"itemBuyingPrice":45,"itemSellingPrice":22,"profile":"WeaponSpear"},"Weapon_Spear_017":{"attackPower":20,"attackRange":5.0,"cannotSell":true,"generalLife":35,"itemBuyingPrice":90,"itemSellingPrice":45,"profile":"WeaponSpear"},"Weapon_Spear_018":{"attackPower":30,"attackRange":5.0,"cannotSell":true,"generalLife":45,"itemBuyingPrice":135,"itemSellingPrice":68,"profile":"WeaponSpear"},"Weapon_Spear_021":{"attackPower":5,"attackRange":5.0,"cannotSell":true,"generalLife":15,"itemBuyingPrice":20,"itemSellingPrice":7,"profile":"WeaponSpear"},"Weapon_Spear_022":{"attackPower":7,"attackRange":5.0,"cannotSell":true,"generalLife":12,"itemBuyingPrice":20,"itemSellingPrice":7,"profile":"WeaponSpear"},"Weapon_Spear_023":{"attackPower":30,"attackRange":5.0,"cannotSell":true,"generalLife":50,"itemBuyingPrice":20,"itemCreatingPrice":1000,"itemSellingPrice":7,"profile":"WeaponSpear"},"Weapon_Spear_024":{"attackPower":26,"attackRange":5.0,"cannotSell":true,"generalLife":50,"itemBuyingPrice":320,"itemSellingPrice":80,"profile":"WeaponSpear"},"Weapon_Spear_025":{"attackPower":11,"attackRange":5.0,"cannotSell":true,"generalLife":35,"itemBuyingPrice":25,"itemSellingPrice":8,"profile":"WeaponSpear"},"Weapon_Spear_027":{"attackPower":9,"attackRange":5.0,"cannotSell":true,"generalLife":40,"itemBuyingPrice":70,"itemSellingPrice":18,"profile":"WeaponSpear"},"Weapon_Spear_028":{"attackPower":12,"attackRange":5.0,"cannotSell":true,"generalLife":40,"itemBuyingPrice":220,"itemSellingPrice":55,"profile":"WeaponSpear"},"Weapon_Spear_029":{"attackPower":16,"attackRange":5.0,"cannotSell":true,"generalLife":35,"itemBuyingPrice":90,"itemSellingPrice":22,"profile":"WeaponSpear"},"Weapon_Spear_030":{"attackPower":6,"attackRange":5.0,"cannotSell":true,"generalLife":20,"itemBuyingPrice":20,"itemSellingPrice":7,"profile":"WeaponSpear"},"Weapon_Spear_031":{"attackPower":14,"attackRange":5.0,"cannotSell":true,"generalLife":50,"itemBuyingPrice":30,"itemSellingPrice":8,"profile":"WeaponSpear"},"Weapon_Spear_032":{"attackPower":10,"attackRange":5.0,"cannotSell":true,"generalLife":35,"itemBuyingPrice":30,"itemSellingPrice":8,"profile":"WeaponSpear"},"Weapon_Spear_033":{"attackPower":24,"attackRange":5.0,"cannotSell":true,"generalLife":50,"itemBuyingPrice":450,"itemSellingPrice":150,"profile":"WeaponSpear"},"Weapon_Spear_034":{"attackPower":20,"attackRange":5.0,"cannotSell":true,"generalLife":40,"itemBuyingPrice":450,"itemSellingPrice":150,"profile":"WeaponSpear"},"Weapon_Spear_035":{"attackPower":22,"attackRange":5.0,"cannotSell":true,"generalLife":50,"itemBuyingPrice":450,"itemSellingPrice":150,"profile":"WeaponSpear"},"Weapon_Spear_036":{"attackPower":5,"attackRange":5.0,"cannotSell":true,"generalLife":8,"itemBuyingPrice":3,"itemSellingPrice":1,"profile":"WeaponSpear"},"Weapon_Spear_037":{"attackPower":12,"attackRange":5.0,"cannotSell":true,"generalLife":35,"itemBuyingPrice":130,"itemSellingPrice":32,"profile":"WeaponSpear"},"Weapon_Spear_038":{"attackPower":8,"attackRange":5.0,"cannotSell":true,"generalLife":12,"itemBuyingPrice":20,"itemSellingPrice":7,"profile":"WeaponSpear"},"Weapon_Spear_047":{"attackPower":32,"attackRange":5.0,"cannotSell":true,"generalLife":15,"itemBuyingPrice":120,"itemSellingPrice":100,"profile":"WeaponSpear"},"Weapon_Spear_049":{"attackPower":14,"attackRange":5.0,"cannotSell":true,"generalLife":40,"itemBuyingPrice":400,"itemSellingPrice":100,"profile":"WeaponSpear"},"Weapon_Spear_050":{"attackPower":22,"attackRange":5.0,"cannotSell":true,"generalLife":70,"itemBuyingPrice":400,"itemSellingPrice":100,"profile":"WeaponSpear"},"Weapon_Spear_080":{"attackPower":22,"attackRange":5.0,"generalLife":70,"itemBuyingPrice":400,"itemSellingPrice":100,"profile":"WeaponSpear"},"Weapon_Sword_001":{"attackPower":5,"attackRange":1.6,"cannotSell":true,"generalLife":20,"itemBuyingPrice":20,"itemSellingPrice":5,"profile":"WeaponSmallSword"},"Weapon_Sword_002":{"attackPower":14,"attackRange":1.6,"cannotSell":true,"generalLife":23,"itemBuyingPrice":70,"itemSellingPrice":18,"profile":"WeaponSmallSword"},"Weapon_Sword_003":{"attackPower":26,"attackRange":1.6,"cannotSell":true,"generalLife":27,"itemBuyingPrice":180,"itemSellingPrice":45,"profile":"WeaponSmallSword"},"Weapon_Sword_004":{"attackPower":4,"attackRange":1.6,"cannotSell":true,"generalLife":12,"itemBuyingPrice":9,"itemSellingPrice":5,"profile":"WeaponSmallSword"},"Weapon_Sword_005":{"attackPower":12,"attackRange":1.6,"cannotSell":true,"generalLife":14,"itemBuyingPrice":15,"itemSellingPrice":10,"profile":"WeaponSmallSword"},"Weapon_Sword_006":{"attackPower":24,"attackRange":1.6,"cannotSell":true,"generalLife":18,"itemBuyingPrice":24,"itemSellingPrice":15,"profile":"WeaponSmallSword"},"Weapon_Sword_007":{"attackPower":14,"attackRange":1.6,"cannotSell":true,"generalLife":17,"itemBuyingPrice":24,"itemSellingPrice":10,"profile":"WeaponSmallSword"},"Weapon_Sword_008":{"attackPower":24,"attackRange":1.6,"cannotSell":true,"generalLife":23,"itemBuyingPrice":45,"itemSellingPrice":20,"profile":"WeaponSmallSword"},"Weapon_Sword_009":{"attackPower":36,"attackRange":1.6,"cannotSell":true,"generalLife":27,"itemBuyingPrice":69,"itemSellingPrice":30,"profile":"WeaponSmallSword"},"Weapon_Sword_013":{"attackPower":20,"attackRange":1.6,"cannotSell":true,"generalLife":17,"itemBuyingPrice":39,"itemSellingPrice":15,"profile":"WeaponSmallSword"},"Weapon_Sword_014":{"attackPower":30,"attackRange":1.6,"cannotSell":true,"generalLife":26,"itemBuyingPrice":75,"itemSellingPrice":30,"profile":"WeaponSmallSword"},"Weapon_Sword_015":{"attackPower":40,"attackRange":1.6,"cannotSell":true,"generalLife":32,"itemBuyingPrice":114,"itemSellingPrice":45,"profile":"WeaponSmallSword"},"Weapon_Sword_016":{"attackPower":24,"attackRange":1.6,"cannotSell":true,"generalLife":26,"itemBuyingPrice":45,"itemSellingPrice":18,"profile":"WeaponSmallSword"},"Weapon_Sword_017":{"attackPower":36,"attackRange":1.6,"cannotSell":true,"generalLife":32,"itemBuyingPrice":90,"itemSellingPrice":35,"profile":"WeaponSmallSword"},"Weapon_Sword_018":{"attackPower":58,"attackRange":1.6,"cannotSell":true,"generalLife":41,"itemBuyingPrice":135,"itemSellingPrice":52,"profile":"WeaponSmallSword"},"Weapon_Sword_019":{"attackPower":5,"attackRange":1.6,"cannotSell":true,"generalLife":5,"itemBuyingPrice":1,"itemSellingPrice":1,"profile":"WeaponSmallSword"},"Weapon_Sword_020":{"attackPower":12,"attackRange":1.6,"cannotSell":true,"generalLife":8,"itemBuyingPrice":1,"itemSellingPrice":1,"profile":"WeaponSmallSword"},"Weapon_Sword_021":{"attackPower":6,"attackRange":1.6,"cannotSell":true,"generalLife":8,"itemBuyingPrice":20,"itemSellingPrice":5,"profile":"WeaponSmallSword"},"Weapon_Sword_022":{"attackPower":4,"attackRange":1.6,"cannotSell":true,"generalLife":5,"itemBuyingPrice":20,"itemSellingPrice":5,"profile":"WeaponSmallSword"},"Weapon_Sword_023":{"attackPower":40,"attackRange":1.6,"cannotSell":true,"generalLife":54,"itemBuyingPrice":20,"itemCreatingPrice":1000,"itemSellingPrice":5,"profile":"WeaponSmallSword"},"Weapon_Sword_024":{"attackPower":36,"attackRange":1.6,"cannotSell":true,"generalLife":36,"itemBuyingPrice":320,"itemSellingPrice":80,"profile":"WeaponSmallSword"},"Weapon_Sword_025":{"attackPower":22,"attackRange":1.6,"cannotSell":true,"generalLife":27,"itemBuyingPrice":25,"itemSellingPrice":6,"profile":"WeaponSmallSword"},"Weapon_Sword_027":{"attackPower":15,"attackRange":1.6,"cannotSell":true,"generalLife":27,"itemBuyingPrice":70,"itemSellingPrice":18,"profile":"WeaponSmallSword"},"Weapon_Sword_029":{"attackPower":16,"attackRange":1.6,"cannotSell":true,"generalLife":23,"itemBuyingPrice":120,"itemSellingPrice":30,"profile":"WeaponSmallSword"},"Weapon_Sword_030":{"attackPower":25,"attackRange":1.6,"cannotSell":true,"generalLife":32,"itemBuyingPrice":220,"itemSellingPrice":55,"profile":"WeaponSmallSword"},"Weapon_Sword_031":{"attackPower":15,"attackRange":1.6,"cannotSell":true,"generalLife":27,"itemBuyingPrice":12,"itemSellingPrice":3,"profile":"WeaponSmallSword"},"Weapon_Sword_033":{"attackPower":24,"attackRange":1.6,"cannotSell":true,"generalLife":36,"itemBuyingPrice":150,"itemSellingPrice":150,"profile":"WeaponSmallSword"},"Weapon_Sword_034":{"attackPower":20,"attackRange":1.6,"cannotSell":true,"generalLife":30,"itemBuyingPrice":150,"itemSellingPrice":150,"profile":"WeaponSmallSword"},"Weapon_Sword_035":{"attackPower":22,"attackRange":1.6,"cannotSell":true,"generalLife":36,"itemBuyingPrice":150,"itemSellingPrice":150,"profile":"WeaponSmallSword"},"Weapon_Sword_040":{"attackPower":1,"attackRange":1.6,"cannotSell":true,"generalLife":80,"itemBuyingPrice":15,"itemSellingPrice":2,"profile":"WeaponSmallSword"},"Weapon_Sword_041":{"attackPower":15,"attackRange":1.6,"cannotSell":true,"generalLife":26,"itemBuyingPrice":110,"itemSellingPrice":28,"profile":"WeaponSmallSword"},"Weapon_Sword_043":{"attackPower":2,"attackRange":1.6,"cannotSell":true,"generalLife":8,"itemBuyingPrice":9,"itemSellingPrice":2,"profile":"WeaponSmallSword"},"Weapon_Sword_044":{"attackPower":2,"attackRange":1.6,"cannotSell":true,"generalLife":4,"itemBuyingPrice":3,"itemSellingPrice":1,"profile":"WeaponSmallSword"},"Weapon_Sword_047":{"attackPower":48,"attackRange":1.6,"cannotSell":true,"generalLife":14,"itemBuyingPrice":120,"itemSellingPrice":100,"profile":"WeaponSmallSword"},"Weapon_Sword_048":{"attackPower":10,"attackRange":30.0,"cannotSell":true,"generalLife":32,"itemBuyingPrice":120,"itemSellingPrice":18,"profile":"WeaponSmallSword"},"Weapon_Sword_049":{"attackPower":10,"attackRange":15.0,"cannotSell":true,"generalLife":32,"itemBuyingPrice":120,"itemSellingPrice":18,"profile":"WeaponSmallSword"},"Weapon_Sword_050":{"attackPower":10,"attackRange":30.0,"cannotSell":true,"generalLife":32,"itemBuyingPrice":120,"itemSellingPrice":18,"profile":"WeaponSmallSword"},"Weapon_Sword_051":{"attackPower":8,"attackRange":1.6,"cannotSell":true,"generalLife":18,"itemBuyingPrice":100,"itemSellingPrice":25,"profile":"WeaponSmallSword"},"Weapon_Sword_052":{"attackPower":32,"attackRange":1.6,"cannotSell":true,"generalLife":60,"itemBuyingPrice":400,"itemSellingPrice":100,"profile":"WeaponSmallSword"},"Weapon_Sword_053":{"attackPower":16,"attackRange":1.0,"cannotSell":true,"generalLife":14,"itemBuyingPrice":50,"itemSellingPrice":12,"profile":"WeaponSmallSword"},"Weapon_Sword_056":{"attackPower":1,"profile":"WeaponSmallSword"},"Weapon_Sword_057":{"attackPower":28,"attackRange":1.6,"cannotSell":true,"generalLife":45,"itemBuyingPrice":20,"itemSellingPrice":5,"profile":"WeaponSmallSword"},"Weapon_Sword_058":{"attackPower":22,"attackRange":1.6,"cannotSell":true,"generalLife":27,"itemBuyingPrice":20,"itemSellingPrice":5,"profile":"WeaponSmallSword"},"Weapon_Sword_059":{"attackPower":20,"attackRange":1.6,"cannotSell":true,"generalLife":20,"itemBuyingPrice":100,"itemSellingPrice":25,"profile":"WeaponSmallSword"},"Weapon_Sword_060":{"attackPower":5,"attackRange":20.0,"cannotSell":true,"generalLife":14,"itemBuyingPrice":120,"itemSellingPrice":18,"profile":"WeaponSmallSword"},"Weapon_Sword_061":{"attackPower":5,"attackRange":15.0,"cannotSell":true,"generalLife":14,"itemBuyingPrice":120,"itemSellingPrice":18,"profile":"WeaponSmallSword"},"Weapon_Sword_062":{"attackPower":5,"attackRange":20.0,"cannotSell":true,"generalLife":14,"itemBuyingPrice":120,"itemSellingPrice":18,"profile":"WeaponSmallSword"},"Weapon_Sword_070":{"attackPower":30,"attackRange":1.6,"cannotSell":true,"generalLife":40,"itemBuyingPrice":1,"itemSellingPrice":1,"profile":"WeaponSmallSword"},"Weapon_Sword_073":{"attackPower":40,"attackRange":1.6,"cannotSell":true,"generalLife":25,"profile":"WeaponSmallSword"},"Weapon_Sword_080":{"cannotSell":true,"profile":"WeaponSmallSword"},"Weapon_Sword_081":{"cannotSell":true,"profile":"WeaponSmallSword"},"Weapon_Sword_502":{"attackPower":1,"attackRange":1.6,"cannotSell":true,"generalLife":40,"itemBuyingPrice":1,"itemSellingPrice":1,"profile":"WeaponSmallSword"},"Weapon_Sword_503":{"attackPower":1,"attackRange":1.6,"generalLife":40,"itemBuyingPrice":1,"itemSellingPrice":1,"profile":"WeaponSmallSword"},"Wizzrobe_WeatherFireBall":{"attackPower":20,"profile":"MapDynamicActive"},"Wizzrobe_WeatherIceBall":{"attackRange":100.0,"profile":"Bullet"},"dyecolor_00":{"itemBuyingPrice":20,"itemStainColor":4,"profile":"Item"},"dyecolor_01":{"itemBuyingPrice":20,"itemStainColor":1,"profile":"Item"},"dyecolor_02":{"itemBuyingPrice":20,"itemStainColor":2,"profile":"Item"},"dyecolor_03":{"itemBuyingPrice":20,"itemStainColor":3,"profile":"Item"},"dyecolor_04":{"itemBuyingPrice":20,"itemStainColor":4,"profile":"Item"},"dyecolor_05":{"itemBuyingPrice":20,"itemStainColor":5,"profile":"Item"},"dyecolor_06":{"itemBuyingPrice":20,"itemStainColor":6,"profile":"Item"},"dyecolor_07":{"itemBuyingPrice":20,"itemStainColor":7,"profile":"Item"},"dyecolor_08":{"itemBuyingPrice":20,"itemStainColor":8,"profile":"Item"},"dyecolor_09":{"itemBuyingPrice":20,"itemStainColor":9,"profile":"Item"},"dyecolor_10":{"itemBuyingPrice":20,"itemStainColor":10,"profile":"Item"},"dyecolor_11":{"itemBuyingPrice":20,"itemStainColor":11,"profile":"Item"},"dyecolor_12":{"itemBuyingPrice":20,"itemStainColor":12,"profile":"Item"},"dyecolor_13":{"itemBuyingPrice":20,"itemStainColor":13,"profile":"Item"},"dyecolor_14":{"itemBuyingPrice":20,"itemStainColor":14,"profile":"Item"},"dyecolor_15":{"itemBuyingPrice":20,"itemStainColor":15,"profile":"Item"}}`);
diff --git a/packages/item-system/src/data/ActorData.ts b/packages/item-system/src/data/ActorData.ts
new file mode 100644
index 0000000..2839760
--- /dev/null
+++ b/packages/item-system/src/data/ActorData.ts
@@ -0,0 +1,152 @@
+import { SpecialStatus } from "./enums.ts";
+import { ActorDataMap } from "./ActorData.gen.ts";
+
+export const DefaultActorData = {
+ /**
+ * The profile user of the actor
+ *
+ * Note that if the actor doesn't have any of the other
+ * data properties, this won't be set
+ */
+ profile: "Unknown" as string,
+
+ /**
+ * Whether the item is stackable (has CanStack tag)
+ */
+ canStack: false as boolean,
+
+ /** Whether the item not is sellable (has CannotSell tag) */
+ cannotSell: false as boolean,
+
+ /**
+ * The derived special status to display
+ *
+ * This could be:
+ * - SpreadFire for bows, derived from bowIsLeadShot
+ * - Armor effect, derived from armorEffectEffectType
+ */
+ specialStatus: SpecialStatus.None as SpecialStatus,
+
+ // default gparam comes from Dummy.gparamlist.yaml
+
+ /**
+ * [GParam] raw string value for armor effects
+ */
+ armorEffectEffectType: "None" as string,
+
+ /**
+ * Derived from GParam. However, will be 0 unless
+ * bowIsRapidFire is true
+ */
+ bowRapidFireNum: 0 as number,
+
+ /**
+ * [GParam] value for multi shot bows
+ * Some non-multishot bows also have this set to 3, even 5
+ */
+ bowLeadShotNum: 0 as number,
+
+ /**
+ * [GParam] Angle for spread fire bows, in degrees. Interestingly,
+ * this is set to 13 for some non-multishot bows. For multishot
+ * bows, this is 3
+ */
+ bowLeadShotAng: 45 as number,
+
+ /**
+ * [GParam] Number of frames per shot for multishot bows
+ * This is usually 1 for multishot bows
+ */
+ bowLeadShotInterval: 0 as number,
+
+ /**
+ * [GParam] (probably) initial speed of the arrow
+ * This is 8 for RGB
+ */
+ bowArrowFirstSpeed: 4.5 as number,
+
+ /**
+ * [GParam] (probably) terminal speed of the arrow (4 for ancient)
+ * bowArrowAcceleration is -0.1 for all bows
+ */
+ bowArrowStabilitySpeed: 3 as number,
+
+ /**
+ * [GParam] gravity constant experienced by arrows fired by the bow
+ *
+ * This is -7 for silver, -2.8 for ancient
+ */
+ bowArrowGravity: -9.8 as number,
+
+ /** [GParam] Misleading name. This is if the bow has default zoom */
+ bowIsLongRange: false as boolean,
+
+ /**
+ * [GParam] How fast the bow charges. Higher means
+ * bow takes shorter from pressing ZR to ready to fire
+ * - Higher for falcon, swallow, GEB, RGB
+ * - Ancient is 0.7
+ *
+ * This also (probably) determines how many arrows
+ * can come out of multishot. Probably min(ceil(1 / bowArrowChargeRate), 10)
+ */
+ bowArrowChargeRate: 1 as number,
+
+ /**
+ * [GParam] How fast the bow reloads. Lower means
+ * bow takes shorter to be able to fire again after firing
+ *
+ * This is 0.8 for RGB
+ */
+ bowArrowReloadRate: 1 as number,
+
+ /** [GParam] If the bow is ancient bow */
+ bowIsGuardPierce: false as boolean,
+
+ /** [GParam] Power for weapon/bow/shield(bashing) */
+ attackPower: 0 as number,
+
+ /** [GParam] Range for weapon/bow/shield */
+ attackRange: 0 as number,
+
+ /** [GParam] Durability */
+ generalLife: 100 as number,
+
+ /** [GParam] If durability decreases with use */
+ generalIsLifeInfinite: false as boolean,
+
+ /** [GParam] selling price */
+ itemSellingPrice: -1 as number,
+ /** [GParam] buying price */
+ itemBuyingPrice: -1 as number,
+ /** [GParam] creating price */
+ itemCreatingPrice: -1 as number,
+
+ /** [GParam] If the item is a dye, the color of it */
+ itemStainColor: -1 as number,
+
+ /** [GParam] Guard power for shields */
+ weaponCommonGuardPower: 0 as number,
+
+ /** [GParam] 0 for not armor, 1-5 for no star to 4 star */
+ armorStarNum: 0 as number,
+
+ /** [GParam] Defense for armor */
+ armorDefenceAddLevel: 0 as number,
+} as const;
+
+export type ActorData = typeof DefaultActorData;
+
+/** Get the data property of the actor, or default if the actor doesn't have the property */
+export const getActorParam = (actor: string, key: K): ActorData[K] => {
+ const data = ActorDataMap[actor];
+ if (!data || !(key in data)) {
+ return DefaultActorData[key];
+ }
+ return data[key];
+}
+
+/** Check if the actor has the property */
+export const hasActorParam = (actor: string, key: K): boolean => {
+ return key in ActorDataMap[actor];
+}
diff --git a/packages/item-system/src/data/ItemSlotInfo.ts b/packages/item-system/src/data/ItemSlotInfo.ts
new file mode 100644
index 0000000..4b3e41d
--- /dev/null
+++ b/packages/item-system/src/data/ItemSlotInfo.ts
@@ -0,0 +1,112 @@
+import type { CookEffect, ItemUse, PouchItemType } from "./enums.ts";
+
+/**
+ * Information to display an item slot
+ *
+ * These are data derived from the native PouchItem class
+ * and simulator runtime info. Data that can be looked up
+ * from the item's parameters should not be included here.
+ */
+export type ItemSlotInfo = {
+ /**
+ * Name of the actor, from PouchItem::mName
+ *
+ * This is what will be used to look up extra data for the item
+ */
+ actorName: string,
+
+ /**
+ * PouchItem::mType
+ *
+ * Note this is raw memory value and may not be a valid enum value
+ */
+ itemType: PouchItemType | number,
+
+ /**
+ * PouchItem::mItemUse
+ *
+ * Note this is raw memory value and may not be a valid enum value
+ */
+ itemUse: ItemUse | number,
+
+ /**
+ * PouchItem::mValue
+ *
+ * This is stack size or durability * 100
+ */
+ value: number,
+
+ /** PouchItem::mEquipped */
+ isEquipped: boolean,
+
+ /** PouchItem::mInInventory */
+ isInInventory: boolean,
+
+ /**
+ * This is either the weapon modifier value,
+ * or the HP recovery value for food (in quarter-hearts)
+ */
+ modEffectValue: number,
+
+ /**
+ * For food with a timed effect, this is the duration in seconds.
+ * For stamina, this is the raw value
+ */
+ modEffectDuration: number,
+
+ /**
+ * For weapon modifier, this is the flag bitset. For food,
+ * this is the sell price
+ */
+ modSellPrice: number,
+
+ /**
+ * Effect ID for the food
+ *
+ * Note this is raw memory value and may not be a valid enum value
+ */
+ modEffectId: CookEffect | number,
+
+ /**
+ * The level of the effect, *usually* 1-3. However this
+ * is the raw memory value and may not be valid
+ */
+ modEffectLevel: number,
+
+ /**
+ * PouchItem::mIngredients. Length should always be 5
+ */
+ ingredientActorNames: string[],
+
+ /**
+ * The item's position in the item list.
+ *
+ * If the item is in the unallocated pool, this is its position
+ * in the unallocated pool (stack). 0 is the top of the stack/beginning
+ * of the list
+ */
+ listPosition: number,
+
+ /** If the item is currently in the unallocated pool */
+ unallocated: boolean,
+
+ /**
+ * The item's position in the pool
+ *
+ * This basically serves as a unique pointer to the item
+ */
+ poolPosition: number,
+
+ /** If the item is in "broken" slot, i.e. will be transferred on reload */
+ isInBrokenSlot: boolean,
+
+ /**
+ * Number of items held if the item is being held by the player
+ */
+ holdingCount: number,
+
+ /**
+ * Enable the prompt entangled state for this slot
+ */
+ promptEntangled: boolean,
+}
diff --git a/packages/item-system/src/data/ModifierInfo.ts b/packages/item-system/src/data/ModifierInfo.ts
new file mode 100644
index 0000000..2ca7086
--- /dev/null
+++ b/packages/item-system/src/data/ModifierInfo.ts
@@ -0,0 +1,256 @@
+import { getActorParam } from "./ActorData.ts";
+import { CookEffect, effectToStatus, modifierToStatus, PouchItemType, SpecialStatus, WeaponModifier } from "./enums.ts";
+import type { ItemSlotInfo } from "./ItemSlotInfo.ts";
+
+/** Modifier display info derived from ItemSlotInfo and ActorData */
+export type ModifierInfo = {
+ /** The special status to display on the item slot */
+ status: SpecialStatus
+ /**
+ * The icon to display for the special status
+ *
+ * Some status corresponds to multiple icons, like AddPower
+ * for weapon and bow
+ */
+ statusIcon: string,
+
+ /** Value to display next to the modifier icon in the item slot */
+ iconValue: string,
+
+ /** Extra details for each of the weapon modifiers */
+ details: ModifierDetail[],
+
+};
+
+/** Extra detail for each of the weapon modifiers */
+export type ModifierDetail = {
+ /** The special status corresponding to the modifier */
+ status: SpecialStatus,
+ /** The special status icon corresponding to the modifier */
+ statusIcon: string,
+ /** If the modifier is active on the item type */
+ active: boolean,
+ /**
+ * The display value of the modifier
+ *
+ * Number for AddPower, AddGuard, SpreadFire, percentage
+ * for LongThrow, RapidFire, SurfMaster
+ */
+ modifierValue: string,
+}
+
+
+
+/** Get the modifier info for an item slot */
+export const getModifierInfo = (info: ItemSlotInfo): ModifierInfo => {
+ const { actorName, itemType, modEffectId, modSellPrice } = info;
+ // only display WeaponModifier for equipments
+ if (itemType === PouchItemType.Sword || itemType === PouchItemType.Bow || itemType === PouchItemType.Shield) {
+ return getModifierInfoForEquipments(info);
+ }
+ // get from cook data
+ let status = SpecialStatus.None;
+ if (modEffectId !== CookEffect.None) {
+ status = effectToStatus(modEffectId);
+ }
+ const defaultData = getDefaultModifierInfoForActor(actorName);
+ // override status if any
+ if (status !== SpecialStatus.None) {
+ defaultData.status = status;
+ defaultData.statusIcon = SpecialStatus[status];
+ }
+ // display price if it's odd, because it's probably used for WMC
+ const iconValue = (modSellPrice > 1 && modSellPrice % 2 === 1) ? `$${modSellPrice}` : "";
+ defaultData.iconValue = iconValue;
+
+ return defaultData;
+}
+
+export const getModifierInfoForEquipments = (info: ItemSlotInfo): ModifierInfo => {
+ const { actorName, itemType, modEffectValue, modSellPrice } = info;
+ const specialStatus = getWeaponSpecialStatusToDisplay(modSellPrice);
+ let iconValue = 0;
+
+ if (specialStatus === SpecialStatus.None) {
+ return getDefaultModifierInfoForActor(actorName);
+ }
+
+ // only display value for AddPower and AddGuard
+ if (specialStatus === SpecialStatus.AddPower) {
+ iconValue += modEffectValue;
+ }
+ // value is doubled if both AddPower and AddGuard are present for shields
+ if (itemType === PouchItemType.Shield && (modSellPrice & WeaponModifier.AddGuard) !== 0) {
+ iconValue += modEffectValue;
+ }
+
+ // Fix multishot icon
+ let statusIcon = SpecialStatus[specialStatus];
+ if (specialStatus === SpecialStatus.SpreadFire) {
+ statusIcon = getMultishotIcon(modEffectValue);
+ }
+
+ // Fix bow attack up
+ if (itemType === PouchItemType.Bow) {
+ if (specialStatus === SpecialStatus.AddPower) {
+ statusIcon = "AddPower_Bow";
+ } else if (specialStatus === SpecialStatus.AddPowerPlus) {
+ statusIcon = "AddPowerPlus_Bow";
+ }
+ }
+
+ // get effect details
+ const details: ModifierDetail[] = [];
+ const yellow = (modSellPrice & WeaponModifier.Yellow) !== 0;
+ if (modSellPrice & WeaponModifier.AddPower) {
+ details.push({
+ status: SpecialStatus.AddPower,
+ statusIcon: itemType === PouchItemType.Bow ? (yellow ? "AddPowerPlus_Bow" : "AddPower_Bow") : (yellow?"AddPowerPlus":"AddPower"),
+ active: true, // attack up is always active
+ modifierValue: `${modEffectValue}`,
+ });
+ }
+ if (modSellPrice & WeaponModifier.AddLife) {
+ details.push({
+ status: SpecialStatus.AddLife,
+ statusIcon: yellow ? "AddLifePlus" : "AddLife",
+ active: true, // durability up, always active, although it doesn't do anything
+ modifierValue: ""
+ });
+ }
+ if (modSellPrice & WeaponModifier.AddGuard) {
+ details.push({
+ status: SpecialStatus.AddGuard,
+ statusIcon: yellow ? "AddGuardPlus" : "AddGuard",
+ active: itemType === PouchItemType.Shield,
+ modifierValue: `${modEffectValue}`
+ });
+ }
+ if (modSellPrice & WeaponModifier.Critical) {
+ details.push({
+ status: SpecialStatus.Critical,
+ statusIcon: "Critical",
+ active: itemType === PouchItemType.Sword,
+ modifierValue: ""
+ });
+ }
+ if (modSellPrice & WeaponModifier.LongThrow) {
+ details.push({
+ status: SpecialStatus.LongThrow,
+ statusIcon: "LongThrow",
+ active: itemType === PouchItemType.Sword,
+ modifierValue: getModifierPercentDifference(modEffectValue)
+ });
+ }
+ if (modSellPrice & WeaponModifier.SpreadFire) {
+ // This is guess on how it works based on experience
+ // multishot is capped at 10. The faster the bow shoots, fewer arrows come out
+ const bowChargeRate = getActorParam(actorName, "bowArrowChargeRate");
+ const quickShotMultiplier = (modSellPrice & WeaponModifier.RapidFire) !== 0 ? (modEffectValue / 1000) : 1;
+ const multishot = 10 / (bowChargeRate * quickShotMultiplier);
+ const modifierValue = multishot >= 10 ? "10" : `~${multishot.toFixed(2)}`;
+ details.push({
+ status: SpecialStatus.SpreadFire,
+ statusIcon: getMultishotIcon(modEffectValue),
+ active: itemType === PouchItemType.Bow,
+ modifierValue
+ });
+ }
+ if (modSellPrice & WeaponModifier.Zoom) {
+ details.push({
+ status: SpecialStatus.Zoom,
+ statusIcon: "Zoom",
+ active: itemType === PouchItemType.Bow,
+ modifierValue: ""
+ });
+ }
+ if (modSellPrice & WeaponModifier.RapidFire) {
+ details.push({
+ status: SpecialStatus.RapidFire,
+ statusIcon: "RapidFire",
+ active: itemType === PouchItemType.Bow,
+ modifierValue: getModifierPercentDifference(modEffectValue)
+ });
+ }
+ if (modSellPrice & WeaponModifier.SurfMaster) {
+ details.push({
+ status: SpecialStatus.SurfMaster,
+ statusIcon: "SurfMaster",
+ active: itemType === PouchItemType.Shield,
+ modifierValue: getModifierPercentDifference(modEffectValue)
+ });
+ }
+
+ return {
+ status: specialStatus,
+ statusIcon,
+ iconValue: iconValue ? `+${iconValue}` : "",
+ details,
+ }
+}
+
+const getWeaponSpecialStatusToDisplay = (modifierSet: number): SpecialStatus => {
+ // 0x7100aa7290 in 1.5.0
+ // https://discord.com/channels/269611402854006785/269616041435332608/1041497732474482698
+ // select the modifier to display from the bitset
+ const applicableModifiers = [
+ WeaponModifier.AddPower,
+ WeaponModifier.AddLife,
+ WeaponModifier.AddGuard,
+ WeaponModifier.Critical,
+ WeaponModifier.LongThrow,
+ WeaponModifier.SpreadFire,
+ WeaponModifier.Zoom,
+ WeaponModifier.RapidFire,
+ WeaponModifier.SurfMaster,
+ ];
+
+ let selectedModifier: WeaponModifier = WeaponModifier.None;
+ for (let i = 0; i < applicableModifiers.length; i++) {
+ if (
+ (applicableModifiers[i] & modifierSet) !==
+ WeaponModifier.None
+ ) {
+ selectedModifier = applicableModifiers[i];
+ break;
+ }
+ }
+
+ return modifierToStatus(selectedModifier, (modifierSet & WeaponModifier.Yellow) !== 0);
+}
+
+export const getDefaultModifierInfoForActor = (actorName: string): ModifierInfo => {
+ const status = getActorParam(actorName, "specialStatus");
+
+ let statusIcon = SpecialStatus[status];
+ // convert to the correct multishot icon
+ if (status === SpecialStatus.SpreadFire) {
+ const num = getActorParam(actorName, "bowLeadShotNum");
+ statusIcon = getMultishotIcon(num);
+ }
+ return {
+ status,
+ statusIcon,
+ iconValue: "",
+ details: [],
+ }
+}
+
+export const getMultishotIcon = (num: number): string => {
+ if (num <= 3) {
+ return "SpreadFire_3";
+ }
+ if (num <= 5) {
+ return "SpreadFire_5";
+ }
+ return "SpreadFire_X";
+}
+
+const getModifierPercentDifference = (value: number): string => {
+ if (value === 1000) {
+ return "0%";
+ }
+ const percentage = (value - 1000) / 10;
+
+ return `${percentage > 0 ? "+" : ""}${percentage.toFixed(1)}%`;
+};
diff --git a/packages/item-system/src/data/enums.ts b/packages/item-system/src/data/enums.ts
new file mode 100644
index 0000000..fa60fcc
--- /dev/null
+++ b/packages/item-system/src/data/enums.ts
@@ -0,0 +1,165 @@
+
+/**
+ * uking::ui::PouchItemType
+ */
+export enum PouchItemType {
+ Sword = 0,
+ Bow = 1,
+ Arrow = 2,
+ Shield = 3,
+ ArmorHead = 4,
+ ArmorUpper = 5,
+ ArmorLower = 6,
+ Material = 7,
+ Food = 8,
+ KeyItem = 9,
+ Invalid = -1,
+}
+
+/**
+ * uking::ui::ItemUse
+ */
+export enum ItemUse {
+ WeaponSmallSword = 0,
+ WeaponLargeSword = 1,
+ WeaponSpear = 2,
+ WeaponBow = 3,
+ WeaponShield = 4,
+ ArmorHead = 5,
+ ArmorUpper = 6,
+ ArmorLower = 7,
+ Item = 8,
+ ImportantItem = 9,
+ CureItem = 10,
+ Invalid = -1,
+}
+
+/** uking::CookEffectId */
+export enum CookEffect {
+ None = -1,
+ LifeRecover = 1,
+ LifeMaxUp = 2,
+ ResistHot = 4,
+ ResistCold = 5,
+ ResistElectric = 6,
+ AttackUp = 10,
+ DefenseUp = 11,
+ Quietness = 12,
+ // note the name we use internally for skybook is different
+ // for decomp, it's MovingSpeed
+ AllSpeed = 13,
+ GutsRecover = 14,
+ ExGutsMaxUp = 15,
+ Fireproof = 16,
+}
+
+/**
+ * Internal used special status enum
+ *
+ * These correspond to modifier icons
+ * These are used in generated data - DO NOT CHANGE
+ */
+export enum SpecialStatus {
+ None = 0,
+ AddGuard = 1,
+ AddGuardPlus,
+ AddLife,
+ AddLifePlus,
+ AddPower,
+ AddPowerPlus,
+ AllSpeed,
+ AttackUp,
+ ClimbSpeedUp,
+ Critical,
+ DefenseUp,
+ ExGutsMaxUp,
+ Fireproof, // "ResistBurn", not the fire-immunity effect
+ GutsRecover,
+ LifeMaxUp,
+ LongThrow,
+ Quietness,
+ RapidFire,
+ ReduceAncientEnemyDamge, // not a typo
+ ResistCold,
+ ResistElectric,
+ ResistFreeze,
+ ResistHot,
+ ResistLightning,
+ SandMoveSpeedUp,
+ SnowMovingSpeed,
+ SpreadFire,
+ SurfMaster,
+ SwimSpeedUp,
+ Zoom,
+}
+
+/** uking::act::WeaponModifier */
+export const WeaponModifier = {
+ None: 0x0,
+ AddPower: 0x1,
+ AddLife: 0x2,
+ Critical: 0x4,
+ LongThrow: 0x8,
+ SpreadFire: 0x10,
+ Zoom: 0x20,
+ RapidFire: 0x40,
+ SurfMaster: 0x80,
+ AddGuard: 0x100,
+ Yellow: 0x80000000
+} as const;
+
+export type WeaponModifier = typeof WeaponModifier[keyof typeof WeaponModifier];
+
+/** Convert a WeaponModifier to a SpecialStatus */
+export const modifierToStatus = (modifier: WeaponModifier, yellow: boolean): SpecialStatus => {
+ switch(modifier) {
+ case WeaponModifier.AddPower:
+ return yellow ? SpecialStatus.AddPowerPlus : SpecialStatus.AddPower;
+ case WeaponModifier.AddLife:
+ return yellow ? SpecialStatus.AddLifePlus : SpecialStatus.AddLife;
+ case WeaponModifier.AddGuard:
+ return yellow ? SpecialStatus.AddGuardPlus : SpecialStatus.AddGuard;
+ case WeaponModifier.Critical:
+ return SpecialStatus.Critical;
+ case WeaponModifier.LongThrow:
+ return SpecialStatus.LongThrow;
+ case WeaponModifier.SpreadFire:
+ return SpecialStatus.SpreadFire;
+ case WeaponModifier.Zoom:
+ return SpecialStatus.Zoom;
+ case WeaponModifier.RapidFire:
+ return SpecialStatus.RapidFire;
+ case WeaponModifier.SurfMaster:
+ return SpecialStatus.SurfMaster;
+ }
+ return SpecialStatus.None;
+}
+
+/** Convert a CookEffect to a SpecialStatus */
+export const effectToStatus = (effect: CookEffect): SpecialStatus => {
+ switch(effect) {
+ case CookEffect.LifeMaxUp:
+ return SpecialStatus.LifeMaxUp;
+ case CookEffect.ResistHot:
+ return SpecialStatus.ResistHot;
+ case CookEffect.ResistCold:
+ return SpecialStatus.ResistCold;
+ case CookEffect.ResistElectric:
+ return SpecialStatus.ResistElectric;
+ case CookEffect.AttackUp:
+ return SpecialStatus.AttackUp;
+ case CookEffect.DefenseUp:
+ return SpecialStatus.DefenseUp;
+ case CookEffect.Quietness:
+ return SpecialStatus.Quietness;
+ case CookEffect.AllSpeed:
+ return SpecialStatus.AllSpeed;
+ case CookEffect.GutsRecover:
+ return SpecialStatus.GutsRecover;
+ case CookEffect.ExGutsMaxUp:
+ return SpecialStatus.ExGutsMaxUp;
+ case CookEffect.Fireproof:
+ return SpecialStatus.Fireproof;
+ }
+ return SpecialStatus.None;
+}
diff --git a/packages/item-system/src/index.ts b/packages/item-system/src/index.ts
new file mode 100644
index 0000000..e69de29
diff --git a/packages/item-system/testpage/main.tsx b/packages/item-system/testpage/main.tsx
new file mode 100644
index 0000000..0e21b35
--- /dev/null
+++ b/packages/item-system/testpage/main.tsx
@@ -0,0 +1,248 @@
+import React, { useState } from "react";
+import { createRoot } from "react-dom/client";
+import { FluentProvider, Switch, webDarkTheme, webLightTheme } from "@fluentui/react-components";
+
+import { ItemTooltipProvider } from "../src/ItemTooltipProvider";
+import { ItemSlotInfo } from "../src/data/ItemSlotInfo.ts";
+import { CookEffect, ItemUse, PouchItemType } from "../src/data/enums.ts";
+
+import { ItemSlot } from "../src/ItemSlot";
+import { ItemTooltip } from "../src/ItemTooltip.tsx";
+import { initI18n } from "skybook-localization";
+
+const DUMMY: ItemSlotInfo = {
+ actorName: "Dummy",
+ itemType: PouchItemType.Sword,
+ itemUse: ItemUse.WeaponSmallSword,
+ value: 0,
+ isEquipped: false,
+ isInInventory: true,
+ modEffectValue: 0,
+ modEffectDuration: 0,
+ modSellPrice: 0,
+ modEffectId: CookEffect.None,
+ modEffectLevel: 0,
+ ingredientActorNames: [],
+ listPosition: 0,
+ unallocated: false,
+ poolPosition: 0,
+ isInBrokenSlot: false,
+ holdingCount: 0,
+ promptEntangled: false,
+}
+
+const TEST_ITEMS: ItemSlotInfo[] = [
+ {
+ ...DUMMY,
+ actorName: "Weapon_Sword_070",
+ itemType: PouchItemType.Sword,
+ itemUse: ItemUse.WeaponSmallSword,
+ value: 4000,
+ },
+ {
+ ...DUMMY,
+ actorName: "Obj_HeroSoul_Zora",
+ itemType: PouchItemType.KeyItem,
+ },
+ {
+ ...DUMMY,
+ actorName: "Item_Ore_A",
+ itemType: PouchItemType.Material,
+ value: 99999,
+ },
+ {
+ ...DUMMY,
+ actorName: "Weapon_Lsword_010",
+ itemType: PouchItemType.Sword,
+ itemUse: ItemUse.WeaponLargeSword,
+ value: 3850,
+ },
+ {
+ ...DUMMY,
+ actorName: "Item_PlantGet_Q",
+ itemType: PouchItemType.Material,
+ value: 5,
+ holdingCount: 4,
+ },
+ {
+ ...DUMMY,
+ actorName: "Obj_DLC_HeroSoul_Goron",
+ itemType: PouchItemType.KeyItem,
+ },
+ {
+ ...DUMMY,
+ actorName: "Weapon_Sword_502",
+ itemType: PouchItemType.Sword,
+ itemUse: ItemUse.WeaponSmallSword,
+ value: 100,
+ },
+ {
+ ...DUMMY,
+ actorName: "Armor_011_Lower",
+ itemType: PouchItemType.ArmorLower,
+ itemUse: ItemUse.ArmorLower,
+ value: 1,
+ },
+ {
+ ...DUMMY,
+ actorName: "Weapon_Bow_028",
+ itemType: PouchItemType.Bow,
+ itemUse: ItemUse.WeaponBow,
+ value: 6000,
+ },
+ {
+ ...DUMMY,
+ actorName: "Weapon_Bow_028",
+ itemType: PouchItemType.Bow,
+ itemUse: ItemUse.WeaponBow,
+ value: 6000,
+ modEffectValue: 120,
+ modSellPrice: 147,
+ },
+ {
+ ...DUMMY,
+ actorName: "Weapon_Shield_001",
+ itemType: PouchItemType.Shield,
+ itemUse: ItemUse.WeaponShield,
+ value: 1000,
+ modEffectValue: 120,
+ modSellPrice: 0xffffffff,
+ },
+ {
+ ...DUMMY,
+ actorName: "Item_Cook_A_01",
+ itemType: PouchItemType.Food,
+ itemUse: ItemUse.CureItem,
+ value: 1,
+ modEffectValue: 120,
+ isInInventory: false,
+ modSellPrice: 115,
+ },
+ {
+ ...DUMMY,
+ actorName: "Item_Cook_C_17",
+ itemType: PouchItemType.Food,
+ itemUse: ItemUse.CureItem,
+ value: 1,
+ modEffectValue: 120,
+ modEffectId: CookEffect.ExGutsMaxUp,
+ modSellPrice: 115,
+ },
+ {
+ ...DUMMY,
+ actorName: "Armor_075_Head",
+ itemType: PouchItemType.ArmorUpper,
+ itemUse: ItemUse.ArmorUpper,
+ value: 1,
+ },
+ {
+ ...DUMMY,
+ actorName: "Item_Cook_C_17",
+ itemType: PouchItemType.Food,
+ itemUse: ItemUse.CureItem,
+ value: 1,
+ modEffectValue: 25,
+ modEffectId: CookEffect.LifeMaxUp,
+ },
+ {
+ ...DUMMY,
+ actorName: "Item_Cook_C_17",
+ itemType: PouchItemType.Food,
+ itemUse: ItemUse.CureItem,
+ value: 1,
+ modEffectValue: 25,
+ modEffectId: CookEffect.GutsRecover,
+ modEffectLevel: 1000,
+ },
+ {
+ ...DUMMY,
+ actorName: "Item_Cook_C_17",
+ itemType: 78,
+ itemUse: 87,
+ value: 1,
+ modEffectValue: 40,
+ modEffectId: CookEffect.AllSpeed,
+ modEffectLevel: 3,
+ modEffectDuration: 3600,
+ },
+];
+
+const App: React.FC = () => {
+ const [cheap, setCheap] = useState(false);
+ const [isEquipped, setIsEquipped] = useState(false);
+ const [isInBrokenSlot, setIsInBrokenSlot] = useState(false);
+ const [deactive, setDeactive] = useState(false);
+ const [badlyDamaged, setBadlyDamaged] = useState(false);
+ const [animation, setAnimation] = useState(true);
+ const [entangled, setEntangled] = useState(false);
+
+ const items = TEST_ITEMS.map((item, i) => {
+ return {
+ ...item, isEquipped, isInBrokenSlot, listPosition: i,
+ promptEntangled: entangled,
+ ...(badlyDamaged ? { value: 200 } : {})
+ }
+ });
+
+ return <>
+
+ {
+ setCheap(!!checked);
+ }} />
+ {
+ setIsEquipped(!!checked);
+ }} />
+ {
+ setIsInBrokenSlot(!!checked);
+ }} />
+ {
+ setDeactive(!!checked);
+ }} />
+ {
+ setBadlyDamaged(!!checked);
+ }} />
+ {
+ setAnimation(!!checked);
+ }} />
+ {
+ setEntangled(!!checked);
+ }} />
+
+
+ {
+ items.map((item, index) => {
+ return (
+
+
+
+ );
+ })
+ }
+
+ >;
+};
+
+void (async function main(){
+ await initI18n();
+
+
+ const root = document.getElementById('root');
+ if (root) {
+ createRoot(root).render(
+
+
+
+
+
+
+
+ );
+ }
+
+})()
+
diff --git a/packages/item-system/tsconfig.app.json b/packages/item-system/tsconfig.app.json
new file mode 100644
index 0000000..6461f97
--- /dev/null
+++ b/packages/item-system/tsconfig.app.json
@@ -0,0 +1,7 @@
+{
+ "extends": "../../config/tsconfig-vite-app.json",
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+ },
+ "include": ["src", "testpage"]
+}
diff --git a/packages/item-system/tsconfig.json b/packages/item-system/tsconfig.json
new file mode 100644
index 0000000..1ffef60
--- /dev/null
+++ b/packages/item-system/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "files": [],
+ "references": [
+ { "path": "./tsconfig.app.json" },
+ { "path": "./tsconfig.node.json" }
+ ]
+}
diff --git a/packages/item-system/tsconfig.node.json b/packages/item-system/tsconfig.node.json
new file mode 100644
index 0000000..c890797
--- /dev/null
+++ b/packages/item-system/tsconfig.node.json
@@ -0,0 +1,7 @@
+{
+ "extends": "../../config/tsconfig-tool.json",
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/packages/item-system/vite.config.ts b/packages/item-system/vite.config.ts
new file mode 100644
index 0000000..9013ec4
--- /dev/null
+++ b/packages/item-system/vite.config.ts
@@ -0,0 +1,17 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+import yaml from "@modyfi/vite-plugin-yaml";
+
+// import esbuildImportMetaUrlPlugin from "@codingame/esbuild-import-meta-url-plugin";
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [react(), yaml()],
+
+ // optimizeDeps: {
+ // esbuildOptions: {
+ // plugins: [esbuildImportMetaUrlPlugin]
+ // }
+ // }
+})
+
diff --git a/packages/localization/.gitignore b/packages/localization/.gitignore
new file mode 100644
index 0000000..d1d744a
--- /dev/null
+++ b/packages/localization/.gitignore
@@ -0,0 +1,2 @@
+src/generated/*.yaml
+/node_modules/
diff --git a/packages/localization/Taskfile.yml b/packages/localization/Taskfile.yml
new file mode 100644
index 0000000..14d1157
--- /dev/null
+++ b/packages/localization/Taskfile.yml
@@ -0,0 +1,7 @@
+version: '3'
+
+tasks:
+ push:
+ desc: Push generated files. Requires gcloud access
+ cmds:
+ - gcloud storage cp src/generated/*.yaml gs://ist-private/i18n/generated
diff --git a/packages/localization/package.json b/packages/localization/package.json
new file mode 100644
index 0000000..7cf2011
--- /dev/null
+++ b/packages/localization/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "skybook-localization",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "dependencies": {
+ "@pistonite/pure": "*",
+ "i18next": "^24.2.0",
+ "react-i18next": "^15.2.0"
+ },
+ "exports": {
+ ".": "./src/index.ts"
+ }
+}
diff --git a/packages/localization/src/index.ts b/packages/localization/src/index.ts
new file mode 100644
index 0000000..ce5d8fc
--- /dev/null
+++ b/packages/localization/src/index.ts
@@ -0,0 +1,85 @@
+import type { BackendModule } from "i18next";
+import i18next from "i18next";
+import { initReactI18next, useTranslation } from "react-i18next";
+import { convertToSupportedLocale, detectLocale, initLocale } from "@pistonite/pure/pref";
+import { useCallback } from "react";
+
+export const backend: BackendModule = {
+ type: "backend",
+ init: () => {
+ // no init needed
+ },
+ read: async (language: string, namespace: string) => {
+ if (namespace === "translation" || language === "dev") {
+ // don't load the default translation namespace
+ return undefined;
+ }
+ const locale = convertToSupportedLocale(language);
+ console.log(locale, namespace);
+ let strings;
+ try {
+ strings = await import(`./${namespace}/${locale}.yaml`);
+ console.log(strings);
+ } catch(e) {
+ console.error(e);
+ try {
+ strings = await import(`./${namespace}/en-US.yaml`);
+ } catch(e) {
+ console.error(e);
+ return undefined;
+ }
+ console.warn(`${language} is not supported for ${namespace} namespace. Falling back to en-US.`);
+ }
+ return strings.default;
+ }
+}
+
+export const SupportedLocales =
+ [
+ "de-DE",
+ "en-US",
+ "es-ES",
+ "fr-FR",
+ "it-IT",
+ "ja-JP", "ko-KR",
+ "nl-NL",
+ "ru-RU", "zh-CN", "zh-TW"
+ ] as const;
+
+export const initI18n = async () => {
+ initLocale({
+ supported: SupportedLocales,
+ default: "en-US",
+ persist: true,
+ });
+
+ await i18next.use(detectLocale).use(backend).use(initReactI18next).init();
+}
+
+export const translateUI = (key: string, options?: Record) => {
+ return i18next.t(`ui:${key}`, options);
+}
+export const translateGenerated = (key: string, options?: Record) => {
+ const value = i18next.t(`generated:${key}`, options);
+ if (value === key) {
+ return "";
+ }
+ return value;
+}
+
+export const useUITranslation = () => {
+ const {t} = useTranslation("ui");
+ return t;
+}
+
+export const useGeneratedTranslation = () => {
+ const {t} = useTranslation("generated", {nsMode: "default"});
+ // return empty string if the key is not found, similar to the game
+ return useCallback((key: string, options?: Record) => {
+ const value = t(key, options);
+ if (value === key) {
+ return "";
+ }
+ return value;
+ }, [t]);
+}
diff --git a/packages/localization/src/ui/en-US.yaml b/packages/localization/src/ui/en-US.yaml
new file mode 100644
index 0000000..abab6ef
--- /dev/null
+++ b/packages/localization/src/ui/en-US.yaml
@@ -0,0 +1,43 @@
+
+button.close: Close
+button.popout: Pop-out to a new window
+
+button.open_extension: Extensions
+button.launch: Launch
+button.cancel: Cancel
+
+status.not_available_platform: Not available for current platform
+status.not_available_window_size: Not available because the window is too small
+
+dialog.extensions.title: Extensions
+dialog.extensions.desc: Launch an extension tool or change its configuration
+field.select_extension: Select an extension
+radio.extension_open_mode.primary: Open in primary view
+radio.extension_open_mode.secondary: Open in secondary view
+radio.extension_open_mode.popout: Pop-out to a new window
+field.extension.remember: Remember my choice
+field.extension.remember.desc: Only effective after clicking "Launch". You can always come back here and change your preference
+
+extension.editor.name: Script Editor
+extension.editor.desc: Edit the script to modify the steps in the simulation
+extension.stub1.name: blaasldkfjasd asdgak sdgfa lskdhgal
+
+
+# Item Slot Tooltip
+tooltip.value: "Value: {{value}}"
+tooltip.equipped: "Equipped"
+tooltip.translucent: "Translucent"
+tooltip.holding: "Holding {{holding}}"
+
+tooltip.cook.price: "Sells for ${{price}}"
+
+tooltip.category: "Category: {pouch_category}"
+tooltip.slot: "Slot #{slot_number}, Pos #{position}"
+tooltip.transfer_slot: "Will be transferred"
+
+tooltip.profile: "Profile: {profile}"
+tooltip.power: "Power: {gparam_attack_power}"
+tooltip.life: "Life: {gparam_general_life}"
+tooltip.life_infinite: "Life: Infinite [{gparam_general_life}]" # generalIsLifeInfinite
+tooltip.buy_price: "Buying Price: {gparam_item_buying_price}"
+tooltip.sell_price: "Selling Price: {gparam_item_selling_price}"
diff --git a/packages/localization/tsconfig.json b/packages/localization/tsconfig.json
new file mode 100644
index 0000000..1f7887e
--- /dev/null
+++ b/packages/localization/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "../../config/tsconfig-vite-app.json",
+ "include": ["src"],
+}
diff --git a/packages/monaco-editor-contrib/.gitignore b/packages/monaco-editor-contrib/.gitignore
new file mode 100644
index 0000000..a55429a
--- /dev/null
+++ b/packages/monaco-editor-contrib/.gitignore
@@ -0,0 +1,5 @@
+/lib
+/esm
+/monaco.d.ts
+/package.original.json
+
diff --git a/packages/monaco-editor-contrib/LICENSE b/packages/monaco-editor-contrib/LICENSE
new file mode 100644
index 0000000..76fdc58
--- /dev/null
+++ b/packages/monaco-editor-contrib/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 - present Microsoft Corporation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/packages/monaco-editor-contrib/Taskfile.yml b/packages/monaco-editor-contrib/Taskfile.yml
new file mode 100644
index 0000000..34a1ca2
--- /dev/null
+++ b/packages/monaco-editor-contrib/Taskfile.yml
@@ -0,0 +1,17 @@
+version: '3'
+
+tasks:
+ clean:
+ cmds:
+ - rm -f monaco.d.ts
+ - rm -f package.original.json
+ - rm -rf lib
+ - rm -rf esm
+ - mkdir lib
+ patch:
+ cmds:
+ - deno --allow-read --allow-write patch.ts
+ - mv lib/monaco-editor/monaco.d.ts .
+ - mv lib/monaco-editor/esm .
+ - mv lib/monaco-editor/package.json package.original.json
+ - rm -rf lib
diff --git a/packages/monaco-editor-contrib/package.json b/packages/monaco-editor-contrib/package.json
new file mode 100644
index 0000000..11e6f64
--- /dev/null
+++ b/packages/monaco-editor-contrib/package.json
@@ -0,0 +1,21 @@
+{
+ "name": "monaco-editor-contrib",
+ "version": "0.52.2",
+ "license": "MIT",
+ "typings": "./esm/vs/editor/editor.api.d.ts",
+ "module": "./esm/vs/editor/editor.main.js",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/microsoft/monaco-editor"
+ },
+ "devDependencies": {
+ "@types/node": "^22.10.2",
+ "monaco-editor": "0.52.2"
+ },
+ "alias": {
+ "process": false,
+ "buffer": false
+ },
+ "vscodeCommitId": "a7d9e2c32d573e29e68975838196722ae9bb0f15",
+ "monacoCommitId": "404545bded1df6ffa41ea0af4e8ddb219018c6c1"
+}
diff --git a/packages/monaco-editor-contrib/patch.ts b/packages/monaco-editor-contrib/patch.ts
new file mode 100644
index 0000000..1bb9a82
--- /dev/null
+++ b/packages/monaco-editor-contrib/patch.ts
@@ -0,0 +1,76 @@
+/**
+ * Patches TS Worker to expose getEncodedSemanticClassifcations
+ * according to the POC here:
+ * https://github.com/Pistonight/monaco-editor/commit/ac884678bc17c0eafe174a9cab84510f3b68b4ed
+ */
+
+import fs from "node:fs";
+
+let lines: string[] = [];
+let currentLine = 0;
+let outLines: string[] = [];
+
+const patchFile = (file: string, fn: () => void) => {
+ const oldFile = file + ".old";
+ if (fs.existsSync(oldFile)) {
+ if (fs.existsSync(file)) {
+ fs.rmSync(file);
+ }
+ } else if (fs.existsSync(file)) {
+ fs.copyFileSync(file, oldFile);
+ } else {
+ throw new Error("File not found: " + file);
+ }
+ console.log("patching", file);
+ lines = fs.readFileSync(oldFile, "utf-8").split("\n");
+ currentLine = 0;
+ outLines = [];
+ fn();
+ skipToEnd();
+ fs.writeFileSync(file, outLines.join("\n"));
+}
+/**
+ * skip from currentLine until a line matches a condition
+ * update currentLine. Throws if not found.
+ *
+ * new current line will not be pushed, but skipped lines will
+ */
+const skipUntil = (matches: (line: string) => boolean) => {
+ for (; currentLine< lines.length; currentLine++) {
+ if (matches(lines[currentLine])) {
+ return;
+ }
+ outLines.push(lines[currentLine]);
+ }
+ throw new Error("Not found");
+}
+const skipToEnd = () => {
+ outLines.push(...lines.slice(currentLine));
+ currentLine = lines.length;
+}
+const addPatch = (content: string) => {
+ outLines.push(...content.split("\n").filter(Boolean).map(line => line.trimEnd()));
+}
+
+patchFile("lib/monaco-editor/esm/vs/language/typescript/ts.worker.js", () => {
+ skipUntil(line => line.trim() === "// src/language/typescript/tsWorker.ts");
+ skipUntil(line => line.trim().includes("class _TypeScriptWorker {"))
+ skipUntil(line => line.trim().startsWith("async provideInlayHints("));
+ // add our function here
+ addPatch(`
+ async getEncodedSemanticClassifications(fileName, start, end) {
+ if (fileNameIsLib(fileName)) { return undefined };
+ const span = { start, length: end - start };
+ return this._languageService.getEncodedSemanticClassifications(fileName, span, "2020");
+ }
+`);
+});
+
+patchFile("lib/monaco-editor/monaco.d.ts", patchTypeScriptWorkerInterface);
+patchFile("lib/monaco-editor/esm/vs/editor/editor.api.d.ts", patchTypeScriptWorkerInterface);
+
+function patchTypeScriptWorkerInterface() {
+ skipUntil(line => line.trim() === "export interface TypeScriptWorker {");
+ skipUntil(line => line.trim().startsWith("provideInlayHints("));
+ addPatch(`getEncodedSemanticClassifications(fileName: string, start: number, end: number): Promise<{spans: number[]}|undefined>;`);
+}
diff --git a/packages/monaco-editor-contrib/tsconfig.json b/packages/monaco-editor-contrib/tsconfig.json
new file mode 100644
index 0000000..081c74d
--- /dev/null
+++ b/packages/monaco-editor-contrib/tsconfig.json
@@ -0,0 +1,23 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "isolatedModules": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
+ },
+ "include": ["patch.ts"]
+}
diff --git a/packages/monaco-typescript-contrib/README.md b/packages/monaco-typescript-contrib/README.md
new file mode 100644
index 0000000..41e7be4
--- /dev/null
+++ b/packages/monaco-typescript-contrib/README.md
@@ -0,0 +1,5 @@
+# monaco-typescript-contrib
+
+This is an experimental improved Monarch tokenizer for TypeScript
+
+## Token Classes
diff --git a/packages/monaco-typescript-contrib/package.json b/packages/monaco-typescript-contrib/package.json
new file mode 100644
index 0000000..7cc7471
--- /dev/null
+++ b/packages/monaco-typescript-contrib/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "@pistonite/monaco-typescript-contrib",
+ "private": true,
+ "version": "0.0.1",
+ "description": "TODO",
+ "homepage": "TODO",
+ "bugs": {
+ "url": "TODO"
+ },
+ "license": "MIT",
+ "author": "Pistonight ",
+ "files": [
+ "src/**/*"
+ ],
+ "exports": {
+ ".": "./src/index.ts"
+ },
+ "todo.repository": {
+ "type": "git",
+ "url": "https://github.com"
+ },
+ "devDependencies": {
+ "monaco-editor-contrib": "0.52.2"
+ }
+}
diff --git a/packages/monaco-typescript-contrib/src/index.ts b/packages/monaco-typescript-contrib/src/index.ts
new file mode 100644
index 0000000..caf2cd7
--- /dev/null
+++ b/packages/monaco-typescript-contrib/src/index.ts
@@ -0,0 +1,16 @@
+import * as monaco from "monaco-editor-contrib";
+import { language } from "./language.ts";
+import { DocumentRangeSemanticTokensProviderAdapter } from "./semantic.ts";
+
+export type Option = {
+ /** maximum source length to enable semantic highlighting */
+ semanticTokensMaxLength?: number;
+}
+
+export function patchMonacoTypeScript(options?: Option) {
+ monaco.languages.setMonarchTokensProvider("typescript", language);
+ monaco.languages.registerDocumentRangeSemanticTokensProvider(
+ "typescript",
+ new DocumentRangeSemanticTokensProviderAdapter(options?.semanticTokensMaxLength)
+ );
+}
diff --git a/packages/monaco-typescript-contrib/src/language.ts b/packages/monaco-typescript-contrib/src/language.ts
new file mode 100644
index 0000000..d767a87
--- /dev/null
+++ b/packages/monaco-typescript-contrib/src/language.ts
@@ -0,0 +1,42 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import * as monaco from "monaco-editor-contrib/esm/vs/editor/editor.api.ts";
+
+// @ts-ignore no types
+import { language as original } from "monaco-editor-contrib/esm/vs/basic-languages/typescript/typescript.js";
+
+export const language = {
+ ...original,
+ tokenizer: {
+ ...original.tokenizer,
+ common: [
+ // New rules
+ [/(true|false)/, "constant.language.boolean"],
+ [/null/, "constant.language.null"],
+ [/undefined/, "constant.language.undefined"],
+ [/(this|super|self)/, "variable.language"],
+ // something that *could* be a function call/declaration
+ [/#?[a-z_$][\w$]*(?=(\s*\(|\s*<.*>\s*\(|\s*`))/, {
+ cases: {
+ '@keywords': "keyword",
+ '@default': "function",
+ }
+ }],
+
+ // patch old rule
+ [
+ /#?[a-z_$][\w$]*/,
+ {
+ cases: {
+ "@keywords": "keyword",
+ "@default": "variable"
+ }
+ }
+ ],
+ ...original.tokenizer.common.slice(1),
+ ]
+ }
+};
diff --git a/packages/monaco-typescript-contrib/src/semantic.ts b/packages/monaco-typescript-contrib/src/semantic.ts
new file mode 100644
index 0000000..162290b
--- /dev/null
+++ b/packages/monaco-typescript-contrib/src/semantic.ts
@@ -0,0 +1,315 @@
+import * as monaco from "monaco-editor-contrib";
+
+const legend: monaco.languages.SemanticTokensLegend = {
+ tokenTypes: [
+ // 1 - Class
+ "type.class",
+ // 2 - Enum
+ "type.enum",
+ // 3 - Interface
+ "type.interface",
+ // 4 - Namespace
+ "type.namespace",
+ // 5 - TypeParameter
+ "type.parameter",
+ // 6 - Type
+ "type",
+ // 7 - Parameter
+ "variable.parameter",
+ // 8 - Variable,
+ "variable",
+ // 9 - EnumMember
+ "variable.other.enummember",
+ // 10 - Property
+ "variable",
+ // 11 - Function
+ "function",
+ // 12 - Member
+ "variable",
+ ],
+ tokenModifiers: [
+ "declaration",
+ "static",
+ "async",
+ "readonly",
+ // "defaultLibrary"
+ "language",
+ "local",
+ ]
+}
+
+const setTimeout = self.setTimeout;
+
+/** Per-model request for semantic tokens */
+type RangeSemanticTokensRequest = {
+ scheduled: false;
+} | {
+ scheduled: true;
+ model: monaco.editor.ITextModel;
+ // merged range
+ range: monaco.Range;
+ // latest cancellation token
+ token: monaco.CancellationToken;
+ promise: Promise;
+ resolve: (value: monaco.languages.SemanticTokens | undefined) => void;
+ reject: (reason: unknown) => void;
+};
+export class DocumentRangeSemanticTokensProviderAdapter
+ implements monaco.languages.DocumentRangeSemanticTokensProvider {
+
+ private worker?: (...uris: monaco.Uri[]) => Promise;
+
+
+ constructor(
+ private maxLength: number = 50000,
+ private debounceInterval: number = 500,
+ ) {
+ }
+
+ // --- batcher implementation ---
+ private requests: Map = new Map();
+
+ public provideDocumentRangeSemanticTokens(
+ model: monaco.editor.ITextModel,
+ range: monaco.Range,
+ token: monaco.CancellationToken):
+ Promise {
+ if (!this.shouldRun(model)) {
+ return Promise.resolve(undefined);
+ }
+ const resource = model.uri.toString();
+ const request = this.requests.get(resource);
+ if (!request) {
+ // not currently running any request for this model,
+ // execute immediately and mark as running
+ this.requests.set(resource, {scheduled: false});
+ return this.executeBatched(resource, model, range, token);
+ }
+ return this.updateRequest(request, model, resource, range, token);
+ }
+
+ private shouldRun(model: monaco.editor.ITextModel): boolean {
+ if (this.maxLength > 0 && model.getValueLength() > this.maxLength) {
+ return false;
+ }
+ return true;
+ }
+
+ private updateRequest(
+ request: RangeSemanticTokensRequest,
+ model: monaco.editor.ITextModel,
+ resource: string,
+ range: monaco.Range,
+ token: monaco.CancellationToken
+ ): Promise {
+ if (request.scheduled) {
+ // abandon old range, since it's probably out of view anyway
+ request.range = range;
+ request.token = token;
+ return request.promise;
+ }
+ let resolve;
+ let reject;
+ const promise = new Promise((res, rej) => {
+ resolve = res;
+ reject= rej;
+ });
+ this.requests.set(resource, {
+ scheduled: true,
+ model,
+ range,
+ token,
+ promise,
+ resolve: resolve!,
+ reject: reject!
+ });
+ return promise;
+ }
+
+ private onRequestFinished(resource: string) {
+ const request = this.requests.get(resource);
+ if (!request) {
+ return;
+ }
+ if (!request.scheduled) {
+ // delete the entry to signify that no current
+ // request is running for this model
+ this.requests.delete(resource);
+ return;
+ }
+
+ this.requests.set(resource, {scheduled: false});
+
+ const { model, range, token, resolve, reject } = request;
+ this.executeBatched(resource, model, range, token).then(resolve, reject);
+ }
+
+ // --- adapter implementation ---
+
+ getLegend(): monaco.languages.SemanticTokensLegend {
+ return legend;
+ }
+
+ async executeBatched(
+ resource: string,
+ model: monaco.editor.ITextModel,
+ range: monaco.Range,
+ token: monaco.CancellationToken):
+ Promise {
+ let isWaitingForWorker = false;
+ const cb = () => {
+ if (!isWaitingForWorker) {
+ this.onRequestFinished(resource);
+ return;
+ }
+ setTimeout(cb, this.debounceInterval);
+ };
+ setTimeout(cb, this.debounceInterval);
+ const start = model.getOffsetAt({
+ lineNumber: range.startLineNumber,
+ column: range.startColumn
+ })
+ const end = model.getOffsetAt({
+ lineNumber: range.endLineNumber,
+ column: range.endColumn
+ })
+ const worker = await this.getWorker(model.uri);
+ // check after await
+ if (model.isDisposed() || token.isCancellationRequested) {
+ return undefined;
+ }
+ isWaitingForWorker = true;
+ const result = await worker.getEncodedSemanticClassifications(resource, start, end);
+ isWaitingForWorker = false;
+ // check after await
+ if (!result || model.isDisposed() || token.isCancellationRequested) {
+ return undefined;
+ }
+ const { spans } = result;
+ const data = this.convertTokens(model, spans );
+ return {
+ data: new Uint32Array(data)
+ }
+ }
+
+ private convertTokens(model: monaco.editor.ITextModel, inputs: number[]): number[] {
+ // inputs are triples: [start, length, type]
+ // outputs are 5-tuples: [deltaLine, deltaStart, length, tokenType, tokenModifiers]
+ const outputs = [];
+ let prevLine = 1;
+ let prevStart = 1;
+
+ // since we only run this for the latest range that's requested,
+ // we should never have to worry about having too many tokens
+ // returned from the worker
+ for (let i = 0; i + 3 <= inputs.length; i += 3) {
+ const start = inputs[i];
+ const length = inputs[i + 1];
+ let modifier = inputs[i + 2];
+ let type = modifier >> 8;
+ // type should be 1-indexed
+ if (!type || type > legend.tokenTypes.length) {
+ continue;
+ }
+
+ // fix the type and modifiers to have better highlighting
+
+ // readonly + lower bits (declaration, static, async)
+ if ((modifier & 0b1000) && (modifier & 0b111)) {
+ // only keep readonly, so less important
+ // modifiers don't take priority
+ modifier = 0b1000;
+ }
+ // special handling for property and member
+ if (type === 10 || type === 12) {
+ // ignore non-readonly modifiers
+ // for things like foo.bar(), we want to hightlight
+ // bar as a function instead of variable
+ if (!(modifier & 0b1000)) {
+ continue;
+ }
+ // only keep defaultLibrary on non-property/member
+ // this is for things like [].length, where length
+ // would be highlighted as a normal property,
+ // instead of the same as this, self, super, etc..
+ modifier &= ~0b10000;
+ }
+ // offset by 1
+ type--;
+ // only keep the bits of modifier that matters
+ modifier &= 0xff;
+
+ const { startLineNumber, startColumn, endLineNumber, endColumn } = this._textSpanToRange(
+ model,
+ { start, length }
+ );
+ if (startLineNumber === endLineNumber) {
+ const deltaLine = startLineNumber - prevLine;
+ const deltaStart = deltaLine === 0 ? startColumn - prevStart : startColumn - 1;
+
+ // handy debug code since we can't inspect semantic tokens yet
+ // console.log({
+ // value: model.getValueInRange({startLineNumber, startColumn, endLineNumber, endColumn}),
+ // type: legend.tokenTypes[type],
+ // modifier: modifier.toString(2)
+ // })
+
+ outputs.push(deltaLine, deltaStart, length, type, modifier);
+ prevStart = startColumn;
+ } else {
+ // token spanning multiple lines, convert it to separate entries
+ const firstStart = startColumn - 1;
+ const firstLength = model.getLineLength(startLineNumber) - firstStart;
+ const firstDeltaLine = startLineNumber - prevLine;
+ const firstDeltaStart = firstDeltaLine === 0 ? firstStart - prevStart : firstStart - 1;
+ outputs.push(firstDeltaLine, firstDeltaStart, firstLength, type, modifier);
+
+ // middle full lines
+ for (let i = startLineNumber + 1; i < endLineNumber; i++) {
+ // delta line is always 1, start is always 0
+ const length = model.getLineLength(i);
+ outputs.push(1, 0, length, type, modifier);
+ }
+
+ // last line, if we are not ending at the start of the line
+ if (endColumn !== 1) {
+ const lastLength = endColumn - 1;
+ outputs.push(1, 0, lastLength, type, modifier);
+ }
+ prevStart = 1;
+ }
+ prevLine = endLineNumber;
+ }
+
+ return outputs;
+ }
+
+ // --- debug/utils --- can be removed when upstreaming the work
+
+ // lazy get the worker, since typescript may not be loaded yet
+ private async getWorker(resource: monaco.Uri): Promise {
+ while (!this.worker) {
+ console.log("getting instance of TypeScript worker...");
+ try {
+ this.worker = await monaco.languages.typescript.getTypeScriptWorker();
+ if (!this.worker) {
+ throw new Error("getTypeScriptWorker returned undefined");
+ }
+ break;
+ } catch (e) {
+ console.error("Failed to get worker", e);
+ console.warn("will try again in a bit. This should not happen when this is initialized as part of TS mode");
+ await new Promise(r => setTimeout(r, 1000));
+ }
+ }
+ return await this.worker(resource);
+ }
+
+ private _textSpanToRange(model: monaco.editor.ITextModel, span: {start: number, length: number}): monaco.IRange {
+ let p1 = model.getPositionAt(span.start);
+ let p2 = model.getPositionAt(span.start + span.length);
+ let { lineNumber: startLineNumber, column: startColumn } = p1;
+ let { lineNumber: endLineNumber, column: endColumn } = p2;
+ return { startLineNumber, startColumn, endLineNumber, endColumn };
+ }
+}
diff --git a/app/tsconfig.app.json b/packages/monaco-typescript-contrib/tsconfig.json
similarity index 88%
rename from app/tsconfig.app.json
rename to packages/monaco-typescript-contrib/tsconfig.json
index f0a2350..512058a 100644
--- a/app/tsconfig.app.json
+++ b/packages/monaco-typescript-contrib/tsconfig.json
@@ -12,13 +12,12 @@
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
- "jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
- "noFallthroughCasesInSwitch": true
+ "noFallthroughCasesInSwitch": true,
},
"include": ["src"]
}
diff --git a/packages/parser/Cargo.toml b/packages/parser/Cargo.toml
new file mode 100644
index 0000000..8fed9e1
--- /dev/null
+++ b/packages/parser/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "skybook-parser"
+version = "0.0.0"
+edition = "2021"
+publish = false
+
+[dependencies]
+derive_more = { version = "1.0.0", features = ["deref", "deref_mut"] }
+teleparse = "0.0.5"
+thiserror = "2.0.9"
diff --git a/packages/parser/src/cir/item_meta.rs b/packages/parser/src/cir/item_meta.rs
new file mode 100644
index 0000000..4968fb8
--- /dev/null
+++ b/packages/parser/src/cir/item_meta.rs
@@ -0,0 +1,324 @@
+use teleparse::{tp, Span};
+
+use crate::error::{ErrorReport, Error};
+use crate::item_search::ItemResolver;
+use crate::syn;
+use crate::cir;
+
+use super::MetaParser;
+
+/// Item metadata used to select or specify item
+#[derive(Debug, Default)]
+pub struct ItemMeta {
+ /// The value of the item
+ ///
+ /// settable by:
+ /// - `life=100` -> 100
+ /// - `value=100` -> 100
+ /// - `durability=1` -> 100
+ pub value: Option,
+
+ /// If the item is equipped
+ ///
+ /// settable by `equip`, `equipped`
+ pub equip: Option,
+
+ /// Settable by key `life_recover, hp, modpower`
+ pub life_recover: Option,
+ /// Settable by `time`
+ pub effect_duration: Option,
+ /// Settable by `price` (set), `modifier` (add)
+ pub sell_price: Option,
+ /// Settable by `effect` name
+ pub effect_id: Option,
+ /// Settable by `level`
+ pub effect_level: Option,
+
+ /// Settable by `ingr`
+ pub ingredients: Vec,
+}
+
+impl ItemMeta {
+ pub async fn parse(meta: &syn::ItemMeta, resolver: &R, errors: &mut Vec) -> ItemMeta {
+ let parser = Parser {
+ meta: ItemMeta::default(),
+ resolver,
+ };
+ cir::parse_meta(meta, parser, errors).await
+ }
+}
+
+struct Parser<'r, R: ItemResolver> {
+ meta: ItemMeta,
+ resolver: &'r R,
+}
+
+impl MetaParser for Parser<'_, R> {
+ type Output = ItemMeta;
+
+ async fn visit_start(&mut self, _meta: &syn::ItemMeta, _errors: &mut Vec) {
+ }
+
+ async fn visit_entry(&mut self, span: Span, key: &tp::String, value: &tp::Option, errors: &mut Vec) {
+ let key_str = key.to_ascii_lowercase();
+ match key_str.trim() {
+ "life" | "value" => {
+ match cir::MetaValue::parse_option(value.as_ref()) {
+ Ok(cir::MetaValue::Int(x)) => {
+ self.meta.value = Some(x as i32);
+ }
+ Ok(mv) => {
+ errors.push(
+ Error::InvalidMetaValue(key_str, mv)
+ .spanned(value)
+ );
+ }
+ Err(e) => {
+ errors.push(e);
+ }
+ }
+ },
+ "durability" | "dura" => {
+ match cir::MetaValue::parse_option(value.as_ref()) {
+ Ok(cir::MetaValue::Int(x)) => {
+ self.meta.value = Some((x * 100) as i32);
+ }
+ Ok(mv) => {
+ errors.push(
+ Error::InvalidMetaValue(key_str, mv)
+ .spanned(value)
+ );
+ }
+ Err(e) => {
+ errors.push(e);
+ }
+ }
+ },
+ "equip" | "equipped"=> {
+ match cir::MetaValue::parse_option(value.as_ref()) {
+ Ok(cir::MetaValue::Bool(x)) => {
+ self.meta.equip = Some(x);
+ }
+ Ok(mv) => {
+ errors.push(
+ Error::InvalidMetaValue(key_str, mv)
+ .spanned(value)
+ );
+ }
+ Err(e) => {
+ errors.push(e);
+ }
+ }
+ },
+ "life_recover" | "hp" | "modpower" => {
+ match cir::MetaValue::parse_option(value.as_ref()) {
+ Ok(cir::MetaValue::Int(x)) => {
+ self.meta.life_recover = Some(x as i32);
+ }
+ Ok(mv) => {
+ errors.push(
+ Error::InvalidMetaValue(key_str, mv)
+ .spanned(value)
+ );
+ }
+ Err(e) => {
+ errors.push(e);
+ }
+ }
+ },
+ "time" => {
+ match cir::MetaValue::parse_option(value.as_ref()) {
+ Ok(cir::MetaValue::Int(x)) => {
+ self.meta.effect_duration = Some(x as i32);
+ }
+ Ok(mv) => {
+ errors.push(
+ Error::InvalidMetaValue(key_str, mv)
+ .spanned(value)
+ );
+ }
+ Err(e) => {
+ errors.push(e);
+ }
+ }
+ },
+ "price" => {
+ match cir::MetaValue::parse_option(value.as_ref()) {
+ Ok(cir::MetaValue::Int(x)) => {
+ self.meta.sell_price = Some(x as i32);
+ }
+ Ok(mv) => {
+ errors.push(
+ Error::InvalidMetaValue(key_str, mv)
+ .spanned(value)
+ );
+ }
+ Err(e) => {
+ errors.push(e);
+ }
+ }
+ },
+ "modifier" | "modtype" => {
+ match cir::MetaValue::parse_option(value.as_ref()) {
+ Ok(cir::MetaValue::Int(x)) => {
+ // integer => same as price
+ self.meta.sell_price = Some(x as i32);
+ }
+ Ok(cir::MetaValue::String(x)) => {
+ // string modifier, parse it and add it
+ match parse_weapon_modifier_bits(&x) {
+ Some(m) => self.meta.sell_price = Some(self.meta.sell_price.unwrap_or_default() | m),
+ None => {
+ errors.push(
+ Error::InvalidWeaponModifier(x)
+ .spanned(value)
+ );
+ }
+ }
+ }
+ Ok(mv) => {
+ errors.push(
+ Error::InvalidWeaponModifier(mv.to_string())
+ .spanned(value)
+ );
+ }
+ Err(e) => {
+ errors.push(e);
+ }
+ }
+ },
+ "effect" => {
+ match cir::MetaValue::parse_option(value.as_ref()) {
+ Ok(cir::MetaValue::Int(x)) => {
+ // integer => set it without checking
+ self.meta.effect_id = Some(x as i32);
+ }
+ Ok(cir::MetaValue::String(x)) => {
+ // string modifier, parse it
+ match parse_cook_effect(&x) {
+ Some(m) => self.meta.effect_id = Some(m),
+ None => {
+ errors.push(
+ Error::InvalidCookEffect(x)
+ .spanned(value)
+ );
+ }
+ }
+ }
+ Ok(mv) => {
+ errors.push(
+ Error::InvalidWeaponModifier(mv.to_string())
+ .spanned(value)
+ );
+ }
+ Err(e) => {
+ errors.push(e);
+ }
+ }
+ },
+ "level" => {
+ match cir::MetaValue::parse_option(value.as_ref()) {
+ Ok(cir::MetaValue::Int(x)) => {
+ self.meta.effect_level = Some(x as f32);
+ }
+ Ok(cir::MetaValue::Float(x)) => {
+ self.meta.effect_level = Some(x as f32);
+ }
+ Ok(mv) => {
+ errors.push(
+ Error::InvalidMetaValue(key_str, mv)
+ .spanned(value)
+ );
+ }
+ Err(e) => {
+ errors.push(e);
+ }
+ }
+ },
+ "ingr" => {
+ if self.meta.ingredients.len() >= 5 {
+ errors.push(
+ Error::TooManyIngredients.spanned(value)
+ );
+ return;
+ }
+ match cir::MetaValue::parse_option(value.as_ref()) {
+ Ok(cir::MetaValue::String(x)) => {
+ // currently we only support looking up by english
+ match self.resolver.resolve(&x).await {
+ Some(item) => {
+ self.meta.ingredients.push(item);
+ }
+ None => {
+ errors.push(
+ Error::InvalidItem(x)
+ .spanned(value)
+ );
+ }
+ }
+ }
+ Ok(mv) => {
+ errors.push(
+ Error::InvalidMetaValue(key_str, mv)
+ .spanned(value)
+ );
+ }
+ Err(e) => {
+ errors.push(e);
+ }
+ }
+ }
+ _ => {
+ errors.push(
+ Error::UnusedMetaKey(key_str).spanned_warning(&span)
+ );
+ }
+ }
+ }
+
+ async fn visit_end(&mut self, meta: &syn::ItemMeta, errors: &mut Vec) {
+ todo!()
+ }
+
+ async fn finish(self) -> Self::Output {
+ todo!()
+ }
+}
+
+fn parse_weapon_modifier_bits(value: &str) -> Option {
+ let value = value.replace("_", "").replace("-", "").replace(" ", "").to_ascii_lowercase();
+ match value.trim() {
+ "attack" | "attackup" | "addpower" => Some(0x1),
+ "addpowerplus" => Some(0x80000001u32 as i32),
+ "durability" | "durabilityup" | "addlife" => Some(0x2),
+ "addlifeplus" => Some(0x80000002u32 as i32),
+ "critical" | "criticalhit" => Some(0x4),
+ "longthrow" | "throw" => Some(0x8),
+ "multishot" | "spreadfire" => Some(0x10),
+ "zoom" => Some(0x20),
+ "quickshot" | "rapidfire" => Some(0x40),
+ "surfmaster" | "surf" | "shieldsurf" | "shieldsurfup" | "surfup" => Some(0x80),
+ "guard" | "guardup" | "addguard" => Some(0x100),
+ "addguardplus" => Some(0x80000100u32 as i32),
+ "plus" | "yellow" => Some(0x80000000u32 as i32),
+ _ => None,
+ }
+}
+
+fn parse_cook_effect(value: &str) -> Option {
+ let value = value.replace("_", "").replace("-", "").replace(" ", "").to_ascii_lowercase();
+ match value.trim() {
+ "hearty" | "lifemaxup" => Some(2),
+ "chilly" | "chill" | "resisthot"=> Some(4),
+ "spicy" | "resistcold" => Some(5),
+ "electro" | "resistelectric" => Some(6),
+ "mighty" | "attack" | "attackup" => Some(10),
+ "tough" | "defense" | "defenseup" => Some(11),
+ "sneaky" | "quiet" | "stealth" | "stealthup" | "quietness" => Some(12),
+ "speed" | "speedup" | "allspeed" | "movingspeed" => Some(13),
+ "energizing" | "stamina" | "staminaup" | "stam" | "stamup" | "gutsrecover" | "guts" => Some(14),
+ "enduring" | "endura" | "endur" | "exgutsmaxup" | "exguts" => Some(15),
+ "fire" | "fireproof" | "resistflame" | "resistfire" => Some(16),
+ _ => None,
+ }
+}
diff --git a/packages/parser/src/cir/mod.rs b/packages/parser/src/cir/mod.rs
new file mode 100644
index 0000000..a8655a2
--- /dev/null
+++ b/packages/parser/src/cir/mod.rs
@@ -0,0 +1,118 @@
+use teleparse::{tp, Span, ToSpan};
+
+use crate::error::Error;
+use crate::syn;
+use crate::{error::ErrorReport};
+
+mod item_meta;
+
+
+pub trait MetaParser {
+ type Output;
+
+ async fn visit_start(&mut self, meta: &syn::ItemMeta, errors: &mut Vec);
+ async fn visit_entry(&mut self, span: Span, key: &tp::String, value: &tp::Option, errors: &mut Vec);
+ async fn visit_end(&mut self, meta: &syn::ItemMeta, errors: &mut Vec);
+ async fn finish(self) -> Self::Output;
+}
+
+pub async fn parse_meta(meta: &syn::ItemMeta, mut parser: T, errors: &mut Vec) -> T::Output {
+ parser.visit_start(meta, errors).await;
+ let span = meta.span();
+ for entry in &meta.entries {
+ parser.visit_entry(span, &entry.key, &entry.value, errors).await;
+ }
+ parser.visit_end(meta, errors).await;
+ parser.finish().await
+}
+
+#[derive(Debug, Clone)]
+pub enum MetaValue {
+ Bool(bool),
+ Int(i64),
+ Float(f64),
+ String(String),
+}
+
+impl std::fmt::Display for MetaValue {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ MetaValue::Bool(b) => write!(f, "{}", b),
+ MetaValue::Int(i) => write!(f, "{}", i),
+ MetaValue::Float(fl) => write!(f, "{}", fl),
+ MetaValue::String(s) => write!(f, "{}", s),
+ }
+ }
+}
+
+impl MetaValue {
+ pub fn parse_option(value: Option<&syn::ItemMetaValue>) -> Result {
+ match value {
+ Some(v) => Ok(Self::parse(&v.value)?),
+ None => Ok(Self::Bool(true)),
+ }
+ }
+ pub fn parse(value: &syn::MetaValueLiteral) -> Result {
+ match value {
+ syn::MetaValueLiteral::Word(x) => {
+ let s = x.trim();
+ match s {
+ "true" => Ok(Self::Bool(true)),
+ "false" => Ok(Self::Bool(false)),
+ _ => Ok(Self::String(s.to_string())),
+ }
+ }
+ syn::MetaValueLiteral::Number(x) => {
+ let int_part: &str = &*x.int_part;
+ let int_part = match int_part.strip_prefix("0x") {
+ Some(rest) => i64::from_str_radix(rest, 16)
+ .map_err(|_| {
+ Error::IntFormat(x.int_part.to_string()).spanned(x)
+ })?,
+
+ None => int_part.parse()
+ .map_err(|_| {
+ Error::IntFormat(x.int_part.to_string()).spanned(x)
+ })?
+ };
+ let float_part = match &*x.float_part {
+ Some(fp) => fp,
+ None => return Ok(Self::Int(int_part)),
+ };
+ let decimal_part = match &*float_part.1 {
+ Some(dp) => dp,
+ // Integer followed by dot, like 3.
+ None => return Ok(Self::Float(int_part as f64)),
+ };
+ let decimal_str: &str = &*decimal_part;
+ let decimal_num = match decimal_part.strip_prefix("0x") {
+ Some(_) => {
+ // float part can't be hex
+ return Err(
+ Error::FloatFormat(format!("{}.{}", int_part, decimal_str)).spanned(x)
+ )
+ }
+
+ None => decimal_part.parse::()
+ .map_err(|_| {
+ Error::FloatFormat(format!("{}.{}", int_part, decimal_str)).spanned(x)
+ })?
+ };
+ // float part can't be negative
+ if decimal_num < 0 {
+ return Err(
+ Error::FloatFormat(format!("{}.{}", int_part, decimal_str)).spanned(x)
+ )
+ }
+ let full_str = format!("{}.{}", int_part, decimal_str);
+ let value = full_str.parse::()
+ .map_err(|_| {
+ Error::FloatFormat(format!("{}.{}", int_part, decimal_str)).spanned(x)
+ })?;
+ return Ok(Self::Float(value));
+ }
+ }
+
+ }
+}
+
diff --git a/packages/parser/src/error.rs b/packages/parser/src/error.rs
new file mode 100644
index 0000000..de906a0
--- /dev/null
+++ b/packages/parser/src/error.rs
@@ -0,0 +1,53 @@
+use teleparse::ToSpan;
+
+use crate::cir;
+
+
+pub struct ErrorReport {
+ pub span: (usize, usize),
+ pub is_warning: bool,
+ pub error: Error,
+}
+
+impl ErrorReport {
+ pub fn spanned(t: &T, error: Error) -> Self {
+ let span = t.span();
+ Self {
+ span: (span.lo, span.hi),
+ is_warning: false,
+ error,
+ }
+ }
+}
+
+#[derive(Debug, Clone, thiserror::Error)]
+pub enum Error {
+ #[error("failed to resolve item: {0}")]
+ InvalidItem(String),
+ #[error("invalid integer format: {0}")]
+ IntFormat(String),
+ #[error("invalid number format: {0}")]
+ FloatFormat(String),
+ #[error("unused meta key: {0}")]
+ UnusedMetaKey(String),
+ #[error("key `{0}` has invalid value: {0}")]
+ InvalidMetaValue(String, cir::MetaValue),
+ #[error("invalid weapon modifier: {0}")]
+ InvalidWeaponModifier(String),
+ #[error("invalid cook effect: {0}")]
+ InvalidCookEffect(String),
+ #[error("item has too many ingredients (max 5)")]
+ TooManyIngredients,
+}
+
+impl Error {
+ pub fn spanned(self, t: &T) -> ErrorReport {
+ ErrorReport::spanned(t, self)
+ }
+
+ pub fn spanned_warning(self, t: &T) -> ErrorReport {
+ let mut report = ErrorReport::spanned(t, self);
+ report.is_warning = true;
+ report
+ }
+}
diff --git a/packages/parser/src/item_search.rs b/packages/parser/src/item_search.rs
new file mode 100644
index 0000000..1ee1285
--- /dev/null
+++ b/packages/parser/src/item_search.rs
@@ -0,0 +1,12 @@
+
+pub trait ItemResolver {
+ type Future: std::future::Future + Send + 'static;
+
+ /// Resolve an item to its actor name
+ fn resolve(&self, word: &str) -> Self::Future>;
+
+ /// Resolve a quote item word "like this" to its actor name
+ fn resolve_quoted(&self, word: &str) -> Self::Future >;
+
+
+}
diff --git a/packages/parser/src/lib.rs b/packages/parser/src/lib.rs
new file mode 100644
index 0000000..9dbaee7
--- /dev/null
+++ b/packages/parser/src/lib.rs
@@ -0,0 +1,12 @@
+
+/// Command syntax
+mod syn;
+/// Command intermediate representation
+mod cir;
+
+mod error;
+mod item_search;
+
+pub fn test_message(n: u64) -> String {
+ format!("Hello from Rust! You passed in {}", n)
+}
diff --git a/packages/parser/src/syn/category.rs b/packages/parser/src/syn/category.rs
new file mode 100644
index 0000000..6322560
--- /dev/null
+++ b/packages/parser/src/syn/category.rs
@@ -0,0 +1,72 @@
+use teleparse::derive_syntax;
+
+use super::token::{KwArmor, KwArmors, KwBow, KwBows, KwFood, KwFoods, KwKeyItem, KwKeyItems, KwMaterial, KwMaterials, KwShield, KwShields, KwWeapon, KwWeapons};
+
+/// Category specifier
+#[derive_syntax]
+#[derive(Debug)]
+pub enum Category {
+ Weapon(CatWeapon),
+ Bow(CatBow),
+ Shield(CatShield),
+ Armor(CatArmor),
+ Material(CatMaterial),
+ Food(CatFood),
+ KeyItem(CatKeyItem),
+}
+
+/// The "weapon" tab/category
+#[derive_syntax]
+#[derive(Debug)]
+pub enum CatWeapon {
+ Singular(KwWeapon),
+ Plural(KwWeapons),
+}
+
+/// The "bow" tab/category
+#[derive_syntax]
+#[derive(Debug)]
+pub enum CatBow {
+ Singular(KwBow),
+ Plural(KwBows),
+}
+
+/// The "shield" tab/category
+#[derive_syntax]
+#[derive(Debug)]
+pub enum CatShield {
+ Singular(KwShield),
+ Plural(KwShields),
+}
+
+/// The "armor" tab/category
+#[derive_syntax]
+#[derive(Debug)]
+pub enum CatArmor {
+ Singular(KwArmor),
+ Plural(KwArmors),
+}
+
+/// The "material" tab/category
+#[derive_syntax]
+#[derive(Debug)]
+pub enum CatMaterial {
+ Singular(KwMaterial),
+ Plural(KwMaterials)
+}
+
+/// The "food" tab/category
+#[derive_syntax]
+#[derive(Debug)]
+pub enum CatFood {
+ Singular(KwFood),
+ Plural(KwFoods)
+}
+
+/// The "key item" tab/category
+#[derive_syntax]
+#[derive(Debug)]
+pub enum CatKeyItem {
+ Singular(KwKeyItem),
+ Plural(KwKeyItems),
+}
diff --git a/packages/parser/src/syn/command.rs b/packages/parser/src/syn/command.rs
new file mode 100644
index 0000000..76d05de
--- /dev/null
+++ b/packages/parser/src/syn/command.rs
@@ -0,0 +1,342 @@
+//! Syntax for commands
+
+use teleparse::{derive_syntax, tp};
+
+use super::token::{KwGet, KwBuy, KwHoldAttach
+};
+use super::item_list::{ItemListFinite, ItemListConstrained};
+use super::{Category, ItemMeta, ItemWithSlot, ItemWithSlotOrCategory, KwBake, KwBoil, KwCloseGame, KwCloseInventory, KwCook, KwDestroy, KwDnp, KwDrop, KwEat, KwEntangle, KwEnter, KwEquip, KwExit, KwFreeze, KwHold, KwHoldSmuggle, KwLeave, KwNewGame, KwOpenInventory, KwPickUp, KwReload, KwRoast, KwSave, KwSaveAs, KwSell, KwShoot, KwSort, KwTalkTo, KwUnequip, KwUnhold, KwUntalk, KwUse, TimesClause, Word};
+
+#[derive_syntax]
+#[derive(Debug)]
+pub enum Command {
+ // ==== adding items ====
+
+ /// `get ITEMS`
+ Get(CmdGet),
+ /// `buy ITEMS`
+ Buy(CmdBuy),
+ /// `pick-up ITEMS`
+ PickUp(CmdPickup),
+
+ // ==== holding items ====
+
+ /// `hold ITEMS`
+ Hold(CmdHold),
+ /// `hold-smuggle ITEMS`
+ HoldSmuggle(CmdHoldSmuggle),
+ /// `hold-attach ITEMS`
+ HoldAttach(CmdHoldAttach),
+ /// `unhold`
+ Unhold(KwUnhold),
+ /// `drop` or `drop ITEMS`
+ Drop(CmdDrop),
+ /// `dnp ITEMS`
+ Dnp(CmdDnp),
+ /// `cook` or `cook ITEMS`
+ Cook(CmdCook),
+
+ // ==== removing items ====
+
+ /// `eat ITEMS`
+ Eat(CmdEat),
+ /// `sell ITEMS`
+ Sell(CmdSell),
+
+ // ==== equipments ====
+
+ /// `equip ITEM`
+ Equip(CmdEquip),
+ /// `unequip ITEM` or `unequip CATEGORY`
+ UnEquip(CmdUnequip),
+ /// `use CATEGORY X times`
+ Use(CmdUse),
+ /// `shoot X times`
+ Shoot(CmdShoot),
+
+ // ==== overworld ====
+
+ /// `roast ITEMS`
+ Roast(CmdRoast),
+ /// `bake ITEMS` - same as roast
+ Bake(CmdBake),
+ /// `boil ITEMS` - same as roast except for eggs
+ Boil(CmdBoil),
+ /// `freeze ITEMS`
+ Freeze(CmdFreeze),
+ /// `destroy ITEMS`
+ Destroy(CmdDestroy),
+
+ // ==== inventory ====
+
+ /// `sort CATEGORY`
+ Sort(CmdSort),
+ /// `entangle CATEGORY [tab=X, rol=R, col=C]`
+ Entangle(CmdEntangle),
+
+ // ==== saves ====
+
+ /// `save`
+ Save(KwSave),
+ /// `save-as NAME`
+ SaveAs(CmdSaveAs),
+ /// `reload` or `reload NAME`
+ Reload(CmdReload),
+ /// `close-game`
+ CloseGame(KwCloseGame),
+ /// `new-game`
+ NewGame(KwNewGame),
+
+ // ==== scopes ====
+ OpenInventory(KwOpenInventory),
+ CloseInventory(KwCloseInventory),
+ TalkTo(KwTalkTo),
+ Untalk(KwUntalk),
+
+ // ==== trials ====
+
+ /// `enter TRIAL`
+ Enter(CmdEnter),
+ /// `exit` - exit current trial
+ Exit(KwExit),
+ /// `leave` - leave current trial without clearing it
+ Leave(KwLeave),
+
+}
+
+/// `get ITEMS` - items come from the area
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdGet {
+ pub lit: KwGet,
+ pub items: ItemListFinite,
+}
+
+/// `buy ITEMS` - items come from shop in the area
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdBuy {
+ pub lit: KwBuy,
+ pub items: ItemListFinite,
+}
+
+/// `pick-up ITEMS` - items come from ground
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdPickup {
+ pub lit: KwPickUp,
+ pub items: ItemListConstrained,
+}
+
+/// `hold ITEMS` - items come from inventory
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdHold {
+ pub lit: KwHold,
+ pub items: ItemListConstrained,
+}
+
+/// `hold-smuggle ITEMS` - items come from inventory, will not hold in overworld
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdHoldSmuggle {
+ pub lit: KwHoldSmuggle,
+ pub items: ItemListConstrained,
+}
+
+/// `hold-attach ITEMS` - items come from inventory,
+/// dropping happens after returning to overworld scope
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdHoldAttach {
+ pub lit: KwHoldAttach,
+ pub items: ItemListConstrained,
+}
+
+/// `drop` or `drop ITEMS`
+///
+/// `drop ITEMS` is a shorthand, which holds the items, then drop them.
+/// Cannot perform if already holding items. The exception is if the
+/// item has "drop" prompt instead of "hold" prompt (equipments),
+/// it will just drop the item instead
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdDrop {
+ pub lit: KwDrop,
+ pub items: tp::Option,
+}
+
+/// `dnp ITEMS` - shorthand for `drop ITEMS` and `pick-up ITEMS`
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdDnp {
+ pub lit: KwDnp,
+ pub items: ItemListConstrained,
+}
+
+/// `cook` or `cook ITEMS` - cook items in inventory
+///
+/// `cook ITEMS` is a shorthand, which holds the items, then cook them.
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdCook {
+ pub lit: KwCook,
+ pub items: tp::Option,
+}
+
+/// `eat ITEMS` - execute eat prompt on targeted items.
+/// The number is the times to eat the item.
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdEat {
+ pub lit: KwEat,
+ pub items: ItemListConstrained,
+}
+
+/// `sell ITEMS` - sell items to shop in the area.
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdSell {
+ pub lit: KwSell,
+ pub items: ItemListConstrained,
+}
+
+/// `equip ITEM` - equip one thing
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdEquip {
+ pub lit: KwEquip,
+ pub items: ItemWithSlot,
+}
+
+/// `unequip ITEM` - unequip one thing, or (all items) in one category
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdUnequip {
+ pub lit: KwUnequip,
+ pub items: ItemWithSlotOrCategory,
+}
+
+/// `use CATEGORY X times` - use the item
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdUse {
+ pub lit: KwUse,
+ pub category: Category,
+ pub times: TimesClause,
+}
+
+/// `shoot X times` is shorthand for `use bow X times`
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdShoot {
+ pub lit: KwShoot,
+ pub times: TimesClause,
+}
+
+/// `roast ITEMS` - roast items on the ground or in inventory
+///
+/// Items on the ground has priority, if there are not enough,
+/// but there are items in inventory, then `drop ITEMS` will be
+/// used to drop the items on the ground.
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdRoast {
+ pub lit: KwRoast,
+ pub items: ItemListConstrained,
+}
+
+/// Alias for `roast`
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdBake {
+ pub lit: KwBake,
+ pub items: ItemListConstrained,
+}
+
+/// Same as `roast`, except for eggs, where you will get boiled eggs
+/// instead of campfire eggs
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdBoil {
+ pub lit: KwBoil,
+ pub items: ItemListConstrained,
+}
+
+/// Similar to `roast`, but get the frozen variants
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdFreeze {
+ pub lit: KwFreeze,
+ pub items: ItemListConstrained,
+}
+
+/// Destroy items on the ground
+///
+/// This will just delete it from simulation. In the game,
+/// there are various way to do it: throw it into the sea,
+/// throw it into the lava, bomb it, etc.
+///
+/// If not enough items are on the ground, items from the inventory
+/// is used
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdDestroy {
+ pub lit: KwDestroy,
+ pub items: ItemListConstrained,
+}
+
+/// `sort CATEGORY` - sort the category
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdSort {
+ pub lit: KwSort,
+ pub category: Category,
+}
+
+/// `entangle CATEGORY [tab=X, rol=R, col=C]` - activate prompt entanglement
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdEntangle {
+ pub lit: KwEntangle,
+ pub category: Category,
+ pub meta: tp::Option
+}
+
+/// `save-as NAME` - save the game to a named slot
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdSaveAs {
+ pub lit: KwSaveAs,
+ pub name: tp::Vec,
+}
+
+/// `reload` - reload the game from manual or named save slot
+///
+/// This can also be used to start the game, then reload a save
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdReload {
+ pub lit: KwReload,
+ pub name: tp::Vec,
+}
+
+/// `enter TRIAL` - enter a trial
+///
+/// # Trials:
+/// - eventide
+/// - tots/trial of the sword
+/// - beginning trial (when you clear a TOTS for the first time, MS will be automatically upgraded,
+/// which constitutes a gamedata sync
+/// - middle trial
+/// - final trial
+/// - thunderblight refight (when you clear a refight for the first time, ability will be upgraded)
+/// - windblight refight
+/// - waterblight refight
+/// - fireblight refight
+#[derive_syntax]
+#[derive(Debug)]
+pub struct CmdEnter {
+ pub lit: KwEnter,
+ pub trial: tp::Vec,
+}
diff --git a/packages/parser/src/syn/item.rs b/packages/parser/src/syn/item.rs
new file mode 100644
index 0000000..bee2a05
--- /dev/null
+++ b/packages/parser/src/syn/item.rs
@@ -0,0 +1,127 @@
+//! Base syntax for specifying an item
+
+use teleparse::{derive_syntax, tp};
+
+use super::token::{
+ AngledWord, ColonOrEqual,
+ NumOrAll, NumOrInfinite, Number,
+ QuotedWord, SymComma, SymLBracket,
+ SymRBracket, Word, MetaValueLiteral, KwAll, SlotClause};
+
+use super::category::Category;
+
+/// Syntax for an item prefixed with a numeric amount
+#[derive_syntax]
+#[derive(Debug)]
+pub struct NumberedItem {
+ #[teleparse(semantic(Amount))]
+ pub num: Number,
+ pub item: Item,
+}
+
+/// Syntax for an item prefixed with an amount or "all"
+#[derive_syntax]
+#[derive(Debug)]
+pub enum NumberedOrAllItemOrCategory {
+ Numbered(NumberedItem),
+ All(AllItemOrCategory),
+}
+
+/// Syntax for an item prefixed with "all"
+#[derive_syntax]
+#[derive(Debug)]
+pub struct AllItemOrCategory {
+ #[teleparse(semantic(Amount))]
+ pub all: KwAll,
+ pub items: ItemOrCategory,
+}
+
+/// Syntax for an item or a category
+#[derive_syntax]
+#[derive(Debug)]
+pub enum ItemOrCategory {
+ Item(Item),
+ Category(Category),
+}
+
+/// Syntax for specifying a single item with a slot
+#[derive_syntax]
+#[derive(Debug)]
+pub struct ItemWithSlot {
+ pub item: Item,
+ pub slot: tp::Option,
+}
+
+/// Syntax for an item with a slot or a category
+#[derive_syntax]
+#[derive(Debug)]
+pub enum ItemWithSlotOrCategory {
+ Item(ItemWithSlot),
+ Category(Category),
+}
+
+/// Syntax for an item prefixed with an amount or "infinite"
+#[derive_syntax]
+#[derive(Debug)]
+pub struct NumberedOrInfiniteItem {
+ #[teleparse(semantic(Amount))]
+ pub num: NumOrInfinite,
+ pub item: Item,
+}
+
+/// Syntax for an item
+///
+/// # Example
+/// - `item`
+/// - `item[meta]`
+/// - `"item"`
+/// - `- `
+#[derive_syntax]
+#[derive(Debug)]
+pub struct Item {
+ #[teleparse(semantic(Name))]
+ pub name: ItemName,
+ pub meta: tp::Option
,
+}
+
+/// Syntax for the name of an item, like `item`, `"item"`, or `- `
+#[derive_syntax]
+#[derive(Debug)]
+pub enum ItemName {
+ /// Using `-` or `_` separated word to search item by English name
+ Word(Word),
+ /// Use quoted value to search by name in any language
+ Quoted(QuotedWord),
+ /// Use angle brackets to use the literal as the actor name
+ /// e.g. `
`
+ Angle(AngledWord),
+}
+
+/// Syntax for the metadata specifier for an item, e.g. `[key1:value1, key2=value2, key3]`
+#[derive_syntax]
+#[derive(Debug)]
+pub struct ItemMeta {
+ pub open: SymLBracket,
+ pub entries: tp::Punct,
+ pub close: SymRBracket,
+}
+
+/// A key-value pair in an item's metadata specifier
+#[derive_syntax]
+#[derive(Debug)]
+pub struct ItemMetaKeyValue {
+ /// The key of the key-value pair
+ #[teleparse(semantic(Variable))]
+ pub key: tp::String,
+ pub value: tp::Option