Deliver DMs to Bluesky users on leaflet.pub comments
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

*: first commit

geesawra a630d8ab

+3511
+1
.gitignore
··· 1 + /target
+2761
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 = "adler2" 7 + version = "2.0.1" 8 + source = "registry+https://github.com/rust-lang/crates.io-index" 9 + checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" 10 + 11 + [[package]] 12 + name = "aho-corasick" 13 + version = "1.1.4" 14 + source = "registry+https://github.com/rust-lang/crates.io-index" 15 + checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" 16 + dependencies = [ 17 + "memchr", 18 + ] 19 + 20 + [[package]] 21 + name = "allocator-api2" 22 + version = "0.2.21" 23 + source = "registry+https://github.com/rust-lang/crates.io-index" 24 + checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" 25 + 26 + [[package]] 27 + name = "android_system_properties" 28 + version = "0.1.5" 29 + source = "registry+https://github.com/rust-lang/crates.io-index" 30 + checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 31 + dependencies = [ 32 + "libc", 33 + ] 34 + 35 + [[package]] 36 + name = "anstream" 37 + version = "0.6.21" 38 + source = "registry+https://github.com/rust-lang/crates.io-index" 39 + checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" 40 + dependencies = [ 41 + "anstyle", 42 + "anstyle-parse", 43 + "anstyle-query", 44 + "anstyle-wincon", 45 + "colorchoice", 46 + "is_terminal_polyfill", 47 + "utf8parse", 48 + ] 49 + 50 + [[package]] 51 + name = "anstyle" 52 + version = "1.0.13" 53 + source = "registry+https://github.com/rust-lang/crates.io-index" 54 + checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" 55 + 56 + [[package]] 57 + name = "anstyle-parse" 58 + version = "0.2.7" 59 + source = "registry+https://github.com/rust-lang/crates.io-index" 60 + checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" 61 + dependencies = [ 62 + "utf8parse", 63 + ] 64 + 65 + [[package]] 66 + name = "anstyle-query" 67 + version = "1.1.5" 68 + source = "registry+https://github.com/rust-lang/crates.io-index" 69 + checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" 70 + dependencies = [ 71 + "windows-sys 0.61.2", 72 + ] 73 + 74 + [[package]] 75 + name = "anstyle-wincon" 76 + version = "3.0.11" 77 + source = "registry+https://github.com/rust-lang/crates.io-index" 78 + checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" 79 + dependencies = [ 80 + "anstyle", 81 + "once_cell_polyfill", 82 + "windows-sys 0.61.2", 83 + ] 84 + 85 + [[package]] 86 + name = "anyhow" 87 + version = "1.0.100" 88 + source = "registry+https://github.com/rust-lang/crates.io-index" 89 + checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" 90 + 91 + [[package]] 92 + name = "async-compression" 93 + version = "0.4.34" 94 + source = "registry+https://github.com/rust-lang/crates.io-index" 95 + checksum = "0e86f6d3dc9dc4352edeea6b8e499e13e3f5dc3b964d7ca5fd411415a3498473" 96 + dependencies = [ 97 + "compression-codecs", 98 + "compression-core", 99 + "futures-core", 100 + "pin-project-lite", 101 + "tokio", 102 + ] 103 + 104 + [[package]] 105 + name = "async-lock" 106 + version = "3.4.1" 107 + source = "registry+https://github.com/rust-lang/crates.io-index" 108 + checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" 109 + dependencies = [ 110 + "event-listener", 111 + "event-listener-strategy", 112 + "pin-project-lite", 113 + ] 114 + 115 + [[package]] 116 + name = "atomic-waker" 117 + version = "1.1.2" 118 + source = "registry+https://github.com/rust-lang/crates.io-index" 119 + checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 120 + 121 + [[package]] 122 + name = "atrium-api" 123 + version = "0.25.6" 124 + source = "registry+https://github.com/rust-lang/crates.io-index" 125 + checksum = "ef9d5e9352fd27d99383ae1db2b6a6aa239e683a7e750e8d73a73996d82b1fd2" 126 + dependencies = [ 127 + "atrium-common", 128 + "atrium-xrpc", 129 + "chrono", 130 + "http", 131 + "ipld-core", 132 + "langtag", 133 + "regex", 134 + "serde", 135 + "serde_bytes", 136 + "serde_json", 137 + "thiserror 1.0.69", 138 + "tokio", 139 + "trait-variant", 140 + ] 141 + 142 + [[package]] 143 + name = "atrium-common" 144 + version = "0.1.2" 145 + source = "registry+https://github.com/rust-lang/crates.io-index" 146 + checksum = "9ed5610654043faa396a5a15afac0ac646d76aebe45aebd7cef4f8b96b0ab7f4" 147 + dependencies = [ 148 + "dashmap", 149 + "lru", 150 + "moka", 151 + "thiserror 1.0.69", 152 + "tokio", 153 + "trait-variant", 154 + "web-time", 155 + ] 156 + 157 + [[package]] 158 + name = "atrium-identity" 159 + version = "0.1.7" 160 + source = "registry+https://github.com/rust-lang/crates.io-index" 161 + checksum = "4d3a56cd2bb695308cb078be80a46a7a2caf79203eda27803f13ee6a38b98378" 162 + dependencies = [ 163 + "atrium-api", 164 + "atrium-common", 165 + "atrium-xrpc", 166 + "serde", 167 + "serde_html_form", 168 + "serde_json", 169 + "thiserror 1.0.69", 170 + "trait-variant", 171 + ] 172 + 173 + [[package]] 174 + name = "atrium-xrpc" 175 + version = "0.12.3" 176 + source = "registry+https://github.com/rust-lang/crates.io-index" 177 + checksum = "0216ad50ce34e9ff982e171c3659e65dedaa2ed5ac2994524debdc9a9647ffa8" 178 + dependencies = [ 179 + "http", 180 + "serde", 181 + "serde_html_form", 182 + "serde_json", 183 + "thiserror 1.0.69", 184 + "trait-variant", 185 + ] 186 + 187 + [[package]] 188 + name = "atrium-xrpc-client" 189 + version = "0.5.14" 190 + source = "registry+https://github.com/rust-lang/crates.io-index" 191 + checksum = "e099e5171f79faef52364ef0657a4cab086a71b384a779a29597a91b780de0d5" 192 + dependencies = [ 193 + "atrium-xrpc", 194 + "reqwest", 195 + ] 196 + 197 + [[package]] 198 + name = "autocfg" 199 + version = "1.5.0" 200 + source = "registry+https://github.com/rust-lang/crates.io-index" 201 + checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" 202 + 203 + [[package]] 204 + name = "base-x" 205 + version = "0.2.11" 206 + source = "registry+https://github.com/rust-lang/crates.io-index" 207 + checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" 208 + 209 + [[package]] 210 + name = "base256emoji" 211 + version = "1.0.2" 212 + source = "registry+https://github.com/rust-lang/crates.io-index" 213 + checksum = "b5e9430d9a245a77c92176e649af6e275f20839a48389859d1661e9a128d077c" 214 + dependencies = [ 215 + "const-str", 216 + "match-lookup", 217 + ] 218 + 219 + [[package]] 220 + name = "base64" 221 + version = "0.22.1" 222 + source = "registry+https://github.com/rust-lang/crates.io-index" 223 + checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 224 + 225 + [[package]] 226 + name = "bitflags" 227 + version = "1.3.2" 228 + source = "registry+https://github.com/rust-lang/crates.io-index" 229 + checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 230 + 231 + [[package]] 232 + name = "bitflags" 233 + version = "2.10.0" 234 + source = "registry+https://github.com/rust-lang/crates.io-index" 235 + checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" 236 + 237 + [[package]] 238 + name = "block-buffer" 239 + version = "0.10.4" 240 + source = "registry+https://github.com/rust-lang/crates.io-index" 241 + checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 242 + dependencies = [ 243 + "generic-array", 244 + ] 245 + 246 + [[package]] 247 + name = "bsky-sdk" 248 + version = "0.1.22" 249 + source = "registry+https://github.com/rust-lang/crates.io-index" 250 + checksum = "f9a9fc66ac805931a0e9fa01c0ca7bfe0e6dad7a144516e0d1f547f3b4e5be2c" 251 + dependencies = [ 252 + "anyhow", 253 + "atrium-api", 254 + "atrium-xrpc-client", 255 + "chrono", 256 + "psl", 257 + "regex", 258 + "serde", 259 + "serde_json", 260 + "thiserror 1.0.69", 261 + "trait-variant", 262 + "unicode-segmentation", 263 + ] 264 + 265 + [[package]] 266 + name = "bumpalo" 267 + version = "3.19.0" 268 + source = "registry+https://github.com/rust-lang/crates.io-index" 269 + checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" 270 + 271 + [[package]] 272 + name = "byteorder" 273 + version = "1.5.0" 274 + source = "registry+https://github.com/rust-lang/crates.io-index" 275 + checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 276 + 277 + [[package]] 278 + name = "bytes" 279 + version = "1.11.0" 280 + source = "registry+https://github.com/rust-lang/crates.io-index" 281 + checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" 282 + 283 + [[package]] 284 + name = "cc" 285 + version = "1.2.43" 286 + source = "registry+https://github.com/rust-lang/crates.io-index" 287 + checksum = "739eb0f94557554b3ca9a86d2d37bebd49c5e6d0c1d2bda35ba5bdac830befc2" 288 + dependencies = [ 289 + "find-msvc-tools", 290 + "shlex", 291 + ] 292 + 293 + [[package]] 294 + name = "cfg-if" 295 + version = "1.0.4" 296 + source = "registry+https://github.com/rust-lang/crates.io-index" 297 + checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" 298 + 299 + [[package]] 300 + name = "chrono" 301 + version = "0.4.42" 302 + source = "registry+https://github.com/rust-lang/crates.io-index" 303 + checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" 304 + dependencies = [ 305 + "iana-time-zone", 306 + "js-sys", 307 + "num-traits", 308 + "serde", 309 + "wasm-bindgen", 310 + "windows-link", 311 + ] 312 + 313 + [[package]] 314 + name = "cid" 315 + version = "0.11.1" 316 + source = "registry+https://github.com/rust-lang/crates.io-index" 317 + checksum = "3147d8272e8fa0ccd29ce51194dd98f79ddfb8191ba9e3409884e751798acf3a" 318 + dependencies = [ 319 + "core2", 320 + "multibase", 321 + "multihash", 322 + "serde", 323 + "serde_bytes", 324 + "unsigned-varint", 325 + ] 326 + 327 + [[package]] 328 + name = "clap" 329 + version = "4.5.53" 330 + source = "registry+https://github.com/rust-lang/crates.io-index" 331 + checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" 332 + dependencies = [ 333 + "clap_builder", 334 + "clap_derive", 335 + ] 336 + 337 + [[package]] 338 + name = "clap_builder" 339 + version = "4.5.53" 340 + source = "registry+https://github.com/rust-lang/crates.io-index" 341 + checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" 342 + dependencies = [ 343 + "anstream", 344 + "anstyle", 345 + "clap_lex", 346 + "strsim", 347 + ] 348 + 349 + [[package]] 350 + name = "clap_derive" 351 + version = "4.5.49" 352 + source = "registry+https://github.com/rust-lang/crates.io-index" 353 + checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" 354 + dependencies = [ 355 + "heck", 356 + "proc-macro2", 357 + "quote", 358 + "syn 2.0.111", 359 + ] 360 + 361 + [[package]] 362 + name = "clap_lex" 363 + version = "0.7.6" 364 + source = "registry+https://github.com/rust-lang/crates.io-index" 365 + checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" 366 + 367 + [[package]] 368 + name = "colorchoice" 369 + version = "1.0.4" 370 + source = "registry+https://github.com/rust-lang/crates.io-index" 371 + checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" 372 + 373 + [[package]] 374 + name = "compression-codecs" 375 + version = "0.4.33" 376 + source = "registry+https://github.com/rust-lang/crates.io-index" 377 + checksum = "302266479cb963552d11bd042013a58ef1adc56768016c8b82b4199488f2d4ad" 378 + dependencies = [ 379 + "compression-core", 380 + "flate2", 381 + "memchr", 382 + ] 383 + 384 + [[package]] 385 + name = "compression-core" 386 + version = "0.4.31" 387 + source = "registry+https://github.com/rust-lang/crates.io-index" 388 + checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d" 389 + 390 + [[package]] 391 + name = "concurrent-queue" 392 + version = "2.5.0" 393 + source = "registry+https://github.com/rust-lang/crates.io-index" 394 + checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" 395 + dependencies = [ 396 + "crossbeam-utils", 397 + ] 398 + 399 + [[package]] 400 + name = "const-str" 401 + version = "0.4.3" 402 + source = "registry+https://github.com/rust-lang/crates.io-index" 403 + checksum = "2f421161cb492475f1661ddc9815a745a1c894592070661180fdec3d4872e9c3" 404 + 405 + [[package]] 406 + name = "core-foundation" 407 + version = "0.9.4" 408 + source = "registry+https://github.com/rust-lang/crates.io-index" 409 + checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 410 + dependencies = [ 411 + "core-foundation-sys", 412 + "libc", 413 + ] 414 + 415 + [[package]] 416 + name = "core-foundation-sys" 417 + version = "0.8.7" 418 + source = "registry+https://github.com/rust-lang/crates.io-index" 419 + checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 420 + 421 + [[package]] 422 + name = "core2" 423 + version = "0.4.0" 424 + source = "registry+https://github.com/rust-lang/crates.io-index" 425 + checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" 426 + dependencies = [ 427 + "memchr", 428 + ] 429 + 430 + [[package]] 431 + name = "cpufeatures" 432 + version = "0.2.17" 433 + source = "registry+https://github.com/rust-lang/crates.io-index" 434 + checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" 435 + dependencies = [ 436 + "libc", 437 + ] 438 + 439 + [[package]] 440 + name = "crc32fast" 441 + version = "1.5.0" 442 + source = "registry+https://github.com/rust-lang/crates.io-index" 443 + checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" 444 + dependencies = [ 445 + "cfg-if", 446 + ] 447 + 448 + [[package]] 449 + name = "crossbeam-channel" 450 + version = "0.5.15" 451 + source = "registry+https://github.com/rust-lang/crates.io-index" 452 + checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" 453 + dependencies = [ 454 + "crossbeam-utils", 455 + ] 456 + 457 + [[package]] 458 + name = "crossbeam-epoch" 459 + version = "0.9.18" 460 + source = "registry+https://github.com/rust-lang/crates.io-index" 461 + checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" 462 + dependencies = [ 463 + "crossbeam-utils", 464 + ] 465 + 466 + [[package]] 467 + name = "crossbeam-utils" 468 + version = "0.8.21" 469 + source = "registry+https://github.com/rust-lang/crates.io-index" 470 + checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" 471 + 472 + [[package]] 473 + name = "crypto-common" 474 + version = "0.1.7" 475 + source = "registry+https://github.com/rust-lang/crates.io-index" 476 + checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" 477 + dependencies = [ 478 + "generic-array", 479 + "typenum", 480 + ] 481 + 482 + [[package]] 483 + name = "dashmap" 484 + version = "6.1.0" 485 + source = "registry+https://github.com/rust-lang/crates.io-index" 486 + checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" 487 + dependencies = [ 488 + "cfg-if", 489 + "crossbeam-utils", 490 + "hashbrown 0.14.5", 491 + "lock_api", 492 + "once_cell", 493 + "parking_lot_core 0.9.12", 494 + ] 495 + 496 + [[package]] 497 + name = "data-encoding" 498 + version = "2.9.0" 499 + source = "registry+https://github.com/rust-lang/crates.io-index" 500 + checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" 501 + 502 + [[package]] 503 + name = "data-encoding-macro" 504 + version = "0.1.18" 505 + source = "registry+https://github.com/rust-lang/crates.io-index" 506 + checksum = "47ce6c96ea0102f01122a185683611bd5ac8d99e62bc59dd12e6bda344ee673d" 507 + dependencies = [ 508 + "data-encoding", 509 + "data-encoding-macro-internal", 510 + ] 511 + 512 + [[package]] 513 + name = "data-encoding-macro-internal" 514 + version = "0.1.16" 515 + source = "registry+https://github.com/rust-lang/crates.io-index" 516 + checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976" 517 + dependencies = [ 518 + "data-encoding", 519 + "syn 2.0.111", 520 + ] 521 + 522 + [[package]] 523 + name = "digest" 524 + version = "0.10.7" 525 + source = "registry+https://github.com/rust-lang/crates.io-index" 526 + checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 527 + dependencies = [ 528 + "block-buffer", 529 + "crypto-common", 530 + ] 531 + 532 + [[package]] 533 + name = "displaydoc" 534 + version = "0.2.5" 535 + source = "registry+https://github.com/rust-lang/crates.io-index" 536 + checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" 537 + dependencies = [ 538 + "proc-macro2", 539 + "quote", 540 + "syn 2.0.111", 541 + ] 542 + 543 + [[package]] 544 + name = "env_filter" 545 + version = "0.1.4" 546 + source = "registry+https://github.com/rust-lang/crates.io-index" 547 + checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" 548 + dependencies = [ 549 + "log", 550 + "regex", 551 + ] 552 + 553 + [[package]] 554 + name = "env_logger" 555 + version = "0.11.8" 556 + source = "registry+https://github.com/rust-lang/crates.io-index" 557 + checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" 558 + dependencies = [ 559 + "anstream", 560 + "anstyle", 561 + "env_filter", 562 + "jiff", 563 + "log", 564 + ] 565 + 566 + [[package]] 567 + name = "equivalent" 568 + version = "1.0.2" 569 + source = "registry+https://github.com/rust-lang/crates.io-index" 570 + checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 571 + 572 + [[package]] 573 + name = "errno" 574 + version = "0.3.14" 575 + source = "registry+https://github.com/rust-lang/crates.io-index" 576 + checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" 577 + dependencies = [ 578 + "libc", 579 + "windows-sys 0.61.2", 580 + ] 581 + 582 + [[package]] 583 + name = "event-listener" 584 + version = "5.4.1" 585 + source = "registry+https://github.com/rust-lang/crates.io-index" 586 + checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" 587 + dependencies = [ 588 + "concurrent-queue", 589 + "parking", 590 + "pin-project-lite", 591 + ] 592 + 593 + [[package]] 594 + name = "event-listener-strategy" 595 + version = "0.5.4" 596 + source = "registry+https://github.com/rust-lang/crates.io-index" 597 + checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" 598 + dependencies = [ 599 + "event-listener", 600 + "pin-project-lite", 601 + ] 602 + 603 + [[package]] 604 + name = "facet-core" 605 + version = "0.31.4" 606 + source = "registry+https://github.com/rust-lang/crates.io-index" 607 + checksum = "aaf9e8a182bc18995dce44bada25f2acb522f85570b1f878b1467db325ce1f94" 608 + dependencies = [ 609 + "bitflags 2.10.0", 610 + "impls", 611 + ] 612 + 613 + [[package]] 614 + name = "facet-pretty" 615 + version = "0.31.0" 616 + source = "registry+https://github.com/rust-lang/crates.io-index" 617 + checksum = "6c9c5117c29f789a737f6d5d92fb326ddec0a12d1ac2a165dad0ccef38aca609" 618 + dependencies = [ 619 + "facet-core", 620 + "facet-reflect", 621 + ] 622 + 623 + [[package]] 624 + name = "facet-reflect" 625 + version = "0.31.4" 626 + source = "registry+https://github.com/rust-lang/crates.io-index" 627 + checksum = "e1cd07b58d1e7df4c0601c7da439f50bed3b06518df8b2ece92188f79892aca9" 628 + dependencies = [ 629 + "bitflags 2.10.0", 630 + "facet-core", 631 + ] 632 + 633 + [[package]] 634 + name = "fastrand" 635 + version = "2.3.0" 636 + source = "registry+https://github.com/rust-lang/crates.io-index" 637 + checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" 638 + 639 + [[package]] 640 + name = "find-msvc-tools" 641 + version = "0.1.4" 642 + source = "registry+https://github.com/rust-lang/crates.io-index" 643 + checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" 644 + 645 + [[package]] 646 + name = "flate2" 647 + version = "1.1.5" 648 + source = "registry+https://github.com/rust-lang/crates.io-index" 649 + checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" 650 + dependencies = [ 651 + "crc32fast", 652 + "miniz_oxide", 653 + ] 654 + 655 + [[package]] 656 + name = "fnv" 657 + version = "1.0.7" 658 + source = "registry+https://github.com/rust-lang/crates.io-index" 659 + checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 660 + 661 + [[package]] 662 + name = "foldhash" 663 + version = "0.1.5" 664 + source = "registry+https://github.com/rust-lang/crates.io-index" 665 + checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" 666 + 667 + [[package]] 668 + name = "foreign-types" 669 + version = "0.3.2" 670 + source = "registry+https://github.com/rust-lang/crates.io-index" 671 + checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 672 + dependencies = [ 673 + "foreign-types-shared", 674 + ] 675 + 676 + [[package]] 677 + name = "foreign-types-shared" 678 + version = "0.1.1" 679 + source = "registry+https://github.com/rust-lang/crates.io-index" 680 + checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 681 + 682 + [[package]] 683 + name = "form_urlencoded" 684 + version = "1.2.2" 685 + source = "registry+https://github.com/rust-lang/crates.io-index" 686 + checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" 687 + dependencies = [ 688 + "percent-encoding", 689 + ] 690 + 691 + [[package]] 692 + name = "fs2" 693 + version = "0.4.3" 694 + source = "registry+https://github.com/rust-lang/crates.io-index" 695 + checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" 696 + dependencies = [ 697 + "libc", 698 + "winapi", 699 + ] 700 + 701 + [[package]] 702 + name = "futures-channel" 703 + version = "0.3.31" 704 + source = "registry+https://github.com/rust-lang/crates.io-index" 705 + checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 706 + dependencies = [ 707 + "futures-core", 708 + ] 709 + 710 + [[package]] 711 + name = "futures-core" 712 + version = "0.3.31" 713 + source = "registry+https://github.com/rust-lang/crates.io-index" 714 + checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 715 + 716 + [[package]] 717 + name = "futures-macro" 718 + version = "0.3.31" 719 + source = "registry+https://github.com/rust-lang/crates.io-index" 720 + checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" 721 + dependencies = [ 722 + "proc-macro2", 723 + "quote", 724 + "syn 2.0.111", 725 + ] 726 + 727 + [[package]] 728 + name = "futures-sink" 729 + version = "0.3.31" 730 + source = "registry+https://github.com/rust-lang/crates.io-index" 731 + checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 732 + 733 + [[package]] 734 + name = "futures-task" 735 + version = "0.3.31" 736 + source = "registry+https://github.com/rust-lang/crates.io-index" 737 + checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 738 + 739 + [[package]] 740 + name = "futures-util" 741 + version = "0.3.31" 742 + source = "registry+https://github.com/rust-lang/crates.io-index" 743 + checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 744 + dependencies = [ 745 + "futures-core", 746 + "futures-macro", 747 + "futures-task", 748 + "pin-project-lite", 749 + "pin-utils", 750 + "slab", 751 + ] 752 + 753 + [[package]] 754 + name = "fxhash" 755 + version = "0.2.1" 756 + source = "registry+https://github.com/rust-lang/crates.io-index" 757 + checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" 758 + dependencies = [ 759 + "byteorder", 760 + ] 761 + 762 + [[package]] 763 + name = "generic-array" 764 + version = "0.14.7" 765 + source = "registry+https://github.com/rust-lang/crates.io-index" 766 + checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 767 + dependencies = [ 768 + "typenum", 769 + "version_check", 770 + ] 771 + 772 + [[package]] 773 + name = "getrandom" 774 + version = "0.2.16" 775 + source = "registry+https://github.com/rust-lang/crates.io-index" 776 + checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" 777 + dependencies = [ 778 + "cfg-if", 779 + "libc", 780 + "wasi", 781 + ] 782 + 783 + [[package]] 784 + name = "getrandom" 785 + version = "0.3.4" 786 + source = "registry+https://github.com/rust-lang/crates.io-index" 787 + checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" 788 + dependencies = [ 789 + "cfg-if", 790 + "libc", 791 + "r-efi", 792 + "wasip2", 793 + ] 794 + 795 + [[package]] 796 + name = "hashbrown" 797 + version = "0.14.5" 798 + source = "registry+https://github.com/rust-lang/crates.io-index" 799 + checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 800 + 801 + [[package]] 802 + name = "hashbrown" 803 + version = "0.15.5" 804 + source = "registry+https://github.com/rust-lang/crates.io-index" 805 + checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" 806 + dependencies = [ 807 + "allocator-api2", 808 + "equivalent", 809 + "foldhash", 810 + ] 811 + 812 + [[package]] 813 + name = "hashbrown" 814 + version = "0.16.1" 815 + source = "registry+https://github.com/rust-lang/crates.io-index" 816 + checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" 817 + 818 + [[package]] 819 + name = "heck" 820 + version = "0.5.0" 821 + source = "registry+https://github.com/rust-lang/crates.io-index" 822 + checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 823 + 824 + [[package]] 825 + name = "http" 826 + version = "1.3.1" 827 + source = "registry+https://github.com/rust-lang/crates.io-index" 828 + checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" 829 + dependencies = [ 830 + "bytes", 831 + "fnv", 832 + "itoa", 833 + ] 834 + 835 + [[package]] 836 + name = "http-body" 837 + version = "1.0.1" 838 + source = "registry+https://github.com/rust-lang/crates.io-index" 839 + checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 840 + dependencies = [ 841 + "bytes", 842 + "http", 843 + ] 844 + 845 + [[package]] 846 + name = "http-body-util" 847 + version = "0.1.3" 848 + source = "registry+https://github.com/rust-lang/crates.io-index" 849 + checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" 850 + dependencies = [ 851 + "bytes", 852 + "futures-core", 853 + "http", 854 + "http-body", 855 + "pin-project-lite", 856 + ] 857 + 858 + [[package]] 859 + name = "httparse" 860 + version = "1.10.1" 861 + source = "registry+https://github.com/rust-lang/crates.io-index" 862 + checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" 863 + 864 + [[package]] 865 + name = "hyper" 866 + version = "1.8.1" 867 + source = "registry+https://github.com/rust-lang/crates.io-index" 868 + checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" 869 + dependencies = [ 870 + "atomic-waker", 871 + "bytes", 872 + "futures-channel", 873 + "futures-core", 874 + "http", 875 + "http-body", 876 + "httparse", 877 + "itoa", 878 + "pin-project-lite", 879 + "pin-utils", 880 + "smallvec", 881 + "tokio", 882 + "want", 883 + ] 884 + 885 + [[package]] 886 + name = "hyper-tls" 887 + version = "0.6.0" 888 + source = "registry+https://github.com/rust-lang/crates.io-index" 889 + checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" 890 + dependencies = [ 891 + "bytes", 892 + "http-body-util", 893 + "hyper", 894 + "hyper-util", 895 + "native-tls", 896 + "tokio", 897 + "tokio-native-tls", 898 + "tower-service", 899 + ] 900 + 901 + [[package]] 902 + name = "hyper-util" 903 + version = "0.1.18" 904 + source = "registry+https://github.com/rust-lang/crates.io-index" 905 + checksum = "52e9a2a24dc5c6821e71a7030e1e14b7b632acac55c40e9d2e082c621261bb56" 906 + dependencies = [ 907 + "base64", 908 + "bytes", 909 + "futures-channel", 910 + "futures-core", 911 + "futures-util", 912 + "http", 913 + "http-body", 914 + "hyper", 915 + "ipnet", 916 + "libc", 917 + "percent-encoding", 918 + "pin-project-lite", 919 + "socket2", 920 + "tokio", 921 + "tower-service", 922 + "tracing", 923 + ] 924 + 925 + [[package]] 926 + name = "iana-time-zone" 927 + version = "0.1.64" 928 + source = "registry+https://github.com/rust-lang/crates.io-index" 929 + checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" 930 + dependencies = [ 931 + "android_system_properties", 932 + "core-foundation-sys", 933 + "iana-time-zone-haiku", 934 + "js-sys", 935 + "log", 936 + "wasm-bindgen", 937 + "windows-core", 938 + ] 939 + 940 + [[package]] 941 + name = "iana-time-zone-haiku" 942 + version = "0.1.2" 943 + source = "registry+https://github.com/rust-lang/crates.io-index" 944 + checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" 945 + dependencies = [ 946 + "cc", 947 + ] 948 + 949 + [[package]] 950 + name = "icu_collections" 951 + version = "2.1.1" 952 + source = "registry+https://github.com/rust-lang/crates.io-index" 953 + checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" 954 + dependencies = [ 955 + "displaydoc", 956 + "potential_utf", 957 + "yoke", 958 + "zerofrom", 959 + "zerovec", 960 + ] 961 + 962 + [[package]] 963 + name = "icu_locale_core" 964 + version = "2.1.1" 965 + source = "registry+https://github.com/rust-lang/crates.io-index" 966 + checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" 967 + dependencies = [ 968 + "displaydoc", 969 + "litemap", 970 + "tinystr", 971 + "writeable", 972 + "zerovec", 973 + ] 974 + 975 + [[package]] 976 + name = "icu_normalizer" 977 + version = "2.1.1" 978 + source = "registry+https://github.com/rust-lang/crates.io-index" 979 + checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" 980 + dependencies = [ 981 + "icu_collections", 982 + "icu_normalizer_data", 983 + "icu_properties", 984 + "icu_provider", 985 + "smallvec", 986 + "zerovec", 987 + ] 988 + 989 + [[package]] 990 + name = "icu_normalizer_data" 991 + version = "2.1.1" 992 + source = "registry+https://github.com/rust-lang/crates.io-index" 993 + checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" 994 + 995 + [[package]] 996 + name = "icu_properties" 997 + version = "2.1.1" 998 + source = "registry+https://github.com/rust-lang/crates.io-index" 999 + checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" 1000 + dependencies = [ 1001 + "icu_collections", 1002 + "icu_locale_core", 1003 + "icu_properties_data", 1004 + "icu_provider", 1005 + "zerotrie", 1006 + "zerovec", 1007 + ] 1008 + 1009 + [[package]] 1010 + name = "icu_properties_data" 1011 + version = "2.1.1" 1012 + source = "registry+https://github.com/rust-lang/crates.io-index" 1013 + checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" 1014 + 1015 + [[package]] 1016 + name = "icu_provider" 1017 + version = "2.1.1" 1018 + source = "registry+https://github.com/rust-lang/crates.io-index" 1019 + checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" 1020 + dependencies = [ 1021 + "displaydoc", 1022 + "icu_locale_core", 1023 + "writeable", 1024 + "yoke", 1025 + "zerofrom", 1026 + "zerotrie", 1027 + "zerovec", 1028 + ] 1029 + 1030 + [[package]] 1031 + name = "idna" 1032 + version = "1.1.0" 1033 + source = "registry+https://github.com/rust-lang/crates.io-index" 1034 + checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" 1035 + dependencies = [ 1036 + "idna_adapter", 1037 + "smallvec", 1038 + "utf8_iter", 1039 + ] 1040 + 1041 + [[package]] 1042 + name = "idna_adapter" 1043 + version = "1.2.1" 1044 + source = "registry+https://github.com/rust-lang/crates.io-index" 1045 + checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" 1046 + dependencies = [ 1047 + "icu_normalizer", 1048 + "icu_properties", 1049 + ] 1050 + 1051 + [[package]] 1052 + name = "impls" 1053 + version = "1.0.3" 1054 + source = "registry+https://github.com/rust-lang/crates.io-index" 1055 + checksum = "7a46645bbd70538861a90d0f26c31537cdf1e44aae99a794fb75a664b70951bc" 1056 + 1057 + [[package]] 1058 + name = "indexmap" 1059 + version = "2.12.1" 1060 + source = "registry+https://github.com/rust-lang/crates.io-index" 1061 + checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" 1062 + dependencies = [ 1063 + "equivalent", 1064 + "hashbrown 0.16.1", 1065 + ] 1066 + 1067 + [[package]] 1068 + name = "instant" 1069 + version = "0.1.13" 1070 + source = "registry+https://github.com/rust-lang/crates.io-index" 1071 + checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" 1072 + dependencies = [ 1073 + "cfg-if", 1074 + ] 1075 + 1076 + [[package]] 1077 + name = "ipld-core" 1078 + version = "0.4.2" 1079 + source = "registry+https://github.com/rust-lang/crates.io-index" 1080 + checksum = "104718b1cc124d92a6d01ca9c9258a7df311405debb3408c445a36452f9bf8db" 1081 + dependencies = [ 1082 + "cid", 1083 + "serde", 1084 + "serde_bytes", 1085 + ] 1086 + 1087 + [[package]] 1088 + name = "ipnet" 1089 + version = "2.11.0" 1090 + source = "registry+https://github.com/rust-lang/crates.io-index" 1091 + checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" 1092 + 1093 + [[package]] 1094 + name = "iri-string" 1095 + version = "0.7.9" 1096 + source = "registry+https://github.com/rust-lang/crates.io-index" 1097 + checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397" 1098 + dependencies = [ 1099 + "memchr", 1100 + "serde", 1101 + ] 1102 + 1103 + [[package]] 1104 + name = "is_terminal_polyfill" 1105 + version = "1.70.2" 1106 + source = "registry+https://github.com/rust-lang/crates.io-index" 1107 + checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" 1108 + 1109 + [[package]] 1110 + name = "itoa" 1111 + version = "1.0.15" 1112 + source = "registry+https://github.com/rust-lang/crates.io-index" 1113 + checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 1114 + 1115 + [[package]] 1116 + name = "jiff" 1117 + version = "0.2.16" 1118 + source = "registry+https://github.com/rust-lang/crates.io-index" 1119 + checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" 1120 + dependencies = [ 1121 + "jiff-static", 1122 + "log", 1123 + "portable-atomic", 1124 + "portable-atomic-util", 1125 + "serde_core", 1126 + ] 1127 + 1128 + [[package]] 1129 + name = "jiff-static" 1130 + version = "0.2.16" 1131 + source = "registry+https://github.com/rust-lang/crates.io-index" 1132 + checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" 1133 + dependencies = [ 1134 + "proc-macro2", 1135 + "quote", 1136 + "syn 2.0.111", 1137 + ] 1138 + 1139 + [[package]] 1140 + name = "js-sys" 1141 + version = "0.3.82" 1142 + source = "registry+https://github.com/rust-lang/crates.io-index" 1143 + checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" 1144 + dependencies = [ 1145 + "once_cell", 1146 + "wasm-bindgen", 1147 + ] 1148 + 1149 + [[package]] 1150 + name = "langtag" 1151 + version = "0.3.4" 1152 + source = "registry+https://github.com/rust-lang/crates.io-index" 1153 + checksum = "ed60c85f254d6ae8450cec15eedd921efbc4d1bdf6fcf6202b9a58b403f6f805" 1154 + dependencies = [ 1155 + "serde", 1156 + ] 1157 + 1158 + [[package]] 1159 + name = "leaflet-notifs" 1160 + version = "0.1.0" 1161 + dependencies = [ 1162 + "anyhow", 1163 + "atrium-api", 1164 + "atrium-common", 1165 + "atrium-identity", 1166 + "atrium-xrpc", 1167 + "atrium-xrpc-client", 1168 + "bsky-sdk", 1169 + "clap", 1170 + "env_logger", 1171 + "facet-pretty", 1172 + "log", 1173 + "serde", 1174 + "serde_json", 1175 + "sled", 1176 + "tempfile", 1177 + "tokio", 1178 + "tungstenite", 1179 + "url", 1180 + ] 1181 + 1182 + [[package]] 1183 + name = "libc" 1184 + version = "0.2.177" 1185 + source = "registry+https://github.com/rust-lang/crates.io-index" 1186 + checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" 1187 + 1188 + [[package]] 1189 + name = "linux-raw-sys" 1190 + version = "0.11.0" 1191 + source = "registry+https://github.com/rust-lang/crates.io-index" 1192 + checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" 1193 + 1194 + [[package]] 1195 + name = "litemap" 1196 + version = "0.8.1" 1197 + source = "registry+https://github.com/rust-lang/crates.io-index" 1198 + checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" 1199 + 1200 + [[package]] 1201 + name = "lock_api" 1202 + version = "0.4.14" 1203 + source = "registry+https://github.com/rust-lang/crates.io-index" 1204 + checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" 1205 + dependencies = [ 1206 + "scopeguard", 1207 + ] 1208 + 1209 + [[package]] 1210 + name = "log" 1211 + version = "0.4.28" 1212 + source = "registry+https://github.com/rust-lang/crates.io-index" 1213 + checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" 1214 + 1215 + [[package]] 1216 + name = "lru" 1217 + version = "0.12.5" 1218 + source = "registry+https://github.com/rust-lang/crates.io-index" 1219 + checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" 1220 + dependencies = [ 1221 + "hashbrown 0.15.5", 1222 + ] 1223 + 1224 + [[package]] 1225 + name = "match-lookup" 1226 + version = "0.1.1" 1227 + source = "registry+https://github.com/rust-lang/crates.io-index" 1228 + checksum = "1265724d8cb29dbbc2b0f06fffb8bf1a8c0cf73a78eede9ba73a4a66c52a981e" 1229 + dependencies = [ 1230 + "proc-macro2", 1231 + "quote", 1232 + "syn 1.0.109", 1233 + ] 1234 + 1235 + [[package]] 1236 + name = "memchr" 1237 + version = "2.7.6" 1238 + source = "registry+https://github.com/rust-lang/crates.io-index" 1239 + checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" 1240 + 1241 + [[package]] 1242 + name = "miniz_oxide" 1243 + version = "0.8.9" 1244 + source = "registry+https://github.com/rust-lang/crates.io-index" 1245 + checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" 1246 + dependencies = [ 1247 + "adler2", 1248 + "simd-adler32", 1249 + ] 1250 + 1251 + [[package]] 1252 + name = "mio" 1253 + version = "1.1.0" 1254 + source = "registry+https://github.com/rust-lang/crates.io-index" 1255 + checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" 1256 + dependencies = [ 1257 + "libc", 1258 + "wasi", 1259 + "windows-sys 0.61.2", 1260 + ] 1261 + 1262 + [[package]] 1263 + name = "moka" 1264 + version = "0.12.11" 1265 + source = "registry+https://github.com/rust-lang/crates.io-index" 1266 + checksum = "8261cd88c312e0004c1d51baad2980c66528dfdb2bee62003e643a4d8f86b077" 1267 + dependencies = [ 1268 + "async-lock", 1269 + "crossbeam-channel", 1270 + "crossbeam-epoch", 1271 + "crossbeam-utils", 1272 + "equivalent", 1273 + "event-listener", 1274 + "futures-util", 1275 + "parking_lot 0.12.5", 1276 + "portable-atomic", 1277 + "rustc_version", 1278 + "smallvec", 1279 + "tagptr", 1280 + "uuid", 1281 + ] 1282 + 1283 + [[package]] 1284 + name = "multibase" 1285 + version = "0.9.2" 1286 + source = "registry+https://github.com/rust-lang/crates.io-index" 1287 + checksum = "8694bb4835f452b0e3bb06dbebb1d6fc5385b6ca1caf2e55fd165c042390ec77" 1288 + dependencies = [ 1289 + "base-x", 1290 + "base256emoji", 1291 + "data-encoding", 1292 + "data-encoding-macro", 1293 + ] 1294 + 1295 + [[package]] 1296 + name = "multihash" 1297 + version = "0.19.3" 1298 + source = "registry+https://github.com/rust-lang/crates.io-index" 1299 + checksum = "6b430e7953c29dd6a09afc29ff0bb69c6e306329ee6794700aee27b76a1aea8d" 1300 + dependencies = [ 1301 + "core2", 1302 + "serde", 1303 + "unsigned-varint", 1304 + ] 1305 + 1306 + [[package]] 1307 + name = "native-tls" 1308 + version = "0.2.14" 1309 + source = "registry+https://github.com/rust-lang/crates.io-index" 1310 + checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" 1311 + dependencies = [ 1312 + "libc", 1313 + "log", 1314 + "openssl", 1315 + "openssl-probe", 1316 + "openssl-sys", 1317 + "schannel", 1318 + "security-framework", 1319 + "security-framework-sys", 1320 + "tempfile", 1321 + ] 1322 + 1323 + [[package]] 1324 + name = "num-traits" 1325 + version = "0.2.19" 1326 + source = "registry+https://github.com/rust-lang/crates.io-index" 1327 + checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 1328 + dependencies = [ 1329 + "autocfg", 1330 + ] 1331 + 1332 + [[package]] 1333 + name = "once_cell" 1334 + version = "1.21.3" 1335 + source = "registry+https://github.com/rust-lang/crates.io-index" 1336 + checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 1337 + 1338 + [[package]] 1339 + name = "once_cell_polyfill" 1340 + version = "1.70.2" 1341 + source = "registry+https://github.com/rust-lang/crates.io-index" 1342 + checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" 1343 + 1344 + [[package]] 1345 + name = "openssl" 1346 + version = "0.10.74" 1347 + source = "registry+https://github.com/rust-lang/crates.io-index" 1348 + checksum = "24ad14dd45412269e1a30f52ad8f0664f0f4f4a89ee8fe28c3b3527021ebb654" 1349 + dependencies = [ 1350 + "bitflags 2.10.0", 1351 + "cfg-if", 1352 + "foreign-types", 1353 + "libc", 1354 + "once_cell", 1355 + "openssl-macros", 1356 + "openssl-sys", 1357 + ] 1358 + 1359 + [[package]] 1360 + name = "openssl-macros" 1361 + version = "0.1.1" 1362 + source = "registry+https://github.com/rust-lang/crates.io-index" 1363 + checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 1364 + dependencies = [ 1365 + "proc-macro2", 1366 + "quote", 1367 + "syn 2.0.111", 1368 + ] 1369 + 1370 + [[package]] 1371 + name = "openssl-probe" 1372 + version = "0.1.6" 1373 + source = "registry+https://github.com/rust-lang/crates.io-index" 1374 + checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" 1375 + 1376 + [[package]] 1377 + name = "openssl-sys" 1378 + version = "0.9.110" 1379 + source = "registry+https://github.com/rust-lang/crates.io-index" 1380 + checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2" 1381 + dependencies = [ 1382 + "cc", 1383 + "libc", 1384 + "pkg-config", 1385 + "vcpkg", 1386 + ] 1387 + 1388 + [[package]] 1389 + name = "parking" 1390 + version = "2.2.1" 1391 + source = "registry+https://github.com/rust-lang/crates.io-index" 1392 + checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" 1393 + 1394 + [[package]] 1395 + name = "parking_lot" 1396 + version = "0.11.2" 1397 + source = "registry+https://github.com/rust-lang/crates.io-index" 1398 + checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" 1399 + dependencies = [ 1400 + "instant", 1401 + "lock_api", 1402 + "parking_lot_core 0.8.6", 1403 + ] 1404 + 1405 + [[package]] 1406 + name = "parking_lot" 1407 + version = "0.12.5" 1408 + source = "registry+https://github.com/rust-lang/crates.io-index" 1409 + checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" 1410 + dependencies = [ 1411 + "lock_api", 1412 + "parking_lot_core 0.9.12", 1413 + ] 1414 + 1415 + [[package]] 1416 + name = "parking_lot_core" 1417 + version = "0.8.6" 1418 + source = "registry+https://github.com/rust-lang/crates.io-index" 1419 + checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" 1420 + dependencies = [ 1421 + "cfg-if", 1422 + "instant", 1423 + "libc", 1424 + "redox_syscall 0.2.16", 1425 + "smallvec", 1426 + "winapi", 1427 + ] 1428 + 1429 + [[package]] 1430 + name = "parking_lot_core" 1431 + version = "0.9.12" 1432 + source = "registry+https://github.com/rust-lang/crates.io-index" 1433 + checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" 1434 + dependencies = [ 1435 + "cfg-if", 1436 + "libc", 1437 + "redox_syscall 0.5.18", 1438 + "smallvec", 1439 + "windows-link", 1440 + ] 1441 + 1442 + [[package]] 1443 + name = "percent-encoding" 1444 + version = "2.3.2" 1445 + source = "registry+https://github.com/rust-lang/crates.io-index" 1446 + checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" 1447 + 1448 + [[package]] 1449 + name = "pin-project-lite" 1450 + version = "0.2.16" 1451 + source = "registry+https://github.com/rust-lang/crates.io-index" 1452 + checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 1453 + 1454 + [[package]] 1455 + name = "pin-utils" 1456 + version = "0.1.0" 1457 + source = "registry+https://github.com/rust-lang/crates.io-index" 1458 + checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1459 + 1460 + [[package]] 1461 + name = "pkg-config" 1462 + version = "0.3.32" 1463 + source = "registry+https://github.com/rust-lang/crates.io-index" 1464 + checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" 1465 + 1466 + [[package]] 1467 + name = "portable-atomic" 1468 + version = "1.11.1" 1469 + source = "registry+https://github.com/rust-lang/crates.io-index" 1470 + checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" 1471 + 1472 + [[package]] 1473 + name = "portable-atomic-util" 1474 + version = "0.2.4" 1475 + source = "registry+https://github.com/rust-lang/crates.io-index" 1476 + checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" 1477 + dependencies = [ 1478 + "portable-atomic", 1479 + ] 1480 + 1481 + [[package]] 1482 + name = "potential_utf" 1483 + version = "0.1.4" 1484 + source = "registry+https://github.com/rust-lang/crates.io-index" 1485 + checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" 1486 + dependencies = [ 1487 + "zerovec", 1488 + ] 1489 + 1490 + [[package]] 1491 + name = "ppv-lite86" 1492 + version = "0.2.21" 1493 + source = "registry+https://github.com/rust-lang/crates.io-index" 1494 + checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" 1495 + dependencies = [ 1496 + "zerocopy", 1497 + ] 1498 + 1499 + [[package]] 1500 + name = "proc-macro2" 1501 + version = "1.0.103" 1502 + source = "registry+https://github.com/rust-lang/crates.io-index" 1503 + checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" 1504 + dependencies = [ 1505 + "unicode-ident", 1506 + ] 1507 + 1508 + [[package]] 1509 + name = "psl" 1510 + version = "2.1.163" 1511 + source = "registry+https://github.com/rust-lang/crates.io-index" 1512 + checksum = "0400437d6f59322214cfd590c23e8e8f69960deca366a95d40d9a9560009a7f2" 1513 + dependencies = [ 1514 + "psl-types", 1515 + ] 1516 + 1517 + [[package]] 1518 + name = "psl-types" 1519 + version = "2.0.11" 1520 + source = "registry+https://github.com/rust-lang/crates.io-index" 1521 + checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" 1522 + 1523 + [[package]] 1524 + name = "quote" 1525 + version = "1.0.42" 1526 + source = "registry+https://github.com/rust-lang/crates.io-index" 1527 + checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" 1528 + dependencies = [ 1529 + "proc-macro2", 1530 + ] 1531 + 1532 + [[package]] 1533 + name = "r-efi" 1534 + version = "5.3.0" 1535 + source = "registry+https://github.com/rust-lang/crates.io-index" 1536 + checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" 1537 + 1538 + [[package]] 1539 + name = "rand" 1540 + version = "0.9.2" 1541 + source = "registry+https://github.com/rust-lang/crates.io-index" 1542 + checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" 1543 + dependencies = [ 1544 + "rand_chacha", 1545 + "rand_core", 1546 + ] 1547 + 1548 + [[package]] 1549 + name = "rand_chacha" 1550 + version = "0.9.0" 1551 + source = "registry+https://github.com/rust-lang/crates.io-index" 1552 + checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" 1553 + dependencies = [ 1554 + "ppv-lite86", 1555 + "rand_core", 1556 + ] 1557 + 1558 + [[package]] 1559 + name = "rand_core" 1560 + version = "0.9.3" 1561 + source = "registry+https://github.com/rust-lang/crates.io-index" 1562 + checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" 1563 + dependencies = [ 1564 + "getrandom 0.3.4", 1565 + ] 1566 + 1567 + [[package]] 1568 + name = "redox_syscall" 1569 + version = "0.2.16" 1570 + source = "registry+https://github.com/rust-lang/crates.io-index" 1571 + checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" 1572 + dependencies = [ 1573 + "bitflags 1.3.2", 1574 + ] 1575 + 1576 + [[package]] 1577 + name = "redox_syscall" 1578 + version = "0.5.18" 1579 + source = "registry+https://github.com/rust-lang/crates.io-index" 1580 + checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" 1581 + dependencies = [ 1582 + "bitflags 2.10.0", 1583 + ] 1584 + 1585 + [[package]] 1586 + name = "regex" 1587 + version = "1.12.2" 1588 + source = "registry+https://github.com/rust-lang/crates.io-index" 1589 + checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" 1590 + dependencies = [ 1591 + "aho-corasick", 1592 + "memchr", 1593 + "regex-automata", 1594 + "regex-syntax", 1595 + ] 1596 + 1597 + [[package]] 1598 + name = "regex-automata" 1599 + version = "0.4.13" 1600 + source = "registry+https://github.com/rust-lang/crates.io-index" 1601 + checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" 1602 + dependencies = [ 1603 + "aho-corasick", 1604 + "memchr", 1605 + "regex-syntax", 1606 + ] 1607 + 1608 + [[package]] 1609 + name = "regex-syntax" 1610 + version = "0.8.8" 1611 + source = "registry+https://github.com/rust-lang/crates.io-index" 1612 + checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" 1613 + 1614 + [[package]] 1615 + name = "reqwest" 1616 + version = "0.12.24" 1617 + source = "registry+https://github.com/rust-lang/crates.io-index" 1618 + checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" 1619 + dependencies = [ 1620 + "async-compression", 1621 + "base64", 1622 + "bytes", 1623 + "futures-core", 1624 + "futures-util", 1625 + "http", 1626 + "http-body", 1627 + "http-body-util", 1628 + "hyper", 1629 + "hyper-tls", 1630 + "hyper-util", 1631 + "js-sys", 1632 + "log", 1633 + "native-tls", 1634 + "percent-encoding", 1635 + "pin-project-lite", 1636 + "rustls-pki-types", 1637 + "serde", 1638 + "serde_json", 1639 + "serde_urlencoded", 1640 + "sync_wrapper", 1641 + "tokio", 1642 + "tokio-native-tls", 1643 + "tokio-util", 1644 + "tower", 1645 + "tower-http", 1646 + "tower-service", 1647 + "url", 1648 + "wasm-bindgen", 1649 + "wasm-bindgen-futures", 1650 + "web-sys", 1651 + ] 1652 + 1653 + [[package]] 1654 + name = "ring" 1655 + version = "0.17.14" 1656 + source = "registry+https://github.com/rust-lang/crates.io-index" 1657 + checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" 1658 + dependencies = [ 1659 + "cc", 1660 + "cfg-if", 1661 + "getrandom 0.2.16", 1662 + "libc", 1663 + "untrusted", 1664 + "windows-sys 0.52.0", 1665 + ] 1666 + 1667 + [[package]] 1668 + name = "rustc_version" 1669 + version = "0.4.1" 1670 + source = "registry+https://github.com/rust-lang/crates.io-index" 1671 + checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" 1672 + dependencies = [ 1673 + "semver", 1674 + ] 1675 + 1676 + [[package]] 1677 + name = "rustix" 1678 + version = "1.1.2" 1679 + source = "registry+https://github.com/rust-lang/crates.io-index" 1680 + checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" 1681 + dependencies = [ 1682 + "bitflags 2.10.0", 1683 + "errno", 1684 + "libc", 1685 + "linux-raw-sys", 1686 + "windows-sys 0.61.2", 1687 + ] 1688 + 1689 + [[package]] 1690 + name = "rustls" 1691 + version = "0.23.35" 1692 + source = "registry+https://github.com/rust-lang/crates.io-index" 1693 + checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" 1694 + dependencies = [ 1695 + "once_cell", 1696 + "rustls-pki-types", 1697 + "rustls-webpki", 1698 + "subtle", 1699 + "zeroize", 1700 + ] 1701 + 1702 + [[package]] 1703 + name = "rustls-pki-types" 1704 + version = "1.13.0" 1705 + source = "registry+https://github.com/rust-lang/crates.io-index" 1706 + checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a" 1707 + dependencies = [ 1708 + "zeroize", 1709 + ] 1710 + 1711 + [[package]] 1712 + name = "rustls-webpki" 1713 + version = "0.103.8" 1714 + source = "registry+https://github.com/rust-lang/crates.io-index" 1715 + checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" 1716 + dependencies = [ 1717 + "ring", 1718 + "rustls-pki-types", 1719 + "untrusted", 1720 + ] 1721 + 1722 + [[package]] 1723 + name = "rustversion" 1724 + version = "1.0.22" 1725 + source = "registry+https://github.com/rust-lang/crates.io-index" 1726 + checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" 1727 + 1728 + [[package]] 1729 + name = "ryu" 1730 + version = "1.0.20" 1731 + source = "registry+https://github.com/rust-lang/crates.io-index" 1732 + checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 1733 + 1734 + [[package]] 1735 + name = "schannel" 1736 + version = "0.1.28" 1737 + source = "registry+https://github.com/rust-lang/crates.io-index" 1738 + checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" 1739 + dependencies = [ 1740 + "windows-sys 0.61.2", 1741 + ] 1742 + 1743 + [[package]] 1744 + name = "scopeguard" 1745 + version = "1.2.0" 1746 + source = "registry+https://github.com/rust-lang/crates.io-index" 1747 + checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1748 + 1749 + [[package]] 1750 + name = "security-framework" 1751 + version = "2.11.1" 1752 + source = "registry+https://github.com/rust-lang/crates.io-index" 1753 + checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" 1754 + dependencies = [ 1755 + "bitflags 2.10.0", 1756 + "core-foundation", 1757 + "core-foundation-sys", 1758 + "libc", 1759 + "security-framework-sys", 1760 + ] 1761 + 1762 + [[package]] 1763 + name = "security-framework-sys" 1764 + version = "2.15.0" 1765 + source = "registry+https://github.com/rust-lang/crates.io-index" 1766 + checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" 1767 + dependencies = [ 1768 + "core-foundation-sys", 1769 + "libc", 1770 + ] 1771 + 1772 + [[package]] 1773 + name = "semver" 1774 + version = "1.0.27" 1775 + source = "registry+https://github.com/rust-lang/crates.io-index" 1776 + checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" 1777 + 1778 + [[package]] 1779 + name = "serde" 1780 + version = "1.0.228" 1781 + source = "registry+https://github.com/rust-lang/crates.io-index" 1782 + checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" 1783 + dependencies = [ 1784 + "serde_core", 1785 + "serde_derive", 1786 + ] 1787 + 1788 + [[package]] 1789 + name = "serde_bytes" 1790 + version = "0.11.19" 1791 + source = "registry+https://github.com/rust-lang/crates.io-index" 1792 + checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" 1793 + dependencies = [ 1794 + "serde", 1795 + "serde_core", 1796 + ] 1797 + 1798 + [[package]] 1799 + name = "serde_core" 1800 + version = "1.0.228" 1801 + source = "registry+https://github.com/rust-lang/crates.io-index" 1802 + checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" 1803 + dependencies = [ 1804 + "serde_derive", 1805 + ] 1806 + 1807 + [[package]] 1808 + name = "serde_derive" 1809 + version = "1.0.228" 1810 + source = "registry+https://github.com/rust-lang/crates.io-index" 1811 + checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" 1812 + dependencies = [ 1813 + "proc-macro2", 1814 + "quote", 1815 + "syn 2.0.111", 1816 + ] 1817 + 1818 + [[package]] 1819 + name = "serde_html_form" 1820 + version = "0.2.8" 1821 + source = "registry+https://github.com/rust-lang/crates.io-index" 1822 + checksum = "b2f2d7ff8a2140333718bb329f5c40fc5f0865b84c426183ce14c97d2ab8154f" 1823 + dependencies = [ 1824 + "form_urlencoded", 1825 + "indexmap", 1826 + "itoa", 1827 + "ryu", 1828 + "serde_core", 1829 + ] 1830 + 1831 + [[package]] 1832 + name = "serde_json" 1833 + version = "1.0.145" 1834 + source = "registry+https://github.com/rust-lang/crates.io-index" 1835 + checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" 1836 + dependencies = [ 1837 + "itoa", 1838 + "memchr", 1839 + "ryu", 1840 + "serde", 1841 + "serde_core", 1842 + ] 1843 + 1844 + [[package]] 1845 + name = "serde_urlencoded" 1846 + version = "0.7.1" 1847 + source = "registry+https://github.com/rust-lang/crates.io-index" 1848 + checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 1849 + dependencies = [ 1850 + "form_urlencoded", 1851 + "itoa", 1852 + "ryu", 1853 + "serde", 1854 + ] 1855 + 1856 + [[package]] 1857 + name = "sha1" 1858 + version = "0.10.6" 1859 + source = "registry+https://github.com/rust-lang/crates.io-index" 1860 + checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 1861 + dependencies = [ 1862 + "cfg-if", 1863 + "cpufeatures", 1864 + "digest", 1865 + ] 1866 + 1867 + [[package]] 1868 + name = "shlex" 1869 + version = "1.3.0" 1870 + source = "registry+https://github.com/rust-lang/crates.io-index" 1871 + checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1872 + 1873 + [[package]] 1874 + name = "signal-hook-registry" 1875 + version = "1.4.6" 1876 + source = "registry+https://github.com/rust-lang/crates.io-index" 1877 + checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" 1878 + dependencies = [ 1879 + "libc", 1880 + ] 1881 + 1882 + [[package]] 1883 + name = "simd-adler32" 1884 + version = "0.3.7" 1885 + source = "registry+https://github.com/rust-lang/crates.io-index" 1886 + checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" 1887 + 1888 + [[package]] 1889 + name = "slab" 1890 + version = "0.4.11" 1891 + source = "registry+https://github.com/rust-lang/crates.io-index" 1892 + checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" 1893 + 1894 + [[package]] 1895 + name = "sled" 1896 + version = "0.34.7" 1897 + source = "registry+https://github.com/rust-lang/crates.io-index" 1898 + checksum = "7f96b4737c2ce5987354855aed3797279def4ebf734436c6aa4552cf8e169935" 1899 + dependencies = [ 1900 + "crc32fast", 1901 + "crossbeam-epoch", 1902 + "crossbeam-utils", 1903 + "fs2", 1904 + "fxhash", 1905 + "libc", 1906 + "log", 1907 + "parking_lot 0.11.2", 1908 + ] 1909 + 1910 + [[package]] 1911 + name = "smallvec" 1912 + version = "1.15.1" 1913 + source = "registry+https://github.com/rust-lang/crates.io-index" 1914 + checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" 1915 + 1916 + [[package]] 1917 + name = "socket2" 1918 + version = "0.6.1" 1919 + source = "registry+https://github.com/rust-lang/crates.io-index" 1920 + checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" 1921 + dependencies = [ 1922 + "libc", 1923 + "windows-sys 0.60.2", 1924 + ] 1925 + 1926 + [[package]] 1927 + name = "stable_deref_trait" 1928 + version = "1.2.1" 1929 + source = "registry+https://github.com/rust-lang/crates.io-index" 1930 + checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" 1931 + 1932 + [[package]] 1933 + name = "strsim" 1934 + version = "0.11.1" 1935 + source = "registry+https://github.com/rust-lang/crates.io-index" 1936 + checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1937 + 1938 + [[package]] 1939 + name = "subtle" 1940 + version = "2.6.1" 1941 + source = "registry+https://github.com/rust-lang/crates.io-index" 1942 + checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 1943 + 1944 + [[package]] 1945 + name = "syn" 1946 + version = "1.0.109" 1947 + source = "registry+https://github.com/rust-lang/crates.io-index" 1948 + checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 1949 + dependencies = [ 1950 + "proc-macro2", 1951 + "quote", 1952 + "unicode-ident", 1953 + ] 1954 + 1955 + [[package]] 1956 + name = "syn" 1957 + version = "2.0.111" 1958 + source = "registry+https://github.com/rust-lang/crates.io-index" 1959 + checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" 1960 + dependencies = [ 1961 + "proc-macro2", 1962 + "quote", 1963 + "unicode-ident", 1964 + ] 1965 + 1966 + [[package]] 1967 + name = "sync_wrapper" 1968 + version = "1.0.2" 1969 + source = "registry+https://github.com/rust-lang/crates.io-index" 1970 + checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" 1971 + dependencies = [ 1972 + "futures-core", 1973 + ] 1974 + 1975 + [[package]] 1976 + name = "synstructure" 1977 + version = "0.13.2" 1978 + source = "registry+https://github.com/rust-lang/crates.io-index" 1979 + checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" 1980 + dependencies = [ 1981 + "proc-macro2", 1982 + "quote", 1983 + "syn 2.0.111", 1984 + ] 1985 + 1986 + [[package]] 1987 + name = "tagptr" 1988 + version = "0.2.0" 1989 + source = "registry+https://github.com/rust-lang/crates.io-index" 1990 + checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" 1991 + 1992 + [[package]] 1993 + name = "tempfile" 1994 + version = "3.23.0" 1995 + source = "registry+https://github.com/rust-lang/crates.io-index" 1996 + checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" 1997 + dependencies = [ 1998 + "fastrand", 1999 + "getrandom 0.3.4", 2000 + "once_cell", 2001 + "rustix", 2002 + "windows-sys 0.61.2", 2003 + ] 2004 + 2005 + [[package]] 2006 + name = "thiserror" 2007 + version = "1.0.69" 2008 + source = "registry+https://github.com/rust-lang/crates.io-index" 2009 + checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" 2010 + dependencies = [ 2011 + "thiserror-impl 1.0.69", 2012 + ] 2013 + 2014 + [[package]] 2015 + name = "thiserror" 2016 + version = "2.0.17" 2017 + source = "registry+https://github.com/rust-lang/crates.io-index" 2018 + checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" 2019 + dependencies = [ 2020 + "thiserror-impl 2.0.17", 2021 + ] 2022 + 2023 + [[package]] 2024 + name = "thiserror-impl" 2025 + version = "1.0.69" 2026 + source = "registry+https://github.com/rust-lang/crates.io-index" 2027 + checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" 2028 + dependencies = [ 2029 + "proc-macro2", 2030 + "quote", 2031 + "syn 2.0.111", 2032 + ] 2033 + 2034 + [[package]] 2035 + name = "thiserror-impl" 2036 + version = "2.0.17" 2037 + source = "registry+https://github.com/rust-lang/crates.io-index" 2038 + checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" 2039 + dependencies = [ 2040 + "proc-macro2", 2041 + "quote", 2042 + "syn 2.0.111", 2043 + ] 2044 + 2045 + [[package]] 2046 + name = "tinystr" 2047 + version = "0.8.2" 2048 + source = "registry+https://github.com/rust-lang/crates.io-index" 2049 + checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" 2050 + dependencies = [ 2051 + "displaydoc", 2052 + "zerovec", 2053 + ] 2054 + 2055 + [[package]] 2056 + name = "tokio" 2057 + version = "1.48.0" 2058 + source = "registry+https://github.com/rust-lang/crates.io-index" 2059 + checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" 2060 + dependencies = [ 2061 + "bytes", 2062 + "libc", 2063 + "mio", 2064 + "parking_lot 0.12.5", 2065 + "pin-project-lite", 2066 + "signal-hook-registry", 2067 + "socket2", 2068 + "tokio-macros", 2069 + "windows-sys 0.61.2", 2070 + ] 2071 + 2072 + [[package]] 2073 + name = "tokio-macros" 2074 + version = "2.6.0" 2075 + source = "registry+https://github.com/rust-lang/crates.io-index" 2076 + checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" 2077 + dependencies = [ 2078 + "proc-macro2", 2079 + "quote", 2080 + "syn 2.0.111", 2081 + ] 2082 + 2083 + [[package]] 2084 + name = "tokio-native-tls" 2085 + version = "0.3.1" 2086 + source = "registry+https://github.com/rust-lang/crates.io-index" 2087 + checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" 2088 + dependencies = [ 2089 + "native-tls", 2090 + "tokio", 2091 + ] 2092 + 2093 + [[package]] 2094 + name = "tokio-util" 2095 + version = "0.7.17" 2096 + source = "registry+https://github.com/rust-lang/crates.io-index" 2097 + checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" 2098 + dependencies = [ 2099 + "bytes", 2100 + "futures-core", 2101 + "futures-sink", 2102 + "pin-project-lite", 2103 + "tokio", 2104 + ] 2105 + 2106 + [[package]] 2107 + name = "tower" 2108 + version = "0.5.2" 2109 + source = "registry+https://github.com/rust-lang/crates.io-index" 2110 + checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" 2111 + dependencies = [ 2112 + "futures-core", 2113 + "futures-util", 2114 + "pin-project-lite", 2115 + "sync_wrapper", 2116 + "tokio", 2117 + "tower-layer", 2118 + "tower-service", 2119 + ] 2120 + 2121 + [[package]] 2122 + name = "tower-http" 2123 + version = "0.6.6" 2124 + source = "registry+https://github.com/rust-lang/crates.io-index" 2125 + checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" 2126 + dependencies = [ 2127 + "bitflags 2.10.0", 2128 + "bytes", 2129 + "futures-util", 2130 + "http", 2131 + "http-body", 2132 + "iri-string", 2133 + "pin-project-lite", 2134 + "tower", 2135 + "tower-layer", 2136 + "tower-service", 2137 + ] 2138 + 2139 + [[package]] 2140 + name = "tower-layer" 2141 + version = "0.3.3" 2142 + source = "registry+https://github.com/rust-lang/crates.io-index" 2143 + checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" 2144 + 2145 + [[package]] 2146 + name = "tower-service" 2147 + version = "0.3.3" 2148 + source = "registry+https://github.com/rust-lang/crates.io-index" 2149 + checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 2150 + 2151 + [[package]] 2152 + name = "tracing" 2153 + version = "0.1.41" 2154 + source = "registry+https://github.com/rust-lang/crates.io-index" 2155 + checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 2156 + dependencies = [ 2157 + "pin-project-lite", 2158 + "tracing-core", 2159 + ] 2160 + 2161 + [[package]] 2162 + name = "tracing-core" 2163 + version = "0.1.34" 2164 + source = "registry+https://github.com/rust-lang/crates.io-index" 2165 + checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" 2166 + dependencies = [ 2167 + "once_cell", 2168 + ] 2169 + 2170 + [[package]] 2171 + name = "trait-variant" 2172 + version = "0.1.2" 2173 + source = "registry+https://github.com/rust-lang/crates.io-index" 2174 + checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7" 2175 + dependencies = [ 2176 + "proc-macro2", 2177 + "quote", 2178 + "syn 2.0.111", 2179 + ] 2180 + 2181 + [[package]] 2182 + name = "try-lock" 2183 + version = "0.2.5" 2184 + source = "registry+https://github.com/rust-lang/crates.io-index" 2185 + checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 2186 + 2187 + [[package]] 2188 + name = "tungstenite" 2189 + version = "0.28.0" 2190 + source = "registry+https://github.com/rust-lang/crates.io-index" 2191 + checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" 2192 + dependencies = [ 2193 + "bytes", 2194 + "data-encoding", 2195 + "http", 2196 + "httparse", 2197 + "log", 2198 + "native-tls", 2199 + "rand", 2200 + "rustls", 2201 + "rustls-pki-types", 2202 + "sha1", 2203 + "thiserror 2.0.17", 2204 + "utf-8", 2205 + "webpki-roots 0.26.11", 2206 + ] 2207 + 2208 + [[package]] 2209 + name = "typenum" 2210 + version = "1.19.0" 2211 + source = "registry+https://github.com/rust-lang/crates.io-index" 2212 + checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" 2213 + 2214 + [[package]] 2215 + name = "unicode-ident" 2216 + version = "1.0.22" 2217 + source = "registry+https://github.com/rust-lang/crates.io-index" 2218 + checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" 2219 + 2220 + [[package]] 2221 + name = "unicode-segmentation" 2222 + version = "1.12.0" 2223 + source = "registry+https://github.com/rust-lang/crates.io-index" 2224 + checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" 2225 + 2226 + [[package]] 2227 + name = "unsigned-varint" 2228 + version = "0.8.0" 2229 + source = "registry+https://github.com/rust-lang/crates.io-index" 2230 + checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" 2231 + 2232 + [[package]] 2233 + name = "untrusted" 2234 + version = "0.9.0" 2235 + source = "registry+https://github.com/rust-lang/crates.io-index" 2236 + checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 2237 + 2238 + [[package]] 2239 + name = "url" 2240 + version = "2.5.7" 2241 + source = "registry+https://github.com/rust-lang/crates.io-index" 2242 + checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" 2243 + dependencies = [ 2244 + "form_urlencoded", 2245 + "idna", 2246 + "percent-encoding", 2247 + "serde", 2248 + ] 2249 + 2250 + [[package]] 2251 + name = "utf-8" 2252 + version = "0.7.6" 2253 + source = "registry+https://github.com/rust-lang/crates.io-index" 2254 + checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" 2255 + 2256 + [[package]] 2257 + name = "utf8_iter" 2258 + version = "1.0.4" 2259 + source = "registry+https://github.com/rust-lang/crates.io-index" 2260 + checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 2261 + 2262 + [[package]] 2263 + name = "utf8parse" 2264 + version = "0.2.2" 2265 + source = "registry+https://github.com/rust-lang/crates.io-index" 2266 + checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 2267 + 2268 + [[package]] 2269 + name = "uuid" 2270 + version = "1.18.1" 2271 + source = "registry+https://github.com/rust-lang/crates.io-index" 2272 + checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" 2273 + dependencies = [ 2274 + "getrandom 0.3.4", 2275 + "js-sys", 2276 + "wasm-bindgen", 2277 + ] 2278 + 2279 + [[package]] 2280 + name = "vcpkg" 2281 + version = "0.2.15" 2282 + source = "registry+https://github.com/rust-lang/crates.io-index" 2283 + checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 2284 + 2285 + [[package]] 2286 + name = "version_check" 2287 + version = "0.9.5" 2288 + source = "registry+https://github.com/rust-lang/crates.io-index" 2289 + checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 2290 + 2291 + [[package]] 2292 + name = "want" 2293 + version = "0.3.1" 2294 + source = "registry+https://github.com/rust-lang/crates.io-index" 2295 + checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 2296 + dependencies = [ 2297 + "try-lock", 2298 + ] 2299 + 2300 + [[package]] 2301 + name = "wasi" 2302 + version = "0.11.1+wasi-snapshot-preview1" 2303 + source = "registry+https://github.com/rust-lang/crates.io-index" 2304 + checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" 2305 + 2306 + [[package]] 2307 + name = "wasip2" 2308 + version = "1.0.1+wasi-0.2.4" 2309 + source = "registry+https://github.com/rust-lang/crates.io-index" 2310 + checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" 2311 + dependencies = [ 2312 + "wit-bindgen", 2313 + ] 2314 + 2315 + [[package]] 2316 + name = "wasm-bindgen" 2317 + version = "0.2.105" 2318 + source = "registry+https://github.com/rust-lang/crates.io-index" 2319 + checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" 2320 + dependencies = [ 2321 + "cfg-if", 2322 + "once_cell", 2323 + "rustversion", 2324 + "wasm-bindgen-macro", 2325 + "wasm-bindgen-shared", 2326 + ] 2327 + 2328 + [[package]] 2329 + name = "wasm-bindgen-futures" 2330 + version = "0.4.55" 2331 + source = "registry+https://github.com/rust-lang/crates.io-index" 2332 + checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0" 2333 + dependencies = [ 2334 + "cfg-if", 2335 + "js-sys", 2336 + "once_cell", 2337 + "wasm-bindgen", 2338 + "web-sys", 2339 + ] 2340 + 2341 + [[package]] 2342 + name = "wasm-bindgen-macro" 2343 + version = "0.2.105" 2344 + source = "registry+https://github.com/rust-lang/crates.io-index" 2345 + checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" 2346 + dependencies = [ 2347 + "quote", 2348 + "wasm-bindgen-macro-support", 2349 + ] 2350 + 2351 + [[package]] 2352 + name = "wasm-bindgen-macro-support" 2353 + version = "0.2.105" 2354 + source = "registry+https://github.com/rust-lang/crates.io-index" 2355 + checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" 2356 + dependencies = [ 2357 + "bumpalo", 2358 + "proc-macro2", 2359 + "quote", 2360 + "syn 2.0.111", 2361 + "wasm-bindgen-shared", 2362 + ] 2363 + 2364 + [[package]] 2365 + name = "wasm-bindgen-shared" 2366 + version = "0.2.105" 2367 + source = "registry+https://github.com/rust-lang/crates.io-index" 2368 + checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" 2369 + dependencies = [ 2370 + "unicode-ident", 2371 + ] 2372 + 2373 + [[package]] 2374 + name = "web-sys" 2375 + version = "0.3.82" 2376 + source = "registry+https://github.com/rust-lang/crates.io-index" 2377 + checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" 2378 + dependencies = [ 2379 + "js-sys", 2380 + "wasm-bindgen", 2381 + ] 2382 + 2383 + [[package]] 2384 + name = "web-time" 2385 + version = "1.1.0" 2386 + source = "registry+https://github.com/rust-lang/crates.io-index" 2387 + checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" 2388 + dependencies = [ 2389 + "js-sys", 2390 + "wasm-bindgen", 2391 + ] 2392 + 2393 + [[package]] 2394 + name = "webpki-roots" 2395 + version = "0.26.11" 2396 + source = "registry+https://github.com/rust-lang/crates.io-index" 2397 + checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" 2398 + dependencies = [ 2399 + "webpki-roots 1.0.4", 2400 + ] 2401 + 2402 + [[package]] 2403 + name = "webpki-roots" 2404 + version = "1.0.4" 2405 + source = "registry+https://github.com/rust-lang/crates.io-index" 2406 + checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e" 2407 + dependencies = [ 2408 + "rustls-pki-types", 2409 + ] 2410 + 2411 + [[package]] 2412 + name = "winapi" 2413 + version = "0.3.9" 2414 + source = "registry+https://github.com/rust-lang/crates.io-index" 2415 + checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 2416 + dependencies = [ 2417 + "winapi-i686-pc-windows-gnu", 2418 + "winapi-x86_64-pc-windows-gnu", 2419 + ] 2420 + 2421 + [[package]] 2422 + name = "winapi-i686-pc-windows-gnu" 2423 + version = "0.4.0" 2424 + source = "registry+https://github.com/rust-lang/crates.io-index" 2425 + checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2426 + 2427 + [[package]] 2428 + name = "winapi-x86_64-pc-windows-gnu" 2429 + version = "0.4.0" 2430 + source = "registry+https://github.com/rust-lang/crates.io-index" 2431 + checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2432 + 2433 + [[package]] 2434 + name = "windows-core" 2435 + version = "0.62.2" 2436 + source = "registry+https://github.com/rust-lang/crates.io-index" 2437 + checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" 2438 + dependencies = [ 2439 + "windows-implement", 2440 + "windows-interface", 2441 + "windows-link", 2442 + "windows-result", 2443 + "windows-strings", 2444 + ] 2445 + 2446 + [[package]] 2447 + name = "windows-implement" 2448 + version = "0.60.2" 2449 + source = "registry+https://github.com/rust-lang/crates.io-index" 2450 + checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" 2451 + dependencies = [ 2452 + "proc-macro2", 2453 + "quote", 2454 + "syn 2.0.111", 2455 + ] 2456 + 2457 + [[package]] 2458 + name = "windows-interface" 2459 + version = "0.59.3" 2460 + source = "registry+https://github.com/rust-lang/crates.io-index" 2461 + checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" 2462 + dependencies = [ 2463 + "proc-macro2", 2464 + "quote", 2465 + "syn 2.0.111", 2466 + ] 2467 + 2468 + [[package]] 2469 + name = "windows-link" 2470 + version = "0.2.1" 2471 + source = "registry+https://github.com/rust-lang/crates.io-index" 2472 + checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" 2473 + 2474 + [[package]] 2475 + name = "windows-result" 2476 + version = "0.4.1" 2477 + source = "registry+https://github.com/rust-lang/crates.io-index" 2478 + checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" 2479 + dependencies = [ 2480 + "windows-link", 2481 + ] 2482 + 2483 + [[package]] 2484 + name = "windows-strings" 2485 + version = "0.5.1" 2486 + source = "registry+https://github.com/rust-lang/crates.io-index" 2487 + checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" 2488 + dependencies = [ 2489 + "windows-link", 2490 + ] 2491 + 2492 + [[package]] 2493 + name = "windows-sys" 2494 + version = "0.52.0" 2495 + source = "registry+https://github.com/rust-lang/crates.io-index" 2496 + checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2497 + dependencies = [ 2498 + "windows-targets 0.52.6", 2499 + ] 2500 + 2501 + [[package]] 2502 + name = "windows-sys" 2503 + version = "0.60.2" 2504 + source = "registry+https://github.com/rust-lang/crates.io-index" 2505 + checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" 2506 + dependencies = [ 2507 + "windows-targets 0.53.5", 2508 + ] 2509 + 2510 + [[package]] 2511 + name = "windows-sys" 2512 + version = "0.61.2" 2513 + source = "registry+https://github.com/rust-lang/crates.io-index" 2514 + checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" 2515 + dependencies = [ 2516 + "windows-link", 2517 + ] 2518 + 2519 + [[package]] 2520 + name = "windows-targets" 2521 + version = "0.52.6" 2522 + source = "registry+https://github.com/rust-lang/crates.io-index" 2523 + checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 2524 + dependencies = [ 2525 + "windows_aarch64_gnullvm 0.52.6", 2526 + "windows_aarch64_msvc 0.52.6", 2527 + "windows_i686_gnu 0.52.6", 2528 + "windows_i686_gnullvm 0.52.6", 2529 + "windows_i686_msvc 0.52.6", 2530 + "windows_x86_64_gnu 0.52.6", 2531 + "windows_x86_64_gnullvm 0.52.6", 2532 + "windows_x86_64_msvc 0.52.6", 2533 + ] 2534 + 2535 + [[package]] 2536 + name = "windows-targets" 2537 + version = "0.53.5" 2538 + source = "registry+https://github.com/rust-lang/crates.io-index" 2539 + checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" 2540 + dependencies = [ 2541 + "windows-link", 2542 + "windows_aarch64_gnullvm 0.53.1", 2543 + "windows_aarch64_msvc 0.53.1", 2544 + "windows_i686_gnu 0.53.1", 2545 + "windows_i686_gnullvm 0.53.1", 2546 + "windows_i686_msvc 0.53.1", 2547 + "windows_x86_64_gnu 0.53.1", 2548 + "windows_x86_64_gnullvm 0.53.1", 2549 + "windows_x86_64_msvc 0.53.1", 2550 + ] 2551 + 2552 + [[package]] 2553 + name = "windows_aarch64_gnullvm" 2554 + version = "0.52.6" 2555 + source = "registry+https://github.com/rust-lang/crates.io-index" 2556 + checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 2557 + 2558 + [[package]] 2559 + name = "windows_aarch64_gnullvm" 2560 + version = "0.53.1" 2561 + source = "registry+https://github.com/rust-lang/crates.io-index" 2562 + checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" 2563 + 2564 + [[package]] 2565 + name = "windows_aarch64_msvc" 2566 + version = "0.52.6" 2567 + source = "registry+https://github.com/rust-lang/crates.io-index" 2568 + checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 2569 + 2570 + [[package]] 2571 + name = "windows_aarch64_msvc" 2572 + version = "0.53.1" 2573 + source = "registry+https://github.com/rust-lang/crates.io-index" 2574 + checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" 2575 + 2576 + [[package]] 2577 + name = "windows_i686_gnu" 2578 + version = "0.52.6" 2579 + source = "registry+https://github.com/rust-lang/crates.io-index" 2580 + checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 2581 + 2582 + [[package]] 2583 + name = "windows_i686_gnu" 2584 + version = "0.53.1" 2585 + source = "registry+https://github.com/rust-lang/crates.io-index" 2586 + checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" 2587 + 2588 + [[package]] 2589 + name = "windows_i686_gnullvm" 2590 + version = "0.52.6" 2591 + source = "registry+https://github.com/rust-lang/crates.io-index" 2592 + checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 2593 + 2594 + [[package]] 2595 + name = "windows_i686_gnullvm" 2596 + version = "0.53.1" 2597 + source = "registry+https://github.com/rust-lang/crates.io-index" 2598 + checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" 2599 + 2600 + [[package]] 2601 + name = "windows_i686_msvc" 2602 + version = "0.52.6" 2603 + source = "registry+https://github.com/rust-lang/crates.io-index" 2604 + checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 2605 + 2606 + [[package]] 2607 + name = "windows_i686_msvc" 2608 + version = "0.53.1" 2609 + source = "registry+https://github.com/rust-lang/crates.io-index" 2610 + checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" 2611 + 2612 + [[package]] 2613 + name = "windows_x86_64_gnu" 2614 + version = "0.52.6" 2615 + source = "registry+https://github.com/rust-lang/crates.io-index" 2616 + checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 2617 + 2618 + [[package]] 2619 + name = "windows_x86_64_gnu" 2620 + version = "0.53.1" 2621 + source = "registry+https://github.com/rust-lang/crates.io-index" 2622 + checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" 2623 + 2624 + [[package]] 2625 + name = "windows_x86_64_gnullvm" 2626 + version = "0.52.6" 2627 + source = "registry+https://github.com/rust-lang/crates.io-index" 2628 + checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 2629 + 2630 + [[package]] 2631 + name = "windows_x86_64_gnullvm" 2632 + version = "0.53.1" 2633 + source = "registry+https://github.com/rust-lang/crates.io-index" 2634 + checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" 2635 + 2636 + [[package]] 2637 + name = "windows_x86_64_msvc" 2638 + version = "0.52.6" 2639 + source = "registry+https://github.com/rust-lang/crates.io-index" 2640 + checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 2641 + 2642 + [[package]] 2643 + name = "windows_x86_64_msvc" 2644 + version = "0.53.1" 2645 + source = "registry+https://github.com/rust-lang/crates.io-index" 2646 + checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" 2647 + 2648 + [[package]] 2649 + name = "wit-bindgen" 2650 + version = "0.46.0" 2651 + source = "registry+https://github.com/rust-lang/crates.io-index" 2652 + checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" 2653 + 2654 + [[package]] 2655 + name = "writeable" 2656 + version = "0.6.2" 2657 + source = "registry+https://github.com/rust-lang/crates.io-index" 2658 + checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" 2659 + 2660 + [[package]] 2661 + name = "yoke" 2662 + version = "0.8.1" 2663 + source = "registry+https://github.com/rust-lang/crates.io-index" 2664 + checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" 2665 + dependencies = [ 2666 + "stable_deref_trait", 2667 + "yoke-derive", 2668 + "zerofrom", 2669 + ] 2670 + 2671 + [[package]] 2672 + name = "yoke-derive" 2673 + version = "0.8.1" 2674 + source = "registry+https://github.com/rust-lang/crates.io-index" 2675 + checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" 2676 + dependencies = [ 2677 + "proc-macro2", 2678 + "quote", 2679 + "syn 2.0.111", 2680 + "synstructure", 2681 + ] 2682 + 2683 + [[package]] 2684 + name = "zerocopy" 2685 + version = "0.8.28" 2686 + source = "registry+https://github.com/rust-lang/crates.io-index" 2687 + checksum = "43fa6694ed34d6e57407afbccdeecfa268c470a7d2a5b0cf49ce9fcc345afb90" 2688 + dependencies = [ 2689 + "zerocopy-derive", 2690 + ] 2691 + 2692 + [[package]] 2693 + name = "zerocopy-derive" 2694 + version = "0.8.28" 2695 + source = "registry+https://github.com/rust-lang/crates.io-index" 2696 + checksum = "c640b22cd9817fae95be82f0d2f90b11f7605f6c319d16705c459b27ac2cbc26" 2697 + dependencies = [ 2698 + "proc-macro2", 2699 + "quote", 2700 + "syn 2.0.111", 2701 + ] 2702 + 2703 + [[package]] 2704 + name = "zerofrom" 2705 + version = "0.1.6" 2706 + source = "registry+https://github.com/rust-lang/crates.io-index" 2707 + checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" 2708 + dependencies = [ 2709 + "zerofrom-derive", 2710 + ] 2711 + 2712 + [[package]] 2713 + name = "zerofrom-derive" 2714 + version = "0.1.6" 2715 + source = "registry+https://github.com/rust-lang/crates.io-index" 2716 + checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" 2717 + dependencies = [ 2718 + "proc-macro2", 2719 + "quote", 2720 + "syn 2.0.111", 2721 + "synstructure", 2722 + ] 2723 + 2724 + [[package]] 2725 + name = "zeroize" 2726 + version = "1.8.2" 2727 + source = "registry+https://github.com/rust-lang/crates.io-index" 2728 + checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" 2729 + 2730 + [[package]] 2731 + name = "zerotrie" 2732 + version = "0.2.3" 2733 + source = "registry+https://github.com/rust-lang/crates.io-index" 2734 + checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" 2735 + dependencies = [ 2736 + "displaydoc", 2737 + "yoke", 2738 + "zerofrom", 2739 + ] 2740 + 2741 + [[package]] 2742 + name = "zerovec" 2743 + version = "0.11.5" 2744 + source = "registry+https://github.com/rust-lang/crates.io-index" 2745 + checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" 2746 + dependencies = [ 2747 + "yoke", 2748 + "zerofrom", 2749 + "zerovec-derive", 2750 + ] 2751 + 2752 + [[package]] 2753 + name = "zerovec-derive" 2754 + version = "0.11.2" 2755 + source = "registry+https://github.com/rust-lang/crates.io-index" 2756 + checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" 2757 + dependencies = [ 2758 + "proc-macro2", 2759 + "quote", 2760 + "syn 2.0.111", 2761 + ]
+24
Cargo.toml
··· 1 + [package] 2 + name = "leaflet-notifs" 3 + version = "0.1.0" 4 + edition = "2024" 5 + 6 + [dependencies] 7 + anyhow = "1.0.100" 8 + atrium-api = { version = "0.25.6", features = ["namespace-chatbsky", "tokio"] } 9 + atrium-common = "0.1.2" 10 + atrium-identity = "0.1.7" 11 + atrium-xrpc = "0.12.3" 12 + atrium-xrpc-client = "0.5.14" 13 + bsky-sdk = "0.1.22" 14 + clap = { version = "4.5.53", features = ["derive", "env", "suggestions"] } 15 + env_logger = "0.11.8" 16 + facet-pretty = "0.31.0" 17 + log = "0.4.28" 18 + serde = "1.0.228" 19 + serde_json = "1.0.145" 20 + sled = "0.34.7" 21 + tempfile = "3.23.0" 22 + tokio = { version = "1.48.0", features = ["full"] } 23 + tungstenite = { version = "0.28.0", features = ["native-tls", "rustls", "rustls-tls-webpki-roots"] } 24 + url = "2.5.7"
+19
Dockerfile
··· 1 + FROM rust:latest AS builder 2 + 3 + WORKDIR /app 4 + 5 + COPY Cargo.toml Cargo.lock ./ 6 + 7 + COPY . . 8 + 9 + RUN cargo build --release 10 + 11 + FROM debian:bookworm-slim 12 + 13 + RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/* 14 + 15 + WORKDIR /app 16 + 17 + COPY --from=builder /app/target/release/leaflet-notifs /app/app 18 + 19 + CMD ["/app/app"]
+19
README.md
··· 1 + # `leaflet-notifs` 2 + 3 + Send DMs to Bluesky users when one of their [leaflet.pub](http://leaflet.pub/) posts gets a new comment. 4 + 5 + Status: WIP 🚧 6 + 7 + --- 8 + 9 + It is very simple and very dumb, many sharp corners, probably not yet ready for production. 10 + 11 + Run it with Docker, run it with `cargo run`, whatever you prefer! 12 + 13 + See `cargo run -- --help` for information on how to configure it -- you can use either environment variables or CLI flags. 14 + 15 + `leaflet-notifs` requires a writable directory to keep a small database with internal accounting data. 16 + 17 + There is one instance kinda running at [@leafnotifs.wallera.computer](https://bsky.app/profile/leafnotifs.wallera.computer): no guarantee of uptime as of now. 18 + 19 + When/if [@leaflet.pub](https://bsky.app/profile/leaflet.pub) will run their own (probably better) notification service, I may discontinue this one.
+451
src/at.rs
··· 1 + use std::{str::FromStr, sync::Arc}; 2 + 3 + use anyhow::{Result, anyhow}; 4 + use atrium_api::{ 5 + agent::{AtprotoServiceType, atp_agent::AtpSession}, 6 + app::bsky::graph::get_followers, 7 + chat::bsky::convo::{defs::MessageInputData, get_convo_for_members, send_message}, 8 + com::atproto::repo::get_record, 9 + did_doc::DidDocument, 10 + types::string::{AtIdentifier, Did, Nsid, RecordKey}, 11 + }; 12 + use atrium_common::types::cached::{Cached, r#impl::CacheImpl}; 13 + use atrium_common::{ 14 + resolver::Resolver, 15 + types::cached::{Cacheable, r#impl::Cache}, 16 + }; 17 + use atrium_identity::did::{CommonDidResolver, CommonDidResolverConfig}; 18 + use atrium_xrpc_client::reqwest::ReqwestClient; 19 + use bsky_sdk::{BskyAgent, agent::config::Config, rich_text::RichText}; 20 + use serde::{Deserialize, Serialize}; 21 + use tokio::sync::mpsc; 22 + 23 + pub struct Handle { 24 + agent: BskyAgent, 25 + session: AtpSession, 26 + did_resolver: Cached< 27 + CommonDidResolver<ReqwestClient>, 28 + CacheImpl<atrium_api::types::string::Did, atrium_api::did_doc::DidDocument>, 29 + >, 30 + } 31 + 32 + const APPVIEW_PROXY: &str = "did:web:api.bsky.app#bsky_appview"; 33 + const CHAT_PROXY_DID: &str = "did:web:api.bsky.chat"; 34 + 35 + impl Handle { 36 + pub async fn new(handle: &str, password: &str, pds: &str) -> Result<Self> { 37 + let agent = BskyAgent::builder() 38 + .config(Config { 39 + endpoint: pds.to_string(), 40 + proxy_header: Some(APPVIEW_PROXY.to_string()), 41 + ..Default::default() 42 + }) 43 + .build() 44 + .await?; 45 + 46 + let c = Arc::new(ReqwestClient::new("http://bsky.social")); 47 + 48 + let did_resolver = atrium_identity::did::CommonDidResolver::new(CommonDidResolverConfig { 49 + plc_directory_url: "http://plc.directory".to_string(), 50 + http_client: c.clone(), 51 + }); 52 + 53 + let cached_did_resolver = did_resolver.cached(CacheImpl::<Did, DidDocument>::new( 54 + atrium_common::types::cached::CacheConfig { 55 + max_capacity: Some(5000), 56 + time_to_live: None, 57 + }, 58 + )); 59 + 60 + let s = agent.login(handle, password).await?; 61 + Ok(Handle { 62 + agent, 63 + session: s, 64 + did_resolver: cached_did_resolver, 65 + }) 66 + } 67 + 68 + pub fn handle(&self) -> String { 69 + self.session.handle.to_string().clone() 70 + } 71 + 72 + pub fn did(&self) -> String { 73 + self.session.did.to_string().clone() 74 + } 75 + 76 + pub async fn followers(&self) -> Result<Vec<(String, String)>> { 77 + let mut cursor: Option<String> = None; 78 + let mut first = true; 79 + let mut followers = vec![]; 80 + 81 + loop { 82 + if first { 83 + first = false; 84 + } 85 + 86 + let res = self 87 + .agent 88 + .api 89 + .app 90 + .bsky 91 + .graph 92 + .get_followers( 93 + get_followers::ParametersData { 94 + actor: AtIdentifier::Did(Did::from_str(&self.did()).unwrap()), 95 + limit: None, 96 + cursor: cursor, 97 + } 98 + .into(), 99 + ) 100 + .await?; 101 + 102 + cursor = res.cursor.clone(); 103 + 104 + followers.append( 105 + &mut res 106 + .data 107 + .followers 108 + .into_iter() 109 + .map(|e| { 110 + let fb = 111 + parse_aturi(e.viewer.clone().unwrap().followed_by.clone().unwrap()) 112 + .unwrap(); 113 + (e.did.to_string(), fb.cid) 114 + }) 115 + .collect(), 116 + ); 117 + 118 + if cursor.is_none() { 119 + break; 120 + } 121 + } 122 + Ok(followers) 123 + } 124 + 125 + pub async fn send_dm(&self, dest: String, content: String) -> Result<()> { 126 + let p = get_convo_for_members::ParametersData { 127 + members: vec![Did::new(dest).unwrap()], 128 + }; 129 + 130 + let chat_agent = self.agent.api_with_proxy( 131 + Did::from_str(CHAT_PROXY_DID).unwrap(), 132 + AtprotoServiceType::BskyChat, 133 + ); 134 + 135 + let s = chat_agent 136 + .chat 137 + .bsky 138 + .convo 139 + .get_convo_for_members(p.into()) 140 + .await?; 141 + 142 + let rt = RichText::new_with_detect_facets(content.clone()) 143 + .await 144 + .unwrap(); 145 + 146 + let p = send_message::InputData { 147 + convo_id: s.convo.id.clone(), 148 + message: MessageInputData { 149 + embed: None, 150 + facets: rt.facets, 151 + text: rt.text, 152 + } 153 + .into(), 154 + }; 155 + 156 + chat_agent.chat.bsky.convo.send_message(p.into()).await?; 157 + 158 + Ok(()) 159 + } 160 + 161 + pub async fn fetch_record(&self, url: String) -> Result<get_record::Output> { 162 + let aturi = parse_aturi(url)?; 163 + let user_pds = match self.fetch_user(aturi.did.clone()).await? { 164 + Some(u) => u, 165 + None => return Err(anyhow!("no pds found for {}", aturi.did.clone())), 166 + }; 167 + 168 + let agent = BskyAgent::builder() 169 + .config(Config { 170 + endpoint: user_pds.pds, 171 + ..Default::default() 172 + }) 173 + .build() 174 + .await?; 175 + 176 + let record = agent 177 + .api 178 + .com 179 + .atproto 180 + .repo 181 + .get_record( 182 + get_record::ParametersData { 183 + cid: None, 184 + collection: Nsid::new(aturi.repo).unwrap(), 185 + repo: AtIdentifier::from_str(&aturi.did).unwrap(), 186 + rkey: RecordKey::new(aturi.cid).unwrap(), 187 + } 188 + .into(), 189 + ) 190 + .await?; 191 + 192 + Ok(record) 193 + } 194 + 195 + pub async fn fetch_leaflet_document(&self, uri: String) -> Result<LeafletDoc> { 196 + let r = self.fetch_record(uri).await?; 197 + let rj = serde_json::to_value(r.value.clone())?; 198 + let d: LeafletDoc = serde_json::from_value(rj)?; 199 + Ok(d) 200 + } 201 + 202 + pub async fn fetch_user(&self, did: String) -> Result<Option<User>> { 203 + let did = &Did::from_str(&did).map_err(|e| anyhow!(e))?; 204 + let did_doc = self.did_resolver.resolve(did).await?; 205 + 206 + let mut u = User { 207 + ..Default::default() 208 + }; 209 + 210 + for s in did_doc.service.unwrap() { 211 + if s.r#type == "AtprotoPersonalDataServer" { 212 + u.pds = s.service_endpoint.clone(); 213 + } 214 + } 215 + 216 + if u.pds.is_empty() { 217 + return Ok(None); 218 + } 219 + 220 + u.handle = match did_doc.also_known_as.unwrap_or_default().first() { 221 + Some(s) => s 222 + .clone() 223 + .strip_prefix("at://") 224 + .unwrap_or(&s.clone()) 225 + .to_string(), 226 + None => Default::default(), 227 + }; 228 + 229 + Ok(Some(u)) 230 + } 231 + } 232 + 233 + #[derive(Default)] 234 + pub struct User { 235 + pub handle: String, 236 + pub pds: String, 237 + } 238 + 239 + #[derive(Serialize, Deserialize, Debug)] 240 + pub struct LeafletDoc { 241 + pub title: String, 242 + pub author: String, 243 + } 244 + 245 + struct AtURI { 246 + did: String, 247 + repo: String, 248 + cid: String, 249 + } 250 + 251 + fn parse_aturi(uri: String) -> Result<AtURI> { 252 + let uri = uri.strip_prefix("at://").unwrap(); 253 + let us: Vec<String> = uri.split("/").map(|e| e.to_string()).collect(); 254 + 255 + Ok(AtURI { 256 + did: us[0].clone(), 257 + repo: us[1].clone(), 258 + cid: us[2].clone(), 259 + }) 260 + } 261 + 262 + #[derive(Debug, Clone)] 263 + pub enum JetstreamEvent { 264 + Follow { 265 + author: String, 266 + followed: String, 267 + rkey: String, 268 + }, 269 + Unfollow { 270 + author: String, 271 + rkey: String, 272 + }, 273 + LeafletComment { 274 + author: String, 275 + subject: String, 276 + content: String, 277 + parent: Option<String>, 278 + }, 279 + Unknown, 280 + } 281 + 282 + static WANTED_COLLECTIONS: &'static [&str] = &["app.bsky.graph.follow", "pub.leaflet.comment"]; 283 + 284 + pub struct Jetstream {} 285 + 286 + impl Jetstream { 287 + pub fn new( 288 + since: Option<String>, 289 + service_did: String, 290 + send_event_chan: mpsc::Sender<JetstreamEvent>, 291 + ) { 292 + tokio::spawn(async move { 293 + let wanted_collections: Vec<String> = WANTED_COLLECTIONS 294 + .into_iter() 295 + .map(|c| format!("wantedCollections={c}")) 296 + .collect(); 297 + 298 + let url = format!( 299 + "wss://jetstream1.us-west.bsky.network/subscribe?{}", 300 + wanted_collections.join("&") 301 + ); 302 + let url = match since { 303 + Some(s) => format!("{}&cursor={}", url, s), 304 + None => url.to_string(), 305 + }; 306 + 307 + // TODO: how to stop this? select!{}? 308 + let (mut socket, response) = match tungstenite::connect(url) { 309 + Ok(m) => m, 310 + Err(e) => match e { 311 + tungstenite::Error::Http(response) => panic!( 312 + "can't connect, http status code {}: {}", 313 + response.status().as_str(), 314 + String::from_utf8(response.body().as_ref().unwrap().to_vec()).unwrap() 315 + ), 316 + _ => { 317 + panic!("can't connect: {}", e) 318 + } 319 + }, 320 + }; 321 + 322 + log::debug!("Connected to the server"); 323 + log::debug!("Response HTTP code: {}", response.status()); 324 + log::debug!("Response contains the following headers:"); 325 + for (header, _value) in response.headers() { 326 + log::debug!("* {header}"); 327 + } 328 + 329 + loop { 330 + let msg = match socket.read() { 331 + Ok(m) => m, 332 + Err(e) => match e { 333 + tungstenite::Error::Http(response) => panic!( 334 + "can't connect, http status code {}: {}", 335 + response.status().as_str(), 336 + String::from_utf8(response.body().as_ref().unwrap().to_vec()).unwrap() 337 + ), 338 + _ => { 339 + panic!("can't connect: {}", e) 340 + } 341 + }, 342 + }; 343 + 344 + if msg.is_empty() { 345 + continue; 346 + } 347 + 348 + if !msg 349 + .clone() 350 + .into_text() 351 + .unwrap() 352 + .contains(r#""kind":"commit""#) 353 + { 354 + continue; 355 + } 356 + 357 + log::trace!("data: {msg}"); 358 + 359 + let jm: JetstreamEvent = 360 + match serde_json::from_slice::<JetstreamMessage>(&msg.clone().into_data()) { 361 + Ok(jm) => jm, 362 + Err(e) => { 363 + log::error!("message: {}\nerror: {}", msg, e); 364 + continue; // ignore messages we can't decode 365 + } 366 + } 367 + .into(); 368 + 369 + match jm.clone() { 370 + JetstreamEvent::Follow { followed, .. } => { 371 + if followed.clone() != service_did { 372 + continue; 373 + } 374 + } 375 + JetstreamEvent::LeafletComment { .. } => (), 376 + JetstreamEvent::Unfollow { .. } => (), 377 + JetstreamEvent::Unknown => continue, 378 + } 379 + 380 + match send_event_chan.send(jm).await { 381 + Ok(_) => (), 382 + Err(e) => log::error!("could not send jetstream event to consumer: {:?}", e), 383 + } 384 + } 385 + }); 386 + } 387 + } 388 + 389 + #[derive(serde::Deserialize, serde::Serialize, Debug)] 390 + pub struct JetstreamMessage { 391 + did: String, 392 + commit: JetstreamCommit, 393 + } 394 + 395 + impl From<JetstreamMessage> for JetstreamEvent { 396 + fn from(value: JetstreamMessage) -> Self { 397 + match value.commit.operation.as_str() { 398 + "create" => match value.commit.record.unwrap() { 399 + Record::Follow(follow_record) => JetstreamEvent::Follow { 400 + author: value.did, 401 + followed: follow_record.subject, 402 + rkey: value.commit.rkey, 403 + }, 404 + Record::Comment(comment_record) => { 405 + let aturi = parse_aturi(comment_record.subject.clone()).unwrap(); 406 + 407 + JetstreamEvent::LeafletComment { 408 + author: aturi.did, 409 + subject: comment_record.subject, 410 + content: comment_record.plaintext, 411 + parent: comment_record.parent, 412 + } 413 + } 414 + }, 415 + "delete" => JetstreamEvent::Unfollow { 416 + author: value.did, 417 + rkey: value.commit.rkey, 418 + }, 419 + _ => JetstreamEvent::Unknown, 420 + } 421 + } 422 + } 423 + 424 + #[derive(serde::Deserialize, serde::Serialize, Debug)] 425 + pub struct JetstreamCommit { 426 + operation: String, 427 + rkey: String, 428 + collection: String, 429 + record: Option<Record>, 430 + } 431 + 432 + #[derive(serde::Deserialize, serde::Serialize, Debug)] 433 + pub struct FollowRecord { 434 + subject: String, 435 + } 436 + 437 + #[derive(serde::Deserialize, serde::Serialize, Debug)] 438 + pub struct CommentRecord { 439 + subject: String, 440 + plaintext: String, 441 + parent: Option<String>, 442 + } 443 + 444 + #[derive(serde::Deserialize, serde::Serialize, Debug)] 445 + #[serde(tag = "$type")] 446 + pub enum Record { 447 + #[serde(rename = "app.bsky.graph.follow")] 448 + Follow(FollowRecord), 449 + #[serde(rename = "pub.leaflet.comment")] 450 + Comment(CommentRecord), 451 + }
+79
src/database.rs
··· 1 + use std::time::{SystemTime, UNIX_EPOCH}; 2 + 3 + use anyhow::{Ok, Result}; 4 + 5 + const LAST_SEEN_KEY: &str = "last_seen_evt"; 6 + const FOLLOWERS_KEY: &str = "follower"; 7 + const RKEY_KEY: &str = "rkey"; 8 + 9 + pub struct Handle { 10 + i: sled::Db, 11 + } 12 + 13 + impl Handle { 14 + pub fn new<P: AsRef<std::path::Path>>(path: P) -> Result<Self> { 15 + let i = sled::open(path)?; 16 + Ok(Self { i }) 17 + } 18 + 19 + pub fn update_last_seen_evt(&self) -> Result<()> { 20 + self.i.insert( 21 + LAST_SEEN_KEY, 22 + SystemTime::now() 23 + .duration_since(UNIX_EPOCH) 24 + .unwrap() 25 + .as_micros() 26 + .to_string() 27 + .as_bytes(), 28 + )?; 29 + 30 + Ok(()) 31 + } 32 + 33 + pub fn last_seen_evt(&self) -> Result<Option<String>> { 34 + match self.i.get(LAST_SEEN_KEY)? { 35 + Some(s) => Ok(Some(String::from_utf8(s.to_vec())?)), 36 + None => Ok(None), 37 + } 38 + } 39 + 40 + pub fn add_follower(&self, handle: String, rkey: String) -> Result<()> { 41 + let fk = follower_key(handle); 42 + if self.i.contains_key(fk.clone())? { 43 + return Ok(()); 44 + } 45 + 46 + self.i.insert(fk, &[1])?; 47 + self.i.insert(rkey_key(rkey), &[1])?; 48 + 49 + Ok(()) 50 + } 51 + 52 + pub fn unfollow_about_us(&self, rkey: String) -> Result<bool> { 53 + Ok(self.i.contains_key(rkey_key(rkey))?) 54 + } 55 + 56 + pub fn follows_us(&self, handle: String) -> Result<bool> { 57 + Ok(self.i.contains_key(follower_key(handle))?) 58 + } 59 + 60 + pub fn remove_follower(&self, handle: String, rkey: String) -> Result<()> { 61 + let fk = follower_key(handle); 62 + if self.i.contains_key(fk.clone())? { 63 + return Ok(()); 64 + } 65 + 66 + self.i.remove(fk)?; 67 + self.i.remove(rkey_key(rkey))?; 68 + 69 + Ok(()) 70 + } 71 + } 72 + 73 + fn follower_key(handle: String) -> String { 74 + format!("{FOLLOWERS_KEY}_{}", handle) 75 + } 76 + 77 + fn rkey_key(rkey: String) -> String { 78 + format!("{RKEY_KEY}_{}", rkey) 79 + }
src/did.rs

This is a binary file and will not be displayed.

+157
src/main.rs
··· 1 + use std::{path::PathBuf, str::FromStr}; 2 + 3 + use anyhow::Result; 4 + use clap::Parser; 5 + use tokio::sync::mpsc; 6 + 7 + use crate::at::JetstreamEvent; 8 + 9 + mod at; 10 + mod database; 11 + mod did; 12 + 13 + #[derive(clap::Parser, Debug)] 14 + #[command(version, about, long_about = None)] 15 + struct Args { 16 + /// Bot account handle 17 + #[arg(long, env = "LEAFNOTIFS_HANDLE")] 18 + handle: String, 19 + 20 + /// Bot account password 21 + #[arg(long, env = "LEAFNOTIFS_PASSWORD")] 22 + password: String, 23 + 24 + /// Bot PDS 25 + #[arg(long, env = "LEAFNOTIFS_PDS", default_value = "https://bsky.social")] 26 + pds: String, 27 + 28 + /// Database path, if not provided will default to a temporary one 29 + #[arg(long, env = "LEAFNOTIFS_DATABASE_PATH")] 30 + database_path: Option<String>, 31 + } 32 + 33 + #[tokio::main] 34 + async fn main() -> Result<()> { 35 + env_logger::init(); 36 + 37 + let args = Args::parse(); 38 + 39 + let db_path = match args.database_path { 40 + Some(s) => PathBuf::from_str(&s)?, 41 + None => { 42 + let td = tempfile::tempdir()?; 43 + td.path().to_path_buf() 44 + } 45 + }; 46 + 47 + log::info!("Database directory: {}", db_path.display()); 48 + 49 + let db_handle = database::Handle::new(db_path)?; 50 + 51 + let bsky_handle = at::Handle::new( 52 + args.handle 53 + .strip_prefix("@") 54 + .unwrap_or(&args.handle.clone()), 55 + &args.password, 56 + &args.pds, 57 + ) 58 + .await?; 59 + 60 + log::info!( 61 + "acting on @{} ({})", 62 + bsky_handle.handle(), 63 + bsky_handle.did() 64 + ); 65 + 66 + let followers = bsky_handle.followers().await?; 67 + 68 + for (did, follow_record) in followers.iter() { 69 + db_handle.add_follower(did.clone(), follow_record.clone())? 70 + } 71 + 72 + log::info!("registered {} existing followers", followers.len()); 73 + 74 + let (event_tx, mut event_rx) = mpsc::channel(1); 75 + 76 + at::Jetstream::new(db_handle.last_seen_evt()?, bsky_handle.did(), event_tx); 77 + 78 + loop { 79 + let msg = event_rx.recv().await; 80 + if msg.is_none() { 81 + continue; 82 + } 83 + 84 + let msg = msg.unwrap(); 85 + 86 + match handle_message(msg, &db_handle, &bsky_handle).await { 87 + Ok(_) => db_handle.update_last_seen_evt()?, 88 + Err(e) => log::error!("message handling error: {}", e), 89 + } 90 + } 91 + } 92 + 93 + static WELCOME_MESSAGE: &'static str = r#"Hey there! 94 + 95 + From now on I'll send you DMs every time someone comments under one of your @leaflet.pub posts. 96 + 97 + If you want me to stop just unfollow, no hard feelings :]"#; 98 + 99 + async fn handle_message( 100 + msg: JetstreamEvent, 101 + db_handle: &database::Handle, 102 + bsky_handle: &at::Handle, 103 + ) -> Result<()> { 104 + match msg { 105 + at::JetstreamEvent::Follow { author, rkey, .. } => { 106 + log::info!("new follower! {}", author.clone()); 107 + db_handle.add_follower(author.clone(), rkey)?; 108 + bsky_handle 109 + .send_dm(author, WELCOME_MESSAGE.to_owned()) 110 + .await?; 111 + Ok(()) 112 + } 113 + at::JetstreamEvent::Unfollow { author, rkey } => { 114 + if !db_handle.unfollow_about_us(rkey.clone())? { 115 + return Ok(()); 116 + } 117 + 118 + log::info!("{} unfollowed", author); 119 + db_handle.remove_follower(author, rkey)?; 120 + Ok(()) 121 + } 122 + at::JetstreamEvent::LeafletComment { 123 + author, 124 + subject, 125 + content, 126 + parent, 127 + } => { 128 + let doc = bsky_handle.fetch_leaflet_document(subject.clone()).await?; 129 + if !db_handle.follows_us(doc.author.clone())? { 130 + return Ok(()); 131 + } 132 + 133 + let commenting_user = match bsky_handle.fetch_user(author.clone()).await? { 134 + Some(s) => s, 135 + None => return Ok(()), 136 + }; 137 + 138 + let action = match parent { 139 + Some(_) => "replied to a comment", 140 + None => "commented", 141 + }; 142 + 143 + bsky_handle 144 + .send_dm( 145 + doc.author, 146 + format!( 147 + "@{} {action} under\n\"{}\":\n\n{content}", 148 + commenting_user.handle, doc.title 149 + ), 150 + ) 151 + .await?; 152 + 153 + Ok(()) 154 + } 155 + at::JetstreamEvent::Unknown => Ok(()), 156 + } 157 + }