[WIP] A (somewhat barebones) atproto app for creating custom sites without hosting!

Compare changes

Choose any two refs to compare.

-4
.gitignore
··· 1 - server/node_modules/* 2 - server/local.db 3 - server/.env 4 - server/blobs
+34 -7
README.md
··· 2 2 3 3 A (somewhat barebones) atproto app for creating custom sites without hosting! 4 4 5 + > [!CAUTION] 6 + > This software is super duper alpha and not tested thoroughly! Use at your own risk! 7 + 5 8 - Lexicons are located at [`./lexicons`](./lexicons/) 6 9 - Server backend is located at [`./server`](./server/) 7 10 - Upload CLI is located at [`./upload`](./upload/) 8 11 - Web GUI **will be** located at [`./web-gui`](./web-gui/) 9 12 - Fuse tool **will be** located at [`./fuse`](./fuse/) 10 13 11 - TODO: 14 + ## How to: 15 + 16 + **View someones site?** 17 + > Head to `https://<handle>.atcities.dev/` or `https://<did>.did-<method>.atcities.dev/`. 18 + 19 + **Upload your own site?** 20 + > Use the upload cli. Installation guide below. 21 + 22 + **Self host atcities.dev?** 23 + > Clone this repo and setup the `.env` file for `/server`, then run `deno run run` 24 + 25 + ### CLI installation guide. 26 + 27 + 1. Build from source: 28 + Prerequisites: `git` `cargo` `rust` 29 + ```sh 30 + git clone https://tangled.org/@vielle.dev/atcities.dev 31 + cd atcities.dev/upload 32 + cargo build 33 + sudo cp ./target/debug/atcities-upload /bin 34 + # Reload your shell environment 35 + atcities-upload --version 36 + ``` 37 + 38 + ## Todo: 12 39 13 40 - [x] Resolve `handle.host` and `did.did-method.host` domains to records/blobs 14 41 - [x] Backfill network 15 42 - [x] Store did+route -> blob & mime type in database 16 43 - [x] Store blobs for CDN (max ~0.25gb per user) 17 - - [ ] Moderate illegal content or hope that people are niceys 18 - - [ ] Finish CLI tool 19 - - [ ] Sign in via app password 20 - - [ ] Sign in via oAuth (for interactive) 21 - - [ ] Clear old site 22 - - [ ] Upload new site 44 + - [x] Moderate illegal content or hope that people are niceys 45 + (Hope that people are niceys) 46 + - [x] Finish CLI tool 47 + - [x] Sign in via app password 48 + - [x] Clear old site 49 + - [x] Upload new site 23 50 - [ ] Fuse uploader 24 51 - [ ] Web GUI uploader
-356
lexicons/com.atproto.sync.subscribeRepos.json
··· 1 - { 2 - "lexicon": 1, 3 - "id": "com.atproto.sync.subscribeRepos", 4 - "defs": { 5 - "info": { 6 - "type": "object", 7 - "required": [ 8 - "name" 9 - ], 10 - "properties": { 11 - "name": { 12 - "type": "string", 13 - "knownValues": [ 14 - "OutdatedCursor" 15 - ] 16 - }, 17 - "message": { 18 - "type": "string" 19 - } 20 - } 21 - }, 22 - "main": { 23 - "type": "subscription", 24 - "errors": [ 25 - { 26 - "name": "FutureCursor" 27 - }, 28 - { 29 - "name": "ConsumerTooSlow", 30 - "description": "If the consumer of the stream can not keep up with events, and a backlog gets too large, the server will drop the connection." 31 - } 32 - ], 33 - "message": { 34 - "schema": { 35 - "refs": [ 36 - "#commit", 37 - "#sync", 38 - "#identity", 39 - "#account", 40 - "#handle", 41 - "#migrate", 42 - "#tombstone", 43 - "#info" 44 - ], 45 - "type": "union" 46 - } 47 - }, 48 - "parameters": { 49 - "type": "params", 50 - "properties": { 51 - "cursor": { 52 - "type": "integer", 53 - "description": "The last known event seq number to backfill from." 54 - } 55 - } 56 - }, 57 - "description": "Repository event stream, aka Firehose endpoint. Outputs repo commits with diff data, and identity update events, for all repositories on the current server. See the atproto specifications for details around stream sequencing, repo versioning, CAR diff format, and more. Public and does not require auth; implemented by PDS and Relay." 58 - }, 59 - "sync": { 60 - "type": "object", 61 - "required": [ 62 - "seq", 63 - "did", 64 - "blocks", 65 - "rev", 66 - "time" 67 - ], 68 - "properties": { 69 - "did": { 70 - "type": "string", 71 - "format": "did", 72 - "description": "The account this repo event corresponds to. Must match that in the commit object." 73 - }, 74 - "rev": { 75 - "type": "string", 76 - "description": "The rev of the commit. This value must match that in the commit object." 77 - }, 78 - "seq": { 79 - "type": "integer", 80 - "description": "The stream sequence number of this message." 81 - }, 82 - "time": { 83 - "type": "string", 84 - "format": "datetime", 85 - "description": "Timestamp of when this message was originally broadcast." 86 - }, 87 - "blocks": { 88 - "type": "bytes", 89 - "maxLength": 10000, 90 - "description": "CAR file containing the commit, as a block. The CAR header must include the commit block CID as the first 'root'." 91 - } 92 - }, 93 - "description": "Updates the repo to a new state, without necessarily including that state on the firehose. Used to recover from broken commit streams, data loss incidents, or in situations where upstream host does not know recent state of the repository." 94 - }, 95 - "commit": { 96 - "type": "object", 97 - "nullable": [ 98 - "since" 99 - ], 100 - "required": [ 101 - "seq", 102 - "rebase", 103 - "tooBig", 104 - "repo", 105 - "commit", 106 - "rev", 107 - "since", 108 - "blocks", 109 - "ops", 110 - "blobs", 111 - "time" 112 - ], 113 - "properties": { 114 - "ops": { 115 - "type": "array", 116 - "items": { 117 - "ref": "#repoOp", 118 - "type": "ref", 119 - "description": "List of repo mutation operations in this commit (eg, records created, updated, or deleted)." 120 - }, 121 - "maxLength": 200 122 - }, 123 - "rev": { 124 - "type": "string", 125 - "format": "tid", 126 - "description": "The rev of the emitted commit. Note that this information is also in the commit object included in blocks, unless this is a tooBig event." 127 - }, 128 - "seq": { 129 - "type": "integer", 130 - "description": "The stream sequence number of this message." 131 - }, 132 - "repo": { 133 - "type": "string", 134 - "format": "did", 135 - "description": "The repo this event comes from. Note that all other message types name this field 'did'." 136 - }, 137 - "time": { 138 - "type": "string", 139 - "format": "datetime", 140 - "description": "Timestamp of when this message was originally broadcast." 141 - }, 142 - "blobs": { 143 - "type": "array", 144 - "items": { 145 - "type": "cid-link", 146 - "description": "DEPRECATED -- will soon always be empty. List of new blobs (by CID) referenced by records in this commit." 147 - } 148 - }, 149 - "since": { 150 - "type": "string", 151 - "format": "tid", 152 - "description": "The rev of the last emitted commit from this repo (if any)." 153 - }, 154 - "blocks": { 155 - "type": "bytes", 156 - "maxLength": 2000000, 157 - "description": "CAR file containing relevant blocks, as a diff since the previous repo state. The commit must be included as a block, and the commit block CID must be the first entry in the CAR header 'roots' list." 158 - }, 159 - "commit": { 160 - "type": "cid-link", 161 - "description": "Repo commit object CID." 162 - }, 163 - "rebase": { 164 - "type": "boolean", 165 - "description": "DEPRECATED -- unused" 166 - }, 167 - "tooBig": { 168 - "type": "boolean", 169 - "description": "DEPRECATED -- replaced by #sync event and data limits. Indicates that this commit contained too many ops, or data size was too large. Consumers will need to make a separate request to get missing data." 170 - }, 171 - "prevData": { 172 - "type": "cid-link", 173 - "description": "The root CID of the MST tree for the previous commit from this repo (indicated by the 'since' revision field in this message). Corresponds to the 'data' field in the repo commit object. NOTE: this field is effectively required for the 'inductive' version of firehose." 174 - } 175 - }, 176 - "description": "Represents an update of repository state. Note that empty commits are allowed, which include no repo data changes, but an update to rev and signature." 177 - }, 178 - "handle": { 179 - "type": "object", 180 - "required": [ 181 - "seq", 182 - "did", 183 - "handle", 184 - "time" 185 - ], 186 - "properties": { 187 - "did": { 188 - "type": "string", 189 - "format": "did" 190 - }, 191 - "seq": { 192 - "type": "integer" 193 - }, 194 - "time": { 195 - "type": "string", 196 - "format": "datetime" 197 - }, 198 - "handle": { 199 - "type": "string", 200 - "format": "handle" 201 - } 202 - }, 203 - "description": "DEPRECATED -- Use #identity event instead" 204 - }, 205 - "repoOp": { 206 - "type": "object", 207 - "nullable": [ 208 - "cid" 209 - ], 210 - "required": [ 211 - "action", 212 - "path", 213 - "cid" 214 - ], 215 - "properties": { 216 - "cid": { 217 - "type": "cid-link", 218 - "description": "For creates and updates, the new record CID. For deletions, null." 219 - }, 220 - "path": { 221 - "type": "string" 222 - }, 223 - "prev": { 224 - "type": "cid-link", 225 - "description": "For updates and deletes, the previous record CID (required for inductive firehose). For creations, field should not be defined." 226 - }, 227 - "action": { 228 - "type": "string", 229 - "knownValues": [ 230 - "create", 231 - "update", 232 - "delete" 233 - ] 234 - } 235 - }, 236 - "description": "A repo operation, ie a mutation of a single record." 237 - }, 238 - "account": { 239 - "type": "object", 240 - "required": [ 241 - "seq", 242 - "did", 243 - "time", 244 - "active" 245 - ], 246 - "properties": { 247 - "did": { 248 - "type": "string", 249 - "format": "did" 250 - }, 251 - "seq": { 252 - "type": "integer" 253 - }, 254 - "time": { 255 - "type": "string", 256 - "format": "datetime" 257 - }, 258 - "active": { 259 - "type": "boolean", 260 - "description": "Indicates that the account has a repository which can be fetched from the host that emitted this event." 261 - }, 262 - "status": { 263 - "type": "string", 264 - "description": "If active=false, this optional field indicates a reason for why the account is not active.", 265 - "knownValues": [ 266 - "takendown", 267 - "suspended", 268 - "deleted", 269 - "deactivated", 270 - "desynchronized", 271 - "throttled" 272 - ] 273 - } 274 - }, 275 - "description": "Represents a change to an account's status on a host (eg, PDS or Relay). The semantics of this event are that the status is at the host which emitted the event, not necessarily that at the currently active PDS. Eg, a Relay takedown would emit a takedown with active=false, even if the PDS is still active." 276 - }, 277 - "migrate": { 278 - "type": "object", 279 - "nullable": [ 280 - "migrateTo" 281 - ], 282 - "required": [ 283 - "seq", 284 - "did", 285 - "migrateTo", 286 - "time" 287 - ], 288 - "properties": { 289 - "did": { 290 - "type": "string", 291 - "format": "did" 292 - }, 293 - "seq": { 294 - "type": "integer" 295 - }, 296 - "time": { 297 - "type": "string", 298 - "format": "datetime" 299 - }, 300 - "migrateTo": { 301 - "type": "string" 302 - } 303 - }, 304 - "description": "DEPRECATED -- Use #account event instead" 305 - }, 306 - "identity": { 307 - "type": "object", 308 - "required": [ 309 - "seq", 310 - "did", 311 - "time" 312 - ], 313 - "properties": { 314 - "did": { 315 - "type": "string", 316 - "format": "did" 317 - }, 318 - "seq": { 319 - "type": "integer" 320 - }, 321 - "time": { 322 - "type": "string", 323 - "format": "datetime" 324 - }, 325 - "handle": { 326 - "type": "string", 327 - "format": "handle", 328 - "description": "The current handle for the account, or 'handle.invalid' if validation fails. This field is optional, might have been validated or passed-through from an upstream source. Semantics and behaviors for PDS vs Relay may evolve in the future; see atproto specs for more details." 329 - } 330 - }, 331 - "description": "Represents a change to an account's identity. Could be an updated handle, signing key, or pds hosting endpoint. Serves as a prod to all downstream services to refresh their identity cache." 332 - }, 333 - "tombstone": { 334 - "type": "object", 335 - "required": [ 336 - "seq", 337 - "did", 338 - "time" 339 - ], 340 - "properties": { 341 - "did": { 342 - "type": "string", 343 - "format": "did" 344 - }, 345 - "seq": { 346 - "type": "integer" 347 - }, 348 - "time": { 349 - "type": "string", 350 - "format": "datetime" 351 - } 352 - }, 353 - "description": "DEPRECATED -- Use #account event instead" 354 - } 355 - } 356 - }
+4
server/.gitignore
··· 1 + node_modules/* 2 + local.db 3 + .env 4 + blobs
+2
server/deno.json
··· 1 1 { 2 2 "tasks": { 3 3 "dev": "deno run --watch --allow-net --allow-env --allow-sys --allow-read=/usr/bin/ldd,./blobs,./src --allow-write=./blobs --allow-ffi --env-file src/index.ts", 4 + "run": "deno run --allow-net --allow-env --allow-sys --allow-read=/usr/bin/ldd,./blobs,./src --allow-write=./blobs --allow-ffi --env-file src/index.ts", 4 5 "lexgen": "deno run --allow-env --allow-sys --allow-read=.. --allow-write=./src/lexicons --no-prompt @atcute/lex-cli generate -c ./lex.config.js && cat ./src/lexicons/index.ts | sed \"s/.js/.ts/\" > ./src/lexicons/index.ts", 5 6 "dk": "deno run -A --node-modules-dir npm:drizzle-kit" 6 7 }, ··· 11 12 "@atcute/client": "npm:@atcute/client@^4.0.3", 12 13 "@atcute/lex-cli": "npm:@atcute/lex-cli@^2.2.0", 13 14 "@atcute/lexicons": "npm:@atcute/lexicons@^1.1.1", 15 + "@atproto-labs/fetch-node": "npm:@atproto-labs/fetch-node@^0.1.10", 14 16 "@libsql/client": "npm:@libsql/client@^0.15.15", 15 17 "drizzle-kit": "npm:drizzle-kit@^0.31.5", 16 18 "drizzle-orm": "npm:drizzle-orm@^0.44.6"
+26
server/deno.lock
··· 7 7 "npm:@atcute/identity-resolver@^1.1.3": "1.1.3_@atcute+identity@1.1.0", 8 8 "npm:@atcute/lex-cli@^2.2.0": "2.2.0_@badrap+valita@0.4.6", 9 9 "npm:@atcute/lexicons@^1.1.1": "1.1.1", 10 + "npm:@atproto-labs/fetch-node@~0.1.10": "0.1.10", 10 11 "npm:@libsql/client@~0.15.15": "0.15.15", 11 12 "npm:drizzle-kit@*": "0.31.5_esbuild@0.25.10", 12 13 "npm:drizzle-kit@~0.31.5": "0.31.5_esbuild@0.25.10", ··· 94 95 "dependencies": [ 95 96 "@badrap/valita" 96 97 ] 98 + }, 99 + "@atproto-labs/fetch-node@0.1.10": { 100 + "integrity": "sha512-o7hGaonA71A6p7O107VhM6UBUN/g9tTyYohMp1q0Kf6xQ4npnuZYRSHSf2g6reSfGQJ1GoFNjBObETTT1ge/jQ==", 101 + "dependencies": [ 102 + "@atproto-labs/fetch", 103 + "@atproto-labs/pipe", 104 + "ipaddr.js", 105 + "undici" 106 + ] 107 + }, 108 + "@atproto-labs/fetch@0.2.3": { 109 + "integrity": "sha512-NZtbJOCbxKUFRFKMpamT38PUQMY0hX0p7TG5AEYOPhZKZEP7dHZ1K2s1aB8MdVH0qxmqX7nQleNrrvLf09Zfdw==", 110 + "dependencies": [ 111 + "@atproto-labs/pipe" 112 + ] 113 + }, 114 + "@atproto-labs/pipe@0.1.1": { 115 + "integrity": "sha512-hdNw2oUs2B6BN1lp+32pF7cp8EMKuIN5Qok2Vvv/aOpG/3tNSJ9YkvfI0k6Zd188LeDDYRUpYpxcoFIcGH/FNg==" 97 116 }, 98 117 "@badrap/valita@0.4.6": { 99 118 "integrity": "sha512-4kdqcjyxo/8RQ8ayjms47HCWZIF5981oE5nIenbfThKDxWXtEHKipAOWlflpPJzZx9y/JWYQkp18Awr7VuepFg==" ··· 583 602 "resolve-pkg-maps" 584 603 ] 585 604 }, 605 + "ipaddr.js@2.2.0": { 606 + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==" 607 + }, 586 608 "js-base64@3.7.8": { 587 609 "integrity": "sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==" 588 610 }, ··· 647 669 "undici-types@7.10.0": { 648 670 "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==" 649 671 }, 672 + "undici@6.22.0": { 673 + "integrity": "sha512-hU/10obOIu62MGYjdskASR3CUAiYaFTtC9Pa6vHyf//mAipSvSQg6od2CnJswq7fvzNS3zJhxoRkgNVaHurWKw==" 674 + }, 650 675 "web-streams-polyfill@3.3.3": { 651 676 "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==" 652 677 }, ··· 662 687 "npm:@atcute/identity-resolver@^1.1.3", 663 688 "npm:@atcute/lex-cli@^2.2.0", 664 689 "npm:@atcute/lexicons@^1.1.1", 690 + "npm:@atproto-labs/fetch-node@~0.1.10", 665 691 "npm:@libsql/client@~0.15.15", 666 692 "npm:drizzle-kit@~0.31.5", 667 693 "npm:drizzle-orm@~0.44.6"
+21 -14
server/src/backfill/blob.ts
··· 1 - import { Client, simpleFetchHandler } from "@atcute/client"; 2 - import { getPds, MAX_SITE_SIZE } from "../utils.ts"; 1 + import { Client } from "@atcute/client"; 2 + import { fetchHandler, getPds, MAX_SITE_SIZE } from "../utils.ts"; 3 3 4 4 export default async function ( 5 5 did: `did:${"plc" | "web"}:${string}`, 6 6 cid: string 7 7 ): Promise<Blob> { 8 + // if the user has been manually taken down (cache dir deleted and replaced with empty file) 9 + // this errors out for quick exit 10 + // saving the round trip to resolve the pds and blob. 11 + await Deno.mkdir(`./blobs/${did}`, { recursive: true }); 12 + 8 13 const pds = await getPds(did); 9 14 if (!pds) throw "PDS not found"; 10 15 11 16 const { data, ok } = await new Client({ 12 - handler: simpleFetchHandler({ service: pds }), 17 + handler: fetchHandler({ service: pds }), 13 18 }).get("com.atproto.sync.getBlob", { 14 19 params: { 15 20 did, ··· 20 25 21 26 if (!ok) throw `${data.error}`; 22 27 23 - // check for CSAM etc here 24 - 25 - await Deno.mkdir(`./blobs/${did}`, { recursive: true }); 26 - let size = 0; 27 - for await (const file of Deno.readDir(`./blobs/${did}`)) { 28 - size += (await Deno.stat(`./blobs/${did}/${file.name}`)).size; 28 + // if the file size cant be calculated or the file cant be written, still return the blob 29 + try { 30 + let size = 0; 31 + for await (const file of Deno.readDir(`./blobs/${did}`)) { 32 + size += (await Deno.stat(`./blobs/${did}/${file.name}`)).size; 33 + } 34 + // only write if total stays below max site size 35 + if (size + data.size <= MAX_SITE_SIZE) 36 + await Deno.writeFile(`./blobs/${did}/${cid}`, await data.bytes(), { 37 + createNew: true, 38 + }); 39 + } catch (e) { 40 + console.warn(e); 29 41 } 30 - // only write if total stays below max site size 31 - if (size + data.size <= MAX_SITE_SIZE) 32 - await Deno.writeFile(`./blobs/${did}/${cid}`, await data.bytes(), { 33 - createNew: true, 34 - }); 35 42 36 43 return data; 37 44 }
+6 -21
server/src/backfill/index.ts
··· 2 2 import { routes } from "../db/schema.ts"; 3 3 import * as schema from "../db/schema.ts"; 4 4 import { db as db_type } from "../utils.ts"; 5 - import { Client, simpleFetchHandler } from "@atcute/client"; 6 5 import oldRecords from "./old-records.ts"; 7 6 import newRecords from "./new-records.ts"; 8 7 ··· 10 9 Deno.env.get("DB_FILE_NAME")! || 11 10 (() => { 12 11 throw "DB_FILE_NAME not set"; 13 - })(), 12 + })() 14 13 ); 15 14 16 - // we block access to the database till we've set up listeners etc 17 - // set an initial value for ts sake; this will set asap 18 - let res: (value: db_type) => void = (v) => console.log("failed to set", v); 19 - export default new Promise<db_type>((p_res) => { 20 - res = p_res; 21 - }); 22 - 23 - // clear old records 15 + // clear old records & blobs 24 16 // accounts could have deleted their sites or anything 25 17 // so we should just nuke them 18 + // blobs could be kept but would be a nightmare 26 19 await db.delete(routes); 20 + await Deno.remove("./blobs", { recursive: true }); 27 21 28 - const relay = new Client({ 29 - handler: simpleFetchHandler({ 30 - service: Deno.env.get("ATPROTO_RELAY") || 31 - (() => { 32 - throw "ATPROTO_RELAY not set"; 33 - })(), 34 - }), 35 - }); 36 - 37 - oldRecords(db, relay); 22 + oldRecords(db); 38 23 newRecords(db); 39 24 40 - res(db); 25 + export default db;
+28 -42
server/src/backfill/new-records.ts
··· 1 - import { db, getPds, isDid, rkeyToUrl } from "../utils.ts"; 1 + import { db, getPds, isDid, rkeyToUrl, fetchHandler } from "../utils.ts"; 2 2 import { decodeFirst } from "@atcute/cbor"; 3 - import { 4 - ComAtprotoSyncSubscribeRepos, 5 - DevAtcitiesRoute, 6 - } from "../lexicons/index.ts"; 3 + import { DevAtcitiesRoute } from "../lexicons/index.ts"; 7 4 import { is } from "@atcute/lexicons"; 8 - import { Client, simpleFetchHandler } from "@atcute/client"; 5 + import { ComAtprotoSyncSubscribeRepos } from "@atcute/atproto"; 6 + import { Client } from "@atcute/client"; 9 7 import { routes } from "../db/schema.ts"; 10 8 import { and, eq } from "drizzle-orm"; 11 9 12 10 const ErrorEvent = Symbol("error event"); 13 - export default async function newRecords(db: db) { 11 + export default function newRecords(db: db) { 14 12 // https://pdsls.dev/at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.subscribeRepos 15 13 const ws = new WebSocket( 16 14 `${ ··· 27 25 ws.addEventListener("error", (ev) => { 28 26 throw ev; 29 27 }); 28 + ws.addEventListener("open", () => console.log("Listening for new events.")); 30 29 31 30 try { 32 31 ws.addEventListener("message", async (ev) => { ··· 43 42 throw ErrorEvent; 44 43 } 45 44 45 + // we only care about commits 46 + // identity events and similar are irrelevant 46 47 if (!is(ComAtprotoSyncSubscribeRepos.commitSchema, payload)) { 47 48 return; 48 49 } ··· 50 51 console.warn("Invalid did:", payload.repo); 51 52 return; 52 53 } 53 - 54 - const pdsClient = (() => { 55 - let client: Client | undefined; 56 - return async () => { 57 - if (client) { 58 - return client; 59 - } 60 - if (!isDid(payload.repo)) { 61 - console.warn("Invalid did:", payload.repo); 62 - return; 63 - } 64 - 65 - const pds = await getPds(payload.repo); 66 - if (!pds) { 67 - return; 68 - } 69 - client = new Client({ 70 - handler: simpleFetchHandler({ 71 - service: pds, 72 - }), 73 - }); 54 + const pds = await getPds(payload.repo); 55 + if (!pds) { 56 + return; 57 + } 74 58 75 - return client; 76 - }; 77 - })(); 59 + const client = new Client({ 60 + handler: fetchHandler({ 61 + service: pds, 62 + }), 63 + }); 78 64 79 65 for (const op of payload.ops) { 80 66 const [collection, rkey] = op.path.split("/"); 81 - const path = rkeyToUrl(rkey); 82 - if (!path) { 83 - console.warn("rkey not valid!"); 67 + if (!collection || !rkey) { 68 + console.warn("Invalid path", op.path); 84 69 continue; 85 70 } 71 + const path = rkeyToUrl(rkey); 72 + if (!path) continue; 86 73 if (collection !== "dev.atcities.route") continue; 74 + 87 75 switch (op.action) { 88 76 case "create": 89 77 case "update": { 90 - const client = await pdsClient(); 91 - if (!client) { 92 - console.warn("could not resolve pds for", payload.repo); 93 - return; 94 - } 78 + // hydrate data 95 79 const { data, ok } = await client.get( 96 80 "com.atproto.repo.getRecord", 97 81 { ··· 109 93 } 110 94 111 95 if (!is(DevAtcitiesRoute.mainSchema, data.value)) { 112 - console.warn("Invalid record"); 96 + console.warn( 97 + "Invalid record:", 98 + `at://${payload.repo}/dev.atcities.route.${rkey}` 99 + ); 113 100 continue; 114 101 } 115 102 116 103 if (data.value.page.$type !== "dev.atcities.route#blob") { 117 - console.warn("Unknown page type"); 118 104 continue; 119 105 } 120 106 107 + // if this page exists in db, get the id so it can be replaced 121 108 const id = ( 122 109 await db 123 110 .select({ ··· 198 185 if (e === ErrorEvent) newRecords(db); 199 186 else throw e; 200 187 } 201 - ws.addEventListener("open", () => console.log("subscribed!!")); 202 188 }
+22 -6
server/src/backfill/old-records.ts
··· 1 - import { Client, simpleFetchHandler } from "@atcute/client"; 2 - import { db, getPds, isDid, rkeyToUrl } from "../utils.ts"; 1 + import { Client } from "@atcute/client"; 2 + import { db, fetchHandler, getPds, isDid, rkeyToUrl } from "../utils.ts"; 3 3 import { is } from "@atcute/lexicons"; 4 4 import { DevAtcitiesRoute } from "../lexicons/index.ts"; 5 5 import { routes } from "../db/schema.ts"; 6 6 7 - async function index(did: `did:${"web" | "plc"}:${string}`, db: db) { 7 + async function indexUser(did: `did:${"web" | "plc"}:${string}`, db: db) { 8 8 const pds = await getPds(did); 9 9 if (!pds) return console.error(did, "could not be resolved to a pds."); 10 10 const pdsClient = new Client({ 11 - handler: simpleFetchHandler({ service: pds }), 11 + handler: fetchHandler({ service: pds }), 12 12 }); 13 + 13 14 let cursor: string | undefined; 14 15 while (true) { 15 16 const { data, ok } = await pdsClient.get("com.atproto.repo.listRecords", { ··· 27 28 28 29 for (const record of data.records) { 29 30 if (is(DevAtcitiesRoute.mainSchema, record.value)) { 31 + // ignore non blob page values 32 + // this will be expanded in future 30 33 if (record.value.page.$type === "dev.atcities.route#blob") { 31 34 const url = rkeyToUrl(record.uri.split("/")[4]); 32 35 if (!url) continue; ··· 49 52 } 50 53 } 51 54 52 - export default async function (db: db, relay: Client) { 55 + export default async function (db: db) { 56 + const relay = new Client({ 57 + handler: fetchHandler({ 58 + service: 59 + Deno.env.get("ATPROTO_RELAY") || 60 + (() => { 61 + throw "ATPROTO_RELAY not set"; 62 + })(), 63 + }), 64 + }); 65 + 53 66 let repos: `did:${string}:${string}`[] = []; 54 67 let cursor: string | undefined; 55 68 while (true) { ··· 72 85 if (!cursor) break; 73 86 } 74 87 88 + const pending: Promise<unknown>[] = []; 75 89 for (const i in repos) { 76 90 const did = repos[i]; 77 91 console.log(`indexing ${Number(i) + 1}/${repos.length} ${did}`); 78 - if (isDid(did)) index(did, db); 92 + if (isDid(did)) pending.push(indexUser(did, db)); 79 93 } 94 + await Promise.all(pending); 95 + console.log("Finished backfilling."); 80 96 }
+7 -7
server/src/index.ts
··· 37 37 req, 38 38 isDidSubdomain 39 39 ? { 40 - did: `did:${subdomain.at(-1) === "did-plc" ? "plc" : "web"}:${ 41 - subdomain.slice(0, -1).join(".") 42 - }`, 43 - } 40 + did: `did:${subdomain.at(-1) === "did-plc" ? "plc" : "web"}:${subdomain 41 + .slice(0, -1) 42 + .join(".")}`, 43 + } 44 44 : { 45 - handle: subdomain.join(".") as `${string}.${string}`, 46 - }, 45 + handle: subdomain.join(".") as `${string}.${string}`, 46 + } 47 47 ); 48 48 return new Response(res.body, { 49 49 ...res, ··· 58 58 `Could not resolve domain "${subdomain.join(".")}.${ROOT_DOMAIN}"`, 59 59 { 60 60 status: 404, 61 - }, 61 + } 62 62 ); 63 63 });
-1
server/src/lexicons/index.ts
··· 1 - export * as ComAtprotoSyncSubscribeRepos from "./types/com/atproto/sync/subscribeRepos.ts"; 2 1 export * as DevAtcitiesRoute from "./types/dev/atcities/route.ts";
-184
server/src/lexicons/types/com/atproto/sync/subscribeRepos.ts
··· 1 - import type {} from "@atcute/lexicons"; 2 - import * as v from "@atcute/lexicons/validations"; 3 - import type {} from "@atcute/lexicons/ambient"; 4 - 5 - const _accountSchema = /*#__PURE__*/ v.object({ 6 - $type: /*#__PURE__*/ v.optional( 7 - /*#__PURE__*/ v.literal("com.atproto.sync.subscribeRepos#account"), 8 - ), 9 - active: /*#__PURE__*/ v.boolean(), 10 - did: /*#__PURE__*/ v.didString(), 11 - seq: /*#__PURE__*/ v.integer(), 12 - status: /*#__PURE__*/ v.optional( 13 - /*#__PURE__*/ v.string< 14 - | "deactivated" 15 - | "deleted" 16 - | "desynchronized" 17 - | "suspended" 18 - | "takendown" 19 - | "throttled" 20 - | (string & {}) 21 - >(), 22 - ), 23 - time: /*#__PURE__*/ v.datetimeString(), 24 - }); 25 - const _commitSchema = /*#__PURE__*/ v.object({ 26 - $type: /*#__PURE__*/ v.optional( 27 - /*#__PURE__*/ v.literal("com.atproto.sync.subscribeRepos#commit"), 28 - ), 29 - blobs: /*#__PURE__*/ v.array(/*#__PURE__*/ v.cidLink()), 30 - blocks: /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.bytes(), [ 31 - /*#__PURE__*/ v.bytesSize(0, 2000000), 32 - ]), 33 - commit: /*#__PURE__*/ v.cidLink(), 34 - get ops() { 35 - return /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.array(repoOpSchema), [ 36 - /*#__PURE__*/ v.arrayLength(0, 200), 37 - ]); 38 - }, 39 - prevData: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidLink()), 40 - rebase: /*#__PURE__*/ v.boolean(), 41 - repo: /*#__PURE__*/ v.didString(), 42 - rev: /*#__PURE__*/ v.tidString(), 43 - seq: /*#__PURE__*/ v.integer(), 44 - since: /*#__PURE__*/ v.nullable(/*#__PURE__*/ v.tidString()), 45 - time: /*#__PURE__*/ v.datetimeString(), 46 - tooBig: /*#__PURE__*/ v.boolean(), 47 - }); 48 - const _handleSchema = /*#__PURE__*/ v.object({ 49 - $type: /*#__PURE__*/ v.optional( 50 - /*#__PURE__*/ v.literal("com.atproto.sync.subscribeRepos#handle"), 51 - ), 52 - did: /*#__PURE__*/ v.didString(), 53 - handle: /*#__PURE__*/ v.handleString(), 54 - seq: /*#__PURE__*/ v.integer(), 55 - time: /*#__PURE__*/ v.datetimeString(), 56 - }); 57 - const _identitySchema = /*#__PURE__*/ v.object({ 58 - $type: /*#__PURE__*/ v.optional( 59 - /*#__PURE__*/ v.literal("com.atproto.sync.subscribeRepos#identity"), 60 - ), 61 - did: /*#__PURE__*/ v.didString(), 62 - handle: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.handleString()), 63 - seq: /*#__PURE__*/ v.integer(), 64 - time: /*#__PURE__*/ v.datetimeString(), 65 - }); 66 - const _infoSchema = /*#__PURE__*/ v.object({ 67 - $type: /*#__PURE__*/ v.optional( 68 - /*#__PURE__*/ v.literal("com.atproto.sync.subscribeRepos#info"), 69 - ), 70 - message: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()), 71 - name: /*#__PURE__*/ v.string<"OutdatedCursor" | (string & {})>(), 72 - }); 73 - const _mainSchema = /*#__PURE__*/ v.subscription( 74 - "com.atproto.sync.subscribeRepos", 75 - { 76 - params: /*#__PURE__*/ v.object({ 77 - cursor: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.integer()), 78 - }), 79 - get message() { 80 - return /*#__PURE__*/ v.variant([ 81 - accountSchema, 82 - commitSchema, 83 - handleSchema, 84 - identitySchema, 85 - infoSchema, 86 - migrateSchema, 87 - syncSchema, 88 - tombstoneSchema, 89 - ]); 90 - }, 91 - }, 92 - ); 93 - const _migrateSchema = /*#__PURE__*/ v.object({ 94 - $type: /*#__PURE__*/ v.optional( 95 - /*#__PURE__*/ v.literal("com.atproto.sync.subscribeRepos#migrate"), 96 - ), 97 - did: /*#__PURE__*/ v.didString(), 98 - migrateTo: /*#__PURE__*/ v.nullable(/*#__PURE__*/ v.string()), 99 - seq: /*#__PURE__*/ v.integer(), 100 - time: /*#__PURE__*/ v.datetimeString(), 101 - }); 102 - const _repoOpSchema = /*#__PURE__*/ v.object({ 103 - $type: /*#__PURE__*/ v.optional( 104 - /*#__PURE__*/ v.literal("com.atproto.sync.subscribeRepos#repoOp"), 105 - ), 106 - action: /*#__PURE__*/ v.string< 107 - "create" | "delete" | "update" | (string & {}) 108 - >(), 109 - cid: /*#__PURE__*/ v.nullable(/*#__PURE__*/ v.cidLink()), 110 - path: /*#__PURE__*/ v.string(), 111 - prev: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.cidLink()), 112 - }); 113 - const _syncSchema = /*#__PURE__*/ v.object({ 114 - $type: /*#__PURE__*/ v.optional( 115 - /*#__PURE__*/ v.literal("com.atproto.sync.subscribeRepos#sync"), 116 - ), 117 - blocks: /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.bytes(), [ 118 - /*#__PURE__*/ v.bytesSize(0, 10000), 119 - ]), 120 - did: /*#__PURE__*/ v.didString(), 121 - rev: /*#__PURE__*/ v.string(), 122 - seq: /*#__PURE__*/ v.integer(), 123 - time: /*#__PURE__*/ v.datetimeString(), 124 - }); 125 - const _tombstoneSchema = /*#__PURE__*/ v.object({ 126 - $type: /*#__PURE__*/ v.optional( 127 - /*#__PURE__*/ v.literal("com.atproto.sync.subscribeRepos#tombstone"), 128 - ), 129 - did: /*#__PURE__*/ v.didString(), 130 - seq: /*#__PURE__*/ v.integer(), 131 - time: /*#__PURE__*/ v.datetimeString(), 132 - }); 133 - 134 - type account$schematype = typeof _accountSchema; 135 - type commit$schematype = typeof _commitSchema; 136 - type handle$schematype = typeof _handleSchema; 137 - type identity$schematype = typeof _identitySchema; 138 - type info$schematype = typeof _infoSchema; 139 - type main$schematype = typeof _mainSchema; 140 - type migrate$schematype = typeof _migrateSchema; 141 - type repoOp$schematype = typeof _repoOpSchema; 142 - type sync$schematype = typeof _syncSchema; 143 - type tombstone$schematype = typeof _tombstoneSchema; 144 - 145 - export interface accountSchema extends account$schematype {} 146 - export interface commitSchema extends commit$schematype {} 147 - export interface handleSchema extends handle$schematype {} 148 - export interface identitySchema extends identity$schematype {} 149 - export interface infoSchema extends info$schematype {} 150 - export interface mainSchema extends main$schematype {} 151 - export interface migrateSchema extends migrate$schematype {} 152 - export interface repoOpSchema extends repoOp$schematype {} 153 - export interface syncSchema extends sync$schematype {} 154 - export interface tombstoneSchema extends tombstone$schematype {} 155 - 156 - export const accountSchema = _accountSchema as accountSchema; 157 - export const commitSchema = _commitSchema as commitSchema; 158 - export const handleSchema = _handleSchema as handleSchema; 159 - export const identitySchema = _identitySchema as identitySchema; 160 - export const infoSchema = _infoSchema as infoSchema; 161 - export const mainSchema = _mainSchema as mainSchema; 162 - export const migrateSchema = _migrateSchema as migrateSchema; 163 - export const repoOpSchema = _repoOpSchema as repoOpSchema; 164 - export const syncSchema = _syncSchema as syncSchema; 165 - export const tombstoneSchema = _tombstoneSchema as tombstoneSchema; 166 - 167 - export interface Account extends v.InferInput<typeof accountSchema> {} 168 - export interface Commit extends v.InferInput<typeof commitSchema> {} 169 - export interface Handle extends v.InferInput<typeof handleSchema> {} 170 - export interface Identity extends v.InferInput<typeof identitySchema> {} 171 - export interface Info extends v.InferInput<typeof infoSchema> {} 172 - export interface Migrate extends v.InferInput<typeof migrateSchema> {} 173 - export interface RepoOp extends v.InferInput<typeof repoOpSchema> {} 174 - export interface Sync extends v.InferInput<typeof syncSchema> {} 175 - export interface Tombstone extends v.InferInput<typeof tombstoneSchema> {} 176 - 177 - export interface $params extends v.InferInput<mainSchema["params"]> {} 178 - export type $message = v.InferInput<mainSchema["message"]>; 179 - 180 - declare module "@atcute/lexicons/ambient" { 181 - interface XRPCSubscriptions { 182 - "com.atproto.sync.subscribeRepos": mainSchema; 183 - } 184 - }
+4 -1
server/src/routes/user.ts
··· 106 106 console.error(e); 107 107 return new Response(`${ascii} 108 108 109 - This page couldn't be resolved. Either the blob does not exist, or contained illegal content. 109 + This page could not be resolved. Either: 110 + - The user has no PDS 111 + - The blob does not exist 112 + - The user has been manually hidden for uploading illegal content. 110 113 `); 111 114 } 112 115 }
+25 -3
server/src/utils.ts
··· 6 6 PlcDidDocumentResolver, 7 7 WebDidDocumentResolver, 8 8 } from "@atcute/identity-resolver"; 9 + import { FetchHandler, SimpleFetchHandlerOptions } from "@atcute/client"; 10 + import { safeFetchWrap } from "@atproto-labs/fetch-node"; 9 11 10 12 export type db = LibSQLDatabase<typeof schema> & { 11 13 $client: Client; ··· 37 39 web: new WebDidDocumentResolver(), 38 40 }, 39 41 }); 42 + 43 + export const fetchHandler: ({ 44 + service, 45 + }: SimpleFetchHandlerOptions) => FetchHandler = ({ 46 + service, 47 + }: SimpleFetchHandlerOptions): FetchHandler => { 48 + const safeFetch = safeFetchWrap(); 49 + return async (pathname, init) => { 50 + const url = new URL(pathname, service); 51 + return await safeFetch(url, init); 52 + }; 53 + }; 40 54 41 55 export async function getPds( 42 56 did: `did:${"plc" | "web"}:${string}` ··· 93 107 */ 94 108 export function urlToRkey(url: string): string | undefined { 95 109 // contains 0-9A-Za-z + special valid chars and / seperator. also can contain %XX with XX being hex 96 - if (!url.match(/^([a-zA-Z0-9/\-._~!$&'()*+,;=:@]|(%[0-9a-fA-F]{2}))*$/gm)) { 110 + if ( 111 + !url.match(/^(?:[a-zA-Z0-9/\-._~!$&'()*+,;=:@]|(?:%[0-9a-fA-F]{2}))*$/gm) 112 + ) { 97 113 return; 98 114 } 99 115 return ( ··· 122 138 * @returns {string | undefined} undefined when input is invalid 123 139 */ 124 140 export function rkeyToUrl(rkey: string): string | undefined { 125 - // contains 0-9A-Za-z .-_:~ 126 - if (!rkey.match(/^[A-Za-z0-9.\-_:~]*$/gm)) return; 141 + // contains 0-9A-Za-z .-_~ 142 + // or any valid colon escape sequence 143 + if ( 144 + !rkey.match( 145 + /^(?:[A-Za-z0-9.\-_~]|(?:::)|(?::~)|(?::21)|(?::24)|(?::26)|(?::27)|(?::28)|(?::29)|(?::2A)|(?::2B)|(?::2C)|(?::3A)|(?::3B)|(?::3D)|(?::40))*$/gm 146 + ) 147 + ) 148 + return; 127 149 return rkey 128 150 .replaceAll("::", "/") 129 151 .replaceAll(":~", "%")
+4435
upload/Cargo.lock
··· 3 3 version = 4 4 4 5 5 [[package]] 6 + name = "abnf" 7 + version = "0.13.0" 8 + source = "registry+https://github.com/rust-lang/crates.io-index" 9 + checksum = "087113bd50d9adce24850eed5d0476c7d199d532fce8fab5173650331e09033a" 10 + dependencies = [ 11 + "abnf-core", 12 + "nom", 13 + ] 14 + 15 + [[package]] 16 + name = "abnf-core" 17 + version = "0.5.0" 18 + source = "registry+https://github.com/rust-lang/crates.io-index" 19 + checksum = "c44e09c43ae1c368fb91a03a566472d0087c26cf7e1b9e8e289c14ede681dd7d" 20 + dependencies = [ 21 + "nom", 22 + ] 23 + 24 + [[package]] 25 + name = "addr2line" 26 + version = "0.25.1" 27 + source = "registry+https://github.com/rust-lang/crates.io-index" 28 + checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" 29 + dependencies = [ 30 + "gimli", 31 + ] 32 + 33 + [[package]] 34 + name = "adler2" 35 + version = "2.0.1" 36 + source = "registry+https://github.com/rust-lang/crates.io-index" 37 + checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" 38 + 39 + [[package]] 40 + name = "adler32" 41 + version = "1.2.0" 42 + source = "registry+https://github.com/rust-lang/crates.io-index" 43 + checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" 44 + 45 + [[package]] 46 + name = "aho-corasick" 47 + version = "1.1.3" 48 + source = "registry+https://github.com/rust-lang/crates.io-index" 49 + checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 50 + dependencies = [ 51 + "memchr", 52 + ] 53 + 54 + [[package]] 55 + name = "aliasable" 56 + version = "0.1.3" 57 + source = "registry+https://github.com/rust-lang/crates.io-index" 58 + checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" 59 + 60 + [[package]] 61 + name = "alloc-no-stdlib" 62 + version = "2.0.4" 63 + source = "registry+https://github.com/rust-lang/crates.io-index" 64 + checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" 65 + 66 + [[package]] 67 + name = "alloc-stdlib" 68 + version = "0.2.2" 69 + source = "registry+https://github.com/rust-lang/crates.io-index" 70 + checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" 71 + dependencies = [ 72 + "alloc-no-stdlib", 73 + ] 74 + 75 + [[package]] 76 + name = "android_system_properties" 77 + version = "0.1.5" 78 + source = "registry+https://github.com/rust-lang/crates.io-index" 79 + checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 80 + dependencies = [ 81 + "libc", 82 + ] 83 + 84 + [[package]] 85 + name = "anstream" 86 + version = "0.6.21" 87 + source = "registry+https://github.com/rust-lang/crates.io-index" 88 + checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" 89 + dependencies = [ 90 + "anstyle", 91 + "anstyle-parse", 92 + "anstyle-query", 93 + "anstyle-wincon", 94 + "colorchoice", 95 + "is_terminal_polyfill", 96 + "utf8parse", 97 + ] 98 + 99 + [[package]] 100 + name = "anstyle" 101 + version = "1.0.13" 102 + source = "registry+https://github.com/rust-lang/crates.io-index" 103 + checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" 104 + 105 + [[package]] 106 + name = "anstyle-parse" 107 + version = "0.2.7" 108 + source = "registry+https://github.com/rust-lang/crates.io-index" 109 + checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" 110 + dependencies = [ 111 + "utf8parse", 112 + ] 113 + 114 + [[package]] 115 + name = "anstyle-query" 116 + version = "1.1.4" 117 + source = "registry+https://github.com/rust-lang/crates.io-index" 118 + checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" 119 + dependencies = [ 120 + "windows-sys 0.60.2", 121 + ] 122 + 123 + [[package]] 124 + name = "anstyle-wincon" 125 + version = "3.0.10" 126 + source = "registry+https://github.com/rust-lang/crates.io-index" 127 + checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" 128 + dependencies = [ 129 + "anstyle", 130 + "once_cell_polyfill", 131 + "windows-sys 0.60.2", 132 + ] 133 + 134 + [[package]] 135 + name = "ascii" 136 + version = "1.1.0" 137 + source = "registry+https://github.com/rust-lang/crates.io-index" 138 + checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" 139 + 140 + [[package]] 141 + name = "async-compression" 142 + version = "0.4.32" 143 + source = "registry+https://github.com/rust-lang/crates.io-index" 144 + checksum = "5a89bce6054c720275ac2432fbba080a66a2106a44a1b804553930ca6909f4e0" 145 + dependencies = [ 146 + "compression-codecs", 147 + "compression-core", 148 + "futures-core", 149 + "pin-project-lite", 150 + "tokio", 151 + ] 152 + 153 + [[package]] 154 + name = "async-trait" 155 + version = "0.1.89" 156 + source = "registry+https://github.com/rust-lang/crates.io-index" 157 + checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" 158 + dependencies = [ 159 + "proc-macro2", 160 + "quote", 161 + "syn 2.0.107", 162 + ] 163 + 164 + [[package]] 6 165 name = "atcities-upload" 166 + version = "1.0.1" 167 + dependencies = [ 168 + "clap", 169 + "env_logger", 170 + "ignore", 171 + "jacquard", 172 + "lexicons", 173 + "miette", 174 + "mime_guess", 175 + "regex", 176 + "reqwest", 177 + "thiserror 2.0.17", 178 + "tokio", 179 + ] 180 + 181 + [[package]] 182 + name = "atomic-waker" 183 + version = "1.1.2" 184 + source = "registry+https://github.com/rust-lang/crates.io-index" 185 + checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 186 + 187 + [[package]] 188 + name = "autocfg" 189 + version = "1.5.0" 190 + source = "registry+https://github.com/rust-lang/crates.io-index" 191 + checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" 192 + 193 + [[package]] 194 + name = "backtrace" 195 + version = "0.3.76" 196 + source = "registry+https://github.com/rust-lang/crates.io-index" 197 + checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" 198 + dependencies = [ 199 + "addr2line", 200 + "cfg-if", 201 + "libc", 202 + "miniz_oxide", 203 + "object", 204 + "rustc-demangle", 205 + "windows-link 0.2.1", 206 + ] 207 + 208 + [[package]] 209 + name = "backtrace-ext" 210 + version = "0.2.1" 211 + source = "registry+https://github.com/rust-lang/crates.io-index" 212 + checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50" 213 + dependencies = [ 214 + "backtrace", 215 + ] 216 + 217 + [[package]] 218 + name = "base-x" 219 + version = "0.2.11" 220 + source = "registry+https://github.com/rust-lang/crates.io-index" 221 + checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" 222 + 223 + [[package]] 224 + name = "base16ct" 225 + version = "0.2.0" 226 + source = "registry+https://github.com/rust-lang/crates.io-index" 227 + checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" 228 + 229 + [[package]] 230 + name = "base256emoji" 231 + version = "1.0.2" 232 + source = "registry+https://github.com/rust-lang/crates.io-index" 233 + checksum = "b5e9430d9a245a77c92176e649af6e275f20839a48389859d1661e9a128d077c" 234 + dependencies = [ 235 + "const-str", 236 + "match-lookup", 237 + ] 238 + 239 + [[package]] 240 + name = "base64" 241 + version = "0.13.1" 242 + source = "registry+https://github.com/rust-lang/crates.io-index" 243 + checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" 244 + 245 + [[package]] 246 + name = "base64" 247 + version = "0.22.1" 248 + source = "registry+https://github.com/rust-lang/crates.io-index" 249 + checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 250 + 251 + [[package]] 252 + name = "base64ct" 253 + version = "1.8.0" 254 + source = "registry+https://github.com/rust-lang/crates.io-index" 255 + checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" 256 + 257 + [[package]] 258 + name = "bitflags" 259 + version = "2.9.4" 260 + source = "registry+https://github.com/rust-lang/crates.io-index" 261 + checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" 262 + 263 + [[package]] 264 + name = "block-buffer" 265 + version = "0.10.4" 266 + source = "registry+https://github.com/rust-lang/crates.io-index" 267 + checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 268 + dependencies = [ 269 + "generic-array", 270 + ] 271 + 272 + [[package]] 273 + name = "bon" 274 + version = "3.8.1" 275 + source = "registry+https://github.com/rust-lang/crates.io-index" 276 + checksum = "ebeb9aaf9329dff6ceb65c689ca3db33dbf15f324909c60e4e5eef5701ce31b1" 277 + dependencies = [ 278 + "bon-macros", 279 + "rustversion", 280 + ] 281 + 282 + [[package]] 283 + name = "bon-macros" 284 + version = "3.8.1" 285 + source = "registry+https://github.com/rust-lang/crates.io-index" 286 + checksum = "77e9d642a7e3a318e37c2c9427b5a6a48aa1ad55dcd986f3034ab2239045a645" 287 + dependencies = [ 288 + "darling", 289 + "ident_case", 290 + "prettyplease", 291 + "proc-macro2", 292 + "quote", 293 + "rustversion", 294 + "syn 2.0.107", 295 + ] 296 + 297 + [[package]] 298 + name = "borsh" 299 + version = "1.5.7" 300 + source = "registry+https://github.com/rust-lang/crates.io-index" 301 + checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" 302 + dependencies = [ 303 + "cfg_aliases", 304 + ] 305 + 306 + [[package]] 307 + name = "brotli" 308 + version = "3.5.0" 309 + source = "registry+https://github.com/rust-lang/crates.io-index" 310 + checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391" 311 + dependencies = [ 312 + "alloc-no-stdlib", 313 + "alloc-stdlib", 314 + "brotli-decompressor", 315 + ] 316 + 317 + [[package]] 318 + name = "brotli-decompressor" 319 + version = "2.5.1" 320 + source = "registry+https://github.com/rust-lang/crates.io-index" 321 + checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" 322 + dependencies = [ 323 + "alloc-no-stdlib", 324 + "alloc-stdlib", 325 + ] 326 + 327 + [[package]] 328 + name = "bstr" 329 + version = "1.12.0" 330 + source = "registry+https://github.com/rust-lang/crates.io-index" 331 + checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" 332 + dependencies = [ 333 + "memchr", 334 + "serde", 335 + ] 336 + 337 + [[package]] 338 + name = "btree-range-map" 339 + version = "0.7.2" 340 + source = "registry+https://github.com/rust-lang/crates.io-index" 341 + checksum = "1be5c9672446d3800bcbcaabaeba121fe22f1fb25700c4562b22faf76d377c33" 342 + dependencies = [ 343 + "btree-slab", 344 + "cc-traits", 345 + "range-traits", 346 + "serde", 347 + "slab", 348 + ] 349 + 350 + [[package]] 351 + name = "btree-slab" 352 + version = "0.6.1" 353 + source = "registry+https://github.com/rust-lang/crates.io-index" 354 + checksum = "7a2b56d3029f075c4fa892428a098425b86cef5c89ae54073137ece416aef13c" 355 + dependencies = [ 356 + "cc-traits", 357 + "slab", 358 + "smallvec", 359 + ] 360 + 361 + [[package]] 362 + name = "buf_redux" 363 + version = "0.8.4" 364 + source = "registry+https://github.com/rust-lang/crates.io-index" 365 + checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f" 366 + dependencies = [ 367 + "memchr", 368 + "safemem", 369 + ] 370 + 371 + [[package]] 372 + name = "bumpalo" 373 + version = "3.19.0" 374 + source = "registry+https://github.com/rust-lang/crates.io-index" 375 + checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" 376 + 377 + [[package]] 378 + name = "byteorder" 379 + version = "1.5.0" 380 + source = "registry+https://github.com/rust-lang/crates.io-index" 381 + checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 382 + 383 + [[package]] 384 + name = "bytes" 385 + version = "1.10.1" 386 + source = "registry+https://github.com/rust-lang/crates.io-index" 387 + checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" 388 + dependencies = [ 389 + "serde", 390 + ] 391 + 392 + [[package]] 393 + name = "cbor4ii" 394 + version = "0.2.14" 395 + source = "registry+https://github.com/rust-lang/crates.io-index" 396 + checksum = "b544cf8c89359205f4f990d0e6f3828db42df85b5dac95d09157a250eb0749c4" 397 + dependencies = [ 398 + "serde", 399 + ] 400 + 401 + [[package]] 402 + name = "cc" 403 + version = "1.2.41" 404 + source = "registry+https://github.com/rust-lang/crates.io-index" 405 + checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7" 406 + dependencies = [ 407 + "find-msvc-tools", 408 + "shlex", 409 + ] 410 + 411 + [[package]] 412 + name = "cc-traits" 413 + version = "2.0.0" 414 + source = "registry+https://github.com/rust-lang/crates.io-index" 415 + checksum = "060303ef31ef4a522737e1b1ab68c67916f2a787bb2f4f54f383279adba962b5" 416 + dependencies = [ 417 + "slab", 418 + ] 419 + 420 + [[package]] 421 + name = "cesu8" 422 + version = "1.1.0" 423 + source = "registry+https://github.com/rust-lang/crates.io-index" 424 + checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" 425 + 426 + [[package]] 427 + name = "cfg-if" 428 + version = "1.0.4" 429 + source = "registry+https://github.com/rust-lang/crates.io-index" 430 + checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" 431 + 432 + [[package]] 433 + name = "cfg_aliases" 434 + version = "0.2.1" 435 + source = "registry+https://github.com/rust-lang/crates.io-index" 436 + checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" 437 + 438 + [[package]] 439 + name = "chrono" 440 + version = "0.4.42" 441 + source = "registry+https://github.com/rust-lang/crates.io-index" 442 + checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" 443 + dependencies = [ 444 + "iana-time-zone", 445 + "js-sys", 446 + "num-traits", 447 + "wasm-bindgen", 448 + "windows-link 0.2.1", 449 + ] 450 + 451 + [[package]] 452 + name = "chunked_transfer" 453 + version = "1.5.0" 454 + source = "registry+https://github.com/rust-lang/crates.io-index" 455 + checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901" 456 + 457 + [[package]] 458 + name = "ciborium" 459 + version = "0.2.2" 460 + source = "registry+https://github.com/rust-lang/crates.io-index" 461 + checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" 462 + dependencies = [ 463 + "ciborium-io", 464 + "ciborium-ll", 465 + "serde", 466 + ] 467 + 468 + [[package]] 469 + name = "ciborium-io" 470 + version = "0.2.2" 471 + source = "registry+https://github.com/rust-lang/crates.io-index" 472 + checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" 473 + 474 + [[package]] 475 + name = "ciborium-ll" 476 + version = "0.2.2" 477 + source = "registry+https://github.com/rust-lang/crates.io-index" 478 + checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" 479 + dependencies = [ 480 + "ciborium-io", 481 + "half", 482 + ] 483 + 484 + [[package]] 485 + name = "cid" 486 + version = "0.11.1" 487 + source = "registry+https://github.com/rust-lang/crates.io-index" 488 + checksum = "3147d8272e8fa0ccd29ce51194dd98f79ddfb8191ba9e3409884e751798acf3a" 489 + dependencies = [ 490 + "core2", 491 + "multibase", 492 + "multihash", 493 + "serde", 494 + "serde_bytes", 495 + "unsigned-varint", 496 + ] 497 + 498 + [[package]] 499 + name = "clap" 500 + version = "4.5.49" 501 + source = "registry+https://github.com/rust-lang/crates.io-index" 502 + checksum = "f4512b90fa68d3a9932cea5184017c5d200f5921df706d45e853537dea51508f" 503 + dependencies = [ 504 + "clap_builder", 505 + "clap_derive", 506 + ] 507 + 508 + [[package]] 509 + name = "clap_builder" 510 + version = "4.5.49" 511 + source = "registry+https://github.com/rust-lang/crates.io-index" 512 + checksum = "0025e98baa12e766c67ba13ff4695a887a1eba19569aad00a472546795bd6730" 513 + dependencies = [ 514 + "anstream", 515 + "anstyle", 516 + "clap_lex", 517 + "strsim", 518 + ] 519 + 520 + [[package]] 521 + name = "clap_derive" 522 + version = "4.5.49" 523 + source = "registry+https://github.com/rust-lang/crates.io-index" 524 + checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" 525 + dependencies = [ 526 + "heck 0.5.0", 527 + "proc-macro2", 528 + "quote", 529 + "syn 2.0.107", 530 + ] 531 + 532 + [[package]] 533 + name = "clap_lex" 534 + version = "0.7.6" 535 + source = "registry+https://github.com/rust-lang/crates.io-index" 536 + checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" 537 + 538 + [[package]] 539 + name = "colorchoice" 540 + version = "1.0.4" 541 + source = "registry+https://github.com/rust-lang/crates.io-index" 542 + checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" 543 + 544 + [[package]] 545 + name = "combine" 546 + version = "4.6.7" 547 + source = "registry+https://github.com/rust-lang/crates.io-index" 548 + checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" 549 + dependencies = [ 550 + "bytes", 551 + "memchr", 552 + ] 553 + 554 + [[package]] 555 + name = "compression-codecs" 556 + version = "0.4.31" 557 + source = "registry+https://github.com/rust-lang/crates.io-index" 558 + checksum = "ef8a506ec4b81c460798f572caead636d57d3d7e940f998160f52bd254bf2d23" 559 + dependencies = [ 560 + "compression-core", 561 + "flate2", 562 + "memchr", 563 + ] 564 + 565 + [[package]] 566 + name = "compression-core" 567 + version = "0.4.29" 568 + source = "registry+https://github.com/rust-lang/crates.io-index" 569 + checksum = "e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb" 570 + 571 + [[package]] 572 + name = "const-oid" 573 + version = "0.9.6" 574 + source = "registry+https://github.com/rust-lang/crates.io-index" 575 + checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" 576 + 577 + [[package]] 578 + name = "const-str" 579 + version = "0.4.3" 580 + source = "registry+https://github.com/rust-lang/crates.io-index" 581 + checksum = "2f421161cb492475f1661ddc9815a745a1c894592070661180fdec3d4872e9c3" 582 + 583 + [[package]] 584 + name = "core-foundation" 585 + version = "0.9.4" 586 + source = "registry+https://github.com/rust-lang/crates.io-index" 587 + checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 588 + dependencies = [ 589 + "core-foundation-sys", 590 + "libc", 591 + ] 592 + 593 + [[package]] 594 + name = "core-foundation-sys" 595 + version = "0.8.7" 596 + source = "registry+https://github.com/rust-lang/crates.io-index" 597 + checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 598 + 599 + [[package]] 600 + name = "core2" 601 + version = "0.4.0" 602 + source = "registry+https://github.com/rust-lang/crates.io-index" 603 + checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" 604 + dependencies = [ 605 + "memchr", 606 + ] 607 + 608 + [[package]] 609 + name = "cpufeatures" 610 + version = "0.2.17" 611 + source = "registry+https://github.com/rust-lang/crates.io-index" 612 + checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" 613 + dependencies = [ 614 + "libc", 615 + ] 616 + 617 + [[package]] 618 + name = "crc32fast" 619 + version = "1.5.0" 620 + source = "registry+https://github.com/rust-lang/crates.io-index" 621 + checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" 622 + dependencies = [ 623 + "cfg-if", 624 + ] 625 + 626 + [[package]] 627 + name = "crossbeam-deque" 628 + version = "0.8.6" 629 + source = "registry+https://github.com/rust-lang/crates.io-index" 630 + checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" 631 + dependencies = [ 632 + "crossbeam-epoch", 633 + "crossbeam-utils", 634 + ] 635 + 636 + [[package]] 637 + name = "crossbeam-epoch" 638 + version = "0.9.18" 639 + source = "registry+https://github.com/rust-lang/crates.io-index" 640 + checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" 641 + dependencies = [ 642 + "crossbeam-utils", 643 + ] 644 + 645 + [[package]] 646 + name = "crossbeam-utils" 647 + version = "0.8.21" 648 + source = "registry+https://github.com/rust-lang/crates.io-index" 649 + checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" 650 + 651 + [[package]] 652 + name = "crunchy" 653 + version = "0.2.4" 654 + source = "registry+https://github.com/rust-lang/crates.io-index" 655 + checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" 656 + 657 + [[package]] 658 + name = "crypto-bigint" 659 + version = "0.5.5" 660 + source = "registry+https://github.com/rust-lang/crates.io-index" 661 + checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" 662 + dependencies = [ 663 + "generic-array", 664 + "rand_core 0.6.4", 665 + "subtle", 666 + "zeroize", 667 + ] 668 + 669 + [[package]] 670 + name = "crypto-common" 671 + version = "0.1.6" 672 + source = "registry+https://github.com/rust-lang/crates.io-index" 673 + checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 674 + dependencies = [ 675 + "generic-array", 676 + "typenum", 677 + ] 678 + 679 + [[package]] 680 + name = "darling" 681 + version = "0.21.3" 682 + source = "registry+https://github.com/rust-lang/crates.io-index" 683 + checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" 684 + dependencies = [ 685 + "darling_core", 686 + "darling_macro", 687 + ] 688 + 689 + [[package]] 690 + name = "darling_core" 691 + version = "0.21.3" 692 + source = "registry+https://github.com/rust-lang/crates.io-index" 693 + checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" 694 + dependencies = [ 695 + "fnv", 696 + "ident_case", 697 + "proc-macro2", 698 + "quote", 699 + "strsim", 700 + "syn 2.0.107", 701 + ] 702 + 703 + [[package]] 704 + name = "darling_macro" 705 + version = "0.21.3" 706 + source = "registry+https://github.com/rust-lang/crates.io-index" 707 + checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" 708 + dependencies = [ 709 + "darling_core", 710 + "quote", 711 + "syn 2.0.107", 712 + ] 713 + 714 + [[package]] 715 + name = "dashmap" 716 + version = "6.1.0" 717 + source = "registry+https://github.com/rust-lang/crates.io-index" 718 + checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" 719 + dependencies = [ 720 + "cfg-if", 721 + "crossbeam-utils", 722 + "hashbrown 0.14.5", 723 + "lock_api", 724 + "once_cell", 725 + "parking_lot_core", 726 + ] 727 + 728 + [[package]] 729 + name = "data-encoding" 730 + version = "2.9.0" 731 + source = "registry+https://github.com/rust-lang/crates.io-index" 732 + checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" 733 + 734 + [[package]] 735 + name = "data-encoding-macro" 736 + version = "0.1.18" 737 + source = "registry+https://github.com/rust-lang/crates.io-index" 738 + checksum = "47ce6c96ea0102f01122a185683611bd5ac8d99e62bc59dd12e6bda344ee673d" 739 + dependencies = [ 740 + "data-encoding", 741 + "data-encoding-macro-internal", 742 + ] 743 + 744 + [[package]] 745 + name = "data-encoding-macro-internal" 746 + version = "0.1.16" 747 + source = "registry+https://github.com/rust-lang/crates.io-index" 748 + checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976" 749 + dependencies = [ 750 + "data-encoding", 751 + "syn 2.0.107", 752 + ] 753 + 754 + [[package]] 755 + name = "deflate" 756 + version = "1.0.0" 757 + source = "registry+https://github.com/rust-lang/crates.io-index" 758 + checksum = "c86f7e25f518f4b81808a2cf1c50996a61f5c2eb394b2393bd87f2a4780a432f" 759 + dependencies = [ 760 + "adler32", 761 + "gzip-header", 762 + ] 763 + 764 + [[package]] 765 + name = "der" 766 + version = "0.7.10" 767 + source = "registry+https://github.com/rust-lang/crates.io-index" 768 + checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" 769 + dependencies = [ 770 + "const-oid", 771 + "pem-rfc7468", 772 + "zeroize", 773 + ] 774 + 775 + [[package]] 776 + name = "deranged" 777 + version = "0.5.4" 778 + source = "registry+https://github.com/rust-lang/crates.io-index" 779 + checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071" 780 + dependencies = [ 781 + "powerfmt", 782 + ] 783 + 784 + [[package]] 785 + name = "digest" 786 + version = "0.10.7" 787 + source = "registry+https://github.com/rust-lang/crates.io-index" 788 + checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 789 + dependencies = [ 790 + "block-buffer", 791 + "const-oid", 792 + "crypto-common", 793 + "subtle", 794 + ] 795 + 796 + [[package]] 797 + name = "displaydoc" 798 + version = "0.2.5" 799 + source = "registry+https://github.com/rust-lang/crates.io-index" 800 + checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" 801 + dependencies = [ 802 + "proc-macro2", 803 + "quote", 804 + "syn 2.0.107", 805 + ] 806 + 807 + [[package]] 808 + name = "ecdsa" 809 + version = "0.16.9" 810 + source = "registry+https://github.com/rust-lang/crates.io-index" 811 + checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" 812 + dependencies = [ 813 + "der", 814 + "digest", 815 + "elliptic-curve", 816 + "rfc6979", 817 + "signature", 818 + "spki", 819 + ] 820 + 821 + [[package]] 822 + name = "elliptic-curve" 823 + version = "0.13.8" 824 + source = "registry+https://github.com/rust-lang/crates.io-index" 825 + checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" 826 + dependencies = [ 827 + "base16ct", 828 + "crypto-bigint", 829 + "digest", 830 + "ff", 831 + "generic-array", 832 + "group", 833 + "pem-rfc7468", 834 + "pkcs8", 835 + "rand_core 0.6.4", 836 + "sec1", 837 + "subtle", 838 + "zeroize", 839 + ] 840 + 841 + [[package]] 842 + name = "encoding_rs" 843 + version = "0.8.35" 844 + source = "registry+https://github.com/rust-lang/crates.io-index" 845 + checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" 846 + dependencies = [ 847 + "cfg-if", 848 + ] 849 + 850 + [[package]] 851 + name = "enum-as-inner" 852 + version = "0.6.1" 853 + source = "registry+https://github.com/rust-lang/crates.io-index" 854 + checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" 855 + dependencies = [ 856 + "heck 0.5.0", 857 + "proc-macro2", 858 + "quote", 859 + "syn 2.0.107", 860 + ] 861 + 862 + [[package]] 863 + name = "env_filter" 864 + version = "0.1.4" 865 + source = "registry+https://github.com/rust-lang/crates.io-index" 866 + checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" 867 + dependencies = [ 868 + "log", 869 + "regex", 870 + ] 871 + 872 + [[package]] 873 + name = "env_logger" 874 + version = "0.11.8" 875 + source = "registry+https://github.com/rust-lang/crates.io-index" 876 + checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" 877 + dependencies = [ 878 + "anstream", 879 + "anstyle", 880 + "env_filter", 881 + "jiff", 882 + "log", 883 + ] 884 + 885 + [[package]] 886 + name = "equivalent" 887 + version = "1.0.2" 888 + source = "registry+https://github.com/rust-lang/crates.io-index" 889 + checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 890 + 891 + [[package]] 892 + name = "errno" 893 + version = "0.3.14" 894 + source = "registry+https://github.com/rust-lang/crates.io-index" 895 + checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" 896 + dependencies = [ 897 + "libc", 898 + "windows-sys 0.61.2", 899 + ] 900 + 901 + [[package]] 902 + name = "fastrand" 903 + version = "2.3.0" 904 + source = "registry+https://github.com/rust-lang/crates.io-index" 905 + checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" 906 + 907 + [[package]] 908 + name = "ff" 909 + version = "0.13.1" 910 + source = "registry+https://github.com/rust-lang/crates.io-index" 911 + checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" 912 + dependencies = [ 913 + "rand_core 0.6.4", 914 + "subtle", 915 + ] 916 + 917 + [[package]] 918 + name = "filetime" 919 + version = "0.2.26" 920 + source = "registry+https://github.com/rust-lang/crates.io-index" 921 + checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" 922 + dependencies = [ 923 + "cfg-if", 924 + "libc", 925 + "libredox", 926 + "windows-sys 0.60.2", 927 + ] 928 + 929 + [[package]] 930 + name = "find-msvc-tools" 931 + version = "0.1.4" 932 + source = "registry+https://github.com/rust-lang/crates.io-index" 933 + checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" 934 + 935 + [[package]] 936 + name = "flate2" 937 + version = "1.1.4" 938 + source = "registry+https://github.com/rust-lang/crates.io-index" 939 + checksum = "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9" 940 + dependencies = [ 941 + "crc32fast", 942 + "miniz_oxide", 943 + ] 944 + 945 + [[package]] 946 + name = "fnv" 947 + version = "1.0.7" 948 + source = "registry+https://github.com/rust-lang/crates.io-index" 949 + checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 950 + 951 + [[package]] 952 + name = "foreign-types" 953 + version = "0.3.2" 954 + source = "registry+https://github.com/rust-lang/crates.io-index" 955 + checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 956 + dependencies = [ 957 + "foreign-types-shared", 958 + ] 959 + 960 + [[package]] 961 + name = "foreign-types-shared" 962 + version = "0.1.1" 963 + source = "registry+https://github.com/rust-lang/crates.io-index" 964 + checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 965 + 966 + [[package]] 967 + name = "form_urlencoded" 968 + version = "1.2.2" 969 + source = "registry+https://github.com/rust-lang/crates.io-index" 970 + checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" 971 + dependencies = [ 972 + "percent-encoding", 973 + ] 974 + 975 + [[package]] 976 + name = "futures-channel" 977 + version = "0.3.31" 978 + source = "registry+https://github.com/rust-lang/crates.io-index" 979 + checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 980 + dependencies = [ 981 + "futures-core", 982 + ] 983 + 984 + [[package]] 985 + name = "futures-core" 986 + version = "0.3.31" 987 + source = "registry+https://github.com/rust-lang/crates.io-index" 988 + checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 989 + 990 + [[package]] 991 + name = "futures-io" 992 + version = "0.3.31" 993 + source = "registry+https://github.com/rust-lang/crates.io-index" 994 + checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 995 + 996 + [[package]] 997 + name = "futures-macro" 998 + version = "0.3.31" 999 + source = "registry+https://github.com/rust-lang/crates.io-index" 1000 + checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" 1001 + dependencies = [ 1002 + "proc-macro2", 1003 + "quote", 1004 + "syn 2.0.107", 1005 + ] 1006 + 1007 + [[package]] 1008 + name = "futures-sink" 1009 + version = "0.3.31" 1010 + source = "registry+https://github.com/rust-lang/crates.io-index" 1011 + checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 1012 + 1013 + [[package]] 1014 + name = "futures-task" 1015 + version = "0.3.31" 1016 + source = "registry+https://github.com/rust-lang/crates.io-index" 1017 + checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 1018 + 1019 + [[package]] 1020 + name = "futures-util" 1021 + version = "0.3.31" 1022 + source = "registry+https://github.com/rust-lang/crates.io-index" 1023 + checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 1024 + dependencies = [ 1025 + "futures-core", 1026 + "futures-io", 1027 + "futures-macro", 1028 + "futures-sink", 1029 + "futures-task", 1030 + "memchr", 1031 + "pin-project-lite", 1032 + "pin-utils", 1033 + "slab", 1034 + ] 1035 + 1036 + [[package]] 1037 + name = "genawaiter" 1038 + version = "0.99.1" 1039 + source = "registry+https://github.com/rust-lang/crates.io-index" 1040 + checksum = "c86bd0361bcbde39b13475e6e36cb24c329964aa2611be285289d1e4b751c1a0" 1041 + dependencies = [ 1042 + "futures-core", 1043 + "genawaiter-macro", 1044 + "genawaiter-proc-macro", 1045 + "proc-macro-hack", 1046 + ] 1047 + 1048 + [[package]] 1049 + name = "genawaiter-macro" 1050 + version = "0.99.1" 1051 + source = "registry+https://github.com/rust-lang/crates.io-index" 1052 + checksum = "0b32dfe1fdfc0bbde1f22a5da25355514b5e450c33a6af6770884c8750aedfbc" 1053 + 1054 + [[package]] 1055 + name = "genawaiter-proc-macro" 1056 + version = "0.99.1" 1057 + source = "registry+https://github.com/rust-lang/crates.io-index" 1058 + checksum = "784f84eebc366e15251c4a8c3acee82a6a6f427949776ecb88377362a9621738" 1059 + dependencies = [ 1060 + "proc-macro-error 0.4.12", 1061 + "proc-macro-hack", 1062 + "proc-macro2", 1063 + "quote", 1064 + "syn 1.0.109", 1065 + ] 1066 + 1067 + [[package]] 1068 + name = "generic-array" 1069 + version = "0.14.9" 1070 + source = "registry+https://github.com/rust-lang/crates.io-index" 1071 + checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" 1072 + dependencies = [ 1073 + "typenum", 1074 + "version_check", 1075 + "zeroize", 1076 + ] 1077 + 1078 + [[package]] 1079 + name = "getrandom" 1080 + version = "0.2.16" 1081 + source = "registry+https://github.com/rust-lang/crates.io-index" 1082 + checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" 1083 + dependencies = [ 1084 + "cfg-if", 1085 + "js-sys", 1086 + "libc", 1087 + "wasi", 1088 + "wasm-bindgen", 1089 + ] 1090 + 1091 + [[package]] 1092 + name = "getrandom" 1093 + version = "0.3.4" 1094 + source = "registry+https://github.com/rust-lang/crates.io-index" 1095 + checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" 1096 + dependencies = [ 1097 + "cfg-if", 1098 + "js-sys", 1099 + "libc", 1100 + "r-efi", 1101 + "wasip2", 1102 + "wasm-bindgen", 1103 + ] 1104 + 1105 + [[package]] 1106 + name = "gimli" 1107 + version = "0.32.3" 1108 + source = "registry+https://github.com/rust-lang/crates.io-index" 1109 + checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" 1110 + 1111 + [[package]] 1112 + name = "globset" 1113 + version = "0.4.17" 1114 + source = "registry+https://github.com/rust-lang/crates.io-index" 1115 + checksum = "eab69130804d941f8075cfd713bf8848a2c3b3f201a9457a11e6f87e1ab62305" 1116 + dependencies = [ 1117 + "aho-corasick", 1118 + "bstr", 1119 + "log", 1120 + "regex-automata", 1121 + "regex-syntax", 1122 + ] 1123 + 1124 + [[package]] 1125 + name = "group" 1126 + version = "0.13.0" 1127 + source = "registry+https://github.com/rust-lang/crates.io-index" 1128 + checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" 1129 + dependencies = [ 1130 + "ff", 1131 + "rand_core 0.6.4", 1132 + "subtle", 1133 + ] 1134 + 1135 + [[package]] 1136 + name = "gzip-header" 1137 + version = "1.0.0" 1138 + source = "registry+https://github.com/rust-lang/crates.io-index" 1139 + checksum = "95cc527b92e6029a62960ad99aa8a6660faa4555fe5f731aab13aa6a921795a2" 1140 + dependencies = [ 1141 + "crc32fast", 1142 + ] 1143 + 1144 + [[package]] 1145 + name = "h2" 1146 + version = "0.4.12" 1147 + source = "registry+https://github.com/rust-lang/crates.io-index" 1148 + checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" 1149 + dependencies = [ 1150 + "atomic-waker", 1151 + "bytes", 1152 + "fnv", 1153 + "futures-core", 1154 + "futures-sink", 1155 + "http", 1156 + "indexmap", 1157 + "slab", 1158 + "tokio", 1159 + "tokio-util", 1160 + "tracing", 1161 + ] 1162 + 1163 + [[package]] 1164 + name = "half" 1165 + version = "2.7.1" 1166 + source = "registry+https://github.com/rust-lang/crates.io-index" 1167 + checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" 1168 + dependencies = [ 1169 + "cfg-if", 1170 + "crunchy", 1171 + "zerocopy", 1172 + ] 1173 + 1174 + [[package]] 1175 + name = "hashbrown" 1176 + version = "0.14.5" 1177 + source = "registry+https://github.com/rust-lang/crates.io-index" 1178 + checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 1179 + 1180 + [[package]] 1181 + name = "hashbrown" 1182 + version = "0.16.0" 1183 + source = "registry+https://github.com/rust-lang/crates.io-index" 1184 + checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" 1185 + 1186 + [[package]] 1187 + name = "heck" 1188 + version = "0.4.1" 1189 + source = "registry+https://github.com/rust-lang/crates.io-index" 1190 + checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 1191 + 1192 + [[package]] 1193 + name = "heck" 1194 + version = "0.5.0" 1195 + source = "registry+https://github.com/rust-lang/crates.io-index" 1196 + checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 1197 + 1198 + [[package]] 1199 + name = "hermit-abi" 1200 + version = "0.5.2" 1201 + source = "registry+https://github.com/rust-lang/crates.io-index" 1202 + checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" 1203 + 1204 + [[package]] 1205 + name = "hex_fmt" 1206 + version = "0.3.0" 1207 + source = "registry+https://github.com/rust-lang/crates.io-index" 1208 + checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f" 1209 + 1210 + [[package]] 1211 + name = "hickory-proto" 1212 + version = "0.24.4" 1213 + source = "registry+https://github.com/rust-lang/crates.io-index" 1214 + checksum = "92652067c9ce6f66ce53cc38d1169daa36e6e7eb7dd3b63b5103bd9d97117248" 1215 + dependencies = [ 1216 + "async-trait", 1217 + "cfg-if", 1218 + "data-encoding", 1219 + "enum-as-inner", 1220 + "futures-channel", 1221 + "futures-io", 1222 + "futures-util", 1223 + "idna", 1224 + "ipnet", 1225 + "once_cell", 1226 + "rand 0.8.5", 1227 + "thiserror 1.0.69", 1228 + "tinyvec", 1229 + "tokio", 1230 + "tracing", 1231 + "url", 1232 + ] 1233 + 1234 + [[package]] 1235 + name = "hickory-resolver" 1236 + version = "0.24.4" 1237 + source = "registry+https://github.com/rust-lang/crates.io-index" 1238 + checksum = "cbb117a1ca520e111743ab2f6688eddee69db4e0ea242545a604dce8a66fd22e" 1239 + dependencies = [ 1240 + "cfg-if", 1241 + "futures-util", 1242 + "hickory-proto", 1243 + "ipconfig", 1244 + "lru-cache", 1245 + "once_cell", 1246 + "parking_lot", 1247 + "rand 0.8.5", 1248 + "resolv-conf", 1249 + "smallvec", 1250 + "thiserror 1.0.69", 1251 + "tokio", 1252 + "tracing", 1253 + ] 1254 + 1255 + [[package]] 1256 + name = "hmac" 1257 + version = "0.12.1" 1258 + source = "registry+https://github.com/rust-lang/crates.io-index" 1259 + checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" 1260 + dependencies = [ 1261 + "digest", 1262 + ] 1263 + 1264 + [[package]] 1265 + name = "home" 1266 + version = "0.5.11" 1267 + source = "registry+https://github.com/rust-lang/crates.io-index" 1268 + checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" 1269 + dependencies = [ 1270 + "windows-sys 0.59.0", 1271 + ] 1272 + 1273 + [[package]] 1274 + name = "http" 1275 + version = "1.3.1" 1276 + source = "registry+https://github.com/rust-lang/crates.io-index" 1277 + checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" 1278 + dependencies = [ 1279 + "bytes", 1280 + "fnv", 1281 + "itoa", 1282 + ] 1283 + 1284 + [[package]] 1285 + name = "http-body" 1286 + version = "1.0.1" 1287 + source = "registry+https://github.com/rust-lang/crates.io-index" 1288 + checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 1289 + dependencies = [ 1290 + "bytes", 1291 + "http", 1292 + ] 1293 + 1294 + [[package]] 1295 + name = "http-body-util" 1296 + version = "0.1.3" 1297 + source = "registry+https://github.com/rust-lang/crates.io-index" 1298 + checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" 1299 + dependencies = [ 1300 + "bytes", 1301 + "futures-core", 1302 + "http", 1303 + "http-body", 1304 + "pin-project-lite", 1305 + ] 1306 + 1307 + [[package]] 1308 + name = "httparse" 1309 + version = "1.10.1" 1310 + source = "registry+https://github.com/rust-lang/crates.io-index" 1311 + checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" 1312 + 1313 + [[package]] 1314 + name = "httpdate" 1315 + version = "1.0.3" 1316 + source = "registry+https://github.com/rust-lang/crates.io-index" 1317 + checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 1318 + 1319 + [[package]] 1320 + name = "hyper" 1321 + version = "1.7.0" 1322 + source = "registry+https://github.com/rust-lang/crates.io-index" 1323 + checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" 1324 + dependencies = [ 1325 + "atomic-waker", 1326 + "bytes", 1327 + "futures-channel", 1328 + "futures-core", 1329 + "h2", 1330 + "http", 1331 + "http-body", 1332 + "httparse", 1333 + "itoa", 1334 + "pin-project-lite", 1335 + "pin-utils", 1336 + "smallvec", 1337 + "tokio", 1338 + "want", 1339 + ] 1340 + 1341 + [[package]] 1342 + name = "hyper-rustls" 1343 + version = "0.27.7" 1344 + source = "registry+https://github.com/rust-lang/crates.io-index" 1345 + checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" 1346 + dependencies = [ 1347 + "http", 1348 + "hyper", 1349 + "hyper-util", 1350 + "rustls", 1351 + "rustls-pki-types", 1352 + "tokio", 1353 + "tokio-rustls", 1354 + "tower-service", 1355 + "webpki-roots", 1356 + ] 1357 + 1358 + [[package]] 1359 + name = "hyper-tls" 1360 + version = "0.6.0" 1361 + source = "registry+https://github.com/rust-lang/crates.io-index" 1362 + checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" 1363 + dependencies = [ 1364 + "bytes", 1365 + "http-body-util", 1366 + "hyper", 1367 + "hyper-util", 1368 + "native-tls", 1369 + "tokio", 1370 + "tokio-native-tls", 1371 + "tower-service", 1372 + ] 1373 + 1374 + [[package]] 1375 + name = "hyper-util" 1376 + version = "0.1.17" 1377 + source = "registry+https://github.com/rust-lang/crates.io-index" 1378 + checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" 1379 + dependencies = [ 1380 + "base64 0.22.1", 1381 + "bytes", 1382 + "futures-channel", 1383 + "futures-core", 1384 + "futures-util", 1385 + "http", 1386 + "http-body", 1387 + "hyper", 1388 + "ipnet", 1389 + "libc", 1390 + "percent-encoding", 1391 + "pin-project-lite", 1392 + "socket2 0.6.1", 1393 + "system-configuration", 1394 + "tokio", 1395 + "tower-service", 1396 + "tracing", 1397 + "windows-registry", 1398 + ] 1399 + 1400 + [[package]] 1401 + name = "iana-time-zone" 1402 + version = "0.1.64" 1403 + source = "registry+https://github.com/rust-lang/crates.io-index" 1404 + checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" 1405 + dependencies = [ 1406 + "android_system_properties", 1407 + "core-foundation-sys", 1408 + "iana-time-zone-haiku", 1409 + "js-sys", 1410 + "log", 1411 + "wasm-bindgen", 1412 + "windows-core", 1413 + ] 1414 + 1415 + [[package]] 1416 + name = "iana-time-zone-haiku" 1417 + version = "0.1.2" 1418 + source = "registry+https://github.com/rust-lang/crates.io-index" 1419 + checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" 1420 + dependencies = [ 1421 + "cc", 1422 + ] 1423 + 1424 + [[package]] 1425 + name = "icu_collections" 1426 + version = "2.0.0" 1427 + source = "registry+https://github.com/rust-lang/crates.io-index" 1428 + checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" 1429 + dependencies = [ 1430 + "displaydoc", 1431 + "potential_utf", 1432 + "yoke", 1433 + "zerofrom", 1434 + "zerovec", 1435 + ] 1436 + 1437 + [[package]] 1438 + name = "icu_locale_core" 1439 + version = "2.0.0" 1440 + source = "registry+https://github.com/rust-lang/crates.io-index" 1441 + checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" 1442 + dependencies = [ 1443 + "displaydoc", 1444 + "litemap", 1445 + "tinystr", 1446 + "writeable", 1447 + "zerovec", 1448 + ] 1449 + 1450 + [[package]] 1451 + name = "icu_normalizer" 1452 + version = "2.0.0" 1453 + source = "registry+https://github.com/rust-lang/crates.io-index" 1454 + checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" 1455 + dependencies = [ 1456 + "displaydoc", 1457 + "icu_collections", 1458 + "icu_normalizer_data", 1459 + "icu_properties", 1460 + "icu_provider", 1461 + "smallvec", 1462 + "zerovec", 1463 + ] 1464 + 1465 + [[package]] 1466 + name = "icu_normalizer_data" 1467 + version = "2.0.0" 1468 + source = "registry+https://github.com/rust-lang/crates.io-index" 1469 + checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" 1470 + 1471 + [[package]] 1472 + name = "icu_properties" 1473 + version = "2.0.1" 1474 + source = "registry+https://github.com/rust-lang/crates.io-index" 1475 + checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" 1476 + dependencies = [ 1477 + "displaydoc", 1478 + "icu_collections", 1479 + "icu_locale_core", 1480 + "icu_properties_data", 1481 + "icu_provider", 1482 + "potential_utf", 1483 + "zerotrie", 1484 + "zerovec", 1485 + ] 1486 + 1487 + [[package]] 1488 + name = "icu_properties_data" 1489 + version = "2.0.1" 1490 + source = "registry+https://github.com/rust-lang/crates.io-index" 1491 + checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" 1492 + 1493 + [[package]] 1494 + name = "icu_provider" 1495 + version = "2.0.0" 1496 + source = "registry+https://github.com/rust-lang/crates.io-index" 1497 + checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" 1498 + dependencies = [ 1499 + "displaydoc", 1500 + "icu_locale_core", 1501 + "stable_deref_trait", 1502 + "tinystr", 1503 + "writeable", 1504 + "yoke", 1505 + "zerofrom", 1506 + "zerotrie", 1507 + "zerovec", 1508 + ] 1509 + 1510 + [[package]] 1511 + name = "ident_case" 1512 + version = "1.0.1" 1513 + source = "registry+https://github.com/rust-lang/crates.io-index" 1514 + checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 1515 + 1516 + [[package]] 1517 + name = "idna" 1518 + version = "1.1.0" 1519 + source = "registry+https://github.com/rust-lang/crates.io-index" 1520 + checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" 1521 + dependencies = [ 1522 + "idna_adapter", 1523 + "smallvec", 1524 + "utf8_iter", 1525 + ] 1526 + 1527 + [[package]] 1528 + name = "idna_adapter" 1529 + version = "1.2.1" 1530 + source = "registry+https://github.com/rust-lang/crates.io-index" 1531 + checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" 1532 + dependencies = [ 1533 + "icu_normalizer", 1534 + "icu_properties", 1535 + ] 1536 + 1537 + [[package]] 1538 + name = "ignore" 1539 + version = "0.4.24" 1540 + source = "registry+https://github.com/rust-lang/crates.io-index" 1541 + checksum = "81776e6f9464432afcc28d03e52eb101c93b6f0566f52aef2427663e700f0403" 1542 + dependencies = [ 1543 + "crossbeam-deque", 1544 + "globset", 1545 + "log", 1546 + "memchr", 1547 + "regex-automata", 1548 + "same-file", 1549 + "walkdir", 1550 + "winapi-util", 1551 + ] 1552 + 1553 + [[package]] 1554 + name = "indexmap" 1555 + version = "2.12.0" 1556 + source = "registry+https://github.com/rust-lang/crates.io-index" 1557 + checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" 1558 + dependencies = [ 1559 + "equivalent", 1560 + "hashbrown 0.16.0", 1561 + ] 1562 + 1563 + [[package]] 1564 + name = "indoc" 1565 + version = "2.0.6" 1566 + source = "registry+https://github.com/rust-lang/crates.io-index" 1567 + checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" 1568 + 1569 + [[package]] 1570 + name = "ipconfig" 1571 + version = "0.3.2" 1572 + source = "registry+https://github.com/rust-lang/crates.io-index" 1573 + checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" 1574 + dependencies = [ 1575 + "socket2 0.5.10", 1576 + "widestring", 1577 + "windows-sys 0.48.0", 1578 + "winreg", 1579 + ] 1580 + 1581 + [[package]] 1582 + name = "ipld-core" 1583 + version = "0.4.2" 1584 + source = "registry+https://github.com/rust-lang/crates.io-index" 1585 + checksum = "104718b1cc124d92a6d01ca9c9258a7df311405debb3408c445a36452f9bf8db" 1586 + dependencies = [ 1587 + "cid", 1588 + "serde", 1589 + "serde_bytes", 1590 + ] 1591 + 1592 + [[package]] 1593 + name = "ipnet" 1594 + version = "2.11.0" 1595 + source = "registry+https://github.com/rust-lang/crates.io-index" 1596 + checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" 1597 + 1598 + [[package]] 1599 + name = "iri-string" 1600 + version = "0.7.8" 1601 + source = "registry+https://github.com/rust-lang/crates.io-index" 1602 + checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" 1603 + dependencies = [ 1604 + "memchr", 1605 + "serde", 1606 + ] 1607 + 1608 + [[package]] 1609 + name = "is_ci" 1610 + version = "1.2.0" 1611 + source = "registry+https://github.com/rust-lang/crates.io-index" 1612 + checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" 1613 + 1614 + [[package]] 1615 + name = "is_terminal_polyfill" 1616 + version = "1.70.1" 1617 + source = "registry+https://github.com/rust-lang/crates.io-index" 1618 + checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 1619 + 1620 + [[package]] 1621 + name = "itoa" 1622 + version = "1.0.15" 1623 + source = "registry+https://github.com/rust-lang/crates.io-index" 1624 + checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 1625 + 1626 + [[package]] 1627 + name = "jacquard" 1628 + version = "0.6.0" 1629 + source = "registry+https://github.com/rust-lang/crates.io-index" 1630 + checksum = "5857f000e67605995ba7c24c9833f840adf5c063a731a6f72f69e0e3c986791c" 1631 + dependencies = [ 1632 + "bon", 1633 + "bytes", 1634 + "getrandom 0.2.16", 1635 + "http", 1636 + "jacquard-api", 1637 + "jacquard-common", 1638 + "jacquard-derive", 1639 + "jacquard-identity", 1640 + "jacquard-oauth", 1641 + "jose-jwk", 1642 + "miette", 1643 + "p256", 1644 + "percent-encoding", 1645 + "rand_core 0.6.4", 1646 + "reqwest", 1647 + "serde", 1648 + "serde_html_form", 1649 + "serde_ipld_dagcbor", 1650 + "serde_json", 1651 + "smol_str", 1652 + "thiserror 2.0.17", 1653 + "tokio", 1654 + "trait-variant", 1655 + "url", 1656 + ] 1657 + 1658 + [[package]] 1659 + name = "jacquard-api" 1660 + version = "0.6.0" 1661 + source = "registry+https://github.com/rust-lang/crates.io-index" 1662 + checksum = "58132b60473124a34c64c267a1c3390c2e4a4dfd62c801639903c4aefd05f52d" 1663 + dependencies = [ 1664 + "bon", 1665 + "bytes", 1666 + "jacquard-common", 1667 + "jacquard-derive", 1668 + "miette", 1669 + "serde", 1670 + "serde_ipld_dagcbor", 1671 + "thiserror 2.0.17", 1672 + ] 1673 + 1674 + [[package]] 1675 + name = "jacquard-common" 1676 + version = "0.6.0" 1677 + source = "registry+https://github.com/rust-lang/crates.io-index" 1678 + checksum = "f7f1bab0279ae2e29c3383f132a05b9c708585fab62e94292affdf352ce13242" 1679 + dependencies = [ 1680 + "base64 0.22.1", 1681 + "bon", 1682 + "bytes", 1683 + "chrono", 1684 + "cid", 1685 + "genawaiter", 1686 + "getrandom 0.3.4", 1687 + "http", 1688 + "ipld-core", 1689 + "k256", 1690 + "langtag", 1691 + "miette", 1692 + "multibase", 1693 + "multihash", 1694 + "ouroboros", 1695 + "p256", 1696 + "rand 0.9.2", 1697 + "regex", 1698 + "reqwest", 1699 + "serde", 1700 + "serde_html_form", 1701 + "serde_ipld_dagcbor", 1702 + "serde_json", 1703 + "signature", 1704 + "smol_str", 1705 + "thiserror 2.0.17", 1706 + "tokio", 1707 + "tokio-util", 1708 + "trait-variant", 1709 + "url", 1710 + ] 1711 + 1712 + [[package]] 1713 + name = "jacquard-derive" 1714 + version = "0.6.0" 1715 + source = "registry+https://github.com/rust-lang/crates.io-index" 1716 + checksum = "a4741844c0638498156338e6230a81ecb54d0a061ffc6f4f54e97b94972a01fb" 1717 + dependencies = [ 1718 + "proc-macro2", 1719 + "quote", 1720 + "syn 2.0.107", 1721 + ] 1722 + 1723 + [[package]] 1724 + name = "jacquard-identity" 1725 + version = "0.6.0" 1726 + source = "registry+https://github.com/rust-lang/crates.io-index" 1727 + checksum = "65ae022725ddc09ce03c1a02a97b895279e1d46957c0574a032fa78b81273263" 1728 + dependencies = [ 1729 + "bon", 1730 + "bytes", 1731 + "hickory-resolver", 1732 + "http", 1733 + "jacquard-api", 1734 + "jacquard-common", 1735 + "miette", 1736 + "percent-encoding", 1737 + "reqwest", 1738 + "serde", 1739 + "serde_html_form", 1740 + "serde_json", 1741 + "thiserror 2.0.17", 1742 + "tokio", 1743 + "trait-variant", 1744 + "url", 1745 + "urlencoding", 1746 + ] 1747 + 1748 + [[package]] 1749 + name = "jacquard-oauth" 1750 + version = "0.6.0" 1751 + source = "registry+https://github.com/rust-lang/crates.io-index" 1752 + checksum = "8c37269e2ea0c6c3418bf61fb3d342aab87b1bda706ebae49e454f8e50580cab" 1753 + dependencies = [ 1754 + "base64 0.22.1", 1755 + "bytes", 1756 + "chrono", 1757 + "dashmap", 1758 + "elliptic-curve", 1759 + "http", 1760 + "jacquard-common", 1761 + "jacquard-identity", 1762 + "jose-jwa", 1763 + "jose-jwk", 1764 + "miette", 1765 + "p256", 1766 + "rand 0.8.5", 1767 + "rand_core 0.6.4", 1768 + "reqwest", 1769 + "rouille", 1770 + "serde", 1771 + "serde_html_form", 1772 + "serde_json", 1773 + "sha2", 1774 + "signature", 1775 + "smol_str", 1776 + "thiserror 2.0.17", 1777 + "tokio", 1778 + "trait-variant", 1779 + "url", 1780 + "webbrowser", 1781 + ] 1782 + 1783 + [[package]] 1784 + name = "jiff" 1785 + version = "0.2.15" 1786 + source = "registry+https://github.com/rust-lang/crates.io-index" 1787 + checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" 1788 + dependencies = [ 1789 + "jiff-static", 1790 + "log", 1791 + "portable-atomic", 1792 + "portable-atomic-util", 1793 + "serde", 1794 + ] 1795 + 1796 + [[package]] 1797 + name = "jiff-static" 1798 + version = "0.2.15" 1799 + source = "registry+https://github.com/rust-lang/crates.io-index" 1800 + checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" 1801 + dependencies = [ 1802 + "proc-macro2", 1803 + "quote", 1804 + "syn 2.0.107", 1805 + ] 1806 + 1807 + [[package]] 1808 + name = "jni" 1809 + version = "0.21.1" 1810 + source = "registry+https://github.com/rust-lang/crates.io-index" 1811 + checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" 1812 + dependencies = [ 1813 + "cesu8", 1814 + "cfg-if", 1815 + "combine", 1816 + "jni-sys", 1817 + "log", 1818 + "thiserror 1.0.69", 1819 + "walkdir", 1820 + "windows-sys 0.45.0", 1821 + ] 1822 + 1823 + [[package]] 1824 + name = "jni-sys" 1825 + version = "0.3.0" 1826 + source = "registry+https://github.com/rust-lang/crates.io-index" 1827 + checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" 1828 + 1829 + [[package]] 1830 + name = "jose-b64" 1831 + version = "0.1.2" 1832 + source = "registry+https://github.com/rust-lang/crates.io-index" 1833 + checksum = "bec69375368709666b21c76965ce67549f2d2db7605f1f8707d17c9656801b56" 1834 + dependencies = [ 1835 + "base64ct", 1836 + "serde", 1837 + "subtle", 1838 + "zeroize", 1839 + ] 1840 + 1841 + [[package]] 1842 + name = "jose-jwa" 1843 + version = "0.1.2" 1844 + source = "registry+https://github.com/rust-lang/crates.io-index" 1845 + checksum = "9ab78e053fe886a351d67cf0d194c000f9d0dcb92906eb34d853d7e758a4b3a7" 1846 + dependencies = [ 1847 + "serde", 1848 + ] 1849 + 1850 + [[package]] 1851 + name = "jose-jwk" 1852 + version = "0.1.2" 1853 + source = "registry+https://github.com/rust-lang/crates.io-index" 1854 + checksum = "280fa263807fe0782ecb6f2baadc28dffc04e00558a58e33bfdb801d11fd58e7" 1855 + dependencies = [ 1856 + "jose-b64", 1857 + "jose-jwa", 1858 + "p256", 1859 + "p384", 1860 + "rsa", 1861 + "serde", 1862 + "zeroize", 1863 + ] 1864 + 1865 + [[package]] 1866 + name = "js-sys" 1867 + version = "0.3.81" 1868 + source = "registry+https://github.com/rust-lang/crates.io-index" 1869 + checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" 1870 + dependencies = [ 1871 + "once_cell", 1872 + "wasm-bindgen", 1873 + ] 1874 + 1875 + [[package]] 1876 + name = "k256" 1877 + version = "0.13.4" 1878 + source = "registry+https://github.com/rust-lang/crates.io-index" 1879 + checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" 1880 + dependencies = [ 1881 + "cfg-if", 1882 + "ecdsa", 1883 + "elliptic-curve", 1884 + "sha2", 1885 + ] 1886 + 1887 + [[package]] 1888 + name = "langtag" 1889 + version = "0.4.0" 1890 + source = "registry+https://github.com/rust-lang/crates.io-index" 1891 + checksum = "9ecb4c689a30e48ebeaa14237f34037e300dd072e6ad21a9ec72e810ff3c6600" 1892 + dependencies = [ 1893 + "serde", 1894 + "static-regular-grammar", 1895 + "thiserror 1.0.69", 1896 + ] 1897 + 1898 + [[package]] 1899 + name = "lazy_static" 1900 + version = "1.5.0" 1901 + source = "registry+https://github.com/rust-lang/crates.io-index" 1902 + checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 1903 + dependencies = [ 1904 + "spin", 1905 + ] 1906 + 1907 + [[package]] 1908 + name = "lexicons" 1909 + version = "1.0.0" 1910 + dependencies = [ 1911 + "bon", 1912 + "bytes", 1913 + "jacquard-common", 1914 + "jacquard-derive", 1915 + "miette", 1916 + "serde", 1917 + "thiserror 2.0.17", 1918 + ] 1919 + 1920 + [[package]] 1921 + name = "libc" 1922 + version = "0.2.177" 1923 + source = "registry+https://github.com/rust-lang/crates.io-index" 1924 + checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" 1925 + 1926 + [[package]] 1927 + name = "libm" 1928 + version = "0.2.15" 1929 + source = "registry+https://github.com/rust-lang/crates.io-index" 1930 + checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" 1931 + 1932 + [[package]] 1933 + name = "libredox" 1934 + version = "0.1.10" 1935 + source = "registry+https://github.com/rust-lang/crates.io-index" 1936 + checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" 1937 + dependencies = [ 1938 + "bitflags", 1939 + "libc", 1940 + "redox_syscall", 1941 + ] 1942 + 1943 + [[package]] 1944 + name = "linked-hash-map" 1945 + version = "0.5.6" 1946 + source = "registry+https://github.com/rust-lang/crates.io-index" 1947 + checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" 1948 + 1949 + [[package]] 1950 + name = "linux-raw-sys" 1951 + version = "0.11.0" 1952 + source = "registry+https://github.com/rust-lang/crates.io-index" 1953 + checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" 1954 + 1955 + [[package]] 1956 + name = "litemap" 1957 + version = "0.8.0" 1958 + source = "registry+https://github.com/rust-lang/crates.io-index" 1959 + checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" 1960 + 1961 + [[package]] 1962 + name = "lock_api" 1963 + version = "0.4.14" 1964 + source = "registry+https://github.com/rust-lang/crates.io-index" 1965 + checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" 1966 + dependencies = [ 1967 + "scopeguard", 1968 + ] 1969 + 1970 + [[package]] 1971 + name = "log" 1972 + version = "0.4.28" 1973 + source = "registry+https://github.com/rust-lang/crates.io-index" 1974 + checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" 1975 + 1976 + [[package]] 1977 + name = "lru-cache" 1978 + version = "0.1.2" 1979 + source = "registry+https://github.com/rust-lang/crates.io-index" 1980 + checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" 1981 + dependencies = [ 1982 + "linked-hash-map", 1983 + ] 1984 + 1985 + [[package]] 1986 + name = "lru-slab" 1987 + version = "0.1.2" 1988 + source = "registry+https://github.com/rust-lang/crates.io-index" 1989 + checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" 1990 + 1991 + [[package]] 1992 + name = "malloc_buf" 1993 + version = "0.0.6" 1994 + source = "registry+https://github.com/rust-lang/crates.io-index" 1995 + checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" 1996 + dependencies = [ 1997 + "libc", 1998 + ] 1999 + 2000 + [[package]] 2001 + name = "match-lookup" 2002 + version = "0.1.1" 2003 + source = "registry+https://github.com/rust-lang/crates.io-index" 2004 + checksum = "1265724d8cb29dbbc2b0f06fffb8bf1a8c0cf73a78eede9ba73a4a66c52a981e" 2005 + dependencies = [ 2006 + "proc-macro2", 2007 + "quote", 2008 + "syn 1.0.109", 2009 + ] 2010 + 2011 + [[package]] 2012 + name = "memchr" 2013 + version = "2.7.6" 2014 + source = "registry+https://github.com/rust-lang/crates.io-index" 2015 + checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" 2016 + 2017 + [[package]] 2018 + name = "miette" 2019 + version = "7.6.0" 2020 + source = "registry+https://github.com/rust-lang/crates.io-index" 2021 + checksum = "5f98efec8807c63c752b5bd61f862c165c115b0a35685bdcfd9238c7aeb592b7" 2022 + dependencies = [ 2023 + "backtrace", 2024 + "backtrace-ext", 2025 + "cfg-if", 2026 + "miette-derive", 2027 + "owo-colors", 2028 + "supports-color", 2029 + "supports-hyperlinks", 2030 + "supports-unicode", 2031 + "terminal_size", 2032 + "textwrap", 2033 + "unicode-width 0.1.14", 2034 + ] 2035 + 2036 + [[package]] 2037 + name = "miette-derive" 2038 + version = "7.6.0" 2039 + source = "registry+https://github.com/rust-lang/crates.io-index" 2040 + checksum = "db5b29714e950dbb20d5e6f74f9dcec4edbcc1067bb7f8ed198c097b8c1a818b" 2041 + dependencies = [ 2042 + "proc-macro2", 2043 + "quote", 2044 + "syn 2.0.107", 2045 + ] 2046 + 2047 + [[package]] 2048 + name = "mime" 2049 + version = "0.3.17" 2050 + source = "registry+https://github.com/rust-lang/crates.io-index" 2051 + checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 2052 + 2053 + [[package]] 2054 + name = "mime_guess" 2055 + version = "2.0.5" 2056 + source = "registry+https://github.com/rust-lang/crates.io-index" 2057 + checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" 2058 + dependencies = [ 2059 + "mime", 2060 + "unicase", 2061 + ] 2062 + 2063 + [[package]] 2064 + name = "minimal-lexical" 2065 + version = "0.2.1" 2066 + source = "registry+https://github.com/rust-lang/crates.io-index" 2067 + checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 2068 + 2069 + [[package]] 2070 + name = "miniz_oxide" 2071 + version = "0.8.9" 2072 + source = "registry+https://github.com/rust-lang/crates.io-index" 2073 + checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" 2074 + dependencies = [ 2075 + "adler2", 2076 + "simd-adler32", 2077 + ] 2078 + 2079 + [[package]] 2080 + name = "mio" 2081 + version = "1.1.0" 2082 + source = "registry+https://github.com/rust-lang/crates.io-index" 2083 + checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" 2084 + dependencies = [ 2085 + "libc", 2086 + "wasi", 2087 + "windows-sys 0.61.2", 2088 + ] 2089 + 2090 + [[package]] 2091 + name = "multibase" 2092 + version = "0.9.2" 2093 + source = "registry+https://github.com/rust-lang/crates.io-index" 2094 + checksum = "8694bb4835f452b0e3bb06dbebb1d6fc5385b6ca1caf2e55fd165c042390ec77" 2095 + dependencies = [ 2096 + "base-x", 2097 + "base256emoji", 2098 + "data-encoding", 2099 + "data-encoding-macro", 2100 + ] 2101 + 2102 + [[package]] 2103 + name = "multihash" 2104 + version = "0.19.3" 2105 + source = "registry+https://github.com/rust-lang/crates.io-index" 2106 + checksum = "6b430e7953c29dd6a09afc29ff0bb69c6e306329ee6794700aee27b76a1aea8d" 2107 + dependencies = [ 2108 + "core2", 2109 + "serde", 2110 + "unsigned-varint", 2111 + ] 2112 + 2113 + [[package]] 2114 + name = "multipart" 2115 + version = "0.18.0" 2116 + source = "registry+https://github.com/rust-lang/crates.io-index" 2117 + checksum = "00dec633863867f29cb39df64a397cdf4a6354708ddd7759f70c7fb51c5f9182" 2118 + dependencies = [ 2119 + "buf_redux", 2120 + "httparse", 2121 + "log", 2122 + "mime", 2123 + "mime_guess", 2124 + "quick-error", 2125 + "rand 0.8.5", 2126 + "safemem", 2127 + "tempfile", 2128 + "twoway", 2129 + ] 2130 + 2131 + [[package]] 2132 + name = "native-tls" 2133 + version = "0.2.14" 2134 + source = "registry+https://github.com/rust-lang/crates.io-index" 2135 + checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" 2136 + dependencies = [ 2137 + "libc", 2138 + "log", 2139 + "openssl", 2140 + "openssl-probe", 2141 + "openssl-sys", 2142 + "schannel", 2143 + "security-framework", 2144 + "security-framework-sys", 2145 + "tempfile", 2146 + ] 2147 + 2148 + [[package]] 2149 + name = "ndk-context" 2150 + version = "0.1.1" 2151 + source = "registry+https://github.com/rust-lang/crates.io-index" 2152 + checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" 2153 + 2154 + [[package]] 2155 + name = "nom" 2156 + version = "7.1.3" 2157 + source = "registry+https://github.com/rust-lang/crates.io-index" 2158 + checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 2159 + dependencies = [ 2160 + "memchr", 2161 + "minimal-lexical", 2162 + ] 2163 + 2164 + [[package]] 2165 + name = "num-bigint-dig" 2166 + version = "0.8.4" 2167 + source = "registry+https://github.com/rust-lang/crates.io-index" 2168 + checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" 2169 + dependencies = [ 2170 + "byteorder", 2171 + "lazy_static", 2172 + "libm", 2173 + "num-integer", 2174 + "num-iter", 2175 + "num-traits", 2176 + "rand 0.8.5", 2177 + "smallvec", 2178 + "zeroize", 2179 + ] 2180 + 2181 + [[package]] 2182 + name = "num-conv" 7 2183 version = "0.1.0" 2184 + source = "registry+https://github.com/rust-lang/crates.io-index" 2185 + checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" 2186 + 2187 + [[package]] 2188 + name = "num-integer" 2189 + version = "0.1.46" 2190 + source = "registry+https://github.com/rust-lang/crates.io-index" 2191 + checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 2192 + dependencies = [ 2193 + "num-traits", 2194 + ] 2195 + 2196 + [[package]] 2197 + name = "num-iter" 2198 + version = "0.1.45" 2199 + source = "registry+https://github.com/rust-lang/crates.io-index" 2200 + checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" 2201 + dependencies = [ 2202 + "autocfg", 2203 + "num-integer", 2204 + "num-traits", 2205 + ] 2206 + 2207 + [[package]] 2208 + name = "num-traits" 2209 + version = "0.2.19" 2210 + source = "registry+https://github.com/rust-lang/crates.io-index" 2211 + checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 2212 + dependencies = [ 2213 + "autocfg", 2214 + "libm", 2215 + ] 2216 + 2217 + [[package]] 2218 + name = "num_cpus" 2219 + version = "1.17.0" 2220 + source = "registry+https://github.com/rust-lang/crates.io-index" 2221 + checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" 2222 + dependencies = [ 2223 + "hermit-abi", 2224 + "libc", 2225 + ] 2226 + 2227 + [[package]] 2228 + name = "num_threads" 2229 + version = "0.1.7" 2230 + source = "registry+https://github.com/rust-lang/crates.io-index" 2231 + checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" 2232 + dependencies = [ 2233 + "libc", 2234 + ] 2235 + 2236 + [[package]] 2237 + name = "objc" 2238 + version = "0.2.7" 2239 + source = "registry+https://github.com/rust-lang/crates.io-index" 2240 + checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" 2241 + dependencies = [ 2242 + "malloc_buf", 2243 + ] 2244 + 2245 + [[package]] 2246 + name = "object" 2247 + version = "0.37.3" 2248 + source = "registry+https://github.com/rust-lang/crates.io-index" 2249 + checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" 2250 + dependencies = [ 2251 + "memchr", 2252 + ] 2253 + 2254 + [[package]] 2255 + name = "once_cell" 2256 + version = "1.21.3" 2257 + source = "registry+https://github.com/rust-lang/crates.io-index" 2258 + checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 2259 + 2260 + [[package]] 2261 + name = "once_cell_polyfill" 2262 + version = "1.70.1" 2263 + source = "registry+https://github.com/rust-lang/crates.io-index" 2264 + checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" 2265 + 2266 + [[package]] 2267 + name = "openssl" 2268 + version = "0.10.74" 2269 + source = "registry+https://github.com/rust-lang/crates.io-index" 2270 + checksum = "24ad14dd45412269e1a30f52ad8f0664f0f4f4a89ee8fe28c3b3527021ebb654" 2271 + dependencies = [ 2272 + "bitflags", 2273 + "cfg-if", 2274 + "foreign-types", 2275 + "libc", 2276 + "once_cell", 2277 + "openssl-macros", 2278 + "openssl-sys", 2279 + ] 2280 + 2281 + [[package]] 2282 + name = "openssl-macros" 2283 + version = "0.1.1" 2284 + source = "registry+https://github.com/rust-lang/crates.io-index" 2285 + checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 2286 + dependencies = [ 2287 + "proc-macro2", 2288 + "quote", 2289 + "syn 2.0.107", 2290 + ] 2291 + 2292 + [[package]] 2293 + name = "openssl-probe" 2294 + version = "0.1.6" 2295 + source = "registry+https://github.com/rust-lang/crates.io-index" 2296 + checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" 2297 + 2298 + [[package]] 2299 + name = "openssl-sys" 2300 + version = "0.9.110" 2301 + source = "registry+https://github.com/rust-lang/crates.io-index" 2302 + checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2" 2303 + dependencies = [ 2304 + "cc", 2305 + "libc", 2306 + "pkg-config", 2307 + "vcpkg", 2308 + ] 2309 + 2310 + [[package]] 2311 + name = "ouroboros" 2312 + version = "0.18.5" 2313 + source = "registry+https://github.com/rust-lang/crates.io-index" 2314 + checksum = "1e0f050db9c44b97a94723127e6be766ac5c340c48f2c4bb3ffa11713744be59" 2315 + dependencies = [ 2316 + "aliasable", 2317 + "ouroboros_macro", 2318 + "static_assertions", 2319 + ] 2320 + 2321 + [[package]] 2322 + name = "ouroboros_macro" 2323 + version = "0.18.5" 2324 + source = "registry+https://github.com/rust-lang/crates.io-index" 2325 + checksum = "3c7028bdd3d43083f6d8d4d5187680d0d3560d54df4cc9d752005268b41e64d0" 2326 + dependencies = [ 2327 + "heck 0.4.1", 2328 + "proc-macro2", 2329 + "proc-macro2-diagnostics", 2330 + "quote", 2331 + "syn 2.0.107", 2332 + ] 2333 + 2334 + [[package]] 2335 + name = "owo-colors" 2336 + version = "4.2.3" 2337 + source = "registry+https://github.com/rust-lang/crates.io-index" 2338 + checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52" 2339 + 2340 + [[package]] 2341 + name = "p256" 2342 + version = "0.13.2" 2343 + source = "registry+https://github.com/rust-lang/crates.io-index" 2344 + checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" 2345 + dependencies = [ 2346 + "ecdsa", 2347 + "elliptic-curve", 2348 + "primeorder", 2349 + "sha2", 2350 + ] 2351 + 2352 + [[package]] 2353 + name = "p384" 2354 + version = "0.13.1" 2355 + source = "registry+https://github.com/rust-lang/crates.io-index" 2356 + checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" 2357 + dependencies = [ 2358 + "elliptic-curve", 2359 + "primeorder", 2360 + ] 2361 + 2362 + [[package]] 2363 + name = "parking_lot" 2364 + version = "0.12.5" 2365 + source = "registry+https://github.com/rust-lang/crates.io-index" 2366 + checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" 2367 + dependencies = [ 2368 + "lock_api", 2369 + "parking_lot_core", 2370 + ] 2371 + 2372 + [[package]] 2373 + name = "parking_lot_core" 2374 + version = "0.9.12" 2375 + source = "registry+https://github.com/rust-lang/crates.io-index" 2376 + checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" 2377 + dependencies = [ 2378 + "cfg-if", 2379 + "libc", 2380 + "redox_syscall", 2381 + "smallvec", 2382 + "windows-link 0.2.1", 2383 + ] 2384 + 2385 + [[package]] 2386 + name = "pem-rfc7468" 2387 + version = "0.7.0" 2388 + source = "registry+https://github.com/rust-lang/crates.io-index" 2389 + checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" 2390 + dependencies = [ 2391 + "base64ct", 2392 + ] 2393 + 2394 + [[package]] 2395 + name = "percent-encoding" 2396 + version = "2.3.2" 2397 + source = "registry+https://github.com/rust-lang/crates.io-index" 2398 + checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" 2399 + 2400 + [[package]] 2401 + name = "pin-project-lite" 2402 + version = "0.2.16" 2403 + source = "registry+https://github.com/rust-lang/crates.io-index" 2404 + checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 2405 + 2406 + [[package]] 2407 + name = "pin-utils" 2408 + version = "0.1.0" 2409 + source = "registry+https://github.com/rust-lang/crates.io-index" 2410 + checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 2411 + 2412 + [[package]] 2413 + name = "pkcs1" 2414 + version = "0.7.5" 2415 + source = "registry+https://github.com/rust-lang/crates.io-index" 2416 + checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" 2417 + dependencies = [ 2418 + "der", 2419 + "pkcs8", 2420 + "spki", 2421 + ] 2422 + 2423 + [[package]] 2424 + name = "pkcs8" 2425 + version = "0.10.2" 2426 + source = "registry+https://github.com/rust-lang/crates.io-index" 2427 + checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" 2428 + dependencies = [ 2429 + "der", 2430 + "spki", 2431 + ] 2432 + 2433 + [[package]] 2434 + name = "pkg-config" 2435 + version = "0.3.32" 2436 + source = "registry+https://github.com/rust-lang/crates.io-index" 2437 + checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" 2438 + 2439 + [[package]] 2440 + name = "portable-atomic" 2441 + version = "1.11.1" 2442 + source = "registry+https://github.com/rust-lang/crates.io-index" 2443 + checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" 2444 + 2445 + [[package]] 2446 + name = "portable-atomic-util" 2447 + version = "0.2.4" 2448 + source = "registry+https://github.com/rust-lang/crates.io-index" 2449 + checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" 2450 + dependencies = [ 2451 + "portable-atomic", 2452 + ] 2453 + 2454 + [[package]] 2455 + name = "potential_utf" 2456 + version = "0.1.3" 2457 + source = "registry+https://github.com/rust-lang/crates.io-index" 2458 + checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" 2459 + dependencies = [ 2460 + "zerovec", 2461 + ] 2462 + 2463 + [[package]] 2464 + name = "powerfmt" 2465 + version = "0.2.0" 2466 + source = "registry+https://github.com/rust-lang/crates.io-index" 2467 + checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" 2468 + 2469 + [[package]] 2470 + name = "ppv-lite86" 2471 + version = "0.2.21" 2472 + source = "registry+https://github.com/rust-lang/crates.io-index" 2473 + checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" 2474 + dependencies = [ 2475 + "zerocopy", 2476 + ] 2477 + 2478 + [[package]] 2479 + name = "prettyplease" 2480 + version = "0.2.37" 2481 + source = "registry+https://github.com/rust-lang/crates.io-index" 2482 + checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" 2483 + dependencies = [ 2484 + "proc-macro2", 2485 + "syn 2.0.107", 2486 + ] 2487 + 2488 + [[package]] 2489 + name = "primeorder" 2490 + version = "0.13.6" 2491 + source = "registry+https://github.com/rust-lang/crates.io-index" 2492 + checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" 2493 + dependencies = [ 2494 + "elliptic-curve", 2495 + ] 2496 + 2497 + [[package]] 2498 + name = "proc-macro-error" 2499 + version = "0.4.12" 2500 + source = "registry+https://github.com/rust-lang/crates.io-index" 2501 + checksum = "18f33027081eba0a6d8aba6d1b1c3a3be58cbb12106341c2d5759fcd9b5277e7" 2502 + dependencies = [ 2503 + "proc-macro-error-attr 0.4.12", 2504 + "proc-macro2", 2505 + "quote", 2506 + "syn 1.0.109", 2507 + "version_check", 2508 + ] 2509 + 2510 + [[package]] 2511 + name = "proc-macro-error" 2512 + version = "1.0.4" 2513 + source = "registry+https://github.com/rust-lang/crates.io-index" 2514 + checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 2515 + dependencies = [ 2516 + "proc-macro-error-attr 1.0.4", 2517 + "proc-macro2", 2518 + "quote", 2519 + "syn 1.0.109", 2520 + "version_check", 2521 + ] 2522 + 2523 + [[package]] 2524 + name = "proc-macro-error-attr" 2525 + version = "0.4.12" 2526 + source = "registry+https://github.com/rust-lang/crates.io-index" 2527 + checksum = "8a5b4b77fdb63c1eca72173d68d24501c54ab1269409f6b672c85deb18af69de" 2528 + dependencies = [ 2529 + "proc-macro2", 2530 + "quote", 2531 + "syn 1.0.109", 2532 + "syn-mid", 2533 + "version_check", 2534 + ] 2535 + 2536 + [[package]] 2537 + name = "proc-macro-error-attr" 2538 + version = "1.0.4" 2539 + source = "registry+https://github.com/rust-lang/crates.io-index" 2540 + checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 2541 + dependencies = [ 2542 + "proc-macro2", 2543 + "quote", 2544 + "version_check", 2545 + ] 2546 + 2547 + [[package]] 2548 + name = "proc-macro-hack" 2549 + version = "0.5.20+deprecated" 2550 + source = "registry+https://github.com/rust-lang/crates.io-index" 2551 + checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" 2552 + 2553 + [[package]] 2554 + name = "proc-macro2" 2555 + version = "1.0.101" 2556 + source = "registry+https://github.com/rust-lang/crates.io-index" 2557 + checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" 2558 + dependencies = [ 2559 + "unicode-ident", 2560 + ] 2561 + 2562 + [[package]] 2563 + name = "proc-macro2-diagnostics" 2564 + version = "0.10.1" 2565 + source = "registry+https://github.com/rust-lang/crates.io-index" 2566 + checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" 2567 + dependencies = [ 2568 + "proc-macro2", 2569 + "quote", 2570 + "syn 2.0.107", 2571 + "version_check", 2572 + "yansi", 2573 + ] 2574 + 2575 + [[package]] 2576 + name = "quick-error" 2577 + version = "1.2.3" 2578 + source = "registry+https://github.com/rust-lang/crates.io-index" 2579 + checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" 2580 + 2581 + [[package]] 2582 + name = "quinn" 2583 + version = "0.11.9" 2584 + source = "registry+https://github.com/rust-lang/crates.io-index" 2585 + checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" 2586 + dependencies = [ 2587 + "bytes", 2588 + "cfg_aliases", 2589 + "pin-project-lite", 2590 + "quinn-proto", 2591 + "quinn-udp", 2592 + "rustc-hash", 2593 + "rustls", 2594 + "socket2 0.6.1", 2595 + "thiserror 2.0.17", 2596 + "tokio", 2597 + "tracing", 2598 + "web-time", 2599 + ] 2600 + 2601 + [[package]] 2602 + name = "quinn-proto" 2603 + version = "0.11.13" 2604 + source = "registry+https://github.com/rust-lang/crates.io-index" 2605 + checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" 2606 + dependencies = [ 2607 + "bytes", 2608 + "getrandom 0.3.4", 2609 + "lru-slab", 2610 + "rand 0.9.2", 2611 + "ring", 2612 + "rustc-hash", 2613 + "rustls", 2614 + "rustls-pki-types", 2615 + "slab", 2616 + "thiserror 2.0.17", 2617 + "tinyvec", 2618 + "tracing", 2619 + "web-time", 2620 + ] 2621 + 2622 + [[package]] 2623 + name = "quinn-udp" 2624 + version = "0.5.14" 2625 + source = "registry+https://github.com/rust-lang/crates.io-index" 2626 + checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" 2627 + dependencies = [ 2628 + "cfg_aliases", 2629 + "libc", 2630 + "once_cell", 2631 + "socket2 0.6.1", 2632 + "tracing", 2633 + "windows-sys 0.60.2", 2634 + ] 2635 + 2636 + [[package]] 2637 + name = "quote" 2638 + version = "1.0.41" 2639 + source = "registry+https://github.com/rust-lang/crates.io-index" 2640 + checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" 2641 + dependencies = [ 2642 + "proc-macro2", 2643 + ] 2644 + 2645 + [[package]] 2646 + name = "r-efi" 2647 + version = "5.3.0" 2648 + source = "registry+https://github.com/rust-lang/crates.io-index" 2649 + checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" 2650 + 2651 + [[package]] 2652 + name = "rand" 2653 + version = "0.8.5" 2654 + source = "registry+https://github.com/rust-lang/crates.io-index" 2655 + checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 2656 + dependencies = [ 2657 + "libc", 2658 + "rand_chacha 0.3.1", 2659 + "rand_core 0.6.4", 2660 + ] 2661 + 2662 + [[package]] 2663 + name = "rand" 2664 + version = "0.9.2" 2665 + source = "registry+https://github.com/rust-lang/crates.io-index" 2666 + checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" 2667 + dependencies = [ 2668 + "rand_chacha 0.9.0", 2669 + "rand_core 0.9.3", 2670 + ] 2671 + 2672 + [[package]] 2673 + name = "rand_chacha" 2674 + version = "0.3.1" 2675 + source = "registry+https://github.com/rust-lang/crates.io-index" 2676 + checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 2677 + dependencies = [ 2678 + "ppv-lite86", 2679 + "rand_core 0.6.4", 2680 + ] 2681 + 2682 + [[package]] 2683 + name = "rand_chacha" 2684 + version = "0.9.0" 2685 + source = "registry+https://github.com/rust-lang/crates.io-index" 2686 + checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" 2687 + dependencies = [ 2688 + "ppv-lite86", 2689 + "rand_core 0.9.3", 2690 + ] 2691 + 2692 + [[package]] 2693 + name = "rand_core" 2694 + version = "0.6.4" 2695 + source = "registry+https://github.com/rust-lang/crates.io-index" 2696 + checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 2697 + dependencies = [ 2698 + "getrandom 0.2.16", 2699 + ] 2700 + 2701 + [[package]] 2702 + name = "rand_core" 2703 + version = "0.9.3" 2704 + source = "registry+https://github.com/rust-lang/crates.io-index" 2705 + checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" 2706 + dependencies = [ 2707 + "getrandom 0.3.4", 2708 + ] 2709 + 2710 + [[package]] 2711 + name = "range-traits" 2712 + version = "0.3.2" 2713 + source = "registry+https://github.com/rust-lang/crates.io-index" 2714 + checksum = "d20581732dd76fa913c7dff1a2412b714afe3573e94d41c34719de73337cc8ab" 2715 + 2716 + [[package]] 2717 + name = "raw-window-handle" 2718 + version = "0.5.2" 2719 + source = "registry+https://github.com/rust-lang/crates.io-index" 2720 + checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" 2721 + 2722 + [[package]] 2723 + name = "redox_syscall" 2724 + version = "0.5.18" 2725 + source = "registry+https://github.com/rust-lang/crates.io-index" 2726 + checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" 2727 + dependencies = [ 2728 + "bitflags", 2729 + ] 2730 + 2731 + [[package]] 2732 + name = "regex" 2733 + version = "1.12.2" 2734 + source = "registry+https://github.com/rust-lang/crates.io-index" 2735 + checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" 2736 + dependencies = [ 2737 + "aho-corasick", 2738 + "memchr", 2739 + "regex-automata", 2740 + "regex-syntax", 2741 + ] 2742 + 2743 + [[package]] 2744 + name = "regex-automata" 2745 + version = "0.4.13" 2746 + source = "registry+https://github.com/rust-lang/crates.io-index" 2747 + checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" 2748 + dependencies = [ 2749 + "aho-corasick", 2750 + "memchr", 2751 + "regex-syntax", 2752 + ] 2753 + 2754 + [[package]] 2755 + name = "regex-syntax" 2756 + version = "0.8.8" 2757 + source = "registry+https://github.com/rust-lang/crates.io-index" 2758 + checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" 2759 + 2760 + [[package]] 2761 + name = "reqwest" 2762 + version = "0.12.24" 2763 + source = "registry+https://github.com/rust-lang/crates.io-index" 2764 + checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" 2765 + dependencies = [ 2766 + "async-compression", 2767 + "base64 0.22.1", 2768 + "bytes", 2769 + "encoding_rs", 2770 + "futures-core", 2771 + "futures-util", 2772 + "h2", 2773 + "http", 2774 + "http-body", 2775 + "http-body-util", 2776 + "hyper", 2777 + "hyper-rustls", 2778 + "hyper-tls", 2779 + "hyper-util", 2780 + "js-sys", 2781 + "log", 2782 + "mime", 2783 + "native-tls", 2784 + "percent-encoding", 2785 + "pin-project-lite", 2786 + "quinn", 2787 + "rustls", 2788 + "rustls-pki-types", 2789 + "serde", 2790 + "serde_json", 2791 + "serde_urlencoded", 2792 + "sync_wrapper", 2793 + "tokio", 2794 + "tokio-native-tls", 2795 + "tokio-rustls", 2796 + "tokio-util", 2797 + "tower", 2798 + "tower-http", 2799 + "tower-service", 2800 + "url", 2801 + "wasm-bindgen", 2802 + "wasm-bindgen-futures", 2803 + "wasm-streams", 2804 + "web-sys", 2805 + "webpki-roots", 2806 + ] 2807 + 2808 + [[package]] 2809 + name = "resolv-conf" 2810 + version = "0.7.5" 2811 + source = "registry+https://github.com/rust-lang/crates.io-index" 2812 + checksum = "6b3789b30bd25ba102de4beabd95d21ac45b69b1be7d14522bab988c526d6799" 2813 + 2814 + [[package]] 2815 + name = "rfc6979" 2816 + version = "0.4.0" 2817 + source = "registry+https://github.com/rust-lang/crates.io-index" 2818 + checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" 2819 + dependencies = [ 2820 + "hmac", 2821 + "subtle", 2822 + ] 2823 + 2824 + [[package]] 2825 + name = "ring" 2826 + version = "0.17.14" 2827 + source = "registry+https://github.com/rust-lang/crates.io-index" 2828 + checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" 2829 + dependencies = [ 2830 + "cc", 2831 + "cfg-if", 2832 + "getrandom 0.2.16", 2833 + "libc", 2834 + "untrusted", 2835 + "windows-sys 0.52.0", 2836 + ] 2837 + 2838 + [[package]] 2839 + name = "rouille" 2840 + version = "3.6.2" 2841 + source = "registry+https://github.com/rust-lang/crates.io-index" 2842 + checksum = "3716fbf57fc1084d7a706adf4e445298d123e4a44294c4e8213caf1b85fcc921" 2843 + dependencies = [ 2844 + "base64 0.13.1", 2845 + "brotli", 2846 + "chrono", 2847 + "deflate", 2848 + "filetime", 2849 + "multipart", 2850 + "percent-encoding", 2851 + "rand 0.8.5", 2852 + "serde", 2853 + "serde_derive", 2854 + "serde_json", 2855 + "sha1_smol", 2856 + "threadpool", 2857 + "time", 2858 + "tiny_http", 2859 + "url", 2860 + ] 2861 + 2862 + [[package]] 2863 + name = "rsa" 2864 + version = "0.9.8" 2865 + source = "registry+https://github.com/rust-lang/crates.io-index" 2866 + checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b" 2867 + dependencies = [ 2868 + "const-oid", 2869 + "digest", 2870 + "num-bigint-dig", 2871 + "num-integer", 2872 + "num-traits", 2873 + "pkcs1", 2874 + "pkcs8", 2875 + "rand_core 0.6.4", 2876 + "signature", 2877 + "spki", 2878 + "subtle", 2879 + "zeroize", 2880 + ] 2881 + 2882 + [[package]] 2883 + name = "rustc-demangle" 2884 + version = "0.1.26" 2885 + source = "registry+https://github.com/rust-lang/crates.io-index" 2886 + checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" 2887 + 2888 + [[package]] 2889 + name = "rustc-hash" 2890 + version = "2.1.1" 2891 + source = "registry+https://github.com/rust-lang/crates.io-index" 2892 + checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" 2893 + 2894 + [[package]] 2895 + name = "rustix" 2896 + version = "1.1.2" 2897 + source = "registry+https://github.com/rust-lang/crates.io-index" 2898 + checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" 2899 + dependencies = [ 2900 + "bitflags", 2901 + "errno", 2902 + "libc", 2903 + "linux-raw-sys", 2904 + "windows-sys 0.61.2", 2905 + ] 2906 + 2907 + [[package]] 2908 + name = "rustls" 2909 + version = "0.23.33" 2910 + source = "registry+https://github.com/rust-lang/crates.io-index" 2911 + checksum = "751e04a496ca00bb97a5e043158d23d66b5aabf2e1d5aa2a0aaebb1aafe6f82c" 2912 + dependencies = [ 2913 + "once_cell", 2914 + "ring", 2915 + "rustls-pki-types", 2916 + "rustls-webpki", 2917 + "subtle", 2918 + "zeroize", 2919 + ] 2920 + 2921 + [[package]] 2922 + name = "rustls-pki-types" 2923 + version = "1.12.0" 2924 + source = "registry+https://github.com/rust-lang/crates.io-index" 2925 + checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" 2926 + dependencies = [ 2927 + "web-time", 2928 + "zeroize", 2929 + ] 2930 + 2931 + [[package]] 2932 + name = "rustls-webpki" 2933 + version = "0.103.7" 2934 + source = "registry+https://github.com/rust-lang/crates.io-index" 2935 + checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" 2936 + dependencies = [ 2937 + "ring", 2938 + "rustls-pki-types", 2939 + "untrusted", 2940 + ] 2941 + 2942 + [[package]] 2943 + name = "rustversion" 2944 + version = "1.0.22" 2945 + source = "registry+https://github.com/rust-lang/crates.io-index" 2946 + checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" 2947 + 2948 + [[package]] 2949 + name = "ryu" 2950 + version = "1.0.20" 2951 + source = "registry+https://github.com/rust-lang/crates.io-index" 2952 + checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 2953 + 2954 + [[package]] 2955 + name = "safemem" 2956 + version = "0.3.3" 2957 + source = "registry+https://github.com/rust-lang/crates.io-index" 2958 + checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" 2959 + 2960 + [[package]] 2961 + name = "same-file" 2962 + version = "1.0.6" 2963 + source = "registry+https://github.com/rust-lang/crates.io-index" 2964 + checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 2965 + dependencies = [ 2966 + "winapi-util", 2967 + ] 2968 + 2969 + [[package]] 2970 + name = "schannel" 2971 + version = "0.1.28" 2972 + source = "registry+https://github.com/rust-lang/crates.io-index" 2973 + checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" 2974 + dependencies = [ 2975 + "windows-sys 0.61.2", 2976 + ] 2977 + 2978 + [[package]] 2979 + name = "scopeguard" 2980 + version = "1.2.0" 2981 + source = "registry+https://github.com/rust-lang/crates.io-index" 2982 + checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 2983 + 2984 + [[package]] 2985 + name = "sec1" 2986 + version = "0.7.3" 2987 + source = "registry+https://github.com/rust-lang/crates.io-index" 2988 + checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" 2989 + dependencies = [ 2990 + "base16ct", 2991 + "der", 2992 + "generic-array", 2993 + "pkcs8", 2994 + "subtle", 2995 + "zeroize", 2996 + ] 2997 + 2998 + [[package]] 2999 + name = "security-framework" 3000 + version = "2.11.1" 3001 + source = "registry+https://github.com/rust-lang/crates.io-index" 3002 + checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" 3003 + dependencies = [ 3004 + "bitflags", 3005 + "core-foundation", 3006 + "core-foundation-sys", 3007 + "libc", 3008 + "security-framework-sys", 3009 + ] 3010 + 3011 + [[package]] 3012 + name = "security-framework-sys" 3013 + version = "2.15.0" 3014 + source = "registry+https://github.com/rust-lang/crates.io-index" 3015 + checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" 3016 + dependencies = [ 3017 + "core-foundation-sys", 3018 + "libc", 3019 + ] 3020 + 3021 + [[package]] 3022 + name = "serde" 3023 + version = "1.0.228" 3024 + source = "registry+https://github.com/rust-lang/crates.io-index" 3025 + checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" 3026 + dependencies = [ 3027 + "serde_core", 3028 + "serde_derive", 3029 + ] 3030 + 3031 + [[package]] 3032 + name = "serde_bytes" 3033 + version = "0.11.19" 3034 + source = "registry+https://github.com/rust-lang/crates.io-index" 3035 + checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" 3036 + dependencies = [ 3037 + "serde", 3038 + "serde_core", 3039 + ] 3040 + 3041 + [[package]] 3042 + name = "serde_core" 3043 + version = "1.0.228" 3044 + source = "registry+https://github.com/rust-lang/crates.io-index" 3045 + checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" 3046 + dependencies = [ 3047 + "serde_derive", 3048 + ] 3049 + 3050 + [[package]] 3051 + name = "serde_derive" 3052 + version = "1.0.228" 3053 + source = "registry+https://github.com/rust-lang/crates.io-index" 3054 + checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" 3055 + dependencies = [ 3056 + "proc-macro2", 3057 + "quote", 3058 + "syn 2.0.107", 3059 + ] 3060 + 3061 + [[package]] 3062 + name = "serde_html_form" 3063 + version = "0.2.8" 3064 + source = "registry+https://github.com/rust-lang/crates.io-index" 3065 + checksum = "b2f2d7ff8a2140333718bb329f5c40fc5f0865b84c426183ce14c97d2ab8154f" 3066 + dependencies = [ 3067 + "form_urlencoded", 3068 + "indexmap", 3069 + "itoa", 3070 + "ryu", 3071 + "serde_core", 3072 + ] 3073 + 3074 + [[package]] 3075 + name = "serde_ipld_dagcbor" 3076 + version = "0.6.4" 3077 + source = "registry+https://github.com/rust-lang/crates.io-index" 3078 + checksum = "46182f4f08349a02b45c998ba3215d3f9de826246ba02bb9dddfe9a2a2100778" 3079 + dependencies = [ 3080 + "cbor4ii", 3081 + "ipld-core", 3082 + "scopeguard", 3083 + "serde", 3084 + ] 3085 + 3086 + [[package]] 3087 + name = "serde_json" 3088 + version = "1.0.145" 3089 + source = "registry+https://github.com/rust-lang/crates.io-index" 3090 + checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" 3091 + dependencies = [ 3092 + "itoa", 3093 + "memchr", 3094 + "ryu", 3095 + "serde", 3096 + "serde_core", 3097 + ] 3098 + 3099 + [[package]] 3100 + name = "serde_urlencoded" 3101 + version = "0.7.1" 3102 + source = "registry+https://github.com/rust-lang/crates.io-index" 3103 + checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 3104 + dependencies = [ 3105 + "form_urlencoded", 3106 + "itoa", 3107 + "ryu", 3108 + "serde", 3109 + ] 3110 + 3111 + [[package]] 3112 + name = "sha1_smol" 3113 + version = "1.0.1" 3114 + source = "registry+https://github.com/rust-lang/crates.io-index" 3115 + checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" 3116 + 3117 + [[package]] 3118 + name = "sha2" 3119 + version = "0.10.9" 3120 + source = "registry+https://github.com/rust-lang/crates.io-index" 3121 + checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" 3122 + dependencies = [ 3123 + "cfg-if", 3124 + "cpufeatures", 3125 + "digest", 3126 + ] 3127 + 3128 + [[package]] 3129 + name = "shlex" 3130 + version = "1.3.0" 3131 + source = "registry+https://github.com/rust-lang/crates.io-index" 3132 + checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 3133 + 3134 + [[package]] 3135 + name = "signature" 3136 + version = "2.2.0" 3137 + source = "registry+https://github.com/rust-lang/crates.io-index" 3138 + checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" 3139 + dependencies = [ 3140 + "digest", 3141 + "rand_core 0.6.4", 3142 + ] 3143 + 3144 + [[package]] 3145 + name = "simd-adler32" 3146 + version = "0.3.7" 3147 + source = "registry+https://github.com/rust-lang/crates.io-index" 3148 + checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" 3149 + 3150 + [[package]] 3151 + name = "slab" 3152 + version = "0.4.11" 3153 + source = "registry+https://github.com/rust-lang/crates.io-index" 3154 + checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" 3155 + 3156 + [[package]] 3157 + name = "smallvec" 3158 + version = "1.15.1" 3159 + source = "registry+https://github.com/rust-lang/crates.io-index" 3160 + checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" 3161 + 3162 + [[package]] 3163 + name = "smol_str" 3164 + version = "0.3.2" 3165 + source = "registry+https://github.com/rust-lang/crates.io-index" 3166 + checksum = "9676b89cd56310a87b93dec47b11af744f34d5fc9f367b829474eec0a891350d" 3167 + dependencies = [ 3168 + "borsh", 3169 + "serde", 3170 + ] 3171 + 3172 + [[package]] 3173 + name = "socket2" 3174 + version = "0.5.10" 3175 + source = "registry+https://github.com/rust-lang/crates.io-index" 3176 + checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" 3177 + dependencies = [ 3178 + "libc", 3179 + "windows-sys 0.52.0", 3180 + ] 3181 + 3182 + [[package]] 3183 + name = "socket2" 3184 + version = "0.6.1" 3185 + source = "registry+https://github.com/rust-lang/crates.io-index" 3186 + checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" 3187 + dependencies = [ 3188 + "libc", 3189 + "windows-sys 0.60.2", 3190 + ] 3191 + 3192 + [[package]] 3193 + name = "spin" 3194 + version = "0.9.8" 3195 + source = "registry+https://github.com/rust-lang/crates.io-index" 3196 + checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 3197 + 3198 + [[package]] 3199 + name = "spki" 3200 + version = "0.7.3" 3201 + source = "registry+https://github.com/rust-lang/crates.io-index" 3202 + checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" 3203 + dependencies = [ 3204 + "base64ct", 3205 + "der", 3206 + ] 3207 + 3208 + [[package]] 3209 + name = "stable_deref_trait" 3210 + version = "1.2.1" 3211 + source = "registry+https://github.com/rust-lang/crates.io-index" 3212 + checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" 3213 + 3214 + [[package]] 3215 + name = "static-regular-grammar" 3216 + version = "2.0.2" 3217 + source = "registry+https://github.com/rust-lang/crates.io-index" 3218 + checksum = "4f4a6c40247579acfbb138c3cd7de3dab113ab4ac6227f1b7de7d626ee667957" 3219 + dependencies = [ 3220 + "abnf", 3221 + "btree-range-map", 3222 + "ciborium", 3223 + "hex_fmt", 3224 + "indoc", 3225 + "proc-macro-error 1.0.4", 3226 + "proc-macro2", 3227 + "quote", 3228 + "serde", 3229 + "sha2", 3230 + "syn 2.0.107", 3231 + "thiserror 1.0.69", 3232 + ] 3233 + 3234 + [[package]] 3235 + name = "static_assertions" 3236 + version = "1.1.0" 3237 + source = "registry+https://github.com/rust-lang/crates.io-index" 3238 + checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 3239 + 3240 + [[package]] 3241 + name = "strsim" 3242 + version = "0.11.1" 3243 + source = "registry+https://github.com/rust-lang/crates.io-index" 3244 + checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 3245 + 3246 + [[package]] 3247 + name = "subtle" 3248 + version = "2.6.1" 3249 + source = "registry+https://github.com/rust-lang/crates.io-index" 3250 + checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 3251 + 3252 + [[package]] 3253 + name = "supports-color" 3254 + version = "3.0.2" 3255 + source = "registry+https://github.com/rust-lang/crates.io-index" 3256 + checksum = "c64fc7232dd8d2e4ac5ce4ef302b1d81e0b80d055b9d77c7c4f51f6aa4c867d6" 3257 + dependencies = [ 3258 + "is_ci", 3259 + ] 3260 + 3261 + [[package]] 3262 + name = "supports-hyperlinks" 3263 + version = "3.1.0" 3264 + source = "registry+https://github.com/rust-lang/crates.io-index" 3265 + checksum = "804f44ed3c63152de6a9f90acbea1a110441de43006ea51bcce8f436196a288b" 3266 + 3267 + [[package]] 3268 + name = "supports-unicode" 3269 + version = "3.0.0" 3270 + source = "registry+https://github.com/rust-lang/crates.io-index" 3271 + checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" 3272 + 3273 + [[package]] 3274 + name = "syn" 3275 + version = "1.0.109" 3276 + source = "registry+https://github.com/rust-lang/crates.io-index" 3277 + checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 3278 + dependencies = [ 3279 + "proc-macro2", 3280 + "quote", 3281 + "unicode-ident", 3282 + ] 3283 + 3284 + [[package]] 3285 + name = "syn" 3286 + version = "2.0.107" 3287 + source = "registry+https://github.com/rust-lang/crates.io-index" 3288 + checksum = "2a26dbd934e5451d21ef060c018dae56fc073894c5a7896f882928a76e6d081b" 3289 + dependencies = [ 3290 + "proc-macro2", 3291 + "quote", 3292 + "unicode-ident", 3293 + ] 3294 + 3295 + [[package]] 3296 + name = "syn-mid" 3297 + version = "0.5.4" 3298 + source = "registry+https://github.com/rust-lang/crates.io-index" 3299 + checksum = "fea305d57546cc8cd04feb14b62ec84bf17f50e3f7b12560d7bfa9265f39d9ed" 3300 + dependencies = [ 3301 + "proc-macro2", 3302 + "quote", 3303 + "syn 1.0.109", 3304 + ] 3305 + 3306 + [[package]] 3307 + name = "sync_wrapper" 3308 + version = "1.0.2" 3309 + source = "registry+https://github.com/rust-lang/crates.io-index" 3310 + checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" 3311 + dependencies = [ 3312 + "futures-core", 3313 + ] 3314 + 3315 + [[package]] 3316 + name = "synstructure" 3317 + version = "0.13.2" 3318 + source = "registry+https://github.com/rust-lang/crates.io-index" 3319 + checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" 3320 + dependencies = [ 3321 + "proc-macro2", 3322 + "quote", 3323 + "syn 2.0.107", 3324 + ] 3325 + 3326 + [[package]] 3327 + name = "system-configuration" 3328 + version = "0.6.1" 3329 + source = "registry+https://github.com/rust-lang/crates.io-index" 3330 + checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" 3331 + dependencies = [ 3332 + "bitflags", 3333 + "core-foundation", 3334 + "system-configuration-sys", 3335 + ] 3336 + 3337 + [[package]] 3338 + name = "system-configuration-sys" 3339 + version = "0.6.0" 3340 + source = "registry+https://github.com/rust-lang/crates.io-index" 3341 + checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" 3342 + dependencies = [ 3343 + "core-foundation-sys", 3344 + "libc", 3345 + ] 3346 + 3347 + [[package]] 3348 + name = "tempfile" 3349 + version = "3.23.0" 3350 + source = "registry+https://github.com/rust-lang/crates.io-index" 3351 + checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" 3352 + dependencies = [ 3353 + "fastrand", 3354 + "getrandom 0.3.4", 3355 + "once_cell", 3356 + "rustix", 3357 + "windows-sys 0.61.2", 3358 + ] 3359 + 3360 + [[package]] 3361 + name = "terminal_size" 3362 + version = "0.4.3" 3363 + source = "registry+https://github.com/rust-lang/crates.io-index" 3364 + checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0" 3365 + dependencies = [ 3366 + "rustix", 3367 + "windows-sys 0.60.2", 3368 + ] 3369 + 3370 + [[package]] 3371 + name = "textwrap" 3372 + version = "0.16.2" 3373 + source = "registry+https://github.com/rust-lang/crates.io-index" 3374 + checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" 3375 + dependencies = [ 3376 + "unicode-linebreak", 3377 + "unicode-width 0.2.2", 3378 + ] 3379 + 3380 + [[package]] 3381 + name = "thiserror" 3382 + version = "1.0.69" 3383 + source = "registry+https://github.com/rust-lang/crates.io-index" 3384 + checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" 3385 + dependencies = [ 3386 + "thiserror-impl 1.0.69", 3387 + ] 3388 + 3389 + [[package]] 3390 + name = "thiserror" 3391 + version = "2.0.17" 3392 + source = "registry+https://github.com/rust-lang/crates.io-index" 3393 + checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" 3394 + dependencies = [ 3395 + "thiserror-impl 2.0.17", 3396 + ] 3397 + 3398 + [[package]] 3399 + name = "thiserror-impl" 3400 + version = "1.0.69" 3401 + source = "registry+https://github.com/rust-lang/crates.io-index" 3402 + checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" 3403 + dependencies = [ 3404 + "proc-macro2", 3405 + "quote", 3406 + "syn 2.0.107", 3407 + ] 3408 + 3409 + [[package]] 3410 + name = "thiserror-impl" 3411 + version = "2.0.17" 3412 + source = "registry+https://github.com/rust-lang/crates.io-index" 3413 + checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" 3414 + dependencies = [ 3415 + "proc-macro2", 3416 + "quote", 3417 + "syn 2.0.107", 3418 + ] 3419 + 3420 + [[package]] 3421 + name = "threadpool" 3422 + version = "1.8.1" 3423 + source = "registry+https://github.com/rust-lang/crates.io-index" 3424 + checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" 3425 + dependencies = [ 3426 + "num_cpus", 3427 + ] 3428 + 3429 + [[package]] 3430 + name = "time" 3431 + version = "0.3.44" 3432 + source = "registry+https://github.com/rust-lang/crates.io-index" 3433 + checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" 3434 + dependencies = [ 3435 + "deranged", 3436 + "libc", 3437 + "num-conv", 3438 + "num_threads", 3439 + "powerfmt", 3440 + "serde", 3441 + "time-core", 3442 + ] 3443 + 3444 + [[package]] 3445 + name = "time-core" 3446 + version = "0.1.6" 3447 + source = "registry+https://github.com/rust-lang/crates.io-index" 3448 + checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" 3449 + 3450 + [[package]] 3451 + name = "tiny_http" 3452 + version = "0.12.0" 3453 + source = "registry+https://github.com/rust-lang/crates.io-index" 3454 + checksum = "389915df6413a2e74fb181895f933386023c71110878cd0825588928e64cdc82" 3455 + dependencies = [ 3456 + "ascii", 3457 + "chunked_transfer", 3458 + "httpdate", 3459 + "log", 3460 + ] 3461 + 3462 + [[package]] 3463 + name = "tinystr" 3464 + version = "0.8.1" 3465 + source = "registry+https://github.com/rust-lang/crates.io-index" 3466 + checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" 3467 + dependencies = [ 3468 + "displaydoc", 3469 + "zerovec", 3470 + ] 3471 + 3472 + [[package]] 3473 + name = "tinyvec" 3474 + version = "1.10.0" 3475 + source = "registry+https://github.com/rust-lang/crates.io-index" 3476 + checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" 3477 + dependencies = [ 3478 + "tinyvec_macros", 3479 + ] 3480 + 3481 + [[package]] 3482 + name = "tinyvec_macros" 3483 + version = "0.1.1" 3484 + source = "registry+https://github.com/rust-lang/crates.io-index" 3485 + checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 3486 + 3487 + [[package]] 3488 + name = "tokio" 3489 + version = "1.48.0" 3490 + source = "registry+https://github.com/rust-lang/crates.io-index" 3491 + checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" 3492 + dependencies = [ 3493 + "bytes", 3494 + "libc", 3495 + "mio", 3496 + "pin-project-lite", 3497 + "socket2 0.6.1", 3498 + "tokio-macros", 3499 + "windows-sys 0.61.2", 3500 + ] 3501 + 3502 + [[package]] 3503 + name = "tokio-macros" 3504 + version = "2.6.0" 3505 + source = "registry+https://github.com/rust-lang/crates.io-index" 3506 + checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" 3507 + dependencies = [ 3508 + "proc-macro2", 3509 + "quote", 3510 + "syn 2.0.107", 3511 + ] 3512 + 3513 + [[package]] 3514 + name = "tokio-native-tls" 3515 + version = "0.3.1" 3516 + source = "registry+https://github.com/rust-lang/crates.io-index" 3517 + checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" 3518 + dependencies = [ 3519 + "native-tls", 3520 + "tokio", 3521 + ] 3522 + 3523 + [[package]] 3524 + name = "tokio-rustls" 3525 + version = "0.26.4" 3526 + source = "registry+https://github.com/rust-lang/crates.io-index" 3527 + checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" 3528 + dependencies = [ 3529 + "rustls", 3530 + "tokio", 3531 + ] 3532 + 3533 + [[package]] 3534 + name = "tokio-util" 3535 + version = "0.7.16" 3536 + source = "registry+https://github.com/rust-lang/crates.io-index" 3537 + checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" 3538 + dependencies = [ 3539 + "bytes", 3540 + "futures-core", 3541 + "futures-sink", 3542 + "pin-project-lite", 3543 + "tokio", 3544 + ] 3545 + 3546 + [[package]] 3547 + name = "tower" 3548 + version = "0.5.2" 3549 + source = "registry+https://github.com/rust-lang/crates.io-index" 3550 + checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" 3551 + dependencies = [ 3552 + "futures-core", 3553 + "futures-util", 3554 + "pin-project-lite", 3555 + "sync_wrapper", 3556 + "tokio", 3557 + "tower-layer", 3558 + "tower-service", 3559 + ] 3560 + 3561 + [[package]] 3562 + name = "tower-http" 3563 + version = "0.6.6" 3564 + source = "registry+https://github.com/rust-lang/crates.io-index" 3565 + checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" 3566 + dependencies = [ 3567 + "bitflags", 3568 + "bytes", 3569 + "futures-util", 3570 + "http", 3571 + "http-body", 3572 + "iri-string", 3573 + "pin-project-lite", 3574 + "tower", 3575 + "tower-layer", 3576 + "tower-service", 3577 + ] 3578 + 3579 + [[package]] 3580 + name = "tower-layer" 3581 + version = "0.3.3" 3582 + source = "registry+https://github.com/rust-lang/crates.io-index" 3583 + checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" 3584 + 3585 + [[package]] 3586 + name = "tower-service" 3587 + version = "0.3.3" 3588 + source = "registry+https://github.com/rust-lang/crates.io-index" 3589 + checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 3590 + 3591 + [[package]] 3592 + name = "tracing" 3593 + version = "0.1.41" 3594 + source = "registry+https://github.com/rust-lang/crates.io-index" 3595 + checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 3596 + dependencies = [ 3597 + "pin-project-lite", 3598 + "tracing-attributes", 3599 + "tracing-core", 3600 + ] 3601 + 3602 + [[package]] 3603 + name = "tracing-attributes" 3604 + version = "0.1.30" 3605 + source = "registry+https://github.com/rust-lang/crates.io-index" 3606 + checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" 3607 + dependencies = [ 3608 + "proc-macro2", 3609 + "quote", 3610 + "syn 2.0.107", 3611 + ] 3612 + 3613 + [[package]] 3614 + name = "tracing-core" 3615 + version = "0.1.34" 3616 + source = "registry+https://github.com/rust-lang/crates.io-index" 3617 + checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" 3618 + dependencies = [ 3619 + "once_cell", 3620 + ] 3621 + 3622 + [[package]] 3623 + name = "trait-variant" 3624 + version = "0.1.2" 3625 + source = "registry+https://github.com/rust-lang/crates.io-index" 3626 + checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7" 3627 + dependencies = [ 3628 + "proc-macro2", 3629 + "quote", 3630 + "syn 2.0.107", 3631 + ] 3632 + 3633 + [[package]] 3634 + name = "try-lock" 3635 + version = "0.2.5" 3636 + source = "registry+https://github.com/rust-lang/crates.io-index" 3637 + checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 3638 + 3639 + [[package]] 3640 + name = "twoway" 3641 + version = "0.1.8" 3642 + source = "registry+https://github.com/rust-lang/crates.io-index" 3643 + checksum = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1" 3644 + dependencies = [ 3645 + "memchr", 3646 + ] 3647 + 3648 + [[package]] 3649 + name = "typenum" 3650 + version = "1.19.0" 3651 + source = "registry+https://github.com/rust-lang/crates.io-index" 3652 + checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" 3653 + 3654 + [[package]] 3655 + name = "unicase" 3656 + version = "2.8.1" 3657 + source = "registry+https://github.com/rust-lang/crates.io-index" 3658 + checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" 3659 + 3660 + [[package]] 3661 + name = "unicode-ident" 3662 + version = "1.0.19" 3663 + source = "registry+https://github.com/rust-lang/crates.io-index" 3664 + checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" 3665 + 3666 + [[package]] 3667 + name = "unicode-linebreak" 3668 + version = "0.1.5" 3669 + source = "registry+https://github.com/rust-lang/crates.io-index" 3670 + checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" 3671 + 3672 + [[package]] 3673 + name = "unicode-width" 3674 + version = "0.1.14" 3675 + source = "registry+https://github.com/rust-lang/crates.io-index" 3676 + checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" 3677 + 3678 + [[package]] 3679 + name = "unicode-width" 3680 + version = "0.2.2" 3681 + source = "registry+https://github.com/rust-lang/crates.io-index" 3682 + checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" 3683 + 3684 + [[package]] 3685 + name = "unsigned-varint" 3686 + version = "0.8.0" 3687 + source = "registry+https://github.com/rust-lang/crates.io-index" 3688 + checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" 3689 + 3690 + [[package]] 3691 + name = "untrusted" 3692 + version = "0.9.0" 3693 + source = "registry+https://github.com/rust-lang/crates.io-index" 3694 + checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 3695 + 3696 + [[package]] 3697 + name = "url" 3698 + version = "2.5.7" 3699 + source = "registry+https://github.com/rust-lang/crates.io-index" 3700 + checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" 3701 + dependencies = [ 3702 + "form_urlencoded", 3703 + "idna", 3704 + "percent-encoding", 3705 + "serde", 3706 + ] 3707 + 3708 + [[package]] 3709 + name = "urlencoding" 3710 + version = "2.1.3" 3711 + source = "registry+https://github.com/rust-lang/crates.io-index" 3712 + checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" 3713 + 3714 + [[package]] 3715 + name = "utf8_iter" 3716 + version = "1.0.4" 3717 + source = "registry+https://github.com/rust-lang/crates.io-index" 3718 + checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 3719 + 3720 + [[package]] 3721 + name = "utf8parse" 3722 + version = "0.2.2" 3723 + source = "registry+https://github.com/rust-lang/crates.io-index" 3724 + checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 3725 + 3726 + [[package]] 3727 + name = "vcpkg" 3728 + version = "0.2.15" 3729 + source = "registry+https://github.com/rust-lang/crates.io-index" 3730 + checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 3731 + 3732 + [[package]] 3733 + name = "version_check" 3734 + version = "0.9.5" 3735 + source = "registry+https://github.com/rust-lang/crates.io-index" 3736 + checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 3737 + 3738 + [[package]] 3739 + name = "walkdir" 3740 + version = "2.5.0" 3741 + source = "registry+https://github.com/rust-lang/crates.io-index" 3742 + checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" 3743 + dependencies = [ 3744 + "same-file", 3745 + "winapi-util", 3746 + ] 3747 + 3748 + [[package]] 3749 + name = "want" 3750 + version = "0.3.1" 3751 + source = "registry+https://github.com/rust-lang/crates.io-index" 3752 + checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 3753 + dependencies = [ 3754 + "try-lock", 3755 + ] 3756 + 3757 + [[package]] 3758 + name = "wasi" 3759 + version = "0.11.1+wasi-snapshot-preview1" 3760 + source = "registry+https://github.com/rust-lang/crates.io-index" 3761 + checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" 3762 + 3763 + [[package]] 3764 + name = "wasip2" 3765 + version = "1.0.1+wasi-0.2.4" 3766 + source = "registry+https://github.com/rust-lang/crates.io-index" 3767 + checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" 3768 + dependencies = [ 3769 + "wit-bindgen", 3770 + ] 3771 + 3772 + [[package]] 3773 + name = "wasm-bindgen" 3774 + version = "0.2.104" 3775 + source = "registry+https://github.com/rust-lang/crates.io-index" 3776 + checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" 3777 + dependencies = [ 3778 + "cfg-if", 3779 + "once_cell", 3780 + "rustversion", 3781 + "wasm-bindgen-macro", 3782 + "wasm-bindgen-shared", 3783 + ] 3784 + 3785 + [[package]] 3786 + name = "wasm-bindgen-backend" 3787 + version = "0.2.104" 3788 + source = "registry+https://github.com/rust-lang/crates.io-index" 3789 + checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" 3790 + dependencies = [ 3791 + "bumpalo", 3792 + "log", 3793 + "proc-macro2", 3794 + "quote", 3795 + "syn 2.0.107", 3796 + "wasm-bindgen-shared", 3797 + ] 3798 + 3799 + [[package]] 3800 + name = "wasm-bindgen-futures" 3801 + version = "0.4.54" 3802 + source = "registry+https://github.com/rust-lang/crates.io-index" 3803 + checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" 3804 + dependencies = [ 3805 + "cfg-if", 3806 + "js-sys", 3807 + "once_cell", 3808 + "wasm-bindgen", 3809 + "web-sys", 3810 + ] 3811 + 3812 + [[package]] 3813 + name = "wasm-bindgen-macro" 3814 + version = "0.2.104" 3815 + source = "registry+https://github.com/rust-lang/crates.io-index" 3816 + checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" 3817 + dependencies = [ 3818 + "quote", 3819 + "wasm-bindgen-macro-support", 3820 + ] 3821 + 3822 + [[package]] 3823 + name = "wasm-bindgen-macro-support" 3824 + version = "0.2.104" 3825 + source = "registry+https://github.com/rust-lang/crates.io-index" 3826 + checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" 3827 + dependencies = [ 3828 + "proc-macro2", 3829 + "quote", 3830 + "syn 2.0.107", 3831 + "wasm-bindgen-backend", 3832 + "wasm-bindgen-shared", 3833 + ] 3834 + 3835 + [[package]] 3836 + name = "wasm-bindgen-shared" 3837 + version = "0.2.104" 3838 + source = "registry+https://github.com/rust-lang/crates.io-index" 3839 + checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" 3840 + dependencies = [ 3841 + "unicode-ident", 3842 + ] 3843 + 3844 + [[package]] 3845 + name = "wasm-streams" 3846 + version = "0.4.2" 3847 + source = "registry+https://github.com/rust-lang/crates.io-index" 3848 + checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" 3849 + dependencies = [ 3850 + "futures-util", 3851 + "js-sys", 3852 + "wasm-bindgen", 3853 + "wasm-bindgen-futures", 3854 + "web-sys", 3855 + ] 3856 + 3857 + [[package]] 3858 + name = "web-sys" 3859 + version = "0.3.81" 3860 + source = "registry+https://github.com/rust-lang/crates.io-index" 3861 + checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" 3862 + dependencies = [ 3863 + "js-sys", 3864 + "wasm-bindgen", 3865 + ] 3866 + 3867 + [[package]] 3868 + name = "web-time" 3869 + version = "1.1.0" 3870 + source = "registry+https://github.com/rust-lang/crates.io-index" 3871 + checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" 3872 + dependencies = [ 3873 + "js-sys", 3874 + "wasm-bindgen", 3875 + ] 3876 + 3877 + [[package]] 3878 + name = "webbrowser" 3879 + version = "0.8.15" 3880 + source = "registry+https://github.com/rust-lang/crates.io-index" 3881 + checksum = "db67ae75a9405634f5882791678772c94ff5f16a66535aae186e26aa0841fc8b" 3882 + dependencies = [ 3883 + "core-foundation", 3884 + "home", 3885 + "jni", 3886 + "log", 3887 + "ndk-context", 3888 + "objc", 3889 + "raw-window-handle", 3890 + "url", 3891 + "web-sys", 3892 + ] 3893 + 3894 + [[package]] 3895 + name = "webpki-roots" 3896 + version = "1.0.3" 3897 + source = "registry+https://github.com/rust-lang/crates.io-index" 3898 + checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8" 3899 + dependencies = [ 3900 + "rustls-pki-types", 3901 + ] 3902 + 3903 + [[package]] 3904 + name = "widestring" 3905 + version = "1.2.1" 3906 + source = "registry+https://github.com/rust-lang/crates.io-index" 3907 + checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" 3908 + 3909 + [[package]] 3910 + name = "winapi-util" 3911 + version = "0.1.11" 3912 + source = "registry+https://github.com/rust-lang/crates.io-index" 3913 + checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" 3914 + dependencies = [ 3915 + "windows-sys 0.61.2", 3916 + ] 3917 + 3918 + [[package]] 3919 + name = "windows-core" 3920 + version = "0.62.2" 3921 + source = "registry+https://github.com/rust-lang/crates.io-index" 3922 + checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" 3923 + dependencies = [ 3924 + "windows-implement", 3925 + "windows-interface", 3926 + "windows-link 0.2.1", 3927 + "windows-result 0.4.1", 3928 + "windows-strings 0.5.1", 3929 + ] 3930 + 3931 + [[package]] 3932 + name = "windows-implement" 3933 + version = "0.60.2" 3934 + source = "registry+https://github.com/rust-lang/crates.io-index" 3935 + checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" 3936 + dependencies = [ 3937 + "proc-macro2", 3938 + "quote", 3939 + "syn 2.0.107", 3940 + ] 3941 + 3942 + [[package]] 3943 + name = "windows-interface" 3944 + version = "0.59.3" 3945 + source = "registry+https://github.com/rust-lang/crates.io-index" 3946 + checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" 3947 + dependencies = [ 3948 + "proc-macro2", 3949 + "quote", 3950 + "syn 2.0.107", 3951 + ] 3952 + 3953 + [[package]] 3954 + name = "windows-link" 3955 + version = "0.1.3" 3956 + source = "registry+https://github.com/rust-lang/crates.io-index" 3957 + checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" 3958 + 3959 + [[package]] 3960 + name = "windows-link" 3961 + version = "0.2.1" 3962 + source = "registry+https://github.com/rust-lang/crates.io-index" 3963 + checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" 3964 + 3965 + [[package]] 3966 + name = "windows-registry" 3967 + version = "0.5.3" 3968 + source = "registry+https://github.com/rust-lang/crates.io-index" 3969 + checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" 3970 + dependencies = [ 3971 + "windows-link 0.1.3", 3972 + "windows-result 0.3.4", 3973 + "windows-strings 0.4.2", 3974 + ] 3975 + 3976 + [[package]] 3977 + name = "windows-result" 3978 + version = "0.3.4" 3979 + source = "registry+https://github.com/rust-lang/crates.io-index" 3980 + checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" 3981 + dependencies = [ 3982 + "windows-link 0.1.3", 3983 + ] 3984 + 3985 + [[package]] 3986 + name = "windows-result" 3987 + version = "0.4.1" 3988 + source = "registry+https://github.com/rust-lang/crates.io-index" 3989 + checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" 3990 + dependencies = [ 3991 + "windows-link 0.2.1", 3992 + ] 3993 + 3994 + [[package]] 3995 + name = "windows-strings" 3996 + version = "0.4.2" 3997 + source = "registry+https://github.com/rust-lang/crates.io-index" 3998 + checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" 3999 + dependencies = [ 4000 + "windows-link 0.1.3", 4001 + ] 4002 + 4003 + [[package]] 4004 + name = "windows-strings" 4005 + version = "0.5.1" 4006 + source = "registry+https://github.com/rust-lang/crates.io-index" 4007 + checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" 4008 + dependencies = [ 4009 + "windows-link 0.2.1", 4010 + ] 4011 + 4012 + [[package]] 4013 + name = "windows-sys" 4014 + version = "0.45.0" 4015 + source = "registry+https://github.com/rust-lang/crates.io-index" 4016 + checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" 4017 + dependencies = [ 4018 + "windows-targets 0.42.2", 4019 + ] 4020 + 4021 + [[package]] 4022 + name = "windows-sys" 4023 + version = "0.48.0" 4024 + source = "registry+https://github.com/rust-lang/crates.io-index" 4025 + checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 4026 + dependencies = [ 4027 + "windows-targets 0.48.5", 4028 + ] 4029 + 4030 + [[package]] 4031 + name = "windows-sys" 4032 + version = "0.52.0" 4033 + source = "registry+https://github.com/rust-lang/crates.io-index" 4034 + checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 4035 + dependencies = [ 4036 + "windows-targets 0.52.6", 4037 + ] 4038 + 4039 + [[package]] 4040 + name = "windows-sys" 4041 + version = "0.59.0" 4042 + source = "registry+https://github.com/rust-lang/crates.io-index" 4043 + checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 4044 + dependencies = [ 4045 + "windows-targets 0.52.6", 4046 + ] 4047 + 4048 + [[package]] 4049 + name = "windows-sys" 4050 + version = "0.60.2" 4051 + source = "registry+https://github.com/rust-lang/crates.io-index" 4052 + checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" 4053 + dependencies = [ 4054 + "windows-targets 0.53.5", 4055 + ] 4056 + 4057 + [[package]] 4058 + name = "windows-sys" 4059 + version = "0.61.2" 4060 + source = "registry+https://github.com/rust-lang/crates.io-index" 4061 + checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" 4062 + dependencies = [ 4063 + "windows-link 0.2.1", 4064 + ] 4065 + 4066 + [[package]] 4067 + name = "windows-targets" 4068 + version = "0.42.2" 4069 + source = "registry+https://github.com/rust-lang/crates.io-index" 4070 + checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" 4071 + dependencies = [ 4072 + "windows_aarch64_gnullvm 0.42.2", 4073 + "windows_aarch64_msvc 0.42.2", 4074 + "windows_i686_gnu 0.42.2", 4075 + "windows_i686_msvc 0.42.2", 4076 + "windows_x86_64_gnu 0.42.2", 4077 + "windows_x86_64_gnullvm 0.42.2", 4078 + "windows_x86_64_msvc 0.42.2", 4079 + ] 4080 + 4081 + [[package]] 4082 + name = "windows-targets" 4083 + version = "0.48.5" 4084 + source = "registry+https://github.com/rust-lang/crates.io-index" 4085 + checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 4086 + dependencies = [ 4087 + "windows_aarch64_gnullvm 0.48.5", 4088 + "windows_aarch64_msvc 0.48.5", 4089 + "windows_i686_gnu 0.48.5", 4090 + "windows_i686_msvc 0.48.5", 4091 + "windows_x86_64_gnu 0.48.5", 4092 + "windows_x86_64_gnullvm 0.48.5", 4093 + "windows_x86_64_msvc 0.48.5", 4094 + ] 4095 + 4096 + [[package]] 4097 + name = "windows-targets" 4098 + version = "0.52.6" 4099 + source = "registry+https://github.com/rust-lang/crates.io-index" 4100 + checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 4101 + dependencies = [ 4102 + "windows_aarch64_gnullvm 0.52.6", 4103 + "windows_aarch64_msvc 0.52.6", 4104 + "windows_i686_gnu 0.52.6", 4105 + "windows_i686_gnullvm 0.52.6", 4106 + "windows_i686_msvc 0.52.6", 4107 + "windows_x86_64_gnu 0.52.6", 4108 + "windows_x86_64_gnullvm 0.52.6", 4109 + "windows_x86_64_msvc 0.52.6", 4110 + ] 4111 + 4112 + [[package]] 4113 + name = "windows-targets" 4114 + version = "0.53.5" 4115 + source = "registry+https://github.com/rust-lang/crates.io-index" 4116 + checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" 4117 + dependencies = [ 4118 + "windows-link 0.2.1", 4119 + "windows_aarch64_gnullvm 0.53.1", 4120 + "windows_aarch64_msvc 0.53.1", 4121 + "windows_i686_gnu 0.53.1", 4122 + "windows_i686_gnullvm 0.53.1", 4123 + "windows_i686_msvc 0.53.1", 4124 + "windows_x86_64_gnu 0.53.1", 4125 + "windows_x86_64_gnullvm 0.53.1", 4126 + "windows_x86_64_msvc 0.53.1", 4127 + ] 4128 + 4129 + [[package]] 4130 + name = "windows_aarch64_gnullvm" 4131 + version = "0.42.2" 4132 + source = "registry+https://github.com/rust-lang/crates.io-index" 4133 + checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" 4134 + 4135 + [[package]] 4136 + name = "windows_aarch64_gnullvm" 4137 + version = "0.48.5" 4138 + source = "registry+https://github.com/rust-lang/crates.io-index" 4139 + checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 4140 + 4141 + [[package]] 4142 + name = "windows_aarch64_gnullvm" 4143 + version = "0.52.6" 4144 + source = "registry+https://github.com/rust-lang/crates.io-index" 4145 + checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 4146 + 4147 + [[package]] 4148 + name = "windows_aarch64_gnullvm" 4149 + version = "0.53.1" 4150 + source = "registry+https://github.com/rust-lang/crates.io-index" 4151 + checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" 4152 + 4153 + [[package]] 4154 + name = "windows_aarch64_msvc" 4155 + version = "0.42.2" 4156 + source = "registry+https://github.com/rust-lang/crates.io-index" 4157 + checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" 4158 + 4159 + [[package]] 4160 + name = "windows_aarch64_msvc" 4161 + version = "0.48.5" 4162 + source = "registry+https://github.com/rust-lang/crates.io-index" 4163 + checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 4164 + 4165 + [[package]] 4166 + name = "windows_aarch64_msvc" 4167 + version = "0.52.6" 4168 + source = "registry+https://github.com/rust-lang/crates.io-index" 4169 + checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 4170 + 4171 + [[package]] 4172 + name = "windows_aarch64_msvc" 4173 + version = "0.53.1" 4174 + source = "registry+https://github.com/rust-lang/crates.io-index" 4175 + checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" 4176 + 4177 + [[package]] 4178 + name = "windows_i686_gnu" 4179 + version = "0.42.2" 4180 + source = "registry+https://github.com/rust-lang/crates.io-index" 4181 + checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" 4182 + 4183 + [[package]] 4184 + name = "windows_i686_gnu" 4185 + version = "0.48.5" 4186 + source = "registry+https://github.com/rust-lang/crates.io-index" 4187 + checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 4188 + 4189 + [[package]] 4190 + name = "windows_i686_gnu" 4191 + version = "0.52.6" 4192 + source = "registry+https://github.com/rust-lang/crates.io-index" 4193 + checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 4194 + 4195 + [[package]] 4196 + name = "windows_i686_gnu" 4197 + version = "0.53.1" 4198 + source = "registry+https://github.com/rust-lang/crates.io-index" 4199 + checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" 4200 + 4201 + [[package]] 4202 + name = "windows_i686_gnullvm" 4203 + version = "0.52.6" 4204 + source = "registry+https://github.com/rust-lang/crates.io-index" 4205 + checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 4206 + 4207 + [[package]] 4208 + name = "windows_i686_gnullvm" 4209 + version = "0.53.1" 4210 + source = "registry+https://github.com/rust-lang/crates.io-index" 4211 + checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" 4212 + 4213 + [[package]] 4214 + name = "windows_i686_msvc" 4215 + version = "0.42.2" 4216 + source = "registry+https://github.com/rust-lang/crates.io-index" 4217 + checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" 4218 + 4219 + [[package]] 4220 + name = "windows_i686_msvc" 4221 + version = "0.48.5" 4222 + source = "registry+https://github.com/rust-lang/crates.io-index" 4223 + checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 4224 + 4225 + [[package]] 4226 + name = "windows_i686_msvc" 4227 + version = "0.52.6" 4228 + source = "registry+https://github.com/rust-lang/crates.io-index" 4229 + checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 4230 + 4231 + [[package]] 4232 + name = "windows_i686_msvc" 4233 + version = "0.53.1" 4234 + source = "registry+https://github.com/rust-lang/crates.io-index" 4235 + checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" 4236 + 4237 + [[package]] 4238 + name = "windows_x86_64_gnu" 4239 + version = "0.42.2" 4240 + source = "registry+https://github.com/rust-lang/crates.io-index" 4241 + checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" 4242 + 4243 + [[package]] 4244 + name = "windows_x86_64_gnu" 4245 + version = "0.48.5" 4246 + source = "registry+https://github.com/rust-lang/crates.io-index" 4247 + checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 4248 + 4249 + [[package]] 4250 + name = "windows_x86_64_gnu" 4251 + version = "0.52.6" 4252 + source = "registry+https://github.com/rust-lang/crates.io-index" 4253 + checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 4254 + 4255 + [[package]] 4256 + name = "windows_x86_64_gnu" 4257 + version = "0.53.1" 4258 + source = "registry+https://github.com/rust-lang/crates.io-index" 4259 + checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" 4260 + 4261 + [[package]] 4262 + name = "windows_x86_64_gnullvm" 4263 + version = "0.42.2" 4264 + source = "registry+https://github.com/rust-lang/crates.io-index" 4265 + checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" 4266 + 4267 + [[package]] 4268 + name = "windows_x86_64_gnullvm" 4269 + version = "0.48.5" 4270 + source = "registry+https://github.com/rust-lang/crates.io-index" 4271 + checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 4272 + 4273 + [[package]] 4274 + name = "windows_x86_64_gnullvm" 4275 + version = "0.52.6" 4276 + source = "registry+https://github.com/rust-lang/crates.io-index" 4277 + checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 4278 + 4279 + [[package]] 4280 + name = "windows_x86_64_gnullvm" 4281 + version = "0.53.1" 4282 + source = "registry+https://github.com/rust-lang/crates.io-index" 4283 + checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" 4284 + 4285 + [[package]] 4286 + name = "windows_x86_64_msvc" 4287 + version = "0.42.2" 4288 + source = "registry+https://github.com/rust-lang/crates.io-index" 4289 + checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" 4290 + 4291 + [[package]] 4292 + name = "windows_x86_64_msvc" 4293 + version = "0.48.5" 4294 + source = "registry+https://github.com/rust-lang/crates.io-index" 4295 + checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 4296 + 4297 + [[package]] 4298 + name = "windows_x86_64_msvc" 4299 + version = "0.52.6" 4300 + source = "registry+https://github.com/rust-lang/crates.io-index" 4301 + checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 4302 + 4303 + [[package]] 4304 + name = "windows_x86_64_msvc" 4305 + version = "0.53.1" 4306 + source = "registry+https://github.com/rust-lang/crates.io-index" 4307 + checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" 4308 + 4309 + [[package]] 4310 + name = "winreg" 4311 + version = "0.50.0" 4312 + source = "registry+https://github.com/rust-lang/crates.io-index" 4313 + checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" 4314 + dependencies = [ 4315 + "cfg-if", 4316 + "windows-sys 0.48.0", 4317 + ] 4318 + 4319 + [[package]] 4320 + name = "wit-bindgen" 4321 + version = "0.46.0" 4322 + source = "registry+https://github.com/rust-lang/crates.io-index" 4323 + checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" 4324 + 4325 + [[package]] 4326 + name = "writeable" 4327 + version = "0.6.1" 4328 + source = "registry+https://github.com/rust-lang/crates.io-index" 4329 + checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" 4330 + 4331 + [[package]] 4332 + name = "yansi" 4333 + version = "1.0.1" 4334 + source = "registry+https://github.com/rust-lang/crates.io-index" 4335 + checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" 4336 + 4337 + [[package]] 4338 + name = "yoke" 4339 + version = "0.8.0" 4340 + source = "registry+https://github.com/rust-lang/crates.io-index" 4341 + checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" 4342 + dependencies = [ 4343 + "serde", 4344 + "stable_deref_trait", 4345 + "yoke-derive", 4346 + "zerofrom", 4347 + ] 4348 + 4349 + [[package]] 4350 + name = "yoke-derive" 4351 + version = "0.8.0" 4352 + source = "registry+https://github.com/rust-lang/crates.io-index" 4353 + checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" 4354 + dependencies = [ 4355 + "proc-macro2", 4356 + "quote", 4357 + "syn 2.0.107", 4358 + "synstructure", 4359 + ] 4360 + 4361 + [[package]] 4362 + name = "zerocopy" 4363 + version = "0.8.27" 4364 + source = "registry+https://github.com/rust-lang/crates.io-index" 4365 + checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" 4366 + dependencies = [ 4367 + "zerocopy-derive", 4368 + ] 4369 + 4370 + [[package]] 4371 + name = "zerocopy-derive" 4372 + version = "0.8.27" 4373 + source = "registry+https://github.com/rust-lang/crates.io-index" 4374 + checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" 4375 + dependencies = [ 4376 + "proc-macro2", 4377 + "quote", 4378 + "syn 2.0.107", 4379 + ] 4380 + 4381 + [[package]] 4382 + name = "zerofrom" 4383 + version = "0.1.6" 4384 + source = "registry+https://github.com/rust-lang/crates.io-index" 4385 + checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" 4386 + dependencies = [ 4387 + "zerofrom-derive", 4388 + ] 4389 + 4390 + [[package]] 4391 + name = "zerofrom-derive" 4392 + version = "0.1.6" 4393 + source = "registry+https://github.com/rust-lang/crates.io-index" 4394 + checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" 4395 + dependencies = [ 4396 + "proc-macro2", 4397 + "quote", 4398 + "syn 2.0.107", 4399 + "synstructure", 4400 + ] 4401 + 4402 + [[package]] 4403 + name = "zeroize" 4404 + version = "1.8.2" 4405 + source = "registry+https://github.com/rust-lang/crates.io-index" 4406 + checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" 4407 + dependencies = [ 4408 + "serde", 4409 + ] 4410 + 4411 + [[package]] 4412 + name = "zerotrie" 4413 + version = "0.2.2" 4414 + source = "registry+https://github.com/rust-lang/crates.io-index" 4415 + checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" 4416 + dependencies = [ 4417 + "displaydoc", 4418 + "yoke", 4419 + "zerofrom", 4420 + ] 4421 + 4422 + [[package]] 4423 + name = "zerovec" 4424 + version = "0.11.4" 4425 + source = "registry+https://github.com/rust-lang/crates.io-index" 4426 + checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" 4427 + dependencies = [ 4428 + "yoke", 4429 + "zerofrom", 4430 + "zerovec-derive", 4431 + ] 4432 + 4433 + [[package]] 4434 + name = "zerovec-derive" 4435 + version = "0.11.1" 4436 + source = "registry+https://github.com/rust-lang/crates.io-index" 4437 + checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" 4438 + dependencies = [ 4439 + "proc-macro2", 4440 + "quote", 4441 + "syn 2.0.107", 4442 + ]
+16 -1
upload/Cargo.toml
··· 1 + [workspace] 2 + resolver = "3" 3 + members = ["lexicons"] 4 + 1 5 [package] 2 6 name = "atcities-upload" 3 - version = "0.1.0" 7 + version = "1.0.1" 4 8 edition = "2024" 5 9 6 10 [dependencies] 11 + lexicons = { path = "./lexicons" } 12 + clap = { version = "4.5.49", features = ["derive"] } 13 + ignore = "0.4.23" 14 + regex = "1.12.2" 15 + mime_guess = "2.0.5" 16 + tokio = { version = "1.48.0", features = [] } 17 + jacquard = "0.6.0" 18 + reqwest = "0.12.24" 19 + env_logger = "0.11.8" 20 + miette = { version = "7.6.0", features = ["derive", "fancy"] } 21 + thiserror = "2.0.17"
+17
upload/lexicons/Cargo.toml
··· 1 + [package] 2 + name = "lexicons" 3 + version = "1.0.0" 4 + edition = "2024" 5 + 6 + [features] 7 + default = ["dev_atcities"] 8 + dev_atcities = [] 9 + 10 + [dependencies] 11 + bon = "3.8.1" 12 + bytes = { version = "1.10.1", features = ["serde"] } 13 + miette = "7.6.0" 14 + serde = "1.0.228" 15 + thiserror = "2.0.17" 16 + jacquard-common = "0.6.0" 17 + jacquard-derive = "0.6.0"
+77
upload/lexicons/src/dev_atcities/route.rs
··· 1 + // @generated by jacquard-lexicon. DO NOT EDIT. 2 + // 3 + // Lexicon: dev.atcities.route 4 + // 5 + // This file was automatically generated from Lexicon schemas. 6 + // Any manual changes will be overwritten on the next regeneration. 7 + 8 + #[jacquard_derive::lexicon] 9 + #[derive( 10 + serde::Serialize, 11 + serde::Deserialize, 12 + Debug, 13 + Clone, 14 + PartialEq, 15 + Eq, 16 + jacquard_derive::IntoStatic, 17 + bon::Builder, 18 + )] 19 + #[serde(rename_all = "camelCase")] 20 + pub struct Blob<'a> { 21 + #[serde(borrow)] 22 + pub blob: jacquard_common::types::blob::Blob<'a>, 23 + } 24 + 25 + /// Page URL maps directly to a record key 26 + #[jacquard_derive::lexicon] 27 + #[derive( 28 + serde::Serialize, 29 + serde::Deserialize, 30 + Debug, 31 + Clone, 32 + PartialEq, 33 + Eq, 34 + jacquard_derive::IntoStatic, 35 + bon::Builder, 36 + )] 37 + #[serde(rename_all = "camelCase")] 38 + pub struct Route<'a> { 39 + #[serde(borrow)] 40 + pub page: crate::dev_atcities::route::Blob<'a>, 41 + } 42 + 43 + /// Typed wrapper for GetRecord response with this collection's record type. 44 + #[derive( 45 + serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, jacquard_derive::IntoStatic, 46 + )] 47 + #[serde(rename_all = "camelCase")] 48 + pub struct RouteGetRecordOutput<'a> { 49 + #[serde(skip_serializing_if = "std::option::Option::is_none")] 50 + #[serde(borrow)] 51 + pub cid: std::option::Option<jacquard_common::types::string::Cid<'a>>, 52 + #[serde(borrow)] 53 + pub uri: jacquard_common::types::string::AtUri<'a>, 54 + #[serde(borrow)] 55 + pub value: Route<'a>, 56 + } 57 + 58 + /// Marker type for deserializing records from this collection. 59 + pub struct RouteRecord; 60 + impl jacquard_common::xrpc::XrpcResp for RouteRecord { 61 + const NSID: &'static str = "dev.atcities.route"; 62 + const ENCODING: &'static str = "application/json"; 63 + type Output<'de> = RouteGetRecordOutput<'de>; 64 + type Err<'de> = jacquard_common::types::collection::RecordError<'de>; 65 + } 66 + 67 + impl jacquard_common::types::collection::Collection for Route<'_> { 68 + const NSID: &'static str = "dev.atcities.route"; 69 + type Record = RouteRecord; 70 + } 71 + 72 + impl From<RouteGetRecordOutput<'_>> for Route<'_> { 73 + fn from(output: RouteGetRecordOutput<'_>) -> Self { 74 + use jacquard_common::IntoStatic; 75 + output.value.into_static() 76 + } 77 + }
+6
upload/lexicons/src/dev_atcities.rs
··· 1 + // @generated by jacquard-lexicon. DO NOT EDIT. 2 + // 3 + // This file was automatically generated from Lexicon schemas. 4 + // Any manual changes will be overwritten on the next regeneration. 5 + 6 + pub mod route;
+7
upload/lexicons/src/lib.rs
··· 1 + // @generated by jacquard-lexicon. DO NOT EDIT. 2 + // 3 + // This file was automatically generated from Lexicon schemas. 4 + // Any manual changes will be overwritten on the next regeneration. 5 + 6 + #[cfg(feature = "dev_atcities")] 7 + pub mod dev_atcities;
-4
upload/src/auth.rs
··· 1 - pub struct Session { 2 - pds: String, 3 - id: crate::config::Id, 4 - }
-81
upload/src/config.rs
··· 1 - pub struct Config { 2 - pub user: String, 3 - pub pword: String, 4 - pub dir: String, 5 - } 6 - 7 - pub enum ConfigErr { 8 - TooManyDirectories, 9 - NotEnoughArgs(String), 10 - UnknownArg(String), 11 - NotADirectory, 12 - } 13 - 14 - pub fn extract() -> Result<Config, ConfigErr> { 15 - let mut user: Option<String> = None; 16 - let mut pword: Option<String> = None; 17 - let mut dir: Option<String> = None; 18 - 19 - let mut args = std::env::args().into_iter(); 20 - // skip first arg 21 - args.next(); 22 - while let Some(arg) = args.next() { 23 - match arg.as_str() { 24 - "--user" => user = args.next(), 25 - "--password" => pword = args.next(), 26 - _ => { 27 - if arg.starts_with("--") { 28 - return Err(ConfigErr::UnknownArg(arg)); 29 - } 30 - if dir.is_some() { 31 - return Err(ConfigErr::TooManyDirectories); 32 - } 33 - dir = Some(arg); 34 - } 35 - } 36 - } 37 - 38 - if let Some(user) = user.clone() 39 - && let Some(pword) = pword.clone() 40 - && let Some(dir) = dir.clone() 41 - { 42 - return Ok(Config { 43 - user, 44 - pword, 45 - dir: dir.to_owned(), 46 - }); 47 - } 48 - 49 - return Err(ConfigErr::NotEnoughArgs(String::from( 50 - // xxx 51 - if user.is_none() && pword.is_none() && dir.is_none() { 52 - "--user, --password, and <dir>" 53 - } 54 - // yxx 55 - else if user.is_some() && pword.is_none() && dir.is_none() { 56 - "--password and <dir>" 57 - } 58 - // xyx 59 - else if user.is_none() && pword.is_some() && dir.is_none() { 60 - "--user and <dir>" 61 - } 62 - // yyx 63 - else if user.is_some() && pword.is_some() && dir.is_none() { 64 - "<dir>" 65 - } 66 - // xxy 67 - else if user.is_none() && pword.is_none() && dir.is_some() { 68 - "--user and --password" 69 - } 70 - // yxy 71 - else if user.is_some() && pword.is_none() && dir.is_some() { 72 - "--password" 73 - } 74 - // xyy 75 - else if user.is_none() && pword.is_some() && dir.is_some() { 76 - "--user" 77 - } else { 78 - "Invalid State, as all values are provided here" 79 - }, 80 - ))); 81 - }
+318 -12
upload/src/main.rs
··· 1 - mod auth; 2 - mod config; 3 - mod types; 1 + use clap::{ArgAction, Parser}; 2 + use jacquard::api::com_atproto::repo::apply_writes::{ 3 + self, ApplyWrites, ApplyWritesOutput, ApplyWritesWritesItem, 4 + }; 5 + use jacquard::client::AgentSessionExt; 6 + use jacquard::client::MemorySessionStore; 7 + use jacquard::oauth::loopback::LoopbackConfig; 8 + use jacquard::oauth::types::AuthorizeOptions; 9 + use jacquard::types::string::{AtStrError, RecordKey, Rkey}; 10 + use jacquard::{AuthorizationToken, CowStr, atproto, oauth}; 11 + use jacquard::{ 12 + Data, 13 + api::com_atproto::{self, repo::list_records::ListRecords}, 14 + client::{Agent, credential_session::CredentialSession}, 15 + cowstr::ToCowStr, 16 + identity::JacquardResolver, 17 + types::{ident::AtIdentifier, nsid::Nsid, string::AtprotoStr, uri::Uri}, 18 + xrpc::XrpcExt, 19 + }; 20 + use miette::{Context, IntoDiagnostic, Result}; 21 + use std::io::Write; 22 + use std::{collections::HashMap, fs, path::PathBuf}; 23 + 24 + use crate::sitemap::{BlobRef, Sitemap, SitemapNode}; 25 + 26 + mod sitemap; 27 + mod utils; 28 + 29 + #[derive(Parser, Debug, Clone)] 30 + #[command(version, about, long_about = None)] 31 + struct Config { 32 + /// Handle or DID to authenticate 33 + #[arg(verbatim_doc_comment)] 34 + user: String, 35 + 36 + /// App password to authenticate the client 37 + /// Normal passwords also work but are not advised 38 + /// If ommited, oauth will be used instead 39 + /// Oauth is reccomended where possible. 40 + #[arg(verbatim_doc_comment, short = 'p', long = "password")] 41 + password: Option<String>, 42 + 43 + /// Include dotfiles in upload 44 + /// Default: false 45 + #[arg(verbatim_doc_comment, short = 'a', long = "all")] 46 + all_files: bool, 47 + 48 + /// Respect gitignore files 49 + /// Note: gitignore files are not uploaded unless --all is set 50 + /// Default: true 51 + #[arg(verbatim_doc_comment, short = 'g', long = "no-gitignore", action = ArgAction::SetFalse, )] 52 + git_ignore: bool, 53 + 54 + /// Directory to upload 55 + #[arg(verbatim_doc_comment)] 56 + dir: PathBuf, 57 + } 58 + 59 + async fn live_records(agent: &impl AgentSessionExt, config: Config) -> Result<Vec<String>> { 60 + // find live site records 61 + let mut cursor = None; 62 + let mut remote_records = Vec::new(); 63 + let user = config.user.clone(); 64 + let user = if user.contains(":") { 65 + AtIdentifier::Did(user.into()) 66 + } else { 67 + AtIdentifier::Handle(user.into()) 68 + }; 69 + loop { 70 + let req = com_atproto::repo::list_records::ListRecords::new() 71 + .collection( 72 + Nsid::new("dev.atcities.route").expect("failed to generate dev.atcities.route nsid"), 73 + ) 74 + .repo(user.clone()) 75 + .limit(100) 76 + .maybe_cursor(cursor) 77 + .build(); 78 + 79 + let res = agent 80 + .xrpc(agent.endpoint().await) 81 + .send::<ListRecords>(&req) 82 + .await? 83 + .into_output()?; 84 + 85 + for record in res.records { 86 + match record { 87 + Data::Object(obj) => { 88 + let obj = obj.0.clone(); 89 + let uri = obj.get_key_value("uri").and_then(|x| match x.1 { 90 + Data::String(str) => Some(str), 91 + _ => None, 92 + }); 93 + 94 + if let Some(uri) = uri 95 + && let AtprotoStr::Uri(uri) = uri 96 + && let Uri::At(uri) = uri 97 + && let Some(rkey) = uri.rkey() 98 + { 99 + let rkey = rkey.0.to_cowstr().to_string(); 100 + remote_records.push(rkey); 101 + } else { 102 + panic!("Warning: pds returned invalid data.") 103 + } 104 + } 105 + _ => { 106 + panic!("Warning: pds returned invalid data.") 107 + } 108 + } 109 + } 4 110 5 - fn main() -> Result<(), ()> { 6 - let config = config::extract(); 7 - if let Err(err) = config { 8 - match err { 9 - config::ConfigErr::TooManyDirectories => println!("Too many directories"), 10 - config::ConfigErr::NotEnoughArgs(args) => println!("Missing {}", args), 11 - config::ConfigErr::UnknownArg(arg) => println!("Unknown arg {}", arg), 12 - config::ConfigErr::NotADirectory => println!("Not a directory"), 111 + cursor = res.cursor; 112 + if cursor.is_none() { 113 + break; 13 114 } 14 - return Err(()); 15 115 } 116 + Ok(remote_records) 117 + } 118 + 119 + async fn upload_site_blobs( 120 + agent: &impl AgentSessionExt, 121 + _config: Config, 122 + local_sitemap: Sitemap, 123 + ) -> Result<Sitemap> { 124 + // upload local site blobs 125 + let mut new_sitemap: Sitemap = HashMap::new(); 126 + for (k, v) in local_sitemap { 127 + print!("Uploading {k}... "); 128 + let _ = std::io::stdout().flush(); 129 + let blob = match v.blob { 130 + BlobRef::Local(path) => path, 131 + BlobRef::Remote(_) => { 132 + panic!("Impossible state") 133 + } 134 + }; 135 + let blob = fs::read(blob).into_diagnostic()?; 136 + 137 + let req = com_atproto::repo::upload_blob::UploadBlob::new() 138 + .body(blob.into()) 139 + .build(); 140 + let res = agent.send(req).await?.into_output()?; 141 + 142 + new_sitemap.insert( 143 + k, 144 + SitemapNode { 145 + mime_type: v.mime_type, 146 + blob: BlobRef::Remote(res.blob.into()), 147 + }, 148 + ); 149 + 150 + println!("Done!"); 151 + } 152 + 153 + Ok(new_sitemap) 154 + } 155 + 156 + async fn update_remote_site( 157 + agent: &impl AgentSessionExt, 158 + config: Config, 159 + auth: AuthorizationToken<'_>, 160 + remote_records: Vec<String>, 161 + new_sitemap: Sitemap, 162 + ) -> Result<ApplyWritesOutput<'static>> { 163 + // batch delete/upload records 164 + let mut writes = Vec::new(); 165 + let mut delete_records = remote_records 166 + .into_iter() 167 + .map(|x| { 168 + let rkey = RecordKey(Rkey::new_owned(x)?); 169 + Ok(ApplyWritesWritesItem::Delete(Box::new( 170 + apply_writes::Delete::builder() 171 + .collection(Nsid::raw("dev.atcities.route")) 172 + .rkey(rkey) 173 + .build(), 174 + ))) 175 + }) 176 + .collect::<Result<Vec<ApplyWritesWritesItem<'_>>, AtStrError>>() 177 + .into_diagnostic()?; 178 + 179 + let mut create_records = new_sitemap 180 + .into_iter() 181 + .map(|(k, v)| { 182 + let k = match k.as_str() { 183 + "404.html" => String::from("404"), 184 + "index.html" => String::from("/"), 185 + _ => match k.strip_suffix("/index.html") { 186 + Some(k) => format!("/{k}/"), 187 + None => format!("/{k}"), 188 + } 189 + }; 190 + let rkey = 191 + utils::url_to_rkey(k).wrap_err("Invalid file path. Could not be converted to rkey")?; 192 + let rkey = RecordKey(Rkey::new_owned(rkey).into_diagnostic()?); 193 + let blob = match v.blob { 194 + BlobRef::Local(_) => panic!("Illegal local blob"), 195 + BlobRef::Remote(cid) => cid, 196 + }; 197 + let data = atproto!({ 198 + "page": { 199 + "$type": "dev.atcities.route#blob", 200 + "blob": { 201 + "$type": "blob", 202 + "ref": { 203 + "$link": blob.r#ref.as_str() 204 + }, 205 + "mimeType": blob.mime_type.0.as_str(), 206 + "size": blob.size 207 + } 208 + } 209 + }); 210 + Ok(ApplyWritesWritesItem::Create(Box::new( 211 + apply_writes::Create::builder() 212 + .collection(Nsid::raw("dev.atcities.route")) 213 + .rkey(rkey) 214 + .value(data) 215 + .build(), 216 + ))) 217 + }) 218 + .collect::<Result<Vec<ApplyWritesWritesItem<'_>>, miette::Error>>()?; 219 + 220 + writes.append(&mut delete_records); 221 + writes.append(&mut create_records); 222 + 223 + let repo = if config.user.contains(":") { 224 + AtIdentifier::Did(config.user.into()) 225 + } else { 226 + AtIdentifier::Handle(config.user.into()) 227 + }; 228 + 229 + let req = com_atproto::repo::apply_writes::ApplyWrites::new() 230 + .repo(repo) 231 + .writes(writes) 232 + .build(); 233 + 234 + let res = agent 235 + .xrpc(agent.endpoint().await) 236 + .auth(auth) 237 + .send::<ApplyWrites>(&req) 238 + .await? 239 + .into_output()?; 240 + 241 + Ok(res) 242 + } 243 + 244 + #[tokio::main] 245 + async fn main() -> Result<(), miette::Error> { 246 + env_logger::init(); 247 + // get config items 248 + let config = Config::parse(); 249 + 250 + // get local site info 251 + let local_sitemap = 252 + sitemap::local_sitemap(config.dir.clone(), config.all_files, config.git_ignore)?; 253 + 254 + // create session 255 + if let Some(password) = config.password.clone() { 256 + let password = password.into(); 257 + let client = JacquardResolver::default(); 258 + let store = MemorySessionStore::default(); 259 + let session = CredentialSession::new(store.into(), client.into()); 260 + 261 + let auth = session 262 + .login(config.user.clone().into(), password, None, None, None) 263 + .await?; 264 + 265 + let agent = Agent::from(session); 266 + 267 + let remote_sitemap = live_records(&agent, config.clone()).await?; 268 + let new_sitemap = upload_site_blobs(&agent, config.clone(), local_sitemap).await?; 269 + let _ = update_remote_site( 270 + &agent, 271 + config.clone(), 272 + AuthorizationToken::Bearer(auth.access_jwt), 273 + remote_sitemap, 274 + new_sitemap, 275 + ) 276 + .await?; 277 + 278 + println!( 279 + "Site is now updated. Live at {}", 280 + utils::site_handle(config.user) 281 + ); 282 + } else { 283 + let oauth = oauth::client::OAuthClient::with_memory_store(); 284 + let session = oauth 285 + .login_with_local_server( 286 + config.user.clone(), 287 + AuthorizeOptions::default(), 288 + LoopbackConfig::default(), 289 + ) 290 + .await?; 291 + 292 + // sick and twisted reference mangling BUT it works So 293 + // tldr: the cowstr is a borrowed cowstr iiuc, 294 + // so it needs to be turned into an owned cowstr 295 + // to break reference to session which gets moved 296 + let auth = session.access_token().await; 297 + let auth = match auth { 298 + AuthorizationToken::Bearer(cow_str) => CowStr::copy_from_str(cow_str.as_str()), 299 + AuthorizationToken::Dpop(cow_str) => CowStr::copy_from_str(cow_str.as_str()), 300 + }; 301 + 302 + println!("{}", auth); 303 + 304 + let agent = Agent::from(session); 305 + 306 + let remote_sitemap = live_records(&agent, config.clone()).await?; 307 + let new_sitemap = upload_site_blobs(&agent, config.clone(), local_sitemap).await?; 308 + let _ = update_remote_site( 309 + &agent, 310 + config.clone(), 311 + AuthorizationToken::Dpop(auth), 312 + remote_sitemap, 313 + new_sitemap, 314 + ) 315 + .await?; 316 + 317 + println!( 318 + "Site is now updated. Live at {}", 319 + utils::site_handle(config.user) 320 + ); 321 + }; 16 322 17 323 Ok(()) 18 324 }
+80
upload/src/sitemap.rs
··· 1 + use ignore::WalkBuilder; 2 + use jacquard::types::blob::Blob; 3 + use miette::Diagnostic; 4 + use mime_guess::mime; 5 + use std::{collections::HashMap, path::PathBuf}; 6 + use thiserror::Error; 7 + 8 + pub type Sitemap = HashMap<String, SitemapNode>; 9 + 10 + #[derive(Debug)] 11 + pub struct SitemapNode { 12 + pub mime_type: String, 13 + pub blob: BlobRef, 14 + } 15 + 16 + #[derive(Debug)] 17 + pub enum BlobRef { 18 + Local(PathBuf), 19 + Remote(Blob<'static>), 20 + } 21 + 22 + #[derive(Debug, Error, Diagnostic)] 23 + pub enum SitemapErr { 24 + #[error("IO error: {}", .0)] 25 + IoErr(#[from] std::io::Error), 26 + #[error("Error finding files: {}", .0)] 27 + IgnoreErr(#[from] ignore::Error), 28 + #[error("Error normalising file paths: {}", .0)] 29 + StripPrefixErr(#[from] std::path::StripPrefixError), 30 + #[error("Found non UTF-8 path")] 31 + NotUTF8Path, 32 + } 33 + 34 + pub fn local_sitemap( 35 + dir: PathBuf, 36 + include_dotfiles: bool, 37 + use_gitignore: bool, 38 + ) -> miette::Result<Sitemap, SitemapErr> { 39 + let prefix = dir.canonicalize()?; 40 + 41 + let mut res = HashMap::new(); 42 + for file in WalkBuilder::new(dir) 43 + .hidden(!include_dotfiles) 44 + .git_ignore(use_gitignore) 45 + .git_exclude(use_gitignore) 46 + .git_global(use_gitignore) 47 + .follow_links(true) 48 + .build() 49 + { 50 + let file = file?; 51 + 52 + let metadata = file.metadata()?; 53 + 54 + if !metadata.is_file() { 55 + continue; 56 + }; 57 + 58 + // find the path of the files relative to the source directory 59 + // source dir `./dist`: 60 + // ./dist/index.html => index.html 61 + // ./dist/assets/cat.jpg => cat.jpg 62 + // etc 63 + let key = file.path().canonicalize()?; 64 + let key = key.strip_prefix(&prefix)?; 65 + let key = String::from(key.to_str().ok_or(SitemapErr::NotUTF8Path)?); 66 + 67 + let mime = mime_guess::from_path(&key); 68 + let mime = mime.first().unwrap_or(mime::APPLICATION_OCTET_STREAM); 69 + let mime = mime.essence_str(); 70 + 71 + res.insert( 72 + key, 73 + SitemapNode { 74 + mime_type: String::from(mime), 75 + blob: BlobRef::Local(file.path().to_owned()), 76 + }, 77 + ); 78 + } 79 + Ok(res) 80 + }
-44
upload/src/types.rs
··· 1 - pub enum Did { 2 - Web(String), 3 - Plc(String), 4 - } 5 - 6 - enum DidError { 7 - UnknownMethod, 8 - MalformedDid, 9 - } 10 - 11 - impl Did { 12 - fn from(did: String) -> Result<Did, DidError> { 13 - if did.starts_with("did:plc:") { 14 - return Ok(Did::Plc(String::from(did[8..]))); 15 - } else if did.starts_with("did:web:") { 16 - return Ok(Did::Plc(String::from(did[8..]))); 17 - } else if did.starts_with("did:") { 18 - return Err(DidError::UnknownMethod); 19 - } else { 20 - return Err(DidError::MalformedDid); 21 - } 22 - } 23 - } 24 - 25 - pub struct User { 26 - handle: Option<String>, 27 - did: Did, 28 - pds: String, 29 - } 30 - 31 - enum UserFromErr { 32 - InvalidHandle, 33 - NoDidForHandle, 34 - HandleNotBidirectional, 35 - DidParseError(DidError), 36 - DidNotBidirectional, 37 - NoPds, 38 - } 39 - 40 - impl User { 41 - fn fromHandle(handle: String) -> Result<User, UserFromErr> {} 42 - 43 - fn fromDid(did: String) -> Result<User, UserFromErr> {} 44 - }
+76
upload/src/utils.rs
··· 1 + use regex::Regex; 2 + 3 + #[allow(dead_code)] 4 + pub fn rkey_to_url(rkey: String) -> Option<String> { 5 + let regex = Regex::new( 6 + // symbols A-Za-z0-9 -._~: are all valid rkey characters 7 + // however we use a subset of record keys where : is an escape character 8 + // allow any rkey character except colons 9 + // or any of the valid escape sequences 10 + // from start of string to end between 0 and unlimited times 11 + r"^(?:[A-Za-z0-9.\-_~]|(?:::)|(?::~)|(?::21)|(?::24)|(?::26)|(?::27)|(?::28)|(?::29)|(?::2A)|(?::2B)|(?::2C)|(?::3A)|(?::3B)|(?::3D)|(?::40))*$", 12 + ) 13 + .expect("Regex failed to generate"); 14 + 15 + if !regex.is_match(&rkey) { 16 + return None; 17 + }; 18 + 19 + let res = rkey 20 + .replace("::", "/") 21 + .replace(":~", "%") 22 + .replace(":21", "!") 23 + .replace(":24", "$") 24 + .replace(":26", "&") 25 + .replace(":27", "'") 26 + .replace(":28", "(") 27 + .replace(":29", ")") 28 + .replace(":2A", "*") 29 + .replace(":2B", "+") 30 + .replace(":2C", ",") 31 + .replace(":3A", ":") 32 + .replace(":3B", ";") 33 + .replace(":3D", "=") 34 + .replace(":40", "@"); 35 + 36 + Some(res) 37 + } 38 + 39 + pub fn url_to_rkey(url: String) -> Option<String> { 40 + let regex = Regex::new(r"^(?:[a-zA-Z0-9/\-._~!$&'()*+,;=:@]|(?:%[0-9a-fA-F]{2}))*$") 41 + .expect("Regex failed to generate"); 42 + if !regex.is_match(&url) { 43 + return None; 44 + } 45 + 46 + let res = url 47 + // : replace is hoisted so it doesnt replace colons from elsewhere 48 + .replace(":", ":3A") 49 + .replace("/", "::") 50 + .replace("%", ":~") 51 + .replace("!", ":21") 52 + .replace("$", ":24") 53 + .replace("&", ":26") 54 + .replace("'", ":27") 55 + .replace("(", ":28") 56 + .replace(")", ":29") 57 + .replace("*", ":2A") 58 + .replace("+", ":2B") 59 + .replace(",", ":2C") 60 + .replace(";", ":3B") 61 + .replace("=", ":3D") 62 + .replace("@", ":40"); 63 + 64 + Some(res) 65 + } 66 + 67 + pub fn site_handle(user: String) -> String { 68 + if user.contains(":") { 69 + let user = user.split(":").collect::<Vec<_>>(); 70 + let method = user[1]; 71 + let did = user[2]; 72 + format!("https://{did}.did-{method}.atcities.dev/") 73 + } else { 74 + format!("https://{user}.atcities.dev/") 75 + } 76 + }