├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── osmos-cli ├── Cargo.toml └── src │ └── main.rs ├── osmos-core ├── Cargo.toml └── src │ ├── cell.rs │ ├── lib.rs │ └── sensor.rs ├── osmos-ga ├── Cargo.toml └── src │ ├── crossover.rs │ ├── evolve.rs │ ├── gene.rs │ ├── lib.rs │ ├── mutation.rs │ └── selection.rs ├── osmos-nn ├── Cargo.toml ├── src │ ├── layer.rs │ ├── lib.rs │ ├── network.rs │ └── neuron.rs └── tests │ ├── layer_test.rs │ ├── network_test.rs │ └── neuron_test.rs ├── osmos-sim ├── Cargo.toml ├── src │ ├── lib.rs │ ├── object.rs │ ├── simulator.rs │ └── system │ │ ├── collision.rs │ │ ├── epoch.rs │ │ ├── mod.rs │ │ ├── movement.rs │ │ ├── network.rs │ │ └── sensor.rs └── tests │ ├── object_test.rs │ ├── sensor_test.rs │ └── simulator_test.rs ├── osmos-wasm ├── Cargo.toml ├── cargo_watch.bat ├── src │ └── lib.rs ├── wasm_pack_build.bat └── wasm_pack_build.sh └── osmos-web ├── .gitignore ├── index.html ├── package-lock.json ├── package.json ├── public └── logo.svg ├── src ├── App.tsx ├── index.css └── index.tsx ├── tsconfig.json └── vite.config.ts /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/pkg 3 | **/*.DS_Store 4 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "approx" 7 | version = "0.5.1" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" 10 | dependencies = [ 11 | "num-traits", 12 | ] 13 | 14 | [[package]] 15 | name = "autocfg" 16 | version = "1.4.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 19 | 20 | [[package]] 21 | name = "bumpalo" 22 | version = "3.16.0" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 25 | 26 | [[package]] 27 | name = "bytemuck" 28 | version = "1.20.0" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" 31 | 32 | [[package]] 33 | name = "byteorder" 34 | version = "1.5.0" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 37 | 38 | [[package]] 39 | name = "cfg-if" 40 | version = "1.0.0" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 43 | 44 | [[package]] 45 | name = "getrandom" 46 | version = "0.2.15" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 49 | dependencies = [ 50 | "cfg-if", 51 | "js-sys", 52 | "libc", 53 | "wasi", 54 | "wasm-bindgen", 55 | ] 56 | 57 | [[package]] 58 | name = "js-sys" 59 | version = "0.3.76" 60 | source = "registry+https://github.com/rust-lang/crates.io-index" 61 | checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" 62 | dependencies = [ 63 | "once_cell", 64 | "wasm-bindgen", 65 | ] 66 | 67 | [[package]] 68 | name = "libc" 69 | version = "0.2.168" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" 72 | 73 | [[package]] 74 | name = "log" 75 | version = "0.4.22" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 78 | 79 | [[package]] 80 | name = "matrixmultiply" 81 | version = "0.3.9" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | checksum = "9380b911e3e96d10c1f415da0876389aaf1b56759054eeb0de7df940c456ba1a" 84 | dependencies = [ 85 | "autocfg", 86 | "rawpointer", 87 | ] 88 | 89 | [[package]] 90 | name = "nalgebra" 91 | version = "0.33.2" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b" 94 | dependencies = [ 95 | "approx", 96 | "matrixmultiply", 97 | "nalgebra-macros", 98 | "num-complex", 99 | "num-rational", 100 | "num-traits", 101 | "simba", 102 | "typenum", 103 | ] 104 | 105 | [[package]] 106 | name = "nalgebra-macros" 107 | version = "0.2.2" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc" 110 | dependencies = [ 111 | "proc-macro2", 112 | "quote", 113 | "syn", 114 | ] 115 | 116 | [[package]] 117 | name = "num-bigint" 118 | version = "0.4.6" 119 | source = "registry+https://github.com/rust-lang/crates.io-index" 120 | checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" 121 | dependencies = [ 122 | "num-integer", 123 | "num-traits", 124 | ] 125 | 126 | [[package]] 127 | name = "num-complex" 128 | version = "0.4.6" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" 131 | dependencies = [ 132 | "num-traits", 133 | ] 134 | 135 | [[package]] 136 | name = "num-integer" 137 | version = "0.1.46" 138 | source = "registry+https://github.com/rust-lang/crates.io-index" 139 | checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 140 | dependencies = [ 141 | "num-traits", 142 | ] 143 | 144 | [[package]] 145 | name = "num-rational" 146 | version = "0.4.2" 147 | source = "registry+https://github.com/rust-lang/crates.io-index" 148 | checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" 149 | dependencies = [ 150 | "num-bigint", 151 | "num-integer", 152 | "num-traits", 153 | ] 154 | 155 | [[package]] 156 | name = "num-traits" 157 | version = "0.2.19" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 160 | dependencies = [ 161 | "autocfg", 162 | ] 163 | 164 | [[package]] 165 | name = "once_cell" 166 | version = "1.20.2" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" 169 | 170 | [[package]] 171 | name = "osmos-cli" 172 | version = "0.1.0" 173 | dependencies = [ 174 | "osmos-sim", 175 | ] 176 | 177 | [[package]] 178 | name = "osmos-core" 179 | version = "0.1.0" 180 | dependencies = [ 181 | "nalgebra", 182 | "rand", 183 | ] 184 | 185 | [[package]] 186 | name = "osmos-ga" 187 | version = "0.1.0" 188 | dependencies = [ 189 | "rand", 190 | ] 191 | 192 | [[package]] 193 | name = "osmos-nn" 194 | version = "0.1.0" 195 | dependencies = [ 196 | "rand", 197 | ] 198 | 199 | [[package]] 200 | name = "osmos-sim" 201 | version = "0.1.0" 202 | dependencies = [ 203 | "nalgebra", 204 | "osmos-core", 205 | "osmos-ga", 206 | "osmos-nn", 207 | "rand", 208 | ] 209 | 210 | [[package]] 211 | name = "osmos-wasm" 212 | version = "0.1.0" 213 | dependencies = [ 214 | "getrandom", 215 | "osmos-sim", 216 | "serde", 217 | "serde-wasm-bindgen", 218 | "wasm-bindgen", 219 | ] 220 | 221 | [[package]] 222 | name = "paste" 223 | version = "1.0.15" 224 | source = "registry+https://github.com/rust-lang/crates.io-index" 225 | checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" 226 | 227 | [[package]] 228 | name = "ppv-lite86" 229 | version = "0.2.20" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" 232 | dependencies = [ 233 | "zerocopy", 234 | ] 235 | 236 | [[package]] 237 | name = "proc-macro2" 238 | version = "1.0.92" 239 | source = "registry+https://github.com/rust-lang/crates.io-index" 240 | checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" 241 | dependencies = [ 242 | "unicode-ident", 243 | ] 244 | 245 | [[package]] 246 | name = "quote" 247 | version = "1.0.37" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 250 | dependencies = [ 251 | "proc-macro2", 252 | ] 253 | 254 | [[package]] 255 | name = "rand" 256 | version = "0.8.5" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 259 | dependencies = [ 260 | "libc", 261 | "rand_chacha", 262 | "rand_core", 263 | ] 264 | 265 | [[package]] 266 | name = "rand_chacha" 267 | version = "0.3.1" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 270 | dependencies = [ 271 | "ppv-lite86", 272 | "rand_core", 273 | ] 274 | 275 | [[package]] 276 | name = "rand_core" 277 | version = "0.6.4" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 280 | dependencies = [ 281 | "getrandom", 282 | ] 283 | 284 | [[package]] 285 | name = "rawpointer" 286 | version = "0.2.1" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" 289 | 290 | [[package]] 291 | name = "safe_arch" 292 | version = "0.7.2" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "c3460605018fdc9612bce72735cba0d27efbcd9904780d44c7e3a9948f96148a" 295 | dependencies = [ 296 | "bytemuck", 297 | ] 298 | 299 | [[package]] 300 | name = "serde" 301 | version = "1.0.216" 302 | source = "registry+https://github.com/rust-lang/crates.io-index" 303 | checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" 304 | dependencies = [ 305 | "serde_derive", 306 | ] 307 | 308 | [[package]] 309 | name = "serde-wasm-bindgen" 310 | version = "0.6.5" 311 | source = "registry+https://github.com/rust-lang/crates.io-index" 312 | checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" 313 | dependencies = [ 314 | "js-sys", 315 | "serde", 316 | "wasm-bindgen", 317 | ] 318 | 319 | [[package]] 320 | name = "serde_derive" 321 | version = "1.0.216" 322 | source = "registry+https://github.com/rust-lang/crates.io-index" 323 | checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" 324 | dependencies = [ 325 | "proc-macro2", 326 | "quote", 327 | "syn", 328 | ] 329 | 330 | [[package]] 331 | name = "simba" 332 | version = "0.9.0" 333 | source = "registry+https://github.com/rust-lang/crates.io-index" 334 | checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa" 335 | dependencies = [ 336 | "approx", 337 | "num-complex", 338 | "num-traits", 339 | "paste", 340 | "wide", 341 | ] 342 | 343 | [[package]] 344 | name = "syn" 345 | version = "2.0.90" 346 | source = "registry+https://github.com/rust-lang/crates.io-index" 347 | checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" 348 | dependencies = [ 349 | "proc-macro2", 350 | "quote", 351 | "unicode-ident", 352 | ] 353 | 354 | [[package]] 355 | name = "typenum" 356 | version = "1.17.0" 357 | source = "registry+https://github.com/rust-lang/crates.io-index" 358 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 359 | 360 | [[package]] 361 | name = "unicode-ident" 362 | version = "1.0.14" 363 | source = "registry+https://github.com/rust-lang/crates.io-index" 364 | checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" 365 | 366 | [[package]] 367 | name = "wasi" 368 | version = "0.11.0+wasi-snapshot-preview1" 369 | source = "registry+https://github.com/rust-lang/crates.io-index" 370 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 371 | 372 | [[package]] 373 | name = "wasm-bindgen" 374 | version = "0.2.99" 375 | source = "registry+https://github.com/rust-lang/crates.io-index" 376 | checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" 377 | dependencies = [ 378 | "cfg-if", 379 | "once_cell", 380 | "wasm-bindgen-macro", 381 | ] 382 | 383 | [[package]] 384 | name = "wasm-bindgen-backend" 385 | version = "0.2.99" 386 | source = "registry+https://github.com/rust-lang/crates.io-index" 387 | checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" 388 | dependencies = [ 389 | "bumpalo", 390 | "log", 391 | "proc-macro2", 392 | "quote", 393 | "syn", 394 | "wasm-bindgen-shared", 395 | ] 396 | 397 | [[package]] 398 | name = "wasm-bindgen-macro" 399 | version = "0.2.99" 400 | source = "registry+https://github.com/rust-lang/crates.io-index" 401 | checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" 402 | dependencies = [ 403 | "quote", 404 | "wasm-bindgen-macro-support", 405 | ] 406 | 407 | [[package]] 408 | name = "wasm-bindgen-macro-support" 409 | version = "0.2.99" 410 | source = "registry+https://github.com/rust-lang/crates.io-index" 411 | checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" 412 | dependencies = [ 413 | "proc-macro2", 414 | "quote", 415 | "syn", 416 | "wasm-bindgen-backend", 417 | "wasm-bindgen-shared", 418 | ] 419 | 420 | [[package]] 421 | name = "wasm-bindgen-shared" 422 | version = "0.2.99" 423 | source = "registry+https://github.com/rust-lang/crates.io-index" 424 | checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" 425 | 426 | [[package]] 427 | name = "wide" 428 | version = "0.7.30" 429 | source = "registry+https://github.com/rust-lang/crates.io-index" 430 | checksum = "58e6db2670d2be78525979e9a5f9c69d296fd7d670549fe9ebf70f8708cb5019" 431 | dependencies = [ 432 | "bytemuck", 433 | "safe_arch", 434 | ] 435 | 436 | [[package]] 437 | name = "zerocopy" 438 | version = "0.7.35" 439 | source = "registry+https://github.com/rust-lang/crates.io-index" 440 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 441 | dependencies = [ 442 | "byteorder", 443 | "zerocopy-derive", 444 | ] 445 | 446 | [[package]] 447 | name = "zerocopy-derive" 448 | version = "0.7.35" 449 | source = "registry+https://github.com/rust-lang/crates.io-index" 450 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 451 | dependencies = [ 452 | "proc-macro2", 453 | "quote", 454 | "syn", 455 | ] 456 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = [ "osmos-cli","osmos-core", "osmos-ga", "osmos-nn", "osmos-sim", "osmos-wasm"] 4 | 5 | [profile.release] 6 | lto = true 7 | strip = true 8 | panic = "abort" 9 | codegen-units = 1 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU AFFERO GENERAL PUBLIC LICENSE 2 | Version 3, 19 November 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU Affero General Public License is a free, copyleft license for 11 | software and other kinds of works, specifically designed to ensure 12 | cooperation with the community in the case of network server software. 13 | 14 | The licenses for most software and other practical works are designed 15 | to take away your freedom to share and change the works. By contrast, 16 | our General Public Licenses are intended to guarantee your freedom to 17 | share and change all versions of a program--to make sure it remains free 18 | software for all its users. 19 | 20 | When we speak of free software, we are referring to freedom, not 21 | price. Our General Public Licenses are designed to make sure that you 22 | have the freedom to distribute copies of free software (and charge for 23 | them if you wish), that you receive source code or can get it if you 24 | want it, that you can change the software or use pieces of it in new 25 | free programs, and that you know you can do these things. 26 | 27 | Developers that use our General Public Licenses protect your rights 28 | with two steps: (1) assert copyright on the software, and (2) offer 29 | you this License which gives you legal permission to copy, distribute 30 | and/or modify the software. 31 | 32 | A secondary benefit of defending all users' freedom is that 33 | improvements made in alternate versions of the program, if they 34 | receive widespread use, become available for other developers to 35 | incorporate. Many developers of free software are heartened and 36 | encouraged by the resulting cooperation. However, in the case of 37 | software used on network servers, this result may fail to come about. 38 | The GNU General Public License permits making a modified version and 39 | letting the public access it on a server without ever releasing its 40 | source code to the public. 41 | 42 | The GNU Affero General Public License is designed specifically to 43 | ensure that, in such cases, the modified source code becomes available 44 | to the community. It requires the operator of a network server to 45 | provide the source code of the modified version running there to the 46 | users of that server. Therefore, public use of a modified version, on 47 | a publicly accessible server, gives the public access to the source 48 | code of the modified version. 49 | 50 | An older license, called the Affero General Public License and 51 | published by Affero, was designed to accomplish similar goals. This is 52 | a different license, not a version of the Affero GPL, but Affero has 53 | released a new version of the Affero GPL which permits relicensing under 54 | this license. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | TERMS AND CONDITIONS 60 | 61 | 0. Definitions. 62 | 63 | "This License" refers to version 3 of the GNU Affero General Public License. 64 | 65 | "Copyright" also means copyright-like laws that apply to other kinds of 66 | works, such as semiconductor masks. 67 | 68 | "The Program" refers to any copyrightable work licensed under this 69 | License. Each licensee is addressed as "you". "Licensees" and 70 | "recipients" may be individuals or organizations. 71 | 72 | To "modify" a work means to copy from or adapt all or part of the work 73 | in a fashion requiring copyright permission, other than the making of an 74 | exact copy. The resulting work is called a "modified version" of the 75 | earlier work or a work "based on" the earlier work. 76 | 77 | A "covered work" means either the unmodified Program or a work based 78 | on the Program. 79 | 80 | To "propagate" a work means to do anything with it that, without 81 | permission, would make you directly or secondarily liable for 82 | infringement under applicable copyright law, except executing it on a 83 | computer or modifying a private copy. Propagation includes copying, 84 | distribution (with or without modification), making available to the 85 | public, and in some countries other activities as well. 86 | 87 | To "convey" a work means any kind of propagation that enables other 88 | parties to make or receive copies. Mere interaction with a user through 89 | a computer network, with no transfer of a copy, is not conveying. 90 | 91 | An interactive user interface displays "Appropriate Legal Notices" 92 | to the extent that it includes a convenient and prominently visible 93 | feature that (1) displays an appropriate copyright notice, and (2) 94 | tells the user that there is no warranty for the work (except to the 95 | extent that warranties are provided), that licensees may convey the 96 | work under this License, and how to view a copy of this License. If 97 | the interface presents a list of user commands or options, such as a 98 | menu, a prominent item in the list meets this criterion. 99 | 100 | 1. Source Code. 101 | 102 | The "source code" for a work means the preferred form of the work 103 | for making modifications to it. "Object code" means any non-source 104 | form of a work. 105 | 106 | A "Standard Interface" means an interface that either is an official 107 | standard defined by a recognized standards body, or, in the case of 108 | interfaces specified for a particular programming language, one that 109 | is widely used among developers working in that language. 110 | 111 | The "System Libraries" of an executable work include anything, other 112 | than the work as a whole, that (a) is included in the normal form of 113 | packaging a Major Component, but which is not part of that Major 114 | Component, and (b) serves only to enable use of the work with that 115 | Major Component, or to implement a Standard Interface for which an 116 | implementation is available to the public in source code form. A 117 | "Major Component", in this context, means a major essential component 118 | (kernel, window system, and so on) of the specific operating system 119 | (if any) on which the executable work runs, or a compiler used to 120 | produce the work, or an object code interpreter used to run it. 121 | 122 | The "Corresponding Source" for a work in object code form means all 123 | the source code needed to generate, install, and (for an executable 124 | work) run the object code and to modify the work, including scripts to 125 | control those activities. However, it does not include the work's 126 | System Libraries, or general-purpose tools or generally available free 127 | programs which are used unmodified in performing those activities but 128 | which are not part of the work. For example, Corresponding Source 129 | includes interface definition files associated with source files for 130 | the work, and the source code for shared libraries and dynamically 131 | linked subprograms that the work is specifically designed to require, 132 | such as by intimate data communication or control flow between those 133 | subprograms and other parts of the work. 134 | 135 | The Corresponding Source need not include anything that users 136 | can regenerate automatically from other parts of the Corresponding 137 | Source. 138 | 139 | The Corresponding Source for a work in source code form is that 140 | same work. 141 | 142 | 2. Basic Permissions. 143 | 144 | All rights granted under this License are granted for the term of 145 | copyright on the Program, and are irrevocable provided the stated 146 | conditions are met. This License explicitly affirms your unlimited 147 | permission to run the unmodified Program. The output from running a 148 | covered work is covered by this License only if the output, given its 149 | content, constitutes a covered work. This License acknowledges your 150 | rights of fair use or other equivalent, as provided by copyright law. 151 | 152 | You may make, run and propagate covered works that you do not 153 | convey, without conditions so long as your license otherwise remains 154 | in force. You may convey covered works to others for the sole purpose 155 | of having them make modifications exclusively for you, or provide you 156 | with facilities for running those works, provided that you comply with 157 | the terms of this License in conveying all material for which you do 158 | not control copyright. Those thus making or running the covered works 159 | for you must do so exclusively on your behalf, under your direction 160 | and control, on terms that prohibit them from making any copies of 161 | your copyrighted material outside their relationship with you. 162 | 163 | Conveying under any other circumstances is permitted solely under 164 | the conditions stated below. Sublicensing is not allowed; section 10 165 | makes it unnecessary. 166 | 167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 168 | 169 | No covered work shall be deemed part of an effective technological 170 | measure under any applicable law fulfilling obligations under article 171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 172 | similar laws prohibiting or restricting circumvention of such 173 | measures. 174 | 175 | When you convey a covered work, you waive any legal power to forbid 176 | circumvention of technological measures to the extent such circumvention 177 | is effected by exercising rights under this License with respect to 178 | the covered work, and you disclaim any intention to limit operation or 179 | modification of the work as a means of enforcing, against the work's 180 | users, your or third parties' legal rights to forbid circumvention of 181 | technological measures. 182 | 183 | 4. Conveying Verbatim Copies. 184 | 185 | You may convey verbatim copies of the Program's source code as you 186 | receive it, in any medium, provided that you conspicuously and 187 | appropriately publish on each copy an appropriate copyright notice; 188 | keep intact all notices stating that this License and any 189 | non-permissive terms added in accord with section 7 apply to the code; 190 | keep intact all notices of the absence of any warranty; and give all 191 | recipients a copy of this License along with the Program. 192 | 193 | You may charge any price or no price for each copy that you convey, 194 | and you may offer support or warranty protection for a fee. 195 | 196 | 5. Conveying Modified Source Versions. 197 | 198 | You may convey a work based on the Program, or the modifications to 199 | produce it from the Program, in the form of source code under the 200 | terms of section 4, provided that you also meet all of these conditions: 201 | 202 | a) The work must carry prominent notices stating that you modified 203 | it, and giving a relevant date. 204 | 205 | b) The work must carry prominent notices stating that it is 206 | released under this License and any conditions added under section 207 | 7. This requirement modifies the requirement in section 4 to 208 | "keep intact all notices". 209 | 210 | c) You must license the entire work, as a whole, under this 211 | License to anyone who comes into possession of a copy. This 212 | License will therefore apply, along with any applicable section 7 213 | additional terms, to the whole of the work, and all its parts, 214 | regardless of how they are packaged. This License gives no 215 | permission to license the work in any other way, but it does not 216 | invalidate such permission if you have separately received it. 217 | 218 | d) If the work has interactive user interfaces, each must display 219 | Appropriate Legal Notices; however, if the Program has interactive 220 | interfaces that do not display Appropriate Legal Notices, your 221 | work need not make them do so. 222 | 223 | A compilation of a covered work with other separate and independent 224 | works, which are not by their nature extensions of the covered work, 225 | and which are not combined with it such as to form a larger program, 226 | in or on a volume of a storage or distribution medium, is called an 227 | "aggregate" if the compilation and its resulting copyright are not 228 | used to limit the access or legal rights of the compilation's users 229 | beyond what the individual works permit. Inclusion of a covered work 230 | in an aggregate does not cause this License to apply to the other 231 | parts of the aggregate. 232 | 233 | 6. Conveying Non-Source Forms. 234 | 235 | You may convey a covered work in object code form under the terms 236 | of sections 4 and 5, provided that you also convey the 237 | machine-readable Corresponding Source under the terms of this License, 238 | in one of these ways: 239 | 240 | a) Convey the object code in, or embodied in, a physical product 241 | (including a physical distribution medium), accompanied by the 242 | Corresponding Source fixed on a durable physical medium 243 | customarily used for software interchange. 244 | 245 | b) Convey the object code in, or embodied in, a physical product 246 | (including a physical distribution medium), accompanied by a 247 | written offer, valid for at least three years and valid for as 248 | long as you offer spare parts or customer support for that product 249 | model, to give anyone who possesses the object code either (1) a 250 | copy of the Corresponding Source for all the software in the 251 | product that is covered by this License, on a durable physical 252 | medium customarily used for software interchange, for a price no 253 | more than your reasonable cost of physically performing this 254 | conveying of source, or (2) access to copy the 255 | Corresponding Source from a network server at no charge. 256 | 257 | c) Convey individual copies of the object code with a copy of the 258 | written offer to provide the Corresponding Source. This 259 | alternative is allowed only occasionally and noncommercially, and 260 | only if you received the object code with such an offer, in accord 261 | with subsection 6b. 262 | 263 | d) Convey the object code by offering access from a designated 264 | place (gratis or for a charge), and offer equivalent access to the 265 | Corresponding Source in the same way through the same place at no 266 | further charge. You need not require recipients to copy the 267 | Corresponding Source along with the object code. If the place to 268 | copy the object code is a network server, the Corresponding Source 269 | may be on a different server (operated by you or a third party) 270 | that supports equivalent copying facilities, provided you maintain 271 | clear directions next to the object code saying where to find the 272 | Corresponding Source. Regardless of what server hosts the 273 | Corresponding Source, you remain obligated to ensure that it is 274 | available for as long as needed to satisfy these requirements. 275 | 276 | e) Convey the object code using peer-to-peer transmission, provided 277 | you inform other peers where the object code and Corresponding 278 | Source of the work are being offered to the general public at no 279 | charge under subsection 6d. 280 | 281 | A separable portion of the object code, whose source code is excluded 282 | from the Corresponding Source as a System Library, need not be 283 | included in conveying the object code work. 284 | 285 | A "User Product" is either (1) a "consumer product", which means any 286 | tangible personal property which is normally used for personal, family, 287 | or household purposes, or (2) anything designed or sold for incorporation 288 | into a dwelling. In determining whether a product is a consumer product, 289 | doubtful cases shall be resolved in favor of coverage. For a particular 290 | product received by a particular user, "normally used" refers to a 291 | typical or common use of that class of product, regardless of the status 292 | of the particular user or of the way in which the particular user 293 | actually uses, or expects or is expected to use, the product. A product 294 | is a consumer product regardless of whether the product has substantial 295 | commercial, industrial or non-consumer uses, unless such uses represent 296 | the only significant mode of use of the product. 297 | 298 | "Installation Information" for a User Product means any methods, 299 | procedures, authorization keys, or other information required to install 300 | and execute modified versions of a covered work in that User Product from 301 | a modified version of its Corresponding Source. The information must 302 | suffice to ensure that the continued functioning of the modified object 303 | code is in no case prevented or interfered with solely because 304 | modification has been made. 305 | 306 | If you convey an object code work under this section in, or with, or 307 | specifically for use in, a User Product, and the conveying occurs as 308 | part of a transaction in which the right of possession and use of the 309 | User Product is transferred to the recipient in perpetuity or for a 310 | fixed term (regardless of how the transaction is characterized), the 311 | Corresponding Source conveyed under this section must be accompanied 312 | by the Installation Information. But this requirement does not apply 313 | if neither you nor any third party retains the ability to install 314 | modified object code on the User Product (for example, the work has 315 | been installed in ROM). 316 | 317 | The requirement to provide Installation Information does not include a 318 | requirement to continue to provide support service, warranty, or updates 319 | for a work that has been modified or installed by the recipient, or for 320 | the User Product in which it has been modified or installed. Access to a 321 | network may be denied when the modification itself materially and 322 | adversely affects the operation of the network or violates the rules and 323 | protocols for communication across the network. 324 | 325 | Corresponding Source conveyed, and Installation Information provided, 326 | in accord with this section must be in a format that is publicly 327 | documented (and with an implementation available to the public in 328 | source code form), and must require no special password or key for 329 | unpacking, reading or copying. 330 | 331 | 7. Additional Terms. 332 | 333 | "Additional permissions" are terms that supplement the terms of this 334 | License by making exceptions from one or more of its conditions. 335 | Additional permissions that are applicable to the entire Program shall 336 | be treated as though they were included in this License, to the extent 337 | that they are valid under applicable law. If additional permissions 338 | apply only to part of the Program, that part may be used separately 339 | under those permissions, but the entire Program remains governed by 340 | this License without regard to the additional permissions. 341 | 342 | When you convey a copy of a covered work, you may at your option 343 | remove any additional permissions from that copy, or from any part of 344 | it. (Additional permissions may be written to require their own 345 | removal in certain cases when you modify the work.) You may place 346 | additional permissions on material, added by you to a covered work, 347 | for which you have or can give appropriate copyright permission. 348 | 349 | Notwithstanding any other provision of this License, for material you 350 | add to a covered work, you may (if authorized by the copyright holders of 351 | that material) supplement the terms of this License with terms: 352 | 353 | a) Disclaiming warranty or limiting liability differently from the 354 | terms of sections 15 and 16 of this License; or 355 | 356 | b) Requiring preservation of specified reasonable legal notices or 357 | author attributions in that material or in the Appropriate Legal 358 | Notices displayed by works containing it; or 359 | 360 | c) Prohibiting misrepresentation of the origin of that material, or 361 | requiring that modified versions of such material be marked in 362 | reasonable ways as different from the original version; or 363 | 364 | d) Limiting the use for publicity purposes of names of licensors or 365 | authors of the material; or 366 | 367 | e) Declining to grant rights under trademark law for use of some 368 | trade names, trademarks, or service marks; or 369 | 370 | f) Requiring indemnification of licensors and authors of that 371 | material by anyone who conveys the material (or modified versions of 372 | it) with contractual assumptions of liability to the recipient, for 373 | any liability that these contractual assumptions directly impose on 374 | those licensors and authors. 375 | 376 | All other non-permissive additional terms are considered "further 377 | restrictions" within the meaning of section 10. If the Program as you 378 | received it, or any part of it, contains a notice stating that it is 379 | governed by this License along with a term that is a further 380 | restriction, you may remove that term. If a license document contains 381 | a further restriction but permits relicensing or conveying under this 382 | License, you may add to a covered work material governed by the terms 383 | of that license document, provided that the further restriction does 384 | not survive such relicensing or conveying. 385 | 386 | If you add terms to a covered work in accord with this section, you 387 | must place, in the relevant source files, a statement of the 388 | additional terms that apply to those files, or a notice indicating 389 | where to find the applicable terms. 390 | 391 | Additional terms, permissive or non-permissive, may be stated in the 392 | form of a separately written license, or stated as exceptions; 393 | the above requirements apply either way. 394 | 395 | 8. Termination. 396 | 397 | You may not propagate or modify a covered work except as expressly 398 | provided under this License. Any attempt otherwise to propagate or 399 | modify it is void, and will automatically terminate your rights under 400 | this License (including any patent licenses granted under the third 401 | paragraph of section 11). 402 | 403 | However, if you cease all violation of this License, then your 404 | license from a particular copyright holder is reinstated (a) 405 | provisionally, unless and until the copyright holder explicitly and 406 | finally terminates your license, and (b) permanently, if the copyright 407 | holder fails to notify you of the violation by some reasonable means 408 | prior to 60 days after the cessation. 409 | 410 | Moreover, your license from a particular copyright holder is 411 | reinstated permanently if the copyright holder notifies you of the 412 | violation by some reasonable means, this is the first time you have 413 | received notice of violation of this License (for any work) from that 414 | copyright holder, and you cure the violation prior to 30 days after 415 | your receipt of the notice. 416 | 417 | Termination of your rights under this section does not terminate the 418 | licenses of parties who have received copies or rights from you under 419 | this License. If your rights have been terminated and not permanently 420 | reinstated, you do not qualify to receive new licenses for the same 421 | material under section 10. 422 | 423 | 9. Acceptance Not Required for Having Copies. 424 | 425 | You are not required to accept this License in order to receive or 426 | run a copy of the Program. Ancillary propagation of a covered work 427 | occurring solely as a consequence of using peer-to-peer transmission 428 | to receive a copy likewise does not require acceptance. However, 429 | nothing other than this License grants you permission to propagate or 430 | modify any covered work. These actions infringe copyright if you do 431 | not accept this License. Therefore, by modifying or propagating a 432 | covered work, you indicate your acceptance of this License to do so. 433 | 434 | 10. Automatic Licensing of Downstream Recipients. 435 | 436 | Each time you convey a covered work, the recipient automatically 437 | receives a license from the original licensors, to run, modify and 438 | propagate that work, subject to this License. You are not responsible 439 | for enforcing compliance by third parties with this License. 440 | 441 | An "entity transaction" is a transaction transferring control of an 442 | organization, or substantially all assets of one, or subdividing an 443 | organization, or merging organizations. If propagation of a covered 444 | work results from an entity transaction, each party to that 445 | transaction who receives a copy of the work also receives whatever 446 | licenses to the work the party's predecessor in interest had or could 447 | give under the previous paragraph, plus a right to possession of the 448 | Corresponding Source of the work from the predecessor in interest, if 449 | the predecessor has it or can get it with reasonable efforts. 450 | 451 | You may not impose any further restrictions on the exercise of the 452 | rights granted or affirmed under this License. For example, you may 453 | not impose a license fee, royalty, or other charge for exercise of 454 | rights granted under this License, and you may not initiate litigation 455 | (including a cross-claim or counterclaim in a lawsuit) alleging that 456 | any patent claim is infringed by making, using, selling, offering for 457 | sale, or importing the Program or any portion of it. 458 | 459 | 11. Patents. 460 | 461 | A "contributor" is a copyright holder who authorizes use under this 462 | License of the Program or a work on which the Program is based. The 463 | work thus licensed is called the contributor's "contributor version". 464 | 465 | A contributor's "essential patent claims" are all patent claims 466 | owned or controlled by the contributor, whether already acquired or 467 | hereafter acquired, that would be infringed by some manner, permitted 468 | by this License, of making, using, or selling its contributor version, 469 | but do not include claims that would be infringed only as a 470 | consequence of further modification of the contributor version. For 471 | purposes of this definition, "control" includes the right to grant 472 | patent sublicenses in a manner consistent with the requirements of 473 | this License. 474 | 475 | Each contributor grants you a non-exclusive, worldwide, royalty-free 476 | patent license under the contributor's essential patent claims, to 477 | make, use, sell, offer for sale, import and otherwise run, modify and 478 | propagate the contents of its contributor version. 479 | 480 | In the following three paragraphs, a "patent license" is any express 481 | agreement or commitment, however denominated, not to enforce a patent 482 | (such as an express permission to practice a patent or covenant not to 483 | sue for patent infringement). To "grant" such a patent license to a 484 | party means to make such an agreement or commitment not to enforce a 485 | patent against the party. 486 | 487 | If you convey a covered work, knowingly relying on a patent license, 488 | and the Corresponding Source of the work is not available for anyone 489 | to copy, free of charge and under the terms of this License, through a 490 | publicly available network server or other readily accessible means, 491 | then you must either (1) cause the Corresponding Source to be so 492 | available, or (2) arrange to deprive yourself of the benefit of the 493 | patent license for this particular work, or (3) arrange, in a manner 494 | consistent with the requirements of this License, to extend the patent 495 | license to downstream recipients. "Knowingly relying" means you have 496 | actual knowledge that, but for the patent license, your conveying the 497 | covered work in a country, or your recipient's use of the covered work 498 | in a country, would infringe one or more identifiable patents in that 499 | country that you have reason to believe are valid. 500 | 501 | If, pursuant to or in connection with a single transaction or 502 | arrangement, you convey, or propagate by procuring conveyance of, a 503 | covered work, and grant a patent license to some of the parties 504 | receiving the covered work authorizing them to use, propagate, modify 505 | or convey a specific copy of the covered work, then the patent license 506 | you grant is automatically extended to all recipients of the covered 507 | work and works based on it. 508 | 509 | A patent license is "discriminatory" if it does not include within 510 | the scope of its coverage, prohibits the exercise of, or is 511 | conditioned on the non-exercise of one or more of the rights that are 512 | specifically granted under this License. You may not convey a covered 513 | work if you are a party to an arrangement with a third party that is 514 | in the business of distributing software, under which you make payment 515 | to the third party based on the extent of your activity of conveying 516 | the work, and under which the third party grants, to any of the 517 | parties who would receive the covered work from you, a discriminatory 518 | patent license (a) in connection with copies of the covered work 519 | conveyed by you (or copies made from those copies), or (b) primarily 520 | for and in connection with specific products or compilations that 521 | contain the covered work, unless you entered into that arrangement, 522 | or that patent license was granted, prior to 28 March 2007. 523 | 524 | Nothing in this License shall be construed as excluding or limiting 525 | any implied license or other defenses to infringement that may 526 | otherwise be available to you under applicable patent law. 527 | 528 | 12. No Surrender of Others' Freedom. 529 | 530 | If conditions are imposed on you (whether by court order, agreement or 531 | otherwise) that contradict the conditions of this License, they do not 532 | excuse you from the conditions of this License. If you cannot convey a 533 | covered work so as to satisfy simultaneously your obligations under this 534 | License and any other pertinent obligations, then as a consequence you may 535 | not convey it at all. For example, if you agree to terms that obligate you 536 | to collect a royalty for further conveying from those to whom you convey 537 | the Program, the only way you could satisfy both those terms and this 538 | License would be to refrain entirely from conveying the Program. 539 | 540 | 13. Remote Network Interaction; Use with the GNU General Public License. 541 | 542 | Notwithstanding any other provision of this License, if you modify the 543 | Program, your modified version must prominently offer all users 544 | interacting with it remotely through a computer network (if your version 545 | supports such interaction) an opportunity to receive the Corresponding 546 | Source of your version by providing access to the Corresponding Source 547 | from a network server at no charge, through some standard or customary 548 | means of facilitating copying of software. This Corresponding Source 549 | shall include the Corresponding Source for any work covered by version 3 550 | of the GNU General Public License that is incorporated pursuant to the 551 | following paragraph. 552 | 553 | Notwithstanding any other provision of this License, you have 554 | permission to link or combine any covered work with a work licensed 555 | under version 3 of the GNU General Public License into a single 556 | combined work, and to convey the resulting work. The terms of this 557 | License will continue to apply to the part which is the covered work, 558 | but the work with which it is combined will remain governed by version 559 | 3 of the GNU General Public License. 560 | 561 | 14. Revised Versions of this License. 562 | 563 | The Free Software Foundation may publish revised and/or new versions of 564 | the GNU Affero General Public License from time to time. Such new versions 565 | will be similar in spirit to the present version, but may differ in detail to 566 | address new problems or concerns. 567 | 568 | Each version is given a distinguishing version number. If the 569 | Program specifies that a certain numbered version of the GNU Affero General 570 | Public License "or any later version" applies to it, you have the 571 | option of following the terms and conditions either of that numbered 572 | version or of any later version published by the Free Software 573 | Foundation. If the Program does not specify a version number of the 574 | GNU Affero General Public License, you may choose any version ever published 575 | by the Free Software Foundation. 576 | 577 | If the Program specifies that a proxy can decide which future 578 | versions of the GNU Affero General Public License can be used, that proxy's 579 | public statement of acceptance of a version permanently authorizes you 580 | to choose that version for the Program. 581 | 582 | Later license versions may give you additional or different 583 | permissions. However, no additional obligations are imposed on any 584 | author or copyright holder as a result of your choosing to follow a 585 | later version. 586 | 587 | 15. Disclaimer of Warranty. 588 | 589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 597 | 598 | 16. Limitation of Liability. 599 | 600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 608 | SUCH DAMAGES. 609 | 610 | 17. Interpretation of Sections 15 and 16. 611 | 612 | If the disclaimer of warranty and limitation of liability provided 613 | above cannot be given local legal effect according to their terms, 614 | reviewing courts shall apply local law that most closely approximates 615 | an absolute waiver of all civil liability in connection with the 616 | Program, unless a warranty or assumption of liability accompanies a 617 | copy of the Program in return for a fee. 618 | 619 | END OF TERMS AND CONDITIONS 620 | 621 | How to Apply These Terms to Your New Programs 622 | 623 | If you develop a new program, and you want it to be of the greatest 624 | possible use to the public, the best way to achieve this is to make it 625 | free software which everyone can redistribute and change under these terms. 626 | 627 | To do so, attach the following notices to the program. It is safest 628 | to attach them to the start of each source file to most effectively 629 | state the exclusion of warranty; and each file should have at least 630 | the "copyright" line and a pointer to where the full notice is found. 631 | 632 | 633 | Copyright (C) 634 | 635 | This program is free software: you can redistribute it and/or modify 636 | it under the terms of the GNU Affero General Public License as published 637 | by the Free Software Foundation, either version 3 of the License, or 638 | (at your option) any later version. 639 | 640 | This program is distributed in the hope that it will be useful, 641 | but WITHOUT ANY WARRANTY; without even the implied warranty of 642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 643 | GNU Affero General Public License for more details. 644 | 645 | You should have received a copy of the GNU Affero General Public License 646 | along with this program. If not, see . 647 | 648 | Also add information on how to contact you by electronic and paper mail. 649 | 650 | If your software can interact with users remotely through a computer 651 | network, you should also make sure that it provides a way for users to 652 | get its source. For example, if your program is a web application, its 653 | interface could display a "Source" link that leads users to an archive 654 | of the code. There are many ways you could offer source, and different 655 | solutions will be better for different programs; see section 13 for the 656 | specific requirements. 657 | 658 | You should also get your employer (if you work as a programmer) or school, 659 | if any, to sign a "copyright disclaimer" for the program, if necessary. 660 | For more information on this, and how to apply and follow the GNU AGPL, see 661 | . -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Osmos 2 | 3 | Rust + WASM + Vite + 神经网络 + 遗传算法 4 | 5 | Bilibili 视频:[BV1vj411A7k2](https://www.bilibili.com/video/BV1vj411A7k2) 6 | 7 | 立刻体验:[osmos.jerryshell.eu.org](https://osmos.jerryshell.eu.org) 8 | 9 | ## 如何运行 10 | 11 | 1. 安装 `wasm-pack` 12 | 13 | [https://rustwasm.github.io/wasm-pack](https://rustwasm.github.io/wasm-pack) 14 | 15 | 2. 编译 `osmos-wasm` 16 | 17 | ```bash 18 | cd osmos-wasm 19 | wasm-pack build --out-dir ../osmos-web/osmos-wasm 20 | ``` 21 | 22 | 3. 进入 `osmos-web` 安装依赖并运行 23 | 24 | ```bash 25 | cd osmos-web 26 | npm install 27 | npm run dev 28 | ``` 29 | 30 | ## 项目结构简介 31 | 32 | ``` 33 | osmos 34 | ├── osmos-core # 核心数据结构 35 | ├── osmos-ga # 遗传算法 36 | ├── osmos-nn # 神经网络 37 | ├── osmos-sim # 进化模拟器 38 | │ └── src 39 | │ └── system # 子系统 40 | │ ├── collision.rs # 碰撞系统 41 | │ ├── epoch.rs # 迭代系统 42 | │ ├── movement.rs # 移动系统 43 | │ ├── network.rs # 神经网络系统 44 | │ └── sensor.rs # 感知器系统 45 | ├── osmos-wasm # 将模拟器编译为 WASM,代理模式 46 | └── osmos-web # Web UI,通过导入 WASM 启动模拟器,并将模拟器的数据渲染到 Canvas 中 47 | ``` 48 | 49 | ## 开源协议 50 | 51 | [GNU Affero General Public License v3.0](LICENSE) 52 | -------------------------------------------------------------------------------- /osmos-cli/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "osmos-cli" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | osmos-sim = { path = "../osmos-sim" } 8 | -------------------------------------------------------------------------------- /osmos-cli/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut v = [-100.0, 0.0, 2.0, 3.0]; 3 | normalize(&mut v); 4 | println!("{:?}", v); 5 | 6 | let mut sim = osmos_sim::simulator::Simulator::default(); 7 | let mut max_step = 0; 8 | loop { 9 | sim.step(); 10 | max_step = max_step.max(sim.step_count); 11 | println!( 12 | "max_step:{} epoch_count:{} sensor:{:?} network_output:{:?} direction:{:?}", 13 | max_step, 14 | sim.epoch_count, 15 | sim.object_list[0].cell.sensor.data_list, 16 | sim.object_list[0].network_output, 17 | sim.object_list[0].cell.direction, 18 | ); 19 | } 20 | } 21 | 22 | fn normalize(v: &mut [f32; 4]) { 23 | let magnitude = (v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]).sqrt(); 24 | if magnitude != 0.0 { 25 | v[0] /= magnitude; 26 | v[1] /= magnitude; 27 | v[2] /= magnitude; 28 | v[3] /= magnitude; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /osmos-core/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "osmos-core" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | nalgebra = "*" 8 | rand = "*" 9 | -------------------------------------------------------------------------------- /osmos-core/src/cell.rs: -------------------------------------------------------------------------------- 1 | use rand::Rng; 2 | 3 | pub struct Cell { 4 | pub position: nalgebra::Point2, 5 | pub direction: nalgebra::Vector2, 6 | pub velocity: nalgebra::Vector2, 7 | pub energy: usize, 8 | pub sensor: crate::sensor::Sensor, 9 | } 10 | 11 | impl Cell { 12 | pub fn random(rng: &mut impl rand::RngCore) -> Self { 13 | let sensor_range = 0.5; 14 | let mut cell = Self { 15 | position: nalgebra::Point2::new(0.0, 0.0), 16 | direction: nalgebra::Vector2::new(0.0, 0.0), 17 | velocity: nalgebra::Vector2::new(0.0, 0.0), 18 | energy: rand::Rng::gen_range(rng, 1..=2), 19 | sensor: crate::sensor::Sensor::new(sensor_range), 20 | }; 21 | cell.random_position(rng); 22 | cell 23 | } 24 | 25 | pub fn random_position(&mut self, rng: &mut impl rand::RngCore) { 26 | self.position.x = rng.gen(); 27 | self.position.y = rng.gen(); 28 | } 29 | 30 | pub fn get_speed(&self) -> f32 { 31 | 0.001 + (1.0 / self.energy as f32) * 0.003 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /osmos-core/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod cell; 2 | pub mod sensor; 3 | -------------------------------------------------------------------------------- /osmos-core/src/sensor.rs: -------------------------------------------------------------------------------- 1 | pub struct Sensor { 2 | pub range: f32, 3 | // [up, right, down, left] 4 | pub data_list: [f32; 4], 5 | } 6 | 7 | impl Sensor { 8 | pub fn new(range: f32) -> Self { 9 | Self { 10 | range, 11 | data_list: [0.0; 4], 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /osmos-ga/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "osmos-ga" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | rand = "*" 8 | -------------------------------------------------------------------------------- /osmos-ga/src/crossover.rs: -------------------------------------------------------------------------------- 1 | pub fn crossover( 2 | rng: &mut impl rand::RngCore, 3 | parent_a_gene: &crate::gene::Gene, 4 | parent_b_gene: &crate::gene::Gene, 5 | ) -> crate::gene::Gene { 6 | parent_a_gene 7 | .iter() 8 | .zip(parent_b_gene) 9 | .map(|(&a, &b)| if rand::Rng::gen_bool(rng, 0.5) { a } else { b }) 10 | .collect() 11 | } 12 | -------------------------------------------------------------------------------- /osmos-ga/src/evolve.rs: -------------------------------------------------------------------------------- 1 | const MUTATE_CHANCE: f64 = 0.01; 2 | const MUTATE_COEFF: f32 = 0.3; 3 | 4 | pub fn evolve(rng: &mut impl rand::RngCore, object_list: &[T], object_count: usize) -> Vec 5 | where 6 | T: crate::gene::GeneObject, 7 | { 8 | (0..object_count) 9 | .map(|id| { 10 | // select parent_a and parent_b 11 | let parent_a_index = crate::selection::selection(rng, object_list); 12 | let parent_b_index = crate::selection::selection(rng, object_list); 13 | 14 | let parent_a = &object_list[parent_a_index]; 15 | let parent_b = &object_list[parent_b_index]; 16 | 17 | // get parent gene 18 | let parent_a_gene = parent_a.gene(); 19 | let parent_b_gene = parent_b.gene(); 20 | 21 | // get child_gene by crossover 22 | let mut child_gene = crate::crossover::crossover(rng, &parent_a_gene, &parent_b_gene); 23 | 24 | // mutate child_gene 25 | crate::mutation::mutation(rng, MUTATE_CHANCE, MUTATE_COEFF, &mut child_gene); 26 | 27 | // build a new object 28 | T::build(rng, child_gene, id) 29 | }) 30 | .collect::>() 31 | } 32 | -------------------------------------------------------------------------------- /osmos-ga/src/gene.rs: -------------------------------------------------------------------------------- 1 | pub type Gene = Vec; 2 | 3 | pub trait GeneObject { 4 | fn build(rng: &mut impl rand::RngCore, gene: Gene, id: usize) -> Self; 5 | 6 | fn gene(&self) -> Gene; 7 | 8 | fn fitness(&self) -> isize; 9 | } 10 | -------------------------------------------------------------------------------- /osmos-ga/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod crossover; 2 | pub mod evolve; 3 | pub mod gene; 4 | pub mod mutation; 5 | pub mod selection; 6 | -------------------------------------------------------------------------------- /osmos-ga/src/mutation.rs: -------------------------------------------------------------------------------- 1 | pub fn mutation( 2 | rng: &mut impl rand::RngCore, 3 | mutate_chance: f64, 4 | mutate_coeff: f32, 5 | gene: &mut crate::gene::Gene, 6 | ) { 7 | gene.iter_mut().for_each(|gene| { 8 | let mutate_flag = rand::Rng::gen_bool(rng, mutate_chance); 9 | if mutate_flag { 10 | let sign = if rand::Rng::gen_bool(rng, 0.5) { 11 | -1.0 12 | } else { 13 | 1.0 14 | }; 15 | *gene += sign * mutate_coeff * rand::Rng::gen::(rng); 16 | } 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /osmos-ga/src/selection.rs: -------------------------------------------------------------------------------- 1 | pub fn selection( 2 | rng: &mut impl rand::RngCore, 3 | object_list: &[impl crate::gene::GeneObject], 4 | ) -> usize { 5 | let total_fitness = object_list.iter().map(|o| o.fitness()).sum::(); 6 | loop { 7 | let random_index = rand::Rng::gen_range(rng, 0..object_list.len()); 8 | let fitness = object_list[random_index].fitness(); 9 | let probability = fitness as f64 / total_fitness as f64; 10 | if probability <= 0.0 { 11 | continue; 12 | } 13 | let win = rand::Rng::gen_bool(rng, probability); 14 | if win { 15 | return random_index; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /osmos-nn/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "osmos-nn" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | rand = "*" 8 | -------------------------------------------------------------------------------- /osmos-nn/src/layer.rs: -------------------------------------------------------------------------------- 1 | pub struct Layer { 2 | pub neuron_list: Vec, 3 | } 4 | 5 | impl Layer { 6 | pub fn new(neuron_list: Vec) -> Self { 7 | assert!(!neuron_list.is_empty()); 8 | let weight_list_len = neuron_list[0].weight_list.len(); 9 | assert!(neuron_list 10 | .iter() 11 | .all(|neuron| neuron.weight_list.len() == weight_list_len)); 12 | Self { neuron_list } 13 | } 14 | 15 | pub fn random( 16 | rng: &mut impl rand::RngCore, 17 | weight_list_len_per_neuron: usize, 18 | neuron_count: usize, 19 | ) -> Self { 20 | let neuron_list = (0..neuron_count) 21 | .map(|_| crate::neuron::Neuron::random(rng, weight_list_len_per_neuron)) 22 | .collect(); 23 | Self { neuron_list } 24 | } 25 | 26 | pub fn feed(&self, input_list: &[f32]) -> Vec { 27 | self.neuron_list 28 | .iter() 29 | .map(|neuron| neuron.feed(input_list)) 30 | .collect() 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /osmos-nn/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod layer; 2 | pub mod network; 3 | pub mod neuron; 4 | -------------------------------------------------------------------------------- /osmos-nn/src/network.rs: -------------------------------------------------------------------------------- 1 | pub struct Network { 2 | pub layer_list: Vec, 3 | } 4 | 5 | impl Network { 6 | pub fn new(layer_list: Vec) -> Self { 7 | Self { layer_list } 8 | } 9 | 10 | pub fn random(rng: &mut impl rand::RngCore, layer_topology: &[usize]) -> Self { 11 | assert!(layer_topology.len() > 1); 12 | let layer_list = layer_topology 13 | .windows(2) 14 | .map(|window| crate::layer::Layer::random(rng, window[0], window[1])) 15 | .collect(); 16 | Self { layer_list } 17 | } 18 | 19 | pub fn feed(&self, input_list: &[f32]) -> Vec { 20 | self.layer_list 21 | .iter() 22 | .fold(input_list.to_vec(), |input_list, x| x.feed(&input_list)) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /osmos-nn/src/neuron.rs: -------------------------------------------------------------------------------- 1 | pub const RANGE: std::ops::RangeInclusive = 0.0..=std::f32::consts::TAU; 2 | 3 | pub struct Neuron { 4 | pub bias: f32, 5 | pub weight_list: Vec, 6 | } 7 | 8 | impl Neuron { 9 | pub fn new(bias: f32, weight_list: &[f32]) -> Self { 10 | assert!(!weight_list.is_empty()); 11 | Self { 12 | bias, 13 | weight_list: weight_list.to_vec(), 14 | } 15 | } 16 | 17 | pub fn random(rng: &mut impl rand::RngCore, weight_list_len: usize) -> Self { 18 | let bias = rand::Rng::gen_range(rng, RANGE); 19 | let weight_list = (0..weight_list_len) 20 | .map(|_| rand::Rng::gen_range(rng, RANGE)) 21 | .collect(); 22 | Self { bias, weight_list } 23 | } 24 | 25 | pub fn feed(&self, input_list: &[f32]) -> f32 { 26 | let sum = input_list 27 | .iter() 28 | .zip(&self.weight_list) 29 | .map(|(input, weight)| input * weight) 30 | .sum::(); 31 | (sum + self.bias).max(0.0) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /osmos-nn/tests/layer_test.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn random_test() { 3 | let mut rng = rand::thread_rng(); 4 | let layer = osmos_nn::layer::Layer::random(&mut rng, 4, 10); 5 | assert!(layer.neuron_list.len() == 10); 6 | assert!(layer 7 | .neuron_list 8 | .iter() 9 | .all(|neuron| neuron.weight_list.len() == 4)); 10 | } 11 | 12 | #[test] 13 | fn feed_test() { 14 | let neuron_list = vec![ 15 | osmos_nn::neuron::Neuron::new(1.0, &[2.0, 3.0, 4.0]), 16 | osmos_nn::neuron::Neuron::new(1.0, &[2.0, 3.0, 4.0]), 17 | ]; 18 | let layer = osmos_nn::layer::Layer::new(neuron_list); 19 | let input_list = [2.0, 2.0, 2.0]; 20 | let output_list = layer.feed(&input_list); 21 | assert_eq!(output_list, &[19.0, 19.0]); 22 | } 23 | -------------------------------------------------------------------------------- /osmos-nn/tests/network_test.rs: -------------------------------------------------------------------------------- 1 | mod random { 2 | #[test] 3 | fn test() { 4 | let mut rng = rand::thread_rng(); 5 | let layer_topology = [4, 8, 2]; 6 | let network = osmos_nn::network::Network::random(&mut rng, &layer_topology); 7 | assert_eq!(network.layer_list[0].neuron_list.len(), layer_topology[1]); 8 | assert_eq!( 9 | network.layer_list[0].neuron_list[0].weight_list.len(), 10 | layer_topology[0] 11 | ); 12 | assert!(layer_topology.windows(2).zip(network.layer_list).all( 13 | |(layer_topology_window, layer)| { 14 | layer_topology_window[1] == layer.neuron_list.len() 15 | && layer_topology_window[0] == layer.neuron_list[0].weight_list.len() 16 | }, 17 | )); 18 | } 19 | } 20 | 21 | mod feed { 22 | #[test] 23 | fn test() { 24 | let layer_1 = osmos_nn::layer::Layer::new(vec![ 25 | osmos_nn::neuron::Neuron::new(1.0, &[2.0, 3.0, 4.0]), 26 | osmos_nn::neuron::Neuron::new(1.0, &[2.0, 3.0, 4.0]), 27 | ]); 28 | let layer_2 = osmos_nn::layer::Layer::new(vec![ 29 | osmos_nn::neuron::Neuron::new(1.0, &[2.0, 3.0]), 30 | osmos_nn::neuron::Neuron::new(1.0, &[2.0, 3.0]), 31 | ]); 32 | let layer_list = vec![layer_1, layer_2]; 33 | let network = osmos_nn::network::Network::new(layer_list); 34 | let input_list = [2.0, 2.0, 2.0]; 35 | let output_list = network.feed(&input_list); 36 | assert_eq!(output_list, [96.0, 96.0]); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /osmos-nn/tests/neuron_test.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn random_test() { 3 | let mut rng = rand::thread_rng(); 4 | let neuron = osmos_nn::neuron::Neuron::random(&mut rng, 100); 5 | assert!(neuron.weight_list.len() == 100); 6 | assert!(osmos_nn::neuron::RANGE.contains(&neuron.bias)); 7 | assert!(neuron 8 | .weight_list 9 | .iter() 10 | .all(|weight| osmos_nn::neuron::RANGE.contains(weight))); 11 | } 12 | 13 | #[test] 14 | fn feed_test() { 15 | let neuron = osmos_nn::neuron::Neuron::new(1.0, &[2.0, 3.0, 4.0]); 16 | let input_list = [2.0, 2.0, 2.0]; 17 | let output = neuron.feed(&input_list); 18 | assert!(output == 19.0); 19 | } 20 | -------------------------------------------------------------------------------- /osmos-sim/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "osmos-sim" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | osmos-core = { path = "../osmos-core" } 8 | osmos-ga = { path = "../osmos-ga" } 9 | osmos-nn = { path = "../osmos-nn" } 10 | nalgebra = "*" 11 | rand = "*" 12 | -------------------------------------------------------------------------------- /osmos-sim/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod object; 2 | pub mod simulator; 3 | pub mod system; 4 | -------------------------------------------------------------------------------- /osmos-sim/src/object.rs: -------------------------------------------------------------------------------- 1 | // 4 = [sensor_up, sensor_right, sensor_down, sensor_left] 2 | // 1 = [angle] 3 | const NETWORK_LAYER_TOPOLOGY: [usize; 3] = [4, 8, 1]; 4 | 5 | pub struct Object { 6 | pub id: usize, 7 | pub cell: osmos_core::cell::Cell, 8 | pub network: osmos_nn::network::Network, 9 | pub network_output: f32, 10 | } 11 | 12 | impl Object { 13 | pub fn new(rng: &mut impl rand::RngCore, id: usize) -> Self { 14 | Self { 15 | id, 16 | cell: osmos_core::cell::Cell::random(rng), 17 | network: osmos_nn::network::Network::random(rng, &NETWORK_LAYER_TOPOLOGY), 18 | network_output: 0.0, 19 | } 20 | } 21 | 22 | pub fn from_network( 23 | rng: &mut impl rand::RngCore, 24 | network: osmos_nn::network::Network, 25 | id: usize, 26 | ) -> Self { 27 | Self { 28 | id, 29 | cell: osmos_core::cell::Cell::random(rng), 30 | network, 31 | network_output: 0.0, 32 | } 33 | } 34 | } 35 | 36 | impl osmos_ga::gene::GeneObject for Object { 37 | fn gene(&self) -> osmos_ga::gene::Gene { 38 | get_gene_from_network(&self.network) 39 | } 40 | 41 | fn fitness(&self) -> isize { 42 | self.cell.energy as isize 43 | } 44 | 45 | fn build(rng: &mut impl rand::RngCore, gene: osmos_ga::gene::Gene, id: usize) -> Self { 46 | let network = build_network(&NETWORK_LAYER_TOPOLOGY, &gene); 47 | Self::from_network(rng, network, id) 48 | } 49 | } 50 | 51 | pub fn get_gene_from_network(network: &osmos_nn::network::Network) -> osmos_ga::gene::Gene { 52 | network 53 | .layer_list 54 | .iter() 55 | .flat_map(get_gene_from_layer) 56 | .collect() 57 | } 58 | 59 | fn get_gene_from_layer(layer: &osmos_nn::layer::Layer) -> osmos_ga::gene::Gene { 60 | layer 61 | .neuron_list 62 | .iter() 63 | .flat_map(get_gene_from_neuron) 64 | .collect() 65 | } 66 | 67 | fn get_gene_from_neuron(neuron: &osmos_nn::neuron::Neuron) -> osmos_ga::gene::Gene { 68 | let mut gene = Vec::with_capacity(neuron.weight_list.len() + 1); 69 | gene.push(neuron.bias); 70 | gene.append(&mut neuron.weight_list.clone()); 71 | gene 72 | } 73 | 74 | pub fn build_network(layer_topology: &[usize], gene: &[f32]) -> osmos_nn::network::Network { 75 | let mut gene_data_iter = gene.iter().copied(); 76 | let layer_list = layer_topology 77 | .windows(2) 78 | .map(|window| build_layer(window[0], window[1], &mut gene_data_iter)) 79 | .collect(); 80 | osmos_nn::network::Network::new(layer_list) 81 | } 82 | 83 | fn build_layer( 84 | weight_list_len_per_neuron: usize, 85 | neuron_count: usize, 86 | gene_data_iter: &mut impl Iterator, 87 | ) -> osmos_nn::layer::Layer { 88 | let neuron_list = (0..neuron_count) 89 | .map(|_| build_neuron(weight_list_len_per_neuron, gene_data_iter)) 90 | .collect(); 91 | osmos_nn::layer::Layer::new(neuron_list) 92 | } 93 | 94 | fn build_neuron( 95 | weight_list_len: usize, 96 | gene_data_iter: &mut impl Iterator, 97 | ) -> osmos_nn::neuron::Neuron { 98 | let bias = gene_data_iter 99 | .next() 100 | .expect("build neuron from gene_data_iter failed"); 101 | let weight_list = (0..weight_list_len) 102 | .map(|_| { 103 | gene_data_iter 104 | .next() 105 | .expect("build neuron from gene_data_iter failed") 106 | }) 107 | .collect::(); 108 | osmos_nn::neuron::Neuron::new(bias, &weight_list) 109 | } 110 | -------------------------------------------------------------------------------- /osmos-sim/src/simulator.rs: -------------------------------------------------------------------------------- 1 | pub struct Simulator { 2 | pub rng: rand::rngs::ThreadRng, 3 | pub object_count: usize, 4 | pub object_list: Vec, 5 | pub step_count: usize, 6 | pub max_step_count_per_epoch: usize, 7 | pub min_object_count_per_epoch: usize, 8 | pub epoch_count: usize, 9 | } 10 | 11 | impl Default for Simulator { 12 | fn default() -> Self { 13 | let object_count = 300; 14 | let mut rng = rand::thread_rng(); 15 | let object_list = (0..object_count) 16 | .map(|id| crate::object::Object::new(&mut rng, id)) 17 | .collect(); 18 | Self { 19 | rng, 20 | object_count, 21 | object_list, 22 | step_count: 0, 23 | max_step_count_per_epoch: 5000, 24 | min_object_count_per_epoch: 50, 25 | epoch_count: 0, 26 | } 27 | } 28 | } 29 | 30 | impl Simulator { 31 | pub fn step(&mut self) { 32 | crate::system::sensor::process(&mut self.object_list); 33 | crate::system::network::process(&mut self.object_list); 34 | crate::system::collision::process(&mut self.object_list); 35 | crate::system::movement::process(&mut self.rng, &mut self.object_list); 36 | crate::system::epoch::process(self); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /osmos-sim/src/system/collision.rs: -------------------------------------------------------------------------------- 1 | pub fn process(object_list: &mut Vec) { 2 | for current_object_index in 0..object_list.len() { 3 | for other_object_index in 0..object_list.len() { 4 | if current_object_index == other_object_index { 5 | continue; 6 | } 7 | 8 | let current_object_energy = object_list[current_object_index].cell.energy; 9 | if current_object_energy == 0 { 10 | continue; 11 | } 12 | 13 | let other_object_energy = object_list[other_object_index].cell.energy; 14 | if other_object_energy == 0 { 15 | continue; 16 | } 17 | 18 | // check collide 19 | let current_object_position = &object_list[current_object_index].cell.position; 20 | let other_object_position = &object_list[other_object_index].cell.position; 21 | let distance = nalgebra::distance(current_object_position, other_object_position); 22 | let energy_sum = current_object_energy + other_object_energy; 23 | if distance >= energy_sum as f32 / 1000.0 { 24 | // current_object and other_object did not collide 25 | continue; 26 | } 27 | 28 | match current_object_energy.cmp(&other_object_energy) { 29 | std::cmp::Ordering::Greater => { 30 | object_list[current_object_index].cell.energy += 1; 31 | object_list[other_object_index].cell.energy -= 1; 32 | } 33 | std::cmp::Ordering::Less => { 34 | object_list[current_object_index].cell.energy -= 1; 35 | object_list[other_object_index].cell.energy += 1; 36 | } 37 | std::cmp::Ordering::Equal => { 38 | let direction = 39 | (current_object_position - other_object_position).cap_magnitude(1.0); 40 | let current_speed = object_list[current_object_index].cell.get_speed(); 41 | let other_speed = object_list[other_object_index].cell.get_speed(); 42 | object_list[current_object_index].cell.velocity = direction * current_speed; 43 | object_list[other_object_index].cell.velocity = -direction * other_speed; 44 | } 45 | } 46 | } 47 | } 48 | // delete Object with energy <= 0 49 | object_list.retain(|object| object.cell.energy > 0); 50 | } 51 | -------------------------------------------------------------------------------- /osmos-sim/src/system/epoch.rs: -------------------------------------------------------------------------------- 1 | pub fn process(simulator: &mut crate::simulator::Simulator) { 2 | simulator.step_count += 1; 3 | if is_epoch_end(simulator) { 4 | let new_object_list = osmos_ga::evolve::evolve( 5 | &mut simulator.rng, 6 | &simulator.object_list, 7 | simulator.object_count, 8 | ); 9 | simulator.object_list = new_object_list; 10 | simulator.step_count = 0; 11 | simulator.epoch_count += 1; 12 | } 13 | } 14 | 15 | fn is_epoch_end(simulator: &crate::simulator::Simulator) -> bool { 16 | simulator.step_count >= simulator.max_step_count_per_epoch 17 | || simulator.object_list.len() <= simulator.min_object_count_per_epoch 18 | } 19 | -------------------------------------------------------------------------------- /osmos-sim/src/system/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod collision; 2 | pub mod epoch; 3 | pub mod movement; 4 | pub mod network; 5 | pub mod sensor; 6 | -------------------------------------------------------------------------------- /osmos-sim/src/system/movement.rs: -------------------------------------------------------------------------------- 1 | use rand::Rng; 2 | 3 | pub fn process(rng: &mut impl rand::RngCore, object_list: &mut [crate::object::Object]) { 4 | object_list.iter_mut().for_each(|object| { 5 | object.cell.direction.x = object.network_output.cos() * object.cell.get_speed(); 6 | object.cell.direction.y = object.network_output.sin() * object.cell.get_speed(); 7 | 8 | object.cell.velocity = object.cell.direction; 9 | 10 | object.cell.position += object.cell.velocity; 11 | 12 | if object.cell.position.x < 0.0 13 | || object.cell.position.x > 1.0 14 | || object.cell.position.y < 0.0 15 | || object.cell.position.y > 1.0 16 | { 17 | object.cell.position.x = rng.gen(); 18 | object.cell.position.y = rng.gen(); 19 | } 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /osmos-sim/src/system/network.rs: -------------------------------------------------------------------------------- 1 | pub fn process(object_list: &mut [crate::object::Object]) { 2 | object_list.iter_mut().for_each(|object| { 3 | let nn_output = object.network.feed(&object.cell.sensor.data_list); 4 | object.network_output = nn_output[0]; 5 | }); 6 | } 7 | -------------------------------------------------------------------------------- /osmos-sim/src/system/sensor.rs: -------------------------------------------------------------------------------- 1 | pub fn process(object_list: &mut [crate::object::Object]) { 2 | for current_object_index in 0..object_list.len() { 3 | // get other object index list 4 | let other_object_index_list = object_list 5 | .iter() 6 | .enumerate() 7 | .map(|(index, _)| index) 8 | .filter(|&index| index != current_object_index) 9 | .collect::>(); 10 | 11 | // get in sensor range other object index list 12 | let in_sensor_range_other_object_index_list = other_object_index_list 13 | .iter() 14 | .filter(|&&other_object_index| { 15 | let distance = nalgebra::distance( 16 | &object_list[current_object_index].cell.position, 17 | &object_list[other_object_index].cell.position, 18 | ); 19 | distance <= object_list[current_object_index].cell.sensor.range 20 | }) 21 | .copied() 22 | .collect::>(); 23 | 24 | // set sensor_data_list by energy and position 25 | // [up, right, down, left] 26 | let mut sensor_data_list = [0.0; 4]; 27 | in_sensor_range_other_object_index_list 28 | .iter() 29 | .for_each(|&other_object_index| { 30 | let current_object_energy = object_list[current_object_index].cell.energy; 31 | let other_object_energy = object_list[other_object_index].cell.energy; 32 | 33 | let current_object_position = object_list[current_object_index].cell.position; 34 | let other_object_position = object_list[other_object_index].cell.position; 35 | let direction = 36 | (other_object_position - current_object_position).cap_magnitude(1.0); 37 | 38 | let sensor_range = object_list[current_object_index].cell.sensor.range; 39 | let distance = nalgebra::distance(¤t_object_position, &other_object_position); 40 | 41 | let status = (current_object_energy as f32 - other_object_energy as f32) 42 | * ((sensor_range - distance) / sensor_range); 43 | 44 | // up-right 45 | if direction.x > 0.0 && direction.y >= 0.0 { 46 | sensor_data_list[0] += status; 47 | } 48 | // up-left 49 | if direction.x <= 0.0 && direction.y > 0.0 { 50 | sensor_data_list[1] += status; 51 | } 52 | // down-left 53 | if direction.x < 0.0 && direction.y <= 0.0 { 54 | sensor_data_list[2] += status; 55 | } 56 | // down-right 57 | if direction.x >= 0.0 && direction.y < 0.0 { 58 | sensor_data_list[3] += status; 59 | } 60 | }); 61 | normalize(&mut sensor_data_list); 62 | object_list[current_object_index].cell.sensor.data_list = sensor_data_list; 63 | } 64 | } 65 | 66 | fn normalize(v: &mut [f32; 4]) { 67 | let magnitude = (v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3]).sqrt(); 68 | if magnitude != 0.0 { 69 | v[0] /= magnitude; 70 | v[1] /= magnitude; 71 | v[2] /= magnitude; 72 | v[3] /= magnitude; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /osmos-sim/tests/object_test.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn get_gene_from_network_test() { 3 | let mut rng = rand::thread_rng(); 4 | let network = osmos_nn::network::Network::random(&mut rng, &[4, 6, 2]); 5 | let gene = osmos_sim::object::get_gene_from_network(&network); 6 | assert_eq!(gene.len(), (4 * 6 + 6) + (6 * 2 + 2)); 7 | } 8 | 9 | #[test] 10 | fn build_network_from_gene_test() { 11 | let mut rng = rand::thread_rng(); 12 | let network = osmos_nn::network::Network::random(&mut rng, &[4, 6, 2]); 13 | let gene = osmos_sim::object::get_gene_from_network(&network); 14 | 15 | let network_2 = osmos_sim::object::build_network(&[4, 6, 2], &gene); 16 | 17 | assert_eq!(gene, osmos_sim::object::get_gene_from_network(&network_2)); 18 | } 19 | -------------------------------------------------------------------------------- /osmos-sim/tests/sensor_test.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn danger_u_test() { 3 | let mut rng = rand::thread_rng(); 4 | let mut object_1 = osmos_sim::object::Object::new(&mut rng, 1); 5 | object_1.cell.position.x = 0.0; 6 | object_1.cell.position.y = 0.0; 7 | object_1.cell.energy = 1; 8 | let mut object_2 = osmos_sim::object::Object::new(&mut rng, 2); 9 | object_2.cell.position.x = 0.0; 10 | object_2.cell.position.y = 0.1; 11 | object_2.cell.energy = 2; 12 | let mut object_list = [object_1, object_2]; 13 | osmos_sim::system::sensor::process(&mut object_list); 14 | assert_eq!(object_list[0].cell.sensor.data_list, [0.0, -1.0, 0.0, 0.0]); 15 | assert_eq!(object_list[1].cell.sensor.data_list, [0.0, 0.0, 0.0, 1.0]); 16 | } 17 | 18 | #[test] 19 | fn danger_r_test() { 20 | let mut rng = rand::thread_rng(); 21 | let mut object_1 = osmos_sim::object::Object::new(&mut rng, 1); 22 | object_1.cell.position.x = 0.0; 23 | object_1.cell.position.y = 0.0; 24 | object_1.cell.energy = 1; 25 | let mut object_2 = osmos_sim::object::Object::new(&mut rng, 2); 26 | object_2.cell.position.x = 0.1; 27 | object_2.cell.position.y = 0.0; 28 | object_2.cell.energy = 2; 29 | let mut object_list = [object_1, object_2]; 30 | osmos_sim::system::sensor::process(&mut object_list); 31 | assert_eq!(object_list[0].cell.sensor.data_list, [-1.0, 0.0, 0.0, 0.0]); 32 | assert_eq!(object_list[1].cell.sensor.data_list, [0.0, 0.0, 1.0, 0.0]); 33 | } 34 | 35 | #[test] 36 | fn danger_d_test() { 37 | let mut rng = rand::thread_rng(); 38 | let mut object_1 = osmos_sim::object::Object::new(&mut rng, 1); 39 | object_1.cell.position.x = 0.0; 40 | object_1.cell.position.y = 0.0; 41 | object_1.cell.energy = 1; 42 | let mut object_2 = osmos_sim::object::Object::new(&mut rng, 2); 43 | object_2.cell.position.x = 0.0; 44 | object_2.cell.position.y = -0.1; 45 | object_2.cell.energy = 2; 46 | let mut object_list = [object_1, object_2]; 47 | osmos_sim::system::sensor::process(&mut object_list); 48 | assert_eq!(object_list[0].cell.sensor.data_list, [0.0, 0.0, 0.0, -1.0]); 49 | assert_eq!(object_list[1].cell.sensor.data_list, [0.0, 1.0, 0.0, 0.0]); 50 | } 51 | 52 | #[test] 53 | fn danger_l_test() { 54 | let mut rng = rand::thread_rng(); 55 | let mut object_1 = osmos_sim::object::Object::new(&mut rng, 1); 56 | object_1.cell.position.x = 0.0; 57 | object_1.cell.position.y = 0.0; 58 | object_1.cell.energy = 1; 59 | let mut object_2 = osmos_sim::object::Object::new(&mut rng, 2); 60 | object_2.cell.position.x = -0.1; 61 | object_2.cell.position.y = 0.0; 62 | object_2.cell.energy = 2; 63 | let mut object_list = [object_1, object_2]; 64 | osmos_sim::system::sensor::process(&mut object_list); 65 | assert_eq!(object_list[0].cell.sensor.data_list, [0.0, 0.0, -1.0, 0.0]); 66 | assert_eq!(object_list[1].cell.sensor.data_list, [1.0, 0.0, 0.0, 0.0]); 67 | } 68 | 69 | #[test] 70 | fn danger_rd_test() { 71 | let mut rng = rand::thread_rng(); 72 | let mut object_1 = osmos_sim::object::Object::new(&mut rng, 1); 73 | object_1.cell.position.x = 0.0; 74 | object_1.cell.position.y = 0.0; 75 | object_1.cell.energy = 1; 76 | let mut object_2 = osmos_sim::object::Object::new(&mut rng, 2); 77 | object_2.cell.position.x = 0.1; 78 | object_2.cell.position.y = 0.1; 79 | object_2.cell.energy = 2; 80 | let mut object_list = [object_1, object_2]; 81 | osmos_sim::system::sensor::process(&mut object_list); 82 | assert_eq!(object_list[0].cell.sensor.data_list, [-1.0, 0.0, 0.0, 0.0]); 83 | assert_eq!(object_list[1].cell.sensor.data_list, [0.0, 0.0, 1.0, 0.0]); 84 | } 85 | 86 | #[test] 87 | fn danger_lu_test() { 88 | assert_eq!( 89 | nalgebra::Vector2::new(-1.0, -1.0).angle(&nalgebra::Vector2::new(1.0, 0.0)), 90 | nalgebra::Vector2::new(-1.0, 1.0).angle(&nalgebra::Vector2::new(1.0, 0.0)) 91 | ); 92 | let mut rng = rand::thread_rng(); 93 | let mut object_1 = osmos_sim::object::Object::new(&mut rng, 1); 94 | object_1.cell.position.x = 0.0; 95 | object_1.cell.position.y = 0.0; 96 | object_1.cell.energy = 1; 97 | let mut object_2 = osmos_sim::object::Object::new(&mut rng, 2); 98 | object_2.cell.position.x = -0.1; 99 | object_2.cell.position.y = -0.1; 100 | object_2.cell.energy = 2; 101 | let mut object_list = [object_1, object_2]; 102 | osmos_sim::system::sensor::process(&mut object_list); 103 | assert_eq!(object_list[0].cell.sensor.data_list, [0.0, 0.0, -1.0, 0.0]); 104 | } 105 | 106 | #[test] 107 | fn danger_ru_test() { 108 | let mut rng = rand::thread_rng(); 109 | let mut object_1 = osmos_sim::object::Object::new(&mut rng, 1); 110 | object_1.cell.position.x = 0.0; 111 | object_1.cell.position.y = 0.0; 112 | object_1.cell.energy = 1; 113 | let mut object_2 = osmos_sim::object::Object::new(&mut rng, 2); 114 | object_2.cell.position.x = 0.1; 115 | object_2.cell.position.y = -0.1; 116 | object_2.cell.energy = 2; 117 | let mut object_list = [object_1, object_2]; 118 | osmos_sim::system::sensor::process(&mut object_list); 119 | assert_eq!(object_list[0].cell.energy, 1); 120 | assert_eq!(object_list[1].cell.energy, 2); 121 | assert_eq!(object_list[0].cell.sensor.data_list, [0.0, 0.0, 0.0, -1.0]); 122 | } 123 | 124 | #[test] 125 | fn danger_ld_test() { 126 | let mut rng = rand::thread_rng(); 127 | let mut object_1 = osmos_sim::object::Object::new(&mut rng, 1); 128 | object_1.cell.position.x = 0.0; 129 | object_1.cell.position.y = 0.0; 130 | object_1.cell.energy = 1; 131 | let mut object_2 = osmos_sim::object::Object::new(&mut rng, 2); 132 | object_2.cell.position.x = -0.3; 133 | object_2.cell.position.y = 0.3; 134 | object_2.cell.energy = 2; 135 | let mut object_list = [object_1, object_2]; 136 | osmos_sim::system::sensor::process(&mut object_list); 137 | assert_eq!(object_list[0].cell.sensor.data_list, [0.0, -1.0, 0.0, 0.0]); 138 | } 139 | 140 | #[test] 141 | fn food_ld_test() { 142 | let mut rng = rand::thread_rng(); 143 | let mut object_1 = osmos_sim::object::Object::new(&mut rng, 1); 144 | object_1.cell.position.x = 0.0; 145 | object_1.cell.position.y = 0.0; 146 | object_1.cell.energy = 2; 147 | let mut object_2 = osmos_sim::object::Object::new(&mut rng, 2); 148 | object_2.cell.position.x = -0.1; 149 | object_2.cell.position.y = 0.1; 150 | object_2.cell.energy = 3; 151 | let mut object_3 = osmos_sim::object::Object::new(&mut rng, 3); 152 | object_3.cell.position.x = -0.01; 153 | object_3.cell.position.y = 0.01; 154 | object_3.cell.energy = 1; 155 | let mut object_list = [object_1, object_2, object_3]; 156 | osmos_sim::system::sensor::process(&mut object_list); 157 | assert_eq!(object_list[0].cell.sensor.data_list, [0.0, 1.0, 0.0, 0.0]); 158 | } 159 | 160 | #[test] 161 | fn equal_rd_test() { 162 | let mut rng = rand::thread_rng(); 163 | let mut object_1 = osmos_sim::object::Object::new(&mut rng, 1); 164 | object_1.cell.position.x = 0.0; 165 | object_1.cell.position.y = 0.0; 166 | object_1.cell.energy = 2; 167 | let mut object_2 = osmos_sim::object::Object::new(&mut rng, 2); 168 | object_2.cell.position.x = -0.1; 169 | object_2.cell.position.y = 0.1; 170 | object_2.cell.energy = 2; 171 | let mut object_3 = osmos_sim::object::Object::new(&mut rng, 3); 172 | object_3.cell.position.x = -0.01; 173 | object_3.cell.position.y = 0.01; 174 | object_3.cell.energy = 2; 175 | let mut object_list = [object_1, object_2, object_3]; 176 | osmos_sim::system::sensor::process(&mut object_list); 177 | assert_eq!(object_list[0].cell.sensor.data_list, [0.0, 0.0, 0.0, 0.0]); 178 | assert_eq!(object_list[1].cell.sensor.data_list, [0.0, 0.0, 0.0, 0.0]); 179 | assert_eq!(object_list[2].cell.sensor.data_list, [0.0, 0.0, 0.0, 0.0]); 180 | } 181 | -------------------------------------------------------------------------------- /osmos-sim/tests/simulator_test.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn test() { 3 | let mut sim = osmos_sim::simulator::Simulator::default(); 4 | for _ in 0..5 { 5 | sim.step(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /osmos-wasm/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "osmos-wasm" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib"] 8 | 9 | [dependencies] 10 | wasm-bindgen = "*" 11 | osmos-sim = { path = "../osmos-sim" } 12 | getrandom = { version = "*", features = ["js"] } 13 | serde = { version = "*", features = ["derive"] } 14 | serde-wasm-bindgen = "*" 15 | -------------------------------------------------------------------------------- /osmos-wasm/cargo_watch.bat: -------------------------------------------------------------------------------- 1 | cargo watch -s wasm_pack_build.bat -------------------------------------------------------------------------------- /osmos-wasm/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[wasm_bindgen::prelude::wasm_bindgen] 2 | #[derive(Default)] 3 | pub struct Simulator { 4 | simulator: osmos_sim::simulator::Simulator, 5 | } 6 | 7 | #[wasm_bindgen::prelude::wasm_bindgen] 8 | impl Simulator { 9 | #[wasm_bindgen::prelude::wasm_bindgen(constructor)] 10 | pub fn new() -> Self { 11 | Self::default() 12 | } 13 | 14 | #[wasm_bindgen::prelude::wasm_bindgen(js_name = getObjectList)] 15 | pub fn get_object_list(&self) -> wasm_bindgen::JsValue { 16 | let object_list = self 17 | .simulator 18 | .object_list 19 | .iter() 20 | .map(Object::from) 21 | .collect::>(); 22 | serde_wasm_bindgen::to_value(&object_list).unwrap() 23 | } 24 | 25 | #[wasm_bindgen::prelude::wasm_bindgen(js_name = getStepCount)] 26 | pub fn get_step_count(&self) -> usize { 27 | self.simulator.step_count 28 | } 29 | 30 | #[wasm_bindgen::prelude::wasm_bindgen(js_name = getEpochCount)] 31 | pub fn get_epoch_count(&self) -> usize { 32 | self.simulator.epoch_count 33 | } 34 | 35 | pub fn step(&mut self) { 36 | self.simulator.step() 37 | } 38 | } 39 | 40 | #[derive(serde::Deserialize, serde::Serialize)] 41 | pub struct Object { 42 | pub id: usize, 43 | pub x: f32, 44 | pub y: f32, 45 | pub energy: usize, 46 | } 47 | 48 | impl From<&osmos_sim::object::Object> for Object { 49 | fn from(sim_object: &osmos_sim::object::Object) -> Self { 50 | Self { 51 | id: sim_object.id, 52 | x: sim_object.cell.position.x, 53 | y: sim_object.cell.position.y, 54 | energy: sim_object.cell.energy, 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /osmos-wasm/wasm_pack_build.bat: -------------------------------------------------------------------------------- 1 | wasm-pack build --release --out-dir ../osmos-web/osmos-wasm 2 | -------------------------------------------------------------------------------- /osmos-wasm/wasm_pack_build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | wasm-pack build --release --out-dir ../osmos-web/osmos-wasm 3 | -------------------------------------------------------------------------------- /osmos-web/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist -------------------------------------------------------------------------------- /osmos-web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Osmos: 🦀️ WASM NN GA 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /osmos-web/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "osmos-web", 3 | "version": "0.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "osmos-web", 9 | "version": "0.0.0", 10 | "dependencies": { 11 | "solid-js": "^1.9.5" 12 | }, 13 | "devDependencies": { 14 | "typescript": "^5.7.2", 15 | "vite": "^5.4.14", 16 | "vite-plugin-solid": "^2.11.0", 17 | "vite-plugin-top-level-await": "^1.4.4", 18 | "vite-plugin-wasm": "^3.3.0" 19 | } 20 | }, 21 | "node_modules/@ampproject/remapping": { 22 | "version": "2.3.0", 23 | "resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.3.0.tgz", 24 | "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", 25 | "dev": true, 26 | "license": "Apache-2.0", 27 | "dependencies": { 28 | "@jridgewell/gen-mapping": "^0.3.5", 29 | "@jridgewell/trace-mapping": "^0.3.24" 30 | }, 31 | "engines": { 32 | "node": ">=6.0.0" 33 | } 34 | }, 35 | "node_modules/@babel/code-frame": { 36 | "version": "7.26.2", 37 | "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.26.2.tgz", 38 | "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", 39 | "dev": true, 40 | "license": "MIT", 41 | "dependencies": { 42 | "@babel/helper-validator-identifier": "^7.25.9", 43 | "js-tokens": "^4.0.0", 44 | "picocolors": "^1.0.0" 45 | }, 46 | "engines": { 47 | "node": ">=6.9.0" 48 | } 49 | }, 50 | "node_modules/@babel/compat-data": { 51 | "version": "7.26.3", 52 | "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.26.3.tgz", 53 | "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==", 54 | "dev": true, 55 | "license": "MIT", 56 | "engines": { 57 | "node": ">=6.9.0" 58 | } 59 | }, 60 | "node_modules/@babel/core": { 61 | "version": "7.26.0", 62 | "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.26.0.tgz", 63 | "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", 64 | "dev": true, 65 | "license": "MIT", 66 | "dependencies": { 67 | "@ampproject/remapping": "^2.2.0", 68 | "@babel/code-frame": "^7.26.0", 69 | "@babel/generator": "^7.26.0", 70 | "@babel/helper-compilation-targets": "^7.25.9", 71 | "@babel/helper-module-transforms": "^7.26.0", 72 | "@babel/helpers": "^7.26.0", 73 | "@babel/parser": "^7.26.0", 74 | "@babel/template": "^7.25.9", 75 | "@babel/traverse": "^7.25.9", 76 | "@babel/types": "^7.26.0", 77 | "convert-source-map": "^2.0.0", 78 | "debug": "^4.1.0", 79 | "gensync": "^1.0.0-beta.2", 80 | "json5": "^2.2.3", 81 | "semver": "^6.3.1" 82 | }, 83 | "engines": { 84 | "node": ">=6.9.0" 85 | }, 86 | "funding": { 87 | "type": "opencollective", 88 | "url": "https://opencollective.com/babel" 89 | } 90 | }, 91 | "node_modules/@babel/generator": { 92 | "version": "7.26.3", 93 | "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.26.3.tgz", 94 | "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", 95 | "dev": true, 96 | "license": "MIT", 97 | "dependencies": { 98 | "@babel/parser": "^7.26.3", 99 | "@babel/types": "^7.26.3", 100 | "@jridgewell/gen-mapping": "^0.3.5", 101 | "@jridgewell/trace-mapping": "^0.3.25", 102 | "jsesc": "^3.0.2" 103 | }, 104 | "engines": { 105 | "node": ">=6.9.0" 106 | } 107 | }, 108 | "node_modules/@babel/helper-compilation-targets": { 109 | "version": "7.25.9", 110 | "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", 111 | "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", 112 | "dev": true, 113 | "license": "MIT", 114 | "dependencies": { 115 | "@babel/compat-data": "^7.25.9", 116 | "@babel/helper-validator-option": "^7.25.9", 117 | "browserslist": "^4.24.0", 118 | "lru-cache": "^5.1.1", 119 | "semver": "^6.3.1" 120 | }, 121 | "engines": { 122 | "node": ">=6.9.0" 123 | } 124 | }, 125 | "node_modules/@babel/helper-module-imports": { 126 | "version": "7.25.9", 127 | "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", 128 | "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", 129 | "dev": true, 130 | "license": "MIT", 131 | "dependencies": { 132 | "@babel/traverse": "^7.25.9", 133 | "@babel/types": "^7.25.9" 134 | }, 135 | "engines": { 136 | "node": ">=6.9.0" 137 | } 138 | }, 139 | "node_modules/@babel/helper-module-transforms": { 140 | "version": "7.26.0", 141 | "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", 142 | "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", 143 | "dev": true, 144 | "license": "MIT", 145 | "dependencies": { 146 | "@babel/helper-module-imports": "^7.25.9", 147 | "@babel/helper-validator-identifier": "^7.25.9", 148 | "@babel/traverse": "^7.25.9" 149 | }, 150 | "engines": { 151 | "node": ">=6.9.0" 152 | }, 153 | "peerDependencies": { 154 | "@babel/core": "^7.0.0" 155 | } 156 | }, 157 | "node_modules/@babel/helper-plugin-utils": { 158 | "version": "7.25.9", 159 | "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", 160 | "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", 161 | "dev": true, 162 | "license": "MIT", 163 | "engines": { 164 | "node": ">=6.9.0" 165 | } 166 | }, 167 | "node_modules/@babel/helper-string-parser": { 168 | "version": "7.25.9", 169 | "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", 170 | "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", 171 | "dev": true, 172 | "license": "MIT", 173 | "engines": { 174 | "node": ">=6.9.0" 175 | } 176 | }, 177 | "node_modules/@babel/helper-validator-identifier": { 178 | "version": "7.25.9", 179 | "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", 180 | "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", 181 | "dev": true, 182 | "license": "MIT", 183 | "engines": { 184 | "node": ">=6.9.0" 185 | } 186 | }, 187 | "node_modules/@babel/helper-validator-option": { 188 | "version": "7.25.9", 189 | "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", 190 | "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", 191 | "dev": true, 192 | "license": "MIT", 193 | "engines": { 194 | "node": ">=6.9.0" 195 | } 196 | }, 197 | "node_modules/@babel/helpers": { 198 | "version": "7.26.0", 199 | "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.26.0.tgz", 200 | "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", 201 | "dev": true, 202 | "license": "MIT", 203 | "dependencies": { 204 | "@babel/template": "^7.25.9", 205 | "@babel/types": "^7.26.0" 206 | }, 207 | "engines": { 208 | "node": ">=6.9.0" 209 | } 210 | }, 211 | "node_modules/@babel/parser": { 212 | "version": "7.26.3", 213 | "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.26.3.tgz", 214 | "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", 215 | "dev": true, 216 | "license": "MIT", 217 | "dependencies": { 218 | "@babel/types": "^7.26.3" 219 | }, 220 | "bin": { 221 | "parser": "bin/babel-parser.js" 222 | }, 223 | "engines": { 224 | "node": ">=6.0.0" 225 | } 226 | }, 227 | "node_modules/@babel/plugin-syntax-jsx": { 228 | "version": "7.25.9", 229 | "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", 230 | "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", 231 | "dev": true, 232 | "license": "MIT", 233 | "dependencies": { 234 | "@babel/helper-plugin-utils": "^7.25.9" 235 | }, 236 | "engines": { 237 | "node": ">=6.9.0" 238 | }, 239 | "peerDependencies": { 240 | "@babel/core": "^7.0.0-0" 241 | } 242 | }, 243 | "node_modules/@babel/template": { 244 | "version": "7.25.9", 245 | "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.25.9.tgz", 246 | "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", 247 | "dev": true, 248 | "license": "MIT", 249 | "dependencies": { 250 | "@babel/code-frame": "^7.25.9", 251 | "@babel/parser": "^7.25.9", 252 | "@babel/types": "^7.25.9" 253 | }, 254 | "engines": { 255 | "node": ">=6.9.0" 256 | } 257 | }, 258 | "node_modules/@babel/traverse": { 259 | "version": "7.26.4", 260 | "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.26.4.tgz", 261 | "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", 262 | "dev": true, 263 | "license": "MIT", 264 | "dependencies": { 265 | "@babel/code-frame": "^7.26.2", 266 | "@babel/generator": "^7.26.3", 267 | "@babel/parser": "^7.26.3", 268 | "@babel/template": "^7.25.9", 269 | "@babel/types": "^7.26.3", 270 | "debug": "^4.3.1", 271 | "globals": "^11.1.0" 272 | }, 273 | "engines": { 274 | "node": ">=6.9.0" 275 | } 276 | }, 277 | "node_modules/@babel/types": { 278 | "version": "7.26.3", 279 | "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.3.tgz", 280 | "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", 281 | "dev": true, 282 | "license": "MIT", 283 | "dependencies": { 284 | "@babel/helper-string-parser": "^7.25.9", 285 | "@babel/helper-validator-identifier": "^7.25.9" 286 | }, 287 | "engines": { 288 | "node": ">=6.9.0" 289 | } 290 | }, 291 | "node_modules/@esbuild/aix-ppc64": { 292 | "version": "0.21.5", 293 | "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", 294 | "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", 295 | "cpu": [ 296 | "ppc64" 297 | ], 298 | "dev": true, 299 | "license": "MIT", 300 | "optional": true, 301 | "os": [ 302 | "aix" 303 | ], 304 | "engines": { 305 | "node": ">=12" 306 | } 307 | }, 308 | "node_modules/@esbuild/android-arm": { 309 | "version": "0.21.5", 310 | "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz", 311 | "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", 312 | "cpu": [ 313 | "arm" 314 | ], 315 | "dev": true, 316 | "license": "MIT", 317 | "optional": true, 318 | "os": [ 319 | "android" 320 | ], 321 | "engines": { 322 | "node": ">=12" 323 | } 324 | }, 325 | "node_modules/@esbuild/android-arm64": { 326 | "version": "0.21.5", 327 | "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", 328 | "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", 329 | "cpu": [ 330 | "arm64" 331 | ], 332 | "dev": true, 333 | "license": "MIT", 334 | "optional": true, 335 | "os": [ 336 | "android" 337 | ], 338 | "engines": { 339 | "node": ">=12" 340 | } 341 | }, 342 | "node_modules/@esbuild/android-x64": { 343 | "version": "0.21.5", 344 | "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz", 345 | "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", 346 | "cpu": [ 347 | "x64" 348 | ], 349 | "dev": true, 350 | "license": "MIT", 351 | "optional": true, 352 | "os": [ 353 | "android" 354 | ], 355 | "engines": { 356 | "node": ">=12" 357 | } 358 | }, 359 | "node_modules/@esbuild/darwin-arm64": { 360 | "version": "0.21.5", 361 | "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", 362 | "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", 363 | "cpu": [ 364 | "arm64" 365 | ], 366 | "dev": true, 367 | "license": "MIT", 368 | "optional": true, 369 | "os": [ 370 | "darwin" 371 | ], 372 | "engines": { 373 | "node": ">=12" 374 | } 375 | }, 376 | "node_modules/@esbuild/darwin-x64": { 377 | "version": "0.21.5", 378 | "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", 379 | "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", 380 | "cpu": [ 381 | "x64" 382 | ], 383 | "dev": true, 384 | "license": "MIT", 385 | "optional": true, 386 | "os": [ 387 | "darwin" 388 | ], 389 | "engines": { 390 | "node": ">=12" 391 | } 392 | }, 393 | "node_modules/@esbuild/freebsd-arm64": { 394 | "version": "0.21.5", 395 | "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", 396 | "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", 397 | "cpu": [ 398 | "arm64" 399 | ], 400 | "dev": true, 401 | "license": "MIT", 402 | "optional": true, 403 | "os": [ 404 | "freebsd" 405 | ], 406 | "engines": { 407 | "node": ">=12" 408 | } 409 | }, 410 | "node_modules/@esbuild/freebsd-x64": { 411 | "version": "0.21.5", 412 | "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", 413 | "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", 414 | "cpu": [ 415 | "x64" 416 | ], 417 | "dev": true, 418 | "license": "MIT", 419 | "optional": true, 420 | "os": [ 421 | "freebsd" 422 | ], 423 | "engines": { 424 | "node": ">=12" 425 | } 426 | }, 427 | "node_modules/@esbuild/linux-arm": { 428 | "version": "0.21.5", 429 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", 430 | "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", 431 | "cpu": [ 432 | "arm" 433 | ], 434 | "dev": true, 435 | "license": "MIT", 436 | "optional": true, 437 | "os": [ 438 | "linux" 439 | ], 440 | "engines": { 441 | "node": ">=12" 442 | } 443 | }, 444 | "node_modules/@esbuild/linux-arm64": { 445 | "version": "0.21.5", 446 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", 447 | "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", 448 | "cpu": [ 449 | "arm64" 450 | ], 451 | "dev": true, 452 | "license": "MIT", 453 | "optional": true, 454 | "os": [ 455 | "linux" 456 | ], 457 | "engines": { 458 | "node": ">=12" 459 | } 460 | }, 461 | "node_modules/@esbuild/linux-ia32": { 462 | "version": "0.21.5", 463 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", 464 | "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", 465 | "cpu": [ 466 | "ia32" 467 | ], 468 | "dev": true, 469 | "license": "MIT", 470 | "optional": true, 471 | "os": [ 472 | "linux" 473 | ], 474 | "engines": { 475 | "node": ">=12" 476 | } 477 | }, 478 | "node_modules/@esbuild/linux-loong64": { 479 | "version": "0.21.5", 480 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", 481 | "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", 482 | "cpu": [ 483 | "loong64" 484 | ], 485 | "dev": true, 486 | "license": "MIT", 487 | "optional": true, 488 | "os": [ 489 | "linux" 490 | ], 491 | "engines": { 492 | "node": ">=12" 493 | } 494 | }, 495 | "node_modules/@esbuild/linux-mips64el": { 496 | "version": "0.21.5", 497 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", 498 | "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", 499 | "cpu": [ 500 | "mips64el" 501 | ], 502 | "dev": true, 503 | "license": "MIT", 504 | "optional": true, 505 | "os": [ 506 | "linux" 507 | ], 508 | "engines": { 509 | "node": ">=12" 510 | } 511 | }, 512 | "node_modules/@esbuild/linux-ppc64": { 513 | "version": "0.21.5", 514 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", 515 | "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", 516 | "cpu": [ 517 | "ppc64" 518 | ], 519 | "dev": true, 520 | "license": "MIT", 521 | "optional": true, 522 | "os": [ 523 | "linux" 524 | ], 525 | "engines": { 526 | "node": ">=12" 527 | } 528 | }, 529 | "node_modules/@esbuild/linux-riscv64": { 530 | "version": "0.21.5", 531 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", 532 | "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", 533 | "cpu": [ 534 | "riscv64" 535 | ], 536 | "dev": true, 537 | "license": "MIT", 538 | "optional": true, 539 | "os": [ 540 | "linux" 541 | ], 542 | "engines": { 543 | "node": ">=12" 544 | } 545 | }, 546 | "node_modules/@esbuild/linux-s390x": { 547 | "version": "0.21.5", 548 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", 549 | "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", 550 | "cpu": [ 551 | "s390x" 552 | ], 553 | "dev": true, 554 | "license": "MIT", 555 | "optional": true, 556 | "os": [ 557 | "linux" 558 | ], 559 | "engines": { 560 | "node": ">=12" 561 | } 562 | }, 563 | "node_modules/@esbuild/linux-x64": { 564 | "version": "0.21.5", 565 | "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", 566 | "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", 567 | "cpu": [ 568 | "x64" 569 | ], 570 | "dev": true, 571 | "license": "MIT", 572 | "optional": true, 573 | "os": [ 574 | "linux" 575 | ], 576 | "engines": { 577 | "node": ">=12" 578 | } 579 | }, 580 | "node_modules/@esbuild/netbsd-x64": { 581 | "version": "0.21.5", 582 | "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", 583 | "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", 584 | "cpu": [ 585 | "x64" 586 | ], 587 | "dev": true, 588 | "license": "MIT", 589 | "optional": true, 590 | "os": [ 591 | "netbsd" 592 | ], 593 | "engines": { 594 | "node": ">=12" 595 | } 596 | }, 597 | "node_modules/@esbuild/openbsd-x64": { 598 | "version": "0.21.5", 599 | "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", 600 | "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", 601 | "cpu": [ 602 | "x64" 603 | ], 604 | "dev": true, 605 | "license": "MIT", 606 | "optional": true, 607 | "os": [ 608 | "openbsd" 609 | ], 610 | "engines": { 611 | "node": ">=12" 612 | } 613 | }, 614 | "node_modules/@esbuild/sunos-x64": { 615 | "version": "0.21.5", 616 | "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", 617 | "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", 618 | "cpu": [ 619 | "x64" 620 | ], 621 | "dev": true, 622 | "license": "MIT", 623 | "optional": true, 624 | "os": [ 625 | "sunos" 626 | ], 627 | "engines": { 628 | "node": ">=12" 629 | } 630 | }, 631 | "node_modules/@esbuild/win32-arm64": { 632 | "version": "0.21.5", 633 | "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", 634 | "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", 635 | "cpu": [ 636 | "arm64" 637 | ], 638 | "dev": true, 639 | "license": "MIT", 640 | "optional": true, 641 | "os": [ 642 | "win32" 643 | ], 644 | "engines": { 645 | "node": ">=12" 646 | } 647 | }, 648 | "node_modules/@esbuild/win32-ia32": { 649 | "version": "0.21.5", 650 | "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", 651 | "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", 652 | "cpu": [ 653 | "ia32" 654 | ], 655 | "dev": true, 656 | "license": "MIT", 657 | "optional": true, 658 | "os": [ 659 | "win32" 660 | ], 661 | "engines": { 662 | "node": ">=12" 663 | } 664 | }, 665 | "node_modules/@esbuild/win32-x64": { 666 | "version": "0.21.5", 667 | "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", 668 | "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", 669 | "cpu": [ 670 | "x64" 671 | ], 672 | "dev": true, 673 | "license": "MIT", 674 | "optional": true, 675 | "os": [ 676 | "win32" 677 | ], 678 | "engines": { 679 | "node": ">=12" 680 | } 681 | }, 682 | "node_modules/@jridgewell/gen-mapping": { 683 | "version": "0.3.8", 684 | "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", 685 | "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", 686 | "dev": true, 687 | "license": "MIT", 688 | "dependencies": { 689 | "@jridgewell/set-array": "^1.2.1", 690 | "@jridgewell/sourcemap-codec": "^1.4.10", 691 | "@jridgewell/trace-mapping": "^0.3.24" 692 | }, 693 | "engines": { 694 | "node": ">=6.0.0" 695 | } 696 | }, 697 | "node_modules/@jridgewell/resolve-uri": { 698 | "version": "3.1.2", 699 | "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 700 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 701 | "dev": true, 702 | "license": "MIT", 703 | "engines": { 704 | "node": ">=6.0.0" 705 | } 706 | }, 707 | "node_modules/@jridgewell/set-array": { 708 | "version": "1.2.1", 709 | "resolved": "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.2.1.tgz", 710 | "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", 711 | "dev": true, 712 | "license": "MIT", 713 | "engines": { 714 | "node": ">=6.0.0" 715 | } 716 | }, 717 | "node_modules/@jridgewell/sourcemap-codec": { 718 | "version": "1.5.0", 719 | "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", 720 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", 721 | "dev": true, 722 | "license": "MIT" 723 | }, 724 | "node_modules/@jridgewell/trace-mapping": { 725 | "version": "0.3.25", 726 | "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", 727 | "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", 728 | "dev": true, 729 | "license": "MIT", 730 | "dependencies": { 731 | "@jridgewell/resolve-uri": "^3.1.0", 732 | "@jridgewell/sourcemap-codec": "^1.4.14" 733 | } 734 | }, 735 | "node_modules/@rollup/plugin-virtual": { 736 | "version": "3.0.2", 737 | "resolved": "https://registry.npmmirror.com/@rollup/plugin-virtual/-/plugin-virtual-3.0.2.tgz", 738 | "integrity": "sha512-10monEYsBp3scM4/ND4LNH5Rxvh3e/cVeL3jWTgZ2SrQ+BmUoQcopVQvnaMcOnykb1VkxUFuDAN+0FnpTFRy2A==", 739 | "dev": true, 740 | "license": "MIT", 741 | "engines": { 742 | "node": ">=14.0.0" 743 | }, 744 | "peerDependencies": { 745 | "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" 746 | }, 747 | "peerDependenciesMeta": { 748 | "rollup": { 749 | "optional": true 750 | } 751 | } 752 | }, 753 | "node_modules/@rollup/rollup-android-arm-eabi": { 754 | "version": "4.28.1", 755 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.1.tgz", 756 | "integrity": "sha512-2aZp8AES04KI2dy3Ss6/MDjXbwBzj+i0GqKtWXgw2/Ma6E4jJvujryO6gJAghIRVz7Vwr9Gtl/8na3nDUKpraQ==", 757 | "cpu": [ 758 | "arm" 759 | ], 760 | "dev": true, 761 | "license": "MIT", 762 | "optional": true, 763 | "os": [ 764 | "android" 765 | ] 766 | }, 767 | "node_modules/@rollup/rollup-android-arm64": { 768 | "version": "4.28.1", 769 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.28.1.tgz", 770 | "integrity": "sha512-EbkK285O+1YMrg57xVA+Dp0tDBRB93/BZKph9XhMjezf6F4TpYjaUSuPt5J0fZXlSag0LmZAsTmdGGqPp4pQFA==", 771 | "cpu": [ 772 | "arm64" 773 | ], 774 | "dev": true, 775 | "license": "MIT", 776 | "optional": true, 777 | "os": [ 778 | "android" 779 | ] 780 | }, 781 | "node_modules/@rollup/rollup-darwin-arm64": { 782 | "version": "4.28.1", 783 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.28.1.tgz", 784 | "integrity": "sha512-prduvrMKU6NzMq6nxzQw445zXgaDBbMQvmKSJaxpaZ5R1QDM8w+eGxo6Y/jhT/cLoCvnZI42oEqf9KQNYz1fqQ==", 785 | "cpu": [ 786 | "arm64" 787 | ], 788 | "dev": true, 789 | "license": "MIT", 790 | "optional": true, 791 | "os": [ 792 | "darwin" 793 | ] 794 | }, 795 | "node_modules/@rollup/rollup-darwin-x64": { 796 | "version": "4.28.1", 797 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.28.1.tgz", 798 | "integrity": "sha512-WsvbOunsUk0wccO/TV4o7IKgloJ942hVFK1CLatwv6TJspcCZb9umQkPdvB7FihmdxgaKR5JyxDjWpCOp4uZlQ==", 799 | "cpu": [ 800 | "x64" 801 | ], 802 | "dev": true, 803 | "license": "MIT", 804 | "optional": true, 805 | "os": [ 806 | "darwin" 807 | ] 808 | }, 809 | "node_modules/@rollup/rollup-freebsd-arm64": { 810 | "version": "4.28.1", 811 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.28.1.tgz", 812 | "integrity": "sha512-HTDPdY1caUcU4qK23FeeGxCdJF64cKkqajU0iBnTVxS8F7H/7BewvYoG+va1KPSL63kQ1PGNyiwKOfReavzvNA==", 813 | "cpu": [ 814 | "arm64" 815 | ], 816 | "dev": true, 817 | "license": "MIT", 818 | "optional": true, 819 | "os": [ 820 | "freebsd" 821 | ] 822 | }, 823 | "node_modules/@rollup/rollup-freebsd-x64": { 824 | "version": "4.28.1", 825 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.28.1.tgz", 826 | "integrity": "sha512-m/uYasxkUevcFTeRSM9TeLyPe2QDuqtjkeoTpP9SW0XxUWfcYrGDMkO/m2tTw+4NMAF9P2fU3Mw4ahNvo7QmsQ==", 827 | "cpu": [ 828 | "x64" 829 | ], 830 | "dev": true, 831 | "license": "MIT", 832 | "optional": true, 833 | "os": [ 834 | "freebsd" 835 | ] 836 | }, 837 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 838 | "version": "4.28.1", 839 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.28.1.tgz", 840 | "integrity": "sha512-QAg11ZIt6mcmzpNE6JZBpKfJaKkqTm1A9+y9O+frdZJEuhQxiugM05gnCWiANHj4RmbgeVJpTdmKRmH/a+0QbA==", 841 | "cpu": [ 842 | "arm" 843 | ], 844 | "dev": true, 845 | "license": "MIT", 846 | "optional": true, 847 | "os": [ 848 | "linux" 849 | ] 850 | }, 851 | "node_modules/@rollup/rollup-linux-arm-musleabihf": { 852 | "version": "4.28.1", 853 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.28.1.tgz", 854 | "integrity": "sha512-dRP9PEBfolq1dmMcFqbEPSd9VlRuVWEGSmbxVEfiq2cs2jlZAl0YNxFzAQS2OrQmsLBLAATDMb3Z6MFv5vOcXg==", 855 | "cpu": [ 856 | "arm" 857 | ], 858 | "dev": true, 859 | "license": "MIT", 860 | "optional": true, 861 | "os": [ 862 | "linux" 863 | ] 864 | }, 865 | "node_modules/@rollup/rollup-linux-arm64-gnu": { 866 | "version": "4.28.1", 867 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.28.1.tgz", 868 | "integrity": "sha512-uGr8khxO+CKT4XU8ZUH1TTEUtlktK6Kgtv0+6bIFSeiSlnGJHG1tSFSjm41uQ9sAO/5ULx9mWOz70jYLyv1QkA==", 869 | "cpu": [ 870 | "arm64" 871 | ], 872 | "dev": true, 873 | "license": "MIT", 874 | "optional": true, 875 | "os": [ 876 | "linux" 877 | ] 878 | }, 879 | "node_modules/@rollup/rollup-linux-arm64-musl": { 880 | "version": "4.28.1", 881 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.28.1.tgz", 882 | "integrity": "sha512-QF54q8MYGAqMLrX2t7tNpi01nvq5RI59UBNx+3+37zoKX5KViPo/gk2QLhsuqok05sSCRluj0D00LzCwBikb0A==", 883 | "cpu": [ 884 | "arm64" 885 | ], 886 | "dev": true, 887 | "license": "MIT", 888 | "optional": true, 889 | "os": [ 890 | "linux" 891 | ] 892 | }, 893 | "node_modules/@rollup/rollup-linux-loongarch64-gnu": { 894 | "version": "4.28.1", 895 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.28.1.tgz", 896 | "integrity": "sha512-vPul4uodvWvLhRco2w0GcyZcdyBfpfDRgNKU+p35AWEbJ/HPs1tOUrkSueVbBS0RQHAf/A+nNtDpvw95PeVKOA==", 897 | "cpu": [ 898 | "loong64" 899 | ], 900 | "dev": true, 901 | "license": "MIT", 902 | "optional": true, 903 | "os": [ 904 | "linux" 905 | ] 906 | }, 907 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { 908 | "version": "4.28.1", 909 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.28.1.tgz", 910 | "integrity": "sha512-pTnTdBuC2+pt1Rmm2SV7JWRqzhYpEILML4PKODqLz+C7Ou2apEV52h19CR7es+u04KlqplggmN9sqZlekg3R1A==", 911 | "cpu": [ 912 | "ppc64" 913 | ], 914 | "dev": true, 915 | "license": "MIT", 916 | "optional": true, 917 | "os": [ 918 | "linux" 919 | ] 920 | }, 921 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { 922 | "version": "4.28.1", 923 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.28.1.tgz", 924 | "integrity": "sha512-vWXy1Nfg7TPBSuAncfInmAI/WZDd5vOklyLJDdIRKABcZWojNDY0NJwruY2AcnCLnRJKSaBgf/GiJfauu8cQZA==", 925 | "cpu": [ 926 | "riscv64" 927 | ], 928 | "dev": true, 929 | "license": "MIT", 930 | "optional": true, 931 | "os": [ 932 | "linux" 933 | ] 934 | }, 935 | "node_modules/@rollup/rollup-linux-s390x-gnu": { 936 | "version": "4.28.1", 937 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.28.1.tgz", 938 | "integrity": "sha512-/yqC2Y53oZjb0yz8PVuGOQQNOTwxcizudunl/tFs1aLvObTclTwZ0JhXF2XcPT/zuaymemCDSuuUPXJJyqeDOg==", 939 | "cpu": [ 940 | "s390x" 941 | ], 942 | "dev": true, 943 | "license": "MIT", 944 | "optional": true, 945 | "os": [ 946 | "linux" 947 | ] 948 | }, 949 | "node_modules/@rollup/rollup-linux-x64-gnu": { 950 | "version": "4.28.1", 951 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.28.1.tgz", 952 | "integrity": "sha512-fzgeABz7rrAlKYB0y2kSEiURrI0691CSL0+KXwKwhxvj92VULEDQLpBYLHpF49MSiPG4sq5CK3qHMnb9tlCjBw==", 953 | "cpu": [ 954 | "x64" 955 | ], 956 | "dev": true, 957 | "license": "MIT", 958 | "optional": true, 959 | "os": [ 960 | "linux" 961 | ] 962 | }, 963 | "node_modules/@rollup/rollup-linux-x64-musl": { 964 | "version": "4.28.1", 965 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.28.1.tgz", 966 | "integrity": "sha512-xQTDVzSGiMlSshpJCtudbWyRfLaNiVPXt1WgdWTwWz9n0U12cI2ZVtWe/Jgwyv/6wjL7b66uu61Vg0POWVfz4g==", 967 | "cpu": [ 968 | "x64" 969 | ], 970 | "dev": true, 971 | "license": "MIT", 972 | "optional": true, 973 | "os": [ 974 | "linux" 975 | ] 976 | }, 977 | "node_modules/@rollup/rollup-win32-arm64-msvc": { 978 | "version": "4.28.1", 979 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.28.1.tgz", 980 | "integrity": "sha512-wSXmDRVupJstFP7elGMgv+2HqXelQhuNf+IS4V+nUpNVi/GUiBgDmfwD0UGN3pcAnWsgKG3I52wMOBnk1VHr/A==", 981 | "cpu": [ 982 | "arm64" 983 | ], 984 | "dev": true, 985 | "license": "MIT", 986 | "optional": true, 987 | "os": [ 988 | "win32" 989 | ] 990 | }, 991 | "node_modules/@rollup/rollup-win32-ia32-msvc": { 992 | "version": "4.28.1", 993 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.28.1.tgz", 994 | "integrity": "sha512-ZkyTJ/9vkgrE/Rk9vhMXhf8l9D+eAhbAVbsGsXKy2ohmJaWg0LPQLnIxRdRp/bKyr8tXuPlXhIoGlEB5XpJnGA==", 995 | "cpu": [ 996 | "ia32" 997 | ], 998 | "dev": true, 999 | "license": "MIT", 1000 | "optional": true, 1001 | "os": [ 1002 | "win32" 1003 | ] 1004 | }, 1005 | "node_modules/@rollup/rollup-win32-x64-msvc": { 1006 | "version": "4.28.1", 1007 | "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.28.1.tgz", 1008 | "integrity": "sha512-ZvK2jBafvttJjoIdKm/Q/Bh7IJ1Ose9IBOwpOXcOvW3ikGTQGmKDgxTC6oCAzW6PynbkKP8+um1du81XJHZ0JA==", 1009 | "cpu": [ 1010 | "x64" 1011 | ], 1012 | "dev": true, 1013 | "license": "MIT", 1014 | "optional": true, 1015 | "os": [ 1016 | "win32" 1017 | ] 1018 | }, 1019 | "node_modules/@swc/core": { 1020 | "version": "1.10.1", 1021 | "resolved": "https://registry.npmmirror.com/@swc/core/-/core-1.10.1.tgz", 1022 | "integrity": "sha512-rQ4dS6GAdmtzKiCRt3LFVxl37FaY1cgL9kSUTnhQ2xc3fmHOd7jdJK/V4pSZMG1ruGTd0bsi34O2R0Olg9Zo/w==", 1023 | "dev": true, 1024 | "hasInstallScript": true, 1025 | "license": "Apache-2.0", 1026 | "dependencies": { 1027 | "@swc/counter": "^0.1.3", 1028 | "@swc/types": "^0.1.17" 1029 | }, 1030 | "engines": { 1031 | "node": ">=10" 1032 | }, 1033 | "funding": { 1034 | "type": "opencollective", 1035 | "url": "https://opencollective.com/swc" 1036 | }, 1037 | "optionalDependencies": { 1038 | "@swc/core-darwin-arm64": "1.10.1", 1039 | "@swc/core-darwin-x64": "1.10.1", 1040 | "@swc/core-linux-arm-gnueabihf": "1.10.1", 1041 | "@swc/core-linux-arm64-gnu": "1.10.1", 1042 | "@swc/core-linux-arm64-musl": "1.10.1", 1043 | "@swc/core-linux-x64-gnu": "1.10.1", 1044 | "@swc/core-linux-x64-musl": "1.10.1", 1045 | "@swc/core-win32-arm64-msvc": "1.10.1", 1046 | "@swc/core-win32-ia32-msvc": "1.10.1", 1047 | "@swc/core-win32-x64-msvc": "1.10.1" 1048 | }, 1049 | "peerDependencies": { 1050 | "@swc/helpers": "*" 1051 | }, 1052 | "peerDependenciesMeta": { 1053 | "@swc/helpers": { 1054 | "optional": true 1055 | } 1056 | } 1057 | }, 1058 | "node_modules/@swc/core-darwin-arm64": { 1059 | "version": "1.10.1", 1060 | "resolved": "https://registry.npmmirror.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.1.tgz", 1061 | "integrity": "sha512-NyELPp8EsVZtxH/mEqvzSyWpfPJ1lugpTQcSlMduZLj1EASLO4sC8wt8hmL1aizRlsbjCX+r0PyL+l0xQ64/6Q==", 1062 | "cpu": [ 1063 | "arm64" 1064 | ], 1065 | "dev": true, 1066 | "license": "Apache-2.0 AND MIT", 1067 | "optional": true, 1068 | "os": [ 1069 | "darwin" 1070 | ], 1071 | "engines": { 1072 | "node": ">=10" 1073 | } 1074 | }, 1075 | "node_modules/@swc/core-darwin-x64": { 1076 | "version": "1.10.1", 1077 | "resolved": "https://registry.npmmirror.com/@swc/core-darwin-x64/-/core-darwin-x64-1.10.1.tgz", 1078 | "integrity": "sha512-L4BNt1fdQ5ZZhAk5qoDfUnXRabDOXKnXBxMDJ+PWLSxOGBbWE6aJTnu4zbGjJvtot0KM46m2LPAPY8ttknqaZA==", 1079 | "cpu": [ 1080 | "x64" 1081 | ], 1082 | "dev": true, 1083 | "license": "Apache-2.0 AND MIT", 1084 | "optional": true, 1085 | "os": [ 1086 | "darwin" 1087 | ], 1088 | "engines": { 1089 | "node": ">=10" 1090 | } 1091 | }, 1092 | "node_modules/@swc/core-linux-arm-gnueabihf": { 1093 | "version": "1.10.1", 1094 | "resolved": "https://registry.npmmirror.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.1.tgz", 1095 | "integrity": "sha512-Y1u9OqCHgvVp2tYQAJ7hcU9qO5brDMIrA5R31rwWQIAKDkJKtv3IlTHF0hrbWk1wPR0ZdngkQSJZple7G+Grvw==", 1096 | "cpu": [ 1097 | "arm" 1098 | ], 1099 | "dev": true, 1100 | "license": "Apache-2.0", 1101 | "optional": true, 1102 | "os": [ 1103 | "linux" 1104 | ], 1105 | "engines": { 1106 | "node": ">=10" 1107 | } 1108 | }, 1109 | "node_modules/@swc/core-linux-arm64-gnu": { 1110 | "version": "1.10.1", 1111 | "resolved": "https://registry.npmmirror.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.1.tgz", 1112 | "integrity": "sha512-tNQHO/UKdtnqjc7o04iRXng1wTUXPgVd8Y6LI4qIbHVoVPwksZydISjMcilKNLKIwOoUQAkxyJ16SlOAeADzhQ==", 1113 | "cpu": [ 1114 | "arm64" 1115 | ], 1116 | "dev": true, 1117 | "license": "Apache-2.0 AND MIT", 1118 | "optional": true, 1119 | "os": [ 1120 | "linux" 1121 | ], 1122 | "engines": { 1123 | "node": ">=10" 1124 | } 1125 | }, 1126 | "node_modules/@swc/core-linux-arm64-musl": { 1127 | "version": "1.10.1", 1128 | "resolved": "https://registry.npmmirror.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.1.tgz", 1129 | "integrity": "sha512-x0L2Pd9weQ6n8dI1z1Isq00VHFvpBClwQJvrt3NHzmR+1wCT/gcYl1tp9P5xHh3ldM8Cn4UjWCw+7PaUgg8FcQ==", 1130 | "cpu": [ 1131 | "arm64" 1132 | ], 1133 | "dev": true, 1134 | "license": "Apache-2.0 AND MIT", 1135 | "optional": true, 1136 | "os": [ 1137 | "linux" 1138 | ], 1139 | "engines": { 1140 | "node": ">=10" 1141 | } 1142 | }, 1143 | "node_modules/@swc/core-linux-x64-gnu": { 1144 | "version": "1.10.1", 1145 | "resolved": "https://registry.npmmirror.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.1.tgz", 1146 | "integrity": "sha512-yyYEwQcObV3AUsC79rSzN9z6kiWxKAVJ6Ntwq2N9YoZqSPYph+4/Am5fM1xEQYf/kb99csj0FgOelomJSobxQA==", 1147 | "cpu": [ 1148 | "x64" 1149 | ], 1150 | "dev": true, 1151 | "license": "Apache-2.0 AND MIT", 1152 | "optional": true, 1153 | "os": [ 1154 | "linux" 1155 | ], 1156 | "engines": { 1157 | "node": ">=10" 1158 | } 1159 | }, 1160 | "node_modules/@swc/core-linux-x64-musl": { 1161 | "version": "1.10.1", 1162 | "resolved": "https://registry.npmmirror.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.1.tgz", 1163 | "integrity": "sha512-tcaS43Ydd7Fk7sW5ROpaf2Kq1zR+sI5K0RM+0qYLYYurvsJruj3GhBCaiN3gkzd8m/8wkqNqtVklWaQYSDsyqA==", 1164 | "cpu": [ 1165 | "x64" 1166 | ], 1167 | "dev": true, 1168 | "license": "Apache-2.0 AND MIT", 1169 | "optional": true, 1170 | "os": [ 1171 | "linux" 1172 | ], 1173 | "engines": { 1174 | "node": ">=10" 1175 | } 1176 | }, 1177 | "node_modules/@swc/core-win32-arm64-msvc": { 1178 | "version": "1.10.1", 1179 | "resolved": "https://registry.npmmirror.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.1.tgz", 1180 | "integrity": "sha512-D3Qo1voA7AkbOzQ2UGuKNHfYGKL6eejN8VWOoQYtGHHQi1p5KK/Q7V1ku55oxXBsj79Ny5FRMqiRJpVGad7bjQ==", 1181 | "cpu": [ 1182 | "arm64" 1183 | ], 1184 | "dev": true, 1185 | "license": "Apache-2.0 AND MIT", 1186 | "optional": true, 1187 | "os": [ 1188 | "win32" 1189 | ], 1190 | "engines": { 1191 | "node": ">=10" 1192 | } 1193 | }, 1194 | "node_modules/@swc/core-win32-ia32-msvc": { 1195 | "version": "1.10.1", 1196 | "resolved": "https://registry.npmmirror.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.1.tgz", 1197 | "integrity": "sha512-WalYdFoU3454Og+sDKHM1MrjvxUGwA2oralknXkXL8S0I/8RkWZOB++p3pLaGbTvOO++T+6znFbQdR8KRaa7DA==", 1198 | "cpu": [ 1199 | "ia32" 1200 | ], 1201 | "dev": true, 1202 | "license": "Apache-2.0 AND MIT", 1203 | "optional": true, 1204 | "os": [ 1205 | "win32" 1206 | ], 1207 | "engines": { 1208 | "node": ">=10" 1209 | } 1210 | }, 1211 | "node_modules/@swc/core-win32-x64-msvc": { 1212 | "version": "1.10.1", 1213 | "resolved": "https://registry.npmmirror.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.1.tgz", 1214 | "integrity": "sha512-JWobfQDbTnoqaIwPKQ3DVSywihVXlQMbDuwik/dDWlj33A8oEHcjPOGs4OqcA3RHv24i+lfCQpM3Mn4FAMfacA==", 1215 | "cpu": [ 1216 | "x64" 1217 | ], 1218 | "dev": true, 1219 | "license": "Apache-2.0 AND MIT", 1220 | "optional": true, 1221 | "os": [ 1222 | "win32" 1223 | ], 1224 | "engines": { 1225 | "node": ">=10" 1226 | } 1227 | }, 1228 | "node_modules/@swc/counter": { 1229 | "version": "0.1.3", 1230 | "resolved": "https://registry.npmmirror.com/@swc/counter/-/counter-0.1.3.tgz", 1231 | "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", 1232 | "dev": true, 1233 | "license": "Apache-2.0" 1234 | }, 1235 | "node_modules/@swc/types": { 1236 | "version": "0.1.17", 1237 | "resolved": "https://registry.npmmirror.com/@swc/types/-/types-0.1.17.tgz", 1238 | "integrity": "sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==", 1239 | "dev": true, 1240 | "license": "Apache-2.0", 1241 | "dependencies": { 1242 | "@swc/counter": "^0.1.3" 1243 | } 1244 | }, 1245 | "node_modules/@types/babel__core": { 1246 | "version": "7.20.5", 1247 | "resolved": "https://registry.npmmirror.com/@types/babel__core/-/babel__core-7.20.5.tgz", 1248 | "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", 1249 | "dev": true, 1250 | "license": "MIT", 1251 | "dependencies": { 1252 | "@babel/parser": "^7.20.7", 1253 | "@babel/types": "^7.20.7", 1254 | "@types/babel__generator": "*", 1255 | "@types/babel__template": "*", 1256 | "@types/babel__traverse": "*" 1257 | } 1258 | }, 1259 | "node_modules/@types/babel__generator": { 1260 | "version": "7.6.8", 1261 | "resolved": "https://registry.npmmirror.com/@types/babel__generator/-/babel__generator-7.6.8.tgz", 1262 | "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", 1263 | "dev": true, 1264 | "license": "MIT", 1265 | "dependencies": { 1266 | "@babel/types": "^7.0.0" 1267 | } 1268 | }, 1269 | "node_modules/@types/babel__template": { 1270 | "version": "7.4.4", 1271 | "resolved": "https://registry.npmmirror.com/@types/babel__template/-/babel__template-7.4.4.tgz", 1272 | "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", 1273 | "dev": true, 1274 | "license": "MIT", 1275 | "dependencies": { 1276 | "@babel/parser": "^7.1.0", 1277 | "@babel/types": "^7.0.0" 1278 | } 1279 | }, 1280 | "node_modules/@types/babel__traverse": { 1281 | "version": "7.20.6", 1282 | "resolved": "https://registry.npmmirror.com/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", 1283 | "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", 1284 | "dev": true, 1285 | "license": "MIT", 1286 | "dependencies": { 1287 | "@babel/types": "^7.20.7" 1288 | } 1289 | }, 1290 | "node_modules/@types/estree": { 1291 | "version": "1.0.6", 1292 | "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.6.tgz", 1293 | "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", 1294 | "dev": true, 1295 | "license": "MIT" 1296 | }, 1297 | "node_modules/babel-plugin-jsx-dom-expressions": { 1298 | "version": "0.39.3", 1299 | "resolved": "https://registry.npmmirror.com/babel-plugin-jsx-dom-expressions/-/babel-plugin-jsx-dom-expressions-0.39.3.tgz", 1300 | "integrity": "sha512-6RzmSu21zYPlV2gNwzjGG9FgODtt9hIWnx7L//OIioIEuRcnpDZoY8Tr+I81Cy1SrH4qoDyKpwHHo6uAMAeyPA==", 1301 | "dev": true, 1302 | "license": "MIT", 1303 | "dependencies": { 1304 | "@babel/helper-module-imports": "7.18.6", 1305 | "@babel/plugin-syntax-jsx": "^7.18.6", 1306 | "@babel/types": "^7.20.7", 1307 | "html-entities": "2.3.3", 1308 | "parse5": "^7.1.2", 1309 | "validate-html-nesting": "^1.2.1" 1310 | }, 1311 | "peerDependencies": { 1312 | "@babel/core": "^7.20.12" 1313 | } 1314 | }, 1315 | "node_modules/babel-plugin-jsx-dom-expressions/node_modules/@babel/helper-module-imports": { 1316 | "version": "7.18.6", 1317 | "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", 1318 | "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", 1319 | "dev": true, 1320 | "license": "MIT", 1321 | "dependencies": { 1322 | "@babel/types": "^7.18.6" 1323 | }, 1324 | "engines": { 1325 | "node": ">=6.9.0" 1326 | } 1327 | }, 1328 | "node_modules/babel-preset-solid": { 1329 | "version": "1.9.3", 1330 | "resolved": "https://registry.npmmirror.com/babel-preset-solid/-/babel-preset-solid-1.9.3.tgz", 1331 | "integrity": "sha512-jvlx5wDp8s+bEF9sGFw/84SInXOA51ttkUEroQziKMbxplXThVKt83qB6bDTa1HuLNatdU9FHpFOiQWs1tLQIg==", 1332 | "dev": true, 1333 | "license": "MIT", 1334 | "dependencies": { 1335 | "babel-plugin-jsx-dom-expressions": "^0.39.3" 1336 | }, 1337 | "peerDependencies": { 1338 | "@babel/core": "^7.0.0" 1339 | } 1340 | }, 1341 | "node_modules/browserslist": { 1342 | "version": "4.24.3", 1343 | "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.24.3.tgz", 1344 | "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==", 1345 | "dev": true, 1346 | "funding": [ 1347 | { 1348 | "type": "opencollective", 1349 | "url": "https://opencollective.com/browserslist" 1350 | }, 1351 | { 1352 | "type": "tidelift", 1353 | "url": "https://tidelift.com/funding/github/npm/browserslist" 1354 | }, 1355 | { 1356 | "type": "github", 1357 | "url": "https://github.com/sponsors/ai" 1358 | } 1359 | ], 1360 | "license": "MIT", 1361 | "dependencies": { 1362 | "caniuse-lite": "^1.0.30001688", 1363 | "electron-to-chromium": "^1.5.73", 1364 | "node-releases": "^2.0.19", 1365 | "update-browserslist-db": "^1.1.1" 1366 | }, 1367 | "bin": { 1368 | "browserslist": "cli.js" 1369 | }, 1370 | "engines": { 1371 | "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" 1372 | } 1373 | }, 1374 | "node_modules/caniuse-lite": { 1375 | "version": "1.0.30001689", 1376 | "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001689.tgz", 1377 | "integrity": "sha512-CmeR2VBycfa+5/jOfnp/NpWPGd06nf1XYiefUvhXFfZE4GkRc9jv+eGPS4nT558WS/8lYCzV8SlANCIPvbWP1g==", 1378 | "dev": true, 1379 | "funding": [ 1380 | { 1381 | "type": "opencollective", 1382 | "url": "https://opencollective.com/browserslist" 1383 | }, 1384 | { 1385 | "type": "tidelift", 1386 | "url": "https://tidelift.com/funding/github/npm/caniuse-lite" 1387 | }, 1388 | { 1389 | "type": "github", 1390 | "url": "https://github.com/sponsors/ai" 1391 | } 1392 | ], 1393 | "license": "CC-BY-4.0" 1394 | }, 1395 | "node_modules/convert-source-map": { 1396 | "version": "2.0.0", 1397 | "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz", 1398 | "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", 1399 | "dev": true, 1400 | "license": "MIT" 1401 | }, 1402 | "node_modules/csstype": { 1403 | "version": "3.1.3", 1404 | "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz", 1405 | "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", 1406 | "license": "MIT" 1407 | }, 1408 | "node_modules/debug": { 1409 | "version": "4.4.0", 1410 | "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.0.tgz", 1411 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 1412 | "dev": true, 1413 | "license": "MIT", 1414 | "dependencies": { 1415 | "ms": "^2.1.3" 1416 | }, 1417 | "engines": { 1418 | "node": ">=6.0" 1419 | }, 1420 | "peerDependenciesMeta": { 1421 | "supports-color": { 1422 | "optional": true 1423 | } 1424 | } 1425 | }, 1426 | "node_modules/electron-to-chromium": { 1427 | "version": "1.5.74", 1428 | "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.74.tgz", 1429 | "integrity": "sha512-ck3//9RC+6oss/1Bh9tiAVFy5vfSKbRHAFh7Z3/eTRkEqJeWgymloShB17Vg3Z4nmDNp35vAd1BZ6CMW4Wt6Iw==", 1430 | "dev": true, 1431 | "license": "ISC" 1432 | }, 1433 | "node_modules/entities": { 1434 | "version": "4.5.0", 1435 | "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", 1436 | "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", 1437 | "dev": true, 1438 | "license": "BSD-2-Clause", 1439 | "engines": { 1440 | "node": ">=0.12" 1441 | }, 1442 | "funding": { 1443 | "url": "https://github.com/fb55/entities?sponsor=1" 1444 | } 1445 | }, 1446 | "node_modules/esbuild": { 1447 | "version": "0.21.5", 1448 | "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz", 1449 | "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", 1450 | "dev": true, 1451 | "hasInstallScript": true, 1452 | "license": "MIT", 1453 | "bin": { 1454 | "esbuild": "bin/esbuild" 1455 | }, 1456 | "engines": { 1457 | "node": ">=12" 1458 | }, 1459 | "optionalDependencies": { 1460 | "@esbuild/aix-ppc64": "0.21.5", 1461 | "@esbuild/android-arm": "0.21.5", 1462 | "@esbuild/android-arm64": "0.21.5", 1463 | "@esbuild/android-x64": "0.21.5", 1464 | "@esbuild/darwin-arm64": "0.21.5", 1465 | "@esbuild/darwin-x64": "0.21.5", 1466 | "@esbuild/freebsd-arm64": "0.21.5", 1467 | "@esbuild/freebsd-x64": "0.21.5", 1468 | "@esbuild/linux-arm": "0.21.5", 1469 | "@esbuild/linux-arm64": "0.21.5", 1470 | "@esbuild/linux-ia32": "0.21.5", 1471 | "@esbuild/linux-loong64": "0.21.5", 1472 | "@esbuild/linux-mips64el": "0.21.5", 1473 | "@esbuild/linux-ppc64": "0.21.5", 1474 | "@esbuild/linux-riscv64": "0.21.5", 1475 | "@esbuild/linux-s390x": "0.21.5", 1476 | "@esbuild/linux-x64": "0.21.5", 1477 | "@esbuild/netbsd-x64": "0.21.5", 1478 | "@esbuild/openbsd-x64": "0.21.5", 1479 | "@esbuild/sunos-x64": "0.21.5", 1480 | "@esbuild/win32-arm64": "0.21.5", 1481 | "@esbuild/win32-ia32": "0.21.5", 1482 | "@esbuild/win32-x64": "0.21.5" 1483 | } 1484 | }, 1485 | "node_modules/escalade": { 1486 | "version": "3.2.0", 1487 | "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz", 1488 | "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", 1489 | "dev": true, 1490 | "license": "MIT", 1491 | "engines": { 1492 | "node": ">=6" 1493 | } 1494 | }, 1495 | "node_modules/fsevents": { 1496 | "version": "2.3.3", 1497 | "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", 1498 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 1499 | "dev": true, 1500 | "hasInstallScript": true, 1501 | "license": "MIT", 1502 | "optional": true, 1503 | "os": [ 1504 | "darwin" 1505 | ], 1506 | "engines": { 1507 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1508 | } 1509 | }, 1510 | "node_modules/gensync": { 1511 | "version": "1.0.0-beta.2", 1512 | "resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz", 1513 | "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", 1514 | "dev": true, 1515 | "license": "MIT", 1516 | "engines": { 1517 | "node": ">=6.9.0" 1518 | } 1519 | }, 1520 | "node_modules/globals": { 1521 | "version": "11.12.0", 1522 | "resolved": "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz", 1523 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", 1524 | "dev": true, 1525 | "license": "MIT", 1526 | "engines": { 1527 | "node": ">=4" 1528 | } 1529 | }, 1530 | "node_modules/html-entities": { 1531 | "version": "2.3.3", 1532 | "resolved": "https://registry.npmmirror.com/html-entities/-/html-entities-2.3.3.tgz", 1533 | "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==", 1534 | "dev": true, 1535 | "license": "MIT" 1536 | }, 1537 | "node_modules/is-what": { 1538 | "version": "4.1.16", 1539 | "resolved": "https://registry.npmmirror.com/is-what/-/is-what-4.1.16.tgz", 1540 | "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", 1541 | "dev": true, 1542 | "license": "MIT", 1543 | "engines": { 1544 | "node": ">=12.13" 1545 | }, 1546 | "funding": { 1547 | "url": "https://github.com/sponsors/mesqueeb" 1548 | } 1549 | }, 1550 | "node_modules/js-tokens": { 1551 | "version": "4.0.0", 1552 | "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz", 1553 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 1554 | "dev": true, 1555 | "license": "MIT" 1556 | }, 1557 | "node_modules/jsesc": { 1558 | "version": "3.1.0", 1559 | "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-3.1.0.tgz", 1560 | "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", 1561 | "dev": true, 1562 | "license": "MIT", 1563 | "bin": { 1564 | "jsesc": "bin/jsesc" 1565 | }, 1566 | "engines": { 1567 | "node": ">=6" 1568 | } 1569 | }, 1570 | "node_modules/json5": { 1571 | "version": "2.2.3", 1572 | "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz", 1573 | "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", 1574 | "dev": true, 1575 | "license": "MIT", 1576 | "bin": { 1577 | "json5": "lib/cli.js" 1578 | }, 1579 | "engines": { 1580 | "node": ">=6" 1581 | } 1582 | }, 1583 | "node_modules/lru-cache": { 1584 | "version": "5.1.1", 1585 | "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz", 1586 | "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", 1587 | "dev": true, 1588 | "license": "ISC", 1589 | "dependencies": { 1590 | "yallist": "^3.0.2" 1591 | } 1592 | }, 1593 | "node_modules/merge-anything": { 1594 | "version": "5.1.7", 1595 | "resolved": "https://registry.npmmirror.com/merge-anything/-/merge-anything-5.1.7.tgz", 1596 | "integrity": "sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==", 1597 | "dev": true, 1598 | "license": "MIT", 1599 | "dependencies": { 1600 | "is-what": "^4.1.8" 1601 | }, 1602 | "engines": { 1603 | "node": ">=12.13" 1604 | }, 1605 | "funding": { 1606 | "url": "https://github.com/sponsors/mesqueeb" 1607 | } 1608 | }, 1609 | "node_modules/ms": { 1610 | "version": "2.1.3", 1611 | "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", 1612 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1613 | "dev": true, 1614 | "license": "MIT" 1615 | }, 1616 | "node_modules/nanoid": { 1617 | "version": "3.3.8", 1618 | "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.8.tgz", 1619 | "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", 1620 | "dev": true, 1621 | "funding": [ 1622 | { 1623 | "type": "github", 1624 | "url": "https://github.com/sponsors/ai" 1625 | } 1626 | ], 1627 | "license": "MIT", 1628 | "bin": { 1629 | "nanoid": "bin/nanoid.cjs" 1630 | }, 1631 | "engines": { 1632 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 1633 | } 1634 | }, 1635 | "node_modules/node-releases": { 1636 | "version": "2.0.19", 1637 | "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.19.tgz", 1638 | "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", 1639 | "dev": true, 1640 | "license": "MIT" 1641 | }, 1642 | "node_modules/parse5": { 1643 | "version": "7.2.1", 1644 | "resolved": "https://registry.npmmirror.com/parse5/-/parse5-7.2.1.tgz", 1645 | "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", 1646 | "dev": true, 1647 | "license": "MIT", 1648 | "dependencies": { 1649 | "entities": "^4.5.0" 1650 | }, 1651 | "funding": { 1652 | "url": "https://github.com/inikulin/parse5?sponsor=1" 1653 | } 1654 | }, 1655 | "node_modules/picocolors": { 1656 | "version": "1.1.1", 1657 | "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", 1658 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", 1659 | "dev": true, 1660 | "license": "ISC" 1661 | }, 1662 | "node_modules/postcss": { 1663 | "version": "8.4.49", 1664 | "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.49.tgz", 1665 | "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", 1666 | "dev": true, 1667 | "funding": [ 1668 | { 1669 | "type": "opencollective", 1670 | "url": "https://opencollective.com/postcss/" 1671 | }, 1672 | { 1673 | "type": "tidelift", 1674 | "url": "https://tidelift.com/funding/github/npm/postcss" 1675 | }, 1676 | { 1677 | "type": "github", 1678 | "url": "https://github.com/sponsors/ai" 1679 | } 1680 | ], 1681 | "license": "MIT", 1682 | "dependencies": { 1683 | "nanoid": "^3.3.7", 1684 | "picocolors": "^1.1.1", 1685 | "source-map-js": "^1.2.1" 1686 | }, 1687 | "engines": { 1688 | "node": "^10 || ^12 || >=14" 1689 | } 1690 | }, 1691 | "node_modules/rollup": { 1692 | "version": "4.28.1", 1693 | "resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.28.1.tgz", 1694 | "integrity": "sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg==", 1695 | "dev": true, 1696 | "license": "MIT", 1697 | "dependencies": { 1698 | "@types/estree": "1.0.6" 1699 | }, 1700 | "bin": { 1701 | "rollup": "dist/bin/rollup" 1702 | }, 1703 | "engines": { 1704 | "node": ">=18.0.0", 1705 | "npm": ">=8.0.0" 1706 | }, 1707 | "optionalDependencies": { 1708 | "@rollup/rollup-android-arm-eabi": "4.28.1", 1709 | "@rollup/rollup-android-arm64": "4.28.1", 1710 | "@rollup/rollup-darwin-arm64": "4.28.1", 1711 | "@rollup/rollup-darwin-x64": "4.28.1", 1712 | "@rollup/rollup-freebsd-arm64": "4.28.1", 1713 | "@rollup/rollup-freebsd-x64": "4.28.1", 1714 | "@rollup/rollup-linux-arm-gnueabihf": "4.28.1", 1715 | "@rollup/rollup-linux-arm-musleabihf": "4.28.1", 1716 | "@rollup/rollup-linux-arm64-gnu": "4.28.1", 1717 | "@rollup/rollup-linux-arm64-musl": "4.28.1", 1718 | "@rollup/rollup-linux-loongarch64-gnu": "4.28.1", 1719 | "@rollup/rollup-linux-powerpc64le-gnu": "4.28.1", 1720 | "@rollup/rollup-linux-riscv64-gnu": "4.28.1", 1721 | "@rollup/rollup-linux-s390x-gnu": "4.28.1", 1722 | "@rollup/rollup-linux-x64-gnu": "4.28.1", 1723 | "@rollup/rollup-linux-x64-musl": "4.28.1", 1724 | "@rollup/rollup-win32-arm64-msvc": "4.28.1", 1725 | "@rollup/rollup-win32-ia32-msvc": "4.28.1", 1726 | "@rollup/rollup-win32-x64-msvc": "4.28.1", 1727 | "fsevents": "~2.3.2" 1728 | } 1729 | }, 1730 | "node_modules/semver": { 1731 | "version": "6.3.1", 1732 | "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", 1733 | "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", 1734 | "dev": true, 1735 | "license": "ISC", 1736 | "bin": { 1737 | "semver": "bin/semver.js" 1738 | } 1739 | }, 1740 | "node_modules/seroval": { 1741 | "version": "1.1.1", 1742 | "resolved": "https://registry.npmmirror.com/seroval/-/seroval-1.1.1.tgz", 1743 | "integrity": "sha512-rqEO6FZk8mv7Hyv4UCj3FD3b6Waqft605TLfsCe/BiaylRpyyMC0b+uA5TJKawX3KzMrdi3wsLbCaLplrQmBvQ==", 1744 | "license": "MIT", 1745 | "engines": { 1746 | "node": ">=10" 1747 | } 1748 | }, 1749 | "node_modules/seroval-plugins": { 1750 | "version": "1.1.1", 1751 | "resolved": "https://registry.npmmirror.com/seroval-plugins/-/seroval-plugins-1.1.1.tgz", 1752 | "integrity": "sha512-qNSy1+nUj7hsCOon7AO4wdAIo9P0jrzAMp18XhiOzA6/uO5TKtP7ScozVJ8T293oRIvi5wyCHSM4TrJo/c/GJA==", 1753 | "license": "MIT", 1754 | "engines": { 1755 | "node": ">=10" 1756 | }, 1757 | "peerDependencies": { 1758 | "seroval": "^1.0" 1759 | } 1760 | }, 1761 | "node_modules/solid-js": { 1762 | "version": "1.9.5", 1763 | "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.9.5.tgz", 1764 | "integrity": "sha512-ogI3DaFcyn6UhYhrgcyRAMbu/buBJitYQASZz5WzfQVPP10RD2AbCoRZ517psnezrasyCbWzIxZ6kVqet768xw==", 1765 | "license": "MIT", 1766 | "dependencies": { 1767 | "csstype": "^3.1.0", 1768 | "seroval": "^1.1.0", 1769 | "seroval-plugins": "^1.1.0" 1770 | } 1771 | }, 1772 | "node_modules/solid-refresh": { 1773 | "version": "0.6.3", 1774 | "resolved": "https://registry.npmmirror.com/solid-refresh/-/solid-refresh-0.6.3.tgz", 1775 | "integrity": "sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA==", 1776 | "dev": true, 1777 | "license": "MIT", 1778 | "dependencies": { 1779 | "@babel/generator": "^7.23.6", 1780 | "@babel/helper-module-imports": "^7.22.15", 1781 | "@babel/types": "^7.23.6" 1782 | }, 1783 | "peerDependencies": { 1784 | "solid-js": "^1.3" 1785 | } 1786 | }, 1787 | "node_modules/source-map-js": { 1788 | "version": "1.2.1", 1789 | "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz", 1790 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", 1791 | "dev": true, 1792 | "license": "BSD-3-Clause", 1793 | "engines": { 1794 | "node": ">=0.10.0" 1795 | } 1796 | }, 1797 | "node_modules/typescript": { 1798 | "version": "5.7.2", 1799 | "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.7.2.tgz", 1800 | "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", 1801 | "dev": true, 1802 | "license": "Apache-2.0", 1803 | "bin": { 1804 | "tsc": "bin/tsc", 1805 | "tsserver": "bin/tsserver" 1806 | }, 1807 | "engines": { 1808 | "node": ">=14.17" 1809 | } 1810 | }, 1811 | "node_modules/update-browserslist-db": { 1812 | "version": "1.1.1", 1813 | "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", 1814 | "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", 1815 | "dev": true, 1816 | "funding": [ 1817 | { 1818 | "type": "opencollective", 1819 | "url": "https://opencollective.com/browserslist" 1820 | }, 1821 | { 1822 | "type": "tidelift", 1823 | "url": "https://tidelift.com/funding/github/npm/browserslist" 1824 | }, 1825 | { 1826 | "type": "github", 1827 | "url": "https://github.com/sponsors/ai" 1828 | } 1829 | ], 1830 | "license": "MIT", 1831 | "dependencies": { 1832 | "escalade": "^3.2.0", 1833 | "picocolors": "^1.1.0" 1834 | }, 1835 | "bin": { 1836 | "update-browserslist-db": "cli.js" 1837 | }, 1838 | "peerDependencies": { 1839 | "browserslist": ">= 4.21.0" 1840 | } 1841 | }, 1842 | "node_modules/uuid": { 1843 | "version": "10.0.0", 1844 | "resolved": "https://registry.npmmirror.com/uuid/-/uuid-10.0.0.tgz", 1845 | "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", 1846 | "dev": true, 1847 | "funding": [ 1848 | "https://github.com/sponsors/broofa", 1849 | "https://github.com/sponsors/ctavan" 1850 | ], 1851 | "license": "MIT", 1852 | "bin": { 1853 | "uuid": "dist/bin/uuid" 1854 | } 1855 | }, 1856 | "node_modules/validate-html-nesting": { 1857 | "version": "1.2.2", 1858 | "resolved": "https://registry.npmmirror.com/validate-html-nesting/-/validate-html-nesting-1.2.2.tgz", 1859 | "integrity": "sha512-hGdgQozCsQJMyfK5urgFcWEqsSSrK63Awe0t/IMR0bZ0QMtnuaiHzThW81guu3qx9abLi99NEuiaN6P9gVYsNg==", 1860 | "dev": true, 1861 | "license": "ISC" 1862 | }, 1863 | "node_modules/vite": { 1864 | "version": "5.4.14", 1865 | "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", 1866 | "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", 1867 | "dev": true, 1868 | "license": "MIT", 1869 | "dependencies": { 1870 | "esbuild": "^0.21.3", 1871 | "postcss": "^8.4.43", 1872 | "rollup": "^4.20.0" 1873 | }, 1874 | "bin": { 1875 | "vite": "bin/vite.js" 1876 | }, 1877 | "engines": { 1878 | "node": "^18.0.0 || >=20.0.0" 1879 | }, 1880 | "funding": { 1881 | "url": "https://github.com/vitejs/vite?sponsor=1" 1882 | }, 1883 | "optionalDependencies": { 1884 | "fsevents": "~2.3.3" 1885 | }, 1886 | "peerDependencies": { 1887 | "@types/node": "^18.0.0 || >=20.0.0", 1888 | "less": "*", 1889 | "lightningcss": "^1.21.0", 1890 | "sass": "*", 1891 | "sass-embedded": "*", 1892 | "stylus": "*", 1893 | "sugarss": "*", 1894 | "terser": "^5.4.0" 1895 | }, 1896 | "peerDependenciesMeta": { 1897 | "@types/node": { 1898 | "optional": true 1899 | }, 1900 | "less": { 1901 | "optional": true 1902 | }, 1903 | "lightningcss": { 1904 | "optional": true 1905 | }, 1906 | "sass": { 1907 | "optional": true 1908 | }, 1909 | "sass-embedded": { 1910 | "optional": true 1911 | }, 1912 | "stylus": { 1913 | "optional": true 1914 | }, 1915 | "sugarss": { 1916 | "optional": true 1917 | }, 1918 | "terser": { 1919 | "optional": true 1920 | } 1921 | } 1922 | }, 1923 | "node_modules/vite-plugin-solid": { 1924 | "version": "2.11.0", 1925 | "resolved": "https://registry.npmmirror.com/vite-plugin-solid/-/vite-plugin-solid-2.11.0.tgz", 1926 | "integrity": "sha512-G+NiwDj4EAeUE0wt3Ur9f+Lt9oMUuLd0FIxYuqwJSqRacKQRteCwUFzNy8zMEt88xWokngQhiFjfJMhjc1fDXw==", 1927 | "dev": true, 1928 | "license": "MIT", 1929 | "dependencies": { 1930 | "@babel/core": "^7.23.3", 1931 | "@types/babel__core": "^7.20.4", 1932 | "babel-preset-solid": "^1.8.4", 1933 | "merge-anything": "^5.1.7", 1934 | "solid-refresh": "^0.6.3", 1935 | "vitefu": "^1.0.4" 1936 | }, 1937 | "peerDependencies": { 1938 | "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", 1939 | "solid-js": "^1.7.2", 1940 | "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" 1941 | }, 1942 | "peerDependenciesMeta": { 1943 | "@testing-library/jest-dom": { 1944 | "optional": true 1945 | } 1946 | } 1947 | }, 1948 | "node_modules/vite-plugin-top-level-await": { 1949 | "version": "1.4.4", 1950 | "resolved": "https://registry.npmmirror.com/vite-plugin-top-level-await/-/vite-plugin-top-level-await-1.4.4.tgz", 1951 | "integrity": "sha512-QyxQbvcMkgt+kDb12m2P8Ed35Sp6nXP+l8ptGrnHV9zgYDUpraO0CPdlqLSeBqvY2DToR52nutDG7mIHuysdiw==", 1952 | "dev": true, 1953 | "license": "MIT", 1954 | "dependencies": { 1955 | "@rollup/plugin-virtual": "^3.0.2", 1956 | "@swc/core": "^1.7.0", 1957 | "uuid": "^10.0.0" 1958 | }, 1959 | "peerDependencies": { 1960 | "vite": ">=2.8" 1961 | } 1962 | }, 1963 | "node_modules/vite-plugin-wasm": { 1964 | "version": "3.3.0", 1965 | "resolved": "https://registry.npmmirror.com/vite-plugin-wasm/-/vite-plugin-wasm-3.3.0.tgz", 1966 | "integrity": "sha512-tVhz6w+W9MVsOCHzxo6SSMSswCeIw4HTrXEi6qL3IRzATl83jl09JVO1djBqPSwfjgnpVHNLYcaMbaDX5WB/pg==", 1967 | "dev": true, 1968 | "license": "MIT", 1969 | "peerDependencies": { 1970 | "vite": "^2 || ^3 || ^4 || ^5" 1971 | } 1972 | }, 1973 | "node_modules/vitefu": { 1974 | "version": "1.0.4", 1975 | "resolved": "https://registry.npmmirror.com/vitefu/-/vitefu-1.0.4.tgz", 1976 | "integrity": "sha512-y6zEE3PQf6uu/Mt6DTJ9ih+kyJLr4XcSgHR2zUkM8SWDhuixEJxfJ6CZGMHh1Ec3vPLoEA0IHU5oWzVqw8ulow==", 1977 | "dev": true, 1978 | "license": "MIT", 1979 | "workspaces": [ 1980 | "tests/deps/*", 1981 | "tests/projects/*" 1982 | ], 1983 | "peerDependencies": { 1984 | "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" 1985 | }, 1986 | "peerDependenciesMeta": { 1987 | "vite": { 1988 | "optional": true 1989 | } 1990 | } 1991 | }, 1992 | "node_modules/yallist": { 1993 | "version": "3.1.1", 1994 | "resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz", 1995 | "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", 1996 | "dev": true, 1997 | "license": "ISC" 1998 | } 1999 | } 2000 | } 2001 | -------------------------------------------------------------------------------- /osmos-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "osmos-web", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "start": "vite --host 0.0.0.0", 6 | "dev": "vite --host 0.0.0.0", 7 | "build": "vite build", 8 | "serve": "vite preview" 9 | }, 10 | "devDependencies": { 11 | "typescript": "^5.7.2", 12 | "vite": "^5.4.14", 13 | "vite-plugin-solid": "^2.11.0", 14 | "vite-plugin-top-level-await": "^1.4.4", 15 | "vite-plugin-wasm": "^3.3.0" 16 | }, 17 | "dependencies": { 18 | "solid-js": "^1.9.5" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /osmos-web/public/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /osmos-web/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { createSignal, onCleanup, onMount } from "solid-js"; 2 | import * as osmos from "../osmos-wasm"; 3 | 4 | const colorList = [ 5 | "#FFF1DC", 6 | "#E8D5C4", 7 | "#EEEEEE", 8 | "#F7C8E0", 9 | "#DFFFD8", 10 | "#B4E4FF", 11 | "#95BDFF", 12 | "#F47C7C", 13 | "#7DB9B6", 14 | "#F0A04B", 15 | ]; 16 | 17 | const size = 900; 18 | const simulator = new osmos.Simulator(); 19 | 20 | const App = () => { 21 | const [speedInput, setSpeedInput] = createSignal(1); 22 | const [speed, setSpeed] = createSignal(1); 23 | const [epoch, setEpoch] = createSignal(1); 24 | const [step, setStep] = createSignal(1); 25 | const [population, setPopulation] = createSignal(1); 26 | 27 | let canvas: HTMLCanvasElement; 28 | 29 | onMount(() => { 30 | const ctx = canvas!.getContext("2d"); 31 | 32 | const render = () => { 33 | ctx!.clearRect(0, 0, size, size); 34 | 35 | setEpoch(simulator.getEpochCount()); 36 | setStep(simulator.getStepCount()); 37 | 38 | const objectList = simulator.getObjectList(); 39 | setPopulation(objectList.length); 40 | 41 | for (let object of objectList) { 42 | ctx!.beginPath(); 43 | ctx!.fillStyle = colorList[object.id % colorList.length]; 44 | ctx!.arc( 45 | object.x * size, 46 | (1 - object.y) * size, 47 | object.energy, 48 | 0, 49 | 2 * Math.PI 50 | ); 51 | ctx!.fill(); 52 | } 53 | 54 | for (let i = 0; i < speed(); i++) { 55 | simulator.step(); 56 | } 57 | 58 | frame = requestAnimationFrame(render); 59 | }; 60 | 61 | let frame = requestAnimationFrame(render); 62 | 63 | onCleanup(() => cancelAnimationFrame(frame)); 64 | }); 65 | 66 | return ( 67 | <> 68 |
69 | 96 | 97 | 98 | 99 | 105 |
106 | 107 | ); 108 | }; 109 | 110 | export default App; 111 | -------------------------------------------------------------------------------- /osmos-web/src/index.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: sans-serif; 3 | color-scheme: dark; 4 | background-color: #242424; 5 | } 6 | 7 | body { 8 | margin: 0; 9 | width: 100%; 10 | height: 100%; 11 | } 12 | 13 | #app { 14 | margin: 0 auto; 15 | text-align: center; 16 | } 17 | 18 | #info, 19 | #footer { 20 | margin: 10px; 21 | font-size: 1.2rem; 22 | color: #17c3b2; 23 | } 24 | 25 | a { 26 | color: #17c3b2; 27 | } 28 | 29 | canvas { 30 | border: #17c3b2 solid; 31 | margin: 5px; 32 | } 33 | 34 | input { 35 | padding: 0.8em 1.8em; 36 | border: 2px solid #17c3b2; 37 | position: relative; 38 | overflow: hidden; 39 | background-color: transparent; 40 | text-transform: uppercase; 41 | font-size: 16px; 42 | color: #17c3b2; 43 | } 44 | 45 | button { 46 | padding: 0.8em 1.8em; 47 | border: 2px solid #17c3b2; 48 | position: relative; 49 | overflow: hidden; 50 | background-color: transparent; 51 | text-align: center; 52 | text-transform: uppercase; 53 | font-size: 16px; 54 | transition: 0.3s; 55 | z-index: 1; 56 | color: #17c3b2; 57 | } 58 | 59 | button::before { 60 | content: ""; 61 | width: 0; 62 | height: 300%; 63 | position: absolute; 64 | top: 50%; 65 | left: 50%; 66 | transform: translate(-50%, -50%) rotate(45deg); 67 | background: #17c3b2; 68 | transition: 0.5s ease; 69 | display: block; 70 | z-index: -1; 71 | } 72 | 73 | button:hover::before { 74 | width: 105%; 75 | } 76 | 77 | button:hover { 78 | color: #242424; 79 | } 80 | -------------------------------------------------------------------------------- /osmos-web/src/index.tsx: -------------------------------------------------------------------------------- 1 | /* @refresh reload */ 2 | import { render } from "solid-js/web"; 3 | 4 | import "./index.css"; 5 | import App from "./App"; 6 | 7 | const root = document.getElementById("root"); 8 | 9 | if (import.meta.env.DEV && !(root instanceof HTMLElement)) { 10 | throw new Error( 11 | "Root element not found. Did you forget to add it to your index.html? Or maybe the id attribute got mispelled?" 12 | ); 13 | } 14 | 15 | render(() => , root!); 16 | -------------------------------------------------------------------------------- /osmos-web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "target": "ESNext", 5 | "module": "ESNext", 6 | "moduleResolution": "node", 7 | "allowSyntheticDefaultImports": true, 8 | "esModuleInterop": true, 9 | "jsx": "preserve", 10 | "jsxImportSource": "solid-js", 11 | "types": ["vite/client"], 12 | "noEmit": true, 13 | "isolatedModules": true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /osmos-web/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import solidPlugin from "vite-plugin-solid"; 3 | import wasm from "vite-plugin-wasm"; 4 | import topLevelAwait from "vite-plugin-top-level-await"; 5 | 6 | export default defineConfig({ 7 | plugins: [solidPlugin(), wasm(), topLevelAwait()], 8 | server: { 9 | port: 8000, 10 | }, 11 | build: { 12 | target: "esnext", 13 | }, 14 | }); 15 | --------------------------------------------------------------------------------