Live location tracking and playback for the game "manhunt"

Better transport error checking

bwc9876.dev 30a75b56 419651c3

verified
+348 -187
+101 -2
Cargo.lock
··· 194 194 checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" 195 195 196 196 [[package]] 197 + name = "ashpd" 198 + version = "0.11.0" 199 + source = "registry+https://github.com/rust-lang/crates.io-index" 200 + checksum = "6cbdf310d77fd3aaee6ea2093db7011dc2d35d2eb3481e5607f1f8d942ed99df" 201 + dependencies = [ 202 + "enumflags2", 203 + "futures-channel", 204 + "futures-util", 205 + "rand 0.9.1", 206 + "raw-window-handle", 207 + "serde", 208 + "serde_repr", 209 + "tokio", 210 + "url", 211 + "zbus", 212 + ] 213 + 214 + [[package]] 197 215 name = "asn1-rs" 198 216 version = "0.6.2" 199 217 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1370 1388 1371 1389 [[package]] 1372 1390 name = "dispatch2" 1391 + version = "0.2.0" 1392 + source = "registry+https://github.com/rust-lang/crates.io-index" 1393 + checksum = "1a0d569e003ff27784e0e14e4a594048698e0c0f0b66cabcb51511be55a7caa0" 1394 + dependencies = [ 1395 + "bitflags 2.9.1", 1396 + "block2 0.6.1", 1397 + "libc", 1398 + "objc2 0.6.1", 1399 + ] 1400 + 1401 + [[package]] 1402 + name = "dispatch2" 1373 1403 version = "0.3.0" 1374 1404 source = "registry+https://github.com/rust-lang/crates.io-index" 1375 1405 checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" ··· 2927 2957 "specta-typescript", 2928 2958 "tauri", 2929 2959 "tauri-build", 2960 + "tauri-plugin-dialog", 2930 2961 "tauri-plugin-geolocation", 2931 2962 "tauri-plugin-log", 2932 2963 "tauri-plugin-notification", ··· 3363 3394 checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" 3364 3395 dependencies = [ 3365 3396 "bitflags 2.9.1", 3366 - "dispatch2", 3397 + "dispatch2 0.3.0", 3367 3398 "objc2 0.6.1", 3368 3399 ] 3369 3400 ··· 3374 3405 checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4" 3375 3406 dependencies = [ 3376 3407 "bitflags 2.9.1", 3377 - "dispatch2", 3408 + "dispatch2 0.3.0", 3378 3409 "objc2 0.6.1", 3379 3410 "objc2-core-foundation", 3380 3411 "objc2-io-surface", ··· 4407 4438 ] 4408 4439 4409 4440 [[package]] 4441 + name = "rfd" 4442 + version = "0.15.3" 4443 + source = "registry+https://github.com/rust-lang/crates.io-index" 4444 + checksum = "80c844748fdc82aae252ee4594a89b6e7ebef1063de7951545564cbc4e57075d" 4445 + dependencies = [ 4446 + "ashpd", 4447 + "block2 0.6.1", 4448 + "dispatch2 0.2.0", 4449 + "glib-sys", 4450 + "gobject-sys", 4451 + "gtk-sys", 4452 + "js-sys", 4453 + "log", 4454 + "objc2 0.6.1", 4455 + "objc2-app-kit", 4456 + "objc2-core-foundation", 4457 + "objc2-foundation 0.3.1", 4458 + "raw-window-handle", 4459 + "wasm-bindgen", 4460 + "wasm-bindgen-futures", 4461 + "web-sys", 4462 + "windows-sys 0.59.0", 4463 + ] 4464 + 4465 + [[package]] 4410 4466 name = "ring" 4411 4467 version = "0.17.14" 4412 4468 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5506 5562 ] 5507 5563 5508 5564 [[package]] 5565 + name = "tauri-plugin-dialog" 5566 + version = "2.2.2" 5567 + source = "registry+https://github.com/rust-lang/crates.io-index" 5568 + checksum = "a33318fe222fc2a612961de8b0419e2982767f213f54a4d3a21b0d7b85c41df8" 5569 + dependencies = [ 5570 + "log", 5571 + "raw-window-handle", 5572 + "rfd", 5573 + "serde", 5574 + "serde_json", 5575 + "tauri", 5576 + "tauri-plugin", 5577 + "tauri-plugin-fs", 5578 + "thiserror 2.0.12", 5579 + "url", 5580 + ] 5581 + 5582 + [[package]] 5583 + name = "tauri-plugin-fs" 5584 + version = "2.3.0" 5585 + source = "registry+https://github.com/rust-lang/crates.io-index" 5586 + checksum = "33ead0daec5d305adcefe05af9d970fc437bcc7996052d564e7393eb291252da" 5587 + dependencies = [ 5588 + "anyhow", 5589 + "dunce", 5590 + "glob", 5591 + "percent-encoding", 5592 + "schemars 0.8.22", 5593 + "serde", 5594 + "serde_json", 5595 + "serde_repr", 5596 + "tauri", 5597 + "tauri-plugin", 5598 + "tauri-utils", 5599 + "thiserror 2.0.12", 5600 + "toml", 5601 + "url", 5602 + ] 5603 + 5604 + [[package]] 5509 5605 name = "tauri-plugin-geolocation" 5510 5606 version = "2.2.4" 5511 5607 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5879 5975 "signal-hook-registry", 5880 5976 "socket2", 5881 5977 "tokio-macros", 5978 + "tracing", 5882 5979 "windows-sys 0.52.0", 5883 5980 ] 5884 5981 ··· 7435 7532 "ordered-stream", 7436 7533 "serde", 7437 7534 "serde_repr", 7535 + "tokio", 7438 7536 "tracing", 7439 7537 "uds_windows", 7440 7538 "windows-sys 0.59.0", ··· 7574 7672 "endi", 7575 7673 "enumflags2", 7576 7674 "serde", 7675 + "url", 7577 7676 "winnow 0.7.11", 7578 7677 "zvariant_derive", 7579 7678 "zvariant_utils",
+4 -1
TODO.md
··· 13 13 - [x] API : Handling Profile Syncing 14 14 - [x] API : State Update Events 15 15 - [x] API : Game Replay Screen 16 - - [ ] Frontend : Scaffolding 16 + - [x] Frontend : Scaffolding 17 17 - [x] Meta : CI Setup 18 18 - [x] Meta : README Instructions 19 19 - [x] Meta : Recipes for type binding generation 20 20 - [x] Signaling: All of it 21 + - [x] Backend : Better transport error handling 22 + - [ ] Backend : Abstract lobby? Separate crate? 23 + - [x] Backend : Add checks for when the `powerup_locations` field is an empty array in settings 21 24 - [ ] Backend : More tests
+1
backend/Cargo.toml
··· 42 42 anyhow = "1.0.98" 43 43 reqwest = { version = "0.12.20", default-features = false, features = ["charset", "http2", "rustls-tls", "system-proxy"] } 44 44 const-str = "0.6.2" 45 + tauri-plugin-dialog = "2"
+2 -1
backend/capabilities/default.json
··· 8 8 "opener:default", 9 9 "notification:default", 10 10 "log:default", 11 - "geolocation:default" 11 + "geolocation:default", 12 + "dialog:default" 12 13 ] 13 14 }
+2
backend/src/game/events.rs
··· 22 22 DroppedPlayer(Id), 23 23 /// The underlying transport has disconnected 24 24 TransportDisconnect, 25 + /// The underlying transport encountered an error 26 + TransportError(String), 25 27 }
+3
backend/src/game/mod.rs
··· 151 151 GameEvent::TransportDisconnect => { 152 152 bail!("Transport disconnected"); 153 153 } 154 + GameEvent::TransportError(err) => { 155 + bail!("Transport error: {err}"); 156 + } 154 157 GameEvent::PostGameSync(id, history) => { 155 158 state.insert_player_location_history(id, history); 156 159 }
+13 -6
backend/src/game/state.rs
··· 193 193 194 194 /// Whether to start spawning powerups 195 195 pub fn should_start_powerups(&self, now: UtcDT) -> bool { 196 - match self.settings.powerup_start { 197 - PingStartCondition::Players(num) => (self.iter_seekers().count() as u32) >= num, 198 - PingStartCondition::Minutes(mins) => self 199 - .minutes_since_seekers_released(now) 200 - .is_some_and(|seekers_released| seekers_released >= mins), 201 - PingStartCondition::Instant => true, 196 + if self.settings.powerup_locations.is_empty() { 197 + false 198 + } else { 199 + match self.settings.powerup_start { 200 + PingStartCondition::Players(num) => (self.iter_seekers().count() as u32) >= num, 201 + PingStartCondition::Minutes(mins) => self 202 + .minutes_since_seekers_released(now) 203 + .is_some_and(|seekers_released| seekers_released >= mins), 204 + PingStartCondition::Instant => true, 205 + } 202 206 } 203 207 } 204 208 ··· 397 401 game_started: self.game_started, 398 402 game_ended: self.game_ended, 399 403 last_global_ping: self.last_global_ping, 404 + last_powerup_spawn: self.last_powerup_spawn, 400 405 held_powerup: self.held_powerup, 401 406 seekers_started: self.seekers_started, 402 407 } ··· 433 438 game_ended: Option<UtcDT>, 434 439 /// The last time all hiders were pinged **in UTC** 435 440 last_global_ping: Option<UtcDT>, 441 + /// The last time a powerup was spawned **in UTC** 442 + last_powerup_spawn: Option<UtcDT>, 436 443 /// The [PowerUpType] the local player is holding 437 444 held_powerup: Option<PowerUpType>, 438 445 /// When the seekers were allowed to start **in UTC**
+12
backend/src/lib.rs
··· 16 16 use profile::PlayerProfile; 17 17 use serde::{Deserialize, Serialize}; 18 18 use tauri::{AppHandle, Manager, State}; 19 + use tauri_plugin_dialog::{DialogExt, MessageDialogKind}; 19 20 use tauri_specta::{collect_commands, collect_events, Event}; 20 21 use tokio::sync::RwLock; 21 22 use transport::MatchboxTransport; ··· 107 108 let history = AppGameHistory::new(history, profiles); 108 109 if let Err(why) = history.save_history(&app2) { 109 110 error!("Failed to save game history: {why:?}"); 111 + app2.dialog() 112 + .message("Failed to save the history of this game") 113 + .kind(MessageDialogKind::Error) 114 + .show(|_| {}); 110 115 } 111 116 state.quit_to_menu(app2); 112 117 } 113 118 Err(why) => { 114 119 error!("Game Error: {why:?}"); 120 + app2.dialog().message("There was a connection error in the game, you have been disconnected").kind(MessageDialogKind::Error).show(|_| {}); 115 121 state.quit_to_menu(app2); 116 122 } 117 123 } ··· 225 231 } 226 232 Err(why) => { 227 233 error!("Lobby Error: {why:?}"); 234 + app_game 235 + .dialog() 236 + .message("Error joining the lobby") 237 + .kind(MessageDialogKind::Error) 238 + .show(|_| {}); 228 239 state.quit_to_menu(app_game); 229 240 } 230 241 } ··· 513 524 let builder = mk_specta(); 514 525 515 526 tauri::Builder::default() 527 + .plugin(tauri_plugin_dialog::init()) 516 528 .plugin(tauri_plugin_notification::init()) 517 529 .plugin( 518 530 tauri_plugin_log::Builder::new()
+4 -1
backend/src/lobby.rs
··· 182 182 } 183 183 TransportMessage::Disconnected => { 184 184 break 'lobby Err(anyhow!( 185 - "Transport disconnected before lobby could start game" 185 + "Transport disconnected unexpectedly before lobby could start game" 186 186 )); 187 + } 188 + TransportMessage::Error(why) => { 189 + break 'lobby Err(anyhow!("Transport error: {why}")); 187 190 } 188 191 TransportMessage::Game(game_event) => { 189 192 eprintln!("Peer {peer:?} sent a GameEvent: {game_event:?}");
+8 -1
backend/src/transport.rs
··· 43 43 /// Event sent when the transport gets disconnected, used to help consumers know when to stop 44 44 /// consuming messages 45 45 Disconnected, 46 + /// Event when the transport encounters a critical error and needs to disconnect 47 + Error(String), 46 48 /// Internal message for packet chunking 47 49 Seq(TransportChunk), 48 50 } ··· 322 324 self.handle_send(&mut socket, &all_peers, &mut buffer).await; 323 325 } 324 326 325 - _ = &mut loop_fut => { 327 + res = &mut loop_fut => { 326 328 // Break on disconnect 329 + if let Err(why) = res { 330 + self.push_incoming(my_id.unwrap_or_default(), TransportMessage::Error(why.to_string())).await; 331 + } 327 332 break; 328 333 } 329 334 } ··· 339 344 .filter_map(|(id, msg)| match msg { 340 345 TransportMessage::Game(game_event) => Some(*game_event), 341 346 TransportMessage::PeerDisconnect => Some(GameEvent::DroppedPlayer(id)), 347 + TransportMessage::Disconnected => Some(GameEvent::TransportDisconnect), 348 + TransportMessage::Error(err) => Some(GameEvent::TransportError(err)), 342 349 _ => None, 343 350 }) 344 351 }
+175 -172
frontend/package-lock.json
··· 9 9 "version": "0.1.0", 10 10 "dependencies": { 11 11 "@tauri-apps/api": "^2", 12 + "@tauri-apps/plugin-dialog": "^2", 12 13 "@tauri-apps/plugin-geolocation": "^2", 13 14 "@tauri-apps/plugin-log": "^2", 14 15 "@tauri-apps/plugin-notification": "^2", ··· 1086 1087 "license": "MIT" 1087 1088 }, 1088 1089 "node_modules/@rollup/rollup-android-arm-eabi": { 1089 - "version": "4.43.0", 1090 - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.43.0.tgz", 1091 - "integrity": "sha512-Krjy9awJl6rKbruhQDgivNbD1WuLb8xAclM4IR4cN5pHGAs2oIMMQJEiC3IC/9TZJ+QZkmZhlMO/6MBGxPidpw==", 1090 + "version": "4.44.0", 1091 + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.0.tgz", 1092 + "integrity": "sha512-xEiEE5oDW6tK4jXCAyliuntGR+amEMO7HLtdSshVuhFnKTYoeYMyXQK7pLouAJJj5KHdwdn87bfHAR2nSdNAUA==", 1092 1093 "cpu": [ 1093 1094 "arm" 1094 1095 ], ··· 1100 1101 ] 1101 1102 }, 1102 1103 "node_modules/@rollup/rollup-android-arm64": { 1103 - "version": "4.43.0", 1104 - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.43.0.tgz", 1105 - "integrity": "sha512-ss4YJwRt5I63454Rpj+mXCXicakdFmKnUNxr1dLK+5rv5FJgAxnN7s31a5VchRYxCFWdmnDWKd0wbAdTr0J5EA==", 1104 + "version": "4.44.0", 1105 + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.44.0.tgz", 1106 + "integrity": "sha512-uNSk/TgvMbskcHxXYHzqwiyBlJ/lGcv8DaUfcnNwict8ba9GTTNxfn3/FAoFZYgkaXXAdrAA+SLyKplyi349Jw==", 1106 1107 "cpu": [ 1107 1108 "arm64" 1108 1109 ], ··· 1114 1115 ] 1115 1116 }, 1116 1117 "node_modules/@rollup/rollup-darwin-arm64": { 1117 - "version": "4.43.0", 1118 - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.43.0.tgz", 1119 - "integrity": "sha512-eKoL8ykZ7zz8MjgBenEF2OoTNFAPFz1/lyJ5UmmFSz5jW+7XbH1+MAgCVHy72aG59rbuQLcJeiMrP8qP5d/N0A==", 1118 + "version": "4.44.0", 1119 + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.44.0.tgz", 1120 + "integrity": "sha512-VGF3wy0Eq1gcEIkSCr8Ke03CWT+Pm2yveKLaDvq51pPpZza3JX/ClxXOCmTYYq3us5MvEuNRTaeyFThCKRQhOA==", 1120 1121 "cpu": [ 1121 1122 "arm64" 1122 1123 ], ··· 1128 1129 ] 1129 1130 }, 1130 1131 "node_modules/@rollup/rollup-darwin-x64": { 1131 - "version": "4.43.0", 1132 - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.43.0.tgz", 1133 - "integrity": "sha512-SYwXJgaBYW33Wi/q4ubN+ldWC4DzQY62S4Ll2dgfr/dbPoF50dlQwEaEHSKrQdSjC6oIe1WgzosoaNoHCdNuMg==", 1132 + "version": "4.44.0", 1133 + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.44.0.tgz", 1134 + "integrity": "sha512-fBkyrDhwquRvrTxSGH/qqt3/T0w5Rg0L7ZIDypvBPc1/gzjJle6acCpZ36blwuwcKD/u6oCE/sRWlUAcxLWQbQ==", 1134 1135 "cpu": [ 1135 1136 "x64" 1136 1137 ], ··· 1142 1143 ] 1143 1144 }, 1144 1145 "node_modules/@rollup/rollup-freebsd-arm64": { 1145 - "version": "4.43.0", 1146 - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.43.0.tgz", 1147 - "integrity": "sha512-SV+U5sSo0yujrjzBF7/YidieK2iF6E7MdF6EbYxNz94lA+R0wKl3SiixGyG/9Klab6uNBIqsN7j4Y/Fya7wAjQ==", 1146 + "version": "4.44.0", 1147 + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.44.0.tgz", 1148 + "integrity": "sha512-u5AZzdQJYJXByB8giQ+r4VyfZP+walV+xHWdaFx/1VxsOn6eWJhK2Vl2eElvDJFKQBo/hcYIBg/jaKS8ZmKeNQ==", 1148 1149 "cpu": [ 1149 1150 "arm64" 1150 1151 ], ··· 1156 1157 ] 1157 1158 }, 1158 1159 "node_modules/@rollup/rollup-freebsd-x64": { 1159 - "version": "4.43.0", 1160 - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.43.0.tgz", 1161 - "integrity": "sha512-J7uCsiV13L/VOeHJBo5SjasKiGxJ0g+nQTrBkAsmQBIdil3KhPnSE9GnRon4ejX1XDdsmK/l30IYLiAaQEO0Cg==", 1160 + "version": "4.44.0", 1161 + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.44.0.tgz", 1162 + "integrity": "sha512-qC0kS48c/s3EtdArkimctY7h3nHicQeEUdjJzYVJYR3ct3kWSafmn6jkNCA8InbUdge6PVx6keqjk5lVGJf99g==", 1162 1163 "cpu": [ 1163 1164 "x64" 1164 1165 ], ··· 1170 1171 ] 1171 1172 }, 1172 1173 "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 1173 - "version": "4.43.0", 1174 - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.43.0.tgz", 1175 - "integrity": "sha512-gTJ/JnnjCMc15uwB10TTATBEhK9meBIY+gXP4s0sHD1zHOaIh4Dmy1X9wup18IiY9tTNk5gJc4yx9ctj/fjrIw==", 1174 + "version": "4.44.0", 1175 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.44.0.tgz", 1176 + "integrity": "sha512-x+e/Z9H0RAWckn4V2OZZl6EmV0L2diuX3QB0uM1r6BvhUIv6xBPL5mrAX2E3e8N8rEHVPwFfz/ETUbV4oW9+lQ==", 1176 1177 "cpu": [ 1177 1178 "arm" 1178 1179 ], ··· 1184 1185 ] 1185 1186 }, 1186 1187 "node_modules/@rollup/rollup-linux-arm-musleabihf": { 1187 - "version": "4.43.0", 1188 - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.43.0.tgz", 1189 - "integrity": "sha512-ZJ3gZynL1LDSIvRfz0qXtTNs56n5DI2Mq+WACWZ7yGHFUEirHBRt7fyIk0NsCKhmRhn7WAcjgSkSVVxKlPNFFw==", 1188 + "version": "4.44.0", 1189 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.44.0.tgz", 1190 + "integrity": "sha512-1exwiBFf4PU/8HvI8s80icyCcnAIB86MCBdst51fwFmH5dyeoWVPVgmQPcKrMtBQ0W5pAs7jBCWuRXgEpRzSCg==", 1190 1191 "cpu": [ 1191 1192 "arm" 1192 1193 ], ··· 1198 1199 ] 1199 1200 }, 1200 1201 "node_modules/@rollup/rollup-linux-arm64-gnu": { 1201 - "version": "4.43.0", 1202 - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.43.0.tgz", 1203 - "integrity": "sha512-8FnkipasmOOSSlfucGYEu58U8cxEdhziKjPD2FIa0ONVMxvl/hmONtX/7y4vGjdUhjcTHlKlDhw3H9t98fPvyA==", 1202 + "version": "4.44.0", 1203 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.44.0.tgz", 1204 + "integrity": "sha512-ZTR2mxBHb4tK4wGf9b8SYg0Y6KQPjGpR4UWwTFdnmjB4qRtoATZ5dWn3KsDwGa5Z2ZBOE7K52L36J9LueKBdOQ==", 1204 1205 "cpu": [ 1205 1206 "arm64" 1206 1207 ], ··· 1212 1213 ] 1213 1214 }, 1214 1215 "node_modules/@rollup/rollup-linux-arm64-musl": { 1215 - "version": "4.43.0", 1216 - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.43.0.tgz", 1217 - "integrity": "sha512-KPPyAdlcIZ6S9C3S2cndXDkV0Bb1OSMsX0Eelr2Bay4EsF9yi9u9uzc9RniK3mcUGCLhWY9oLr6er80P5DE6XA==", 1216 + "version": "4.44.0", 1217 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.44.0.tgz", 1218 + "integrity": "sha512-GFWfAhVhWGd4r6UxmnKRTBwP1qmModHtd5gkraeW2G490BpFOZkFtem8yuX2NyafIP/mGpRJgTJ2PwohQkUY/Q==", 1218 1219 "cpu": [ 1219 1220 "arm64" 1220 1221 ], ··· 1226 1227 ] 1227 1228 }, 1228 1229 "node_modules/@rollup/rollup-linux-loongarch64-gnu": { 1229 - "version": "4.43.0", 1230 - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.43.0.tgz", 1231 - "integrity": "sha512-HPGDIH0/ZzAZjvtlXj6g+KDQ9ZMHfSP553za7o2Odegb/BEfwJcR0Sw0RLNpQ9nC6Gy8s+3mSS9xjZ0n3rhcYg==", 1230 + "version": "4.44.0", 1231 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.44.0.tgz", 1232 + "integrity": "sha512-xw+FTGcov/ejdusVOqKgMGW3c4+AgqrfvzWEVXcNP6zq2ue+lsYUgJ+5Rtn/OTJf7e2CbgTFvzLW2j0YAtj0Gg==", 1232 1233 "cpu": [ 1233 1234 "loong64" 1234 1235 ], ··· 1240 1241 ] 1241 1242 }, 1242 1243 "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { 1243 - "version": "4.43.0", 1244 - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.43.0.tgz", 1245 - "integrity": "sha512-gEmwbOws4U4GLAJDhhtSPWPXUzDfMRedT3hFMyRAvM9Mrnj+dJIFIeL7otsv2WF3D7GrV0GIewW0y28dOYWkmw==", 1244 + "version": "4.44.0", 1245 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.44.0.tgz", 1246 + "integrity": "sha512-bKGibTr9IdF0zr21kMvkZT4K6NV+jjRnBoVMt2uNMG0BYWm3qOVmYnXKzx7UhwrviKnmK46IKMByMgvpdQlyJQ==", 1246 1247 "cpu": [ 1247 1248 "ppc64" 1248 1249 ], ··· 1254 1255 ] 1255 1256 }, 1256 1257 "node_modules/@rollup/rollup-linux-riscv64-gnu": { 1257 - "version": "4.43.0", 1258 - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.43.0.tgz", 1259 - "integrity": "sha512-XXKvo2e+wFtXZF/9xoWohHg+MuRnvO29TI5Hqe9xwN5uN8NKUYy7tXUG3EZAlfchufNCTHNGjEx7uN78KsBo0g==", 1258 + "version": "4.44.0", 1259 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.44.0.tgz", 1260 + "integrity": "sha512-vV3cL48U5kDaKZtXrti12YRa7TyxgKAIDoYdqSIOMOFBXqFj2XbChHAtXquEn2+n78ciFgr4KIqEbydEGPxXgA==", 1260 1261 "cpu": [ 1261 1262 "riscv64" 1262 1263 ], ··· 1268 1269 ] 1269 1270 }, 1270 1271 "node_modules/@rollup/rollup-linux-riscv64-musl": { 1271 - "version": "4.43.0", 1272 - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.43.0.tgz", 1273 - "integrity": "sha512-ruf3hPWhjw6uDFsOAzmbNIvlXFXlBQ4nk57Sec8E8rUxs/AI4HD6xmiiasOOx/3QxS2f5eQMKTAwk7KHwpzr/Q==", 1272 + "version": "4.44.0", 1273 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.44.0.tgz", 1274 + "integrity": "sha512-TDKO8KlHJuvTEdfw5YYFBjhFts2TR0VpZsnLLSYmB7AaohJhM8ctDSdDnUGq77hUh4m/djRafw+9zQpkOanE2Q==", 1274 1275 "cpu": [ 1275 1276 "riscv64" 1276 1277 ], ··· 1282 1283 ] 1283 1284 }, 1284 1285 "node_modules/@rollup/rollup-linux-s390x-gnu": { 1285 - "version": "4.43.0", 1286 - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.43.0.tgz", 1287 - "integrity": "sha512-QmNIAqDiEMEvFV15rsSnjoSmO0+eJLoKRD9EAa9rrYNwO/XRCtOGM3A5A0X+wmG+XRrw9Fxdsw+LnyYiZWWcVw==", 1286 + "version": "4.44.0", 1287 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.44.0.tgz", 1288 + "integrity": "sha512-8541GEyktXaw4lvnGp9m84KENcxInhAt6vPWJ9RodsB/iGjHoMB2Pp5MVBCiKIRxrxzJhGCxmNzdu+oDQ7kwRA==", 1288 1289 "cpu": [ 1289 1290 "s390x" 1290 1291 ], ··· 1296 1297 ] 1297 1298 }, 1298 1299 "node_modules/@rollup/rollup-linux-x64-gnu": { 1299 - "version": "4.43.0", 1300 - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.43.0.tgz", 1301 - "integrity": "sha512-jAHr/S0iiBtFyzjhOkAics/2SrXE092qyqEg96e90L3t9Op8OTzS6+IX0Fy5wCt2+KqeHAkti+eitV0wvblEoQ==", 1300 + "version": "4.44.0", 1301 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.44.0.tgz", 1302 + "integrity": "sha512-iUVJc3c0o8l9Sa/qlDL2Z9UP92UZZW1+EmQ4xfjTc1akr0iUFZNfxrXJ/R1T90h/ILm9iXEY6+iPrmYB3pXKjw==", 1302 1303 "cpu": [ 1303 1304 "x64" 1304 1305 ], ··· 1310 1311 ] 1311 1312 }, 1312 1313 "node_modules/@rollup/rollup-linux-x64-musl": { 1313 - "version": "4.43.0", 1314 - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.43.0.tgz", 1315 - "integrity": "sha512-3yATWgdeXyuHtBhrLt98w+5fKurdqvs8B53LaoKD7P7H7FKOONLsBVMNl9ghPQZQuYcceV5CDyPfyfGpMWD9mQ==", 1314 + "version": "4.44.0", 1315 + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.44.0.tgz", 1316 + "integrity": "sha512-PQUobbhLTQT5yz/SPg116VJBgz+XOtXt8D1ck+sfJJhuEsMj2jSej5yTdp8CvWBSceu+WW+ibVL6dm0ptG5fcA==", 1316 1317 "cpu": [ 1317 1318 "x64" 1318 1319 ], ··· 1324 1325 ] 1325 1326 }, 1326 1327 "node_modules/@rollup/rollup-win32-arm64-msvc": { 1327 - "version": "4.43.0", 1328 - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.43.0.tgz", 1329 - "integrity": "sha512-wVzXp2qDSCOpcBCT5WRWLmpJRIzv23valvcTwMHEobkjippNf+C3ys/+wf07poPkeNix0paTNemB2XrHr2TnGw==", 1328 + "version": "4.44.0", 1329 + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.44.0.tgz", 1330 + "integrity": "sha512-M0CpcHf8TWn+4oTxJfh7LQuTuaYeXGbk0eageVjQCKzYLsajWS/lFC94qlRqOlyC2KvRT90ZrfXULYmukeIy7w==", 1330 1331 "cpu": [ 1331 1332 "arm64" 1332 1333 ], ··· 1338 1339 ] 1339 1340 }, 1340 1341 "node_modules/@rollup/rollup-win32-ia32-msvc": { 1341 - "version": "4.43.0", 1342 - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.43.0.tgz", 1343 - "integrity": "sha512-fYCTEyzf8d+7diCw8b+asvWDCLMjsCEA8alvtAutqJOJp/wL5hs1rWSqJ1vkjgW0L2NB4bsYJrpKkiIPRR9dvw==", 1342 + "version": "4.44.0", 1343 + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.44.0.tgz", 1344 + "integrity": "sha512-3XJ0NQtMAXTWFW8FqZKcw3gOQwBtVWP/u8TpHP3CRPXD7Pd6s8lLdH3sHWh8vqKCyyiI8xW5ltJScQmBU9j7WA==", 1344 1345 "cpu": [ 1345 1346 "ia32" 1346 1347 ], ··· 1352 1353 ] 1353 1354 }, 1354 1355 "node_modules/@rollup/rollup-win32-x64-msvc": { 1355 - "version": "4.43.0", 1356 - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.43.0.tgz", 1357 - "integrity": "sha512-SnGhLiE5rlK0ofq8kzuDkM0g7FN1s5VYY+YSMTibP7CqShxCQvqtNxTARS4xX4PFJfHjG0ZQYX9iGzI3FQh5Aw==", 1356 + "version": "4.44.0", 1357 + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.44.0.tgz", 1358 + "integrity": "sha512-Q2Mgwt+D8hd5FIPUuPDsvPR7Bguza6yTkJxspDGkZj7tBRn2y4KSWYuIXpftFSjBra76TbKerCV7rgFPQrn+wQ==", 1358 1359 "cpu": [ 1359 1360 "x64" 1360 1361 ], ··· 1375 1376 "url": "https://opencollective.com/tauri" 1376 1377 } 1377 1378 }, 1379 + "node_modules/@tauri-apps/plugin-dialog": { 1380 + "version": "2.2.2", 1381 + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.2.2.tgz", 1382 + "integrity": "sha512-Pm9qnXQq8ZVhAMFSEPwxvh+nWb2mk7LASVlNEHYaksHvcz8P6+ElR5U5dNL9Ofrm+uwhh1/gYKWswK8JJJAh6A==", 1383 + "license": "MIT OR Apache-2.0", 1384 + "dependencies": { 1385 + "@tauri-apps/api": "^2.0.0" 1386 + } 1387 + }, 1378 1388 "node_modules/@tauri-apps/plugin-geolocation": { 1379 - "version": "2.2.4", 1380 - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-geolocation/-/plugin-geolocation-2.2.4.tgz", 1381 - "integrity": "sha512-c/kqxMW3DjCl+EzFRRBc2B9J22DqzmQOt02i9IWy3WYXIRF8/krTqZpqNIi2Db2/eWS5dEtS6z5S9sBk6UIr2g==", 1389 + "version": "2.2.5", 1390 + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-geolocation/-/plugin-geolocation-2.2.5.tgz", 1391 + "integrity": "sha512-sBQQyxdNnSHIiFwSxTO52kRiPdQsec1pvaD5g1lXX8NjPOQNN3ujPWM5Fq81eubdrkhCHoNrWAfd9ix7sxLrRA==", 1382 1392 "license": "MIT OR Apache-2.0", 1383 1393 "dependencies": { 1384 1394 "@tauri-apps/api": "^2.0.0" 1385 1395 } 1386 1396 }, 1387 1397 "node_modules/@tauri-apps/plugin-log": { 1388 - "version": "2.4.0", 1389 - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-log/-/plugin-log-2.4.0.tgz", 1390 - "integrity": "sha512-j7yrDtLNmayCBOO2esl3aZv9jSXy2an8MDLry3Ys9ZXerwUg35n1Y2uD8HoCR+8Ng/EUgx215+qOUfJasjYrHw==", 1398 + "version": "2.5.0", 1399 + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-log/-/plugin-log-2.5.0.tgz", 1400 + "integrity": "sha512-ZMq6aZbezMk/rqXopu7tQse9ljQhUTt5cje4nAQ8LumIu6dgN8QseonbuPd198toUNj3tvWTxVR8/lBemG64tw==", 1391 1401 "license": "MIT OR Apache-2.0", 1392 1402 "dependencies": { 1393 1403 "@tauri-apps/api": "^2.0.0" 1394 1404 } 1395 1405 }, 1396 1406 "node_modules/@tauri-apps/plugin-notification": { 1397 - "version": "2.2.2", 1398 - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-notification/-/plugin-notification-2.2.2.tgz", 1399 - "integrity": "sha512-d71rJdtkFUTcG4dqydnv6d7ZwlNZVcdjrVOPwc9GsF6y9DgVN1WCZ9T/vbfD2qrJslf7ai+rnNJc62TLLC2IdA==", 1407 + "version": "2.2.3", 1408 + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-notification/-/plugin-notification-2.2.3.tgz", 1409 + "integrity": "sha512-IlMdSVFsrKg0eIHBloFFosnWbbz6JdwBywfZrYZnE1+acgXvNS3T1YB5w9R6UXw+KKQ94ODBu7JF7a1YUiAK6A==", 1400 1410 "license": "MIT OR Apache-2.0", 1401 1411 "dependencies": { 1402 1412 "@tauri-apps/api": "^2.0.0" 1403 1413 } 1404 1414 }, 1405 1415 "node_modules/@tauri-apps/plugin-opener": { 1406 - "version": "2.2.7", 1407 - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-opener/-/plugin-opener-2.2.7.tgz", 1408 - "integrity": "sha512-uduEyvOdjpPOEeDRrhwlCspG/f9EQalHumWBtLBnp3fRp++fKGLqDOyUhSIn7PzX45b/rKep//ZQSAQoIxobLA==", 1416 + "version": "2.3.0", 1417 + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-opener/-/plugin-opener-2.3.0.tgz", 1418 + "integrity": "sha512-yAbauwp8BCHIhhA48NN8rEf6OtfZBPCgTOCa10gmtoVCpmic5Bq+1Ba7C+NZOjogedkSiV7hAotjYnnbUVmYrw==", 1409 1419 "license": "MIT OR Apache-2.0", 1410 1420 "dependencies": { 1411 1421 "@tauri-apps/api": "^2.0.0" ··· 1501 1511 } 1502 1512 }, 1503 1513 "node_modules/@typescript-eslint/eslint-plugin": { 1504 - "version": "8.34.0", 1505 - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.34.0.tgz", 1506 - "integrity": "sha512-QXwAlHlbcAwNlEEMKQS2RCgJsgXrTJdjXT08xEgbPFa2yYQgVjBymxP5DrfrE7X7iodSzd9qBUHUycdyVJTW1w==", 1514 + "version": "8.34.1", 1515 + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.34.1.tgz", 1516 + "integrity": "sha512-STXcN6ebF6li4PxwNeFnqF8/2BNDvBupf2OPx2yWNzr6mKNGF7q49VM00Pz5FaomJyqvbXpY6PhO+T9w139YEQ==", 1507 1517 "dev": true, 1508 1518 "license": "MIT", 1509 1519 "dependencies": { 1510 1520 "@eslint-community/regexpp": "^4.10.0", 1511 - "@typescript-eslint/scope-manager": "8.34.0", 1512 - "@typescript-eslint/type-utils": "8.34.0", 1513 - "@typescript-eslint/utils": "8.34.0", 1514 - "@typescript-eslint/visitor-keys": "8.34.0", 1521 + "@typescript-eslint/scope-manager": "8.34.1", 1522 + "@typescript-eslint/type-utils": "8.34.1", 1523 + "@typescript-eslint/utils": "8.34.1", 1524 + "@typescript-eslint/visitor-keys": "8.34.1", 1515 1525 "graphemer": "^1.4.0", 1516 1526 "ignore": "^7.0.0", 1517 1527 "natural-compare": "^1.4.0", ··· 1525 1535 "url": "https://opencollective.com/typescript-eslint" 1526 1536 }, 1527 1537 "peerDependencies": { 1528 - "@typescript-eslint/parser": "^8.34.0", 1538 + "@typescript-eslint/parser": "^8.34.1", 1529 1539 "eslint": "^8.57.0 || ^9.0.0", 1530 1540 "typescript": ">=4.8.4 <5.9.0" 1531 1541 } ··· 1541 1551 } 1542 1552 }, 1543 1553 "node_modules/@typescript-eslint/parser": { 1544 - "version": "8.34.0", 1545 - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.34.0.tgz", 1546 - "integrity": "sha512-vxXJV1hVFx3IXz/oy2sICsJukaBrtDEQSBiV48/YIV5KWjX1dO+bcIr/kCPrW6weKXvsaGKFNlwH0v2eYdRRbA==", 1554 + "version": "8.34.1", 1555 + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.34.1.tgz", 1556 + "integrity": "sha512-4O3idHxhyzjClSMJ0a29AcoK0+YwnEqzI6oz3vlRf3xw0zbzt15MzXwItOlnr5nIth6zlY2RENLsOPvhyrKAQA==", 1547 1557 "dev": true, 1548 1558 "license": "MIT", 1549 1559 "dependencies": { 1550 - "@typescript-eslint/scope-manager": "8.34.0", 1551 - "@typescript-eslint/types": "8.34.0", 1552 - "@typescript-eslint/typescript-estree": "8.34.0", 1553 - "@typescript-eslint/visitor-keys": "8.34.0", 1560 + "@typescript-eslint/scope-manager": "8.34.1", 1561 + "@typescript-eslint/types": "8.34.1", 1562 + "@typescript-eslint/typescript-estree": "8.34.1", 1563 + "@typescript-eslint/visitor-keys": "8.34.1", 1554 1564 "debug": "^4.3.4" 1555 1565 }, 1556 1566 "engines": { ··· 1566 1576 } 1567 1577 }, 1568 1578 "node_modules/@typescript-eslint/project-service": { 1569 - "version": "8.34.0", 1570 - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.34.0.tgz", 1571 - "integrity": "sha512-iEgDALRf970/B2YExmtPMPF54NenZUf4xpL3wsCRx/lgjz6ul/l13R81ozP/ZNuXfnLCS+oPmG7JIxfdNYKELw==", 1579 + "version": "8.34.1", 1580 + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.34.1.tgz", 1581 + "integrity": "sha512-nuHlOmFZfuRwLJKDGQOVc0xnQrAmuq1Mj/ISou5044y1ajGNp2BNliIqp7F2LPQ5sForz8lempMFCovfeS1XoA==", 1572 1582 "dev": true, 1573 1583 "license": "MIT", 1574 1584 "dependencies": { 1575 - "@typescript-eslint/tsconfig-utils": "^8.34.0", 1576 - "@typescript-eslint/types": "^8.34.0", 1585 + "@typescript-eslint/tsconfig-utils": "^8.34.1", 1586 + "@typescript-eslint/types": "^8.34.1", 1577 1587 "debug": "^4.3.4" 1578 1588 }, 1579 1589 "engines": { ··· 1588 1598 } 1589 1599 }, 1590 1600 "node_modules/@typescript-eslint/scope-manager": { 1591 - "version": "8.34.0", 1592 - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.34.0.tgz", 1593 - "integrity": "sha512-9Ac0X8WiLykl0aj1oYQNcLZjHgBojT6cW68yAgZ19letYu+Hxd0rE0veI1XznSSst1X5lwnxhPbVdwjDRIomRw==", 1601 + "version": "8.34.1", 1602 + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.34.1.tgz", 1603 + "integrity": "sha512-beu6o6QY4hJAgL1E8RaXNC071G4Kso2MGmJskCFQhRhg8VOH/FDbC8soP8NHN7e/Hdphwp8G8cE6OBzC8o41ZA==", 1594 1604 "dev": true, 1595 1605 "license": "MIT", 1596 1606 "dependencies": { 1597 - "@typescript-eslint/types": "8.34.0", 1598 - "@typescript-eslint/visitor-keys": "8.34.0" 1607 + "@typescript-eslint/types": "8.34.1", 1608 + "@typescript-eslint/visitor-keys": "8.34.1" 1599 1609 }, 1600 1610 "engines": { 1601 1611 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" ··· 1606 1616 } 1607 1617 }, 1608 1618 "node_modules/@typescript-eslint/tsconfig-utils": { 1609 - "version": "8.34.0", 1610 - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.34.0.tgz", 1611 - "integrity": "sha512-+W9VYHKFIzA5cBeooqQxqNriAP0QeQ7xTiDuIOr71hzgffm3EL2hxwWBIIj4GuofIbKxGNarpKqIq6Q6YrShOA==", 1619 + "version": "8.34.1", 1620 + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.34.1.tgz", 1621 + "integrity": "sha512-K4Sjdo4/xF9NEeA2khOb7Y5nY6NSXBnod87uniVYW9kHP+hNlDV8trUSFeynA2uxWam4gIWgWoygPrv9VMWrYg==", 1612 1622 "dev": true, 1613 1623 "license": "MIT", 1614 1624 "engines": { ··· 1623 1633 } 1624 1634 }, 1625 1635 "node_modules/@typescript-eslint/type-utils": { 1626 - "version": "8.34.0", 1627 - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.34.0.tgz", 1628 - "integrity": "sha512-n7zSmOcUVhcRYC75W2pnPpbO1iwhJY3NLoHEtbJwJSNlVAZuwqu05zY3f3s2SDWWDSo9FdN5szqc73DCtDObAg==", 1636 + "version": "8.34.1", 1637 + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.34.1.tgz", 1638 + "integrity": "sha512-Tv7tCCr6e5m8hP4+xFugcrwTOucB8lshffJ6zf1mF1TbU67R+ntCc6DzLNKM+s/uzDyv8gLq7tufaAhIBYeV8g==", 1629 1639 "dev": true, 1630 1640 "license": "MIT", 1631 1641 "dependencies": { 1632 - "@typescript-eslint/typescript-estree": "8.34.0", 1633 - "@typescript-eslint/utils": "8.34.0", 1642 + "@typescript-eslint/typescript-estree": "8.34.1", 1643 + "@typescript-eslint/utils": "8.34.1", 1634 1644 "debug": "^4.3.4", 1635 1645 "ts-api-utils": "^2.1.0" 1636 1646 }, ··· 1647 1657 } 1648 1658 }, 1649 1659 "node_modules/@typescript-eslint/types": { 1650 - "version": "8.34.0", 1651 - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.34.0.tgz", 1652 - "integrity": "sha512-9V24k/paICYPniajHfJ4cuAWETnt7Ssy+R0Rbcqo5sSFr3QEZ/8TSoUi9XeXVBGXCaLtwTOKSLGcInCAvyZeMA==", 1660 + "version": "8.34.1", 1661 + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.34.1.tgz", 1662 + "integrity": "sha512-rjLVbmE7HR18kDsjNIZQHxmv9RZwlgzavryL5Lnj2ujIRTeXlKtILHgRNmQ3j4daw7zd+mQgy+uyt6Zo6I0IGA==", 1653 1663 "dev": true, 1654 1664 "license": "MIT", 1655 1665 "engines": { ··· 1661 1671 } 1662 1672 }, 1663 1673 "node_modules/@typescript-eslint/typescript-estree": { 1664 - "version": "8.34.0", 1665 - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.34.0.tgz", 1666 - "integrity": "sha512-rOi4KZxI7E0+BMqG7emPSK1bB4RICCpF7QD3KCLXn9ZvWoESsOMlHyZPAHyG04ujVplPaHbmEvs34m+wjgtVtg==", 1674 + "version": "8.34.1", 1675 + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.34.1.tgz", 1676 + "integrity": "sha512-rjCNqqYPuMUF5ODD+hWBNmOitjBWghkGKJg6hiCHzUvXRy6rK22Jd3rwbP2Xi+R7oYVvIKhokHVhH41BxPV5mA==", 1667 1677 "dev": true, 1668 1678 "license": "MIT", 1669 1679 "dependencies": { 1670 - "@typescript-eslint/project-service": "8.34.0", 1671 - "@typescript-eslint/tsconfig-utils": "8.34.0", 1672 - "@typescript-eslint/types": "8.34.0", 1673 - "@typescript-eslint/visitor-keys": "8.34.0", 1680 + "@typescript-eslint/project-service": "8.34.1", 1681 + "@typescript-eslint/tsconfig-utils": "8.34.1", 1682 + "@typescript-eslint/types": "8.34.1", 1683 + "@typescript-eslint/visitor-keys": "8.34.1", 1674 1684 "debug": "^4.3.4", 1675 1685 "fast-glob": "^3.3.2", 1676 1686 "is-glob": "^4.0.3", ··· 1729 1739 } 1730 1740 }, 1731 1741 "node_modules/@typescript-eslint/utils": { 1732 - "version": "8.34.0", 1733 - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.34.0.tgz", 1734 - "integrity": "sha512-8L4tWatGchV9A1cKbjaavS6mwYwp39jql8xUmIIKJdm+qiaeHy5KMKlBrf30akXAWBzn2SqKsNOtSENWUwg7XQ==", 1742 + "version": "8.34.1", 1743 + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.34.1.tgz", 1744 + "integrity": "sha512-mqOwUdZ3KjtGk7xJJnLbHxTuWVn3GO2WZZuM+Slhkun4+qthLdXx32C8xIXbO1kfCECb3jIs3eoxK3eryk7aoQ==", 1735 1745 "dev": true, 1736 1746 "license": "MIT", 1737 1747 "dependencies": { 1738 1748 "@eslint-community/eslint-utils": "^4.7.0", 1739 - "@typescript-eslint/scope-manager": "8.34.0", 1740 - "@typescript-eslint/types": "8.34.0", 1741 - "@typescript-eslint/typescript-estree": "8.34.0" 1749 + "@typescript-eslint/scope-manager": "8.34.1", 1750 + "@typescript-eslint/types": "8.34.1", 1751 + "@typescript-eslint/typescript-estree": "8.34.1" 1742 1752 }, 1743 1753 "engines": { 1744 1754 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" ··· 1753 1763 } 1754 1764 }, 1755 1765 "node_modules/@typescript-eslint/visitor-keys": { 1756 - "version": "8.34.0", 1757 - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.34.0.tgz", 1758 - "integrity": "sha512-qHV7pW7E85A0x6qyrFn+O+q1k1p3tQCsqIZ1KZ5ESLXY57aTvUd3/a4rdPTeXisvhXn2VQG0VSKUqs8KHF2zcA==", 1766 + "version": "8.34.1", 1767 + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.34.1.tgz", 1768 + "integrity": "sha512-xoh5rJ+tgsRKoXnkBPFRLZ7rjKM0AfVbC68UZ/ECXoDbfggb9RbEySN359acY1vS3qZ0jVTVWzbtfapwm5ztxw==", 1759 1769 "dev": true, 1760 1770 "license": "MIT", 1761 1771 "dependencies": { 1762 - "@typescript-eslint/types": "8.34.0", 1763 - "eslint-visitor-keys": "^4.2.0" 1772 + "@typescript-eslint/types": "8.34.1", 1773 + "eslint-visitor-keys": "^4.2.1" 1764 1774 }, 1765 1775 "engines": { 1766 1776 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" ··· 2143 2153 } 2144 2154 }, 2145 2155 "node_modules/caniuse-lite": { 2146 - "version": "1.0.30001723", 2147 - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001723.tgz", 2148 - "integrity": "sha512-1R/elMjtehrFejxwmexeXAtae5UO9iSyFn6G/I806CYC/BLyyBk1EPhrKBkWhy6wM6Xnm47dSJQec+tLJ39WHw==", 2156 + "version": "1.0.30001724", 2157 + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001724.tgz", 2158 + "integrity": "sha512-WqJo7p0TbHDOythNTqYujmaJTvtYRZrjpP8TCvH6Vb9CYJerJNKamKzIWOM4BkQatWj9H2lYulpdAQNBe7QhNA==", 2149 2159 "dev": true, 2150 2160 "funding": [ 2151 2161 { ··· 2389 2399 } 2390 2400 }, 2391 2401 "node_modules/electron-to-chromium": { 2392 - "version": "1.5.167", 2393 - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.167.tgz", 2394 - "integrity": "sha512-LxcRvnYO5ez2bMOFpbuuVuAI5QNeY1ncVytE/KXaL6ZNfzX1yPlAO0nSOyIHx2fVAuUprMqPs/TdVhUFZy7SIQ==", 2402 + "version": "1.5.171", 2403 + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.171.tgz", 2404 + "integrity": "sha512-scWpzXEJEMrGJa4Y6m/tVotb0WuvNmasv3wWVzUAeCgKU0ToFOhUW6Z+xWnRQANMYGxN4ngJXIThgBJOqzVPCQ==", 2395 2405 "dev": true, 2396 2406 "license": "ISC" 2397 2407 }, ··· 4220 4230 } 4221 4231 }, 4222 4232 "node_modules/postcss": { 4223 - "version": "8.5.5", 4224 - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.5.tgz", 4225 - "integrity": "sha512-d/jtm+rdNT8tpXuHY5MMtcbJFBkhXE6593XVR9UoGCH8jSFGci7jGvMGH5RYd5PBJW+00NZQt6gf7CbagJCrhg==", 4233 + "version": "8.5.6", 4234 + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", 4235 + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", 4226 4236 "dev": true, 4227 4237 "funding": [ 4228 4238 { ··· 4439 4449 } 4440 4450 }, 4441 4451 "node_modules/rollup": { 4442 - "version": "4.43.0", 4443 - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.43.0.tgz", 4444 - "integrity": "sha512-wdN2Kd3Twh8MAEOEJZsuxuLKCsBEo4PVNLK6tQWAn10VhsVewQLzcucMgLolRlhFybGxfclbPeEYBaP6RvUFGg==", 4452 + "version": "4.44.0", 4453 + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.44.0.tgz", 4454 + "integrity": "sha512-qHcdEzLCiktQIfwBq420pn2dP+30uzqYxv9ETm91wdt2R9AFcWfjNAmje4NWlnCIQ5RMTzVf0ZyisOKqHR6RwA==", 4445 4455 "dev": true, 4446 4456 "license": "MIT", 4447 4457 "dependencies": { 4448 - "@types/estree": "1.0.7" 4458 + "@types/estree": "1.0.8" 4449 4459 }, 4450 4460 "bin": { 4451 4461 "rollup": "dist/bin/rollup" ··· 4455 4465 "npm": ">=8.0.0" 4456 4466 }, 4457 4467 "optionalDependencies": { 4458 - "@rollup/rollup-android-arm-eabi": "4.43.0", 4459 - "@rollup/rollup-android-arm64": "4.43.0", 4460 - "@rollup/rollup-darwin-arm64": "4.43.0", 4461 - "@rollup/rollup-darwin-x64": "4.43.0", 4462 - "@rollup/rollup-freebsd-arm64": "4.43.0", 4463 - "@rollup/rollup-freebsd-x64": "4.43.0", 4464 - "@rollup/rollup-linux-arm-gnueabihf": "4.43.0", 4465 - "@rollup/rollup-linux-arm-musleabihf": "4.43.0", 4466 - "@rollup/rollup-linux-arm64-gnu": "4.43.0", 4467 - "@rollup/rollup-linux-arm64-musl": "4.43.0", 4468 - "@rollup/rollup-linux-loongarch64-gnu": "4.43.0", 4469 - "@rollup/rollup-linux-powerpc64le-gnu": "4.43.0", 4470 - "@rollup/rollup-linux-riscv64-gnu": "4.43.0", 4471 - "@rollup/rollup-linux-riscv64-musl": "4.43.0", 4472 - "@rollup/rollup-linux-s390x-gnu": "4.43.0", 4473 - "@rollup/rollup-linux-x64-gnu": "4.43.0", 4474 - "@rollup/rollup-linux-x64-musl": "4.43.0", 4475 - "@rollup/rollup-win32-arm64-msvc": "4.43.0", 4476 - "@rollup/rollup-win32-ia32-msvc": "4.43.0", 4477 - "@rollup/rollup-win32-x64-msvc": "4.43.0", 4468 + "@rollup/rollup-android-arm-eabi": "4.44.0", 4469 + "@rollup/rollup-android-arm64": "4.44.0", 4470 + "@rollup/rollup-darwin-arm64": "4.44.0", 4471 + "@rollup/rollup-darwin-x64": "4.44.0", 4472 + "@rollup/rollup-freebsd-arm64": "4.44.0", 4473 + "@rollup/rollup-freebsd-x64": "4.44.0", 4474 + "@rollup/rollup-linux-arm-gnueabihf": "4.44.0", 4475 + "@rollup/rollup-linux-arm-musleabihf": "4.44.0", 4476 + "@rollup/rollup-linux-arm64-gnu": "4.44.0", 4477 + "@rollup/rollup-linux-arm64-musl": "4.44.0", 4478 + "@rollup/rollup-linux-loongarch64-gnu": "4.44.0", 4479 + "@rollup/rollup-linux-powerpc64le-gnu": "4.44.0", 4480 + "@rollup/rollup-linux-riscv64-gnu": "4.44.0", 4481 + "@rollup/rollup-linux-riscv64-musl": "4.44.0", 4482 + "@rollup/rollup-linux-s390x-gnu": "4.44.0", 4483 + "@rollup/rollup-linux-x64-gnu": "4.44.0", 4484 + "@rollup/rollup-linux-x64-musl": "4.44.0", 4485 + "@rollup/rollup-win32-arm64-msvc": "4.44.0", 4486 + "@rollup/rollup-win32-ia32-msvc": "4.44.0", 4487 + "@rollup/rollup-win32-x64-msvc": "4.44.0", 4478 4488 "fsevents": "~2.3.2" 4479 4489 } 4480 - }, 4481 - "node_modules/rollup/node_modules/@types/estree": { 4482 - "version": "1.0.7", 4483 - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", 4484 - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", 4485 - "dev": true, 4486 - "license": "MIT" 4487 4490 }, 4488 4491 "node_modules/run-parallel": { 4489 4492 "version": "1.2.0", ··· 5079 5082 } 5080 5083 }, 5081 5084 "node_modules/typescript-eslint": { 5082 - "version": "8.34.0", 5083 - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.34.0.tgz", 5084 - "integrity": "sha512-MRpfN7uYjTrTGigFCt8sRyNqJFhjN0WwZecldaqhWm+wy0gaRt8Edb/3cuUy0zdq2opJWT6iXINKAtewnDOltQ==", 5085 + "version": "8.34.1", 5086 + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.34.1.tgz", 5087 + "integrity": "sha512-XjS+b6Vg9oT1BaIUfkW3M3LvqZE++rbzAMEHuccCfO/YkP43ha6w3jTEMilQxMF92nVOYCcdjv1ZUhAa1D/0ow==", 5085 5088 "dev": true, 5086 5089 "license": "MIT", 5087 5090 "dependencies": { 5088 - "@typescript-eslint/eslint-plugin": "8.34.0", 5089 - "@typescript-eslint/parser": "8.34.0", 5090 - "@typescript-eslint/utils": "8.34.0" 5091 + "@typescript-eslint/eslint-plugin": "8.34.1", 5092 + "@typescript-eslint/parser": "8.34.1", 5093 + "@typescript-eslint/utils": "8.34.1" 5091 5094 }, 5092 5095 "engines": { 5093 5096 "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+1
frontend/package.json
··· 15 15 "@tauri-apps/plugin-log": "^2", 16 16 "@tauri-apps/plugin-notification": "^2", 17 17 "@tauri-apps/plugin-opener": "^2", 18 + "@tauri-apps/plugin-dialog": "^2", 18 19 "react": "^19", 19 20 "react-dom": "^19", 20 21 "swr": "^2.3.3"
+9 -1
frontend/src/bindings.ts
··· 302 302 /** 303 303 * The underlying transport has disconnected 304 304 */ 305 - | "TransportDisconnect"; 305 + | "TransportDisconnect" 306 + /** 307 + * The underlying transport encountered an error 308 + */ 309 + | { TransportError: string }; 306 310 export type GameHistory = { 307 311 my_id: string; 308 312 game_started: string; ··· 385 389 * The last time all hiders were pinged **in UTC** 386 390 */ 387 391 last_global_ping: string | null; 392 + /** 393 + * The last time a powerup was spawned **in UTC** 394 + */ 395 + last_powerup_spawn: string | null; 388 396 /** 389 397 * The [PowerUpType] the local player is holding 390 398 */
+9
frontend/src/components/GameScreen.tsx
··· 41 41 } 42 42 }; 43 43 44 + const quitToMenu = async () => { 45 + unwrapResult(await commands.quitToMenu()); 46 + }; 47 + 44 48 if (gameState.game_ended) { 45 49 return <h2>Game Over! Syncing histories...</h2>; 46 50 } else if (isSeeker && gameState.seekers_started === null) { ··· 72 76 <small>Pings haven&apos;t started yet</small> 73 77 )} 74 78 <h2>Powerups</h2> 79 + {gameState.last_powerup_spawn === null && ( 80 + <small>Powerups haven&apos;t started yet</small> 81 + )} 75 82 {gameState.available_powerup && ( 76 83 <p> 77 84 Powerup Available: {JSON.stringify(gameState.available_powerup)}{" "} ··· 86 93 )) || <button onClick={usePowerup}>Use</button>} 87 94 </p> 88 95 )} 96 + <h2>Quit</h2> 97 + <button onClick={quitToMenu}>Quit To Menu</button> 89 98 </> 90 99 ); 91 100 }
+4 -2
frontend/src/components/LobbyScreen.tsx
··· 32 32 unwrapResult(await commands.quitToMenu()); 33 33 }; 34 34 35 + if (lobbyState.self_id === null) { 36 + return <h2>Connecting to Lobby...</h2>; 37 + } 38 + 35 39 return ( 36 40 <> 37 41 <h2>Join Code: {lobbyState.join_code}</h2> ··· 58 62 ))} 59 63 </ul> 60 64 <button onClick={quit}>Quit to Menu</button> 61 - 62 - <code>{JSON.stringify(lobbyState)}</code> 63 65 </> 64 66 ); 65 67 }